{"version":3,"file":"bundle.js","sources":["../node_modules/browserify/node_modules/browser-pack/_prelude.js","../lib/index.js","../lib/connectors/core/HandshakeConnector.js","../lib/WebP2P.js","../node_modules/browserify/node_modules/process/browser.js","../lib/managers/HandshakeManager.js","../lib/managers/PeersManager.js","../lib/packer.js","../lib/connectors/core/Connector.js","../node_modules/browserify/node_modules/events/events.js","../lib/managers/Manager.js","../lib/errors.js","../lib/connectors/PubNub.js","../lib/connectors/xRTML.js","../lib/connectors/core/DataChannel.js","../node_modules/inherits/inherits_browser.js","../node_modules/freeice/index.js","../node_modules/uuid/uuid.js","../node_modules/wrtc/lib/browser.js","../node_modules/process-events-shim/lib/process-events-shim.js","../node_modules/rpc-builder/lib/index.js","../shim/pubnub.js","../node_modules/freeice/servers.js","../node_modules/uuid/rng-browser.js","../node_modules/browserify/node_modules/buffer/index.js","../node_modules/rpc-builder/lib/Mapper.js","../node_modules/rpc-builder/lib/packers/index.js","../node_modules/rpc-builder/lib/packers/JsonRPC.js","../node_modules/rpc-builder/lib/packers/XmlRPC.js","../node_modules/ibtrealtimesjnode/index.js","../node_modules/browserify/node_modules/buffer/node_modules/ieee754/index.js","../node_modules/browserify/node_modules/buffer/node_modules/base64-js/lib/b64.js","../node_modules/ibtrealtimesjnode/IbtRealTimeSJNode.js","../node_modules/ibtrealtimesjnode/http-request.js","../node_modules/ibtrealtimesjnode/strings.js","../node_modules/ibtrealtimesjnode/object-literals.js","../node_modules/ibtrealtimesjnode/IbtRealtimeRestServices.js","../node_modules/browserify/node_modules/url/url.js","../node_modules/browserify/node_modules/path-browserify/index.js","../node_modules/ibtrealtimesjnode/math.js","../node_modules/browserify/node_modules/querystring-es3/index.js","../node_modules/browserify/node_modules/util/util.js","../node_modules/ibtrealtimesjnode/node_modules/ws/lib/browser.js","../node_modules/browserify/node_modules/punycode/punycode.js","../node_modules/browserify/node_modules/querystring-es3/encode.js","../node_modules/browserify/node_modules/util/support/isBufferBrowser.js","../node_modules/browserify/node_modules/querystring-es3/decode.js"],"names":["HandshakeConnector","require","WebP2P","module","exports","max_connections","Connector","call","this","self","undefined","Math","min","shouldConnect","connections","increaseConnections","close","inherits","prototype","Number","POSITIVE_INFINITY","noop","error","console","options","onerror","emit","Error","createPeerConnection","sessionID","callbackType","callback","pc","RTCPeerConnection","iceServers","optional","DtlsSrtpKeyAgreement","addEventListener","event","candidate","type","localDescription","sdp","signalingState","channels","_channels","peersManager","add","offer","offers","Object","defineProperty","value","forward","message","connector","dest","from","ttl","warn","pack","peer","i","_connectors","send","handshakeManager","connectionProcessed","get","log","code","MAX_TTL_DEFAULT","rpcBuilder","cancel","peerConnection","debug","onpresence","generateOffer","onoffer","request","processed","reply","answer","response","setRemoteDescription","RTCSessionDescription","createAnswer","setLocalDescription","channel","push","labels","encode","result","processAnswer","Array","forEach","c","routingLabel","concat","commonLabels","label","createDataChannel","splice","indexOf","mediaConstraints","mandatory","OfferToReceiveAudio","OfferToReceiveVideo","createOffer","initManagerEvents","manager","on","status","handshake_servers","freeice","uuid","v4","max_retries","peerID","RpcBuilder","packer","HandshakeManager","PeersManager","__defineGetter__","peers","connectTo","Function","SyntaxError","process","EventEmitter","wrtc","nextTick","canSetImmediate","window","setImmediate","canPost","postMessage","f","queue","ev","source","data","stopPropagation","length","fn","shift","setTimeout","title","browser","env","argv","addListener","once","off","removeListener","removeAllListeners","binding","cwd","chdir","createConnector","config","config_init","config_mess","connectorConstructor","handshakeConnectorConstructors","_initConnector","_messageUnpacked","method","params","handshake","configs","index","Manager","registerConnectorConstructor","constructor","Connector_PubNub","Connector_xRTML","configs_infinity","addConfigs_byObject","addConfigs","errors","configuration","addConfigs_byUri","addConfigs_byArray","json_uri","dispatchError","http_request","XMLHttpRequest","open","onload","JSON","parse","ERROR_REQUEST_EMPTY","ERROR_REQUEST_FAILURE","navigator","onLine","ERROR_NETWORK_UNKNOWN","ERROR_NETWORK_OFFLINE","Connector_DataChannel","initDataChannel","initDataChannel_listener","target","removeEventListener","_close","id","ERROR","PRESENCE","OFFER","ANSWER","stringify","unpack","ack","responseMethods","presence","_open","_message","_error","TypeError","_events","_maxListeners","isFunction","arg","isNumber","isObject","isUndefined","defaultMaxListeners","setMaxListeners","n","isNaN","er","handler","len","args","listeners","arguments","apply","slice","listener","m","newListener","warned","trace","g","fired","list","position","key","ret","listenerCount","emitter","decode","stored","incomingConnector","msg","ERROR_NO_PEERS","pubnub","PUBNUB","init","subscribe","restore","backfill","connect","disconnect","unsubscribe","publish","ortcClient","ortcNodeclient","setClusterUrl","onConnected","ortc","onSubscribed","bind","onUnsubscribed","onException","exception","application_key","authentication_token","IbtRealTimeSJNode","datachannel","create","ctor","superCtor","super_","enumerable","writable","configurable","TempCtor","opts","getServers","count","idx","out","input","servers","random","map","url","selected","stunCount","stun","turnCount","turn","s","buf","offset","ii","toLowerCase","replace","oct","_hexToByte","unparse","bth","_byteToHex","v1","b","clockseq","_clockseq","msecs","Date","getTime","nsecs","_lastNSecs","dt","_lastMSecs","tl","tmh","node","_nodeId","BufferClass","rnds","rng","_rng","Buffer","toString","substr","_seedBytes","RTCIceCandidate","mozRTCIceCandidate","webkitRTCIceCandidate","mozRTCPeerConnection","webkitRTCPeerConnection","mozRTCSessionDescription","webkitRTCSessionDescription","name","processLacksEventFunctions","_ref","document","global","err","line","unifyResponseMethods","unifyTransport","transport","RpcNotification","storeResponse","timeout","responses","remove","response_timeout","set","storeProcessedResponse","processedResponses","duplicates_timeout","RpcRequest","Boolean","responseMethod","clearTimeout","message2Key","requests","pop","request_timeout","BASE_TIMEOUT","requestID","Mapper","dispatchCallback","sendRequest","pow","retried","encode_transport","retry","processRequest","idAck","processResponse","duplicatedResponse","packers","unique","NOW","rnow","build_url","url_components","url_params","join","URLBIT","each","value_str","PARAMSBIT","updater","fun","rate","last","runnit","grep","fin","l","supplant","str","values","REPL","_","match","wait","u","r","v","isArray","o","hasOwnProperty","k","path","encodeURIComponent","generate_channel_list","nopresence","search","subscribed","sort","ready","READY","READY_BUFFER","SECOND","PN_API","setup","_get_url_params","_object_to_key_list","_object_to_key_list_sorted","_get_pam_sign_input_from_params","si","validate_presence_heartbeat","heartbeat","cur_heartbeat","PRESENCE_HB_THRESHOLD","PRESENCE_HB_DEFAULT","encrypt","crypto_obj","CIPHER_KEY","decrypt","_presence_heartbeat","PRESENCE_HB_TIMEOUT","PRESENCE_HB_INTERVAL","CHANNELS","PRESENCE_HB_RUNNING","SELF","e","start_presence_heartbeat","next","NO_WAIT_FOR_PENDING","PUB_QUEUE","sending","xdr","each_channel","chan","_invoke_callback","payload","_invoke_error","_poll_online","_is_online","_reset_offline","_poll_online2","success","detect_time_detla","KEEPALIVE","SUB_RECEIVER","detect_latency","tt","adjusted_time","TIME_DRIFT","cb","time","calculate","ptime","latency","stime","SUB_WINDOWING","DEF_WINDOWING","SUB_TIMEOUT","DEF_SUB_TIMEOUT","DEF_KEEPALIVE","NOLEAVE","PUBLISH_KEY","SUBSCRIBE_KEY","AUTH_KEY","SECRET_KEY","hmac_SHA256","SSL","ORIGIN","STD_ORIGIN","nextorigin","SUB_ORIGIN","CONNECT","SUB_CALLBACK","SUB_CHANNEL","SUB_RESTORE","TIMETOKEN","RESUMED","STATE","PRESENCE_HB","COMPATIBLE_35","jsonp_cb","db","UUID","a","LEAVE","blocking","auth","origin","jsonp","PRESENCE_SUFFIX","fail","set_resumed","resumed","get_cipher_key","set_cipher_key","raw_encrypt","raw_decrypt","get_heartbeat","set_heartbeat","get_heartbeat_interval","set_heartbeat_interval","heartbeat_interval","get_version","SDK_VER","_add_param","val","history","reverse","auth_key","cipher_key","start","end","include_token","messages","decrypted_messages","new_message","replay","destination","stop","limit","post","add_msg","mode","split","CB_CALLED","action","_test_connection","disconnected","reconnect","_connect","st","sub_timeout","errcb","idlecb","connected","windowing","next_callback","decrypted_msg","noheresync","timetoken","state","settings","here","uid","timestamp","occupancy","here_now","uuids","where_now","grant","w","floor","sign_input","signature","audit","revoke","set_uuid","get_uuid","presence_heartbeat","each-channel","offline","now","SHA256","safe_add","x","y","lsw","msw","S","X","R","Ch","z","Maj","Sigma0256","Sigma1256","Gamma0256","Gamma1256","core_sha256","d","h","j","T1","T2","K","HASH","W","str2binb","bin","mask","chrsz","charCodeAt","Utf8Encode","string","utftext","String","fromCharCode","binb2hex","binarray","hex_tab","hexcase","charAt","crypto","CRYPTO","iv","hex_message","encryptedHexArray","base_64_encrypted","binary_enc","json_plain","plaintext","DEF_TIMEOUT","max","ori","failover","Nr","Nk","Decrypt","enc_utf8","unescape","dec_utf8","decodeURIComponent","escape","padBlock","byteArr","cpad","array","block2s","block","lastBlock","padding","a2h","numArr","h2a","parseInt","s2a","binary","size","newsize","randArr","num","openSSLKey","passwordArr","saltArr","rounds","md5_hash","data00","GibberishAES","Hash","MD5","rawEncrypt","expandKey","numBlocks","ceil","blocks","cipherBlocks","xorBlocks","encryptBlock","rawDecrypt","cryptArr","plainBlocks","decryptBlock","words","round","addRoundKey","subBytes","shiftRows","mixColumns","SBoxInv","SBox","temp","shiftBy","t","GEX","GBX","GDX","G9X","G2X","G3X","block1","block2","flat","subWord","rotWord","Rcon","tmp","strhex","invertArr","arr","Gxx","Gx","enc","pass","salt","pbe","saltBlock","Base64","dec","rotateLeft","lValue","iShiftBits","addUnsigned","lX","lY","lX4","lY4","lX8","lY8","lResult","funcI","ff","ac","gg","hh","convertToWordArray","lWordCount","lMessageLength","lNumberOfWords_temp1","lNumberOfWords_temp2","lNumberOfWords","lWordArray","lBytePosition","lByteCount","wordToHex","lByte","lCount","wordToHexArr","AA","BB","CC","DD","rnd","_chars","chars","broken_b64","flatArr","b64","xhr","finished","loaded","timer","responseText","done","complete","XHRTME","async","failed","abort","XDomainRequest","onabort","onloadend","onreadystatechange","readyState","PNSDK","eee","el","etype","rapfun","cancelBubble","returnValue","preventDefault","attachEvent","attr","attribute","setAttribute","getAttribute","$","getElementById","elements","getElementsByTagName","css","element","styles","style","createElement","get_hmac_SHA256","hash","CryptoJS","CREATE_PUBNUB","pnsdk","PN","prop","ch","ls","localStorage","getItem","cookie","RegExp","setItem","WS","protocols","bits","protocol","ssl","publish_key","subscribe_key","reason","wasClean","getRandomValues","_rnds8","Uint8Array","_rnds","subject","encoding","noZero","stringtrim","coerce","byteLength","_useTypedArrays","_augment","_isBuffer","_set","isArrayish","isBuffer","readUInt8","writeInt8","write","hexWrite","remaining","strLen","assert","byte","utf8Write","charsWritten","blitBuffer","utf8ToBytes","asciiWrite","asciiToBytes","binaryWrite","base64Write","base64ToBytes","utf16leWrite","utf16leToBytes","base64Slice","base64","fromByteArray","utf8Slice","res","decodeUtf8Char","asciiSlice","binarySlice","hexSlice","toHex","utf16leSlice","bytes","readUInt16","littleEndian","noAssert","readUInt32","readInt16","neg","readInt32","readFloat","ieee754","read","readDouble","writeUInt16","verifuint","writeUInt32","writeInt16","verifsint","writeInt32","writeFloat","verifIEEE754","writeDouble","trim","clamp","defaultValue","byteArray","hi","lo","toByteArray","src","dst","test","SlowBuffer","INSPECT_MAX_BYTES","poolSize","ArrayBuffer","foo","subarray","isEncoding","totalLength","pos","item","copy","compare","isFinite","swap","toJSON","_arr","equals","target_start","sliceLen","newBuf","writeUInt8","readUInt16LE","readUInt16BE","readUInt32LE","readUInt32BE","readInt8","readInt16LE","readInt16BE","readInt32LE","readInt32BE","readFloatLE","readFloatBE","readDoubleLE","readDoubleBE","writeUInt16LE","writeUInt16BE","writeUInt32LE","writeUInt32BE","writeInt16LE","writeInt16BE","writeInt32LE","writeInt32BE","writeFloatLE","writeFloatBE","writeDoubleLE","writeDoubleBE","fill","inspect","toArrayBuffer","buffer","BP","_get","toLocaleString","sources","key2","ids","keys","JsonRPC","XmlRPC","jsonrpc","version","result_defined","error_defined","isLE","mLen","nBytes","eLen","eMax","eBias","nBits","NaN","Infinity","rt","abs","LN2","lookup","elt","PLUS","SLASH","NUMBER","UPPER","LOWER","b64ToByteArray","L","placeHolders","Arr","uint8ToBase64","uint8","tripletToBase64","extraBytes","output","clusterUrl","connectionTimeout","messageMaxSize","channelMaxSize","messagesBuffer","isConnected","isConnecting","alreadyConnectedFirstTime","stopReconnecting","sockjs","userPerms","connectionMetadata","announcementSubChannel","subscribedChannels","lastKeepAlive","invalidConnection","reconnectStartedAt","connectionMetadataMaxSize","getId","setId","newId","getUrl","setUrl","newUrl","getClusterUrl","getConnectionTimeout","setConnectionTimeout","newTimeout","getIsConnected","getConnectionMetadata","setConnectionMetadata","newConnectionMetadata","getAnnouncementSubChannel","setAnnouncementSubChannel","newAnnouncementSubChannel","onDisconnected","onReconnecting","onReconnected","appKey","authToken","delegateExceptionCallback","ortcIsValidUrl","ortcIsValidInput","ortcTreatUrl","clusterConnection","createSocketConnection","reconnectTimeoutlId","reconnectSocket","subscribeOnReconnected","onMessageCallback","isSubscribing","isSubscribed","ortcIsValidBoolean","ortcIsFunction","domainChannelCharacterIndex","channelToValidate","hashPerm","substring","ortcIsString","messageParts","messageId","generateId","allowedMaxSize","messageToSend","sendMultiPartMessage","sendProxy","applicationKey","privateKey","clearReconnectInterval","disconnectSocket","saveAuthentication","isCluster","authenticationToken","authenticationTokenIsPrivate","timeToLive","permissions","connectionUrl","getServerFromCluster","clusterUri","body","IbtRealtimeRestServices","parameters","requestUrl","getServerUrl","serverUrl","getPresence","enablePresence","metadata","disablePresence","resultUrl","reconnectIntervalId","clearInterval","exec","S4","clusterTimeout","delegateReconnectingCallback","queryString","parsedUrl","urlParser","httpRequest","hostname","pathname","query","responseData","content","wsScheme","wsUrl","connid","strings","random_string","serverId","random_number_string","WebSocket","onopen","onclose","delegateDisconnectedCallback","onmessage","messageType","op","up","channelsToRemove","chnKey","ObjectLiterals","removeEntry","delegateReconnectedCallback","delegateConnectedCallback","setInterval","channelSubscribed","delegateSubscribedCallback","channelUnsubscribed","delegateUnsubscribedCallback","ex","operation","regexPattern","messageCurrentPart","messageTotalPart","lastPart","delegateMessagesCallback","fs","querystring","postData","postContent","headers","host","port","content-length","content-type","httpClient","statusCode","chunk","getData","getParameters","requestPath","user-agent","util","math","strg","ws","generateGuid","random_string_chars","p","random_number","obj","urlApi","channelPermissions","Read","Write","Presence","saveAuthenticationData","AT","PVT","AK","TTL","PK","TP","permission","saveAuthenticationRequest","enableParameters","privatekey","enablePresenceRequest","disablePresenceRequest","postOptions","headerIndex","secure","getOptions","Url","slashes","href","urlParse","parseQueryString","slashesDenoteHost","urlFormat","isString","format","urlResolve","relative","resolve","urlResolveObject","resolveObject","isNull","isNullOrUndefined","punycode","protocolPattern","portPattern","delims","unwise","autoEscape","nonHostChars","hostEndingChars","hostnameMaxLen","hostnamePartPattern","hostnamePartStart","unsafeProtocol","javascript","javascript:","hostlessProtocol","slashedProtocol","http","https","ftp","gopher","file","http:","https:","ftp:","gopher:","file:","rest","proto","lowerProto","hostEnd","hec","atSign","lastIndexOf","parseHost","ipv6Hostname","hostparts","part","newpart","validParts","notHost","bit","unshift","domainArray","newOut","ae","esc","qm","rel","relPath","isSourceAbs","isRelAbs","mustEndAbs","removeAllDots","srcPath","psychotic","authInHost","hasTrailingSlash","isAbsolute","normalizeArray","parts","allowAboveRoot","filter","xs","splitPathRe","splitPath","filename","resolvedPath","resolvedAbsolute","normalize","trailingSlash","paths","to","fromParts","toParts","samePartsLength","outputParts","sep","delimiter","dirname","root","dir","basename","ext","extname","roundNumber","ctx","seen","stylize","stylizeNoColor","depth","colors","isBoolean","showHidden","_extend","customInspect","stylizeWithColor","formatValue","styleType","arrayToHash","recurseTimes","primitive","formatPrimitive","visibleKeys","getOwnPropertyNames","isError","formatError","isRegExp","isDate","base","braces","toUTCString","formatArray","formatProperty","reduceToSingleString","simple","desc","getOwnPropertyDescriptor","numLinesEst","reduce","prev","cur","ar","isSymbol","re","objectToString","isPrimitive","pad","getHours","getMinutes","getSeconds","getDate","months","getMonth","formatRegExp","objects","deprecate","deprecated","throwDeprecation","traceDeprecation","noDeprecation","debugs","debugEnviron","debuglog","NODE_DEBUG","toUpperCase","pid","bold","italic","underline","inverse","white","grey","black","blue","cyan","green","magenta","red","yellow","special","number","boolean","null","date","regexp","uri","instance","MozWebSocket","RangeError","mapDomain","regexSeparators","ucs2decode","extra","counter","ucs2encode","stringFromCharCode","basicToDigit","codePoint","digitToBasic","digit","flag","adapt","delta","numPoints","firstTime","damp","baseMinusTMin","tMax","skew","basic","oldi","baseMinusT","inputLength","initialN","bias","initialBias","maxInt","tMin","handledCPCount","basicLength","q","currentValue","handledCPCountPlusOne","qMinusT","toUnicode","domain","regexPunycode","toASCII","regexNonASCII","freeExports","freeModule","freeGlobal","overflow","not-basic","invalid-input","ucs2","define","amd","nodeType","stringifyPrimitive","eq","objectKeys","ks","qs","maxKeys","kstr","vstr"],"mappings":"AAAA;AGuBA,QAASqB,MAAKC,GAETA,GAAOC,QAAQD,MAAMA,GAU1B,QAASpB,QAAOsB,GAgDd,QAASC,GAAQH,GAEfb,EAAKiB,KAAK,QAAS,GAAIC,OAAML,IAY/B,QAASM,GAAqBC,EAAWC,EAAcC,GAErD,GAAIC,GAAK,GAAIC,oBAEVC,WAAYA,IACZC,WAAYC,sBAAsB,KA0CrC,OAvCAJ,GAAGK,iBAAiB,eAAgB,SAASC,GAG3C,IAAGA,EAAMC,UAAT,CAGA,GAAIC,GAAOhC,KAAKiC,iBAAiBD,KAC7BE,EAAOlC,KAAKiC,iBAAiBC,GAE9BF,IAAQV,EACTC,EAASW,GAETnB,QAAQD,MAAMkB,EAAK,6BAA6BV,EAAa,qBAGjEE,EAAGK,iBAAiB,uBAAwB,WAG1C,GAAwB,UAArBL,EAAGW,eACN,CACE,GAAIC,GAAWZ,EAAGa,aAElBC,GAAaC,IAAIlB,EAAWG,EAAIY,EAEhC,IAAII,GAAQC,EAAOpB,EAChBmB,WAEMC,GAAOpB,GAEdmB,EAAMjB,SAAS,KAAMC,EAAIY,IAG3BnC,EAAKiB,KAAK,iBAAkBM,EAAIY,MAKpCM,OAAOC,eAAenB,EAAI,aAAcoB,MAAQvB,IAEzCG,EA0FT,QAASqB,GAAQC,EAASC,GAExB,GACIC,IADOF,EAAQG,KACRH,EAAQE,KAGnB,IAAGA,GAAQ/C,EAAKoB,UACd,MAAON,SAAQD,MAAM,6BAA8BgC,EAGrD,MAAKA,EAAQI,KAAO,EAClB,MAAOnC,SAAQoC,KAAK,gBAAgBL,EAEtC,IAAIE,GAAOF,EAAQE,IAEnBF,GAAUA,EAAQM,MAIlB,KAAI,GAASC,GAALC,EAAE,EAASD,EAAKf,EAAaiB,YAAYD,GAAIA,IACnD,GAAGD,EAAKhC,WAAa2B,EACnB,MAAOK,GAAKG,KAAKV,EAIrBR,GAAakB,KAAKV,EAASC,GAC3BU,EAAiBD,KAAKV,EAASC,GA+BjC,QAASW,GAAoBT,GAG3B,GAAII,GAAOf,EAAaqB,IAAIV,EAC5B,IAAGI,EACH,CAIE,GAAIP,GAAU,IAAI7C,EAAKoB,UAAU,0BAA0B4B,CAC3DlC,SAAQ6C,IAAId,EAEZ,IAAIhC,IAEF+C,KAAM,GACNf,QAASA,EACTI,IAAKY,gBAEP,OAAOhD,GAIT,GAAI0B,GAAQC,EAAOQ,EACnB,IAAGT,EACH,CAIE,GAAIM,GAAU,IAAI7C,EAAKoB,UAAU,qCAAqC4B,CAItE,IAHAlC,QAAQ6C,IAAId,GAGT7C,EAAKoB,UAAY4B,EACpB,CACElC,QAAQ6C,IAAI,IAAI3D,EAAKoB,UAAU,4BAA4B4B,EAAK,kBAEhE,IAAInC,IAEF+C,KAAM,GACNf,QAASA,EACTI,IAAKY,gBAEP,OAAOhD,GAYT,aAPO2B,GAAOQ,GAEdc,EAAWC,OAAOxB,EAAMM,SACxBN,EAAMyB,eAAezD,QAErBO,QAAQmD,MAAM,IAAIjE,EAAKoB,UAAU,2BAA2B4B,EAAK,sBAE1DT,EAAMjB,UAWjB,QAAS4C,GAAWlB,EAAMF,GAGxB,GAAIM,GAAOf,EAAaqB,IAAIV,EAC5B,KAAGI,EAAH,CAGA,GAAIb,GAAQC,EAAOQ,EACnB,KAAGT,EAAH,CAEA,GAAIhB,GAAK4C,EAAcnB,EAAMF,EAE7BvB,GAAGK,iBAAiB,uBAAwB,WAIlB,UAArBL,EAAGW,gBACJY,EAAUxC,0BAIhB,QAAS8D,GAAQC,EAASvB,GAExB,GAAIE,GAAOqB,EAAQrB,KACfD,EAAOsB,EAAQtB,IAGnB,IAAGA,GAAQ/C,EAAKoB,UAChB,CACEN,QAAQ6C,IAAI,IAAIZ,EAAK,sCAAsCC,EAG3D,IAAIsB,GAAYb,EAAoBT,EACpC,IAAGsB,GAAaA,EAAUV,KACxB,MAAOS,GAAQE,MAAMD,EAIvB,IAAI/C,GAAKJ,EAAqB6B,EAAM,SAAU,SAASwB,GAErD,GAAIC,IAEFxC,IAAKuC,EACLvB,IAAKY,gBAKPQ,GAAQE,MAAM,KAAME,IAItBlD,GAAGmD,qBAAqB,GAAIC,wBAE1B1C,IAAMoC,EAAQpC,IACdF,KAAM,UAER,WAEER,EAAGqD,aAAa,SAASJ,GAEvBjD,EAAGsD,oBAAoBL,EAAQ,KAAMxD,IAEvCA,IAEFA,GAEGsD,GACD/C,EAAGK,iBAAiB,uBAAwB,WAE1C,GAAwB,UAArBL,EAAGW,eACN,CACE,GAAIC,GAAWZ,EAAGa,aAElBkC,GAAU,KAAM/C,EAAIY,MAI1BZ,EAAGK,iBAAiB,cAAe,SAASC,GAE1C,GAAIiD,GAAUjD,EAAMiD,QAEhB3C,EAAWZ,EAAGa,aAElBD,GAAS4C,KAAKD,GAEdvD,EAAGa,UAAYD,QAMjBS,GAAQyB,EAASvB,GAIrB,QAASqB,GAAcpB,EAAMD,EAAWkC,EAAQ1D,GAE9C,GAAIC,GAAKJ,EAAqB4B,EAAM,QAAS,SAASR,GAEpD,GAAIM,IAEFZ,IAAKM,EACLU,IAAK3B,EAAWuC,gBAAkB,EAGpCvC,GAAWA,GAAYV,IAEvB,IAAIyD,GAAUP,EAAWmB,OAAO,QAASpC,EAASE,EAClD,SAASlC,EAAOqE,GAEd,MAAGrE,GAAcS,EAAST,OAE1BsE,GAAcD,IAGhB1C,GAAOO,IAELzB,SAAUA,EACVuB,QAASwB,EACTL,eAAgBzC,GAGfuB,YAAqBsC,OACtBtC,EAAUuC,QAAQ,SAASC,GAEzBA,EAAE/B,KAAKc,KAMTvB,EAAUS,KAAKc,IAQnBW,IAAUhF,EAAKuF,cAAcC,OAAOC,EAAcT,EAIlD,KAAI,GAASU,GAFTvD,EAAWZ,EAAGa,aAEViB,EAAE,EAAUqC,EAAMV,EAAO3B,GAAIA,IACrC,CACE,GAAIyB,GAAUvD,EAAGoE,kBAAkBD,EAEnCvD,GAAS4C,KAAKD,GAEdA,EAAQlD,iBAAiB,QAAS,WAEhCO,EAASyD,OAAOzD,EAAS0D,QAAQf,GAAU,KAK/C,GAAIgB,IAEFC,WAEEC,qBAAqB,EACrBC,qBAAqB,GAWzB,OAPA1E,GAAG2E,YAAY,SAAS3D,GAEtBhB,EAAGsD,oBAAoBtC,EAAO,KAAMvB,IAEtCA,EACA8E,GAEOvE,EAGT,QAAS4D,GAAcV,GAErB,GAAIzB,GAAOyB,EAASzB,IAEpBlC,SAAQmD,MAAM,IAAIjE,EAAKoB,UAAU,0BAA0B4B,EAE3D,IAAIT,GAAQC,EAAOQ,EAChBT,GACDA,EAAMyB,eAAeU,qBAAqB,GAAIC,wBAE5C1C,IAAMwC,EAASxC,IACfF,KAAM,WAER,KAAMf,GAENF,QAAQoC,KAAK,IAAIlD,EAAKoB,UAAU,2BAA6B4B,EAAO,kCAQxE,QAASmD,GAAkBC,GAEzBA,EAAQC,GAAG,YAAa,WAEnB7C,EAAiB8C,QAAUjE,EAAaiE,QACzCtG,EAAKiB,KAAK,eAEdmF,EAAQC,GAAG,eAAgB,WAEtB7C,EAAiB8C,QAAUjE,EAAaiE,QACzCtG,EAAKiB,KAAK,kBAIdmF,EAAQC,GAAG,QAAUjC,GACrBgC,EAAQC,GAAG,SAAUzD,GACrBwD,EAAQC,GAAG,QAAUzD,GAthBvB,GAAI5C,GAAOD,IAGXgB,GAAUA,KAGV,IAAI0E,GAAoB1E,EAAQ0E,iBAC5Bc,EAAoBxF,EAAQwF,kBAC5B9E,EAAoB+E,QAAQzF,EAAQU,WAGxCgB,QAAOC,eAAe3C,KAAM,gBAE1B4C,MAAO5B,EAAQwE,cAAgB,WAEjC9C,OAAOC,eAAe3C,KAAM,aAE1B4C,MAAO5B,EAAQK,WAAaqF,KAAKC,MAInC,IAAI3F,IAEF4F,YAAa,EACbC,OAAQ7G,KAAKqB,WAGX0C,EAAa,GAAI+C,YAAWC,OAAQ/F,GAEpCyC,EAAmB,GAAIuD,kBAAiBjD,EAAYyC,GACpDlE,EAAmB,GAAI2E,cAAalD,EAAY9D,EAAKuF,aAEzDxF,MAAKkH,iBAAiB,SAAU,WAE9B,MAA0B,aAAvB5E,EAAaiE,OACP,YAEF9C,EAAiB8C,SAG1BvG,KAAKkH,iBAAiB,QAAS,WAE7B,MAAO5E,GAAa6E,OAUtB,IAAI1E,KA+EJzC,MAAKoH,UAAY,SAASpE,EAAMiC,EAAQ1D,GAEtC,GAAG0D,YAAkBoC,UACrB,CACE,GAAG9F,EACD,KAAM,IAAI+F,aAAY,4CAExB/F,GAAW0D,EACXA,EAAS/E,OAIX,GAAG8C,GAAQ/C,EAAKoB,UACd,MAAOE,GAAS,GAAIJ,OAAM,yBAG5B,IAAIK,GAAKc,EAAaqB,IAAIX,EAC1B,IAAGxB,EACH,CAEE,GAAIsB,GAAU,IAAI7C,EAAKoB,UAAU,0BAA0B2B,CAC3DjC,SAAQ6C,IAAId,EAIZ,IAAIV,GAAWZ,EAAGa,aAIlB,YAFAd,GAAS,KAAMC,EAAIY,GAMrB,GAAII,GAAQC,EAAOO,EACnB,IAAGR,EACH,CAEE,GAAIM,GAAU,IAAI7C,EAAKoB,UAAU,qCAAqC2B,CACtEjC,SAAQ6C,IAAId,EAEZ,IAAItB,GAAKgB,EAAMyB,cAcf,YAVAzC,GAAGK,iBAAiB,uBAAwB,WAE1C,GAAwB,UAArBL,EAAGW,eACN,CACE,GAAIC,GAAWZ,EAAGa,aAElBd,GAAS,KAAMC,EAAIY,MAQzBgC,EAAcpB,GAAOS,EAAkBnB,GAAe2C,EAAQ1D,IAsChEkC,EAAiB6C,GAAG,YAAa,WAE/BrG,EAAKiB,KAAK,6BAA8BuC,KAE1CA,EAAiB6C,GAAG,eAAgB,WAElCrG,EAAKiB,KAAK,gCAAiCuC,KAG7CnB,EAAagE,GAAG,YAAa,WAE3BrG,EAAKiB,KAAK,yBAA0BoB,KAEtCA,EAAagE,GAAG,eAAgB,WAE9BrG,EAAKiB,KAAK,4BAA6BoB,KAySzC8D,EAAkB3C,GAClB2C,EAAkB9D,GAElBmB,EAAiB6C,GAAG,WAAYnC,GAOhCnE,KAAKQ,MAAQ,WAEXiD,EAAiBjD,QACjB8B,EAAa9B,QAEbuD,EAAWvD,SAIb+G,QAAQjB,GAAG,OAAQ,WAEjBrG,EAAKO,UArlBT,GAAIgH,cAAe/H,QAAQ,UAAU+H,aAEjC/G,SAAWhB,QAAQ,YACnBgH,QAAWhH,QAAQ,WACnBiH,KAAWjH,QAAQ,QACnBgI,KAAWhI,QAAQ,QAEnBgC,kBAAwBgG,KAAKhG,kBAC7BmD,sBAAwB6C,KAAK7C,qBAEjCnF,SAAQ,sBAER,IAAIqH,YAAarH,QAAQ,eAErBuH,iBAAmBvH,QAAQ,+BAC3BwH,aAAmBxH,QAAQ,2BAE3BsH,OAAStH,QAAQ,WAGrB,MAAMqE,iBAAkB,CAokBxBrD,UAASf,OAAQ8H,cAGjB7H,OAAOC,QAAUF;;;;AShlBjB,QAAS4K,kBAAiBd,EAAaC,EAAa5J,GAElDL,mBAAmBO,KAAKC,KAAMH,EAE9B,IAAII,GAAOD,KAEP+E,EAAU0E,EAAY1E,QAItBuK,EAASC,OAAOC,KAAKhG,EAGzB8F,GAAOG,WAEL1K,QAASA,EACT2K,SAAS,EACTC,UAAU,EAEVC,QAAY3P,EAAK4M,MACjB/J,QAAY7C,EAAK6M,SACjB+C,WAAY5P,EAAKiM,OAEjBpL,MAAO,SAAS4D,GAEdzE,EAAK8M,OAAO,GAAI5L,OAAMuD,EAAWA,EAAS5D,MAAQ,uBAUtDd,KAAKQ,MAAQ,WAEX8O,EAAOQ,aAEL/K,QAASA,IAKX9E,EAAKiM,UAMPlM,KAAKwD,KAAO,SAASV,GAEnBwM,EAAOS,SAELhL,QAASA,EACTjC,QAASA,KAlEf,GAAIrC,UAAWhB,QAAQ,YAEnBD,mBAAqBC,QAAQ,6BAE7B8P,OAAS9P,QAAQ,SAkErBgB,UAAS6J,iBAAkB9K,oBAI3B8K,iBAAiB5J,UAAUb,gBAAkB,GAC7C6C,OAAOC,eAAe2H,iBAAiB5J,UAAW,aAAckC,MAAO,OAGvEjD,OAAOC,QAAU0K;;AJzEjB,QAASxK,aAEP0H,aAAazH,KAAKC,KAElB,IAAIC,GAAOD,IAMXA,MAAK6M,MAAQ,WAEX5M,EAAKiB,KAAK,SAGZlB,KAAK8M,SAAW,SAAShK,GAEvB7C,EAAKiB,KAAK,UAAW4B,IAGvB9C,KAAKkM,OAAS,WAEZjM,EAAKiB,KAAK,UAGZlB,KAAK+M,OAAS,SAASjM,GAErBb,EAAKiB,KAAK,QAASJ,IAhCvB,GAAIL,UAAWhB,QAAQ,YAEnB+H,aAAe/H,QAAQ,UAAU+H,YAiCrC/G,UAASX,UAAW0H,cAGpB1H,UAAUY,UAAUF,MAAQ,WAE1B,KAAM,IAAIwM,WAAU,uDAEtBlN,UAAUY,UAAU8C,KAAO,WAEzB,KAAM,IAAIwJ,WAAU,sDAItBrN,OAAOC,QAAUE;;AM3CjB,QAAS+L,uBAAsBgF,GAE7B/Q,UAAUC,KAAKC,KAEf,IAAIC,GAAOD,IAGX6Q,GAAYhP,iBAAiB,OAAS5B,EAAK4M,OAC3CgE,EAAYhP,iBAAiB,UAAW,SAASC,GAE/C7B,EAAK6M,SAAShL,EAAMsG,QAEtByI,EAAYhP,iBAAiB,QAAS5B,EAAKiM,QAC3C2E,EAAYhP,iBAAiB,QAAS5B,EAAK8M,QAQ3C/M,KAAKQ,MAAQ,WAEXqQ,EAAYrQ,SAMdR,KAAKwD,KAAO,SAASV,GAEnB+N,EAAYrN,KAAKV,IApCrB,GAAIrC,UAAWhB,QAAQ,YAEnBK,UAAYL,QAAQ,cAqCxBgB,UAASoL,sBAAuB/L,WAGhCH,OAAOC,QAAUiM;;AZrCjB,QAASrM,oBAAmBK,GAE1BC,UAAUC,KAAKC,KAEf,IAAIC,GAAOD,IAGWE,SAAnBL,IACDG,KAAKH,gBAAkBM,KAAKC,IAAIP,EAAiBG,KAAKH,kBAQxDG,KAAKK,cAAgB,WAEnB,OAAO,EAMT,IAAIC,GAAc,CAElBN,MAAKO,oBAAsB,WAIzBD,IAGGA,GAAeL,EAAKJ,iBACpBI,EAAKO,SAvCZ,GAAIC,UAAWhB,QAAQ,YAEnBK,UAAYL,QAAQ,cAwCxBgB,UAASjB,mBAAoBM,WAI7BN,mBAAmBkB,UAAUb,gBAAkBc,OAAOC,kBAGtDjB,OAAOC,QAAUJ;;AWtCjB,QAAS+K,iBAAgBf,EAAaC,EAAa5J,GAEjDL,mBAAmBO,KAAKC,KAAMH,EAE9B,IAAII,GAAOD,KAEP+E,EAAU0E,EAAY1E,QAGtBiL,EAAa,GAAIC,eAErBD,GAAWE,cAAc,kDAEzBF,EAAWG,YAAc,WAEvBH,EAAWP,UAAU1K,GAAS,EAAM,SAASqL,EAAMrL,EAASjC,GAE1D7C,EAAK6M,SAAShK,MAIlBkN,EAAWK,aAAiBrQ,KAAK6M,MAAMyD,KAAKtQ,MAC5CgQ,EAAWO,eAAiBvQ,KAAKkM,OAAOoE,KAAKtQ,MAE7CgQ,EAAWQ,YAAc,SAASJ,EAAMK,GAEtCxQ,EAAK8M,OAAO0D,IAIdT,EAAWJ,QAAQpG,EAAYkH,gBAAiBlH,EAAYmH,sBAQ5D3Q,KAAKQ,MAAQ,WAEXwP,EAAWF,YAAY/K,IAMzB/E,KAAKwD,KAAO,SAASV,GAEnBkN,EAAWxM,KAAKuB,EAASjC,IA3D7B,GAAIrC,UAAWhB,QAAQ,YAEnBD,mBAAqBC,QAAQ,6BAE7BwQ,eAAiBxQ,QAAQ,qBAAqBmR,iBA0DlDnQ,UAAS8J,gBAAiB/K,oBAG1BG,OAAOC,QAAU2K;;AFjEjB,KAAMoB,wBAAyBQ,GAAI,EAAGiD,IAAK,mDACrCxD,uBAAyBO,GAAI,EAAGiD,IAAK,gCACrC5D,uBAAyBW,GAAI,EAAGiD,IAAK,mDACrC7D,qBAAyBY,GAAI,EAAGiD,IAAK,4CAErCC,gBAAyBlD,GAAI,EAAGiD,IAAK,4BAG3CxP,SAAQ+L,sBAAwBA,sBAChC/L,QAAQgM,sBAAwBA,sBAChChM,QAAQ4L,sBAAwBA,sBAChC5L,QAAQ2L,oBAAwBA,oBAChC3L,QAAQyP,eAAwBA;;AVThC,GAAI7P,oBAAqBC,QAAQ,wCAC7BC,OAAqBD,QAAQ,WAGjCE,QAAOC,QAAUF,OACjBC,OAAOC,QAAQJ,mBAAqBA;;AISpC,QAASwH,kBAAiBjD,EAAYyC,GAoBpC,QAAS8C,GAAgBC,GAEvB,GAAIvH,GAAkBuH,EAAOvH,KACzBwH,EAAkBD,EAAOC,YACzBC,EAAkBF,EAAOE,YACzB5J,EAAkB0J,EAAO1J,gBAGzB6J,EAAuBC,EAA+B3H,EAC1D,KAAI0H,EACF,KAAMvI,OAAM,kCAAoCa,EAAO,IAEzD,IAAIe,GAAY,GAAI2G,GAAqBF,EAAaC,EAAa5J,EAEnEI,GAAK2J,eAAe7G,GAEpBA,EAAUuD,GAAG,OAAQ,WAGnBvD,EAAUS,KAAKO,EAAWmB,OAAO,cAGnC,IAAI2E,GAAmB9G,EAAU8G,gBAYjC,OAXA9G,GAAU8G,iBAAmB,SAAS/G,GAEf,YAAlBA,EAAQgH,OAEN/G,EAAU1C,iBACXJ,EAAKiB,KAAK,WAAY4B,EAAQiH,OAAO9G,KAAMF,GAG7C8G,EAAiB9J,KAAKgD,EAAWD,IAG9BC,EAaT,QAASiH,KAEP,IAAIC,EAAQ3B,OACV,KAAMnH,OAAM,+BAEd,MAAM+I,EAAQD,EAAQ3B,OAAQ4B,IAC9B,CACE,GAAInH,GAAYuG,EAAgBW,EAAQC,GASxC,YARInH,GAAUuD,GAAG,QAAS,WAGxB4D,IACAF,MASJE,EAAQ,EAtFVC,QAAQpK,KAAKC,KAAM+D,EAEnB,IAAI9D,GAAOD,KAGP2J,IAEJ3J,MAAKoK,6BAA+B,SAASpI,EAAMqI,GAEjDV,EAA+B3H,GAAQqI,GAKzCrK,KAAKoK,6BAA6B,SAAUE,kBAC5CtK,KAAKoK,6BAA6B,QAAUG,gBAyC5C,IAAIN,MACAC,EAAQ,EAERM,IA+BJxK,MAAKyK,oBAAsB,SAASlB,GAGlC,GAAIG,GAAuBC,EAA+BJ,EAAOvH,KACjE,OAAI0H,QAGDA,EAAqBhJ,UAAUb,iBAAmBc,OAAOC,mBACxD2I,EAAO1J,iBASToK,EAAQjF,KAAKuE,GAGK,gBAAftJ,EAAKsG,QACNyD,MAXFQ,EAAiBxF,KAAKuE,GAGtBD,EAAgBC,KARTxI,QAAQD,MAAM,oCAAqCyI,IAsB3D/C,GACDxG,KAAK0K,WAAWlE,GAzIpB,GAAI/F,UAAWhB,QAAQ,YAEnB0K,QAAU1K,QAAQ,aAElBkL,OAASlL,QAAQ,aAGjB6K,iBAAmB7K,QAAQ,wBAC3B8K,gBAAmB9K,QAAQ,sBAmI/BgB,UAASuG,iBAAkBmD,SAG3BnD,iBAAiBtG,UAAUgK,WAAa,SAASE,GAE/C,MAA2B,gBAAjBA,GACD5K,KAAK6K,iBAAiBD,GAE5BA,YAAyBvF,OACnBrF,KAAK8K,mBAAmBF,OAEjC5K,MAAKyK,oBAAoBG,IAG3B5D,iBAAiBtG,UAAUoK,mBAAqB,SAASF,GAEvD,IAAI,GAASrB,GAALjG,EAAE,EAAWiG,EAAOqB,EAActH,GAAIA,IAC5CtD,KAAKyK,oBAAoBlB,IAG7BvC,iBAAiBtG,UAAUmK,iBAAmB,SAASE,GAIrD,QAASC,GAAclK,GAErBb,EAAKiB,KAAK,QAASJ,GAJrB,GAAIb,GAAOD,KAQPiL,EAAe,GAAIC,eAEvBD,GAAaE,KAAK,MAAOJ,GACzBE,EAAaG,OAAS,WAEpB,GAAkB,KAAfpL,KAAKuG,OACR,CACE,GAAIqE,GAAgBS,KAAKC,MAAML,EAAavG,SAGzCkG,GAActC,OACfrI,EAAK6K,mBAAmBF,GAIxBI,EAAcL,OAAOY,yBAKvBP,GAAcL,OAAOa,wBAIzBP,EAAahK,QAAU,WAErB+J,EAAcS,UAAUC,OAASf,OAAOgB,sBACPhB,OAAOiB,wBAG1CX,EAAazH,QAIf7D,OAAOC,QAAUoH;;AKtMjB,QAASmD,SAAQpG,GAEfyD,aAAazH,KAAKC,KAElB,IAAIC,GAAOD,IAGXA,MAAKuD,eAELvD,KAAKkH,iBAAiB,SAAU,WAE9B,MAAOlH,MAAKuD,YAAY+E,OAAS,YAAc,iBAIjDtI,KAAK4J,eAAiB,SAAS7G,GAE7BA,EAAUuD,GAAG,OAAQ,WAMnBrG,EAAKsD,YAAYyB,KAAKjC,GAEQ,GAA3B9C,EAAKsD,YAAY+E,QACjBrI,EAAKiB,KAAK,eAEf6B,EAAUuD,GAAG,QAAS,WAEpBrG,EAAKsD,YAAYsC,OAAO5F,EAAKsD,YAAYuC,QAAQ/C,GAAY,GAE/B,GAA3B9C,EAAKsD,YAAY+E,QACjBrI,EAAKiB,KAAK,kBAEf6B,EAAUuD,GAAG,QAAS,SAASxF,GAE7BiC,EAAUvC,QAEVP,EAAKiB,KAAK,QAASJ,KAGrBiC,EAAU8G,iBAAmB,SAAS/G,GAEpC,GAAIgH,GAAShH,EAAQgH,OACjBC,EAASjH,EAAQiH,MAErB,QAAOD,GAEL,IAAK,QACHC,EAAOvF,MAAQ,SAAS1D,EAAOqE,GAE7B,MAAOrC,GAAQ0B,MAAM1D,EAAOqE,EAAQpC,GAGxC,KAAK,SACL,IAAK,QACHgH,EAAO3G,KAAO,WAEZ,MAAON,GAAQM,QAGjBnD,EAAKiB,KAAK4I,EAAQC,EAAQhH,EAC5B,MAEA,SAEEhC,QAAQD,MAAM,2BAA2BgJ,EAAO,IAAKhH,KAI3DC,EAAUuD,GAAG,UAAW,SAASxD,GAE/BA,EAAUiB,EAAWkL,OAAOnM,GACzBA,IAGEA,EAAQoM,OACTnM,EAAUS,KAAKV,GAIfC,EAAU8G,iBAAiB/G,OAvFrC,GAAI0E,cAAe/H,QAAQ,UAAU+H,aAEjC/G,SAAWhB,QAAQ,WA0FvBgB,UAAS0J,QAAS3C,cAMlB2C,QAAQzJ,UAAUF,MAAQ,WAExB,IAAI,GAASuC,GAALO,EAAE,EAAcP,EAAU/C,KAAKuD,YAAYD,GAAIA,IACrDP,EAAUvC,SAOd2J,QAAQzJ,UAAU8C,KAAO,SAASV,EAASqM,GAEzC,IAAI,GAASpM,GAALO,EAAE,EAAcP,EAAU/C,KAAKuD,YAAYD,GAAIA,IAGlDP,IAAcoM,GAGjBpM,EAAUS,KAAKV,IAKnBnD,OAAOC,QAAUuK;;AJ7GjB,QAASlD,cAAalD,EAAYyB,GAOhC,QAAS8D,GAAgBvE,GAEvB,GAAIhC,GAAY,GAAI8I,uBAAsB9G,EAI1C,OAFA9E,GAAK2J,eAAe7G,GAEbA,EAYT,QAAS+I,GAAgB/G,EAAS1D,GAEhC,GAAG0D,EAAQY,OAASH,EACpB,CACE,GAAIzC,GAAYuG,EAAgBvE,EAGhC,OAFIhC,GAAU1B,UAAYA,EAEnB0B,GA9BXoH,QAAQpK,KAAKC,KAAM+D,EAEnB,IAAI9D,GAAOD,KAaPmH,IAEJnH,MAAKkH,iBAAiB,QAAS,WAE7B,MAAOC,KAeTnH,KAAKuC,IAAM,SAASlB,EAAW4C,EAAgB7B,GAqB3C,QAAS2J,GAAyBjK,GAEhC,GAAIiD,GAAUjD,EAAMiD,QAEhBhC,EAAY+I,EAAgB/G,EAAS1D,EACtC0B,IACDjB,EAAMkK,OAAOC,oBAAoB,cAAeF,GAjBtD,GARA9H,EAAepC,iBAAiB,uBAAwB,WAGlB,UAAjCoC,EAAe9B,sBACTgF,GAAM9F,KAIde,EAASkG,OAGV,IAAI,GAASvD,GAALzB,EAAE,GAAYyB,EAAQ3C,EAASkB,MAClCwI,EAAgB/G,EAAS1D,GADaiC,SAiB3CW,GAAepC,iBAAiB,cAAekK,EAIjD5E,GAAM9F,GAAa4C,GAGrBjE,KAAK2D,IAAM,SAAStC,GAElB,MAAO8F,GAAM9F,GAGf,IAAI6K,GAASlM,KAAKQ,KAClBR,MAAKQ,MAAQ,WAEX,IAAI,GAAI2L,KAAMhF,GACZA,EAAMgF,GAAI3L,OAEZ0L,GAAOnM,KAAKC,OAhGhB,GAAIS,UAAWhB,QAAQ,YAEnB0K,QAAU1K,QAAQ,aAElBoM,sBAAwBpM,QAAQ,iCA+FpCgB,UAASwG,aAAckD,SAGvBxK,OAAOC,QAAUqH;;AChGjB,QAAS7D,MAAKN,EAASqJ,GAErB,GAAIhH,GAAS,GAAIE,OAAM,GACnB0E,EAASjH,EAAQiH,WAGjBD,EAAShH,EAAQgH,MACrB,QAAOA,GAEL,IAAK,QACH3E,EAAO,GAAKiH,KACd,MAEA,KAAK,WACHjH,EAAO,GAAKkH,QACd,MAEA,KAAK,QACHlH,EAAO,GAAKmH,KACd,MAEA,KAAK,SACHnH,EAAO,GAAKoH,MACd,MAEA,SAEE,GAAIzL,GAAQ,GAAIK,OAAM,2BAA2B2I,EAAO,IAGxD,MAFIhJ,GAAMgC,QAAUA,EAEdhC,EAiBV,MAZAqE,GAAO,GAAK4E,EAAO9G,KAIN,YAAV6G,IAED3E,EAAO,GAAK4E,EAAO/G,KACnBmC,EAAO,GAAKgH,EACZhH,EAAO,GAAK4E,EAAO7G,IACnBiC,EAAO,GAAK4E,EAAO7H,KAAO6H,EAAOjH,SAG5BuI,KAAKmB,UAAUrH,GAGxB,QAASsH,QAAO3J,GAEd,GAAIqC,MACA4E,IAEJjH,GAAUuI,KAAKC,MAAMxI,EAGrB,IAAIgH,GAAShH,EAAQ,EACrB,QAAOgH,GAEL,IAAKsC,OACHjH,EAAO2E,OAAS,OAClB,MAEA,KAAKuC,UACHlH,EAAO2E,OAAS,UAClB,MAEA,KAAKwC,OACHnH,EAAO2E,OAAS,OAClB,MAEA,KAAKyC,QACHpH,EAAO2E,OAAS,QAClB,MAEA,SAEE,GAAIhJ,GAAQ,GAAIK,OAAM,2BAA2B2I,EAAO,IAGxD,MAFIhJ,GAAMgC,QAAUA,EAEdhC,EA6BV,MAxBAiJ,GAAO9G,KAAOH,EAAQ,GAInBgH,GAAUuC,WAEXtC,EAAO/G,KAAOF,EAAQ,GAEnBgH,GAAUsC,OAAStC,GAAUyC,OAC9BpH,EAAOuH,IAAM5J,EAAQ,GAErBqC,EAAOgH,GAAKrJ,EAAQ,GAEtBiH,EAAO7G,IAAOJ,EAAQ,GAEnBgH,GAAUsC,MACXrC,EAAOjH,QAAUA,EAAQ,GAEzBiH,EAAO7H,IAAMY,EAAQ,IAIzBqC,EAAO4E,OAASA,EAET5E,EArHT,KAAMiH,OAAW,EACXC,SAAW,EACXC,MAAW,EACXC,OAAW,CAsHjB,IAAII,kBAEFC,SAAY,QAEZpK,OAEE1B,MAAU,QACV4D,SAAU,UAKd9E,SAAQwD,KAASA,KACjBxD,QAAQ6M,OAASA,OAEjB7M,QAAQ+M,gBAAkBA;;;;AiBvF1B,QAASwH,QAAQgf,EAASC,EAAUC,GAClC,KAAMrzB,eAAgBmU,SACpB,MAAO,IAAIA,QAAOgf,EAASC,EAAUC,EAEvC,IAAIrxB,SAAcmxB,EAIlB,IAAiB,WAAbC,GAAkC,WAATpxB,EAE3B,IADAmxB,EAAUG,WAAWH,GACdA,EAAQ7qB,OAAS,IAAM,GAC5B6qB,GAAoB,GAKxB,IAAI7qB,EACJ,IAAa,WAATtG,EACFsG,EAASirB,OAAOJ,OACb,IAAa,WAATnxB,EACPsG,EAAS6L,OAAOqf,WAAWL,EAASC,OACjC,CAAA,GAAa,WAATpxB,EAGP,KAAM,IAAIb,OAAM,wDAFhBmH,GAASirB,OAAOJ,EAAQ7qB,QAI1B,GAAIgK,EACA6B,QAAOsf,gBAETnhB,EAAM6B,OAAOuf,SAAS,GAAIT,YAAW3qB,KAGrCgK,EAAMtS,KACNsS,EAAIhK,OAASA,EACbgK,EAAIqhB,WAAY,EAGlB,IAAIrwB,EACJ,IAAI6Q,OAAOsf,iBAAiD,gBAAvBN,GAAQK,WAE3ClhB,EAAIshB,KAAKT,OACJ,IAAIU,WAAWV,GAEpB,IAAK7vB,EAAI,EAAOgF,EAAJhF,EAAYA,IAClB6Q,OAAO2f,SAASX,GAClB7gB,EAAIhP,GAAK6vB,EAAQY,UAAUzwB,GAE3BgP,EAAI0hB,UAAUb,EAAQ7vB,GAAIA,OAEzB,IAAa,WAATtB,EACTsQ,EAAI2hB,MAAMd,EAAS,EAAGC,OACjB,IAAa,WAATpxB,IAAsBmS,OAAOsf,kBAAoBJ,EAC1D,IAAK/vB,EAAI,EAAOgF,EAAJhF,EAAYA,IACtBgP,EAAIhP,GAAK,CAIb,OAAOgP,GA4GT,QAAS4hB,UAAU5hB,EAAK4T,EAAQ3T,EAAQjK,GACtCiK,EAAS5R,OAAO4R,IAAW,CAC3B,IAAI4hB,GAAY7hB,EAAIhK,OAASiK,CACxBjK,IAGHA,EAAS3H,OAAO2H,GACZA,EAAS6rB,IACX7rB,EAAS6rB,IAJX7rB,EAAS6rB,CASX,IAAIC,GAASlO,EAAO5d,MACpB+rB,QAAOD,EAAS,IAAM,EAAG,sBAErB9rB,EAAS8rB,EAAS,IACpB9rB,EAAS8rB,EAAS,EAEpB,KAAK,GAAI9wB,GAAI,EAAOgF,EAAJhF,EAAYA,IAAK,CAC/B,GAAIgxB,GAAO3L,SAASzC,EAAO7R,OAAW,EAAJ/Q,EAAO,GAAI,GAC7C+wB,SAAQ1mB,MAAM2mB,GAAO,sBACrBhiB,EAAIC,EAASjP,GAAKgxB,EAEpB,MAAOhxB,GAGT,QAASixB,WAAWjiB,EAAK4T,EAAQ3T,EAAQjK,GACvC,GAAIksB,GAAeC,WAAWC,YAAYxO,GAAS5T,EAAKC,EAAQjK,EAChE,OAAOksB,GAGT,QAASG,YAAYriB,EAAK4T,EAAQ3T,EAAQjK,GACxC,GAAIksB,GAAeC,WAAWG,aAAa1O,GAAS5T,EAAKC,EAAQjK,EACjE,OAAOksB,GAGT,QAASK,aAAaviB,EAAK4T,EAAQ3T,EAAQjK,GACzC,MAAOqsB,YAAWriB,EAAK4T,EAAQ3T,EAAQjK,GAGzC,QAASwsB,aAAaxiB,EAAK4T,EAAQ3T,EAAQjK,GACzC,GAAIksB,GAAeC,WAAWM,cAAc7O,GAAS5T,EAAKC,EAAQjK,EAClE,OAAOksB,GAGT,QAASQ,cAAc1iB,EAAK4T,EAAQ3T,EAAQjK,GAC1C,GAAIksB,GAAeC,WAAWQ,eAAe/O,GAAS5T,EAAKC,EAAQjK,EACnE,OAAOksB,GA0JT,QAASU,aAAa5iB,EAAKyO,EAAOC,GAChC,MACSmU,QAAOC,cADF,IAAVrU,GAAeC,IAAQ1O,EAAIhK,OACDgK,EAEAA,EAAInE,MAAM4S,EAAOC,IAIjD,QAASqU,WAAW/iB,EAAKyO,EAAOC,GAC9B,GAAIsU,GAAM,GACNxJ,EAAM,EACV9K,GAAM7gB,KAAKC,IAAIkS,EAAIhK,OAAQ0Y,EAE3B,KAAK,GAAI1d,GAAIyd,EAAWC,EAAJ1d,EAASA,IACvBgP,EAAIhP,IAAM,KACZgyB,GAAOC,eAAezJ,GAAO1F,OAAOC,aAAa/T,EAAIhP,IACrDwoB,EAAM,IAENA,GAAO,IAAMxZ,EAAIhP,GAAG8Q,SAAS,GAIjC,OAAOkhB,GAAMC,eAAezJ,GAG9B,QAAS0J,YAAYljB,EAAKyO,EAAOC,GAC/B,GAAIlS,GAAM,EACVkS,GAAM7gB,KAAKC,IAAIkS,EAAIhK,OAAQ0Y,EAE3B,KAAK,GAAI1d,GAAIyd,EAAWC,EAAJ1d,EAASA,IAC3BwL,GAAOsX,OAAOC,aAAa/T,EAAIhP,GAEjC,OAAOwL,GAGT,QAAS2mB,aAAanjB,EAAKyO,EAAOC,GAChC,MAAOwU,YAAWljB,EAAKyO,EAAOC,GAGhC,QAAS0U,UAAUpjB,EAAKyO,EAAOC,GAC7B,GAAIlT,GAAMwE,EAAIhK,SAETyY,GAAiB,EAARA,KAAWA,EAAQ,KAC5BC,GAAa,EAANA,GAAWA,EAAMlT,KAAKkT,EAAMlT,EAGxC,KAAK,GADD4D,GAAM,GACDpO,EAAIyd,EAAWC,EAAJ1d,EAASA,IAC3BoO,GAAOikB,MAAMrjB,EAAIhP,GAEnB,OAAOoO,GAGT,QAASkkB,cAActjB,EAAKyO,EAAOC,GAGjC,IAAK,GAFD6U,GAAQvjB,EAAInE,MAAM4S,EAAOC,GACzBsU,EAAM,GACDhyB,EAAI,EAAGA,EAAIuyB,EAAMvtB,OAAQhF,GAAK,EACrCgyB,GAAOlP,OAAOC,aAAawP,EAAMvyB,GAAoB,IAAfuyB,EAAMvyB,EAAI,GAElD,OAAOgyB,GA4CT,QAASQ,YAAYxjB,EAAKC,EAAQwjB,EAAcC,GACzCA,IACH3B,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,uCAGlC,IAAIwF,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAAd,CAGA,GAAI4S,EAUJ,OATIqV,IACFrV,EAAMpO,EAAIC,GACOzE,EAAbyE,EAAS,IACXmO,GAAOpO,EAAIC,EAAS,IAAM,KAE5BmO,EAAMpO,EAAIC,IAAW,EACJzE,EAAbyE,EAAS,IACXmO,GAAOpO,EAAIC,EAAS,KAEjBmO,GAWT,QAASuV,YAAY3jB,EAAKC,EAAQwjB,EAAcC,GACzCA,IACH3B,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,uCAGlC,IAAIwF,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAAd,CAGA,GAAI4S,EAkBJ,OAjBIqV,IACejoB,EAAbyE,EAAS,IACXmO,EAAMpO,EAAIC,EAAS,IAAM,IACVzE,EAAbyE,EAAS,IACXmO,GAAOpO,EAAIC,EAAS,IAAM,GAC5BmO,GAAOpO,EAAIC,GACMzE,EAAbyE,EAAS,IACXmO,GAAapO,EAAIC,EAAS,IAAM,KAAO,KAExBzE,EAAbyE,EAAS,IACXmO,EAAMpO,EAAIC,EAAS,IAAM,IACVzE,EAAbyE,EAAS,IACXmO,GAAOpO,EAAIC,EAAS,IAAM,GACXzE,EAAbyE,EAAS,IACXmO,GAAOpO,EAAIC,EAAS,IACtBmO,GAAapO,EAAIC,IAAW,KAAO,GAE9BmO,GA4BT,QAASwV,WAAW5jB,EAAKC,EAAQwjB,EAAcC,GACxCA,IACH3B,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,uCAGlC,IAAIwF,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAAd,CAGA,GAAI4S,GAAMoV,WAAWxjB,EAAKC,EAAQwjB,GAAc,GAC5CI,EAAY,MAANzV,CACV,OAAIyV,GAC0B,IAApB,MAASzV,EAAM,GAEhBA,GAWX,QAAS0V,WAAW9jB,EAAKC,EAAQwjB,EAAcC,GACxCA,IACH3B,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,uCAGlC,IAAIwF,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAAd,CAGA,GAAI4S,GAAMuV,WAAW3jB,EAAKC,EAAQwjB,GAAc,GAC5CI,EAAY,WAANzV,CACV,OAAIyV,GAC8B,IAAxB,WAAazV,EAAM,GAEpBA,GAWX,QAAS2V,WAAW/jB,EAAKC,EAAQwjB,EAAcC,GAM7C,MALKA,KACH3B,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,wCAG3BguB,QAAQC,KAAKjkB,EAAKC,EAAQwjB,EAAc,GAAI,GAWrD,QAASS,YAAYlkB,EAAKC,EAAQwjB,EAAcC,GAM9C,MALKA,KACH3B,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,wCAG3BguB,QAAQC,KAAKjkB,EAAKC,EAAQwjB,EAAc,GAAI,GAyBrD,QAASU,aAAankB,EAAK1P,EAAO2P,EAAQwjB,EAAcC,GACjDA,IACH3B,OAAiBn0B,SAAV0C,GAAiC,OAAVA,EAAgB,iBAC9CyxB,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,wCAChCouB,UAAU9zB,EAAO,OAGnB,IAAIkL,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAAd,CAGA,IAAK,GAAIxK,GAAI,EAAGgiB,EAAInlB,KAAKC,IAAI0N,EAAMyE,EAAQ,GAAQ+S,EAAJhiB,EAAOA,IACpDgP,EAAIC,EAASjP,IACRV,EAAS,KAAS,GAAKmzB,EAAezyB,EAAI,EAAIA,MACd,GAA5ByyB,EAAezyB,EAAI,EAAIA,EAElC,OAAOiP,GAAS,GAWlB,QAASokB,aAAarkB,EAAK1P,EAAO2P,EAAQwjB,EAAcC,GACjDA,IACH3B,OAAiBn0B,SAAV0C,GAAiC,OAAVA,EAAgB,iBAC9CyxB,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,wCAChCouB,UAAU9zB,EAAO,YAGnB,IAAIkL,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAAd,CAGA,IAAK,GAAIxK,GAAI,EAAGgiB,EAAInlB,KAAKC,IAAI0N,EAAMyE,EAAQ,GAAQ+S,EAAJhiB,EAAOA,IACpDgP,EAAIC,EAASjP,GACRV,IAAuC,GAA5BmzB,EAAezyB,EAAI,EAAIA,GAAU,GAEnD,OAAOiP,GAAS,GA6BlB,QAASqkB,YAAYtkB,EAAK1P,EAAO2P,EAAQwjB,EAAcC,GAChDA,IACH3B,OAAiBn0B,SAAV0C,GAAiC,OAAVA,EAAgB,iBAC9CyxB,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,wCAChCuuB,UAAUj0B,EAAO,MAAQ,QAG3B,IAAIkL,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAOd,MAJIlL,IAAS,EACX6zB,YAAYnkB,EAAK1P,EAAO2P,EAAQwjB,EAAcC,GAE9CS,YAAYnkB,EAAK,MAAS1P,EAAQ,EAAG2P,EAAQwjB,EAAcC,GACtDzjB,EAAS,EAWlB,QAASukB,YAAYxkB,EAAK1P,EAAO2P,EAAQwjB,EAAcC,GAChDA,IACH3B,OAAiBn0B,SAAV0C,GAAiC,OAAVA,EAAgB,iBAC9CyxB,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,wCAChCuuB,UAAUj0B,EAAO,WAAY,aAG/B,IAAIkL,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAOd,MAJIlL,IAAS,EACX+zB,YAAYrkB,EAAK1P,EAAO2P,EAAQwjB,EAAcC,GAE9CW,YAAYrkB,EAAK,WAAa1P,EAAQ,EAAG2P,EAAQwjB,EAAcC,GAC1DzjB,EAAS,EAWlB,QAASwkB,YAAYzkB,EAAK1P,EAAO2P,EAAQwjB,EAAcC,GAChDA,IACH3B,OAAiBn0B,SAAV0C,GAAiC,OAAVA,EAAgB,iBAC9CyxB,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OAAQ,wCAChC0uB,aAAap0B,EAAO,sBAAwB,wBAG9C,IAAIkL,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAId,MADAwoB,SAAQrC,MAAM3hB,EAAK1P,EAAO2P,EAAQwjB,EAAc,GAAI,GAC7CxjB,EAAS,EAWlB,QAAS0kB,aAAa3kB,EAAK1P,EAAO2P,EAAQwjB,EAAcC,GACjDA,IACH3B,OAAiBn0B,SAAV0C,GAAiC,OAAVA,EAAgB,iBAC9CyxB,OAA+B,iBAAjB0B,GAA4B,6BAC1C1B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAAS,EAAID,EAAIhK,OACpB,wCACJ0uB,aAAap0B,EAAO,uBAAyB,yBAG/C,IAAIkL,GAAMwE,EAAIhK,MACd,MAAIiK,GAAUzE,GAId,MADAwoB,SAAQrC,MAAM3hB,EAAK1P,EAAO2P,EAAQwjB,EAAc,GAAI,GAC7CxjB,EAAS,EAyIlB,QAAS+gB,YAAY1a,GACnB,MAAIA,GAAIse,KAAate,EAAIse,OAClBte,EAAIlG,QAAQ,aAAc,IAInC,QAASykB,OAAOjtB,EAAO4D,EAAKspB,GAC1B,MAAqB,gBAAVltB,GAA2BktB,GACtCltB,IAAUA,EACNA,GAAS4D,EAAYA,EACrB5D,GAAS,EAAUA,GACvBA,GAAS4D,EACL5D,GAAS,EAAUA,EAChB,IAGT,QAASqpB,QAAQjrB,GAKf,MADAA,KAAWnI,KAAK2pB,MAAMxhB,GACN,EAATA,EAAa,EAAIA,EAG1B,QAAS+Q,SAAS8Z,GAChB,OAAQ9tB,MAAMgU,SAAW,SAAU8Z,GACjC,MAAmD,mBAA5CzwB,OAAOhC,UAAU0T,SAASrU,KAAKozB,KACrCA,GAGL,QAASU,YAAYV,GACnB,MAAO9Z,SAAQ8Z,IAAYhf,OAAO2f,SAASX,IACvCA,GAA8B,gBAAZA,IACQ,gBAAnBA,GAAQ7qB,OAGrB,QAASqtB,OAAOjoB,GACd,MAAQ,IAAJA,EAAe,IAAMA,EAAE0G,SAAS,IAC7B1G,EAAE0G,SAAS,IAGpB,QAASsgB,aAAa9b,GAEpB,IAAK,GADDye,MACK/zB,EAAI,EAAGA,EAAIsV,EAAItQ,OAAQhF,IAAK,CACnC,GAAI2P,GAAI2F,EAAIoN,WAAW1iB,EACvB,IAAS,KAAL2P,EACFokB,EAAUryB,KAAKiO,OACV,CACL,GAAI8N,GAAQzd,CACR2P,IAAK,OAAe,OAALA,GAAa3P,GAEhC,KAAK,GADD+hB,GAAI3L,mBAAmBd,EAAIzK,MAAM4S,EAAOzd,EAAE,IAAI+Q,OAAO,GAAGuN,MAAM,KACzD0D,EAAI,EAAGA,EAAID,EAAE/c,OAAQgd,IAC5B+R,EAAUryB,KAAK2jB,SAAStD,EAAEC,GAAI,MAIpC,MAAO+R,GAGT,QAASzC,cAAchc,GAErB,IAAK,GADDye,MACK/zB,EAAI,EAAGA,EAAIsV,EAAItQ,OAAQhF,IAE9B+zB,EAAUryB,KAAyB,IAApB4T,EAAIoN,WAAW1iB,GAEhC,OAAO+zB,GAGT,QAASpC,gBAAgBrc,GAGvB,IAAK,GAFDrT,GAAG+xB,EAAIC,EACPF,KACK/zB,EAAI,EAAGA,EAAIsV,EAAItQ,OAAQhF,IAC9BiC,EAAIqT,EAAIoN,WAAW1iB,GACnBg0B,EAAK/xB,GAAK,EACVgyB,EAAKhyB,EAAI,IACT8xB,EAAUryB,KAAKuyB,GACfF,EAAUryB,KAAKsyB,EAGjB,OAAOD,GAGT,QAAStC,eAAenc,GACtB,MAAOuc,QAAOqC,YAAY5e,GAG5B,QAAS6b,YAAYgD,EAAKC,EAAKnlB,EAAQjK,GACrC,IAAK,GAAIhF,GAAI,EAAOgF,EAAJhF,KACTA,EAAIiP,GAAUmlB,EAAIpvB,QAAYhF,GAAKm0B,EAAInvB,QADlBhF,IAG1Bo0B,EAAIp0B,EAAIiP,GAAUklB,EAAIn0B,EAExB,OAAOA,GAGT,QAASiyB,gBAAgB3c,GACvB,IACE,MAAOkP,oBAAmBlP,GAC1B,MAAOzD,GACP,MAAOiR,QAAOC,aAAa,QAS/B,QAASqQ,WAAW9zB,EAAOykB,GACzBgN,OAAwB,gBAAVzxB,GAAoB,yCAClCyxB,OAAOzxB,GAAS,EAAG,4DACnByxB,OAAgBhN,GAATzkB,EAAc,+CACrByxB,OAAOl0B,KAAKqjB,MAAM5gB,KAAWA,EAAO,oCAGtC,QAASi0B,WAAWj0B,EAAOykB,EAAKjnB,GAC9Bi0B,OAAwB,gBAAVzxB,GAAoB,yCAClCyxB,OAAgBhN,GAATzkB,EAAc,2CACrByxB,OAAOzxB,GAASxC,EAAK,4CACrBi0B,OAAOl0B,KAAKqjB,MAAM5gB,KAAWA,EAAO,oCAGtC,QAASo0B,cAAcp0B,EAAOykB,EAAKjnB,GACjCi0B,OAAwB,gBAAVzxB,GAAoB,yCAClCyxB,OAAgBhN,GAATzkB,EAAc,2CACrByxB,OAAOzxB,GAASxC,EAAK,4CAGvB,QAASi0B,QAAQsD,EAAM70B,GACrB,IAAK60B,EAAM,KAAM,IAAIx2B,OAAM2B,GAAW,oBAnnCxC,GAAIqyB,QAAS11B,QAAQ,aACjB62B,QAAU72B,QAAQ,UAEtBG,SAAQuU,OAASA,OACjBvU,QAAQg4B,WAAazjB,OACrBvU,QAAQi4B,kBAAoB,GAC5B1jB,OAAO2jB,SAAW,KAOlB3jB,OAAOsf,gBAAkB,WAMvB,IACE,GAAInhB,GAAM,GAAIylB,aAAY,GACtB9L,EAAM,GAAIgH,YAAW3gB,EAEzB,OADA2Z,GAAI+L,IAAM,WAAc,MAAO,KACxB,KAAO/L,EAAI+L,OACU,kBAAjB/L,GAAIgM,SACf,MAAOvc,GACP,OAAO,MA+EXvH,OAAO+jB,WAAa,SAAU9E,GAC5B,OAAQhN,OAAOgN,GAAU3gB,eACvB,IAAK,MACL,IAAK,OACL,IAAK,QACL,IAAK,QACL,IAAK,SACL,IAAK,SACL,IAAK,MACL,IAAK,OACL,IAAK,QACL,IAAK,UACL,IAAK,WACH,OAAO,CACT,SACE,OAAO,IAIb0B,OAAO2f,SAAW,SAAU7gB,GAC1B,QAAgB,OAANA,GAAoB/S,SAAN+S,IAAmBA,EAAE0gB,YAG/Cxf,OAAOqf,WAAa,SAAU5a,EAAKwa,GACjC,GAAItkB,EAEJ,QADA8J,EAAMA,EAAIxE,WACFgf,GAAY,QAClB,IAAK,MACHtkB,EAAM8J,EAAItQ,OAAS,CACnB,MACF,KAAK,OACL,IAAK,QACHwG,EAAM4lB,YAAY9b,GAAKtQ,MACvB,MACF,KAAK,QACL,IAAK,SACL,IAAK,MACHwG,EAAM8J,EAAItQ,MACV,MACF,KAAK,SACHwG,EAAMimB,cAAcnc,GAAKtQ,MACzB,MACF,KAAK,OACL,IAAK,QACL,IAAK,UACL,IAAK,WACHwG,EAAmB,EAAb8J,EAAItQ,MACV,MACF,SACE,KAAM,IAAInH,OAAM,oBAEpB,MAAO2N,IAGTqF,OAAO1O,OAAS,SAAUkJ,EAAMwpB,GAG9B,GAFA9D,OAAOhb,QAAQ1K,GAAO,wCAEF,IAAhBA,EAAKrG,OACP,MAAO,IAAI6L,QAAO,EACb,IAAoB,IAAhBxF,EAAKrG,OACd,MAAOqG,GAAK,EAGd,IAAIrL,EACJ,IAAoBpD,SAAhBi4B,EAEF,IADAA,EAAc,EACT70B,EAAI,EAAGA,EAAIqL,EAAKrG,OAAQhF,IAC3B60B,GAAexpB,EAAKrL,GAAGgF,MAI3B,IAAIgK,GAAM,GAAI6B,QAAOgkB,GACjBC,EAAM,CACV,KAAK90B,EAAI,EAAGA,EAAIqL,EAAKrG,OAAQhF,IAAK,CAChC,GAAI+0B,GAAO1pB,EAAKrL,EAChB+0B,GAAKC,KAAKhmB,EAAK8lB,GACfA,GAAOC,EAAK/vB,OAEd,MAAOgK,IAGT6B,OAAOokB,QAAU,SAAUnZ,EAAGnM,GAC5BohB,OAAOlgB,OAAO2f,SAAS1U,IAAMjL,OAAO2f,SAAS7gB,GAAI,4BAGjD,KAAK,GAFDoR,GAAIjF,EAAE9W,OACNgc,EAAIrR,EAAE3K,OACDhF,EAAI,EAAGwK,EAAM3N,KAAKC,IAAIikB,EAAGC,GAAQxW,EAAJxK,GAAW8b,EAAE9b,KAAO2P,EAAE3P,GAAIA,KAKhE,MAJIA,KAAMwK,IACRuW,EAAIjF,EAAE9b,GACNghB,EAAIrR,EAAE3P,IAEAghB,EAAJD,EACK,GAEDA,EAAJC,EACK,EAEF,GAyDTnQ,OAAOzT,UAAUuzB,MAAQ,SAAU/N,EAAQ3T,EAAQjK,EAAQ8qB,GAGzD,GAAIoF,SAASjmB,GACNimB,SAASlwB,KACZ8qB,EAAW9qB,EACXA,EAASpI,YAEN,CACL,GAAIu4B,GAAOrF,CACXA,GAAW7gB,EACXA,EAASjK,EACTA,EAASmwB,EAGXlmB,EAAS5R,OAAO4R,IAAW,CAC3B,IAAI4hB,GAAYn0B,KAAKsI,OAASiK,CACzBjK,IAGHA,EAAS3H,OAAO2H,GACZA,EAAS6rB,IACX7rB,EAAS6rB,IAJX7rB,EAAS6rB,EAOXf,EAAWhN,OAAOgN,GAAY,QAAQ3gB,aAEtC,IAAI3D,EACJ,QAAQskB,GACN,IAAK,MACHtkB,EAAMolB,SAASl0B,KAAMkmB,EAAQ3T,EAAQjK,EACrC,MACF,KAAK,OACL,IAAK,QACHwG,EAAMylB,UAAUv0B,KAAMkmB,EAAQ3T,EAAQjK,EACtC,MACF,KAAK,QACHwG,EAAM6lB,WAAW30B,KAAMkmB,EAAQ3T,EAAQjK,EACvC,MACF,KAAK,SACHwG,EAAM+lB,YAAY70B,KAAMkmB,EAAQ3T,EAAQjK,EACxC,MACF,KAAK,SACHwG,EAAMgmB,YAAY90B,KAAMkmB,EAAQ3T,EAAQjK,EACxC,MACF,KAAK,OACL,IAAK,QACL,IAAK,UACL,IAAK,WACHwG,EAAMkmB,aAAah1B,KAAMkmB,EAAQ3T,EAAQjK,EACzC,MACF,SACE,KAAM,IAAInH,OAAM,oBAEpB,MAAO2N,IAGTqF,OAAOzT,UAAU0T,SAAW,SAAUgf,EAAUrS,EAAOC,GACrD,GAAI/gB,GAAOD,IAOX,IALAozB,EAAWhN,OAAOgN,GAAY,QAAQ3gB,cACtCsO,EAAQpgB,OAAOogB,IAAU,EACzBC,EAAe9gB,SAAR8gB,EAAqB/gB,EAAKqI,OAAS3H,OAAOqgB,GAG7CA,IAAQD,EACV,MAAO,EAET,IAAIjS,EACJ,QAAQskB,GACN,IAAK,MACHtkB,EAAM4mB,SAASz1B,EAAM8gB,EAAOC,EAC5B,MACF,KAAK,OACL,IAAK,QACHlS,EAAMumB,UAAUp1B,EAAM8gB,EAAOC,EAC7B,MACF,KAAK,QACHlS,EAAM0mB,WAAWv1B,EAAM8gB,EAAOC,EAC9B,MACF,KAAK,SACHlS,EAAM2mB,YAAYx1B,EAAM8gB,EAAOC,EAC/B,MACF,KAAK,SACHlS,EAAMomB,YAAYj1B,EAAM8gB,EAAOC,EAC/B,MACF,KAAK,OACL,IAAK,QACL,IAAK,UACL,IAAK,WACHlS,EAAM8mB,aAAa31B,EAAM8gB,EAAOC,EAChC,MACF,SACE,KAAM,IAAI7f,OAAM,oBAEpB,MAAO2N,IAGTqF,OAAOzT,UAAUg4B,OAAS,WACxB,OACE12B,KAAM,SACNoG,KAAM/C,MAAM3E,UAAUyN,MAAMpO,KAAKC,KAAK24B,MAAQ34B,KAAM,KAIxDmU,OAAOzT,UAAUk4B,OAAS,SAAU3lB,GAElC,MADAohB,QAAOlgB,OAAO2f,SAAS7gB,GAAI,6BACQ,IAA5BkB,OAAOokB,QAAQv4B,KAAMiT,IAG9BkB,OAAOzT,UAAU63B,QAAU,SAAUtlB,GAEnC,MADAohB,QAAOlgB,OAAO2f,SAAS7gB,GAAI,6BACpBkB,OAAOokB,QAAQv4B,KAAMiT,IAI9BkB,OAAOzT,UAAU43B,KAAO,SAAUtsB,EAAQ6sB,EAAc9X,EAAOC,GAC7D,GAAI7Y,GAASnI,IAOb,IALK+gB,IAAOA,EAAQ,GACfC,GAAe,IAARA,IAAWA,EAAMhhB,KAAKsI,QAC7BuwB,IAAcA,EAAe,GAG9B7X,IAAQD,GACU,IAAlB/U,EAAO1D,QAAkC,IAAlBH,EAAOG,OAAlC,CAGA+rB,OAAOrT,GAAOD,EAAO,2BACrBsT,OAAOwE,GAAgB,GAAKA,EAAe7sB,EAAO1D,OAC9C,6BACJ+rB,OAAOtT,GAAS,GAAKA,EAAQ5Y,EAAOG,OAAQ,6BAC5C+rB,OAAOrT,GAAO,GAAKA,GAAO7Y,EAAOG,OAAQ,2BAGrC0Y,EAAMhhB,KAAKsI,SACb0Y,EAAMhhB,KAAKsI,QACT0D,EAAO1D,OAASuwB,EAAe7X,EAAMD,IACvCC,EAAMhV,EAAO1D,OAASuwB,EAAe9X,EAEvC,IAAIjT,GAAMkT,EAAMD,CAEhB,IAAU,IAANjT,IAAcqG,OAAOsf,gBACvB,IAAK,GAAInwB,GAAI,EAAOwK,EAAJxK,EAASA,IACvB0I,EAAO1I,EAAIu1B,GAAgB74B,KAAKsD,EAAIyd,OAGtC/U,GAAO4nB,KAAK5zB,KAAKi4B,SAASlX,EAAOA,EAAQjT,GAAM+qB,KAiEnD1kB,OAAOzT,UAAUyN,MAAQ,SAAU4S,EAAOC,GACxC,GAAIlT,GAAM9N,KAAKsI,MAIf,IAHAyY,EAAQoW,MAAMpW,EAAOjT,EAAK,GAC1BkT,EAAMmW,MAAMnW,EAAKlT,EAAKA,GAElBqG,OAAOsf,gBACT,MAAOtf,QAAOuf,SAAS1zB,KAAKi4B,SAASlX,EAAOC,GAI5C,KAAK,GAFD8X,GAAW9X,EAAMD,EACjBgY,EAAS,GAAI5kB,QAAO2kB,EAAU54B,QAAW,GACpCoD,EAAI,EAAOw1B,EAAJx1B,EAAcA,IAC5By1B,EAAOz1B,GAAKtD,KAAKsD,EAAIyd,EAEvB,OAAOgY,IAKX5kB,OAAOzT,UAAUiD,IAAM,SAAU4O,GAE/B,MADAxR,SAAQ6C,IAAI,6DACL5D,KAAK+zB,UAAUxhB,IAIxB4B,OAAOzT,UAAUoV,IAAM,SAAUsD,EAAG7G,GAElC,MADAxR,SAAQ6C,IAAI,6DACL5D,KAAKg5B,WAAW5f,EAAG7G,IAG5B4B,OAAOzT,UAAUqzB,UAAY,SAAUxhB,EAAQyjB,GAM7C,MALKA,KACH3B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAASvS,KAAKsI,OAAQ,wCAG3BiK,GAAUvS,KAAKsI,OAAnB,OAGOtI,KAAKuS,IA2Bd4B,OAAOzT,UAAUu4B,aAAe,SAAU1mB,EAAQyjB,GAChD,MAAOF,YAAW91B,KAAMuS,GAAQ,EAAMyjB,IAGxC7hB,OAAOzT,UAAUw4B,aAAe,SAAU3mB,EAAQyjB,GAChD,MAAOF,YAAW91B,KAAMuS,GAAQ,EAAOyjB,IAmCzC7hB,OAAOzT,UAAUy4B,aAAe,SAAU5mB,EAAQyjB,GAChD,MAAOC,YAAWj2B,KAAMuS,GAAQ,EAAMyjB,IAGxC7hB,OAAOzT,UAAU04B,aAAe,SAAU7mB,EAAQyjB,GAChD,MAAOC,YAAWj2B,KAAMuS,GAAQ,EAAOyjB,IAGzC7hB,OAAOzT,UAAU24B,SAAW,SAAU9mB,EAAQyjB,GAO5C,GANKA,IACH3B,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAC3B,kBACJ8hB,OAAO9hB,EAASvS,KAAKsI,OAAQ,0CAG3BiK,GAAUvS,KAAKsI,QAAnB,CAGA,GAAI6tB,GAAqB,IAAfn2B,KAAKuS,EACf,OAAI4jB,GACiC,IAA3B,IAAOn2B,KAAKuS,GAAU,GAEvBvS,KAAKuS,KAsBhB4B,OAAOzT,UAAU44B,YAAc,SAAU/mB,EAAQyjB,GAC/C,MAAOE,WAAUl2B,KAAMuS,GAAQ,EAAMyjB,IAGvC7hB,OAAOzT,UAAU64B,YAAc,SAAUhnB,EAAQyjB,GAC/C,MAAOE,WAAUl2B,KAAMuS,GAAQ,EAAOyjB,IAsBxC7hB,OAAOzT,UAAU84B,YAAc,SAAUjnB,EAAQyjB,GAC/C,MAAOI,WAAUp2B,KAAMuS,GAAQ,EAAMyjB,IAGvC7hB,OAAOzT,UAAU+4B,YAAc,SAAUlnB,EAAQyjB,GAC/C,MAAOI,WAAUp2B,KAAMuS,GAAQ,EAAOyjB,IAYxC7hB,OAAOzT,UAAUg5B,YAAc,SAAUnnB,EAAQyjB,GAC/C,MAAOK,WAAUr2B,KAAMuS,GAAQ,EAAMyjB,IAGvC7hB,OAAOzT,UAAUi5B,YAAc,SAAUpnB,EAAQyjB,GAC/C,MAAOK,WAAUr2B,KAAMuS,GAAQ,EAAOyjB,IAYxC7hB,OAAOzT,UAAUk5B,aAAe,SAAUrnB,EAAQyjB,GAChD,MAAOQ,YAAWx2B,KAAMuS,GAAQ,EAAMyjB,IAGxC7hB,OAAOzT,UAAUm5B,aAAe,SAAUtnB,EAAQyjB,GAChD,MAAOQ,YAAWx2B,KAAMuS,GAAQ,EAAOyjB,IAGzC7hB,OAAOzT,UAAUs4B,WAAa,SAAUp2B,EAAO2P,EAAQyjB,GAQrD,MAPKA,KACH3B,OAAiBn0B,SAAV0C,GAAiC,OAAVA,EAAgB,iBAC9CyxB,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAASvS,KAAKsI,OAAQ,wCAC7BouB,UAAU9zB,EAAO,MAGf2P,GAAUvS,KAAKsI,OAAnB,QAEAtI,KAAKuS,GAAU3P,EACR2P,EAAS,IAwBlB4B,OAAOzT,UAAUo5B,cAAgB,SAAUl3B,EAAO2P,EAAQyjB,GACxD,MAAOS,aAAYz2B,KAAM4C,EAAO2P,GAAQ,EAAMyjB,IAGhD7hB,OAAOzT,UAAUq5B,cAAgB,SAAUn3B,EAAO2P,EAAQyjB,GACxD,MAAOS,aAAYz2B,KAAM4C,EAAO2P,GAAQ,EAAOyjB,IAuBjD7hB,OAAOzT,UAAUs5B,cAAgB,SAAUp3B,EAAO2P,EAAQyjB,GACxD,MAAOW,aAAY32B,KAAM4C,EAAO2P,GAAQ,EAAMyjB,IAGhD7hB,OAAOzT,UAAUu5B,cAAgB,SAAUr3B,EAAO2P,EAAQyjB,GACxD,MAAOW,aAAY32B,KAAM4C,EAAO2P,GAAQ,EAAOyjB,IAGjD7hB,OAAOzT,UAAUszB,UAAY,SAAUpxB,EAAO2P,EAAQyjB,GAQpD,MAPKA,KACH3B,OAAiBn0B,SAAV0C,GAAiC,OAAVA,EAAgB,iBAC9CyxB,OAAkBn0B,SAAXqS,GAAmC,OAAXA,EAAiB,kBAChD8hB,OAAO9hB,EAASvS,KAAKsI,OAAQ,wCAC7BuuB,UAAUj0B,EAAO,IAAM,OAGrB2P,GAAUvS,KAAKsI,OAAnB,QAGI1F,GAAS,EACX5C,KAAKg5B,WAAWp2B,EAAO2P,EAAQyjB,GAE/Bh2B,KAAKg5B,WAAW,IAAOp2B,EAAQ,EAAG2P,EAAQyjB,GACrCzjB,EAAS,IAuBlB4B,OAAOzT,UAAUw5B,aAAe,SAAUt3B,EAAO2P,EAAQyjB,GACvD,MAAOY,YAAW52B,KAAM4C,EAAO2P,GAAQ,EAAMyjB,IAG/C7hB,OAAOzT,UAAUy5B,aAAe,SAAUv3B,EAAO2P,EAAQyjB,GACvD,MAAOY,YAAW52B,KAAM4C,EAAO2P,GAAQ,EAAOyjB,IAuBhD7hB,OAAOzT,UAAU05B,aAAe,SAAUx3B,EAAO2P,EAAQyjB,GACvD,MAAOc,YAAW92B,KAAM4C,EAAO2P,GAAQ,EAAMyjB,IAG/C7hB,OAAOzT,UAAU25B,aAAe,SAAUz3B,EAAO2P,EAAQyjB,GACvD,MAAOc,YAAW92B,KAAM4C,EAAO2P,GAAQ,EAAOyjB,IAoBhD7hB,OAAOzT,UAAU45B,aAAe,SAAU13B,EAAO2P,EAAQyjB,GACvD,MAAOe,YAAW/2B,KAAM4C,EAAO2P,GAAQ,EAAMyjB,IAG/C7hB,OAAOzT,UAAU65B,aAAe,SAAU33B,EAAO2P,EAAQyjB,GACvD,MAAOe,YAAW/2B,KAAM4C,EAAO2P,GAAQ,EAAOyjB,IAqBhD7hB,OAAOzT,UAAU85B,cAAgB,SAAU53B,EAAO2P,EAAQyjB,GACxD,MAAOiB,aAAYj3B,KAAM4C,EAAO2P,GAAQ,EAAMyjB,IAGhD7hB,OAAOzT,UAAU+5B,cAAgB,SAAU73B,EAAO2P,EAAQyjB,GACxD,MAAOiB,aAAYj3B,KAAM4C,EAAO2P,GAAQ,EAAOyjB,IAIjD7hB,OAAOzT,UAAUg6B,KAAO,SAAU93B,EAAOme,EAAOC,GAQ9C,GAPKpe,IAAOA,EAAQ,GACfme,IAAOA,EAAQ,GACfC,IAAKA,EAAMhhB,KAAKsI,QAErB+rB,OAAOrT,GAAOD,EAAO,eAGjBC,IAAQD,GACQ,IAAhB/gB,KAAKsI,OAAT,CAEA+rB,OAAOtT,GAAS,GAAKA,EAAQ/gB,KAAKsI,OAAQ,uBAC1C+rB,OAAOrT,GAAO,GAAKA,GAAOhhB,KAAKsI,OAAQ,oBAEvC,IAAIhF,EACJ,IAAqB,gBAAVV,GACT,IAAKU,EAAIyd,EAAWC,EAAJ1d,EAASA,IACvBtD,KAAKsD,GAAKV,MAEP,CACL,GAAIizB,GAAQnB,YAAY9xB,EAAMwR,YAC1BtG,EAAM+nB,EAAMvtB,MAChB,KAAKhF,EAAIyd,EAAWC,EAAJ1d,EAASA,IACvBtD,KAAKsD,GAAKuyB,EAAMvyB,EAAIwK,GAIxB,MAAO9N,QAGTmU,OAAOzT,UAAUi6B,QAAU,WAGzB,IAAK,GAFDjpB,MACA5D,EAAM9N,KAAKsI,OACNhF,EAAI,EAAOwK,EAAJxK,EAASA,IAEvB,GADAoO,EAAIpO,GAAKqyB,MAAM31B,KAAKsD,IAChBA,IAAM1D,QAAQi4B,kBAAmB,CACnCnmB,EAAIpO,EAAI,GAAK,KACb,OAGJ,MAAO,WAAaoO,EAAIoG,KAAK,KAAO,KAOtC3D,OAAOzT,UAAUk6B,cAAgB,WAC/B,GAA0B,mBAAf3H,YAA4B,CACrC,GAAI9e,OAAOsf,gBACT,MAAO,IAAKtf,QAAOnU,MAAO66B,MAG1B,KAAK,GADDvoB,GAAM,GAAI2gB,YAAWjzB,KAAKsI,QACrBhF,EAAI,EAAGwK,EAAMwE,EAAIhK,OAAYwF,EAAJxK,EAASA,GAAK,EAC9CgP,EAAIhP,GAAKtD,KAAKsD,EAEhB,OAAOgP,GAAIuoB,OAGb,KAAM,IAAI15B,OAAM,sDAOpB,IAAI25B,IAAK3mB,OAAOzT,SAKhByT,QAAOuf,SAAW,SAAUzH,GAmD1B,MAlDAA,GAAI0H,WAAY,EAGhB1H,EAAI8O,KAAO9O,EAAItoB,IACfsoB,EAAI2H,KAAO3H,EAAInW,IAGfmW,EAAItoB,IAAMm3B,GAAGn3B,IACbsoB,EAAInW,IAAMglB,GAAGhlB,IAEbmW,EAAIgI,MAAQ6G,GAAG7G,MACfhI,EAAI7X,SAAW0mB,GAAG1mB,SAClB6X,EAAI+O,eAAiBF,GAAG1mB,SACxB6X,EAAIyM,OAASoC,GAAGpC,OAChBzM,EAAI2M,OAASkC,GAAGlC,OAChB3M,EAAIsM,QAAUuC,GAAGvC,QACjBtM,EAAIqM,KAAOwC,GAAGxC,KACdrM,EAAI9d,MAAQ2sB,GAAG3sB,MACf8d,EAAI8H,UAAY+G,GAAG/G,UACnB9H,EAAIgN,aAAe6B,GAAG7B,aACtBhN,EAAIiN,aAAe4B,GAAG5B,aACtBjN,EAAIkN,aAAe2B,GAAG3B,aACtBlN,EAAImN,aAAe0B,GAAG1B,aACtBnN,EAAIoN,SAAWyB,GAAGzB,SAClBpN,EAAIqN,YAAcwB,GAAGxB,YACrBrN,EAAIsN,YAAcuB,GAAGvB,YACrBtN,EAAIuN,YAAcsB,GAAGtB,YACrBvN,EAAIwN,YAAcqB,GAAGrB,YACrBxN,EAAIyN,YAAcoB,GAAGpB,YACrBzN,EAAI0N,YAAcmB,GAAGnB,YACrB1N,EAAI2N,aAAekB,GAAGlB,aACtB3N,EAAI4N,aAAeiB,GAAGjB,aACtB5N,EAAI+M,WAAa8B,GAAG9B,WACpB/M,EAAI6N,cAAgBgB,GAAGhB,cACvB7N,EAAI8N,cAAgBe,GAAGf,cACvB9N,EAAI+N,cAAgBc,GAAGd,cACvB/N,EAAIgO,cAAgBa,GAAGb,cACvBhO,EAAI+H,UAAY8G,GAAG9G,UACnB/H,EAAIiO,aAAeY,GAAGZ,aACtBjO,EAAIkO,aAAeW,GAAGX,aACtBlO,EAAImO,aAAeU,GAAGV,aACtBnO,EAAIoO,aAAeS,GAAGT,aACtBpO,EAAIqO,aAAeQ,GAAGR,aACtBrO,EAAIsO,aAAeO,GAAGP,aACtBtO,EAAIuO,cAAgBM,GAAGN,cACvBvO,EAAIwO,cAAgBK,GAAGL,cACvBxO,EAAIyO,KAAOI,GAAGJ,KACdzO,EAAI0O,QAAUG,GAAGH,QACjB1O,EAAI2O,cAAgBE,GAAGF,cAEhB3O;;AOt/BT,GAAIsQ,QAAS,oEAEX,WACD,YAaA,SAASttB,GAAQutB,GAChB,GAAI34B,GAAO24B,EAAIxW,WAAW,EAC1B,OAAIniB,KAAS44B,EACL,GACJ54B,IAAS64B,EACL,GACGC,EAAP94B,EACI,GACG84B,EAAS,GAAhB94B,EACIA,EAAO84B,EAAS,GAAK,GAClBC,EAAQ,GAAf/4B,EACIA,EAAO+4B,EACJC,EAAQ,GAAfh5B,EACIA,EAAOg5B,EAAQ,GADvB,OAID,QAASC,GAAgB7N,GAuBxB,QAASjqB,GAAMoU,GACd6S,EAAI8Q,KAAO3jB,EAvBZ,GAAI9V,GAAGgiB,EAAG5M,EAAGoT,EAAKkR,EAAc/Q,CAEhC,IAAIgD,EAAI3mB,OAAS,EAAI,EACpB,KAAM,IAAInH,OAAM,iDAQjB,IAAI2M,GAAMmhB,EAAI3mB,MACd00B,GAAe,MAAQ/N,EAAIvI,OAAO5Y,EAAM,GAAK,EAAI,MAAQmhB,EAAIvI,OAAO5Y,EAAM,GAAK,EAAI,EAGnFme,EAAM,GAAIgR,GAAiB,EAAbhO,EAAI3mB,OAAa,EAAI00B,GAGnCtkB,EAAIskB,EAAe,EAAI/N,EAAI3mB,OAAS,EAAI2mB,EAAI3mB,MAE5C,IAAIy0B,GAAI,CAMR,KAAKz5B,EAAI,EAAGgiB,EAAI,EAAO5M,EAAJpV,EAAOA,GAAK,EAAGgiB,GAAK,EACtCwG,EAAO7c,EAAOggB,EAAIvI,OAAOpjB,KAAO,GAAO2L,EAAOggB,EAAIvI,OAAOpjB,EAAI,KAAO,GAAO2L,EAAOggB,EAAIvI,OAAOpjB,EAAI,KAAO,EAAK2L,EAAOggB,EAAIvI,OAAOpjB,EAAI,IACnI0B,GAAY,SAAN8mB,IAAmB,IACzB9mB,GAAY,MAAN8mB,IAAiB,GACvB9mB,EAAW,IAAN8mB,EAYN,OATqB,KAAjBkR,GACHlR,EAAO7c,EAAOggB,EAAIvI,OAAOpjB,KAAO,EAAM2L,EAAOggB,EAAIvI,OAAOpjB,EAAI,KAAO,EACnE0B,EAAW,IAAN8mB,IACsB,IAAjBkR,IACVlR,EAAO7c,EAAOggB,EAAIvI,OAAOpjB,KAAO,GAAO2L,EAAOggB,EAAIvI,OAAOpjB,EAAI,KAAO,EAAM2L,EAAOggB,EAAIvI,OAAOpjB,EAAI,KAAO,EACvG0B,EAAM8mB,GAAO,EAAK,KAClB9mB,EAAW,IAAN8mB,IAGCG,EAGR,QAASiR,GAAeC,GAMvB,QAASj4B,GAAQ+jB,GAChB,MAAOsT,QAAO7V,OAAOuC,GAGtB,QAASmU,GAAiBnU,GACzB,MAAO/jB,GAAO+jB,GAAO,GAAK,IAAQ/jB,EAAO+jB,GAAO,GAAK,IAAQ/jB,EAAO+jB,GAAO,EAAI,IAAQ/jB,EAAa,GAAN+jB,GAV/F,GAAI3lB,GAGHynB,EAAMziB,EAFN+0B,EAAaF,EAAM70B,OAAS,EAC5Bg1B,EAAS,EAYV,KAAKh6B,EAAI,EAAGgF,EAAS60B,EAAM70B,OAAS+0B,EAAgB/0B,EAAJhF,EAAYA,GAAK,EAChEynB,GAAQoS,EAAM75B,IAAM,KAAO65B,EAAM75B,EAAI,IAAM,GAAM65B,EAAM75B,EAAI,GAC3Dg6B,GAAUF,EAAgBrS,EAI3B,QAAQsS,GACP,IAAK,GACJtS,EAAOoS,EAAMA,EAAM70B,OAAS,GAC5Bg1B,GAAUp4B,EAAO6lB,GAAQ,GACzBuS,GAAUp4B,EAAQ6lB,GAAQ,EAAK,IAC/BuS,GAAU,IACV,MACD,KAAK,GACJvS,GAAQoS,EAAMA,EAAM70B,OAAS,IAAM,GAAM60B,EAAMA,EAAM70B,OAAS,GAC9Dg1B,GAAUp4B,EAAO6lB,GAAQ,IACzBuS,GAAUp4B,EAAQ6lB,GAAQ,EAAK,IAC/BuS,GAAUp4B,EAAQ6lB,GAAQ,EAAK,IAC/BuS,GAAU,IAIZ,MAAOA,GA9GP,GAAIL,GAA6B,mBAAfhK,YACdA,WACA5tB,MAGDo3B,GADS,IAAIzW,WAAW,GACf,IAAIA,WAAW,IACxB0W,EAAS,IAAI1W,WAAW,GACxB2W,EAAS,IAAI3W,WAAW,GACxB6W,EAAS,IAAI7W,WAAW,GACxB4W,EAAS,IAAI5W,WAAW,EAwG5BrmB,QAAOC,QAAQ43B,YAAcsF,EAC7Bn9B,OAAOC,QAAQw1B,cAAgB8H;;ADvHhCt9B,QAAQ22B,KAAO,SAASsE,EAAQtoB,EAAQopB,EAAMC,EAAMC,GAClD,GAAIngB,GAAGrN,EACHytB,EAAgB,EAATD,EAAaD,EAAO,EAC3BG,GAAQ,GAAKD,GAAQ,EACrBE,EAAQD,GAAQ,EAChBE,EAAQ,GACR34B,EAAIq4B,EAAQE,EAAS,EAAK,EAC1BzW,EAAIuW,EAAO,GAAK,EAChBtpB,EAAIwoB,EAAOtoB,EAASjP,EAOxB,KALAA,GAAK8hB,EAEL1J,EAAIrJ,GAAM,IAAO4pB,GAAU,EAC3B5pB,KAAQ4pB,EACRA,GAASH,EACFG,EAAQ,EAAGvgB,EAAQ,IAAJA,EAAUmf,EAAOtoB,EAASjP,GAAIA,GAAK8hB,EAAG6W,GAAS,GAKrE,IAHA5tB,EAAIqN,GAAM,IAAOugB,GAAU,EAC3BvgB,KAAQugB,EACRA,GAASL,EACFK,EAAQ,EAAG5tB,EAAQ,IAAJA,EAAUwsB,EAAOtoB,EAASjP,GAAIA,GAAK8hB,EAAG6W,GAAS,GAErE,GAAU,IAANvgB,EACFA,EAAI,EAAIsgB,MACH,CAAA,GAAItgB,IAAMqgB,EACf,MAAO1tB,GAAI6tB,IAAsBC,KAAd9pB,EAAI,GAAK,EAE5BhE,IAAQlO,KAAK4W,IAAI,EAAG6kB,GACpBlgB,GAAQsgB,EAEV,OAAQ3pB,EAAI,GAAK,GAAKhE,EAAIlO,KAAK4W,IAAI,EAAG2E,EAAIkgB,IAG5Ch8B,QAAQq0B,MAAQ,SAAS4G,EAAQj4B,EAAO2P,EAAQopB,EAAMC,EAAMC,GAC1D,GAAIngB,GAAGrN,EAAG9I,EACNu2B,EAAgB,EAATD,EAAaD,EAAO,EAC3BG,GAAQ,GAAKD,GAAQ,EACrBE,EAAQD,GAAQ,EAChBK,EAAe,KAATR,EAAcz7B,KAAK4W,IAAI,EAAG,KAAO5W,KAAK4W,IAAI,EAAG,KAAO,EAC1DzT,EAAIq4B,EAAO,EAAKE,EAAS,EACzBzW,EAAIuW,EAAO,EAAI,GACftpB,EAAY,EAARzP,GAAwB,IAAVA,GAA2B,EAAZ,EAAIA,EAAa,EAAI,CAmC1D,KAjCAA,EAAQzC,KAAKk8B,IAAIz5B,GAEb+K,MAAM/K,IAAoBu5B,MAAVv5B,GAClByL,EAAIV,MAAM/K,GAAS,EAAI,EACvB8Y,EAAIqgB,IAEJrgB,EAAIvb,KAAKqjB,MAAMrjB,KAAKyD,IAAIhB,GAASzC,KAAKm8B,KAClC15B,GAAS2C,EAAIpF,KAAK4W,IAAI,GAAI2E,IAAM,IAClCA,IACAnW,GAAK,GAGL3C,GADE8Y,EAAIsgB,GAAS,EACNI,EAAK72B,EAEL62B,EAAKj8B,KAAK4W,IAAI,EAAG,EAAIilB,GAE5Bp5B,EAAQ2C,GAAK,IACfmW,IACAnW,GAAK,GAGHmW,EAAIsgB,GAASD,GACf1tB,EAAI,EACJqN,EAAIqgB,GACKrgB,EAAIsgB,GAAS,GACtB3tB,GAAKzL,EAAQ2C,EAAI,GAAKpF,KAAK4W,IAAI,EAAG6kB,GAClClgB,GAAQsgB,IAER3tB,EAAIzL,EAAQzC,KAAK4W,IAAI,EAAGilB,EAAQ,GAAK77B,KAAK4W,IAAI,EAAG6kB,GACjDlgB,EAAI,IAIDkgB,GAAQ,EAAGf,EAAOtoB,EAASjP,GAAS,IAAJ+K,EAAU/K,GAAK8hB,EAAG/W,GAAK,IAAKutB,GAAQ,GAI3E,IAFAlgB,EAAKA,GAAKkgB,EAAQvtB,EAClBytB,GAAQF,EACDE,EAAO,EAAGjB,EAAOtoB,EAASjP,GAAS,IAAJoY,EAAUpY,GAAK8hB,EAAG1J,GAAK,IAAKogB,GAAQ,GAE1EjB,EAAOtoB,EAASjP,EAAI8hB,IAAU,IAAJ/S;;ArB7D5B,QAAS7K,gBACPxH,KAAKiN,QAAUjN,KAAKiN,YACpBjN,KAAKkN,cAAgBlN,KAAKkN,eAAiBhN,OAyQ7C,QAASiN,YAAWC,GAClB,MAAsB,kBAARA,GAGhB,QAASC,UAASD,GAChB,MAAsB,gBAARA,GAGhB,QAASE,UAASF,GAChB,MAAsB,gBAARA,IAA4B,OAARA,EAGpC,QAASG,aAAYH,GACnB,MAAe,UAARA,EApRTzN,OAAOC,QAAU4H,aAGjBA,aAAaA,aAAeA,aAE5BA,aAAa9G,UAAUuM,QAAU/M,OACjCsH,aAAa9G,UAAUwM,cAAgBhN,OAIvCsH,aAAagG,oBAAsB,GAInChG,aAAa9G,UAAU+M,gBAAkB,SAASC,GAChD,IAAKL,SAASK,IAAU,EAAJA,GAASC,MAAMD,GACjC,KAAMV,WAAU,8BAElB,OADAhN,MAAKkN,cAAgBQ,EACd1N,MAGTwH,aAAa9G,UAAUQ,KAAO,SAASc,GACrC,GAAI4L,GAAIC,EAASC,EAAKC,EAAMzK,EAAG0K,CAM/B,IAJKhO,KAAKiN,UACRjN,KAAKiN,YAGM,UAATjL,KACGhC,KAAKiN,QAAQnM,OACbwM,SAAStN,KAAKiN,QAAQnM,SAAWd,KAAKiN,QAAQnM,MAAMwH,QAEvD,KADAsF,GAAKK,UAAU,GACXL,YAAczM,OACVyM,EAEAZ,UAAU,uCAQtB,IAFAa,EAAU7N,KAAKiN,QAAQjL,GAEnBuL,YAAYM,GACd,OAAO,CAET,IAAIV,WAAWU,GACb,OAAQI,UAAU3F,QAEhB,IAAK,GACHuF,EAAQ9N,KAAKC,KACb,MACF,KAAK,GACH6N,EAAQ9N,KAAKC,KAAMiO,UAAU,GAC7B,MACF,KAAK,GACHJ,EAAQ9N,KAAKC,KAAMiO,UAAU,GAAIA,UAAU,GAC3C,MAEF,SAGE,IAFAH,EAAMG,UAAU3F,OAChByF,EAAO,GAAI1I,OAAMyI,EAAM,GAClBxK,EAAI,EAAOwK,EAAJxK,EAASA,IACnByK,EAAKzK,EAAI,GAAK2K,UAAU3K,EAC1BuK,GAAQK,MAAMlO,KAAM+N,OAEnB,IAAIT,SAASO,GAAU,CAG5B,IAFAC,EAAMG,UAAU3F,OAChByF,EAAO,GAAI1I,OAAMyI,EAAM,GAClBxK,EAAI,EAAOwK,EAAJxK,EAASA,IACnByK,EAAKzK,EAAI,GAAK2K,UAAU3K,EAI1B,KAFA0K,EAAYH,EAAQM,QACpBL,EAAME,EAAU1F,OACXhF,EAAI,EAAOwK,EAAJxK,EAASA,IACnB0K,EAAU1K,GAAG4K,MAAMlO,KAAM+N,GAG7B,OAAO,GAGTvG,aAAa9G,UAAUoI,YAAc,SAAS9G,EAAMoM,GAClD,GAAIC,EAEJ,KAAKlB,WAAWiB,GACd,KAAMpB,WAAU,8BAuBlB,IArBKhN,KAAKiN,UACRjN,KAAKiN,YAIHjN,KAAKiN,QAAQqB,aACftO,KAAKkB,KAAK,cAAec,EACfmL,WAAWiB,EAASA,UACpBA,EAASA,SAAWA,GAE3BpO,KAAKiN,QAAQjL,GAGTsL,SAAStN,KAAKiN,QAAQjL,IAE7BhC,KAAKiN,QAAQjL,GAAMgD,KAAKoJ,GAGxBpO,KAAKiN,QAAQjL,IAAShC,KAAKiN,QAAQjL,GAAOoM,GAN1CpO,KAAKiN,QAAQjL,GAAQoM,EASnBd,SAAStN,KAAKiN,QAAQjL,MAAWhC,KAAKiN,QAAQjL,GAAMuM,OAAQ,CAC9D,GAAIF,EAIFA,GAHGd,YAAYvN,KAAKkN,eAGhB1F,aAAagG,oBAFbxN,KAAKkN,cAKPmB,GAAKA,EAAI,GAAKrO,KAAKiN,QAAQjL,GAAMsG,OAAS+F,IAC5CrO,KAAKiN,QAAQjL,GAAMuM,QAAS,EAC5BxN,QAAQD,MAAM,mIAGAd,KAAKiN,QAAQjL,GAAMsG,QACJ,kBAAlBvH,SAAQyN,OAEjBzN,QAAQyN,SAKd,MAAOxO,OAGTwH,aAAa9G,UAAU4F,GAAKkB,aAAa9G,UAAUoI,YAEnDtB,aAAa9G,UAAUqI,KAAO,SAAS/G,EAAMoM,GAM3C,QAASK,KACPzO,KAAKiJ,eAAejH,EAAMyM,GAErBC,IACHA,GAAQ,EACRN,EAASF,MAAMlO,KAAMiO,YAVzB,IAAKd,WAAWiB,GACd,KAAMpB,WAAU,8BAElB,IAAI0B,IAAQ,CAcZ,OAHAD,GAAEL,SAAWA,EACbpO,KAAKsG,GAAGtE,EAAMyM,GAEPzO,MAITwH,aAAa9G,UAAUuI,eAAiB,SAASjH,EAAMoM,GACrD,GAAIO,GAAMC,EAAUtG,EAAQhF,CAE5B,KAAK6J,WAAWiB,GACd,KAAMpB,WAAU,8BAElB,KAAKhN,KAAKiN,UAAYjN,KAAKiN,QAAQjL,GACjC,MAAOhC,KAMT,IAJA2O,EAAO3O,KAAKiN,QAAQjL,GACpBsG,EAASqG,EAAKrG,OACdsG,EAAW,GAEPD,IAASP,GACRjB,WAAWwB,EAAKP,WAAaO,EAAKP,WAAaA,QAC3CpO,MAAKiN,QAAQjL,GAChBhC,KAAKiN,QAAQhE,gBACfjJ,KAAKkB,KAAK,iBAAkBc,EAAMoM,OAE/B,IAAId,SAASqB,GAAO,CACzB,IAAKrL,EAAIgF,EAAQhF,IAAM,GACrB,GAAIqL,EAAKrL,KAAO8K,GACXO,EAAKrL,GAAG8K,UAAYO,EAAKrL,GAAG8K,WAAaA,EAAW,CACvDQ,EAAWtL,CACX,OAIJ,GAAe,EAAXsL,EACF,MAAO5O,KAEW,KAAhB2O,EAAKrG,QACPqG,EAAKrG,OAAS,QACPtI,MAAKiN,QAAQjL,IAEpB2M,EAAK9I,OAAO+I,EAAU,GAGpB5O,KAAKiN,QAAQhE,gBACfjJ,KAAKkB,KAAK,iBAAkBc,EAAMoM,GAGtC,MAAOpO,OAGTwH,aAAa9G,UAAUwI,mBAAqB,SAASlH,GACnD,GAAI6M,GAAKb,CAET,KAAKhO,KAAKiN,QACR,MAAOjN,KAGT,KAAKA,KAAKiN,QAAQhE,eAKhB,MAJyB,KAArBgF,UAAU3F,OACZtI,KAAKiN,WACEjN,KAAKiN,QAAQjL,UACbhC,MAAKiN,QAAQjL,GACfhC,IAIT,IAAyB,IAArBiO,UAAU3F,OAAc,CAC1B,IAAKuG,IAAO7O,MAAKiN,QACH,mBAAR4B,GACJ7O,KAAKkJ,mBAAmB2F,EAI1B,OAFA7O,MAAKkJ,mBAAmB,kBACxBlJ,KAAKiN,WACEjN,KAKT,GAFAgO,EAAYhO,KAAKiN,QAAQjL,GAErBmL,WAAWa,GACbhO,KAAKiJ,eAAejH,EAAMgM,OAG1B,MAAOA,EAAU1F,QACftI,KAAKiJ,eAAejH,EAAMgM,EAAUA,EAAU1F,OAAS,GAI3D,cAFOtI,MAAKiN,QAAQjL,GAEbhC,MAGTwH,aAAa9G,UAAUsN,UAAY,SAAShM,GAC1C,GAAI8M,EAOJ,OAHEA,GAHG9O,KAAKiN,SAAYjN,KAAKiN,QAAQjL,GAE1BmL,WAAWnN,KAAKiN,QAAQjL,KACxBhC,KAAKiN,QAAQjL,IAEdhC,KAAKiN,QAAQjL,GAAMmM,YAI7B3G,aAAauH,cAAgB,SAASC,EAAShN,GAC7C,GAAI8M,EAOJ,OAHEA,GAHGE,EAAQ/B,SAAY+B,EAAQ/B,QAAQjL,GAEhCmL,WAAW6B,EAAQ/B,QAAQjL,IAC5B,EAEAgN,EAAQ/B,QAAQjL,GAAMsG,OAJtB;;A6B/PV,QAASolC,gBAAeC,EAAOC,GAG7B,IAAK,GADD9I,GAAK,EACAxhC,EAAIqqC,EAAMrlC,OAAS,EAAGhF,GAAK,EAAGA,IAAK,CAC1C,GAAIgV,GAAOq1B,EAAMrqC,EACJ,OAATgV,EACFq1B,EAAM9nC,OAAOvC,EAAG,GACE,OAATgV,GACTq1B,EAAM9nC,OAAOvC,EAAG,GAChBwhC,KACSA,IACT6I,EAAM9nC,OAAOvC,EAAG,GAChBwhC,KAKJ,GAAI8I,EACF,KAAO9I,IAAMA,EACX6I,EAAMlB,QAAQ,KAIlB,OAAOkB,GA+JT,QAASE,QAAQC,EAAI9lC,GACjB,GAAI8lC,EAAGD,OAAQ,MAAOC,GAAGD,OAAO7lC,EAEhC,KAAK,GADDstB,MACKhyB,EAAI,EAAGA,EAAIwqC,EAAGxlC,OAAQhF,IACvB0E,EAAE8lC,EAAGxqC,GAAIA,EAAGwqC,IAAKxY,EAAItwB,KAAK8oC,EAAGxqC,GAErC,OAAOgyB,GAhKX,GAAIyY,aACA,gEACAC,UAAY,SAASC,GACvB,MAAOF,aAAY5K,KAAK8K,GAAU9/B,MAAM,GAK1CvO,SAAQ+pC,QAAU,WAIhB,IAAK,GAHDuE,GAAe,GACfC,GAAmB,EAEd7qC,EAAI2K,UAAU3F,OAAS,EAAGhF,GAAK,KAAO6qC,EAAkB7qC,IAAK,CACpE,GAAImW,GAAQnW,GAAK,EAAK2K,UAAU3K,GAAKiE,QAAQ6B,KAG7C,IAAoB,gBAATqQ,GACT,KAAM,IAAIzM,WAAU,4CACVyM,KAIZy0B,EAAez0B,EAAO,IAAMy0B,EAC5BC,EAAsC,MAAnB10B,EAAKiN,OAAO,IAWjC,MAJAwnB,GAAeR,eAAeG,OAAOK,EAAatsB,MAAM,KAAM,SAAS2lB,GACrE,QAASA,KACN4G,GAAkBr2B,KAAK,MAEnBq2B,EAAmB,IAAM,IAAMD,GAAiB,KAK3DtuC,QAAQwuC,UAAY,SAAS30B,GAC3B,GAAIg0B,GAAa7tC,QAAQ6tC,WAAWh0B,GAChC40B,EAAqC,MAArBh6B,OAAOoF,EAAM,GAcjC,OAXAA,GAAOi0B,eAAeG,OAAOp0B,EAAKmI,MAAM,KAAM,SAAS2lB,GACrD,QAASA,KACNkG,GAAY31B,KAAK,KAEjB2B,GAASg0B,IACZh0B,EAAO,KAELA,GAAQ40B,IACV50B,GAAQ,MAGFg0B,EAAa,IAAM,IAAMh0B,GAInC7Z,QAAQ6tC,WAAa,SAASh0B,GAC5B,MAA0B,MAAnBA,EAAKiN,OAAO,IAIrB9mB,QAAQkY,KAAO,WACb,GAAIw2B,GAAQjpC,MAAM3E,UAAUyN,MAAMpO,KAAKkO,UAAW,EAClD,OAAOrO,SAAQwuC,UAAUP,OAAOS,EAAO,SAAS/G,GAC9C,GAAiB,gBAANA,GACT,KAAM,IAAIv6B,WAAU,yCAEtB,OAAOu6B,KACNzvB,KAAK,OAMVlY,QAAQ8pC,SAAW,SAASzmC,EAAMsrC,GAIhC,QAASrX,GAAKjL,GAEZ,IADA,GAAIlL,GAAQ,EACLA,EAAQkL,EAAI3jB,QACE,KAAf2jB,EAAIlL,GADiBA,KAK3B,IADA,GAAIC,GAAMiL,EAAI3jB,OAAS,EAChB0Y,GAAO,GACK,KAAbiL,EAAIjL,GADOA,KAIjB,MAAID,GAAQC,KACLiL,EAAI9d,MAAM4S,EAAOC,EAAMD,EAAQ,GAfxC9d,EAAOrD,QAAQ+pC,QAAQ1mC,GAAMoR,OAAO,GACpCk6B,EAAK3uC,QAAQ+pC,QAAQ4E,GAAIl6B,OAAO,EAsBhC,KAAK,GALDm6B,GAAYtX,EAAKj0B,EAAK2e,MAAM,MAC5B6sB,EAAUvX,EAAKqX,EAAG3sB,MAAM,MAExBtZ,EAASnI,KAAKC,IAAIouC,EAAUlmC,OAAQmmC,EAAQnmC,QAC5ComC,EAAkBpmC,EACbhF,EAAI,EAAOgF,EAAJhF,EAAYA,IAC1B,GAAIkrC,EAAUlrC,KAAOmrC,EAAQnrC,GAAI,CAC/BorC,EAAkBprC,CAClB,OAKJ,IAAK,GADDqrC,MACKrrC,EAAIorC,EAAiBprC,EAAIkrC,EAAUlmC,OAAQhF,IAClDqrC,EAAY3pC,KAAK,KAKnB,OAFA2pC,GAAcA,EAAYlpC,OAAOgpC,EAAQtgC,MAAMugC,IAExCC,EAAY72B,KAAK,MAG1BlY,QAAQgvC,IAAM,IACdhvC,QAAQivC,UAAY,IAEpBjvC,QAAQkvC,QAAU,SAASr1B,GACzB,GAAItU,GAAS6oC,UAAUv0B,GACnBs1B,EAAO5pC,EAAO,GACd6pC,EAAM7pC,EAAO,EAEjB,OAAK4pC,IAASC,GAKVA,IAEFA,EAAMA,EAAI36B,OAAO,EAAG26B,EAAI1mC,OAAS,IAG5BymC,EAAOC,GARL,KAYXpvC,QAAQqvC,SAAW,SAASx1B,EAAMy1B,GAChC,GAAIlnC,GAAIgmC,UAAUv0B,GAAM,EAKxB,OAHIy1B,IAAOlnC,EAAEqM,OAAO,GAAK66B,EAAI5mC,UAAY4mC,IACvClnC,EAAIA,EAAEqM,OAAO,EAAGrM,EAAEM,OAAS4mC,EAAI5mC,SAE1BN,GAITpI,QAAQuvC,QAAU,SAAS11B,GACzB,MAAOu0B,WAAUv0B,GAAM,GAazB,IAAIpF,QAA6B,MAApB,KAAKA,OAAO,IACnB,SAAUuE,EAAKmI,EAAOjT,GAAO,MAAO8K,GAAIvE,OAAO0M,EAAOjT,IACtD,SAAU8K,EAAKmI,EAAOjT,GAEpB,MADY,GAARiT,IAAWA,EAAQnI,EAAItQ,OAASyY,GAC7BnI,EAAIvE,OAAO0M,EAAOjT;;;;AlCjLjC,QAASjN,SA1CT,GAAI0G,SAAU5H,OAAOC,UAErB2H,SAAQG,SAAW,WACf,GAAIC,GAAoC,mBAAXC,SAC1BA,OAAOC,aACNC,EAA4B,mBAAXF,SAClBA,OAAOG,aAAeH,OAAO/F,gBAGhC,IAAI8F,EACA,MAAO,UAAUK,GAAK,MAAOJ,QAAOC,aAAaG,GAGrD,IAAIF,EAAS,CACT,GAAIG,KAYJ,OAXAL,QAAO/F,iBAAiB,UAAW,SAAUqG,GACzC,GAAIC,GAASD,EAAGC,MAChB,KAAKA,IAAWP,QAAqB,OAAXO,IAAgC,iBAAZD,EAAGE,OAC7CF,EAAGG,kBACCJ,EAAMK,OAAS,GAAG,CAClB,GAAIC,GAAKN,EAAMO,OACfD,QAGT,GAEI,SAAkBA,GACrBN,EAAMjD,KAAKuD,GACXX,OAAOG,YAAY,eAAgB,MAI3C,MAAO,UAAkBQ,GACrBE,WAAWF,EAAI,OAIvBhB,QAAQmB,MAAQ,UAChBnB,QAAQoB,SAAU,EAClBpB,QAAQqB,OACRrB,QAAQsB,QAIRtB,QAAQjB,GAAKzF,KACb0G,QAAQuB,YAAcjI,KACtB0G,QAAQwB,KAAOlI,KACf0G,QAAQyB,IAAMnI,KACd0G,QAAQ0B,eAAiBpI,KACzB0G,QAAQ2B,mBAAqBrI,KAC7B0G,QAAQrG,KAAOL,KAEf0G,QAAQ4B,QAAU,WACd,KAAM,IAAIhI,OAAM,qCAIpBoG,QAAQ6B,IAAM,WAAc,MAAO,KACnC7B,QAAQ8B,MAAQ,WACZ,KAAM,IAAIlI,OAAM;;CuC5DlB,SAAS4tC,GA2DV,QAASjuC,GAAMkB,GACd,KAAMwyC,YAAW7pC,EAAO3I,IAWzB,QAAS8P,GAAIqW,EAAO5f,GAEnB,IADA,GAAID,GAAS6f,EAAM7f,OACZA,KACN6f,EAAM7f,GAAUC,EAAG4f,EAAM7f,GAE1B,OAAO6f,GAYR,QAASssB,GAAUvuB,EAAQ3d,GAC1B,MAAOuJ,GAAIoU,EAAOtE,MAAM8yB,GAAkBnsC,GAAIuP,KAAK,KAgBpD,QAAS68B,GAAWzuB,GAMnB,IALA,GAGItjB,GACAgyC,EAJAtX,KACAuX,EAAU,EACVvsC,EAAS4d,EAAO5d,OAGHA,EAAVusC,GACNjyC,EAAQsjB,EAAOF,WAAW6uB,KACtBjyC,GAAS,OAAmB,OAATA,GAA6B0F,EAAVusC,GAEzCD,EAAQ1uB,EAAOF,WAAW6uB,KACF,QAAX,MAARD,GACJtX,EAAOt4B,OAAe,KAARpC,IAAkB,KAAe,KAARgyC,GAAiB,QAIxDtX,EAAOt4B,KAAKpC,GACZiyC,MAGDvX,EAAOt4B,KAAKpC,EAGd,OAAO06B,GAWR,QAASwX,GAAW3sB,GACnB,MAAOrW,GAAIqW,EAAO,SAASvlB,GAC1B,GAAI06B,GAAS,EAOb,OANI16B,GAAQ,QACXA,GAAS,MACT06B,GAAUyX,EAAmBnyC,IAAU,GAAK,KAAQ,OACpDA,EAAQ,MAAiB,KAARA,GAElB06B,GAAUyX,EAAmBnyC,KAE3BkV,KAAK,IAYT,QAASk9B,GAAaC,GACrB,MAAqB,IAAjBA,EAAY,GACRA,EAAY,GAEC,GAAjBA,EAAY,GACRA,EAAY,GAEC,GAAjBA,EAAY,GACRA,EAAY,GAEbrE,EAcR,QAASsE,GAAaC,EAAOC,GAG5B,MAAOD,GAAQ,GAAK,IAAc,GAARA,KAAwB,GAARC,IAAc,GAQzD,QAASC,GAAMC,EAAOC,EAAWC,GAChC,GAAIh8B,GAAI,CAGR,KAFA87B,EAAQE,EAAYhyB,EAAM8xB,EAAQG,GAAQH,GAAS,EACnDA,GAAS9xB,EAAM8xB,EAAQC,GACOD,EAAQI,EAAgBC,GAAQ,EAAGn8B,GAAKo3B,EACrE0E,EAAQ9xB,EAAM8xB,EAAQI,EAEvB,OAAOlyB,GAAMhK,GAAKk8B,EAAgB,GAAKJ,GAASA,EAAQM,IAUzD,QAAS3mC,GAAO0C,GAEf,GAEID,GAIAmkC,EACAvwB,EACApb,EACA4rC,EACAvyB,EACA/J,EACA27B,EACAlqB,EAEA8qB,EAfAzY,KACA0Y,EAAcrkC,EAAMrJ,OAEpBhF,EAAI,EACJoK,EAAIuoC,EACJC,EAAOC,CAqBX,KALAN,EAAQlkC,EAAMq6B,YAAY6C,GACd,EAARgH,IACHA,EAAQ,GAGJvwB,EAAI,EAAOuwB,EAAJvwB,IAAaA,EAEpB3T,EAAMqU,WAAWV,IAAM,KAC1BxkB,EAAM,aAEPw8B,EAAOt4B,KAAK2M,EAAMqU,WAAWV,GAM9B,KAAKpb,EAAQ2rC,EAAQ,EAAIA,EAAQ,EAAI,EAAWG,EAAR9rC,GAAgD,CAOvF,IAAK4rC,EAAOxyC,EAAGigB,EAAI,EAAG/J,EAAIo3B,EAErB1mC,GAAS8rC,GACZl1C,EAAM,iBAGPq0C,EAAQH,EAAarjC,EAAMqU,WAAW9b,OAElCirC,GAASvE,GAAQuE,EAAQ3xB,GAAO4yB,EAAS9yC,GAAKigB,KACjDziB,EAAM,YAGPwC,GAAK6xC,EAAQ5xB,EACb0H,EAASirB,GAAL18B,EAAY68B,EAAQ78B,GAAK08B,EAAOP,EAAOA,EAAOn8B,EAAI08B,IAE1CjrB,EAARkqB,GAf+C37B,GAAKo3B,EAmBxDmF,EAAanF,EAAO3lB,EAChB1H,EAAIC,EAAM4yB,EAASL,IACtBj1C,EAAM,YAGPyiB,GAAKwyB,CAINrkC,GAAM4rB,EAAOh1B,OAAS,EACtB4tC,EAAOb,EAAM/xC,EAAIwyC,EAAMpkC,EAAa,GAARokC,GAIxBtyB,EAAMlgB,EAAIoO,GAAO0kC,EAAS1oC,GAC7B5M,EAAM,YAGP4M,GAAK8V,EAAMlgB,EAAIoO,GACfpO,GAAKoO,EAGL4rB,EAAOz3B,OAAOvC,IAAK,EAAGoK,GAIvB,MAAOonC,GAAWxX,GAUnB,QAASp4B,GAAOyM,GACf,GAAIjE,GACA4nC,EACAgB,EACAC,EACAL,EACA5wB,EACAjX,EACAmoC,EACAh9B,EACAyR,EACAwrB,EAGAT,EAEAU,EACAX,EACAY,EANArZ,IAoBJ,KAXA3rB,EAAQgjC,EAAWhjC,GAGnBqkC,EAAcrkC,EAAMrJ,OAGpBoF,EAAIuoC,EACJX,EAAQ,EACRY,EAAOC,EAGF7wB,EAAI,EAAO0wB,EAAJ1wB,IAAmBA,EAC9BmxB,EAAe9kC,EAAM2T,GACF,IAAfmxB,GACHnZ,EAAOt4B,KAAK+vC,EAAmB0B,GAejC,KAXAH,EAAiBC,EAAcjZ,EAAOh1B,OAMlCiuC,GACHjZ,EAAOt4B,KAAK6pC,GAIWmH,EAAjBM,GAA8B,CAIpC,IAAKjoC,EAAI+nC,EAAQ9wB,EAAI,EAAO0wB,EAAJ1wB,IAAmBA,EAC1CmxB,EAAe9kC,EAAM2T,GACjBmxB,GAAgB/oC,GAAoBW,EAAfooC,IACxBpoC,EAAIooC,EAcN,KARAC,EAAwBJ,EAAiB,EACrCjoC,EAAIX,EAAI8V,GAAO4yB,EAASd,GAASoB,IACpC51C,EAAM,YAGPw0C,IAAUjnC,EAAIX,GAAKgpC,EACnBhpC,EAAIW,EAECiX,EAAI,EAAO0wB,EAAJ1wB,IAAmBA,EAO9B,GANAmxB,EAAe9kC,EAAM2T,GAEF5X,EAAf+oC,KAAsBnB,EAAQc,GACjCt1C,EAAM,YAGH21C,GAAgB/oC,EAAG,CAEtB,IAAK8oC,EAAIlB,EAAO97B,EAAIo3B,EACnB3lB,EAASirB,GAAL18B,EAAY68B,EAAQ78B,GAAK08B,EAAOP,EAAOA,EAAOn8B,EAAI08B,IAC9CjrB,EAAJurB,GAFyCh9B,GAAKo3B,EAKlD+F,EAAUH,EAAIvrB,EACd8qB,EAAanF,EAAO3lB,EACpBqS,EAAOt4B,KACN+vC,EAAmBG,EAAajqB,EAAI0rB,EAAUZ,EAAY,KAE3DS,EAAIhzB,EAAMmzB,EAAUZ,EAGrBzY,GAAOt4B,KAAK+vC,EAAmBG,EAAasB,EAAG,KAC/CN,EAAOb,EAAMC,EAAOoB,EAAuBJ,GAAkBC,GAC7DjB,EAAQ,IACNgB,IAIFhB,IACA5nC,EAGH,MAAO4vB,GAAOxlB,KAAK,IAapB,QAAS8+B,GAAUC,GAClB,MAAOpC,GAAUoC,EAAQ,SAAS3wB,GACjC,MAAO4wB,GAAcnf,KAAKzR,GACvBjX,EAAOiX,EAAO/X,MAAM,GAAGsE,eACvByT,IAYL,QAAS6wB,GAAQF,GAChB,MAAOpC,GAAUoC,EAAQ,SAAS3wB,GACjC,MAAO8wB,GAAcrf,KAAKzR,GACvB,OAAShhB,EAAOghB,GAChBA,IAhcL,GAAI+wB,GAAgC,gBAAXr3C,UAAuBA,QAC5Cs3C,EAA8B,gBAAVv3C,SAAsBA,QAC7CA,OAAOC,SAAWq3C,GAAet3C,OAC9Bw3C,EAA8B,gBAAVjiC,SAAsBA,QAC1CiiC,EAAWjiC,SAAWiiC,GAAcA,EAAWvvC,SAAWuvC,KAC7DpI,EAAOoI,EAQR,IAAInN,GAiCJn7B,EA9BAunC,EAAS,WAGTxF,EAAO,GACPyF,EAAO,EACPV,EAAO,GACPC,EAAO,GACPH,EAAO,IACPU,EAAc,GACdF,EAAW,IACXpH,EAAY,IAGZiI,EAAgB,QAChBE,EAAgB,SAChBtC,EAAkB,6BAGlB/pC,GACCysC,SAAY,kDACZC,YAAa,iDACbC,gBAAiB,iBAIlB5B,EAAgB9E,EAAOyF,EACvB7yB,EAAQrjB,KAAKqjB,MACbuxB,EAAqB3uB,OAAOC,YAub5B,IA3BA2jB,GAMCxO,QAAW,QAQX+b,MACCtoC,OAAU0lC,EACVzvC,OAAU4vC,GAEX7lC,OAAUA,EACV/J,OAAUA,EACV6xC,QAAWA,EACXH,UAAaA,GAOI,kBAAVY,SACc,gBAAdA,QAAOC,KACdD,OAAOC,IAEPD,OAAO,WAAY,WAClB,MAAOxN,SAEF,IAAIiN,IAAgBA,EAAYS,SACtC,GAAIR,EACHA,EAAWt3C,QAAUoqC,MAErB,KAAKn7B,IAAOm7B,GACXA,EAASzwB,eAAe1K,KAASooC,EAAYpoC,GAAOm7B,EAASn7B,QAI/DkgC,GAAK/E,SAAWA,GAGhBhqC;;;;AGreF,YAKA,SAASuZ,gBAAekuB,EAAK3V,GAC3B,MAAOpvB,QAAOhC,UAAU6Y,eAAexZ,KAAK0nC,EAAK3V,GAGnDnyB,OAAOC,QAAU,SAASm4C,EAAInJ,EAAKgJ,EAAI52C,GACrC4tC,EAAMA,GAAO,IACbgJ,EAAKA,GAAM,GACX,IAAInQ,KAEJ,IAAkB,gBAAPsQ,IAAiC,IAAdA,EAAGzvC,OAC/B,MAAOm/B,EAGT,IAAI2M,GAAS,KACb2D,GAAKA,EAAGn2B,MAAMgtB,EAEd,IAAIoJ,GAAU,GACVh3C,IAAsC,gBAApBA,GAAQg3C,UAC5BA,EAAUh3C,EAAQg3C,QAGpB,IAAIlqC,GAAMiqC,EAAGzvC,MAET0vC,GAAU,GAAKlqC,EAAMkqC,IACvBlqC,EAAMkqC,EAGR,KAAK,GAAI10C,GAAI,EAAOwK,EAAJxK,IAAWA,EAAG,CAC5B,GAEI20C,GAAMC,EAAM1+B,EAAGJ,EAFfiL,EAAI0zB,EAAGz0C,GAAGoP,QAAQ0hC,EAAQ,OAC1B3iC,EAAM4S,EAAEve,QAAQ8xC,EAGhBnmC,IAAO,GACTwmC,EAAO5zB,EAAEhQ,OAAO,EAAG5C,GACnBymC,EAAO7zB,EAAEhQ,OAAO5C,EAAM,KAEtBwmC,EAAO5zB,EACP6zB,EAAO,IAGT1+B,EAAIsO,mBAAmBmwB,GACvB7+B,EAAI0O,mBAAmBowB,GAElB3+B,eAAekuB,EAAKjuB,GAEdH,QAAQouB,EAAIjuB,IACrBiuB,EAAIjuB,GAAGxU,KAAKoU,GAEZquB,EAAIjuB,IAAMiuB,EAAIjuB,GAAIJ,GAJlBquB,EAAIjuB,GAAKJ,EAQb,MAAOquB,GAGT,IAAIpuB,SAAUhU,MAAMgU,SAAW,SAAUy0B,GACvC,MAA8C,mBAAvCprC,OAAOhC,UAAU0T,SAASrU,KAAK+tC;;AF7DxC,YAgDA,SAASh8B,KAAKg8B,EAAI9lC,GAChB,GAAI8lC,EAAGh8B,IAAK,MAAOg8B,GAAGh8B,IAAI9J,EAE1B,KAAK,GADDstB,MACKhyB,EAAI,EAAGA,EAAIwqC,EAAGxlC,OAAQhF,IAC7BgyB,EAAItwB,KAAKgD,EAAE8lC,EAAGxqC,GAAIA,GAEpB,OAAOgyB,GApDT,GAAIqiB,oBAAqB,SAASv+B,GAChC,aAAeA,IACb,IAAK,SACH,MAAOA,EAET,KAAK,UACH,MAAOA,GAAI,OAAS,OAEtB,KAAK,SACH,MAAOof,UAASpf,GAAKA,EAAI,EAE3B,SACE,MAAO,IAIbzZ,QAAOC,QAAU,SAAS6nC,EAAKmH,EAAKgJ,EAAI9iC,GAOtC,MANA85B,GAAMA,GAAO,IACbgJ,EAAKA,GAAM,IACC,OAARnQ,IACFA,EAAMvnC,QAGW,gBAARunC,GACF31B,IAAI+lC,WAAWpQ,GAAM,SAASjuB,GACnC,GAAIs+B,GAAKp+B,mBAAmBi+B,mBAAmBn+B,IAAMo+B,CACrD,OAAIv+B,SAAQouB,EAAIjuB,IACP1H,IAAI21B,EAAIjuB,GAAI,SAASJ,GAC1B,MAAO0+B,GAAKp+B,mBAAmBi+B,mBAAmBv+B,MACjDtB,KAAK82B,GAEDkJ,EAAKp+B,mBAAmBi+B,mBAAmBlQ,EAAIjuB,OAEvD1B,KAAK82B,GAIL95B,EACE4E,mBAAmBi+B,mBAAmB7iC,IAAS8iC,EAC/Cl+B,mBAAmBi+B,mBAAmBlQ,IAF3B,GAKpB,IAAIpuB,SAAUhU,MAAMgU,SAAW,SAAUy0B,GACvC,MAA8C,mBAAvCprC,OAAOhC,UAAU0T,SAASrU,KAAK+tC,IAYpC+J,WAAan1C,OAAO04B,MAAQ,SAAUqM,GACxC,GAAInS,KACJ,KAAK,GAAIzmB,KAAO44B,GACV/kC,OAAOhC,UAAU6Y,eAAexZ,KAAK0nC,EAAK54B,IAAMymB,EAAItwB,KAAK6J,EAE/D,OAAOymB;;AJnFT,YAEA11B,SAAQqP,OAASrP,QAAQ0L,MAAQ7L,QAAQ,YACzCG,QAAQsF,OAAStF,QAAQ4M,UAAY/M,QAAQ;;AH2B7C,QAASupC,OACPhpC,KAAKyyB,SAAW,KAChBzyB,KAAKipC,QAAU,KACfjpC,KAAKuf,KAAO,KACZvf,KAAKsmC,KAAO,KACZtmC,KAAKumC,KAAO,KACZvmC,KAAK2jC,SAAW,KAChB3jC,KAAKyxB,KAAO,KACZzxB,KAAK6Z,OAAS,KACd7Z,KAAK6jC,MAAQ,KACb7jC,KAAK4jC,SAAW,KAChB5jC,KAAKyZ,KAAO,KACZzZ,KAAKkpC,KAAO,KAqDd,QAASC,UAASp3B,EAAKq3B,EAAkBC,GACvC,GAAIt3B,GAAOzE,SAASyE,IAAQA,YAAei3B,KAAK,MAAOj3B,EAEvD,IAAImH,GAAI,GAAI8vB,IAEZ,OADA9vB,GAAE5N,MAAMyG,EAAKq3B,EAAkBC,GACxBnwB,EA6OT,QAASowB,WAAU7B,GAMjB,MADI8B,UAAS9B,KAAMA,EAAM0B,SAAS1B,IAC5BA,YAAeuB,KACdvB,EAAI+B,SADuBR,IAAItoC,UAAU8oC,OAAOzpC,KAAK0nC,GA4D9D,QAASgC,YAAWthC,EAAQuhC,GAC1B,MAAOP,UAAShhC,GAAQ,GAAO,GAAMwhC,QAAQD,GAO/C,QAASE,kBAAiBzhC,EAAQuhC,GAChC,MAAKvhC,GACEghC,SAAShhC,GAAQ,GAAO,GAAM0hC,cAAcH,GAD/BA,EAyRtB,QAASH,UAASn8B,GAChB,MAAsB,gBAARA,GAGhB,QAASE,UAASF,GAChB,MAAsB,gBAARA,IAA4B,OAARA,EAGpC,QAAS08B,QAAO18B,GACd,MAAe,QAARA,EAET,QAAS28B,mBAAkB38B,GACzB,MAAe,OAAPA,EA5qBV,GAAI48B,UAAWvqC,QAAQ,WAEvBG,SAAQ0L,MAAQ69B,SAChBvpC,QAAQ+pC,QAAUF,WAClB7pC,QAAQiqC,cAAgBD,iBACxBhqC,QAAQ4pC,OAASF,UAEjB1pC,QAAQopC,IAAMA,GAqBd,IAAIiB,iBAAkB,oBAClBC,YAAc,WAIdC,QAAU,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAG/CC,QAAU,IAAK,IAAK,IAAK,KAAM,IAAK,KAAK3kC,OAAO0kC,QAGhDE,YAAc,KAAM5kC,OAAO2kC,QAK3BE,cAAgB,IAAK,IAAK,IAAK,IAAK,KAAK7kC,OAAO4kC,YAChDE,iBAAmB,IAAK,IAAK,KAC7BC,eAAiB,IACjBC,oBAAsB,wBACtBC,kBAAoB,8BAEpBC,gBACEC,YAAc,EACdC,eAAe,GAGjBC,kBACEF,YAAc,EACdC,eAAe,GAGjBE,iBACEC,MAAQ,EACRC,OAAS,EACTC,KAAO,EACPC,QAAU,EACVC,MAAQ,EACRC,SAAS,EACTC,UAAU,EACVC,QAAQ,EACRC,WAAW,EACXC,SAAS,GAEXvF,YAAczmC,QAAQ,cAU1BupC,KAAItoC,UAAU4K,MAAQ,SAASyG,EAAKq3B,EAAkBC,GACpD,IAAKE,SAASx3B,GACZ,KAAM,IAAI/E,WAAU,+CAAkD+E,GAGxE,IAAI25B,GAAO35B,CAIX25B,GAAOA,EAAKxU,MAEZ,IAAIyU,GAAQ1B,gBAAgB9G,KAAKuI,EACjC,IAAIC,EAAO,CACTA,EAAQA,EAAM,EACd,IAAIC,GAAaD,EAAMl5B,aACvBzS,MAAKyyB,SAAWmZ,EAChBF,EAAOA,EAAKr3B,OAAOs3B,EAAMrjC,QAO3B,GAAI+gC,GAAqBsC,GAASD,EAAK1yB,MAAM,wBAAyB,CACpE,GAAIiwB,GAAgC,OAAtByC,EAAKr3B,OAAO,EAAG,IACzB40B,GAAa0C,GAASb,iBAAiBa,KACzCD,EAAOA,EAAKr3B,OAAO,GACnBrU,KAAKipC,SAAU,GAInB,IAAK6B,iBAAiBa,KACjB1C,GAAY0C,IAAUZ,gBAAgBY,IAAU,CAmBnD,IAAK,GADDE,GAAU,GACLvoC,EAAI,EAAGA,EAAIinC,gBAAgBjiC,OAAQhF,IAAK,CAC/C,GAAIwoC,GAAMJ,EAAK5lC,QAAQykC,gBAAgBjnC,GAC3B,MAARwoC,IAA2B,KAAZD,GAAwBA,EAANC,KACnCD,EAAUC,GAKd,GAAIvsB,GAAMwsB,CAGRA,GAFc,KAAZF,EAEOH,EAAKM,YAAY,KAIjBN,EAAKM,YAAY,IAAKH,GAKlB,KAAXE,IACFxsB,EAAOmsB,EAAKv9B,MAAM,EAAG49B,GACrBL,EAAOA,EAAKv9B,MAAM49B,EAAS,GAC3B/rC,KAAKuf,KAAOuI,mBAAmBvI,IAIjCssB,EAAU,EACV,KAAK,GAAIvoC,GAAI,EAAGA,EAAIgnC,aAAahiC,OAAQhF,IAAK,CAC5C,GAAIwoC,GAAMJ,EAAK5lC,QAAQwkC,aAAahnC,GACxB,MAARwoC,IAA2B,KAAZD,GAAwBA,EAANC,KACnCD,EAAUC,GAGE,KAAZD,IACFA,EAAUH,EAAKpjC,QAEjBtI,KAAKsmC,KAAOoF,EAAKv9B,MAAM,EAAG09B,GAC1BH,EAAOA,EAAKv9B,MAAM09B,GAGlB7rC,KAAKisC,YAILjsC,KAAK2jC,SAAW3jC,KAAK2jC,UAAY,EAIjC,IAAIuI,GAAoC,MAArBlsC,KAAK2jC,SAAS,IACe,MAA5C3jC,KAAK2jC,SAAS3jC,KAAK2jC,SAASr7B,OAAS,EAGzC,KAAK4jC,EAEH,IAAK,GADDC,GAAYnsC,KAAK2jC,SAAS/hB,MAAM,MAC3Bte,EAAI,EAAGoV,EAAIyzB,EAAU7jC,OAAYoQ,EAAJpV,EAAOA,IAAK,CAChD,GAAI8oC,GAAOD,EAAU7oC,EACrB,IAAK8oC,IACAA,EAAKpzB,MAAMyxB,qBAAsB,CAEpC,IAAK,GADD4B,GAAU,GACL/mB,EAAI,EAAG9L,EAAI4yB,EAAK9jC,OAAYkR,EAAJ8L,EAAOA,IAKpC+mB,GAJED,EAAKpmB,WAAWV,GAAK,IAIZ,IAEA8mB,EAAK9mB,EAIpB,KAAK+mB,EAAQrzB,MAAMyxB,qBAAsB,CACvC,GAAI6B,GAAaH,EAAUh+B,MAAM,EAAG7K,GAChCipC,EAAUJ,EAAUh+B,MAAM7K,EAAI,GAC9BkpC,EAAMJ,EAAKpzB,MAAM0xB,kBACjB8B,KACFF,EAAWtnC,KAAKwnC,EAAI,IACpBD,EAAQE,QAAQD,EAAI,KAElBD,EAAQjkC,SACVojC,EAAO,IAAMa,EAAQz0B,KAAK,KAAO4zB,GAEnC1rC,KAAK2jC,SAAW2I,EAAWx0B,KAAK,IAChC,SAaR,GANE9X,KAAK2jC,SADH3jC,KAAK2jC,SAASr7B,OAASkiC,eACT,GAGAxqC,KAAK2jC,SAASlxB,eAG3By5B,EAAc,CAOjB,IAAK,GAFDQ,GAAc1sC,KAAK2jC,SAAS/hB,MAAM,KAClC+qB,KACKrpC,EAAI,EAAGA,EAAIopC,EAAYpkC,SAAUhF,EAAG,CAC3C,GAAI+O,GAAIq6B,EAAYppC,EACpBqpC,GAAO3nC,KAAKqN,EAAE2G,MAAM,kBAChB,OAASgxB,SAAS9kC,OAAOmN,GAAKA,GAEpCrS,KAAK2jC,SAAWgJ,EAAO70B,KAAK,KAG9B,GAAIyvB,GAAIvnC,KAAKumC,KAAO,IAAMvmC,KAAKumC,KAAO,GAClClhB,EAAIrlB,KAAK2jC,UAAY,EACzB3jC,MAAKsmC,KAAOjhB,EAAIkiB,EAChBvnC,KAAKkpC,MAAQlpC,KAAKsmC,KAId4F,IACFlsC,KAAK2jC,SAAW3jC,KAAK2jC,SAAStvB,OAAO,EAAGrU,KAAK2jC,SAASr7B,OAAS,GAC/C,MAAZojC,EAAK,KACPA,EAAO,IAAMA,IAOnB,IAAKf,eAAeiB,GAKlB,IAAK,GAAItoC,GAAI,EAAGoV,EAAI2xB,WAAW/hC,OAAYoQ,EAAJpV,EAAOA,IAAK,CACjD,GAAIspC,GAAKvC,WAAW/mC,GAChBupC,EAAMnzB,mBAAmBkzB,EACzBC,KAAQD,IACVC,EAAM9kB,OAAO6kB,IAEflB,EAAOA,EAAK9pB,MAAMgrB,GAAI90B,KAAK+0B,GAM/B,GAAIpb,GAAOia,EAAK5lC,QAAQ,IACX,MAAT2rB,IAEFzxB,KAAKyxB,KAAOia,EAAKr3B,OAAOod,GACxBia,EAAOA,EAAKv9B,MAAM,EAAGsjB,GAEvB,IAAIqb,GAAKpB,EAAK5lC,QAAQ,IAoBtB,IAnBW,KAAPgnC,GACF9sC,KAAK6Z,OAAS6xB,EAAKr3B,OAAOy4B,GAC1B9sC,KAAK6jC,MAAQ6H,EAAKr3B,OAAOy4B,EAAK,GAC1B1D,IACFppC,KAAK6jC,MAAQqC,YAAY56B,MAAMtL,KAAK6jC,QAEtC6H,EAAOA,EAAKv9B,MAAM,EAAG2+B,IACZ1D,IAETppC,KAAK6Z,OAAS,GACd7Z,KAAK6jC,UAEH6H,IAAM1rC,KAAK4jC,SAAW8H,GACtBX,gBAAgBa,IAChB5rC,KAAK2jC,WAAa3jC,KAAK4jC,WACzB5jC,KAAK4jC,SAAW,KAId5jC,KAAK4jC,UAAY5jC,KAAK6Z,OAAQ,CAChC,GAAI0tB,GAAIvnC,KAAK4jC,UAAY,GACrBvxB,EAAIrS,KAAK6Z,QAAU,EACvB7Z,MAAKyZ,KAAO8tB,EAAIl1B,EAKlB,MADArS,MAAKkpC,KAAOlpC,KAAKwpC,SACVxpC,MAcTgpC,IAAItoC,UAAU8oC,OAAS,WACrB,GAAIjqB,GAAOvf,KAAKuf,MAAQ,EACpBA,KACFA,EAAO7F,mBAAmB6F,GAC1BA,EAAOA,EAAK7M,QAAQ,OAAQ,KAC5B6M,GAAQ,IAGV,IAAIkT,GAAWzyB,KAAKyyB,UAAY,GAC5BmR,EAAW5jC,KAAK4jC,UAAY,GAC5BnS,EAAOzxB,KAAKyxB,MAAQ,GACpB6U,GAAO,EACPzC,EAAQ,EAER7jC,MAAKsmC,KACPA,EAAO/mB,EAAOvf,KAAKsmC,KACVtmC,KAAK2jC,WACd2C,EAAO/mB,GAAuC,KAA/Bvf,KAAK2jC,SAAS79B,QAAQ,KACjC9F,KAAK2jC,SACL,IAAM3jC,KAAK2jC,SAAW,KACtB3jC,KAAKumC,OACPD,GAAQ,IAAMtmC,KAAKumC,OAInBvmC,KAAK6jC,OACLv2B,SAAStN,KAAK6jC,QACdnhC,OAAO04B,KAAKp7B,KAAK6jC,OAAOv7B,SAC1Bu7B,EAAQqC,YAAY15B,UAAUxM,KAAK6jC,OAGrC,IAAIhqB,GAAS7Z,KAAK6Z,QAAWgqB,GAAU,IAAMA,GAAW,EAsBxD,OApBIpR,IAAoC,MAAxBA,EAASpe,OAAO,MAAaoe,GAAY,KAIrDzyB,KAAKipC,WACHxW,GAAYsY,gBAAgBtY,KAAc6T,KAAS,GACvDA,EAAO,MAAQA,GAAQ,IACnB1C,GAAmC,MAAvBA,EAASld,OAAO,KAAYkd,EAAW,IAAMA,IACnD0C,IACVA,EAAO,IAGL7U,GAA2B,MAAnBA,EAAK/K,OAAO,KAAY+K,EAAO,IAAMA,GAC7C5X,GAA+B,MAArBA,EAAO6M,OAAO,KAAY7M,EAAS,IAAMA,GAEvD+pB,EAAWA,EAASlxB,QAAQ,QAAS,SAASsG,GAC5C,MAAOU,oBAAmBV,KAE5Ba,EAASA,EAAOnH,QAAQ,IAAK,OAEtB+f,EAAW6T,EAAO1C,EAAW/pB,EAAS4X,GAO/CuX,IAAItoC,UAAUipC,QAAU,SAASD,GAC/B,MAAO1pC,MAAK6pC,cAAcV,SAASO,GAAU,GAAO,IAAOF,UAQ7DR,IAAItoC,UAAUmpC,cAAgB,SAASH,GACrC,GAAIH,SAASG,GAAW,CACtB,GAAIqD,GAAM,GAAI/D,IACd+D,GAAIzhC,MAAMo+B,GAAU,GAAO,GAC3BA,EAAWqD,EAGb,GAAI5nC,GAAS,GAAI6jC,IAUjB,IATAtmC,OAAO04B,KAAKp7B,MAAMsF,QAAQ,SAASkU,GACjCrU,EAAOqU,GAAKxZ,KAAKwZ,IAChBxZ,MAIHmF,EAAOssB,KAAOiY,EAASjY,KAGD,KAAlBiY,EAASR,KAEX,MADA/jC,GAAO+jC,KAAO/jC,EAAOqkC,SACdrkC,CAIT,IAAIukC,EAAST,UAAYS,EAASjX,SAchC,MAZA/vB,QAAO04B,KAAKsO,GAAUpkC,QAAQ,SAASkU,GAC3B,aAANA,IACFrU,EAAOqU,GAAKkwB,EAASlwB,MAIrBuxB,gBAAgB5lC,EAAOstB,WACvBttB,EAAOw+B,WAAax+B,EAAOy+B,WAC7Bz+B,EAAOsU,KAAOtU,EAAOy+B,SAAW,KAGlCz+B,EAAO+jC,KAAO/jC,EAAOqkC,SACdrkC,CAGT,IAAIukC,EAASjX,UAAYiX,EAASjX,WAAattB,EAAOstB,SAAU,CAS9D,IAAKsY,gBAAgBrB,EAASjX,UAK5B,MAJA/vB,QAAO04B,KAAKsO,GAAUpkC,QAAQ,SAASkU,GACrCrU,EAAOqU,GAAKkwB,EAASlwB,KAEvBrU,EAAO+jC,KAAO/jC,EAAOqkC,SACdrkC,CAIT,IADAA,EAAOstB,SAAWiX,EAASjX,SACtBiX,EAASpD,MAASwE,iBAAiBpB,EAASjX,UAS/CttB,EAAOy+B,SAAW8F,EAAS9F,aAT+B,CAE1D,IADA,GAAIoJ,IAAWtD,EAAS9F,UAAY,IAAIhiB,MAAM,KACvCorB,EAAQ1kC,UAAYohC,EAASpD,KAAO0G,EAAQxkC,WAC9CkhC,EAASpD,OAAMoD,EAASpD,KAAO,IAC/BoD,EAAS/F,WAAU+F,EAAS/F,SAAW,IACzB,KAAfqJ,EAAQ,IAAWA,EAAQP,QAAQ,IACnCO,EAAQ1kC,OAAS,GAAG0kC,EAAQP,QAAQ,IACxCtnC,EAAOy+B,SAAWoJ,EAAQl1B,KAAK,KAWjC,GAPA3S,EAAO0U,OAAS6vB,EAAS7vB,OACzB1U,EAAO0+B,MAAQ6F,EAAS7F,MACxB1+B,EAAOmhC,KAAOoD,EAASpD,MAAQ,GAC/BnhC,EAAOoa,KAAOmqB,EAASnqB,KACvBpa,EAAOw+B,SAAW+F,EAAS/F,UAAY+F,EAASpD,KAChDnhC,EAAOohC,KAAOmD,EAASnD,KAEnBphC,EAAOy+B,UAAYz+B,EAAO0U,OAAQ,CACpC,GAAI0tB,GAAIpiC,EAAOy+B,UAAY,GACvBvxB,EAAIlN,EAAO0U,QAAU,EACzB1U,GAAOsU,KAAO8tB,EAAIl1B,EAIpB,MAFAlN,GAAO8jC,QAAU9jC,EAAO8jC,SAAWS,EAAST,QAC5C9jC,EAAO+jC,KAAO/jC,EAAOqkC,SACdrkC,EAGT,GAAI8nC,GAAe9nC,EAAOy+B,UAA0C,MAA9Bz+B,EAAOy+B,SAASld,OAAO,GACzDwmB,EACIxD,EAASpD,MACToD,EAAS9F,UAA4C,MAAhC8F,EAAS9F,SAASld,OAAO,GAElDymB,EAAcD,GAAYD,GACX9nC,EAAOmhC,MAAQoD,EAAS9F,SACvCwJ,EAAgBD,EAChBE,EAAUloC,EAAOy+B,UAAYz+B,EAAOy+B,SAAShiB,MAAM,SACnDorB,EAAUtD,EAAS9F,UAAY8F,EAAS9F,SAAShiB,MAAM,SACvD0rB,EAAYnoC,EAAOstB,WAAasY,gBAAgB5lC,EAAOstB,SA2B3D,IApBI6a,IACFnoC,EAAOw+B,SAAW,GAClBx+B,EAAOohC,KAAO,KACVphC,EAAOmhC,OACU,KAAf+G,EAAQ,GAAWA,EAAQ,GAAKloC,EAAOmhC,KACtC+G,EAAQZ,QAAQtnC,EAAOmhC,OAE9BnhC,EAAOmhC,KAAO,GACVoD,EAASjX,WACXiX,EAAS/F,SAAW,KACpB+F,EAASnD,KAAO,KACZmD,EAASpD,OACQ,KAAf0G,EAAQ,GAAWA,EAAQ,GAAKtD,EAASpD,KACxC0G,EAAQP,QAAQ/C,EAASpD,OAEhCoD,EAASpD,KAAO,MAElB6G,EAAaA,IAA8B,KAAfH,EAAQ,IAA4B,KAAfK,EAAQ,KAGvDH,EAEF/nC,EAAOmhC,KAAQoD,EAASpD,MAA0B,KAAlBoD,EAASpD,KAC3BoD,EAASpD,KAAOnhC,EAAOmhC,KACrCnhC,EAAOw+B,SAAY+F,EAAS/F,UAAkC,KAAtB+F,EAAS/F,SAC/B+F,EAAS/F,SAAWx+B,EAAOw+B,SAC7Cx+B,EAAO0U,OAAS6vB,EAAS7vB,OACzB1U,EAAO0+B,MAAQ6F,EAAS7F,MACxBwJ,EAAUL,MAEL,IAAIA,EAAQ1kC,OAGZ+kC,IAASA,MACdA,EAAQ72B,MACR62B,EAAUA,EAAQ5nC,OAAOunC,GACzB7nC,EAAO0U,OAAS6vB,EAAS7vB,OACzB1U,EAAO0+B,MAAQ6F,EAAS7F,UACnB,KAAKkG,kBAAkBL,EAAS7vB,QAAS,CAI9C,GAAIyzB,EAAW,CACbnoC,EAAOw+B,SAAWx+B,EAAOmhC,KAAO+G,EAAQ7kC,OAIxC,IAAI+kC,GAAapoC,EAAOmhC,MAAQnhC,EAAOmhC,KAAKxgC,QAAQ,KAAO,EAC1CX,EAAOmhC,KAAK1kB,MAAM,MAAO,CACtC2rB,KACFpoC,EAAOoa,KAAOguB,EAAW/kC,QACzBrD,EAAOmhC,KAAOnhC,EAAOw+B,SAAW4J,EAAW/kC,SAW/C,MARArD,GAAO0U,OAAS6vB,EAAS7vB,OACzB1U,EAAO0+B,MAAQ6F,EAAS7F,MAEnBiG,OAAO3kC,EAAOy+B,WAAckG,OAAO3kC,EAAO0U,UAC7C1U,EAAOsU,MAAQtU,EAAOy+B,SAAWz+B,EAAOy+B,SAAW,KACpCz+B,EAAO0U,OAAS1U,EAAO0U,OAAS,KAEjD1U,EAAO+jC,KAAO/jC,EAAOqkC,SACdrkC,EAGT,IAAKkoC,EAAQ/kC,OAWX,MARAnD,GAAOy+B,SAAW,KAGhBz+B,EAAOsU,KADLtU,EAAO0U,OACK,IAAM1U,EAAO0U,OAEb,KAEhB1U,EAAO+jC,KAAO/jC,EAAOqkC,SACdrkC,CAcT,KAAK,GARDmT,GAAO+0B,EAAQl/B,MAAM,IAAI,GACzBq/B,GACCroC,EAAOmhC,MAAQoD,EAASpD,QAAmB,MAAThuB,GAAyB,OAATA,IAC1C,KAATA,EAIAwsB,EAAK,EACAxhC,EAAI+pC,EAAQ/kC,OAAQhF,GAAK,EAAGA,IACnCgV,EAAO+0B,EAAQ/pC,GACH,KAARgV,EACF+0B,EAAQxnC,OAAOvC,EAAG,GACA,OAATgV,GACT+0B,EAAQxnC,OAAOvC,EAAG,GAClBwhC,KACSA,IACTuI,EAAQxnC,OAAOvC,EAAG,GAClBwhC,IAKJ,KAAKqI,IAAeC,EAClB,KAAOtI,IAAMA,EACXuI,EAAQZ,QAAQ,OAIhBU,GAA6B,KAAfE,EAAQ,IACpBA,EAAQ,IAA+B,MAAzBA,EAAQ,GAAG3mB,OAAO,IACpC2mB,EAAQZ,QAAQ,IAGde,GAAsD,MAAjCH,EAAQv1B,KAAK,KAAKzD,OAAO,KAChDg5B,EAAQroC,KAAK,GAGf,IAAIyoC,GAA4B,KAAfJ,EAAQ,IACpBA,EAAQ,IAA+B,MAAzBA,EAAQ,GAAG3mB,OAAO,EAGrC,IAAI4mB,EAAW,CACbnoC,EAAOw+B,SAAWx+B,EAAOmhC,KAAOmH,EAAa,GACbJ,EAAQ/kC,OAAS+kC,EAAQ7kC,QAAU,EAInE,IAAI+kC,GAAapoC,EAAOmhC,MAAQnhC,EAAOmhC,KAAKxgC,QAAQ,KAAO,EAC1CX,EAAOmhC,KAAK1kB,MAAM,MAAO,CACtC2rB,KACFpoC,EAAOoa,KAAOguB,EAAW/kC,QACzBrD,EAAOmhC,KAAOnhC,EAAOw+B,SAAW4J,EAAW/kC,SAyB/C,MArBA2kC,GAAaA,GAAehoC,EAAOmhC,MAAQ+G,EAAQ/kC,OAE/C6kC,IAAeM,GACjBJ,EAAQZ,QAAQ,IAGbY,EAAQ/kC,OAIXnD,EAAOy+B,SAAWyJ,EAAQv1B,KAAK,MAH/B3S,EAAOy+B,SAAW,KAClBz+B,EAAOsU,KAAO,MAMXqwB,OAAO3kC,EAAOy+B,WAAckG,OAAO3kC,EAAO0U,UAC7C1U,EAAOsU,MAAQtU,EAAOy+B,SAAWz+B,EAAOy+B,SAAW,KACpCz+B,EAAO0U,OAAS1U,EAAO0U,OAAS,KAEjD1U,EAAOoa,KAAOmqB,EAASnqB,MAAQpa,EAAOoa,KACtCpa,EAAO8jC,QAAU9jC,EAAO8jC,SAAWS,EAAST,QAC5C9jC,EAAO+jC,KAAO/jC,EAAOqkC,SACdrkC,GAGT6jC,IAAItoC,UAAUurC,UAAY,WACxB,GAAI3F,GAAOtmC,KAAKsmC,KACZC,EAAO2D,YAAY/G,KAAKmD,EACxBC,KACFA,EAAOA,EAAK,GACC,MAATA,IACFvmC,KAAKumC,KAAOA,EAAKlyB,OAAO,IAE1BiyB,EAAOA,EAAKjyB,OAAO,EAAGiyB,EAAKh+B,OAASi+B,EAAKj+B,SAEvCg+B,IAAMtmC,KAAK2jC,SAAW2C;;AQlrB5B3mC,OAAOC,QAAU,SAAkBwN,GACjC,MAAOA,IAAsB,gBAARA,IACI,kBAAbA,GAAIkrB,MACS,kBAAblrB,GAAIstB,MACc,kBAAlBttB,GAAI2mB;;AJwHlB,QAAS4G,SAAQ8M,EAAKn2B,GAEpB,GAAI+9B,IACFC,QACAC,QAASC,eAkBX,OAfIvhC,WAAU3F,QAAU,IAAG+mC,EAAII,MAAQxhC,UAAU,IAC7CA,UAAU3F,QAAU,IAAG+mC,EAAIK,OAASzhC,UAAU,IAC9C0hC,UAAUr+B,GAEZ+9B,EAAIO,WAAat+B,EACRA,GAET1R,QAAQiwC,QAAQR,EAAK/9B,GAGnB/D,YAAY8hC,EAAIO,cAAaP,EAAIO,YAAa,GAC9CriC,YAAY8hC,EAAII,SAAQJ,EAAII,MAAQ,GACpCliC,YAAY8hC,EAAIK,UAASL,EAAIK,QAAS,GACtCniC,YAAY8hC,EAAIS,iBAAgBT,EAAIS,eAAgB,GACpDT,EAAIK,SAAQL,EAAIE,QAAUQ,kBACvBC,YAAYX,EAAK5H,EAAK4H,EAAII,OAoCnC,QAASM,kBAAiBn3B,EAAKq3B,GAC7B,GAAI3e,GAAQqJ,QAAQtJ,OAAO4e,EAE3B,OAAI3e,GACK,KAAYqJ,QAAQ+U,OAAOpe,GAAO,GAAK,IAAM1Y,EAC7C,KAAY+hB,QAAQ+U,OAAOpe,GAAO,GAAK,IAEvC1Y,EAKX,QAAS42B,gBAAe52B,GACtB,MAAOA,GAIT,QAASs3B,aAAY/nB,GACnB,GAAIsJ,KAMJ,OAJAtJ,GAAM7iB,QAAQ,SAASob,GACrB+Q,EAAK/Q,IAAO,IAGP+Q,EAIT,QAASue,aAAYX,EAAKzsC,EAAOutC,GAG/B,GAAId,EAAIS,eACJltC,GACAuK,WAAWvK,EAAM+3B,UAEjB/3B,EAAM+3B,UAAY/6B,QAAQ+6B,WAExB/3B,EAAMyH,aAAezH,EAAMyH,YAAY3J,YAAckC,GAAQ,CACjE,GAAIkM,GAAMlM,EAAM+3B,QAAQwV,EAAcd,EAItC,OAHK9F,UAASz6B,KACZA,EAAMkhC,YAAYX,EAAKvgC,EAAKqhC,IAEvBrhC,EAIT,GAAIshC,GAAYC,gBAAgBhB,EAAKzsC,EACrC,IAAIwtC,EACF,MAAOA,EAIT,IAAIhV,GAAO14B,OAAO04B,KAAKx4B,GACnB0tC,EAAcJ,YAAY9U,EAQ9B,IANIiU,EAAIO,aACNxU,EAAO14B,OAAO6tC,oBAAoB3tC,IAKhC4tC,QAAQ5tC,KACJw4B,EAAKt1B,QAAQ,YAAc,GAAKs1B,EAAKt1B,QAAQ,gBAAkB,GACrE,MAAO2qC,aAAY7tC,EAIrB,IAAoB,IAAhBw4B,EAAK9yB,OAAc,CACrB,GAAI6E,WAAWvK,GAAQ,CACrB,GAAIkS,GAAOlS,EAAMkS,KAAO,KAAOlS,EAAMkS,KAAO,EAC5C,OAAOu6B,GAAIE,QAAQ,YAAcz6B,EAAO,IAAK,WAE/C,GAAI47B,SAAS9tC,GACX,MAAOysC,GAAIE,QAAQnd,OAAO1xB,UAAU0T,SAASrU,KAAK6C,GAAQ,SAE5D,IAAI+tC,OAAO/tC,GACT,MAAOysC,GAAIE,QAAQl8B,KAAK3S,UAAU0T,SAASrU,KAAK6C,GAAQ,OAE1D,IAAI4tC,QAAQ5tC,GACV,MAAO6tC,aAAY7tC,GAIvB,GAAIguC,GAAO,GAAIzoB,GAAQ,EAAO0oB,GAAU,IAAK,IAS7C,IANIx3B,QAAQzW,KACVulB,GAAQ,EACR0oB,GAAU,IAAK,MAIb1jC,WAAWvK,GAAQ,CACrB,GAAI8K,GAAI9K,EAAMkS,KAAO,KAAOlS,EAAMkS,KAAO,EACzC87B,GAAO,aAAeljC,EAAI,IAkB5B,GAdIgjC,SAAS9tC,KACXguC,EAAO,IAAMxe,OAAO1xB,UAAU0T,SAASrU,KAAK6C,IAI1C+tC,OAAO/tC,KACTguC,EAAO,IAAMv9B,KAAK3S,UAAUowC,YAAY/wC,KAAK6C,IAI3C4tC,QAAQ5tC,KACVguC,EAAO,IAAMH,YAAY7tC,IAGP,IAAhBw4B,EAAK9yB,UAAkB6f,GAAyB,GAAhBvlB,EAAM0F,QACxC,MAAOuoC,GAAO,GAAKD,EAAOC,EAAO,EAGnC,IAAmB,EAAfV,EACF,MAAIO,UAAS9tC,GACJysC,EAAIE,QAAQnd,OAAO1xB,UAAU0T,SAASrU,KAAK6C,GAAQ,UAEnDysC,EAAIE,QAAQ,WAAY,UAInCF,GAAIC,KAAKtqC,KAAKpC,EAEd,IAAI06B,EAWJ,OATEA,GADEnV,EACO4oB,YAAY1B,EAAKzsC,EAAOutC,EAAcG,EAAalV,GAEnDA,EAAKtpB,IAAI,SAASjD,GACzB,MAAOmiC,gBAAe3B,EAAKzsC,EAAOutC,EAAcG,EAAazhC,EAAKsZ,KAItEknB,EAAIC,KAAK94B,MAEFy6B,qBAAqB3T,EAAQsT,EAAMC,GAI5C,QAASR,iBAAgBhB,EAAKzsC,GAC5B,GAAI2K,YAAY3K,GACd,MAAOysC,GAAIE,QAAQ,YAAa,YAClC,IAAIhG,SAAS3mC,GAAQ,CACnB,GAAIsuC,GAAS,IAAO7lC,KAAKmB,UAAU5J,GAAO8P,QAAQ,SAAU,IAClBA,QAAQ,KAAM,OACdA,QAAQ,OAAQ,KAAO,GACjE,OAAO28B,GAAIE,QAAQ2B,EAAQ,UAE7B,MAAI7jC,UAASzK,GACJysC,EAAIE,QAAQ,GAAK3sC,EAAO,UAC7B+sC,UAAU/sC,GACLysC,EAAIE,QAAQ,GAAK3sC,EAAO,WAE7BknC,OAAOlnC,GACFysC,EAAIE,QAAQ,OAAQ,QAD7B,OAKF,QAASkB,aAAY7tC,GACnB,MAAO,IAAMzB,MAAMT,UAAU0T,SAASrU,KAAK6C,GAAS,IAItD,QAASmuC,aAAY1B,EAAKzsC,EAAOutC,EAAcG,EAAalV,GAE1D,IAAK,GADDkC,MACKh6B,EAAI,EAAGoV,EAAI9V,EAAM0F,OAAYoQ,EAAJpV,IAASA,EAEvCg6B,EAAOt4B,KADLuU,eAAe3W,EAAOwjB,OAAO9iB,IACnB0tC,eAAe3B,EAAKzsC,EAAOutC,EAAcG,EACjDlqB,OAAO9iB,IAAI,GAEH,GAShB,OANA83B,GAAK91B,QAAQ,SAASuJ,GACfA,EAAImK,MAAM,UACbskB,EAAOt4B,KAAKgsC,eAAe3B,EAAKzsC,EAAOutC,EAAcG,EACjDzhC,GAAK,MAGNyuB,EAIT,QAAS0T,gBAAe3B,EAAKzsC,EAAOutC,EAAcG,EAAazhC,EAAKsZ,GAClE,GAAIrT,GAAM8D,EAAKu4B,CAsCf,IArCAA,EAAOzuC,OAAO0uC,yBAAyBxuC,EAAOiM,KAAUjM,MAAOA,EAAMiM,IACjEsiC,EAAKxtC,IAELiV,EADEu4B,EAAKr7B,IACDu5B,EAAIE,QAAQ,kBAAmB,WAE/BF,EAAIE,QAAQ,WAAY,WAG5B4B,EAAKr7B,MACP8C,EAAMy2B,EAAIE,QAAQ,WAAY,YAG7Bh2B,eAAe+2B,EAAazhC,KAC/BiG,EAAO,IAAMjG,EAAM,KAEhB+J,IACCy2B,EAAIC,KAAKxpC,QAAQqrC,EAAKvuC,OAAS,GAE/BgW,EADEkxB,OAAOqG,GACHH,YAAYX,EAAK8B,EAAKvuC,MAAO,MAE7BotC,YAAYX,EAAK8B,EAAKvuC,MAAOutC,EAAe,GAEhDv3B,EAAI9S,QAAQ,MAAQ,KAEpB8S,EADEuP,EACIvP,EAAIgJ,MAAM,MAAM9P,IAAI,SAASsD,GACjC,MAAO,KAAOA,IACb0C,KAAK,MAAMzD,OAAO,GAEf,KAAOuE,EAAIgJ,MAAM,MAAM9P,IAAI,SAASsD,GACxC,MAAO,MAAQA,IACd0C,KAAK,QAIZc,EAAMy2B,EAAIE,QAAQ,aAAc,YAGhChiC,YAAYuH,GAAO,CACrB,GAAIqT,GAAStZ,EAAImK,MAAM,SACrB,MAAOJ,EAET9D,GAAOzJ,KAAKmB,UAAU,GAAKqC,GACvBiG,EAAKkE,MAAM,iCACblE,EAAOA,EAAKT,OAAO,EAAGS,EAAKxM,OAAS,GACpCwM,EAAOu6B,EAAIE,QAAQz6B,EAAM,UAEzBA,EAAOA,EAAKpC,QAAQ,KAAM,OACdA,QAAQ,OAAQ,KAChBA,QAAQ,WAAY,KAChCoC,EAAOu6B,EAAIE,QAAQz6B,EAAM,WAI7B,MAAOA,GAAO,KAAO8D,EAIvB,QAASq4B,sBAAqB3T,EAAQsT,EAAMC,GAC1C,GAAIQ,GAAc,EACd/oC,EAASg1B,EAAOgU,OAAO,SAASC,EAAMC,GAGxC,MAFAH,KACIG,EAAI1rC,QAAQ,OAAS,GAAGurC,IACrBE,EAAOC,EAAI9+B,QAAQ,kBAAmB,IAAIpK,OAAS,GACzD,EAEH,OAAIA,GAAS,GACJuoC,EAAO,IACG,KAATD,EAAc,GAAKA,EAAO,OAC3B,IACAtT,EAAOxlB,KAAK,SACZ,IACA+4B,EAAO,GAGTA,EAAO,GAAKD,EAAO,IAAMtT,EAAOxlB,KAAK,MAAQ,IAAM+4B,EAAO,GAMnE,QAASx3B,SAAQo4B,GACf,MAAOpsC,OAAMgU,QAAQo4B,GAIvB,QAAS9B,WAAUviC,GACjB,MAAsB,iBAARA,GAIhB,QAAS08B,QAAO18B,GACd,MAAe,QAARA,EAIT,QAAS28B,mBAAkB38B,GACzB,MAAc,OAAPA,EAIT,QAASC,UAASD,GAChB,MAAsB,gBAARA,GAIhB,QAASm8B,UAASn8B,GAChB,MAAsB,gBAARA,GAIhB,QAASskC,UAAStkC,GAChB,MAAsB,gBAARA,GAIhB,QAASG,aAAYH,GACnB,MAAe,UAARA,EAIT,QAASsjC,UAASiB,GAChB,MAAOrkC,UAASqkC,IAA8B,oBAAvBC,eAAeD,GAIxC,QAASrkC,UAASF,GAChB,MAAsB,gBAARA,IAA4B,OAARA,EAIpC,QAASujC,QAAOvrB,GACd,MAAO9X,UAAS8X,IAA4B,kBAAtBwsB,eAAexsB,GAIvC,QAASorB,SAAQ90B,GACf,MAAOpO,UAASoO,KACW,mBAAtBk2B,eAAel2B,IAA2BA,YAAava,QAI9D,QAASgM,YAAWC,GAClB,MAAsB,kBAARA,GAIhB,QAASykC,aAAYzkC,GACnB,MAAe,QAARA,GACe,iBAARA,IACQ,gBAARA,IACQ,gBAARA,IACQ,gBAARA,IACQ,mBAARA,GAMhB,QAASwkC,gBAAet4B,GACtB,MAAO5W,QAAOhC,UAAU0T,SAASrU,KAAKuZ,GAIxC,QAASw4B,KAAIpkC,GACX,MAAW,IAAJA,EAAS,IAAMA,EAAE0G,SAAS,IAAM1G,EAAE0G,SAAS,IAQpD,QAAS6O,aACP,GAAImC,GAAI,GAAI/R,MACR8J,GAAQ20B,IAAI1sB,EAAE2sB,YACND,IAAI1sB,EAAE4sB,cACNF,IAAI1sB,EAAE6sB,eAAen6B,KAAK,IACtC,QAAQsN,EAAE8sB,UAAWC,OAAO/sB,EAAEgtB,YAAaj1B,GAAMrF,KAAK,KAqCxD,QAASyB,gBAAekuB,EAAK3V,GAC3B,MAAOpvB,QAAOhC,UAAU6Y,eAAexZ,KAAK0nC,EAAK3V,GAnjBnD,GAAIugB,cAAe,UACnBzyC,SAAQ4pC,OAAS,SAASxhC,GACxB,IAAKuhC,SAASvhC,GAAI,CAEhB,IAAK,GADDsqC,MACKhvC,EAAI,EAAGA,EAAI2K,UAAU3F,OAAQhF,IACpCgvC,EAAQttC,KAAK21B,QAAQ1sB,UAAU3K,IAEjC,OAAOgvC,GAAQx6B,KAAK,KAsBtB,IAAK,GAnBDxU,GAAI,EACJyK,EAAOE,UACPH,EAAMC,EAAKzF,OACXsQ,EAAMwN,OAAOpe,GAAG0K,QAAQ2/B,aAAc,SAAShuB,GACjD,GAAU,OAANA,EAAY,MAAO,GACvB,IAAI/gB,GAAKwK,EAAK,MAAOuW,EACrB,QAAQA,GACN,IAAK,KAAM,MAAO+B,QAAOrY,EAAKzK,KAC9B,KAAK,KAAM,MAAO3C,QAAOoN,EAAKzK,KAC9B,KAAK,KACH,IACE,MAAO+H,MAAKmB,UAAUuB,EAAKzK,MAC3B,MAAOyV,GACP,MAAO,aAEX,QACE,MAAOsL,MAGJA,EAAItW,EAAKzK,GAAQwK,EAAJxK,EAAS+gB,EAAItW,IAAOzK,GAEtCsV,GADEkxB,OAAOzlB,KAAO/W,SAAS+W,GAClB,IAAMA,EAEN,IAAMsW,QAAQtW,EAGzB,OAAOzL,IAOThZ,QAAQ2yC,UAAY,SAAShqC,EAAI6G,GAa/B,QAASojC,KACP,IAAKjkC,EAAQ,CACX,GAAIhH,QAAQkrC,iBACV,KAAM,IAAItxC,OAAMiO,EACP7H,SAAQmrC,iBACjB3xC,QAAQyN,MAAMY,GAEdrO,QAAQD,MAAMsO,GAEhBb,GAAS,EAEX,MAAOhG,GAAG2F,MAAMlO,KAAMiO,WAtBxB,GAAIV,YAAY2H,OAAO3N,SACrB,MAAO,YACL,MAAO3H,SAAQ2yC,UAAUhqC,EAAI6G,GAAKlB,MAAMlO,KAAMiO,WAIlD,IAAI1G,QAAQorC,iBAAkB,EAC5B,MAAOpqC,EAGT,IAAIgG,IAAS,CAeb,OAAOikC,GAIT,IAAII,WACAC,YACJjzC,SAAQkzC,SAAW,SAASh9B,GAI1B,GAHIvI,YAAYslC,gBACdA,aAAetrC,QAAQqB,IAAImqC,YAAc,IAC3Cj9B,EAAMA,EAAIk9B,eACLJ,OAAO98B,GACV,GAAI,GAAIsc,QAAO,MAAQtc,EAAM,MAAO,KAAK6hB,KAAKkb,cAAe,CAC3D,GAAII,GAAM1rC,QAAQ0rC,GAClBL,QAAO98B,GAAO,WACZ,GAAI1G,GAAMxP,QAAQ4pC,OAAOt7B,MAAMtO,QAASqO,UACxClN,SAAQD,MAAM,YAAagV,EAAKm9B,EAAK7jC,QAGvCwjC,QAAO98B,GAAO,YAGlB,OAAO88B,QAAO98B,IAoChBlW,QAAQ+6B,QAAUA,QAIlBA,QAAQ+U,QACNwD,MAAU,EAAG,IACbC,QAAY,EAAG,IACfC,WAAe,EAAG,IAClBC,SAAa,EAAG,IAChBC,OAAW,GAAI,IACfC,MAAU,GAAI,IACdC,OAAW,GAAI,IACfC,MAAU,GAAI,IACdC,MAAU,GAAI,IACdC,OAAW,GAAI,IACfC,SAAa,GAAI,IACjBC,KAAS,GAAI,IACbC,QAAY,GAAI,KAIlBnZ,QAAQtJ,QACN0iB,QAAW,OACXC,OAAU,SACVC,UAAW,SACX/zC,UAAa,OACbg0C,OAAQ,OACRhuB,OAAU,QACViuB,KAAQ,UAERC,OAAU,OAkRZx0C,QAAQyZ,QAAUA,QAKlBzZ,QAAQ+vC,UAAYA,UAKpB/vC,QAAQkqC,OAASA,OAKjBlqC,QAAQmqC,kBAAoBA,kBAK5BnqC,QAAQyN,SAAWA,SAKnBzN,QAAQ2pC,SAAWA,SAKnB3pC,QAAQ8xC,SAAWA,SAKnB9xC,QAAQ2N,YAAcA,YAKtB3N,QAAQ8wC,SAAWA,SAKnB9wC,QAAQ0N,SAAWA,SAKnB1N,QAAQ+wC,OAASA,OAMjB/wC,QAAQ4wC,QAAUA,QAKlB5wC,QAAQuN,WAAaA,WAUrBvN,QAAQiyC,YAAcA,YAEtBjyC,QAAQk0B,SAAWr0B,QAAQ,qBAY3B,IAAI0yC,SAAU,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MACxD,MAAO,MAAO,MAa5BvyC,SAAQgE,IAAM,WACZ7C,QAAQ6C,IAAI,UAAWqf,YAAarjB,QAAQ4pC,OAAOt7B,MAAMtO,QAASqO,aAiBpErO,QAAQa,SAAWhB,QAAQ,YAE3BG,QAAQiwC,QAAU,SAASrwB,EAAQjd,GAEjC,IAAKA,IAAQ+K,SAAS/K,GAAM,MAAOid,EAInC,KAFA,GAAI4b,GAAO14B,OAAO04B,KAAK74B,GACnBe,EAAI83B,EAAK9yB,OACNhF,KACLkc,EAAO4b,EAAK93B,IAAMf,EAAI64B,EAAK93B,GAE7B,OAAOkc;;;;AzBnkBT,YAsDA,IAAI/Y,SAAU9G,OAAOC,QAAU,SAAS0R,GAQtC,QAASC,GAAWvP,EAAMwP,GAKxB,IAJA,GAEIC,GAFAC,KACAC,KAAWlM,OAAOmM,EAAQ5P,IAGvB2P,EAAMrJ,QAAUoJ,EAAIpJ,OAASkJ,GAClCC,EAAOtR,KAAK0R,SAAWF,EAAMrJ,OAAU,EACvCoJ,EAAMA,EAAIjM,OAAOkM,EAAM9L,OAAO4L,EAAK,GAGrC,OAAOC,GAAII,IAAI,SAASC,GACtB,OAASA,IAAK/P,EAAO,IAAM+P,KAjB/B,GAIIC,GAJAJ,GAAWN,OAAYM,SAAWnS,QAAQ,aAE1CwS,GAAaX,OAAYY,MAAQ,EACjCC,GAAab,OAAYc,MAAQ,CAyBrC,OANAJ,MAAcvM,OAAO8L,EAAW,OAAQU,IAEpCE,IACFH,EAAWA,EAASvM,OAAO8L,EAAW,OAAQY,KAGzCH;;AMpFTpS,QAAQsS,MACN,0BACA,2BACA,2BACA,2BACA,2BACA,iBACA,mBACA,iBACA,qBACA,kBACA,iBAEA,6BAEA,sBACA,sBACA,sBAIFtS,QAAQwS;;AURR,QAASxB,qBAML,GAEI2sB,GACAC,EACAC,EACAC,EACAC,EACAxxB,EACAyxB,EACAC,EACAC,EACAC,EACA3tB,EAGA4tB,EACAjsB,EACAksB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAQJf,GAAoB,KACpBC,EAAiB,IACjBC,EAAiB,IACjBc,0BAA4B,IAE5Bb,EAAiBj7B,OAAOoO,OAAO,MAC/BstB,EAAqB17B,OAAOoO,OAAO,MAEnC8sB,GAAc,EACdC,GAAe,EACfC,GAA4B,EAC5BQ,GAAoB,EAEpBluB,EAAOpQ,KACPq+B,EAAgB,KAChBJ,EAAY,KACZM,EAAqB,KAQrBv+B,KAAKy+B,MAAQ,WAAc,MAAOtyB,IAClCnM,KAAK0+B,MAAQ,SAAUC,GAASxyB,EAAKwyB,GAErC3+B,KAAK4+B,OAAS,WAAc,MAAO7sB,IACnC/R,KAAK6+B,OAAS,SAAUC,GAAU/sB,EAAM+sB,EAAQvB,EAAa,MAE7Dv9B,KAAK++B,cAAgB,WAAc,MAAOxB,IAC1Cv9B,KAAKkQ,cAAgB,SAAU4uB,GAAUvB,EAAauB,EAAQ/sB,EAAM,MAEpE/R,KAAKg/B,qBAAuB,WAAc,MAAOxB,IACjDx9B,KAAKi/B,qBAAuB,SAAUC,GAAc1B,EAAoB0B,GAExEl/B,KAAKm/B,eAAiB,WAAc,MAAOvB,IAA8B,MAAfxtB,EAAK4tB,QAE/Dh+B,KAAKo/B,sBAAwB,WAAc,MAAOlB,IAClDl+B,KAAKq/B,sBAAwB,SAAUC,GAAyBpB,EAAqBoB,GAErFt/B,KAAKu/B,0BAA4B,WAAc,MAAOpB,IACtDn+B,KAAKw/B,0BAA4B,SAAUC,GAA6BtB,EAAyBsB,GAMjGz/B,KAAKmQ,YAAc,KACnBnQ,KAAK0/B,eAAiB,KACtB1/B,KAAKqQ,aAAe,KACpBrQ,KAAKuQ,eAAiB,KACtBvQ,KAAKwQ,YAAc,KACnBxQ,KAAK2/B,eAAiB,KACtB3/B,KAAK4/B,cAAgB,KASrB5/B,KAAK4P,QAAU,SAAUiwB,EAAQC,GAIzBlC,EACAmC,EAA0B3vB,EAAM,qBAE1B2B,GAAQwrB,EAGRsC,EAGAC,EAGD/tB,IAAQiuB,EAAejuB,GAC5BguB,EAA0B3vB,EAAM,eAE3BmtB,IAAeyC,EAAezC,GACnCwC,EAA0B3vB,EAAM,uBAE1B6vB,EAAiBJ,GAGjBI,EAAiBH,GAGjBG,EAAiB9B,GAGlBD,GAAsBA,EAAmB51B,OAASk2B,0BACvDuB,EAA0B3vB,EAAM,iDAAmDouB,0BAA4B,gBAG/GpuB,EAAKyvB,OAASA,EACdzvB,EAAK0vB,UAAYA,EAEjBjC,GAAe,EACfE,GAAmB,EAEfR,GAA4B,MAAdA,GACdA,EAAa2C,EAAa3C,GAE1B4C,EAAkB/vB,EAAK4uB,0BAGvBjtB,EAAMmuB,EAAanuB,GAEnB3B,EAAK4tB,OAASoC,EAAuBruB,IAGpC3B,EAAKiwB,sBAENjwB,EAAKiwB,oBAAsB53B,WAAW,WAC7Bm1B,GACD0C,EAAgBlwB,EAAK4uB,yBAE1B5uB,EAAK4uB,0BA7BZe,EAA0B3vB,EAAM,kDAHhC2vB,EAA0B3vB,EAAM,+CAHhC2vB,EAA0B3vB,EAAM,0CAThC2vB,EAA0B3vB,EAAM,yCAHhC2vB,EAA0B3vB,EAAM,oCAHhC2vB,EAA0B3vB,EAAM,0CA0DxCpQ,KAAKyP,UAAY,SAAU1K,EAASw7B,EAAwBC,GAIxD,GAAK5C,EAGA,GAAK74B,EAGL,GAAKk7B,EAAiBl7B,GAGtB,GAAIq5B,EAAmBr5B,IAAYq5B,EAAmBr5B,GAAS07B,cAChEV,EAA0B3vB,EAAM,uCAA0CrL,EAAU,SAEnF,IAAIq5B,EAAmBr5B,IAAYq5B,EAAmBr5B,GAAS27B,aAChEX,EAA0B3vB,EAAM,sCAAyCrL,EAAU,SAElF,IAAIA,EAAQuD,OAASo1B,EACtBqC,EAA0B3vB,EAAM,qCAAuCstB,EAAiB,mBAEvF,IAAKiD,EAAmBJ,GAGxB,GAAKK,EAAeJ,IAIrB,GAAmB,MAAfpwB,EAAK4tB,OAAgB,CACrB,GAAI6C,GAA8B97B,EAAQe,QAAQ,KAC9Cg7B,EAAoB/7B,EACpBg8B,EAAW,IAEXF,GAA8B,IAC9BC,EAAoB/7B,EAAQi8B,UAAU,EAAGH,EAA8B,GAAK,KAG5E5C,GAA0B,MAAbA,IACb8C,EAAW9C,EAAU6C,GAAqB7C,EAAU6C,GAAqB7C,EAAUl5B,IAGnFk5B,GAA0B,MAAbA,IAAsB8C,EACnChB,EAA0B3vB,EAAM,oDAAuDrL,EAAU,MAG7Fq5B,EAAmBr5B,IACnBq5B,EAAmBr5B,GAAS07B,eAAgB,EAC5CrC,EAAmBr5B,GAAS27B,cAAe,EAC3CtC,EAAmBr5B,GAASw7B,uBAAyBA,EACrDnC,EAAmBr5B,GAASy7B,kBAAoBA,GAGhDpC,EAAmBr5B,IAAa07B,eAAiB,EAAMC,cAAgB,EAAOH,uBAA0BA,EAAwBC,kBAAqBA,GAGzJpwB,EAAK4tB,OAAOx6B,KAAK6H,KAAKmB,UAAU,aAAe4D,EAAKyvB,OAAS,IAAMzvB,EAAK0vB,UAAY,IAAM/6B,EAAU,IAAMg8B,UA9BlHhB,GAA0B3vB,EAAM,2DAHhC2vB,GAA0B3vB,EAAM,+DAZhC2vB,GAA0B3vB,EAAM,sCAHhC2vB,GAA0B3vB,EAAM,gCAHhC2vB,GAA0B3vB,EAAM,kBA4DxCpQ,KAAK8P,YAAc,SAAU/K,GAIpB64B,EAGK74B,EAGAk7B,EAAiBl7B,IAGjBq5B,EAAmBr5B,IAAaq5B,EAAmBr5B,KAAaq5B,EAAmBr5B,GAAS27B,aAClGX,EAA0B3vB,EAAM,iCAAmCrL,GAE9DA,EAAQuD,OAASo1B,EACtBqC,EAA0B3vB,EAAM,qCAAuCstB,EAAiB,eAGrE,MAAfttB,EAAK4tB,QACL5tB,EAAK4tB,OAAOx6B,KAAK6H,KAAKmB,UAAU,eAAiB4D,EAAKyvB,OAAS,IAAM96B,IAVzEg7B,EAA0B3vB,EAAM,kCAHhC2vB,EAA0B3vB,EAAM,4BAHhC2vB,EAA0B3vB,EAAM,kBAwBxCpQ,KAAKwD,KAAO,SAAUuB,EAASjC,GAI3B,GAAK86B,GAA8B,MAAfxtB,EAAK4tB,OAGpB,GAAKj5B,EAGL,GAAKk7B,EAAiBl7B,GAGtB,GAAKjC,EAGL,GAAKm+B,EAAan+B,GAGlB,GAAIiC,EAAQuD,OAASo1B,EACtBqC,EAA0B3vB,EAAM,qCAAuCstB,EAAiB,mBAEvF,CACD,GAAImD,GAA8B97B,EAAQe,QAAQ,KAC9Cg7B,EAAoB/7B,EACpBg8B,EAAW,IAUf,IARIF,EAA8B,IAC9BC,EAAoB/7B,EAAQi8B,UAAU,EAAGH,EAA8B,GAAK,KAG5E5C,GAA0B,MAAbA,IACb8C,EAAW9C,EAAU6C,GAAqB7C,EAAU6C,GAAqB7C,EAAUl5B,IAGnFk5B,GAA0B,MAAbA,IAAsB8C,EACnChB,EAA0B3vB,EAAM,+CAAkDrL,EAAU,SAE3F,CAED,GAEIzB,GAFA49B,KACAC,EAAYC,EAAW,GAEvBC,EAAiB5D,EAAiB14B,EAAQuD,MAE9C,KAAKhF,EAAI,EAAGA,EAAIR,EAAQwF,OAAQhF,GAAQ+9B,EAAgB,CAEpD,GAAIv+B,EAAQwF,QAAU+4B,EAAgB,CAClCH,EAAal8B,KAAKlC,EAClB,OAGAA,EAAQk+B,UAAU19B,EAAGA,EAAI+9B,IACzBH,EAAal8B,KAAKlC,EAAQk+B,UAAU19B,EAAGA,EAAI+9B,IAInD,GAA2B,GAAvBH,EAAa54B,OACb8H,EAAK4tB,OAAOx6B,KAAK6H,KAAKmB,UAAU,QAAU4D,EAAKyvB,OAAS,IAAMzvB,EAAK0vB,UAAY,IAAM/6B,EAAU,IAAMg8B,EAAW,IAAMI,EAAY,QAAUD,EAAa,SAGzJ,KAAK,GAAI5b,GAAI,EAAGA,GAAK4b,EAAa54B,OAAQgd,IAAK,CAC3C,GAAIgc,GAAgB,QAAUlxB,EAAKyvB,OAAS,IAAMzvB,EAAK0vB,UAAY,IAAM/6B,EAAU,IAAMg8B,EAAW,IAAMI,EAAY,IAAM7b,EAAI,IAAM4b,EAAa54B,OAAS,IAAM44B,EAAa5b,EAAI,EACnLtlB,MAAKuhC,qBAAqBD,SA9CtCvB,GAA0B3vB,EAAM,gCAHhC2vB,GAA0B3vB,EAAM,gCAHhC2vB,GAA0B3vB,EAAM,sCAHhC2vB,GAA0B3vB,EAAM,gCAHhC2vB,GAA0B3vB,EAAM,kBAoExCpQ,KAAKwhC,UAAY,SAAUC,EAAgBC,EAAY38B,EAASjC,GAI5D,GAAK86B,GAA8B,MAAfxtB,EAAK4tB,OAGpB,GAAKyD,EAGL,GAAKC,EAGL,GAAK38B,EAGL,GAAKk7B,EAAiBl7B,GAGtB,GAAKjC,EAGL,GAAKm+B,EAAan+B,GAGlB,GAAIiC,EAAQuD,OAASo1B,EACtBqC,EAA0B3vB,EAAM,qCAAuCstB,EAAiB,mBAEvF,CAGD,GAEIp6B,GAFA49B,KACAC,EAAYC,EAAW,GAEvBC,EAAiB5D,EAAiB14B,EAAQuD,MAE9C,KAAKhF,EAAI,EAAGA,EAAIR,EAAQwF,OAAQhF,GAAQ+9B,EAAgB,CAEpD,GAAIv+B,EAAQwF,QAAU+4B,EAAgB,CAClCH,EAAal8B,KAAKlC,EAClB,OAGAA,EAAQk+B,UAAU19B,EAAGA,EAAI+9B,IACzBH,EAAal8B,KAAKlC,EAAQk+B,UAAU19B,EAAGA,EAAI+9B,IAInD,GAA2B,GAAvBH,EAAa54B,OACb8H,EAAK4tB,OAAOx6B,KAAK6H,KAAKmB,UAAU,aAAei1B,EAAiB,IAAMC,EAAa,IAAM38B,EAAU,IAAMo8B,EAAY,QAAUD,EAAa,SAG5I,KAAK,GAAI5b,GAAI,EAAGA,GAAK4b,EAAa54B,OAAQgd,IAAK,CAC3C,GAAIgc,GAAgB,aAAeG,EAAiB,IAAMC,EAAa,IAAM38B,EAAU,IAAMo8B,EAAY,IAAM7b,EAAI,IAAM4b,EAAa54B,OAAS,IAAM44B,EAAa5b,EAAI,EACtKtlB,MAAKuhC,qBAAqBD,QA/BlCvB,GAA0B3vB,EAAM,gCAHhC2vB,GAA0B3vB,EAAM,gCAHhC2vB,GAA0B3vB,EAAM,WAAarL,EAAU,+BAHvDg7B,GAA0B3vB,EAAM,gCAHhC2vB,GAA0B3vB,EAAM,oCAHhC2vB,GAA0B3vB,EAAM,wCAHhC2vB,GAA0B3vB,EAAM,kBAwDxCpQ,KAAKuhC,qBAAuB,SAASz+B,GACjCyE,QAAQG,SAAS,WACb0I,EAAK4tB,OAAOx6B,KAAK6H,KAAKmB,UAAU1J,OAOxC9C,KAAK6P,WAAa,WACd8xB,IAGA5D,GAAmB,EACnBD,GAA4B,EAG5BM,EAAqB17B,OAAOoO,OAAO,MAK9B8sB,GAAgBU,EAIjBsD,IAHA7B,EAA0B3vB,EAAM,kBAUxCpQ,KAAK0gC,aAAe,SAAU37B,GAI1B,GAAK64B,EAGA,GAAK74B,EAGL,CAAA,GAAKk7B,EAAiBl7B,GAIvB,MAAIq5B,GAAmBr5B,IAAYq5B,EAAmBr5B,GAAS27B,aACpDtC,EAAmBr5B,GAAS27B,cAG5B,CAPXX,GAA0B3vB,EAAM,sCAHhC2vB,GAA0B3vB,EAAM,gCAHhC2vB,GAA0B3vB,EAAM,kBAgDxCpQ,KAAK6hC,mBAAqB,SAAU9vB,EAAK+vB,EAAWC,EAAqBC,EAA8BP,EAAgBQ,EAAYP,EAAYQ,EAAa3gC,GACxJ,GAAI4gC,GAAgBpwB,CAEhB+vB,GACAM,GACIC,WAAaF,EACb3E,kBAAoBptB,EAAK4uB,uBACzBa,OAAS4B,GAEb,SAAU3gC,EAAOwhC,GACA,MAATxhC,GACAi/B,EAA0B3vB,EAAM,qCAChC7O,EAAS,oCAAoC,QAG7C4gC,EAAgBG,EAAKtB,UAAUsB,EAAKx8B,QAAQ,KAAO,EAAGw8B,EAAKh6B,OAAS,GACpEi6B,wBAAwBV,mBAAmBM,EAAeJ,EAAqBC,EAA8BP,EAAgBQ,EAAYP,EAAYQ,EAAa3gC,MAI1KghC,wBAAwBV,mBAAmBM,EAAeJ,EAAqBC,EAA8BP,EAAgBQ,EAAYP,EAAYQ,EAAa3gC,IA2C1KvB,KAAK4M,SAAW,SAAU41B,EAAWjhC,GACjC,IACI,GAAIkhC,GAAa,KACfX,GAAY,EACZjC,EAASzvB,EAAKyvB,OACdC,EAAY1vB,EAAK0vB,SAEhB0C,GAAWzwB,KACV0wB,EAAaD,EAAWzwB,IACxB+vB,EAAYU,EAAWV,UACvBjC,EAAS2C,EAAWf,eACpB3B,EAAY0C,EAAWT,qBAEnBxE,GAA4B,MAAdA,GACdkF,EAAalF,EACbuE,GAAY,GAGZW,EAAa1wB,EAIrB2wB,GACID,WAAaA,EACbX,UAAYA,EACZjC,OAASA,GAEb,SAAS/+B,EAAM6hC,GACR7hC,EACCS,EAAST,EAAM,MAEfyhC,wBAAwBK,aACpB7wB,IAAM4wB,EACN9C,OAASA,EACTC,UAAYA,EACZ/6B,QAAUy9B,EAAWz9B,SACvBxD,KAGb,MAAMma,GACHna,EAAS,+BAAiCma,EAAE,QAoCpD1b,KAAK6iC,eAAiB,SAAUL,EAAWjhC,GACvC,IACI,GAAIkhC,GAAa,KACfX,GAAY,EACZjC,EAASzvB,EAAKyvB,MAEb2C,GAAWzwB,KACV0wB,EAAaD,EAAWzwB,IACxB+vB,EAAYU,EAAWV,UACvBjC,EAAS2C,EAAWf,gBAEhBlE,GAA4B,MAAdA,GACdkF,EAAalF,EACbuE,GAAY,GAGZW,EAAa1wB,EAIrB2wB,GACID,WAAaA,EACbX,UAAYA,EACZjC,OAASA,GAEb,SAAS/+B,EAAM6hC,GACR7hC,EACCS,EAAST,EAAM,MAEfyhC,wBAAwBM,gBACpB9wB,IAAM4wB,EACN9C,OAASA,EACT6B,WAAac,EAAWd,WACxB38B,QAAUy9B,EAAWz9B,QACrB+9B,SAAkC,GAAvBN,EAAWM,SAAmB,EAAI,GAC/CvhC,KAGb,MAAMma,GACHna,EAAS,6BAA+Bma,EAAE,QAkClD1b,KAAK+iC,gBAAkB,SAAUP,EAAWjhC,GACxC,IACI,GAAIkhC,GAAa,KACfX,GAAY,EACZjC,EAASzvB,EAAKyvB,MAEb2C,GAAWzwB,KACV0wB,EAAaD,EAAWzwB,IACxB+vB,EAAYU,EAAWV,UACvBjC,EAAS2C,EAAWf,gBAEhBlE,GAA4B,MAAdA,GACdkF,EAAalF,EACbuE,GAAY,GAGZW,EAAa1wB,EAIrB2wB,GACID,WAAaA,EACbX,UAAYA,EACZjC,OAASA,GAEb,SAAS/+B,EAAM6hC,GACR7hC,EACCS,EAAST,EAAM,MAEfyhC,wBAAwBQ,iBACpBhxB,IAAM4wB,EACN9C,OAASA,EACT6B,WAAac,EAAWd,WACxB38B,QAAUy9B,EAAWz9B,SACvBxD,KAGb,MAAMma,GACHna,EAAS,8BAAgCma,EAAE,OAQnD,IAAIgnB,GAAe,SAASF,EAAWjhC,GAClC,GAAIihC,EAAWC,YAAcD,EAAWV,UAAW,CAChD,GAAIvE,GAAa2C,EAAasC,EAAWC,WAEzCL,IACIC,WAAa9E,EACbsC,OAAS2C,EAAW3C,QAExB,SAAU/+B,EAAOwhC,GACb,GAAa,MAATxhC,EACAS,EAAS,oCAAoC,UAE5C,CACD,GAAIyhC,GAAYV,EAAKtB,UAAUsB,EAAKx8B,QAAQ,KAAO,EAAGw8B,EAAKh6B,OAAS,EACpE/G,GAAS,KAAKyhC,UAIrB,CACD,GAAIA,GAAY9C,EAAasC,EAAWC,WACxClhC,GAAS,KAAKyhC,KAIlBrB,EAAyB,WAErBvxB,EAAK6yB,sBACLC,cAAc9yB,EAAK6yB,qBACnB7yB,EAAK6yB,oBAAsB,MAI3B7yB,EAAKiwB,sBACLhqB,aAAajG,EAAKiwB,qBAClBjwB,EAAKiwB,oBAAsB,OAI/BL,EAAiB,SAAUruB,GAC3B,MAAO,wFAA0FwxB,KAAKxxB,IAAS,GAAO,GAGtHsuB,EAAmB,SAAUtuB,GAC7B,MAAO,gBAAkBwxB,KAAKxxB,IAAS,GAAO,GAG9CgvB,EAAqB,SAAUhvB,GAC/B,MAAO,qBAAuBwxB,KAAKxxB,IAAS,GAAO,GAGnDivB,EAAiB,SAAUjvB,GAC3B,MAAyB,kBAAX,IAAwB,GAAO,GAG7CsvB,EAAe,SAAUtvB,GACzB,MAAyB,gBAAX,IAAsB,GAAO,GAG3CuuB,EAAe,SAAUnuB,GAOzB,MANAA,GAAMA,EAAIW,QAAQ,OAAQ,IAEQ,KAA9BX,EAAI2U,OAAO3U,EAAIzJ,OAAS,KACxByJ,EAAMA,EAAIivB,UAAU,EAAGjvB,EAAIzJ,OAAS,IAGjCyJ,GAMPqvB,EAAa,SAAUtY,GAOvB,IAAK,GAND3jB,GAAS,GAETi+B,EAAK,WACL,OAA+B,OAArB,EAAIjjC,KAAK0R,UAAuB,GAAGuC,SAAS,IAAI4sB,UAAU,IAG/D19B,EAAI,EAAOwlB,EAAO,EAAXxlB,EAAcA,IAC1B6B,GAAUi+B,GAGd,OAAOj+B,IAMPy8B,EAAmB,WACnBrD,EAAqB,KACrBV,GAAe,EAEI,MAAfztB,EAAK4tB,SACL5tB,EAAK4tB,OAAOx9B,QACZ4P,EAAK4tB,OAAS,OAOlBsC,EAAkB,SAAU+C,GAC5B1B,IAEAvxB,EAAK4tB,OAAS,KAEVH,GACAkC,EAA0B3vB,EAAM,qBAGpCytB,GAAe,EAEfyF,EAA6BlzB,GAE7BmuB,GAAqB,GAAIlrB,OAAOC,UAE5BiqB,GAA4B,MAAdA,EACd4C,EAAkBkD,GAGlBjzB,EAAK4tB,OAASoC,EAAuBruB,GAGpC3B,EAAKiwB,sBAENjwB,EAAKiwB,oBAAsB53B,WAAW,WAC7Bm1B,GACD0C,EAAgBlwB,EAAK4uB,yBAE1B5uB,EAAK4uB,0BAOZmB,EAAoB,SAAUkD,GACZ,MAAd9F,GACA6E,GACIC,WAAa9E,EACb8F,eAAiBA,EACjBxD,OAASzvB,EAAKyvB,QAElB,SAAU/+B,EAAOwhC,GACA,MAATxhC,EACAi/B,EAA0B3vB,EAAM,qCAG5BkyB,EAAKx8B,QAAQ,kBAAoB,IACjCiM,EAAMuwB,EAAKtB,UAAUsB,EAAKx8B,QAAQ,KAAO,EAAGw8B,EAAKh6B,OAAS,GAC1D01B,EAASoC,EAAuBhwB,EAAKwuB,cAUrDwD,EAAuB,SAAUI,EAAWjhC,GAC5C,GAAIgiC,GAAcf,EAAW3C,OAAS,UAAY2C,EAAW3C,OAAS,GAElE2D,EAAYC,UAAUn4B,MAAMk3B,EAAWH,WAAa,IAAMkB,EAE9DG,aAAY//B,KACRoO,IAAMyxB,EAAUG,SAChBlqB,KAAO+pB,EAAUI,SACjBpB,WAAagB,EAAUK,MACvBtiC,SAAW,SAAST,EAAMgjC,GACT,MAAThjC,EACAS,EAAST,EAAO,MAGhBS,EAAS,KAAMuiC,EAAaC,aASxC3D,EAAyB,SAAU+B,GACnC,GAAmB,MAAf/xB,EAAK4tB,OAAgB,CACrB,GAAIgG,GAAW,KACXC,EAAQ9B,CAEyB,YAAjCA,EAAcnB,UAAU,EAAG,GAC3BiD,EAAQA,EAAMjD,UAAU,GAEc,YAAjCmB,EAAcnB,UAAU,EAAG,KAChCiD,EAAQA,EAAMjD,UAAU,GACxBgD,EAAW,MAGf,IAAIE,GAASC,QAAQC,cAAc,GAC/BC,EAAWF,QAAQG,qBAAqB,IAC5Cl0B,GAAK4tB,OAAS,GAAIuG,WAAUP,EAAW,MAAQC,EAAQ,cAAgBI,EAAW,IAAMH,EAAS,cAGjG9zB,EAAK4tB,OAAOwG,OAAS,WAEjBnG,GAAgB,GAAIhrB,OAAOC,UAE3BlD,EAAK4tB,OAAOx6B,KAAK6H,KAAKmB,UAAU,YAAc4D,EAAKyvB,OAAS,IAAMzvB,EAAK0vB,UAAY,KAAO3B,EAAyBA,EAAyB,IAAM,MAAkBD,EAAqBA,EAAqB,OAIlN9tB,EAAK4tB,OAAOyG,QAAU,WAClBr0B,EAAK4tB,OAAS,KAEVJ,IACAA,GAAc,EACdC,GAAe,EAEf6G,EAA6Bt0B,IAG5B2tB,GAAsBQ,KAAuBA,EAAqBf,GAAoB,GAAInqB,OAAOC,YAClGgtB,EAAgBlwB,EAAK4uB,yBAK7B5uB,EAAK4tB,OAAO/8B,QAAU,aAItBmP,EAAK4tB,OAAO2G,UAAY,SAAUt2B,GAE9BgwB,GAAgB,GAAIhrB,OAAOC,SAE3B,IAAIsxB,GAAcv2B,EAAEjG,KAAK,EAEzB,QAAQw8B,GACJ,IAAK,IACD,KACJ,KAAK,IACD,GAAIx8B,GAAOiD,KAAKC,MAAMD,KAAKC,MAAM+C,EAAEjG,KAAK44B,UAAU,IAAI,IAClD6D,EAAKz8B,EAAKy8B,EAEd,QAAQA,GACJ,IAAK,iBASD,GARIz8B,EAAK08B,KACL7G,EAAY71B,EAAK08B,IAGrBjH,GAAe,EACfD,GAAc,EACdW,EAAqB,KAEjBT,EAA2B,CAC3B,GAAIiH,GAAmBriC,OAAOoO,OAAO,KAGrC,KAAK,GAAIjC,KAAOuvB,GAEZ,GAAsD,GAAlDA,EAAmBvvB,GAAK0xB,yBAAmCnC,EAAmBvvB,GAAK4xB,eAAiBrC,EAAmBvvB,GAAK6xB,cAAe,CAC3ItC,EAAmBvvB,GAAK4xB,eAAgB,EACxCrC,EAAmBvvB,GAAK6xB,cAAe,CAEvC,IAAIG,GAA8BhyB,EAAI/I,QAAQ,KAC1Cg7B,EAAoBjyB,EACpBkyB,EAAW,IAEXF,GAA8B,IAC9BC,EAAoBjyB,EAAImyB,UAAU,EAAGH,EAA8B,GAAK,KAGxE5C,GAA0B,MAAbA,IACb8C,EAAW9C,EAAU6C,GAAqB7C,EAAU6C,GAAqB7C,EAAUpvB,IAGvFuB,EAAK4tB,OAAOx6B,KAAK6H,KAAKmB,UAAU,aAAe4D,EAAKyvB,OAAS,IAAMzvB,EAAK0vB,UAAY,IAAMjxB,EAAM,IAAMkyB,QAGtGgE,GAAiBl2B,GAAOA,CAIhC,KAAK,GAAIm2B,KAAUD,GACfE,eAAeC,YAAY9G,EAAmB4G,EAIlDrH,GAAiBj7B,OAAOoO,OAAO,MAE/Bq0B,EAA4B/0B,OAG5B0tB,IAA4B,EAE5BsH,EAA0Bh1B,EAGzBA,GAAK6yB,sBAEN7yB,EAAK6yB,oBAAsBoC,YAAY,WACd,MAAjBhH,GAA0BA,EAAgB,MAAQ,GAAIhrB,OAAOC,YAC7D+qB,EAAgB,KAGZT,IACAgE,IAEIhE,IACAA,GAAc,EACdC,GAAe,EAEf6G,EAA6Bt0B,GAE7BkwB,EAAgBlwB,EAAK4uB,4BAIlC5uB,EAAK4uB,wBAGZ,MACJ,KAAK,kBACD,GAAIsG,GAAoBl9B,EAAK2pB,EAEzBqM,GAAmBkH,KACnBlH,EAAmBkH,GAAmB7E,eAAgB,EACtDrC,EAAmBkH,GAAmB5E,cAAe,GAGzD6E,EAA2Bn1B,EAAMk1B,EACjC,MACJ,KAAK,oBACD,GAAIE,GAAsBp9B,EAAK2pB,EAE3BqM,GAAmBoH,KACnBpH,EAAmBoH,GAAqB/E,eAAgB,EACxDrC,EAAmBoH,GAAqB9E,cAAe,GAG3D+E,EAA6Br1B,EAAMo1B,EACnC,MACJ,KAAK,aACD,GAAIp9B,GAAOA,EAAKs9B,GAAKt9B,EAAKs9B,GAAKt9B,EAC3Bu9B,EAAYv9B,EAAKy8B,GACjB/jC,EAAQsH,EAAKs9B,EAGjB,QADA3F,EAA0B3vB,EAAMtP,GACxB6kC,GACJ,IAAK,WACE7kC,EAAMgF,QAAQ,qBAAuB,IAAMhF,EAAMgF,QAAQ,sBAAwB,KAGhFw4B,GAAoB,EAGpBP,GAAmB,EACnBD,GAA4B,EAE5B6D,IAEJ,MACJ,KAAK,YACG58B,GAAWq5B,EAAmBr5B,KAC9Bq5B,EAAmBr5B,GAAS07B,eAAgB,EAEhD,MACJ,KAAK,oBACL,IAAK,sBACL,IAAK,eACG17B,GAAWq5B,EAAmBr5B,KAC9Bq5B,EAAmBr5B,GAAS07B,eAAgB,GAIhD1C,GAAmB,EACnBD,GAA4B,EAE5B6D,IAMJ5D,GACA2G,EAA6Bt0B,EAEjC,MACJ,SACI,GAAIrL,GAAUqD,EAAK2pB,GACfjvB,EAAUsF,EAAKiG,EAGfu3B,EAAe,8CACf5sB,EAAQ4sB,EAAazC,KAAKrgC,GAE1Bq+B,EAAY,KACZ0E,EAAqB,EACrBC,EAAmB,EACnBC,GAAW,CAmCf,IAjCI/sB,GAASA,EAAM1Q,OAAS,IACpB0Q,EAAM,KACNmoB,EAAYnoB,EAAM,IAElBA,EAAM,KACN6sB,EAAqB7sB,EAAM,IAE3BA,EAAM,KACN8sB,EAAmB9sB,EAAM,IAEzBA,EAAM,KACNlW,EAAUkW,EAAM,KAKpBmoB,GACKxD,EAAewD,KAChBxD,EAAewD,GAAaz+B,OAAOoO,OAAO,OAG9C6sB,EAAewD,GAAW0E,GAAsB/iC,EAG5CJ,OAAO04B,KAAKuC,EAAewD,IAAY74B,QAAUw9B,IACjDC,GAAW,IAKfA,GAAW,EAGXA,EAAU,CACV,GAAI5E,EAAW,CACXr+B,EAAU,EAEV,KAAK,GAAIQ,GAAI,EAAQwiC,GAALxiC,EAAuBA,IACnCR,GAAW66B,EAAewD,GAAW79B,GAGrC2hC,eAAeC,YAAYvH,EAAewD,GAAW79B,EAIzD2hC,gBAAeC,YAAYvH,EAAewD,GAG9C6E,EAAyB51B,EAAMrL,EAASjC,IAKpD,KACJ,KAAK,OAQjB,MAAOsN,GAAK4tB,QAMZoH,EAA4B,SAAUh1B,GAC1B,MAARA,GAAoC,MAApBA,EAAKD,aACrBC,EAAKD,YAAYC,IAOrBs0B,EAA+B,SAAUt0B,GAC7B,MAARA,GAAuC,MAAvBA,EAAKsvB,gBACrBtvB,EAAKsvB,eAAetvB,IAOxBm1B,EAA6B,SAAUn1B,EAAMrL,GACjC,MAARqL,GAAqC,MAArBA,EAAKC,cAAmC,MAAXtL,GAC7CqL,EAAKC,aAAaD,EAAMrL,IAO5B0gC,EAA+B,SAAUr1B,EAAMrL,GACnC,MAARqL,GAAuC,MAAvBA,EAAKG,gBAAqC,MAAXxL,GAC/CqL,EAAKG,eAAeH,EAAMrL,IAO9BihC,EAA2B,SAAU51B,EAAMrL,EAASjC,GACxC,MAARsN,GAAgBguB,EAAmBr5B,IAAYq5B,EAAmBr5B,GAAS27B,cAAiE,MAAjDtC,EAAmBr5B,GAASy7B,mBACvHpC,EAAmBr5B,GAASy7B,kBAAkBpwB,EAAMrL,EAASjC,IAOjEi9B,EAA4B,SAAU3vB,EAAMtO,GAChC,MAARsO,GAAoC,MAApBA,EAAKI,aACrBJ,EAAKI,YAAYJ,EAAMtO,IAO3BwhC,EAA+B,SAAUlzB,GAC7B,MAARA,GAAuC,MAAvBA,EAAKuvB,gBACrBvvB,EAAKuvB,eAAevvB,IAOxB+0B,EAA8B,SAAU/0B,GAC5B,MAARA,GAAsC,MAAtBA,EAAKwvB,eACrBxvB,EAAKwvB,cAAcxvB,IApwC/B,GAAIm0B,WAAY9kC,QAAQ,MACpBikC,YAAcjkC,QAAQ,kBACtBgkC,UAAYhkC,QAAQ,OACpB0kC,QAAU1kC,QAAQ,aAClBwmC,GAAKxmC,QAAQ,MACbga,KAAOha,QAAQ,QACfwlC,eAAiBxlC,QAAQ,qBACzB8iC,wBAA0B9iC,QAAQ,4BAEtCG,SAAUD,OAAOC,QAAUgR;;;;AIL3B,GAAIs1B,aAAczmC,QAAQ,eACtBioC,OAASjoC,QAAQ,MAErBO,MAAK2nC,oBACHC,KAAO,IACPC,MAAQ,IACFC,SAAW,KAOnB9nC,KAAK6hC,mBAAqB,SAAUM,EAAeJ,EAAqBC,EAA8BP,EAAgBQ,EAAYP,EAAYQ,EAAa3gC,GACvJ,GAAIwQ,GAAM21B,OAAOp8B,MAAM62B,GAEnB4F,GACAC,GAAIjG,EACJkG,IAAKjG,EACLkG,GAAIzG,EACJ0G,IAAKlG,EACLmG,GAAI1G,EACJ2G,GAAI3lC,OAAOomB,KAAKoZ,GAGpB,KAAK,GAAIoG,KAAcpG,GACnB6F,EAAuBO,GAAcpG,EAAYoG,EAGrD,IAAIC,IACDx2B,IAAMA,EAAI4xB,SACT4C,KAAOx0B,EAAIw0B,KACX9sB,KAAO,gBACP+oB,WAAauF,EACbxmC,SAAW,SAAST,GACbA,EACCS,EAAST,EAAMijC,SAAQ,GAEvBxiC,EAAS,MAAK,IAK1BkgB,MAAK8mB,IAGTvoC,KAAK6iC,eAAiB,SAASL,EAAWjhC,GACtC,GAAIwQ,GAAM21B,OAAOp8B,MAAMk3B,EAAWzwB,KAE9By2B,GAAqBC,WAAajG,EAAWd,WAC9Cc,GAAWM,WACV0F,EAA2B,SAAIhG,EAAWM,SAG9C,IAAI4F,IACD32B,IAAMA,EAAI4xB,SACT4C,KAAOx0B,EAAIw0B,KACX9sB,KAAO,oBAAsB+oB,EAAW3C,OAAS,IAAM2C,EAAWz9B,QAClEy9B,WAAagG,EACbjnC,SAAW,SAAST,EAAMqE,GACnBrE,EACCS,EAAST,EAAMijC,QAAQ,MAEpB5+B,EACC5D,EAAS,KAAK4D,EAAO4+B,SAErBxiC,EAAS,KAAK,OAM9BkgB,MAAKinB,IAGT1oC,KAAK+iC,gBAAkB,SAASP,EAAWjhC,GACvC,GAAIwQ,GAAM21B,OAAOp8B,MAAMk3B,EAAWzwB,KAE9B42B,GACD52B,IAAMA,EAAI4xB,SACT4C,KAAOx0B,EAAIw0B,KACX9sB,KAAO,qBAAuB+oB,EAAW3C,OAAS,IAAM2C,EAAWz9B,QACnEy9B,YAAeiG,WAAajG,EAAWd,YACvCngC,SAAW,SAAST,EAAMqE,GACnBrE,EACCS,EAAST,EAAMijC,QAAQ,MAEpB5+B,EACC5D,EAAS,KAAK4D,EAAO4+B,SAErBxiC,EAAS,KAAK,OAM9BkgB,MAAKknB,IAGT3oC,KAAK4iC,YAAc,SAASJ,EAAWjhC,GACnC,GAAIwQ,GAAM21B,OAAOp8B,MAAMk3B,EAAWzwB,KAE9B22B,GACA32B,IAAMA,EAAI4xB,SACV4C,KAAOx0B,EAAIw0B,KACX9sB,KAAO,aAAe+oB,EAAW3C,OAAS,IAAM2C,EAAW1C,UAAY,IAAM0C,EAAWz9B,QACxFxD,SAAW,SAAST,EAAMqE,GACtB,GAAGrE,EACCS,EAAST,EAAMijC,QAAQ,UACtB,CACD,GAAI37B,GAAO,IACX,IAAGjD,EACC,IACIiD,EAAOiD,KAAKC,MAAMnG,EAAO4+B,SAC5B,MAAMroB,IAEXna,EAAS,KAAK6G,KAK1BzE,KAAI+kC,GAIR,IAAIjnB,MAAO,SAAU0kB,GACjB,GAAIC,GAAeD,EAAS3D,WAAmD,gBAAxB2D,GAAmB,WAAiBA,EAAS3D,WAAa0D,YAAY15B,UAAU25B,EAAS3D,YAAvG,GAErCoG,GACAtC,KAAQH,EAASp0B,IACjBw0B,KAAQJ,EAASI,KACjB9sB,KAAQ0sB,EAAS1sB,KACjB3P,OAAU,OACVu8B,SACIG,iBAAkBJ,EAAY99B,OAC9Bm+B,eAAgB,qCAIxB,KAAI,GAAIoC,KAAe1C,GAASE,QAC5BuC,EAAYvC,QAAQwC,GAAe1C,EAASE,QAAQwC,EAGxD,IAAInC,GAAuDjnC,QAAzB,KAAjB0mC,EAASI,MAAeJ,EAAS2C,OAAiB,QAAmB,QAElFxkC,EAAUoiC,EAAWpiC,QAAQskC,EAAa,SAAUlkC,GACpD,GAAIiiC,GAAajiC,EAASiiC,WACtBv+B,EAAO,EAEX1D,GAASoE,YAAY,OAAQ,SAAU89B,GACnCx+B,GAAQw+B,IAGZliC,EAASoE,YAAY,MAAO,WACpB69B,GAAc,KAAqB,KAAdA,EACrBR,EAAS5kC,UACLsC,KAAM8iC,EACN5C,QAAS,GAAI5vB,QAAO/L,EAAM,UAAUgM,YACrC,MAEH+xB,EAAS5kC,SAAS,MACdsC,KAAM8iC,EACN5C,QAAS,GAAI5vB,QAAO/L,EAAM,UAAUgM,gBAMpD9P,GAAQgC,GAAG,QAAS,SAAUxF,GAC1BqlC,EAAS5kC,UACLsC,KAAM,KACNkgC,QAASjjC,EAAMsT,YAChB,QAGP9P,EAAQ2vB,MAAMmS,GACd9hC,EAAQ0c,OAGRrd,IAAM,SAAUkjC,GAChB,GAAIC,GAAiBD,EAAQrE,WAAkD,gBAAvBqE,GAAkB,WAAiBA,EAAQrE,WAAa0D,YAAY15B,UAAUq6B,EAAQrE,YAApG,GACtCuE,EAAcD,EAAgBD,EAAQptB,KAAO,IAAMqtB,EAAgBD,EAAQptB,KAE3EsvB,GACAzC,KAAQO,EAAQ90B,IAChBw0B,KAAQM,EAAQN,KAChB9sB,KAAQstB,EACRj9B,OAAW,MAGf,KAAI,GAAI++B,KAAehC,GAAQR,QAC3B0C,EAAW1C,QAAU0C,EAAW1C,QAAU0C,EAAW1C,WAErD0C,EAAW1C,QAAQwC,GAAehC,EAAQR,QAAQwC,EAGtD,IAAInC,GAAqDjnC,QAAxB,KAAhBonC,EAAQN,MAAeM,EAAQiC,OAAiB,QAAmB,QAEhFxkC,EAAUoiC,EAAW/iC,IAAIolC,EAAY,SAAUrkC,GAC/C,GAAIiiC,GAAajiC,EAASiiC,WACtBv+B,EAAO,EAEX1D,GAASoE,YAAY,OAAQ,SAAU89B,GACnCx+B,GAAQw+B,IAGZliC,EAASoE,YAAY,MAAO,WACpB69B,GAAc,KAAqB,KAAdA,EACrBE,EAAQtlC,UACJsC,KAAM8iC,EACN5C,QAAS,GAAI5vB,QAAO/L,EAAM,UAAUgM,YACrC,MAEHyyB,EAAQtlC,SAAS,MACbsC,KAAM8iC,EACN5C,QAAS,GAAI5vB,QAAO/L,EAAM,UAAUgM,gBAMpD9P,GAAQgC,GAAG,QAAS,SAAUxF,GAC1B+lC,EAAQtlC,UACJsC,KAAM,KACNkgC,QAASjjC,EAAMsT,YAChB,QAGP9P,EAAQ0c,MAGZte,QAAOomB,KAAO,SAAS2e,GACnB,GAAc54B,GAAVia,EAAO,CACX,KAAKja,IAAO44B,GACJA,EAAIluB,eAAe1K,IAAMia,GAEjC,OAAOA;;;;AHhPX,GAAIod,aAAczmC,QAAQ,cAE1BO,MAAKyhB,KAAO,SAAU0kB,GAClB,GAAIC,GAAeD,EAAS3D,WAAmD,gBAAxB2D,GAAmB,WAAiBA,EAAS3D,WAAa0D,YAAY15B,UAAU25B,EAAS3D,YAAvG,GAErC6D,GACAC,KAAQH,EAASp0B,IACjBw0B,KAAQJ,EAASI,KACjB9sB,KAAQ0sB,EAAS1sB,KACjB3P,OAAU,OACV08B,iBAAkBJ,EAAY99B,OAC9Bm+B,eAAgB,sCAGhBC,EAAoCjnC,QAAN,KAAjB0mC,EAASI,KAAsB,QAAmB,QAE/DjiC,EAAUoiC,EAAWpiC,QAAQ+hC,EAAS,SAAU3hC,GAChD,GAAIiiC,GAAajiC,EAASiiC,WACtBv+B,EAAO,EAEX1D,GAASoE,YAAY,OAAQ,SAAU89B,GACnCx+B,GAAQw+B,IAGZliC,EAASoE,YAAY,MAAO,WACpB69B,GAAc,KAAqB,KAAdA,EACrBR,EAAS5kC,UACLsC,KAAM8iC,EACN5C,QAAS,GAAI5vB,QAAO/L,EAAM,UAAUgM,YACrC,MAEH+xB,EAAS5kC,SAAS,MACdsC,KAAM8iC,EACN5C,QAAS,GAAI5vB,QAAO/L,EAAM,UAAUgM,gBAMpD9P,GAAQgC,GAAG,QAAS,SAAUxF,GAC1BqlC,EAAS5kC,UACLsC,KAAM,KACNkgC,QAASjjC,EAAMsT,YAChB,QAGP9P,EAAQ2vB,MAAMmS,GACd9hC,EAAQ0c,OAGZhhB,KAAK2D,IAAM,SAAUkjC,GACjB,GAAIC,GAAiBD,EAAQrE,WAAkD,gBAAvBqE,GAAkB,WAAiBA,EAAQrE,WAAa0D,YAAY15B,UAAUq6B,EAAQrE,YAApG,GACtCuE,EAAcD,EAAgBD,EAAQptB,KAAO,IAAMqtB,EAAgBD,EAAQptB,KAE3E4sB,GACAC,KAAQO,EAAQ90B,IAChBw0B,KAAQM,EAAQN,KAChB9sB,KAAQstB,EACRC,aAAe,wBAGfN,EAAmCjnC,QAAN,KAAhBonC,EAAQN,KAAsB,QAAmB,QAE9DjiC,EAAUoiC,EAAW/iC,IAAI0iC,EAAS,SAAU3hC,GAC5C,GAAIiiC,GAAajiC,EAASiiC,WACtBv+B,EAAO,EAEX1D,GAASoE,YAAY,OAAQ,SAAU89B,GACnCx+B,GAAQw+B,IAGZliC,EAASoE,YAAY,MAAO,WACpB69B,GAAc,KAAqB,KAAdA,EACrBE,EAAQtlC,UACJsC,KAAM8iC,EACN5C,QAAS,GAAI5vB,QAAO/L,EAAM,UAAUgM,YACrC,MAEHyyB,EAAQtlC,SAAS,MACbsC,KAAM8iC,EACN5C,QAAS,GAAI5vB,QAAO/L,EAAM,UAAUgM,gBAMpD9P,GAAQgC,GAAG,QAAS,SAAUxF,GAC1B+lC,EAAQtlC,UACJsC,KAAM,KACNkgC,QAASjjC,EAAMsT,YAChB,QAGP9P,EAAQ0c;;;;AJzFZrhB,OAAOC,SACHgR,kBAAmBnR,QAAQ;;AUI/BO,KAAKovC,YAAc,SAAUnmB,EAAKyD,GAC9B,GAAIvnB,GAAShF,KAAKqqB,MAAMvB,EAAM9oB,KAAK4W,IAAI,GAAI2V,IAAQvsB,KAAK4W,IAAI,GAAI2V,EAChE,OAAOvnB,IAOXnF,KAAKwnC,cAAgB,SAASngB,GAC1B,MAAOlnB,MAAKqjB,MAAMrjB,KAAK0R,SAAWwV;;AGatC,QAAS+f,IAAGiN,EAAK9hB,GACf,GAAI+hB,EAMJ,OAJEA,GADE/hB,EACS,GAAIgS,WAAU8P,EAAK9hB,GAEnB,GAAIgS,WAAU8P,GAhC7B,GAAIn/B,QAAS,WAAc,MAAOlV,SAM9BukC,UAAYrvB,OAAOqvB,WAAarvB,OAAOq/B,YAM3C50C,QAAOC,QAAU2kC,UAAY6C,GAAK,KAyB9B7C,YAAW6C,GAAG1mC,UAAY6jC,UAAU7jC;;APhCxCV,KAAKklC,YAAc,SAAUuC,EAAK54B,GAC9B,GAAIjM,GAAQ6kC,EAAI54B,EAEhB,OADAjM,GAAQ,WACM6kC,GAAI54B;;ADTtB,GAAIo4B,MAAOxnC,QAAQ,QACfynC,KAAOznC,QAAQ,SAMnBO,MAAKk3B,KAAO,SAAUiQ,GAIlB,IAHA,GAAIvuB,GAAMuuB,EAAKz0B,QAAQ,SAAU,IACnC00B,EAAK,KACL9jC,EAAIsV,EAAItQ,OACC8+B,EAAGzP,KAAK/e,EAAI8N,SAASpjB,MAC5B,MAAOsV,GAAIzK,MAAM,EAAG7K,EAAI,IAM5BtD,KAAKqnC,aAAe,WACZ,GAAIjE,GAAK,WACL,OAA+B,OAArB,EAAIjjC,KAAK0R,UAAuB,GAAGuC,SAAS,IAAI4sB,UAAU,GAExE,OAAQoC,KAAOA,IAAO,IAAMA,IAAO,IAAMA,IAAO,IAAMA,IAAO,IAAMA,IAAOA,IAAOA,IAGzF,IAAIkE,qBAAsB,uCAK1BtnC,MAAKokC,cAAgB,SAAS97B,EAAQ+e,GAClCA,EAAMA,GAAOigB,oBAAoBh/B,MACjC,IAAIhF,GAAGwL,IACP,KAAIxL,EAAE,EAAOgF,EAAJhF,EAAYA,IACjBwL,EAAI9J,KAAMsiC,oBAAoBjzB,OAAOlU,KAAKqjB,MAAMrjB,KAAK0R,SAAWwV,GAAK,GAEzE,OAAOvY,GAAIgJ,KAAK,KAOpB9X,KAAKskC,qBAAuB,SAASjd,GACjC,GAAI4D,IAAK,IAAI5D,EAAM,IAAI/e,OACnBi/B,EAAIliC,MAAM4lB,EAAE,GAAGnT,KAAK,IACxB,QAAQyvB,EAAIL,KAAKM,cAAcngB,IAAMlZ,OAAO8c;;AnBhD9CtrB,OAAOC,QAFoB,kBAAlB8C,QAAOoO,OAEC,SAAkBC,EAAMC,GACvCD,EAAKE,OAASD,EACdD,EAAKrQ,UAAYgC,OAAOoO,OAAOE,EAAUtQ,WACvC2J,aACEzH,MAAOmO,EACPG,YAAY,EACZC,UAAU,EACVC,cAAc,MAMH,SAAkBL,EAAMC,GACvCD,EAAKE,OAASD,CACd,IAAIK,GAAW,YACfA,GAAS3Q,UAAYsQ,EAAUtQ,UAC/BqQ,EAAKrQ,UAAY,GAAI2Q,GACrBN,EAAKrQ,UAAU2J,YAAc0G;;CInBjC,WACE,GAAIvJ,GAAcsN,EAAMC,EAA4BnS,EAAOoS,CAiB3D,IAfAxN,EAAe/H,QAAQ,UAAU+H,aAEjCuN,EAA6B,WAC3B,GAAID,GAAMlS,EAAOoS,CAEjBA,GAAOxN,EAAa9G,SACpB,KAAKoU,IAAQE,GAEX,GADApS,EAAQoS,EAAKF,GACQ,MAAjBvN,QAAQuN,GACV,OAAO,CAGX,QAAO,GAGgB,mBAAXlN,SAAqC,OAAXA,QAAoBA,OAAOqN,UAAYrN,OAAO6D,WAI5D,mBAAZlE,UAAuC,OAAZA,SAAwC,mBAAX2N,SAAqC,OAAXA,QAI5FtN,SAAWsN,QAIQ,OAAnBtN,OAAO3G,SAIN8T,IAAL,CAIAC,EAAOxN,EAAa9G,SACpB,KAAKoU,IAAQE,GACXpS,EAAQoS,EAAKF,GACbvN,QAAQuN,GAAQlS,CAGlBgF,QAAO3G,QAAU,SAASkU,EAAKpD,EAAKqD,GAClC,MAAO7N,SAAQrG,KAAK,oBAAqB,GAAIC,OAAM,GAAKgU,EAAM,KAAOpD,EAAM,IAAMqD,EAAO,OAG1FxN,OAAO/F,iBAAiB,SAAU,WAChC,MAAO0F,SAAQrG,KAAK,aAGrBnB,KAAKC;;;;AMrDR,QAAS4W,UAEP,GAAIqkB,KAGJj7B,MAAKsF,QAAU,SAAS/D,GAEtB,IAAI,GAAIsN,KAAOosB,GACf,CACE,GAAI9yB,GAAS8yB,EAAQpsB,EAErB,KAAI,GAAIqsB,KAAQ/yB,GACd5G,EAAS4G,EAAO+yB,MAItBl7B,KAAK2D,IAAM,SAASwI,EAAIhE,GAEtB,GAAIgzB,GAAMF,EAAQ9yB,EAClB,OAAUjI,SAAPi7B,EACMj7B,OAEFi7B,EAAIhvB,IAGbnM,KAAK4V,OAAS,SAASzJ,EAAIhE,GAEzB,GAAIgzB,GAAMF,EAAQ9yB,EACRjI,SAAPi7B,UAGIA,GAAIhvB,GAEPzJ,OAAO04B,KAAKD,GAAK7yB,cACZ2yB,GAAQ9yB,KAGnBnI,KAAK8V,IAAM,SAASlT,EAAOuJ,EAAIhE,GAE7B,GAAYjI,QAAT0C,EACD,MAAO5C,MAAK4V,OAAOzJ,EAAIhE,EAEzB,IAAIgzB,GAAMF,EAAQ9yB,EACRjI,SAAPi7B,IACDF,EAAQ9yB,GAAUgzB,MAEpBA,EAAIhvB,GAAMvJ,GAKdgU,OAAOlW,UAAU8V,IAAM,SAASrK,EAAIhE,GAElC,GAAIvF,GAAQ5C,KAAK2D,IAAIwI,EAAIhE,EACzB,OAAYjI,SAAT0C,EACM1C,QAETF,KAAK4V,OAAOzJ,EAAIhE,GAETvF,IAITjD,OAAOC,QAAUgX;;ALvCjB,QAASvB,sBAAqB1I,GAE5B,IAAIA,EAAiB,QAErB,KAAI,GAAIkC,KAAOlC,GACf,CACE,GAAI/J,GAAQ+J,EAAgBkC,EAET,iBAATjM,KACR+J,EAAgBkC,IAEdnK,SAAU9B,IAIhB,MAAO+J,GAGT,QAAS2I,gBAAeC,GAEtB,GAAIA,EAAJ,CAEA,GAAGA,YAAqBlO,UACtB,MAAOkO,EAET,IAAGA,EAAU/R,eAAgB6D,UAC3B,MAAOkO,GAAU/R,KAAK8M,KAAKiF,EAE7B,IAAGA,EAAUxN,sBAAuBV,UAClC,MAAOkO,GAAUxN,YAAYuI,KAAKiF,EAEpC,MAAM,IAAIjO,aAAY,mDAcxB,QAASkO,iBAAgB1L,EAAQC,GAE/BrH,OAAOC,eAAe3C,KAAM,UAAW4C,MAAOkH,EAAQoH,YAAY,IAClExO,OAAOC,eAAe3C,KAAM,UAAW4C,MAAOmH,EAAQmH,YAAY,IASpE,QAASpK,YAAWC,EAAQ/F,EAASuU,GAiDnC,QAASE,GAAc3S,EAASqJ,EAAInJ,GAElC,GAAI0B,IAEF5B,QAASA,EAET4S,QAASjN,WAAW,WAElBkN,EAAUC,OAAOzJ,EAAInJ,IAEvB6S,GAGFF,GAAUG,IAAIpR,EAAUyH,EAAInJ,GAM9B,QAAS+S,GAAuBrJ,EAAKzJ,GAEnC,GAAIyS,GAAUjN,WAAW,WAEvBuN,EAAmBJ,OAAOlJ,EAAKzJ,IAEjCgT,EAEAD,GAAmBF,IAAIJ,EAAShJ,EAAKzJ,GAiBvC,QAASiT,GAAWpM,EAAQC,EAAQoC,EAAIlJ,EAAMsS,GAE5CC,gBAAgBzV,KAAKC,KAAM8J,EAAQC,GAEnC/J,KAAKuV,UAAYA,CAEjB,IAAI7Q,GAAWiR,EAAUhS,IAAIwI,EAAIlJ,EAKjCsS,GAAYA,GAAatV,EAAKsV,UAC1BA,GACF7S,OAAOC,eAAe3C,KAAM,cAE1B4C,MAAOuT,QAAQzR,IAGnB,IAAI0R,GAAiBzJ,EAAgB7C,EAErC9J,MAAKoD,KAAO,WAEV,MAAO2D,GAAO3D,KAAKpD,KAAMmM,IAW3BnM,KAAKwE,MAAQ,SAAS1D,EAAOqE,EAAQoQ,GAGnC,GAAGzU,YAAiBuG,WAAYvG,GAASA,EAAM0C,eAAgB6D,UAC/D,CACE,GAAanH,QAAViF,EACD,KAAM,IAAImC,aAAY,2CAExBiO,GAAYzU,EACZqE,EAAS,KACTrE,EAAQZ,WAGL,IAAGiF,YAAkBkC,WACvBlC,GAAUA,EAAO3B,eAAgB6D,UACpC,CACE,GAAgBnH,QAAbqV,EACD,KAAM,IAAIjO,aAAY,2CAExBiO,GAAYpQ,EACZA,EAAS,KAGXoQ,EAAYD,eAAeC,GAGxB7Q,GACD2R,aAAa3R,EAASgR,SAEbxV,QAAR+C,IAEEnC,IACDA,EAAMkC,KAAOC,GAEZkC,IACDA,EAAOnC,KAAOC,GAGlB,IAAIH,EAGJ,IAAGhC,GAAmBZ,QAAViF,EACZ,CAUE,GATkBjF,QAAfD,EAAK4G,SAEH/F,EACDA,EAAMmC,KAAOhD,EAAK4G,OAElB1B,EAAOlC,KAAOhD,EAAK4G,QAIpBuP,EAED,GAA2BlW,QAAxBkW,EAAetV,OAAsBA,EACtCgC,GAEEhC,MAAOA,OAIX,CACE,GAAIgJ,GAAShJ,EACAsV,EAAetV,MACfsV,EAAe1R,QAE5B5B,IAEEgH,OAAQA,EACRC,OAAQjJ,GAASqE,OAKrBrC,IAEEhC,MAAQA,EACRqE,OAAQA,EAGZrC,GAAUiE,EAAO3D,KAAKN,EAASqJ,OAK/BrJ,GADM4B,EACIA,EAAS5B,QAITiE,EAAO3D,MAAM+B,OAAQ,MAAOgH,EAQxC,OALAsJ,GAAc3S,EAASqJ,EAAIlJ,GAG3BsS,EAAYA,GAAavV,KAAKuV,WAAatV,EAAKsV,UAE7CA,EACMA,EAAUzS,GAEZA,GAMX,QAASkB,GAAOlB,GAEd,GAAI+L,GAAMyH,EAAYxT,EACtB,IAAI+L,EAAJ,OAEOyH,GAAYxT,EAEnB,IAAIwB,GAAUiS,EAASC,IAAI3H,EAAI1C,GAAI0C,EAAI7L,KACnCsB,KAEJ+R,aAAa/R,EAAQoR,SAGrBK,EAAuBlH,EAAI1C,GAAI0C,EAAI7L,QAnPrC,GAAI/C,GAAOD,IAEX,KAAI+G,EACF,KAAM,IAAIO,aAAY,wBAExB,KAAIP,EAAO3D,OAAS2D,EAAO0F,OACzB,KAAM,IAAInF,aAAY,oBAExB,IAAIqF,GAAkB0I,qBAAqBtO,EAAO4F,gBAGlD,IAAG3L,YAAmBqG,WAAYrG,GAAWA,EAAQwC,eAAgB6D,UACrE,CACE,GAAGkO,EACD,KAAM,IAAIjO,aAAY,2CAExBiO,GAAYvU,EACZA,EAAUd,OAGZc,EAAUA,MAGV0B,OAAOC,eAAe3C,KAAM,UAAW4C,MAAO5B,EAAQ6F,QAEtD,IAAID,GAAc5F,EAAQ4F,aAAe,CAGzC5G,MAAKuV,UAAYD,eAAeC,EAEhC,MAAMkB,GAAqBzV,EAAQyV,iBAAsBC,aACnDb,EAAqB7U,EAAQ6U,kBAAsBa,aACnDT,EAAqBjV,EAAQiV,oBAAsBS,YAGzD,IAAIC,GAAY,EAEZJ,EAAY,GAAIK,QAChBjB,EAAY,GAAIiB,QAChBZ,EAAqB,GAAIY,QAEzBN,IA0LJ7V,UAASyV,EAAYV,iBAwBrBxV,KAAKgE,OAAS,SAASlB,GAErB,GAAGA,EAAS,MAAOkB,GAAOlB,EAE1B,KAAI,GAAIA,KAAWwT,GACjBtS,EAAOlB,IAIX9C,KAAKQ,MAAQ,WAGR+U,GAAaA,EAAU/U,OACvB+U,EAAU/U,QAGbR,KAAKgE,SAELgS,EAAmB1Q,QAAQ,SAASoQ,GAElCW,aAAaX,KAIfC,EAAUrQ,QAAQ,SAASZ,GAEzB2R,aAAa3R,EAASgR,YAiB1B1V,KAAKkF,OAAS,SAAS4E,EAAQC,EAAQ/G,EAAMuS,EAAWhU,GAgEpD,QAASsV,GAAiB/V,EAAOqE,GAE/BlF,EAAK+D,OAAOlB,GAEZvB,EAAST,EAAOqE,GAKlB,QAAS2R,GAAYvB,GAQnB,MANAjR,GAAQoR,QAAUjN,WAAWiN,EACAe,EAAgBtW,KAAK4W,IAAI,EAAGC,MACzDV,EAAYxT,IAAYqJ,GAAIA,EAAInJ,KAAMA,GACtCuT,EAAST,IAAIxR,EAAS6H,EAAInJ,GAE1BuS,EAAYA,GAAa0B,GAAoBhX,EAAKsV,UAC/CA,EACMA,EAAUzS,GAEZA,EAGT,QAASoU,GAAM3B,GAEbA,EAAYD,eAAeC,GAE3BxU,QAAQoC,KAAK6T,EAAQ,8BAA8BlU,EAEnD,IAAI4S,GAAUM,EAAmBQ,IAAIrK,EAAInJ,EAGzC,OAFAqT,cAAaX,GAENoB,EAAYvB,GAGrB,QAASG,KAEP,GAAa9O,EAAVoQ,EACD,MAAOE,GAAM3B,EAEf,IAAIzU,GAAQ,GAAIK,OAAM,wBAClBL,GAAMwD,QAAUxB,EAEpBhC,EAAMoW,MAAQA,EAEdL,EAAiB/V,GA1GrB,GAAGiJ,YAAkB1C,UACrB,CACE,GAAWnH,QAAR8C,EACD,KAAM,IAAIsE,aAAY,2CAExB/F,GAAYwI,EACZwL,EAAYrV,OACZ8C,EAAY9C,OACZ6J,EAAY7J,WAGT,IAAG8C,YAAgBqE,UACxB,CACE,GAAgBnH,QAAbqV,EACD,KAAM,IAAIjO,aAAY,2CAExB/F,GAAYyB,EACZuS,EAAYrV,OACZ8C,EAAY9C,WAGT,IAAGqV,YAAqBlO,UAC7B,CACE,GAAenH,QAAZqB,EACD,KAAM,IAAI+F,aAAY,2CAExB/F,GAAYgU,EACZA,EAAYrV,OAGIA,QAAfD,EAAK4G,SAENkD,EAASA,MAETA,EAAO9G,KAAOhD,EAAK4G,QAGV3G,QAAR8C,IACD+G,EAAO/G,KAAOA,EAGhB,IAAIF,IAEFgH,OAAQA,EACRC,OAAQA,EAGV,IAAGxI,EACH,CACE,GAAI4K,GAAKwK,IACLK,EAAU,CAEdlU,GAAUiE,EAAO3D,KAAKN,EAASqJ,EAE/B,IAAI7H,IAEFxB,QAAiBA,EACjBvB,SAAiBsV,EACjBlK,gBAAiBA,EAAgB7C,QAU/BmN,EAAmB3B,eAAeC,EAyCtC,OAAOuB,GAAYvB,GAOrB,MAHAzS,GAAUiE,EAAO3D,KAAKN,GAEtByS,EAAYA,GAAatV,EAAKsV,UAC3BA,EACMA,EAAUzS,GAEZA,GAcT9C,KAAKiP,OAAS,SAASnM,EAASyS,GAuB9B,QAAS4B,KAIP,GADA5B,EAAYD,eAAeC,IAActV,EAAKsV,UAE9C,CACE,GAAI7Q,GAAWiR,EAAUhS,IAAIwI,EAAIlJ,EACjC,IAAGyB,EACD,MAAO6Q,GAAU7Q,EAAS5B,SAG9B,GAAIsU,GAAelX,QAANiM,EAAmBA,EAAKO,CACrC,OAAO,IAAIwJ,GAAWpM,EAAQC,EAAQqN,EAAOnU,EAAMsS,GAGrD,QAAS8B,GAAgB/S,EAASxD,EAAOqE,GAEvCb,EAAQ/C,SAAST,EAAOqE,GAG1B,QAASmS,GAAmB5B,GAE1B3U,QAAQoC,KAAK,6BAA8BL,GAG3CuT,aAAaX,GACbK,EAAuBrJ,EAAKzJ,GA/C9B,IAAIH,EACF,KAAM,IAAIkK,WAAU,yBAEtBlK,GAAUiE,EAAO0F,OAAO3J,EAExB,IAAIqJ,GAASrJ,EAAQqJ,GACjBO,EAAS5J,EAAQ4J,IACjB5C,EAAShH,EAAQgH,OACjBC,EAASjH,EAAQiH,WAEjB9G,EAAO8G,EAAO9G,KACdD,EAAO+G,EAAO/G,IAGlB,IAAkB9C,QAAfD,EAAK4G,QAAuB5D,GAAQhD,EAAK4G,OAA5C,CAGA,GAAS3G,QAANiM,GAA0BjM,QAAPwM,EACpB,MAAO,IAAI8I,iBAAgB1L,EAAQC,EAkCrC,IAAGD,EACH,CAEE,GAAW5J,QAAR8C,GAAqBA,GAAQ/C,EAAK4G,OACrC,CACE,GAAIvC,GAAUiS,EAAS5S,IAAI+I,EAAKzJ,EAChC,IAAGqB,EACH,CACE,GAAIqI,GAAkBrI,EAAQqI,eAE9B,OAAG7C,IAAU6C,EAAgB7L,MACpBuW,EAAgB/S,EAASyF,GAE/BD,GAAU6C,EAAgBjI,SACpB2S,EAAgB/S,EAAS,KAAMyF,GAEjCoN,IAGT,GAAI5S,GAAYyR,EAAmBrS,IAAI+I,EAAKzJ,EAC5C,IAAGsB,EACD,MAAO+S,GAAmB/S,GAI9B,MAAO4S,KAGT,GAAIrW,GAASgC,EAAQhC,MACjBqE,EAASrC,EAAQqC,MAGrB,MAAGrE,GAAUA,EAAMkC,MAASlC,EAAMkC,MAAS/C,EAAKoB,WAC7C8D,GAAUA,EAAOnC,MAAQmC,EAAOnC,MAAQ/C,EAAKoB,WAAhD,CAGA,GAAIiD,GAAUiS,EAAS5S,IAAI+I,EAAKzJ,EAChC,KAAIqB,EACJ,CACE,GAAIC,GAAYyR,EAAmBrS,IAAI+I,EAAKzJ,EAC5C,OAAGsB,GACM+S,EAAmB/S,GAErBxD,QAAQoC,KAAK,2CAA4CL,GAIlEuU,EAAgB/S,EAASxD,EAAOqE,MAvlBpC,GAAI1E,UAAWhB,QAAQ,YAEnB8X,QAAU9X,QAAQ,aAClBmX,OAASnX,QAAQ,WAGrB,MAAMiX,cAAe,GAslBrB5P,YAAW0O,gBAAkBA,gBAG7B7V,OAAOC,QAAUkH,WAEjBA,WAAWyQ,QAAUA;;AOpmBrB,QAASnU,MAAKN,EAASqJ,GAErB,GAAIhH,IAEFo2B,QAAS,MAIX,IAAGz4B,EAAQgH,OAET3E,EAAO2E,OAAShH,EAAQgH,OAErBhH,EAAQiH,SACT5E,EAAO4E,OAASjH,EAAQiH,QAGjB7J,QAANiM,IACDhH,EAAOgH,GAAKA,OAIX,IAASjM,QAANiM,EACR,CACE,GAAGrJ,EAAQhC,MACX,CACE,GAAsBZ,SAAnB4C,EAAQqC,OACT,KAAM,IAAI6H,WAAU,oCAEtB7H,GAAOrE,MAAQgC,EAAQhC,UAEpB,CAAA,GAAsBZ,SAAnB4C,EAAQqC,OAGd,KAAM,IAAI6H,WAAU,gCAFpB7H,GAAOA,OAASrC,EAAQqC,OAI1BA,EAAOgH,GAAKA,EAGd,MAAOd,MAAKmB,UAAUrH,GAYxB,QAASsH,QAAO3J,GAEd,GAAIqC,GAASrC,GAEQ,gBAAXA,IAAuBA,YAAmBsjB,WAClDjhB,EAASkG,KAAKC,MAAMxI,GAItB,IAAI04B,GAAUr2B,EAAOo2B,OACrB,IAAc,OAAXC,EACD,KAAM,IAAIxuB,WAAU,4BAA4BwuB,EAAQ,MAAM14B,EAGhE,IAAoB5C,QAAjBiF,EAAO2E,OACV,CACE,GAAgB5J,QAAbiF,EAAOgH,GACR,KAAM,IAAIa,WAAU,oBAAoBlK,EAE1C,IAAI24B,GAAmCv7B,SAAlBiF,EAAOA,OACxBu2B,EAAmCx7B,SAAlBiF,EAAOrE,KAG5B,IAAG26B,GAAkBC,EACnB,KAAM,IAAI1uB,WAAU,sCAAsClK,EAE5D,KAAI24B,IAAmBC,EACrB,KAAM,IAAI1uB,WAAU,kCAAkClK,EAExDqC,GAAOuH,IAAMvH,EAAOgH,SACbhH,GAAOgH,GAIhB,MAAOhH,GAITvF,QAAQwD,KAASA,KACjBxD,QAAQ6M,OAASA;;ACrGjB,QAASrJ,QAEP,KAAM,IAAI4J,WAAU,uBAGtB,QAASP,UAEP,KAAM,IAAIO,WAAU,uBAItBpN,QAAQwD,KAASA,KACjBxD,QAAQ6M,OAASA;;AFZjB,GAAI4uB,SAAU57B,QAAQ,aAClB67B,OAAU77B,QAAQ,WAGtBG,SAAQy7B,QAAUA,QAClBz7B,QAAQ07B,OAAUA;;;;AHJlB,GAAIrnB,IAEJ,IAAIiB,OAAOyR,QAAUA,OAAOoM,gBAAiB,CAG3C,GAAIC,QAAS,GAAIC,YAAW,GAC5Bhf,KAAM,WAEJ,MADA0S,QAAOoM,gBAAgBC,QAChBA,QAIX,IAAK/e,IAAK,CAKR,GAAKif,OAAQ,GAAI7tB,OAAM,GACvB4O,KAAM,WACJ,IAAK,GAAWkF,GAAP7V,EAAI,EAAU,GAAJA,EAAQA,IACN,KAAV,EAAJA,KAAiB6V,EAAoB,WAAhBhZ,KAAK0R,UAC/BqhB,MAAM5vB,GAAK6V,MAAY,EAAJ7V,IAAa,GAAK,GAGvC,OAAO4vB,QAIXvzB,OAAOC,QAAUqU;;;;ANPjB,QAAS3I,OAAM+G,EAAGC,EAAKC,GACrB,GAAIjP,GAAKgP,GAAOC,GAAW,EAAGC,EAAK,CAUnC,KARAF,EAAMA,MACND,EAAEI,cAAcC,QAAQ,eAAgB,SAASC,GACtC,GAALH,IACFF,EAAIhP,EAAIkP,KAAQI,WAAWD,MAKnB,GAALH,GACLF,EAAIhP,EAAIkP,KAAQ,CAGlB,OAAOF,GAIT,QAASO,SAAQP,EAAKC,GACpB,GAAIjP,GAAIiP,GAAU,EAAGO,EAAMC,UAC3B,OAAQD,GAAIR,EAAIhP,MAAQwP,EAAIR,EAAIhP,MACxBwP,EAAIR,EAAIhP,MAAQwP,EAAIR,EAAIhP,MAAQ,IAChCwP,EAAIR,EAAIhP,MAAQwP,EAAIR,EAAIhP,MAAQ,IAChCwP,EAAIR,EAAIhP,MAAQwP,EAAIR,EAAIhP,MAAQ,IAChCwP,EAAIR,EAAIhP,MAAQwP,EAAIR,EAAIhP,MAAQ,IAChCwP,EAAIR,EAAIhP,MAAQwP,EAAIR,EAAIhP,MACxBwP,EAAIR,EAAIhP,MAAQwP,EAAIR,EAAIhP,MACxBwP,EAAIR,EAAIhP,MAAQwP,EAAIR,EAAIhP,MAwBlC,QAAS0P,IAAGhS,EAASsR,EAAKC,GACxB,GAAIjP,GAAIgP,GAAOC,GAAU,EACrBU,EAAIX,KAERtR,GAAUA,KAEV,IAAIkS,GAAgChT,SAArBc,EAAQkS,SAAyBlS,EAAQkS,SAAWC,UAM/DC,EAA0BlT,SAAlBc,EAAQoS,MAAsBpS,EAAQoS,OAAQ,GAAIC,OAAOC,UAIjEC,EAA0BrT,SAAlBc,EAAQuS,MAAsBvS,EAAQuS,MAAQC,WAAa,EAGnEC,EAAML,EAAQM,YAAeH,EAAQC,YAAY,GAcrD,IAXS,EAALC,GAA+BvT,SAArBc,EAAQkS,WACpBA,EAAWA,EAAW,EAAI,QAKlB,EAALO,GAAUL,EAAQM,aAAiCxT,SAAlBc,EAAQuS,QAC5CA,EAAQ,GAINA,GAAS,IACX,KAAM,IAAIpS,OAAM,kDAGlBuS,YAAaN,EACbI,WAAaD,EACbJ,UAAYD,EAGZE,GAAS,WAGT,IAAIO,IAA4B,KAAb,UAARP,GAA6BG,GAAS,UACjDN,GAAE3P,KAAOqQ,IAAO,GAAK,IACrBV,EAAE3P,KAAOqQ,IAAO,GAAK,IACrBV,EAAE3P,KAAOqQ,IAAO,EAAI,IACpBV,EAAE3P,KAAY,IAALqQ,CAGT,IAAIC,GAAOR,EAAQ,WAAc,IAAS,SAC1CH,GAAE3P,KAAOsQ,IAAQ,EAAI,IACrBX,EAAE3P,KAAa,IAANsQ,EAGTX,EAAE3P,KAAOsQ,IAAQ,GAAK,GAAM,GAC5BX,EAAE3P,KAAOsQ,IAAQ,GAAK,IAGtBX,EAAE3P,KAAO4P,IAAa,EAAI,IAG1BD,EAAE3P,KAAkB,IAAX4P,CAIT,KAAK,GADDW,GAAO7S,EAAQ6S,MAAQC,QAClBpG,EAAI,EAAO,EAAJA,EAAOA,IACrBuF,EAAE3P,EAAIoK,GAAKmG,EAAKnG,EAGlB,OAAO4E,GAAMA,EAAMO,QAAQI,GAM7B,QAAStM,IAAG3F,EAASsR,EAAKC,GAExB,GAAIjP,GAAIgP,GAAOC,GAAU,CAEF,iBAAb,KACRD,EAAiB,UAAXtR,EAAsB,GAAI+S,aAAY,IAAM,KAClD/S,EAAU,MAEZA,EAAUA,KAEV,IAAIgT,GAAOhT,EAAQ6Q,SAAW7Q,EAAQiT,KAAOC,OAO7C,IAJAF,EAAK,GAAgB,GAAVA,EAAK,GAAa,GAC7BA,EAAK,GAAgB,GAAVA,EAAK,GAAa,IAGzB1B,EACF,IAAK,GAAIE,GAAK,EAAQ,GAALA,EAASA,IACxBF,EAAIhP,EAAIkP,GAAMwB,EAAKxB,EAIvB,OAAOF,IAAOO,QAAQmB,GA/JxB,IAAK,GARDE,MAAOzU,QAAQ,SAGfsU,YAAgC,kBAAZ,QAAyBI,OAAS9O,MAGtD0N,cACAH,cACKtP,EAAI,EAAO,IAAJA,EAASA,IACvByP,WAAWzP,IAAMA,EAAI,KAAO8Q,SAAS,IAAIC,OAAO,GAChDzB,WAAWG,WAAWzP,IAAMA,CAyC9B,IAAIgR,YAAaJ,OAGbJ,SACc,EAAhBQ,WAAW,GACXA,WAAW,GAAIA,WAAW,GAAIA,WAAW,GAAIA,WAAW,GAAIA,WAAW,IAIrEnB,UAAmD,OAAtCmB,WAAW,IAAM,EAAIA,WAAW,IAG7CZ,WAAa,EAAGF,WAAa,EA4G7B9M,KAAOC,EACXD,MAAKsM,GAAKA,GACVtM,KAAKC,GAAKA,GACVD,KAAK4E,MAAQA,MACb5E,KAAKmM,QAAUA,QACfnM,KAAKqN,YAAcA,YAEnBpU,OAAOC,QAAU8G;;;;AC1LjB,GAAI6N,iBAAwB3M,OAAO4M,oBAA4B5M,OAAO6M,uBAA+B7M,OAAO2M,gBACxG9S,kBAAwBmG,OAAO8M,sBAA4B9M,OAAO+M,yBAA+B/M,OAAOnG,kBACxGmD,sBAAwBgD,OAAOgN,0BAA4BhN,OAAOiN,6BAA+BjN,OAAOhD,qBAE5GhF,SAAQ2U,gBAAwBA,gBAChC3U,QAAQ6B,kBAAwBA,kBAChC7B,QAAQgF,sBAAwBA;;AGchC,QAAS4S,UAAW,MAAM,OAAOC,MAAS,GAAIpE,MAC9C,QAASqE,QAAW,OAAO,GAAIrE,MA0B/B,QAASsE,WAAWC,EAAgBC,GAChC,GAAI9F,GAAS6F,EAAeE,KAAKC,QAC7BhO,IAEJ,OAAK8N,IAELG,KAAMH,EAAY,SAAUhJ,EAAKjM,GAC7B,GAAIqV,GAA6B,gBAATrV,GAAmByI,KAAgB,UAAEzI,GAAOA,CACnD,oBAATA,IACK,MAATA,GAAiBsC,OAAO+S,GAAW3P,OAAS,GAC3CyB,EAAO/E,KAAK6J,EAAM,IAAM3J,OAAO+S,MAGxClG,GAAO,IAAMhI,EAAO+N,KAAKI,YATDnG,EAkB5B,QAASoG,SAASC,EAAKC,GACnB,GAAI3C,GACA4C,EAAS,EACTC,EAAS,WACLD,EAAOD,EAAOX,QACdrB,aAAaX,GACbA,EAAUjN,WAAY8P,EAAQF,KAG9BC,EAAOZ,OACPU,KAIR,OAAOG,GAQX,QAASC,MAAM7J,EAAMyJ,GACjB,GAAIK,KAEJ,OADAT,MAAMrJ,MAAY,SAAS+J,GAAKN,EAAIM,IAAMD,EAAIzT,KAAK0T,KAC5CD,EAQX,QAASE,UAAUC,EAAKC,GACpB,MAAOD,GAAIlG,QAASoG,KAAM,SAAUC,EAAGC,GACnC,MAAOH,GAAOG,IAAUD,IAShC,QAASrD,SAAS0C,EAAKa,GACnB,MAAOxQ,YAAY2P,EAAKa,GAQ5B,QAASvS,MAAKnF,GACV,GAAI2X,GAAI,uCAAuCxG,QAAQ,QACvD,SAASnN,GACL,GAAI4T,GAAkB,GAAdhZ,KAAK0R,SAAY,EAAGuH,EAAS,KAAL7T,EAAW4T,EAAO,EAAFA,EAAM,CACtD,OAAOC,GAAEhF,SAAS,KAGtB,OADI7S,IAAUA,EAAS2X,GAChBA,EAGX,QAASG,SAAQjM,GACf,QAASA,IAAQ/H,MAAMgU,SAAWhU,MAAMgU,QAAQjM,IAA+B,gBAAhBA,GAAU,QAQ3E,QAAS4K,MAAMsB,EAAGtR,GACd,GAAMsR,GAAMtR,EAEZ,GAAKqR,QAAQC,GACT,IAAM,GAAIhW,GAAI,EAAGoV,EAAIY,EAAEhR,OAAYoQ,EAAJpV,GAC3B0E,EAAEjI,KAAMuZ,EAAEhW,GAAIgW,EAAEhW,GAAIA,SAExB,KAAM,GAAIA,KAAKgW,GACXA,EAAEC,gBACFD,EAAEC,eAAejW,IACjB0E,EAAEjI,KAAMuZ,EAAEhW,GAAIA,EAAGgW,EAAEhW,IAQ/B,QAASwO,KAAKnD,EAAMyJ,GAChB,GAAIK,KAEJ,OADAT,MAAMrJ,MAAY,SAAU6K,EAAGJ,GAAMX,EAAIzT,KAAKoT,EAAKoB,EAAGJ,MAC/CX,EAQX,QAASvT,QAAOuU,GAAQ,MAAOC,oBAAmBD,GAOlD,QAASE,uBAAsBvX,EAAUwX,GACrC,GAAIjL,KAUJ,OATAqJ,MAAM5V,EAAU,SAAU2C,EAASwB,GAC3BqT,EACG7U,EAAQ8U,OAAO,WAAa,GACvBtT,EAAOuT,YAAYnL,EAAK3J,KAAKD,GAGjCwB,EAAOuT,YAAYnL,EAAK3J,KAAKD,KAGlC4J,EAAKoL,OAKhB,QAASC,SAAUtE,QAAS,WACpBuE,QACJA,MAAQ,EACRjC,KAAMkC,aAAc,SAAStK,GAAWA,QACzCuK,QAEH,QAASC,QAAOC,GA+CZ,QAASC,GAAgBlS,GAKrB,MAJKA,KAAMA,MACX4P,KAAMjO,EAAS,SAAU8E,EAAKjM,GAC1BwF,EAAKyG,GAAOjM,IAETwF,EAGX,QAASmS,GAAoBjB,GACzB,GAAIZ,KAIJ,OAHAV,MAAMsB,EAAI,SAAUzK,GAChB6J,EAAE1T,KAAK6J,KAEJ6J,EAEX,QAAS8B,GAA2BlB,GAChC,MAAOiB,GAAoBjB,GAAGS,OAGlC,QAASU,GAAgC1Q,GACrC,GAAI2Q,GAAK,GACLhC,EAAI8B,EAA2BzQ,EAEnC,KAAK,GAAIzG,KAAKoV,GAAG,CACb,GAAIc,GAAId,EAAEpV,EACVoX,IAAMlB,EAAI,IAAMtU,OAAO6E,EAAOyP,IAC1BlW,GAAKoV,EAAEpQ,OAAS,IAAGoS,GAAM,KAEjC,MAAOA,GAGX,QAASC,GAA4BC,EAAWC,EAAe/Z,GAC3D,GAAIqU,IAAM,CAEV,IAAyB,gBAAdyF,GAEHzF,EADAyF,EAAYE,uBAAsC,GAAbF,GAC/B,GAEA,MACP,CAAA,GAAwB,iBAAdA,GACb,MAAKA,GAGMG,oBAFA,CAKX5F,IAAM,EAGV,MAAIA,IACArU,GAASA,EAAM,uDAAyDga,sBAAwB,gCAAkCD,GAAiBC,wBAC5ID,GAAiBC,uBACdF,EAGlB,QAASI,GAAQrJ,EAAO9C,GACpB,MAAOoM,IAAoB,QAAEtJ,EAAO9C,GAAOqM,KAAevJ,EAE9D,QAASwJ,GAAQxJ,EAAO9C,GACpB,MAAOoM,IAAoB,QAAEtJ,EAAO9C,GAAOqM,KACpCD,GAAoB,QAAEtJ,EAAOuJ,KAC7BvJ,EAOX,QAASyJ,KAIL,MAFA/E,cAAagF,IAERC,GAAwBA,GAAwB,KAA8B,EAAvBA,IAA6B3B,sBAAsB4B,GAAS,GAAMjT,YAC1HkT,GAAsB,IAI1BA,GAAsB,MACtBC,IAAyB,oBACrBla,SAAa,WACT8Z,EAAsB3F,QAAS0F,EAAqB,EAAyBjB,SAEjFrZ,MAAU,SAAS4a,GACf5a,GAASA,EAAM,qDAAuDuK,KAAKmB,UAAUkP,IACrFL,EAAsB3F,QAAS0F,EAAqB,EAAyBjB,YAKzF,QAASwB,MACJH,GAAuBJ,IAG5B,QAASrL,GAAQ6L,GAEb,GAAIC,GACA,IAAKC,EAAUxT,OAAQ,WACpB,CAEH,GADIsT,IAAME,EAAUC,QAAU,GACzBD,EAAUC,UAAYD,EAAUxT,OAAS,MAC9CwT,GAAUC,QAAU,EAGxBC,EAAIF,EAAUtT,SAGlB,QAASyT,GAAa1a,GAClB,GAAIiQ,GAAQ,CAWZ,OATAwG,MAAM2B,sBAAsB4B,GAAW,SAASxW,GAC5C,GAAImX,GAAOX,EAASxW,EAEfmX,KAEL1K,KACCjQ,GAAU,cAAc2a,MAGtB1K,EAEX,QAAS2K,GAAiBzX,EAAUnD,EAAU4T,GAC1C,GAAuB,gBAAZzQ,GAAsB,CAC7B,GAAIA,EAAgB,OAAKA,EAAkB,SAAKA,EAAkB,QAE9D,WADAyQ,IAAKrS,QAAY4B,EAAkB,QAAG0X,QAAY1X,EAAkB,SAGxE,IAAIA,EAAkB,QAElB,WADAnD,GAASmD,EAAkB,SAInCnD,EAASmD,GAGb,QAAS2X,GAAc3X,EAASyQ,GAGxBA,EAFmB,gBAAZzQ,IAAwBA,EAAgB,OAC/CA,EAAkB,SAAKA,EAAkB,SACpC5B,QAAY4B,EAAkB,QAAG0X,QAAY1X,EAAkB,SAC7DA,GA43Bf,QAAS4X,KACLC,KAAgBC,EAAgB,GAC5B1b,MAAU,kDAEd4U,QAAS4G,EAAcnC,QAG3B,QAASsC,KACLhB,GAAW,KAAE,SAASiB,GAClBC,EAAmB,aAAcD,GACjCA,GAAWF,EAAgB,GACvB1b,MAAU,sFAGd4U,QAAS+G,EAAeG,KAIhC,QAASJ,GAAerH,EAAK/F,GACzByN,GAAgBA,EAAa1H,EAAK/F,GAClCyN,EAAe,KAWnB,QAASC,GAAeC,GACpB,GAAIC,GAAgBtF,OAASuF,CAC7B,OAAOD,GAAgBD,EAAK,IAIhC,QAASJ,GAAmBO,EAAIC,GAK5B,QAASC,GAAUD,GACf,GAAKA,EAAL,CACA,GAAIE,GAAUF,EAAO,IACjBG,GAAW5F,OAAS6F,GAAS,CACjCN,GAAavF,QAAU2F,EAAQC,GAC/BJ,GAAMA,EAAGD,IATb,GAAIM,GAAQ7F,MAEZyF,IAAQC,EAAUD,IAAS1B,GAAW,KAAE2B,GA5lC5C,GAAII,IAAkBnD,EAAiB,WAAOoD,cAC1CC,IAAkBrD,EAAe,SAASsD,iBAAmBxD,OAC7DyC,IAAkBvC,EAAiB,WAAOuD,eAAmBzD,OAC7D0D,EAAgBxD,EAAe,SAAW,EAC1CyD,EAAgBzD,EAAmB,aAAO,OAC1C0D,EAAgB1D,EAAqB,eAAK,OAC1C2D,EAAgB3D,EAAgB,UAAU,GAC1C4D,EAAgB5D,EAAkB,YAAQ,GAC1C6D,EAAgB7D,EAAmB,YACnC8D,EAAgB9D,EAAW,IAAe,IAAM,GAChD+D,EAAgB,OAAOD,EAAI,OAAO9D,EAAc,QAAG,qBACnDgE,EAAgBC,WAAWF,GAC3BG,EAAgBD,WAAWF,GAC3BI,EAAgB,aAChB1C,KACAmB,EAAgB,EAChBwB,EAAgB,EAChBC,EAAgB,EAChB7B,EAAgB,EAChB8B,EAAgB,EAEhBC,EAAgB,EAChBC,GAAgB,EAChBtD,KACAuD,KACAzD,EAAuB,KACvB0D,EAAuBpE,EAA4BN,EAAiB,WAAKA,EAAiB,WAAK,EAAGA,EAAa,OAC/GiB,EAAuBjB,EAA0B,oBAAK0E,EAAc,EACpEvD,GAAuB,EACvBK,EAAuBxB,EAA2B,oBAClD2E,EAAgB3E,EAAM,oBAAsB,EAC5C2B,EAAgB3B,EAAW,IAC3BtQ,EAAgBsQ,EAAc,WAC9BvZ,EAAgBuZ,EAAa,OAAU,aACvCkC,EAAgBlC,EAAkB,YAAK,WAAa,MAAO,IAC3D4E,EAAgB5E,EAAgB,UAAO,WAAa,MAAO,IAC3D6E,GAAgB7E,EAAU,KAAc1W,IAAO,aAAcmS,IAAO,cACpEoF,GAAgBb,EAAkB,WAClC8E,GAAgB9E,EAAY,MAAO6E,IAAMA,GAAQ,IAAEnB,EAAc,SAAW,GAE5E9C,GAAgBZ,EAAkB,aAE9BW,QAAY,SAASoE,GAAQ,MAAOA,IACpCjE,QAAY,SAASlI,GAAO,MAAOA,KAiJvCwI,IACA4D,MAAU,SAAUta,EAASua,EAAU/d,EAAUT,GAE7C,GAAIsH,IAAW1B,KAASyY,GAAMI,KAASvB,GACnCwB,EAASlB,WAAWF,GACpB7c,EAAWA,GAAY,aACvB4T,EAAWrU,GAAY,aACvB2e,EAASR,GAGb,IAAIla,EAAQe,QAAQ4Z,iBAAmB,EAAG,OAAO,CAEjD,IAAIV,EAAe,CACf,IAAKb,EAAa,OAAO,CACzB,IAAa,KAATsB,EAAc,OAAO,EAG7B,MAAI5B,IAAiB,GAER,KAAT4B,IAAcrX,EAAe,SAAIqX,GAErCzD,GACIsD,SAAWA,GAAYnB,EACvBzI,QAAW,IACXnU,SAAWke,EACXrX,KAAWkS,EAAgBlS,GAC3BsU,QAAW,SAAShY,GAChByX,EAAiBzX,EAAUnD,EAAU4T,IAEzCwK,KAAW,SAASjb,GAChB2X,EAAc3X,EAAUyQ,IAE5BpD,KACIyN,EAAQ,KAAM,WAAY,UAC1BzB,EAAe,UAAW7Y,OAAOH,GAAU,YAG5C,IAEX6a,YAAgB,SAASC,GACjBhB,EAAUgB,GAElBC,eAAmB,WACf,MAAO5E,KAEX6E,eAAmB,SAASlR,GACxBqM,GAAarM,GAEjBmR,YAAgB,SAASrO,EAAO9C,GAC5B,MAAOmM,GAAQrJ,EAAO9C,IAE1BoR,YAAgB,SAAStO,EAAO9C,GAC5B,MAAOsM,GAAQxJ,EAAO9C,IAE1BqR,cAAkB,WACd,MAAOnB,IAEXoB,cAAkB,SAASvF,GACvBmE,EAAcpE,EAA4BC,EAAWU,EAAsBxa,GAC3Ewa,EAAwByD,EAAc,GAAK,EAAGA,EAAc,EAAE,EAC9DP,IACApD,KAEJgF,uBAA2B,WACvB,MAAO9E,IAEX+E,uBAA2B,SAASC,GAChChF,EAAuBgF,EACvBlF,KAEJmF,YAAgB,WACZ,MAAOC,UAEXC,WAAe,SAAS5R,EAAI6R,GACxB3W,EAAO8E,GAAO6R,GAUlBC,QAAY,SAAU5S,EAAMxM,GACxB,GAAIA,GAAmBwM,EAAe,UAAKxM,EACvCiQ,EAAmBzD,EAAY,OAAQA,EAAY,OAAK,IACxD6S,EAAmB7S,EAAc,SAAM,QACvCoH,EAAmBpH,EAAY,OAAQ,aACvC8S,EAAmB9S,EAAe,UAAKiQ,EACvC8C,EAAmB/S,EAAiB,WACpChJ,EAAmBgJ,EAAc,QACjCgT,EAAmBhT,EAAY,MAC/BiT,EAAmBjT,EAAU,IAC7BkT,EAAmBlT,EAAoB,cACvChE,KACA0V,EAAmBR,GAGvB,OAAKla,GACAxD,EACAwc,GAELhU,EAAoB,YAAI,OACxBA,EAAc,MAAUyH,EACxBzH,EAAgB,QAAQ6W,EACxB7W,EAAa,KAAW8W,EAEpBpB,IAAO1V,EAAiB,SAAiB0V,GACzCsB,IAAOhX,EAAc,MAAoBgX,GACzCC,IAAOjX,EAAY,IAAsBiX,GACzCC,IAAelX,EAAsB,cAAI,YAG7CiS,IACIza,SAAWke,EACXrX,KAAWkS,EAAgBvQ,GAC3B2S,QAAW,SAAShY,GAChB,GAAuB,gBAAZA,IAAwBA,EAAgB,MAE/C,WADAyQ,IAAKrS,QAAY4B,EAAkB,QAAG0X,QAAY1X,EAAkB,SAKxE,KAAK,GAFDwc,GAAWxc,EAAS,GACpByc,KACK/B,EAAI,EAAGA,EAAI8B,EAAS5Y,OAAQ8W,IAAK,CACtC,GAAIgC,GAAcjG,EAAQ+F,EAAS9B,GAAG0B,EACtC,KACIK,EAAyB,KAAE9V,KAAY,MAAE+V,IAC3C,MAAO1F,GACLyF,EAAyB,KAAE,IAGnC5f,GAAU4f,EAAoBzc,EAAS,GAAIA,EAAS,MAExDib,KAAW,SAASjb,GAChB2X,EAAc3X,EAAUyQ,IAE5BpD,KACIsM,EAAY,KAAM,UAAW,UAC7BN,EAAe,UAAW7Y,OAAOH,OAtCdjE,EAAM,yBADNA,EAAM,oBADNA,EAAM,oBAmDrCugB,OAAW,SAAStT,EAAMxM,GACtB,GAWIwQ,GAXAxQ,EAAcA,GAAYwM,EAAe,UAAK,aAC9C8S,EAAc9S,EAAe,UAAKiQ,EAClC7V,EAAc4F,EAAa,OAC3BuT,EAAcvT,EAAkB,YAChCwT,EAAcxT,EAAW,KACzBgT,EAAchT,EAAY,MAC1BiT,EAAcjT,EAAU,IACxB6S,EAAc7S,EAAc,QAC5ByT,EAAczT,EAAY,MAC1B0R,EAAcR,IACd7W,IAIJ,OAAKD,GACAmZ,EACAxD,EACAC,GAGQ,KAAT0B,IAAcrX,EAAe,SAAIqX,GACjC8B,IAAcnZ,EAAW,KAAQ,OACjCwY,IAAcxY,EAAc,QAAK,QACjC2Y,IAAc3Y,EAAY,MAAO2Y,GACjCC,IAAc5Y,EAAU,IAAS4Y,GACjCQ,IAAcpZ,EAAY,MAAOoZ,GAErCpZ,EAAW,KAAIyY,EAGf9O,GACIsM,EAAY,KAAM,SAClBP,EAAaC,EACb5V,EAAQmZ,OAIZtF,IACIza,SAAWke,EACX/C,QAAW,SAAShY,GAChByX,EAAiBzX,EAAUnD,EAAU4T,MAEzCwK,KAAW,WAAape,GAAW,EAAG,kBACtCwQ,IAAWA,EACX3J,KAAWkS,EAAgBlS,MA3BJtH,EAAM,yBADNA,EAAM,uBADNA,EAAM,+BADNA,EAAM,2BAqCrCye,KAAS,SAASA,GACdvB,EAAWuB,EACXf,KAMJrB,KAAS,SAAS5b,GACd,GAAIke,GAAQR,GACZjD,IACIza,SAAWke,EACXrX,KAAWkS,GAAkB5T,KAASyY,GAAMI,KAASvB,IACrDtI,QAAoB,EAATyE,OACXpI,KAAYsM,EAAY,OAAQoB,GAChC/C,QAAW,SAAShY,GAAYnD,EAASmD,EAAS,KAClDib,KAAW,WAAape,EAAS,OAUzCwO,QAAY,SAAUhC,EAAMxM,GACxB,GASIwQ,GATAxQ,EAAWA,GAAYwM,EAAe,UAAK,aAC3CqB,EAAWrB,EAAc,QACzBhJ,EAAWgJ,EAAc,QACzB8S,EAAW9S,EAAe,UAAKiQ,EAC/B8C,EAAa/S,EAAiB,WAC9BoH,EAAWpH,EAAY,OAAK,aAC5B0T,EAAW1T,EAAW,OAAK,EAC3B0R,EAAWR,IACXyC,EAAW,MAKf,OAFI3T,GAAc,UAAG2T,EAAU,WAE1BtS,EACArK,EACA+Y,EACAC,GAGL3O,EAAM/D,KAAgB,UAAE2P,EAAQ5L,EAAK0R,IAGrC/O,GACIsM,EAAY,UACZP,EAAaC,EACb,EAAG7Y,OAAOH,GACV0a,EAAOva,OAAOkK,IAIlB0M,EAAU4F,IACNngB,SAAWke,EACX/J,QAAoB,EAATyE,OACXpI,IAAWA,EACX3J,KAAWkS,GAAkB5T,KAASyY,GAAMI,KAASsB,IACrDlB,KAAW,SAASjb,GAChB2X,EAAc3X,EAAUyQ,GACxBpF,EAAQ,IAEZ2M,QAAW,SAAShY,GAChByX,EAAiBzX,EAAUnD,EAAU4T,GACrCpF,EAAQ,IAEZ4R,KAAW,EAAO,OAAO,YAI7B5R,MA/B2BjP,EAAM,yBADNA,EAAM,uBADNA,EAAM,mBADNA,EAAM,oBAwCrCgP,YAAgB,SAAS/B,EAAMxM,GAC3B,GAAIwD,GAAUgJ,EAAc,QACxBxM,EAAgBA,GAAuBwM,EAAe,UAAK,aAC3DoH,EAAgBpH,EAAY,OAAW,YAE3C6Q,GAAc,EACdD,EAAc,EAGd5Z,EAAU+M,KACN/M,EAAQ+S,KAAO/S,EAAQ+S,KAAK,KAAO,GAAG/S,GACxC6c,MAAM,KAAM,SAAS7c,GACnB,MAAKwW,GAASxW,GACPA,EAAU,IAAMA,EAAU2a,gBADjC,SAEA5H,KAAK,KAGTE,KAAMjT,EAAQ6c,MAAM,KAAM,SAAS7c,GAC/B,GAAI8c,IAAY,CACX9c,KACDkV,QACA4H,EAAYpG,GAAY,MAAG1W,EAAS,EAAIxD,EAAU4T,IAEjD0M,GAAWtgB,GAAUugB,OAAS,UACnCvG,EAASxW,GAAW,EAChBA,IAAW+Z,UAAcA,GAAM/Z,MAIvCyZ,KASJ/O,UAAc,SAAU1B,EAAMxM,GA0F1B,QAASwgB,GAAiBrF,GAClBA,EAEAhH,QAAS8I,EAASrE,SAIlBkE,EAAaC,WAAYF,EAAQ,GACjCG,EAAaD,WAAYF,EAAQ,GAGjC1I,QAAS,WACL+F,GAAW,KAAEsG,IACd5H,SAIP8B,EAAa,SAASlX,GAElB,MAAI2X,IAAW3X,EAAQid,cACnBjd,EAAQid,aAAe,EAChBjd,EAAQkd,UAAUld,EAAQ+P,YAIhC4H,GAAY3X,EAAQid,eACrBjd,EAAQid,aAAe,EACvBjd,EAAQ8K,WAAW9K,EAAQ+P,UAMvC,QAASoN,KACL,GAAIzC,GAAWR,IACX7c,EAAWuX,sBAAsB4B,GAAUzD,KAAK,IAGpD,IAAK1V,EAAL,CAGAoa,GAEA,IAAIpU,GAAOkS,GAAkB5T,KAASyY,GAAMI,KAASsB,IAEjDsB,EAAK9W,KAAKmB,UAAUsS,EACpBqD,GAAG7Z,OAAS,IAAGF,EAAY,MAAIiD,KAAKmB,UAAUsS,IAE9CC,IAAa3W,EAAgB,UAAI2W,GAErCpD,IACAkB,EAAeb,GACXtG,QAAW0M,EACX7gB,SAAWke,EACXE,KAAW,SAASjb,GAChB2X,EAAc3X,EAAU2d,GAExB5G,GAAW,KAAEsG,IAEjB3Z,KAAWkS,EAAgBlS,GAC3B2J,KACIwM,EAAY,YACZR,EAAe7Y,OAAO9C,GACtBqd,EAAOb,GAEXlC,QAAU,SAASwE,GAIf,IAAKA,GACkB,gBAAZA,IACP,SAAWA,IACXA,EAAgB,MAGhB,MADAmB,GAAMnB,EAAgB,OACfxL,QAAS8I,EAASrE,OAkB7B,IAdAmI,EAAOpB,EAAS,IAGhBtC,GAAaA,GACDD,GACAO,GAAQ,IAAEnB,IAAkBmD,EAAS,GAGjDjF,EAAa,SAASlX,GACdA,EAAQwd,YACZxd,EAAQwd,UAAY,EACpBxd,EAAQ6K,QAAQ7K,EAAQ+P,SAGxB+J,IAAYF,EAMR,MALAC,GAAY,EACZC,GAAU,EAEVK,GAAQ,IAAGnB,EAAe,OAC1BrI,SAASwM,EAAUM,EAMvB7S,KACAiP,EAAY,IACZjP,EAAY,GAIhBuP,GAAQ,IAAGnB,EAAemD,EAAS,GAGnC,IAAIuB,GAAgB,WAChB,GAAIrgB,GAAY8e,EAAS5Y,OAAO,EAAE4Y,EAAS,GAAGpP,IAC1C6H,sBAAsB4B,GAAW,SAASW,GAAQ,MAAOpK,KACrDzM,MAAM6b,EAAS,GAAG5Y,QACjBwP,KAAK,KAAK8J,MAAM,KACjB,WAAa,MAAO1F,OACnBpE,KAAK,KACVnJ,EAAOvM,EAASwf,MAAM,IAE1B,OAAO,YACH,GAAI7c,GAAU4J,EAAKnG,SAASkW,CAC5B,SACKnD,EAASxW,QACTxD,UAAUkd,EACX1Z,EAAQ6c,MAAMlC,iBAAiB,QAKvCpC,EAAUR,GAAgBoE,EAAS,GACvClJ,MAAMkJ,EAAS,GAAI,SAAS9R,GACxB,GAAIwM,GAAO6G,IACPC,EAAgBvH,EAAQ/L,EAAImM,EAASK,EAAK,IAAgB,WAC9DA,GAAK,GAAI8G,EAAexB,EAAUtF,EAAK,GAAI0B,KAG/C5H,QAASwM,EAAUM,OApO/B,GAAIzd,GAAgBgJ,EAAc,QAC9BxM,EAAgBA,GAAuBwM,EAAe,SACtDxM,EAAgBA,GAAuBwM,EAAc,QACrD8S,EAAgB9S,EAAe,UAAQiQ,EACvCpO,EAAgB7B,EAAc,SAAS,aACvCkU,EAAgBlU,EAAgB,WAAO,aACvC8B,EAAgB9B,EAAiB,YAAM,aACvCsU,EAAgBtU,EAAY,OAAW,aACvCuU,EAAgBvU,EAAW,MAAY,aACvCnB,EAAgBmB,EAAe,UAAQ,EACvC4U,EAAgB5U,EAAiB,YAAM,EACvC4B,EAAgB5B,EAAe,UAAQ,EACvC6U,EAAgB7U,EAAgB,WAAO,EACvCqU,EAAgBrU,EAAc,SAAS2P,EACvC8E,EAAgBzU,EAAgB,WAAOyP,EACvCqF,EAAgB9U,EAAY,MAC5B6M,EAAgB7M,EAAgB,WAAKA,EAAgB,UACrD2B,EAAgB3B,EAAc,OASlC,OANA4Q,GAAcjP,EAGdkP,EAAYgE,EAGP7d,EACAxD,EACAwc,IAEDnD,GAA2B,IAAdA,IACba,GAAoB,cAAEb,GAI1B5C,MAAOjT,EAAQ+S,KAAO/S,EAAQ+S,KAAK,KAAO,GAAG/S,GAAS6c,MAAM,KAC5D,SAAS7c,GACL,GAAI+d,GAAWvH,EAASxW,MAGxBwW,GAASmD,EAAc3Z,IACnB+P,KAAe/P,EACfwd,UAAeO,EAASP,UACxBP,aAAec,EAASd,aACxBlI,WAAe,EACfvY,SAAekd,EAAeld,EAC9Buf,WAAe/S,EAAiB,WAChC6B,QAAeA,EACfC,WAAeA,EACfoS,UAAeA,GAEfY,IAEI/D,EAAM/Z,GADNA,IAAW8d,GACMA,EAAM9d,GAEN8d,GAKpBjW,IAGL6O,GAAgB,WACZ1W,QAAaA,EAAU2a,gBACvBne,SAAaqL,EACb8C,QAAaA,IAIboT,EAAShJ,YAGT6I,GACJlH,GAAe,UACX1W,QAAaA,EACbxD,SAAa,SAASwhB,GAClB/K,KAAM,SAAW+K,GAAOA,EAAY,SACpC,SAASC,GAAOpW,GACZkV,OAAc,OACdpb,KAAcsc,EACdC,UAAcvL,OACdwL,UAAcH,EAAgB,WAAK,GACpCA,EAAMhe,WAsJrByZ,EAAU,WACNhC,IACA9G,QAASwM,EAAUM,IAIlBvI,UAGLuE,KAHmBtE,aAAalV,KAAKwZ,IAnNV1d,EAAM,yBADNA,EAAM,oBADNA,EAAM,oBA8NrCqiB,SAAa,SAAUpV,EAAMxM,GACzB,GAAIA,GAAWwM,EAAe,UAAKxM,EAC/B4T,EAAWpH,EAAY,OAAQ,aAC/B8S,EAAW9S,EAAe,UAAKiQ,EAC/BjZ,EAAWgJ,EAAc,QACzB0R,EAAWR,IACXmE,EAAY,SAAWrV,GAAQA,EAAY,OAAI,EAC/C8U,EAAW9U,EAAY,MACvB3F,GAAa1B,KAASyY,GAAMI,KAASsB,EAMzC,IAJKuC,IAAOhb,EAAoB,cAAI,GAChCya,IAAOza,EAAY,MAAI,IAGtB7G,EAAe,MAAOT,GAAM,mBACjC,KAAKid,EAAe,MAAOjd,GAAM,wBAEjC,IAAIiR,IACIsM,EAAY,KAAM,WAClB,UAAWN,EAGnBhZ,IAAWgN,EAAI/M,KAAK,YAAc+M,EAAI/M,KAAKE,OAAOH,IAErC,KAAT0a,IAAgBrX,EAAe,SAAIqX,GAEvCzD,GACIza,SAAWke,EACXrX,KAAWkS,EAAgBlS,GAC3BsU,QAAW,SAAShY,GAChByX,EAAiBzX,EAAUnD,EAAU4T,IAEzCwK,KAAW,SAASjb,GAChB2X,EAAc3X,EAAUyQ,IAE5BpD,IAAWA,KAOnBsR,UAAc,SAAUtV,EAAMxM,GAC1B,GAAIA,GAAWwM,EAAe,UAAKxM,EAC/B4T,EAAWpH,EAAY,OAAQ,aAC/B8S,EAAW9S,EAAe,UAAKiQ,EAC/ByB,EAAWR,IACXvY,EAAWqH,EAAW,MAASoR,GAC/B/W,GAAamX,KAASsB,EAG1B,OAAKtf,GACAwc,GAEQ,KAAT0B,IAAgBrX,EAAe,SAAIqX,OAEvCzD,IACIza,SAAWke,EACXrX,KAAWkS,EAAgBlS,GAC3BsU,QAAW,SAAShY,GAChByX,EAAiBzX,EAAUnD,EAAU4T,IAEzCwK,KAAW,SAASjb,GAChB2X,EAAc3X,EAAUyQ,IAE5BpD,KACIsM,EAAY,KAAM,WAClB,UAAWN,EACX,OAAQ7Y,OAAOwB,OAhBI5F,EAAM,yBADNA,EAAM,qBAsBrC+hB,MAAU,SAAS9U,EAAMxM,GACrB,GAOIwQ,GAPAxQ,EAAWwM,EAAe,UAAKxM,GAAY,aAC3C4T,EAAWpH,EAAY,OAAQ,aAC/B8S,EAAW9S,EAAe,UAAKiQ,EAC/ByB,EAAWR,IACX4D,EAAW9U,EAAY,MACvBrH,EAAWqH,EAAW,MAAKoR,GAC3Bpa,EAAWgJ,EAAc,QAEzB3F,EAAWkS,GAAkBiF,KAASsB,GAG1C,OAAK9C,GACArX,EACA3B,GAEQ,KAAT0a,IAAgBrX,EAAe,SAAIqX,GAEnClE,EAASxW,IAAYwW,EAASxW,GAAS+U,aAAYgF,EAAM/Z,GAAW8d,GAExEza,EAAY,MAAIiD,KAAKmB,UAAUqW,GAG3B9Q,EADA8Q,GAEIxE,EAAY,KAAM,WAClB,UAAWN,EACX,UAAW7Y,OAAOH,GAClB,OAAQ2B,EAAM,SAId2X,EAAY,KAAM,WAClB,UAAWN,EACX,UAAW7Y,OAAOH,GAClB,OAAQG,OAAOwB,QAIvBsV,IACIza,SAAWke,EACXrX,KAAWkS,EAAgBlS,GAC3BsU,QAAW,SAAShY,GAChByX,EAAiBzX,EAAUnD,EAAU4T,IAEzCwK,KAAW,SAASjb,GAChB2X,EAAc3X,EAAUyQ,IAE5BpD,IAAWA,KAjCMjR,EAAM,mBADTA,EAAM,gBADGA,EAAM,0BAoDrCwiB,MAAU,SAAUvV,EAAMxM,GACtB,GAAIA,GAAWwM,EAAe,UAAKxM,EAC/B4T,EAAWpH,EAAY,OAAQ,aAC/BhJ,EAAWgJ,EAAc,QACzB0R,EAAWR,IACX/b,EAAW6K,EAAU,IACrBoL,EAAYpL,EAAa,KAAE,IAAI,IAC/BwV,EAAYxV,EAAa,MAAE,IAAI,IAC/B8S,EAAW9S,EAAe,QAG9B,KAAKhJ,EAAe,MAAOjE,GAAM,kBACjC,KAAKS,EAAe,MAAOT,GAAM,mBACjC,KAAKid,EAAe,MAAOjd,GAAM,wBACjC,KAAKgd,EAAe,MAAOhd,GAAM,sBACjC,KAAKmd,EAAe,MAAOnd,GAAM,qBAEjC,IAAImiB,GAAa9iB,KAAKqjB,OAAM,GAAInQ,OAAOC,UAAY,KAC/CmQ,EAAa1F,EAAgB,KAAOD,EAAc,YAGlD1V,GACAmb,EAAcA,EACdpK,EAAcA,EACdpU,QAAcA,EACdke,UAAcA,EAGL,MAATxD,IAAgBrX,EAAe,SAAIqX,IACnCvc,GAAe,IAARA,KAAWkF,EAAU,IAAIlF,GAChC2d,IAAUzY,EAAW,KAAIyY,GAE7BzY,EAAOkS,EAAgBlS,GAEvBqb,GAAchJ,EAAgCrS,EAE9C,IAAIsb,GAAYxF,EAAauF,EAAYxF,EAEzCyF,GAAYA,EAAUhR,QAAS,MAAO,KACtCgR,EAAYA,EAAUhR,QAAS,MAAO,KAEtCtK,EAAgB,UAAIsb,EAEpB1H,GACIza,SAAWke,EACXrX,KAAWA,EACXsU,QAAW,SAAShY,GAChByX,EAAiBzX,EAAUnD,EAAU4T,IAEzCwK,KAAW,SAASjb,GAChB2X,EAAc3X,EAAUyQ,IAE5BpD,KACIsM,EAAY,KAAM,OAAQ,QAC1B,UAAWN,MAevB4F,MAAU,SAAU5V,EAAMxM,GACtB,GAAIA,GAAWwM,EAAe,UAAKxM,EAC/B4T,EAAWpH,EAAY,OAAQ,aAC/BhJ,EAAWgJ,EAAc,QACzB8S,EAAW9S,EAAe,SAC1B0R,EAAWR,GAGf,KAAK1d,EAAe,MAAOT,GAAM,mBACjC,KAAKid,EAAe,MAAOjd,GAAM,wBACjC,KAAKgd,EAAe,MAAOhd,GAAM,sBACjC,KAAKmd,EAAe,MAAOnd,GAAM,qBAEjC,IAAImiB,GAAa9iB,KAAKqjB,OAAM,GAAInQ,OAAOC,UAAY,KAC/CmQ,EAAa1F,EAAgB,KAC3BD,EAAc,YAGhB1V,GAAQ6a,UAAcA,EACb,MAATxD,IAAgBrX,EAAe,SAAIqX,GACnC1a,IAAUqD,EAAc,QAAIrD,GAC5B8b,IAAUzY,EAAW,KAAOyY,GAEhCzY,EAAOkS,EAAgBlS,GAEvBqb,GAAchJ,EAAgCrS,EAE9C,IAAIsb,GAAYxF,EAAauF,EAAYxF,EAEzCyF,GAAYA,EAAUhR,QAAS,MAAO,KACtCgR,EAAYA,EAAUhR,QAAS,MAAO,KAEtCtK,EAAgB,UAAIsb,EACpB1H,GACIza,SAAWke,EACXrX,KAAWA,EACXsU,QAAW,SAAShY,GAChByX,EAAiBzX,EAAUnD,EAAU4T,IAEzCwK,KAAW,SAASjb,GAChB2X,EAAc3X,EAAUyQ,IAE5BpD,KACIsM,EAAY,KAAM,OAAQ,QAC1B,UAAWN,MAavB6F,OAAW,SAAU7V,EAAMxM,GACvBwM,EAAW,MAAK,EAChBA,EAAY,OAAI,EAChB0N,GAAY,MAAG1N,EAAMxM,IAEzBsiB,SAAa,SAASnd,GAClByY,GAAOzY,EACP8X,KAEJsF,SAAa,WACT,MAAO3E,KAEX4E,mBAAuB,SAAShW,GAC5B,GAAIxM,GAAWwM,EAAe,UAAK,aAC/BoH,EAAWpH,EAAY,OAAQ,aAC/B0R,EAAWR,IACX7W,GAAa1B,KAASyY,GAAMI,KAASvB,GAErCmE,EAAK9W,KAAgB,UAAEyT,EACvBqD,GAAG7Z,OAAS,IAAGF,EAAY,MAAIiD,KAAgB,UAAEyT,IAEjDC,EAAc,GAAmB,IAAdA,IAAmB3W,EAAgB,UAAI2W,GAE9D/C,GACIza,SAAWke,EACXrX,KAAWkS,EAAgBlS,GAC3BsN,QAAoB,EAATyE,OACXpI,KACIsM,EAAY,KAAM,WAClB,UAAWN,EACX,UAAY7Y,OAAOyU,sBAAsB4B,GAAU,GAAY,KAAE,MACjE,aAEJmB,QAAW,SAAShY,GAChByX,EAAiBzX,EAAUnD,EAAU4T,IAEzCwK,KAAW,SAASjb,GAAY2X,EAAc3X,EAAUyQ,OAKhE6G,IAAkBA,EAClBhC,MAAkBA,MAClBkF,GAAkBA,GAClBxY,KAAkBA,KAClBoL,IAAkBA,IAClBkG,KAAkBA,KAClBgM,eAAkB/H,EAClBzD,KAAkBA,KAClByL,QAAkB,WAAWzH,EAAe,GAAK1Z,QAAU,kDAC3D6V,SAAkBA,SAClBuL,IAAkBxM,KAClBF,OAAkBA,OAClBW,QAAkBA,QAsDtB,OA5BKgH,MAAMA,GAAO1D,GAAW,QAC7ByD,GAAQ,IAAGnB,EAAgB,OAAQoB,IAEnCzJ,QAAS4G,EAAenC,QACxBzE,QAAS+G,EAAeG,GACxBvB,EAAsB3F,QAASiG,GAA4BL,EAAuB,GAAMnB,QAQxFwC,IAeOlB,GAi9BX,QAASR,cAGT,QAASkJ,GAAO9R,GAKZ,QAAS+R,GAASC,EAAGC,GACjB,GAAIC,IAAW,MAAJF,IAAmB,MAAJC,GACtBE,GAAOH,GAAK,KAAOC,GAAK,KAAOC,GAAO,GAC1C,OAAQC,IAAO,GAAa,MAAND,EAG1B,QAASE,GAAEC,EAAGhX,GACV,MAASgX,KAAMhX,EAAOgX,GAAM,GAAKhX,EAGrC,QAASiX,GAAED,EAAGhX,GACV,MAASgX,KAAMhX,EAGnB,QAASkX,GAAGP,EAAGC,EAAGO,GACd,MAASR,GAAIC,GAAQD,EAAKQ,EAG9B,QAASC,GAAIT,EAAGC,EAAGO,GACf,MAASR,GAAIC,EAAMD,EAAIQ,EAAMP,EAAIO,EAGrC,QAASE,GAAUV,GACf,MAAQI,GAAEJ,EAAG,GAAKI,EAAEJ,EAAG,IAAMI,EAAEJ,EAAG,IAGtC,QAASW,GAAUX,GACf,MAAQI,GAAEJ,EAAG,GAAKI,EAAEJ,EAAG,IAAMI,EAAEJ,EAAG,IAGtC,QAASY,GAAUZ,GACf,MAAQI,GAAEJ,EAAG,GAAKI,EAAEJ,EAAG,IAAMM,EAAEN,EAAG,GAGtC,QAASa,GAAUb,GACf,MAAQI,GAAEJ,EAAG,IAAMI,EAAEJ,EAAG,IAAMM,EAAEN,EAAG,IAGvC,QAASc,GAAY9W,EAAGqK,GACpB,GAGI0G,GAAGnM,EAAG1N,EAAG6f,EAAG1J,EAAG1T,EAAGyG,EAAG4W,EAAG/hB,EAAGgiB,EAC3BC,EAAIC,EAJJC,EAAI,GAAIpgB,OAAM,WAAY,WAAY,WAAY,WAAY,UAAY,WAAY,WAAY,WAAY,WAAY,UAAY,UAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,UAAW,UAAY,UAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,UAAW,UAAY,UAAY,UAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,UAAY,UAAY,UAAY,UAAY,UAAY,UAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,YAChwBqgB,EAAO,GAAIrgB,OAAM,WAAY,WAAY,WAAY,WAAY,WAAY,WAAY,UAAY,YACrGsgB,EAAI,GAAItgB,OAAM,GAIlBgJ,GAAEqK,GAAK,IAAM,KAAS,GAAKA,EAAI,GAC/BrK,GAAIqK,EAAI,IAAM,GAAM,GAAK,IAAMA,CAE/B,KAAK,GAAIpV,GAAI,EAAGA,EAAI+K,EAAE/F,OAAQhF,GAAK,GAAI,CACnC8b,EAAIsG,EAAK,GACTzS,EAAIyS,EAAK,GACTngB,EAAImgB,EAAK,GACTN,EAAIM,EAAK,GACThK,EAAIgK,EAAK,GACT1d,EAAI0d,EAAK,GACTjX,EAAIiX,EAAK,GACTL,EAAIK,EAAK,EAET,KAAK,GAAIJ,GAAI,EAAO,GAAJA,EAAQA,IACRK,EAAEL,GAAN,GAAJA,EAAejX,EAAEiX,EAAIhiB,GACb8gB,EAASA,EAASA,EAASc,EAAUS,EAAEL,EAAI,IAAKK,EAAEL,EAAI,IAAKL,EAAUU,EAAEL,EAAI,MAAOK,EAAEL,EAAI,KAEpGC,EAAKnB,EAASA,EAASA,EAASA,EAASiB,EAAGL,EAAUtJ,IAAKkJ,EAAGlJ,EAAG1T,EAAGyG,IAAKgX,EAAEH,IAAKK,EAAEL,IAClFE,EAAKpB,EAASW,EAAU3F,GAAI0F,EAAI1F,EAAGnM,EAAG1N,IAEtC8f,EAAI5W,EACJA,EAAIzG,EACJA,EAAI0T,EACJA,EAAI0I,EAASgB,EAAGG,GAChBH,EAAI7f,EACJA,EAAI0N,EACJA,EAAImM,EACJA,EAAIgF,EAASmB,EAAIC,EAGrBE,GAAK,GAAKtB,EAAShF,EAAGsG,EAAK,IAC3BA,EAAK,GAAKtB,EAASnR,EAAGyS,EAAK,IAC3BA,EAAK,GAAKtB,EAAS7e,EAAGmgB,EAAK,IAC3BA,EAAK,GAAKtB,EAASgB,EAAGM,EAAK,IAC3BA,EAAK,GAAKtB,EAAS1I,EAAGgK,EAAK,IAC3BA,EAAK,GAAKtB,EAASpc,EAAG0d,EAAK,IAC3BA,EAAK,GAAKtB,EAAS3V,EAAGiX,EAAK,IAC3BA,EAAK,GAAKtB,EAASiB,EAAGK,EAAK,IAE/B,MAAOA,GAGX,QAASE,GAAShN,GAGd,IAAK,GAFDiN,GAAMxgB,QACNygB,GAAQ,GAAKC,GAAS,EACjBziB,EAAI,EAAGA,EAAIsV,EAAItQ,OAASyd,EAAOziB,GAAKyiB,EACzCF,EAAIviB,GAAK,KAAOsV,EAAIoN,WAAW1iB,EAAIyiB,GAASD,IAAU,GAAKxiB,EAAI,EAEnE,OAAOuiB,GAGX,QAASI,GAAWC,GAChBA,EAASA,EAAgB,QAAE,QAAS,KAGpC,KAAK,GAFDC,GAAU,GAELzY,EAAI,EAAGA,EAAIwY,EAAe,OAAGxY,IAAK,CAEvC,GAAInI,GAAI2gB,EAAOF,WAAWtY,EAElB,KAAJnI,EACA4gB,GAAWC,OAAOC,aAAa9gB,GAEzBA,EAAI,KAAa,KAAJA,GACnB4gB,GAAWC,OAAOC,aAAc9gB,GAAK,EAAK,KAC1C4gB,GAAWC,OAAOC,aAAkB,GAAJ9gB,EAAU,OAG1C4gB,GAAWC,OAAOC,aAAc9gB,GAAK,GAAM,KAC3C4gB,GAAWC,OAAOC,aAAe9gB,GAAK,EAAK,GAAM,KACjD4gB,GAAWC,OAAOC,aAAkB,GAAJ9gB,EAAU,MAKlD,MAAO4gB,GAGX,QAASG,GAASC,GAGd,IAAK,GAFDC,GAAUC,EAAU,mBAAqB,mBACzC7N,EAAM,GACDtV,EAAI,EAAGA,EAAsB,EAAlBijB,EAASje,OAAYhF,IACrCsV,GAAO4N,EAAQE,OAAQH,EAASjjB,GAAK,IAAqB,GAAb,EAAIA,EAAI,GAAS,EAAM,IAChEkjB,EAAQE,OAAQH,EAASjjB,GAAK,IAAqB,GAAb,EAAIA,EAAI,GAAa,GAEnE,OAAOsV,GApIX,GAAImN,GAAQ,EACRU,EAAU,CAuId,OADApU,GAAI4T,EAAW5T,GACRiU,EAASnB,EAAYS,EAASvT,GAAIA,EAAE/J,OAASyd,IAEpD,GAAIY,GAASC,MACbD,GAAa,KAAE,IAEf,IACIE,GAAKF,EAAY,IAAE,mBAEvB,QAEI3L,QAAY,SAAS5S,EAAMyG,GACvB,IAAKA,EAAK,MAAOzG,EACjB,IAAI0Y,GAAa6F,EAAY,IAAExC,EAAOtV,GAAY,MAAE,EAAE,KAClDiY,EAAcH,EAAY,IAAEtb,KAAgB,UAAEjD,IAC9C2e,EAAoBJ,EAAmB,WAAEG,EAAahG,EAAY+F,GAClEG,EAAoBL,EAAe,OAAU,OAAEI,EACnD,OAAOC,IAAqB5e,GAGhC+S,QAAY,SAAS/S,EAAMyG,GACvB,IAAKA,EAAK,MAAOzG,EACjB,IAAI0Y,GAAa6F,EAAY,IAAExC,EAAOtV,GAAY,MAAE,EAAE,IACtD,KACI,GAAIoY,GAAaN,EAAe,OAAU,OAAEve,GACxC8e,EAAaP,EAAmB,WAAEM,EAAYnG,EAAY+F,GAAI,GAC9DM,EAAY9b,KAAY,MAAE6b,EAC9B,OAAOC,GAEX,MAAOzL,GACH,MAAOxb,WAz6EvB,GAAIuX,KAAkB,EAClBwC,OAAkB,EAClBC,gBACAwF,gBAAkB,UAClBjC,cAAkB,GAClB2J,YAAkB,IAClBzJ,gBAAkB,IAClBC,cAAkB,GAClBzD,OAAkB,IAClBpC,OAAkB,IAClBG,UAAkB,IAClB4C,sBAAwB,EACxBC,oBAAuB,GACvByF,QAAkB,QAClB1H,KAAkB,eAalBwF,WAAa,WACb,GAAI+I,GAAM,GACNC,EAAMnnB,KAAKqjB,MAAMrjB,KAAK0R,SAAWwV,EACrC,OAAO,UAAU7H,EAAQ+H,GACrB,MAAO/H,GAAO1Z,QAAQ,WAAa,GAC5B0Z,EAAO9M,QACT,SAAU,MACP6U,EAAW7gB,OAAOkb,MAAM,KAAK,KAC1B0F,EAAMD,EAAKC,EAAMA,EAAI,KACrB9H,MA6wCfoH,OAAS,WACT,GAAIY,GAAK,GAETC,EAAK,EACLC,GAAU,EAEVC,EAAW,SAAStV,GAEhB,IACI,MAAOuV,UAASlO,mBAAmBrH,IAEvC,MAAMqJ,GACF,KAAM,0BAIdmM,EAAW,SAASxV,GAEhB,IACI,MAAOyV,oBAAmBC,OAAO1V,IAErC,MAAMqJ,GACF,KAAM,YAIdsM,EAAW,SAASC,GAEhB,GAAgBC,GAAM5kB,EAAlB6kB,IAKJ,KAJIF,EAAQ3f,OAAS,KACjB4f,EAAO,GAAKD,EAAQ3f,OACpB6f,GAASD,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,EAAMA,IAElG5kB,EAAI,EAAGA,EAAI2kB,EAAQ3f,OAAQhF,IAE5B6kB,EAAM7kB,GAAK2kB,EAAQ3kB,EAEvB,OAAO6kB,IAGXC,EAAU,SAASC,EAAOC,GAEtB,GAAiBC,GAASjlB,EAAtB4iB,EAAS,EACb,IAAIoC,EAAW,CAEX,GADAC,EAAUF,EAAM,IACZE,EAAU,GACV,KAAM,iCAEV,IAAe,IAAXA,EACA,MAAO,EAEX,KAAKjlB,EAAI,EAAO,GAAKilB,EAATjlB,EAAkBA,IAC1B4iB,GAAUE,OAAOC,aAAagC,EAAM/kB,QAGxC,KAAKA,EAAI,EAAO,GAAJA,EAAQA,IAChB4iB,GAAUE,OAAOC,aAAagC,EAAM/kB,GAG5C,OAAO4iB,IAGXsC,EAAM,SAASC,GAEX,GAAiBnlB,GAAb4iB,EAAS,EACb,KAAK5iB,EAAI,EAAGA,EAAImlB,EAAOngB,OAAQhF,IAC3B4iB,IAAWuC,EAAOnlB,GAAK,GAAK,IAAK,IAAMmlB,EAAOnlB,GAAG8Q,SAAS,GAE9D,OAAO8R,IAGXwC,EAAM,SAASrW,GAEX,GAAIvD,KAKJ,OAJAuD,GAAEK,QAAQ,QACV,SAASL,GACLvD,EAAI9J,KAAK2jB,SAAStW,EAAG,OAElBvD,GAGX8Z,EAAM,SAAS1C,EAAQ2C,GACnB,GAAgBvlB,GAAZ6kB,IAMJ,KAJMU,IACF3C,EAASyB,EAASzB,IAGjB5iB,EAAI,EAAGA,EAAI4iB,EAAO5d,OAAQhF,IAE3B6kB,EAAM7kB,GAAK4iB,EAAOF,WAAW1iB,EAGjC,OAAO6kB,IAGXW,EAAO,SAASC,GAEZ,OAAQA,GAER,IAAK,KACDvB,EAAK,GACLC,EAAK,CACL,MACJ,KAAK,KACDD,EAAK,GACLC,EAAK,CACL,MACJ,KAAK,KACDD,EAAK,GACLC,EAAK,CACL,MACJ,SACI,KAAO,8BAAgCsB,IAI/CC,EAAU,SAASC,GACf,GAAiB3lB,GAAb6B,IACJ,KAAK7B,EAAI,EAAO2lB,EAAJ3lB,EAASA,IACjB6B,EAASA,EAAOM,OAAOtF,KAAKqjB,MAAsB,IAAhBrjB,KAAK0R,UAE3C,OAAO1M,IAGX+jB,EAAa,SAASC,EAAaC,GAO/B,GAMA9lB,GANI+lB,EAAS7B,GAAM,GAAK,EAAG,EAC3B3Y,KACAgY,KACAyC,KACAnkB,KACAokB,EAASJ,EAAY1jB,OAAO2jB,EAI5B,KAFAE,EAAS,GAAKE,aAAaC,KAAKC,IAAIH,GACpCpkB,EAASmkB,EAAS,GACbhmB,EAAI,EAAO+lB,EAAJ/lB,EAAYA,IACpBgmB,EAAShmB,GAAKkmB,aAAaC,KAAKC,IAAIJ,EAAShmB,EAAI,GAAGmC,OAAO8jB,IAC3DpkB,EAASA,EAAOM,OAAO6jB,EAAShmB,GAIpC,OAFAuL,GAAM1J,EAAOgJ,MAAM,EAAG,EAAIsZ,GAC1BZ,EAAK1hB,EAAOgJ,MAAM,EAAIsZ,EAAI,EAAIA,EAAK,KAE/B5Y,IAAKA,EACLgY,GAAIA,IAIZ8C,EAAa,SAASxC,EAAWtY,EAAKgY,GAElChY,EAAM+a,EAAU/a,EAChB,IAEAvL,GAFIumB,EAAY1pB,KAAK2pB,KAAK3C,EAAU7e,OAAS,IAC7CyhB,KAEAC,IACA,KAAK1mB,EAAI,EAAOumB,EAAJvmB,EAAeA,IACvBymB,EAAOzmB,GAAK0kB,EAASb,EAAUhZ,MAAU,GAAJ7K,EAAY,GAAJA,EAAS,IAO1D,KALI6jB,EAAU7e,OAAS,KAAO,IAC1ByhB,EAAO/kB,MAAM,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,KAEzE6kB,KAECvmB,EAAI,EAAGA,EAAIymB,EAAOzhB,OAAQhF,IAC3BymB,EAAOzmB,GAAY,IAANA,EAAW2mB,EAAUF,EAAOzmB,GAAIujB,GAAMoD,EAAUF,EAAOzmB,GAAI0mB,EAAa1mB,EAAI,IACzF0mB,EAAa1mB,GAAK4mB,EAAaH,EAAOzmB,GAAIuL,EAE9C,OAAOmb,IAGXG,EAAa,SAASC,EAAUvb,EAAKgY,EAAIgC,GAErCha,EAAM+a,EAAU/a,EAChB,IAEAvL,GAFIumB,EAAYO,EAAS9hB,OAAS,GAClC0hB,KAEAK,KACAnE,EAAS,EACT,KAAK5iB,EAAI,EAAOumB,EAAJvmB,EAAeA,IACvB0mB,EAAahlB,KAAKolB,EAASjc,MAAU,GAAJ7K,EAAkB,IAATA,EAAI,IAElD,KAAKA,EAAI0mB,EAAa1hB,OAAS,EAAGhF,GAAK,EAAGA,IACtC+mB,EAAY/mB,GAAKgnB,EAAaN,EAAa1mB,GAAIuL,GAC/Cwb,EAAY/mB,GAAY,IAANA,EAAW2mB,EAAUI,EAAY/mB,GAAIujB,GAAMoD,EAAUI,EAAY/mB,GAAI0mB,EAAa1mB,EAAI,GAE5G,KAAKA,EAAI,EAAOumB,EAAY,EAAhBvmB,EAAmBA,IAC3B4iB,GAAUkC,EAAQiC,EAAY/mB,GAGlC,OADA4iB,IAAUkC,EAAQiC,EAAY/mB,IAAI,GAC3BulB,EAAS3C,EAAS2B,EAAS3B,IAGtCgE,EAAe,SAAS7B,EAAOkC,GAC3B7C,GAAU,CACV,IACA8C,GADI3H,EAAQ4H,EAAYpC,EAAOkC,EAAO,EAEtC,KAAKC,EAAQ,EAAYhD,EAAK,EAAdgD,EAAkBA,IAC9B3H,EAAQ6H,EAAS7H,GACjBA,EAAQ8H,EAAU9H,GACN2E,EAARgD,IACA3H,EAAQ+H,EAAW/H,IAGvBA,EAAQ4H,EAAY5H,EAAO0H,EAAOC,EAGtC,OAAO3H,IAGXyH,EAAe,SAASjC,EAAOkC,GAC3B7C,GAAU,CACV,IACA8C,GADI3H,EAAQ4H,EAAYpC,EAAOkC,EAAO/C,EAEtC,KAAKgD,EAAQhD,EAAK,EAAGgD,EAAQ,GAAIA,IAC7B3H,EAAQ8H,EAAU9H,GAClBA,EAAQ6H,EAAS7H,GACjBA,EAAQ4H,EAAY5H,EAAO0H,EAAOC,GAC9BA,EAAQ,IACR3H,EAAQ+H,EAAW/H,GAK3B,OAAOA,IAGX6H,EAAW,SAAS7H,GAChB,GAEAvf,GAFImhB,EAAIiD,EAAUmD,EAASC,EAC3BC,IAEA,KAAKznB,EAAI,EAAO,GAAJA,EAAQA,IAChBynB,EAAKznB,GAAKmhB,EAAE5B,EAAMvf,GAEtB,OAAOynB,IAGXJ,EAAY,SAAS9H,GACjB,GAEAvf,GAFIynB,KACJC,EAAUtD,GAAW,EAAG,GAAI,GAAI,EAAG,EAAG,EAAG,GAAI,GAAI,EAAG,EAAG,EAAG,GAAI,GAAI,EAAG,EAAG,IAAM,EAAG,EAAG,GAAI,GAAI,EAAG,EAAG,GAAI,EAAG,EAAG,GAAI,EAAG,EAAG,GAAI,EAAG,EAAG,GAEhI,KAAKpkB,EAAI,EAAO,GAAJA,EAAQA,IAChBynB,EAAKznB,GAAKuf,EAAMmI,EAAQ1nB,GAE5B,OAAOynB,IAGXH,EAAa,SAAS/H,GAClB,GACAtd,GADI0lB,IAEJ,IAAKvD,EAQD,IAAKniB,EAAI,EAAO,EAAJA,EAAOA,IACf0lB,EAAI,EAAF1lB,GAAO2lB,EAAIrI,EAAQ,EAAFtd,IAAQ4lB,EAAItI,EAAM,EAAI,EAAFtd,IAAQ6lB,EAAIvI,EAAM,EAAI,EAAFtd,IAAQ8lB,EAAIxI,EAAM,EAAI,EAAFtd,IAC/E0lB,EAAE,EAAI,EAAF1lB,GAAO8lB,EAAIxI,EAAQ,EAAFtd,IAAQ2lB,EAAIrI,EAAM,EAAI,EAAFtd,IAAQ4lB,EAAItI,EAAM,EAAI,EAAFtd,IAAQ6lB,EAAIvI,EAAM,EAAI,EAAFtd,IACjF0lB,EAAE,EAAI,EAAF1lB,GAAO6lB,EAAIvI,EAAQ,EAAFtd,IAAQ8lB,EAAIxI,EAAM,EAAI,EAAFtd,IAAQ2lB,EAAIrI,EAAM,EAAI,EAAFtd,IAAQ4lB,EAAItI,EAAM,EAAI,EAAFtd,IACjF0lB,EAAE,EAAI,EAAF1lB,GAAO4lB,EAAItI,EAAQ,EAAFtd,IAAQ6lB,EAAIvI,EAAM,EAAI,EAAFtd,IAAQ8lB,EAAIxI,EAAM,EAAI,EAAFtd,IAAQ2lB,EAAIrI,EAAM,EAAI,EAAFtd,QAXrF,KAAKA,EAAI,EAAO,EAAJA,EAAOA,IACf0lB,EAAM,EAAJ1lB,GAAS+lB,EAAIzI,EAAU,EAAJtd,IAAUgmB,EAAI1I,EAAM,EAAQ,EAAJtd,IAAUsd,EAAM,EAAQ,EAAJtd,GAASsd,EAAM,EAAQ,EAAJtd,GACpF0lB,EAAE,EAAQ,EAAJ1lB,GAASsd,EAAU,EAAJtd,GAAS+lB,EAAIzI,EAAM,EAAQ,EAAJtd,IAAUgmB,EAAI1I,EAAM,EAAQ,EAAJtd,IAAUsd,EAAM,EAAQ,EAAJtd,GACxF0lB,EAAE,EAAQ,EAAJ1lB,GAASsd,EAAU,EAAJtd,GAASsd,EAAM,EAAQ,EAAJtd,GAAS+lB,EAAIzI,EAAM,EAAQ,EAAJtd,IAAUgmB,EAAI1I,EAAM,EAAQ,EAAJtd,IACvF0lB,EAAE,EAAQ,EAAJ1lB,GAASgmB,EAAI1I,EAAU,EAAJtd,IAAUsd,EAAM,EAAQ,EAAJtd,GAASsd,EAAM,EAAQ,EAAJtd,GAAS+lB,EAAIzI,EAAM,EAAQ,EAAJtd,GAW/F,OAAO0lB,IAGXR,EAAc,SAAS5H,EAAO0H,EAAOC,GACjC,GACAlnB,GADIynB,IAEJ,KAAKznB,EAAI,EAAO,GAAJA,EAAQA,IAChBynB,EAAKznB,GAAKuf,EAAMvf,GAAKinB,EAAMC,GAAOlnB,EAEtC,OAAOynB,IAGXd,EAAY,SAASuB,EAAQC,GACzB,GACAnoB,GADIynB,IAEJ,KAAKznB,EAAI,EAAO,GAAJA,EAAQA,IAChBynB,EAAKznB,GAAKkoB,EAAOloB,GAAKmoB,EAAOnoB,EAEjC,OAAOynB,IAGXnB,EAAY,SAAS/a,GAEjB,GAEAvL,GACA6V,EACA8R,EAEA3F,EANI/B,KACJwH,KAIAW,IAGA,KAAKpoB,EAAI,EAAOmkB,EAAJnkB,EAAQA,IAChB6V,GAAKtK,EAAI,EAAIvL,GAAIuL,EAAI,EAAIvL,EAAI,GAAIuL,EAAI,EAAIvL,EAAI,GAAIuL,EAAI,EAAIvL,EAAI,IAC7DigB,EAAEjgB,GAAK6V,CAGX,KAAK7V,EAAImkB,EAAS,GAAKD,EAAK,GAAflkB,EAAoBA,IAAK,CAElC,IADAigB,EAAEjgB,MACG2nB,EAAI,EAAO,EAAJA,EAAOA,IACfF,EAAKE,GAAK1H,EAAEjgB,EAAI,GAAG2nB,EAQvB,KANI3nB,EAAImkB,IAAO,GACXsD,EAAOY,EAAQC,EAAQb,IACvBA,EAAK,IAAMc,EAAKvoB,EAAImkB,EAAK,IAClBA,EAAK,GAAKnkB,EAAImkB,GAAM,IAC3BsD,EAAOY,EAAQZ,IAEdE,EAAI,EAAO,EAAJA,EAAOA,IACf1H,EAAEjgB,GAAG2nB,GAAK1H,EAAEjgB,EAAImkB,GAAIwD,GAAKF,EAAKE,GAGtC,IAAK3nB,EAAI,EAAQkkB,EAAK,EAAVlkB,EAAcA,IAEtB,IADAooB,EAAKpoB,MACAgiB,EAAI,EAAO,EAAJA,EAAOA,IACfoG,EAAKpoB,GAAG0B,KAAKue,EAAM,EAAJjgB,EAAQgiB,GAAG,GAAI/B,EAAM,EAAJjgB,EAAQgiB,GAAG,GAAI/B,EAAM,EAAJjgB,EAAQgiB,GAAG,GAAI/B,EAAM,EAAJjgB,EAAQgiB,GAAG,GAGrF,OAAOoG,IAGXC,EAAU,SAASpI,GAEf,IAAK,GAAIjgB,GAAI,EAAO,EAAJA,EAAOA,IACnBigB,EAAEjgB,GAAKwnB,EAAKvH,EAAEjgB,GAElB,OAAOigB,IAGXqI,EAAU,SAASrI,GAEf,GACAjgB,GADIwoB,EAAMvI,EAAE,EAEZ,KAAKjgB,EAAI,EAAO,EAAJA,EAAOA,IACfigB,EAAEjgB,GAAKigB,EAAEjgB,EAAI,EAGjB,OADAigB,GAAE,GAAKuI,EACAvI,GAIXwI,EAAS,SAASnT,EAAIkQ,GAClB,GAAIha,KACJ,KAAKxL,EAAE,EAAGA,EAAEsV,EAAItQ,OAAQhF,GAAGwlB,EACvBha,EAAIxL,EAAEwlB,GAAQH,SAAS/P,EAAIvE,OAAO/Q,EAAEwlB,GAAO,GAC/C,OAAOha,IAEXkd,EAAY,SAASC,GACjB,GAAInd,KACJ,KAAKxL,EAAE,EAAGA,EAAE2oB,EAAI3jB,OAAQhF,IACpBwL,EAAImd,EAAI3oB,IAAMA,CAClB,OAAOwL,IAEXod,EAAM,SAAS9M,EAAGnM,GACd,GAAI3P,GAAGwL,CAGP,KADAA,EAAM,EACDxL,EAAE,EAAK,EAAFA,EAAKA,IACXwL,EAAc,IAAJ,EAAFmE,GAAWnE,EAAIsQ,EAAItQ,EAE3BsQ,EAAKA,EAAE,IAAQ,IAAOA,GAAG,EAAMA,GAAG,EAClCnM,KAAO,CAGX,OAAOnE,IAEXqd,EAAK,SAAS9H,GAEV,IAAK,GADDlL,MACK7V,EAAE,EAAK,IAAFA,EAAOA,IACjB6V,EAAE7V,GAAK4oB,EAAI7H,EAAG/gB,EAClB,OAAO6V,IAuBD2R,EAAOiB,EAAO,mgBAAmgB,GAqBhhBlB,EAAUmB,EAAUlB,GAM9Be,EAAOE,EAAO,+DAA+D,GA0BtET,EAAMa,EAAG,GAyBTZ,EAAMY,EAAG,GA0BTd,EAAMc,EAAG,GAyBThB,EAAMgB,EAAG,IA0BTf,EAAMe,EAAG,IA0BTjB,EAAMiB,EAAG,IAEjBC,EAAM,SAASlG,EAAQmG,EAAMxD,GAEzB,GAIAmB,GAJIsC,EAAOtD,EAAQ,GACnBuD,EAAMrD,EAAWN,EAAIyD,EAAMxD,GAASyD,GACpCzd,EAAM0d,EAAI1d,IACVgY,EAAK0F,EAAI1F,GAET2F,IAAc,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAI/mB,OAAO6mB,GAKzD,OAJApG,GAAS0C,EAAI1C,EAAQ2C,GACrBmB,EAAeL,EAAWzD,EAAQrX,EAAKgY,GAEvCmD,EAAewC,EAAU/mB,OAAOukB,GACzByC,EAAOvnB,OAAO8kB,IAGzB0C,EAAM,SAASxG,EAAQmG,EAAMxD,GAEzB,GAAIuB,GAAWqC,EAAOxd,OAAOiX,GAC7BoG,EAAOlC,EAASjc,MAAM,EAAG,IACzBoe,EAAMrD,EAAWN,EAAIyD,EAAMxD,GAASyD,GACpCzd,EAAM0d,EAAI1d,IACVgY,EAAK0F,EAAI1F,EAIT,OAHAuD,GAAWA,EAASjc,MAAM,GAAIic,EAAS9hB,QAEvC4d,EAASiE,EAAWC,EAAUvb,EAAKgY,EAAIgC,IAI3Ca,EAAM,SAASjB,GAEX,QAASkE,GAAWC,EAAQC,GACxB,MAAQD,IAAUC,EAAeD,IAAY,GAAKC,EAGtD,QAASC,GAAYC,EAAIC,GACrB,GAAIC,GACJC,EACAC,EACAC,EACAC,CAMA,OALAF,GAAY,WAALJ,EACPK,EAAY,WAALJ,EACPC,EAAY,WAALF,EACPG,EAAY,WAALF,EACPK,GAAgB,WAALN,IAAyB,WAALC,GAC3BC,EAAMC,EACY,WAAVG,EAAuBF,EAAMC,EAErCH,EAAMC,EACQ,WAAVG,EACkB,WAAVA,EAAuBF,EAAMC,EAEnB,WAAVC,EAAuBF,EAAMC,EAGjCC,EAAUF,EAAMC,EAIhC,QAASplB,GAAEqc,EAAGC,EAAGO,GACb,MAAQR,GAAIC,GAAQD,EAAKQ,EAE7B,QAASpW,GAAE4V,EAAGC,EAAGO,GACb,MAAQR,GAAIQ,EAAMP,GAAMO,EAE5B,QAASQ,GAAEhB,EAAGC,EAAGO,GACb,MAAQR,GAAIC,EAAIO,EAEpB,QAASyI,GAAMjJ,EAAGC,EAAGO,GACjB,MAAQP,IAAKD,GAAMQ,GAGvB,QAAS0I,GAAGnO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAGhS,EAAGmb,GAE1B,MADApO,GAAI0N,EAAY1N,EAAG0N,EAAYA,EAAY9kB,EAAEiL,EAAG1N,EAAG6f,GAAIf,GAAImJ,IACpDV,EAAYH,EAAWvN,EAAG/M,GAAIY,GAGzC,QAASwa,GAAGrO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAGhS,EAAGmb,GAE1B,MADApO,GAAI0N,EAAY1N,EAAG0N,EAAYA,EAAYre,EAAEwE,EAAG1N,EAAG6f,GAAIf,GAAImJ,IACpDV,EAAYH,EAAWvN,EAAG/M,GAAIY,GAGzC,QAASya,GAAGtO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAGhS,EAAGmb,GAE1B,MADApO,GAAI0N,EAAY1N,EAAG0N,EAAYA,EAAYzH,EAAEpS,EAAG1N,EAAG6f,GAAIf,GAAImJ,IACpDV,EAAYH,EAAWvN,EAAG/M,GAAIY,GAGzC,QAAST,GAAG4M,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAGhS,EAAGmb,GAE1B,MADApO,GAAI0N,EAAY1N,EAAG0N,EAAYA,EAAYQ,EAAMra,EAAG1N,EAAG6f,GAAIf,GAAImJ,IACxDV,EAAYH,EAAWvN,EAAG/M,GAAIY,GAGzC,QAAS0a,GAAmBlF,GASxB,IARA,GAAImF,GACJC,EAAiBpF,EAAOngB,OACxBwlB,EAAuBD,EAAiB,EACxCE,GAAwBD,EAAwBA,EAAuB,IAAO,GAC9EE,EAA8C,IAA5BD,EAAuB,GACzCE,KACAC,EAAgB,EAChBC,EAAa,EACON,EAAbM,GACHP,GAAcO,EAAcA,EAAa,GAAM,EAC/CD,EAAiBC,EAAa,EAAK,EACnCF,EAAWL,GAAeK,EAAWL,GAAenF,EAAO0F,IAAeD,EAC1EC,GAOJ,OALAP,IAAcO,EAAcA,EAAa,GAAM,EAC/CD,EAAiBC,EAAa,EAAK,EACnCF,EAAWL,GAAcK,EAAWL,GAAe,KAAQM,EAC3DD,EAAWD,EAAiB,GAAKH,GAAkB,EACnDI,EAAWD,EAAiB,GAAKH,IAAmB,GAC7CI,EAGX,QAASG,GAAUxB,GACf,GAAIyB,GACJC,EACAC,IACA,KAAKD,EAAS,EAAa,GAAVA,EAAaA,IAC1BD,EAASzB,IAAqB,EAAT0B,EAAe,IACpCC,EAAeA,EAAa9oB,OAAO4oB,EAEvC,OAAOE,GA+BX,GACA/U,GACAgV,EACAC,EACAC,EACAC,EACAvP,EACAnM,EACA1N,EACA6f,EATIf,KAUJuK,EAAM7C,EAAO,miBAAmiB,EAShjB,KAPA1H,EAAIsJ,EAAmBlF,GAEvBrJ,EAAIwP,EAAI,GACR3b,EAAI2b,EAAI,GACRrpB,EAAIqpB,EAAI,GACRxJ,EAAIwJ,EAAI,GAEHpV,EAAI,EAAGA,EAAI6K,EAAE/b,OAAQkR,GAAK,GAC3BgV,EAAKpP,EACLqP,EAAKxb,EACLyb,EAAKnpB,EACLopB,EAAKvJ,EACLhG,EAAImO,EAAGnO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,IACpCxJ,EAAImI,EAAGnI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,IACrCrpB,EAAIgoB,EAAGhoB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,IACrC3b,EAAIsa,EAAGta,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,IACrCxP,EAAImO,EAAGnO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,IACpCxJ,EAAImI,EAAGnI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,IACrCrpB,EAAIgoB,EAAGhoB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrC3b,EAAIsa,EAAGta,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCxP,EAAImO,EAAGnO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAImI,EAAGnI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCrpB,EAAIgoB,EAAGhoB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtC3b,EAAIsa,EAAGta,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCxP,EAAImO,EAAGnO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,IAAK,EAAGoV,EAAI,KACrCxJ,EAAImI,EAAGnI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCrpB,EAAIgoB,EAAGhoB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtC3b,EAAIsa,EAAGta,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCxP,EAAIqO,EAAGrO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAIqI,EAAGrI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCrpB,EAAIkoB,EAAGloB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtC3b,EAAIwa,EAAGxa,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCxP,EAAIqO,EAAGrO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAIqI,EAAGrI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,IAAK,EAAGoV,EAAI,KACrCrpB,EAAIkoB,EAAGloB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtC3b,EAAIwa,EAAGxa,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCxP,EAAIqO,EAAGrO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAIqI,EAAGrI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,IAAK,EAAGoV,EAAI,KACrCrpB,EAAIkoB,EAAGloB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrC3b,EAAIwa,EAAGxa,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCxP,EAAIqO,EAAGrO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,IAAK,EAAGoV,EAAI,KACrCxJ,EAAIqI,EAAGrI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCrpB,EAAIkoB,EAAGloB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrC3b,EAAIwa,EAAGxa,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCxP,EAAIsO,EAAGtO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAIsI,EAAGtI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCrpB,EAAImoB,EAAGnoB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtC3b,EAAIya,EAAGza,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCxP,EAAIsO,EAAGtO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAIsI,EAAGtI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCrpB,EAAImoB,EAAGnoB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrC3b,EAAIya,EAAGza,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCxP,EAAIsO,EAAGtO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,IAAK,EAAGoV,EAAI,KACrCxJ,EAAIsI,EAAGtI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCrpB,EAAImoB,EAAGnoB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrC3b,EAAIya,EAAGza,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCxP,EAAIsO,EAAGtO,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAIsI,EAAGtI,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCrpB,EAAImoB,EAAGnoB,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtC3b,EAAIya,EAAGza,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCxP,EAAI5M,EAAG4M,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAI5S,EAAG4S,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCrpB,EAAIiN,EAAGjN,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtC3b,EAAIT,EAAGS,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCxP,EAAI5M,EAAG4M,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,IAAK,EAAGoV,EAAI,KACrCxJ,EAAI5S,EAAG4S,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCrpB,EAAIiN,EAAGjN,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtC3b,EAAIT,EAAGS,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCxP,EAAI5M,EAAG4M,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAI5S,EAAG4S,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCrpB,EAAIiN,EAAGjN,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrC3b,EAAIT,EAAGS,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCxP,EAAI5M,EAAG4M,EAAGnM,EAAG1N,EAAG6f,EAAGf,EAAE7K,EAAI,GAAI,EAAGoV,EAAI,KACpCxJ,EAAI5S,EAAG4S,EAAGhG,EAAGnM,EAAG1N,EAAG8e,EAAE7K,EAAI,IAAK,GAAIoV,EAAI,KACtCrpB,EAAIiN,EAAGjN,EAAG6f,EAAGhG,EAAGnM,EAAGoR,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrC3b,EAAIT,EAAGS,EAAG1N,EAAG6f,EAAGhG,EAAGiF,EAAE7K,EAAI,GAAI,GAAIoV,EAAI,KACrCxP,EAAI0N,EAAY1N,EAAGoP,GACnBvb,EAAI6Z,EAAY7Z,EAAGwb,GACnBlpB,EAAIunB,EAAYvnB,EAAGmpB,GACnBtJ,EAAI0H,EAAY1H,EAAGuJ,EAGvB,OAAOP,GAAUhP,GAAG3Z,OAAO2oB,EAAUnb,GAAImb,EAAU7oB,GAAI6oB,EAAUhJ,KAsCrEqH,EAAS,WAEL,GAAIoC,GAAS,mEACbC,EAAQD,EAAOjN,MAAM,IAErB1c,EAAS,SAAS+N,GACd,CAAA,GAEA3P,GACAyrB,EAHIC,KACJC,EAAM,EAGY9uB,MAAKqjB,MAAiB,GAAXvQ,EAAE3K,OAAc,GAC7C,IAAKhF,EAAI,EAAGA,EAAe,GAAX2P,EAAE3K,OAAahF,IAC3B0rB,EAAQhqB,KAAKiO,EAAE9S,KAAKqjB,MAAMlgB,EAAI,KAAKA,EAAI,IAE3C,KAAKA,EAAI,EAAGA,EAAI0rB,EAAQ1mB,OAAQhF,GAAQ,EACpC2rB,GAAOH,EAAME,EAAQ1rB,IAAM,GAC3B2rB,GAAOH,GAAqB,EAAbE,EAAQ1rB,KAAW,EAAM0rB,EAAQ1rB,EAAI,IAAM,GAEtD2rB,GADsB/uB,SAAnB8uB,EAAQ1rB,EAAI,GACRwrB,GAAyB,GAAjBE,EAAQ1rB,EAAI,KAAY,EAAM0rB,EAAQ1rB,EAAI,IAAM,GAExD,IAGP2rB,GADsB/uB,SAAnB8uB,EAAQ1rB,EAAI,GACRwrB,EAAuB,GAAjBE,EAAQ1rB,EAAI,IAElB,GAKf,KADAyrB,EAAaE,EAAI9gB,MAAM,EAAG,IACrB7K,EAAI,EAAGA,EAAKnD,KAAW,KAAE8uB,EAAI3mB,OAAS,IAAMhF,IAC7CyrB,GAAcE,EAAI9gB,MAAU,GAAJ7K,EAAY,GAAJA,EAAS,KAAOnD,KAAK2pB,KAAKmF,EAAI3mB,OAAS,KAAOhF,EAAI,EAAI,GAAI,KAE9F,OAAOyrB,IAGX9f,EAAS,SAASiX,GACdA,EAASA,EAAgB,QAAE,MAAO,GAClC,IAGA5iB,GAHI0rB,KACJzpB,KACA0N,IAEA,KAAK3P,EAAI,EAAGA,EAAI4iB,EAAO5d,OAAQhF,GAAQ,EACnCiC,EAAE,GAAKspB,EAAO/oB,QAAQogB,EAAOQ,OAAOpjB,IACpCiC,EAAE,GAAKspB,EAAO/oB,QAAQogB,EAAOQ,OAAOpjB,EAAI,IACxCiC,EAAE,GAAKspB,EAAO/oB,QAAQogB,EAAOQ,OAAOpjB,EAAI,IACxCiC,EAAE,GAAKspB,EAAO/oB,QAAQogB,EAAOQ,OAAOpjB,EAAI,IAExC2P,EAAE,GAAM1N,EAAE,IAAM,EAAMA,EAAE,IAAM,EAC9B0N,EAAE,IAAc,GAAP1N,EAAE,KAAY,EAAMA,EAAE,IAAM,EACrC0N,EAAE,IAAc,EAAP1N,EAAE,KAAW,EAAKA,EAAE,GAC7BypB,EAAQhqB,KAAKiO,EAAE,GAAIA,EAAE,GAAIA,EAAE,GAG/B,OADA+b,GAAUA,EAAQ7gB,MAAM,EAAG6gB,EAAQ1mB,OAAU0mB,EAAQ1mB,OAAS,IAwBlE,OAnB4B,kBAAlBjD,OAAMS,UACZ+oB,EAASC,IAmBT5pB,OAAUA,EACV+J,OAAUA,KAIlB,QACI6Z,KAAQA,EACRJ,IAAMA,EACNkB,UAAYA,EACZM,aAAeA,EACfI,aAAeA,EACf5C,QAAUA,EACVkB,IAAMA,EACNe,WAAaA,EACbQ,WAAaA,EACbuC,IAAMA,EACNxD,WAAaA,EACbV,IAAMA,EACN4D,IAAMA,EACN3C,MAAQC,IAAMA,GACd+C,OAASA,OAiNjB,WA8CA,QAASzQ,GAAK3B,GACV,GAAI6U,GACAC,EAAW,WACP,IAAIC,EAAJ,CACIA,EAAS,EAEb/Y,aAAagZ,EAEb,KAAY3qB,SAAW2G,KAAY,MAAE6jB,EAAII,cACzC,MAAOnW,GAAK,MAAOoW,GAAK,GAExB7S,EAAQhY,YAEZ8qB,EAAW,EACXJ,EAAW,EACXC,EAAW3Z,QAAS,WAAW6Z,EAAK,IAAKE,GACzCrnB,EAAWiS,EAAMjS,SACjBuX,EAAWtF,EAAMsF,MAAW,aAC5BjD,EAAWrC,EAAMqC,SAAW,aAC5BgT,EAAwC,mBAApBrV,GAAc,SAClCkV,EAAW,SAASI,EAAQjrB,GACpB8qB,IACAA,EAAW,EAEfnZ,aAAagZ,GAETH,IACAA,EAAIjuB,QAAUiuB,EAAI9jB,OAAS,KAC3B8jB,EAAIU,OAASV,EAAIU,QACjBV,EAAM,MAGVS,GAAUhQ,EAAKjb,IAIvB,KACIwqB,EAAgC,mBAAnBW,iBACP,GAAIA,iBACJ,GAAI3kB,gBAEVgkB,EAAIjuB,QAAUiuB,EAAIY,QAAY,WAAYP,EAAK,EAAGL,EAAII,eAAkBxuB,MAAU,8BAClFouB,EAAI9jB,OAAU8jB,EAAIa,UAAYZ,EAC9BD,EAAIc,mBAAqB,WACrB,GAAsB,GAAlBd,EAAIe,WACJ,OAAOf,EAAI3oB,QACP,IAAK,KACL,IAAK,KACL,IAAK,KACD,IACI7B,SAAW2G,KAAY,MAAE6jB,EAAII,cAC7BC,EAAK,EAAE7qB,UAEX,MAAOyU,GAAK,MAAOoW,GAAK,EAAGL,EAAII,iBAO3CI,IAAOR,EAAIxZ,QAAU+Z,GACzBrnB,EAAY,MAAI8nB,EAChBne,IAAM4F,UAAU0C,EAAMtI,IAAK3J,GAC3B8mB,EAAI/jB,KAAM,MAAO4G,IAAK2d,GACtBR,EAAI1rB,OAER,MAAM2sB,GAEF,MADAZ,GAAK,GACEvT,EAAI3B,GAIf,MAAOkV,GAUX,QAASjf,GAAMtO,EAAMouB,EAAIhY,GACrBJ,KAAMhW,EAAK4f,MAAM,KAAM,SAASyO,GAC5B,GAAIC,GAAS,SAAS5U,GACbA,IAAGA,EAAI9T,OAAO9F,OACdsW,EAAIsD,KACLA,EAAE6U,cAAe,EACjB7U,EAAE8U,aAAe,EACjB9U,EAAE+U,gBAAkB/U,EAAE+U,iBACtB/U,EAAErT,iBAAmBqT,EAAErT,mBAI1B+nB,GAAGvuB,iBAAmBuuB,EAAGvuB,iBAAkBwuB,EAAOC,GAAQ,GACrDF,EAAGM,YAAcN,EAAGM,YAAa,KAAOL,EAAOC,GACnDF,EAAI,KAAOC,GAAUC,IAoBnC,QAASxvB,GAAMgC,GAAW/B,QAAe,MAAE+B,GAiC3C,QAAS6tB,GAAM9c,EAAM+c,EAAWhuB,GAC5B,MAAIA,OAAOiR,GAAKgd,aAAcD,EAAWhuB,GAC7BiR,GAAQA,EAAKid,cAAgBjd,EAAKid,aAAaF,GAQ/D,QAASG,GAAE5kB,GAAM,MAAO8I,UAAS+b,eAAe7kB,GAQhD,QAAS0N,GAAQoX,EAAUlQ,GACvB,GAAIpS,KAMJ,OALAqJ,MAAMiZ,EAASrP,MAAM,OAAQ,SAASwO,GAClCpY,MAAO+I,GAAS9L,UAAUic,qBAAqBd,GAAK,SAASvc,GACzDlF,EAAK3J,KAAK6O,OAGXlF,EAQX,QAASwiB,GAAKC,EAASC,GACnB,IAAK,GAAIC,KAASD,GAAQ,GAAIA,EAAO9X,eAAe+X,GAChD,IAAKF,EAAQE,MAAMA,GAASD,EAAOC,IAC/B,0BAA0BxrB,QAAQwrB,GAAS,GACnB,gBAAjBD,GAAOC,GACZ,KAAO,IACX,MAAM5V,KAQhB,QAAS5K,GAAOsgB,GAAW,MAAOnc,UAASsc,cAAcH,GAGzD,QAASI,GAAgBppB,EAAKyG,GAC1B,GAAI4iB,GAAOC,SAAqB,WAAEtpB,EAAMyG,EACxC,OAAO4iB,GAAKrd,SAASsd,SAAc,IAAU,QASjD,QAASC,GAActX,GAGnBA,EAAU,GAAI6E,EACd7E,EAAW,IAAI2B,EACf3B,EAAa,MAAIA,EAAa,OAAKvZ,EACnCuZ,EAAmB,YAAGmX,EACtBnX,EAAkB,WAAIY,aACtBZ,EAAc,QAAWuX,MAAU1B,GAEnCzU,KAAO,SAASpB,GACZ,MAAOsX,GAActX,GAEzB,IAAIwX,GAAKzX,OAAOC,EAChB,KAAK,GAAIyX,KAAQD,GACTA,EAAGtY,eAAeuY,KAClBrW,KAAKqW,GAAQD,EAAGC,GAoBxB,OAhBArW,MAAW,KAAIA,KACfA,KAAQ,EAAIsV,EACZtV,KAAW,KAAIkV,EACflV,KAAa,OAAI5B,EACjB4B,KAAW,KAAInL,EACfmL,KAAU,IAAI0V,EACd1V,KAAa,OAAI3K,EAEM,mBAAb,SACNR,EAAM,eAAgB1I,OAAQ,WAE1B,MADA6T,MAAK,gBAAgB,SAASsW,GAAKtW,KAAY,MAAGsW,EAAGjd,KAAM,MACpD,IAKXuF,EAAc,OAAUoB,MAEL,mBAAb,SACNnL,EAAM,UAAW1I,OAAU6T,KAAqB,gBAG3B,mBAAf,WACNnL,EAAM,UAAW2E,SAAUwG,KAAqB,gBAGpDA,KAAY,QACLA,MA1SX,GACKyU,GAAa,yBACdT,EAAa,KAObvQ,EAAK,WACL,GAAI8S,GAA4B,mBAAhBC,eAA+BA,YAC/C,QACItuB,IAAM,SAASkL,GACX,IACI,MAAImjB,GAAWA,EAAGE,QAAQrjB,GACU,IAAhCoG,SAASkd,OAAOrsB,QAAQ+I,GAAmB,OACtCoG,SAASkd,QAAQ,IAAInZ,MAC1BoZ,OAAOvjB,EAAI,kBACR,IAAM,KACf,MAAM6M,GAAK,SAEjB5F,IAAM,SAAUjH,EAAKjM,GACjB,IACI,GAAIovB,EAAI,MAAOA,GAAGK,QAASxjB,EAAKjM,IAAW,CAC3CqS,UAASkd,OAAStjB,EAAM,IAAMjM,EAC1B,iDACN,MAAM8Y,GAAK,YAkRzBiW,GAAoB,KAAIA,EACxBA,EAAsB,OAAIA,EAC1BpiB,OAASoiB,MACU,mBAAZhyB,UAA4BA,OAAOC,QAAU+xB,IACjC,mBAAZ/xB,WAA4BA,QAAQ2P,OAASoiB,KAAmBpiB,OAASoiB,MAGhF,WAKA,GAAIW,GAAK/iB,OAAW,GAAI,SAAUwC,EAAKwgB,GACnC,KAAMvyB,eAAgBsyB,IAAK,MAAO,IAAIA,GAAIvgB,EAAKwgB,EAE/C,IAAItyB,GAAWD,KACX+R,EAAW9R,EAAK8R,IAAWA,GAAO,GAElCygB,GADWvyB,EAAKwyB,SAAWF,GAAa,yBAC7BxgB,EAAI6P,MAAM,MACrBvH,GACCqY,IAA8B,SAAZF,EAAK,GACvBhT,OAAkBgT,EAAK,GACvBG,YAAkBH,EAAK,GACvBI,cAAkBJ,EAAK,GACvBztB,QAAkBytB,EAAK,GAgC5B,OA5BAvyB,GAAiB,WAAI,EACrBA,EAAW,KAAU,EACrBA,EAAc,QAAO,EACrBA,EAAa,OAAQ,EAGrBA,EAAmB,aAAY,IAC/BA,EAAuB,iBAAQ,KAC/BA,EAA2B,qBAAI,KAC/BA,EAAwB,kBAAO,KAC/BA,EAAsB,gBAAS,KAC/BA,EAAsB,gBAAS,KAC/BA,EAAqB,eAAU,KAG/BA,EAAc,QAAMA,EAAc,QAClCA,EAAgB,UAAIA,EAAa,OACjCA,EAAa,OAAQ,aAGrBA,EAAiB,WAAQ,GACzBA,EAAiB,WAAQ,GACzBA,EAAqB,eAAI,EACzBA,EAAmB,cAAM,EACzBA,EAAa,UACbA,EAAiB,WAAQA,EAAiB,WAGrC8R,GAWL9R,EAAKqP,OAAeC,OAAa,KAAE8K,GACnCpa,EAAKqP,OAAO+K,MAAQA,EACpBpa,EAAKoa,MAAeA,MAEpBpa,GAAKqP,OAAkB,WACnBI,SAAe,EACf3K,QAAesV,EAAe,QAC9BxK,WAAe5P,EAAc,QAC7BgiB,UAAehiB,EAAa,OAC5Ba,MAAe,WACXb,EAAc,SACV4D,KAAa5D,EAAqB,eAClC4yB,OAAa,cACbC,UAAa,KAGrBvxB,SAAe,SAASuB,GACpB7C,EAAgB,WAAImI,KAAStF,KAEjC8M,QAAe,WACX3P,EAAiB,WAAIA,EAAW,KAChCA,EAAa,cA/BjBA,EAAiB,WAAIA,EAAa,OAClCA,EAAc,SACV4D,KAAa5D,EAAqB,eAClC4yB,OAAa,cACbC,UAAa,IAEV7yB,GAiCfqyB,GAAG5xB,UAAU8C,KAAO,SAAS4E,GACzB,GAAInI,GAAOD,IACXC,GAAKqP,OAAgB,SACjBvK,QAAa9E,EAAKqP,OAAO+K,MAAe,QACxCvX,QAAasF,EACb7G,SAAa,SAASmD,GAClBzE,EAAa,QAAImI,KAAS1D,QAQtC4tB,EAAG5xB,UAAUF,MAAQ,WACjB,GAAIP,GAAOD,IACXC,GAAKqP,OAAoB,aAAIvK,QAAY9E,EAAKqP,OAAO+K,MAAe,UACpEpa,EAAiB,WAAIA,EAAa,OAClCA,EAAc","sourcesContent":["(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);throw new Error(\"Cannot find module '\"+o+\"'\")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.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})","/**\n * New node file\n */\nvar HandshakeConnector = require('./connectors/core/HandshakeConnector');\nvar WebP2P             = require('./WebP2P');\n\n\nmodule.exports = WebP2P;\nmodule.exports.HandshakeConnector = HandshakeConnector;","var inherits = require(\"inherits\");\n\nvar Connector = require(\"./Connector\");\n\n\nfunction HandshakeConnector(max_connections)\n{\n  Connector.call(this);\n\n  var self = this;\n\n\n  if(max_connections != undefined)\n    this.max_connections = Math.min(max_connections, this.max_connections);\n\n  /**\n   * Check if we should connect this new peer or ignore it to increase entropy\n   * in the network mesh\n   *\n   * @returns {Boolean}\n   */\n  this.shouldConnect = function()\n  {\n    return true;\n  };\n\n\n  // Count the maximum number of pending connections allowed to be\n  // done with this handshake server (undefined == unlimited)\n  var connections = 0;\n\n  this.increaseConnections = function()\n  {\n    // Increase the number of connections reached throught\n    // this handshake server\n    connections++;\n\n    // Close connection with handshake server if we got its quota of peers\n    if(connections >= self.max_connections)\n       self.close();\n  };\n};\ninherits(HandshakeConnector, Connector);\n\n\n// Class constants\nHandshakeConnector.prototype.max_connections = Number.POSITIVE_INFINITY;\n\n\nmodule.exports = HandshakeConnector;\n","var EventEmitter = require(\"events\").EventEmitter;\n\nvar inherits = require('inherits');\nvar freeice  = require('freeice');\nvar uuid     = require('uuid');\nvar wrtc     = require('wrtc');\n\nvar RTCPeerConnection     = wrtc.RTCPeerConnection;\nvar RTCSessionDescription = wrtc.RTCSessionDescription;\n\nrequire(\"process-events-shim\");\n\nvar RpcBuilder = require('rpc-builder');\n\nvar HandshakeManager = require('./managers/HandshakeManager');\nvar PeersManager     = require('./managers/PeersManager');\n\nvar packer = require('./packer');\n\n\nconst MAX_TTL_DEFAULT = 5;\n\n\nfunction noop(error)\n{\n  if(error) console.error(error);\n};\n\n\n\n/**\n * @classdesc Init and connect to the WebP2P.io network\n *\n * @constructor\n */\nfunction WebP2P(options)\n{\n  var self = this;\n\n\n  options = options || {};\n\n  // Internal options\n  var commonLabels      = options.commonLabels || [];\n  var handshake_servers = options.handshake_servers;\n  var iceServers        = freeice(options.iceServers);\n\n  // Read-only options\n  Object.defineProperty(this, \"routingLabel\",\n  {\n    value: options.routingLabel || \"webp2p\"\n  });\n  Object.defineProperty(this, \"sessionID\",\n  {\n    value: options.sessionID || uuid.v4()\n  });\n\n\n  var options =\n  {\n    max_retries: 3,\n    peerID: this.sessionID\n  };\n\n  var rpcBuilder = new RpcBuilder(packer, options);\n\n  var handshakeManager = new HandshakeManager(rpcBuilder, handshake_servers);\n  var peersManager     = new PeersManager(rpcBuilder, self.routingLabel);\n\n  this.__defineGetter__('status', function()\n  {\n    if(peersManager.status == 'connected')\n      return 'connected';\n\n    return handshakeManager.status;\n  });\n\n  this.__defineGetter__(\"peers\", function()\n  {\n    return peersManager.peers;\n  });\n\n\n  function onerror(error)\n  {\n    self.emit('error', new Error(error));\n  };\n\n\n  var offers = {};\n\n  /**\n   * Create a new RTCPeerConnection\n   * @param {UUID} sessionID Identifier of the other peer so later can be accessed.\n   *\n   * @return {RTCPeerConnection}\n   */\n  function createPeerConnection(sessionID, callbackType, callback)\n  {\n    var pc = new RTCPeerConnection\n    (\n      {iceServers: iceServers},\n      {optional: [{DtlsSrtpKeyAgreement: true}]}\n    );\n\n    pc.addEventListener('icecandidate', function(event)\n    {\n      // There's a candidate, ignore it\n      if(event.candidate) return;\n\n      // There's no candidate, send the full SDP\n      var type = this.localDescription.type;\n      var sdp  = this.localDescription.sdp;\n\n      if(type == callbackType)\n        callback(sdp)\n      else\n        console.error(type+\" SDP type is not equal to \"+callbackType+\" callback type\");\n    });\n\n    pc.addEventListener('signalingstatechange', function(event)\n    {\n      // Add PeerConnection object to available ones when gets open\n      if(pc.signalingState == 'stable')\n      {\n        var channels = pc._channels || [];\n\n        peersManager.add(sessionID, pc, channels);\n\n        var offer = offers[sessionID];\n        if(offer)\n        {\n          delete offers[sessionID];\n\n          offer.callback(null, pc, channels);\n        };\n\n        self.emit('peerconnection', pc, channels);\n      };\n    });\n\n    // Set ID of the PeerConnection\n    Object.defineProperty(pc, \"sessionID\", {value : sessionID});\n\n    return pc;\n  };\n\n\n  //\n  // Connection methods\n  //\n\n  /**\n   * Callback to send the offer. If not defined send it to all connected peers.\n   *\n   * @callback WebP2P~ConnectToCallback\n   * @param {Error} error\n   * @param {RTCPeerConnection} peer - The (newly created) peer\n   */\n\n  /**\n   * Connects to another peer based on its UID. If we are already connected,\n   * it does nothing.\n   *\n   * @param {UUID} sessionID - Identifier of the other peer to be connected.\n   * @param {string[]} [labels] - Per-connection labels\n   * @param {WebP2P~ConnectToCallback} callback\n   */\n  this.connectTo = function(dest, labels, callback)\n  {\n    if(labels instanceof Function)\n    {\n      if(callback)\n        throw new SyntaxError(\"Nothing can be defined after the callback\");\n\n      callback = labels;\n      labels = undefined;\n    };\n\n    // Don't connect to ourself\n    if(dest == self.sessionID)\n      return callback(new Error(\"Connecting to ourself\"));\n\n    // Check if we are already connected to the requested peer\n    var pc = peersManager.get(dest);\n    if(pc)\n    {\n      // We are already connected to that peer, ignore the request\n      var message = \"[\"+self.sessionID+\"] Already connected to \"+dest;\n      console.log(message);\n\n      // [ToDo] AddChannels(pc, labels);\n\n      var channels = pc._channels || [];\n\n      callback(null, pc, channels);\n\n      return;\n    };\n\n    // Check if we are already trying to connect to that peer\n    var offer = offers[dest];\n    if(offer)\n    {\n      // We are already trying to connect to that peer, ignore the request\n      var message = \"[\"+self.sessionID+\"] Already requested connection to \"+dest;\n      console.log(message);\n\n      var pc = offer.peerConnection;\n\n      // [ToDo] AddChannels(pc, labels);\n\n      pc.addEventListener('signalingstatechange', function(event)\n      {\n        if(pc.signalingState == 'stable')\n        {\n          var channels = pc._channels || [];\n\n          callback(null, pc, channels);\n        }\n      });\n\n      return;\n    };\n\n    // Request to connect to a new peer, generate the offer\n    generateOffer(dest, [handshakeManager, peersManager], labels, callback);\n  };\n\n\n  //\n  // Managers\n  //\n\n  function forward(message, connector)\n  {\n    var from = message.from;\n    var dest = message.dest;\n\n    // Message was for us, raise error\n    if(dest == self.sessionID)\n      return console.error('Ignored message send to us', message);\n\n    // Don't forward the message if TTL has been achieved\n    if(--message.ttl <= 0)\n      return console.warn(\"TTL achieved:\",message);\n\n    var dest = message.dest;\n\n    message = message.pack();\n\n    // Search the peer between the ones currently connected so we can send the\n    // message directly to it\n    for(var i=0, peer; peer=peersManager._connectors[i]; i++)\n      if(peer.sessionID == dest)\n        return peer.send(message);\n\n    // Peer was not found, forward message to all the connectors except the one\n    // where we received it\n    peersManager.send(message, connector);\n    handshakeManager.send(message, connector);\n  };\n\n\n  handshakeManager.on('connected', function()\n  {\n    self.emit('handshakeManager.connected', handshakeManager);\n  });\n  handshakeManager.on('disconnected', function()\n  {\n    self.emit('handshakeManager.disconnected', handshakeManager);\n  });\n\n  peersManager.on('connected', function()\n  {\n    self.emit('peersManager.connected', peersManager);\n  });\n  peersManager.on('disconnected', function()\n  {\n    self.emit('peersManager.disconnected', peersManager);\n  });\n\n\n  /**\n   * Check if it's a request from a peer we are already connected or trying to\n   * connect to, so we can prevent to do crossed connections\n   *\n   * @param from - ID of the other peer\n   *\n   * @returns {Boolean} - If we are already connected or trying to connect\n   */\n  function connectionProcessed(from)\n  {\n    // Check if we are already connected to the requester peer\n    var peer = peersManager.get(from);\n    if(peer)\n    {\n      // [ToDo] AddChannels(peer, labels);\n\n      // We are already connected to that peer, send an error to the other end\n      var message = \"[\"+self.sessionID+\"] Already connected to \"+from;\n      console.log(message);\n\n      var error =\n      {\n        code: -1,\n        message: message,\n        ttl: MAX_TTL_DEFAULT\n      };\n      return error;\n    };\n\n    // Check if we are already trying to connect to that peer\n    var offer = offers[from];\n    if(offer)\n    {\n      // [ToDo] AddChannels(offer.peerConnection, labels);\n\n      // We are already trying to connect to that peer, ignore the request\n      var message = \"[\"+self.sessionID+\"] Already requested connection to \"+from;\n      console.log(message);\n\n      // We have higher precedence, send an error to the other end\n      if(self.sessionID < from)\n      {\n        console.log(\"[\"+self.sessionID+\"] Higher precedence than \"+from+\", sending error\");\n\n        var error =\n        {\n          code: -2,\n          message: message,\n          ttl: MAX_TTL_DEFAULT\n        };\n        return error;\n      }\n\n      // We have less precedence, cancel our connection request and prepare to use the\n      // incoming one with the previous callback\n      delete offers[from];\n\n      rpcBuilder.cancel(offer.message);\n      offer.peerConnection.close();\n\n      console.debug(\"[\"+self.sessionID+\"] Lower precedence than \"+from+\", request canceled\");\n\n      return offer.callback;\n    };\n\n    // Connection request is a genuinely new one, process it as usual\n  };\n\n\n    //\n    // Protocol messages\n    //\n\n  function onpresence(from, connector)\n  {\n    // Check if we are already connected to the new peer\n    var peer = peersManager.get(from);\n    if(peer) return;\n\n    // Check if we are already trying to connect to the new peer\n    var offer = offers[from];\n    if(offer) return;\n\n    var pc = generateOffer(from, connector);\n\n    pc.addEventListener('signalingstatechange', function(event)\n    {\n      // If PeerConnection object gets open, increase number of connections\n      // fetch over this connector so it can decide if it could close\n      if(pc.signalingState == 'stable')\n        connector.increaseConnections();\n    });\n  };\n\n  function onoffer(request, connector)\n  {\n    var from = request.from;\n    var dest = request.dest;\n\n    // Message is for us\n    if(dest == self.sessionID)\n    {\n      console.log(\"[\"+dest+\"] Received connection request from \"+from);\n\n      // If connection is already processed, send an error to the other end\n      var processed = connectionProcessed(from);\n      if(processed && processed.code)\n        return request.reply(processed);\n\n      // Search the peer between the list of currently connected ones,\n      // or create it if it's not connected\n      var pc = createPeerConnection(from, \"answer\", function(answer)\n      {\n        var response =\n        {\n          sdp: answer,\n          ttl: MAX_TTL_DEFAULT\n        };\n\n        // Send back the connection request over the same connector, since\n        // this should be the shortest path to connect both peers\n        request.reply(null, response);\n      });\n\n      // Process offer & generate answer\n      pc.setRemoteDescription(new RTCSessionDescription(\n      {\n        sdp:  request.sdp,\n        type: 'offer'\n      }),\n      function()\n      {\n        pc.createAnswer(function(answer)\n        {\n          pc.setLocalDescription(answer, null, onerror);\n        },\n        onerror)\n      },\n      onerror);\n\n      if(processed)\n        pc.addEventListener('signalingstatechange', function(event)\n        {\n          if(pc.signalingState == 'stable')\n          {\n            var channels = pc._channels || [];\n\n            processed(null, pc, channels);\n          }\n        });\n\n      pc.addEventListener('datachannel', function(event)\n      {\n        var channel = event.channel;\n\n        var channels = pc._channels || [];\n\n        channels.push(channel);\n\n        pc._channels = channels;\n      });\n    }\n\n    // Forward message\n    else\n      forward(request, connector);\n  };\n\n\n  function generateOffer(dest, connector, labels, callback)\n  {\n    var pc = createPeerConnection(dest, \"offer\", function(offer)\n    {\n      var message =\n      {\n        sdp: offer,\n        ttl: callback ? MAX_TTL_DEFAULT : 1\n      };\n\n      callback = callback || noop;\n\n      var request = rpcBuilder.encode('offer', message, dest,\n      function(error, result)\n      {\n        if(error) return callback(error);\n\n        processAnswer(result);\n      });\n\n      offers[dest] =\n      {\n        callback: callback,\n        message: request,\n        peerConnection: pc\n      };\n\n      if(connector instanceof Array)\n        connector.forEach(function(c)\n        {\n          c.send(request);\n        });\n\n      // Send back the connection request over the same connector, since this\n      // should be the shortest path to connect both peers\n      else\n        connector.send(request);\n    });\n\n    //\n    // Init PeerConnection\n    //\n\n    // Set channels for this PeerConnection object\n    labels = [self.routingLabel].concat(commonLabels, labels);\n\n    var channels = pc._channels = [];\n\n    for(var i=0, label; label=labels[i]; i++)\n    {\n      var channel = pc.createDataChannel(label);\n\n      channels.push(channel);\n\n      channel.addEventListener('close', function(event)\n      {\n        channels.splice(channels.indexOf(channel), 1);\n      });\n    };\n\n    // Send offer\n    var mediaConstraints =\n    {\n      mandatory:\n      {\n        OfferToReceiveAudio: false,\n        OfferToReceiveVideo: false\n      }\n    };\n\n    pc.createOffer(function(offer)\n    {\n      pc.setLocalDescription(offer, null, onerror);\n    },\n    onerror,\n    mediaConstraints);\n\n    return pc;\n  };\n\n  function processAnswer(response)\n  {\n    var from = response.from;\n\n    console.debug('['+self.sessionID+'] Received answer from '+from);\n\n    var offer = offers[from];\n    if(offer)\n      offer.peerConnection.setRemoteDescription(new RTCSessionDescription(\n      {\n        sdp:  response.sdp,\n        type: 'answer'\n      }),\n      null, onerror);\n    else\n      console.warn(\"[\"+self.sessionID+\"] Connection with peer '\" + from + \"' was not previously requested\");\n  };\n\n\n    //\n    // Manager events\n    //\n\n  function initManagerEvents(manager)\n  {\n    manager.on('connected', function()\n    {\n      if(handshakeManager.status != peersManager.status)\n        self.emit('connected');\n    });\n    manager.on('disconnected', function()\n    {\n      if(handshakeManager.status == peersManager.status)\n        self.emit('disconnected');\n    });\n//    manager.on('error', onerror);\n\n    manager.on('offer',  onoffer);\n    manager.on('answer', forward);\n    manager.on('error',  forward);\n  };\n\n  // Init managers events\n\n  initManagerEvents(handshakeManager);\n  initManagerEvents(peersManager);\n\n  handshakeManager.on('presence', onpresence);\n\n\n  //\n  // Clossing functions\n  //\n\n  this.close = function()\n  {\n    handshakeManager.close();\n    peersManager.close();\n\n    rpcBuilder.close();\n  };\n\n  // Close all connections when user goes out of the page or app is clossed\n  process.on('exit', function(code)\n  {\n    self.close();\n  });\n};\ninherits(WebP2P, EventEmitter);\n\n\nmodule.exports = WebP2P;\n","// shim for using process in browser\n\nvar process = module.exports = {};\n\nprocess.nextTick = (function () {\n    var canSetImmediate = typeof window !== 'undefined'\n    && window.setImmediate;\n    var canPost = typeof window !== 'undefined'\n    && window.postMessage && window.addEventListener\n    ;\n\n    if (canSetImmediate) {\n        return function (f) { return window.setImmediate(f) };\n    }\n\n    if (canPost) {\n        var queue = [];\n        window.addEventListener('message', function (ev) {\n            var source = ev.source;\n            if ((source === window || source === null) && ev.data === 'process-tick') {\n                ev.stopPropagation();\n                if (queue.length > 0) {\n                    var fn = queue.shift();\n                    fn();\n                }\n            }\n        }, true);\n\n        return function nextTick(fn) {\n            queue.push(fn);\n            window.postMessage('process-tick', '*');\n        };\n    }\n\n    return function nextTick(fn) {\n        setTimeout(fn, 0);\n    };\n})();\n\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n}\n\n// TODO(shtylman)\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\n","var inherits = require('inherits');\n\nvar Manager = require('./Manager');\n\nvar errors = require('../errors');\n\n\nvar Connector_PubNub = require('../connectors/PubNub');\nvar Connector_xRTML  = require('../connectors/xRTML');\n\n\n/**\n * Manage the handshake connectors using several servers\n *\n * @constructor\n * @param {String} json_uri URI of the handshake servers configuration.\n */\nfunction HandshakeManager(rpcBuilder, handshake_servers)\n{\n  Manager.call(this, rpcBuilder);\n\n  var self = this;\n\n\n  var handshakeConnectorConstructors = {};\n\n  this.registerConnectorConstructor = function(type, constructor)\n  {\n    handshakeConnectorConstructors[type] = constructor\n  };\n\n\n  // Default handshake connectors\n  this.registerConnectorConstructor('PubNub', Connector_PubNub);\n  this.registerConnectorConstructor('xRTML',  Connector_xRTML);\n\n\n  function createConnector(config)\n  {\n    var type            = config.type;\n    var config_init     = config.config_init;\n    var config_mess     = config.config_mess;\n    var max_connections = config.max_connections;\n\n    // Check if connector constructor is from a valid handshake server\n    var connectorConstructor = handshakeConnectorConstructors[type];\n    if(!connectorConstructor)\n      throw Error(\"Invalid handshake server type '\" + type + \"'\");\n\n    var connector = new connectorConstructor(config_init, config_mess, max_connections);\n\n    self._initConnector(connector);\n\n    connector.on('open', function()\n    {\n      // Notify our presence to the other peers\n      connector.send(rpcBuilder.encode('presence'));\n    });\n\n    var _messageUnpacked = connector._messageUnpacked;\n    connector._messageUnpacked = function(message)\n    {\n      if(message.method == 'presence')\n      {\n        if(connector.shouldConnect())\n          self.emit(\"presence\", message.params.from, connector);\n      }\n      else\n        _messageUnpacked.call(connector, message);\n    };\n\n    return connector;\n  };\n\n\n  var configs = [];\n  var index = 0;\n\n  var configs_infinity = [];\n\n  /**\n   * Get a random handshake connector or test for the next one\n   * @param {Object} configuration Handshake servers configuration.\n   */\n  function handshake()\n  {\n    if(!configs.length)\n      throw Error('No handshake servers defined')\n\n    for(; index < configs.length; index++)\n    {\n      var connector = createConnector(configs[index]);\n          connector.on('close', function()\n      {\n        // Handshake connector has been closed, try to get an alternative one\n        index++;\n        handshake();\n      });\n\n      // Connector successfully created\n      return;\n    };\n\n    // All configured handshake servers has been consumed\n    // Get ready to start again from beginning of handshake servers list\n    index = 0;\n  };\n\n\n  this.addConfigs_byObject = function(config)\n  {\n    // Check if connector constructor is from a valid handshake server\n    var connectorConstructor = handshakeConnectorConstructors[config.type];\n    if(!connectorConstructor)\n      return console.error(\"Invalid handshake server config: \", config);\n\n    if(connectorConstructor.prototype.max_connections == Number.POSITIVE_INFINITY\n    && !config.max_connections)\n    {\n      configs_infinity.push(config)\n\n      // Start handshaking\n      createConnector(config);\n    }\n    else\n    {\n      configs.push(config);\n\n      // Start handshaking\n      if(self.status == 'disconnected')\n        handshake();\n    }\n  };\n\n\n  // Add handshake servers configuration\n  if(handshake_servers)\n    this.addConfigs(handshake_servers)\n};\ninherits(HandshakeManager, Manager);\n\n\nHandshakeManager.prototype.addConfigs = function(configuration)\n{\n  if(typeof configuration == 'string')\n    return this.addConfigs_byUri(configuration);\n\n  if(configuration instanceof Array)\n    return this.addConfigs_byArray(configuration);\n\n  this.addConfigs_byObject(configuration);\n};\n\nHandshakeManager.prototype.addConfigs_byArray = function(configuration)\n{\n  for(var i=0, config; config=configuration[i]; i++)\n    this.addConfigs_byObject(config);\n};\n\nHandshakeManager.prototype.addConfigs_byUri = function(json_uri)\n{\n  var self = this;\n\n  function dispatchError(error)\n  {\n    self.emit('error', error);\n  };\n\n  // Request the handshake servers configuration file\n  var http_request = new XMLHttpRequest();\n\n  http_request.open('GET', json_uri);\n  http_request.onload = function(event)\n  {\n    if(this.status == 200)\n    {\n      var configuration = JSON.parse(http_request.response);\n\n      // We got some config entries\n      if(configuration.length)\n        self.addConfigs_byArray(configuration)\n\n      // Config was empty\n      else\n        dispatchError(errors.ERROR_REQUEST_EMPTY)\n    }\n\n    // Request returned an error\n    else\n      dispatchError(errors.ERROR_REQUEST_FAILURE)\n  };\n\n  // Connection error\n  http_request.onerror = function(event)\n  {\n    dispatchError(navigator.onLine ? errors.ERROR_NETWORK_UNKNOWN\n                                   : errors.ERROR_NETWORK_OFFLINE)\n  };\n\n  http_request.send();\n};\n\n\nmodule.exports = HandshakeManager;\n","var inherits = require('inherits');\n\nvar Manager = require('./Manager');\n\nvar Connector_DataChannel = require('../connectors/core/DataChannel');\n\n\n/**\n * @classdesc Manager of the communications with the other peers\n *\n * @constructor\n */\nfunction PeersManager(rpcBuilder, routingLabel)\n{\n  Manager.call(this, rpcBuilder);\n\n  var self = this;\n\n\n  function createConnector(channel)\n  {\n    var connector = new Connector_DataChannel(channel);\n\n    self._initConnector(connector);\n\n    return connector;\n  };\n\n\n  var peers = {};\n\n  this.__defineGetter__(\"peers\", function()\n  {\n    return peers;\n  });\n\n\n  function initDataChannel(channel, sessionID)\n  {\n    if(channel.label == routingLabel)\n    {\n      var connector = createConnector(channel);\n          connector.sessionID = sessionID;\n\n      return connector;\n    };\n  };\n\n  this.add = function(sessionID, peerConnection, channels)\n  {\n    peerConnection.addEventListener('signalingstatechange', function(event)\n    {\n      // Remove the peer from the list of peers when gets closed\n      if(peerConnection.signalingState == 'closed')\n        delete peers[sessionID];\n    });\n\n    // Connection initiator\n    if(channels.length)\n    {\n      // Only init the routing functionality on the routing channel\n      for(var i=0, channel; channel=channels[i]; i++)\n        if(initDataChannel(channel, sessionID))\n          break;\n    }\n\n    // Connection receiver\n    else\n    {\n      function initDataChannel_listener(event)\n      {\n        var channel = event.channel;\n\n        var connector = initDataChannel(channel, sessionID);\n        if(connector)\n          event.target.removeEventListener('datachannel', initDataChannel_listener);\n      };\n\n      peerConnection.addEventListener('datachannel', initDataChannel_listener);\n    };\n\n    // Add PeerConnection to the list of enabled ones\n    peers[sessionID] = peerConnection;\n  };\n\n  this.get = function(sessionID)\n  {\n    return peers[sessionID];\n  };\n\n  var _close = this.close;\n  this.close = function()\n  {\n    for(var id in peers)\n      peers[id].close();\n\n    _close.call(this);\n  };\n};\ninherits(PeersManager, Manager);\n\n\nmodule.exports = PeersManager;\n","const ERROR    = 0;\nconst PRESENCE = 1;\nconst OFFER    = 2;\nconst ANSWER   = 3;\n\n\nfunction pack(message, id)\n{\n  var result = new Array(6);\n  var params = message.params || {};\n\n  // Method\n  var method = message.method;\n  switch(method)\n  {\n    case \"error\":\n      result[0] = ERROR;\n    break;\n\n    case \"presence\":\n      result[0] = PRESENCE;\n    break;\n\n    case \"offer\":\n      result[0] = OFFER;\n    break;\n\n    case \"answer\":\n      result[0] = ANSWER;\n    break;\n\n    default:\n    {\n      var error = new Error(\"Unknown message method '\"+method+\"'\");\n          error.message = message;\n\n      throw error;\n    };\n  };\n\n  // From\n  result[1] = params.from;\n\n  // Offer & Answer\n\n  if(method != 'presence')\n  {\n    result[2] = params.dest;\n    result[3] = id;\n    result[4] = params.ttl;\n    result[5] = params.sdp || params.message;\n  };\n\n  return JSON.stringify(result);\n};\n\nfunction unpack(message)\n{\n  var result = {};\n  var params = {};\n\n  message = JSON.parse(message);\n\n  // Method\n  var method = message[0];\n  switch(method)\n  {\n    case ERROR:\n      result.method = \"error\";\n    break;\n\n    case PRESENCE:\n      result.method = \"presence\";\n    break;\n\n    case OFFER:\n      result.method = \"offer\";\n    break;\n\n    case ANSWER:\n      result.method = \"answer\";\n    break;\n\n    default:\n    {\n      var error = new Error(\"Unknown message method '\"+method+\"'\");\n          error.message = message;\n\n      throw error;\n    };\n  };\n\n  // From\n  params.from = message[1];\n\n  // Offer & Answer\n\n  if(method != PRESENCE)\n  {\n    params.dest = message[2];\n\n    if(method == ERROR || method == ANSWER)\n      result.ack = message[3];\n    else\n      result.id = message[3];\n\n    params.ttl  = message[4];\n\n    if(method == ERROR)\n      params.message = message[5];\n    else\n      params.sdp = message[5];\n  };\n\n  // Return unpacked message\n  result.params = params;\n\n  return result;\n};\n\n\nvar responseMethods =\n{\n  'presence': 'offer',\n\n  'offer':\n  {\n    error:    'error',\n    response: 'answer'\n  }\n};\n\n\nexports.pack   = pack;\nexports.unpack = unpack;\n\nexports.responseMethods = responseMethods;\n","var inherits = require(\"inherits\");\n\nvar EventEmitter = require(\"events\").EventEmitter;\n\n\nfunction Connector()\n{\n  EventEmitter.call(this);\n\n  var self = this;\n\n\n  /**\n   * Notify that the connection to this handshake server is open\n   */\n  this._open = function()\n  {\n    self.emit('open');\n  };\n\n  this._message = function(message)\n  {\n    self.emit(\"message\", message);\n  };\n\n  this._close = function()\n  {\n    self.emit('close');\n  };\n\n  this._error = function(error)\n  {\n    self.emit('error', error);\n  };\n};\ninherits(Connector, EventEmitter);\n\n\nConnector.prototype.close = function()\n{\n  throw new TypeError(\"Connector.close should be defined in a child class\");\n};\nConnector.prototype.send = function(message)\n{\n  throw new TypeError(\"Connector.send should be defined in a child class\");\n};\n\n\nmodule.exports = Connector;\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      } else {\n        throw TypeError('Uncaught, unspecified \"error\" event.');\n      }\n      return false;\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        len = arguments.length;\n        args = new Array(len - 1);\n        for (i = 1; i < len; i++)\n          args[i - 1] = arguments[i];\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    len = arguments.length;\n    args = new Array(len - 1);\n    for (i = 1; i < len; i++)\n      args[i - 1] = arguments[i];\n\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    var m;\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  var ret;\n  if (!emitter._events || !emitter._events[type])\n    ret = 0;\n  else if (isFunction(emitter._events[type]))\n    ret = 1;\n  else\n    ret = emitter._events[type].length;\n  return ret;\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n","var EventEmitter = require(\"events\").EventEmitter;\n\nvar inherits = require('inherits');\n\n\nfunction Manager(rpcBuilder)\n{\n  EventEmitter.call(this);\n\n  var self = this;\n\n\n  this._connectors = [];\n\n  this.__defineGetter__(\"status\", function()\n  {\n    return this._connectors.length ? 'connected' : 'disconnected';\n  });\n\n\n  this._initConnector = function(connector)\n  {\n    connector.on('open', function()\n    {\n//      for(var i=0, conn; conn=self._connectors[i]; i++)\n//        if(conn===connector)\n//          console.error('Duplicate connector',connector);\n\n      self._connectors.push(connector);\n\n      if(self._connectors.length == 1)\n         self.emit('connected');\n    });\n    connector.on('close', function()\n    {\n      self._connectors.splice(self._connectors.indexOf(connector), 1);\n\n      if(self._connectors.length == 0)\n         self.emit('disconnected');\n    });\n    connector.on('error', function(error)\n    {\n      connector.close();\n\n      self.emit('error', error);\n    });\n\n    connector._messageUnpacked = function(message)\n    {\n      var method = message.method;\n      var params = message.params;\n\n      switch(method)\n      {\n        case 'offer':\n          params.reply = function(error, result)\n          {\n            return message.reply(error, result, connector);\n          };\n\n        case 'answer':\n        case 'error':\n          params.pack = function()\n          {\n            return message.pack();\n          };\n\n          self.emit(method, params, connector);\n        break;\n\n        default:\n          // This should never be reached\n          console.error(\"Unknown message method '\"+method+\"'\", message);\n      };\n    };\n\n    connector.on('message', function(message)\n    {\n      message = rpcBuilder.decode(message);\n      if(message)\n      {\n        // Response was previously stored, send it directly\n        if(message.stored)\n          connector.send(message)\n\n        // Normal message, process it\n        else\n          connector._messageUnpacked(message);\n      };\n    });\n  };\n};\ninherits(Manager, EventEmitter);\n\n\n/**\n * Close all the connections\n */\nManager.prototype.close = function()\n{\n  for(var i=0, connector; connector=this._connectors[i]; i++)\n    connector.close();\n};\n\n/**\n * {Object} message - Message to be send\n * {Connector} [incomingConnector] - {Connector} to don't send the message\n */\nManager.prototype.send = function(message, incomingConnector)\n{\n  for(var i=0, connector; connector=this._connectors[i]; i++)\n  {\n    // Don't send the message to the same connector where we received it\n    if(connector === incomingConnector)\n      continue;\n\n    connector.send(message);\n  };\n};\n\n\nmodule.exports = Manager;\n","const ERROR_NETWORK_UNKNOWN = {id: 0, msg: 'Unable to fetch handshake servers configuration'};\nconst ERROR_NETWORK_OFFLINE = {id: 1, msg: \"There's no available network\"};\nconst ERROR_REQUEST_FAILURE = {id: 2, msg: 'Unable to fetch handshake servers configuration'};\nconst ERROR_REQUEST_EMPTY   = {id: 3, msg: 'Handshake servers configuration is empty'};\n\nconst ERROR_NO_PEERS        = {id: 4, msg: 'Not connected to any peer'};\n\n\nexports.ERROR_NETWORK_UNKNOWN = ERROR_NETWORK_UNKNOWN;\nexports.ERROR_NETWORK_OFFLINE = ERROR_NETWORK_OFFLINE;\nexports.ERROR_REQUEST_FAILURE = ERROR_REQUEST_FAILURE;\nexports.ERROR_REQUEST_EMPTY   = ERROR_REQUEST_EMPTY;\nexports.ERROR_NO_PEERS        = ERROR_NO_PEERS;","var inherits = require(\"inherits\");\n\nvar HandshakeConnector = require(\"./core/HandshakeConnector\");\n\nvar PUBNUB = require(\"pubnub\");\n\n\n/**\n * Handshake connector for PubNub\n * @param {Object} configuration Configuration object.\n */\nfunction Connector_PubNub(config_init, config_mess, max_connections)\n{\n  HandshakeConnector.call(this, max_connections);\n\n  var self = this;\n\n  var channel = config_mess.channel;\n\n\n  // Connect a handshake connector to the PubNub server\n  var pubnub = PUBNUB.init(config_init);\n\n  // Configure handshake connector\n  pubnub.subscribe(\n  {\n    channel: channel,\n    restore: false,\n    backfill: false,\n\n    connect:    self._open,\n    message:    self._message,\n    disconnect: self._close,\n\n    error: function(response)\n    {\n      self._error(new Error(response ? response.error : 'Undefined error'))\n    }\n  });\n\n\n  // Define methods\n\n  /**\n   * Close the connection with this handshake server\n   */\n  this.close = function()\n  {\n    pubnub.unsubscribe(\n    {\n      channel: channel\n    });\n\n    // This shouldn't be necesary, but seems 'disconnect' event is not being\n    // dispatched by the PubNub channel, so we close the connector explicitly\n    self._close();\n  }\n\n  /**\n   * Send the message\n   */\n  this.send = function(message)\n  {\n    pubnub.publish(\n    {\n      channel: channel,\n      message: message\n    });\n  };\n}\ninherits(Connector_PubNub, HandshakeConnector);\n\n\n// Class constants\nConnector_PubNub.prototype.max_connections = 50;\nObject.defineProperty(Connector_PubNub.prototype, 'max_chars', {value: 1800});\n\n\nmodule.exports = Connector_PubNub;\n","var inherits = require('inherits');\n\nvar HandshakeConnector = require(\"./core/HandshakeConnector\");\n\nvar ortcNodeclient = require('ibtrealtimesjnode').IbtRealTimeSJNode;\n\n\n/**\n * Handshake connector for xRTML\n * @param {Object} configuration Configuration object\n */\nfunction Connector_xRTML(config_init, config_mess, max_connections)\n{\n  HandshakeConnector.call(this, max_connections);\n\n  var self = this;\n\n  var channel = config_mess.channel;\n\n  // Create ORTC client\n  var ortcClient = new ortcNodeclient();\n\n  ortcClient.setClusterUrl('http://ortc-developers.realtime.co/server/2.1/');\n\n  ortcClient.onConnected = function(ortc)\n  {\n    ortcClient.subscribe(channel, true, function(ortc, channel, message)\n    {\n      self._message(message);\n    });\n  };\n\n  ortcClient.onSubscribed   = this._open.bind(this);\n  ortcClient.onUnsubscribed = this._close.bind(this);\n\n  ortcClient.onException = function(ortc, exception)\n  {\n    self._error(exception);\n  };\n\n  // Connect a handshake connector to the xRTML server\n  ortcClient.connect(config_init.application_key, config_init.authentication_token);\n\n\n  // Define methods\n\n  /**\n   * Close the connection with this handshake server\n   */\n  this.close = function()\n  {\n    ortcClient.unsubscribe(channel);\n  };\n\n  /**\n   * Send the message\n   */\n  this.send = function(message)\n  {\n    ortcClient.send(channel, message);\n  };\n}\ninherits(Connector_xRTML, HandshakeConnector);\n\n\nmodule.exports = Connector_xRTML;\n","var inherits = require(\"inherits\");\n\nvar Connector = require(\"./Connector\");\n\n\nfunction Connector_DataChannel(datachannel)\n{\n  Connector.call(this);\n\n  var self = this;\n\n\n  datachannel.addEventListener('open',  self._open);\n  datachannel.addEventListener('message', function(event)\n  {\n    self._message(event.data);\n  });\n  datachannel.addEventListener('close', self._close);\n  datachannel.addEventListener('error', self._error);\n\n\n  // Define methods\n\n  /**\n   * Close the connection with the peer\n   */\n  this.close = function()\n  {\n    datachannel.close();\n  };\n\n  /**\n   * Send the message\n   */\n  this.send = function(message)\n  {\n    datachannel.send(message);\n  };\n};\ninherits(Connector_DataChannel, Connector);\n\n\nmodule.exports = Connector_DataChannel;\n","if (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n","/* jshint node: true */\n'use strict';\n\n/**\n  # freeice\n\n  The `freeice` module is a simple way of getting random STUN or TURN server\n  for your WebRTC application.  The list of servers (just STUN at this stage)\n  were sourced from this [gist](https://gist.github.com/zziuni/3741933).\n\n  ## Example Use\n\n  The following demonstrates how you can use `freeice` with\n  [rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect):\n\n  <<< examples/quickconnect.js\n\n  As the `freeice` module generates ice servers in a list compliant with the\n  WebRTC spec you will be able to use it with raw `RTCPeerConnection`\n  constructors and other WebRTC libraries. \n\n  ## Hey, don't use my STUN/TURN server!\n\n  If for some reason your free STUN or TURN server ends up in the\n  [list](servers.js) of servers that is used in this module, you can feel\n  free to open an issue on this repository and those servers will be removed\n  within 24 hours (or sooner).  This is the quickest and probably the most\n  polite way to have something removed (and provides us some visibility\n  if someone opens a pull request requesting that a server is added).\n\n  ## Please add my server!\n\n  If you have a server that you wish to add to the list, that's awesome! I'm\n  sure I speak on behalf of a whole pile of WebRTC developers who say thanks.\n  To get it into the list, feel free to either open a pull request or if you\n  find that process a bit daunting then just create an issue requesting\n  the addition of the server (make sure you provide all the details, and if\n  you have a Terms of Service then including that in the PR/issue would be\n  awesome).\n\n  ## I know of a free server, can I add it?\n\n  Sure, if you do your homework and make sure it is ok to use (I'm currently\n  in the process of reviewing the terms of those STUN servers included from\n  the original list).  If it's ok to go, then please see the previous entry\n  for how to add it.\n\n  ## Current List of Servers\n\n  * current as at the time of last `README.md` file generation\n\n  <<< servers.js\n\n**/\n\nvar freeice = module.exports = function(opts) {\n  // if a list of servers has been provided, then use it instead of defaults\n  var servers = (opts || {}).servers || require('./servers');\n\n  var stunCount = (opts || {}).stun || 2;\n  var turnCount = (opts || {}).turn || 0;\n  var selected;\n\n  function getServers(type, count) {\n    var out = [];\n    var input = [].concat(servers[type]);\n    var idx;\n\n    while (input.length && out.length < count) {\n      idx = (Math.random() * input.length) | 0;\n      out = out.concat(input.splice(idx, 1));\n    }\n\n    return out.map(function(url) {\n      return { url: type + ':' + url };\n    });\n  }\n\n  // add stun servers\n  selected = [].concat(getServers('stun', stunCount));\n\n  if (turnCount) {\n    selected = selected.concat(getServers('turn', turnCount));\n  }\n\n  return selected;\n};","//     uuid.js\n//\n//     Copyright (c) 2010-2012 Robert Kieffer\n//     MIT License - http://opensource.org/licenses/mit-license.php\n\n// Unique ID creation requires a high quality random # generator.  We feature\n// detect to determine the best RNG source, normalizing to a function that\n// returns 128-bits of randomness, since that's what's usually required\nvar _rng = require('./rng');\n\n// Buffer class to use\nvar BufferClass = typeof(Buffer) == 'function' ? Buffer : Array;\n\n// Maps for number <-> hex string conversion\nvar _byteToHex = [];\nvar _hexToByte = {};\nfor (var i = 0; i < 256; i++) {\n  _byteToHex[i] = (i + 0x100).toString(16).substr(1);\n  _hexToByte[_byteToHex[i]] = i;\n}\n\n// **`parse()` - Parse a UUID into it's component bytes**\nfunction parse(s, buf, offset) {\n  var i = (buf && offset) || 0, ii = 0;\n\n  buf = buf || [];\n  s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {\n    if (ii < 16) { // Don't overflow!\n      buf[i + ii++] = _hexToByte[oct];\n    }\n  });\n\n  // Zero out remaining bytes if string was short\n  while (ii < 16) {\n    buf[i + ii++] = 0;\n  }\n\n  return buf;\n}\n\n// **`unparse()` - Convert UUID byte array (ala parse()) into a string**\nfunction unparse(buf, offset) {\n  var i = offset || 0, bth = _byteToHex;\n  return  bth[buf[i++]] + bth[buf[i++]] +\n          bth[buf[i++]] + bth[buf[i++]] + '-' +\n          bth[buf[i++]] + bth[buf[i++]] + '-' +\n          bth[buf[i++]] + bth[buf[i++]] + '-' +\n          bth[buf[i++]] + bth[buf[i++]] + '-' +\n          bth[buf[i++]] + bth[buf[i++]] +\n          bth[buf[i++]] + bth[buf[i++]] +\n          bth[buf[i++]] + bth[buf[i++]];\n}\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\n\n// random #'s we need to init node and clockseq\nvar _seedBytes = _rng();\n\n// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\nvar _nodeId = [\n  _seedBytes[0] | 0x01,\n  _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]\n];\n\n// Per 4.2.2, randomize (14 bit) clockseq\nvar _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;\n\n// Previous uuid creation time\nvar _lastMSecs = 0, _lastNSecs = 0;\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v1(options, buf, offset) {\n  var i = buf && offset || 0;\n  var b = buf || [];\n\n  options = options || {};\n\n  var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;\n\n  // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n  // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so\n  // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n  // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n  var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();\n\n  // Per 4.2.1.2, use count of uuid's generated during the current clock\n  // cycle to simulate higher resolution clock\n  var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;\n\n  // Time since last uuid creation (in msecs)\n  var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n  // Per 4.2.1.2, Bump clockseq on clock regression\n  if (dt < 0 && options.clockseq === undefined) {\n    clockseq = clockseq + 1 & 0x3fff;\n  }\n\n  // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n  // time interval\n  if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n    nsecs = 0;\n  }\n\n  // Per 4.2.1.2 Throw error if too many uuids are requested\n  if (nsecs >= 10000) {\n    throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n  }\n\n  _lastMSecs = msecs;\n  _lastNSecs = nsecs;\n  _clockseq = clockseq;\n\n  // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n  msecs += 12219292800000;\n\n  // `time_low`\n  var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n  b[i++] = tl >>> 24 & 0xff;\n  b[i++] = tl >>> 16 & 0xff;\n  b[i++] = tl >>> 8 & 0xff;\n  b[i++] = tl & 0xff;\n\n  // `time_mid`\n  var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n  b[i++] = tmh >>> 8 & 0xff;\n  b[i++] = tmh & 0xff;\n\n  // `time_high_and_version`\n  b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n  b[i++] = tmh >>> 16 & 0xff;\n\n  // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n  b[i++] = clockseq >>> 8 | 0x80;\n\n  // `clock_seq_low`\n  b[i++] = clockseq & 0xff;\n\n  // `node`\n  var node = options.node || _nodeId;\n  for (var n = 0; n < 6; n++) {\n    b[i + n] = node[n];\n  }\n\n  return buf ? buf : unparse(b);\n}\n\n// **`v4()` - Generate random UUID**\n\n// See https://github.com/broofa/node-uuid for API details\nfunction v4(options, buf, offset) {\n  // Deprecated - 'format' argument, as supported in v1.2\n  var i = buf && offset || 0;\n\n  if (typeof(options) == 'string') {\n    buf = options == 'binary' ? new BufferClass(16) : null;\n    options = null;\n  }\n  options = options || {};\n\n  var rnds = options.random || (options.rng || _rng)();\n\n  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n  rnds[6] = (rnds[6] & 0x0f) | 0x40;\n  rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n  // Copy bytes to buffer, if provided\n  if (buf) {\n    for (var ii = 0; ii < 16; ii++) {\n      buf[i + ii] = rnds[ii];\n    }\n  }\n\n  return buf || unparse(rnds);\n}\n\n// Export public API\nvar uuid = v4;\nuuid.v1 = v1;\nuuid.v4 = v4;\nuuid.parse = parse;\nuuid.unparse = unparse;\nuuid.BufferClass = BufferClass;\n\nmodule.exports = uuid;\n","var RTCIceCandidate       = window.mozRTCIceCandidate       || window.webkitRTCIceCandidate       || window.RTCIceCandidate;\nvar RTCPeerConnection     = window.mozRTCPeerConnection     || window.webkitRTCPeerConnection     || window.RTCPeerConnection;\nvar RTCSessionDescription = window.mozRTCSessionDescription || window.webkitRTCSessionDescription || window.RTCSessionDescription;\n\nexports.RTCIceCandidate       = RTCIceCandidate;\nexports.RTCPeerConnection     = RTCPeerConnection;\nexports.RTCSessionDescription = RTCSessionDescription;\n","// Generated by CoffeeScript 1.6.2\n(function() {\n  var EventEmitter, name, processLacksEventFunctions, value, _ref;\n\n  EventEmitter = require(\"events\").EventEmitter;\n\n  processLacksEventFunctions = function() {\n    var name, value, _ref;\n\n    _ref = EventEmitter.prototype;\n    for (name in _ref) {\n      value = _ref[name];\n      if (process[name] != null) {\n        return false;\n      }\n    }\n    return true;\n  };\n\n  if (!((typeof window !== \"undefined\" && window !== null) && window.document && window.navigator)) {\n    return;\n  }\n\n  if (!((typeof process !== \"undefined\" && process !== null) && (typeof global !== \"undefined\" && global !== null))) {\n    return;\n  }\n\n  if (window !== global) {\n    return;\n  }\n\n  if (window.onerror !== null) {\n    return;\n  }\n\n  if (!processLacksEventFunctions()) {\n    return;\n  }\n\n  _ref = EventEmitter.prototype;\n  for (name in _ref) {\n    value = _ref[name];\n    process[name] = value;\n  }\n\n  window.onerror = function(err, url, line) {\n    return process.emit(\"uncaughtException\", new Error(\"\" + err + \" (\" + url + \":\" + line + \")\"));\n  };\n\n  window.addEventListener(\"unload\", function(event) {\n    return process.emit(\"exit\");\n  });\n\n}).call(this);\n\n/*\n//@ sourceMappingURL=process-events-shim.map\n*/\n","/*\n * (C) Copyright 2014 Kurento (http://kurento.org/)\n *\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the GNU Lesser General Public License\n * (LGPL) version 2.1 which accompanies this distribution, and is available at\n * http://www.gnu.org/licenses/lgpl-2.1.html\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n */\n\nvar inherits = require('inherits');\n\nvar packers = require('./packers');\nvar Mapper = require('./Mapper');\n\n\nconst BASE_TIMEOUT = 5000;\n\n\nfunction unifyResponseMethods(responseMethods)\n{\n  if(!responseMethods) return {};\n\n  for(var key in responseMethods)\n  {\n    var value = responseMethods[key];\n\n    if(typeof value == 'string')\n      responseMethods[key] =\n      {\n        response: value\n      }\n  };\n\n  return responseMethods;\n};\n\nfunction unifyTransport(transport)\n{\n  if(!transport) return;\n\n  if(transport instanceof Function)\n    return transport;\n\n  if(transport.send instanceof Function)\n    return transport.send.bind(transport);\n\n  if(transport.postMessage instanceof Function)\n    return transport.postMessage.bind(transport);\n\n  throw new SyntaxError(\"Transport is not a function nor a valid object\");\n};\n\n\n/**\n * Representation of a RPC notification\n *\n * @class\n *\n * @constructor\n *\n * @param {String} method -method of the notification\n * @param params - parameters of the notification\n */\nfunction RpcNotification(method, params)\n{\n  Object.defineProperty(this, 'method', {value: method, enumerable: true});\n  Object.defineProperty(this, 'params', {value: params, enumerable: true});\n};\n\n\n/**\n * @class\n *\n * @constructor\n */\nfunction RpcBuilder(packer, options, transport)\n{\n  var self = this;\n\n  if(!packer)\n    throw new SyntaxError('Packer is not defined');\n\n  if(!packer.pack || !packer.unpack)\n    throw new SyntaxError('Packer is invalid');\n\n  var responseMethods = unifyResponseMethods(packer.responseMethods);\n\n\n  if(options instanceof Function || options && options.send instanceof Function)\n  {\n    if(transport)\n      throw new SyntaxError(\"There can't be parameters after callback\");\n\n    transport = options;\n    options = undefined;\n  };\n\n  options = options || {};\n\n\n  Object.defineProperty(this, 'peerID', {value: options.peerID});\n\n  var max_retries = options.max_retries || 0;\n\n\n  this.transport = unifyTransport(transport);\n\n  const request_timeout    = options.request_timeout    || BASE_TIMEOUT;\n  const response_timeout   = options.response_timeout   || BASE_TIMEOUT;\n  const duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT;\n\n\n  var requestID = 0;\n\n  var requests  = new Mapper();\n  var responses = new Mapper();\n  var processedResponses = new Mapper();\n\n  var message2Key = {};\n\n\n  /**\n   * Store the response to prevent to process duplicate request later\n   */\n  function storeResponse(message, id, dest)\n  {\n    var response =\n    {\n      message: message,\n      /** Timeout to auto-clean old responses */\n      timeout: setTimeout(function()\n      {\n        responses.remove(id, dest);\n      },\n      response_timeout)\n    };\n\n    responses.set(response, id, dest);\n  };\n\n  /**\n   * Store the response to ignore duplicated messages later\n   */\n  function storeProcessedResponse(ack, from)\n  {\n    var timeout = setTimeout(function()\n    {\n      processedResponses.remove(ack, from);\n    },\n    duplicates_timeout);\n\n    processedResponses.set(timeout, ack, from);\n  };\n\n\n  /**\n   * Representation of a RPC request\n   *\n   * @class\n   * @extends RpcNotification\n   *\n   * @constructor\n   *\n   * @param {String} method -method of the notification\n   * @param params - parameters of the notification\n   * @param {Integer} id - identifier of the request\n   * @param [from] - source of the notification\n   */\n  function RpcRequest(method, params, id, from, transport)\n  {\n    RpcNotification.call(this, method, params);\n\n    this.transport = transport;\n\n    var response = responses.get(id, from);\n\n    /**\n     * @constant {Boolean} duplicated\n     */\n    transport = transport || self.transport;\n    if(!transport)\n      Object.defineProperty(this, 'duplicated',\n      {\n        value: Boolean(response)\n      });\n\n    var responseMethod = responseMethods[method];\n\n    this.pack = function()\n    {\n      return packer.pack(this, id);\n    }\n\n    /**\n     * Generate a response to this request\n     *\n     * @param {Error} [error]\n     * @param {*} [result]\n     *\n     * @returns {string}\n     */\n    this.reply = function(error, result, transport)\n    {\n      // Fix optional parameters\n      if(error instanceof Function || error && error.send instanceof Function)\n      {\n        if(result != undefined)\n          throw new SyntaxError(\"There can't be parameters after callback\");\n\n        transport = error;\n        result = null;\n        error = undefined;\n      }\n\n      else if(result instanceof Function\n      || result && result.send instanceof Function)\n      {\n        if(transport != undefined)\n          throw new SyntaxError(\"There can't be parameters after callback\");\n\n        transport = result;\n        result = null;\n      };\n\n      transport = unifyTransport(transport);\n\n      // Duplicated request, remove old response timeout\n      if(response)\n        clearTimeout(response.timeout);\n\n      if(from != undefined)\n      {\n        if(error)\n          error.dest = from;\n\n        if(result)\n          result.dest = from;\n      };\n\n      var message;\n\n      // New request or overriden one, create new response with provided data\n      if(error || result != undefined)\n      {\n        if(self.peerID != undefined)\n        {\n          if(error)\n            error.from = self.peerID;\n          else\n            result.from = self.peerID;\n        }\n\n        // Protocol indicates that responses has own request methods\n        if(responseMethod)\n        {\n          if(responseMethod.error == undefined && error)\n            message =\n            {\n              error: error\n            };\n\n          else\n          {\n            var method = error\n                       ? responseMethod.error\n                       : responseMethod.response;\n\n            message =\n            {\n              method: method,\n              params: error || result\n            };\n          }\n        }\n        else\n          message =\n          {\n            error:  error,\n            result: result\n          };\n\n        message = packer.pack(message, id);\n      }\n\n      // Duplicate & not-overriden request, re-send old response\n      else if(response)\n        message = response.message;\n\n      // New empty reply, response null value\n      else\n        message = packer.pack({result: null}, id);\n\n      // Store the response to prevent to process a duplicated request later\n      storeResponse(message, id, from);\n\n      // Return the stored response so it can be directly send back\n      transport = transport || this.transport || self.transport;\n\n      if(transport)\n        return transport(message);\n\n      return message;\n    }\n  };\n  inherits(RpcRequest, RpcNotification);\n\n\n  function cancel(message)\n  {\n    var key = message2Key[message];\n    if(!key) return;\n\n    delete message2Key[message];\n\n    var request = requests.pop(key.id, key.dest);\n    if(!request) return;\n\n    clearTimeout(request.timeout);\n\n    // Start duplicated responses timeout\n    storeProcessedResponse(key.id, key.dest);\n  };\n\n  /**\n   * Allow to cancel a request and don't wait for a response\n   *\n   * If `message` is not given, cancel all the request\n   */\n  this.cancel = function(message)\n  {\n    if(message) return cancel(message);\n\n    for(var message in message2Key)\n      cancel(message);\n  };\n\n\n  this.close = function()\n  {\n    // Prevent to receive new messages\n    if(transport && transport.close)\n       transport.close();\n\n    // Request & processed responses\n    this.cancel();\n\n    processedResponses.forEach(function(timeout)\n    {\n      clearTimeout(timeout);\n    });\n\n    // Responses\n    responses.forEach(function(response)\n    {\n      clearTimeout(response.timeout);\n    });\n  };\n\n\n  /**\n   * Generates and encode a JsonRPC 2.0 message\n   *\n   * @param {String} method -method of the notification\n   * @param params - parameters of the notification\n   * @param [dest] - destination of the notification\n   * @param {object} [transport] - transport where to send the message\n   * @param [callback] - function called when a response to this request is\n   *   received. If not defined, a notification will be send instead\n   *\n   * @returns {string} A raw JsonRPC 2.0 request or notification string\n   */\n  this.encode = function(method, params, dest, transport, callback)\n  {\n    // Fix optional parameters\n    if(params instanceof Function)\n    {\n      if(dest != undefined)\n        throw new SyntaxError(\"There can't be parameters after callback\");\n\n      callback  = params;\n      transport = undefined;\n      dest      = undefined;\n      params    = undefined;\n    }\n\n    else if(dest instanceof Function)\n    {\n      if(transport != undefined)\n        throw new SyntaxError(\"There can't be parameters after callback\");\n\n      callback  = dest;\n      transport = undefined;\n      dest      = undefined;\n    }\n\n    else if(transport instanceof Function)\n    {\n      if(callback != undefined)\n        throw new SyntaxError(\"There can't be parameters after callback\");\n\n      callback  = transport;\n      transport = undefined;\n    };\n\n    if(self.peerID != undefined)\n    {\n      params = params || {};\n\n      params.from = self.peerID;\n    };\n\n    if(dest != undefined)\n      params.dest = dest;\n\n    // Encode message\n    var message =\n    {\n      method: method,\n      params: params\n    };\n\n    if(callback)\n    {\n      var id = requestID++;\n      var retried = 0;\n\n      message = packer.pack(message, id);\n\n      var request =\n      {\n        message:         message,\n        callback:        dispatchCallback,\n        responseMethods: responseMethods[method] || {}\n      };\n\n      function dispatchCallback(error, result)\n      {\n        self.cancel(message);\n\n        callback(error, result);\n      };\n\n      var encode_transport = unifyTransport(transport);\n\n      function sendRequest(transport)\n      {\n        request.timeout = setTimeout(timeout,\n                                     request_timeout*Math.pow(2, retried++));\n        message2Key[message] = {id: id, dest: dest};\n        requests.set(request, id, dest);\n\n        transport = transport || encode_transport || self.transport;\n        if(transport)\n          return transport(message);\n\n        return message;\n      };\n\n      function retry(transport)\n      {\n        transport = unifyTransport(transport);\n\n        console.warn(retried+' retry for request message:',message);\n\n        var timeout = processedResponses.pop(id, dest);\n        clearTimeout(timeout);\n\n        return sendRequest(transport);\n      };\n\n      function timeout()\n      {\n        if(retried < max_retries)\n          return retry(transport);\n\n        var error = new Error('Request has timed out');\n            error.request = message;\n\n        error.retry = retry;\n\n        dispatchCallback(error)\n      };\n\n      return sendRequest(transport);\n    };\n\n    // Return the packed message\n    message = packer.pack(message);\n\n    transport = transport || self.transport;\n    if(transport)\n      return transport(message);\n\n    return message;\n  };\n\n  /**\n   * Decode and process a JsonRPC 2.0 message\n   *\n   * @param {string} message - string with the content of the message\n   *\n   * @returns {RpcNotification|RpcRequest|undefined} - the representation of the\n   *   notification or the request. If a response was processed, it will return\n   *   `undefined` to notify that it was processed\n   *\n   * @throws {TypeError} - Message is not defined\n   */\n  this.decode = function(message, transport)\n  {\n    if(!message)\n      throw new TypeError(\"Message is not defined\");\n\n    message = packer.unpack(message);\n\n    var id     = message.id;\n    var ack    = message.ack;\n    var method = message.method;\n    var params = message.params || {};\n\n    var from = params.from;\n    var dest = params.dest;\n\n    // Ignore messages send by us\n    if(self.peerID != undefined && from == self.peerID) return;\n\n    // Notification\n    if(id == undefined && ack == undefined)\n      return new RpcNotification(method, params);\n\n\n    function processRequest()\n    {\n      // If we have a transport and it's a duplicated request, reply inmediatly\n      transport = unifyTransport(transport) || self.transport;\n      if(transport)\n      {\n        var response = responses.get(id, from);\n        if(response)\n          return transport(response.message);\n      };\n\n      var idAck = (id != undefined) ? id : ack;\n      return new RpcRequest(method, params, idAck, from, transport);\n    };\n\n    function processResponse(request, error, result)\n    {\n      request.callback(error, result);\n    };\n\n    function duplicatedResponse(timeout)\n    {\n      console.warn(\"Response already processed\", message);\n\n      // Update duplicated responses timeout\n      clearTimeout(timeout);\n      storeProcessedResponse(ack, from);\n    };\n\n\n    // Request, or response with own method\n    if(method)\n    {\n      // Check if it's a response with own method\n      if(dest == undefined || dest == self.peerID)\n      {\n        var request = requests.get(ack, from);\n        if(request)\n        {\n          var responseMethods = request.responseMethods;\n\n          if(method == responseMethods.error)\n            return processResponse(request, params);\n\n          if(method == responseMethods.response)\n            return processResponse(request, null, params);\n\n          return processRequest();\n        }\n\n        var processed = processedResponses.get(ack, from);\n        if(processed)\n          return duplicatedResponse(processed);\n      }\n\n      // Request\n      return processRequest();\n    };\n\n    var error  = message.error;\n    var result = message.result;\n\n    // Ignore responses not send to us\n    if(error  && error.dest  && error.dest  != self.sessionID) return;\n    if(result && result.dest && result.dest != self.sessionID) return;\n\n    // Response\n    var request = requests.get(ack, from);\n    if(!request)\n    {\n      var processed = processedResponses.get(ack, from);\n      if(processed)\n        return duplicatedResponse(processed);\n\n      return console.warn(\"No callback was defined for this message\", message);\n    };\n\n    // Process response\n    processResponse(request, error, result);\n  };\n};\n\n\nRpcBuilder.RpcNotification = RpcNotification;\n\n\nmodule.exports = RpcBuilder;\n\nRpcBuilder.packers = packers;\n","// Version: 3.6.4\nvar NOW             = 1\n,   READY           = false\n,   READY_BUFFER    = []\n,   PRESENCE_SUFFIX = '-pnpres'\n,   DEF_WINDOWING   = 10     // MILLISECONDS.\n,   DEF_TIMEOUT     = 10000  // MILLISECONDS.\n,   DEF_SUB_TIMEOUT = 310    // SECONDS.\n,   DEF_KEEPALIVE   = 60     // SECONDS (FOR TIMESYNC).\n,   SECOND          = 1000   // A THOUSAND MILLISECONDS.\n,   URLBIT          = '/'\n,   PARAMSBIT       = '&'\n,   PRESENCE_HB_THRESHOLD = 5\n,   PRESENCE_HB_DEFAULT  = 30\n,   SDK_VER         = '3.6.4'\n,   REPL            = /{([\\w\\-]+)}/g;\n\n/**\n * UTILITIES\n */\nfunction unique() { return'x'+ ++NOW+''+(+new Date) }\nfunction rnow()   { return+new Date }\n\n/**\n * NEXTORIGIN\n * ==========\n * var next_origin = nextorigin();\n */\nvar nextorigin = (function() {\n    var max = 20\n    ,   ori = Math.floor(Math.random() * max);\n    return function( origin, failover ) {\n        return origin.indexOf('pubsub.') > 0\n            && origin.replace(\n             'pubsub', 'ps' + (\n                failover ? uuid().split('-')[0] :\n                (++ori < max? ori : ori=1)\n            ) ) || origin;\n    }\n})();\n\n\n/**\n * Build Url\n * =======\n *\n */\nfunction build_url( url_components, url_params ) {\n    var url    = url_components.join(URLBIT)\n    ,   params = [];\n\n    if (!url_params) return url;\n\n    each( url_params, function( key, value ) {\n        var value_str = (typeof value == 'object')?JSON['stringify'](value):value;\n        (typeof value != 'undefined' &&\n            value != null && encode(value_str).length > 0\n        ) && params.push(key + \"=\" + encode(value_str));\n    } );\n\n    url += \"?\" + params.join(PARAMSBIT);\n    return url;\n}\n\n/**\n * UPDATER\n * =======\n * var timestamp = unique();\n */\nfunction updater( fun, rate ) {\n    var timeout\n    ,   last   = 0\n    ,   runnit = function() {\n        if (last + rate > rnow()) {\n            clearTimeout(timeout);\n            timeout = setTimeout( runnit, rate );\n        }\n        else {\n            last = rnow();\n            fun();\n        }\n    };\n\n    return runnit;\n}\n\n/**\n * GREP\n * ====\n * var list = grep( [1,2,3], function(item) { return item % 2 } )\n */\nfunction grep( list, fun ) {\n    var fin = [];\n    each( list || [], function(l) { fun(l) && fin.push(l) } );\n    return fin\n}\n\n/**\n * SUPPLANT\n * ========\n * var text = supplant( 'Hello {name}!', { name : 'John' } )\n */\nfunction supplant( str, values ) {\n    return str.replace( REPL, function( _, match ) {\n        return values[match] || _\n    } );\n}\n\n/**\n * timeout\n * =======\n * timeout( function(){}, 100 );\n */\nfunction timeout( fun, wait ) {\n    return setTimeout( fun, wait );\n}\n\n/**\n * uuid\n * ====\n * var my_uuid = uuid();\n */\nfunction uuid(callback) {\n    var u = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,\n    function(c) {\n        var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);\n        return v.toString(16);\n    });\n    if (callback) callback(u);\n    return u;\n}\n\nfunction isArray(arg) {\n  return !!arg && (Array.isArray && Array.isArray(arg) || typeof(arg.length) === \"number\")\n}\n\n/**\n * EACH\n * ====\n * each( [1,2,3], function(item) { } )\n */\nfunction each( o, f) {\n    if ( !o || !f ) return;\n\n    if ( isArray(o) )\n        for ( var i = 0, l = o.length; i < l; )\n            f.call( o[i], o[i], i++ );\n    else\n        for ( var i in o )\n            o.hasOwnProperty    &&\n            o.hasOwnProperty(i) &&\n            f.call( o[i], i, o[i] );\n}\n\n/**\n * MAP\n * ===\n * var list = map( [1,2,3], function(item) { return item + 1 } )\n */\nfunction map( list, fun ) {\n    var fin = [];\n    each( list || [], function( k, v ) { fin.push(fun( k, v )) } );\n    return fin;\n}\n\n/**\n * ENCODE\n * ======\n * var encoded_data = encode('path');\n */\nfunction encode(path) { return encodeURIComponent(path) }\n\n/**\n * Generate Subscription Channel List\n * ==================================\n * generate_channel_list(channels_object);\n */\nfunction generate_channel_list(channels, nopresence) {\n    var list = [];\n    each( channels, function( channel, status ) {\n        if (nopresence) {\n            if(channel.search('-pnpres') < 0) { \n                if (status.subscribed) list.push(channel);\n            }    \n        } else {\n            if (status.subscribed) list.push(channel);\n        }  \n    });\n    return list.sort();\n}\n\n\n// PUBNUB READY TO CONNECT\nfunction ready() { timeout( function() {\n    if (READY) return;\n    READY = 1;\n    each( READY_BUFFER, function(connect) { connect() } );\n}, SECOND ); }\n\nfunction PN_API(setup) {\n    var SUB_WINDOWING =  +setup['windowing']   || DEF_WINDOWING\n    ,   SUB_TIMEOUT   = (+setup['timeout']     || DEF_SUB_TIMEOUT) * SECOND\n    ,   KEEPALIVE     = (+setup['keepalive']   || DEF_KEEPALIVE)   * SECOND\n    ,   NOLEAVE       = setup['noleave']       || 0\n    ,   PUBLISH_KEY   = setup['publish_key']   || 'demo'\n    ,   SUBSCRIBE_KEY = setup['subscribe_key'] || 'demo'\n    ,   AUTH_KEY      = setup['auth_key']      || ''\n    ,   SECRET_KEY    = setup['secret_key']    || ''\n    ,   hmac_SHA256   = setup['hmac_SHA256']\n    ,   SSL           = setup['ssl']            ? 's' : ''\n    ,   ORIGIN        = 'http'+SSL+'://'+(setup['origin']||'pubsub.pubnub.com')\n    ,   STD_ORIGIN    = nextorigin(ORIGIN)\n    ,   SUB_ORIGIN    = nextorigin(ORIGIN)\n    ,   CONNECT       = function(){}\n    ,   PUB_QUEUE     = []\n    ,   TIME_DRIFT    = 0\n    ,   SUB_CALLBACK  = 0\n    ,   SUB_CHANNEL   = 0\n    ,   SUB_RECEIVER  = 0\n    ,   SUB_RESTORE   = 0\n    ,   SUB_BUFF_WAIT = 0\n    ,   TIMETOKEN     = 0\n    ,   RESUMED       = false\n    ,   CHANNELS      = {}\n    ,   STATE         = {}\n    ,   PRESENCE_HB_TIMEOUT  = null\n    ,   PRESENCE_HB          = validate_presence_heartbeat(setup['heartbeat'] || setup['pnexpires'] || 0, setup['error'])\n    ,   PRESENCE_HB_INTERVAL = setup['heartbeat_interval'] || PRESENCE_HB - 3\n    ,   PRESENCE_HB_RUNNING  = false\n    ,   NO_WAIT_FOR_PENDING  = setup['no_wait_for_pending']\n    ,   COMPATIBLE_35 = setup['compatible_3.5']  || false\n    ,   xdr           = setup['xdr']\n    ,   params        = setup['params'] || {}\n    ,   error         = setup['error']      || function() {}\n    ,   _is_online    = setup['_is_online'] || function() { return 1 }\n    ,   jsonp_cb      = setup['jsonp_cb']   || function() { return 0 }\n    ,   db            = setup['db']         || {'get': function(){}, 'set': function(){}}\n    ,   CIPHER_KEY    = setup['cipher_key']\n    ,   UUID          = setup['uuid'] || ( db && db['get'](SUBSCRIBE_KEY+'uuid') || '');\n\n    var crypto_obj    = setup['crypto_obj'] ||\n        {\n            'encrypt' : function(a,key){ return a},\n            'decrypt' : function(b,key){return b}\n        };\n\n    function _get_url_params(data) {\n        if (!data) data = {};\n        each( params , function( key, value ) {\n            data[key] = value;\n        });\n        return data;\n    }\n\n    function _object_to_key_list(o) {\n        var l = []\n        each( o , function( key, value ) {\n            l.push(key);\n        });\n        return l;\n    }    \n    function _object_to_key_list_sorted(o) {\n        return _object_to_key_list(o).sort();\n    }\n\n    function _get_pam_sign_input_from_params(params) {\n        var si = \"\";\n        var l = _object_to_key_list_sorted(params);\n\n        for (var i in l) {\n            var k = l[i]\n            si += k + \"=\" + encode(params[k]) ;\n            if (i != l.length - 1) si += \"&\"\n        }\n        return si;\n    }\n\n    function validate_presence_heartbeat(heartbeat, cur_heartbeat, error) {\n        var err = false;\n\n        if (typeof heartbeat === 'number') {\n            if (heartbeat > PRESENCE_HB_THRESHOLD || heartbeat == 0)\n                err = false;\n            else\n                err = true;\n        } else if(typeof heartbeat === 'boolean'){\n            if (!heartbeat) {\n                return 0;\n            } else {\n                return PRESENCE_HB_DEFAULT;\n            }\n        } else {\n            err = true;\n        }\n\n        if (err) {\n            error && error(\"Presence Heartbeat value invalid. Valid range ( x > \" + PRESENCE_HB_THRESHOLD + \" or x = 0). Current Value : \" + (cur_heartbeat || PRESENCE_HB_THRESHOLD));\n            return cur_heartbeat || PRESENCE_HB_THRESHOLD;\n        } else return heartbeat;\n    }\n\n    function encrypt(input, key) {\n        return crypto_obj['encrypt'](input, key || CIPHER_KEY) || input;\n    }\n    function decrypt(input, key) {\n        return crypto_obj['decrypt'](input, key || CIPHER_KEY) ||\n               crypto_obj['decrypt'](input, CIPHER_KEY) ||\n               input;\n    }\n\n    function error_common(message, callback) {\n        callback && callback({ 'error' : message || \"error occurred\"});\n        error && error(message);\n    }\n    function _presence_heartbeat() {\n\n        clearTimeout(PRESENCE_HB_TIMEOUT);\n\n        if (!PRESENCE_HB_INTERVAL || PRESENCE_HB_INTERVAL >= 500 || PRESENCE_HB_INTERVAL < 1 || !generate_channel_list(CHANNELS,true).length){\n            PRESENCE_HB_RUNNING = false;\n            return;\n        }\n\n        PRESENCE_HB_RUNNING = true;\n        SELF['presence_heartbeat']({\n            'callback' : function(r) {\n                PRESENCE_HB_TIMEOUT = timeout( _presence_heartbeat, (PRESENCE_HB_INTERVAL) * SECOND );\n            },\n            'error' : function(e) {\n                error && error(\"Presence Heartbeat unable to reach Pubnub servers.\" + JSON.stringify(e));\n                PRESENCE_HB_TIMEOUT = timeout( _presence_heartbeat, (PRESENCE_HB_INTERVAL) * SECOND );\n            }\n        });\n    }\n\n    function start_presence_heartbeat() {\n        !PRESENCE_HB_RUNNING && _presence_heartbeat();\n    }\n\n    function publish(next) {\n\n        if (NO_WAIT_FOR_PENDING) {\n            if (!PUB_QUEUE.length) return;\n        } else {\n            if (next) PUB_QUEUE.sending = 0;\n            if ( PUB_QUEUE.sending || !PUB_QUEUE.length ) return;\n            PUB_QUEUE.sending = 1;\n        }\n\n        xdr(PUB_QUEUE.shift());\n    }\n\n    function each_channel(callback) {\n        var count = 0;\n\n        each( generate_channel_list(CHANNELS), function(channel) {\n            var chan = CHANNELS[channel];\n\n            if (!chan) return;\n\n            count++;\n            (callback||function(){})(chan);\n        } );\n\n        return count;\n    }\n    function _invoke_callback(response, callback, err) {\n        if (typeof response == 'object') {\n            if (response['error'] && response['message'] && response['payload']) {\n                err({'message' : response['message'], 'payload' : response['payload']});\n                return;\n            }\n            if (response['payload']) {\n                callback(response['payload']);\n                return;\n            }\n        }\n        callback(response);\n    }\n\n    function _invoke_error(response,err) {\n        if (typeof response == 'object' && response['error'] &&\n            response['message'] && response['payload']) {\n            err({'message' : response['message'], 'payload' : response['payload']});\n        } else err(response);\n    }\n\n    // Announce Leave Event\n    var SELF = {\n        'LEAVE' : function( channel, blocking, callback, error ) {\n\n            var data   = { 'uuid' : UUID, 'auth' : AUTH_KEY }\n            ,   origin = nextorigin(ORIGIN)\n            ,   callback = callback || function(){}\n            ,   err      = error    || function(){}\n            ,   jsonp  = jsonp_cb();\n\n            // Prevent Leaving a Presence Channel\n            if (channel.indexOf(PRESENCE_SUFFIX) > 0) return true;\n\n            if (COMPATIBLE_35) {\n                if (!SSL)         return false;\n                if (jsonp == '0') return false;\n            }\n            \n            if (NOLEAVE)  return false;\n\n            if (jsonp != '0') data['callback'] = jsonp;\n\n            xdr({\n                blocking : blocking || SSL,\n                timeout  : 2000,\n                callback : jsonp,\n                data     : _get_url_params(data),\n                success  : function(response) {\n                    _invoke_callback(response, callback, err);\n                },\n                fail     : function(response) {\n                    _invoke_error(response, err);\n                },\n                url      : [\n                    origin, 'v2', 'presence', 'sub_key',\n                    SUBSCRIBE_KEY, 'channel', encode(channel), 'leave'\n                ]\n            });\n            return true;\n        },\n        'set_resumed' : function(resumed) {\n                RESUMED = resumed;\n        },\n        'get_cipher_key' : function() {\n            return CIPHER_KEY;\n        },\n        'set_cipher_key' : function(key) {\n            CIPHER_KEY = key;\n        },\n        'raw_encrypt' : function(input, key) {\n            return encrypt(input, key);\n        },\n        'raw_decrypt' : function(input, key) {\n            return decrypt(input, key);\n        },\n        'get_heartbeat' : function() {\n            return PRESENCE_HB;\n        },\n        'set_heartbeat' : function(heartbeat) {\n            PRESENCE_HB = validate_presence_heartbeat(heartbeat, PRESENCE_HB_INTERVAL, error);\n            PRESENCE_HB_INTERVAL = (PRESENCE_HB - 3 >= 1)?PRESENCE_HB - 3:1;\n            CONNECT();\n            _presence_heartbeat();\n        },\n        'get_heartbeat_interval' : function() {\n            return PRESENCE_HB_INTERVAL;\n        },\n        'set_heartbeat_interval' : function(heartbeat_interval) {\n            PRESENCE_HB_INTERVAL = heartbeat_interval;\n            _presence_heartbeat();\n        },\n        'get_version' : function() {\n            return SDK_VER;\n        },\n        '_add_param' : function(key,val) {\n            params[key] = val;\n        },\n\n        /*\n            PUBNUB.history({\n                channel  : 'my_chat_channel',\n                limit    : 100,\n                callback : function(history) { }\n            });\n        */\n        'history' : function( args, callback ) {\n            var callback         = args['callback'] || callback\n            ,   count            = args['count']    || args['limit'] || 100\n            ,   reverse          = args['reverse']  || \"false\"\n            ,   err              = args['error']    || function(){}\n            ,   auth_key         = args['auth_key'] || AUTH_KEY\n            ,   cipher_key       = args['cipher_key']\n            ,   channel          = args['channel']\n            ,   start            = args['start']\n            ,   end              = args['end']\n            ,   include_token    = args['include_token']\n            ,   params           = {}\n            ,   jsonp            = jsonp_cb();\n\n            // Make sure we have a Channel\n            if (!channel)       return error('Missing Channel');\n            if (!callback)      return error('Missing Callback');\n            if (!SUBSCRIBE_KEY) return error('Missing Subscribe Key');\n\n            params['stringtoken'] = 'true';\n            params['count']       = count;\n            params['reverse']     = reverse;\n            params['auth']        = auth_key;\n\n            if (jsonp) params['callback']              = jsonp;\n            if (start) params['start']                 = start;\n            if (end)   params['end']                   = end;\n            if (include_token) params['include_token'] = 'true';\n\n            // Send Message\n            xdr({\n                callback : jsonp,\n                data     : _get_url_params(params),\n                success  : function(response) {\n                    if (typeof response == 'object' && response['error']) {\n                        err({'message' : response['message'], 'payload' : response['payload']});\n                        return;\n                    }\n                    var messages = response[0];\n                    var decrypted_messages = [];\n                    for (var a = 0; a < messages.length; a++) {\n                        var new_message = decrypt(messages[a],cipher_key);\n                        try {\n                            decrypted_messages['push'](JSON['parse'](new_message));\n                        } catch (e) {\n                            decrypted_messages['push']((new_message));\n                        }\n                    }\n                    callback([decrypted_messages, response[1], response[2]]);\n                },\n                fail     : function(response) {\n                    _invoke_error(response, err);\n                },\n                url      : [\n                    STD_ORIGIN, 'v2', 'history', 'sub-key',\n                    SUBSCRIBE_KEY, 'channel', encode(channel)\n                ]\n            });\n        },\n\n        /*\n            PUBNUB.replay({\n                source      : 'my_channel',\n                destination : 'new_channel'\n            });\n        */\n        'replay' : function(args, callback) {\n            var callback    = callback || args['callback'] || function(){}\n            ,   auth_key    = args['auth_key'] || AUTH_KEY\n            ,   source      = args['source']\n            ,   destination = args['destination']\n            ,   stop        = args['stop']\n            ,   start       = args['start']\n            ,   end         = args['end']\n            ,   reverse     = args['reverse']\n            ,   limit       = args['limit']\n            ,   jsonp       = jsonp_cb()\n            ,   data        = {}\n            ,   url;\n\n            // Check User Input\n            if (!source)        return error('Missing Source Channel');\n            if (!destination)   return error('Missing Destination Channel');\n            if (!PUBLISH_KEY)   return error('Missing Publish Key');\n            if (!SUBSCRIBE_KEY) return error('Missing Subscribe Key');\n\n            // Setup URL Params\n            if (jsonp != '0') data['callback'] = jsonp;\n            if (stop)         data['stop']     = 'all';\n            if (reverse)      data['reverse']  = 'true';\n            if (start)        data['start']    = start;\n            if (end)          data['end']      = end;\n            if (limit)        data['count']    = limit;\n\n            data['auth'] = auth_key;\n\n            // Compose URL Parts\n            url = [\n                STD_ORIGIN, 'v1', 'replay',\n                PUBLISH_KEY, SUBSCRIBE_KEY,\n                source, destination\n            ];\n\n            // Start (or Stop) Replay!\n            xdr({\n                callback : jsonp,\n                success  : function(response) {\n                    _invoke_callback(response, callback, err);\n                },\n                fail     : function() { callback([ 0, 'Disconnected' ]) },\n                url      : url,\n                data     : _get_url_params(data)\n            });\n        },\n\n        /*\n            PUBNUB.auth('AJFLKAJSDKLA');\n        */\n        'auth' : function(auth) {\n            AUTH_KEY = auth;\n            CONNECT();\n        },\n\n        /*\n            PUBNUB.time(function(time){ });\n        */\n        'time' : function(callback) {\n            var jsonp = jsonp_cb();\n            xdr({\n                callback : jsonp,\n                data     : _get_url_params({ 'uuid' : UUID, 'auth' : AUTH_KEY }),\n                timeout  : SECOND * 5,\n                url      : [STD_ORIGIN, 'time', jsonp],\n                success  : function(response) { callback(response[0]) },\n                fail     : function() { callback(0) }\n            });\n        },\n\n        /*\n            PUBNUB.publish({\n                channel : 'my_chat_channel',\n                message : 'hello!'\n            });\n        */\n        'publish' : function( args, callback ) {\n            var callback = callback || args['callback'] || function(){}\n            ,   msg      = args['message']\n            ,   channel  = args['channel']\n            ,   auth_key = args['auth_key'] || AUTH_KEY\n            ,   cipher_key = args['cipher_key']\n            ,   err      = args['error'] || function() {}\n            ,   post     = args['post'] || false\n            ,   jsonp    = jsonp_cb()\n            ,   add_msg  = 'push'\n            ,   url;\n\n            if (args['prepend']) add_msg = 'unshift'\n\n            if (!msg)           return error('Missing Message');\n            if (!channel)       return error('Missing Channel');\n            if (!PUBLISH_KEY)   return error('Missing Publish Key');\n            if (!SUBSCRIBE_KEY) return error('Missing Subscribe Key');\n\n            // If trying to send Object\n            msg = JSON['stringify'](encrypt(msg, cipher_key));\n\n            // Create URL\n            url = [\n                STD_ORIGIN, 'publish',\n                PUBLISH_KEY, SUBSCRIBE_KEY,\n                0, encode(channel),\n                jsonp, encode(msg)\n            ];\n\n            // Queue Message Send\n            PUB_QUEUE[add_msg]({\n                callback : jsonp,\n                timeout  : SECOND * 5,\n                url      : url,\n                data     : _get_url_params({ 'uuid' : UUID, 'auth' : auth_key }),\n                fail     : function(response){\n                    _invoke_error(response, err);\n                    publish(1);\n                },\n                success  : function(response) {\n                    _invoke_callback(response, callback, err);\n                    publish(1);\n                },\n                mode     : (post)?'POST':'GET'\n            });\n\n            // Send Message\n            publish();\n        },\n\n        /*\n            PUBNUB.unsubscribe({ channel : 'my_chat' });\n        */\n        'unsubscribe' : function(args, callback) {\n            var channel = args['channel']\n            ,   callback      = callback            || args['callback'] || function(){}\n            ,   err           = args['error']       || function(){};\n\n            TIMETOKEN   = 0;\n            SUB_RESTORE = 1;\n\n            // Prepare Channel(s)\n            channel = map( (\n                channel.join ? channel.join(',') : ''+channel\n            ).split(','), function(channel) {\n                if (!CHANNELS[channel]) return;\n                return channel + ',' + channel + PRESENCE_SUFFIX;\n            } ).join(',');\n\n            // Iterate over Channels\n            each( channel.split(','), function(channel) {\n                var CB_CALLED = true;\n                if (!channel) return;\n                if (READY) {\n                    CB_CALLED = SELF['LEAVE']( channel, 0 , callback, err);\n                }\n                if (!CB_CALLED) callback({action : \"leave\"});\n                CHANNELS[channel] = 0;\n                if (channel in STATE) delete STATE[channel];\n            } );\n\n            // Reset Connection if Count Less\n            CONNECT();\n        },\n\n        /*\n            PUBNUB.subscribe({\n                channel  : 'my_chat'\n                callback : function(message) { }\n            });\n        */\n        'subscribe' : function( args, callback ) {\n            var channel       = args['channel']\n            ,   callback      = callback            || args['callback']\n            ,   callback      = callback            || args['message']\n            ,   auth_key      = args['auth_key']    || AUTH_KEY\n            ,   connect       = args['connect']     || function(){}\n            ,   reconnect     = args['reconnect']   || function(){}\n            ,   disconnect    = args['disconnect']  || function(){}\n            ,   errcb         = args['error']       || function(){}\n            ,   idlecb        = args['idle']        || function(){}\n            ,   presence      = args['presence']    || 0\n            ,   noheresync    = args['noheresync']  || 0\n            ,   backfill      = args['backfill']    || 0\n            ,   timetoken     = args['timetoken']   || 0\n            ,   sub_timeout   = args['timeout']     || SUB_TIMEOUT\n            ,   windowing     = args['windowing']   || SUB_WINDOWING\n            ,   state         = args['state']\n            ,   heartbeat     = args['heartbeat'] || args['pnexpires']\n            ,   restore       = args['restore'];\n\n            // Restore Enabled?\n            SUB_RESTORE = restore;\n\n            // Always Reset the TT\n            TIMETOKEN = timetoken;\n\n            // Make sure we have a Channel\n            if (!channel)       return error('Missing Channel');\n            if (!callback)      return error('Missing Callback');\n            if (!SUBSCRIBE_KEY) return error('Missing Subscribe Key');\n\n            if (heartbeat || heartbeat === 0) {\n                SELF['set_heartbeat'](heartbeat);\n            }\n\n            // Setup Channel(s)\n            each( (channel.join ? channel.join(',') : ''+channel).split(','),\n            function(channel) {\n                var settings = CHANNELS[channel] || {};\n\n                // Store Channel State\n                CHANNELS[SUB_CHANNEL = channel] = {\n                    name         : channel,\n                    connected    : settings.connected,\n                    disconnected : settings.disconnected,\n                    subscribed   : 1,\n                    callback     : SUB_CALLBACK = callback,\n                    'cipher_key' : args['cipher_key'],\n                    connect      : connect,\n                    disconnect   : disconnect,\n                    reconnect    : reconnect\n                };\n                if (state) {\n                    if (channel in state) {\n                        STATE[channel] = state[channel];\n                    } else {\n                        STATE[channel] = state;\n                    }\n                }\n\n                // Presence Enabled?\n                if (!presence) return;\n\n                // Subscribe Presence Channel\n                SELF['subscribe']({\n                    'channel'  : channel + PRESENCE_SUFFIX,\n                    'callback' : presence,\n                    'restore'  : restore\n                });\n\n                // Presence Subscribed?\n                if (settings.subscribed) return;\n\n                // See Who's Here Now?\n                if (noheresync) return;\n                SELF['here_now']({\n                    'channel'  : channel,\n                    'callback' : function(here) {\n                        each( 'uuids' in here ? here['uuids'] : [],\n                        function(uid) { presence( {\n                            'action'    : 'join',\n                            'uuid'      : uid,\n                            'timestamp' : rnow(),\n                            'occupancy' : here['occupancy'] || 1\n                        }, here, channel ); } );\n                    }\n                });\n            } );\n\n            // Test Network Connection\n            function _test_connection(success) {\n                if (success) {\n                    // Begin Next Socket Connection\n                    timeout( CONNECT, SECOND );\n                }\n                else {\n                    // New Origin on Failed Connection\n                    STD_ORIGIN = nextorigin( ORIGIN, 1 );\n                    SUB_ORIGIN = nextorigin( ORIGIN, 1 );\n\n                    // Re-test Connection\n                    timeout( function() {\n                        SELF['time'](_test_connection);\n                    }, SECOND );\n                }\n\n                // Disconnect & Reconnect\n                each_channel(function(channel){\n                    // Reconnect\n                    if (success && channel.disconnected) {\n                        channel.disconnected = 0;\n                        return channel.reconnect(channel.name);\n                    }\n\n                    // Disconnect\n                    if (!success && !channel.disconnected) {\n                        channel.disconnected = 1;\n                        channel.disconnect(channel.name);\n                    }\n                });\n            }\n\n            // Evented Subscribe\n            function _connect() {\n                var jsonp    = jsonp_cb()\n                ,   channels = generate_channel_list(CHANNELS).join(',');\n\n                // Stop Connection\n                if (!channels) return;\n\n                // Connect to PubNub Subscribe Servers\n                _reset_offline();\n\n                var data = _get_url_params({ 'uuid' : UUID, 'auth' : auth_key });\n\n                var st = JSON.stringify(STATE);\n                if (st.length > 2) data['state'] = JSON.stringify(STATE);\n\n                if (PRESENCE_HB) data['heartbeat'] = PRESENCE_HB;\n\n                start_presence_heartbeat();\n                SUB_RECEIVER = xdr({\n                    timeout  : sub_timeout,\n                    callback : jsonp,\n                    fail     : function(response) {\n                        _invoke_error(response, errcb);\n                        //SUB_RECEIVER = null;\n                        SELF['time'](_test_connection);\n                    },\n                    data     : _get_url_params(data),\n                    url      : [\n                        SUB_ORIGIN, 'subscribe',\n                        SUBSCRIBE_KEY, encode(channels),\n                        jsonp, TIMETOKEN\n                    ],\n                    success : function(messages) {\n\n                        //SUB_RECEIVER = null;\n                        // Check for Errors\n                        if (!messages || (\n                            typeof messages == 'object' &&\n                            'error' in messages         &&\n                            messages['error']\n                        )) {\n                            errcb(messages['error']);\n                            return timeout( CONNECT, SECOND );\n                        }\n\n                        // User Idle Callback\n                        idlecb(messages[1]);\n\n                        // Restore Previous Connection Point if Needed\n                        TIMETOKEN = !TIMETOKEN               &&\n                                    SUB_RESTORE              &&\n                                    db['get'](SUBSCRIBE_KEY) || messages[1];\n\n                        // Connect\n                        each_channel(function(channel){\n                            if (channel.connected) return;\n                            channel.connected = 1;\n                            channel.connect(channel.name);\n                        });\n\n                        if (RESUMED && !SUB_RESTORE) {\n                                TIMETOKEN = 0;\n                                RESUMED = false;\n                                // Update Saved Timetoken\n                                db['set']( SUBSCRIBE_KEY, 0 );\n                                timeout( _connect, windowing );\n                                return;\n                        }\n\n                        // Invoke Memory Catchup and Receive Up to 100\n                        // Previous Messages from the Queue.\n                        if (backfill) {\n                            TIMETOKEN = 10000;\n                            backfill  = 0;\n                        }\n\n                        // Update Saved Timetoken\n                        db['set']( SUBSCRIBE_KEY, messages[1] );\n\n                        // Route Channel <---> Callback for Message\n                        var next_callback = (function() {\n                            var channels = (messages.length>2?messages[2]:map(\n                                generate_channel_list(CHANNELS), function(chan) { return map(\n                                    Array(messages[0].length)\n                                    .join(',').split(','),\n                                    function() { return chan; }\n                                ) }).join(','));\n                            var list = channels.split(',');\n\n                            return function() {\n                                var channel = list.shift()||SUB_CHANNEL;\n                                return [\n                                    (CHANNELS[channel]||{})\n                                    .callback||SUB_CALLBACK,\n                                    channel.split(PRESENCE_SUFFIX)[0]\n                                ];\n                            };\n                        })();\n\n                        var latency = detect_latency(+messages[1]);\n                        each( messages[0], function(msg) {\n                            var next = next_callback();\n                            var decrypted_msg = decrypt(msg,CHANNELS[next[1]]['cipher_key']);\n                            next[0]( decrypted_msg, messages, next[1], latency);\n                        });\n\n                        timeout( _connect, windowing );\n                    }\n                });\n            }\n\n            CONNECT = function() {\n                _reset_offline();\n                timeout( _connect, windowing );\n            };\n\n            // Reduce Status Flicker\n            if (!READY) return READY_BUFFER.push(CONNECT);\n\n            // Connect Now\n            CONNECT();\n        },\n\n        /*\n            PUBNUB.here_now({ channel : 'my_chat', callback : fun });\n        */\n        'here_now' : function( args, callback ) {\n            var callback = args['callback'] || callback\n            ,   err      = args['error']    || function(){}\n            ,   auth_key = args['auth_key'] || AUTH_KEY\n            ,   channel  = args['channel']\n            ,   jsonp    = jsonp_cb()\n            ,   uuids    = ('uuids' in args) ? args['uuids'] : true\n            ,   state    = args['state']\n            ,   data     = { 'uuid' : UUID, 'auth' : auth_key };\n\n            if (!uuids) data['disable_uuids'] = 1;\n            if (state) data['state'] = 1;\n\n            // Make sure we have a Channel\n            if (!callback)      return error('Missing Callback');\n            if (!SUBSCRIBE_KEY) return error('Missing Subscribe Key');\n\n            var url = [\n                    STD_ORIGIN, 'v2', 'presence',\n                    'sub_key', SUBSCRIBE_KEY\n                ];\n\n            channel && url.push('channel') && url.push(encode(channel));\n\n            if (jsonp != '0') { data['callback'] = jsonp; }\n\n            xdr({\n                callback : jsonp,\n                data     : _get_url_params(data),\n                success  : function(response) {\n                    _invoke_callback(response, callback, err);\n                },\n                fail     : function(response) {\n                    _invoke_error(response, err);\n                },\n                url      : url\n            });\n        },\n\n        /*\n            PUBNUB.current_channels_by_uuid({ channel : 'my_chat', callback : fun });\n        */\n        'where_now' : function( args, callback ) {\n            var callback = args['callback'] || callback\n            ,   err      = args['error']    || function(){}\n            ,   auth_key = args['auth_key'] || AUTH_KEY\n            ,   jsonp    = jsonp_cb()\n            ,   uuid     = args['uuid']     || UUID\n            ,   data     = { 'auth' : auth_key };\n\n            // Make sure we have a Channel\n            if (!callback)      return error('Missing Callback');\n            if (!SUBSCRIBE_KEY) return error('Missing Subscribe Key');\n\n            if (jsonp != '0') { data['callback'] = jsonp; }\n\n            xdr({\n                callback : jsonp,\n                data     : _get_url_params(data),\n                success  : function(response) {\n                    _invoke_callback(response, callback, err);\n                },\n                fail     : function(response) {\n                    _invoke_error(response, err);\n                },\n                url      : [\n                    STD_ORIGIN, 'v2', 'presence',\n                    'sub_key', SUBSCRIBE_KEY,\n                    'uuid', encode(uuid)\n                ]\n            });\n        },\n\n        'state' : function(args, callback) {\n            var callback = args['callback'] || callback || function(r) {}\n            ,   err      = args['error']    || function(){}\n            ,   auth_key = args['auth_key'] || AUTH_KEY\n            ,   jsonp    = jsonp_cb()\n            ,   state    = args['state']\n            ,   uuid     = args['uuid'] || UUID\n            ,   channel  = args['channel']\n            ,   url\n            ,   data     = _get_url_params({ 'auth' : auth_key });\n\n            // Make sure we have a Channel\n            if (!SUBSCRIBE_KEY) return error('Missing Subscribe Key');\n            if (!uuid) return error('Missing UUID');\n            if (!channel) return error('Missing Channel');\n\n            if (jsonp != '0') { data['callback'] = jsonp; }\n\n            if (CHANNELS[channel] && CHANNELS[channel].subscribed) STATE[channel] = state;\n\n            data['state'] = JSON.stringify(state);\n\n            if (state) {\n                url      = [\n                    STD_ORIGIN, 'v2', 'presence',\n                    'sub-key', SUBSCRIBE_KEY,\n                    'channel', encode(channel),\n                    'uuid', uuid, 'data'\n                ]\n            } else {\n                url      = [\n                    STD_ORIGIN, 'v2', 'presence',\n                    'sub-key', SUBSCRIBE_KEY,\n                    'channel', encode(channel),\n                    'uuid', encode(uuid)\n                ]\n            }\n\n            xdr({\n                callback : jsonp,\n                data     : _get_url_params(data),\n                success  : function(response) {\n                    _invoke_callback(response, callback, err);\n                },\n                fail     : function(response) {\n                    _invoke_error(response, err);\n                },\n                url      : url\n\n            });\n\n        },\n\n        /*\n            PUBNUB.grant({\n                channel  : 'my_chat',\n                callback : fun,\n                error    : fun,\n                ttl      : 24 * 60, // Minutes\n                read     : true,\n                write    : true,\n                auth_key : '3y8uiajdklytowsj'\n            });\n        */\n        'grant' : function( args, callback ) {\n            var callback = args['callback'] || callback\n            ,   err      = args['error']    || function(){}\n            ,   channel  = args['channel']\n            ,   jsonp    = jsonp_cb()\n            ,   ttl      = args['ttl']\n            ,   r        = (args['read'] )?\"1\":\"0\"\n            ,   w        = (args['write'])?\"1\":\"0\"\n            ,   auth_key = args['auth_key'];\n\n            // Make sure we have a Channel\n            if (!channel)       return error('Missing Channel');\n            if (!callback)      return error('Missing Callback');\n            if (!SUBSCRIBE_KEY) return error('Missing Subscribe Key');\n            if (!PUBLISH_KEY)   return error('Missing Publish Key');\n            if (!SECRET_KEY)    return error('Missing Secret Key');\n\n            var timestamp  = Math.floor(new Date().getTime() / 1000)\n            ,   sign_input = SUBSCRIBE_KEY + \"\\n\" + PUBLISH_KEY + \"\\n\"\n                    + \"grant\" + \"\\n\";\n\n            var data = {\n                'w'         : w,\n                'r'         : r,\n                'channel'   : channel,\n                'timestamp' : timestamp\n            };\n\n            if (jsonp != '0') { data['callback'] = jsonp; }\n            if (ttl || ttl === 0) data['ttl'] = ttl;\n            if (auth_key) data['auth'] = auth_key;\n\n            data = _get_url_params(data)\n\n            sign_input += _get_pam_sign_input_from_params(data);\n\n            var signature = hmac_SHA256( sign_input, SECRET_KEY );\n\n            signature = signature.replace( /\\+/g, \"-\" );\n            signature = signature.replace( /\\//g, \"_\" );\n\n            data['signature'] = signature;\n\n            xdr({\n                callback : jsonp,\n                data     : data,\n                success  : function(response) {\n                    _invoke_callback(response, callback, err);\n                },\n                fail     : function(response) {\n                    _invoke_error(response, err);\n                },\n                url      : [\n                    STD_ORIGIN, 'v1', 'auth', 'grant' ,\n                    'sub-key', SUBSCRIBE_KEY\n                ]\n            });\n        },\n\n        /*\n            PUBNUB.audit({\n                channel  : 'my_chat',\n                callback : fun,\n                error    : fun,\n                read     : true,\n                write    : true,\n                auth_key : '3y8uiajdklytowsj'\n            });\n        */\n        'audit' : function( args, callback ) {\n            var callback = args['callback'] || callback\n            ,   err      = args['error']    || function(){}\n            ,   channel  = args['channel']\n            ,   auth_key = args['auth_key']\n            ,   jsonp    = jsonp_cb();\n\n            // Make sure we have a Channel\n            if (!callback)      return error('Missing Callback');\n            if (!SUBSCRIBE_KEY) return error('Missing Subscribe Key');\n            if (!PUBLISH_KEY)   return error('Missing Publish Key');\n            if (!SECRET_KEY)    return error('Missing Secret Key');\n\n            var timestamp  = Math.floor(new Date().getTime() / 1000)\n            ,   sign_input = SUBSCRIBE_KEY + \"\\n\"\n                + PUBLISH_KEY + \"\\n\"\n                + \"audit\" + \"\\n\";\n\n            var data = {'timestamp' : timestamp };\n            if (jsonp != '0') { data['callback'] = jsonp; }\n            if (channel)  data['channel'] = channel;\n            if (auth_key) data['auth']    = auth_key;    \n\n            data = _get_url_params(data)\n\n            sign_input += _get_pam_sign_input_from_params(data);\n\n            var signature = hmac_SHA256( sign_input, SECRET_KEY );\n\n            signature = signature.replace( /\\+/g, \"-\" );\n            signature = signature.replace( /\\//g, \"_\" );\n\n            data['signature'] = signature;\n            xdr({\n                callback : jsonp,\n                data     : data,\n                success  : function(response) {\n                    _invoke_callback(response, callback, err);\n                },\n                fail     : function(response) {\n                    _invoke_error(response, err);\n                },\n                url      : [\n                    STD_ORIGIN, 'v1', 'auth', 'audit' ,\n                    'sub-key', SUBSCRIBE_KEY\n                ]\n            });\n        },\n\n        /*\n            PUBNUB.revoke({\n                channel  : 'my_chat',\n                callback : fun,\n                error    : fun,\n                auth_key : '3y8uiajdklytowsj'\n            });\n        */\n        'revoke' : function( args, callback ) {\n            args['read']  = false;\n            args['write'] = false;\n            SELF['grant']( args, callback );\n        },\n        'set_uuid' : function(uuid) {\n            UUID = uuid;\n            CONNECT();\n        },\n        'get_uuid' : function() {\n            return UUID;\n        },\n        'presence_heartbeat' : function(args) {\n            var callback = args['callback'] || function() {}\n            var err      = args['error']    || function() {}\n            var jsonp    = jsonp_cb();\n            var data     = { 'uuid' : UUID, 'auth' : AUTH_KEY };\n\n            var st = JSON['stringify'](STATE);\n            if (st.length > 2) data['state'] = JSON['stringify'](STATE);\n\n            if (PRESENCE_HB > 0 && PRESENCE_HB < 320) data['heartbeat'] = PRESENCE_HB;\n\n            xdr({\n                callback : jsonp,\n                data     : _get_url_params(data),\n                timeout  : SECOND * 5,\n                url      : [\n                    STD_ORIGIN, 'v2', 'presence',\n                    'sub-key', SUBSCRIBE_KEY,\n                    'channel' , encode(generate_channel_list(CHANNELS, true)['join'](',')),\n                    'heartbeat'\n                ],\n                success  : function(response) {\n                    _invoke_callback(response, callback, err);\n                },\n                fail     : function(response) { _invoke_error(response, err); }\n            });\n        },\n\n        // Expose PUBNUB Functions\n        'xdr'           : xdr,\n        'ready'         : ready,\n        'db'            : db,\n        'uuid'          : uuid,\n        'map'           : map,\n        'each'          : each,\n        'each-channel'  : each_channel,\n        'grep'          : grep,\n        'offline'       : function(){_reset_offline(1, { \"message\":\"Offline. Please check your network settings.\" })},\n        'supplant'      : supplant,\n        'now'           : rnow,\n        'unique'        : unique,\n        'updater'       : updater\n    };\n\n    function _poll_online() {\n        _is_online() || _reset_offline( 1, {\n            \"error\" : \"Offline. Please check your network settings. \"\n        });\n        timeout( _poll_online, SECOND );\n    }\n\n    function _poll_online2() {\n        SELF['time'](function(success){\n            detect_time_detla( function(){}, success );\n            success || _reset_offline( 1, {\n                \"error\" : \"Heartbeat failed to connect to Pubnub Servers.\" +\n                    \"Please check your network settings.\"\n                });\n            timeout( _poll_online2, KEEPALIVE );\n        });\n    }\n\n    function _reset_offline(err, msg) {\n        SUB_RECEIVER && SUB_RECEIVER(err, msg);\n        SUB_RECEIVER = null;\n    }\n\n    if (!UUID) UUID = SELF['uuid']();\n    db['set']( SUBSCRIBE_KEY + 'uuid', UUID );\n\n    timeout( _poll_online,  SECOND    );\n    timeout( _poll_online2, KEEPALIVE );\n    PRESENCE_HB_TIMEOUT = timeout( start_presence_heartbeat, ( PRESENCE_HB_INTERVAL - 3 ) * SECOND ) ;\n\n    // Detect Age of Message\n    function detect_latency(tt) {\n        var adjusted_time = rnow() - TIME_DRIFT;\n        return adjusted_time - tt / 10000;\n    }\n\n    detect_time_detla();\n    function detect_time_detla( cb, time ) {\n        var stime = rnow();\n\n        time && calculate(time) || SELF['time'](calculate);\n\n        function calculate(time) {\n            if (!time) return;\n            var ptime   = time / 10000\n            ,   latency = (rnow() - stime) / 2;\n            TIME_DRIFT = rnow() - (ptime + latency);\n            cb && cb(TIME_DRIFT);\n        }\n    }\n\n    return SELF;\n}\n\nvar CRYPTO = (function(){\n    var Nr = 14,\n    /* Default to 256 Bit Encryption */\n    Nk = 8,\n    Decrypt = false,\n\n    enc_utf8 = function(s)\n    {\n        try {\n            return unescape(encodeURIComponent(s));\n        }\n        catch(e) {\n            throw 'Error on UTF-8 encode';\n        }\n    },\n\n    dec_utf8 = function(s)\n    {\n        try {\n            return decodeURIComponent(escape(s));\n        }\n        catch(e) {\n            throw ('Bad Key');\n        }\n    },\n\n    padBlock = function(byteArr)\n    {\n        var array = [], cpad, i;\n        if (byteArr.length < 16) {\n            cpad = 16 - byteArr.length;\n            array = [cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad, cpad];\n        }\n        for (i = 0; i < byteArr.length; i++)\n        {\n            array[i] = byteArr[i];\n        }\n        return array;\n    },\n\n    block2s = function(block, lastBlock)\n    {\n        var string = '', padding, i;\n        if (lastBlock) {\n            padding = block[15];\n            if (padding > 16) {\n                throw ('Decryption error: Maybe bad key');\n            }\n            if (padding == 16) {\n                return '';\n            }\n            for (i = 0; i < 16 - padding; i++) {\n                string += String.fromCharCode(block[i]);\n            }\n        } else {\n            for (i = 0; i < 16; i++) {\n                string += String.fromCharCode(block[i]);\n            }\n        }\n        return string;\n    },\n\n    a2h = function(numArr)\n    {\n        var string = '', i;\n        for (i = 0; i < numArr.length; i++) {\n            string += (numArr[i] < 16 ? '0': '') + numArr[i].toString(16);\n        }\n        return string;\n    },\n\n    h2a = function(s)\n    {\n        var ret = [];\n        s.replace(/(..)/g,\n        function(s) {\n            ret.push(parseInt(s, 16));\n        });\n        return ret;\n    },\n\n    s2a = function(string, binary) {\n        var array = [], i;\n\n        if (! binary) {\n            string = enc_utf8(string);\n        }\n\n        for (i = 0; i < string.length; i++)\n        {\n            array[i] = string.charCodeAt(i);\n        }\n\n        return array;\n    },\n\n    size = function(newsize)\n    {\n        switch (newsize)\n        {\n        case 128:\n            Nr = 10;\n            Nk = 4;\n            break;\n        case 192:\n            Nr = 12;\n            Nk = 6;\n            break;\n        case 256:\n            Nr = 14;\n            Nk = 8;\n            break;\n        default:\n            throw ('Invalid Key Size Specified:' + newsize);\n        }\n    },\n\n    randArr = function(num) {\n        var result = [], i;\n        for (i = 0; i < num; i++) {\n            result = result.concat(Math.floor(Math.random() * 256));\n        }\n        return result;\n    },\n\n    openSSLKey = function(passwordArr, saltArr) {\n        // Number of rounds depends on the size of the AES in use\n        // 3 rounds for 256\n        //        2 rounds for the key, 1 for the IV\n        // 2 rounds for 128\n        //        1 round for the key, 1 round for the IV\n        // 3 rounds for 192 since it's not evenly divided by 128 bits\n        var rounds = Nr >= 12 ? 3: 2,\n        key = [],\n        iv = [],\n        md5_hash = [],\n        result = [],\n        data00 = passwordArr.concat(saltArr),\n        i;\n        md5_hash[0] = GibberishAES.Hash.MD5(data00);\n        result = md5_hash[0];\n        for (i = 1; i < rounds; i++) {\n            md5_hash[i] = GibberishAES.Hash.MD5(md5_hash[i - 1].concat(data00));\n            result = result.concat(md5_hash[i]);\n        }\n        key = result.slice(0, 4 * Nk);\n        iv = result.slice(4 * Nk, 4 * Nk + 16);\n        return {\n            key: key,\n            iv: iv\n        };\n    },\n\n    rawEncrypt = function(plaintext, key, iv) {\n        // plaintext, key and iv as byte arrays\n        key = expandKey(key);\n        var numBlocks = Math.ceil(plaintext.length / 16),\n        blocks = [],\n        i,\n        cipherBlocks = [];\n        for (i = 0; i < numBlocks; i++) {\n            blocks[i] = padBlock(plaintext.slice(i * 16, i * 16 + 16));\n        }\n        if (plaintext.length % 16 === 0) {\n            blocks.push([16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]);\n            // CBC OpenSSL padding scheme\n            numBlocks++;\n        }\n        for (i = 0; i < blocks.length; i++) {\n            blocks[i] = (i === 0) ? xorBlocks(blocks[i], iv) : xorBlocks(blocks[i], cipherBlocks[i - 1]);\n            cipherBlocks[i] = encryptBlock(blocks[i], key);\n        }\n        return cipherBlocks;\n    },\n\n    rawDecrypt = function(cryptArr, key, iv, binary) {\n        //  cryptArr, key and iv as byte arrays\n        key = expandKey(key);\n        var numBlocks = cryptArr.length / 16,\n        cipherBlocks = [],\n        i,\n        plainBlocks = [],\n        string = '';\n        for (i = 0; i < numBlocks; i++) {\n            cipherBlocks.push(cryptArr.slice(i * 16, (i + 1) * 16));\n        }\n        for (i = cipherBlocks.length - 1; i >= 0; i--) {\n            plainBlocks[i] = decryptBlock(cipherBlocks[i], key);\n            plainBlocks[i] = (i === 0) ? xorBlocks(plainBlocks[i], iv) : xorBlocks(plainBlocks[i], cipherBlocks[i - 1]);\n        }\n        for (i = 0; i < numBlocks - 1; i++) {\n            string += block2s(plainBlocks[i]);\n        }\n        string += block2s(plainBlocks[i], true);\n        return binary ? string : dec_utf8(string);\n    },\n\n    encryptBlock = function(block, words) {\n        Decrypt = false;\n        var state = addRoundKey(block, words, 0),\n        round;\n        for (round = 1; round < (Nr + 1); round++) {\n            state = subBytes(state);\n            state = shiftRows(state);\n            if (round < Nr) {\n                state = mixColumns(state);\n            }\n            //last round? don't mixColumns\n            state = addRoundKey(state, words, round);\n        }\n\n        return state;\n    },\n\n    decryptBlock = function(block, words) {\n        Decrypt = true;\n        var state = addRoundKey(block, words, Nr),\n        round;\n        for (round = Nr - 1; round > -1; round--) {\n            state = shiftRows(state);\n            state = subBytes(state);\n            state = addRoundKey(state, words, round);\n            if (round > 0) {\n                state = mixColumns(state);\n            }\n            //last round? don't mixColumns\n        }\n\n        return state;\n    },\n\n    subBytes = function(state) {\n        var S = Decrypt ? SBoxInv: SBox,\n        temp = [],\n        i;\n        for (i = 0; i < 16; i++) {\n            temp[i] = S[state[i]];\n        }\n        return temp;\n    },\n\n    shiftRows = function(state) {\n        var temp = [],\n        shiftBy = Decrypt ? [0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3] : [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11],\n        i;\n        for (i = 0; i < 16; i++) {\n            temp[i] = state[shiftBy[i]];\n        }\n        return temp;\n    },\n\n    mixColumns = function(state) {\n        var t = [],\n        c;\n        if (!Decrypt) {\n            for (c = 0; c < 4; c++) {\n                t[c * 4] = G2X[state[c * 4]] ^ G3X[state[1 + c * 4]] ^ state[2 + c * 4] ^ state[3 + c * 4];\n                t[1 + c * 4] = state[c * 4] ^ G2X[state[1 + c * 4]] ^ G3X[state[2 + c * 4]] ^ state[3 + c * 4];\n                t[2 + c * 4] = state[c * 4] ^ state[1 + c * 4] ^ G2X[state[2 + c * 4]] ^ G3X[state[3 + c * 4]];\n                t[3 + c * 4] = G3X[state[c * 4]] ^ state[1 + c * 4] ^ state[2 + c * 4] ^ G2X[state[3 + c * 4]];\n            }\n        }else {\n            for (c = 0; c < 4; c++) {\n                t[c*4] = GEX[state[c*4]] ^ GBX[state[1+c*4]] ^ GDX[state[2+c*4]] ^ G9X[state[3+c*4]];\n                t[1+c*4] = G9X[state[c*4]] ^ GEX[state[1+c*4]] ^ GBX[state[2+c*4]] ^ GDX[state[3+c*4]];\n                t[2+c*4] = GDX[state[c*4]] ^ G9X[state[1+c*4]] ^ GEX[state[2+c*4]] ^ GBX[state[3+c*4]];\n                t[3+c*4] = GBX[state[c*4]] ^ GDX[state[1+c*4]] ^ G9X[state[2+c*4]] ^ GEX[state[3+c*4]];\n            }\n        }\n\n        return t;\n    },\n\n    addRoundKey = function(state, words, round) {\n        var temp = [],\n        i;\n        for (i = 0; i < 16; i++) {\n            temp[i] = state[i] ^ words[round][i];\n        }\n        return temp;\n    },\n\n    xorBlocks = function(block1, block2) {\n        var temp = [],\n        i;\n        for (i = 0; i < 16; i++) {\n            temp[i] = block1[i] ^ block2[i];\n        }\n        return temp;\n    },\n\n    expandKey = function(key) {\n        // Expects a 1d number array\n        var w = [],\n        temp = [],\n        i,\n        r,\n        t,\n        flat = [],\n        j;\n\n        for (i = 0; i < Nk; i++) {\n            r = [key[4 * i], key[4 * i + 1], key[4 * i + 2], key[4 * i + 3]];\n            w[i] = r;\n        }\n\n        for (i = Nk; i < (4 * (Nr + 1)); i++) {\n            w[i] = [];\n            for (t = 0; t < 4; t++) {\n                temp[t] = w[i - 1][t];\n            }\n            if (i % Nk === 0) {\n                temp = subWord(rotWord(temp));\n                temp[0] ^= Rcon[i / Nk - 1];\n            } else if (Nk > 6 && i % Nk == 4) {\n                temp = subWord(temp);\n            }\n            for (t = 0; t < 4; t++) {\n                w[i][t] = w[i - Nk][t] ^ temp[t];\n            }\n        }\n        for (i = 0; i < (Nr + 1); i++) {\n            flat[i] = [];\n            for (j = 0; j < 4; j++) {\n                flat[i].push(w[i * 4 + j][0], w[i * 4 + j][1], w[i * 4 + j][2], w[i * 4 + j][3]);\n            }\n        }\n        return flat;\n    },\n\n    subWord = function(w) {\n        // apply SBox to 4-byte word w\n        for (var i = 0; i < 4; i++) {\n            w[i] = SBox[w[i]];\n        }\n        return w;\n    },\n\n    rotWord = function(w) {\n        // rotate 4-byte word w left by one byte\n        var tmp = w[0],\n        i;\n        for (i = 0; i < 4; i++) {\n            w[i] = w[i + 1];\n        }\n        w[3] = tmp;\n        return w;\n    },\n\n// jlcooke: 2012-07-12: added strhex + invertArr to compress G2X/G3X/G9X/GBX/GEX/SBox/SBoxInv/Rcon saving over 7KB, and added encString, decString\n    strhex = function(str,size) {\n        var ret = [];\n        for (i=0; i<str.length; i+=size)\n            ret[i/size] = parseInt(str.substr(i,size), 16);\n        return ret;\n    },\n    invertArr = function(arr) {\n        var ret = [];\n        for (i=0; i<arr.length; i++)\n            ret[arr[i]] = i;\n        return ret;\n    },\n    Gxx = function(a, b) {\n        var i, ret;\n\n        ret = 0;\n        for (i=0; i<8; i++) {\n            ret = ((b&1)==1) ? ret^a : ret;\n            /* xmult */\n            a = (a>0x7f) ? 0x11b^(a<<1) : (a<<1);\n            b >>>= 1;\n        }\n\n        return ret;\n    },\n    Gx = function(x) {\n        var r = [];\n        for (var i=0; i<256; i++)\n            r[i] = Gxx(x, i);\n        return r;\n    },\n\n    // S-box\n/*\n    SBox = [\n    99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171,\n    118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164,\n    114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113,\n    216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226,\n    235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214,\n    179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,\n    190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69,\n    249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245,\n    188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68,\n    23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42,\n    144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73,\n    6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109,\n    141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37,\n    46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,\n    181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225,\n    248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,\n    140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187,\n    22], //*/ SBox = strhex('637c777bf26b6fc53001672bfed7ab76ca82c97dfa5947f0add4a2af9ca472c0b7fd9326363ff7cc34a5e5f171d8311504c723c31896059a071280e2eb27b27509832c1a1b6e5aa0523bd6b329e32f8453d100ed20fcb15b6acbbe394a4c58cfd0efaafb434d338545f9027f503c9fa851a3408f929d38f5bcb6da2110fff3d2cd0c13ec5f974417c4a77e3d645d197360814fdc222a908846eeb814de5e0bdbe0323a0a4906245cc2d3ac629195e479e7c8376d8dd54ea96c56f4ea657aae08ba78252e1ca6b4c6e8dd741f4bbd8b8a703eb5664803f60e613557b986c11d9ee1f8981169d98e949b1e87e9ce5528df8ca1890dbfe6426841992d0fb054bb16',2),\n\n    // Precomputed lookup table for the inverse SBox\n/*    SBoxInv = [\n    82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215,\n    251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222,\n    233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66,\n    250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73,\n    109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92,\n    204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21,\n    70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247,\n    228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2,\n    193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220,\n    234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173,\n    53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29,\n    41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75,\n    198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168,\n    51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81,\n    127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160,\n    224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,\n    23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12,\n    125], //*/ SBoxInv = invertArr(SBox),\n\n    // Rijndael Rcon\n/*\n    Rcon = [1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94,\n    188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145],\n//*/ Rcon = strhex('01020408102040801b366cd8ab4d9a2f5ebc63c697356ad4b37dfaefc591',2),\n\n/*\n    G2X = [\n    0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16,\n    0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,\n    0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46,\n    0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,\n    0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76,\n    0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,\n    0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6,\n    0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,\n    0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6,\n    0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,\n    0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d,\n    0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,\n    0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d,\n    0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55,\n    0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d,\n    0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,\n    0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d,\n    0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5,\n    0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd,\n    0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,\n    0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed,\n    0xe3, 0xe1, 0xe7, 0xe5\n    ], //*/ G2X = Gx(2),\n\n/*    G3X = [\n    0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d,\n    0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39,\n    0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65,\n    0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,\n    0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d,\n    0x44, 0x47, 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9,\n    0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, 0xf6, 0xf5,\n    0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,\n    0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd,\n    0xb4, 0xb7, 0xb2, 0xb1, 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99,\n    0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9b, 0x98, 0x9d, 0x9e,\n    0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,\n    0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6,\n    0xbf, 0xbc, 0xb9, 0xba, 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2,\n    0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 0xcb, 0xc8, 0xcd, 0xce,\n    0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,\n    0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46,\n    0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62,\n    0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e,\n    0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,\n    0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16,\n    0x1f, 0x1c, 0x19, 0x1a\n    ], //*/ G3X = Gx(3),\n\n/*\n    G9X = [\n    0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53,\n    0x6c, 0x65, 0x7e, 0x77, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,\n    0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3b, 0x32, 0x29, 0x20,\n    0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,\n    0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8,\n    0xc7, 0xce, 0xd5, 0xdc, 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,\n    0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 0xe6, 0xef, 0xf4, 0xfd,\n    0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,\n    0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e,\n    0x21, 0x28, 0x33, 0x3a, 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,\n    0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 0xec, 0xe5, 0xfe, 0xf7,\n    0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,\n    0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f,\n    0x10, 0x19, 0x02, 0x0b, 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,\n    0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 0x47, 0x4e, 0x55, 0x5c,\n    0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,\n    0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9,\n    0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,\n    0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba,\n    0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,\n    0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62,\n    0x5d, 0x54, 0x4f, 0x46\n    ], //*/ G9X = Gx(9),\n\n/*    GBX = [\n    0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45,\n    0x74, 0x7f, 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,\n    0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7b, 0x70, 0x6d, 0x66,\n    0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,\n    0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, ,0x85, 0x8e,\n    0xbf, 0xb4, 0xa9, 0xa2, 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,\n    0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 0x46, 0x4d, 0x50, 0x5b,\n    0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,\n    0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8,\n    0xf9, 0xf2, 0xef, 0xe4, 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,\n    0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 0xf7, 0xfc, 0xe1, 0xea,\n    0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,\n    0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02,\n    0x33, 0x38, 0x25, 0x2e, 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,\n    0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 0x3c, 0x37, 0x2a, 0x21,\n    0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,\n    0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44,\n    0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,\n    0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67,\n    0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,\n    0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f,\n    0xbe, 0xb5, 0xa8, 0xa3\n    ], //*/ GBX = Gx(0xb),\n\n/*\n    GDX = [\n    0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f,\n    0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,\n    0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xbb, 0xb6, 0xa1, 0xac,\n    0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,\n    0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14,\n    0x37, 0x3a, 0x2d, 0x20, 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,\n    0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 0xbd, 0xb0, 0xa7, 0xaa,\n    0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,\n    0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9,\n    0x8a, 0x87, 0x90, 0x9d, 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,\n    0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 0xda, 0xd7, 0xc0, 0xcd,\n    0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,\n    0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75,\n    0x56, 0x5b, 0x4c, 0x41, 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,\n    0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 0xb1, 0xbc, 0xab, 0xa6,\n    0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,\n    0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8,\n    0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,\n    0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b,\n    0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,\n    0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3,\n    0x80, 0x8d, 0x9a, 0x97\n    ], //*/ GDX = Gx(0xd),\n\n/*\n    GEX = [\n    0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62,\n    0x48, 0x46, 0x54, 0x5a, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,\n    0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdb, 0xd5, 0xc7, 0xc9,\n    0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,\n    0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59,\n    0x73, 0x7d, 0x6f, 0x61, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,\n    0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 0x4d, 0x43, 0x51, 0x5f,\n    0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,\n    0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14,\n    0x3e, 0x30, 0x22, 0x2c, 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,\n    0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 0x41, 0x4f, 0x5d, 0x53,\n    0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,\n    0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3,\n    0xe9, 0xe7, 0xf5, 0xfb, 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,\n    0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 0x7a, 0x74, 0x66, 0x68,\n    0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,\n    0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e,\n    0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,\n    0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25,\n    0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,\n    0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5,\n    0x9f, 0x91, 0x83, 0x8d\n    ], //*/ GEX = Gx(0xe),\n\n    enc = function(string, pass, binary) {\n        // string, password in plaintext\n        var salt = randArr(8),\n        pbe = openSSLKey(s2a(pass, binary), salt),\n        key = pbe.key,\n        iv = pbe.iv,\n        cipherBlocks,\n        saltBlock = [[83, 97, 108, 116, 101, 100, 95, 95].concat(salt)];\n        string = s2a(string, binary);\n        cipherBlocks = rawEncrypt(string, key, iv);\n        // Spells out 'Salted__'\n        cipherBlocks = saltBlock.concat(cipherBlocks);\n        return Base64.encode(cipherBlocks);\n    },\n\n    dec = function(string, pass, binary) {\n        // string, password in plaintext\n        var cryptArr = Base64.decode(string),\n        salt = cryptArr.slice(8, 16),\n        pbe = openSSLKey(s2a(pass, binary), salt),\n        key = pbe.key,\n        iv = pbe.iv;\n        cryptArr = cryptArr.slice(16, cryptArr.length);\n        // Take off the Salted__ffeeddcc\n        string = rawDecrypt(cryptArr, key, iv, binary);\n        return string;\n    },\n\n    MD5 = function(numArr) {\n\n        function rotateLeft(lValue, iShiftBits) {\n            return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));\n        }\n\n        function addUnsigned(lX, lY) {\n            var lX4,\n            lY4,\n            lX8,\n            lY8,\n            lResult;\n            lX8 = (lX & 0x80000000);\n            lY8 = (lY & 0x80000000);\n            lX4 = (lX & 0x40000000);\n            lY4 = (lY & 0x40000000);\n            lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);\n            if (lX4 & lY4) {\n                return (lResult ^ 0x80000000 ^ lX8 ^ lY8);\n            }\n            if (lX4 | lY4) {\n                if (lResult & 0x40000000) {\n                    return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);\n                } else {\n                    return (lResult ^ 0x40000000 ^ lX8 ^ lY8);\n                }\n            } else {\n                return (lResult ^ lX8 ^ lY8);\n            }\n        }\n\n        function f(x, y, z) {\n            return (x & y) | ((~x) & z);\n        }\n        function g(x, y, z) {\n            return (x & z) | (y & (~z));\n        }\n        function h(x, y, z) {\n            return (x ^ y ^ z);\n        }\n        function funcI(x, y, z) {\n            return (y ^ (x | (~z)));\n        }\n\n        function ff(a, b, c, d, x, s, ac) {\n            a = addUnsigned(a, addUnsigned(addUnsigned(f(b, c, d), x), ac));\n            return addUnsigned(rotateLeft(a, s), b);\n        }\n\n        function gg(a, b, c, d, x, s, ac) {\n            a = addUnsigned(a, addUnsigned(addUnsigned(g(b, c, d), x), ac));\n            return addUnsigned(rotateLeft(a, s), b);\n        }\n\n        function hh(a, b, c, d, x, s, ac) {\n            a = addUnsigned(a, addUnsigned(addUnsigned(h(b, c, d), x), ac));\n            return addUnsigned(rotateLeft(a, s), b);\n        }\n\n        function ii(a, b, c, d, x, s, ac) {\n            a = addUnsigned(a, addUnsigned(addUnsigned(funcI(b, c, d), x), ac));\n            return addUnsigned(rotateLeft(a, s), b);\n        }\n\n        function convertToWordArray(numArr) {\n            var lWordCount,\n            lMessageLength = numArr.length,\n            lNumberOfWords_temp1 = lMessageLength + 8,\n            lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64,\n            lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16,\n            lWordArray = [],\n            lBytePosition = 0,\n            lByteCount = 0;\n            while (lByteCount < lMessageLength) {\n                lWordCount = (lByteCount - (lByteCount % 4)) / 4;\n                lBytePosition = (lByteCount % 4) * 8;\n                lWordArray[lWordCount] = (lWordArray[lWordCount] | (numArr[lByteCount] << lBytePosition));\n                lByteCount++;\n            }\n            lWordCount = (lByteCount - (lByteCount % 4)) / 4;\n            lBytePosition = (lByteCount % 4) * 8;\n            lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);\n            lWordArray[lNumberOfWords - 2] = lMessageLength << 3;\n            lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;\n            return lWordArray;\n        }\n\n        function wordToHex(lValue) {\n            var lByte,\n            lCount,\n            wordToHexArr = [];\n            for (lCount = 0; lCount <= 3; lCount++) {\n                lByte = (lValue >>> (lCount * 8)) & 255;\n                wordToHexArr = wordToHexArr.concat(lByte);\n             }\n            return wordToHexArr;\n        }\n\n        /*function utf8Encode(string) {\n            string = string.replace(/\\r\\n/g, \"\\n\");\n            var utftext = \"\",\n            n,\n            c;\n\n            for (n = 0; n < string.length; n++) {\n\n                c = string.charCodeAt(n);\n\n                if (c < 128) {\n                    utftext += String.fromCharCode(c);\n                }\n                else if ((c > 127) && (c < 2048)) {\n                    utftext += String.fromCharCode((c >> 6) | 192);\n                    utftext += String.fromCharCode((c & 63) | 128);\n                }\n                else {\n                    utftext += String.fromCharCode((c >> 12) | 224);\n                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);\n                    utftext += String.fromCharCode((c & 63) | 128);\n                }\n\n            }\n\n            return utftext;\n        }*/\n\n        var x = [],\n        k,\n        AA,\n        BB,\n        CC,\n        DD,\n        a,\n        b,\n        c,\n        d,\n        rnd = strhex('67452301efcdab8998badcfe10325476d76aa478e8c7b756242070dbc1bdceeef57c0faf4787c62aa8304613fd469501698098d88b44f7afffff5bb1895cd7be6b901122fd987193a679438e49b40821f61e2562c040b340265e5a51e9b6c7aad62f105d02441453d8a1e681e7d3fbc821e1cde6c33707d6f4d50d87455a14eda9e3e905fcefa3f8676f02d98d2a4c8afffa39428771f6816d9d6122fde5380ca4beea444bdecfa9f6bb4b60bebfbc70289b7ec6eaa127fad4ef308504881d05d9d4d039e6db99e51fa27cf8c4ac5665f4292244432aff97ab9423a7fc93a039655b59c38f0ccc92ffeff47d85845dd16fa87e4ffe2ce6e0a30143144e0811a1f7537e82bd3af2352ad7d2bbeb86d391',8);\n\n        x = convertToWordArray(numArr);\n\n        a = rnd[0];\n        b = rnd[1];\n        c = rnd[2];\n        d = rnd[3]\n\n        for (k = 0; k < x.length; k += 16) {\n            AA = a;\n            BB = b;\n            CC = c;\n            DD = d;\n            a = ff(a, b, c, d, x[k + 0], 7, rnd[4]);\n            d = ff(d, a, b, c, x[k + 1], 12, rnd[5]);\n            c = ff(c, d, a, b, x[k + 2], 17, rnd[6]);\n            b = ff(b, c, d, a, x[k + 3], 22, rnd[7]);\n            a = ff(a, b, c, d, x[k + 4], 7, rnd[8]);\n            d = ff(d, a, b, c, x[k + 5], 12, rnd[9]);\n            c = ff(c, d, a, b, x[k + 6], 17, rnd[10]);\n            b = ff(b, c, d, a, x[k + 7], 22, rnd[11]);\n            a = ff(a, b, c, d, x[k + 8], 7, rnd[12]);\n            d = ff(d, a, b, c, x[k + 9], 12, rnd[13]);\n            c = ff(c, d, a, b, x[k + 10], 17, rnd[14]);\n            b = ff(b, c, d, a, x[k + 11], 22, rnd[15]);\n            a = ff(a, b, c, d, x[k + 12], 7, rnd[16]);\n            d = ff(d, a, b, c, x[k + 13], 12, rnd[17]);\n            c = ff(c, d, a, b, x[k + 14], 17, rnd[18]);\n            b = ff(b, c, d, a, x[k + 15], 22, rnd[19]);\n            a = gg(a, b, c, d, x[k + 1], 5, rnd[20]);\n            d = gg(d, a, b, c, x[k + 6], 9, rnd[21]);\n            c = gg(c, d, a, b, x[k + 11], 14, rnd[22]);\n            b = gg(b, c, d, a, x[k + 0], 20, rnd[23]);\n            a = gg(a, b, c, d, x[k + 5], 5, rnd[24]);\n            d = gg(d, a, b, c, x[k + 10], 9, rnd[25]);\n            c = gg(c, d, a, b, x[k + 15], 14, rnd[26]);\n            b = gg(b, c, d, a, x[k + 4], 20, rnd[27]);\n            a = gg(a, b, c, d, x[k + 9], 5, rnd[28]);\n            d = gg(d, a, b, c, x[k + 14], 9, rnd[29]);\n            c = gg(c, d, a, b, x[k + 3], 14, rnd[30]);\n            b = gg(b, c, d, a, x[k + 8], 20, rnd[31]);\n            a = gg(a, b, c, d, x[k + 13], 5, rnd[32]);\n            d = gg(d, a, b, c, x[k + 2], 9, rnd[33]);\n            c = gg(c, d, a, b, x[k + 7], 14, rnd[34]);\n            b = gg(b, c, d, a, x[k + 12], 20, rnd[35]);\n            a = hh(a, b, c, d, x[k + 5], 4, rnd[36]);\n            d = hh(d, a, b, c, x[k + 8], 11, rnd[37]);\n            c = hh(c, d, a, b, x[k + 11], 16, rnd[38]);\n            b = hh(b, c, d, a, x[k + 14], 23, rnd[39]);\n            a = hh(a, b, c, d, x[k + 1], 4, rnd[40]);\n            d = hh(d, a, b, c, x[k + 4], 11, rnd[41]);\n            c = hh(c, d, a, b, x[k + 7], 16, rnd[42]);\n            b = hh(b, c, d, a, x[k + 10], 23, rnd[43]);\n            a = hh(a, b, c, d, x[k + 13], 4, rnd[44]);\n            d = hh(d, a, b, c, x[k + 0], 11, rnd[45]);\n            c = hh(c, d, a, b, x[k + 3], 16, rnd[46]);\n            b = hh(b, c, d, a, x[k + 6], 23, rnd[47]);\n            a = hh(a, b, c, d, x[k + 9], 4, rnd[48]);\n            d = hh(d, a, b, c, x[k + 12], 11, rnd[49]);\n            c = hh(c, d, a, b, x[k + 15], 16, rnd[50]);\n            b = hh(b, c, d, a, x[k + 2], 23, rnd[51]);\n            a = ii(a, b, c, d, x[k + 0], 6, rnd[52]);\n            d = ii(d, a, b, c, x[k + 7], 10, rnd[53]);\n            c = ii(c, d, a, b, x[k + 14], 15, rnd[54]);\n            b = ii(b, c, d, a, x[k + 5], 21, rnd[55]);\n            a = ii(a, b, c, d, x[k + 12], 6, rnd[56]);\n            d = ii(d, a, b, c, x[k + 3], 10, rnd[57]);\n            c = ii(c, d, a, b, x[k + 10], 15, rnd[58]);\n            b = ii(b, c, d, a, x[k + 1], 21, rnd[59]);\n            a = ii(a, b, c, d, x[k + 8], 6, rnd[60]);\n            d = ii(d, a, b, c, x[k + 15], 10, rnd[61]);\n            c = ii(c, d, a, b, x[k + 6], 15, rnd[62]);\n            b = ii(b, c, d, a, x[k + 13], 21, rnd[63]);\n            a = ii(a, b, c, d, x[k + 4], 6, rnd[64]);\n            d = ii(d, a, b, c, x[k + 11], 10, rnd[65]);\n            c = ii(c, d, a, b, x[k + 2], 15, rnd[66]);\n            b = ii(b, c, d, a, x[k + 9], 21, rnd[67]);\n            a = addUnsigned(a, AA);\n            b = addUnsigned(b, BB);\n            c = addUnsigned(c, CC);\n            d = addUnsigned(d, DD);\n        }\n\n        return wordToHex(a).concat(wordToHex(b), wordToHex(c), wordToHex(d));\n    },\n\n    encString = function(plaintext, key, iv) {\n        plaintext = s2a(plaintext);\n\n        key = s2a(key);\n        for (var i=key.length; i<32; i++)\n            key[i] = 0;\n\n        if (iv == null) {\n            iv = genIV();\n        } else {\n            iv = s2a(iv);\n            for (var i=iv.length; i<16; i++)\n                iv[i] = 0;\n        }\n\n        var ct = rawEncrypt(plaintext, key, iv);\n        var ret = [iv];\n        for (var i=0; i<ct.length; i++)\n            ret[ret.length] = ct[i];\n        return Base64.encode(ret);\n    },\n\n    decString = function(ciphertext, key) {\n        var tmp = Base64.decode(ciphertext);\n        var iv = tmp.slice(0, 16);\n        var ct = tmp.slice(16, tmp.length);\n\n        key = s2a(key);\n        for (var i=key.length; i<32; i++)\n            key[i] = 0;\n\n        var pt = rawDecrypt(ct, key, iv, false);\n        return pt;\n    },\n\n    Base64 = (function(){\n        // Takes a Nx16x1 byte array and converts it to Base64\n        var _chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',\n        chars = _chars.split(''),\n\n        encode = function(b, withBreaks) {\n            var flatArr = [],\n            b64 = '',\n            i,\n            broken_b64;\n            var totalChunks = Math.floor(b.length * 16 / 3);\n            for (i = 0; i < b.length * 16; i++) {\n                flatArr.push(b[Math.floor(i / 16)][i % 16]);\n            }\n            for (i = 0; i < flatArr.length; i = i + 3) {\n                b64 += chars[flatArr[i] >> 2];\n                b64 += chars[((flatArr[i] & 3) << 4) | (flatArr[i + 1] >> 4)];\n                if (! (flatArr[i + 1] === undefined)) {\n                    b64 += chars[((flatArr[i + 1] & 15) << 2) | (flatArr[i + 2] >> 6)];\n                } else {\n                    b64 += '=';\n                }\n                if (! (flatArr[i + 2] === undefined)) {\n                    b64 += chars[flatArr[i + 2] & 63];\n                } else {\n                    b64 += '=';\n                }\n            }\n            // OpenSSL is super particular about line breaks\n            broken_b64 = b64.slice(0, 64); // + '\\n';\n            for (i = 1; i < (Math['ceil'](b64.length / 64)); i++) {\n                broken_b64 += b64.slice(i * 64, i * 64 + 64) + (Math.ceil(b64.length / 64) == i + 1 ? '': '\\n');\n            }\n            return broken_b64;\n        },\n\n        decode = function(string) {\n            string = string['replace'](/\\n/g, '');\n            var flatArr = [],\n            c = [],\n            b = [],\n            i;\n            for (i = 0; i < string.length; i = i + 4) {\n                c[0] = _chars.indexOf(string.charAt(i));\n                c[1] = _chars.indexOf(string.charAt(i + 1));\n                c[2] = _chars.indexOf(string.charAt(i + 2));\n                c[3] = _chars.indexOf(string.charAt(i + 3));\n\n                b[0] = (c[0] << 2) | (c[1] >> 4);\n                b[1] = ((c[1] & 15) << 4) | (c[2] >> 2);\n                b[2] = ((c[2] & 3) << 6) | c[3];\n                flatArr.push(b[0], b[1], b[2]);\n            }\n            flatArr = flatArr.slice(0, flatArr.length - (flatArr.length % 16));\n            return flatArr;\n        };\n\n        //internet explorer\n        if(typeof Array.indexOf === \"function\") {\n            _chars = chars;\n        }\n\n        /*\n        //other way to solve internet explorer problem\n        if(!Array.indexOf){\n            Array.prototype.indexOf = function(obj){\n                for(var i=0; i<this.length; i++){\n                    if(this[i]===obj){\n                        return i;\n                    }\n                }\n                return -1;\n            }\n        }\n        */\n\n\n        return {\n            \"encode\": encode,\n            \"decode\": decode\n        };\n    })();\n\n    return {\n        \"size\": size,\n        \"h2a\":h2a,\n        \"expandKey\":expandKey,\n        \"encryptBlock\":encryptBlock,\n        \"decryptBlock\":decryptBlock,\n        \"Decrypt\":Decrypt,\n        \"s2a\":s2a,\n        \"rawEncrypt\":rawEncrypt,\n        \"rawDecrypt\":rawDecrypt,\n        \"dec\":dec,\n        \"openSSLKey\":openSSLKey,\n        \"a2h\":a2h,\n        \"enc\":enc,\n        \"Hash\":{\"MD5\":MD5},\n        \"Base64\":Base64\n    };\n\n})();\n\nfunction crypto_obj (){\n\n\nfunction SHA256(s) {\n\n    var chrsz = 8;\n    var hexcase = 0;\n\n    function safe_add(x, y) {\n        var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n        var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n        return (msw << 16) | (lsw & 0xFFFF);\n    }\n\n    function S(X, n) {\n        return ( X >>> n ) | (X << (32 - n));\n    }\n\n    function R(X, n) {\n        return ( X >>> n );\n    }\n\n    function Ch(x, y, z) {\n        return ((x & y) ^ ((~x) & z));\n    }\n\n    function Maj(x, y, z) {\n        return ((x & y) ^ (x & z) ^ (y & z));\n    }\n\n    function Sigma0256(x) {\n        return (S(x, 2) ^ S(x, 13) ^ S(x, 22));\n    }\n\n    function Sigma1256(x) {\n        return (S(x, 6) ^ S(x, 11) ^ S(x, 25));\n    }\n\n    function Gamma0256(x) {\n        return (S(x, 7) ^ S(x, 18) ^ R(x, 3));\n    }\n\n    function Gamma1256(x) {\n        return (S(x, 17) ^ S(x, 19) ^ R(x, 10));\n    }\n\n    function core_sha256(m, l) {\n        var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);\n        var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);\n        var W = new Array(64);\n        var a, b, c, d, e, f, g, h, i, j;\n        var T1, T2;\n\n        m[l >> 5] |= 0x80 << (24 - l % 32);\n        m[((l + 64 >> 9) << 4) + 15] = l;\n\n        for (var i = 0; i < m.length; i += 16) {\n            a = HASH[0];\n            b = HASH[1];\n            c = HASH[2];\n            d = HASH[3];\n            e = HASH[4];\n            f = HASH[5];\n            g = HASH[6];\n            h = HASH[7];\n\n            for (var j = 0; j < 64; j++) {\n                if (j < 16) W[j] = m[j + i];\n                else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);\n\n                T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);\n                T2 = safe_add(Sigma0256(a), Maj(a, b, c));\n\n                h = g;\n                g = f;\n                f = e;\n                e = safe_add(d, T1);\n                d = c;\n                c = b;\n                b = a;\n                a = safe_add(T1, T2);\n            }\n\n            HASH[0] = safe_add(a, HASH[0]);\n            HASH[1] = safe_add(b, HASH[1]);\n            HASH[2] = safe_add(c, HASH[2]);\n            HASH[3] = safe_add(d, HASH[3]);\n            HASH[4] = safe_add(e, HASH[4]);\n            HASH[5] = safe_add(f, HASH[5]);\n            HASH[6] = safe_add(g, HASH[6]);\n            HASH[7] = safe_add(h, HASH[7]);\n        }\n        return HASH;\n    }\n\n    function str2binb(str) {\n        var bin = Array();\n        var mask = (1 << chrsz) - 1;\n        for (var i = 0; i < str.length * chrsz; i += chrsz) {\n            bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i % 32);\n        }\n        return bin;\n    }\n\n    function Utf8Encode(string) {\n        string = string['replace'](/\\r\\n/g, \"\\n\");\n        var utftext = \"\";\n\n        for (var n = 0; n < string['length']; n++) {\n\n            var c = string.charCodeAt(n);\n\n            if (c < 128) {\n                utftext += String.fromCharCode(c);\n            }\n            else if ((c > 127) && (c < 2048)) {\n                utftext += String.fromCharCode((c >> 6) | 192);\n                utftext += String.fromCharCode((c & 63) | 128);\n            }\n            else {\n                utftext += String.fromCharCode((c >> 12) | 224);\n                utftext += String.fromCharCode(((c >> 6) & 63) | 128);\n                utftext += String.fromCharCode((c & 63) | 128);\n            }\n\n        }\n\n        return utftext;\n    }\n\n    function binb2hex(binarray) {\n        var hex_tab = hexcase ? \"0123456789ABCDEF\" : \"0123456789abcdef\";\n        var str = \"\";\n        for (var i = 0; i < binarray.length * 4; i++) {\n            str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +\n                hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8  )) & 0xF);\n        }\n        return str;\n    }\n\n    s = Utf8Encode(s);\n    return binb2hex(core_sha256(str2binb(s), s.length * chrsz));\n}\n    var crypto = CRYPTO;\n    crypto['size'](256);\n\n    var cipher_key = \"\";\n    var iv = crypto['s2a'](\"0123456789012345\");\n\n    return {\n\n        'encrypt' : function(data, key) {\n            if (!key) return data;\n            var cipher_key = crypto['s2a'](SHA256(key)['slice'](0,32));\n            var hex_message = crypto['s2a'](JSON['stringify'](data));\n            var encryptedHexArray = crypto['rawEncrypt'](hex_message, cipher_key, iv);\n            var base_64_encrypted = crypto['Base64']['encode'](encryptedHexArray);\n            return base_64_encrypted || data;\n        } ,\n\n        'decrypt' : function(data, key) {\n            if (!key) return data;\n            var cipher_key = crypto['s2a'](SHA256(key)['slice'](0,32));\n            try {\n                var binary_enc = crypto['Base64']['decode'](data);\n                var json_plain = crypto['rawDecrypt'](binary_enc, cipher_key, iv, false);\n                var plaintext = JSON['parse'](json_plain);\n                return plaintext;\n            }\n            catch (e) {\n                return undefined;\n            }\n        }\n    };\n}\n/* ---------------------------------------------------------------------------\n--------------------------------------------------------------------------- */\n\n/* ---------------------------------------------------------------------------\nPubNub Real-time Cloud-Hosted Push API and Push Notification Client Frameworks\nCopyright (c) 2011 PubNub Inc.\nhttp://www.pubnub.com/\nhttp://www.pubnub.com/terms\n--------------------------------------------------------------------------- */\n\n/* ---------------------------------------------------------------------------\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n--------------------------------------------------------------------------- */\n(function(){\n\n/**\n * UTIL LOCALS\n */\nvar NOW        = 1\n,    PNSDK      = 'PubNub-JS-' + 'Modern' + '/' + '3.6.4'\n,   XHRTME     = 310000;\n\n\n\n/**\n * LOCAL STORAGE\n */\nvar db = (function(){\n    var ls = typeof localStorage != 'undefined' && localStorage;\n    return {\n        get : function(key) {\n            try {\n                if (ls) return ls.getItem(key);\n                if (document.cookie.indexOf(key) == -1) return null;\n                return ((document.cookie||'').match(\n                    RegExp(key+'=([^;]+)')\n                )||[])[1] || null;\n            } catch(e) { return }\n        },\n        set : function( key, value ) {\n            try {\n                if (ls) return ls.setItem( key, value ) && 0;\n                document.cookie = key + '=' + value +\n                    '; expires=Thu, 1 Aug 2030 20:00:00 UTC; path=/';\n            } catch(e) { return }\n        }\n    };\n})();\n\n\n/**\n * CORS XHR Request\n * ================\n *  xdr({\n *     url     : ['http://www.blah.com/url'],\n *     success : function(response) {},\n *     fail    : function() {}\n *  });\n */\nfunction xdr( setup ) {\n    var xhr\n    ,   finished = function() {\n            if (loaded) return;\n                loaded = 1;\n\n            clearTimeout(timer);\n\n            try       { response = JSON['parse'](xhr.responseText); }\n            catch (r) { return done(1); }\n\n            success(response);\n        }\n    ,   complete = 0\n    ,   loaded   = 0\n    ,   timer    = timeout( function(){done(1)}, XHRTME )\n    ,   data     = setup.data || {}\n    ,   fail     = setup.fail    || function(){}\n    ,   success  = setup.success || function(){}\n    ,   async    = ( typeof(setup.blocking) === 'undefined' )\n    ,   done     = function(failed, response) {\n            if (complete) return;\n                complete = 1;\n\n            clearTimeout(timer);\n\n            if (xhr) {\n                xhr.onerror = xhr.onload = null;\n                xhr.abort && xhr.abort();\n                xhr = null;\n            }\n\n            failed && fail(response);\n        };\n\n    // Send\n    try {\n        xhr = typeof XDomainRequest !== 'undefined' &&\n              new XDomainRequest()  ||\n              new XMLHttpRequest();\n\n        xhr.onerror = xhr.onabort   = function(){ done(1, xhr.responseText || { \"error\" : \"Network Connection Error\"}) };\n        xhr.onload  = xhr.onloadend = finished;\n        xhr.onreadystatechange = function() {\n            if (xhr.readyState == 4) {\n                switch(xhr.status) {\n                    case 401:\n                    case 402:\n                    case 403:\n                        try {\n                            response = JSON['parse'](xhr.responseText);\n                            done(1,response);\n                        }\n                        catch (r) { return done(1, xhr.responseText); }\n                        break;\n                    default:\n                        break;\n                }\n            }\n        }\n        if (async) xhr.timeout = XHRTME;\n        data['pnsdk'] = PNSDK;\n        url = build_url(setup.url, data);\n        xhr.open( 'GET', url, async);\n        xhr.send();\n    }\n    catch(eee) {\n        done(0);\n        return xdr(setup);\n    }\n\n    // Return 'done'\n    return done;\n}\n\n/**\n * BIND\n * ====\n * bind( 'keydown', search('a')[0], function(element) {\n *     ...\n * } );\n */\nfunction bind( type, el, fun ) {\n    each( type.split(','), function(etype) {\n        var rapfun = function(e) {\n            if (!e) e = window.event;\n            if (!fun(e)) {\n                e.cancelBubble = true;\n                e.returnValue  = false;\n                e.preventDefault && e.preventDefault();\n                e.stopPropagation && e.stopPropagation();\n            }\n        };\n\n        if ( el.addEventListener ) el.addEventListener( etype, rapfun, false );\n        else if ( el.attachEvent ) el.attachEvent( 'on' + etype, rapfun );\n        else  el[ 'on' + etype ] = rapfun;\n    } );\n}\n\n/**\n * UNBIND\n * ======\n * unbind( 'keydown', search('a')[0] );\n */\nfunction unbind( type, el, fun ) {\n    if ( el.removeEventListener ) el.removeEventListener( type, false );\n    else if ( el.detachEvent ) el.detachEvent( 'on' + type, false );\n    else  el[ 'on' + type ] = null;\n}\n\n/**\n * ERROR\n * ===\n * error('message');\n */\nfunction error(message) { console['error'](message) }\n\n/**\n * EVENTS\n * ======\n * PUBNUB.events.bind( 'you-stepped-on-flower', function(message) {\n *     // Do Stuff with message\n * } );\n *\n * PUBNUB.events.fire( 'you-stepped-on-flower', \"message-data\" );\n * PUBNUB.events.fire( 'you-stepped-on-flower', {message:\"data\"} );\n * PUBNUB.events.fire( 'you-stepped-on-flower', [1,2,3] );\n *\n */\nvar events = {\n    'list'   : {},\n    'unbind' : function( name ) { events.list[name] = [] },\n    'bind'   : function( name, fun ) {\n        (events.list[name] = events.list[name] || []).push(fun);\n    },\n    'fire' : function( name, data ) {\n        each(\n            events.list[name] || [],\n            function(fun) { fun(data) }\n        );\n    }\n};\n\n/**\n * ATTR\n * ====\n * var attribute = attr( node, 'attribute' );\n */\nfunction attr( node, attribute, value ) {\n    if (value) node.setAttribute( attribute, value );\n    else return node && node.getAttribute && node.getAttribute(attribute);\n}\n\n/**\n * $\n * =\n * var div = $('divid');\n */\nfunction $(id) { return document.getElementById(id) }\n\n\n/**\n * SEARCH\n * ======\n * var elements = search('a div span');\n */\nfunction search( elements, start ) {\n    var list = [];\n    each( elements.split(/\\s+/), function(el) {\n        each( (start || document).getElementsByTagName(el), function(node) {\n            list.push(node);\n        } );\n    } );\n    return list;\n}\n\n/**\n * CSS\n * ===\n * var obj = create('div');\n */\nfunction css( element, styles ) {\n    for (var style in styles) if (styles.hasOwnProperty(style))\n        try {element.style[style] = styles[style] + (\n            '|width|height|top|left|'.indexOf(style) > 0 &&\n            typeof styles[style] == 'number'\n            ? 'px' : ''\n        )}catch(e){}\n}\n\n/**\n * CREATE\n * ======\n * var obj = create('div');\n */\nfunction create(element) { return document.createElement(element) }\n\n\nfunction get_hmac_SHA256(data,key) {\n    var hash = CryptoJS['HmacSHA256'](data, key);\n    return hash.toString(CryptoJS['enc']['Base64']);\n}\n\n/* =-====================================================================-= */\n/* =-====================================================================-= */\n/* =-=========================     PUBNUB     ===========================-= */\n/* =-====================================================================-= */\n/* =-====================================================================-= */\n\nfunction CREATE_PUBNUB(setup) {\n\n\n    setup['db'] = db;\n    setup['xdr'] = xdr;\n    setup['error'] = setup['error'] || error;\n    setup['hmac_SHA256']= get_hmac_SHA256;\n    setup['crypto_obj'] = crypto_obj();\n    setup['params']      = { 'pnsdk' : PNSDK }\n\n    SELF = function(setup) {\n        return CREATE_PUBNUB(setup);\n    }\n    var PN = PN_API(setup);\n    for (var prop in PN) {\n        if (PN.hasOwnProperty(prop)) {\n            SELF[prop] = PN[prop];\n        }\n    }\n\n    SELF['init'] = SELF;\n    SELF['$'] = $;\n    SELF['attr'] = attr;\n    SELF['search'] = search;\n    SELF['bind'] = bind;\n    SELF['css'] = css;\n    SELF['create'] = create;\n\n    if (typeof(window) !== 'undefined'){\n        bind( 'beforeunload', window, function() {\n            SELF['each-channel'](function(ch){ SELF['LEAVE']( ch.name, 1 ) });\n            return true;\n        });\n    }\n\n    // Return without Testing\n    if (setup['notest']) return SELF;\n\n    if (typeof(window) !== 'undefined'){\n        bind( 'offline', window,   SELF['_reset_offline'] );\n    }\n\n    if (typeof(document) !== 'undefined'){\n        bind( 'offline', document, SELF['_reset_offline'] );\n    }\n\n    SELF['ready']();\n    return SELF;\n}\nCREATE_PUBNUB['init'] = CREATE_PUBNUB\nCREATE_PUBNUB['secure'] = CREATE_PUBNUB\nPUBNUB = CREATE_PUBNUB({})\ntypeof module  !== 'undefined' && (module.exports = CREATE_PUBNUB) ||\ntypeof exports !== 'undefined' && (exports.PUBNUB = CREATE_PUBNUB) || (PUBNUB = CREATE_PUBNUB);\n\n})();\n(function(){\n\n// ---------------------------------------------------------------------------\n// WEBSOCKET INTERFACE\n// ---------------------------------------------------------------------------\nvar WS = PUBNUB['ws'] = function( url, protocols ) {\n    if (!(this instanceof WS)) return new WS( url, protocols );\n\n    var self     = this\n    ,   url      = self.url      = url || ''\n    ,   protocol = self.protocol = protocols || 'Sec-WebSocket-Protocol'\n    ,   bits     = url.split('/')\n    ,   setup    = {\n         'ssl'           : bits[0] === 'wss:'\n        ,'origin'        : bits[2]\n        ,'publish_key'   : bits[3]\n        ,'subscribe_key' : bits[4]\n        ,'channel'       : bits[5]\n    };\n\n    // READY STATES\n    self['CONNECTING'] = 0; // The connection is not yet open.\n    self['OPEN']       = 1; // The connection is open and ready to communicate.\n    self['CLOSING']    = 2; // The connection is in the process of closing.\n    self['CLOSED']     = 3; // The connection is closed or couldn't be opened.\n\n    // CLOSE STATES\n    self['CLOSE_NORMAL']         = 1000; // Normal Intended Close; completed.\n    self['CLOSE_GOING_AWAY']     = 1001; // Closed Unexpecttedly.\n    self['CLOSE_PROTOCOL_ERROR'] = 1002; // Server: Not Supported.\n    self['CLOSE_UNSUPPORTED']    = 1003; // Server: Unsupported Protocol.\n    self['CLOSE_TOO_LARGE']      = 1004; // Server: Too Much Data.\n    self['CLOSE_NO_STATUS']      = 1005; // Server: No reason.\n    self['CLOSE_ABNORMAL']       = 1006; // Abnormal Disconnect.\n\n    // Events Default\n    self['onclose']   = self['onerror'] =\n    self['onmessage'] = self['onopen']  =\n    self['onsend']    =  function(){};\n\n    // Attributes\n    self['binaryType']     = '';\n    self['extensions']     = '';\n    self['bufferedAmount'] = 0;\n    self['trasnmitting']   = false;\n    self['buffer']         = [];\n    self['readyState']     = self['CONNECTING'];\n\n    // Close if no setup.\n    if (!url) {\n        self['readyState'] = self['CLOSED'];\n        self['onclose']({\n            'code'     : self['CLOSE_ABNORMAL'],\n            'reason'   : 'Missing URL',\n            'wasClean' : true\n        });\n        return self;\n    }\n\n    // PubNub WebSocket Emulation\n    self.pubnub       = PUBNUB['init'](setup);\n    self.pubnub.setup = setup;\n    self.setup        = setup;\n\n    self.pubnub['subscribe']({\n        'restore'    : false,\n        'channel'    : setup['channel'],\n        'disconnect' : self['onerror'],\n        'reconnect'  : self['onopen'],\n        'error'      : function() {\n            self['onclose']({\n                'code'     : self['CLOSE_ABNORMAL'],\n                'reason'   : 'Missing URL',\n                'wasClean' : false\n            });\n        },\n        'callback'   : function(message) {\n            self['onmessage']({ 'data' : message });\n        },\n        'connect'    : function() {\n            self['readyState'] = self['OPEN'];\n            self['onopen']();\n        }\n    });\n};\n\n// ---------------------------------------------------------------------------\n// WEBSOCKET SEND\n// ---------------------------------------------------------------------------\nWS.prototype.send = function(data) {\n    var self = this;\n    self.pubnub['publish']({\n        'channel'  : self.pubnub.setup['channel'],\n        'message'  : data,\n        'callback' : function(response) {\n            self['onsend']({ 'data' : response });\n        }\n    });\n};\n\n// ---------------------------------------------------------------------------\n// WEBSOCKET CLOSE\n// ---------------------------------------------------------------------------\nWS.prototype.close = function() {\n    var self = this;\n    self.pubnub['unsubscribe']({ 'channel' : self.pubnub.setup['channel'] });\n    self['readyState'] = self['CLOSED'];\n    self['onclose']({});\n};\n\n})();\n","// STUN servers\nexports.stun = [\n  'stun.l.google.com:19302',\n  'stun1.l.google.com:19302',\n  'stun2.l.google.com:19302',\n  'stun3.l.google.com:19302',\n  'stun4.l.google.com:19302',\n  'stun.ekiga.net',\n  'stun.ideasip.com',\n  'stun.iptel.org',\n  'stun.rixtelecom.se',\n  'stun.schlund.de',\n  'stunserver.org',\n  // 'stun.softjoys.com',\n  'stun.stunprotocol.org:3478',\n  // 'stun.turnservers.com:3478',\n  'stun.voiparound.com',\n  'stun.voipbuster.com',\n  'stun.voipstunt.com'\n];\n\n// TURN servers\nexports.turn = [\n];\n","\nvar rng;\n\nif (global.crypto && crypto.getRandomValues) {\n  // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto\n  // Moderately fast, high quality\n  var _rnds8 = new Uint8Array(16);\n  rng = function whatwgRNG() {\n    crypto.getRandomValues(_rnds8);\n    return _rnds8;\n  };\n}\n\nif (!rng) {\n  // Math.random()-based (RNG)\n  //\n  // If all else fails, use Math.random().  It's fast, but is of unspecified\n  // quality.\n  var  _rnds = new Array(16);\n  rng = function() {\n    for (var i = 0, r; i < 16; i++) {\n      if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n      _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n    }\n\n    return _rnds;\n  };\n}\n\nmodule.exports = rng;\n\n","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = Buffer\nexports.INSPECT_MAX_BYTES = 50\nBuffer.poolSize = 8192\n\n/**\n * If `Buffer._useTypedArrays`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (compatible down to IE6)\n */\nBuffer._useTypedArrays = (function () {\n  // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+,\n  // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding\n  // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support\n  // because we need to be able to add all the node Buffer API methods. This is an issue\n  // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438\n  try {\n    var buf = new ArrayBuffer(0)\n    var arr = new Uint8Array(buf)\n    arr.foo = function () { return 42 }\n    return 42 === arr.foo() &&\n        typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray`\n  } catch (e) {\n    return false\n  }\n})()\n\n/**\n * Class: Buffer\n * =============\n *\n * The Buffer constructor returns instances of `Uint8Array` that are augmented\n * with function properties for all the node `Buffer` API functions. We use\n * `Uint8Array` so that square bracket notation works as expected -- it returns\n * a single octet.\n *\n * By augmenting the instances, we can avoid modifying the `Uint8Array`\n * prototype.\n */\nfunction Buffer (subject, encoding, noZero) {\n  if (!(this instanceof Buffer))\n    return new Buffer(subject, encoding, noZero)\n\n  var type = typeof subject\n\n  // Workaround: node's base64 implementation allows for non-padded strings\n  // while base64-js does not.\n  if (encoding === 'base64' && type === 'string') {\n    subject = stringtrim(subject)\n    while (subject.length % 4 !== 0) {\n      subject = subject + '='\n    }\n  }\n\n  // Find the length\n  var length\n  if (type === 'number')\n    length = coerce(subject)\n  else if (type === 'string')\n    length = Buffer.byteLength(subject, encoding)\n  else if (type === 'object')\n    length = coerce(subject.length) // assume that object is array-like\n  else\n    throw new Error('First argument needs to be a number, array or string.')\n\n  var buf\n  if (Buffer._useTypedArrays) {\n    // Preferred: Return an augmented `Uint8Array` instance for best performance\n    buf = Buffer._augment(new Uint8Array(length))\n  } else {\n    // Fallback: Return THIS instance of Buffer (created by `new`)\n    buf = this\n    buf.length = length\n    buf._isBuffer = true\n  }\n\n  var i\n  if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') {\n    // Speed optimization -- use set if we're copying from a typed array\n    buf._set(subject)\n  } else if (isArrayish(subject)) {\n    // Treat array-ish objects as a byte array\n    for (i = 0; i < length; i++) {\n      if (Buffer.isBuffer(subject))\n        buf[i] = subject.readUInt8(i)\n      else\n        buf.writeInt8(subject[i], i)\n    }\n  } else if (type === 'string') {\n    buf.write(subject, 0, encoding)\n  } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) {\n    for (i = 0; i < length; i++) {\n      buf[i] = 0\n    }\n  }\n\n  return buf\n}\n\n// STATIC METHODS\n// ==============\n\nBuffer.isEncoding = function (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'binary':\n    case 'base64':\n    case 'raw':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.isBuffer = function (b) {\n  return !!(b !== null && b !== undefined && b._isBuffer)\n}\n\nBuffer.byteLength = function (str, encoding) {\n  var ret\n  str = str.toString()\n  switch (encoding || 'utf8') {\n    case 'hex':\n      ret = str.length / 2\n      break\n    case 'utf8':\n    case 'utf-8':\n      ret = utf8ToBytes(str).length\n      break\n    case 'ascii':\n    case 'binary':\n    case 'raw':\n      ret = str.length\n      break\n    case 'base64':\n      ret = base64ToBytes(str).length\n      break\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      ret = str.length * 2\n      break\n    default:\n      throw new Error('Unknown encoding')\n  }\n  return ret\n}\n\nBuffer.concat = function (list, totalLength) {\n  assert(isArray(list), 'Usage: Buffer.concat(list[, length])')\n\n  if (list.length === 0) {\n    return new Buffer(0)\n  } else if (list.length === 1) {\n    return list[0]\n  }\n\n  var i\n  if (totalLength === undefined) {\n    totalLength = 0\n    for (i = 0; i < list.length; i++) {\n      totalLength += list[i].length\n    }\n  }\n\n  var buf = new Buffer(totalLength)\n  var pos = 0\n  for (i = 0; i < list.length; i++) {\n    var item = list[i]\n    item.copy(buf, pos)\n    pos += item.length\n  }\n  return buf\n}\n\nBuffer.compare = function (a, b) {\n  assert(Buffer.isBuffer(a) && Buffer.isBuffer(b), 'Arguments must be Buffers')\n  var x = a.length\n  var y = b.length\n  for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {}\n  if (i !== len) {\n    x = a[i]\n    y = b[i]\n  }\n  if (x < y) {\n    return -1\n  }\n  if (y < x) {\n    return 1\n  }\n  return 0\n}\n\n// BUFFER INSTANCE METHODS\n// =======================\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  assert(strLen % 2 === 0, 'Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; i++) {\n    var byte = parseInt(string.substr(i * 2, 2), 16)\n    assert(!isNaN(byte), 'Invalid hex string')\n    buf[offset + i] = byte\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  var charsWritten = blitBuffer(utf8ToBytes(string), buf, offset, length)\n  return charsWritten\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length)\n  return charsWritten\n}\n\nfunction binaryWrite (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length)\n  return charsWritten\n}\n\nfunction utf16leWrite (buf, string, offset, length) {\n  var charsWritten = blitBuffer(utf16leToBytes(string), buf, offset, length)\n  return charsWritten\n}\n\nBuffer.prototype.write = function (string, offset, length, encoding) {\n  // Support both (string, offset, length, encoding)\n  // and the legacy (string, encoding, offset, length)\n  if (isFinite(offset)) {\n    if (!isFinite(length)) {\n      encoding = length\n      length = undefined\n    }\n  } else {  // legacy\n    var swap = encoding\n    encoding = offset\n    offset = length\n    length = swap\n  }\n\n  offset = Number(offset) || 0\n  var remaining = this.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n  encoding = String(encoding || 'utf8').toLowerCase()\n\n  var ret\n  switch (encoding) {\n    case 'hex':\n      ret = hexWrite(this, string, offset, length)\n      break\n    case 'utf8':\n    case 'utf-8':\n      ret = utf8Write(this, string, offset, length)\n      break\n    case 'ascii':\n      ret = asciiWrite(this, string, offset, length)\n      break\n    case 'binary':\n      ret = binaryWrite(this, string, offset, length)\n      break\n    case 'base64':\n      ret = base64Write(this, string, offset, length)\n      break\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      ret = utf16leWrite(this, string, offset, length)\n      break\n    default:\n      throw new Error('Unknown encoding')\n  }\n  return ret\n}\n\nBuffer.prototype.toString = function (encoding, start, end) {\n  var self = this\n\n  encoding = String(encoding || 'utf8').toLowerCase()\n  start = Number(start) || 0\n  end = (end === undefined) ? self.length : Number(end)\n\n  // Fastpath empty strings\n  if (end === start)\n    return ''\n\n  var ret\n  switch (encoding) {\n    case 'hex':\n      ret = hexSlice(self, start, end)\n      break\n    case 'utf8':\n    case 'utf-8':\n      ret = utf8Slice(self, start, end)\n      break\n    case 'ascii':\n      ret = asciiSlice(self, start, end)\n      break\n    case 'binary':\n      ret = binarySlice(self, start, end)\n      break\n    case 'base64':\n      ret = base64Slice(self, start, end)\n      break\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      ret = utf16leSlice(self, start, end)\n      break\n    default:\n      throw new Error('Unknown encoding')\n  }\n  return ret\n}\n\nBuffer.prototype.toJSON = function () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nBuffer.prototype.equals = function (b) {\n  assert(Buffer.isBuffer(b), 'Argument must be a Buffer')\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.compare = function (b) {\n  assert(Buffer.isBuffer(b), 'Argument must be a Buffer')\n  return Buffer.compare(this, b)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function (target, target_start, start, end) {\n  var source = this\n\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (!target_start) target_start = 0\n\n  // Copy 0 bytes; we're done\n  if (end === start) return\n  if (target.length === 0 || source.length === 0) return\n\n  // Fatal error conditions\n  assert(end >= start, 'sourceEnd < sourceStart')\n  assert(target_start >= 0 && target_start < target.length,\n      'targetStart out of bounds')\n  assert(start >= 0 && start < source.length, 'sourceStart out of bounds')\n  assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length)\n    end = this.length\n  if (target.length - target_start < end - start)\n    end = target.length - target_start + start\n\n  var len = end - start\n\n  if (len < 100 || !Buffer._useTypedArrays) {\n    for (var i = 0; i < len; i++) {\n      target[i + target_start] = this[i + start]\n    }\n  } else {\n    target._set(this.subarray(start, start + len), target_start)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  var res = ''\n  var tmp = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; i++) {\n    if (buf[i] <= 0x7F) {\n      res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])\n      tmp = ''\n    } else {\n      tmp += '%' + buf[i].toString(16)\n    }\n  }\n\n  return res + decodeUtf8Char(tmp)\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; i++) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction binarySlice (buf, start, end) {\n  return asciiSlice(buf, start, end)\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; i++) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function (start, end) {\n  var len = this.length\n  start = clamp(start, len, 0)\n  end = clamp(end, len, len)\n\n  if (Buffer._useTypedArrays) {\n    return Buffer._augment(this.subarray(start, end))\n  } else {\n    var sliceLen = end - start\n    var newBuf = new Buffer(sliceLen, undefined, true)\n    for (var i = 0; i < sliceLen; i++) {\n      newBuf[i] = this[i + start]\n    }\n    return newBuf\n  }\n}\n\n// `get` will be removed in Node 0.13+\nBuffer.prototype.get = function (offset) {\n  console.log('.get() is deprecated. Access using array indexes instead.')\n  return this.readUInt8(offset)\n}\n\n// `set` will be removed in Node 0.13+\nBuffer.prototype.set = function (v, offset) {\n  console.log('.set() is deprecated. Access using array indexes instead.')\n  return this.writeUInt8(v, offset)\n}\n\nBuffer.prototype.readUInt8 = function (offset, noAssert) {\n  if (!noAssert) {\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset < this.length, 'Trying to read beyond buffer length')\n  }\n\n  if (offset >= this.length)\n    return\n\n  return this[offset]\n}\n\nfunction readUInt16 (buf, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  var val\n  if (littleEndian) {\n    val = buf[offset]\n    if (offset + 1 < len)\n      val |= buf[offset + 1] << 8\n  } else {\n    val = buf[offset] << 8\n    if (offset + 1 < len)\n      val |= buf[offset + 1]\n  }\n  return val\n}\n\nBuffer.prototype.readUInt16LE = function (offset, noAssert) {\n  return readUInt16(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readUInt16BE = function (offset, noAssert) {\n  return readUInt16(this, offset, false, noAssert)\n}\n\nfunction readUInt32 (buf, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  var val\n  if (littleEndian) {\n    if (offset + 2 < len)\n      val = buf[offset + 2] << 16\n    if (offset + 1 < len)\n      val |= buf[offset + 1] << 8\n    val |= buf[offset]\n    if (offset + 3 < len)\n      val = val + (buf[offset + 3] << 24 >>> 0)\n  } else {\n    if (offset + 1 < len)\n      val = buf[offset + 1] << 16\n    if (offset + 2 < len)\n      val |= buf[offset + 2] << 8\n    if (offset + 3 < len)\n      val |= buf[offset + 3]\n    val = val + (buf[offset] << 24 >>> 0)\n  }\n  return val\n}\n\nBuffer.prototype.readUInt32LE = function (offset, noAssert) {\n  return readUInt32(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readUInt32BE = function (offset, noAssert) {\n  return readUInt32(this, offset, false, noAssert)\n}\n\nBuffer.prototype.readInt8 = function (offset, noAssert) {\n  if (!noAssert) {\n    assert(offset !== undefined && offset !== null,\n        'missing offset')\n    assert(offset < this.length, 'Trying to read beyond buffer length')\n  }\n\n  if (offset >= this.length)\n    return\n\n  var neg = this[offset] & 0x80\n  if (neg)\n    return (0xff - this[offset] + 1) * -1\n  else\n    return this[offset]\n}\n\nfunction readInt16 (buf, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  var val = readUInt16(buf, offset, littleEndian, true)\n  var neg = val & 0x8000\n  if (neg)\n    return (0xffff - val + 1) * -1\n  else\n    return val\n}\n\nBuffer.prototype.readInt16LE = function (offset, noAssert) {\n  return readInt16(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readInt16BE = function (offset, noAssert) {\n  return readInt16(this, offset, false, noAssert)\n}\n\nfunction readInt32 (buf, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  var val = readUInt32(buf, offset, littleEndian, true)\n  var neg = val & 0x80000000\n  if (neg)\n    return (0xffffffff - val + 1) * -1\n  else\n    return val\n}\n\nBuffer.prototype.readInt32LE = function (offset, noAssert) {\n  return readInt32(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readInt32BE = function (offset, noAssert) {\n  return readInt32(this, offset, false, noAssert)\n}\n\nfunction readFloat (buf, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')\n  }\n\n  return ieee754.read(buf, offset, littleEndian, 23, 4)\n}\n\nBuffer.prototype.readFloatLE = function (offset, noAssert) {\n  return readFloat(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readFloatBE = function (offset, noAssert) {\n  return readFloat(this, offset, false, noAssert)\n}\n\nfunction readDouble (buf, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset + 7 < buf.length, 'Trying to read beyond buffer length')\n  }\n\n  return ieee754.read(buf, offset, littleEndian, 52, 8)\n}\n\nBuffer.prototype.readDoubleLE = function (offset, noAssert) {\n  return readDouble(this, offset, true, noAssert)\n}\n\nBuffer.prototype.readDoubleBE = function (offset, noAssert) {\n  return readDouble(this, offset, false, noAssert)\n}\n\nBuffer.prototype.writeUInt8 = function (value, offset, noAssert) {\n  if (!noAssert) {\n    assert(value !== undefined && value !== null, 'missing value')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset < this.length, 'trying to write beyond buffer length')\n    verifuint(value, 0xff)\n  }\n\n  if (offset >= this.length) return\n\n  this[offset] = value\n  return offset + 1\n}\n\nfunction writeUInt16 (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(value !== undefined && value !== null, 'missing value')\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 1 < buf.length, 'trying to write beyond buffer length')\n    verifuint(value, 0xffff)\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) {\n    buf[offset + i] =\n        (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n            (littleEndian ? i : 1 - i) * 8\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16LE = function (value, offset, noAssert) {\n  return writeUInt16(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeUInt16BE = function (value, offset, noAssert) {\n  return writeUInt16(this, value, offset, false, noAssert)\n}\n\nfunction writeUInt32 (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(value !== undefined && value !== null, 'missing value')\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 3 < buf.length, 'trying to write beyond buffer length')\n    verifuint(value, 0xffffffff)\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) {\n    buf[offset + i] =\n        (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32LE = function (value, offset, noAssert) {\n  return writeUInt32(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeUInt32BE = function (value, offset, noAssert) {\n  return writeUInt32(this, value, offset, false, noAssert)\n}\n\nBuffer.prototype.writeInt8 = function (value, offset, noAssert) {\n  if (!noAssert) {\n    assert(value !== undefined && value !== null, 'missing value')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset < this.length, 'Trying to write beyond buffer length')\n    verifsint(value, 0x7f, -0x80)\n  }\n\n  if (offset >= this.length)\n    return\n\n  if (value >= 0)\n    this.writeUInt8(value, offset, noAssert)\n  else\n    this.writeUInt8(0xff + value + 1, offset, noAssert)\n  return offset + 1\n}\n\nfunction writeInt16 (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(value !== undefined && value !== null, 'missing value')\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 1 < buf.length, 'Trying to write beyond buffer length')\n    verifsint(value, 0x7fff, -0x8000)\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  if (value >= 0)\n    writeUInt16(buf, value, offset, littleEndian, noAssert)\n  else\n    writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert)\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16LE = function (value, offset, noAssert) {\n  return writeInt16(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeInt16BE = function (value, offset, noAssert) {\n  return writeInt16(this, value, offset, false, noAssert)\n}\n\nfunction writeInt32 (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(value !== undefined && value !== null, 'missing value')\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')\n    verifsint(value, 0x7fffffff, -0x80000000)\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  if (value >= 0)\n    writeUInt32(buf, value, offset, littleEndian, noAssert)\n  else\n    writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert)\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32LE = function (value, offset, noAssert) {\n  return writeInt32(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeInt32BE = function (value, offset, noAssert) {\n  return writeInt32(this, value, offset, false, noAssert)\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(value !== undefined && value !== null, 'missing value')\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')\n    verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    assert(value !== undefined && value !== null, 'missing value')\n    assert(typeof littleEndian === 'boolean', 'missing or invalid endian')\n    assert(offset !== undefined && offset !== null, 'missing offset')\n    assert(offset + 7 < buf.length,\n        'Trying to write beyond buffer length')\n    verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n\n  var len = buf.length\n  if (offset >= len)\n    return\n\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// fill(value, start=0, end=buffer.length)\nBuffer.prototype.fill = function (value, start, end) {\n  if (!value) value = 0\n  if (!start) start = 0\n  if (!end) end = this.length\n\n  assert(end >= start, 'end < start')\n\n  // Fill 0 bytes; we're done\n  if (end === start) return\n  if (this.length === 0) return\n\n  assert(start >= 0 && start < this.length, 'start out of bounds')\n  assert(end >= 0 && end <= this.length, 'end out of bounds')\n\n  var i\n  if (typeof value === 'number') {\n    for (i = start; i < end; i++) {\n      this[i] = value\n    }\n  } else {\n    var bytes = utf8ToBytes(value.toString())\n    var len = bytes.length\n    for (i = start; i < end; i++) {\n      this[i] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\nBuffer.prototype.inspect = function () {\n  var out = []\n  var len = this.length\n  for (var i = 0; i < len; i++) {\n    out[i] = toHex(this[i])\n    if (i === exports.INSPECT_MAX_BYTES) {\n      out[i + 1] = '...'\n      break\n    }\n  }\n  return '<Buffer ' + out.join(' ') + '>'\n}\n\n/**\n * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.\n * Added in Node 0.12. Only available in browsers that support ArrayBuffer.\n */\nBuffer.prototype.toArrayBuffer = function () {\n  if (typeof Uint8Array !== 'undefined') {\n    if (Buffer._useTypedArrays) {\n      return (new Buffer(this)).buffer\n    } else {\n      var buf = new Uint8Array(this.length)\n      for (var i = 0, len = buf.length; i < len; i += 1) {\n        buf[i] = this[i]\n      }\n      return buf.buffer\n    }\n  } else {\n    throw new Error('Buffer.toArrayBuffer not supported in this browser')\n  }\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar BP = Buffer.prototype\n\n/**\n * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods\n */\nBuffer._augment = function (arr) {\n  arr._isBuffer = true\n\n  // save reference to original Uint8Array get/set methods before overwriting\n  arr._get = arr.get\n  arr._set = arr.set\n\n  // deprecated, will be removed in node 0.13+\n  arr.get = BP.get\n  arr.set = BP.set\n\n  arr.write = BP.write\n  arr.toString = BP.toString\n  arr.toLocaleString = BP.toString\n  arr.toJSON = BP.toJSON\n  arr.equals = BP.equals\n  arr.compare = BP.compare\n  arr.copy = BP.copy\n  arr.slice = BP.slice\n  arr.readUInt8 = BP.readUInt8\n  arr.readUInt16LE = BP.readUInt16LE\n  arr.readUInt16BE = BP.readUInt16BE\n  arr.readUInt32LE = BP.readUInt32LE\n  arr.readUInt32BE = BP.readUInt32BE\n  arr.readInt8 = BP.readInt8\n  arr.readInt16LE = BP.readInt16LE\n  arr.readInt16BE = BP.readInt16BE\n  arr.readInt32LE = BP.readInt32LE\n  arr.readInt32BE = BP.readInt32BE\n  arr.readFloatLE = BP.readFloatLE\n  arr.readFloatBE = BP.readFloatBE\n  arr.readDoubleLE = BP.readDoubleLE\n  arr.readDoubleBE = BP.readDoubleBE\n  arr.writeUInt8 = BP.writeUInt8\n  arr.writeUInt16LE = BP.writeUInt16LE\n  arr.writeUInt16BE = BP.writeUInt16BE\n  arr.writeUInt32LE = BP.writeUInt32LE\n  arr.writeUInt32BE = BP.writeUInt32BE\n  arr.writeInt8 = BP.writeInt8\n  arr.writeInt16LE = BP.writeInt16LE\n  arr.writeInt16BE = BP.writeInt16BE\n  arr.writeInt32LE = BP.writeInt32LE\n  arr.writeInt32BE = BP.writeInt32BE\n  arr.writeFloatLE = BP.writeFloatLE\n  arr.writeFloatBE = BP.writeFloatBE\n  arr.writeDoubleLE = BP.writeDoubleLE\n  arr.writeDoubleBE = BP.writeDoubleBE\n  arr.fill = BP.fill\n  arr.inspect = BP.inspect\n  arr.toArrayBuffer = BP.toArrayBuffer\n\n  return arr\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\n// slice(start, end)\nfunction clamp (index, len, defaultValue) {\n  if (typeof index !== 'number') return defaultValue\n  index = ~~index;  // Coerce to integer.\n  if (index >= len) return len\n  if (index >= 0) return index\n  index += len\n  if (index >= 0) return index\n  return 0\n}\n\nfunction coerce (length) {\n  // Coerce length to a number (possibly NaN), round up\n  // in case it's fractional (e.g. 123.456) then do a\n  // double negate to coerce a NaN to 0. Easy, right?\n  length = ~~Math.ceil(+length)\n  return length < 0 ? 0 : length\n}\n\nfunction isArray (subject) {\n  return (Array.isArray || function (subject) {\n    return Object.prototype.toString.call(subject) === '[object Array]'\n  })(subject)\n}\n\nfunction isArrayish (subject) {\n  return isArray(subject) || Buffer.isBuffer(subject) ||\n      subject && typeof subject === 'object' &&\n      typeof subject.length === 'number'\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; i++) {\n    var b = str.charCodeAt(i)\n    if (b <= 0x7F) {\n      byteArray.push(b)\n    } else {\n      var start = i\n      if (b >= 0xD800 && b <= 0xDFFF) i++\n      var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%')\n      for (var j = 0; j < h.length; j++) {\n        byteArray.push(parseInt(h[j], 16))\n      }\n    }\n  }\n  return byteArray\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; i++) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; i++) {\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(str)\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; i++) {\n    if ((i + offset >= dst.length) || (i >= src.length))\n      break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction decodeUtf8Char (str) {\n  try {\n    return decodeURIComponent(str)\n  } catch (err) {\n    return String.fromCharCode(0xFFFD) // UTF 8 invalid char\n  }\n}\n\n/*\n * We have to make sure that the value is a valid integer. This means that it\n * is non-negative. It has no fractional component and that it does not\n * exceed the maximum allowed value.\n */\nfunction verifuint (value, max) {\n  assert(typeof value === 'number', 'cannot write a non-number as a number')\n  assert(value >= 0, 'specified a negative value for writing an unsigned value')\n  assert(value <= max, 'value is larger than maximum value for type')\n  assert(Math.floor(value) === value, 'value has a fractional component')\n}\n\nfunction verifsint (value, max, min) {\n  assert(typeof value === 'number', 'cannot write a non-number as a number')\n  assert(value <= max, 'value larger than maximum allowed value')\n  assert(value >= min, 'value smaller than minimum allowed value')\n  assert(Math.floor(value) === value, 'value has a fractional component')\n}\n\nfunction verifIEEE754 (value, max, min) {\n  assert(typeof value === 'number', 'cannot write a non-number as a number')\n  assert(value <= max, 'value larger than maximum allowed value')\n  assert(value >= min, 'value smaller than minimum allowed value')\n}\n\nfunction assert (test, message) {\n  if (!test) throw new Error(message || 'Failed assertion')\n}\n","function Mapper()\n{\n  var sources = {};\n\n\n  this.forEach = function(callback)\n  {\n    for(var key in sources)\n    {\n      var source = sources[key];\n\n      for(var key2 in source)\n        callback(source[key2]);\n    };\n  };\n\n  this.get = function(id, source)\n  {\n    var ids = sources[source];\n    if(ids == undefined)\n      return undefined;\n\n    return ids[id];\n  };\n\n  this.remove = function(id, source)\n  {\n    var ids = sources[source];\n    if(ids == undefined)\n      return;\n\n    delete ids[id];\n\n    if(!Object.keys(ids).length)\n      delete sources[source];\n  };\n\n  this.set = function(value, id, source)\n  {\n    if(value == undefined)\n      return this.remove(id, source);\n\n    var ids = sources[source];\n    if(ids == undefined)\n      sources[source] = ids = {};\n\n    ids[id] = value;\n  };\n};\n\n\nMapper.prototype.pop = function(id, source)\n{\n  var value = this.get(id, source);\n  if(value == undefined)\n    return undefined;\n\n  this.remove(id, source);\n\n  return value;\n};\n\n\nmodule.exports = Mapper;\n","var JsonRPC = require('./JsonRPC');\nvar XmlRPC  = require('./XmlRPC');\n\n\nexports.JsonRPC = JsonRPC;\nexports.XmlRPC  = XmlRPC;\n","/**\n * JsonRPC 2.0 packer\n */\n\n/**\n * Pack a JsonRPC 2.0 message\n *\n * @param {Object} message - object to be packaged. It requires to have all the\n *   fields needed by the JsonRPC 2.0 message that it's going to be generated\n *\n * @return {String} - the stringified JsonRPC 2.0 message\n */\nfunction pack(message, id)\n{\n  var result =\n  {\n    jsonrpc: \"2.0\"\n  };\n\n  // Request\n  if(message.method)\n  {\n    result.method = message.method;\n\n    if(message.params)\n      result.params = message.params;\n\n    // Request is a notification\n    if(id != undefined)\n      result.id = id;\n  }\n\n  // Response\n  else if(id != undefined)\n  {\n    if(message.error)\n    {\n      if(message.result !== undefined)\n        throw new TypeError(\"Both result and error are defined\");\n\n      result.error = message.error;\n    }\n    else if(message.result !== undefined)\n      result.result = message.result;\n    else\n      throw new TypeError(\"No result or error is defined\");\n\n    result.id = id;\n  };\n\n  return JSON.stringify(result);\n};\n\n/**\n * Unpack a JsonRPC 2.0 message\n *\n * @param {String} message - string with the content of the JsonRPC 2.0 message\n *\n * @throws {TypeError} - Invalid JsonRPC version\n *\n * @return {Object} - object filled with the JsonRPC 2.0 message content\n */\nfunction unpack(message)\n{\n  var result = message;\n\n  if(typeof message == 'string' || message instanceof String)\n    result = JSON.parse(message);\n\n  // Check if it's a valid message\n\n  var version = result.jsonrpc;\n  if(version != \"2.0\")\n    throw new TypeError(\"Invalid JsonRPC version '\"+version+\"': \"+message);\n\n  // Response\n  if(result.method == undefined)\n  {\n    if(result.id == undefined)\n      throw new TypeError(\"Invalid message: \"+message);\n\n    var result_defined = result.result !== undefined;\n    var error_defined  = result.error  !== undefined;\n\n    // Check only result or error is defined, not both or none\n    if(result_defined && error_defined)\n      throw new TypeError(\"Both result and error are defined: \"+message);\n\n    if(!result_defined && !error_defined)\n      throw new TypeError(\"No result or error is defined: \"+message);\n\n    result.ack = result.id;\n    delete result.id;\n  }\n\n  // Return unpacked message\n  return result;\n};\n\n\nexports.pack   = pack;\nexports.unpack = unpack;\n","function pack(message)\n{\n  throw new TypeError(\"Not yet implemented\");\n};\n\nfunction unpack(message)\n{\n  throw new TypeError(\"Not yet implemented\");\n};\n\n\nexports.pack   = pack;\nexports.unpack = unpack;\n","/**\r\n * @fileoverview Exports IbtRealTimeSJNode\r\n */\r\n\r\nmodule.exports = {\r\n    IbtRealTimeSJNode: require('./IbtRealTimeSJNode.js')\r\n};","exports.read = function(buffer, offset, isLE, mLen, nBytes) {\n  var e, m,\n      eLen = nBytes * 8 - mLen - 1,\n      eMax = (1 << eLen) - 1,\n      eBias = eMax >> 1,\n      nBits = -7,\n      i = isLE ? (nBytes - 1) : 0,\n      d = isLE ? -1 : 1,\n      s = buffer[offset + i];\n\n  i += d;\n\n  e = s & ((1 << (-nBits)) - 1);\n  s >>= (-nBits);\n  nBits += eLen;\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);\n\n  m = e & ((1 << (-nBits)) - 1);\n  e >>= (-nBits);\n  nBits += mLen;\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);\n\n  if (e === 0) {\n    e = 1 - eBias;\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity);\n  } else {\n    m = m + Math.pow(2, mLen);\n    e = e - eBias;\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen);\n};\n\nexports.write = function(buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c,\n      eLen = nBytes * 8 - mLen - 1,\n      eMax = (1 << eLen) - 1,\n      eBias = eMax >> 1,\n      rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),\n      i = isLE ? 0 : (nBytes - 1),\n      d = isLE ? 1 : -1,\n      s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;\n\n  value = Math.abs(value);\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0;\n    e = eMax;\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2);\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--;\n      c *= 2;\n    }\n    if (e + eBias >= 1) {\n      value += rt / c;\n    } else {\n      value += rt * Math.pow(2, 1 - eBias);\n    }\n    if (value * c >= 2) {\n      e++;\n      c /= 2;\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0;\n      e = eMax;\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen);\n      e = e + eBias;\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);\n      e = 0;\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);\n\n  e = (e << mLen) | m;\n  eLen += mLen;\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);\n\n  buffer[offset + i - d] |= s * 128;\n};\n","var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n;(function (exports) {\n\t'use strict';\n\n  var Arr = (typeof Uint8Array !== 'undefined')\n    ? Uint8Array\n    : Array\n\n\tvar ZERO   = '0'.charCodeAt(0)\n\tvar PLUS   = '+'.charCodeAt(0)\n\tvar SLASH  = '/'.charCodeAt(0)\n\tvar NUMBER = '0'.charCodeAt(0)\n\tvar LOWER  = 'a'.charCodeAt(0)\n\tvar UPPER  = 'A'.charCodeAt(0)\n\n\tfunction decode (elt) {\n\t\tvar code = elt.charCodeAt(0)\n\t\tif (code === PLUS)\n\t\t\treturn 62 // '+'\n\t\tif (code === SLASH)\n\t\t\treturn 63 // '/'\n\t\tif (code < NUMBER)\n\t\t\treturn -1 //no match\n\t\tif (code < NUMBER + 10)\n\t\t\treturn code - NUMBER + 26 + 26\n\t\tif (code < UPPER + 26)\n\t\t\treturn code - UPPER\n\t\tif (code < LOWER + 26)\n\t\t\treturn code - LOWER + 26\n\t}\n\n\tfunction b64ToByteArray (b64) {\n\t\tvar i, j, l, tmp, placeHolders, arr\n\n\t\tif (b64.length % 4 > 0) {\n\t\t\tthrow new Error('Invalid string. Length must be a multiple of 4')\n\t\t}\n\n\t\t// the number of equal signs (place holders)\n\t\t// if there are two placeholders, than the two characters before it\n\t\t// represent one byte\n\t\t// if there is only one, then the three characters before it represent 2 bytes\n\t\t// this is just a cheap hack to not do indexOf twice\n\t\tvar len = b64.length\n\t\tplaceHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0\n\n\t\t// base64 is 4/3 + up to two characters of the original data\n\t\tarr = new Arr(b64.length * 3 / 4 - placeHolders)\n\n\t\t// if there are placeholders, only get up to the last complete 4 chars\n\t\tl = placeHolders > 0 ? b64.length - 4 : b64.length\n\n\t\tvar L = 0\n\n\t\tfunction push (v) {\n\t\t\tarr[L++] = v\n\t\t}\n\n\t\tfor (i = 0, j = 0; i < l; i += 4, j += 3) {\n\t\t\ttmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))\n\t\t\tpush((tmp & 0xFF0000) >> 16)\n\t\t\tpush((tmp & 0xFF00) >> 8)\n\t\t\tpush(tmp & 0xFF)\n\t\t}\n\n\t\tif (placeHolders === 2) {\n\t\t\ttmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)\n\t\t\tpush(tmp & 0xFF)\n\t\t} else if (placeHolders === 1) {\n\t\t\ttmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)\n\t\t\tpush((tmp >> 8) & 0xFF)\n\t\t\tpush(tmp & 0xFF)\n\t\t}\n\n\t\treturn arr\n\t}\n\n\tfunction uint8ToBase64 (uint8) {\n\t\tvar i,\n\t\t\textraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes\n\t\t\toutput = \"\",\n\t\t\ttemp, length\n\n\t\tfunction encode (num) {\n\t\t\treturn lookup.charAt(num)\n\t\t}\n\n\t\tfunction tripletToBase64 (num) {\n\t\t\treturn encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)\n\t\t}\n\n\t\t// go through the array every three bytes, we'll deal with trailing stuff later\n\t\tfor (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {\n\t\t\ttemp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\n\t\t\toutput += tripletToBase64(temp)\n\t\t}\n\n\t\t// pad the end with zeros, but make sure to not forget the extra bytes\n\t\tswitch (extraBytes) {\n\t\t\tcase 1:\n\t\t\t\ttemp = uint8[uint8.length - 1]\n\t\t\t\toutput += encode(temp >> 2)\n\t\t\t\toutput += encode((temp << 4) & 0x3F)\n\t\t\t\toutput += '=='\n\t\t\t\tbreak\n\t\t\tcase 2:\n\t\t\t\ttemp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])\n\t\t\t\toutput += encode(temp >> 10)\n\t\t\t\toutput += encode((temp >> 4) & 0x3F)\n\t\t\t\toutput += encode((temp << 2) & 0x3F)\n\t\t\t\toutput += '='\n\t\t\t\tbreak\n\t\t}\n\n\t\treturn output\n\t}\n\n\tmodule.exports.toByteArray = b64ToByteArray\n\tmodule.exports.fromByteArray = uint8ToBase64\n}())\n","var WebSocket = require('ws'),\r\n    httpRequest = require('./http-request'),\r\n    urlParser = require('url'),\r\n    strings = require('./strings'),\r\n    fs = require('fs'),\r\n    path = require('path'),\r\n    ObjectLiterals = require('./object-literals'),\r\n    IbtRealtimeRestServices = require('./IbtRealtimeRestServices');\r\n\r\nexports = module.exports = IbtRealTimeSJNode;\r\n\r\n/*\r\n* Initializes a new instance of the IbtRealTimeSJNode class.\r\n*/\r\nfunction IbtRealTimeSJNode() {\r\n\r\n    /***********************************************************\r\n    * @attributes \r\n    ***********************************************************/\r\n\r\n    var appKey;                     // application key\r\n    var authToken;                  // authentication token\r\n    var clusterUrl;                 // cluster URL to connect\r\n    var connectionTimeout;          // connection timeout in milliseconds\r\n    var messageMaxSize;             // message maximum size in bytes\r\n    var channelMaxSize;             // channel maximum size in bytes\r\n    var messagesBuffer;             // buffer to hold the message parts\r\n    var id;                         // object identifier\r\n    var isConnected;                // indicates whether the client object is connected\r\n    var isConnecting;               // indicates whether the client object is connecting\r\n    var alreadyConnectedFirstTime;  // indicates whether the client already connected for the first time\r\n    var stopReconnecting;           // indicates whether the user disconnected (stop the reconnecting proccess)\r\n    var ortc;                       // represents the object itself\r\n    var reconnectIntervalId;        // id used for the reconnect interval\r\n    var reconnectTimeoutlId;        // id used for the reconnect timeout\r\n    var sockjs;                     // socket connected to\r\n    var url;                        // URL to connect\r\n    var userPerms;                  // user permissions\r\n    var connectionMetadata;         // connection metadata used to identify the client\r\n    var announcementSubChannel;     // announcement subchannel\r\n    var subscribedChannels;         // subscribed/subscribing channels\r\n    var lastKeepAlive;              // holds the time of the last keep alive received\r\n    var invalidConnection;          // indicates whether the connection is valid\r\n    var reconnectStartedAt;         // the time which the reconnect started\r\n    var eventEmitter;               // event emitter to send message\r\n   \r\n\r\n    /***********************************************************\r\n    * @attributes initialization\r\n    ***********************************************************/\r\n\r\n    connectionTimeout = 15000;\r\n    messageMaxSize = 800;\r\n    channelMaxSize = 100;\r\n    connectionMetadataMaxSize = 256;\r\n\r\n    messagesBuffer = Object.create(null);\r\n    subscribedChannels = Object.create(null);\r\n\r\n    isConnected = false;\r\n    isConnecting = false;\r\n    alreadyConnectedFirstTime = false;\r\n    invalidConnection = false;\r\n\r\n    ortc = this;\r\n    lastKeepAlive = null;\r\n    userPerms = null;\r\n    reconnectStartedAt = null;\r\n    \r\n//    this.eventEmitter = new process.EventEmitter();\r\n\r\n    /***********************************************************\r\n    * @properties\r\n    ***********************************************************/\r\n\r\n    this.getId = function () { return id; };\r\n    this.setId = function (newId) { id = newId; };\r\n\r\n    this.getUrl = function () { return url; };\r\n    this.setUrl = function (newUrl) { url = newUrl; clusterUrl = null; };\r\n\r\n    this.getClusterUrl = function () { return clusterUrl; };\r\n    this.setClusterUrl = function (newUrl) { clusterUrl = newUrl; url = null; };\r\n\r\n    this.getConnectionTimeout = function () { return connectionTimeout; };\r\n    this.setConnectionTimeout = function (newTimeout) { connectionTimeout = newTimeout; };\r\n\r\n    this.getIsConnected = function () { return isConnected && ortc.sockjs != null; };\r\n\r\n    this.getConnectionMetadata = function () { return connectionMetadata; };\r\n    this.setConnectionMetadata = function (newConnectionMetadata) { connectionMetadata = newConnectionMetadata; };\r\n\r\n    this.getAnnouncementSubChannel = function () { return announcementSubChannel; };\r\n    this.setAnnouncementSubChannel = function (newAnnouncementSubChannel) { announcementSubChannel = newAnnouncementSubChannel; };\r\n\r\n    /***********************************************************\r\n    * @events\r\n    ***********************************************************/\r\n\r\n    this.onConnected = null;\r\n    this.onDisconnected = null;\r\n    this.onSubscribed = null;\r\n    this.onUnsubscribed = null;\r\n    this.onException = null;\r\n    this.onReconnecting = null;\r\n    this.onReconnected = null;\r\n\r\n    /***********************************************************\r\n    * @public methods\r\n    ***********************************************************/\r\n\r\n    /*\r\n    * Connects to the gateway with the application key and authentication token.\r\n    */\r\n    this.connect = function (appKey, authToken) {\r\n        /*\r\n        Sanity Checks\r\n        */\r\n        if (isConnected) {\r\n            delegateExceptionCallback(ortc, 'Already connected');\r\n        }\r\n        else if (!url && !clusterUrl) {\r\n            delegateExceptionCallback(ortc, 'URL and Cluster URL are null or empty');\r\n        }\r\n        else if (!appKey) {\r\n            delegateExceptionCallback(ortc, 'Application key is null or empty');\r\n        }\r\n        else if (!authToken) {\r\n            delegateExceptionCallback(ortc, 'Authentication Token is null or empty');\r\n        }\r\n        else if (url && !ortcIsValidUrl(url)) {\r\n            delegateExceptionCallback(ortc, 'Invalid URL');\r\n        }\r\n        else if (clusterUrl && !ortcIsValidUrl(clusterUrl)) {\r\n            delegateExceptionCallback(ortc, 'Invalid Cluster URL');\r\n        }\r\n        else if (!ortcIsValidInput(appKey)) {\r\n            delegateExceptionCallback(ortc, 'Application Key has invalid characters');\r\n        }\r\n        else if (!ortcIsValidInput(authToken)) {\r\n            delegateExceptionCallback(ortc, 'Authentication Token has invalid characters');\r\n        }\r\n        else if (!ortcIsValidInput(announcementSubChannel)) {\r\n            delegateExceptionCallback(ortc, 'Announcement Subchannel has invalid characters');\r\n        }\r\n        else if (connectionMetadata && connectionMetadata.length > connectionMetadataMaxSize) {\r\n            delegateExceptionCallback(ortc, 'Connection metadata size exceeds the limit of ' + connectionMetadataMaxSize + ' characters');\r\n        }\r\n        else {\r\n            ortc.appKey = appKey;\r\n            ortc.authToken = authToken;\r\n\r\n            isConnecting = true;\r\n            stopReconnecting = false;\r\n\r\n            if (clusterUrl && clusterUrl != null) {\r\n                clusterUrl = ortcTreatUrl(clusterUrl);\r\n\r\n                clusterConnection(ortc.getConnectionTimeout());\r\n            }\r\n            else {\r\n                url = ortcTreatUrl(url);\r\n\r\n                ortc.sockjs = createSocketConnection(url);\r\n            }\r\n\r\n            if (!ortc.reconnectTimeoutlId) {\r\n                // Timeout to reconnect\r\n                ortc.reconnectTimeoutlId = setTimeout(function () {\r\n                    if (!isConnected) {\r\n                        reconnectSocket(ortc.getConnectionTimeout());\r\n                    }\r\n                }, ortc.getConnectionTimeout());\r\n            }\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Subscribes to the channel so the client object can receive all messages sent to it by other clients.\r\n    */\r\n    this.subscribe = function (channel, subscribeOnReconnected, onMessageCallback) {\r\n        /*\r\n        Sanity Checks\r\n        */\r\n        if (!isConnected) {\r\n            delegateExceptionCallback(ortc, 'Not connected');\r\n        }\r\n        else if (!channel) {\r\n            delegateExceptionCallback(ortc, 'Channel is null or empty');\r\n        }\r\n        else if (!ortcIsValidInput(channel)) {\r\n            delegateExceptionCallback(ortc, 'Channel has invalid characters');\r\n        }\r\n        else if (subscribedChannels[channel] && subscribedChannels[channel].isSubscribing) {\r\n            delegateExceptionCallback(ortc, 'Already subscribing to the channel \\'' + channel + '\\'');\r\n        }\r\n        else if (subscribedChannels[channel] && subscribedChannels[channel].isSubscribed) {\r\n            delegateExceptionCallback(ortc, 'Already subscribed to the channel \\'' + channel + '\\'');\r\n        }\r\n        else if (channel.length > channelMaxSize) {\r\n            delegateExceptionCallback(ortc, 'Channel size exceeds the limit of ' + channelMaxSize + ' characters');\r\n        }\r\n        else if (!ortcIsValidBoolean(subscribeOnReconnected)) {\r\n            delegateExceptionCallback(ortc, 'The argument \\'subscribeOnReconnected\\' must be a boolean');\r\n        }\r\n        else if (!ortcIsFunction(onMessageCallback)) {\r\n            delegateExceptionCallback(ortc, 'The argument \\'onMessageCallback\\' must be a function');\r\n        }\r\n        else {\r\n            if (ortc.sockjs != null) {\r\n                var domainChannelCharacterIndex = channel.indexOf(':');\r\n                var channelToValidate = channel;\r\n                var hashPerm = null;\r\n\r\n                if (domainChannelCharacterIndex > 0) {\r\n                    channelToValidate = channel.substring(0, domainChannelCharacterIndex + 1) + '*';\r\n                }\r\n\r\n                if (userPerms && userPerms != null) {\r\n                    hashPerm = userPerms[channelToValidate] ? userPerms[channelToValidate] : userPerms[channel];\r\n                }\r\n\r\n                if (userPerms && userPerms != null && !hashPerm) {\r\n                    delegateExceptionCallback(ortc, 'No permission found to subscribe to the channel \\'' + channel + '\\'');\r\n                }\r\n                else {\r\n                    if (subscribedChannels[channel]) {\r\n                        subscribedChannels[channel].isSubscribing = true;\r\n                        subscribedChannels[channel].isSubscribed = false;\r\n                        subscribedChannels[channel].subscribeOnReconnected = subscribeOnReconnected;\r\n                        subscribedChannels[channel].onMessageCallback = onMessageCallback;\r\n                    }\r\n                    else {\r\n                        subscribedChannels[channel] = { 'isSubscribing': true, 'isSubscribed': false, 'subscribeOnReconnected': subscribeOnReconnected, 'onMessageCallback': onMessageCallback };\r\n                    }\r\n\r\n                    ortc.sockjs.send(JSON.stringify('subscribe;' + ortc.appKey + ';' + ortc.authToken + ';' + channel + ';' + hashPerm));\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Unsubscribes from the channel so the client object stops receiving messages sent to it.\r\n    */\r\n    this.unsubscribe = function (channel) {\r\n        /*\r\n        Sanity Checks\r\n        */\r\n        if (!isConnected) {\r\n            delegateExceptionCallback(ortc, 'Not connected');\r\n        }\r\n        else if (!channel) {\r\n            delegateExceptionCallback(ortc, 'Channel is null or empty');\r\n        }\r\n        else if (!ortcIsValidInput(channel)) {\r\n            delegateExceptionCallback(ortc, 'Channel has invalid characters');\r\n        }\r\n        else if (!subscribedChannels[channel] || (subscribedChannels[channel] && !subscribedChannels[channel].isSubscribed)) {\r\n            delegateExceptionCallback(ortc, 'Not subscribed to the channel ' + channel);\r\n        }\r\n        else if (channel.length > channelMaxSize) {\r\n            delegateExceptionCallback(ortc, 'Channel size exceeds the limit of ' + channelMaxSize + ' characters');\r\n        }\r\n        else {\r\n            if (ortc.sockjs != null) {\r\n                ortc.sockjs.send(JSON.stringify('unsubscribe;' + ortc.appKey + ';' + channel));\r\n            }\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Sends the message to the channel.\r\n    */\r\n    this.send = function (channel, message) {\r\n        /*\r\n        Sanity Checks\r\n        */\r\n        if (!isConnected || ortc.sockjs == null) {\r\n            delegateExceptionCallback(ortc, 'Not connected');\r\n        }\r\n        else if (!channel) {\r\n            delegateExceptionCallback(ortc, 'Channel is null or empty');\r\n        }\r\n        else if (!ortcIsValidInput(channel)) {\r\n            delegateExceptionCallback(ortc, 'Channel has invalid characters');\r\n        }\r\n        else if (!message) {\r\n            delegateExceptionCallback(ortc, 'Message is null or empty');\r\n        }\r\n        else if (!ortcIsString(message)) {\r\n            delegateExceptionCallback(ortc, 'Message must be a string');\r\n        }\r\n        else if (channel.length > channelMaxSize) {\r\n            delegateExceptionCallback(ortc, 'Channel size exceeds the limit of ' + channelMaxSize + ' characters');\r\n        }\r\n        else {\r\n            var domainChannelCharacterIndex = channel.indexOf(':');\r\n            var channelToValidate = channel;\r\n            var hashPerm = null;\r\n\r\n            if (domainChannelCharacterIndex > 0) {\r\n                channelToValidate = channel.substring(0, domainChannelCharacterIndex + 1) + '*';\r\n            }\r\n\r\n            if (userPerms && userPerms != null) {\r\n                hashPerm = userPerms[channelToValidate] ? userPerms[channelToValidate] : userPerms[channel];\r\n            }\r\n\r\n            if (userPerms && userPerms != null && !hashPerm) {\r\n                delegateExceptionCallback(ortc, 'No permission found to send to the channel \\'' + channel + '\\'');\r\n            }\r\n            else {\r\n                // Multi part\r\n                var messageParts = [];\r\n                var messageId = generateId(8);\r\n                var i;\r\n                var allowedMaxSize = messageMaxSize - channel.length;\r\n\r\n                for (i = 0; i < message.length; i = i + allowedMaxSize) {\r\n                    // Just one part\r\n                    if (message.length <= allowedMaxSize) {\r\n                        messageParts.push(message);\r\n                        break;\r\n                    }\r\n\r\n                    if (message.substring(i, i + allowedMaxSize)) {\r\n                        messageParts.push(message.substring(i, i + allowedMaxSize));\r\n                    }\r\n                }\r\n\r\n                if (messageParts.length == 1) {\r\n                    ortc.sockjs.send(JSON.stringify('send;' + ortc.appKey + ';' + ortc.authToken + ';' + channel + ';' + hashPerm + ';' + messageId + '_1-1_' + messageParts[0]));\r\n                }\r\n                else {\r\n                    for (var j = 1; j <= messageParts.length; j++) {\r\n                        var messageToSend = 'send;' + ortc.appKey + ';' + ortc.authToken + ';' + channel + ';' + hashPerm + ';' + messageId + '_' + j + '-' + messageParts.length + '_' + messageParts[j - 1];\r\n                        this.sendMultiPartMessage(messageToSend);                        \r\n                    }\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Sends the message to the channel.\r\n    */\r\n    this.sendProxy = function (applicationKey, privateKey, channel, message) {\r\n        /*\r\n        Sanity Checks\r\n        */\r\n        if (!isConnected || ortc.sockjs == null) {\r\n            delegateExceptionCallback(ortc, 'Not connected');\r\n        }\r\n        else if (!applicationKey) {\r\n            delegateExceptionCallback(ortc, 'Application key is null or empty');\r\n        }\r\n        else if (!privateKey) {\r\n            delegateExceptionCallback(ortc, 'Private key is null or empty');\r\n        }\r\n        else if (!channel) {\r\n            delegateExceptionCallback(ortc, 'Channel is null or empty');\r\n        }\r\n        else if (!ortcIsValidInput(channel)) {\r\n            delegateExceptionCallback(ortc, 'Channel ' + channel + ' has invalid characters');\r\n        }\r\n        else if (!message) {\r\n            delegateExceptionCallback(ortc, 'Message is null or empty');\r\n        }\r\n        else if (!ortcIsString(message)) {\r\n            delegateExceptionCallback(ortc, 'Message must be a string');\r\n        }\r\n        else if (channel.length > channelMaxSize) {\r\n            delegateExceptionCallback(ortc, 'Channel size exceeds the limit of ' + channelMaxSize + ' characters');\r\n        }\r\n        else {\r\n\r\n            // Multi part\r\n            var messageParts = [];\r\n            var messageId = generateId(8);\r\n            var i;\r\n            var allowedMaxSize = messageMaxSize - channel.length;\r\n\r\n            for (i = 0; i < message.length; i = i + allowedMaxSize) {\r\n                // Just one part\r\n                if (message.length <= allowedMaxSize) {\r\n                    messageParts.push(message);\r\n                    break;\r\n                }\r\n\r\n                if (message.substring(i, i + allowedMaxSize)) {\r\n                    messageParts.push(message.substring(i, i + allowedMaxSize));\r\n                }\r\n            }\r\n\r\n            if (messageParts.length == 1) {\r\n                ortc.sockjs.send(JSON.stringify('sendproxy;' + applicationKey + ';' + privateKey + ';' + channel + ';' + messageId + '_1-1_' + messageParts[0]));\r\n            }\r\n            else {\r\n                for (var j = 1; j <= messageParts.length; j++) {\r\n                    var messageToSend = 'sendproxy;' + applicationKey + ';' + privateKey + ';' + channel + ';' + messageId + '_' + j + '-' + messageParts.length + '_' + messageParts[j - 1];\r\n                    this.sendMultiPartMessage(messageToSend);                        \r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n\r\n    this.sendMultiPartMessage = function(message){\r\n        process.nextTick(function(){\r\n            ortc.sockjs.send(JSON.stringify(message));\r\n        });\r\n    }\r\n\r\n    /*\r\n    * Disconnects from the gateway.\r\n    */\r\n    this.disconnect = function () {\r\n        clearReconnectInterval();\r\n\r\n        // Stop the reconnecting process\r\n        stopReconnecting = true;\r\n        alreadyConnectedFirstTime = false;\r\n\r\n        // Clear subscribed channels\r\n        subscribedChannels = Object.create(null);\r\n\r\n        /*\r\n        Sanity Checks\r\n        */\r\n        if (!isConnected && !invalidConnection) {\r\n            delegateExceptionCallback(ortc, 'Not connected');\r\n        }\r\n        else {\r\n            disconnectSocket();\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Gets a value indicating whether this client object is subscribed to the channel.\r\n    */\r\n    this.isSubscribed = function (channel) {\r\n        /*\r\n        Sanity Checks\r\n        */\r\n        if (!isConnected) {\r\n            delegateExceptionCallback(ortc, 'Not connected');\r\n        }\r\n        else if (!channel) {\r\n            delegateExceptionCallback(ortc, 'Channel is null or empty');\r\n        }\r\n        else if (!ortcIsValidInput(channel)) {\r\n            delegateExceptionCallback(ortc, 'Channel has invalid characters');\r\n        }\r\n        else {\r\n            if (subscribedChannels[channel] && subscribedChannels[channel].isSubscribed) {\r\n                return subscribedChannels[channel].isSubscribed;\r\n            }\r\n            else {\r\n                return false;\r\n            }\r\n        }\r\n    };   \r\n\t\r\n    /**\r\n    * @function {public} saveAuthentication Saves the channels and its permissions for the supplied application key and authentication token.\r\n    * @param {string} url The ORTC server URL.\r\n    * @param {bool} isCluster Indicates whether the ORTC server is in a cluster.\r\n    * @param {string} authenticationToken The authentication token generated by an application server (for instance: a unique session ID).\r\n    * @param {bool} authenticationTokenIsPrivate Indicates whether the authentication token is private.\r\n    * @param {string} applicationKey The application key provided when the ORTC service is purchased.\r\n    * @param {int} timeToLive The authentication token time to live (TTL), in other words, the allowed activity time (in seconds).\r\n    * @param {string} privateKey The private key provided when the ORTC service is purchased.\r\n    * @param {object} permissions The channels and their permissions (w: write/read or r: read or p: presence, case sensitive).\r\n    * @param {function(error, success)} callback Function called when the authentication finishes. If 'error' is not null then an error occurred.\r\n    * @returns void\r\n\r\n    * @returns void\r\n    *\r\n    * </br>\r\n    * <b class=\"codeSample\">Code Sample:</b>\r\n    *\r\n    * <pre class=\"brush: js; gutter: false;\">\r\n    *   ortcClient.saveAuthentication('http://developers2.realtime.livehtml.net/server/2.1/', true, 'myAuthenticationToken', 0, 'myApplicationKey', 1400, 'myPrivateKey', { \"channel1\": \"wrp\", \"channel2\": \"w\" }, function (error, success) {\r\n    *       if (error) {\r\n    *           console.log('Error saving authentication: ' + error);\r\n    *       } else if (success) {\r\n    *           console.log('Successfully authenticated');\r\n    *       } else {\r\n    *           console.log('Not authenticated');\r\n    *       }\r\n    *   });\r\n    * </pre>\r\n    */\r\n    this.saveAuthentication = function (url, isCluster, authenticationToken, authenticationTokenIsPrivate, applicationKey, timeToLive, privateKey, permissions, callback) {\r\n        var connectionUrl = url;\r\n\r\n        if (isCluster) {\r\n            getServerFromCluster({\r\n                clusterUri : connectionUrl, \r\n                connectionTimeout : ortc.getConnectionTimeout(),\r\n                appKey : applicationKey\r\n            }, \r\n            function (error, body) {\r\n                if (error != null) {\r\n                    delegateExceptionCallback(ortc, 'Error getting server from Cluster');\r\n                    callback('Error getting server from Cluster',null);\r\n                }\r\n                else {\r\n                    connectionUrl = body.substring(body.indexOf('=') + 3, body.length - 2);\r\n                    IbtRealtimeRestServices.saveAuthentication(connectionUrl, authenticationToken, authenticationTokenIsPrivate, applicationKey, timeToLive, privateKey, permissions, callback);\r\n                }\r\n            });\r\n        } else {\r\n            IbtRealtimeRestServices.saveAuthentication(connectionUrl, authenticationToken, authenticationTokenIsPrivate, applicationKey, timeToLive, privateKey, permissions, callback);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * @function {public} presence Gets a json indicating the subscriptions in the specified channel and if active the first 100 unique metadata.\r\n     * @param {object} Object literal with presence attributes.\r\n     * @... {String} url Server containing the presence service (optional if connected).\r\n     * @... {bool} isCluster Specifies if url is cluster (optional if connected).\r\n     * @... {String} applicationKey Application key with access to presence service (optional if connected).\r\n     * @... {String} authenticationToken Authentication token with access to presence service (optional if connected).\r\n     * @... {String} channel Channel with presence data active.\r\n     * @param {function} Callback with error and result parameters.\r\n     * @returns void\r\n     * \r\n     * </br>\r\n     * <b class=\"codeSample\">Code Sample:</b>\r\n     *\r\n     * <pre class=\"brush: js; gutter: false;\">\r\n     *      ortcClient.presence({\r\n     *          applicationKey : 'ORTC_APPLICATION_KEY',\r\n     *          authenticationToken : 'AUTHENTICATION_TOKEN',\r\n     *          isCluster : true,\r\n     *          url : 'http://ortc-developers.realtime.co/server/2.1/',\r\n     *          channel : 'CHANNEL_WITH_ACTIVE_PRESENCE'\r\n     *      },\r\n     *      function(error,result){\r\n     *          if(error){\r\n     *              console.log('Presence error:',error);\r\n     *          }else{\r\n     *              if(result){\r\n     *                  console.log('Subscriptions',result.subscriptions);  \r\n     *\r\n     *                  for(var metadata in result.metadata){\r\n     *                      console.log(metadata,'-',result.metadata[metadata]);                                    \r\n     *                  }\r\n     *              }else{\r\n     *                  console.log('Subscriptions empty'); \r\n     *              }                           \r\n     *          }\r\n     *      }); \r\n     * </pre>\r\n     */\r\n    this.presence = function (parameters,callback) {\r\n        try{\r\n            var requestUrl = null\r\n            , isCluster = false\r\n            , appKey = ortc.appKey\r\n            , authToken = ortc.authToken;\r\n\r\n            if(parameters.url){\r\n                requestUrl = parameters.url;\r\n                isCluster = parameters.isCluster;\r\n                appKey = parameters.applicationKey;\r\n                authToken = parameters.authenticationToken;\r\n            }else{\r\n                if (clusterUrl && clusterUrl != null) {\r\n                    requestUrl = clusterUrl;\r\n                    isCluster = true;\r\n                }\r\n                else {\r\n                    requestUrl = url;\r\n                }    \r\n            }\r\n\r\n            getServerUrl({\r\n                requestUrl : requestUrl,\r\n                isCluster : isCluster,\r\n                appKey : appKey\r\n            },\r\n            function(error,serverUrl){\r\n                if(error){\r\n                    callback(error,null);\r\n                }else{\r\n                    IbtRealtimeRestServices.getPresence({\r\n                        url : serverUrl,\r\n                        appKey : appKey, \r\n                        authToken : authToken,\r\n                        channel : parameters.channel\r\n                    },callback);\r\n                }\r\n            });\r\n        }catch(e){\r\n            callback('Unable to get presence data ' + e,null);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * @function {public} enablePresence Enables presence for the specified channel with first 100 unique metadata if true.\r\n     * @param {object} Object literal with presence attributes.\r\n     * @... {String} url Server containing the presence service (optional if connected).\r\n     * @... {bool} isCluster Specifies if url is cluster (optional if connected).\r\n     * @... {String} applicationKey Application key with access to presence service (optional if connected).\r\n     * @... {String} privateKey The private key provided when the ORTC service is purchased.\r\n     * @... {String} channel Channel to activate presence.\r\n     * @... {bool} metadata Defines if to collect first 100 unique metadata.\r\n     * @param {function} Callback with error and result parameters.\r\n     * @returns void\r\n     * \r\n     * </br>\r\n     * <b class=\"codeSample\">Code Sample:</b>\r\n     *\r\n     * <pre class=\"brush: js; gutter: false;\">\r\n     *      ortcClient.enablePresence({\r\n     *          applicationKey : 'ORTC_APPLICATION_KEY',\r\n     *          channel : 'CHANNEL_TO_ACTIVATE_PRESENCE', \r\n     *          privateKey : 'ORTC_PRIVATE_KEY', \r\n     *          url : 'http://ortc-developers.realtime.co/server/2.1/',\r\n     *          isCluster : true,\r\n                metadata : true\r\n     *      },\r\n     *      function(error,result){\r\n     *          if(error){\r\n     *              console.log('Presence',error);  \r\n     *          }else{\r\n     *              console.log('Presence enable',result);              \r\n     *      }); \r\n     * </pre>\r\n     */\r\n    this.enablePresence = function (parameters,callback) {\r\n        try{\r\n            var requestUrl = null\r\n            , isCluster = false\r\n            , appKey = ortc.appKey;\r\n\r\n            if(parameters.url){\r\n                requestUrl = parameters.url;\r\n                isCluster = parameters.isCluster;\r\n                appKey = parameters.applicationKey;\r\n            }else{\r\n                if (clusterUrl && clusterUrl != null) {\r\n                    requestUrl = clusterUrl;\r\n                    isCluster = true;\r\n                }\r\n                else {\r\n                    requestUrl = url;\r\n                }    \r\n            }\r\n\r\n            getServerUrl({\r\n                requestUrl : requestUrl,\r\n                isCluster : isCluster,\r\n                appKey : appKey\r\n            },\r\n            function(error,serverUrl){\r\n                if(error){\r\n                    callback(error,null);\r\n                }else{\r\n                    IbtRealtimeRestServices.enablePresence({\r\n                        url : serverUrl,\r\n                        appKey : appKey, \r\n                        privateKey : parameters.privateKey,\r\n                        channel : parameters.channel,\r\n                        metadata : parameters.metadata == true ? 1 : 0\r\n                    },callback);\r\n                }\r\n            });\r\n        }catch(e){\r\n            callback('Unable to enable presence ' + e,null);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * @function {public} disablePresence Disables presence for the specified channel.\r\n     * @param {object} Object literal with presence attributes.\r\n     * @... {String} url Server containing the presence service (optional if connected).\r\n     * @... {bool} isCluster Specifies if url is cluster (optional if connected).\r\n     * @... {String} applicationKey Application key with access to presence service (optional if connected).\r\n     * @... {String} privateKey The private key provided when the ORTC service is purchased.\r\n     * @... {String} channel Channel to disable presence.\r\n     * @param {function} Callback with error and result parameters.\r\n     * @returns void\r\n     * \r\n     * </br>\r\n     * <b class=\"codeSample\">Code Sample:</b>\r\n     *\r\n     * <pre class=\"brush: js; gutter: false;\">\r\n     *      ortcClient.disablePresence({\r\n     *          applicationKey : 'ORTC_APPLICATION_KEY',\r\n     *          channel : 'CHANNEL_TO_ACTIVATE_PRESENCE', \r\n     *          privateKey : 'ORTC_PRIVATE_KEY', \r\n     *          url : 'http://ortc-developers.realtime.co/server/2.1/',\r\n     *          isCluster : true\r\n     *      },\r\n     *      function(error,result){\r\n     *          if(error){\r\n     *              console.log('Presence',error);  \r\n     *          }else{\r\n     *              console.log('Presence enable',result);              \r\n     *      }); \r\n     * </pre>\r\n     */\r\n    this.disablePresence = function (parameters,callback) {\r\n        try{\r\n            var requestUrl = null\r\n            , isCluster = false\r\n            , appKey = ortc.appKey;\r\n\r\n            if(parameters.url){\r\n                requestUrl = parameters.url;\r\n                isCluster = parameters.isCluster;\r\n                appKey = parameters.applicationKey;\r\n            }else{\r\n                if (clusterUrl && clusterUrl != null) {\r\n                    requestUrl = clusterUrl;\r\n                    isCluster = true;\r\n                }\r\n                else {\r\n                    requestUrl = url;\r\n                }    \r\n            }\r\n\r\n            getServerUrl({\r\n                requestUrl : requestUrl,\r\n                isCluster : isCluster,\r\n                appKey : appKey\r\n            },\r\n            function(error,serverUrl){\r\n                if(error){\r\n                    callback(error,null);\r\n                }else{\r\n                    IbtRealtimeRestServices.disablePresence({\r\n                        url : serverUrl,\r\n                        appKey : appKey, \r\n                        privateKey : parameters.privateKey,\r\n                        channel : parameters.channel\r\n                    },callback);\r\n                }\r\n            });\r\n        }catch(e){\r\n            callback('Unable to disable presence ' + e,null);\r\n        }\r\n    };\r\n\r\n    /***********************************************************\r\n    * @private methods\r\n    ***********************************************************/\r\n\r\n    var getServerUrl = function(parameters,callback){\r\n         if (parameters.requestUrl && parameters.isCluster) {\r\n            var clusterUrl = ortcTreatUrl(parameters.requestUrl);\r\n\r\n            getServerFromCluster({\r\n                clusterUri : clusterUrl, \r\n                appKey : parameters.appKey\r\n            }, \r\n            function (error, body) {\r\n                if (error != null) {\r\n                    callback('Error getting server from Cluster',null);\r\n                }\r\n                else {\r\n                    var resultUrl = body.substring(body.indexOf('=') + 3, body.length - 2);\r\n                    callback(null,resultUrl);\r\n                }\r\n            });\r\n        }\r\n        else {\r\n            var resultUrl = ortcTreatUrl(parameters.requestUrl);\r\n            callback(null,resultUrl);\r\n        }\r\n    };\r\n\r\n    var clearReconnectInterval = function () {\r\n        // Clear the reconnecting interval\r\n        if (ortc.reconnectIntervalId) {\r\n            clearInterval(ortc.reconnectIntervalId);\r\n            ortc.reconnectIntervalId = null;\r\n        }\r\n\r\n        // Clear the reconnecting timeout\r\n        if (ortc.reconnectTimeoutlId) {\r\n            clearTimeout(ortc.reconnectTimeoutlId);\r\n            ortc.reconnectTimeoutlId = null;\r\n        }\r\n    };\r\n\r\n    var ortcIsValidUrl = function (input) {\r\n        return (/^\\s*(http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-\\/]))?\\s*$/).exec(input) ? true : false;\r\n    };\r\n\r\n    var ortcIsValidInput = function (input) {\r\n        return (/^[\\w-:\\/\\.]*$/).exec(input) ? true : false;\r\n    };\r\n\r\n    var ortcIsValidBoolean = function (input) {\r\n        return (/^(true|false|0|1)$/).exec(input) ? true : false;\r\n    };\r\n\r\n    var ortcIsFunction = function (input) {\r\n        return typeof (input) == 'function' ? true : false;\r\n    };\r\n\r\n    var ortcIsString = function (input) {\r\n        return typeof (input) == 'string' ? true : false;\r\n    };\r\n\r\n    var ortcTreatUrl = function (url) {\r\n        url = url.replace(/\\s+/g, '');\r\n\r\n        if (url.charAt(url.length - 1) == '/') {\r\n            url = url.substring(0, url.length - 1);\r\n        }\r\n\r\n        return url;\r\n    };\r\n\r\n    /*\r\n    * Generates an ID.\r\n    */\r\n    var generateId = function (size) {\r\n        var result = '';\r\n\r\n        var S4 = function () {\r\n            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);\r\n        };\r\n\r\n        for (var i = 0; i < size / 4; i++) {\r\n            result += S4();\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    /*\r\n    * Disconnects the socket.\r\n    */\r\n    var disconnectSocket = function () {\r\n        reconnectStartedAt = null;\r\n        isConnecting = false;\r\n\r\n        if (ortc.sockjs != null) {\r\n            ortc.sockjs.close();\r\n            ortc.sockjs = null;\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Reconnects the socket.\r\n    */\r\n    var reconnectSocket = function (clusterTimeout) {\r\n        clearReconnectInterval();\r\n\r\n        ortc.sockjs = null;\r\n\r\n        if (isConnecting) {\r\n            delegateExceptionCallback(ortc, 'Unable to connect');\r\n        }\r\n\r\n        isConnecting = true;\r\n\r\n        delegateReconnectingCallback(ortc);\r\n\r\n        reconnectStartedAt = new Date().getTime();\r\n\r\n        if (clusterUrl && clusterUrl != null) {\r\n            clusterConnection(clusterTimeout);\r\n        }\r\n        else {\r\n            ortc.sockjs = createSocketConnection(url);\r\n        }\r\n\r\n        if (!ortc.reconnectTimeoutlId) {\r\n            // Timeout to reconnect\r\n            ortc.reconnectTimeoutlId = setTimeout(function () {\r\n                if (!isConnected) {\r\n                    reconnectSocket(ortc.getConnectionTimeout());\r\n                }\r\n            }, ortc.getConnectionTimeout());\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Tries a connection through the cluster gateway with the application key and authentication token.\r\n    */\r\n    var clusterConnection = function (clusterTimeout) {\r\n        if (clusterUrl != null) {\r\n            getServerFromCluster({\r\n                clusterUri : clusterUrl, \r\n                clusterTimeout : clusterTimeout,\r\n                appKey : ortc.appKey\r\n            }, \r\n            function (error, body) {\r\n                if (error != null) {\r\n                    delegateExceptionCallback(ortc, 'Error getting server from Cluster');\r\n                }\r\n                else {\r\n                    if (body.indexOf('SOCKET_SERVER') >= 0) {\r\n                        url = body.substring(body.indexOf('=') + 3, body.length - 2);\r\n                        sockjs = createSocketConnection(ortc.getUrl());\r\n                    }\r\n                }\r\n            });\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Gets server from the cluster.\r\n    */\r\n    var getServerFromCluster = function (parameters,callback) {\r\n        var queryString = parameters.appKey ? 'appkey=' + parameters.appKey : \"\";\r\n\r\n        var parsedUrl = urlParser.parse(parameters.clusterUri + '?' + queryString);\r\n        \r\n        httpRequest.get({\r\n            url : parsedUrl.hostname,        \r\n            path : parsedUrl.pathname,\r\n            parameters : parsedUrl.query,\r\n            callback : function(error,responseData){\r\n                if (error != null) {\r\n                    callback(error, null);\r\n                }\r\n                else {\r\n                    callback(null, responseData.content);\r\n                }\r\n            }\r\n        });\r\n    };\r\n\r\n    /*\r\n    * Creates a socket connection.\r\n    */\r\n    var createSocketConnection = function (connectionUrl) {\r\n        if (ortc.sockjs == null) {\r\n            var wsScheme = 'ws';\r\n            var wsUrl = connectionUrl;\r\n\r\n            if (connectionUrl.substring(0, 7) == 'http://') {\r\n                wsUrl = wsUrl.substring(7);\r\n            }\r\n            else if (connectionUrl.substring(0, 8) == 'https://') {\r\n                wsUrl = wsUrl.substring(8);\r\n                wsScheme = 'wss';\r\n            }\r\n\r\n            var connid = strings.random_string(8);\r\n            var serverId = strings.random_number_string(1000);\r\n            ortc.sockjs = new WebSocket(wsScheme + '://' + wsUrl + '/broadcast/' + serverId + '/' + connid + '/websocket');\r\n\r\n            // Connect handler\r\n            ortc.sockjs.onopen = function () {\r\n                // Update last keep alive time\r\n                lastKeepAlive = new Date().getTime();\r\n\r\n                ortc.sockjs.send(JSON.stringify('validate;' + ortc.appKey + ';' + ortc.authToken + ';' + (announcementSubChannel ? announcementSubChannel : '') + ';' + '' + ';' + (connectionMetadata ? connectionMetadata : '')));\r\n            };\r\n\r\n            // Disconnect handler\r\n            ortc.sockjs.onclose = function (e) {\r\n                ortc.sockjs = null;\r\n\r\n                if (isConnected) {\r\n                    isConnected = false;\r\n                    isConnecting = false;\r\n\r\n                    delegateDisconnectedCallback(ortc);\r\n                }\r\n\r\n                if (!stopReconnecting && (!reconnectStartedAt || (reconnectStartedAt + connectionTimeout < new Date().getTime()))) {\r\n                    reconnectSocket(ortc.getConnectionTimeout());\r\n                }\r\n            };\r\n\r\n            // Error handler (when connecting to an non existent server)\r\n            ortc.sockjs.onerror = function () {\r\n            };\r\n\r\n            // Receive handler\r\n            ortc.sockjs.onmessage = function (m) {\r\n                // Update last keep alive time\r\n                lastKeepAlive = new Date().getTime();\r\n\r\n                var messageType = m.data[0];\r\n\r\n                switch (messageType) {\r\n                    case 'o': // open\r\n                        break;\r\n                    case 'a': // message\r\n                        var data = JSON.parse(JSON.parse(m.data.substring(1))[0]);\r\n                        var op = data.op;\r\n\r\n                        switch (op) {\r\n                            case 'ortc-validated':\r\n                                if (data.up) {\r\n                                    userPerms = data.up; // user permissions\r\n                                }\r\n\r\n                                isConnecting = false;\r\n                                isConnected = true;\r\n                                reconnectStartedAt = null;\r\n\r\n                                if (alreadyConnectedFirstTime) {\r\n                                    var channelsToRemove = Object.create(null);\r\n\r\n                                    // Subscribe to the previously subscribed channels\r\n                                    for (var key in subscribedChannels) {\r\n                                        // Subscribe again\r\n                                        if (subscribedChannels[key].subscribeOnReconnected == true && (subscribedChannels[key].isSubscribing || subscribedChannels[key].isSubscribed)) {\r\n                                            subscribedChannels[key].isSubscribing = true;\r\n                                            subscribedChannels[key].isSubscribed = false;\r\n\r\n                                            var domainChannelCharacterIndex = key.indexOf(':');\r\n                                            var channelToValidate = key;\r\n                                            var hashPerm = null;\r\n\r\n                                            if (domainChannelCharacterIndex > 0) {\r\n                                                channelToValidate = key.substring(0, domainChannelCharacterIndex + 1) + '*';\r\n                                            }\r\n\r\n                                            if (userPerms && userPerms != null) {\r\n                                                hashPerm = userPerms[channelToValidate] ? userPerms[channelToValidate] : userPerms[key];\r\n                                            }\r\n\r\n                                            ortc.sockjs.send(JSON.stringify('subscribe;' + ortc.appKey + ';' + ortc.authToken + ';' + key + ';' + hashPerm));\r\n                                        }\r\n                                        else {\r\n                                            channelsToRemove[key] = key;\r\n                                        }\r\n                                    }\r\n\r\n                                    for (var chnKey in channelsToRemove) {                                        \r\n                                        ObjectLiterals.removeEntry(subscribedChannels,chnKey);\r\n                                    }\r\n\r\n                                    // Clean messages buffer (can have lost message parts in memory)\r\n                                    messagesBuffer = Object.create(null);\r\n\r\n                                    delegateReconnectedCallback(ortc);\r\n                                }\r\n                                else {\r\n                                    alreadyConnectedFirstTime = true;\r\n\r\n                                    delegateConnectedCallback(ortc);\r\n                                }\r\n\r\n                                if (!ortc.reconnectIntervalId) {\r\n                                    // Interval to reconnect\r\n                                    ortc.reconnectIntervalId = setInterval(function () {\r\n                                        if (lastKeepAlive != null && (lastKeepAlive + 35000 < new Date().getTime())) { // 35 seconds\r\n                                            lastKeepAlive = null;\r\n\r\n                                            // Server went down\r\n                                            if (isConnected) {\r\n                                                disconnectSocket();\r\n\r\n                                                if (isConnected) {\r\n                                                    isConnected = false;\r\n                                                    isConnecting = false;\r\n\r\n                                                    delegateDisconnectedCallback(ortc);\r\n\r\n                                                    reconnectSocket(ortc.getConnectionTimeout());\r\n                                                }\r\n                                            }\r\n                                        }\r\n                                    }, ortc.getConnectionTimeout());\r\n                                }\r\n\r\n                                break;\r\n                            case 'ortc-subscribed':\r\n                                var channelSubscribed = data.ch;\r\n\r\n                                if (subscribedChannels[channelSubscribed]) {\r\n                                    subscribedChannels[channelSubscribed].isSubscribing = false;\r\n                                    subscribedChannels[channelSubscribed].isSubscribed = true;\r\n                                }\r\n\r\n                                delegateSubscribedCallback(ortc, channelSubscribed)\r\n                                break;\r\n                            case 'ortc-unsubscribed':\r\n                                var channelUnsubscribed = data.ch;\r\n\r\n                                if (subscribedChannels[channelUnsubscribed]) {\r\n                                    subscribedChannels[channelUnsubscribed].isSubscribing = false;\r\n                                    subscribedChannels[channelUnsubscribed].isSubscribed = false;\r\n                                }\r\n\r\n                                delegateUnsubscribedCallback(ortc, channelUnsubscribed)\r\n                                break;\r\n                            case 'ortc-error':\r\n                                var data = data.ex ? data.ex : data;\r\n                                var operation = data.op;\r\n                                var error = data.ex;\r\n\r\n                                delegateExceptionCallback(ortc, error);\r\n                                switch (operation) {\r\n                                    case 'validate':\r\n                                        if(error.indexOf(\"Unable to connect\") > -1 || error.indexOf(\"Server is too busy\") > -1){\r\n                                            \r\n                                        }else{\r\n                                            invalidConnection = true;\r\n\r\n                                            // Stop the reconnecting process\r\n                                            stopReconnecting = true;\r\n                                            alreadyConnectedFirstTime = false;\r\n\r\n                                            clearReconnectInterval();\r\n                                        }                                        \r\n                                        break;\r\n                                    case 'subscribe':\r\n                                        if (channel && subscribedChannels[channel]) {\r\n                                            subscribedChannels[channel].isSubscribing = false;\r\n                                        }\r\n                                        break;\r\n                                    case 'subscribe_maxsize':\r\n                                    case 'unsubscribe_maxsize':\r\n                                    case 'send_maxsize':\r\n                                        if (channel && subscribedChannels[channel]) {\r\n                                            subscribedChannels[channel].isSubscribing = false;\r\n                                        }\r\n\r\n                                        // Stop the reconnecting process\r\n                                        stopReconnecting = true;\r\n                                        alreadyConnectedFirstTime = false;\r\n\r\n                                        clearReconnectInterval();\r\n                                        break;\r\n                                    default:\r\n                                        break;\r\n                                }\r\n\r\n                                if (stopReconnecting) {\r\n                                    delegateDisconnectedCallback(ortc);\r\n                                }\r\n                                break;\r\n                            default:\r\n                                var channel = data.ch;\r\n                                var message = data.m;\r\n\r\n                                // Multi part\r\n                                var regexPattern = /^(\\w[^_]*)_{1}(\\d*)-{1}(\\d*)_{1}([\\s\\S.]*)$/;\r\n                                var match = regexPattern.exec(message);\r\n\r\n                                var messageId = null;\r\n                                var messageCurrentPart = 1;\r\n                                var messageTotalPart = 1;\r\n                                var lastPart = false;\r\n\r\n                                if (match && match.length > 0) {\r\n                                    if (match[1]) {\r\n                                        messageId = match[1];\r\n                                    }\r\n                                    if (match[2]) {\r\n                                        messageCurrentPart = match[2];\r\n                                    }\r\n                                    if (match[3]) {\r\n                                        messageTotalPart = match[3];\r\n                                    }\r\n                                    if (match[4]) {\r\n                                        message = match[4];\r\n                                    }\r\n                                }\r\n\r\n                                // Is a message part\r\n                                if (messageId) {\r\n                                    if (!messagesBuffer[messageId]) {\r\n                                        messagesBuffer[messageId] = Object.create(null);\r\n                                    }\r\n\r\n                                    messagesBuffer[messageId][messageCurrentPart] = message;\r\n\r\n                                    // Last message part\r\n                                    if (Object.keys(messagesBuffer[messageId]).length == messageTotalPart) {\r\n                                        lastPart = true;\r\n                                    }\r\n                                }\r\n                                // Message does not have multipart, like the messages received at announcement channels\r\n                                else {\r\n                                    lastPart = true;\r\n                                }\r\n\r\n                                if (lastPart) {\r\n                                    if (messageId) {\r\n                                        message = '';\r\n\r\n                                        for (var i = 1; i <= messageTotalPart; i++) {\r\n                                            message += messagesBuffer[messageId][i];\r\n\r\n                                            // Delete from messages buffer                                            \r\n                                            ObjectLiterals.removeEntry(messagesBuffer[messageId],i)\r\n                                        }\r\n\r\n                                        // Delete from messages buffer\r\n                                        ObjectLiterals.removeEntry(messagesBuffer,messageId);\r\n                                    }\r\n\r\n                                    delegateMessagesCallback(ortc, channel, message);\r\n                                }\r\n                                break;\r\n                        }\r\n\r\n                        break;\r\n                    case 'h': // heartbeat\r\n                        break;\r\n                    default:\r\n                        break;\r\n                }\r\n            };\r\n        }\r\n\r\n        return ortc.sockjs;\r\n    };\r\n\r\n    /*\r\n    * Calls the onConnected callback if defined.\r\n    */\r\n    var delegateConnectedCallback = function (ortc) {\r\n        if (ortc != null && ortc.onConnected != null) {\r\n            ortc.onConnected(ortc);\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Calls the onDisconnected callback if defined.\r\n    */\r\n    var delegateDisconnectedCallback = function (ortc) {\r\n        if (ortc != null && ortc.onDisconnected != null) {\r\n            ortc.onDisconnected(ortc);\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Calls the onSubscribed callback if defined.\r\n    */\r\n    var delegateSubscribedCallback = function (ortc, channel) {\r\n        if (ortc != null && ortc.onSubscribed != null && channel != null) {\r\n            ortc.onSubscribed(ortc, channel);\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Calls the onUnsubscribed callback if defined.\r\n    */\r\n    var delegateUnsubscribedCallback = function (ortc, channel) {\r\n        if (ortc != null && ortc.onUnsubscribed != null && channel != null) {\r\n            ortc.onUnsubscribed(ortc, channel);\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Calls the onMessages callbacks if defined.\r\n    */\r\n    var delegateMessagesCallback = function (ortc, channel, message) {\r\n        if (ortc != null && subscribedChannels[channel] && subscribedChannels[channel].isSubscribed && subscribedChannels[channel].onMessageCallback != null) {\r\n            subscribedChannels[channel].onMessageCallback(ortc, channel, message);\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Calls the onException callback if defined.\r\n    */\r\n    var delegateExceptionCallback = function (ortc, event) {\r\n        if (ortc != null && ortc.onException != null) {\r\n            ortc.onException(ortc, event);\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Calls the onReconnecting callback if defined.\r\n    */\r\n    var delegateReconnectingCallback = function (ortc) {\r\n        if (ortc != null && ortc.onReconnecting != null) {\r\n            ortc.onReconnecting(ortc);\r\n        }\r\n    };\r\n\r\n    /*\r\n    * Calls the onReconnected callback if defined.\r\n    */\r\n    var delegateReconnectedCallback = function (ortc) {\r\n        if (ortc != null && ortc.onReconnected != null) {\r\n            ortc.onReconnected(ortc);\r\n        }\r\n    };\r\n};","var querystring = require('querystring');\r\n\r\nthis.post = function (postData) {\r\n    var postContent = !postData.parameters ? \"\" : (typeof (postData.parameters) == 'string') ? postData.parameters : querystring.stringify(postData.parameters);\r\n\r\n    var headers = {\r\n        'host': postData.url,\r\n        'port': postData.port,\r\n        'path': postData.path,\r\n        'method': 'POST',\r\n        'content-length': postContent.length,\r\n        'content-type': 'application/x-www-forum-urlencoded'\r\n    };\r\n\r\n    var httpClient = postData.port == 443 ? require('https') : require('http');\r\n\r\n    var request = httpClient.request(headers, function (response) {\r\n        var statusCode = response.statusCode;\r\n        var data = '';\r\n\r\n        response.addListener('data', function (chunk) {\r\n            data += chunk;\r\n        });\r\n\r\n        response.addListener('end', function () {\r\n            if (statusCode >= 400 && statusCode <= 599) {\r\n                postData.callback({\r\n                    code: statusCode,\r\n                    content: new Buffer(data, 'binary').toString()\r\n                }, null);\r\n            } else {\r\n                postData.callback(null, {\r\n                    code: statusCode,\r\n                    content: new Buffer(data, 'binary').toString()\r\n                });\r\n            }\r\n        });\r\n    });\r\n\r\n    request.on('error', function (error) {\r\n        postData.callback({\r\n            code: null,\r\n            content: error.toString()\r\n        }, null);\r\n    });\r\n\r\n    request.write(postContent);\r\n    request.end();\r\n};\r\n\r\nthis.get = function (getData) {\r\n    var getParameters = !getData.parameters ? \"\" : (typeof (getData.parameters) == 'string') ? getData.parameters : querystring.stringify(getData.parameters);\r\n    var requestPath = getParameters ? getData.path + '?' + getParameters : getData.path;\r\n\r\n    var headers = {\r\n        'host': getData.url,\r\n        'port': getData.port,\r\n        'path': requestPath,\r\n        \"user-agent\" : \"ortc-server-side-api\"\r\n    };\r\n\r\n    var httpClient = getData.port == 443 ? require('https') : require('http');\r\n\r\n    var request = httpClient.get(headers, function (response) {\r\n        var statusCode = response.statusCode;\r\n        var data = '';\r\n\r\n        response.addListener('data', function (chunk) {\r\n            data += chunk;\r\n        });\r\n\r\n        response.addListener('end', function () {\r\n            if (statusCode >= 400 && statusCode <= 599) {\r\n                getData.callback({\r\n                    code: statusCode,\r\n                    content: new Buffer(data, 'binary').toString()\r\n                }, null);\r\n            } else {\r\n                getData.callback(null, {\r\n                    code: statusCode,\r\n                    content: new Buffer(data, 'binary').toString()\r\n                });\r\n            }\r\n        });\r\n    });\r\n\r\n    request.on('error', function (error) {\r\n        getData.callback({\r\n            code: null,\r\n            content: error.toString()\r\n        }, null);\r\n    });\r\n\r\n    request.end();\r\n};","/**\r\n * @fileoverview This file contains some strings generic functions\r\n */\r\n\r\nvar util = require('util');\r\nvar math = require('./math');\r\n\r\n /**\r\n * Removes the white spaces after and before the text in a string\r\n * @param {string} String to trim\r\n */\r\nthis.trim = function (strg) {\r\n    var str = strg.replace(/^\\s\\s*/, ''),\r\n\t\tws = /\\s/,\r\n\t\ti = str.length;\r\n    while (ws.test(str.charAt(--i)));\r\n    return str.slice(0, i + 1);\r\n};\r\n\r\n /**\r\n * Generates a GUID\r\n */\r\nthis.generateGuid = function () {\r\n        var S4 = function () {\r\n            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);\r\n        };\r\n        return (S4() + S4() + \"-\" + S4() + \"-\" + S4() + \"-\" + S4() + \"-\" + S4() + S4() + S4());\r\n};\r\n\r\nvar random_string_chars = 'abcdefghijklmnopqrstuvwxyz0123456789_';\r\n /**\r\n * Generates a random alpha numeric string with the specified length\r\n * @param {int} String length\r\n */\r\nthis.random_string = function(length, max) {\r\n    max = max || random_string_chars.length;\r\n    var i, ret = [];\r\n    for(i=0; i < length; i++) {\r\n        ret.push( random_string_chars.substr(Math.floor(Math.random() * max),1) );\r\n    }\r\n    return ret.join('');\r\n};\r\n\r\n /**\r\n * Generates a random numeric string with the specified max number\r\n * @param {int} String max number\r\n */\r\nthis.random_number_string = function(max) {\r\n    var t = (''+(max - 1)).length;\r\n    var p = Array(t+1).join('0');\r\n    return (p + math.random_number(max)).slice(-t);\r\n};","/**\r\n* @fileoverview This file contains some object literals generic functions\r\n* @author ORTC team members (ortc@ibt.pt) \r\n*/\r\n\r\n/**\r\n * Remove the entry from an object\r\n * @param {object} obj - The object.\r\n * @param {string} key - The key to remove.\r\n */\r\nthis.removeEntry = function (obj, key) {\r\n    var value = obj[key];\r\n    value = null;\r\n    return delete obj[key];\r\n};","/**\r\n * @fileoverview This file contains calls to the ortc rest webservices\r\n */\r\n\r\nvar querystring = require('querystring'); \r\nvar urlApi = require('url');\r\n\r\nthis.channelPermissions = {\r\n\t\tRead : 'r',\r\n\t\tWrite : 'w',\r\n        Presence : 'p'\r\n};\t \r\n\t\r\n /**\r\n * Saves authentication for the specified token with the specified authentication key\r\n * @param {int} Max value\r\n */\r\nthis.saveAuthentication = function (connectionUrl, authenticationToken, authenticationTokenIsPrivate, applicationKey, timeToLive, privateKey, permissions, callback) {\r\n    var url = urlApi.parse(connectionUrl);\r\n    \r\n    var saveAuthenticationData = {\r\n        AT: authenticationToken,\r\n        PVT: authenticationTokenIsPrivate,\r\n        AK: applicationKey,\r\n        TTL: timeToLive,\r\n        PK: privateKey,\r\n        TP: Object.size(permissions)\r\n    }\r\n\r\n    for (var permission in permissions) {\r\n        saveAuthenticationData[permission] = permissions[permission];\r\n    }\r\n\r\n    var saveAuthenticationRequest = {\r\n       url : url.hostname,\r\n        port : url.port,\r\n        path : '/authenticate',\r\n        parameters : saveAuthenticationData,\r\n        callback : function(error,result){\r\n            if(error){\r\n                callback(error.content,false);\r\n            }else{\r\n                callback(null,true);\r\n            }\r\n        }\r\n    }\r\n\r\n    post(saveAuthenticationRequest);\r\n};\r\n\r\nthis.enablePresence = function(parameters,callback){\r\n    var url = urlApi.parse(parameters.url);\r\n\r\n    var enableParameters = { privatekey : parameters.privateKey };\r\n    if(parameters.metadata){\r\n        enableParameters[\"metadata\"] = parameters.metadata;    \r\n    }     \r\n\r\n    var enablePresenceRequest = {\r\n       url : url.hostname,\r\n        port : url.port,\r\n        path : '/presence/enable/' + parameters.appKey + '/' + parameters.channel,\r\n        parameters : enableParameters,\r\n        callback : function(error,result){\r\n            if(error){\r\n                callback(error.content,null);\r\n            }else{\r\n                if(result){\r\n                    callback(null,result.content);\r\n                }else{\r\n                    callback(null,null);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    post(enablePresenceRequest);\r\n};\r\n\r\nthis.disablePresence = function(parameters,callback){\r\n    var url = urlApi.parse(parameters.url);\r\n    \r\n    var disablePresenceRequest = {\r\n       url : url.hostname,\r\n        port : url.port,\r\n        path : '/presence/disable/' + parameters.appKey + '/' + parameters.channel,\r\n        parameters : { privatekey : parameters.privateKey},\r\n        callback : function(error,result){\r\n            if(error){\r\n                callback(error.content,null);\r\n            }else{\r\n                if(result){\r\n                    callback(null,result.content);\r\n                }else{\r\n                    callback(null,null);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    post(disablePresenceRequest);\r\n};\r\n\r\nthis.getPresence = function(parameters,callback){\r\n    var url = urlApi.parse(parameters.url);\r\n\r\n    var enablePresenceRequest = {\r\n        url : url.hostname,\r\n        port : url.port,\r\n        path : '/presence/' + parameters.appKey + '/' + parameters.authToken + '/' + parameters.channel,\r\n        callback : function(error,result){\r\n            if(error){\r\n                callback(error.content,null);\r\n            }else{\r\n                var data = null;\r\n                if(result){\r\n                    try{\r\n                        data = JSON.parse(result.content);\r\n                    }catch(e){}                    \r\n                }\r\n                callback(null,data);\r\n            }\r\n        }\r\n    }\r\n\r\n    get(enablePresenceRequest);\r\n};\r\n\r\n\r\nvar post = function (postData) {\r\n    var postContent = !postData.parameters ? \"\" : (typeof (postData.parameters) == 'string') ? postData.parameters : querystring.stringify(postData.parameters);\r\n\r\n    var postOptions = {\r\n        'host': postData.url,\r\n        'port': postData.port,\r\n        'path': postData.path,\r\n        'method': 'POST',\r\n        'headers' : {\r\n            'content-length': postContent.length,\r\n            'content-type': 'application/x-www-form-urlencoded'\r\n        }\r\n    };\r\n\r\n    for(var headerIndex in postData.headers){\r\n        postOptions.headers[headerIndex] = postData.headers[headerIndex];\r\n    }\r\n\r\n    var httpClient = postData.port == 443 || postData.secure ? require('https') : require('http');\r\n\r\n    var request = httpClient.request(postOptions, function (response) {\r\n        var statusCode = response.statusCode;\r\n        var data = '';\r\n\r\n        response.addListener('data', function (chunk) {\r\n            data += chunk;\r\n        });\r\n\r\n        response.addListener('end', function () {\r\n            if (statusCode >= 400 && statusCode <= 599) {\r\n                postData.callback({\r\n                    code: statusCode,\r\n                    content: new Buffer(data, 'binary').toString()\r\n                }, null);\r\n            } else {\r\n                postData.callback(null, {\r\n                    code: statusCode,\r\n                    content: new Buffer(data, 'binary').toString()\r\n                });\r\n            }\r\n        });\r\n    });\r\n\r\n    request.on('error', function (error) {\r\n        postData.callback({\r\n            code: null,\r\n            content: error.toString()\r\n        }, null);\r\n    });\r\n\r\n    request.write(postContent);\r\n    request.end();\r\n};\r\n\r\nvar get = function (getData) {\r\n    var getParameters = !getData.parameters ? \"\" : (typeof (getData.parameters) == 'string') ? getData.parameters : querystring.stringify(getData.parameters);\r\n    var requestPath = getParameters ? getData.path + '?' + getParameters : getData.path;\r\n\r\n    var getOptions = {\r\n        'host': getData.url,\r\n        'port': getData.port,\r\n        'path': requestPath,\r\n        'method' : 'GET'\r\n    };\r\n\r\n    for(var headerIndex in getData.headers){\r\n        getOptions.headers = getOptions.headers ? getOptions.headers : {};\r\n\r\n        getOptions.headers[headerIndex] = getData.headers[headerIndex];\r\n    }\r\n\r\n    var httpClient = getData.port == 443 || getData.secure ? require('https') : require('http');\r\n\r\n    var request = httpClient.get(getOptions, function (response) {\r\n        var statusCode = response.statusCode;\r\n        var data = '';\r\n\r\n        response.addListener('data', function (chunk) {\r\n            data += chunk;\r\n        });\r\n\r\n        response.addListener('end', function () {\r\n            if (statusCode >= 400 && statusCode <= 599) {\r\n                getData.callback({\r\n                    code: statusCode,\r\n                    content: new Buffer(data, 'binary').toString()\r\n                }, null);\r\n            } else {\r\n                getData.callback(null, {\r\n                    code: statusCode,\r\n                    content: new Buffer(data, 'binary').toString()\r\n                });\r\n            }\r\n        });\r\n    });\r\n\r\n    request.on('error', function (error) {\r\n        getData.callback({\r\n            code: null,\r\n            content: error.toString()\r\n        }, null);\r\n    });\r\n\r\n    request.end();\r\n};\r\n\r\nObject.size = function(obj) {\r\n    var size = 0, key;\r\n    for (key in obj) {\r\n        if (obj.hasOwnProperty(key)) size++;\r\n    }\r\n    return size;\r\n};\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar punycode = require('punycode');\n\nexports.parse = urlParse;\nexports.resolve = urlResolve;\nexports.resolveObject = urlResolveObject;\nexports.format = urlFormat;\n\nexports.Url = Url;\n\nfunction Url() {\n  this.protocol = null;\n  this.slashes = null;\n  this.auth = null;\n  this.host = null;\n  this.port = null;\n  this.hostname = null;\n  this.hash = null;\n  this.search = null;\n  this.query = null;\n  this.pathname = null;\n  this.path = null;\n  this.href = null;\n}\n\n// Reference: RFC 3986, RFC 1808, RFC 2396\n\n// define these here so at least they only have to be\n// compiled once on the first module load.\nvar protocolPattern = /^([a-z0-9.+-]+:)/i,\n    portPattern = /:[0-9]*$/,\n\n    // RFC 2396: characters reserved for delimiting URLs.\n    // We actually just auto-escape these.\n    delims = ['<', '>', '\"', '`', ' ', '\\r', '\\n', '\\t'],\n\n    // RFC 2396: characters not allowed for various reasons.\n    unwise = ['{', '}', '|', '\\\\', '^', '`'].concat(delims),\n\n    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.\n    autoEscape = ['\\''].concat(unwise),\n    // Characters that are never ever allowed in a hostname.\n    // Note that any invalid chars are also handled, but these\n    // are the ones that are *expected* to be seen, so we fast-path\n    // them.\n    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),\n    hostEndingChars = ['/', '?', '#'],\n    hostnameMaxLen = 255,\n    hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,\n    hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,\n    // protocols that can allow \"unsafe\" and \"unwise\" chars.\n    unsafeProtocol = {\n      'javascript': true,\n      'javascript:': true\n    },\n    // protocols that never have a hostname.\n    hostlessProtocol = {\n      'javascript': true,\n      'javascript:': true\n    },\n    // protocols that always contain a // bit.\n    slashedProtocol = {\n      'http': true,\n      'https': true,\n      'ftp': true,\n      'gopher': true,\n      'file': true,\n      'http:': true,\n      'https:': true,\n      'ftp:': true,\n      'gopher:': true,\n      'file:': true\n    },\n    querystring = require('querystring');\n\nfunction urlParse(url, parseQueryString, slashesDenoteHost) {\n  if (url && isObject(url) && url instanceof Url) return url;\n\n  var u = new Url;\n  u.parse(url, parseQueryString, slashesDenoteHost);\n  return u;\n}\n\nUrl.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {\n  if (!isString(url)) {\n    throw new TypeError(\"Parameter 'url' must be a string, not \" + typeof url);\n  }\n\n  var rest = url;\n\n  // trim before proceeding.\n  // This is to support parse stuff like \"  http://foo.com  \\n\"\n  rest = rest.trim();\n\n  var proto = protocolPattern.exec(rest);\n  if (proto) {\n    proto = proto[0];\n    var lowerProto = proto.toLowerCase();\n    this.protocol = lowerProto;\n    rest = rest.substr(proto.length);\n  }\n\n  // figure out if it's got a host\n  // user@server is *always* interpreted as a hostname, and url\n  // resolution will treat //foo/bar as host=foo,path=bar because that's\n  // how the browser resolves relative URLs.\n  if (slashesDenoteHost || proto || rest.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)) {\n    var slashes = rest.substr(0, 2) === '//';\n    if (slashes && !(proto && hostlessProtocol[proto])) {\n      rest = rest.substr(2);\n      this.slashes = true;\n    }\n  }\n\n  if (!hostlessProtocol[proto] &&\n      (slashes || (proto && !slashedProtocol[proto]))) {\n\n    // there's a hostname.\n    // the first instance of /, ?, ;, or # ends the host.\n    //\n    // If there is an @ in the hostname, then non-host chars *are* allowed\n    // to the left of the last @ sign, unless some host-ending character\n    // comes *before* the @-sign.\n    // URLs are obnoxious.\n    //\n    // ex:\n    // http://a@b@c/ => user:a@b host:c\n    // http://a@b?@c => user:a host:c path:/?@c\n\n    // v0.12 TODO(isaacs): This is not quite how Chrome does things.\n    // Review our test case against browsers more comprehensively.\n\n    // find the first instance of any hostEndingChars\n    var hostEnd = -1;\n    for (var i = 0; i < hostEndingChars.length; i++) {\n      var hec = rest.indexOf(hostEndingChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n        hostEnd = hec;\n    }\n\n    // at this point, either we have an explicit point where the\n    // auth portion cannot go past, or the last @ char is the decider.\n    var auth, atSign;\n    if (hostEnd === -1) {\n      // atSign can be anywhere.\n      atSign = rest.lastIndexOf('@');\n    } else {\n      // atSign must be in auth portion.\n      // http://a@b/c@d => host:b auth:a path:/c@d\n      atSign = rest.lastIndexOf('@', hostEnd);\n    }\n\n    // Now we have a portion which is definitely the auth.\n    // Pull that off.\n    if (atSign !== -1) {\n      auth = rest.slice(0, atSign);\n      rest = rest.slice(atSign + 1);\n      this.auth = decodeURIComponent(auth);\n    }\n\n    // the host is the remaining to the left of the first non-host char\n    hostEnd = -1;\n    for (var i = 0; i < nonHostChars.length; i++) {\n      var hec = rest.indexOf(nonHostChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n        hostEnd = hec;\n    }\n    // if we still have not hit it, then the entire thing is a host.\n    if (hostEnd === -1)\n      hostEnd = rest.length;\n\n    this.host = rest.slice(0, hostEnd);\n    rest = rest.slice(hostEnd);\n\n    // pull out port.\n    this.parseHost();\n\n    // we've indicated that there is a hostname,\n    // so even if it's empty, it has to be present.\n    this.hostname = this.hostname || '';\n\n    // if hostname begins with [ and ends with ]\n    // assume that it's an IPv6 address.\n    var ipv6Hostname = this.hostname[0] === '[' &&\n        this.hostname[this.hostname.length - 1] === ']';\n\n    // validate a little.\n    if (!ipv6Hostname) {\n      var hostparts = this.hostname.split(/\\./);\n      for (var i = 0, l = hostparts.length; i < l; i++) {\n        var part = hostparts[i];\n        if (!part) continue;\n        if (!part.match(hostnamePartPattern)) {\n          var newpart = '';\n          for (var j = 0, k = part.length; j < k; j++) {\n            if (part.charCodeAt(j) > 127) {\n              // we replace non-ASCII char with a temporary placeholder\n              // we need this to make sure size of hostname is not\n              // broken by replacing non-ASCII by nothing\n              newpart += 'x';\n            } else {\n              newpart += part[j];\n            }\n          }\n          // we test again with ASCII char only\n          if (!newpart.match(hostnamePartPattern)) {\n            var validParts = hostparts.slice(0, i);\n            var notHost = hostparts.slice(i + 1);\n            var bit = part.match(hostnamePartStart);\n            if (bit) {\n              validParts.push(bit[1]);\n              notHost.unshift(bit[2]);\n            }\n            if (notHost.length) {\n              rest = '/' + notHost.join('.') + rest;\n            }\n            this.hostname = validParts.join('.');\n            break;\n          }\n        }\n      }\n    }\n\n    if (this.hostname.length > hostnameMaxLen) {\n      this.hostname = '';\n    } else {\n      // hostnames are always lower case.\n      this.hostname = this.hostname.toLowerCase();\n    }\n\n    if (!ipv6Hostname) {\n      // IDNA Support: Returns a puny coded representation of \"domain\".\n      // It only converts the part of the domain name that\n      // has non ASCII characters. I.e. it dosent matter if\n      // you call it with a domain that already is in ASCII.\n      var domainArray = this.hostname.split('.');\n      var newOut = [];\n      for (var i = 0; i < domainArray.length; ++i) {\n        var s = domainArray[i];\n        newOut.push(s.match(/[^A-Za-z0-9_-]/) ?\n            'xn--' + punycode.encode(s) : s);\n      }\n      this.hostname = newOut.join('.');\n    }\n\n    var p = this.port ? ':' + this.port : '';\n    var h = this.hostname || '';\n    this.host = h + p;\n    this.href += this.host;\n\n    // strip [ and ] from the hostname\n    // the host field still retains them, though\n    if (ipv6Hostname) {\n      this.hostname = this.hostname.substr(1, this.hostname.length - 2);\n      if (rest[0] !== '/') {\n        rest = '/' + rest;\n      }\n    }\n  }\n\n  // now rest is set to the post-host stuff.\n  // chop off any delim chars.\n  if (!unsafeProtocol[lowerProto]) {\n\n    // First, make 100% sure that any \"autoEscape\" chars get\n    // escaped, even if encodeURIComponent doesn't think they\n    // need to be.\n    for (var i = 0, l = autoEscape.length; i < l; i++) {\n      var ae = autoEscape[i];\n      var esc = encodeURIComponent(ae);\n      if (esc === ae) {\n        esc = escape(ae);\n      }\n      rest = rest.split(ae).join(esc);\n    }\n  }\n\n\n  // chop off from the tail first.\n  var hash = rest.indexOf('#');\n  if (hash !== -1) {\n    // got a fragment string.\n    this.hash = rest.substr(hash);\n    rest = rest.slice(0, hash);\n  }\n  var qm = rest.indexOf('?');\n  if (qm !== -1) {\n    this.search = rest.substr(qm);\n    this.query = rest.substr(qm + 1);\n    if (parseQueryString) {\n      this.query = querystring.parse(this.query);\n    }\n    rest = rest.slice(0, qm);\n  } else if (parseQueryString) {\n    // no query string, but parseQueryString still requested\n    this.search = '';\n    this.query = {};\n  }\n  if (rest) this.pathname = rest;\n  if (slashedProtocol[lowerProto] &&\n      this.hostname && !this.pathname) {\n    this.pathname = '/';\n  }\n\n  //to support http.request\n  if (this.pathname || this.search) {\n    var p = this.pathname || '';\n    var s = this.search || '';\n    this.path = p + s;\n  }\n\n  // finally, reconstruct the href based on what has been validated.\n  this.href = this.format();\n  return this;\n};\n\n// format a parsed object into a url string\nfunction urlFormat(obj) {\n  // ensure it's an object, and not a string url.\n  // If it's an obj, this is a no-op.\n  // this way, you can call url_format() on strings\n  // to clean up potentially wonky urls.\n  if (isString(obj)) obj = urlParse(obj);\n  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);\n  return obj.format();\n}\n\nUrl.prototype.format = function() {\n  var auth = this.auth || '';\n  if (auth) {\n    auth = encodeURIComponent(auth);\n    auth = auth.replace(/%3A/i, ':');\n    auth += '@';\n  }\n\n  var protocol = this.protocol || '',\n      pathname = this.pathname || '',\n      hash = this.hash || '',\n      host = false,\n      query = '';\n\n  if (this.host) {\n    host = auth + this.host;\n  } else if (this.hostname) {\n    host = auth + (this.hostname.indexOf(':') === -1 ?\n        this.hostname :\n        '[' + this.hostname + ']');\n    if (this.port) {\n      host += ':' + this.port;\n    }\n  }\n\n  if (this.query &&\n      isObject(this.query) &&\n      Object.keys(this.query).length) {\n    query = querystring.stringify(this.query);\n  }\n\n  var search = this.search || (query && ('?' + query)) || '';\n\n  if (protocol && protocol.substr(-1) !== ':') protocol += ':';\n\n  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.\n  // unless they had them to begin with.\n  if (this.slashes ||\n      (!protocol || slashedProtocol[protocol]) && host !== false) {\n    host = '//' + (host || '');\n    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;\n  } else if (!host) {\n    host = '';\n  }\n\n  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;\n  if (search && search.charAt(0) !== '?') search = '?' + search;\n\n  pathname = pathname.replace(/[?#]/g, function(match) {\n    return encodeURIComponent(match);\n  });\n  search = search.replace('#', '%23');\n\n  return protocol + host + pathname + search + hash;\n};\n\nfunction urlResolve(source, relative) {\n  return urlParse(source, false, true).resolve(relative);\n}\n\nUrl.prototype.resolve = function(relative) {\n  return this.resolveObject(urlParse(relative, false, true)).format();\n};\n\nfunction urlResolveObject(source, relative) {\n  if (!source) return relative;\n  return urlParse(source, false, true).resolveObject(relative);\n}\n\nUrl.prototype.resolveObject = function(relative) {\n  if (isString(relative)) {\n    var rel = new Url();\n    rel.parse(relative, false, true);\n    relative = rel;\n  }\n\n  var result = new Url();\n  Object.keys(this).forEach(function(k) {\n    result[k] = this[k];\n  }, this);\n\n  // hash is always overridden, no matter what.\n  // even href=\"\" will remove it.\n  result.hash = relative.hash;\n\n  // if the relative url is empty, then there's nothing left to do here.\n  if (relative.href === '') {\n    result.href = result.format();\n    return result;\n  }\n\n  // hrefs like //foo/bar always cut to the protocol.\n  if (relative.slashes && !relative.protocol) {\n    // take everything except the protocol from relative\n    Object.keys(relative).forEach(function(k) {\n      if (k !== 'protocol')\n        result[k] = relative[k];\n    });\n\n    //urlParse appends trailing / to urls like http://www.example.com\n    if (slashedProtocol[result.protocol] &&\n        result.hostname && !result.pathname) {\n      result.path = result.pathname = '/';\n    }\n\n    result.href = result.format();\n    return result;\n  }\n\n  if (relative.protocol && relative.protocol !== result.protocol) {\n    // if it's a known url protocol, then changing\n    // the protocol does weird things\n    // first, if it's not file:, then we MUST have a host,\n    // and if there was a path\n    // to begin with, then we MUST have a path.\n    // if it is file:, then the host is dropped,\n    // because that's known to be hostless.\n    // anything else is assumed to be absolute.\n    if (!slashedProtocol[relative.protocol]) {\n      Object.keys(relative).forEach(function(k) {\n        result[k] = relative[k];\n      });\n      result.href = result.format();\n      return result;\n    }\n\n    result.protocol = relative.protocol;\n    if (!relative.host && !hostlessProtocol[relative.protocol]) {\n      var relPath = (relative.pathname || '').split('/');\n      while (relPath.length && !(relative.host = relPath.shift()));\n      if (!relative.host) relative.host = '';\n      if (!relative.hostname) relative.hostname = '';\n      if (relPath[0] !== '') relPath.unshift('');\n      if (relPath.length < 2) relPath.unshift('');\n      result.pathname = relPath.join('/');\n    } else {\n      result.pathname = relative.pathname;\n    }\n    result.search = relative.search;\n    result.query = relative.query;\n    result.host = relative.host || '';\n    result.auth = relative.auth;\n    result.hostname = relative.hostname || relative.host;\n    result.port = relative.port;\n    // to support http.request\n    if (result.pathname || result.search) {\n      var p = result.pathname || '';\n      var s = result.search || '';\n      result.path = p + s;\n    }\n    result.slashes = result.slashes || relative.slashes;\n    result.href = result.format();\n    return result;\n  }\n\n  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),\n      isRelAbs = (\n          relative.host ||\n          relative.pathname && relative.pathname.charAt(0) === '/'\n      ),\n      mustEndAbs = (isRelAbs || isSourceAbs ||\n                    (result.host && relative.pathname)),\n      removeAllDots = mustEndAbs,\n      srcPath = result.pathname && result.pathname.split('/') || [],\n      relPath = relative.pathname && relative.pathname.split('/') || [],\n      psychotic = result.protocol && !slashedProtocol[result.protocol];\n\n  // if the url is a non-slashed url, then relative\n  // links like ../.. should be able\n  // to crawl up to the hostname, as well.  This is strange.\n  // result.protocol has already been set by now.\n  // Later on, put the first path part into the host field.\n  if (psychotic) {\n    result.hostname = '';\n    result.port = null;\n    if (result.host) {\n      if (srcPath[0] === '') srcPath[0] = result.host;\n      else srcPath.unshift(result.host);\n    }\n    result.host = '';\n    if (relative.protocol) {\n      relative.hostname = null;\n      relative.port = null;\n      if (relative.host) {\n        if (relPath[0] === '') relPath[0] = relative.host;\n        else relPath.unshift(relative.host);\n      }\n      relative.host = null;\n    }\n    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');\n  }\n\n  if (isRelAbs) {\n    // it's absolute.\n    result.host = (relative.host || relative.host === '') ?\n                  relative.host : result.host;\n    result.hostname = (relative.hostname || relative.hostname === '') ?\n                      relative.hostname : result.hostname;\n    result.search = relative.search;\n    result.query = relative.query;\n    srcPath = relPath;\n    // fall through to the dot-handling below.\n  } else if (relPath.length) {\n    // it's relative\n    // throw away the existing file, and take the new path instead.\n    if (!srcPath) srcPath = [];\n    srcPath.pop();\n    srcPath = srcPath.concat(relPath);\n    result.search = relative.search;\n    result.query = relative.query;\n  } else if (!isNullOrUndefined(relative.search)) {\n    // just pull out the search.\n    // like href='?foo'.\n    // Put this after the other two cases because it simplifies the booleans\n    if (psychotic) {\n      result.hostname = result.host = srcPath.shift();\n      //occationaly the auth can get stuck only in host\n      //this especialy happens in cases like\n      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n      var authInHost = result.host && result.host.indexOf('@') > 0 ?\n                       result.host.split('@') : false;\n      if (authInHost) {\n        result.auth = authInHost.shift();\n        result.host = result.hostname = authInHost.shift();\n      }\n    }\n    result.search = relative.search;\n    result.query = relative.query;\n    //to support http.request\n    if (!isNull(result.pathname) || !isNull(result.search)) {\n      result.path = (result.pathname ? result.pathname : '') +\n                    (result.search ? result.search : '');\n    }\n    result.href = result.format();\n    return result;\n  }\n\n  if (!srcPath.length) {\n    // no path at all.  easy.\n    // we've already handled the other stuff above.\n    result.pathname = null;\n    //to support http.request\n    if (result.search) {\n      result.path = '/' + result.search;\n    } else {\n      result.path = null;\n    }\n    result.href = result.format();\n    return result;\n  }\n\n  // if a url ENDs in . or .., then it must get a trailing slash.\n  // however, if it ends in anything else non-slashy,\n  // then it must NOT get a trailing slash.\n  var last = srcPath.slice(-1)[0];\n  var hasTrailingSlash = (\n      (result.host || relative.host) && (last === '.' || last === '..') ||\n      last === '');\n\n  // strip single dots, resolve double dots to parent dir\n  // if the path tries to go above the root, `up` ends up > 0\n  var up = 0;\n  for (var i = srcPath.length; i >= 0; i--) {\n    last = srcPath[i];\n    if (last == '.') {\n      srcPath.splice(i, 1);\n    } else if (last === '..') {\n      srcPath.splice(i, 1);\n      up++;\n    } else if (up) {\n      srcPath.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (!mustEndAbs && !removeAllDots) {\n    for (; up--; up) {\n      srcPath.unshift('..');\n    }\n  }\n\n  if (mustEndAbs && srcPath[0] !== '' &&\n      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {\n    srcPath.unshift('');\n  }\n\n  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {\n    srcPath.push('');\n  }\n\n  var isAbsolute = srcPath[0] === '' ||\n      (srcPath[0] && srcPath[0].charAt(0) === '/');\n\n  // put the host back\n  if (psychotic) {\n    result.hostname = result.host = isAbsolute ? '' :\n                                    srcPath.length ? srcPath.shift() : '';\n    //occationaly the auth can get stuck only in host\n    //this especialy happens in cases like\n    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n    var authInHost = result.host && result.host.indexOf('@') > 0 ?\n                     result.host.split('@') : false;\n    if (authInHost) {\n      result.auth = authInHost.shift();\n      result.host = result.hostname = authInHost.shift();\n    }\n  }\n\n  mustEndAbs = mustEndAbs || (result.host && srcPath.length);\n\n  if (mustEndAbs && !isAbsolute) {\n    srcPath.unshift('');\n  }\n\n  if (!srcPath.length) {\n    result.pathname = null;\n    result.path = null;\n  } else {\n    result.pathname = srcPath.join('/');\n  }\n\n  //to support request.http\n  if (!isNull(result.pathname) || !isNull(result.search)) {\n    result.path = (result.pathname ? result.pathname : '') +\n                  (result.search ? result.search : '');\n  }\n  result.auth = relative.auth || result.auth;\n  result.slashes = result.slashes || relative.slashes;\n  result.href = result.format();\n  return result;\n};\n\nUrl.prototype.parseHost = function() {\n  var host = this.host;\n  var port = portPattern.exec(host);\n  if (port) {\n    port = port[0];\n    if (port !== ':') {\n      this.port = port.substr(1);\n    }\n    host = host.substr(0, host.length - port.length);\n  }\n  if (host) this.hostname = host;\n};\n\nfunction isString(arg) {\n  return typeof arg === \"string\";\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isNull(arg) {\n  return arg === null;\n}\nfunction isNullOrUndefined(arg) {\n  return  arg == null;\n}\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// resolves . and .. elements in a path array with directory names there\n// must be no slashes, empty elements, or device names (c:\\) in the array\n// (so also no leading and trailing slashes - it does not distinguish\n// relative and absolute paths)\nfunction normalizeArray(parts, allowAboveRoot) {\n  // if the path tries to go above the root, `up` ends up > 0\n  var up = 0;\n  for (var i = parts.length - 1; i >= 0; i--) {\n    var last = parts[i];\n    if (last === '.') {\n      parts.splice(i, 1);\n    } else if (last === '..') {\n      parts.splice(i, 1);\n      up++;\n    } else if (up) {\n      parts.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (allowAboveRoot) {\n    for (; up--; up) {\n      parts.unshift('..');\n    }\n  }\n\n  return parts;\n}\n\n// Split a filename into [root, dir, basename, ext], unix version\n// 'root' is just a slash, or nothing.\nvar splitPathRe =\n    /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/;\nvar splitPath = function(filename) {\n  return splitPathRe.exec(filename).slice(1);\n};\n\n// path.resolve([from ...], to)\n// posix version\nexports.resolve = function() {\n  var resolvedPath = '',\n      resolvedAbsolute = false;\n\n  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n    var path = (i >= 0) ? arguments[i] : process.cwd();\n\n    // Skip empty and invalid entries\n    if (typeof path !== 'string') {\n      throw new TypeError('Arguments to path.resolve must be strings');\n    } else if (!path) {\n      continue;\n    }\n\n    resolvedPath = path + '/' + resolvedPath;\n    resolvedAbsolute = path.charAt(0) === '/';\n  }\n\n  // At this point the path should be resolved to a full absolute path, but\n  // handle relative paths to be safe (might happen when process.cwd() fails)\n\n  // Normalize the path\n  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {\n    return !!p;\n  }), !resolvedAbsolute).join('/');\n\n  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';\n};\n\n// path.normalize(path)\n// posix version\nexports.normalize = function(path) {\n  var isAbsolute = exports.isAbsolute(path),\n      trailingSlash = substr(path, -1) === '/';\n\n  // Normalize the path\n  path = normalizeArray(filter(path.split('/'), function(p) {\n    return !!p;\n  }), !isAbsolute).join('/');\n\n  if (!path && !isAbsolute) {\n    path = '.';\n  }\n  if (path && trailingSlash) {\n    path += '/';\n  }\n\n  return (isAbsolute ? '/' : '') + path;\n};\n\n// posix version\nexports.isAbsolute = function(path) {\n  return path.charAt(0) === '/';\n};\n\n// posix version\nexports.join = function() {\n  var paths = Array.prototype.slice.call(arguments, 0);\n  return exports.normalize(filter(paths, function(p, index) {\n    if (typeof p !== 'string') {\n      throw new TypeError('Arguments to path.join must be strings');\n    }\n    return p;\n  }).join('/'));\n};\n\n\n// path.relative(from, to)\n// posix version\nexports.relative = function(from, to) {\n  from = exports.resolve(from).substr(1);\n  to = exports.resolve(to).substr(1);\n\n  function trim(arr) {\n    var start = 0;\n    for (; start < arr.length; start++) {\n      if (arr[start] !== '') break;\n    }\n\n    var end = arr.length - 1;\n    for (; end >= 0; end--) {\n      if (arr[end] !== '') break;\n    }\n\n    if (start > end) return [];\n    return arr.slice(start, end - start + 1);\n  }\n\n  var fromParts = trim(from.split('/'));\n  var toParts = trim(to.split('/'));\n\n  var length = Math.min(fromParts.length, toParts.length);\n  var samePartsLength = length;\n  for (var i = 0; i < length; i++) {\n    if (fromParts[i] !== toParts[i]) {\n      samePartsLength = i;\n      break;\n    }\n  }\n\n  var outputParts = [];\n  for (var i = samePartsLength; i < fromParts.length; i++) {\n    outputParts.push('..');\n  }\n\n  outputParts = outputParts.concat(toParts.slice(samePartsLength));\n\n  return outputParts.join('/');\n};\n\nexports.sep = '/';\nexports.delimiter = ':';\n\nexports.dirname = function(path) {\n  var result = splitPath(path),\n      root = result[0],\n      dir = result[1];\n\n  if (!root && !dir) {\n    // No dirname whatsoever\n    return '.';\n  }\n\n  if (dir) {\n    // It has a dirname, strip trailing slash\n    dir = dir.substr(0, dir.length - 1);\n  }\n\n  return root + dir;\n};\n\n\nexports.basename = function(path, ext) {\n  var f = splitPath(path)[2];\n  // TODO: make this comparison case-insensitive on windows?\n  if (ext && f.substr(-1 * ext.length) === ext) {\n    f = f.substr(0, f.length - ext.length);\n  }\n  return f;\n};\n\n\nexports.extname = function(path) {\n  return splitPath(path)[3];\n};\n\nfunction filter (xs, f) {\n    if (xs.filter) return xs.filter(f);\n    var res = [];\n    for (var i = 0; i < xs.length; i++) {\n        if (f(xs[i], i, xs)) res.push(xs[i]);\n    }\n    return res;\n}\n\n// String.prototype.substr - negative index don't work in IE8\nvar substr = 'ab'.substr(-1) === 'b'\n    ? function (str, start, len) { return str.substr(start, len) }\n    : function (str, start, len) {\n        if (start < 0) start = str.length + start;\n        return str.substr(start, len);\n    }\n;\n","/**\r\n * @fileoverview This file contains some math generic functions\r\n */\r\n\r\n /**\r\n * Rounds a decimal number for the specified number of decimal places\r\n * @param {float} Number to round\r\n * @param {int} Number of decimal places\r\n */\r\nthis.roundNumber = function (num, dec) {\r\n    var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);\r\n    return result;\r\n};\r\n\r\n /**\r\n * Generates a random number in the interval [0,max]\r\n * @param {int} Max value\r\n */\r\nthis.random_number = function(max) {\r\n    return Math.floor(Math.random() * max);\r\n};","'use strict';\n\nexports.decode = exports.parse = require('./decode');\nexports.encode = exports.stringify = require('./encode');\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n","\n/**\n * Module dependencies.\n */\n\nvar global = (function() { return this; })();\n\n/**\n * WebSocket constructor.\n */\n\nvar WebSocket = global.WebSocket || global.MozWebSocket;\n\n/**\n * Module exports.\n */\n\nmodule.exports = WebSocket ? ws : null;\n\n/**\n * WebSocket constructor.\n *\n * The third `opts` options object gets ignored in web browsers, since it's\n * non-standard, and throws a TypeError if passed to the constructor.\n * See: https://github.com/einaros/ws/issues/227\n *\n * @param {String} uri\n * @param {Array} protocols (optional)\n * @param {Object) opts (optional)\n * @api public\n */\n\nfunction ws(uri, protocols, opts) {\n  var instance;\n  if (protocols) {\n    instance = new WebSocket(uri, protocols);\n  } else {\n    instance = new WebSocket(uri);\n  }\n  return instance;\n}\n\nif (WebSocket) ws.prototype = WebSocket.prototype;\n","/*! http://mths.be/punycode v1.2.4 by @mathias */\n;(function(root) {\n\n\t/** Detect free variables */\n\tvar freeExports = typeof exports == 'object' && exports;\n\tvar freeModule = typeof module == 'object' && module &&\n\t\tmodule.exports == freeExports && module;\n\tvar freeGlobal = typeof global == 'object' && global;\n\tif (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n\t\troot = freeGlobal;\n\t}\n\n\t/**\n\t * The `punycode` object.\n\t * @name punycode\n\t * @type Object\n\t */\n\tvar punycode,\n\n\t/** Highest positive signed 32-bit float value */\n\tmaxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1\n\n\t/** Bootstring parameters */\n\tbase = 36,\n\ttMin = 1,\n\ttMax = 26,\n\tskew = 38,\n\tdamp = 700,\n\tinitialBias = 72,\n\tinitialN = 128, // 0x80\n\tdelimiter = '-', // '\\x2D'\n\n\t/** Regular expressions */\n\tregexPunycode = /^xn--/,\n\tregexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars\n\tregexSeparators = /\\x2E|\\u3002|\\uFF0E|\\uFF61/g, // RFC 3490 separators\n\n\t/** Error messages */\n\terrors = {\n\t\t'overflow': 'Overflow: input needs wider integers to process',\n\t\t'not-basic': 'Illegal input >= 0x80 (not a basic code point)',\n\t\t'invalid-input': 'Invalid input'\n\t},\n\n\t/** Convenience shortcuts */\n\tbaseMinusTMin = base - tMin,\n\tfloor = Math.floor,\n\tstringFromCharCode = String.fromCharCode,\n\n\t/** Temporary variable */\n\tkey;\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/**\n\t * A generic error utility function.\n\t * @private\n\t * @param {String} type The error type.\n\t * @returns {Error} Throws a `RangeError` with the applicable error message.\n\t */\n\tfunction error(type) {\n\t\tthrow RangeError(errors[type]);\n\t}\n\n\t/**\n\t * A generic `Array#map` utility function.\n\t * @private\n\t * @param {Array} array The array to iterate over.\n\t * @param {Function} callback The function that gets called for every array\n\t * item.\n\t * @returns {Array} A new array of values returned by the callback function.\n\t */\n\tfunction map(array, fn) {\n\t\tvar length = array.length;\n\t\twhile (length--) {\n\t\t\tarray[length] = fn(array[length]);\n\t\t}\n\t\treturn array;\n\t}\n\n\t/**\n\t * A simple `Array#map`-like wrapper to work with domain name strings.\n\t * @private\n\t * @param {String} domain The domain name.\n\t * @param {Function} callback The function that gets called for every\n\t * character.\n\t * @returns {Array} A new string of characters returned by the callback\n\t * function.\n\t */\n\tfunction mapDomain(string, fn) {\n\t\treturn map(string.split(regexSeparators), fn).join('.');\n\t}\n\n\t/**\n\t * Creates an array containing the numeric code points of each Unicode\n\t * character in the string. While JavaScript uses UCS-2 internally,\n\t * this function will convert a pair of surrogate halves (each of which\n\t * UCS-2 exposes as separate characters) into a single code point,\n\t * matching UTF-16.\n\t * @see `punycode.ucs2.encode`\n\t * @see <http://mathiasbynens.be/notes/javascript-encoding>\n\t * @memberOf punycode.ucs2\n\t * @name decode\n\t * @param {String} string The Unicode input string (UCS-2).\n\t * @returns {Array} The new array of code points.\n\t */\n\tfunction ucs2decode(string) {\n\t\tvar output = [],\n\t\t    counter = 0,\n\t\t    length = string.length,\n\t\t    value,\n\t\t    extra;\n\t\twhile (counter < length) {\n\t\t\tvalue = string.charCodeAt(counter++);\n\t\t\tif (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n\t\t\t\t// high surrogate, and there is a next character\n\t\t\t\textra = string.charCodeAt(counter++);\n\t\t\t\tif ((extra & 0xFC00) == 0xDC00) { // low surrogate\n\t\t\t\t\toutput.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n\t\t\t\t} else {\n\t\t\t\t\t// unmatched surrogate; only append this code unit, in case the next\n\t\t\t\t\t// code unit is the high surrogate of a surrogate pair\n\t\t\t\t\toutput.push(value);\n\t\t\t\t\tcounter--;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toutput.push(value);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Creates a string based on an array of numeric code points.\n\t * @see `punycode.ucs2.decode`\n\t * @memberOf punycode.ucs2\n\t * @name encode\n\t * @param {Array} codePoints The array of numeric code points.\n\t * @returns {String} The new Unicode string (UCS-2).\n\t */\n\tfunction ucs2encode(array) {\n\t\treturn map(array, function(value) {\n\t\t\tvar output = '';\n\t\t\tif (value > 0xFFFF) {\n\t\t\t\tvalue -= 0x10000;\n\t\t\t\toutput += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);\n\t\t\t\tvalue = 0xDC00 | value & 0x3FF;\n\t\t\t}\n\t\t\toutput += stringFromCharCode(value);\n\t\t\treturn output;\n\t\t}).join('');\n\t}\n\n\t/**\n\t * Converts a basic code point into a digit/integer.\n\t * @see `digitToBasic()`\n\t * @private\n\t * @param {Number} codePoint The basic numeric code point value.\n\t * @returns {Number} The numeric value of a basic code point (for use in\n\t * representing integers) in the range `0` to `base - 1`, or `base` if\n\t * the code point does not represent a value.\n\t */\n\tfunction basicToDigit(codePoint) {\n\t\tif (codePoint - 48 < 10) {\n\t\t\treturn codePoint - 22;\n\t\t}\n\t\tif (codePoint - 65 < 26) {\n\t\t\treturn codePoint - 65;\n\t\t}\n\t\tif (codePoint - 97 < 26) {\n\t\t\treturn codePoint - 97;\n\t\t}\n\t\treturn base;\n\t}\n\n\t/**\n\t * Converts a digit/integer into a basic code point.\n\t * @see `basicToDigit()`\n\t * @private\n\t * @param {Number} digit The numeric value of a basic code point.\n\t * @returns {Number} The basic code point whose value (when used for\n\t * representing integers) is `digit`, which needs to be in the range\n\t * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is\n\t * used; else, the lowercase form is used. The behavior is undefined\n\t * if `flag` is non-zero and `digit` has no uppercase form.\n\t */\n\tfunction digitToBasic(digit, flag) {\n\t\t//  0..25 map to ASCII a..z or A..Z\n\t\t// 26..35 map to ASCII 0..9\n\t\treturn digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);\n\t}\n\n\t/**\n\t * Bias adaptation function as per section 3.4 of RFC 3492.\n\t * http://tools.ietf.org/html/rfc3492#section-3.4\n\t * @private\n\t */\n\tfunction adapt(delta, numPoints, firstTime) {\n\t\tvar k = 0;\n\t\tdelta = firstTime ? floor(delta / damp) : delta >> 1;\n\t\tdelta += floor(delta / numPoints);\n\t\tfor (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {\n\t\t\tdelta = floor(delta / baseMinusTMin);\n\t\t}\n\t\treturn floor(k + (baseMinusTMin + 1) * delta / (delta + skew));\n\t}\n\n\t/**\n\t * Converts a Punycode string of ASCII-only symbols to a string of Unicode\n\t * symbols.\n\t * @memberOf punycode\n\t * @param {String} input The Punycode string of ASCII-only symbols.\n\t * @returns {String} The resulting string of Unicode symbols.\n\t */\n\tfunction decode(input) {\n\t\t// Don't use UCS-2\n\t\tvar output = [],\n\t\t    inputLength = input.length,\n\t\t    out,\n\t\t    i = 0,\n\t\t    n = initialN,\n\t\t    bias = initialBias,\n\t\t    basic,\n\t\t    j,\n\t\t    index,\n\t\t    oldi,\n\t\t    w,\n\t\t    k,\n\t\t    digit,\n\t\t    t,\n\t\t    /** Cached calculation results */\n\t\t    baseMinusT;\n\n\t\t// Handle the basic code points: let `basic` be the number of input code\n\t\t// points before the last delimiter, or `0` if there is none, then copy\n\t\t// the first basic code points to the output.\n\n\t\tbasic = input.lastIndexOf(delimiter);\n\t\tif (basic < 0) {\n\t\t\tbasic = 0;\n\t\t}\n\n\t\tfor (j = 0; j < basic; ++j) {\n\t\t\t// if it's not a basic code point\n\t\t\tif (input.charCodeAt(j) >= 0x80) {\n\t\t\t\terror('not-basic');\n\t\t\t}\n\t\t\toutput.push(input.charCodeAt(j));\n\t\t}\n\n\t\t// Main decoding loop: start just after the last delimiter if any basic code\n\t\t// points were copied; start at the beginning otherwise.\n\n\t\tfor (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {\n\n\t\t\t// `index` is the index of the next character to be consumed.\n\t\t\t// Decode a generalized variable-length integer into `delta`,\n\t\t\t// which gets added to `i`. The overflow checking is easier\n\t\t\t// if we increase `i` as we go, then subtract off its starting\n\t\t\t// value at the end to obtain `delta`.\n\t\t\tfor (oldi = i, w = 1, k = base; /* no condition */; k += base) {\n\n\t\t\t\tif (index >= inputLength) {\n\t\t\t\t\terror('invalid-input');\n\t\t\t\t}\n\n\t\t\t\tdigit = basicToDigit(input.charCodeAt(index++));\n\n\t\t\t\tif (digit >= base || digit > floor((maxInt - i) / w)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\ti += digit * w;\n\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\n\t\t\t\tif (digit < t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tbaseMinusT = base - t;\n\t\t\t\tif (w > floor(maxInt / baseMinusT)) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tw *= baseMinusT;\n\n\t\t\t}\n\n\t\t\tout = output.length + 1;\n\t\t\tbias = adapt(i - oldi, out, oldi == 0);\n\n\t\t\t// `i` was supposed to wrap around from `out` to `0`,\n\t\t\t// incrementing `n` each time, so we'll fix that now:\n\t\t\tif (floor(i / out) > maxInt - n) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tn += floor(i / out);\n\t\t\ti %= out;\n\n\t\t\t// Insert `n` at position `i` of the output\n\t\t\toutput.splice(i++, 0, n);\n\n\t\t}\n\n\t\treturn ucs2encode(output);\n\t}\n\n\t/**\n\t * Converts a string of Unicode symbols to a Punycode string of ASCII-only\n\t * symbols.\n\t * @memberOf punycode\n\t * @param {String} input The string of Unicode symbols.\n\t * @returns {String} The resulting Punycode string of ASCII-only symbols.\n\t */\n\tfunction encode(input) {\n\t\tvar n,\n\t\t    delta,\n\t\t    handledCPCount,\n\t\t    basicLength,\n\t\t    bias,\n\t\t    j,\n\t\t    m,\n\t\t    q,\n\t\t    k,\n\t\t    t,\n\t\t    currentValue,\n\t\t    output = [],\n\t\t    /** `inputLength` will hold the number of code points in `input`. */\n\t\t    inputLength,\n\t\t    /** Cached calculation results */\n\t\t    handledCPCountPlusOne,\n\t\t    baseMinusT,\n\t\t    qMinusT;\n\n\t\t// Convert the input in UCS-2 to Unicode\n\t\tinput = ucs2decode(input);\n\n\t\t// Cache the length\n\t\tinputLength = input.length;\n\n\t\t// Initialize the state\n\t\tn = initialN;\n\t\tdelta = 0;\n\t\tbias = initialBias;\n\n\t\t// Handle the basic code points\n\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\tcurrentValue = input[j];\n\t\t\tif (currentValue < 0x80) {\n\t\t\t\toutput.push(stringFromCharCode(currentValue));\n\t\t\t}\n\t\t}\n\n\t\thandledCPCount = basicLength = output.length;\n\n\t\t// `handledCPCount` is the number of code points that have been handled;\n\t\t// `basicLength` is the number of basic code points.\n\n\t\t// Finish the basic string - if it is not empty - with a delimiter\n\t\tif (basicLength) {\n\t\t\toutput.push(delimiter);\n\t\t}\n\n\t\t// Main encoding loop:\n\t\twhile (handledCPCount < inputLength) {\n\n\t\t\t// All non-basic code points < n have been handled already. Find the next\n\t\t\t// larger one:\n\t\t\tfor (m = maxInt, j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\t\t\t\tif (currentValue >= n && currentValue < m) {\n\t\t\t\t\tm = currentValue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,\n\t\t\t// but guard against overflow\n\t\t\thandledCPCountPlusOne = handledCPCount + 1;\n\t\t\tif (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {\n\t\t\t\terror('overflow');\n\t\t\t}\n\n\t\t\tdelta += (m - n) * handledCPCountPlusOne;\n\t\t\tn = m;\n\n\t\t\tfor (j = 0; j < inputLength; ++j) {\n\t\t\t\tcurrentValue = input[j];\n\n\t\t\t\tif (currentValue < n && ++delta > maxInt) {\n\t\t\t\t\terror('overflow');\n\t\t\t\t}\n\n\t\t\t\tif (currentValue == n) {\n\t\t\t\t\t// Represent delta as a generalized variable-length integer\n\t\t\t\t\tfor (q = delta, k = base; /* no condition */; k += base) {\n\t\t\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\t\t\t\t\t\tif (q < t) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tqMinusT = q - t;\n\t\t\t\t\t\tbaseMinusT = base - t;\n\t\t\t\t\t\toutput.push(\n\t\t\t\t\t\t\tstringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))\n\t\t\t\t\t\t);\n\t\t\t\t\t\tq = floor(qMinusT / baseMinusT);\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.push(stringFromCharCode(digitToBasic(q, 0)));\n\t\t\t\t\tbias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);\n\t\t\t\t\tdelta = 0;\n\t\t\t\t\t++handledCPCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t++delta;\n\t\t\t++n;\n\n\t\t}\n\t\treturn output.join('');\n\t}\n\n\t/**\n\t * Converts a Punycode string representing a domain name to Unicode. Only the\n\t * Punycoded parts of the domain name will be converted, i.e. it doesn't\n\t * matter if you call it on a string that has already been converted to\n\t * Unicode.\n\t * @memberOf punycode\n\t * @param {String} domain The Punycode domain name to convert to Unicode.\n\t * @returns {String} The Unicode representation of the given Punycode\n\t * string.\n\t */\n\tfunction toUnicode(domain) {\n\t\treturn mapDomain(domain, function(string) {\n\t\t\treturn regexPunycode.test(string)\n\t\t\t\t? decode(string.slice(4).toLowerCase())\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/**\n\t * Converts a Unicode string representing a domain name to Punycode. Only the\n\t * non-ASCII parts of the domain name will be converted, i.e. it doesn't\n\t * matter if you call it with a domain that's already in ASCII.\n\t * @memberOf punycode\n\t * @param {String} domain The domain name to convert, as a Unicode string.\n\t * @returns {String} The Punycode representation of the given domain name.\n\t */\n\tfunction toASCII(domain) {\n\t\treturn mapDomain(domain, function(string) {\n\t\t\treturn regexNonASCII.test(string)\n\t\t\t\t? 'xn--' + encode(string)\n\t\t\t\t: string;\n\t\t});\n\t}\n\n\t/*--------------------------------------------------------------------------*/\n\n\t/** Define the public API */\n\tpunycode = {\n\t\t/**\n\t\t * A string representing the current Punycode.js version number.\n\t\t * @memberOf punycode\n\t\t * @type String\n\t\t */\n\t\t'version': '1.2.4',\n\t\t/**\n\t\t * An object of methods to convert from JavaScript's internal character\n\t\t * representation (UCS-2) to Unicode code points, and back.\n\t\t * @see <http://mathiasbynens.be/notes/javascript-encoding>\n\t\t * @memberOf punycode\n\t\t * @type Object\n\t\t */\n\t\t'ucs2': {\n\t\t\t'decode': ucs2decode,\n\t\t\t'encode': ucs2encode\n\t\t},\n\t\t'decode': decode,\n\t\t'encode': encode,\n\t\t'toASCII': toASCII,\n\t\t'toUnicode': toUnicode\n\t};\n\n\t/** Expose `punycode` */\n\t// Some AMD build optimizers, like r.js, check for specific condition patterns\n\t// like the following:\n\tif (\n\t\ttypeof define == 'function' &&\n\t\ttypeof define.amd == 'object' &&\n\t\tdefine.amd\n\t) {\n\t\tdefine('punycode', function() {\n\t\t\treturn punycode;\n\t\t});\n\t} else if (freeExports && !freeExports.nodeType) {\n\t\tif (freeModule) { // in Node.js or RingoJS v0.8.0+\n\t\t\tfreeModule.exports = punycode;\n\t\t} else { // in Narwhal or RingoJS v0.7.0-\n\t\t\tfor (key in punycode) {\n\t\t\t\tpunycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);\n\t\t\t}\n\t\t}\n\t} else { // in Rhino or a web browser\n\t\troot.punycode = punycode;\n\t}\n\n}(this));\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar stringifyPrimitive = function(v) {\n  switch (typeof v) {\n    case 'string':\n      return v;\n\n    case 'boolean':\n      return v ? 'true' : 'false';\n\n    case 'number':\n      return isFinite(v) ? v : '';\n\n    default:\n      return '';\n  }\n};\n\nmodule.exports = function(obj, sep, eq, name) {\n  sep = sep || '&';\n  eq = eq || '=';\n  if (obj === null) {\n    obj = undefined;\n  }\n\n  if (typeof obj === 'object') {\n    return map(objectKeys(obj), function(k) {\n      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;\n      if (isArray(obj[k])) {\n        return map(obj[k], function(v) {\n          return ks + encodeURIComponent(stringifyPrimitive(v));\n        }).join(sep);\n      } else {\n        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));\n      }\n    }).join(sep);\n\n  }\n\n  if (!name) return '';\n  return encodeURIComponent(stringifyPrimitive(name)) + eq +\n         encodeURIComponent(stringifyPrimitive(obj));\n};\n\nvar isArray = Array.isArray || function (xs) {\n  return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\nfunction map (xs, f) {\n  if (xs.map) return xs.map(f);\n  var res = [];\n  for (var i = 0; i < xs.length; i++) {\n    res.push(f(xs[i], i));\n  }\n  return res;\n}\n\nvar objectKeys = Object.keys || function (obj) {\n  var res = [];\n  for (var key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);\n  }\n  return res;\n};\n","module.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\n// If obj.hasOwnProperty has been overridden, then calling\n// obj.hasOwnProperty(prop) will break.\n// See: https://github.com/joyent/node/issues/1707\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nmodule.exports = function(qs, sep, eq, options) {\n  sep = sep || '&';\n  eq = eq || '=';\n  var obj = {};\n\n  if (typeof qs !== 'string' || qs.length === 0) {\n    return obj;\n  }\n\n  var regexp = /\\+/g;\n  qs = qs.split(sep);\n\n  var maxKeys = 1000;\n  if (options && typeof options.maxKeys === 'number') {\n    maxKeys = options.maxKeys;\n  }\n\n  var len = qs.length;\n  // maxKeys <= 0 means that we should not limit keys count\n  if (maxKeys > 0 && len > maxKeys) {\n    len = maxKeys;\n  }\n\n  for (var i = 0; i < len; ++i) {\n    var x = qs[i].replace(regexp, '%20'),\n        idx = x.indexOf(eq),\n        kstr, vstr, k, v;\n\n    if (idx >= 0) {\n      kstr = x.substr(0, idx);\n      vstr = x.substr(idx + 1);\n    } else {\n      kstr = x;\n      vstr = '';\n    }\n\n    k = decodeURIComponent(kstr);\n    v = decodeURIComponent(vstr);\n\n    if (!hasOwnProperty(obj, k)) {\n      obj[k] = v;\n    } else if (isArray(obj[k])) {\n      obj[k].push(v);\n    } else {\n      obj[k] = [obj[k], v];\n    }\n  }\n\n  return obj;\n};\n\nvar isArray = Array.isArray || function (xs) {\n  return Object.prototype.toString.call(xs) === '[object Array]';\n};\n"]}