").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
5 |
--------------------------------------------------------------------------------
/Chrome Extension/jquery-ui-1.11.2.css:
--------------------------------------------------------------------------------
1 | /*! jQuery UI - v1.11.2 - 2014-10-16
2 | * http://jqueryui.com
3 | * Includes: core.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, draggable.css, menu.css, progressbar.css, resizable.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css
4 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
5 | * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
6 |
7 | /* Layout helpers
8 | ----------------------------------*/
9 | .ui-helper-hidden {
10 | display: none;
11 | }
12 | .ui-helper-hidden-accessible {
13 | border: 0;
14 | clip: rect(0 0 0 0);
15 | height: 1px;
16 | margin: -1px;
17 | overflow: hidden;
18 | padding: 0;
19 | position: absolute;
20 | width: 1px;
21 | }
22 | .ui-helper-reset {
23 | margin: 0;
24 | padding: 0;
25 | border: 0;
26 | outline: 0;
27 | line-height: 1.3;
28 | text-decoration: none;
29 | font-size: 100%;
30 | list-style: none;
31 | }
32 | .ui-helper-clearfix:before,
33 | .ui-helper-clearfix:after {
34 | content: "";
35 | display: table;
36 | border-collapse: collapse;
37 | }
38 | .ui-helper-clearfix:after {
39 | clear: both;
40 | }
41 | .ui-helper-clearfix {
42 | min-height: 0; /* support: IE7 */
43 | }
44 | .ui-helper-zfix {
45 | width: 100%;
46 | height: 100%;
47 | top: 0;
48 | left: 0;
49 | position: absolute;
50 | opacity: 0;
51 | filter:Alpha(Opacity=0); /* support: IE8 */
52 | }
53 |
54 | .ui-front {
55 | z-index: 100;
56 | }
57 |
58 |
59 | /* Interaction Cues
60 | ----------------------------------*/
61 | .ui-state-disabled {
62 | cursor: default !important;
63 | }
64 |
65 |
66 | /* Icons
67 | ----------------------------------*/
68 |
69 | /* states and images */
70 | .ui-icon {
71 | display: block;
72 | text-indent: -99999px;
73 | overflow: hidden;
74 | background-repeat: no-repeat;
75 | }
76 |
77 |
78 | /* Misc visuals
79 | ----------------------------------*/
80 |
81 | /* Overlays */
82 | .ui-widget-overlay {
83 | position: fixed;
84 | top: 0;
85 | left: 0;
86 | width: 100%;
87 | height: 100%;
88 | }
89 | .ui-accordion .ui-accordion-header {
90 | display: block;
91 | cursor: pointer;
92 | position: relative;
93 | margin: 2px 0 0 0;
94 | padding: .5em .5em .5em .7em;
95 | min-height: 0; /* support: IE7 */
96 | font-size: 100%;
97 | }
98 | .ui-accordion .ui-accordion-icons {
99 | padding-left: 2.2em;
100 | }
101 | .ui-accordion .ui-accordion-icons .ui-accordion-icons {
102 | padding-left: 2.2em;
103 | }
104 | .ui-accordion .ui-accordion-header .ui-accordion-header-icon {
105 | position: absolute;
106 | left: .5em;
107 | top: 50%;
108 | margin-top: -8px;
109 | }
110 | .ui-accordion .ui-accordion-content {
111 | padding: 1em 2.2em;
112 | border-top: 0;
113 | overflow: auto;
114 | }
115 | .ui-autocomplete {
116 | position: absolute;
117 | top: 0;
118 | left: 0;
119 | cursor: default;
120 | }
121 | .ui-button {
122 | display: inline-block;
123 | position: relative;
124 | padding: 0;
125 | line-height: normal;
126 | margin-right: .1em;
127 | cursor: pointer;
128 | vertical-align: middle;
129 | text-align: center;
130 | overflow: visible; /* removes extra width in IE */
131 | }
132 | .ui-button,
133 | .ui-button:link,
134 | .ui-button:visited,
135 | .ui-button:hover,
136 | .ui-button:active {
137 | text-decoration: none;
138 | }
139 | /* to make room for the icon, a width needs to be set here */
140 | .ui-button-icon-only {
141 | width: 2.2em;
142 | }
143 | /* button elements seem to need a little more width */
144 | button.ui-button-icon-only {
145 | width: 2.4em;
146 | }
147 | .ui-button-icons-only {
148 | width: 3.4em;
149 | }
150 | button.ui-button-icons-only {
151 | width: 3.7em;
152 | }
153 |
154 | /* button text element */
155 | .ui-button .ui-button-text {
156 | display: block;
157 | line-height: normal;
158 | }
159 | .ui-button-text-only .ui-button-text {
160 | padding: .4em 1em;
161 | }
162 | .ui-button-icon-only .ui-button-text,
163 | .ui-button-icons-only .ui-button-text {
164 | padding: .4em;
165 | text-indent: -9999999px;
166 | }
167 | .ui-button-text-icon-primary .ui-button-text,
168 | .ui-button-text-icons .ui-button-text {
169 | padding: .4em 1em .4em 2.1em;
170 | }
171 | .ui-button-text-icon-secondary .ui-button-text,
172 | .ui-button-text-icons .ui-button-text {
173 | padding: .4em 2.1em .4em 1em;
174 | }
175 | .ui-button-text-icons .ui-button-text {
176 | padding-left: 2.1em;
177 | padding-right: 2.1em;
178 | }
179 | /* no icon support for input elements, provide padding by default */
180 | input.ui-button {
181 | padding: .4em 1em;
182 | }
183 |
184 | /* button icon element(s) */
185 | .ui-button-icon-only .ui-icon,
186 | .ui-button-text-icon-primary .ui-icon,
187 | .ui-button-text-icon-secondary .ui-icon,
188 | .ui-button-text-icons .ui-icon,
189 | .ui-button-icons-only .ui-icon {
190 | position: absolute;
191 | top: 50%;
192 | margin-top: -8px;
193 | }
194 | .ui-button-icon-only .ui-icon {
195 | left: 50%;
196 | margin-left: -8px;
197 | }
198 | .ui-button-text-icon-primary .ui-button-icon-primary,
199 | .ui-button-text-icons .ui-button-icon-primary,
200 | .ui-button-icons-only .ui-button-icon-primary {
201 | left: .5em;
202 | }
203 | .ui-button-text-icon-secondary .ui-button-icon-secondary,
204 | .ui-button-text-icons .ui-button-icon-secondary,
205 | .ui-button-icons-only .ui-button-icon-secondary {
206 | right: .5em;
207 | }
208 |
209 | /* button sets */
210 | .ui-buttonset {
211 | margin-right: 7px;
212 | }
213 | .ui-buttonset .ui-button {
214 | margin-left: 0;
215 | margin-right: -.3em;
216 | }
217 |
218 | /* workarounds */
219 | /* reset extra padding in Firefox, see h5bp.com/l */
220 | input.ui-button::-moz-focus-inner,
221 | button.ui-button::-moz-focus-inner {
222 | border: 0;
223 | padding: 0;
224 | }
225 | .ui-datepicker {
226 | width: 17em;
227 | padding: .2em .2em 0;
228 | display: none;
229 | }
230 | .ui-datepicker .ui-datepicker-header {
231 | position: relative;
232 | padding: .2em 0;
233 | }
234 | .ui-datepicker .ui-datepicker-prev,
235 | .ui-datepicker .ui-datepicker-next {
236 | position: absolute;
237 | top: 2px;
238 | width: 1.8em;
239 | height: 1.8em;
240 | }
241 | .ui-datepicker .ui-datepicker-prev-hover,
242 | .ui-datepicker .ui-datepicker-next-hover {
243 | top: 1px;
244 | }
245 | .ui-datepicker .ui-datepicker-prev {
246 | left: 2px;
247 | }
248 | .ui-datepicker .ui-datepicker-next {
249 | right: 2px;
250 | }
251 | .ui-datepicker .ui-datepicker-prev-hover {
252 | left: 1px;
253 | }
254 | .ui-datepicker .ui-datepicker-next-hover {
255 | right: 1px;
256 | }
257 | .ui-datepicker .ui-datepicker-prev span,
258 | .ui-datepicker .ui-datepicker-next span {
259 | display: block;
260 | position: absolute;
261 | left: 50%;
262 | margin-left: -8px;
263 | top: 50%;
264 | margin-top: -8px;
265 | }
266 | .ui-datepicker .ui-datepicker-title {
267 | margin: 0 2.3em;
268 | line-height: 1.8em;
269 | text-align: center;
270 | }
271 | .ui-datepicker .ui-datepicker-title select {
272 | font-size: 1em;
273 | margin: 1px 0;
274 | }
275 | .ui-datepicker select.ui-datepicker-month,
276 | .ui-datepicker select.ui-datepicker-year {
277 | width: 45%;
278 | }
279 | .ui-datepicker table {
280 | width: 100%;
281 | font-size: .9em;
282 | border-collapse: collapse;
283 | margin: 0 0 .4em;
284 | }
285 | .ui-datepicker th {
286 | padding: .7em .3em;
287 | text-align: center;
288 | font-weight: bold;
289 | border: 0;
290 | }
291 | .ui-datepicker td {
292 | border: 0;
293 | padding: 1px;
294 | }
295 | .ui-datepicker td span,
296 | .ui-datepicker td a {
297 | display: block;
298 | padding: .2em;
299 | text-align: right;
300 | text-decoration: none;
301 | }
302 | .ui-datepicker .ui-datepicker-buttonpane {
303 | background-image: none;
304 | margin: .7em 0 0 0;
305 | padding: 0 .2em;
306 | border-left: 0;
307 | border-right: 0;
308 | border-bottom: 0;
309 | }
310 | .ui-datepicker .ui-datepicker-buttonpane button {
311 | float: right;
312 | margin: .5em .2em .4em;
313 | cursor: pointer;
314 | padding: .2em .6em .3em .6em;
315 | width: auto;
316 | overflow: visible;
317 | }
318 | .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
319 | float: left;
320 | }
321 |
322 | /* with multiple calendars */
323 | .ui-datepicker.ui-datepicker-multi {
324 | width: auto;
325 | }
326 | .ui-datepicker-multi .ui-datepicker-group {
327 | float: left;
328 | }
329 | .ui-datepicker-multi .ui-datepicker-group table {
330 | width: 95%;
331 | margin: 0 auto .4em;
332 | }
333 | .ui-datepicker-multi-2 .ui-datepicker-group {
334 | width: 50%;
335 | }
336 | .ui-datepicker-multi-3 .ui-datepicker-group {
337 | width: 33.3%;
338 | }
339 | .ui-datepicker-multi-4 .ui-datepicker-group {
340 | width: 25%;
341 | }
342 | .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
343 | .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
344 | border-left-width: 0;
345 | }
346 | .ui-datepicker-multi .ui-datepicker-buttonpane {
347 | clear: left;
348 | }
349 | .ui-datepicker-row-break {
350 | clear: both;
351 | width: 100%;
352 | font-size: 0;
353 | }
354 |
355 | /* RTL support */
356 | .ui-datepicker-rtl {
357 | direction: rtl;
358 | }
359 | .ui-datepicker-rtl .ui-datepicker-prev {
360 | right: 2px;
361 | left: auto;
362 | }
363 | .ui-datepicker-rtl .ui-datepicker-next {
364 | left: 2px;
365 | right: auto;
366 | }
367 | .ui-datepicker-rtl .ui-datepicker-prev:hover {
368 | right: 1px;
369 | left: auto;
370 | }
371 | .ui-datepicker-rtl .ui-datepicker-next:hover {
372 | left: 1px;
373 | right: auto;
374 | }
375 | .ui-datepicker-rtl .ui-datepicker-buttonpane {
376 | clear: right;
377 | }
378 | .ui-datepicker-rtl .ui-datepicker-buttonpane button {
379 | float: left;
380 | }
381 | .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
382 | .ui-datepicker-rtl .ui-datepicker-group {
383 | float: right;
384 | }
385 | .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
386 | .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
387 | border-right-width: 0;
388 | border-left-width: 1px;
389 | }
390 | .ui-dialog {
391 | overflow: hidden;
392 | position: absolute;
393 | top: 0;
394 | left: 0;
395 | padding: .2em;
396 | outline: 0;
397 | }
398 | .ui-dialog .ui-dialog-titlebar {
399 | padding: .4em 1em;
400 | position: relative;
401 | }
402 | .ui-dialog .ui-dialog-title {
403 | float: left;
404 | margin: .1em 0;
405 | white-space: nowrap;
406 | width: 90%;
407 | overflow: hidden;
408 | text-overflow: ellipsis;
409 | }
410 | .ui-dialog .ui-dialog-titlebar-close {
411 | position: absolute;
412 | right: .3em;
413 | top: 50%;
414 | width: 20px;
415 | margin: -10px 0 0 0;
416 | padding: 1px;
417 | height: 20px;
418 | }
419 | .ui-dialog .ui-dialog-content {
420 | position: relative;
421 | border: 0;
422 | padding: .5em 1em;
423 | background: none;
424 | overflow: auto;
425 | }
426 | .ui-dialog .ui-dialog-buttonpane {
427 | text-align: left;
428 | border-width: 1px 0 0 0;
429 | background-image: none;
430 | margin-top: .5em;
431 | padding: .3em 1em .5em .4em;
432 | }
433 | .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
434 | float: right;
435 | }
436 | .ui-dialog .ui-dialog-buttonpane button {
437 | margin: .5em .4em .5em 0;
438 | cursor: pointer;
439 | }
440 | .ui-dialog .ui-resizable-se {
441 | width: 12px;
442 | height: 12px;
443 | right: -5px;
444 | bottom: -5px;
445 | background-position: 16px 16px;
446 | }
447 | .ui-draggable .ui-dialog-titlebar {
448 | cursor: move;
449 | }
450 | .ui-draggable-handle {
451 | -ms-touch-action: none;
452 | touch-action: none;
453 | }
454 | .ui-menu {
455 | list-style: none;
456 | padding: 0;
457 | margin: 0;
458 | display: block;
459 | outline: none;
460 | }
461 | .ui-menu .ui-menu {
462 | position: absolute;
463 | }
464 | .ui-menu .ui-menu-item {
465 | position: relative;
466 | margin: 0;
467 | padding: 3px 1em 3px .4em;
468 | cursor: pointer;
469 | min-height: 0; /* support: IE7 */
470 | /* support: IE10, see #8844 */
471 | list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
472 | }
473 | .ui-menu .ui-menu-divider {
474 | margin: 5px 0;
475 | height: 0;
476 | font-size: 0;
477 | line-height: 0;
478 | border-width: 1px 0 0 0;
479 | }
480 | .ui-menu .ui-state-focus,
481 | .ui-menu .ui-state-active {
482 | margin: -1px;
483 | }
484 |
485 | /* icon support */
486 | .ui-menu-icons {
487 | position: relative;
488 | }
489 | .ui-menu-icons .ui-menu-item {
490 | padding-left: 2em;
491 | }
492 |
493 | /* left-aligned */
494 | .ui-menu .ui-icon {
495 | position: absolute;
496 | top: 0;
497 | bottom: 0;
498 | left: .2em;
499 | margin: auto 0;
500 | }
501 |
502 | /* right-aligned */
503 | .ui-menu .ui-menu-icon {
504 | left: auto;
505 | right: 0;
506 | }
507 | .ui-progressbar {
508 | height: 2em;
509 | text-align: left;
510 | overflow: hidden;
511 | }
512 | .ui-progressbar .ui-progressbar-value {
513 | margin: -1px;
514 | height: 100%;
515 | }
516 | .ui-progressbar .ui-progressbar-overlay {
517 | background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
518 | height: 100%;
519 | filter: alpha(opacity=25); /* support: IE8 */
520 | opacity: 0.25;
521 | }
522 | .ui-progressbar-indeterminate .ui-progressbar-value {
523 | background-image: none;
524 | }
525 | .ui-resizable {
526 | position: relative;
527 | }
528 | .ui-resizable-handle {
529 | position: absolute;
530 | font-size: 0.1px;
531 | display: block;
532 | -ms-touch-action: none;
533 | touch-action: none;
534 | }
535 | .ui-resizable-disabled .ui-resizable-handle,
536 | .ui-resizable-autohide .ui-resizable-handle {
537 | display: none;
538 | }
539 | .ui-resizable-n {
540 | cursor: n-resize;
541 | height: 7px;
542 | width: 100%;
543 | top: -5px;
544 | left: 0;
545 | }
546 | .ui-resizable-s {
547 | cursor: s-resize;
548 | height: 7px;
549 | width: 100%;
550 | bottom: -5px;
551 | left: 0;
552 | }
553 | .ui-resizable-e {
554 | cursor: e-resize;
555 | width: 7px;
556 | right: -5px;
557 | top: 0;
558 | height: 100%;
559 | }
560 | .ui-resizable-w {
561 | cursor: w-resize;
562 | width: 7px;
563 | left: -5px;
564 | top: 0;
565 | height: 100%;
566 | }
567 | .ui-resizable-se {
568 | cursor: se-resize;
569 | width: 12px;
570 | height: 12px;
571 | right: 1px;
572 | bottom: 1px;
573 | }
574 | .ui-resizable-sw {
575 | cursor: sw-resize;
576 | width: 9px;
577 | height: 9px;
578 | left: -5px;
579 | bottom: -5px;
580 | }
581 | .ui-resizable-nw {
582 | cursor: nw-resize;
583 | width: 9px;
584 | height: 9px;
585 | left: -5px;
586 | top: -5px;
587 | }
588 | .ui-resizable-ne {
589 | cursor: ne-resize;
590 | width: 9px;
591 | height: 9px;
592 | right: -5px;
593 | top: -5px;
594 | }
595 | .ui-selectable {
596 | -ms-touch-action: none;
597 | touch-action: none;
598 | }
599 | .ui-selectable-helper {
600 | position: absolute;
601 | z-index: 100;
602 | border: 1px dotted black;
603 | }
604 | .ui-selectmenu-menu {
605 | padding: 0;
606 | margin: 0;
607 | position: absolute;
608 | top: 0;
609 | left: 0;
610 | display: none;
611 | }
612 | .ui-selectmenu-menu .ui-menu {
613 | overflow: auto;
614 | /* Support: IE7 */
615 | overflow-x: hidden;
616 | padding-bottom: 1px;
617 | }
618 | .ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
619 | font-size: 1em;
620 | font-weight: bold;
621 | line-height: 1.5;
622 | padding: 2px 0.4em;
623 | margin: 0.5em 0 0 0;
624 | height: auto;
625 | border: 0;
626 | }
627 | .ui-selectmenu-open {
628 | display: block;
629 | }
630 | .ui-selectmenu-button {
631 | display: inline-block;
632 | overflow: hidden;
633 | position: relative;
634 | text-decoration: none;
635 | cursor: pointer;
636 | }
637 | .ui-selectmenu-button span.ui-icon {
638 | right: 0.5em;
639 | left: auto;
640 | margin-top: -8px;
641 | position: absolute;
642 | top: 50%;
643 | }
644 | .ui-selectmenu-button span.ui-selectmenu-text {
645 | text-align: left;
646 | padding: 0.4em 2.1em 0.4em 1em;
647 | display: block;
648 | line-height: 1.4;
649 | overflow: hidden;
650 | text-overflow: ellipsis;
651 | white-space: nowrap;
652 | }
653 | .ui-slider {
654 | position: relative;
655 | text-align: left;
656 | }
657 | .ui-slider .ui-slider-handle {
658 | position: absolute;
659 | z-index: 2;
660 | width: 1.2em;
661 | height: 1.2em;
662 | cursor: default;
663 | -ms-touch-action: none;
664 | touch-action: none;
665 | }
666 | .ui-slider .ui-slider-range {
667 | position: absolute;
668 | z-index: 1;
669 | font-size: .7em;
670 | display: block;
671 | border: 0;
672 | background-position: 0 0;
673 | }
674 |
675 | /* support: IE8 - See #6727 */
676 | .ui-slider.ui-state-disabled .ui-slider-handle,
677 | .ui-slider.ui-state-disabled .ui-slider-range {
678 | filter: inherit;
679 | }
680 |
681 | .ui-slider-horizontal {
682 | height: .8em;
683 | }
684 | .ui-slider-horizontal .ui-slider-handle {
685 | top: -.3em;
686 | margin-left: -.6em;
687 | }
688 | .ui-slider-horizontal .ui-slider-range {
689 | top: 0;
690 | height: 100%;
691 | }
692 | .ui-slider-horizontal .ui-slider-range-min {
693 | left: 0;
694 | }
695 | .ui-slider-horizontal .ui-slider-range-max {
696 | right: 0;
697 | }
698 |
699 | .ui-slider-vertical {
700 | width: .8em;
701 | height: 100px;
702 | }
703 | .ui-slider-vertical .ui-slider-handle {
704 | left: -.3em;
705 | margin-left: 0;
706 | margin-bottom: -.6em;
707 | }
708 | .ui-slider-vertical .ui-slider-range {
709 | left: 0;
710 | width: 100%;
711 | }
712 | .ui-slider-vertical .ui-slider-range-min {
713 | bottom: 0;
714 | }
715 | .ui-slider-vertical .ui-slider-range-max {
716 | top: 0;
717 | }
718 | .ui-sortable-handle {
719 | -ms-touch-action: none;
720 | touch-action: none;
721 | }
722 | .ui-spinner {
723 | position: relative;
724 | display: inline-block;
725 | overflow: hidden;
726 | padding: 0;
727 | vertical-align: middle;
728 | }
729 | .ui-spinner-input {
730 | border: none;
731 | background: none;
732 | color: inherit;
733 | padding: 0;
734 | margin: .2em 0;
735 | vertical-align: middle;
736 | margin-left: .4em;
737 | margin-right: 22px;
738 | }
739 | .ui-spinner-button {
740 | width: 16px;
741 | height: 50%;
742 | font-size: .5em;
743 | padding: 0;
744 | margin: 0;
745 | text-align: center;
746 | position: absolute;
747 | cursor: default;
748 | display: block;
749 | overflow: hidden;
750 | right: 0;
751 | }
752 | /* more specificity required here to override default borders */
753 | .ui-spinner a.ui-spinner-button {
754 | border-top: none;
755 | border-bottom: none;
756 | border-right: none;
757 | }
758 | /* vertically center icon */
759 | .ui-spinner .ui-icon {
760 | position: absolute;
761 | margin-top: -8px;
762 | top: 50%;
763 | left: 0;
764 | }
765 | .ui-spinner-up {
766 | top: 0;
767 | }
768 | .ui-spinner-down {
769 | bottom: 0;
770 | }
771 |
772 | /* TR overrides */
773 | .ui-spinner .ui-icon-triangle-1-s {
774 | /* need to fix icons sprite */
775 | background-position: -65px -16px;
776 | }
777 | .ui-tabs {
778 | position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
779 | padding: .2em;
780 | }
781 | .ui-tabs .ui-tabs-nav {
782 | margin: 0;
783 | padding: .2em .2em 0;
784 | }
785 | .ui-tabs .ui-tabs-nav li {
786 | list-style: none;
787 | float: left;
788 | position: relative;
789 | top: 0;
790 | margin: 1px .2em 0 0;
791 | border-bottom-width: 0;
792 | padding: 0;
793 | white-space: nowrap;
794 | }
795 | .ui-tabs .ui-tabs-nav .ui-tabs-anchor {
796 | float: left;
797 | padding: .5em 1em;
798 | text-decoration: none;
799 | }
800 | .ui-tabs .ui-tabs-nav li.ui-tabs-active {
801 | margin-bottom: -1px;
802 | padding-bottom: 1px;
803 | }
804 | .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
805 | .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
806 | .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
807 | cursor: text;
808 | }
809 | .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
810 | cursor: pointer;
811 | }
812 | .ui-tabs .ui-tabs-panel {
813 | display: block;
814 | border-width: 0;
815 | padding: 1em 1.4em;
816 | background: none;
817 | }
818 | .ui-tooltip {
819 | padding: 8px;
820 | position: absolute;
821 | z-index: 9999;
822 | max-width: 300px;
823 | -webkit-box-shadow: 0 0 5px #aaa;
824 | box-shadow: 0 0 5px #aaa;
825 | }
826 | body .ui-tooltip {
827 | border-width: 2px;
828 | }
829 |
830 | /* Component containers
831 | ----------------------------------*/
832 | .ui-widget {
833 | font-family: Verdana,Arial,sans-serif;
834 | font-size: 1.1em;
835 | }
836 | .ui-widget .ui-widget {
837 | font-size: 1em;
838 | }
839 | .ui-widget input,
840 | .ui-widget select,
841 | .ui-widget textarea,
842 | .ui-widget button {
843 | font-family: Verdana,Arial,sans-serif;
844 | font-size: 1em;
845 | }
846 | .ui-widget-content {
847 | border: 1px solid #aaaaaa;
848 | background: #ffffff url("images/ui-bg_flat_75_ffffff_40x100.png") 50% 50% repeat-x;
849 | color: #222222;
850 | }
851 | .ui-widget-content a {
852 | color: #222222;
853 | }
854 | .ui-widget-header {
855 | border: 1px solid #aaaaaa;
856 | background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
857 | color: #222222;
858 | font-weight: bold;
859 | }
860 | .ui-widget-header a {
861 | color: #222222;
862 | }
863 |
864 | /* Interaction states
865 | ----------------------------------*/
866 | .ui-state-default,
867 | .ui-widget-content .ui-state-default,
868 | .ui-widget-header .ui-state-default {
869 | border: 1px solid #d3d3d3;
870 | background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
871 | font-weight: normal;
872 | color: #555555;
873 | }
874 | .ui-state-default a,
875 | .ui-state-default a:link,
876 | .ui-state-default a:visited {
877 | color: #555555;
878 | text-decoration: none;
879 | }
880 | .ui-state-hover,
881 | .ui-widget-content .ui-state-hover,
882 | .ui-widget-header .ui-state-hover,
883 | .ui-state-focus,
884 | .ui-widget-content .ui-state-focus,
885 | .ui-widget-header .ui-state-focus {
886 | border: 1px solid #999999;
887 | background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
888 | font-weight: normal;
889 | color: #212121;
890 | }
891 | .ui-state-hover a,
892 | .ui-state-hover a:hover,
893 | .ui-state-hover a:link,
894 | .ui-state-hover a:visited,
895 | .ui-state-focus a,
896 | .ui-state-focus a:hover,
897 | .ui-state-focus a:link,
898 | .ui-state-focus a:visited {
899 | color: #212121;
900 | text-decoration: none;
901 | }
902 | .ui-state-active,
903 | .ui-widget-content .ui-state-active,
904 | .ui-widget-header .ui-state-active {
905 | border: 1px solid #aaaaaa;
906 | background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
907 | font-weight: normal;
908 | color: #212121;
909 | }
910 | .ui-state-active a,
911 | .ui-state-active a:link,
912 | .ui-state-active a:visited {
913 | color: #212121;
914 | text-decoration: none;
915 | }
916 |
917 | /* Interaction Cues
918 | ----------------------------------*/
919 | .ui-state-highlight,
920 | .ui-widget-content .ui-state-highlight,
921 | .ui-widget-header .ui-state-highlight {
922 | border: 1px solid #fcefa1;
923 | background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
924 | color: #363636;
925 | }
926 | .ui-state-highlight a,
927 | .ui-widget-content .ui-state-highlight a,
928 | .ui-widget-header .ui-state-highlight a {
929 | color: #363636;
930 | }
931 | .ui-state-error,
932 | .ui-widget-content .ui-state-error,
933 | .ui-widget-header .ui-state-error {
934 | border: 1px solid #cd0a0a;
935 | background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
936 | color: #cd0a0a;
937 | }
938 | .ui-state-error a,
939 | .ui-widget-content .ui-state-error a,
940 | .ui-widget-header .ui-state-error a {
941 | color: #cd0a0a;
942 | }
943 | .ui-state-error-text,
944 | .ui-widget-content .ui-state-error-text,
945 | .ui-widget-header .ui-state-error-text {
946 | color: #cd0a0a;
947 | }
948 | .ui-priority-primary,
949 | .ui-widget-content .ui-priority-primary,
950 | .ui-widget-header .ui-priority-primary {
951 | font-weight: bold;
952 | }
953 | .ui-priority-secondary,
954 | .ui-widget-content .ui-priority-secondary,
955 | .ui-widget-header .ui-priority-secondary {
956 | opacity: .7;
957 | filter:Alpha(Opacity=70); /* support: IE8 */
958 | font-weight: normal;
959 | }
960 | .ui-state-disabled,
961 | .ui-widget-content .ui-state-disabled,
962 | .ui-widget-header .ui-state-disabled {
963 | opacity: .35;
964 | filter:Alpha(Opacity=35); /* support: IE8 */
965 | background-image: none;
966 | }
967 | .ui-state-disabled .ui-icon {
968 | filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
969 | }
970 |
971 | /* Icons
972 | ----------------------------------*/
973 |
974 | /* states and images */
975 | .ui-icon {
976 | width: 16px;
977 | height: 16px;
978 | }
979 | .ui-icon,
980 | .ui-widget-content .ui-icon {
981 | background-image: url("images/ui-icons_222222_256x240.png");
982 | }
983 | .ui-widget-header .ui-icon {
984 | background-image: url("images/ui-icons_222222_256x240.png");
985 | }
986 | .ui-state-default .ui-icon {
987 | background-image: url("images/ui-icons_888888_256x240.png");
988 | }
989 | .ui-state-hover .ui-icon,
990 | .ui-state-focus .ui-icon {
991 | background-image: url("images/ui-icons_454545_256x240.png");
992 | }
993 | .ui-state-active .ui-icon {
994 | background-image: url("images/ui-icons_454545_256x240.png");
995 | }
996 | .ui-state-highlight .ui-icon {
997 | background-image: url("images/ui-icons_2e83ff_256x240.png");
998 | }
999 | .ui-state-error .ui-icon,
1000 | .ui-state-error-text .ui-icon {
1001 | background-image: url("images/ui-icons_cd0a0a_256x240.png");
1002 | }
1003 |
1004 | /* positioning */
1005 | .ui-icon-blank { background-position: 16px 16px; }
1006 | .ui-icon-carat-1-n { background-position: 0 0; }
1007 | .ui-icon-carat-1-ne { background-position: -16px 0; }
1008 | .ui-icon-carat-1-e { background-position: -32px 0; }
1009 | .ui-icon-carat-1-se { background-position: -48px 0; }
1010 | .ui-icon-carat-1-s { background-position: -64px 0; }
1011 | .ui-icon-carat-1-sw { background-position: -80px 0; }
1012 | .ui-icon-carat-1-w { background-position: -96px 0; }
1013 | .ui-icon-carat-1-nw { background-position: -112px 0; }
1014 | .ui-icon-carat-2-n-s { background-position: -128px 0; }
1015 | .ui-icon-carat-2-e-w { background-position: -144px 0; }
1016 | .ui-icon-triangle-1-n { background-position: 0 -16px; }
1017 | .ui-icon-triangle-1-ne { background-position: -16px -16px; }
1018 | .ui-icon-triangle-1-e { background-position: -32px -16px; }
1019 | .ui-icon-triangle-1-se { background-position: -48px -16px; }
1020 | .ui-icon-triangle-1-s { background-position: -64px -16px; }
1021 | .ui-icon-triangle-1-sw { background-position: -80px -16px; }
1022 | .ui-icon-triangle-1-w { background-position: -96px -16px; }
1023 | .ui-icon-triangle-1-nw { background-position: -112px -16px; }
1024 | .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
1025 | .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
1026 | .ui-icon-arrow-1-n { background-position: 0 -32px; }
1027 | .ui-icon-arrow-1-ne { background-position: -16px -32px; }
1028 | .ui-icon-arrow-1-e { background-position: -32px -32px; }
1029 | .ui-icon-arrow-1-se { background-position: -48px -32px; }
1030 | .ui-icon-arrow-1-s { background-position: -64px -32px; }
1031 | .ui-icon-arrow-1-sw { background-position: -80px -32px; }
1032 | .ui-icon-arrow-1-w { background-position: -96px -32px; }
1033 | .ui-icon-arrow-1-nw { background-position: -112px -32px; }
1034 | .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
1035 | .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
1036 | .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
1037 | .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
1038 | .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
1039 | .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
1040 | .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
1041 | .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
1042 | .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
1043 | .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
1044 | .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
1045 | .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
1046 | .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
1047 | .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
1048 | .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
1049 | .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
1050 | .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
1051 | .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
1052 | .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
1053 | .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
1054 | .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
1055 | .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
1056 | .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
1057 | .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
1058 | .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
1059 | .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
1060 | .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
1061 | .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
1062 | .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
1063 | .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
1064 | .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
1065 | .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
1066 | .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
1067 | .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
1068 | .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
1069 | .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
1070 | .ui-icon-arrow-4 { background-position: 0 -80px; }
1071 | .ui-icon-arrow-4-diag { background-position: -16px -80px; }
1072 | .ui-icon-extlink { background-position: -32px -80px; }
1073 | .ui-icon-newwin { background-position: -48px -80px; }
1074 | .ui-icon-refresh { background-position: -64px -80px; }
1075 | .ui-icon-shuffle { background-position: -80px -80px; }
1076 | .ui-icon-transfer-e-w { background-position: -96px -80px; }
1077 | .ui-icon-transferthick-e-w { background-position: -112px -80px; }
1078 | .ui-icon-folder-collapsed { background-position: 0 -96px; }
1079 | .ui-icon-folder-open { background-position: -16px -96px; }
1080 | .ui-icon-document { background-position: -32px -96px; }
1081 | .ui-icon-document-b { background-position: -48px -96px; }
1082 | .ui-icon-note { background-position: -64px -96px; }
1083 | .ui-icon-mail-closed { background-position: -80px -96px; }
1084 | .ui-icon-mail-open { background-position: -96px -96px; }
1085 | .ui-icon-suitcase { background-position: -112px -96px; }
1086 | .ui-icon-comment { background-position: -128px -96px; }
1087 | .ui-icon-person { background-position: -144px -96px; }
1088 | .ui-icon-print { background-position: -160px -96px; }
1089 | .ui-icon-trash { background-position: -176px -96px; }
1090 | .ui-icon-locked { background-position: -192px -96px; }
1091 | .ui-icon-unlocked { background-position: -208px -96px; }
1092 | .ui-icon-bookmark { background-position: -224px -96px; }
1093 | .ui-icon-tag { background-position: -240px -96px; }
1094 | .ui-icon-home { background-position: 0 -112px; }
1095 | .ui-icon-flag { background-position: -16px -112px; }
1096 | .ui-icon-calendar { background-position: -32px -112px; }
1097 | .ui-icon-cart { background-position: -48px -112px; }
1098 | .ui-icon-pencil { background-position: -64px -112px; }
1099 | .ui-icon-clock { background-position: -80px -112px; }
1100 | .ui-icon-disk { background-position: -96px -112px; }
1101 | .ui-icon-calculator { background-position: -112px -112px; }
1102 | .ui-icon-zoomin { background-position: -128px -112px; }
1103 | .ui-icon-zoomout { background-position: -144px -112px; }
1104 | .ui-icon-search { background-position: -160px -112px; }
1105 | .ui-icon-wrench { background-position: -176px -112px; }
1106 | .ui-icon-gear { background-position: -192px -112px; }
1107 | .ui-icon-heart { background-position: -208px -112px; }
1108 | .ui-icon-star { background-position: -224px -112px; }
1109 | .ui-icon-link { background-position: -240px -112px; }
1110 | .ui-icon-cancel { background-position: 0 -128px; }
1111 | .ui-icon-plus { background-position: -16px -128px; }
1112 | .ui-icon-plusthick { background-position: -32px -128px; }
1113 | .ui-icon-minus { background-position: -48px -128px; }
1114 | .ui-icon-minusthick { background-position: -64px -128px; }
1115 | .ui-icon-close { background-position: -80px -128px; }
1116 | .ui-icon-closethick { background-position: -96px -128px; }
1117 | .ui-icon-key { background-position: -112px -128px; }
1118 | .ui-icon-lightbulb { background-position: -128px -128px; }
1119 | .ui-icon-scissors { background-position: -144px -128px; }
1120 | .ui-icon-clipboard { background-position: -160px -128px; }
1121 | .ui-icon-copy { background-position: -176px -128px; }
1122 | .ui-icon-contact { background-position: -192px -128px; }
1123 | .ui-icon-image { background-position: -208px -128px; }
1124 | .ui-icon-video { background-position: -224px -128px; }
1125 | .ui-icon-script { background-position: -240px -128px; }
1126 | .ui-icon-alert { background-position: 0 -144px; }
1127 | .ui-icon-info { background-position: -16px -144px; }
1128 | .ui-icon-notice { background-position: -32px -144px; }
1129 | .ui-icon-help { background-position: -48px -144px; }
1130 | .ui-icon-check { background-position: -64px -144px; }
1131 | .ui-icon-bullet { background-position: -80px -144px; }
1132 | .ui-icon-radio-on { background-position: -96px -144px; }
1133 | .ui-icon-radio-off { background-position: -112px -144px; }
1134 | .ui-icon-pin-w { background-position: -128px -144px; }
1135 | .ui-icon-pin-s { background-position: -144px -144px; }
1136 | .ui-icon-play { background-position: 0 -160px; }
1137 | .ui-icon-pause { background-position: -16px -160px; }
1138 | .ui-icon-seek-next { background-position: -32px -160px; }
1139 | .ui-icon-seek-prev { background-position: -48px -160px; }
1140 | .ui-icon-seek-end { background-position: -64px -160px; }
1141 | .ui-icon-seek-start { background-position: -80px -160px; }
1142 | /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
1143 | .ui-icon-seek-first { background-position: -80px -160px; }
1144 | .ui-icon-stop { background-position: -96px -160px; }
1145 | .ui-icon-eject { background-position: -112px -160px; }
1146 | .ui-icon-volume-off { background-position: -128px -160px; }
1147 | .ui-icon-volume-on { background-position: -144px -160px; }
1148 | .ui-icon-power { background-position: 0 -176px; }
1149 | .ui-icon-signal-diag { background-position: -16px -176px; }
1150 | .ui-icon-signal { background-position: -32px -176px; }
1151 | .ui-icon-battery-0 { background-position: -48px -176px; }
1152 | .ui-icon-battery-1 { background-position: -64px -176px; }
1153 | .ui-icon-battery-2 { background-position: -80px -176px; }
1154 | .ui-icon-battery-3 { background-position: -96px -176px; }
1155 | .ui-icon-circle-plus { background-position: 0 -192px; }
1156 | .ui-icon-circle-minus { background-position: -16px -192px; }
1157 | .ui-icon-circle-close { background-position: -32px -192px; }
1158 | .ui-icon-circle-triangle-e { background-position: -48px -192px; }
1159 | .ui-icon-circle-triangle-s { background-position: -64px -192px; }
1160 | .ui-icon-circle-triangle-w { background-position: -80px -192px; }
1161 | .ui-icon-circle-triangle-n { background-position: -96px -192px; }
1162 | .ui-icon-circle-arrow-e { background-position: -112px -192px; }
1163 | .ui-icon-circle-arrow-s { background-position: -128px -192px; }
1164 | .ui-icon-circle-arrow-w { background-position: -144px -192px; }
1165 | .ui-icon-circle-arrow-n { background-position: -160px -192px; }
1166 | .ui-icon-circle-zoomin { background-position: -176px -192px; }
1167 | .ui-icon-circle-zoomout { background-position: -192px -192px; }
1168 | .ui-icon-circle-check { background-position: -208px -192px; }
1169 | .ui-icon-circlesmall-plus { background-position: 0 -208px; }
1170 | .ui-icon-circlesmall-minus { background-position: -16px -208px; }
1171 | .ui-icon-circlesmall-close { background-position: -32px -208px; }
1172 | .ui-icon-squaresmall-plus { background-position: -48px -208px; }
1173 | .ui-icon-squaresmall-minus { background-position: -64px -208px; }
1174 | .ui-icon-squaresmall-close { background-position: -80px -208px; }
1175 | .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
1176 | .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
1177 | .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
1178 | .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
1179 | .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
1180 | .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
1181 |
1182 |
1183 | /* Misc visuals
1184 | ----------------------------------*/
1185 |
1186 | /* Corner radius */
1187 | .ui-corner-all,
1188 | .ui-corner-top,
1189 | .ui-corner-left,
1190 | .ui-corner-tl {
1191 | border-top-left-radius: 4px;
1192 | }
1193 | .ui-corner-all,
1194 | .ui-corner-top,
1195 | .ui-corner-right,
1196 | .ui-corner-tr {
1197 | border-top-right-radius: 4px;
1198 | }
1199 | .ui-corner-all,
1200 | .ui-corner-bottom,
1201 | .ui-corner-left,
1202 | .ui-corner-bl {
1203 | border-bottom-left-radius: 4px;
1204 | }
1205 | .ui-corner-all,
1206 | .ui-corner-bottom,
1207 | .ui-corner-right,
1208 | .ui-corner-br {
1209 | border-bottom-right-radius: 4px;
1210 | }
1211 |
1212 | /* Overlays */
1213 | .ui-widget-overlay {
1214 | background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
1215 | opacity: .3;
1216 | filter: Alpha(Opacity=30); /* support: IE8 */
1217 | }
1218 | .ui-widget-shadow {
1219 | margin: -8px 0 0 -8px;
1220 | padding: 8px;
1221 | background: #aaaaaa url("images/ui-bg_flat_0_aaaaaa_40x100.png") 50% 50% repeat-x;
1222 | opacity: .3;
1223 | filter: Alpha(Opacity=30); /* support: IE8 */
1224 | border-radius: 8px;
1225 | }
1226 |
--------------------------------------------------------------------------------
/Chrome Extension/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 2,
3 |
4 | "name": "Alizon",
5 | "description": "This extension reveals AliExpress offers on similar Amazon items when shopping!",
6 | "version": "1.1",
7 | "icons": {"16": "icon16.png",
8 | "48": "icon48.png",
9 | "128": "icon128.png"},
10 |
11 | "browser_action": {
12 | "default_icon": {"19": "active19.png",
13 | "38": "active38.png"},
14 | "default_popup": "popup.html"
15 | },
16 |
17 | "permissions": [
18 | "activeTab",
19 | "https://ajax.googleapis.com/"
20 | ],
21 |
22 | "background": {
23 | "scripts": ["background.js", "jquery-1.11.1.min.js"]
24 | },
25 |
26 | "web_accessible_resources": [
27 | "style.css",
28 | "modal.html",
29 | "modal-script.js"
30 | ],
31 |
32 | "content_scripts": [
33 | {
34 | "matches": [
35 | "http://*/*",
36 | "https://*/*"
37 | ],
38 | "js": ["jquery-1.11.1.min.js", "content.js"],
39 | "run_at": "document_start"
40 | }
41 | ]
42 |
43 | }
--------------------------------------------------------------------------------
/Chrome Extension/modal-script.js:
--------------------------------------------------------------------------------
1 | // When the user clicks anywhere outside of the modal, close it
2 | window.onclick = function(event) {
3 | if (event.target == document.getElementById("myModal")) {
4 | document.getElementById("myModal").style.display = "none";
5 | }
6 | }
--------------------------------------------------------------------------------
/Chrome Extension/modal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
Some text in the Modal Body
12 |
Some other text...
13 |
14 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Chrome Extension/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
Getting Started Extension's Popup
10 |
23 |
24 |
30 |
31 |
32 |
33 |
34 |
35 |
Helps score better deals on AliExpress if any are available.
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Chrome Extension/popup.js:
--------------------------------------------------------------------------------
1 | //toggles the state of status in localstorage
2 | //communicates to content.js with background.js as proxy
3 | function toggle(){
4 |
5 | var state = document.getElementById("toggle").innerText;
6 | console.log(state);
7 | if(state == "Turn On"){
8 |
9 | document.getElementById("toggle").innerHTML = "Turn Off";
10 |
11 | localStorage.status = "On";
12 |
13 | chrome.browserAction.setIcon({path: "active38.png"});
14 |
15 | } else if(state == "Turn Off"){
16 |
17 | document.getElementById("toggle").innerHTML = "Turn On";
18 |
19 | localStorage.status = "Off";
20 |
21 | chrome.browserAction.setIcon({path: "inactive38.png"});
22 |
23 | } else{
24 |
25 | throw "Unexpected toggle error";
26 |
27 | }
28 |
29 | }
30 |
31 | //waits until the page is fully loaded, then awaits click to toggle
32 | document.addEventListener('DOMContentLoaded', function() {
33 |
34 | if(!localStorage.status) localStorage.status = "On";
35 |
36 | //popup.html resets per window open/close
37 | //save state in localStore, then load the proper
38 | //attributes and image for the browserAction and popup
39 |
40 | var state = localStorage.status;
41 | var buttonState;
42 |
43 | if(state == "On"){
44 | buttonState = "Off";
45 | chrome.browserAction.setIcon({path: "active38.png"});
46 | } else{
47 | buttonState = "On";
48 | chrome.browserAction.setIcon({path: "inactive38.png"});
49 | }
50 |
51 | document.getElementById("toggle").innerHTML = "Turn " + buttonState;
52 |
53 | //wait for user click to toggle the button
54 | document.getElementById("toggle").addEventListener("click", toggle)
55 |
56 | });
57 |
58 |
--------------------------------------------------------------------------------
/Chrome Extension/style.css:
--------------------------------------------------------------------------------
1 | /* The Modal (background) */
2 | .modal {
3 | position: fixed; /* Stay in place */
4 | z-index: 1; /* Sit on top */
5 | left: 0;
6 | top: 0;
7 | width: 100%; /* Full width */
8 | height: 100%; /* Full height */
9 | overflow: auto; /* Enable scroll if needed */
10 | background-color: rgb(0,0,0); /* Fallback color */
11 | background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
12 | -webkit-animation-name: fadeIn; /* Fade in the background */
13 | -webkit-animation-duration: 0.4s;
14 | animation-name: fadeIn;
15 | animation-duration: 0.4s
16 | }
17 |
18 | /* Modal Content */
19 | .modal-content {
20 | position: fixed;
21 | right: 0;
22 | bottom: 0;
23 | background-color: #fefefe;
24 | width: 30%;
25 | -webkit-animation-name: slideIn;
26 | -webkit-animation-duration: 0.4s;
27 | animation-name: slideIn;
28 | animation-duration: 0.4s
29 | }
30 |
31 | /* The Close Button */
32 | .close {
33 | color: white;
34 | float: right;
35 | font-size: 28px;
36 | font-weight: bold;
37 | }
38 |
39 | .close:hover,
40 | .close:focus {
41 | color: #000;
42 | text-decoration: none;
43 | cursor: pointer;
44 | }
45 |
46 | .modal-header {
47 | padding: 2px 16px;
48 | background-color: #5cb85c;
49 | color: white;
50 | }
51 |
52 | .modal-body {padding: 2px 16px;}
53 |
54 | .modal-footer {
55 | padding: 2px 16px;
56 | background-color: #5cb85c;
57 | color: white;
58 | }
59 |
60 | /* Add Animation */
61 | @-webkit-keyframes slideIn {
62 | from {bottom: -300px; opacity: 0}
63 | to {bottom: 0; opacity: 1}
64 | }
65 |
66 | @keyframes slideIn {
67 | from {bottom: -300px; opacity: 0}
68 | to {bottom: 0; opacity: 1}
69 | }
70 |
71 | @-webkit-keyframes fadeIn {
72 | from {opacity: 0}
73 | to {opacity: 1}
74 | }
75 |
76 | @keyframes fadeIn {
77 | from {opacity: 0}
78 | to {opacity: 1}
79 | }
--------------------------------------------------------------------------------
/Chrome Extension/transparenticon128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winsonluk/Alizon/02ef84d0dbfb0e444257f57865de9a3c42af8229/Chrome Extension/transparenticon128.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Alizon: Cut out the Middleman
7 | ===========================
8 | Alizon lets you know if an Amazon item is not actually an Amazon item at all. Don't be fooled by the vague descriptions, unreliable pictures, and fake reviews; you are likely seeing a generic product from the Chinese website AliExpress.com that has been extravagently marked up for American consumers. Laptop chargers selling for $0.82 on AliExpress are advertised on Amazon for $14.95. Amazon resellers sell clothes hangers for $12.99/dozen, but you can find the identical item on AliExpress for $11.32/100. Trendy clothing is given a fancy description and a 300% premium for uninformed Westerners. Alizon protects you from predatory price gouging by letting you know if the Amazon item you're vieiwng can be purchased directly from the seller at AliExpress. Save money, save time, and cut out the middleman.
9 |
10 |

