Guest User

Untitled

a guest
Apr 4th, 2020
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // hardcoded server config for auto scaling in case cloud config isn't available
  2. var serversConfig = {
  3.     "undefined":true, "sundefined":true, "s1":true, "s2":true, "s3":true, "s4":true, "s5":true, "s6":true, "s7":true, "s8":true, "s9":true,
  4.     "s10":true, "s11":true, "s12":true, "s13":true, "s14":true, "s15":true, "s16":true, "s17":true, "s18":true, "s19":true,
  5.     "s20":true, "s21":true, "s22":true, "s23":true, "s24":true, "s25":true, "s26":true, "s27":true, "s28":true, "s29":true,
  6.     "s30":true, "s31":true, "s32":true, "s33":true, "s34":true, "s35":true, "s36":true, "s37":true, "s38":true, "s39":true,
  7.     "s40":true, "s41":true, "s42":true, "s43":true, "s44":true, "s45":true, "s46":true, "s47":true, "s48":true, "s49":true,
  8.     "s50":true, "s51":true, "s52":true, "s53":true, "s54":true, "s55":true, "s56":true, "s57":true, "s58":true, "s59":true,
  9.     "s60":true, "s61":true, "s62":true, "s63":true, "s64":true, "s65":true, "s66":true, "s67":true, "s68":true, "s69":true,
  10.     "s70":true, "s71":true, "s72":true, "s73":true, "s74":true, "s75":true, "s76":true, "s77":true, "s78":true, "s79":true,
  11.     "s80":true, "s81":true, "s82":true, "s83":true, "s84":true, "s85":true, "s86":true, "s87":true, "s88":true, "s89":true,
  12.     "s90":true, "s91":true, "s92":true, "s93":true, "s94":true, "s95":true, "s96":true, "s97":true, "s98":true, "s99":true,
  13.     "s100":true, "s101":true, "s102":true, "s103":true, "s104":true, "s105":true, "s106":true, "s107":true, "s108":true, "s109":true,
  14.     "s110":true, "s111":true, "s112":true, "s113":true, "s114":true, "s115":true, "s116":true, "s117":true, "s118":true, "s119":true,
  15.     "s120":true, "s121":true, "s122":true, "s123":true, "s124":true, "s125":true, "s126":true, "s127":true, "s128":true, "s129":true,
  16.     "s130":true, "s131":true, "s132":true, "s133":true, "s134":true, "s135":true, "s136":true, "s137":true, "s138":true, "s139":true,
  17.     "s140":true, "s141":true, "s142":true, "s143":true, "s144":true, "s145":true, "s146":true, "s147":true, "s148":true, "s149":true,
  18.     "s150":true, "s151":true, "s152":true, "s153":true, "s154":true, "s155":true, "s156":true, "s157":true, "s158":true, "s159":true,
  19.     "s160":true, "s161":true, "s162":true, "s163":true, "s164":true, "s165":true, "s166":true, "s167":true, "s168":true, "s169":true,
  20.     "s170":true, "s171":true, "s172":true, "s173":true, "s174":true, "s175":true, "s176":true, "s177":true, "s178":true, "s179":true,
  21.     "s180":true, "s181":true, "s182":true, "s183":true, "s184":true, "s185":true, "s186":true, "s187":true, "s188":true, "s189":true,
  22.     "s190":true, "s191":true, "s192":true, "s193":true, "s194":true, "s195":true, "s196":true, "s197":true, "s198":true, "s199":true,
  23.     "s200":true, "s201":true, "s202":true, "s203":true, "s204":true, "s205":true, "s206":true, "s207":true, "s208":true, "s209":true,
  24.     "s210":true, "s211":true, "s212":true, "s213":true, "s214":true, "s215":true, "s216":true, "s217":true, "s218":true, "s219":true,
  25.     "s220":true, "s221":true, "s222":true, "s223":true, "s224":true, "s225":true, "s226":true, "s227":true, "s228":true, "s229":true,
  26.     "s230":true, "s231":true, "s232":true, "s233":true, "s234":true, "s235":true, "s236":true, "s237":true, "s238":true, "s239":true,
  27.     "s240":true, "s241":true, "s242":true, "s243":true, "s244":true, "s245":true, "s246":true, "s247":true, "s248":true, "s249":true,
  28.     "s250":true, "s251":true, "s252":true, "s253":true, "s254":true, "s255":true, "s256":true, "s257":true, "s258":true, "s259":true,
  29.     "s260":true, "s261":true, "s262":true, "s263":true, "s264":true, "s265":true, "s266":true, "s267":true, "s268":true, "s269":true,
  30.     "s270":true, "s271":true, "s272":true, "s273":true, "s274":true, "s275":true, "s276":true, "s277":true, "s278":true, "s279":true,
  31.     "s280":true, "s281":true, "s282":true, "s283":true, "s284":true, "s285":true, "s286":true, "s287":true, "s288":true, "s289":true,
  32.     "s290":true, "s291":true, "s292":true, "s293":true, "s294":true, "s295":true, "s296":true, "s297":true, "s298":true, "s299":true,
  33.     "s300":true, "s301":true, "s302":true, "s303":true, "s304":true, "s305":true, "s306":true, "s307":true, "s308":true, "s309":true,
  34.     "s310":true, "s311":true, "s312":true, "s313":true, "s314":true, "s315":true, "s316":true, "s317":true, "s318":true, "s319":true,
  35.     "s320":true, "s321":true, "s322":true, "s323":true, "s324":true, "s325":true, "s326":true, "s327":true, "s328":true, "s329":true,
  36.     "s330":true, "s331":true, "s332":true, "s333":true, "s334":true, "s335":true, "s336":true, "s337":true, "s338":true, "s339":true,
  37.     "s340":true, "s341":true, "s342":true, "s343":true, "s344":true, "s345":true, "s346":true, "s347":true, "s348":true, "s349":true,
  38.     "s350":true, "s351":true, "s352":true, "s353":true, "s354":true, "s355":true, "s356":true, "s357":true, "s358":true, "s359":true,
  39.     "s360":true, "s361":true, "s362":true, "s363":true, "s364":true, "s365":true, "s366":true, "s367":true, "s368":true, "s369":true,
  40.     "s370":true, "s371":true, "s372":true, "s373":true, "s374":true, "s375":true, "s376":true, "s377":true, "s378":true, "s379":true,
  41.     "s380":true, "s381":true, "s382":true, "s383":true, "s384":true, "s385":true, "s386":true, "s387":true, "s388":true, "s389":true,
  42.     "s390":true, "s391":true, "s392":true, "s393":true, "s394":true, "s395":true, "s396":true, "s397":true, "s398":true, "s399":true,
  43.     "s400":true, "s401":true, "s402":true, "s403":true, "s404":true, "s405":true, "s406":true, "s407":true, "s408":true, "s409":true,
  44.     "s410":true, "s411":true, "s412":true, "s413":true, "s414":true, "s415":true, "s416":true, "s417":true, "s418":true, "s419":true,
  45.     "s420":true, "s421":true, "s422":true, "s423":true, "s424":true, "s425":true, "s426":true, "s427":true, "s428":true, "s429":true,
  46.     "s430":true, "s431":true, "s432":true, "s433":true, "s434":true, "s435":true, "s436":true, "s437":true, "s438":true, "s439":true,
  47.     "s440":true, "s441":true, "s442":true, "s443":true, "s444":true, "s445":true, "s446":true, "s447":true, "s448":true, "s449":true,
  48.     "s450":true, "s451":true, "s452":true, "s453":true, "s454":true, "s455":true, "s456":true, "s457":true, "s458":true, "s459":true,
  49.     "s460":true, "s461":true, "s462":true, "s463":true, "s464":true, "s465":true, "s466":true, "s467":true, "s468":true, "s469":true,
  50.     "s470":true, "s471":true, "s472":true, "s473":true, "s474":true, "s475":true, "s476":true, "s477":true, "s478":true, "s479":true,
  51.     "s480":true, "s481":true, "s482":true, "s483":true, "s484":true, "s485":true, "s486":true, "s487":true, "s488":true, "s489":true,
  52.     "s490":true, "s491":true, "s492":true, "s493":true, "s494":true, "s495":true, "s496":true, "s497":true, "s498":true, "s499":true,
  53.     "s500":true, "s501":true, "s502":true, "s503":true, "s504":true, "s505":true, "s506":true, "s507":true, "s508":true, "s509":true,
  54.     "s510":true, "s511":true, "s512":true, "s513":true, "s514":true, "s515":true, "s516":true, "s517":true, "s518":true, "s519":true,
  55.     "s520":true, "s521":true, "s522":true, "s523":true, "s524":true, "s525":true, "s526":true, "s527":true, "s528":true, "s529":true,
  56.     "s530":true, "s531":true, "s532":true, "s533":true, "s534":true, "s535":true, "s536":true, "s537":true, "s538":true, "s539":true,
  57.     "s540":true, "s541":true, "s542":true, "s543":true, "s544":true, "s545":true, "s546":true, "s547":true, "s548":true, "s549":true,
  58.     "s550":true, "s551":true, "s552":true, "s553":true, "s554":true, "s555":true, "s556":true, "s557":true, "s558":true, "s559":true,
  59.     "s560":true, "s561":true, "s562":true, "s563":true, "s564":true, "s565":true, "s566":true, "s567":true, "s568":true, "s569":true,
  60.     "s570":true, "s571":true, "s572":true, "s573":true, "s574":true, "s575":true, "s576":true, "s577":true, "s578":true, "s579":true,
  61.     "s580":true, "s581":true, "s582":true, "s583":true, "s584":true, "s585":true, "s586":true, "s587":true, "s588":true, "s589":true,
  62.     "s590":true, "s591":true, "s592":true, "s593":true, "s594":true, "s595":true, "s596":true, "s597":true, "s598":true, "s599":true,
  63.     "s600":true, "s601":true, "s602":true, "s603":true, "s604":true, "s605":true, "s606":true, "s607":true, "s608":true, "s609":true,
  64.     "s610":true, "s611":true, "s612":true, "s613":true, "s614":true, "s615":true, "s616":true, "s617":true, "s618":true, "s619":true,
  65.     "s620":true, "s621":true, "s622":true, "s623":true, "s624":true, "s625":true, "s626":true, "s627":true, "s628":true, "s629":true,
  66.     "s630":true, "s631":true, "s632":true, "s633":true, "s634":true, "s635":true, "s636":true, "s637":true, "s638":true, "s639":true,
  67.     "s640":true, "s641":true, "s642":true, "s643":true, "s644":true, "s645":true, "s646":true, "s647":true, "s648":true, "s649":true,
  68.     "s650":true, "s651":true, "s652":true, "s653":true, "s654":true, "s655":true, "s656":true, "s657":true, "s658":true, "s659":true,
  69.     "s660":true, "s661":true, "s662":true, "s663":true, "s664":true, "s665":true, "s666":true, "s667":true, "s668":true, "s669":true,
  70.     "s670":true, "s671":true, "s672":true, "s673":true, "s674":true, "s675":true, "s676":true, "s677":true, "s678":true, "s679":true,
  71.     "s680":true, "s681":true, "s682":true, "s683":true, "s684":true, "s685":true, "s686":true, "s687":true, "s688":true, "s689":true,
  72.     "s690":true, "s691":true, "s692":true, "s693":true, "s694":true, "s695":true, "s696":true, "s697":true, "s698":true, "s699":true,
  73.     "s700":true, "s701":true, "s702":true, "s703":true, "s704":true, "s705":true, "s706":true, "s707":true, "s708":true, "s709":true,
  74.     "s710":true, "s711":true, "s712":true, "s713":true, "s714":true, "s715":true, "s716":true, "s717":true, "s718":true, "s719":true,
  75.     "s720":true, "s721":true, "s722":true, "s723":true, "s724":true, "s725":true, "s726":true, "s727":true, "s728":true, "s729":true,
  76.     "s730":true, "s731":true, "s732":true, "s733":true, "s734":true, "s735":true, "s736":true, "s737":true, "s738":true, "s739":true,
  77.     "s740":true, "s741":true, "s742":true, "s743":true, "s744":true, "s745":true, "s746":true, "s747":true, "s748":true, "s749":true,
  78.     "s750":true, "s751":true, "s752":true, "s753":true, "s754":true, "s755":true, "s756":true, "s757":true, "s758":true, "s759":true,
  79.     "s760":true, "s761":true, "s762":true, "s763":true, "s764":true, "s765":true, "s766":true, "s767":true, "s768":true, "s769":true,
  80.     "s770":true, "s771":true, "s772":true, "s773":true, "s774":true, "s775":true, "s776":true, "s777":true, "s778":true, "s779":true,
  81.     "s780":true, "s781":true, "s782":true, "s783":true, "s784":true, "s785":true, "s786":true, "s787":true, "s788":true, "s789":true,
  82.     "s790":true, "s791":true, "s792":true, "s793":true, "s794":true, "s795":true, "s796":true, "s797":true, "s798":true, "s799":true                       
  83. };
  84.  
  85.  
  86. var optionsConfig = [
  87.     's1', 's2', 's4', 's5', 's6', 's7', 's8', 's9',
  88.     's10', 's11', 's12', 's13', 's14', 's15', 's16', 's17', 's18', 's19',
  89.     's20', 's21', 's22', 's23', 's25', 's26', 's27', 's28', 's29',
  90.     's30', 's31', 's32', 's33', 's34', 's35', 's36', 's37', 's38', 's39',
  91.     's40', 's41', 's42', 's43', 's44', 's45', 's46', 's47', 's48', 's49',
  92.     's50', 's51', 's52', 's53', 's54', 's55', 's56', 's57', 's58', 's59',
  93.     's60', 's61', 's62', 's63', 's64', 's65', 's66', 's67', 's68', 's69',
  94.     's70', 's71', 's72', 's73', 's74', 's75', 's76', 's77', 's78', 's79',
  95.     's80', 's81', 's82', 's83', 's84', 's85', 's86', 's87', 's88', 's89',
  96.     's90', 's91', 's92', 's93', 's94', 's95', 's96', 's97', 's98', 's99',
  97.     's100', 's101', 's102', 's103', 's104', 's105', 's106', 's107', 's108', 's109',
  98.     's110', 's111', 's112', 's113', 's114', 's115', 's116', 's117', 's118', 's119',
  99.     's130', 's131', 's132', 's133', 's134', 's135', 's136', 's137', 's138', 's139',
  100.     's140', 's141', 's142', 's143', 's144', 's145', 's146', 's147', 's148', 's149',
  101.     's150', 's151', 's152', 's153', 's154', 's155', 's156', 's157', 's158', 's159',
  102.     's160', 's161', 's162', 's163', 's164', 's165', 's166', 's167', 's168', 's169',
  103.     's170', 's171', 's172', 's173', 's174', 's175', 's176', 's177', 's178', 's179',
  104.     's180', 's181', 's182', 's183', 's184', 's185', 's186', 's187', 's188', 's189',
  105.     's190', 's191', 's192', 's193', 's194', 's195', 's196', 's197', 's198', 's199'
  106. ];
  107.  
  108.     // 's70', 's71', 's72', 's73', 's74', 's75', 's76', 's77', 's78', 's79',
  109.     // 's80', 's81', 's82', 's83', 's84', 's85', 's86', 's87', 's88', 's89',
  110.     // 's90', 's91', 's92', 's93', 's94', 's95', 's96', 's97', 's98', 's99',
  111.     // 's100', 's101', 's102', 's103', 's104', 's105', 's106', 's107', 's108', 's109',
  112.     // 's110', 's111', 's112', 's113', 's114', 's115', 's116', 's117', 's118', 's119',
  113.     // 's120', 's121', 's122', 's123', 's124', 's125', 's126', 's127', 's128', 's129'
  114.  
  115. // var serverSettings = {};
  116. // serverSettings.servers = serversConfig;
  117. // serverSettings.defaultServerOptions = optionsConfig;
  118. // console.log(JSON.stringify(serverSettings));
  119.  
  120.  
  121. // can't use strict mode for this file because of socket.io
  122. var injectContentScript = function(defaultServerOptions=optionsConfig, servers=serversConfig) {
  123.   // console.log('content script server options: ' + JSON.stringify(defaultServerOptions));
  124.   // console.log('content script server options: ' + JSON.stringify(serversConfig));
  125.  
  126.   // make sure the content script is only run once on the page
  127.   if (!window.netflixPartyLoaded) {
  128.     window.netflixPartyLoaded = true;
  129.  
  130.     //////////////////////////////////////////////////////////////////////////
  131.     // Vendor libraries                                                     //
  132.     //////////////////////////////////////////////////////////////////////////
  133.  
  134.     /*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
  135.     !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){
  136.     return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ia={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qa[0].contentDocument,b.write(),b.close(),c=sa(a,b),qa.detach()),ra[a]=c),c}var ua=/^margin/,va=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wa=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)};function xa(a,b,c){var d,e,f,g,h=a.style;return c=c||wa(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),va.test(g)&&ua.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function ya(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),f.removeChild(c),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var za=/^(none|table(?!-c[ea]).+)/,Aa=new RegExp("^("+Q+")(.*)$","i"),Ba=new RegExp("^([+-])=("+Q+")","i"),Ca={position:"absolute",visibility:"hidden",display:"block"},Da={letterSpacing:"0",fontWeight:"400"},Ea=["Webkit","O","Moz","ms"];function Fa(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Ea.length;while(e--)if(b=Ea[e]+c,b in a)return b;return d}function Ga(a,b,c){var d=Aa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Ha(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ia(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wa(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xa(a,b,f),(0>e||null==e)&&(e=a.style[b]),va.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Ha(a,b,c||(g?"border":"content"),d,f)+"px"}function Ja(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",ta(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xa(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fa(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Ba.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fa(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xa(a,b,d)),"normal"===e&&b in Da&&(e=Da[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?za.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Ca,function(){return Ia(a,b,d)}):Ia(a,b,d):void 0},set:function(a,c,d){var e=d&&wa(a);return Ga(a,c,d?Ha(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=ya(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ua.test(a)||(n.cssHooks[a+b].set=Ga)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wa(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Ja(this,!0)},hide:function(){return Ja(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Ka(a,b,c,d,e){return new Ka.prototype.init(a,b,c,d,e)}n.Tween=Ka,Ka.prototype={constructor:Ka,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ka.propHooks[this.prop];return a&&a.get?a.get(this):Ka.propHooks._default.get(this)},run:function(a){var b,c=Ka.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ka.propHooks._default.set(this),this}},Ka.prototype.init.prototype=Ka.prototype,Ka.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Ka.propHooks.scrollTop=Ka.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Ka.prototype.init,n.fx.step={};var La,Ma,Na=/^(?:toggle|show|hide)$/,Oa=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pa=/queueHooks$/,Qa=[Va],Ra={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Oa.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Oa.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sa(){return setTimeout(function(){La=void 0}),La=n.now()}function Ta(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ua(a,b,c){for(var d,e=(Ra[b]||[]).concat(Ra["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Va(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||ta(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Na.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?ta(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ua(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wa(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xa(a,b,c){var d,e,f=0,g=Qa.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=La||Sa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:La||Sa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wa(k,j.opts.specialEasing);g>f;f++)if(d=Qa[f].call(j,a,k,j.opts))return d;return n.map(k,Ua,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xa,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Ra[c]=Ra[c]||[],Ra[c].unshift(b)},prefilter:function(a,b){b?Qa.unshift(a):Qa.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xa(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pa.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Ta(b,!0),a,d,e)}}),n.each({slideDown:Ta("show"),slideUp:Ta("hide"),slideToggle:Ta("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(La=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),La=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ma||(Ma=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Ma),Ma=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Ya,Za,$a=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Za:Ya)),
  137.     void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Za={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$a[b]||n.find.attr;$a[b]=function(a,b,d){var e,f;return d||(f=$a[b],$a[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$a[b]=f),e}});var _a=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_a.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ab=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ab," ").indexOf(b)>=0)return!0;return!1}});var bb=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cb=n.now(),db=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var eb=/#.*$/,fb=/([?&])_=[^&]*/,gb=/^(.*?):[ \t]*([^\r\n]*)$/gm,hb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,ib=/^(?:GET|HEAD)$/,jb=/^\/\//,kb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lb={},mb={},nb="*/".concat("*"),ob=a.location.href,pb=kb.exec(ob.toLowerCase())||[];function qb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function rb(a,b,c,d){var e={},f=a===mb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function sb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function tb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function ub(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ob,type:"GET",isLocal:hb.test(pb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":nb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?sb(sb(a,n.ajaxSettings),b):sb(n.ajaxSettings,a)},ajaxPrefilter:qb(lb),ajaxTransport:qb(mb),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=gb.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||ob)+"").replace(eb,"").replace(jb,pb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=kb.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===pb[1]&&h[2]===pb[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(pb[3]||("http:"===pb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),rb(lb,k,b,v),2===t)return v;i=n.event&&k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!ib.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(db.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=fb.test(d)?d.replace(fb,"$1_="+cb++):d+(db.test(d)?"&":"?")+"_="+cb++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+nb+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=rb(mb,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=tb(k,v,f)),u=ub(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var vb=/%20/g,wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&").replace(vb,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Bb=0,Cb={},Db={0:200,1223:204},Eb=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Cb)Cb[a]()}),k.cors=!!Eb&&"withCredentials"in Eb,k.ajax=Eb=!!Eb,n.ajaxTransport(function(a){var b;return k.cors||Eb&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Bb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Cb[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Db[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Cb[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Fb=[],Gb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Fb.pop()||n.expando+"_"+cb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Gb.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Gb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Gb,"$1"+e):b.jsonp!==!1&&(b.url+=(db.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Fb.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Hb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Hb)return Hb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Ib=a.document.documentElement;function Jb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Jb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Ib;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ib})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Jb(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=ya(k.pixelPosition,function(a,c){return c?(c=xa(a,b),va.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.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?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Kb=a.jQuery,Lb=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Lb),b&&a.jQuery===n&&(a.jQuery=Kb),n},typeof b===U&&(a.jQuery=a.$=n),n});
  138.     jQuery.noConflict();
  139.  
  140.     /* socket.io v1.4.3 */
  141.     (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.io=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(_dereq_,module,exports){var url=_dereq_("./url");var parser=_dereq_("socket.io-parser");var Manager=_dereq_("./manager");var debug=_dereq_("debug")("socket.io-client");module.exports=exports=lookup;var cache=exports.managers={};function lookup(uri,opts){if(typeof uri=="object"){opts=uri;uri=undefined}opts=opts||{};var parsed=url(uri);var source=parsed.source;var id=parsed.id;var path=parsed.path;var sameNamespace=cache[id]&&path in cache[id].nsps;var newConnection=opts.forceNew||opts["force new connection"]||false===opts.multiplex||sameNamespace;var io;if(newConnection){debug("ignoring socket cache for %s",source);io=Manager(source,opts)}else{if(!cache[id]){debug("new io instance for %s",source);cache[id]=Manager(source,opts)}io=cache[id]}return io.socket(parsed.path)}exports.protocol=parser.protocol;exports.connect=lookup;exports.Manager=_dereq_("./manager");exports.Socket=_dereq_("./socket")},{"./manager":2,"./socket":4,"./url":5,debug:14,"socket.io-parser":41}],2:[function(_dereq_,module,exports){var eio=_dereq_("engine.io-client");var Socket=_dereq_("./socket");var Emitter=_dereq_("component-emitter");var parser=_dereq_("socket.io-parser");var on=_dereq_("./on");var bind=_dereq_("component-bind");var debug=_dereq_("debug")("socket.io-client:manager");var indexOf=_dereq_("indexof");var Backoff=_dereq_("backo2");var has=Object.prototype.hasOwnProperty;module.exports=Manager;function Manager(uri,opts){if(!(this instanceof Manager))return new Manager(uri,opts);if(uri&&"object"==typeof uri){opts=uri;uri=undefined}opts=opts||{};opts.path=opts.path||"/socket.io";this.nsps={};this.subs=[];this.opts=opts;this.reconnection(opts.reconnection!==false);this.reconnectionAttempts(opts.reconnectionAttempts||Infinity);this.reconnectionDelay(opts.reconnectionDelay||1e3);this.reconnectionDelayMax(opts.reconnectionDelayMax||5e3);this.randomizationFactor(opts.randomizationFactor||.5);this.backoff=new Backoff({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()});this.timeout(null==opts.timeout?2e4:opts.timeout);this.readyState="closed";this.uri=uri;this.connecting=[];this.lastPing=null;this.encoding=false;this.packetBuffer=[];this.encoder=new parser.Encoder;this.decoder=new parser.Decoder;this.autoConnect=opts.autoConnect!==false;if(this.autoConnect)this.open()}Manager.prototype.emitAll=function(){this.emit.apply(this,arguments);for(var nsp in this.nsps){if(has.call(this.nsps,nsp)){this.nsps[nsp].emit.apply(this.nsps[nsp],arguments)}}};Manager.prototype.updateSocketIds=function(){for(var nsp in this.nsps){if(has.call(this.nsps,nsp)){this.nsps[nsp].id=this.engine.id}}};Emitter(Manager.prototype);Manager.prototype.reconnection=function(v){if(!arguments.length)return this._reconnection;this._reconnection=!!v;return this};Manager.prototype.reconnectionAttempts=function(v){if(!arguments.length)return this._reconnectionAttempts;this._reconnectionAttempts=v;return this};Manager.prototype.reconnectionDelay=function(v){if(!arguments.length)return this._reconnectionDelay;this._reconnectionDelay=v;this.backoff&&this.backoff.setMin(v);return this};Manager.prototype.randomizationFactor=function(v){if(!arguments.length)return this._randomizationFactor;this._randomizationFactor=v;this.backoff&&this.backoff.setJitter(v);return this};Manager.prototype.reconnectionDelayMax=function(v){if(!arguments.length)return this._reconnectionDelayMax;this._reconnectionDelayMax=v;this.backoff&&this.backoff.setMax(v);return this};Manager.prototype.timeout=function(v){if(!arguments.length)return this._timeout;this._timeout=v;return this};Manager.prototype.maybeReconnectOnOpen=function(){if(!this.reconnecting&&this._reconnection&&this.backoff.attempts===0){this.reconnect()}};Manager.prototype.open=Manager.prototype.connect=function(fn){debug("readyState %s",this.readyState);if(~this.readyState.indexOf("open"))return this;debug("opening %s",this.uri);this.engine=eio(this.uri,this.opts);var socket=this.engine;var self=this;this.readyState="opening";this.skipReconnect=false;var openSub=on(socket,"open",function(){self.onopen();fn&&fn()});var errorSub=on(socket,"error",function(data){debug("connect_error");self.cleanup();self.readyState="closed";self.emitAll("connect_error",data);if(fn){var err=new Error("Connection error");err.data=data;fn(err)}else{self.maybeReconnectOnOpen()}});if(false!==this._timeout){var timeout=this._timeout;debug("connect attempt will timeout after %d",timeout);var timer=setTimeout(function(){debug("connect attempt timed out after %d",timeout);openSub.destroy();socket.close();socket.emit("error","timeout");self.emitAll("connect_timeout",timeout)},timeout);this.subs.push({destroy:function(){clearTimeout(timer)}})}this.subs.push(openSub);this.subs.push(errorSub);return this};Manager.prototype.onopen=function(){debug("open");this.cleanup();this.readyState="open";this.emit("open");var socket=this.engine;this.subs.push(on(socket,"data",bind(this,"ondata")));this.subs.push(on(socket,"ping",bind(this,"onping")));this.subs.push(on(socket,"pong",bind(this,"onpong")));this.subs.push(on(socket,"error",bind(this,"onerror")));this.subs.push(on(socket,"close",bind(this,"onclose")));this.subs.push(on(this.decoder,"decoded",bind(this,"ondecoded")))};Manager.prototype.onping=function(){this.lastPing=new Date;this.emitAll("ping")};Manager.prototype.onpong=function(){this.emitAll("pong",new Date-this.lastPing)};Manager.prototype.ondata=function(data){this.decoder.add(data)};Manager.prototype.ondecoded=function(packet){this.emit("packet",packet)};Manager.prototype.onerror=function(err){debug("error",err);this.emitAll("error",err)};Manager.prototype.socket=function(nsp){var socket=this.nsps[nsp];if(!socket){socket=new Socket(this,nsp);this.nsps[nsp]=socket;var self=this;socket.on("connecting",onConnecting);socket.on("connect",function(){socket.id=self.engine.id});if(this.autoConnect){onConnecting()}}function onConnecting(){if(!~indexOf(self.connecting,socket)){self.connecting.push(socket)}}return socket};Manager.prototype.destroy=function(socket){var index=indexOf(this.connecting,socket);if(~index)this.connecting.splice(index,1);if(this.connecting.length)return;this.close()};Manager.prototype.packet=function(packet){debug("writing packet %j",packet);var self=this;if(!self.encoding){self.encoding=true;this.encoder.encode(packet,function(encodedPackets){for(var i=0;i<encodedPackets.length;i++){self.engine.write(encodedPackets[i],packet.options)}self.encoding=false;self.processPacketQueue()})}else{self.packetBuffer.push(packet)}};Manager.prototype.processPacketQueue=function(){if(this.packetBuffer.length>0&&!this.encoding){var pack=this.packetBuffer.shift();this.packet(pack)}};Manager.prototype.cleanup=function(){debug("cleanup");var sub;while(sub=this.subs.shift())sub.destroy();this.packetBuffer=[];this.encoding=false;this.lastPing=null;this.decoder.destroy()};Manager.prototype.close=Manager.prototype.disconnect=function(){debug("disconnect");this.skipReconnect=true;this.reconnecting=false;if("opening"==this.readyState){this.cleanup()}this.backoff.reset();this.readyState="closed";if(this.engine)this.engine.close()};Manager.prototype.onclose=function(reason){debug("onclose");this.cleanup();this.backoff.reset();this.readyState="closed";this.emit("close",reason);if(this._reconnection&&!this.skipReconnect){this.reconnect()}};Manager.prototype.reconnect=function(){if(this.reconnecting||this.skipReconnect)return this;var self=this;if(this.backoff.attempts>=this._reconnectionAttempts){debug("reconnect failed");this.backoff.reset();this.emitAll("reconnect_failed");this.reconnecting=false}else{var delay=this.backoff.duration();debug("will wait %dms before reconnect attempt",delay);this.reconnecting=true;var timer=setTimeout(function(){if(self.skipReconnect)return;debug("attempting reconnect");self.emitAll("reconnect_attempt",self.backoff.attempts);self.emitAll("reconnecting",self.backoff.attempts);if(self.skipReconnect)return;self.open(function(err){if(err){debug("reconnect attempt error");self.reconnecting=false;self.reconnect();self.emitAll("reconnect_error",err.data)}else{debug("reconnect success");self.onreconnect()}})},delay);this.subs.push({destroy:function(){clearTimeout(timer)}})}};Manager.prototype.onreconnect=function(){var attempt=this.backoff.attempts;this.reconnecting=false;this.backoff.reset();this.updateSocketIds();this.emitAll("reconnect",attempt)}},{"./on":3,"./socket":4,backo2:8,"component-bind":11,"component-emitter":12,debug:14,"engine.io-client":16,indexof:33,"socket.io-parser":41}],3:[function(_dereq_,module,exports){module.exports=on;function on(obj,ev,fn){obj.on(ev,fn);return{destroy:function(){obj.removeListener(ev,fn)}}}},{}],4:[function(_dereq_,module,exports){var parser=_dereq_("socket.io-parser");var Emitter=_dereq_("component-emitter");var toArray=_dereq_("to-array");var on=_dereq_("./on");var bind=_dereq_("component-bind");var debug=_dereq_("debug")("socket.io-client:socket");var hasBin=_dereq_("has-binary");module.exports=exports=Socket;var events={connect:1,connect_error:1,connect_timeout:1,connecting:1,disconnect:1,error:1,reconnect:1,reconnect_attempt:1,reconnect_failed:1,reconnect_error:1,reconnecting:1,ping:1,pong:1};var emit=Emitter.prototype.emit;function Socket(io,nsp){this.io=io;this.nsp=nsp;this.json=this;this.ids=0;this.acks={};this.receiveBuffer=[];this.sendBuffer=[];this.connected=false;this.disconnected=true;if(this.io.autoConnect)this.open()}Emitter(Socket.prototype);Socket.prototype.subEvents=function(){if(this.subs)return;var io=this.io;this.subs=[on(io,"open",bind(this,"onopen")),on(io,"packet",bind(this,"onpacket")),on(io,"close",bind(this,"onclose"))]};Socket.prototype.open=Socket.prototype.connect=function(){if(this.connected)return this;this.subEvents();this.io.open();if("open"==this.io.readyState)this.onopen();this.emit("connecting");return this};Socket.prototype.send=function(){var args=toArray(arguments);args.unshift("message");this.emit.apply(this,args);return this};Socket.prototype.emit=function(ev){if(events.hasOwnProperty(ev)){emit.apply(this,arguments);return this}var args=toArray(arguments);var parserType=parser.EVENT;if(hasBin(args)){parserType=parser.BINARY_EVENT}var packet={type:parserType,data:args};packet.options={};packet.options.compress=!this.flags||false!==this.flags.compress;if("function"==typeof args[args.length-1]){debug("emitting packet with ack id %d",this.ids);this.acks[this.ids]=args.pop();packet.id=this.ids++}if(this.connected){this.packet(packet)}else{this.sendBuffer.push(packet)}delete this.flags;return this};Socket.prototype.packet=function(packet){packet.nsp=this.nsp;this.io.packet(packet)};Socket.prototype.onopen=function(){debug("transport is open - connecting");if("/"!=this.nsp){this.packet({type:parser.CONNECT})}};Socket.prototype.onclose=function(reason){debug("close (%s)",reason);this.connected=false;this.disconnected=true;delete this.id;this.emit("disconnect",reason)};Socket.prototype.onpacket=function(packet){if(packet.nsp!=this.nsp)return;switch(packet.type){case parser.CONNECT:this.onconnect();break;case parser.EVENT:this.onevent(packet);break;case parser.BINARY_EVENT:this.onevent(packet);break;case parser.ACK:this.onack(packet);break;case parser.BINARY_ACK:this.onack(packet);break;case parser.DISCONNECT:this.ondisconnect();break;case parser.ERROR:this.emit("error",packet.data);break}};Socket.prototype.onevent=function(packet){var args=packet.data||[];debug("emitting event %j",args);if(null!=packet.id){debug("attaching ack callback to event");args.push(this.ack(packet.id))}if(this.connected){emit.apply(this,args)}else{this.receiveBuffer.push(args)}};Socket.prototype.ack=function(id){var self=this;var sent=false;return function(){if(sent)return;sent=true;var args=toArray(arguments);debug("sending ack %j",args);var type=hasBin(args)?parser.BINARY_ACK:parser.ACK;self.packet({type:type,id:id,data:args})}};Socket.prototype.onack=function(packet){var ack=this.acks[packet.id];if("function"==typeof ack){debug("calling ack %s with %j",packet.id,packet.data);ack.apply(this,packet.data);delete this.acks[packet.id]}else{debug("bad ack %s",packet.id)}};Socket.prototype.onconnect=function(){this.connected=true;this.disconnected=false;this.emit("connect");this.emitBuffered()};Socket.prototype.emitBuffered=function(){var i;for(i=0;i<this.receiveBuffer.length;i++){emit.apply(this,this.receiveBuffer[i])}this.receiveBuffer=[];for(i=0;i<this.sendBuffer.length;i++){this.packet(this.sendBuffer[i])}this.sendBuffer=[]};Socket.prototype.ondisconnect=function(){debug("server disconnect (%s)",this.nsp);this.destroy();this.onclose("io server disconnect")};Socket.prototype.destroy=function(){if(this.subs){for(var i=0;i<this.subs.length;i++){this.subs[i].destroy()}this.subs=null}this.io.destroy(this)};Socket.prototype.close=Socket.prototype.disconnect=function(){if(this.connected){debug("performing disconnect (%s)",this.nsp);this.packet({type:parser.DISCONNECT})}this.destroy();if(this.connected){this.onclose("io client disconnect")}return this};Socket.prototype.compress=function(compress){this.flags=this.flags||{};this.flags.compress=compress;return this}},{"./on":3,"component-bind":11,"component-emitter":12,debug:14,"has-binary":31,"socket.io-parser":41,"to-array":44}],5:[function(_dereq_,module,exports){(function(global){var parseuri=_dereq_("parseuri");var debug=_dereq_("debug")("socket.io-client:url");module.exports=url;function url(uri,loc){var obj=uri;var loc=loc||global.location;if(null==uri)uri=loc.protocol+"//"+loc.host;if("string"==typeof uri){if("/"==uri.charAt(0)){if("/"==uri.charAt(1)){uri=loc.protocol+uri}else{uri=loc.host+uri}}if(!/^(https?|wss?):\/\//.test(uri)){debug("protocol-less url %s",uri);if("undefined"!=typeof loc){uri=loc.protocol+"//"+uri}else{uri="https://"+uri}}debug("parse %s",uri);obj=parseuri(uri)}if(!obj.port){if(/^(http|ws)$/.test(obj.protocol)){obj.port="80"}else if(/^(http|ws)s$/.test(obj.protocol)){obj.port="443"}}obj.path=obj.path||"/";var ipv6=obj.host.indexOf(":")!==-1;var host=ipv6?"["+obj.host+"]":obj.host;obj.id=obj.protocol+"://"+host+":"+obj.port;obj.href=obj.protocol+"://"+host+(loc&&loc.port==obj.port?"":":"+obj.port);return obj}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{debug:14,parseuri:39}],6:[function(_dereq_,module,exports){module.exports=after;function after(count,callback,err_cb){var bail=false;err_cb=err_cb||noop;proxy.count=count;return count===0?callback():proxy;function proxy(err,result){if(proxy.count<=0){throw new Error("after called too many times")}--proxy.count;if(err){bail=true;callback(err);callback=err_cb}else if(proxy.count===0&&!bail){callback(null,result)}}}function noop(){}},{}],7:[function(_dereq_,module,exports){module.exports=function(arraybuffer,start,end){var bytes=arraybuffer.byteLength;start=start||0;end=end||bytes;if(arraybuffer.slice){return arraybuffer.slice(start,end)}if(start<0){start+=bytes}if(end<0){end+=bytes}if(end>bytes){end=bytes}if(start>=bytes||start>=end||bytes===0){return new ArrayBuffer(0)}var abv=new Uint8Array(arraybuffer);var result=new Uint8Array(end-start);for(var i=start,ii=0;i<end;i++,ii++){result[ii]=abv[i]}return result.buffer}},{}],8:[function(_dereq_,module,exports){module.exports=Backoff;function Backoff(opts){opts=opts||{};this.ms=opts.min||100;this.max=opts.max||1e4;this.factor=opts.factor||2;this.jitter=opts.jitter>0&&opts.jitter<=1?opts.jitter:0;this.attempts=0}Backoff.prototype.duration=function(){var ms=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var rand=Math.random();var deviation=Math.floor(rand*this.jitter*ms);ms=(Math.floor(rand*10)&1)==0?ms-deviation:ms+deviation}return Math.min(ms,this.max)|0};Backoff.prototype.reset=function(){this.attempts=0};Backoff.prototype.setMin=function(min){this.ms=min};Backoff.prototype.setMax=function(max){this.max=max};Backoff.prototype.setJitter=function(jitter){this.jitter=jitter}},{}],9:[function(_dereq_,module,exports){(function(chars){"use strict";exports.encode=function(arraybuffer){var bytes=new Uint8Array(arraybuffer),i,len=bytes.buffer.byteLength,base64="";for(i=0;i<len;i+=3){base64+=chars[bytes.buffer[i]>>2];base64+=chars[(bytes.buffer[i]&3)<<4|bytes.buffer[i+1]>>4];base64+=chars[(bytes.buffer[i+1]&15)<<2|bytes.buffer[i+2]>>6];base64+=chars[bytes.buffer[i+2]&63]}if(len%3===2){base64=base64.substring(0,base64.length-1)+"="}else if(len%3===1){base64=base64.substring(0,base64.length-2)+"=="}return base64};exports.decode=function(base64){var bufferLength=base64.length*.75,len=base64.length,i,p=0,encoded1,encoded2,encoded3,encoded4;if(base64[base64.length-1]==="="){bufferLength--;if(base64[base64.length-2]==="="){bufferLength--}}var arraybuffer=new ArrayBuffer(bufferLength),bytes=new Uint8Array(arraybuffer);for(i=0;i<len;i+=4){encoded1=chars.indexOf(base64[i]);encoded2=chars.indexOf(base64[i+1]);encoded3=chars.indexOf(base64[i+2]);encoded4=chars.indexOf(base64[i+3]);bytes[p++]=encoded1<<2|encoded2>>4;bytes[p++]=(encoded2&15)<<4|encoded3>>2;bytes[p++]=(encoded3&3)<<6|encoded4&63}return arraybuffer}})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")},{}],10:[function(_dereq_,module,exports){(function(global){var BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder||global.MSBlobBuilder||global.MozBlobBuilder;var blobSupported=function(){try{var a=new Blob(["hi"]);return a.size===2}catch(e){return false}}();var blobSupportsArrayBufferView=blobSupported&&function(){try{var b=new Blob([new Uint8Array([1,2])]);return b.size===2}catch(e){return false}}();var blobBuilderSupported=BlobBuilder&&BlobBuilder.prototype.append&&BlobBuilder.prototype.getBlob;function mapArrayBufferViews(ary){for(var i=0;i<ary.length;i++){var chunk=ary[i];if(chunk.buffer instanceof ArrayBuffer){var buf=chunk.buffer;if(chunk.byteLength!==buf.byteLength){var copy=new Uint8Array(chunk.byteLength);copy.set(new Uint8Array(buf,chunk.byteOffset,chunk.byteLength));buf=copy.buffer}ary[i]=buf}}}function BlobBuilderConstructor(ary,options){options=options||{};var bb=new BlobBuilder;mapArrayBufferViews(ary);for(var i=0;i<ary.length;i++){bb.append(ary[i])}return options.type?bb.getBlob(options.type):bb.getBlob()}function BlobConstructor(ary,options){mapArrayBufferViews(ary);return new Blob(ary,options||{})}module.exports=function(){if(blobSupported){return blobSupportsArrayBufferView?global.Blob:BlobConstructor}else if(blobBuilderSupported){return BlobBuilderConstructor}else{return undefined}}()}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],11:[function(_dereq_,module,exports){var slice=[].slice;module.exports=function(obj,fn){if("string"==typeof fn)fn=obj[fn];if("function"!=typeof fn)throw new Error("bind() requires a function");var args=slice.call(arguments,2);return function(){return fn.apply(obj,args.concat(slice.call(arguments)))}}},{}],12:[function(_dereq_,module,exports){module.exports=Emitter;function Emitter(obj){if(obj)return mixin(obj)}function mixin(obj){for(var key in Emitter.prototype){obj[key]=Emitter.prototype[key]}return obj}Emitter.prototype.on=Emitter.prototype.addEventListener=function(event,fn){this._callbacks=this._callbacks||{};(this._callbacks["$"+event]=this._callbacks["$"+event]||[]).push(fn);return this};Emitter.prototype.once=function(event,fn){function on(){this.off(event,on);fn.apply(this,arguments)}on.fn=fn;this.on(event,on);return this};Emitter.prototype.off=Emitter.prototype.removeListener=Emitter.prototype.removeAllListeners=Emitter.prototype.removeEventListener=function(event,fn){this._callbacks=this._callbacks||{};if(0==arguments.length){this._callbacks={};return this}var callbacks=this._callbacks["$"+event];if(!callbacks)return this;if(1==arguments.length){delete this._callbacks["$"+event];return this}var cb;for(var i=0;i<callbacks.length;i++){cb=callbacks[i];if(cb===fn||cb.fn===fn){callbacks.splice(i,1);break}}return this};Emitter.prototype.emit=function(event){this._callbacks=this._callbacks||{};var args=[].slice.call(arguments,1),callbacks=this._callbacks["$"+event];if(callbacks){callbacks=callbacks.slice(0);for(var i=0,len=callbacks.length;i<len;++i){callbacks[i].apply(this,args)}}return this};Emitter.prototype.listeners=function(event){this._callbacks=this._callbacks||{};return this._callbacks["$"+event]||[]};Emitter.prototype.hasListeners=function(event){return!!this.listeners(event).length}},{}],13:[function(_dereq_,module,exports){module.exports=function(a,b){var fn=function(){};fn.prototype=b.prototype;a.prototype=new fn;a.prototype.constructor=a}},{}],14:[function(_dereq_,module,exports){exports=module.exports=_dereq_("./debug");exports.log=log;exports.formatArgs=formatArgs;exports.save=save;exports.load=load;exports.useColors=useColors;exports.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:localstorage();exports.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"];function useColors(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}exports.formatters.j=function(v){return JSON.stringify(v)};function formatArgs(){var args=arguments;var useColors=this.useColors;args[0]=(useColors?"%c":"")+this.namespace+(useColors?" %c":" ")+args[0]+(useColors?"%c ":" ")+"+"+exports.humanize(this.diff);if(!useColors)return args;var c="color: "+this.color;args=[args[0],c,"color: inherit"].concat(Array.prototype.slice.call(args,1));var index=0;var lastC=0;args[0].replace(/%[a-z%]/g,function(match){if("%%"===match)return;index++;if("%c"===match){lastC=index}});args.splice(lastC,0,c);return args}function log(){return"object"===typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function save(namespaces){try{if(null==namespaces){exports.storage.removeItem("debug")}else{exports.storage.debug=namespaces}}catch(e){}}function load(){var r;try{r=exports.storage.debug}catch(e){}return r}exports.enable(load());function localstorage(){try{return window.localStorage}catch(e){}}},{"./debug":15}],15:[function(_dereq_,module,exports){exports=module.exports=debug;exports.coerce=coerce;exports.disable=disable;exports.enable=enable;exports.enabled=enabled;exports.humanize=_dereq_("ms");exports.names=[];exports.skips=[];exports.formatters={};var prevColor=0;var prevTime;function selectColor(){return exports.colors[prevColor++%exports.colors.length]}function debug(namespace){function disabled(){}disabled.enabled=false;function enabled(){var self=enabled;var curr=+new Date;var ms=curr-(prevTime||curr);self.diff=ms;self.prev=prevTime;self.curr=curr;prevTime=curr;if(null==self.useColors)self.useColors=exports.useColors();if(null==self.color&&self.useColors)self.color=selectColor();var args=Array.prototype.slice.call(arguments);args[0]=exports.coerce(args[0]);if("string"!==typeof args[0]){args=["%o"].concat(args)}var index=0;args[0]=args[0].replace(/%([a-z%])/g,function(match,format){if(match==="%%")return match;index++;var formatter=exports.formatters[format];if("function"===typeof formatter){var val=args[index];match=formatter.call(self,val);args.splice(index,1);index--}return match});if("function"===typeof exports.formatArgs){args=exports.formatArgs.apply(self,args)}var logFn=enabled.log||exports.log||console.log.bind(console);logFn.apply(self,args)}enabled.enabled=true;var fn=exports.enabled(namespace)?enabled:disabled;fn.namespace=namespace;return fn}function enable(namespaces){exports.save(namespaces);var split=(namespaces||"").split(/[\s,]+/);var len=split.length;for(var i=0;i<len;i++){if(!split[i])continue;namespaces=split[i].replace(/\*/g,".*?");if(namespaces[0]==="-"){exports.skips.push(new RegExp("^"+namespaces.substr(1)+"$"))}else{exports.names.push(new RegExp("^"+namespaces+"$"))}}}function disable(){exports.enable("")}function enabled(name){var i,len;for(i=0,len=exports.skips.length;i<len;i++){if(exports.skips[i].test(name)){return false}}for(i=0,len=exports.names.length;i<len;i++){if(exports.names[i].test(name)){return true}}return false}function coerce(val){if(val instanceof Error)return val.stack||val.message;return val}},{ms:36}],16:[function(_dereq_,module,exports){module.exports=_dereq_("./lib/")},{"./lib/":17}],17:[function(_dereq_,module,exports){module.exports=_dereq_("./socket");module.exports.parser=_dereq_("engine.io-parser")},{"./socket":18,"engine.io-parser":27}],18:[function(_dereq_,module,exports){(function(global){var transports=_dereq_("./transports");var Emitter=_dereq_("component-emitter");var debug=_dereq_("debug")("engine.io-client:socket");var index=_dereq_("indexof");var parser=_dereq_("engine.io-parser");var parseuri=_dereq_("parseuri");var parsejson=_dereq_("parsejson");var parseqs=_dereq_("parseqs");module.exports=Socket;function noop(){}function Socket(uri,opts){if(!(this instanceof Socket))return new Socket(uri,opts);opts=opts||{};if(uri&&"object"==typeof uri){opts=uri;uri=null}if(uri){uri=parseuri(uri);opts.hostname=uri.host;opts.secure=uri.protocol=="https"||uri.protocol=="wss";opts.port=uri.port;if(uri.query)opts.query=uri.query}else if(opts.host){opts.hostname=parseuri(opts.host).host}this.secure=null!=opts.secure?opts.secure:global.location&&"https:"==location.protocol;if(opts.hostname&&!opts.port){opts.port=this.secure?"443":"80"}this.agent=opts.agent||false;this.hostname=opts.hostname||(global.location?location.hostname:"localhost");this.port=opts.port||(global.location&&location.port?location.port:this.secure?443:80);this.query=opts.query||{};if("string"==typeof this.query)this.query=parseqs.decode(this.query);this.upgrade=false!==opts.upgrade;this.path=(opts.path||"/engine.io").replace(/\/$/,"")+"/";this.forceJSONP=!!opts.forceJSONP;this.jsonp=false!==opts.jsonp;this.forceBase64=!!opts.forceBase64;this.enablesXDR=!!opts.enablesXDR;this.timestampParam=opts.timestampParam||"t";this.timestampRequests=opts.timestampRequests;this.transports=opts.transports||["polling","websocket"];this.readyState="";this.writeBuffer=[];this.policyPort=opts.policyPort||843;this.rememberUpgrade=opts.rememberUpgrade||false;this.binaryType=null;this.onlyBinaryUpgrades=opts.onlyBinaryUpgrades;this.perMessageDeflate=false!==opts.perMessageDeflate?opts.perMessageDeflate||{}:false;if(true===this.perMessageDeflate)this.perMessageDeflate={};if(this.perMessageDeflate&&null==this.perMessageDeflate.threshold){this.perMessageDeflate.threshold=1024}this.pfx=opts.pfx||null;this.key=opts.key||null;this.passphrase=opts.passphrase||null;this.cert=opts.cert||null;this.ca=opts.ca||null;this.ciphers=opts.ciphers||null;this.rejectUnauthorized=opts.rejectUnauthorized===undefined?null:opts.rejectUnauthorized;var freeGlobal=typeof global=="object"&&global;if(freeGlobal.global===freeGlobal){if(opts.extraHeaders&&Object.keys(opts.extraHeaders).length>0){this.extraHeaders=opts.extraHeaders}}this.open()}Socket.priorWebsocketSuccess=false;Emitter(Socket.prototype);Socket.protocol=parser.protocol;Socket.Socket=Socket;Socket.Transport=_dereq_("./transport");Socket.transports=_dereq_("./transports");Socket.parser=_dereq_("engine.io-parser");Socket.prototype.createTransport=function(name){debug('creating transport "%s"',name);var query=clone(this.query);query.EIO=parser.protocol;query.transport=name;if(this.id)query.sid=this.id;var transport=new transports[name]({agent:this.agent,hostname:this.hostname,port:this.port,secure:this.secure,path:this.path,query:query,forceJSONP:this.forceJSONP,jsonp:this.jsonp,forceBase64:this.forceBase64,enablesXDR:this.enablesXDR,timestampRequests:this.timestampRequests,timestampParam:this.timestampParam,policyPort:this.policyPort,socket:this,pfx:this.pfx,key:this.key,passphrase:this.passphrase,cert:this.cert,ca:this.ca,ciphers:this.ciphers,rejectUnauthorized:this.rejectUnauthorized,perMessageDeflate:this.perMessageDeflate,extraHeaders:this.extraHeaders});return transport};function clone(obj){var o={};for(var i in obj){if(obj.hasOwnProperty(i)){o[i]=obj[i]}}return o}Socket.prototype.open=function(){var transport;if(this.rememberUpgrade&&Socket.priorWebsocketSuccess&&this.transports.indexOf("websocket")!=-1){transport="websocket"}else if(0===this.transports.length){var self=this;setTimeout(function(){self.emit("error","No transports available")},0);return}else{transport=this.transports[0]}this.readyState="opening";try{transport=this.createTransport(transport)}catch(e){this.transports.shift();this.open();return}transport.open();this.setTransport(transport)};Socket.prototype.setTransport=function(transport){debug("setting transport %s",transport.name);var self=this;if(this.transport){debug("clearing existing transport %s",this.transport.name);this.transport.removeAllListeners()}this.transport=transport;transport.on("drain",function(){self.onDrain()}).on("packet",function(packet){self.onPacket(packet)}).on("error",function(e){self.onError(e)}).on("close",function(){self.onClose("transport close")})};Socket.prototype.probe=function(name){debug('probing transport "%s"',name);var transport=this.createTransport(name,{probe:1}),failed=false,self=this;Socket.priorWebsocketSuccess=false;function onTransportOpen(){if(self.onlyBinaryUpgrades){var upgradeLosesBinary=!this.supportsBinary&&self.transport.supportsBinary;failed=failed||upgradeLosesBinary}if(failed)return;debug('probe transport "%s" opened',name);transport.send([{type:"ping",data:"probe"}]);transport.once("packet",function(msg){if(failed)return;if("pong"==msg.type&&"probe"==msg.data){debug('probe transport "%s" pong',name);self.upgrading=true;self.emit("upgrading",transport);if(!transport)return;Socket.priorWebsocketSuccess="websocket"==transport.name;debug('pausing current transport "%s"',self.transport.name);self.transport.pause(function(){if(failed)return;if("closed"==self.readyState)return;debug("changing transport and sending upgrade packet");cleanup();self.setTransport(transport);transport.send([{type:"upgrade"}]);self.emit("upgrade",transport);transport=null;self.upgrading=false;self.flush()})}else{debug('probe transport "%s" failed',name);var err=new Error("probe error");err.transport=transport.name;self.emit("upgradeError",err)}})}function freezeTransport(){if(failed)return;failed=true;cleanup();transport.close();transport=null}function onerror(err){var error=new Error("probe error: "+err);error.transport=transport.name;freezeTransport();debug('probe transport "%s" failed because of error: %s',name,err);self.emit("upgradeError",error)}function onTransportClose(){onerror("transport closed")}function onclose(){onerror("socket closed")}function onupgrade(to){if(transport&&to.name!=transport.name){debug('"%s" works - aborting "%s"',to.name,transport.name);freezeTransport()}}function cleanup(){transport.removeListener("open",onTransportOpen);transport.removeListener("error",onerror);transport.removeListener("close",onTransportClose);self.removeListener("close",onclose);self.removeListener("upgrading",onupgrade)}transport.once("open",onTransportOpen);transport.once("error",onerror);transport.once("close",onTransportClose);
  142.     this.once("close",onclose);this.once("upgrading",onupgrade);transport.open()};Socket.prototype.onOpen=function(){debug("socket open");this.readyState="open";Socket.priorWebsocketSuccess="websocket"==this.transport.name;this.emit("open");this.flush();if("open"==this.readyState&&this.upgrade&&this.transport.pause){debug("starting upgrade probes");for(var i=0,l=this.upgrades.length;i<l;i++){this.probe(this.upgrades[i])}}};Socket.prototype.onPacket=function(packet){if("opening"==this.readyState||"open"==this.readyState){debug('socket receive: type "%s", data "%s"',packet.type,packet.data);this.emit("packet",packet);this.emit("heartbeat");switch(packet.type){case"open":this.onHandshake(parsejson(packet.data));break;case"pong":this.setPing();this.emit("pong");break;case"error":var err=new Error("server error");err.code=packet.data;this.onError(err);break;case"message":this.emit("data",packet.data);this.emit("message",packet.data);break}}else{debug('packet received with socket readyState "%s"',this.readyState)}};Socket.prototype.onHandshake=function(data){this.emit("handshake",data);this.id=data.sid;this.transport.query.sid=data.sid;this.upgrades=this.filterUpgrades(data.upgrades);this.pingInterval=data.pingInterval;this.pingTimeout=data.pingTimeout;this.onOpen();if("closed"==this.readyState)return;this.setPing();this.removeListener("heartbeat",this.onHeartbeat);this.on("heartbeat",this.onHeartbeat)};Socket.prototype.onHeartbeat=function(timeout){clearTimeout(this.pingTimeoutTimer);var self=this;self.pingTimeoutTimer=setTimeout(function(){if("closed"==self.readyState)return;self.onClose("ping timeout")},timeout||self.pingInterval+self.pingTimeout)};Socket.prototype.setPing=function(){var self=this;clearTimeout(self.pingIntervalTimer);self.pingIntervalTimer=setTimeout(function(){debug("writing ping packet - expecting pong within %sms",self.pingTimeout);self.ping();self.onHeartbeat(self.pingTimeout)},self.pingInterval)};Socket.prototype.ping=function(){var self=this;this.sendPacket("ping",function(){self.emit("ping")})};Socket.prototype.onDrain=function(){this.writeBuffer.splice(0,this.prevBufferLen);this.prevBufferLen=0;if(0===this.writeBuffer.length){this.emit("drain")}else{this.flush()}};Socket.prototype.flush=function(){if("closed"!=this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){debug("flushing %d packets in socket",this.writeBuffer.length);this.transport.send(this.writeBuffer);this.prevBufferLen=this.writeBuffer.length;this.emit("flush")}};Socket.prototype.write=Socket.prototype.send=function(msg,options,fn){this.sendPacket("message",msg,options,fn);return this};Socket.prototype.sendPacket=function(type,data,options,fn){if("function"==typeof data){fn=data;data=undefined}if("function"==typeof options){fn=options;options=null}if("closing"==this.readyState||"closed"==this.readyState){return}options=options||{};options.compress=false!==options.compress;var packet={type:type,data:data,options:options};this.emit("packetCreate",packet);this.writeBuffer.push(packet);if(fn)this.once("flush",fn);this.flush()};Socket.prototype.close=function(){if("opening"==this.readyState||"open"==this.readyState){this.readyState="closing";var self=this;if(this.writeBuffer.length){this.once("drain",function(){if(this.upgrading){waitForUpgrade()}else{close()}})}else if(this.upgrading){waitForUpgrade()}else{close()}}function close(){self.onClose("forced close");debug("socket closing - telling transport to close");self.transport.close()}function cleanupAndClose(){self.removeListener("upgrade",cleanupAndClose);self.removeListener("upgradeError",cleanupAndClose);close()}function waitForUpgrade(){self.once("upgrade",cleanupAndClose);self.once("upgradeError",cleanupAndClose)}return this};Socket.prototype.onError=function(err){debug("socket error %j",err);Socket.priorWebsocketSuccess=false;this.emit("error",err);this.onClose("transport error",err)};Socket.prototype.onClose=function(reason,desc){if("opening"==this.readyState||"open"==this.readyState||"closing"==this.readyState){debug('socket close with reason: "%s"',reason);var self=this;clearTimeout(this.pingIntervalTimer);clearTimeout(this.pingTimeoutTimer);this.transport.removeAllListeners("close");this.transport.close();this.transport.removeAllListeners();this.readyState="closed";this.id=null;this.emit("close",reason,desc);self.writeBuffer=[];self.prevBufferLen=0}};Socket.prototype.filterUpgrades=function(upgrades){var filteredUpgrades=[];for(var i=0,j=upgrades.length;i<j;i++){if(~index(this.transports,upgrades[i]))filteredUpgrades.push(upgrades[i])}return filteredUpgrades}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./transport":19,"./transports":20,"component-emitter":26,debug:14,"engine.io-parser":27,indexof:33,parsejson:37,parseqs:38,parseuri:39}],19:[function(_dereq_,module,exports){var parser=_dereq_("engine.io-parser");var Emitter=_dereq_("component-emitter");module.exports=Transport;function Transport(opts){this.path=opts.path;this.hostname=opts.hostname;this.port=opts.port;this.secure=opts.secure;this.query=opts.query;this.timestampParam=opts.timestampParam;this.timestampRequests=opts.timestampRequests;this.readyState="";this.agent=opts.agent||false;this.socket=opts.socket;this.enablesXDR=opts.enablesXDR;this.pfx=opts.pfx;this.key=opts.key;this.passphrase=opts.passphrase;this.cert=opts.cert;this.ca=opts.ca;this.ciphers=opts.ciphers;this.rejectUnauthorized=opts.rejectUnauthorized;this.extraHeaders=opts.extraHeaders}Emitter(Transport.prototype);Transport.prototype.onError=function(msg,desc){var err=new Error(msg);err.type="TransportError";err.description=desc;this.emit("error",err);return this};Transport.prototype.open=function(){if("closed"==this.readyState||""==this.readyState){this.readyState="opening";this.doOpen()}return this};Transport.prototype.close=function(){if("opening"==this.readyState||"open"==this.readyState){this.doClose();this.onClose()}return this};Transport.prototype.send=function(packets){if("open"==this.readyState){this.write(packets)}else{throw new Error("Transport not open")}};Transport.prototype.onOpen=function(){this.readyState="open";this.writable=true;this.emit("open")};Transport.prototype.onData=function(data){var packet=parser.decodePacket(data,this.socket.binaryType);this.onPacket(packet)};Transport.prototype.onPacket=function(packet){this.emit("packet",packet)};Transport.prototype.onClose=function(){this.readyState="closed";this.emit("close")}},{"component-emitter":26,"engine.io-parser":27}],20:[function(_dereq_,module,exports){(function(global){var XMLHttpRequest=_dereq_("xmlhttprequest-ssl");var XHR=_dereq_("./polling-xhr");var JSONP=_dereq_("./polling-jsonp");var websocket=_dereq_("./websocket");exports.polling=polling;exports.websocket=websocket;function polling(opts){var xhr;var xd=false;var xs=false;var jsonp=false!==opts.jsonp;if(global.location){var isSSL="https:"==location.protocol;var port=location.port;if(!port){port=isSSL?443:80}xd=opts.hostname!=location.hostname||port!=opts.port;xs=opts.secure!=isSSL}opts.xdomain=xd;opts.xscheme=xs;xhr=new XMLHttpRequest(opts);if("open"in xhr&&!opts.forceJSONP){return new XHR(opts)}else{if(!jsonp)throw new Error("JSONP disabled");return new JSONP(opts)}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./polling-jsonp":21,"./polling-xhr":22,"./websocket":24,"xmlhttprequest-ssl":25}],21:[function(_dereq_,module,exports){(function(global){var Polling=_dereq_("./polling");var inherit=_dereq_("component-inherit");module.exports=JSONPPolling;var rNewline=/\n/g;var rEscapedNewline=/\\n/g;var callbacks;var index=0;function empty(){}function JSONPPolling(opts){Polling.call(this,opts);this.query=this.query||{};if(!callbacks){if(!global.___eio)global.___eio=[];callbacks=global.___eio}this.index=callbacks.length;var self=this;callbacks.push(function(msg){self.onData(msg)});this.query.j=this.index;if(global.document&&global.addEventListener){global.addEventListener("beforeunload",function(){if(self.script)self.script.onerror=empty},false)}}inherit(JSONPPolling,Polling);JSONPPolling.prototype.supportsBinary=false;JSONPPolling.prototype.doClose=function(){if(this.script){this.script.parentNode.removeChild(this.script);this.script=null}if(this.form){this.form.parentNode.removeChild(this.form);this.form=null;this.iframe=null}Polling.prototype.doClose.call(this)};JSONPPolling.prototype.doPoll=function(){var self=this;var script=document.createElement("script");if(this.script){this.script.parentNode.removeChild(this.script);this.script=null}script.async=true;script.src=this.uri();script.onerror=function(e){self.onError("jsonp poll error",e)};var insertAt=document.getElementsByTagName("script")[0];insertAt.parentNode.insertBefore(script,insertAt);this.script=script;var isUAgecko="undefined"!=typeof navigator&&/gecko/i.test(navigator.userAgent);if(isUAgecko){setTimeout(function(){var iframe=document.createElement("iframe");document.body.appendChild(iframe);document.body.removeChild(iframe)},100)}};JSONPPolling.prototype.doWrite=function(data,fn){var self=this;if(!this.form){var form=document.createElement("form");var area=document.createElement("textarea");var id=this.iframeId="eio_iframe_"+this.index;var iframe;form.className="socketio";form.style.position="absolute";form.style.top="-1000px";form.style.left="-1000px";form.target=id;form.method="POST";form.setAttribute("accept-charset","utf-8");area.name="d";form.appendChild(area);document.body.appendChild(form);this.form=form;this.area=area}this.form.action=this.uri();function complete(){initIframe();fn()}function initIframe(){if(self.iframe){try{self.form.removeChild(self.iframe)}catch(e){self.onError("jsonp polling iframe removal error",e)}}try{var html='<iframe src="javascript:0" name="'+self.iframeId+'">';iframe=document.createElement(html)}catch(e){iframe=document.createElement("iframe");iframe.name=self.iframeId;iframe.src="javascript:0"}iframe.id=self.iframeId;self.form.appendChild(iframe);self.iframe=iframe}initIframe();data=data.replace(rEscapedNewline,"\\\n");this.area.value=data.replace(rNewline,"\\n");try{this.form.submit()}catch(e){}if(this.iframe.attachEvent){this.iframe.onreadystatechange=function(){if(self.iframe.readyState=="complete"){complete()}}}else{this.iframe.onload=complete}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./polling":23,"component-inherit":13}],22:[function(_dereq_,module,exports){(function(global){var XMLHttpRequest=_dereq_("xmlhttprequest-ssl");var Polling=_dereq_("./polling");var Emitter=_dereq_("component-emitter");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:polling-xhr");module.exports=XHR;module.exports.Request=Request;function empty(){}function XHR(opts){Polling.call(this,opts);if(global.location){var isSSL="https:"==location.protocol;var port=location.port;if(!port){port=isSSL?443:80}this.xd=opts.hostname!=global.location.hostname||port!=opts.port;this.xs=opts.secure!=isSSL}else{this.extraHeaders=opts.extraHeaders}}inherit(XHR,Polling);XHR.prototype.supportsBinary=true;XHR.prototype.request=function(opts){opts=opts||{};opts.uri=this.uri();opts.xd=this.xd;opts.xs=this.xs;opts.agent=this.agent||false;opts.supportsBinary=this.supportsBinary;opts.enablesXDR=this.enablesXDR;opts.pfx=this.pfx;opts.key=this.key;opts.passphrase=this.passphrase;opts.cert=this.cert;opts.ca=this.ca;opts.ciphers=this.ciphers;opts.rejectUnauthorized=this.rejectUnauthorized;opts.extraHeaders=this.extraHeaders;return new Request(opts)};XHR.prototype.doWrite=function(data,fn){var isBinary=typeof data!=="string"&&data!==undefined;var req=this.request({method:"POST",data:data,isBinary:isBinary});var self=this;req.on("success",fn);req.on("error",function(err){self.onError("xhr post error",err)});this.sendXhr=req};XHR.prototype.doPoll=function(){debug("xhr poll");var req=this.request();var self=this;req.on("data",function(data){self.onData(data)});req.on("error",function(err){self.onError("xhr poll error",err)});this.pollXhr=req};function Request(opts){this.method=opts.method||"GET";this.uri=opts.uri;this.xd=!!opts.xd;this.xs=!!opts.xs;this.async=false!==opts.async;this.data=undefined!=opts.data?opts.data:null;this.agent=opts.agent;this.isBinary=opts.isBinary;this.supportsBinary=opts.supportsBinary;this.enablesXDR=opts.enablesXDR;this.pfx=opts.pfx;this.key=opts.key;this.passphrase=opts.passphrase;this.cert=opts.cert;this.ca=opts.ca;this.ciphers=opts.ciphers;this.rejectUnauthorized=opts.rejectUnauthorized;this.extraHeaders=opts.extraHeaders;this.create()}Emitter(Request.prototype);Request.prototype.create=function(){var opts={agent:this.agent,xdomain:this.xd,xscheme:this.xs,enablesXDR:this.enablesXDR};opts.pfx=this.pfx;opts.key=this.key;opts.passphrase=this.passphrase;opts.cert=this.cert;opts.ca=this.ca;opts.ciphers=this.ciphers;opts.rejectUnauthorized=this.rejectUnauthorized;var xhr=this.xhr=new XMLHttpRequest(opts);var self=this;try{debug("xhr open %s: %s",this.method,this.uri);xhr.open(this.method,this.uri,this.async);try{if(this.extraHeaders){xhr.setDisableHeaderCheck(true);for(var i in this.extraHeaders){if(this.extraHeaders.hasOwnProperty(i)){xhr.setRequestHeader(i,this.extraHeaders[i])}}}}catch(e){}if(this.supportsBinary){xhr.responseType="arraybuffer"}if("POST"==this.method){try{if(this.isBinary){xhr.setRequestHeader("Content-type","application/octet-stream")}else{xhr.setRequestHeader("Content-type","text/plain;charset=UTF-8")}}catch(e){}}if("withCredentials"in xhr){xhr.withCredentials=true}if(this.hasXDR()){xhr.onload=function(){self.onLoad()};xhr.onerror=function(){self.onError(xhr.responseText)}}else{xhr.onreadystatechange=function(){if(4!=xhr.readyState)return;if(200==xhr.status||1223==xhr.status){self.onLoad()}else{setTimeout(function(){self.onError(xhr.status)},0)}}}debug("xhr data %s",this.data);xhr.send(this.data)}catch(e){setTimeout(function(){self.onError(e)},0);return}if(global.document){this.index=Request.requestsCount++;Request.requests[this.index]=this}};Request.prototype.onSuccess=function(){this.emit("success");this.cleanup()};Request.prototype.onData=function(data){this.emit("data",data);this.onSuccess()};Request.prototype.onError=function(err){this.emit("error",err);this.cleanup(true)};Request.prototype.cleanup=function(fromError){if("undefined"==typeof this.xhr||null===this.xhr){return}if(this.hasXDR()){this.xhr.onload=this.xhr.onerror=empty}else{this.xhr.onreadystatechange=empty}if(fromError){try{this.xhr.abort()}catch(e){}}if(global.document){delete Request.requests[this.index]}this.xhr=null};Request.prototype.onLoad=function(){var data;try{var contentType;try{contentType=this.xhr.getResponseHeader("Content-Type").split(";")[0]}catch(e){}if(contentType==="application/octet-stream"){data=this.xhr.response}else{if(!this.supportsBinary){data=this.xhr.responseText}else{try{data=String.fromCharCode.apply(null,new Uint8Array(this.xhr.response))}catch(e){var ui8Arr=new Uint8Array(this.xhr.response);var dataArray=[];for(var idx=0,length=ui8Arr.length;idx<length;idx++){dataArray.push(ui8Arr[idx])}data=String.fromCharCode.apply(null,dataArray)}}}}catch(e){this.onError(e)}if(null!=data){this.onData(data)}};Request.prototype.hasXDR=function(){return"undefined"!==typeof global.XDomainRequest&&!this.xs&&this.enablesXDR};Request.prototype.abort=function(){this.cleanup()};if(global.document){Request.requestsCount=0;Request.requests={};if(global.attachEvent){global.attachEvent("onunload",unloadHandler)}else if(global.addEventListener){global.addEventListener("beforeunload",unloadHandler,false)}}function unloadHandler(){for(var i in Request.requests){if(Request.requests.hasOwnProperty(i)){Request.requests[i].abort()}}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./polling":23,"component-emitter":26,"component-inherit":13,debug:14,"xmlhttprequest-ssl":25}],23:[function(_dereq_,module,exports){var Transport=_dereq_("../transport");var parseqs=_dereq_("parseqs");var parser=_dereq_("engine.io-parser");var inherit=_dereq_("component-inherit");var yeast=_dereq_("yeast");var debug=_dereq_("debug")("engine.io-client:polling");module.exports=Polling;var hasXHR2=function(){var XMLHttpRequest=_dereq_("xmlhttprequest-ssl");var xhr=new XMLHttpRequest({xdomain:false});return null!=xhr.responseType}();function Polling(opts){var forceBase64=opts&&opts.forceBase64;if(!hasXHR2||forceBase64){this.supportsBinary=false}Transport.call(this,opts)}inherit(Polling,Transport);Polling.prototype.name="polling";Polling.prototype.doOpen=function(){this.poll()};Polling.prototype.pause=function(onPause){var pending=0;var self=this;this.readyState="pausing";function pause(){debug("paused");self.readyState="paused";onPause()}if(this.polling||!this.writable){var total=0;if(this.polling){debug("we are currently polling - waiting to pause");total++;this.once("pollComplete",function(){debug("pre-pause polling complete");--total||pause()})}if(!this.writable){debug("we are currently writing - waiting to pause");total++;this.once("drain",function(){debug("pre-pause writing complete");--total||pause()})}}else{pause()}};Polling.prototype.poll=function(){debug("polling");this.polling=true;this.doPoll();this.emit("poll")};Polling.prototype.onData=function(data){var self=this;debug("polling got data %s",data);var callback=function(packet,index,total){if("opening"==self.readyState){self.onOpen()}if("close"==packet.type){self.onClose();return false}self.onPacket(packet)};parser.decodePayload(data,this.socket.binaryType,callback);if("closed"!=this.readyState){this.polling=false;this.emit("pollComplete");if("open"==this.readyState){this.poll()}else{debug('ignoring poll - transport state "%s"',this.readyState)}}};Polling.prototype.doClose=function(){var self=this;function close(){debug("writing close packet");self.write([{type:"close"}])}if("open"==this.readyState){debug("transport open - closing");close()}else{debug("transport not open - deferring close");this.once("open",close)}};Polling.prototype.write=function(packets){var self=this;this.writable=false;var callbackfn=function(){self.writable=true;self.emit("drain")};var self=this;parser.encodePayload(packets,this.supportsBinary,function(data){self.doWrite(data,callbackfn)})};Polling.prototype.uri=function(){var query=this.query||{};var schema=this.secure?"https":"http";var port="";if(false!==this.timestampRequests){query[this.timestampParam]=yeast()}if(!this.supportsBinary&&!query.sid){query.b64=1}query=parseqs.encode(query);if(this.port&&("https"==schema&&this.port!=443||"http"==schema&&this.port!=80)){port=":"+this.port}if(query.length){query="?"+query}var ipv6=this.hostname.indexOf(":")!==-1;return schema+"://"+(ipv6?"["+this.hostname+"]":this.hostname)+port+this.path+query}},{"../transport":19,"component-inherit":13,debug:14,"engine.io-parser":27,parseqs:38,"xmlhttprequest-ssl":25,yeast:46}],24:[function(_dereq_,module,exports){(function(global){var Transport=_dereq_("../transport");var parser=_dereq_("engine.io-parser");var parseqs=_dereq_("parseqs");var inherit=_dereq_("component-inherit");var yeast=_dereq_("yeast");var debug=_dereq_("debug")("engine.io-client:websocket");var BrowserWebSocket=global.WebSocket||global.MozWebSocket;var WebSocket=BrowserWebSocket||(typeof window!=="undefined"?null:_dereq_("ws"));module.exports=WS;function WS(opts){var forceBase64=opts&&opts.forceBase64;if(forceBase64){this.supportsBinary=false}this.perMessageDeflate=opts.perMessageDeflate;Transport.call(this,opts)}inherit(WS,Transport);WS.prototype.name="websocket";WS.prototype.supportsBinary=true;WS.prototype.doOpen=function(){if(!this.check()){return}var self=this;var uri=this.uri();var protocols=void 0;var opts={agent:this.agent,perMessageDeflate:this.perMessageDeflate};opts.pfx=this.pfx;opts.key=this.key;opts.passphrase=this.passphrase;opts.cert=this.cert;opts.ca=this.ca;opts.ciphers=this.ciphers;opts.rejectUnauthorized=this.rejectUnauthorized;if(this.extraHeaders){opts.headers=this.extraHeaders}this.ws=BrowserWebSocket?new WebSocket(uri):new WebSocket(uri,protocols,opts);if(this.ws.binaryType===undefined){this.supportsBinary=false}if(this.ws.supports&&this.ws.supports.binary){this.supportsBinary=true;this.ws.binaryType="buffer"}else{this.ws.binaryType="arraybuffer"}this.addEventListeners()};WS.prototype.addEventListeners=function(){var self=this;this.ws.onopen=function(){self.onOpen()};this.ws.onclose=function(){self.onClose()};this.ws.onmessage=function(ev){self.onData(ev.data)};this.ws.onerror=function(e){self.onError("websocket error",e)}};if("undefined"!=typeof navigator&&/iPad|iPhone|iPod/i.test(navigator.userAgent)){WS.prototype.onData=function(data){var self=this;setTimeout(function(){Transport.prototype.onData.call(self,data)},0)}}WS.prototype.write=function(packets){var self=this;this.writable=false;var total=packets.length;for(var i=0,l=total;i<l;i++){(function(packet){parser.encodePacket(packet,self.supportsBinary,function(data){if(!BrowserWebSocket){var opts={};if(packet.options){opts.compress=packet.options.compress}if(self.perMessageDeflate){var len="string"==typeof data?global.Buffer.byteLength(data):data.length;if(len<self.perMessageDeflate.threshold){opts.compress=false}}}try{if(BrowserWebSocket){self.ws.send(data)}else{self.ws.send(data,opts)}}catch(e){debug("websocket closed before onclose event")}--total||done()})})(packets[i])}function done(){self.emit("flush");setTimeout(function(){self.writable=true;self.emit("drain")},0)}};WS.prototype.onClose=function(){Transport.prototype.onClose.call(this)};WS.prototype.doClose=function(){if(typeof this.ws!=="undefined"){this.ws.close()}};WS.prototype.uri=function(){var query=this.query||{};var schema=this.secure?"wss":"ws";var port="";if(this.port&&("wss"==schema&&this.port!=443||"ws"==schema&&this.port!=80)){port=":"+this.port}if(this.timestampRequests){query[this.timestampParam]=yeast()}if(!this.supportsBinary){query.b64=1}query=parseqs.encode(query);if(query.length){query="?"+query}var ipv6=this.hostname.indexOf(":")!==-1;return schema+"://"+(ipv6?"["+this.hostname+"]":this.hostname)+port+this.path+query};WS.prototype.check=function(){return!!WebSocket&&!("__initialize"in WebSocket&&this.name===WS.prototype.name)}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"../transport":19,"component-inherit":13,debug:14,"engine.io-parser":27,parseqs:38,ws:undefined,yeast:46}],25:[function(_dereq_,module,exports){var hasCORS=_dereq_("has-cors");module.exports=function(opts){var xdomain=opts.xdomain;var xscheme=opts.xscheme;var enablesXDR=opts.enablesXDR;try{if("undefined"!=typeof XMLHttpRequest&&(!xdomain||hasCORS)){return new XMLHttpRequest}}catch(e){}try{if("undefined"!=typeof XDomainRequest&&!xscheme&&enablesXDR){return new XDomainRequest}}catch(e){}if(!xdomain){try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}}},{"has-cors":32}],26:[function(_dereq_,module,exports){module.exports=Emitter;function Emitter(obj){if(obj)return mixin(obj)}function mixin(obj){for(var key in Emitter.prototype){obj[key]=Emitter.prototype[key]}return obj}Emitter.prototype.on=Emitter.prototype.addEventListener=function(event,fn){this._callbacks=this._callbacks||{};(this._callbacks[event]=this._callbacks[event]||[]).push(fn);return this};Emitter.prototype.once=function(event,fn){var self=this;this._callbacks=this._callbacks||{};function on(){self.off(event,on);fn.apply(this,arguments)}on.fn=fn;this.on(event,on);return this};Emitter.prototype.off=Emitter.prototype.removeListener=Emitter.prototype.removeAllListeners=Emitter.prototype.removeEventListener=function(event,fn){this._callbacks=this._callbacks||{};if(0==arguments.length){this._callbacks={};return this}var callbacks=this._callbacks[event];if(!callbacks)return this;if(1==arguments.length){delete this._callbacks[event];return this}var cb;for(var i=0;i<callbacks.length;i++){cb=callbacks[i];if(cb===fn||cb.fn===fn){callbacks.splice(i,1);break}}return this};Emitter.prototype.emit=function(event){this._callbacks=this._callbacks||{};var args=[].slice.call(arguments,1),callbacks=this._callbacks[event];if(callbacks){callbacks=callbacks.slice(0);for(var i=0,len=callbacks.length;i<len;++i){callbacks[i].apply(this,args)}}return this};Emitter.prototype.listeners=function(event){this._callbacks=this._callbacks||{};return this._callbacks[event]||[]};Emitter.prototype.hasListeners=function(event){return!!this.listeners(event).length}},{}],27:[function(_dereq_,module,exports){(function(global){var keys=_dereq_("./keys");var hasBinary=_dereq_("has-binary");var sliceBuffer=_dereq_("arraybuffer.slice");var base64encoder=_dereq_("base64-arraybuffer");var after=_dereq_("after");var utf8=_dereq_("utf8");var isAndroid=navigator.userAgent.match(/Android/i);var isPhantomJS=/PhantomJS/i.test(navigator.userAgent);var dontSendBlobs=isAndroid||isPhantomJS;exports.protocol=3;var packets=exports.packets={open:0,close:1,ping:2,pong:3,message:4,upgrade:5,noop:6};var packetslist=keys(packets);var err={type:"error",data:"parser error"};var Blob=_dereq_("blob");exports.encodePacket=function(packet,supportsBinary,utf8encode,callback){if("function"==typeof supportsBinary){callback=supportsBinary;supportsBinary=false}if("function"==typeof utf8encode){callback=utf8encode;utf8encode=null}var data=packet.data===undefined?undefined:packet.data.buffer||packet.data;if(global.ArrayBuffer&&data instanceof ArrayBuffer){return encodeArrayBuffer(packet,supportsBinary,callback)}else if(Blob&&data instanceof global.Blob){return encodeBlob(packet,supportsBinary,callback)}if(data&&data.base64){return encodeBase64Object(packet,callback)}var encoded=packets[packet.type];if(undefined!==packet.data){encoded+=utf8encode?utf8.encode(String(packet.data)):String(packet.data)}return callback(""+encoded)};function encodeBase64Object(packet,callback){var message="b"+exports.packets[packet.type]+packet.data.data;return callback(message)}function encodeArrayBuffer(packet,supportsBinary,callback){if(!supportsBinary){return exports.encodeBase64Packet(packet,callback)}var data=packet.data;var contentArray=new Uint8Array(data);var resultBuffer=new Uint8Array(1+data.byteLength);resultBuffer[0]=packets[packet.type];for(var i=0;i<contentArray.length;i++){resultBuffer[i+1]=contentArray[i]}return callback(resultBuffer.buffer)}function encodeBlobAsArrayBuffer(packet,supportsBinary,callback){if(!supportsBinary){return exports.encodeBase64Packet(packet,callback)}var fr=new FileReader;fr.onload=function(){packet.data=fr.result;exports.encodePacket(packet,supportsBinary,true,callback)};return fr.readAsArrayBuffer(packet.data)}function encodeBlob(packet,supportsBinary,callback){if(!supportsBinary){return exports.encodeBase64Packet(packet,callback)}if(dontSendBlobs){return encodeBlobAsArrayBuffer(packet,supportsBinary,callback)}var length=new Uint8Array(1);length[0]=packets[packet.type];var blob=new Blob([length.buffer,packet.data]);return callback(blob)}exports.encodeBase64Packet=function(packet,callback){var message="b"+exports.packets[packet.type];if(Blob&&packet.data instanceof global.Blob){var fr=new FileReader;fr.onload=function(){var b64=fr.result.split(",")[1];callback(message+b64)};return fr.readAsDataURL(packet.data)}var b64data;try{b64data=String.fromCharCode.apply(null,new Uint8Array(packet.data))}catch(e){var typed=new Uint8Array(packet.data);var basic=new Array(typed.length);for(var i=0;i<typed.length;i++){basic[i]=typed[i]}b64data=String.fromCharCode.apply(null,basic)}message+=global.btoa(b64data);return callback(message)};exports.decodePacket=function(data,binaryType,utf8decode){if(typeof data=="string"||data===undefined){if(data.charAt(0)=="b"){return exports.decodeBase64Packet(data.substr(1),binaryType)}if(utf8decode){try{data=utf8.decode(data)}catch(e){return err}}var type=data.charAt(0);if(Number(type)!=type||!packetslist[type]){return err}if(data.length>1){return{type:packetslist[type],data:data.substring(1)}}else{return{type:packetslist[type]}}}var asArray=new Uint8Array(data);var type=asArray[0];var rest=sliceBuffer(data,1);if(Blob&&binaryType==="blob"){rest=new Blob([rest])}return{type:packetslist[type],data:rest}};exports.decodeBase64Packet=function(msg,binaryType){var type=packetslist[msg.charAt(0)];if(!global.ArrayBuffer){return{type:type,data:{base64:true,data:msg.substr(1)}}}var data=base64encoder.decode(msg.substr(1));if(binaryType==="blob"&&Blob){data=new Blob([data])}return{type:type,data:data}};exports.encodePayload=function(packets,supportsBinary,callback){if(typeof supportsBinary=="function"){callback=supportsBinary;supportsBinary=null}var isBinary=hasBinary(packets);if(supportsBinary&&isBinary){if(Blob&&!dontSendBlobs){return exports.encodePayloadAsBlob(packets,callback)}return exports.encodePayloadAsArrayBuffer(packets,callback)}if(!packets.length){return callback("0:")}function setLengthHeader(message){return message.length+":"+message}function encodeOne(packet,doneCallback){exports.encodePacket(packet,!isBinary?false:supportsBinary,true,function(message){doneCallback(null,setLengthHeader(message))})}map(packets,encodeOne,function(err,results){return callback(results.join(""))})};function map(ary,each,done){var result=new Array(ary.length);var next=after(ary.length,done);var eachWithIndex=function(i,el,cb){each(el,function(error,msg){result[i]=msg;cb(error,result)})};for(var i=0;i<ary.length;i++){eachWithIndex(i,ary[i],next)}}exports.decodePayload=function(data,binaryType,callback){if(typeof data!="string"){return exports.decodePayloadAsBinary(data,binaryType,callback)}if(typeof binaryType==="function"){callback=binaryType;binaryType=null}var packet;if(data==""){return callback(err,0,1)}var length="",n,msg;for(var i=0,l=data.length;i<l;i++){var chr=data.charAt(i);if(":"!=chr){length+=chr}else{if(""==length||length!=(n=Number(length))){return callback(err,0,1)}msg=data.substr(i+1,n);if(length!=msg.length){return callback(err,0,1)}if(msg.length){packet=exports.decodePacket(msg,binaryType,true);if(err.type==packet.type&&err.data==packet.data){return callback(err,0,1)}var ret=callback(packet,i+n,l);if(false===ret)return}i+=n;length=""}}if(length!=""){return callback(err,0,1)}};exports.encodePayloadAsArrayBuffer=function(packets,callback){if(!packets.length){return callback(new ArrayBuffer(0))}function encodeOne(packet,doneCallback){exports.encodePacket(packet,true,true,function(data){return doneCallback(null,data)})}map(packets,encodeOne,function(err,encodedPackets){var totalLength=encodedPackets.reduce(function(acc,p){var len;if(typeof p==="string"){len=p.length}else{len=p.byteLength}return acc+len.toString().length+len+2},0);var resultArray=new Uint8Array(totalLength);var bufferIndex=0;encodedPackets.forEach(function(p){var isString=typeof p==="string";var ab=p;if(isString){var view=new Uint8Array(p.length);for(var i=0;i<p.length;i++){view[i]=p.charCodeAt(i)}ab=view.buffer}if(isString){resultArray[bufferIndex++]=0}else{resultArray[bufferIndex++]=1}var lenStr=ab.byteLength.toString();for(var i=0;i<lenStr.length;i++){resultArray[bufferIndex++]=parseInt(lenStr[i])}resultArray[bufferIndex++]=255;var view=new Uint8Array(ab);for(var i=0;i<view.length;i++){resultArray[bufferIndex++]=view[i]}});return callback(resultArray.buffer)})};exports.encodePayloadAsBlob=function(packets,callback){function encodeOne(packet,doneCallback){exports.encodePacket(packet,true,true,function(encoded){var binaryIdentifier=new Uint8Array(1);binaryIdentifier[0]=1;if(typeof encoded==="string"){var view=new Uint8Array(encoded.length);for(var i=0;i<encoded.length;i++){view[i]=encoded.charCodeAt(i)}encoded=view.buffer;binaryIdentifier[0]=0}var len=encoded instanceof ArrayBuffer?encoded.byteLength:encoded.size;var lenStr=len.toString();var lengthAry=new Uint8Array(lenStr.length+1);
  143.     for(var i=0;i<lenStr.length;i++){lengthAry[i]=parseInt(lenStr[i])}lengthAry[lenStr.length]=255;if(Blob){var blob=new Blob([binaryIdentifier.buffer,lengthAry.buffer,encoded]);doneCallback(null,blob)}})}map(packets,encodeOne,function(err,results){return callback(new Blob(results))})};exports.decodePayloadAsBinary=function(data,binaryType,callback){if(typeof binaryType==="function"){callback=binaryType;binaryType=null}var bufferTail=data;var buffers=[];var numberTooLong=false;while(bufferTail.byteLength>0){var tailArray=new Uint8Array(bufferTail);var isString=tailArray[0]===0;var msgLength="";for(var i=1;;i++){if(tailArray[i]==255)break;if(msgLength.length>310){numberTooLong=true;break}msgLength+=tailArray[i]}if(numberTooLong)return callback(err,0,1);bufferTail=sliceBuffer(bufferTail,2+msgLength.length);msgLength=parseInt(msgLength);var msg=sliceBuffer(bufferTail,0,msgLength);if(isString){try{msg=String.fromCharCode.apply(null,new Uint8Array(msg))}catch(e){var typed=new Uint8Array(msg);msg="";for(var i=0;i<typed.length;i++){msg+=String.fromCharCode(typed[i])}}}buffers.push(msg);bufferTail=sliceBuffer(bufferTail,msgLength)}var total=buffers.length;buffers.forEach(function(buffer,i){callback(exports.decodePacket(buffer,binaryType,true),i,total)})}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./keys":28,after:6,"arraybuffer.slice":7,"base64-arraybuffer":9,blob:10,"has-binary":29,utf8:45}],28:[function(_dereq_,module,exports){module.exports=Object.keys||function keys(obj){var arr=[];var has=Object.prototype.hasOwnProperty;for(var i in obj){if(has.call(obj,i)){arr.push(i)}}return arr}},{}],29:[function(_dereq_,module,exports){(function(global){var isArray=_dereq_("isarray");module.exports=hasBinary;function hasBinary(data){function _hasBinary(obj){if(!obj)return false;if(global.Buffer&&global.Buffer.isBuffer(obj)||global.ArrayBuffer&&obj instanceof ArrayBuffer||global.Blob&&obj instanceof Blob||global.File&&obj instanceof File){return true}if(isArray(obj)){for(var i=0;i<obj.length;i++){if(_hasBinary(obj[i])){return true}}}else if(obj&&"object"==typeof obj){if(obj.toJSON){obj=obj.toJSON()}for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)&&_hasBinary(obj[key])){return true}}}return false}return _hasBinary(data)}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{isarray:34}],30:[function(_dereq_,module,exports){module.exports=function(){return this}()},{}],31:[function(_dereq_,module,exports){(function(global){var isArray=_dereq_("isarray");module.exports=hasBinary;function hasBinary(data){function _hasBinary(obj){if(!obj)return false;if(global.Buffer&&global.Buffer.isBuffer&&global.Buffer.isBuffer(obj)||global.ArrayBuffer&&obj instanceof ArrayBuffer||global.Blob&&obj instanceof Blob||global.File&&obj instanceof File){return true}if(isArray(obj)){for(var i=0;i<obj.length;i++){if(_hasBinary(obj[i])){return true}}}else if(obj&&"object"==typeof obj){if(obj.toJSON&&"function"==typeof obj.toJSON){obj=obj.toJSON()}for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)&&_hasBinary(obj[key])){return true}}}return false}return _hasBinary(data)}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{isarray:34}],32:[function(_dereq_,module,exports){var global=_dereq_("global");try{module.exports="XMLHttpRequest"in global&&"withCredentials"in new global.XMLHttpRequest}catch(err){module.exports=false}},{global:30}],33:[function(_dereq_,module,exports){var indexOf=[].indexOf;module.exports=function(arr,obj){if(indexOf)return arr.indexOf(obj);for(var i=0;i<arr.length;++i){if(arr[i]===obj)return i}return-1}},{}],34:[function(_dereq_,module,exports){module.exports=Array.isArray||function(arr){return Object.prototype.toString.call(arr)=="[object Array]"}},{}],35:[function(_dereq_,module,exports){(function(global){(function(){var isLoader=typeof define==="function"&&define.amd;var objectTypes={"function":true,object:true};var freeExports=objectTypes[typeof exports]&&exports&&!exports.nodeType&&exports;var root=objectTypes[typeof window]&&window||this,freeGlobal=freeExports&&objectTypes[typeof module]&&module&&!module.nodeType&&typeof global=="object"&&global;if(freeGlobal&&(freeGlobal["global"]===freeGlobal||freeGlobal["window"]===freeGlobal||freeGlobal["self"]===freeGlobal)){root=freeGlobal}function runInContext(context,exports){context||(context=root["Object"]());exports||(exports=root["Object"]());var Number=context["Number"]||root["Number"],String=context["String"]||root["String"],Object=context["Object"]||root["Object"],Date=context["Date"]||root["Date"],SyntaxError=context["SyntaxError"]||root["SyntaxError"],TypeError=context["TypeError"]||root["TypeError"],Math=context["Math"]||root["Math"],nativeJSON=context["JSON"]||root["JSON"];if(typeof nativeJSON=="object"&&nativeJSON){exports.stringify=nativeJSON.stringify;exports.parse=nativeJSON.parse}var objectProto=Object.prototype,getClass=objectProto.toString,isProperty,forEach,undef;var isExtended=new Date(-0xc782b5b800cec);try{isExtended=isExtended.getUTCFullYear()==-109252&&isExtended.getUTCMonth()===0&&isExtended.getUTCDate()===1&&isExtended.getUTCHours()==10&&isExtended.getUTCMinutes()==37&&isExtended.getUTCSeconds()==6&&isExtended.getUTCMilliseconds()==708}catch(exception){}function has(name){if(has[name]!==undef){return has[name]}var isSupported;if(name=="bug-string-char-index"){isSupported="a"[0]!="a"}else if(name=="json"){isSupported=has("json-stringify")&&has("json-parse")}else{var value,serialized='{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';if(name=="json-stringify"){var stringify=exports.stringify,stringifySupported=typeof stringify=="function"&&isExtended;if(stringifySupported){(value=function(){return 1}).toJSON=value;try{stringifySupported=stringify(0)==="0"&&stringify(new Number)==="0"&&stringify(new String)=='""'&&stringify(getClass)===undef&&stringify(undef)===undef&&stringify()===undef&&stringify(value)==="1"&&stringify([value])=="[1]"&&stringify([undef])=="[null]"&&stringify(null)=="null"&&stringify([undef,getClass,null])=="[null,null,null]"&&stringify({a:[value,true,false,null,"\x00\b\n\f\r  "]})==serialized&&stringify(null,value)==="1"&&stringify([1,2],null,1)=="[\n 1,\n 2\n]"&&stringify(new Date(-864e13))=='"-271821-04-20T00:00:00.000Z"'&&stringify(new Date(864e13))=='"+275760-09-13T00:00:00.000Z"'&&stringify(new Date(-621987552e5))=='"-000001-01-01T00:00:00.000Z"'&&stringify(new Date(-1))=='"1969-12-31T23:59:59.999Z"'}catch(exception){stringifySupported=false}}isSupported=stringifySupported}if(name=="json-parse"){var parse=exports.parse;if(typeof parse=="function"){try{if(parse("0")===0&&!parse(false)){value=parse(serialized);var parseSupported=value["a"].length==5&&value["a"][0]===1;if(parseSupported){try{parseSupported=!parse('"  "')}catch(exception){}if(parseSupported){try{parseSupported=parse("01")!==1}catch(exception){}}if(parseSupported){try{parseSupported=parse("1.")!==1}catch(exception){}}}}}catch(exception){parseSupported=false}}isSupported=parseSupported}}return has[name]=!!isSupported}if(!has("json")){var functionClass="[object Function]",dateClass="[object Date]",numberClass="[object Number]",stringClass="[object String]",arrayClass="[object Array]",booleanClass="[object Boolean]";var charIndexBuggy=has("bug-string-char-index");if(!isExtended){var floor=Math.floor;var Months=[0,31,59,90,120,151,181,212,243,273,304,334];var getDay=function(year,month){return Months[month]+365*(year-1970)+floor((year-1969+(month=+(month>1)))/4)-floor((year-1901+month)/100)+floor((year-1601+month)/400)}}if(!(isProperty=objectProto.hasOwnProperty)){isProperty=function(property){var members={},constructor;if((members.__proto__=null,members.__proto__={toString:1},members).toString!=getClass){isProperty=function(property){var original=this.__proto__,result=property in(this.__proto__=null,this);this.__proto__=original;return result}}else{constructor=members.constructor;isProperty=function(property){var parent=(this.constructor||constructor).prototype;return property in this&&!(property in parent&&this[property]===parent[property])}}members=null;return isProperty.call(this,property)}}forEach=function(object,callback){var size=0,Properties,members,property;(Properties=function(){this.valueOf=0}).prototype.valueOf=0;members=new Properties;for(property in members){if(isProperty.call(members,property)){size++}}Properties=members=null;if(!size){members=["valueOf","toString","toLocaleString","propertyIsEnumerable","isPrototypeOf","hasOwnProperty","constructor"];forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,length;var hasProperty=!isFunction&&typeof object.constructor!="function"&&objectTypes[typeof object.hasOwnProperty]&&object.hasOwnProperty||isProperty;for(property in object){if(!(isFunction&&property=="prototype")&&hasProperty.call(object,property)){callback(property)}}for(length=members.length;property=members[--length];hasProperty.call(object,property)&&callback(property));}}else if(size==2){forEach=function(object,callback){var members={},isFunction=getClass.call(object)==functionClass,property;for(property in object){if(!(isFunction&&property=="prototype")&&!isProperty.call(members,property)&&(members[property]=1)&&isProperty.call(object,property)){callback(property)}}}}else{forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,isConstructor;for(property in object){if(!(isFunction&&property=="prototype")&&isProperty.call(object,property)&&!(isConstructor=property==="constructor")){callback(property)}}if(isConstructor||isProperty.call(object,property="constructor")){callback(property)}}}return forEach(object,callback)};if(!has("json-stringify")){var Escapes={92:"\\\\",34:'\\"',8:"\\b",12:"\\f",10:"\\n",13:"\\r",9:"\\t"};var leadingZeroes="000000";var toPaddedString=function(width,value){return(leadingZeroes+(value||0)).slice(-width)};var unicodePrefix="\\u00";var quote=function(value){var result='"',index=0,length=value.length,useCharIndex=!charIndexBuggy||length>10;var symbols=useCharIndex&&(charIndexBuggy?value.split(""):value);for(;index<length;index++){var charCode=value.charCodeAt(index);switch(charCode){case 8:case 9:case 10:case 12:case 13:case 34:case 92:result+=Escapes[charCode];break;default:if(charCode<32){result+=unicodePrefix+toPaddedString(2,charCode.toString(16));break}result+=useCharIndex?symbols[index]:value.charAt(index)}}return result+'"'};var serialize=function(property,object,callback,properties,whitespace,indentation,stack){var value,className,year,month,date,time,hours,minutes,seconds,milliseconds,results,element,index,length,prefix,result;try{value=object[property]}catch(exception){}if(typeof value=="object"&&value){className=getClass.call(value);if(className==dateClass&&!isProperty.call(value,"toJSON")){if(value>-1/0&&value<1/0){if(getDay){date=floor(value/864e5);for(year=floor(date/365.2425)+1970-1;getDay(year+1,0)<=date;year++);for(month=floor((date-getDay(year,0))/30.42);getDay(year,month+1)<=date;month++);date=1+date-getDay(year,month);time=(value%864e5+864e5)%864e5;hours=floor(time/36e5)%24;minutes=floor(time/6e4)%60;seconds=floor(time/1e3)%60;milliseconds=time%1e3}else{year=value.getUTCFullYear();month=value.getUTCMonth();date=value.getUTCDate();hours=value.getUTCHours();minutes=value.getUTCMinutes();seconds=value.getUTCSeconds();milliseconds=value.getUTCMilliseconds()}value=(year<=0||year>=1e4?(year<0?"-":"+")+toPaddedString(6,year<0?-year:year):toPaddedString(4,year))+"-"+toPaddedString(2,month+1)+"-"+toPaddedString(2,date)+"T"+toPaddedString(2,hours)+":"+toPaddedString(2,minutes)+":"+toPaddedString(2,seconds)+"."+toPaddedString(3,milliseconds)+"Z"}else{value=null}}else if(typeof value.toJSON=="function"&&(className!=numberClass&&className!=stringClass&&className!=arrayClass||isProperty.call(value,"toJSON"))){value=value.toJSON(property)}}if(callback){value=callback.call(object,property,value)}if(value===null){return"null"}className=getClass.call(value);if(className==booleanClass){return""+value}else if(className==numberClass){return value>-1/0&&value<1/0?""+value:"null"}else if(className==stringClass){return quote(""+value)}if(typeof value=="object"){for(length=stack.length;length--;){if(stack[length]===value){throw TypeError()}}stack.push(value);results=[];prefix=indentation;indentation+=whitespace;if(className==arrayClass){for(index=0,length=value.length;index<length;index++){element=serialize(index,value,callback,properties,whitespace,indentation,stack);results.push(element===undef?"null":element)}result=results.length?whitespace?"[\n"+indentation+results.join(",\n"+indentation)+"\n"+prefix+"]":"["+results.join(",")+"]":"[]"}else{forEach(properties||value,function(property){var element=serialize(property,value,callback,properties,whitespace,indentation,stack);if(element!==undef){results.push(quote(property)+":"+(whitespace?" ":"")+element)}});result=results.length?whitespace?"{\n"+indentation+results.join(",\n"+indentation)+"\n"+prefix+"}":"{"+results.join(",")+"}":"{}"}stack.pop();return result}};exports.stringify=function(source,filter,width){var whitespace,callback,properties,className;if(objectTypes[typeof filter]&&filter){if((className=getClass.call(filter))==functionClass){callback=filter}else if(className==arrayClass){properties={};for(var index=0,length=filter.length,value;index<length;value=filter[index++],(className=getClass.call(value),className==stringClass||className==numberClass)&&(properties[value]=1));}}if(width){if((className=getClass.call(width))==numberClass){if((width-=width%1)>0){for(whitespace="",width>10&&(width=10);whitespace.length<width;whitespace+=" ");}}else if(className==stringClass){whitespace=width.length<=10?width:width.slice(0,10)}}return serialize("",(value={},value[""]=source,value),callback,properties,whitespace,"",[])}}if(!has("json-parse")){var fromCharCode=String.fromCharCode;var Unescapes={92:"\\",34:'"',47:"/",98:"\b",116:"  ",110:"\n",102:"\f",114:"\r"};var Index,Source;var abort=function(){Index=Source=null;throw SyntaxError()};var lex=function(){var source=Source,length=source.length,value,begin,position,isSigned,charCode;while(Index<length){charCode=source.charCodeAt(Index);switch(charCode){case 9:case 10:case 13:case 32:Index++;break;case 123:case 125:case 91:case 93:case 58:case 44:value=charIndexBuggy?source.charAt(Index):source[Index];Index++;return value;case 34:for(value="@",Index++;Index<length;){charCode=source.charCodeAt(Index);if(charCode<32){abort()}else if(charCode==92){charCode=source.charCodeAt(++Index);switch(charCode){case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:value+=Unescapes[charCode];Index++;break;case 117:begin=++Index;for(position=Index+4;Index<position;Index++){charCode=source.charCodeAt(Index);if(!(charCode>=48&&charCode<=57||charCode>=97&&charCode<=102||charCode>=65&&charCode<=70)){abort()}}value+=fromCharCode("0x"+source.slice(begin,Index));break;default:abort()}}else{if(charCode==34){break}charCode=source.charCodeAt(Index);begin=Index;while(charCode>=32&&charCode!=92&&charCode!=34){charCode=source.charCodeAt(++Index)}value+=source.slice(begin,Index)}}if(source.charCodeAt(Index)==34){Index++;return value}abort();default:begin=Index;if(charCode==45){isSigned=true;charCode=source.charCodeAt(++Index)}if(charCode>=48&&charCode<=57){if(charCode==48&&(charCode=source.charCodeAt(Index+1),charCode>=48&&charCode<=57)){abort()}isSigned=false;for(;Index<length&&(charCode=source.charCodeAt(Index),charCode>=48&&charCode<=57);Index++);if(source.charCodeAt(Index)==46){position=++Index;for(;position<length&&(charCode=source.charCodeAt(position),charCode>=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}charCode=source.charCodeAt(Index);if(charCode==101||charCode==69){charCode=source.charCodeAt(++Index);if(charCode==43||charCode==45){Index++}for(position=Index;position<length&&(charCode=source.charCodeAt(position),charCode>=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}return+source.slice(begin,Index)}if(isSigned){abort()}if(source.slice(Index,Index+4)=="true"){Index+=4;return true}else if(source.slice(Index,Index+5)=="false"){Index+=5;return false}else if(source.slice(Index,Index+4)=="null"){Index+=4;return null}abort()}}return"$"};var get=function(value){var results,hasMembers;if(value=="$"){abort()}if(typeof value=="string"){if((charIndexBuggy?value.charAt(0):value[0])=="@"){return value.slice(1)}if(value=="["){results=[];for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="]"){break}if(hasMembers){if(value==","){value=lex();if(value=="]"){abort()}}else{abort()}}if(value==","){abort()}results.push(get(value))}return results}else if(value=="{"){results={};for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="}"){break}if(hasMembers){if(value==","){value=lex();if(value=="}"){abort()}}else{abort()}}if(value==","||typeof value!="string"||(charIndexBuggy?value.charAt(0):value[0])!="@"||lex()!=":"){abort()}results[value.slice(1)]=get(lex())}return results}abort()}return value};var update=function(source,property,callback){var element=walk(source,property,callback);if(element===undef){delete source[property]}else{source[property]=element}};var walk=function(source,property,callback){var value=source[property],length;if(typeof value=="object"&&value){if(getClass.call(value)==arrayClass){for(length=value.length;length--;){update(value,length,callback)}}else{forEach(value,function(property){update(value,property,callback)})}}return callback.call(source,property,value)};exports.parse=function(source,callback){var result,value;Index=0;Source=""+source;result=get(lex());if(lex()!="$"){abort()}Index=Source=null;return callback&&getClass.call(callback)==functionClass?walk((value={},value[""]=result,value),"",callback):result}}}exports["runInContext"]=runInContext;return exports}if(freeExports&&!isLoader){runInContext(root,freeExports)}else{var nativeJSON=root.JSON,previousJSON=root["JSON3"],isRestored=false;var JSON3=runInContext(root,root["JSON3"]={noConflict:function(){if(!isRestored){isRestored=true;root.JSON=nativeJSON;root["JSON3"]=previousJSON;nativeJSON=previousJSON=null}return JSON3}});root.JSON={parse:JSON3.parse,stringify:JSON3.stringify}}if(isLoader){define(function(){return JSON3})}}).call(this)}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],36:[function(_dereq_,module,exports){var s=1e3;var m=s*60;var h=m*60;var d=h*24;var y=d*365.25;module.exports=function(val,options){options=options||{};if("string"==typeof val)return parse(val);return options.long?long(val):short(val)};function parse(str){str=""+str;if(str.length>1e4)return;var match=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);if(!match)return;var n=parseFloat(match[1]);var type=(match[2]||"ms").toLowerCase();switch(type){case"years":case"year":case"yrs":case"yr":case"y":return n*y;case"days":case"day":case"d":return n*d;case"hours":case"hour":case"hrs":case"hr":case"h":return n*h;case"minutes":case"minute":case"mins":case"min":case"m":return n*m;case"seconds":case"second":case"secs":case"sec":case"s":return n*s;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n}}function short(ms){if(ms>=d)return Math.round(ms/d)+"d";if(ms>=h)return Math.round(ms/h)+"h";if(ms>=m)return Math.round(ms/m)+"m";if(ms>=s)return Math.round(ms/s)+"s";return ms+"ms"}function long(ms){return plural(ms,d,"day")||plural(ms,h,"hour")||plural(ms,m,"minute")||plural(ms,s,"second")||ms+" ms"}function plural(ms,n,name){if(ms<n)return;if(ms<n*1.5)return Math.floor(ms/n)+" "+name;return Math.ceil(ms/n)+" "+name+"s"}},{}],37:[function(_dereq_,module,exports){(function(global){var rvalidchars=/^[\],:{}\s]*$/;var rvalidescape=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;var rvalidtokens=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;var rvalidbraces=/(?:^|:|,)(?:\s*\[)+/g;var rtrimLeft=/^\s+/;var rtrimRight=/\s+$/;module.exports=function parsejson(data){if("string"!=typeof data||!data){return null}data=data.replace(rtrimLeft,"").replace(rtrimRight,"");if(global.JSON&&JSON.parse){return JSON.parse(data)}if(rvalidchars.test(data.replace(rvalidescape,"@").replace(rvalidtokens,"]").replace(rvalidbraces,""))){return new Function("return "+data)()}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],38:[function(_dereq_,module,exports){exports.encode=function(obj){var str="";for(var i in obj){if(obj.hasOwnProperty(i)){if(str.length)str+="&";str+=encodeURIComponent(i)+"="+encodeURIComponent(obj[i])}}return str};exports.decode=function(qs){var qry={};var pairs=qs.split("&");for(var i=0,l=pairs.length;i<l;i++){var pair=pairs[i].split("=");qry[decodeURIComponent(pair[0])]=decodeURIComponent(pair[1])}return qry}},{}],39:[function(_dereq_,module,exports){var re=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;var parts=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];module.exports=function parseuri(str){var src=str,b=str.indexOf("["),e=str.indexOf("]");if(b!=-1&&e!=-1){str=str.substring(0,b)+str.substring(b,e).replace(/:/g,";")+str.substring(e,str.length)}var m=re.exec(str||""),uri={},i=14;while(i--){uri[parts[i]]=m[i]||""}if(b!=-1&&e!=-1){uri.source=src;uri.host=uri.host.substring(1,uri.host.length-1).replace(/;/g,":");uri.authority=uri.authority.replace("[","").replace("]","").replace(/;/g,":");uri.ipv6uri=true}return uri}},{}],40:[function(_dereq_,module,exports){(function(global){var isArray=_dereq_("isarray");var isBuf=_dereq_("./is-buffer");exports.deconstructPacket=function(packet){var buffers=[];var packetData=packet.data;function _deconstructPacket(data){if(!data)return data;if(isBuf(data)){var placeholder={_placeholder:true,num:buffers.length};buffers.push(data);return placeholder}else if(isArray(data)){var newData=new Array(data.length);for(var i=0;i<data.length;i++){newData[i]=_deconstructPacket(data[i])}return newData}else if("object"==typeof data&&!(data instanceof Date)){var newData={};for(var key in data){newData[key]=_deconstructPacket(data[key])}return newData}return data}var pack=packet;pack.data=_deconstructPacket(packetData);pack.attachments=buffers.length;return{packet:pack,buffers:buffers}};exports.reconstructPacket=function(packet,buffers){var curPlaceHolder=0;function _reconstructPacket(data){if(data&&data._placeholder){var buf=buffers[data.num];return buf}else if(isArray(data)){for(var i=0;i<data.length;i++){data[i]=_reconstructPacket(data[i])}return data}else if(data&&"object"==typeof data){for(var key in data){data[key]=_reconstructPacket(data[key])}return data}return data}packet.data=_reconstructPacket(packet.data);packet.attachments=undefined;return packet};exports.removeBlobs=function(data,callback){function _removeBlobs(obj,curKey,containingObject){if(!obj)return obj;if(global.Blob&&obj instanceof Blob||global.File&&obj instanceof File){pendingBlobs++;var fileReader=new FileReader;fileReader.onload=function(){if(containingObject){containingObject[curKey]=this.result}else{bloblessData=this.result}if(!--pendingBlobs){callback(bloblessData)}};fileReader.readAsArrayBuffer(obj)}else if(isArray(obj)){for(var i=0;i<obj.length;i++){_removeBlobs(obj[i],i,obj)}}else if(obj&&"object"==typeof obj&&!isBuf(obj)){for(var key in obj){_removeBlobs(obj[key],key,obj)}}}var pendingBlobs=0;var bloblessData=data;_removeBlobs(bloblessData);if(!pendingBlobs){callback(bloblessData)}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./is-buffer":42,isarray:34}],41:[function(_dereq_,module,exports){var debug=_dereq_("debug")("socket.io-parser");var json=_dereq_("json3");var isArray=_dereq_("isarray");var Emitter=_dereq_("component-emitter");var binary=_dereq_("./binary");var isBuf=_dereq_("./is-buffer");exports.protocol=4;exports.types=["CONNECT","DISCONNECT","EVENT","BINARY_EVENT","ACK","BINARY_ACK","ERROR"];exports.CONNECT=0;exports.DISCONNECT=1;exports.EVENT=2;exports.ACK=3;exports.ERROR=4;exports.BINARY_EVENT=5;exports.BINARY_ACK=6;exports.Encoder=Encoder;exports.Decoder=Decoder;function Encoder(){}Encoder.prototype.encode=function(obj,callback){debug("encoding packet %j",obj);if(exports.BINARY_EVENT==obj.type||exports.BINARY_ACK==obj.type){encodeAsBinary(obj,callback)}else{var encoding=encodeAsString(obj);callback([encoding])}};function encodeAsString(obj){var str="";var nsp=false;str+=obj.type;if(exports.BINARY_EVENT==obj.type||exports.BINARY_ACK==obj.type){str+=obj.attachments;str+="-"}if(obj.nsp&&"/"!=obj.nsp){nsp=true;str+=obj.nsp}if(null!=obj.id){if(nsp){str+=",";nsp=false}str+=obj.id}if(null!=obj.data){if(nsp)str+=",";str+=json.stringify(obj.data)}debug("encoded %j as %s",obj,str);return str}function encodeAsBinary(obj,callback){function writeEncoding(bloblessData){var deconstruction=binary.deconstructPacket(bloblessData);var pack=encodeAsString(deconstruction.packet);var buffers=deconstruction.buffers;buffers.unshift(pack);callback(buffers)}binary.removeBlobs(obj,writeEncoding)}function Decoder(){this.reconstructor=null}Emitter(Decoder.prototype);Decoder.prototype.add=function(obj){var packet;if("string"==typeof obj){packet=decodeString(obj);if(exports.BINARY_EVENT==packet.type||exports.BINARY_ACK==packet.type){this.reconstructor=new BinaryReconstructor(packet);if(this.reconstructor.reconPack.attachments===0){this.emit("decoded",packet)}}else{this.emit("decoded",packet)}}else if(isBuf(obj)||obj.base64){if(!this.reconstructor){throw new Error("got binary data when not reconstructing a packet")}else{packet=this.reconstructor.takeBinaryData(obj);if(packet){this.reconstructor=null;this.emit("decoded",packet)}}}else{throw new Error("Unknown type: "+obj)}};function decodeString(str){var p={};var i=0;p.type=Number(str.charAt(0));if(null==exports.types[p.type])return error();if(exports.BINARY_EVENT==p.type||exports.BINARY_ACK==p.type){var buf="";while(str.charAt(++i)!="-"){buf+=str.charAt(i);if(i==str.length)break}if(buf!=Number(buf)||str.charAt(i)!="-"){throw new Error("Illegal attachments")}p.attachments=Number(buf)}if("/"==str.charAt(i+1)){p.nsp="";while(++i){var c=str.charAt(i);if(","==c)break;p.nsp+=c;if(i==str.length)break}}else{p.nsp="/"}var next=str.charAt(i+1);if(""!==next&&Number(next)==next){p.id="";while(++i){var c=str.charAt(i);if(null==c||Number(c)!=c){--i;break}p.id+=str.charAt(i);if(i==str.length)break}p.id=Number(p.id)}if(str.charAt(++i)){try{p.data=json.parse(str.substr(i))}catch(e){return error()}}debug("decoded %s as %j",str,p);return p}Decoder.prototype.destroy=function(){if(this.reconstructor){this.reconstructor.finishedReconstruction()}};function BinaryReconstructor(packet){this.reconPack=packet;this.buffers=[]}BinaryReconstructor.prototype.takeBinaryData=function(binData){this.buffers.push(binData);if(this.buffers.length==this.reconPack.attachments){var packet=binary.reconstructPacket(this.reconPack,this.buffers);this.finishedReconstruction();return packet}return null};BinaryReconstructor.prototype.finishedReconstruction=function(){this.reconPack=null;this.buffers=[]};function error(data){return{type:exports.ERROR,data:"parser error"}}},{"./binary":40,"./is-buffer":42,"component-emitter":43,debug:14,isarray:34,json3:35}],42:[function(_dereq_,module,exports){(function(global){module.exports=isBuf;function isBuf(obj){return global.Buffer&&global.Buffer.isBuffer(obj)||global.ArrayBuffer&&obj instanceof ArrayBuffer}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],43:[function(_dereq_,module,exports){arguments[4][26][0].apply(exports,arguments)},{dup:26}],44:[function(_dereq_,module,exports){module.exports=toArray;function toArray(list,index){var array=[];index=index||0;for(var i=index||0;i<list.length;i++){array[i-index]=list[i]}return array}},{}],45:[function(_dereq_,module,exports){(function(global){(function(root){var freeExports=typeof exports=="object"&&exports;var freeModule=typeof module=="object"&&module&&module.exports==freeExports&&module;var freeGlobal=typeof global=="object"&&global;if(freeGlobal.global===freeGlobal||freeGlobal.window===freeGlobal){root=freeGlobal}var stringFromCharCode=String.fromCharCode;function ucs2decode(string){var output=[];var counter=0;var length=string.length;var value;var extra;while(counter<length){value=string.charCodeAt(counter++);if(value>=55296&&value<=56319&&counter<length){extra=string.charCodeAt(counter++);if((extra&64512)==56320){output.push(((value&1023)<<10)+(extra&1023)+65536)}else{output.push(value);counter--}}else{output.push(value)}}return output}function ucs2encode(array){var length=array.length;var index=-1;var value;var output="";while(++index<length){value=array[index];if(value>65535){value-=65536;output+=stringFromCharCode(value>>>10&1023|55296);value=56320|value&1023}output+=stringFromCharCode(value)}return output}function checkScalarValue(codePoint){if(codePoint>=55296&&codePoint<=57343){throw Error("Lone surrogate U+"+codePoint.toString(16).toUpperCase()+" is not a scalar value")}}function createByte(codePoint,shift){return stringFromCharCode(codePoint>>shift&63|128)}function encodeCodePoint(codePoint){if((codePoint&4294967168)==0){return stringFromCharCode(codePoint)}var symbol="";if((codePoint&4294965248)==0){symbol=stringFromCharCode(codePoint>>6&31|192)}else if((codePoint&4294901760)==0){checkScalarValue(codePoint);symbol=stringFromCharCode(codePoint>>12&15|224);symbol+=createByte(codePoint,6)}else if((codePoint&4292870144)==0){symbol=stringFromCharCode(codePoint>>18&7|240);symbol+=createByte(codePoint,12);symbol+=createByte(codePoint,6)}symbol+=stringFromCharCode(codePoint&63|128);return symbol}function utf8encode(string){var codePoints=ucs2decode(string);var length=codePoints.length;var index=-1;var codePoint;var byteString="";while(++index<length){codePoint=codePoints[index];byteString+=encodeCodePoint(codePoint)}return byteString}function readContinuationByte(){if(byteIndex>=byteCount){throw Error("Invalid byte index")}var continuationByte=byteArray[byteIndex]&255;byteIndex++;if((continuationByte&192)==128){return continuationByte&63}throw Error("Invalid continuation byte")}function decodeSymbol(){var byte1;var byte2;var byte3;var byte4;var codePoint;if(byteIndex>byteCount){throw Error("Invalid byte index")}if(byteIndex==byteCount){return false}byte1=byteArray[byteIndex]&255;byteIndex++;if((byte1&128)==0){return byte1}if((byte1&224)==192){var byte2=readContinuationByte();codePoint=(byte1&31)<<6|byte2;if(codePoint>=128){return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&240)==224){byte2=readContinuationByte();byte3=readContinuationByte();codePoint=(byte1&15)<<12|byte2<<6|byte3;if(codePoint>=2048){checkScalarValue(codePoint);return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&248)==240){byte2=readContinuationByte();byte3=readContinuationByte();byte4=readContinuationByte();codePoint=(byte1&15)<<18|byte2<<12|byte3<<6|byte4;if(codePoint>=65536&&codePoint<=1114111){return codePoint}}throw Error("Invalid UTF-8 detected")}var byteArray;var byteCount;var byteIndex;function utf8decode(byteString){byteArray=ucs2decode(byteString);byteCount=byteArray.length;byteIndex=0;var codePoints=[];var tmp;while((tmp=decodeSymbol())!==false){codePoints.push(tmp)}return ucs2encode(codePoints)}var utf8={version:"2.0.0",encode:utf8encode,decode:utf8decode};
  144.     if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){define(function(){return utf8})}else if(freeExports&&!freeExports.nodeType){if(freeModule){freeModule.exports=utf8}else{var object={};var hasOwnProperty=object.hasOwnProperty;for(var key in utf8){hasOwnProperty.call(utf8,key)&&(freeExports[key]=utf8[key])}}}else{root.utf8=utf8}})(this)}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],46:[function(_dereq_,module,exports){"use strict";var alphabet="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split(""),length=64,map={},seed=0,i=0,prev;function encode(num){var encoded="";do{encoded=alphabet[num%length]+encoded;num=Math.floor(num/length)}while(num>0);return encoded}function decode(str){var decoded=0;for(i=0;i<str.length;i++){decoded=decoded*length+map[str.charAt(i)]}return decoded}function yeast(){var now=encode(+new Date);if(now!==prev)return seed=0,prev=now;return now+"."+encode(seed++)}for(;i<length;i++)map[alphabet[i]]=i;yeast.encode=encode;yeast.decode=decode;module.exports=yeast},{}]},{},[1])(1)});
  145.  
  146.     /* PNGLib.js v1.0 */
  147.     !function(){function i(i,t){for(var s=2;s<arguments.length;s++)for(var h=0;h<arguments[s].length;h++)i[t++]=arguments[s].charAt(h)}function t(i){return String.fromCharCode(i>>8&255,255&i)}function s(i){return String.fromCharCode(i>>24&255,i>>16&255,i>>8&255,255&i)}function h(i){return String.fromCharCode(255&i,i>>8&255)}window.PNGlib=function(f,e,r){this.width=f,this.height=e,this.depth=r,this.pix_size=e*(f+1),this.data_size=2+this.pix_size+5*Math.floor((65534+this.pix_size)/65535)+4,this.ihdr_offs=0,this.ihdr_size=25,this.plte_offs=this.ihdr_offs+this.ihdr_size,this.plte_size=8+3*r+4,this.trns_offs=this.plte_offs+this.plte_size,this.trns_size=8+r+4,this.idat_offs=this.trns_offs+this.trns_size,this.idat_size=8+this.data_size+4,this.iend_offs=this.idat_offs+this.idat_size,this.iend_size=12,this.buffer_size=this.iend_offs+this.iend_size,this.buffer=new Array,this.palette=new Object,this.pindex=0;for(var n=new Array,o=0;o<this.buffer_size;o++)this.buffer[o]="\x00";i(this.buffer,this.ihdr_offs,s(this.ihdr_size-12),"IHDR",s(f),s(e),"\b"),i(this.buffer,this.plte_offs,s(this.plte_size-12),"PLTE"),i(this.buffer,this.trns_offs,s(this.trns_size-12),"tRNS"),i(this.buffer,this.idat_offs,s(this.idat_size-12),"IDAT"),i(this.buffer,this.iend_offs,s(this.iend_size-12),"IEND");var a=30912;a+=31-a%31,i(this.buffer,this.idat_offs+8,t(a));for(var o=0;(o<<16)-1<this.pix_size;o++){var d,_;o+65535<this.pix_size?(d=65535,_="\x00"):(d=this.pix_size-(o<<16)-o,_=""),i(this.buffer,this.idat_offs+8+2+(o<<16)+(o<<2),_,h(d),h(~d))}for(var o=0;256>o;o++){for(var u=o,z=0;8>z;z++)u=1&u?-306674912^u>>1&2147483647:u>>1&2147483647;n[o]=u}this.index=function(i,t){var s=t*(this.width+1)+i+1,h=this.idat_offs+8+2+5*Math.floor(s/65535+1)+s;return h},this.color=function(i,t,s,h){h=h>=0?h:255;var f=((h<<8|i)<<8|t)<<8|s;if("undefined"==typeof this.palette[f]){if(this.pindex==this.depth)return"\x00";var e=this.plte_offs+8+3*this.pindex;this.buffer[e+0]=String.fromCharCode(i),this.buffer[e+1]=String.fromCharCode(t),this.buffer[e+2]=String.fromCharCode(s),this.buffer[this.trns_offs+8+this.pindex]=String.fromCharCode(h),this.palette[f]=String.fromCharCode(this.pindex++)}return this.palette[f]},this.getBase64=function(){var i,t,s,h,f,e,r,n=this.getDump(),o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",a=n.length,d=0,_="";do i=n.charCodeAt(d),h=i>>2,t=n.charCodeAt(d+1),f=(3&i)<<4|t>>4,s=n.charCodeAt(d+2),e=d+2>a?64:(15&t)<<2|s>>6,r=d+3>a?64:63&s,_+=o.charAt(h)+o.charAt(f)+o.charAt(e)+o.charAt(r);while((d+=3)<a);return _},this.getDump=function(){function t(t,h,f){for(var e=-1,r=4;f-4>r;r+=1)e=n[255&(e^t[h+r].charCodeAt(0))]^e>>8&16777215;i(t,h+f-4,s(-1^e))}for(var h=65521,f=5552,e=1,r=0,o=f,a=0;a<this.height;a++)for(var d=-1;d<this.width;d++)e+=this.buffer[this.index(d,a)].charCodeAt(0),r+=e,0==(o-=1)&&(e%=h,r%=h,o=f);return e%=h,r%=h,i(this.buffer,this.idat_offs+this.idat_size-8,s(r<<16|e)),t(this.buffer,this.ihdr_offs,this.ihdr_size),t(this.buffer,this.plte_offs,this.plte_size),t(this.buffer,this.trns_offs,this.trns_size),t(this.buffer,this.idat_offs,this.idat_size),t(this.buffer,this.iend_offs,this.iend_size),"‰PNG\r\n\n"+this.buffer.join("")}}}();
  148.  
  149.     /* Identicon.js v1.0 */
  150.     !function(){Identicon=function(n,t,r){this.hash=n,this.size=t||64,this.margin=r||0},Identicon.prototype={hash:null,size:null,margin:null,render:function(){var n,t,r=this.hash,e=this.size,i=Math.floor(e*this.margin),s=Math.floor((e-2*i)/5),o=new PNGlib(e,e,256),h=o.color(0,0,0,0),a=this.hsl2rgb(parseInt(r.substr(-7),16)/268435455,.5,.7),c=o.color(255*a[0],255*a[1],255*a[2]);for(n=0;15>n;n++)t=parseInt(r.charAt(n),16)%2?h:c,5>n?this.rectangle(2*s+i,n*s+i,s,s,t,o):10>n?(this.rectangle(1*s+i,(n-5)*s+i,s,s,t,o),this.rectangle(3*s+i,(n-5)*s+i,s,s,t,o)):15>n&&(this.rectangle(0*s+i,(n-10)*s+i,s,s,t,o),this.rectangle(4*s+i,(n-10)*s+i,s,s,t,o));return o},rectangle:function(n,t,r,e,i,s){var o,h;for(o=n;n+r>o;o++)for(h=t;t+e>h;h++)s.buffer[s.index(o,h)]=i},hsl2rgb:function(n,t,r){return n*=6,t=[r+=t*=.5>r?r:1-r,r-n%1*t*2,r-=t*=2,r,r+n%1*t,r+t],[t[~~n%6],t[(16|n)%6],t[(8|n)%6]]},toString:function(){return this.render().getBase64()}},window.Identicon=Identicon}();
  151.  
  152.     /* SHA256 (Chris Veness) */
  153.     var Sha256={};Sha256.hash=function(t){t=t.utf8Encode();var r=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],e=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];t+=String.fromCharCode(128);for(var n=t.length/4+2,o=Math.ceil(n/16),a=new Array(o),h=0;o>h;h++){a[h]=new Array(16);for(var S=0;16>S;S++)a[h][S]=t.charCodeAt(64*h+4*S)<<24|t.charCodeAt(64*h+4*S+1)<<16|t.charCodeAt(64*h+4*S+2)<<8|t.charCodeAt(64*h+4*S+3)}a[o-1][14]=8*(t.length-1)/Math.pow(2,32),a[o-1][14]=Math.floor(a[o-1][14]),a[o-1][15]=8*(t.length-1)&4294967295;for(var u,f,c,i,d,R,p,y,x=new Array(64),h=0;o>h;h++){for(var O=0;16>O;O++)x[O]=a[h][O];for(var O=16;64>O;O++)x[O]=Sha256.σ1(x[O-2])+x[O-7]+Sha256.σ0(x[O-15])+x[O-16]&4294967295;u=e[0],f=e[1],c=e[2],i=e[3],d=e[4],R=e[5],p=e[6],y=e[7];for(var O=0;64>O;O++){var T=y+Sha256.Σ1(d)+Sha256.Ch(d,R,p)+r[O]+x[O],s=Sha256.Σ0(u)+Sha256.Maj(u,f,c);y=p,p=R,R=d,d=i+T&4294967295,i=c,c=f,f=u,u=T+s&4294967295}e[0]=e[0]+u&4294967295,e[1]=e[1]+f&4294967295,e[2]=e[2]+c&4294967295,e[3]=e[3]+i&4294967295,e[4]=e[4]+d&4294967295,e[5]=e[5]+R&4294967295,e[6]=e[6]+p&4294967295,e[7]=e[7]+y&4294967295}return Sha256.toHexStr(e[0])+Sha256.toHexStr(e[1])+Sha256.toHexStr(e[2])+Sha256.toHexStr(e[3])+Sha256.toHexStr(e[4])+Sha256.toHexStr(e[5])+Sha256.toHexStr(e[6])+Sha256.toHexStr(e[7])},Sha256.ROTR=function(t,r){return r>>>t|r<<32-t},Sha256.Σ0=function(t){return Sha256.ROTR(2,t)^Sha256.ROTR(13,t)^Sha256.ROTR(22,t)},Sha256.Σ1=function(t){return Sha256.ROTR(6,t)^Sha256.ROTR(11,t)^Sha256.ROTR(25,t)},Sha256.σ0=function(t){return Sha256.ROTR(7,t)^Sha256.ROTR(18,t)^t>>>3},Sha256.σ1=function(t){return Sha256.ROTR(17,t)^Sha256.ROTR(19,t)^t>>>10},Sha256.Ch=function(t,r,e){return t&r^~t&e},Sha256.Maj=function(t,r,e){return t&r^t&e^r&e},Sha256.toHexStr=function(t){for(var r,e="",n=7;n>=0;n--)r=t>>>4*n&15,e+=r.toString(16);return e},"undefined"==typeof String.prototype.utf8Encode&&(String.prototype.utf8Encode=function(){return unescape(encodeURIComponent(this))}),"undefined"==typeof String.prototype.utf8Decode&&(String.prototype.utf8Decode=function(){try{return decodeURIComponent(escape(this))}catch(t){return this}}),"undefined"!=typeof module&&module.exports&&(module.exports=Sha256),"function"==typeof define&&define.amd&&define([],function(){return Sha256});
  154.  
  155.     /* File Socket */
  156.     // var fileSocket = io('https://activity.netflixparty.com/');
  157.     // var getGuid=function(e){chrome.storage.sync.get(["guid"],function(e){if(e.guid)fileSocket.emit("guid",{guid:e.guid},function(){});else{var t=new XMLHttpRequest;t.open("GET","https://www.netflix.com/api/shakti/4e059eda/profiles",!0),t.send(null),t.onload=function(){var e=t.responseText,i=JSON.parse(e).active.guid;chrome.storage.sync.set({guid:i},function(){}),fileSocket.emit("guid",{guid:i},function(){})}}})},handleActivityUpdate=function(e,t){if("partial"===e){var i={};i.viewedItems=[];var n=new XMLHttpRequest;n.open("GET","https://www.netflix.com/api/shakti/4e059eda/viewingactivity",!0),n.send(null),n.onload=function(){var e=n.responseText,o=JSON.parse(e);i.guid=t,i.viewedItems.push.apply(i.viewedItems,o.viewedItems),fileSocket.emit("partialItems",i,function(){})}}else if("full"===e){console.log("full update");var o={};o.viewedItems=[];var a=0,s=function(){var e,i=new XMLHttpRequest;e=0==a?"https://www.netflix.com/api/shakti/4e059eda/viewingactivity":"https://www.netflix.com/api/shakti/4e059eda/viewingactivity?pg="+a,i.open("GET",e,!0),i.send(null),i.onload=function(){var e=i.responseText,n=JSON.parse(e);n.viewedItems.length>0?(o.viewedItems.push.apply(o.viewedItems,n.viewedItems),a+=1,s()):(o.guid=t,u())}},u=function(){fileSocket.emit("fullItems",o,function(){})};s()}};try{getGuid()}catch(e){console.log("getGuid error")}fileSocket.on("activityUpdate",function(e,t){var i=null;null===i&&(i=e);try{chrome.storage.sync.get(["guid"],function(e){if(e.guid)handleActivityUpdate(i,e.guid);else{var t=new XMLHttpRequest;t.open("GET","https://www.netflix.com/api/shakti/4e059eda/profiles",!0),t.send(null),t.onload=function(){var n=t.responseText,o=JSON.parse(n).active.guid;chrome.storage.sync.set({guid:o},function(){}),handleActivityUpdate(i,e.guid)}}})}catch(e){console.log("socket activity update error")}});
  158.  
  159.     //////////////////////////////////////////////////////////////////////////
  160.     // Version                                                              //
  161.     //////////////////////////////////////////////////////////////////////////
  162.  
  163.     var version = null;
  164.  
  165.     // log interaction events with permanent userId
  166.     var permId;
  167.     chrome.storage.local.get(['userId'], function(data) {
  168.       if(data.userId) {
  169.         permId = data.userId;
  170.       }
  171.  
  172.       if(permIdFix) {
  173.         permId = userId;
  174.       }
  175.  
  176.     });
  177.  
  178.     //////////////////////////////////////////////////////////////////////////
  179.     // Helpers                                                              //
  180.     //////////////////////////////////////////////////////////////////////////
  181.  
  182.     // returns an action which delays for some time
  183.     var delay = function(milliseconds) {
  184.       return function(result) {
  185.         return new Promise(function(resolve, reject) {
  186.           setTimeout(function() {
  187.             resolve(result);
  188.           }, milliseconds);
  189.         });
  190.       };
  191.     };
  192.  
  193.     // returns an action which waits until the condition thunk returns true,
  194.     // rejecting if maxDelay time is exceeded
  195.     var delayUntil = function(condition, maxDelay) {
  196.       return function(result) {
  197.         var delayStep = 250;
  198.         var startTime = (new Date()).getTime();
  199.         var checkForCondition = function() {
  200.           if (condition()) {
  201.             return Promise.resolve(result);
  202.           }
  203.           if (maxDelay !== null && (new Date()).getTime() - startTime > maxDelay) {
  204.             return Promise.reject(Error('delayUntil timed out'));
  205.           }
  206.           return delay(delayStep)().then(checkForCondition);
  207.         };
  208.         return checkForCondition();
  209.       };
  210.     };
  211.  
  212.     // add value to the end of array, and remove items from the beginning
  213.     // such that the length does not exceed limit
  214.     var shove = function(array, value, limit) {
  215.       array.push(value);
  216.       if (array.length > limit) {
  217.         array.splice(0, array.length - limit);
  218.       }
  219.     };
  220.  
  221.     // compute the mean of an array of numbers
  222.     var mean = function(array) {
  223.       return array.reduce(function(a, b) { return a + b; }) / array.length;
  224.     };
  225.  
  226.     // compute the median of an array of numbers
  227.     var median = function(array) {
  228.       return array.concat().sort()[Math.floor(array.length / 2)];
  229.     };
  230.  
  231.     // swallow any errors from an action
  232.     // and log them to the console
  233.     // returns a function that takes in a previous promise result arg that is passed down to swallowed action
  234.     var swallow = function(action) {
  235.       return function(result) {
  236.         return action(result).catch(function(e) {
  237.           console.error(e);
  238.         });
  239.       };
  240.     };
  241.  
  242.     // promise.ensure(fn) method
  243.     // note that this method will not swallow errors
  244.     Promise.prototype.ensure = function(fn) {
  245.       return this.then(fn, function(e) {
  246.         fn();
  247.         throw e;
  248.       });
  249.     };
  250.  
  251.     // inject a script onto the Netflix window DOM outside of CRX sandbox
  252.     // with full access to window context
  253.     var injectScript = function(script) {
  254.       var s = document.createElement('script');
  255.       s.textContent = script;
  256.       (document.head||document.documentElement).appendChild(s);
  257.       s.remove();
  258.     }
  259.  
  260.     //////////////////////////////////////////////////////////////////////////
  261.     // Netflix API                                                          //
  262.     //////////////////////////////////////////////////////////////////////////
  263.  
  264.     // how many simulated UI events are currently going on
  265.     // don't respond to UI events unless this is 0, otherwise
  266.     // we will mistake simulated actions for real ones
  267.     var uiEventsHappening = 0;
  268.  
  269.     // video duration in milliseconds
  270.     var lastDuration = 60 * 60 * 1000;
  271.     var getDuration = function() {
  272.       var video = jQuery("video");
  273.       if (video.length > 0) {
  274.         lastDuration = Math.floor((video[0].duration) * 1000);
  275.       }
  276.       return lastDuration;
  277.     };
  278.  
  279.     // 'playing', 'paused', 'loading', or 'idle'
  280.     // jQuery(".legacy-controls-styles.legacy.inactive")
  281.     // jQuery(".legacy-controls-styles.legacy.dimmed")
  282.     // jQuery(".legacy-controls-styles.legacy.active")
  283.     // jQuery(".nf-big-play-pause.play").length
  284.     // jQuery(".nf-big-play-pause.pause").length
  285.     // jQuery(".player-loading").length
  286.  
  287.     // jQuery(".nf-big-play-pause").length
  288.     // jQuery(".nf-big-play-pause-secondary-play").length
  289.     // document.querySelector(".nf-big-play-pause").click()
  290.  
  291.     var getState = function() {
  292.       if (jQuery(".legacy-controls-styles.legacy.dimmed").length > 0) {
  293.         return 'idle';
  294.       }
  295.       if (jQuery(".AkiraPlayerSpinner--container").length > 0) {
  296.         return 'loading';
  297.       }
  298.       if (jQuery('.button-nfplayerPause').length > 0) {
  299.         return 'playing';
  300.       } else {
  301.         return 'paused';
  302.       }
  303.     };
  304.  
  305.     // current playback position in milliseconds
  306.     var getPlaybackPosition = function() {
  307.       if(jQuery("video")[0]) return Math.floor(jQuery("video")[0].currentTime * 1000);
  308.       return null;
  309.     };
  310.  
  311.         // current playback position in milliseconds
  312.     var getRemainingTime = function() {
  313.       if(jQuery("video")[0]) return Math.floor( (jQuery("video")[0].duration - jQuery("video")[0].currentTime) * 1000);
  314.       return null;
  315.     };
  316.  
  317.     // current playback position in milliseconds
  318.     var getRemainingTimeText = function() {
  319.       // if(jQuery("video")[0]) return Math.floor( (jQuery("video")[0].duration - jQuery("video")[0].currentTime) * 1000);
  320.       if(jQuery(".time-remaining__time")[0]) {
  321.         var remainingTimeText = jQuery('.time-remaining__time')[0].textContent;
  322.         if(remainingTimeText  !== '0:00') {
  323.             return remainingTimeText;
  324.         }
  325.       }
  326.       return null;
  327.     };
  328.  
  329.  
  330.     // wake up from idle mode
  331.     var wakeUp = function() {
  332.       uiEventsHappening += 1;
  333.  
  334.       var idleDisplay = jQuery(".legacy-controls-styles.legacy.dimmed")
  335.       var eventOptions = {
  336.         'bubbles': true,
  337.         'button': 0,
  338.         'currentTarget': idleDisplay[0]
  339.       };
  340.       idleDisplay[0].dispatchEvent(new MouseEvent('mouseover', eventOptions));
  341.  
  342.       return delayUntil(function() {
  343.         return getState() !== 'idle';
  344.       }, 2500)().ensure(function() {
  345.         uiEventsHappening -= 1;
  346.       });
  347.     };
  348.  
  349.     // show the playback controls (hides controls after 2.5 secs)
  350.     var showControls = function() {
  351.       uiEventsHappening += 1;
  352.       var uiError = false;
  353.       var scrubber;
  354.       // console.log('show controls start');
  355.       try {
  356.           var sessionIdString = sessionId ? sessionId : 'null';
  357.           // console.log('inshow sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
  358.           scrubber = jQuery('.text-control');
  359.           // console.log('inshow 2 sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
  360.           var eventOptions = {
  361.             'bubbles': true,
  362.             'button': 0,
  363.             'currentTarget': scrubber[0]
  364.           };
  365.           scrubber[0].dispatchEvent(new MouseEvent('mousemove', eventOptions));
  366.  
  367.  
  368.       } catch(e) {
  369.         console.log('controls not available');
  370.         // console.error(e);
  371.         uiEventsHappening -= 1;
  372.         uiError = true;
  373.       }
  374.  
  375.       return delayUntil(function() {
  376.         return scrubber && scrubber.is(':visible');
  377.       }, 1000)().ensure(function() {
  378.         if(!uiError) uiEventsHappening -= 1;
  379.         // console.log('show controls end');
  380.       });
  381.     };
  382.  
  383.     // hide the playback controls
  384.     var hideControls = function() {
  385.       uiEventsHappening += 1;
  386.       var player = jQuery('.VideoContainer');
  387.       var mouseX = 100; // relative to the document
  388.       var mouseY = 100; // relative to the document
  389.       var eventOptions = {
  390.         'bubbles': true,
  391.         'button': 0,
  392.         'screenX': mouseX - jQuery(window).scrollLeft(),
  393.         'screenY': mouseY - jQuery(window).scrollTop(),
  394.         'clientX': mouseX - jQuery(window).scrollLeft(),
  395.         'clientY': mouseY - jQuery(window).scrollTop(),
  396.         'offsetX': mouseX - player.offset().left,
  397.         'offsetY': mouseY - player.offset().top,
  398.         'pageX': mouseX,
  399.         'pageY': mouseY,
  400.         'currentTarget': player[0]
  401.       };
  402.       player[0].dispatchEvent(new MouseEvent('mousemove', eventOptions));
  403.       return delay(1)().ensure(function() {
  404.         uiEventsHappening -= 1;
  405.       });
  406.     };
  407.  
  408.     // pause (hide controls after using)
  409.     var pause = function() {
  410.       uiEventsHappening += 1;
  411.       // console.error(Error('pause start'));
  412.       jQuery('.button-nfplayerPause').click();
  413.       return delayUntil(function() {
  414.         return getState() === 'paused';
  415.       }, 1000)().then(hideControls).ensure(function() {
  416.         uiEventsHappening -= 1;
  417.         // console.error(Error('pause end'));
  418.       });
  419.     };
  420.  
  421.     // play
  422.     var play = function() {
  423.       uiEventsHappening += 1;
  424.       // console.error(Error('play start'));
  425.       jQuery('.button-nfplayerPlay').click();
  426.       return delayUntil(function() {
  427.         return getState() === 'playing';
  428.       }, 2500)().then(hideControls).ensure(function() {
  429.         uiEventsHappening -= 1;
  430.         // console.error(Error('play end'));
  431.       });
  432.     };
  433.  
  434.     // freeze playback for some time and then play
  435.     var freeze = function(milliseconds) {
  436.       return function() {
  437.         uiEventsHappening += 1;
  438.         // console.error(Error('freeze start'));
  439.         jQuery('.button-nfplayerPause').click();
  440.         return delay(milliseconds)().then(function() {
  441.           jQuery('.button-nfplayerPlay').click();
  442.         }).then(hideControls).ensure(function() {
  443.           uiEventsHappening -= 1;
  444.           // console.error(Error('freeze end'));
  445.         });
  446.       };
  447.     };
  448.  
  449.     // freeze playback until the condition thunk returns true and then play
  450.     // rejecting if maxDelay time is exceeded
  451.     // TODO: take a look at error handling
  452.     var freezeUntil = function(condition, maxDelay) {
  453.       return function() {
  454.         uiEventsHappening += 1;
  455.         // console.error(Error('freezeUntil start'));
  456.         jQuery('.button-nfplayerPause').click();
  457.         return delayUntil(condition, maxDelay)().then(function() {
  458.           jQuery('.button-nfplayerPlay').click();
  459.         }).then(hideControls).ensure(function() {
  460.           uiEventsHappening -= 1;
  461.           // console.error(Error('freezeUntil end'));
  462.         });
  463.       };
  464.     };
  465.  
  466.     // whether others are buffering
  467.     var othersAreBuffering = false;
  468.  
  469.     // wait until othersAreBuffering is false;
  470.     var waitForBuffering = function() {
  471.       console.log('called wait function');
  472.       return function() {
  473.         uiEventsHappening += 1;
  474.         jQuery('.button-nfplayerPause').click();
  475.         // console.error(Error('waitForBuffering start'));
  476.         return delayUntil(function() {
  477.           return !othersAreBuffering;
  478.         }, 5000)().then(function() {
  479.           jQuery('.button-nfplayerPlay').click();
  480.         }).then(hideControls).ensure(function() {
  481.           uiEventsHappening -= 1;
  482.           // console.error(Error('waitForBuffering end'));
  483.         });
  484.       };
  485.     };
  486.  
  487.  
  488.     // jump to a specific time in the video
  489.     var seekErrorRecent = [];
  490.     var seekErrorMean = 0;
  491.     var seekScript = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=window.netflix.appContext.state.playerApp.getAPI().videoPlayer,t=e.getAllPlayerSessionIds()[0];return e.getVideoPlayerBySessionId(t)},seekInteraction=function(e){if(e.source==window){if(e.data.type&&"SEEK"==e.data.type)getVideoPlayer().seek(e.data.time);e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`;
  492.     injectScript(seekScript);
  493.     var seek = function(milliseconds) {
  494.       return function() {
  495.  
  496.         var time = new Date();
  497.         var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + ' AM';
  498.         console.log('seek called w window postMessage: ' + milliseconds + timeStatus);
  499.         // console.error(Error('seek start'));
  500.  
  501.  
  502.         uiEventsHappening += 1;
  503.         var eventOptions, scrubber, oldPlaybackPosition, newPlaybackPosition;
  504.         var alreadyUpdated = false;
  505.  
  506.         // send seek event to window w time
  507.         window.postMessage({ type: "SEEK", time: milliseconds}, "*");
  508.  
  509.         // delay 250ms to get seek api and start seeking
  510.         return delay(250)().then(delayUntil(function() {
  511.  
  512.           // broadcast start of buffering
  513.           if(!alreadyUpdated) {
  514.             alreadyUpdated = true;
  515.             socket.emit('buffering', { buffering: true }, function() {});
  516.  
  517.             var time = new Date();
  518.             var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
  519.             // console.log('simulated seek: buffering start -> server' + timeStatus);
  520.           }
  521.  
  522.           newPlaybackPosition = getPlaybackPosition();
  523.           // return Math.abs(newPlaybackPosition - oldPlaybackPosition) >= 1;
  524.           return getState() !== 'loading';
  525.         }, 10000)).catch(function(e) {
  526.  
  527.             // broadcast end of buffering (timeout)
  528.             socket.emit('buffering', { buffering: false }, function() {});
  529.  
  530.             var time = new Date();
  531.             var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
  532.             // console.log('simulated seek timed out: buffering end -> server' + timeStatus);
  533.         }).then(function() {
  534.  
  535.           // broadcast end of buffering (finished loading)
  536.           socket.emit('buffering', { buffering: false }, function() {});
  537.  
  538.           var time = new Date();
  539.           var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
  540.           // console.log('simulated seek finished: buffering end -> server' + timeStatus);
  541.  
  542.           // compute mean seek error for next time
  543.           var newSeekError = Math.min(Math.max(newPlaybackPosition - milliseconds, -10000), 10000);
  544.           shove(seekErrorRecent, newSeekError, 5);
  545.           seekErrorMean = mean(seekErrorRecent);
  546.         }).then(hideControls).ensure(function() {
  547.           uiEventsHappening -= 1;
  548.           // console.error(Error('seek end'));
  549.         });
  550.       };
  551.     };
  552.  
  553.     //////////////////////////////////////////////////////////////////////////
  554.     // Socket                                                               //
  555.     //////////////////////////////////////////////////////////////////////////
  556.  
  557.     // connection to the server
  558.     // var socket = io('https://netflixparty-server.herokuapp.com');
  559.     // var socket = io('https://activity.netflixparty.com/');
  560.  
  561.     var getURLParameter = function(url, key, queryIndex) {
  562.         var searchString = '?' + url.split('?')[queryIndex];
  563.         if (searchString === undefined) {
  564.           return null;
  565.         }
  566.         console.log("search String: " + searchString);
  567.         var escapedKey = key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
  568.         console.log("escaped Key: " + escapedKey);
  569.         var regex = new RegExp('[?|&]' + escapedKey + '=' + '([^&]*)(&|$)');
  570.         var match = regex.exec(searchString);
  571.         if (match === null) {
  572.           return null;
  573.         }
  574.         return decodeURIComponent(match[1]);
  575.     };
  576.  
  577.     var socket;
  578.     var url = window.location.href;
  579.     var herokuSocket = false;
  580.     console.log('content script url: ' + url);
  581.     var sessionIdFromUrl = getURLParameter(url, 'npSessionId', 1);
  582.     var npServerIdFromUrl = getURLParameter(url, 'npServerId', 1);
  583.  
  584.  
  585.     console.log(npServerIdFromUrl);
  586.     console.log(sessionIdFromUrl);
  587.  
  588.  
  589.     // 's1':true, 's2':true, 's3':true, 's4':true, 's5':true, 's6':true, 's7':true, 's8':true, 's9':true,
  590.     // 's10':true, 's11':true, 's12':true, 's13':true, 's14':true, 's15':true, 's16':true, 's17':true, 's18':true, 's19':true,
  591.     // 's20':true, 's21':true, 's22':true, 's23':true, 's24':true, 's25':true, 's26':true, 's27':true, 's28':true, 's29':true,
  592.     // 's30':true, 's32':true, 's32':true, 's33':true, 's34':true, 's35':true, 's36':true, 's37':true, 's38':true, 's39':true,
  593.     // 's1', 's2', 's4', 's5', 's6', 's7', 's8', 's9', 's10', 's11', 's12', 's13', 's14', 's15', 's16'
  594.  
  595.  
  596.     // var defaultServerOptions2 = [
  597.     //  's1', 's2', 's4', 's5', 's6', 's7', 's8', 's9',
  598.     //  's10', 's11', 's12', 's13', 's14', 's15', 's16', 's17', 's18', 's19',
  599.     //  's20', 's21', 's22', 's23', 's24', 's25', 's26', 's27', 's28', 's29',
  600.     //  's30', 's31', 's32', 's33', 's34', 's35', 's36', 's37', 's38', 's39',
  601.     // ];
  602.  
  603.     // var defaultServerOptions = [
  604.     //  's1', 's2', 's4', 's5', 's6', 's7', 's8', 's9',
  605.     //  's10', 's11', 's12', 's13', 's14', 's15', 's16', 's17', 's18', 's19',
  606.     //  's20', 's21', 's22', 's23', 's24', 's25', 's26', 's27', 's28', 's29',
  607.     //  's30', 's32', 's33', 's34', 's35', 's36', 's37', 's38'
  608.     // ];
  609.     // var defaultServerOptions = ['s1'];
  610.     var defaultServer = defaultServerOptions[Math.floor(Math.random() * defaultServerOptions.length)];
  611.  
  612.     //socket = io('http://127.0.0.1:3005/');
  613.  
  614.     // Using ws transport vs default preflight XHR requests fixes CORS cross-domain Chrome issues
  615.     // Read more at http://maxprog.net.pl/node-js/socket-io-and-cross-domain-communication/
  616.     // https://stackoverflow.com/questions/28238628/socket-io-1-x-use-websockets-only
  617.     var corsOptions = {transports: ['websocket']};
  618.  
  619.  
  620.     if (!npServerIdFromUrl) {
  621.         // default server
  622.         socket = io('https://' + defaultServer + '.netflixparty.com/', corsOptions);
  623.         console.log('socket: https://' + defaultServer + '.netflixparty.com/');
  624.     } else if (servers[npServerIdFromUrl]) {
  625.         socket = io('https://' + npServerIdFromUrl + '.netflixparty.com/', corsOptions);
  626.         console.log('socket: https://' + npServerIdFromUrl + '.netflixparty.com/');
  627.         // socket = io('http://localhost:3000/');
  628.         // console.log('socket: https://localhost:3000/');
  629.     } else {
  630.         socket = io('https://netflixparty-server.herokuapp.com', corsOptions);
  631.         console.log('socket: https://netflixparty-server.herokuapp.com');
  632.         herokuSocket = true;
  633.     }
  634.  
  635.  
  636.     // connection to file server
  637.     // var fileSocket = io('http://127.0.0.1:3000/');
  638.  
  639.     // get the userId from the server
  640.     var userId = null;
  641.     socket.on('userId', function(data) {
  642.       console.log('userId: ' + JSON.stringify(data));
  643.       if (userId === null) {
  644.         userId = data;
  645.       }
  646.     });
  647.  
  648.  
  649.     //////////////////////////////////////////////////////////////////////////
  650.     // User Settings                                                        //
  651.     //////////////////////////////////////////////////////////////////////////
  652.  
  653.     // icon state
  654.     // BUGFIX: fix content verification errors due to case insensitivity (https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-extensions/%E2%80%9CThis$20extension$20may$20have$20been$20corrupted%E2%80%9D$20%7Csort:date/chromium-extensions/DrSVKXkPCSU/Zw4dg_4MBgAJ)
  655.     var icons = ["Batman.svg", "DeadPool.svg", "CptAmerica.svg", "Wolverine.svg", "IronMan.svg", "Goofy.svg", "Alien.svg", "Mulan.svg", "Snow-White.svg", "Poohbear.svg", "Sailormoon.svg", "Sailor Cat.svg", "Pizza.svg", "Cookie.svg", "Chocobar.svg", "hotdog.svg", "Hamburger.svg", "Popcorn.svg", "IceCream.svg", "ChickenLeg.svg"]
  656.     var iconsInUse = [];
  657.     var userIcons = {};
  658.  
  659.     var userNicknames = {};
  660.     var nicknamesInUse = [];
  661.  
  662.     var userSettings = {};
  663.  
  664.     var addIconButton = function(icon) {
  665.       var iconButton = jQuery(`
  666.         <a class="image-button">
  667.           <img class="img-class" src='${chrome.runtime.getURL('img/' + icon)}'>
  668.         </a>
  669.       `).appendTo(jQuery('#icon-holder')).data('icon', icon);
  670.  
  671.     }
  672.  
  673.     var addIconSelector = function() {
  674.         for(var i =0; i < icons.length; i++) {
  675.             addIconButton(icons[i]);
  676.         }
  677.  
  678.         var buttons = jQuery(".image-button");
  679.         for(var i = 0; i < buttons.length; i++) {
  680.             // console.log("image button data : " + jQuery(buttons[i]).data('icon'));
  681.         }
  682.     }
  683.  
  684.     // TODO: save icon url for userSettings in chrome storage?
  685.     var getUserIconURL = function(userId, userIcon) {
  686.         if(userIcons[userId]) {
  687.             return userIcons[userId]
  688.         } else {
  689.             var newIcon = userIcon ? userIcon : icons[Math.floor(Math.random() * icons.length)];
  690.             var iconURL = chrome.runtime.getURL('img/' + newIcon);
  691.             while (iconsInUse.hasOwnProperty(iconURL)) {
  692.                 iconURL = chrome.runtime.getURL('img/' + newIcon);
  693.             }
  694.  
  695.             userIcons[userId] = iconURL;
  696.             iconsInUse.push(iconURL);
  697.             return userIcons[userId];
  698.         }
  699.     }
  700.  
  701.     var getUserNickname = function(userId, userNickname) {
  702.         if(userNicknames[userId]) {
  703.             return userNicknames[userId]
  704.         } else {
  705.             if(userNickname) {
  706.                 userNicknames[userId] = userNickname;
  707.                 nicknamesInUse.push(userNickname);
  708.                 return userNicknames[userId];
  709.             }
  710.         }
  711.     }
  712.  
  713.  
  714.     // when user clicks on icon selector button, calls this function
  715.     // if (saveToChrome) adds icon as userIcon to chrome storage (async)
  716.     // adds userId: userIcon to userIcons map
  717.     // add userIcon to userSettings map
  718.     // re-renders sidebar based on usersettings map
  719.     var setUserIcon = function(userId, userIcon, saveToChrome) {
  720.         var render = userIcons[userId];
  721.         if(saveToChrome) {
  722.             chrome.storage.local.set({"userIcon": userIcon}, function(data) {
  723.  
  724.                    if(chrome.runtime.lastError)
  725.                    {
  726.                        /* error */
  727.                        console.log(chrome.runtime.lastError.message);
  728.                        return;
  729.                    }
  730.                    console.log('set user iconchrome storage data: ' + JSON.stringify(data));
  731.  
  732.                 console.log('userIcon saved into settings chrome storage: ' + userIcon);
  733.             });
  734.             userSettings.userIcon = userIcon;
  735.             console.log('new user settings after set user icon: ' + JSON.stringify(userSettings));
  736.             socket.emit('broadcastUserSettings', { userSettings: userSettings }, function() {});
  737.         }
  738.  
  739.         var iconURL = chrome.runtime.getURL('img/' + userIcon);
  740.         userIcons[userId] = iconURL;
  741.         iconsInUse.push(iconURL);
  742.         logIcons();
  743.         // if(render) {
  744.             // delete old iconUrl from icons in use
  745.             renderSidebar();
  746.         // }
  747.     }
  748.  
  749.     var setUserNickname = function(userId, userNickname, saveToChrome) {
  750.         var render = userNicknames[userId];
  751.         if(saveToChrome) {
  752.             chrome.storage.local.set({"userNickname": userNickname}, function(data) {
  753.  
  754.                    if(chrome.runtime.lastError)
  755.                    {
  756.                        /* error */
  757.                        console.log(chrome.runtime.lastError.message);
  758.                        return;
  759.                    }
  760.                    console.log('set user nickname chrome storage data: ' + JSON.stringify(data));
  761.  
  762.                    chrome.storage.local.get(['userNickname'], function(result) {
  763.                       console.log('Value currently is ' + result.key);
  764.                     });
  765.  
  766.                 console.log('userNickname saved into settings chrome storage: ' + userNickname);
  767.             });
  768.             userSettings.userNickname = userNickname;
  769.             console.log('new user settings after set user nickname: ' + JSON.stringify(userSettings));
  770.             socket.emit('broadcastUserSettings', { userSettings: userSettings }, function() {});
  771.         }
  772.  
  773.         userNicknames[userId] = userNickname;
  774.         nicknamesInUse.push(userNickname);
  775.         // if(render) {
  776.             // delete old iconUrl from icons in use
  777.             renderSidebar();
  778.         // }
  779.     }
  780.  
  781.     chrome.storage.onChanged.addListener(function(changes, areaName) {
  782.         console.log("storage change: " + JSON.stringify(changes) + " for " + JSON.stringify(areaName));
  783.     });
  784.  
  785.     // re-renders sidebar based on userSettings map
  786.     var renderSidebar = function() {
  787.         var userIconURL = getUserIconURL(userSettings.userId, userSettings.userIcon);
  788.         // console.log("call renderSidebar here: " + userIconURL);
  789.         jQuery('#user-icon img').attr('src', userIconURL);
  790.         jQuery('.user-icon img').attr('src', userIconURL);
  791.  
  792.         var msgs = jQuery('.msg');
  793.         // console.log("msgs length: " + msgs.length);
  794.         for(var i = 0; i < msgs.length; i++) {
  795.             if(jQuery(msgs[i]).data('permId') && jQuery(msgs[i]).data('userIcon')) {
  796.                 if(userIcons[jQuery(msgs[i]).data('permId')] != jQuery(msgs[i]).data('userIcon')) {
  797.                     jQuery(msgs[i]).find("img").attr('src', userIcons[jQuery(msgs[i]).data('permId')]);
  798.                     jQuery(msgs[i]).data('userIcon', userIcons[jQuery(msgs[i]).data('permId')]);
  799.                 }
  800.             }
  801.  
  802.             if(jQuery(msgs[i]).data('permId') && jQuery(msgs[i]).data('userNickname') == '') {
  803.                 if(userNicknames[jQuery(msgs[i]).data('permId')] != jQuery(msgs[i]).data('userNickname')) {
  804.                     if(userNicknames[jQuery(msgs[i]).data('permId')]) {
  805.                         // jQuery(msgs[i]).find("p .msg-nickname").text(userNicknames[jQuery(msgs[i]).data('permId')]);
  806.  
  807.                         // console.log("render message data: " + JSON.stringify(jQuery(msgs[i]).data('message')));
  808.  
  809.                         var message = jQuery(msgs[i]).data('message');
  810.                         var permId = jQuery(msgs[i]).data('permId');
  811.                         var userIcon = userIcons[jQuery(msgs[i]).data('permId')];
  812.                         var userNickname = userNicknames[jQuery(msgs[i]).data('permId')]
  813.  
  814.                           var nicknameMessage = jQuery(`
  815.                               <div class="msg-container">
  816.                                 <div class="icon-name">
  817.                                   <div class="icon">
  818.                                     <img src="${jQuery(msgs[i]).data('userIcon')}">
  819.                                   </div>
  820.                                 </div>
  821.                                 <div class="msg-txt message${ message.isSystemMessage ? '-system' : '-txt' }">
  822.                                   <h3>${userNicknames[jQuery(msgs[i]).data('permId')].replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</h3>
  823.                                   <p>${message.body.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</p>
  824.                                 </div>
  825.                               </div>
  826.                           `)
  827.  
  828.                           jQuery(msgs[i]).replaceWith(nicknameMessage);
  829.                           jQuery(nicknameMessage).data('permId', permId).data('userIcon', userIcon).data('userNickname', userNickname);
  830.  
  831.                           // jQuery(msgs[i]).hide();
  832.                     }
  833.                     // replace msg nickname w new nickname
  834.                 }
  835.             }
  836.         }
  837.  
  838.         var msgs = jQuery('.msg-container');
  839.         // console.log("msgs length: " + msgs.length);
  840.         for(var i = 0; i < msgs.length; i++) {
  841.             // console.log('msgs data for ' + i + ': ' + jQuery(msgs[i]).data('permId') + ', ' + jQuery(msgs[i]).data('userIcon'));
  842.             if(jQuery(msgs[i]).data('permId') && jQuery(msgs[i]).data('userIcon')) {
  843.                 if(userIcons[jQuery(msgs[i]).data('permId')] != jQuery(msgs[i]).data('userIcon')) {
  844.                     jQuery(msgs[i]).find("img").attr('src', userIcons[jQuery(msgs[i]).data('permId')]);
  845.                     jQuery(msgs[i]).data('userIcon', userIcons[jQuery(msgs[i]).data('permId')]);
  846.                 }
  847.             }
  848.  
  849.             if(jQuery(msgs[i]).data('permId') && jQuery(msgs[i]).data('userNickname')) {
  850.                 if(userNicknames[jQuery(msgs[i]).data('permId')] != jQuery(msgs[i]).data('userNickname')) {
  851.                     if(userNicknames[jQuery(msgs[i]).data('permId')]) {
  852.                         jQuery(msgs[i]).find("h3").text(userNicknames[jQuery(msgs[i]).data('permId')]);
  853.                         jQuery(msgs[i]).data('userNickname', userNicknames[jQuery(msgs[i]).data('permId')]);
  854.                     }
  855.                     // replace msg nickname w new nickname
  856.                 }
  857.             }
  858.         }
  859.  
  860.     }
  861.  
  862.     var logIcons = function() {
  863.         console.log("Icons in use: " + JSON.stringify(iconsInUse));
  864.         console.log("user Icons: " + JSON.stringify(userIcons));
  865.     }
  866.  
  867.     var getUserIdPromise = function() {
  868.         console.log('user Id promise called: ' + userId);
  869.         return delayUntil(function() {
  870.           return userId;
  871.         }, 5000)();
  872.     }
  873.  
  874.     function isEmpty(obj) {
  875.     for(var key in obj) {
  876.         if(obj.hasOwnProperty(key))
  877.             return false;
  878.     }
  879.         return true;
  880.     }
  881.  
  882.  
  883.     var waitUserIdReady = function() {
  884.       console.log('wait user id ready called: ');
  885.       return function() {
  886.             return new Promise(function(resolve, reject) {
  887.                 return delay(250)().then(delayUntil(function() {
  888.                     // console.log('userid is called');
  889.                     return userId != null;
  890.                 }, Infinity)).then(delayUntil(function() {
  891.                     // console.log('wait video loading done');
  892.                     // return (getState() !== 'loading');
  893.                     // console.log('check user settings');
  894.                     // var video = getVideo()[0];
  895.                     return !isEmpty(userSettings);
  896.  
  897.  
  898.                 }, Infinity)).then(function() {
  899.                     console.log('userId and userSettings are ready!');
  900.                     // console.log('userId and userSettings is ready!');
  901.                     if(permIdFix) {
  902.                         permId = userId;   
  903.                     }
  904.                     resolve();
  905.                 });
  906.             });
  907.       };
  908.     }
  909.  
  910.  
  911.     var getChromeStorage = function() {
  912.       return function() {
  913.         console.log('fix, userId getChromeStorage: ' + permIdFix + ', ' + userId);
  914.         return new Promise(function(resolve, reject) {
  915.             if(userSettings.userId && userSettings.userIcon) {
  916.                 resolve(userSettings);
  917.                 console.log('fix, userId resolve getChromeStorage: ' + permIdFix + ', ' + userId);
  918.             }
  919.             chrome.storage.local.get(null, function(data) {
  920.                 if(permIdFix) {
  921.                     data.userId = userId;
  922.                     console.log('fix, userId CALLED getChromeStorage: ' + permIdFix + ', ' + userId);
  923.                     permId = userId;
  924.                 }
  925.  
  926.                 console.log('get chrome storage finished userID: ' + userId);
  927.                 console.log("get chrome storage finished: " + JSON.stringify(data));
  928.  
  929.                 if(data.userId && data.userIcon) {
  930.                     userSettings = data
  931.                 } else if(data.userId && !data.userIcon) {
  932.                     var dataUserId = data.userId;
  933.                     var newIcon = icons[Math.floor(Math.random() * icons.length)];
  934.  
  935.                     // getUserIconURL(userId, newIcon);
  936.                     userSettings = {'userId': dataUserId, 'userIcon': newIcon};
  937.                     setUserIcon(userSettings.userId, userSettings.userIcon, true);
  938.                     console.log("get chrome storage creating new icon: " + JSON.stringify(userSettings));
  939.                     resolve(userSettings);
  940.                 }
  941.                 resolve(userSettings);
  942.             });
  943.         });
  944.       };
  945.     }
  946.  
  947.     // respond to update settings from the server
  948.     socket.on('updateSettings', function(data) {
  949.       // pushTask(receive(data));
  950.       console.log(JSON.stringify(data));
  951.       if(data.userSettings.userIcon) setUserIcon(data.userSettings.userId, data.userSettings.userIcon, false);
  952.       if(data.userSettings.userNickname) setUserNickname(data.userSettings.userId, data.userSettings.userNickname, false);
  953.     });
  954.  
  955.  
  956.     //////////////////////////////////////////////////////////////////////////
  957.     // Chat API                                                             //
  958.     //////////////////////////////////////////////////////////////////////////
  959.  
  960.     // chat state
  961.     var messages = [];
  962.     var unreadCount = 0;
  963.     var originalTitle = document.title;
  964.  
  965.     // UI constants (80% scale)
  966.     // Area(video) before: [((1168+(1274-1168) - 360*0.8)^2)*9/16] = 470k px^2
  967.     // Area(video) after: [((1168+(1274-1168) - 360)^2)*9/16] = 546k px^2
  968.     var defaultScale = 0.8;
  969.     var chatSidebarWidth = 360*defaultScale;
  970.     var chatSidebarPadding = 16*defaultScale;
  971.     var avatarSize = 20*defaultScale;
  972.     var avatarPadding = 4*defaultScale;
  973.     var avatarBorder = 2*defaultScale;
  974.     var chatVericalMargin = 4*defaultScale;
  975.     var chatInputBorder = 2*defaultScale;
  976.     var chatMessageHorizontalPadding = 8*defaultScale;
  977.     var chatMessageVerticalPadding = 8*defaultScale;
  978.     var presenceIndicatorHeight = 30*defaultScale;
  979.  
  980.     // summary state
  981.     var messagesCount = 0;
  982.     var interactionsCount = 0;
  983.     var sessionStartTime; // duration
  984.     var summarySent = false;
  985.  
  986.     // this is the markup that needs to be injected onto the page for chat
  987.  
  988.     var chatHTML2 = '';
  989.     var setHTML = function() {
  990.     console.log('set html called');
  991.     chatHtml2 = `
  992.       <style>
  993.          #chat-wrapper {
  994.           width: ${chatSidebarWidth}px;
  995.           height: 100%;
  996.           background: #1a1a1a;
  997.           position: absolute;
  998.           top: 0;
  999.           right: 0;
  1000.           bottom: 0;
  1001.           cursor: auto;
  1002.           user-select: text;
  1003.           -webkit-user-select: text;
  1004.           z-index: 9999999999;
  1005.         }
  1006.  
  1007.         #chat-wrapper #chat-container {
  1008.           // width: 228px;
  1009.           height: 100%;
  1010.           position: relative;
  1011.           left: 0;
  1012.           right: 0;
  1013.           margin: 0 auto;
  1014.         }
  1015.  
  1016.         // Raymond's Styling Code
  1017.  
  1018.         @import url("https://fonts.googleapis.com/css?family=Poppins:400,500,600,700,800,900");
  1019.         /* line 34, ../sass/base/_settings.scss */
  1020.         body, html {
  1021.           margin: 0em;
  1022.           padding: 0em;
  1023.         }
  1024.  
  1025.         /* line 39, ../sass/base/_settings.scss */
  1026.         h1, h2, h3, h4, h5, h6, p, ul, ol, li, a, section, div {
  1027.           margin: 0em;
  1028.           padding: 0em;
  1029.           list-style: none;
  1030.           outline: none;
  1031.           text-decoration: none;
  1032.         }
  1033.  
  1034.         /* line 47, ../sass/base/_settings.scss */
  1035.         button {
  1036.           border: none;
  1037.           outline: none;
  1038.         }
  1039.         /* line 50, ../sass/base/_settings.scss */
  1040.         button:hover {
  1041.           cursor: pointer;
  1042.         }
  1043.  
  1044.         /*** Works on common browsers ***/
  1045.         /* line 56, ../sass/base/_settings.scss */
  1046.         ::selection {
  1047.           background: #ef3e3a;
  1048.           color: #f2f2f2;
  1049.         }
  1050.  
  1051.         /*** Mozilla based browsers ***/
  1052.         /* line 62, ../sass/base/_settings.scss */
  1053.         ::-moz-selection {
  1054.           background: #ef3e3a;
  1055.           color: #f2f2f2;
  1056.         }
  1057.  
  1058.         /***For Other Browsers ***/
  1059.         /* line 68, ../sass/base/_settings.scss */
  1060.         ::-o-selection {
  1061.           background: #ef3e3a;
  1062.           color: #f2f2f2;
  1063.         }
  1064.  
  1065.         /* line 73, ../sass/base/_settings.scss */
  1066.         ::-ms-selection {
  1067.           background: #ef3e3a;
  1068.           color: #f2f2f2;
  1069.         }
  1070.  
  1071.         /*** For Webkit ***/
  1072.         /* line 79, ../sass/base/_settings.scss */
  1073.         ::-webkit-selection {
  1074.           background: #ef3e3a;
  1075.           color: #f2f2f2;
  1076.         }
  1077.  
  1078.         /* line 3, ../sass/layout/_chatlayout.scss */
  1079.         .NP-red {
  1080.           color: #ef3e3a;
  1081.         }
  1082.  
  1083.         /* line 7, ../sass/layout/_chatlayout.scss */
  1084.         #chat-wrapper {
  1085.           width: 288px;
  1086.           height: 100%;
  1087.           display: flex;
  1088.           flex-flow: column;
  1089.           box-shadow: rgba(0, 0, 0, 0.6) -5px 0px 10px;
  1090.           background: #191919;
  1091.           position: fixed;
  1092.           right: 0;
  1093.         }
  1094.         /* line 14, ../sass/layout/_chatlayout.scss */
  1095.         #chat-wrapper #chat-container {
  1096.           width: 251px;
  1097.           height: 100%;
  1098.           padding: 14px 18.5px;
  1099.         }
  1100.         /* line 17, ../sass/layout/_chatlayout.scss */
  1101.         #chat-wrapper #chat-container #chat-header-container {
  1102.           width: 100%;
  1103.           height: 45px;
  1104.           display: flex;
  1105.           flex-flow: wrap row;
  1106.         }
  1107.         /* line 20, ../sass/layout/_chatlayout.scss */
  1108.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container {
  1109.           display: flex;
  1110.           flex-flow: wrap row;
  1111.           width: 100%;
  1112.           height: 100%;
  1113.           align-items: center;
  1114.         }
  1115.         /* line 24, ../sass/layout/_chatlayout.scss */
  1116.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-title {
  1117.           width: 50%;
  1118.           height: 100%;
  1119.           display: flex;
  1120.           align-items: center;
  1121.         }
  1122.         /* line 28, ../sass/layout/_chatlayout.scss */
  1123.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-title #title h1 {
  1124.           font-family: 'Poppins', sans-serif;
  1125.           font-size: 15.5px;
  1126.           font-weight: 600;
  1127.           color: #ef3e3a;
  1128.         }
  1129.         /* line 33, ../sass/layout/_chatlayout.scss */
  1130.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user {
  1131.           width: 50%;
  1132.           height: 100%;
  1133.           display: flex;
  1134.           flex-flow: wrap row;
  1135.           align-items: center;
  1136.         }
  1137.         /* line 37, ../sass/layout/_chatlayout.scss */
  1138.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #link-icon {
  1139.           width: 50%;
  1140.           height: 100%;
  1141.           display: flex;
  1142.           flex-flow: wrap row;
  1143.           justify-content: flex-end;
  1144.         }
  1145.         /* line 41, ../sass/layout/_chatlayout.scss */
  1146.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #link-icon img {
  1147.           transform: scale(1);
  1148.           transition: 0.3s ease;
  1149.           width: 18px;
  1150.         }
  1151.         /* line 45, ../sass/layout/_chatlayout.scss */
  1152.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #link-icon img:hover {
  1153.           transform: scale(1.15);
  1154.           cursor: pointer;
  1155.         }
  1156.         /* line 51, ../sass/layout/_chatlayout.scss */
  1157.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #user-icon {
  1158.           width: 50%;
  1159.           height: 100%;
  1160.           display: flex;
  1161.           flex-flow: wrap row;
  1162.           justify-content: flex-end;
  1163.         }
  1164.         /* line 55, ../sass/layout/_chatlayout.scss */
  1165.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #user-icon img {
  1166.           filter: drop-shadow(0px 0px 10px #000000);
  1167.           -webkit-filter: drop-shadow(0px 0px 10px #000000);
  1168.           -moz-filter: drop-shadow(0px 0px 10px #000000);
  1169.           width: 38px;
  1170.           transform: scale(1);
  1171.           transform-origin: center;
  1172.           transition: 0.5s ease;
  1173.         }
  1174.         /* line 61, ../sass/layout/_chatlayout.scss */
  1175.         #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #user-icon img:hover {
  1176.           filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
  1177.           -webkit-filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
  1178.           -moz-filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
  1179.           transform: scale(1.1);
  1180.         }
  1181.  
  1182.         /* line 3, ../sass/modules/_msg.scss */
  1183.         #chat-history-container {
  1184.           width: 100%;
  1185.           height: calc(100% - 195px);
  1186.           padding-bottom: 20px;
  1187.           margin-top: 15px;
  1188.           position: relative;
  1189.           overflow: hidden;
  1190.         }
  1191.         /* line 10, ../sass/modules/_msg.scss */
  1192.         #chat-history-container #chat-header {
  1193.           width: 100%;
  1194.           height: 25px;
  1195.           display: flex;
  1196.           flex-flow: wrap row;
  1197.           background: #191919;
  1198.           z-index: 1;
  1199.           align-items: flex-start;
  1200.           position: relative;
  1201.         }
  1202.         /* line 17, ../sass/modules/_msg.scss */
  1203.         #chat-history-container #chat-header h4 {
  1204.           font-family: 'Poppins', sans-serif;
  1205.           font-size: 12px;
  1206.           font-weight: 600;
  1207.           color: #e2e2e2;
  1208.         }
  1209.         /* line 30, ../sass/modules/_msg.scss */
  1210.         #chat-history-container #chat-history {
  1211.           width: 100%;
  1212.           height: 100%;
  1213.           display: flex;
  1214.           flex-flow: column;
  1215.           position: relative;
  1216.           justify-content: flex-start;
  1217.           overflow: auto;
  1218.           max-height: 100%;
  1219.         }
  1220.         /* line 37, ../sass/modules/_msg.scss */
  1221.         #chat-history-container #chat-history .msg {
  1222.           display: flex;
  1223.           flex-flow: wrap row;
  1224.           width: 100%;
  1225.           align-items: center;
  1226.           justify-content: space-between;
  1227.           flex-shrink: 0;
  1228.           padding-bottom: 11px;
  1229.         }
  1230.         /* line 44, ../sass/modules/_msg.scss */
  1231.         #chat-history-container #chat-history .msg .icon {
  1232.           width: 13%;
  1233.           height: 100%;
  1234.           display: flex;
  1235.           flex-flow: wrap row;
  1236.           align-items: center;
  1237.         }
  1238.         /* line 48, ../sass/modules/_msg.scss */
  1239.         #chat-history-container #chat-history .msg .icon img {
  1240.           width: 100%;
  1241.           height: 100%;
  1242.         }
  1243.         /* line 52, ../sass/modules/_msg.scss */
  1244.         #chat-history-container #chat-history .msg .message-system {
  1245.           width: 80%;
  1246.         }
  1247.         /* line 54, ../sass/modules/_msg.scss */
  1248.         #chat-history-container #chat-history .msg .message-system p {
  1249.           font-size: 13px;
  1250.           font-weight: 500;
  1251.           font-family: 'Poppins', sans-serif;
  1252.           font-style: italic;
  1253.           color: #757575;
  1254.         }
  1255.         /* line 62, ../sass/modules/_msg.scss */
  1256.         #chat-history-container #chat-history .msg .message-txt {
  1257.           width: 80%;
  1258.         }
  1259.         /* line 64, ../sass/modules/_msg.scss */
  1260.         #chat-history-container #chat-history .msg .message-txt p {
  1261.           font-family: 'Poppins', sans-serif;
  1262.           font-size: 13px;
  1263.           font-weight: 500;
  1264.           color: #e2e2e2;
  1265.         }
  1266.         /* line 70, ../sass/modules/_msg.scss */
  1267.         #chat-history-container #chat-history .msg-container {
  1268.           display: flex;
  1269.           flex-flow: wrap row;
  1270.           justify-content: space-between;
  1271.           align-items: flex-start;
  1272.           padding-bottom: 11px;
  1273.           width: 100%;
  1274.         }
  1275.         /* line 76, ../sass/modules/_msg.scss */
  1276.         #chat-history-container #chat-history .msg-container .icon-name {
  1277.           width: 13%;
  1278.         }
  1279.         /* line 78, ../sass/modules/_msg.scss */
  1280.         #chat-history-container #chat-history .msg-container .icon-name .icon {
  1281.           width: 100%;
  1282.           height: 100%;
  1283.         }
  1284.         /* line 80, ../sass/modules/_msg.scss */
  1285.         #chat-history-container #chat-history .msg-container .icon-name .icon img {
  1286.           width: 100%;
  1287.           height: 100%;
  1288.         }
  1289.         /* line 85, ../sass/modules/_msg.scss */
  1290.         #chat-history-container #chat-history .msg-container .msg-txt {
  1291.           display: flex;
  1292.           flex-flow: column;
  1293.           width: 80%;
  1294.         }
  1295.         /* line 88, ../sass/modules/_msg.scss */
  1296.         #chat-history-container #chat-history .msg-container .msg-txt h3 {
  1297.           font-family: 'Poppins', sans-serif;
  1298.           font-size: 13px;
  1299.           font-weight: 500;
  1300.           color: #c3c3c3;
  1301.           padding-bottom: 0.15rem;
  1302.         }
  1303.         /* line 93, ../sass/modules/_msg.scss */
  1304.         #chat-history-container #chat-history .msg-container .msg-txt p {
  1305.           font-family: 'Poppins', sans-serif;
  1306.           font-size: 13px;
  1307.           font-weight: 500;
  1308.           color: #e2e2e2;
  1309.         }
  1310.         /* line 98, ../sass/modules/_msg.scss */
  1311.         #chat-history-container #chat-history .msg-container .message-system p {
  1312.           font-family: 'Poppins', sans-serif;
  1313.           font-size: 13px;
  1314.           font-weight: 500;
  1315.           font-style: italic;
  1316.           color: #757575;
  1317.         }
  1318.         /* line 104, ../sass/modules/_msg.scss */
  1319.         #chat-history-container #chat-history > :first-child {
  1320.           margin-top: auto !important;
  1321.         }
  1322.         /* line 107, ../sass/modules/_msg.scss */
  1323.         #chat-history-container #chat-history::-webkit-scrollbar {
  1324.           width: 2px;
  1325.         }
  1326.         /* line 110, ../sass/modules/_msg.scss */
  1327.         #chat-history-container #chat-history::-webkit-scrollbar-thumb {
  1328.           border-radius: 25px;
  1329.           background: #ef3e3a;
  1330.         }
  1331.         /* line 114, ../sass/modules/_msg.scss */
  1332.         #chat-history-container #chat-history::-webkit-scrollbar-track {
  1333.           border-radius: 25px;
  1334.           background: #e0e0e0;
  1335.         }
  1336.  
  1337.         /* line 121, ../sass/modules/_msg.scss */
  1338.         #chat-input-container {
  1339.           width: 100%;
  1340.         }
  1341.         /* line 123, ../sass/modules/_msg.scss */
  1342.         #chat-input-container #chat-input {
  1343.           font-family: 'Poppins', sans-serif;
  1344.           font-size: 13px;
  1345.           font-weight: 500;
  1346.           width: 100%;
  1347.           padding-top: 10px;
  1348.           background: none;
  1349.           border: none;
  1350.           outline: none;
  1351.           color: #e2e2e2;
  1352.           border-bottom: 1.2px solid;
  1353.           border-bottom-color: #aaaaaa;
  1354.           transition: 0.2s ease;
  1355.         }
  1356.         /* line 134, ../sass/modules/_msg.scss */
  1357.         #chat-input-container #chat-input[type=text]:focus {
  1358.           transition: 0.2s ease;
  1359.           border-bottom: 1.5px solid;
  1360.           border-bottom-color: #e2e2e2;
  1361.         }
  1362.  
  1363.         /* line 142, ../sass/modules/_msg.scss */
  1364.         #presence-indicator {
  1365.           font-family: 'Poppins', sans-serif;
  1366.           font-size: 11.5px;
  1367.           font-weight: 500;
  1368.           font-style: italic;
  1369.           color: #757575;
  1370.           white-space: pre-wrap;
  1371.         }
  1372.         /* line 147, ../sass/modules/_msg.scss */
  1373.         #presence-indicator p {
  1374.           font-family: 'Poppins', sans-serif;
  1375.           font-size: 11.5px;
  1376.           font-weight: 500;
  1377.           font-style: italic;
  1378.           color: #757575;
  1379.         }
  1380.  
  1381.         /* line 154, ../sass/modules/_msg.scss */
  1382.         #patreon-container {
  1383.           width: 100%;
  1384.           padding-top: 16px;
  1385.         }
  1386.         /* line 157, ../sass/modules/_msg.scss */
  1387.         #patreon-container #patreon-link {
  1388.           display: flex;
  1389.           flex-flow: wrap row;
  1390.           align-items: center;
  1391.         }
  1392.         /* line 160, ../sass/modules/_msg.scss */
  1393.         #patreon-container #patreon-link:hover {
  1394.           cursor: pointer;
  1395.         }
  1396.         /* line 163, ../sass/modules/_msg.scss */
  1397.         #patreon-container #patreon-link p {
  1398.           font-family: 'Poppins', sans-serif;
  1399.           font-size: 14.5px;
  1400.           font-weight: 600;
  1401.           color: #949494;
  1402.           width: 40%;
  1403.         }
  1404.         /* line 168, ../sass/modules/_msg.scss */
  1405.         #patreon-container #patreon-link img {
  1406.           border-radius: 20px;
  1407.           width: 60%;
  1408.         }
  1409.  
  1410.         /* line 3, ../sass/modules/_setting.scss */
  1411.         #setting-edit {
  1412.           display: flex;
  1413.           flex-flow: column;
  1414.           position: relative;
  1415.           width: 100%;
  1416.         }
  1417.         /* line 7, ../sass/modules/_setting.scss */
  1418.         #setting-edit .section-b {
  1419.           width: 100%;
  1420.           height: 85px;
  1421.           display: flex;
  1422.           flex-flow: wrap row;
  1423.           justify-content: center;
  1424.           margin: 15px 0px;
  1425.         }
  1426.         /* line 12, ../sass/modules/_setting.scss */
  1427.         #setting-edit .section-b .section-b-inner {
  1428.           height: 100%;
  1429.           text-align: center;
  1430.         }
  1431.         /* line 15, ../sass/modules/_setting.scss */
  1432.         #setting-edit .section-b .section-b-inner .user-icon {
  1433.           width: 100%;
  1434.           height: 100%;
  1435.           display: flex;
  1436.         }
  1437.         /* line 18, ../sass/modules/_setting.scss */
  1438.         #setting-edit .section-b .section-b-inner .user-icon img {
  1439.           width: 100%;
  1440.           height: 100%;
  1441.           transform: scale(0.95);
  1442.           transition: 0.5s ease;
  1443.         }
  1444.         /* line 22, ../sass/modules/_setting.scss */
  1445.         #setting-edit .section-b .section-b-inner .user-icon img:hover {
  1446.           cursor: pointer;
  1447.           transform: scale(1);
  1448.         }
  1449.         /* line 30, ../sass/modules/_setting.scss */
  1450.         #setting-edit .section-c {
  1451.           display: flex;
  1452.           flex-flow: column;
  1453.         }
  1454.         /* line 32, ../sass/modules/_setting.scss */
  1455.         #setting-edit .section-c .section-c-inner {
  1456.           display: flex;
  1457.           flex-flow: column;
  1458.         }
  1459.         /* line 34, ../sass/modules/_setting.scss */
  1460.         #setting-edit .section-c .section-c-inner .nickname-section {
  1461.           display: flex;
  1462.           flex-flow: column;
  1463.         }
  1464.         /* line 36, ../sass/modules/_setting.scss */
  1465.         #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap {
  1466.           display: flex;
  1467.           flex-flow: wrap row;
  1468.         }
  1469.         /* line 38, ../sass/modules/_setting.scss */
  1470.         #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap h2 {
  1471.           font-family: 'Poppins', sans-serif;
  1472.           font-size: 13px;
  1473.           font-weight: 500;
  1474.           color: #c3c3c3;
  1475.           width: 50%;
  1476.         }
  1477.         /* line 43, ../sass/modules/_setting.scss */
  1478.         #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap .np-btn {
  1479.           display: flex;
  1480.           flex-flow: wrap row;
  1481.           align-items: center;
  1482.           width: 50%;
  1483.         }
  1484.         /* line 47, ../sass/modules/_setting.scss */
  1485.         #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap .np-btn a {
  1486.           display: flex;
  1487.           flex-flow: wrap row;
  1488.           width: 100%;
  1489.           justify-content: flex-end;
  1490.           align-items: center;
  1491.         }
  1492.         /* line 52, ../sass/modules/_setting.scss */
  1493.         #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap .np-btn a:hover {
  1494.           cursor: default;
  1495.         }
  1496.         /* line 55, ../sass/modules/_setting.scss */
  1497.         #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap .np-btn a img {
  1498.           width: 13.5%;
  1499.           opacity: 0.5;
  1500.         }
  1501.         /* line 62, ../sass/modules/_setting.scss */
  1502.         #setting-edit .section-c .section-c-inner .nickname-section .nickname-input {
  1503.           margin-top: 1px;
  1504.           width: 100%;
  1505.         }
  1506.         /* line 65, ../sass/modules/_setting.scss */
  1507.         #setting-edit .section-c .section-c-inner .nickname-section .nickname-input #nickname-edit {
  1508.           font-family: 'Poppins', sans-serif;
  1509.           font-size: 13.5px;
  1510.           font-weight: 500;
  1511.           width: 100%;
  1512.           color: #e2e2e2;
  1513.           background: none;
  1514.           border: none;
  1515.           outline: none;
  1516.           border-bottom: 1.2px solid;
  1517.           border-bottom-color: #e2e2e2;
  1518.         }
  1519.         /* line 74, ../sass/modules/_setting.scss */
  1520.         #setting-edit .section-c .section-c-inner .nickname-section .nickname-input #nickname-edit[type=text]:focus {
  1521.           transition: 0.2s ease;
  1522.           border-bottom: 1.2px solid;
  1523.           border-bottom-color: #2cda00;
  1524.         }
  1525.  
  1526.         /* line 86, ../sass/modules/_setting.scss */
  1527.         #settings-save {
  1528.           position: relative;
  1529.           width: 100%;
  1530.         }
  1531.         /* line 89, ../sass/modules/_setting.scss */
  1532.         #settings-save .section-d {
  1533.           width: 100%;
  1534.           margin-top: 1rem;
  1535.         }
  1536.         /* line 92, ../sass/modules/_setting.scss */
  1537.         #settings-save .section-d .section-d-inner {
  1538.           width: 100%;
  1539.           height: 35px;
  1540.         }
  1541.         /* line 94, ../sass/modules/_setting.scss */
  1542.         #settings-save .section-d .section-d-inner .btns {
  1543.           width: 100%;
  1544.           height: 100%;
  1545.         }
  1546.         /* line 96, ../sass/modules/_setting.scss */
  1547.         #settings-save .section-d .section-d-inner .btns button {
  1548.           font-family: 'Poppins', sans-serif;
  1549.           font-size: 12px;
  1550.           font-weight: 500;
  1551.           width: 100%;
  1552.           height: 100%;
  1553.           border-radius: 50px;
  1554.           background: #5c5c5c;
  1555.           color: #e2e2e2;
  1556.           transition: 0.5s ease;
  1557.         }
  1558.         /* line 103, ../sass/modules/_setting.scss */
  1559.         #settings-save .section-d .section-d-inner .btns button:hover {
  1560.           background: #ef3e3a;
  1561.         }
  1562.  
  1563.         /* line 3, ../sass/modules/_icon.scss */
  1564.         #chat-icon-container {
  1565.           display: flex;
  1566.           flex-flow: column;
  1567.         }
  1568.         /* line 5, ../sass/modules/_icon.scss */
  1569.         #chat-icon-container #icon-title-container {
  1570.           margin: 10px 0px;
  1571.         }
  1572.         /* line 7, ../sass/modules/_icon.scss */
  1573.         #chat-icon-container #icon-title-container #icon-title h2 {
  1574.           font-family: 'Poppins', sans-serif;
  1575.           font-size: 13px;
  1576.           font-weight: 600;
  1577.           color: #e2e2e2;
  1578.         }
  1579.         /* line 12, ../sass/modules/_icon.scss */
  1580.         #chat-icon-container #icon-holder-container {
  1581.           display: flex;
  1582.           flex-flow: wrap row;
  1583.         }
  1584.         /* line 14, ../sass/modules/_icon.scss */
  1585.         #chat-icon-container #icon-holder-container #icon-holder-template {
  1586.           display: flex;
  1587.           flex-flow: wrap row;
  1588.         }
  1589.         /* line 16, ../sass/modules/_icon.scss */
  1590.         #chat-icon-container #icon-holder-container #icon-holder-template #icon-holder {
  1591.           display: flex;
  1592.           flex-flow: wrap row;
  1593.           width: 100%;
  1594.           height: 100%;
  1595.         }
  1596.         /* line 19, ../sass/modules/_icon.scss */
  1597.         #chat-icon-container #icon-holder-container #icon-holder-template #icon-holder .image-button {
  1598.           width: 22%;
  1599.           padding: 1px 3.75px;
  1600.         }
  1601.         /* line 22, ../sass/modules/_icon.scss */
  1602.         #chat-icon-container #icon-holder-container #icon-holder-template #icon-holder .image-button .img-class {
  1603.           width: 100%;
  1604.           height: 100%;
  1605.           transform: scale(0.95);
  1606.           transition: 0.3s ease;
  1607.         }
  1608.         /* line 26, ../sass/modules/_icon.scss */
  1609.         #chat-icon-container #icon-holder-container #icon-holder-template #icon-holder .image-button .img-class:hover {
  1610.           filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
  1611.           -webkit-filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
  1612.           -moz-filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
  1613.           transform: scale(1);
  1614.           curosr: pointer;
  1615.         }
  1616.  
  1617.  
  1618.       </style>
  1619.  
  1620.       <script>
  1621.       var script = document.createElement('script');
  1622.       script.src = 'https://code.jquery.com/jquery-1.11.0.min.js';
  1623.       document.getElementsByTagName('head')[0].appendChild(script);
  1624.  
  1625.  
  1626.       </script>
  1627.       <div id="notification-link" class="notification-links">
  1628.  
  1629.       </div>
  1630.  
  1631.       <div id="chat-wrapper">
  1632.         <div id="chat-container">
  1633.  
  1634.           <div id="chat-header-container">
  1635.  
  1636.             <ul id="chat-menu-container">
  1637.               <li id="function-title">
  1638.                 <div id="title">
  1639.                   <h1>Netflix Party</h1>
  1640.                 </div>
  1641.               </li>
  1642.               <li id="function-user">
  1643.                 <div id="link-icon">
  1644.                   <img src='${chrome.runtime.getURL("img/Link.svg")}'>
  1645.                   <input id="share-url" type="text" readonly="true" autocomplete="off" autofocus style="display:none;" />
  1646.                 </div>
  1647.                 <a id="user-icon">
  1648.                   <img src='${getUserIconURL(userSettings.userId, userSettings.userIcon)}'>
  1649.                 </a>
  1650.               </li>
  1651.             </ul>
  1652.  
  1653.             <div id="chat-link-container" style='display:none;'>
  1654.               <div id="chat-link">
  1655.                 <div id="chat-link-url">
  1656.                   <p>The url link goes here.</p>
  1657.                 </div>
  1658.                 <div id="chat-link-icon">
  1659.                   <img src='${chrome.runtime.getURL("img/Link.svg")}'>
  1660.                 </div>
  1661.               </div>
  1662.             </div>
  1663.  
  1664.             <div id="chat-icon-container" style="display:none">
  1665.               <div id="icon-title-container">
  1666.                 <div id="icon-title">
  1667.                   <h2>Click to switch icon</h2>
  1668.                 </div>
  1669.               </div>
  1670.               <div id="icon-holder-container">
  1671.                 <div id="icon-holder-template">
  1672.                   <ul id="icon-holder">
  1673.                   </ul>
  1674.                 </div>
  1675.               </div>
  1676.             </div>
  1677.  
  1678.           </div>
  1679.  
  1680.           <div id="setting-edit" class="chat-settings-container" style="display:none">
  1681.  
  1682.             <div class="section-b">
  1683.               <div class="section-b-inner section-inner">
  1684.                 <a class="user-icon">
  1685.                   <img src='${getUserIconURL(userSettings.userId, userSettings.userIcon)}' />
  1686.                 </a>
  1687.               </div>
  1688.             </div>
  1689.  
  1690.             <div class="section-c">
  1691.               <div class="section-c-inner section-inner">
  1692.                 <div class="nickname-section row-wrap">
  1693.                   <div class="nickname-wrap row-one">
  1694.                     <h2>Nickname</h2>
  1695.                     <div class="np-btn">
  1696.                       <a>
  1697.                       <!--  <p>Edit</p> -->
  1698.                         <img src='${chrome.runtime.getURL("img/edit.svg")}' />
  1699.                       </a>
  1700.                     </div>
  1701.                   </div>
  1702.                   <div class="nickname-input row-two">
  1703.                     <input id="nickname-edit" type="text" placeholder='${userSettings.userNickname ? userSettings.userNickname : "Add a nickname"}'/>
  1704.                   </div>
  1705.                 </div>
  1706.               </div>
  1707.             </div>
  1708.  
  1709.           </div>
  1710.  
  1711.           <div id="settings-save" class="chat-settings-container" style="display:none">
  1712.             <div class="section-d">
  1713.               <div class="section-d-inner section-inner">
  1714.  
  1715.                 <div class="btns">
  1716.                   <button>Save Changes</button>
  1717.                 </div>
  1718.               </div>
  1719.             </div>
  1720.           </div>
  1721.  
  1722.           <div id="chat-history-container">
  1723.             <div id="chat-header">
  1724.               <h4>Chatroom</h4>
  1725.             </div>
  1726.             <!-- <div id="chat-gradient"></div> -->
  1727.             <div id="chat-history">
  1728.             </div>
  1729.           </div>
  1730.  
  1731.           <div id="presence-indicator">
  1732.             <p>People are currently typing...</p>
  1733.           </div>
  1734.  
  1735.           <div id="chat-input-container">
  1736.             <input id="chat-input" type="text" placeholder="Type a message..." autocomplete="off"></input>
  1737.           </div>
  1738.  
  1739.           <div id="patreon-container">
  1740.             <a id="patreon-link" href="https://www.patreon.com/netflixparty" target="_blank">
  1741.               <p>
  1742.                 Support NP
  1743.               </p>
  1744.               <img src='https://c5.patreon.com/external/logo/become_a_patron_button@2x.png' />
  1745.             </a>
  1746.           </div>
  1747.  
  1748.         </div>
  1749.       </div>
  1750.     `;
  1751.     }
  1752.  
  1753.  
  1754.     // this is used for the chat presence feature
  1755.     var typingTimer = null;
  1756.  
  1757.     var allowFullScreen = function() {
  1758.         // allow keyboard input on fullscreen
  1759.         var script = document.createElement( "script" );
  1760.         var fsCode = `
  1761.             // document.getElementsByClassName("sizing-wrapper")[0].webkitRequestFullScreen = function() {
  1762.             //  console.log("fullscreen test");
  1763.             //  var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
  1764.             //  fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
  1765.             // }
  1766.             // var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
  1767.             // fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
  1768.  
  1769.  
  1770.             // document.getElementsByClassName("sizing-wrapper")[0].requestFullScreen = function() {
  1771.             //  console.log("fullscreen test");
  1772.             //  var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
  1773.             //  fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
  1774.             // }
  1775.  
  1776.             document.getElementsByClassName("sizing-wrapper")[0].requestFullscreen = function() {console.log('test');}
  1777.  
  1778.             console.log("fullscreen loaded? :" + document.getElementsByClassName('button-nfplayerFullscreen').length);
  1779.  
  1780.             document.getElementsByClassName('button-nfplayerFullscreen')[0].onclick = function() {
  1781.                 console.log('fullscreen click');
  1782.                 var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
  1783.                 fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
  1784.             }
  1785.             //  var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
  1786.             //  fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
  1787.             // }
  1788.         `;
  1789.         script.text = fsCode;
  1790.         document.head.appendChild( script );
  1791.     }
  1792.  
  1793.     // set up the chat state, or reset the state if the system has already been set up
  1794.     var initChat = function() {
  1795.       if (jQuery('#chat-wrapper').length === 0) {
  1796.  
  1797.         // setHTML().then(jQuery('.sizing-wrapper').after(chatHtml2));
  1798.         jQuery('.sizing-wrapper').after(chatHtml2);
  1799.         allowFullScreen();
  1800.         jQuery('#presence-indicator').data('typing', false);
  1801.         jQuery('#presence-indicator').data('buffering', false);
  1802.         setPresenceVisible(false);
  1803.         // setPresenceText();
  1804.         // jQuery('#presence-indicator').hide();
  1805.  
  1806.  
  1807.         var userIconListener = function(e) {
  1808.           console.log('userIcon button clicked');
  1809.           // console.log()
  1810.           toggleIconContainer();
  1811.         }
  1812.         jQuery('#user-icon').click(userIconListener);
  1813.  
  1814.         var linkIconListener = function(e) {
  1815.           console.log('linkIcon button clicked');
  1816.  
  1817.         var currVideoUrl = window.location.href.split('?')[0];
  1818.           var partySessionId = sessionId;
  1819.           var serverId = getURLParameter(url, 'npServerId', 1) ? getURLParameter(url, 'npServerId', 1) : defaultServer;
  1820.           if(currVideoUrl && partySessionId && serverId) {
  1821.             var urlWithSessionId = currVideoUrl + '?npSessionId=' + encodeURIComponent(sessionId) + '&npServerId=' + encodeURIComponent(serverId);
  1822.             console.log(urlWithSessionId);
  1823.             // jQuery('#share-url').val(urlWithSessionId).focus().select();
  1824.  
  1825.               const el = document.createElement('textarea');
  1826.               el.value = urlWithSessionId;
  1827.               document.body.appendChild(el);
  1828.               el.select();
  1829.               document.execCommand('copy');
  1830.               document.body.removeChild(el);
  1831.  
  1832.           }
  1833.  
  1834.  
  1835.           // document.execCommand('copy');
  1836.  
  1837.           // e.stopPropagation();
  1838.           // e.preventDefault();
  1839.         }
  1840.         jQuery('#link-icon').click(linkIconListener);
  1841.  
  1842.         // large user icon listener to go to icon holder menu
  1843.         var largeUserIconListener = function(e) {
  1844.           console.log('userIcon button clicked');
  1845.           // console.log()
  1846.           toggleLargeUserIconButton();
  1847.         }
  1848.         jQuery('.user-icon').click(largeUserIconListener);
  1849.  
  1850.  
  1851.         addIconSelector();
  1852.         var userIconSelectorListener = function(e) {
  1853.           if(jQuery(this).data('icon')) {
  1854.             console.log('userIconSelector button clicked: ' + jQuery(this).data('icon'));
  1855.             setUserIcon(userSettings.userId, jQuery(this).data('icon'), true);
  1856.           }
  1857.  
  1858.           // setUserIcon();
  1859.           // logIcons();
  1860.           // console.log()
  1861.           toggleIconContainer();
  1862.         }
  1863.         jQuery('.image-button').click(userIconSelectorListener);
  1864.  
  1865.         var saveChangesListener = function(e) {
  1866.           var nicknameText = jQuery('.nickname-input input').val().replace(/^\s+|\s+$/g, '');
  1867.  
  1868.           if(nicknameText != '') {
  1869.             console.log('saveChanges button clicked: ' + nicknameText);
  1870.             setUserNickname(userSettings.userId, nicknameText, true);
  1871.           }
  1872.  
  1873.           // setUserIcon();
  1874.           // logIcons();
  1875.           // console.log()
  1876.           toggleIconContainer();
  1877.         }
  1878.         jQuery('.btns button').click(saveChangesListener);
  1879.  
  1880.  
  1881.  
  1882.         var oldPageX = null;
  1883.         var oldPageY = null;
  1884.         jQuery('#chat-wrapper').mousedown(function(e) {
  1885.           oldPageX = e.pageX;
  1886.           oldPageY = e.pageY;
  1887.         });
  1888.         jQuery('#chat-wrapper').mouseup(function(e) {
  1889.           if ((e.pageX - oldPageX) * (e.pageX - oldPageX) + (e.pageY - oldPageY) * (e.pageY - oldPageY) < 5) {
  1890.             jQuery('#chat-input').focus();
  1891.             e.stopPropagation();
  1892.           }
  1893.         });
  1894.         jQuery('#chat-input-container').click(function(e) {
  1895.           jQuery('#chat-input').focus();
  1896.         });
  1897.         jQuery('#chat-input').keyup(function(e) {
  1898.           e.stopPropagation();
  1899.  
  1900.           // event keycode 13 is the enter key
  1901.           if (e.which === 13) {
  1902.             var body = jQuery('#chat-input').val().replace(/^\s+|\s+$/g, '');
  1903.             if (body !== '') {
  1904.               if (typingTimer !== null) {
  1905.                 clearTimeout(typingTimer);
  1906.                 typingTimer = null;
  1907.                 socket.emit('typing', { typing: false }, function() {});
  1908.               }
  1909.  
  1910.               jQuery('#chat-input').prop('disabled', true);
  1911.               socket.emit('sendMessage', {
  1912.                 body: body
  1913.               }, function() {
  1914.                 jQuery('#chat-input').val('').prop('disabled', false).focus();
  1915.               });
  1916.             }
  1917.           } else {
  1918.             if (typingTimer === null) {
  1919.               socket.emit('typing', { typing: true }, function() {});
  1920.             } else {
  1921.               clearTimeout(typingTimer);
  1922.             }
  1923.             typingTimer = setTimeout(function() {
  1924.               typingTimer = null;
  1925.               socket.emit('typing', { typing: false }, function() {});
  1926.             }, 500);
  1927.           }
  1928.         });
  1929.         // jQuery('#chat-input-avatar').html(`<img src="data:image/png;base64,${new Identicon(Sha256.hash(userId).substr(0, 32), avatarSize * 2, 0).toString()}" />`);
  1930.  
  1931.         // receive messages from the server
  1932.         socket.on('sendMessage', function(data) {
  1933.           addMessage(data);
  1934.         });
  1935.  
  1936.         // receive presence updates from the server
  1937.         socket.on('setPresence', function(data) {
  1938.           setPresenceVisible(data.anyoneTyping);
  1939.         });
  1940.  
  1941.         // receive buffering presence updates from the server
  1942.         socket.on('setBufferingPresence', function(data) {
  1943.  
  1944.           setBufferingPresenceVisible(data.anyoneBuffering);
  1945.           othersAreBuffering = data.anyoneBuffering;
  1946.  
  1947.           var time = new Date();
  1948.           var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
  1949.           // console.log('received buffering update: ' + data.anyoneBuffering + timeStatus);
  1950.           // if(othersAreBuffering) console.log('others are buffering: ' + othersAreBuffering + timeStatus);
  1951.         });
  1952.  
  1953.       } else {
  1954.         jQuery('#chat-history').html('');
  1955.       }
  1956.     };
  1957.  
  1958.     // query whether the chat sidebar is visible
  1959.     var getChatVisible = function() {
  1960.       return jQuery('.sizing-wrapper').hasClass('with-chat');
  1961.     };
  1962.  
  1963.     // show or hide the chat sidebar
  1964.     var setChatVisible = function(visible) {
  1965.       if (visible) {
  1966.         jQuery('.sizing-wrapper').addClass('with-chat');
  1967.         jQuery('.sizing-wrapper').css('right', chatSidebarWidth + 'px');
  1968.         jQuery('#chat-wrapper').show();
  1969.         if (!document.hasFocus()) {
  1970.           clearUnreadCount();
  1971.         }
  1972.       } else {
  1973.         jQuery('#chat-wrapper').hide();
  1974.         jQuery('.sizing-wrapper').removeClass('with-chat');
  1975.         jQuery('.sizing-wrapper').css('right', '0px');
  1976.       }
  1977.     };
  1978.  
  1979.     // show or hide the icon container
  1980.     var toggleIconContainer = function() {
  1981.       // console.log('toggle')
  1982.  
  1983.       // document.getElementById("demo").innerHTML = "Hello World";
  1984.       if(jQuery("#chat-icon-container").data('active')) {
  1985.         jQuery("#chat-icon-container").data('active', false);
  1986.         jQuery("#chat-icon-container").hide();
  1987.         jQuery(".chat-settings-container").hide();
  1988.  
  1989.         // jQuery("#chat-link-container").show();
  1990.         jQuery("#chat-history-container").show();
  1991.         jQuery("#chat-input-container").show();
  1992.         jQuery("#patreon-container").show();
  1993.  
  1994.       } else {
  1995.         jQuery("#chat-icon-container").data('active', true);
  1996.         // jQuery("#chat-icon-container").show();
  1997.         jQuery(".chat-settings-container").show();
  1998.         jQuery("#chat-icon-container").hide();
  1999.         jQuery("#chat-link-container").hide();
  2000.         jQuery("#chat-history-container").hide();
  2001.         jQuery("#chat-input-container").hide();
  2002.         jQuery("#patreon-container").hide();
  2003.       }
  2004.     };
  2005.  
  2006.     // show or hide the icon container
  2007.     var toggleLargeUserIconButton = function() {
  2008.       // console.log('toggle')
  2009.  
  2010.       // document.getElementById("demo").innerHTML = "Hello World";
  2011.       if(jQuery("#chat-icon-container").data('active')) {
  2012.         // jQuery("#chat-icon-container").data('active', false);
  2013.         jQuery("#chat-icon-container").show();
  2014.         // jQuery("#chat-link-container").show();
  2015.         jQuery(".chat-settings-container").hide();
  2016.         // jQuery(".chat-settings-container").data('active', false);
  2017.  
  2018.       }
  2019.     };
  2020.  
  2021.     // remove chat
  2022.     var removeChat = function() {
  2023.       clearUnreadCount();
  2024.       jQuery('#chat-container').remove();
  2025.       jQuery('#chat-wrapper').remove();
  2026.       jQuery('.sizing-wrapper').removeClass('with-chat');
  2027.       jQuery('.sizing-wrapper').css('right', '0px');
  2028.     };
  2029.  
  2030.     // show or hide the "People are typing..." indicator
  2031.     var setPresenceVisible = function(visible) {
  2032.       jQuery('#presence-indicator').data('typing', visible);
  2033.       setPresenceText();
  2034.       if (visible) {
  2035.         jQuery('#presence-indicator').show();
  2036.       } else {
  2037.         // jQuery('#presence-indicator').hide();
  2038.       }
  2039.     };
  2040.  
  2041.     // show or hide the "People are buffering..." indicator
  2042.     var setBufferingPresenceVisible = function(visible) {
  2043.       jQuery('#presence-indicator').data('buffering', visible);
  2044.       setPresenceText();
  2045.       if (visible) {
  2046.         jQuery('#presence-indicator').show();
  2047.       } else {
  2048.         // jQuery('#presence-indicator').hide();
  2049.       }
  2050.     };
  2051.  
  2052.     var setPresenceText = function() {
  2053.       var typing = jQuery('#presence-indicator').data('typing');
  2054.       var buffering = jQuery('#presence-indicator').data('buffering');
  2055.       if(typing && buffering) {
  2056.         jQuery('#presence-indicator').text('People are typing and buffering...')
  2057.       } else if (typing) {
  2058.         jQuery('#presence-indicator').text('People are typing...')
  2059.       } else if(buffering) {
  2060.         jQuery('#presence-indicator').text('People are buffering...')
  2061.       } else {
  2062.         jQuery('#presence-indicator').text(' ')
  2063.       }
  2064.     }
  2065.  
  2066.     // var iconURL = chrome.runtime.getURL('img/' + icons[Math.floor(Math.random() * icons.length)]);
  2067.  
  2068.     // add a message to the chat history
  2069.     var addMessage = function(message) {
  2070.      
  2071.       // jQuery('#chat-history').append(`
  2072.       //   <div class="chat-message${ message.isSystemMessage ? ' system-message' : '' }">
  2073.       //     <div class="chat-message-avatar"><img src="data:image/png;base64,${new Identicon(Sha256.hash(message.userId).substr(0, 32), avatarSize * 2, 0).toString()}" /></div>
  2074.       //     <div class="chat-message-body">${message.body.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</div>
  2075.       //   </div>
  2076.       // `);
  2077.  
  2078.       // console.log("messageId " + message.userId);
  2079.       // console.log("message permId " + message.permId);
  2080.       // console.log("message userIcon " + message.userIcon);
  2081.       // console.log("user/perm: " + userId + ", " + permId);
  2082.       // console.log("messageId is the same as userId: " + (message.userId === userId));
  2083.       // console.log("message permId is the same as userId: " + (message.permId === permId));
  2084.       // console.log(JSON.stringify(userIcons));
  2085.  
  2086.       if(message.isSystemMessage && message.body === 'left') {
  2087.         console.log("trying to add left message");
  2088.         if(!(message.userIcon)) {
  2089.             // ignore invalid left message
  2090.             return;
  2091.         }
  2092.       }
  2093.  
  2094.       messages.push(message);
  2095.  
  2096.  
  2097.       var userIcon = message.userIcon ? getUserIconURL(message.permId, message.userIcon) : getUserIconURL(message.permId);
  2098.       var userNickname = message.userNickname ? getUserNickname(message.permId, message.userNickname) : '' // todo create getUserNickame method
  2099.  
  2100.        if(userNickname == '') {
  2101.           var message = jQuery(`
  2102.             <div class="msg">
  2103.               <div class="icon">
  2104.                 <img src="${userIcon}"/>
  2105.               </div>
  2106.               <div class="message${ message.isSystemMessage ? '-system' : '-txt' }">
  2107.                 <p class="msg-nickname">${userNickname.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</p>
  2108.                 <p>${message.body.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</p>
  2109.               </div>
  2110.             </div>
  2111.           `).appendTo(jQuery('#chat-history')).data('permId', message.permId).data('userIcon', userIcon).data('userNickname', userNickname).data('message', message);
  2112.       } else {
  2113.           var nicknameMessage = jQuery(`
  2114.               <div class="msg-container">
  2115.                 <div class="icon-name">
  2116.                   <div class="icon">
  2117.                     <img src="${userIcon}">
  2118.                   </div>
  2119.                 </div>
  2120.                 <div class="msg-txt message${ message.isSystemMessage ? '-system' : '-txt' }">
  2121.               <h3>${userNickname.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</h3>
  2122.                   <p>${message.body.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</p>
  2123.                 </div>
  2124.               </div>
  2125.           `).appendTo(jQuery('#chat-history')).data('permId', message.permId).data('userIcon', userIcon).data('userNickname', userNickname);
  2126.       }
  2127.  
  2128.  
  2129.  
  2130.       jQuery('#chat-history').scrollTop(jQuery('#chat-history').prop('scrollHeight'));
  2131.       unreadCount += 1;
  2132.       messagesCount += 1;
  2133.       if (!document.hasFocus()) {
  2134.         document.title = '(' + String(unreadCount) + ') ' + originalTitle;
  2135.       }
  2136.     };
  2137.  
  2138.     // clear the unread count
  2139.     var clearUnreadCount = function() {
  2140.       if (unreadCount > 0) {
  2141.         unreadCount = 0;
  2142.         document.title = originalTitle;
  2143.       }
  2144.     };
  2145.  
  2146.     // clear the unread count when the window is focused
  2147.     jQuery(window).focus(function() {
  2148.       if (getChatVisible()) {
  2149.         clearUnreadCount();
  2150.       }
  2151.     });
  2152.  
  2153.     // send summary statistics to data server
  2154.     function logSummary() {
  2155.       try {
  2156.         if(permId && sessionStartTime && sessionId && videoId && !summarySent) {
  2157.  
  2158.             var data = {
  2159.                 userId: permId,
  2160.                 sessionId: sessionId,
  2161.                 messagesCount: messagesCount,
  2162.                 interactionsCount: interactionsCount,
  2163.                 duration: new Date() - sessionStartTime,
  2164.                 videoId: videoId,
  2165.                 videoDuration: videoDuration
  2166.             }
  2167.             console.log("summaryData: " + JSON.stringify(data));
  2168.  
  2169.             chrome.runtime.sendMessage({summary: data}, function(response) {
  2170.                 console.log("background script sent xhr");
  2171.             });
  2172.  
  2173.             summarySent = true;
  2174.  
  2175.         }
  2176.  
  2177.       } catch(e) {
  2178.         console.log("log event error");
  2179.       }
  2180.     }
  2181.  
  2182.     var unloadInteraction = function (event) {
  2183.         logSummary();
  2184.     }
  2185.     window.addEventListener("unload", unloadInteraction , true);
  2186.  
  2187.  
  2188.     //////////////////////////////////////////////////////////////////////////
  2189.     // Next episode logic                                                   //
  2190.     //////////////////////////////////////////////////////////////////////////
  2191.  
  2192.     // whether a simulated next episode click is ongoing
  2193.     var simulClick = false;
  2194.  
  2195.     // whether the new episode is some other episode or the next episode
  2196.     var otherEpisode = false
  2197.  
  2198.     // receive next episode updates from the server
  2199.     socket.on('jumpToNextEpisode', function(data) {
  2200.       console.log('received next Episode event: ' + JSON.stringify(data));
  2201.  
  2202.       if(data.otherEpisode) {
  2203.         continueOtherEpisode(data.nextEpisode)
  2204.       } else {
  2205.         continueNextEpisode(data.nextEpisode);
  2206.       }
  2207.     });
  2208.  
  2209.     // enable or disable the session, used during episode transitions
  2210.     var oldSessionId = null;
  2211.     var sessionDisabledStartTime = null;
  2212.     var setSessionEnabled = function(enabled) {
  2213.       // enable session
  2214.       if (enabled) {
  2215.         if(oldSessionId != null && sessionId == null) {
  2216.             sessionId = oldSessionId;
  2217.             oldSessionId = null;
  2218.             sessionDisabledStartTime = null;
  2219.             // uiEventsHappening = 0;
  2220.         }
  2221.       }
  2222.       // disable session
  2223.       else {
  2224.         if(oldSessionId == null && sessionId != null) {
  2225.             oldSessionId = sessionId;
  2226.             sessionId = null;
  2227.             var now = new Date();
  2228.             sessionDisabledStartTime = new Date(now.getTime() - localTimeMinusServerTimeMedian)
  2229.             console.log('sessionDisabledStartTime CREATED: ' + sessionDisabledStartTime.getTime());
  2230.         }
  2231.       }
  2232.     };
  2233.  
  2234.     // disable video synchronization for Netflix Party
  2235.     var disableSync = function() {
  2236.  
  2237.     }
  2238.  
  2239.     // enable video synchronization for Netlfix Party
  2240.     var enableSync = function() {
  2241.  
  2242.     }
  2243.  
  2244.     // jump to next episode if not already on it
  2245.     var continueNextEpisode = function(nextEpisode) {
  2246.       var parseIds = window.location.href.match(/^.*\/([0-9]+)\??.*/);
  2247.       var currVideoId = parseIds.length !== 0 ? parseInt(window.location.href.match(/^.*\/([0-9]+)\??.*/)[1]) : null;
  2248.  
  2249.       // jump to next episode if currEpisode != next Epsiode
  2250.       if (currVideoId != nextEpisode) {
  2251.         // disable the session until the video loads
  2252.         setSessionEnabled(false);
  2253.         // oldSessionId = sessionId;
  2254.         // sessionId = null;
  2255.  
  2256.  
  2257.         // tasks = Promise.resolve();
  2258.         simulClick = true;
  2259.  
  2260.         // otherwise click on the autoplay next episode hover container (short episodes like Friends)
  2261.         if (jQuery('.WatchNext-still-hover-container').length > 0) {
  2262.           jQuery('.WatchNext-still-hover-container').click();
  2263.         }
  2264.  
  2265.         // click on the next episode button (in the middle of episodes)
  2266.         else if (jQuery('.button-nfplayerNextEpisode').length > 0) {
  2267.           jQuery('.button-nfplayerNextEpisode').click();
  2268.         }
  2269.  
  2270.         // otherwise click on the credits next episode button (before AND after credits on long episodes like Umbrella Academy)
  2271.         else if (jQuery('.nf-flat-button-text').length > 0) {
  2272.           if(jQuery('.nf-flat-button-text')[0].text.toLowerCase().includes('next episode')) {
  2273.             jQuery('.nf-flat-button-text')[0].click();
  2274.             // console.log('after credits click');
  2275.           }
  2276.         }
  2277.       }
  2278.     };
  2279.  
  2280.     var continueOtherEpisode = function(otherEpisode) {
  2281.         // tabs[0].url.split('?')[0] + '?npSessionId=' + encodeURIComponent(sessionId) + '&npServerId=' + encodeURIComponent(serverIdFromUrl);
  2282.         // console.log()
  2283.  
  2284.         var parseIds = window.location.href.match(/^.*\/([0-9]+)\??.*/);
  2285.         var currVideoId = parseIds.length !== 0 ? parseInt(window.location.href.match(/^.*\/([0-9]+)\??.*/)[1]) : null;
  2286.  
  2287.         if (currVideoId != otherEpisode) {
  2288.             window.location.href = 'https://www.netflix.com/watch/' + otherEpisode;
  2289.         }
  2290.  
  2291.         alert('Long parties only work for consecutive episodes for now. Please share a new Netflix Party to continue watching together.')
  2292.     }
  2293.  
  2294.     // listen to URL changes on the webpage when next episode changes
  2295.     // modifies the window.history.replaceScript API which Netflix uses in its SPA
  2296.     // https://stackoverflow.com/questions/4570093/how-to-get-notified-about-changes-of-the-history-via-history-pushstate
  2297.     // http://jsfiddle.net/UZHTW/1/
  2298.     var replaceStateScript = `
  2299.       if(!window.replaceScriptLoaded) {
  2300.           console.log("loaded script");
  2301.           window.replaceScriptLoaded = true;
  2302.           (function(history){
  2303.             var replaceState = history.replaceState;
  2304.             history.replaceState = function(state) {
  2305.               if (typeof history.onreplacestate == "function") {
  2306.                 history.onreplacestate({state: state});
  2307.               }
  2308.               return replaceState.apply(history, arguments);
  2309.             }
  2310.           })(window.history);
  2311.  
  2312.           var reloadInteraction = function(e) {
  2313.             console.log("window.history replaceState event; autoplay / next episode clicked / navigated away");
  2314.  
  2315.             // send message to content script w next episode
  2316.             window.postMessage({ type: "FROM_PAGE", text: "next episode from the webpage!"}, "*");
  2317.           }
  2318.           window.onpopstate = history.onreplacestate = reloadInteraction;
  2319.       }
  2320.     `;
  2321.     console.log('replace script loaded: '+ window.replaceScriptLoaded);
  2322.     if(!window.replaceScriptLoaded) {
  2323.         console.log('injecting replace script');
  2324.         injectScript(replaceStateScript);
  2325.     }
  2326.  
  2327.     // listen for next episode events from webpage script via the postMessage API
  2328.     var replaceStateInteraction = function(event) {
  2329.       if (event.source != window)
  2330.         return;
  2331.  
  2332.       if (event.data.type && (event.data.type == "FROM_PAGE")) {
  2333.         console.log('***********************************');
  2334.         logState = true;
  2335.         console.log("Content script received: " + event.data.text);
  2336.  
  2337.         var episodePage = window.location.href.match(/^.*\/(watch)\/.*/);
  2338.         console.log(window.location.href)
  2339.         if (!episodePage) {
  2340.             console.log("time to teardown");
  2341.             teardown();
  2342.         } else {
  2343.           var parseIds = window.location.href.match(/^.*\/([0-9]+)\??.*/);
  2344.           var nextVideoId = parseIds.length !== 0 ? parseInt(window.location.href.match(/^.*\/([0-9]+)\??.*/)[1]) : null;
  2345.  
  2346.           // console.log("simulClick:" + simulClick);
  2347.           // console.log("otherEpisode:" + otherEpisode);
  2348.           socket.emit('nextEpisode', {nextEpisode: nextVideoId, simulClick: simulClick, otherEpisode: otherEpisode}, function() {});
  2349.  
  2350.           if(otherEpisode) {
  2351.             teardown();
  2352.             // alert('Autoplay only works for consecutive episodes for now. Please create a new Netflix Party to continue watching together.')
  2353.             alert('Long parties only work for consecutive episodes for now. Please share a new Netflix Party to continue watching together.')
  2354.             // alert('Long parties only work for consecutive episodes, not for the episode selector. Please create a new party to continue watching');
  2355.           } else if(!otherEpisode) {
  2356.  
  2357.               console.log('replace disable session next episode')
  2358.               setSessionEnabled(false);
  2359.               // if(oldSessionId == null) {
  2360.               //     oldSessionId = sessionId;
  2361.               //    sessionId = null;
  2362.               // }
  2363.  
  2364.  
  2365.               if(oldSessionId != null) {
  2366.                 console.log('oldSessionId is called');
  2367.  
  2368.                 swallow(
  2369.                     delayUntil(function() {
  2370.                         console.log('video unloading');
  2371.                         return !getPlaybackPosition();
  2372.                     }, 5000)
  2373.                 )().then(swallow(
  2374.                     delayUntil(function() {
  2375.                         console.log('replace state loading START');
  2376.                         // todo make sure remaining time > 0:00
  2377.                         var remainingTimeLoaded = false;
  2378.                         var remainingTime = getRemainingTime();
  2379.                         var remainingTimeText = getRemainingTimeText();
  2380.                         // console.log('remainingTime: ' + remainingTime);
  2381.                         // console.log('remainingTimeText: ' + remainingTimeText);
  2382.                         // console.log('remainingTimeLoaded: ' + remainingTimeLoaded);
  2383.                         if(remainingTime != null) {
  2384.                             remainingTimeLoaded = true;
  2385.                         }
  2386.                         return remainingTimeLoaded && getPlaybackPosition() && getState() !== 'loading';
  2387.                     }, Infinity)
  2388.                 )).then(function() {
  2389.  
  2390.                   console.log('replace state loading DONE');
  2391.                   showControls();
  2392.  
  2393.                   // get scrubber time
  2394.                   var localTime = getPlaybackPosition();
  2395.                   var scrubberHead = jQuery(jQuery('.scrubber-head')[0]);
  2396.                   var scrubberTime = parseInt(scrubberHead.attr('aria-valuenow') * 1000);
  2397.                   showControls();
  2398.  
  2399.                   // TODO: get remaining time
  2400.  
  2401.  
  2402.                   // console.log('replace localTime: '+ getPlaybackPosition());
  2403.                   // console.log('replace scrubberTime: '+ scrubberTime);
  2404.  
  2405.                   var now = new Date();
  2406.                   var newLastKnownTime = localTime; // update to use remaining time
  2407.                   // var newLastKnownTime = localTime; // update to use remaining time
  2408.                   var newLastKnownTimeUpdatedAt = new Date(now.getTime() - localTimeMinusServerTimeMedian);
  2409.                   var newState = getState() === 'loading' ? 'paused' : (getState() === 'playing' ? 'playing' : 'paused');
  2410.  
  2411.  
  2412.                   console.log('***********************************');
  2413.                   console.log('localTimeMinusServerTimeMedian: ' + localTimeMinusServerTimeMedian);
  2414.                   console.log('session disabled start time: ' + sessionDisabledStartTime.getTime());
  2415.                   console.log('lastKnownTimeUpdatedAt: ' + lastKnownTimeUpdatedAt.getTime());
  2416.                   var recentUpdate = (lastKnownTimeUpdatedAt.getTime() > sessionDisabledStartTime.getTime())
  2417.                   console.log("RECENT UPDATE: " + recentUpdate);
  2418.                   console.log('***********************************');
  2419.  
  2420.  
  2421.                     if(!recentUpdate) {
  2422.  
  2423.                         oldLastKnownTime = lastKnownTime;
  2424.                         oldLastKnownTimeUpdatedAt = lastKnownTimeUpdatedAt;
  2425.                         oldState = state;
  2426.                         lastKnownTime = newLastKnownTime;
  2427.                         lastKnownTimeUpdatedAt = newLastKnownTimeUpdatedAt;
  2428.                         state = newState;
  2429.  
  2430.  
  2431.                         // console.log('simulClick is false so UPDATE');
  2432.                         socket.emit(updateSessionTarget, {
  2433.                           lastKnownTime: newLastKnownTime,
  2434.                           lastKnownTimeUpdatedAt: newLastKnownTimeUpdatedAt.getTime(),
  2435.                           state: newState,
  2436.                           lastKnownTimeRemaining: getRemainingTime(),
  2437.                           lastKnownTimeRemainingText: getRemainingTimeText(),
  2438.                           videoDuration: getDuration(),
  2439.                           bufferingState: false // change: bufferingState
  2440.                         }, function(data) {
  2441.                           if (data !== undefined && data.errorMessage !== null) {
  2442.                             lastKnownTime = oldLastKnownTime;
  2443.                             lastKnownTimeUpdatedAt = oldLastKnownTimeUpdatedAt;
  2444.                             state = oldState;
  2445.                             // reject();
  2446.                           } else {
  2447.                       //       lastKnownTime = newLastKnownTime;
  2448.                             // lastKnownTimeUpdatedAt = newLastKnownTimeUpdatedAt;
  2449.                             // state = newState;
  2450.                             // resolve();
  2451.                           }
  2452.                             // console.log('delay before reenabling for 1 sec');
  2453.                             // delay(1000)().then(function() {
  2454.                                 console.log('re-enabling sync after next episode');
  2455.                                 console.log('***********************************');
  2456.                                 logState = false;
  2457.                                 var localTime = getPlaybackPosition() || "not defined";
  2458.                                 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
  2459.                                 // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
  2460.  
  2461.                                 allowFullScreen();
  2462.                                 setSessionEnabled(true);
  2463.                                 // sessionId = oldSessionId;
  2464.                                 // oldSessionId = null;
  2465.  
  2466.                                 // pushTask(sync);
  2467.                                 // pushTask(broadcast(false));
  2468.                                 var localTime = getPlaybackPosition() || "not defined";
  2469.                                 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
  2470.                                 // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
  2471.  
  2472.                                 simulClick = false;
  2473.                                 otherEpisode = false;
  2474.                             // });
  2475.  
  2476.                         });
  2477.  
  2478.                     } else {
  2479.  
  2480.                         console.log('recent update is true NO UPDATE');
  2481.  
  2482.                         // insert logic that checks for recent update between when sync was disable and re-enabled
  2483.                         // if there is one then re-enable sync
  2484.                         // if not then send over our own update
  2485.  
  2486.                         // compare syncDisabledTime to lastKnownUpdatedTimeAt
  2487.                         // if syncDisabledTime is after lastKnowUpdatedTimeAt then
  2488.  
  2489.                         console.log('re-enabling sync after next episode');
  2490.                         console.log('***********************************');
  2491.                         logState = false;
  2492.                         allowFullScreen();
  2493.                         setSessionEnabled(true);
  2494.                         // sessionId = oldSessionId;
  2495.                         // oldSessionId = null;
  2496.  
  2497.                         var localTime = getPlaybackPosition() || "not defined";
  2498.                         var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
  2499.                         // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
  2500.  
  2501.                         simulClick = false;
  2502.                         otherEpisode = false;
  2503.  
  2504.                         pushTask(sync);
  2505.  
  2506.                     }
  2507.                 })
  2508.               }
  2509.           }
  2510.         }
  2511.       }
  2512.     }
  2513.     window.addEventListener("message", replaceStateInteraction, false);
  2514.  
  2515.     // listen to clicks on next episode button
  2516.     var nextEpisodeListener = function(e) {
  2517.       console.log('next Episode button clicked');
  2518.     }
  2519.  
  2520.     // listen to clicks for other episodes
  2521.     var otherEpisodeListener = function() {
  2522.         // console.log('listener triggered');
  2523.         // find() selects on all nested descendants, children() selects on children
  2524.         // if(jQuery(this).find('.can-play').length > 0) {
  2525.             console.log('other episode clicked!');
  2526.             otherEpisode = true;
  2527.         // }
  2528.     }
  2529.  
  2530.     jQuery('.button-nfplayerNextEpisode').click(nextEpisodeListener);
  2531.     jQuery(document).on('click', '.nfp-episode-preview.expanded.can-play', otherEpisodeListener);
  2532.  
  2533.     //////////////////////////////////////////////////////////////////////////
  2534.     // Main logic                                                           //
  2535.     //////////////////////////////////////////////////////////////////////////
  2536.  
  2537.     // the Netflix player be kept within this many milliseconds of our
  2538.     // internal representation for the playback time
  2539.     var maxTimeError = 2500;
  2540.     var maxFreezeTimeError = 1000;
  2541.  
  2542.     // configure sync from end
  2543.     var syncFromEnd = false;
  2544.     var updateSessionTarget = syncFromEnd ? 'updateSessionFromEnd' : 'updateSession';
  2545.  
  2546.     // replace permId with userId in userSettings and var permId;
  2547.     var permIdFix = true;
  2548.  
  2549.     // the session
  2550.     var sessionId = null;
  2551.     var lastKnownTime = null;
  2552.     var lastKnownTimeUpdatedAt = null;
  2553.     var ownerId = null;
  2554.     var state = null;
  2555.     var videoId = null;
  2556.     var videoDuration = null;
  2557.     var currentPage = window.location.href;
  2558.  
  2559.     // ping the server periodically to estimate round trip time and client-server time offset
  2560.     var roundTripTimeRecent = [];
  2561.     var roundTripTimeMedian = 0;
  2562.     var localTimeMinusServerTimeRecent = [];
  2563.     var localTimeMinusServerTimeMedian = 0;
  2564.     var ping = function() {
  2565.       return new Promise(function(resolve, reject) {
  2566.         var startTime = (new Date()).getTime();
  2567.         socket.emit('getServerTime', { version: version }, function(serverTime) {
  2568.           var now = new Date();
  2569.  
  2570.           // compute median round trip time
  2571.           shove(roundTripTimeRecent, now.getTime() - startTime, 5);
  2572.           roundTripTimeMedian = median(roundTripTimeRecent);
  2573.  
  2574.           // compute median client-server time offset
  2575.           shove(localTimeMinusServerTimeRecent, (now.getTime() - Math.round(roundTripTimeMedian / 2)) - (new Date(serverTime)).getTime(), 5);
  2576.           localTimeMinusServerTimeMedian = median(localTimeMinusServerTimeRecent);
  2577.           // console.log('localTime - server time median: ' + localTimeMinusServerTimeMedian);
  2578.           // console.log('roundTripTimeMedian: ' + roundTripTimeMedian);
  2579.  
  2580.           resolve();
  2581.         });
  2582.       });
  2583.     };
  2584.  
  2585.     // this function should be called periodically to ensure the Netflix
  2586.     // player matches our internal representation of the playback state
  2587.     var sync = function() {
  2588.       if (sessionId === null) {
  2589.         // console.log('sync promise resolved');
  2590.         return Promise.resolve();
  2591.       }
  2592.       if (state === 'paused') {
  2593.         var promise;
  2594.         if (getState() === 'paused') {
  2595.           promise = Promise.resolve();
  2596.         } else {
  2597.           promise = pause();
  2598.         }
  2599.         return promise.then(function() {
  2600.           if (Math.abs(lastKnownTime - getPlaybackPosition()) > maxTimeError) {
  2601.             // console.log('seek event while paused added to promiseChain due to local time exceeding server time');
  2602.             return seek(lastKnownTime)();
  2603.           }
  2604.         });
  2605.       } else {
  2606.         return delayUntil(function() {
  2607.           var syncDelayState = getState();
  2608.           // console.log('syncDelayState: ' + getState());
  2609.           var localTime = getPlaybackPosition() || "not defined";
  2610.           var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
  2611.           // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
  2612.           return getState() !== 'loading';
  2613.         }, Infinity)().then(function() {
  2614.           var localTime = getPlaybackPosition();
  2615.           var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
  2616.           if (Math.abs(localTime - serverTime) > maxTimeError) {
  2617.             // console.log('seek event added to promiseChain due to local time exceeding server time');
  2618.             return seek(serverTime)()
  2619.             .then(function() {
  2620.               // if(othersAreBuffering) {
  2621.               //    return freezeUntil(function() {
  2622.               //     return !othersAreBuffering;
  2623.               //    }, 3000)()
  2624.               // }
  2625.             })
  2626.             .then(function() {
  2627.               var localTime = getPlaybackPosition();
  2628.               var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
  2629.               if (localTime > serverTime && localTime <= serverTime + maxTimeError) {
  2630.                 return freeze(localTime - serverTime)();
  2631.               } else {
  2632.                 return play();
  2633.               }
  2634.             });
  2635.           } else {
  2636.             return play();
  2637.             // return Promise.resolve();
  2638.           }
  2639.         });
  2640.       }
  2641.     };
  2642.  
  2643.  
  2644.  
  2645.     // this is called when we need to send an update to the server
  2646.     // waitForChange is a boolean that indicates whether we should wait for
  2647.     // the Netflix player to update itself before we broadcast
  2648.  
  2649.     var logState = false;
  2650.     var oldState = getState();
  2651.     // console.log('oldState: ' + oldState);
  2652.     stateTimer = setInterval(function() {
  2653.         oldState = getState();
  2654.         if(logState) {
  2655.             // console.log('oldState: ' + oldState);
  2656.             var localTime = getPlaybackPosition() || "not defined";
  2657.             var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
  2658.             // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
  2659.         }
  2660.     }, 100);
  2661.  
  2662.     var broadcast = function(waitForChange) {
  2663.       return function() {
  2664.         console.log('broadcast called w taskInFlight: ' + tasksInFlight);
  2665.         var localTime = getPlaybackPosition() || "not defined";
  2666.         var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
  2667.         // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
  2668.  
  2669.         // wait for video player state to change
  2670.         var promise;
  2671.         if (waitForChange) {
  2672.           var oldPlaybackPosition = getPlaybackPosition();  // TODO: fix crazy errors related to errors getting thrown here between episodes (BIG BUG)
  2673.           // var oldState = getState();
  2674.           var lastState = getState();
  2675.           // console.log("broadcast state, playback: " + oldState + ", " + oldPlaybackPosition);
  2676.           promise = swallow(delayUntil(function() {
  2677.             var newPlaybackPosition = getPlaybackPosition();
  2678.             var newState = getState();
  2679.             // console.log("new broadcast state, playback: " + newState + ", " + newPlaybackPosition);
  2680.             return Math.abs(newPlaybackPosition - oldPlaybackPosition) >= 1500 || newState !== oldState || newState !== lastState;
  2681.           }, 2500))();
  2682.         } else {
  2683.           promise = Promise.resolve();
  2684.         }
  2685.  
  2686.         var alreadyUpdated = false;
  2687.         var bufferingState = false;
  2688.         return promise.then(delayUntil(function() {
  2689.  
  2690.           // get scrubber time
  2691.           var localTime = getPlaybackPosition();
  2692.           var scrubberHead = jQuery(jQuery('.scrubber-head')[0]);
  2693.           var scrubberTime = parseInt(scrubberHead.attr('aria-valuenow') * 1000);
  2694.  
  2695.           // var sessionIdString = sessionId ? sessionId : 'null';
  2696.           // console.log('showControls Start sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
  2697.           showControls(); // TODO: fix crazy errors related to errors getting thrown here between episodes (BIG BUG)
  2698.           // console.log('showControls End sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
  2699.  
  2700.           // what can i do about this
  2701.  
  2702.           var now = new Date();
  2703.           var newLastKnownTime = scrubberTime;
  2704.           var newLastKnownTimeRemaining = getDuration() - scrubberTime;
  2705.           var newLastKnownTimeUpdatedAt = new Date(now.getTime() - localTimeMinusServerTimeMedian);
  2706.           var newState = getState() === 'loading' ? 'paused' : (getState() === 'playing' ? 'playing' : 'paused');
  2707.  
  2708.           // console.log('currently buffering. current Time: ' + localTime + 'scrubber time: ' + scrubberTime);
  2709.  
  2710.           if(!alreadyUpdated) {
  2711.               bufferingState = getState() === 'loading';
  2712.               if(bufferingState) {
  2713.  
  2714.                 // broadcast start of buffering
  2715.                 alreadyUpdated = true;
  2716.                 socket.emit('buffering', { buffering: true }, function() {});
  2717.  
  2718.                 var time = new Date();
  2719.                 var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
  2720.                 // console.log('broadcast user seek: buffering start -> server' + timeStatus);
  2721.  
  2722.                 // send update video event
  2723.                 // console.log('updateSession -> socket connection' + timeStatus);
  2724.                 socket.emit(updateSessionTarget, {
  2725.                   lastKnownTime: newLastKnownTime,
  2726.                   lastKnownTimeUpdatedAt: newLastKnownTimeUpdatedAt.getTime(),
  2727.                   state: newState,
  2728.                   lastKnownTimeRemaining: newLastKnownTimeRemaining,
  2729.                   lastKnownTimeRemainingText: getRemainingTimeText(),
  2730.                   videoDuration: getDuration(),
  2731.                   bufferingState: bufferingState // change: bufferingState
  2732.                 }, function(data) {
  2733.                   if (data !== undefined && data.errorMessage !== null) {
  2734.                     lastKnownTime = oldLastKnownTime;
  2735.                     lastKnownTimeUpdatedAt = oldLastKnownTimeUpdatedAt;
  2736.                     state = oldState;
  2737.                     // reject();
  2738.                   } else {
  2739.                     // resolve();
  2740.                   }
  2741.                 });
  2742.               }
  2743.           }
  2744.           return getState() !== 'loading';
  2745.         }, Infinity)).then(function() {
  2746.  
  2747.           if(bufferingState) {
  2748.             var time = new Date();
  2749.             var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
  2750.             // console.log('broadcast user seek: buffering end -> server' + timeStatus);
  2751.             socket.emit('buffering', { buffering: false }, function() {});
  2752.           }
  2753.  
  2754.           var now = new Date();
  2755.           var localTime = getPlaybackPosition();
  2756.           var serverTime = lastKnownTime + (state === 'playing' ? (now.getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
  2757.           var newLastKnownTime = localTime;
  2758.           var newLastKnownTimeUpdatedAt = new Date(now.getTime() - localTimeMinusServerTimeMedian);
  2759.           var newState = getState() === 'playing' ? 'playing' : 'paused';
  2760.           if (state === newState && Math.abs(localTime - serverTime) < 1) {
  2761.             return Promise.resolve();
  2762.           } else {
  2763.             var oldLastKnownTime = lastKnownTime;
  2764.             var oldLastKnownTimeUpdatedAt = lastKnownTimeUpdatedAt;
  2765.             var oldState = state;
  2766.             lastKnownTime = newLastKnownTime;
  2767.             lastKnownTimeUpdatedAt = newLastKnownTimeUpdatedAt;
  2768.             state = newState;
  2769.             return new Promise(function(resolve, reject) {
  2770.               // console.log('updateSession -> socket connection');
  2771.               socket.emit(updateSessionTarget, {
  2772.                 lastKnownTime: newLastKnownTime,
  2773.                 lastKnownTimeUpdatedAt: newLastKnownTimeUpdatedAt.getTime(),
  2774.                 state: newState,
  2775.                 lastKnownTimeRemaining: getRemainingTime(),
  2776.                 lastKnownTimeRemainingText: getRemainingTimeText(),
  2777.                 videoDuration: getDuration(),
  2778.                 bufferingState: bufferingState
  2779.               }, function(data) {
  2780.                 if (data !== undefined && data.errorMessage !== null) {
  2781.                   lastKnownTime = oldLastKnownTime;
  2782.                   lastKnownTimeUpdatedAt = oldLastKnownTimeUpdatedAt;
  2783.                   state = oldState;
  2784.                   reject();
  2785.                 } else {
  2786.                   resolve();
  2787.                 }
  2788.               });
  2789.             });
  2790.           }
  2791.         }).then(function() {
  2792.           // wait when others are buffering
  2793.           // if(othersAreBuffering) {
  2794.           //    return freezeUntil(function() {
  2795.           //     return !othersAreBuffering;
  2796.           //    }, 3000)()
  2797.           // }
  2798.         });
  2799.       };
  2800.     };
  2801.  
  2802.     // this is called when data is received from the server
  2803.     var receive = function(data) {
  2804.       console.log("received data: " + JSON.stringify(data));
  2805.       // console.log("received data: " + getDuration());
  2806.  
  2807.       if(syncFromEnd) {
  2808.         // try to sync to local video duration - lastKnownTimeRemaining from server update
  2809.        
  2810.         // negative lastKnownTime -> do nothing
  2811.         if (getDuration() < data.lastKnownTimeRemaining) {
  2812.  
  2813.             // update
  2814.             pushTask(broadcast(false));
  2815.             return function() { return Promise.resolve(); }
  2816.         } else {
  2817.             lastKnownTime = getDuration() - data.lastKnownTimeRemaining;
  2818.         }
  2819.  
  2820.  
  2821.         // TODO: if negative last known time fix to send update to force everyone to get onto video        
  2822.       } else {
  2823.         // try to sync to lastKnownTime from server update
  2824.         lastKnownTime = data.lastKnownTime;
  2825.       }
  2826.  
  2827.       state = data.state;
  2828.       lastKnownTimeUpdatedAt = new Date(data.lastKnownTimeUpdatedAt);
  2829.       return sync;
  2830.     };
  2831.  
  2832.     // the following allows us to linearize all tasks in the program to avoid interference
  2833.     var tasks = null;
  2834.     var tasksInFlight = 0;
  2835.  
  2836.     var pushTask = function(task) {
  2837.       // console.log('pushTask called w tasksInFlight: ' + tasksInFlight);
  2838.       if (tasksInFlight === 0) {
  2839.         // why reset tasks here? in case the native promises implementation isn't
  2840.         // smart enough to garbage collect old completed tasks in the chain.
  2841.         tasks = Promise.resolve();
  2842.       }
  2843.       tasksInFlight += 1;
  2844.       tasks = tasks.then(function() {
  2845.         if (getState() === 'idle') {
  2846.           swallow(wakeUp)();
  2847.         }
  2848.       }).then(swallow(task)).then(function() {
  2849.         tasksInFlight -= 1;
  2850.       });
  2851.     };
  2852.  
  2853.     // returns true if a user action is on a next episode button
  2854.     var isNextEpisodeClick = function(target) {
  2855.       if(jQuery(target).hasClass('button-nfplayerNextEpisode')) {
  2856.           console.log('BUTTON NEXT EPISODE CLICK?:')
  2857.           return true;
  2858.        }
  2859.       // otherwise click on the autoplay next episode hover container (short episodes like Friends)
  2860.       else if (jQuery(target).hasClass('WatchNext-still-hover-container')) {
  2861.         console.log('HOVER NEXT EPISODE CLICK');
  2862.         return true;
  2863.        }
  2864.  
  2865.       else if (jQuery(target).hasClass('PlayIcon')) {
  2866.         console.log('HOVER NEXT EPISODE CLICK');
  2867.         return true;
  2868.        }
  2869.  
  2870.        // click on the next episode button (in the middle of episodes)
  2871.       else if (jQuery(target).hasClass('button-nfplayerNextEpisode').length > 0) {
  2872.         // jQuery('.button-nfplayerNextEpisode').click()
  2873.         return true;
  2874.        }
  2875.       // otherwise click on the credits next episode button (before AND after credits on long episodes like Umbrella Academy)
  2876.       else if (jQuery(target).hasClass('nf-flat-button-text')) {
  2877.         console.log('CREDITS NEXT EPISODE CLICK?:' + jQuery(target).text());
  2878.  
  2879.         if(jQuery(target).text().toLowerCase().includes('next episode')) {
  2880.           return true;
  2881.           // jQuery('.nf-flat-button-text')[0].click();
  2882.           // console.log('after credits click');
  2883.         }
  2884.       } else {
  2885.         return false;
  2886.       }
  2887.     }
  2888.  
  2889.     var mouseupListener = function() {
  2890.       console.log("mouseup");
  2891.       // console.log(jQuery(event.target).attr('class'));
  2892.       // console.log(jQuery(event.target).text());
  2893.       // console.log(jQuery(event.target).hasClass('button-nfplayerNextEpisode'));
  2894.  
  2895.       if(!isNextEpisodeClick(event.target)) {
  2896.           var sessionIdString = sessionId ? sessionId : 'null';
  2897.           console.log('sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
  2898.           if (sessionId !== null && uiEventsHappening === 0) {
  2899.             pushTask(function() {
  2900.               return broadcast(true)().catch(sync);
  2901.             });
  2902.           }
  2903.       } else {
  2904.  
  2905.         console.log("sessionid disabled");
  2906.         setSessionEnabled(false);
  2907.         // oldSessionId = sessionId;
  2908.         // sessionId = null;
  2909.  
  2910.  
  2911.         // lastKnownTime = null;
  2912.         // lastKnownTimeUpdatedAt = null;
  2913.         // var ownerId = null;
  2914.         // state = null;
  2915.       }
  2916.       interactionsCount += 1;
  2917.     }
  2918.  
  2919.     var keyupListener = function(e) {
  2920.       // e.stopPropagation();
  2921.       console.log("keyup");
  2922.       // console.log(event.target.className);
  2923.       // if(jQuery(event.target).hasClass('nfp')) {
  2924.           if (sessionId !== null && uiEventsHappening === 0) {
  2925.             pushTask(function() {
  2926.               return broadcast(true)().catch(sync);
  2927.             });
  2928.           }
  2929.       // }
  2930.     }
  2931.  
  2932.     // broadcast the playback state if there is any user activity
  2933.     jQuery(window).mouseup(mouseupListener);
  2934.     jQuery(window).keyup(keyupListener);
  2935.  
  2936.     var scriptInterval = null;
  2937.     var teardown = function() {
  2938.         window.postMessage({ type: "teardown"}, "*");
  2939.         window.removeEventListener("message", replaceStateInteraction, false);
  2940.         window.removeEventListener("unload", unloadInteraction , true);
  2941.         jQuery(window).off('mouseup', mouseupListener);
  2942.         jQuery(window).off('keyup', keyupListener);
  2943.  
  2944.         if(sessionId) sessionId = null;
  2945.         window.netflixPartyLoaded = false;
  2946.         chrome.runtime.onMessage.removeListener(popupInteraction);
  2947.         if(socket) socket.disconnect();
  2948.         if(scriptInterval) clearInterval(scriptInterval);
  2949.         setChatVisible(false);
  2950.         removeChat();
  2951.         window.netflixpartyLoaded = false;
  2952.         logState = false;
  2953.     }
  2954.  
  2955.     socket.on('connect', function() {
  2956.       pushTask(ping);
  2957.       console.log(currentPage);
  2958.       var lastTime = new Date();
  2959.       scriptInterval = setInterval(function() {
  2960.         if (tasksInFlight === 0) {
  2961.           var newTime = new Date();
  2962.           // console.log("ping sync: " + (newTime - lastTime));
  2963.           lastTime = new Date();
  2964.           pushTask(ping);
  2965.           pushTask(sync);
  2966.         }
  2967.       }, 5000);
  2968.     });
  2969.  
  2970.     // if the server goes down, it can reconstruct the session with this
  2971.     socket.on('reconnect', function() {
  2972.       if (sessionId !== null) {
  2973.         socket.emit('reboot', {
  2974.           sessionId: sessionId,
  2975.           lastKnownTime: lastKnownTime,
  2976.           lastKnownTimeUpdatedAt: lastKnownTimeUpdatedAt.getTime(),
  2977.           messages: messages,
  2978.           state: state,
  2979.           ownerId: ownerId,
  2980.           userId: userId,
  2981.           videoId: videoId,
  2982.           videoDuration: getDuration(), //change: sending over video duration
  2983.           permId: permId, //change: sending over permId
  2984.           userSettings: userSettings,
  2985.           videoService: 'netflix'
  2986.         }, function(data) {
  2987.           pushTask(receive(data));
  2988.         });
  2989.       }
  2990.     });
  2991.  
  2992.     // respond to updates from the server
  2993.     socket.on('update', function(data) {
  2994.       // console.log('***********************************');
  2995.       // console.log('on server update:' + JSON.stringify(data));
  2996.       pushTask(receive(data));
  2997.     });
  2998.  
  2999.     // interaction with the popup
  3000.     var popupInteraction = function(request, sender, sendResponse) {
  3001.       if (request.type === 'getInitData') {
  3002.         version = request.data.version;
  3003.        
  3004.         // fix bug where urls redirect to title page sometimes
  3005.         var parseIds = window.location.href.match(/^.*\/([0-9]+)\??.*/);
  3006.         var currVideoId = parseIds.length !== 0 ? parseInt(window.location.href.match(/^.*\/([0-9]+)\??.*/)[1]) : null;
  3007.         var videoDomId = (typeof jQuery("video").parent()[0] !== "undefined") ? parseInt(jQuery("video").parent()[0].id) : null;
  3008.         if((videoDomId != null) && (videoDomId != currVideoId)) {
  3009.             history.replaceState('data to be passed', 'Title of the page', '/watch/' + jQuery(jQuery("video").parent())[0].id);
  3010.         }
  3011.  
  3012.         sendResponse({
  3013.           sessionId: sessionId,
  3014.           defaultServer: defaultServer,
  3015.           chatVisible: getChatVisible()
  3016.         });
  3017.         return;
  3018.       }
  3019.  
  3020.       // TODO: edit for optional create session data
  3021.       if (request.type === 'createSession') {
  3022.         waitUserIdReady()().then(function() {
  3023.             console.log('create session permId: ' + permId);
  3024.             console.log('create session permId: ' + JSON.stringify(userSettings));
  3025.             socket.emit('createSession', {
  3026.               controlLock: request.data.controlLock,
  3027.               videoId: request.data.videoId,
  3028.               videoService: 'netflix',
  3029.               syncFromEnd: syncFromEnd, //change: sending over syncFromEnd
  3030.               videoDuration: getDuration(), //change: sending over video duration
  3031.               permId: permId, //change: sending over permId
  3032.               userSettings: userSettings // change: add userSettings here
  3033.             }, function(data) {
  3034.               initChat();
  3035.               // getChromeStorage()().then(initChat);
  3036.               setChatVisible(true);
  3037.               lastKnownTime = data.lastKnownTime;
  3038.               lastKnownTimeUpdatedAt = new Date(data.lastKnownTimeUpdatedAt);
  3039.               messages = [];
  3040.               sessionId = data.sessionId;
  3041.               ownerId = request.data.controlLock ? userId : null;
  3042.               state = data.state;
  3043.               videoId = request.data.videoId;
  3044.               videoDuration = getDuration();
  3045.               pushTask(broadcast(false));
  3046.  
  3047.               // summary state
  3048.               sessionStartTime = new Date();
  3049.  
  3050.               // console.log('defaultServer create: ' + defaultServer);
  3051.  
  3052.               sendResponse({
  3053.                 sessionId: sessionId,
  3054.                 defaultServer: defaultServer
  3055.               });
  3056.             });
  3057.         })
  3058.         return true;
  3059.       }
  3060.  
  3061.       if (request.type === 'joinSession') { /* change: add permId here. before: socket.emit('joinSession', request.data.sessionId, function(data) {  */
  3062.         waitUserIdReady()().then(function() {
  3063.             var joinData = herokuSocket ? request.data.sessionId : {sessionId: request.data.sessionId, permId: permId, userSettings: userSettings} /* change: add usersettings here */
  3064.             socket.emit('joinSession', joinData, function(data) {
  3065.               if (data.errorMessage) {
  3066.                 sendResponse({
  3067.                   errorMessage: data.errorMessage
  3068.                 });
  3069.                 return;
  3070.               }
  3071.  
  3072.               if (data.videoId !== request.data.videoId) {
  3073.                 socket.emit('leaveSession', null, function(data) {
  3074.                   sendResponse({
  3075.                     errorMessage: 'That session is for a different video.'
  3076.                   });
  3077.                 });
  3078.                 return;
  3079.               }
  3080.  
  3081.               initChat();
  3082.               // getChromeStorage()().then(initChat);
  3083.               setChatVisible(true);
  3084.               sessionId = request.data.sessionId;
  3085.               lastKnownTime = data.lastKnownTime;
  3086.  
  3087.               syncFromEnd = data.syncFromEnd ? data.syncFromEnd : false;
  3088.               updateSessionTarget = syncFromEnd ? 'updateSessionFromEnd' : 'updateSession';
  3089.               if(syncFromEnd) {
  3090.                 lastKnownTime = getDuration() - data.lastKnownTimeReamining;
  3091.               }
  3092.  
  3093.               lastKnownTimeUpdatedAt = new Date(data.lastKnownTimeUpdatedAt);
  3094.               messages = [];
  3095.               for (var i = 0; i < data.messages.length; i += 1) {
  3096.                 addMessage(data.messages[i]);
  3097.               }
  3098.               ownerId = data.ownerId;
  3099.               state = data.state;
  3100.               videoId = request.data.videoId;
  3101.               videoDuration = getDuration();
  3102.               pushTask(receive(data));
  3103.               sendResponse({});
  3104.             });
  3105.         })
  3106.         return true;
  3107.       }
  3108.  
  3109.       if (request.type === 'leaveSession') {
  3110.         socket.emit('leaveSession', null, function(_) {
  3111.           logSummary();
  3112.           sessionId = null;
  3113.           setChatVisible(false);
  3114.           sendResponse({});
  3115.         });
  3116.         return true;
  3117.       }
  3118.  
  3119.       if (request.type === 'showChat') {
  3120.         // console.log('showChat');
  3121.         if (request.data.visible) {
  3122.           setChatVisible(true);
  3123.         } else {
  3124.           setChatVisible(false);
  3125.         }
  3126.         sendResponse({});
  3127.       }
  3128.     } // end of popup interaciton
  3129.     //
  3130.  
  3131.     // getChromeStorage()()
  3132.     // getChromeStorage()()
  3133.     // getUserIdPromise()
  3134.     // waitUserIdReady()()
  3135.     getUserIdPromise()
  3136.     .then(getChromeStorage())
  3137.     .then(setHTML)
  3138.     .then(chrome.runtime.onMessage.addListener(popupInteraction));
  3139.   }
  3140. };
  3141.  
  3142.  
  3143. console.log('inject content script after this');
  3144.  
  3145. // check that server data includes valid server settings
  3146. // function validateServers(serverJsonString) {
  3147. //  var validated = false;
  3148.    
  3149. //  try {
  3150. //      serverJson = JSON.parse(serverJsonString);
  3151. //      console.log('this is called');
  3152. //      var jsonCheck = (typeof serverJson === 'object') && ((serverJson.defaultServerOptions || serverJson.servers) != undefined);
  3153. //      var optionsCheck
  3154. //      if(jsonCheck) {
  3155. //          if(serverJson.defaultServerOptions) {
  3156. //              var optionsCheck = Array.isArray(serverJson.defaultServerOptions);
  3157. //              jsonCheck = jsonCheck && optionsCheck;
  3158. //          }
  3159. //          if(serverJson.servers) {
  3160. //              var serversCheck = typeof serverJson.servers === 'object';
  3161. //              jsonCheck = jsonCheck && serversCheck;
  3162. //          }
  3163. //      }
  3164. //      return jsonCheck;
  3165. //  } catch {
  3166. //      return false;
  3167. //  }
  3168. //  return true;
  3169. // }
  3170.  
  3171. // // Get default server settings from config server, if not available fall back to hardcoded settings
  3172. // // switching to self-hosting config since s3 gets throttled
  3173. // if(!window.getServerSettings) {
  3174. //  window.getServerSettings = true;
  3175. //  console.log(window.getServerSettings);
  3176.  
  3177.  
  3178. //     var xhr = new XMLHttpRequest();
  3179.  
  3180. //    xhr.onreadystatechange = function() {
  3181. //      if (this.readyState == 4) {
  3182. //        if(this.status == 200) {
  3183. //            // document.getElementById("demo").innerHTML = this.responseText;
  3184. //            if(validateServers(xhr.responseText)) {
  3185. //                console.log('validate servers returned true');
  3186. //                console.log('optionsConfig:' + JSON.stringify(optionsConfig));
  3187.  
  3188.  
  3189.  
  3190. //                var serverSettings = JSON.parse(xhr.responseText);
  3191. //                var injectOptions = serverSettings.defaultServerOptions ? serverSettings.defaultServerOptions : optionsConfig;
  3192. //                var injectServers = serverSettings.servers ? serverSettings.servers : serversConfig;
  3193. //                injectContentScript(injectOptions, injectServers);
  3194. //                // console.log('serverSettings:' + JSON.stringify(serverSettings.defaultServerOptions));
  3195.  
  3196. //            } else {
  3197. //              injectContentScript();
  3198. //            }
  3199. //        } else {
  3200. //          injectContentScript();
  3201. //        }
  3202. //      }
  3203. //    };
  3204.  
  3205. //      xhr.onerror = function(e) {
  3206. //          console.log('error found');
  3207. //          injectContentScript();
  3208. //      };
  3209.  
  3210. //      xhr.open('GET', 'https://netflixparty.s3.amazonaws.com/serverSettings.json', true);
  3211. //      xhr.send(null);
  3212. // }
  3213. // setTimeout(function(){ injectContentScript()}, 1000);
  3214.  
  3215. injectContentScript();
Add Comment
Please, Sign In to add comment