11 |
12 | Finding a Match
13 | ----------------------
14 | Alizon extracts an Amazon product's ASIN (Amazon Standard Identification Number) and uses the Amazon API to find more information about the product such as the title, price, and image. It then proceeds to conduct an exhaustive search of the item on AliExpress to find products with equivalent titles. Alizon uses the Python Imaging Library to intelligently find matches between the product images from Amazon and AliExpress, with images over a 95% match being considered the most seriously. An algorithm computes a confidence value of a match based on these results and returns the duplicate AliExpress item.
15 |
16 | Deploying the Software
17 | ------------------------------
18 | Almost everything in the Alizon works on Python 2.7. We've been using Python Flask module to provide a stable server for the requests. Our server is located on
https://pythonanywhere.com. Server takes in a link from a user (using JavaScript
Google Chrome Extension), then it processes the information given by
Amazon's api and goes through a thorough comparison with lots of products on Aliexpress. In order to find the best match among products, we have been using
Aliexpress Api,
PIL Library and some amount of computational libraries. On the client side, beyond JavaScript, we've been using
jQuery with Ajax.
19 |
20 |

21 |
--------------------------------------------------------------------------------
/aliexp.py:
--------------------------------------------------------------------------------
1 | from aliexpress_api_client import AliExpress
2 | import PIL
3 | from PIL import Image, ImageChops
4 | import urllib2 as urllib
5 | import io
6 | from itertools import izip
7 |
8 | from libImgComp import comp_imgs
9 |
10 |
11 |
12 | def comp_images(i1, i2):
13 | maxsize = (500, 500)
14 | i1.resize(maxsize)
15 | i2.resize(maxsize)
16 | i1 = i1.convert('RGB')
17 | i2 = i2.convert('RGB')
18 | return comp_imgs(i1, i2)
19 | '''pairs = izip(i1.getdata(), i2.getdata())
20 | if len(i1.getbands()) == 1:
21 | # for gray-scale jpegs
22 | dif = sum(abs(p1-p2) for p1,p2 in pairs)
23 | else:
24 | dif = sum(abs(c1-c2) for p1,p2 in pairs for c1,c2 in zip(p1,p2))
25 |
26 | ncomponents = i1.size[0] * i1.size[1] * 3
27 | return 100 - (dif / 255.0 * 100) / ncomponents'''
28 |
29 | import math, operator
30 |
31 | def process_str(s):
32 | s = s.replace('(', '')
33 | s = s.replace(')', '')
34 | s = s.replace('
', '')
35 | s = s.replace('', '')
36 | s = s.replace('
', '')
37 | s = s.replace('', '')
38 | s = s.replace('Generic', '')
39 | s = s.replace(',', '')
40 | s = s.replace('.', '')
41 | s = s.replace('-', '')
42 | s = s.replace('/', '')
43 | s = s.replace('\\', '')
44 | s = s.replace(' ', ' ')
45 | return s
46 |
47 | def rmsdiff(im1, im2):
48 | "Calculate the root-mean-square difference between two images"
49 | diff = ImageChops.difference(im1, im2)
50 | h = diff.histogram()
51 | sq = (value*((idx%256)**2) for idx, value in enumerate(h))
52 | sum_of_squares = sum(sq)
53 | rms = math.sqrt(sum_of_squares/float(im1.size[0] * im1.size[1]))
54 | return rms
55 |
56 | def strdiff(s1, s2):
57 | s1 = s1.lower()
58 | s2 = s2.lower()
59 | count = 0
60 | l1 = s1.split(' ')
61 | for item in l1:
62 | if (s2.find(item) != -1):
63 | count += 1
64 |
65 | return count
66 |
67 | def get_perc(mi, ma, va):
68 | if (mi == ma):
69 | for item in va:
70 | yield 100.0
71 | else:
72 | for item in va:
73 | yield (((item - mi)/(ma - mi)))*100
74 |
75 |
76 | def get_perc_w(mi, ma, va):
77 | if (mi == ma):
78 | for item in va:
79 | yield 100.0
80 | else:
81 | for item in va:
82 | n = (item/ma)*100
83 | yield n
84 |
85 | def get_max_ind(a):
86 | x = max(a)
87 | for i in range(len(a)):
88 | if (a[i] >= x - 15):
89 | yield i
90 |
91 | def get_min_ind(a):
92 | x = min(a)
93 | for i in range(len(a)):
94 | if (a[i] <= x + 15):
95 | return i
96 |
97 | def get_m_i(a):
98 | x = max(a)
99 | for i in range(len(a)):
100 | if (a[i] == x):
101 | return i
102 |
103 |
104 | def get_avg(st, img):
105 | return (1.7*st + 0.3*img) / 2.0
106 |
107 | def price_float(s):
108 | return float(s[4:])
109 |
110 | def eval_p(prices, or_p):
111 | for price in prices:
112 | print str(price) + ' <- PRICE'
113 | print str(or_p) + ' <- OR_PRICE'
114 | if (5*price > (or_p - price) and price >= 0.45*or_p):
115 | print 'GOT ' + str(price)
116 | yield price
117 |
118 | def get_pairs(li):
119 | for i in range(len(li)-1):
120 | yield li[i] + ' ' + li[i + 1]
121 |
122 | def get_pairs_strict(li):
123 | for i in range(len(li)/2):
124 | yield li[2*i] + ' ' + li[2*i + 1]
125 |
126 | def get_all_maxs(li):
127 | m = max(li)
128 | for i in range(len(li)):
129 | if li[i] == m:
130 | yield i
131 |
132 | def get_all_mins(li):
133 | m = min([n for n in li if n>0])
134 | for i in range(len(li)):
135 | if li[i] == m:
136 | yield i
137 |
138 | def get_all_maxs_mild(li):
139 | m = max(li)
140 | for i in range(len(li)):
141 | if li[i] >= m - 10:
142 | yield i
143 |
144 | def get_all_mins_mild(li):
145 | m = min([n for n in li if n>0])
146 | for i in range(len(li)):
147 | if li[i] <= m + 10:
148 | yield i
149 |
150 |
151 | def process_pr(li, t):
152 | for i in li:
153 | if i > t:
154 | yield -1
155 | else:
156 | yield i
157 |
158 |
159 | def calc_result(s_item, or_price, or_img):
160 | # print 'starting Daniils part'
161 | COEFF = 0.7
162 | s_item = process_str(s_item)
163 | item_copy = s_item
164 | aliexpress = AliExpress('YOUR_CODE_HERE')
165 |
166 | '''while (not_working):
167 | try:
168 | print ' '.join(s_item.split(' ')[:-count])
169 | products = aliexpress.get_product_list(['productTitle', 'salePrice', 'imageUrl', 'productUrl'], ' '.join(s_item.split(' ')[0:-count]))['products']
170 | cur_len = len(products)
171 | print cur_len
172 | if ((cur_len < old_len or cur_len >= 15) and count >= 3):
173 | if (cur_len < old_len):
174 | products = aliexpress.get_product_list(['productTitle', 'salePrice', 'imageUrl', 'productUrl'], ' '.join(s_item.split(' ')[0:-(count - 1)]))['products']
175 | print 'disabling'
176 | not_working = False
177 | else:
178 | raise ValueError(' fff ')
179 | except:
180 | count += 1;
181 | old_len = cur_len
182 | if (count + 1 == len(item_copy.split(' '))):
183 | break
184 | #print ' '.join(s_item.split(' ')[:count])'''
185 | done = False
186 | old_len = 0
187 | cur_len = 0
188 | products = {}
189 | le_s = len(item_copy.split(' '))
190 | search_query = s_item.split(' ')
191 |
192 |
193 | previous_max = 20
194 |
195 |
196 | #a = raw_input()
197 | while (not done):
198 | count = 0
199 | print "Going into the next lap"
200 | print search_query
201 | lens_titles = []
202 | lens_values = []
203 | if (len(search_query) != 1):
204 | search_query = list(get_pairs(search_query))
205 | max_count = len(search_query)
206 | while (count < max_count):
207 | products = aliexpress.get_product_list(['productTitle', 'salePrice', 'imageUrl', 'productUrl'], search_query[count],
208 | originalPriceFrom=str(or_price*COEFF), sort="orignalPriceUp")['products']
209 | lens_titles.append(search_query[count])
210 | lens_values.append(len(products))
211 | count += 1
212 |
213 | maxs_i = list(get_all_maxs(lens_values))
214 | print '--------------------------------'
215 | #print maxs_i
216 | if (len(maxs_i) == 0 or lens_values[maxs_i[0]] == 0):
217 | #print maxs_i
218 | #print lens_values[maxs_i[0]]
219 | search_query = list(get_pairs_strict(final_search_query))
220 | print 'Shutting down'
221 | done = True
222 | elif (len(maxs_i) == 1 and lens_values[maxs_i[0]] >= 2):
223 | search_query = [lens_titles[maxs_i[0]]]
224 | #print maxs_i
225 | #print lens_values
226 | print 'Shutting down - one good result'
227 | done = True
228 | elif (len(maxs_i) == 1 and lens_values[maxs_i[0]] < 2):
229 | search_query = list(get_pairs_strict(final_search_query))
230 | #print maxs_i
231 | #print lens_values
232 | print 'Shutting down - one bad result'
233 | done = True
234 | else:
235 | search_query = []
236 | #print maxs_i
237 | print 'Keeping on'
238 | if (len(maxs_i) >= 2 and lens_values[maxs_i[0]] != 0):
239 | final_search_query = []
240 | for item in maxs_i:
241 | k = len(lens_titles[item].split(' '))
242 | final_search_query.append(' '.join(lens_titles[item].split(' ')[:k/2]))
243 |
244 | final_search_query.append(' '.join(lens_titles[-1].split(' ')[k/2+1:]))
245 | search_query = list(get_pairs_strict(final_search_query))
246 |
247 |
248 |
249 |
250 | #printing the result
251 | '''
252 | for item in search_query:
253 | products = aliexpress.get_product_list(['productTitle', 'salePrice', 'imageUrl', 'productUrl'], item)['products']
254 | print '----------------------------------------------------------------------'
255 | print item
256 | print len(products)
257 | for i in products:
258 | print i['productTitle']
259 | '''
260 | links = []
261 | prices = []
262 | perc = []
263 | diffs = []
264 | print search_query
265 | print 'STARTING CHECK FOR EACH POS ...'
266 | for s in search_query:
267 | print 'INPUT:'
268 | print s
269 | products = aliexpress.get_product_list(['productTitle', 'salePrice', 'imageUrl', 'productUrl'], s,
270 | originalPriceFrom=str(or_price*COEFF), sort="orignalPriceUp")['products']
271 | print len(products)
272 | #a = raw_input()
273 | l, p, perct, diff = search(products, item_copy, or_price, or_img)
274 | links.extend(l)
275 | prices.extend(p)
276 | perc.extend(perct)
277 | diffs.extend(diff)
278 |
279 |
280 |
281 |
282 | max_perc = list(get_all_maxs_mild(perc))
283 | min_prices = list(get_all_mins_mild(prices))
284 |
285 | print 'ORIG PR : ' + str(or_price)
286 | result = list(set(max_perc).intersection(min_prices))
287 | print 'MAX PERC:'
288 | print max_perc
289 | print 'MIN PRC:'
290 | print min_prices
291 | prices = list(process_pr(prices, or_price))
292 | print prices
293 | print 'RES:'
294 | print result
295 |
296 | result_perc = []
297 |
298 | for item in result:
299 | print links[item]
300 | print prices[item]
301 | print perc[item]
302 | result_perc.append(perc[item])
303 |
304 | if (len(result) != 0):
305 | final_ind = get_m_i(result_perc)
306 | fin = result[final_ind]
307 |
308 |
309 | #a = raw_input()
310 | if (len(result) != 0):
311 | return links[fin], prices[fin], diffs[fin]
312 | else:
313 | return links[min_prices[0]], prices[min_prices[0]], diffs[min_prices[0]]
314 |
315 |
316 |
317 | def search(products, s_item, or_price, or_img):
318 | print 'Starting search...'
319 | #print len(products)
320 | #try:
321 | #print or_img
322 | fd = urllib.urlopen(or_img)
323 | orig_img_link = io.BytesIO(fd.read())
324 | orig_img = Image.open(orig_img_link)
325 |
326 |
327 |
328 | #except:
329 | #orig_img_link = cStringIO.StringIO(urllib.urlopen('http://cs617219.vk.me/v617219415/c9c4/KUCX_V8m7CQ.jpg').read())
330 | #orig_img = Image.open(orig_img_link)
331 |
332 | titles = []
333 | image_diffs = []
334 | img_data = []
335 |
336 | #i = 0;
337 | for item in products:
338 | #i += 1;
339 | #img.show()
340 | #print process_str(item['productTitle'])
341 | titles.append(process_str(item['productTitle']))
342 | try:
343 | #print item['productTitle'] + item['salePrice'] + '\n' + item['imageUrl'] + '\n'
344 | fd = urllib.urlopen(item['imageUrl'])
345 | img_link = io.BytesIO(fd.read())
346 | img = Image.open(img_link)
347 | #image_diffs.append(rmsdiff(img, orig_img))
348 | #print comp_images(orig_img, img)
349 | img_data.append(comp_images(orig_img, img))
350 | #a = raw_input();
351 | #print i
352 | #print '___________________________________________________________________________'
353 | except:
354 | img_data.append(50)
355 |
356 | string_diffs = map(strdiff, titles, [s_item]*len(titles))
357 | max_strdiff = float(max(string_diffs))
358 | # max_imgdiff = float(max(image_diffs))
359 | min_strdiff = float(min(string_diffs))
360 | # min_imgdiff = float(min(image_diffs))
361 | #print 'CHECK IMG DATA'
362 | #print img_data
363 | #print 'MIN'
364 | #print min(img_data)
365 | #print 'MAX'
366 | #print max(img_data)
367 |
368 | str_data = list(get_perc_w(min_strdiff, max_strdiff, string_diffs))
369 | img_data = list(get_perc(min(img_data), max(img_data), img_data))
370 |
371 | comp_data = map(get_avg, str_data, img_data)
372 |
373 |
374 |
375 | #print "word matches: "
376 | #print str_data
377 | #print "images:"
378 | #print img_data
379 | #print "comp:"
380 | #print comp_data
381 |
382 | ids = list(get_max_ind(comp_data))
383 |
384 | #print 'IDs'
385 | #print ids
386 |
387 |
388 | urls = []
389 | prices = []
390 | percs = []
391 | diffs = []
392 | for item in ids:
393 | urls.append(products[item]['productUrl'])
394 | prices.append(price_float(products[item]['salePrice']))
395 | percs.append(comp_data[item])
396 | diffs.append(or_price - price_float(products[item]['salePrice']))
397 |
398 | print urls
399 | print prices
400 | print percs
401 | print diffs
402 |
403 | #'''or (or_price - new_price > 5*new_price) or comp_data[ids[get_min_ind(prices)]] < 50'''
404 |
405 | return urls, prices, percs, diffs
406 |
407 |
408 |
--------------------------------------------------------------------------------
/docs/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winsonluk/Alizon/02ef84d0dbfb0e444257f57865de9a3c42af8229/docs/.DS_Store
--------------------------------------------------------------------------------
/docs/images/comparisons.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winsonluk/Alizon/02ef84d0dbfb0e444257f57865de9a3c42af8229/docs/images/comparisons.gif
--------------------------------------------------------------------------------
/docs/images/keyboard.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winsonluk/Alizon/02ef84d0dbfb0e444257f57865de9a3c42af8229/docs/images/keyboard.gif
--------------------------------------------------------------------------------
/docs/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winsonluk/Alizon/02ef84d0dbfb0e444257f57865de9a3c42af8229/docs/images/logo.png
--------------------------------------------------------------------------------
/docs/images/logo_shiny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winsonluk/Alizon/02ef84d0dbfb0e444257f57865de9a3c42af8229/docs/images/logo_shiny.png
--------------------------------------------------------------------------------
/libImgComp.py:
--------------------------------------------------------------------------------
1 | from itertools import izip
2 | from PIL import Image
3 | import time
4 | import math, operator
5 |
6 | def comp_imgs(im1, im2):
7 | i1 = im1.convert('RGB')
8 | i2 = im2.convert('RGB')
9 | print i1.size, i2.size
10 | i1 = i1.resize((200, 200), Image.ANTIALIAS)
11 | i2 = i2.resize((200, 200), Image.ANTIALIAS)
12 | print i1.size, i2.size
13 |
14 | h1 = i1.histogram()
15 | h2 = i2.histogram()
16 |
17 | rms = math.sqrt(reduce(operator.add,
18 | map(lambda a,b: (a-b)**2, h1, h2))/len(h1))
19 |
20 | #i1.save("temp1.png", "PNG")
21 | #i2.save("temp2.png", "PNG")
22 |
23 | print rms
24 |
25 | #a = raw_input()
26 | return rms
27 |
28 | def comp_imgs2(im1, im2):
29 | i1 = im1.convert('RGB')
30 | i2 = im2.convert('RGB')
31 | i1.resize((400,400))
32 | i2.resize((400,400))
33 | #print 'SIZE'
34 | #print i1.size, i2.size
35 |
36 | i1.save("temp1.png", "PNG")
37 | i2.save("temp2.png", "PNG")
38 | pairs = izip(i1.getdata(), i2.getdata())
39 | if len(i1.getbands()) == 1:
40 | dif = sum(abs(p1-p2) for p1,p2 in pairs)
41 | else:
42 | dif = sum(abs(c1-c2) for p1,p2 in pairs for c1,c2 in zip(p1,p2))
43 |
44 | ncomponents = i1.size[0] * i1.size[1] * 3
45 | print 100 - (dif / 255.0 * 100) / ncomponents
46 | a = raw_input()
47 | return 100 - (dif / 255.0 * 100) / ncomponents
48 |
--------------------------------------------------------------------------------
/server.py:
--------------------------------------------------------------------------------
1 | from flask import Flask
2 | from Alizon import main
3 | import json
4 |
5 | app = Flask(__name__)
6 |
7 | @app.route("/")
8 | def home():
9 | return "first page"
10 |
11 | @app.route("/getInfo", methods=['POST'])
12 | def getInfo():
13 | link = request.args['link']
14 | res = main('https://www.amazon.com/Apple-iPhone-5S-Certified-Refurbished/dp/B00YD53YQU/ref=sr_1_1?s=wireless&ie=UTF8&qid=1484390983&sr=1-1&keywords=iphone')
15 | return json.dumps({'link':res})
16 | if __name__ == "__main__":
17 | app.run()
18 |
--------------------------------------------------------------------------------