{"version":3,"sources":["node_modules/browser-pack/_prelude.js","browser-index.js","/source/lib/src/ReEmitter.js","/source/lib/src/base-apis.js","/source/lib/src/client.js","/source/lib/src/content-repo.js","/source/lib/src/crypto/DeviceList.js","/source/lib/src/crypto/OlmDevice.js","/source/lib/src/crypto/OutgoingRoomKeyRequestManager.js","/source/lib/src/crypto/algorithms/base.js","/source/lib/src/crypto/algorithms/index.js","/source/lib/src/crypto/algorithms/megolm.js","/source/lib/src/crypto/algorithms/olm.js","/source/lib/src/crypto/deviceinfo.js","/source/lib/src/crypto/index.js","/source/lib/src/crypto/olmlib.js","/source/lib/src/crypto/store/indexeddb-crypto-store-backend.js","/source/lib/src/crypto/store/indexeddb-crypto-store.js","/source/lib/src/crypto/store/memory-crypto-store.js","/source/lib/src/filter-component.js","/source/lib/src/filter.js","/source/lib/src/http-api.js","/source/lib/src/interactive-auth.js","/source/lib/src/matrix.js","/source/lib/src/models/event-context.js","/source/lib/src/models/event-timeline-set.js","/source/lib/src/models/event-timeline.js","/source/lib/src/models/event.js","/source/lib/src/models/group.js","/source/lib/src/models/room-member.js","/source/lib/src/models/room-state.js","/source/lib/src/models/room-summary.js","/source/lib/src/models/room.js","/source/lib/src/models/search-result.js","/source/lib/src/models/user.js","/source/lib/src/pushprocessor.js","/source/lib/src/realtime-callbacks.js","/source/lib/src/scheduler.js","/source/lib/src/store/indexeddb-local-backend.js","/source/lib/src/store/indexeddb-remote-backend.js","/source/lib/src/store/indexeddb.js","/source/lib/src/store/memory.js","/source/lib/src/store/session/webstorage.js","/source/lib/src/store/stub.js","/source/lib/src/sync-accumulator.js","/source/lib/src/sync.js","/source/lib/src/timeline-window.js","/source/lib/src/utils.js","/source/lib/src/webrtc/call.js","node_modules/another-json/another-json.js","node_modules/babel-runtime/core-js/get-iterator.js","node_modules/babel-runtime/core-js/is-iterable.js","node_modules/babel-runtime/core-js/json/stringify.js","node_modules/babel-runtime/core-js/object/assign.js","node_modules/babel-runtime/core-js/object/create.js","node_modules/babel-runtime/core-js/object/define-property.js","node_modules/babel-runtime/core-js/object/get-prototype-of.js","node_modules/babel-runtime/core-js/object/keys.js","node_modules/babel-runtime/core-js/object/set-prototype-of.js","node_modules/babel-runtime/core-js/set.js","node_modules/babel-runtime/core-js/symbol.js","node_modules/babel-runtime/core-js/symbol/iterator.js","node_modules/babel-runtime/helpers/classCallCheck.js","node_modules/babel-runtime/helpers/createClass.js","node_modules/babel-runtime/helpers/defineProperty.js","node_modules/babel-runtime/helpers/inherits.js","node_modules/babel-runtime/helpers/possibleConstructorReturn.js","node_modules/babel-runtime/helpers/slicedToArray.js","node_modules/babel-runtime/helpers/typeof.js","node_modules/babel-runtime/regenerator/index.js","node_modules/bluebird/js/browser/bluebird.js","node_modules/browser-request/index.js","node_modules/content-type/index.js","node_modules/core-js/library/fn/get-iterator.js","node_modules/core-js/library/fn/is-iterable.js","node_modules/core-js/library/fn/json/stringify.js","node_modules/core-js/library/fn/object/assign.js","node_modules/core-js/library/fn/object/create.js","node_modules/core-js/library/fn/object/define-property.js","node_modules/core-js/library/fn/object/get-prototype-of.js","node_modules/core-js/library/fn/object/keys.js","node_modules/core-js/library/fn/object/set-prototype-of.js","node_modules/core-js/library/fn/set.js","node_modules/core-js/library/fn/symbol/index.js","node_modules/core-js/library/fn/symbol/iterator.js","node_modules/core-js/library/modules/_a-function.js","node_modules/core-js/library/modules/_add-to-unscopables.js","node_modules/core-js/library/modules/_an-instance.js","node_modules/core-js/library/modules/_an-object.js","node_modules/core-js/library/modules/_array-from-iterable.js","node_modules/core-js/library/modules/_array-includes.js","node_modules/core-js/library/modules/_array-methods.js","node_modules/core-js/library/modules/_array-species-constructor.js","node_modules/core-js/library/modules/_array-species-create.js","node_modules/core-js/library/modules/_classof.js","node_modules/core-js/library/modules/_cof.js","node_modules/core-js/library/modules/_collection-strong.js","node_modules/core-js/library/modules/_collection-to-json.js","node_modules/core-js/library/modules/_collection.js","node_modules/core-js/library/modules/_core.js","node_modules/core-js/library/modules/_ctx.js","node_modules/core-js/library/modules/_defined.js","node_modules/core-js/library/modules/_descriptors.js","node_modules/core-js/library/modules/_dom-create.js","node_modules/core-js/library/modules/_enum-bug-keys.js","node_modules/core-js/library/modules/_enum-keys.js","node_modules/core-js/library/modules/_export.js","node_modules/core-js/library/modules/_fails.js","node_modules/core-js/library/modules/_for-of.js","node_modules/core-js/library/modules/_global.js","node_modules/core-js/library/modules/_has.js","node_modules/core-js/library/modules/_hide.js","node_modules/core-js/library/modules/_html.js","node_modules/core-js/library/modules/_ie8-dom-define.js","node_modules/core-js/library/modules/_iobject.js","node_modules/core-js/library/modules/_is-array-iter.js","node_modules/core-js/library/modules/_is-array.js","node_modules/core-js/library/modules/_is-object.js","node_modules/core-js/library/modules/_iter-call.js","node_modules/core-js/library/modules/_iter-create.js","node_modules/core-js/library/modules/_iter-define.js","node_modules/core-js/library/modules/_iter-step.js","node_modules/core-js/library/modules/_iterators.js","node_modules/core-js/library/modules/_library.js","node_modules/core-js/library/modules/_meta.js","node_modules/core-js/library/modules/_object-assign.js","node_modules/core-js/library/modules/_object-create.js","node_modules/core-js/library/modules/_object-dp.js","node_modules/core-js/library/modules/_object-dps.js","node_modules/core-js/library/modules/_object-gopd.js","node_modules/core-js/library/modules/_object-gopn-ext.js","node_modules/core-js/library/modules/_object-gopn.js","node_modules/core-js/library/modules/_object-gops.js","node_modules/core-js/library/modules/_object-gpo.js","node_modules/core-js/library/modules/_object-keys-internal.js","node_modules/core-js/library/modules/_object-keys.js","node_modules/core-js/library/modules/_object-pie.js","node_modules/core-js/library/modules/_object-sap.js","node_modules/core-js/library/modules/_property-desc.js","node_modules/core-js/library/modules/_redefine-all.js","node_modules/core-js/library/modules/_redefine.js","node_modules/core-js/library/modules/_set-collection-from.js","node_modules/core-js/library/modules/_set-collection-of.js","node_modules/core-js/library/modules/_set-proto.js","node_modules/core-js/library/modules/_set-species.js","node_modules/core-js/library/modules/_set-to-string-tag.js","node_modules/core-js/library/modules/_shared-key.js","node_modules/core-js/library/modules/_shared.js","node_modules/core-js/library/modules/_string-at.js","node_modules/core-js/library/modules/_to-absolute-index.js","node_modules/core-js/library/modules/_to-integer.js","node_modules/core-js/library/modules/_to-iobject.js","node_modules/core-js/library/modules/_to-length.js","node_modules/core-js/library/modules/_to-object.js","node_modules/core-js/library/modules/_to-primitive.js","node_modules/core-js/library/modules/_uid.js","node_modules/core-js/library/modules/_validate-collection.js","node_modules/core-js/library/modules/_wks-define.js","node_modules/core-js/library/modules/_wks-ext.js","node_modules/core-js/library/modules/_wks.js","node_modules/core-js/library/modules/core.get-iterator-method.js","node_modules/core-js/library/modules/core.get-iterator.js","node_modules/core-js/library/modules/core.is-iterable.js","node_modules/core-js/library/modules/es6.array.iterator.js","node_modules/core-js/library/modules/es6.object.assign.js","node_modules/core-js/library/modules/es6.object.create.js","node_modules/core-js/library/modules/es6.object.define-property.js","node_modules/core-js/library/modules/es6.object.get-prototype-of.js","node_modules/core-js/library/modules/es6.object.keys.js","node_modules/core-js/library/modules/es6.object.set-prototype-of.js","node_modules/core-js/library/modules/es6.set.js","node_modules/core-js/library/modules/es6.string.iterator.js","node_modules/core-js/library/modules/es6.symbol.js","node_modules/core-js/library/modules/es7.set.from.js","node_modules/core-js/library/modules/es7.set.of.js","node_modules/core-js/library/modules/es7.set.to-json.js","node_modules/core-js/library/modules/es7.symbol.async-iterator.js","node_modules/core-js/library/modules/es7.symbol.observable.js","node_modules/core-js/library/modules/web.dom.iterable.js","node_modules/events/events.js","node_modules/process/browser.js","node_modules/punycode/punycode.js","node_modules/querystring-es3/decode.js","node_modules/querystring-es3/encode.js","node_modules/querystring-es3/index.js","node_modules/regenerator-runtime/runtime-module.js","node_modules/regenerator-runtime/runtime.js","node_modules/url/url.js","node_modules/url/util.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","matrixcs","request","indexedDB","global","setCryptoStoreFactory","IndexedDBCryptoStore","Reemitter","target","_classCallCheck3","default","this","boundHandlers","eventName","_target","_len","arguments","args","Array","_key","emit","apply","concat","source","eventNames","_iteratorNormalCompletion","_didIteratorError","_iteratorError","undefined","_step","_iterator","_getIterator3","next","done","value","_handleEvent","bind","boundHandler","on","err","return","MatrixBaseApis","opts","utils","checkObjectHasKeys","baseUrl","idBaseUrl","httpOpts","accessToken","prefix","httpApi","PREFIX_R0","onlyData","extraParams","queryParams","localTimeoutMs","useAuthorizationHeader","_http","MatrixHttpApi","_txnCtr","prototype","getHomeserverUrl","getIdentityServerUrl","getAccessToken","isLoggedIn","makeTxnId","Date","getTime","isUsernameAvailable","username","authedRequest","then","response","available","register","password","sessionId","auth","bindThreepids","guestAccessToken","callback","email","session","params","bind_email","msisdn","bind_msisdn","guest_access_token","x_show_msisdn","registerRequest","registerGuest","body","data","kind","loginFlows","login","loginType","login_data","type","extend","loginWithPassword","user","loginWithSAML2","relayState","relay_state","getCasLoginUrl","redirectUrl","getUrl","PREFIX_UNSTABLE","loginWithToken","token","logout","deactivateAccount","authedRequestWithPrefix","getFallbackAuthUrl","authSessionId","path","encodeUri","$loginType","createRoom","options","roomState","roomId","$roomId","getGroupSummary","groupId","$groupId","getGroupProfile","setGroupProfile","profile","getGroupUsers","getGroupInvitedUsers","getGroupRooms","inviteUserToGroup","userId","$userId","removeUserFromGroup","addUserToGroupSummary","roleId","$roleId","removeUserFromGroupSummary","addRoomToGroupSummary","categoryId","$categoryId","removeRoomFromGroupSummary","addRoomToGroup","isPublic","visibility","updateGroupRoomVisibility","removeRoomFromGroup","acceptGroupInvite","leaveGroup","getJoinedGroups","createGroup","content","getPublicisedGroups","userIds","user_ids","setGroupPublicity","publicise","getStateEvent","eventType","stateKey","pathParams","$eventType","$stateKey","sendStateEvent","redactEvent","eventId","$eventId","roomInitialSync","limit","isFunction","setRoomReadMarkersHttpRequest","rmEventId","rrEventId","m.fully_read","m.read","publicRooms","query_params","server","_keys2","createAlias","alias","$alias","room_id","deleteAlias","getRoomIdForAlias","resolveRoomAlias","roomAlias","getRoomDirectoryVisibility","setRoomDirectoryVisibility","setRoomDirectoryVisibilityAppService","networkId","$networkId","searchUserDirectory","search_term","term","uploadContent","file","cancelUpload","promise","getCurrentUploads","getProfileInfo","info","$info","getThreePids","addThreePid","creds","threePidCreds","deleteThreePid","medium","address","setPassword","authDict","newPassword","new_password","getDevices","setDeviceDetails","device_id","$device_id","deleteDevice","getPushers","setPusher","pusher","getPushRules","addPushRule","scope","ruleId","$kind","$ruleId","deletePushRule","setPushRuleEnabled","enabled","setPushRuleActions","actions","search","queryparams","next_batch","uploadKeysRequest","deviceId","$deviceId","downloadKeysForUsers","device_keys","forEach","claimOneTimeKeys","devices","key_algorithm","queries","query","one_time_keys","getKeyChanges","oldToken","newToken","qps","from","to","requestEmailToken","clientSecret","sendAttempt","nextLink","client_secret","send_attempt","next_link","idServerRequest","PREFIX_IDENTITY_V1","submitMsisdnToken","sid","lookupThreePid","sendToDevice","contentMap","txnId","$txnId","messages","getThirdpartyProtocols","_typeof3","getThirdpartyLocation","protocol","$protocol","MatrixClient","endsWith","substr","reEmitter","_ReEmitter2","store","StubStore","credentials","scheduler","self","setProcessFunction","eventToSend","room","getRoom","getRoomId","status","EventStatus","SENDING","_updatePendingEventStatus","_sendEventHttpRequest","clientRunning","callList","webRtcCall","createNewMatrixCall","_supportsVoip","setupCallEventHandler","_syncingRetry","_syncApi","_peekSync","_isGuest","_ongoingScrollbacks","timelineSupport","Boolean","urlPreviewCache","_notifTimelineSet","_crypto","_cryptoStore","cryptoStore","_sessionStore","sessionStore","_forceTURN","forceTURN","CRYPTO_ENABLED","olmVersion","Crypto","getOlmVersion","_sendEvent","client","event","_bluebird2","resolve","encryptionPromise","_encryptEventIfNeeded","ENCRYPTING","queueEvent","getQueueForEvent","QUEUED","res","updatePendingEvent","SENT","event_id","console","error","stack","NOT_SENT","err2","isEncrypted","isRoomEncrypted","encryptEvent","newStatus","_txnId","getWireType","getStateKey","isState","pathTemplate","getWireContent","log","_setMembershipState","membershipValue","reason","membership","_membershipChange","$room_id","$membership","user_id","_presenceList","method","onEvent","getType","indexOf","isBeingDecrypted","isDecryptionFailure","once","isClientPrepared","callEventHandler","callEventBuffer","push","getContent","call_id","getSender","getAge","lifetime","state","callId","_initWithInvite","candidatesByCall","_gotRemoteIceCandidate","existingCall","existingCalls","values","thisCall","direction","_replacedBy","answer","hangup","_onAnsweredElsewhere","_receivedAnswer","candidates","_onHangupReceived","_initWithHangup","ignoreCallIds","ev","checkTurnServers","isGuest","turnServer","uris","ttl","servers","urls","credential","_turnServers","_checkTurnServersTimeoutID","setTimeout","_reject","defer","reject","_resolve","_PojoToMatrixEventMapper","mapper","plainOldJsObject","MatrixEvent","reEmit","attemptDecryption","_callee2","verified","blocked","known","dev","_regenerator2","wrap","_context2","prev","_bluebird","setDeviceVerification","sent","stop","_ReEmitter","PushProcessor","EventEmitter","url","EventTimeline","SearchResult","contentRepo","Filter","SyncApi","MatrixError","warn","inherits","clearStores","_clientRunning","promises","deleteAllData","all","getUserId","getDomain","replace","getUserIdLocalpart","split","substring","getDeviceId","supportsVoip","setForceTURN","getSyncState","getScheduler","setGuest","retryImmediately","getNotifTimelineSet","setNotifTimelineSet","notifTimelineSet","initCrypto","coroutine","mark","_callee","crypto","_context","abrupt","init","registerEventHandlers","isCryptoEnabled","getDeviceEd25519Key","uploadKeys","uploadDeviceKeys","downloadKeys","forceDownload","getStoredDevicesForUser","_ref2","_x","getStoredDevice","_ref3","_x2","_x3","setDeviceVerified","_setDeviceVerification","setDeviceBlocked","setDeviceKnown","setGlobalBlacklistUnverifiedDevices","getGlobalBlacklistUnverifiedDevices","getEventSenderDeviceInfo","_ref5","_x10","isEventSenderVerified","_ref6","_callee3","device","_context3","isVerified","_x11","setRoomEncryption","config","currentState","getStateEvents","getEndToEndRoom","exportRoomKeys","importRoomKeys","keys","getGroup","getGroups","getRooms","getUser","getUsers","setAccountData","contents","$type","getAccountData","getIgnoredUsers","setIgnoredUsers","ignored_users","map","isUserIgnored","joinRoom","roomIdOrAlias","syncRoom","hasMembershipState","sign_promise","inviteSignUrl","requestOtherUrl","mxid","signed_invite_object","third_party_signed","$roomid","syncApi","_clientOpts","resendEvent","cancelPendingEvent","removeEventFromQueue","CANCELLED","setRoomName","name","setRoomTopic","topic","getRoomTags","setRoomTag","tagName","metadata","$tag","deleteRoomTag","setRoomAccountData","setPowerLevel","powerLevel","users","deepCopy","sendEvent","localEvent","origin_server_ts","addPendingEvent","sendMessage","sendTextMessage","msgtype","sendNotice","sendEmoteMessage","sendImageMessage","text","sendHtmlMessage","htmlBody","format","formatted_body","sendHtmlNotice","sendHtmlEmote","sendReceipt","receiptType","$receiptType","getId","_addLocalEchoReceipt","sendReadReceipt","setRoomReadMarkers","rrEvent","getUrlPreview","ts","key","og","PREFIX_MEDIA_R0","sendTyping","isTyping","timeoutMs","typing","timeout","invite","inviteByEmail","inviteByThreePid","identityServerUrl","id_server","errcode","leave","ban","forget","deleteRoom","removeRoom","unban","kick","getPushActionsForEvent","getPushActions","pushProcessor","setPushActions","actionsForEvent","setProfileInfo","setDisplayName","displayname","setAvatarUrl","avatar_url","mxcUrlToHttp","mxcUrl","width","height","resizeMethod","allowDirectLinks","getHttpUriForMxc","setPresence","presence","getPresenceList","inviteToPresenceList","dropFromPresenceList","drop","scrollback","timeToWaitMs","errorTs","timeWaitedMs","now","Math","max","oldState","paginationToken","numAdded","dir","delay","matrixEvents","chunk","addEventsToTimeline","getLiveTimeline","end","storeEvents","paginateEventContext","eventContext","backwards","getPaginateToken","pendingRequest","_paginateRequests","getEvent","getEventMapper","reverse","addEvents","setPaginateToken","finally","getEventTimeline","timelineSet","getTimelineForEvent","events_after","events","events_before","timeline","addTimeline","initialiseState","getState","FORWARDS","start","paginateEventTimeline","eventTimeline","isNotifTimeline","getTimelineSet","BACKWARDS","getPaginationToken","_paginationRequests","only","next_token","notifications","notification","actionListToActionsObject","setPaginationToken","filter","getFilter","_stringify2","getRoomTimelineFilterComponent","resetNotifTimelineSet","resetLiveTimeline","peekInRoom","stopPeeking","peek","setGuestAccess","writePromise","guest_access","allowJoin","readPromise","allowRead","history_visibility","requestRegisterEmailToken","_requestTokenFromEndpoint","requestRegisterMsisdnToken","phoneCountry","phoneNumber","country","phone_number","requestAdd3pidEmailToken","requestAdd3pidMsisdnToken","requestPasswordEmailToken","requestPasswordMsisdnToken","endpoint","id_server_url","parse","host","postParams","_assign2","getRoomPushRule","pushRules","rule","rule_id","setRoomMutePushRule","mute","deferred","hasDontNotifyRule","roomPushRule","ruleRefreshDeferred","result","searchMessageText","roomEvents","search_categories","room_events","searchRoomEvents","order_by","event_context","before_limit","after_limit","include_profile","searchResults","_query","results","highlights","_processRoomEventsSearch","backPaginateRoomEventsSearch","searchOpts","count","hl","sr","fromJson","syncLeftRooms","_syncedLeftRooms","_syncLeftRoomsPromise","createFilter","filter_id","storeFilter","filterId","allowCached","$filterId","getOrCreateFilter","filterName","getFilterIdByName","existingFilter","oldDef","getDefinition","newDef","deepCompare","setFilterIdByName","httpStatus","existingId","createdFilter","getOpenIdToken","getTurnServers","startClient","_this","initialSyncLimit","canResetEntireTimeline","_canResetTimelineCallback","sync","stopClient","clearTimeout","setCanResetTimelineCallback","cb","getCanResetTimelineCallback","generateClientSecret","ret","chars","charAt","floor","random","mxc","serverAndMediaId","slice","fragmentOffset","fragment","encodeParams","getIdenticonUri","identiconString","$ident","_olmDevice","userStore","userResult","updated","_deviceId","deviceResult","t0","t1","hasOwnProperty","t2","t3","_storeDeviceKeys","signKeyId","signKey","unsigned","deviceStore","_olmlib2","verifySignature","getFingerprint","_deviceinfo2","algorithms","_deviceinfo","_olmlib","TRACKING_STATUS_PENDING_DOWNLOAD","TRACKING_STATUS_DOWNLOAD_IN_PROGRESS","DeviceList","baseApis","olmDevice","_serialiser","DeviceListUpdateSerialiser","_deviceTrackingStatus","getEndToEndDeviceTrackingStatus","_keyDownloadsInProgressByUser","lastKnownSyncToken","usersToDownload","trackingStatus","downloadPromise","_doKeyDownload","_getDevicesFromStore","stored","devs","getEndToEndDevicesForUser","fromStorage","algorithm","senderKey","OLM_ALGORITHM","MEGOLM_ALGORITHM","keyId","deviceKey","_iteratorNormalCompletion2","_didIteratorError2","_iteratorError2","_step2","_iterator2","invalidateUserDeviceList","_iteratorNormalCompletion3","_didIteratorError3","_iteratorError3","_step3","_iterator3","_persistDeviceTrackingStatus","_this2","prom","updateDevicesForUsers","finished","success","storeEndToEndDeviceTrackingStatus","_baseApis","_downloadInProgress","_keyDownloadsQueuedByUser","_queuedQueryDeferred","_nextSyncToken","syncToken","_this3","_doQueuedQueries","_this4","downloadUsers","dk","_iteratorNormalCompletion4","_didIteratorError4","_iteratorError4","_step4","_iterator4","_processQueryResponseForUser","d","_updateStoredDeviceKeysForUser","storage","toStorage","storeEndToEndDevicesForUser","checkPayloadLength","payloadString","MAX_PLAINTEXT_LENGTH","OlmDevice","_pickleKey","deviceCurve25519Key","deviceEd25519Key","_maxOneTimeKeys","_outboundGroupSessionStore","_inboundGroupSessionMessageIndexes","_initialise_account","pickleKey","account","e2eAccount","getEndToEndAccount","unpickle","create","pickled","pickle","storeEndToEndAccount","Olm","e2eKeys","Account","JSON","identity_keys","max_number_of_one_time_keys","free","curve25519","ed25519","get_library_version","_getAccount","func","pickledAccount","_saveAccount","_getSession","sessions","getEndToEndSessions","pickledSession","Session","_saveSession","storeEndToEndSession","session_id","_getUtility","utility","Utility","sign","message","getOneTimeKeys","maxNumberOfOneTimeKeys","markKeysAsPublished","mark_keys_as_published","generateOneTimeKeys","numKeys","generate_one_time_keys","createOutboundSession","theirIdentityKey","theirOneTimeKey","create_outbound","_x4","createInboundSession","_ref7","theirDeviceIdentityKey","message_type","ciphertext","create_inbound_from","remove_one_time_keys","decrypt","payload","_x5","_x6","_x7","getSessionIdsForDevice","_ref8","_x8","getSessionIdForDevice","_ref9","sessionIds","sort","_x9","getSessionInfoForDevice","_ref10","deviceIdentityKey","getSessionInfo","hasReceivedMessage","has_received_message","encryptMessage","_ref11","encrypt","_x12","_x13","decryptMessage","_ref12","_x14","_x15","_x16","_x17","matchesSession","_ref13","matches_inbound","_x18","_x19","_x20","_x21","_saveOutboundGroupSession","_getOutboundGroupSession","OutboundGroupSession","createOutboundGroupSession","encryptGroupMessage","getOutboundGroupSessionKey","chain_index","message_index","session_key","_saveInboundGroupSession","senderCurve25519Key","sessionData","storeEndToEndInboundGroupSession","_getInboundGroupSession","getEndToEndInboundGroupSession","InboundGroupSession","addInboundGroupSession","_ref14","forwardingCurve25519KeyChain","sessionKey","keysClaimed","exportFormat","updateSession","import_session","_x22","_x23","_x24","_x25","_x26","_x27","_x28","importInboundGroupSession","_ref15","sender_key","sender_claimed_keys","forwarding_curve25519_key_chain","_x29","decryptGroupMessage","_ref16","timestamp","plaintext","messageIndexKey","msgInfo","id","_x30","_x31","_x32","_x33","_x34","_x35","hasInboundSessionKeys","_ref17","_x36","_x37","_x38","getInboundGroupSessionKey","_ref18","getKey","messageIndex","first_known_index","claimedKeys","senderEd25519Key","export_session","sender_claimed_ed25519_key","_x39","_x40","_x41","exportInboundGroupSession","_ref19","_x42","_x43","signature","util","ed25519_verify","stringifyRequestBody","requestBody","stringifyRecipientList","recipients","_utils2","join","_utils","ROOM_KEY_REQUEST_STATES","UNSENT","CANCELLATION_PENDING","OutgoingRoomKeyRequestManager","_sendOutgoingRoomKeyRequestsTimer","_sendOutgoingRoomKeyRequestsRunning","_startTimer","getOrAddOutgoingRoomKeyRequest","requestId","req","getOutgoingRoomKeyRequest","deleteOutgoingRoomKeyRequest","updateOutgoingRoomKeyRequest","cancellationTxnId","updatedReq","_sendOutgoingRoomKeyRequestCancellation","catch","startSendingOutgoingRoomKeyRequests","_sendOutgoingRoomKeyRequests","getOutgoingRoomKeyRequestByState","_sendOutgoingRoomKeyRequest","_this5","requestMessage","action","requesting_device_id","request_id","_sendMessageToDevices","_this6","recip","registerAlgorithm","encryptor","decryptor","ENCRYPTION_CLASSES","DECRYPTION_CLASSES","EncryptionAlgorithm","_userId","_roomId","member","oldMembership","DecryptionAlgorithm","keyRequest","DecryptionError","msg","details","_possibleConstructorReturn3","__proto__","_getPrototypeOf2","k","UnknownDeviceError","base","OutboundSessionInfo","useCount","creationTime","sharedWithDevices","MegolmEncryption","_setupPromise","_sessionRotationPeriodMsgs","_sessionRotationPeriodMs","rotation_period_ms","rotation_period_msgs","MegolmDecryption","_pendingEvents","olmlib","needsRotation","rotationPeriodMsgs","rotationPeriodMs","sessionLifetime","markSharedWithDevice","chainIndex","sharedWithTooManyDevices","devicesInRoom","_ensureOutboundSession","returnSession","prepareSession","_ref","oldSession","shareMap","userDevices","deviceInfo","_prepareNewSession","getIdentityKey","_shareKeyWithDevices","_splitUserDeviceMap","devicemap","devicesByUser","mapSlices","currentSliceId","entriesInCurrentSlice","devicesToShareWith","sessionResults","sessionResult","_encryptAndSendKeysToDevices","userDeviceMap","encryptedContent","val","encryptMessageForDevice","userDeviceMaps","ensureOlmSessionsForDevices","_getDevicesInRoom","_checkForUnknownDevices","payloadJson","unknownDevices","isUnverified","isKnown","roomMembers","getJoinedMembers","isBlocked","getBlacklistUnverifiedDevices","decryptEvent","_ref4","_callee4","_context4","_addEventToPendingList","getTs","_requestKeysForEvent","toString","_removeEventFromPendingList","clearEvent","claimedEd25519Key","sender","wireContent","requestRoomKey","_set2","add","delete","size","onRoomKeyEvent","getSenderKey","forwardingKeyChain","isArray","ed25519Key","getKeysClaimed","cancelRoomKeyRequest","_retryDecryption","hasKeysForKeyRequest","shareKeysWithDevice","_defineProperty3","_buildKeyForwardingMessage","_callee5","_context5","importRoomKey","pending","OlmEncryption","_sessionPrepared","_prepPromise","OlmDecryption","DeviceInfo","DeviceVerification","_ensureSession","ensureOlmSessionsForUsers","payloadFields","j","BLOCKED","_decryptMessage","recipient","recipient_keys","intended","our_key","reported_sender","reported_room","decryptionErrors","foundSession","Object","defineProperty","enumerable","UNVERIFIED","obj","prop","getDisplayName","device_display_name","VERIFIED","clientStore","_clientStore","_deviceList","_lastOneTimeKeyCheck","_oneTimeKeyCheckInProgress","_roomEncryptors","_roomDecryptors","_supportedAlgorithms","_deviceKeys","_globalBlacklistUnverifiedDevices","_outgoingRoomKeyRequestManager","_OutgoingRoomKeyRequestManager2","_receivedRoomKeyRequests","_receivedRoomKeyRequestCancellations","_processingRoomKeyRequests","_maybeUploadOneTimeKeys","uploadLoop","keyCount","keyLimit","keysThisLoop","min","maxKeysPerCycle","_uploadOneTimeKeys","one_time_key_counts","signed_curve25519","maxOneTimeKeys","_oneTimeKeyCount","oneTimeKeys","oneTimeJson","_signObject","_events","_OutgoingRoomKeyRequestManager","anotherjson","myDevices","eventEmitter","_onRoomMembership","_onToDeviceEvent","deviceKeys","updateOneTimeKeyCount","currentCount","isFinite","TypeError","verificationStatus","knownStatus","getOlmSessionsForUser","deviceIdKey","getForwardingCurve25519KeyChain","getDeviceByIdentityKey","claimedKey","getClaimedEd25519Key","inhibitDeviceQuery","existingConfig","AlgClass","storeEndToEndRoom","alg","m","startTrackingDeviceList","refreshOutdatedDeviceLists","getAllEndToEndInboundGroupSessionKeys","sess","_getRoomDecryptor","makeEncrypted","isRedacted","handleDeviceListChanges","deviceLists","changed","left","stopTrackingDeviceList","sendRoomKeyRequest","onCryptoEvent","onSyncCompleted","syncData","nextSyncToken","oldSyncToken","getEndToEndDeviceSyncToken","_invalidateDeviceListsSince","invalidateAllDeviceLists","storeEndToEndDeviceSyncToken","catchingUp","_processReceivedRoomKeyRequests","_callee6","_context6","_getE2eRooms","me","getMember","_this7","_onRoomKeyEvent","_onRoomKeyRequestEvent","onRoomMembership","IncomingRoomKeyRequest","_req","IncomingRoomKeyRequestCancellation","_callee7","requests","cancellations","_this8","_context7","_processReceivedRoomKeyRequest","cancellation","_processReceivedRoomKeyRequestCancellation","finish","_callee8","_context8","share","decryptors","_callee9","sigs","_context9","stringify","signatures","oneTimeKey","_verifySignature","resultsObject","ourUserId","ourDeviceId","recipientUserId","recipientDevice","sender_device","devicesWithoutSession","oneTimeKeyAlgorithm","otk_res","_loop","_ret","userRes","_j","deviceRes","_verifyKeyAndStartSession","signingUserId","signingDeviceId","signingKey","userSigs","json","upgradeDatabase","db","oldVersion","VERSION","createDatabase","outgoingRoomKeyRequestsStore","createObjectStore","keyPath","createIndex","promiseifyTxn","txn","oncomplete","onerror","Backend","_db","onversionchange","_dbName","close","transaction","_getOutgoingRoomKeyRequest","existing","objectStore","onsuccess","index","openCursor","cursor","continue","wantedStates","stateIndex","wantedState","expectedState","updates","update","_memoryCryptoStore","_indexeddbCryptoStoreBackend","IndexedDBCryptoStoreBackend","dbName","_indexedDB","_backendPromise","open","onupgradeneeded","onblocked","_memoryCryptoStore2","deleteDatabase","_connect","backend","MemoryCryptoStore","_outgoingRoomKeyRequests","try","splice","_matches_wildcard","actual_value","filter_value","type_prefix","FilterComponent","filter_json","types","not_types","rooms","not_rooms","senders","not_senders","contains_url","check","_checkFields","event_type","literal_keys","v","match_func","allowed_values","contains_url_filter","setProp","keyNesting","nestedKeys","currentObj","definition","getFilterId","setDefinition","room_filter_json","room_filter_fields","_include_leave","include_leave","_room_filter","_room_timeline_filter","filterRoomTimeline","setTimelineLimit","setIncludeLeaveRooms","includeLeave","jsonObj","parseErrorResponse","statusCode","contentType","getResponseContentType","getResponseHeader","headers","parseContentType","callbacks","event_emitter","uploads","getContentUri","access_token","fileName","stream","rawResponse","XMLHttpRequest","onlyContentUri","upload","loaded","total","bodyParser","rawBody","content_uri","xhr","requestCallback","timeout_fn","abort","timeout_timer","onreadystatechange","readyState","DONE","resp","responseText","http_status","addEventListener","progressHandler","encodeURIComponent","setRequestHeader","send","filename","Content-Type","promise0","fullUri","uri","withCredentials","_matrix_opts","qs","form","Authorization","requestPromise","requestWithPrefix","_request","queryString","timeoutId","timedOut","resetTimeout","reqPromise","onprogress","ex","userDefinedCallback","errorJson","_create2","constructor","InteractiveAuth","_matrixClient","matrixClient","_data","authData","_requestCallback","doRequest","_stateUpdatedCallback","stateUpdated","startAuthStage","_completionDeferred","_inputs","inputs","_clientSecret","_emailSid","emailSid","_currentStage","attemptAuth","flows","_startNextAuthStage","_doRequest","poll","idServerParsedUrl","threepid_creds","submitAuthDict","getSessionId","getClientSecret","getStageParams","background","getEmailSid","setEmailSid","errorFlows","haveFlows","completed","nextStage","_chooseStage","stageStatus","flow","_chooseFlow","_firstUncompletedStage","haveEmail","emailAddress","haveMsisdn","flowHasEmail","flowHasMsisdn","stages","stage","required_stages","available_flows","stageType","MatrixInMemoryStore","IndexedDBStore","IndexedDBStoreBackend","SyncAccumulator","Room","EventTimelineSet","RoomMember","RoomState","User","MatrixScheduler","WebStorageSessionStore","ContentRepo","TimelineWindow","setMatrixCallAudioInput","setAudioInput","setMatrixCallVideoInput","setVideoInput","getRequest","wrapRequest","wrapper","origRequest","cryptoStoreFactory","fac","createClient","localStorage","EventContext","ourEvent","_timeline","_ourEventIndex","_paginateTokens","b","getTimeline","getOurEventIndex","atStart","_timelineSupport","_liveTimeline","_timelines","_eventIdToTimeline","_filter","debuglog","setFilter","getPendingEvents","eventIdToTimeline","replaceEventId","oldEventId","newEventId","existingTimeline","backPaginationToken","forwardPaginationToken","resetAllTimelines","newTimeline","oldTimeline","evMap","evtype","freshEndState","_endState","findEventById","tl","findElement","getEvents","toStartOfTimeline","inverseDirection","didUpdate","lastEventWasNew","neighbour","getNeighbouringTimeline","setNeighbouringTimeline","addEventToTimeline","addLiveEvent","duplicateStrategy","tlEvents","setEventMetadata","encryptedType","addEvent","liveEvent","handleRemoteEcho","removeEvent","removed","compareEventOrdering","eventId1","eventId2","timeline1","timeline2","idx1","idx2","idx","evId","eventTimelineSet","_eventTimelineSet","_baseIndex","_startState","_prevTimeline","_nextTimeline","_name","toISOString","stateEvents","oldStateEvents","mxEvent","setStateEvents","getBaseIndex","stateContext","getUnfilteredTimelineSet","insertIndex","getSentinelMember","forwardLooking","interns","_pushActions","_date","_clearEvent","_senderCurve25519Key","_claimedEd25519Key","_forwardingCurve25519KeyChain","_decryptionPromise","getDate","getPrevContent","getUnsigned","prev_content","getDirectionalContent","age","state_key","crypto_type","crypto_content","_decryptionLoop","_badEncryptedMessage","_setClearData","decryptionResult","makeRedacted","redaction_event","redacted_because","_REDACT_KEEP_KEY_MAP","keeps","_REDACT_KEEP_CONTENT_MAP","pushActions","reduce","m.room.member","m.room.create","creator","m.room.join_rules","join_rule","m.room.power_levels","events_default","redact","state_default","users_default","m.room.aliases","aliases","Group","avatarUrl","myMembership","inviter","setProfile","setMyMembership","setInviter","rawDisplayName","powerLevelNorm","_updateModifiedTime","calculateDisplayName","displayName","selfUserId","getUserIdsWithDisplayName","setMembershipEvent","oldName","setPowerLevelEvent","powerLevelEvent","evContent","maxLevel","lvl","oldPowerLevel","oldPowerLevelNorm","setTypingEvent","oldTyping","typingList","_modified","getLastModifiedTime","getAvatarUrl","allowDefault","rawUrl","httpUrl","members","_sentinels","_displayNameToUserIds","_userIdsToDisplayNames","_tokenToInvite","_updateThirdPartyTokenCache","memberEvent","third_party_invite","signed","_updateDisplayNameCache","existingUserIds","getMembers","sentinel","roomMember","pwrLvlEvent","oldSentinel","newSentinel","getInviteForThreePidToken","maySendRedactionForEvent","_hasSufficientPowerLevelFor","powerLevelsEvent","powerLevels","requiredLevel","maySendMessage","_maySendEventOfType","maySendEvent","mayClientSendStateEvent","stateEventType","cli","maySendStateEvent","power_levels_event","power_levels","events_levels","required_level","mayTriggerNotifOfType","notifLevelKey","notifLevel","RoomSummary","synthesizeReceipt","fakeReceipt","pendingEventOrdering","tags","accountData","summary","storageToken","_opts","_txnToEvent","_receipts","_receiptCacheByEventId","_realReceipts","_notificationCounts","_timelineSets","_fixUpLegacyTimelineFields","_filteredTimelineSets","_pendingEventList","_blacklistUnverifiedDevices","calculateRoomName","ignoreRoomNameEvent","mRoomName","getCanonicalAlias","getAliases","otherMembers","allMembers","myMemberEventArray","myMemberEvent","thirdPartyInvites","display_name","getTimelineSets","getUnreadNotificationCount","setUnreadNotificationCount","setBlacklistUnverifiedDevices","roomAvatarEvent","mainUrl","alias_strings","alias_events","alias_event","canonicalAlias","getMembersWithMembership","getDefaultRoomName","getOrCreateFilteredTimelineSet","unfilteredLiveTimeline","removeFilteredTimelineSet","_addLiveEvent","redactId","redacts","redactedEvent","transaction_id","existingEvent","_handleRemoteEcho","addReceipt","remoteEvent","oldStatus","removeElement","ALLOWED_TRANSITIONS","allowed","addLiveEvents","liveTimeline","removeEvents","event_ids","removedAny","recalculate","membershipEvent","strippedStateEvents","invite_room_state","strippedEvent","title","getUsersReadUpTo","getReceiptsForEvent","receipt","getEventReadUpTo","ignoreSynthesized","receipts","fake","_addReceiptsToStructure","_buildReceiptCache","existingReceipt","ordering","receiptCacheByEventId","addTags","addAccountData","rank","context","eventMapper","jsonContext","presenceStatusMsg","lastActiveAgo","lastPresenceTs","currentlyActive","setPresenceEvent","firstFire","eventsToFire","currently_active","status_msg","last_active_ago","setRawDisplayName","oldUrl","getLastActiveTs","escapeRegExp","string","matchingRuleFromKindSet","kindset","ruleKindIndex","RULEKINDS_IN_ORDER","ruleset","ruleIndex","rawrule","templateRuleToRaw","ruleMatchesEvent","tprule","conditions","pattern","profile_tag","eventFulfillsCondition","cond","condition_functions","event_match","eventFulfillsEventMatchCondition","eventFulfillsDeviceCondition","contains_display_name","eventFulfillsDisplayNameCondition","room_member_count","eventFulfillsRoomMemberCountCondition","sender_notification_permission","eventFulfillsSenderNotifPermCondition","is","memberCount","match","ineq","rhs","parseInt","isNaN","pat","RegExp","valueForDottedKey","globToRegexp","regex","glob","p1","p2","offset","parts","firstPart","shift","thispart","matchingRuleForEventWithRulesets","rulesets","allDevNames","devname","devrules","matchingRule","pushActionsForEventAndRulesets","actionObj","tweaks","highlight","getPushRuleById","_arr","_i","actionlist","actionobj","notify","set_tweak","_scheduleRealCallback","_realCallbackKey","first","_callbackList","_now","delayMs","runAt","TIMER_CHECK_PERIOD_MS","_runCallbacks","callbacksToRun","binarySearch","array","mid","_count","setNow","el","retryAlgorithm","queueAlgorithm","RETRY_BACKOFF_RATELIMIT","QUEUE_MESSAGES","_queues","_activeQueues","_procFn","_startProcessingQueues","queueName","_processQueue","_peekNextEvent","_removeNextEvent","attempts","waitTimeMs","queue","DEBUG","_console","element","fn","cors","waitTime","retry_after_ms","pow","selectQuery","keyRange","resultMapper","errorCode","promiseifyRequest","_syncAccumulator","LocalIndexedDBStoreBackend","indexedDBInterface","_syncAccumulator2","connect","_init","_loadAccountData","_loadSyncData","_slicedToArray3","accumulate","nextBatch","roomsData","groups","groupsData","account_data","clearDatabase","getSavedSync","copy","getJSON","setSyncData","syncToDatabase","userTuples","_persistUserPresenceEvents","_persistAccountData","_persistSyncData","put","clobber","tuples","tuple","getUserPresenceEvents","_this9","_this10","RemoteIndexedDBStoreBackend","workerScript","WorkerApi","_worker","_nextSeq","_inFlight","onmessage","_onWorkerMessage","_startPromise","_doCmd","cmd","seq","def","postMessage","command","_memory","_indexeddbLocalBackend","_indexeddbRemoteBackend","_user","_event","workerApi","Worker","_indexeddbRemoteBackend2","_indexeddbLocalBackend2","startedUp","_syncTs","_userModifiedMap","startup","userPresenceEvents","rawEvent","_user2","storeUser","save","_reallySave","filters","getSyncToken","setSyncToken","storeGroup","group","storeRoom","_onRoomMember","removeListener","getRoomSummaries","toStart","getItem","setItem","storeAccountDataEvents","webStore","removeItem","keyEndToEndDevicesForUser","E2E_PREFIX","keyEndToEndSessions","keyEndToEndInboundGroupSession","keyEndToEndRoom","getJsonItem","setJsonItem","KEY_END_TO_END_ACCOUNT","statusMap","KEY_END_TO_END_DEVICE_LIST_TRACKING_STATUS","KEY_END_TO_END_DEVICE_SYNC_TOKEN","startsWith","roomInfo","fromToken","setState","eventMap","maxTimelineEntries","inviteRooms","joinRooms","syncResponse","_accumulateRooms","_accumulateGroups","_accumulateAccountData","_accumulateRoom","category","_accumulateInviteState","_accumulateJoinState","invite_state","currentData","hasAdded","current","_currentState","_accountData","_unreadNotifications","_readReceipts","unread_notifications","ephemeral","limited","prev_batch","startIndex","_accumulateGroup","cat","roomData","roomJson","evType","receiptEvent","receiptData","msgData","rollBackState","timelineEvent","prevStateEvent","prev_sender","accData","getFilterName","suffix","resolveInvitesToProfiles","pollTimeout","_peekRoomId","_currentSyncRequest","_syncState","_catchingUp","_running","_keepAliveTimer","_connectionReturnedDefer","_notifEvents","_failedSyncCount","createNewUser","_registerStateListeners","_deregisterStateListeners","removeAllListeners","leaveRooms","_mapSyncResponseToRoomArray","leaveObj","isBrandNewRoom","timelineEvents","_mapSyncEventsFormat","_processRoomEvents","_processEventsForNotifs","peekRoom","presenceEvent","_resolveInvites","_peekPoll","_startKeepAlives","_updateSyncState","_sync","document","_onOnlineBound","_onOnline","removeEventListener","syncOptions","clientSideTimeoutMs","savedSync","isCachedResponse","syncEventData","_getGuestFilter","since","_cacheBuster","hasSyncedBefore","_onSyncError","_processSyncResponse","accountDataEvent","to_device","toDeviceEvent","_processGroupSyncEntry","inviteObj","mapSeries","joinObj","ephemeralEvents","accountDataEvents","processRoomEvent","notification_count","highlight_count","device_lists","device_one_time_keys_count","_pokeKeepAlive","groupsSection","sectionName","groupInfo","isBrandNew","arrObj","_requestedProfileInfo","inviteEvent","stateEventList","timelineEventList","_guestRooms","newState","old","_client","_timelineSet","_start","_end","_eventCount","_windowLimit","windowLimit","TimelineIndex","load","initialEventId","initialWindowSize","initFields","eventIndex","endIndex","ceil","isFulfilled","canPaginate","minIndex","maxIndex","paginate","makeRequest","requestLimit","pendingPaginate","retreat","advance","excess","unpaginate","delta","startOfTimeline","cappedDelta","variables","checkObjectHasNoAdditionalKeys","allowedKeys","x","y","p","propName","runPolyfills","fun","len","thisArg","T","O","A","kValue","mappedValue","ctor","superCtor","Temp","hasOwn","Properties","super_","writable","configurable","MatrixCall","webRtc","URL","turnServers","FALLBACK_STUN_SERVER","didConnect","candidateSendQueue","candidateSendTries","mediaPromises","screenSharingStream","CALL_TIMEOUT_MS","ERR_LOCAL_OFFER_FAILED","ERR_NO_USER_MEDIA","placeVoiceCall","checkForErrorListener","_placeCallWithConstraints","_getUserMediaVideoContraints","placeVideoCall","remoteVideoElement","localVideoElement","_tryPlayRemoteStream","placeScreenSharingCall","screenConstraints","_getScreenSharingConstraints","getUserMedia","audioConstraints","callError","playElement","queueId","play","pauseElement","pause","assignElement","srcObject","getLocalVideoElement","getRemoteVideoElement","getRemoteAudioElement","remoteAudioElement","setLocalVideoElement","localAVStream","autoplay","muted","vel","setRemoteVideoElement","setRemoteAudioElement","_tryPlayRemoteAudioStream","peerConn","_createPeerConnection","setRemoteDescription","RtcSessionDescription","offer","hookCallback","_onSetRemoteDescriptionSuccess","_onSetRemoteDescriptionError","sdp","hangupParty","stopAllMedia","signalingState","waitForLocalAVStream","_maybeGotUserMediaForAnswer","newCall","successor","suppressEvent","terminate","version","setLocalVideoMuted","setTracksEnabled","getVideoTracks","isLocalVideoMuted","isTracksEnabled","setMicrophoneMuted","getAudioTracks","isMicrophoneMuted","_maybeGotUserMediaForInvite","constraints","mandatory","OfferToReceiveAudio","OfferToReceiveVideo","MediaStream","videoEl","addTrack","addStream","_getUserMediaFailed","createOffer","_gotLocalOffer","_getLocalOfferFailed","localVidEl","createAnswer","description","setLocalDescription","localDescription","_gotLocalIceCandidate","candidate","sdpMid","c","sdpMLineIndex","sendCandidate","cand","addIceCandidate","RtcIceCandidate","_onIceConnectionStateChanged","iceConnectionState","_onSignallingStateChanged","_onAddStream","remoteAVStream","remoteAStream","forAllTracksOnStream","onstarted","_onRemoteStreamTrackStarted","oninactive","_onRemoteStreamEnded","onended","_onRemoteStreamStarted","tracks","_sendCandidateQueue","hangupReason","shouldEmit","player","isOpenWebRTC","ael","listeners","cands","vendor","pc","RtcPeerConnection","iceTransportPolicy","iceServers","oniceconnectionstatechange","onsignalingstatechange","onicecandidate","onaddstream","screen","video","mediaSource","chromeMediaSource","chromeMediaSourceId","maxWidth","maxHeight","minFrameRate","maxFrameRate","callType","isWebkit","window","navigator","webkitGetUserMedia","audio","audioInput","exact","videoInput","ideal","forAllVideoTracksOnStream","forAllAudioTracksOnStream","w","doc","scripts","getElementById","src","mozGetUserMedia","RTCPeerConnection","webkitRTCPeerConnection","mozRTCPeerConnection","RTCSessionDescription","webkitRTCSessionDescription","mozRTCSessionDescription","RTCIceCandidate","webkitRTCIceCandidate","mozRTCIceCandidate","optionsForceTURN","escapeString","escaped","lastIndex","escapes","stringifyArray","stringifyObject","sep","object","String","fromCharCode","toUpperCase","__esModule","instance","Constructor","_defineProperty","_defineProperty2","defineProperties","props","descriptor","protoProps","staticProps","_interopRequireDefault","_setPrototypeOf","_setPrototypeOf2","_create","_typeof2","subClass","superClass","ReferenceError","_isIterable2","_isIterable3","_getIterator2","sliceIterator","arr","_n","_d","_e","_s","_symbol","_symbol2","_typeof","define","amd","Promise","_dereq_","any","SomePromiseArray","setHowMany","setUnwrap","_SomePromiseArray","2","Async","_customScheduler","_isTickUsed","_lateQueue","Queue","_normalQueue","_haveDrainedQueues","_trampolineEnabled","drainQueues","_drainQueues","_schedule","schedule","AsyncInvokeLater","receiver","arg","_queueTick","AsyncInvoke","AsyncSettlePromises","_pushOne","firstLineError","setScheduler","hasCustomScheduler","enableTrampoline","disableTrampolineIfNecessary","hasDevTools","haveItemsQueued","fatalError","isNode","process","stderr","write","exit","throwLater","invokeLater","invoke","settlePromises","_settlePromises","_drainQueue","_reset","./queue","./schedule","./util","3","INTERNAL","tryConvertToPromise","debug","calledBind","rejectThis","_","targetRejected","promiseRejectionQueued","bindingPromise","_then","bindingResolved","_bitField","_resolveCallback","bindingRejected","_propagateFrom","propagateFromFunction","_boundValue","boundValueFunction","maybePromise","_setBoundTo","_setOnCancel","_boundTo","_isBound","4","noConflict","bluebird","./promise","5","cr","callerCache","getterCache","ensureMethod","methodName","classString","caller","pop","namedGetter","indexedGetter","getGetter","canEvaluate","isIdentifier","get","propertyName","getter","isIndex","maybeGetter","6","PromiseArray","apiRejection","tryCatch","errorObj","async","_async","cancel","_warn","child","_isCancellable","_cancelBy","_isFollowing","_followee","_cancelBranched","parent","_cancellationParent","_setWillBeCancelled","_branchHasCancelled","_branchesRemainingToCancel","_enoughBranchesHaveCancelled","canceller","_invokeOnCancel","_cancel","_setCancelled","_cancelPromises","_length","_unsetOnCancel","_onCancelField","isPending","_isCancelled","isCancellable","isCancelled","_doInvokeOnCancel","onCancelCallback","internalOnly","_attachExtraTrace","_resultCancelled","_onCancel","_invokeInternalOnCancel","7","NEXT_FILTER","catchFilter","instances","boundTo","predicateLoop","item","matchesPredicate","isObject","getKeys","./es5","8","Context","_trace","CapturedTrace","peekContext","createContext","longStackTraces","contextStack","_promiseCreated","_pushContext","_popContext","_peekContext","trace","deactivateLongStackTraces","activateLongStackTraces","Promise_pushContext","Promise_popContext","Promise_PeekContext","Promise_peekContext","Promise_promiseCreated","ctx","9","generatePromiseLifecycleEventObject","defaultFireEvent","cancellationExecute","executor","onCancel","_attachCancellationCallback","cancellationAttachCancellationCallback","previousOnCancel","cancellationOnCancel","cancellationSetOnCancel","cancellationClearCancellationData","cancellationPropagateFrom","flags","branchesRemainingToCancel","bindingPropagateFrom","longStackTracesCaptureStackTrace","longStackTracesAttachExtraTrace","ignoreSelf","canAttachTrace","_parent","attachExtraTrace","__stackCleaned__","parsed","parseStackAndMessage","notEnumerableProp","checkForgottenReturns","returnValue","promiseCreated","wForgottenReturn","_returnedNonUndefined","handlerLine","creatorLine","traceLines","cleanStack","line","nodeFramePattern","test","lineMatches","parseLinePattern","firstUserLine","deprecated","replacement","shouldUseOwnTrace","warnings","warning","Warning","activeFireEvent","formatAndLogError","reconstructStack","stacks","removeDuplicateOrEmptyJumps","removeCommonRoots","currentLastIndex","currentLastLine","commonRootMeetPoint","isTraceLine","stackFramePattern","isInternalFrame","shouldIgnore","indentStackFrames","stackFramesAsArray","isSoft","formatStack","printWarning","fireRejectionEvent","localHandler","localEventFired","formatNonError","str","snip","maxChars","longStackTracesIsSupported","captureStackTrace","parseLineInfo","matches","parseLineInfoRegex","setBounds","lastLineError","firstFileName","lastFileName","firstStackLines","lastStackLines","firstIndex","bluebirdFramePattern","_promisesCreated","uncycle","unhandledRejectionHandled","possiblyUnhandledRejection","_getDomain","debugging","env","suppressUnhandledRejections","_ensurePossibleRejectionHandled","_setRejectionIsUnhandled","_notifyUnhandledRejection","_notifyUnhandledRejectionIsHandled","_setReturnedNonUndefined","_isRejectionUnhandled","_settledValue","_setUnhandledRejectionIsNotified","_unsetUnhandledRejectionIsNotified","_isUnhandledRejectionNotified","_unsetRejectionIsUnhandled","onPossiblyUnhandledRejection","domain","domainBind","onUnhandledRejectionHandled","disableLongStackTraces","Promise_captureStackTrace","_captureStackTrace","Promise_attachExtraTrace","hasLongStackTraces","fireDomEvent","CustomEvent","dispatchEvent","domEvent","toLowerCase","detail","cancelable","Event","createEvent","initCustomEvent","fireGlobalEvent","eventToObjectGenerator","promiseFulfilled","promiseRejected","promiseResolved","promiseCancelled","promiseChained","unhandledRejection","rejectionHandled","globalEventFired","domEventFired","warningsOption","_clearCancellationData","_execute","monitoring","_fireEvent","handler","nodes","stackToIndex","node","currentStack","cycleEdgeNode","currentChildLength","v8stackFramePattern","v8stackFormatter","stackTraceLimit","ignoreUntil","hasStackAfterThrow","isTTY","color","./errors","10","returner","thrower","thenReturn","thenThrow","catchThrow","_reason","caught","catchReturn","_value","11","promiseAllThis","PromiseAll","PromiseMapSeries","PromiseReduce","each","12","subError","nameProperty","defaultMessage","SubError","OperationalError","cause","_TypeError","_RangeError","es5","Objectfreeze","freeze","CancellationError","TimeoutError","AggregateError","RangeError","methods","level","indent","lines","errorTypes","RejectionError","13","isES5","getDescriptor","getOwnPropertyDescriptor","names","getOwnPropertyNames","getPrototypeOf","propertyIsWritable","set","has","proto","ObjectKeys","ObjectGetDescriptor","ObjectDefineProperty","desc","ObjectFreeze","ObjectGetPrototypeOf","ArrayIsArray","14","PromiseMap","15","PassThroughHandlerContext","called","cancelPromise","FinallyHandlerCancelReaction","finallyHandler","checkCancel","succeed","fail","reasonOrValue","isFinallyHandler","isRejected","_passThrough","lastly","tap","tapCatch","handlerOrPredicate","catchInstances","./catch_filter","16","Proxyable","promiseFromYieldHandler","yieldHandlers","traceParent","PromiseSpawn","generatorFunction","yieldHandler","internal","_finallyPromise","_promise","_stack","_generatorFunction","_receiver","_generator","_yieldHandlers","_yieldedPromise","_cancellationPhase","errors","_isResolved","_cleanup","_fulfill","_promiseCancelled","implementsReturn","returnSentinel","_continue","_promiseFulfilled","_promiseRejected","_run","_rejectCallback","bitField","_proxy","PromiseSpawn$","generator","spawn","addYieldHandler","17","last","spread","18","MappingPromiseArray","constructor$","_callback","_preservedValues","_limit","_queue","_asyncInit","concurrency","_init$","_values","preservedValues","_totalResolved","booleans","19","_resolveFromSyncValue","attempt","20","isUntypedError","wrapAsOperationalError","rErrorKey","markAsOriginatingFromRejection","nodebackForPromise","multiArgs","wrapped","maybeWrapAsError","21","spreadAdapter","nodeback","successAdapter","errorAdapter","newReason","asCallback","nodeify","adapter","22","_fulfillmentHandler0","_rejectionHandler0","_promise0","_receiver0","_resolveFromExecutor","deferResolve","deferReject","fillTypes","makeSelfResolutionError","reflectHandler","PromiseInspection","UNDEFINED_BINDING","APPLY","reflect","didFulfill","didReject","_setIsFinal","toJSON","fulfillmentValue","rejectionReason","originatesFromRejection","getNewLibraryCopy","fromNode","fromCallback","_isFateSealed","_setAsyncGuaranteed","cast","_setFulfilled","fulfilled","rejected","internalData","haveInternalData","settler","_settlePromiseCtx","_settlePromiseLateCancellationObserver","_addCallbacks","_setLength","_setRejected","_setFollowing","_isFinal","_unsetCancelled","_receiverAt","_promiseAt","_fulfillmentHandlerAt","_rejectionHandlerAt","_migrateCallback0","follower","fulfill","_migrateCallbackAt","proxyable","shouldBind","_setFollowee","synchronous","ignoreNonErrorWarnings","ensureErrorObject","hasStack","_settlePromiseFromHandler","_settlePromise","isPromise","asyncGuaranteed","_settlePromise0","_clearCallbackDataAtIndex","_fulfillPromises","_rejectPromises","toFastProperties","./any.js","./async","./bind","./call_get.js","./cancel","./context","./debuggability","./direct_resolve","./each.js","./filter.js","./finally","./generators.js","./join","./map.js","./method","./nodeback","./nodeify.js","./promise_array","./promisify.js","./props.js","./race.js","./reduce.js","./settle.js","./some.js","./synchronous_inspection","./thenables","./timers.js","./using.js","23","toResolutionValue","Map","resolveValueIfEmpty","asArray","_resolveEmptyArray","_iterate","getActualLength","shouldCopyValues","isResolved","24","propsFilter","noCopyPropsPattern","isPromisified","__isPromisified__","hasPromisified","getDataPropertyOrDefault","defaultPromisified","checkValid","suffixRegexp","keyWithoutAsyncSuffix","promisifiableMethods","inheritedDataKeys","passesDefaultFilter","defaultFilter","makeNodePromisifiedClosure","__","promisified","THIS","defaultThis","withAppended","promisifyAll","promisifier","escapeIdentRegex","promisifiedKey","makeNodePromisified","promisify","makeNodePromisifiedEval","noCopyProps","copyDescriptors","isClass","25","PropertiesPromiseArray","entries","isMap","Es6Map","mapToEntries","_isMap","castValue","extractEntry","entriesToMap","keyOffset","26","arrayMove","srcIndex","dst","dstIndex","capacity","_capacity","_front","_willBeOverCapacity","_checkCapacity","wrapMask","front","_resizeTo","oldCapacity","27","race","raceLater","28","ReductionPromiseArray","initialValue","_each","_fn","_initialValue","_currentCancellable","_eachValues","valueOrReason","gotAccum","accum","_gotAccum","gotValue","_eachComplete","_resultCancelled$","29","noAsyncScheduler","NativePromise","getNativePromise","MutationObserver","GlobalSetImmediate","setImmediate","ProcessNextTick","nextTick","isRecentNode","nativePromise","standalone","cordova","div","createElement","attributes","toggleScheduled","div2","classList","toggle","observe","scheduleToggle","disconnect","30","SettledPromiseArray","_promiseResolved","inspection","_settledValueField","settle","31","_howMany","_unwrap","_initialized","some","howMany","CANCELLATION","isArrayResolved","_canPossiblyFulfill","_getRangeError","_addFulfilled","_fulfilled","_addRejected","_checkOutcome","_rejected","32","__isCancelled","33","getThen","isAnyBluebirdPromise","doThenable","doGetThen","hasProp","34","HandleWrapper","handle","successClear","failureClear","afterValue","ms","afterTimeout","handleWrapper","35","castPreservingDisposable","thenable","_isDisposable","_getDisposer","_setDisposable","dispose","resources","iterator","tryDispose","Disposer","FunctionDisposer","maybeUnwrapDisposer","isDisposer","ResourceList","NULL","resource","doDispose","_unsetDisposable","using","input","spreadArgs","disposer","reflectedResources","resultPromise","inspections","_disposer","36","tryCatcher","tryCatchTarget","isPrimitive","maybeError","safeToString","appendee","defaultValue","hasMethods","hasMethodsOtherThanConstructor","hasThisAssignmentAndStaticMethods","thisAssignmentPattern","FakeConstructor","rident","filledRange","isError","ignore","hasEnvVariables","globalObject","Child","Parent","excludedPrototypes","Function","isExcludedProto","visitedKeys","enumeration","Symbol","ArrayFrom","itResult","it","chrome","loadTimes","versions","Number","P","root","factory","returnExports","options_onResponse","onResponse","verbose","getLogger","unsupported_options","DEFAULT_TIMEOUT","accept","serialize","encoding","multi","boundry","noop","authorization","b64_enc","run_xhr","too_late","timed_out","er","duration","_id","milliseconds","on_state_change","XHR","OPENED","HEADERS_RECEIVED","on_response","LOADING","on_loading","on_end","did","timeoutTimer","is_cors","cors_err","loading","is_crossDomain","supports_cors","req_seq","seq_id","logger","levels","formatted","formatted_logger","ajaxLocation","rurl","location","href","ajaxLocParts","exec","o1","o2","o3","h1","h2","h3","h4","bits","b64","ac","enc","tmp_arr","charCodeAt","defaults","requester","de","post","head","shortcut","couch","couch_handler","parameters","TYPE_REGEXP","param","TOKEN_REGEXP","qstring","header","getcontenttype","trim","ContentType","PARAM_REGEXP","QESC_REGEXP","getHeader","TEXT_REGEXP","QUOTE_REGEXP","core","$JSON","assign","$Object","D","setPrototypeOf","Set","forbiddenField","forOf","iter","ITERATOR","toIObject","toLength","toAbsoluteIndex","IS_INCLUDES","$this","fromIndex","IObject","toObject","asc","TYPE","$create","IS_MAP","IS_FILTER","IS_SOME","IS_EVERY","IS_FIND_INDEX","NO_HOLES","callbackfn","that","SPECIES","original","C","speciesConstructor","cof","TAG","ARG","tryGet","B","callee","dP","redefineAll","anInstance","$iterDefine","step","setSpecies","DESCRIPTORS","fastKey","validate","SIZE","getEntry","entry","_f","getConstructor","NAME","ADDER","iterable","_t","_l","clear","setStrong","iterated","_k","classof","$export","meta","fails","hide","setToStringTag","common","IS_WEAK","Base","_c","KEY","IS_ADDER","NEED","G","W","F","__e","aFunction","gOPS","pIE","getSymbols","symbols","isEnum","own","out","IS_FORCED","IS_GLOBAL","IS_STATIC","S","IS_PROTO","IS_BIND","IS_WRAP","expProto","virtual","R","U","isArrayIter","anObject","getIterFn","BREAK","RETURN","iterFn","__g","createDesc","documentElement","propertyIsEnumerable","Iterators","ArrayProto","IteratorPrototype","LIBRARY","redefine","$iterCreate","BUGGY","returnThis","DEFAULT","IS_SET","FORCED","getMethod","DEF_VALUES","VALUES_BUG","$native","$default","$entries","$anyNative","META","setDesc","isExtensible","FREEZE","preventExtensions","setMeta","getWeak","onFreeze","$assign","K","aLen","dPs","enumBugKeys","IE_PROTO","Empty","createDict","iframeDocument","iframe","style","display","appendChild","contentWindow","lt","IE8_DOM_DEFINE","toPrimitive","Attributes","gOPD","gOPN","windowNames","getWindowNames","$keys","hiddenKeys","getOwnPropertySymbols","ObjectProto","arrayIndexOf","exp","bitmap","safe","COLLECTION","mapping","mapFn","nextItem","of","buggy","tag","stat","shared","uid","toInteger","defined","TO_STRING","pos","valueOf","px","wksExt","$Symbol","USE_SYMBOL","getIteratorMethod","getIterator","isIterable","addToUnscopables","Arguments","$getPrototypeOf","strong","$at","point","$fails","wks","wksDefine","enumKeys","gOPNExt","$GOPD","$DP","_stringify","HIDDEN","TO_PRIMITIVE","SymbolRegistry","AllSymbols","OPSymbols","USE_NATIVE","QObject","setter","findChild","setSymbolDesc","protoDesc","sym","isSymbol","$defineProperty","$defineProperties","$propertyIsEnumerable","E","$getOwnPropertyDescriptor","$getOwnPropertyNames","$getOwnPropertySymbols","IS_OP","$set","es6Symbols","wellKnownSymbols","for","keyFor","useSetter","useSimple","replacer","$replacer","TO_STRING_TAG","DOMIterables","Collection","_maxListeners","isNumber","isUndefined","defaultMaxListeners","setMaxListeners","addListener","listener","newListener","warned","g","fired","list","position","listenerCount","evlistener","emitter","defaultSetTimout","defaultClearTimeout","runTimeout","cachedSetTimeout","runClearTimeout","marker","cachedClearTimeout","cleanUpNextTick","draining","currentQueue","queueIndex","drainQueue","run","Item","browser","argv","off","prependListener","prependOnceListener","binding","cwd","chdir","umask","mapDomain","regexSeparators","ucs2decode","extra","output","counter","ucs2encode","stringFromCharCode","basicToDigit","codePoint","digitToBasic","digit","flag","adapt","numPoints","firstTime","damp","baseMinusTMin","tMax","skew","decode","basic","oldi","baseMinusT","inputLength","initialN","bias","initialBias","lastIndexOf","delimiter","maxInt","tMin","encode","handledCPCount","basicLength","q","currentValue","handledCPCountPlusOne","qMinusT","toUnicode","regexPunycode","toASCII","regexNonASCII","freeExports","nodeType","freeModule","freeGlobal","punycode","overflow","not-basic","invalid-input","ucs2","eq","regexp","maxKeys","kstr","vstr","decodeURIComponent","xs","stringifyPrimitive","objectKeys","ks","hadRuntime","regeneratorRuntime","oldRuntime","innerFn","outerFn","tryLocsList","protoGenerator","Generator","_invoke","makeInvokeMethod","GeneratorFunction","GeneratorFunctionPrototype","defineIteratorMethods","AsyncIterator","record","__await","unwrapped","enqueue","callInvokeWithMethodAndArg","previousPromise","GenStateSuspendedStart","GenStateExecuting","GenStateCompleted","doneResult","delegate","delegateResult","maybeInvokeDelegate","ContinueSentinel","_sent","dispatchException","GenStateSuspendedYield","resultName","nextLoc","pushTryEntry","locs","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","reset","iteratorMethod","iteratorSymbol","Op","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","inModule","runtime","getProto","NativeIteratorPrototype","Gp","isGeneratorFunction","genFun","awrap","skipTempReset","rootEntry","rootRecord","rval","exception","loc","hasCatch","hasFinally","finallyEntry","complete","thrown","delegateYield","Url","slashes","port","hostname","hash","pathname","urlParse","parseQueryString","slashesDenoteHost","urlFormat","isString","urlResolve","relative","urlResolveObject","resolveObject","protocolPattern","portPattern","simplePathPattern","delims","unwise","autoEscape","nonHostChars","hostEndingChars","hostnamePartPattern","hostnamePartStart","unsafeProtocol","javascript","javascript:","hostlessProtocol","slashedProtocol","http","https","ftp","gopher","http:","https:","ftp:","gopher:","file:","querystring","queryIndex","splitter","uSplit","slashRegex","rest","simplePath","lowerProto","hostEnd","hec","atSign","parseHost","ipv6Hostname","hostparts","part","newpart","validParts","notHost","bit","unshift","h","ae","esc","escape","qm","rel","tkeys","tk","tkey","rkeys","rk","rkey","relPath","isSourceAbs","isRelAbs","mustEndAbs","removeAllDots","srcPath","psychotic","isNullOrUndefined","authInHost","isNull","hasTrailingSlash","up","isAbsolute"],"mappings":"CAAA,QAAAA,GAAAC,EAAAC,EAAAC,GAAA,QAAAC,GAAAC,EAAAC,GAAA,IAAAJ,EAAAG,GAAA,CAAA,IAAAJ,EAAAI,GAAA,CAAA,GAAAE,GAAA,kBAAAC,UAAAA,OAAA,KAAAF,GAAAC,EAAA,MAAAA,GAAAF,GAAA,EAAA,IAAAI,EAAA,MAAAA,GAAAJ,GAAA,EAAA,IAAAK,GAAA,GAAAC,OAAA,uBAAAN,EAAA,IAAA,MAAAK,GAAAE,KAAA,mBAAAF,EAAA,GAAAG,GAAAX,EAAAG,IAAAS,WAAAb,GAAAI,GAAA,GAAAU,KAAAF,EAAAC,QAAA,SAAAd,GAAA,GAAAE,GAAAD,EAAAI,GAAA,GAAAL,EAAA,OAAAI,GAAAF,GAAAF,IAAAa,EAAAA,EAAAC,QAAAd,EAAAC,EAAAC,EAAAC,GAAA,MAAAD,GAAAG,GAAAS,QAAA,IAAA,GAAAL,GAAA,kBAAAD,UAAAA,QAAAH,EAAA,EAAAA,EAAAF,EAAAa,OAAAX,IAAAD,EAAAD,EAAAE,GAAA,OAAAD,KAAAa,GAAA,SAAAT,EAAAU,EAAAJ,gBCAA,GAAAK,GAAAX,EAAA,eACAW,GAAAC,QAAAZ,EAAA,mBAIA,IAAAa,EACA,KACAA,EAAAC,EAAAD,UACA,MAAArB,IAGAqB,GACAF,EAAAI,sBACA,WACA,MAAA,IAAAJ,GAAAK,qBACAH,EAAA,0BAMAH,EAAAJ,QAAAK,EACAG,EAAAH,SAAAA,2bCAqBM,aACjB,QAAAA,GAAYC,IAAQ,EAAAC,EAAAC,SAAAC,KAAAJ,GAChBI,KAAKH,OAASA,EAIdG,KAAKC,2EAGIC,GAAoB,IAAA,GAAAC,GAAAC,EAAAC,UAAAlB,OAANmB,EAAMC,MAAAH,EAAA,EAAAA,EAAA,EAAA,GAAAI,EAAA,EAAAA,EAAAJ,EAAAI,IAANF,EAAME,EAAA,GAAAH,UAAAG,IAC7BL,EAAAH,KAAKH,QAAOY,KAAZC,MAAAP,GAAiBD,GAAjBS,OAA+BL,mCAG5BM,EAAQC,GAAY,GAAAC,IAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KACvB,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,SAAwBc,KAAxBC,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAAoC,CAAA,GAAzBZ,GAAyBgB,EAAAK,UACMN,KAAlCjB,KAAKC,cAAcC,KACnBF,KAAKC,cAAcC,GAAaF,KAAKwB,aAAaC,KAAKzB,KAAME,GAEjE,IAAMwB,GAAe1B,KAAKC,cAAcC,EAExCU,GAAOe,GAAGzB,EAAWwB,IAPF,MAAAE,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,wBAbVpB,kJCNrB,gEA2CA,QAASkC,GAAeC,GACpBC,EAAMC,mBAAmBF,GAAO,UAAW,YAE3C/B,KAAKkC,QAAUH,EAAKG,QACpBlC,KAAKmC,UAAYJ,EAAKI,SAEtB,IAAMC,IACFF,QAASH,EAAKG,QACdC,UAAWJ,EAAKI,UAChBE,YAAaN,EAAKM,YAClB9C,QAASwC,EAAKxC,QACd+C,OAAQC,EAAQC,UAChBC,UAAU,EACVC,YAAaX,EAAKY,YAClBC,eAAgBb,EAAKa,eACrBC,uBAAwBd,EAAKc,uBAEjC7C,MAAK8C,MAAQ,GAAIP,GAAQQ,cAAc/C,KAAMoC,GAE7CpC,KAAKgD,QAAU,iGArDbT,EAAU5D,EAAQ,cAClBqD,EAAQrD,EAAQ,UA2DtBmD,GAAemB,UAAUC,iBAAmB,WACxC,MAAOlD,MAAKkC,SAOhBJ,EAAemB,UAAUE,qBAAuB,WAC5C,MAAOnD,MAAKmC,WAOhBL,EAAemB,UAAUG,eAAiB,WACtC,MAAOpD,MAAK8C,MAAMf,KAAKM,aAAe,MAM1CP,EAAemB,UAAUI,WAAa,WAClC,WAAuCpC,KAAhCjB,KAAK8C,MAAMf,KAAKM,aAQ3BP,EAAemB,UAAUK,UAAY,WACjC,MAAO,KAAM,GAAIC,OAAOC,UAAY,IAAOxD,KAAKgD,WAapDlB,EAAemB,UAAUQ,oBAAsB,SAASC,GACpD,MAAO1D,MAAK8C,MAAMa,kBACd1C,GAAW,MAAO,uBAAyByC,SAAUA,IACvDE,KAAK,SAACC,GACJ,MAAOA,GAASC,aAiBxBhC,EAAemB,UAAUc,SAAW,SAChCL,EAAUM,EACVC,EAAWC,EAAMC,EAAeC,EAChCC,IAGsB,IAAlBF,EACAA,GAAiBG,OAAO,GACC,OAAlBH,OAA4ClD,KAAlBkD,IACjCA,UAGSlD,KAATiD,GAA+B,OAATA,IACtBA,MAEAD,IACAC,EAAKK,QAAUN,EAGnB,IAAMO,IACFN,KAAMA,EA2BV,YAzBiBjD,KAAbyC,GAAuC,OAAbA,IAC1Bc,EAAOd,SAAWA,OAELzC,KAAb+C,GAAuC,OAAbA,IAC1BQ,EAAOR,SAAWA,GAElBG,EAAcG,QACdE,EAAOC,YAAa,GAEpBN,EAAcO,SACdF,EAAOG,aAAc,OAEA1D,KAArBmD,GAAuD,OAArBA,IAClCI,EAAOI,mBAAqBR,OAQfnD,KAAb+C,GAAuC,OAAbA,IAC1BQ,EAAOK,eAAgB,GAGpB7E,KAAK8E,gBAAgBN,MAAQvD,GAAWoD,IAWnDvC,EAAemB,UAAU8B,cAAgB,SAAShD,EAAMsC,GAGpD,MAFAtC,GAAOA,MACPA,EAAKiD,KAAOjD,EAAKiD,SACVhF,KAAK8E,gBAAgB/C,EAAKiD,KAAM,QAASX,IAUpDvC,EAAemB,UAAU6B,gBAAkB,SAASG,EAAMC,EAAMb,GAC5D,GAAMG,KAKN,OAJIU,KACAV,EAAOU,KAAOA,GAGXlF,KAAK8C,MAAMvD,QACd8E,EAAU,OAAQ,YAAaG,EAAQS,IAS/CnD,EAAemB,UAAUkC,WAAa,SAASd,GAC3C,MAAOrE,MAAK8C,MAAMvD,QAAQ8E,EAAU,MAAO,WAU/CvC,EAAemB,UAAUmC,MAAQ,SAASC,EAAWJ,EAAMZ,GACvD,GAAMiB,IACFC,KAAMF,EAMV,OAFArD,GAAMwD,OAAOF,EAAYL,GAElBjF,KAAK8C,MAAMa,cACdU,EAAU,OAAQ,aAAUpD,GAAWqE,IAW/CxD,EAAemB,UAAUwC,kBAAoB,SAASC,EAAM1B,EAAUK,GAClE,MAAOrE,MAAKoF,MAAM,oBACdM,KAAMA,EACN1B,SAAUA,GACXK,IASPvC,EAAemB,UAAU0C,eAAiB,SAASC,EAAYvB,GAC3D,MAAOrE,MAAKoF,MAAM,iBACdS,YAAaD,GACdvB,IAQPvC,EAAemB,UAAU6C,eAAiB,SAASC,GAC/C,MAAO/F,MAAK8C,MAAMkD,OAAO,uBACrBD,YAAeA,GAChBxD,EAAQ0D,kBASfnE,EAAemB,UAAUiD,eAAiB,SAASC,EAAO9B,GACtD,MAAOrE,MAAKoF,MAAM,iBACde,MAAOA,GACR9B,IAaPvC,EAAemB,UAAUmD,OAAS,SAAS/B,GACvC,MAAOrE,MAAK8C,MAAMa,cACdU,EAAU,OAAQ,YAc1BvC,EAAemB,UAAUoD,kBAAoB,SAASnC,EAAMG,GACxD,GAAIW,KAMJ,OALId,KACAc,GACId,KAAMA,IAGPlE,KAAK8C,MAAMwD,wBACdjC,EAAU,OAAQ,0BAAuBpD,GAAW+D,EAAMzC,EAAQ0D,kBAY1EnE,EAAemB,UAAUsD,mBAAqB,SAASlB,EAAWmB,GAC9D,GAAMC,GAAOzE,EAAM0E,UAAU,iCACzBC,WAAYtB,GAGhB,OAAOrF,MAAK8C,MAAMkD,OAAOS,GACrBlC,QAASiC,GACVjE,EAAQC,YAoBfV,EAAemB,UAAU2D,WAAa,SAASC,EAASxC,GAEpD,MAAOrE,MAAK8C,MAAMa,cACdU,EAAU,OAAQ,kBAAepD,GAAW4F,IAUpD/E,EAAemB,UAAU6D,UAAY,SAASC,EAAQ1C,GAClD,GAAMoC,GAAOzE,EAAM0E,UAAU,wBAAyBM,QAASD,GAC/D,OAAO/G,MAAK8C,MAAMa,cAAcU,EAAU,MAAOoC,IAQrD3E,EAAemB,UAAUgE,gBAAkB,SAASC,GAChD,GAAMT,GAAOzE,EAAM0E,UAAU,4BAA6BS,SAAUD,GACpE,OAAOlH,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,IAQtD3E,EAAemB,UAAUmE,gBAAkB,SAASF,GAChD,GAAMT,GAAOzE,EAAM0E,UAAU,4BAA6BS,SAAUD,GACpE,OAAOlH,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,IAatD3E,EAAemB,UAAUoE,gBAAkB,SAASH,EAASI,GACzD,GAAMb,GAAOzE,EAAM0E,UAAU,4BAA6BS,SAAUD,GACpE,OAAOlH,MAAK8C,MAAMa,kBACd1C,GAAW,OAAQwF,MAAMxF,GAAWqG,IAS5CxF,EAAemB,UAAUsE,cAAgB,SAASL,GAC9C,GAAMT,GAAOzE,EAAM0E,UAAU,0BAA2BS,SAAUD,GAClE,OAAOlH,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,IAQtD3E,EAAemB,UAAUuE,qBAAuB,SAASN,GACrD,GAAMT,GAAOzE,EAAM0E,UAAU,kCAAmCS,SAAUD,GAC1E,OAAOlH,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,IAQtD3E,EAAemB,UAAUwE,cAAgB,SAASP,GAC9C,GAAMT,GAAOzE,EAAM0E,UAAU,0BAA2BS,SAAUD,GAClE,OAAOlH,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,IAStD3E,EAAemB,UAAUyE,kBAAoB,SAASR,EAASS,GAC3D,GAAMlB,GAAOzE,EAAM0E,UACf,+CACCS,SAAUD,EAASU,QAASD,GAEjC,OAAO3H,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,MAAMxF,QAS5Da,EAAemB,UAAU4E,oBAAsB,SAASX,EAASS,GAC7D,GAAMlB,GAAOzE,EAAM0E,UACf,+CACCS,SAAUD,EAASU,QAASD,GAEjC,OAAO3H,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,MAAMxF,QAU5Da,EAAemB,UAAU6E,sBAAwB,SAASZ,EAASS,EAAQI,GACvE,GAAMtB,GAAOzE,EAAM0E,UACfqB,EACI,iDACA,0CACHZ,SAAUD,EAASc,QAASD,EAAQH,QAASD,GAElD,OAAO3H,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,MAAMxF,QAS5Da,EAAemB,UAAUgF,2BAA6B,SAASf,EAASS,GACpE,GAAMlB,GAAOzE,EAAM0E,UACf,0CACCS,SAAUD,EAASU,QAASD,GAEjC,OAAO3H,MAAK8C,MAAMa,kBAAc1C,GAAW,SAAUwF,MAAMxF,QAU/Da,EAAemB,UAAUiF,sBAAwB,SAAShB,EAASH,EAAQoB,GACvE,GAAM1B,GAAOzE,EAAM0E,UACfyB,EACI,qDACA,0CACHhB,SAAUD,EAASkB,YAAaD,EAAYnB,QAASD,GAE1D,OAAO/G,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,MAAMxF,QAS5Da,EAAemB,UAAUoF,2BAA6B,SAASnB,EAASH,GACpE,GAAMN,GAAOzE,EAAM0E,UACf,0CACCS,SAAUD,EAASF,QAASD,GAEjC,OAAO/G,MAAK8C,MAAMa,kBAAc1C,GAAW,SAAUwF,MAAMxF,QAU/Da,EAAemB,UAAUqF,eAAiB,SAASpB,EAASH,EAAQwB,OAC/CtH,KAAbsH,IACAA,GAAW,EAEf,IAAM9B,GAAOzE,EAAM0E,UACf,wCACCS,SAAUD,EAASF,QAASD,GAEjC,OAAO/G,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,MAAMxF,IAClDuH,YAAcjD,KAAMgD,EAAW,SAAW,cAYpDzG,EAAemB,UAAUwF,0BAA4B,SAASvB,EAASH,EAAQwB,GAK3E,GAAM9B,GAAOzE,EAAM0E,UACf,4DACCS,SAAUD,EAASF,QAASD,GAEjC,OAAO/G,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,MAAMxF,IAClDsE,KAAMgD,EAAW,SAAW,aAUtCzG,EAAemB,UAAUyF,oBAAsB,SAASxB,EAASH,GAC7D,GAAMN,GAAOzE,EAAM0E,UACf,wCACCS,SAAUD,EAASF,QAASD,GAEjC,OAAO/G,MAAK8C,MAAMa,kBAAc1C,GAAW,SAAUwF,MAAMxF,QAQ/Da,EAAemB,UAAU0F,kBAAoB,SAASzB,GAClD,GAAMT,GAAOzE,EAAM0E,UACf,uCACCS,SAAUD,GAEf,OAAOlH,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,MAAMxF,QAQ5Da,EAAemB,UAAU2F,WAAa,SAAS1B,GAC3C,GAAMT,GAAOzE,EAAM0E,UACf,+BACCS,SAAUD,GAEf,OAAOlH,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,MAAMxF,QAO5Da,EAAemB,UAAU4F,gBAAkB,WACvC,GAAMpC,GAAOzE,EAAM0E,UAAU,iBAC7B,OAAO1G,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,IAUtD3E,EAAemB,UAAU6F,YAAc,SAASC,GAC5C,GAAMtC,GAAOzE,EAAM0E,UAAU,gBAC7B,OAAO1G,MAAK8C,MAAMa,kBACd1C,GAAW,OAAQwF,MAAMxF,GAAW8H,IAiB5CjH,EAAemB,UAAU+F,oBAAsB,SAASC,GACpD,GAAMxC,GAAOzE,EAAM0E,UAAU,qBAC7B,OAAO1G,MAAK8C,MAAMa,kBACd1C,GAAW,OAAQwF,MAAMxF,IAAaiI,SAAUD,KAUxDnH,EAAemB,UAAUkG,kBAAoB,SAASjC,EAASqB,GAC3D,GAAM9B,GAAOzE,EAAM0E,UACf,0CACCS,SAAUD,GAEf,OAAOlH,MAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,MAAMxF,IACpDmI,UAAWb,KAanBzG,EAAemB,UAAUoG,cAAgB,SAAStC,EAAQuC,EAAWC,EAAUlF,GAC3E,GAAMmF,IACFxC,QAASD,EACT0C,WAAYH,EACZI,UAAWH,GAEX9C,EAAOzE,EAAM0E,UAAU,kCAAmC8C,EAI9D,YAHiBvI,KAAbsI,IACA9C,EAAOzE,EAAM0E,UAAUD,EAAO,aAAc+C,IAEzCxJ,KAAK8C,MAAMa,cACdU,EAAU,MAAOoC,IAazB3E,EAAemB,UAAU0G,eAAiB,SAAS5C,EAAQuC,EAAWP,EAASQ,EAC9BlF,GAC7C,GAAMmF,IACFxC,QAASD,EACT0C,WAAYH,EACZI,UAAWH,GAEX9C,EAAOzE,EAAM0E,UAAU,kCAAmC8C,EAI9D,YAHiBvI,KAAbsI,IACA9C,EAAOzE,EAAM0E,UAAUD,EAAO,aAAc+C,IAEzCxJ,KAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAW8H,IAW1CjH,EAAemB,UAAU2G,YAAc,SAAS7C,EAAQ8C,EAASxF,GAC7D,GAAMoC,GAAOzE,EAAM0E,UAAU,kCACzBM,QAASD,EACT+C,SAAUD,GAEd,OAAO7J,MAAK8C,MAAMa,cAAcU,EAAU,OAAQoC,MAAMxF,QAU5Da,EAAemB,UAAU8G,gBAAkB,SAAShD,EAAQiD,EAAO3F,GAC3DrC,EAAMiI,WAAWD,KACjB3F,EAAW2F,EAAOA,MAAQ/I,GAE9B,IAAMwF,GAAOzE,EAAM0E,UAAU,8BACxBM,QAASD,GAKd,OAHKiD,KACDA,EAAQ,IAELhK,KAAK8C,MAAMa,cACdU,EAAU,MAAOoC,GAAQuD,MAAOA,KAgBxClI,EAAemB,UAAUiH,8BACO,SAASnD,EAAQoD,EAAWC,GACxD,GAAM3D,GAAOzE,EAAM0E,UAAU,+BACzBM,QAASD,IAGPgC,GACFsB,eAAgBF,EAChBG,SAAUF,EAGd,OAAOpK,MAAK8C,MAAMa,kBACd1C,GAAW,OAAQwF,MAAMxF,GAAW8H,IAqB5CjH,EAAemB,UAAUsH,YAAc,SAAS1D,EAASxC,GAC9B,kBAAZwC,KACPxC,EAAWwC,EACXA,UAEY5F,KAAZ4F,IACAA,KAGJ,IAAM2D,KAMN,OALI3D,GAAQ4D,SACRD,EAAaC,OAAS5D,EAAQ4D,aACvB5D,GAAQ4D,QAGiB,KAAhC,EAAAC,EAAA3K,SAAY8G,GAAS1H,QAAqD,KAArC,EAAAuL,EAAA3K,SAAYyK,GAAcrL,OACxDa,KAAK8C,MAAMa,cAAcU,EAAU,MAAO,gBAE1CrE,KAAK8C,MAAMa,cACdU,EAAU,OAAQ,eAAgBmG,EAAc3D,IAa5D/E,EAAemB,UAAU0H,YAAc,SAASC,EAAO7D,EAAQ1C,GAC3D,GAAMoC,GAAOzE,EAAM0E,UAAU,0BACzBmE,OAAQD,IAEN3F,GACF6F,QAAS/D,EAEb,OAAO/G,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAWgE,IAY1CnD,EAAemB,UAAU8H,YAAc,SAASH,EAAOvG,GACnD,GAAMoC,GAAOzE,EAAM0E,UAAU,0BACzBmE,OAAQD,GAEZ,OAAO5K,MAAK8C,MAAMa,cACdU,EAAU,SAAUoC,MAAMxF,OAAWA,KAW7Ca,EAAemB,UAAU+H,kBAAoB,SAASJ,EAAOvG,GAEzD,GAAMoC,GAAOzE,EAAM0E,UAAU,0BACzBmE,OAAQD,GAEZ,OAAO5K,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,IAUzB3E,EAAemB,UAAUgI,iBAAmB,SAASC,EAAW7G,GAE5D,GAAMoC,GAAOzE,EAAM0E,UAAU,0BAA2BmE,OAAQK,GAChE,OAAOlL,MAAK8C,MAAMvD,QAAQ8E,EAAU,MAAOoC,IAU/C3E,EAAemB,UAAUkI,2BACO,SAASpE,EAAQ1C,GAC7C,GAAMoC,GAAOzE,EAAM0E,UAAU,gCACzBM,QAASD,GAEb,OAAO/G,MAAK8C,MAAMa,cAAcU,EAAU,MAAOoC,IAarD3E,EAAemB,UAAUmI,2BACO,SAASrE,EAAQyB,EAAYnE,GACzD,GAAMoC,GAAOzE,EAAM0E,UAAU,gCACzBM,QAASD,GAEb,OAAO/G,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,IAAauH,WAAcA,KAiB1D1G,EAAemB,UAAUoI,qCACO,SAASC,EAAWvE,EAAQyB,EAAYnE,GACpE,GAAMoC,GAAOzE,EAAM0E,UAAU,iDACzB6E,WAAYD,EACZtE,QAASD,GAEb,OAAO/G,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,IAAauH,WAAcA,KAe1D1G,EAAemB,UAAUuI,oBAAsB,SAASzJ,GACpD,GAAMiD,IACFyG,YAAa1J,EAAK2J,KAOtB,YAJmBzK,KAAfc,EAAKiI,QACLhF,EAAKgF,MAAQjI,EAAKiI,OAGfhK,KAAK8C,MAAMa,kBACd1C,GAAW,OAAQ,6BAA0BA,GAAW+D,IA4ChElD,EAAemB,UAAU0I,cAAgB,SAASC,EAAM7J,GACpD,MAAO/B,MAAK8C,MAAM6I,cAAcC,EAAM7J,IAQ1CD,EAAemB,UAAU4I,aAAe,SAASC,GAC7C,MAAO9L,MAAK8C,MAAM+I,aAAaC,IAWnChK,EAAemB,UAAU8I,kBAAoB,WACzC,MAAO/L,MAAK8C,MAAMiJ,qBAetBjK,EAAemB,UAAU+I,eAAiB,SAASrE,EAAQsE,EAAM5H,GACzDrC,EAAMiI,WAAWgC,KACjB5H,EAAW4H,EAAMA,MAAOhL,GAG5B,IAAMwF,GAAOwF,EACbjK,EAAM0E,UAAU,0BACLkB,QAASD,EAAQuE,MAAOD,IACnCjK,EAAM0E,UAAU,oBACLkB,QAASD,GACpB,OAAO3H,MAAK8C,MAAMa,cAAcU,EAAU,MAAOoC,IAYrD3E,EAAemB,UAAUkJ,aAAe,SAAS9H,GAE7C,MAAOrE,MAAK8C,MAAMa,cACdU,EAAU,MAFD,oBAEcpD,OAAWA,KAW1Ca,EAAemB,UAAUmJ,YAAc,SAASC,EAAO5K,EAAM4C,GACzD,GACMY,IACFqH,cAAiBD,EACjB5K,KAAQA,EAEZ,OAAOzB,MAAK8C,MAAMa,cACdU,EAAU,OAND,gBAMe,KAAMY,IAYtCnD,EAAemB,UAAUsJ,eAAiB,SAASC,EAAQC,GACvD,GACMxH,IACFuH,OAAUA,EACVC,QAAWA,EAEf,OAAOzM,MAAK8C,MAAMwD,4BACdrF,GAAW,OANF,uBAMgB,KAAMgE,EAAM1C,EAAQ0D,kBAYrDnE,EAAemB,UAAUyJ,YAAc,SAASC,EAAUC,EAAavI,GACnE,GACMY,IACFf,KAAQyI,EACRE,aAAgBD,EAGpB,OAAO5M,MAAK8C,MAAMa,cACdU,EAAU,OAPD,oBAOe,KAAMY,IAatCnD,EAAemB,UAAU6J,WAAa,WAElC,MAAO9M,MAAK8C,MAAMwD,4BACdrF,GAAW,MAFF,eAEeA,OAAWA,GACnCsB,EAAQ0D,kBAYhBnE,EAAemB,UAAU8J,iBAAmB,SAASC,EAAWhI,GAC5D,GAAMyB,GAAOzE,EAAM0E,UAAU,uBACzBuG,WAAYD,GAIhB,OAAOhN,MAAK8C,MAAMwD,4BACdrF,GAAW,MAAOwF,MAAMxF,GAAW+D,EACnCzC,EAAQ0D,kBAYhBnE,EAAemB,UAAUiK,aAAe,SAASF,EAAW9I,GACxD,GAAMuC,GAAOzE,EAAM0E,UAAU,uBACzBuG,WAAYD,IAGVhI,IAMN,OAJId,KACAc,EAAKd,KAAOA,GAGTlE,KAAK8C,MAAMwD,4BACdrF,GAAW,SAAUwF,MAAMxF,GAAW+D,EACtCzC,EAAQ0D,kBAehBnE,EAAemB,UAAUkK,WAAa,SAAS9I,GAE3C,MAAOrE,MAAK8C,MAAMa,cACdU,EAAU,MAFD,eAEcpD,OAAWA,KAY1Ca,EAAemB,UAAUmK,UAAY,SAASC,EAAQhJ,GAElD,MAAOrE,MAAK8C,MAAMa,cACdU,EAAU,OAFD,eAEe,KAAMgJ,IAStCvL,EAAemB,UAAUqK,aAAe,SAASjJ,GAC7C,MAAOrE,MAAK8C,MAAMa,cAAcU,EAAU,MAAO,gBAYrDvC,EAAemB,UAAUsK,YAAc,SAASC,EAAOtI,EAAMuI,EAAQzI,EAAMX,GAEvE,GAAMoC,GAAOzE,EAAM0E,UAAU,cAAgB8G,EAAQ,kBACjDE,MAAOxI,EACPyI,QAASF,GAEb,OAAOzN,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAW+D,IAY1ClD,EAAemB,UAAU2K,eAAiB,SAASJ,EAAOtI,EAAMuI,EAAQpJ,GAEpE,GAAMoC,GAAOzE,EAAM0E,UAAU,cAAgB8G,EAAQ,kBACjDE,MAAOxI,EACPyI,QAASF,GAEb,OAAOzN,MAAK8C,MAAMa,cAAcU,EAAU,SAAUoC,IAaxD3E,EAAemB,UAAU4K,mBAAqB,SAASL,EAAOtI,EACTuI,EAAQK,EAASzJ,GAClE,GAAMoC,GAAOzE,EAAM0E,UAAU,cAAgB8G,EAAQ,0BACjDE,MAAOxI,EACPyI,QAASF,GAEb,OAAOzN,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,IAAY6M,QAAWA,KActDhM,EAAemB,UAAU8K,mBAAqB,SAASP,EAAOtI,EACTuI,EAAQO,EAAS3J,GAClE,GAAMoC,GAAOzE,EAAM0E,UAAU,cAAgB8G,EAAQ,0BACjDE,MAAOxI,EACPyI,QAASF,GAEb,OAAOzN,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,IAAY+M,QAAWA,KAiBtDlM,EAAemB,UAAUgL,OAAS,SAASlM,EAAMsC,GAC7C,GAAM6J,KAIN,OAHInM,GAAKoM,aACLD,EAAYC,WAAapM,EAAKoM,YAE3BnO,KAAK8C,MAAMa,cACdU,EAAU,OAAQ,UAAW6J,EAAanM,EAAKiD,OAsBvDlD,EAAemB,UAAUmL,kBAAoB,SAASrF,EAAShH,EAAMsC,GACjEtC,EAAOA,KACP,IAAMsM,GAAWtM,EAAKiL,UAClBvG,MAAA,EAQJ,OANIA,GADA4H,EACOrM,EAAM0E,UAAU,0BACnB4H,UAAWD,IAGR,eAEJrO,KAAK8C,MAAMwD,wBACdjC,EAAU,OAAQoC,MAAMxF,GAAW8H,EAASxG,EAAQ0D,kBAiB5DnE,EAAemB,UAAUsL,qBAAuB,SAAStF,EAASlH,GAC9D,GAAIC,EAAMiI,WAAWlI,GAEjB,KAAM,IAAIjD,OACN,8DAGRiD,GAAOA,KAEP,IAAMgH,IACFyF,eASJ,OAPI,SAAWzM,KACXgH,EAAQ5C,MAAQpE,EAAKoE,OAEzB8C,EAAQwF,QAAQ,SAAChQ,GACbsK,EAAQyF,YAAY/P,QAGjBuB,KAAK8C,MAAMwD,4BACdrF,GAAW,OAAQ,kBAAeA,GAAW8H,EAC7CxG,EAAQ0D,kBAchBnE,EAAemB,UAAUyL,iBAAmB,SAASC,EAASC,GAC1D,GAAMC,UAEgB5N,KAAlB2N,IACAA,EAAgB,oBAGpB,KAAK,GAAIhQ,GAAI,EAAGA,EAAI+P,EAAQxP,SAAUP,EAAG,CACrC,GAAM+I,GAASgH,EAAQ/P,GAAG,GACpByP,EAAWM,EAAQ/P,GAAG,GACtBkQ,EAAQD,EAAQlH,MACtBkH,GAAQlH,GAAUmH,EAClBA,EAAMT,GAAYO,EAEtB,GAAM7F,IAAWgG,cAAeF,EAChC,OAAO7O,MAAK8C,MAAMwD,4BACdrF,GAAW,OAAQ,kBAAeA,GAAW8H,EAC7CxG,EAAQ0D,kBAchBnE,EAAemB,UAAU+L,cAAgB,SAASC,EAAUC,GACxD,GAAMC,IACFC,KAAMH,EACNI,GAAIH,EAGR,OAAOlP,MAAK8C,MAAMwD,4BACdrF,GAAW,MAAO,gBAAiBkO,MAAKlO,GACxCsB,EAAQ0D,kBA4BhBnE,EAAemB,UAAUqM,kBAAoB,SAAShL,EAAOiL,EACTC,EAAaC,EAAUpL,GACvE,GAAMG,IACFkL,cAAeH,EACfjL,MAAOA,EACPqL,aAAcH,EACdI,UAAWH,EAEf,OAAOzP,MAAK8C,MAAM+M,gBACdxL,EAAU,OAAQ,+BAClBG,EAAQjC,EAAQuN,qBAqBxBhO,EAAemB,UAAU8M,kBAAoB,SAASC,EAAKT,EAAcpJ,GACrE,GAAM3B,IACFwL,IAAKA,EACLN,cAAeH,EACfpJ,MAAOA,EAEX,OAAOnG,MAAK8C,MAAM+M,oBACd5O,GAAW,OAAQ,+BACnBuD,EAAQjC,EAAQuN,qBAexBhO,EAAemB,UAAUgN,eAAiB,SAASzD,EAAQC,EAASpI,GAChE,GAAMG,IACFgI,OAAQA,EACRC,QAASA,EAEb,OAAOzM,MAAK8C,MAAM+M,gBACdxL,EAAU,MAAO,UACjBG,EAAQjC,EAAQuN,qBAkBxBhO,EAAemB,UAAUiN,aAAe,SACpC5G,EAAW6G,EAAYC,GAEvB,GAAM3J,GAAOzE,EAAM0E,UAAU,mCACzB+C,WAAYH,EACZ+G,OAAQD,GAAgBpQ,KAAKsD,cAG3B0B,GACFsL,SAAUH,EAGd,OAAOnQ,MAAK8C,MAAMwD,4BACdrF,GAAW,MAAOwF,MAAMxF,GAAW+D,EACnCzC,EAAQ0D,kBAYhBnE,EAAemB,UAAUsN,uBAAyB,WAC9C,MAAOvQ,MAAK8C,MAAMwD,4BACdrF,GAAW,MAAO,4BAAyBA,OAAWA,GACtDsB,EAAQ0D,iBACVrC,KAAK,SAACC,GAEJ,IAAKA,GAAiC,gBAArB,KAAOA,EAAP,aAAA,EAAA2M,EAAAzQ,SAAO8D,IACpB,KAAM,IAAI/E,OAAJ,mDACiD+E,EAG3D,OAAOA,MAYf/B,EAAemB,UAAUwN,sBAAwB,SAASC,EAAUlM,GAChE,GAAMiC,GAAOzE,EAAM0E,UAAU,kCACzBiK,UAAWD,GAGf,OAAO1Q,MAAK8C,MAAMwD,4BACdrF,GAAW,MAAOwF,EAAMjC,MAAQvD,GAChCsB,EAAQ0D,kBAOhB5G,EAAOJ,QAAU6C,4IClnDjB,gEAkGA,QAAS8O,GAAa7O,GAEdA,EAAKG,SAAWH,EAAKG,QAAQ2O,SAAS,OACtC9O,EAAKG,QAAUH,EAAKG,QAAQ4O,OAAO,EAAG/O,EAAKG,QAAQ/C,OAAS,IAI5D4C,EAAKI,WAAaJ,EAAKI,UAAU0O,SAAS,OAC1C9O,EAAKI,UAAYJ,EAAKI,UAAU2O,OAAO,EAAG/O,EAAKI,UAAUhD,OAAS,IAGtE2C,EAAe5C,KAAKc,KAAM+B,GAE1B/B,KAAK+Q,UAAY,GAAAC,GAAAjR,QAAcC,MAE/BA,KAAKiR,MAAQlP,EAAKkP,OAAS,GAAIC,GAE/BlR,KAAKqO,SAAWtM,EAAKsM,UAAY,IAEjC,IAAM1G,GAAU5F,EAAK4F,QAAU,IAM/B,IALA3H,KAAKmR,aACDxJ,OAAQA,GAGZ3H,KAAKoR,UAAYrP,EAAKqP,UAClBpR,KAAKoR,UAAW,CAChB,GAAMC,GAAOrR,IACbA,MAAKoR,UAAUE,mBAAmB,SAASC,GACvC,GAAMC,GAAOH,EAAKI,QAAQF,EAAYG,YAKtC,OAJIH,GAAYI,SAAWC,EAAYC,SACnCC,EAA0BN,EAAMD,EACNK,EAAYC,SAEnCE,EAAsBV,EAAME,KAG3CvR,KAAKgS,eAAgB,EAErBhS,KAAKiS,WAML,IAAM/S,GAAOgT,EAAWC,oBAAoBnS,KAC5CA,MAAKoS,eAAgB,EACjBlT,IACAmT,EAAsBrS,MACtBA,KAAKoS,eAAgB,GAEzBpS,KAAKsS,cAAgB,KACrBtS,KAAKuS,SAAW,KAChBvS,KAAKwS,UAAY,KACjBxS,KAAKyS,UAAW,EAChBzS,KAAK0S,uBACL1S,KAAK2S,gBAAkBC,QAAQ7Q,EAAK4Q,iBACpC3S,KAAK6S,mBACL7S,KAAK8S,kBAAoB,KAEzB9S,KAAK+S,QAAU,KACf/S,KAAKgT,aAAejR,EAAKkR,YACzBjT,KAAKkT,cAAgBnR,EAAKoR,aAE1BnT,KAAKoT,WAAarR,EAAKsR,YAAa,EAEhCC,IACAtT,KAAKuT,WAAaC,EAAOC,iBA+4BjC,QAASC,GAAWC,EAAQnC,EAAMoC,EAAOvP,GAIrC,MAAOwP,GAAA9T,QAAQ+T,UAAUlQ,KAAK,WAC1B,GAAMmQ,GAAoBC,EAAsBL,EAAQC,EAAOpC,EAE/D,OAAKuC,IAILjC,EAA0BN,EAAMoC,EAAOhC,EAAYqC,YAC5CF,EAAkBnQ,KAAK,WAC1BkO,EAA0BN,EAAMoC,EAAOhC,EAAYC,YAL5C,OAOZjO,KAAK,WACJ,GAAIkI,OAAA,EAkBJ,OAhBI6H,GAAOvC,YAKPtF,EAAU6H,EAAOvC,UAAU8C,WAAWN,KACvBD,EAAOvC,UAAU+C,iBAAiBP,GAAOzU,OAAS,GAG7D2S,EAA0BN,EAAMoC,EAAOhC,EAAYwC,QAItDtI,IACDA,EAAUiG,EAAsB4B,EAAQC,IAErC9H,IACRlI,KAAK,SAASyQ,GAOb,MANI7C,IACAA,EAAK8C,mBAAmBV,EAAOhC,EAAY2C,KAAMF,EAAIG,UAErDnQ,GACAA,EAAS,KAAMgQ,GAEZA,GACR,SAASzS,GAER6S,QAAQC,MAAM,sBAAuB9S,EAAI+S,OAAS/S,EAElD,KACIkQ,EAA0BN,EAAMoC,EAAOhC,EAAYgD,UACnDhB,EAAMc,MAAQ9S,EAEVyC,GACAA,EAASzC,GAEf,MAAOiT,GACLJ,QAAQC,MAAM,8BAA+BG,EAAKF,OAAS/S,GAE/D,KAAMA,KAkBd,QAASoS,GAAsBL,EAAQC,EAAOpC,GAC1C,GAAIoC,EAAMkB,cAIN,MAAO,KAGX,KAAKnB,EAAOoB,gBAAgBnB,EAAMlC,aAE9B,MAAO,KAGX,KAAKiC,EAAOZ,QACR,KAAM,IAAIjU,OACN,0FAKR,OAAO6U,GAAOZ,QAAQiC,aAAapB,EAAOpC,GAG9C,QAASM,GAA0BN,EAAMoC,EAAOqB,GACxCzD,EACAA,EAAK8C,mBAAmBV,EAAOqB,GAE/BrB,EAAMjC,OAASsD,EAIvB,QAASlD,GAAsB4B,EAAQC,GACnC,GAAMxD,GAAQwD,EAAMsB,OAAStB,EAAMsB,OAASvB,EAAOrQ,YAE7CkG,GACFxC,QAAS4M,EAAMlC,YACfjI,WAAYmK,EAAMuB,cAClBzL,UAAWkK,EAAMwB,cACjB/E,OAAQD,GAGR3J,MAAA,EAEJ,IAAImN,EAAMyB,UAAW,CACjB,GAAIC,GAAe,iCACf1B,GAAMwB,eAAiBxB,EAAMwB,cAAcjW,OAAS,IACpDmW,EAAe,6CAEnB7O,EAAOzE,EAAM0E,UAAU4O,EAAc9L,OAErC/C,GAAOzE,EAAM0E,UACT,wCAAyC8C,EAIjD,OAAOmK,GAAO7Q,MAAMa,kBAChB1C,GAAW,MAAOwF,MAAMxF,GAAW2S,EAAM2B,kBAC3C3R,KAAK,SAACyQ,GAIJ,MAHAI,SAAQe,IAAR,iBACqB5B,EAAMlC,YAD3B,kBACwD2C,EAAIG,UAErDH,IAsbf,QAASoB,GAAoB9B,EAAQ5M,EAAQY,EAAQ+N,EAAiBC,EACzCtR,GACrBrC,EAAMiI,WAAW0L,KACjBtR,EAAWsR,EAAQA,MAAS1U,GAGhC,IAAMwF,GAAOzE,EAAM0E,UACf,8CACEM,QAASD,EAAQa,QAASD,GAGhC,OAAOgM,GAAO7Q,MAAMa,cAAcU,EAAU,MAAOoC,MAAMxF,IACrD2U,WAAYF,EACZC,OAAQA,IAehB,QAASE,GAAkBlC,EAAQ5M,EAAQY,EAAQiO,EAAYD,EAAQtR,GAC/DrC,EAAMiI,WAAW0L,KACjBtR,EAAWsR,EAAQA,MAAS1U,GAGhC,IAAMwF,GAAOzE,EAAM0E,UAAU,+BACzBoP,SAAU/O,EACVgP,YAAaH,GAEjB,OAAOjC,GAAO7Q,MAAMa,cAChBU,EAAU,OAAQoC,MAAMxF,IACpB+U,QAASrO,EACTgO,OAAQA,IA8GpB,QAASM,GAAc5R,EAAUsP,EAAQ5R,EAAMmU,GAC7C,GAAMzP,GAAOzE,EAAM0E,UAAU,0BACzBkB,QAAS+L,EAAOxC,YAAYxJ,QAEhC,OAAOgM,GAAO7Q,MAAMa,cAAcU,EAAU6R,EAAQzP,MAAMxF,GAAWc,GAivCvE,QAASsQ,GAAsBsB,GAyC3B,QAASwC,GAAQvC,GACb,MAA2C,KAAvCA,EAAMwC,UAAUC,QAAQ,iBAEpBzC,EAAM0C,oBAAsB1C,EAAM2C,wBAElC3C,EAAM4C,KAAK,kBAAmBL,IAIjCM,MAILC,GAAiB9C,OAHb+C,GAAgBC,KAAKhD,GAM7B,QAAS8C,GAAiB9C,GACtB,GAAM7K,GAAU6K,EAAMiD,aAClB3X,EAAO6J,EAAQ+N,QAAUnD,EAAO1B,SAASlJ,EAAQ+N,aAAW7V,GAC5DrC,MAAA,EAGJ,IAAwB,kBAApBgV,EAAMwC,UAA+B,CACrC,GAAIxC,EAAMmD,cAAgBpD,EAAOxC,YAAYxJ,OACzC,MAGJ,IAAIiM,EAAMoD,SAAWjO,EAAQkO,SACzB,MAGJ,IAAI/X,GAAuB,UAAfA,EAAKgY,MACb,MAaJ,IAXIhY,GACAuV,QAAQe,IACJ,4EAEAzM,EAAQ+N,WAIhB5X,EAAOgT,EAAWC,oBAAoBwB,EAAQC,EAAMlC,aAChD2B,UAAWM,EAAOP,cAUlB,WAPAqB,SAAQe,IACJ,oBAAsBzM,EAAQ+N,QAAU,0CAchD,IALA5X,EAAKiY,OAASpO,EAAQ+N,QACtB5X,EAAKkY,gBAAgBxD,GACrBD,EAAO1B,SAAS/S,EAAKiY,QAAUjY,EAG3BmY,EAAiBnY,EAAKiY,QACtB,IAAKvY,EAAI,EAAGA,EAAIyY,EAAiBnY,EAAKiY,QAAQhY,OAAQP,IAClDM,EAAKoY,uBACDD,EAAiBnY,EAAKiY,QAAQvY,GAM1C,IAAI2Y,OAAA,GACEC,EAAgBxV,EAAMyV,OAAO9D,EAAO1B,SAC1C,KAAKrT,EAAI,EAAGA,EAAI4Y,EAAcrY,SAAUP,EAAG,CACvC,GAAM8Y,GAAWF,EAAc5Y,EAC/B,IAAIM,EAAK6H,SAAW2Q,EAAS3Q,QACE,aAAvB2Q,EAASC,YAEgB,KADvB,mBAAoB,eAAgB,eAAetB,QACjDqB,EAASR,OAAgB,CACjCK,EAAeG,CACf,QAIJH,EAK2B,qBAAvBA,EAAaL,OACc,iBAAvBK,EAAaL,OACbK,EAAaJ,OAASjY,EAAKiY,QAC/B1C,QAAQe,IACJ,2CAA6CtW,EAAKiY,OAClD,gCAAkCI,EAAaJ,QAEnDI,EAAaK,YAAY1Y,GACzBA,EAAK2Y,WAELpD,QAAQe,IACJ,2CAA6CtW,EAAKiY,OAClD,8BAAgCI,EAAaJ,QAEjDjY,EAAK4Y,UAGTnE,EAAOlT,KAAK,gBAAiBvB,OAE9B,IAAwB,kBAApB0U,EAAMwC,UAA+B,CAC5C,IAAKlX,EACD,MAEA0U,GAAMmD,cAAgBpD,EAAOxC,YAAYxJ,OACtB,YAAfzI,EAAKgY,OACLhY,EAAK6Y,qBAAqBhP,GAG9B7J,EAAK8Y,gBAAgBjP,OAEtB,IAAwB,sBAApB6K,EAAMwC,UAAmC,CAChD,GAAIxC,EAAMmD,cAAgBpD,EAAOxC,YAAYxJ,OACzC,MAEJ,IAAKzI,EASD,IAAKN,EAAI,EAAGA,EAAImK,EAAQkP,WAAW9Y,OAAQP,IACvCM,EAAKoY,uBAAuBvO,EAAQkP,WAAWrZ,QAR9CyY,GAAiBtO,EAAQ+N,WAC1BO,EAAiBtO,EAAQ+N,aAE7BO,EAAiBtO,EAAQ+N,SAAWO,EAChCtO,EAAQ+N,SACVnW,OAAOoI,EAAQkP,gBAMM,kBAApBrE,EAAMwC,YAGRlX,EAWkB,UAAfA,EAAKgY,QACLhY,EAAKgZ,kBAAkBnP,SAChB4K,GAAO1B,SAASlJ,EAAQ+N,WATnC5X,EAAOgT,EAAWC,oBAAoBwB,EAAQC,EAAMlC,gBAEhDxS,EAAKiY,OAASpO,EAAQ+N,QACtB5X,EAAKiZ,gBAAgBvE,GACrBD,EAAO1B,SAASlJ,EAAQ+N,SAAW5X,IA1LnD,GAAMmY,MAQFV,KACAF,GAAmB,CACvB9C,GAAOhS,GAAG,OAAQ,SAASuV,GACvB,GAAc,aAAVA,EAAsB,CACtBT,GAAmB,CAInB,KAAK,GAHC2B,MAGGxZ,EAAI+X,EAAgBxX,OAAS,EAAGP,GAAK,EAAGA,IAAK,CAClD,GAAMyZ,GAAK1B,EAAgB/X,EACN,mBAAjByZ,EAAGjC,WACkB,kBAAjBiC,EAAGjC,YACPgC,EAAcC,EAAGxB,aAAaC,SAAW,OAIjDH,EAAgBlI,QAAQ,SAAStQ,GAC7B,GAAIia,EAAcja,EAAE0Y,aAAaC,SAK7B,WAJArC,SAAQe,IACJ,4CACIrX,EAAE0Y,aAAaC,QAI3BJ,GAAiBvY,KAErBwY,QAIRhD,EAAOhS,GAAG,QAASwU,GAgKvB,QAASmC,GAAiB3E,GACjBA,EAAOvB,gBAGRuB,EAAO4E,WAIX5E,EAAO6E,aAAalX,KAAK,SAAS+S,GAC9B,GAAIA,EAAIoE,KAAM,CACVhE,QAAQe,IAAI,kBAAoBnB,EAAIoE,KAAO,eACvCpE,EAAIqE,IAAM,QAGd,IAAMC,IACFC,KAAMvE,EAAIoE,KACV/U,SAAU2Q,EAAI3Q,SACdmV,WAAYxE,EAAIrQ,SAEpB2P,GAAOmF,cAAgBH,GAEvBhF,EAAOoF,2BAA6BC,WAAW,WAC3CV,EAAiB3E,IACO,KAAxBU,EAAIqE,KAAQ,MAAmB,MAExC,SAAS9W,GACR6S,QAAQC,MAAM,2BACdf,EAAOoF,2BACHC,WAAW,WACtBV,EAAiB3E,IACf,QAIH,QAASsF,GAAQ5U,EAAU6U,EAAOtX,GAC1ByC,GACAA,EAASzC,GAEbsX,EAAMC,OAAOvX,GAGjB,QAASwX,GAAS/U,EAAU6U,EAAO7E,GAC3BhQ,GACAA,EAAS,KAAMgQ,GAEnB6E,EAAMpF,QAAQO,GAGlB,QAASgF,GAAyB1F,GAC9B,QAAS2F,GAAOC,GACZ,GAAM3F,GAAQ,GAAI4F,GAAYD,EAO9B,OANI3F,GAAMkB,gBACNnB,EAAO5C,UAAU0I,OAAO7F,GACpB,oBAEJA,EAAM8F,kBAAkB/F,EAAOZ,UAE5Ba,EAEX,MAAO0F,6QA/uFX,QAAAK,GACIhG,EAAQhM,EAAQ0G,EAAUuL,EAAUC,EAASC,GADjD,GAAAC,EAAA,OAAAC,GAAAja,QAAAka,KAAA,SAAAC,GAAA,OAAA,OAAAA,EAAAC,KAAAD,EAAA7Y,MAAA,IAAA,GAAA,GAGSsS,EAAOZ,QAHhB,CAAAmH,EAAA7Y,KAAA,CAAA,OAAA,KAIc,IAAIvC,OAAM,iCAJxB,KAAA,GAAA,MAAAob,GAAA7Y,KAAA,GAAA,EAAA+Y,EAAAtG,SAMsBH,EAAOZ,QAAQsH,sBAC7B1S,EAAQ0G,EAAUuL,EAAUC,EAASC,GAP7C,KAAA,GAMUC,EANVG,EAAAI,KASI3G,EAAOlT,KAAK,4BAA6BkH,EAAQ0G,EAAU0L,EAT/D,KAAA,GAAA,IAAA,MAAA,MAAAG,GAAAK,SAAAZ,EAAA3Z,yEArfAwa,EAAA7b,EAAA,sBAxBM8b,EAAgB9b,EAAQ,mBAMxB+b,EAAe/b,EAAQ,UAAU+b,aAEjCC,EAAMhc,EAAQ,OAEd4D,EAAU5D,EAAQ,cAClB6a,EAAc7a,EAAQ,kBAAkB6a,YACxC5H,EAAcjT,EAAQ,kBAAkBiT,YACxCgJ,EAAgBjc,EAAQ,2BACxBkc,EAAelc,EAAQ,0BACvBuS,EAAYvS,EAAQ,gBACpBuT,EAAavT,EAAQ,iBACrBqD,EAAQrD,EAAQ,WAChBmc,EAAcnc,EAAQ,kBACtBoc,EAASpc,EAAQ,YACjBqc,EAAUrc,EAAQ,UAClBmD,EAAiBnD,EAAQ,eACzBsc,EAAc1Y,EAAQ0Y,YAKxB3H,GAAiB,CAErB,KACI,GAAIE,GAAS7U,EAAQ,WACrB2U,IAAiB,EACnB,MAAOnV,GACLsW,QAAQyG,KAAK,0DAA4D/c,GAoI7E6D,EAAMmZ,SAASvK,EAAc8J,GAC7B1Y,EAAMwD,OAAOoL,EAAa3N,UAAWnB,EAAemB,WAOpD2N,EAAa3N,UAAUmY,YAAc,WACjC,GAAIpb,KAAKqb,eACL,KAAM,IAAIvc,OAAM,8CAGpB,IAAMwc,KAMN,OAJAA,GAAS1E,KAAK5W,KAAKiR,MAAMsK,iBACrBvb,KAAKgT,cACLsI,EAAS1E,KAAK5W,KAAKgT,aAAauI,iBAE7B1H,EAAA9T,QAAQyb,IAAIF,IAQvB1K,EAAa3N,UAAUwY,UAAY,WAC/B,MAAIzb,MAAKmR,aAAenR,KAAKmR,YAAYxJ,OAC9B3H,KAAKmR,YAAYxJ,OAErB,MAOXiJ,EAAa3N,UAAUyY,UAAY,WAC/B,MAAI1b,MAAKmR,aAAenR,KAAKmR,YAAYxJ,OAC9B3H,KAAKmR,YAAYxJ,OAAOgU,QAAQ,QAAS,IAE7C,MAOX/K,EAAa3N,UAAU2Y,mBAAqB,WACxC,MAAI5b,MAAKmR,aAAenR,KAAKmR,YAAYxJ,OAC9B3H,KAAKmR,YAAYxJ,OAAOkU,MAAM,KAAK,GAAGC,UAAU,GAEpD,MAOXlL,EAAa3N,UAAU8Y,YAAc,WACjC,MAAO/b,MAAKqO,UAQhBuC,EAAa3N,UAAU+Y,aAAe,WAClC,MAAOhc,MAAKoS,eAShBxB,EAAa3N,UAAUgZ,aAAe,SAAS5I,GAC3CrT,KAAKoT,WAAaC,GAQtBzC,EAAa3N,UAAUiZ,aAAe,WAClC,MAAKlc,MAAKuS,SAGHvS,KAAKuS,SAAS2J,eAFV,MASftL,EAAa3N,UAAUsV,QAAU,WAC7B,MAAOvY,MAAKyS,UAOhB7B,EAAa3N,UAAUkZ,aAAe,WAClC,MAAOnc,MAAKoR,WAQhBR,EAAa3N,UAAUmZ,SAAW,SAAS7D,GAKvCvY,KAAKyS,SAAW8F,GAQpB3H,EAAa3N,UAAUoZ,iBAAmB,WACtC,MAAOrc,MAAKuS,SAAS8J,oBAQzBzL,EAAa3N,UAAUqZ,oBAAsB,WACzC,MAAOtc,MAAK8S,mBAQhBlC,EAAa3N,UAAUsZ,oBAAsB,SAASC,GAClDxc,KAAK8S,kBAAoB0J,GAe7B5L,EAAa3N,UAAUwZ,YAAvB,EAAArC,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAoC,QAAAC,KAAA,GAAAjV,GAAAkV,CAAA,OAAA7C,GAAAja,QAAAka,KAAA,SAAA6C,GAAA,OAAA,OAAAA,EAAA3C,KAAA2C,EAAAzb,MAAA,IAAA,GAAA,IAC5BrB,KAAK+S,QADuB,CAAA+J,EAAAzb,KAAA,CAAA,OAAA,MAE5BoT,SAAQyG,KAAK,2DAFe4B,EAAAC,OAAA,SAAA,KAAA,GAAA,GAM3BzJ,EAN2B,CAAAwJ,EAAAzb,KAAA,CAAA,OAAA,KAOtB,IAAIvC,OACN,sGARwB,KAAA,GAAA,GAa3BkB,KAAKkT,cAbsB,CAAA4J,EAAAzb,KAAA,CAAA,OAAA,KAetB,IAAIvC,OAAJ,qDAfsB,KAAA,GAAA,GAiB3BkB,KAAKgT,aAjBsB,CAAA8J,EAAAzb,KAAA,CAAA,OAAA,KAmBtB,IAAIvC,OAAJ,oDAnBsB,KAAA,GAAA,GAuBjB,QADT6I,EAAS3H,KAAKyb,aAtBY,CAAAqB,EAAAzb,KAAA,EAAA,OAAA,KAwBtB,IAAIvC,OACN,2GAzBwB,KAAA,IAAA,GA6BV,OAAlBkB,KAAKqO,SA7BuB,CAAAyO,EAAAzb,KAAA,EAAA,OAAA,KA8BtB,IAAIvC,OACN,+GA/BwB,KAAA,IAAA,MAoC1B+d,GAAS,GAAIrJ,GACfxT,KACAA,KAAKkT,cACLvL,EAAQ3H,KAAKqO,SACbrO,KAAKiR,MACLjR,KAAKgT,cAGThT,KAAK+Q,UAAU0I,OAAOoD,GAClB,wBACA,sCA9C4BC,EAAAzb,KAAA,IAAA,EAAA+Y,EAAAtG,SAiD1B+I,EAAOG,OAjDmB,KAAA,IAqDhCH,EAAOI,sBAAsBjd,MAC7BA,KAAK+S,QAAU8J,CAtDiB,KAAA,IAAA,IAAA,MAAA,MAAAC,GAAAvC,SAAAqC,EAAA5c,SA8DpC4Q,EAAa3N,UAAUia,gBAAkB,WACrC,MAAwB,QAAjBld,KAAK+S,SAUhBnC,EAAa3N,UAAUka,oBAAsB,WACzC,MAAKnd,MAAK+S,QAGH/S,KAAK+S,QAAQoK,sBAFT,MASfvM,EAAa3N,UAAUma,WAAa,WAChC,GAAqB,OAAjBpd,KAAK+S,QACL,KAAM,IAAIjU,OAAM,iCAGpB,OAAOkB,MAAK+S,QAAQsK,oBAYxBzM,EAAa3N,UAAUqa,aAAe,SAASrU,EAASsU,GACpD,MAAqB,QAAjBvd,KAAK+S,QACEc,EAAA9T,QAAQoZ,OAAO,GAAIra,OAAM,mCAE7BkB,KAAK+S,QAAQuK,aAAarU,EAASsU,IAU9C3M,EAAa3N,UAAUua,wBAAvB,WAAA,GAAAC,IAAA,EAAArD,EAAAlE,QAAiD,SAAevO,GAC5D,GAAqB,OAAjB3H,KAAK+S,QACL,KAAM,IAAIjU,OAAM,iCAEpB,OAAOkB,MAAK+S,QAAQyK,wBAAwB7V,QAJhD,OAAA,UAAA+V,GAAA,MAAAD,GAAA/c,MAAAV,KAAAK,eAeAuQ,EAAa3N,UAAU0a,gBAAvB,WAAA,GAAAC,IAAA,EAAAxD,EAAAlE,QAAyC,SAAevO,EAAQ0G,GAC5D,GAAqB,OAAjBrO,KAAK+S,QACL,KAAM,IAAIjU,OAAM,iCAEpB,OAAOkB,MAAK+S,QAAQ4K,gBAAgBhW,EAAQ0G,IAAa,MAJ7D,OAAA,UAAAwP,EAAAC,GAAA,MAAAF,GAAAld,MAAAV,KAAAK,eAoBAuQ,EAAa3N,UAAU8a,kBAAoB,SAASpW,EAAQ0G,EAAUuL,GAIlE,WAHiB3Y,KAAb2Y,IACAA,GAAW,GAERoE,EAAuBhe,KAAM2H,EAAQ0G,EAAUuL,EAAU,OAgBpEhJ,EAAa3N,UAAUgb,iBAAmB,SAAStW,EAAQ0G,EAAUwL,GAIjE,WAHgB5Y,KAAZ4Y,IACAA,GAAU,GAEPmE,EAAuBhe,KAAM2H,EAAQ0G,EAAU,KAAMwL,IAgBhEjJ,EAAa3N,UAAUib,eAAiB,SAASvW,EAAQ0G,EAAUyL,GAI/D,WAHc7Y,KAAV6Y,IACAA,GAAQ,GAELkE,EAAuBhe,KAAM2H,EAAQ0G,EAAU,KAAM,KAAMyL,IAuBtElJ,EAAa3N,UAAUkb,oCAAsC,SAAS5c,GAClE,GAAqB,OAAjBvB,KAAK+S,QACL,KAAM,IAAIjU,OAAM,iCAEpBkB,MAAK+S,QAAQoL,oCAAoC5c,IAOrDqP,EAAa3N,UAAUmb,oCAAsC,WACzD,GAAqB,OAAjBpe,KAAK+S,QACL,KAAM,IAAIjU,OAAM,iCAEpB,OAAOkB,MAAK+S,QAAQqL,uCAUxBxN,EAAa3N,UAAUob,yBAAvB,WAAA,GAAAC,IAAA,EAAAlE,EAAAlE,QAAkD,SAAetC,GAC7D,MAAK5T,MAAK+S,QAIH/S,KAAK+S,QAAQsL,yBAAyBzK,GAHlC,MAFf,OAAA,UAAA2K,GAAA,MAAAD,GAAA5d,MAAAV,KAAAK,eAgBAuQ,EAAa3N,UAAUub,sBAAvB,WAAA,GAAAC,IAAA,EAAArE,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA+C,QAAA+B,GAAe9K,GAAf,GAAA+K,EAAA,OAAA3E,GAAAja,QAAAka,KAAA,SAAA2E,GAAA,OAAA,OAAAA,EAAAzE,KAAAyE,EAAAvd,MAAA,IAAA,GAAA,MAAAud,GAAAvd,KAAA,GAAA,EAAA+Y,EAAAtG,SACtB9T,KAAKqe,yBAAyBzK,GADR,KAAA,GAAA,GACrC+K,EADqCC,EAAAtE,KAAA,CAAAsE,EAAAvd,KAAA,CAAA,OAAA,MAAAud,GAAA7B,OAAA,UAGhC,EAHgC,KAAA,GAAA,MAAA6B,GAAA7B,OAAA,SAKpC4B,EAAOE,aAL6B,KAAA,GAAA,IAAA,MAAA,MAAAD,GAAArE,SAAAmE,EAAA1e,QAA/C,OAAA,UAAA8e,GAAA,MAAAL,GAAA/d,MAAAV,KAAAK,eAcAuQ,EAAa3N,UAAU8b,kBAAoB,SAAShY,EAAQiY,GACxD,IAAKhf,KAAK+S,QACN,KAAM,IAAIjU,OAAM,iCAEpB,OAAOkB,MAAK+S,QAAQgM,kBAAkBhY,EAAQiY,IAQlDpO,EAAa3N,UAAU8R,gBAAkB,SAAShO,GAC9C,GAAMyK,GAAOxR,KAAKyR,QAAQ1K,EAC1B,SAAKyK,MAQMA,EAAKyN,aAAaC,eAAe,oBAAqB,OAQ5Dlf,KAAKkT,eAIHN,QAAQ5S,KAAKkT,cAAciM,gBAAgBpY,MAWtD6J,EAAa3N,UAAUmc,eAAiB,WACpC,MAAKpf,MAAK+S,QAGH/S,KAAK+S,QAAQqM,iBAFTvL,EAAA9T,QAAQoZ,OAAO,GAAIra,OAAM,oCAaxC8R,EAAa3N,UAAUoc,eAAiB,SAASC,GAC7C,IAAKtf,KAAK+S,QACN,KAAM,IAAIjU,OAAM,iCAEpB,OAAOkB,MAAK+S,QAAQsM,eAAeC,IAevC1O,EAAa3N,UAAUsc,SAAW,SAASrY,GACvC,MAAOlH,MAAKiR,MAAMsO,SAASrY,IAO/B0J,EAAa3N,UAAUuc,UAAY,WAC/B,MAAOxf,MAAKiR,MAAMuO,aActB5O,EAAa3N,UAAUwO,QAAU,SAAS1K,GACtC,MAAO/G,MAAKiR,MAAMQ,QAAQ1K,IAO9B6J,EAAa3N,UAAUwc,SAAW,WAC9B,MAAOzf,MAAKiR,MAAMwO,YAStB7O,EAAa3N,UAAUyc,QAAU,SAAS/X,GACtC,MAAO3H,MAAKiR,MAAMyO,QAAQ/X,IAO9BiJ,EAAa3N,UAAU0c,SAAW,WAC9B,MAAO3f,MAAKiR,MAAM0O,YActB/O,EAAa3N,UAAU2c,eAAiB,SAAStW,EAAWuW,EAAUxb,GAClE,GAAMoC,GAAOzE,EAAM0E,UAAU,oCACzBkB,QAAS5H,KAAKmR,YAAYxJ,OAC1BmY,MAAOxW,GAEX,OAAOtJ,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAW4e,IAU1CjP,EAAa3N,UAAU8c,eAAiB,SAASzW,GAC7C,MAAOtJ,MAAKiR,MAAM8O,eAAezW,IAOrCsH,EAAa3N,UAAU+c,gBAAkB,WACrC,GAAMpM,GAAQ5T,KAAK+f,eAAe,sBAClC,OAAKnM,IAAUA,EAAMiD,cAAiBjD,EAAMiD,aAAN,eAC/B,EAAAnM,EAAA3K,SAAY6T,EAAMiD,aAAN,mBAUvBjG,EAAa3N,UAAUgd,gBAAkB,SAAShX,EAAS5E,GACvD,GAAM0E,IAAWmX,iBAEjB,OADAjX,GAAQkX,IAAI,SAAC1hB,GAAD,MAAOsK,GAAQmX,cAAczhB,QAClCuB,KAAK4f,eAAe,sBAAuB7W,EAAS1E,IAQ/DuM,EAAa3N,UAAUmd,cAAgB,SAASzY,GAC5C,OAAmD,IAA5C3H,KAAKggB,kBAAkB3J,QAAQ1O,IAmB1CiJ,EAAa3N,UAAUod,SAAW,SAASC,EAAeve,EAAMsC,GAE5D,GAAIrC,EAAMiI,WAAWlI,GACjB,KAAM,IAAIjD,OAAM,wCAEpBiD,GAAOA,UACed,KAAlBc,EAAKwe,WACLxe,EAAKwe,UAAW,EAGpB,IAAM/O,GAAOxR,KAAKyR,QAAQ6O,EAC1B,IAAI9O,GAAQA,EAAKgP,mBAAmBxgB,KAAKmR,YAAYxJ,OAAQ,QACzD,MAAOkM,GAAA9T,QAAQ+T,QAAQtC,EAG3B,IAAIiP,GAAe5M,EAAA9T,QAAQ+T,SAEvB/R,GAAK2e,gBACLD,EAAezgB,KAAK8C,MAAM6d,oBACtB1f,GAAW,OACXc,EAAK2e,eAAiBE,KAAM5gB,KAAKmR,YAAYxJ,SAIrD,IAAMuR,GAAQrF,EAAA9T,QAAQmZ,QAEhB7H,EAAOrR,IAuBb,OAtBAygB,GAAa7c,KAAK,SAASid,GACvB,GAAM5b,KACF4b,KACA5b,EAAK6b,mBAAqBD,EAG9B,IAAMpa,GAAOzE,EAAM0E,UAAU,iBAAmBqa,QAAST,GACzD,OAAOjP,GAAKvO,MAAMa,kBAAc1C,GAAW,OAAQwF,MAAMxF,GAAWgE,KACrErB,KAAK,SAASyQ,GACb,GAAMtN,GAASsN,EAAIvJ,QACbkW,EAAU,GAAIhG,GAAQ3J,EAAMA,EAAK4P,aACjCzP,EAAOwP,EAAQpa,WAAWG,EAKhC,OAJIhF,GAAKwe,SAIF1M,EAAA9T,QAAQ+T,QAAQtC,KACxBlQ,KAAK,SAASkQ,GACb4H,EAAS/U,EAAU6U,EAAO1H,IAC3B,SAAS5P,GACRqX,EAAQ5U,EAAU6U,EAAOtX,KAEtBsX,EAAMpN,SAWjB8E,EAAa3N,UAAUie,YAAc,SAAStN,EAAOpC,GAEjD,MADAM,GAA0BN,EAAMoC,EAAOhC,EAAYC,SAC5C6B,EAAW1T,KAAMwR,EAAMoC,IASlChD,EAAa3N,UAAUke,mBAAqB,SAASvN,GACjD,IAAKhC,EAAYwC,OAAQxC,EAAYgD,UAAUyB,QAAQzC,EAAMjC,QAAU,EACnE,KAAM,IAAI7S,OAAM,sCAAwC8U,EAAMjC,OAI9D3R,MAAKoR,WACLpR,KAAKoR,UAAUgQ,qBAAqBxN,GAMxC9B,EADa9R,KAAKyR,QAAQmC,EAAMlC,aACAkC,EAAOhC,EAAYyP,YAUvDzQ,EAAa3N,UAAUqe,YAAc,SAASva,EAAQwa,EAAMld,GACxD,MAAOrE,MAAK2J,eAAe5C,EAAQ,eAAgBwa,KAAMA,OAC9BtgB,GAAWoD,IAU1CuM,EAAa3N,UAAUue,aAAe,SAASza,EAAQ0a,EAAOpd,GAC1D,MAAOrE,MAAK2J,eAAe5C,EAAQ,gBAAiB0a,MAAOA,OAChCxgB,GAAWoD,IAS1CuM,EAAa3N,UAAUye,YAAc,SAAS3a,EAAQ1C;sCAClD,GAAMoC,GAAOzE,EAAM0E,UAAU,qCACzBkB,QAAS5H,KAAKmR,YAAYxJ,OAC1BX,QAASD,GAEb,OAAO/G,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,KAY/B2P,EAAa3N,UAAU0e,WAAa,SAAS5a,EAAQ6a,EAASC,EAAUxd,GACpE,GAAMoC,GAAOzE,EAAM0E,UAAU,yCACzBkB,QAAS5H,KAAKmR,YAAYxJ,OAC1BX,QAASD,EACT+a,KAAMF,GAEV,OAAO5hB,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAW4gB,IAW1CjR,EAAa3N,UAAU8e,cAAgB,SAAShb,EAAQ6a,EAASvd,GAC7D,GAAMoC,GAAOzE,EAAM0E,UAAU,yCACzBkB,QAAS5H,KAAKmR,YAAYxJ,OAC1BX,QAASD,EACT+a,KAAMF,GAEV,OAAO5hB,MAAK8C,MAAMa,cACdU,EAAU,SAAUoC,MAAMxF,OAAWA,KAY7C2P,EAAa3N,UAAU+e,mBAAqB,SAASjb,EAAQuC,EACRP,EAAS1E,GAC1D,GAAMoC,GAAOzE,EAAM0E,UAAU,kDACzBkB,QAAS5H,KAAKmR,YAAYxJ,OAC1BX,QAASD,EACT+Y,MAAOxW,GAEX,OAAOtJ,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAW8H,IAc1C6H,EAAa3N,UAAUgf,cAAgB,SAASlb,EAAQY,EAAQua,EAChBtO,EAAOvP,GACnD,GAAI0E,IACAoZ,SAEAvO,IAA6B,wBAApBA,EAAMwC,YAGfrN,EAAU/G,EAAMogB,SAASxO,EAAMiD,eAEnC9N,EAAQoZ,MAAMxa,GAAUua,CACxB,IAAMzb,GAAOzE,EAAM0E,UAAU,4CACzBM,QAASD,GAEb,OAAO/G,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAW8H,IAa1C6H,EAAa3N,UAAUof,UAAY,SAAStb,EAAQuC,EAAWP,EAASqH,EAC5B/L,GACpCrC,EAAMiI,WAAWmG,KACjB/L,EAAW+L,EAAOA,MAAQnP,IAGzBmP,IACDA,EAAQpQ,KAAKsD,aAGjBmR,QAAQe,IAAR,qBAAiClM,EAAjC,OAAiDvC,EAAjD,eAAsEqJ,EAKtE,IAAMoB,GAAOxR,KAAKyR,QAAQ1K,GACpBub,EAAa,GAAI9I,IACnBhF,SAAU,IAAMzN,EAAS,IAAMqJ,EAC/B4F,QAAShW,KAAKmR,YAAYxJ,OAC1BmD,QAAS/D,EACTxB,KAAM+D,EACNiZ,kBAAkB,GAAIhf,OAAOC,UAC7BuF,QAASA,GAUb,OARAuZ,GAAWpN,OAAS9E,EACpBkS,EAAW3Q,OAASC,EAAYC,QAG5BL,GACAA,EAAKgR,gBAAgBF,EAAYlS,GAG9BsD,EAAW1T,KAAMwR,EAAM8Q,EAAYje,IA4J9CuM,EAAa3N,UAAUwf,YAAc,SAAS1b,EAAQgC,EAASqH,EAAO/L,GAIlE,MAHIrC,GAAMiI,WAAWmG,KACjB/L,EAAW+L,EAAOA,MAAQnP,IAEvBjB,KAAKqiB,UACRtb,EAAQ,iBAAkBgC,EAASqH,EAAO/L,IAYlDuM,EAAa3N,UAAUyf,gBAAkB,SAAS3b,EAAQ/B,EAAMoL,EAAO/L,GACnE,GAAM0E,IACD4Z,QAAS,SACT3d,KAAMA,EAEX,OAAOhF,MAAKyiB,YAAY1b,EAAQgC,EAASqH,EAAO/L,IAWpDuM,EAAa3N,UAAU2f,WAAa,SAAS7b,EAAQ/B,EAAMoL,EAAO/L,GAC9D,GAAM0E,IACD4Z,QAAS,WACT3d,KAAMA,EAEX,OAAOhF,MAAKyiB,YAAY1b,EAAQgC,EAASqH,EAAO/L,IAWpDuM,EAAa3N,UAAU4f,iBAAmB,SAAS9b,EAAQ/B,EAAMoL,EAAO/L,GACpE,GAAM0E,IACD4Z,QAAS,UACT3d,KAAMA,EAEX,OAAOhF,MAAKyiB,YAAY1b,EAAQgC,EAASqH,EAAO/L,IAYpDuM,EAAa3N,UAAU6f,iBAAmB,SAAS/b,EAAQ4T,EAAK1O,EAAM8W,EAAM1e,GACpErC,EAAMiI,WAAW8Y,KACjB1e,EAAW0e,EAAMA,MAAO9hB,IAEvB8hB,IACDA,EAAO,QAEX,IAAMha,IACD4Z,QAAS,UACThI,IAAKA,EACL1O,KAAMA,EACNjH,KAAM+d,EAEX,OAAO/iB,MAAKyiB,YAAY1b,EAAQgC,EAAS1E,IAW7CuM,EAAa3N,UAAU+f,gBAAkB,SAASjc,EAAQ/B,EAAMie,EAAU5e,GACtE,GAAM0E,IACF4Z,QAAS,SACTO,OAAQ,yBACRle,KAAMA,EACNme,eAAgBF,EAEpB,OAAOjjB,MAAKyiB,YAAY1b,EAAQgC,EAAS1E,IAW7CuM,EAAa3N,UAAUmgB,eAAiB,SAASrc,EAAQ/B,EAAMie,EAAU5e,GACrE,GAAM0E,IACF4Z,QAAS,WACTO,OAAQ,yBACRle,KAAMA,EACNme,eAAgBF,EAEpB,OAAOjjB,MAAKyiB,YAAY1b,EAAQgC,EAAS1E,IAW7CuM,EAAa3N,UAAUogB,cAAgB,SAAStc,EAAQ/B,EAAMie,EAAU5e,GACpE,GAAM0E,IACF4Z,QAAS,UACTO,OAAQ,yBACRle,KAAMA,EACNme,eAAgBF,EAEpB,OAAOjjB,MAAKyiB,YAAY1b,EAAQgC,EAAS1E,IAW7CuM,EAAa3N,UAAUqgB,YAAc,SAAS1P,EAAO2P,EAAalf,GAC9D,GAAIrE,KAAKuY,UACL,MAAO1E,GAAA9T,QAAQ+T,WAGnB,IAAMrN,GAAOzE,EAAM0E,UAAU,gDACzBM,QAAS4M,EAAMlC,YACf8R,aAAcD,EACdzZ,SAAU8J,EAAM6P,UAEd3X,EAAU9L,KAAK8C,MAAMa,cACvBU,EAAU,OAAQoC,MAAMxF,OAGtBuQ,EAAOxR,KAAKyR,QAAQmC,EAAMlC,YAIhC,OAHIF,IACAA,EAAKkS,qBAAqB1jB,KAAKmR,YAAYxJ,OAAQiM,EAAO2P,GAEvDzX,GAUX8E,EAAa3N,UAAU0gB,gBAAkB,SAAS/P,EAAOvP,GACrD,MAAOrE,MAAKsjB,YAAY1P,EAAO,SAAUvP,IAe7CuM,EAAa3N,UAAU2gB,mBAAqB,SAAS7c,EAAQ8C,EAASga,GAClE,GAAM1Z,GAAYN,EACdO,MAAA,EAGJ,IAAIyZ,EAAS,CACTzZ,EAAYyZ,EAAQJ,OACpB,IAAMjS,GAAOxR,KAAKyR,QAAQ1K,EACtByK,IACAA,EAAKkS,qBAAqB1jB,KAAKmR,YAAYxJ,OAAQkc,EAAS,UAIpE,MAAO7jB,MAAKkK,8BAA8BnD,EAAQoD,EAAWC,IAkBjEwG,EAAa3N,UAAU6gB,cAAgB,SAASnJ,EAAKoJ,EAAI1f,GACrD,GAAM2f,GAAMD,EAAK,IAAMpJ,EACjBsJ,EAAKjkB,KAAK6S,gBAAgBmR,EAChC,IAAIC,EACA,MAAOpQ,GAAA9T,QAAQ+T,QAAQmQ,EAG3B,IAAM5S,GAAOrR,IACb,OAAOA,MAAK8C,MAAMwD,wBACdjC,EAAU,MAAO,gBACbsW,IAAKA,EACLoJ,GAAIA,OACL9iB,GAAWsB,EAAQ2hB,iBACxBtgB,KAAK,SAASC,GAGZ,MADAwN,GAAKwB,gBAAgBmR,GAAOngB,EACrBA,KAYf+M,EAAa3N,UAAUkhB,WAAa,SAASpd,EAAQqd,EAAUC,EAAWhgB,GACtE,GAAIrE,KAAKuY,UACL,MAAO1E,GAAA9T,QAAQ+T,WAGnB,IAAMrN,GAAOzE,EAAM0E,UAAU,iCACzBM,QAASD,EACTa,QAAS5H,KAAKmR,YAAYxJ,SAExB1C,GACFqf,OAAQF,EAKZ,OAHIA,KACAnf,EAAKsf,QAAUF,GAAwB,KAEpCrkB,KAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAWgE,IAW1C2L,EAAa3N,UAAUuhB,OAAS,SAASzd,EAAQY,EAAQtD,GACrD,MAAOwR,GAAkB7V,KAAM+G,EAAQY,EAAQ,aAAU1G,GACrDoD,IAWRuM,EAAa3N,UAAUwhB,cAAgB,SAAS1d,EAAQzC,EAAOD,GAC3D,MAAOrE,MAAK0kB,iBACR3d,EAAQ,QAASzC,EAAOD,IAahCuM,EAAa3N,UAAUyhB,iBAAmB,SAAS3d,EAAQyF,EAAQC,EAASpI,GACxE,GAAMoC,GAAOzE,EAAM0E,UACf,yBACEM,QAASD,IAGX4d,EAAoB3kB,KAAKmD,sBAC7B,OAAKwhB,IAMwC,IAAzCA,EAAkBtO,QAAQ,YACoB,IAA1CsO,EAAkBtO,QAAQ,cAE9BsO,EAAoBA,EAAkB9I,MAAM,OAAO,IAGhD7b,KAAK8C,MAAMa,cAAcU,EAAU,OAAQoC,MAAMxF,IACpD2jB,UAAWD,EACXnY,OAAQA,EACRC,QAASA,KAdFoH,EAAA9T,QAAQoZ,OAAO,GAAI8B,IACtBvG,MAAO,kCACPmQ,QAAS,qCAsBrBjU,EAAa3N,UAAU6hB,MAAQ,SAAS/d,EAAQ1C,GAC5C,MAAOwR,GAAkB7V,KAAM+G,MAAQ9F,GAAW,YAASA,GACvDoD,IAWRuM,EAAa3N,UAAU8hB,IAAM,SAAShe,EAAQY,EAAQgO,EAAQtR,GAC1D,MAAOwR,GAAkB7V,KAAM+G,EAAQY,EAAQ,MAAOgO,EAClDtR,IAWRuM,EAAa3N,UAAU+hB,OAAS,SAASje,EAAQke,EAAY5gB,OACtCpD,KAAfgkB,IACAA,GAAa,EAEjB,IAAMnZ,GAAU+J,EAAkB7V,KAAM+G,MAAQ9F,GAAW,aAAUA,GACjEoD,EACJ,KAAK4gB,EACD,MAAOnZ,EAEX,IAAMuF,GAAOrR,IACb,OAAO8L,GAAQlI,KAAK,SAASC,GAGzB,MAFAwN,GAAKJ,MAAMiU,WAAWne,GACtBsK,EAAK5Q,KAAK,aAAcsG,GACjBlD,KAWf+M,EAAa3N,UAAUkiB,MAAQ,SAASpe,EAAQY,EAAQtD,GAMpD,GAAMoC,GAAOzE,EAAM0E,UAAU,wBACzBM,QAASD,IAEP9B,GACF+Q,QAASrO,EAEb,OAAO3H,MAAK8C,MAAMa,cACdU,EAAU,OAAQoC,MAAMxF,GAAWgE,IAY3C2L,EAAa3N,UAAUmiB,KAAO,SAASre,EAAQY,EAAQgO,EAAQtR,GAC3D,MAAOoR,GACHzV,KAAM+G,EAAQY,EAAQ,QAASgO,EAAQtR,IAkE/CuM,EAAa3N,UAAUoiB,uBAAyB,SAASzR,GACrD,IAAKA,EAAM0R,iBAAkB,CACzB,GAAMC,GAAgB,GAAI9K,GAAcza,KACxC4T,GAAM4R,eAAeD,EAAcE,gBAAgB7R,IAEvD,MAAOA,GAAM0R,kBAajB1U,EAAa3N,UAAUyiB,eAAiB,SAASzZ,EAAMhH,EAAMZ,GACzD,GAAMoC,GAAOzE,EAAM0E,UAAU,0BACzBkB,QAAS5H,KAAKmR,YAAYxJ,OAC1BuE,MAAOD,GAEX,OAAOjM,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAWgE,IAU1C2L,EAAa3N,UAAU0iB,eAAiB,SAASpE,EAAMld,GACnD,MAAOrE,MAAK0lB,eACR,eAAiBE,YAAarE,GAAQld,IAU9CuM,EAAa3N,UAAU4iB,aAAe,SAASlL,EAAKtW,GAChD,MAAOrE,MAAK0lB,eACR,cAAgBI,WAAYnL,GAAOtW,IAiB3CuM,EAAa3N,UAAU8iB,aACf,SAASC,EAAQC,EAAOC,EAAQC,EAAcC,GAClD,MAAOtL,GAAYuL,iBACfrmB,KAAKkC,QAAS8jB,EAAQC,EAAOC,EAAQC,EAAcC,IAa3DxV,EAAa3N,UAAUqjB,YAAc,SAASvkB,EAAMsC,GAChD,GAAMoC,GAAOzE,EAAM0E,UAAU,4BACzBkB,QAAS5H,KAAKmR,YAAYxJ,QAQ9B,IALoB,gBAAT5F,KACTA,GAASwkB,SAAUxkB,KAIsB,IADtB,UAAW,SAAU,eAC1BsU,QAAQtU,EAAKwkB,UACzB,KAAM,IAAIznB,OAAM,uBAAyBiD,EAAKwkB,SAElD,OAAOvmB,MAAK8C,MAAMa,cACdU,EAAU,MAAOoC,MAAMxF,GAAWc,IAiB1C6O,EAAa3N,UAAUujB,gBAAkB,SAASniB,GAChD,MAAO4R,GAAc5R,EAAUrE,SAAMiB,GAAW,QAUlD2P,EAAa3N,UAAUwjB,qBAAuB,SAASpiB,EAAU4E,GAE/D,MAAOgN,GAAc5R,EAAUrE,MADjBwkB,OAAUvb,GACmB,SAU7C2H,EAAa3N,UAAUyjB,qBAAuB,SAASriB,EAAU4E,GAE/D,MAAOgN,GAAc5R,EAAUrE,MADjB2mB,KAAQ1d,GACqB,SAoB7C2H,EAAa3N,UAAU2jB,WAAa,SAASpV,EAAMxH,EAAO3F,GAClDrC,EAAMiI,WAAWD,KACjB3F,EAAW2F,EAAOA,MAAQ/I,IAE9B+I,EAAQA,GAAS,EACjB,IAAI6c,GAAe,EAEf5a,EAAOjM,KAAK0S,oBAAoBlB,EAAKzK,WACzC,IAAIkF,EAAKH,QACL,MAAOG,GAAKH,OACT,IAAIG,EAAK6a,QAAS,CACrB,GAAMC,GAAexjB,KAAKyjB,MAAQ/a,EAAK6a,OACvCD,GAAeI,KAAKC,IAjzDA,IAizD0BH,EAAc,GAGhE,GAAsC,OAAlCvV,EAAK2V,SAASC,gBACd,MAAOvT,GAAA9T,QAAQ+T,QAAQtC,EAG3B,IAAM6V,GAAWrnB,KAAKiR,MAAM2V,WAAWpV,EAAMxH,GAAO7K,MACpD,IAAIkoB,IAAard,EAEb,MAAO6J,GAAA9T,QAAQ+T,QAAQtC,EAG3BxH,IAAgBqd,CAEhB,IAAM5gB,GAAOzE,EAAM0E,UACf,2BAA4BM,QAASwK,EAAKzK,SAExCvC,GACF4K,KAAMoC,EAAK2V,SAASC,gBACpBpd,MAAOA,EACPsd,IAAK,KAEHpO,EAAQrF,EAAA9T,QAAQmZ,OACtBjN,IACIH,QAASoN,EAAMpN,QACfgb,QAAS,KAEb,IAAMzV,GAAOrR,IAsBb,OAnBA6T,GAAA9T,QAAQwnB,MAAMV,GAAcjjB,KAAK,WAC7B,MAAOyN,GAAKvO,MAAMa,cAAcU,EAAU,MAAOoC,EAAMjC,KACxDlD,KAAK,SAAS+S,GACb,GAAMmT,GAAexlB,EAAMme,IAAI9L,EAAIoT,MAAOpO,EAAyBhI,GACnEG,GAAKkW,oBAAoBF,GAAc,EAAMhW,EAAKmW,mBAClDnW,EAAK2V,SAASC,gBAAkB/S,EAAIuT,IACX,IAArBvT,EAAIoT,MAAMtoB,SACVqS,EAAK2V,SAASC,gBAAkB,MAEpC/V,EAAKJ,MAAM4W,YAAYrW,EAAMgW,EAAcnT,EAAIuT,KAAK,GACpDvW,EAAKqB,oBAAoBlB,EAAKzK,QAAU,KACxCqS,EAAS/U,EAAU6U,EAAO1H,IAC3B,SAAS5P,GACRyP,EAAKqB,oBAAoBlB,EAAKzK,SAC1B+f,QAASvjB,KAAKyjB,OAElB/N,EAAQ5U,EAAU6U,EAAOtX,KAE7B5B,KAAK0S,oBAAoBlB,EAAKzK,QAAUkF,EACjCiN,EAAMpN,SAejB8E,EAAa3N,UAAU6kB,qBAAuB,SAASC,EAAchmB,GAGjEA,EAAOA,KACP,IAAMimB,GAAYjmB,EAAKimB,YAAa,EAE9B7hB,EAAQ4hB,EAAaE,iBAAiBD,EAC5C,KAAK7hB,EAED,MAAO0N,GAAA9T,QAAQoZ,OAAO,GAAIra,OAAM,qBAGpC,IAAMwoB,GAAMU,EAAY,IAAM,IACxBE,EAAiBH,EAAaI,kBAAkBb,EAEtD,IAAIY,EAEA,MAAOA,EAGX,IAAMzhB,GAAOzE,EAAM0E,UACf,2BAA4BM,QAAS+gB,EAAaK,WAAW1W,cAE3DlN,GACF4K,KAAMjJ,EACN6D,MAAQ,SAAWjI,GAAQA,EAAKiI,MAAQ,GACxCsd,IAAKA,GAGHjW,EAAOrR,KACP8L,EACFuF,EAAKvO,MAAMa,kBAAc1C,GAAW,MAAOwF,EAAMjC,GACnDZ,KAAK,SAASyQ,GACZ,GAAIlO,GAAQkO,EAAIuT,GAChB,IAAyB,IAArBvT,EAAIoT,MAAMtoB,OACVgH,EAAQ,SACL,CACH,GAAMqhB,GAAexlB,EAAMme,IAAI9L,EAAIoT,MAAOpW,EAAKgX,iBAC3CL,IAGAR,EAAac,UAEjBP,EAAaQ,UAAUf,EAAcQ,GAGzC,MADAD,GAAaS,iBAAiBriB,EAAO6hB,GAC9BD,IACRU,QAAQ,WACPV,EAAaI,kBAAkBb,GAAO,MAI1C,OAFAS,GAAaI,kBAAkBb,GAAOxb,EAE/BA,GAiBX8E,EAAa3N,UAAUylB,iBAAmB,SAASC,EAAa9e,GAE5D,IAAK7J,KAAK2S,gBACN,KAAM,IAAI7T,OAAM,qHAKpB,IAAI6pB,EAAYC,oBAAoB/e,GAChC,MAAOgK,GAAA9T,QAAQ+T,QAAQ6U,EAAYC,oBAAoB/e,GAG3D,IAAMpD,GAAOzE,EAAM0E,UACf,mCACIM,QAAS2hB,EAAYnX,KAAKzK,OAC1B+C,SAAUD,IAMZwH,EAAOrR,IAwCb,OAtCIqR,GAAKvO,MAAMa,kBAAc1C,GAAW,MAAOwF,GAC7C7C,KAAK,SAASyQ,GACZ,IAAKA,EAAIT,MACL,KAAM,IAAI9U,OAAM,yDAKpB,IAAI6pB,EAAYC,oBAAoB/e,GAChC,MAAO8e,GAAYC,oBAAoB/e,EAM3CwK,GAAIwU,aAAaP,SACjB,IAAMQ,GAASzU,EAAIwU,aACdloB,QAAQ0T,EAAIT,QACZjT,OAAO0T,EAAI0U,eACVvB,EAAexlB,EAAMme,IAAI2I,EAAQzX,EAAKgX,kBAExCW,EAAWL,EAAYC,oBAAoBpB,EAAa,GAAG/D,QAe/D,OAdKuF,KACDA,EAAWL,EAAYM,cACvBD,EAASE,gBAAgBlnB,EAAMme,IAAI9L,EAAI6C,MACJ7F,EAAKgX,mBACxCW,EAASG,SAASvO,EAAcwO,UAAUhC,gBAAkB/S,EAAIuT,KAEpEe,EAAYjB,oBAAoBF,GAAc,EAAMwB,EAAU3U,EAAIgV,OAOvDV,EAAYC,oBAAoB/e,IAAYmf,KAoB/DpY,EAAa3N,UAAUqmB,sBAAwB,SAASC,EAAexnB,GACnE,GAAMynB,GAAmBD,EAAcE,mBAAqBzpB,KAAK8S,iBAIjE/Q,GAAOA,KACP,IAAMimB,GAAYjmB,EAAKimB,YAAa,CAEpC,IAAIwB,IACKxB,EACD,KAAM,IAAIlpB,OAAM,oDAIxB,IAAMwoB,GAAMU,EAAYpN,EAAc8O,UAAY9O,EAAcwO,SAE1DjjB,EAAQojB,EAAcI,mBAAmBrC,EAC/C,KAAKnhB,EAED,MAAO0N,GAAA9T,QAAQ+T,SAAQ,EAG3B,IAAMoU,GAAiBqB,EAAcK,oBAAoBtC,EAEzD,IAAIY,EAEA,MAAOA,EAGX,IAAIzhB,OAAA,GAAMjC,MAAA,GAAQsH,MAAA,GACZuF,EAAOrR,IAEb,IAAIwpB,EACA/iB,EAAO,iBACPjC,GACIwF,MAAQ,SAAWjI,GAAQA,EAAKiI,MAAQ,GACxC6f,KAAM,aAGN1jB,GAAmB,QAAVA,IACT3B,EAAO4K,KAAOjJ,GAGlB2F,EACI9L,KAAK8C,MAAMwD,4BAAwBrF,GAAW,MAAOwF,EAAMjC,MACvDvD,GAAWsB,EAAQ0D,iBACzBrC,KAAK,SAASyQ,GAIZ,IAAK,GAHClO,GAAQkO,EAAIyV,WACZtC,KAEG5oB,EAAI,EAAGA,EAAIyV,EAAI0V,cAAc5qB,OAAQP,IAAK,CAC/C,GAAMorB,GAAe3V,EAAI0V,cAAcnrB,GACjCgV,EAAQvC,EAAKgX,iBAAiB2B,EAAapW,MACjDA,GAAM4R,eACF/K,EAAcwP,0BAA0BD,EAAahc,UAEzD4F,EAAMA,MAAM9I,QAAUkf,EAAalf,QACnC0c,EAAa5oB,GAAKgV,EAYtB,MATA2V,GAAcE,iBACT/B,oBAAoBF,EAAcQ,EAAWuB,EAAepjB,GAK7D6hB,IAAc3T,EAAIyV,YAClBP,EAAcW,mBAAmB,KAAM5C,KAEpCjT,EAAIyV,aACZrB,QAAQ,WACPc,EAAcK,oBAAoBtC,GAAO,OAE7CiC,EAAcK,oBAAoBtC,GAAOxb,MACtC,CAEH,IADa9L,KAAKyR,QAAQ8X,EAAc7X,aAEpC,KAAM,IAAI5S,OAAM,gBAAkByqB,EAAc7X,YAGpDjL,GAAOzE,EAAM0E,UACT,2BAA4BM,QAASuiB,EAAc7X,cAEvDlN,GACI4K,KAAMjJ,EACN6D,MAAQ,SAAWjI,GAAQA,EAAKiI,MAAQ,GACxCsd,IAAKA,EAGT,IAAM6C,GAASZ,EAAca,WACzBD,KAGA3lB,EAAO2lB,QAAS,EAAAE,EAAAtqB,SAAeoqB,EAAOG,mCAG1Cxe,EACI9L,KAAK8C,MAAMa,kBAAc1C,GAAW,MAAOwF,EAAMjC,GACnDZ,KAAK,SAASyQ,GACZ,GAAMlO,GAAQkO,EAAIuT,IACZJ,EAAexlB,EAAMme,IAAI9L,EAAIoT,MAAOpW,EAAKgX,iBAU/C,OATAkB,GAAcE,iBACT/B,oBAAoBF,EAAcQ,EAAWuB,EAAepjB,GAK7D6hB,GAAa3T,EAAIuT,KAAOvT,EAAIgV,OAC5BE,EAAcW,mBAAmB,KAAM5C,GAEpCjT,EAAIuT,KAAOvT,EAAIgV,QACvBZ,QAAQ,WACPc,EAAcK,oBAAoBtC,GAAO,OAE7CiC,EAAcK,oBAAoBtC,GAAOxb,EAG7C,MAAOA,IAOX8E,EAAa3N,UAAUsnB,sBAAwB,WACtCvqB,KAAK8S,mBAcV9S,KAAK8S,kBAAkB0X,kBAAkB,MAAO,OAqBpD5Z,EAAa3N,UAAUwnB,WAAa,SAAS1jB,GAKzC,MAJI/G,MAAKwS,WACLxS,KAAKwS,UAAUkY,cAEnB1qB,KAAKwS,UAAY,GAAIwI,GAAQhb,KAAMA,KAAKihB,aACjCjhB,KAAKwS,UAAUmY,KAAK5jB,IAM/B6J,EAAa3N,UAAUynB,YAAc,WAC7B1qB,KAAKwS,YACLxS,KAAKwS,UAAUkY,cACf1qB,KAAKwS,UAAY,OAiBzB5B,EAAa3N,UAAU2nB,eAAiB,SAAS7jB,EAAQhF,GACrD,GAAM8oB,GAAe7qB,KAAK2J,eAAe5C,EAAQ,uBAC7C+jB,aAAc/oB,EAAKgpB,UAAY,WAAa,cAG5CC,EAAcnX,EAAA9T,QAAQ+T,SAO1B,OANI/R,GAAKkpB,YACLD,EAAchrB,KAAK2J,eAAe5C,EAAQ,6BACtCmkB,mBAAoB,oBAIrBrX,EAAA9T,QAAQyb,KAAKwP,EAAaH,KAyBrCja,EAAa3N,UAAUkoB,0BAA4B,SAAS7mB,EAAOiL,EACfC,EAAaC,GAC7D,MAAOzP,MAAKorB,0BACR,gCAEI9mB,MAAOA,EACPoL,cAAeH,EACfI,aAAcH,EACdI,UAAWH,KAkBvBmB,EAAa3N,UAAUooB,2BAA6B,SAASC,EAAcC,EACvBhc,EAAcC,EAAaC,GAC3E,MAAOzP,MAAKorB,0BACR,iCAEII,QAASF,EACTG,aAAcF,EACd7b,cAAeH,EACfI,aAAcH,EACdI,UAAWH,KAwBvBmB,EAAa3N,UAAUyoB,yBAA2B,SAASpnB,EAAOiL,EACdC,EAAaC,GAC7D,MAAOzP,MAAKorB,0BACR,oCAEI9mB,MAAOA,EACPoL,cAAeH,EACfI,aAAcH,EACdI,UAAWH,KAmBvBmB,EAAa3N,UAAU0oB,0BAA4B,SAASL,EAAcC,EACtBhc,EAAcC,EAAaC,GAC3E,MAAOzP,MAAKorB,0BACR,qCAEII,QAASF,EACTG,aAAcF,EACd7b,cAAeH,EACfI,aAAcH,EACdI,UAAWH,KAwBvBmB,EAAa3N,UAAU2oB,0BAA4B,SAAStnB,EAAOiL,EACfC,EAAaC,GAC7D,MAAOzP,MAAKorB,0BACR,wCAEI9mB,MAAOA,EACPoL,cAAeH,EACfI,aAAcH,EACdI,UAAWH,KAkBvBmB,EAAa3N,UAAU4oB,2BAA6B,SAASP,EAAcC,EACvBhc,EAAcC,EAAaC,GAC3E,MAAOzP,MAAKorB,0BACR,yCAEII,QAASF,EACTG,aAAcF,EACd7b,cAAeH,EACfI,aAAcH,EACdI,UAAWH,KAavBmB,EAAa3N,UAAUmoB,0BAA4B,SAASU,EAAUtnB,GAClE,GAAMunB,GAAgBpR,EAAIqR,MAAMhsB,KAAKmC,UACrC,IAA2B,OAAvB4pB,EAAcE,KACd,KAAM,IAAIntB,OAAM,0BAA4BkB,KAAKmC,UAGrD,IAAM+pB,IAAa,EAAAC,EAAApsB,YAAkByE,GACjCogB,UAAWmH,EAAcE,MAE7B,OAAOjsB,MAAK8C,MAAMvD,YACd0B,GAAW,OAAQ6qB,MAAU7qB,GAC7BirB,IAcRtb,EAAa3N,UAAUmpB,gBAAkB,SAAS5e,EAAOzG,GAGrD,IAAI/G,KAAKqsB,UAQL,KAAM,IAAIvtB,OACN,8DARJ,KAAK,GAAIF,GAAI,EAAGA,EAAIoB,KAAKqsB,UAAU7e,GAAOgE,KAAKrS,OAAQP,IAAK,CACxD,GAAM0tB,GAAOtsB,KAAKqsB,UAAU7e,GAAOgE,KAAK5S,EACxC,IAAI0tB,EAAKC,UAAYxlB,EACjB,MAAOulB,KAmBvB1b,EAAa3N,UAAUupB,oBAAsB,SAAShf,EAAOzG,EAAQ0lB,GACjE,GAAMpb,GAAOrR,KACT0sB,MAAA,GAAUC,MAAA,GAGRC,EAAe5sB,KAAKosB,gBAAgB5e,EAAOzG,EAsCjD,IArCI6lB,GACI,GAAKA,EAAa5e,QAAQqI,QAAQ,iBAClCsW,GAAoB,GAIvBF,EAMIG,EAIOD,IAGRD,EAAW7Y,EAAA9T,QAAQmZ,QACnBlZ,KAAK4N,eAAeJ,EAAO,OAAQof,EAAaL,SAC/CjrB,KAAK,WACF+P,EAAK9D,YAAYC,EAAO,OAAQzG,GAC5BiH,SAAU,iBACX1M,KAAK,WACJorB,EAAS5Y,WACV,SAASlS,GACR8qB,EAASvT,OAAOvX,MAErB,SAASA,GACR8qB,EAASvT,OAAOvX,KAGpB8qB,EAAWA,EAAS5gB,SApBpB4gB,EAAW1sB,KAAKuN,YAAYC,EAAO,OAAQzG,GACvCiH,SAAU,iBANd2e,IACAD,EAAW1sB,KAAK4N,eAAeJ,EAAO,OAAQof,EAAaL,UA4B/DG,EAAU,CAEV,GAAMG,GAAsBhZ,EAAA9T,QAAQmZ,OAkBpC,OAjBAwT,GAASprB,KAAK,WACV+P,EAAK/D,eAAehM,KAAK,SAASwrB,GAC9Bzb,EAAKgb,UAAYS,EACjBD,EAAoB/Y,WACrB,SAASlS,GACRirB,EAAoB1T,OAAOvX,MAEhC,SAASA,GAGRyP,EAAK/D,eAAehM,KAAK,SAASwrB,GAC9Bzb,EAAKgb,UAAYS,EACjBD,EAAoB1T,OAAOvX,IAC5B,SAASiT,GACRgY,EAAoB1T,OAAOvX,OAG5BirB,EAAoB/gB,UAiBnC8E,EAAa3N,UAAU8pB,kBAAoB,SAAShrB,EAAMsC,GACtD,GAAM2oB,IACFvhB,YAAa1J,EAAK+M,MAOtB,OAJI,QAAU/M,KACVirB,EAAW1N,KAAOvd,EAAKud,MAGpBtf,KAAKiO,QACRjJ,MACIioB,mBACIC,YAAaF,KAGtB3oB,IAuBPuM,EAAa3N,UAAUkqB,iBAAmB,SAASprB,GAG/C,GAAMiD,IACFioB,mBACIC,aACIzhB,YAAa1J,EAAK2J,KAClBye,OAAQpoB,EAAKooB,OACbiD,SAAU,SACVC,eACIC,aAAc,EACdC,YAAa,EACbC,iBAAiB,MAM3BC,GACFC,OAAQ1oB,EACR2oB,WACAC,cAGJ,OAAO5tB,MAAKiO,QAAQjJ,KAAMA,IAAOpB,KAC7B5D,KAAK6tB,yBAAyBpsB,KAAKzB,KAAMytB,KAWjD7c,EAAa3N,UAAU6qB,6BAA+B,SAASL,GAI3D,IAAKA,EAActf,WACf,MAAO0F,GAAA9T,QAAQoZ,OAAO,GAAIra,OAAM,gDAGpC,IAAI2uB,EAAcvF,eAEd,MAAOuF,GAAcvF,cAGzB,IAAM6F,IACF/oB,KAAMyoB,EAAcC,OACpBvf,WAAYsf,EAActf,YAGxBrC,EAAU9L,KAAKiO,OAAO8f,GAAYnqB,KACpC5D,KAAK6tB,yBAAyBpsB,KAAKzB,KAAMytB,IAC3ChF,QAAQ,WACNgF,EAAcvF,eAAiB,MAInC,OAFAuF,GAAcvF,eAAiBpc,EAExBA,GAYX8E,EAAa3N,UAAU4qB,yBAA2B,SAASJ,EAAe5pB,GACtE,GAAMqpB,GAAcrpB,EAASopB,kBAAkBC,WAE/CO,GAAcO,MAAQd,EAAYc,MAClCP,EAActf,WAAa+e,EAAY/e,UAIvC,IAAMyf,KACNV,GAAYU,WAAWnf,QAAQ,SAASwf,GACpCL,EAAWK,GAAM,IAErBR,EAAcG,WAAWnf,QAAQ,SAASwf,GACtCL,EAAWK,GAAM,IAIrBR,EAAcG,YAAa,EAAAljB,EAAA3K,SAAY6tB,EAGvC,KAAK,GAAIhvB,GAAI,EAAGA,EAAIsuB,EAAYS,QAAQxuB,OAAQP,IAAK,CACjD,GAAMsvB,GAAKrT,EAAasT,SAASjB,EAAYS,QAAQ/uB,GAAIoB,KAAKqoB,iBAC9DoF,GAAcE,QAAQ/W,KAAKsX,GAE/B,MAAOT,IAUX7c,EAAa3N,UAAUmrB,cAAgB,WAEnC,GAAIpuB,KAAKquB,iBACL,MAAOxa,GAAA9T,QAAQ+T,WAEnB,IAAI9T,KAAKsuB,sBACL,MAAOtuB,MAAKsuB,qBAEhB,IAAMjd,GAAOrR,KACPghB,EAAU,GAAIhG,GAAQhb,KAAMA,KAAKihB,YAWvC,OAVAjhB,MAAKsuB,sBAAwBtN,EAAQoN,gBAGrCpuB,KAAKsuB,sBAAsB1qB,KAAK,SAASyQ,GACrCI,QAAQe,IAAI,6CACZnE,EAAKgd,kBAAmB,IACzB5F,QAAQ,WACPpX,EAAKid,sBAAwB,OAG1BtuB,KAAKsuB,uBAYhB1d,EAAa3N,UAAUsrB,aAAe,SAASxlB,GAC3C,GAAMsI,GAAOrR,KACPyG,EAAOzE,EAAM0E,UAAU,wBACzBkB,QAAS5H,KAAKmR,YAAYxJ,QAE9B,OAAO3H,MAAK8C,MAAMa,kBACd1C,GAAW,OAAQwF,MAAMxF,GAAW8H,GACtCnF,KAAK,SAASC,GAEZ,GAAMsmB,GAASpP,EAAOoT,SAClB9c,EAAKF,YAAYxJ,OAAQ9D,EAAS2qB,UAAWzlB,EAGjD,OADAsI,GAAKJ,MAAMwd,YAAYtE,GAChBA,KAafvZ,EAAa3N,UAAUmnB,UAAY,SAASziB,EAAQ+mB,EAAUC,GAC1D,GAAIA,EAAa,CACb,GAAMxE,GAASnqB,KAAKiR,MAAMmZ,UAAUziB,EAAQ+mB,EAC5C,IAAIvE,EACA,MAAOtW,GAAA9T,QAAQ+T,QAAQqW,GAI/B,GAAM9Y,GAAOrR,KACPyG,EAAOzE,EAAM0E,UAAU,kCACzBkB,QAASD,EACTinB,UAAWF,GAGf,OAAO1uB,MAAK8C,MAAMa,kBACd1C,GAAW,MAAOwF,MAAMxF,OAAWA,IACrC2C,KAAK,SAASC,GAEZ,GAAMsmB,GAASpP,EAAOoT,SAClBxmB,EAAQ+mB,EAAU7qB,EAGtB,OADAwN,GAAKJ,MAAMwd,YAAYtE,GAChBA,KASfvZ,EAAa3N,UAAU4rB,kBAAoB,SAASC,EAAY3E,GAC5D,GAAMuE,GAAW1uB,KAAKiR,MAAM8d,kBAAkBD,GAC1ChjB,EAAU+H,EAAA9T,QAAQ+T,UAChBzC,EAAOrR,IAyCb,OAvCI0uB,KAEA5iB,EAAUuF,EAAK+Y,UAAU/Y,EAAKF,YAAYxJ,OACzB+mB,GAAU,GACzB9qB,KAAK,SAASorB,GACZ,GAAMC,GAASD,EAAeE,gBACxBC,EAAShF,EAAO+E,eAEtB,IAAIltB,EAAMotB,YAAYH,EAAQE,GAI1B,MAAOtb,GAAA9T,QAAQ+T,QAAQ4a,EAI3Brd,GAAKJ,MAAMoe,kBAAkBP,MAAY7tB,KAE1C,SAASyT,GAQR,GAAyB,MAArBA,EAAM4a,YACa,cAAlB5a,EAAMmQ,SAA6C,gBAAlBnQ,EAAMmQ,QAOxC,KAAMnQ,EAFN,YAFArD,GAAKJ,MAAMoe,kBAAkBP,MAAY7tB,OAS9C6K,EAAQlI,KAAK,SAAS2rB,GACzB,MAAIA,IAKGle,EAAKkd,aAAapE,EAAO+E,iBAC9BtrB,KAAK,SAAS4rB,GAIZ,MADAne,GAAKJ,MAAMoe,kBAAkBP,EAAYU,EAAcd,UAChDc,EAAcd,cAajC9d,EAAa3N,UAAUwsB,eAAiB,WACpC,GAAMhpB,GAAOzE,EAAM0E,UAAU,sCACzBkB,QAAS5H,KAAKmR,YAAYxJ,QAG9B,OAAO3H,MAAK8C,MAAMa,kBACd1C,GAAW,OAAQwF,MAAMxF,QAajC2P,EAAa3N,UAAUuV,WAAa,SAASnU,GACzC,MAAOrE,MAAK8C,MAAMa,cAAcU,EAAU,MAAO,qBAOrDuM,EAAa3N,UAAUysB,eAAiB,WACpC,MAAO1vB,MAAK8Y,kBA6ChBlI,EAAa3N,UAAU0sB,YAAc,SAAS5tB,GAAM,GAAA6tB,GAAA5vB,IAC5CA,MAAKgS,gBAIThS,KAAKgS,eAAgB,EAED,gBAATjQ,KACPA,GACI8tB,iBAAkB9tB,IAItB/B,KAAK+S,UACL/S,KAAK+S,QAAQsK,mBAAmB/b,OAChCtB,KAAK+S,QAAQsW,SAIjB/Q,EAAiBtY,MAEbA,KAAKuS,WAELkC,QAAQC,MAAM,+DACd1U,KAAKuS,SAASgI,QAIlBxY,GAAO,EAAAoqB,EAAApsB,YAAkBgC,GAEzBA,EAAK8a,OAAS7c,KAAK+S,QACnBhR,EAAK+tB,uBAAyB,SAAC/oB,GAC3B,QAAK6oB,EAAKG,2BAGHH,EAAKG,0BAA0BhpB,IAE1C/G,KAAKihB,YAAclf,EAEnB/B,KAAKuS,SAAW,GAAIyI,GAAQhb,KAAM+B,GAClC/B,KAAKuS,SAASyd,SAOlBpf,EAAa3N,UAAUgtB,WAAa,WAChCxb,QAAQe,IAAI,yBAEZxV,KAAKgS,eAAgB,EAEjBhS,KAAKuS,WACLvS,KAAKuS,SAASgI,OACdva,KAAKuS,SAAW,MAEhBvS,KAAK+S,SACL/S,KAAK+S,QAAQwH,OAEbva,KAAKwS,WACLxS,KAAKwS,UAAUkY,cAEnBjrB,EAAOywB,aAAalwB,KAAK+Y,6BAY7BnI,EAAa3N,UAAUktB,4BAA8B,SAASC,GAC1DpwB,KAAK+vB,0BAA4BK,GAOrCxf,EAAa3N,UAAUotB,4BAA8B,WACjD,MAAOrwB,MAAK+vB,2BA2QhBnf,EAAa3N,UAAUolB,eAAiB,WACpC,MAAOhP,GAAyBrZ,OAWpC4Q,EAAa3N,UAAUqtB,qBAAuB,WAI1C,IAAK,GAHDC,GAAM,GACJC,EAAQ,iEAEL5xB,EAAI,EAAGA,EAAI,GAAIA,IACpB2xB,GAAOC,EAAMC,OAAOxJ,KAAKyJ,MAAMzJ,KAAK0J,SAAWH,EAAMrxB,QAGzD,OAAOoxB,IAIXlxB,EAAOJ,QAAQ2R,aAAeA,EAE9BvR,EAAOJ,QAAQqU,eAAiBA,8kBC5xGhC,IAAMtR,GAAQrD,EAAQ,UAGtBU,GAAOJ,SAeHonB,iBAAkB,SAASnkB,EAAS0uB,EAAK3K,EAAOC,EACrBC,EAAcC,GACrC,GAAmB,gBAARwK,KAAqBA,EAC5B,MAAO,EAEX,IAA8B,IAA1BA,EAAIva,QAAQ,UACZ,MAAI+P,GACOwK,EAEA,EAGf,IAAIC,GAAmBD,EAAIE,MAAM,GAC7BxuB,EAAS,8BACPkC,IAEFyhB,KACAzhB,EAAOyhB,MAAQA,GAEfC,IACA1hB,EAAO0hB,OAASA,GAEhBC,IACA3hB,EAAO0R,OAASiQ,GAEhBnkB,EAAMsd,KAAK9a,GAAQrF,OAAS,IAG5BmD,EAAS,+BAGb,IAAMyuB,GAAiBF,EAAiBxa,QAAQ,KAC5C2a,EAAW,EAKf,OAJID,IAAkB,IAClBC,EAAWH,EAAiB/f,OAAOigB,GACnCF,EAAmBA,EAAiB/f,OAAO,EAAGigB,IAE3C7uB,EAAUI,EAASuuB,GACS,IAA9B7uB,EAAMsd,KAAK9a,GAAQrF,OAAe,GAClC,IAAM6C,EAAMivB,aAAazsB,IAAYwsB,GAW9CE,gBAAiB,SAAShvB,EAASivB,EAAiBlL,EAAOC,GACvD,IAAKiL,EACD,MAAO,KAENlL,KACDA,EAAQ,IAEPC,IACDA,EAAS,GAEb,IAAM1hB,IACFyhB,MAAOA,EACPC,OAAQA,EAMZ,OAAOhkB,GAHMF,EAAM0E,UAAU,sCACzB0qB,OAAQD,KAGuB,IAA9BnvB,EAAMsd,KAAK9a,GAAQrF,OAAe,GAC9B,IAAM6C,EAAMivB,aAAazsB,0CC3F1C,0aA8hBA,QAAAmV,GAA8C0X,EAAY1pB,EAAQ2pB,EAC1DC,GADR,GAAAC,GAAAnjB,EAAAojB,EAAAC,CAAA,OAAA1X,GAAAja,QAAAka,KAAA,SAAAC,GAAA,OAAA,OAAAA,EAAAC,KAAAD,EAAA7Y,MAAA,IAAA,GAEQmwB,GAAU,EAFlBtX,EAAAyX,GAAA3X,EAAAja,QAAAuf,KAK2BgS,EAL3B,KAAA,GAAA,IAAApX,EAAA0X,GAAA1X,EAAAyX,MAAArwB,KAAA,CAAA4Y,EAAA7Y,KAAA,CAAA,OAAA,GAKegN,EALf6L,EAAA0X,GAAArwB,MAMa+vB,EAAUO,eAAexjB,GANtC,CAAA6L,EAAA7Y,KAAA,CAAA,OAAA,MAAA6Y,GAAA6C,OAAA,WAAA,EAAA,KAAA,GAUc1O,IAAYkjB,KACd9c,QAAQe,IAAI,UAAY7N,EAAS,IAAM0G,EACnC,2BACGijB,GAAUjjB,GACjBmjB,GAAU,GAdtBtX,EAAA7Y,KAAA,CAAA,MAAA,KAAA,GAAA6Y,EAAA4X,GAAA9X,EAAAja,QAAAuf,KAkB2BiS,EAlB3B,KAAA,IAAA,IAAArX,EAAA6X,GAAA7X,EAAA4X,MAAAxwB,KAAA,CAAA4Y,EAAA7Y,KAAA,EAAA,OAAA,GAkBeowB,EAlBfvX,EAAA6X,GAAAxwB,MAmBagwB,EAAWM,eAAeJ,GAnBvC,CAAAvX,EAAA7Y,KAAA,EAAA,OAAA,MAAA6Y,GAAA6C,OAAA,WAAA,GAAA,KAAA,IAAA,GAuBc2U,EAAeH,EAAWE,GAI5BC,EAAa1b,UAAYrO,EA3BrC,CAAAuS,EAAA7Y,KAAA,EAAA,OAAA,MA4BYoT,SAAQyG,KAAK,sBAAwBwW,EAAa1b,QAC/C,iBAAmBrO,EAAS,IAAM8pB,GA7BjDvX,EAAA6C,OAAA,WAAA,GAAA,KAAA,IAAA,GAgCY2U,EAAa1kB,YAAcykB,EAhCvC,CAAAvX,EAAA7Y,KAAA,EAAA,OAAA,MAiCYoT,SAAQyG,KAAK,wBAA0BwW,EAAa1kB,UACjD,iBAAmBrF,EAAS,IAAM8pB,GAlCjDvX,EAAA6C,OAAA,WAAA,GAAA,KAAA,IAAA,MAAA7C,GAAA7Y,KAAA,IAAA,EAAA+Y,EAAAtG,SAsCkBke,EAAiBX,EAAYC,EAAWI,GAtC1D,KAAA,IAAA,IAAAxX,EAAAI,KAAA,CAAAJ,EAAA7Y,KAAA,EAAA,OAuCYmwB,GAAU,CAvCtB,KAAA,IAAAtX,EAAA7Y,KAAA,EAAA,MAAA,KAAA,IAAA,MAAA6Y,GAAA6C,OAAA,SA2CWyU,EA3CX,KAAA,IAAA,IAAA,MAAA,MAAAtX,GAAAK,SAAAZ,EAAA3Z,uHAmDA,QAAA0e,GAAgC2S,EAAYC,EAAWI,GAAvD,GAAArjB,GAAA1G,EAAAsqB,EAAAC,EAAAC,EAAAC,CAAA,OAAApY,GAAAja,QAAAka,KAAA,SAAA2E,GAAA,OAAA,OAAAA,EAAAzE,KAAAyE,EAAAvd,MAAA,IAAA,GAAA,GACSqwB,EAAapS,KADtB,CAAAV,EAAAvd,KAAA,CAAA,OAAA,MAAAud,GAAA7B,OAAA,UAGe,EAHf,KAAA,GAAA,GAMU1O,EAAWqjB,EAAa1kB,UACxBrF,EAAS+pB,EAAa1b,QAEtBic,EAAY,WAAa5jB,EACzB6jB,EAAUR,EAAapS,KAAK2S,GAVtC,CAAArT,EAAAvd,KAAA,CAAA,OAAA,MAYQoT,SAAQyG,KAAK,UAAYvT,EAAS,IAAM0G,EACpC,uBAbZuQ,EAAA7B,OAAA,UAce,EAdf,KAAA,GAAA,MAiBUoV,GAAWT,EAAaS,aAjBlCvT,EAAAzE,KAAA,GAAAyE,EAAAvd,KAAA,IAAA,EAAA+Y,EAAAtG,SAoBcue,EAAAtyB,QAAOuyB,gBAAgBjB,EAAYK,EAAc/pB,EAAQ0G,EAAU6jB,GApBjF,KAAA,IAAAtT,EAAAvd,KAAA,EAAA,MAAA,KAAA,IAAA,MAAAud,GAAAzE,KAAA,GAAAyE,EAAA+S,GAAA/S,EAAA,MAAA,IAsBQnK,QAAQyG,KAAK,wCACTvT,EAAS,IAAM0G,EAAW,IADjBuQ,EAAA+S,IAtBrB/S,EAAA7B,OAAA,UAwBe,EAxBf,KAAA,IAAA,GA4BQqV,MA5BR,KA8BQ/jB,IAAYijB,IA9BpB,CAAA1S,EAAAvd,KAAA,EAAA,OAAA,GAgCQ+wB,EAAcd,EAAUjjB,GAEpB+jB,EAAYG,kBAAoBL,EAlC5C,CAAAtT,EAAAvd,KAAA,EAAA,OAAA,MAuCYoT,SAAQyG,KAAK,0BAA4BvT,EAAS,IAC/C0G,EAAW,gBAxC1BuQ,EAAA7B,OAAA,UAyCmB,EAzCnB,KAAA,IAAA6B,EAAAvd,KAAA,EAAA,MAAA,KAAA,IA4CQiwB,EAAUjjB,GAAY+jB,EAAc,GAAAI,GAAAzyB,QAAesO,EA5C3D,KAAA,IAAA,MA+CI+jB,GAAY9S,KAAOoS,EAAapS,SAChC8S,EAAYK,WAAaf,EAAae,eACtCL,EAAYD,SAAWA,EAjD3BvT,EAAA7B,OAAA,UAkDW,EAlDX,KAAA,IAAA,IAAA,MAAA,MAAA6B,GAAArE,SAAAmE,EAAA1e,OAAA,GAAA,mEAvkBA0yB,EAAA/zB,EAAA,uBACAg0B,EAAAh0B,EAAA,mBA0BMi0B,EAAmC,EACnCC,EAAuC,EAMxBC,aACjB,QAAAA,GAAYC,EAAU5f,EAAc6f,IAAW,EAAAlzB,EAAAC,SAAAC,KAAA8yB,GAC3C9yB,KAAKkT,cAAgBC,EACrBnT,KAAKizB,YAAc,GAAIC,GACnBH,EAAU5f,EAAc6f,GAK5BhzB,KAAKmzB,sBAAwBhgB,EAAaigB,qCARC,IAAAtyB,IAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KAS3C,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,UAAgB,EAAA2K,EAAA3K,SAAYC,KAAKmzB,0BAAjCryB,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAAyD,CAAA,GAA9CrC,GAA8CyC,EAAAK,KAEjDvB,MAAKmzB,sBAAsB10B,IAAMo0B,IACjC7yB,KAAKmzB,sBAAsB10B,GAAKm0B,IAZG,MAAAhxB,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,IAiB3ChB,KAAKqzB,iCAELrzB,KAAKszB,mBAAqB,+DAYjBrqB,EAASsU,GAAe,GAAAqS,GAAA5vB,KAC3BuzB,KACAjY,IAiBN,IAfArS,EAAQwF,QAAQ,SAAChQ,GACb,GAAM+0B,GAAiB5D,EAAKuD,sBAAsB10B,EAC9CmxB,GAAKyD,8BAA8B50B,IAGnCgW,QAAQe,IACJ,yDACG/W,EADH,yBAGJ6c,EAAS1E,KAAKgZ,EAAKyD,8BAA8B50B,MAC1C8e,GAnDY,GAmDKiW,IACxBD,EAAgB3c,KAAKnY,KAIC,GAA1B80B,EAAgBp0B,OAAa,CAC7BsV,QAAQe,IAAI,gCAAiC+d,EAC7C,IAAME,GAAkBzzB,KAAK0zB,eAAeH,EAC5CjY,GAAS1E,KAAK6c,GAOlB,MAJwB,KAApBnY,EAASnc,QACTsV,QAAQe,IAAI,iDAGT3B,EAAA9T,QAAQyb,IAAIF,GAAU1X,KAAK,WAC9B,MAAOgsB,GAAK+D,qBAAqB1qB,kDAWpBA,GACjB,GAAM2qB,MACAviB,EAAOrR,IAQb,OAPAiJ,GAAQkX,IAAI,SAAS1hB,GACjBm1B,EAAOn1B,OACS4S,EAAKmM,wBAAwB/e,QACrC0hB,IAAI,SAASpG,GACjB6Z,EAAOn1B,GAAGsb,EAAI1L,UAAY0L,MAG3B6Z,kDAWajsB,GACpB,GAAMksB,GAAO7zB,KAAKkT,cAAc4gB,0BAA0BnsB,EAC1D,KAAKksB,EACD,MAAO,KAEX,IAAMxf,KACN,KAAK,GAAMhG,KAAYwlB,GACfA,EAAKhC,eAAexjB,IACpBgG,EAAIuC,KAAK4b,EAAAzyB,QAAWg0B,YAAYF,EAAKxlB,GAAWA,GAGxD,OAAOgG,2CAYK1M,EAAQ0G,GACpB,GAAMwlB,GAAO7zB,KAAKkT,cAAc4gB,0BAA0BnsB,EAC1D,IAAKksB,GAASA,EAAKxlB,GAGnB,MAAOmkB,GAAAzyB,QAAWg0B,YAAYF,EAAKxlB,GAAWA,kDAY3B1G,EAAQqsB,EAAWC,GACtC,GACID,IAAc3B,EAAAtyB,QAAOm0B,eACrBF,IAAc3B,EAAAtyB,QAAOo0B,iBAGrB,MAAO,KAGX,IAAMxlB,GAAU3O,KAAKkT,cAAc4gB,0BAA0BnsB,EAC7D,KAAKgH,EACD,MAAO,KAGX,KAAK,GAAMN,KAAYM,GACnB,GAAKA,EAAQkjB,eAAexjB,GAA5B,CAIA,GAAMsQ,GAAShQ,EAAQN,EACvB,KAAK,GAAM+lB,KAASzV,GAAOW,KACvB,GAAKX,EAAOW,KAAKuS,eAAeuC,IAGK,IAAjCA,EAAM/d,QAAQ,eAAlB,CAGA,GAAMge,GAAY1V,EAAOW,KAAK8U,EAC9B,IAAIC,GAAaJ,EACb,MAAOzB,GAAAzyB,QAAWg0B,YAAYpV,EAAQtQ,IAMlD,MAAO,sDAYa1G,GAQpB,GAAsB,gBAAXA,GACP,KAAM,IAAI7I,OAAM,gCAAgC6I,EAE/C3H,MAAKmzB,sBAAsBxrB,KAC5B8M,QAAQe,IAAI,gCAAkC7N,GAC9C3H,KAAKmzB,sBAAsBxrB,GAAUirB,kDAgBtBjrB,GACf3H,KAAKmzB,sBAAsBxrB,KAC3B8M,QAAQe,IAAI,sCAAwC7N,GACpD3H,KAAKmzB,sBAAsBxrB,GA7NH,oDAgPPA,GACjB3H,KAAKmzB,sBAAsBxrB,KAC3B8M,QAAQe,IAAI,mCAAoC7N,GAChD3H,KAAKmzB,sBAAsBxrB,GAAUirB,sDAalB,GAAA0B,IAAA,EAAAC,GAAA,EAAAC,MAAAvzB,EAAA,KACvB,IAAA,GAAAwzB,GAAAC,GAAA,EAAAtzB,EAAArB,UAAqB,EAAA2K,EAAA3K,SAAYC,KAAKmzB,0BAAtCmB,GAAAG,EAAAC,EAAArzB,QAAAC,MAAAgzB,GAAA,EAA8D,CAAA,GAAnD3sB,GAAmD8sB,EAAAlzB,KAC1DvB,MAAK20B,yBAAyBhtB,IAFX,MAAA/F,GAAA2yB,GAAA,EAAAC,EAAA5yB,EAAA,QAAA,KAAA0yB,GAAAI,EAAA7yB,QAAA6yB,EAAA7yB,SAAA,QAAA,GAAA0yB,EAAA,KAAAC,0DAavB,GAAMjB,MADmBqB,GAAA,EAAAC,GAAA,EAAAC,MAAA7zB,EAAA,KAEzB,IAAA,GAAA8zB,GAAAC,GAAA,EAAA5zB,EAAArB,UAAqB,EAAA2K,EAAA3K,SAAYC,KAAKmzB,0BAAtCyB,GAAAG,EAAAC,EAAA3zB,QAAAC,MAAAszB,GAAA,EAA8D,CAAA,GAAnDjtB,GAAmDotB,EAAAxzB,KAC7CvB,MAAKmzB,sBAAsBxrB,IAC5BirB,GACRW,EAAgB3c,KAAKjP,IALJ,MAAA/F,GAAAizB,GAAA,EAAAC,EAAAlzB,EAAA,QAAA,KAAAgzB,GAAAI,EAAAnzB,QAAAmzB,EAAAnzB,SAAA,QAAA,GAAAgzB,EAAA,KAAAC,IAazB,MAFA90B,MAAKi1B,+BAEEj1B,KAAK0zB,eAAeH,0CAehBpR,GAAO,GAAA+S,GAAAl1B,IAClB,IAAqB,IAAjBmiB,EAAMhjB,OAEN,MAAO0U,GAAA9T,QAAQ+T,SAGnB,IAAMqhB,GAAOn1B,KAAKizB,YAAYmC,sBAC1BjT,EAAOniB,KAAKszB,oBACd1vB,KAAK,WACHyxB,GAAS,IACV,SAACl3B,GAKA,KAJAsW,SAAQC,MACJ,8BAAgCyN,EAAQ,IAAKhkB,GAEjDk3B,GAAS,GACHl3B,GAGVgkB,GAAM1T,QAAQ,SAAChQ,GACXy2B,EAAK7B,8BAA8B50B,GAAK02B,EAC3BD,EAAK/B,sBAAsB10B,IAC5Bm0B,IACRsC,EAAK/B,sBAAsB10B,GAAKo0B,IAIxC,IAAMwC,GAAW,SAACC,GACdnT,EAAM1T,QAAQ,SAAChQ,GAIX,GAAIy2B,EAAK7B,8BAA8B50B,KAAO02B,EAG1C,WAFA1gB,SAAQe,IAAI,kCAAmC/W,EACnC,kCAGTy2B,GAAK7B,8BAA8B50B,GAC7By2B,EAAK/B,sBAAsB10B,IAC5Bo0B,IACJyC,GAGAJ,EAAK/B,sBAAsB10B,GA/UhB,EAgVXgW,QAAQe,IAAI,kBAAmB/W,EAAG,mBAElCy2B,EAAK/B,sBAAsB10B,GAAKm0B,KAI5CsC,EAAKD,+BAGT,OAAOE,0DAIPn1B,KAAKkT,cAAcqiB,kCAAkCv1B,KAAKmzB,0CAxV7CL,KAqWfI,cACF,QAAAA,GAAYH,EAAU5f,EAAc6f,IAAW,EAAAlzB,EAAAC,SAAAC,KAAAkzB,GAC3ClzB,KAAKw1B,UAAYzC,EACjB/yB,KAAKkT,cAAgBC,EACrBnT,KAAKqxB,WAAa2B,EAElBhzB,KAAKy1B,qBAAsB,EAI3Bz1B,KAAK01B,6BAKL11B,KAAK21B,qBAAuB,KAI5B31B,KAAK41B,eAAiB,wEAeJzT,EAAO0T,GAAW,GAAAC,GAAA91B,IAUpC,OATAmiB,GAAM1T,QAAQ,SAAChQ,GACXq3B,EAAKJ,0BAA0Bj3B,IAAK,IAExCuB,KAAK41B,eAAiBC,EAEjB71B,KAAK21B,uBACN31B,KAAK21B,qBAAuB9hB,EAAA9T,QAAQmZ,SAGpClZ,KAAKy1B,qBAELhhB,QAAQe,IAAI,0BAA2B2M,GAChCniB,KAAK21B,qBAAqB7pB,SAI9B9L,KAAK+1B,8DAGG,GAAAC,GAAAh2B,IACf,IAAIA,KAAKy1B,oBACL,KAAM,IAAI32B,OACN,yEAIR,IAAMm3B,IAAgB,EAAAvrB,EAAA3K,SAAYC,KAAK01B,0BACvC11B,MAAK01B,4BACL,IAAMhJ,GAAW1sB,KAAK21B,oBACtB31B,MAAK21B,qBAAuB,KAE5BlhB,QAAQe,IAAI,4BAA6BygB,GACzCj2B,KAAKy1B,qBAAsB,CAE3B,IAAM1zB,KAuCN,OAtCI/B,MAAK41B,iBACL7zB,EAAKoE,MAAQnG,KAAK41B,gBAGtB51B,KAAKw1B,UAAUjnB,qBACX0nB,EAAel0B,GACjB6B,KAAK,SAACyQ,GACJ,GAAM6hB,GAAK7hB,EAAI7F,gBAOX2mB,EAAOthB,EAAA9T,QAAQ+T,UARPqiB,GAAA,EAAAC,GAAA,EAAAC,MAAAp1B,EAAA,KASZ,IAAA,GAAAq1B,GAAAC,GAAA,EAAAn1B,EAAArB,SAAqBk2B,KAArBE,GAAAG,EAAAC,EAAAl1B,QAAAC,MAAA60B,GAAA,GATY,WAAA,GASDxuB,GATC2uB,EAAA/0B,KAUR4zB,GAAOA,EAAK5N,MAAM,GAAG3jB,KAAK,WACtB,MAAOoyB,GAAKQ,6BAA6B7uB,EAAQuuB,EAAGvuB,SAXhD,MAAA/F,GAAAw0B,GAAA,EAAAC,EAAAz0B,EAAA,QAAA,KAAAu0B,GAAAI,EAAA10B,QAAA00B,EAAA10B,SAAA,QAAA,GAAAu0B,EAAA,KAAAC,IAeZ,MAAOlB,KACR7zB,KAAK,WACJmT,QAAQe,IAAI,8BAAgCygB,GAE5CD,EAAKP,qBAAsB,EAC3B/I,EAAS5Y,UAGLkiB,EAAKL,sBACLK,EAAKD,oBAEV,SAAC53B,GACAsW,QAAQyG,KAAK,8BAAgC+a,EAAgB,IAAK93B,GAClE63B,EAAKP,qBAAsB,EAC3B/I,EAASvT,OAAOhb,KAGbuuB,EAAS5gB,8JAGenE,EAAQ9D,yFACvC4Q,SAAQe,IAAI,gBAAkB7N,EAAS,IAAK9D,GAGtCytB,KACAuC,EAAO7zB,KAAKkT,cAAc4gB,0BAA0BnsB,GACtDksB,IACA,EAAAnpB,EAAA3K,SAAY8zB,GAAMplB,QAAQ,SAACJ,GACvB,GAAMooB,GAAIjE,EAAAzyB,QAAWg0B,YAAYF,EAAKxlB,GAAWA,EACjDijB,GAAUjjB,GAAYooB,2BAIxBC,EACF12B,KAAKqxB,WAAY1pB,EAAQ2pB,EAAWztB,eAIlC8yB,MACN,EAAAjsB,EAAA3K,SAAYuxB,GAAW7iB,QAAQ,SAACJ,GAC5BsoB,EAAQtoB,GAAYijB,EAAUjjB,GAAUuoB,cAG5C52B,KAAKkT,cAAc2jB,4BACflvB,EAAQgvB,oVCxhBpB,gEAkBA,QAASG,GAAmBC,GACxB,OAAsB91B,KAAlB81B,EACA,KAAM,IAAIj4B,OAAM,0BAGpB,IAAIi4B,EAAc53B,OAAS63B,EAOvB,KAAM,IAAIl4B,OAAM,qBAAuBi4B,EAAc53B,OAAS,oDAE9C63B,EAAuB,WAkC/C,QAASC,GAAU9jB,GACfnT,KAAKkT,cAAgBC,EACrBnT,KAAKk3B,WAAa,cAGlBl3B,KAAKm3B,oBAAsB,KAC3Bn3B,KAAKo3B,iBAAmB,KACxBp3B,KAAKq3B,gBAAkB,KAIvBr3B,KAAKs3B,8BAkBLt3B,KAAKu3B,sCA6BT,QAASC,GAAoBrkB,EAAcskB,EAAWC,GAClD,GAAMC,GAAaxkB,EAAaykB,oBAChC,IAAmB,OAAfD,EAEA,WADAD,GAAQG,SAASJ,EAAWE,EAIhCD,GAAQI,QACR,IAAMC,GAAUL,EAAQM,OAAOP,EAC/BtkB,GAAa8kB,qBAAqBF,kHA9HhCG,EAAMz4B,EAAOy4B,GACnB,KAAKA,EACD,KAAM,IAAIp5B,OAAM,4BAEpB,IAAMkD,GAAQrD,EAAQ,YAKhBq4B,EAAuB,KA2F7BC,GAAUh0B,UAAU+Z,MAApB,EAAA5C,EAAAlE,QAA2B,WACvB,GAAIiiB,OAAA,GACET,EAAU,GAAIQ,GAAIE,OACxB,KACIZ,EAAoBx3B,KAAKkT,cAAelT,KAAKk3B,WAAYQ,GACzDS,EAAUE,KAAKrM,MAAM0L,EAAQY,iBAE7Bt4B,KAAKq3B,gBAAkBK,EAAQa,8BAJnC,QAMIb,EAAQc,OAGZx4B,KAAKm3B,oBAAsBgB,EAAQM,WACnCz4B,KAAKo3B,iBAAmBe,EAAQO,UAmBpCzB,EAAUxjB,cAAgB,WACtB,MAAOykB,GAAIS,uBAWf1B,EAAUh0B,UAAU21B,YAAc,SAASC,GACvC,GAAMnB,GAAU,GAAIQ,GAAIE,OACxB,KACI,GAAMU,GAAiB94B,KAAKkT,cAAc0kB,oBAE1C,OADAF,GAAQG,SAAS73B,KAAKk3B,WAAY4B,GAC3BD,EAAKnB,GAHhB,QAKIA,EAAQc,SAWhBvB,EAAUh0B,UAAU81B,aAAe,SAASrB,GACxC,GAAMoB,GAAiBpB,EAAQM,OAAOh4B,KAAKk3B,WAC3Cl3B,MAAKkT,cAAc+kB,qBAAqBa,IAa5C7B,EAAUh0B,UAAU+1B,YAAc,SAAS3E,EAAWpwB,EAAW40B,GAC7D,GAAMI,GAAWj5B,KAAKkT,cAAcgmB,oBAAoB7E,GAClD8E,EAAiBF,EAASh1B,GAE1BM,EAAU,GAAI2zB,GAAIkB,OACxB,KAEI,MADA70B,GAAQszB,SAAS73B,KAAKk3B,WAAYiC,GAC3BN,EAAKt0B,GAFhB,QAIIA,EAAQi0B,SAYhBvB,EAAUh0B,UAAUo2B,aAAe,SAAShF,EAAW9vB,GACnD,GAAM40B,GAAiB50B,EAAQyzB,OAAOh4B,KAAKk3B,WAC3Cl3B,MAAKkT,cAAcomB,qBACfjF,EAAW9vB,EAAQg1B,aAAcJ,IAYzClC,EAAUh0B,UAAUu2B,YAAc,SAASX,GACvC,GAAMY,GAAU,GAAIvB,GAAIwB,OACxB,KACI,MAAOb,GAAKY,GADhB,QAGIA,EAAQjB,SAWhBvB,EAAUh0B,UAAU02B,KAApB,WAAA,GAAAlc,IAAA,EAAArD,EAAAlE,QAA2B,SAAe0jB,GACtC,MAAO55B,MAAK44B,YAAY,SAASlB,GAC7B,MAAOA,GAAQiC,KAAKC,MAF5B,OAAA,UAAAlc,GAAA,MAAAD,GAAA/c,MAAAV,KAAAK,eAaA42B,EAAUh0B,UAAU42B,gBAApB,EAAAzf,EAAAlE,QAAqC,WACjC,MAAOlW,MAAK44B,YAAY,SAASlB,GAC7B,MAAOW,MAAKrM,MAAM0L,EAAQ3oB,qBAUlCkoB,EAAUh0B,UAAU62B,uBAAyB,WACzC,MAAO95B,MAAKq3B,iBAMhBJ,EAAUh0B,UAAU82B,qBAApB,EAAA3f,EAAAlE,QAA0C,WACtC,GAAM7E,GAAOrR,IACbA,MAAK44B,YAAY,SAASlB,GACtBA,EAAQsC,yBACR3oB,EAAK0nB,aAAarB,OAS1BT,EAAUh0B,UAAUg3B,oBAApB,WAAA,GAAA3b,IAAA,EAAAlE,EAAAlE,QAA0C,SAAegkB,GACrD,GAAM7oB,GAAOrR,IACbA,MAAK44B,YAAY,SAASlB,GACtBA,EAAQyC,uBAAuBD,GAC/B7oB,EAAK0nB,aAAarB,MAJ1B,OAAA,UAAA7Z,GAAA,MAAAS,GAAA5d,MAAAV,KAAAK,eAiBA42B,EAAUh0B,UAAUm3B,sBAApB,WAAA,GAAA3b,IAAA,EAAArE,EAAAlE,QAA4C,SACxCmkB,EAAkBC,GAElB,GAAMjpB,GAAOrR,IACb,OAAOA,MAAK44B,YAAY,SAASlB,GAC7B,GAAMnzB,GAAU,GAAI2zB,GAAIkB,OACxB,KAGI,MAFA70B,GAAQg2B,gBAAgB7C,EAAS2C,EAAkBC,GACnDjpB,EAAKgoB,aAAagB,EAAkB91B,GAC7BA,EAAQg1B,aAHnB,QAKIh1B,EAAQi0B,WAXpB,OAAA,UAAA1a,EAAA0c,GAAA,MAAA/b,GAAA/d,MAAAV,KAAAK,eA8BA42B,EAAUh0B,UAAUw3B,qBAApB,WAAA,GAAAC,IAAA,EAAAtgB,EAAAlE,QAA2C,SACvCykB,EAAwBC,EAAcC,GAEtC,GAAqB,IAAjBD,EACA,KAAM,IAAI97B,OAAM,mDAGpB,IAAMuS,GAAOrR,IACb,OAAOA,MAAK44B,YAAY,SAASlB,GAC7B,GAAMnzB,GAAU,GAAI2zB,GAAIkB,OACxB,KACI70B,EAAQu2B,oBAAoBpD,EAASiD,EAAwBE,GAC7DnD,EAAQqD,qBAAqBx2B,GAC7B8M,EAAK0nB,aAAarB,EAElB,IAAMX,GAAgBxyB,EAAQy2B,QAAQJ,EAAcC,EAIpD,OAFAxpB,GAAKgoB,aAAasB,EAAwBp2B,IAGtC02B,QAASlE;UACTwC,WAAYh1B,EAAQg1B,cAX5B,QAcIh1B,EAAQi0B,WAxBpB,OAAA,UAAA0C,EAAAC,EAAAC,GAAA,MAAAV,GAAAh6B,MAAAV,KAAAK,eAqCA42B,EAAUh0B,UAAUo4B,uBAApB,WAAA,GAAAC,IAAA,EAAAlhB,EAAAlE,QAA6C,SAAeykB,GACxD,GAAM1B,GAAWj5B,KAAKkT,cAAcgmB,oBAChCyB,EAEJ,OAAO34B,GAAMsd,KAAK2Z,IAJtB,OAAA,UAAAsC,GAAA,MAAAD,GAAA56B,MAAAV,KAAAK,eAcA42B,EAAUh0B,UAAUu4B,sBAApB,WAAA,GAAAC,IAAA,EAAArhB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA4C,QAAAC,GAAe+d,GAAf,GAAAe,EAAA,OAAA1hB,GAAAja,QAAAka,KAAA,SAAA6C,GAAA,OAAA,OAAAA,EAAA3C,KAAA2C,EAAAzb,MAAA,IAAA,GAAA,MAAAyb,GAAAzb,KAAA,GAAA,EAAA+Y,EAAAtG,SACf9T,KAAKq7B,uBAAuBV,GADb,KAAA,GAAA,GAClCe,EADkC5e,EAAAxC,KAEd,IAAtBohB,EAAWv8B,OAFyB,CAAA2d,EAAAzb,KAAA,CAAA,OAAA,MAAAyb,GAAAC,OAAA,SAG7B,KAH6B,KAAA,GAAA,MAMxC2e,GAAWC,OAN6B7e,EAAAC,OAAA,SAOjC2e,EAAW,GAPsB,KAAA,GAAA,IAAA,MAAA,MAAA5e,GAAAvC,SAAAqC,EAAA5c,QAA5C,OAAA,UAAA47B,GAAA,MAAAH,GAAA/6B,MAAAV,KAAAK,eAqBA42B,EAAUh0B,UAAU44B,wBAApB,WAAA,GAAAC,IAAA,EAAA1hB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA8C,QAAAhD,GAAeoiB,GAAf,GAAAL,GAAAzvB,EAMjC+vB,EANiCp9B,EAAAqF,EAAAoQ,CAAA,OAAA2F,GAAAja,QAAAka,KAAA,SAAAC,GAAA,OAAA,OAAAA,EAAAC,KAAAD,EAAA7Y,MAAA,IAAA,GAAA,MAMjC26B,GANiC,SAMlBz3B,GACpB,OACI03B,mBAAoB13B,EAAQ23B,yBARMhiB,EAAA7Y,KAAA,GAAA,EAAA+Y,EAAAtG,SACjB9T,KAAKq7B,uBAAuBU,GADX,KAAA,GAY1C,IAXML,EADoCxhB,EAAAI,KAE1CohB,EAAWC,OAEL1vB,KAQGrN,EAAI,EAAGA,EAAI88B,EAAWv8B,OAAQP,IAC7BqF,EAAYy3B,EAAW98B,GACvByV,EAAMrU,KAAKg5B,YAAY+C,EAAmB93B,EAAW+3B,GAC3D3nB,EAAIpQ,UAAYA,EAChBgI,EAAK2K,KAAKvC,EAhB4B,OAAA6F,GAAA6C,OAAA,SAkBnC9Q,EAlBmC,KAAA,GAAA,IAAA,MAAA,MAAAiO,GAAAK,SAAAZ,EAAA3Z,QAA9C,OAAA,UAAAue,GAAA,MAAAud,GAAAp7B,MAAAV,KAAAK,eA+BA42B,EAAUh0B,UAAUk5B,eAApB,WAAA,GAAAC,IAAA,EAAAhiB,EAAAlE,QAAqC,SACjCykB,EAAwB12B,EAAW8yB,GAEnC,GAAM1lB,GAAOrR,IAIb,OAFA82B,GAAmBC,GAEZ/2B,KAAKg5B,YAAY2B,EAAwB12B,EAAW,SAASM,GAChE,GAAM8P,GAAM9P,EAAQ83B,QAAQtF,EAE5B,OADA1lB,GAAKgoB,aAAasB,EAAwBp2B,GACnC8P,KAVf,OAAA,UAAAyK,EAAAwd,EAAAC,GAAA,MAAAH,GAAA17B,MAAAV,KAAAK,eAyBA42B,EAAUh0B,UAAUu5B,eAApB,WAAA,GAAAC,IAAA,EAAAriB,EAAAlE,QAAqC,SACjCykB,EAAwB12B,EAAW22B,EAAcC,GAEjD,GAAMxpB,GAAOrR,IAEb,OAAOA,MAAKg5B,YAAY2B,EAAwB12B,EAAW,SAASM,GAChE,GAAMwyB,GAAgBxyB,EAAQy2B,QAAQJ,EAAcC,EAGpD,OAFAxpB,GAAKgoB,aAAasB,EAAwBp2B,GAEnCwyB,KATf,OAAA,UAAA2F,EAAAC,EAAAC,EAAAC,GAAA,MAAAJ,GAAA/7B,MAAAV,KAAAK,eAyBA42B,EAAUh0B,UAAU65B,eAApB,WAAA,GAAAC,IAAA,EAAA3iB,EAAAlE,QAAqC,SACjCykB,EAAwB12B,EAAW22B,EAAcC,GAEjD,MAAqB,KAAjBD,GAIG56B,KAAKg5B,YAAY2B,EAAwB12B,EAAW,SAASM,GAChE,MAAOA,GAAQy4B,gBAAgBnC,MARvC,OAAA,UAAAoC,EAAAC,EAAAC,EAAAC,GAAA,MAAAL,GAAAr8B,MAAAV,KAAAK,eAsBA42B,EAAUh0B,UAAUo6B,0BAA4B,SAAS94B,GACrD,GAAM40B,GAAiB50B,EAAQyzB,OAAOh4B,KAAKk3B,WAC3Cl3B,MAAKs3B,2BAA2B/yB,EAAQg1B,cAAgBJ,GAa5DlC,EAAUh0B,UAAUq6B,yBAA2B,SAASr5B,EAAW40B,GAC/D,GAAMd,GAAU/3B,KAAKs3B,2BAA2BrzB,EAChD,IAAgB,OAAZ8zB,EACA,KAAM,IAAIj5B,OAAM,kCAAoCmF,EAGxD,IAAMM,GAAU,GAAI2zB,GAAIqF,oBACxB,KAEI,MADAh5B,GAAQszB,SAAS73B,KAAKk3B,WAAYa,GAC3Bc,EAAKt0B,GAFhB,QAIIA,EAAQi0B,SAUhBvB,EAAUh0B,UAAUu6B,2BAA6B,WAC7C,GAAMj5B,GAAU,GAAI2zB,GAAIqF,oBACxB,KAGI,MAFAh5B,GAAQuzB,SACR93B,KAAKq9B,0BAA0B94B,GACxBA,EAAQg1B,aAHnB,QAKIh1B,EAAQi0B,SAahBvB,EAAUh0B,UAAUw6B,oBAAsB,SAASx5B,EAAW8yB,GAC1D,GAAM1lB,GAAOrR,IAIb,OAFA82B,GAAmBC,GAEZ/2B,KAAKs9B,yBAAyBr5B,EAAW,SAASM,GACrD,GAAM8P,GAAM9P,EAAQ83B,QAAQtF,EAE5B,OADA1lB,GAAKgsB,0BAA0B94B,GACxB8P,KAYf4iB,EAAUh0B,UAAUy6B,2BAA6B,SAASz5B,GACtD,MAAOjE,MAAKs9B,yBAAyBr5B,EAAW,SAASM,GACrD,OACIo5B,YAAap5B,EAAQq5B,gBACrB5Z,IAAKzf,EAAQs5B,kBA4BzB5G,EAAUh0B,UAAU66B,yBAA2B,SAC3CC,EAAqB95B,EAAW+5B,GAEhCh+B,KAAKkT,cAAc+qB,iCACfF,EAAqB95B,GAAW,EAAAomB,EAAAtqB,SAAei+B,KAoBvD/G,EAAUh0B,UAAUi7B,wBAA0B,SAC1Cn3B,EAAQktB,EAAWhwB,EAAW40B,GAE9B,GAAIv6B,GAAI0B,KAAKkT,cAAcirB,+BACvBlK,EAAWhwB,EAGf,IAAU,OAAN3F,EACA,MAAO,KAOX,IAJAA,EAAI+5B,KAAKrM,MAAM1tB,GAIXyI,IAAWzI,EAAEwM,QACb,KAAM,IAAIhM,OACN,0DAA4DR,EAAEwM,QAC1D,SAAW/D,EAAS,IAIhC,IAAMxC,GAAU,GAAI2zB,GAAIkG,mBACxB,KAEI,MADA75B,GAAQszB,SAAS73B,KAAKk3B,WAAY54B,EAAEiG,SAC7Bs0B,EAAKt0B,EAASjG,GAFzB,QAIIiG,EAAQi0B,SAiBhBvB,EAAUh0B,UAAUo7B,uBAApB,WAAA,GAAAC,IAAA,EAAAlkB,EAAAlE,QAA6C,SACzCnP,EAAQktB,EAAWsK,EACnBt6B,EAAWu6B,EAAYC,EACvBC,GAKA,QAASC,GAAcp6B,EAASy5B,GAI5B,MAHAvpB,SAAQe,IAAI,6BAA+Bye,EAAY,IAAMhwB,IAGtD,EAPX,GAAMoN,GAAOrR,IAcb,IAAU,OAJAA,KAAKk+B,wBACXn3B,EAAQktB,EAAWhwB,EAAW06B,GAGlC,CAKA,GAAMp6B,GAAU,GAAI2zB,GAAIkG,mBACxB,KAMI,GALIM,EACAn6B,EAAQq6B,eAAeJ,GAEvBj6B,EAAQuzB,OAAO0G,GAEfv6B,GAAaM,EAAQg1B,aACrB,KAAM,IAAIz6B,OACN,+CAAiDm1B,EAIzD,IAAM+J,IACFlzB,QAAS/D,EACTxC,QAASA,EAAQyzB,OAAOh4B,KAAKk3B,YAC7BuH,YAAaA,EACbF,6BAA8BA,EAGlCltB,GAAKysB,yBACD7J,EAAWhwB,EAAW+5B,GApB9B,QAuBIz5B,EAAQi0B,UAhDhB,OAAA,UAAAqG,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAA,MAAAb,GAAA59B,MAAAV,KAAAK,eA0DA42B,EAAUh0B,UAAUm8B,0BAApB,WAAA,GAAAC,IAAA,EAAAjlB,EAAAlE,QAAgD,SAAejR,GAE3D,QAAS05B,GAAcp6B,EAASy5B,GAK5B,MAJAvpB,SAAQe,IAAI,6BAA+BvQ,EAAKq6B,WAAa,IACjDr6B,EAAKs0B,aAGV,EAOX,GAAU,OAJAv5B,KAAKk+B,wBACXj5B,EAAK6F,QAAS7F,EAAKq6B,WAAYr6B,EAAKs0B,WAAYoF,GAGpD,CAKA,GAAMp6B,GAAU,GAAI2zB,GAAIkG,mBACxB,KAEI,GADA75B,EAAQq6B,eAAe35B,EAAK44B,aACxB54B,EAAKs0B,YAAch1B,EAAQg1B,aAC3B,KAAM,IAAIz6B,OACN,+CAAiDmG,EAAKq6B,WAI9D,IAAMtB,IACFlzB,QAAS7F,EAAK6F,QACdvG,QAASA,EAAQyzB,OAAOh4B,KAAKk3B,YAC7BuH,YAAax5B,EAAKs6B,oBAClBhB,6BAA8Bt5B,EAAKu6B,gCAGvCx/B,MAAK89B,yBACD74B,EAAKq6B,WAAYr6B,EAAKs0B,WAAYyE,GAhB1C,QAmBIz5B,EAAQi0B,UAvChB,OAAA,UAAAiH,GAAA,MAAAJ,GAAA3+B,MAAAV,KAAAK,eA2DA42B,EAAUh0B,UAAUy8B,oBAApB,WAAA,GAAAC,IAAA,EAAAvlB,EAAAlE,QAA0C,SACtCnP,EAAQktB,EAAWhwB,EAAWe,EAAM6E,EAAS+1B,GAI7C,QAAS5E,GAAQz2B,EAASy5B,GACtB,GAAM3pB,GAAM9P,EAAQy2B,QAAQh2B,GAExB66B,EAAYxrB,EAAIwrB,SACpB,QAAkB5+B,KAAd4+B,EAEAA,EAAYxrB,MACT,CAKH,GAAMyrB,GAAkB7L,EAAY,IAAMhwB,EAAY,IAAMoQ,EAAIupB,aAChE,IAAIkC,IAAmBzuB,GAAKkmB,mCAAoC,CAC5D,GAAMwI,GAAU1uB,EAAKkmB,mCAAmCuI,EACxD,IAAIC,EAAQC,KAAOn2B,GAAWk2B,EAAQH,YAAcA,EAChD,KAAM,IAAI9gC,OACN,oDACAghC,GAIZzuB,EAAKkmB,mCAAmCuI,IACpCE,GAAIn2B,EACJ+1B,UAAWA,GAQnB,MAJA5B,GAAYz5B,QAAUA,EAAQyzB,OAAO3mB,EAAK6lB,YAC1C7lB,EAAKysB,yBACD7J,EAAWhwB,EAAW+5B,IAGtBlR,OAAQ+S,EACRpB,YAAaT,EAAYS,gBACzBxK,UAAWA,EACXsK,6BAA8BP,EAAYO,kCAtClD,GAAMltB,GAAOrR,IA0Cb,OAAOA,MAAKk+B,wBACRn3B,EAAQktB,EAAWhwB,EAAW+2B,IA9CtC,OAAA,UAAAiF,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAA,MAAAX,GAAAj/B,MAAAV,KAAAK,eA2DA42B,EAAUh0B,UAAUs9B,sBAApB,WAAA,GAAAC,IAAA,EAAApmB,EAAAlE,QAA4C,SAAenP,EAAQktB,EAAWhwB,GAC1E,GAAM1F,GAAIyB,KAAKkT,cAAcirB,+BACzBlK,EAAWhwB,EAGf,IAAU,OAAN1F,EACA,OAAO,CAGX,IAAMD,GAAI+5B,KAAKrM,MAAMztB,EACrB,OAAIwI,KAAWzI,EAAEwM,UACb2J,QAAQyG,KACJ,4CAA4C+Y,EAA5C,IACGhwB,EADH,sCACkD3F,EAAEwM,QADpD,SAEO/D,EAFP,MAIG,IAhBf,OAAA,UAAA05B,EAAAC,EAAAC,GAAA,MAAAH,GAAA9/B,MAAAV,KAAAK,eAoCA42B,EAAUh0B,UAAU29B,0BAApB,WAAA,GAAAC,IAAA,EAAAzmB,EAAAlE,QAAgD,SAC5CnP,EAAQktB,EAAWhwB,GAEnB,QAAS68B,GAAOv8B,EAASy5B,GACrB,GAAM+C,GAAex8B,EAAQy8B,oBAEvBC,EAAcjD,EAAYS,gBAC1ByC,EAAmBD,EAAYvI,SAAW,IAEhD,QACIiF,YAAeoD,EACf/c,IAAOzf,EAAQ48B,eAAeJ,GAC9BvB,gCACIxB,EAAYO,iCAChB6C,2BAA8BF,GAItC,MAAOlhC,MAAKk+B,wBACRn3B,EAAQktB,EAAWhwB,EAAW68B,IAnBtC,OAAA,UAAAO,EAAAC,EAAAC,GAAA,MAAAV,GAAAngC,MAAAV,KAAAK,eA8BA42B,EAAUh0B,UAAUu+B,0BAApB,WAAA,GAAAC,IAAA,EAAArnB,EAAAlE,QAAgD,SAAe+d,EAAWhwB,GACtE,GAAM1F,GAAIyB,KAAKkT,cAAcirB,+BACzBlK,EAAWhwB,EAGf,IAAU,OAAN1F,EACA,KAAM,IAAIO,OAAM,kCAAoCm1B,EAAY,IAChDhwB,EAAY,IAEhC,IAAM3F,GAAI+5B,KAAKrM,MAAMztB,GAEfgG,EAAU,GAAI2zB,GAAIkG,mBACxB,KACI75B,EAAQszB,SAAS73B,KAAKk3B,WAAY54B,EAAEiG,QAEpC,IAAMw8B,GAAex8B,EAAQy8B,mBAE7B,QACI1B,WAAcrL,EACdsL,oBAAuBjhC,EAAEmgC,YACzB3zB,QAAWxM,EAAEwM,QACbyuB,WAAct1B,EACd45B,YAAet5B,EAAQ48B,eAAeJ,GACtCvB,gCACIj7B,EAAQg6B,kCAZpB,QAeIh6B,EAAQi0B,SA3BhB,OAAA,UAAAkJ,EAAAC,GAAA,MAAAF,GAAA/gC,MAAAV,KAAAK,eA6CA42B,EAAUh0B,UAAUqvB,gBAAkB,SAClCtO,EAAK4V,EAASgI,GAEd5hC,KAAKw5B,YAAY,SAASqI,GACtBA,EAAKC,eAAe9d,EAAK4V,EAASgI,MAK1CviC,EAAOJ,QAAUg4B,2TC/nBjB,QAAS8K,GAAqBC,GAG1B,MAAOA,GAAYl3B,QAAU,MAAQk3B,EAAYzI,WAGrD,QAAS0I,GAAuBC,GAC5B,MAAO,IACDC,EAAApiC,QAAMogB,IAAI+hB,EAAY,SAAC5jC,GAAD,MAAUA,GAAEqJ,OAAZ,IAAsBrJ,EAAE+P,WAAY+zB,KAAK,KAC/D,6MAxVVhoB,EAAAzb,EAAA,mBAEA0jC,EAAA1jC,EAAA,mBAqCM2jC,GAEFC,OAAQ,EAGRhuB,KAAM,EAGNiuB,qBAAsB,GAGLC,aACjB,QAAAA,GAAY1P,EAAU1kB,EAAU4E,IAAa,EAAAnT,EAAAC,SAAAC,KAAAyiC,GACzCziC,KAAKw1B,UAAYzC,EACjB/yB,KAAKyxB,UAAYpjB,EACjBrO,KAAKgT,aAAeC,EAIpBjT,KAAK0iC,kCAAoC,KAIzC1iC,KAAK2iC,qCAAsC,EAE3C3iC,KAAKqb,gBAAiB,uDAOtBrb,KAAKqb,gBAAiB,EAItBrb,KAAK4iC,6CAOLnuB,QAAQe,IAAI,0CAEZxV,KAAKqb,gBAAiB,6CAkBP2mB,EAAaE,GAAY,GAAAtS,GAAA5vB,IACxC,OAAOA,MAAKgT,aAAa6vB,gCACrBb,YAAaA,EACbE,WAAYA,EACZY,UAAW9iC,KAAKw1B,UAAUlyB,YAC1B4T,MAAOorB,EAAwBC,SAChC3+B,KAAK,SAACm/B,GACDA,EAAI7rB,QAAUorB,EAAwBC,QACtC3S,EAAKgT,6DAaIZ,GAAa,GAAA9M,GAAAl1B,IAC9B,OAAOA,MAAKgT,aAAagwB,0BACrBhB,GACFp+B,KAAK,SAACm/B,GACJ,GAAKA,EAIL,OAAQA,EAAI7rB,OACR,IAAKorB,GAAwBE,qBAEzB,MAEJ,KAAKF,GAAwBC,OAYzB,MAJA9tB,SAAQe,IACJ,6CACAusB,EAAqBC,IAElB9M,EAAKliB,aAAaiwB,6BACrBF,EAAID,UAAWR,EAAwBC,OAG/C,KAAKD,GAAwB/tB,KAEzB,MAAO2gB,GAAKliB,aAAakwB,6BACrBH,EAAID,UAAWR,EAAwB/tB,MACnC2C,MAAOorB,EAAwBE,qBAC/BW,kBAAmBjO,EAAKM,UAAUlyB,cAExCM,KAAK,SAACw/B,GACJ,IAAKA,EAYD,WALA3uB,SAAQe,IACJ,wCACAusB,EAAqBC,GACrB,+CAcR9M,GAAKmO,wCACDD,GACFE,MAAM,SAACnlC,GACLsW,QAAQC,MACJ,iEACwBvW,GAE5B+2B,EAAK0N,gBACNthC,QAGX,SACI,KAAM,IAAIxC,OAAM,oBAAsBikC,EAAI7rB,gDAO5C,GAAA4e,GAAA91B,IACV,KAAIA,KAAK0iC,kCAAT,CAIA,GAAMa,GAAsC,WACxC,GAAIzN,EAAK6M,oCACL,KAAM,IAAI7jC,OAAM,0CAEpBg3B,GAAK6M,qCAAsC,EAE3C7M,EAAK0N,+BAA+B/a,QAAQ,WACxCqN,EAAK6M,qCAAsC,IAC5CW,MAAM,SAACnlC,GAGNsW,QAAQyG,KAAR,2CAC+C/c,KAEhDmD,OAGPtB,MAAK0iC,kCAAoCjjC,EAAOuZ,WAC5CuqB,EAnNuB,6DA2NA,GAAAvN,GAAAh2B,IAC3B,OAAKA,MAAKqb,gBAKV5G,QAAQe,IAAI,iDAELxV,KAAKgT,aAAaywB,kCACrBnB,EAAwBE,qBACxBF,EAAwBC,SACzB3+B,KAAK,SAACm/B,GACL,IAAKA,EAGD,MAFAtuB,SAAQe,IAAI,2CACZwgB,EAAK0M,kCAAoC,KAI7C,IAAIvN,OAAA,EAOJ,OALIA,GADA4N,EAAI7rB,QAAUorB,EAAwBC,OAC/BvM,EAAK0N,4BAA4BX,GAEjC/M,EAAKqN,wCAAwCN,GAGjD5N,EAAKvxB,KAAK,WAEb,MAAOoyB,GAAKwN,iCACbF,MAAM,SAACnlC,GACNsW,QAAQC,MAAM,oDAAqDvW,GACnE63B,EAAK0M,kCAAoC,KACzC1M,EAAK4M,gBACNthC,WA9BHtB,KAAK0iC,kCAAoC,KAClC7uB,EAAA9T,QAAQ+T,+DAkCKivB,GAAK,GAAAY,GAAA3jC,IAC7ByU,SAAQe,IACJ,uBAAuBusB,EAAqBgB,EAAIf,aAAhD,SACSC,EAAuBc,EAAIb,YADpC,OAEOa,EAAID,UAFX,IAKJ,IAAMc,IACFC,OAAQ,UACRC,qBAAsB9jC,KAAKyxB,UAC3BsS,WAAYhB,EAAID,UAChB99B,KAAM+9B,EAAIf,YAGd,OAAOhiC,MAAKgkC,sBACRJ,EAAgBb,EAAIb,WAAYa,EAAID,WACtCl/B,KAAK,WACH,MAAO+/B,GAAK3wB,aAAakwB,6BACrBH,EAAID,UAAWR,EAAwBC,QACrCrrB,MAAOorB,EAAwB/tB,yEAMLwuB,GAAK,GAAAkB,GAAAjkC,IACzCyU,SAAQe,IACJ,4CACGusB,EAAqBgB,EAAIf,aAD5B,OAEGC,EAAuBc,EAAIb,YAF9B,qBAGoBa,EAAII,kBAHxB,IAMJ,IAAMS,IACFC,OAAQ,uBACRC,qBAAsB9jC,KAAKyxB,UAC3BsS,WAAYhB,EAAID,UAGpB,OAAO9iC,MAAKgkC,sBACRJ,EAAgBb,EAAIb,WAAYa,EAAII,mBACtCv/B,KAAK,WACH,MAAOqgC,GAAKjxB,aAAaiwB,6BACrBF,EAAID,UAAWR,EAAwBE,sEAM7B5I,EAASsI,EAAY9xB,GACvC,GAAMD,MADwCrP,GAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KAE9C,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,SAAoBmiC,KAApBphC,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAAgC,CAAA,GAArBojC,GAAqBhjC,EAAAK,KACvB4O,GAAW+zB,EAAMv8B,UAClBwI,EAAW+zB,EAAMv8B,YAErBwI,EAAW+zB,EAAMv8B,QAAQu8B,EAAM71B,UAAYurB,GAND,MAAAh4B,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,IAS9C,MAAOhB,MAAKw1B,UAAUtlB,aAClB,qBAAsBC,EAAYC,sBAxRzBqyB,8VC0Kd,QAAS0B,GAAkBnQ,EAAWoQ,EAAWC,GACpDC,EAAmBtQ,GAAaoQ,EAChCG,EAAmBvQ,GAAaqQ,ufAFpBF,kBAAAA,CAtNhB,IAAA/pB,GAAAzb,EAAA,mBAQa2lC,EAAArlC,EAAAqlC,sBAQAC,EAAAtlC,EAAAslC,sBAgBPC,aACF,QAAAA,GAAYhgC,IAAQ,EAAA1E,EAAAC,SAAAC,KAAAwkC,GAChBxkC,KAAKykC,QAAUjgC,EAAOmD,OACtB3H,KAAKyxB,UAAYjtB,EAAO6J,SACxBrO,KAAK+S,QAAUvO,EAAOqY,OACtB7c,KAAKqxB,WAAa7sB,EAAOwuB,UACzBhzB,KAAKw1B,UAAYhxB,EAAOuuB,SACxB/yB,KAAK0kC,QAAUlgC,EAAOuC,qEAwBR6M,EAAO+wB,EAAQC,eAG7BJ,oBAAAA,KAcFK,cACF,QAAAA,GAAYrgC,IAAQ,EAAA1E,EAAAC,SAAAC,KAAA6kC,GAChB7kC,KAAKykC,QAAUjgC,EAAOmD,OACtB3H,KAAK+S,QAAUvO,EAAOqY,OACtB7c,KAAKqxB,WAAa7sB,EAAOwuB,UACzBhzB,KAAKw1B,UAAYhxB,EAAOuuB,SACxB/yB,KAAK0kC,QAAUlgC,EAAOuC,mEAuBXvC,0CASDD,iDAWOugC,GACjB,MAAOjxB,GAAA9T,QAAQ+T,SAAQ,+CAQPgxB,GAChB,KAAM,IAAIhmC,OAAM,6EAGhB+lC,oBAAAA,KAaFE,eACF,QAAAA,GAAYC,EAAKC,IAAS,EAAAnlC,EAAAC,SAAAC,KAAA+kC,EAAA,IAAAnV,IAAA,EAAAsV,EAAAnlC,SAAAC,MAAA+kC,EAAAI,YAAA,EAAAC,EAAArlC,SAAAglC,IAAA7lC,KAAAc,KAChBglC,GADgB,OAEtBpV,GAAKrO,KAAO,kBACZqO,EAAKqV,QAAUA,EAHOrV,6EAWf,GAAAsF,GAAAl1B,KACH8sB,EAAS9sB,KAAKuhB,KAAO,SAAWvhB,KAAK45B,OAWzC,OATI55B,MAAKilC,UACLnY,GAAU,MACN,EAAApiB,EAAA3K,SAAYC,KAAKilC,SAAS9kB,IACtB,SAACklB,GAAD,MAAOA,GAAI,KAAOnQ,EAAK+P,QAAQI,KACjCjD,KAAK,OAGftV,GAAU,WAtBYhuB,SA2BtBimC,gBAAAA,IAWKO,+BACT,QAAAA,GAAYN,EAAKr2B,IAAS,EAAA7O,EAAAC,SAAAC,KAAAslC,EAAA,IAAAxP,IAAA,EAAAoP,EAAAnlC,SAAAC,MAAAslC,EAAAH,YAAA,EAAAC,EAAArlC,SAAAulC,IAAApmC,KAAAc,KAChBglC,GADgB,OAEtBlP,GAAKvU,KAAO,qBACZuU,EAAKnnB,QAAUA,EAHOmnB,8BADUh3B,+SCxMxC,YAMA,IAAMymC,GAAO5mC,EAAQ,SAErBA,GAAQ,SACRA,EAAQ,YAKRU,EAAOJ,QAAQqlC,mBAAqBiB,EAAKjB,mBAKzCjlC,EAAOJ,QAAQslC,mBAAqBgB,EAAKhB,mBAKzCllC,EAAOJ,QAAQ8lC,gBAAkBQ,EAAKR,4ECxBtC,gEA4BA,QAASS,GAAoBvhC,GACzBjE,KAAKiE,UAAYA,EACjBjE,KAAKylC,SAAW,EAChBzlC,KAAK0lC,cAAe,GAAIniC,OAAOC,UAC/BxD,KAAK2lC,qBAuFT,QAASC,GAAiBphC,GACtB+gC,EAAKf,oBAAoBtlC,KAAKc,KAAMwE,GAOpCxE,KAAK6lC,cAAgBhyB,EAAA9T,QAAQ+T,UAG7B9T,KAAK8lC,2BAA6B,IAClC9lC,KAAK+lC,yBAA2B,WAES9kC,KAArCuD,EAAOwa,OAAOgnB,qBACdhmC,KAAK+lC,yBAA2BvhC,EAAOwa,OAAOgnB,wBAGP/kC,KAAvCuD,EAAOwa,OAAOinB,uBACdjmC,KAAK8lC,2BAA6BthC,EAAOwa,OAAOinB,sBAmbxD,QAASC,GAAiB1hC,GACtB+gC,EAAKV,oBAAoB3lC,KAAKc,KAAMwE,GAIpCxE,KAAKmmC,kBAGLnmC,KAAKomC,OAASA,oTA3jBZpkC,EAAQrD,EAAQ,eAChBynC,EAASznC,EAAQ,aACjB4mC,EAAO5mC,EAAQ,SA+BrB6mC,GAAoBviC,UAAUojC,cAAgB,SAC1CC,EAAoBC,GAEpB,GAAMC,IAAkB,GAAIjjC,OAAOC,UAAYxD,KAAK0lC,YAEpD,QAAI1lC,KAAKylC,UAAYa,GACjBE,GAAmBD,KAEnB9xB,QAAQe,IACJ,iCAAmCxV,KAAKylC,SACpC,cAAgBe,EAAkB,OAEnC,IAMfhB,EAAoBviC,UAAUwjC,qBAAuB,SACjD9+B,EAAQ0G,EAAUq4B,GAEb1mC,KAAK2lC,kBAAkBh+B,KACxB3H,KAAK2lC,kBAAkBh+B,OAE3B3H,KAAK2lC,kBAAkBh+B,GAAQ0G,GAAYq4B,GAa/ClB,EAAoBviC,UAAU0jC,yBAA2B,SACrDC,GAEA,IAAK,GAAMj/B,KAAU3H,MAAK2lC,kBACtB,GAAK3lC,KAAK2lC,kBAAkB9T,eAAelqB,GAA3C,CAIA,IAAKi/B,EAAc/U,eAAelqB,GAE9B,MADA8M,SAAQe,IAAI,+CAAiD7N,IACtD,CAGX,KAAK,GAAM0G,KAAYrO,MAAK2lC,kBAAkBh+B,GAC1C,GAAK3H,KAAK2lC,kBAAkBh+B,GAAQkqB,eAAexjB,KAI9Cu4B,EAAcj/B,GAAQkqB,eAAexjB,GAKtC,MAJAoG,SAAQe,IACJ,+CACI7N,EAAS,IAAM0G,IAEhB,IAsCvBrM,EAAMmZ,SAASyqB,EAAkBL,EAAKf,qBAUtCoB,EAAiB3iC,UAAU4jC,uBAAyB,SAASD,GAsEzD,QAASE,KACL,MAAOviC,GAvE6D,GAAAwiC,GAAA,WAAA,GAAAC,IAAA,EAAA5sB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAUxE,QAAAC,GAA8BqqB,GAA9B,GAAAC,GAAAv/B,EAAAw/B,EAAA94B,EAAA+4B,EAAApjB,CAAA,OAAAhK,GAAAja,QAAAka,KAAA,SAAA6C,GAAA,OAAA,OAAAA,EAAA3C,KAAA2C,EAAAzb,MAAA,IAAA,GAAA,GACIkD,EAAU0iC,EAGN1iC,GAAWA,EAAQ8hC,cAAch1B,EAAKy0B,2BACLz0B,EAAK00B,4BAEtCtxB,QAAQe,IAAI,0DACZjR,EAAU,MAIVA,GAAWA,EAAQoiC,yBAAyBC,KAC5CriC,EAAU,MAGTA,EAhBT,CAAAuY,EAAAzb,KAAA,CAAA,OAAA,MAiBQoT,SAAQe,IAAR,wCAAoDnE,EAAKqzB,SAjBjE5nB,EAAAzb,KAAA,GAAA,EAAA+Y,EAAAtG,SAkBwBzC,EAAKg2B,qBAlB7B,KAAA,GAkBQ9iC,EAlBRuY,EAAAxC,IAAA,KAAA,GAsBU4sB,KAtBVpqB,EAAA6U,GAAA3X,EAAAja,QAAAuf,KAwByBsnB,EAxBzB,KAAA,IAAA,IAAA9pB,EAAA8U,GAAA9U,EAAA6U,MAAArwB,KAAA,CAAAwb,EAAAzb,KAAA,EAAA,OAAA,GAwBesG,EAxBfmV,EAAA8U,GAAArwB,MAyBaqlC,EAAc/U,eAAelqB,GAzB1C,CAAAmV,EAAAzb,KAAA,EAAA,OAAA,MAAAyb,GAAAC,OAAA,WAAA,GAAA,KAAA,IA6BcoqB,EAAcP,EAAcj/B,GA7B1CmV,EAAAgV,GAAA9X,EAAAja,QAAAuf,KA+B+B6nB,EA/B/B,KAAA,IAAA,IAAArqB,EAAAiV,GAAAjV,EAAAgV,MAAAxwB,KAAA,CAAAwb,EAAAzb,KAAA,EAAA,OAAA,GA+BmBgN,EA/BnByO,EAAAiV,GAAAxwB,MAgCiB4lC,EAAYtV,eAAexjB,GAhC5C,CAAAyO,EAAAzb,KAAA,EAAA,OAAA,MAAAyb,GAAAC,OAAA,WAAA,GAAA,KAAA,IAAA,GAoCkBqqB,EAAaD,EAAY94B,IAEzB2V,EAAMojB,EAAWE,mBACZj2B,EAAKggB,WAAW8F,oBAvCvC,CAAAra,EAAAzb,KAAA,EAAA,OAAA,MAAAyb,GAAAC,OAAA,WAAA,GAAA,KAAA,IA6CiBxY,EAAQohC,kBAAkBh+B,QACyB1G,KAAhDsD,EAAQohC,kBAAkBh+B,GAAQ0G,KAEtC64B,EAASv/B,GAAUu/B,EAASv/B,OAC5Bu/B,EAASv/B,GAAQiP,KAAKwwB,IAjDtCtqB,EAAAzb,KAAA,EAAA,MAAA,KAAA,IAAAyb,EAAAzb,KAAA,EAAA,MAAA,KAAA,IAAA,MAAAyb,GAAAC,OAAA,SAsDW1L,EAAKk2B,qBACRhjC,EAAS2iC,GAvDjB,KAAA,IAAA,IAAA,MAAA,MAAApqB,GAAAvC,SAAAqC,EAAA5c,QAVwE,OAAA,UAAA0d,GAAA,MAAAspB,GAAAtmC,MAAAV,KAAAK,eAClEgR,EAAOrR,KAETuE,MAAA,GAwEE4wB,EAAOn1B,KAAK6lC,cAAcjiC,KAAKmjC,EAMrC,OAHA/mC,MAAK6lC,cAAgB1Q,EAAKvxB,KAAKkjC,EAAeA,GAGvC3R,EAAKvxB,KAAKkjC,IAQrBlB,EAAiB3iC,UAAUokC,oBAA3B,EAAAjtB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAgD,QAAAhD,KAAA,GAAA1V,GAAA+f,CAAA,OAAAhK,GAAAja,QAAAka,KAAA,SAAAC,GAAA,OAAA,OAAAA,EAAAC,KAAAD,EAAA7Y,MAAA,IAAA,GAAA,MACtC4C,GAAYjE,KAAKqxB,WAAWmM,6BAC5BxZ,EAAMhkB,KAAKqxB,WAAWqM,2BAA2Bz5B,GAFXiW,EAAA7Y,KAAA,GAAA,EAAA+Y,EAAAtG,SAItC9T,KAAKqxB,WAAWgN,uBAClBr+B,KAAK0kC,QAAS1kC,KAAKqxB,WAAW8F,uBAAyBlzB,EACvD+f,EAAIA,KAAM0U,QAAS14B,KAAKqxB,WAAW+F,mBANK,KAAA,GAAA,MAAAld,GAAA6C,OAAA,SASrC,GAAIyoB,GAAoBvhC,GATa,KAAA,GAAA,IAAA,MAAA,MAAAiW,GAAAK,SAAAZ,EAAA3Z,SA2BhD4lC,EAAiB3iC,UAAUukC,oBAAsB,SAC7CjjC,EAASmiC,EAAYe,EAAWC,GAEhC,GAGMC,MACFC,EAAiB,EACjBC,EAAwB,EAN9B/mC,GAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KAQE,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,UAAqB,EAAA2K,EAAA3K,SAAY2nC,MAAjC5mC,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAII,IAAK,GAJE6G,GAAsCzG,EAAAK,MACvCumC,EAAqBJ,EAAc//B,GACnCogC,EAAiBN,EAAU9/B,GAExB/I,EAAI,EAAGA,EAAIkpC,EAAmB3oC,OAAQP,IAAK,CAChD,GAAMwoC,GAAaU,EAAmBlpC,GAChCyP,EAAW+4B,EAAW/4B,SAEtB25B,EAAgBD,EAAe15B,EAChC25B,GAAc/jC,WAmBnBwQ,QAAQe,IACJ,0BAA4B7N,EAAS,IAAM0G,GAG3Cw5B,EAvC0B,KAyC1BA,EAAwB,EACxBD,KAECD,EAAUC,KACXD,EAAUC,OAGdD,EAAUC,GAAgBhxB,MACtBjP,OAAQA,EACRy/B,WAAYA,IAGhBS,KAzBItjC,EAAQkiC,qBAAqB9+B,EAAQ0G,EAAUq4B,IA7B7D,MAAA9kC,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,IAyDE,MAAO2mC,IAkBX/B,EAAiB3iC,UAAUglC,6BAA+B,SACtD1jC,EAASmiC,EAAYwB,EAAejN,GAUpC,IAAK,GATPrL,GAAA5vB,KACQmoC,GACFnU,UAAWoS,EAAOlS,cAClBoL,WAAYt/B,KAAKqxB,WAAW8F,oBAC5B0D,eAEE1qB,KAEAmL,KACG1c,EAAI,EAAGA,EAAIspC,EAAc/oC,OAAQP,IAAK,CAC3C,GAAMwpC,GAAMF,EAActpC,GACpB+I,EAASygC,EAAIzgC,OACby/B,EAAagB,EAAIhB,WACjB/4B,EAAW+4B,EAAW/4B,QAEvB8B,GAAWxI,KACZwI,EAAWxI,OAEfwI,EAAWxI,GAAQ0G,GAAY85B,EAE/B7sB,EAAS1E,KACLwvB,EAAOiC,wBACHF,EAAiBtN,WACjB76B,KAAKykC,QACLzkC,KAAKyxB,UACLzxB,KAAKqxB,WACL1pB,EACAy/B,EACAnM,IAKZ,MAAOpnB,GAAA9T,QAAQyb,IAAIF,GAAU1X,KAAK,WAC9B,MAAOgsB,GAAK4F,UAAUtlB,aAAa,mBAAoBC,GAAYvM,KAAK,WAAM,GAAA0wB,IAAA,EAAAC,GAAA,EAAAC,MAAAvzB,EAAA,KAE1E,IAAA,GAAAwzB,GAAAC,GAAA,EAAAtzB,EAAArB,UAAqB,EAAA2K,EAAA3K,SAAYoQ,MAAjCmkB,GAAAG,EAAAC,EAAArzB,QAAAC,MAAAgzB,GAAA,EAA8C,CAAA,GAAnCmQ,GAAmChQ,EAAAlzB,MAAAqzB,GAAA,EAAAC,GAAA,EAAAC,MAAA7zB,EAAA,KAC1C,IAAA,GAAA8zB,GAAAC,GAAA,EAAA5zB,EAAArB,UAAuB,EAAA2K,EAAA3K,SAAYoQ,EAAWs0B,OAA9C7P,GAAAG,EAAAC,EAAA3zB,QAAAC,MAAAszB,GAAA,EAAwD,CAAA,GAA7CnD,GAA6CsD,EAAAxzB,KACpDgD,GAAQkiC,qBACJhC,EAAQhT,EAAUiV,IAHgB,MAAA9kC,GAAAizB,GAAA,EAAAC,EAAAlzB,EAAA,QAAA,KAAAgzB,GAAAI,EAAAnzB,QAAAmzB,EAAAnzB,SAAA,QAAA,GAAAgzB,EAAA,KAAAC,MAF4B,MAAAlzB,GAAA2yB,GAAA,EAAAC,EAAA5yB,EAAA,QAAA,KAAA0yB,GAAAI,EAAA7yB,QAAA6yB,EAAA7yB,SAAA,QAAA,GAAA0yB,EAAA,KAAAC,UAqBtFoR,EAAiB3iC,UAAUskC,qBAA3B,WAAA,GAAA3pB,IAAA,EAAAxD,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAkD,QAAA+B,GAAena,EAASmjC,GAAxB,GAAA1jB,GAAAiX,EAAAwM,EAAAa,EAAA1pC,CAAA,OAAAob,GAAAja,QAAAka,KAAA,SAAA2E,GAAA,OAAA,OAAAA,EAAAzE,KAAAyE,EAAAvd,MAAA,IAAA,GAAA,MACxC2iB,GAAMhkB,KAAKqxB,WAAWqM,2BAA2Bn5B,EAAQN,WACzDg3B,GACF11B,KAAM,aACNwD,SACIirB,UAAWoS,EAAOjS,iBAClBrpB,QAAS9K,KAAK0kC,QACdnL,WAAYh1B,EAAQN,UACpB45B,YAAa7Z,EAAIA,IACjB2Z,YAAa3Z,EAAI2Z,cATqB/e,EAAAvd,KAAA,GAAA,EAAA+Y,EAAAtG,SAatBsyB,EAAOmC,4BAC3BvoC,KAAKqxB,WAAYrxB,KAAKw1B,UAAWkS,GAdS,KAAA,GAaxCD,EAbwC7oB,EAAAtE,KAiBxCguB,EAAiBtoC,KAAKwnC,oBACxBjjC,EAASyf,EAAI2Z,YAAa8J,EAAWC,GAGhC9oC,EAAI,CArBiC,KAAA,GAAA,KAqB9BA,EAAI0pC,EAAenpC,QArBW,CAAAyf,EAAAvd,KAAA,EAAA,OAAA,MAAAud,GAAAzE,KAAA,EAAAyE,EAAAvd,KAAA,IAAA,EAAA+Y,EAAAtG,SAuBhC9T,KAAKioC,6BACP1jC,EAASyf,EAAI2Z,YAAa2K,EAAe1pC,GAAIq8B,GAxBX,KAAA,IA0BtCxmB,QAAQe,IAAI,gCAAgCxV,KAAK0kC,QAArC,YACI9lC,EAAI,GADR,IACa0pC,EAAenpC,OAD5B,KA1B0Byf,EAAAvd,KAAA,EAAA,MAAA,KAAA,IAAA,KAAAud,GAAAzE,KAAA,GAAAyE,EAAA+S,GAAA/S,EAAA,MAAA,GA6BtCnK,QAAQe,IAAI,sBAAsBxV,KAAK0kC,QAA3B,YACI9lC,EAAI,GADR,IACa0pC,EAAenpC,OAD5B,YA7B0Byf,EAAA+S,EAAA,KAAA,IAqBH/yB,IArBGggB,EAAAvd,KAAA,CAAA,MAAA,KAAA,IAAA,IAAA,MAAA,MAAAud,GAAArE,SAAAmE,EAAA1e,OAAA,EAAA,QAAlD,OAAA,UAAA6d,EAAAC,GAAA,MAAAF,GAAAld,MAAAV,KAAAK,eA8CAulC,EAAiB3iC,UAAUk5B,eAAiB,SAAS3qB,EAAMlI,EAAWP,GAClE,GAAMsI,GAAOrR,IAGb,OAFAyU,SAAQe,IAAR,iCAA6CxV,KAAK0kC,SAE3C1kC,KAAKwoC,kBAAkBh3B,GAAM5N,KAAK,SAASgjC,GAK9C,MAFAv1B,GAAKo3B,wBAAwB7B,GAEtBv1B,EAAKw1B,uBAAuBD,KACpChjC,KAAK,SAASW,GACb,GAAMmkC,IACF59B,QAASuG,EAAKqzB,QACdn/B,KAAM+D,EACNP,QAASA,GAGP8xB,EAAaxpB,EAAKggB,WAAWoM,oBAC/Bl5B,EAAQN,WAAW,EAAAomB,EAAAtqB,SAAe2oC,IAGhCP,GACFnU,UAAWoS,EAAOjS,iBAClBmL,WAAYjuB,EAAKggB,WAAW8F,oBAC5B0D,WAAYA,EACZtB,WAAYh1B,EAAQN,UAGpB+I,UAAWqE,EAAKogB,UAIpB,OADAltB,GAAQkhC,WACD0C,KAYfvC,EAAiB3iC,UAAUwlC,wBAA0B,SAAS7B,GAC1D,GAAM+B,KAcN,KAZA,EAAAj+B,EAAA3K,SAAY6mC,GAAen4B,QAAQ,SAAC9G,IAChC,EAAA+C,EAAA3K,SAAY6mC,EAAcj/B,IAAS8G,QAAQ,SAACJ,GACxC,GAAMsQ,GAASioB,EAAcj/B,GAAQ0G,EACjCsQ,GAAOiqB,iBAAmBjqB,EAAOkqB,YAC5BF,EAAehhC,KAChBghC,EAAehhC,OAEnBghC,EAAehhC,GAAQ0G,GAAYsQ,QAK3C,EAAAjU,EAAA3K,SAAY4oC,GAAgBxpC,OAE5B,KAAM,IAAIomC,GAAKD,mBACX,4HAC4DqD,IAYxE/C,EAAiB3iC,UAAUulC,kBAAoB,SAASh3B,GAAM,GAAA0jB,GAAAl1B,KAEpD8oC,EAAc9mC,EAAMme,IAAI3O,EAAKu3B,mBAAoB,SAAStqC,GAC5D,MAAOA,GAAEkJ,QAYb,OAAO3H,MAAK+S,QAAQuK,aAAawrB,GAAa,GAAOllC,KAAK,SAAC+K,GAEvD,IAAK,GAAMhH,KAAUgH,GACjB,GAAKA,EAAQkjB,eAAelqB,GAA5B,CAIA,GAAMw/B,GAAcx4B,EAAQhH,EAC5B,KAAK,GAAM0G,KAAY84B,GACdA,EAAYtV,eAAexjB,KAI5B84B,EAAY94B,GAAU26B,aACrB7B,EAAY94B,GAAUu6B,iBACrBp3B,EAAKy3B,iCACL/T,EAAKniB,QAAQqL,+CAER+oB,GAAY94B,GAK/B,MAAOM,MAuBf3M,EAAMmZ,SAAS+qB,EAAkBX,EAAKV,qBAYtCqB,EAAiBjjC,UAAUimC,aAA3B,WAAA,GAAAC,IAAA,EAAA/uB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA0C,QAAAysB,GAAex1B,GAAf,GAAA7K,GAAAsL,EAAA4mB,CAAA,OAAAjhB,GAAAja,QAAAka,KAAA,SAAAovB,GAAA,OAAA,OAAAA,EAAAlvB,KAAAkvB,EAAAhoC,MAAA,IAAA,GAAA,GAChC0H,EAAU6K,EAAM2B,iBAEjBxM,EAAQu2B,YAAev2B,EAAQwwB,YAC/BxwB,EAAQ8xB,WAJyB,CAAAwO,EAAAhoC,KAAA,CAAA,OAAA,KAM5B,IAAIkkC,GAAKR,gBAAgB,0BANG,KAAA,GAAA,MActC/kC,MAAKspC,uBAAuB11B,GAExBS,MAhBkC,GAAAg1B,EAAAlvB,KAAA,EAAAkvB,EAAAhoC,KAAA,GAAA,EAAA+Y,EAAAtG,SAkBtB9T,KAAKqxB,WAAWqO,oBACxB9rB,EAAMlC,YAAa3I,EAAQu2B,WAAYv2B,EAAQwwB,WAAYxwB,EAAQ8xB,WACnEjnB,EAAM6P,QAAS7P,EAAM21B,SApBS,KAAA,GAkBlCl1B,EAlBkCg1B,EAAA/uB,KAAA+uB,EAAAhoC,KAAA,EAAA,MAAA,KAAA,IAAA,KAAAgoC,GAAAlvB,KAAA,GAAAkvB,EAAA1X,GAAA0X,EAAA,MAAA,GAuBhB,8BAAdA,EAAA1X,GAAEiI,SACF55B,KAAKwpC,qBAAqB51B,GAExB,GAAI2xB,GAAKR,gBACXsE,EAAA1X,GAAE8X,YACEllC,QAASwE,EAAQu2B,WAAa,IAAMv2B,EAAQwwB,YA5BlB,KAAA,IAAA,GAiC1B,OAARllB,EAjCkC,CAAAg1B,EAAAhoC,KAAA,EAAA,OAAA,KAyClCrB,MAAKwpC,qBAAqB51B,GACpB,GAAI2xB,GAAKR,gBACX,kEAEIxgC,QAASwE,EAAQu2B,WAAa,IAAMv2B,EAAQwwB,YA7ClB,KAAA,IAAA,GAoDtCv5B,KAAK0pC,4BAA4B91B,GAE3BqnB,EAAU5C,KAAKrM,MAAM3X,EAAIyY,QAK3BmO,EAAQnwB,UAAY8I,EAAMlC,YA3DQ,CAAA23B,EAAAhoC,KAAA,EAAA,OAAA,KA4D5B,IAAIkkC,GAAKR,gBACX,6BAA+B9J,EAAQnwB,QA7DT,KAAA,IAAA,MAAAu+B,GAAAtsB,OAAA,UAkElC4sB,WAAY1O,EACZ8C,oBAAqB1pB,EAAI4f,UACzB2V,kBAAmBv1B,EAAIoqB,YAAY/F,QACnC6F,6BAA8BlqB,EAAIkqB,8BArEA,KAAA,IAAA,IAAA,MAAA,MAAA8K,GAAA9uB,SAAA6uB,EAAAppC,OAAA,EAAA,QAA1C,OAAA,UAAAw6B,GAAA,MAAA2O,GAAAzoC,MAAAV,KAAAK,eAyEA6lC,EAAiBjjC,UAAUumC,qBAAuB,SAAS51B,GACvD,GAAMi2B,GAASj2B,EAAMmD,YACf+yB,EAAcl2B,EAAM2B,iBAIpB2sB,IACFv6B,OAAQ3H,KAAKykC,QAASp2B,SAAU,KAEhCw7B,IAAU7pC,KAAKykC,SACfvC,EAAWtrB,MACPjP,OAAQkiC,EAAQx7B,SAAUy7B,EAAY98B,YAI9ChN,KAAK+S,QAAQg3B,gBACTj/B,QAAS8I,EAAMlC,YACfsiB,UAAW8V,EAAY9V,UACvBsL,WAAYwK,EAAYxK,WACxB/F,WAAYuQ,EAAYvQ,YACzB2I,IAUPgE,EAAiBjjC,UAAUqmC,uBAAyB,SAAS11B,GACzD,GAAM7K,GAAU6K,EAAM2B,iBAChB8vB,EAAIt8B,EAAQu2B,WAAa,IAAMv2B,EAAQwwB,UACxCv5B,MAAKmmC,eAAed,KACrBrlC,KAAKmmC,eAAed,GAAK,GAAA2E,GAAAjqC,SAE7BC,KAAKmmC,eAAed,GAAG4E,IAAIr2B,IAU/BsyB,EAAiBjjC,UAAUymC,4BAA8B,SAAS91B,GAC9D,GAAM7K,GAAU6K,EAAM2B,iBAChB8vB,EAAIt8B,EAAQu2B,WAAa,IAAMv2B,EAAQwwB,UACxCv5B,MAAKmmC,eAAed,KAIzBrlC,KAAKmmC,eAAed,GAAG6E,OAAOt2B,GACM,IAAhC5T,KAAKmmC,eAAed,GAAG8E,YAChBnqC,MAAKmmC,eAAed,KAUnCa,EAAiBjjC,UAAUmnC,eAAiB,SAASx2B,GAAO,GAAAkiB,GAAA91B,KAClD+I,EAAU6K,EAAMiD,aAChB5S,EAAY8E,EAAQwwB,WACtBtF,EAAYrgB,EAAMy2B,eAClBC,KACA5L,GAAe,EACfD,MAAA,EAEJ,KAAK11B,EAAQ+B,UACR7G,IACA8E,EAAQ80B,YAGT,WADAppB,SAAQC,MAAM,8BAIlB,KAAKuf,EAED,WADAxf,SAAQC,MAAM,+CAIlB,IAAuB,wBAAnBd,EAAMwC,UAAqC,CAY3C,GAXAsoB,GAAe,EACf4L,EAAqBvhC,EAAQy2B,gCACxBx9B,EAAMuoC,QAAQD,KACfA,MAIJA,EAAqBA,EAAmBxZ,QACxCwZ,EAAmB1zB,KAAKqd,KAExBA,EAAYlrB,EAAQu2B,YAGhB,WADA7qB,SAAQC,MAAM,uDAIlB,IAAM81B,GAAazhC,EAAQq4B,0BAC3B,KAAKoJ,EAID,WAHA/1B,SAAQC,MAAR,uEAMJ+pB,IACI/F,QAAS8R,OAGb/L,GAAc7qB,EAAM62B,gBAGxBh2B,SAAQe,IAAR,iCAA6Cye,EAA7C,IAA0DhwB,GAC1DjE,KAAKqxB,WAAWgN,uBACZt1B,EAAQ+B,QAASmpB,EAAWqW,EAAoBrmC,EAChD8E,EAAQ80B,YAAaY,EACrBC,GACF96B,KAAK,WAEHkyB,EAAK/iB,QAAQ23B,sBACT1W,UAAWjrB,EAAQirB,UACnBlpB,QAAS/B,EAAQ+B,QACjByuB,WAAYxwB,EAAQwwB,WACpB+F,WAAYrL,IAIhB6B,EAAK6U,iBAAiB1W,EAAWhwB,KAClCq/B,MAAM,SAACnlC,GACNsW,QAAQC,MAAR,oCAAkDvW,MAO1D+nC,EAAiBjjC,UAAU2nC,qBAAuB,SAAS9F,GACvD,GAAM9/B,GAAO8/B,EAAW9C,WAExB,OAAOhiC,MAAKqxB,WAAWkP,sBACnBv7B,EAAK8F,QACL9F,EAAKs6B,WACLt6B,EAAKu0B,aAQb2M,EAAiBjjC,UAAU4nC,oBAAsB,SAAS/F,GAAY,GAAA9O,GAAAh2B,KAC5D2H,EAASm9B,EAAWn9B,OACpB0G,EAAWy2B,EAAWz2B,SACtB+4B,EAAapnC,KAAK+S,QAAQ4K,gBAAgBhW,EAAQ0G,GAClDrJ,EAAO8/B,EAAW9C,WAExBhiC,MAAKomC,OAAOmC,4BACRvoC,KAAKqxB,WAAYrxB,KAAKw1B,WAD1B,EAAAsV,EAAA/qC,YAES4H,GAAUy/B,KAEjBxjC,KAAK,SAAC6jC,GAEJ,MADyBA,GAAU9/B,GAAQ0G,GACrBpK,WAStBwQ,QAAQe,IACJ,4BAA8BxQ,EAAKs6B,WAAa,IAC9Ct6B,EAAKu0B,WAAa,gBAClB5xB,EAAS,IAAM0G,GAGd2nB,EAAK+U,2BACR/lC,EAAK8F,QAAS9F,EAAKs6B,WAAYt6B,EAAKu0B,aAV7B,OAYZ31B,KAAK,SAACq3B,GACL,GAAMkN,IACFnU,UAAWoS,EAAOlS,cAClBoL,WAAYtJ,EAAK3E,WAAW8F,oBAC5B0D,cAGJ,OAAO7E,GAAKoQ,OAAOiC,wBACfF,EAAiBtN,WACjB7E,EAAKyO,QACLzO,EAAKvE,UACLuE,EAAK3E,WACL1pB,EACAy/B,EACAnM,GACFr3B,KAAK,WACH,GAAMuM,IAAA,EAAA26B,EAAA/qC,YACD4H,GADC,EAAAmjC,EAAA/qC,YAEGsO,EAAW85B,GAKpB,OAAOnS,GAAKR,UAAUtlB,aAAa,mBAAoBC,OAE5D7O,QAGP4kC,EAAiBjjC,UAAU8nC,2BAA3B,WAAA,GAAAzsB,IAAA,EAAAlE,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAwD,QAAAquB,GACpDjkC,EAAQktB,EAAWhwB,GADiC,GAAA+f,EAAA,OAAAhK,GAAAja,QAAAka,KAAA,SAAAgxB,GAAA,OAAA,OAAAA,EAAA9wB,KAAA8wB,EAAA5pC,MAAA,IAAA,GAAA,MAAA4pC,GAAA5pC,KAAA,GAAA,EAAA+Y,EAAAtG,SAGlC9T,KAAKqxB,WAAWuP,0BAC9B75B,EAAQktB,EAAWhwB,GAJ6B,KAAA,GAAA,MAG9C+f,GAH8CinB,EAAA3wB,KAAA2wB,EAAAluB,OAAA,UAQhDxX,KAAM,uBACNwD,SACIirB,UAAWoS,EAAOjS,iBAClBrpB,QAAS/D,EACTu4B,WAAYrL,EACZmN,2BAA4Bpd,EAAIod,2BAChC7H,WAAYt1B,EACZ45B,YAAa7Z,EAAIA,IACjB2Z,YAAa3Z,EAAI2Z,YACjB6B,gCAAiCxb,EAAIwb,kCAjBO,KAAA,GAAA,IAAA,MAAA,MAAAyL,GAAA1wB,SAAAywB,EAAAhrC,QAAxD,OAAA,UAAAk7B,EAAAC,EAAAC,GAAA,MAAA9c,GAAA5d,MAAAV,KAAAK,eA2BA6lC,EAAiBjjC,UAAUioC,cAAgB,SAAS3mC,GAChDvE,KAAKqxB,WAAW+N,0BAA0B76B,GAG1CvE,KAAK2qC,iBAAiBpmC,EAAQ+6B,WAAY/6B,EAAQg1B,aAUtD2M,EAAiBjjC,UAAU0nC,iBAAmB,SAAS1W,EAAWhwB,GAC9D,GAAMohC,GAAIpR,EAAY,IAAMhwB,EACtBknC,EAAUnrC,KAAKmmC,eAAed,EACpC,IAAK8F,EAAL,OAIOnrC,MAAKmmC,eAAed,EAP8C,IAAAlP,IAAA,EAAAC,GAAA,EAAAC,MAAAp1B,EAAA,KASzE,IAAA,GAAAq1B,GAAAC,GAAA,EAAAn1B,EAAArB,SAAiBorC,KAAjBhV,GAAAG,EAAAC,EAAAl1B,QAAAC,MAAA60B,GAAA,EAA0B,CAAAG,EAAA/0B,MACnBmY,kBAAkB1Z,KAAK+S,UAV2C,MAAAnR,GAAAw0B,GAAA,EAAAC,EAAAz0B,EAAA,QAAA,KAAAu0B,GAAAI,EAAA10B,QAAA00B,EAAA10B,SAAA,QAAA,GAAAu0B,EAAA,KAAAC,OAc7EkP,EAAKpB,kBACDiC,EAAOjS,iBAAkByR,EAAkBM,mTC16B/C,gEA0BA,QAASkF,GAAc5mC,GACnB+gC,EAAKf,oBAAoBtlC,KAAKc,KAAMwE,GACpCxE,KAAKqrC,kBAAmB,EACxBrrC,KAAKsrC,aAAe,KAyGxB,QAASC,GAAc/mC,GACnB+gC,EAAKV,oBAAoB3lC,KAAKc,KAAMwE,yHA9HlCxC,EAAQrD,EAAQ,eAChBynC,EAASznC,EAAQ,aACjB6sC,EAAa7sC,EAAQ,iBACrB8sC,EAAqBD,EAAWC,mBAGhClG,EAAO5mC,EAAQ,SAgBrBqD,GAAMmZ,SAASiwB,EAAe7F,EAAKf,qBAQnC4G,EAAcnoC,UAAUyoC,eAAiB,SAAS5C,GAC9C,GAAI9oC,KAAKsrC,aAEL,MAAOtrC,MAAKsrC,YAGhB,IAAItrC,KAAKqrC,iBAEL,MAAOx3B,GAAA9T,QAAQ+T,SAGnB,IAAMzC,GAAOrR,IAQb,OAPAA,MAAKsrC,aAAej6B,EAAK0B,QAAQuK,aAAawrB,GAAallC,KAAK,SAASyQ,GACrE,MAAOhD,GAAK0B,QAAQ44B,0BAA0B7C,KAC/CllC,KAAK,WACJyN,EAAKg6B,kBAAmB,IACzB5iB,QAAQ,WACPpX,EAAKi6B,aAAe,OAEjBtrC,KAAKsrC,cAYhBF,EAAcnoC,UAAUk5B,eAAiB,SAAS3qB,EAAMlI,EAAWP,GAM/D,GAAMoZ,GAAQngB,EAAMme,IAAI3O,EAAKu3B,mBAAoB,SAAStqC,GACtD,MAAOA,GAAEkJ,SAGP0J,EAAOrR,IACb,OAAOA,MAAK0rC,eAAevpB,GAAOve,KAAK,WAenC,IAAK,GAdCgoC,IACF9gC,QAAS0G,EAAKzK,OACdxB,KAAM+D,EACNP,QAASA,GAGPo/B,GACFnU,UAAWoS,EAAOlS,cAClBoL,WAAYjuB,EAAKggB,WAAW8F,oBAC5B0D,eAGEvf,KAEG1c,EAAI,EAAGA,EAAIujB,EAAMhjB,SAAUP,EAIhC,IAAK,GAHC+I,GAASwa,EAAMvjB,GACf+P,EAAU0C,EAAK0B,QAAQyK,wBAAwB7V,GAE5CkkC,EAAI,EAAGA,EAAIl9B,EAAQxP,SAAU0sC,EAAG,CACrC,GAAMzE,GAAaz4B,EAAQk9B,GACrB7nB,EAAMojB,EAAWE,gBACnBtjB,IAAO3S,EAAKggB,WAAW8F,sBAIvBiQ,EAAWxtB,UAAY6xB,EAAmBK,SAK9CxwB,EAAS1E,KACLwvB,EAAOiC,wBACHF,EAAiBtN,WACjBxpB,EAAKozB,QAASpzB,EAAKogB,UAAWpgB,EAAKggB,WACnC1pB,EAAQy/B,EAAYwE,KAMpC,MAAO/3B,GAAA9T,QAAQyb,IAAIF,GAAUzZ,OAAOsmC,MAe5CnmC,EAAMmZ,SAASowB,EAAehG,EAAKV,qBAYnC0G,EAActoC,UAAUimC,aAAxB,WAAA,GAAAlC,IAAA,EAAA5sB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAuC,QAAAC,GAAehJ,GAAf,GAAA7K,GAAAsrB,EAAAwG,EAAAjB,EAAA7C,EAAAkE,EAAAgG,CAAA,OAAAjnB,GAAAja,QAAAka,KAAA,SAAA6C,GAAA,OAAA,OAAAA,EAAA3C,KAAA2C,EAAAzb,MAAA,IAAA,GAAA,GAC7B0H,EAAU6K,EAAM2B,iBAChB8e,EAAYtrB,EAAQu2B,WACpBzE,EAAa9xB,EAAQ8xB,WAHQ,CAAA/d,EAAAzb,KAAA,CAAA,OAAA,KAMzB,IAAIkkC,GAAKR,gBAAgB,qBANA,KAAA,GAAA,GAS7B/kC,KAAKqxB,WAAW8F,sBAAuB0D,GATV,CAAA/d,EAAAzb,KAAA,CAAA,OAAA,KAUzB,IAAIkkC,GAAKR,gBAAgB,6BAVA,KAAA,GAAA,MAY7BnL,GAAUiB,EAAW76B,KAAKqxB,WAAW8F,qBACvCJ,MAb+B,GAAAja,EAAA3C,KAAA,EAAA2C,EAAAzb,KAAA,IAAA,EAAA+Y,EAAAtG,SAgBT9T,KAAK+rC,gBAAgB1X,EAAWuF,GAhBvB,KAAA,IAgB/B7C,EAhB+Bja,EAAAxC,KAAAwC,EAAAzb,KAAA,EAAA,MAAA,KAAA,IAAA,KAAAyb,GAAA3C,KAAA,GAAA2C,EAAA6U,GAAA7U,EAAA,MAAA,GAkBzB,GAAIyoB,GAAKR,gBACX,yBACI8E,OAAQxV,EACRzyB,IAAAkb,EAAA6U,IArBuB,KAAA,IAAA,GA0B7BsJ,EAAU5C,KAAKrM,MAAM+K,GAIvBkE,EAAQ+Q,WAAahsC,KAAKykC,QA9BK,CAAA3nB,EAAAzb,KAAA,EAAA,OAAA,KA+BzB,IAAIkkC,GAAKR,gBACX,4BAA8B9J,EAAQ+Q,UAhCX,KAAA,IAAA,GAoC/B/Q,EAAQgR,eAAevT,SAAW14B,KAAKqxB,WAAW+F,iBApCnB,CAAAta,EAAAzb,KAAA,EAAA,OAAA,KAqCzB,IAAIkkC,GAAKR,gBACX,wCACImH,SAAUjR,EAAQgR,eAAevT,QACjCyT,QAASnsC,KAAKqxB,WAAW+F,kBAxCF,KAAA,IAAA,GAiD/B6D,EAAQ4O,QAAUj2B,EAAMmD,YAjDO,CAAA+F,EAAAzb,KAAA,EAAA,OAAA,KAkDzB,IAAIkkC,GAAKR,gBACX,0BAA4B9J,EAAQ4O,QAChCuC,gBAAiBx4B,EAAMmD,aApDA,KAAA,IAAA,GA0D/BkkB,EAAQnwB,UAAY8I,EAAMlC,YA1DK,CAAAoL,EAAAzb,KAAA,EAAA,OAAA,KA2DzB,IAAIkkC,GAAKR,gBACX,6BAA+B9J,EAAQnwB,SACnCuhC,cAAez4B,EAAM9I,SA7DE,KAAA,IAAA,MAkE7Bm2B,GAAchG,EAAQ3b,SAlEOxC,EAAAC,OAAA,UAqE/B4sB,WAAY1O,EACZ8C,oBAAqB1J,EACrBuV,kBAAmB3I,EAAYvI,SAAW,MAvEX,KAAA,IAAA,IAAA,MAAA,MAAA5b,GAAAvC,SAAAqC,EAAA5c,OAAA,EAAA,QAAvC,OAAA,UAAA0d,GAAA,MAAAspB,GAAAtmC,MAAAV,KAAAK,eAmFAkrC,EAActoC,UAAU8oC,gBAAxB,WAAA,GAAAtuB,IAAA,EAAArD,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA0C,QAAAhD,GACtCghB,EAAwBf,GADc,GAAA8B,GAAA4Q,EAAA1tC,EAAAqF,EAAAg3B,EAAAsR,EAAAl4B,CAAA,OAAA2F,GAAAja,QAAAka,KAAA,SAAAC,GAAA,OAAA,OAAAA,EAAAC,KAAAD,EAAA7Y,MAAA,IAAA,GAAA,MAAA6Y,GAAA7Y,KAAA,GAAA,EAAA+Y,EAAAtG,SAGb9T,KAAKqxB,WAAWgK,uBACrCV,GAJkC,KAAA,GAGhCe,EAHgCxhB,EAAAI,KAQhCgyB,KACG1tC,EAAI,CATyB,KAAA,GAAA,KAStBA,EAAI88B,EAAWv8B,QATO,CAAA+a,EAAA7Y,KAAA,EAAA,OAAA,MAU5B4C,GAAYy3B,EAAW98B,GAVKsb,EAAAC,KAAA,EAAAD,EAAA7Y,KAAA,IAAA,EAAA+Y,EAAAtG,SAYR9T,KAAKqxB,WAAWmL,eAClC7B,EAAwB12B,EAAW21B,EAAQr0B,KAAMq0B,EAAQ50B,MAb/B,KAAA,IAAA,MAYxBi2B,GAZwB/gB,EAAAI,KAe9B7F,QAAQe,IACJ,8BAAgCmlB,EAC5B,iBAAmB12B,GAjBGiW,EAAA6C,OAAA,SAmBvBke,EAnBuB,KAAA,IAAA,MAAA/gB,GAAAC,KAAA,GAAAD,EAAAyX,GAAAzX,EAAA,MAAA,GAAAA,EAAA7Y,KAAA,IAAA,EAAA+Y,EAAAtG,SAqBH9T,KAAKqxB,WAAWyL,eACvCnC,EAAwB12B,EAAW21B,EAAQr0B,KAAMq0B,EAAQ50B,MAtB/B,KAAA,IAAA,KAqBxBunC,EArBwBryB,EAAAI,MAAA,CAAAJ,EAAA7Y,KAAA,EAAA,OAAA,KA4BpB,IAAIvC,OACN,4DACImF,EAAY,KAAOiW,EAAAyX,GAAEiI,QA9BH,KAAA,IAoC9B0S,EAAiBroC,GAAaiW,EAAAyX,GAAEiI,OApCF,KAAA,IASCh7B,IATDsb,EAAA7Y,KAAA,CAAA,MAAA,KAAA,IAAA,GAwCjB,IAAjBu4B,EAAQr0B,KAxC0B,CAAA2U,EAAA7Y,KAAA,EAAA,OAAA,GA4CR,IAAtBq6B,EAAWv8B,OA5CmB,CAAA+a,EAAA7Y,KAAA,EAAA,OAAA,KA6CxB,IAAIvC,OAAM;uCA7Cc,KAAA,IAAA,KAgD5B,IAAIA,OACN,gEACI,EAAAurB,EAAAtqB,SAAeusC,GAlDW,KAAA,IAAA,MAyDlCj4B,OAzDkC,GAAA6F,EAAAC,KAAA,GAAAD,EAAA7Y,KAAA,IAAA,EAAA+Y,EAAAtG,SA2DtB9T,KAAKqxB,WAAWoJ,qBACxBE,EAAwBf,EAAQr0B,KAAMq0B,EAAQ50B,MA5DhB,KAAA,IA2DlCqP,EA3DkC6F,EAAAI,KAAAJ,EAAA7Y,KAAA,EAAA,MAAA,KAAA,IAAA,KAAA6Y,GAAAC,KAAA,GAAAD,EAAA0X,GAAA1X,EAAA,MAAA,IA+DlCoyB,EAAiB,SAAWpyB,EAAA0X,GAAEgI,QACxB,GAAI96B,OACN,qCACI,EAAAurB,EAAAtqB,SAAeusC,GAlEW,KAAA,IAAA,MAsEtC73B,SAAQe,IACJ,sCACInB,EAAIklB,WAAa,SAAWoB,GAxEEzgB,EAAA6C,OAAA,SA0E/B1I,EAAI4mB,QA1E2B,KAAA,IAAA,IAAA,MAAA,MAAA/gB,GAAAK,SAAAZ,EAAA3Z,OAAA,EAAA,KAAA,GAAA,QAA1C,OAAA,UAAA6d,EAAAC,GAAA,MAAAL,GAAA/c,MAAAV,KAAAK,eA8EAklC,EAAKpB,kBAAkBiC,EAAOlS,cAAekX,EAAeG,8KCtT5D,YA+BA,SAASC,GAAWn9B,GAEhBm+B,OAAOC,eAAezsC,KAAM,YACxB0sC,YAAY,EACZnrC,MAAO8M,IAGXrO,KAAKyyB,cACLzyB,KAAKsf,QACLtf,KAAK4Z,SAAW6xB,EAAmBkB,WACnC3sC,KAAK8Z,OAAQ,EACb9Z,KAAKmyB,YAWTqZ,EAAWzX,YAAc,SAAS6Y,EAAKv+B,GACnC,GAAMgG,GAAM,GAAIm3B,GAAWn9B,EAC3B,KAAK,GAAMw+B,KAAQD,GACXA,EAAI/a,eAAegb,KACnBx4B,EAAIw4B,GAAQD,EAAIC,GAGxB,OAAOx4B,IAQXm3B,EAAWvoC,UAAU2zB,UAAY,WAC7B,OACInE,WAAYzyB,KAAKyyB,WACjBnT,KAAMtf,KAAKsf,KACX1F,SAAU5Z,KAAK4Z,SACfE,MAAO9Z,KAAK8Z,MACZqY,SAAUnyB,KAAKmyB,WASvBqZ,EAAWvoC,UAAUsvB,eAAiB,WAClC,MAAOvyB,MAAKsf,KAAK,WAAatf,KAAKqO,WAQvCm9B,EAAWvoC,UAAUqkC,eAAiB,WAClC,MAAOtnC,MAAKsf,KAAK,cAAgBtf,KAAKqO,WAQ1Cm9B,EAAWvoC,UAAU6pC,eAAiB,WAClC,MAAO9sC,MAAKmyB,SAAS4a,qBAAuB,MAQhDvB,EAAWvoC,UAAU+lC,UAAY,WAC7B,MAAOhpC,MAAK4Z,UAAY6xB,EAAmBK,SAQ/CN,EAAWvoC,UAAU4b,WAAa,WAC9B,MAAO7e,MAAK4Z,UAAY6xB,EAAmBuB,UAQ/CxB,EAAWvoC,UAAU2lC,aAAe,WAChC,MAAO5oC,MAAK4Z,UAAY6xB,EAAmBkB,YAQ/CnB,EAAWvoC,UAAU4lC,QAAU,WAC3B,MAAqB,IAAd7oC,KAAK8Z,OAMhB0xB,EAAWC,oBACPuB,SAAU,EACVL,WAAY,EACZb,SAAU,EAGd,IAAML,GAAqBD,EAAWC,kBAGtCpsC,GAAOJ,QAAUusC,2BCxJjB,gEA4CA,QAASh4B,GAAOuf,EAAU5f,EAAcxL,EAAQ0G,EAChC4+B,EAAah6B,GACzBjT,KAAKw1B,UAAYzC,EACjB/yB,KAAKkT,cAAgBC,EACrBnT,KAAKykC,QAAU98B,EACf3H,KAAKyxB,UAAYpjB,EACjBrO,KAAKktC,aAAeD,EACpBjtC,KAAKgT,aAAeC,EAEpBjT,KAAKqxB,WAAa,GAAI4F,GAAU9jB,GAChCnT,KAAKmtC,YAAc,GAAIra,GAAWC,EAAU5f,EAAcnT,KAAKqxB,YAI/DrxB,KAAKotC,qBAAuB,KAC5BptC,KAAKqtC,4BAA6B,EAGlCrtC,KAAKstC,mBAGLttC,KAAKutC,mBAELvtC,KAAKwtC,qBAAuBxrC,EAAMsd,KAC9BmT,EAAW8R,oBAGfvkC,KAAKytC,eAELztC,KAAK0tC,mCAAoC,EAEzC1tC,KAAK2tC,+BAAiC,GAAAC,GAAA7tC,QACjCgzB,EAAU/yB,KAAKyxB,UAAWzxB,KAAKgT,cAKpChT,KAAK6tC,4BACL7tC,KAAK8tC,wCAEL9tC,KAAK+tC,4BAA6B,EAyJtC,QAASC,GAAwBnxB,GA8C7B,QAASoxB,GAAWC,GAChB,GAAIC,GAAYD,EAEZ,MAAOr6B,GAAA9T,QAAQ+T,SAGnB,IAAMs6B,GAAennB,KAAKonB,IAAIF,EAAWD,EAAUI,EAGnD,OAAOzxB,GAAOwU,WAAW4I,oBAAoBmU,GAAcxqC,KAAK,WAC5D,MAAO2qC,GAAmB1xB,KAC3BjZ,KAAK,SAACyQ,GACL,GAAIA,EAAIm6B,qBAAuBn6B,EAAIm6B,oBAAoBC,kBAGnD,MAAOR,GAAW55B,EAAIm6B,oBAAoBC,kBAE1C,MAAM,IAAI3vC,OAAM,wFA7D5B,GAMMwvC,GAAkB,CAExB,KAAIzxB,EAAOwwB,2BAAX,CAIA,GAAMrmB,GAAMzjB,KAAKyjB,KACjB,MAAoC,OAAhCnK,EAAOuwB,sBACPpmB,EAAMnK,EAAOuwB,qBAdI,KAarB,CAOAvwB,EAAOuwB,qBAAuBpmB,CAe9B,IAAM0nB,GAAiB7xB,EAAOwU,WAAWyI,yBAOnCqU,EAAWlnB,KAAKyJ,MAAMge,EAAiB,EAyB7C7xB,GAAOwwB,4BAA6B,EACpCx5B,EAAA9T,QAAQ+T,UAAUlQ,KAAK,WACnB,WAAgC3C,KAA5B4b,EAAO8xB,iBAGA96B,EAAA9T,QAAQ+T,QAAQ+I,EAAO8xB,kBAG3B9xB,EAAO2Y,UAAUpnB,sBACpBpB,UAAW6P,EAAO4U,YACnB7tB,KAAK,SAACyQ,GACL,MAAOA,GAAIm6B,oBAAoBC,mBAAqB,MAEzD7qC,KAAK,SAACsqC,GAKL,MAAOD,GAAWC,KACnB5K,MAAM,SAACnlC,GACNsW,QAAQC,MAAM,gCAAiCvW,EAAEwW,OAASxW,KAC3DsqB,QAAQ,WAGP5L,EAAO8xB,qBAAmB1tC,GAC1B4b,EAAOwwB,4BAA6B,IACrC/rC,oOAIP,QAAAqY,GAAkCkD,GAAlC,GAAA+xB,GAAAC,EAAAvzB,EAAA8Y,EAAAiR,EAAAhxB,CAAA,OAAA2F,GAAAja,QAAAka,KAAA,SAAAC,GAAA,OAAA,OAAAA,EAAAC,KAAAD,EAAA7Y,MAAA,IAAA,GAAA,MAAA6Y,GAAA7Y,KAAA,GAAA,EAAA+Y,EAAAtG,SAC8B+I,EAAOwU,WAAWwI,iBADhD,KAAA,GACU+U,EADV10B,EAAAI,KAEUu0B,KAEAvzB,IAEN,KAAW8Y,IAASwa,GAAYnW,WACxBmW,EAAYnW,WAAW5G,eAAeuC,KAChCiR,GACFrhB,IAAK4qB,EAAYnW,WAAWrE,IAEhCya,EAAY,qBAAuBza,GAASiR,EAC5C/pB,EAAS1E,KAAKiG,EAAOiyB,YAAYzJ,IAZ7C,OAAAnrB,GAAA7Y,KAAA,GAAA,EAAA+Y,EAAAtG,SAgBUD,EAAA9T,QAAQyb,IAAIF,GAhBtB,KAAA,GAAA,MAAApB,GAAA7Y,KAAA,IAAA,EAAA+Y,EAAAtG,SAkBsB+I,EAAO2Y,UAAUpnB,mBAC/BW,cAAe8/B,IAIf7hC,UAAW6P,EAAO4U,YAvB1B,KAAA,IAAA,MAkBUpd,GAlBV6F,EAAAI,KAAAJ,EAAA7Y,KAAA,IAAA,EAAA+Y,EAAAtG,SA0BU+I,EAAOwU,WAAW0I,sBA1B5B,KAAA,IAAA,MAAA7f,GAAA6C,OAAA,SA2BW1I,EA3BX,KAAA,IAAA,IAAA,MAAA,MAAA6F,GAAAK,SAAAZ,EAAA3Z,+DAxUA+uC,EAAApwC,EAAA,UAUAqwC,EAAArwC,EAAA,0CAZMswC,EAActwC,EAAQ,gBAItBqD,EAAQrD,EAAQ,YAChBs4B,EAAYt4B,EAAQ,eACpBynC,EAASznC,EAAQ,YACjB8zB,EAAa9zB,EAAQ,gBACrB6sC,EAAa7sC,EAAQ,gBACrB8sC,EAAqBD,EAAWC,mBAChC3Y,EAAan0B,EAAQ,gBAAgBoB,OAsE3CiC,GAAMmZ,SAAS3H,EAAfu7B,EAAAr0B,cAOAlH,EAAOvQ,UAAU+Z,MAAjB,EAAA5C,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAwB,QAAAC,KAAA,GAAAsyB,GAAA9H,CAAA,OAAAptB,GAAAja,QAAAka,KAAA,SAAA6C,GAAA,OAAA,OAAAA,EAAA3C,KAAA2C,EAAAzb,MAAA,IAAA,GAAA,MAAAyb,GAAAzb,KAAA,GAAA,EAAA+Y,EAAAtG,SACd9T,KAAKqxB,WAAWrU,OADF,KAAA,GAIpBhd,KAAKytC,YAAY,WAAaztC,KAAKyxB,WAC/BzxB,KAAKqxB,WAAW+F,iBACpBp3B,KAAKytC,YAAY,cAAgBztC,KAAKyxB,WAClCzxB,KAAKqxB,WAAW8F,oBAEhB+X,EAAYlvC,KAAKkT,cAAc4gB,0BAC/B9zB,KAAKykC,SAGJyK,IACDA,MAGCA,EAAUlvC,KAAKyxB,aAEV2V,GACF9nB,KAAMtf,KAAKytC,YACXhb,WAAYzyB,KAAKwtC,qBACjB5zB,SAAU6xB,EAAmBuB,SAC7BlzB,OAAO,GAGXo1B,EAAUlvC,KAAKyxB,WAAa2V,EAC5BpnC,KAAKkT,cAAc2jB,4BACf72B,KAAKykC,QAASyK,GA5BF,KAAA,GAAA,IAAA,MAAA,MAAApyB,GAAAvC,SAAAqC,EAAA5c,SAwCxBwT,EAAOvQ,UAAUga,sBAAwB,SAASkyB,GAC9C,GAAMtyB,GAAS7c,IAEfmvC,GAAaxtC,GAAG,wBAAyB,SAASiS,EAAO+wB,EAAQC,GAC7D,IACI/nB,EAAOuyB,kBAAkBx7B,EAAO+wB,EAAQC,GAC1C,MAAOzmC,GACJsW,QAAQC,MAAM,oCAAqCvW,MAI5DgxC,EAAaxtC,GAAG,gBAAiB,SAASiS,GACtCiJ,EAAOwyB,iBAAiBz7B,MAMhCJ,EAAOvQ,UAAUomB,MAAQ,WACrBrpB,KAAK2tC,+BAA+BtkB,SAIxC7V,EAAOvQ,UAAUsX,KAAO,WACpBva,KAAK2tC,+BAA+BpzB,QAMxC/G,EAAOC,cAAgB,WACnB,MAAOwjB,GAAUxjB,iBAQrBD,EAAOvQ,UAAUka,oBAAsB,WACnC,MAAOnd,MAAKqxB,WAAW+F,kBAW3B5jB,EAAOvQ,UAAUkb,oCAAsC,SAAS5c,GAC5DvB,KAAK0tC,kCAAoCnsC,GAM7CiS,EAAOvQ,UAAUmb,oCAAsC,WACnD,MAAOpe,MAAK0tC,mCAOhBl6B,EAAOvQ,UAAUoa,iBAAmB,WAChC,GAAMR,GAAS7c,KACT2H,EAASkV,EAAO4nB,QAChBp2B,EAAWwO,EAAO4U,UAElB6d,GACF7c,WAAY5V,EAAO2wB,qBACnBxgC,UAAWqB,EACXiR,KAAMzC,EAAO4wB,YACbz3B,QAASrO,EAGb,OAAOkV,GAAOiyB,YAAYQ,GAAY1rC,KAAK,WACvCiZ,EAAO2Y,UAAUpnB,mBACbI,YAAa8gC,IAIbtiC,UAAWqB,OAWvBmF,EAAOvQ,UAAUssC,sBAAwB,SAASC,GAC9C,IAAIC,SAASD,GAGT,KAAM,IAAIE,WAAU,yDAFpB1vC,MAAK2uC,iBAAmBa,GAiJhCh8B,EAAOvQ,UAAUqa,aAAe,SAASrU,EAASsU,GAC9C,MAAOvd,MAAKmtC,YAAY7vB,aAAarU,EAASsU,IAWlD/J,EAAOvQ,UAAUua,wBAA0B,SAAS7V,GAChD,MAAO3H,MAAKmtC,YAAY3vB,wBAAwB7V,IAYpD6L,EAAOvQ,UAAU0a,gBAAkB,SAAShW,EAAQ0G,GAChD,MAAOrO,MAAKmtC,YAAYxvB,gBAAgBhW,EAAQ0G,IAoBpDmF,EAAOvQ,UAAUoX,sBAAjB,WAAA,GAAAuD,IAAA,EAAAxD,EAAAlE,QAAyC,SACrCvO,EAAQ0G,EAAUuL,EAAUC,EAASC,GAErC,GAAMnL,GAAU3O,KAAKkT,cAAc4gB,0BAA0BnsB,EAC7D,KAAKgH,IAAYA,EAAQN,GACrB,KAAM,IAAIvP,OAAM,kBAAoB6I,EAAS,IAAM0G,EAGvD,IAAM0L,GAAMpL,EAAQN,GAChBshC,EAAqB51B,EAAIH,QAEzBA,GACA+1B,EAAqBlE,EAAmBuB,SACpB,OAAbpzB,GAAqB+1B,GAAsBlE,EAAmBuB,WACrE2C,EAAqBlE,EAAmBkB,YAGxC9yB,EACA81B,EAAqBlE,EAAmBK,QACrB,OAAZjyB,GAAoB81B,GAAsBlE,EAAmBK,UACpE6D,EAAqBlE,EAAmBkB,WAG5C,IAAIiD,GAAc71B,EAAID,KAUtB,OATc,QAAVA,OAA4B7Y,KAAV6Y,IAClB81B,EAAc91B,GAGdC,EAAIH,WAAa+1B,GAAsB51B,EAAID,QAAU81B,IACrD71B,EAAIH,SAAW+1B,EACf51B,EAAID,MAAQ81B,EACZ5vC,KAAKkT,cAAc2jB,4BAA4BlvB,EAAQgH,IAEpD68B,EAAWzX,YAAYha,EAAK1L,IAjCvC,OAAA,UAAAwP,EAAAC,EAAA0c,EAAAU,EAAAC,GAAA,MAAAvd,GAAAld,MAAAV,KAAAK,eAmDAmT,EAAOvQ,UAAU4sC,sBAAjB,WAAA,GAAA1G,IAAA,EAAA/uB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAyC,QAAA+B,GAAe/W,GAAf,GAAAgH,GAAAme,EAAA+e,EAAAltB,EAAA0V,EAAA4E,CAAA,OAAAjf,GAAAja,QAAAka,KAAA,SAAA2E,GAAA,OAAA,OAAAA,EAAAzE,KAAAyE,EAAAvd,MAAA,IAAA,GAC/BsN,EAAU3O,KAAKwd,wBAAwB7V,OACvCmlB,KACG+e,EAAI,CAHwB,KAAA,GAAA,KAGrBA,EAAIl9B,EAAQxP,QAHS,CAAAyf,EAAAvd,KAAA,EAAA,OAAA,MAI3Bsd,GAAShQ,EAAQk9B,GACjBxX,EAAY1V,EAAO2oB,iBALQ1oB,EAAAvd,KAAA,GAAA,EAAA+Y,EAAAtG,SAMV9T,KAAKqxB,WAAWwK,wBAAwBxH,GAN9B,KAAA,GAM3B4E,EAN2Bra,EAAAtE,KAQjCwS,EAAOnO,EAAOtQ,WACVyhC,YAAazb,EACb4E,SAAUA,EAVmB,KAAA,MAGC4S,EAHDjtB,EAAAvd,KAAA,CAAA,MAAA,KAAA,IAAA,MAAAud,GAAA7B,OAAA,SAa9B+P,EAb8B,KAAA,IAAA,IAAA,MAAA,MAAAlO,GAAArE,SAAAmE,EAAA1e,QAAzC,OAAA,UAAAo7B,GAAA,MAAA+N,GAAAzoC,MAAAV,KAAAK,eAwBAmT,EAAOvQ,UAAUob,yBAA2B,SAASzK,GACjD,GAAMqgB,GAAYrgB,EAAMy2B,eAClBrW,EAAYpgB,EAAM2B,iBAAiBye,SAEzC,KAAKC,IAAcD,EACf,MAAO,KAIX,IADwBpgB,EAAMm8B,kCACV5wC,OAAS,EAGzB,MAAO,KAOX,IAAMwf,GAAS3e,KAAKmtC,YAAY6C,uBAC5Bp8B,EAAMmD,YAAaid,EAAWC,EAGlC,IAAe,OAAXtV,EAEA,MAAO,KAWX,IAAMsxB,GAAar8B,EAAMs8B,sBACzB,OAAKD,GAMDA,IAAetxB,EAAO4T,kBACtB9d,QAAQyG,KACJ,SAAWtH,EAAM6P,QAAU,uBAAyBwsB,EAChD,6BAA+BtxB,EAAO4T,kBACvC,MAGJ5T,GAZHlK,QAAQyG,KAAK,SAAWtH,EAAM6P,QAAU,wDAEjC,OAwBfjQ,EAAOvQ,UAAU8b,kBAAjB,WAAA,GAAAT,IAAA,EAAAlE,EAAAlE,QAAqC,SAAenP,EAAQiY,EAAQmxB,GAAoB,GAAAvgB,GAAA5vB,KAG9EowC,EAAiBpwC,KAAKkT,cAAciM,gBAAgBpY,EAC1D,IAAIqpC,IACI,EAAA/lB,EAAAtqB,SAAeqwC,KAAmB,EAAA/lB,EAAAtqB,SAAeif,GAGjD,WAFAvK,SAAQC,MAAM,yEAC2B3N,EAKjD,IAAMspC,GAAW5d,EAAW6R,mBAAmBtlB,EAAOgV,UACtD,KAAKqc,EACD,KAAM,IAAIvxC,OAAM,0BAA4BkgB,EAAOgV,UAGvDh0B,MAAKkT,cAAco9B,kBAAkBvpC,EAAQiY,EAE7C,IAAMuxB,GAAM,GAAIF,IACZ1oC,OAAQ3H,KAAKykC,QACbp2B,SAAUrO,KAAKyxB,UACf5U,OAAQ7c,KACRgzB,UAAWhzB,KAAKqxB,WAChB0B,SAAU/yB,KAAKw1B,UACfzuB,OAAQA,EACRiY,OAAQA,GAEZhf,MAAKstC,gBAAgBvmC,GAAUwpC,EAG/B97B,QAAQe,IAAI,0BAA4BzO,EAAS,yDAEjD,IAAMyK,GAAOxR,KAAKktC,aAAaz7B,QAAQ1K,EACvC,KAAKyK,EACD,KAAM,IAAI1S,OAAJ,+CAAyDiI,EAGnDyK,GAAKu3B,mBACbt6B,QAAQ,SAAC+hC,GACb5gB,EAAKud,YAAYsD,wBAAwBD,EAAE7oC,UAE1CwoC,GACDnwC,KAAKmtC,YAAYuD,8BA3CzB,OAAA,UAAAnV,EAAAK,EAAArd,GAAA,MAAAD,GAAA5d,MAAAV,KAAAK,eAiEAmT,EAAOvQ,UAAU0oC,0BAA4B,SAASxpB,GAGlD,IAAK,GAFCulB,MAEG9oC,EAAI,EAAGA,EAAIujB,EAAMhjB,SAAUP,EAAG,CACnC,GAAM+I,GAASwa,EAAMvjB,EACrB8oC,GAAc//B,KAGd,KAAK,GADCgH,GAAU3O,KAAKwd,wBAAwB7V,OACpCkkC,EAAI,EAAGA,EAAIl9B,EAAQxP,SAAU0sC,EAAG,CACrC,GAAMzE,GAAaz4B,EAAQk9B,EAEfzE,GAAWE,kBACZtnC,KAAKqxB,WAAW8F,sBAIvBiQ,EAAWxtB,UAAY6xB,EAAmBK,SAK9CpE,EAAc//B,GAAQiP,KAAKwwB,KAInC,MAAOhB,GAAOmC,4BACVvoC,KAAKqxB,WAAYrxB,KAAKw1B,UAAWkS,IASzCl0B,EAAOvQ,UAAU8R,gBAAkB,SAAShO,GACxC,MAAO6L,SAAQ5S,KAAKstC,gBAAgBvmC,KAUxCyM,EAAOvQ,UAAUmc,eAAiB,WAAW,GAAA8V,GAAAl1B,IACzC,OAAO6T,GAAA9T,QAAQogB,IACXngB,KAAKkT,cAAcy9B,wCACnB,SAACpyC,GACG,MAAO22B,GAAK7D,WAAWmQ,0BACnBjjC,EAAE01B,UAAW11B,EAAE0F,WACjBL,KAAK,SAACgtC,GAEJ,MADAA,GAAK5c,UAAYoS,EAAOjS,iBACjByc,OAYvBp9B,EAAOvQ,UAAUoc,eAAiB,SAASC,GAAM,GAAAwW,GAAA91B,IAC7C,OAAO6T,GAAA9T,QAAQogB,IACXb,EAAM,SAAC0E,GACH,MAAKA,GAAIlZ,SAAYkZ,EAAIgQ,UAKb8B,EAAK+a,kBAAkB7sB,EAAIlZ,QAASkZ,EAAIgQ,WACzCkX,cAAclnB,IALrBvP,QAAQyG,KAAK,8CAA+C8I,GACrD,SAmBvBxQ,EAAOvQ,UAAU+R,aAAe,SAASpB,EAAOpC,GAAM,GAAAwkB,GAAAh2B,IAClD,KAAKwR,EACD,KAAM,IAAI1S,OAAM,kDAGpB,IAAMiI,GAAS6M,EAAMlC,YAEf6+B,EAAMvwC,KAAKstC,gBAAgBvmC,EACjC,KAAKwpC,EAGD,KAAM,IAAIzxC,OACN,gIAMR,OAAOyxC,GAAIpU,eACP3qB,EAAMoC,EAAMwC,UAAWxC,EAAMiD,cAC/BjT,KAAK,SAACukC,GACJv0B,EAAMk9B,cACF,mBACA3I,EACAnS,EAAK3E,WAAW8F,oBAChBnB,EAAK3E,WAAW+F,qBAc5B5jB,EAAOvQ,UAAUimC,aAAe,SAASt1B,GACrC,GAAIA,EAAMm9B,aACN,MAAOl9B,GAAA9T,QAAQ+T,SACX61B,YACI7+B,QAAS8I,EAAMlC,YACfnM,KAAM,iBACNwD,aAIZ,IAAMA,GAAU6K,EAAM2B,gBAEtB,OADYvV,MAAK6wC,kBAAkBj9B,EAAMlC,YAAa3I,EAAQirB,WACnDkV,aAAat1B,IAU5BJ,EAAOvQ,UAAU+tC,wBAAjB,WAAA,GAAAvyB,IAAA,EAAArE,EAAAlE,QAA2C,SAAe+6B,GAAa,GAAAtN,GAAA3jC,IAC/DixC,GAAYC,SAAW3wC,MAAMgqC,QAAQ0G,EAAYC,UACjDD,EAAYC,QAAQziC,QAAQ,SAAChQ,GACzBklC,EAAKwJ,YAAYxY,yBAAyBl2B,KAI9CwyC,EAAYE,MAAQ5wC,MAAMgqC,QAAQ0G,EAAYE,OAC9CF,EAAYE,KAAK1iC,QAAQ,SAAChQ,GACtBklC,EAAKwJ,YAAYiE,uBAAuB3yC,MATpD,OAAA,UAAAqgB,GAAA,MAAAL,GAAA/d,MAAAV,KAAAK,eAuBAmT,EAAOvQ,UAAU8mC,eAAiB,SAAS/H,EAAaE,GACpDliC,KAAK2tC,+BAA+B0D,mBAChCrP,EAAaE,GACfoB,MAAM,SAACnlC,GAELsW,QAAQC,MACJ,iCAAkCvW,KAEvCmD,QASPkS,EAAOvQ,UAAUynC,qBAAuB,SAAS1I,GAC7ChiC,KAAK2tC,+BAA+BjD,qBAAqB1I,GACxDsB,MAAM,SAACnlC,GACJsW,QAAQyG,KAAK,2CAA4C/c,KAC1DmD,QAQPkS,EAAOvQ,UAAUquC,cAAjB,WAAA,GAAA5W,IAAA,EAAAtgB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAiC,QAAAysB,GAAex1B,GAAf,GAAA7M,GAAAgC,CAAA,OAAAiR,GAAAja,QAAAka,KAAA,SAAAovB,GAAA,OAAA,OAAAA,EAAAlvB,KAAAkvB,EAAAhoC,MAAA,IAAA,GAAA,MACvB0F,GAAS6M,EAAMlC,YACf3I,EAAU6K,EAAMiD,aAFOwyB,EAAAlvB,KAAA,EAAAkvB,EAAAhoC,KAAA,GAAA,EAAA+Y,EAAAtG,SAOnB9T,KAAK+e,kBAAkBhY,EAAQgC,GAAS,GAPrB,KAAA,GAAAsgC,EAAAhoC,KAAA,EAAA,MAAA,KAAA,GAAAgoC,EAAAlvB,KAAA,EAAAkvB,EAAA1X,GAAA0X,EAAA,MAAA,GASzB50B,QAAQC,MAAM,wCAA0C3N,EAC1C,IADdsiC,EAAA1X,GATyB,KAAA,IAAA,IAAA,MAAA,MAAA0X,GAAA9uB,SAAA6uB,EAAAppC,OAAA,EAAA,OAAjC,OAAA,UAAAs8B,GAAA,MAAA5B,GAAAh6B,MAAAV,KAAAK,eAsBAmT,EAAOvQ,UAAUsuC,gBAAjB,WAAA,GAAAjW,IAAA,EAAAlhB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAmC,QAAAquB,GAAewG,GAAf,GAAAC,GAAAC,CAAA,OAAA13B,GAAAja,QAAAka,KAAA,SAAAgxB,GAAA,OAAA,OAAAA,EAAA9wB,KAAA8wB,EAAA5pC,MAAA,IAAA,GAAA,GACzBowC,EAAgBD,EAASC,cAE1BD,EAASE,aAHiB,CAAAzG,EAAA5pC,KAAA,EAAA,OAAA,GAI3BoT,QAAQe,IAAI,0BAKS,QADfk8B,EAAe1xC,KAAKkT,cAAcy+B,8BARb,CAAA1G,EAAA5pC,KAAA,EAAA,OAAA,MAAA4pC,GAAA9wB,KAAA,EAAA8wB,EAAA5pC,KAAA,GAAA,EAAA+Y,EAAAtG,SAWb9T,KAAK4xC,4BACPF,EAAcD,GAZC,KAAA,GAAAxG,EAAA5pC,KAAA,EAAA,MAAA,KAAA,IAAA4pC,EAAA9wB,KAAA,GAAA8wB,EAAAtZ,GAAAsZ,EAAA,MAAA,GAgBnBx2B,QAAQyG,KAAK,qCAAb+vB,EAAAtZ,IACA3xB,KAAKmtC,YAAY0E,0BAjBE,KAAA,IAAA5G,EAAA5pC,KAAA,EAAA,MAAA,KAAA,IAsBvBoT,QAAQe,IAAI,oEAEZxV,KAAKmtC,YAAY0E,0BAxBM,KAAA,IAiC/B7xC,KAAKkT,cAAc4+B,6BAA6BL,GAGhDzxC,KAAKmtC,YAAY7Z,mBAAqBme,EACtCzxC,KAAKmtC,YAAYuD,6BAMZc,EAASO,aACV/D,EAAwBhuC,MACxBA,KAAKgyC,kCA7CsB,KAAA,IAAA,IAAA,MAAA,MAAA/G,GAAA1wB,SAAAywB,EAAAhrC,OAAA,EAAA,QAAnC,OAAA,UAAAu8B,GAAA,MAAAjB,GAAA56B,MAAAV,KAAAK,eA2DAmT,EAAOvQ,UAAU2uC,4BAAjB,WAAA,GAAAnW,IAAA,EAAArhB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA+C,QAAAs1B,GAC3CP,EAAcpe,GAD6B,GAAAh1B,EAAA,OAAA0b,GAAAja,QAAAka,KAAA,SAAAi4B,GAAA,OAAA,OAAAA,EAAA/3B,KAAA+3B,EAAA7wC,MAAA,IAAA,GAAA,MAAA6wC,GAAA7wC,KAAA,GAAA,EAAA+Y,EAAAtG,SAG3B9T,KAAKw1B,UAAUxmB,cAC3B0iC,EAAcpe,GAJyB,KAAA,GAAA,MAGrCh1B,GAHqC4zC,EAAA53B,KAO3C7F,QAAQe,IAAI,wBAAyBk8B,EAAc,IAAKpzC,GAPb4zC,EAAA7wC,KAAA,GAAA,EAAA+Y,EAAAtG,SASrC9T,KAAKgxC,wBAAwB1yC,GATQ,KAAA,GAAA,IAAA,MAAA,MAAA4zC,GAAA33B,SAAA03B,EAAAjyC,QAA/C,OAAA,UAAA08B,EAAAC,GAAA,MAAAlB,GAAA/6B,MAAAV,KAAAK,eAiBAmT,EAAOvQ,UAAUkvC,aAAe,WAAW,GAAAlO,GAAAjkC,IACvC,OAAOA,MAAKktC,aAAaztB,WAAW0K,OAAO,SAAC3Y,GAGxC,IADYyyB,EAAKqJ,gBAAgB97B,EAAKzK,QAElC,OAAO,CAIX,IAAMqrC,GAAK5gC,EAAK6gC,UAAUpO,EAAKQ,QAC/B,UAAK2N,GACiB,SAAlBA,EAAGx8B,YAA2C,WAAlBw8B,EAAGx8B,eAU3CpC,EAAOvQ,UAAUosC,iBAAmB,SAASz7B,GAAO,GAAA0+B,GAAAtyC,IAChD,KAC2B,cAAnB4T,EAAMwC,WACgB,wBAAnBxC,EAAMwC,UACTpW,KAAKuyC,gBAAgB3+B,GACK,sBAAnBA,EAAMwC,UACbpW,KAAKwyC,uBAAuB5+B,GACrBA,EAAM0C,oBAEb1C,EAAM4C,KAAK,kBAAmB,SAAC6B,GAC3Bi6B,EAAKjD,iBAAiBh3B,KAGhC,MAAOla,GACLsW,QAAQC,MAAM,gCAAiCvW,KAUvDqV,EAAOvQ,UAAUsvC,gBAAkB,SAAS3+B,GACxC,GAAM7K,GAAU6K,EAAMiD,YAEtB,KAAK9N,EAAQ+B,UAAY/B,EAAQirB,UAE7B,WADAvf,SAAQC,MAAM,8BAIN1U,MAAK6wC,kBAAkB9nC,EAAQ+B,QAAS/B,EAAQirB,WACxDoW,eAAex2B,IAWvBJ,EAAOvQ,UAAUmsC,kBAAoB,SAASx7B,EAAO+wB,EAAQC,GASzD,GAAM79B,GAAS49B,EAAO59B,OAEhBwpC,EAAMvwC,KAAKstC,gBAAgBvmC,EAC5BwpC,KAKoB,QAArB5L,EAAO/uB,aACPnB,QAAQe,IAAI,kBAAoBmvB,EAAOh9B,OAAS,OAASZ,GAEzD/G,KAAKmtC,YAAYsD,wBAAwB9L,EAAOh9B,SAGpD4oC,EAAIkC,iBAAiB7+B,EAAO+wB,EAAQC,KAUxCpxB,EAAOvQ,UAAUuvC,uBAAyB,SAAS5+B,GAC/C,GAAM7K,GAAU6K,EAAMiD,YACtB,IAAuB,YAAnB9N,EAAQ86B,OAAsB,CAI9B,GAAMd,GAAM,GAAI2P,GAAuB9+B,EACvC5T,MAAK6tC,yBAAyBj3B,KAAKmsB,OAChC,IAAuB,yBAAnBh6B,EAAQ86B,OAAmC,CAClD,GAAM8O,GAAM,GAAIC,GAAmCh/B,EACnD5T,MAAK8tC,qCAAqCl3B,KAAK+7B,KAUvDn/B,EAAOvQ,UAAU+uC,iCAAjB,EAAA53B,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAmD,QAAAk2B,KAAA,GAAAC,GAAAC,EAAAC,EAAAhzC,IAAA,OAAAga,GAAAja,QAAAka,KAAA,SAAAg5B,GAAA,OAAA,OAAAA,EAAA94B,KAAA84B,EAAA5xC,MAAA,IAAA,GAAA,IAC3CrB,KAAK+tC,2BADsC,CAAAkF,EAAA5xC,KAAA,CAAA,OAAA,MAAA4xC,GAAAl2B,OAAA,SAAA,KAAA,GAAA,MAM/C/c,MAAK+tC,4BAA6B,EANakF,EAAA94B,KAAA,EAWrC24B,EAAW9yC,KAAK6tC,yBACtB7tC,KAAK6tC,4BACCkF,EAAgB/yC,KAAK8tC,qCAC3B9tC,KAAK8tC,wCAdsCmF,EAAA5xC,KAAA,IAAA,EAAA+Y,EAAAtG,SAuBrCD,EAAA9T,QAAQogB,IACV2yB,EAAU,SAAC/P,GAAD,MACNiQ,GAAKE,+BAA+BnQ,KAzBD,KAAA,IAAA,MAAAkQ,GAAA5xC,KAAA,IAAA,EAAA+Y,EAAAtG,SA2BrCD,EAAA9T,QAAQogB,IACV4yB,EAAe,SAACI,GAAD,MACXH,GAAKI,2CAA2CD,KA7Bb,KAAA,IAAAF,EAAA5xC,KAAA,EAAA,MAAA,KAAA,IAAA4xC,EAAA94B,KAAA,GAAA84B,EAAAthB,GAAAshB,EAAA,MAAA,GAgC3Cx+B,QAAQC,MAAR,sCAAAu+B,EAAAthB,GAhC2C,KAAA,IAAA,MAAAshB,GAAA94B,KAAA,GAkC3Cna,KAAK+tC,4BAA6B,EAlCSkF,EAAAI,OAAA,GAAA,KAAA,IAAA,IAAA,MAAA,MAAAJ,GAAA14B,SAAAs4B,EAAA7yC,OAAA,EAAA,GAAA,GAAA,SA2CnDwT,EAAOvQ,UAAUiwC,+BAAjB,WAAA,GAAA9W,IAAA,EAAAhiB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAkD,QAAA22B,GAAevQ,GAAf,GAAAp7B,GAAA0G,EAAArJ,EAAA+B,EAAAwpC,EAAAlM,EAAA1lB,CAAA,OAAA3E,GAAAja,QAAAka,KAAA,SAAAs5B,GAAA,OAAA,OAAAA,EAAAp5B,KAAAo5B,EAAAlyC,MAAA,IAAA,GAAA,GACxCsG,EAASo7B,EAAIp7B,OACb0G,EAAW00B,EAAI10B,SAEfrJ,EAAO+9B,EAAIf,YACXj7B,EAAS/B,EAAK8F,QACdylC,EAAMvrC,EAAKgvB,UAEjBvf,QAAQe,IAAI,2BAA2B7N,EAA3B,IAAqC0G,EAArC,QACQtH,EADR,MACoB/B,EAAKu0B,WADzB,QAC2CwJ,EAAID,UAD/C,KAGRn7B,IAAW3H,KAAKykC,QAX0B,CAAA8O,EAAAlyC,KAAA,CAAA,OAAA,MAc1CoT,SAAQe,IAAI,qDAd8B+9B,EAAAx2B,OAAA,SAAA,KAAA,GAAA,GAuBzC/c,KAAKutC,gBAAgBxmC,GAvBoB,CAAAwsC,EAAAlyC,KAAA,EAAA,OAAA,MAwB1CoT,SAAQe,IAAR,yCAAqDzO,GAxBXwsC,EAAAx2B,OAAA,SAAA,KAAA,IAAA,GA4BxCsnB,EAAYrkC,KAAKutC,gBAAgBxmC,GAAQwpC,GA5BD,CAAAgD,EAAAlyC,KAAA,EAAA,OAAA,MA8B1CoT,SAAQe,IAAR,oCAAgD+6B,EAAhD,YAA+DxpC,GA9BrBwsC,EAAAx2B,OAAA,SAAA,KAAA,IAAA,MAAAw2B,GAAAlyC,KAAA,IAAA,EAAA+Y,EAAAtG,SAkCnCuwB,EAAUuG,qBAAqB7H,GAlCI,KAAA,IAAA,GAAAwQ,EAAAj5B,KAAA,CAAAi5B,EAAAlyC,KAAA,EAAA,OAAA,MAmC1CoT,SAAQe,IACJ,wCAAwCzO,EAAxC,MACI/B,EAAKu0B,YArC6Bga,EAAAx2B,OAAA,SAAA,KAAA,IAAA,GA0C9CgmB,EAAIyQ,MAAQ,WACRnP,EAAUwG,oBAAoB9H,MAI5BpkB,EAAS3e,KAAKmtC,YAAYxvB,gBAAgBhW,EAAQ0G,MAC1CsQ,EAAOE,aAhDyB,CAAA00B,EAAAlyC,KAAA,EAAA,OAAA,MAiD1CoT,SAAQe,IAAI,4CACZutB,EAAIyQ,QAlDsCD,EAAAx2B,OAAA,SAAA,KAAA,IAsD9C/c,KAAKS,KAAK,wBAAyBsiC,EAtDW,KAAA,IAAA,IAAA,MAAA,MAAAwQ,GAAAh5B,SAAA+4B,EAAAtzC,QAAlD,OAAA,UAAA48B,GAAA,MAAAR,GAAA17B,MAAAV,KAAAK,eA+DAmT,EAAOvQ,UAAUmwC,2CAAjB,WAAA,GAAA3W,IAAA,EAAAriB,EAAAlE,QAA8D,SAC1Di9B,GAEA1+B,QAAQe,IACJ,uCAAuC29B,EAAaxrC,OAApD,IACOwrC,EAAa9kC,SADpB,QACoC8kC,EAAarQ,UADjD,KAOJ9iC,KAAKS,KAAK,oCAAqC0yC,IAXnD,OAAA,UAAAtW,GAAA,MAAAJ,GAAA/7B,MAAAV,KAAAK,eAgCAmT,EAAOvQ,UAAU4tC,kBAAoB,SAAS9pC,EAAQitB,GAClD,GAAIyf,OAAA,GACAlD,MAAA,EAGJ,KADAxpC,EAASA,GAAU,QAEf0sC,EAAazzC,KAAKutC,gBAAgBxmC,GAC7B0sC,IACDzzC,KAAKutC,gBAAgBxmC,GAAU0sC,MAGnClD,EAAMkD,EAAWzf,IAEb,MAAOuc,EAIf,IAAMF,GAAW5d,EAAW8R,mBAAmBvQ,EAC/C,KAAKqc,EACD,KAAM,IAAI5d,GAAWsS,gBACjB,iCAAmC/Q,EAAY,KAcvD,OAXAuc,GAAM,GAAIF,IACN1oC,OAAQ3H,KAAKykC,QACb5nB,OAAQ7c,KACRgzB,UAAWhzB,KAAKqxB,WAChB0B,SAAU/yB,KAAKw1B,UACfzuB,OAAQA,IAGR0sC,IACAA,EAAWzf,GAAauc,GAErBA,GASX/8B,EAAOvQ,UAAU6rC,YAAjB,WAAA,GAAA/R,IAAA,EAAA3iB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA+B,QAAA+2B,GAAe9G,GAAf,GAAA+G,EAAA,OAAA35B,GAAAja,QAAAka,KAAA,SAAA25B,GAAA,OAAA,OAAAA,EAAAz5B,KAAAy5B,EAAAvyC,MAAA,IAAA,GAAA,MACrBsyC,MACNA,EAAK3zC,KAAKykC,YAFiBmP,EAAAvyC,KAAA,GAAA,EAAA+Y,EAAAtG,SAIjB9T,KAAKqxB,WAAWsI,KAAKsV,EAAY4E,UAAUjH,IAJ1B,KAAA,GAG3B+G,EAAK3zC,KAAKykC,SAAS,WAAazkC,KAAKyxB,WAHVmiB,EAAAt5B,KAK3BsyB,EAAIkH,WAAaH,CALU,KAAA,GAAA,IAAA,MAAA,MAAAC,GAAAr5B,SAAAm5B,EAAA1zC,QAA/B,OAAA,UAAAi9B,GAAA,MAAAF,GAAAr8B,MAAAV,KAAAK,kBA4BMqyC,GACF,QAAAA,GAAY9+B,IAAO,EAAA9T,EAAAC,SAAAC,KAAA0yC,EACf,IAAM3pC,GAAU6K,EAAMiD,YAEtB7W,MAAK2H,OAASiM,EAAMmD,YACpB/W,KAAKqO,SAAWtF,EAAQ+6B,qBACxB9jC,KAAK8iC,UAAY/5B,EAAQg7B,WACzB/jC,KAAKgiC,YAAcj5B,EAAQ/D,SAC3BhF,KAAKwzC,MAAQ,WACT,KAAM,IAAI10C,OAAM,uDAYtB8zC,EACF,QAAAA,GAAYh/B,IAAO,EAAA9T,EAAAC,SAAAC,KAAA4yC,EACf,IAAM7pC,GAAU6K,EAAMiD,YAEtB7W,MAAK2H,OAASiM,EAAMmD,YACpB/W,KAAKqO,SAAWtF,EAAQ+6B,qBACxB9jC,KAAK8iC,UAAY/5B,EAAQg7B,WAwCjC1kC,GAAOJ,QAAUuU,miBCnmCjB,QAAAkL,GAAyCsU,EAAW+gB,EAAYpsC,EAAQy/B,GAAxE,GAAA/4B,GAAA2B,CAAA,OAAAgK,GAAAja,QAAAka,KAAA,SAAA2E,GAAA,OAAA,OAAAA,EAAAzE,KAAAyE,EAAAvd,MAAA,IAAA,GAAA,MACUgN,GAAW+4B,EAAW/4B,SADhCuQ,EAAAzE,KAAA,EAAAyE,EAAAvd,KAAA,GAAA,EAAA+Y,EAAAtG,SAGckgC,EACFhhB,EAAW+gB,EAAYpsC,EAAQ0G,EAC/B+4B,EAAW7U,kBALvB,KAAA,GAAA3T,EAAAvd,KAAA,EAAA,MAAA,KAAA,GAAA,MAAAud,GAAAzE,KAAA,EAAAyE,EAAA+S,GAAA/S,EAAA,MAAA,GAQQnK,QAAQC,MACJ,yDACI/M,EAAS,IAAM0G,EAAW,IAFlCuQ,EAAA+S,IARR/S,EAAA7B,OAAA,SAYe,KAZf,KAAA,IAAA,MAeQ/M,OAfR,GAAA4O,EAAAzE,KAAA,GAAAyE,EAAAvd,KAAA,IAAA,EAAA+Y,EAAAtG,SAiBoBkf,EAAUoH,sBAClBgN,EAAWE,iBAAkByM,EAAW/vB,KAlBpD,KAAA,IAiBQhU,EAjBR4O,EAAAtE,KAAAsE,EAAAvd,KAAA,EAAA,MAAA,KAAA,IAAA,MAAAud,GAAAzE,KAAA,GAAAyE,EAAAgT,GAAAhT,EAAA,MAAA,IAsBQnK,QAAQC,MAAM,sCACA/M,EAAS,IAAM0G,EAAW,KAD1BuQ,EAAAgT,IAtBtBhT,EAAA7B,OAAA,SAwBe,KAxBf,KAAA,IAAA,MA2BItI,SAAQe,IAAI,yBAA2BxF,EAC3B,eAAiBrI,EAAS,IAAM0G,GA5BhDuQ,EAAA7B,OAAA,SA6BW/M,EA7BX,KAAA,IAAA,IAAA,MAAA,MAAA4O,GAAArE,SAAAmE,EAAA1e,OAAA,EAAA,IAAA,GAAA,qEA9LMivC,EAActwC,EAAQ,gBAEtBqD,EAAQrD,EAAQ,WAKtBU,GAAOJ,QAAQi1B,cAAgB,+BAK/B70B,EAAOJ,QAAQk1B,iBAAmB,uBAmBlC90B,EAAOJ,QAAQopC,wBAAf,WAAA,GAAArB,IAAA,EAAA5sB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAyC,QAAAC,GACrCq3B,EACAC,EAAWC,EAAanhB,EAAWohB,EAAiBC,EACpDzI,GAHqC,GAAAvX,GAAApwB,EAAAg3B,CAAA,OAAAjhB,GAAAja,QAAAka,KAAA,SAAA6C,GAAA,OAAA,OAAAA,EAAA3C,KAAA2C,EAAAzb,MAAA,IAAA,GAAA,MAK/BgzB,GAAYggB,EAAgB/M,iBALGxqB,EAAAzb,KAAA,GAAA,EAAA+Y,EAAAtG,SAMbkf,EAAUwI,sBAAsBnH,GANnB,KAAA,GAAA,GAOnB,QADZpwB,EAN+B6Y,EAAAxC,MAAA,CAAAwC,EAAAzb,KAAA,CAAA,OAAA,MAAAyb,GAAAC,OAAA,SAAA,KAAA,GAAA,MAarCtI,SAAQe,IACJ,mBAAqBvR,EAAY,eAC7BmwC,EAAkB,IAAMC,EAAgBhmC,UAG1C4sB,GACF4O,OAAQqK,EACRI,cAAeH,EAUf70B,MACIoZ,QAAW1F,EAAUoE,kBAMzB4U,UAAWoI,EACXnI,gBACIvT,QAAW2b,EAAgB9hB,mBASnCvwB,EAAMwD,OAAOy1B,EAAS2Q,GAhDe9uB,EAAAzb,KAAA,IAAA,EAAA+Y,EAAAtG,SAkDJkf,EAAUmJ,eACvC9H,EAAWpwB,GAAW,EAAAomB,EAAAtqB,SAAek7B,IAnDJ,KAAA,IAkDrCgZ,EAAc5f,GAlDuBvX,EAAAxC,IAAA,KAAA,IAAA,IAAA,MAAA,MAAAwC,GAAAvC,SAAAqC,EAAA5c,QAAzC,OAAA,UAAA0d,EAAAG,EAAAC,EAAA0c,EAAAU,EAAAC,EAAAC,GAAA,MAAA4L,GAAAtmC,MAAAV,KAAAK,eAqEAhB,EAAOJ,QAAQspC,4BAAf,WAAA,GAAA9qB,IAAA,EAAArD,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA6C,QAAAhD,GACzCqZ,EAAWD,EAAU2U,GADoB,GAAA6M,GAAAznB,EAAAnlB,EAAAgH,EAAAk9B,EAAAzE,EAAA/4B,EAAA2V,EAAA/f,EAAAuwC,EAAAngC,EAAAogC,EAAAn5B,EAAAo5B,EAAAjQ,EAAAkQ,CAAA,OAAA36B,GAAAja,QAAAka,KAAA,SAAAC,GAAA,OAAA,OAAAA,EAAAC,KAAAD,EAAA7Y,MAAA,IAAA,GAGnCkzC,KAGAznB,KANmC5S,EAAAyX,GAAA3X,EAAAja,QAAAuf,KAQpBooB,EARoB,KAAA,GAAA,IAAAxtB,EAAA0X,GAAA1X,EAAAyX,MAAArwB,KAAA,CAAA4Y,EAAA7Y,KAAA,EAAA,OAAA,GAQ9BsG,EAR8BuS,EAAA0X,GAAArwB,MAShCmmC,EAAc7V,eAAelqB,GATG,CAAAuS,EAAA7Y,KAAA,CAAA,OAAA,MAAA6Y,GAAA6C,OAAA,WAAA,EAAA,KAAA,GAYrC+P,EAAOnlB,MACDgH,EAAU+4B,EAAc//B,GACrBkkC,EAAI,CAdwB,KAAA,IAAA,KAcrBA,EAAIl9B,EAAQxP,QAdS,CAAA+a,EAAA7Y,KAAA,EAAA,OAAA,MAe3B+lC,GAAaz4B,EAAQk9B,GACrBx9B,EAAW+4B,EAAW/4B,SACtB2V,EAAMojB,EAAWE,iBAjBUptB,EAAA7Y,KAAA,IAAA,EAAA+Y,EAAAtG,SAkBTkf,EAAUwI,sBAAsBxX,GAlBvB,KAAA,IAkB3B/f,EAlB2BiW,EAAAI,KAmBf,OAAdrW,GACAswC,EAAsB39B,MAAMjP,EAAQ0G,IAExCye,EAAOnlB,GAAQ0G,IACXsQ,OAAQyoB,EACRnjC,UAAWA,EAxBkB,KAAA,IAcD4nC,IAdC3xB,EAAA7Y,KAAA,EAAA,MAAA,KAAA,IAAA6Y,EAAA7Y,KAAA,CAAA,MAAA,KAAA,IAAA,GA6BJ,IAAjCkzC,EAAsBp1C,OA7Be,CAAA+a,EAAA7Y,KAAA,EAAA,OAAA,MAAA6Y,GAAA6C,OAAA,SA8B9B+P,EA9B8B,KAAA,IAAA,MAuCnC0nB,GAAsB,oBAvCat6B,EAAA7Y,KAAA,IAAA,EAAA+Y,EAAAtG,SAwCvBif,EAASrkB,iBACvB6lC,EAAuBC,GAzCc,KAAA,IAwCnCngC,EAxCmC6F,EAAAI,KA4CnCm6B,EAAUpgC,EAAItF,kBACduM,KA7CmCo5B,EAAA,SA8C9BjQ,GACP,IAAKiD,EAAc7V,eAAe4S,GAC9B,MAAA,UAIJ,KAAK,GAFCmQ,GAAUH,EAAQhQ,OAClB91B,EAAU+4B,EAAcjD,GACrBoQ,EAAI,EAAGA,EAAIlmC,EAAQxP,OAAQ01C,IAAK,EApDJ,SAoD5BA,GACL,GAAMzN,GAAaz4B,EAAQkmC,GACrBxmC,EAAW+4B,EAAW/4B,QAC5B,IAAIye,EAAO2X,GAAQp2B,GAAUpK,UAEzB,MAAA,UAGJ,IAAM6wC,GAAYF,EAAQvmC,OACtB0lC,EAAa,IACjB,KAAK,GAAM3f,KAAS0gB,GACiC,IAA7C1gB,EAAM/d,QAAQm+B,EAAsB,OACpCT,EAAae,EAAU1gB,GAI/B,KAAK2f,EAKD,MAJAt/B,SAAQyG,KACJ,yBAA2Bs5B,EACvB,gBAAkB/P,EAAS,IAAMp2B,GAEzC,UAGJiN,GAAS1E,KACLm+B,EACI/hB,EAAW+gB,EAAYtP,EAAQ2C,GACjCxjC,KAAK,SAACoM,GACJ8c,EAAO2X,GAAQp2B,GAAUpK,UAAY+L,OA5BxC6kC,KApD4B36B,EAAA4X,GAAA9X,EAAAja,QAAAuf,KA8CpBooB,EA9CoB,KAAA,IAAA,IAAAxtB,EAAA6X,GAAA7X,EAAA4X,MAAAxwB,KAAA,CAAA4Y,EAAA7Y,KAAA,EAAA,OAAA,GA8C9BojC,EA9C8BvqB,EAAA6X,GAAAxwB,MAAA,cAAAozC,EAAAD,EA8C9BjQ,IA9C8B,CAAAvqB,EAAA7Y,KAAA,EAAA,OAAA,MAAA6Y,GAAA6C,OAAA,WAAA,GAAA,KAAA,IAAA7C,EAAA7Y,KAAA,EAAA,MAAA,KAAA,IAAA,MAAA6Y,GAAA7Y,KAAA,IAAA,EAAA+Y,EAAAtG,SAsFnCD,EAAA9T,QAAQyb,IAAIF,GAtFuB,KAAA,IAAA,MAAApB,GAAA6C,OAAA,SAuFlC+P,EAvFkC,KAAA,IAAA,IAAA,MAAA,MAAA5S,GAAAK,SAAAZ,EAAA3Z,QAA7C,OAAA,UAAAu7B,EAAAK,EAAArd,GAAA,MAAAd,GAAA/c,MAAAV,KAAAK,cA4IA,IAAM2zC,GAAmB30C,EAAOJ,QAAQqzB,gBAAf,WAAA,GAAA6W,IAAA,EAAA/uB,EAAAlE,QAAiC,SACtD8c,EAAW4Z,EAAKoI,EAAeC,EAAiBC,GAEhD,GAAMjjB,GAAY,WAAagjB,EACzBnB,EAAalH,EAAIkH,eACjBqB,EAAWrB,EAAWkB,OACtBpT,EAAYuT,EAASljB,EAC3B,KAAK2P,EACD,KAAM9iC,OAAM,sBAKT8tC,GAAIza,eACJya,GAAIkH,UACX,IAAMsB,GAAOnG,EAAY4E,UAAUjH,EAEnC5Z,GAAUV,gBACN4iB,EAAYE,EAAMxT,IAlBD,OAAA,UAAAjF,EAAAC,EAAAC,EAAAI,EAAAC,GAAA,MAAAiM,GAAAzoC,MAAAV,KAAAK,4NCFlB,QAASg1C,GAAgBC,EAAIC,GAChC9gC,QAAQe,IACJ,+CAA+C+/B,EAA/C,OACaC,GAEbD,EAAa,GACbE,EAAeH,GAKvB,QAASG,GAAeH,GACpB,GAAMI,GACFJ,EAAGK,kBAAkB,2BAA6BC,QAAS,aAI/DF,GAA6BG,YAAY,WACpC,sBAAuB,2BAG5BH,EAA6BG,YAAY,QAAS,SAGtD,QAASC,GAAcC,GACnB,MAAO,IAAAliC,GAAA9T,QAAY,SAAC+T,EAASqF,GACzB48B,EAAIC,WAAaliC,EACjBiiC,EAAIE,QAAU98B,2OA3BNk8B,gBAAAA,CArQhB,IAAAj7B,GAAAzb,EAAA,mBACA0jC,EAAA1jC,EAAA,sBAEa62C,EAAAv2C,EAAAu2C,QAAU,IASVU,mBAIT,QAAAA,GAAYZ,GAAI,GAAA1lB,GAAA5vB,MAAA,EAAAF,EAAAC,SAAAC,KAAAk2C,GACZl2C,KAAKm2C,IAAMb,EAKXA,EAAGc,gBAAkB,SAAC/9B,GAClB5D,QAAQe,IAAR,+BAA2Coa,EAAKymB,QAAhD,aACAf,EAAGgB,qFAcoB/2C,GAC3B,GAAMyiC,GAAcziC,EAAQyiC,YAEtBtV,EAAW7Y,EAAA9T,QAAQmZ,QACnB68B,EAAM/1C,KAAKm2C,IAAII,YAAY,0BAA2B,YA2B5D,OA1BAR,GAAIE,QAAUvpB,EAASvT,OAGvBnZ,KAAKw2C,2BAA2BT,EAAK/T,EAAa,SAACyU,GAC/C,GAAIA,EAQA,MANAhiC,SAAQe,IACJ,4CACOwsB,EAAYl3B,QADnB,MACgCk3B,EAAYzI,WAD5C,6BAIJ7M,GAAS5Y,QAAQ2iC,EAMrBhiC,SAAQe,IACJ,8BAA8BwsB,EAAYl3B,QAA1C,MACIk3B,EAAYzI,YAENwc,EAAIW,YAAY,2BACxBzM,IAAI1qC,GACVw2C,EAAIY,UAAY,WAAQjqB,EAAS5Y,QAAQvU,MAGtCmtB,EAAS5gB,0DAaMk2B,GACtB,GAAMtV,GAAW7Y,EAAA9T,QAAQmZ,QAEnB68B,EAAM/1C,KAAKm2C,IAAII,YAAY,0BAA2B,WAM5D,OALAR,GAAIE,QAAUvpB,EAASvT,OAEvBnZ,KAAKw2C,2BAA2BT,EAAK/T,EAAa,SAACyU,GAC/C/pB,EAAS5Y,QAAQ2iC,KAEd/pB,EAAS5gB,2DAeOiqC,EAAK/T,EAAa39B,GAC3B0xC,EAAIW,YAAY,2BAEZE,MAAM,WACFC,YAClB7U,EAAYl3B,QACZk3B,EAAYzI,aAGNod,UAAY,SAACt+B,GACnB,GAAMy+B,GAASz+B,EAAGxY,OAAOitB,MACzB,KAAIgqB,EAGA,WADAzyC,GAAS,KAIb,IAAMoyC,GAAWK,EAAOv1C,KAExB,IAAI4gC,EAAApiC,QAAMqvB,YAAYqnB,EAASzU,YAAaA,GAGxC,WADA39B,GAASoyC,EAKbK,GAAOC,qEAckBC,GAa7B,QAASL,GAAUt+B,GACf,GAAMy+B,GAASz+B,EAAGxY,OAAOitB,MACzB,IAAIgqB,EAGA,YADAhqB,EAASgqB,EAAOv1C,MAMpB,QADA01C,GACkBD,EAAa73C,QAA/B,CAKA,GAAM+3C,GAAcF,EAAaC,EACf5+B,GAAGxY,OAAOe,OAAOi2C,WAAWK,GACpCP,UAAYA,GA7B1B,GAA4B,IAAxBK,EAAa73C,OACb,MAAO0U,GAAA9T,QAAQ+T,QAAQ,KAQ3B,IAAImjC,GAAa,EACbnqB,MAAA,GAsBEipB,EAAM/1C,KAAKm2C,IAAII,YAAY,0BAA2B,YACtDtlC,EAAQ8kC,EAAIW,YAAY,2BAExBQ,EAAcF,EAAaC,EAIjC,OAHkBhmC,GAAM2lC,MAAM,SAASC,WAAWK,GACxCP,UAAYA,EAEfb,EAAcC,GAAKnyC,KAAK,WAAA,MAAMkpB,0DAeZgW,EAAWqU,EAAeC,GAGnD,QAAST,GAAUt+B,GACf,GAAMy+B,GAASz+B,EAAGxY,OAAOitB,MACzB,IAAKgqB,EAAL,CAGA,GAAM7xC,GAAO6xC,EAAOv1C,KACpB,IAAI0D,EAAKiS,OAASigC,EAKd,WAJA1iC,SAAQyG,KACJ,uCAAuCi8B,EAAvC,iCACgClyC,EAAKiS,QAI7C,EAAAiV,EAAApsB,SAAckF,EAAMmyC,GACpBN,EAAOO,OAAOpyC,GACd6nB,EAAS7nB,GAjBb,GAAI6nB,GAAS,KAoBPipB,EAAM/1C,KAAKm2C,IAAII,YAAY,0BAA2B,YAI5D,OAHkBR,GAAIW,YAAY,2BACvBG,WAAW/T,GACZ6T,UAAYA,EACfb,EAAcC,GAAKnyC,KAAK,WAAA,MAAMkpB,0DAYZgW,EAAWqU,GACpC,GAAMpB,GAAM/1C,KAAKm2C,IAAII,YAAY,0BAA2B,YAkB5D,OAjBkBR,GAAIW,YAAY,2BACvBG,WAAW/T,GACZ6T,UAAY,SAACt+B,GACnB,GAAMy+B,GAASz+B,EAAGxY,OAAOitB,MACzB,IAAKgqB,EAAL,CAGA,GAAM7xC,GAAO6xC,EAAOv1C,KACpB,IAAI0D,EAAKiS,OAASigC,EAKd,WAJA1iC,SAAQyG,KACJ,2CAA2CjW,EAAKiS,MAAhD,cACmBigC,EADnB,IAKRL,GAAO5M,WAEJ4L,EAAcC,mZCjP7B37B,EAAAzb,EAAA,mBAEA24C,EAAA34C,EAAA,gCACA44C,EAAA54C,EAAA,oCAAY64C,6JAcS73C,aAOjB,QAAAA,GAAYH,EAAWi4C,IAAQ,EAAA33C,EAAAC,SAAAC,KAAAL,GAC3BK,KAAK03C,WAAal4C,EAClBQ,KAAKq2C,QAAUoB,EACfz3C,KAAK23C,gBAAkB,6DAUhB,GAAA/nB,GAAA5vB,IACP,OAAIA,MAAK23C,gBACE33C,KAAK23C,iBAGhB33C,KAAK23C,gBAAkB,GAAA9jC,GAAA9T,QAAY,SAAC+T,EAASqF,GACzC,IAAKyW,EAAK8nB,WAEN,WADAv+B,GAAO,GAAIra,OAAM,kCAIrB2V,SAAQe,IAAR,2BAAuCoa,EAAKymB,QAE5C,IAAMtT,GAAMnT,EAAK8nB,WAAWE,KACxBhoB,EAAKymB,QAASmB,EAA4BhC,QAG9CzS,GAAI8U,gBAAkB,SAACx/B,GACnB,GAAMi9B,GAAKj9B,EAAGxY,OAAOitB,OACfyoB,EAAal9B,EAAGk9B,UACtBiC,GAA4BnC,gBAAgBC,EAAIC,IAGpDxS,EAAI+U,UAAY,WACZrjC,QAAQe,IAAR,qEAKJutB,EAAIkT,QAAU,SAAC59B,GACXc,EAAOd,EAAGxY,OAAO6U,QAGrBquB,EAAI4T,UAAY,SAACr4C,GACb,GAAMg3C,GAAKh3C,EAAEuB,OAAOitB,MAEpBrY,SAAQe,IAAR,0BAAsCoa,EAAKymB,SAC3CviC,EAAQ,GAAI0jC,GAA4BtB,QAAQZ,OAErDhS,MAAM,SAACnlC,GAKN,MAJAsW,SAAQyG,KACJ,kCAAkC0U,EAAKymB,QAAvC,sCAC0Cl4C,GAEvC,GAAA45C,GAAAh4C,UAGJC,KAAK23C,yDAQA,GAAAziB,GAAAl1B,IACZ,OAAO,IAAA6T,GAAA9T,QAAY,SAAC+T,EAASqF,GACzB,IAAK+b,EAAKwiB,WAEN,WADAv+B,GAAO,GAAIra,OAAM,kCAIrB2V,SAAQe,IAAR,gCAA4C0f,EAAKmhB,QACjD,IAAMtT,GAAM7N,EAAKwiB,WAAWM,eAAe9iB,EAAKmhB,QAEhDtT,GAAI+U,UAAY,WACZrjC,QAAQe,IAAR,uEAKJutB,EAAIkT,QAAU,SAAC59B,GACXc,EAAOd,EAAGxY,OAAO6U,QAGrBquB,EAAI4T,UAAY,WACZliC,QAAQe,IAAR,+BAA2C0f,EAAKmhB,SAChDviC,OAELwvB,MAAM,SAACnlC,GAINsW,QAAQyG,KAAR,0CAAuD/c,4DAchCoB,GAC3B,MAAOS,MAAKi4C,WAAWr0C,KAAK,SAACs0C,GACzB,MAAOA,GAAQrV,+BAA+BtjC,uDAc5ByiC,GACtB,MAAOhiC,MAAKi4C,WAAWr0C,KAAK,SAACs0C,GACzB,MAAOA,GAAQlV,0BAA0BhB,8DAchBgV,GAC7B,MAAOh3C,MAAKi4C,WAAWr0C,KAAK,SAACs0C,GACzB,MAAOA,GAAQzU,iCAAiCuT,0DAgB3BlU,EAAWqU,EAAeC,GACnD,MAAOp3C,MAAKi4C,WAAWr0C,KAAK,SAACs0C,GACzB,MAAOA,GAAQhV,6BACXJ,EAAWqU,EAAeC,0DAcTtU,EAAWqU,GACpC,MAAOn3C,MAAKi4C,WAAWr0C,KAAK,SAACs0C,GACzB,MAAOA,GAAQjV,6BAA6BH,EAAWqU,wBA1L9Cx3C,mfCjBrBya,EAAAzb,EAAA,mBAEA0jC,EAAA1jC,EAAA,sBAWqBw5C,aACjB,QAAAA,MAAc,EAAAr4C,EAAAC,SAAAC,KAAAm4C,GACVn4C,KAAKo4C,yFASL,MAAOvkC,GAAA9T,QAAQ+T,iEAaYvU,GAAS,GAAAqwB,GAAA5vB,KAC9BgiC,EAAcziC,EAAQyiC,WAE5B,OAAOnuB,GAAA9T,QAAQs4C,IAAI,WAEf,GAAM5B,GAAW7mB,EAAK4mB,2BAA2BxU,EAEjD,OAAIyU,IAEAhiC,QAAQe,IACJ,4CACGwsB,EAAYl3B,QADf,MAC4Bk3B,EAAYzI,WADxC,yBAIGkd,IAKXhiC,QAAQe,IACJ,8BAA8BwsB,EAAYl3B,QAA1C,MACAk3B,EAAYzI,YAEhB3J,EAAKwoB,yBAAyBxhC,KAAKrX,GAC5BA,uDAcWyiC,GACtB,MAAOnuB,GAAA9T,QAAQ+T,QAAQ9T,KAAKw2C,2BAA2BxU,uDAchCA,GAAa,GAAAlhC,IAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KACpC,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,SAAuBC,KAAKo4C,4BAA5Bt3C,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAAsD,CAAA,GAA3C21C,GAA2Cv1C,EAAAK,KAClD,IAAI4gC,EAAApiC,QAAMqvB,YAAYqnB,EAASzU,YAAaA,GACxC,MAAOyU,IAHqB,MAAA70C,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,IAMpC,MAAO,+DAYsBg2C,GAAc,GAAA1iB,IAAA,EAAAC,GAAA,EAAAC,MAAAvzB,EAAA,KAC3C,IAAA,GAAAwzB,GAAAC,GAAA,EAAAtzB,EAAArB,SAAkBC,KAAKo4C,4BAAvB9jB,GAAAG,EAAAC,EAAArzB,QAAAC,MAAAgzB,GAAA,EAAiD,CAAA,GAAtCyO,GAAsCtO,EAAAlzB,MAAAqzB,GAAA,EAAAC,GAAA,EAAAC,MAAA7zB,EAAA,KAC7C,IAAA,GAAA8zB,GAAAC,GAAA,EAAA5zB,EAAArB,SAAoBi3C,KAApBpiB,GAAAG,EAAAC,EAAA3zB,QAAAC,MAAAszB,GAAA,EAAkC,CAAA,GAAvB1d,GAAuB6d,EAAAxzB,KAC9B,IAAIwhC,EAAI7rB,QAAUA,EACd,MAAOrD,GAAA9T,QAAQ+T,QAAQivB,IAHc,MAAAnhC,GAAAizB,GAAA,EAAAC,EAAAlzB,EAAA,QAAA,KAAAgzB,GAAAI,EAAAnzB,QAAAmzB,EAAAnzB,SAAA,QAAA,GAAAgzB,EAAA,KAAAC,MADN,MAAAlzB,GAAA2yB,GAAA,EAAAC,EAAA5yB,EAAA,QAAA,KAAA0yB,GAAAI,EAAA7yB,QAAA6yB,EAAA7yB,SAAA,QAAA,GAAA0yB,EAAA,KAAAC,IAQ3C,MAAO3gB,GAAA9T,QAAQ+T,QAAQ,2DAeEgvB,EAAWqU,EAAeC;sBAAS,GAAAjhB,IAAA,EAAAC,GAAA,EAAAC,MAAAp1B,EAAA,KAC5D,IAAA,GAAAq1B,GAAAC,GAAA,EAAAn1B,EAAArB,SAAkBC,KAAKo4C,4BAAvBjiB,GAAAG,EAAAC,EAAAl1B,QAAAC,MAAA60B,GAAA,EAAiD,CAAA,GAAtC4M,GAAsCzM,EAAA/0B,KAC7C,IAAIwhC,EAAID,YAAcA,EAItB,MAAIC,GAAI7rB,OAASigC,GACb1iC,QAAQyG,KACJ,uCAAuCi8B,EAAvC,iCACgCpU,EAAI7rB,OAEjCrD,EAAA9T,QAAQ+T,QAAQ,SAE3B,EAAAqY,EAAApsB,SAAcgjC,EAAKqU,GACZvjC,EAAA9T,QAAQ+T,QAAQivB,KAdiC,MAAAnhC,GAAAw0B,GAAA,EAAAC,EAAAz0B,EAAA,QAAA,KAAAu0B,GAAAI,EAAA10B,QAAA00B,EAAA10B,SAAA,QAAA,GAAAu0B,EAAA,KAAAC,IAiB5D,MAAOxiB,GAAA9T,QAAQ+T,QAAQ,2DAYEgvB,EAAWqU,GACpC,IAAK,GAAIv4C,GAAI,EAAGA,EAAIoB,KAAKo4C,yBAAyBj5C,OAAQP,IAAK,CAC3D,GAAMmkC,GAAM/iC,KAAKo4C,yBAAyBx5C,EAE1C,IAAImkC,EAAID,YAAcA,EAItB,MAAIC,GAAI7rB,OAASigC,GACb1iC,QAAQyG,KACJ,2CAA2C6nB,EAAI7rB,MAA/C,cACeigC,EADf,KAGGtjC,EAAA9T,QAAQ+T,QAAQ,QAG3B9T,KAAKo4C,yBAAyBE,OAAO15C,EAAG,GACjCiV,EAAA9T,QAAQ+T,QAAQivB,IAG3B,MAAOlvB,GAAA9T,QAAQ+T,QAAQ,yBAvKVqkC,yNCdrB,YAYA,SAASI,GAAkBC,EAAcC,GACrC,GAAIA,EAAa5nC,SAAS,KAAM,CAC5B,GAAM6nC,GAAcD,EAAa3nB,MAAM,GAAI,EAC3C,OAAO0nB,GAAa1nC,OAAO,EAAG4nC,EAAYv5C,UAAYu5C,EAEtD,MAAOF,KAAiBC,EAehC,QAASE,GAAgBC,GACrB54C,KAAK44C,YAAcA,EAEnB54C,KAAK64C,MAAQD,EAAYC,OAAS,KAClC74C,KAAK84C,UAAYF,EAAYE,cAE7B94C,KAAK+4C,MAAQH,EAAYG,OAAS,KAClC/4C,KAAKg5C,UAAYJ,EAAYI,cAE7Bh5C,KAAKi5C,QAAUL,EAAYK,SAAW,KACtCj5C,KAAKk5C,YAAcN,EAAYM,gBAE/Bl5C,KAAKm5C,aAAeP,EAAYO,cAAgB,wGAQpDR,GAAgB11C,UAAUm2C,MAAQ,SAASxlC,GACvC,MAAO5T,MAAKq5C,aACRzlC,EAAMlC,YACNkC,EAAMmD,YACNnD,EAAMwC,YACNxC,EAAMiD,kBAA0C5V,KAA3B2S,EAAMiD,aAAa8D,MAYhDg+B,EAAgB11C,UAAUo2C,aACtB,SAASvuC,EAAS++B,EAAQyP,EAAYH,GACtC,GAAMI,IACFR,MAAS,SAASS,GACd,MAAO1uC,KAAY0uC,GAEvBP,QAAW,SAASO,GAChB,MAAO3P,KAAW2P,GAEtBX,MAAS,SAASW,GACd,MAAOjB,GAAkBe,EAAYE,KAIvCnoC,EAAOrR,MACb,EAAA0K,EAAA3K,SAAYw5C,GAAc9qC,QAAQ,SAAS8S,GACvC,GAAMk4B,GAAaF,EAAah4B,EAGhC,IAD0BlQ,EADT,OAASkQ,GAEJpB,IAAIs5B,GACtB,OAAO,CAGX,IAAMC,GAAiBroC,EAAKkQ,EAC5B,SAAIm4B,IACKA,EAAev5B,IAAIs5B,SAD5B,IAOJ,IAAME,GAAsB35C,KAAK44C,YAAYO,YAC7C,YAA4Bl4C,KAAxB04C,GACIA,IAAwBR,GAapCR,EAAgB11C,UAAUknB,OAAS,SAASrB,GACxC,MAAOA,GAAOqB,OAAOnqB,KAAKo5C,MAAOp5C,OAQrC24C,EAAgB11C,UAAU+G,MAAQ,WAC9B,WAAkC/I,KAA3BjB,KAAK44C,YAAY5uC,MAAsBhK,KAAK44C,YAAY5uC,MAAQ,IAI3E3K,EAAOJ,QAAU05C,iECjIjB,YAYA,SAASiB,GAAQhN,EAAKiN,EAAYzR,GAG9B,IAAK,GAFC0R,GAAaD,EAAWh+B,MAAM,KAChCk+B,EAAanN,EACRhuC,EAAI,EAAGA,EAAKk7C,EAAW36C,OAAS,EAAIP,IACpCm7C,EAAWD,EAAWl7C,MACvBm7C,EAAWD,EAAWl7C,QAE1Bm7C,EAAaA,EAAWD,EAAWl7C,GAEvCm7C,GAAWD,EAAWA,EAAW36C,OAAS,IAAMipC,EAWpD,QAASrtB,GAAOpT,EAAQ+mB,GACpB1uB,KAAK2H,OAASA,EACd3H,KAAK0uB,SAAWA,EAChB1uB,KAAKg6C,cA9BT,GAAMrB,GAAkBh6C,EAAQ,qBAqChCoc,GAAO9X,UAAUg3C,YAAc,WAC3B,MAAOj6C,MAAK0uB,UAOhB3T,EAAO9X,UAAUisB,cAAgB,WAC7B,MAAOlvB,MAAKg6C,YAOhBj/B,EAAO9X,UAAUi3C,cAAgB,SAASF,GACtCh6C,KAAKg6C,WAAaA,CAkClB,IAAMG,GAAmBH,EAAWxoC,KAG9B4oC,IACFD,KACIA,EAAiBpB,QACjBqB,EAAmBrB,MAAQoB,EAAiBpB,OAE5CoB,EAAiBpB,QACjBqB,EAAmBpB,UAAYmB,EAAiBnB,WAGpDh5C,KAAKq6C,eAAiBF,EAAiBG,gBAAiB,GAG5Dt6C,KAAKu6C,aAAe,GAAI5B,GAAgByB,GACxCp6C,KAAKw6C,sBAAwB,GAAI7B,GAC7BwB,EAAoBA,EAAiBnxB,kBAoB7CjO,EAAO9X,UAAUqnB,+BAAiC,WAC9C,MAAOtqB,MAAKw6C,uBAShBz/B,EAAO9X,UAAUw3C,mBAAqB,SAAS3xB,GAC3C,MAAO9oB,MAAKw6C,sBAAsBrwB,OAAOnqB,KAAKu6C,aAAapwB,OAAOrB,KAOtE/N,EAAO9X,UAAUy3C,iBAAmB,SAAS1wC,GACzC4vC,EAAQ55C,KAAKg6C,WAAY,sBAAuBhwC,IAQpD+Q,EAAO9X,UAAU03C,qBAAuB,SAASC,GAC7ChB,EAAQ55C,KAAKg6C,WAAY,qBAAsBY,IAWnD7/B,EAAOoT,SAAW,SAASxmB,EAAQ+mB,EAAUmsB,GACzC,GAAM1wB,GAAS,GAAIpP,GAAOpT,EAAQ+mB,EAElC,OADAvE,GAAO+vB,cAAcW,GACd1wB,GAIX9qB,EAAOJ,QAAU8b,+DChLjB,gEAizBA,QAAS+/B,GAAmBj3C,EAAUmB,GAClC,GAAMsqB,GAAazrB,EAASk3C,WACtBC,EAAcC,EAAuBp3C,GAEvCjC,MAAA,EAaJ,OAZIo5C,KACyB,qBAArBA,EAAYz1C,KACZ3D,EAAM,GAAIvC,GAAOJ,QAAQgc,YAAYod,KAAKrM,MAAMhnB,IACpB,eAArBg2C,EAAYz1C,OACnB3D,EAAM,GAAI9C,OAAJ,mBAA6BwwB,EAA7B,WAAkDtqB,KAI3DpD,IACDA,EAAM,GAAI9C,OAAJ,mBAA6BwwB,EAA7B,WAEV1tB,EAAI0tB,WAAaA,EACV1tB,EAaX,QAASq5C,GAAuBp3C,GAC5B,GAAIm3C,OAAA,EASJ,IARIn3C,EAASq3C,kBAETF,EAAcn3C,EAASq3C,kBAAkB,gBAClCr3C,EAASs3C,UAEhBH,EAAcn3C,EAASs3C,QAAQ,iBAAmB,OAGjDH,EACD,MAAO,KAGX,KACI,MAAOI,GAAiBJ,GAC1B,MAAM78C,GACJ,KAAM,IAAIW,OAAJ,+BAAyCk8C,EAAzC,MAA0D78C,wJA31BxEic,EAAAzb,EAAA,mBACMy8C,EAAmBz8C,EAAQ,gBAAgBqtB,MAE3ChqB,EAAQrD,EAAQ,WAKhB08C,EAAY18C,EAAQ,uBAW1BU,GAAOJ,QAAQuD,UAAY,qBAK3BnD,EAAOJ,QAAQgH,gBAAkB,2BAKjC5G,EAAOJ,QAAQ6Q,mBAAqB,2BAKpCzQ,EAAOJ,QAAQilB,gBAAkB,oBA2BjC7kB,EAAOJ,QAAQ8D,cAAgB,SAAuBu4C,EAAev5C,GACjEC,EAAMC,mBAAmBF,GAAO,UAAW,UAAW,WACtDA,EAAKU,SAAWV,EAAKU,WAAY,EACjCzC,KAAKs7C,cAAgBA,EACrBt7C,KAAK+B,KAAOA,EACZ/B,KAAK6C,uBAAyB+P,QAAQ7Q,EAAKc,wBAC3C7C,KAAKu7C,YAGTl8C,EAAOJ,QAAQ8D,cAAcE,WAOzBu4C,cAAe,WACX,GAAMh3C,IACFi3C,aAAcz7C,KAAK+B,KAAKM,YAE5B,QACIkjC,KAAMvlC,KAAK+B,KAAKG,QAChBuE,KAAM,2BACNjC,OAAQA,IAwChBmH,cAAe,SAASC,EAAM7J,GACtBC,EAAMiI,WAAWlI,GAEjBA,GACIsC,SAAUtC,OAEEd,KAATc,IACPA,KAKJ,IAAMi5C,GAAcj5C,EAAKwD,MAAQqG,EAAKrG,MAAQ,2BACxCm2C,EAAW35C,EAAKwf,MAAQ3V,EAAK2V,KAI7Bvc,EAAO4G,EAAK+vC,OAAS/vC,EAAK+vC,OAAS/vC,EAIrCgwC,EAAc75C,EAAK65C,gBACH36C,KAAhB26C,IACIn8C,EAAOo8C,eACPD,GAAc,GAEdnnC,QAAQyG,KACJ,8LAKJ0gC,GAAc,GAItB,IAAIE,GAAiB/5C,EAAK+5C,cACrBF,QAAkC36C,KAAnB66C,IACZr8C,EAAOo8C,gBACPpnC,QAAQyG,KACJ,iNAKJ4gC,GAAiB,GAEjBA,GAAiB,EAYzB,IAAMC,IAAWC,OAAQ,EAAGC,MAAO,GAC/BnwC,MAAA,GAMAowC,EAAa,IAcjB,IAbKN,IACDM,EAAa,SAASC,GAClB,GAAIn3C,GAAOqzB,KAAKrM,MAAMmwB,EACtB,IAAIL,OAEa76C,MADb+D,EAAOA,EAAKo3C,aAER,KAAMt9C,OAAM,eAGpB,OAAOkG,KAIXvF,EAAOo8C,eAAgB,CACvB,GAAM3iC,GAAQrF,EAAA9T,QAAQmZ,QAChBmjC,EAAM,GAAI58C,GAAOo8C,cACvBE,GAAOM,IAAMA,CACb,IAAMjsB,GAAKksB,EAAgBpjC,EAAOnX,EAAKsC,SAAUrE,KAAK+B,KAAKU,UAErD85C,EAAa,WACfF,EAAIG,QACJpsB,EAAG,GAAItxB,OAAM,YAKjBu9C,GAAII,cAAgBpB,EAAUriC,WAAWujC,EAAY,KAErDF,EAAIK,mBAAqB,WACrB,OAAQL,EAAIM,YACR,IAAKl9C,GAAOo8C,eAAee,KACvBvB,EAAUnrB,aAAamsB,EAAII,cAC3B,IAAII,EACJ,KACI,IAAKR,EAAIS,aACL,KAAM,IAAIh+C,OAAM,oBAEpB+9C,GAAOR,EAAIS,aACPZ,IACAW,EAAOX,EAAWW,IAExB,MAAOj7C,GAGL,MAFAA,GAAIm7C,YAAcV,EAAI1qC,WACtBye,GAAGxuB,GAGPwuB,MAAGnvB,GAAWo7C,EAAKQ,KAI/BR,EAAIN,OAAOiB,iBAAiB,WAAY,SAAS3kC,GAC7CgjC,EAAUnrB,aAAamsB,EAAII,eAC3BV,EAAOC,OAAS3jC,EAAG2jC,OACnBD,EAAOE,MAAQ5jC,EAAG4jC,MAClBI,EAAII,cAAgBpB,EAAUriC,WAAWujC,EAAY,KACjDx6C,EAAKk7C,iBACLl7C,EAAKk7C,iBACDjB,OAAQ3jC,EAAG2jC,OACXC,MAAO5jC,EAAG4jC,SAItB,IAAIthC,GAAM3a,KAAK+B,KAAKG,QAAU,0BAC9ByY,IAAO,iBAAmBuiC,mBAAmBl9C,KAAK+B,KAAKM,aACvDsY,GAAO,aAAeuiC,mBAAmBxB,GAEzCW,EAAIzE,KAAK,OAAQj9B,GACjB0hC,EAAIc,iBAAiB,eAAgBnC,GACrCqB,EAAIe,KAAKp4C,GACT8G,EAAUoN,EAAMpN,QAGhBA,EAAQ0wC,MAAQH,EAAIG,MAAM/6C,KAAK46C,OAC5B,CACH,GAAM15C,IACF06C,SAAU3B,EAGd5vC,GAAU9L,KAAK2D,cACX5B,EAAKsC,SAAU,OAAQ,UAAW1B,EAAaqC,GAC3C1C,OAAQ,oBACR64C,SAAUmC,eAAgBtC,GAC1B5F,MAAM,EACN8G,WAAYA,IAKxB,GAAM7qC,GAAOrR,KAGPu9C,EAAWzxC,EAAQ2c,QAAQ,WAC7B,IAAK,GAAI7pB,GAAI,EAAGA,EAAIyS,EAAKkqC,QAAQp8C,SAAUP,EACvC,GAAIyS,EAAKkqC,QAAQ38C,KAAOm9C,EAEpB,WADA1qC,GAAKkqC,QAAQjD,OAAO15C,EAAG,IAYnC,OALA2+C,GAASf,MAAQ1wC,EAAQ0wC,MAEzBT,EAAOjwC,QAAUyxC,EACjBv9C,KAAKu7C,QAAQ3kC,KAAKmlC,GAEXwB,GAGX1xC,aAAc,SAASC,GACnB,QAAIA,EAAQ0wC,QACR1wC,EAAQ0wC,SACD,IAKfzwC,kBAAmB,WACf,MAAO/L,MAAKu7C,SAGhB1rC,gBAAiB,SAASxL,EAAU6R,EAAQzP,EAAMjC,EAAQlC,GACtD,GAAMk7C,GAAUx9C,KAAK+B,KAAKI,UAAYG,EAASmE,CAE/C,QAAiBxF,KAAboD,IAA2BrC,EAAMiI,WAAW5F,GAC5C,KAAMvF,OACF,mDAAA,KAAuDuF,EAAvD,aAAA,EAAAmM,EAAAzQ,SAAuDsE,IAI/D,IAAMtC,IACF07C,IAAKD,EACLtnC,OAAQA,EACRwnC,iBAAiB,EACjBtI,MAAM,EACNuI,aAAc39C,KAAK+B,KAET,QAAVmU,EACAnU,EAAK67C,GAAKp5C,EAEVzC,EAAK87C,KAAOr5C,CAGhB,IAAM0U,GAAQrF,EAAA9T,QAAQmZ,OAQtB,OAPAlZ,MAAK+B,KAAKxC,QACNwC,EACAu6C,EAAgBpjC,EAAO7U,EAAUrE,KAAK+B,KAAKU,WAKxCyW,EAAMpN,QAAQlI,KAAK,SAASC,GAC/B,MAAOw0B,MAAKrM,MAAMnoB,MAmC1BF,cAAe,SAASU,EAAU6R,EAAQzP,EAAM9D,EAAasC,EAAMlD,GAC1DY,IACDA,MAEA3C,KAAK6C,wBACD4sC,SAAS1tC,KAETA,GACIa,eAAgBb,IAGnBA,IACDA,MAECA,EAAKo5C,UACNp5C,EAAKo5C,YAEJp5C,EAAKo5C,QAAQ2C,gBACd/7C,EAAKo5C,QAAQ2C,cAAgB,UAAY99C,KAAK+B,KAAKM,aAEnDM,EAAY84C,oBACL94C,GAAY84C,cAGlB94C,EAAY84C,eACb94C,EAAY84C,aAAez7C,KAAK+B,KAAKM,YAI7C,IAAM07C,GAAiB/9C,KAAKT,QACxB8E,EAAU6R,EAAQzP,EAAM9D,EAAasC,EAAMlD,GAGzCsP,EAAOrR,IASb,OARA+9C,GAAeza,MAAM,SAAS1hC,GACP,mBAAfA,EAAIijB,SACJxT,EAAKiqC,cAAc76C,KAAK,wBAMzBs9C,GAiCXx+C,QAAS,SAAS8E,EAAU6R,EAAQzP,EAAM9D,EAAasC,EAAMlD,GACzDA,EAAOA,KACP,IAAMO,OAAyBrB,KAAhBc,EAAKO,OAAuBP,EAAKO,OAAStC,KAAK+B,KAAKO,OAC7Dk7C,EAAUx9C,KAAK+B,KAAKG,QAAUI,EAASmE,CAE7C,OAAOzG,MAAK2gB,gBACRtc,EAAU6R,EAAQsnC,EAAS76C,EAAasC,EAAMlD,IA6BtDuE,wBAAyB,SAASjC,EAAU6R,EAAQzP,EAAM9D,EAAasC,EACrC3C,EAAQM,GACtC,MAAO5C,MAAK2D,cACRU,EAAU6R,EAAQzP,EAAM9D,EAAasC,GACjCrC,eAAgBA,EAChBN,OAAQA,KA8BpB07C,kBAAmB,SAAS35C,EAAU6R,EAAQzP,EAAM9D,EAAasC,EAAM3C,EAC3CM,GACxB,MAAO5C,MAAKT,QACR8E,EAAU6R,EAAQzP,EAAM9D,EAAasC,GACjCrC,eAAgBA,EAChBN,OAAQA,KAkCpBqe,gBAAiB,SAAStc,EAAU6R,EAAQunC,EAAK96C,EAAasC,EACpClD,GAUtB,WATad,KAATc,GAA+B,OAATA,EACtBA,KACO0tC,SAAS1tC,KAEhBA,GACIa,eAAgBb,IAIjB/B,KAAKi+C,SACR55C,EAAU6R,EAAQunC,EAAK96C,EAAasC,EAAMlD,IAelDiE,OAAQ,SAASS,EAAM9D,EAAaL,GAChC,GAAI47C,GAAc,EAIlB,OAHIv7C,KACAu7C,EAAc,IAAMl8C,EAAMivB,aAAatuB,IAEpC3C,KAAK+B,KAAKG,QAAUI,EAASmE,EAAOy3C,GA6B/CD,SAAU,SAAS55C,EAAU6R,EAAQunC,EAAK96C,EAAasC,EAAMlD,GACzD,OAAiBd,KAAboD,IAA2BrC,EAAMiI,WAAW5F,GAC5C,KAAMvF,OACF,mDAAA,KAAuDuF,EAAvD,aAAA,EAAAmM,EAAAzQ,SAAuDsE,IAG/DtC,GAAOA,KAEP,IAAMsP,GAAOrR,IACb,IAAIA,KAAK+B,KAAKW,YACV,IAAK,GAAMshB,KAAOhkB,MAAK+B,KAAKW,YACnB1C,KAAK+B,KAAKW,YAAYmvB,eAAe7N,KAG1CrhB,EAAYqhB,GAAOhkB,KAAK+B,KAAKW,YAAYshB,GAIjD,IAAMm3B,GAAUn5C,EAAMwD,UAAWzD,EAAKo5C,aAChC/F,MAAqBn0C,KAAdc,EAAKqzC,MAA4BrzC,EAAKqzC,KAC/C8G,EAAan6C,EAAKm6C,UAOlB9G,KACInwC,IACAA,GAAO,EAAAolB,EAAAtqB,SAAekF,GACtBk2C,EAAQ,gBAAkB,oBAGzBA,EAAA,SACDA,EAAA,OAAoB,wBAGLl6C,KAAfi7C,IACAA,EAAa,SAASC,GAClB,MAAO9jB,MAAKrM,MAAMmwB,KAK9B,IAAMjjC,GAAQrF,EAAA9T,QAAQmZ,QAElBilC,MAAA,GACAC,GAAW,EACXrb,MAAA,GACEngC,EAAiBb,EAAKa,gBAAkB5C,KAAK+B,KAAKa,eAElDy7C,EAAe,WACbz7C,IACIu7C,GACA9C,EAAUnrB,aAAaiuB,GAE3BA,EAAY9C,EAAUriC,WAAW,WAC7BolC,GAAW,EACPrb,GAAOA,EAAIyZ,OACXzZ,EAAIyZ,QAERtjC,EAAMC,OAAO,GAAI9Z,GAAOJ,QAAQgc,aAC5BvG,MAAO,2CACPmQ,QAAS,2BACTN,QAAS3hB,MAEdA,IAGXy7C,IAEA,IAAMC,GAAaplC,EAAMpN,OAEzB,KACIi3B,EAAM/iC,KAAK+B,KAAKxC,SAERk+C,IAAKA,EACLvnC,OAAQA,EACRwnC,iBAAiB,EACjBE,GAAIj7C,EACJqC,KAAMC,EACNmwC,MAAM,EACN7wB,QAAS3hB,EACTu4C,QAASp5C,EAAKo5C,YACdwC,aAAc39C,KAAK+B,MAEvB,SAASH,EAAKiC,EAAUmB,GACpB,IAAIpC,IACAy4C,EAAUnrB,aAAaiuB,IACnBC,GAFR,CAOkB9B,EACdpjC,EAAO7U,EAAUgN,EAAKtP,KAAKU,SAC3By5C,GAEMt6C,EAAKiC,EAAUmB,MAG7B+9B,IAKI,cAAgBA,KAChBA,EAAIwb,WAAa,SAACpgD,GAGdkgD,MAMJtb,EAAIyZ,QAAO8B,EAAW9B,MAAQzZ,EAAIyZ,MAAM/6C,KAAKshC,KAEvD,MAAOyb,GACLtlC,EAAMC,OAAOqlC,GACTn6C,GACAA,EAASm6C,GAGjB,MAAOF,IAkBf,IAAMhC,GAAkB,SACpBpjC,EAAOulC,EAAqBh8C,EAC5By5C,GAIA,MAFAuC,GAAsBA,GAAuB,aAEtC,SAAS78C,EAAKiC,EAAUmB,GAC3B,IAAKpD,EACD,IACQiC,EAASk3C,YAAc,IACvBn5C,EAAMk5C,EAAmBj3C,EAAUmB,GAC5Bk3C,IACPl3C,EAAOk3C,EAAWl3C,IAExB,MAAO7G,GACLyD,EAAM,GAAI9C,OAAJ,kCAA4CX,GAI1D,GAAIyD,EACAsX,EAAMC,OAAOvX,GACb68C,EAAoB78C,OACjB,CACH,GAAMyS,IACFtV,KAAM8E,EAASk3C,WAIfI,QAASt3C,EAASs3C,QAClBl2C,KAAMD,EAEVkU,GAAMpF,QAAQrR,EAAWuC,EAAOqP,GAChCoqC,EAAoB,KAAMh8C,EAAWuC,EAAOqP,KA6ExDhV,GAAOJ,QAAQgc,YAAc,SAAqByjC,GAC9CA,EAAYA,MACZ1+C,KAAK6kB,QAAU65B,EAAU75B,QACzB7kB,KAAKuhB,KAAOm9B,EAAU75B,SAAW,qBACjC7kB,KAAK45B,QAAU8kB,EAAUhqC,OAAS,kBAClC1U,KAAKiF,KAAOy5C,GAEhBr/C,EAAOJ,QAAQgc,YAAYhY,WAAY,EAAA07C,EAAA5+C,SAAcjB,MAAMmE,WAE3D5D,EAAOJ,QAAQgc,YAAYhY,UAAU27C,YAAcv/C,EAAOJ,QAAQgc,gVCv3BlE,gEA2EA,QAAS4jC,GAAgB98C,GACrB/B,KAAK8+C,cAAgB/8C,EAAKg9C,aAC1B/+C,KAAKg/C,MAAQj9C,EAAKk9C,aAClBj/C,KAAKk/C,iBAAmBn9C,EAAKo9C,UAE7Bn/C,KAAKo/C,sBAAwBr9C,EAAKs9C,cAAgBt9C,EAAKu9C,eACvDt/C,KAAKu/C,oBAAsB,KAC3Bv/C,KAAKw/C,QAAUz9C,EAAK09C,WAEhB19C,EAAKkC,YAAWjE,KAAKg/C,MAAMz6C,QAAUxC,EAAKkC,WAC9CjE,KAAK0/C,cAAgB39C,EAAKwN,cAAgBvP,KAAK8+C,cAAcxuB,uBAC7DtwB,KAAK2/C,UAAY59C,EAAK69C,aACC3+C,KAAnBjB,KAAK2/C,YAAyB3/C,KAAK2/C,UAAY,MAEnD3/C,KAAK6/C,cAAgB,6GAtFzBzlC,EAAAzb,EAAA,mBACMgc,EAAMhc,EAAQ,OAEdqD,EAAQrD,EAAQ,UAsFtBkgD,GAAgB57C,WAQZ68C,YAAa,WAAW,GAAAlwB,GAAA5vB,IAKpB,OAJAA,MAAKu/C,oBAAsB1rC,EAAA9T,QAAQmZ,QAI5BrF,EAAA9T,QAAQ+T,UAAUlQ,KAAK,WAQ1B,MALKgsB,GAAKovB,MAAMe,MAGZnwB,EAAKowB,sBAFLpwB,EAAKqwB,WAAWrwB,EAAKovB,OAIlBpvB,EAAK2vB,oBAAoBzzC,WASxCo0C,KAAM,WACF,GAAKlgD,KAAKg/C,MAAMz6C,QAAhB,CAEA,GAAIoI,KACJ,IAtHiB,0BAsHb3M,KAAK6/C,eAGD7/C,KAAK2/C,UAAW,CAChB,GAAMQ,GAAoBxlC,EAAIqR,MAC1BhsB,KAAK8+C,cAAc37C,uBAEvBwJ,IACIpH,KA9HK,yBA+HL66C,gBACIpwC,IAAKhQ,KAAK2/C,UACVjwC,cAAe1P,KAAK0/C,cACpB96B,UAAWu7B,EAAkBl0B,OAM7CjsB,KAAKqgD,eAAe1zC,GAAU,KAQlC2zC,aAAc,WACV,MAAOtgD,MAAKg/C,MAAQh/C,KAAKg/C,MAAMz6C,YAAUtD,IAS7Cs/C,gBAAiB,WACb,MAAOvgD,MAAK0/C,eAShBc,eAAgB,SAASn7C,GACrB,GAAIb,KAIJ,OAHIxE,MAAKg/C,OAASh/C,KAAKg/C,MAAMx6C,SACzBA,EAASxE,KAAKg/C,MAAMx6C,QAEjBA,EAAOa,IAelBg7C,eAAgB,SAASpB,EAAUwB,GAC/B,IAAKzgD,KAAKu/C,oBACN,KAAM,IAAIzgD,OAAM,+CAIpB,IAAMoF,IACFK,QAASvE,KAAKg/C,MAAMz6C,QAExBvC,GAAMwD,OAAOtB,EAAM+6C,GAEnBj/C,KAAKigD,WAAW/7C,EAAMu8C,IAS1BC,YAAa,WACT,MAAO1gD,MAAK2/C,WAWhBgB,YAAa,SAAS3wC,GAClBhQ,KAAK2/C,UAAY3vC,GAcrBiwC,WAAY,SAAS/7C,EAAMu8C,GAAY,GAAAvrB,GAAAl1B,KAC7BqR,EAAOrR,KAKTm1B,MAAA,EACJ,KACIA,EAAOn1B,KAAKk/C,iBAAiBh7C,EAAMu8C,GACrC,MAAOtiD,GACLg3B,EAAOthB,EAAA9T,QAAQoZ,OAAOhb,GAG1Bg3B,EAAOA,EAAKvxB,KACR,SAASkpB,GACLrY,QAAQe,IAAI,wBAAyBsX,GACrCzb,EAAKkuC,oBAAoBzrC,QAAQgZ,IAClC,SAASpY,GAER,GAAMksC,GAAalsC,EAAMzP,KAAOyP,EAAMzP,KAAK86C,MAAQ,KAC7Cc,EAAYjuC,QAAQvB,EAAK2tC,MAAMe,QAAUntC,QAAQguC,EACvD,IAAyB,MAArBlsC,EAAM4a,aAAuB5a,EAAMzP,OAAS47C,EAE5C,KAAMnsC,EAOLA,GAAMzP,KAAK86C,OAAUrrC,EAAMzP,KAAK67C,WAAcpsC,EAAMzP,KAAKV,UAC1DmQ,EAAMzP,KAAK86C,MAAQ1uC,EAAK2tC,MAAMe,MAC9BrrC,EAAMzP,KAAK67C,UAAYzvC,EAAK2tC,MAAM8B,UAClCpsC,EAAMzP,KAAKV,QAAU8M,EAAK2tC,MAAMz6C,SAEpC8M,EAAK2tC,MAAQtqC,EAAMzP,KACnBoM,EAAK2uC,wBAWT7qB,EARCsrB,EAQMtrB,EAAKmO,MAAM,SAAC5uB,GACfD,QAAQe,IAAI,gCAAkCd,KAR3CygB,EAAKmO,MAAM,SAACnlC,GACf+2B,EAAKqqB,oBAAoBpmC,OAAOhb,KAUxCg3B,EAAK7zB,QAST0+C,oBAAqB,WACjB,GAAMe,GAAY/gD,KAAKghD,cACvB,KAAKD,EACD,KAAM,IAAIjiD,OAAM,sCAIpB,IAFAkB,KAAK6/C,cAAgBkB,EAEJ,iBAAbA,EAIA,WAHA/gD,MAAKqgD,gBACD96C,KAAM,iBAKd,IAAIvF,KAAKg/C,MAAMn6B,SAAW7kB,KAAKg/C,MAAMtqC,MAKjC,WAJA1U,MAAKo/C,sBAAsB2B,GACvBl8B,QAAS7kB,KAAKg/C,MAAMn6B,SAAW,GAC/BnQ,MAAO1U,KAAKg/C,MAAMtqC,OAAS,IAKnC,IAAMusC,KAzTW,2BA0TbF,IACAE,EAAYrB,SAAW5/C,KAAK2/C,WAEhC3/C,KAAKo/C,sBAAsB2B,EAAWE,IAU1CD,aAAc,WACV,GAAME,GAAOlhD,KAAKmhD,aAClB1sC,SAAQe,IAAI,qBAAqB,EAAA6U,EAAAtqB,SAAemhD,GAChD,IAAMH,GAAY/gD,KAAKohD,uBAAuBF,EAE9C,OADAzsC,SAAQe,IAAI,iBAAkBurC,GACvBA,GAkBXI,YAAa,WACT,GAAMpB,GAAQ//C,KAAKg/C,MAAMe,UAGnBsB,EAAYzuC,QAAQ5S,KAAKw/C,QAAQ8B,eAAiB1uC,QAAQ5S,KAAK2/C,WAC/D4B,EACF3uC,QAAQ5S,KAAKw/C,QAAQl0B,eACrB1Y,QAAQ5S,KAAKw/C,QAAQj0B,aAPLzqB,GAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KAUpB,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,SAAmBggD,KAAnBj/C,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAA0B,CAAA,GAAfogD,GAAehgD,EAAAK,MAClBigD,GAAe,EACfC,GAAgB,EAFEntB,GAAA,EAAAC,GAAA,EAAAC,MAAAvzB,EAAA,KAGtB,IAAA,GAAAwzB,GAAAC,GAAA,EAAAtzB,EAAArB,SAAoBmhD,EAAKQ,UAAzBptB,GAAAG,EAAAC,EAAArzB,QAAAC,MAAAgzB,GAAA,EAAiC,CAAA,GAAtBqtB,GAAsBltB,EAAAlzB,KA3WpB,4BA4WLogD,EACAH,GAAe,EA5WT,kBA6WCG,IACPF,GAAgB,IAPF,MAAA7/C,GAAA2yB,GAAA,EAAAC,EAAA5yB,EAAA,QAAA,KAAA0yB,GAAAI,EAAA7yB,QAAA6yB,EAAA7yB,SAAA,QAAA,GAAA0yB,EAAA,KAAAC,IAWtB,GAAIgtB,GAAgBH,GAAaI,GAAiBF,EAC9C,MAAOL,IAtBK,MAAAt/C,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,IA2BpB,GAAMY,GAAM,GAAI9C,OAAM,2CAMtB,MALA8C,GAAI2f,KAAO,uBACX3f,EAAIggD,mBACAP,GAAWz/C,EAAIggD,gBAAgBhrC,KA5XlB,0BA6Xb2qC,GAAY3/C,EAAIggD,gBAAgBhrC,KA5XlB,kBA6XlBhV,EAAIigD,gBAAkB9B,EAChBn+C,GAUVw/C,uBAAwB,SAASF,GAE7B,IAAK,GADCJ,IAAa9gD,KAAKg/C,WAAa8B,cAC5BliD,EAAI,EAAGA,EAAIsiD,EAAKQ,OAAOviD,SAAUP,EAAG,CACzC,GAAMkjD,GAAYZ,EAAKQ,OAAO9iD,EAC9B,KAAsC,IAAlCkiD,EAAUzqC,QAAQyrC,GAClB,MAAOA,MAQvBziD,EAAOJ,QAAU4/C,0JC9ZjB,YAGAx/C,GAAOJ,QAAQua,YAAc7a,EAAQ,kBAAkB6a,YAEvDna,EAAOJ,QAAQ2S,YAAcjT,EAAQ,kBAAkBiT,YAEvDvS,EAAOJ,QAAQ8iD,oBAAsBpjD,EAAQ,kBAAkBojD,oBAE/D1iD,EAAOJ,QAAQ+iD,eAAiBrjD,EAAQ,qBAAqBqjD,eAE7D3iD,EAAOJ,QAAQgjD,sBAAwBtjD,EAAQ,qBAAqBsjD,sBAEpE5iD,EAAOJ,QAAQijD,gBAAkBvjD,EAAQ,sBAEzCU,EAAOJ,QAAQ8D,cAAgBpE,EAAQ,cAAcoE,cAErD1D,EAAOJ,QAAQgc,YAActc,EAAQ,cAAcsc,YAEnD5b,EAAOJ,QAAQ2R,aAAejS,EAAQ,YAAYiS,aAElDvR,EAAOJ,QAAQkjD,KAAOxjD,EAAQ,iBAE9BU,EAAOJ,QAAQ2b,cAAgBjc,EAAQ,2BAEvCU,EAAOJ,QAAQmjD,iBAAmBzjD,EAAQ,+BAE1CU,EAAOJ,QAAQojD,WAAa1jD,EAAQ,wBAEpCU,EAAOJ,QAAQqjD,UAAY3jD,EAAQ,uBAEnCU,EAAOJ,QAAQsjD,KAAO5jD,EAAQ,iBAE9BU,EAAOJ,QAAQujD,gBAAkB7jD,EAAQ,eAGzCU,EAAOJ,QAAQwjD,uBAAyB9jD,EAAQ,8BAEhDU,EAAOJ,QAAQqU,eAAiB3U,EAAQ,YAAY2U,eAEpDjU,EAAOJ,QAAQyjD,YAAc/jD,EAAQ,kBAErCU,EAAOJ,QAAQ8b,OAASpc,EAAQ,YAEhCU,EAAOJ,QAAQ0jD,eAAiBhkD,EAAQ,qBAAqBgkD,eAE7DtjD,EAAOJ,QAAQ4/C,gBAAkBlgD,EAAQ,sBAGzCU,EAAOJ,QAAQk5C,kBACXx5C,EAAQ,sCAAsCoB,QAClDV,EAAOJ,QAAQU,qBACXhB,EAAQ,yCAAyCoB,QAUrDV,EAAOJ,QAAQkT,oBAAsBxT,EAAQ,iBAAiBwT,oBAS9D9S,EAAOJ,QAAQ2jD,wBAA0BjkD,EAAQ,iBAAiBkkD,cAOlExjD,EAAOJ,QAAQ6jD,wBAA0BnkD,EAAQ,iBAAiBokD,aAKlE,IAAIxjD,OAAA,EAOJF,GAAOJ,QAAQM,QAAU,SAASjB,GAC9BiB,EAAUjB,GAOde,EAAOJ,QAAQ+jD,WAAa,WACxB,MAAOzjD,IASXF,EAAOJ,QAAQgkD,YAAc,SAASC,GAClC,GAAMC,GAAc5jD,CACpBA,GAAU,SAASsH,EAASxC,GACxB,MAAO6+C,GAAQC,EAAat8C,EAASxC,IAK7C,IAAI++C,GAAqB,WAAA,MAAM,IAAI/jD,GAAOJ,QAAQk5C,kBAQlD94C,GAAOJ,QAAQS,sBAAwB,SAAS2jD,GAC5CD,EAAqBC,GA0BzBhkD,EAAOJ,QAAQqkD,aAAe,SAASvhD,GAYnC,MAXoB,gBAATA,KACPA,GACIG,QAAWH,IAGnBA,EAAKxC,QAAUwC,EAAKxC,SAAWA,EAC/BwC,EAAKkP,MAAQlP,EAAKkP,OAAS,GAAI5R,GAAOJ,QAAQ8iD,qBAC5CwB,aAAc9jD,EAAO8jD,eAEvBxhD,EAAKqP,UAAYrP,EAAKqP,WAAa,GAAI/R,GAAOJ,QAAQujD,gBACtDzgD,EAAKkR,YAAclR,EAAKkR,aAAemwC,IAChC,GAAI/jD,GAAOJ,QAAQ2R,aAAa7O,goBCpK3C,YAoBA,SAASyhD,GAAaC,GAClBzjD,KAAK0jD,WAAaD,GAClBzjD,KAAK2jD,eAAiB,EACtB3jD,KAAK4jD,iBAAmBC,EAAG,KAAMhlD,EAAG,MAGpCmB,KAAKmoB,mBAAqB07B,EAAG,KAAMhlD,EAAG,MAU1C2kD,EAAavgD,UAAUmlB,SAAW,WAC9B,MAAOpoB,MAAK0jD,UAAU1jD,KAAK2jD,iBAQ/BH,EAAavgD,UAAU6gD,YAAc,WACjC,MAAO9jD,MAAK0jD,WAQhBF,EAAavgD,UAAU8gD,iBAAmB,WACtC,MAAO/jD,MAAK2jD,gBAUhBH,EAAavgD,UAAUglB,iBAAmB,SAASD,GAC/C,MAAOhoB,MAAK4jD,gBAAgB57B,EAAY,IAAM,MAYlDw7B,EAAavgD,UAAUulB,iBAAmB,SAASriB,EAAO6hB,GACtDhoB,KAAK4jD,gBAAgB57B,EAAY,IAAM,KAAO7hB,GASlDq9C,EAAavgD,UAAUslB,UAAY,SAASO,EAAQk7B,GAI5CA,GACAhkD,KAAK0jD,UAAY56B,EAAOnoB,OAAOX,KAAK0jD,WACpC1jD,KAAK2jD,gBAAkB76B,EAAO3pB,QAE9Ba,KAAK0jD,UAAY1jD,KAAK0jD,UAAU/iD,OAAOmoB,IAO/CzpB,EAAOJ,QAAUukD,2BCvGjB,YA8CA,SAASpB,GAAiB5wC,EAAMzP,GAC5B/B,KAAKwR,KAAOA,EAEZxR,KAAKikD,iBAAmBrxC,QAAQ7Q,EAAK4Q,iBACrC3S,KAAKkkD,cAAgB,GAAItpC,GAAc5a,MAGvCA,KAAKmkD,YAAcnkD,KAAKkkD,eACxBlkD,KAAKokD,sBAELpkD,KAAKqkD,QAAUtiD,EAAKooB,QAAU,KApDlC,GAAMzP,GAAe/b,EAAQ,UAAU+b,aACjC1Y,EAAQrD,EAAQ,YAChBic,EAAgBjc,EAAQ,oBAK1B2lD,MAAA,EAGAA,GAAW7vC,QAAQe,IAAI/T,KAAKgT,SA4ChCzS,EAAMmZ,SAASinC,EAAkB1nC,GAMjC0nC,EAAiBn/C,UAAUmnB,UAAY,WACnC,MAAOpqB,MAAKqkD,SAQhBjC,EAAiBn/C,UAAUshD,UAAY,SAASp6B,GAC5CnqB,KAAKqkD,QAAUl6B,GAYnBi4B,EAAiBn/C,UAAUuhD,iBAAmB,WAC1C,MAAKxkD,MAAKwR,KAINxR,KAAKqkD,QACErkD,KAAKqkD,QAAQ5J,mBAAmBz6C,KAAKwR,KAAKgzC,oBAE1CxkD,KAAKwR,KAAKgzC,uBASzBpC,EAAiBn/C,UAAU0kB,gBAAkB,WACzC,MAAO3nB,MAAKkkD,eAQhB9B,EAAiBn/C,UAAUwhD,kBAAoB,SAAS56C,GACpD,MAAO7J,MAAKokD,mBAAmBv6C,IASnCu4C,EAAiBn/C,UAAUyhD,eAAiB,SAASC,EAAYC,GAC7D,GAAMC,GAAmB7kD,KAAKokD,mBAAmBO,EAC7CE,WACO7kD,MAAKokD,mBAAmBO,GAC/B3kD,KAAKokD,mBAAmBQ,GAAcC,IAe9CzC,EAAiBn/C,UAAUunB,kBAAoB,SAC3Cs6B,EAAqBC,GAWrB,GAAMC,IAAqBhlD,KAAKikD,mBAAqBc,EAEjDE,MAAA,EACAD,IACAC,EAAc,GAAIrqC,GAAc5a,MAChCA,KAAKmkD,YAAcc,GACnBjlD,KAAKokD,uBAELa,EAAcjlD,KAAKipB,aAGvB,IAAMi8B,GAAcllD,KAAKkkD,cAGnBiB,EAAQD,EAAY/7B,SAASvO,EAAcwO,UAAUN,OACrDA,IACN,KAAK,GAAMs8B,KAAUD,GACjB,GAAKA,EAAMtzB,eAAeuzB,GAG1B,IAAK,GAAM77C,KAAY47C,GAAMC,GACpBD,EAAMC,GAAQvzB,eAAetoB,IAGlCuf,EAAOlS,KAAKuuC,EAAMC,GAAQ77C,GAKlC07C,GAAY/7B,gBAAgBJ,EAE5B,IAAMu8B,GAAgBJ,EAAYK,SAKlCL,GAAYK,UAAYJ,EAAYI,UAG/BN,IAIDE,EAAYI,UAAYD,EAIxBH,EAAYh7B,mBACR66B,EAAwBnqC,EAAcwO,WAO9C67B,EAAY/6B,mBAAmB46B,EAAqBlqC,EAAc8O,WAGlE1pB,KAAKkkD,cAAgBe,EACrBjlD,KAAKS,KAAK,qBAAsBT,KAAKwR,KAAMxR,KAAMglD,IAUrD5C,EAAiBn/C,UAAU2lB,oBAAsB,SAAS/e,GACtD,GAAMwK,GAAMrU,KAAKokD,mBAAmBv6C,EACpC,YAAgB5I,KAARoT,EAAqB,KAAOA,GASxC+tC,EAAiBn/C,UAAUsiD,cAAgB,SAAS17C,GAChD,GAAM27C,GAAKxlD,KAAK4oB,oBAAoB/e,EACpC,IAAK27C,EAGL,MAAOxjD,GAAMyjD,YAAYD,EAAGE,YAAa,SAASrtC,GAC9C,MAAOA,GAAGoL,SAAW5Z,KAS7Bu4C,EAAiBn/C,UAAUgmB,YAAc,WACrC,IAAKjpB,KAAKikD,iBACN,KAAM,IAAInlD,OAAM,qHAKpB,IAAMkqB,GAAW,GAAIpO,GAAc5a,KAEnC,OADAA,MAAKmkD,WAAWvtC,KAAKoS,GACdA,GAuBXo5B,EAAiBn/C,UAAUykB,oBAAsB,SAASoB,EAAQ68B,EACpB38B,EAAU5B,GACpD,IAAK4B,EACD,KAAM,IAAIlqB,OACN,oEAIR,KAAK6mD,GAAqB38B,GAAYhpB,KAAKkkD,cACvC,KAAM,IAAIplD,OACN,8HAKR,KAAIkB,KAAKqkD,UACLv7B,EAAS9oB,KAAKqkD,QAAQ5J,mBAAmB3xB,GACpCA,EAAO3pB,QAFhB,CAmFA,IAAK,GA5ECwY,GAAYguC,EAAoB/qC,EAAc8O,UAChD9O,EAAcwO,SACZw8B,EAAmBD,EAAoB/qC,EAAcwO,SACvDxO,EAAc8O,UAuEdm8B,GAAY,EACZC,GAAkB,EACblnD,EAAI,EAAGA,EAAIkqB,EAAO3pB,OAAQP,IAAK,CACpC,GAAMgV,GAAQkV,EAAOlqB,GACfiL,EAAU+J,EAAM6P,QAEhBohC,EAAmB7kD,KAAKokD,mBAAmBv6C,EAEjD,IAAKg7C,EAUL,GAFAiB,GAAkB,EAEdjB,GAAoB77B,EAAxB,CAKA,GAAM+8B,GAAY/8B,EAASg9B,wBAAwBruC,EAC/CouC,IAWIzB,EADAO,GAAoBkB,EACX,SAAWl8C,EAAU,4CACAg7C,EAErB,SAAWh7C,EAAU,oCACJg7C,GAE9B77B,EAAW67B,IAKfpwC,QAAQxI,KAAK,6BAA+BpC,EAC/B,uBAAyBmf,EAAW,OACpC67B,GACb77B,EAASi9B,wBAAwBpB,EAAkBltC,GACnDktC,EAAiBoB,wBAAwBj9B,EAAU48B,GACnD58B,EAAW67B,EACXgB,GAAY,OAjCRvB,GAAS,SAAWz6C,EAAU,wBAA0Bmf,OATxDhpB,MAAKkmD,mBAAmBtyC,EAAOoV,EAAU28B,GACzCG,GAAkB,EAClBD,GAAY,GA8ChBC,GAAoBD,GACpB78B,EAASkB,mBAAmB9C,EAAiBzP,KAUrDyqC,EAAiBn/C,UAAUkjD,aAAe,SAASvyC,EAAOwyC,GACtD,GAAIpmD,KAAKqkD,QAAS,CAEd,IADerkD,KAAKqkD,QAAQ5J,oBAAoB7mC,IACpCzU,OACR,OAIR,GAAM6pB,GAAWhpB,KAAKokD,mBAAmBxwC,EAAM6P,QAC/C,IAAIuF,EACA,GAA0B,YAAtBo9B,EAAiC,CACjC9B,EAAS,4DACA1wC,EAAM6P,QAEf,KAAK,GADC4iC,GAAWr9B,EAAS08B,YACjB7Z,EAAI,EAAGA,EAAIwa,EAASlnD,OAAQ0sC,IACjC,GAAIwa,EAASxa,GAAGpoB,UAAY7P,EAAM6P,QAAS,CAEvC7I,EAAc0rC,iBACV1yC,EACAoV,EAASG,SAASvO,EAAcwO,WAChC,GAGCi9B,EAASxa,GAAG0a,gBACbF,EAASxa,GAAKj4B,EAIlB,YAIR0wC,GAAS,2DACA1wC,EAAM6P,aAKvBzjB,MAAKkmD,mBAAmBtyC,EAAO5T,KAAKkkD,eAAe,IAevD9B,EAAiBn/C,UAAUijD,mBAAqB,SAAStyC,EAAOoV,EACP28B,GACrD,GAAM97C,GAAU+J,EAAM6P,OACtBuF,GAASw9B,SAAS5yC,EAAO+xC,GACzB3lD,KAAKokD,mBAAmBv6C,GAAWmf,CAEnC,IAAM/jB,IACF+jB,SAAUA,EACVy9B,WAAYd,GAAqB38B,GAAYhpB,KAAKkkD,cAEtDlkD,MAAKS,KAAK,gBAAiBmT,EAAO5T,KAAKwR,KAC7BoB,QAAQ+yC,IAAoB,EAAO1gD,IAajDm9C,EAAiBn/C,UAAUyjD,iBAAmB,SAASpkC,EAAYqiC,EACXC,GAEpD,GAAMC,GAAmB7kD,KAAKokD,mBAAmBO,EAC7CE,UACO7kD,MAAKokD,mBAAmBO,GAC/B3kD,KAAKokD,mBAAmBQ,GAAcC,GAElC7kD,KAAKqkD,QACDrkD,KAAKqkD,QAAQ5J,oBAAoBn4B,IAAanjB,QAC9Ca,KAAKkmD,mBAAmB5jC,EAAYtiB,KAAKkkD,eAAe,GAG5DlkD,KAAKkmD,mBAAmB5jC,EAAYtiB,KAAKkkD,eAAe,IAapE9B,EAAiBn/C,UAAU0jD,YAAc,SAAS98C,GAC9C,GAAMmf,GAAWhpB,KAAKokD,mBAAmBv6C,EACzC,KAAKmf,EACD,MAAO,KAGX,IAAM49B,GAAU59B,EAAS29B,YAAY98C,EACrC,IAAI+8C,EAAS,OACF5mD,MAAKokD,mBAAmBv6C,EAC/B,IAAM5E,IACF+jB,SAAUA,EAEdhpB,MAAKS,KAAK,gBAAiBmmD,EAAS5mD,KAAKwR,SAAMvQ,IAAW,EAAMgE,GAEpE,MAAO2hD,IAeXxE,EAAiBn/C,UAAU4jD,qBAAuB,SAASC,EAAUC,GACjE,GAAID,GAAYC,EAEZ,MAAO,EAGX,IAAMC,GAAYhnD,KAAKokD,mBAAmB0C,GACpCG,EAAYjnD,KAAKokD,mBAAmB2C,EAE1C,QAAkB9lD,KAAd+lD,EACA,MAAO,KAEX,QAAkB/lD,KAAdgmD,EACA,MAAO,KAGX,IAAID,IAAcC,EAAW,CAKzB,IAAK,GAFDC,OAAA,GAAMC,MAAA,GACJr+B,EAASk+B,EAAUtB,YAChB0B,EAAM,EAAGA,EAAMt+B,EAAO3pB,aAChB8B,KAATimD,OAA+BjmD,KAATkmD,GAAqBC,IAAO,CACpD,GAAMC,GAAOv+B,EAAOs+B,GAAK3jC,OACrB4jC,IAAQP,IACRI,EAAOE,GAEPC,GAAQN,IACRI,EAAOC,GAGf,MAAOF,GAAOC,EAQlB,IADA,GAAI3B,GAAKwB,EACFxB,GAAI,CACP,GAAIA,IAAOyB,EAEP,OAAQ,CAEZzB,GAAKA,EAAGQ,wBAAwBprC,EAAcwO,UAKlD,IADAo8B,EAAKwB,EACExB,GAAI,CACP,GAAIA,IAAOyB,EAEP,MAAO,EAEXzB,GAAKA,EAAGQ,wBAAwBprC,EAAc8O,WAIlD,MAAO,OAMXrqB,EAAOJ,QAAUmjD,yECjoBjB,YA8BA,SAASxnC,GAAc0sC,GACnBtnD,KAAKunD,kBAAoBD,EACzBtnD,KAAK0kC,QAAU4iB,EAAiB91C,KAAO81C,EAAiB91C,KAAKzK,OAAS,KACtE/G,KAAK+uC,WACL/uC,KAAKwnD,WAAa,EAClBxnD,KAAKynD,YAAc,GAAInF,GAAUtiD,KAAK0kC,SACtC1kC,KAAKynD,YAAYrgC,gBAAkB,KACnCpnB,KAAKslD,UAAY,GAAIhD,GAAUtiD,KAAK0kC,SACpC1kC,KAAKslD,UAAUl+B,gBAAkB,KAEjCpnB,KAAK0nD,cAAgB,KACrB1nD,KAAK2nD,cAAgB,KAGrB3nD,KAAK4pB,qBAAuBi6B,EAAK,KAAMhlD,EAAK,MAE5CmB,KAAK4nD,MAAQ5nD,KAAK0kC,QAAU,KAAM,GAAInhC,OAAOskD,cAxCjD,GAAMvF,GAAY3jD,EAAQ,gBACpBqD,EAAQrD,EAAQ,YAChB6a,EAAc7a,EAAQ,WAAW6a,WA6CvCoB,GAAc8O,UAAY,IAM1B9O,EAAcwO,SAAW,IAWzBxO,EAAc3X,UAAUimB,gBAAkB,SAAS4+B,GAC/C,GAAI9nD,KAAK+uC,QAAQ5vC,OAAS,EACtB,KAAM,IAAIL,OAAM,iDAKpB,IAAMipD,GAAiB/lD,EAAMme,IACzBne,EAAMogB,SACF0lC,EAAY3nC,IAAI,SAAS6nC,GACrB,MAAOA,GAAQp0C,SAG3B,SAASyE,GACL,MAAO,IAAImB,GAAYnB,IAG3BrY,MAAKynD,YAAYQ,eAAeF,GAChC/nD,KAAKslD,UAAU2C,eAAeH,IAOlCltC,EAAc3X,UAAUyO,UAAY,WAChC,MAAO1R,MAAK0kC,SAOhB9pB,EAAc3X,UAAUmnB,UAAY,WAChC,MAAOpqB,MAAKunD,kBAAkBn9B,aAOlCxP,EAAc3X,UAAUwmB,eAAiB,WACrC,MAAOzpB,MAAKunD,mBAchB3sC,EAAc3X,UAAUilD,aAAe,WACnC,MAAOloD,MAAKwnD,YAQhB5sC,EAAc3X,UAAUyiD,UAAY,WAChC,MAAO1lD,MAAK+uC,SAYhBn0B,EAAc3X,UAAUkmB,SAAW,SAASxR,GACxC,GAAIA,GAAaiD,EAAc8O,UAC3B,MAAO1pB,MAAKynD,WACT,IAAI9vC,GAAaiD,EAAcwO,SAClC,MAAOppB,MAAKslD,SAEZ,MAAM,IAAIxmD,OAAM,sBAAwB6Y,EAAY,MAa5DiD,EAAc3X,UAAU0mB,mBAAqB,SAAShS,GAClD,MAAO3X,MAAKmpB,SAASxR,GAAWyP,iBAYpCxM,EAAc3X,UAAUinB,mBAAqB,SAAS/jB,EAAOwR,GACzD3X,KAAKmpB,SAASxR,GAAWyP,gBAAkBjhB,GAY/CyU,EAAc3X,UAAU+iD,wBAA0B,SAASruC,GACvD,GAAIA,GAAaiD,EAAc8O,UAC3B,MAAO1pB,MAAK0nD,aACT,IAAI/vC,GAAaiD,EAAcwO,SAClC,MAAOppB,MAAK2nD,aAEZ,MAAM,IAAI7oD,OAAM,sBAAwB6Y,EAAY,MAe5DiD,EAAc3X,UAAUgjD,wBAA0B,SAASF,EAAWpuC,GAClE,GAAI3X,KAAKgmD,wBAAwBruC,GAC7B,KAAM,IAAI7Y,OAAM,wEAIpB,IAAI6Y,GAAaiD,EAAc8O,UAC3B1pB,KAAK0nD,cAAgB3B,MAClB,CAAA,GAAIpuC,GAAaiD,EAAcwO,SAGlC,KAAM,IAAItqB,OAAM,sBAAwB6Y,EAAY,IAFpD3X,MAAK2nD,cAAgB5B,EAMzB/lD,KAAKkqB,mBAAmB,KAAMvS,IASlCiD,EAAc3X,UAAUujD,SAAW,SAAS5yC,EAAOowC,GAC/C,GAAMmE,GAAenE,EAAUhkD,KAAKynD,YAAcznD,KAAKslD,UAGjD38B,EAAc3oB,KAAKypB,gBACrBd,GAAYnX,MACZmX,EAAYnX,KAAK42C,6BAA+Bz/B,IAChD/N,EAAc0rC,iBAAiB1yC,EAAOu0C,EAAcnE,GAGhDpwC,EAAMyB,YACN8yC,EAAaF,gBAAgBr0C,IAWxBA,EAAMi2B,SAA+B,kBAApBj2B,EAAMwC,WAAkC4tC,IAC1DppC,EAAc0rC,iBAAiB1yC,EAAOu0C,EAAcnE,IAKhE,IAAIqE,OAAA,EAGAA,GADArE,EACc,EAEAhkD,KAAK+uC,QAAQ5vC,OAG/Ba,KAAK+uC,QAAQuJ,OAAO+P,EAAa,EAAGz0C,GAChCowC,GACAhkD,KAAKwnD,cAWb5sC,EAAc0rC,iBAAmB,SAAS1yC,EAAOu0C,EAAcxC,GAE3D/xC,EAAMi2B,OAASse,EAAaG,kBACxB10C,EAAMmD,aAEc,kBAApBnD,EAAMwC,YACNxC,EAAM/T,OAASsoD,EAAaG,kBACxB10C,EAAMwB,gBAGVxB,EAAMyB,WAKFswC,IACA/xC,EAAM20C,gBAAiB,IAWnC3tC,EAAc3X,UAAU0jD,YAAc,SAAS98C,GAC3C,IAAK,GAAIjL,GAAIoB,KAAK+uC,QAAQ5vC,OAAS,EAAGP,GAAK,EAAGA,IAAK,CAC/C,GAAMyZ,GAAKrY,KAAK+uC,QAAQnwC,EACxB,IAAIyZ,EAAGoL,SAAW5Z,EAKd,MAJA7J,MAAK+uC,QAAQuJ,OAAO15C,EAAG,GACnBA,EAAIoB,KAAKwnD,YACTxnD,KAAKwnD,aAEFnvC,EAGf,MAAO,OAQXuC,EAAc3X,UAAUwmC,SAAW,WAC/B,MAAOzpC,MAAK4nD,OAOhBvoD,EAAOJ,QAAU2b,uECrVjB,mIASAm0B,EAAApwC,EAAA,UACA0jC,EAAA1jC,EAAA,qBAOAU,GAAOJ,QAAQ2S,aAEXgD,SAAU,WAGVX,WAAY,aAGZpC,QAAS,UAETuC,OAAQ,SAGRG,KAAM,OAGN8M,UAAW,YAGf,IAAMmnC,KAyBNnpD,GAAOJ,QAAQua,YAAc,SACzB5F,IAKC,YAAa,OAAQ,SAAU,WAAWnF,QAAQ,SAACo+B,GAC3Cj5B,EAAMi5B,KAGN2b,EAAQ50C,EAAMi5B,MACf2b,EAAQ50C,EAAMi5B,IAASj5B,EAAMi5B,IAEjCj5B,EAAMi5B,GAAQ2b,EAAQ50C,EAAMi5B,QAG/B,aAAc,aAAc,eAAep+B,QAAQ,SAACo+B,GAC5Cj5B,EAAM7K,SAAY6K,EAAM7K,QAAQ8jC,KAGhC2b,EAAQ50C,EAAM7K,QAAQ8jC,MACvB2b,EAAQ50C,EAAM7K,QAAQ8jC,IAASj5B,EAAM7K,QAAQ8jC,IAEjDj5B,EAAM7K,QAAQ8jC,GAAQ2b,EAAQ50C,EAAM7K,QAAQ8jC,OAGhD7sC,KAAK4T,MAAQA,MAEb5T,KAAK6pC,OAAS,KACd7pC,KAAKH,OAAS,KACdG,KAAK2R,OAAS,KACd3R,KAAK0U,MAAQ,KACb1U,KAAKuoD,gBAAiB,EACtBvoD,KAAKyoD,aAAe,KACpBzoD,KAAK0oD,MAAQ1oD,KAAK4T,MAAM2O,iBACpB,GAAIhf,MAAKvD,KAAK4T,MAAM2O,kBAAoB,KAE5CviB,KAAK2oD,eAKL3oD,KAAK4oD,qBAAuB,KAK5B5oD,KAAK6oD,mBAAqB,KAM1B7oD,KAAK8oD,iCAKL9oD,KAAK+oD,mBAAqB,KAM1B/oD,KAAK2qC,kBAAmB,GAE5BxI,EAAApiC,QAAMob,SAAS9b,EAAOJ,QAAQua,YAA9Bu1B,EAAAr0B,cAGAynB,EAAApiC,QAAMyF,OAAOnG,EAAOJ,QAAQua,YAAYvW,WAOpCwgB,MAAO,WACH,MAAOzjB,MAAK4T,MAAMY,UAOtBuC,UAAW,WACP,MAAO/W,MAAK4T,MAAMi2B,QAAU7pC,KAAK4T,MAAMoC,SAQ3CI,QAAS,WACL,MAAOpW,MAAK2oD,YAAYpjD,MAAQvF,KAAK4T,MAAMrO,MAS/C4P,YAAa,WACT,MAAOnV,MAAK4T,MAAMrO,MAStBmM,UAAW,WACP,MAAO1R,MAAK4T,MAAM9I,SAOtBy+B,MAAO,WACH,MAAOvpC,MAAK4T,MAAM2O,kBAOtBymC,QAAS,WACL,MAAOhpD,MAAK0oD,OAQhB7xC,WAAY,WACR,MAAO7W,MAAK2oD,YAAY5/C,SAAW/I,KAAK4T,MAAM7K,aASlDwM,eAAgB,WACZ,MAAOvV,MAAK4T,MAAM7K,aAQtBkgD,eAAgB,WAEZ,MAAOjpD,MAAKkpD,cAAcC,cAAgBnpD,KAAK4T,MAAMu1C,kBAYzDC,sBAAuB,WACnB,MAAOppD,MAAKuoD,eAAiBvoD,KAAK6W,aAAe7W,KAAKipD,kBAS1DjyC,OAAQ,WACJ,MAAOhX,MAAKkpD,cAAcG,KAAOrpD,KAAK4T,MAAMy1C,KAQhDj0C,YAAa,WACT,MAAOpV,MAAK4T,MAAM01C,WAOtBj0C,QAAS,WACL,WAAgCpU,KAAzBjB,KAAK4T,MAAM01C,WAsBtBxY,cAAe,SACXyY,EAAaC,EAAgBzrB,EAAqB6L,GAGlD5pC,KAAK2oD,aACDpjD,KAAMvF,KAAK4T,MAAMrO,KACjBwD,QAAS/I,KAAK4T,MAAM7K,SAExB/I,KAAK4T,MAAMrO,KAAOgkD,EAClBvpD,KAAK4T,MAAM7K,QAAUygD,EACrBxpD,KAAK4oD,qBAAuB7qB,EAC5B/9B,KAAK6oD,mBAAqBjf,GAQ9BtzB,iBAAkB,WACd,MAAkC,OAA3BtW,KAAK+oD,oBAWhBxyC,oBAAqB,WACjB,MAAOvW,MAAK2oD,aAAe3oD,KAAK2oD,YAAY5/C,SACH,oBAArC/I,KAAK2oD,YAAY5/C,QAAQ4Z,SAejCjJ,kBAAA,WAAA,QAAAA,GAAAgE,GAAA,MAAAspB,GAAAtmC,MAAAV,KAAAK,WAAA,GAAA2mC,IAAA,EAAA5sB,EAAAlE,QAAmB,SAAe2G,GAE9B,IAAK7c,KAAK8U,cACN,KAAM,IAAIhW,OAAM,iDAGpB,IACIkB,KAAK2oD,aAAe3oD,KAAK2oD,YAAY5/C,SACI,oBAArC/I,KAAK2oD,YAAY5/C,QAAQ4Z,QAG7B,KAAM,IAAI7jB,OACN,4DAUR,OAAIkB,MAAK+oD,oBACLt0C,QAAQe,IAAR,SACaxV,KAAKyjB,QADlB,8CAGAzjB,KAAK2qC,kBAAmB,EACjB3qC,KAAK+oD,qBAGhB/oD,KAAK+oD,mBAAqB/oD,KAAKypD,gBAAgB5sC,GACxC7c,KAAK+oD,qBA/BhB,OAAArvC,MAkCA+vC,gBAAA,WAAA,QAAAA,GAAA5rC,GAAA,MAAAJ,GAAA/c,MAAAV,KAAAK,WAAA,GAAAod,IAAA,EAAArD,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAiB,QAAAC,GAAeC,GAAf,GAAAxI,EAAA,OAAA2F,GAAAja,QAAAka,KAAA,SAAA6C,GAAA,OAAA,OAAAA,EAAA3C,KAAA2C,EAAAzb,MAAA,IAAA,GAAA,MAAAyb,GAAAzb,KAAA,GAAA,EAAA+Y,EAAAtG,SAKPD,EAAA9T,QAAQ+T,UALD,KAAA,GAAA,GAQT9T,KAAK2qC,kBAAmB,EAEpBt2B,MAVK,GAAAyI,EAAA3C,KAAA,EAYA0C,EAZA,CAAAC,EAAAzb,KAAA,EAAA,OAaDgT,EAAMrU,KAAK0pD,qBAAqB,0BAb/B5sC,EAAAzb,KAAA,EAAA,MAAA,KAAA,IAAA,MAAAyb,GAAAzb,KAAA,IAAA,EAAA+Y,EAAAtG,SAeW+I,EAAOqsB,aAAalpC,MAf/B,KAAA,IAeDqU,EAfCyI,EAAAxC,IAAA,KAAA,IAAAwC,EAAAzb,KAAA,EAAA,MAAA,KAAA,IAAA,GAAAyb,EAAA3C,KAAA,GAAA2C,EAAA6U,GAAA7U,EAAA,MAAA,GAkBU,oBAAXA,EAAA6U,GAAEpQ,KAlBD,CAAAzE,EAAAzb,KAAA,EAAA,OAAA,MAqBDoT,SAAQC,MAAR,8BACkC1U,KAAKyjB,QADvC,OACoD3G,EAAA6U,GAAEhd,OAAFmI,EAAA6U,KAEpD3xB,KAAK+oD,mBAAqB,KAC1B/oD,KAAK2qC,kBAAmB,EAzBvB7tB,EAAAC,OAAA,SAAA,KAAA,IAAA,IA2CD/c,KAAK2qC,iBA3CJ,CAAA7tB,EAAAzb,KAAA,EAAA,OAAA,MA6CDoT,SAAQe,IACJ,kCAAkCxV,KAAKyjB,QAAvC,KACG3G,EAAA6U,GAAEiI,QADL,mBA9CH9c,EAAAC,OAAA,WAAA,EAAA,KAAA,IAsDLtI,QAAQyG,KAAR,8BACkClb,KAAKyjB,QADvC,MAAA3G,EAAA6U,IAIAtd,EAAMrU,KAAK0pD,qBAAqB5sC,EAAA6U,GAAEiI,QA1D7B,KAAA,IAAA,MAuET55B,MAAK+oD,mBAAqB,KAC1B/oD,KAAK2qC,kBAAmB,EACxB3qC,KAAK2pD,cAAct1C,GAzEVyI,EAAAC,OAAA,SAAA,KAAA,IAAA,IAAA,MAAA,MAAAD,GAAAvC,SAAAqC,EAAA5c,OAAA,EAAA,QAAjB,OAAAypD,MA8EAC,qBAAsB,SAAS/zC,GAC3B,OACIg0B,YACIpkC,KAAM,iBACNwD,SACI4Z,QAAS,kBACT3d,KAAM,yBAA2B2Q,EAAS,UAkB1Dg0C,cAAe,SAASC,GACpB5pD,KAAK2oD,YAAciB,EAAiBjgB,WACpC3pC,KAAK4oD,qBACDgB,EAAiB7rB,qBAAuB,KAC5C/9B,KAAK6oD,mBACDe,EAAiBhgB,mBAAqB,KAC1C5pC,KAAK8oD,8BACDc,EAAiBrrB,iCACrBv+B,KAAKS,KAAK,kBAAmBT,OAOjC8U,YAAa,WACT,MAA2B,qBAApB9U,KAAK4T,MAAMrO,MAgBtB8kC,aAAc,WACV,MAAOrqC,MAAK4oD,sBAUhBne,eAAgB,WACZ,OACI/R,QAAS14B,KAAK6oD,qBAqBtB3Y,qBAAsB,WAClB,MAAOlwC,MAAK6oD,oBAiBhB9Y,gCAAiC,WAC7B,MAAO/vC,MAAK8oD,+BAGhBI,YAAa,WACT,MAAOlpD,MAAK4T,MAAMue,cAUtB03B,aAAc,SAASC,GAEnB,IAAKA,EAAgBl2C,MACjB,KAAM,IAAI9U,OAAM,0CASfkB,MAAK4T,MAAMue,WACZnyB,KAAK4T,MAAMue,aAEfnyB,KAAK4T,MAAMue,SAAS43B,iBAAmBD,EAAgBl2C,KAEvD,IAAIoQ,OAAA,EACJ,KAAKA,IAAOhkB,MAAK4T,MACR5T,KAAK4T,MAAMie,eAAe7N,KAG1BgmC,EAAqBhmC,UACfhkB,MAAK4T,MAAMoQ,GAI1B,IAAMimC,GAAQC,EAAyBlqD,KAAKoW,eACtCrN,EAAU/I,KAAK6W,YACrB,KAAKmN,IAAOjb,GACHA,EAAQ8oB,eAAe7N,KAGvBimC,EAAMjmC,UACAjb,GAAQib,KAU3B+sB,WAAY,WACR,MAAOn+B,SAAQ5S,KAAKkpD,cAAca,mBAQrCzkC,eAAgB,WACb,MAAOtlB,MAAKyoD,cAQfjjC,eAAgB,SAAS2kC,GACtBnqD,KAAKyoD,aAAe0B,GAOvBzD,iBAAkB,SAAS9yC,GACxB5T,KAAK4T,MAAQA,EAEb5T,KAAK2R,OAAS,KACd3R,KAAK0oD,MAAQ,GAAInlD,MAAKvD,KAAK4T,MAAM2O,oBAczC,IAAMynC,IACF,WAAY,OAAQ,UAAW,UAAW,SAAU,YAAa,aACjE,UAAW,WAAY,oBACzBI,OAAO,SAAS75B,EAAK6X,GACL,MAAd7X,GAAI6X,GAAO,EAAU7X,OAInB25B,GACFG,iBAAkBz0C,WAAc,GAChC00C,iBAAkBC,QAAW,GAC7BC,qBAAsBC,UAAa,GACnCC,uBAAwB3lC,IAAO,EAAG+D,OAAU,EAAG6hC,eAAkB,EACzCvlC,KAAQ,EAAGwlC,OAAU,EAAGC,cAAiB,EACzC1oC,MAAS,EAAG2oC,cAAiB;iBAErDC,kBAAmBC,QAAW,+GCxoBlC,SAASC,GAAM/jD,GACXlH,KAAKkH,QAAUA,EACflH,KAAKuhB,KAAO,KACZvhB,KAAKkrD,UAAY,KACjBlrD,KAAKmrD,aAAe,KACpBnrD,KAAKorD,QAAU,KAtBnB,GAAM1wC,GAAe/b,EAAQ,UAAU+b,YAEzB/b,GAAQ,YAsBhBwc,SAAS8vC,EAAOvwC,GAEtBuwC,EAAMhoD,UAAUooD,WAAa,SAAS9pC,EAAM2pC,GACpClrD,KAAKuhB,OAASA,GAAQvhB,KAAKkrD,YAAcA,IAE7ClrD,KAAKuhB,KAAOA,GAAQvhB,KAAKkH,QACzBlH,KAAKkrD,UAAYA,EAEjBlrD,KAAKS,KAAK,gBAAiBT,QAG/BirD,EAAMhoD,UAAUqoD,gBAAkB,SAAS11C,GACnC5V,KAAKmrD,eAAiBv1C,IAE1B5V,KAAKmrD,aAAev1C,EAEpB5V,KAAKS,KAAK,qBAAsBT,QASpCirD,EAAMhoD,UAAUsoD,WAAa,SAASH,GAClCprD,KAAKorD,QAAUA,GAGnB/rD,EAAOJ,QAAUgsD,mDCzDjB,YAgCA,SAAS5I,GAAWt7C,EAAQY,GACxB3H,KAAK+G,OAASA,EACd/G,KAAK2H,OAASA,EACd3H,KAAKskB,QAAS,EACdtkB,KAAKuhB,KAAO5Z,EACZ3H,KAAKwrD,eAAiB7jD,EACtB3H,KAAKkiB,WAAa,EAClBliB,KAAKyrD,eAAiB,EACtBzrD,KAAK0F,KAAO,KACZ1F,KAAK4V,WAAa,KAClB5V,KAAK8oB,QACD6b,OAAQ,MAEZ3kC,KAAK0rD,sBA+JT,QAASC,GAAqBhnB,EAAQ/wB,EAAO9M,GACzC,GAAM8kD,GAAch4C,EAAMw1C,wBAAwBxjC,YAC5CimC,EAAalnB,EAAOh9B,MAE1B,OAAKikD,GAIA9kD,GAIWA,EAAUglD,0BAA0BF,GACzBzhC,OAAO,SAAS1rB,GACvC,MAAOA,KAAMotD,IAEF1sD,OAAS,EACbysD,EAAc,KAAOC,EAAa,IARlCD,EAJAC,EA7Mf,GAAMnxC,GAAe/b,EAAQ,UAAU+b,aACjCgoC,EAAc/jD,EAAQ,mBAEtBqD,EAAQrD,EAAQ,WAwCtBqD,GAAMmZ,SAASknC,EAAY3nC,GAW3B2nC,EAAWp/C,UAAU8oD,mBAAqB,SAASn4C,EAAO9M,GACtD,GAAwB,kBAApB8M,EAAMwC,UAAV,CAGApW,KAAK8oB,OAAO6b,OAAS/wB,CAErB,IAAMgxB,GAAgB5kC,KAAK4V,UAC3B5V,MAAK4V,WAAahC,EAAMw1C,wBAAwBxzC,UAEhD,IAAMo2C,GAAUhsD,KAAKuhB,IACrBvhB,MAAKuhB,KAAOoqC,EAAqB3rD,KAAM4T,EAAO9M,GAC9C9G,KAAKwrD,eAAiB53C,EAAMw1C,wBAAwBxjC,aAAe5lB,KAAK2H,OACpEi9B,IAAkB5kC,KAAK4V,aACvB5V,KAAK0rD,sBACL1rD,KAAKS,KAAK,wBAAyBmT,EAAO5T,KAAM4kC,IAEhDonB,IAAYhsD,KAAKuhB,OACjBvhB,KAAK0rD,sBACL1rD,KAAKS,KAAK,kBAAmBmT,EAAO5T,KAAMgsD,MAWlD3J,EAAWp/C,UAAUgpD,mBAAqB,SAASC,GAC/C,GAAkC,wBAA9BA,EAAgB91C,UAApB,CAIA,GAAM+1C,GAAYD,EAAgB9C,wBAE9BgD,EAAWD,EAAUrB,eAAiB,CAC1C9oD,GAAMyM,QAAQzM,EAAMyV,OAAO00C,EAAUhqC,OAAQ,SAASkqC,GAClDD,EAAWnlC,KAAKC,IAAIklC,EAAUC,IAElC,IAAMC,GAAgBtsD,KAAKkiB,WACrBqqC,EAAoBvsD,KAAKyrD,cAE3BU,GAAUhqC,WAA0ClhB,KAAjCkrD,EAAUhqC,MAAMniB,KAAK2H,QACxC3H,KAAKkiB,WAAaiqC,EAAUhqC,MAAMniB,KAAK2H,YACJ1G,KAA5BkrD,EAAUrB,cACjB9qD,KAAKkiB,WAAaiqC,EAAUrB,cAE5B9qD,KAAKkiB,WAAa,EAEtBliB,KAAKyrD,eAAiB,EAClBW,EAAW,IACXpsD,KAAKyrD,eAAoC,IAAlBzrD,KAAKkiB,WAAoBkqC,GAKhDE,IAAkBtsD,KAAKkiB,YAAcqqC,IAAsBvsD,KAAKyrD,iBAChEzrD,KAAK0rD,sBACL1rD,KAAKS,KAAK,wBAAyByrD,EAAiBlsD,SAU5DqiD,EAAWp/C,UAAUupD,eAAiB,SAAS54C,GAC3C,GAAwB,aAApBA,EAAMwC,UAAV,CAGA,GAAMq2C,GAAYzsD,KAAKskB,MACvBtkB,MAAKskB,QAAS,CACd,IAAMooC,GAAa94C,EAAMiD,aAAa3N,QACjClH,GAAMuoC,QAAQmiB,MAIsB,IAArCA,EAAWr2C,QAAQrW,KAAK2H,UACxB3H,KAAKskB,QAAS,GAEdmoC,IAAczsD,KAAKskB,SACnBtkB,KAAK0rD,sBACL1rD,KAAKS,KAAK,oBAAqBmT,EAAO5T,UAO9CqiD,EAAWp/C,UAAUyoD,oBAAsB,WACvC1rD,KAAK2sD,UAAYppD,KAAKyjB,OAS1Bq7B,EAAWp/C,UAAU2pD,oBAAsB,WACvC,MAAO5sD,MAAK2sD,WAqBhBtK,EAAWp/C,UAAU4pD,aACb,SAAS3qD,EAAS+jB,EAAOC,EAAQC,EAAc2mC,EAAc1mC,GAIjE,OAHqBnlB,KAAjB6rD,IACAA,GAAe,IAEd9sD,KAAK8oB,OAAO6b,SAAWmoB,EACxB,MAAO,KAEX,IAAMC,GAAS/sD,KAAK8oB,OAAO6b,OAAS3kC,KAAK8oB,OAAO6b,OAAO9tB,aAAaiP,WAAa,KAC3EknC,EAAUtK,EAAYr8B,iBACxBnkB,EAAS6qD,EAAQ9mC,EAAOC,EAAQC,EAAcC,EAElD,OAAI4mC,KAEOF,EACApK,EAAYxxB,gBACfhvB,EAASlC,KAAK2H,OAAQse,EAAOC,GAG9B,OA4BX7mB,EAAOJ,QAAUojD,uECrOjB,gEAoBA,QAASC,GAAUv7C,GACf/G,KAAK+G,OAASA,EACd/G,KAAKitD,WAGLjtD,KAAK8oB,UAGL9oB,KAAKonB,gBAAkB,KAEvBpnB,KAAKktD,cAGLltD,KAAK0rD,sBACL1rD,KAAKmtD,yBACLntD,KAAKotD,0BACLptD,KAAKqtD,kBA2XT,QAASC,GAA4BxmD,EAAWymD,GAC5C,GAAKA,EAAY12C,aAAa22C,mBAA9B,CAGA,GAAMrnD,IAASonD,EAAY12C,aAAa22C,mBAAmBC,YAActnD,KACzE,IAAKA,EAAL,CAGuBW,EAAUoY,eAC7B,4BAA6B/Y,KAKjCW,EAAUumD,eAAelnD,GAASonD,KAGtC,QAASG,GAAwB5mD,EAAWa,EAAQikD,GAChD,GAAMI,GAAUllD,EAAUsmD,uBAAuBzlD,EAEjD,UADOb,GAAUsmD,uBAAuBzlD,GACpCqkD,EAAS,CAMT,IAAK,GADC2B,GAAkB7mD,EAAUqmD,sBAAsBnB,OAC/CptD,EAAI,EAAGA,EAAI+uD,EAAgBxuD,OAAQP,IACpC+uD,EAAgB/uD,KAAO+I,IAEvBgmD,EAAgBrV,OAAO15C,EAAG,GAC1BA,IAGRkI,GAAUqmD,sBAAsBnB,GAAW2B,EAG/C7mD,EAAUsmD,uBAAuBzlD,GAAUikD,EACtC9kD,EAAUqmD,sBAAsBvB,KACjC9kD,EAAUqmD,sBAAsBvB,OAEpC9kD,EAAUqmD,sBAAsBvB,GAAah1C,KAAKjP,wGAnchD+S,EAAe/b,EAAQ,UAAU+b,aAEjC1Y,EAAQrD,EAAQ,YAChB0jD,EAAa1jD,EAAQ,gBA+B3BqD,GAAMmZ,SAASmnC,EAAW5nC,GAM1B4nC,EAAUr/C,UAAU2qD,WAAa,WAC7B,MAAO5rD,GAAMyV,OAAOzX,KAAKitD,UAQ7B3K,EAAUr/C,UAAUovC,UAAY,SAAS1qC,GACrC,MAAO3H,MAAKitD,QAAQtlD,IAAW,MAYnC26C,EAAUr/C,UAAUqlD,kBAAoB,SAAS3gD,GAC7C,MAAO3H,MAAKktD,WAAWvlD,IAAW,MAYtC26C,EAAUr/C,UAAUic,eAAiB,SAAS5V,EAAWC,GACrD,IAAKvJ,KAAK8oB,OAAOxf,GAEb,WAAoBrI,KAAbsI,KAA8B,IAEzC,QAAiBtI,KAAbsI,EACA,MAAOvH,GAAMyV,OAAOzX,KAAK8oB,OAAOxf,GAEpC,IAAMsK,GAAQ5T,KAAK8oB,OAAOxf,GAAWC,EACrC,OAAOqK,IAAgB,MAa3B0uC,EAAUr/C,UAAUglD,eAAiB,SAASH,GAC1C,GAAMz2C,GAAOrR,IACbA,MAAK0rD,sBAGL1pD,EAAMyM,QAAQq5C,EAAa,SAASl0C,GAC5BA,EAAMlC,cAAgBL,EAAKtK,QAG1B6M,EAAMyB,gBAI0BpU,KAAjCoQ,EAAKyX,OAAOlV,EAAMwC,aAClB/E,EAAKyX,OAAOlV,EAAMwC,eAEtB/E,EAAKyX,OAAOlV,EAAMwC,WAAWxC,EAAMwB,eAAiBxB,EAC5B,kBAApBA,EAAMwC,YACNs3C,EACIr8C,EAAMuC,EAAMwB,cAAexB,EAAMiD,aAAa+O,aAElD0nC,EAA4Bj8C,EAAMuC,IAEtCvC,EAAK5Q,KAAK,mBAAoBmT,EAAOvC,MAOzCrP,EAAMyM,QAAQq5C,EAAa,SAASl0C,GAChC,GAAIA,EAAMlC,cAAgBL,EAAKtK,QAG1B6M,EAAMyB,UAIX,GAAwB,kBAApBzB,EAAMwC,UAA+B,CACrC,GAAMzO,GAASiM,EAAMwB,aAKiB,WAAlCxB,EAAMiD,aAAajB,YACe,QAAlChC,EAAMiD,aAAajB,aACnBhC,EAAMiD,aAAaiP,WACflS,EAAMiD,aAAaiP,YACnBlS,EAAMq1C,iBAAiBnjC,WAC3BlS,EAAMiD,aAAa+O,YACfhS,EAAMiD,aAAa+O,aACnBhS,EAAMq1C,iBAAiBrjC,YAG/B,IAAI+e,GAAStzB,EAAK47C,QAAQtlD,EACrBg9B,KACDA,EAAS,GAAI0d,GAAWzuC,EAAMlC,YAAa/J,GAC3C0J,EAAK5Q,KAAK,sBAAuBmT,EAAOvC,EAAMszB,GAOlD,IAAMkpB,GAAW,GAAIxL,GAAWzuC,EAAMlC,YAAa/J,EACnD3F,GAAMyM,SAASk2B,EAAQkpB,GAAW,SAASC,GACvCA,EAAW/B,mBAAmBn4C,EAAOvC,EAErC,IAAM08C,GAAc18C,EAAK6N,eAAe,sBAAuB,GAC3D6uC,IACAD,EAAW7B,mBAAmB8B,KAItC18C,EAAK67C,WAAWvlD,GAAUkmD,EAC1Bx8C,EAAK47C,QAAQtlD,GAAUg9B,EACvBtzB,EAAK5Q,KAAK,oBAAqBmT,EAAOvC,EAAMszB,OACzC,IAAwB,wBAApB/wB,EAAMwC,UAAqC,CAClD,GAAM62C,GAAUjrD,EAAMyV,OAAOpG,EAAK47C,QAClCjrD,GAAMyM,QAAQw+C,EAAS,SAAStoB,GAC5BA,EAAOsnB,mBAAmBr4C,GAC1BvC,EAAK5Q,KAAK,oBAAqBmT,EAAOvC,EAAMszB,IAJE,IAAA7jC,IAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KASlD,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,UAAqB,EAAA2K,EAAA3K,SAAYsR,EAAK67C,eAAtCpsD,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAAmD,CAAA,GAAxC2jC,GAAwCvjC,EAAAK,MACzCysD,EAAc38C,EAAK67C,WAAWzoB,GAC9BwpB,EAAc,GAAI5L,GAAWzuC,EAAMlC,YAAa+yB,EACtDwpB,GAAYlC,mBAAmBiC,EAAYllC,OAAO6b,OAAQtzB,GAC1D48C,EAAYhC,mBAAmBr4C,GAC/BvC,EAAK67C,WAAWzoB,GAAUwpB,GAdoB,MAAArsD,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,SAwB9DshD,EAAUr/C,UAAUupD,eAAiB,SAAS54C,GAC1C5R,EAAMyM,QAAQzM,EAAMyV,OAAOzX,KAAKitD,SAAU,SAAStoB,GAC/CA,EAAO6nB,eAAe54C,MAU9B0uC,EAAUr/C,UAAUirD,0BAA4B,SAAS/nD,GACrD,MAAOnG,MAAKqtD,eAAelnD,IAAU,MAMzCm8C,EAAUr/C,UAAUyoD,oBAAsB,WACtC1rD,KAAK2sD,UAAYppD,KAAKyjB,OAQ1Bs7B,EAAUr/C,UAAU2pD,oBAAsB,WACtC,MAAO5sD,MAAK2sD,WAQhBrK,EAAUr/C,UAAU6oD,0BAA4B,SAASF,GACrD,MAAO5rD,MAAKmtD,sBAAsBvB,QAUtCtJ,EAAUr/C,UAAUkrD,yBAA2B,SAASnG,EAASrgD,GAC7D,GAAMg9B,GAAS3kC,KAAKqyC,UAAU1qC,EAC9B,UAAKg9B,GAAgC,UAAtBA,EAAO/uB,eAElBoyC,EAAQr2C,SAAUq2C,EAAQjX,eAC1BiX,EAAQjxC,cAAgBpP,GAErB3H,KAAKouD,4BAA4B,SAAUzpB,EAAOziB,eAS7DogC,EAAUr/C,UAAUmrD,4BAA8B,SAASvqB,EAAQ3hB,GAC/D,GAAMmsC,GAAmBruD,KAAKkf,eAAe,sBAAuB,IAEhEovC,IACAD,KACAC,EAAcD,EAAiBx3C,aAGnC,IAAI03C,GAAgB,EAKpB,YAJ4BttD,KAAxBqtD,EAAYzqB,KACZ0qB,EAAgBD,EAAYzqB,IAGzB3hB,GAAcqsC,GASzBjM,EAAUr/C,UAAUurD,eAAiB,SAAS7mD,GAC1C,MAAO3H,MAAKyuD,oBAAoB,iBAAkB9mD,GAAQ,IAY9D26C,EAAUr/C,UAAUyrD,aAAe,SAASplD,EAAW3B,GACnD,MAAO3H,MAAKyuD,oBAAoBnlD,EAAW3B,GAAQ,IAYvD26C,EAAUr/C,UAAU0rD,wBAA0B,SAASC,EAAgBC,GACnE,OAAIA,EAAIt2C,WAGDvY,KAAK8uD,kBAAkBF,EAAgBC,EAAI19C,YAAYxJ,SAYlE26C,EAAUr/C,UAAU6rD,kBAAoB,SAASF,EAAgBjnD,GAC7D,MAAO3H,MAAKyuD,oBAAoBG,EAAgBjnD,GAAQ,IAe5D26C,EAAUr/C,UAAUwrD,oBAAsB,SAASnlD,EAAW3B,EAAQuP,GAClE,GAAMytB,GAAS3kC,KAAKqyC,UAAU1qC,EAC9B,KAAKg9B,GAA+B,SAArBA,EAAO/uB,WAClB,OAAO,CAGX,IAAMm5C,GAAqB/uD,KAAKkf,eAAe,sBAAuB,IAElE8vC,MAAA,GACAC,KAEApE,EAAgB,EAChBF,EAAiB,CACjBoE,KACAC,EAAeD,EAAmBl4C,aAClCo4C,EAAgBD,EAAalmC,WAGzB+hC,MAD+B5pD,KAA/B+tD,EAAanE,cACGmE,EAAanE,cAEb,OAEgB5pD,KAAhC+tD,EAAarE,iBACbA,EAAiBqE,EAAarE,gBAItC,IAAIuE,GAAiBh4C,EAAQ2zC,EAAgBF,CAI7C,YAHiC1pD,KAA7BguD,EAAc3lD,KACd4lD,EAAiBD,EAAc3lD,IAE5Bq7B,EAAOziB,YAAcgtC,GAWhC5M,EAAUr/C,UAAUksD,sBAAwB,SAASC,EAAeznD,GAChE,GAAMg9B,GAAS3kC,KAAKqyC,UAAU1qC,EAC9B,KAAKg9B,EACD,OAAO,CAGX,IAAM0pB,GAAmBruD,KAAKkf,eAAe,sBAAuB,IAEhEmwC,EAAa,EAUjB,OARIhB,IACAA,EAAiBx3C,cACjBw3C,EAAiBx3C,aAAakT,eAC9BskC,EAAiBx3C,aAAakT,cAAcqlC,KAE5CC,EAAahB,EAAiBx3C,aAAakT,cAAcqlC,IAGtDzqB,EAAOziB,YAAcmtC,GAMhChwD,EAAOJ,QAAUqjD,qJC5ZjB,YAkBA,SAASgN,GAAYvoD,EAAQkF,GACzBjM,KAAK+G,OAASA,EACd/G,KAAKiM,KAAOA,EAMhB5M,EAAOJ,QAAUqwD,2BC1BjB,gEAgBA,QAASC,GAAkB5nD,EAAQiM,EAAO2P,GAItC,GAAMisC,IACFzmD,WACAxD,KAAM,YACNuF,QAAS8I,EAAMlC,YAOnB,OALA89C,GAAYzmD,QAAQ6K,EAAM6P,YAC1B+rC,EAAYzmD,QAAQ6K,EAAM6P,SAASF,MACnCisC,EAAYzmD,QAAQ6K,EAAM6P,SAASF,GAAa5b,IAC5Coc,GAAInQ,EAAM21B,SAEP,GAAI/vB,GAAYg2C,GA2D3B,QAASrN,GAAKp7C,EAAQhF,GAMlB,GALAA,EAAOA,MACPA,EAAK0tD,qBAAuB1tD,EAAK0tD,sBAAwB,gBAEzDzvD,KAAK+Q,UAAY,GAAAC,GAAAjR,QAAcC,OAE2C,KAArE,gBAAiB,YAAYqW,QAAQtU,EAAK0tD,sBAC3C,KAAM,IAAI3wD,OACN,iFACuBiD,EAAK0tD,qBAAuB,IAI3DzvD,MAAK+G,OAASA,EACd/G,KAAKuhB,KAAOxa,EACZ/G,KAAK0vD,QAIL1vD,KAAK2vD,eAGL3vD,KAAK4vD,QAAU,KACf5vD,KAAK6vD,aAAe9tD,EAAK8tD,aACzB7vD,KAAK8vD,MAAQ/tD,EACb/B,KAAK+vD,eAKL/vD,KAAKgwD,aAQLhwD,KAAKiwD,0BAQLjwD,KAAKkwD,iBAELlwD,KAAKmwD,uBAILnwD,KAAKowD,eAAiB,GAAIhO,GAAiBpiD,KAAM+B,IACjD/B,KAAK+Q,UAAU0I,OAAOzZ,KAAKooD,4BACnB,gBAAiB,uBAEzBpoD,KAAKqwD,6BAGLrwD,KAAKswD,yBAIkC,YAAnCtwD,KAAK8vD,MAAML,uBACXzvD,KAAKuwD,sBAGTvwD,KAAKwwD,6BAA8B,EAg+BvC,QAASC,GAAkBj/C,EAAM7J,EAAQ+oD,GACrC,IAAKA,EAAqB,CAGtB,GAAMC,GAAYn/C,EAAKyN,aAAaC,eAAe,cAAe,GAClE,IAAIyxC,GAAaA,EAAU95C,cAAgB85C,EAAU95C,aAAa0K,KAC9D,MAAOovC,GAAU95C,aAAa0K,KAItC,GAAI3W,GAAQ4G,EAAKo/C,mBAEjB,KAAKhmD,EAAO,CACR,GAAMogD,GAAUx5C,EAAKq/C,YAEjB7F,GAAQ7rD,SACRyL,EAAQogD,EAAQ,IAGxB,GAAIpgD,EACA,MAAOA,EAIX,IAAMkmD,GAAe9uD,EAAMmoB,OAAO3Y,EAAKyN,aAAa2uC,aAAc,SAASpd,GACvE,MACIA,GAAE7oC,SAAWA,GAA2B,UAAjB6oC,EAAE56B,YAA2C,QAAjB46B,EAAE56B,aAGvDm7C,EAAa/uD,EAAMmoB,OAAO3Y,EAAKyN,aAAa2uC,aAAc,SAASpd,GACrE,MAAyB,UAAjBA,EAAE56B,aAERo7C,EAAqBhvD,EAAMmoB,OAAO3Y,EAAKyN,aAAa2uC,aAAc,SAASpd,GAC7E,MAAQA,GAAE7oC,QAAUA,IAElBspD,EACDD,EAAmB7xD,QAAU6xD,EAAmB,GAAGloC,OAChDkoC,EAAmB,GAAGloC,OAAO6b,OAAO/wB,UAAQ3S,EAIpD,IAAIgwD,GAAqD,UAApCA,EAAcloD,QAAQ6M,WACvC,MAAIpE,GAAKyN,aAAaozB,UAAU4e,EAAcpnB,QAEnCr4B,EAAKyN,aAAaozB,UACrB4e,EAAcpnB,QAChBtoB,KACKwvC,EAAW,GAAGjoC,OAAO6b,OAGrBssB,EAAcpnB,OAEd,aAKf,IAA4B,IAAxBinB,EAAa3xD,OAAc,CAC3B,GAA0B,IAAtB4xD,EAAW5xD,OAAc,CAGzB,GAAI4xD,EAAW,GAAGppD,SAAWA,EAAQ,CACjC,GAAMupD,GACF1/C,EAAKyN,aAAaC,eAAe,4BACrC,IAAIgyC,GAAqBA,EAAkB/xD,OAAS,EAAG,CACnD,GAAIoiB,GAAO,YACA2vC,EAAkB,GAAGr6C,aAAas6C,YAU7C,OATID,GAAkB/xD,OAAS,IACK,GAA5B+xD,EAAkB/xD,OAClBoiB,GAAQ,QACA2vC,EAAkB,GAAGr6C,aAAas6C,aAE1C5vC,GAAQ,QACA2vC,EAAkB/xD,OAAS,WAGpCoiB,EAEP,MAAO,aAGX,MAAOwvC,GAAW,GAAGxvC,KAIzB,MAAO,aAER,MAA4B,KAAxBuvC,EAAa3xD,OACb2xD,EAAa,GAAGvvC,KACQ,IAAxBuvC,EAAa3xD,OAEhB2xD,EAAa,GAAGvvC,KAAO,QAAUuvC,EAAa,GAAGvvC,KAIjDuvC,EAAa,GAAGvvC,KAAO,SAAWuvC,EAAa3xD,OAAS,GAAK,gEA7sCzEqb,EAAA7b,EAAA,uBAVM+b,EAAe/b,EAAQ,UAAU+b,aAEjC9I,EAAcjT,EAAQ,WAAWiT,YACjC09C,EAAc3wD,EAAQ,kBACtB6a,EAAc7a,EAAQ,WAAW6a,YACjCxX,EAAQrD,EAAQ,YAChB+jD,EAAc/jD,EAAQ,mBACtBic,EAAgBjc,EAAQ,oBACxByjD,EAAmBzjD,EAAQ,uBAkJjCqD,GAAMmZ,SAASgnC,EAAMznC,GAUrBynC,EAAKl/C,UAAUuhD,iBAAmB,WAC9B,GAAwC,aAApCxkD,KAAK8vD,MAAML,qBACX,KAAM,IAAI3wD,OACN,gEACIkB,KAAK8vD,MAAML,qBAGvB,OAAOzvD,MAAKuwD,mBAQhBpO,EAAKl/C,UAAU0kB,gBAAkB,WAC7B,MAAO3nB,MAAKooD,2BAA2BzgC,mBAe3Cw6B,EAAKl/C,UAAUunB,kBAAoB,SAASs6B,EAAqBC,GAC7D,IAAK,GAAInmD,GAAI,EAAGA,EAAIoB,KAAKowD,cAAcjxD,OAAQP,IAC3CoB,KAAKowD,cAAcxxD,GAAG4rB,kBAClBs6B,EAAqBC,EAI7B/kD,MAAKqwD,8BAQTlO,EAAKl/C,UAAUotD,2BAA6B,WAKxCrwD,KAAKgpB,SAAWhpB,KAAK2nB,kBAAkB+9B,YACvC1lD,KAAKmnB,SAAWnnB,KAAK2nB,kBACAwB,SAASvO,EAAc8O,WAC5C1pB,KAAKif,aAAejf,KAAK2nB,kBACAwB,SAASvO,EAAcwO,WAOpD+4B,EAAKl/C,UAAUmuD,gBAAkB,WAC7B,MAAOpxD,MAAKowD,eAOhBjO,EAAKl/C,UAAUmlD,yBAA2B,WACtC,MAAOpoD,MAAKowD,cAAc,IAU9BjO,EAAKl/C,UAAU2lB,oBAAsB,SAAS/e,GAC1C,MAAO7J,MAAKooD,2BAA2Bx/B,oBAAoB/e,IAQ/Ds4C,EAAKl/C,UAAUgmB,YAAc,WACzB,MAAOjpB,MAAKooD,2BAA2Bn/B,eAS3Ck5B,EAAKl/C,UAAUsiD,cAAgB,SAAS17C,GACpC,MAAO7J,MAAKooD,2BAA2B7C,cAAc17C,IASzDs4C,EAAKl/C,UAAUouD,2BAA6B,SAAS9rD,GAEjD,MADAA,GAAOA,GAAQ,QACRvF,KAAKmwD,oBAAoB5qD,IAQpC48C,EAAKl/C,UAAUquD,2BAA6B,SAAS/rD,EAAMyoB,GACvDhuB,KAAKmwD,oBAAoB5qD,GAAQyoB,GAQrCm0B,EAAKl/C,UAAUsuD,8BAAgC,SAAShwD,GACpDvB,KAAKwwD,4BAA8BjvD,GAQvC4gD,EAAKl/C,UAAUgmC,8BAAgC,WAC3C,MAAOjpC,MAAKwwD,6BAehBrO,EAAKl/C,UAAU4pD,aAAe,SAAS3qD,EAAS+jB,EAAOC,EAAQC,EACxB2mC,GACnC,GAAM0E,GAAkBxxD,KAAKif,aAAaC,eAAe,gBAAiB,GAI1E,QAHqBje,KAAjB6rD,IACAA,GAAe,IAEd0E,IAAoB1E,EACrB,MAAO,KAGX,IAAM2E,GAAUD,EAAkBA,EAAgB36C,aAAa8D,IAAM,IACrE,OAAI82C,GACO/O,EAAYr8B,iBACfnkB,EAASuvD,EAASxrC,EAAOC,EAAQC,GAE9B2mC,EACApK,EAAYxxB,gBACfhvB,EAASlC,KAAK+G,OAAQkf,EAAOC,GAI9B,MASXi8B,EAAKl/C,UAAU4tD,WAAa,WACxB,GAAMa,MAEAC,EAAe3xD,KAAKif,aAAaC,eAAe,iBACtD,IAAIyyC,EACA,IAAK,GAAI/yD,GAAI,EAAGA,EAAI+yD,EAAaxyD,SAAUP,EAAG,CAC1C,GAAMgzD,GAAcD,EAAa/yD,EAC7BoD,GAAMuoC,QAAQqnB,EAAY/6C,aAAam0C,UACvCzqD,MAAM0C,UAAU2T,KAAKlW,MACjBgxD,EAAeE,EAAY/6C,aAAam0C,SAKxD,MAAO0G,IASXvP,EAAKl/C,UAAU2tD,kBAAoB,WAC/B,GAAMiB,GAAiB7xD,KAAKif,aAAaC,eAAe,yBAA0B,GAClF,OAAI2yC,GACOA,EAAeh7C,aAAajM,MAEhC,MAsBXu3C,EAAKl/C,UAAUykB,oBAAsB,SAASoB,EAAQ68B,EACR38B,EAAU5B,GACpD4B,EAASS,iBAAiB/B,oBACtBoB,EAAQ68B,EACR38B,EAAU5B,IASjB+6B,EAAKl/C,UAAUovC,UAAY,SAAS1qC,GACjC,GAAMg9B,GAAS3kC,KAAKif,aAAaguC,QAAQtlD,EACzC,OAAKg9B,IACM,MASdwd,EAAKl/C,UAAU8lC,iBAAmB,WAC/B,MAAO/oC,MAAK8xD,yBAAyB,SAQxC3P,EAAKl/C,UAAU6uD,yBAA2B,SAASl8C,GAChD,MAAO5T,GAAMmoB,OAAOnqB,KAAKif,aAAa2uC,aAAc,SAASpd,GACzD,MAAOA,GAAE56B,aAAeA,KAW/BusC,EAAKl/C,UAAU8uD,mBAAqB,SAASpqD,GAC1C,MAAO8oD,GAAkBzwD,KAAM2H,GAAQ,IAU1Cw6C,EAAKl/C,UAAUud,mBAAqB,SAAS7Y,EAAQiO,GAClD,GAAM+uB,GAAS3kC,KAAKqyC,UAAU1qC,EAC9B,SAAKg9B,GAGEA,EAAO/uB,aAAeA,GAQjCusC,EAAKl/C,UAAU+uD,+BAAiC,SAAS7nC,GACrD,GAAInqB,KAAKswD,sBAAsBnmC,EAAOuE,UAClC,MAAO1uB,MAAKswD,sBAAsBnmC,EAAOuE,SAE7C,IAAM3sB,IAAO,EAAAoqB,EAAApsB,UAAgBoqB,OAAQA,GAAUnqB,KAAK8vD,OAC9CnnC,EAAc,GAAIy5B,GAAiBpiD,KAAM+B,EAC/C/B,MAAK+Q,UAAU0I,OAAOkP,GAAc,gBAAiB,uBACrD3oB,KAAKswD,sBAAsBnmC,EAAOuE,UAAY/F,EAC9C3oB,KAAKowD,cAAcx5C,KAAK+R,EASxB,IAAMspC,GAAyBjyD,KAAK2nB,iBAEpCsqC,GAAuBvM,YAAYj3C,QAAQ,SAASmF,GAChD+U,EAAYw9B,aAAavyC,IAK7B,KADA,GAAIoV,GAAWipC,EACRjpC,EAASg9B,wBAAwBprC,EAAc8O,YAClDV,EAAWA,EAASg9B,wBAAwBprC,EAAc8O,UAgB9D,OAbAf,GAAYhB,kBAAkBuC,mBAC1BlB,EAASW,mBAAmB/O,EAAc8O,WAC1C9O,EAAc8O,WAWXf,GAQXw5B,EAAKl/C,UAAUivD,0BAA4B,SAAS/nC,GAChD,GAAMxB,GAAc3oB,KAAKswD,sBAAsBnmC,EAAOuE,gBAC/C1uB,MAAKswD,sBAAsBnmC,EAAOuE,SACzC,IAAM9vB,GAAIoB,KAAKowD,cAAc/5C,QAAQsS,EACjC/pB,IAAK,GACLoB,KAAKowD,cAAc9X,OAAO15C,EAAG,IAarCujD,EAAKl/C,UAAUkvD,cAAgB,SAASv+C,EAAOwyC,GAC3C,GAAIxnD,OAAA,EACJ,IAAwB,qBAApBgV,EAAMwC,UAAkC,CACxC,GAAMg8C,GAAWx+C,EAAMA,MAAMy+C,QAGvBC,EAAgBtyD,KAAKooD,2BAA2B7C,cAAc6M,EAChEE,KACAA,EAAczI,aAAaj2C,GAC3B5T,KAAKS,KAAK,iBAAkBmT,EAAO5T,OAgB3C,GAAI4T,EAAMs1C,cAAcqJ,eAAgB,CACpC,GAAMC,GAAgBxyD,KAAK+vD,YAAYn8C,EAAMs1C,cAAcqJ,eAC3D,IAAIC,EAGA,WADAxyD,MAAKyyD,kBAAkB7+C,EAAO4+C,GAMtC,IAAK5zD,EAAI,EAAGA,EAAIoB,KAAKowD,cAAcjxD,OAAQP,IACvCoB,KAAKowD,cAAcxxD,GAAGunD,aAAavyC,EAAOwyC,EAM1CxyC,GAAMi2B,QACN7pC,KAAK0yD,WAAWnD,EACZ37C,EAAMi2B,OAAOliC,OAAQiM,EAAO,WAC7B,IA6BXuuC,EAAKl/C,UAAUuf,gBAAkB,SAAS5O,EAAOxD,GAC7C,GAAIwD,EAAMjC,SAAWC,EAAYC,QAC7B,KAAM,IAAI/S,OAAM,kDACA8U,EAAMjC,OAG1B,IAAI3R,KAAK+vD,YAAY3/C,GACjB,KAAM,IAAItR,OAAM,uDACAsR,EAcpB,IARAwK,EAAc0rC,iBACV1yC,EACA5T,KAAK2nB,kBAAkBwB,SAASvO,EAAcwO,WAC9C,GAGJppB,KAAK+vD,YAAY3/C,GAASwD,EAEa,YAAnC5T,KAAK8vD,MAAML,qBACXzvD,KAAKuwD,kBAAkB35C,KAAKhD,OAE5B,KAAK,GAAIhV,GAAI,EAAGA,EAAIoB,KAAKowD,cAAcjxD,OAAQP,IAAK,CAChD,GAAM+pB,GAAc3oB,KAAKowD,cAAcxxD,EACnC+pB,GAAYyB,YACRpqB,KAAKqkD,QAAQ5J,oBAAoB7mC,IAAQzU,QACzCwpB,EAAYu9B,mBAAmBtyC,EAC3B+U,EAAYhB,mBAAmB,GAGvCgB,EAAYu9B,mBAAmBtyC,EAC3B+U,EAAYhB,mBAAmB,GAK/C3nB,KAAKS,KAAK,wBAAyBmT,EAAO5T,KAAM,KAAM,OAiB1DmiD,EAAKl/C,UAAUwvD,kBAAoB,SAASE,EAAarwC,GACrD,GAAMqiC,GAAariC,EAAWmB,QACxBmhC,EAAa+N,EAAYlvC,QACzBmvC,EAAYtwC,EAAW3Q,aAGtB3R,MAAK+vD,YAAY4C,EAAYJ,gBAGhCvyD,KAAKuwD,mBACLvuD,EAAM6wD,cACF7yD,KAAKuwD,kBACL,SAASl4C,GACL,MAAOA,GAAGoL,SAAWkhC,IACtB,GAMXriC,EAAWokC,iBAAiBiM,EAAY/+C,MAExC,KAAK,GAAIhV,GAAI,EAAGA,EAAIoB,KAAKowD,cAAcjxD,OAAQP,IAAK,CAC5BoB,KAAKowD,cAAcxxD,GAG3B8nD,iBAAiBpkC,EAAYqiC,EAAYC,GAGzD5kD,KAAKS,KAAK,wBAAyB6hB,EAAYtiB,KACrC2kD,EAAYiO,GAK1B,IAAME,KAENA,GAAoBlhD,EAAYqC,aAC5BrC,EAAYC,QACZD,EAAYgD,UAGhBk+C,EAAoBlhD,EAAYC,UAC5BD,EAAYqC,WACZrC,EAAYwC,OACZxC,EAAYgD,SACZhD,EAAY2C,MAGhBu+C,EAAoBlhD,EAAYwC,SAC3BxC,EAAYC,QAASD,EAAYyP,WAEtCyxC,EAAoBlhD,EAAY2C,SAGhCu+C,EAAoBlhD,EAAYgD,WAC3BhD,EAAYC,QAASD,EAAYwC,OAAQxC,EAAYyP,WAE1DyxC,EAAoBlhD,EAAYyP,cAehC8gC,EAAKl/C,UAAUqR,mBAAqB,SAASV,EAAOqB,EAAW2vC,GAI3D,GAHAnwC,QAAQe,IAAR,kCAA8CP,EAA9C,OAA8DrB,EAAMlC,aAGhEuD,GAAarD,EAAY2C,OAASqwC,EAClC,KAAM,IAAI9lD,OAAM,kEAKpB,IAAImW,GAAarD,EAAY2C,KAAM,CAE/B,GADiBvU,KAAKooD,2BAA2B3D,kBAAkBG,GAI/D,OAIR,GAAMgO,GAAYh/C,EAAMjC,OAClBgzC,EAAa/wC,EAAM6P,OAEzB,KAAKmvC,EACD,KAAM,IAAI9zD,OAAM,yEAIpB,IAAMi0D,GAAUD,EAAoBF,EACpC,KAAKG,GAAWA,EAAQ18C,QAAQpB,GAAa,EACzC,KAAM,IAAInW,OAAM,kCAAoC8zD,EAAY,KAChD39C,EAKpB,IAFArB,EAAMjC,OAASsD,EAEXA,GAAarD,EAAY2C,KAAM,CAE/BX,EAAMA,MAAMY,SAAWowC,CAKvB,KAAK,GAAIhmD,GAAI,EAAGA,EAAIoB,KAAKowD,cAAcjxD,OAAQP,IAC3CoB,KAAKowD,cAAcxxD,GAAG8lD,eAAeC,EAAYC,OAE9C3vC,IAAarD,EAAYyP,YAE5BrhB,KAAKuwD,mBACLvuD,EAAM6wD,cACF7yD,KAAKuwD,kBACL,SAASl4C,GACL,MAAOA,GAAGoL,SAAWkhC,IACtB,GAGX3kD,KAAK2mD,YAAYhC,GAGrB3kD,MAAKS,KAAK,wBAAyBmT,EAAO5T,KAAM4T,EAAM6P,QAASmvC,IAoBnEzQ,EAAKl/C,UAAU+vD,cAAgB,SAASlqC,EAAQs9B,GAC5C,GAAIxnD,OAAA,EACJ,IAAIwnD,IAA2E,KAArD,UAAW,UAAU/vC,QAAQ+vC,GACnD,KAAM,IAAItnD,OAAM,yDAIpB,KAAKF,EAAI,EAAGA,EAAIoB,KAAKowD,cAAcjxD,OAAQP,IAAK,CAC5C,GAAMq0D,GAAejzD,KAAKowD,cAAcxxD,GAAG+oB,iBAC3C,IAAIsrC,EAAatpC,mBAAmB/O,EAAcwO,UAC9C,KAAM,IAAItqB,OACN,iBAAmBF,EAAI,mDACjBq0D,EAAatpC,mBAAmB/O,EAAcwO,UAAY,IAGxE,IAAI6pC,EAAajN,wBAAwBprC,EAAcwO,UACnD,KAAM,IAAItqB,OACN,iBAAmBF,EAAI,uDAMnC,IAAKA,EAAI,EAAGA,EAAIkqB,EAAO3pB,OAAQP,IACC,aAAxBkqB,EAAOlqB,GAAGwX,UACVpW,KAAKif,aAAautC,eAAe1jC,EAAOlqB,IACT,cAAxBkqB,EAAOlqB,GAAGwX,UACjBpW,KAAK0yD,WAAW5pC,EAAOlqB,IAOvBoB,KAAKmyD,cAAcrpC,EAAOlqB,GAAIwnD,IAS1CjE,EAAKl/C,UAAUiwD,aAAe,SAASC,GACnC,IAAK,GAAIv0D,GAAI,EAAGA,EAAIu0D,EAAUh0D,SAAUP,EACpCoB,KAAK2mD,YAAYwM,EAAUv0D,KAWnCujD,EAAKl/C,UAAU0jD,YAAc,SAAS98C,GAElC,IAAK,GADDupD,IAAa,EACRx0D,EAAI,EAAGA,EAAIoB,KAAKowD,cAAcjxD,OAAQP,IAAK,CAChCoB,KAAKowD,cAAcxxD,GAAG+nD,YAAY98C,KAE9CupD,GAAa,GAGrB,MAAOA,IAWXjR,EAAKl/C,UAAUowD,YAAc,SAAS1rD,GAGlC,GAAM0J,GAAOrR,KACPszD,EAAkBtzD,KAAKif,aAAaC,eACtC,gBAAiBvX,EAErB,IAAI2rD,GAA+D,WAA5CA,EAAgBz8C,aAAajB,WAAyB,CACzE,GAAM29C,GAAsBD,EAAgB1/C,MAAM4/C,qBAClDxxD,GAAMyM,QAAQ8kD,EAAqB,SAASE,GAClBpiD,EAAK4N,aAAaC,eACpCu0C,EAAcluD,KAAMkuD,EAAcnK,YAIlCj4C,EAAK4N,aAAagpC,gBAAgB,GAAIzuC,IAClCjU,KAAMkuD,EAAcluD,KACpB+jD,UAAWmK,EAAcnK,UACzBvgD,QAAS0qD,EAAc1qD,QACvByL,SAAU,QAAUjR,KAAKyjB,MACzBlc,QAASuG,EAAKtK,OACdiP,QAASrO,QAMzB,GAAMqkD,GAAUhsD,KAAKuhB,IACrBvhB,MAAKuhB,KAAOkvC,EAAkBzwD,KAAM2H,GACpC3H,KAAK4vD,QAAU,GAAIN,GAAYtvD,KAAK+G,QAChC2sD,MAAO1zD,KAAKuhB,OAGZyqC,IAAYhsD,KAAKuhB,MACjBvhB,KAAKS,KAAK,YAAaT,OAU/BmiD,EAAKl/C,UAAU0wD,iBAAmB,SAAS//C,GACvC,MAAO5T,MAAK4zD,oBAAoBhgD,GAAOuW,OAAO,SAAS0pC,GACnD,MAAwB,WAAjBA,EAAQtuD,OAChB4a,IAAI,SAAS0zC,GACZ,MAAOA,GAAQlsD,UAavBw6C,EAAKl/C,UAAU6wD,iBAAmB,SAASnsD,EAAQosD,GAC/C,GAAIC,GAAWh0D,KAAKgwD,SAKpB,OAJI+D,KACAC,EAAWh0D,KAAKkwD,mBAIOjvD,KAAvB+yD,EAAS,eACsB/yD,KAA/B+yD,EAAS,UAAUrsD,GAEZ,KAGJqsD,EAAS,UAAUrsD,GAAQkC,SAStCs4C,EAAKl/C,UAAU2wD,oBAAsB,SAAShgD,GAC1C,MAAO5T,MAAKiwD,uBAAuBr8C,EAAM6P,cAQ7C0+B,EAAKl/C,UAAUyvD,WAAa,SAAS9+C,EAAOqgD,OAW3BhzD,KAATgzD,IACAA,GAAO,GAENA,GACDj0D,KAAKk0D,wBAAwBtgD,EAAO5T,KAAKkwD,eAI7ClwD,KAAKk0D,wBAAwBtgD,EAAO5T,KAAKgwD,WACzChwD,KAAKiwD,uBAAyBjwD,KAAKm0D,mBAAmBn0D,KAAKgwD,WAI3DhwD,KAAKS,KAAK,eAAgBmT,EAAO5T,OAQrCmiD,EAAKl/C,UAAUixD,wBAA0B,SAAStgD,EAAOogD,GACrD,GAAM3iD,GAAOrR,IACbgC,GAAMsd,KAAK1L,EAAMiD,cAAcpI,QAAQ,SAAS5E,GAC5C7H,EAAMsd,KAAK1L,EAAMiD,aAAahN,IAAU4E,QAAQ,SAAS8U,GACrDvhB,EAAMsd,KAAK1L,EAAMiD,aAAahN,GAAS0Z,IAAc9U,QACrD,SAAS9G,GACL,GAAMksD,GAAUjgD,EAAMiD,aAAahN,GAAS0Z,GAAa5b,EAEpDqsD,GAASzwC,KACVywC,EAASzwC,MAGb,IAAM6wC,GAAkBJ,EAASzwC,GAAa5b,EAE9C,IAAKysD,EAEE,CAKH,GAAMC,GAAWhjD,EAAK+2C,2BAA2BvB,qBAC7CuN,EAAgBvqD,QAASA,EAC7B,IAAiB,OAAbwqD,GAAqBA,GAAY,EACjC,WATJL,GAASzwC,GAAa5b,KAa1BqsD,GAASzwC,GAAa5b,IAClBkC,QAASA,EACT5E,KAAM4uD,UAY1B1R,EAAKl/C,UAAUkxD,mBAAqB,SAASH,GACzC,GAAMM,KAcN,OAbAtyD,GAAMsd,KAAK00C,GAAUvlD,QAAQ,SAAS8U,GAClCvhB,EAAMsd,KAAK00C,EAASzwC,IAAc9U,QAAQ,SAAS9G,GAC/C,GAAMksD,GAAUG,EAASzwC,GAAa5b,EACjC2sD,GAAsBT,EAAQhqD,WAC/ByqD,EAAsBT,EAAQhqD,aAElCyqD,EAAsBT,EAAQhqD,SAAS+M,MACnCjP,OAAQA,EACRpC,KAAMge,EACNte,KAAM4uD,EAAQ5uD,WAInBqvD,GAWXnS,EAAKl/C,UAAUygB,qBAAuB,SAAS/b,EAAQxJ,EAAGolB,GACtDvjB,KAAK0yD,WAAWnD,EAAkB5nD,EAAQxJ,EAAGolB,IAAc,IAO/D4+B,EAAKl/C,UAAUsxD,QAAU,SAAS3gD,GAU9B5T,KAAK0vD,KAAO97C,EAAMiD,aAAa64C,KAI/B1vD,KAAKS,KAAK,YAAamT,EAAO5T,OAOlCmiD,EAAKl/C,UAAUuxD,eAAiB,SAAS1rC,GACrC,IAAK,GAAIlqB,GAAI,EAAGA,EAAIkqB,EAAO3pB,OAAQP,IAAK,CACpC,GAAMgV,GAAQkV,EAAOlqB,EACG,WAApBgV,EAAMwC,WACNpW,KAAKu0D,QAAQ3gD,GAEjB5T,KAAK2vD,YAAY/7C,EAAMwC,WAAaxC,EACpC5T,KAAKS,KAAK,mBAAoBmT,EAAO5T,QAS7CmiD,EAAKl/C,UAAU8c,eAAiB,SAASxa,GACrC,MAAOvF,MAAK2vD,YAAYpqD,IAoH5BlG,EAAOJ,QAAUkjD,kNCnuCjB,YAkBA,SAAStnC,GAAa45C,EAAM1sC,GACxB/nB,KAAKy0D,KAAOA,EACZz0D,KAAK00D,QAAU3sC,EAdnB,GAAMy7B,GAAe7kD,EAAQ,mBACvBqD,EAAQrD,EAAQ,WAwBtBkc,GAAasT,SAAW,SAAS0sB,EAAS8Z,GACtC,GAAMC,GAAc/Z,EAAQ6Z,YACtB3rC,EAAgB6rC,EAAY7rC,kBAC5BF,EAAe+rC,EAAY/rC,iBAE3B6rC,EAAU,GAAIlR,GAAamR,EAAY9Z,EAAQ/tB,QAOrD,OALA4nC,GAAQlsC,iBAAiBosC,EAAYvrC,OAAO,GAC5CqrC,EAAQnsC,UAAUvmB,EAAMme,IAAI4I,EAAe4rC,IAAc,GACzDD,EAAQnsC,UAAUvmB,EAAMme,IAAI0I,EAAc8rC,IAAc,GACxDD,EAAQlsC,iBAAiBosC,EAAYhtC,KAAK,GAEnC,GAAI/M,GAAaggC,EAAQ4Z,KAAMC,IAO1Cr1D,EAAOJ,QAAU4b,6DClDjB,YA6BA,SAAS0nC,GAAK56C,GACV3H,KAAK2H,OAASA,EACd3H,KAAKumB,SAAW,UAChBvmB,KAAK60D,kBAAoB,KACzB70D,KAAK4rD,YAAcjkD,EACnB3H,KAAKwrD,eAAiB7jD,EACtB3H,KAAKkrD,UAAY,KACjBlrD,KAAK80D,cAAgB,EACrB90D,KAAK+0D,eAAiB,EACtB/0D,KAAKg1D,iBAAkB,EACvBh1D,KAAK8oB,QACDvC,SAAU,KACVjf,QAAS,MAEbtH,KAAK0rD,sBAvCR,GAAMhxC,GAAe/b,EAAQ,UAAU+b,YACzB/b,GAAQ,YAwCjBwc,SAASonC,EAAM7nC,GAWrB6nC,EAAKt/C,UAAUgyD,iBAAmB,SAASrhD,GACvC,GAAwB,eAApBA,EAAMwC,UAAV,CAGA,GAAM8+C,GAAqC,OAAzBl1D,KAAK8oB,OAAOvC,QAC9BvmB,MAAK8oB,OAAOvC,SAAW3S,CAEvB,IAAMuhD,OACFvhD,EAAMiD,aAAa0P,WAAavmB,KAAKumB,UAAY2uC,IACjDC,EAAav+C,KAAK,iBAElBhD,EAAMiD,aAAaiP,YACnBlS,EAAMiD,aAAaiP,aAAe9lB,KAAKkrD,WACvCiK,EAAav+C,KAAK,kBAElBhD,EAAMiD,aAAa+O,aACnBhS,EAAMiD,aAAa+O,cAAgB5lB,KAAK4rD,aACxCuJ,EAAav+C,KAAK,wBAEsB3V,KAAxC2S,EAAMiD,aAAau+C,kBACnBxhD,EAAMiD,aAAau+C,mBAAqBp1D,KAAKg1D,iBAC7CG,EAAav+C,KAAK,wBAGtB5W,KAAKumB,SAAW3S,EAAMiD,aAAa0P,SACnC4uC,EAAav+C,KAAK,uBAEdhD,EAAMiD,aAAaw+C,aACrBr1D,KAAK60D,kBAAoBjhD,EAAMiD,aAAaw+C,YAE1CzhD,EAAMiD,aAAa+O,cACnB5lB,KAAK4rD,YAAch4C,EAAMiD,aAAa+O,aAEtChS,EAAMiD,aAAaiP,aACnB9lB,KAAKkrD,UAAYt3C,EAAMiD,aAAaiP,YAExC9lB,KAAK80D,cAAgBlhD,EAAMiD,aAAay+C,gBACxCt1D,KAAK+0D,eAAiBxxD,KAAKyjB,MAC3BhnB,KAAKg1D,gBAAkBphD,EAAMiD,aAAau+C,iBAE1Cp1D,KAAK0rD,qBAEL,KAAK,GAAI9sD,GAAI,EAAGA,EAAIu2D,EAAah2D,OAAQP,IACrCoB,KAAKS,KAAK00D,EAAav2D,GAAIgV,EAAO5T,QAS1CuiD,EAAKt/C,UAAU0iB,eAAiB,SAASpE,GACrC,GAAMyqC,GAAUhsD,KAAK4rD,WACrB5rD,MAAK4rD,YAAcrqC,EACfA,IAASyqC,GACThsD,KAAK0rD,uBAUbnJ,EAAKt/C,UAAUsyD,kBAAoB,SAASh0C,GACxCvhB,KAAKwrD,eAAiBjqC,GAS1BghC,EAAKt/C,UAAU4iB,aAAe,SAASlL,GACnC,GAAM66C,GAASx1D,KAAKkrD,SACpBlrD,MAAKkrD,UAAYvwC,EACbA,IAAQ66C,GACRx1D,KAAK0rD,uBAObnJ,EAAKt/C,UAAUyoD,oBAAsB,WACjC1rD,KAAK2sD,UAAYppD,KAAKyjB,OAS1Bu7B,EAAKt/C,UAAU2pD,oBAAsB,WACjC,MAAO5sD,MAAK2sD,WAQhBpK,EAAKt/C,UAAUwyD,gBAAkB,WAC7B,MAAOz1D,MAAK+0D,eAAiB/0D,KAAK80D,eAMtCz1D,EAAOJ,QAAUsjD,mHC7JjB,QAAS9nC,GAAc9G,GAAQ,GAAAic,GAAA5vB,KACrB01D,EAAe,SAASC,GAC1B,MAAOA,GAAOh6C,QAAQ,sBAAuB,SAG3Ci6C,EAA0B,SAACv9C,EAAIw9C,EAASl3C,GAC1C,IAAK,GAAIm3C,GAAgB,EACjBA,EAAgBC,EAAmB52D,SACjC22D,EAIN,IAAK,GAHC5wD,GAAO6wD,EAAmBD,GAC1BE,EAAUH,EAAQ3wD,GAEf+wD,EAAY,EAAGA,EAAYD,EAAQ72D,SAAU82D,EAAW,CAC7D,GAAM3pC,GAAO0pC,EAAQC,EACrB,IAAK3pC,EAAKxe,QAAV,CAIA,GAAMooD,GAAUC,EAAkBjxD,EAAMonB,EAAM3N,EAC9C,IAAKu3C,GAIDtmC,EAAKwmC,iBAAiBF,EAAS79C,GAE/B,MADAiU,GAAKpnB,KAAOA,EACLonB,GAInB,MAAO,OAGL6pC,EAAoB,SAASjxD,EAAMmxD,EAAQ13C,GAC7C,GAAMu3C,IACF3pC,QAAW8pC,EAAO9pC,QAClBve,QAAWqoD,EAAOroD,QAClBsoD,cAEJ,QAAQpxD,GACJ,IAAK,YACL,IAAK,WACDgxD,EAAQI,WAAaD,EAAOC,UAC5B,MACJ,KAAK,OACD,IAAKD,EAAO9pC,QACR,MAAO,KAEX2pC,GAAQI,WAAW1/C,MACf1R,KAAQ,cACR8e,IAAO,UACPuyC,QAAWF,EAAO9pC,SAEtB,MACJ,KAAK,SACD,IAAK8pC,EAAO9pC,QACR,MAAO,KAEX2pC,GAAQI,WAAW1/C,MACf1R,KAAQ,cACR8e,IAAO,UACPuyC,QAAWF,EAAO9pC,SAEtB,MACJ,KAAK,UACD,IAAK8pC,EAAOE,QACR,MAAO,KAEXL,GAAQI,WAAW1/C,MACf1R,KAAQ,cACR8e,IAAO,eACPuyC,QAAWF,EAAOE,UAU9B,MANI53C,IACAu3C,EAAQI,WAAW1/C,MACf1R,KAAQ,SACRsxD,YAAe73C,IAGhBu3C,GAGLO,EAAyB,SAASC,EAAMr+C,GAC1C,GAAMs+C,IACFC,YAAeC,EACfl4C,OAAUm4C,EACVC,sBAAyBC,EACzBC,kBAAqBC,EACrBC,+BAAkCC,EAEtC,SAAIT,EAAoBD,EAAKxxD,OAClByxD,EAAoBD,EAAKxxD,MAAMwxD,EAAMr+C,IAQ9C++C,EAAwC,SAASV,EAAMr+C,GACzD,GAAM+2C,GAAgBsH,EAAA,GACtB,KAAKtH,EACD,OAAO,CAGX,IAAM59C,GAAOmC,EAAOlC,QAAQ4G,EAAG3G,YAC/B,UAAKF,IAASA,EAAKyN,eAOZzN,EAAKyN,aAAakwC,sBAAsBC,EAAe/2C,EAAGtB,cAG/DmgD,EAAwC,SAASR,EAAMr+C,GACzD,IAAKq+C,EAAKW,GACN,OAAO,CAGX,IAAM7lD,GAAOmC,EAAOlC,QAAQ4G,EAAG3G,YAC/B,KAAKF,IAASA,EAAKyN,eAAiBzN,EAAKyN,aAAaguC,QAClD,OAAO,CAGX,IAAMqK,IAAc,EAAA5sD,EAAA3K,SAAYyR,EAAKyN,aAAaguC,SAAS9iC,OAAO,SAASqmB,GACvE,MAAkD,QAA3Ch/B,EAAKyN,aAAaguC,QAAQzc,GAAG56B,aACrCzW,OAEGqxC,EAAIkmB,EAAKW,GAAGE,MAAM,qBACxB,KAAK/mB,EACD,OAAO,CAEX,IAAMgnB,GAAOhnB,EAAE,GACTinB,EAAMC,SAASlnB,EAAE,GACvB,IAAImnB,MAAMF,GACN,OAAO,CAEX,QAAQD,GACJ,IAAK,GACL,IAAK,KACD,MAAOF,IAAeG,CAC1B,KAAK,IACD,MAAOH,GAAcG,CACzB,KAAK,IACD,MAAOH,GAAcG,CACzB,KAAK,KACD,MAAOH,IAAeG,CAC1B,KAAK,KACD,MAAOH,IAAeG,CAC1B,SACI,OAAO,IAIbT,EAAoC,SAASN,EAAMr+C,GACrD,GAAMtP,GAAUsP,EAAGxB,YACnB,KAAK9N,IAAYA,EAAQ/D,MAA+B,gBAAhB+D,GAAQ/D,KAC5C,OAAO,CAGX,IAAMwM,GAAOmC,EAAOlC,QAAQ4G,EAAG3G,YAC/B,MAAKF,GAASA,EAAKyN,cAAiBzN,EAAKyN,aAAaguC,SACjDz7C,EAAKyN,aAAaozB,UAAU1+B,EAAOxC,YAAYxJ,SAChD,OAAO,CAGX,IAAMikD,GAAcp6C,EAAKyN,aAAaozB,UAAU1+B,EAAOxC,YAAYxJ,QAAQ4Z,KAIrEq2C,EAAM,GAAIC,QAAO,UAAYnC,EAAa9J,GAAe,UAAW,IAC1E,OAAO7iD,GAAQ/D,KAAKiJ,OAAO2pD,IAAQ,GAGjCd,EAA+B,SAASJ,EAAMr+C,GAChD,OAAO,GAGLw+C,EAAmC,SAASH,EAAMr+C,GACpD,GAAM+vB,GAAM0vB,EAAkBpB,EAAK1yC,IAAK3L,EACxC,KAAK+vB,GAAqB,gBAAPA,GACf,OAAO,CAGX,IAAIwvB,OAAA,EAEAA,GADY,gBAAZlB,EAAK1yC,IACC,UAAY+zC,EAAarB,EAAKH,SAAW,UAEzC,IAAMwB,EAAarB,EAAKH,SAAW,GAE7C,IAAMyB,GAAQ,GAAIH,QAAOD,EAAK,IAC9B,SAASxvB,EAAImvB,MAAMS,IAGjBD,EAAe,SAASE,GAK1B,GAAIL,GAAMlC,EAAauC,EAQvB,OAPAL,GAAMA,EAAIj8C,QAAQ,QAAS,MAC3Bi8C,EAAMA,EAAIj8C,QAAQ,MAAO,KACzBi8C,EAAMA,EAAIj8C,QAAQ,mBAAoB,SAAS47C,EAAOW,EAAIC,EAAIC,EAAQzC,GAGlE,MAAO,KAFOuC,GAAM,KAAO,IACZC,EAAGx8C,QAAQ,OAAQ,KACJ,OAKhCm8C,EAAoB,SAAS9zC,EAAK3L,GACpC,GAAMggD,GAAQr0C,EAAInI,MAAM,KACpBusB,MAAA,GAGEkwB,EAAYD,EAAM,EAYxB,KAXiB,WAAbC,GACAlwB,EAAM/vB,EAAGxB,aACTwhD,EAAME,SACc,QAAbD,GACPlwB,EAAM/vB,EAAGjC,UACTiiD,EAAME,SAGNnwB,EAAM/vB,EAAGzE,MAGNykD,EAAMl5D,OAAS,GAAG,CACrB,GAAMq5D,GAAWH,EAAME,OACvB,KAAKnwB,EAAIowB,GACL,MAAO,KAEXpwB,GAAMA,EAAIowB,GAEd,MAAOpwB,IAGLqwB,EAAmC,SAASpgD,EAAIqgD,GAClD,IAAKA,IAAaA,EAAS/5C,OACvB,MAAO,KAEX,IAAItG,EAAGtB,aAAepD,EAAOxC,YAAYxJ,OACrC,MAAO,KAIX,KAAK,GADCgxD,IAAc,EAAAjuD,EAAA3K,SAAY24D,EAAS/5C,QAChC/f,EAAI,EAAGA,EAAI+5D,EAAYx5D,SAAUP,EAAG,CACzC,GAAMg6D,GAAUD,EAAY/5D,GACtBi6D,EAAWH,EAAS/5C,OAAOi6C,GAE3BE,EAAelD,EAAwBiD,EAAUD,EACvD,IAAIE,EACA,MAAOA,GAGf,MAAOlD,GAAwBv9C,EAAIqgD,EAASj5D,SAG1Cs5D,EAAiC,SAAS1gD,EAAIqgD,GAChD,GAAMpsC,GAAOmsC,EAAiCpgD,EAAIqgD,EAClD,KAAKpsC,EACD,QAGJ,IAAM0sC,GAAYv+C,EAAcwP,0BAA0BqC,EAAKte,QAS/D,YANmC/M,KAA/B+3D,EAAUC,OAAOC,YAGjBF,EAAUC,OAAOC,UAA0B,WAAb5sC,EAAKpnB,MAGhC8zD,EAGXh5D,MAAKo2D,iBAAmB,SAAS9pC,EAAMjU,GAEnC,IAAK,GADDkY,IAAM,EACD3xB,EAAI,EAAGA,EAAI0tB,EAAKgqC,WAAWn3D,SAAUP,EAAG,CAC7C,GAAM83D,GAAOpqC,EAAKgqC,WAAW13D,EAC7B2xB,IAAOkmC,EAAuBC,EAAMr+C,GAGxC,MAAOkY,IAWXvwB,KAAKylB,gBAAkB,SAASpN,GAC5B,MAAO0gD,GAA+B1gD,EAAI1E,EAAO0Y,YASrDrsB,KAAKm5D,gBAAkB,SAAS1rD,GAC5B,IAAA,GADoC2rD,IACf,SAAU,UAA/BC,EAAA,EAAAA,EAAAD,EAAAj6D,OAAAk6D,IAA0C,CAArC,GAAM7rD,GAAA4rD,EAAAC,EACP,QAAgCp4D,KAA5B0S,EAAO0Y,UAAU7e,GAArB,CADsC,GAAA1M,IAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KAGtC,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,SAAmBg2D,KAAnBj1D,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAAuC,CAAA,GAA5BoE,GAA4BhE,EAAAK,KACnC,QAAsCN,KAAlC0S,EAAO0Y,UAAU7e,GAAOtI,GAA5B,CADmC,GAAAovB,IAAA,EAAAC,GAAA,EAAAC,MAAAvzB,EAAA,KAGnC,IAAA,GAAAwzB,GAAAC,GAAA,EAAAtzB,EAAArB,SAAmB4T,EAAO0Y,UAAU7e,GAAOtI,MAA3CovB,GAAAG,EAAAC,EAAArzB,QAAAC,MAAAgzB,GAAA,EAAkD,CAAA,GAAvChI,GAAuCmI,EAAAlzB,KAC9C,IAAI+qB,EAAKC,UAAY9e,EAAQ,MAAO6e,IAJL,MAAA1qB,GAAA2yB,GAAA,EAAAC,EAAA5yB,EAAA,QAAA,KAAA0yB,GAAAI,EAAA7yB,QAAA6yB,EAAA7yB,SAAA,QAAA,GAAA0yB,EAAA,KAAAC,OAHD,MAAA5yB,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,MAW1C,MAAO,uJAtUT+0D,GAAsB,WAAY,UAAW,OAAQ,SAAU,YAkVrEt7C,GAAcwP,0BAA4B,SAASqvC,GAE/C,IAAK,GADCC,IAAcC,QAAU,EAAOP,WAC5Br6D,EAAI,EAAGA,EAAI06D,EAAWn6D,SAAUP,EAAG,CACxC,GAAMilC,GAASy1B,EAAW16D,EACX,YAAXilC,EACA01B,EAAUC,QAAS,EACM,gBAAlB,KAAO31B,EAAP,aAAA,EAAArzB,EAAAzQ,SAAO8jC,UACO5iC,KAAjB4iC,EAAOtiC,QACPsiC,EAAOtiC,OAAQ,GAEnBg4D,EAAUN,OAAOp1B,EAAO41B,WAAa51B,EAAOtiC,OAGpD,MAAOg4D,IAeXl6D,EAAOJ,QAAUwb,wJCzWjB,YAqGA,SAASi/C,KACDC,GACAl6D,EAAOywB,aAAaypC,EAGxB,IAAMC,GAAQC,EAAc,EAE5B,KAAKD,EAED,WADAtV,GAAS,6DAIb,IAAMt9B,GAAM8yC,IACNC,EAAU9yC,KAAKonB,IAAIurB,EAAMI,MAAQhzC,EAAKizC,EAE5C3V,GAAS,8BAA+Bt9B,EAAK,SAAU+yC,GACvDJ,EAAmBl6D,EAAOuZ,WAAWkhD,EAAeH,GAGxD,QAASG,KACL,GAAI9pC,OAAA,GACEpJ,EAAM8yC,GACZxV,GAAS,sBAAuBt9B,EAIhC,KADA,GAAMmzC,QACO,CACT,GAAMP,GAAQC,EAAc,EAC5B,KAAKD,GAASA,EAAMI,MAAQhzC,EACxB,KAEJoJ,GAAKypC,EAActB,QACnBjU,EAAS,yBAA0Bl0B,EAAGpM,KACtCm2C,EAAevjD,KAAKwZ,GAMxBspC,GAEA,KAAK,GAAI96D,GAAI,EAAGA,EAAIu7D,EAAeh7D,OAAQP,IAAK,CAC5CwxB,EAAK+pC,EAAev7D,EACpB,KACIwxB,EAAGyI,KAAKn4B,MAAMjB,EAAQ2wB,EAAG5rB,QAC3B,MAAOrG,GACLsW,QAAQC,MAAM,0CACAvW,EAAEwW,OAASxW,KAWrC,QAASi8D,GAAaC,EAAOxhC,GAKzB,IAHA,GAAIwV,GAAM,EACNnnB,EAAMmzC,EAAMl7D,OAETkvC,EAAMnnB,GAAK,CACd,GAAMozC,GAAOjsB,EAAMnnB,GAAQ,CACf2R,GAAKwhC,EAAMC,IACb,EAENpzC,EAAMozC,EAGNjsB,EAAMisB,EAAM,EAIpB,MAAOjsB,GA5KX,GAAM4rB,GAAwB,IAG1BM,EAAS,EAGTZ,MAAA,GAIEE,KAGAvV,EAAW,YAWjBjlD,GAAOJ,QAAQu7D,OAAS,SAAS37D,GAC7Bi7D,EAAOj7D,GAAK0E,KAAKyjB,IAErB,IAAI8yC,GAAOv2D,KAAKyjB,GAYhB3nB,GAAOJ,QAAQ+Z,WAAa,SAAS6f,EAAMkhC,IACvCA,EAAUA,GAAW,GACP,IACVA,EAAU,EAGd,IAAMv1D,GAASjE,MAAM0C,UAAU6tB,MAAM5xB,KAAKmB,UAAW,GAC/C25D,EAAQF,IAASC,EACjB/1C,EAAMu2C,GACZjW,GAAS,4BAA6BtgC,EAAK,KAAMg2C,EACxC,SAAUD,EAAS,IAC5B,IAAM90D,IACF+0D,MAAOA,EACPnhC,KAAMA,EACNr0B,OAAQA,EACRwf,IAAKA,GAIHojC,EAAMgT,EACRP,EAAe,SAASY,GACpB,MAAOA,GAAGT,MAAQA,GAO1B,OAHAH,GAAcvhB,OAAO8O,EAAK,EAAGniD,GAC7By0D,IAEO11C,GAQX3kB,EAAOJ,QAAQixB,aAAe,SAASlM,GACnC,GAA6B,IAAzB61C,EAAc16D,OAAlB,CAKA,GAAIP,OAAA,EACJ,KAAKA,EAAI,EAAGA,EAAIi7D,EAAc16D,OAAQP,IAAK,CAEvC,GADWi7D,EAAcj7D,GAClBolB,KAAOA,EAAK,CACf61C,EAAcvhB,OAAO15C,EAAG,EACxB,QAKE,IAANA,GACA86D,iJC1GR,YAuBA,SAASlX,GAAgBkY,EAAgBC,GACrC36D,KAAK06D,eAAiBA,GAAkBlY,EAAgBoY,wBACxD56D,KAAK26D,eAAiBA,GAAkBnY,EAAgBqY,eACxD76D,KAAK86D,WAOL96D,KAAK+6D,iBACL/6D,KAAKg7D,QAAU,KAyInB,QAASC,GAAuB7pD,GACvBA,EAAU4pD,SAIfh5D,EAAMyM,QAAQzM,EAAMmoB,OAAOnoB,EAAMsd,KAAKlO,EAAU0pD,SAAU,SAASI,GAC/D,OAAuD,IAAhD9pD,EAAU2pD,cAAc1kD,QAAQ6kD,IAC/B9pD,EAAU0pD,QAAQI,GAAW/7D,OAAS,IAC9C,SAAS+7D,GAET9pD,EAAU2pD,cAAcnkD,KAAKskD,GAE7B5W,EAAS,0BAA2B4W,GACpCC,EAAc/pD,EAAW8pD,KAIjC,QAASC,GAAc/pD,EAAW8pD,GAE9B,GAAMtuB,GAAMwuB,EAAehqD,EAAW8pD,EACtC,KAAKtuB,EAAK,CAEN,GAAMgK,GAAQxlC,EAAU2pD,cAAc1kD,QAAQ6kD,EAK9C,OAJItkB,IAAS,GACTxlC,EAAU2pD,cAAcziB,OAAO1B,EAAO,OAE1C0N,GAAS,yCAA0C4W,GAGvD5W,EACI,mCACA4W,EAAW9pD,EAAU0pD,QAAQI,GAAW/7D,QAI5CiS,EAAU4pD,QAAQpuB,EAAIh5B,OAAOtS,KAAK,SAAS+S,GAEvCgnD,EAAiBjqD,EAAW8pD,GAC5B5W,EAAS,2BAA4B4W,EAAWtuB,EAAIh5B,MAAM6P,SAC1DmpB,EAAI1zB,MAAMpF,QAAQO,GAElB8mD,EAAc/pD,EAAW8pD,IAC1B,SAASt5D,GACRgrC,EAAI0uB,UAAY,CAEhB,IAAMC,GAAanqD,EAAUspD,eAAe9tB,EAAIh5B,MAAOg5B,EAAI0uB,SAAU15D,EACrE0iD,GACI,2CACA1X,EAAI0uB,SAAU15D,EAAKgrC,EAAIh5B,MAAM6P,QAAS83C,IAEtB,IAAhBA,GACAjX,EACI,mCAAoC4W,EAAWtuB,EAAIh5B,MAAM6P,SAG7D43C,EAAiBjqD,EAAW8pD,GAC5BtuB,EAAI1zB,MAAMC,OAAOvX,GAEjBu5D,EAAc/pD,EAAW8pD,IAEzBliD,WAAW,WACPmiD,EAAc/pD,EAAW8pD,IAC1BK,KAKf,QAASH,GAAehqD,EAAW8pD,GAC/B,GAAMM,GAAQpqD,EAAU0pD,QAAQI,EAChC,OAAKl5D,GAAMuoC,QAAQixB,GAGZA,EAAM,GAFF,KAKf,QAASH,GAAiBjqD,EAAW8pD,GACjC,GAAMM,GAAQpqD,EAAU0pD,QAAQI,EAChC,OAAKl5D,GAAMuoC,QAAQixB,GAGZA,EAAMjD,QAFF,KAKf,QAASjU,KACL,GAAImX,EAAO,CAAA,GAAAC,IACPA,EAAAjnD,SAAQe,IAAR9U,MAAAg7D,EAAer7D,YAzPvB,GAAA+Z,GAAAzb,EAAA,mEADMqD,EAAQrD,EAAQ,WAGhB88D,GAAQ,CAqCdjZ,GAAgBv/C,UAAUkR,iBAAmB,SAASP,GAClD,GAAM2N,GAAOvhB,KAAK26D,eAAe/mD,EACjC,OAAK2N,IAASvhB,KAAK86D,QAAQv5C,GAGpBvf,EAAMme,IAAIngB,KAAK86D,QAAQv5C,GAAO,SAASqrB,GAC1C,MAAOA,GAAIh5B,QAHJ,MAaf4uC,EAAgBv/C,UAAUme,qBAAuB,SAASxN,GACtD,GAAM2N,GAAOvhB,KAAK26D,eAAe/mD,EACjC,KAAK2N,IAASvhB,KAAK86D,QAAQv5C,GACvB,OAAO,CAEX,IAAIqlC,IAAU,CASd,OARA5kD,GAAM6wD,cAAc7yD,KAAK86D,QAAQv5C,GAAO,SAASo6C,GAC7C,GAAIA,EAAQ/nD,MAAM6P,UAAY7P,EAAM6P,QAIhC,MADAmjC,IAAU,GACH,IAGRA,GAWXpE,EAAgBv/C,UAAUqO,mBAAqB,SAASsqD,GACpD57D,KAAKg7D,QAAUY,EACfX,EAAuBj7D,OAS3BwiD,EAAgBv/C,UAAUiR,WAAa,SAASN,GAC5C,GAAMsnD,GAAYl7D,KAAK26D,eAAe/mD,EACtC,KAAKsnD,EACD,MAAO,KAGNl7D,MAAK86D,QAAQI,KACdl7D,KAAK86D,QAAQI,MAEjB,IAAMhiD,GAAQrF,EAAA9T,QAAQmZ,OAWtB,OAVAlZ,MAAK86D,QAAQI,GAAWtkD,MACpBhD,MAAOA,EACPsF,MAAOA,EACPoiD,SAAU,IAEdhX,EACI,kDACA1wC,EAAM6P,QAASy3C,GAEnBD,EAAuBj7D,MAChBkZ,EAAMpN,SAcjB02C,EAAgBoY,wBAA0B,SAAShnD,EAAO0nD,EAAU15D,GAChE,GAAuB,MAAnBA,EAAI0tB,YAAyC,MAAnB1tB,EAAI0tB,YAAyC,MAAnB1tB,EAAI0tB,WAExD,OAAQ,CAIZ,IAAiB,aAAb1tB,EAAIi6D,KACJ,OAAQ,CAGZ,IAAiB,qBAAbj6D,EAAI2f,KAA6B,CACjC,GAAMu6C,GAAWl6D,EAAIqD,KAAK82D,cAC1B,IAAID,EACA,MAAOA,GAGf,MAAIR,GAAW,GACH,EAEJ,IAAOr0C,KAAK+0C,IAAI,EAAGV,IAU/B9Y,EAAgBqY,eAAiB,SAASjnD,GACtC,MAAwB,mBAApBA,EAAMwC,UAEC,UAGJ,MAoIX/W,EAAOJ,QAAUujD,mHCrSjB,QAAS/M,GAAeH,GAEpBA,EAAGK,kBAAkB,SAAWC,SAAU,YAI1CN,EAAGK,kBAAkB,eAAiBC,SAAU,UAGhDN,EAAGK,kBAAkB,QAAUC,SAAU,aAa7C,QAASqmB,GAAYhrD,EAAOirD,EAAUC,GAClC,GAAMrtD,GAAQmC,EAAM4lC,WAAWqlB,EAC/B,OAAO,IAAAroD,GAAA9T,QAAY,SAAC+T,EAASqF,GACzB,GAAMwU,KACN7e,GAAMmnC,QAAU,SAACriC,GACbuF,EAAO,GAAIra,OAAM,iBAAmB8U,EAAM/T,OAAOu8D,aAGrDttD,EAAM6nC,UAAY,SAAC/iC,GACf,GAAMkjC,GAASljC,EAAM/T,OAAOitB,MAC5B,KAAKgqB,EAED,WADAhjC,GAAQ6Z,EAGZA,GAAQ/W,KAAKulD,EAAarlB,IAC1BA,EAAOC,cAKnB,QAASjB,GAAcC,GACnB,MAAO,IAAAliC,GAAA9T,QAAY,SAAC+T,EAASqF,GACzB48B,EAAIC,WAAa,SAASpiC,GACtBE,EAAQF,IAEZmiC,EAAIE,QAAU,SAASriC,GACnBuF,EAAOvF,MAKnB,QAASyoD,GAAkBt5B,GACvB,MAAO,IAAAlvB,GAAA9T,QAAY,SAAC+T,EAASqF,GACzB4pB,EAAI4T,UAAY,SAAS/iC,GACrBE,EAAQF,IAEZmvB,EAAIkT,QAAU,SAASriC,GACnBuF,EAAOvF,8JAjEnBwG,EAAAzb,EAAA,mBACA29D,EAAA39D,EAAA,8BACA0jC,EAAA1jC,EAAA,mBA+EM49D,EAA6B,SAC/BC,EAAoB/kB,GAEpBz3C,KAAKR,UAAYg9D,EACjBx8D,KAAKq2C,QAAU,kBAAoBoB,GAAU,WAC7Cz3C,KAAKs1C,GAAK,KACVt1C,KAAKs8D,iBAAmB,GAAAG,GAAA18D,QAI5Bw8D,GAA2Bt5D,WAMvBy5D,QAAS,WAAW,GAAA9sC,GAAA5vB,IAChB,IAAIA,KAAKs1C,GAIL,MAHA7gC,SAAQe,IAAR,yDAGO3B,EAAA9T,QAAQ+T,SAGnBW,SAAQe,IAAR;8DAGA,IAAMutB,GAAM/iC,KAAKR,UAAUo4C,KAAK53C,KAAKq2C,QAxG7B,EA8HR,OArBAtT,GAAI8U,gBAAkB,SAACx/B,GACnB,GAAMi9B,GAAKj9B,EAAGxY,OAAOitB,OACfyoB,EAAal9B,EAAGk9B,UACtB9gC,SAAQe,IAAR,sDAC0D+/B,GAEtDA,EAAa,GACbE,EAAeH,IAKvBvS,EAAI+U,UAAY,WACZrjC,QAAQe,IAAR,2EAKJf,QAAQe,IAAR,2DAGO6mD,EAAkBt5B,GAAKn/B,KAAK,SAACyU,GAYhC,MAXA5D,SAAQe,IAAR,iDAGAoa,EAAK0lB,GAAKj9B,EAAGxY,OAAOitB,OAIpB8C,EAAK0lB,GAAGc,gBAAkB,WACtBxmB,EAAK0lB,GAAGgB,SAGL1mB,EAAK+sC,WAQpBA,MAAO,WAAW,GAAAznC,GAAAl1B,IACd,OAAO6T,GAAA9T,QAAQyb,KACXxb,KAAK48D,mBACL58D,KAAK68D,kBACNj5D,KAAK,SAAAojC,GAA6B,GAAAvpB,IAAA,EAAAq/C,EAAA/8D,SAAAinC,EAAA,GAA3B2oB,EAA2BlyC,EAAA,GAAd+zB,EAAc/zB,EAAA,EACjChJ,SAAQe,IAAR,mDAGA0f,EAAKonC,iBAAiBS,YAClB5uD,WAAYqjC,EAASwrB,UACrBjkB,MAAOvH,EAASyrB,UAChBC,OAAQ1rB,EAAS2rB,WACjBC,cACIt0C,OAAQ6mC,QAWxB0N,cAAe,WAAW,GAAAvnC,GAAA91B,IACtB,OAAO,IAAA6T,GAAA9T,QAAY,SAAC+T,EAASqF,GACzB1E,QAAQe,IAAR,gCAA4CsgB,EAAKugB,QACjD,IAAMtT,GAAMjN,EAAKt2B,UAAUw4C,eAAeliB,EAAKugB,QAE/CtT,GAAI+U,UAAY,WACZrjC,QAAQe,IACJ,8BAA8BsgB,EAAKugB,QAAnC,kCAKRtT,EAAIkT,QAAU,SAAC59B,GAIX5D,QAAQyG,KAAR,4CACgD7C,EAAGxY,OAAO6U,OAE1DZ,KAGJivB,EAAI4T,UAAY,WACZliC,QAAQe,IAAR,+BAA2CsgB,EAAKugB,SAChDviC,QAcZwpD,aAAc,SAASC,OACNt8D,KAATs8D,IAAoBA,GAAO,EAE/B,IAAMt4D,GAAOjF,KAAKs8D,iBAAiBkB,SACnC,OAAKv4D,GAAK+3D,UACNO,EAGO1pD,EAAA9T,QAAQ+T,QAAQquB,EAAApiC,QAAMqiB,SAASnd,IAE/B4O,EAAA9T,QAAQ+T,QAAQ7O,GANC4O,EAAA9T,QAAQ+T,QAAQ,OAUhD2pD,YAAa,SAASjsB,GAAU,GAAAxb,GAAAh2B,IAC5B,OAAO6T,GAAA9T,QAAQ+T,UAAUlQ,KAAK,WAC1BoyB,EAAKsmC,iBAAiBS,WAAWvrB,MAIzCksB,eAAgB,SAASC,GACrB,GAAMnsB,GAAWxxC,KAAKs8D,iBAAiBkB,SAEvC,OAAO3pD,GAAA9T,QAAQyb,KACXxb,KAAK49D,2BAA2BD,GAChC39D,KAAK69D,oBAAoBrsB,EAASme,aAClC3vD,KAAK89D,iBACDtsB,EAASwrB,UAAWxrB,EAASyrB,UAAWzrB,EAAS2rB,eAY7DW,iBAAkB,SAASd,EAAWC,EAAWE,GAAY,GAAAx5B,GAAA3jC,IAEzD,OADAyU,SAAQe,IAAI,8BAA+BwnD,GACpCnpD,EAAA9T,QAAQs4C,IAAI,WACf,GAAMtC,GAAMpS,EAAK2R,GAAGiB,aAAa,QAAS,YAQ1C,OAPcR,GAAIW,YAAY,QACxBqnB,KACFC,QAAS,IACThB,UAAWA,EACXC,UAAWA,EACXE,WAAYA,IAETrnB,EAAcC,MAU7B8nB,oBAAqB,SAASlO,GAAa,GAAA1rB,GAAAjkC,IACvC,OAAO6T,GAAA9T,QAAQs4C,IAAI,WAGf,IAAK,GAFCtC,GAAM9R,EAAKqR,GAAGiB,aAAa,eAAgB,aAC3CtlC,EAAQ8kC,EAAIW,YAAY,eACrB93C,EAAI,EAAGA,EAAI+wD,EAAYxwD,OAAQP,IACpCqS,EAAM8sD,IAAIpO,EAAY/wD,GAE1B,OAAOk3C,GAAcC,MAY7B6nB,2BAA4B,SAASK,GAAQ,GAAA3rB,GAAAtyC,IACzC,OAAO6T,GAAA9T,QAAQs4C,IAAI,WACf,GAAMtC,GAAMzD,EAAKgD,GAAGiB,aAAa,SAAU,aACrCtlC,EAAQ8kC,EAAIW,YAAY,SAFT51C,GAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KAGrB,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,SAAoBk+D,KAApBn9D,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAA4B,CAAA,GAAjBo9D,GAAiBh9D,EAAAK,KACxB0P,GAAM8sD,KACFp2D,OAAQu2D,EAAM,GACdtqD,MAAOsqD,EAAM,MANA,MAAAt8D,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,IASrB,MAAO80C,GAAcC,MAU7BooB,sBAAuB,WAAW,GAAAnrB,GAAAhzC,IAC9B,OAAO6T,GAAA9T,QAAQs4C,IAAI,WAGf,MAAO4jB,GAFKjpB,EAAKsC,GAAGiB,aAAa,SAAU,YACzBG,YAAY,aACJz1C,GAAW,SAAC61C,GAClC,OAAQA,EAAOv1C,MAAMoG,OAAQmvC,EAAOv1C,MAAMqS,YAStDgpD,iBAAkB,WAAW,GAAAwB,GAAAp+D,IAIzB,OAHAyU,SAAQe,IAAR,oDAGO3B,EAAA9T,QAAQs4C,IAAI,WAMf,MALA5jC,SAAQe,IAAR,mDAKOymD,EAFKmC,EAAK9oB,GAAGiB,aAAa,eAAgB,YAC/BG,YAAY,mBACJz1C,GAAW,SAAC61C,GAClC,MAAOA,GAAOv1C,WAS1Bs7D,cAAe,WAAW,GAAAwB,GAAAr+D,IAItB,OAHAyU,SAAQe,IAAR,gDAGO3B,EAAA9T,QAAQs4C,IAAI,WAMf,MALA5jC,SAAQe,IAAR,gDAKOymD,EAFKoC,EAAK/oB,GAAGiB,aAAa,QAAS,YACxBG,YAAY,YACJz1C,GAAW,SAAC61C,GAClC,MAAOA,GAAOv1C,QACfqC,KAAK,SAAC+pB,GAIL,MAHIA,GAAQxuB,OAAS,GACjBsV,QAAQyG,KAAK,6CAETyS,EAAQxuB,OAAS,EAAIwuB,EAAQ,sBAMtC4uC,2NC/Wf,IAAAniD,GAAAzb,EAAA,mEAcM2/D,EAA8B,SAChCC,EAAc9mB,EAAQ+mB,GAEtBx+D,KAAKq2C,QAAUoB,EACfz3C,KAAKy+D,QAAU,GAAID,GAAUD,GAC7Bv+D,KAAK0+D,SAAW,EAEhB1+D,KAAK2+D,aAIL3+D,KAAKy+D,QAAQG,UAAY5+D,KAAK6+D,iBAAiBp9D,KAAKzB,MAGpDA,KAAK8+D,cAAgB9+D,KAAK++D,OAAO,gBAAiB/+D,KAAKq2C,UAAUzyC,KAAK,WAClE6Q,QAAQe,IAAI,+BAKpB8oD,GAA4Br7D,WAMxBy5D,QAAS,WAAW,GAAA9sC,GAAA5vB,IAChB,OAAOA,MAAK8+D,cAAcl7D,KAAK,WAAA,MAAMgsB,GAAKmvC,OAAO,cAQrD1B,cAAe,WAAW,GAAAnoC,GAAAl1B,IACtB,OAAOA,MAAK8+D,cAAcl7D,KAAK,WAAA,MAAMsxB,GAAK6pC,OAAO,oBAQrDzB,aAAc,WACV,MAAOt9D,MAAK++D,OAAO,iBAGvBtB,YAAa,SAASjsB,GAClB,MAAOxxC,MAAK++D,OAAO,eAAgBvtB,KAGvCksB,eAAgB,SAASv7C,GACrB,MAAOniB,MAAK++D,OAAO,kBAAmB58C,KAQ1Cg8C,sBAAuB,WACnB,MAAOn+D,MAAK++D,OAAO,0BAGvBA,OAAQ,SAASC,EAAK1+D,GAAM,GAAAw1B,GAAA91B,IAGxB,OAAO6T,GAAA9T,QAAQ+T,UAAUlQ,KAAK,WAC1B,GAAMq7D,GAAMnpC,EAAK4oC,WACXQ,EAAMrrD,EAAA9T,QAAQmZ,OAUpB,OARA4c,GAAK6oC,UAAUM,GAAOC,EAEtBppC,EAAK2oC,QAAQU,aACTC,QAASJ,EACTC,IAAKA,EACL3+D,KAAMA,IAGH4+D,EAAIpzD,WAInB+yD,iBAAkB,SAASxmD,GACvB,GAAM2sB,GAAM3sB,EAAGpT,IAEf,IAAmB,eAAf+/B,EAAIo6B,SAA2C,YAAfp6B,EAAIo6B,QAAuB,CAC3D,OAAgBn+D,KAAZ+jC,EAAIi6B,IAEJ,WADAxqD,SAAQC,MAAM,oCAIlB,IAAMwqD,GAAMl/D,KAAK2+D,UAAU35B,EAAIi6B,IAC/B,QAAYh+D,KAARi+D,EAEA,WADAzqD,SAAQC,MAAM,6BAA+BswB,EAAIi6B,WAG9Cj/D,MAAK2+D,UAAU35B,EAAIi6B,KAEP,eAAfj6B,EAAIo6B,QACJF,EAAIprD,QAAQkxB,EAAIlY,QAEhBoyC,EAAI/lD,OAAO6rB,EAAItwB,WAGnBD,SAAQyG,KAAK,qCAAuC8pB,eAKjDs5B,0NC7HflkD,EAAAzb,EAAA,mBACA0gE,EAAA1gE,EAAA,YACA0jC,EAAA1jC,EAAA,mBACA2gE,EAAA3gE,EAAA,uCACA4gE,EAAA5gE,EAAA,wCACA6gE,EAAA7gE,EAAA,yBACA8gE,EAAA9gE,EAAA,mBAyDMqjD,EAAiB,SAAwBjgD,GAG3C,GAFAs9D,EAAAtd,oBAAoB7iD,KAAKc,KAAM+B,IAE1BA,EAAKvC,UACN,KAAM,IAAIV,OAAM,qCAGpB,IAAIiD,EAAKw8D,aAAc,CAEnB,GAAImB,GAAY39D,EAAK29D,SAChBA,KAEDA,EAAYjgE,EAAOkgE,QAEvB3/D,KAAKk4C,QAAU,GAAA0nB,GAAA7/D,QACXgC,EAAKw8D,aAAcx8D,EAAK01C,OAAQioB,OAGpC1/D,MAAKk4C,QAAU,GAAA2nB,GAAA9/D,QAA+BgC,EAAKvC,UAAWuC,EAAK01C,OAGvEz3C,MAAK8/D,WAAY,EACjB9/D,KAAK+/D,QAAU,EAKf//D,KAAKggE,oBAIT79B,GAAApiC,QAAMob,SAAS6mC,EAAfqd,EAAAtd,qBAKAC,EAAe/+C,UAAUg9D,QAAU,WAAW,GAAArwC,GAAA5vB,IAC1C,OAAIA,MAAK8/D,WACLrrD,QAAQe,IAAR,2CACO3B,EAAA9T,QAAQ+T,YAGnBW,QAAQe,IAAR,iDACOxV,KAAKk4C,QAAQwkB,UAAU94D,KAAK,WAE/B,MADA6Q,SAAQe,IAAR,mDACOoa,EAAKsoB,QAAQimB,0BACrBv6D,KAAK,SAACs8D,GACLzrD,QAAQe,IAAR,sDACA0qD,EAAmBzxD,QAAQ,SAAAu4B,GAAwB,GAAAvpB,IAAA,EAAAq/C,EAAA/8D,SAAAinC,EAAA,GAAtBr/B,EAAsB8V,EAAA,GAAd0iD,EAAc1iD,EAAA,GACzChf,EAAI,GAAA2hE,GAAArgE,QAAS4H,EACfw4D,IACA1hE,EAAEw2D,iBAAiB,GAAAwK,GAAAjmD,YAAgB2mD,IAEvCvwC,EAAKowC,iBAAiBvhE,EAAEkJ,QAAUlJ,EAAEmuD,sBACpCh9B,EAAKywC,UAAU5hE,SAU3BujD,EAAe/+C,UAAUq6D,aAAe,WACpC,MAAOt9D,MAAKk4C,QAAQolB,gBAOxBtb,EAAe/+C,UAAUsY,cAAgB,WAErC,MADA8jD,GAAAtd,oBAAoB9+C,UAAUsY,cAAcrc,KAAKc,MAC1CA,KAAKk4C,QAAQmlB,gBAAgBz5D,KAAK,WACrC6Q,QAAQe,IAAI,4BACb,SAAC5T,GAEA,KADA6S,SAAQC,MAAR,oCAAkD9S,GAC5CA,KAQdogD,EAAe/+C,UAAUq9D,KAAO,WAE5B,MADY/8D,MAAKyjB,MACPhnB,KAAK+/D,QArII,IAsIR//D,KAAKugE,cAET1sD,EAAA9T,QAAQ+T,WAGnBkuC,EAAe/+C,UAAUs9D,YAAc,WACnCvgE,KAAK+/D,QAAUx8D,KAAKyjB,KAIpB,IAAM22C,MALwC78D,GAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KAM9C,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,SAAgBC,KAAK2f,cAArB7e,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAAiC,CAAA,GAAtBrC,GAAsByC,EAAAK,KACzBvB,MAAKggE,iBAAiBvhE,EAAEkJ,UAAYlJ,EAAEmuD,wBACrCnuD,EAAEqqB,OAAOvC,WAEdo3C,EAAW/mD,MAAMnY,EAAEkJ,OAAQlJ,EAAEqqB,OAAOvC,SAAS3S,QAG7C5T,KAAKggE,iBAAiBvhE,EAAEkJ,QAAUlJ,EAAEmuD,yBAbM,MAAAhrD,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,IAgB9C,MAAOhB,MAAKk4C,QAAQwlB,eAAeC,GAAYr6B,MAAM,SAAC1hC,GAClD6S,QAAQC,MAAM,aAAc9S,MAIpCogD,EAAe/+C,UAAUw6D,YAAc,SAASjsB,GAC5C,MAAOxxC,MAAKk4C,QAAQulB,YAAYjsB,IAGpCnyC,EAAOJ,QAAQ+iD,eAAiBA,mXCtLhC,YAOA,IAAA5nC,GAAAzb,EAAA,mEAFMqD,EAAQrD,EAAQ,YAChB4jD,EAAO5jD,EAAQ,iBAUrBU,GAAOJ,QAAQ8iD,oBAAsB,SAA6BhgD,GAC9DA,EAAOA,MACP/B,KAAK+4C,SAGL/4C,KAAKk9D,UAGLl9D,KAAKmiB,SAGLniB,KAAK61B,UAAY,KACjB71B,KAAKwgE,WAKLxgE,KAAK2vD,eAGL3vD,KAAKujD,aAAexhD,EAAKwhD,cAG7BlkD,EAAOJ,QAAQ8iD,oBAAoB9+C,WAM/Bw9D,aAAc,WACV,MAAOzgE,MAAK61B,WAQhB6qC,aAAc,SAASv6D,GACnBnG,KAAK61B,UAAY1vB,GAOrBw6D,WAAY,SAASC,GACjB5gE,KAAKk9D,OAAO0D,EAAM15D,SAAW05D,GAQjCrhD,SAAU,SAASrY,GACf,MAAOlH,MAAKk9D,OAAOh2D,IAAY,MAOnCsY,UAAW,WACP,MAAOxd,GAAMyV,OAAOzX,KAAKk9D,SAO7B2D,UAAW,SAASrvD,GAChBxR,KAAK+4C,MAAMvnC,EAAKzK,QAAUyK,EAG1BA,EAAKyN,aAAatd,GAAG,oBAAqB3B,KAAK8gE,cAAcr/D,KAAKzB,MAElE,IAAMqR,GAAOrR,IACbwR,GAAKyN,aAAa2uC,aAAan/C,QAAQ,SAAS+hC,GAC5Cn/B,EAAKyvD,cAAc,KAAMtvD,EAAKyN,aAAcuxB,MAWpDswB,cAAe,SAASltD,EAAOsD,EAAOytB,GAClC,GAA0B,WAAtBA,EAAO/uB,WAAX,CAMA,GAAMlQ,GAAO1F,KAAKmiB,MAAMwiB,EAAOh9B,SAAW,GAAI46C,GAAK5d,EAAOh9B,OACtDg9B,GAAOpjB,OACP7b,EAAKigB,eAAegf,EAAOpjB,MACvBojB,EAAO7b,OAAO6b,QACdj/B,EAAK6vD,kBACD5wB,EAAO7b,OAAO6b,OAAOykB,wBAAwBxjC,cAIrD+e,EAAO7b,OAAO6b,QAAUA,EAAO7b,OAAO6b,OAAO9tB,aAAaiP,YAC1DpgB,EAAKmgB,aAAa8e,EAAO7b,OAAO6b,OAAO9tB,aAAaiP,YAExD9lB,KAAKmiB,MAAMzc,EAAKiC,QAAUjC,IAQ9B+L,QAAS,SAAS1K,GACd,MAAO/G,MAAK+4C,MAAMhyC,IAAW,MAOjC0Y,SAAU,WACN,MAAOzd,GAAMyV,OAAOzX,KAAK+4C,QAO7B7zB,WAAY,SAASne,GACb/G,KAAK+4C,MAAMhyC,IACX/G,KAAK+4C,MAAMhyC,GAAQg6D,eAAe,oBAAqB/gE,KAAK8gE,qBAEzD9gE,MAAK+4C,MAAMhyC,IAOtBi6D,iBAAkB,WACd,MAAOh/D,GAAMme,IAAIne,EAAMyV,OAAOzX,KAAK+4C,OAAQ,SAASvnC,GAChD,MAAOA,GAAKo+C,WAQpByQ,UAAW,SAAS36D,GAChB1F,KAAKmiB,MAAMzc,EAAKiC,QAAUjC,GAQ9Bga,QAAS,SAAS/X,GACd,MAAO3H,MAAKmiB,MAAMxa,IAAW,MAOjCgY,SAAU,WACN,MAAO3d,GAAMyV,OAAOzX,KAAKmiB,QAU7ByE,WAAY,SAASpV,EAAMxH,GACvB,UAUJ6d,YAAa,SAASrW,EAAMsX,EAAQ3iB,EAAO86D,KAQ3CxyC,YAAa,SAAStE,GACbA,IAGAnqB,KAAKwgE,QAAQr2C,EAAOxiB,UACrB3H,KAAKwgE,QAAQr2C,EAAOxiB,YAExB3H,KAAKwgE,QAAQr2C,EAAOxiB,QAAQwiB,EAAOuE,UAAYvE,IASnDC,UAAW,SAASziB,EAAQ+mB,GACxB,MAAK1uB,MAAKwgE,QAAQ74D,IAAY3H,KAAKwgE,QAAQ74D,GAAQ+mB,GAG5C1uB,KAAKwgE,QAAQ74D,GAAQ+mB,GAFjB,MAUfK,kBAAmB,SAASD,GACxB,IAAK9uB,KAAKujD,aACN,MAAO,KAEX,KACI,MAAOvjD,MAAKujD,aAAa2d,QAAQ,yBAA2BpyC,GAC9D,MAAO3wB,IACT,MAAO,OAQXkxB,kBAAmB,SAASP,EAAYJ,GACpC,GAAK1uB,KAAKujD,aAGV,IACIvjD,KAAKujD,aAAa4d,QAAQ,yBAA2BryC,EAAYJ,GACnE,MAAOvwB,MASbijE,uBAAwB,SAASt4C,GAC7B,GAAMzX,GAAOrR,IACb8oB,GAAOra,QAAQ,SAASmF,GACpBvC,EAAKs+C,YAAY/7C,EAAMwC,WAAaxC,KAS5CmM,eAAgB,SAASzW,GACrB,MAAOtJ,MAAK2vD,YAAYrmD,IAS5Bm0D,YAAa,SAASjsB,GAClB,MAAO39B,GAAA9T,QAAQ+T,WAMnBwsD,KAAM,aAMNL,QAAS,WACL,MAAOpsD,GAAA9T,QAAQ+T,WAQnBwpD,aAAc,WACV,MAAOzpD,GAAA9T,QAAQ+T,QAAQ,OAO3ByH,cAAe,WAgBX,MAfAvb,MAAK+4C,SAGL/4C,KAAKmiB,SAGLniB,KAAK61B,UAAY,KACjB71B,KAAKwgE,WAKLxgE,KAAK2vD,eAGE97C,EAAA9T,QAAQ+T,kFCxVvB,YAoBA,SAAS2uC,GAAuB4e,GAE5B,GADArhE,KAAKiR,MAAQowD,IACRr/D,EAAMiI,WAAWo3D,EAASH,UAC1Bl/D,EAAMiI,WAAWo3D,EAASF,UAC1Bn/D,EAAMiI,WAAWo3D,EAASC,aAC1Bt/D,EAAMiI,WAAWo3D,EAASr9C,MACC,gBAArBq9C,GAASliE,QAEhB,KAAM,IAAIL,OACN,gEAyJZ,QAASyiE,GAA0B55D,GAC/B,MAAO65D,GAAa,WAAa75D,EAGrC,QAAS85D,GAAoBptC,GACzB,MAAOmtC,GAAa,YAAcntC,EAGtC,QAASqtC,GAA+BztC,EAAWhwB,GAC/C,MAAOu9D,GAAa,wBAA0BvtC,EAAY,IAAMhwB,EAGpE,QAAS09D,GAAgB56D,GACrB,MAAOy6D,GAAa,SAAWz6D,EAGnC,QAAS66D,GAAY3wD,EAAO+S,GACxB,IAGI,MAAOqU,MAAKrM,MAAM/a,EAAMiwD,QAAQl9C,IAClC,MAAO7lB,GACLmmD,EAAS,2BAA4BtgC,EAAK7lB,GAC1CmmD,EAASnmD,EAAEwW,OAEf,MAAO,MAGX,QAASktD,GAAY5wD,EAAO+S,EAAKokB,GAC7Bn3B,EAAMkwD,QAAQn9C,GAAK,EAAAqG,EAAAtqB,SAAeqoC,IAGtC,QAASkc,KACL,GAAImX,EAAO,CAAA,GAAAC,IACPA,EAAAjnD,SAAQe,IAAR9U,MAAAg7D,EAAer7D,mHAlNjB2B,EAAQrD,EAAQ,eAEhB88D,GAAQ,EACR+F,EAAa,cAyBnB/e,GAAuBx/C,WAMnBg1B,qBAAsB,SAASP,GAC3B13B,KAAKiR,MAAMkwD,QAAQW,EAAwBpqC,IAO/CE,mBAAoB,WAChB,MAAO53B,MAAKiR,MAAMiwD,QAAQY,IAQ9BjrC,4BAA6B,SAASlvB,EAAQgH,GAC1CkzD,EAAY7hE,KAAKiR,MAAOswD,EAA0B55D,GAASgH,IAQ/DmlB,0BAA2B,SAASnsB,GAChC,MAAOi6D,GAAY5hE,KAAKiR,MAAOswD,EAA0B55D,KAG7D4tB,kCAAmC,SAASwsC,GACxCF,EAAY7hE,KAAKiR,MAAO+wD,EAA4CD,IAGxE3uC,gCAAiC,WAC7B,MAAOwuC,GAAY5hE,KAAKiR,MAAO+wD,IAWnClwB,6BAA8B,SAAS3rC,GACnC07D,EAAY7hE,KAAKiR,MAAOgxD,EAAkC97D,IAQ9DwrC,2BAA4B,WACxB,MAAOiwB,GAAY5hE,KAAKiR,MAAOgxD,IASnC3oC,qBAAsB,SAASjF,EAAWpwB,EAAWM,GACjD,GAAM00B,GAAWj5B,KAAKk5B,oBAAoB7E,MAC1C4E,GAASh1B,GAAaM,EACtBs9D,EACI7hE,KAAKiR,MAAOwwD,EAAoBptC,GAAY4E,IAUpDC,oBAAqB,SAAS7E,GAC1B,MAAOutC,GAAY5hE,KAAKiR,MAAOwwD,EAAoBptC,KAQvDsc,sCAAuC,WAGnC,IAAK,GAFCruC,GAASk/D,EAAa,wBACtB10C,KACGluB,EAAI,EAAGA,EAAIoB,KAAKiR,MAAM9R,OAAQP,IAAK,CACxC,GAAMolB,GAAMhkB,KAAKiR,MAAM+S,IAAIplB,EACtBolB,GAAIk+C,WAAW5/D,IAQpBwqB,EAAOlW,MACHqd,UAAWjQ,EAAIlT,OAAOxO,EAAOnD,OAAQ,IACrC8E,UAAW+f,EAAIlT,OAAOxO,EAAOnD,OAAS,MAG9C,MAAO2tB,IAGXqR,+BAAgC,SAASlK,EAAWhwB,GAChD,GAAM+f,GAAM09C,EAA+BztC,EAAWhwB,EACtD,OAAOjE,MAAKiR,MAAMiwD,QAAQl9C,IAG9Bia,iCAAkC,SAAShK,EAAWhwB,EAAWk1B,GAC7D,GAAMnV,GAAM09C,EAA+BztC,EAAWhwB,EACtD,OAAOjE,MAAKiR,MAAMkwD,QAAQn9C,EAAKmV,IAQnCmX,kBAAmB,SAASvpC,EAAQo7D,GAChCN,EAAY7hE,KAAKiR,MAAO0wD,EAAgB56D,GAASo7D,IAQrDhjD,gBAAiB,SAASpY,GACtB,MAAO66D,GAAY5hE,KAAKiR,MAAO0wD,EAAgB56D,KAIvD,IAAM+6D,GAAyBN,EAAa,UACtCS,EAAmCT,EAAa,oBAChDQ,EAA6CR,EAAa,iBAyChEniE,GAAOJ,QAAUwjD,qFC5NjB,YAWA,SAASvxC,KACLlR,KAAKoiE,UAAY,KAXrB,GAAAhoD,GAAAzb,EAAA,kEAcAuS,GAAUjO,WAMNw9D,aAAc,WACV,MAAOzgE,MAAKoiE,WAOhB1B,aAAc,SAASv6D,GACnBnG,KAAKoiE,UAAYj8D,GAOrBw6D,WAAY,SAASC,KAQrBrhD,SAAU,SAASrY,GACf,MAAO,OAOXsY,UAAW,WACP,UAOJqhD,UAAW,SAASrvD,KAQpBC,QAAS,SAAS1K,GACd,MAAO,OAOX0Y,SAAU,WACN,UAOJyF,WAAY,SAASne,KAQrBi6D,iBAAkB,WACd,UAOJX,UAAW,SAAS36D,KAQpBga,QAAS,SAAS/X,GACd,MAAO,OAOXgY,SAAU,WACN,UASJiH,WAAY,SAASpV,EAAMxH,GACvB,UAUJ6d,YAAa,SAASrW,EAAMsX,EAAQ3iB,EAAO86D,KAO3CxyC,YAAa,SAAStE,KAStBC,UAAW,SAASziB,EAAQ+mB,GACxB,MAAO,OAQXK,kBAAmB,SAASD,GACxB,MAAO,OAQXO,kBAAmB,SAASP,EAAYJ,KAQxC0yC,uBAAwB,SAASt4C,KAQjC/I,eAAgB,SAASzW,KAUzBm0D,YAAa,SAASjsB,GAClB,MAAO39B,GAAA9T,QAAQ+T,WAMnBwsD,KAAM,aAMNL,QAAS,WACL,MAAOpsD,GAAA9T,QAAQ+T,WAQnBwpD,aAAc,WACV,MAAOzpD,GAAA9T,QAAQ+T,QAAQ,OAQ3ByH,cAAe,WACX,MAAO1H,GAAA9T,QAAQ+T,YAKvBzU,EAAOJ,QAAUiS,sGCiRjB,QAASmxD,GAASC,EAAU1uD,GACA,OAApBA,EAAM01C,eAA0CroD,KAApB2S,EAAM01C,WAA4B11C,EAAMrO,OAGnE+8D,EAAS1uD,EAAMrO,QAChB+8D,EAAS1uD,EAAMrO,OAAQ,EAAAo5C,EAAA5+C,SAAc,OAEzCuiE,EAAS1uD,EAAMrO,MAAMqO,EAAM01C,WAAa11C,4MA9f5CyuB,EAAA1jC,EAAA,kBAaMujD,aAWF,QAAAA,GAAYngD,IAAM,EAAAjC,EAAAC,SAAAC,KAAAkiD,GACdngD,EAAOA,MACPA,EAAKwgE,mBAAqBxgE,EAAKwgE,oBAAsB,GACrDviE,KAAK+B,KAAOA,EACZ/B,KAAK2vD,eAGL3vD,KAAKwiE,eAGLxiE,KAAKyiE,aAkBLziE,KAAKg9D,UAAY,KAGjBh9D,KAAKk9D,QACD14C,UACA4d,QACAtd,kEAIG49C,GACP1iE,KAAK2iE,iBAAiBD,GACtB1iE,KAAK4iE,kBAAkBF,GACvB1iE,KAAK6iE,uBAAuBH,GAC5B1iE,KAAKg9D,UAAY0F,EAAav0D,0DAGXu0D,GAAc,GAAA9yC,GAAA5vB,IAC5B0iE,GAAatF,cAAiBsF,EAAatF,aAAat0C,QAI7D45C,EAAatF,aAAat0C,OAAOra,QAAQ,SAACtQ,GACtCyxB,EAAK+/B,YAAYxxD,EAAEoH,MAAQpH,6CAQlBukE,GAAc,GAAAxtC,GAAAl1B,IACtB0iE,GAAa3pB,QAGd2pB,EAAa3pB,MAAMv0B,SACnB,EAAA9Z,EAAA3K,SAAY2iE,EAAa3pB,MAAMv0B,QAAQ/V,QAAQ,SAAC1H,GAC5CmuB,EAAK4tC,gBACD/7D,EAAQ,SAAU27D,EAAa3pB,MAAMv0B,OAAOzd,MAIpD27D,EAAa3pB,MAAM3W,OACnB,EAAA13B,EAAA3K,SAAY2iE,EAAa3pB,MAAM3W,MAAM3zB,QAAQ,SAAC1H,GAC1CmuB,EAAK4tC,gBACD/7D,EAAQ,OAAQ27D,EAAa3pB,MAAM3W,KAAKr7B,MAIhD27D,EAAa3pB,MAAMj0B,QACnB,EAAApa,EAAA3K,SAAY2iE,EAAa3pB,MAAMj0B,OAAOrW,QAAQ,SAAC1H,GAC3CmuB,EAAK4tC,gBACD/7D,EAAQ,QAAS27D,EAAa3pB,MAAMj0B,MAAM/d,+CAM1CA,EAAQg8D,EAAU99D,GAY9B,OAAQ89D,GACJ,IAAK,SACD/iE,KAAKgjE,uBAAuBj8D,EAAQ9B,EACpC,MACJ,KAAK,OACGjF,KAAKwiE,YAAYz7D,UAIV/G,MAAKwiE,YAAYz7D,GAG5B/G,KAAKijE,qBAAqBl8D,EAAQ9B,EAClC,MACJ,KAAK,QACGjF,KAAKwiE,YAAYz7D,SACV/G,MAAKwiE,YAAYz7D,SAEjB/G,MAAKyiE,UAAU17D,EAE1B,MACJ,SACI0N,QAAQC,MAAM,sBAAuBquD,mDAI1Bh8D,EAAQ9B,GAC3B,GAAKA,EAAKi+D,cAAiBj+D,EAAKi+D,aAAap6C,OAA7C,CAGA,IAAK9oB,KAAKwiE,YAAYz7D,GAIlB,YAHA/G,KAAKwiE,YAAYz7D,IACbm8D,aAAcj+D,EAAKi+D,cAO3B,IAAMC,GAAcnjE,KAAKwiE,YAAYz7D,EACrC9B,GAAKi+D,aAAap6C,OAAOra,QAAQ,SAACtQ,GAE9B,IAAK,GADDilE,IAAW,EACNxkE,EAAI,EAAGA,EAAIukE,EAAYD,aAAap6C,OAAO3pB,OAAQP,IAAK,CAC7D,GAAMykE,GAAUF,EAAYD,aAAap6C,OAAOlqB,EAC5CykE,GAAQ99D,OAASpH,EAAEoH,MAAQ89D,EAAQ/Z,WAAanrD,EAAEmrD,YAClD6Z,EAAYD,aAAap6C,OAAOlqB,GAAKT,EACrCilE,GAAW,GAGdA,GACDD,EAAYD,aAAap6C,OAAOlS,KAAKzY,mDAM5B4I,EAAQ9B,GAoCpBjF,KAAKyiE,UAAU17D,KAGhB/G,KAAKyiE,UAAU17D,IACXu8D,eAAe,EAAA3kB,EAAA5+C,SAAc,MAC7B2jD,aACA6f,cAAc,EAAA5kB,EAAA5+C,SAAc,MAC5ByjE,wBACAC,kBAGR,IAAMN,GAAcnjE,KAAKyiE,UAAU17D,EAoFnC,IAlFI9B,EAAKm4D,cAAgBn4D,EAAKm4D,aAAat0C,QAEvC7jB,EAAKm4D,aAAat0C,OAAOra,QAAQ,SAACtQ,GAC9BglE,EAAYI,aAAaplE,EAAEoH,MAAQpH,IAKvC8G,EAAKy+D,uBACLP,EAAYK,qBAAuBv+D,EAAKy+D,sBAGxCz+D,EAAK0+D,WAAa1+D,EAAK0+D,UAAU76C,QACjC7jB,EAAK0+D,UAAU76C,OAAOra,QAAQ,SAACtQ,GASZ,cAAXA,EAAEoH,MAAyBpH,EAAE4K,UAejC,EAAA2B,EAAA3K,SAAY5B,EAAE4K,SAAS0F,QAAQ,SAAC5E,GACvB1L,EAAE4K,QAAQc,GAAS,YAGxB,EAAAa,EAAA3K,SAAY5B,EAAE4K,QAAQc,GAAS,WAAW4E,QAAQ,SAAC9G,GAE/Cw7D,EAAYM,cAAc97D,IACtB1C,KAAM9G,EAAE4K,QAAQc,GAAS,UAAUlC,GACnCkC,QAASA,SASzB5E,EAAK+jB,UAAY/jB,EAAK+jB,SAAS46C,UAC/BT,EAAYzf,cAOZz+C,EAAKiS,OAASjS,EAAKiS,MAAM4R,QACzB7jB,EAAKiS,MAAM4R,OAAOra,QAAQ,SAACtQ,GACvBkkE,EAASc,EAAYG,cAAenlE,KAGxC8G,EAAK+jB,UAAY/jB,EAAK+jB,SAASF,QAC/B7jB,EAAK+jB,SAASF,OAAOra,QAAQ,SAACtQ,EAAGy4C,GAE7ByrB,EAASc,EAAYG,cAAenlE,GAGpCglE,EAAYzf,UAAU9sC,MAClBhD,MAAOzV,EACPgI,MAAiB,IAAVywC,EAAc3xC,EAAK+jB,SAAS66C,WAAa,SAOxDV,EAAYzf,UAAUvkD,OAASa,KAAK+B,KAAKwgE,mBAIzC,IAAK,GAHCuB,GACFX,EAAYzf,UAAUvkD,OAASa,KAAK+B,KAAKwgE,mBAEpC3jE,EAAIklE,EAAYllE,EAAIukE,EAAYzf,UAAUvkD,OAAQP,IACvD,GAAIukE,EAAYzf,UAAU9kD,GAAGuH,MAAO,CAEhCg9D,EAAYzf,UAAYyf,EAAYzf,UAAU5yB,MAC1ClyB,EAAGukE,EAAYzf,UAAUvkD,OAE7B,kDAUEujE,GAAc,GAAA5sC,GAAA91B,IACvB0iE,GAAaxF,SAGdwF,EAAaxF,OAAO14C,SACpB,EAAA9Z,EAAA3K,SAAY2iE,EAAaxF,OAAO14C,QAAQ/V,QAAQ,SAACvH,GAC7C4uB,EAAKiuC,iBACD78D,EAAS,SAAUw7D,EAAaxF,OAAO14C,OAAOtd,MAItDw7D,EAAaxF,OAAO96B,OACpB,EAAA13B,EAAA3K,SAAY2iE,EAAaxF,OAAO96B,MAAM3zB,QAAQ,SAACvH,GAC3C4uB,EAAKiuC,iBACD78D,EAAS,OAAQw7D,EAAaxF,OAAO96B,KAAKl7B,MAIlDw7D,EAAaxF,OAAOp4C,QACpB,EAAApa,EAAA3K,SAAY2iE,EAAaxF,OAAOp4C,OAAOrW,QAAQ,SAACvH,GAC5C4uB,EAAKiuC,iBACD78D,EAAS,QAASw7D,EAAaxF,OAAOp4C,MAAM5d,gDAM3CA,EAAS67D,EAAU99D,GAChC,IAAA,GADsCm0D,IACnB,SAAU,OAAQ,SAArCC,EAAA,EAAAA,EAAAD,EAAAj6D,OAAAk6D,IAA+C,CAA1C,GAAM2K,GAAA5K,EAAAC,SACAr5D,MAAKk9D,OAAO8G,GAAK98D,GAE5BlH,KAAKk9D,OAAO6F,GAAU77D,GAAWjC,oCAiB3B,GAAA+wB,GAAAh2B,KACAiF,GACFm9B,QACA5d,UAYAM,WAEJ,EAAApa,EAAA3K,SAAYC,KAAKwiE,aAAa/zD,QAAQ,SAAC1H,GACnC9B,EAAKuf,OAAOzd,GAAUivB,EAAKwsC,YAAYz7D,MAE3C,EAAA2D,EAAA3K,SAAYC,KAAKyiE,WAAWh0D,QAAQ,SAAC1H,GACjC,GAAMk9D,GAAWjuC,EAAKysC,UAAU17D,GAC1Bm9D,GACFP,WAAa76C,WACbs0C,cAAgBt0C,WAChB5R,OAAS4R,WACTE,UACIF,UACA+6C,WAAY,MAEhBH,qBAAsBO,EAAST,uBAGnC,EAAA94D,EAAA3K,SAAYkkE,EAASV,cAAc90D,QAAQ,SAAC01D,GACxCD,EAAS9G,aAAat0C,OAAOlS,KAAKqtD,EAASV,aAAaY,KAI5D,IAAMC,IACF7+D,KAAM,YACNuF,QAAS/D,EACTgC,aAIJ,EAAA2B,EAAA3K,SAAYkkE,EAASR,eAAeh1D,QAAQ,SAAC9G,GACzC,GAAM08D,GAAcJ,EAASR,cAAc97D,EACtCy8D,GAAar7D,QAAQs7D,EAAYx6D,WAClCu6D,EAAar7D,QAAQs7D,EAAYx6D,UAC7BS,cAGR85D,EAAar7D,QAAQs7D,EAAYx6D,SAAS,UAAUlC,GAChD08D,EAAYp/D,QAIhB,EAAAyF,EAAA3K,SAAYqkE,EAAar7D,SAAS5J,OAAS,GAC3C+kE,EAASP,UAAU76C,OAAOlS,KAAKwtD,GAInCH,EAASvgB,UAAUj1C,QAAQ,SAAC61D,GACxB,IAAKJ,EAASl7C,SAAS66C,WAAY,CAG/B,IAAKS,EAAQn+D,MACT,MAEJ+9D,GAASl7C,SAAS66C,WAAaS,EAAQn+D,MAE3C+9D,EAASl7C,SAASF,OAAOlS,KAAK0tD,EAAQ1wD,QAO1C,KAAK,GADC2wD,IAAgB,EAAA5lB,EAAA5+C,SAAc,MAC3BnB,EAAIslE,EAASl7C,SAASF,OAAO3pB,OAAS,EAAGP,GAAI,EAAGA,IAAK,CAC1D,GAAM4lE,GAAgBN,EAASl7C,SAASF,OAAOlqB,EAC/C,IAAgC,OAA5B4lE,EAAclb,eACkBroD,KAA5BujE,EAAclb,UADtB,CAOA,GAAMmb,GAAiBtiC,EAAApiC,QAAMqiB,SAASoiD,EAClCC,GAAetyC,WACXsyC,EAAetyC,SAASg3B,eACxBsb,EAAe17D,QAAU07D,EAAetyC,SAASg3B,cAEjDsb,EAAetyC,SAASuyC,cACxBD,EAAe56B,OAAS46B,EAAetyC,SAASuyC,cAGxDrC,EAASkC,EAAeE,KAE5B,EAAA/5D,EAAA3K,SAAYkkE,EAASX,eAAe70D,QAAQ,SAAC01D,IACzC,EAAAz5D,EAAA3K,SAAYkkE,EAASX,cAAca,IAAS11D,QAAQ,SAAClF,GACjD,GAAI8O,GAAK4rD,EAASX,cAAca,GAAQ56D,EACpCg7D,GAAcJ,IAAWI,EAAcJ,GAAQ56D,KAE/C8O,EAAKksD,EAAcJ,GAAQ56D,IAE/B26D,EAAShtD,MAAM4R,OAAOlS,KAAKyB,OAGnCpT,EAAKm9B,KAAKr7B,GAAUm9D,GAIxB,IAAMS,KAKN,QAJA,EAAAj6D,EAAA3K,SAAYC,KAAK2vD,aAAalhD,QAAQ,SAAC01D,GACnCQ,EAAQ/tD,KAAKof,EAAK25B,YAAYwU,OAI9BnH,UAAWh9D,KAAKg9D,UAChBC,UAAWh4D,EACXk4D,WAAYn9D,KAAKk9D,OACjBvN,YAAagV,WAezBtlE,GAAOJ,QAAUijD,qNCtgBjB,gEA+BA,QAAS0iB,GAAcj9D,EAAQk9D,GAG3B,MAAO,eAAiBl9D,GAAUk9D,EAAS,IAAMA,EAAS,IAG9D,QAASvgB,KAAoB,GAAAoX,EACpBD,KAGLC,EAAAjnD,SAAQe,IAAR9U,MAAAg7D,EAAAr7D,WAiBJ,QAAS2a,GAAQrH,EAAQ5R,GACrB/B,KAAK2T,OAASA,EACd5R,EAAOA,MACPA,EAAK8tB,qBACyB5uB,KAA1Bc,EAAK8tB,iBAAiC,EAAI9tB,EAAK8tB,iBAEnD9tB,EAAK+iE,yBAA2B/iE,EAAK+iE,2BAA4B,EACjE/iE,EAAKgjE,YAAchjE,EAAKgjE,aAAgB,IACxChjE,EAAK0tD,qBAAuB1tD,EAAK0tD,sBAAwB,gBACpD1tD,EAAK+tB,yBACN/tB,EAAK+tB,uBAAyB,SAAS/oB,GACnC,OAAO,IAGf/G,KAAK+B,KAAOA,EACZ/B,KAAKglE,YAAc,KACnBhlE,KAAKilE,oBAAsB,KAC3BjlE,KAAKklE,WAAa,KAClBllE,KAAKmlE,aAAc,EACnBnlE,KAAKolE,UAAW,EAChBplE,KAAKqlE,gBAAkB,KACvBrlE,KAAKslE,yBAA2B,KAChCtlE,KAAKulE,gBACLvlE,KAAKwlE,iBAAmB,EAEpB7xD,EAAO2I,uBACP3I,EAAO5C,UAAU0I,OAAO9F,EAAO2I,uBACvB,gBAAiB,uBA+uCjC,QAASmpD,GAAc9xD,EAAQhM,GAC3B,GAAMjC,GAAO,GAAI68C,GAAK56C,EAKtB,OAJAgM,GAAO5C,UAAU0I,OAAO/T,GACpB,iBAAkB,mBAAoB,gBACtC,uBAAwB,wBAErBA,yNA/zCL68C,EAAO5jD,EAAQ,iBACfwjD,EAAOxjD,EAAQ,iBACfssD,EAAQtsD,EAAQ,kBAChBqD,EAAQrD,EAAQ,WAChBoc,EAASpc,EAAQ,YACjBic,EAAgBjc,EAAQ,2BAExB88D,GAAQ,CA2EdzgD,GAAQ/X,UAAU2D,WAAa,SAASG,GACpC,GAAM4M,GAAS3T,KAAK2T,OACdnC,EAAO,GAAI2wC,GAAKp7C,GAClB0oD,qBAAsBzvD,KAAK+B,KAAK0tD,qBAChC98C,gBAAiBgB,EAAOhB,iBAS5B,OAPAgB,GAAO5C,UAAU0I,OAAOjI,GAAO,YAAa,gBAAiB,iBACvC,eAAgB,YAChB,qBACA,wBACA,qBAEtBxR,KAAK0lE,wBAAwBl0D,GACtBA,GAOXwJ,EAAQ/X,UAAU6F,YAAc,SAAS5B,GACrC,GAAMyM,GAAS3T,KAAK2T,OACditD,EAAQ,GAAI3V,GAAM/jD,EAGxB,OAFAyM,GAAO5C,UAAU0I,OAAOmnD,GAAQ,gBAAiB,uBACjDjtD,EAAO1C,MAAM0vD,WAAWC,GACjBA,GAOX5lD,EAAQ/X,UAAUyiE,wBAA0B,SAASl0D,GACjD,GAAMmC,GAAS3T,KAAK2T,MAIpBA,GAAO5C,UAAU0I,OAAOjI,EAAKyN,cACzB,mBAAoB,oBAAqB,wBAE7CzN,EAAKyN,aAAatd,GAAG,sBAAuB,SAASiS,EAAOsD,EAAOytB,GAC/DA,EAAOj/B,KAAOiO,EAAO+L,QAAQilB,EAAOh9B,QACpCgM,EAAO5C,UAAU0I,OACbkrB,GAEI,kBAAmB,oBAAqB,wBACxC,6BAUhB3pB,EAAQ/X,UAAU0iE,0BAA4B,SAASn0D,GAEnDA,EAAKyN,aAAa2mD,mBAAmB,oBACrCp0D,EAAKyN,aAAa2mD,mBAAmB,qBACrCp0D,EAAKyN,aAAa2mD,mBAAmB,wBAQzC5qD,EAAQ/X,UAAUmrB,cAAgB,WAC9B,GAAMza,GAAS3T,KAAK2T,OACdtC,EAAOrR,KAGPmqB,EAAS,GAAIpP,GAAO/a,KAAK2T,OAAOxC,YAAYxJ,OAClDwiB,GAAOuwB,iBAAiB,GACxBvwB,EAAOwwB,sBAAqB,EAE5B,IAAM/3C,GAAiB5C,KAAK+B,KAAKgjE,YAlJZ,IAmJf51D,GACFoV,QAAS,EAGb,OAAO5Q,GAAOkb,kBACV+1C,EAAcjxD,EAAOxC,YAAYxJ,OAAQ,cAAewiB,GAC1DvmB,KAAK,SAAS8qB,GAEZ,MADAvf,GAAIgb,OAASuE,EACN/a,EAAO7Q,MAAMa,kBAChB1C,GAAW,MAAO,QAASkO,MAAKlO,GAAW2B,KAEhDgB,KAAK,SAASqB,GACb,GAAI4gE,KACA5gE,GAAK8zC,OAAS9zC,EAAK8zC,MAAMj0B,QACzB+gD,EAAax0D,EAAKy0D,4BAA4B7gE,EAAK8zC,MAAMj0B,OAE7D,IAAMi0B,KAiCN,OAhCA8sB,GAAWp3D,QAAQ,SAASs3D,GACxB,GAAMv0D,GAAOu0D,EAASv0D,IAEtB,IADAunC,EAAMniC,KAAKpF,GACNu0D,EAASC,eAAd,CAWAD,EAAS/8C,SAAW+8C,EAAS/8C,YAC7B,IAAMi9C,GACF50D,EAAK60D,qBAAqBH,EAAS/8C,SAAUxX,GAC3Cs2C,EAAcz2C,EAAK60D,qBAAqBH,EAAS7uD,MAAO1F,EAI9DA,GAAKmW,kBAAkBuC,mBAAmB67C,EAAS/8C,SAAS66C,WAClBjpD,EAAc8O,WAExDrY,EAAK80D,mBAAmB30D,EAAMs2C,EAAame,GAE3Cz0D,EAAK6hD,YAAY1/C,EAAOxC,YAAYxJ,QACpCgM,EAAO1C,MAAM4vD,UAAUrvD,GACvBmC,EAAOlT,KAAK,OAAQ+Q,GAEpBH,EAAK+0D,wBAAwB50D,EAAMy0D,MAEhCltB,KAWf/9B,EAAQ/X,UAAU0nB,KAAO,SAAS5jB,GAC9B,GAAMsK,GAAOrR,KACP2T,EAAS3T,KAAK2T,MAEpB,OADA3T,MAAKglE,YAAcj+D,EACZ/G,KAAK2T,OAAO5J,gBAAgBhD,EAAQ,IAAInD,KAAK,SAASC,GAEzDA,EAASyM,SAAWzM,EAASyM,aAC7BzM,EAASyM,SAASmX,MAAQ5jB,EAASyM,SAASmX,UAC5C5jB,EAASqT,MAAQrT,EAASqT,SAE1B,IAAMmvD,GAAWh1D,EAAKzK,WAAWG,GAI3BghD,EAAiB/lD,EAAMme,IACzBne,EAAMogB,SAASve,EAASqT,OAAQvD,EAAO0U,kBAErCy/B,EAAc9lD,EAAMme,IACtBtc,EAASqT,MAAOvD,EAAO0U,kBAErB/X,EAAWtO,EAAMme,IACnBtc,EAASyM,SAASmX,MAAO9T,EAAO0U,iBA8CpC,OAxCIxkB,GAAS0iB,UAAYvkB,EAAMuoC,QAAQ1mC,EAAS0iB,WAC5C1iB,EAAS0iB,SAASpG,IAAIxM,EAAO0U,kBAAkB5Z,QAC/C,SAAS63D,GACL,GAAI5gE,GAAOiO,EAAO1C,MAAMyO,QAAQ4mD,EAAczvD,aAAab,QACvDtQ,GACAA,EAAKuvD,iBAAiBqR,IAEtB5gE,EAAO+/D,EAAc9xD,EAAQ2yD,EAAczvD,aAAab,SACxDtQ,EAAKuvD,iBAAiBqR,GACtB3yD,EAAO1C,MAAMovD,UAAU36D,IAE3BiO,EAAOlT,KAAK,QAAS6lE,KAOzBziE,EAASyM,SAAS+Y,QAClBg9C,EAASl/C,SAASC,gBAAkBvjB,EAASyM,SAAS+Y,OAI1Dg9C,EAASl/C,SAAS8gC,eAAeF,GACjCse,EAASpnD,aAAagpC,eAAeH,GAErCz2C,EAAKk1D,gBAAgBF,GACrBA,EAAShT,YAAYhiD,EAAKsC,OAAOxC,YAAYxJ,QAK7C0+D,EAAS3+C,oBAAoBpX,EAASgY,WAAW,EACpB+9C,EAAS1+C,kBACT9jB,EAASyM,SAAS+Y,OAE/C1V,EAAO1C,MAAM4vD,UAAUwF,GACvB1yD,EAAOlT,KAAK,OAAQ4lE,GAEpBh1D,EAAKm1D,UAAUH,GACRA,KAQfrrD,EAAQ/X,UAAUynB,YAAc,WAC5B1qB,KAAKglE,YAAc,MAQvBhqD,EAAQ/X,UAAUujE,UAAY,SAASH,EAAUlgE,GAC7C,GAAInG,KAAKglE,cAAgBqB,EAASt/D,OAE9B,WADAu9C,GAAS,6BAA8B+hB,EAASt/D,OAIpD,IAAMsK,GAAOrR,IAEbA,MAAK2T,OAAO7Q,MAAMa,kBAAc1C,GAAW,MAAO,WAC9C6J,QAASu7D,EAASt/D,OAClBwd,QAAS,IACTnV,KAAMjJ,OACPlF,GAAW,KAAWK,KAAK,SAAS+S,GACnC,GAAIhD,EAAK2zD,cAAgBqB,EAASt/D,OAE9B,WADAu9C,GAAS,6BAA8B+hB,EAASt/D,OAYpDsN,GAAIoT,MAAM0C,OAAO,SAAShsB,GACtB,MAAkB,eAAXA,EAAEoH,OACV4a,IAAI9O,EAAKsC,OAAO0U,kBAAkB5Z,QAAQ,SAAS63D,GAClD,GAAI5gE,GAAO2L,EAAKsC,OAAO1C,MAAMyO,QAAQ4mD,EAAczvD,aAAab,QAC5DtQ,GACAA,EAAKuvD,iBAAiBqR,IAEtB5gE,EAAO+/D,EAAcp0D,EAAKsC,OAAQ2yD,EAAczvD,aAAab,SAC7DtQ,EAAKuvD,iBAAiBqR,GACtBj1D,EAAKsC,OAAO1C,MAAMovD,UAAU36D,IAEhC2L,EAAKsC,OAAOlT,KAAK,QAAS6lE,IAI9B,IAAMx9C,GAASzU,EAAIoT,MAAM0C,OAAO,SAAShsB,GACrC,MAAOA,GAAE2M,UAAYu7D,EAASt/D,SAC/BoZ,IAAI9O,EAAKsC,OAAO0U,iBAEnBg+C,GAASrT,cAAclqC,GACvBzX,EAAKm1D,UAAUH,EAAUhyD,EAAIuT,MAC9B,SAAShmB,GACR6S,QAAQC,MAAM,4BAA6B2xD,EAASt/D,OAAQnF,GAC5DoX,WAAW,WACP3H,EAAKm1D,UAAUH,EAAUlgE,IAC1B,QASX6U,EAAQ/X,UAAUiZ,aAAe,WAC7B,MAAOlc,MAAKklE,YAMhBlqD,EAAQ/X,UAAU+sB,KAAO,WAiBrB,QAAS1iB,KACLqG,EAAOrG,eAAehM,KAAK,SAASwrB,GAChCw3B,EAAS,kBACT3wC,EAAO0Y,UAAYS,EACnB1C,KACD,SAASxoB,GACRyP,EAAKo1D,mBAAmBnlE,KAAK,WACzBgM,MAEJ+D,EAAKq1D,iBAAiB,SAAWhyD,MAAO9S,MAIhD,QAASwoB,KACL,GAAID,OAAA,EACA9Y,GAAKtP,KAAKooB,OACVA,EAAS9Y,EAAKtP,KAAKooB,QAEnBA,EAAS,GAAIpP,GAAOpH,EAAOxC,YAAYxJ,QACvCwiB,EAAOuwB,iBAAiBrpC,EAAKtP,KAAK8tB,mBAGtClc,EAAOkb,kBACH+1C,EAAcjxD,EAAOxC,YAAYxJ,QAASwiB,GAC5C7oB,KAAK,SAASotB,GAKZ/a,EAAO4W,wBAEPlZ,EAAKs1D,OAAQj4C,SAAUA,KACxB,SAAS9sB,GACRyP,EAAKo1D,mBAAmBnlE,KAAK,WACzB8oB,MAEJ/Y,EAAKq1D,iBAAiB,SAAWhyD,MAAO9S,MApDhD,GAAM+R,GAAS3T,KAAK2T,OACdtC,EAAOrR,IAEbA,MAAKolE,UAAW,EAEZ3lE,EAAOmnE,WACP5mE,KAAK6mE,eAAiB7mE,KAAK8mE,UAAUrlE,KAAKzB,MAC1CP,EAAOmnE,SAAS5pB,iBAAiB,SAAUh9C,KAAK6mE,gBAAgB,IAiDhElzD,EAAO4E,UAEPlH,EAAKs1D,UAELr5D,KAOR0N,EAAQ/X,UAAUsX,KAAO,WACrB+pC,EAAS,gBACL7kD,EAAOmnE,WACPnnE,EAAOmnE,SAASG,oBAAoB,SAAU/mE,KAAK6mE,gBAAgB,GACnE7mE,KAAK6mE,mBAAiB5lE,IAE1BjB,KAAKolE,UAAW,EACZplE,KAAKilE,qBACLjlE,KAAKilE,oBAAoBzoB,QAEzBx8C,KAAKqlE,kBACLn1C,aAAalwB,KAAKqlE,iBAClBrlE,KAAKqlE,gBAAkB,OAS/BrqD,EAAQ/X,UAAUoZ,iBAAmB,WACjC,QAAKrc,KAAKslE,2BAGVtlE,KAAKymE,iBAAiB,IACf,IASXzrD,EAAQ/X,UAAU0jE,MAAlB,WAAA,GAAA3/B,IAAA,EAAA5sB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA0B,QAAAC,GAAeoqD,GAAf,GAAArzD,GAAA+a,EAAAmH,EAAAkvC,EAAAkC,EAAA93D,EAAA+3D,EAAAC,EAAAliE,EAAAmiE,CAAA,OAAAptD,GAAAja,QAAAka,KAAA,SAAA6C,GAAA,OAAA,OAAAA,EAAA3C,KAAA2C,EAAAzb,MAAA,IAAA,GAAA,GAChBsS,EAAS3T,KAAK2T,OAEf3T,KAAKolE,SAHY,CAAAtoD,EAAAzb,KAAA,CAAA,OAAA,MAIlBijD,GAAS,oCACLtkD,KAAKslE,2BACLtlE,KAAKslE,yBAAyBnsD,SAC9BnZ,KAAKslE,yBAA2B,MAEpCtlE,KAAK0mE,iBAAiB,WATJ5pD,EAAAC,OAAA,SAAA,KAAA,GAAA,GAalB2R,EAAWs4C,EAAYt4C,SACvB/a,EAAO4E,YAAcmW,IACrBA,EAAW1uB,KAAKqnE,mBAGdxxC,EAAYliB,EAAO1C,MAAMwvD,eAE3BsE,EAAc/kE,KAAK+B,KAAKgjE,aAEA,YAAxB/kE,KAAKkc,gBAAgClc,KAAKmlE,eAY1CnlE,KAAKmlE,aAAc,EACnBJ,EAAc,GAIZkC,EAAsBlC,EApfP,IAsff51D,GACFgb,OAAQuE,EACRnK,QAASwgD,GAGTlvC,EACA1mB,EAAIm4D,MAAQzxC,EAKZ1mB,EAAIo4D,aAAehkE,KAAKyjB,MAGD,SAAvBhnB,KAAKkc,gBAAoD,gBAAvBlc,KAAKkc,iBAKvC/M,EAAIoV,QAAU,GAGd2iD,MA/DkB,GAgEjBF,EAAYQ,gBAhEK,CAAA1qD,EAAAzb,KAAA,EAAA,OAAA,MAAAyb,GAAAzb,KAAA,IAAA,EAAA+Y,EAAAtG,SAmEAH,EAAO1C,MAAMqsD,eAnEb,KAAA,IAmElB4J,EAnEkBpqD,EAAAxC,IAAA,KAAA,IAAA,GAsElB6sD,GAAmB,EACnBliE,MAvEkB,IAyElBiiE,EAzEkB,CAAApqD,EAAAzb,KAAA,EAAA,OA0ElBijD,EAAS,mEACT6iB,GAAmB,EACnBliE,GACIkJ,WAAY+4D,EAAUlK,UACtBjkB,MAAOmuB,EAAUjK,UACjBC,OAAQgK,EAAU/J,WAClBC,cACIt0C,OAAQo+C,EAAUvX,cAjFR7yC,EAAAzb,KAAA,EAAA,MAAA,KAAA,IAAA,MAAAyb,GAAA3C,KAAA,GAuFdna,KAAKilE,oBAAsBtxD,EAAO7Q,MAAMa,kBACpC1C,GAAW,MAAO,QAASkO,MAAKlO,GAAWgmE,GAxFjCnqD,EAAAzb,KAAA,IAAA,EAAA+Y,EAAAtG,SA0FD9T,KAAKilE,oBA1FJ,KAAA,IA0FdhgE,EA1Fc6X,EAAAxC,KAAAwC,EAAAzb,KAAA,EAAA,MAAA,KAAA,IAAA,MAAAyb,GAAA3C,KAAA,GAAA2C,EAAA6U,GAAA7U,EAAA,MAAA,IA4Fd9c,KAAKynE,aAAL3qD,EAAA6U,GAAqBq1C,GA5FPlqD,EAAAC,OAAA,SAAA,KAAA,IAAA,GAsGtBpJ,EAAO1C,MAAMyvD,aAAaz7D,EAAKkJ,YAG/BnO,KAAKwlE,iBAAmB,EAMnB2B,EA/GiB,CAAArqD,EAAAzb,KAAA,EAAA,OAAA,MAAAyb,GAAAzb,KAAA,IAAA,EAAA+Y,EAAAtG,SAiHZH,EAAO1C,MAAMwsD,YAAYx4D,GAjHb,KAAA,IAAA,MAAA6X,GAAA3C,KAAA,GAAA2C,EAAAzb,KAAA,IAAA,EAAA+Y,EAAAtG,SAqHZ9T,KAAK0nE,qBAAqB7xC,EAAW5wB,EAAMkiE,GArH/B,KAAA,IAAArqD,EAAAzb,KAAA,EAAA,MAAA,KAAA,IAAAyb,EAAA3C,KAAA,GAAA2C,EAAA8U,GAAA9U,EAAA,MAAA,IAyHlBrI,QAAQC,MAAM,qBAAsBoI,EAAA8U,GAAEjd,OAAFmI,EAAA8U,GAzHlB,KAAA,IAAA,GA6HhBw1C,GACF11B,aAAc7b,EACd4b,cAAexsC,EAAKkJ,WACpB4jC,WAAY/xC,KAAKmlE,aAGhB6B,EAAYQ,kBACbxnE,KAAK0mE,iBAAiB,WAAYU,GAClCJ,EAAYQ,iBAAkB,GAG7BL,EAxIiB,CAAArqD,EAAAzb,KAAA,EAAA,OAAA,IA2IdrB,KAAK+B,KAAK8a,OA3II,CAAAC,EAAAzb,KAAA,EAAA,OAAA,MAAAyb,GAAAzb,KAAA,IAAA,EAAA+Y,EAAAtG,SA4IR9T,KAAK+B,KAAK8a,OAAO00B,gBAAgB61B,GA5IzB,KAAA,IAgJlBpnE,KAAK0mE,iBAAiB,UAAWU,GAKjCzzD,EAAO1C,MAAMqvD,MArJK,KAAA,IAyJtBtgE,KAAK2mE,MAAMK,EAzJW,KAAA,IAAA,IAAA,MAAA,MAAAlqD,GAAAvC,SAAAqC,EAAA5c,OAAA,GAAA,KAAA,GAAA,QAA1B,OAAA,UAAA0d,GAAA,MAAAspB,GAAAtmC,MAAAV,KAAAK,eA4JA2a,EAAQ/X,UAAUwkE,aAAe,SAAS7lE,EAAKolE,GAAa,GAAAp3C,GAAA5vB,IACxD,KAAKA,KAAKolE,SAON,MANA9gB,GAAS,mCACLtkD,KAAKslE,2BACLtlE,KAAKslE,yBAAyBnsD,SAC9BnZ,KAAKslE,yBAA2B,UAEpCtlE,MAAK0mE,iBAAiB,UAI1BjyD,SAAQC,MAAM,iBAAkB9S,GAChC6S,QAAQC,MAAM9S,GAEd5B,KAAKwlE,mBACL/wD,QAAQe,IAAI,8CAA+CxV,KAAKwlE,kBAEhElhB,EAAS,uBAQTtkD,KAAKymE,mBAAmB7iE,KAAK,WACzBgsB,EAAK+2C,MAAMK,KAGfhnE,KAAKilE,oBAAsB,KAE3BjlE,KAAK0mE,iBACD1mE,KAAKwlE,kBApoBuB,EAqoBxB,QAAU,iBAatBxqD,EAAQ/X,UAAUykE,qBAAlB,WAAA,GAAAjqD,IAAA,EAAArD,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAAyC,QAAAysB,GACrCvT,EAAW5wB,EAAMkiE,GADoB,GAAAxzD,GAAAtC,EAAAyX,EAAA05C,EAAAC,EAAAoD,EAAAr2B,CAAA,OAAAx1B,GAAAja,QAAAka,KAAA,SAAAovB,GAAA,OAAA,OAAAA,EAAAlvB,KAAAkvB,EAAAhoC,MAAA,IAAA,GAAA,MAG/BsS,GAAS3T,KAAK2T,OACdtC,EAAOrR,KAwDTiF,EAAKshB,UAAYvkB,EAAMuoC,QAAQtlC,EAAKshB,SAASuC,SAC7C7jB,EAAKshB,SAASuC,OAAO3I,IAAIxM,EAAO0U,kBAAkB5Z,QAClD,SAAS63D,GACL,GAAI5gE,GAAOiO,EAAO1C,MAAMyO,QAAQ4mD,EAAcvvD,YAC1CrR,GACAA,EAAKuvD,iBAAiBqR,IAEtB5gE,EAAO+/D,EAAc9xD,EAAQ2yD,EAAcvvD,aAC3CrR,EAAKuvD,iBAAiBqR,GACtB3yD,EAAO1C,MAAMovD,UAAU36D,IAE3BiO,EAAOlT,KAAK,QAAS6lE,KAKzBrhE,EAAKm4D,cAAgBp7D,EAAMuoC,QAAQtlC,EAAKm4D,aAAat0C,UAC/CA,EAAS7jB,EAAKm4D,aAAat0C,OAAO3I,IAAIxM,EAAO0U,kBACnD1U,EAAO1C,MAAMmwD,uBAAuBt4C,GACpCA,EAAOra,QACH,SAASk5D,GAWL,MAJkC,gBAA9BA,EAAiBvxD,WAAgC+wD,IACjDxzD,EAAO0Y,UAAYs7C,EAAiB9wD,cAExClD,EAAOlT,KAAK,cAAeknE,GACpBA,KAMf1iE,EAAK2iE,WAAa5lE,EAAMuoC,QAAQtlC,EAAK2iE,UAAU9+C,SAC/C7jB,EAAK2iE,UAAU9+C,OAAO3pB,OAAS,EAE/B8F,EAAK2iE,UAAU9+C,OACV3I,IAAIxM,EAAO0U,kBACX5Z,QACG,SAASo5D,GACL,GAAM9+D,GAAU8+D,EAAchxD,YAC9B,IAC+B,kBAA3BgxD,EAAczxD,WACS,mBAAnBrN,EAAQ4Z,QAOZ,WAJAlO,SAAQe,IACJ,+CACIqyD,EAAc9wD,YAK1BpD,GAAOlT,KAAK,gBAAiBonE,KAKzC7nE,KAAKmlE,aAAc,EAGnBlgE,EAAKi4D,SACDj4D,EAAKi4D,OAAO14C,QACZxkB,KAAK8nE,uBAAuB7iE,EAAKi4D,OAAO14C,OAAQ,UAGhDvf,EAAKi4D,OAAO96B,MACZpiC,KAAK8nE,uBAAuB7iE,EAAKi4D,OAAO96B,KAAM,QAG9Cn9B,EAAKi4D,OAAOp4C,OACZ9kB,KAAK8nE,uBAAuB7iE,EAAKi4D,OAAOp4C,MAAO,UAOnD09C,KACAC,KACAoD,KAEA5gE,EAAK8zC,QACD9zC,EAAK8zC,MAAMv0B,SACXg+C,EAAcxiE,KAAK8lE,4BAA4B7gE,EAAK8zC,MAAMv0B,SAE1Dvf,EAAK8zC,MAAM3W,OACXqgC,EAAYziE,KAAK8lE,4BAA4B7gE,EAAK8zC,MAAM3W,OAExDn9B,EAAK8zC,MAAMj0B,QACX+gD,EAAa7lE,KAAK8lE,4BAA4B7gE,EAAK8zC,MAAMj0B,SAIjE9kB,KAAKulE,gBAGL/C,EAAY/zD,QAAQ,SAASs5D,GACzB,GAAMv2D,GAAOu2D,EAAUv2D,KACjBs2C,EACFz2C,EAAK60D,qBAAqB6B,EAAU7E,aAAc1xD,EACtDH,GAAK80D,mBAAmB30D,EAAMs2C,GAC1BigB,EAAU/B,iBACVx0D,EAAK6hD,YAAY1/C,EAAOxC,YAAYxJ,QACpCgM,EAAO1C,MAAM4vD,UAAUrvD,GACvBmC,EAAOlT,KAAK,OAAQ+Q,IAExBs2C,EAAYr5C,QAAQ,SAAStQ,GACzBwV,EAAOlT,KAAK,QAAStC,OA5KQkrC,EAAAhoC,KAAA,IAAA,EAAA+Y,EAAAtG,SAiL/BD,EAAA9T,QAAQioE,UAAUvF,EAAlB,WAAA,GAAA7kD,IAAA,EAAAxD,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAA6B,QAAA+B,GAAeupD,GAAf,GAAAz2D,GAAAs2C,EAAAme,EAAAiC,EAAAC,EAAAvE,EAAAhlE,EAAAiL,EAAAu+D,EAAA,WAAA,GAAAj/B,IAAA,EAAA/uB,EAAAsC,WAAA1C,EAAAja,QAAA4c,KAgG/B,QAAAhD,GAAgCxb,GAAhC,MAAA6b,GAAAja,QAAAka,KAAA,SAAAC,GAAA,OAAA,OAAAA,EAAAC,KAAAD,EAAA7Y,MAAA,IAAA,GAAA,GACIsS,EAAOlT,KAAK,QAAStC,IACjBA,EAAEkX,WAA4B,qBAAflX,EAAEiY,YAAoC/E,EAAKtP,KAAK8a,OAFvE,CAAA3C,EAAA7Y,KAAA,CAAA,OAAA,MAAA6Y,GAAA7Y,KAAA,GAAA,EAAA+Y,EAAAtG,SAGczC,EAAKtP,KAAK8a,OAAOy0B,cAAcnzC,GAH7C,KAAA,GAAA,IAAA,MAAA,MAAA+b,GAAAK,SAAAZ,EAAA3Z,QAhG+B,OAAA,UAAAm7B,GAAA,MAAAgO,GAAAzoC,MAAAV,KAAAK,cAAA,OAAA2Z,GAAAja,QAAAka,KAAA,SAAA2E,GAAA,OAAA,OAAAA,EAAAzE,KAAAyE,EAAAvd,MAAA,IAAA,GAAA,GACzBmQ,EAAOy2D,EAAQz2D,KACfs2C,EAAcz2C,EAAK60D,qBAAqB+B,EAAQ/wD,MAAO1F,GACvDy0D,EAAiB50D,EAAK60D,qBAAqB+B,EAAQj/C,SAAUxX,GAC7D02D,EAAkB72D,EAAK60D,qBAAqB+B,EAAQtE,WACpDwE,EAAoB92D,EAAK60D,qBAAqB+B,EAAQ7K,cAGxD6K,EAAQvE,uBACRlyD,EAAK8/C,2BACD,QAAS2W,EAAQvE,qBAAqB2E,oBAE1C72D,EAAK8/C,2BACD,YAAa2W,EAAQvE,qBAAqB4E;kFAIlDL,EAAQj/C,SAAWi/C,EAAQj/C,cAEvBi/C,EAAQjC,eAnBmB,CAAApnD,EAAAvd,KAAA,EAAA,OAsB3BmQ,EAAKmW,kBAAkBuC,mBACnB+9C,EAAQj/C,SAAS66C,WAAYjpD,EAAc8O,WAvBpB9K,EAAAvd,KAAA,EAAA,MAAA,KAAA,IAAA,IAwBpB4mE,EAAQj/C,SAAS46C,QAxBG,CAAAhlD,EAAAvd,KAAA,EAAA,OAyBvBuiE,GAAU,EAcLhlE,EAAIqnE,EAAe9mE,OAAS,CAvCV,KAAA,IAAA,KAuCaP,GAAK,GAvClB,CAAAggB,EAAAvd,KAAA,EAAA,OAAA,GAwCjBwI,EAAUo8D,EAAernE,GAAG6kB,SAC9BjS,EAAKoX,oBAAoB/e,GAzCN,CAAA+U,EAAAvd,KAAA,EAAA,OAAA,MA0CnBijD,GAAS,sBAAwBz6C,EAAU,oCAE3C+5D,GAAU,EAKVqC,EAAe3tB,OAAO,EAAG15C,GAjDNggB,EAAA7B,OAAA,QAAA,GAAA,KAAA,IAuCqBne,IAvCrBggB,EAAAvd,KAAA,EAAA,MAAA,KAAA,IA8DvBuiE,IACAvyD,EAAKs0D,0BAA0Bn0D,GAC/BA,EAAKgZ,kBACDy9C,EAAQj/C,SAAS66C,WACjBxyD,EAAKtP,KAAK+tB,uBAAuBte,EAAKzK,QAAU,KAAO8uB,GAM3DliB,EAAO4W,wBAEPlZ,EAAKq0D,wBAAwBl0D,GA1EN,KAAA,IAAA,MA8E/BH,GAAK80D,mBAAmB30D,EAAMs2C,EAAame,GAK3Cz0D,EAAKwhD,cAAckV,GAGnB12D,EAAKgjD,eAAe2T,GAEpB32D,EAAK6hD,YAAY1/C,EAAOxC,YAAYxJ,QAChCsgE,EAAQjC,iBACRryD,EAAO1C,MAAM4vD,UAAUrvD,GACvBmC,EAAOlT,KAAK,OAAQ+Q,IAGxBH,EAAK+0D,wBAAwB50D,EAAMy0D,GA9FJrnD,EAAAvd,KAAA,IAAA,EAAA+Y,EAAAtG,SAuGzBD,EAAA9T,QAAQioE,UAAUlgB,EAAasgB,GAvGN,KAAA,IAAA,MAAAxpD,GAAAvd,KAAA,IAAA,EAAA+Y,EAAAtG,SAwGzBD,EAAA9T,QAAQioE,UAAU/B,EAAgBmC,GAxGT,KAAA,IAyG/BF,EAAgBz5D,QAAQ,SAAStQ,GAC7BwV,EAAOlT,KAAK,QAAStC,KAEzBgqE,EAAkB15D,QAAQ,SAAStQ,GAC/BwV,EAAOlT,KAAK,QAAStC,IA7GM,KAAA,IAAA,IAAA,MAAA,MAAAygB,GAAArE,SAAAmE,EAAA1e,QAA7B,OAAA,UAAAk7B,GAAA,MAAAtd,GAAAld,MAAAV,KAAAK,gBAjL+B,KAAA,IAAA,GAmSrCwlE,EAAWp3D,QAAQ,SAASs3D,GACxB,GAAMv0D,GAAOu0D,EAASv0D,KAChBs2C,EACFz2C,EAAK60D,qBAAqBH,EAAS7uD,MAAO1F,GACxCy0D,EACF50D,EAAK60D,qBAAqBH,EAAS/8C,SAAUxX,GAC3C22D,EACF92D,EAAK60D,qBAAqBH,EAAS3I,aAEvC/rD,GAAK80D,mBAAmB30D,EAAMs2C,EAAame,GAC3Cz0D,EAAKgjD,eAAe2T,GAEpB32D,EAAK6hD,YAAY1/C,EAAOxC,YAAYxJ,QAChCo+D,EAASC,iBACTryD,EAAO1C,MAAM4vD,UAAUrvD,GACvBmC,EAAOlT,KAAK,OAAQ+Q,IAGxBH,EAAK+0D,wBAAwB50D,EAAMy0D,GAEnCne,EAAYr5C,QAAQ,SAAStQ,GACzBwV,EAAOlT,KAAK,QAAStC,KAEzB8nE,EAAex3D,QAAQ,SAAStQ,GAC5BwV,EAAOlT,KAAK,QAAStC,KAEzBgqE,EAAkB15D,QAAQ,SAAStQ,GAC/BwV,EAAOlT,KAAK,QAAStC,OASzB03B,GAAa71B,KAAKulE,aAAapmE,SAC/Ba,KAAKulE,aAAa5pC,KAAK,SAASj9B,EAAGmlD,GAC/B,MAAOnlD,GAAE6qC,QAAUsa,EAAEta,UAEzBvpC,KAAKulE,aAAa92D,QAAQ,SAASmF,GAC/BD,EAAO2I,sBAAsB6pC,aAAavyC,OAK9C3O,EAAKsjE,aAjV4B,CAAAl/B,EAAAhoC,KAAA,EAAA,OAAA,IAkV7BrB,KAAK+B,KAAK8a,OAlVmB,CAAAwsB,EAAAhoC,KAAA,EAAA,OAAA,MAAAgoC,GAAAhoC,KAAA,IAAA,EAAA+Y,EAAAtG,SAmVvB9T,KAAK+B,KAAK8a,OAAOm0B,wBAAwB/rC,EAAKsjE,cAnVvB,KAAA,IAAAl/B,EAAAhoC,KAAA,EAAA,MAAA,KAAA,IA4VjCrB,KAAK+B,KAAK8a,QAAU5X,EAAKujE,6BACnBh5B,EAAevqC,EAAKujE,2BAA2B/5B,mBAAqB,EAC1EzuC,KAAK+B,KAAK8a,OAAO0yB,sBAAsBC,GA9VN,KAAA,IAAA,IAAA,MAAA,MAAAnG,GAAA9uB,SAAA6uB,EAAAppC,QAAzC,OAAA,UAAA6d,EAAAC,EAAA0c,GAAA,MAAA/c,GAAA/c,MAAAV,KAAAK,eAyWA2a,EAAQ/X,UAAUwjE,iBAAmB,SAASl/C,OAC5BtmB,KAAVsmB,IACAA,EAAQ,IAAON,KAAKyJ,MAAsB,IAAhBzJ,KAAK0J,WAGN,OAAzB3wB,KAAKqlE,iBACLn1C,aAAalwB,KAAKqlE,gBAEtB,IAAMh0D,GAAOrR,IAYb,OAXIunB,GAAQ,EACRlW,EAAKg0D,gBAAkBrsD,WACnB3H,EAAKo3D,eAAehnE,KAAK4P,GACzBkW,GAGJlW,EAAKo3D,iBAEJzoE,KAAKslE,2BACNtlE,KAAKslE,yBAA2BzxD,EAAA9T,QAAQmZ,SAErClZ,KAAKslE,yBAAyBx5D,SAUzCkP,EAAQ/X,UAAUwlE,eAAiB,WAE/B,QAASnzC,KACLpF,aAAa7e,EAAKg0D,iBACdh0D,EAAKi0D,2BACLj0D,EAAKi0D,yBAAyBxxD,UAC9BzC,EAAKi0D,yBAA2B,MALxC,GAAMj0D,GAAOrR,IASbA,MAAK2T,OAAO7Q,MAAMvD,YACd0B,GACA,MAAO,+BACPA,OACAA,IAEIqB,OAAQ,GACRM,eAAgB,OAEtBtB,KAAK,WACHg0B,KACD,SAAS1zB,GACc,KAAlBA,EAAI0tB,WAMJje,EAAKg0D,gBAAkBrsD,WAAWsc,EAAS,MAE3CjkB,EAAKg0D,gBAAkBrsD,WACnB3H,EAAKo3D,eAAehnE,KAAK4P,GACzB,IAAO4V,KAAKyJ,MAAsB,IAAhBzJ,KAAK0J,WAQ3Btf,EAAKq1D,iBAAiB,SAAWhyD,MAAO9S,QASpDoZ,EAAQ/X,UAAU6kE,uBAAyB,SAASY,EAAeC,GAAa,GAAA7nE,IAAA,EAAAC,GAAA,EAAAC,MAAAC,EAAA,KAE5E,IAAA,GAAAC,GAAAC,GAAA,EAAAC,EAAArB,UAAsB,EAAA2K,EAAA3K,SAAY2oE,MAAlC5nE,GAAAI,EAAAC,EAAAE,QAAAC,MAAAR,GAAA,EAAkD,CAAA,GAAvCoG,GAAuChG,EAAAK,MACxCqnE,EAAYF,EAAcxhE,GAC5B05D,EAAQ5gE,KAAK2T,OAAO1C,MAAMsO,SAASrY,GACjC2hE,EAAuB,OAAVjI,CACL,QAAVA,IACAA,EAAQ5gE,KAAK8I,YAAY5B,IAEzB0hE,EAAUthE,SACVs5D,EAAMvV,WACFud,EAAUthE,QAAQia,KAAMqnD,EAAUthE,QAAQwe,YAG9C8iD,EAAUxd,SACVwV,EAAMrV,YAAY5jD,OAAQihE,EAAUxd,UAExCwV,EAAMtV,gBAAgBqd,GAClBE,GAEA7oE,KAAK2T,OAAOlT,KAAK,QAASmgE,IApB0C,MAAAh/D,GAAAb,GAAA,EAAAC,EAAAY,EAAA,QAAA,KAAAd,GAAAK,EAAAU,QAAAV,EAAAU,SAAA,QAAA,GAAAd,EAAA,KAAAC,MA6BhFga,EAAQ/X,UAAU6iE,4BAA8B,SAASl5B,GAIrD,GAAMj5B,GAAS3T,KAAK2T,OACdtC,EAAOrR,IACb,OAAOgC,GAAMsd,KAAKstB,GAAKzsB,IAAI,SAASpZ,GAChC,GAAM+hE,GAASl8B,EAAI7lC,GACfyK,EAAOmC,EAAO1C,MAAMQ,QAAQ1K,GAC5Bi/D,GAAiB,CAOrB,OANKx0D,KACDA,EAAOH,EAAKzK,WAAWG,GACvBi/D,GAAiB,GAErB8C,EAAOt3D,KAAOA,EACds3D,EAAO9C,eAAiBA,EACjB8C,KASf9tD,EAAQ/X,UAAUijE,qBAAuB,SAASt5B,EAAKp7B,GACnD,IAAKo7B,IAAQ5qC,EAAMuoC,QAAQqC,EAAI9jB,QAC3B,QAEJ,IAAMxP,GAAStZ,KAAK2T,OAAO0U,gBAC3B,OAAOukB,GAAI9jB,OAAO3I,IAAI,SAAShiB,GAI3B,MAHIqT,KACArT,EAAE2M,QAAU0G,EAAKzK,QAEduS,EAAOnb,MAOtB6c,EAAQ/X,UAAUsjE,gBAAkB,SAAS/0D,GACzC,GAAKA,GAASxR,KAAK+B,KAAK+iE,yBAAxB,CAGA,GAAMnxD,GAAS3T,KAAK2T,MAGpBnC,GAAKsgD,yBAAyB,UAAUrjD,QAAQ,SAASk2B,GACrD,IAAIA,EAAOokC,sBAAX,CAGApkC,EAAOokC,uBAAwB,CAE/B,IAAMrjE,GAAOiO,EAAO+L,QAAQilB,EAAOh9B,QAC/BmE,MAAA,EAEAA,GADApG,EACUmO,EAAA9T,QAAQ+T,SACdgS,WAAYpgB,EAAKwlD,UACjBtlC,YAAalgB,EAAKkmD,cAGZj4C,EAAO3H,eAAe24B,EAAOh9B,QAE3CmE,EAAQxK,KAAK,SAAS2K,GAIlB,GAAM+8D,GAAcrkC,EAAO7b,OAAO6b,MACU,YAAxCqkC,EAAYnyD,aAAajB,aAI7BozD,EAAYnyD,aAAaiP,WAAa7Z,EAAK6Z,WAC3CkjD,EAAYnyD,aAAa+O,YAAc3Z,EAAK2Z,YAE5C+e,EAAOonB,mBAAmBid,EAAax3D,EAAKyN,gBAC7C,SAASrd,WAapBoZ,EAAQ/X,UAAUkjE,mBAAqB,SAAS30D,EAAMy3D,EACNC,GAC5CA,EAAoBA,KACpB,IAAMv1D,GAAS3T,KAAK2T,OAKdo0C,EAAiB/lD,EAAMme,IACzBne,EAAMogB,SACF6mD,EAAe9oD,IAAI,SAAS6nC,GACxB,MAAOA,GAAQp0C,SAEpBD,EAAO0U,kBAERy/B,EAAcmhB,CAQpBz3D,GAAK2V,SAAS8gC,eAAeF,GAC7Bv2C,EAAKyN,aAAagpC,eAAeH,GAEjC9nD,KAAKumE,gBAAgB/0D,GAIrBA,EAAK6hD,YAAYrzD,KAAK2T,OAAOxC,YAAYxJ,QAMzC6J,EAAKwhD,cAAckW,IAYvBluD,EAAQ/X,UAAUmjE,wBAA0B,SAAS50D,EAAM03D,GAEvD,GAAIlpE,KAAK2T,OAAO2I,sBACZ,IAAK,GAAI1d,GAAI,EAAGA,EAAIsqE,EAAkB/pE,OAAQP,IAAK,CAC/C,GAAMurD,GAAcnqD,KAAK2T,OAAO0R,uBAAuB6jD,EAAkBtqE,GACrEurD,IAAeA,EAAYqP,QAC3BrP,EAAY8O,QAAU9O,EAAY8O,OAAOC,WACzCl5D,KAAKulE,aAAa3uD,KAAKsyD,EAAkBtqE,MASzDoc,EAAQ/X,UAAUokE,gBAAkB,WAEhC,MADmBrnE,MAAK2T,OAAOw1D,aAMxB,EAAA9+C,EAAAtqB,UACHyR,MACIwX,UACIhf,MAAO,OAPR,MAkBfgR,EAAQ/X,UAAUyjE,iBAAmB,SAAS0C,EAAUnkE,GACpD,GAAMokE,GAAMrpE,KAAKklE,UACjBllE,MAAKklE,WAAakE,EAClBppE,KAAK2T,OAAOlT,KAAK,OAAQT,KAAKklE,WAAYmE,EAAKpkE,IASnD+V,EAAQ/X,UAAU6jE,UAAY,WAC1BxiB,EAAS,qCACTtkD,KAAKymE,iBAAiB,IAa1BpnE,EAAOJ,QAAU+b,kaC/0CjB,YAqDA,SAAS2nC,GAAehvC,EAAQgV,EAAa5mB,GACzCA,EAAOA,MACP/B,KAAKspE,QAAU31D,EACf3T,KAAKupE,aAAe5gD,EAMpB3oB,KAAKwpE,OAAS,KACdxpE,KAAKypE,KAAO,KAEZzpE,KAAK0pE,YAAc,EACnB1pE,KAAK2pE,aAAe5nE,EAAK6nE,aAAe,IA6T5C,QAASC,GAAc7gD,EAAU4tB,GAC7B52C,KAAKgpB,SAAWA,EAGhBhpB,KAAK42C,MAAQA,EA/XjB,GAAAx8B,GAAAzb,EAAA,mEACMic,EAAgBjc,EAAQ,2BAUxB2lD,EAA+C,YA+DrD3B,GAAe1/C,UAAU6mE,KAAO,SAASC,EAAgBC,GACrD,GAAM34D,GAAOrR,IACbgqE,GAAoBA,GAAqB,EAIzC,IAAMC,GAAa,SAASjhD,GACxB,GAAIkhD,OAAA,GAEEphD,EAASE,EAAS08B,WAExB,IAAKqkB,EAGE,CACH,IAAK,GAAInrE,GAAI,EAAGA,EAAIkqB,EAAO3pB,OAAQP,IAC/B,GAAIkqB,EAAOlqB,GAAG6kB,SAAWsmD,EAAgB,CACrCG,EAAatrE,CACb,OAIR,OAAmBqC,KAAfipE,EACA,KAAM,IAAIprE,OAAM,8DAVpBorE,GAAaphD,EAAO3pB,MAcxB,IAAMgrE,GAAWljD,KAAKonB,IAAIvlB,EAAO3pB,OACT+qE,EAAajjD,KAAKmjD,KAAKJ,EAAoB,IAC7DlG,EAAa78C,KAAKC,IAAI,EAAGijD,EAAWH,EAC1C34D,GAAKm4D,OAAS,GAAIK,GAAc7gD,EAAU86C,EAAa96C,EAASk/B,gBAChE72C,EAAKo4D,KAAO,GAAII,GAAc7gD,EAAUmhD,EAAWnhD,EAASk/B,gBAC5D72C,EAAKq4D,YAAcS,EAAWrG,EAOlC,IAAIiG,EAAgB,CAChB,GAAM50C,GAAOn1B,KAAKspE,QAAQ5gD,iBAAiB1oB,KAAKupE,aAAcQ,EAE9D,OAAI50C,GAAKk1C,eACLJ,EAAW90C,EAAK5zB,SACTsS,EAAA9T,QAAQ+T,WAERqhB,EAAKvxB,KAAKqmE,GAKrB,MADAA,GADWjqE,KAAKupE,aAAa5hD,mBAEtB9T,EAAA9T,QAAQ+T,WAiBvB6uC,EAAe1/C,UAAUqnE,YAAc,SAAS3yD,GAC5C,GAAI6tC,OAAA,EACJ,IAAI7tC,GAAaiD,EAAc8O,UAC3B87B,EAAKxlD,KAAKwpE,WACP,CAAA,GAAI7xD,GAAaiD,EAAcwO,SAGlC,KAAM,IAAItqB,OAAM,sBAAwB6Y,EAAY,IAFpD6tC,GAAKxlD,KAAKypE,KAKd,IAAKjkB,EAED,MADAlB,GAAS,oCACF,CAGX,IAAI3sC,GAAaiD,EAAc8O,WAC3B,GAAI87B,EAAG5O,MAAQ4O,EAAG+kB,WACd,OAAO,MAGX,IAAI/kB,EAAG5O,MAAQ4O,EAAGglB,WACd,OAAO,CAIf,OAAO53D,SAAQ4yC,EAAGx8B,SAASg9B,wBAAwBruC,IACpC6tC,EAAGx8B,SAASW,mBAAmBhS,KAyBlDgrC,EAAe1/C,UAAUwnE,SAAW,SAAS9yD,EAAWwyB,EAAMugC,EACjBC,OAIrB1pE,KAAhBypE,IACAA,GAAc,OAGGzpE,KAAjB0pE,IACAA,EAzL4B,EA4LhC,IAAInlB,OAAA,EACJ,IAAI7tC,GAAaiD,EAAc8O,UAC3B87B,EAAKxlD,KAAKwpE,WACP,CAAA,GAAI7xD,GAAaiD,EAAcwO,SAGlC,KAAM,IAAItqB,OAAM,sBAAwB6Y,EAAY,IAFpD6tC,GAAKxlD,KAAKypE,KAKd,IAAKjkB,EAED,MADAlB,GAAS,mCACFzwC,EAAA9T,QAAQ+T,SAAQ,EAG3B,IAAI0xC,EAAGolB,gBACH,MAAOplB,GAAGolB,eAId,IAAM58C,GAASrW,GAAaiD,EAAc8O,UACtC87B,EAAGqlB,QAAQ1gC,GAAQqb,EAAGslB,QAAQ3gC,EAElC,IAAInc,EAAO,CACPhuB,KAAK0pE,aAAe17C,EACpBs2B,EAAS,oCAAsCt2B,EACtC,SAAWhuB,KAAK0pE,YAAc,IAEvC,IAAMqB,GAAS/qE,KAAK0pE,YAAc1pE,KAAK2pE,YAIvC,OAHIoB,GAAS,GACT/qE,KAAKgrE,WAAWD,EAAQpzD,GAAaiD,EAAc8O,WAEhD7V,EAAA9T,QAAQ+T,SAAQ,GAG3B,IAAK42D,GAAgC,IAAjBC,EAGhB,MAAO92D,GAAA9T,QAAQ+T,SAAQ,EAK3B,KADc0xC,EAAGx8B,SAASW,mBAAmBhS,GAGzC,MADA2sC,GAAS,4BACFzwC,EAAA9T,QAAQ+T,SAAQ,EAG3BwwC,GAAS,mCACT,IAAMjzC,GAAOrR,KAEPm1B,EAAOn1B,KAAKspE,QAAQhgD,sBAAsBk8B,EAAGx8B,UAC/ChB,UAAWrQ,GAAaiD,EAAc8O,UACtC1f,MAAOmgC,IACR1hB,QAAQ,WACP+8B,EAAGolB,gBAAkB,OACtBhnE,KAAK,SAAStF,GAEb,MADAgmD,GAAS,iDAAmDhmD,KACvDA,GAiBE+S,EAAKo5D,SAAS9yD,EAAWwyB,GAAM,EAAMwgC,EAAe,IAG/D,OADAnlB,GAAGolB,gBAAkBz1C,EACdA,GAWXwtB,EAAe1/C,UAAU+nE,WAAa,SAASC,EAAOC,GAClD,GAAM1lB,GAAK0lB,EAAkBlrE,KAAKwpE,OAASxpE,KAAKypE,IAGhD,IAAIwB,EAAQjrE,KAAK0pE,aAAeuB,EAAQ,EACpC,KAAM,IAAInsE,OAAM,2BAA6BmsE,EAAQ,0BACtBjrE,KAAK0pE,YAAc,mBAGtD,MAAOuB,EAAQ,GAAG,CACd,GAAMj9C,GAAQk9C,EAAkB1lB,EAAGslB,QAAQG,GAASzlB,EAAGqlB,QAAQI,EAC/D,IAAIj9C,GAAS,EAET,KAAM,IAAIlvB,OACN,oDACIkB,KAAK0pE,YAAc,UAG/BuB,IAASj9C,EACThuB,KAAK0pE,aAAe17C,EACpBs2B,EAAS,sCAAwCt2B,EACxC,SAAWhuB,KAAK0pE,YAAc,OAU/C/mB,EAAe1/C,UAAUyiD,UAAY,WACjC,IAAK1lD,KAAKwpE,OAEN,QAQJ,KALA,GAAM18C,MAIF9D,EAAWhpB,KAAKwpE,OAAOxgD,WACd,CACT,GAAMF,GAASE,EAAS08B,YAUpBoe,EAAa,EAAGqG,EAAWrhD,EAAO3pB,MAClC6pB,KAAahpB,KAAKwpE,OAAOxgD,WACzB86C,EAAa9jE,KAAKwpE,OAAO5yB,MAAQ5tB,EAASk/B,gBAE1Cl/B,IAAahpB,KAAKypE,KAAKzgD,WACvBmhD,EAAWnqE,KAAKypE,KAAK7yB,MAAQ5tB,EAASk/B,eAG1C,KAAK,GAAItpD,GAAIklE,EAAYllE,EAAIurE,EAAUvrE,IACnCkuB,EAAOlW,KAAKkS,EAAOlqB,GAIvB,IAAIoqB,IAAahpB,KAAKypE,KAAKzgD,SACvB,KAEAA,GAAWA,EAASg9B,wBAAwBprC,EAAcwO,UAIlE,MAAO0D,IAuBX+8C,EAAc5mE,UAAUsnE,SAAW,WAC/B,OAAuC,EAAhCvqE,KAAKgpB,SAASk/B,gBAQzB2hB,EAAc5mE,UAAUunE,SAAW,WAC/B,MAAOxqE,MAAKgpB,SAAS08B,YAAYvmD,OAASa,KAAKgpB,SAASk/B,gBAS5D2hB,EAAc5mE,UAAU6nE,QAAU,SAASG,GACvC,IAAKA,EACD,MAAO,EAKX,IAAIE,OAAA,EACJ,IAAIF,EAAQ,GAOR,IADAE,EAAclkD,KAAKC,IAAI+jD,EAAOjrE,KAAKuqE,WAAavqE,KAAK42C,QACnC,EAEd,MADA52C,MAAK42C,OAASu0B,EACPA,MASX,KADAA,EAAclkD,KAAKonB,IAAI48B,EAAOjrE,KAAKwqE,WAAaxqE,KAAK42C,QACnC,EAEd,MADA52C,MAAK42C,OAASu0B,EACPA,CAOf,IAAMplB,GAAY/lD,KAAKgpB,SAASg9B,wBAC5BilB,EAAQ,EAAIrwD,EAAc8O,UAAY9O,EAAcwO,SACxD,OAAI28B,IACA/lD,KAAKgpB,SAAW+8B,EAEZ/lD,KAAK42C,MADLq0B,EAAQ,EACKjrE,KAAKwqE,WAELxqE,KAAKuqE,WAGtBjmB,EAAS,uCAGFtkD,KAAK8qE,QAAQG,IAGjB,GASXpB,EAAc5mE,UAAU4nE,QAAU,SAASI,GACvC,OAAmC,EAA5BjrE,KAAK8qE,SAAiB,EAATG,IAMxB5rE,EAAOJ,QAAQ0jD,eAAiBA,EAKhCtjD,EAAOJ,QAAQ4qE,cAAgBA,mECre/B,mNAYAxqE,GAAOJ,QAAQgyB,aAAe,SAASzsB,GACnC,GAAIo5C,GAAK,EACT,KAAK,GAAM55B,KAAOxf,GACTA,EAAOqtB,eAAe7N,KAG3B45B,GAAM,IAAMV,mBAAmBl5B,GAAO,IAC9Bk5B,mBAAmB14C,EAAOwf,IAEtC,OAAO45B,GAAG9hC,UAAU,IAWxBzc,EAAOJ,QAAQyH,UAAY,SAAS4O,EAAc81D,GAC9C,IAAK,GAAMpnD,KAAOonD,GACTA,EAAUv5C,eAAe7N,KAG9B1O,EAAeA,EAAaqG,QACxBqI,EAAKk5B,mBAAmBkuB,EAAUpnD,KAG1C,OAAO1O,IAUXjW,EAAOJ,QAAQkhB,IAAM,SAASk6C,EAAOuB,GAEjC,IAAK,GADCjuC,GAAU,GAAIptB,OAAM85D,EAAMl7D,QACvBP,EAAI,EAAGA,EAAIy7D,EAAMl7D,OAAQP,IAC9B+uB,EAAQ/uB,GAAKg9D,EAAGvB,EAAMz7D,GAE1B,OAAO+uB,IAWXtuB,EAAOJ,QAAQkrB,OAAS,SAASkwC,EAAOuB,GAEpC,IAAK,GADCjuC,MACG/uB,EAAI,EAAGA,EAAIy7D,EAAMl7D,OAAQP,IAC1Bg9D,EAAGvB,EAAMz7D,GAAIA,EAAGy7D,IAChB1sC,EAAQ/W,KAAKyjD,EAAMz7D,GAG3B,OAAO+uB,IAQXtuB,EAAOJ,QAAQqgB,KAAO,SAASstB,GAC3B,GAAMttB,KACN,KAAK,GAAM0E,KAAO4oB,GACTA,EAAI/a,eAAe7N,IAGxB1E,EAAK1I,KAAKoN,EAEd,OAAO1E,IAQXjgB,EAAOJ,QAAQwY,OAAS,SAASm1B,GAC7B,GAAMn1B,KACN,KAAK,GAAMuM,KAAO4oB,GACTA,EAAI/a,eAAe7N,IAGxBvM,EAAOb,KAAKg2B,EAAI5oB,GAEpB,OAAOvM,IASXpY,EAAOJ,QAAQwP,QAAU,SAAS4rD,EAAOuB,GACrC,IAAK,GAAIh9D,GAAI,EAAGA,EAAIy7D,EAAMl7D,OAAQP,IAC9Bg9D,EAAGvB,EAAMz7D,GAAIA,IAerBS,EAAOJ,QAAQwmD,YAAc,SAAS4U,EAAOuB,EAAItzC,GAC7C,GAAI1pB,OAAA,EACJ,IAAI0pB,GACA,IAAK1pB,EAAIy7D,EAAMl7D,OAAS,EAAGP,GAAK,EAAGA,IAC/B,GAAIg9D,EAAGvB,EAAMz7D,GAAIA,EAAGy7D,GAChB,MAAOA,GAAMz7D,OAIrB,KAAKA,EAAI,EAAGA,EAAIy7D,EAAMl7D,OAAQP,IAC1B,GAAIg9D,EAAGvB,EAAMz7D,GAAIA,EAAGy7D,GAChB,MAAOA,GAAMz7D,IAgB7BS,EAAOJ,QAAQ4zD,cAAgB,SAASwH,EAAOuB,EAAItzC,GAC/C,GAAI1pB,OAAA,GACAgoD,MAAA,EACJ,IAAIt+B,GACA,IAAK1pB,EAAIy7D,EAAMl7D,OAAS,EAAGP,GAAK,EAAGA,IAC/B,GAAIg9D,EAAGvB,EAAMz7D,GAAIA,EAAGy7D,GAGhB,MAFAzT,GAAUyT,EAAMz7D,GAChBy7D,EAAM/hB,OAAO15C,EAAG,GACTgoD,MAIf,KAAKhoD,EAAI,EAAGA,EAAIy7D,EAAMl7D,OAAQP,IAC1B,GAAIg9D,EAAGvB,EAAMz7D,GAAIA,EAAGy7D,GAGhB,MAFAzT,GAAUyT,EAAMz7D,GAChBy7D,EAAM/hB,OAAO15C,EAAG,GACTgoD,CAInB,QAAO,GAQXvnD,EAAOJ,QAAQgL,WAAa,SAAS1I,GACjC,MAAgD,qBAAzCirC,OAAOvpC,UAAUwmC,SAASvqC,KAAKqC,IAQ1ClC,EAAOJ,QAAQsrC,QAAU,SAAShpC,GAC9B,MAAOhB,OAAMgqC,QAAUhqC,MAAMgqC,QAAQhpC,GACjCqR,QAAQrR,GAASA,EAAMq9C,cAAgBr+C,QAS/ClB,EAAOJ,QAAQgD,mBAAqB,SAAS2qC,EAAKttB,GAC9C,IAAK,GAAI1gB,GAAI,EAAGA,EAAI0gB,EAAKngB,OAAQP,IAC7B,IAAKguC,EAAI/a,eAAevS,EAAK1gB,IACzB,KAAM,IAAIE,OAAM,yBAA2BwgB,EAAK1gB,KAW5DS,EAAOJ,QAAQosE,+BAAiC,SAASz+B,EAAK0+B,GAC1D,IAAK,GAAMtnD,KAAO4oB,GACd,GAAKA,EAAI/a,eAAe7N,KAGU,IAA9BsnD,EAAYj1D,QAAQ2N,GACpB,KAAM,IAAIllB,OAAM,gBAAkBklB,IAW9C3kB,EAAOJ,QAAQmjB,SAAW,SAASwqB,GAC/B,MAAOvU,MAAKrM,OAAM,EAAA3B,EAAAtqB,SAAe6sC,IAWrC,IAAMxd,GAAc/vB,EAAOJ,QAAQmwB,YAAc,SAASm8C,EAAGC,GAMzD,GAAID,IAAMC,EACN,OAAO,CAGX,SAAI,KAAOD,EAAP,aAAA,EAAA/6D,EAAAzQ,SAAOwrE,WAAP,KAAoBC,EAApB,aAAA,EAAAh7D,EAAAzQ,SAAoByrE,IACpB,OAAO,CAIX,IAAiB,gBAAND,IAAkB5T,MAAM4T,IAAM5T,MAAM6T,GAC1C,OAAO,CAKZ,IAAU,OAAND,GAAoB,OAANC,EACd,MAAOD,KAAMC,CAIjB,MAAMD,YAAa/+B,SACf,OAAO,CAIX,IAAI++B,EAAE3sB,cAAgB4sB,EAAE5sB,aAAe2sB,EAAEtoE,YAAcuoE,EAAEvoE,UACrD,OAAO,CAIX,IAAIsoE,YAAa1T,SAAU0T,YAAahoE,MACpC,MAAOgoE,GAAE9hC,aAAe+hC,EAAE/hC,UAI9B,IAAI8hC,YAAahrE,OAAO,CACpB,GAAIgrE,EAAEpsE,SAAWqsE,EAAErsE,OACf,OAAO,CAGX,KAAK,GAAIP,GAAI,EAAGA,EAAI2sE,EAAEpsE,OAAQP,IAC1B,IAAKwwB,EAAYm8C,EAAE3sE,GAAI4sE,EAAE5sE,IACrB,OAAO,MAGZ,CAMH,GAAI6sE,OAAA,EACJ,KAAKA,IAAKD,GACN,GAAIA,EAAE35C,eAAe45C,KAAOF,EAAE15C,eAAe45C,GACzC,OAAO,CAKf,KAAKA,IAAKD,GAAG,CACT,GAAIA,EAAE35C,eAAe45C,KAAOF,EAAE15C,eAAe45C,GACzC,OAAO,CAEX,KAAKr8C,EAAYm8C,EAAEE,GAAID,EAAEC,IACrB,OAAO,GAKnB,OAAO,EAgBXpsE,GAAOJ,QAAQuG,OAAS,WAEpB,IAAK,GADC3F,GAASQ,UAAU,OAChBzB,EAAI,EAAGA,EAAIyB,UAAUlB,OAAQP,IAAK,CACvC,GAAMgC,GAASP,UAAUzB,EACzB,KAAK,GAAM8sE,KAAY9qE,GACnBf,EAAO6rE,GAAY9qE,EAAO8qE,GAGlC,MAAO7rE,IAMXR,EAAOJ,QAAQ0sE,aAAe,WAKrBprE,MAAM0C,UAAUknB,SACnB5pB,MAAM0C,UAAUknB,OAAS,SAASyhD,GAChC,OAAa,KAAT5rE,MAA4B,OAATA,KACrB,KAAM,IAAI0vC,UAGZ,IAAMtxC,GAAIouC,OAAOxsC,MACX6rE,EAAMztE,EAAEe,SAAW,CACzB,IAAmB,kBAARysE,GACT,KAAM,IAAIl8B,UAKZ,KAAK,GAFCr7B,MACAy3D,EAAUzrE,UAAUlB,QAAU,EAAIkB,UAAU,OAAK,GAC9CzB,EAAI,EAAGA,EAAIitE,EAAKjtE,IACvB,GAAIA,IAAKR,GAAG,CACV,GAAMgqC,GAAMhqC,EAAEQ,EAOVgtE,GAAI1sE,KAAK4sE,EAAS1jC,EAAKxpC,EAAGR,IAC5BiW,EAAIuC,KAAKwxB,GAKf,MAAO/zB,KAUN9T,MAAM0C,UAAUkd,MACnB5f,MAAM0C,UAAUkd,IAAM,SAAS9b,EAAUynE,GACvC,GAAIC,OAAA,GAAG1mC,MAAA,EAEP,IAAa,OAATrlC,UAA0BiB,KAATjB,KACnB,KAAM,IAAI0vC,WAAU,+BAKtB,IAAMs8B,GAAIx/B,OAAOxsC,MAKX6rE,EAAMG,EAAE7sE,SAAW,CAIzB,IAAwB,kBAAbkF,GACT,KAAM,IAAIqrC,WAAUrrC,EAAW,qBAI7BhE,WAAUlB,OAAS,IACrB4sE,EAAID,EAMN,IAAMG,GAAI,GAAI1rE,OAAMsrE,EAMpB,KAHAxmC,EAAI,EAGGA,EAAIwmC,GAAK,CACd,GAAIK,GAAQC,CAQR9mC,KAAK2mC,KAGPE,EAASF,EAAE3mC,GAKX8mC,EAAc9nE,EAASnF,KAAK6sE,EAAGG,EAAQ7mC,EAAG2mC,GAmB1CC,EAAE5mC,GAAK8mC,GAGT9mC,IAIF,MAAO4mC,KAUN1rE,MAAM0C,UAAUwL,UACnBlO,MAAM0C,UAAUwL,QAAU,SAASpK,EAAUynE,GAC3C,GAAIC,OAAA,GAAG1mC,MAAA,EAEP,IAAa,OAATrlC,UAA0BiB,KAATjB,KACnB,KAAM,IAAI0vC,WAAU,+BAKtB,IAAMs8B,GAAIx/B,OAAOxsC,MAKX6rE,EAAMG,EAAE7sE,SAAW,CAIzB,IAAwB,kBAAbkF,GACT,KAAM,IAAIqrC,WAAUrrC,EAAW,qBAYjC,KARIhE,UAAUlB,OAAS,IACrB4sE,EAAID,GAINzmC,EAAI,EAGGA,EAAIwmC,GAAK,CACd,GAAIK,EASA7mC,KAAK2mC,KAGPE,EAASF,EAAE3mC,GAIXhhC,EAASnF,KAAK6sE,EAAGG,EAAQ7mC,EAAG2mC,IAG9B3mC,QAeVhmC,EAAOJ,QAAQkc,SAAW,SAASixD,EAAMC,GAKT,kBAAxB1tB,GAAA5+C,UAGFysC,OAAO1U,OAAU,WAEf,QAASw0C,MAGT,GAAMC,GAAS//B,OAAOvpC,UAAU4uB,cAEhC,OAAO,UAASm6C,GAEd,GAAgB,eAAZ,KAAOA,EAAP,aAAA,EAAAx7D,EAAAzQ,SAAOisE,IACT,KAAM,IAAIt8B,WAAU,iDAOtB48B,GAAKrpE,UAAY+oE,CACjB,IAAMp/B,GAAM,GAAI0/B,EAOhB,IANAA,EAAKrpE,UAAY,KAMb5C,UAAUlB,OAAS,EAAG,CAExB,GAAMqtE,GAAahgC,OAAOnsC,UAAU,GACpC,KAAK,GAAMwsC,KAAQ2/B,GACbD,EAAOrtE,KAAKstE,EAAY3/B,KAC1BD,EAAIC,GAAQ2/B,EAAW3/B,IAM7B,MAAOD,QA6Bbw/B,EAAKK,OAASJ,EACdD,EAAKnpE,WAAY,EAAA07C,EAAA5+C,SAAcssE,EAAUppE,WACrC27C,aACIr9C,MAAO6qE,EACP1/B,YAAY,EACZggC,UAAU,EACVC,cAAc,gKC3nB1B,YA+DA,SAASC,GAAW7qE,GAChB/B,KAAK+G,OAAShF,EAAKgF,OACnB/G,KAAK2T,OAAS5R,EAAK4R,OACnB3T,KAAK6sE,OAAS9qE,EAAK8qE,OACnB7sE,KAAKqT,UAAYtR,EAAKsR,UACtBrT,KAAK8sE,IAAM/qE,EAAK+qE,IAEhB9sE,KAAK+sE,YAAchrE,EAAKgrE,gBACQ,IAA5B/sE,KAAK+sE,YAAY5tE,QACjBa,KAAK+sE,YAAYn2D,MACbgC,MAAOg0D,EAAWI,wBAG1BhrE,EAAMyM,QAAQzO,KAAK+sE,YAAa,SAAStiE,GACrCzI,EAAMC,mBAAmBwI,GAAS,WAGtCzK,KAAKmX,OAAS,KAAM,GAAI5T,OAAOC,UAAYyjB,KAAK0J,SAChD3wB,KAAKkX,MAAQ,YACblX,KAAKitE,YAAa,EAKlBjtE,KAAKktE,sBACLltE,KAAKmtE,mBAAqB,EAM1BntE,KAAKotE,eAAgB,EAAAzuB,EAAA5+C,SAAc,MAEnCC,KAAKqtE,oBAAsB,2GA3FzBrrE,EAAQrD,EAAQ,YAChB+b,EAAe/b,EAAQ,UAAU+b,YA6FvCkyD,GAAWU,gBAAkB,IAE7BV,EAAWI,qBAAuB,+BAElCJ,EAAWW,uBAAyB,qBAKpCX,EAAWY,kBAAoB,gBAE/BxrE,EAAMmZ,SAASyxD,EAAYlyD,GAM3BkyD,EAAW3pE,UAAUwqE,eAAiB,WAClCnpB,EAAS,kBACTopB,EAAsB1tE,MACtB2tE,EAA0B3tE,KAAM4tE,EAA6B,UAC7D5tE,KAAKuF,KAAO,SAWhBqnE,EAAW3pE,UAAU4qE,eAAiB,SAASC,EAAoBC,GAC/DzpB,EAAS,kBACTopB,EAAsB1tE,MACtBA,KAAK+tE,kBAAoBA,EACzB/tE,KAAK8tE,mBAAqBA,EAC1BH,EAA0B3tE,KAAM4tE,EAA6B,UAC7D5tE,KAAKuF,KAAO,QACZyoE,EAAqBhuE,OAazB4sE,EAAW3pE,UAAUgrE,uBACjB,SAASH,EAAoBC,GAC7BzpB,EAAS,0BACTopB,EAAsB1tE,KACtB,IAAMkuE,GAAoBC,EAA6BnuE,KACvD,IAAKkuE,EAAL,CAGAluE,KAAK+tE,kBAAoBA,EACzB/tE,KAAK8tE,mBAAqBA,CAC1B,IAAMz8D,GAAOrR,IACbA,MAAK6sE,OAAOuB,aAAaF,EAAmB,SAASvyB,GACjDtqC,EAAKg8D,oBAAsB1xB,EAC3B2I,EAAS,gDACT,IAAM+pB,GAAmBT,EAA6B,QACtDD,GAA0Bt8D,EAAMg9D,IACjC,SAASzsE,GACRyP,EAAK5Q,KAAK,QACN6tE,EACI1B,EAAWY,kBACX,wCAA0C5rE,MAItD5B,KAAKuF,KAAO,QACZyoE,EAAqBhuE,QASzB4sE,EAAW3pE,UAAUsrE,YAAc,SAAS5S,EAAS6S,GACjD/5D,QAAQe,IAAI,mBAAqBg5D,EAAU,gBAAkB7S,GAGzD37D,KAAKotE,cAAcoB,GAMnBxuE,KAAKotE,cAAcoB,GACfxuE,KAAKotE,cAAcoB,GAAS5qE,KAAK,WAE7B,MADA6Q,SAAQe,IAAI,kCAAoCg5D,GACzC7S,EAAQ8S,QAChB,WAEC,MADAh6D,SAAQe,IAAI,+BAAiCg5D,GACtC7S,EAAQ8S,SAGvBzuE,KAAKotE,cAAcoB,GAAW7S,EAAQ8S,QAU9C7B,EAAW3pE,UAAUyrE,aAAe,SAAS/S,EAAS6S,GAClD/5D,QAAQe,IAAI,oBAAsBg5D,EAAU,gBAAkB7S,GAC1D37D,KAAKotE,cAAcoB,GACnBxuE,KAAKotE,cAAcoB,GACfxuE,KAAKotE,cAAcoB,GAAS5qE,KAAK,WAE7B,MADA6Q,SAAQe,IAAI,kCAAoCg5D,GACzC7S,EAAQgT,SAChB,WAEC,MADAl6D,SAAQe,IAAI,+BAAiCg5D,GACtC7S,EAAQgT,UAKvB3uE,KAAKotE,cAAcoB,GAAW7S,EAAQgT,SAY9C/B,EAAW3pE,UAAU2rE,cAAgB,SAASjT,EAASkT,EAAWL,GAC9D/5D,QAAQe,IAAI,qBAAuBg5D,EAAU,YAAc7S,EAAU,QACjEkT,GACA7uE,KAAKotE,cAAcoB,GACnBxuE,KAAKotE,cAAcoB,GACfxuE,KAAKotE,cAAcoB,GAAS5qE,KAAK,WAC7B6Q,QAAQe,IAAI,kCAAoCg5D,GAChD7S,EAAQkT,UAAYA,GACrB,WACCp6D,QAAQe,IAAI,+BAAiCg5D,GAC7C7S,EAAQkT,UAAYA,IAG5BlT,EAAQkT,UAAYA,GAQ5BjC,EAAW3pE,UAAU6rE,qBAAuB,WACxC,MAAO9uE,MAAK+tE,mBAQhBnB,EAAW3pE,UAAU8rE,sBAAwB,WACzC,MAAO/uE,MAAK8tE,oBAQhBlB,EAAW3pE,UAAU+rE,sBAAwB,WACzC,MAAOhvE,MAAKivE,oBAQhBrC,EAAW3pE,UAAUisE,qBAAuB,SAASvT,GAGjD,GAFA37D,KAAK+tE,kBAAoBpS,EAErBA,GAAW37D,KAAKmvE,eAA+B,UAAdnvE,KAAKuF,KAAkB,CACxDo2D,EAAQyT,UAAW,EACnBpvE,KAAK4uE,cAAcjT,EAAS37D,KAAKmvE,cAAe,cAChDxT,EAAQ0T,OAAQ,CAChB,IAAMh+D,GAAOrR,IACbgZ,YAAW,WACP,GAAMs2D,GAAMj+D,EAAKy9D,sBACbQ,GAAIb,MACJp9D,EAAKk9D,YAAYe,EAAK,eAE3B,KASX1C,EAAW3pE,UAAUssE,sBAAwB,SAAS5T,GAClD37D,KAAK8tE,mBAAqBnS,EAC1BqS,EAAqBhuE,OASzB4sE,EAAW3pE,UAAUusE,sBAAwB,SAAS7T,GAClD37D,KAAK8tE,mBAAmBuB,OAAQ,EAChCrvE,KAAKivE,mBAAqBtT,EAC1B37D,KAAKivE,mBAAmBI,OAAQ,EAChCI,EAA0BzvE,OAQ9B4sE,EAAW3pE,UAAUmU,gBAAkB,SAASxD,GAC5C5T,KAAKglC,IAAMpxB,EAAMiD,aACjB7W,KAAK0vE,SAAWC,EAAsB3vE,KACtC,IAAMqR,GAAOrR,IACTA,MAAK0vE,UACL1vE,KAAK0vE,SAASE,qBACV,GAAI5vE,MAAK6sE,OAAOgD,sBAAsB7vE,KAAKglC,IAAI8qC,OAC/CC,EAAa1+D,EAAMA,EAAK2+D,gCACxBD,EAAa1+D,EAAMA,EAAK4+D,+BAGhC5N,EAASriE,KAAM,WACfA,KAAK2X,UAAY,UAMb3X,KAAKglC,IAAI8qC,OACT9vE,KAAKglC,IAAI8qC,MAAMI,KACflwE,KAAKglC,IAAI8qC,MAAMI,IAAI75D,QAAQ,YAAc,EAEzCrW,KAAKuF,KAAO,QAEZvF,KAAKuF,KAAO,QAGZqO,EAAMoD,UACNgC,WAAW,WACW,WAAd3H,EAAK6F,QACLotC,EAAS,wCACTjzC,EAAK8+D,YAAc,SACnB9N,EAAShxD,EAAM,SACf++D,EAAa/+D,GACuB,UAAhCA,EAAKq+D,SAASW,gBACdh/D,EAAKq+D,SAASp5B,QAElBjlC,EAAK5Q,KAAK,SAAU4Q,KAEzBrR,KAAKglC,IAAI/tB,SAAWrD,EAAMoD,WASrC41D,EAAW3pE,UAAUkV,gBAAkB,SAASvE,GAI5C5T,KAAKglC,IAAMpxB,EAAMiD,aACjBwrD,EAASriE,KAAM,UAMnB4sE,EAAW3pE,UAAU4U,OAAS,WAC1BysC,EAAS,+BAAgCtkD,KAAKmX,OAAQnX,KAAKuF,KAC3D,IAAM8L,GAAOrR,IAERA,MAAKmvE,eAAkBnvE,KAAKswE,qBAOtBtwE,KAAKmvE,cACZnvE,KAAKuwE,4BAA4BvwE,KAAKmvE,eAC/BnvE,KAAKswE,sBACZjO,EAASriE,KAAM,qBATfA,KAAK6sE,OAAOuB,aACRR,EAA6B5tE,KAAKuF,MAClCwqE,EAAa1+D,EAAMA,EAAKk/D,6BACxBR,EAAa1+D,EAAMA,EAAKk/D,8BAE5BlO,EAASriE,KAAM,sBAcvB4sE,EAAW3pE,UAAU2U,YAAc,SAAS44D,GACxClsB,EAAStkD,KAAKmX,OAAS,sBAAwBq5D,EAAQr5D,QACrC,oBAAdnX,KAAKkX,OACLotC,EAAS,4CACTksB,EAAQF,sBAAuB,GACV,gBAAdtwE,KAAKkX,OACZotC,EAAS,oCACTksB,EAAQD,4BAA4BvwE,KAAKmvE,qBAClCnvE,MAAKmvE,eACS,eAAdnvE,KAAKkX,QACZotC,EAAS,oCACTksB,EAAQD,4BAA4BvwE,KAAKmvE,qBAClCnvE,MAAKmvE,eAEhBqB,EAAQzC,kBAAoB/tE,KAAK+tE,kBACjCyC,EAAQ1C,mBAAqB9tE,KAAK8tE,mBAClC0C,EAAQvB,mBAAqBjvE,KAAKivE,mBAClCjvE,KAAKywE,UAAYD,EACjBxwE,KAAKS,KAAK,WAAY+vE,GACtBxwE,KAAK8X,QAAO,IAQhB80D,EAAW3pE,UAAU6U,OAAS,SAASnC,EAAQ+6D,GAC3CpsB,EAAS,eAAiBtkD,KAAKmX,QAC/Bw5D,EAAU3wE,KAAM,QAAS2V,GAAS+6D,EAClC,IAAM3nE,IACF6nE,QAAS,EACT95D,QAAS9W,KAAKmX,OACdxB,OAAQA,EAEZ0M,GAAUriB,KAAM,gBAAiB+I,IAOrC6jE,EAAW3pE,UAAU4tE,mBAAqB,SAASxB,GAC1CrvE,KAAKmvE,eAGV2B,EAAiB9wE,KAAKmvE,cAAc4B,kBAAmB1B,IAY3DzC,EAAW3pE,UAAU+tE,kBAAoB,WACrC,QAAKhxE,KAAKmvE,gBAGF8B,EAAgBjxE,KAAKmvE,cAAc4B,mBAO/CnE,EAAW3pE,UAAUiuE,mBAAqB,SAAS7B,GAC1CrvE,KAAKmvE,eAGV2B,EAAiB9wE,KAAKmvE,cAAcgC,kBAAmB9B,IAY3DzC,EAAW3pE,UAAUmuE,kBAAoB,WACrC,QAAKpxE,KAAKmvE,gBAGF8B,EAAgBjxE,KAAKmvE,cAAcgC,mBAQ/CvE,EAAW3pE,UAAUouE,4BAA8B,SAAS11B,GACxD,GAAI37C,KAAKywE,UAEL,WADAzwE,MAAKywE,UAAUF,4BAA4B50B,EAG/C,IAAkB,SAAd37C,KAAKkX,MAAT,CAGAotC,EAAS,kCAAoCtkD,KAAKuF,KAClD,IAAM8L,GAAOrR,KAEP0U,EAAQinC,EACR21B,GACFC,WACIC,qBAAuB,EACvBC,oBAAqC,UAAdpgE,EAAK9L,MAGpC,IAAIo2C,YAAkB+1B,aAAa,CAC/B,GAAMC,GAAU3xE,KAAK8uE,sBAEjB6C,IAAwB,SAAb3xE,KAAKuF,OAChBosE,EAAQvC,UAAW,EACfpvE,KAAKqtE,qBACL/oB,EAAS,4DAETtkD,KAAK4uE,cAAc+C,EAAS3xE,KAAKqtE,oBAAqB,eAEtDrtE,KAAK4uE,cAAc+C,EAASh2B,EAAQ,cAExCg2B,EAAQtC,OAAQ,EAChBr2D,WAAW,WACP,GAAMs2D,GAAMj+D,EAAKy9D,sBACbQ,GAAIb,MACJp9D,EAAKk9D,YAAYe,EAAK,eAE3B,IAGHtvE,KAAKqtE,sBACLrtE,KAAKqtE,oBAAoBuE,SAASj2B,EAAOw1B,iBAAiB,IAC1Dx1B,EAAS37C,KAAKqtE,qBAGlBrtE,KAAKmvE,cAAgBxzB,EAErBm1B,EAAiBn1B,EAAOw1B,kBAAkB,GAC1CnxE,KAAK0vE,SAAWC,EAAsB3vE,MACtCA,KAAK0vE,SAASmC,UAAUl2B,OACrB,CAAA,GAAmB,0BAAfjnC,EAAM6M,KAOb,MAFA+iC,GAAS,+BACTtkD,MAAK8xE,oBAAoBp9D,EALzB4vC,GAAS,0GAETtkD,KAAK0vE,SAAWC,EAAsB3vE,MAO1CA,KAAK0vE,SAASqC,YACVhC,EAAa1+D,EAAMA,EAAK2gE,gBACxBjC,EAAa1+D,EAAMA,EAAK4gE,sBACxBX,GAEJjP,EAAShxD,EAAM,kBAQnBu7D,EAAW3pE,UAAUstE,4BAA8B,SAAS50B,GACxD,GAAMtqC,GAAOrR,IACb,IAAkB,SAAdqR,EAAK6F,MAAT,CAIA,GAAMxC,GAAQinC,CACd,IAAIA,YAAkB+1B,aAAa,CAC/B,GAAMQ,GAAa7gE,EAAKy9D,sBAEpBoD,IAA2B,SAAb7gE,EAAK9L,OACnB2sE,EAAW9C,UAAW,EACtBpvE,KAAK4uE,cAAcsD,EAAYv2B,EAAQ,cACvCu2B,EAAW7C,OAAQ,EACnBr2D,WAAW,WACP,GAAMs2D,GAAMj+D,EAAKy9D,sBACbQ,GAAIb,MACJp9D,EAAKk9D,YAAYe,EAAK,eAE3B,IAGPj+D,EAAK89D,cAAgBxzB,EACrBm1B,EAAiBn1B,EAAOw1B,kBAAkB,GAC1C9/D,EAAKq+D,SAASmC,UAAUl2B,OACrB,CAAA,GAAmB,0BAAfjnC,EAAM6M,KAMb,MAFA+iC,GAAS,+BACTtkD,MAAK8xE,oBAAoBp9D,EAJzB4vC,GAAS,0GAQb,GAAMgtB,IACFC,WACIC,qBAAuB,EACvBC,oBAAqC,UAAdpgE,EAAK9L,MAGpC8L,GAAKq+D,SAASyC,aAAa,SAASC,GAChC9tB,EAAS,mBAAqB8tB,GAC9B/gE,EAAKq+D,SAAS2C,oBAAoBD,EAAa,WAC3C,GAAMrpE,IACF6nE,QAAS,EACT95D,QAASzF,EAAK8F,OACdU,QACIq4D,IAAK7+D,EAAKq+D,SAAS4C,iBAAiBpC,IACpC3qE,KAAM8L,EAAKq+D,SAAS4C,iBAAiB/sE,MAG7C8c,GAAUhR,EAAM,gBAAiBtI,GACjCs5D,EAAShxD,EAAM,eAChB,WACCizC,EAAS,qCACVgtB,IACJ,SAAS1vE,GACR0iD,EAAS,4BAA8B1iD,KAE3CygE,EAAShxD,EAAM,mBAQnBu7D,EAAW3pE,UAAUsvE,sBAAwB,SAAS3+D,GAClD,GAAIA,EAAM4+D,UAAW,CACjBluB,EACI,iBAAmB1wC,EAAM4+D,UAAUC,OAAS,eAC5C7+D,EAAM4+D,UAAUA,UAIpB,IAAME,IACFF,UAAW5+D,EAAM4+D,UAAUA,UAC3BC,OAAQ7+D,EAAM4+D,UAAUC,OACxBE,cAAe/+D,EAAM4+D,UAAUG,cAEnCC,GAAc5yE,KAAM0yE,KAS5B9F,EAAW3pE,UAAUqU,uBAAyB,SAASu7D,GACjC,SAAd7yE,KAAKkX,QAITotC,EAAS,kBAAoBuuB,EAAKJ,OAAS,eAAiBI,EAAKL,WACjExyE,KAAK0vE,SAASoD,gBACV,GAAI9yE,MAAK6sE,OAAOkG,gBAAgBF,GAChC,aACA,SAAS10E,QASjByuE,EAAW3pE,UAAU+U,gBAAkB,SAASgtB,GAC5C,GAAkB,SAAdhlC,KAAKkX,MAAT,CAIA,GAAM7F,GAAOrR,IACbA,MAAK0vE,SAASE,qBACV,GAAI5vE,MAAK6sE,OAAOgD,sBAAsB7qC,EAAIntB,QAC1Ck4D,EAAa1+D,EAAMA,EAAK2+D,gCACxBD,EAAa1+D,EAAMA,EAAK4+D,+BAE5B5N,EAAShxD,EAAM,gBAQnBu7D,EAAW3pE,UAAU+uE,eAAiB,SAASI,GAC3C,GAAM/gE,GAAOrR,IAGb,IAFAskD,EAAS,kBAAoB8tB,GAEX,SAAd/gE,EAAK6F,MAGL,WAFAotC,GAAS,2CAA6CjzC,EAAK8F,OACvD,8BAIR9F,GAAKq+D,SAAS2C,oBAAoBD,EAAa,WAC3C,GAAMrpE,IACF6nE,QAAS,EACT95D,QAASzF,EAAK8F,OAUd24D,OACII,IAAK7+D,EAAKq+D,SAAS4C,iBAAiBpC,IACpC3qE,KAAM8L,EAAKq+D,SAAS4C,iBAAiB/sE,MAEzC0R,SAAU21D,EAAWU,gBAEzBjrD,GAAUhR,EAAM,gBAAiBtI,GAEjCiQ,WAAW,WACW,eAAd3H,EAAK6F,OACL7F,EAAKyG,OAAO,mBAEjB80D,EAAWU,iBACdjL,EAAShxD,EAAM,gBAChB,WACCizC,EAAS,uCASjBsoB,EAAW3pE,UAAUgvE,qBAAuB,SAASv9D,GACjD1U,KAAKS,KACD,QACA6tE,EAAU1B,EAAWW,uBAAwB,qCASrDX,EAAW3pE,UAAU6uE,oBAAsB,SAASp9D,GAChD1U,KAAKS,KACD,QACA6tE,EACI1B,EAAWY,kBACX,iGAIRxtE,KAAK8X,OAAO,sBAOhB80D,EAAW3pE,UAAU+vE,6BAA+B,WAC9B,SAAdhzE,KAAKkX,QAGTotC,EACI,oCAAsCtkD,KAAK0vE,SAASuD,oBAIhB,aAApCjzE,KAAK0vE,SAASuD,oBAC0B,aAApCjzE,KAAK0vE,SAASuD,oBAClB5Q,EAASriE,KAAM,aACfA,KAAKitE,YAAa,GACyB,UAApCjtE,KAAK0vE,SAASuD,oBACrBjzE,KAAK8X,OAAO,gBAQpB80D,EAAW3pE,UAAUiwE,0BAA4B,WAC7C5uB,EACI,QAAUtkD,KAAKmX,OAAS,kCACxBnX,KAAK0vE,SAASW,iBAQtBzD,EAAW3pE,UAAU+sE,+BAAiC,WAClD1rB,EAAS,2BAQbsoB,EAAW3pE,UAAUgtE,6BAA+B,SAAS9xE,GACzDmmD,EAAS,mCAAqCnmD,IAQlDyuE,EAAW3pE,UAAUkwE,aAAe,SAASv/D,GACzC0wC,EAAS,aAAe1wC,EAAM+nC,OAAO3b,GAAK,SAE1C,IAAMzhC,GAAIqV,EAAM+nC,MAEZp9C,GAAEwyE,iBAAiB5xE,OAAS,GAC5Ba,KAAKuF,KAAO,QACZvF,KAAKozE,eAAiB70E,EACtByB,KAAKqzE,cAAgB90E,IAErByB,KAAKuF,KAAO,QACZvF,KAAKqzE,cAAgB90E,EAGzB,IAAM8S,GAAOrR,IACbszE,GAAqB/0E,EAAG,SAASH,GAC7BkmD,EAAS,YAAclmD,EAAE4hC,GAAK,UAE9B5hC,EAAEm1E,UAAYxD,EAAa1+D,EAAMA,EAAKmiE,mCAGVvyE,KAA5B2S,EAAM+nC,OAAO83B,WACb7/D,EAAM+nC,OAAO83B,WAAa1D,EAAa1+D,EAAMA,EAAKqiE,sBAGlD9/D,EAAM+nC,OAAOg4B,QAAU5D,EAAa1+D,EAAMA,EAAKqiE,sBAInD9/D,EAAM+nC,OAAO43B,UAAYxD,EAAa1+D,EAAMA,EAAKuiE,wBAE/B,UAAd5zE,KAAKuF,MACLyoE,EAAqBhuE,MACrByvE,EAA0BzvE,OAE1ByvE,EAA0BzvE,OASlC4sE,EAAW3pE,UAAU2wE,uBAAyB,SAAShgE,GACnDyuD,EAASriE,KAAM,cAQnB4sE,EAAW3pE,UAAUywE,qBAAuB,SAAS9/D,GACjD0wC,EAAS,uBACTtkD,KAAKmwE,YAAc,SACnB9N,EAASriE,KAAM,SACfowE,EAAapwE,MACuB,UAAhCA,KAAK0vE,SAASW,gBACdrwE,KAAK0vE,SAASp5B,QAElBt2C,KAAKS,KAAK,SAAUT,OAQxB4sE,EAAW3pE,UAAUuwE,4BAA8B,SAAS5/D,GACxDyuD,EAASriE,KAAM,cAQnB4sE,EAAW3pE,UAAUiV,kBAAoB,SAAS8sB,GAC9Csf,EAAS,mBACTqsB,EAAU3wE,KAAM,SAAUglC,EAAIrvB,QAAQ,IAQ1Ci3D,EAAW3pE,UAAU8U,qBAAuB,SAASitB,GACjDsf,EAAS,sBACTqsB,EAAU3wE,KAAM,SAAU,sBAAsB,GAGpD,IAAM8wE,GAAmB,SAAS+C,EAAQ/lE,GACtC,IAAK,GAAIlP,GAAI,EAAGA,EAAIi1E,EAAO10E,OAAQP,IAC/Bi1E,EAAOj1E,GAAGkP,QAAUA,GAItBmjE,EAAkB,SAAS4C,GAC7B,IAAK,GAAIj1E,GAAI,EAAGA,EAAIi1E,EAAO10E,OAAQP,IAC/B,GAAIi1E,EAAOj1E,GAAGkP,QACV,OAAO,CAGf,QAAO,GAGLu0D,EAAW,SAAShxD,EAAM6F,GAC5B,GAAMiQ,GAAW9V,EAAK6F,KACtB7F,GAAK6F,MAAQA,EACb7F,EAAK5Q,KAAK,QAASyW,EAAOiQ,IAUxB9E,EAAY,SAAShR,EAAM/H,EAAWP,GACxC,MAAOsI,GAAKsC,OAAO0O,UAAUhR,EAAKtK,OAAQuC,EAAWP,GAASu6B,MAC1D,SAAC1hC,GACGyP,EAAK5Q,KAAK,mBAAoBmB,MAKpCgxE,EAAgB,SAASvhE,EAAMtI,GAGjCsI,EAAK67D,mBAAmBt2D,KAAK7N,GACG,IAA5BsI,EAAK87D,oBACLn0D,WAAW,WACP86D,EAAoBziE,IACrB,MAILs/D,EAAY,SAASt/D,EAAM8+D,EAAa4D,EAAcC,GACpD3iE,EAAK09D,0BACD19D,EAAK09D,wBAAwBJ,OAC7Bt9D,EAAKq9D,aAAar9D,EAAK09D,wBAAyB,eAEpD19D,EAAKu9D,cAAcv9D,EAAK09D,wBAAyB,KAAM,gBAEvD19D,EAAK29D,0BACD39D,EAAK29D,wBAAwBL,OAC7Bt9D,EAAKq9D,aAAar9D,EAAK29D,wBAAyB,eAEpD39D,EAAKu9D,cAAcv9D,EAAK29D,wBAAyB,KAAM,gBAEvD39D,EAAKy9D,yBACDz9D,EAAKy9D,uBAAuBH,OAC5Bt9D,EAAKq9D,aAAar9D,EAAKy9D,uBAAwB,cAEnDz9D,EAAKu9D,cAAcv9D,EAAKy9D,uBAAwB,KAAM,eAE1Dz9D,EAAK8+D,YAAcA,EACnB9+D,EAAK0iE,aAAeA,EACpB1R,EAAShxD,EAAM,SACf++D,EAAa/+D,GACTA,EAAKq+D,UAA6C,WAAjCr+D,EAAKq+D,SAASW,gBAC/Bh/D,EAAKq+D,SAASp5B,QAEd09B,GACA3iE,EAAK5Q,KAAK,SAAU4Q,IAItB++D,EAAe,SAAS/+D,GAC1BizC,EAAS,2BAA4BjzC,EAAK89D,eACtC99D,EAAK89D,gBACLmE,EAAqBjiE,EAAK89D,cAAe,SAAS/wE,GAC1CA,EAAEmc,MACFnc,EAAEmc,SAKNlJ,EAAK89D,cAAc50D,MACnBlJ,EAAK89D,cAAc50D,QAGvBlJ,EAAKg8D,sBACLiG,EAAqBjiE,EAAKg8D,oBAAqB,SAASjvE,GAChDA,EAAEmc,MACFnc,EAAEmc,SAGNlJ,EAAKg8D,oBAAoB9yD,MACzBlJ,EAAKg8D,oBAAoB9yD,QAG7BlJ,EAAK+hE,gBACLE,EAAqBjiE,EAAK+hE,eAAgB,SAASh1E,GAC3CA,EAAEmc,MACFnc,EAAEmc,SAIVlJ,EAAKgiE,eACLC,EAAqBjiE,EAAKgiE,cAAe,SAASj1E,GAC1CA,EAAEmc,MACFnc,EAAEmc,UAMZyzD,EAAuB,SAAS38D,GAClC,GAAIA,EAAK09D,yBAA2B19D,EAAK+hE,eAAgB,CACrD,GAAMa,GAAS5iE,EAAK09D,uBACpBkF,GAAO7E,UAAW,EAClB/9D,EAAKu9D,cAAcqF,EAAQ5iE,EAAK+hE,eAAgB,eAChDp6D,WAAW,WACP,GAAMs2D,GAAMj+D,EAAK09D,uBACbO,GAAIb,MACJp9D,EAAKk9D,YAAYe,EAAK,eAGtBj+D,EAAKw7D,OAAOqH,gBACZ7R,EAAShxD,EAAM,cAEpB,KAILo+D,EAA4B,SAASp+D,GACvC,GAAIA,EAAK29D,yBAA2B39D,EAAKgiE,cAAe,CACpD,GAAMY,GAAS5iE,EAAK29D,uBACpBiF,GAAO7E,UAAW,EAClB/9D,EAAKu9D,cAAcqF,EAAQ5iE,EAAKgiE,cAAe,eAC/Cr6D,WAAW,WACP,GAAMm7D,GAAM9iE,EAAK29D,uBACbmF,GAAI1F,MACJp9D,EAAKk9D,YAAY4F,EAAK,eAGtB9iE,EAAKw7D,OAAOqH,gBACZ7R,EAAShxD,EAAM,cAEpB,KAILq8D,EAAwB,SAASr8D,GACnC,GAAuC,IAAnCA,EAAK+iE,UAAU,SAASj1E,OACxB,KAAM,IAAIL,OACN,4EAKNwvE,EAAY,SAASvvE,EAAMimC,GAC7B,GAAM7mC,GAAI,GAAIW,OAAMkmC,EAEpB,OADA7mC,GAAEY,KAAOA,EACFZ,GAGLmmD,EAAW,WACF,GAAAoX,IACPA,EAAAjnD,SAAQe,IAAR9U,MAAAg7D,EAAer7D,YAIjByzE,EAAsB,QAAtBA,GAA+BziE,GACjC,GAAuC,IAAnCA,EAAK67D,mBAAmB/tE,OAA5B,CAIA,GAAMk1E,GAAQhjE,EAAK67D,kBACnB77D,GAAK67D,wBACH77D,EAAK87D,kBACP,IAAMpkE,IACF6nE,QAAS,EACT95D,QAASzF,EAAK8F,OACdc,WAAYo8D,EAEhB/vB,GAAS,sBAAwB+vB,EAAMl1E,OAAS,eAChDkjB,EAAUhR,EAAM,oBAAqBtI,GAASnF,KAAK,WAC/CyN,EAAK87D,mBAAqB,EAC1B2G,EAAoBziE,IACrB,SAASqD,GACR,IAAK,GAAI9V,GAAI,EAAGA,EAAIy1E,EAAMl1E,OAAQP,IAC9ByS,EAAK67D,mBAAmBt2D,KAAKy9D,EAAMz1E,GAGvC,IAAIyS,EAAK87D,mBAAqB,EAM1B,MALA7oB,GACI,8DACAjzC,EAAK87D,yBAET97D,EAAK87D,mBAAqB,EAI9B,IAAMpT,GAAU,IAAM9yC,KAAK+0C,IAAI,EAAG3qD,EAAK87D,sBACrC97D,EAAK87D,mBACP7oB,EAAS,0CAA4CyV,EAAU,MAC/D/gD,WAAW,WACP86D,EAAoBziE,IACrB0oD,OAIL4T,EAA4B,SAASt8D,EAAMigE,GAC7CjgE,EAAKsC,OAAO1B,SAASZ,EAAK8F,QAAU9F,EACpCA,EAAKw7D,OAAOuB,aACRkD,EACAvB,EAAa1+D,EAAMA,EAAKggE,6BACxBtB,EAAa1+D,EAAMA,EAAKggE,8BAE5BhP,EAAShxD,EAAM,oBACfA,EAAKsG,UAAY,WACjBtG,EAAK2N,OAASsyD,GAGZ3B,EAAwB,SAASt+D,GACnC,GAAIsH,GAAUtH,EAAK07D,WACnB,IAA2B,YAAvB17D,EAAKw7D,OAAOyH,OAAsB,CAElC37D,IACA,KAAK,GAAI/Z,GAAI,EAAGA,EAAIyS,EAAK07D,YAAY5tE,OAAQP,IACzC,IAAK,GAAIitC,GAAI,EAAGA,EAAIx6B,EAAK07D,YAAYnuE,GAAGga,KAAKzZ,OAAQ0sC,IACjDlzB,EAAQ/B,MACJ+D,IAAKtJ,EAAK07D,YAAYnuE,GAAGga,KAAKizB,GAC9BnoC,SAAU2N,EAAK07D,YAAYnuE,GAAG8E,SAC9BmV,WAAYxH,EAAK07D,YAAYnuE,GAAGia,aAMhD,GAAM07D,GAAK,GAAIljE,GAAKw7D,OAAO2H,mBACvBC,mBAAoBpjE,EAAKgC,UAAY,YAAUpS,GAC/CyzE,WAAY/7D,GAMhB,OAJA47D,GAAGI,2BAA6B5E,EAAa1+D,EAAMA,EAAK2hE,8BACxDuB,EAAGK,uBAAyB7E,EAAa1+D,EAAMA,EAAK6hE,2BACpDqB,EAAGM,eAAiB9E,EAAa1+D,EAAMA,EAAKkhE,uBAC5CgC,EAAGO,YAAc/E,EAAa1+D,EAAMA,EAAK8hE,cAClCoB,GAGLpG,EAA+B,SAASjvE,GAC1C,GAAM61E,GAASt1E,EAAOs1E,MACtB,OAAKA,IASDC,OACIC,YAAa,SACb1D,WACI2D,kBAAmB,SACnBC,oBAAqB,GAAK5xE,KAAKyjB,MAC/BouD,SAAUL,EAAO9uD,MACjBovD,UAAWN,EAAO7uD,OAClBovD,aAAc,EACdC,aAAc,UAhBtBr2E,GAAKuB,KAAK,QAAS6tE,EACf1B,EAAWY,kBACX,mDAoBNI,EAA+B,SAAS4H,GAC1C,GAAMC,KAAah2E,EAAOi2E,OAAOC,UAAUC,kBAE3C,QAAQJ,GACJ,IAAK,QACD,OACIK,OACIxnE,SAAUynE,GAAcC,MAAOD,OAAc70E,IAC9C+zE,OAAO,EAElB,KAAK,QACD,OACIa,OACIxnE,SAAUynE,GAAcC,MAAOD,OAAc70E,IAC9C+zE,OACC3mE,SAAU2nE,GAAcD,MAAOC,OAAc/0E,GAI7CglB,MAAOwvD,GAAaM,MAAO,MAAUE,MAAO,KAC5C/vD,OAAQuvD,GAAaM,MAAO,MAAUE,MAAO,SAM3DlG,EAAe,SAAS7wE,EAAM08D,GAChC,MAAO,YACH,MAAOA,GAAGl7D,MAAMxB,EAAMmB,aAIxB61E,EAA4B,SAAS33E,EAAGM,GAE1C,IAAK,GADCg1E,GAASt1E,EAAEwyE,iBACRnyE,EAAI,EAAGA,EAAIi1E,EAAO10E,OAAQP,IAC/BC,EAAEg1E,EAAOj1E,KAIXu3E,EAA4B,SAAS53E,EAAGM,GAE1C,IAAK,GADCg1E,GAASt1E,EAAE4yE,iBACRvyE,EAAI,EAAGA,EAAIi1E,EAAO10E,OAAQP,IAC/BC,EAAEg1E,EAAOj1E,KAIX00E,EAAuB,SAAS/0E,EAAGM,GACrCq3E,EAA0B33E,EAAGM,GAC7Bs3E,EAA0B53E,EAAGM,GAIjCQ,GAAOJ,QAAQ2tE,WAAaA,CAE5B,IAAIkJ,OAAA,GACAE,MAAA,EAOJ32E,GAAOJ,QAAQ4jD,cAAgB,SAASx0C,GAAYynE,EAAaznE,GAOjEhP,EAAOJ,QAAQ8jD,cAAgB,SAAS10C,GAAY2nE,EAAa3nE,GAUjEhP,EAAOJ,QAAQkT,oBAAsB,SAASwB,EAAQ5M,EAAQF,GAC1D,GAAMuvE,GAAI32E,EAAOi2E,OACXW,EAAM52E,EAAOmnE,QACnB,KAAKwP,IAAMC,EACP,MAAO,KAEX,IAAMxJ,KACNA,GAAOqH,aAAe,WAClB,GAAMoC,GAAUD,EAAIE,eAAe,SACnC,KAAKD,IAAYA,EAAQn3E,OACrB,OAAO,CAEX,KAAK,GAAIP,GAAI,EAAGA,EAAI03E,EAAQn3E,OAAQP,IAChC,GAAI03E,EAAQ13E,GAAG43E,IAAIngE,QAAQ,WAAa,EACpC,OAAO,CAGf,QAAO,EAEX,IAAM+3D,GACFgI,EAAET,UAAUvH,cAAgBgI,EAAET,UAAUC,oBACxCQ,EAAET,UAAUc,eAyBhB,IAvBIrI,IACAvB,EAAOuB,aAAe,WAClB,MAAOA,GAAa1tE,MAAM01E,EAAET,UAAWt1E,aAG/CwsE,EAAO2H,kBACH4B,EAAEM,mBAAqBN,EAAEO,yBAA2BP,EAAEQ,qBAE1D/J,EAAOgD,sBACHuG,EAAES,uBAAyBT,EAAEU,6BAC7BV,EAAEW,yBAENlK,EAAOkG,gBACHqD,EAAEY,iBAAmBZ,EAAEa,uBAAyBb,EAAEc,mBAEtDrK,EAAOyH,OAAS,KACZ8B,EAAEQ,qBACF/J,EAAOyH,OAAS,UACT8B,EAAEO,wBACT9J,EAAOyH,OAAS,SACT8B,EAAEM,oBACT7J,EAAOyH,OAAS,aAEfzH,EAAOkG,iBAAoBlG,EAAOgD,uBAC9BhD,EAAO2H,mBAAsB3H,EAAOuB,cACzC,MAAO,KAGX,IAAM+I,KAAmBtwE,GAAUA,EAAQwM,SAW3C,OAAO,IAAIu5D,IARPC,OAAQA,EACRl5D,OAAQA,EACRm5D,IAAKsJ,EAAEtJ,IACP/lE,OAAQA,EACRgmE,YAAap5D,EAAO+b,iBAEpBrc,UAAWM,EAAOP,YAAc+jE;2FCn0CxC,YAiBA,SAAAC,GAAA71E,GAEA,MADA81E,GAAAC,UAAA,EACA/1E,EAAAoa,QAAA07D,EAAA,SAAA3E,GAAA,MAAA6E,GAAA7E,KAGA,QAAA7+B,GAAAtyC,GACA,aAAAA,IACA,IAAA,SACA,MAAA,IAAA61E,EAAA71E,GAAA,GACA,KAAA,SACA,MAAAkuC,UAAAluC,GAAAA,EAAA,MACA,KAAA,UACA,MAAAA,EACA,KAAA,SACA,MAAA,QAAAA,EACA,OAEAhB,MAAAgqC,QAAAhpC,GACAi2E,EAAAj2E,GAEAk2E,EAAAl2E,EACA,SACA,KAAA,IAAAzC,OAAA,2BAAAyC,KAIA,QAAAi2E,GAAAnd,GAGA,IAAA,GAFAqd,GAAA,IACA5qD,EAAA,GACAluB,EAAA,EAAAA,EAAAy7D,EAAAl7D,SAAAP,EACAkuB,GAAA4qD,EACAA,EAAA,IACA5qD,GAAA+mB,EAAAwmB,EAAAz7D,GAEA,OAAA,KAAA84E,EACA,KAEA5qD,EAAA,IAIA,QAAA2qD,GAAAE,GACA,GAAAD,GAAA,IACA5qD,EAAA,GACAxN,EAAAktB,OAAAltB,KAAAq4D,EACAr4D,GAAAqc,MACA,KAAA,GAAA/8B,GAAA,EAAAA,EAAA0gB,EAAAngB,SAAAP,EAAA,CACA,GAAAolB,GAAA1E,EAAA1gB,EACAkuB,IAAA4qD,EAAA,IAAAN,EAAApzD,GAAA,KACA0zD,EAAA,IACA5qD,GAAA+mB,EAAA8jC,EAAA3zD,IAEA,MAAA,KAAA0zD,EACA,KAEA5qD,EAAA,IApEA,IAAA,GAFAuqD,GAAA,mBACAE,KACA34E,EAAA,EAAAA,EAAA,KAAAA,EACA24E,EAAAK,OAAAC,aAAAj5E,IACA,OAAA,OAAAA,EAAA6qC,SAAA,KAAA3Y,OAAA,GAAAgnD,aAGAP,GAAA,MAAA,MACAA,EAAA,MAAA,MACAA,EAAA,MAAA,MACAA,EAAA,MAAA,MACAA,EAAA,MAAA,MACAA,EAAA,KAAA,MACAA,EAAA,MAAA,OA8DAl4E,EAAAJ,SAAA40C,UAAAA,4BC5FAx0C,EAAAJ,SAAAc,QAAApB,EAAA,mCAAAo5E,YAAA,gECAA14E,EAAAJ,SAAAc,QAAApB,EAAA,kCAAAo5E,YAAA,+DCAA14E,EAAAJ,SAAAc,QAAApB,EAAA,qCAAAo5E,YAAA,kECAA14E,EAAAJ,SAAAc,QAAApB,EAAA,oCAAAo5E,YAAA,iECAA14E,EAAAJ,SAAAc,QAAApB,EAAA,oCAAAo5E,YAAA,iECAA14E,EAAAJ,SAAAc,QAAApB,EAAA,6CAAAo5E,YAAA,0ECAA14E,EAAAJ,SAAAc,QAAApB,EAAA,8CAAAo5E,YAAA,2ECAA14E,EAAAJ,SAAAc,QAAApB,EAAA,kCAAAo5E,YAAA,+DCAA14E,EAAAJ,SAAAc,QAAApB,EAAA,8CAAAo5E,YAAA,2ECAA14E,EAAAJ,SAAAc,QAAApB,EAAA,0BAAAo5E,YAAA,uDCAA14E,EAAAJ,SAAAc,QAAApB,EAAA,6BAAAo5E,YAAA,0DCAA14E,EAAAJ,SAAAc,QAAApB,EAAA,sCAAAo5E,YAAA,mECAA,YAEA94E,GAAA84E,YAAA,EAEA94E,EAAAc,QAAA,SAAAi4E,EAAAC,GACA,KAAAD,YAAAC,IACA,KAAA,IAAAvoC,WAAA,+DCNA,YAEAzwC,GAAA84E,YAAA,CAEA,IAAAG,GAAAv5E,EAAA,qCAEAw5E,EAEA,SAAAvrC,GAAA,MAAAA,IAAAA,EAAAmrC,WAAAnrC,GAAA7sC,QAAA6sC,IAFAsrC,EAIAj5E,GAAAc,QAAA,WACA,QAAAq4E,GAAAv4E,EAAAw4E,GACA,IAAA,GAAAz5E,GAAA,EAAAA,EAAAy5E,EAAAl5E,OAAAP,IAAA,CACA,GAAA05E,GAAAD,EAAAz5E,EACA05E,GAAA5rC,WAAA4rC,EAAA5rC,aAAA,EACA4rC,EAAA3L,cAAA,EACA,SAAA2L,KAAAA,EAAA5L,UAAA,IACA,EAAAyL,EAAAp4E,SAAAF,EAAAy4E,EAAAt0D,IAAAs0D,IAIA,MAAA,UAAAL,EAAAM,EAAAC,GAGA,MAFAD,IAAAH,EAAAH,EAAAh1E,UAAAs1E,GACAC,GAAAJ,EAAAH,EAAAO,GACAP,qECxBA,YAEAh5E,GAAA84E,YAAA,CAEA,IAAAG,GAAAv5E,EAAA,qCAEAw5E,EAEA,SAAAvrC,GAAA,MAAAA,IAAAA,EAAAmrC,WAAAnrC,GAAA7sC,QAAA6sC,IAFAsrC,EAIAj5E,GAAAc,QAAA,SAAA6sC,EAAA5oB,EAAAziB,GAYA,MAXAyiB,KAAA4oB,IACA,EAAAurC,EAAAp4E,SAAA6sC,EAAA5oB,GACAziB,MAAAA,EACAmrC,YAAA,EACAigC,cAAA,EACAD,UAAA,IAGA9/B,EAAA5oB,GAAAziB,EAGAqrC,kECtBA,YAgBA,SAAA6rC,GAAA7rC,GAAA,MAAAA,IAAAA,EAAAmrC,WAAAnrC,GAAA7sC,QAAA6sC,GAdA3tC,EAAA84E,YAAA,CAEA,IAAAW,GAAA/5E,EAAA,sCAEAg6E,EAAAF,EAAAC,GAEAE,EAAAj6E,EAAA,4BAEAggD,EAAA85B,EAAAG,GAEAC,EAAAl6E,EAAA,qBAEA6R,EAAAioE,EAAAI,EAIA55E,GAAAc,QAAA,SAAA+4E,EAAAC,GACA,GAAA,kBAAAA,IAAA,OAAAA,EACA,KAAA,IAAArpC,WAAA,gEAAA,KAAAqpC,EAAA,aAAA,EAAAvoE,EAAAzQ,SAAAg5E,IAGAD,GAAA71E,WAAA,EAAA07C,EAAA5+C,SAAAg5E,GAAAA,EAAA91E,WACA27C,aACAr9C,MAAAu3E,EACApsC,YAAA,EACAggC,UAAA,EACAC,cAAA,KAGAoM,IAAAJ,EAAA54E,SAAA,EAAA44E,EAAA54E,SAAA+4E,EAAAC,GAAAD,EAAA3zC,UAAA4zC,yHC/BA,YAEA95E,GAAA84E,YAAA,CAEA,IAAAc,GAAAl6E,EAAA,qBAEA6R,EAEA,SAAAo8B,GAAA,MAAAA,IAAAA,EAAAmrC,WAAAnrC,GAAA7sC,QAAA6sC,IAFAisC,EAIA55E,GAAAc,QAAA,SAAAsR,EAAAnS,GACA,IAAAmS,EACA,KAAA,IAAA2nE,gBAAA,4DAGA,QAAA95E,GAAA,gBAAA,KAAAA,EAAA,aAAA,EAAAsR,EAAAzQ,SAAAb,KAAA,kBAAAA,GAAAmS,EAAAnS,kDCfA,YAYA,SAAAu5E,GAAA7rC,GAAA,MAAAA,IAAAA,EAAAmrC,WAAAnrC,GAAA7sC,QAAA6sC,GAVA3tC,EAAA84E,YAAA,CAEA,IAAAkB,GAAAt6E,EAAA,0BAEAu6E,EAAAT,EAAAQ,GAEAE,EAAAx6E,EAAA,2BAEAyC,EAAAq3E,EAAAU,EAIAl6E,GAAAc,QAAA,WACA,QAAAq5E,GAAAC,EAAAz6E,GACA,GAAAw6D,MACAkgB,GAAA,EACAC,GAAA,EACAC,MAAAv4E,EAEA,KACA,IAAA,GAAAw4E,GAAApgB,GAAA,EAAAj4D,EAAArB,SAAAs5E,KAAAC,GAAAG,EAAApgB,EAAAh4D,QAAAC,QACA83D,EAAAxiD,KAAA6iE,EAAAl4E,QAEA3C,GAAAw6D,EAAAj6D,SAAAP,GAHA06E,GAAA,IAKA,MAAA13E,GACA23E,GAAA,EACAC,EAAA53E,EACA,QACA,KACA03E,GAAAjgB,EAAA,QAAAA,EAAA,SACA,QACA,GAAAkgB,EAAA,KAAAC,IAIA,MAAApgB,GAGA,MAAA,UAAAigB,EAAAz6E,GACA,GAAA2B,MAAAgqC,QAAA8uC,GACA,MAAAA,EACA,KAAA,EAAAH,EAAAn5E,SAAAysC,OAAA6sC,IACA,MAAAD,GAAAC,EAAAz6E,EAEA,MAAA,IAAA8wC,WAAA,6IC/CA,YAcA,SAAA+oC,GAAA7rC,GAAA,MAAAA,IAAAA,EAAAmrC,WAAAnrC,GAAA7sC,QAAA6sC,GAZA3tC,EAAA84E,YAAA,CAEA,IAAA52E,GAAAxC,EAAA,8BAEA+1B,EAAA+jD,EAAAt3E,GAEAu4E,EAAA/6E,EAAA,qBAEAg7E,EAAAlB,EAAAiB,GAEAE,EAAA,kBAAAD,GAAA55E,SAAA,gBAAA20B,GAAA30B,QAAA,SAAA6sC,GAAA,aAAAA,IAAA,SAAAA,GAAA,MAAAA,IAAA,kBAAA+sC,GAAA55E,SAAA6sC,EAAAgS,cAAA+6B,EAAA55E,SAAA6sC,IAAA+sC,EAAA55E,QAAAkD,UAAA,eAAA2pC,GAIA3tC,GAAAc,QAAA,kBAAA45E,GAAA55E,SAAA,WAAA65E,EAAAllD,EAAA30B,SAAA,SAAA6sC,GACA,WAAA,KAAAA,EAAA,YAAAgtC,EAAAhtC,IACA,SAAAA,GACA,MAAAA,IAAA,kBAAA+sC,GAAA55E,SAAA6sC,EAAAgS,cAAA+6B,EAAA55E,SAAA6sC,IAAA+sC,EAAA55E,QAAAkD,UAAA,aAAA,KAAA2pC,EAAA,YAAAgtC,EAAAhtC,mFCnBAvtC,EAAAJ,QAAAN,EAAA,yFC4BA,SAAAR,GAAA,GAAA,gBAAAc,QAAA,KAAAI,EAAAA,EAAAJ,QAAAd,QAAA,IAAA,kBAAA07E,SAAAA,OAAAC,IAAAD,UAAA17E,OAAA,CAAA,GAAAU,EAAA,oBAAA62E,QAAA72E,EAAA62E,WAAA,KAAAj2E,EAAAZ,EAAAY,EAAA,mBAAA4R,QAAAxS,EAAAwS,MAAAxS,EAAAk7E,QAAA57E,MAAA,WAAA,GAAA07E,GAAAx6E,EAAAJ,CAAA,OAAA,SAAAd,GAAAC,EAAAC,EAAAC,GAAA,QAAAC,GAAAC,EAAAC,GAAA,IAAAJ,EAAAG,GAAA,CAAA,IAAAJ,EAAAI,GAAA,CAAA,GAAAE,GAAA,kBAAAs7E,UAAAA,OAAA,KAAAv7E,GAAAC,EAAA,MAAAA,GAAAF,GAAA,EAAA,IAAAI,EAAA,MAAAA,GAAAJ,GAAA,EAAA,IAAAK,GAAA,GAAAC,OAAA,uBAAAN,EAAA,IAAA,MAAAK,GAAAE,KAAA,mBAAAF,EAAA,GAAAG,GAAAX,EAAAG,IAAAS,WAAAb,GAAAI,GAAA,GAAAU,KAAAF,EAAAC,QAAA,SAAAd,GAAA,GAAAE,GAAAD,EAAAI,GAAA,GAAAL,EAAA,OAAAI,GAAAF,GAAAF,IAAAa,EAAAA,EAAAC,QAAAd,EAAAC,EAAAC,EAAAC,GAAA,MAAAD,GAAAG,GAAAS,QAAA,IAAA,GAAAL,GAAA,kBAAAo7E,UAAAA,QAAAx7E,EAAA,EAAAA,EAAAF,EAAAa,OAAAX,IAAAD,EAAAD,EAAAE,GAAA,OAAAD,KAAAa,GAAA,SAAA46E,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,GAEA,QAAAE,GAAA3+D,GACA,GAAAiV,GAAA,GAAA2pD,GAAA5+D,GACAxP,EAAAykB,EAAAzkB,SAIA,OAHAykB,GAAA4pD,WAAA,GACA5pD,EAAA6pD,YACA7pD,EAAAvT,OACAlR,EAPA,GAAAouE,GAAAH,EAAAM,iBAUAN,GAAAE,IAAA,SAAA3+D,GACA,MAAA2+D,GAAA3+D,IAGAy+D,EAAA92E,UAAAg3E,IAAA,WACA,MAAAA,GAAAj6E,aAKAs6E,GAAA,SAAAN,EAAA36E,EAAAJ,GACA,YAOA,SAAAs7E,KACAv6E,KAAAw6E,kBAAA,EACAx6E,KAAAy6E,aAAA,EACAz6E,KAAA06E,WAAA,GAAAC,GAAA,IACA36E,KAAA46E,aAAA,GAAAD,GAAA,IACA36E,KAAA66E,oBAAA,EACA76E,KAAA86E,oBAAA,CACA,IAAAzpE,GAAArR,IACAA,MAAA+6E,YAAA,WACA1pE,EAAA2pE,gBAEAh7E,KAAAi7E,UAAAC,EAyDA,QAAAC,GAAAvf,EAAAwf,EAAAC,GACAr7E,KAAA06E,WAAA9jE,KAAAglD,EAAAwf,EAAAC,GACAr7E,KAAAs7E,aAGA,QAAAC,GAAA3f,EAAAwf,EAAAC,GACAr7E,KAAA46E,aAAAhkE,KAAAglD,EAAAwf,EAAAC,GACAr7E,KAAAs7E,aAGA,QAAAE,GAAA1vE,GACA9L,KAAA46E,aAAAa,SAAA3vE,GACA9L,KAAAs7E,aAtFA,GAAAI,EACA,KAAA,KAAA,IAAA58E,OAAA,MAAAX,GAAAu9E,EAAAv9E,EACA,GAAA+8E,GAAAlB,EAAA,cACAW,EAAAX,EAAA,WACAn4C,EAAAm4C,EAAA,SAgBAO,GAAAt3E,UAAA04E,aAAA,SAAA/f,GACA,GAAAzhD,GAAAna,KAAAi7E,SAGA,OAFAj7E,MAAAi7E,UAAArf,EACA57D,KAAAw6E,kBAAA,EACArgE,GAGAogE,EAAAt3E,UAAA24E,mBAAA,WACA,MAAA57E,MAAAw6E,kBAGAD,EAAAt3E,UAAA44E,iBAAA,WACA77E,KAAA86E,oBAAA,GAGAP,EAAAt3E,UAAA64E,6BAAA,WACAj6C,EAAAk6C,cACA/7E,KAAA86E,oBAAA,IAIAP,EAAAt3E,UAAA+4E,gBAAA,WACA,MAAAh8E,MAAAy6E,aAAAz6E,KAAA66E,oBAIAN,EAAAt3E,UAAAg5E,WAAA,SAAA99E,EAAA+9E,GACAA,GACAC,EAAAC,OAAAC,MAAA,UAAAl+E,YAAAW,OAAAX,EAAAwW,MAAAxW,GACA,MACAg+E,EAAAG,KAAA,IAEAt8E,KAAAu8E,WAAAp+E,IAIAo8E,EAAAt3E,UAAAs5E,WAAA,SAAA3gB,EAAAyf,GAKA,GAJA,IAAAh7E,UAAAlB,SACAk8E,EAAAzf,EACAA,EAAA,WAAA,KAAAyf,KAEA,mBAAAriE,YACAA,WAAA,WACA4iD,EAAAyf,IACA,OACA,KACAr7E,KAAAi7E,UAAA,WACArf,EAAAyf,KAEA,MAAAl9E,GACA,KAAA,IAAAW,OAAA,oEAmBA+iC,EAAAk6C,aAKAxB,EAAAt3E,UAAAu5E,YAAA,SAAA5gB,EAAAwf,EAAAC,GACAr7E,KAAA86E,mBACAK,EAAAj8E,KAAAc,KAAA47D,EAAAwf,EAAAC,GAEAr7E,KAAAi7E,UAAA,WACAjiE,WAAA,WACA4iD,EAAA18D,KAAAk8E,EAAAC,IACA,QAKAd,EAAAt3E,UAAAw5E,OAAA,SAAA7gB,EAAAwf,EAAAC,GACAr7E,KAAA86E,mBACAS,EAAAr8E,KAAAc,KAAA47D,EAAAwf,EAAAC,GAEAr7E,KAAAi7E,UAAA,WACArf,EAAA18D,KAAAk8E,EAAAC,MAKAd,EAAAt3E,UAAAy5E,eAAA,SAAA5wE,GACA9L,KAAA86E,mBACAU,EAAAt8E,KAAAc,KAAA8L,GAEA9L,KAAAi7E,UAAA,WACAnvE,EAAA6wE,uBA/BApC,EAAAt3E,UAAAu5E,YAAArB,EACAZ,EAAAt3E,UAAAw5E,OAAAlB,EACAhB,EAAAt3E,UAAAy5E,eAAAlB,GAmCAjB,EAAAt3E,UAAA25E,YAAA,SAAAphB,GACA,KAAAA,EAAAr8D,SAAA,GAAA,CACA,GAAAy8D,GAAAJ,EAAAjD,OACA,IAAA,kBAAAqD,GAAA,CAIA,GAAAwf,GAAA5f,EAAAjD,QACA8iB,EAAA7f,EAAAjD,OACAqD,GAAA18D,KAAAk8E,EAAAC,OALAzf,GAAA+gB,oBASApC,EAAAt3E,UAAA+3E,aAAA,WACAh7E,KAAA48E,YAAA58E,KAAA46E,cACA56E,KAAA68E,SACA78E,KAAA66E,oBAAA,EACA76E,KAAA48E,YAAA58E,KAAA06E,aAGAH,EAAAt3E,UAAAq4E,WAAA,WACAt7E,KAAAy6E,cACAz6E,KAAAy6E,aAAA,EACAz6E,KAAAi7E,UAAAj7E,KAAA+6E,eAIAR,EAAAt3E,UAAA45E,OAAA,WACA78E,KAAAy6E,aAAA,GAGAp7E,EAAAJ,QAAAs7E,EACAl7E,EAAAJ,QAAAy8E,eAAAA,IAEAoB,UAAA,GAAAC,aAAA,GAAAC,SAAA,KAAAC,GAAA,SAAAjD,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAmD,EAAAC,EAAAC,GACA,GAAAC,IAAA,EACAC,EAAA,SAAAC,EAAAp/E,GACA6B,KAAAiZ,QAAA9a,IAGAq/E,EAAA,SAAAr/E,EAAAu2D,GACAA,EAAA+oB,wBAAA,EACA/oB,EAAAgpB,eAAAC,MAAAL,EAAAA,EAAA,KAAAt9E,KAAA7B,IAGAy/E,EAAA,SAAA9R,EAAApX,GACA,IAAA,SAAA10D,KAAA69E,YACA79E,KAAA89E,iBAAAppB,EAAA70D,SAIAk+E,EAAA,SAAA5/E,EAAAu2D,GACAA,EAAA+oB,wBAAAz9E,KAAAiZ,QAAA9a,GAGA47E,GAAA92E,UAAAxB,KAAA,SAAAqqE,GACAuR,IACAA,GAAA,EACAtD,EAAA92E,UAAA+6E,eAAAZ,EAAAa,wBACAlE,EAAA92E,UAAAi7E,YAAAd,EAAAe,qBAEA,IAAAC,GAAAjB,EAAArR,GACAv7C,EAAA,GAAAwpD,GAAAmD,EACA3sD,GAAAytD,eAAAh+E,KAAA,EACA,IAAAH,GAAAG,KAAAG,SAEA,IADAowB,EAAA8tD,YAAAD,GACAA,YAAArE,GAAA,CACA,GAAArlB,IACA+oB,wBAAA,EACA3xE,QAAAykB,EACA1wB,OAAAA,EACA69E,eAAAU,EAEAv+E,GAAA89E,MAAAT,EAAAM,MAAAv8E,GAAAsvB,EAAAmkC,GACA0pB,EAAAT,MACAC,EAAAG,MAAA98E,GAAAsvB,EAAAmkC,GACAnkC,EAAA+tD,aAAAF,OAEA7tD,GAAAutD,iBAAAj+E,EAEA,OAAA0wB,IAGAwpD,EAAA92E,UAAAo7E,YAAA,SAAAzxC,OACA3rC,KAAA2rC,GACA5sC,KAAA69E,UAAA,QAAA79E,KAAA69E,UACA79E,KAAAu+E,SAAA3xC,GAEA5sC,KAAA69E,WAAA,QAAA79E,KAAA69E,WAIA9D,EAAA92E,UAAAu7E,SAAA,WACA,MAAA,WAAA,QAAAx+E,KAAA69E,YAGA9D,EAAAt4E,KAAA,SAAAqqE,EAAAvqE,GACA,MAAAw4E,GAAAjmE,QAAAvS,GAAAE,KAAAqqE,UAIA2S,GAAA,SAAAzE,EAAA36E,EAAAJ,GACA,YAGA,SAAAy/E,KACA,IAAA3E,UAAA4E,IAAA5E,QAAA1Q,GACA,MAAAlrE,IACA,MAAAwgF,GALA,GAAAtV,EACA,oBAAA0Q,WAAA1Q,EAAA0Q,QAMA,IAAA4E,GAAA3E,EAAA,cACA2E,GAAAD,WAAAA,EACAr/E,EAAAJ,QAAA0/E,IAEAC,YAAA,KAAAC,GAAA,SAAA7E,EAAA36E,EAAAJ,GACA,YACA,IAAA6/E,GAAAtyC,OAAA1U,MACA,IAAAgnD,EAAA,CACA,GAAAC,GAAAD,EAAA,MACAE,EAAAF,EAAA,KACAC,GAAA,SAAAC,EAAA,SAAA,EAGA3/E,EAAAJ,QAAA,SAAA86E,GA4DA,QAAAkF,GAAAryC,EAAAsyC,GACA,GAAAtjB,EAEA,IADA,MAAAhvB,IAAAgvB,EAAAhvB,EAAAsyC,IACA,kBAAAtjB,GAAA,CACA,GAAAhiC,GAAA,UAAAiI,EAAAs9C,YAAAvyC,GAAA,mBACA/K,EAAA4H,SAAAy1C,GAAA,GACA,MAAA,IAAAnF,GAAArqC,UAAA9V,GAEA,MAAAgiC,GAGA,QAAAwjB,GAAAxyC,GAGA,MADAqyC,GAAAryC,EADA5sC,KAAAq/E,OAEA3+E,MAAAksC,EAAA5sC,MAiBA,QAAAs/E,GAAA1yC,GACA,MAAAA,GAAA5sC,MAEA,QAAAu/E,GAAA3yC,GACA,GAAAgK,IAAA52C,IAEA,OADA42C,GAAA,IAAAA,EAAA3vB,KAAAC,IAAA,EAAA0vB,EAAAhK,EAAAztC,SACAytC,EAAAgK,GAhGA,GAKA4oC,GALA39C,EAAAm4C,EAAA,UACAyF,EAAA59C,EAAA49C,WACA59C,GAAA69C,YAyEA3F,GAAA92E,UAAA/D,KAAA,SAAAggF,GACA,GAAA5+E,MAAAwwB,MAAA5xB,KAAAmB,UAAA,EAWA,OADAC,GAAAsW,KAAAsoE,GACAl/E,KAAA29E,MAAAyB,MAAAn+E,OAAAA,GAAAX,MAAAW,KAWA84E,EAAA92E,UAAA08E,IAAA,SAAAC,GACA,GACAC,GADAC,EAAA,gBAAAF,EAEA,IAAAE,EAQAD,EAAAN,MAPA,IAAAE,EAAA,CACA,GAAAM,GAAAP,EAAAI,EACAC,GAAA,OAAAE,EAAAA,EAAAT,MAEAO,GAAAP,CAKA,OAAAt/E,MAAA29E,MAAAkC,MAAA5+E,OAAAA,GAAA2+E,MAAA3+E,QAIA+7E,SAAA,KAAAgD,GAAA,SAAAhG,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAkG,EAAAC,EAAA9C,GACA,GAAAv7C,GAAAm4C,EAAA,UACAmG,EAAAt+C,EAAAs+C,SACAC,EAAAv+C,EAAAu+C,SACAC,EAAAtG,EAAAuG,MAEAvG,GAAA92E,UAAA,MAAA82E,EAAA92E,UAAAs9E,OAAA,WACA,IAAAnD,EAAAjqC,eAAA,MAAAnzC,MAAAwgF,MAAA,2BAIA,KAFA,GAAA10E,GAAA9L,KACAygF,EAAA30E,EACAA,EAAA40E,kBAAA,CACA,IAAA50E,EAAA60E,UAAAF,GAAA,CACAA,EAAAG,eACAH,EAAAI,YAAAN,SAEAE,EAAAK,iBAEA,OAGA,GAAAC,GAAAj1E,EAAAk1E,mBACA,IAAA,MAAAD,IAAAA,EAAAL,iBAAA,CACA50E,EAAA80E,eACA90E,EAAA+0E,YAAAN,SAEAz0E,EAAAg1E,iBAEA,OAEAh1E,EAAA80E,gBAAA90E,EAAA+0E,YAAAN,SACAz0E,EAAAm1E,sBACAR,EAAA30E,EACAA,EAAAi1E,IAKAhH,EAAA92E,UAAAi+E,oBAAA,WACAlhF,KAAAmhF,8BAGApH,EAAA92E,UAAAm+E,6BAAA,WACA,WAAAngF,KAAAjB,KAAAmhF,4BACAnhF,KAAAmhF,4BAAA,GAGApH,EAAA92E,UAAA09E,UAAA,SAAAU,GACA,MAAAA,KAAArhF,MACAA,KAAAmhF,2BAAA,EACAnhF,KAAAshF,mBACA,IAEAthF,KAAAkhF,wBACAlhF,KAAAohF,iCACAphF,KAAAshF,mBACA,KAMAvH,EAAA92E,UAAA69E,gBAAA,WACA9gF,KAAAohF,gCACAphF,KAAAuhF,WAIAxH,EAAA92E,UAAAs+E,QAAA,WACAvhF,KAAA0gF,mBACA1gF,KAAAwhF,gBACAnB,EAAA5D,OAAAz8E,KAAAyhF,gBAAAzhF,SAAAiB,MAGA84E,EAAA92E,UAAAw+E,gBAAA,WACAzhF,KAAA0hF,UAAA,GAAA1hF,KAAA28E,mBAGA5C,EAAA92E,UAAA0+E,eAAA,WACA3hF,KAAA4hF,mBAAA3gF,IAGA84E,EAAA92E,UAAAy9E,eAAA,WACA,MAAA1gF,MAAA6hF,cAAA7hF,KAAA8hF,gBAGA/H,EAAA92E,UAAA8+E,cAAA,WACA,MAAA/hF,MAAA6hF,cAAA7hF,KAAAgiF,eAGAjI,EAAA92E,UAAAg/E,kBAAA,SAAAC,EAAAC,GACA,GAAAtgD,EAAA0I,QAAA23C,GACA,IAAA,GAAAtjF,GAAA,EAAAA,EAAAsjF,EAAA/iF,SAAAP,EACAoB,KAAAiiF,kBAAAC,EAAAtjF,GAAAujF,OAEA,QAAAlhF,KAAAihF,EACA,GAAA,kBAAAA,IACA,IAAAC,EAAA,CACA,GAAAhkF,GAAAgiF,EAAA+B,GAAAhjF,KAAAc,KAAAk+E,cACA//E,KAAAiiF,IACApgF,KAAAoiF,kBAAAjkF,EAAAA,GACAkiF,EAAA9D,WAAAp+E,EAAAA,SAIA+jF,GAAAG,iBAAAriF,OAKA+5E,EAAA92E,UAAAq+E,gBAAA,WACA,GAAAY,GAAAliF,KAAAsiF,WACAtiF,MAAA2hF,iBACAtB,EAAA5D,OAAAz8E,KAAAiiF,kBAAAjiF,KAAAkiF,IAGAnI,EAAA92E,UAAAs/E,wBAAA,WACAviF,KAAA0gF,mBACA1gF,KAAAiiF,kBAAAjiF,KAAAsiF,aAAA,GACAtiF,KAAA2hF,mBAIA5H,EAAA92E,UAAAo/E,iBAAA,WACAriF,KAAAugF,aAKAvD,SAAA,KAAAwF,GAAA,SAAAxI,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAAwjF,GAMA,QAAAC,GAAAC,EAAAvyD,EAAAtkB,GACA,MAAA,UAAA3N,GACA,GAAAykF,GAAA92E,EAAAoyE,aACA2E,GAAA,IAAA,GAAAjkF,GAAA,EAAAA,EAAA+jF,EAAAxjF,SAAAP,EAAA,CACA,GAAAkkF,GAAAH,EAAA/jF,EAEA,IAAAkkF,IAAAhkF,OACA,MAAAgkF,GAAAA,EAAA7/E,oBAAAnE,QACA,GAAAX,YAAA2kF,GACA,MAAA3C,GAAA/vD,GAAAlxB,KAAA0jF,EAAAzkF,OAEA,IAAA,kBAAA2kF,GAAA,CACA,GAAAC,GAAA5C,EAAA2C,GAAA5jF,KAAA0jF,EAAAzkF,EACA,IAAA4kF,IAAA3C,EACA,MAAA2C,EACA,IAAAA,EACA,MAAA5C,GAAA/vD,GAAAlxB,KAAA0jF,EAAAzkF,OAEA,IAAA0jC,EAAAmhD,SAAA7kF,GAAA,CAEA,IAAA,GADAmhB,GAAA2jE,EAAAH,GACAj3C,EAAA,EAAAA,EAAAvsB,EAAAngB,SAAA0sC,EAAA,CACA,GAAA7nB,GAAA1E,EAAAusB,EACA,IAAAi3C,EAAA9+D,IAAA7lB,EAAA6lB,GACA,QAAA6+D,GAGA,MAAA1C,GAAA/vD,GAAAlxB,KAAA0jF,EAAAzkF,IAGA,MAAAskF,IAlCA,GAAA5gD,GAAAm4C,EAAA,UACAiJ,EAAAjJ,EAAA,SAAA16D,KACA6gE,EAAAt+C,EAAAs+C,SACAC,EAAAv+C,EAAAu+C,QAmCA,OAAAsC,MAGAQ,QAAA,GAAAlG,SAAA,KAAAmG,GAAA,SAAAnJ,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,GASA,QAAAqJ,KACApjF,KAAAqjF,OAAA,GAAAD,GAAAE,cAAAC,KAmBA,QAAAC,KACA,GAAAC,EAAA,MAAA,IAAAL,GAGA,QAAAG,KACA,GAAAjM,GAAAoM,EAAAvkF,OAAA,CACA,IAAAm4E,GAAA,EACA,MAAAoM,GAAApM,GAnCA,GAAAmM,IAAA,EACAC,IAgEA,OA9DA3J,GAAA92E,UAAA0gF,gBAAA,aACA5J,EAAA92E,UAAA2gF,aAAA,aACA7J,EAAA92E,UAAA4gF,YAAA,WAAA,MAAA,OACA9J,EAAA+J,aAAA/J,EAAA92E,UAAA6gF,aAAA,aAKAV,EAAAngF,UAAA2gF,aAAA,eACA3iF,KAAAjB,KAAAqjF,SACArjF,KAAAqjF,OAAAM,gBAAA,KACAD,EAAA9sE,KAAA5W,KAAAqjF,UAIAD,EAAAngF,UAAA4gF,YAAA,WACA,OAAA5iF,KAAAjB,KAAAqjF,OAAA,CACA,GAAAU,GAAAL,EAAArE,MACA9uD,EAAAwzD,EAAAJ,eAEA,OADAI,GAAAJ,gBAAA,KACApzD,EAEA,MAAA,OAcA6yD,EAAAE,cAAA,KACAF,EAAAtrD,OAAA0rD,EACAJ,EAAAY,0BAAA,aACAZ,EAAAa,wBAAA,WACA,GAAAC,GAAAnK,EAAA92E,UAAA2gF,aACAO,EAAApK,EAAA92E,UAAA4gF,YACAO,EAAArK,EAAA+J,aACAO,EAAAtK,EAAA92E,UAAA6gF,aACAQ,EAAAvK,EAAA92E,UAAA0gF,eACAP,GAAAY,0BAAA,WACAjK,EAAA92E,UAAA2gF,aAAAM,EACAnK,EAAA92E,UAAA4gF,YAAAM,EACApK,EAAA+J,aAAAM,EACArK,EAAA92E,UAAA6gF,aAAAO,EACAtK,EAAA92E,UAAA0gF,gBAAAW,EACAb,GAAA,GAEAA,GAAA,EACA1J,EAAA92E,UAAA2gF,aAAAR,EAAAngF,UAAA2gF,aACA7J,EAAA92E,UAAA4gF,YAAAT,EAAAngF,UAAA4gF,YACA9J,EAAA+J,aAAA/J,EAAA92E,UAAA6gF,aAAAP,EACAxJ,EAAA92E,UAAA0gF,gBAAA,WACA,GAAAY,GAAAvkF,KAAA8jF,cACAS,IAAA,MAAAA,EAAAZ,kBAAAY,EAAAZ,gBAAA3jF,QAGAojF,QAGAoB,GAAA,SAAAxK,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAqJ,GA6MA,QAAAqB,GAAAljE,EAAAzV,GACA,OAAAA,QAAAA,GA0FA,QAAA44E,KAAA,OAAA,EAuBA,QAAAC,GAAAC,EAAA9wE,EAAAqF,GACA,GAAArN,GAAA9L,IACA,KACA4kF,EAAA9wE,EAAAqF,EAAA,SAAA0rE,GACA,GAAA,kBAAAA,GACA,KAAA,IAAAn1C,WAAA,qCACA7N,EAAA4H,SAAAo7C,GAEA/4E,GAAAg5E,4BAAAD,KAEA,MAAA1mF,GACA,MAAAA,IAIA,QAAA4mF,GAAAF,GACA,IAAA7kF,KAAA0gF,iBAAA,MAAA1gF,KAEA,IAAAglF,GAAAhlF,KAAAsiF,gBACArhF,KAAA+jF,EACAnjD,EAAA0I,QAAAy6C,GACAA,EAAApuE,KAAAiuE,GAEA7kF,KAAAs+E,cAAA0G,EAAAH,IAGA7kF,KAAAs+E,aAAAuG,GAIA,QAAAI,KACA,MAAAjlF,MAAA4hF,eAGA,QAAAsD,GAAAL,GACA7kF,KAAA4hF,eAAAiD,EAGA,QAAAM,KACAnlF,KAAAghF,wBAAA//E,GACAjB,KAAA4hF,mBAAA3gF,GAGA,QAAAmkF,GAAArE,EAAAsE,GACA,GAAA,IAAA,EAAAA,GAAA,CACArlF,KAAAghF,oBAAAD,CACA,IAAAuE,GAAAvE,EAAAI,+BACAlgF,KAAAqkF,IACAA,EAAA,GAEAvE,EAAAI,2BAAAmE,EAAA,EAEA,IAAA,EAAAD,IAAAtE,EAAAvC,YACAx+E,KAAAq+E,YAAA0C,EAAAxC,UAIA,QAAAgH,GAAAxE,EAAAsE,GACA,IAAA,EAAAA,IAAAtE,EAAAvC,YACAx+E,KAAAq+E,YAAA0C,EAAAxC,UAKA,QAAAJ,KACA,GAAA5tD,GAAAvwB,KAAAu+E,QACA,YAAAt9E,KAAAsvB,GACAA,YAAAwpD,GACAxpD,EAAA85C,cACA95C,EAAAhvB,YAEA,GAIAgvB,EAGA,QAAAi1D,KACAxlF,KAAAqjF,OAAA,GAAAC,GAAAtjF,KAAA8jF,gBAGA,QAAA2B,GAAA/wE,EAAAgxE,GACA,GAAAC,EAAAjxE,GAAA,CACA,GAAAqvE,GAAA/jF,KAAAqjF,MAIA,QAHApiF,KAAA8iF,GACA2B,IAAA3B,EAAAA,EAAA6B,aAEA3kF,KAAA8iF,EACAA,EAAA8B,iBAAAnxE,OACA,KAAAA,EAAAoxE,iBAAA,CACA,GAAAC,GAAAC,EAAAtxE,EACAmtB,GAAAokD,kBAAAvxE,EAAA,QACAqxE,EAAAnsD,QAAA,KAAAmsD,EAAApxE,MAAAytB,KAAA,OACAP,EAAAokD,kBAAAvxE,EAAA,oBAAA,KAKA,QAAAwxE,GAAAC,EAAAC,EAAA7kE,EAAAzV,EACAi1E,GACA,OAAA9/E,KAAAklF,GAAA,OAAAC,GACAC,EAAA,CACA,OAAAplF,KAAA8/E,GAAAA,EAAAuF,wBAAA,MACA,IAAA,IAAA,MAAAx6E,EAAA+xE,WAAA,MAEAt8D,KAAAA,GAAA,IACA,IAAAglE,GAAA,GACAC,EAAA,EACA,IAAAJ,EAAA/C,OAAA,CAGA,IAAA,GAFAoD,GAAAL,EAAA/C,OAAA1uE,MAAAkH,MAAA,MACAlH,EAAA+xE,EAAAD,GACA7nF,EAAA+V,EAAAxV,OAAA,EAAAP,GAAA,IAAAA,EAAA,CACA,GAAA+nF,GAAAhyE,EAAA/V,EACA,KAAAgoF,EAAAC,KAAAF,GAAA,CACA,GAAAG,GAAAH,EAAApvB,MAAAwvB,EACAD,KACAP,EAAA,MAAAO,EAAA,GACA,IAAAA,EAAA,GAAA,IAAAA,EAAA,GAAA,IAEA,QAIA,GAAAnyE,EAAAxV,OAAA,EAEA,IAAA,GADA6nF,GAAAryE,EAAA,GACA/V,EAAA,EAAAA,EAAA6nF,EAAAtnF,SAAAP,EAEA,GAAA6nF,EAAA7nF,KAAAooF,EAAA,CACApoF,EAAA,IACA4nF,EAAA,KAAAC,EAAA7nF,EAAA,GAEA,QAMA,GAAAomC,GAAA,8BAAAzjB,EACA,WAAAglE,EAAA,yDAEAC,CACA16E,GAAA00E,MAAAx7C,GAAA,EAAAohD,IAIA,QAAAa,GAAA1lE,EAAA2lE,GACA,GAAAttD,GAAArY,EACA,yDAEA,OADA2lE,KAAAttD,GAAA,QAAAstD,EAAA,aACAhsE,EAAA0e,GAGA,QAAA1e,GAAA0e,EAAAutD,EAAAr7E,GACA,GAAAkT,GAAAooE,SAAA,CACA,GACA7C,GADA8C,EAAA,GAAAC,GAAA1tD,EAEA,IAAAutD,EACAr7E,EAAAs2E,kBAAAiF,OACA,IAAAroE,GAAAykE,kBAAAc,EAAAxK,EAAA+J,gBACAS,EAAAsB,iBAAAwB,OACA,CACA,GAAAtB,GAAAC,EAAAqB,EACAA,GAAA1yE,MAAAoxE,EAAAnsD,QAAA,KAAAmsD,EAAApxE,MAAAytB,KAAA,MAGAmlD,GAAA,UAAAF,IACAG,EAAAH,EAAA,IAAA,IAIA,QAAAI,GAAA7tD,EAAA8tD,GACA,IAAA,GAAA9oF,GAAA,EAAAA,EAAA8oF,EAAAvoF,OAAA,IAAAP,EACA8oF,EAAA9oF,GAAAgY,KAAA,wBACA8wE,EAAA9oF,GAAA8oF,EAAA9oF,GAAAwjC,KAAA,KAKA,OAHAxjC,GAAA8oF,EAAAvoF,SACAuoF,EAAA9oF,GAAA8oF,EAAA9oF,GAAAwjC,KAAA,OAEAxI,EAAA,KAAA8tD,EAAAtlD,KAAA,MAGA,QAAAulD,GAAAD,GACA,IAAA,GAAA9oF,GAAA,EAAAA,EAAA8oF,EAAAvoF,SAAAP,GACA,IAAA8oF,EAAA9oF,GAAAO,QACAP,EAAA,EAAA8oF,EAAAvoF,QAAAuoF,EAAA9oF,GAAA,KAAA8oF,EAAA9oF,EAAA,GAAA,MACA8oF,EAAApvC,OAAA15C,EAAA,GACAA,KAKA,QAAAgpF,GAAAF,GAEA,IAAA,GADArkB,GAAAqkB,EAAA,GACA9oF,EAAA,EAAAA,EAAA8oF,EAAAvoF,SAAAP,EAAA,CAMA,IAAA,GALAub,GAAAutE,EAAA9oF,GACAipF,EAAAxkB,EAAAlkE,OAAA,EACA2oF,EAAAzkB,EAAAwkB,GACAE,GAAA,EAEAl8C,EAAA1xB,EAAAhb,OAAA,EAAA0sC,GAAA,IAAAA,EACA,GAAA1xB,EAAA0xB,KAAAi8C,EAAA,CACAC,EAAAl8C,CACA,OAIA,IAAA,GAAAA,GAAAk8C,EAAAl8C,GAAA,IAAAA,EAAA,CACA,GAAA86C,GAAAxsE,EAAA0xB,EACA,IAAAw3B,EAAAwkB,KAAAlB,EAIA,KAHAtjB,GAAAgc,MACAwI,IAKAxkB,EAAAlpD,GAIA,QAAAusE,GAAA/xE,GAEA,IAAA,GADA4b,MACA3xB,EAAA,EAAAA,EAAA+V,EAAAxV,SAAAP,EAAA,CACA,GAAA+nF,GAAAhyE,EAAA/V,GACAopF,EAAA,yBAAArB,GACAsB,EAAApB,KAAAF,GACAuB,EAAAF,GAAAG,GAAAxB,EACAqB,KAAAE,IACAE,GAAA,MAAAzB,EAAAl2D,OAAA,KACAk2D,EAAA,OAAAA,GAEAp2D,EAAA3Z,KAAA+vE,IAGA,MAAAp2D,GAGA,QAAA83D,GAAA3zE,GAEA,IAAA,GADAC,GAAAD,EAAAC,MAAAgH,QAAA,QAAA,IAAAE,MAAA,MACAjd,EAAA,EAAAA,EAAA+V,EAAAxV,SAAAP,EAAA,CACA,GAAA+nF,GAAAhyE,EAAA/V,EACA,IAAA,yBAAA+nF,GAAAsB,EAAApB,KAAAF,GACA,MAMA,MAHA/nF,GAAA,GAAA,eAAA8V,EAAA6M,OACA5M,EAAAA,EAAAmc,MAAAlyB,IAEA+V,EAGA,QAAAqxE,GAAAtxE,GACA,GAAAC,GAAAD,EAAAC,MACAilB,EAAAllB,EAAA+0B,UAGA,OAFA90B,GAAA,gBAAAA,IAAAA,EAAAxV,OAAA,EACAkpF,EAAA3zE,IAAA,yBAEAklB,QAAAA,EACAjlB,MAAA,eAAAD,EAAA6M,KAAA5M,EAAA+xE,EAAA/xE,IAIA,QAAA6yE,GAAA9yE,EAAAg/C,EAAA40B,GACA,GAAA,mBAAA7zE,SAAA,CACA,GAAAmlB,EACA,IAAAiI,EAAAmhD,SAAAtuE,GAAA,CACA,GAAAC,GAAAD,EAAAC,KACAilB,GAAA85B,EAAA60B,EAAA5zE,EAAAD,OAEAklB,GAAA85B,EAAAkkB,OAAAljE,EAEA,mBAAA8zE,GACAA,EAAA5uD,EAAA0uD,GACA,kBAAA7zE,SAAAe,KACA,gBAAAf,SAAAe,KACAf,QAAAe,IAAAokB,IAKA,QAAA6uD,GAAAlnE,EAAAmnE,EAAA/yE,EAAA7J,GACA,GAAA68E,IAAA,CACA,KACA,kBAAAD,KACAC,GAAA,EACA,qBAAApnE,EACAmnE,EAAA58E,GAEA48E,EAAA/yE,EAAA7J,IAGA,MAAA3N,GACAkiF,EAAA9D,WAAAp+E,GAGA,uBAAAojB,EACAgmE,GAAAhmE,EAAA5L,EAAA7J,IAAA68E,GACAnB,EAAA7xE,EAAA,wBAGA4xE,GAAAhmE,EAAAzV,GAIA,QAAA88E,GAAAh8C,GACA,GAAAi8C,EACA,IAAA,kBAAAj8C,GACAi8C,EAAA,cACAj8C,EAAArrB,MAAA,aACA,QACA,CACAsnE,EAAAj8C,GAAA,kBAAAA,GAAAnD,SACAmD,EAAAnD,WAAA5H,EAAA4H,SAAAmD,EAEA,IADA,4BACAi6C,KAAAgC,GACA,IAEAA,EADAxwD,KAAAwb,UAAAjH,GAGA,MAAAzuC,IAIA,IAAA0qF,EAAA1pF,SACA0pF,EAAA,iBAGA,MAAA,KAAAC,EAAAD,GAAA,qBAGA,QAAAC,GAAAD,GAEA,MAAAA,GAAA1pF,OADA,GAEA0pF,EAEAA,EAAA/3E,OAAA,EAAAi4E,IAAA,MAGA,QAAAC,KACA,MAAA,kBAAAC,IAKA,QAAAC,GAAAvC,GACA,GAAAwC,GAAAxC,EAAApvB,MAAA6xB,GACA,IAAAD,EACA,OACAztC,SAAAytC,EAAA,GACAxC,KAAAjvB,SAAAyxB,EAAA,GAAA,KAKA,QAAAE,GAAA3N,EAAA4N,GACA,GAAAN,IAAA,CAOA,IAAA,GAFAO,GACAC,EALAC,EAAA/N,EAAA/mE,MAAAkH,MAAA,MACA6tE,EAAAJ,EAAA30E,MAAAkH,MAAA,MACA8tE,GAAA,EACArS,GAAA,EAGA14E,EAAA,EAAAA,EAAA6qF,EAAAtqF,SAAAP,EAAA,CACA,GAAAkuB,GAAAo8D,EAAAO,EAAA7qF,GACA,IAAAkuB,EAAA,CACAy8D,EAAAz8D,EAAA4uB,SACAiuC,EAAA78D,EAAA65D,IACA,QAGA,IAAA,GAAA/nF,GAAA,EAAAA,EAAA8qF,EAAAvqF,SAAAP,EAAA,CACA,GAAAkuB,GAAAo8D,EAAAQ,EAAA9qF,GACA,IAAAkuB,EAAA,CACA08D,EAAA18D,EAAA4uB,SACA47B,EAAAxqD,EAAA65D,IACA,QAGAgD,EAAA,GAAArS,EAAA,IAAAiS,IAAAC,GACAD,IAAAC,GAAAG,GAAArS,IAIA6Q,GAAA,SAAAxB,GACA,GAAAiD,EAAA/C,KAAAF,GAAA,OAAA,CACA,IAAA16E,GAAAi9E,EAAAvC,EACA,UAAA16E,GACAA,EAAAyvC,WAAA6tC,GACAI,GAAA19E,EAAA06E,MAAA16E,EAAA06E,MAAArP,MAQA,QAAAgM,GAAAvC,GACA/gF,KAAA4lF,QAAA7E,EACA/gF,KAAA6pF,iBAAA,CACA,IAAA1qF,GAAAa,KAAA0hF,QAAA,OAAAzgF,KAAA8/E,EAAA,EAAAA,EAAAW,QACAuH,IAAAjpF,KAAAsjF,GACAnkF,EAAA,IAAAa,KAAA8pF,UA/sBA,GAKAC,GACAC,EAQAxB,EAdA9sE,EAAAq+D,EAAAkQ,WACA5J,EAAAtG,EAAAuG,OACAgH,EAAAtN,EAAA,YAAAsN,QACAzlD,EAAAm4C,EAAA,UACA2L,EAAA9jD,EAAA8jD,eAGAiE,EACA,2DACAhD,EAAA,6BACAG,EAAA,kCACAkB,EAAA,KACAM,EAAA,KACAH,GAAA,EAEA8B,IAAA,GAAAroD,EAAAsoD,IAAA,mBAKA/C,IAAA,GAAAvlD,EAAAsoD,IAAA,uBACAD,IAAAroD,EAAAsoD,IAAA,sBAEA1G,IAAA,GAAA5hD,EAAAsoD,IAAA,gCACAD,IAAAroD,EAAAsoD,IAAA,+BAEA9D,EAAA,GAAAxkD,EAAAsoD,IAAA,iCACA/C,KAAAvlD,EAAAsoD,IAAA,+BAEApQ,GAAA92E,UAAAmnF,4BAAA,WACA,GAAAvqF,GAAAG,KAAAG,SACAN,GAAAg+E,WAAA,QAAAh+E,EAAAg+E,UACA,QAGA9D,EAAA92E,UAAAonF,gCAAA,WACA,GAAA,IAAA,OAAArqF,KAAA69E,WAAA,CACA79E,KAAAsqF,0BACA,IAAAj5E,GAAArR,IACAgZ,YAAA,WACA3H,EAAAk5E,6BACA,KAGAxQ,EAAA92E,UAAAunF,mCAAA,WACA/B,EAAA,mBACAsB,MAAA9oF,GAAAjB,OAGA+5E,EAAA92E,UAAAwnF,yBAAA,WACAzqF,KAAA69E,UAAA,UAAA79E,KAAA69E,WAGA9D,EAAA92E,UAAAqjF,sBAAA,WACA,MAAA,KAAA,UAAAtmF,KAAA69E,YAGA9D,EAAA92E,UAAAsnF,0BAAA,WACA,GAAAvqF,KAAA0qF,wBAAA,CACA,GAAA/0E,GAAA3V,KAAA2qF,eACA3qF,MAAA4qF,mCACAnC,EAAA,qBACAuB,EAAAr0E,EAAA3V,QAIA+5E,EAAA92E,UAAA2nF,iCAAA,WACA5qF,KAAA69E,UAAA,OAAA79E,KAAA69E,WAGA9D,EAAA92E,UAAA4nF,mCAAA,WACA7qF,KAAA69E,WAAA,OAAA79E,KAAA69E,WAGA9D,EAAA92E,UAAA6nF,8BAAA,WACA,OAAA,OAAA9qF,KAAA69E,WAAA,GAGA9D,EAAA92E,UAAAqnF,yBAAA,WACAtqF,KAAA69E,UAAA,QAAA79E,KAAA69E,WAGA9D,EAAA92E,UAAA8nF,2BAAA,WACA/qF,KAAA69E,WAAA,QAAA79E,KAAA69E,UACA79E,KAAA8qF,kCACA9qF,KAAA6qF,qCACA7qF,KAAAwqF,uCAIAzQ,EAAA92E,UAAAynF,sBAAA,WACA,OAAA,QAAA1qF,KAAA69E,WAAA,GAGA9D,EAAA92E,UAAAu9E,MAAA,SAAA5mD,EAAAutD,EAAAr7E,GACA,MAAAoP,GAAA0e,EAAAutD,EAAAr7E,GAAA9L,OAGA+5E,EAAAiR,6BAAA,SAAApvB,GACA,GAAAqvB,GAAAvvE,GACAsuE,GACA,kBAAApuB,GAAA,OAAAqvB,EACArvB,EAAA/5B,EAAAqpD,WAAAD,EAAArvB,OACA36D,IAGA84E,EAAAoR,4BAAA,SAAAvvB,GACA,GAAAqvB,GAAAvvE,GACAquE,GACA,kBAAAnuB,GAAA,OAAAqvB,EACArvB,EAAA/5B,EAAAqpD,WAAAD,EAAArvB,OACA36D,GAGA,IAAAmqF,GAAA,YACArR,GAAA0J,gBAAA,WACA,GAAApD,EAAArE,oBAAAh9D,GAAAykE,gBACA,KAAA,IAAA3kF,OAAA,qGAEA,KAAAkgB,GAAAykE,iBAAAuF,IAAA,CACA,GAAAqC,GAAAtR,EAAA92E,UAAAqoF,mBACAC,EAAAxR,EAAA92E,UAAAm/E,iBACApjE,IAAAykE,iBAAA,EACA2H,EAAA,WACA,GAAA/K,EAAArE,oBAAAh9D,GAAAykE,gBACA,KAAA,IAAA3kF,OAAA,qGAEAi7E,GAAA92E,UAAAqoF,mBAAAD,EACAtR,EAAA92E,UAAAm/E,kBAAAmJ,EACAnI,EAAAY,4BACA3D,EAAAxE,mBACA78D,GAAAykE,iBAAA,GAEA1J,EAAA92E,UAAAqoF,mBAAA9F,EACAzL,EAAA92E,UAAAm/E,kBAAAqD,EACArC,EAAAa,0BACA5D,EAAAvE,iCAIA/B,EAAAyR,mBAAA,WACA,MAAAxsE,IAAAykE,iBAAAuF,IAGA,IAAAyC,GAAA,WACA,IACA,GAAA,kBAAAC,aAAA,CACA,GAAA93E,GAAA,GAAA83E,aAAA,cAEA,OADA7pD,GAAApiC,OAAAksF,cAAA/3E,GACA,SAAA2N,EAAA3N,GACA,GAAAg4E,GAAA,GAAAF,aAAAnqE,EAAAsqE,eACAC,OAAAl4E,EACAm4E,YAAA,GAEA,QAAAlqD,EAAApiC,OAAAksF,cAAAC,IAEA,GAAA,kBAAAI,OAAA,CACA,GAAAp4E,GAAA,GAAAo4E,OAAA,cAEA,OADAnqD,GAAApiC,OAAAksF,cAAA/3E,GACA,SAAA2N,EAAA3N,GACA,GAAAg4E,GAAA,GAAAI,OAAAzqE,EAAAsqE,eACAE,YAAA,GAGA,OADAH,GAAAE,OAAAl4E,GACAiuB,EAAApiC,OAAAksF,cAAAC,IAGA,GAAAh4E,GAAAgzD,SAAAqlB,YAAA,cAGA,OAFAr4E,GAAAs4E,gBAAA,mBAAA,GAAA,MACArqD,EAAApiC,OAAAksF,cAAA/3E,GACA,SAAA2N,EAAA3N,GACA,GAAAg4E,GAAAhlB,SAAAqlB,YAAA,cAGA,OAFAL,GAAAM,gBAAA3qE,EAAAsqE,eAAA,GAAA,EACAj4E,IACAiuB,EAAApiC,OAAAksF,cAAAC,IAGA,MAAAztF,IACA,MAAA,YACA,OAAA,MAIAguF,EAAA,WACA,MAAAtqD,GAAAq6C,OACA,WACA,MAAAC,GAAA17E,KAAAC,MAAAy7E,EAAA97E,YAGAwhC,EAAApiC,OAKA,SAAA8hB,GACA,GAAA29D,GAAA,KAAA39D,EAAAsqE,cACA31E,EAAA2rB,EAAApiC,OAAAy/E,EACA,SAAAhpE,IACAA,EAAAxV,MAAAmhC,EAAApiC,UAAAqxB,MAAA5xB,KAAAmB,UAAA,KACA,IATA,WACA,OAAA,MAiBA+rF,IACAhG,eAAA3B,EACA4H,iBAAA5H,EACA6H,gBAAA7H,EACA8H,gBAAA9H,EACA+H,iBAAA/H,EACAgI,eAAA,SAAAlrE,EAAAzV,EAAA20E,GACA,OAAA30E,QAAAA,EAAA20E,MAAAA,IAEA4G,QAAA,SAAA9lE,EAAA8lE,GACA,OAAAA,QAAAA,IAEAqF,mBAAA,SAAAnrE,EAAA5L,EAAA7J,GACA,OAAA6J,OAAAA,EAAA7J,QAAAA,IAEA6gF,iBAAAlI,GAGA8C,GAAA,SAAAhmE,GACA,GAAAqrE,IAAA,CACA,KACAA,EAAAT,EAAAzrF,MAAA,KAAAL,WACA,MAAAlC,GACAkiF,EAAA9D,WAAAp+E,GACAyuF,GAAA,EAGA,GAAAC,IAAA,CACA,KACAA,EAAApB,EAAAlqE,EACA6qE,GAAA7qE,GAAA7gB,MAAA,KAAAL,YACA,MAAAlC,GACAkiF,EAAA9D,WAAAp+E,GACA0uF,GAAA,EAGA,MAAAA,IAAAD,EAGA7S,GAAA/6D,OAAA,SAAAjd,GASA,GARAA,EAAAyqC,OAAAzqC,GACA,mBAAAA,KACAA,EAAA0hF,gBACA1J,EAAA0J,mBACA1hF,EAAA0hF,iBAAA1J,EAAAyR,sBACAJ,KAGA,YAAArpF,GAAA,CACA,GAAA+qF,GAAA/qF,EAAAqlF,QACApoE,IAAAooE,WAAA0F,EACAzG,EAAArnE,GAAAooE,SAEAvlD,EAAAmhD,SAAA8J,IACA,oBAAAA,KACAzG,IAAAyG,EAAAzG,kBAIA,GAAA,gBAAAtkF,IAAAA,EAAAoxC,eAAAn0B,GAAAm0B,aAAA,CACA,GAAAktC,EAAArE,kBACA,KAAA,IAAAl9E,OACA,uDAEAi7E,GAAA92E,UAAA8pF,uBACA5H,EACApL,EAAA92E,UAAA+6E,eAAAoH,EACArL,EAAA92E,UAAAq/E,UAAA2C,EACAlL,EAAA92E,UAAAq7E,aAAA4G,EACAnL,EAAA92E,UAAA6hF,4BACAC,EACAhL,EAAA92E,UAAA+pF,SAAArI,EACA1G,GAAAmH,EACApmE,GAAAm0B,cAAA,EAWA,MATA,cAAApxC,KACAA,EAAAkrF,aAAAjuE,GAAAiuE,YACAjuE,GAAAiuE,YAAA,EACAlT,EAAA92E,UAAAiqF,WAAA3F,KACAxlF,EAAAkrF,YAAAjuE,GAAAiuE,aACAjuE,GAAAiuE,YAAA,EACAlT,EAAA92E,UAAAiqF,WAAAxI,IAGA3K,GAKAA,EAAA92E,UAAAiqF,WAAAxI,EACA3K,EAAA92E,UAAA+pF,SAAA,SAAApI,EAAA9wE,EAAAqF,GACA,IACAyrE,EAAA9wE,EAAAqF,GACA,MAAAhb,GACA,MAAAA,KAGA47E,EAAA92E,UAAAq/E,UAAA,aACAvI,EAAA92E,UAAAq7E,aAAA,SAAA6O,KACApT,EAAA92E,UAAA6hF,4BAAA,SAAAD,KAGA9K,EAAA92E,UAAAqoF,mBAAA,aACAvR,EAAA92E,UAAAm/E,kBAAA,aACArI,EAAA92E,UAAA8pF,uBAAA,aACAhT,EAAA92E,UAAA+6E,eAAA,SAAA+C,EAAAsE,IAmEA,IAAApH,IAAAsH,EAwRA4C,GAAA,WAAA,OAAA,GACAiB,GAAA,uCA4DAvnD,GAAA1mB,SAAAmoE,EAAAxkF,OACAskF,EAAAE,cAAAA,EAEAA,EAAArgF,UAAA6mF,QAAA,WACA,GAAA3qF,GAAAa,KAAA0hF,OACA,MAAAviF,EAAA,GAAA,CAIA,IAAA,GAHAiuF,MACAC,KAEAzuF,EAAA,EAAA0uF,EAAAttF,SAAAiB,KAAAqsF,IAAA1uF,EACAwuF,EAAAx2E,KAAA02E,GACAA,EAAAA,EAAA1H,OAEAzmF,GAAAa,KAAA0hF,QAAA9iF,CACA,KAAA,GAAAA,GAAAO,EAAA,EAAAP,GAAA,IAAAA,EAAA,CACA,GAAA+V,GAAAy4E,EAAAxuF,GAAA+V,UACA1T,KAAAosF,EAAA14E,KACA04E,EAAA14E,GAAA/V,GAGA,IAAA,GAAAA,GAAA,EAAAA,EAAAO,IAAAP,EAAA,CACA,GAAA2uF,GAAAH,EAAAxuF,GAAA+V,MACAiiC,EAAAy2C,EAAAE,EACA,QAAAtsF,KAAA21C,GAAAA,IAAAh4C,EAAA,CACAg4C,EAAA,IACAw2C,EAAAx2C,EAAA,GAAAgvC,YAAA3kF,GACAmsF,EAAAx2C,EAAA,GAAA8qC,QAAA,GAEA0L,EAAAxuF,GAAAgnF,YAAA3kF,GACAmsF,EAAAxuF,GAAA8iF,QAAA,CACA,IAAA8L,GAAA5uF,EAAA,EAAAwuF,EAAAxuF,EAAA,GAAAoB,IAEA42C,GAAAz3C,EAAA,GACAquF,EAAA5H,QAAAwH,EAAAx2C,EAAA,GACA42C,EAAA5H,QAAAkE,UACA0D,EAAA9L,QACA8L,EAAA5H,QAAAlE,QAAA,IAEA8L,EAAA5H,YAAA3kF,GACAusF,EAAA9L,QAAA,EAGA,KAAA,GADA+L,GAAAD,EAAA9L,QAAA,EACA71C,EAAAjtC,EAAA,EAAAitC,GAAA,IAAAA,EACAuhD,EAAAvhD,GAAA61C,QAAA+L,EACAA,GAEA,YAKAnK,EAAArgF,UAAA4iF,iBAAA,SAAAnxE,GACA,IAAAA,EAAAoxE,iBAAA,CACA9lF,KAAA8pF,SAMA,KALA,GAAA/D,GAAAC,EAAAtxE,GACAklB,EAAAmsD,EAAAnsD,QACA8tD,GAAA3B,EAAApxE,OAEAovE,EAAA/jF,SACAiB,KAAA8iF,GACA2D,EAAA9wE,KAAA8vE,EAAA3C,EAAApvE,MAAAkH,MAAA,QACAkoE,EAAAA,EAAA6B,OAEAgC,GAAAF,GACAC,EAAAD,GACA7lD,EAAAokD,kBAAAvxE,EAAA,QAAA+yE,EAAA7tD,EAAA8tD,IACA7lD,EAAAokD,kBAAAvxE,EAAA,oBAAA,IAGA,IAAAu0E,IAAA,WACA,GAAAyE,GAAA,YACAC,EAAA,SAAAh5E,EAAAD,GACA,MAAA,gBAAAC,GAAAA,MAEA1T,KAAAyT,EAAA6M,UACAtgB,KAAAyT,EAAAklB,QACAllB,EAAA+0B,WAEAm/C,EAAAl0E,GAGA,IAAA,gBAAA5V,OAAA8uF,iBACA,kBAAA9uF,OAAAmqF,kBAAA,CACAnqF,MAAA8uF,iBAAA,EACA3F,EAAAyF,EACAnF,EAAAoF,CACA,IAAA1E,GAAAnqF,MAAAmqF,iBAKA,OAHAd,IAAA,SAAAxB,GACA,MAAAiD,GAAA/C,KAAAF,IAEA,SAAAvL,EAAAyS,GACA/uF,MAAA8uF,iBAAA,EACA3E,EAAA7N,EAAAyS,GACA/uF,MAAA8uF,iBAAA,GAGA,GAAAhsF,GAAA,GAAA9C,MAEA,IAAA,gBAAA8C,GAAA+S,OACA/S,EAAA+S,MAAAkH,MAAA,MAAA,GAAAxF,QAAA,oBAAA,EAIA,MAHA4xE,GAAA,IACAM,EAAAoF,EACAvF,GAAA,EACA,SAAA5pF,GACAA,EAAAmW,OAAA,GAAA7V,QAAA6V,MAIA,IAAAm5E,EACA,KAAA,KAAA,IAAAhvF,OACA,MAAAX,GACA2vF,EAAA,SAAA3vF,GAEA,MAAA,SAAAyD,KAAAksF,GACA,gBAAAhvF,OAAA8uF,iBAWArF,EAAA,SAAA5zE,EAAAD,GACA,MAAA,gBAAAC,GAAAA,EAEA,gBAAAD,IACA,kBAAAA,QACAzT,KAAAyT,EAAA6M,UACAtgB,KAAAyT,EAAAklB,QAGAgvD,EAAAl0E,GAFAA,EAAA+0B,YAKA,OAtBAw+C,EAAAyF,EACAnF,EAAAoF,EACA,SAAAnvF,GACAM,MAAA8uF,iBAAA,CACA,KAAA,KAAA,IAAA9uF,OACA,MAAAX,GAAAK,EAAAmW,MAAAxW,EAAAwW,MACA7V,MAAA8uF,iBAAA,MAoBA,oBAAAn5E,cAAA,KAAAA,QAAAyG,OACAstE,EAAA,SAAA5uD,GACAnlB,QAAAyG,KAAA0e,IAEAiI,EAAAq6C,QAAAC,EAAAC,OAAA2R,MACAvF,EAAA,SAAA5uD,EAAA0uD,GACA,GAAA0F,GAAA1F,EAAA,QAAA,OACA7zE,SAAAyG,KAAA8yE,EAAAp0D,EAAA,WAEAiI,EAAAq6C,QAAA,iBAAA,GAAAp9E,QAAA,QACA0pF,EAAA,SAAA5uD,EAAA0uD,GACA7zE,QAAAyG,KAAA,KAAA0e,EACA0uD,EAAA,oBAAA,gBAKA,IAAAtpE,KACAooE,SAAAA,EACA3D,iBAAA,EACAtwC,cAAA,EACA85C,YAAA,EAKA,OAFAxJ,IAAA1J,EAAA0J,mBAGAA,gBAAA,WACA,MAAAzkE,IAAAykE,iBAEA2D,SAAA,WACA,MAAApoE,IAAAooE,UAEAj0C,aAAA,WACA,MAAAn0B,IAAAm0B,cAEA85C,WAAA,WACA,MAAAjuE,IAAAiuE,YAEAhP,sBAAA,WACA,MAAAA,KAEAE,mBAAA,WACA,MAAAA,IAEA+H,sBAAAA,EACAmD,UAAAA,EACAnuE,KAAAA,EACA+rE,WAAAA,EACA3D,cAAAA,EACAmI,aAAAA,EACAU,gBAAAA,MAIA8B,WAAA,GAAAjR,SAAA,KAAAkR,IAAA,SAAAlU,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,GACA,QAAAoU,KACA,MAAAnuF,MAAAuB,MAEA,QAAA6sF,KACA,KAAApuF,MAAA2V,OAGAokE,EAAA92E,UAAA,OACA82E,EAAA92E,UAAAorF,WAAA,SAAA9sF,GAEA,MADAA,aAAAw4E,IAAAx4E,EAAA6oF,8BACApqF,KAAA29E,MACAwQ,MAAAltF,OAAAA,IAAAM,MAAAA,OAAAN,KAGA84E,EAAA92E,UAAA,MACA82E,EAAA92E,UAAAqrF,UAAA,SAAA34E,GACA,MAAA3V,MAAA29E,MACAyQ,MAAAntF,OAAAA,IAAA0U,OAAAA,OAAA1U,KAGA84E,EAAA92E,UAAAsrF,WAAA,SAAA54E,GACA,GAAAtV,UAAAlB,QAAA,EACA,MAAAa,MAAA29E,UACA18E,GAAAmtF,MAAAntF,IAAA0U,OAAAA,OAAA1U,GAEA,IAAAutF,GAAAnuF,UAAA,GACA8sF,EAAA,WAAA,KAAAqB,GACA,OAAAxuF,MAAAyuF,OAAA94E,EAAAw3E,IAIApT,EAAA92E,UAAAyrF,YAAA,SAAAntF,GACA,GAAAlB,UAAAlB,QAAA,EAEA,MADAoC,aAAAw4E,IAAAx4E,EAAA6oF,8BACApqF,KAAA29E,UACA18E,GAAAktF,MAAAltF,IAAAM,MAAAA,OAAAN,GAEA,IAAA0tF,GAAAtuF,UAAA,EACAsuF,aAAA5U,IAAA4U,EAAAvE,6BACA,IAAA+C,GAAA,WAAA,MAAAwB,GACA,OAAA3uF,MAAAyuF,OAAAltF,EAAA4rF,UAKAyB,IAAA,SAAA5U,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAmD,GAIA,QAAA2R,KACA,MAAAC,GAAA9uF,MAGA,QAAA+uF,GAAAzzE,EAAAsgD,GACA,MAAAozB,GAAA1zE,EAAAsgD,EAAAshB,EAAAA,GARA,GAAA8R,GAAAjV,EAAA3vB,OACA0kC,EAAA/U,EAAAv+D,GAUAu+D,GAAA92E,UAAAgsF,KAAA,SAAArzB,GACA,MAAAozB,GAAAhvF,KAAA47D,EAAAshB,EAAA,GACAS,MAAAkR,MAAA5tF,OAAAA,GAAAjB,SAAAiB,KAGA84E,EAAA92E,UAAA+kE,UAAA,SAAApM,GACA,MAAAozB,GAAAhvF,KAAA47D,EAAAshB,EAAAA,IAGAnD,EAAAkV,KAAA,SAAA3zE,EAAAsgD,GACA,MAAAozB,GAAA1zE,EAAAsgD,EAAAshB,EAAA,GACAS,MAAAkR,MAAA5tF,OAAAA,GAAAqa,MAAAra,KAGA84E,EAAA/R,UAAA+mB,QAIAG,IAAA,SAAAlV,EAAA36E,EAAAJ,GACA,YAOA,SAAAkwF,GAAAC,EAAAC,GACA,QAAAC,GAAA11D,GACA,KAAA55B,eAAAsvF,IAAA,MAAA,IAAAA,GAAA11D,EACAqsD,GAAAjmF,KAAA,UACA,gBAAA45B,GAAAA,EAAAy1D,GACApJ,EAAAjmF,KAAA,OAAAovF,GACAtwF,MAAAmqF,kBACAnqF,MAAAmqF,kBAAAjpF,KAAAA,KAAA4+C,aAEA9/C,MAAAI,KAAAc,MAIA,MADAmb,GAAAm0E,EAAAxwF,OACAwwF,EAmDA,QAAAC,GAAA31D,GACA,KAAA55B,eAAAuvF,IACA,MAAA,IAAAA,GAAA31D,EACAqsD,GAAAjmF,KAAA,OAAA,oBACAimF,EAAAjmF,KAAA,UAAA45B,GACA55B,KAAAwvF,MAAA51D,EACA55B,KAAA,eAAA,EAEA45B,YAAA96B,QACAmnF,EAAAjmF,KAAA,UAAA45B,EAAAA,SACAqsD,EAAAjmF,KAAA,QAAA45B,EAAAjlB,QACA7V,MAAAmqF,mBACAnqF,MAAAmqF,kBAAAjpF,KAAAA,KAAA4+C,aAlFA,GAsBA6wC,GAAAC,EAtBAC,EAAA3V,EAAA,SACA4V,EAAAD,EAAAE,OACAhuD,EAAAm4C,EAAA,UACA7+D,EAAA0mB,EAAA1mB,SACA8qE,EAAApkD,EAAAokD,kBAmBAqB,EAAA6H,EAAA,UAAA,WACAW,EAAAX,EAAA,oBAAA,sBACAY,EAAAZ,EAAA,eAAA,iBACAa,EAAAb,EAAA,iBAAA,kBACA,KACAM,EAAA//C,UACAggD,EAAAO,WACA,MAAA9xF,GACAsxF,EAAAN,EAAA,YAAA,cACAO,EAAAP,EAAA,aAAA,eAMA,IAAA,GAHAe,GAAA,sHACAr0E,MAAA,KAEAjd,EAAA,EAAAA,EAAAsxF,EAAA/wF,SAAAP,EACA,kBAAA2B,OAAA0C,UAAAitF,EAAAtxF,MACAoxF,EAAA/sF,UAAAitF,EAAAtxF,IAAA2B,MAAA0C,UAAAitF,EAAAtxF,IAIA+wF,GAAAljD,eAAAujD,EAAA/sF,UAAA,UACA1B,MAAA,EACAorE,cAAA,EACAD,UAAA,EACAhgC,YAAA,IAEAsjD,EAAA/sF,UAAA,eAAA,CACA,IAAAktF,GAAA,CACAH,GAAA/sF,UAAAwmC,SAAA,WACA,GAAA2mD,GAAA7vF,MAAA,EAAA4vF,EAAA,GAAA/tD,KAAA,KACA7R,EAAA,KAAA6/D,EAAA,sBACAD,KACAC,EAAA7vF,MAAA,EAAA4vF,EAAA,GAAA/tD,KAAA,IACA,KAAA,GAAAxjC,GAAA,EAAAA,EAAAoB,KAAAb,SAAAP,EAAA,CAGA,IAAA,GAFAiqF,GAAA7oF,KAAApB,KAAAoB,KAAA,4BAAAA,KAAApB,GAAA,GACAyxF,EAAAxH,EAAAhtE,MAAA,MACAgwB,EAAA,EAAAA,EAAAwkD,EAAAlxF,SAAA0sC,EACAwkD,EAAAxkD,GAAAukD,EAAAC,EAAAxkD,EAEAg9C,GAAAwH,EAAAjuD,KAAA,MACA7R,GAAAs4D,EAAA,KAGA,MADAsH,KACA5/D,GAmBApV,EAAAo0E,EAAAzwF,MAEA,IAAAwxF,GAAAxxF,MAAA,sBACAwxF,KACAA,EAAAV,GACAE,kBAAAA,EACAC,aAAAA,EACAR,iBAAAA,EACAgB,eAAAhB,EACAS,eAAAA,IAEAL,EAAAljD,eAAA3tC,MAAA,0BACAyC,MAAA+uF,EACA5jB,UAAA,EACAhgC,YAAA,EACAigC,cAAA,KAIAttE,EAAAJ,SACAH,MAAAA,MACA4wC,UAAA+/C,EACAQ,WAAAP,EACAI,kBAAAQ,EAAAR,kBACAP,iBAAAe,EAAAf,iBACAQ,aAAAO,EAAAP,aACAC,eAAAM,EAAAN,eACA1I,QAAAA,KAGApE,QAAA,GAAAlG,SAAA,KAAAwT,IAAA,SAAAxW,EAAA36E,EAAAJ,GACA,GAAAwxF,GAAA,WACA,YACA,YAAAxvF,KAAAjB,OAGA,IAAAywF,EACApxF,EAAAJ,SACA4wF,OAAArjD,OAAAqjD,OACApjD,eAAAD,OAAAC,eACAikD,cAAAlkD,OAAAmkD,yBACArxE,KAAAktB,OAAAltB,KACAsxE,MAAApkD,OAAAqkD,oBACAC,eAAAtkD,OAAAskD,eACAvmD,QAAAhqC,MAAAgqC,QACAkmD,MAAAA,EACAM,mBAAA,SAAAnkD,EAAAC,GACA,GAAAyrC,GAAA9rC,OAAAmkD,yBAAA/jD,EAAAC,EACA,SAAAyrC,IAAAA,EAAA5L,WAAA4L,EAAA0Y;uCAGA,CACA,GAAAC,MAAAp/D,eACAg3D,KAAAp/C,SACAynD,KAAAtyC,YAAA37C,UAEAkuF,EAAA,SAAA3yF,GACA,GAAA+xB,KACA,KAAA,GAAAvM,KAAAxlB,GACAyyF,EAAA/xF,KAAAV,EAAAwlB,IACAuM,EAAA3Z,KAAAoN,EAGA,OAAAuM,IAGA6gE,EAAA,SAAA5yF,EAAAwlB,GACA,OAAAziB,MAAA/C,EAAAwlB,KAGAqtE,EAAA,SAAA7yF,EAAAwlB,EAAAstE,GAEA,MADA9yF,GAAAwlB,GAAAstE,EAAA/vF,MACA/C,GAGA+yF,EAAA,SAAA3kD,GACA,MAAAA,IAGA4kD,EAAA,SAAA5kD,GACA,IACA,MAAAJ,QAAAI,GAAAgS,YAAA37C,UAEA,MAAA9E,GACA,MAAA+yF,KAIAO,EAAA,SAAA7kD,GACA,IACA,MAAA,mBAAAi8C,EAAA3pF,KAAA0tC,GAEA,MAAAzuC,GACA,OAAA,GAIAkB,GAAAJ,SACAsrC,QAAAknD,EACAnyE,KAAA6xE,EACAP,MAAAO,EACA1kD,eAAA4kD,EACAX,cAAAU,EACAvB,OAAA0B,EACAT,eAAAU,EACAf,MAAAA,EACAM,mBAAA,WACA,OAAA,UAKAW,IAAA,SAAA1X,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAmD,GACA,GAAAyU,GAAA5X,EAAA55D,GAEA45D,GAAA92E,UAAAknB,OAAA,SAAAyxC,EAAA/0D,GACA,MAAA8qF,GAAA3xF,KAAA47D,EAAA/0D,EAAAq2E,IAGAnD,EAAA5vD,OAAA,SAAA7O,EAAAsgD,EAAA/0D,GACA,MAAA8qF,GAAAr2E,EAAAsgD,EAAA/0D,EAAAq2E,UAIA0U,IAAA,SAAA5X,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAoD,EAAAsF,GAMA,QAAAoP,GAAA/lF,EAAAvG,EAAA4nF,GACAntF,KAAA8L,QAAAA,EACA9L,KAAAuF,KAAAA,EACAvF,KAAAmtF,QAAAA,EACAntF,KAAA8xF,QAAA,EACA9xF,KAAA+xF,cAAA,KAOA,QAAAC,GAAAC,GACAjyF,KAAAiyF,eAAAA,EAOA,QAAAC,GAAA3N,EAAA5uE,GACA,MAAA,OAAA4uE,EAAAwN,gBACA1xF,UAAAlB,OAAA,EACAolF,EAAAwN,cAAA94E,QAAAtD,GAEA4uE,EAAAwN,cAAAxQ,UAEAgD,EAAAwN,cAAA,MACA,GAKA,QAAAI,KACA,MAAAF,GAAA/yF,KAAAc,KAAAA,KAAA8L,QAAA3L,UAAAwqF,iBAEA,QAAAyH,GAAAz8E,GACA,IAAAu8E,EAAAlyF,KAAA2V,GAEA,MADAyqE,GAAAjiF,EAAAwX,EACAyqE,EAEA,QAAA6R,GAAAI,GACA,GAAAvmF,GAAA9L,KAAA8L,QACAqhF,EAAAntF,KAAAmtF,OAEA,KAAAntF,KAAA8xF,OAAA,CACA9xF,KAAA8xF,QAAA,CACA,IAAAvhE,GAAAvwB,KAAAsyF,mBACAnF,EAAAjuF,KAAA4M,EAAAoyE,eACAiP,EAAAjuF,KAAA4M,EAAAoyE,cAAAmU,EACA,IAAA9hE,IAAAkyD,EACA,MAAAlyD,EACA,QAAAtvB,KAAAsvB,EAAA,CACAzkB,EAAA2+E,0BACA,IAAArM,GAAAjB,EAAA5sD,EAAAzkB,EACA,IAAAsyE,YAAArE,GAAA,CACA,GAAA,MAAA/5E,KAAA+xF,cAAA,CACA,GAAA3T,EAAA0D,eAAA,CACA,GAAAnsE,GACA,GAAAm6E,GAAA,6BAGA,OAFAhkF,GAAAs2E,kBAAAzsE,GACAyqE,EAAAjiF,EAAAwX,EACAyqE,EACAhC,EAAAyD,aACAzD,EAAA0G,4BACA,GAAAkN,GAAAhyF,OAGA,MAAAo+E,GAAAT,MACAwU,EAAAC,MAAAnxF,GAAAjB,SAAAiB,MAKA,MAAA6K,GAAAymF,cACAL,EAAAlyF,MACAogF,EAAAjiF,EAAAk0F,EACAjS,IAEA8R,EAAAlyF,MACAqyF,GArFA,GAAAxwD,GAAAm4C,EAAA,UACA8V,EAAA/V,EAAA+V,kBACA1P,EAAAv+C,EAAAu+C,SACAsC,EAAA1I,EAAA,kBAAAyI,EA2IA,OAjIAoP,GAAA5uF,UAAAqvF,iBAAA,WACA,MAAA,KAAAtyF,KAAAuF,MAOAysF,EAAA/uF,UAAAo/E,iBAAA,WACA6P,EAAAlyF,KAAAiyF,iBAmEAlY,EAAA92E,UAAAuvF,aAAA,SAAArF,EAAA5nF,EAAA+vB,EAAA88D,GACA,MAAA,kBAAAjF,GAAAntF,KAAA4D,OACA5D,KAAA29E,MAAAroD,EACA88D,MACAnxF,GACA,GAAA4wF,GAAA7xF,KAAAuF,EAAA4nF,OACAlsF,KAGA84E,EAAA92E,UAAAwvF,OACA1Y,EAAA92E,UAAA,QAAA,SAAAkqF,GACA,MAAAntF,MAAAwyF,aAAArF,EACA,EACA8E,EACAA,IAIAlY,EAAA92E,UAAAyvF,IAAA,SAAAvF,GACA,MAAAntF,MAAAwyF,aAAArF,EAAA,EAAA8E,IAGAlY,EAAA92E,UAAA0vF,SAAA,SAAAC,GACA,GAAA/mB,GAAAxrE,UAAAlB,MACA,IAAA,IAAA0sE,EACA,MAAA7rE,MAAAwyF,aAAAI,EACA,MACA3xF,GACAgxF,EAEA,IACArzF,GADAi0F,EAAA,GAAAtyF,OAAAsrE,EAAA,GACAhgC,EAAA,CACA,KAAAjtC,EAAA,EAAAA,EAAAitE,EAAA,IAAAjtE,EAAA,CACA,GAAAkkF,GAAAziF,UAAAzB,EACA,KAAAijC,EAAAmhD,SAAAF,GAGA,MAAA/I,GAAA5gE,OAAA,GAAAu2B,WACA,6DACA7N,EAAAs9C,YAAA2D,IAJA+P,GAAAhnD,KAAAi3C,EAQA+P,EAAA1zF,OAAA0sC,CACA,IAAAshD,GAAA9sF,UAAAzB,EACA,OAAAoB,MAAAwyF,aAAA9P,EAAAmQ,EAAA1F,EAAAntF,MACA,MACAiB,GACAgxF,IAKAJ,KAGAiB,iBAAA,EAAA9V,SAAA,KAAA+V,IAAA,SAAA/Y,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EACAmG,EACAhD,EACAC,EACA6V,EACA5V,GAQA,QAAA6V,GAAA1xF,EAAA2xF,EAAAC,GACA,IAAA,GAAAv0F,GAAA,EAAAA,EAAAs0F,EAAA/zF,SAAAP,EAAA,CACAu0F,EAAAvP,cACA,IAAA92D,GAAAqzD,EAAA+S,EAAAt0F,IAAA2C,EAEA,IADA4xF,EAAAtP,cACA/2D,IAAAszD,EAAA,CACA+S,EAAAvP,cACA,IAAArzD,GAAAwpD,EAAA5gE,OAAAinE,EAAAjiF,EAEA,OADAg1F,GAAAtP,cACAtzD,EAEA,GAAA6tD,GAAAjB,EAAArwD,EAAAqmE,EACA,IAAA/U,YAAArE,GAAA,MAAAqE,GAEA,MAAA,MAGA,QAAAgV,GAAAC,EAAAjY,EAAAkY,EAAA3+E,GACA,GAAAyoE,EAAAjqC,eAAA,CACA,GAAAogD,GAAA,GAAAxZ,GAAAmD,GACAsW,EAAAxzF,KAAAwzF,gBAAA,GAAAzZ,GAAAmD,EACAl9E,MAAAyzF,SAAAF,EAAAd,OAAA,WACA,MAAAe,KAEAD,EAAAjI,qBACAiI,EAAAjV,aAAAt+E,UACA,EACAA,KAAAyzF,SAAA,GAAA1Z,GAAAmD,IACAoO,qBAEAtrF,KAAA0zF,OAAA/+E,EACA3U,KAAA2zF,mBAAAN,EACArzF,KAAA4zF,UAAAxY,EACAp7E,KAAA6zF,eAAA5yF,GACAjB,KAAA8zF,eAAA,kBAAAR,IACAA,GAAA3yF,OAAAuyF,GACAA,EACAlzF,KAAA+zF,gBAAA,KACA/zF,KAAAg0F,oBAAA,EA7CA,GAAAC,GAAAja,EAAA,YACAtqC,EAAAukD,EAAAvkD,UACA7N,EAAAm4C,EAAA,UACAoG,EAAAv+C,EAAAu+C,SACAD,EAAAt+C,EAAAs+C,SACA+S,IA0CArxD,GAAA1mB,SAAAi4E,EAAAJ,GAEAI,EAAAnwF,UAAAixF,YAAA,WACA,MAAA,QAAAl0F,KAAAyzF,UAGAL,EAAAnwF,UAAAkxF,SAAA,WACAn0F,KAAAyzF,SAAAzzF,KAAA6zF,WAAA,KACAzW,EAAAjqC,gBAAA,OAAAnzC,KAAAwzF,kBACAxzF,KAAAwzF,gBAAAY,WACAp0F,KAAAwzF,gBAAA,OAIAJ,EAAAnwF,UAAAoxF,kBAAA,WACA,IAAAr0F,KAAAk0F,cAAA,CACA,GAEApnE,GAFAwnE,MAAA,KAAAt0F,KAAA6zF,WAAA,MAGA,IAAAS,EAUAt0F,KAAAyzF,SAAA7P,eACA92D,EAAAqzD,EAAAngF,KAAA6zF,WAAA,QAAA30F,KAAAc,KAAA6zF,eACA5yF,IACAjB,KAAAyzF,SAAA5P,kBAbA,CACA,GAAAluE,GAAA,GAAAokE,GAAA+V,kBACA,+BACA/V,GAAAr9D,UAAA63E,eAAA5+E,EACA3V,KAAAyzF,SAAArR,kBAAAzsE,GACA3V,KAAAyzF,SAAA7P,eACA92D,EAAAqzD,EAAAngF,KAAA6zF,WAAA,OAAA30F,KAAAc,KAAA6zF,WACAl+E,GACA3V,KAAAyzF,SAAA5P,cAOA7jF,KAAAg0F,oBAAA,EACAh0F,KAAA+zF,gBAAA,KACA/zF,KAAAw0F,UAAA1nE,KAGAsmE,EAAAnwF,UAAAwxF,kBAAA,SAAAlzF,GACAvB,KAAA+zF,gBAAA,KACA/zF,KAAAyzF,SAAA7P,cACA,IAAA92D,GAAAqzD,EAAAngF,KAAA6zF,WAAAxyF,MAAAnC,KAAAc,KAAA6zF,WAAAtyF,EACAvB,MAAAyzF,SAAA5P,cACA7jF,KAAAw0F,UAAA1nE,IAGAsmE,EAAAnwF,UAAAyxF,iBAAA,SAAA/+E,GACA3V,KAAA+zF,gBAAA,KACA/zF,KAAAyzF,SAAArR,kBAAAzsE,GACA3V,KAAAyzF,SAAA7P,cACA,IAAA92D,GAAAqzD,EAAAngF,KAAA6zF,WAAA,OACA30F,KAAAc,KAAA6zF,WAAAl+E,EACA3V,MAAAyzF,SAAA5P,cACA7jF,KAAAw0F,UAAA1nE,IAGAsmE,EAAAnwF,UAAAo/E,iBAAA,WACA,GAAAriF,KAAA+zF,0BAAAha,GAAA,CACA,GAAAjuE,GAAA9L,KAAA+zF,eACA/zF,MAAA+zF,gBAAA,KACAjoF,EAAAy0E,WAIA6S,EAAAnwF,UAAA6I,QAAA,WACA,MAAA9L,MAAAyzF,UAGAL,EAAAnwF,UAAA0xF,KAAA,WACA30F,KAAA6zF,WAAA7zF,KAAA2zF,mBAAAz0F,KAAAc,KAAA4zF,WACA5zF,KAAA4zF,UACA5zF,KAAA2zF,uBAAA1yF,GACAjB,KAAAy0F,sBAAAxzF,KAGAmyF,EAAAnwF,UAAAuxF,UAAA,SAAA1nE,GACA,GAAAhhB,GAAA9L,KAAAyzF,QACA,IAAA3mE,IAAAszD,EAEA,MADApgF,MAAAm0F,WACAn0F,KAAAg0F,mBACAloF,EAAAy0E,SAEAz0E,EAAA8oF,gBAAA9nE,EAAA3uB,GAAA,EAIA,IAAAoD,GAAAurB,EAAAvrB,KACA,KAAA,IAAAurB,EAAAxrB,KAEA,MADAtB,MAAAm0F,WACAn0F,KAAAg0F,mBACAloF,EAAAy0E,SAEAz0E,EAAAgyE,iBAAAv8E,EAGA,IAAA68E,GAAAjB,EAAA57E,EAAAvB,KAAAyzF,SACA,MAAArV,YAAArE,KAKA,QAJAqE,EACA6U,EAAA7U,EACAp+E,KAAA8zF,eACA9zF,KAAAyzF,WASA,WAPAzzF,MAAA00F,iBACA,GAAAhlD,GACA,oGAAA/zB,QAAA,KAAAi8D,OAAAr2E,IACA,oBACAvB,KAAA0zF,OAAA73E,MAAA,MAAAiV,MAAA,GAAA,GAAAsR,KAAA,OAMAg8C,GAAAA,EAAAj+E,SACA,IAAA00F,GAAAzW,EAAAP,SAEA,KAAA,SAAAgX,IACA70F,KAAA+zF,gBAAA3V,EACAA,EAAA0W,OAAA90F,KAAA,OACA,IAAA,SAAA60F,GACA9a,EAAAuG,OAAA7D,OACAz8E,KAAAy0F,kBAAAz0F,KAAAo+E,EAAAuQ,UAEA,IAAA,SAAAkG,GACA9a,EAAAuG,OAAA7D,OACAz8E,KAAA00F,iBAAA10F,KAAAo+E,EAAAoQ,WAGAxuF,KAAAq0F,qBAKAta,EAAAr9D,UAAA,SAAA22E,EAAAxsF,GACA,GAAA,kBAAAwsF,GACA,KAAA,IAAA3jD,GAAA,yEAEA,IAAA4jD,GAAA9mD,OAAA3lC,GAAAysF,aACAyB,EAAA3B,EACAz+E,GAAA,GAAA7V,QAAA6V,KACA,OAAA,YACA,GAAAqgF,GAAA3B,EAAA3yF,MAAAV,KAAAK,WACA40F,EAAA,GAAAF,OAAA9zF,OAAAA,GAAAqyF,EACA3+E,GACA4b,EAAA0kE,EAAAnpF,SAGA,OAFAmpF,GAAApB,WAAAmB,EACAC,EAAAR,sBAAAxzF,IACAsvB,IAIAwpD,EAAAr9D,UAAAw4E,gBAAA,SAAAt5B,GACA,GAAA,kBAAAA,GACA,KAAA,IAAAlsB,GAAA,gCAAA7N,EAAAs9C,YAAAvjB,GAEAs3B,GAAAt8E,KAAAglD,IAGAme,EAAAkb,MAAA,SAAA5B,GAEA,GADAjW,EAAA6J,WAAA,kBAAA,uBACA,kBAAAoM,GACA,MAAAnT,GAAA,yEAEA,IAAA+U,GAAA,GAAA7B,GAAAC,EAAArzF,MACAuwB,EAAA0kE,EAAAnpF,SAEA,OADAmpF,GAAAN,KAAA5a,EAAAkb,OACA1kE,MAIA09D,WAAA,GAAAjR,SAAA,KAAAmY,IAAA,SAAAnb,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QACA,SAAA86E,EAAAkG,EAAA9C,EAAAD,EAAAmD,EACA3kE,GACA,GAAAmmB,GAAAm4C,EAAA,SACAn4C,GAAA49C,YACA59C,EAAAs+C,SACAt+C,EAAAu+C,QAuGArG,GAAA33C,KAAA,WACA,GACAw5B,GADAw5B,EAAA/0F,UAAAlB,OAAA,CAEA,IAAAi2F,EAAA,GAAA,kBAAA/0F,WAAA+0F,GAAA,CACAx5B,EAAAv7D,UAAA+0F,EAGA,IAAA7kE,GA4CA,GAAAjwB,MAAAwwB,MAAA5xB,KAAAmB,UACAu7D,IAAAt7D,EAAA++E,KACA,IAAA9uD,GAAA,GAAA0vD,GAAA3/E,GAAAwL,SACA,YAAA7K,KAAA26D,EAAArrC,EAAA8kE,OAAAz5B,GAAArrC,MAKAysD,SAAA,KAAAsY,IAAA,SAAAtb,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EACAkG,EACAC,EACA/C,EACAD,EACAE,GAOA,QAAAmY,GAAAj6E,EAAAsgD,EAAA5xD,EAAAq6C,GACArkD,KAAAw1F,aAAAl6E,GACAtb,KAAAyzF,SAAAnI,oBACA,IAAAL,GAAAvvE,GACA1b,MAAAy1F,UAAA,OAAAxK,EAAArvB,EAAA/5B,EAAAqpD,WAAAD,EAAArvB,GACA57D,KAAA01F,iBAAArxC,IAAA64B,EACA,GAAA38E,OAAAP,KAAAb,UACA,KACAa,KAAA21F,OAAA3rF,EACAhK,KAAA2+D,UAAA,EACA3+D,KAAA41F,UACAvV,EAAA5D,OAAAz8E,KAAA61F,WAAA71F,SAAAiB,IA6GA,QAAAkf,GAAA7E,EAAAsgD,EAAA/0D,EAAAw9C,GACA,GAAA,kBAAAuX,GACA,MAAAskB,GAAA,gCAAAr+C,EAAAs9C,YAAAvjB,GAGA,IAAA5xD,GAAA,CACA,QAAA/I,KAAA4F,EAAA,CACA,GAAA,gBAAAA,IAAA,OAAAA,EAQA,MAAAkzE,GAAA5gE,OAAA,GAAAu2B,WACA,gDACA7N,EAAAs9C,YAAAt4E,IATA,IAAA,gBAAAA,GAAAivF,YACA,MAAA/b,GAAA5gE,OACA,GAAAu2B,WAAA,4CACA7N,EAAAs9C,YAAAt4E,EAAAivF,cAEA9rF,GAAAnD,EAAAivF,YASA,MAFA9rF,GAAA,gBAAAA,IACAylC,SAAAzlC,IAAAA,GAAA,EAAAA,EAAA,EACA,GAAAurF,GAAAj6E,EAAAsgD,EAAA5xD,EAAAq6C,GAAAv4C,UApJA,GAAA4P,GAAAq+D,EAAAkQ,WACApoD,EAAAm4C,EAAA,UACAmG,EAAAt+C,EAAAs+C,SACAC,EAAAv+C,EAAAu+C,SACAC,EAAAtG,EAAAuG,MAeAz+C,GAAA1mB,SAAAo6E,EAAAtV,GAEAsV,EAAAtyF,UAAA4yF,WAAA,WACA71F,KAAA+1F,WAAA90F,IAAA,IAGAs0F,EAAAtyF,UAAA05D,MAAA,aAEA44B,EAAAtyF,UAAAwxF,kBAAA,SAAAlzF,EAAAq1C,GACA,GAAAn/B,GAAAzX,KAAAg2F,QACA72F,EAAAa,KAAAb,SACA82F,EAAAj2F,KAAA01F,iBACA1rF,EAAAhK,KAAA21F,MAEA,IAAA/+C,EAAA,GAGA,GAFAA,GAAA,EAAAA,EAAA,EACAn/B,EAAAm/B,GAAAr1C,EACAyI,GAAA,IACAhK,KAAA2+D,YACA3+D,KAAA48E,cACA58E,KAAAk0F,eAAA,OAAA,MAEA,CACA,GAAAlqF,GAAA,GAAAhK,KAAA2+D,WAAA30D,EAGA,MAFAyN,GAAAm/B,GAAAr1C,EACAvB,KAAA41F,OAAAh/E,KAAAggC,IACA,CAEA,QAAAq/C,IAAAA,EAAAr/C,GAAAr1C,EAEA,IAAAuK,GAAA9L,KAAAyzF,SACApvF,EAAArE,KAAAy1F,UACAra,EAAAtvE,EAAAoyE,aACApyE,GAAA83E,cACA,IAAArzD,GAAA4vD,EAAA97E,GAAAnF,KAAAk8E,EAAA75E,EAAAq1C,EAAAz3C,GACAinF,EAAAt6E,EAAA+3E,aAOA,IANAzG,EAAA8I,sBACA31D,EACA61D,EACA,OAAA6P,EAAA,iBAAA,cACAnqF,GAEAykB,IAAA6vD,EAEA,MADApgF,MAAAiZ,QAAAsX,EAAApyB,IACA,CAGA,IAAAigF,GAAAjB,EAAA5sD,EAAAvwB,KAAAyzF,SACA,IAAArV,YAAArE,GAAA,CACAqE,EAAAA,EAAAj+E,SACA,IAAA00F,GAAAzW,EAAAP,SAEA,IAAA,IAAA,SAAAgX,GAIA,MAHA7qF,IAAA,GAAAhK,KAAA2+D,YACAlnD,EAAAm/B,GAAAwnC,EACAA,EAAA0W,OAAA90F,MAAA,GAAA42C,EAAA,KACA,CACA,IAAA,IAAA,SAAAi+C,GAEA,MAAA,KAAA,SAAAA,IACA70F,KAAAiZ,QAAAmlE,EAAAoQ,YACA,IAEAxuF,KAAAuhF,WACA,EANAhxD,GAAA6tD,EAAAuQ,SASAl3E,EAAAm/B,GAAArmB,EAGA,QADAvwB,KAAAk2F,gBACA/2F,IACA,OAAA82F,EACAj2F,KAAAqkD,QAAA5sC,EAAAw+E,GAEAj2F,KAAAoZ,SAAA3B,IAEA,IAKA89E,EAAAtyF,UAAA25E,YAAA,WAIA,IAHA,GAAAphB,GAAAx7D,KAAA41F,OACA5rF,EAAAhK,KAAA21F,OACAl+E,EAAAzX,KAAAg2F,QACAx6B,EAAAr8D,OAAA,GAAAa,KAAA2+D,UAAA30D,GAAA,CACA,GAAAhK,KAAAk0F,cAAA,MACA,IAAAt9C,GAAA4kB,EAAA6jB,KACAr/E,MAAAy0F,kBAAAh9E,EAAAm/B,GAAAA,KAIA2+C,EAAAtyF,UAAAohD,QAAA,SAAA8xC,EAAA1+E,GAIA,IAAA,GAHAo0D,GAAAp0D,EAAAtY,OACAoxB,EAAA,GAAAhwB,OAAAsrE,GACAhgC,EAAA,EACAjtC,EAAA,EAAAA,EAAAitE,IAAAjtE,EACAu3F,EAAAv3F,KAAA2xB,EAAAsb,KAAAp0B,EAAA7Y,GAEA2xB,GAAApxB,OAAA0sC,EACA7rC,KAAAoZ,SAAAmX,IAGAglE,EAAAtyF,UAAAgzF,gBAAA,WACA,MAAAj2F,MAAA01F,kBA4BA3b,EAAA92E,UAAAkd,IAAA,SAAAy7C,EAAA/0D,GACA,MAAAsZ,GAAAngB,KAAA47D,EAAA/0D,EAAA,OAGAkzE,EAAA55D,IAAA,SAAA7E,EAAAsgD,EAAA/0D,EAAAw9C,GACA,MAAAlkC,GAAA7E,EAAAsgD,EAAA/0D,EAAAw9C,OAMA24B,SAAA,KAAAoZ,IAAA,SAAApc,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QACA,SAAA86E,EAAAmD,EAAAC,EAAA+C,EAAA9C,GACA,GAAAv7C,GAAAm4C,EAAA,UACAmG,EAAAt+C,EAAAs+C,QAEApG,GAAA7jE,OAAA,SAAA0lD,GACA,GAAA,kBAAAA,GACA,KAAA,IAAAme,GAAArqC,UAAA,gCAAA7N,EAAAs9C,YAAAvjB,GAEA,OAAA,YACA,GAAArrC,GAAA,GAAAwpD,GAAAmD,EACA3sD,GAAA+6D,qBACA/6D,EAAAqzD,cACA,IAAAriF,GAAA4+E,EAAAvkB,GAAAl7D,MAAAV,KAAAK,WACA+lF,EAAA71D,EAAAszD,aAIA,OAHAzG,GAAA8I,sBACA3kF,EAAA6kF,EAAA,iBAAA71D,GACAA,EAAA8lE,sBAAA90F,GACAgvB,IAIAwpD,EAAAuc,QAAAvc,EAAA,IAAA,SAAAne,GACA,GAAA,kBAAAA,GACA,MAAAskB,GAAA,gCAAAr+C,EAAAs9C,YAAAvjB,GAEA,IAAArrC,GAAA,GAAAwpD,GAAAmD,EACA3sD,GAAA+6D,qBACA/6D,EAAAqzD,cACA,IAAAriF,EACA,IAAAlB,UAAAlB,OAAA,EAAA,CACAi+E,EAAA6J,WAAA,gDACA,IAAA5L,GAAAh7E,UAAA,GACAkkF,EAAAlkF,UAAA,EACAkB,GAAAsgC,EAAA0I,QAAA8wC,GAAA8E,EAAAvkB,GAAAl7D,MAAA6jF,EAAAlJ,GACA8E,EAAAvkB,GAAA18D,KAAAqlF,EAAAlJ,OAEA95E,GAAA4+E,EAAAvkB,IAEA,IAAAwqB,GAAA71D,EAAAszD,aAIA,OAHAzG,GAAA8I,sBACA3kF,EAAA6kF,EAAA,cAAA71D,GACAA,EAAA8lE,sBAAA90F,GACAgvB,GAGAwpD,EAAA92E,UAAAozF,sBAAA,SAAA90F,GACAA,IAAAsgC,EAAAu+C,SACApgF,KAAA40F,gBAAArzF,EAAApD,GAAA,GAEA6B,KAAA89E,iBAAAv8E,GAAA,OAKAy7E,SAAA,KAAAuZ,IAAA,SAAAvc,EAAA36E,EAAAJ,GACA,YAOA,SAAAu3F,GAAA5pD,GACA,MAAAA,aAAA9tC,QACA6wF,EAAAmB,eAAAlkD,KAAA9tC,MAAAmE,UAIA,QAAAwzF,GAAA7pD,GACA,GAAArc,EACA,IAAAimE,EAAA5pD,GAAA,CACArc,EAAA,GAAAg/D,GAAA3iD,GACArc,EAAAhP,KAAAqrB,EAAArrB,KACAgP,EAAAqJ,QAAAgT,EAAAhT,QACArJ,EAAA5b,MAAAi4B,EAAAj4B,KAEA,KAAA,GADA2K,GAAAqwE,EAAArwE,KAAAstB,GACAhuC,EAAA,EAAAA,EAAA0gB,EAAAngB,SAAAP,EAAA,CACA,GAAAolB,GAAA1E,EAAA1gB,EACA83F,GAAA7P,KAAA7iE,KACAuM,EAAAvM,GAAA4oB,EAAA5oB,IAGA,MAAAuM,GAGA,MADAsR,GAAA80D,+BAAA/pD,GACAA,EAGA,QAAAgqD,GAAA9qF,EAAA+qF,GACA,MAAA,UAAAj1F,EAAAL,GACA,GAAA,OAAAuK,EAAA,CACA,GAAAlK,EAAA,CACA,GAAAk1F,GAAAL,EAAAM,EAAAn1F,GACAkK,GAAAs2E,kBAAA0U,GACAhrF,EAAAmN,QAAA69E,OACA,IAAAD,EAEA,CACA,GAAAv2F,MAAAwwB,MAAA5xB,KAAAmB,UAAA,EACAyL,GAAAsoF,SAAA9zF,OAHAwL,GAAAsoF,SAAA7yF,EAKAuK,GAAA,OA7CA,GAAA+1B,GAAAm4C,EAAA,UACA+c,EAAAl1D,EAAAk1D,iBACA9C,EAAAja,EAAA,YACAuV,EAAA0E,EAAA1E,iBACAI,EAAA3V,EAAA,SAOA0c,EAAA,gCAsCAr3F,GAAAJ,QAAA23F,IAEA3I,WAAA,GAAA/K,QAAA,GAAAlG,SAAA,KAAAga,IAAA,SAAAhd,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,GAMA,QAAAkd,GAAA7uD,EAAA8uD,GACA,GAAAprF,GAAA9L,IACA,KAAA6hC,EAAA0I,QAAAnC,GAAA,MAAA+uD,GAAAj4F,KAAA4M,EAAAs8B,EAAA8uD,EACA,IAAA3mE,GACA4vD,EAAA+W,GAAAx2F,MAAAoL,EAAAoyE,eAAA,MAAAv9E,OAAAynC,GACA7X,KAAA6vD,GACAC,EAAA9D,WAAAhsD,EAAApyB,GAIA,QAAAg5F,GAAA/uD,EAAA8uD,GACA,GAAAprF,GAAA9L,KACAo7E,EAAAtvE,EAAAoyE,cACA3tD,MAAAtvB,KAAAmnC,EACA+3C,EAAA+W,GAAAh4F,KAAAk8E,EAAA,MACA+E,EAAA+W,GAAAh4F,KAAAk8E,EAAA,KAAAhzC,EACA7X,KAAA6vD,GACAC,EAAA9D,WAAAhsD,EAAApyB,GAGA,QAAAi5F,GAAAzhF,EAAAuhF,GACA,GAAAprF,GAAA9L,IACA,KAAA2V,EAAA,CACA,GAAA0hF,GAAA,GAAAv4F,OAAA6W,EAAA,GACA0hF,GAAA7H,MAAA75E,EACAA,EAAA0hF,EAEA,GAAA9mE,GAAA4vD,EAAA+W,GAAAh4F,KAAA4M,EAAAoyE,cAAAvoE,EACA4a,KAAA6vD,GACAC,EAAA9D,WAAAhsD,EAAApyB,GAlCA,GAAA0jC,GAAAm4C,EAAA,UACAqG,EAAAtG,EAAAuG,OACAH,EAAAt+C,EAAAs+C,SACAC,EAAAv+C,EAAAu+C,QAmCArG,GAAA92E,UAAAq0F,WAAAvd,EAAA92E,UAAAs0F,QAAA,SAAAL,EACArwF,GACA,GAAA,kBAAAqwF,GAAA,CACA,GAAAM,GAAAL,MACAl2F,KAAA4F,GAAA2lC,OAAA3lC,GAAAwuF,SACAmC,EAAAP,GAEAj3F,KAAA29E,MACA6Z,EACAJ,MACAn2F,GACAjB,KACAk3F,GAGA,MAAAl3F,UAIAg9E,SAAA,KAAAya,IAAA,SAAAzd,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,WAUA,QAAA+zF,MAgDA,QAAA55C,GAAA/nC,EAAAuzE,GACA,GAAA,MAAAvzE,GAAAA,EAAAutC,cAAAm7B,EACA,KAAA,IAAArqC,GAAA,uFAEA,IAAA,kBAAAk1C,GACA,KAAA,IAAAl1C,GAAA,gCAAA7N,EAAAs9C,YAAAyF,IAKA,QAAA7K,GAAA6K,GACAA,IAAA1H,GACA9jC,EAAAp5C,KAAA4kF,GAEA5kF,KAAA69E,UAAA,EACA79E,KAAA03F,yBAAAz2F,GACAjB,KAAA23F,uBAAA12F,GACAjB,KAAA43F,cAAA32F,GACAjB,KAAA63F,eAAA52F,GACAjB,KAAA83F,qBAAAlT,GACA5kF,KAAA2jF,kBACA3jF,KAAAktF,WAAA,iBAAAltF,MAqnBA,QAAA+3F,GAAAv+C,GAAAx5C,KAAA8L,QAAAgyE,iBAAAtkC,GACA,QAAAw+C,GAAAx+C,GAAAx5C,KAAA8L,QAAA8oF,gBAAAp7C,GAAA,GA4CA,QAAAy+C,GAAA12F,GACA,GAAAkqE,GAAA,GAAAsO,GAAAmD,EACAzR,GAAAisB,qBAAAn2F,EACAkqE,EAAAksB,mBAAAp2F,EACAkqE,EAAAmsB,UAAAr2F,EACAkqE,EAAAosB,WAAAt2F,EArvBA,GAaAma,GAbAw8E,EAAA,WACA,MAAA,IAAAxoD,GAAA,wEAEAyoD,EAAA,WACA,MAAA,IAAApe,GAAAqe,kBAAAp4F,KAAAG,YAEA+/E,EAAA,SAAAl7C,GACA,MAAA+0C,GAAA5gE,OAAA,GAAAu2B,GAAA1K,KAGAqzD,KACAx2D,EAAAm4C,EAAA,SAIAt+D,GADAmmB,EAAAq6C,OACA,WACA,GAAA3rD,GAAA4rD,EAAA8O,MAEA,YADAhqF,KAAAsvB,IAAAA,EAAA,MACAA,GAGA,WACA,MAAA,OAGAsR,EAAAokD,kBAAAlM,EAAA,aAAAr+D,EAEA,IAAAi0E,GAAA3V,EAAA,SACAO,EAAAP,EAAA,WACAqG,EAAA,GAAA9F,EACAoV,GAAAljD,eAAAstC,EAAA,UAAAx4E,MAAA8+E,GACA,IAAA4T,GAAAja,EAAA,YACAtqC,EAAAqqC,EAAArqC,UAAAukD,EAAAvkD,SACAqqC,GAAAkW,WAAAgE,EAAAhE,UACA,IAAAH,GAAA/V,EAAA+V,kBAAAmE,EAAAnE,iBACA/V,GAAAgW,aAAAkE,EAAAlE,aACAhW,EAAAwV,iBAAA0E,EAAA1E,iBACAxV,EAAAwW,eAAA0D,EAAA1E,iBACAxV,EAAAiW,eAAAiE,EAAAjE,cACA,IAAA9S,GAAA,aACAob,KACA7V,KACAtF,EAAAnD,EAAA,eAAAD,EAAAmD,GACA+C,EACAjG,EAAA,mBAAAD,EAAAmD,EACAC,EAAA+C,EAAA8S,GACA5P,EAAApJ,EAAA,aAAAD,GAEAyJ,EAAAJ,EAAAtrD,OACAslD,EAAApD,EAAA,mBAAAD,EAAAqJ,GAEAyO,GADAzU,EAAAkG,cAEAtJ,EAAA,aAAAD,EAAAoD,EAAAsF,IACAC,EAAA1I,EAAA,kBAAAyI,GACAmU,EAAA5c,EAAA,cACAoG,EAAAv+C,EAAAu+C,SACAD,EAAAt+C,EAAAs+C,QA0sBA,OAjrBApG,GAAA92E,UAAAwmC,SAAA,WACA,MAAA,oBAGAswC,EAAA92E,UAAAwrF,OAAA1U,EAAA92E,UAAA,MAAA,SAAA24D,GACA,GAAAiQ,GAAAxrE,UAAAlB,MACA,IAAA0sE,EAAA,EAAA,CACA,GACAjtE,GADAi0F,EAAA,GAAAtyF,OAAAsrE,EAAA,GACAhgC,EAAA,CACA,KAAAjtC,EAAA,EAAAA,EAAAitE,EAAA,IAAAjtE,EAAA,CACA,GAAAkkF,GAAAziF,UAAAzB,EACA,KAAAijC,EAAAmhD,SAAAF,GAGA,MAAA5C,GAAA,0DACAr+C,EAAAs9C,YAAA2D,GAHA+P,GAAAhnD,KAAAi3C,EAQA,MAFA+P,GAAA1zF,OAAA0sC,EACA+vB,EAAAv7D,UAAAzB,GACAoB,KAAA4D,SAAA3C,GAAAyhF,EAAAmQ,EAAAj3B,EAAA57D,OAEA,MAAAA,MAAA4D,SAAA3C,GAAA26D,IAGAme,EAAA92E,UAAAs1F,QAAA,WACA,MAAAv4F,MAAA29E,MAAAwa,EACAA,MAAAl3F,GAAAjB,SAAAiB,KAGA84E,EAAA92E,UAAAW,KAAA,SAAA40F,EAAAC,GACA,GAAArb,EAAAgK,YAAA/mF,UAAAlB,OAAA,GACA,kBAAAq5F,IACA,kBAAAC,GAAA,CACA,GAAAzzD,GAAA,kDACAnD,EAAAs9C,YAAAqZ,EACAn4F,WAAAlB,OAAA,IACA6lC,GAAA,KAAAnD,EAAAs9C,YAAAsZ,IAEAz4F,KAAAwgF,MAAAx7C,GAEA,MAAAhlC,MAAA29E,MAAA6a,EAAAC,MAAAx3F,OAAAA,OAAAA,KAGA84E,EAAA92E,UAAA3B,KAAA,SAAAk3F,EAAAC,GAEAz4F,KAAA29E,MAAA6a,EAAAC,MAAAx3F,OAAAA,OAAAA,IACAy3F,eAGA3e,EAAA92E,UAAAoyF,OAAA,SAAAz5B,GACA,MAAA,kBAAAA,GACAskB,EAAA,gCAAAr+C,EAAAs9C,YAAAvjB,IAEA57D,KAAAwb,MAAAmiE,MAAA/hB,MAAA36D,OAAAA,GAAAq3F,MAAAr3F,KAGA84E,EAAA92E,UAAA01F,OAAA,WACA,GAAApoE,IACA85C,aAAA,EACAkoB,YAAA,EACAqG,qBAAA33F,GACA43F,oBAAA53F,GASA,OAPAjB,MAAAqqE,eACA95C,EAAAqoE,iBAAA54F,KAAAuB,QACAgvB,EAAA85C,aAAA,GACArqE,KAAAuyF,eACAhiE,EAAAsoE,gBAAA74F,KAAA2V,SACA4a,EAAAgiE,YAAA,GAEAhiE,GAGAwpD,EAAA92E,UAAAuY,IAAA,WAIA,MAHAnb,WAAAlB,OAAA,GACAa,KAAAwgF,MAAA,wDAEA,GAAAP,GAAAjgF,MAAA8L,WAGAiuE,EAAA92E,UAAAyR,MAAA,SAAAknD,GACA,MAAA57D,MAAAyuF,OAAA5sD,EAAAi3D,wBAAAl9B,IAGAme,EAAAgf,kBAAA15F,EAAAJ,QAEA86E,EAAA1iB,GAAA,SAAAjvB,GACA,MAAAA,aAAA2xC,IAGAA,EAAAif,SAAAjf,EAAAkf,aAAA,SAAAr9B,GACA,GAAArrC,GAAA,GAAAwpD,GAAAmD,EACA3sD,GAAA+6D,oBACA,IAAAuL,GAAAx2F,UAAAlB,OAAA,KAAAqtC,OAAAnsC,UAAA,IAAAw2F,UAEA/pE,EAAAqzD,EAAAvkB,GAAAg7B,EAAArmE,EAAAsmE,GAKA,OAJA/pE,KAAAszD,GACA7vD,EAAAqkE,gBAAA9nE,EAAA3uB,GAAA,GAEAoyB,EAAA2oE,iBAAA3oE,EAAA4oE,sBACA5oE,GAGAwpD,EAAAv+D,IAAA,SAAAF,GACA,MAAA,IAAA2kE,GAAA3kE,GAAAxP,WAGAiuE,EAAAqf,KAAA,SAAAxsD,GACA,GAAArc,GAAA4sD,EAAAvwC,EAOA,OANArc,aAAAwpD,KACAxpD,EAAA,GAAAwpD,GAAAmD,GACA3sD,EAAA+6D,qBACA/6D,EAAA8oE,gBACA9oE,EAAAonE,mBAAA/qD,GAEArc,GAGAwpD,EAAAjmE,QAAAimE,EAAAuf,UAAAvf,EAAAqf,KAEArf,EAAA5gE,OAAA4gE,EAAAwf,SAAA,SAAA5jF,GACA,GAAA4a,GAAA,GAAAwpD,GAAAmD,EAGA,OAFA3sD,GAAA+6D,qBACA/6D,EAAAqkE,gBAAAj/E,GAAA,GACA4a,GAGAwpD,EAAA4B,aAAA,SAAA/f,GACA,GAAA,kBAAAA,GACA,KAAA,IAAAlsB,GAAA,gCAAA7N,EAAAs9C,YAAAvjB,GAEA,OAAAykB,GAAA1E,aAAA/f,IAGAme,EAAA92E,UAAA06E,MAAA,SACA6a,EACAC,EACAlb,EAAAnC,EACAoe,GAEA,GAAAC,OAAAx4F,KAAAu4F,EACA1tF,EAAA2tF,EAAAD,EAAA,GAAAzf,GAAAmD,GACAr9E,EAAAG,KAAAG,UACA00F,EAAAh1F,EAAAg+E,SAEA4b,KACA3tF,EAAAkyE,eAAAh+E,KAAA,GACA8L,EAAAw/E,yBACArqF,KAAAm6E,GACA,IAAA,QAAAp7E,KAAA69E,aAEAzC,EADA,IAAA,SAAAyZ,GACA70F,KAAAk+E,cAEAr+E,IAAAG,SAAAiB,GAAAjB,KAAAu+E,UAGAv+E,KAAAktF,WAAA,iBAAAltF,KAAA8L,GAGA,IAAAm/E,GAAAvvE,GACA,IAAA,IAAA,SAAAm5E,GAAA,CACA,GAAA1H,GAAA5rF,EAAAm4F,EAAA75F,EAAA85F,iBACA,KAAA,SAAA9E,IACAtzF,EAAA1B,EAAA83F,mBACAxK,EAAAqL,GACA,IAAA,SAAA3D,IACAtzF,EAAA1B,EAAA63F,qBACAvK,EAAAsL,EACA54F,EAAAkrF,+BAEA2O,EAAA75F,EAAA+5F,uCACAr4F,EAAA,GAAAuuF,GAAA,8BACAjwF,EAAAuiF,kBAAA7gF,GACA4rF,EAAAsL,GAGApY,EAAA5D,OAAAid,EAAA75F,GACAstF,QAAA,OAAAlC,EAAAkC,EACA,kBAAAA,IACAtrD,EAAAqpD,WAAAD,EAAAkC,GACArhF,QAAAA,EACAsvE,SAAAA,EACA75E,MAAAA,QAGA1B,GAAAg6F,cAAArB,EAAAC,EAAA3sF,EAAAsvE,EAAA6P,EAGA,OAAAn/E,IAGAiuE,EAAA92E,UAAAy+E,QAAA,WACA,MAAA,OAAA1hF,KAAA69E,WAGA9D,EAAA92E,UAAAi2F,cAAA,WACA,MAAA,KAAA,UAAAl5F,KAAA69E,YAGA9D,EAAA92E,UAAA29E,aAAA,WACA,MAAA,YAAA,SAAA5gF,KAAA69E,YAGA9D,EAAA92E,UAAA62F,WAAA,SAAAjuB,GACA7rE,KAAA69E,WAAA,MAAA79E,KAAA69E,UACA,MAAAhS,GAGAkO,EAAA92E,UAAAo2F,cAAA,WACAr5F,KAAA69E,UAAA,SAAA79E,KAAA69E,UACA79E,KAAAktF,WAAA,mBAAAltF,OAGA+5E,EAAA92E,UAAA82F,aAAA,WACA/5F,KAAA69E,UAAA,SAAA79E,KAAA69E,UACA79E,KAAAktF,WAAA,kBAAAltF,OAGA+5E,EAAA92E,UAAA+2F,cAAA,WACAh6F,KAAA69E,UAAA,SAAA79E,KAAA69E,UACA79E,KAAAktF,WAAA,kBAAAltF,OAGA+5E,EAAA92E,UAAAy1F,YAAA,WACA14F,KAAA69E,UAAA,QAAA79E,KAAA69E,WAGA9D,EAAA92E,UAAAg3F,SAAA,WACA,OAAA,QAAAj6F,KAAA69E,WAAA,GAGA9D,EAAA92E,UAAAi3F,gBAAA,WACAl6F,KAAA69E,WAAA,MAAA79E,KAAA69E,WAGA9D,EAAA92E,UAAAu+E,cAAA,WACAxhF,KAAA69E,UAAA,MAAA79E,KAAA69E,UACA79E,KAAAktF,WAAA,mBAAAltF,OAGA+5E,EAAA92E,UAAAg+E,oBAAA,WACAjhF,KAAA69E,UAAA,QAAA79E,KAAA69E,WAGA9D,EAAA92E,UAAAk2F,oBAAA,WACA9Y,EAAAzE,uBACA57E,KAAA69E,UAAA,UAAA79E,KAAA69E,YAGA9D,EAAA92E,UAAAk3F,YAAA,SAAAvjD,GACA,GAAArmB,GAAA,IAAAqmB,EAAA52C,KAAA63F,WAAA73F,KACA,EAAA42C,EAAA,EAAA,EACA,IAAArmB,IAAA8nE,EAEA,WAAAp3F,KAAAsvB,GAAAvwB,KAAAw+E,WACAx+E,KAAAk+E,cAEA3tD,GAGAwpD,EAAA92E,UAAAm3F,WAAA,SAAAxjD,GACA,MAAA52C,MACA,EAAA42C,EAAA,EAAA,IAGAmjC,EAAA92E,UAAAo3F,sBAAA,SAAAzjD,GACA,MAAA52C,MACA,EAAA42C,EAAA,EAAA,IAGAmjC,EAAA92E,UAAAq3F,oBAAA,SAAA1jD,GACA,MAAA52C,MACA,EAAA42C,EAAA,EAAA,IAGAmjC,EAAA92E,UAAAi7E,YAAA,aAEAnE,EAAA92E,UAAAs3F,kBAAA,SAAAC,GACA,GACAC,IADAD,EAAA3c,UACA2c,EAAA9C,sBACAv+E,EAAAqhF,EAAA7C,mBACA7rF,EAAA0uF,EAAA5C,UACAxc,EAAAof,EAAAL,YAAA,OACAl5F,KAAAm6E,IAAAA,EAAAid,GACAr4F,KAAA65F,cAAAY,EAAAthF,EAAArN,EAAAsvE,EAAA,OAGArB,EAAA92E,UAAAy3F,mBAAA,SAAAF,EAAA5jD,GACA,GAAA6jD,GAAAD,EAAAH,sBAAAzjD,GACAz9B,EAAAqhF,EAAAF,oBAAA1jD,GACA9qC,EAAA0uF,EAAAJ,WAAAxjD,GACAwkC,EAAAof,EAAAL,YAAAvjD,OACA31C,KAAAm6E,IAAAA,EAAAid,GACAr4F,KAAA65F,cAAAY,EAAAthF,EAAArN,EAAAsvE,EAAA,OAGArB,EAAA92E,UAAA42F,cAAA,SACAY,EACAthF,EACArN,EACAsvE,EACA6P,GAEA,GAAAr0C,GAAA52C,KAAA0hF,SAOA,IALA9qC,GAAA,QACAA,EAAA,EACA52C,KAAA85F,WAAA,IAGA,IAAAljD,EACA52C,KAAA43F,UAAA9rF,EACA9L,KAAA63F,WAAAzc,EACA,kBAAAqf,KACAz6F,KAAA03F,qBACA,OAAAzM,EAAAwP,EAAA54D,EAAAqpD,WAAAD,EAAAwP,IAEA,kBAAAthF,KACAnZ,KAAA23F,mBACA,OAAA1M,EAAA9xE,EAAA0oB,EAAAqpD,WAAAD,EAAA9xE,QAEA,CACA,GAAAosB,GAAA,EAAAqR,EAAA,CACA52C,MAAAulC,EAAA,GAAAz5B,EACA9L,KAAAulC,EAAA,GAAA61C,EACA,kBAAAqf,KACAz6F,KAAAulC,EAAA,GACA,OAAA0lD,EAAAwP,EAAA54D,EAAAqpD,WAAAD,EAAAwP,IAEA,kBAAAthF,KACAnZ,KAAAulC,EAAA,GACA,OAAA0lD,EAAA9xE,EAAA0oB,EAAAqpD,WAAAD,EAAA9xE,IAIA,MADAnZ,MAAA85F,WAAAljD,EAAA,GACAA,GAGAmjC,EAAA92E,UAAA6xF,OAAA,SAAA6F,EAAAtf,GACAr7E,KAAA65F,kBAAA54F,OAAAA,GAAAo6E,EAAAsf,EAAA,OAGA5gB,EAAA92E,UAAA66E,iBAAA,SAAAv8E,EAAAq5F,GACA,GAAA,IAAA,UAAA56F,KAAA69E,WAAA,CACA,GAAAt8E,IAAAvB,KACA,MAAAA,MAAA40F,gBAAAsD,KAAA,EACA,IAAA9Z,GAAAjB,EAAA57E,EAAAvB,KACA,MAAAo+E,YAAArE,IAAA,MAAA/5E,MAAAo0F,SAAA7yF,EAEAq5F,IAAA56F,KAAAg+E,eAAAI,EAAA,EAEA,IAAAtyE,GAAAsyE,EAAAj+E,SAEA,IAAA2L,IAAA9L,KAEA,WADAA,MAAAiZ,QAAAi/E,IAIA,IAAArD,GAAA/oF,EAAA+xE,SACA,IAAA,IAAA,SAAAgX,GAAA,CACA,GAAAhpB,GAAA7rE,KAAA0hF,SACA7V,GAAA,GAAA//D,EAAAyuF,kBAAAv6F,KACA,KAAA,GAAApB,GAAA,EAAAA,EAAAitE,IAAAjtE,EACAkN,EAAA4uF,mBAAA16F,KAAApB,EAEAoB,MAAAg6F,gBACAh6F,KAAA85F,WAAA,GACA95F,KAAA66F,aAAA/uF,OACA,IAAA,IAAA,SAAA+oF,GACA70F,KAAAo0F,SAAAtoF,EAAA6iF,cACA,IAAA,IAAA,SAAAkG,GACA70F,KAAAiZ,QAAAnN,EAAA0iF,eACA,CACA,GAAA74E,GAAA,GAAAm6E,GAAA,6BACAhkF,GAAAs2E,kBAAAzsE,GACA3V,KAAAiZ,QAAAtD,MAIAokE,EAAA92E,UAAA2xF,gBACA,SAAAj/E,EAAAmlF,EAAAC,GACA,GAAAhX,GAAAliD,EAAAm5D,kBAAArlF,GACAslF,EAAAlX,IAAApuE,CACA,KAAAslF,IAAAF,GAAA3d,EAAAgK,WAAA,CACA,GAAAxtD,GAAA,4CACAiI,EAAAs9C,YAAAxpE,EACA3V,MAAAwgF,MAAA5mD,GAAA,GAEA55B,KAAAoiF,kBAAA2B,IAAA+W,GAAAG,GACAj7F,KAAAiZ,QAAAtD,IAGAokE,EAAA92E,UAAA60F,qBAAA,SAAAlT,GACA,GAAAA,IAAA1H,EAAA,CACA,GAAApxE,GAAA9L,IACAA,MAAAsrF,qBACAtrF,KAAA4jF,cACA,IAAAkX,IAAA,EACAx8F,EAAA0B,KAAAgtF,SAAApI,EAAA,SAAArjF,GACAuK,EAAAgyE,iBAAAv8E,IACA,SAAAoU,GACA7J,EAAA8oF,gBAAAj/E,EAAAmlF,IAEAA,IAAA,EACA96F,KAAA6jF,kBAEA5iF,KAAA3C,GACAwN,EAAA8oF,gBAAAt2F,GAAA,KAIAy7E,EAAA92E,UAAAi4F,0BAAA,SACA/N,EAAA/R,EAAA75E,EAAAuK,GAEA,GAAA+oF,GAAA/oF,EAAA+xE,SACA,IAAA,IAAA,MAAAgX,GAAA,CACA/oF,EAAA83E,cACA,IAAArY,EACA6P,KAAAkd,EACA/2F,GAAA,gBAAAA,GAAApC,OAKAosE,EAAA4U,EAAAgN,GAAAzsF,MAAAV,KAAAk+E,cAAA38E,IAJAgqE,EAAA6U,EACA7U,EAAAptE,EAAA,GAAAuxC,GAAA,iCACA7N,EAAAs9C,YAAA59E,KAKAgqE,EAAA4U,EAAAgN,GAAAjuF,KAAAk8E,EAAA75E,EAEA,IAAA6kF,GAAAt6E,EAAA+3E,aACAgR,GAAA/oF,EAAA+xE,UACA,IAAA,MAAAgX,KAEAtpB,IAAAkX,EACA32E,EAAAmN,QAAA1X,GACAgqE,IAAA6U,EACAt0E,EAAA8oF,gBAAArpB,EAAAptE,GAAA,IAEAi/E,EAAA8I,sBAAA3a,EAAA6a,EAAA,GAAAt6E,EAAA9L,MACA8L,EAAAgyE,iBAAAvS,OAIAwO,EAAA92E,UAAA9C,QAAA,WAEA,IADA,GAAAowB,GAAAvwB,KACAuwB,EAAAqwD,gBAAArwD,EAAAA,EAAAswD,WACA,OAAAtwD,IAGAwpD,EAAA92E,UAAA49E,UAAA,WACA,MAAA7gF,MAAA23F,oBAGA5d,EAAA92E,UAAA43F,aAAA,SAAA/uF,GACA9L,KAAA23F,mBAAA7rF,GAGAiuE,EAAA92E,UAAAk4F,eAAA,SAAArvF,EAAAqhF,EAAA/R,EAAA75E,GACA,GAAA65F,GAAAtvF,YAAAiuE,GACA8a,EAAA70F,KAAA69E,UACAwd,EAAA,IAAA,UAAAxG,EACA,KAAA,MAAAA,IACAuG,GAAAtvF,EAAAy2E,0BAEAnH,YAAAyW,IACAzW,EAAAkX,oBACAlX,EAAA2W,cAAAjmF,EACAq0E,EAAAgN,GAAAjuF,KAAAk8E,EAAA75E,KAAA6+E,GACAt0E,EAAAmN,QAAAmnE,EAAAjiF,IAEAgvF,IAAAgL,EACArsF,EAAAsoF,SAAA+D,EAAAj5F,KAAAk8E,IACAA,YAAA4X,GACA5X,EAAAiZ,kBAAAvoF,GACAsvF,GAAAtvF,YAAAm0E,GACAn0E,EAAAy1E,UAEAnG,EAAAmF,UAEA,kBAAA4M,GACAiO,GAGAC,GAAAvvF,EAAAqtF,sBACAn5F,KAAAk7F,0BAAA/N,EAAA/R,EAAA75E,EAAAuK,IAHAqhF,EAAAjuF,KAAAk8E,EAAA75E,EAAAuK,GAKAsvE,YAAA4X,GACA5X,EAAA8Y,gBACA,IAAA,SAAAW,GACAzZ,EAAAqZ,kBAAAlzF,EAAAuK,GAEAsvE,EAAAsZ,iBAAAnzF,EAAAuK,IAGAsvF,IACAC,GAAAvvF,EAAAqtF,sBACA,IAAA,SAAAtE,GACA/oF,EAAAsoF,SAAA7yF,GAEAuK,EAAAmN,QAAA1X,KAKAw4E,EAAA92E,UAAA22F,uCAAA,SAAArV,GACA,GAAA4I,GAAA5I,EAAA4I,QACArhF,EAAAy4E,EAAAz4E,QACAsvE,EAAAmJ,EAAAnJ,SACA75E,EAAAgjF,EAAAhjF,KACA,mBAAA4rF,GACArhF,YAAAiuE,GAGA/5E,KAAAk7F,0BAAA/N,EAAA/R,EAAA75E,EAAAuK,GAFAqhF,EAAAjuF,KAAAk8E,EAAA75E,EAAAuK,GAIAA,YAAAiuE,IACAjuE,EAAAmN,QAAA1X,IAIAw4E,EAAA92E,UAAA02F,kBAAA,SAAApV,GACAvkF,KAAAm7F,eAAA5W,EAAAz4E,QAAAy4E,EAAA4I,QAAA5I,EAAAnJ,SAAAmJ,EAAAhjF,QAGAw4E,EAAA92E,UAAAq4F,gBAAA,SAAAnO,EAAA5rF,EAAAszF,GACA,GAAA/oF,GAAA9L,KAAA43F,UACAxc,EAAAp7E,KAAAm6F,YAAA,EACAn6F,MAAA43F,cAAA32F,GACAjB,KAAA63F,eAAA52F,GACAjB,KAAAm7F,eAAArvF,EAAAqhF,EAAA/R,EAAA75E,IAGAw4E,EAAA92E,UAAAs4F,0BAAA,SAAA3kD,GACA,GAAArR,GAAA,EAAAqR,EAAA,CACA52C,MAAAulC,EAAA,GACAvlC,KAAAulC,EAAA,GACAvlC,KAAAulC,EAAA,GACAvlC,KAAAulC,EAAA,OAAAtkC,IAGA84E,EAAA92E,UAAAmxF,SAAA,SAAA7yF,GACA,GAAAszF,GAAA70F,KAAA69E,SACA,OAAA,UAAAgX,KAAA,IAAA,CACA,GAAAtzF,IAAAvB,KAAA,CACA,GAAA4B,GAAAs2F,GAEA,OADAl4F,MAAAoiF,kBAAAxgF,GACA5B,KAAAiZ,QAAArX,GAEA5B,KAAAq5F,gBACAr5F,KAAA23F,mBAAAp2F,GAEA,MAAAszF,GAAA,IACA,IAAA,UAAAA,GACA70F,KAAA28E,kBAEA0D,EAAA3D,eAAA18E,SAKA+5E,EAAA92E,UAAAgW,QAAA,SAAAtD,GACA,GAAAk/E,GAAA70F,KAAA69E,SACA,OAAA,UAAAgX,KAAA,IAAA,CAIA,GAHA70F,KAAA+5F,eACA/5F,KAAA03F,qBAAA/hF,EAEA3V,KAAAi6F,WACA,MAAA5Z,GAAApE,WAAAtmE,EAAAksB,EAAAq6C,SAGA,MAAA2Y,GAAA,EACAxU,EAAA3D,eAAA18E,MAEAA,KAAAqqF,oCAIAtQ,EAAA92E,UAAAu4F,iBAAA,SAAA3vB,EAAAtqE,GACA,IAAA,GAAA3C,GAAA,EAAAA,EAAAitE,EAAAjtE,IAAA,CACA,GAAAuuF,GAAAntF,KAAAq6F,sBAAAz7F,GACAkN,EAAA9L,KAAAo6F,WAAAx7F,GACAw8E,EAAAp7E,KAAAm6F,YAAAv7F,EACAoB,MAAAu7F,0BAAA38F,GACAoB,KAAAm7F,eAAArvF,EAAAqhF,EAAA/R,EAAA75E,KAIAw4E,EAAA92E,UAAAw4F,gBAAA,SAAA5vB,EAAAl2D,GACA,IAAA,GAAA/W,GAAA,EAAAA,EAAAitE,EAAAjtE,IAAA,CACA,GAAAuuF,GAAAntF,KAAAs6F,oBAAA17F,GACAkN,EAAA9L,KAAAo6F,WAAAx7F,GACAw8E,EAAAp7E,KAAAm6F,YAAAv7F,EACAoB,MAAAu7F,0BAAA38F,GACAoB,KAAAm7F,eAAArvF,EAAAqhF,EAAA/R,EAAAzlE,KAIAokE,EAAA92E,UAAA05E,gBAAA,WACA,GAAAkY,GAAA70F,KAAA69E,UACAhS,EAAA,MAAAgpB,CAEA,IAAAhpB,EAAA,EAAA,CACA,GAAA,IAAA,SAAAgpB,GAAA,CACA,GAAAl/E,GAAA3V,KAAA03F,oBACA13F,MAAAs7F,gBAAAt7F,KAAA23F,mBAAAhiF,EAAAk/E,GACA70F,KAAAy7F,gBAAA5vB,EAAAl2D,OACA,CACA,GAAApU,GAAAvB,KAAA23F,kBACA33F,MAAAs7F,gBAAAt7F,KAAA03F,qBAAAn2F,EAAAszF,GACA70F,KAAAw7F,iBAAA3vB,EAAAtqE,GAEAvB,KAAA85F,WAAA,GAEA95F,KAAA+sF,0BAGAhT,EAAA92E,UAAA0nF,cAAA,WACA,GAAAkK,GAAA70F,KAAA69E,SACA,OAAA,KAAA,SAAAgX,GACA70F,KAAA23F,mBACA,IAAA,SAAA9C,GACA70F,KAAA03F,yBADA,IAQA3d,EAAA7gE,MAAA6gE,EAAA5uC,QAAA,WAGA,MAFAiyC,GAAA6J,WAAA,gBAAA,gBAGAn7E,QAFA,GAAAiuE,GAAAmD,GAGAppE,QAAAikF,EACA5+E,OAAA6+E,IAIAn2D,EAAAokD,kBAAAlM,EACA,2BACAme,GAEAle,EAAA,YAAAD,EAAAmD,EAAAC,EAAA+C,EACA9C,GACApD,EAAA,UAAAD,EAAAmD,EAAAC,EAAAC,GACApD,EAAA,YAAAD,EAAAkG,EAAAC,EAAA9C,GACApD,EAAA,oBAAAD,GACAC,EAAA,4BAAAD,GACAC,EAAA,UACAD,EAAAkG,EAAA9C,EAAAD,EAAAmD,EAAA3kE,GACAq+D,EAAAA,QAAAA,EACAA,EAAAnJ,QAAA,QACAoJ,EAAA,YAAAD,EAAAkG,EAAAC,EAAA/C,EAAAD,EAAAE,GACApD,EAAA,iBAAAD,GACAC,EAAA,cAAAD,EAAAmG,EAAA/C,EAAAqG,EAAAtG,EAAAE,GACApD,EAAA,eAAAD,EAAAmD,EAAAE,GACApD,EAAA,mBAAAD,EAAAmG,EAAAhD,EAAAC,EAAA6V,EAAA5V,GACApD,EAAA,gBAAAD,GACAC,EAAA,kBAAAD,EAAAmD,GACAlD,EAAA,cAAAD,EAAAkG,EAAA9C,EAAA+C,GACAlG,EAAA,aAAAD,EAAAmD,EAAAC,EAAA+C,GACAlG,EAAA,eAAAD,EAAAkG,EAAAC,EAAA/C,EAAAD,EAAAE,GACApD,EAAA,eAAAD,EAAAkG,EAAA7C,GACApD,EAAA,aAAAD,EAAAkG,EAAAC,GACAlG,EAAA,eAAAD,EAAAmD,GACAlD,EAAA,aAAAD,EAAAmD,GACAlD,EAAA,YAAAD,GAEAl4C,EAAA65D,iBAAA3hB,GACAl4C,EAAA65D,iBAAA3hB,EAAA92E,WAUAg1F,GAAAv5F,EAAA,IACAu5F,GAAAp0C,EAAA,IACAo0C,GAAAvlB,EAAA,IACAulB,EAAA,GACAA,EAAA,cACAA,MAAAh3F,IACAg3F,GAAA,GACAA,EAAA,GAAAle,GAAAmD,IACAE,EAAAiM,UAAA9O,EAAAmB,eAAA75C,EAAAynD,eACAvP,KAIA4hB,WAAA,EAAAC,UAAA,EAAAC,SAAA,EAAAC,gBAAA,EAAAC,WAAA,EAAAjJ,iBAAA,EAAAkJ,YAAA,EAAAC,kBAAA,EAAAC,mBAAA,GAAAC,YAAA,GAAAlO,WAAA,GAAA/K,QAAA,GAAAkZ,cAAA,GAAAC,YAAA,GAAAC,kBAAA,GAAAC,SAAA,GAAAC,WAAA,GAAAC,WAAA,GAAAC,aAAA,GAAAC,eAAA,GAAAC,kBAAA,GAAAC,iBAAA,GAAAC,aAAA,GAAAC,YAAA,GAAAC,cAAA,GAAAC,cAAA,GAAAC,YAAA,GAAAC,2BAAA,GAAAC,cAAA,GAAAC,cAAA,GAAAC,aAAA,GAAAtgB,SAAA,KAAAugB,IAAA,SAAAvjB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAmD,EAAAC,EACA+C,EAAA8S,GAIA,QAAAwK,GAAAp1D,GACA,OAAAA,GACA,KAAA,EAAA,QACA,MAAA,EAAA,QACA,MAAA,EAAA,MAAA,IAAAq1D,MAIA,QAAAxd,GAAAxoE,GACA,GAAA3L,GAAA9L,KAAAyzF,SAAA,GAAA1Z,GAAAmD,EACAzlE,aAAAsiE,IACAjuE,EAAAkyE,eAAAvmE,EAAA,GAEA3L,EAAAwyE,aAAAt+E,MACAA,KAAAg2F,QAAAv+E,EACAzX,KAAA0hF,QAAA,EACA1hF,KAAAk2F,eAAA,EACAl2F,KAAA28D,UAAA17D,IAAA,GApBA,GAAA4gC,GAAAm4C,EAAA,SACAn4C,GAAA0I,OAmLA,OA9JA1I,GAAA1mB,SAAA8kE,EAAA+S,GAEA/S,EAAAh9E,UAAA9D,OAAA,WACA,MAAAa,MAAA0hF,SAGAzB,EAAAh9E,UAAA6I,QAAA,WACA,MAAA9L,MAAAyzF,UAGAxT,EAAAh9E,UAAA05D,MAAA,QAAA3/C,GAAAugE,EAAAmgB,GACA,GAAAjmF,GAAA0lE,EAAAn9E,KAAAg2F,QAAAh2F,KAAAyzF,SACA,IAAAh8E,YAAAsiE,GAAA,CACAtiE,EAAAA,EAAAtX,SACA,IAAA00F,GAAAp9E,EAAAomE,SAIA,IAFA79E,KAAAg2F,QAAAv+E,EAEA,IAAA,SAAAo9E,GAEA,MADA70F,MAAAyzF,SAAA0F,sBACA1hF,EAAAkmE,MACA3gE,EACAhd,KAAAiZ,YACAhY,GACAjB,KACA09F,EAEA,IAAA,IAAA,SAAA7I,GAEA,MAAA,KAAA,SAAAA,GACA70F,KAAAiZ,QAAAxB,EAAA+2E,WAEAxuF,KAAAuhF,SAJA9pE,GAAAA,EAAAk3E,SAQA,GAAA,QADAl3E,EAAAoqB,EAAA87D,QAAAlmF,IACA,CACA,GAAA7V,GAAAs+E,EACA,oDAAAr+C,EAAAs9C,YAAA1nE,IAAA9B,QAEA,YADA3V,MAAAyzF,SAAAmB,gBAAAhzF,GAAA,GAIA,GAAA,IAAA6V,EAAAtY,OAOA,aANA,IAAAu+F,EACA19F,KAAA49F,qBAGA59F,KAAAoZ,SAAAokF,EAAAE,IAIA19F,MAAA69F,SAAApmF,IAGAwoE,EAAAh9E,UAAA46F,SAAA,SAAApmF,GACA,GAAAo0D,GAAA7rE,KAAA89F,gBAAArmF,EAAAtY,OACAa,MAAA0hF,QAAA7V,EACA7rE,KAAAg2F,QAAAh2F,KAAA+9F,mBAAA,GAAAx9F,OAAAsrE,GAAA7rE,KAAAg2F,OAIA,KAAA,GAHAlpE,GAAA9sB,KAAAyzF,SACAuK,GAAA,EACAnJ,EAAA,KACAj2F,EAAA,EAAAA,EAAAitE,IAAAjtE,EAAA,CACA,GAAAw/E,GAAAjB,EAAA1lE,EAAA7Y,GAAAkuB,EAEAsxD,aAAArE,IACAqE,EAAAA,EAAAj+E,UACA00F,EAAAzW,EAAAP,WAEAgX,EAAA,KAGAmJ,EACA,OAAAnJ,GACAzW,EAAAgM,8BAEA,OAAAyK,EACA,IAAA,SAAAA,IACAzW,EAAA0W,OAAA90F,KAAApB,GACAoB,KAAAg2F,QAAAp3F,GAAAw/E,GAEA4f,EADA,IAAA,SAAAnJ,GACA70F,KAAAy0F,kBAAArW,EAAAuQ,SAAA/vF,GACA,IAAA,SAAAi2F,GACA70F,KAAA00F,iBAAAtW,EAAAoQ,UAAA5vF,GAEAoB,KAAAq0F,kBAAAz1F,GAGAo/F,EAAAh+F,KAAAy0F,kBAAArW,EAAAx/E,GAGAo/F,GAAAlxE,EAAAqsE,uBAGAlZ,EAAAh9E,UAAAixF,YAAA,WACA,MAAA,QAAAl0F,KAAAg2F,SAGA/V,EAAAh9E,UAAAmW,SAAA,SAAA7X,GACAvB,KAAAg2F,QAAA,KACAh2F,KAAAyzF,SAAAW,SAAA7yF,IAGA0+E,EAAAh9E,UAAAs+E,QAAA,YACAvhF,KAAAk0F,eAAAl0F,KAAAyzF,SAAA/S,mBACA1gF,KAAAg2F,QAAA,KACAh2F,KAAAyzF,SAAAlS,YAGAtB,EAAAh9E,UAAAgW,QAAA,SAAAtD,GACA3V,KAAAg2F,QAAA,KACAh2F,KAAAyzF,SAAAmB,gBAAAj/E,GAAA,IAGAsqE,EAAAh9E,UAAAwxF,kBAAA,SAAAlzF,EAAAq1C,GAGA,MAFA52C,MAAAg2F,QAAAp/C,GAAAr1C,IACAvB,KAAAk2F,gBACAl2F,KAAA0hF,UACA1hF,KAAAoZ,SAAApZ,KAAAg2F,UACA,IAKA/V,EAAAh9E,UAAAoxF,kBAAA,WAEA,MADAr0F,MAAAuhF,WACA,GAGAtB,EAAAh9E,UAAAyxF,iBAAA,SAAA/+E,GAGA,MAFA3V,MAAAk2F,iBACAl2F,KAAAiZ,QAAAtD,IACA,GAGAsqE,EAAAh9E,UAAAo/E,iBAAA,WACA,IAAAriF,KAAAk0F,cAAA,CACA,GAAAz8E,GAAAzX,KAAAg2F,OAEA,IADAh2F,KAAAuhF,UACA9pE,YAAAsiE,GACAtiE,EAAA8oE,aAEA,KAAA,GAAA3hF,GAAA,EAAAA,EAAA6Y,EAAAtY,SAAAP,EACA6Y,EAAA7Y,YAAAm7E,IACAtiE,EAAA7Y,GAAA2hF,WAMAN,EAAAh9E,UAAA86F,iBAAA,WACA,OAAA,GAGA9d,EAAAh9E,UAAA66F,gBAAA,SAAAjyB,GACA,MAAAA,IAGAoU,KAGAjD,SAAA,KAAAihB,IAAA,SAAAjkB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAmD,GA2BA,QAAAghB,GAAAl6E,GACA,OAAAm6E,EAAAtX,KAAA7iE,GAGA,QAAAo6E,GAAAxiC,GACA,IACA,OAAA,IAAAA,EAAAyiC,kBAEA,MAAAlgG,GACA,OAAA,GAIA,QAAAmgG,GAAA1xD,EAAA5oB,EAAA6gD,GACA,GAAAz8B,GAAAvG,EAAA08D,yBAAA3xD,EAAA5oB,EAAA6gD,EACA25B,EACA,SAAAp2D,GAAAg2D,EAAAh2D,GAEA,QAAAq2D,GAAAluE,EAAAs0C,EAAA65B,GACA,IAAA,GAAA9/F,GAAA,EAAAA,EAAA2xB,EAAApxB,OAAAP,GAAA,EAAA,CACA,GAAAolB,GAAAuM,EAAA3xB,EACA,IAAA8/F,EAAA7X,KAAA7iE,GAEA,IAAA,GADA26E,GAAA36E,EAAArI,QAAA+iF,EAAA,IACA7yD,EAAA,EAAAA,EAAAtb,EAAApxB,OAAA0sC,GAAA,EACA,GAAAtb,EAAAsb,KAAA8yD,EACA,KAAA,IAAAjvD,GAAA,qGACA/zB,QAAA,KAAAkpD,KAOA,QAAA+5B,GAAAhyD,EAAAi4B,EAAA65B,EAAAv0E,GAGA,IAAA,GAFA7K,GAAAuiB,EAAAg9D,kBAAAjyD,GACArc,KACA3xB,EAAA,EAAAA,EAAA0gB,EAAAngB,SAAAP,EAAA,CACA,GAAAolB,GAAA1E,EAAA1gB,GACA2C,EAAAqrC,EAAA5oB,GACA86E,EAAA30E,IAAA40E,GACAA,EAAA/6E,EAAAziB,EAAAqrC,EACA,mBAAArrC,IACA68F,EAAA78F,IACA+8F,EAAA1xD,EAAA5oB,EAAA6gD,KACA16C,EAAAnG,EAAAziB,EAAAqrC,EAAAkyD,IACAvuE,EAAA3Z,KAAAoN,EAAAziB,GAIA,MADAk9F,GAAAluE,EAAAs0C,EAAA65B,GACAnuE,EAkIA,QAAAyuE,GAAA36F,EAAA+2E,EAAAmC,EAAA3hB,EAAAqjC,EAAApI,GAMA,QAAAqI,KACA,GAAAtL,GAAAxY,CACAA,KAAA+jB,IAAAvL,EAAA5zF,KACA,IAAA8L,GAAA,GAAAiuE,GAAAmD,EACApxE,GAAAw/E,oBACA,IAAAl7D,GAAA,gBAAAla,IAAAlW,OAAAo/F,EACAp/F,KAAAkW,GAAA7R,EACAu3D,EAAAg7B,EAAA9qF,EAAA+qF,EACA,KACAzmE,EAAA1vB,MAAAkzF,EAAAyL,EAAAh/F,UAAAu7D,IACA,MAAAz9D,GACA2N,EAAA8oF,gBAAAmC,EAAA54F,IAAA,GAAA,GAGA,MADA2N,GAAAotF,iBAAAptF,EAAAqtF,sBACArtF,EAnBA,GAAAszF,GAAA,WAAA,MAAAp/F,SACAkW,EAAA7R,CAqBA,OApBA,gBAAA6R,KACA7R,EAAAu3D,GAkBA/5B,EAAAokD,kBAAAiZ,EAAA,qBAAA,GACAA,EAOA,QAAAI,GAAA1yD,EAAAi4B,EAAA16C,EAAAo1E,EAAA1I,GAKA,IAAA,GAJA6H,GAAA,GAAA7mC,QAAA2nC,EAAA36B,GAAA,KACAqrB,EACA0O,EAAAhyD,EAAAi4B,EAAA65B,EAAAv0E,GAEAvrB,EAAA,EAAAitE,EAAAqkB,EAAA/wF,OAAAP,EAAAitE,EAAAjtE,GAAA,EAAA,CACA,GAAAolB,GAAAksE,EAAAtxF,GACAg9D,EAAAs0B,EAAAtxF,EAAA,GACA6gG,EAAAz7E,EAAA6gD,CACA,IAAA06B,IAAAG,EACA9yD,EAAA6yD,GACAC,EAAA17E,EAAAm7E,EAAAn7E,EAAA43C,EAAAiJ,EAAAgyB,OACA,CACA,GAAAqI,GAAAK,EAAA3jC,EAAA,WACA,MAAA8jC,GAAA17E,EAAAm7E,EAAAn7E,EACA43C,EAAAiJ,EAAAgyB,IAEAh1D,GAAAokD,kBAAAiZ,EAAA,qBAAA,GACAtyD,EAAA6yD,GAAAP,GAIA,MADAr9D,GAAA65D,iBAAA9uD,GACAA,EAGA,QAAA+yD,GAAAt7F,EAAA+2E,EAAAyb,GACA,MAAA6I,GAAAr7F,EAAA+2E,MAAAn6E,GACAoD,EAAA,KAAAwyF,GAtQA,GAkFA+I,GAlFAT,KACAt9D,EAAAm4C,EAAA,UACA4c,EAAA5c,EAAA,cACAqlB,EAAAx9D,EAAAw9D,aACAtI,EAAAl1D,EAAAk1D,iBACAtX,EAAA59C,EAAA49C,YACA/vC,EAAAsqC,EAAA,YAAAtqC,UAEA8uD,GAAAH,mBAAA,GACAwB,GACA,QAAA,SACA,OACA,YACA,SACA,SACA,YACA,qBAEA1B,EAAA,GAAAtmC,QAAA,OAAAgoC,EAAAz9D,KAAA,KAAA,MAEA28D,EAAA,SAAAx9E,GACA,MAAAsgB,GAAA69C,aAAAn+D,IACA,MAAAA,EAAAkP,OAAA,IACA,gBAAAlP,GAuDAi+E,EAAA,SAAA3W,GACA,MAAAA,GAAAltE,QAAA,QAAA,QAwJA+jF,EAAAjgB,EACAmgB,EACAZ,CAgCAjlB,GAAA4lB,UAAA,SAAA/jC,EAAA/0D,GACA,GAAA,kBAAA+0D,GACA,KAAA,IAAAlsB,GAAA,gCAAA7N,EAAAs9C,YAAAvjB,GAEA,IAAAwiC,EAAAxiC,GACA,MAAAA,EAEA/0D,GAAA2lC,OAAA3lC,EACA,IAAAu0E,OAAAn6E,KAAA4F,EAAA6tD,QAAAyqC,EAAAt4F,EAAA6tD,QACAmiC,IAAAhwF,EAAAgwF,UACAtmE,EAAAovE,EAAA/jC,EAAAwf,EAAAyb,EAEA,OADAh1D,GAAAi+D,gBAAAlkC,EAAArrC,EAAA2tE,GACA3tE,GAGAwpD,EAAAulB,aAAA,SAAAz/F,EAAAgH,GACA,GAAA,kBAAAhH,IAAA,gBAAAA,GACA,KAAA,IAAA6vC,GAAA,+FAEA7oC,GAAA2lC,OAAA3lC,EACA,IAAAgwF,KAAAhwF,EAAAgwF,UACAhyB,EAAAh+D,EAAAg+D,MACA,iBAAAA,KAAAA,EAxRA,QAyRA,IAAA16C,GAAAtjB,EAAAsjB,MACA,mBAAAA,KAAAA,EAAA40E,EACA,IAAAQ,GAAA14F,EAAA04F,WAGA,IAFA,kBAAAA,KAAAA,EAAAG,IAEA79D,EAAA69C,aAAA7a,GACA,KAAA,IAAAorB,YAAA,sEAIA,KAAA,GADA3wE,GAAAuiB,EAAAg9D,kBAAAh/F,GACAjB,EAAA,EAAAA,EAAA0gB,EAAAngB,SAAAP,EAAA,CACA,GAAA2C,GAAA1B,EAAAyf,EAAA1gB,GACA,iBAAA0gB,EAAA1gB,IACAijC,EAAAk+D,QAAAx+F,KACA+9F,EAAA/9F,EAAA0B,UAAA4hE,EAAA16C,EAAAo1E,EACA1I,GACAyI,EAAA/9F,EAAAsjE,EAAA16C,EAAAo1E,EAAA1I,IAIA,MAAAyI,GAAAz/F,EAAAglE,EAAA16C,EAAAo1E,EAAA1I,OAKA5I,WAAA,GAAAyO,aAAA,GAAA1f,SAAA,KAAAgjB,IAAA,SAAAhmB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SACA86E,EAAAkG,EAAA9C,EAAA+C,GAqCA,QAAA+f,GAAArzD,GACA,GACAszD,GADAC,GAAA,CAEA,QAAAl/F,KAAAm/F,GAAAxzD,YAAAwzD,GACAF,EAAAG,EAAAzzD,GACAuzD,GAAA,MACA,CACA,GAAA7gF,GAAAqwE,EAAArwE,KAAAstB,GACAi/B,EAAAvsD,EAAAngB,MACA+gG,GAAA,GAAA3/F,OAAA,EAAAsrE,EACA,KAAA,GAAAjtE,GAAA,EAAAA,EAAAitE,IAAAjtE,EAAA,CACA,GAAAolB,GAAA1E,EAAA1gB,EACAshG,GAAAthG,GAAAguC,EAAA5oB,GACAk8E,EAAAthG,EAAAitE,GAAA7nD,GAGAhkB,KAAAw1F,aAAA0K,GACAlgG,KAAAsgG,OAAAH,EACAngG,KAAA+1F,WAAA90F,GAAAk/F,GAAA,GAAA,GAkCA,QAAA9nB,GAAA/8D,GACA,GAAAiV,GACAgwE,EAAApjB,EAAA7hE,EAEA,OAAA0nE,GAAAud,IAGAhwE,EADAgwE,YAAAxmB,GACAwmB,EAAA5iB,MACA5D,EAAA1B,UAAAp3E,OAAAA,OAAAA,OAAAA,IAEA,GAAAg/F,GAAAM,GAAAz0F,UAGAy0F,YAAAxmB,IACAxpD,EAAAytD,eAAAuiB,EAAA,GAEAhwE,GAXA2vD,EAAA,6EA7FA,GAGAkgB,GAHAv+D,EAAAm4C,EAAA,UACAgJ,EAAAnhD,EAAAmhD,SACA2M,EAAA3V,EAAA,QAEA,mBAAAyjB,OAAA2C,EAAA3C,IAEA,IAAA4C,GAAA,WAIA,QAAAG,GAAAj/F,EAAAyiB,GACAhkB,KAAA42C,GAAAr1C,EACAvB,KAAA42C,EAAAzM,GAAAnmB,EACA4yB,IANA,GAAAA,GAAA,EACAzM,EAAA,CAQA,OAAA,UAAAhqB,GACAgqB,EAAAhqB,EAAAgqB,KACAyM,EAAA,CACA,IAAArmB,GAAA,GAAAhwB,OAAA,EAAA4f,EAAAgqB,KAEA,OADAhqB,GAAA1R,QAAA+xF,EAAAjwE,GACAA,MAIAkwE,EAAA,SAAAP,GAGA,IAAA,GAFA3vE,GAAA,GAAA6vE,GACAjhG,EAAA+gG,EAAA/gG,OAAA,EAAA,EACAP,EAAA,EAAAA,EAAAO,IAAAP,EAAA,CACA,GAAAolB,GAAAk8E,EAAA/gG,EAAAP,GACA2C,EAAA2+F,EAAAthG,EACA2xB,GAAAygE,IAAAhtE,EAAAziB,GAEA,MAAAgvB,GAuBAsR,GAAA1mB,SAAA8kF,EAAAhgB,GAEAggB,EAAAh9F,UAAA05D,MAAA,aAEAsjC,EAAAh9F,UAAAwxF,kBAAA,SAAAlzF,EAAAq1C,GAGA,GAFA52C,KAAAg2F,QAAAp/C,GAAAr1C,IACAvB,KAAAk2F,gBACAl2F,KAAA0hF,QAAA,CACA,GAAAt5C,EACA,IAAApoC,KAAAsgG,OACAl4D,EAAAq4D,EAAAzgG,KAAAg2F,aACA,CACA5tD,IAEA,KAAA,GADAs4D,GAAA1gG,KAAAb,SACAP,EAAA,EAAAitE,EAAA7rE,KAAAb,SAAAP,EAAAitE,IAAAjtE,EACAwpC,EAAApoC,KAAAg2F,QAAAp3F,EAAA8hG,IAAA1gG,KAAAg2F,QAAAp3F,GAIA,MADAoB,MAAAoZ,SAAAgvB,IACA,EAEA,OAAA,GAGA63D,EAAAh9F,UAAA86F,iBAAA,WACA,OAAA,GAGAkC,EAAAh9F,UAAA66F,gBAAA,SAAAjyB,GACA,MAAAA,IAAA,GAsBAkO,EAAA92E,UAAAo1E,MAAA,WACA,MAAAA,GAAAr4E,OAGA+5E,EAAA1B,MAAA,SAAA/8D,GACA,MAAA+8D,GAAA/8D,OAIA4nE,QAAA,GAAAlG,SAAA,KAAA2jB,IAAA,SAAA3mB,EAAA36E,EAAAJ,GACA,YACA,SAAA2hG,GAAApqB,EAAAqqB,EAAAC,EAAAC,EAAAl1B,GACA,IAAA,GAAAhgC,GAAA,EAAAA,EAAAggC,IAAAhgC,EACAi1D,EAAAj1D,EAAAk1D,GAAAvqB,EAAA3qC,EAAAg1D,GACArqB,EAAA3qC,EAAAg1D,OAAA,GAIA,QAAAlmB,GAAAqmB,GACAhhG,KAAAihG,UAAAD,EACAhhG,KAAA0hF,QAAA,EACA1hF,KAAAkhG,OAAA,EAGAvmB,EAAA13E,UAAAk+F,oBAAA,SAAAh3D,GACA,MAAAnqC,MAAAihG,UAAA92D,GAGAwwC,EAAA13E,UAAAw4E,SAAA,SAAAJ,GACA,GAAAl8E,GAAAa,KAAAb,QACAa,MAAAohG,eAAAjiG,EAAA,GAEAa,KADAA,KAAAkhG,OAAA/hG,EAAAa,KAAAihG,UAAA,GACA5lB,EACAr7E,KAAA0hF,QAAAviF,EAAA,GAGAw7E,EAAA13E,UAAA2T,KAAA,SAAAglD,EAAAwf,EAAAC;iCACA,GAAAl8E,GAAAa,KAAAb,SAAA,CACA,IAAAa,KAAAmhG,oBAAAhiG,GAIA,MAHAa,MAAAy7E,SAAA7f,GACA57D,KAAAy7E,SAAAL,OACAp7E,MAAAy7E,SAAAJ,EAGA,IAAAxvC,GAAA7rC,KAAAkhG,OAAA/hG,EAAA,CACAa,MAAAohG,eAAAjiG,EACA,IAAAkiG,GAAArhG,KAAAihG,UAAA,CACAjhG,MAAA6rC,EAAA,EAAAw1D,GAAAzlC,EACA57D,KAAA6rC,EAAA,EAAAw1D,GAAAjmB,EACAp7E,KAAA6rC,EAAA,EAAAw1D,GAAAhmB,EACAr7E,KAAA0hF,QAAAviF,GAGAw7E,EAAA13E,UAAAs1D,MAAA,WACA,GAAA+oC,GAAAthG,KAAAkhG,OACA3wE,EAAAvwB,KAAAshG,EAKA,OAHAthG,MAAAshG,OAAArgG,GACAjB,KAAAkhG,OAAAI,EAAA,EAAAthG,KAAAihG,UAAA,EACAjhG,KAAA0hF,UACAnxD,GAGAoqD,EAAA13E,UAAA9D,OAAA,WACA,MAAAa,MAAA0hF,SAGA/G,EAAA13E,UAAAm+F,eAAA,SAAAj3D,GACAnqC,KAAAihG,UAAA92D,GACAnqC,KAAAuhG,UAAAvhG,KAAAihG,WAAA,IAIAtmB,EAAA13E,UAAAs+F,UAAA,SAAAP,GACA,GAAAQ,GAAAxhG,KAAAihG,SACAjhG,MAAAihG,UAAAD,EAIAJ,EAAA5gG,KAAA,EAAAA,KAAAwhG,EAHAxhG,KAAAkhG,OACAlhG,KAAA0hF,QACA8f,EAAA,IAIAniG,EAAAJ,QAAA07E,OAEA8mB,IAAA,SAAAznB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SACA86E,EAAAmD,EAAAC,EAAA+C,GASA,QAAAwhB,GAAApmF,EAAAylE,GACA,GAAA3C,GAAAjB,EAAA7hE,EAEA,IAAA8iE,YAAArE,GACA,MAAA4nB,GAAAvjB,EAGA,IAAA,QADA9iE,EAAAumB,EAAA87D,QAAAriF,IAEA,MAAA4kE,GAAA,oDAAAr+C,EAAAs9C,YAAA7jE,GAGA,IAAAiV,GAAA,GAAAwpD,GAAAmD,OACAj8E,KAAA8/E,GACAxwD,EAAAytD,eAAA+C,EAAA,EAIA,KAAA,GAFA0Z,GAAAlqE,EAAA6jE,SACAj7E,EAAAoX,EAAAtX,QACAra,EAAA,EAAAitE,EAAAvwD,EAAAnc,OAAAP,EAAAitE,IAAAjtE,EAAA,CACA,GAAAwpC,GAAA9sB,EAAA1c,QAEAqC,KAAAmnC,GAAAxpC,IAAA0c,KAIAy+D,EAAAqf,KAAAhxD,GAAAu1C,MAAA8c,EAAAthF,MAAAlY,GAAAsvB,EAAA,MAEA,MAAAA,GAlCA,GAAAsR,GAAAm4C,EAAA,UAEA2nB,EAAA,SAAA71F,GACA,MAAAA,GAAAlI,KAAA,SAAAy2D,GACA,MAAAqnC,GAAArnC,EAAAvuD,KAiCAiuE,GAAA2nB,KAAA,SAAApmF,GACA,MAAAomF,GAAApmF,MAAAra,KAGA84E,EAAA92E,UAAAy+F,KAAA,WACA,MAAAA,GAAA1hG,SAAAiB,QAKA+7E,SAAA,KAAA4kB,IAAA,SAAA5nB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EACAkG,EACAC,EACA/C,EACAD,EACAE,GAKA,QAAAykB,GAAAvmF,EAAAsgD,EAAAkmC,EAAAC,GACA/hG,KAAAw1F,aAAAl6E,EACA,IAAA2vE,GAAAvvE,GACA1b,MAAAgiG,IAAA,OAAA/W,EAAArvB,EAAA/5B,EAAAqpD,WAAAD,EAAArvB,OACA36D,KAAA6gG,IACAA,EAAA/nB,EAAAjmE,QAAAguF,GACAA,EAAAhd,4BAAA9kF,OAEAA,KAAAiiG,cAAAH,EACA9hG,KAAAkiG,oBAAA,KAEAliG,KAAAmiG,YADAJ,IAAA7kB,EACA38E,MAAAP,KAAA0hF,SACA,IAAAqgB,EACA,SAEA9gG,GAEAjB,KAAAyzF,SAAAnI,qBACAtrF,KAAA+1F,WAAA90F,IAAA,GA0FA,QAAA6/C,GAAAshD,EAAA/nC,GACAr6D,KAAAqqE,cACAhQ,EAAAjhD,SAAAgpF,GAEA/nC,EAAAphD,QAAAmpF,GAIA,QAAAh4C,GAAA9uC,EAAAsgD,EAAAkmC,EAAAC,GACA,MAAA,kBAAAnmC,GACAskB,EAAA,gCAAAr+C,EAAAs9C,YAAAvjB,IAEA,GAAAimC,GAAAvmF,EAAAsgD,EAAAkmC,EAAAC,GACAj2F,UAGA,QAAAu2F,GAAAC,GACAtiG,KAAAsiG,MAAAA,EACAtiG,KAAAq6D,MAAAkoC,UAAAD,EACA,IAAA/gG,GAAA47E,EAAAn9E,KAAAuB,MAAAvB,KAAAq6D,MAAAo5B,SACA,OAAAlyF,aAAAw4E,IACA/5E,KAAAq6D,MAAA6nC,oBAAA3gG,EACAA,EAAAo8E,MAAA6kB,MAAAvhG,OAAAA,GAAAjB,SAAAiB,KAEAuhG,EAAAtjG,KAAAc,KAAAuB,GAIA,QAAAihG,GAAAjhG,GACA,GAAA84D,GAAAr6D,KAAAq6D,MACAvuD,EAAAuuD,EAAAo5B,SACA73B,EAAAukB,EAAA9lB,EAAA2nC,IACAl2F,GAAA83E,cACA,IAAArzD,IAEAA,MADAtvB,KAAAo5D,EAAA8nC,YACAvmC,EAAA18D,KAAA4M,EAAAoyE,cAAA38E,EAAAvB,KAAA42C,MAAA52C,KAAAb,QAEAy8D,EAAA18D,KAAA4M,EAAAoyE,cACAl+E,KAAAsiG,MAAA/gG,EAAAvB,KAAA42C,MAAA52C,KAAAb,kBAEA46E,KACA1f,EAAA6nC,oBAAA3xE,EAEA,IAAA61D,GAAAt6E,EAAA+3E,aAOA,OANAzG,GAAA8I,sBACA31D,EACA61D,MACAnlF,KAAAo5D,EAAA8nC,YAAA,eAAA,iBACAr2F,GAEAykB,EAlKA,GAAA7U,GAAAq+D,EAAAkQ,WACApoD,EAAAm4C,EAAA,UACAmG,EAAAt+C,EAAAs+C,QAsBAt+C,GAAA1mB,SAAA0mF,EAAA5hB,GAEA4hB,EAAA5+F,UAAAs/F,UAAA,SAAAD,OACArhG,KAAAjB,KAAAmiG,aACA,OAAAniG,KAAAmiG,aACAG,IAAAplB,GACAl9E,KAAAmiG,YAAAvrF,KAAA0rF,IAIAT,EAAA5+F,UAAAw/F,cAAA,SAAAlhG,GAIA,MAHA,QAAAvB,KAAAmiG,aACAniG,KAAAmiG,YAAAvrF,KAAArV,GAEAvB,KAAAmiG,aAGAN,EAAA5+F,UAAA05D,MAAA,aAEAklC,EAAA5+F,UAAA26F,mBAAA,WACA59F,KAAAoZ,aAAAnY,KAAAjB,KAAAmiG,YAAAniG,KAAAmiG,YACAniG,KAAAiiG,gBAGAJ,EAAA5+F,UAAA86F,iBAAA,WACA,OAAA,GAGA8D,EAAA5+F,UAAAmW,SAAA,SAAA7X,GACAvB,KAAAyzF,SAAA3V,iBAAAv8E,GACAvB,KAAAg2F,QAAA,MAGA6L,EAAA5+F,UAAAo/E,iBAAA,SAAAx4C,GACA,GAAAA,IAAA7pC,KAAAiiG,cAAA,MAAAjiG,MAAAuhF,SACAvhF,MAAAk0F,gBACAl0F,KAAA0iG,oBACA1iG,KAAAkiG,8BAAAnoB,IACA/5E,KAAAkiG,oBAAA3hB,SAEAvgF,KAAAiiG,wBAAAloB,IACA/5E,KAAAiiG,cAAA1hB,WAIAshB,EAAA5+F,UAAA46F,SAAA,SAAApmF,GACAzX,KAAAg2F,QAAAv+E,CACA,IAAAlW,GACA3C,EACAO,EAAAsY,EAAAtY,MAWA,QAVA8B,KAAAjB,KAAAiiG,eACA1gG,EAAAvB,KAAAiiG,cACArjG,EAAA,IAEA2C,EAAAw4E,EAAAjmE,QAAA2D,EAAA,IACA7Y,EAAA,GAGAoB,KAAAkiG,oBAAA3gG,GAEAA,EAAAgxF,aACA,KAAA3zF,EAAAO,IAAAP,EAAA,CACA,GAAA2lF,IACA+d,MAAA,KACA/gG,MAAAkW,EAAA7Y,GACAg4C,MAAAh4C,EACAO,OAAAA,EACAk7D,MAAAr6D,KAEAuB,GAAAA,EAAAo8E,MAAA0kB,MAAAphG,OAAAA,GAAAsjF,MAAAtjF,QAIAA,KAAAjB,KAAAmiG,cACA5gG,EAAAA,EACAo8E,MAAA39E,KAAAyiG,kBAAAxhG,OAAAA,GAAAjB,SAAAiB,KAEAM,EAAAo8E,MAAA78B,EAAAA,MAAA7/C,GAAAM,EAAAvB,OAGA+5E,EAAA92E,UAAAmnD,OAAA,SAAAwR,EAAAkmC,GACA,MAAA13C,GAAApqD,KAAA47D,EAAAkmC,EAAA,OAGA/nB,EAAA3vB,OAAA,SAAA9uC,EAAAsgD,EAAAkmC,EAAAC,GACA,MAAA33C,GAAA9uC,EAAAsgD,EAAAkmC,EAAAC,OAyDA/kB,SAAA,KAAA2lB,IAAA,SAAA3oB,EAAA36E,EAAAJ,GACA,YACA,IACAi8E,GADAr5C,EAAAm4C,EAAA,UAEA4oB,EAAA,WACA,KAAA,IAAA9jG,OAAA,mEAEA+jG,EAAAhhE,EAAAihE,kBACA,IAAAjhE,EAAAq6C,QAAA,mBAAA6mB,kBAAA,CACA,GAAAC,GAAAvjG,EAAAwjG,aACAC,EAAA/mB,EAAAgnB,QACAjoB,GAAAr5C,EAAAuhE,aACA,SAAAxnC,GAAAonC,EAAA9jG,KAAAO,EAAAm8D,IACA,SAAAA,GAAAsnC,EAAAhkG,KAAAi9E,EAAAvgB,QACA,IAAA,kBAAAinC,IACA,kBAAAA,GAAA/uF,QAAA,CACA,GAAAuvF,GAAAR,EAAA/uF,SACAonE,GAAA,SAAAtf,GACAynC,EAAAz/F,KAAAg4D,QAiCAsf,GA/BA,mBAAA6nB,mBACA,mBAAArtB,SACAA,OAAAC,YACAD,OAAAC,UAAA2tB,YAAA5tB,OAAA6tB,SA2BA,mBAAAN,cACA,SAAArnC,GACAqnC,aAAArnC,IAEA,mBAAA5iD,YACA,SAAA4iD,GACA5iD,WAAA4iD,EAAA,IAGAgnC,EAnCA,WACA,GAAAY,GAAA58B,SAAA68B,cAAA,OACA1hG,GAAA2hG,YAAA,GACAC,GAAA,EACAC,EAAAh9B,SAAA68B,cAAA,MACA,IAAAV,kBAAA,WACAS,EAAAK,UAAAC,OAAA,OACAH,GAAA,IAEAI,QAAAH,EAAA7hG,EAEA,IAAAiiG,GAAA,WACAL,IACAA,GAAA,EACAC,EAAAC,UAAAC,OAAA,QAGA,OAAA,UAAAloC,GACA,GAAAp9D,GAAA,GAAAukG,kBAAA,WACAvkG,EAAAylG,aACAroC,KAEAp9D,GAAAulG,QAAAP,EAAAzhG,GACAiiG,OAcA3kG,GAAAJ,QAAAi8E,IAEA8B,SAAA,KAAAknB,IAAA,SAAAlqB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QACA,SAAA86E,EAAAkG,EAAA7C,GAIA,QAAA+mB,GAAA1sF,GACAzX,KAAAw1F,aAAA/9E,GAJA,GAAA2gF,GAAAre,EAAAqe,iBACApe,GAAA,UAKA7+D,SAAAgpF,EAAAlkB,GAEAkkB,EAAAlhG,UAAAmhG,iBAAA,SAAAxtD,EAAAytD,GAGA,MAFArkG,MAAAg2F,QAAAp/C,GAAAytD,IACArkG,KAAAk2F,gBACAl2F,KAAA0hF,UACA1hF,KAAAoZ,SAAApZ,KAAAg2F,UACA,IAKAmO,EAAAlhG,UAAAwxF,kBAAA,SAAAlzF,EAAAq1C,GACA,GAAArmB,GAAA,GAAA6nE,EAGA,OAFA7nE,GAAAstD,UAAA,SACAttD,EAAA+zE,mBAAA/iG,EACAvB,KAAAokG,iBAAAxtD,EAAArmB,IAEA4zE,EAAAlhG,UAAAyxF,iBAAA,SAAA/+E,EAAAihC,GACA,GAAArmB,GAAA,GAAA6nE,EAGA,OAFA7nE,GAAAstD,UAAA,SACAttD,EAAA+zE,mBAAA3uF,EACA3V,KAAAokG,iBAAAxtD,EAAArmB,IAGAwpD,EAAAwqB,OAAA,SAAAjpF,GAEA,MADA8hE,GAAA6J,WAAA,YAAA,cACA,GAAAkd,GAAA7oF,GAAAxP,WAGAiuE,EAAA92E,UAAAshG,OAAA,WACA,MAAAxqB,GAAAwqB,OAAAvkG,UAIAg9E,SAAA,KAAAwnB,IAAA,SAAAxqB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QACA,SAAA86E,EAAAkG,EAAAC,GAQA,QAAAhG,GAAAziE,GACAzX,KAAAw1F,aAAA/9E,GACAzX,KAAAykG,SAAA,EACAzkG,KAAA0kG,SAAA,EACA1kG,KAAA2kG,cAAA,EAiHA,QAAAC,GAAAtpF,EAAAupF,GACA,IAAA,EAAAA,KAAAA,GAAAA,EAAA,EACA,MAAA3kB,GAAA,iEAEA,IAAA3vD,GAAA,GAAA2pD,GAAA5+D,GACAxP,EAAAykB,EAAAzkB,SAGA,OAFAykB,GAAA4pD,WAAA0qB,GACAt0E,EAAAvT,OACAlR,EApIA,GAAA+1B,GAAAm4C,EAAA,UACAiW,EAAAjW,EAAA,YAAAiW,WACAD,EAAAhW,EAAA,YAAAgW,eACAzlD,EAAA1I,EAAA0I,QACAu6D,IASAjjE,GAAA1mB,SAAA++D,EAAA+F,GAEA/F,EAAAj3E,UAAA05D,MAAA,WACA,GAAA38D,KAAA2kG,aAAA,CAGA,GAAA,IAAA3kG,KAAAykG,SAEA,WADAzkG,MAAAoZ,YAGApZ,MAAA+1F,WAAA90F,IAAA,EACA,IAAA8jG,GAAAx6D,EAAAvqC,KAAAg2F,UACAh2F,KAAAk0F,eACA6Q,GACA/kG,KAAAykG,SAAAzkG,KAAAglG,uBACAhlG,KAAAiZ,QAAAjZ,KAAAilG,eAAAjlG,KAAAb,aAIA+6E,EAAAj3E,UAAA+Z,KAAA,WACAhd,KAAA2kG,cAAA,EACA3kG,KAAA28D,SAGAud,EAAAj3E,UAAAm3E,UAAA,WACAp6E,KAAA0kG,SAAA,GAGAxqB,EAAAj3E,UAAA4hG,QAAA,WACA,MAAA7kG,MAAAykG,UAGAvqB,EAAAj3E,UAAAk3E,WAAA,SAAAnsD,GACAhuB,KAAAykG,SAAAz2E,GAGAksD,EAAAj3E,UAAAwxF,kBAAA,SAAAlzF,GAEA,MADAvB,MAAAklG,cAAA3jG,GACAvB,KAAAmlG,eAAAnlG,KAAA6kG,YACA7kG,KAAAg2F,QAAA72F,OAAAa,KAAA6kG,UACA,IAAA7kG,KAAA6kG,WAAA7kG,KAAA0kG,QACA1kG,KAAAoZ,SAAApZ,KAAAg2F,QAAA,IAEAh2F,KAAAoZ,SAAApZ,KAAAg2F,UAEA,IAKA9b,EAAAj3E,UAAAyxF,iBAAA,SAAA/+E,GAEA,MADA3V,MAAAolG,aAAAzvF,GACA3V,KAAAqlG,iBAGAnrB,EAAAj3E,UAAAoxF,kBAAA,WACA,MAAAr0F,MAAAg2F,kBAAAjc,IAAA,MAAA/5E,KAAAg2F,QACAh2F,KAAAuhF,WAEAvhF,KAAAolG,aAAAN,GACA9kG,KAAAqlG,kBAGAnrB,EAAAj3E,UAAAoiG,cAAA,WACA,GAAArlG,KAAA6kG,UAAA7kG,KAAAglG,sBAAA,CAEA,IAAA,GADA7mG,GAAA,GAAA6xF,GACApxF,EAAAoB,KAAAb,SAAAP,EAAAoB,KAAAg2F,QAAA72F,SAAAP,EACAoB,KAAAg2F,QAAAp3F,KAAAkmG,GACA3mG,EAAAyY,KAAA5W,KAAAg2F,QAAAp3F,GAQA,OALAT,GAAAgB,OAAA,EACAa,KAAAiZ,QAAA9a,GAEA6B,KAAAuhF,WAEA,EAEA,OAAA,GAGArH,EAAAj3E,UAAAkiG,WAAA,WACA,MAAAnlG,MAAAk2F,gBAGAhc,EAAAj3E,UAAAqiG,UAAA,WACA,MAAAtlG,MAAAg2F,QAAA72F,OAAAa,KAAAb,UAGA+6E,EAAAj3E,UAAAmiG,aAAA,SAAAzvF,GACA3V,KAAAg2F,QAAAp/E,KAAAjB,IAGAukE,EAAAj3E,UAAAiiG,cAAA,SAAA3jG,GACAvB,KAAAg2F,QAAAh2F,KAAAk2F,kBAAA30F,GAGA24E,EAAAj3E,UAAA+hG,oBAAA,WACA,MAAAhlG,MAAAb,SAAAa,KAAAslG,aAGAprB,EAAAj3E,UAAAgiG,eAAA,SAAAj3E,GACA,GAAA4L,GAAA,qCACA55B,KAAAykG,SAAA,4BAAAz2E,EAAA,QACA,OAAA,IAAAiiE,GAAAr2D,IAGAsgD,EAAAj3E,UAAA26F,mBAAA,WACA59F,KAAAiZ,QAAAjZ,KAAAilG,eAAA,KAcAlrB,EAAA6qB,KAAA,SAAAtpF,EAAAupF,GACA,MAAAD,GAAAtpF,EAAAupF,IAGA9qB,EAAA92E,UAAA2hG,KAAA,SAAAC,GACA,MAAAD,GAAA5kG,KAAA6kG,IAGA9qB,EAAAM,kBAAAH,KAGA+T,WAAA,GAAAjR,SAAA,KAAAuoB,IAAA,SAAAvrB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,GACA,QAAAqe,GAAAtsF,OACA7K,KAAA6K,GACAA,EAAAA,EAAA3L,UACAH,KAAA69E,UAAA/xE,EAAA+xE,UACA79E,KAAAskG,mBAAAx4F,EAAAotF,gBACAptF,EAAA6+E,oBAAA1pF,KAGAjB,KAAA69E,UAAA,EACA79E,KAAAskG,uBAAArjG,IAIAm3F,EAAAn1F,UAAA0nF,cAAA,WACA,MAAA3qF,MAAAskG,mBAGA,IAAA/iG,GAAA62F,EAAAn1F,UAAA1B,MAAA,WACA,IAAAvB,KAAAqqE,cACA,KAAA,IAAA36B,WAAA,4FAEA,OAAA1vC,MAAA2qF,iBAGAh1E,EAAAyiF,EAAAn1F,UAAAyR,MACA0jF,EAAAn1F,UAAA0S,OAAA,WACA,IAAA3V,KAAAuyF,aACA,KAAA,IAAA7iD,WAAA,0FAEA,OAAA1vC,MAAA2qF,iBAGAtgB,EAAA+tB,EAAAn1F,UAAAonE,YAAA,WACA,MAAA,KAAA,SAAArqE,KAAA69E,YAGA0U,EAAA6F,EAAAn1F,UAAAsvF,WAAA,WACA,MAAA,KAAA,SAAAvyF,KAAA69E,YAGAgE,EAAAuW,EAAAn1F,UAAA4+E,UAAA,WACA,MAAA,KAAA,SAAA7hF,KAAA69E,YAGAmgB,EAAA5F,EAAAn1F,UAAA+6F,WAAA,WACA,MAAA,KAAA,SAAAh+F,KAAA69E,WAGAua,GAAAn1F,UAAA++E,YAAA,WACA,MAAA,KAAA,QAAAhiF,KAAA69E,YAGA9D,EAAA92E,UAAAuiG,cAAA,WACA,MAAA,SAAA,MAAAxlG,KAAA69E,YAGA9D,EAAA92E,UAAA6+E,aAAA,WACA,MAAA9hF,MAAAG,UAAAqlG,iBAGAzrB,EAAA92E,UAAA++E,YAAA,WACA,MAAA,KAAA,QAAAhiF,KAAAG,UAAA09E,YAGA9D,EAAA92E,UAAA4+E,UAAA,WACA,MAAAA,GAAA3iF,KAAAc,KAAAG,YAGA45E,EAAA92E,UAAAsvF,WAAA,WACA,MAAAA,GAAArzF,KAAAc,KAAAG,YAGA45E,EAAA92E,UAAAonE,YAAA,WACA,MAAAA,GAAAnrE,KAAAc,KAAAG,YAGA45E,EAAA92E,UAAA+6F,WAAA,WACA,MAAAA,GAAA9+F,KAAAc,KAAAG,YAGA45E,EAAA92E,UAAA1B,MAAA,WACA,MAAAA,GAAArC,KAAAc,KAAAG,YAGA45E,EAAA92E,UAAA0S,OAAA,WACA,GAAA9V,GAAAG,KAAAG,SAEA,OADAN,GAAAkrF,6BACAp1E,EAAAzW,KAAAW,IAGAk6E,EAAA92E,UAAA0rF,OAAA,WACA,MAAA3uF,MAAA2qF,iBAGA5Q,EAAA92E,UAAAurF,QAAA,WAEA,MADAxuF,MAAA+qF,6BACA/qF,KAAA2qF,iBAGA5Q,EAAAqe,kBAAAA,QAGAqN,IAAA,SAAAzrB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAmD,GAKA,QAAAC,GAAAvwC,EAAA8nB,GACA,GAAAsuB,EAAAp2C,GAAA,CACA,GAAAA,YAAAmtC,GAAA,MAAAntC,EACA,IAAAhpC,GAAA8hG,EAAA94D,EACA,IAAAhpC,IAAAw8E,EAAA,CACA1rB,GAAAA,EAAAkvB,cACA,IAAArzD,GAAAwpD,EAAA5gE,OAAAvV,EAAAzF,EAEA,OADAu2D,IAAAA,EAAAmvB,cACAtzD,EACA,GAAA,kBAAA3sB,GAAA,CACA,GAAA+hG,EAAA/4D,GAAA,CACA,GAAArc,GAAA,GAAAwpD,GAAAmD,EAQA,OAPAtwC,GAAA+wC,MACAptD,EAAA6jE,SACA7jE,EAAAtX,YACAhY,GACAsvB,EACA,MAEAA,EAEA,MAAAq1E,GAAAh5D,EAAAhpC,EAAA8wD,IAGA,MAAA9nB,GAGA,QAAAi5D,GAAAj5D,GACA,MAAAA,GAAAhpC,KAGA,QAAA8hG,GAAA94D,GACA,IACA,MAAAi5D,GAAAj5D,GACA,MAAAzuC,GAEA,MADAiiF,GAAAjiF,EAAAA,EACAiiF,GAKA,QAAAulB,GAAA/4D,GACA,IACA,MAAAk5D,GAAA5mG,KAAA0tC,EAAA,aACA,MAAAzuC,GACA,OAAA,GAIA,QAAAynG,GAAAr6B,EAAA3nE,EAAA8wD,GAeA,QAAA5gD,GAAAvS,GACAuK,IACAA,EAAAgyE,iBAAAv8E,GACAuK,EAAA,MAGA,QAAAqN,GAAAxD,GACA7J,IACAA,EAAA8oF,gBAAAj/E,EAAAmlF,GAAA,GACAhvF,EAAA,MAvBA,GAAAA,GAAA,GAAAiuE,GAAAmD,GACA3sD,EAAAzkB,CACA4oD,IAAAA,EAAAkvB,eACA93E,EAAAw/E,qBACA52B,GAAAA,EAAAmvB,aACA,IAAAiX,IAAA,EACAhuE,EAAA+U,EAAAs+C,SAAAv8E,GAAA1E,KAAAqsE,EAAAz3D,EAAAqF,EAmBA,OAlBA2hF,IAAA,EAEAhvF,GAAAghB,IAAAszD,IACAt0E,EAAA8oF,gBAAA9nE,EAAA3uB,GAAA,GAAA,GACA2N,EAAA,MAcAykB,EA/EA,GAAAsR,GAAAm4C,EAAA,UACAoG,EAAAv+C,EAAAu+C,SACA4C,EAAAnhD,EAAAmhD,SA0CA8iB,KAAAj0E,cAsCA,OAAAsrD,MAGAH,SAAA,KAAA+oB,IAAA,SAAA/rB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAmD,EAAAE,GAIA,QAAA4oB,GAAAC,GACAjmG,KAAAimG,OAAAA,EAqDA,QAAAC,GAAA3kG,GAEA,MADA2uB,cAAAlwB,KAAAimG,QACA1kG,EAGA,QAAA4kG,GAAAxwF,GAEA,KADAua,cAAAlwB,KAAAimG,QACAtwF,EAhEA,GAAAksB,GAAAm4C,EAAA,UACA+V,EAAAhW,EAAAgW,YAMAiW,GAAA/iG,UAAAo/E,iBAAA,WACAnyD,aAAAlwB,KAAAimG,QAGA,IAAAG,GAAA,SAAA7kG,GAAA,MAAAgmB,IAAAvnB,MAAAquF,WAAA9sF,IACAgmB,EAAAwyD,EAAAxyD,MAAA,SAAA8+E,EAAA9kG,GACA,GAAAgvB,GACA01E,CAgBA,YAfAhlG,KAAAM,GACAgvB,EAAAwpD,EAAAjmE,QAAAvS,GACAo8E,MAAAyoB,EAAA,KAAA,KAAAC,MAAAplG,IACAm8E,EAAAjqC,gBAAA5xC,YAAAw4E,IACAxpD,EAAA+tD,aAAA/8E,KAGAgvB,EAAA,GAAAwpD,GAAAmD,GACA+oB,EAAAjtF,WAAA,WAAAuX,EAAA6jE,aAAAiS,GACAjpB,EAAAjqC,gBACA5iB,EAAA+tD,aAAA,GAAA0nB,GAAAC,IAEA11E,EAAA+6D,sBAEA/6D,EAAA4oE,sBACA5oE,EAGAwpD,GAAA92E,UAAAskB,MAAA,SAAA8+E,GACA,MAAA9+E,GAAA8+E,EAAArmG,MAGA,IAAAsmG,GAAA,SAAAx6F,EAAA8tB,EAAAmnD,GACA,GAAAn/E,EAGAA,GAFA,gBAAAg4B,GACAA,YAAA96B,OACA86B,EAEA,GAAAm2D,GAAA,uBAGA,GAAAA,GAAAn2D,GAEAiI,EAAA80D,+BAAA/0F,GACAkK,EAAAs2E,kBAAAxgF,GACAkK,EAAAmN,QAAArX,GAEA,MAAAm/E,GACAA,EAAAR,SAcAxG,GAAA92E,UAAAshB,QAAA,SAAA8hF,EAAAzsE,GACAysE,GAAAA,CACA,IAAA91E,GAAAwwD,EAEAwlB,EAAA,GAAAP,GAAAhtF,WAAA,WACAuX,EAAAsxD,aACAykB,EAAA/1E,EAAAqJ,EAAAmnD,IAEAslB,GAYA,OAVAjpB,GAAAjqC,gBACA4tC,EAAA/gF,KAAA4D,OACA2sB,EAAAwwD,EAAApD,MAAAuoB,EAAAC,MACAllG,GAAAslG,MAAAtlG,IACAsvB,EAAA+tD,aAAAioB,IAEAh2E,EAAAvwB,KAAA29E,MAAAuoB,EAAAC,MACAllG,GAAAslG,MAAAtlG,IAGAsvB,MAKAysD,SAAA,KAAAwpB,IAAA,SAAAxsB,EAAA36E,EAAAJ,GACA,YACAI,GAAAJ,QAAA,SAAA86E,EAAAmG,EAAA/C,EACAqG,EAAAtG,EAAAE,GAQA,QAAAgR,GAAAjwF,GACA6a,WAAA,WAAA,KAAA7a,IAAA,GAGA,QAAAsoG,GAAAC,GACA,GAAAtoB,GAAAjB,EAAAupB,EAOA,OANAtoB,KAAAsoB,GACA,kBAAAA,GAAAC,eACA,kBAAAD,GAAAE,cACAF,EAAAC,iBACAvoB,EAAAyoB,eAAAH,EAAAE,gBAEAxoB,EAEA,QAAA0oB,GAAAC,EAAA1C,GAIA,QAAA2C,KACA,GAAApoG,GAAAitE,EAAA,MAAAt7C,GAAA6jE,UACA,IAAAhW,GAAAqoB,EAAAM,EAAAnoG,KACA,IAAAw/E,YAAArE,IACAqE,EAAAuoB,gBAAA,CACA,IACAvoB,EAAAjB,EACAiB,EAAAwoB,eAAAK,WAAA5C,GACA0C,EAAAj7F,SACA,MAAA3N,GACA,MAAAiwF,GAAAjwF,GAEA,GAAAigF,YAAArE,GACA,MAAAqE,GAAAT,MAAAqpB,EAAA5Y,EACA,KAAA,KAAA,MAGA4Y,IApBA,GAAApoG,GAAA,EACAitE,EAAAk7B,EAAA5nG,OACAoxB,EAAA,GAAAwpD,GAAAmD,EAqBA,OADA8pB,KACAz2E,EAGA,QAAA22E,GAAAjiG,EAAA6G,EAAA4oD,GACA10D,KAAAg/C,MAAA/5C,EACAjF,KAAAyzF,SAAA3nF,EACA9L,KAAA8c,SAAA43C,EAoCA,QAAAyyC,GAAAvrC,EAAA9vD,EAAA4oD,GACA10D,KAAAw1F,aAAA55B,EAAA9vD,EAAA4oD,GASA,QAAA0yC,GAAA7lG,GACA,MAAA2lG,GAAAG,WAAA9lG,IACAvB,KAAA+mG,UAAA/mG,KAAA42C,OAAAiwD,eAAAtlG,GACAA,EAAAuK,WAEAvK,EAGA,QAAA+lG,GAAAnoG,GACAa,KAAAb,OAAAA,EACAa,KAAA8L,QAAA,KACA9L,KAAAb,EAAA,GAAA,KA5GA,GAAA0iC,GAAAm4C,EAAA,UACAtqC,EAAAsqC,EAAA,YAAAtqC,UACAv0B,EAAA6+D,EAAA,UAAA7+D,SACAilE,EAAAv+C,EAAAu+C,SACAD,EAAAt+C,EAAAs+C,SACAonB,IAiDAL,GAAAjkG,UAAAgC,KAAA,WACA,MAAAjF,MAAAg/C,OAGAkoD,EAAAjkG,UAAA6I,QAAA,WACA,MAAA9L,MAAAyzF,UAGAyT,EAAAjkG,UAAAukG,SAAA,WACA,MAAAxnG,MAAA8L,UAAAu+D,cACArqE,KAAA8L,UAAAvK,QAEAgmG,GAGAL,EAAAjkG,UAAAgkG,WAAA,SAAA5C,GACA,GAAAmD,GAAAxnG,KAAAwnG,WACA9yC,EAAA10D,KAAA8c,aACA7b,KAAAyzD,GAAAA,EAAAkvB,cACA,IAAArzD,GAAAi3E,IAAAD,EACAvnG,KAAAynG,UAAAD,EAAAnD,GAAA,IAIA,YAHApjG,KAAAyzD,GAAAA,EAAAmvB,cACA7jF,KAAAyzF,SAAAiU,mBACA1nG,KAAAg/C,MAAA,KACAzuB,GAGA22E,EAAAG,WAAA,SAAA5wE,GACA,MAAA,OAAAA,GACA,kBAAAA,GAAA+wE,UACA,kBAAA/wE,GAAAwwE,YAMA9rF,EAAAgsF,EAAAD,GAEAC,EAAAlkG,UAAAwkG,UAAA,SAAAD,EAAAnD,GAEA,MADArkG,MAAAiF,OACA/F,KAAAsoG,EAAAA,EAAAnD,IAiBAiD,EAAArkG,UAAAo/E,iBAAA,WAEA,IAAA,GADAxW,GAAA7rE,KAAAb,OACAP,EAAA,EAAAA,EAAAitE,IAAAjtE,EAAA,CACA,GAAAkkF,GAAA9iF,KAAApB,EACAkkF,aAAA/I,IACA+I,EAAAvC,WAKAxG,EAAA4tB,MAAA,WACA,GAAA97B,GAAAxrE,UAAAlB,MACA,IAAA0sE,EAAA,EAAA,MAAAqU,GACA,sDACA,IAAAtkB,GAAAv7D,UAAAwrE,EAAA,EACA,IAAA,kBAAAjQ,GACA,MAAAskB,GAAA,gCAAAr+C,EAAAs9C,YAAAvjB,GAEA,IAAAgsC,GACAC,GAAA,CACA,KAAAh8B,GAAAtrE,MAAAgqC,QAAAlqC,UAAA,KACAunG,EAAAvnG,UAAA,GACAwrE,EAAA+7B,EAAAzoG,OACA0oG,GAAA,IAEAD,EAAAvnG,UACAwrE,IAGA,KAAA,GADAk7B,GAAA,GAAAO,GAAAz7B,GACAjtE,EAAA,EAAAA,EAAAitE,IAAAjtE,EAAA,CACA,GAAA4oG,GAAAI,EAAAhpG,EACA,IAAAsoG,EAAAG,WAAAG,GAAA,CACA,GAAAM,GAAAN,CACAA,GAAAA,EAAA17F,UACA07F,EAAAX,eAAAiB,OACA,CACA,GAAA1pB,GAAAjB,EAAAqqB,EACAppB,aAAArE,KACAytB,EACAppB,EAAAT,MAAAypB,EAAA,KAAA,MACAL,UAAAA,EACAnwD,MAAAh4C,OACAqC,KAGA8lG,EAAAnoG,GAAA4oG,EAIA,IAAA,GADAO,GAAA,GAAAxnG,OAAAwmG,EAAA5nG,QACAP,EAAA,EAAAA,EAAAmpG,EAAA5oG,SAAAP,EACAmpG,EAAAnpG,GAAAm7E,EAAAjmE,QAAAizF,EAAAnoG,IAAA25F,SAGA,IAAAyP,GAAAjuB,EAAAv+D,IAAAusF,GACAnkG,KAAA,SAAAqkG,GACA,IAAA,GAAArpG,GAAA,EAAAA,EAAAqpG,EAAA9oG,SAAAP,EAAA,CACA,GAAAylG,GAAA4D,EAAArpG,EACA,IAAAylG,EAAA9R,aAEA,MADAnS,GAAAjiF,EAAAkmG,EAAA3vF,QACA0rE,CACA,KAAAikB,EAAAh6B,cAEA,WADA29B,GAAAznB,QAGA0nB,GAAArpG,GAAAylG,EAAA9iG,QAEAuK,EAAA83E,eAEAhoB,EAAAukB,EAAAvkB,EACA,IAAArrC,GAAAs3E,EACAjsC,EAAAl7D,UAAAO,GAAAgnG,GAAArsC,EAAAqsC,GACA7hB,EAAAt6E,EAAA+3E,aAGA,OAFAzG,GAAA8I,sBACA31D,EAAA61D,EAAA,gBAAAt6E,GACAykB,IAGAzkB,EAAAk8F,EAAAvV,OAAA,WACA,GAAA4R,GAAA,GAAAtqB,GAAAqe,kBAAA4P,EACA,OAAAlB,GAAAC,EAAA1C,IAIA,OAFA0C,GAAAj7F,QAAAA,EACAA,EAAAwyE,aAAAyoB,GACAj7F,GAGAiuE,EAAA92E,UAAA4jG,eAAA,SAAAiB,GACA9nG,KAAA69E,UAAA,OAAA79E,KAAA69E,UACA79E,KAAAkoG,UAAAJ,GAGA/tB,EAAA92E,UAAA0jG,cAAA,WACA,OAAA,OAAA3mG,KAAA69E,WAAA,GAGA9D,EAAA92E,UAAA2jG,aAAA,WACA,MAAA5mG,MAAAkoG,WAGAnuB,EAAA92E,UAAAykG,iBAAA,WACA1nG,KAAA69E,WAAA,OAAA79E,KAAA69E,UACA79E,KAAAkoG,cAAAjnG,IAGA84E,EAAA92E,UAAA6kG,SAAA,SAAAlsC,GACA,GAAA,kBAAAA,GACA,MAAA,IAAAurC,GAAAvrC,EAAA57D,KAAAwjF,IAEA,MAAA,IAAA9zC,OAKAu+C,WAAA,GAAAjR,SAAA,KAAAmrB,IAAA,SAAAnuB,EAAA36E,EAAAJ,GACA,YAWA,SAAAmpG,KACA,IACA,GAAAvoG,GAAAwoG,CAEA,OADAA,GAAA,KACAxoG,EAAAa,MAAAV,KAAAK,WACA,MAAAlC,GAEA,MADAiiF,GAAAjiF,EAAAA,EACAiiF,GAGA,QAAAD,GAAAvkB,GAEA,MADAysC,GAAAzsC,EACAwsC,EAuBA,QAAAE,GAAAlgE,GACA,MAAA,OAAAA,IAAA,IAAAA,IAAA,IAAAA,GACA,gBAAAA,IAAA,gBAAAA,GAIA,QAAA46C,GAAAzhF,GACA,MAAA,kBAAAA,IACA,gBAAAA,IAAA,OAAAA,EAGA,QAAAw1F,GAAAwR,GACA,MAAAD,GAAAC,GAEA,GAAAzpG,OAAA0pG,EAAAD,IAFAA,EAKA,QAAAlJ,GAAAx/F,EAAA4oG,GACA,GAEA7pG,GAFAitE,EAAAhsE,EAAAV,OACAoxB,EAAA,GAAAhwB,OAAAsrE,EAAA,EAEA,KAAAjtE,EAAA,EAAAA,EAAAitE,IAAAjtE,EACA2xB,EAAA3xB,GAAAiB,EAAAjB,EAGA,OADA2xB,GAAA3xB,GAAA6pG,EACAl4E,EAGA,QAAAguE,GAAA3xD,EAAA5oB,EAAA0kF,GACA,IAAA/Y,EAAAc,MASA,SAAA5+D,eAAA3yB,KAAA0tC,EAAA5oB,GAAA4oB,EAAA5oB,OAAA/iB,EARA,IAAAqwF,GAAA9kD,OAAAmkD,yBAAA/jD,EAAA5oB,EAEA,OAAA,OAAAstE,EACA,MAAAA,EAAA3R,KAAA,MAAA2R,EAAAN,IACAM,EAAA/vF,MACAmnG,MAHA,GAUA,QAAAziB,GAAAr5C,EAAArrB,EAAAhgB,GACA,GAAA+mG,EAAA17D,GAAA,MAAAA,EACA,IAAA0rC,IACA/2E,MAAAA,EACAorE,cAAA,EACAjgC,YAAA,EACAggC,UAAA,EAGA,OADAijB,GAAAljD,eAAAG,EAAArrB,EAAA+2D,GACA1rC,EAGA,QAAAwhD,GAAA9vF,GACA,KAAAA,GAsEA,QAAAyhG,GAAAnkC,GACA,IACA,GAAA,kBAAAA,GAAA,CACA,GAAAt8C,GAAAqwE,EAAAiB,MAAAh1B,EAAA34D,WAEA0lG,EAAAhZ,EAAAc,OAAAnxE,EAAAngB,OAAA,EACAypG,EAAAtpF,EAAAngB,OAAA,KACA,IAAAmgB,EAAAngB,QAAA,gBAAAmgB,EAAA,IACAupF,EACAC,EAAAjiB,KAAAjrB,EAAA,KAAA+zB,EAAAiB,MAAAh1B,GAAAz8D,OAAA,CAEA,IAAAwpG,GAAAC,GACAC,EACA,OAAA,EAGA,OAAA,EACA,MAAA1qG,GACA,OAAA,GAIA,QAAAu9F,GAAA9uD,GAEA,QAAAm8D,MACAA,EAAA9lG,UAAA2pC,CAEA,KADA,GAAA5tC,GAAA,EACAA,KAAA,GAAA+pG,EACA,OAAAn8D,GAKA,QAAA8yC,GAAAmJ,GACA,MAAAmgB,GAAAniB,KAAAgC,GAGA,QAAAogB,GAAAj7E,EAAA1rB,EAAAuiE,GAEA,IAAA,GADAt0C,GAAA,GAAAhwB,OAAAytB,GACApvB,EAAA,EAAAA,EAAAovB,IAAApvB,EACA2xB,EAAA3xB,GAAA0D,EAAA1D,EAAAimE,CAEA,OAAAt0C,GAGA,QAAAi4E,GAAA57D,GACA,IACA,MAAAA,GAAA,GACA,MAAAzuC,GACA,MAAA,8BAIA,QAAA+qG,GAAAt8D,GACA,MAAAA,aAAA9tC,QACA,OAAA8tC,GACA,gBAAAA,IACA,gBAAAA,GAAAhT,SACA,gBAAAgT,GAAArrB,KAGA,QAAAo1E,GAAAx4F,GACA,IACA8nF,EAAA9nF,EAAA,iBAAA,GAEA,MAAAgrG,KAGA,QAAArQ,GAAA36F,GACA,MAAA,OAAAA,IACAA,YAAAW,OAAA,uBAAAywF,mBACA,IAAApxF,EAAA,eAGA,QAAAwnF,GAAA/4C,GACA,MAAAs8D,GAAAt8D,IAAA+iD,EAAAoB,mBAAAnkD,EAAA,SAkBA,QAAAuyC,GAAAvyC,GACA,SAAAnD,SAAAvqC,KAAA0tC,GAGA,QAAAkzD,GAAA1wF,EAAAC,EAAA8a,GAEA,IAAA,GADA7K,GAAAqwE,EAAAiB,MAAAxhF,GACAxQ,EAAA,EAAAA,EAAA0gB,EAAAngB,SAAAP,EAAA,CACA,GAAAolB,GAAA1E,EAAA1gB,EACA,IAAAurB,EAAAnG,GACA,IACA2rE,EAAAljD,eAAAp9B,EAAA2U,EAAA2rE,EAAAe,cAAAthF,EAAA4U,IACA,MAAAmlF,MAyCA,QAAAhf,GAAAnmE,GACA,MAAAolF,GAAAjtB,EAAAgO,IAAAnmE,OAAA/iB,GAGA,QAAA6hG,KACA,GAAA,kBAAA/oB,SACA,IACA,GAAAjuE,GAAA,GAAAiuE,SAAA,aACA,IAAA,wBAAAtwC,SAAAvqC,KAAA4M,GACA,MAAAiuE,SAEA,MAAA57E,KAIA,QAAA+sF,GAAA75E,EAAA+e,GACA,MAAA/e,GAAA5P,KAAA2uB,GA3UA,GAAAu/D,GAAA3V,EAAA,SACAyF,EAAA,mBAAA9J,WAEAyK,GAAAjiF,MACAkqG,EACAgB,EAAA,mBAAAh4F,MAAAA,KACA,mBAAAqkE,QAAAA,WACA,KAAAj2E,EAAAA,MACAwB,KAAAjB,KAAAA,KAAA,KAiBAmb,EAAA,SAAAmuF,EAAAC,GAGA,QAAAx9B,KACA/rE,KAAA4+C,YAAA0qD,EACAtpG,KAAAw1F,aAAA+T,CACA,KAAA,GAAA3pB,KAAA2pB,GAAAtmG,UACA6iG,EAAA5mG,KAAAqqG,EAAAtmG,UAAA28E,IACA,MAAAA,EAAAnvD,OAAAmvD,EAAAzgF,OAAA,KAEAa,KAAA4/E,EAAA,KAAA2pB,EAAAtmG,UAAA28E,IATA,GAAAkmB,MAAAj0E,cAeA,OAFAk6C,GAAA9oE,UAAAsmG,EAAAtmG,UACAqmG,EAAArmG,UAAA,GAAA8oE,GACAu9B,EAAArmG,WA8DA47F,EAAA,WACA,GAAA2K,IACAjpG,MAAA0C,UACAupC,OAAAvpC,UACAwmG,SAAAxmG,WAGAymG,EAAA,SAAAthE,GACA,IAAA,GAAAxpC,GAAA,EAAAA,EAAA4qG,EAAArqG,SAAAP,EACA,GAAA4qG,EAAA5qG,KAAAwpC,EACA,OAAA,CAGA,QAAA,EAGA,IAAAunD,EAAAc,MAAA,CACA,GAAAxN,GAAAz2C,OAAAqkD,mBACA,OAAA,UAAAjkD,GAGA,IAFA,GAAArc,MACAo5E,EAAAn9D,OAAA1U,OAAA,MACA,MAAA8U,IAAA88D,EAAA98D,IAAA,CACA,GAAAttB,EACA,KACAA,EAAA2jE,EAAAr2C,GACA,MAAAzuC,GACA,MAAAoyB,GAEA,IAAA,GAAA3xB,GAAA,EAAAA,EAAA0gB,EAAAngB,SAAAP,EAAA,CACA,GAAAolB,GAAA1E,EAAA1gB,EACA,KAAA+qG,EAAA3lF,GAAA,CACA2lF,EAAA3lF,IAAA,CACA,IAAAstE,GAAA9kD,OAAAmkD,yBAAA/jD,EAAA5oB,EACA,OAAAstE,GAAA,MAAAA,EAAA3R,KAAA,MAAA2R,EAAAN,KACAzgE,EAAA3Z,KAAAoN,IAGA4oB,EAAA+iD,EAAAmB,eAAAlkD,GAEA,MAAArc,IAGA,GAAAu1E,MAAAj0E,cACA,OAAA,UAAA+a,GACA,GAAA88D,EAAA98D,GAAA,QACA,IAAArc,KAGAq5E,GAAA,IAAA,GAAA5lF,KAAA4oB,GACA,GAAAk5D,EAAA5mG,KAAA0tC,EAAA5oB,GACAuM,EAAA3Z,KAAAoN,OACA,CACA,IAAA,GAAAplB,GAAA,EAAAA,EAAA4qG,EAAArqG,SAAAP,EACA,GAAAknG,EAAA5mG,KAAAsqG,EAAA5qG,GAAAolB,GACA,QAAA4lF,EAGAr5E,GAAA3Z,KAAAoN,GAGA,MAAAuM,OAMAu4E,EAAA,sBAiCAE,EAAA,wBA8CAhO,EAAA,WACA,MAAA,SAAA,IAAAl8F,OAOA,SAAAyC,GACA,MAAAokF,GAAApkF,GAAAA,EACA,GAAAzC,OAAA0pG,EAAAjnG,KARA,SAAAA,GACA,GAAAokF,EAAApkF,GAAA,MAAAA,EACA,KAAA,KAAA,IAAAzC,OAAA0pG,EAAAjnG,IACA,MAAAK,GAAA,MAAAA,QA0BA+7F,EAAA,SAAAnkD,GACA,MAAAm2C,GAAAplD,QAAAiP,GACAA,EAEA,KAGA,IAAA,mBAAAqwD,SAAAA,OAAA7C,SAAA,CACA,GAAA8C,GAAA,kBAAAvpG,OAAA6O,KAAA,SAAAoqC,GACA,MAAAj5C,OAAA6O,KAAAoqC,IACA,SAAAA,GAIA,IAHA,GAEAuwD,GAFAx5E,KACAy5E,EAAAxwD,EAAAqwD,OAAA7C,cAEA+C,EAAAC,EAAA3oG,QAAA,MACAkvB,EAAA3Z,KAAAmzF,EAAAxoG,MAEA,OAAAgvB,GAGAotE,GAAA,SAAAnkD,GACA,MAAAm2C,GAAAplD,QAAAiP,GACAA,EACA,MAAAA,GAAA,kBAAAA,GAAAqwD,OAAA7C,UACA8C,EAAAtwD,GAEA,MAIA,GAAA0iC,OAAA,KAAAC,GACA,qBAAAgD,EAAAhD,GAAA0P,cAEAud,MAAA,KAAAjtB,OACA,KAAAA,EAAAgO,IAqBA55D,GACAwvE,QAAAA,EACArgB,aAAAA,EACAmf,kBAAAA,EACAN,yBAAAA,EACAnQ,QAAAA,EACA7jD,QAAAolD,EAAAplD,QACAozD,QAAAA,EACA1X,kBAAAA,EACAqiB,YAAAA,EACAtlB,SAAAA,EACAkmB,QAAAA,EACAzpB,YAAAA,EACAW,SAAAA,EACAD,SAAAA,EACAhlE,SAAAA,EACAkkF,aAAAA,EACAtI,iBAAAA,EACA2E,iBAAAA,EACAuN,YAAAA,EACAx/D,SAAA++D,EACA7iB,eAAAA,EACAqV,kBAAAA,EACAlC,wBAAAA,EACAnC,+BAAAA,EACAxX,YAAAA,EACA2gB,gBAAAA,EACA/jB,YAAA,mBAAAkuB,SAAAA,QACA,kBAAAA,QAAAC,UACAhuB,OAAAA,EACAktB,gBAAAA,EACAjf,IAAAA,EACA1qF,OAAA4pG,EACAvG,iBAAAA,EACA5X,WAAAA,EAEA36D,GAAA6yE,aAAA7yE,EAAA2rD,QAAA,WACA,GAAAtL,GAAAuL,EAAAguB,SAAA7c,KAAAzxE,MAAA,KAAAsE,IAAAiqF,OACA,OAAA,KAAAx5B,EAAA,IAAAA,EAAA,GAAA,IAAAA,EAAA,GAAA,KAGArgD,EAAA2rD,QAAA3rD,EAAAmrE,iBAAAvf,EAEA,KAAA,KAAA,IAAAr9E,OAAA,MAAAX,GAAAoyB,EAAA+4D,cAAAnrF,EACAkB,EAAAJ,QAAAsxB,IAEA2yD,QAAA,UAAA,IAAA,KACA,mBAAAxN,SAAA,OAAAA,OAAAA,OAAA20B,EAAA30B,OAAAqE,QAAA,mBAAA1oE,OAAA,OAAAA,OAAAA,KAAAg5F,EAAAh5F,KAAA0oE,+KCv+KA,SAAAuwB,EAAAC,GACA,kBAAA1wB,SAAAA,OAAAC,IAEAD,UAAA0wB,GACA,gBAAAtrG,GAIAI,EAAAJ,QAAAsrG,IAGAD,EAAAE,cAAAD,KAEAvqG,KAAA,WAeA,QAAAT,GAAAsH,EAAAxC,GAEA,GAAA,kBAAAA,GACA,KAAA,IAAAvF,OAAA,uBAAAuF,EAEA,KAAAwC,EACA,KAAA,IAAA/H,OAAA,mBAEA,IAAA2rG,GAAA5jG,EAAA6jG,UAgBA,IAbA7jG,EADA,gBAAAA,IACA42C,IAAA52C,GAEAwxB,KAAArM,MAAAqM,KAAAwb,UAAAhtC,IAEAA,EAAA6jG,WAAAD,EAEA5jG,EAAA8jG,UAAAprG,EAAAiW,IAAAo1F,KAEA/jG,EAAA8T,MACA9T,EAAA42C,IAAA52C,EAAA8T,UACA9T,GAAA8T,MAGA9T,EAAA42C,KAAA,KAAA52C,EAAA42C,IACA,KAAA,IAAA3+C,OAAA,qCAEA,IAAA,gBAAA+H,GAAA42C,IACA,KAAA,IAAA3+C,OAAA,+BAGA,KAAA,GADA+rG,IAAA,QAAA,qBAAA,eAAA,kBACAjsG,EAAA,EAAAA,EAAAisG,EAAA1rG,OAAAP,IACA,GAAAiI,EAAAgkG,EAAAjsG,IACA,KAAA,IAAAE,OAAA,WAAA+rG,EAAAjsG,GAAA,oBAQA,IANAiI,EAAAxC,SAAAA,EACAwC,EAAAqP,OAAArP,EAAAqP,QAAA,MACArP,EAAAs0C,QAAAt0C,EAAAs0C,YACAt0C,EAAA7B,KAAA6B,EAAA7B,MAAA,KACA6B,EAAA0d,QAAA1d,EAAA0d,SAAAhlB,EAAAurG,gBAEAjkG,EAAAs0C,QAAAlvB,KACA,KAAA,IAAAntB,OAAA,wCAEA+H,GAAAuuC,OACAvuC,EAAAs0C,QAAA4vD,OAAAlkG,EAAAs0C,QAAA4vD,QAAA,mBACA,QAAAlkG,EAAAqP,SACArP,EAAAs0C,QAAA,gBAAA,oBAEA,iBAAAt0C,GAAAuuC,KACAvuC,EAAA7B,KAAAqzB,KAAAwb,UAAAhtC,EAAAuuC,MACA,gBAAAvuC,GAAA7B,OACA6B,EAAA7B,KAAAqzB,KAAAwb,UAAAhtC,EAAA7B,OAIA,IAAAgmG,GAAA,SAAAp+D,GACA,GAAAi8C,KACA,KAAA,GAAApd,KAAA7+B,GACAA,EAAA/a,eAAA45C,IACAod,EAAAjyE,KAAAsmC,mBAAAuuB,GAAA,IAAAvuB,mBAAAtQ,EAAA6+B,IAEA,OAAAod,GAAAzmD,KAAA,KAGA,IAAAv7B,EAAA+2C,GAAA,CACA,GAAAA,GAAA,gBAAA/2C,GAAA+2C,GAAA/2C,EAAA+2C,GAAAotD,EAAAnkG,EAAA+2C,KACA,IAAA/2C,EAAA42C,IAAApnC,QAAA,KACAxP,EAAA42C,IAAA52C,EAAA42C,IAAA,IAAAG,EAEA/2C,EAAA42C,IAAA52C,EAAA42C,IAAA,IAAAG,EA4BA,GAAA/2C,EAAAg3C,KAAA,CACA,GAAA,gBAAAh3C,GAAAg3C,KAAA,KAAA,uBACA,IAAA,SAAAh3C,EAAAqP,OAAA,CACA,GAAA+0F,IAAApkG,EAAAokG,UAAA,qCAAApf,aAEA,QADAhlF,EAAAs0C,QAAA,gBAAA8vD,EACAA,GACA,IAAA,oCACApkG,EAAA7B,KAAAgmG,EAAAnkG,EAAAg3C,MAAAliC,QAAA,OAAA,IACA,MACA,KAAA,sBACA,GAAAuvF,GAhCA,SAAAt+D,GAEA,GAAA9f,KACAA,GAAAq+E,QAAA,kCAAAlkF,KAAAyJ,MAAA,IAAAzJ,KAAA0J,SACA,IAAA0/D,KACA,KAAA,GAAA5kB,KAAA7+B,GACAA,EAAA/a,eAAA45C,IACA4kB,EAAAz5E,KACA,KAAAkW,EAAAq+E,QAAA,2CACA1/B,EAAA,QAEA7+B,EAAA6+B,GAAA,KAQA,OAJA4kB,GAAAz5E,KAAA,KAAAkW,EAAAq+E,QAAA,MACAr+E,EAAA9nB,KAAAqrF,EAAAjuD,KAAA,IACAtV,EAAA3tB,OAAA2tB,EAAA9nB,KAAA7F,OACA2tB,EAAAvnB,KAAA,iCAAAunB,EAAAq+E,QACAr+E,GAaAjmB,EAAAg3C,KAEAh3C,GAAA7B,KAAAkmG,EAAAlmG,KACA6B,EAAAs0C,QAAA,gBAAA+vD,EAAA3lG,IACA,MACA,SAAA,KAAA,IAAAzG,OAAA,wBAAAmsG,KAsBA,MAdApkG,GAAA6jG,WAAA7jG,EAAA6jG,YAAAU,GACA,IAAAvkG,EAAA6jG,aACA7jG,EAAA6jG,WAAArmG,EACAwC,EAAAxC,SAAA+mG,IAQAvkG,EAAAs0C,QAAAkwD,eAAAxkG,EAAA3C,OACA2C,EAAAs0C,QAAAkwD,cAAA,SAAAC,EAAAzkG,EAAA3C,KAAAR,SAAA,IAAAmD,EAAA3C,KAAAF,WAEAunG,EAAA1kG,GAIA,QAAA0kG,GAAA1kG,GAkBA,QAAA2kG,KACAC,GAAA,CACA,IAAAC,GAAA,GAAA5sG,OAAA,YAKA,OAJA4sG,GAAA3sG,KAAA,YACA2sG,EAAAC,SAAA9kG,EAAA0d,QAEAhlB,EAAAiW,IAAAd,MAAA,WAAAsrB,GAAAqc,EAAAuvD,IAAAC,aAAAhlG,EAAA0d,UACA1d,EAAAxC,SAAAqnG,EAAArvD,GAaA,QAAAyvD,GAAAl4F,GACA,GAAA63F,EACA,MAAAlsG,GAAAiW,IAAA4nE,MAAA,mCAAAlmE,MAAAmlC,EAAAM,WAAA3c,GAAAqc,EAAArc,IAIA,IAFAzgC,EAAAiW,IAAA4nE,MAAA,gBAAAlmE,MAAAmlC,EAAAM,WAAA3c,GAAAqc,EAAArc,GAAAyrE,UAAAA,IAEApvD,EAAAM,aAAAovD,EAAAC,OAAA,CACAzsG,EAAAiW,IAAA4nE,MAAA,mBAAAp9C,GAAAqc,EAAArc,IACA,KAAA,GAAAhc,KAAAnd,GAAAs0C,QACAkB,EAAAc,iBAAAn5B,EAAAnd,EAAAs0C,QAAAn3B,QAGAq4B,GAAAM,aAAAovD,EAAAE,iBACAC,IAEA7vD,EAAAM,aAAAovD,EAAAI,SACAD,IACAE,KAGA/vD,EAAAM,aAAAovD,EAAAnvD,OACAsvD,IACAE,IACAC,KAIA,QAAAH,KACA,IAAAI,EAAAzoG,SAAA,CASA,GANAyoG,EAAAzoG,UAAA,EACAtE,EAAAiW,IAAA4nE,MAAA,gBAAAp9C,GAAAqc,EAAArc,GAAAruB,OAAA0qC,EAAA1qC,SACAue,aAAAmsB,EAAAkwD,cACAlwD,EAAAtB,WAAAsB,EAAA1qC,OAGA66F,GAAA,GAAAnwD,EAAAtB,WAAA,CACA,GAAA0xD,GAAA,GAAA3tG,OAAA,0BAAA+H,EAAA42C,IAOA,OANAgvD,GAAA5wC,KAAA,WAGAywC,EAAAI,SAAA,EACAJ,EAAA1kF,KAAA,EAEA/gB,EAAAxC,SAAAooG,EAAApwD,GAGAx1C,EAAA6jG,WAAA,KAAAruD,IAGA,QAAA+vD,KACAE,EAAAI,UAGAJ,EAAAI,SAAA,EACAntG,EAAAiW,IAAA4nE,MAAA,yBAAAp9C,GAAAqc,EAAArc,MAIA,QAAAqsE,KACA,IAAAC,EAAA1kF,IAAA,CAOA,GAJA0kF,EAAA1kF,KAAA,EACAroB,EAAAiW,IAAA4nE,MAAA,gBAAAp9C,GAAAqc,EAAArc,KAEAqc,EAAAr3C,KAAAq3C,EAAAS,aACAj2C,EAAAuuC,KACA,IAAAiH,EAAAr3C,KAAAqzB,KAAArM,MAAAqwB,EAAAS,cACA,MAAA4uD,GAAA,MAAA7kG,GAAAxC,SAAAqnG,EAAArvD,GAGAx1C,EAAAxC,SAAA,KAAAg4C,EAAAA,EAAAr3C,OA9GA,GAAAq3C,GAAA,GAAA0vD,GACAN,GAAA,EACAe,EAAAG,EAAA9lG,EAAA42C,KACAmvD,EAAA,mBAAAvwD,EAOA,IALAwwD,GAAA,EACAxwD,EAAAywD,OAAAD,EACAxwD,EAAArc,GAAA6sE,EAAA,KAAAhmG,EAAAqP,OAAA,IAAArP,EAAA42C,IACApB,EAAAuvD,IAAAvvD,EAAArc,GAEAwsE,IAAAI,EAAA,CACA,GAAAH,GAAA,GAAA3tG,OAAA,kDAAA+H,EAAA42C,IAEA,OADAgvD,GAAA5wC,KAAA,cACAh1D,EAAAxC,SAAAooG,EAAApwD,GAGAA,EAAAkwD,aAAAvzF,WAAAwyF,EAAA3kG,EAAA0d,QAYA,IAAA+nF,IAAAzoG,UAAA,EAAA6oG,SAAA,EAAA9kF,KAAA,EAOA,OALAy0B,GAAAK,mBAAAovD,EACAzvD,EAAAzE,KAAA/wC,EAAAqP,OAAArP,EAAA42C,KAAA,GACA+uD,IACAnwD,EAAAqB,kBAAA72C,EAAA62C,iBACArB,EAAAe,KAAAv2C,EAAA7B,MACAq3C,EA2KA,QAAA+uD,MAEA,QAAAR,KACA,GAEAza,GAAAvxF,EAFAmuG,KACAC,GAAA,QAAA,QAAA,OAAA,OAAA,QAGA,KAAApuG,EAAA,EAAAA,EAAAouG,EAAA7tG,OAAAP,IACAuxF,EAAA6c,EAAApuG,GAEAmuG,EAAA5c,GAAAib,EACA,mBAAA32F,UAAAA,SAAAA,QAAA07E,KACA4c,EAAA5c,GAAA8c,EAAAx4F,QAAA07E,GAGA,OAAA4c,GAGA,QAAAE,GAAArgE,EAAA12B,GAGA,QAAAg3F,GAAArkB,EAAAn0B,GAIA,MAHA,gBAAAA,KACAm0B,GAAA,IAAAxwD,KAAAwb,UAAA6gB,IAEA9nB,EAAA12B,GAAAhX,KAAA0tC,EAAAi8C,GANA,MAAAqkB,GAWA,QAAAP,GAAAhyF,GACA,GAIAwyF,GAJAC,EAAA,gDAKA,KAAAD,EAAAE,SAAAC,KACA,MAAAnvG,GAEAgvG,EAAAvmC,SAAA68B,cAAA,KACA0J,EAAAG,KAAA,GACAH,EAAAA,EAAAG,KAGA,GAAAC,GAAAH,EAAAI,KAAAL,EAAAthB,mBACAxzB,EAAA+0C,EAAAI,KAAA7yF,EAAAkxE,cAWA,UARAxzB,GACAA,EAAA,IAAAk1C,EAAA,IACAl1C,EAAA,IAAAk1C,EAAA,KACAl1C,EAAA,KAAA,UAAAA,EAAA,GAAA,GAAA,QAAAk1C,EAAA,KAAA,UAAAA,EAAA,GAAA,GAAA,OASA,QAAAjC,GAAArmG,GAEA,GACAwoG,GAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EADAC,EAAA,oEACArvG,EAAA,EAAAsvG,EAAA,EAAAC,EAAA,GAAAC,IAEA,KAAAnpG,EACA,MAAAA,EAMA,IACAwoG,EAAAxoG,EAAAopG,WAAAzvG,KACA8uG,EAAAzoG,EAAAopG,WAAAzvG,KACA+uG,EAAA1oG,EAAAopG,WAAAzvG,KAEAovG,EAAAP,GAAA,GAAAC,GAAA,EAAAC,EAEAC,EAAAI,GAAA,GAAA,GACAH,EAAAG,GAAA,GAAA,GACAF,EAAAE,GAAA,EAAA,GACAD,EAAA,GAAAC,EAGAI,EAAAF,KAAAD,EAAAx9E,OAAAm9E,GAAAK,EAAAx9E,OAAAo9E,GAAAI,EAAAx9E,OAAAq9E,GAAAG,EAAAx9E,OAAAs9E,SACAnvG,EAAAqG,EAAA9F,OAIA,QAFAgvG,EAAAC,EAAAhsE,KAAA,IAEAn9B,EAAA9F,OAAA,GACA,IAAA,GACAgvG,EAAAA,EAAAr9E,MAAA,GAAA,GAAA,IACA,MACA,KAAA,GACAq9E,EAAAA,EAAAr9E,MAAA,GAAA,GAAA,IAIA,MAAAq9E,GAzcA,GAAApC,GAAAlwD,cACA,KAAAkwD,EAAA,KAAA,IAAAjtG,OAAA,yBACAS,GAAAiW,KACAuuE,MAAAqnB,EAAAhuB,MAAAguB,EAAAn/F,KAAAm/F,EAAAlwF,KAAAkwF,EAAA12F,MAAA02F,EAGA,IAgJAyB,GAAA,CAqTA,OAhMAttG,GAAAm+C,iBAAA,EACAn+C,EAAAurG,gBAtQA,KA4QAvrG,EAAA+uG,SAAA,SAAAznG,EAAA0nG,GACA,GAAArvC,GAAA,SAAAhpD,GAYA,MAXA,UAAA1R,EAAAH,GAEAG,EADA,gBAAAA,IACAi5C,IAAAj5C,GAEA6zB,KAAArM,MAAAqM,KAAAwb,UAAArvC,GAEA,KAAA,GAAA5F,KAAAiI,OACA5F,KAAAuD,EAAA5F,KAAA4F,EAAA5F,GAAAiI,EAAAjI,GAEA,OAAAsX,GAAA1R,EAAAH,KAIAmqG,EAAAtvC,EAAA3/D,EAKA,OAJAivG,GAAA7uB,IAAAzgB,EAAA3/D,EAAAogF,KACA6uB,EAAAC,KAAAvvC,EAAA3/D,EAAAkvG,MACAD,EAAAzwC,IAAAmB,EAAA3/D,EAAAw+D,KACAywC,EAAAE,KAAAxvC,EAAA3/D,EAAAmvG,MACAF,IAOA,MAAA,MAAA,OAAA,QACA//F,QAAA,SAAAkgG,GACA,GAAAz4F,GAAAy4F,EAAA72B,aAGAv4E,GAFAovG,EAAA9iB,eAEA,SAAA9pF,GACA,gBAAAA,GACAA,GAAAmU,OAAAA,EAAAunC,IAAA17C,IAEAA,EAAAs2B,KAAArM,MAAAqM,KAAAwb,UAAA9xC,IACAA,EAAAmU,OAAAA,EAGA,IAAA5V,IAAAyB,GAAApB,OAAAJ,MAAA0C,UAAA6tB,MAAApwB,MAAAL,WAAA,IACA,OAAAd,GAAAmB,MAAAV,KAAAM,MAQAf,EAAAqvG,MAAA,SAAA/nG,EAAAxC,GAeA,QAAAwqG,GAAAnD,EAAA7uD,EAAA73C,GACA,GAAA0mG,EACA,MAAArnG,GAAAqnG,EAAA7uD,EAAA73C,EAEA,KAAA63C,EAAA9B,WAAA,KAAA8B,EAAA9B,WAAA,MAAA/1C,EAAA0P,MAAA,CAEAg3F,EAAA,GAAA5sG,OAAA,mBAAAkG,EAAA0P,MAAAiB,QAAA3Q,EAAA0P,MAAAA,OACA,KAAA,GAAAsP,KAAAhf,GACA0mG,EAAA1nF,GAAAhf,EAAAgf,EACA,OAAA3f,GAAAqnG,EAAA7uD,EAAA73C,GAGA,MAAAX,GAAAqnG,EAAA7uD,EAAA73C,GAdA,MAZA,gBAAA6B,KACAA,GAAA42C,IAAA52C,IAGAA,EAAAuuC,MAAA,EACAvuC,EAAA7B,OACA6B,EAAAuuC,KAAAvuC,EAAA7B,YACA6B,GAAA7B,KAEAX,EAAAA,GAAA+mG,EAEA7rG,EAAAsH,EAAAgoG,IA4HAtvG,6BCpeA,YA0DA,SAAA2jB,GAAA0pB,GACA,IAAAA,GAAA,gBAAAA,GACA,KAAA,IAAA8C,WAAA,2BAGA,IAAAo/D,GAAAliE,EAAAkiE,WACAvpG,EAAAqnC,EAAArnC,IAEA,KAAAA,IAAAwpG,EAAAloB,KAAAthF,GACA,KAAA,IAAAmqC,WAAA,eAGA,IAAAimB,GAAApwD,CAGA,IAAAupG,GAAA,gBAAAA,GAIA,IAAA,GAHAE,GACAxqG,EAAAgoC,OAAAltB,KAAAwvF,GAAAnzE,OAEA/8B,EAAA,EAAAA,EAAA4F,EAAArF,OAAAP,IAAA,CAGA,GAFAowG,EAAAxqG,EAAA5F,IAEAqwG,EAAApoB,KAAAmoB,GACA,KAAA,IAAAt/D,WAAA,yBAGAimB,IAAA,KAAAq5C,EAAA,IAAAE,EAAAJ,EAAAE,IAIA,MAAAr5C,GAWA,QAAA3pC,GAAA2pC,GACA,IAAAA,EACA,KAAA,IAAAjmB,WAAA,8BAIA,IAAAy/D,GAAA,gBAAAx5C,GACAy5C,EAAAz5C,GACAA,CAEA,IAAA,gBAAAw5C,GACA,KAAA,IAAAz/D,WAAA,6CAGA,IAAAkH,GAAAu4D,EAAA94F,QAAA,KACA9Q,GAAA,IAAAqxC,EACAu4D,EAAAr+F,OAAA,EAAA8lC,GAAAy4D,OACAF,EAAAE,MAEA,KAAAN,EAAAloB,KAAAthF,GACA,KAAA,IAAAmqC,WAAA,qBAGA,IAAA9C,GAAA,GAAA0iE,GAAA/pG,EAAAsmF,cAGA,KAAA,IAAAj1C,EAAA,CACA,GAAA5yB,GACAuzC,EACAh2D,CAIA,KAFAguG,EAAAj4B,UAAA1gC,EAEA2gB,EAAAg4C,EAAA/B,KAAA2B,IAAA,CACA,GAAA53C,EAAA3gB,QAAAA,EACA,KAAA,IAAAlH,WAAA,2BAGAkH,IAAA2gB,EAAA,GAAAp4D,OACA6kB,EAAAuzC,EAAA,GAAAs0B,cACAtqF,EAAAg2D,EAAA,GAEA,MAAAh2D,EAAA,KAEAA,EAAAA,EACAuP,OAAA,EAAAvP,EAAApC,OAAA,GACAwc,QAAA6zF,EAAA,OAGA5iE,EAAAkiE,WAAA9qF,GAAAziB,EAGA,GAAAq1C,IAAAu4D,EAAAhwG,OACA,KAAA,IAAAuwC,WAAA,4BAIA,MAAA9C,GAWA,QAAAwiE,GAAAxiE,GACA,GAAAuiE,EAUA,IARA,kBAAAviE,GAAA6iE,UAEAN,EAAAviE,EAAA6iE,UAAA,gBACA,gBAAA7iE,GAAAuO,UAEAg0D,EAAAviE,EAAAuO,SAAAvO,EAAAuO,QAAA,iBAGA,gBAAAg0D,GACA,KAAA,IAAAz/D,WAAA,6CAGA,OAAAy/D,GAWA,QAAAD,GAAA9mE,GACA,GAAAygD,GAAAjR,OAAAxvC,EAGA,IAAA6mE,EAAApoB,KAAAgC,GACA,MAAAA,EAGA,IAAAA,EAAA1pF,OAAA,IAAAuwG,EAAA7oB,KAAAgC,GACA,KAAA,IAAAn5C,WAAA,0BAGA,OAAA,IAAAm5C,EAAAltE,QAAAg0F,EAAA,QAAA,IAOA,QAAAL,GAAA/pG,GACAvF,KAAA8uG,WAAAtiE,OAAA1U,OAAA,MACA93B,KAAAuF,KAAAA,EAtMA,GAAAgqG,GAAA,mKACAG,EAAA,wCACAT,EAAA,gCAQAO,EAAA,6BAKAG,EAAA,WASAZ,EAAA,4DAOA9vG,GAAAikB,OAAAA,EACAjkB,EAAA+sB,MAAAA,2BCtDArtB,EAAA,+BACAA,EAAA,kCACAU,EAAAJ,QAAAN,EAAA,kKCFAA,EAAA,+BACAA,EAAA,kCACAU,EAAAJ,QAAAN,EAAA,gKCFA,GAAAixG,GAAAjxG,EAAA,uBACAkxG,EAAAD,EAAAv3E,OAAAu3E,EAAAv3E,MAAAwb,UAAAxb,KAAAwb,WACAx0C,GAAAJ,QAAA,SAAA+qG,GACA,MAAA6F,GAAAh8D,UAAAnzC,MAAAmvG,EAAAxvG,6DCHA1B,EAAA,mCACAU,EAAAJ,QAAAN,EAAA,uBAAA6tC,OAAAsjE,8FCDAnxG,EAAA,kCACA,IAAAoxG,GAAApxG,EAAA,uBAAA6tC,MACAntC,GAAAJ,QAAA,SAAAorG,EAAA2F,GACA,MAAAD,GAAAj4E,OAAAuyE,EAAA2F,2FCHArxG,EAAA,2CACA,IAAAoxG,GAAApxG,EAAA,uBAAA6tC,MACAntC,GAAAJ,QAAA,SAAA+qG,EAAAhmF,EAAAstE,GACA,MAAAye,GAAAtjE,eAAAu9D,EAAAhmF,EAAAstE,oGCHA3yF,EAAA,6CACAU,EAAAJ,QAAAN,EAAA,uBAAA6tC,OAAAskD,gHCDAnyF,EAAA,iCACAU,EAAAJ,QAAAN,EAAA,uBAAA6tC,OAAAltB,0FCDA3gB,EAAA,6CACAU,EAAAJ,QAAAN,EAAA,uBAAA6tC,OAAAyjE,gHCDAtxG,EAAA,mCACAA,EAAA,kCACAA,EAAA,+BACAA,EAAA,sBACAA,EAAA,8BACAA,EAAA,yBACAA,EAAA,2BACAU,EAAAJ,QAAAN,EAAA,oBAAAuxG,mRCPAvxG,EAAA,4BACAA,EAAA,sCACAA,EAAA,2CACAA,EAAA,uCACAU,EAAAJ,QAAAN,EAAA,uBAAAkrG,wNCJAlrG,EAAA,qCACAA,EAAA,kCACAU,EAAAJ,QAAAN,EAAA,0BAAAE,EAAA,8ICFAQ,EAAAJ,QAAA,SAAA+qG,GACA,GAAA,kBAAAA,GAAA,KAAAt6D,WAAAs6D,EAAA,sBACA,OAAAA,6BCFA3qG,EAAAJ,QAAA,sCCAAI,EAAAJ,QAAA,SAAA+qG,EAAA/xB,EAAA12D,EAAA4uF,GACA,KAAAnG,YAAA/xB,SAAAh3E,KAAAkvG,GAAAA,IAAAnG,GACA,KAAAt6D,WAAAnuB,EAAA,0BACA,OAAAyoF,6BCHA,GAAAhnB,GAAArkF,EAAA,eACAU,GAAAJ,QAAA,SAAA+qG,GACA,IAAAhnB,EAAAgnB,GAAA,KAAAt6D,WAAAs6D,EAAA,qBACA,OAAAA,+CCHA,GAAAoG,GAAAzxG,EAAA,YAEAU,GAAAJ,QAAA,SAAAoxG,EAAAC,GACA,GAAAxjF,KAEA,OADAsjF,GAAAC,GAAA,EAAAvjF,EAAAlW,KAAAkW,EAAAwjF,GACAxjF,2CCHA,GAAAyjF,GAAA5xG,EAAA,iBACA6xG,EAAA7xG,EAAA,gBACA8xG,EAAA9xG,EAAA,uBACAU,GAAAJ,QAAA,SAAAyxG,GACA,MAAA,UAAAC,EAAAl2C,EAAAm2C,GACA,GAGArvG,GAHAyqE,EAAAukC,EAAAI,GACAxxG,EAAAqxG,EAAAxkC,EAAA7sE,QACAy3C,EAAA65D,EAAAG,EAAAzxG,EAIA,IAAAuxG,GAAAj2C,GAAAA,GAAA,KAAAt7D,EAAAy3C,GAGA,IAFAr1C,EAAAyqE,EAAAp1B,OAEAr1C,EAAA,OAAA,MAEA,MAAApC,EAAAy3C,EAAAA,IAAA,IAAA85D,GAAA95D,IAAAo1B,KACAA,EAAAp1B,KAAA6jB,EAAA,MAAAi2C,IAAA95D,GAAA,CACA,QAAA85D,IAAA,8FCbA,GAAAnsB,GAAA5lF,EAAA,UACAkyG,EAAAlyG,EAAA,cACAmyG,EAAAnyG,EAAA,gBACA6xG,EAAA7xG,EAAA,gBACAoyG,EAAApyG,EAAA,0BACAU,GAAAJ,QAAA,SAAA+xG,EAAAC,GACA,GAAAC,GAAA,GAAAF,EACAG,EAAA,GAAAH,EACAI,EAAA,GAAAJ,EACAK,EAAA,GAAAL,EACAM,EAAA,GAAAN,EACAO,EAAA,GAAAP,GAAAM,EACAx5E,EAAAm5E,GAAAF,CACA,OAAA,UAAAJ,EAAAa,EAAAC,GAQA,IAPA,GAMArpE,GAAA/zB,EANA23D,EAAA8kC,EAAAH,GACAt/F,EAAAw/F,EAAA7kC,GACAntE,EAAA0lF,EAAAitB,EAAAC,EAAA,GACAtyG,EAAAqxG,EAAAn/F,EAAAlS,QACAy3C,EAAA,EACA9pB,EAAAokF,EAAAp5E,EAAA64E,EAAAxxG,GAAAgyG,EAAAr5E,EAAA64E,EAAA,OAAA1vG,GAEA9B,EAAAy3C,EAAAA,IAAA,IAAA26D,GAAA36D,IAAAvlC,MACA+2B,EAAA/2B,EAAAulC;kHACAviC,EAAAxV,EAAAupC,EAAAwO,EAAAo1B,GACAglC,GACA,GAAAE,EAAApkF,EAAA8pB,GAAAviC,MACA,IAAAA,EAAA,OAAA28F,GACA,IAAA,GAAA,OAAA,CACA,KAAA,GAAA,MAAA5oE,EACA,KAAA,GAAA,MAAAwO,EACA,KAAA,GAAA9pB,EAAAlW,KAAAwxB,OACA,IAAAipE,EAAA,OAAA,CAGA,OAAAC,IAAA,EAAAF,GAAAC,EAAAA,EAAAvkF,6HCzCA,GAAAk2D,GAAArkF,EAAA,gBACA4rC,EAAA5rC,EAAA,eACA+yG,EAAA/yG,EAAA,UAAA,UAEAU,GAAAJ,QAAA,SAAA0yG,GACA,GAAAC,EASA,OARArnE,GAAAonE,KACAC,EAAAD,EAAA/yD,YAEA,kBAAAgzD,IAAAA,IAAArxG,QAAAgqC,EAAAqnE,EAAA3uG,aAAA2uG,MAAA3wG,IACA+hF,EAAA4uB,IAEA,QADAA,EAAAA,EAAAF,MACAE,MAAA3wG,SAEAA,KAAA2wG,EAAArxG,MAAAqxG,6ECbA,GAAAC,GAAAlzG,EAAA,+BAEAU,GAAAJ,QAAA,SAAA0yG,EAAAxyG,GACA,MAAA,KAAA0yG,EAAAF,IAAAxyG,8DCHA,GAAA2yG,GAAAnzG,EAAA,UACAozG,EAAApzG,EAAA,UAAA,eAEAqzG,EAAA,aAAAF,EAAA,WAAA,MAAAzxG,eAGA4xG,EAAA,SAAAjI,EAAAhmF,GACA,IACA,MAAAgmF,GAAAhmF,GACA,MAAA7lB,KAGAkB,GAAAJ,QAAA,SAAA+qG,GACA,GAAAh+B,GAAAD,EAAAmmC,CACA,YAAAjxG,KAAA+oG,EAAA,YAAA,OAAAA,EAAA,OAEA,iBAAAj+B,EAAAkmC,EAAAjmC,EAAAx/B,OAAAw9D,GAAA+H,IAAAhmC,EAEAimC,EAAAF,EAAA9lC,GAEA,WAAAkmC,EAAAJ,EAAA9lC,KAAA,kBAAAA,GAAAmmC,OAAA,YAAAD,oDCrBA,GAAAzoE,MAAAA,QAEApqC,GAAAJ,QAAA,SAAA+qG,GACA,MAAAvgE,GAAAvqC,KAAA8qG,GAAAl5E,MAAA,GAAA,6BCHA,YACA,IAAAshF,GAAAzzG,EAAA,gBAAAE,EACAi5B,EAAAn5B,EAAA,oBACA0zG,EAAA1zG,EAAA,mBACA4lF,EAAA5lF,EAAA,UACA2zG,EAAA3zG,EAAA,kBACAyxG,EAAAzxG,EAAA,aACA4zG,EAAA5zG,EAAA,kBACA6zG,EAAA7zG,EAAA,gBACA8zG,EAAA9zG,EAAA,kBACA+zG,EAAA/zG,EAAA,kBACAg0G,EAAAh0G,EAAA,WAAAg0G,QACAC,EAAAj0G,EAAA,0BACAk0G,EAAAH,EAAA,KAAA,OAEAI,EAAA,SAAArB,EAAAztF,GAEA,GACA+uF,GADAn8D,EAAA+7D,EAAA3uF,EAEA,IAAA,MAAA4yB,EAAA,MAAA66D,GAAAp4C,GAAAziB,EAEA,KAAAm8D,EAAAtB,EAAAuB,GAAAD,EAAAA,EAAAA,EAAA10G,EACA,GAAA00G,EAAA1tE,GAAArhB,EAAA,MAAA+uF,GAIA1zG,GAAAJ,SACAg0G,eAAA,SAAA/vD,EAAAgwD,EAAAhC,EAAAiC,GACA,GAAAvB,GAAA1uD,EAAA,SAAAuuD,EAAA2B,GACAd,EAAAb,EAAAG,EAAAsB,EAAA,MACAzB,EAAA4B,GAAAH,EACAzB,EAAAp4C,GAAAvhC,EAAA,MACA25E,EAAAuB,OAAA/xG,GACAwwG,EAAA6B,OAAAryG,GACAwwG,EAAAoB,GAAA,MACA5xG,IAAAmyG,GAAAhD,EAAAgD,EAAAlC,EAAAO,EAAA0B,GAAA1B,IAsDA,OApDAY,GAAAT,EAAA3uG,WAGAswG,MAAA,WACA,IAAA,GAAA9B,GAAAmB,EAAA5yG,KAAAkzG,GAAAjuG,EAAAwsG,EAAAp4C,GAAA05C,EAAAtB,EAAAuB,GAAAD,EAAAA,EAAAA,EAAA10G,EACA00G,EAAAz0G,GAAA,EACAy0G,EAAAtnC,IAAAsnC,EAAAtnC,EAAAsnC,EAAAtnC,EAAAptE,MAAA4C,UACAgE,GAAA8tG,EAAAn0G,EAEA6yG,GAAAuB,GAAAvB,EAAA6B,OAAAryG,GACAwwG,EAAAoB,GAAA,GAIA3oE,OAAA,SAAAlmB,GACA,GAAAytF,GAAAmB,EAAA5yG,KAAAkzG,GACAH,EAAAD,EAAArB,EAAAztF,EACA,IAAA+uF,EAAA,CACA,GAAA1xG,GAAA0xG,EAAA10G,EACA8b,EAAA44F,EAAAtnC,QACAgmC,GAAAp4C,GAAA05C,EAAAn0G,GACAm0G,EAAAz0G,GAAA,EACA6b,IAAAA,EAAA9b,EAAAgD,GACAA,IAAAA,EAAAoqE,EAAAtxD,GACAs3F,EAAAuB,IAAAD,IAAAtB,EAAAuB,GAAA3xG,GACAowG,EAAA6B,IAAAP,IAAAtB,EAAA6B,GAAAn5F,GACAs3F,EAAAoB,KACA,QAAAE,GAIAtkG,QAAA,SAAA+iG,GACAoB,EAAA5yG,KAAAkzG,EAGA,KAFA,GACAH,GADAl0G,EAAA0lF,EAAAitB,EAAAnxG,UAAAlB,OAAA,EAAAkB,UAAA,OAAAY,GAAA,GAEA8xG,EAAAA,EAAAA,EAAA10G,EAAA2B,KAAAgzG,IAGA,IAFAn0G,EAAAk0G,EAAAv5D,EAAAu5D,EAAA1tE,EAAArlC,MAEA+yG,GAAAA,EAAAz0G,GAAAy0G,EAAAA,EAAAtnC,GAKAwlB,IAAA,SAAAjtE,GACA,QAAA8uF,EAAAF,EAAA5yG,KAAAkzG,GAAAlvF,MAGA0uF,GAAAN,EAAAR,EAAA3uG,UAAA,QACA08E,IAAA,WACA,MAAAizB,GAAA5yG,KAAAkzG,GAAAL,MAGAjB,GAEA1yC,IAAA,SAAAuyC,EAAAztF,EAAAziB,GACA,GACA4Y,GAAAy8B,EADAm8D,EAAAD,EAAArB,EAAAztF,EAoBA,OAjBA+uF,GACAA,EAAAv5D,EAAAj4C,GAGAkwG,EAAA6B,GAAAP,GACAn0G,EAAAg4C,EAAA+7D,EAAA3uF,GAAA,GACAqhB,EAAArhB,EACAw1B,EAAAj4C,EACAkqE,EAAAtxD,EAAAs3F,EAAA6B,GACAj1G,MAAA4C,GACA3C,GAAA,GAEAmzG,EAAAuB,KAAAvB,EAAAuB,GAAAD,GACA54F,IAAAA,EAAA9b,EAAA00G,GACAtB,EAAAoB,KAEA,MAAAj8D,IAAA66D,EAAAp4C,GAAAziB,GAAAm8D,IACAtB,GAEAqB,SAAAA,EACAU,UAAA,SAAA5B,EAAAsB,EAAAhC,GAGAqB,EAAAX,EAAAsB,EAAA,SAAAO,EAAAvuG,GACAlF,KAAAqzG,GAAAT,EAAAa,EAAAP,GACAlzG,KAAA0zG,GAAAxuG,EACAlF,KAAAszG,OAAAryG,IACA,WAKA,IAJA,GAAAwwG,GAAAzxG,KACAkF,EAAAusG,EAAAiC,GACAX,EAAAtB,EAAA6B,GAEAP,GAAAA,EAAAz0G,GAAAy0G,EAAAA,EAAAtnC,CAEA,OAAAgmC,GAAA4B,KAAA5B,EAAA6B,GAAAP,EAAAA,EAAAA,EAAA10G,EAAAozG,EAAA4B,GAAAL,IAMA,QAAA9tG,EAAAstG,EAAA,EAAAO,EAAA1tE,GACA,UAAAngC,EAAAstG,EAAA,EAAAO,EAAAv5D,GACAg5D,EAAA,GAAAO,EAAA1tE,EAAA0tE,EAAAv5D,KANAi4D,EAAA4B,OAAApyG,GACAuxG,EAAA,KAMAtB,EAAA,UAAA,UAAAA,GAAA,GAGAuB,EAAAS,2QC5IA,GAAAS,GAAAh1G,EAAA,cACAyQ,EAAAzQ,EAAA,yBACAU,GAAAJ,QAAA,SAAAi0G,GACA,MAAA,YACA,GAAAS,EAAA3zG,OAAAkzG,EAAA,KAAAxjE,WAAAwjE,EAAA,wBACA,OAAA9jG,GAAApP,4ECNA,YACA,IAAAP,GAAAd,EAAA,aACAi1G,EAAAj1G,EAAA,aACAk1G,EAAAl1G,EAAA,WACAm1G,EAAAn1G,EAAA,YACAo1G,EAAAp1G,EAAA,WACA0zG,EAAA1zG,EAAA,mBACAyxG,EAAAzxG,EAAA,aACA2zG,EAAA3zG,EAAA,kBACAqkF,EAAArkF,EAAA,gBACAq1G,EAAAr1G,EAAA,wBACAyzG,EAAAzzG,EAAA,gBAAAE,EACAowF,EAAAtwF,EAAA,oBAAA,GACA+zG,EAAA/zG,EAAA,iBAEAU,GAAAJ,QAAA,SAAAi0G,EAAAhwD,EAAAgtC,EAAA+jB,EAAA/C,EAAAgD,GACA,GAAAC,GAAA10G,EAAAyzG,GACAtB,EAAAuC,EACAhB,EAAAjC,EAAA,MAAA,MACAhgB,EAAA0gB,GAAAA,EAAA3uG,UACA+oE,IAqCA,OApCA0mC,IAAA,kBAAAd,KAAAsC,GAAAhjB,EAAAziF,UAAAqlG,EAAA,YACA,GAAAlC,IAAA1R,UAAA7+F,WAOAuwG,EAAA1uD,EAAA,SAAArjD,EAAAuzG,GACAd,EAAAzyG,EAAA+xG,EAAAsB,EAAA,MACArzG,EAAAu0G,GAAA,GAAAD,OACAlzG,IAAAmyG,GAAAhD,EAAAgD,EAAAlC,EAAArxG,EAAAszG,GAAAtzG,KAEAovF,EAAA,kEAAApzE,MAAA,KAAA,SAAAw4F,GACA,GAAAC,GAAA,OAAAD,GAAA,OAAAA,CACAA,KAAAnjB,MAAAgjB,GAAA,SAAAG,IAAAN,EAAAnC,EAAA3uG,UAAAoxG,EAAA,SAAA31G,EAAAmlD,GAEA,GADAyuD,EAAAtyG,KAAA4xG,EAAAyC,IACAC,GAAAJ,IAAAlxB,EAAAtkF,GAAA,MAAA,OAAA21G,OAAApzG,EACA,IAAA6rB,GAAA9sB,KAAAo0G,GAAAC,GAAA,IAAA31G,EAAA,EAAAA,EAAAmlD,EACA,OAAAywD,GAAAt0G,KAAA8sB,MAGAonF,GAAA9B,EAAAR,EAAA3uG,UAAA,QACA08E,IAAA,WACA,MAAA3/E,MAAAo0G,GAAAjqE,UApBAynE,EAAAqC,EAAAhB,eAAA/vD,EAAAgwD,EAAAhC,EAAAiC,GACAd,EAAAT,EAAA3uG,UAAAitF,GACA2jB,EAAAU,MAAA,GAuBAP,EAAApC,EAAAsB,GAEAlnC,EAAAknC,GAAAtB,EACAgC,EAAAA,EAAAY,EAAAZ,EAAAa,EAAAb,EAAAc,EAAA1oC,GAEAkoC,GAAAD,EAAAT,UAAA5B,EAAAsB,EAAAhC,GAEAU,4QCzDA,GAAAhC,GAAAvwG,EAAAJ,SAAA2xE,QAAA,QACA,iBAAA+jC,OAAAA,IAAA/E,6BCAA,GAAAgF,GAAAj2G,EAAA,gBACAU,GAAAJ,QAAA,SAAA28D,EAAA61C,EAAAtyG,GAEA,GADAy1G,EAAAh5C,OACA36D,KAAAwwG,EAAA,MAAA71C,EACA,QAAAz8D,GACA,IAAA,GAAA,MAAA,UAAAT,GACA,MAAAk9D,GAAA18D,KAAAuyG,EAAA/yG,GAEA,KAAA,GAAA,MAAA,UAAAA,EAAAmlD,GACA,MAAA+X,GAAA18D,KAAAuyG,EAAA/yG,EAAAmlD,GAEA,KAAA,GAAA,MAAA,UAAAnlD,EAAAmlD,EAAA6uB,GACA,MAAA9W,GAAA18D,KAAAuyG,EAAA/yG,EAAAmlD,EAAA6uB,IAGA,MAAA,YACA,MAAA9W,GAAAl7D,MAAA+wG,EAAApxG,yDChBAhB,EAAAJ,QAAA,SAAA+qG,GACA,OAAA/oG,IAAA+oG,EAAA,KAAAt6D,WAAA,yBAAAs6D,EACA,OAAAA,8BCFA3qG,EAAAJ,SAAAN,EAAA,YAAA,WACA,MAAA,IAAA6tC,OAAAC,kBAAA,KAAAkzC,IAAA,WAAA,MAAA,MAAAjhF,4CCFA,GAAAskF,GAAArkF,EAAA,gBACAioE,EAAAjoE,EAAA,aAAAioE,SAEAvP,EAAA2rB,EAAApc,IAAAoc,EAAApc,EAAA68B,cACApkG,GAAAJ,QAAA,SAAA+qG,GACA,MAAA3yC,GAAAuP,EAAA68B,cAAAuG,mECJA3qG,EAAAJ,QAAA,gGAEA4c,MAAA,+BCFA,GAAAonE,GAAAtkF,EAAA,kBACAk2G,EAAAl2G,EAAA,kBACAm2G,EAAAn2G,EAAA,gBACAU,GAAAJ,QAAA,SAAA+qG,GACA,GAAAl9E,GAAAm2D,EAAA+mB,GACA+K,EAAAF,EAAAh2G,CACA,IAAAk2G,EAKA,IAJA,GAGA/wF,GAHAgxF,EAAAD,EAAA/K,GACAiL,EAAAH,EAAAj2G,EACAD,EAAA,EAEAo2G,EAAA71G,OAAAP,GAAAq2G,EAAA/1G,KAAA8qG,EAAAhmF,EAAAgxF,EAAAp2G,OAAAkuB,EAAAlW,KAAAoN,EACA,OAAA8I,2FCbA,GAAArtB,GAAAd,EAAA,aACAixG,EAAAjxG,EAAA,WACA4lF,EAAA5lF,EAAA,UACAo1G,EAAAp1G,EAAA,WAGAi1G,EAAA,SAAAruG,EAAAgc,EAAA3gB,GACA,GASAojB,GAAAkxF,EAAAC,EATAC,EAAA7vG,EAAAquG,EAAAc,EACAW,EAAA9vG,EAAAquG,EAAAY,EACAc,EAAA/vG,EAAAquG,EAAA2B,EACAC,EAAAjwG,EAAAquG,EAAAvJ,EACAoL,EAAAlwG,EAAAquG,EAAA1B,EACAwD,EAAAnwG,EAAAquG,EAAAa,EACAx1G,EAAAo2G,EAAAzF,EAAAA,EAAAruF,KAAAquF,EAAAruF,OACAo0F,EAAA12G,EAAA,UACAY,EAAAw1G,EAAA51G,EAAA61G,EAAA71G,EAAA8hB,IAAA9hB,EAAA8hB,QAAA,SAEA8zF,KAAAz0G,EAAA2gB,EACA,KAAAyC,IAAApjB,IAEAs0G,GAAAE,GAAAv1G,OAAAoB,KAAApB,EAAAmkB,KACAA,IAAA/kB,KAEAk2G,EAAAD,EAAAr1G,EAAAmkB,GAAApjB,EAAAojB,GAEA/kB,EAAA+kB,GAAAqxF,GAAA,kBAAAx1G,GAAAmkB,GAAApjB,EAAAojB,GAEAyxF,GAAAP,EAAA3wB,EAAA4wB,EAAA11G,GAEAi2G,GAAA71G,EAAAmkB,IAAAmxF,EAAA,SAAAvD,GACA,GAAA8C,GAAA,SAAAh2G,EAAAmlD,EAAA6uB,GACA,GAAA1yE,eAAA4xG,GAAA,CACA,OAAAvxG,UAAAlB,QACA,IAAA,GAAA,MAAA,IAAAyyG,EACA,KAAA,GAAA,MAAA,IAAAA,GAAAlzG,EACA,KAAA,GAAA,MAAA,IAAAkzG,GAAAlzG,EAAAmlD,GACA,MAAA,IAAA+tD,GAAAlzG,EAAAmlD,EAAA6uB,GACA,MAAAk/B,GAAAlxG,MAAAV,KAAAK,WAGA,OADAq0G,GAAA,UAAA9C,EAAA,UACA8C,GAEAS,GAAAK,GAAA,kBAAAL,GAAA5wB,EAAAklB,SAAAvqG,KAAAi2G,GAAAA,EAEAK,KACAv2G,EAAA22G,UAAA32G,EAAA22G,aAAA5xF,GAAAmxF,EAEA5vG,EAAAquG,EAAAiC,GAAAF,IAAAA,EAAA3xF,IAAA+vF,EAAA4B,EAAA3xF,EAAAmxF,KAKAvB,GAAAc,EAAA,EACAd,EAAAY,EAAA,EACAZ,EAAA2B,EAAA,EACA3B,EAAAvJ,EAAA,EACAuJ,EAAA1B,EAAA,GACA0B,EAAAa,EAAA,GACAb,EAAAkC,EAAA,GACAlC,EAAAiC,EAAA,IACAx2G,EAAAJ,QAAA20G,mFC5DAv0G,EAAAJ,QAAA,SAAAuuG,GACA,IACA,QAAAA,IACA,MAAArvG,GACA,OAAA,8BCJA,GAAAomF,GAAA5lF,EAAA,UACAO,EAAAP,EAAA,gBACAo3G,EAAAp3G,EAAA,oBACAq3G,EAAAr3G,EAAA,gBACA6xG,EAAA7xG,EAAA,gBACAs3G,EAAAt3G,EAAA,8BACAu3G,KACAC,KACAl3G,EAAAI,EAAAJ,QAAA,SAAAm0G,EAAAlT,EAAAtkC,EAAA61C,EAAAnB,GACA,GAGAnxG,GAAAqzG,EAAAxL,EAAAl6E,EAHAspF,EAAA9F,EAAA,WAAA,MAAA8C,IAAA6C,EAAA7C,GACAv0G,EAAA0lF,EAAA3oB,EAAA61C,EAAAvR,EAAA,EAAA,GACAtpD,EAAA,CAEA,IAAA,kBAAAw/D,GAAA,KAAA1mE,WAAA0jE,EAAA,oBAEA,IAAA2C,EAAAK,IAAA,IAAAj3G,EAAAqxG,EAAA4C,EAAAj0G,QAAAA,EAAAy3C,EAAAA,IAEA,IADA9pB,EAAAozE,EAAArhG,EAAAm3G,EAAAxD,EAAAY,EAAAx8D,IAAA,GAAA47D,EAAA,IAAA3zG,EAAAu0G,EAAAx8D,OACAs/D,GAAAppF,IAAAqpF,EAAA,MAAArpF,OACA,KAAAk6E,EAAAoP,EAAAl3G,KAAAk0G,KAAAZ,EAAAxL,EAAA3lG,QAAAC,MAEA,IADAwrB,EAAA5tB,EAAA8nG,EAAAnoG,EAAA2zG,EAAAjxG,MAAA2+F,MACAgW,GAAAppF,IAAAqpF,EAAA,MAAArpF,GAGA7tB,GAAAi3G,MAAAA,EACAj3G,EAAAk3G,OAAAA,wJCvBA,GAAA12G,GAAAJ,EAAAJ,QAAA,mBAAAy2E,SAAAA,OAAAzuD,MAAAA,KACAyuD,OAAA,mBAAArkE,OAAAA,KAAA4V,MAAAA,KAAA5V,KAEAo4F,SAAA,gBACA,iBAAA4M,OAAAA,IAAA52G,6BCLA,GAAAoyB,MAAAA,cACAxyB,GAAAJ,QAAA,SAAA+qG,EAAAhmF,GACA,MAAA6N,GAAA3yB,KAAA8qG,EAAAhmF,8BCFA,GAAAouF,GAAAzzG,EAAA,gBACA23G,EAAA33G,EAAA,mBACAU,GAAAJ,QAAAN,EAAA,kBAAA,SAAAg5E,EAAA3zD,EAAAziB,GACA,MAAA6wG,GAAAvzG,EAAA84E,EAAA3zD,EAAAsyF,EAAA,EAAA/0G,KACA,SAAAo2E,EAAA3zD,EAAAziB,GAEA,MADAo2E,GAAA3zD,GAAAziB,EACAo2E,2FCNA,GAAA/Q,GAAAjoE,EAAA,aAAAioE,QACAvnE,GAAAJ,QAAA2nE,GAAAA,EAAA2vC,yDCDAl3G,EAAAJ,SAAAN,EAAA,oBAAAA,EAAA,YAAA,WACA,MAAA,IAAA6tC,OAAAC,eAAA9tC,EAAA,iBAAA,OAAA,KAAAghF,IAAA,WAAA,MAAA,MAAAjhF,qFCAA,GAAAozG,GAAAnzG,EAAA,SAEAU,GAAAJ,QAAAutC,OAAA,KAAAgqE,qBAAA,GAAAhqE,OAAA,SAAAw9D,GACA,MAAA,UAAA8H,EAAA9H,GAAAA,EAAAnuF,MAAA,IAAA2wB,OAAAw9D,yCCHA,GAAAyM,GAAA93G,EAAA,gBACA2xG,EAAA3xG,EAAA,UAAA,YACA+3G,EAAAn2G,MAAA0C,SAEA5D,GAAAJ,QAAA,SAAA+qG,GACA,WAAA/oG,KAAA+oG,IAAAyM,EAAAl2G,QAAAypG,GAAA0M,EAAApG,KAAAtG,6DCLA,GAAA8H,GAAAnzG,EAAA,SACAU,GAAAJ,QAAAsB,MAAAgqC,SAAA,SAAA8wC,GACA,MAAA,SAAAy2B,EAAAz2B,yCCHAh8E,EAAAJ,QAAA,SAAA+qG,GACA,MAAA,gBAAAA,GAAA,OAAAA,EAAA,kBAAAA,8BCAA,GAAAgM,GAAAr3G,EAAA,eACAU,GAAAJ,QAAA,SAAA+nG,EAAAprC,EAAAr6D,EAAA2+F,GACA,IACA,MAAAA,GAAAtkC,EAAAo6C,EAAAz0G,GAAA,GAAAA,EAAA,IAAAq6D,EAAAr6D,GAEA,MAAApD,GACA,GAAAoyB,GAAAy2E,EAAA,MAEA,WADA/lG,KAAAsvB,GAAAylF,EAAAzlF,EAAArxB,KAAA8nG,IACA7oG,+CCTA,YACA,IAAA25B,GAAAn5B,EAAA,oBACA25E,EAAA35E,EAAA,oBACAq1G,EAAAr1G,EAAA,wBACAg4G,IAGAh4G,GAAA,WAAAg4G,EAAAh4G,EAAA,UAAA,YAAA,WAAA,MAAAqB,QAEAX,EAAAJ,QAAA,SAAAg5E,EAAAi7B,EAAA7xG,GACA42E,EAAAh1E,UAAA60B,EAAA6+E,GAAAt1G,KAAAi3E,EAAA,EAAAj3E,KACA2yG,EAAA/7B,EAAAi7B,EAAA,2ICXA,YACA,IAAA0D,GAAAj4G,EAAA,cACAi1G,EAAAj1G,EAAA,aACAk4G,EAAAl4G,EAAA,eACAo1G,EAAAp1G,EAAA,WACAsyF,EAAAtyF,EAAA,UACA83G,EAAA93G,EAAA,gBACAm4G,EAAAn4G,EAAA,kBACAq1G,EAAAr1G,EAAA,wBACAmyF,EAAAnyF,EAAA,iBACA2xG,EAAA3xG,EAAA,UAAA,YACAo4G,OAAAz3F,MAAA,WAAAA,QAKA03F,EAAA,WAAA,MAAAh3G,MAEAX,GAAAJ,QAAA,SAAAk1G,EAAAjB,EAAAj7B,EAAA52E,EAAA41G,EAAAC,EAAAC,GACAL,EAAA7+B,EAAAi7B,EAAA7xG,EACA,IAeA6uF,GAAAlsE,EAAA2yF,EAfAS,EAAA,SAAAlyG,GACA,IAAA6xG,GAAA7xG,IAAAgsF,GAAA,MAAAA,GAAAhsF,EACA,QAAAA,GACA,IAVA,OAWA,IAVA,SAUA,MAAA,YAAA,MAAA,IAAA+yE,GAAAj4E,KAAAkF,IACA,MAAA,YAAA,MAAA,IAAA+yE,GAAAj4E,KAAAkF,KAEA6sG,EAAAmB,EAAA,YACAmE,EAdA,UAcAJ,EACAK,GAAA,EACApmB,EAAAijB,EAAAlxG,UACAs0G,EAAArmB,EAAAof,IAAApf,EAnBA,eAmBA+lB,GAAA/lB,EAAA+lB,GACAO,EAAAD,GAAAH,EAAAH,GACAQ,EAAAR,EAAAI,EAAAD,EAAA,WAAAI,MAAAv2G,GACAy2G,EAAA,SAAAxE,EAAAhiB,EAAAgP,SAAAqX,EAAAA,CAwBA,IArBAG,IACAf,EAAA7lB,EAAA4mB,EAAAx4G,KAAA,GAAAi1G,QACA3nE,OAAAvpC,WAAA0zG,EAAAt1G,OAEA2yG,EAAA2C,EAAA5E,GAAA,GAEA6E,GAAA3lB,EAAA0lB,EAAArG,IAAAyD,EAAA4C,EAAArG,EAAA0G,IAIAK,GAAAE,GAjCA,WAiCAA,EAAAh2F,OACA+1F,GAAA,EACAE,EAAA,WAAA,MAAAD,GAAAr4G,KAAAc,QAGA42G,IAAAO,IAAAJ,IAAAO,GAAApmB,EAAAof,IACAyD,EAAA7iB,EAAAof,EAAAkH,GAGAf,EAAAvD,GAAAsE,EACAf,EAAA1E,GAAAiF,EACAC,EAMA,GALA/mB,GACAz4E,OAAA4/F,EAAAG,EAAAJ,EA9CA,UA+CA93F,KAAA43F,EAAAM,EAAAJ,EAhDA,QAiDAlX,QAAAuX,GAEAN,EAAA,IAAAnzF,IAAAksE,GACAlsE,IAAAktE,IAAA2lB,EAAA3lB,EAAAltE,EAAAksE,EAAAlsE,QACA4vF,GAAAA,EAAAvJ,EAAAuJ,EAAAc,GAAAqC,GAAAO,GAAApE,EAAAhjB,EAEA,OAAAA,+MCpEA7wF,EAAAJ,QAAA,SAAAqC,EAAAC,GACA,OAAAA,MAAAA,EAAAD,OAAAA,8BCDAjC,EAAAJ,qCCAAI,EAAAJ,SAAA,4BCAA,GAAA04G,GAAAh5G,EAAA,UAAA,QACAqkF,EAAArkF,EAAA,gBACAsyF,EAAAtyF,EAAA,UACAi5G,EAAAj5G,EAAA,gBAAAE,EACAmhC,EAAA,EACA63E,EAAArrE,OAAAqrE,cAAA,WACA,OAAA,GAEAC,GAAAn5G,EAAA,YAAA,WACA,MAAAk5G,GAAArrE,OAAAurE,yBAEAC,EAAA,SAAAhO,GACA4N,EAAA5N,EAAA2N,GAAAp2G,OACA3C,EAAA,OAAAohC,EACAo2C,SAGAu8B,EAAA,SAAA3I,EAAAlyE,GAEA,IAAAkrD,EAAAgnB,GAAA,MAAA,gBAAAA,GAAAA,GAAA,gBAAAA,GAAA,IAAA,KAAAA,CACA,KAAA/Y,EAAA+Y,EAAA2N,GAAA,CAEA,IAAAE,EAAA7N,GAAA,MAAA,GAEA,KAAAlyE,EAAA,MAAA,GAEAkgF,GAAAhO,GAEA,MAAAA,GAAA2N,GAAA/4G,GAEAq5G,EAAA,SAAAjO,EAAAlyE,GACA,IAAAm5D,EAAA+Y,EAAA2N,GAAA,CAEA,IAAAE,EAAA7N,GAAA,OAAA,CAEA,KAAAlyE,EAAA,OAAA,CAEAkgF,GAAAhO,GAEA,MAAAA,GAAA2N,GAAAvhC,GAGA8hC,EAAA,SAAAlO,GAEA,MADA8N,IAAAjE,EAAAU,MAAAsD,EAAA7N,KAAA/Y,EAAA+Y,EAAA2N,IAAAK,EAAAhO,GACAA,GAEA6J,EAAAx0G,EAAAJ,SACAo1G,IAAAsD,EACApD,MAAA,EACA5B,QAAAA,EACAsF,QAAAA,EACAC,SAAAA,2GCnDA,YAEA,IAAAj1B,GAAAtkF,EAAA,kBACAk2G,EAAAl2G,EAAA,kBACAm2G,EAAAn2G,EAAA,iBACAmyG,EAAAnyG,EAAA,gBACAkyG,EAAAlyG,EAAA,cACAw5G,EAAA3rE,OAAAsjE,MAGAzwG,GAAAJ,SAAAk5G,GAAAx5G,EAAA,YAAA,WACA,GAAAstE,MACAimC,KAEAqD,EAAA1L,SACAuO,EAAA,sBAGA,OAFAnsC,GAAAspC,GAAA,EACA6C,EAAAv8F,MAAA,IAAApN,QAAA,SAAA42B,GAAA6sE,EAAA7sE,GAAAA,IACA,GAAA8yE,KAAAlsC,GAAAspC,IAAA/oE,OAAAltB,KAAA64F,KAAAjG,IAAA9vE,KAAA,KAAAg2E,IACA,SAAAv4G,EAAAe,GAMA,IALA,GAAAmrE,GAAA+kC,EAAAjxG,GACAw4G,EAAAh4G,UAAAlB,OACAy3C,EAAA,EACAm+D,EAAAF,EAAAh2G,EACAo2G,EAAAH,EAAAj2G,EACAw5G,EAAAzhE,GAMA,IALA,GAIA5yB,GAJAuxF,EAAA1E,EAAAxwG,UAAAu2C,MACAt3B,EAAAy1F,EAAA9xB,EAAAsyB,GAAA50G,OAAAo0G,EAAAQ,IAAAtyB,EAAAsyB,GACAp2G,EAAAmgB,EAAAngB,OACA0sC,EAAA,EAEA1sC,EAAA0sC,GAAAopE,EAAA/1G,KAAAq2G,EAAAvxF,EAAA1E,EAAAusB,QAAAkgC,EAAA/nD,GAAAuxF,EAAAvxF,GACA,OAAA+nD,IACAosC,4IChCA,GAAAnC,GAAAr3G,EAAA,gBACA25G,EAAA35G,EAAA,iBACA45G,EAAA55G,EAAA,oBACA65G,EAAA75G,EAAA,iBAAA,YACA85G,EAAA,aAIAC,EAAA,WAEA,GAIAC,GAJAC,EAAAj6G,EAAA,iBAAA,UACAC,EAAA25G,EAAAp5G,MAcA,KAVAy5G,EAAAC,MAAAC,QAAA,OACAn6G,EAAA,WAAAo6G,YAAAH,GACAA,EAAApiC,IAAA,cAGAmiC,EAAAC,EAAAI,cAAApyC,SACA+xC,EAAA/gE,OACA+gE,EAAAt8B,MAAA48B,uCACAN,EAAAriE,QACAoiE,EAAAC,EAAAjE,EACA91G,WAAA85G,GAAA,UAAAH,EAAA35G,GACA,OAAA85G,KAGAr5G,GAAAJ,QAAAutC,OAAA1U,QAAA,SAAAk0C,EAAAQ,GACA,GAAA1/C,EAQA,OAPA,QAAAk/C,GACAysC,EAAA,UAAAzC,EAAAhqC,GACAl/C,EAAA,GAAA2rF,GACAA,EAAA,UAAA,KAEA3rF,EAAA0rF,GAAAxsC,GACAl/C,EAAA4rF,QACAz3G,KAAAurE,EAAA1/C,EAAAwrF,EAAAxrF,EAAA0/C,gJCvCA,GAAAwpC,GAAAr3G,EAAA,gBACAu6G,EAAAv6G,EAAA,qBACAw6G,EAAAx6G,EAAA,mBACAyzG,EAAA5lE,OAAAC,cAEAxtC,GAAAJ,EAAAF,EAAA,kBAAA6tC,OAAAC,eAAA,SAAAu/B,EAAAq+B,EAAA+O,GAIA,GAHApD,EAAAhqC,GACAq+B,EAAA8O,EAAA9O,GAAA,GACA2L,EAAAoD,GACAF,EAAA,IACA,MAAA9G,GAAApmC,EAAAq+B,EAAA+O,GACA,MAAAj7G,IACA,GAAA,OAAAi7G,IAAA,OAAAA,GAAA,KAAA1pE,WAAA,2BAEA,OADA,SAAA0pE,KAAAptC,EAAAq+B,GAAA+O,EAAA73G,OACAyqE,iHCdA,GAAAomC,GAAAzzG,EAAA,gBACAq3G,EAAAr3G,EAAA,gBACAskF,EAAAtkF,EAAA,iBAEAU,GAAAJ,QAAAN,EAAA,kBAAA6tC,OAAA4rC,iBAAA,SAAApM,EAAAQ,GACAwpC,EAAAhqC,EAKA,KAJA,GAGAq+B,GAHA/qF,EAAA2jE,EAAAzW,GACArtE,EAAAmgB,EAAAngB,OACAP,EAAA,EAEAO,EAAAP,GAAAwzG,EAAAvzG,EAAAmtE,EAAAq+B,EAAA/qF,EAAA1gB,KAAA4tE,EAAA69B,GACA,OAAAr+B,4GCXA,GAAA8oC,GAAAn2G,EAAA,iBACA23G,EAAA33G,EAAA,oBACA4xG,EAAA5xG,EAAA,iBACAw6G,EAAAx6G,EAAA,mBACAsyF,EAAAtyF,EAAA,UACAu6G,EAAAv6G,EAAA,qBACA06G,EAAA7sE,OAAAmkD,wBAEA1xF,GAAAJ,EAAAF,EAAA,kBAAA06G,EAAA,SAAArtC,EAAAq+B,GAGA,GAFAr+B,EAAAukC,EAAAvkC,GACAq+B,EAAA8O,EAAA9O,GAAA,GACA6O,EAAA,IACA,MAAAG,GAAArtC,EAAAq+B,GACA,MAAAlsG,IACA,GAAA8yF,EAAAjlB,EAAAq+B,GAAA,MAAAiM,IAAAxB,EAAAj2G,EAAAK,KAAA8sE,EAAAq+B,GAAAr+B,EAAAq+B,6KCbA,GAAAkG,GAAA5xG,EAAA,iBACA26G,EAAA36G,EAAA,kBAAAE,EACA4qC,KAAAA,SAEA8vE,EAAA,gBAAA7jC,SAAAA,QAAAlpC,OAAAqkD,oBACArkD,OAAAqkD,oBAAAnb,WAEA8jC,EAAA,SAAAxP,GACA,IACA,MAAAsP,GAAAtP,GACA,MAAA7rG,GACA,MAAAo7G,GAAAzoF,SAIAzxB,GAAAJ,QAAAJ,EAAA,SAAAmrG,GACA,MAAAuP,IAAA,mBAAA9vE,EAAAvqC,KAAA8qG,GAAAwP,EAAAxP,GAAAsP,EAAA/I,EAAAvG,uEChBA,GAAAyP,GAAA96G,EAAA,2BACA+6G,EAAA/6G,EAAA,oBAAAgC,OAAA,SAAA,YAEA1B,GAAAJ,EAAA2tC,OAAAqkD,qBAAA,SAAA7kB,GACA,MAAAytC,GAAAztC,EAAA0tC,kFCLAz6G,EAAAJ,EAAA2tC,OAAAmtE,gDCCA,GAAA1oB,GAAAtyF,EAAA,UACAmyG,EAAAnyG,EAAA,gBACA65G,EAAA75G,EAAA,iBAAA,YACAi7G,EAAAptE,OAAAvpC,SAEA5D,GAAAJ,QAAAutC,OAAAskD,gBAAA,SAAA9kB,GAEA,MADAA,GAAA8kC,EAAA9kC,GACAilB,EAAAjlB,EAAAwsC,GAAAxsC,EAAAwsC,GACA,kBAAAxsC,GAAAptB,aAAAotB,YAAAA,GAAAptB,YACAotB,EAAAptB,YAAA37C,UACA+oE,YAAAx/B,QAAAotE,EAAA,mFCXA,GAAA3oB,GAAAtyF,EAAA,UACA4xG,EAAA5xG,EAAA,iBACAk7G,EAAAl7G,EAAA,sBAAA,GACA65G,EAAA75G,EAAA,iBAAA,WAEAU,GAAAJ,QAAA,SAAA04E,EAAAiZ,GACA,GAGA5sE,GAHAgoD,EAAAukC,EAAA54B,GACA/4E,EAAA,EACAkuB,IAEA,KAAA9I,IAAAgoD,GAAAhoD,GAAAw0F,GAAAvnB,EAAAjlB,EAAAhoD,IAAA8I,EAAAlW,KAAAoN,EAEA,MAAA4sE,EAAAzxF,OAAAP,GAAAqyF,EAAAjlB,EAAAhoD,EAAA4sE,EAAAhyF,SACAi7G,EAAA/sF,EAAA9I,IAAA8I,EAAAlW,KAAAoN,GAEA,OAAA8I,yGCdA,GAAA2sF,GAAA96G,EAAA,2BACA45G,EAAA55G,EAAA,mBAEAU,GAAAJ,QAAAutC,OAAAltB,MAAA,SAAA0sD,GACA,MAAAytC,GAAAztC,EAAAusC,kFCLAt5G,EAAAJ,KAAA23G,+CCCA,GAAA5C,GAAAj1G,EAAA,aACAixG,EAAAjxG,EAAA,WACAm1G,EAAAn1G,EAAA,WACAU,GAAAJ,QAAA,SAAAo1G,EAAA7G,GACA,GAAA5xC,IAAAg0C,EAAApjE,YAAA6nE,IAAA7nE,OAAA6nE,GACAyF,IACAA,GAAAzF,GAAA7G,EAAA5xC,GACAg4C,EAAAA,EAAA2B,EAAA3B,EAAAc,EAAAZ,EAAA,WAAAl4C,EAAA,KAAA,SAAAk+C,yECRAz6G,EAAAJ,QAAA,SAAA86G,EAAAx4G,GACA,OACAmrC,aAAA,EAAAqtE,GACAptC,eAAA,EAAAotC,GACArtC,WAAA,EAAAqtC,GACAx4G,MAAAA,8BCLA,GAAAwyG,GAAAp1G,EAAA,UACAU,GAAAJ,QAAA,SAAAY,EAAA22E,EAAAwjC,GACA,IAAA,GAAAh2F,KAAAwyD,GACAwjC,GAAAn6G,EAAAmkB,GAAAnkB,EAAAmkB,GAAAwyD,EAAAxyD,GACA+vF,EAAAl0G,EAAAmkB,EAAAwyD,EAAAxyD,GACA,OAAAnkB,2CCLAR,EAAAJ,QAAAN,EAAA,kDCAA,YAEA,IAAAi1G,GAAAj1G,EAAA,aACAi2G,EAAAj2G,EAAA,iBACA4lF,EAAA5lF,EAAA,UACAyxG,EAAAzxG,EAAA,YAEAU,GAAAJ,QAAA,SAAAg7G,GACArG,EAAAA,EAAA2B,EAAA0E,GAAA7qG,KAAA,SAAAxO,GACA,GACAs5G,GAAAjuC,EAAA5tE,EAAA+xB,EADA+pF,EAAA95G,UAAA,EAKA,OAHAu0G,GAAA50G,MACAk6G,MAAAj5G,KAAAk5G,EACAD,GAAAtF,EAAAuF,OACAl5G,IAAAL,EAAA,GAAAZ,OACAisE,KACAiuC,GACA77G,EAAA,EACA+xB,EAAAm0D,EAAA41B,EAAA95G,UAAA,GAAA,GACA+vG,EAAAxvG,GAAA,EAAA,SAAAw5G,GACAnuC,EAAAr1D,KAAAwZ,EAAAgqF,EAAA/7G,SAGA+xG,EAAAxvG,GAAA,EAAAqrE,EAAAr1D,KAAAq1D,GAEA,GAAAjsE,MAAAisE,iGCzBA,YAEA,IAAA2nC,GAAAj1G,EAAA,YAEAU,GAAAJ,QAAA,SAAAg7G,GACArG,EAAAA,EAAA2B,EAAA0E,GAAAI,GAAA,WAGA,IAFA,GAAAl7G,GAAAkB,UAAAlB,OACA8sE,EAAA1rE,MAAApB,GACAA,KAAA8sE,EAAA9sE,GAAAkB,UAAAlB,EACA,OAAA,IAAAa,MAAAisE,gDCPA,GAAA+W,GAAArkF,EAAA,gBACAq3G,EAAAr3G,EAAA,gBACAy6C,EAAA,SAAA4yB,EAAAklB,GAEA,GADA8kB,EAAAhqC,IACAgX,EAAAkO,IAAA,OAAAA,EAAA,KAAAxhD,WAAAwhD,EAAA,6BAEA7xF,GAAAJ,SACA+xF,IAAAxkD,OAAAyjE,iBAAA,gBACA,SAAAppB,EAAAyzB,EAAAtpB,GACA,IACAA,EAAAryF,EAAA,UAAA8qG,SAAAvqG,KAAAP,EAAA,kBAAAE,EAAA2tC,OAAAvpC,UAAA,aAAA+tF,IAAA,GACAA,EAAAnK,MACAyzB,IAAAzzB,YAAAtmF,QACA,MAAApC,GAAAm8G,GAAA,EACA,MAAA,UAAAtuC,EAAAklB,GAIA,MAHA93C,GAAA4yB,EAAAklB,GACAopB,EAAAtuC,EAAA7mC,UAAA+rD,EACAF,EAAAhlB,EAAAklB,GACAllB,QAEA,OAAA/qE,IACAm4C,MAAAA,mGCvBA,YACA,IAAA35C,GAAAd,EAAA,aACAixG,EAAAjxG,EAAA,WACAyzG,EAAAzzG,EAAA,gBACA+zG,EAAA/zG,EAAA,kBACA+yG,EAAA/yG,EAAA,UAAA,UAEAU,GAAAJ,QAAA,SAAAo1G,GACA,GAAAzC,GAAA,kBAAAhC,GAAAyE,GAAAzE,EAAAyE,GAAA50G,EAAA40G,EACA3B,IAAAd,IAAAA,EAAAF,IAAAU,EAAAvzG,EAAA+yG,EAAAF,GACA/kC,cAAA,EACAgT,IAAA,WAAA,MAAA3/E,qHCXA,GAAAk/D,GAAAvgE,EAAA,gBAAAE,EACAoyF,EAAAtyF,EAAA,UACAozG,EAAApzG,EAAA,UAAA,cAEAU,GAAAJ,QAAA,SAAA+qG,EAAAuQ,EAAAC,GACAxQ,IAAA/Y,EAAA+Y,EAAAwQ,EAAAxQ,EAAAA,EAAA/mG,UAAA8uG,IAAA7yC,EAAA8qC,EAAA+H,GAAAplC,cAAA,EAAAprE,MAAAg5G,2ECLA,GAAAE,GAAA97G,EAAA,aAAA,QACA+7G,EAAA/7G,EAAA,SACAU,GAAAJ,QAAA,SAAA+kB,GACA,MAAAy2F,GAAAz2F,KAAAy2F,EAAAz2F,GAAA02F,EAAA12F,2DCHA,GAAAvkB,GAAAd,EAAA,aAEAsS,EAAAxR,EADA,wBACAA,EADA,yBAEAJ,GAAAJ,QAAA,SAAA+kB,GACA,MAAA/S,GAAA+S,KAAA/S,EAAA+S,iDCJA,GAAA22F,GAAAh8G,EAAA,iBACAi8G,EAAAj8G,EAAA,aAGAU,GAAAJ,QAAA,SAAA47G,GACA,MAAA,UAAApJ,EAAAqJ,GACA,GAGAp8G,GAAAmlD,EAHAtlD,EAAAq5E,OAAAgjC,EAAAnJ,IACA7yG,EAAA+7G,EAAAG,GACA97G,EAAAT,EAAAY,MAEA,OAAAP,GAAA,GAAAA,GAAAI,EAAA67G,EAAA,OAAA55G,IACAvC,EAAAH,EAAA8vG,WAAAzvG,GACAF,EAAA,OAAAA,EAAA,OAAAE,EAAA,IAAAI,IAAA6kD,EAAAtlD,EAAA8vG,WAAAzvG,EAAA,IAAA,OAAAilD,EAAA,MACAg3D,EAAAt8G,EAAAkyB,OAAA7xB,GAAAF,EACAm8G,EAAAt8G,EAAAuyB,MAAAlyB,EAAAA,EAAA,GAAAilD,EAAA,OAAAnlD,EAAA,OAAA,IAAA,uECdA,GAAAi8G,GAAAh8G,EAAA,iBACAuoB,EAAAD,KAAAC,IACAmnB,EAAApnB,KAAAonB,GACAhvC,GAAAJ,QAAA,SAAA23C,EAAAz3C,GAEA,MADAy3C,GAAA+jE,EAAA/jE,GACAA,EAAA,EAAA1vB,EAAA0vB,EAAAz3C,EAAA,GAAAkvC,EAAAuI,EAAAz3C,iDCJA,GAAAirE,GAAAnjD,KAAAmjD,KACA15C,EAAAzJ,KAAAyJ,KACArxB,GAAAJ,QAAA,SAAA+qG,GACA,MAAAryC,OAAAqyC,GAAAA,GAAA,GAAAA,EAAA,EAAAt5E,EAAA05C,GAAA4/B,8BCHA,GAAA6G,GAAAlyG,EAAA,cACAi8G,EAAAj8G,EAAA,aACAU,GAAAJ,QAAA,SAAA+qG,GACA,MAAA6G,GAAA+J,EAAA5Q,gECHA,GAAA2Q,GAAAh8G,EAAA,iBACA0vC,EAAApnB,KAAAonB,GACAhvC,GAAAJ,QAAA,SAAA+qG,GACA,MAAAA,GAAA,EAAA37D,EAAAssE,EAAA3Q,GAAA,kBAAA,gDCHA,GAAA4Q,GAAAj8G,EAAA,aACAU,GAAAJ,QAAA,SAAA+qG,GACA,MAAAx9D,QAAAouE,EAAA5Q,+CCFA,GAAAhnB,GAAArkF,EAAA,eAGAU,GAAAJ,QAAA,SAAA+qG,EAAAuL,GACA,IAAAvyB,EAAAgnB,GAAA,MAAAA,EACA,IAAApuC,GAAAxzB,CACA,IAAAmtE,GAAA,mBAAA35C,EAAAouC,EAAAvgE,YAAAu5C,EAAA56C,EAAAwzB,EAAA18D,KAAA8qG,IAAA,MAAA5hE,EACA,IAAA,mBAAAwzB,EAAAouC,EAAA+Q,WAAA/3B,EAAA56C,EAAAwzB,EAAA18D,KAAA8qG,IAAA,MAAA5hE,EACA,KAAAmtE,GAAA,mBAAA35C,EAAAouC,EAAAvgE,YAAAu5C,EAAA56C,EAAAwzB,EAAA18D,KAAA8qG,IAAA,MAAA5hE,EACA,MAAAsH,WAAA,wFCVA,GAAA1P,GAAA,EACAg7E,EAAA/zF,KAAA0J,QACAtxB,GAAAJ,QAAA,SAAA+kB,GACA,MAAA,UAAArjB,WAAAM,KAAA+iB,EAAA,GAAAA,EAAA,QAAAgc,EAAAg7E,GAAAvxE,SAAA,gCCHA,GAAAu5C,GAAArkF,EAAA,eACAU,GAAAJ,QAAA,SAAA+qG,EAAAgH,GACA,IAAAhuB,EAAAgnB,IAAAA,EAAAqJ,KAAArC,EAAA,KAAAthE,WAAA,0BAAAshE,EAAA,aACA,OAAAhH,gDCHA,GAAAvqG,GAAAd,EAAA,aACAixG,EAAAjxG,EAAA,WACAi4G,EAAAj4G,EAAA,cACAs8G,EAAAt8G,EAAA,cACA8tC,EAAA9tC,EAAA,gBAAAE,CACAQ,GAAAJ,QAAA,SAAAsiB,GACA,GAAA25F,GAAAtL,EAAA/F,SAAA+F,EAAA/F,OAAA+M,KAAAn3G,EAAAoqG,WACA,MAAAtoF,EAAAkP,OAAA,IAAAlP,IAAA25F,IAAAzuE,EAAAyuE,EAAA35F,GAAAhgB,MAAA05G,EAAAp8G,EAAA0iB,iHCPAtiB,EAAAJ,EAAAF,EAAA,gDCAA,GAAAsS,GAAAtS,EAAA,aAAA,OACA+7G,EAAA/7G,EAAA,UACAkrG,EAAAlrG,EAAA,aAAAkrG,OACAsR,EAAA,kBAAAtR,IAEAxqG,EAAAJ,QAAA,SAAAsiB,GACA,MAAAtQ,GAAAsQ,KAAAtQ,EAAAsQ,GACA45F,GAAAtR,EAAAtoF,KAAA45F,EAAAtR,EAAA6Q,GAAA,UAAAn5F,MAGAtQ,MAAAA,wECVA,GAAA0iG,GAAAh1G,EAAA,cACA2xG,EAAA3xG,EAAA,UAAA,YACA83G,EAAA93G,EAAA,eACAU,GAAAJ,QAAAN,EAAA,WAAAy8G,kBAAA,SAAApR,GACA,OAAA/oG,IAAA+oG,EAAA,MAAAA,GAAAsG,IACAtG,EAAA,eACAyM,EAAA9C,EAAA3J,2FCNA,GAAAgM,GAAAr3G,EAAA,gBACAghF,EAAAhhF,EAAA,6BACAU,GAAAJ,QAAAN,EAAA,WAAA08G,YAAA,SAAArR,GACA,GAAAoM,GAAAz2B,EAAAqqB,EACA,IAAA,kBAAAoM,GAAA,KAAA1mE,WAAAs6D,EAAA,oBACA,OAAAgM,GAAAI,EAAAl3G,KAAA8qG,8FCLA,GAAA2J,GAAAh1G,EAAA,cACA2xG,EAAA3xG,EAAA,UAAA,YACA83G,EAAA93G,EAAA,eACAU,GAAAJ,QAAAN,EAAA,WAAA28G,WAAA,SAAAtR,GACA,GAAAh+B,GAAAx/B,OAAAw9D,EACA,YAAA/oG,KAAA+qE,EAAAskC,IACA,cAAAtkC,IAEAyqC,EAAA5kF,eAAA8hF,EAAA3nC,2FCRA,YACA,IAAAuvC,GAAA58G,EAAA,yBACA6zG,EAAA7zG,EAAA,gBACA83G,EAAA93G,EAAA,gBACA4xG,EAAA5xG,EAAA,gBAMAU,GAAAJ,QAAAN,EAAA,kBAAA4B,MAAA,QAAA,SAAAkzG,EAAAvuG,GACAlF,KAAAqzG,GAAA9C,EAAAkD,GACAzzG,KAAAq5D,GAAA,EACAr5D,KAAA0zG,GAAAxuG,GAEA,WACA,GAAA8mE,GAAAhsE,KAAAqzG,GACAnuG,EAAAlF,KAAA0zG,GACA98D,EAAA52C,KAAAq5D,IACA,QAAA2S,GAAAp1B,GAAAo1B,EAAA7sE,QACAa,KAAAqzG,OAAApyG,GACAuxG,EAAA,IAEA,QAAAttG,EAAAstG,EAAA,EAAA57D,GACA,UAAA1xC,EAAAstG,EAAA,EAAAxmC,EAAAp1B,IACA47D,EAAA,GAAA57D,EAAAo1B,EAAAp1B,MACA,UAGA6/D,EAAA+E,UAAA/E,EAAAl2G,MAEAg7G,EAAA,QACAA,EAAA,UACAA,EAAA,8IChCA,GAAA3H,GAAAj1G,EAAA,YAEAi1G,GAAAA,EAAA2B,EAAA3B,EAAAc,EAAA,UAAA5E,OAAAnxG,EAAA,sFCHA,GAAAi1G,GAAAj1G,EAAA,YAEAi1G,GAAAA,EAAA2B,EAAA,UAAAz9E,OAAAn5B,EAAA,sFCFA,GAAAi1G,GAAAj1G,EAAA,YAEAi1G,GAAAA,EAAA2B,EAAA3B,EAAAc,GAAA/1G,EAAA,kBAAA,UAAA8tC,eAAA9tC,EAAA,gBAAAE,qFCDA,GAAAiyG,GAAAnyG,EAAA,gBACA88G,EAAA98G,EAAA,gBAEAA,GAAA,iBAAA,iBAAA,WACA,MAAA,UAAAqrG,GACA,MAAAyR,GAAA3K,EAAA9G,2FCLA,GAAA8G,GAAAnyG,EAAA,gBACA86G,EAAA96G,EAAA,iBAEAA,GAAA,iBAAA,OAAA,WACA,MAAA,UAAAqrG,GACA,MAAAyP,GAAA3I,EAAA9G,4FCLA,GAAA4J,GAAAj1G,EAAA,YACAi1G,GAAAA,EAAA2B,EAAA,UAAAtF,eAAAtxG,EAAA,gBAAAqyF,6FCFA,YACA,IAAA0qB,GAAA/8G,EAAA,wBACAi0G,EAAAj0G,EAAA,yBAIAU,GAAAJ,QAAAN,EAAA,iBAHA,MAGA,SAAAghF,GACA,MAAA,YAAA,MAAAA,GAAA3/E,KAAAK,UAAAlB,OAAA,EAAAkB,UAAA,OAAAY,OAGAgpC,IAAA,SAAA1oC,GACA,MAAAm6G,GAAAx8C,IAAA0zC,EAAA5yG,KARA,OAQAuB,EAAA,IAAAA,EAAA,EAAAA,EAAAA,KAEAm6G,sGCbA,YACA,IAAAC,GAAAh9G,EAAA,iBAAA,EAGAA,GAAA,kBAAAi5E,OAAA,SAAA,SAAA67B,GACAzzG,KAAAqzG,GAAAz7B,OAAA67B,GACAzzG,KAAAq5D,GAAA,GAEA,WACA,GAEAuiD,GAFA5vC,EAAAhsE,KAAAqzG,GACAz8D,EAAA52C,KAAAq5D,EAEA,OAAAziB,IAAAo1B,EAAA7sE,QAAAoC,UAAAN,GAAAK,MAAA,IACAs6G,EAAAD,EAAA3vC,EAAAp1B,GACA52C,KAAAq5D,IAAAuiD,EAAAz8G,QACAoC,MAAAq6G,EAAAt6G,MAAA,uECfA,YAEA,IAAA7B,GAAAd,EAAA,aACAsyF,EAAAtyF,EAAA,UACA+zG,EAAA/zG,EAAA,kBACAi1G,EAAAj1G,EAAA,aACAk4G,EAAAl4G,EAAA,eACAg5G,EAAAh5G,EAAA,WAAA01G,IACAwH,EAAAl9G,EAAA,YACA87G,EAAA97G,EAAA,aACAq1G,EAAAr1G,EAAA,wBACA+7G,EAAA/7G,EAAA,UACAm9G,EAAAn9G,EAAA,UACAs8G,EAAAt8G,EAAA,cACAo9G,EAAAp9G,EAAA,iBACAq9G,EAAAr9G,EAAA,gBACA4rC,EAAA5rC,EAAA,eACAq3G,EAAAr3G,EAAA,gBACA4xG,EAAA5xG,EAAA,iBACAw6G,EAAAx6G,EAAA,mBACA23G,EAAA33G,EAAA,oBACAi6E,EAAAj6E,EAAA,oBACAs9G,EAAAt9G,EAAA,sBACAu9G,EAAAv9G,EAAA,kBACAw9G,EAAAx9G,EAAA,gBACA86G,EAAA96G,EAAA,kBACA06G,EAAA6C,EAAAr9G,EACAuzG,EAAA+J,EAAAt9G,EACAy6G,EAAA2C,EAAAp9G,EACAq8G,EAAAz7G,EAAAoqG,OACAgG,EAAApwG,EAAA44B,KACA+jF,EAAAvM,GAAAA,EAAAh8D,UAEAwoE,EAAAP,EAAA,WACAQ,EAAAR,EAAA,eACA7G,KAAAuB,qBACA+F,EAAA9B,EAAA,mBACA+B,EAAA/B,EAAA,WACAgC,EAAAhC,EAAA,cACAb,EAAAptE,OAAA,UACAkwE,EAAA,kBAAAxB,GACAyB,EAAAl9G,EAAAk9G,QAEAC,GAAAD,IAAAA,EAAA,YAAAA,EAAA,UAAAE,UAGAC,EAAApK,GAAAmJ,EAAA,WACA,MAEA,IAFAjjC,EAAAw5B,KAAA,KACAzyB,IAAA,WAAA,MAAAyyB,GAAApyG,KAAA,KAAAuB,MAAA,IAAA7C,MACAA,IACA,SAAAsrG,EAAAhmF,EAAAgsF,GACA,GAAA+M,GAAA1D,EAAAO,EAAA51F,EACA+4F,UAAAnD,GAAA51F,GACAouF,EAAApI,EAAAhmF,EAAAgsF,GACA+M,GAAA/S,IAAA4P,GAAAxH,EAAAwH,EAAA51F,EAAA+4F,IACA3K,EAEAn4F,EAAA,SAAAsgG,GACA,GAAAyC,GAAAR,EAAAjC,GAAA3hC,EAAAsiC,EAAA,UAEA,OADA8B,GAAAtJ,GAAA6G,EACAyC,GAGAC,EAAAP,GAAA,gBAAAxB,GAAAlU,SAAA,SAAAgD,GACA,MAAA,gBAAAA,IACA,SAAAA,GACA,MAAAA,aAAAkR,IAGAgC,EAAA,SAAAlT,EAAAhmF,EAAAgsF,GAKA,MAJAhG,KAAA4P,GAAAsD,EAAAT,EAAAz4F,EAAAgsF,GACAgG,EAAAhM,GACAhmF,EAAAm1F,EAAAn1F,GAAA,GACAgyF,EAAAhG,GACA/e,EAAAurB,EAAAx4F,IACAgsF,EAAAtjE,YAIAukD,EAAA+Y,EAAAqS,IAAArS,EAAAqS,GAAAr4F,KAAAgmF,EAAAqS,GAAAr4F,IAAA,GACAgsF,EAAAp3B,EAAAo3B,GAAAtjE,WAAA4pE,EAAA,GAAA,OAJArlB,EAAA+Y,EAAAqS,IAAAjK,EAAApI,EAAAqS,EAAA/F,EAAA,OACAtM,EAAAqS,GAAAr4F,IAAA,GAIA84F,EAAA9S,EAAAhmF,EAAAgsF,IACAoC,EAAApI,EAAAhmF,EAAAgsF,IAEAmN,EAAA,SAAAnT,EAAAK,GACA2L,EAAAhM,EAKA,KAJA,GAGAhmF,GAHA1E,EAAA08F,EAAA3R,EAAAkG,EAAAlG,IACAzrG,EAAA,EACAI,EAAAsgB,EAAAngB,OAEAH,EAAAJ,GAAAs+G,EAAAlT,EAAAhmF,EAAA1E,EAAA1gB,KAAAyrG,EAAArmF,GACA,OAAAgmF,IAEAiH,EAAA,SAAAjH,EAAAK,GACA,WAAAppG,KAAAopG,EAAAzxB,EAAAoxB,GAAAmT,EAAAvkC,EAAAoxB,GAAAK,IAEA+S,EAAA,SAAAp5F,GACA,GAAAq5F,GAAApI,EAAA/1G,KAAAc,KAAAgkB,EAAAm1F,EAAAn1F,GAAA,GACA,SAAAhkB,OAAA45G,GAAA3oB,EAAAurB,EAAAx4F,KAAAitE,EAAAwrB,EAAAz4F,QACAq5F,IAAApsB,EAAAjxF,KAAAgkB,KAAAitE,EAAAurB,EAAAx4F,IAAAitE,EAAAjxF,KAAAq8G,IAAAr8G,KAAAq8G,GAAAr4F,KAAAq5F,IAEAC,EAAA,SAAAtT,EAAAhmF,GAGA,GAFAgmF,EAAAuG,EAAAvG,GACAhmF,EAAAm1F,EAAAn1F,GAAA,GACAgmF,IAAA4P,IAAA3oB,EAAAurB,EAAAx4F,IAAAitE,EAAAwrB,EAAAz4F,GAAA,CACA,GAAAgsF,GAAAqJ,EAAArP,EAAAhmF,EAEA,QADAgsF,IAAA/e,EAAAurB,EAAAx4F,IAAAitE,EAAA+Y,EAAAqS,IAAArS,EAAAqS,GAAAr4F,KAAAgsF,EAAAtjE,YAAA,GACAsjE,IAEAuN,EAAA,SAAAvT,GAKA,IAJA,GAGAhmF,GAHA4sE,EAAA0oB,EAAA/I,EAAAvG,IACAl9E,KACAluB,EAAA,EAEAgyF,EAAAzxF,OAAAP,GACAqyF,EAAAurB,EAAAx4F,EAAA4sE,EAAAhyF,OAAAolB,GAAAq4F,GAAAr4F,GAAA2zF,GAAA7qF,EAAAlW,KAAAoN,EACA,OAAA8I,IAEA0wF,EAAA,SAAAxT,GAMA,IALA,GAIAhmF,GAJAy5F,EAAAzT,IAAA4P,EACAhpB,EAAA0oB,EAAAmE,EAAAhB,EAAAlM,EAAAvG,IACAl9E,KACAluB,EAAA,EAEAgyF,EAAAzxF,OAAAP,IACAqyF,EAAAurB,EAAAx4F,EAAA4sE,EAAAhyF,OAAA6+G,IAAAxsB,EAAA2oB,EAAA51F,IAAA8I,EAAAlW,KAAA4lG,EAAAx4F,GACA,OAAA8I,GAIA4vF,KACAxB,EAAA,WACA,GAAAl7G,eAAAk7G,GAAA,KAAAxrE,WAAA,+BACA,IAAA6qE,GAAAG,EAAAr6G,UAAAlB,OAAA,EAAAkB,UAAA,OAAAY,IACAy8G,EAAA,SAAAn8G,GACAvB,OAAA45G,GAAA8D,EAAAx+G,KAAAu9G,EAAAl7G,GACA0vF,EAAAjxF,KAAAq8G,IAAAprB,EAAAjxF,KAAAq8G,GAAA9B,KAAAv6G,KAAAq8G,GAAA9B,IAAA,GACAuC,EAAA98G,KAAAu6G,EAAAjE,EAAA,EAAA/0G,IAGA,OADAmxG,IAAAkK,GAAAE,EAAAlD,EAAAW,GAAA5tC,cAAA,EAAAqkB,IAAA0sB,IACAzjG,EAAAsgG,IAEA1D,EAAAqE,EAAA,UAAA,WAAA,WACA,MAAAl7G,MAAA0zG,KAGAwI,EAAAr9G,EAAAy+G,EACAnB,EAAAt9G,EAAAq+G,EACAv+G,EAAA,kBAAAE,EAAAo9G,EAAAp9G,EAAA0+G,EACA5+G,EAAA,iBAAAE,EAAAu+G,EACAz+G,EAAA,kBAAAE,EAAA2+G,EAEA9K,IAAA/zG,EAAA,eACAk4G,EAAA+C,EAAA,uBAAAwD,GAAA,GAGAnC,EAAAp8G,EAAA,SAAA0iB,GACA,MAAAtH,GAAA6hG,EAAAv6F,MAIAqyF,EAAAA,EAAAY,EAAAZ,EAAAa,EAAAb,EAAAc,GAAAgI,GAAA7S,OAAAqR,GAEA,KAAA,GAAAyC,GAAA,iHAGA9hG,MAAA,KAAAgwB,GAAA,EAAA8xE,EAAAx+G,OAAA0sC,IAAAiwE,EAAA6B,EAAA9xE,MAEA,KAAA,GAAA+xE,IAAAnE,EAAAqC,EAAA7qG,OAAAo0B,GAAA,EAAAu4E,GAAAz+G,OAAAkmC,IAAA02E,EAAA6B,GAAAv4E,MAEAuuE,GAAAA,EAAA2B,EAAA3B,EAAAc,GAAAgI,EAAA,UAEAmB,IAAA,SAAA75F,GACA,MAAAitE,GAAAsrB,EAAAv4F,GAAA,IACAu4F,EAAAv4F,GACAu4F,EAAAv4F,GAAAk3F,EAAAl3F,IAGA85F,OAAA,SAAAd,GACA,IAAAC,EAAAD,GAAA,KAAAttE,WAAAstE,EAAA,oBACA,KAAA,GAAAh5F,KAAAu4F,GAAA,GAAAA,EAAAv4F,KAAAg5F,EAAA,MAAAh5F,IAEA+5F,UAAA,WAAAnB,GAAA,GACAoB,UAAA,WAAApB,GAAA,KAGAhJ,EAAAA,EAAA2B,EAAA3B,EAAAc,GAAAgI,EAAA,UAEA5kF,OAAAm5E,EAEAxkE,eAAAywE,EAEA9kC,iBAAA+kC,EAEAxsB,yBAAA2sB,EAEAzsB,oBAAA0sB,EAEA5D,sBAAA6D,IAIA3N,GAAA+D,EAAAA,EAAA2B,EAAA3B,EAAAc,IAAAgI,GAAAb,EAAA,WACA,GAAAtG,GAAA2F,GAIA,OAAA,UAAAkB,GAAA7G,KAAA,MAAA6G,GAAA19G,EAAA62G,KAAA,MAAA6G,EAAA5vE,OAAA+oE,OACA,QACA1hE,UAAA,SAAAm2D,GACA,OAAA/oG,KAAA+oG,IAAAiT,EAAAjT,GAAA,CAIA,IAHA,GAEAiU,GAAAC,EAFA59G,GAAA0pG,GACAprG,EAAA,EAEAyB,UAAAlB,OAAAP,GAAA0B,EAAAsW,KAAAvW,UAAAzB,KAQA,OAPAq/G,GAAA39G,EAAA,GACA,kBAAA29G,KAAAC,EAAAD,IACAC,GAAA3zE,EAAA0zE,KAAAA,EAAA,SAAAj6F,EAAAziB,GAEA,GADA28G,IAAA38G,EAAA28G,EAAAh/G,KAAAc,KAAAgkB,EAAAziB,KACA07G,EAAA17G,GAAA,MAAAA,KAEAjB,EAAA,GAAA29G,EACA7B,EAAA17G,MAAAmvG,EAAAvvG,OAKA46G,EAAA,UAAAoB,IAAA39G,EAAA,WAAAu8G,EAAA,UAAAoB,EAAApB,EAAA,UAAAH,SAEA/G,EAAAkH,EAAA,UAEAlH,EAAA/sF,KAAA,QAAA,GAEA+sF,EAAAv0G,EAAA44B,KAAA,QAAA,yjBCxOA15B,EAAA,0BAAA,6DCAAA,EAAA,wBAAA,2DCAA,GAAAi1G,GAAAj1G,EAAA,YAEAi1G,GAAAA,EAAAvJ,EAAAuJ,EAAAiC,EAAA,OAAAld,OAAAh6F,EAAA,yBAAA,6ECHAA,EAAA,iBAAA,8DCAAA,EAAA,iBAAA,2DCAAA,EAAA,uBAYA,KAAA,GAXAc,GAAAd,EAAA,aACAo1G,EAAAp1G,EAAA,WACA83G,EAAA93G,EAAA,gBACAw/G,EAAAx/G,EAAA,UAAA,eAEAy/G,EAAA,wbAIAviG,MAAA,KAEAjd,EAAA,EAAAA,EAAAw/G,EAAAj/G,OAAAP,IAAA,CACA,GAAAs0G,GAAAkL,EAAAx/G,GACAy/G,EAAA5+G,EAAAyzG,GACAhiB,EAAAmtB,GAAAA,EAAAp7G,SACAiuF,KAAAA,EAAAitB,IAAApK,EAAA7iB,EAAAitB,EAAAjL,GACAuD,EAAAvD,GAAAuD,EAAAl2G,yHCIA,QAAAma,KACA1a,KAAA+uC,QAAA/uC,KAAA+uC,YACA/uC,KAAAs+G,cAAAt+G,KAAAs+G,mBAAAr9G,GAwQA,QAAAgJ,GAAAoxE,GACA,MAAA,kBAAAA,GAGA,QAAAkjC,GAAAljC,GACA,MAAA,gBAAAA,GAGA,QAAA2H,GAAA3H,GACA,MAAA,gBAAAA,IAAA,OAAAA,EAGA,QAAAmjC,GAAAnjC,GACA,WAAA,KAAAA,EAnRAh8E,EAAAJ,QAAAyb,EAGAA,EAAAA,aAAAA,EAEAA,EAAAzX,UAAA8rC,YAAA9tC,GACAyZ,EAAAzX,UAAAq7G,kBAAAr9G,GAIAyZ,EAAA+jG,oBAAA,GAIA/jG,EAAAzX,UAAAy7G,gBAAA,SAAArgH,GACA,IAAAkgH,EAAAlgH,IAAAA,EAAA,GAAAs5D,MAAAt5D,GACA,KAAAqxC,WAAA,8BAEA,OADA1vC,MAAAs+G,cAAAjgH,EACA2B,MAGA0a,EAAAzX,UAAAxC,KAAA,SAAA8E,GACA,GAAAmmG,GAAAve,EAAAthB,EAAAvrE,EAAA1B,EAAAw1E,CAMA,IAJAp0E,KAAA+uC,UACA/uC,KAAA+uC,YAGA,UAAAxpC,KACAvF,KAAA+uC,QAAAr6B,OACAsuE,EAAAhjF,KAAA+uC,QAAAr6B,SAAA1U,KAAA+uC,QAAAr6B,MAAAvV,QAAA,CAEA,IADAusG,EAAArrG,UAAA,aACAvB,OACA,KAAA4sG,EAGA,IAAA9pG,GAAA,GAAA9C,OAAA,yCAAA4sG,EAAA,IAEA,MADA9pG,GAAA8yD,QAAAg3C,EACA9pG,EAOA,GAFAurF,EAAAntF,KAAA+uC,QAAAxpC,GAEAi5G,EAAArxB,GACA,OAAA,CAEA,IAAAljF,EAAAkjF,GACA,OAAA9sF,UAAAlB,QAEA,IAAA,GACAguF,EAAAjuF,KAAAc,KACA,MACA,KAAA,GACAmtF,EAAAjuF,KAAAc,KAAAK,UAAA,GACA,MACA,KAAA,GACA8sF,EAAAjuF,KAAAc,KAAAK,UAAA,GAAAA,UAAA,GACA,MAEA,SACAC,EAAAC,MAAA0C,UAAA6tB,MAAA5xB,KAAAmB,UAAA,GACA8sF,EAAAzsF,MAAAV,KAAAM,OAEA,IAAA0iF,EAAAmK,GAIA,IAHA7sF,EAAAC,MAAA0C,UAAA6tB,MAAA5xB,KAAAmB,UAAA,GACA+zE,EAAA+Y,EAAAr8D,QACA+6C,EAAAuI,EAAAj1E,OACAP,EAAA,EAAAA,EAAAitE,EAAAjtE,IACAw1E,EAAAx1E,GAAA8B,MAAAV,KAAAM,EAGA,QAAA,GAGAoa,EAAAzX,UAAA07G,YAAA,SAAAp5G,EAAAq5G,GACA,GAAApuE,EAEA,KAAAvmC,EAAA20G,GACA,KAAAlvE,WAAA,8BA2CA,OAzCA1vC,MAAA+uC,UACA/uC,KAAA+uC,YAIA/uC,KAAA+uC,QAAA8vE,aACA7+G,KAAAS,KAAA,cAAA8E,EACA0E,EAAA20G,EAAAA,UACAA,EAAAA,SAAAA,GAEA5+G,KAAA+uC,QAAAxpC,GAGAy9E,EAAAhjF,KAAA+uC,QAAAxpC,IAEAvF,KAAA+uC,QAAAxpC,GAAAqR,KAAAgoG,GAGA5+G,KAAA+uC,QAAAxpC,IAAAvF,KAAA+uC,QAAAxpC,GAAAq5G,GANA5+G,KAAA+uC,QAAAxpC,GAAAq5G,EASA57B,EAAAhjF,KAAA+uC,QAAAxpC,MAAAvF,KAAA+uC,QAAAxpC,GAAAu5G,SAIAtuE,EAHAguE,EAAAx+G,KAAAs+G,eAGA5jG,EAAA+jG,oBAFAz+G,KAAAs+G,gBAKA9tE,EAAA,GAAAxwC,KAAA+uC,QAAAxpC,GAAApG,OAAAqxC,IACAxwC,KAAA+uC,QAAAxpC,GAAAu5G,QAAA,EACArqG,QAAAC,MAAA,mIAGA1U,KAAA+uC,QAAAxpC,GAAApG,QACA,kBAAAsV,SAAAsvE,OAEAtvE,QAAAsvE,SAKA/jF,MAGA0a,EAAAzX,UAAAtB,GAAA+Y,EAAAzX,UAAA07G,YAEAjkG,EAAAzX,UAAAuT,KAAA,SAAAjR,EAAAq5G,GAMA,QAAAG,KACA/+G,KAAA+gE,eAAAx7D,EAAAw5G,GAEAC,IACAA,GAAA,EACAJ,EAAAl+G,MAAAV,KAAAK,YAVA,IAAA4J,EAAA20G,GACA,KAAAlvE,WAAA,8BAEA,IAAAsvE,IAAA,CAcA,OAHAD,GAAAH,SAAAA,EACA5+G,KAAA2B,GAAA4D,EAAAw5G,GAEA/+G,MAIA0a,EAAAzX,UAAA89D,eAAA,SAAAx7D,EAAAq5G,GACA,GAAAK,GAAAC,EAAA//G,EAAAP,CAEA,KAAAqL,EAAA20G,GACA,KAAAlvE,WAAA,8BAEA,KAAA1vC,KAAA+uC,UAAA/uC,KAAA+uC,QAAAxpC,GACA,MAAAvF,KAMA,IAJAi/G,EAAAj/G,KAAA+uC,QAAAxpC,GACApG,EAAA8/G,EAAA9/G,OACA+/G,GAAA,EAEAD,IAAAL,GACA30G,EAAAg1G,EAAAL,WAAAK,EAAAL,WAAAA,QACA5+G,MAAA+uC,QAAAxpC,GACAvF,KAAA+uC,QAAAgyB,gBACA/gE,KAAAS,KAAA,iBAAA8E,EAAAq5G,OAEA,IAAA57B,EAAAi8B,GAAA,CACA,IAAArgH,EAAAO,EAAAP,KAAA,GACA,GAAAqgH,EAAArgH,KAAAggH,GACAK,EAAArgH,GAAAggH,UAAAK,EAAArgH,GAAAggH,WAAAA,EAAA,CACAM,EAAAtgH,CACA,OAIA,GAAAsgH,EAAA,EACA,MAAAl/G,KAEA,KAAAi/G,EAAA9/G,QACA8/G,EAAA9/G,OAAA,QACAa,MAAA+uC,QAAAxpC,IAEA05G,EAAA3mE,OAAA4mE,EAAA,GAGAl/G,KAAA+uC,QAAAgyB,gBACA/gE,KAAAS,KAAA,iBAAA8E,EAAAq5G,GAGA,MAAA5+G,OAGA0a,EAAAzX,UAAA2iE,mBAAA,SAAArgE,GACA,GAAAye,GAAAowD,CAEA,KAAAp0E,KAAA+uC,QACA,MAAA/uC,KAGA,KAAAA,KAAA+uC,QAAAgyB,eAKA,MAJA,KAAA1gE,UAAAlB,OACAa,KAAA+uC,WACA/uC,KAAA+uC,QAAAxpC,UACAvF,MAAA+uC,QAAAxpC,GACAvF,IAIA,IAAA,IAAAK,UAAAlB,OAAA,CACA,IAAA6kB,IAAAhkB,MAAA+uC,QACA,mBAAA/qB,GACAhkB,KAAA4lE,mBAAA5hD,EAIA,OAFAhkB,MAAA4lE,mBAAA,kBACA5lE,KAAA+uC,WACA/uC,KAKA,GAFAo0E,EAAAp0E,KAAA+uC,QAAAxpC;qBAEA0E,EAAAmqE,GACAp0E,KAAA+gE,eAAAx7D,EAAA6uE,OACA,IAAAA,EAEA,KAAAA,EAAAj1E,QACAa,KAAA+gE,eAAAx7D,EAAA6uE,EAAAA,EAAAj1E,OAAA,GAIA,cAFAa,MAAA+uC,QAAAxpC,GAEAvF,MAGA0a,EAAAzX,UAAAmxE,UAAA,SAAA7uE,GAQA,MANAvF,MAAA+uC,SAAA/uC,KAAA+uC,QAAAxpC,GAEA0E,EAAAjK,KAAA+uC,QAAAxpC,KACAvF,KAAA+uC,QAAAxpC,IAEAvF,KAAA+uC,QAAAxpC,GAAAurB,YAIApW,EAAAzX,UAAAk8G,cAAA,SAAA55G,GACA,GAAAvF,KAAA+uC,QAAA,CACA,GAAAqwE,GAAAp/G,KAAA+uC,QAAAxpC,EAEA,IAAA0E,EAAAm1G,GACA,MAAA,EACA,IAAAA,EACA,MAAAA,GAAAjgH,OAEA,MAAA,IAGAub,EAAAykG,cAAA,SAAAE,EAAA95G,GACA,MAAA85G,GAAAF,cAAA55G,8BCjRA,QAAA+5G,KACA,KAAA,IAAAxgH,OAAA,mCAEA,QAAAygH,KACA,KAAA,IAAAzgH,OAAA,qCAsBA,QAAA0gH,GAAA5zC,GACA,GAAA6zC,IAAAzmG,WAEA,MAAAA,YAAA4yD,EAAA,EAGA,KAAA6zC,IAAAH,IAAAG,IAAAzmG,WAEA,MADAymG,GAAAzmG,WACAA,WAAA4yD,EAAA,EAEA,KAEA,MAAA6zC,GAAA7zC,EAAA,GACA,MAAAztE,GACA,IAEA,MAAAshH,GAAAvgH,KAAA,KAAA0sE,EAAA,GACA,MAAAztE,GAEA,MAAAshH,GAAAvgH,KAAAc,KAAA4rE,EAAA,KAMA,QAAA8zC,GAAAC,GACA,GAAAC,IAAA1vF,aAEA,MAAAA,cAAAyvF,EAGA,KAAAC,IAAAL,IAAAK,IAAA1vF,aAEA,MADA0vF,GAAA1vF,aACAA,aAAAyvF,EAEA,KAEA,MAAAC,GAAAD,GACA,MAAAxhH,GACA,IAEA,MAAAyhH,GAAA1gH,KAAA,KAAAygH,GACA,MAAAxhH,GAGA,MAAAyhH,GAAA1gH,KAAAc,KAAA2/G,KAYA,QAAAE,KACAC,GAAAC,IAGAD,GAAA,EACAC,EAAA5gH,OACAq8D,EAAAukD,EAAAp/G,OAAA66D,GAEAwkD,GAAA,EAEAxkD,EAAAr8D,QACA8gH,KAIA,QAAAA,KACA,IAAAH,EAAA,CAGA,GAAAv7F,GAAAi7F,EAAAK,EACAC,IAAA,CAGA,KADA,GAAAj0C,GAAArQ,EAAAr8D,OACA0sE,GAAA,CAGA,IAFAk0C,EAAAvkD,EACAA,OACAwkD,EAAAn0C,GACAk0C,GACAA,EAAAC,GAAAE,KAGAF,IAAA,EACAn0C,EAAArQ,EAAAr8D,OAEA4gH,EAAA,KACAD,GAAA,EACAJ,EAAAn7F,IAiBA,QAAA47F,GAAAv0C,EAAAvR,GACAr6D,KAAA4rE,IAAAA,EACA5rE,KAAAq6D,MAAAA,EAYA,QAAA+wC,MAhKA,GAOAqU,GACAG,EARAzjC,EAAA98E,EAAAJ,YAgBA,WACA,IAEAwgH,EADA,kBAAAzmG,YACAA,WAEAsmG,EAEA,MAAAnhH,GACAshH,EAAAH,EAEA,IAEAM,EADA,kBAAA1vF,cACAA,aAEAqvF,EAEA,MAAAphH,GACAyhH,EAAAL,KAuDA,IAEAQ,GAFAvkD,KACAskD,GAAA,EAEAE,GAAA,CAyCA7jC,GAAAgnB,SAAA,SAAAv3B,GACA,GAAAtrE,GAAA,GAAAC,OAAAF,UAAAlB,OAAA,EACA,IAAAkB,UAAAlB,OAAA,EACA,IAAA,GAAAP,GAAA,EAAAA,EAAAyB,UAAAlB,OAAAP,IACA0B,EAAA1B,EAAA,GAAAyB,UAAAzB,EAGA48D,GAAA5kD,KAAA,GAAAupG,GAAAv0C,EAAAtrE,IACA,IAAAk7D,EAAAr8D,QAAA2gH,GACAN,EAAAS,IASAE,EAAAl9G,UAAAi9G,IAAA,WACAlgH,KAAA4rE,IAAAlrE,MAAA,KAAAV,KAAAq6D,QAEA8hB,EAAAzoB,MAAA,UACAyoB,EAAAikC,SAAA,EACAjkC,EAAAgO,OACAhO,EAAAkkC,QACAlkC,EAAAvL,QAAA,GACAuL,EAAAguB,YAIAhuB,EAAAx6E,GAAAypG,EACAjvB,EAAAwiC,YAAAvT,EACAjvB,EAAA3lE,KAAA40F,EACAjvB,EAAAmkC,IAAAlV,EACAjvB,EAAApb,eAAAqqC,EACAjvB,EAAAvW,mBAAAwlC,EACAjvB,EAAA17E,KAAA2qG,EACAjvB,EAAAokC,gBAAAnV,EACAjvB,EAAAqkC,oBAAApV,EAEAjvB,EAAA/H,UAAA,SAAA7yD,GAAA,UAEA46D,EAAAskC,QAAA,SAAAl/F,GACA,KAAA,IAAAziB,OAAA,qCAGAq9E,EAAAukC,IAAA,WAAA,MAAA,KACAvkC,EAAAwkC,MAAA,SAAAr5F,GACA,KAAA,IAAAxoB,OAAA,mCAEAq9E,EAAAykC,MAAA,WAAA,MAAA,4CCtLA,SAAAtW,GAgEA,QAAA51F,GAAAnP,GACA,KAAA,IAAA0qF,YAAAgE,EAAA1uF,IAWA,QAAA4a,GAAAk6C,EAAAuB,GAGA,IAFA,GAAAz8D,GAAAk7D,EAAAl7D,OACA2tB,KACA3tB,KACA2tB,EAAA3tB,GAAAy8D,EAAAvB,EAAAl7D,GAEA,OAAA2tB,GAaA,QAAA+zF,GAAAlrD,EAAAiG,GACA,GAAAvD,GAAA1C,EAAA95C,MAAA,KACAiR,EAAA,EAWA,OAVAurC,GAAAl5D,OAAA,IAGA2tB,EAAAurC,EAAA,GAAA,IACA1C,EAAA0C,EAAA,IAGA1C,EAAAA,EAAAh6C,QAAAmlG,EAAA,KAGAh0F,EADA3M,EADAw1C,EAAA95C,MAAA,KACA+/C,GAAAx5B,KAAA,KAiBA,QAAA2+E,GAAAprD,GAMA,IALA,GAGAp0D,GACAy/G,EAJAC,KACAC,EAAA,EACA/hH,EAAAw2D,EAAAx2D,OAGA+hH,EAAA/hH,GACAoC,EAAAo0D,EAAA04C,WAAA6S,KACA3/G,GAAA,OAAAA,GAAA,OAAA2/G,EAAA/hH,GAEA6hH,EAAArrD,EAAA04C,WAAA6S,KACA,QAAA,MAAAF,GACAC,EAAArqG,OAAA,KAAArV,IAAA,KAAA,KAAAy/G,GAAA,QAIAC,EAAArqG,KAAArV,GACA2/G,MAGAD,EAAArqG,KAAArV,EAGA,OAAA0/G,GAWA,QAAAE,GAAA9mD,GACA,MAAAl6C,GAAAk6C,EAAA,SAAA94D,GACA,GAAA0/G,GAAA,EAOA,OANA1/G,GAAA,QACAA,GAAA,MACA0/G,GAAAG,EAAA7/G,IAAA,GAAA,KAAA,OACAA,EAAA,MAAA,KAAAA,GAEA0/G,GAAAG,EAAA7/G,KAEA6gC,KAAA,IAYA,QAAAi/E,GAAAC,GACA,MAAAA,GAAA,GAAA,GACAA,EAAA,GAEAA,EAAA,GAAA,GACAA,EAAA,GAEAA,EAAA,GAAA,GACAA,EAAA,GAEA/7E,EAcA,QAAAg8E,GAAAC,EAAAC,GAGA,MAAAD,GAAA,GAAA,IAAAA,EAAA,MAAA,GAAAC,IAAA,GAQA,QAAAC,GAAAz2C,EAAA02C,EAAAC,GACA,GAAAv8E,GAAA,CAGA,KAFA4lC,EAAA22C,EAAAlxF,EAAAu6C,EAAA42C,GAAA52C,GAAA,EACAA,GAAAv6C,EAAAu6C,EAAA02C,GACA12C,EAAA62C,EAAAC,GAAA,EAAA18E,GAAAE,EACA0lC,EAAAv6C,EAAAu6C,EAAA62C,EAEA,OAAApxF,GAAA2U,GAAAy8E,EAAA,GAAA72C,GAAAA,EAAA+2C,IAUA,QAAAC,GAAAra,GAEA,GAEAuN,GAIA+M,EACAr2E,EACA+K,EACAurE,EACA/rC,EACA/wC,EACAm8E,EACApjH,EAEAgkH,EAfAnB,KACAoB,EAAAza,EAAAzoG,OAEAP,EAAA,EACAP,EAAAikH,EACAC,EAAAC,CAqBA,KALAN,EAAAta,EAAA6a,YAAAC,GACAR,EAAA,IACAA,EAAA,GAGAr2E,EAAA,EAAAA,EAAAq2E,IAAAr2E,EAEA+7D,EAAAyG,WAAAxiE,IAAA,KACAn3B,EAAA,aAEAusG,EAAArqG,KAAAgxF,EAAAyG,WAAAxiE,GAMA,KAAA+K,EAAAsrE,EAAA,EAAAA,EAAA,EAAA,EAAAtrE,EAAAyrE,GAAA,CAOA,IAAAF,EAAAvjH,EAAAw3E,EAAA,EAAA/wC,EAAAE,EAEAqR,GAAAyrE,GACA3tG,EAAA,iBAGA8sG,EAAAH,EAAAzZ,EAAAyG,WAAAz3D,OAEA4qE,GAAAj8E,GAAAi8E,EAAA9wF,GAAAiyF,EAAA/jH,GAAAw3E,KACA1hE,EAAA,YAGA9V,GAAA4iH,EAAAprC,EACAh4E,EAAAinC,GAAAk9E,EAAAK,EAAAv9E,GAAAk9E,EAAAR,EAAAA,EAAA18E,EAAAk9E,IAEAf,EAAApjH,GAfAinC,GAAAE,EAmBA68E,EAAA78E,EAAAnnC,EACAg4E,EAAA1lD,EAAAiyF,EAAAP,IACA1tG,EAAA,YAGA0hE,GAAAgsC,CAIAjN,GAAA8L,EAAA9hH,OAAA,EACAojH,EAAAb,EAAA9iH,EAAAujH,EAAAhN,EAAA,GAAAgN,GAIAzxF,EAAA9xB,EAAAu2G,GAAAwN,EAAAtkH,GACAqW,EAAA,YAGArW,GAAAqyB,EAAA9xB,EAAAu2G,GACAv2G,GAAAu2G,EAGA8L,EAAA3oE,OAAA15C,IAAA,EAAAP,GAIA,MAAA8iH,GAAAF,GAUA,QAAA4B,GAAAjb,GACA,GAAAvpG,GACA4sE,EACA63C,EACAC,EACAR,EACA12E,EACA2E,EACAwyE,EACA39E,EACAjnC,EACA6kH,EAGAZ,EAEAa,EACAd,EACAe,EANAlC,IAoBA,KAXArZ,EAAAmZ,EAAAnZ,GAGAya,EAAAza,EAAAzoG,OAGAd,EAAAikH,EACAr3C,EAAA,EACAs3C,EAAAC,EAGA32E,EAAA,EAAAA,EAAAw2E,IAAAx2E,GACAo3E,EAAArb,EAAA/7D,IACA,KACAo1E,EAAArqG,KAAAwqG,EAAA6B,GAeA,KAXAH,EAAAC,EAAA9B,EAAA9hH,OAMA4jH,GACA9B,EAAArqG,KAAA8rG,GAIAI,EAAAT,GAAA,CAIA,IAAA7xE,EAAAmyE,EAAA92E,EAAA,EAAAA,EAAAw2E,IAAAx2E,GACAo3E,EAAArb,EAAA/7D,KACAxtC,GAAA4kH,EAAAzyE,IACAA,EAAAyyE,EAcA,KARAC,EAAAJ,EAAA,EACAtyE,EAAAnyC,EAAAqyB,GAAAiyF,EAAA13C,GAAAi4C,IACAxuG,EAAA,YAGAu2D,IAAAz6B,EAAAnyC,GAAA6kH,EACA7kH,EAAAmyC,EAEA3E,EAAA,EAAAA,EAAAw2E,IAAAx2E,EAOA,GANAo3E,EAAArb,EAAA/7D,GAEAo3E,EAAA5kH,KAAA4sE,EAAA03C,GACAjuG,EAAA,YAGAuuG,GAAA5kH,EAAA,CAEA,IAAA2kH,EAAA/3C,EAAA5lC,EAAAE,EACAnnC,EAAAinC,GAAAk9E,EAAAK,EAAAv9E,GAAAk9E,EAAAR,EAAAA,EAAA18E,EAAAk9E,IACAS,EAAA5kH,GAFAinC,GAAAE,EAKA49E,EAAAH,EAAA5kH,EACAgkH,EAAA78E,EAAAnnC,EACA6iH,EAAArqG,KACAwqG,EAAAG,EAAAnjH,EAAA+kH,EAAAf,EAAA,KAEAY,EAAAtyF,EAAAyyF,EAAAf,EAGAnB,GAAArqG,KAAAwqG,EAAAG,EAAAyB,EAAA,KACAT,EAAAb,EAAAz2C,EAAAi4C,EAAAJ,GAAAC,GACA93C,EAAA,IACA63C,IAIA73C,IACA5sE,EAGA,MAAA4iH,GAAA7+E,KAAA,IAcA,QAAAghF,GAAAxb,GACA,MAAAiZ,GAAAjZ,EAAA,SAAAjyC,GACA,MAAA0tD,GAAAx8B,KAAAlxB,GACAssD,EAAAtsD,EAAA7kC,MAAA,GAAA+6D,eACAl2B,IAeA,QAAA2tD,GAAA1b,GACA,MAAAiZ,GAAAjZ,EAAA,SAAAjyC,GACA,MAAA4tD,GAAA18B,KAAAlxB,GACA,OAAAktD,EAAAltD,GACAA,IAvdA,GAAA6tD,GAAA,gBAAAvkH,IAAAA,IACAA,EAAAwkH,UAAAxkH,EACAykH,EAAA,gBAAArkH,IAAAA,IACAA,EAAAokH,UAAApkH,EACAskH,EAAA,gBAAAlkH,IAAAA,CAEAkkH,GAAAlkH,SAAAkkH,GACAA,EAAAjuC,SAAAiuC,GACAA,EAAAtyG,OAAAsyG,IAEArZ,EAAAqZ,EAQA,IAAAC,GAiCA5/F,EA9BA2+F,EAAA,WAGAp9E,EAAA,GACAq9E,EAAA,EACAb,EAAA,GACAC,EAAA,GACAH,EAAA,IACAW,EAAA,GACAF,EAAA,IACAI,EAAA,IAGAW,EAAA,QACAE,EAAA,eACAzC,EAAA,4BAGA7sB,GACA4vB,SAAA,kDACAC,YAAA,iDACAC,gBAAA,iBAIAjC,EAAAv8E,EAAAq9E,EACAlyF,EAAAzJ,KAAAyJ,MACA0wF,EAAAxpC,OAAAC,YAycA,IA3BA+rC,GAMAhzC,QAAA,QAQAozC,MACA/B,OAAAlB,EACA8B,OAAA1B,GAEAc,OAAAA,EACAY,OAAAA,EACAS,QAAAA,EACAF,UAAAA,GAOA,kBAAAvpC,SACA,gBAAAA,QAAAC,KACAD,OAAAC,IAEAD,OAAA,WAAA,WACA,MAAA+pC,SAEA,IAAAJ,GAAAE,EACA,GAAArkH,EAAAJ,SAAAukH,EAEAE,EAAAzkH,QAAA2kH,MAGA,KAAA5/F,IAAA4/F,GACAA,EAAA/xF,eAAA7N,KAAAw/F,EAAAx/F,GAAA4/F,EAAA5/F,QAKAsmF,GAAAsZ,SAAAA,GAGA5jH,kJC/fA,YAKA,SAAA6xB,GAAA+a,EAAAC,GACA,MAAAL,QAAAvpC,UAAA4uB,eAAA3yB,KAAA0tC,EAAAC,GAGAxtC,EAAAJ,QAAA,SAAA2+C,EAAA85B,EAAAusC,EAAAp9G,GACA6wE,EAAAA,GAAA,IACAusC,EAAAA,GAAA,GACA,IAAAr3E,KAEA,IAAA,gBAAAgR,IAAA,IAAAA,EAAAz+C,OACA,MAAAytC,EAGA,IAAAs3E,GAAA,KACAtmE,GAAAA,EAAA/hC,MAAA67D,EAEA,IAAAysC,GAAA,GACAt9G,IAAA,gBAAAA,GAAAs9G,UACAA,EAAAt9G,EAAAs9G,QAGA,IAAAt4C,GAAAjuB,EAAAz+C,MAEAglH,GAAA,GAAAt4C,EAAAs4C,IACAt4C,EAAAs4C,EAGA,KAAA,GAAAvlH,GAAA,EAAAA,EAAAitE,IAAAjtE,EAAA,CACA,GAEAwlH,GAAAC,EAAAh/E,EAAAmU,EAFA+xB,EAAA3tB,EAAAh/C,GAAA+c,QAAAuoG,EAAA,OACA98D,EAAAmkB,EAAAl1D,QAAA4tG,EAGA78D,IAAA,GACAg9D,EAAA74C,EAAAz6D,OAAA,EAAAs2C,GACAi9D,EAAA94C,EAAAz6D,OAAAs2C,EAAA,KAEAg9D,EAAA74C,EACA84C,EAAA,IAGAh/E,EAAAi/E,mBAAAF,GACA5qE,EAAA8qE,mBAAAD,GAEAxyF,EAAA+a,EAAAvH,GAEAkF,EAAAqC,EAAAvH,IACAuH,EAAAvH,GAAAzuB,KAAA4iC,GAEA5M,EAAAvH,IAAAuH,EAAAvH,GAAAmU,GAJA5M,EAAAvH,GAAAmU,EAQA,MAAA5M,GAGA,IAAArC,GAAAhqC,MAAAgqC,SAAA,SAAAg6E,GACA,MAAA,mBAAA/3E,OAAAvpC,UAAAwmC,SAAAvqC,KAAAqlH,8BC7DA,YAgDA,SAAApkG,GAAAokG,EAAA1lH,GACA,GAAA0lH,EAAApkG,IAAA,MAAAokG,GAAApkG,IAAAthB,EAEA,KAAA,GADAwV,MACAzV,EAAA,EAAAA,EAAA2lH,EAAAplH,OAAAP,IACAyV,EAAAuC,KAAA/X,EAAA0lH,EAAA3lH,GAAAA,GAEA,OAAAyV,GApDA,GAAAmwG,GAAA,SAAAhrE,GACA,aAAAA,IACA,IAAA,SACA,MAAAA,EAEA,KAAA,UACA,MAAAA,GAAA,OAAA,OAEA,KAAA,SACA,MAAA/J,UAAA+J,GAAAA,EAAA,EAEA,SACA,MAAA,IAIAn6C,GAAAJ,QAAA,SAAA2tC,EAAA8qC,EAAAusC,EAAA1iG,GAOA,MANAm2D,GAAAA,GAAA,IACAusC,EAAAA,GAAA,IACA,OAAAr3E,IACAA,MAAA3rC,IAGA,gBAAA2rC,GACAzsB,EAAAskG,EAAA73E,GAAA,SAAAvH,GACA,GAAAq/E,GAAAxnE,mBAAAsnE,EAAAn/E,IAAA4+E,CACA,OAAA15E,GAAAqC,EAAAvH,IACAllB,EAAAysB,EAAAvH,GAAA,SAAAmU,GACA,MAAAkrE,GAAAxnE,mBAAAsnE,EAAAhrE,MACApX,KAAAs1C,GAEAgtC,EAAAxnE,mBAAAsnE,EAAA53E,EAAAvH,OAEAjD,KAAAs1C,GAIAn2D,EACA27B,mBAAAsnE,EAAAjjG,IAAA0iG,EACA/mE,mBAAAsnE,EAAA53E,IAFA,GAKA,IAAArC,GAAAhqC,MAAAgqC,SAAA,SAAAg6E,GACA,MAAA,mBAAA/3E,OAAAvpC,UAAAwmC,SAAAvqC,KAAAqlH,IAYAE,EAAAj4E,OAAAltB,MAAA,SAAAstB,GACA,GAAAv4B,KACA,KAAA,GAAA2P,KAAA4oB,GACAJ,OAAAvpC,UAAA4uB,eAAA3yB,KAAA0tC,EAAA5oB,IAAA3P,EAAAuC,KAAAoN,EAEA,OAAA3P,8BCnFA,YAEApV,GAAAgjH,OAAAhjH,EAAA+sB,MAAArtB,EAAA,YACAM,EAAA4jH,OAAA5jH,EAAA40C,UAAAl1C,EAAA,mECDA,GAAAogH,GAAA,WAAA,MAAA/+G,UAAAypG,SAAA,iBAIAkb,EAAA5F,EAAA6F,oBACAp4E,OAAAqkD,oBAAAkuB,GAAA1oG,QAAA,uBAAA,EAGAwuG,EAAAF,GAAA5F,EAAA6F,kBAOA,IAJA7F,EAAA6F,uBAAA3jH,GAEA5B,EAAAJ,QAAAN,EAAA,aAEAgmH,EAEA5F,EAAA6F,mBAAAC,MAGA,WACA9F,GAAA6F,mBACA,MAAAzmH,GACA4gH,EAAA6F,uBAAA3jH,8CCfA,SAAAxB,GACA,YA2BA,SAAAwa,GAAA6qG,EAAAC,EAAA1zG,EAAA2zG,GAEA,GAAAC,GAAAF,GAAAA,EAAA9hH,oBAAAiiH,GAAAH,EAAAG,EACAlwB,EAAAxoD,OAAA1U,OAAAmtF,EAAAhiH,WACAyxD,EAAA,GAAA0uB,GAAA4hC,MAMA,OAFAhwB,GAAAmwB,QAAAC,EAAAN,EAAAzzG,EAAAqjD,GAEAsgC,EAcA,QAAA7U,GAAAvkB,EAAAhvB,EAAAyuC,GACA,IACA,OAAA91E,KAAA,SAAA81E,IAAAzf,EAAA18D,KAAA0tC,EAAAyuC,IACA,MAAAz5E,GACA,OAAA2D,KAAA,QAAA81E,IAAAz5E,IAiBA,QAAAsjH,MACA,QAAAG,MACA,QAAAC,MA4BA,QAAAC,GAAAtiH,IACA,OAAA,QAAA,UAAAwL,QAAA,SAAAyH,GACAjT,EAAAiT,GAAA,SAAAmlE,GACA,MAAAr7E,MAAAmlH,QAAAjvG,EAAAmlE,MAoCA,QAAAmqC,GAAAxwB,GACA,QAAAvY,GAAAvmE,EAAAmlE,EAAAvnE,EAAAqF,GACA,GAAAssG,GAAAtlC,EAAA6U,EAAA9+E,GAAA8+E,EAAA3Z,EACA,IAAA,UAAAoqC,EAAAlgH,KAEA,CACA,GAAAunB,GAAA24F,EAAApqC,IACA95E,EAAAurB,EAAAvrB,KACA,OAAAA,IACA,gBAAAA,IACAgrE,EAAArtE,KAAAqC,EAAA,WACAw4E,QAAAjmE,QAAAvS,EAAAmkH,SAAA9hH,KAAA,SAAArC,GACAk7E,EAAA,OAAAl7E,EAAAuS,EAAAqF,IACA,SAAAvX,GACA66E,EAAA,QAAA76E,EAAAkS,EAAAqF,KAIA4gE,QAAAjmE,QAAAvS,GAAAqC,KAAA,SAAA+hH,GAgBA74F,EAAAvrB,MAAAokH,EACA7xG,EAAAgZ,IACA3T,GAhCAA,EAAAssG,EAAApqC,KAsCA,QAAAuqC,GAAA1vG,EAAAmlE,GACA,QAAAwqC,KACA,MAAA,IAAA9rC,SAAA,SAAAjmE,EAAAqF,GACAsjE,EAAAvmE,EAAAmlE,EAAAvnE,EAAAqF,KAIA,MAAA2sG,GAaAA,EAAAA,EAAAliH,KACAiiH,EAGAA,GACAA,IA3BA,GAAAC,EAgCA9lH,MAAAmlH,QAAAS,EAwBA,QAAAR,GAAAN,EAAAzzG,EAAAqjD,GACA,GAAAx9C,GAAA6uG,CAEA,OAAA,UAAA7vG,EAAAmlE,GACA,GAAAnkE,IAAA8uG,EACA,KAAA,IAAAlnH,OAAA,+BAGA,IAAAoY,IAAA+uG,EAAA,CACA,GAAA,UAAA/vG,EACA,KAAAmlE,EAKA,OAAA6qC,KAMA,IAHAxxD,EAAAx+C,OAAAA,EACAw+C,EAAA2mB,IAAAA,IAEA,CACA,GAAA8qC,GAAAzxD,EAAAyxD,QACA,IAAAA,EAAA,CACA,GAAAC,GAAAC,EAAAF,EAAAzxD,EACA,IAAA0xD,EAAA,CACA,GAAAA,IAAAE,EAAA,QACA,OAAAF,IAIA,GAAA,SAAA1xD,EAAAx+C,OAGAw+C,EAAAp6C,KAAAo6C,EAAA6xD,MAAA7xD,EAAA2mB,QAEA,IAAA,UAAA3mB,EAAAx+C,OAAA,CACA,GAAAgB,IAAA6uG,EAEA,KADA7uG,GAAA+uG,EACAvxD,EAAA2mB,GAGA3mB,GAAA8xD,kBAAA9xD,EAAA2mB,SAEA,WAAA3mB,EAAAx+C,QACAw+C,EAAA33C,OAAA,SAAA23C,EAAA2mB,IAGAnkE,GAAA8uG,CAEA,IAAAP,GAAAtlC,EAAA2kC,EAAAzzG,EAAAqjD,EACA,IAAA,WAAA+wD,EAAAlgH,KAAA,CAOA,GAJA2R,EAAAw9C,EAAApzD,KACA2kH,EACAQ,EAEAhB,EAAApqC,MAAAirC,EACA,QAGA,QACA/kH,MAAAkkH,EAAApqC,IACA/5E,KAAAozD,EAAApzD,MAGA,UAAAmkH,EAAAlgH,OACA2R,EAAA+uG,EAGAvxD,EAAAx+C,OAAA,QACAw+C,EAAA2mB,IAAAoqC,EAAApqC,OAUA,QAAAgrC,GAAAF,EAAAzxD,GACA,GAAAx+C,GAAAiwG,EAAAnf,SAAAtyC,EAAAx+C,OACA,IAAAA,IAAAjV,EAAA,CAKA,GAFAyzD,EAAAyxD,SAAA,KAEA,UAAAzxD,EAAAx+C,OAAA,CACA,GAAAiwG,EAAAnf,SAAAnlG,SAGA6yD,EAAAx+C,OAAA,SACAw+C,EAAA2mB,IAAAp6E,EACAolH,EAAAF,EAAAzxD,GAEA,UAAAA,EAAAx+C,QAGA,MAAAowG,EAIA5xD,GAAAx+C,OAAA,QACAw+C,EAAA2mB,IAAA,GAAA3rC,WACA,kDAGA,MAAA42E,GAGA,GAAAb,GAAAtlC,EAAAjqE,EAAAiwG,EAAAnf,SAAAtyC,EAAA2mB,IAEA,IAAA,UAAAoqC,EAAAlgH,KAIA,MAHAmvD,GAAAx+C,OAAA,QACAw+C,EAAA2mB,IAAAoqC,EAAApqC,IACA3mB,EAAAyxD,SAAA,KACAG,CAGA,IAAAr6G,GAAAw5G,EAAApqC,GAEA,OAAApvE,GAOAA,EAAA3K,MAGAozD,EAAAyxD,EAAAO,YAAAz6G,EAAA1K,MAGAmzD,EAAArzD,KAAA8kH,EAAAQ,QAQA,WAAAjyD,EAAAx+C,SACAw+C,EAAAx+C,OAAA,OACAw+C,EAAA2mB,IAAAp6E,GAUAyzD,EAAAyxD,SAAA,KACAG,GANAr6G,GA3BAyoD,EAAAx+C,OAAA,QACAw+C,EAAA2mB,IAAA,GAAA3rC,WAAA,oCACAglB,EAAAyxD,SAAA,KACAG,GAoDA,QAAAM,GAAAC,GACA,GAAA9T,IAAA+T,OAAAD,EAAA,GAEA,KAAAA,KACA9T,EAAAgU,SAAAF,EAAA,IAGA,IAAAA,KACA9T,EAAAiU,WAAAH,EAAA,GACA9T,EAAAkU,SAAAJ,EAAA,IAGA7mH,KAAAknH,WAAAtwG,KAAAm8F,GAGA,QAAAoU,GAAApU,GACA,GAAA0S,GAAA1S,EAAAqU,cACA3B,GAAAlgH,KAAA,eACAkgH,GAAApqC,IACA03B,EAAAqU,WAAA3B,EAGA,QAAAriC,GAAA4hC,GAIAhlH,KAAAknH,aAAAJ,OAAA,SACA9B,EAAAv2G,QAAAm4G,EAAA5mH,MACAA,KAAAqnH,OAAA,GA8BA,QAAA5vG,GAAA27F,GACA,GAAAA,EAAA,CACA,GAAAkU,GAAAlU,EAAAmU,EACA,IAAAD,EACA,MAAAA,GAAApoH,KAAAk0G,EAGA,IAAA,kBAAAA,GAAA/xG,KACA,MAAA+xG,EAGA,KAAAz7C,MAAAy7C,EAAAj0G,QAAA,CACA,GAAAP,IAAA,EAAAyC,EAAA,QAAAA,KACA,OAAAzC,EAAAw0G,EAAAj0G,QACA,GAAAotE,EAAArtE,KAAAk0G,EAAAx0G,GAGA,MAFAyC,GAAAE,MAAA6xG,EAAAx0G,GACAyC,EAAAC,MAAA,EACAD,CAOA,OAHAA,GAAAE,MAAAN,EACAI,EAAAC,MAAA,EAEAD,EAGA,OAAAA,GAAAA,KAAAA,GAKA,OAAAA,KAAA6kH,GAIA,QAAAA,KACA,OAAA3kH,MAAAN,EAAAK,MAAA,GA7fA,GAEAL,GAFAumH,EAAAh7E,OAAAvpC,UACAspE,EAAAi7C,EAAA31F,eAEAqpF,EAAA,kBAAArR,QAAAA,UACA0d,EAAArM,EAAAlU,UAAA,aACAygB,EAAAvM,EAAAwM,eAAA,kBACAC,EAAAzM,EAAA0M,aAAA,gBAEAC,EAAA,gBAAAxoH,GACAyoH,EAAAroH,EAAAmlH,kBACA,IAAAkD,EAQA,YAPAD,IAGAxoH,EAAAJ,QAAA6oH,GASAA,GAAAroH,EAAAmlH,mBAAAiD,EAAAxoH,EAAAJ,WAcA6oH,EAAA7tG,KAAAA,CAoBA,IAAA8rG,GAAA,iBACAU,EAAA,iBACAT,EAAA,YACAC,EAAA,YAIAK,KAYA3P,IACAA,GAAA4Q,GAAA,WACA,MAAAvnH,MAGA,IAAA+nH,GAAAv7E,OAAAskD,eACAk3B,EAAAD,GAAAA,EAAAA,EAAAtwG,OACAuwG,IACAA,IAAAR,GACAj7C,EAAArtE,KAAA8oH,EAAAT,KAGA5Q,EAAAqR,EAGA,IAAAC,GAAA3C,EAAAriH,UACAiiH,EAAAjiH,UAAAupC,OAAA1U,OAAA6+E,EACA0O,GAAApiH,UAAAglH,EAAArpE,YAAA0mE,EACAA,EAAA1mE,YAAAymE,EACAC,EAAAqC,GACAtC,EAAAz5D,YAAA,oBAYAk8D,EAAAI,oBAAA,SAAAC,GACA,GAAA/7C,GAAA,kBAAA+7C,IAAAA,EAAAvpE,WACA,SAAAwtB,IACAA,IAAAi5C,GAGA,uBAAAj5C,EAAAxgB,aAAAwgB,EAAA7qD,QAIAumG,EAAAnrG,KAAA,SAAAwrG,GAUA,MATA37E,QAAAyjE,eACAzjE,OAAAyjE,eAAAkY,EAAA7C,IAEA6C,EAAAhjF,UAAAmgF,EACAqC,IAAAQ,KACAA,EAAAR,GAAA,sBAGAQ,EAAAllH,UAAAupC,OAAA1U,OAAAmwF,GACAE,GAOAL,EAAAM,MAAA,SAAA/sC,GACA,OAAAqqC,QAAArqC,IA8EAkqC,EAAAC,EAAAviH,WACAuiH,EAAAviH,UAAAwkH,GAAA,WACA,MAAAznH,OAEA8nH,EAAAtC,cAAAA,EAKAsC,EAAAznC,MAAA,SAAAykC,EAAAC,EAAA1zG,EAAA2zG,GACA,GAAA3U,GAAA,GAAAmV,GACAvrG,EAAA6qG,EAAAC,EAAA1zG,EAAA2zG,GAGA,OAAA8C,GAAAI,oBAAAnD,GACA1U,EACAA,EAAAhvG,OAAAuC,KAAA,SAAAkpB,GACA,MAAAA,GAAAxrB,KAAAwrB,EAAAvrB,MAAA8uG,EAAAhvG,UAsKAkkH,EAAA0C,GAEAA,EAAAN,GAAA,YAOAM,EAAAV,GAAA,WACA,MAAAvnH,OAGAioH,EAAAx+E,SAAA,WACA,MAAA,sBAkCAq+E,EAAAxoG,KAAA,SAAAq4D,GACA,GAAAr4D,KACA,KAAA,GAAA0E,KAAA2zD,GACAr4D,EAAA1I,KAAAoN,EAMA,OAJA1E,GAAAgJ,UAIA,QAAAjnB,KACA,KAAAie,EAAAngB,QAAA,CACA,GAAA6kB,GAAA1E,EAAA+/D,KACA,IAAAr7D,IAAA2zD,GAGA,MAFAt2E,GAAAE,MAAAyiB,EACA3iB,EAAAC,MAAA,EACAD,EAQA,MADAA,GAAAC,MAAA,EACAD,IAsCAymH,EAAArwG,OAAAA,EAMA2rE,EAAAngF,WACA27C,YAAAwkC,EAEAikC,MAAA,SAAAgB,GAcA,GAbAroH,KAAAma,KAAA,EACAna,KAAAqB,KAAA,EAGArB,KAAAsa,KAAAta,KAAAumH,MAAAtlH,EACAjB,KAAAsB,MAAA,EACAtB,KAAAmmH,SAAA,KAEAnmH,KAAAkW,OAAA,OACAlW,KAAAq7E,IAAAp6E,EAEAjB,KAAAknH,WAAAz4G,QAAA04G,IAEAkB,EACA,IAAA,GAAA9mG,KAAAvhB,MAEA,MAAAuhB,EAAAkP,OAAA,IACA87C,EAAArtE,KAAAc,KAAAuhB,KACAo2C,OAAAp2C,EAAAuP,MAAA,MACA9wB,KAAAuhB,GAAAtgB,IAMAsZ,KAAA,WACAva,KAAAsB,MAAA,CAEA,IAAAgnH,GAAAtoH,KAAAknH,WAAA,GACAqB,EAAAD,EAAAlB,UACA,IAAA,UAAAmB,EAAAhjH,KACA,KAAAgjH,GAAAltC,GAGA,OAAAr7E,MAAAwoH,MAGAhC,kBAAA,SAAAiC,GAMA,QAAAxiB,GAAAyiB,EAAAj6B,GAYA,MAXAg3B,GAAAlgH,KAAA,QACAkgH,EAAApqC,IAAAotC,EACA/zD,EAAArzD,KAAAqnH,EAEAj6B,IAGA/5B,EAAAx+C,OAAA,OACAw+C,EAAA2mB,IAAAp6E,KAGAwtF,EAjBA,GAAAzuF,KAAAsB,KACA,KAAAmnH,EAmBA,KAAA,GAhBA/zD,GAAA10D,KAgBApB,EAAAoB,KAAAknH,WAAA/nH,OAAA,EAAAP,GAAA,IAAAA,EAAA,CACA,GAAAm0G,GAAA/yG,KAAAknH,WAAAtoH,GACA6mH,EAAA1S,EAAAqU,UAEA,IAAA,SAAArU,EAAA+T,OAIA,MAAA7gB,GAAA,MAGA,IAAA8M,EAAA+T,QAAA9mH,KAAAma,KAAA,CACA,GAAAwuG,GAAAp8C,EAAArtE,KAAA6zG,EAAA,YACA6V,EAAAr8C,EAAArtE,KAAA6zG,EAAA,aAEA,IAAA4V,GAAAC,EAAA,CACA,GAAA5oH,KAAAma,KAAA44F,EAAAgU,SACA,MAAA9gB,GAAA8M,EAAAgU,UAAA,EACA,IAAA/mH,KAAAma,KAAA44F,EAAAiU,WACA,MAAA/gB,GAAA8M,EAAAiU,gBAGA,IAAA2B,GACA,GAAA3oH,KAAAma,KAAA44F,EAAAgU,SACA,MAAA9gB,GAAA8M,EAAAgU,UAAA,OAGA,CAAA,IAAA6B,EAMA,KAAA,IAAA9pH,OAAA,yCALA,IAAAkB,KAAAma,KAAA44F,EAAAiU,WACA,MAAA/gB,GAAA8M,EAAAiU,gBAUAjqG,OAAA,SAAAxX,EAAA81E,GACA,IAAA,GAAAz8E,GAAAoB,KAAAknH,WAAA/nH,OAAA,EAAAP,GAAA,IAAAA,EAAA,CACA,GAAAm0G,GAAA/yG,KAAAknH,WAAAtoH,EACA,IAAAm0G,EAAA+T,QAAA9mH,KAAAma,MACAoyD,EAAArtE,KAAA6zG,EAAA,eACA/yG,KAAAma,KAAA44F,EAAAiU,WAAA,CACA,GAAA6B,GAAA9V,CACA,QAIA8V,IACA,UAAAtjH,GACA,aAAAA,IACAsjH,EAAA/B,QAAAzrC,GACAA,GAAAwtC,EAAA7B,aAGA6B,EAAA,KAGA,IAAApD,GAAAoD,EAAAA,EAAAzB,aAIA,OAHA3B,GAAAlgH,KAAAA,EACAkgH,EAAApqC,IAAAA,EAEAwtC,GACA7oH,KAAAkW,OAAA,OACAlW,KAAAqB,KAAAwnH,EAAA7B,WACAV,GAGAtmH,KAAA8oH,SAAArD,IAGAqD,SAAA,SAAArD,EAAAwB,GACA,GAAA,UAAAxB,EAAAlgH,KACA,KAAAkgH,GAAApqC,GAcA,OAXA,UAAAoqC,EAAAlgH,MACA,aAAAkgH,EAAAlgH,KACAvF,KAAAqB,KAAAokH,EAAApqC,IACA,WAAAoqC,EAAAlgH,MACAvF,KAAAwoH,KAAAxoH,KAAAq7E,IAAAoqC,EAAApqC,IACAr7E,KAAAkW,OAAA,SACAlW,KAAAqB,KAAA,OACA,WAAAokH,EAAAlgH,MAAA0hH,IACAjnH,KAAAqB,KAAA4lH,GAGAX,GAGAjzE,OAAA,SAAA2zE,GACA,IAAA,GAAApoH,GAAAoB,KAAAknH,WAAA/nH,OAAA,EAAAP,GAAA,IAAAA,EAAA,CACA,GAAAm0G,GAAA/yG,KAAAknH,WAAAtoH,EACA,IAAAm0G,EAAAiU,aAAAA,EAGA,MAFAhnH,MAAA8oH,SAAA/V,EAAAqU,WAAArU,EAAAkU,UACAE,EAAApU,GACAuT,IAKAhjF,MAAA,SAAAwjF,GACA,IAAA,GAAAloH,GAAAoB,KAAAknH,WAAA/nH,OAAA,EAAAP,GAAA,IAAAA,EAAA,CACA,GAAAm0G,GAAA/yG,KAAAknH,WAAAtoH,EACA,IAAAm0G,EAAA+T,SAAAA,EAAA,CACA,GAAArB,GAAA1S,EAAAqU,UACA,IAAA,UAAA3B,EAAAlgH,KAAA,CACA,GAAAwjH,GAAAtD,EAAApqC,GACA8rC,GAAApU,GAEA,MAAAgW,IAMA,KAAA,IAAAjqH,OAAA,0BAGAkqH,cAAA,SAAA5V,EAAAsT,EAAAC,GAaA,MAZA3mH,MAAAmmH,UACAnf,SAAAvvF,EAAA27F,GACAsT,WAAAA,EACAC,QAAAA,GAGA,SAAA3mH,KAAAkW,SAGAlW,KAAAq7E,IAAAp6E,GAGAqlH,KAOA,WAAA,MAAAtmH,UAAAypG,SAAA,4CCnsBA,YAYA,SAAAwf,KACAjpH,KAAA0Q,SAAA,KACA1Q,KAAAkpH,QAAA,KACAlpH,KAAAkE,KAAA,KACAlE,KAAAisB,KAAA,KACAjsB,KAAAmpH,KAAA,KACAnpH,KAAAopH,SAAA,KACAppH,KAAAqpH,KAAA,KACArpH,KAAAiO,OAAA,KACAjO,KAAA8O,MAAA,KACA9O,KAAAspH,SAAA,KACAtpH,KAAAyG,KAAA,KACAzG,KAAAstG,KAAA,KAwDA,QAAAic,GAAA5uG,EAAA6uG,EAAAC,GACA,GAAA9uG,GAAAknB,EAAAmhD,SAAAroE,IAAAA,YAAAsuG,GAAA,MAAAtuG,EAEA,IAAAlc,GAAA,GAAAwqH,EAEA,OADAxqH,GAAAutB,MAAArR,EAAA6uG,EAAAC,GACAhrH,EAyQA,QAAAirH,GAAA98E,GAMA,MADA/K,GAAA8nF,SAAA/8E,KAAAA,EAAA28E,EAAA38E,IACAA,YAAAq8E,GACAr8E,EAAA1pB,SADA+lG,EAAAhmH,UAAAigB,OAAAhkB,KAAA0tC,GA4DA,QAAAg9E,GAAAhpH,EAAAipH,GACA,MAAAN,GAAA3oH,GAAA,GAAA,GAAAkT,QAAA+1G,GAOA,QAAAC,GAAAlpH,EAAAipH,GACA,MAAAjpH,GACA2oH,EAAA3oH,GAAA,GAAA,GAAAmpH,cAAAF,GADAA,EAvaA,GAAAjG,GAAAjlH,EAAA,YACAkjC,EAAAljC,EAAA,SAEAM,GAAA+sB,MAAAu9F,EACAtqH,EAAA6U,QAAA81G,EACA3qH,EAAA8qH,cAAAD,EACA7qH,EAAAikB,OAAAwmG,EAEAzqH,EAAAgqH,IAAAA,CAqBA,IAAAe,GAAA,oBACAC,EAAA,WAGAC,EAAA,qCAIAC,GAAA,IAAA,IAAA,IAAA,IAAA,IAAA,KAAA,KAAA,MAGAC,GAAA,IAAA,IAAA,IAAA,KAAA,IAAA,KAAAzpH,OAAAwpH,GAGAE,GAAA,KAAA1pH,OAAAypH,GAKAE,GAAA,IAAA,IAAA,IAAA,IAAA,KAAA3pH,OAAA0pH,GACAE,GAAA,IAAA,IAAA,KAEAC,EAAA,yBACAC,EAAA,+BAEAC,GACAC,YAAA,EACAC,eAAA,GAGAC,GACAF,YAAA,EACAC,eAAA,GAGAE,GACAC,MAAA,EACAC,OAAA,EACAC,KAAA,EACAC,QAAA,EACAt/G,MAAA,EACAu/G,SAAA,EACAC,UAAA,EACAC,QAAA,EACAC,WAAA,EACAC,SAAA,GAEAC,EAAA7sH,EAAA,cAUAsqH,GAAAhmH,UAAA+oB,MAAA,SAAArR,EAAA6uG,EAAAC,GACA,IAAA5nF,EAAA8nF,SAAAhvG,GACA,KAAA,IAAA+0B,WAAA,+CAAA/0B,GAMA,IAAA8wG,GAAA9wG,EAAAtE,QAAA,KACAq1G,GACA,IAAAD,GAAAA,EAAA9wG,EAAAtE,QAAA,KAAA,IAAA,IACAs1G,EAAAhxG,EAAAkB,MAAA6vG,GACAE,EAAA,KACAD,GAAA,GAAAA,EAAA,GAAAhwG,QAAAiwG,EAAA,KACAjxG,EAAAgxG,EAAAvpF,KAAAspF,EAEA,IAAAG,GAAAlxG,CAMA,IAFAkxG,EAAAA,EAAAxc,QAEAoa,GAAA,IAAA9uG,EAAAkB,MAAA,KAAA1c,OAAA,CAEA,GAAA2sH,GAAA5B,EAAA1c,KAAAqe,EACA,IAAAC,EAeA,MAdA9rH,MAAAyG,KAAAolH,EACA7rH,KAAAstG,KAAAue,EACA7rH,KAAAspH,SAAAwC,EAAA,GACAA,EAAA,IACA9rH,KAAAiO,OAAA69G,EAAA,GAEA9rH,KAAA8O,MADA06G,EACAgC,EAAAx/F,MAAAhsB,KAAAiO,OAAA6C,OAAA,IAEA9Q,KAAAiO,OAAA6C,OAAA,IAEA04G,IACAxpH,KAAAiO,OAAA,GACAjO,KAAA8O,UAEA9O,KAIA,GAAAkxF,GAAA84B,EAAAxc,KAAAqe,EACA,IAAA36B,EAAA,CACAA,EAAAA,EAAA,EACA,IAAA66B,GAAA76B,EAAArF,aACA7rF,MAAA0Q,SAAAq7G,EACAF,EAAAA,EAAA/6G,OAAAogF,EAAA/xF,QAOA,GAAAsqH,GAAAv4B,GAAA26B,EAAAt0D,MAAA,wBAAA,CACA,GAAA2xD,GAAA,OAAA2C,EAAA/6G,OAAA,EAAA,IACAo4G,GAAAh4B,GAAA25B,EAAA35B,KACA26B,EAAAA,EAAA/6G,OAAA,GACA9Q,KAAAkpH,SAAA,GAIA,IAAA2B,EAAA35B,KACAg4B,GAAAh4B,IAAA45B,EAAA55B,IAAA,CAmBA,IAAA,GADA86B,IAAA,EACAptH,EAAA,EAAAA,EAAA2rH,EAAAprH,OAAAP,IAAA,CACA,GAAAqtH,GAAAJ,EAAAx1G,QAAAk0G,EAAA3rH,KACA,IAAAqtH,KAAA,IAAAD,GAAAC,EAAAD,KACAA,EAAAC,GAKA,GAAA/nH,GAAAgoH,CAGAA,IAFA,IAAAF,EAEAH,EAAApJ,YAAA,KAIAoJ,EAAApJ,YAAA,IAAAuJ,IAKA,IAAAE,IACAhoH,EAAA2nH,EAAA/6F,MAAA,EAAAo7F,GACAL,EAAAA,EAAA/6F,MAAAo7F,EAAA,GACAlsH,KAAAkE,KAAAogH,mBAAApgH,IAIA8nH,GAAA,CACA,KAAA,GAAAptH,GAAA,EAAAA,EAAA0rH,EAAAnrH,OAAAP,IAAA,CACA,GAAAqtH,GAAAJ,EAAAx1G,QAAAi0G,EAAA1rH,KACA,IAAAqtH,KAAA,IAAAD,GAAAC,EAAAD,KACAA,EAAAC,IAGA,IAAAD,IACAA,EAAAH,EAAA1sH,QAEAa,KAAAisB,KAAA4/F,EAAA/6F,MAAA,EAAAk7F,GACAH,EAAAA,EAAA/6F,MAAAk7F,GAGAhsH,KAAAmsH,YAIAnsH,KAAAopH,SAAAppH,KAAAopH,UAAA,EAIA,IAAAgD,GAAA,MAAApsH,KAAAopH,SAAA,IACA,MAAAppH,KAAAopH,SAAAppH,KAAAopH,SAAAjqH,OAAA,EAGA,KAAAitH,EAEA,IAAA,GADAC,GAAArsH,KAAAopH,SAAAvtG,MAAA,MACAjd,EAAA,EAAAI,EAAAqtH,EAAAltH,OAAAP,EAAAI,EAAAJ,IAAA,CACA,GAAA0tH,GAAAD,EAAAztH,EACA,IAAA0tH,IACAA,EAAA/0D,MAAAizD,GAAA,CAEA,IAAA,GADA+B,GAAA,GACA1gF,EAAA,EAAAxG,EAAAinF,EAAAntH,OAAA0sC,EAAAxG,EAAAwG,IACAygF,EAAAje,WAAAxiE,GAAA,IAIA0gF,GAAA,IAEAA,GAAAD,EAAAzgF,EAIA,KAAA0gF,EAAAh1D,MAAAizD,GAAA,CACA,GAAAgC,GAAAH,EAAAv7F,MAAA,EAAAlyB,GACA6tH,EAAAJ,EAAAv7F,MAAAlyB,EAAA,GACA8tH,EAAAJ,EAAA/0D,MAAAkzD,EACAiC,KACAF,EAAA51G,KAAA81G,EAAA,IACAD,EAAAE,QAAAD,EAAA,KAEAD,EAAAttH,SACA0sH,EAAA,IAAAY,EAAArqF,KAAA,KAAAypF,GAEA7rH,KAAAopH,SAAAoD,EAAApqF,KAAA,IACA,SAMApiC,KAAAopH,SAAAjqH,OAjNA,IAkNAa,KAAAopH,SAAA,GAGAppH,KAAAopH,SAAAppH,KAAAopH,SAAAv9B,cAGAugC,IAKApsH,KAAAopH,SAAAxF,EAAAN,QAAAtjH,KAAAopH,UAGA,IAAA39C,GAAAzrE,KAAAmpH,KAAA,IAAAnpH,KAAAmpH,KAAA,GACAyD,EAAA5sH,KAAAopH,UAAA,EACAppH,MAAAisB,KAAA2gG,EAAAnhD,EACAzrE,KAAAstG,MAAAttG,KAAAisB,KAIAmgG,IACApsH,KAAAopH,SAAAppH,KAAAopH,SAAAt4G,OAAA,EAAA9Q,KAAAopH,SAAAjqH,OAAA,GACA,MAAA0sH,EAAA,KACAA,EAAA,IAAAA,IAOA,IAAAnB,EAAAqB,GAKA,IAAA,GAAAntH,GAAA,EAAAI,EAAAqrH,EAAAlrH,OAAAP,EAAAI,EAAAJ,IAAA,CACA,GAAAiuH,GAAAxC,EAAAzrH,EACA,KAAA,IAAAitH,EAAAx1G,QAAAw2G,GAAA,CAEA,GAAAC,GAAA5vE,mBAAA2vE,EACAC,KAAAD,IACAC,EAAAC,OAAAF,IAEAhB,EAAAA,EAAAhwG,MAAAgxG,GAAAzqF,KAAA0qF,IAMA,GAAAzD,GAAAwC,EAAAx1G,QAAA,MACA,IAAAgzG,IAEArpH,KAAAqpH,KAAAwC,EAAA/6G,OAAAu4G,GACAwC,EAAAA,EAAA/6F,MAAA,EAAAu4F,GAEA,IAAA2D,GAAAnB,EAAAx1G,QAAA,IAoBA,KAnBA,IAAA22G,GACAhtH,KAAAiO,OAAA49G,EAAA/6G,OAAAk8G,GACAhtH,KAAA8O,MAAA+8G,EAAA/6G,OAAAk8G,EAAA,GACAxD,IACAxpH,KAAA8O,MAAA08G,EAAAx/F,MAAAhsB,KAAA8O,QAEA+8G,EAAAA,EAAA/6F,MAAA,EAAAk8F,IACAxD,IAEAxpH,KAAAiO,OAAA,GACAjO,KAAA8O,UAEA+8G,IAAA7rH,KAAAspH,SAAAuC,GACAf,EAAAiB,IACA/rH,KAAAopH,WAAAppH,KAAAspH,WACAtpH,KAAAspH,SAAA,KAIAtpH,KAAAspH,UAAAtpH,KAAAiO,OAAA,CACA,GAAAw9D,GAAAzrE,KAAAspH,UAAA,GACA/qH,EAAAyB,KAAAiO,QAAA,EACAjO,MAAAyG,KAAAglE,EAAAltE,EAKA,MADAyB,MAAAstG,KAAAttG,KAAAkjB,SACAljB,MAcAipH,EAAAhmH,UAAAigB,OAAA,WACA,GAAAhf,GAAAlE,KAAAkE,MAAA,EACAA,KACAA,EAAAg5C,mBAAAh5C,GACAA,EAAAA,EAAAyX,QAAA,OAAA,KACAzX,GAAA,IAGA,IAAAwM,GAAA1Q,KAAA0Q,UAAA,GACA44G,EAAAtpH,KAAAspH,UAAA,GACAD,EAAArpH,KAAAqpH,MAAA,GACAp9F,GAAA,EACAnd,EAAA,EAEA9O,MAAAisB,KACAA,EAAA/nB,EAAAlE,KAAAisB,KACAjsB,KAAAopH,WACAn9F,EAAA/nB,IAAA,IAAAlE,KAAAopH,SAAA/yG,QAAA,KACArW,KAAAopH,SACA,IAAAppH,KAAAopH,SAAA,KACAppH,KAAAmpH,OACAl9F,GAAA,IAAAjsB,KAAAmpH,OAIAnpH,KAAA8O,OACA+yB,EAAAmhD,SAAAhjF,KAAA8O,QACA09B,OAAAltB,KAAAtf,KAAA8O,OAAA3P,SACA2P,EAAA08G,EAAA33E,UAAA7zC,KAAA8O,OAGA,IAAAb,GAAAjO,KAAAiO,QAAAa,GAAA,IAAAA,GAAA,EAsBA,OApBA4B,IAAA,MAAAA,EAAAI,QAAA,KAAAJ,GAAA,KAIA1Q,KAAAkpH,WACAx4G,GAAAo6G,EAAAp6G,MAAA,IAAAub,GACAA,EAAA,MAAAA,GAAA,IACAq9F,GAAA,MAAAA,EAAA74F,OAAA,KAAA64F,EAAA,IAAAA,IACAr9F,IACAA,EAAA,IAGAo9F,GAAA,MAAAA,EAAA54F,OAAA,KAAA44F,EAAA,IAAAA,GACAp7G,GAAA,MAAAA,EAAAwiB,OAAA,KAAAxiB,EAAA,IAAAA,GAEAq7G,EAAAA,EAAA3tG,QAAA,QAAA,SAAA47C,GACA,MAAAra,oBAAAqa,KAEAtpD,EAAAA,EAAA0N,QAAA,IAAA,OAEAjL,EAAAub,EAAAq9F,EAAAr7G,EAAAo7G,GAOAJ,EAAAhmH,UAAA6Q,QAAA,SAAA+1G,GACA,MAAA7pH,MAAA+pH,cAAAR,EAAAM,GAAA,GAAA,IAAA3mG,UAQA+lG,EAAAhmH,UAAA8mH,cAAA,SAAAF,GACA,GAAAhoF,EAAA8nF,SAAAE,GAAA,CACA,GAAAoD,GAAA,GAAAhE,EACAgE,GAAAjhG,MAAA69F,GAAA,GAAA,GACAA,EAAAoD,EAKA,IAAA,GAFAngG,GAAA,GAAAm8F,GACAiE,EAAA1gF,OAAAltB,KAAAtf,MACAmtH,EAAA,EAAAA,EAAAD,EAAA/tH,OAAAguH,IAAA,CACA,GAAAC,GAAAF,EAAAC,EACArgG,GAAAsgG,GAAAptH,KAAAotH,GAQA,GAHAtgG,EAAAu8F,KAAAQ,EAAAR,KAGA,KAAAQ,EAAAvc,KAEA,MADAxgF,GAAAwgF,KAAAxgF,EAAA5J,SACA4J,CAIA,IAAA+8F,EAAAX,UAAAW,EAAAn5G,SAAA,CAGA,IAAA,GADA28G,GAAA7gF,OAAAltB,KAAAuqG,GACAyD,EAAA,EAAAA,EAAAD,EAAAluH,OAAAmuH,IAAA,CACA,GAAAC,GAAAF,EAAAC,EACA,cAAAC,IACAzgG,EAAAygG,GAAA1D,EAAA0D,IAUA,MANAzC,GAAAh+F,EAAApc,WACAoc,EAAAs8F,WAAAt8F,EAAAw8F,WACAx8F,EAAArmB,KAAAqmB,EAAAw8F,SAAA,KAGAx8F,EAAAwgF,KAAAxgF,EAAA5J,SACA4J,EAGA,GAAA+8F,EAAAn5G,UAAAm5G,EAAAn5G,WAAAoc,EAAApc,SAAA,CASA,IAAAo6G,EAAAjB,EAAAn5G,UAAA,CAEA,IAAA,GADA4O,GAAAktB,OAAAltB,KAAAuqG,GACArwE,EAAA,EAAAA,EAAAl6B,EAAAngB,OAAAq6C,IAAA,CACA,GAAAnU,GAAA/lB,EAAAk6B,EACA1sB,GAAAuY,GAAAwkF,EAAAxkF,GAGA,MADAvY,GAAAwgF,KAAAxgF,EAAA5J,SACA4J,EAIA,GADAA,EAAApc,SAAAm5G,EAAAn5G,SACAm5G,EAAA59F,MAAA4+F,EAAAhB,EAAAn5G,UASAoc,EAAAw8F,SAAAO,EAAAP,aATA,CAEA,IADA,GAAAkE,IAAA3D,EAAAP,UAAA,IAAAztG,MAAA,KACA2xG,EAAAruH,UAAA0qH,EAAA59F,KAAAuhG,EAAAj1D,WACAsxD,EAAA59F,OAAA49F,EAAA59F,KAAA,IACA49F,EAAAT,WAAAS,EAAAT,SAAA,IACA,KAAAoE,EAAA,IAAAA,EAAAb,QAAA,IACAa,EAAAruH,OAAA,GAAAquH,EAAAb,QAAA,IACA7/F,EAAAw8F,SAAAkE,EAAAprF,KAAA,KAWA,GAPAtV,EAAA7e,OAAA47G,EAAA57G,OACA6e,EAAAhe,MAAA+6G,EAAA/6G,MACAge,EAAAb,KAAA49F,EAAA59F,MAAA,GACAa,EAAA5oB,KAAA2lH,EAAA3lH,KACA4oB,EAAAs8F,SAAAS,EAAAT,UAAAS,EAAA59F,KACAa,EAAAq8F,KAAAU,EAAAV,KAEAr8F,EAAAw8F,UAAAx8F,EAAA7e,OAAA,CACA,GAAAw9D,GAAA3+C,EAAAw8F,UAAA,GACA/qH,EAAAuuB,EAAA7e,QAAA,EACA6e,GAAArmB,KAAAglE,EAAAltE,EAIA,MAFAuuB,GAAAo8F,QAAAp8F,EAAAo8F,SAAAW,EAAAX,QACAp8F,EAAAwgF,KAAAxgF,EAAA5J,SACA4J,EAGA,GAAA2gG,GAAA3gG,EAAAw8F,UAAA,MAAAx8F,EAAAw8F,SAAA74F,OAAA,GACAi9F,EACA7D,EAAA59F,MACA49F,EAAAP,UAAA,MAAAO,EAAAP,SAAA74F,OAAA,GAEAk9F,EAAAD,GAAAD,GACA3gG,EAAAb,MAAA49F,EAAAP,SACAsE,EAAAD,EACAE,EAAA/gG,EAAAw8F,UAAAx8F,EAAAw8F,SAAAztG,MAAA,SACA2xG,EAAA3D,EAAAP,UAAAO,EAAAP,SAAAztG,MAAA,SACAiyG,EAAAhhG,EAAApc,WAAAo6G,EAAAh+F,EAAApc,SA2BA,IApBAo9G,IACAhhG,EAAAs8F,SAAA,GACAt8F,EAAAq8F,KAAA,KACAr8F,EAAAb,OACA,KAAA4hG,EAAA,GAAAA,EAAA,GAAA/gG,EAAAb,KACA4hG,EAAAlB,QAAA7/F,EAAAb,OAEAa,EAAAb,KAAA,GACA49F,EAAAn5G,WACAm5G,EAAAT,SAAA,KACAS,EAAAV,KAAA,KACAU,EAAA59F,OACA,KAAAuhG,EAAA,GAAAA,EAAA,GAAA3D,EAAA59F,KACAuhG,EAAAb,QAAA9C,EAAA59F,OAEA49F,EAAA59F,KAAA,MAEA0hG,EAAAA,IAAA,KAAAH,EAAA,IAAA,KAAAK,EAAA,KAGAH,EAEA5gG,EAAAb,KAAA49F,EAAA59F,MAAA,KAAA49F,EAAA59F,KACA49F,EAAA59F,KAAAa,EAAAb,KACAa,EAAAs8F,SAAAS,EAAAT,UAAA,KAAAS,EAAAT,SACAS,EAAAT,SAAAt8F,EAAAs8F,SACAt8F,EAAA7e,OAAA47G,EAAA57G,OACA6e,EAAAhe,MAAA+6G,EAAA/6G,MACA++G,EAAAL,MAEA,IAAAA,EAAAruH,OAGA0uH,IAAAA,MACAA,EAAAxuC,MACAwuC,EAAAA,EAAAltH,OAAA6sH,GACA1gG,EAAA7e,OAAA47G,EAAA57G,OACA6e,EAAAhe,MAAA+6G,EAAA/6G,UACA,KAAA+yB,EAAAksF,kBAAAlE,EAAA57G,QAAA,CAIA,GAAA6/G,EAAA,CACAhhG,EAAAs8F,SAAAt8F,EAAAb,KAAA4hG,EAAAt1D,OAIA,IAAAy1D,MAAAlhG,EAAAb,MAAAa,EAAAb,KAAA5V,QAAA,KAAA,IACAyW,EAAAb,KAAApQ,MAAA,IACAmyG,KACAlhG,EAAA5oB,KAAA8pH,EAAAz1D,QACAzrC,EAAAb,KAAAa,EAAAs8F,SAAA4E,EAAAz1D,SAWA,MARAzrC,GAAA7e,OAAA47G,EAAA57G,OACA6e,EAAAhe,MAAA+6G,EAAA/6G,MAEA+yB,EAAAosF,OAAAnhG,EAAAw8F,WAAAznF,EAAAosF,OAAAnhG,EAAA7e,UACA6e,EAAArmB,MAAAqmB,EAAAw8F,SAAAx8F,EAAAw8F,SAAA,KACAx8F,EAAA7e,OAAA6e,EAAA7e,OAAA,KAEA6e,EAAAwgF,KAAAxgF,EAAA5J,SACA4J,EAGA,IAAA+gG,EAAA1uH,OAWA,MARA2tB,GAAAw8F,SAAA,KAEAx8F,EAAA7e,OACA6e,EAAArmB,KAAA,IAAAqmB,EAAA7e,OAEA6e,EAAArmB,KAAA,KAEAqmB,EAAAwgF,KAAAxgF,EAAA5J,SACA4J,CAcA,KAAA,GARAsoE,GAAAy4B,EAAA/8F,OAAA,GAAA,GACAo9F,GACAphG,EAAAb,MAAA49F,EAAA59F,MAAA4hG,EAAA1uH,OAAA,KACA,MAAAi2F,GAAA,OAAAA,IAAA,KAAAA,EAIA+4B,EAAA,EACAvvH,EAAAivH,EAAA1uH,OAAAP,GAAA,EAAAA,IACAw2F,EAAAy4B,EAAAjvH,GACA,MAAAw2F,EACAy4B,EAAAv1E,OAAA15C,EAAA,GACA,OAAAw2F,GACAy4B,EAAAv1E,OAAA15C,EAAA,GACAuvH,KACAA,IACAN,EAAAv1E,OAAA15C,EAAA,GACAuvH,IAKA,KAAAR,IAAAC,EACA,KAAAO,IAAAA,EACAN,EAAAlB,QAAA,OAIAgB,GAAA,KAAAE,EAAA,IACAA,EAAA,IAAA,MAAAA,EAAA,GAAAp9F,OAAA,IACAo9F,EAAAlB,QAAA,IAGAuB,GAAA,MAAAL,EAAAzrF,KAAA,KAAAtxB,QAAA,IACA+8G,EAAAj3G,KAAA,GAGA,IAAAw3G,GAAA,KAAAP,EAAA,IACAA,EAAA,IAAA,MAAAA,EAAA,GAAAp9F,OAAA,EAGA,IAAAq9F,EAAA,CACAhhG,EAAAs8F,SAAAt8F,EAAAb,KAAAmiG,EAAA,GACAP,EAAA1uH,OAAA0uH,EAAAt1D,QAAA,EAIA,IAAAy1D,MAAAlhG,EAAAb,MAAAa,EAAAb,KAAA5V,QAAA,KAAA,IACAyW,EAAAb,KAAApQ,MAAA,IACAmyG,KACAlhG,EAAA5oB,KAAA8pH,EAAAz1D,QACAzrC,EAAAb,KAAAa,EAAAs8F,SAAA4E,EAAAz1D,SAyBA,MArBAo1D,GAAAA,GAAA7gG,EAAAb,MAAA4hG,EAAA1uH,OAEAwuH,IAAAS,GACAP,EAAAlB,QAAA,IAGAkB,EAAA1uH,OAIA2tB,EAAAw8F,SAAAuE,EAAAzrF,KAAA,MAHAtV,EAAAw8F,SAAA,KACAx8F,EAAArmB,KAAA,MAMAo7B,EAAAosF,OAAAnhG,EAAAw8F,WAAAznF,EAAAosF,OAAAnhG,EAAA7e,UACA6e,EAAArmB,MAAAqmB,EAAAw8F,SAAAx8F,EAAAw8F,SAAA,KACAx8F,EAAA7e,OAAA6e,EAAA7e,OAAA,KAEA6e,EAAA5oB,KAAA2lH,EAAA3lH,MAAA4oB,EAAA5oB,KACA4oB,EAAAo8F,QAAAp8F,EAAAo8F,SAAAW,EAAAX,QACAp8F,EAAAwgF,KAAAxgF,EAAA5J,SACA4J,GAGAm8F,EAAAhmH,UAAAkpH,UAAA,WACA,GAAAlgG,GAAAjsB,KAAAisB,KACAk9F,EAAAc,EAAAzc,KAAAvhF,EACAk9F,KACAA,EAAAA,EAAA,GACA,MAAAA,IACAnpH,KAAAmpH,KAAAA,EAAAr4G,OAAA,IAEAmb,EAAAA,EAAAnb,OAAA,EAAAmb,EAAA9sB,OAAAgqH,EAAAhqH,SAEA8sB,IAAAjsB,KAAAopH,SAAAn9F,uEC1tBA,YAEA5sB,GAAAJ,SACA0qH,SAAA,SAAAtuC,GACA,MAAA,gBAAA,IAEA2H,SAAA,SAAA3H,GACA,MAAA,gBAAA,IAAA,OAAAA,GAEA4yC,OAAA,SAAA5yC,GACA,MAAA,QAAAA,GAEA0yC,kBAAA,SAAA1yC,GACA,MAAA,OAAAA","file":"dist/browser-matrix.min.js","sourceRoot":"","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);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;orequire(\"request\")\n * as it returns a function which meets the required interface. See\n * {@link requestFunction} for more information.\n *\n * @param {string} opts.accessToken The access_token for this user.\n *\n * @param {Number=} opts.localTimeoutMs Optional. The default maximum amount of\n * time to wait before timing out HTTP requests. If not specified, there is no\n * timeout.\n *\n * @param {Object} opts.queryParams Optional. Extra query parameters to append\n * to all requests with this client. Useful for application services which require\n * ?user_id=.\n *\n * @param {boolean} [opts.useAuthorizationHeader = false] Set to true to use\n * Authorization header instead of query param to send the access token to the server.\n */\nfunction MatrixBaseApis(opts) {\n utils.checkObjectHasKeys(opts, [\"baseUrl\", \"request\"]);\n\n this.baseUrl = opts.baseUrl;\n this.idBaseUrl = opts.idBaseUrl;\n\n const httpOpts = {\n baseUrl: opts.baseUrl,\n idBaseUrl: opts.idBaseUrl,\n accessToken: opts.accessToken,\n request: opts.request,\n prefix: httpApi.PREFIX_R0,\n onlyData: true,\n extraParams: opts.queryParams,\n localTimeoutMs: opts.localTimeoutMs,\n useAuthorizationHeader: opts.useAuthorizationHeader,\n };\n this._http = new httpApi.MatrixHttpApi(this, httpOpts);\n\n this._txnCtr = 0;\n}\n\n/**\n * Get the Homeserver URL of this client\n * @return {string} Homeserver URL of this client\n */\nMatrixBaseApis.prototype.getHomeserverUrl = function() {\n return this.baseUrl;\n};\n\n/**\n * Get the Identity Server URL of this client\n * @return {string} Identity Server URL of this client\n */\nMatrixBaseApis.prototype.getIdentityServerUrl = function() {\n return this.idBaseUrl;\n};\n\n/**\n * Get the access token associated with this account.\n * @return {?String} The access_token or null\n */\nMatrixBaseApis.prototype.getAccessToken = function() {\n return this._http.opts.accessToken || null;\n};\n\n/**\n * @return {boolean} true if there is a valid access_token for this client.\n */\nMatrixBaseApis.prototype.isLoggedIn = function() {\n return this._http.opts.accessToken !== undefined;\n};\n\n/**\n * Make up a new transaction id\n *\n * @return {string} a new, unique, transaction id\n */\nMatrixBaseApis.prototype.makeTxnId = function() {\n return \"m\" + new Date().getTime() + \".\" + (this._txnCtr++);\n};\n\n\n// Registration/Login operations\n// =============================\n\n/**\n * Check whether a username is available prior to registration. An error response\n * indicates an invalid/unavailable username.\n * @param {string} username The username to check the availability of.\n * @return {module:client.Promise} Resolves: to `true`.\n */\nMatrixBaseApis.prototype.isUsernameAvailable = function(username) {\n return this._http.authedRequest(\n undefined, \"GET\", '/register/available', { username: username },\n ).then((response) => {\n return response.available;\n });\n};\n\n/**\n * @param {string} username\n * @param {string} password\n * @param {string} sessionId\n * @param {Object} auth\n * @param {Object} bindThreepids Set key 'email' to true to bind any email\n * threepid uses during registration in the ID server. Set 'msisdn' to\n * true to bind msisdn.\n * @param {string} guestAccessToken\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.register = function(\n username, password,\n sessionId, auth, bindThreepids, guestAccessToken,\n callback,\n) {\n // backwards compat\n if (bindThreepids === true) {\n bindThreepids = {email: true};\n } else if (bindThreepids === null || bindThreepids === undefined) {\n bindThreepids = {};\n }\n\n if (auth === undefined || auth === null) {\n auth = {};\n }\n if (sessionId) {\n auth.session = sessionId;\n }\n\n const params = {\n auth: auth,\n };\n if (username !== undefined && username !== null) {\n params.username = username;\n }\n if (password !== undefined && password !== null) {\n params.password = password;\n }\n if (bindThreepids.email) {\n params.bind_email = true;\n }\n if (bindThreepids.msisdn) {\n params.bind_msisdn = true;\n }\n if (guestAccessToken !== undefined && guestAccessToken !== null) {\n params.guest_access_token = guestAccessToken;\n }\n // Temporary parameter added to make the register endpoint advertise\n // msisdn flows. This exists because there are clients that break\n // when given stages they don't recognise. This parameter will cease\n // to be necessary once these old clients are gone.\n // Only send it if we send any params at all (the password param is\n // mandatory, so if we send any params, we'll send the password param)\n if (password !== undefined && password !== null) {\n params.x_show_msisdn = true;\n }\n\n return this.registerRequest(params, undefined, callback);\n};\n\n/**\n * Register a guest account.\n * @param {Object=} opts Registration options\n * @param {Object} opts.body JSON HTTP body to provide.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.registerGuest = function(opts, callback) {\n opts = opts || {};\n opts.body = opts.body || {};\n return this.registerRequest(opts.body, \"guest\", callback);\n};\n\n/**\n * @param {Object} data parameters for registration request\n * @param {string=} kind type of user to register. may be \"guest\"\n * @param {module:client.callback=} callback\n * @return {module:client.Promise} Resolves: to the /register response\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.registerRequest = function(data, kind, callback) {\n const params = {};\n if (kind) {\n params.kind = kind;\n }\n\n return this._http.request(\n callback, \"POST\", \"/register\", params, data,\n );\n};\n\n/**\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.loginFlows = function(callback) {\n return this._http.request(callback, \"GET\", \"/login\");\n};\n\n/**\n * @param {string} loginType\n * @param {Object} data\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.login = function(loginType, data, callback) {\n const login_data = {\n type: loginType,\n };\n\n // merge data into login_data\n utils.extend(login_data, data);\n\n return this._http.authedRequest(\n callback, \"POST\", \"/login\", undefined, login_data,\n );\n};\n\n/**\n * @param {string} user\n * @param {string} password\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.loginWithPassword = function(user, password, callback) {\n return this.login(\"m.login.password\", {\n user: user,\n password: password,\n }, callback);\n};\n\n/**\n * @param {string} relayState URL Callback after SAML2 Authentication\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.loginWithSAML2 = function(relayState, callback) {\n return this.login(\"m.login.saml2\", {\n relay_state: relayState,\n }, callback);\n};\n\n/**\n * @param {string} redirectUrl The URL to redirect to after the HS\n * authenticates with CAS.\n * @return {string} The HS URL to hit to begin the CAS login process.\n */\nMatrixBaseApis.prototype.getCasLoginUrl = function(redirectUrl) {\n return this._http.getUrl(\"/login/cas/redirect\", {\n \"redirectUrl\": redirectUrl,\n }, httpApi.PREFIX_UNSTABLE);\n};\n\n/**\n * @param {string} token Login token previously received from homeserver\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.loginWithToken = function(token, callback) {\n return this.login(\"m.login.token\", {\n token: token,\n }, callback);\n};\n\n\n/**\n * Logs out the current session.\n * Obviously, further calls that require authorisation should fail after this\n * method is called. The state of the MatrixClient object is not affected:\n * it is up to the caller to either reset or destroy the MatrixClient after\n * this method succeeds.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: On success, the empty object\n */\nMatrixBaseApis.prototype.logout = function(callback) {\n return this._http.authedRequest(\n callback, \"POST\", '/logout',\n );\n};\n\n/**\n * Deactivates the logged-in account.\n * Obviously, further calls that require authorisation should fail after this\n * method is called. The state of the MatrixClient object is not affected:\n * it is up to the caller to either reset or destroy the MatrixClient after\n * this method succeeds.\n * @param {object} auth Optional. Auth data to supply for User-Interactive auth.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: On success, the empty object\n */\nMatrixBaseApis.prototype.deactivateAccount = function(auth, callback) {\n let body = {};\n if (auth) {\n body = {\n auth: auth,\n };\n }\n return this._http.authedRequestWithPrefix(\n callback, \"POST\", '/account/deactivate', undefined, body, httpApi.PREFIX_UNSTABLE,\n );\n};\n\n/**\n * Get the fallback URL to use for unknown interactive-auth stages.\n *\n * @param {string} loginType the type of stage being attempted\n * @param {string} authSessionId the auth session ID provided by the homeserver\n *\n * @return {string} HS URL to hit to for the fallback interface\n */\nMatrixBaseApis.prototype.getFallbackAuthUrl = function(loginType, authSessionId) {\n const path = utils.encodeUri(\"/auth/$loginType/fallback/web\", {\n $loginType: loginType,\n });\n\n return this._http.getUrl(path, {\n session: authSessionId,\n }, httpApi.PREFIX_R0);\n};\n\n// Room operations\n// ===============\n\n/**\n * Create a new room.\n * @param {Object} options a list of options to pass to the /createRoom API.\n * @param {string} options.room_alias_name The alias localpart to assign to\n * this room.\n * @param {string} options.visibility Either 'public' or 'private'.\n * @param {string[]} options.invite A list of user IDs to invite to this room.\n * @param {string} options.name The name to give this room.\n * @param {string} options.topic The topic to give this room.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: {room_id: {string},\n * room_alias: {string(opt)}}\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.createRoom = function(options, callback) {\n // valid options include: room_alias_name, visibility, invite\n return this._http.authedRequest(\n callback, \"POST\", \"/createRoom\", undefined, options,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.roomState = function(roomId, callback) {\n const path = utils.encodeUri(\"/rooms/$roomId/state\", {$roomId: roomId});\n return this._http.authedRequest(callback, \"GET\", path);\n};\n\n/**\n * @param {string} groupId\n * @return {module:client.Promise} Resolves: Group summary object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getGroupSummary = function(groupId) {\n const path = utils.encodeUri(\"/groups/$groupId/summary\", {$groupId: groupId});\n return this._http.authedRequest(undefined, \"GET\", path);\n};\n\n/**\n * @param {string} groupId\n * @return {module:client.Promise} Resolves: Group profile object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getGroupProfile = function(groupId) {\n const path = utils.encodeUri(\"/groups/$groupId/profile\", {$groupId: groupId});\n return this._http.authedRequest(undefined, \"GET\", path);\n};\n\n/**\n * @param {string} groupId\n * @param {Object} profile The group profile object\n * @param {string=} profile.name Name of the group\n * @param {string=} profile.avatar_url MXC avatar URL\n * @param {string=} profile.short_description A short description of the room\n * @param {string=} profile.long_description A longer HTML description of the room\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.setGroupProfile = function(groupId, profile) {\n const path = utils.encodeUri(\"/groups/$groupId/profile\", {$groupId: groupId});\n return this._http.authedRequest(\n undefined, \"POST\", path, undefined, profile,\n );\n};\n\n/**\n * @param {string} groupId\n * @return {module:client.Promise} Resolves: Group users list object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getGroupUsers = function(groupId) {\n const path = utils.encodeUri(\"/groups/$groupId/users\", {$groupId: groupId});\n return this._http.authedRequest(undefined, \"GET\", path);\n};\n\n/**\n * @param {string} groupId\n * @return {module:client.Promise} Resolves: Group users list object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getGroupInvitedUsers = function(groupId) {\n const path = utils.encodeUri(\"/groups/$groupId/invited_users\", {$groupId: groupId});\n return this._http.authedRequest(undefined, \"GET\", path);\n};\n\n/**\n * @param {string} groupId\n * @return {module:client.Promise} Resolves: Group rooms list object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getGroupRooms = function(groupId) {\n const path = utils.encodeUri(\"/groups/$groupId/rooms\", {$groupId: groupId});\n return this._http.authedRequest(undefined, \"GET\", path);\n};\n\n/**\n * @param {string} groupId\n * @param {string} userId\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.inviteUserToGroup = function(groupId, userId) {\n const path = utils.encodeUri(\n \"/groups/$groupId/admin/users/invite/$userId\",\n {$groupId: groupId, $userId: userId},\n );\n return this._http.authedRequest(undefined, \"PUT\", path, undefined, {});\n};\n\n/**\n * @param {string} groupId\n * @param {string} userId\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.removeUserFromGroup = function(groupId, userId) {\n const path = utils.encodeUri(\n \"/groups/$groupId/admin/users/remove/$userId\",\n {$groupId: groupId, $userId: userId},\n );\n return this._http.authedRequest(undefined, \"PUT\", path, undefined, {});\n};\n\n/**\n * @param {string} groupId\n * @param {string} userId\n * @param {string} roleId Optional.\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.addUserToGroupSummary = function(groupId, userId, roleId) {\n const path = utils.encodeUri(\n roleId ?\n \"/groups/$groupId/summary/$roleId/users/$userId\" :\n \"/groups/$groupId/summary/users/$userId\",\n {$groupId: groupId, $roleId: roleId, $userId: userId},\n );\n return this._http.authedRequest(undefined, \"PUT\", path, undefined, {});\n};\n\n/**\n * @param {string} groupId\n * @param {string} userId\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.removeUserFromGroupSummary = function(groupId, userId) {\n const path = utils.encodeUri(\n \"/groups/$groupId/summary/users/$userId\",\n {$groupId: groupId, $userId: userId},\n );\n return this._http.authedRequest(undefined, \"DELETE\", path, undefined, {});\n};\n\n/**\n * @param {string} groupId\n * @param {string} roomId\n * @param {string} categoryId Optional.\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.addRoomToGroupSummary = function(groupId, roomId, categoryId) {\n const path = utils.encodeUri(\n categoryId ?\n \"/groups/$groupId/summary/$categoryId/rooms/$roomId\" :\n \"/groups/$groupId/summary/rooms/$roomId\",\n {$groupId: groupId, $categoryId: categoryId, $roomId: roomId},\n );\n return this._http.authedRequest(undefined, \"PUT\", path, undefined, {});\n};\n\n/**\n * @param {string} groupId\n * @param {string} roomId\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.removeRoomFromGroupSummary = function(groupId, roomId) {\n const path = utils.encodeUri(\n \"/groups/$groupId/summary/rooms/$roomId\",\n {$groupId: groupId, $roomId: roomId},\n );\n return this._http.authedRequest(undefined, \"DELETE\", path, undefined, {});\n};\n\n/**\n * @param {string} groupId\n * @param {string} roomId\n * @param {bool} isPublic Whether the room-group association is visible to non-members\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.addRoomToGroup = function(groupId, roomId, isPublic) {\n if (isPublic === undefined) {\n isPublic = true;\n }\n const path = utils.encodeUri(\n \"/groups/$groupId/admin/rooms/$roomId\",\n {$groupId: groupId, $roomId: roomId},\n );\n return this._http.authedRequest(undefined, \"PUT\", path, undefined,\n { visibility: { type: isPublic ? \"public\" : \"private\" } },\n );\n};\n\n/**\n * Configure the visibility of a room-group association.\n * @param {string} groupId\n * @param {string} roomId\n * @param {bool} isPublic Whether the room-group association is visible to non-members\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.updateGroupRoomVisibility = function(groupId, roomId, isPublic) {\n // NB: The /config API is generic but there's not much point in exposing this yet as synapse\n // is the only server to implement this. In future we should consider an API that allows\n // arbitrary configuration, i.e. \"config/$configKey\".\n\n const path = utils.encodeUri(\n \"/groups/$groupId/admin/rooms/$roomId/config/m.visibility\",\n {$groupId: groupId, $roomId: roomId},\n );\n return this._http.authedRequest(undefined, \"PUT\", path, undefined,\n { type: isPublic ? \"public\" : \"private\" },\n );\n};\n\n/**\n * @param {string} groupId\n * @param {string} roomId\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.removeRoomFromGroup = function(groupId, roomId) {\n const path = utils.encodeUri(\n \"/groups/$groupId/admin/rooms/$roomId\",\n {$groupId: groupId, $roomId: roomId},\n );\n return this._http.authedRequest(undefined, \"DELETE\", path, undefined, {});\n};\n\n/**\n * @param {string} groupId\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.acceptGroupInvite = function(groupId) {\n const path = utils.encodeUri(\n \"/groups/$groupId/self/accept_invite\",\n {$groupId: groupId},\n );\n return this._http.authedRequest(undefined, \"PUT\", path, undefined, {});\n};\n\n/**\n * @param {string} groupId\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.leaveGroup = function(groupId) {\n const path = utils.encodeUri(\n \"/groups/$groupId/self/leave\",\n {$groupId: groupId},\n );\n return this._http.authedRequest(undefined, \"PUT\", path, undefined, {});\n};\n\n/**\n * @return {module:client.Promise} Resolves: The groups to which the user is joined\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getJoinedGroups = function() {\n const path = utils.encodeUri(\"/joined_groups\");\n return this._http.authedRequest(undefined, \"GET\", path);\n};\n\n/**\n * @param {Object} content Request content\n * @param {string} content.localpart The local part of the desired group ID\n * @param {Object} content.profile Group profile object\n * @return {module:client.Promise} Resolves: Object with key group_id: id of the created group\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.createGroup = function(content) {\n const path = utils.encodeUri(\"/create_group\");\n return this._http.authedRequest(\n undefined, \"POST\", path, undefined, content,\n );\n};\n\n/**\n * @param {string[]} userIds List of user IDs\n * @return {module:client.Promise} Resolves: Object as exmaple below\n *\n * {\n * \"users\": {\n * \"@bob:example.com\": {\n * \"+example:example.com\"\n * }\n * }\n * }\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getPublicisedGroups = function(userIds) {\n const path = utils.encodeUri(\"/publicised_groups\");\n return this._http.authedRequest(\n undefined, \"POST\", path, undefined, { user_ids: userIds },\n );\n};\n\n/**\n * @param {string} groupId\n * @param {bool} isPublic Whether the user's membership of this group is made public\n * @return {module:client.Promise} Resolves: Empty object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.setGroupPublicity = function(groupId, isPublic) {\n const path = utils.encodeUri(\n \"/groups/$groupId/self/update_publicity\",\n {$groupId: groupId},\n );\n return this._http.authedRequest(undefined, \"PUT\", path, undefined, {\n publicise: isPublic,\n });\n};\n\n/**\n * Retrieve a state event.\n * @param {string} roomId\n * @param {string} eventType\n * @param {string} stateKey\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getStateEvent = function(roomId, eventType, stateKey, callback) {\n const pathParams = {\n $roomId: roomId,\n $eventType: eventType,\n $stateKey: stateKey,\n };\n let path = utils.encodeUri(\"/rooms/$roomId/state/$eventType\", pathParams);\n if (stateKey !== undefined) {\n path = utils.encodeUri(path + \"/$stateKey\", pathParams);\n }\n return this._http.authedRequest(\n callback, \"GET\", path,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {string} eventType\n * @param {Object} content\n * @param {string} stateKey\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.sendStateEvent = function(roomId, eventType, content, stateKey,\n callback) {\n const pathParams = {\n $roomId: roomId,\n $eventType: eventType,\n $stateKey: stateKey,\n };\n let path = utils.encodeUri(\"/rooms/$roomId/state/$eventType\", pathParams);\n if (stateKey !== undefined) {\n path = utils.encodeUri(path + \"/$stateKey\", pathParams);\n }\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, content,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {string} eventId\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.redactEvent = function(roomId, eventId, callback) {\n const path = utils.encodeUri(\"/rooms/$roomId/redact/$eventId\", {\n $roomId: roomId,\n $eventId: eventId,\n });\n return this._http.authedRequest(callback, \"POST\", path, undefined, {});\n};\n\n/**\n * @param {string} roomId\n * @param {Number} limit\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.roomInitialSync = function(roomId, limit, callback) {\n if (utils.isFunction(limit)) {\n callback = limit; limit = undefined;\n }\n const path = utils.encodeUri(\"/rooms/$roomId/initialSync\",\n {$roomId: roomId},\n );\n if (!limit) {\n limit = 30;\n }\n return this._http.authedRequest(\n callback, \"GET\", path, { limit: limit },\n );\n};\n\n/**\n * Set a marker to indicate the point in a room before which the user has read every\n * event. This can be retrieved from room account data (the event type is `m.fully_read`)\n * and displayed as a horizontal line in the timeline that is visually distinct to the\n * position of the user's own read receipt.\n * @param {string} roomId ID of the room that has been read\n * @param {string} rmEventId ID of the event that has been read\n * @param {string} rrEventId ID of the event tracked by the read receipt. This is here\n * for convenience because the RR and the RM are commonly updated at the same time as\n * each other. Optional.\n * @return {module:client.Promise} Resolves: the empty object, {}.\n */\nMatrixBaseApis.prototype.setRoomReadMarkersHttpRequest =\n function(roomId, rmEventId, rrEventId) {\n const path = utils.encodeUri(\"/rooms/$roomId/read_markers\", {\n $roomId: roomId,\n });\n\n const content = {\n \"m.fully_read\": rmEventId,\n \"m.read\": rrEventId,\n };\n\n return this._http.authedRequest(\n undefined, \"POST\", path, undefined, content,\n );\n};\n\n\n// Room Directory operations\n// =========================\n\n/**\n * @param {Object} options Options for this request\n * @param {string} options.server The remote server to query for the room list.\n * Optional. If unspecified, get the local home\n * server's public room list.\n * @param {number} options.limit Maximum number of entries to return\n * @param {string} options.since Token to paginate from\n * @param {object} options.filter Filter parameters\n * @param {string} options.filter.generic_search_term String to search for\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.publicRooms = function(options, callback) {\n if (typeof(options) == 'function') {\n callback = options;\n options = {};\n }\n if (options === undefined) {\n options = {};\n }\n\n const query_params = {};\n if (options.server) {\n query_params.server = options.server;\n delete options.server;\n }\n\n if (Object.keys(options).length === 0 && Object.keys(query_params).length === 0) {\n return this._http.authedRequest(callback, \"GET\", \"/publicRooms\");\n } else {\n return this._http.authedRequest(\n callback, \"POST\", \"/publicRooms\", query_params, options,\n );\n }\n};\n\n/**\n * Create an alias to room ID mapping.\n * @param {string} alias The room alias to create.\n * @param {string} roomId The room ID to link the alias to.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO.\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.createAlias = function(alias, roomId, callback) {\n const path = utils.encodeUri(\"/directory/room/$alias\", {\n $alias: alias,\n });\n const data = {\n room_id: roomId,\n };\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, data,\n );\n};\n\n/**\n * Delete an alias to room ID mapping. This alias must be on your local server\n * and you must have sufficient access to do this operation.\n * @param {string} alias The room alias to delete.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO.\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.deleteAlias = function(alias, callback) {\n const path = utils.encodeUri(\"/directory/room/$alias\", {\n $alias: alias,\n });\n return this._http.authedRequest(\n callback, \"DELETE\", path, undefined, undefined,\n );\n};\n\n/**\n * Get room info for the given alias.\n * @param {string} alias The room alias to resolve.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: Object with room_id and servers.\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getRoomIdForAlias = function(alias, callback) {\n // TODO: deprecate this or resolveRoomAlias\n const path = utils.encodeUri(\"/directory/room/$alias\", {\n $alias: alias,\n });\n return this._http.authedRequest(\n callback, \"GET\", path,\n );\n};\n\n/**\n * @param {string} roomAlias\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.resolveRoomAlias = function(roomAlias, callback) {\n // TODO: deprecate this or getRoomIdForAlias\n const path = utils.encodeUri(\"/directory/room/$alias\", {$alias: roomAlias});\n return this._http.request(callback, \"GET\", path);\n};\n\n/**\n * Get the visibility of a room in the current HS's room directory\n * @param {string} roomId\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getRoomDirectoryVisibility =\n function(roomId, callback) {\n const path = utils.encodeUri(\"/directory/list/room/$roomId\", {\n $roomId: roomId,\n });\n return this._http.authedRequest(callback, \"GET\", path);\n};\n\n/**\n * Set the visbility of a room in the current HS's room directory\n * @param {string} roomId\n * @param {string} visibility \"public\" to make the room visible\n * in the public directory, or \"private\" to make\n * it invisible.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: result object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.setRoomDirectoryVisibility =\n function(roomId, visibility, callback) {\n const path = utils.encodeUri(\"/directory/list/room/$roomId\", {\n $roomId: roomId,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, { \"visibility\": visibility },\n );\n};\n\n/**\n * Set the visbility of a room bridged to a 3rd party network in\n * the current HS's room directory.\n * @param {string} networkId the network ID of the 3rd party\n * instance under which this room is published under.\n * @param {string} roomId\n * @param {string} visibility \"public\" to make the room visible\n * in the public directory, or \"private\" to make\n * it invisible.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: result object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.setRoomDirectoryVisibilityAppService =\n function(networkId, roomId, visibility, callback) {\n const path = utils.encodeUri(\"/directory/list/appservice/$networkId/$roomId\", {\n $networkId: networkId,\n $roomId: roomId,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, { \"visibility\": visibility },\n );\n};\n\n// User Directory Operations\n// =========================\n\n/**\n * Query the user directory with a term matching user IDs, display names and domains.\n * @param {object} opts options\n * @param {string} opts.term the term with which to search.\n * @param {number} opts.limit the maximum number of results to return. The server will\n * apply a limit if unspecified.\n * @return {module:client.Promise} Resolves: an array of results.\n */\nMatrixBaseApis.prototype.searchUserDirectory = function(opts) {\n const body = {\n search_term: opts.term,\n };\n\n if (opts.limit !== undefined) {\n body.limit = opts.limit;\n }\n\n return this._http.authedRequest(\n undefined, \"POST\", \"/user_directory/search\", undefined, body,\n );\n};\n\n\n// Media operations\n// ================\n\n/**\n * Upload a file to the media repository on the home server.\n *\n * @param {object} file The object to upload. On a browser, something that\n * can be sent to XMLHttpRequest.send (typically a File). Under node.js,\n * a a Buffer, String or ReadStream.\n *\n * @param {object} opts options object\n *\n * @param {string=} opts.name Name to give the file on the server. Defaults\n * to file.name.\n *\n * @param {string=} opts.type Content-type for the upload. Defaults to\n * file.type, or applicaton/octet-stream.\n *\n * @param {boolean=} opts.rawResponse Return the raw body, rather than\n * parsing the JSON. Defaults to false (except on node.js, where it\n * defaults to true for backwards compatibility).\n *\n * @param {boolean=} opts.onlyContentUri Just return the content URI,\n * rather than the whole body. Defaults to false (except on browsers,\n * where it defaults to true for backwards compatibility). Ignored if\n * opts.rawResponse is true.\n *\n * @param {Function=} opts.callback Deprecated. Optional. The callback to\n * invoke on success/failure. See the promise return values for more\n * information.\n *\n * @param {Function=} opts.progressHandler Optional. Called when a chunk of\n * data has been uploaded, with an object containing the fields `loaded`\n * (number of bytes transferred) and `total` (total size, if known).\n *\n * @return {module:client.Promise} Resolves to response object, as\n * determined by this.opts.onlyData, opts.rawResponse, and\n * opts.onlyContentUri. Rejects with an error (usually a MatrixError).\n */\nMatrixBaseApis.prototype.uploadContent = function(file, opts) {\n return this._http.uploadContent(file, opts);\n};\n\n/**\n * Cancel a file upload in progress\n * @param {module:client.Promise} promise The promise returned from uploadContent\n * @return {boolean} true if canceled, otherwise false\n */\nMatrixBaseApis.prototype.cancelUpload = function(promise) {\n return this._http.cancelUpload(promise);\n};\n\n/**\n * Get a list of all file uploads in progress\n * @return {array} Array of objects representing current uploads.\n * Currently in progress is element 0. Keys:\n * - promise: The promise associated with the upload\n * - loaded: Number of bytes uploaded\n * - total: Total number of bytes to upload\n */\nMatrixBaseApis.prototype.getCurrentUploads = function() {\n return this._http.getCurrentUploads();\n};\n\n\n// Profile operations\n// ==================\n\n/**\n * @param {string} userId\n * @param {string} info The kind of info to retrieve (e.g. 'displayname',\n * 'avatar_url').\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getProfileInfo = function(userId, info, callback) {\n if (utils.isFunction(info)) {\n callback = info; info = undefined;\n }\n\n const path = info ?\n utils.encodeUri(\"/profile/$userId/$info\",\n { $userId: userId, $info: info }) :\n utils.encodeUri(\"/profile/$userId\",\n { $userId: userId });\n return this._http.authedRequest(callback, \"GET\", path);\n};\n\n\n// Account operations\n// ==================\n\n/**\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getThreePids = function(callback) {\n const path = \"/account/3pid\";\n return this._http.authedRequest(\n callback, \"GET\", path, undefined, undefined,\n );\n};\n\n/**\n * @param {Object} creds\n * @param {boolean} bind\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) {\n const path = \"/account/3pid\";\n const data = {\n 'threePidCreds': creds,\n 'bind': bind,\n };\n return this._http.authedRequest(\n callback, \"POST\", path, null, data,\n );\n};\n\n/**\n * @param {string} medium The threepid medium (eg. 'email')\n * @param {string} address The threepid address (eg. 'bob@example.com')\n * this must be as returned by getThreePids.\n * @return {module:client.Promise} Resolves: The server response on success\n * (generally the empty JSON object)\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.deleteThreePid = function(medium, address) {\n const path = \"/account/3pid/delete\";\n const data = {\n 'medium': medium,\n 'address': address,\n };\n return this._http.authedRequestWithPrefix(\n undefined, \"POST\", path, null, data, httpApi.PREFIX_UNSTABLE,\n );\n};\n\n/**\n * Make a request to change your password.\n * @param {Object} authDict\n * @param {string} newPassword The new desired password.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.setPassword = function(authDict, newPassword, callback) {\n const path = \"/account/password\";\n const data = {\n 'auth': authDict,\n 'new_password': newPassword,\n };\n\n return this._http.authedRequest(\n callback, \"POST\", path, null, data,\n );\n};\n\n\n// Device operations\n// =================\n\n/**\n * Gets all devices recorded for the logged-in user\n * @return {module:client.Promise} Resolves: result object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getDevices = function() {\n const path = \"/devices\";\n return this._http.authedRequestWithPrefix(\n undefined, \"GET\", path, undefined, undefined,\n httpApi.PREFIX_UNSTABLE,\n );\n};\n\n/**\n * Update the given device\n *\n * @param {string} device_id device to update\n * @param {Object} body body of request\n * @return {module:client.Promise} Resolves: result object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.setDeviceDetails = function(device_id, body) {\n const path = utils.encodeUri(\"/devices/$device_id\", {\n $device_id: device_id,\n });\n\n\n return this._http.authedRequestWithPrefix(\n undefined, \"PUT\", path, undefined, body,\n httpApi.PREFIX_UNSTABLE,\n );\n};\n\n/**\n * Delete the given device\n *\n * @param {string} device_id device to delete\n * @param {object} auth Optional. Auth data to supply for User-Interactive auth.\n * @return {module:client.Promise} Resolves: result object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.deleteDevice = function(device_id, auth) {\n const path = utils.encodeUri(\"/devices/$device_id\", {\n $device_id: device_id,\n });\n\n const body = {};\n\n if (auth) {\n body.auth = auth;\n }\n\n return this._http.authedRequestWithPrefix(\n undefined, \"DELETE\", path, undefined, body,\n httpApi.PREFIX_UNSTABLE,\n );\n};\n\n\n// Push operations\n// ===============\n\n/**\n * Gets all pushers registered for the logged-in user\n *\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: Array of objects representing pushers\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getPushers = function(callback) {\n const path = \"/pushers\";\n return this._http.authedRequest(\n callback, \"GET\", path, undefined, undefined,\n );\n};\n\n/**\n * Adds a new pusher or updates an existing pusher\n *\n * @param {Object} pusher Object representing a pusher\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: Empty json object on success\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.setPusher = function(pusher, callback) {\n const path = \"/pushers/set\";\n return this._http.authedRequest(\n callback, \"POST\", path, null, pusher,\n );\n};\n\n/**\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.getPushRules = function(callback) {\n return this._http.authedRequest(callback, \"GET\", \"/pushrules/\");\n};\n\n/**\n * @param {string} scope\n * @param {string} kind\n * @param {string} ruleId\n * @param {Object} body\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.addPushRule = function(scope, kind, ruleId, body, callback) {\n // NB. Scope not uri encoded because devices need the '/'\n const path = utils.encodeUri(\"/pushrules/\" + scope + \"/$kind/$ruleId\", {\n $kind: kind,\n $ruleId: ruleId,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, body,\n );\n};\n\n/**\n * @param {string} scope\n * @param {string} kind\n * @param {string} ruleId\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.deletePushRule = function(scope, kind, ruleId, callback) {\n // NB. Scope not uri encoded because devices need the '/'\n const path = utils.encodeUri(\"/pushrules/\" + scope + \"/$kind/$ruleId\", {\n $kind: kind,\n $ruleId: ruleId,\n });\n return this._http.authedRequest(callback, \"DELETE\", path);\n};\n\n/**\n * Enable or disable a push notification rule.\n * @param {string} scope\n * @param {string} kind\n * @param {string} ruleId\n * @param {boolean} enabled\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: result object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.setPushRuleEnabled = function(scope, kind,\n ruleId, enabled, callback) {\n const path = utils.encodeUri(\"/pushrules/\" + scope + \"/$kind/$ruleId/enabled\", {\n $kind: kind,\n $ruleId: ruleId,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, {\"enabled\": enabled},\n );\n};\n\n/**\n * Set the actions for a push notification rule.\n * @param {string} scope\n * @param {string} kind\n * @param {string} ruleId\n * @param {array} actions\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: result object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.setPushRuleActions = function(scope, kind,\n ruleId, actions, callback) {\n const path = utils.encodeUri(\"/pushrules/\" + scope + \"/$kind/$ruleId/actions\", {\n $kind: kind,\n $ruleId: ruleId,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, {\"actions\": actions},\n );\n};\n\n\n// Search\n// ======\n\n/**\n * Perform a server-side search.\n * @param {Object} opts\n * @param {string} opts.next_batch the batch token to pass in the query string\n * @param {Object} opts.body the JSON object to pass to the request body.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.search = function(opts, callback) {\n const queryparams = {};\n if (opts.next_batch) {\n queryparams.next_batch = opts.next_batch;\n }\n return this._http.authedRequest(\n callback, \"POST\", \"/search\", queryparams, opts.body,\n );\n};\n\n// Crypto\n// ======\n\n/**\n * Upload keys\n *\n * @param {Object} content body of upload request\n *\n * @param {Object=} opts\n *\n * @param {string=} opts.device_id explicit device_id to use for upload\n * (default is to use the same as that used during auth).\n *\n * @param {module:client.callback=} callback\n *\n * @return {module:client.Promise} Resolves: result object. Rejects: with\n * an error response ({@link module:http-api.MatrixError}).\n */\nMatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) {\n opts = opts || {};\n const deviceId = opts.device_id;\n let path;\n if (deviceId) {\n path = utils.encodeUri(\"/keys/upload/$deviceId\", {\n $deviceId: deviceId,\n });\n } else {\n path = \"/keys/upload\";\n }\n return this._http.authedRequestWithPrefix(\n callback, \"POST\", path, undefined, content, httpApi.PREFIX_UNSTABLE,\n );\n};\n\n/**\n * Download device keys\n *\n * @param {string[]} userIds list of users to get keys for\n *\n * @param {Object=} opts\n *\n * @param {string=} opts.token sync token to pass in the query request, to help\n * the HS give the most recent results\n *\n * @return {module:client.Promise} Resolves: result object. Rejects: with\n * an error response ({@link module:http-api.MatrixError}).\n */\nMatrixBaseApis.prototype.downloadKeysForUsers = function(userIds, opts) {\n if (utils.isFunction(opts)) {\n // opts used to be 'callback'.\n throw new Error(\n 'downloadKeysForUsers no longer accepts a callback parameter',\n );\n }\n opts = opts || {};\n\n const content = {\n device_keys: {},\n };\n if ('token' in opts) {\n content.token = opts.token;\n }\n userIds.forEach((u) => {\n content.device_keys[u] = {};\n });\n\n return this._http.authedRequestWithPrefix(\n undefined, \"POST\", \"/keys/query\", undefined, content,\n httpApi.PREFIX_UNSTABLE,\n );\n};\n\n/**\n * Claim one-time keys\n *\n * @param {string[]} devices a list of [userId, deviceId] pairs\n *\n * @param {string} [key_algorithm = signed_curve25519] desired key type\n *\n * @return {module:client.Promise} Resolves: result object. Rejects: with\n * an error response ({@link module:http-api.MatrixError}).\n */\nMatrixBaseApis.prototype.claimOneTimeKeys = function(devices, key_algorithm) {\n const queries = {};\n\n if (key_algorithm === undefined) {\n key_algorithm = \"signed_curve25519\";\n }\n\n for (let i = 0; i < devices.length; ++i) {\n const userId = devices[i][0];\n const deviceId = devices[i][1];\n const query = queries[userId] || {};\n queries[userId] = query;\n query[deviceId] = key_algorithm;\n }\n const content = {one_time_keys: queries};\n return this._http.authedRequestWithPrefix(\n undefined, \"POST\", \"/keys/claim\", undefined, content,\n httpApi.PREFIX_UNSTABLE,\n );\n};\n\n/**\n * Ask the server for a list of users who have changed their device lists\n * between a pair of sync tokens\n *\n * @param {string} oldToken\n * @param {string} newToken\n *\n * @return {module:client.Promise} Resolves: result object. Rejects: with\n * an error response ({@link module:http-api.MatrixError}).\n */\nMatrixBaseApis.prototype.getKeyChanges = function(oldToken, newToken) {\n const qps = {\n from: oldToken,\n to: newToken,\n };\n\n return this._http.authedRequestWithPrefix(\n undefined, \"GET\", \"/keys/changes\", qps, undefined,\n httpApi.PREFIX_UNSTABLE,\n );\n};\n\n\n// Identity Server Operations\n// ==========================\n\n/**\n * Requests an email verification token directly from an Identity Server.\n *\n * Note that the Home Server offers APIs to proxy this API for specific\n * situations, allowing for better feedback to the user.\n *\n * @param {string} email The email address to request a token for\n * @param {string} clientSecret A secret binary string generated by the client.\n * It is recommended this be around 16 ASCII characters.\n * @param {number} sendAttempt If an identity server sees a duplicate request\n * with the same sendAttempt, it will not send another email.\n * To request another email to be sent, use a larger value for\n * the sendAttempt param as was used in the previous request.\n * @param {string} nextLink Optional If specified, the client will be redirected\n * to this link after validation.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n * @throws Error if No ID server is set\n */\nMatrixBaseApis.prototype.requestEmailToken = function(email, clientSecret,\n sendAttempt, nextLink, callback) {\n const params = {\n client_secret: clientSecret,\n email: email,\n send_attempt: sendAttempt,\n next_link: nextLink,\n };\n return this._http.idServerRequest(\n callback, \"POST\", \"/validate/email/requestToken\",\n params, httpApi.PREFIX_IDENTITY_V1,\n );\n};\n\n/**\n * Submits an MSISDN token to the identity server\n *\n * This is used when submitting the code sent by SMS to a phone number.\n * The ID server has an equivalent API for email but the js-sdk does\n * not expose this, since email is normally validated by the user clicking\n * a link rather than entering a code.\n *\n * @param {string} sid The sid given in the response to requestToken\n * @param {string} clientSecret A secret binary string generated by the client.\n * This must be the same value submitted in the requestToken call.\n * @param {string} token The token, as enetered by the user.\n *\n * @return {module:client.Promise} Resolves: Object, currently with no parameters.\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n * @throws Error if No ID server is set\n */\nMatrixBaseApis.prototype.submitMsisdnToken = function(sid, clientSecret, token) {\n const params = {\n sid: sid,\n client_secret: clientSecret,\n token: token,\n };\n return this._http.idServerRequest(\n undefined, \"POST\", \"/validate/msisdn/submitToken\",\n params, httpApi.PREFIX_IDENTITY_V1,\n );\n};\n\n/**\n * Looks up the public Matrix ID mapping for a given 3rd party\n * identifier from the Identity Server\n * @param {string} medium The medium of the threepid, eg. 'email'\n * @param {string} address The textual address of the threepid\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: A threepid mapping\n * object or the empty object if no mapping\n * exists\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixBaseApis.prototype.lookupThreePid = function(medium, address, callback) {\n const params = {\n medium: medium,\n address: address,\n };\n return this._http.idServerRequest(\n callback, \"GET\", \"/lookup\",\n params, httpApi.PREFIX_IDENTITY_V1,\n );\n};\n\n\n// Direct-to-device messaging\n// ==========================\n\n/**\n * Send an event to a specific list of devices\n *\n * @param {string} eventType type of event to send\n * @param {Object.>} contentMap\n * content to send. Map from user_id to device_id to content object.\n * @param {string=} txnId transaction id. One will be made up if not\n * supplied.\n * @return {module:client.Promise} Resolves to the result object\n */\nMatrixBaseApis.prototype.sendToDevice = function(\n eventType, contentMap, txnId,\n) {\n const path = utils.encodeUri(\"/sendToDevice/$eventType/$txnId\", {\n $eventType: eventType,\n $txnId: txnId ? txnId : this.makeTxnId(),\n });\n\n const body = {\n messages: contentMap,\n };\n\n return this._http.authedRequestWithPrefix(\n undefined, \"PUT\", path, undefined, body,\n httpApi.PREFIX_UNSTABLE,\n );\n};\n\n// Third party Lookup API\n// ======================\n\n/**\n * Get the third party protocols that can be reached using\n * this HS\n * @return {module:client.Promise} Resolves to the result object\n */\nMatrixBaseApis.prototype.getThirdpartyProtocols = function() {\n return this._http.authedRequestWithPrefix(\n undefined, \"GET\", \"/thirdparty/protocols\", undefined, undefined,\n httpApi.PREFIX_UNSTABLE,\n ).then((response) => {\n // sanity check\n if (!response || typeof(response) !== 'object') {\n throw new Error(\n `/thirdparty/protocols did not return an object: ${response}`,\n );\n }\n return response;\n });\n};\n\n/**\n * Get information on how a specific place on a third party protocol\n * may be reached.\n * @param {string} protocol The protocol given in getThirdpartyProtocols()\n * @param {object} params Protocol-specific parameters, as given in th\n * response to getThirdpartyProtocols()\n * @return {module:client.Promise} Resolves to the result object\n */\nMatrixBaseApis.prototype.getThirdpartyLocation = function(protocol, params) {\n const path = utils.encodeUri(\"/thirdparty/location/$protocol\", {\n $protocol: protocol,\n });\n\n return this._http.authedRequestWithPrefix(\n undefined, \"GET\", path, params, undefined,\n httpApi.PREFIX_UNSTABLE,\n );\n};\n\n/**\n * MatrixBaseApis object\n */\nmodule.exports = MatrixBaseApis;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\nconst PushProcessor = require('./pushprocessor');\n\n/**\n * This is an internal module. See {@link MatrixClient} for the public class.\n * @module client\n */\nconst EventEmitter = require(\"events\").EventEmitter;\nimport Promise from 'bluebird';\nconst url = require('url');\n\nconst httpApi = require(\"./http-api\");\nconst MatrixEvent = require(\"./models/event\").MatrixEvent;\nconst EventStatus = require(\"./models/event\").EventStatus;\nconst EventTimeline = require(\"./models/event-timeline\");\nconst SearchResult = require(\"./models/search-result\");\nconst StubStore = require(\"./store/stub\");\nconst webRtcCall = require(\"./webrtc/call\");\nconst utils = require(\"./utils\");\nconst contentRepo = require(\"./content-repo\");\nconst Filter = require(\"./filter\");\nconst SyncApi = require(\"./sync\");\nconst MatrixBaseApis = require(\"./base-apis\");\nconst MatrixError = httpApi.MatrixError;\n\nimport ReEmitter from './ReEmitter';\n\nconst SCROLLBACK_DELAY_MS = 3000;\nlet CRYPTO_ENABLED = false;\n\ntry {\n var Crypto = require(\"./crypto\");\n CRYPTO_ENABLED = true;\n} catch (e) {\n console.warn(\"Unable to load crypto module: crypto will be disabled: \" + e);\n}\n\n/**\n * Construct a Matrix Client. Only directly construct this if you want to use\n * custom modules. Normally, {@link createClient} should be used\n * as it specifies 'sensible' defaults for these modules.\n * @constructor\n * @extends {external:EventEmitter}\n * @extends {module:base-apis~MatrixBaseApis}\n *\n * @param {Object} opts The configuration options for this client.\n * @param {string} opts.baseUrl Required. The base URL to the client-server\n * HTTP API.\n * @param {string} opts.idBaseUrl Optional. The base identity server URL for\n * identity server requests.\n * @param {Function} opts.request Required. The function to invoke for HTTP\n * requests. The value of this property is typically require(\"request\")\n * as it returns a function which meets the required interface. See\n * {@link requestFunction} for more information.\n *\n * @param {string} opts.accessToken The access_token for this user.\n *\n * @param {string} opts.userId The user ID for this user.\n *\n * @param {Object=} opts.store The data store to use. If not specified,\n * this client will not store any HTTP responses.\n *\n * @param {string=} opts.deviceId A unique identifier for this device; used for\n * tracking things like crypto keys and access tokens. If not specified,\n * end-to-end crypto will be disabled.\n *\n * @param {Object=} opts.sessionStore A store to be used for end-to-end crypto\n * session data. This should be a {@link\n * module:store/session/webstorage~WebStorageSessionStore|WebStorageSessionStore},\n * or an object implementing the same interface. If not specified,\n * end-to-end crypto will be disabled.\n *\n * @param {Object} opts.scheduler Optional. The scheduler to use. If not\n * specified, this client will not retry requests on failure. This client\n * will supply its own processing function to\n * {@link module:scheduler~MatrixScheduler#setProcessFunction}.\n *\n * @param {Object} opts.queryParams Optional. Extra query parameters to append\n * to all requests with this client. Useful for application services which require\n * ?user_id=.\n *\n * @param {Number=} opts.localTimeoutMs Optional. The default maximum amount of\n * time to wait before timing out HTTP requests. If not specified, there is no timeout.\n *\n * @param {boolean} [opts.useAuthorizationHeader = false] Set to true to use\n * Authorization header instead of query param to send the access token to the server.\n *\n * @param {boolean} [opts.timelineSupport = false] Set to true to enable\n * improved timeline support ({@link\n * module:client~MatrixClient#getEventTimeline getEventTimeline}). It is\n * disabled by default for compatibility with older clients - in particular to\n * maintain support for back-paginating the live timeline after a '/sync'\n * result with a gap.\n *\n * @param {module:crypto.store.base~CryptoStore} opts.cryptoStore\n * crypto store implementation.\n */\nfunction MatrixClient(opts) {\n // Allow trailing slash in HS url\n if (opts.baseUrl && opts.baseUrl.endsWith(\"/\")) {\n opts.baseUrl = opts.baseUrl.substr(0, opts.baseUrl.length - 1);\n }\n\n // Allow trailing slash in IS url\n if (opts.idBaseUrl && opts.idBaseUrl.endsWith(\"/\")) {\n opts.idBaseUrl = opts.idBaseUrl.substr(0, opts.idBaseUrl.length - 1);\n }\n\n MatrixBaseApis.call(this, opts);\n\n this.reEmitter = new ReEmitter(this);\n\n this.store = opts.store || new StubStore();\n\n this.deviceId = opts.deviceId || null;\n\n const userId = (opts.userId || null);\n this.credentials = {\n userId: userId,\n };\n\n this.scheduler = opts.scheduler;\n if (this.scheduler) {\n const self = this;\n this.scheduler.setProcessFunction(function(eventToSend) {\n const room = self.getRoom(eventToSend.getRoomId());\n if (eventToSend.status !== EventStatus.SENDING) {\n _updatePendingEventStatus(room, eventToSend,\n EventStatus.SENDING);\n }\n return _sendEventHttpRequest(self, eventToSend);\n });\n }\n this.clientRunning = false;\n\n this.callList = {\n // callId: MatrixCall\n };\n\n // try constructing a MatrixCall to see if we are running in an environment\n // which has WebRTC. If we are, listen for and handle m.call.* events.\n const call = webRtcCall.createNewMatrixCall(this);\n this._supportsVoip = false;\n if (call) {\n setupCallEventHandler(this);\n this._supportsVoip = true;\n }\n this._syncingRetry = null;\n this._syncApi = null;\n this._peekSync = null;\n this._isGuest = false;\n this._ongoingScrollbacks = {};\n this.timelineSupport = Boolean(opts.timelineSupport);\n this.urlPreviewCache = {};\n this._notifTimelineSet = null;\n\n this._crypto = null;\n this._cryptoStore = opts.cryptoStore;\n this._sessionStore = opts.sessionStore;\n\n this._forceTURN = opts.forceTURN || false;\n\n if (CRYPTO_ENABLED) {\n this.olmVersion = Crypto.getOlmVersion();\n }\n}\nutils.inherits(MatrixClient, EventEmitter);\nutils.extend(MatrixClient.prototype, MatrixBaseApis.prototype);\n\n/**\n * Clear any data out of the persistent stores used by the client.\n *\n * @returns {Promise} Promise which resolves when the stores have been cleared.\n */\nMatrixClient.prototype.clearStores = function() {\n if (this._clientRunning) {\n throw new Error(\"Cannot clear stores while client is running\");\n }\n\n const promises = [];\n\n promises.push(this.store.deleteAllData());\n if (this._cryptoStore) {\n promises.push(this._cryptoStore.deleteAllData());\n }\n return Promise.all(promises);\n};\n\n/**\n * Get the user-id of the logged-in user\n *\n * @return {?string} MXID for the logged-in user, or null if not logged in\n */\nMatrixClient.prototype.getUserId = function() {\n if (this.credentials && this.credentials.userId) {\n return this.credentials.userId;\n }\n return null;\n};\n\n/**\n * Get the domain for this client's MXID\n * @return {?string} Domain of this MXID\n */\nMatrixClient.prototype.getDomain = function() {\n if (this.credentials && this.credentials.userId) {\n return this.credentials.userId.replace(/^.*?:/, '');\n }\n return null;\n};\n\n/**\n * Get the local part of the current user ID e.g. \"foo\" in \"@foo:bar\".\n * @return {?string} The user ID localpart or null.\n */\nMatrixClient.prototype.getUserIdLocalpart = function() {\n if (this.credentials && this.credentials.userId) {\n return this.credentials.userId.split(\":\")[0].substring(1);\n }\n return null;\n};\n\n/**\n * Get the device ID of this client\n * @return {?string} device ID\n */\nMatrixClient.prototype.getDeviceId = function() {\n return this.deviceId;\n};\n\n\n/**\n * Check if the runtime environment supports VoIP calling.\n * @return {boolean} True if VoIP is supported.\n */\nMatrixClient.prototype.supportsVoip = function() {\n return this._supportsVoip;\n};\n\n/**\n * Set whether VoIP calls are forced to use only TURN\n * candidates. This is the same as the forceTURN option\n * when creating the client.\n * @param {bool} forceTURN True to force use of TURN servers\n */\nMatrixClient.prototype.setForceTURN = function(forceTURN) {\n this._forceTURN = forceTURN;\n};\n\n/**\n * Get the current sync state.\n * @return {?string} the sync state, which may be null.\n * @see module:client~MatrixClient#event:\"sync\"\n */\nMatrixClient.prototype.getSyncState = function() {\n if (!this._syncApi) {\n return null;\n }\n return this._syncApi.getSyncState();\n};\n\n/**\n * Return whether the client is configured for a guest account.\n * @return {boolean} True if this is a guest access_token (or no token is supplied).\n */\nMatrixClient.prototype.isGuest = function() {\n return this._isGuest;\n};\n\n/**\n * Return the provided scheduler, if any.\n * @return {?module:scheduler~MatrixScheduler} The scheduler or null\n */\nMatrixClient.prototype.getScheduler = function() {\n return this.scheduler;\n};\n\n/**\n * Set whether this client is a guest account. This method is experimental\n * and may change without warning.\n * @param {boolean} isGuest True if this is a guest account.\n */\nMatrixClient.prototype.setGuest = function(isGuest) {\n // EXPERIMENTAL:\n // If the token is a macaroon, it should be encoded in it that it is a 'guest'\n // access token, which means that the SDK can determine this entirely without\n // the dev manually flipping this flag.\n this._isGuest = isGuest;\n};\n\n/**\n * Retry a backed off syncing request immediately. This should only be used when\n * the user explicitly attempts to retry their lost connection.\n * @return {boolean} True if this resulted in a request being retried.\n */\nMatrixClient.prototype.retryImmediately = function() {\n return this._syncApi.retryImmediately();\n};\n\n/**\n * Return the global notification EventTimelineSet, if any\n *\n * @return {EventTimelineSet} the globl notification EventTimelineSet\n */\nMatrixClient.prototype.getNotifTimelineSet = function() {\n return this._notifTimelineSet;\n};\n\n/**\n * Set the global notification EventTimelineSet\n *\n * @param {EventTimelineSet} notifTimelineSet\n */\nMatrixClient.prototype.setNotifTimelineSet = function(notifTimelineSet) {\n this._notifTimelineSet = notifTimelineSet;\n};\n\n// Crypto bits\n// ===========\n\n/**\n * Initialise support for end-to-end encryption in this client\n *\n * You should call this method after creating the matrixclient, but *before*\n * calling `startClient`, if you want to support end-to-end encryption.\n *\n * It will return a Promise which will resolve when the crypto layer has been\n * successfully initialised.\n */\nMatrixClient.prototype.initCrypto = async function() {\n if (this._crypto) {\n console.warn(\"Attempt to re-initialise e2e encryption on MatrixClient\");\n return;\n }\n\n if (!CRYPTO_ENABLED) {\n throw new Error(\n `End-to-end encryption not supported in this js-sdk build: did ` +\n `you remember to load the olm library?`,\n );\n }\n\n if (!this._sessionStore) {\n // this is temporary, the sessionstore is supposed to be going away\n throw new Error(`Cannot enable encryption: no sessionStore provided`);\n }\n if (!this._cryptoStore) {\n // the cryptostore is provided by sdk.createClient, so this shouldn't happen\n throw new Error(`Cannot enable encryption: no cryptoStore provided`);\n }\n\n const userId = this.getUserId();\n if (userId === null) {\n throw new Error(\n `Cannot enable encryption on MatrixClient with unknown userId: ` +\n `ensure userId is passed in createClient().`,\n );\n }\n if (this.deviceId === null) {\n throw new Error(\n `Cannot enable encryption on MatrixClient with unknown deviceId: ` +\n `ensure deviceId is passed in createClient().`,\n );\n }\n\n const crypto = new Crypto(\n this,\n this._sessionStore,\n userId, this.deviceId,\n this.store,\n this._cryptoStore,\n );\n\n this.reEmitter.reEmit(crypto, [\n \"crypto.roomKeyRequest\",\n \"crypto.roomKeyRequestCancellation\",\n ]);\n\n await crypto.init();\n\n // if crypto initialisation was successful, tell it to attach its event\n // handlers.\n crypto.registerEventHandlers(this);\n this._crypto = crypto;\n};\n\n\n/**\n * Is end-to-end crypto enabled for this client.\n * @return {boolean} True if end-to-end is enabled.\n */\nMatrixClient.prototype.isCryptoEnabled = function() {\n return this._crypto !== null;\n};\n\n\n/**\n * Get the Ed25519 key for this device\n *\n * @return {?string} base64-encoded ed25519 key. Null if crypto is\n * disabled.\n */\nMatrixClient.prototype.getDeviceEd25519Key = function() {\n if (!this._crypto) {\n return null;\n }\n return this._crypto.getDeviceEd25519Key();\n};\n\n/**\n * Upload the device keys to the homeserver.\n * @return {object} A promise that will resolve when the keys are uploaded.\n */\nMatrixClient.prototype.uploadKeys = function() {\n if (this._crypto === null) {\n throw new Error(\"End-to-end encryption disabled\");\n }\n\n return this._crypto.uploadDeviceKeys();\n};\n\n/**\n * Download the keys for a list of users and stores the keys in the session\n * store.\n * @param {Array} userIds The users to fetch.\n * @param {bool} forceDownload Always download the keys even if cached.\n *\n * @return {Promise} A promise which resolves to a map userId->deviceId->{@link\n * module:crypto~DeviceInfo|DeviceInfo}.\n */\nMatrixClient.prototype.downloadKeys = function(userIds, forceDownload) {\n if (this._crypto === null) {\n return Promise.reject(new Error(\"End-to-end encryption disabled\"));\n }\n return this._crypto.downloadKeys(userIds, forceDownload);\n};\n\n/**\n * Get the stored device keys for a user id\n *\n * @param {string} userId the user to list keys for.\n *\n * @return {Promise} list of devices\n */\nMatrixClient.prototype.getStoredDevicesForUser = async function(userId) {\n if (this._crypto === null) {\n throw new Error(\"End-to-end encryption disabled\");\n }\n return this._crypto.getStoredDevicesForUser(userId) || [];\n};\n\n/**\n * Get the stored device key for a user id and device id\n *\n * @param {string} userId the user to list keys for.\n * @param {string} deviceId unique identifier for the device\n *\n * @return {Promise} device or null\n */\nMatrixClient.prototype.getStoredDevice = async function(userId, deviceId) {\n if (this._crypto === null) {\n throw new Error(\"End-to-end encryption disabled\");\n }\n return this._crypto.getStoredDevice(userId, deviceId) || null;\n};\n\n/**\n * Mark the given device as verified\n *\n * @param {string} userId owner of the device\n * @param {string} deviceId unique identifier for the device\n *\n * @param {boolean=} verified whether to mark the device as verified. defaults\n * to 'true'.\n *\n * @returns {Promise}\n *\n * @fires module:client~event:MatrixClient\"deviceVerificationChanged\"\n */\nMatrixClient.prototype.setDeviceVerified = function(userId, deviceId, verified) {\n if (verified === undefined) {\n verified = true;\n }\n return _setDeviceVerification(this, userId, deviceId, verified, null);\n};\n\n/**\n * Mark the given device as blocked/unblocked\n *\n * @param {string} userId owner of the device\n * @param {string} deviceId unique identifier for the device\n *\n * @param {boolean=} blocked whether to mark the device as blocked. defaults\n * to 'true'.\n *\n * @returns {Promise}\n *\n * @fires module:client~event:MatrixClient\"deviceVerificationChanged\"\n */\nMatrixClient.prototype.setDeviceBlocked = function(userId, deviceId, blocked) {\n if (blocked === undefined) {\n blocked = true;\n }\n return _setDeviceVerification(this, userId, deviceId, null, blocked);\n};\n\n/**\n * Mark the given device as known/unknown\n *\n * @param {string} userId owner of the device\n * @param {string} deviceId unique identifier for the device\n *\n * @param {boolean=} known whether to mark the device as known. defaults\n * to 'true'.\n *\n * @returns {Promise}\n *\n * @fires module:client~event:MatrixClient\"deviceVerificationChanged\"\n */\nMatrixClient.prototype.setDeviceKnown = function(userId, deviceId, known) {\n if (known === undefined) {\n known = true;\n }\n return _setDeviceVerification(this, userId, deviceId, null, null, known);\n};\n\nasync function _setDeviceVerification(\n client, userId, deviceId, verified, blocked, known,\n) {\n if (!client._crypto) {\n throw new Error(\"End-to-End encryption disabled\");\n }\n const dev = await client._crypto.setDeviceVerification(\n userId, deviceId, verified, blocked, known,\n );\n client.emit(\"deviceVerificationChanged\", userId, deviceId, dev);\n}\n\n/**\n * Set the global override for whether the client should ever send encrypted\n * messages to unverified devices. If false, it can still be overridden\n * per-room. If true, it overrides the per-room settings.\n *\n * @param {boolean} value whether to unilaterally blacklist all\n * unverified devices\n */\nMatrixClient.prototype.setGlobalBlacklistUnverifiedDevices = function(value) {\n if (this._crypto === null) {\n throw new Error(\"End-to-end encryption disabled\");\n }\n this._crypto.setGlobalBlacklistUnverifiedDevices(value);\n};\n\n/**\n * @return {boolean} whether to unilaterally blacklist all\n * unverified devices\n */\nMatrixClient.prototype.getGlobalBlacklistUnverifiedDevices = function() {\n if (this._crypto === null) {\n throw new Error(\"End-to-end encryption disabled\");\n }\n return this._crypto.getGlobalBlacklistUnverifiedDevices();\n};\n\n/**\n * Get e2e information on the device that sent an event\n *\n * @param {MatrixEvent} event event to be checked\n *\n * @return {Promise}\n */\nMatrixClient.prototype.getEventSenderDeviceInfo = async function(event) {\n if (!this._crypto) {\n return null;\n }\n\n return this._crypto.getEventSenderDeviceInfo(event);\n};\n\n/**\n * Check if the sender of an event is verified\n *\n * @param {MatrixEvent} event event to be checked\n *\n * @return {boolean} true if the sender of this event has been verified using\n * {@link module:client~MatrixClient#setDeviceVerified|setDeviceVerified}.\n */\nMatrixClient.prototype.isEventSenderVerified = async function(event) {\n const device = await this.getEventSenderDeviceInfo(event);\n if (!device) {\n return false;\n }\n return device.isVerified();\n};\n\n/**\n * Enable end-to-end encryption for a room.\n * @param {string} roomId The room ID to enable encryption in.\n * @param {object} config The encryption config for the room.\n * @return {Promise} A promise that will resolve when encryption is set up.\n */\nMatrixClient.prototype.setRoomEncryption = function(roomId, config) {\n if (!this._crypto) {\n throw new Error(\"End-to-End encryption disabled\");\n }\n return this._crypto.setRoomEncryption(roomId, config);\n};\n\n/**\n * Whether encryption is enabled for a room.\n * @param {string} roomId the room id to query.\n * @return {bool} whether encryption is enabled.\n */\nMatrixClient.prototype.isRoomEncrypted = function(roomId) {\n const room = this.getRoom(roomId);\n if (!room) {\n // we don't know about this room, so can't determine if it should be\n // encrypted. Let's assume not.\n return false;\n }\n\n // if there is an 'm.room.encryption' event in this room, it should be\n // encrypted (independently of whether we actually support encryption)\n const ev = room.currentState.getStateEvents(\"m.room.encryption\", \"\");\n if (ev) {\n return true;\n }\n\n // we don't have an m.room.encrypted event, but that might be because\n // the server is hiding it from us. Check the store to see if it was\n // previously encrypted.\n if (!this._sessionStore) {\n return false;\n }\n\n return Boolean(this._sessionStore.getEndToEndRoom(roomId));\n};\n\n/**\n * Get a list containing all of the room keys\n *\n * This should be encrypted before returning it to the user.\n *\n * @return {module:client.Promise} a promise which resolves to a list of\n * session export objects\n */\nMatrixClient.prototype.exportRoomKeys = function() {\n if (!this._crypto) {\n return Promise.reject(new Error(\"End-to-end encryption disabled\"));\n }\n return this._crypto.exportRoomKeys();\n};\n\n/**\n * Import a list of room keys previously exported by exportRoomKeys\n *\n * @param {Object[]} keys a list of session export objects\n *\n * @return {module:client.Promise} a promise which resolves when the keys\n * have been imported\n */\nMatrixClient.prototype.importRoomKeys = function(keys) {\n if (!this._crypto) {\n throw new Error(\"End-to-end encryption disabled\");\n }\n return this._crypto.importRoomKeys(keys);\n};\n\n// Group ops\n// =========\n// Operations on groups that come down the sync stream (ie. ones the\n// user is a member of or invited to)\n\n/**\n * Get the group for the given group ID.\n * This function will return a valid group for any group for which a Group event\n * has been emitted.\n * @param {string} groupId The group ID\n * @return {Group} The Group or null if the group is not known or there is no data store.\n */\nMatrixClient.prototype.getGroup = function(groupId) {\n return this.store.getGroup(groupId);\n};\n\n/**\n * Retrieve all known groups.\n * @return {Groups[]} A list of groups, or an empty list if there is no data store.\n */\nMatrixClient.prototype.getGroups = function() {\n return this.store.getGroups();\n};\n\n// Room ops\n// ========\n\n/**\n * Get the room for the given room ID.\n * This function will return a valid room for any room for which a Room event\n * has been emitted. Note in particular that other events, eg. RoomState.members\n * will be emitted for a room before this function will return the given room.\n * @param {string} roomId The room ID\n * @return {Room} The Room or null if it doesn't exist or there is no data store.\n */\nMatrixClient.prototype.getRoom = function(roomId) {\n return this.store.getRoom(roomId);\n};\n\n/**\n * Retrieve all known rooms.\n * @return {Room[]} A list of rooms, or an empty list if there is no data store.\n */\nMatrixClient.prototype.getRooms = function() {\n return this.store.getRooms();\n};\n\n/**\n * Retrieve a user.\n * @param {string} userId The user ID to retrieve.\n * @return {?User} A user or null if there is no data store or the user does\n * not exist.\n */\nMatrixClient.prototype.getUser = function(userId) {\n return this.store.getUser(userId);\n};\n\n/**\n * Retrieve all known users.\n * @return {User[]} A list of users, or an empty list if there is no data store.\n */\nMatrixClient.prototype.getUsers = function() {\n return this.store.getUsers();\n};\n\n// User Account Data operations\n// ============================\n\n/**\n * Set account data event for the current user.\n * @param {string} eventType The event type\n * @param {Object} contents the contents object for the event\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setAccountData = function(eventType, contents, callback) {\n const path = utils.encodeUri(\"/user/$userId/account_data/$type\", {\n $userId: this.credentials.userId,\n $type: eventType,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, contents,\n );\n};\n\n/**\n * Get account data event of given type for the current user.\n * @param {string} eventType The event type\n * @param {module:client.callback} callback Optional.\n * @return {?object} The contents of the given account data event\n */\nMatrixClient.prototype.getAccountData = function(eventType) {\n return this.store.getAccountData(eventType);\n};\n\n/**\n * Gets the users that are ignored by this client\n * @returns {string[]} The array of users that are ignored (empty if none)\n */\nMatrixClient.prototype.getIgnoredUsers = function() {\n const event = this.getAccountData(\"m.ignored_user_list\");\n if (!event || !event.getContent() || !event.getContent()[\"ignored_users\"]) return [];\n return Object.keys(event.getContent()[\"ignored_users\"]);\n};\n\n/**\n * Sets the users that the current user should ignore.\n * @param {string[]} userIds the user IDs to ignore\n * @param {module:client.callback} [callback] Optional.\n * @return {module:client.Promise} Resolves: Account data event\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setIgnoredUsers = function(userIds, callback) {\n const content = {ignored_users: {}};\n userIds.map((u) => content.ignored_users[u] = {});\n return this.setAccountData(\"m.ignored_user_list\", content, callback);\n};\n\n/**\n * Gets whether or not a specific user is being ignored by this client.\n * @param {string} userId the user ID to check\n * @returns {boolean} true if the user is ignored, false otherwise\n */\nMatrixClient.prototype.isUserIgnored = function(userId) {\n return this.getIgnoredUsers().indexOf(userId) !== -1;\n};\n\n// Room operations\n// ===============\n\n/**\n * Join a room. If you have already joined the room, this will no-op.\n * @param {string} roomIdOrAlias The room ID or room alias to join.\n * @param {Object} opts Options when joining the room.\n * @param {boolean} opts.syncRoom True to do a room initial sync on the resulting\n * room. If false, the returned Room object will have no current state.\n * Default: true.\n * @param {boolean} opts.inviteSignUrl If the caller has a keypair 3pid invite,\n * the signing URL is passed in this parameter.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: Room object.\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.joinRoom = function(roomIdOrAlias, opts, callback) {\n // to help people when upgrading..\n if (utils.isFunction(opts)) {\n throw new Error(\"Expected 'opts' object, got function.\");\n }\n opts = opts || {};\n if (opts.syncRoom === undefined) {\n opts.syncRoom = true;\n }\n\n const room = this.getRoom(roomIdOrAlias);\n if (room && room.hasMembershipState(this.credentials.userId, \"join\")) {\n return Promise.resolve(room);\n }\n\n let sign_promise = Promise.resolve();\n\n if (opts.inviteSignUrl) {\n sign_promise = this._http.requestOtherUrl(\n undefined, 'POST',\n opts.inviteSignUrl, { mxid: this.credentials.userId },\n );\n }\n\n const defer = Promise.defer();\n\n const self = this;\n sign_promise.then(function(signed_invite_object) {\n const data = {};\n if (signed_invite_object) {\n data.third_party_signed = signed_invite_object;\n }\n\n const path = utils.encodeUri(\"/join/$roomid\", { $roomid: roomIdOrAlias});\n return self._http.authedRequest(undefined, \"POST\", path, undefined, data);\n }).then(function(res) {\n const roomId = res.room_id;\n const syncApi = new SyncApi(self, self._clientOpts);\n const room = syncApi.createRoom(roomId);\n if (opts.syncRoom) {\n // v2 will do this for us\n // return syncApi.syncRoom(room);\n }\n return Promise.resolve(room);\n }).done(function(room) {\n _resolve(callback, defer, room);\n }, function(err) {\n _reject(callback, defer, err);\n });\n return defer.promise;\n};\n\n/**\n * Resend an event.\n * @param {MatrixEvent} event The event to resend.\n * @param {Room} room Optional. The room the event is in. Will update the\n * timeline entry if provided.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.resendEvent = function(event, room) {\n _updatePendingEventStatus(room, event, EventStatus.SENDING);\n return _sendEvent(this, room, event);\n};\n\n/**\n * Cancel a queued or unsent event.\n *\n * @param {MatrixEvent} event Event to cancel\n * @throws Error if the event is not in QUEUED or NOT_SENT state\n */\nMatrixClient.prototype.cancelPendingEvent = function(event) {\n if ([EventStatus.QUEUED, EventStatus.NOT_SENT].indexOf(event.status) < 0) {\n throw new Error(\"cannot cancel an event with status \" + event.status);\n }\n\n // first tell the scheduler to forget about it, if it's queued\n if (this.scheduler) {\n this.scheduler.removeEventFromQueue(event);\n }\n\n // then tell the room about the change of state, which will remove it\n // from the room's list of pending events.\n const room = this.getRoom(event.getRoomId());\n _updatePendingEventStatus(room, event, EventStatus.CANCELLED);\n};\n\n/**\n * @param {string} roomId\n * @param {string} name\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setRoomName = function(roomId, name, callback) {\n return this.sendStateEvent(roomId, \"m.room.name\", {name: name},\n undefined, callback);\n};\n\n/**\n * @param {string} roomId\n * @param {string} topic\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setRoomTopic = function(roomId, topic, callback) {\n return this.sendStateEvent(roomId, \"m.room.topic\", {topic: topic},\n undefined, callback);\n};\n\n/**\n * @param {string} roomId\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.getRoomTags = function(roomId, callback) {\n const path = utils.encodeUri(\"/user/$userId/rooms/$roomId/tags/\", {\n $userId: this.credentials.userId,\n $roomId: roomId,\n });\n return this._http.authedRequest(\n callback, \"GET\", path, undefined,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {string} tagName name of room tag to be set\n * @param {object} metadata associated with that tag to be stored\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setRoomTag = function(roomId, tagName, metadata, callback) {\n const path = utils.encodeUri(\"/user/$userId/rooms/$roomId/tags/$tag\", {\n $userId: this.credentials.userId,\n $roomId: roomId,\n $tag: tagName,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, metadata,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {string} tagName name of room tag to be removed\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.deleteRoomTag = function(roomId, tagName, callback) {\n const path = utils.encodeUri(\"/user/$userId/rooms/$roomId/tags/$tag\", {\n $userId: this.credentials.userId,\n $roomId: roomId,\n $tag: tagName,\n });\n return this._http.authedRequest(\n callback, \"DELETE\", path, undefined, undefined,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {string} eventType event type to be set\n * @param {object} content event content\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setRoomAccountData = function(roomId, eventType,\n content, callback) {\n const path = utils.encodeUri(\"/user/$userId/rooms/$roomId/account_data/$type\", {\n $userId: this.credentials.userId,\n $roomId: roomId,\n $type: eventType,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, content,\n );\n};\n\n/**\n * Set a user's power level.\n * @param {string} roomId\n * @param {string} userId\n * @param {Number} powerLevel\n * @param {MatrixEvent} event\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setPowerLevel = function(roomId, userId, powerLevel,\n event, callback) {\n let content = {\n users: {},\n };\n if (event && event.getType() === \"m.room.power_levels\") {\n // take a copy of the content to ensure we don't corrupt\n // existing client state with a failed power level change\n content = utils.deepCopy(event.getContent());\n }\n content.users[userId] = powerLevel;\n const path = utils.encodeUri(\"/rooms/$roomId/state/m.room.power_levels\", {\n $roomId: roomId,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, content,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {string} eventType\n * @param {Object} content\n * @param {string} txnId Optional.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendEvent = function(roomId, eventType, content, txnId,\n callback) {\n if (utils.isFunction(txnId)) {\n callback = txnId; txnId = undefined;\n }\n\n if (!txnId) {\n txnId = this.makeTxnId();\n }\n\n console.log(`sendEvent of type ${eventType} in ${roomId} with txnId ${txnId}`);\n\n // we always construct a MatrixEvent when sending because the store and\n // scheduler use them. We'll extract the params back out if it turns out\n // the client has no scheduler or store.\n const room = this.getRoom(roomId);\n const localEvent = new MatrixEvent({\n event_id: \"~\" + roomId + \":\" + txnId,\n user_id: this.credentials.userId,\n room_id: roomId,\n type: eventType,\n origin_server_ts: new Date().getTime(),\n content: content,\n });\n localEvent._txnId = txnId;\n localEvent.status = EventStatus.SENDING;\n\n // add this event immediately to the local store as 'sending'.\n if (room) {\n room.addPendingEvent(localEvent, txnId);\n }\n\n return _sendEvent(this, room, localEvent, callback);\n};\n\n\n// encrypts the event if necessary\n// adds the event to the queue, or sends it\n// marks the event as sent/unsent\n// returns a promise which resolves with the result of the send request\nfunction _sendEvent(client, room, event, callback) {\n // Add an extra Promise.resolve() to turn synchronous exceptions into promise rejections,\n // so that we can handle synchronous and asynchronous exceptions with the\n // same code path.\n return Promise.resolve().then(function() {\n const encryptionPromise = _encryptEventIfNeeded(client, event, room);\n\n if (!encryptionPromise) {\n return null;\n }\n\n _updatePendingEventStatus(room, event, EventStatus.ENCRYPTING);\n return encryptionPromise.then(() => {\n _updatePendingEventStatus(room, event, EventStatus.SENDING);\n });\n }).then(function() {\n let promise;\n // this event may be queued\n if (client.scheduler) {\n // if this returns a promsie then the scheduler has control now and will\n // resolve/reject when it is done. Internally, the scheduler will invoke\n // processFn which is set to this._sendEventHttpRequest so the same code\n // path is executed regardless.\n promise = client.scheduler.queueEvent(event);\n if (promise && client.scheduler.getQueueForEvent(event).length > 1) {\n // event is processed FIFO so if the length is 2 or more we know\n // this event is stuck behind an earlier event.\n _updatePendingEventStatus(room, event, EventStatus.QUEUED);\n }\n }\n\n if (!promise) {\n promise = _sendEventHttpRequest(client, event);\n }\n return promise;\n }).then(function(res) { // the request was sent OK\n if (room) {\n room.updatePendingEvent(event, EventStatus.SENT, res.event_id);\n }\n if (callback) {\n callback(null, res);\n }\n return res;\n }, function(err) {\n // the request failed to send.\n console.error(\"Error sending event\", err.stack || err);\n\n try {\n _updatePendingEventStatus(room, event, EventStatus.NOT_SENT);\n event.error = err;\n\n if (callback) {\n callback(err);\n }\n } catch (err2) {\n console.error(\"Exception in error handler!\", err2.stack || err);\n }\n throw err;\n });\n}\n\n/**\n * Encrypt an event according to the configuration of the room, if necessary.\n *\n * @param {MatrixClient} client\n *\n * @param {module:models/event.MatrixEvent} event event to be sent\n *\n * @param {module:models/room?} room destination room. Null if the destination\n * is not a room we have seen over the sync pipe.\n *\n * @return {module:client.Promise?} Promise which resolves when the event has been\n * encrypted, or null if nothing was needed\n */\n\nfunction _encryptEventIfNeeded(client, event, room) {\n if (event.isEncrypted()) {\n // this event has already been encrypted; this happens if the\n // encryption step succeeded, but the send step failed on the first\n // attempt.\n return null;\n }\n\n if (!client.isRoomEncrypted(event.getRoomId())) {\n // looks like this room isn't encrypted.\n return null;\n }\n\n if (!client._crypto) {\n throw new Error(\n \"This room is configured to use encryption, but your client does \" +\n \"not support encryption.\",\n );\n }\n\n return client._crypto.encryptEvent(event, room);\n}\n\nfunction _updatePendingEventStatus(room, event, newStatus) {\n if (room) {\n room.updatePendingEvent(event, newStatus);\n } else {\n event.status = newStatus;\n }\n}\n\nfunction _sendEventHttpRequest(client, event) {\n const txnId = event._txnId ? event._txnId : client.makeTxnId();\n\n const pathParams = {\n $roomId: event.getRoomId(),\n $eventType: event.getWireType(),\n $stateKey: event.getStateKey(),\n $txnId: txnId,\n };\n\n let path;\n\n if (event.isState()) {\n let pathTemplate = \"/rooms/$roomId/state/$eventType\";\n if (event.getStateKey() && event.getStateKey().length > 0) {\n pathTemplate = \"/rooms/$roomId/state/$eventType/$stateKey\";\n }\n path = utils.encodeUri(pathTemplate, pathParams);\n } else {\n path = utils.encodeUri(\n \"/rooms/$roomId/send/$eventType/$txnId\", pathParams,\n );\n }\n\n return client._http.authedRequest(\n undefined, \"PUT\", path, undefined, event.getWireContent(),\n ).then((res) => {\n console.log(\n `Event sent to ${event.getRoomId()} with event id ${res.event_id}`,\n );\n return res;\n });\n}\n\n/**\n * @param {string} roomId\n * @param {Object} content\n * @param {string} txnId Optional.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendMessage = function(roomId, content, txnId, callback) {\n if (utils.isFunction(txnId)) {\n callback = txnId; txnId = undefined;\n }\n return this.sendEvent(\n roomId, \"m.room.message\", content, txnId, callback,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {string} body\n * @param {string} txnId Optional.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendTextMessage = function(roomId, body, txnId, callback) {\n const content = {\n msgtype: \"m.text\",\n body: body,\n };\n return this.sendMessage(roomId, content, txnId, callback);\n};\n\n/**\n * @param {string} roomId\n * @param {string} body\n * @param {string} txnId Optional.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendNotice = function(roomId, body, txnId, callback) {\n const content = {\n msgtype: \"m.notice\",\n body: body,\n };\n return this.sendMessage(roomId, content, txnId, callback);\n};\n\n/**\n * @param {string} roomId\n * @param {string} body\n * @param {string} txnId Optional.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendEmoteMessage = function(roomId, body, txnId, callback) {\n const content = {\n msgtype: \"m.emote\",\n body: body,\n };\n return this.sendMessage(roomId, content, txnId, callback);\n};\n\n/**\n * @param {string} roomId\n * @param {string} url\n * @param {Object} info\n * @param {string} text\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendImageMessage = function(roomId, url, info, text, callback) {\n if (utils.isFunction(text)) {\n callback = text; text = undefined;\n }\n if (!text) {\n text = \"Image\";\n }\n const content = {\n msgtype: \"m.image\",\n url: url,\n info: info,\n body: text,\n };\n return this.sendMessage(roomId, content, callback);\n};\n\n/**\n * @param {string} roomId\n * @param {string} body\n * @param {string} htmlBody\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendHtmlMessage = function(roomId, body, htmlBody, callback) {\n const content = {\n msgtype: \"m.text\",\n format: \"org.matrix.custom.html\",\n body: body,\n formatted_body: htmlBody,\n };\n return this.sendMessage(roomId, content, callback);\n};\n\n/**\n * @param {string} roomId\n * @param {string} body\n * @param {string} htmlBody\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendHtmlNotice = function(roomId, body, htmlBody, callback) {\n const content = {\n msgtype: \"m.notice\",\n format: \"org.matrix.custom.html\",\n body: body,\n formatted_body: htmlBody,\n };\n return this.sendMessage(roomId, content, callback);\n};\n\n/**\n * @param {string} roomId\n * @param {string} body\n * @param {string} htmlBody\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendHtmlEmote = function(roomId, body, htmlBody, callback) {\n const content = {\n msgtype: \"m.emote\",\n format: \"org.matrix.custom.html\",\n body: body,\n formatted_body: htmlBody,\n };\n return this.sendMessage(roomId, content, callback);\n};\n\n/**\n * Send a receipt.\n * @param {Event} event The event being acknowledged\n * @param {string} receiptType The kind of receipt e.g. \"m.read\"\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendReceipt = function(event, receiptType, callback) {\n if (this.isGuest()) {\n return Promise.resolve({}); // guests cannot send receipts so don't bother.\n }\n\n const path = utils.encodeUri(\"/rooms/$roomId/receipt/$receiptType/$eventId\", {\n $roomId: event.getRoomId(),\n $receiptType: receiptType,\n $eventId: event.getId(),\n });\n const promise = this._http.authedRequest(\n callback, \"POST\", path, undefined, {},\n );\n\n const room = this.getRoom(event.getRoomId());\n if (room) {\n room._addLocalEchoReceipt(this.credentials.userId, event, receiptType);\n }\n return promise;\n};\n\n/**\n * Send a read receipt.\n * @param {Event} event The event that has been read.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendReadReceipt = function(event, callback) {\n return this.sendReceipt(event, \"m.read\", callback);\n};\n\n/**\n * Set a marker to indicate the point in a room before which the user has read every\n * event. This can be retrieved from room account data (the event type is `m.fully_read`)\n * and displayed as a horizontal line in the timeline that is visually distinct to the\n * position of the user's own read receipt.\n * @param {string} roomId ID of the room that has been read\n * @param {string} eventId ID of the event that has been read\n * @param {string} rrEvent the event tracked by the read receipt. This is here for\n * convenience because the RR and the RM are commonly updated at the same time as each\n * other. The local echo of this receipt will be done if set. Optional.\n * @return {module:client.Promise} Resolves: the empty object, {}.\n */\nMatrixClient.prototype.setRoomReadMarkers = function(roomId, eventId, rrEvent) {\n const rmEventId = eventId;\n let rrEventId;\n\n // Add the optional RR update, do local echo like `sendReceipt`\n if (rrEvent) {\n rrEventId = rrEvent.getId();\n const room = this.getRoom(roomId);\n if (room) {\n room._addLocalEchoReceipt(this.credentials.userId, rrEvent, \"m.read\");\n }\n }\n\n return this.setRoomReadMarkersHttpRequest(roomId, rmEventId, rrEventId);\n};\n\n/**\n * Get a preview of the given URL as of (roughly) the given point in time,\n * described as an object with OpenGraph keys and associated values.\n * Attributes may be synthesized where actual OG metadata is lacking.\n * Caches results to prevent hammering the server.\n * @param {string} url The URL to get preview data for\n * @param {Number} ts The preferred point in time that the preview should\n * describe (ms since epoch). The preview returned will either be the most\n * recent one preceding this timestamp if available, or failing that the next\n * most recent available preview.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: Object of OG metadata.\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n * May return synthesized attributes if the URL lacked OG meta.\n */\nMatrixClient.prototype.getUrlPreview = function(url, ts, callback) {\n const key = ts + \"_\" + url;\n const og = this.urlPreviewCache[key];\n if (og) {\n return Promise.resolve(og);\n }\n\n const self = this;\n return this._http.authedRequestWithPrefix(\n callback, \"GET\", \"/preview_url\", {\n url: url,\n ts: ts,\n }, undefined, httpApi.PREFIX_MEDIA_R0,\n ).then(function(response) {\n // TODO: expire cache occasionally\n self.urlPreviewCache[key] = response;\n return response;\n });\n};\n\n/**\n * @param {string} roomId\n * @param {boolean} isTyping\n * @param {Number} timeoutMs\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.sendTyping = function(roomId, isTyping, timeoutMs, callback) {\n if (this.isGuest()) {\n return Promise.resolve({}); // guests cannot send typing notifications so don't bother.\n }\n\n const path = utils.encodeUri(\"/rooms/$roomId/typing/$userId\", {\n $roomId: roomId,\n $userId: this.credentials.userId,\n });\n const data = {\n typing: isTyping,\n };\n if (isTyping) {\n data.timeout = timeoutMs ? timeoutMs : 20000;\n }\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, data,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {string} userId\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.invite = function(roomId, userId, callback) {\n return _membershipChange(this, roomId, userId, \"invite\", undefined,\n callback);\n};\n\n/**\n * Invite a user to a room based on their email address.\n * @param {string} roomId The room to invite the user to.\n * @param {string} email The email address to invite.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.inviteByEmail = function(roomId, email, callback) {\n return this.inviteByThreePid(\n roomId, \"email\", email, callback,\n );\n};\n\n/**\n * Invite a user to a room based on a third-party identifier.\n * @param {string} roomId The room to invite the user to.\n * @param {string} medium The medium to invite the user e.g. \"email\".\n * @param {string} address The address for the specified medium.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.inviteByThreePid = function(roomId, medium, address, callback) {\n const path = utils.encodeUri(\n \"/rooms/$roomId/invite\",\n { $roomId: roomId },\n );\n\n let identityServerUrl = this.getIdentityServerUrl();\n if (!identityServerUrl) {\n return Promise.reject(new MatrixError({\n error: \"No supplied identity server URL\",\n errcode: \"ORG.MATRIX.JSSDK_MISSING_PARAM\",\n }));\n }\n if (identityServerUrl.indexOf(\"http://\") === 0 ||\n identityServerUrl.indexOf(\"https://\") === 0) {\n // this request must not have the protocol part because reasons\n identityServerUrl = identityServerUrl.split(\"://\")[1];\n }\n\n return this._http.authedRequest(callback, \"POST\", path, undefined, {\n id_server: identityServerUrl,\n medium: medium,\n address: address,\n });\n};\n\n/**\n * @param {string} roomId\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.leave = function(roomId, callback) {\n return _membershipChange(this, roomId, undefined, \"leave\", undefined,\n callback);\n};\n\n/**\n * @param {string} roomId\n * @param {string} userId\n * @param {string} reason Optional.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.ban = function(roomId, userId, reason, callback) {\n return _membershipChange(this, roomId, userId, \"ban\", reason,\n callback);\n};\n\n/**\n * @param {string} roomId\n * @param {boolean} deleteRoom True to delete the room from the store on success.\n * Default: true.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.forget = function(roomId, deleteRoom, callback) {\n if (deleteRoom === undefined) {\n deleteRoom = true;\n }\n const promise = _membershipChange(this, roomId, undefined, \"forget\", undefined,\n callback);\n if (!deleteRoom) {\n return promise;\n }\n const self = this;\n return promise.then(function(response) {\n self.store.removeRoom(roomId);\n self.emit(\"deleteRoom\", roomId);\n return response;\n });\n};\n\n/**\n * @param {string} roomId\n * @param {string} userId\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: Object (currently empty)\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.unban = function(roomId, userId, callback) {\n // unbanning != set their state to leave: this used to be\n // the case, but was then changed so that leaving was always\n // a revoking of priviledge, otherwise two people racing to\n // kick / ban someone could end up banning and then un-banning\n // them.\n const path = utils.encodeUri(\"/rooms/$roomId/unban\", {\n $roomId: roomId,\n });\n const data = {\n user_id: userId,\n };\n return this._http.authedRequest(\n callback, \"POST\", path, undefined, data,\n );\n};\n\n/**\n * @param {string} roomId\n * @param {string} userId\n * @param {string} reason Optional.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.kick = function(roomId, userId, reason, callback) {\n return _setMembershipState(\n this, roomId, userId, \"leave\", reason, callback,\n );\n};\n\n/**\n * This is an internal method.\n * @param {MatrixClient} client\n * @param {string} roomId\n * @param {string} userId\n * @param {string} membershipValue\n * @param {string} reason\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nfunction _setMembershipState(client, roomId, userId, membershipValue, reason,\n callback) {\n if (utils.isFunction(reason)) {\n callback = reason; reason = undefined;\n }\n\n const path = utils.encodeUri(\n \"/rooms/$roomId/state/m.room.member/$userId\",\n { $roomId: roomId, $userId: userId},\n );\n\n return client._http.authedRequest(callback, \"PUT\", path, undefined, {\n membership: membershipValue,\n reason: reason,\n });\n}\n\n/**\n * This is an internal method.\n * @param {MatrixClient} client\n * @param {string} roomId\n * @param {string} userId\n * @param {string} membership\n * @param {string} reason\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nfunction _membershipChange(client, roomId, userId, membership, reason, callback) {\n if (utils.isFunction(reason)) {\n callback = reason; reason = undefined;\n }\n\n const path = utils.encodeUri(\"/rooms/$room_id/$membership\", {\n $room_id: roomId,\n $membership: membership,\n });\n return client._http.authedRequest(\n callback, \"POST\", path, undefined, {\n user_id: userId, // may be undefined e.g. on leave\n reason: reason,\n },\n );\n}\n\n/**\n * Obtain a dict of actions which should be performed for this event according\n * to the push rules for this user. Caches the dict on the event.\n * @param {MatrixEvent} event The event to get push actions for.\n * @return {module:pushprocessor~PushAction} A dict of actions to perform.\n */\nMatrixClient.prototype.getPushActionsForEvent = function(event) {\n if (!event.getPushActions()) {\n const pushProcessor = new PushProcessor(this);\n event.setPushActions(pushProcessor.actionsForEvent(event));\n }\n return event.getPushActions();\n};\n\n// Profile operations\n// ==================\n\n/**\n * @param {string} info The kind of info to set (e.g. 'avatar_url')\n * @param {Object} data The JSON object to set.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setProfileInfo = function(info, data, callback) {\n const path = utils.encodeUri(\"/profile/$userId/$info\", {\n $userId: this.credentials.userId,\n $info: info,\n });\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, data,\n );\n};\n\n/**\n * @param {string} name\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setDisplayName = function(name, callback) {\n return this.setProfileInfo(\n \"displayname\", { displayname: name }, callback,\n );\n};\n\n/**\n * @param {string} url\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setAvatarUrl = function(url, callback) {\n return this.setProfileInfo(\n \"avatar_url\", { avatar_url: url }, callback,\n );\n};\n\n/**\n * Turn an MXC URL into an HTTP one. This method is experimental and\n * may change.\n * @param {string} mxcUrl The MXC URL\n * @param {Number} width The desired width of the thumbnail.\n * @param {Number} height The desired height of the thumbnail.\n * @param {string} resizeMethod The thumbnail resize method to use, either\n * \"crop\" or \"scale\".\n * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs\n * directly. Fetching such URLs will leak information about the user to\n * anyone they share a room with. If false, will return null for such URLs.\n * @return {?string} the avatar URL or null.\n */\nMatrixClient.prototype.mxcUrlToHttp =\n function(mxcUrl, width, height, resizeMethod, allowDirectLinks) {\n return contentRepo.getHttpUriForMxc(\n this.baseUrl, mxcUrl, width, height, resizeMethod, allowDirectLinks,\n );\n};\n\n/**\n * @param {Object} opts Options to apply\n * @param {string} opts.presence One of \"online\", \"offline\" or \"unavailable\"\n * @param {string} opts.status_msg The status message to attach.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n * @throws If 'presence' isn't a valid presence enum value.\n */\nMatrixClient.prototype.setPresence = function(opts, callback) {\n const path = utils.encodeUri(\"/presence/$userId/status\", {\n $userId: this.credentials.userId,\n });\n\n if (typeof opts === \"string\") {\n opts = { presence: opts };\n }\n\n const validStates = [\"offline\", \"online\", \"unavailable\"];\n if (validStates.indexOf(opts.presence) == -1) {\n throw new Error(\"Bad presence value: \" + opts.presence);\n }\n return this._http.authedRequest(\n callback, \"PUT\", path, undefined, opts,\n );\n};\n\nfunction _presenceList(callback, client, opts, method) {\n const path = utils.encodeUri(\"/presence/list/$userId\", {\n $userId: client.credentials.userId,\n });\n return client._http.authedRequest(callback, method, path, undefined, opts);\n}\n\n/**\n* Retrieve current user presence list.\n* @param {module:client.callback} callback Optional.\n* @return {module:client.Promise} Resolves: TODO\n* @return {module:http-api.MatrixError} Rejects: with an error response.\n*/\nMatrixClient.prototype.getPresenceList = function(callback) {\n return _presenceList(callback, this, undefined, \"GET\");\n};\n\n/**\n* Add users to the current user presence list.\n* @param {module:client.callback} callback Optional.\n* @param {string[]} userIds\n* @return {module:client.Promise} Resolves: TODO\n* @return {module:http-api.MatrixError} Rejects: with an error response.\n*/\nMatrixClient.prototype.inviteToPresenceList = function(callback, userIds) {\n const opts = {\"invite\": userIds};\n return _presenceList(callback, this, opts, \"POST\");\n};\n\n/**\n* Drop users from the current user presence list.\n* @param {module:client.callback} callback Optional.\n* @param {string[]} userIds\n* @return {module:client.Promise} Resolves: TODO\n* @return {module:http-api.MatrixError} Rejects: with an error response.\n**/\nMatrixClient.prototype.dropFromPresenceList = function(callback, userIds) {\n const opts = {\"drop\": userIds};\n return _presenceList(callback, this, opts, \"POST\");\n};\n\n/**\n * Retrieve older messages from the given room and put them in the timeline.\n *\n * If this is called multiple times whilst a request is ongoing, the same\n * Promise will be returned. If there was a problem requesting scrollback, there\n * will be a small delay before another request can be made (to prevent tight-looping\n * when there is no connection).\n *\n * @param {Room} room The room to get older messages in.\n * @param {Integer} limit Optional. The maximum number of previous events to\n * pull in. Default: 30.\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: Room. If you are at the beginning\n * of the timeline, Room.oldState.paginationToken will be\n * null.\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.scrollback = function(room, limit, callback) {\n if (utils.isFunction(limit)) {\n callback = limit; limit = undefined;\n }\n limit = limit || 30;\n let timeToWaitMs = 0;\n\n let info = this._ongoingScrollbacks[room.roomId] || {};\n if (info.promise) {\n return info.promise;\n } else if (info.errorTs) {\n const timeWaitedMs = Date.now() - info.errorTs;\n timeToWaitMs = Math.max(SCROLLBACK_DELAY_MS - timeWaitedMs, 0);\n }\n\n if (room.oldState.paginationToken === null) {\n return Promise.resolve(room); // already at the start.\n }\n // attempt to grab more events from the store first\n const numAdded = this.store.scrollback(room, limit).length;\n if (numAdded === limit) {\n // store contained everything we needed.\n return Promise.resolve(room);\n }\n // reduce the required number of events appropriately\n limit = limit - numAdded;\n\n const path = utils.encodeUri(\n \"/rooms/$roomId/messages\", {$roomId: room.roomId},\n );\n const params = {\n from: room.oldState.paginationToken,\n limit: limit,\n dir: 'b',\n };\n const defer = Promise.defer();\n info = {\n promise: defer.promise,\n errorTs: null,\n };\n const self = this;\n // wait for a time before doing this request\n // (which may be 0 in order not to special case the code paths)\n Promise.delay(timeToWaitMs).then(function() {\n return self._http.authedRequest(callback, \"GET\", path, params);\n }).done(function(res) {\n const matrixEvents = utils.map(res.chunk, _PojoToMatrixEventMapper(self));\n room.addEventsToTimeline(matrixEvents, true, room.getLiveTimeline());\n room.oldState.paginationToken = res.end;\n if (res.chunk.length === 0) {\n room.oldState.paginationToken = null;\n }\n self.store.storeEvents(room, matrixEvents, res.end, true);\n self._ongoingScrollbacks[room.roomId] = null;\n _resolve(callback, defer, room);\n }, function(err) {\n self._ongoingScrollbacks[room.roomId] = {\n errorTs: Date.now(),\n };\n _reject(callback, defer, err);\n });\n this._ongoingScrollbacks[room.roomId] = info;\n return defer.promise;\n};\n\n/**\n * Take an EventContext, and back/forward-fill results.\n *\n * @param {module:models/event-context.EventContext} eventContext context\n * object to be updated\n * @param {Object} opts\n * @param {boolean} opts.backwards true to fill backwards, false to go forwards\n * @param {boolean} opts.limit number of events to request\n *\n * @return {module:client.Promise} Resolves: updated EventContext object\n * @return {Error} Rejects: with an error response.\n */\nMatrixClient.prototype.paginateEventContext = function(eventContext, opts) {\n // TODO: we should implement a backoff (as per scrollback()) to deal more\n // nicely with HTTP errors.\n opts = opts || {};\n const backwards = opts.backwards || false;\n\n const token = eventContext.getPaginateToken(backwards);\n if (!token) {\n // no more results.\n return Promise.reject(new Error(\"No paginate token\"));\n }\n\n const dir = backwards ? 'b' : 'f';\n const pendingRequest = eventContext._paginateRequests[dir];\n\n if (pendingRequest) {\n // already a request in progress - return the existing promise\n return pendingRequest;\n }\n\n const path = utils.encodeUri(\n \"/rooms/$roomId/messages\", {$roomId: eventContext.getEvent().getRoomId()},\n );\n const params = {\n from: token,\n limit: ('limit' in opts) ? opts.limit : 30,\n dir: dir,\n };\n\n const self = this;\n const promise =\n self._http.authedRequest(undefined, \"GET\", path, params,\n ).then(function(res) {\n let token = res.end;\n if (res.chunk.length === 0) {\n token = null;\n } else {\n const matrixEvents = utils.map(res.chunk, self.getEventMapper());\n if (backwards) {\n // eventContext expects the events in timeline order, but\n // back-pagination returns them in reverse order.\n matrixEvents.reverse();\n }\n eventContext.addEvents(matrixEvents, backwards);\n }\n eventContext.setPaginateToken(token, backwards);\n return eventContext;\n }).finally(function() {\n eventContext._paginateRequests[dir] = null;\n });\n eventContext._paginateRequests[dir] = promise;\n\n return promise;\n};\n\n/**\n * Get an EventTimeline for the given event\n *\n *

If the EventTimelineSet object already has the given event in its store, the\n * corresponding timeline will be returned. Otherwise, a /context request is\n * made, and used to construct an EventTimeline.\n *\n * @param {EventTimelineSet} timelineSet The timelineSet to look for the event in\n * @param {string} eventId The ID of the event to look for\n *\n * @return {module:client.Promise} Resolves:\n * {@link module:models/event-timeline~EventTimeline} including the given\n * event\n */\nMatrixClient.prototype.getEventTimeline = function(timelineSet, eventId) {\n // don't allow any timeline support unless it's been enabled.\n if (!this.timelineSupport) {\n throw new Error(\"timeline support is disabled. Set the 'timelineSupport'\" +\n \" parameter to true when creating MatrixClient to enable\" +\n \" it.\");\n }\n\n if (timelineSet.getTimelineForEvent(eventId)) {\n return Promise.resolve(timelineSet.getTimelineForEvent(eventId));\n }\n\n const path = utils.encodeUri(\n \"/rooms/$roomId/context/$eventId\", {\n $roomId: timelineSet.room.roomId,\n $eventId: eventId,\n },\n );\n\n // TODO: we should implement a backoff (as per scrollback()) to deal more\n // nicely with HTTP errors.\n const self = this;\n const promise =\n self._http.authedRequest(undefined, \"GET\", path,\n ).then(function(res) {\n if (!res.event) {\n throw new Error(\"'event' not in '/context' result - homeserver too old?\");\n }\n\n // by the time the request completes, the event might have ended up in\n // the timeline.\n if (timelineSet.getTimelineForEvent(eventId)) {\n return timelineSet.getTimelineForEvent(eventId);\n }\n\n // we start with the last event, since that's the point at which we\n // have known state.\n // events_after is already backwards; events_before is forwards.\n res.events_after.reverse();\n const events = res.events_after\n .concat([res.event])\n .concat(res.events_before);\n const matrixEvents = utils.map(events, self.getEventMapper());\n\n let timeline = timelineSet.getTimelineForEvent(matrixEvents[0].getId());\n if (!timeline) {\n timeline = timelineSet.addTimeline();\n timeline.initialiseState(utils.map(res.state,\n self.getEventMapper()));\n timeline.getState(EventTimeline.FORWARDS).paginationToken = res.end;\n }\n timelineSet.addEventsToTimeline(matrixEvents, true, timeline, res.start);\n\n // there is no guarantee that the event ended up in \"timeline\" (we\n // might have switched to a neighbouring timeline) - so check the\n // room's index again. On the other hand, there's no guarantee the\n // event ended up anywhere, if it was later redacted, so we just\n // return the timeline we first thought of.\n const tl = timelineSet.getTimelineForEvent(eventId) || timeline;\n return tl;\n });\n return promise;\n};\n\n\n/**\n * Take an EventTimeline, and back/forward-fill results.\n *\n * @param {module:models/event-timeline~EventTimeline} eventTimeline timeline\n * object to be updated\n * @param {Object} [opts]\n * @param {bool} [opts.backwards = false] true to fill backwards,\n * false to go forwards\n * @param {number} [opts.limit = 30] number of events to request\n *\n * @return {module:client.Promise} Resolves to a boolean: false if there are no\n * events and we reached either end of the timeline; else true.\n */\nMatrixClient.prototype.paginateEventTimeline = function(eventTimeline, opts) {\n const isNotifTimeline = (eventTimeline.getTimelineSet() === this._notifTimelineSet);\n\n // TODO: we should implement a backoff (as per scrollback()) to deal more\n // nicely with HTTP errors.\n opts = opts || {};\n const backwards = opts.backwards || false;\n\n if (isNotifTimeline) {\n if (!backwards) {\n throw new Error(\"paginateNotifTimeline can only paginate backwards\");\n }\n }\n\n const dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;\n\n const token = eventTimeline.getPaginationToken(dir);\n if (!token) {\n // no token - no results.\n return Promise.resolve(false);\n }\n\n const pendingRequest = eventTimeline._paginationRequests[dir];\n\n if (pendingRequest) {\n // already a request in progress - return the existing promise\n return pendingRequest;\n }\n\n let path, params, promise;\n const self = this;\n\n if (isNotifTimeline) {\n path = \"/notifications\";\n params = {\n limit: ('limit' in opts) ? opts.limit : 30,\n only: 'highlight',\n };\n\n if (token && token !== \"end\") {\n params.from = token;\n }\n\n promise =\n this._http.authedRequestWithPrefix(undefined, \"GET\", path, params,\n undefined, httpApi.PREFIX_UNSTABLE,\n ).then(function(res) {\n const token = res.next_token;\n const matrixEvents = [];\n\n for (let i = 0; i < res.notifications.length; i++) {\n const notification = res.notifications[i];\n const event = self.getEventMapper()(notification.event);\n event.setPushActions(\n PushProcessor.actionListToActionsObject(notification.actions),\n );\n event.event.room_id = notification.room_id; // XXX: gutwrenching\n matrixEvents[i] = event;\n }\n\n eventTimeline.getTimelineSet()\n .addEventsToTimeline(matrixEvents, backwards, eventTimeline, token);\n\n // if we've hit the end of the timeline, we need to stop trying to\n // paginate. We need to keep the 'forwards' token though, to make sure\n // we can recover from gappy syncs.\n if (backwards && !res.next_token) {\n eventTimeline.setPaginationToken(null, dir);\n }\n return res.next_token ? true : false;\n }).finally(function() {\n eventTimeline._paginationRequests[dir] = null;\n });\n eventTimeline._paginationRequests[dir] = promise;\n } else {\n const room = this.getRoom(eventTimeline.getRoomId());\n if (!room) {\n throw new Error(\"Unknown room \" + eventTimeline.getRoomId());\n }\n\n path = utils.encodeUri(\n \"/rooms/$roomId/messages\", {$roomId: eventTimeline.getRoomId()},\n );\n params = {\n from: token,\n limit: ('limit' in opts) ? opts.limit : 30,\n dir: dir,\n };\n\n const filter = eventTimeline.getFilter();\n if (filter) {\n // XXX: it's horrific that /messages' filter parameter doesn't match\n // /sync's one - see https://matrix.org/jira/browse/SPEC-451\n params.filter = JSON.stringify(filter.getRoomTimelineFilterComponent());\n }\n\n promise =\n this._http.authedRequest(undefined, \"GET\", path, params,\n ).then(function(res) {\n const token = res.end;\n const matrixEvents = utils.map(res.chunk, self.getEventMapper());\n eventTimeline.getTimelineSet()\n .addEventsToTimeline(matrixEvents, backwards, eventTimeline, token);\n\n // if we've hit the end of the timeline, we need to stop trying to\n // paginate. We need to keep the 'forwards' token though, to make sure\n // we can recover from gappy syncs.\n if (backwards && res.end == res.start) {\n eventTimeline.setPaginationToken(null, dir);\n }\n return res.end != res.start;\n }).finally(function() {\n eventTimeline._paginationRequests[dir] = null;\n });\n eventTimeline._paginationRequests[dir] = promise;\n }\n\n return promise;\n};\n\n/**\n * Reset the notifTimelineSet entirely, paginating in some historical notifs as\n * a starting point for subsequent pagination.\n */\nMatrixClient.prototype.resetNotifTimelineSet = function() {\n if (!this._notifTimelineSet) {\n return;\n }\n\n // FIXME: This thing is a total hack, and results in duplicate events being\n // added to the timeline both from /sync and /notifications, and lots of\n // slow and wasteful processing and pagination. The correct solution is to\n // extend /messages or /search or something to filter on notifications.\n\n // use the fictitious token 'end'. in practice we would ideally give it\n // the oldest backwards pagination token from /sync, but /sync doesn't\n // know about /notifications, so we have no choice but to start paginating\n // from the current point in time. This may well overlap with historical\n // notifs which are then inserted into the timeline by /sync responses.\n this._notifTimelineSet.resetLiveTimeline('end', null);\n\n // we could try to paginate a single event at this point in order to get\n // a more valid pagination token, but it just ends up with an out of order\n // timeline. given what a mess this is and given we're going to have duplicate\n // events anyway, just leave it with the dummy token for now.\n /*\n this.paginateNotifTimeline(this._notifTimelineSet.getLiveTimeline(), {\n backwards: true,\n limit: 1\n });\n */\n};\n\n/**\n * Peek into a room and receive updates about the room. This only works if the\n * history visibility for the room is world_readable.\n * @param {String} roomId The room to attempt to peek into.\n * @return {module:client.Promise} Resolves: Room object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.peekInRoom = function(roomId) {\n if (this._peekSync) {\n this._peekSync.stopPeeking();\n }\n this._peekSync = new SyncApi(this, this._clientOpts);\n return this._peekSync.peek(roomId);\n};\n\n/**\n * Stop any ongoing room peeking.\n */\nMatrixClient.prototype.stopPeeking = function() {\n if (this._peekSync) {\n this._peekSync.stopPeeking();\n this._peekSync = null;\n }\n};\n\n/**\n * Set r/w flags for guest access in a room.\n * @param {string} roomId The room to configure guest access in.\n * @param {Object} opts Options\n * @param {boolean} opts.allowJoin True to allow guests to join this room. This\n * implicitly gives guests write access. If false or not given, guests are\n * explicitly forbidden from joining the room.\n * @param {boolean} opts.allowRead True to set history visibility to\n * be world_readable. This gives guests read access *from this point forward*.\n * If false or not given, history visibility is not modified.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setGuestAccess = function(roomId, opts) {\n const writePromise = this.sendStateEvent(roomId, \"m.room.guest_access\", {\n guest_access: opts.allowJoin ? \"can_join\" : \"forbidden\",\n });\n\n let readPromise = Promise.resolve();\n if (opts.allowRead) {\n readPromise = this.sendStateEvent(roomId, \"m.room.history_visibility\", {\n history_visibility: \"world_readable\",\n });\n }\n\n return Promise.all([readPromise, writePromise]);\n};\n\n// Registration/Login operations\n// =============================\n\n/**\n * Requests an email verification token for the purposes of registration.\n * This API proxies the Identity Server /validate/email/requestToken API,\n * adding registration-specific behaviour. Specifically, if an account with\n * the given email address already exists, it will either send an email\n * to the address informing them of this or return M_THREEPID_IN_USE\n * (which one is up to the Home Server).\n *\n * requestEmailToken calls the equivalent API directly on the ID server,\n * therefore bypassing the registration-specific logic.\n *\n * Parameters and return value are as for requestEmailToken\n\n * @param {string} email As requestEmailToken\n * @param {string} clientSecret As requestEmailToken\n * @param {number} sendAttempt As requestEmailToken\n * @param {string} nextLink As requestEmailToken\n * @return {module:client.Promise} Resolves: As requestEmailToken\n */\nMatrixClient.prototype.requestRegisterEmailToken = function(email, clientSecret,\n sendAttempt, nextLink) {\n return this._requestTokenFromEndpoint(\n \"/register/email/requestToken\",\n {\n email: email,\n client_secret: clientSecret,\n send_attempt: sendAttempt,\n next_link: nextLink,\n },\n );\n};\n\n/**\n * Requests a text message verification token for the purposes of registration.\n * This API proxies the Identity Server /validate/msisdn/requestToken API,\n * adding registration-specific behaviour, as with requestRegisterEmailToken.\n *\n * @param {string} phoneCountry The ISO 3166-1 alpha-2 code for the country in which\n * phoneNumber should be parsed relative to.\n * @param {string} phoneNumber The phone number, in national or international format\n * @param {string} clientSecret As requestEmailToken\n * @param {number} sendAttempt As requestEmailToken\n * @param {string} nextLink As requestEmailToken\n * @return {module:client.Promise} Resolves: As requestEmailToken\n */\nMatrixClient.prototype.requestRegisterMsisdnToken = function(phoneCountry, phoneNumber,\n clientSecret, sendAttempt, nextLink) {\n return this._requestTokenFromEndpoint(\n \"/register/msisdn/requestToken\",\n {\n country: phoneCountry,\n phone_number: phoneNumber,\n client_secret: clientSecret,\n send_attempt: sendAttempt,\n next_link: nextLink,\n },\n );\n};\n\n/**\n * Requests an email verification token for the purposes of adding a\n * third party identifier to an account.\n * This API proxies the Identity Server /validate/email/requestToken API,\n * adding specific behaviour for the addition of email addresses to an\n * account. Specifically, if an account with\n * the given email address already exists, it will either send an email\n * to the address informing them of this or return M_THREEPID_IN_USE\n * (which one is up to the Home Server).\n *\n * requestEmailToken calls the equivalent API directly on the ID server,\n * therefore bypassing the email addition specific logic.\n *\n * @param {string} email As requestEmailToken\n * @param {string} clientSecret As requestEmailToken\n * @param {number} sendAttempt As requestEmailToken\n * @param {string} nextLink As requestEmailToken\n * @return {module:client.Promise} Resolves: As requestEmailToken\n */\nMatrixClient.prototype.requestAdd3pidEmailToken = function(email, clientSecret,\n sendAttempt, nextLink) {\n return this._requestTokenFromEndpoint(\n \"/account/3pid/email/requestToken\",\n {\n email: email,\n client_secret: clientSecret,\n send_attempt: sendAttempt,\n next_link: nextLink,\n },\n );\n};\n\n/**\n * Requests a text message verification token for the purposes of adding a\n * third party identifier to an account.\n * This API proxies the Identity Server /validate/email/requestToken API,\n * adding specific behaviour for the addition of phone numbers to an\n * account, as requestAdd3pidEmailToken.\n *\n * @param {string} phoneCountry As requestRegisterMsisdnToken\n * @param {string} phoneNumber As requestRegisterMsisdnToken\n * @param {string} clientSecret As requestEmailToken\n * @param {number} sendAttempt As requestEmailToken\n * @param {string} nextLink As requestEmailToken\n * @return {module:client.Promise} Resolves: As requestEmailToken\n */\nMatrixClient.prototype.requestAdd3pidMsisdnToken = function(phoneCountry, phoneNumber,\n clientSecret, sendAttempt, nextLink) {\n return this._requestTokenFromEndpoint(\n \"/account/3pid/msisdn/requestToken\",\n {\n country: phoneCountry,\n phone_number: phoneNumber,\n client_secret: clientSecret,\n send_attempt: sendAttempt,\n next_link: nextLink,\n },\n );\n};\n\n/**\n * Requests an email verification token for the purposes of resetting\n * the password on an account.\n * This API proxies the Identity Server /validate/email/requestToken API,\n * adding specific behaviour for the password resetting. Specifically,\n * if no account with the given email address exists, it may either\n * return M_THREEPID_NOT_FOUND or send an email\n * to the address informing them of this (which one is up to the Home Server).\n *\n * requestEmailToken calls the equivalent API directly on the ID server,\n * therefore bypassing the password reset specific logic.\n *\n * @param {string} email As requestEmailToken\n * @param {string} clientSecret As requestEmailToken\n * @param {number} sendAttempt As requestEmailToken\n * @param {string} nextLink As requestEmailToken\n * @param {module:client.callback} callback Optional. As requestEmailToken\n * @return {module:client.Promise} Resolves: As requestEmailToken\n */\nMatrixClient.prototype.requestPasswordEmailToken = function(email, clientSecret,\n sendAttempt, nextLink) {\n return this._requestTokenFromEndpoint(\n \"/account/password/email/requestToken\",\n {\n email: email,\n client_secret: clientSecret,\n send_attempt: sendAttempt,\n next_link: nextLink,\n },\n );\n};\n\n/**\n * Requests a text message verification token for the purposes of resetting\n * the password on an account.\n * This API proxies the Identity Server /validate/email/requestToken API,\n * adding specific behaviour for the password resetting, as requestPasswordEmailToken.\n *\n * @param {string} phoneCountry As requestRegisterMsisdnToken\n * @param {string} phoneNumber As requestRegisterMsisdnToken\n * @param {string} clientSecret As requestEmailToken\n * @param {number} sendAttempt As requestEmailToken\n * @param {string} nextLink As requestEmailToken\n * @return {module:client.Promise} Resolves: As requestEmailToken\n */\nMatrixClient.prototype.requestPasswordMsisdnToken = function(phoneCountry, phoneNumber,\n clientSecret, sendAttempt, nextLink) {\n return this._requestTokenFromEndpoint(\n \"/account/password/msisdn/requestToken\",\n {\n country: phoneCountry,\n phone_number: phoneNumber,\n client_secret: clientSecret,\n send_attempt: sendAttempt,\n next_link: nextLink,\n },\n );\n};\n\n/**\n * Internal utility function for requesting validation tokens from usage-specific\n * requestToken endpoints.\n *\n * @param {string} endpoint The endpoint to send the request to\n * @param {object} params Parameters for the POST request\n * @return {module:client.Promise} Resolves: As requestEmailToken\n */\nMatrixClient.prototype._requestTokenFromEndpoint = function(endpoint, params) {\n const id_server_url = url.parse(this.idBaseUrl);\n if (id_server_url.host === null) {\n throw new Error(\"Invalid ID server URL: \" + this.idBaseUrl);\n }\n\n const postParams = Object.assign({}, params, {\n id_server: id_server_url.host,\n });\n return this._http.request(\n undefined, \"POST\", endpoint, undefined,\n postParams,\n );\n};\n\n\n// Push operations\n// ===============\n\n/**\n * Get the room-kind push rule associated with a room.\n * @param {string} scope \"global\" or device-specific.\n * @param {string} roomId the id of the room.\n * @return {object} the rule or undefined.\n */\nMatrixClient.prototype.getRoomPushRule = function(scope, roomId) {\n // There can be only room-kind push rule per room\n // and its id is the room id.\n if (this.pushRules) {\n for (let i = 0; i < this.pushRules[scope].room.length; i++) {\n const rule = this.pushRules[scope].room[i];\n if (rule.rule_id === roomId) {\n return rule;\n }\n }\n } else {\n throw new Error(\n \"SyncApi.sync() must be done before accessing to push rules.\",\n );\n }\n};\n\n/**\n * Set a room-kind muting push rule in a room.\n * The operation also updates MatrixClient.pushRules at the end.\n * @param {string} scope \"global\" or device-specific.\n * @param {string} roomId the id of the room.\n * @param {string} mute the mute state.\n * @return {module:client.Promise} Resolves: result object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.setRoomMutePushRule = function(scope, roomId, mute) {\n const self = this;\n let deferred, hasDontNotifyRule;\n\n // Get the existing room-kind push rule if any\n const roomPushRule = this.getRoomPushRule(scope, roomId);\n if (roomPushRule) {\n if (0 <= roomPushRule.actions.indexOf(\"dont_notify\")) {\n hasDontNotifyRule = true;\n }\n }\n\n if (!mute) {\n // Remove the rule only if it is a muting rule\n if (hasDontNotifyRule) {\n deferred = this.deletePushRule(scope, \"room\", roomPushRule.rule_id);\n }\n } else {\n if (!roomPushRule) {\n deferred = this.addPushRule(scope, \"room\", roomId, {\n actions: [\"dont_notify\"],\n });\n } else if (!hasDontNotifyRule) {\n // Remove the existing one before setting the mute push rule\n // This is a workaround to SYN-590 (Push rule update fails)\n deferred = Promise.defer();\n this.deletePushRule(scope, \"room\", roomPushRule.rule_id)\n .done(function() {\n self.addPushRule(scope, \"room\", roomId, {\n actions: [\"dont_notify\"],\n }).done(function() {\n deferred.resolve();\n }, function(err) {\n deferred.reject(err);\n });\n }, function(err) {\n deferred.reject(err);\n });\n\n deferred = deferred.promise;\n }\n }\n\n if (deferred) {\n // Update this.pushRules when the operation completes\n const ruleRefreshDeferred = Promise.defer();\n deferred.done(function() {\n self.getPushRules().done(function(result) {\n self.pushRules = result;\n ruleRefreshDeferred.resolve();\n }, function(err) {\n ruleRefreshDeferred.reject(err);\n });\n }, function(err) {\n // Update it even if the previous operation fails. This can help the\n // app to recover when push settings has been modifed from another client\n self.getPushRules().done(function(result) {\n self.pushRules = result;\n ruleRefreshDeferred.reject(err);\n }, function(err2) {\n ruleRefreshDeferred.reject(err);\n });\n });\n return ruleRefreshDeferred.promise;\n }\n};\n\n// Search\n// ======\n\n/**\n * Perform a server-side search for messages containing the given text.\n * @param {Object} opts Options for the search.\n * @param {string} opts.query The text to query.\n * @param {string=} opts.keys The keys to search on. Defaults to all keys. One\n * of \"content.body\", \"content.name\", \"content.topic\".\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.searchMessageText = function(opts, callback) {\n const roomEvents = {\n search_term: opts.query,\n };\n\n if ('keys' in opts) {\n roomEvents.keys = opts.keys;\n }\n\n return this.search({\n body: {\n search_categories: {\n room_events: roomEvents,\n },\n },\n }, callback);\n};\n\n/**\n * Perform a server-side search for room events.\n *\n * The returned promise resolves to an object containing the fields:\n *\n * * {number} count: estimate of the number of results\n * * {string} next_batch: token for back-pagination; if undefined, there are\n * no more results\n * * {Array} highlights: a list of words to highlight from the stemming\n * algorithm\n * * {Array} results: a list of results\n *\n * Each entry in the results list is a {module:models/search-result.SearchResult}.\n *\n * @param {Object} opts\n * @param {string} opts.term the term to search for\n * @param {Object} opts.filter a JSON filter object to pass in the request\n * @return {module:client.Promise} Resolves: result object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.searchRoomEvents = function(opts) {\n // TODO: support groups\n\n const body = {\n search_categories: {\n room_events: {\n search_term: opts.term,\n filter: opts.filter,\n order_by: \"recent\",\n event_context: {\n before_limit: 1,\n after_limit: 1,\n include_profile: true,\n },\n },\n },\n };\n\n const searchResults = {\n _query: body,\n results: [],\n highlights: [],\n };\n\n return this.search({body: body}).then(\n this._processRoomEventsSearch.bind(this, searchResults),\n );\n};\n\n/**\n * Take a result from an earlier searchRoomEvents call, and backfill results.\n *\n * @param {object} searchResults the results object to be updated\n * @return {module:client.Promise} Resolves: updated result object\n * @return {Error} Rejects: with an error response.\n */\nMatrixClient.prototype.backPaginateRoomEventsSearch = function(searchResults) {\n // TODO: we should implement a backoff (as per scrollback()) to deal more\n // nicely with HTTP errors.\n\n if (!searchResults.next_batch) {\n return Promise.reject(new Error(\"Cannot backpaginate event search any further\"));\n }\n\n if (searchResults.pendingRequest) {\n // already a request in progress - return the existing promise\n return searchResults.pendingRequest;\n }\n\n const searchOpts = {\n body: searchResults._query,\n next_batch: searchResults.next_batch,\n };\n\n const promise = this.search(searchOpts).then(\n this._processRoomEventsSearch.bind(this, searchResults),\n ).finally(function() {\n searchResults.pendingRequest = null;\n });\n searchResults.pendingRequest = promise;\n\n return promise;\n};\n\n/**\n * helper for searchRoomEvents and backPaginateRoomEventsSearch. Processes the\n * response from the API call and updates the searchResults\n *\n * @param {Object} searchResults\n * @param {Object} response\n * @return {Object} searchResults\n * @private\n */\nMatrixClient.prototype._processRoomEventsSearch = function(searchResults, response) {\n const room_events = response.search_categories.room_events;\n\n searchResults.count = room_events.count;\n searchResults.next_batch = room_events.next_batch;\n\n // combine the highlight list with our existing list; build an object\n // to avoid O(N^2) fail\n const highlights = {};\n room_events.highlights.forEach(function(hl) {\n highlights[hl] = 1;\n });\n searchResults.highlights.forEach(function(hl) {\n highlights[hl] = 1;\n });\n\n // turn it back into a list.\n searchResults.highlights = Object.keys(highlights);\n\n // append the new results to our existing results\n for (let i = 0; i < room_events.results.length; i++) {\n const sr = SearchResult.fromJson(room_events.results[i], this.getEventMapper());\n searchResults.results.push(sr);\n }\n return searchResults;\n};\n\n\n/**\n * Populate the store with rooms the user has left.\n * @return {module:client.Promise} Resolves: TODO - Resolved when the rooms have\n * been added to the data store.\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.syncLeftRooms = function() {\n // Guard against multiple calls whilst ongoing and multiple calls post success\n if (this._syncedLeftRooms) {\n return Promise.resolve([]); // don't call syncRooms again if it succeeded.\n }\n if (this._syncLeftRoomsPromise) {\n return this._syncLeftRoomsPromise; // return the ongoing request\n }\n const self = this;\n const syncApi = new SyncApi(this, this._clientOpts);\n this._syncLeftRoomsPromise = syncApi.syncLeftRooms();\n\n // cleanup locks\n this._syncLeftRoomsPromise.then(function(res) {\n console.log(\"Marking success of sync left room request\");\n self._syncedLeftRooms = true; // flip the bit on success\n }).finally(function() {\n self._syncLeftRoomsPromise = null; // cleanup ongoing request state\n });\n\n return this._syncLeftRoomsPromise;\n};\n\n// Filters\n// =======\n\n/**\n * Create a new filter.\n * @param {Object} content The HTTP body for the request\n * @return {Filter} Resolves to a Filter object.\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.createFilter = function(content) {\n const self = this;\n const path = utils.encodeUri(\"/user/$userId/filter\", {\n $userId: this.credentials.userId,\n });\n return this._http.authedRequest(\n undefined, \"POST\", path, undefined, content,\n ).then(function(response) {\n // persist the filter\n const filter = Filter.fromJson(\n self.credentials.userId, response.filter_id, content,\n );\n self.store.storeFilter(filter);\n return filter;\n });\n};\n\n/**\n * Retrieve a filter.\n * @param {string} userId The user ID of the filter owner\n * @param {string} filterId The filter ID to retrieve\n * @param {boolean} allowCached True to allow cached filters to be returned.\n * Default: True.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.getFilter = function(userId, filterId, allowCached) {\n if (allowCached) {\n const filter = this.store.getFilter(userId, filterId);\n if (filter) {\n return Promise.resolve(filter);\n }\n }\n\n const self = this;\n const path = utils.encodeUri(\"/user/$userId/filter/$filterId\", {\n $userId: userId,\n $filterId: filterId,\n });\n\n return this._http.authedRequest(\n undefined, \"GET\", path, undefined, undefined,\n ).then(function(response) {\n // persist the filter\n const filter = Filter.fromJson(\n userId, filterId, response,\n );\n self.store.storeFilter(filter);\n return filter;\n });\n};\n\n/**\n * @param {string} filterName\n * @param {Filter} filter\n * @return {Promise} Filter ID\n */\nMatrixClient.prototype.getOrCreateFilter = function(filterName, filter) {\n const filterId = this.store.getFilterIdByName(filterName);\n let promise = Promise.resolve();\n const self = this;\n\n if (filterId) {\n // check that the existing filter matches our expectations\n promise = self.getFilter(self.credentials.userId,\n filterId, true,\n ).then(function(existingFilter) {\n const oldDef = existingFilter.getDefinition();\n const newDef = filter.getDefinition();\n\n if (utils.deepCompare(oldDef, newDef)) {\n // super, just use that.\n // debuglog(\"Using existing filter ID %s: %s\", filterId,\n // JSON.stringify(oldDef));\n return Promise.resolve(filterId);\n }\n // debuglog(\"Existing filter ID %s: %s; new filter: %s\",\n // filterId, JSON.stringify(oldDef), JSON.stringify(newDef));\n self.store.setFilterIdByName(filterName, undefined);\n return undefined;\n }, function(error) {\n // Synapse currently returns the following when the filter cannot be found:\n // {\n // errcode: \"M_UNKNOWN\",\n // name: \"M_UNKNOWN\",\n // message: \"No row found\",\n // data: Object, httpStatus: 404\n // }\n if (error.httpStatus === 404 &&\n (error.errcode === \"M_UNKNOWN\" || error.errcode === \"M_NOT_FOUND\")) {\n // Clear existing filterId from localStorage\n // if it no longer exists on the server\n self.store.setFilterIdByName(filterName, undefined);\n // Return a undefined value for existingId further down the promise chain\n return undefined;\n } else {\n throw error;\n }\n });\n }\n\n return promise.then(function(existingId) {\n if (existingId) {\n return existingId;\n }\n\n // create a new filter\n return self.createFilter(filter.getDefinition(),\n ).then(function(createdFilter) {\n // debuglog(\"Created new filter ID %s: %s\", createdFilter.filterId,\n // JSON.stringify(createdFilter.getDefinition()));\n self.store.setFilterIdByName(filterName, createdFilter.filterId);\n return createdFilter.filterId;\n });\n });\n};\n\n\n/**\n * Gets a bearer token from the Home Server that the user can\n * present to a third party in order to prove their ownership\n * of the Matrix account they are logged into.\n * @return {module:client.Promise} Resolves: Token object\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.getOpenIdToken = function() {\n const path = utils.encodeUri(\"/user/$userId/openid/request_token\", {\n $userId: this.credentials.userId,\n });\n\n return this._http.authedRequest(\n undefined, \"POST\", path, undefined, {},\n );\n};\n\n\n// VoIP operations\n// ===============\n\n/**\n * @param {module:client.callback} callback Optional.\n * @return {module:client.Promise} Resolves: TODO\n * @return {module:http-api.MatrixError} Rejects: with an error response.\n */\nMatrixClient.prototype.turnServer = function(callback) {\n return this._http.authedRequest(callback, \"GET\", \"/voip/turnServer\");\n};\n\n/**\n * Get the TURN servers for this home server.\n * @return {Array} The servers or an empty list.\n */\nMatrixClient.prototype.getTurnServers = function() {\n return this._turnServers || [];\n};\n\n// Higher level APIs\n// =================\n\n// TODO: stuff to handle:\n// local echo\n// event dup suppression? - apparently we should still be doing this\n// tracking current display name / avatar per-message\n// pagination\n// re-sending (including persisting pending messages to be sent)\n// - Need a nice way to callback the app for arbitrary events like\n// displayname changes\n// due to ambiguity (or should this be on a chat-specific layer)?\n// reconnect after connectivity outages\n\n\n/**\n * High level helper method to begin syncing and poll for new events. To listen for these\n * events, add a listener for {@link module:client~MatrixClient#event:\"event\"}\n * via {@link module:client~MatrixClient#on}. Alternatively, listen for specific\n * state change events.\n * @param {Object=} opts Options to apply when syncing.\n * @param {Number=} opts.initialSyncLimit The event limit= to apply\n * to initial sync. Default: 8.\n * @param {Boolean=} opts.includeArchivedRooms True to put archived=true\n * on the /initialSync request. Default: false.\n * @param {Boolean=} opts.resolveInvitesToProfiles True to do /profile requests\n * on every invite event if the displayname/avatar_url is not known for this user ID.\n * Default: false.\n *\n * @param {String=} opts.pendingEventOrdering Controls where pending messages\n * appear in a room's timeline. If \"chronological\", messages will appear\n * in the timeline when the call to sendEvent was made. If\n * \"detached\", pending messages will appear in a separate list,\n * accessbile via {@link module:models/room#getPendingEvents}. Default:\n * \"chronological\".\n *\n * @param {Number=} opts.pollTimeout The number of milliseconds to wait on /sync.\n * Default: 30000 (30 seconds).\n *\n * @param {Filter=} opts.filter The filter to apply to /sync calls. This will override\n * the opts.initialSyncLimit, which would normally result in a timeline limit filter.\n */\nMatrixClient.prototype.startClient = function(opts) {\n if (this.clientRunning) {\n // client is already running.\n return;\n }\n this.clientRunning = true;\n // backwards compat for when 'opts' was 'historyLen'.\n if (typeof opts === \"number\") {\n opts = {\n initialSyncLimit: opts,\n };\n }\n\n if (this._crypto) {\n this._crypto.uploadDeviceKeys().done();\n this._crypto.start();\n }\n\n // periodically poll for turn servers if we support voip\n checkTurnServers(this);\n\n if (this._syncApi) {\n // This shouldn't happen since we thought the client was not running\n console.error(\"Still have sync object whilst not running: stopping old one\");\n this._syncApi.stop();\n }\n\n // shallow-copy the opts dict before modifying and storing it\n opts = Object.assign({}, opts);\n\n opts.crypto = this._crypto;\n opts.canResetEntireTimeline = (roomId) => {\n if (!this._canResetTimelineCallback) {\n return false;\n }\n return this._canResetTimelineCallback(roomId);\n };\n this._clientOpts = opts;\n\n this._syncApi = new SyncApi(this, opts);\n this._syncApi.sync();\n};\n\n/**\n * High level helper method to stop the client from polling and allow a\n * clean shutdown.\n */\nMatrixClient.prototype.stopClient = function() {\n console.log('stopping MatrixClient');\n\n this.clientRunning = false;\n // TODO: f.e. Room => self.store.storeRoom(room) ?\n if (this._syncApi) {\n this._syncApi.stop();\n this._syncApi = null;\n }\n if (this._crypto) {\n this._crypto.stop();\n }\n if (this._peekSync) {\n this._peekSync.stopPeeking();\n }\n global.clearTimeout(this._checkTurnServersTimeoutID);\n};\n\n/*\n * Set a function which is called when /sync returns a 'limited' response.\n * It is called with a room ID and returns a boolean. It should return 'true' if the SDK\n * can SAFELY remove events from this room. It may not be safe to remove events if there\n * are other references to the timelines for this room, e.g because the client is\n * actively viewing events in this room.\n * Default: returns false.\n * @param {Function} cb The callback which will be invoked.\n */\nMatrixClient.prototype.setCanResetTimelineCallback = function(cb) {\n this._canResetTimelineCallback = cb;\n};\n\n/**\n * Get the callback set via `setCanResetTimelineCallback`.\n * @return {?Function} The callback or null\n */\nMatrixClient.prototype.getCanResetTimelineCallback = function() {\n return this._canResetTimelineCallback;\n};\n\nfunction setupCallEventHandler(client) {\n const candidatesByCall = {\n // callId: [Candidate]\n };\n\n // Maintain a buffer of events before the client has synced for the first time.\n // This buffer will be inspected to see if we should send incoming call\n // notifications. It needs to be buffered to correctly determine if an\n // incoming call has had a matching answer/hangup.\n let callEventBuffer = [];\n let isClientPrepared = false;\n client.on(\"sync\", function(state) {\n if (state === \"PREPARED\") {\n isClientPrepared = true;\n const ignoreCallIds = {}; // Set\n // inspect the buffer and mark all calls which have been answered\n // or hung up before passing them to the call event handler.\n for (let i = callEventBuffer.length - 1; i >= 0; i--) {\n const ev = callEventBuffer[i];\n if (ev.getType() === \"m.call.answer\" ||\n ev.getType() === \"m.call.hangup\") {\n ignoreCallIds[ev.getContent().call_id] = \"yep\";\n }\n }\n // now loop through the buffer chronologically and inject them\n callEventBuffer.forEach(function(e) {\n if (ignoreCallIds[e.getContent().call_id]) {\n console.log(\n 'Ignoring previously answered/hungup call ' +\n e.getContent().call_id,\n );\n return;\n }\n callEventHandler(e);\n });\n callEventBuffer = [];\n }\n });\n\n client.on(\"event\", onEvent);\n\n function onEvent(event) {\n if (event.getType().indexOf(\"m.call.\") !== 0) {\n // not a call event\n if (event.isBeingDecrypted() || event.isDecryptionFailure()) {\n // not *yet* a call event, but might become one...\n event.once(\"Event.decrypted\", onEvent);\n }\n return;\n }\n if (!isClientPrepared) {\n callEventBuffer.push(event);\n return;\n }\n callEventHandler(event);\n }\n\n function callEventHandler(event) {\n const content = event.getContent();\n let call = content.call_id ? client.callList[content.call_id] : undefined;\n let i;\n //console.log(\"RECV %s content=%s\", event.getType(), JSON.stringify(content));\n\n if (event.getType() === \"m.call.invite\") {\n if (event.getSender() === client.credentials.userId) {\n return; // ignore invites you send\n }\n\n if (event.getAge() > content.lifetime) {\n return; // expired call\n }\n\n if (call && call.state === \"ended\") {\n return; // stale/old invite event\n }\n if (call) {\n console.log(\n \"WARN: Already have a MatrixCall with id %s but got an \" +\n \"invite. Clobbering.\",\n content.call_id,\n );\n }\n\n call = webRtcCall.createNewMatrixCall(client, event.getRoomId(), {\n forceTURN: client._forceTURN,\n });\n if (!call) {\n console.log(\n \"Incoming call ID \" + content.call_id + \" but this client \" +\n \"doesn't support WebRTC\",\n );\n // don't hang up the call: there could be other clients\n // connected that do support WebRTC and declining the\n // the call on their behalf would be really annoying.\n return;\n }\n\n call.callId = content.call_id;\n call._initWithInvite(event);\n client.callList[call.callId] = call;\n\n // if we stashed candidate events for that call ID, play them back now\n if (candidatesByCall[call.callId]) {\n for (i = 0; i < candidatesByCall[call.callId].length; i++) {\n call._gotRemoteIceCandidate(\n candidatesByCall[call.callId][i],\n );\n }\n }\n\n // Were we trying to call that user (room)?\n let existingCall;\n const existingCalls = utils.values(client.callList);\n for (i = 0; i < existingCalls.length; ++i) {\n const thisCall = existingCalls[i];\n if (call.roomId === thisCall.roomId &&\n thisCall.direction === 'outbound' &&\n ([\"wait_local_media\", \"create_offer\", \"invite_sent\"].indexOf(\n thisCall.state) !== -1)) {\n existingCall = thisCall;\n break;\n }\n }\n\n if (existingCall) {\n // If we've only got to wait_local_media or create_offer and\n // we've got an invite, pick the incoming call because we know\n // we haven't sent our invite yet otherwise, pick whichever\n // call has the lowest call ID (by string comparison)\n if (existingCall.state === 'wait_local_media' ||\n existingCall.state === 'create_offer' ||\n existingCall.callId > call.callId) {\n console.log(\n \"Glare detected: answering incoming call \" + call.callId +\n \" and canceling outgoing call \" + existingCall.callId,\n );\n existingCall._replacedBy(call);\n call.answer();\n } else {\n console.log(\n \"Glare detected: rejecting incoming call \" + call.callId +\n \" and keeping outgoing call \" + existingCall.callId,\n );\n call.hangup();\n }\n } else {\n client.emit(\"Call.incoming\", call);\n }\n } else if (event.getType() === 'm.call.answer') {\n if (!call) {\n return;\n }\n if (event.getSender() === client.credentials.userId) {\n if (call.state === 'ringing') {\n call._onAnsweredElsewhere(content);\n }\n } else {\n call._receivedAnswer(content);\n }\n } else if (event.getType() === 'm.call.candidates') {\n if (event.getSender() === client.credentials.userId) {\n return;\n }\n if (!call) {\n // store the candidates; we may get a call eventually.\n if (!candidatesByCall[content.call_id]) {\n candidatesByCall[content.call_id] = [];\n }\n candidatesByCall[content.call_id] = candidatesByCall[\n content.call_id\n ].concat(content.candidates);\n } else {\n for (i = 0; i < content.candidates.length; i++) {\n call._gotRemoteIceCandidate(content.candidates[i]);\n }\n }\n } else if (event.getType() === 'm.call.hangup') {\n // Note that we also observe our own hangups here so we can see\n // if we've already rejected a call that would otherwise be valid\n if (!call) {\n // if not live, store the fact that the call has ended because\n // we're probably getting events backwards so\n // the hangup will come before the invite\n call = webRtcCall.createNewMatrixCall(client, event.getRoomId());\n if (call) {\n call.callId = content.call_id;\n call._initWithHangup(event);\n client.callList[content.call_id] = call;\n }\n } else {\n if (call.state !== 'ended') {\n call._onHangupReceived(content);\n delete client.callList[content.call_id];\n }\n }\n }\n }\n}\n\nfunction checkTurnServers(client) {\n if (!client._supportsVoip) {\n return;\n }\n if (client.isGuest()) {\n return; // guests can't access TURN servers\n }\n\n client.turnServer().done(function(res) {\n if (res.uris) {\n console.log(\"Got TURN URIs: \" + res.uris + \" refresh in \" +\n res.ttl + \" secs\");\n // map the response to a format that can be fed to\n // RTCPeerConnection\n const servers = {\n urls: res.uris,\n username: res.username,\n credential: res.password,\n };\n client._turnServers = [servers];\n // re-fetch when we're about to reach the TTL\n client._checkTurnServersTimeoutID = setTimeout(() => {\n checkTurnServers(client);\n }, (res.ttl || (60 * 60)) * 1000 * 0.9);\n }\n }, function(err) {\n console.error(\"Failed to get TURN URIs\");\n client._checkTurnServersTimeoutID =\n setTimeout(function() {\n checkTurnServers(client);\n}, 60000);\n });\n}\n\nfunction _reject(callback, defer, err) {\n if (callback) {\n callback(err);\n }\n defer.reject(err);\n}\n\nfunction _resolve(callback, defer, res) {\n if (callback) {\n callback(null, res);\n }\n defer.resolve(res);\n}\n\nfunction _PojoToMatrixEventMapper(client) {\n function mapper(plainOldJsObject) {\n const event = new MatrixEvent(plainOldJsObject);\n if (event.isEncrypted()) {\n client.reEmitter.reEmit(event, [\n \"Event.decrypted\",\n ]);\n event.attemptDecryption(client._crypto);\n }\n return event;\n }\n return mapper;\n}\n\n/**\n * @return {Function}\n */\nMatrixClient.prototype.getEventMapper = function() {\n return _PojoToMatrixEventMapper(this);\n};\n\n// Identity Server Operations\n// ==========================\n\n/**\n * Generates a random string suitable for use as a client secret. This\n * method is experimental and may change.\n * @return {string} A new client secret\n */\nMatrixClient.prototype.generateClientSecret = function() {\n let ret = \"\";\n const chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n for (let i = 0; i < 32; i++) {\n ret += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n\n return ret;\n};\n\n/** */\nmodule.exports.MatrixClient = MatrixClient;\n/** */\nmodule.exports.CRYPTO_ENABLED = CRYPTO_ENABLED;\n\n// MatrixClient Event JSDocs\n\n/**\n * Fires whenever the SDK receives a new event.\n *

\n * This is only fired for live events received via /sync - it is not fired for\n * events received over context, search, or pagination APIs.\n *\n * @event module:client~MatrixClient#\"event\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @example\n * matrixClient.on(\"event\", function(event){\n * var sender = event.getSender();\n * });\n */\n\n/**\n * Fires whenever the SDK receives a new to-device event.\n * @event module:client~MatrixClient#\"toDeviceEvent\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @example\n * matrixClient.on(\"toDeviceEvent\", function(event){\n * var sender = event.getSender();\n * });\n */\n\n/**\n * Fires whenever the SDK's syncing state is updated. The state can be one of:\n *

    \n *\n *
  • PREPARED: The client has synced with the server at least once and is\n * ready for methods to be called on it. This will be immediately followed by\n * a state of SYNCING. This is the equivalent of \"syncComplete\" in the\n * previous API.
  • \n *\n *
  • SYNCING : The client is currently polling for new events from the server.\n * This will be called after processing latest events from a sync.
  • \n *\n *
  • ERROR : The client has had a problem syncing with the server. If this is\n * called before PREPARED then there was a problem performing the initial\n * sync. If this is called after PREPARED then there was a problem polling\n * the server for updates. This may be called multiple times even if the state is\n * already ERROR. This is the equivalent of \"syncError\" in the previous\n * API.
  • \n *\n *
  • RECONNECTING: The sync connection has dropped, but not (yet) in a way that\n * should be considered erroneous.\n *
  • \n *\n *
  • STOPPED: The client has stopped syncing with server due to stopClient\n * being called.\n *
  • \n *
\n * State transition diagram:\n *
\n *                                          +---->STOPPED\n *                                          |\n *              +----->PREPARED -------> SYNCING <--+\n *              |        ^                |  ^      |\n *              |        |                |  |      |\n *              |        |                V  |      |\n *   null ------+        |  +--------RECONNECTING   |\n *              |        |  V                       |\n *              +------->ERROR ---------------------+\n *\n * NB: 'null' will never be emitted by this event.\n *\n * 
\n * Transitions:\n *
    \n *\n *
  • null -> PREPARED : Occurs when the initial sync is completed\n * first time. This involves setting up filters and obtaining push rules.\n *\n *
  • null -> ERROR : Occurs when the initial sync failed first time.\n *\n *
  • ERROR -> PREPARED : Occurs when the initial sync succeeds\n * after previously failing.\n *\n *
  • PREPARED -> SYNCING : Occurs immediately after transitioning\n * to PREPARED. Starts listening for live updates rather than catching up.\n *\n *
  • SYNCING -> RECONNECTING : Occurs when the live update fails.\n *\n *
  • RECONNECTING -> RECONNECTING : Can occur if the update calls\n * continue to fail, but the keepalive calls (to /versions) succeed.\n *\n *
  • RECONNECTING -> ERROR : Occurs when the keepalive call also fails\n *\n *
  • ERROR -> SYNCING : Occurs when the client has performed a\n * live update after having previously failed.\n *\n *
  • ERROR -> ERROR : Occurs when the client has failed to keepalive\n * for a second time or more.
  • \n *\n *
  • SYNCING -> SYNCING : Occurs when the client has performed a live\n * update. This is called after processing.
  • \n *\n *
  • * -> STOPPED : Occurs once the client has stopped syncing or\n * trying to sync after stopClient has been called.
  • \n *
\n *\n * @event module:client~MatrixClient#\"sync\"\n *\n * @param {string} state An enum representing the syncing state. One of \"PREPARED\",\n * \"SYNCING\", \"ERROR\", \"STOPPED\".\n *\n * @param {?string} prevState An enum representing the previous syncing state.\n * One of \"PREPARED\", \"SYNCING\", \"ERROR\", \"STOPPED\" or null.\n *\n * @param {?Object} data Data about this transition.\n *\n * @param {MatrixError} data.err The matrix error if state=ERROR.\n *\n * @param {String} data.oldSyncToken The 'since' token passed to /sync.\n * null for the first successful sync since this client was\n * started. Only present if state=PREPARED or\n * state=SYNCING.\n *\n * @param {String} data.nextSyncToken The 'next_batch' result from /sync, which\n * will become the 'since' token for the next call to /sync. Only present if\n * state=PREPARED or state=SYNCING.\n *\n * @param {boolean} data.catchingUp True if we are working our way through a\n * backlog of events after connecting. Only present if state=SYNCING.\n *\n * @example\n * matrixClient.on(\"sync\", function(state, prevState, data) {\n * switch (state) {\n * case \"ERROR\":\n * // update UI to say \"Connection Lost\"\n * break;\n * case \"SYNCING\":\n * // update UI to remove any \"Connection Lost\" message\n * break;\n * case \"PREPARED\":\n * // the client instance is ready to be queried.\n * var rooms = matrixClient.getRooms();\n * break;\n * }\n * });\n */\n\n /**\n * Fires whenever the sdk learns about a new group. This event\n * is experimental and may change.\n * @event module:client~MatrixClient#\"Group\"\n * @param {Group} group The newly created, fully populated group.\n * @example\n * matrixClient.on(\"Group\", function(group){\n * var groupId = group.groupId;\n * });\n */\n\n /**\n * Fires whenever a new Room is added. This will fire when you are invited to a\n * room, as well as when you join a room. This event is experimental and\n * may change.\n * @event module:client~MatrixClient#\"Room\"\n * @param {Room} room The newly created, fully populated room.\n * @example\n * matrixClient.on(\"Room\", function(room){\n * var roomId = room.roomId;\n * });\n */\n\n /**\n * Fires whenever a Room is removed. This will fire when you forget a room.\n * This event is experimental and may change.\n * @event module:client~MatrixClient#\"deleteRoom\"\n * @param {string} roomId The deleted room ID.\n * @example\n * matrixClient.on(\"deleteRoom\", function(roomId){\n * // update UI from getRooms()\n * });\n */\n\n/**\n * Fires whenever an incoming call arrives.\n * @event module:client~MatrixClient#\"Call.incoming\"\n * @param {module:webrtc/call~MatrixCall} call The incoming call.\n * @example\n * matrixClient.on(\"Call.incoming\", function(call){\n * call.answer(); // auto-answer\n * });\n */\n\n/**\n * Fires whenever the login session the JS SDK is using is no\n * longer valid and the user must log in again.\n * NB. This only fires when action is required from the user, not\n * when then login session can be renewed by using a refresh token.\n * @event module:client~MatrixClient#\"Session.logged_out\"\n * @example\n * matrixClient.on(\"Session.logged_out\", function(call){\n * // show the login screen\n * });\n */\n\n/**\n * Fires when a device is marked as verified/unverified/blocked/unblocked by\n * {@link module:client~MatrixClient#setDeviceVerified|MatrixClient.setDeviceVerified} or\n * {@link module:client~MatrixClient#setDeviceBlocked|MatrixClient.setDeviceBlocked}.\n *\n * @event module:client~MatrixClient#\"deviceVerificationChanged\"\n * @param {string} userId the owner of the verified device\n * @param {string} deviceId the id of the verified device\n * @param {module:crypto/deviceinfo} deviceInfo updated device information\n */\n\n/**\n * Fires whenever new user-scoped account_data is added.\n * @event module:client~MatrixClient#\"accountData\"\n * @param {MatrixEvent} event The event describing the account_data just added\n * @example\n * matrixClient.on(\"accountData\", function(event){\n * myAccountData[event.type] = event.content;\n * });\n */\n\n\n// EventEmitter JSDocs\n\n/**\n * The {@link https://nodejs.org/api/events.html|EventEmitter} class.\n * @external EventEmitter\n * @see {@link https://nodejs.org/api/events.html}\n */\n\n/**\n * Adds a listener to the end of the listeners array for the specified event.\n * No checks are made to see if the listener has already been added. Multiple\n * calls passing the same combination of event and listener will result in the\n * listener being added multiple times.\n * @function external:EventEmitter#on\n * @param {string} event The event to listen for.\n * @param {Function} listener The function to invoke.\n * @return {EventEmitter} for call chaining.\n */\n\n/**\n * Alias for {@link external:EventEmitter#on}.\n * @function external:EventEmitter#addListener\n * @param {string} event The event to listen for.\n * @param {Function} listener The function to invoke.\n * @return {EventEmitter} for call chaining.\n */\n\n/**\n * Adds a one time listener for the event. This listener is invoked only\n * the next time the event is fired, after which it is removed.\n * @function external:EventEmitter#once\n * @param {string} event The event to listen for.\n * @param {Function} listener The function to invoke.\n * @return {EventEmitter} for call chaining.\n */\n\n/**\n * Remove a listener from the listener array for the specified event.\n * Caution: changes array indices in the listener array behind the\n * listener.\n * @function external:EventEmitter#removeListener\n * @param {string} event The event to listen for.\n * @param {Function} listener The function to invoke.\n * @return {EventEmitter} for call chaining.\n */\n\n/**\n * Removes all listeners, or those of the specified event. It's not a good idea\n * to remove listeners that were added elsewhere in the code, especially when\n * it's on an emitter that you didn't create (e.g. sockets or file streams).\n * @function external:EventEmitter#removeAllListeners\n * @param {string} event Optional. The event to remove listeners for.\n * @return {EventEmitter} for call chaining.\n */\n\n/**\n * Execute each of the listeners in order with the supplied arguments.\n * @function external:EventEmitter#emit\n * @param {string} event The event to emit.\n * @param {Function} listener The function to invoke.\n * @return {boolean} true if event had listeners, false otherwise.\n */\n\n/**\n * By default EventEmitters will print a warning if more than 10 listeners are\n * added for a particular event. This is a useful default which helps finding\n * memory leaks. Obviously not all Emitters should be limited to 10. This\n * function allows that to be increased. Set to zero for unlimited.\n * @function external:EventEmitter#setMaxListeners\n * @param {Number} n The max number of listeners.\n * @return {EventEmitter} for call chaining.\n */\n\n// MatrixClient Callback JSDocs\n\n/**\n * The standard MatrixClient callback interface. Functions which accept this\n * will specify 2 return arguments. These arguments map to the 2 parameters\n * specified in this callback.\n * @callback module:client.callback\n * @param {Object} err The error value, the \"rejected\" value or null.\n * @param {Object} data The data returned, the \"resolved\" value.\n */\n\n /**\n * {@link https://github.com/kriskowal/q|A promise implementation (Q)}. Functions\n * which return this will specify 2 return arguments. These arguments map to the\n * \"onFulfilled\" and \"onRejected\" values of the Promise.\n * @typedef {Object} Promise\n * @static\n * @property {Function} then promise.then(onFulfilled, onRejected, onProgress)\n * @property {Function} catch promise.catch(onRejected)\n * @property {Function} finally promise.finally(callback)\n * @property {Function} done promise.done(onFulfilled, onRejected, onProgress)\n */\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n/**\n * @module content-repo\n */\nconst utils = require(\"./utils\");\n\n/** Content Repo utility functions */\nmodule.exports = {\n /**\n * Get the HTTP URL for an MXC URI.\n * @param {string} baseUrl The base homeserver url which has a content repo.\n * @param {string} mxc The mxc:// URI.\n * @param {Number} width The desired width of the thumbnail.\n * @param {Number} height The desired height of the thumbnail.\n * @param {string} resizeMethod The thumbnail resize method to use, either\n * \"crop\" or \"scale\".\n * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs\n * directly. Fetching such URLs will leak information about the user to\n * anyone they share a room with. If false, will return the emptry string\n * for such URLs.\n * @return {string} The complete URL to the content.\n */\n getHttpUriForMxc: function(baseUrl, mxc, width, height,\n resizeMethod, allowDirectLinks) {\n if (typeof mxc !== \"string\" || !mxc) {\n return '';\n }\n if (mxc.indexOf(\"mxc://\") !== 0) {\n if (allowDirectLinks) {\n return mxc;\n } else {\n return '';\n }\n }\n let serverAndMediaId = mxc.slice(6); // strips mxc://\n let prefix = \"/_matrix/media/v1/download/\";\n const params = {};\n\n if (width) {\n params.width = width;\n }\n if (height) {\n params.height = height;\n }\n if (resizeMethod) {\n params.method = resizeMethod;\n }\n if (utils.keys(params).length > 0) {\n // these are thumbnailing params so they probably want the\n // thumbnailing API...\n prefix = \"/_matrix/media/v1/thumbnail/\";\n }\n\n const fragmentOffset = serverAndMediaId.indexOf(\"#\");\n let fragment = \"\";\n if (fragmentOffset >= 0) {\n fragment = serverAndMediaId.substr(fragmentOffset);\n serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset);\n }\n return baseUrl + prefix + serverAndMediaId +\n (utils.keys(params).length === 0 ? \"\" :\n (\"?\" + utils.encodeParams(params))) + fragment;\n },\n\n /**\n * Get an identicon URL from an arbitrary string.\n * @param {string} baseUrl The base homeserver url which has a content repo.\n * @param {string} identiconString The string to create an identicon for.\n * @param {Number} width The desired width of the image in pixels. Default: 96.\n * @param {Number} height The desired height of the image in pixels. Default: 96.\n * @return {string} The complete URL to the identicon.\n */\n getIdenticonUri: function(baseUrl, identiconString, width, height) {\n if (!identiconString) {\n return null;\n }\n if (!width) {\n width = 96;\n }\n if (!height) {\n height = 96;\n }\n const params = {\n width: width,\n height: height,\n };\n\n const path = utils.encodeUri(\"/_matrix/media/v1/identicon/$ident\", {\n $ident: identiconString,\n });\n return baseUrl + path +\n (utils.keys(params).length === 0 ? \"\" :\n (\"?\" + utils.encodeParams(params)));\n },\n};\n","/*\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * @module crypto/DeviceList\n *\n * Manages the list of other users' devices\n */\n\nimport Promise from 'bluebird';\n\nimport DeviceInfo from './deviceinfo';\nimport olmlib from './olmlib';\n\n\n/* State transition diagram for DeviceList._deviceTrackingStatus\n *\n * |\n * stopTrackingDeviceList V\n * +---------------------> NOT_TRACKED\n * | |\n * +<--------------------+ | startTrackingDeviceList\n * | | V\n * | +-------------> PENDING_DOWNLOAD <--------------------+-+\n * | | ^ | | |\n * | | restart download | | start download | | invalidateUserDeviceList\n * | | client failed | | | |\n * | | | V | |\n * | +------------ DOWNLOAD_IN_PROGRESS -------------------+ |\n * | | | |\n * +<-------------------+ | download successful |\n * ^ V |\n * +----------------------- UP_TO_DATE ------------------------+\n */\n\n\n// constants for DeviceList._deviceTrackingStatus\nconst TRACKING_STATUS_NOT_TRACKED = 0;\nconst TRACKING_STATUS_PENDING_DOWNLOAD = 1;\nconst TRACKING_STATUS_DOWNLOAD_IN_PROGRESS = 2;\nconst TRACKING_STATUS_UP_TO_DATE = 3;\n\n/**\n * @alias module:crypto/DeviceList\n */\nexport default class DeviceList {\n constructor(baseApis, sessionStore, olmDevice) {\n this._sessionStore = sessionStore;\n this._serialiser = new DeviceListUpdateSerialiser(\n baseApis, sessionStore, olmDevice,\n );\n\n // which users we are tracking device status for.\n // userId -> TRACKING_STATUS_*\n this._deviceTrackingStatus = sessionStore.getEndToEndDeviceTrackingStatus() || {};\n for (const u of Object.keys(this._deviceTrackingStatus)) {\n // if a download was in progress when we got shut down, it isn't any more.\n if (this._deviceTrackingStatus[u] == TRACKING_STATUS_DOWNLOAD_IN_PROGRESS) {\n this._deviceTrackingStatus[u] = TRACKING_STATUS_PENDING_DOWNLOAD;\n }\n }\n\n // userId -> promise\n this._keyDownloadsInProgressByUser = {};\n\n this.lastKnownSyncToken = null;\n }\n\n /**\n * Download the keys for a list of users and stores the keys in the session\n * store.\n * @param {Array} userIds The users to fetch.\n * @param {bool} forceDownload Always download the keys even if cached.\n *\n * @return {Promise} A promise which resolves to a map userId->deviceId->{@link\n * module:crypto/deviceinfo|DeviceInfo}.\n */\n downloadKeys(userIds, forceDownload) {\n const usersToDownload = [];\n const promises = [];\n\n userIds.forEach((u) => {\n const trackingStatus = this._deviceTrackingStatus[u];\n if (this._keyDownloadsInProgressByUser[u]) {\n // already a key download in progress/queued for this user; its results\n // will be good enough for us.\n console.log(\n `downloadKeys: already have a download in progress for ` +\n `${u}: awaiting its result`,\n );\n promises.push(this._keyDownloadsInProgressByUser[u]);\n } else if (forceDownload || trackingStatus != TRACKING_STATUS_UP_TO_DATE) {\n usersToDownload.push(u);\n }\n });\n\n if (usersToDownload.length != 0) {\n console.log(\"downloadKeys: downloading for\", usersToDownload);\n const downloadPromise = this._doKeyDownload(usersToDownload);\n promises.push(downloadPromise);\n }\n\n if (promises.length === 0) {\n console.log(\"downloadKeys: already have all necessary keys\");\n }\n\n return Promise.all(promises).then(() => {\n return this._getDevicesFromStore(userIds);\n });\n }\n\n /**\n * Get the stored device keys for a list of user ids\n *\n * @param {string[]} userIds the list of users to list keys for.\n *\n * @return {Object} userId->deviceId->{@link module:crypto/deviceinfo|DeviceInfo}.\n */\n _getDevicesFromStore(userIds) {\n const stored = {};\n const self = this;\n userIds.map(function(u) {\n stored[u] = {};\n const devices = self.getStoredDevicesForUser(u) || [];\n devices.map(function(dev) {\n stored[u][dev.deviceId] = dev;\n });\n });\n return stored;\n }\n\n /**\n * Get the stored device keys for a user id\n *\n * @param {string} userId the user to list keys for.\n *\n * @return {module:crypto/deviceinfo[]|null} list of devices, or null if we haven't\n * managed to get a list of devices for this user yet.\n */\n getStoredDevicesForUser(userId) {\n const devs = this._sessionStore.getEndToEndDevicesForUser(userId);\n if (!devs) {\n return null;\n }\n const res = [];\n for (const deviceId in devs) {\n if (devs.hasOwnProperty(deviceId)) {\n res.push(DeviceInfo.fromStorage(devs[deviceId], deviceId));\n }\n }\n return res;\n }\n\n /**\n * Get the stored keys for a single device\n *\n * @param {string} userId\n * @param {string} deviceId\n *\n * @return {module:crypto/deviceinfo?} device, or undefined\n * if we don't know about this device\n */\n getStoredDevice(userId, deviceId) {\n const devs = this._sessionStore.getEndToEndDevicesForUser(userId);\n if (!devs || !devs[deviceId]) {\n return undefined;\n }\n return DeviceInfo.fromStorage(devs[deviceId], deviceId);\n }\n\n /**\n * Find a device by curve25519 identity key\n *\n * @param {string} userId owner of the device\n * @param {string} algorithm encryption algorithm\n * @param {string} senderKey curve25519 key to match\n *\n * @return {module:crypto/deviceinfo?}\n */\n getDeviceByIdentityKey(userId, algorithm, senderKey) {\n if (\n algorithm !== olmlib.OLM_ALGORITHM &&\n algorithm !== olmlib.MEGOLM_ALGORITHM\n ) {\n // we only deal in olm keys\n return null;\n }\n\n const devices = this._sessionStore.getEndToEndDevicesForUser(userId);\n if (!devices) {\n return null;\n }\n\n for (const deviceId in devices) {\n if (!devices.hasOwnProperty(deviceId)) {\n continue;\n }\n\n const device = devices[deviceId];\n for (const keyId in device.keys) {\n if (!device.keys.hasOwnProperty(keyId)) {\n continue;\n }\n if (keyId.indexOf(\"curve25519:\") !== 0) {\n continue;\n }\n const deviceKey = device.keys[keyId];\n if (deviceKey == senderKey) {\n return DeviceInfo.fromStorage(device, deviceId);\n }\n }\n }\n\n // doesn't match a known device\n return null;\n }\n\n /**\n * flag the given user for device-list tracking, if they are not already.\n *\n * This will mean that a subsequent call to refreshOutdatedDeviceLists()\n * will download the device list for the user, and that subsequent calls to\n * invalidateUserDeviceList will trigger more updates.\n *\n * @param {String} userId\n */\n startTrackingDeviceList(userId) {\n // sanity-check the userId. This is mostly paranoia, but if synapse\n // can't parse the userId we give it as an mxid, it 500s the whole\n // request and we can never update the device lists again (because\n // the broken userId is always 'invalid' and always included in any\n // refresh request).\n // By checking it is at least a string, we can eliminate a class of\n // silly errors.\n if (typeof userId !== 'string') {\n throw new Error('userId must be a string; was '+userId);\n }\n if (!this._deviceTrackingStatus[userId]) {\n console.log('Now tracking device list for ' + userId);\n this._deviceTrackingStatus[userId] = TRACKING_STATUS_PENDING_DOWNLOAD;\n }\n // we don't yet persist the tracking status, since there may be a lot\n // of calls; instead we wait for the forthcoming\n // refreshOutdatedDeviceLists.\n }\n\n /**\n * Mark the given user as no longer being tracked for device-list updates.\n *\n * This won't affect any in-progress downloads, which will still go on to\n * complete; it will just mean that we don't think that we have an up-to-date\n * list for future calls to downloadKeys.\n *\n * @param {String} userId\n */\n stopTrackingDeviceList(userId) {\n if (this._deviceTrackingStatus[userId]) {\n console.log('No longer tracking device list for ' + userId);\n this._deviceTrackingStatus[userId] = TRACKING_STATUS_NOT_TRACKED;\n }\n // we don't yet persist the tracking status, since there may be a lot\n // of calls; instead we wait for the forthcoming\n // refreshOutdatedDeviceLists.\n }\n\n\n /**\n * Mark the cached device list for the given user outdated.\n *\n * If we are not tracking this user's devices, we'll do nothing. Otherwise\n * we flag the user as needing an update.\n *\n * This doesn't actually set off an update, so that several users can be\n * batched together. Call refreshOutdatedDeviceLists() for that.\n *\n * @param {String} userId\n */\n invalidateUserDeviceList(userId) {\n if (this._deviceTrackingStatus[userId]) {\n console.log(\"Marking device list outdated for\", userId);\n this._deviceTrackingStatus[userId] = TRACKING_STATUS_PENDING_DOWNLOAD;\n }\n // we don't yet persist the tracking status, since there may be a lot\n // of calls; instead we wait for the forthcoming\n // refreshOutdatedDeviceLists.\n }\n\n /**\n * Mark all tracked device lists as outdated.\n *\n * This will flag each user whose devices we are tracking as in need of an\n * update.\n */\n invalidateAllDeviceLists() {\n for (const userId of Object.keys(this._deviceTrackingStatus)) {\n this.invalidateUserDeviceList(userId);\n }\n }\n\n /**\n * If we have users who have outdated device lists, start key downloads for them\n *\n * @returns {Promise} which completes when the download completes; normally there\n * is no need to wait for this (it's mostly for the unit tests).\n */\n refreshOutdatedDeviceLists() {\n const usersToDownload = [];\n for (const userId of Object.keys(this._deviceTrackingStatus)) {\n const stat = this._deviceTrackingStatus[userId];\n if (stat == TRACKING_STATUS_PENDING_DOWNLOAD) {\n usersToDownload.push(userId);\n }\n }\n\n // we didn't persist the tracking status during\n // invalidateUserDeviceList, so do it now.\n this._persistDeviceTrackingStatus();\n\n return this._doKeyDownload(usersToDownload);\n }\n\n\n /**\n * Fire off download update requests for the given users, and update the\n * device list tracking status for them, and the\n * _keyDownloadsInProgressByUser map for them.\n *\n * @param {String[]} users list of userIds\n *\n * @return {module:client.Promise} resolves when all the users listed have\n * been updated. rejects if there was a problem updating any of the\n * users.\n */\n _doKeyDownload(users) {\n if (users.length === 0) {\n // nothing to do\n return Promise.resolve();\n }\n\n const prom = this._serialiser.updateDevicesForUsers(\n users, this.lastKnownSyncToken,\n ).then(() => {\n finished(true);\n }, (e) => {\n console.error(\n 'Error downloading keys for ' + users + \":\", e,\n );\n finished(false);\n throw e;\n });\n\n users.forEach((u) => {\n this._keyDownloadsInProgressByUser[u] = prom;\n const stat = this._deviceTrackingStatus[u];\n if (stat == TRACKING_STATUS_PENDING_DOWNLOAD) {\n this._deviceTrackingStatus[u] = TRACKING_STATUS_DOWNLOAD_IN_PROGRESS;\n }\n });\n\n const finished = (success) => {\n users.forEach((u) => {\n // we may have queued up another download request for this user\n // since we started this request. If that happens, we should\n // ignore the completion of the first one.\n if (this._keyDownloadsInProgressByUser[u] !== prom) {\n console.log('Another update in the queue for', u,\n '- not marking up-to-date');\n return;\n }\n delete this._keyDownloadsInProgressByUser[u];\n const stat = this._deviceTrackingStatus[u];\n if (stat == TRACKING_STATUS_DOWNLOAD_IN_PROGRESS) {\n if (success) {\n // we didn't get any new invalidations since this download started:\n // this user's device list is now up to date.\n this._deviceTrackingStatus[u] = TRACKING_STATUS_UP_TO_DATE;\n console.log(\"Device list for\", u, \"now up to date\");\n } else {\n this._deviceTrackingStatus[u] = TRACKING_STATUS_PENDING_DOWNLOAD;\n }\n }\n });\n this._persistDeviceTrackingStatus();\n };\n\n return prom;\n }\n\n _persistDeviceTrackingStatus() {\n this._sessionStore.storeEndToEndDeviceTrackingStatus(this._deviceTrackingStatus);\n }\n}\n\n/**\n * Serialises updates to device lists\n *\n * Ensures that results from /keys/query are not overwritten if a second call\n * completes *before* an earlier one.\n *\n * It currently does this by ensuring only one call to /keys/query happens at a\n * time (and queuing other requests up).\n */\nclass DeviceListUpdateSerialiser {\n constructor(baseApis, sessionStore, olmDevice) {\n this._baseApis = baseApis;\n this._sessionStore = sessionStore;\n this._olmDevice = olmDevice;\n\n this._downloadInProgress = false;\n\n // users which are queued for download\n // userId -> true\n this._keyDownloadsQueuedByUser = {};\n\n // deferred which is resolved when the queued users are downloaded.\n //\n // non-null indicates that we have users queued for download.\n this._queuedQueryDeferred = null;\n\n // sync token to be used for the next query: essentially the\n // most recent one we know about\n this._nextSyncToken = null;\n }\n\n /**\n * Make a key query request for the given users\n *\n * @param {String[]} users list of user ids\n *\n * @param {String} syncToken sync token to pass in the query request, to\n * help the HS give the most recent results\n *\n * @return {module:client.Promise} resolves when all the users listed have\n * been updated. rejects if there was a problem updating any of the\n * users.\n */\n updateDevicesForUsers(users, syncToken) {\n users.forEach((u) => {\n this._keyDownloadsQueuedByUser[u] = true;\n });\n this._nextSyncToken = syncToken;\n\n if (!this._queuedQueryDeferred) {\n this._queuedQueryDeferred = Promise.defer();\n }\n\n if (this._downloadInProgress) {\n // just queue up these users\n console.log('Queued key download for', users);\n return this._queuedQueryDeferred.promise;\n }\n\n // start a new download.\n return this._doQueuedQueries();\n }\n\n _doQueuedQueries() {\n if (this._downloadInProgress) {\n throw new Error(\n \"DeviceListUpdateSerialiser._doQueuedQueries called with request active\",\n );\n }\n\n const downloadUsers = Object.keys(this._keyDownloadsQueuedByUser);\n this._keyDownloadsQueuedByUser = {};\n const deferred = this._queuedQueryDeferred;\n this._queuedQueryDeferred = null;\n\n console.log('Starting key download for', downloadUsers);\n this._downloadInProgress = true;\n\n const opts = {};\n if (this._nextSyncToken) {\n opts.token = this._nextSyncToken;\n }\n\n this._baseApis.downloadKeysForUsers(\n downloadUsers, opts,\n ).then((res) => {\n const dk = res.device_keys || {};\n\n // do each user in a separate promise, to avoid wedging the CPU\n // (https://github.com/vector-im/riot-web/issues/3158)\n //\n // of course we ought to do this in a web worker or similar, but\n // this serves as an easy solution for now.\n let prom = Promise.resolve();\n for (const userId of downloadUsers) {\n prom = prom.delay(5).then(() => {\n return this._processQueryResponseForUser(userId, dk[userId]);\n });\n }\n\n return prom;\n }).done(() => {\n console.log('Completed key download for ' + downloadUsers);\n\n this._downloadInProgress = false;\n deferred.resolve();\n\n // if we have queued users, fire off another request.\n if (this._queuedQueryDeferred) {\n this._doQueuedQueries();\n }\n }, (e) => {\n console.warn('Error downloading keys for ' + downloadUsers + ':', e);\n this._downloadInProgress = false;\n deferred.reject(e);\n });\n\n return deferred.promise;\n }\n\n async _processQueryResponseForUser(userId, response) {\n console.log('got keys for ' + userId + ':', response);\n\n // map from deviceid -> deviceinfo for this user\n const userStore = {};\n const devs = this._sessionStore.getEndToEndDevicesForUser(userId);\n if (devs) {\n Object.keys(devs).forEach((deviceId) => {\n const d = DeviceInfo.fromStorage(devs[deviceId], deviceId);\n userStore[deviceId] = d;\n });\n }\n\n await _updateStoredDeviceKeysForUser(\n this._olmDevice, userId, userStore, response || {},\n );\n\n // update the session store\n const storage = {};\n Object.keys(userStore).forEach((deviceId) => {\n storage[deviceId] = userStore[deviceId].toStorage();\n });\n\n this._sessionStore.storeEndToEndDevicesForUser(\n userId, storage,\n );\n }\n}\n\n\nasync function _updateStoredDeviceKeysForUser(_olmDevice, userId, userStore,\n userResult) {\n let updated = false;\n\n // remove any devices in the store which aren't in the response\n for (const deviceId in userStore) {\n if (!userStore.hasOwnProperty(deviceId)) {\n continue;\n }\n\n if (!(deviceId in userResult)) {\n console.log(\"Device \" + userId + \":\" + deviceId +\n \" has been removed\");\n delete userStore[deviceId];\n updated = true;\n }\n }\n\n for (const deviceId in userResult) {\n if (!userResult.hasOwnProperty(deviceId)) {\n continue;\n }\n\n const deviceResult = userResult[deviceId];\n\n // check that the user_id and device_id in the response object are\n // correct\n if (deviceResult.user_id !== userId) {\n console.warn(\"Mismatched user_id \" + deviceResult.user_id +\n \" in keys from \" + userId + \":\" + deviceId);\n continue;\n }\n if (deviceResult.device_id !== deviceId) {\n console.warn(\"Mismatched device_id \" + deviceResult.device_id +\n \" in keys from \" + userId + \":\" + deviceId);\n continue;\n }\n\n if (await _storeDeviceKeys(_olmDevice, userStore, deviceResult)) {\n updated = true;\n }\n }\n\n return updated;\n}\n\n/*\n * Process a device in a /query response, and add it to the userStore\n *\n * returns (a promise for) true if a change was made, else false\n */\nasync function _storeDeviceKeys(_olmDevice, userStore, deviceResult) {\n if (!deviceResult.keys) {\n // no keys?\n return false;\n }\n\n const deviceId = deviceResult.device_id;\n const userId = deviceResult.user_id;\n\n const signKeyId = \"ed25519:\" + deviceId;\n const signKey = deviceResult.keys[signKeyId];\n if (!signKey) {\n console.warn(\"Device \" + userId + \":\" + deviceId +\n \" has no ed25519 key\");\n return false;\n }\n\n const unsigned = deviceResult.unsigned || {};\n\n try {\n await olmlib.verifySignature(_olmDevice, deviceResult, userId, deviceId, signKey);\n } catch (e) {\n console.warn(\"Unable to verify signature on device \" +\n userId + \":\" + deviceId + \":\" + e);\n return false;\n }\n\n // DeviceInfo\n let deviceStore;\n\n if (deviceId in userStore) {\n // already have this device.\n deviceStore = userStore[deviceId];\n\n if (deviceStore.getFingerprint() != signKey) {\n // this should only happen if the list has been MITMed; we are\n // best off sticking with the original keys.\n //\n // Should we warn the user about it somehow?\n console.warn(\"Ed25519 key for device \" + userId + \":\" +\n deviceId + \" has changed\");\n return false;\n }\n } else {\n userStore[deviceId] = deviceStore = new DeviceInfo(deviceId);\n }\n\n deviceStore.keys = deviceResult.keys || {};\n deviceStore.algorithms = deviceResult.algorithms || [];\n deviceStore.unsigned = unsigned;\n return true;\n}\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * olm.js wrapper\n *\n * @module crypto/OlmDevice\n */\nconst Olm = global.Olm;\nif (!Olm) {\n throw new Error(\"global.Olm is not defined\");\n}\nconst utils = require(\"../utils\");\n\n\n// The maximum size of an event is 65K, and we base64 the content, so this is a\n// reasonable approximation to the biggest plaintext we can encrypt.\nconst MAX_PLAINTEXT_LENGTH = 65536 * 3 / 4;\n\nfunction checkPayloadLength(payloadString) {\n if (payloadString === undefined) {\n throw new Error(\"payloadString undefined\");\n }\n\n if (payloadString.length > MAX_PLAINTEXT_LENGTH) {\n // might as well fail early here rather than letting the olm library throw\n // a cryptic memory allocation error.\n //\n // Note that even if we manage to do the encryption, the message send may fail,\n // because by the time we've wrapped the ciphertext in the event object, it may\n // exceed 65K. But at least we won't just fail with \"abort()\" in that case.\n throw new Error(\"Message too long (\" + payloadString.length + \" bytes). \" +\n \"The maximum for an encrypted message is \" +\n MAX_PLAINTEXT_LENGTH + \" bytes.\");\n }\n}\n\n\n/**\n * The type of object we use for importing and exporting megolm session data.\n *\n * @typedef {Object} module:crypto/OlmDevice.MegolmSessionData\n * @property {String} sender_key Sender's Curve25519 device key\n * @property {String[]} forwarding_curve25519_key_chain Devices which forwarded\n * this session to us (normally empty).\n * @property {Object} sender_claimed_keys Other keys the sender claims.\n * @property {String} room_id Room this session is used in\n * @property {String} session_id Unique id for the session\n * @property {String} session_key Base64'ed key data\n */\n\n\n/**\n * Manages the olm cryptography functions. Each OlmDevice has a single\n * OlmAccount and a number of OlmSessions.\n *\n * Accounts and sessions are kept pickled in a sessionStore.\n *\n * @constructor\n * @alias module:crypto/OlmDevice\n *\n * @param {Object} sessionStore A store to be used for data in end-to-end\n * crypto\n *\n * @property {string} deviceCurve25519Key Curve25519 key for the account\n * @property {string} deviceEd25519Key Ed25519 key for the account\n */\nfunction OlmDevice(sessionStore) {\n this._sessionStore = sessionStore;\n this._pickleKey = \"DEFAULT_KEY\";\n\n // don't know these until we load the account from storage in init()\n this.deviceCurve25519Key = null;\n this.deviceEd25519Key = null;\n this._maxOneTimeKeys = null;\n\n // we don't bother stashing outboundgroupsessions in the sessionstore -\n // instead we keep them here.\n this._outboundGroupSessionStore = {};\n\n // Store a set of decrypted message indexes for each group session.\n // This partially mitigates a replay attack where a MITM resends a group\n // message into the room.\n //\n // When we decrypt a message and the message index matches a previously\n // decrypted message, one possible cause of that is that we are decrypting\n // the same event, and may not indicate an actual replay attack. For\n // example, this could happen if we receive events, forget about them, and\n // then re-fetch them when we backfill. So we store the event ID and\n // timestamp corresponding to each message index when we first decrypt it,\n // and compare these against the event ID and timestamp every time we use\n // that same index. If they match, then we're probably decrypting the same\n // event and we don't consider it a replay attack.\n //\n // Keys are strings of form \"||\"\n // Values are objects of the form \"{id: , timestamp: }\"\n this._inboundGroupSessionMessageIndexes = {};\n}\n\n/**\n * Initialise the OlmAccount. This must be called before any other operations\n * on the OlmDevice.\n *\n * Attempts to load the OlmAccount from localStorage, or creates one if none is\n * found.\n *\n * Reads the device keys from the OlmAccount object.\n */\nOlmDevice.prototype.init = async function() {\n let e2eKeys;\n const account = new Olm.Account();\n try {\n _initialise_account(this._sessionStore, this._pickleKey, account);\n e2eKeys = JSON.parse(account.identity_keys());\n\n this._maxOneTimeKeys = account.max_number_of_one_time_keys();\n } finally {\n account.free();\n }\n\n this.deviceCurve25519Key = e2eKeys.curve25519;\n this.deviceEd25519Key = e2eKeys.ed25519;\n};\n\n\nfunction _initialise_account(sessionStore, pickleKey, account) {\n const e2eAccount = sessionStore.getEndToEndAccount();\n if (e2eAccount !== null) {\n account.unpickle(pickleKey, e2eAccount);\n return;\n }\n\n account.create();\n const pickled = account.pickle(pickleKey);\n sessionStore.storeEndToEndAccount(pickled);\n}\n\n/**\n * @return {array} The version of Olm.\n */\nOlmDevice.getOlmVersion = function() {\n return Olm.get_library_version();\n};\n\n\n/**\n * extract our OlmAccount from the session store and call the given function\n *\n * @param {function} func\n * @return {object} result of func\n * @private\n */\nOlmDevice.prototype._getAccount = function(func) {\n const account = new Olm.Account();\n try {\n const pickledAccount = this._sessionStore.getEndToEndAccount();\n account.unpickle(this._pickleKey, pickledAccount);\n return func(account);\n } finally {\n account.free();\n }\n};\n\n\n/**\n * store our OlmAccount in the session store\n *\n * @param {OlmAccount} account\n * @private\n */\nOlmDevice.prototype._saveAccount = function(account) {\n const pickledAccount = account.pickle(this._pickleKey);\n this._sessionStore.storeEndToEndAccount(pickledAccount);\n};\n\n\n/**\n * extract an OlmSession from the session store and call the given function\n *\n * @param {string} deviceKey\n * @param {string} sessionId\n * @param {function} func\n * @return {object} result of func\n * @private\n */\nOlmDevice.prototype._getSession = function(deviceKey, sessionId, func) {\n const sessions = this._sessionStore.getEndToEndSessions(deviceKey);\n const pickledSession = sessions[sessionId];\n\n const session = new Olm.Session();\n try {\n session.unpickle(this._pickleKey, pickledSession);\n return func(session);\n } finally {\n session.free();\n }\n};\n\n\n/**\n * store our OlmSession in the session store\n *\n * @param {string} deviceKey\n * @param {OlmSession} session\n * @private\n */\nOlmDevice.prototype._saveSession = function(deviceKey, session) {\n const pickledSession = session.pickle(this._pickleKey);\n this._sessionStore.storeEndToEndSession(\n deviceKey, session.session_id(), pickledSession,\n );\n};\n\n\n/**\n * get an OlmUtility and call the given function\n *\n * @param {function} func\n * @return {object} result of func\n * @private\n */\nOlmDevice.prototype._getUtility = function(func) {\n const utility = new Olm.Utility();\n try {\n return func(utility);\n } finally {\n utility.free();\n }\n};\n\n\n/**\n * Signs a message with the ed25519 key for this account.\n *\n * @param {string} message message to be signed\n * @return {Promise} base64-encoded signature\n */\nOlmDevice.prototype.sign = async function(message) {\n return this._getAccount(function(account) {\n return account.sign(message);\n });\n};\n\n/**\n * Get the current (unused, unpublished) one-time keys for this account.\n *\n * @return {object} one time keys; an object with the single property\n * curve25519, which is itself an object mapping key id to Curve25519\n * key.\n */\nOlmDevice.prototype.getOneTimeKeys = async function() {\n return this._getAccount(function(account) {\n return JSON.parse(account.one_time_keys());\n });\n};\n\n\n/**\n * Get the maximum number of one-time keys we can store.\n *\n * @return {number} number of keys\n */\nOlmDevice.prototype.maxNumberOfOneTimeKeys = function() {\n return this._maxOneTimeKeys;\n};\n\n/**\n * Marks all of the one-time keys as published.\n */\nOlmDevice.prototype.markKeysAsPublished = async function() {\n const self = this;\n this._getAccount(function(account) {\n account.mark_keys_as_published();\n self._saveAccount(account);\n });\n};\n\n/**\n * Generate some new one-time keys\n *\n * @param {number} numKeys number of keys to generate\n */\nOlmDevice.prototype.generateOneTimeKeys = async function(numKeys) {\n const self = this;\n this._getAccount(function(account) {\n account.generate_one_time_keys(numKeys);\n self._saveAccount(account);\n });\n};\n\n/**\n * Generate a new outbound session\n *\n * The new session will be stored in the sessionStore.\n *\n * @param {string} theirIdentityKey remote user's Curve25519 identity key\n * @param {string} theirOneTimeKey remote user's one-time Curve25519 key\n * @return {string} sessionId for the outbound session.\n */\nOlmDevice.prototype.createOutboundSession = async function(\n theirIdentityKey, theirOneTimeKey,\n) {\n const self = this;\n return this._getAccount(function(account) {\n const session = new Olm.Session();\n try {\n session.create_outbound(account, theirIdentityKey, theirOneTimeKey);\n self._saveSession(theirIdentityKey, session);\n return session.session_id();\n } finally {\n session.free();\n }\n });\n};\n\n\n/**\n * Generate a new inbound session, given an incoming message\n *\n * @param {string} theirDeviceIdentityKey remote user's Curve25519 identity key\n * @param {number} message_type message_type field from the received message (must be 0)\n * @param {string} ciphertext base64-encoded body from the received message\n *\n * @return {{payload: string, session_id: string}} decrypted payload, and\n * session id of new session\n *\n * @raises {Error} if the received message was not valid (for instance, it\n * didn't use a valid one-time key).\n */\nOlmDevice.prototype.createInboundSession = async function(\n theirDeviceIdentityKey, message_type, ciphertext,\n) {\n if (message_type !== 0) {\n throw new Error(\"Need message_type == 0 to create inbound session\");\n }\n\n const self = this;\n return this._getAccount(function(account) {\n const session = new Olm.Session();\n try {\n session.create_inbound_from(account, theirDeviceIdentityKey, ciphertext);\n account.remove_one_time_keys(session);\n self._saveAccount(account);\n\n const payloadString = session.decrypt(message_type, ciphertext);\n\n self._saveSession(theirDeviceIdentityKey, session);\n\n return {\n payload: payloadString,\n session_id: session.session_id(),\n };\n } finally {\n session.free();\n }\n });\n};\n\n\n/**\n * Get a list of known session IDs for the given device\n *\n * @param {string} theirDeviceIdentityKey Curve25519 identity key for the\n * remote device\n * @return {Promise} a list of known session ids for the device\n */\nOlmDevice.prototype.getSessionIdsForDevice = async function(theirDeviceIdentityKey) {\n const sessions = this._sessionStore.getEndToEndSessions(\n theirDeviceIdentityKey,\n );\n return utils.keys(sessions);\n};\n\n/**\n * Get the right olm session id for encrypting messages to the given identity key\n *\n * @param {string} theirDeviceIdentityKey Curve25519 identity key for the\n * remote device\n * @return {Promise} session id, or null if no established session\n */\nOlmDevice.prototype.getSessionIdForDevice = async function(theirDeviceIdentityKey) {\n const sessionIds = await this.getSessionIdsForDevice(theirDeviceIdentityKey);\n if (sessionIds.length === 0) {\n return null;\n }\n // Use the session with the lowest ID.\n sessionIds.sort();\n return sessionIds[0];\n};\n\n/**\n * Get information on the active Olm sessions for a device.\n *

\n * Returns an array, with an entry for each active session. The first entry in\n * the result will be the one used for outgoing messages. Each entry contains\n * the keys 'hasReceivedMessage' (true if the session has received an incoming\n * message and is therefore past the pre-key stage), and 'sessionId'.\n *\n * @param {string} deviceIdentityKey Curve25519 identity key for the device\n * @return {Array.<{sessionId: string, hasReceivedMessage: Boolean}>}\n */\nOlmDevice.prototype.getSessionInfoForDevice = async function(deviceIdentityKey) {\n const sessionIds = await this.getSessionIdsForDevice(deviceIdentityKey);\n sessionIds.sort();\n\n const info = [];\n\n function getSessionInfo(session) {\n return {\n hasReceivedMessage: session.has_received_message(),\n };\n }\n\n for (let i = 0; i < sessionIds.length; i++) {\n const sessionId = sessionIds[i];\n const res = this._getSession(deviceIdentityKey, sessionId, getSessionInfo);\n res.sessionId = sessionId;\n info.push(res);\n }\n return info;\n};\n\n/**\n * Encrypt an outgoing message using an existing session\n *\n * @param {string} theirDeviceIdentityKey Curve25519 identity key for the\n * remote device\n * @param {string} sessionId the id of the active session\n * @param {string} payloadString payload to be encrypted and sent\n *\n * @return {Promise} ciphertext\n */\nOlmDevice.prototype.encryptMessage = async function(\n theirDeviceIdentityKey, sessionId, payloadString,\n) {\n const self = this;\n\n checkPayloadLength(payloadString);\n\n return this._getSession(theirDeviceIdentityKey, sessionId, function(session) {\n const res = session.encrypt(payloadString);\n self._saveSession(theirDeviceIdentityKey, session);\n return res;\n });\n};\n\n/**\n * Decrypt an incoming message using an existing session\n *\n * @param {string} theirDeviceIdentityKey Curve25519 identity key for the\n * remote device\n * @param {string} sessionId the id of the active session\n * @param {number} message_type message_type field from the received message\n * @param {string} ciphertext base64-encoded body from the received message\n *\n * @return {Promise} decrypted payload.\n */\nOlmDevice.prototype.decryptMessage = async function(\n theirDeviceIdentityKey, sessionId, message_type, ciphertext,\n) {\n const self = this;\n\n return this._getSession(theirDeviceIdentityKey, sessionId, function(session) {\n const payloadString = session.decrypt(message_type, ciphertext);\n self._saveSession(theirDeviceIdentityKey, session);\n\n return payloadString;\n });\n};\n\n/**\n * Determine if an incoming messages is a prekey message matching an existing session\n *\n * @param {string} theirDeviceIdentityKey Curve25519 identity key for the\n * remote device\n * @param {string} sessionId the id of the active session\n * @param {number} message_type message_type field from the received message\n * @param {string} ciphertext base64-encoded body from the received message\n *\n * @return {Promise} true if the received message is a prekey message which matches\n * the given session.\n */\nOlmDevice.prototype.matchesSession = async function(\n theirDeviceIdentityKey, sessionId, message_type, ciphertext,\n) {\n if (message_type !== 0) {\n return false;\n }\n\n return this._getSession(theirDeviceIdentityKey, sessionId, function(session) {\n return session.matches_inbound(ciphertext);\n });\n};\n\n\n// Outbound group session\n// ======================\n\n/**\n * store an OutboundGroupSession in _outboundGroupSessionStore\n *\n * @param {Olm.OutboundGroupSession} session\n * @private\n */\nOlmDevice.prototype._saveOutboundGroupSession = function(session) {\n const pickledSession = session.pickle(this._pickleKey);\n this._outboundGroupSessionStore[session.session_id()] = pickledSession;\n};\n\n\n/**\n * extract an OutboundGroupSession from _outboundGroupSessionStore and call the\n * given function\n *\n * @param {string} sessionId\n * @param {function} func\n * @return {object} result of func\n * @private\n */\nOlmDevice.prototype._getOutboundGroupSession = function(sessionId, func) {\n const pickled = this._outboundGroupSessionStore[sessionId];\n if (pickled === null) {\n throw new Error(\"Unknown outbound group session \" + sessionId);\n }\n\n const session = new Olm.OutboundGroupSession();\n try {\n session.unpickle(this._pickleKey, pickled);\n return func(session);\n } finally {\n session.free();\n }\n};\n\n\n/**\n * Generate a new outbound group session\n *\n * @return {string} sessionId for the outbound session.\n */\nOlmDevice.prototype.createOutboundGroupSession = function() {\n const session = new Olm.OutboundGroupSession();\n try {\n session.create();\n this._saveOutboundGroupSession(session);\n return session.session_id();\n } finally {\n session.free();\n }\n};\n\n\n/**\n * Encrypt an outgoing message with an outbound group session\n *\n * @param {string} sessionId the id of the outboundgroupsession\n * @param {string} payloadString payload to be encrypted and sent\n *\n * @return {string} ciphertext\n */\nOlmDevice.prototype.encryptGroupMessage = function(sessionId, payloadString) {\n const self = this;\n\n checkPayloadLength(payloadString);\n\n return this._getOutboundGroupSession(sessionId, function(session) {\n const res = session.encrypt(payloadString);\n self._saveOutboundGroupSession(session);\n return res;\n });\n};\n\n/**\n * Get the session keys for an outbound group session\n *\n * @param {string} sessionId the id of the outbound group session\n *\n * @return {{chain_index: number, key: string}} current chain index, and\n * base64-encoded secret key.\n */\nOlmDevice.prototype.getOutboundGroupSessionKey = function(sessionId) {\n return this._getOutboundGroupSession(sessionId, function(session) {\n return {\n chain_index: session.message_index(),\n key: session.session_key(),\n };\n });\n};\n\n\n// Inbound group session\n// =====================\n\n/**\n * data stored in the session store about an inbound group session\n *\n * @typedef {Object} InboundGroupSessionData\n * @property {string} room_Id\n * @property {string} session pickled Olm.InboundGroupSession\n * @property {Object} keysClaimed\n * @property {Array} forwardingCurve25519KeyChain Devices involved in forwarding\n * this session to us (normally empty).\n */\n\n/**\n * store an InboundGroupSession in the session store\n *\n * @param {string} senderCurve25519Key\n * @param {string} sessionId\n * @param {InboundGroupSessionData} sessionData\n * @private\n */\nOlmDevice.prototype._saveInboundGroupSession = function(\n senderCurve25519Key, sessionId, sessionData,\n) {\n this._sessionStore.storeEndToEndInboundGroupSession(\n senderCurve25519Key, sessionId, JSON.stringify(sessionData),\n );\n};\n\n/**\n * extract an InboundGroupSession from the session store and call the given function\n *\n * @param {string} roomId\n * @param {string} senderKey\n * @param {string} sessionId\n * @param {function(Olm.InboundGroupSession, InboundGroupSessionData): T} func\n * function to call.\n *\n * @return {null} the sessionId is unknown\n *\n * @return {T} result of func\n *\n * @private\n * @template {T}\n */\nOlmDevice.prototype._getInboundGroupSession = function(\n roomId, senderKey, sessionId, func,\n) {\n let r = this._sessionStore.getEndToEndInboundGroupSession(\n senderKey, sessionId,\n );\n\n if (r === null) {\n return null;\n }\n\n r = JSON.parse(r);\n\n // check that the room id matches the original one for the session. This stops\n // the HS pretending a message was targeting a different room.\n if (roomId !== r.room_id) {\n throw new Error(\n \"Mismatched room_id for inbound group session (expected \" + r.room_id +\n \", was \" + roomId + \")\",\n );\n }\n\n const session = new Olm.InboundGroupSession();\n try {\n session.unpickle(this._pickleKey, r.session);\n return func(session, r);\n } finally {\n session.free();\n }\n};\n\n/**\n * Add an inbound group session to the session store\n *\n * @param {string} roomId room in which this session will be used\n * @param {string} senderKey base64-encoded curve25519 key of the sender\n * @param {Array} forwardingCurve25519KeyChain Devices involved in forwarding\n * this session to us.\n * @param {string} sessionId session identifier\n * @param {string} sessionKey base64-encoded secret key\n * @param {Object} keysClaimed Other keys the sender claims.\n * @param {boolean} exportFormat true if the megolm keys are in export format\n * (ie, they lack an ed25519 signature)\n */\nOlmDevice.prototype.addInboundGroupSession = async function(\n roomId, senderKey, forwardingCurve25519KeyChain,\n sessionId, sessionKey, keysClaimed,\n exportFormat,\n) {\n const self = this;\n\n /* if we already have this session, consider updating it */\n function updateSession(session, sessionData) {\n console.log(\"Update for megolm session \" + senderKey + \"/\" + sessionId);\n // for now we just ignore updates. TODO: implement something here\n\n return true;\n }\n\n const r = this._getInboundGroupSession(\n roomId, senderKey, sessionId, updateSession,\n );\n\n if (r !== null) {\n return;\n }\n\n // new session.\n const session = new Olm.InboundGroupSession();\n try {\n if (exportFormat) {\n session.import_session(sessionKey);\n } else {\n session.create(sessionKey);\n }\n if (sessionId != session.session_id()) {\n throw new Error(\n \"Mismatched group session ID from senderKey: \" + senderKey,\n );\n }\n\n const sessionData = {\n room_id: roomId,\n session: session.pickle(this._pickleKey),\n keysClaimed: keysClaimed,\n forwardingCurve25519KeyChain: forwardingCurve25519KeyChain,\n };\n\n self._saveInboundGroupSession(\n senderKey, sessionId, sessionData,\n );\n } finally {\n session.free();\n }\n};\n\n\n/**\n * Add a previously-exported inbound group session to the session store\n *\n * @param {module:crypto/OlmDevice.MegolmSessionData} data session data\n */\nOlmDevice.prototype.importInboundGroupSession = async function(data) {\n /* if we already have this session, consider updating it */\n function updateSession(session, sessionData) {\n console.log(\"Update for megolm session \" + data.sender_key + \"|\" +\n data.session_id);\n // for now we just ignore updates. TODO: implement something here\n\n return true;\n }\n\n const r = this._getInboundGroupSession(\n data.room_id, data.sender_key, data.session_id, updateSession,\n );\n\n if (r !== null) {\n return;\n }\n\n // new session.\n const session = new Olm.InboundGroupSession();\n try {\n session.import_session(data.session_key);\n if (data.session_id != session.session_id()) {\n throw new Error(\n \"Mismatched group session ID from senderKey: \" + data.sender_key,\n );\n }\n\n const sessionData = {\n room_id: data.room_id,\n session: session.pickle(this._pickleKey),\n keysClaimed: data.sender_claimed_keys,\n forwardingCurve25519KeyChain: data.forwarding_curve25519_key_chain,\n };\n\n this._saveInboundGroupSession(\n data.sender_key, data.session_id, sessionData,\n );\n } finally {\n session.free();\n }\n};\n\n/**\n * Decrypt a received message with an inbound group session\n *\n * @param {string} roomId room in which the message was received\n * @param {string} senderKey base64-encoded curve25519 key of the sender\n * @param {string} sessionId session identifier\n * @param {string} body base64-encoded body of the encrypted message\n * @param {string} eventId ID of the event being decrypted\n * @param {Number} timestamp timestamp of the event being decrypted\n *\n * @return {null} the sessionId is unknown\n *\n * @return {Promise<{result: string, senderKey: string,\n * forwardingCurve25519KeyChain: Array,\n * keysClaimed: Object}>}\n */\nOlmDevice.prototype.decryptGroupMessage = async function(\n roomId, senderKey, sessionId, body, eventId, timestamp,\n) {\n const self = this;\n\n function decrypt(session, sessionData) {\n const res = session.decrypt(body);\n\n let plaintext = res.plaintext;\n if (plaintext === undefined) {\n // Compatibility for older olm versions.\n plaintext = res;\n } else {\n // Check if we have seen this message index before to detect replay attacks.\n // If the event ID and timestamp are specified, and the match the event ID\n // and timestamp from the last time we used this message index, then we\n // don't consider it a replay attack.\n const messageIndexKey = senderKey + \"|\" + sessionId + \"|\" + res.message_index;\n if (messageIndexKey in self._inboundGroupSessionMessageIndexes) {\n const msgInfo = self._inboundGroupSessionMessageIndexes[messageIndexKey];\n if (msgInfo.id !== eventId || msgInfo.timestamp !== timestamp) {\n throw new Error(\n \"Duplicate message index, possible replay attack: \" +\n messageIndexKey,\n );\n }\n }\n self._inboundGroupSessionMessageIndexes[messageIndexKey] = {\n id: eventId,\n timestamp: timestamp,\n };\n }\n\n sessionData.session = session.pickle(self._pickleKey);\n self._saveInboundGroupSession(\n senderKey, sessionId, sessionData,\n );\n return {\n result: plaintext,\n keysClaimed: sessionData.keysClaimed || {},\n senderKey: senderKey,\n forwardingCurve25519KeyChain: sessionData.forwardingCurve25519KeyChain || [],\n };\n }\n\n return this._getInboundGroupSession(\n roomId, senderKey, sessionId, decrypt,\n );\n};\n\n/**\n * Determine if we have the keys for a given megolm session\n *\n * @param {string} roomId room in which the message was received\n * @param {string} senderKey base64-encoded curve25519 key of the sender\n * @param {sring} sessionId session identifier\n *\n * @returns {Promise} true if we have the keys to this session\n */\nOlmDevice.prototype.hasInboundSessionKeys = async function(roomId, senderKey, sessionId) {\n const s = this._sessionStore.getEndToEndInboundGroupSession(\n senderKey, sessionId,\n );\n\n if (s === null) {\n return false;\n }\n\n const r = JSON.parse(s);\n if (roomId !== r.room_id) {\n console.warn(\n `requested keys for inbound group session ${senderKey}|` +\n `${sessionId}, with incorrect room_id (expected ${r.room_id}, ` +\n `was ${roomId})`,\n );\n return false;\n }\n\n return true;\n};\n\n/**\n * Extract the keys to a given megolm session, for sharing\n *\n * @param {string} roomId room in which the message was received\n * @param {string} senderKey base64-encoded curve25519 key of the sender\n * @param {string} sessionId session identifier\n *\n * @returns {Promise<{chain_index: number, key: string,\n * forwarding_curve25519_key_chain: Array,\n * sender_claimed_ed25519_key: string\n * }>}\n * details of the session key. The key is a base64-encoded megolm key in\n * export format.\n */\nOlmDevice.prototype.getInboundGroupSessionKey = async function(\n roomId, senderKey, sessionId,\n) {\n function getKey(session, sessionData) {\n const messageIndex = session.first_known_index();\n\n const claimedKeys = sessionData.keysClaimed || {};\n const senderEd25519Key = claimedKeys.ed25519 || null;\n\n return {\n \"chain_index\": messageIndex,\n \"key\": session.export_session(messageIndex),\n \"forwarding_curve25519_key_chain\":\n sessionData.forwardingCurve25519KeyChain || [],\n \"sender_claimed_ed25519_key\": senderEd25519Key,\n };\n }\n\n return this._getInboundGroupSession(\n roomId, senderKey, sessionId, getKey,\n );\n};\n\n/**\n * Export an inbound group session\n *\n * @param {string} senderKey base64-encoded curve25519 key of the sender\n * @param {string} sessionId session identifier\n * @return {Promise} exported session data\n */\nOlmDevice.prototype.exportInboundGroupSession = async function(senderKey, sessionId) {\n const s = this._sessionStore.getEndToEndInboundGroupSession(\n senderKey, sessionId,\n );\n\n if (s === null) {\n throw new Error(\"Unknown inbound group session [\" + senderKey + \",\" +\n sessionId + \"]\");\n }\n const r = JSON.parse(s);\n\n const session = new Olm.InboundGroupSession();\n try {\n session.unpickle(this._pickleKey, r.session);\n\n const messageIndex = session.first_known_index();\n\n return {\n \"sender_key\": senderKey,\n \"sender_claimed_keys\": r.keysClaimed,\n \"room_id\": r.room_id,\n \"session_id\": sessionId,\n \"session_key\": session.export_session(messageIndex),\n \"forwarding_curve25519_key_chain\":\n session.forwardingCurve25519KeyChain || [],\n };\n } finally {\n session.free();\n }\n};\n\n// Utilities\n// =========\n\n/**\n * Verify an ed25519 signature.\n *\n * @param {string} key ed25519 key\n * @param {string} message message which was signed\n * @param {string} signature base64-encoded signature to be checked\n *\n * @raises {Error} if there is a problem with the verification. If the key was\n * too small then the message will be \"OLM.INVALID_BASE64\". If the signature\n * was invalid then the message will be \"OLM.BAD_MESSAGE_MAC\".\n */\nOlmDevice.prototype.verifySignature = function(\n key, message, signature,\n) {\n this._getUtility(function(util) {\n util.ed25519_verify(key, message, signature);\n });\n};\n\n/** */\nmodule.exports = OlmDevice;\n","/*\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport Promise from 'bluebird';\n\nimport utils from '../utils';\n\n/**\n * Internal module. Management of outgoing room key requests.\n *\n * See https://docs.google.com/document/d/1m4gQkcnJkxNuBmb5NoFCIadIY-DyqqNAS3lloE73BlQ\n * for draft documentation on what we're supposed to be implementing here.\n *\n * @module\n */\n\n// delay between deciding we want some keys, and sending out the request, to\n// allow for (a) it turning up anyway, (b) grouping requests together\nconst SEND_KEY_REQUESTS_DELAY_MS = 500;\n\n/** possible states for a room key request\n *\n * The state machine looks like:\n *\n * |\n * V (cancellation requested)\n * UNSENT -----------------------------+\n * | |\n * | (send successful) |\n * V |\n * SENT |\n * | |\n * | (cancellation requested) |\n * V |\n * CANCELLATION_PENDING |\n * | |\n * | (cancellation sent) |\n * V |\n * (deleted) <---------------------------+\n *\n * @enum {number}\n */\nconst ROOM_KEY_REQUEST_STATES = {\n /** request not yet sent */\n UNSENT: 0,\n\n /** request sent, awaiting reply */\n SENT: 1,\n\n /** reply received, cancellation not yet sent */\n CANCELLATION_PENDING: 2,\n};\n\nexport default class OutgoingRoomKeyRequestManager {\n constructor(baseApis, deviceId, cryptoStore) {\n this._baseApis = baseApis;\n this._deviceId = deviceId;\n this._cryptoStore = cryptoStore;\n\n // handle for the delayed call to _sendOutgoingRoomKeyRequests. Non-null\n // if the callback has been set, or if it is still running.\n this._sendOutgoingRoomKeyRequestsTimer = null;\n\n // sanity check to ensure that we don't end up with two concurrent runs\n // of _sendOutgoingRoomKeyRequests\n this._sendOutgoingRoomKeyRequestsRunning = false;\n\n this._clientRunning = false;\n }\n\n /**\n * Called when the client is started. Sets background processes running.\n */\n start() {\n this._clientRunning = true;\n\n // set the timer going, to handle any requests which didn't get sent\n // on the previous run of the client.\n this._startTimer();\n }\n\n /**\n * Called when the client is stopped. Stops any running background processes.\n */\n stop() {\n console.log('stopping OutgoingRoomKeyRequestManager');\n // stop the timer on the next run\n this._clientRunning = false;\n }\n\n /**\n * Send off a room key request, if we haven't already done so.\n *\n * The `requestBody` is compared (with a deep-equality check) against\n * previous queued or sent requests and if it matches, no change is made.\n * Otherwise, a request is added to the pending list, and a job is started\n * in the background to send it.\n *\n * @param {module:crypto~RoomKeyRequestBody} requestBody\n * @param {Array<{userId: string, deviceId: string}>} recipients\n *\n * @returns {Promise} resolves when the request has been added to the\n * pending list (or we have established that a similar request already\n * exists)\n */\n sendRoomKeyRequest(requestBody, recipients) {\n return this._cryptoStore.getOrAddOutgoingRoomKeyRequest({\n requestBody: requestBody,\n recipients: recipients,\n requestId: this._baseApis.makeTxnId(),\n state: ROOM_KEY_REQUEST_STATES.UNSENT,\n }).then((req) => {\n if (req.state === ROOM_KEY_REQUEST_STATES.UNSENT) {\n this._startTimer();\n }\n });\n }\n\n /**\n * Cancel room key requests, if any match the given details\n *\n * @param {module:crypto~RoomKeyRequestBody} requestBody\n *\n * @returns {Promise} resolves when the request has been updated in our\n * pending list.\n */\n cancelRoomKeyRequest(requestBody) {\n return this._cryptoStore.getOutgoingRoomKeyRequest(\n requestBody,\n ).then((req) => {\n if (!req) {\n // no request was made for this key\n return;\n }\n switch (req.state) {\n case ROOM_KEY_REQUEST_STATES.CANCELLATION_PENDING:\n // nothing to do here\n return;\n\n case ROOM_KEY_REQUEST_STATES.UNSENT:\n // just delete it\n\n // FIXME: ghahah we may have attempted to send it, and\n // not yet got a successful response. So the server\n // may have seen it, so we still need to send a cancellation\n // in that case :/\n\n console.log(\n 'deleting unnecessary room key request for ' +\n stringifyRequestBody(requestBody),\n );\n return this._cryptoStore.deleteOutgoingRoomKeyRequest(\n req.requestId, ROOM_KEY_REQUEST_STATES.UNSENT,\n );\n\n case ROOM_KEY_REQUEST_STATES.SENT:\n // send a cancellation.\n return this._cryptoStore.updateOutgoingRoomKeyRequest(\n req.requestId, ROOM_KEY_REQUEST_STATES.SENT, {\n state: ROOM_KEY_REQUEST_STATES.CANCELLATION_PENDING,\n cancellationTxnId: this._baseApis.makeTxnId(),\n },\n ).then((updatedReq) => {\n if (!updatedReq) {\n // updateOutgoingRoomKeyRequest couldn't find the\n // request in state ROOM_KEY_REQUEST_STATES.SENT,\n // so we must have raced with another tab to mark\n // the request cancelled. There is no point in\n // sending another cancellation since the other tab\n // will do it.\n console.log(\n 'Tried to cancel room key request for ' +\n stringifyRequestBody(requestBody) +\n ' but it was already cancelled in another tab',\n );\n return;\n }\n\n // We don't want to wait for the timer, so we send it\n // immediately. (We might actually end up racing with the timer,\n // but that's ok: even if we make the request twice, we'll do it\n // with the same transaction_id, so only one message will get\n // sent).\n //\n // (We also don't want to wait for the response from the server\n // here, as it will slow down processing of received keys if we\n // do.)\n this._sendOutgoingRoomKeyRequestCancellation(\n updatedReq,\n ).catch((e) => {\n console.error(\n \"Error sending room key request cancellation;\"\n + \" will retry later.\", e,\n );\n this._startTimer();\n }).done();\n });\n\n default:\n throw new Error('unhandled state: ' + req.state);\n }\n });\n }\n\n // start the background timer to send queued requests, if the timer isn't\n // already running\n _startTimer() {\n if (this._sendOutgoingRoomKeyRequestsTimer) {\n return;\n }\n\n const startSendingOutgoingRoomKeyRequests = () => {\n if (this._sendOutgoingRoomKeyRequestsRunning) {\n throw new Error(\"RoomKeyRequestSend already in progress!\");\n }\n this._sendOutgoingRoomKeyRequestsRunning = true;\n\n this._sendOutgoingRoomKeyRequests().finally(() => {\n this._sendOutgoingRoomKeyRequestsRunning = false;\n }).catch((e) => {\n // this should only happen if there is an indexeddb error,\n // in which case we're a bit stuffed anyway.\n console.warn(\n `error in OutgoingRoomKeyRequestManager: ${e}`,\n );\n }).done();\n };\n\n this._sendOutgoingRoomKeyRequestsTimer = global.setTimeout(\n startSendingOutgoingRoomKeyRequests,\n SEND_KEY_REQUESTS_DELAY_MS,\n );\n }\n\n // look for and send any queued requests. Runs itself recursively until\n // there are no more requests, or there is an error (in which case, the\n // timer will be restarted before the promise resolves).\n _sendOutgoingRoomKeyRequests() {\n if (!this._clientRunning) {\n this._sendOutgoingRoomKeyRequestsTimer = null;\n return Promise.resolve();\n }\n\n console.log(\"Looking for queued outgoing room key requests\");\n\n return this._cryptoStore.getOutgoingRoomKeyRequestByState([\n ROOM_KEY_REQUEST_STATES.CANCELLATION_PENDING,\n ROOM_KEY_REQUEST_STATES.UNSENT,\n ]).then((req) => {\n if (!req) {\n console.log(\"No more outgoing room key requests\");\n this._sendOutgoingRoomKeyRequestsTimer = null;\n return;\n }\n\n let prom;\n if (req.state === ROOM_KEY_REQUEST_STATES.UNSENT) {\n prom = this._sendOutgoingRoomKeyRequest(req);\n } else { // must be a cancellation\n prom = this._sendOutgoingRoomKeyRequestCancellation(req);\n }\n\n return prom.then(() => {\n // go around the loop again\n return this._sendOutgoingRoomKeyRequests();\n }).catch((e) => {\n console.error(\"Error sending room key request; will retry later.\", e);\n this._sendOutgoingRoomKeyRequestsTimer = null;\n this._startTimer();\n }).done();\n });\n }\n\n // given a RoomKeyRequest, send it and update the request record\n _sendOutgoingRoomKeyRequest(req) {\n console.log(\n `Requesting keys for ${stringifyRequestBody(req.requestBody)}` +\n ` from ${stringifyRecipientList(req.recipients)}` +\n `(id ${req.requestId})`,\n );\n\n const requestMessage = {\n action: \"request\",\n requesting_device_id: this._deviceId,\n request_id: req.requestId,\n body: req.requestBody,\n };\n\n return this._sendMessageToDevices(\n requestMessage, req.recipients, req.requestId,\n ).then(() => {\n return this._cryptoStore.updateOutgoingRoomKeyRequest(\n req.requestId, ROOM_KEY_REQUEST_STATES.UNSENT,\n { state: ROOM_KEY_REQUEST_STATES.SENT },\n );\n });\n }\n\n // given a RoomKeyRequest, cancel it and delete the request record\n _sendOutgoingRoomKeyRequestCancellation(req) {\n console.log(\n `Sending cancellation for key request for ` +\n `${stringifyRequestBody(req.requestBody)} to ` +\n `${stringifyRecipientList(req.recipients)} ` +\n `(cancellation id ${req.cancellationTxnId})`,\n );\n\n const requestMessage = {\n action: \"request_cancellation\",\n requesting_device_id: this._deviceId,\n request_id: req.requestId,\n };\n\n return this._sendMessageToDevices(\n requestMessage, req.recipients, req.cancellationTxnId,\n ).then(() => {\n return this._cryptoStore.deleteOutgoingRoomKeyRequest(\n req.requestId, ROOM_KEY_REQUEST_STATES.CANCELLATION_PENDING,\n );\n });\n }\n\n // send a RoomKeyRequest to a list of recipients\n _sendMessageToDevices(message, recipients, txnId) {\n const contentMap = {};\n for (const recip of recipients) {\n if (!contentMap[recip.userId]) {\n contentMap[recip.userId] = {};\n }\n contentMap[recip.userId][recip.deviceId] = message;\n }\n\n return this._baseApis.sendToDevice(\n 'm.room_key_request', contentMap, txnId,\n );\n }\n}\n\nfunction stringifyRequestBody(requestBody) {\n // we assume that the request is for megolm keys, which are identified by\n // room id and session id\n return requestBody.room_id + \" / \" + requestBody.session_id;\n}\n\nfunction stringifyRecipientList(recipients) {\n return '['\n + utils.map(recipients, (r) => `${r.userId}:${r.deviceId}`).join(\",\")\n + ']';\n}\n\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * Internal module. Defines the base classes of the encryption implementations\n *\n * @module\n */\n\nimport Promise from 'bluebird';\n\n/**\n * map of registered encryption algorithm classes. A map from string to {@link\n * module:crypto/algorithms/base.EncryptionAlgorithm|EncryptionAlgorithm} class\n *\n * @type {Object.}\n */\nexport const ENCRYPTION_CLASSES = {};\n\n/**\n * map of registered encryption algorithm classes. Map from string to {@link\n * module:crypto/algorithms/base.DecryptionAlgorithm|DecryptionAlgorithm} class\n *\n * @type {Object.}\n */\nexport const DECRYPTION_CLASSES = {};\n\n/**\n * base type for encryption implementations\n *\n * @alias module:crypto/algorithms/base.EncryptionAlgorithm\n *\n * @param {object} params parameters\n * @param {string} params.userId The UserID for the local user\n * @param {string} params.deviceId The identifier for this device.\n * @param {module:crypto} params.crypto crypto core\n * @param {module:crypto/OlmDevice} params.olmDevice olm.js wrapper\n * @param {module:base-apis~MatrixBaseApis} baseApis base matrix api interface\n * @param {string} params.roomId The ID of the room we will be sending to\n * @param {object} params.config The body of the m.room.encryption event\n */\nclass EncryptionAlgorithm {\n constructor(params) {\n this._userId = params.userId;\n this._deviceId = params.deviceId;\n this._crypto = params.crypto;\n this._olmDevice = params.olmDevice;\n this._baseApis = params.baseApis;\n this._roomId = params.roomId;\n }\n\n /**\n * Encrypt a message event\n *\n * @method module:crypto/algorithms/base.EncryptionAlgorithm.encryptMessage\n * @abstract\n *\n * @param {module:models/room} room\n * @param {string} eventType\n * @param {object} plaintext event content\n *\n * @return {module:client.Promise} Promise which resolves to the new event body\n */\n\n /**\n * Called when the membership of a member of the room changes.\n *\n * @param {module:models/event.MatrixEvent} event event causing the change\n * @param {module:models/room-member} member user whose membership changed\n * @param {string=} oldMembership previous membership\n * @public\n */\n onRoomMembership(event, member, oldMembership) {\n }\n}\nexport {EncryptionAlgorithm}; // https://github.com/jsdoc3/jsdoc/issues/1272\n\n/**\n * base type for decryption implementations\n *\n * @alias module:crypto/algorithms/base.DecryptionAlgorithm\n * @param {object} params parameters\n * @param {string} params.userId The UserID for the local user\n * @param {module:crypto} params.crypto crypto core\n * @param {module:crypto/OlmDevice} params.olmDevice olm.js wrapper\n * @param {module:base-apis~MatrixBaseApis} baseApis base matrix api interface\n * @param {string=} params.roomId The ID of the room we will be receiving\n * from. Null for to-device events.\n */\nclass DecryptionAlgorithm {\n constructor(params) {\n this._userId = params.userId;\n this._crypto = params.crypto;\n this._olmDevice = params.olmDevice;\n this._baseApis = params.baseApis;\n this._roomId = params.roomId;\n }\n\n /**\n * Decrypt an event\n *\n * @method module:crypto/algorithms/base.DecryptionAlgorithm#decryptEvent\n * @abstract\n *\n * @param {MatrixEvent} event undecrypted event\n *\n * @return {Promise} promise which\n * resolves once we have finished decrypting. Rejects with an\n * `algorithms.DecryptionError` if there is a problem decrypting the event.\n */\n\n /**\n * Handle a key event\n *\n * @method module:crypto/algorithms/base.DecryptionAlgorithm#onRoomKeyEvent\n *\n * @param {module:models/event.MatrixEvent} params event key event\n */\n onRoomKeyEvent(params) {\n // ignore by default\n }\n\n /**\n * Import a room key\n *\n * @param {module:crypto/OlmDevice.MegolmSessionData} session\n */\n importRoomKey(session) {\n // ignore by default\n }\n\n /**\n * Determine if we have the keys necessary to respond to a room key request\n *\n * @param {module:crypto~IncomingRoomKeyRequest} keyRequest\n * @return {Promise} true if we have the keys and could (theoretically) share\n * them; else false.\n */\n hasKeysForKeyRequest(keyRequest) {\n return Promise.resolve(false);\n }\n\n /**\n * Send the response to a room key request\n *\n * @param {module:crypto~IncomingRoomKeyRequest} keyRequest\n */\n shareKeysWithDevice(keyRequest) {\n throw new Error(\"shareKeysWithDevice not supported for this DecryptionAlgorithm\");\n }\n}\nexport {DecryptionAlgorithm}; // https://github.com/jsdoc3/jsdoc/issues/1272\n\n/**\n * Exception thrown when decryption fails\n *\n * @alias module:crypto/algorithms/base.DecryptionError\n * @param {string} msg user-visible message describing the problem\n *\n * @param {Object=} details key/value pairs reported in the logs but not shown\n * to the user.\n *\n * @extends Error\n */\nclass DecryptionError extends Error {\n constructor(msg, details) {\n super(msg);\n this.name = 'DecryptionError';\n this.details = details;\n }\n\n /**\n * override the string used when logging\n *\n * @returns {String}\n */\n toString() {\n let result = this.name + '[msg: ' + this.message;\n\n if (this.details) {\n result += ', ' +\n Object.keys(this.details).map(\n (k) => k + ': ' + this.details[k],\n ).join(', ');\n }\n\n result += ']';\n\n return result;\n }\n}\nexport {DecryptionError}; // https://github.com/jsdoc3/jsdoc/issues/1272\n\n/**\n * Exception thrown specifically when we want to warn the user to consider\n * the security of their conversation before continuing\n *\n * @param {string} msg message describing the problem\n * @param {Object} devices userId -> {deviceId -> object}\n * set of unknown devices per user we're warning about\n * @extends Error\n */\nexport class UnknownDeviceError extends Error {\n constructor(msg, devices) {\n super(msg);\n this.name = \"UnknownDeviceError\";\n this.devices = devices;\n }\n}\n\n/**\n * Registers an encryption/decryption class for a particular algorithm\n *\n * @param {string} algorithm algorithm tag to register for\n *\n * @param {class} encryptor {@link\n * module:crypto/algorithms/base.EncryptionAlgorithm|EncryptionAlgorithm}\n * implementation\n *\n * @param {class} decryptor {@link\n * module:crypto/algorithms/base.DecryptionAlgorithm|DecryptionAlgorithm}\n * implementation\n */\nexport function registerAlgorithm(algorithm, encryptor, decryptor) {\n ENCRYPTION_CLASSES[algorithm] = encryptor;\n DECRYPTION_CLASSES[algorithm] = decryptor;\n}\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * @module crypto/algorithms\n */\n\nconst base = require(\"./base\");\n\nrequire(\"./olm\");\nrequire(\"./megolm\");\n\n/**\n * @see module:crypto/algorithms/base.ENCRYPTION_CLASSES\n */\nmodule.exports.ENCRYPTION_CLASSES = base.ENCRYPTION_CLASSES;\n\n/**\n * @see module:crypto/algorithms/base.DECRYPTION_CLASSES\n */\nmodule.exports.DECRYPTION_CLASSES = base.DECRYPTION_CLASSES;\n\n/**\n * @see module:crypto/algorithms/base.DecryptionError\n */\nmodule.exports.DecryptionError = base.DecryptionError;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * Defines m.olm encryption/decryption\n *\n * @module crypto/algorithms/megolm\n */\n\nimport Promise from 'bluebird';\n\nconst utils = require(\"../../utils\");\nconst olmlib = require(\"../olmlib\");\nconst base = require(\"./base\");\n\n/**\n * @private\n * @constructor\n *\n * @param {string} sessionId\n *\n * @property {string} sessionId\n * @property {Number} useCount number of times this session has been used\n * @property {Number} creationTime when the session was created (ms since the epoch)\n *\n * @property {object} sharedWithDevices\n * devices with which we have shared the session key\n * userId -> {deviceId -> msgindex}\n */\nfunction OutboundSessionInfo(sessionId) {\n this.sessionId = sessionId;\n this.useCount = 0;\n this.creationTime = new Date().getTime();\n this.sharedWithDevices = {};\n}\n\n\n/**\n * Check if it's time to rotate the session\n *\n * @param {Number} rotationPeriodMsgs\n * @param {Number} rotationPeriodMs\n * @return {Boolean}\n */\nOutboundSessionInfo.prototype.needsRotation = function(\n rotationPeriodMsgs, rotationPeriodMs,\n) {\n const sessionLifetime = new Date().getTime() - this.creationTime;\n\n if (this.useCount >= rotationPeriodMsgs ||\n sessionLifetime >= rotationPeriodMs\n ) {\n console.log(\n \"Rotating megolm session after \" + this.useCount +\n \" messages, \" + sessionLifetime + \"ms\",\n );\n return true;\n }\n\n return false;\n};\n\nOutboundSessionInfo.prototype.markSharedWithDevice = function(\n userId, deviceId, chainIndex,\n) {\n if (!this.sharedWithDevices[userId]) {\n this.sharedWithDevices[userId] = {};\n }\n this.sharedWithDevices[userId][deviceId] = chainIndex;\n};\n\n/**\n * Determine if this session has been shared with devices which it shouldn't\n * have been.\n *\n * @param {Object} devicesInRoom userId -> {deviceId -> object}\n * devices we should shared the session with.\n *\n * @return {Boolean} true if we have shared the session with devices which aren't\n * in devicesInRoom.\n */\nOutboundSessionInfo.prototype.sharedWithTooManyDevices = function(\n devicesInRoom,\n) {\n for (const userId in this.sharedWithDevices) {\n if (!this.sharedWithDevices.hasOwnProperty(userId)) {\n continue;\n }\n\n if (!devicesInRoom.hasOwnProperty(userId)) {\n console.log(\"Starting new session because we shared with \" + userId);\n return true;\n }\n\n for (const deviceId in this.sharedWithDevices[userId]) {\n if (!this.sharedWithDevices[userId].hasOwnProperty(deviceId)) {\n continue;\n }\n\n if (!devicesInRoom[userId].hasOwnProperty(deviceId)) {\n console.log(\n \"Starting new session because we shared with \" +\n userId + \":\" + deviceId,\n );\n return true;\n }\n }\n }\n};\n\n\n/**\n * Megolm encryption implementation\n *\n * @constructor\n * @extends {module:crypto/algorithms/base.EncryptionAlgorithm}\n *\n * @param {object} params parameters, as per\n * {@link module:crypto/algorithms/base.EncryptionAlgorithm}\n */\nfunction MegolmEncryption(params) {\n base.EncryptionAlgorithm.call(this, params);\n\n // the most recent attempt to set up a session. This is used to serialise\n // the session setups, so that we have a race-free view of which session we\n // are using, and which devices we have shared the keys with. It resolves\n // with an OutboundSessionInfo (or undefined, for the first message in the\n // room).\n this._setupPromise = Promise.resolve();\n\n // default rotation periods\n this._sessionRotationPeriodMsgs = 100;\n this._sessionRotationPeriodMs = 7 * 24 * 3600 * 1000;\n\n if (params.config.rotation_period_ms !== undefined) {\n this._sessionRotationPeriodMs = params.config.rotation_period_ms;\n }\n\n if (params.config.rotation_period_msgs !== undefined) {\n this._sessionRotationPeriodMsgs = params.config.rotation_period_msgs;\n }\n}\nutils.inherits(MegolmEncryption, base.EncryptionAlgorithm);\n\n/**\n * @private\n *\n * @param {Object} devicesInRoom The devices in this room, indexed by user ID\n *\n * @return {module:client.Promise} Promise which resolves to the\n * OutboundSessionInfo when setup is complete.\n */\nMegolmEncryption.prototype._ensureOutboundSession = function(devicesInRoom) {\n const self = this;\n\n let session;\n\n // takes the previous OutboundSessionInfo, and considers whether to create\n // a new one. Also shares the key with any (new) devices in the room.\n // Updates `session` to hold the final OutboundSessionInfo.\n //\n // returns a promise which resolves once the keyshare is successful.\n async function prepareSession(oldSession) {\n session = oldSession;\n\n // need to make a brand new session?\n if (session && session.needsRotation(self._sessionRotationPeriodMsgs,\n self._sessionRotationPeriodMs)\n ) {\n console.log(\"Starting new megolm session because we need to rotate.\");\n session = null;\n }\n\n // determine if we have shared with anyone we shouldn't have\n if (session && session.sharedWithTooManyDevices(devicesInRoom)) {\n session = null;\n }\n\n if (!session) {\n console.log(`Starting new megolm session for room ${self._roomId}`);\n session = await self._prepareNewSession();\n }\n\n // now check if we need to share with any devices\n const shareMap = {};\n\n for (const userId in devicesInRoom) {\n if (!devicesInRoom.hasOwnProperty(userId)) {\n continue;\n }\n\n const userDevices = devicesInRoom[userId];\n\n for (const deviceId in userDevices) {\n if (!userDevices.hasOwnProperty(deviceId)) {\n continue;\n }\n\n const deviceInfo = userDevices[deviceId];\n\n const key = deviceInfo.getIdentityKey();\n if (key == self._olmDevice.deviceCurve25519Key) {\n // don't bother sending to ourself\n continue;\n }\n\n if (\n !session.sharedWithDevices[userId] ||\n session.sharedWithDevices[userId][deviceId] === undefined\n ) {\n shareMap[userId] = shareMap[userId] || [];\n shareMap[userId].push(deviceInfo);\n }\n }\n }\n\n return self._shareKeyWithDevices(\n session, shareMap,\n );\n }\n\n // helper which returns the session prepared by prepareSession\n function returnSession() {\n return session;\n }\n\n // first wait for the previous share to complete\n const prom = this._setupPromise.then(prepareSession);\n\n // _setupPromise resolves to `session` whether or not the share succeeds\n this._setupPromise = prom.then(returnSession, returnSession);\n\n // but we return a promise which only resolves if the share was successful.\n return prom.then(returnSession);\n};\n\n/**\n * @private\n *\n * @return {module:crypto/algorithms/megolm.OutboundSessionInfo} session\n */\nMegolmEncryption.prototype._prepareNewSession = async function() {\n const sessionId = this._olmDevice.createOutboundGroupSession();\n const key = this._olmDevice.getOutboundGroupSessionKey(sessionId);\n\n await this._olmDevice.addInboundGroupSession(\n this._roomId, this._olmDevice.deviceCurve25519Key, [], sessionId,\n key.key, {ed25519: this._olmDevice.deviceEd25519Key},\n );\n\n return new OutboundSessionInfo(sessionId);\n};\n\n/**\n * @private\n *\n * @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session\n *\n * @param {number} chainIndex current chain index\n *\n * @param {object} devicemap\n * mapping from userId to deviceId to {@link module:crypto~OlmSessionResult}\n *\n * @param {object} devicesByUser\n * map from userid to list of devices\n *\n * @return {array>}\n */\nMegolmEncryption.prototype._splitUserDeviceMap = function(\n session, chainIndex, devicemap, devicesByUser,\n) {\n const maxToDeviceMessagesPerRequest = 20;\n\n // use an array where the slices of a content map gets stored\n const mapSlices = [];\n let currentSliceId = 0; // start inserting in the first slice\n let entriesInCurrentSlice = 0;\n\n for (const userId of Object.keys(devicesByUser)) {\n const devicesToShareWith = devicesByUser[userId];\n const sessionResults = devicemap[userId];\n\n for (let i = 0; i < devicesToShareWith.length; i++) {\n const deviceInfo = devicesToShareWith[i];\n const deviceId = deviceInfo.deviceId;\n\n const sessionResult = sessionResults[deviceId];\n if (!sessionResult.sessionId) {\n // no session with this device, probably because there\n // were no one-time keys.\n //\n // we could send them a to_device message anyway, as a\n // signal that they have missed out on the key sharing\n // message because of the lack of keys, but there's not\n // much point in that really; it will mostly serve to clog\n // up to_device inboxes.\n\n // mark this device as \"handled\" because we don't want to try\n // to claim a one-time-key for dead devices on every message.\n session.markSharedWithDevice(userId, deviceId, chainIndex);\n\n // ensureOlmSessionsForUsers has already done the logging,\n // so just skip it.\n continue;\n }\n\n console.log(\n \"share keys with device \" + userId + \":\" + deviceId,\n );\n\n if (entriesInCurrentSlice > maxToDeviceMessagesPerRequest) {\n // the current slice is filled up. Start inserting into the next slice\n entriesInCurrentSlice = 0;\n currentSliceId++;\n }\n if (!mapSlices[currentSliceId]) {\n mapSlices[currentSliceId] = [];\n }\n\n mapSlices[currentSliceId].push({\n userId: userId,\n deviceInfo: deviceInfo,\n });\n\n entriesInCurrentSlice++;\n }\n }\n return mapSlices;\n};\n\n/**\n * @private\n *\n * @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session\n *\n * @param {number} chainIndex current chain index\n *\n * @param {object} userDeviceMap\n * mapping from userId to deviceInfo\n *\n * @param {object} payload fields to include in the encrypted payload\n *\n * @return {module:client.Promise} Promise which resolves once the key sharing\n * for the given userDeviceMap is generated and has been sent.\n */\nMegolmEncryption.prototype._encryptAndSendKeysToDevices = function(\n session, chainIndex, userDeviceMap, payload,\n) {\n const encryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this._olmDevice.deviceCurve25519Key,\n ciphertext: {},\n };\n const contentMap = {};\n\n const promises = [];\n for (let i = 0; i < userDeviceMap.length; i++) {\n const val = userDeviceMap[i];\n const userId = val.userId;\n const deviceInfo = val.deviceInfo;\n const deviceId = deviceInfo.deviceId;\n\n if (!contentMap[userId]) {\n contentMap[userId] = {};\n }\n contentMap[userId][deviceId] = encryptedContent;\n\n promises.push(\n olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n this._userId,\n this._deviceId,\n this._olmDevice,\n userId,\n deviceInfo,\n payload,\n ),\n );\n }\n\n return Promise.all(promises).then(() => {\n return this._baseApis.sendToDevice(\"m.room.encrypted\", contentMap).then(() => {\n // store that we successfully uploaded the keys of the current slice\n for (const userId of Object.keys(contentMap)) {\n for (const deviceId of Object.keys(contentMap[userId])) {\n session.markSharedWithDevice(\n userId, deviceId, chainIndex,\n );\n }\n }\n });\n });\n};\n\n/**\n * @private\n *\n * @param {module:crypto/algorithms/megolm.OutboundSessionInfo} session\n *\n * @param {object} devicesByUser\n * map from userid to list of devices\n */\nMegolmEncryption.prototype._shareKeyWithDevices = async function(session, devicesByUser) {\n const key = this._olmDevice.getOutboundGroupSessionKey(session.sessionId);\n const payload = {\n type: \"m.room_key\",\n content: {\n algorithm: olmlib.MEGOLM_ALGORITHM,\n room_id: this._roomId,\n session_id: session.sessionId,\n session_key: key.key,\n chain_index: key.chain_index,\n },\n };\n\n const devicemap = await olmlib.ensureOlmSessionsForDevices(\n this._olmDevice, this._baseApis, devicesByUser,\n );\n\n const userDeviceMaps = this._splitUserDeviceMap(\n session, key.chain_index, devicemap, devicesByUser,\n );\n\n for (let i = 0; i < userDeviceMaps.length; i++) {\n try {\n await this._encryptAndSendKeysToDevices(\n session, key.chain_index, userDeviceMaps[i], payload,\n );\n console.log(`Completed megolm keyshare in ${this._roomId} `\n + `(slice ${i + 1}/${userDeviceMaps.length})`);\n } catch (e) {\n console.log(`megolm keyshare in ${this._roomId} `\n + `(slice ${i + 1}/${userDeviceMaps.length}) failed`);\n\n throw e;\n }\n }\n};\n\n/**\n * @inheritdoc\n *\n * @param {module:models/room} room\n * @param {string} eventType\n * @param {object} content plaintext event content\n *\n * @return {module:client.Promise} Promise which resolves to the new event body\n */\nMegolmEncryption.prototype.encryptMessage = function(room, eventType, content) {\n const self = this;\n console.log(`Starting to encrypt event for ${this._roomId}`);\n\n return this._getDevicesInRoom(room).then(function(devicesInRoom) {\n // check if any of these devices are not yet known to the user.\n // if so, warn the user so they can verify or ignore.\n self._checkForUnknownDevices(devicesInRoom);\n\n return self._ensureOutboundSession(devicesInRoom);\n }).then(function(session) {\n const payloadJson = {\n room_id: self._roomId,\n type: eventType,\n content: content,\n };\n\n const ciphertext = self._olmDevice.encryptGroupMessage(\n session.sessionId, JSON.stringify(payloadJson),\n );\n\n const encryptedContent = {\n algorithm: olmlib.MEGOLM_ALGORITHM,\n sender_key: self._olmDevice.deviceCurve25519Key,\n ciphertext: ciphertext,\n session_id: session.sessionId,\n // Include our device ID so that recipients can send us a\n // m.new_device message if they don't have our session key.\n device_id: self._deviceId,\n };\n\n session.useCount++;\n return encryptedContent;\n });\n};\n\n/**\n * Checks the devices we're about to send to and see if any are entirely\n * unknown to the user. If so, warn the user, and mark them as known to\n * give the user a chance to go verify them before re-sending this message.\n *\n * @param {Object} devicesInRoom userId -> {deviceId -> object}\n * devices we should shared the session with.\n */\nMegolmEncryption.prototype._checkForUnknownDevices = function(devicesInRoom) {\n const unknownDevices = {};\n\n Object.keys(devicesInRoom).forEach((userId)=>{\n Object.keys(devicesInRoom[userId]).forEach((deviceId)=>{\n const device = devicesInRoom[userId][deviceId];\n if (device.isUnverified() && !device.isKnown()) {\n if (!unknownDevices[userId]) {\n unknownDevices[userId] = {};\n }\n unknownDevices[userId][deviceId] = device;\n }\n });\n });\n\n if (Object.keys(unknownDevices).length) {\n // it'd be kind to pass unknownDevices up to the user in this error\n throw new base.UnknownDeviceError(\n \"This room contains unknown devices which have not been verified. \" +\n \"We strongly recommend you verify them before continuing.\", unknownDevices);\n }\n};\n\n/**\n * Get the list of unblocked devices for all users in the room\n *\n * @param {module:models/room} room\n *\n * @return {module:client.Promise} Promise which resolves to a map\n * from userId to deviceId to deviceInfo\n */\nMegolmEncryption.prototype._getDevicesInRoom = function(room) {\n // XXX what about rooms where invitees can see the content?\n const roomMembers = utils.map(room.getJoinedMembers(), function(u) {\n return u.userId;\n });\n\n // We are happy to use a cached version here: we assume that if we already\n // have a list of the user's devices, then we already share an e2e room\n // with them, which means that they will have announced any new devices via\n // an m.new_device.\n //\n // XXX: what if the cache is stale, and the user left the room we had in\n // common and then added new devices before joining this one? --Matthew\n //\n // yup, see https://github.com/vector-im/riot-web/issues/2305 --richvdh\n return this._crypto.downloadKeys(roomMembers, false).then((devices) => {\n // remove any blocked devices\n for (const userId in devices) {\n if (!devices.hasOwnProperty(userId)) {\n continue;\n }\n\n const userDevices = devices[userId];\n for (const deviceId in userDevices) {\n if (!userDevices.hasOwnProperty(deviceId)) {\n continue;\n }\n\n if (userDevices[deviceId].isBlocked() ||\n (userDevices[deviceId].isUnverified() &&\n (room.getBlacklistUnverifiedDevices() ||\n this._crypto.getGlobalBlacklistUnverifiedDevices()))\n ) {\n delete userDevices[deviceId];\n }\n }\n }\n\n return devices;\n });\n};\n\n/**\n * Megolm decryption implementation\n *\n * @constructor\n * @extends {module:crypto/algorithms/base.DecryptionAlgorithm}\n *\n * @param {object} params parameters, as per\n * {@link module:crypto/algorithms/base.DecryptionAlgorithm}\n */\nfunction MegolmDecryption(params) {\n base.DecryptionAlgorithm.call(this, params);\n\n // events which we couldn't decrypt due to unknown sessions / indexes: map from\n // senderKey|sessionId to Set of MatrixEvents\n this._pendingEvents = {};\n\n // this gets stubbed out by the unit tests.\n this.olmlib = olmlib;\n}\nutils.inherits(MegolmDecryption, base.DecryptionAlgorithm);\n\n/**\n * @inheritdoc\n *\n * @param {MatrixEvent} event\n *\n * returns a promise which resolves to a\n * {@link module:crypto~EventDecryptionResult} once we have finished\n * decrypting, or rejects with an `algorithms.DecryptionError` if there is a\n * problem decrypting the event.\n */\nMegolmDecryption.prototype.decryptEvent = async function(event) {\n const content = event.getWireContent();\n\n if (!content.sender_key || !content.session_id ||\n !content.ciphertext\n ) {\n throw new base.DecryptionError(\"Missing fields in input\");\n }\n\n // we add the event to the pending list *before* we start decryption.\n //\n // then, if the key turns up while decryption is in progress (and\n // decryption fails), we will schedule a retry.\n // (fixes https://github.com/vector-im/riot-web/issues/5001)\n this._addEventToPendingList(event);\n\n let res;\n try {\n res = await this._olmDevice.decryptGroupMessage(\n event.getRoomId(), content.sender_key, content.session_id, content.ciphertext,\n event.getId(), event.getTs(),\n );\n } catch (e) {\n if (e.message === 'OLM.UNKNOWN_MESSAGE_INDEX') {\n this._requestKeysForEvent(event);\n }\n throw new base.DecryptionError(\n e.toString(), {\n session: content.sender_key + '|' + content.session_id,\n },\n );\n }\n\n if (res === null) {\n // We've got a message for a session we don't have.\n //\n // (XXX: We might actually have received this key since we started\n // decrypting, in which case we'll have scheduled a retry, and this\n // request will be redundant. We could probably check to see if the\n // event is still in the pending list; if not, a retry will have been\n // scheduled, so we needn't send out the request here.)\n this._requestKeysForEvent(event);\n throw new base.DecryptionError(\n \"The sender's device has not sent us the keys for this message.\",\n {\n session: content.sender_key + '|' + content.session_id,\n },\n );\n }\n\n // success. We can remove the event from the pending list, if that hasn't\n // already happened.\n this._removeEventFromPendingList(event);\n\n const payload = JSON.parse(res.result);\n\n // belt-and-braces check that the room id matches that indicated by the HS\n // (this is somewhat redundant, since the megolm session is scoped to the\n // room, so neither the sender nor a MITM can lie about the room_id).\n if (payload.room_id !== event.getRoomId()) {\n throw new base.DecryptionError(\n \"Message intended for room \" + payload.room_id,\n );\n }\n\n return {\n clearEvent: payload,\n senderCurve25519Key: res.senderKey,\n claimedEd25519Key: res.keysClaimed.ed25519,\n forwardingCurve25519KeyChain: res.forwardingCurve25519KeyChain,\n };\n};\n\nMegolmDecryption.prototype._requestKeysForEvent = function(event) {\n const sender = event.getSender();\n const wireContent = event.getWireContent();\n\n // send the request to all of our own devices, and the\n // original sending device if it wasn't us.\n const recipients = [{\n userId: this._userId, deviceId: '*',\n }];\n if (sender != this._userId) {\n recipients.push({\n userId: sender, deviceId: wireContent.device_id,\n });\n }\n\n this._crypto.requestRoomKey({\n room_id: event.getRoomId(),\n algorithm: wireContent.algorithm,\n sender_key: wireContent.sender_key,\n session_id: wireContent.session_id,\n }, recipients);\n};\n\n/**\n * Add an event to the list of those awaiting their session keys.\n *\n * @private\n *\n * @param {module:models/event.MatrixEvent} event\n */\nMegolmDecryption.prototype._addEventToPendingList = function(event) {\n const content = event.getWireContent();\n const k = content.sender_key + \"|\" + content.session_id;\n if (!this._pendingEvents[k]) {\n this._pendingEvents[k] = new Set();\n }\n this._pendingEvents[k].add(event);\n};\n\n/**\n * Remove an event from the list of those awaiting their session keys.\n *\n * @private\n *\n * @param {module:models/event.MatrixEvent} event\n */\nMegolmDecryption.prototype._removeEventFromPendingList = function(event) {\n const content = event.getWireContent();\n const k = content.sender_key + \"|\" + content.session_id;\n if (!this._pendingEvents[k]) {\n return;\n }\n\n this._pendingEvents[k].delete(event);\n if (this._pendingEvents[k].size === 0) {\n delete this._pendingEvents[k];\n }\n};\n\n\n/**\n * @inheritdoc\n *\n * @param {module:models/event.MatrixEvent} event key event\n */\nMegolmDecryption.prototype.onRoomKeyEvent = function(event) {\n const content = event.getContent();\n const sessionId = content.session_id;\n let senderKey = event.getSenderKey();\n let forwardingKeyChain = [];\n let exportFormat = false;\n let keysClaimed;\n\n if (!content.room_id ||\n !sessionId ||\n !content.session_key\n ) {\n console.error(\"key event is missing fields\");\n return;\n }\n\n if (!senderKey) {\n console.error(\"key event has no sender key (not encrypted?)\");\n return;\n }\n\n if (event.getType() == \"m.forwarded_room_key\") {\n exportFormat = true;\n forwardingKeyChain = content.forwarding_curve25519_key_chain;\n if (!utils.isArray(forwardingKeyChain)) {\n forwardingKeyChain = [];\n }\n\n // copy content before we modify it\n forwardingKeyChain = forwardingKeyChain.slice();\n forwardingKeyChain.push(senderKey);\n\n senderKey = content.sender_key;\n if (!senderKey) {\n console.error(\"forwarded_room_key event is missing sender_key field\");\n return;\n }\n\n const ed25519Key = content.sender_claimed_ed25519_key;\n if (!ed25519Key) {\n console.error(\n `forwarded_room_key_event is missing sender_claimed_ed25519_key field`,\n );\n return;\n }\n\n keysClaimed = {\n ed25519: ed25519Key,\n };\n } else {\n keysClaimed = event.getKeysClaimed();\n }\n\n console.log(`Adding key for megolm session ${senderKey}|${sessionId}`);\n this._olmDevice.addInboundGroupSession(\n content.room_id, senderKey, forwardingKeyChain, sessionId,\n content.session_key, keysClaimed,\n exportFormat,\n ).then(() => {\n // cancel any outstanding room key requests for this session\n this._crypto.cancelRoomKeyRequest({\n algorithm: content.algorithm,\n room_id: content.room_id,\n session_id: content.session_id,\n sender_key: senderKey,\n });\n\n // have another go at decrypting events sent with this session.\n this._retryDecryption(senderKey, sessionId);\n }).catch((e) => {\n console.error(`Error handling m.room_key_event: ${e}`);\n });\n};\n\n/**\n * @inheritdoc\n */\nMegolmDecryption.prototype.hasKeysForKeyRequest = function(keyRequest) {\n const body = keyRequest.requestBody;\n\n return this._olmDevice.hasInboundSessionKeys(\n body.room_id,\n body.sender_key,\n body.session_id,\n // TODO: ratchet index\n );\n};\n\n/**\n * @inheritdoc\n */\nMegolmDecryption.prototype.shareKeysWithDevice = function(keyRequest) {\n const userId = keyRequest.userId;\n const deviceId = keyRequest.deviceId;\n const deviceInfo = this._crypto.getStoredDevice(userId, deviceId);\n const body = keyRequest.requestBody;\n\n this.olmlib.ensureOlmSessionsForDevices(\n this._olmDevice, this._baseApis, {\n [userId]: [deviceInfo],\n },\n ).then((devicemap) => {\n const olmSessionResult = devicemap[userId][deviceId];\n if (!olmSessionResult.sessionId) {\n // no session with this device, probably because there\n // were no one-time keys.\n //\n // ensureOlmSessionsForUsers has already done the logging,\n // so just skip it.\n return null;\n }\n\n console.log(\n \"sharing keys for session \" + body.sender_key + \"|\"\n + body.session_id + \" with device \"\n + userId + \":\" + deviceId,\n );\n\n return this._buildKeyForwardingMessage(\n body.room_id, body.sender_key, body.session_id,\n );\n }).then((payload) => {\n const encryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: this._olmDevice.deviceCurve25519Key,\n ciphertext: {},\n };\n\n return this.olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n this._userId,\n this._deviceId,\n this._olmDevice,\n userId,\n deviceInfo,\n payload,\n ).then(() => {\n const contentMap = {\n [userId]: {\n [deviceId]: encryptedContent,\n },\n };\n\n // TODO: retries\n return this._baseApis.sendToDevice(\"m.room.encrypted\", contentMap);\n });\n }).done();\n};\n\nMegolmDecryption.prototype._buildKeyForwardingMessage = async function(\n roomId, senderKey, sessionId,\n) {\n const key = await this._olmDevice.getInboundGroupSessionKey(\n roomId, senderKey, sessionId,\n );\n\n return {\n type: \"m.forwarded_room_key\",\n content: {\n algorithm: olmlib.MEGOLM_ALGORITHM,\n room_id: roomId,\n sender_key: senderKey,\n sender_claimed_ed25519_key: key.sender_claimed_ed25519_key,\n session_id: sessionId,\n session_key: key.key,\n chain_index: key.chain_index,\n forwarding_curve25519_key_chain: key.forwarding_curve25519_key_chain,\n },\n };\n};\n\n/**\n * @inheritdoc\n *\n * @param {module:crypto/OlmDevice.MegolmSessionData} session\n */\nMegolmDecryption.prototype.importRoomKey = function(session) {\n this._olmDevice.importInboundGroupSession(session);\n\n // have another go at decrypting events sent with this session.\n this._retryDecryption(session.sender_key, session.session_id);\n};\n\n/**\n * Have another go at decrypting events after we receive a key\n *\n * @private\n * @param {String} senderKey\n * @param {String} sessionId\n */\nMegolmDecryption.prototype._retryDecryption = function(senderKey, sessionId) {\n const k = senderKey + \"|\" + sessionId;\n const pending = this._pendingEvents[k];\n if (!pending) {\n return;\n }\n\n delete this._pendingEvents[k];\n\n for (const ev of pending) {\n ev.attemptDecryption(this._crypto);\n }\n};\n\nbase.registerAlgorithm(\n olmlib.MEGOLM_ALGORITHM, MegolmEncryption, MegolmDecryption,\n);\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * Defines m.olm encryption/decryption\n *\n * @module crypto/algorithms/olm\n */\nimport Promise from 'bluebird';\n\nconst utils = require(\"../../utils\");\nconst olmlib = require(\"../olmlib\");\nconst DeviceInfo = require(\"../deviceinfo\");\nconst DeviceVerification = DeviceInfo.DeviceVerification;\n\n\nconst base = require(\"./base\");\n\n/**\n * Olm encryption implementation\n *\n * @constructor\n * @extends {module:crypto/algorithms/base.EncryptionAlgorithm}\n *\n * @param {object} params parameters, as per\n * {@link module:crypto/algorithms/base.EncryptionAlgorithm}\n */\nfunction OlmEncryption(params) {\n base.EncryptionAlgorithm.call(this, params);\n this._sessionPrepared = false;\n this._prepPromise = null;\n}\nutils.inherits(OlmEncryption, base.EncryptionAlgorithm);\n\n/**\n * @private\n\n * @param {string[]} roomMembers list of currently-joined users in the room\n * @return {module:client.Promise} Promise which resolves when setup is complete\n */\nOlmEncryption.prototype._ensureSession = function(roomMembers) {\n if (this._prepPromise) {\n // prep already in progress\n return this._prepPromise;\n }\n\n if (this._sessionPrepared) {\n // prep already done\n return Promise.resolve();\n }\n\n const self = this;\n this._prepPromise = self._crypto.downloadKeys(roomMembers).then(function(res) {\n return self._crypto.ensureOlmSessionsForUsers(roomMembers);\n }).then(function() {\n self._sessionPrepared = true;\n }).finally(function() {\n self._prepPromise = null;\n });\n return this._prepPromise;\n};\n\n/**\n * @inheritdoc\n *\n * @param {module:models/room} room\n * @param {string} eventType\n * @param {object} content plaintext event content\n *\n * @return {module:client.Promise} Promise which resolves to the new event body\n */\nOlmEncryption.prototype.encryptMessage = function(room, eventType, content) {\n // pick the list of recipients based on the membership list.\n //\n // TODO: there is a race condition here! What if a new user turns up\n // just as you are sending a secret message?\n\n const users = utils.map(room.getJoinedMembers(), function(u) {\n return u.userId;\n });\n\n const self = this;\n return this._ensureSession(users).then(function() {\n const payloadFields = {\n room_id: room.roomId,\n type: eventType,\n content: content,\n };\n\n const encryptedContent = {\n algorithm: olmlib.OLM_ALGORITHM,\n sender_key: self._olmDevice.deviceCurve25519Key,\n ciphertext: {},\n };\n\n const promises = [];\n\n for (let i = 0; i < users.length; ++i) {\n const userId = users[i];\n const devices = self._crypto.getStoredDevicesForUser(userId);\n\n for (let j = 0; j < devices.length; ++j) {\n const deviceInfo = devices[j];\n const key = deviceInfo.getIdentityKey();\n if (key == self._olmDevice.deviceCurve25519Key) {\n // don't bother sending to ourself\n continue;\n }\n if (deviceInfo.verified == DeviceVerification.BLOCKED) {\n // don't bother setting up sessions with blocked users\n continue;\n }\n\n promises.push(\n olmlib.encryptMessageForDevice(\n encryptedContent.ciphertext,\n self._userId, self._deviceId, self._olmDevice,\n userId, deviceInfo, payloadFields,\n ),\n );\n }\n }\n\n return Promise.all(promises).return(encryptedContent);\n });\n};\n\n/**\n * Olm decryption implementation\n *\n * @constructor\n * @extends {module:crypto/algorithms/base.DecryptionAlgorithm}\n * @param {object} params parameters, as per\n * {@link module:crypto/algorithms/base.DecryptionAlgorithm}\n */\nfunction OlmDecryption(params) {\n base.DecryptionAlgorithm.call(this, params);\n}\nutils.inherits(OlmDecryption, base.DecryptionAlgorithm);\n\n/**\n * @inheritdoc\n *\n * @param {MatrixEvent} event\n *\n * returns a promise which resolves to a\n * {@link module:crypto~EventDecryptionResult} once we have finished\n * decrypting. Rejects with an `algorithms.DecryptionError` if there is a\n * problem decrypting the event.\n */\nOlmDecryption.prototype.decryptEvent = async function(event) {\n const content = event.getWireContent();\n const deviceKey = content.sender_key;\n const ciphertext = content.ciphertext;\n\n if (!ciphertext) {\n throw new base.DecryptionError(\"Missing ciphertext\");\n }\n\n if (!(this._olmDevice.deviceCurve25519Key in ciphertext)) {\n throw new base.DecryptionError(\"Not included in recipients\");\n }\n const message = ciphertext[this._olmDevice.deviceCurve25519Key];\n let payloadString;\n\n try {\n payloadString = await this._decryptMessage(deviceKey, message);\n } catch (e) {\n throw new base.DecryptionError(\n \"Bad Encrypted Message\", {\n sender: deviceKey,\n err: e,\n },\n );\n }\n\n const payload = JSON.parse(payloadString);\n\n // check that we were the intended recipient, to avoid unknown-key attack\n // https://github.com/vector-im/vector-web/issues/2483\n if (payload.recipient != this._userId) {\n throw new base.DecryptionError(\n \"Message was intented for \" + payload.recipient,\n );\n }\n\n if (payload.recipient_keys.ed25519 != this._olmDevice.deviceEd25519Key) {\n throw new base.DecryptionError(\n \"Message not intended for this device\", {\n intended: payload.recipient_keys.ed25519,\n our_key: this._olmDevice.deviceEd25519Key,\n },\n );\n }\n\n // check that the original sender matches what the homeserver told us, to\n // avoid people masquerading as others.\n // (this check is also provided via the sender's embedded ed25519 key,\n // which is checked elsewhere).\n if (payload.sender != event.getSender()) {\n throw new base.DecryptionError(\n \"Message forwarded from \" + payload.sender, {\n reported_sender: event.getSender(),\n },\n );\n }\n\n // Olm events intended for a room have a room_id.\n if (payload.room_id !== event.getRoomId()) {\n throw new base.DecryptionError(\n \"Message intended for room \" + payload.room_id, {\n reported_room: event.room_id,\n },\n );\n }\n\n const claimedKeys = payload.keys || {};\n\n return {\n clearEvent: payload,\n senderCurve25519Key: deviceKey,\n claimedEd25519Key: claimedKeys.ed25519 || null,\n };\n};\n\n/**\n * Attempt to decrypt an Olm message\n *\n * @param {string} theirDeviceIdentityKey Curve25519 identity key of the sender\n * @param {object} message message object, with 'type' and 'body' fields\n *\n * @return {string} payload, if decrypted successfully.\n */\nOlmDecryption.prototype._decryptMessage = async function(\n theirDeviceIdentityKey, message,\n) {\n const sessionIds = await this._olmDevice.getSessionIdsForDevice(\n theirDeviceIdentityKey,\n );\n\n // try each session in turn.\n const decryptionErrors = {};\n for (let i = 0; i < sessionIds.length; i++) {\n const sessionId = sessionIds[i];\n try {\n const payload = await this._olmDevice.decryptMessage(\n theirDeviceIdentityKey, sessionId, message.type, message.body,\n );\n console.log(\n \"Decrypted Olm message from \" + theirDeviceIdentityKey +\n \" with session \" + sessionId,\n );\n return payload;\n } catch (e) {\n const foundSession = await this._olmDevice.matchesSession(\n theirDeviceIdentityKey, sessionId, message.type, message.body,\n );\n\n if (foundSession) {\n // decryption failed, but it was a prekey message matching this\n // session, so it should have worked.\n throw new Error(\n \"Error decrypting prekey message with existing session id \" +\n sessionId + \": \" + e.message,\n );\n }\n\n // otherwise it's probably a message for another session; carry on, but\n // keep a record of the error\n decryptionErrors[sessionId] = e.message;\n }\n }\n\n if (message.type !== 0) {\n // not a prekey message, so it should have matched an existing session, but it\n // didn't work.\n\n if (sessionIds.length === 0) {\n throw new Error(\"No existing sessions\");\n }\n\n throw new Error(\n \"Error decrypting non-prekey message with existing sessions: \" +\n JSON.stringify(decryptionErrors),\n );\n }\n\n // prekey message which doesn't match any existing sessions: make a new\n // session.\n\n let res;\n try {\n res = await this._olmDevice.createInboundSession(\n theirDeviceIdentityKey, message.type, message.body,\n );\n } catch (e) {\n decryptionErrors[\"(new)\"] = e.message;\n throw new Error(\n \"Error decrypting prekey message: \" +\n JSON.stringify(decryptionErrors),\n );\n }\n\n console.log(\n \"created new inbound Olm session ID \" +\n res.session_id + \" with \" + theirDeviceIdentityKey,\n );\n return res.payload;\n};\n\n\nbase.registerAlgorithm(olmlib.OLM_ALGORITHM, OlmEncryption, OlmDecryption);\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n\n/**\n * @module crypto/deviceinfo\n */\n\n/**\n * Information about a user's device\n *\n * @constructor\n * @alias module:crypto/deviceinfo\n *\n * @property {string} deviceId the ID of this device\n *\n * @property {string[]} algorithms list of algorithms supported by this device\n *\n * @property {Object.} keys a map from\n * <key type>:<id> -> <base64-encoded key>>\n *\n * @property {module:crypto/deviceinfo.DeviceVerification} verified\n * whether the device has been verified/blocked by the user\n *\n * @property {boolean} known\n * whether the user knows of this device's existence (useful when warning\n * the user that a user has added new devices)\n *\n * @property {Object} unsigned additional data from the homeserver\n *\n * @param {string} deviceId id of the device\n */\nfunction DeviceInfo(deviceId) {\n // you can't change the deviceId\n Object.defineProperty(this, 'deviceId', {\n enumerable: true,\n value: deviceId,\n });\n\n this.algorithms = [];\n this.keys = {};\n this.verified = DeviceVerification.UNVERIFIED;\n this.known = false;\n this.unsigned = {};\n}\n\n/**\n * rehydrate a DeviceInfo from the session store\n *\n * @param {object} obj raw object from session store\n * @param {string} deviceId id of the device\n *\n * @return {module:crypto~DeviceInfo} new DeviceInfo\n */\nDeviceInfo.fromStorage = function(obj, deviceId) {\n const res = new DeviceInfo(deviceId);\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n res[prop] = obj[prop];\n }\n }\n return res;\n};\n\n/**\n * Prepare a DeviceInfo for JSON serialisation in the session store\n *\n * @return {object} deviceinfo with non-serialised members removed\n */\nDeviceInfo.prototype.toStorage = function() {\n return {\n algorithms: this.algorithms,\n keys: this.keys,\n verified: this.verified,\n known: this.known,\n unsigned: this.unsigned,\n };\n};\n\n/**\n * Get the fingerprint for this device (ie, the Ed25519 key)\n *\n * @return {string} base64-encoded fingerprint of this device\n */\nDeviceInfo.prototype.getFingerprint = function() {\n return this.keys[\"ed25519:\" + this.deviceId];\n};\n\n/**\n * Get the identity key for this device (ie, the Curve25519 key)\n *\n * @return {string} base64-encoded identity key of this device\n */\nDeviceInfo.prototype.getIdentityKey = function() {\n return this.keys[\"curve25519:\" + this.deviceId];\n};\n\n/**\n * Get the configured display name for this device, if any\n *\n * @return {string?} displayname\n */\nDeviceInfo.prototype.getDisplayName = function() {\n return this.unsigned.device_display_name || null;\n};\n\n/**\n * Returns true if this device is blocked\n *\n * @return {Boolean} true if blocked\n */\nDeviceInfo.prototype.isBlocked = function() {\n return this.verified == DeviceVerification.BLOCKED;\n};\n\n/**\n * Returns true if this device is verified\n *\n * @return {Boolean} true if verified\n */\nDeviceInfo.prototype.isVerified = function() {\n return this.verified == DeviceVerification.VERIFIED;\n};\n\n/**\n * Returns true if this device is unverified\n *\n * @return {Boolean} true if unverified\n */\nDeviceInfo.prototype.isUnverified = function() {\n return this.verified == DeviceVerification.UNVERIFIED;\n};\n\n/**\n * Returns true if the user knows about this device's existence\n *\n * @return {Boolean} true if known\n */\nDeviceInfo.prototype.isKnown = function() {\n return this.known == true;\n};\n\n/**\n * @enum\n */\nDeviceInfo.DeviceVerification = {\n VERIFIED: 1,\n UNVERIFIED: 0,\n BLOCKED: -1,\n};\n\nconst DeviceVerification = DeviceInfo.DeviceVerification;\n\n/** */\nmodule.exports = DeviceInfo;\n","/*\nCopyright 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * @module crypto\n */\n\nconst anotherjson = require('another-json');\nimport Promise from 'bluebird';\nimport {EventEmitter} from 'events';\n\nconst utils = require(\"../utils\");\nconst OlmDevice = require(\"./OlmDevice\");\nconst olmlib = require(\"./olmlib\");\nconst algorithms = require(\"./algorithms\");\nconst DeviceInfo = require(\"./deviceinfo\");\nconst DeviceVerification = DeviceInfo.DeviceVerification;\nconst DeviceList = require('./DeviceList').default;\n\nimport OutgoingRoomKeyRequestManager from './OutgoingRoomKeyRequestManager';\n\n/**\n * Cryptography bits\n *\n * This module is internal to the js-sdk; the public API is via MatrixClient.\n *\n * @constructor\n * @alias module:crypto\n *\n * @internal\n *\n * @param {module:base-apis~MatrixBaseApis} baseApis base matrix api interface\n *\n * @param {module:store/session/webstorage~WebStorageSessionStore} sessionStore\n * Store to be used for end-to-end crypto session data\n *\n * @param {string} userId The user ID for the local user\n *\n * @param {string} deviceId The identifier for this device.\n *\n * @param {Object} clientStore the MatrixClient data store.\n *\n * @param {module:crypto/store/base~CryptoStore} cryptoStore\n * storage for the crypto layer.\n */\nfunction Crypto(baseApis, sessionStore, userId, deviceId,\n clientStore, cryptoStore) {\n this._baseApis = baseApis;\n this._sessionStore = sessionStore;\n this._userId = userId;\n this._deviceId = deviceId;\n this._clientStore = clientStore;\n this._cryptoStore = cryptoStore;\n\n this._olmDevice = new OlmDevice(sessionStore);\n this._deviceList = new DeviceList(baseApis, sessionStore, this._olmDevice);\n\n // the last time we did a check for the number of one-time-keys on the\n // server.\n this._lastOneTimeKeyCheck = null;\n this._oneTimeKeyCheckInProgress = false;\n\n // EncryptionAlgorithm instance for each room\n this._roomEncryptors = {};\n\n // map from algorithm to DecryptionAlgorithm instance, for each room\n this._roomDecryptors = {};\n\n this._supportedAlgorithms = utils.keys(\n algorithms.DECRYPTION_CLASSES,\n );\n\n this._deviceKeys = {};\n\n this._globalBlacklistUnverifiedDevices = false;\n\n this._outgoingRoomKeyRequestManager = new OutgoingRoomKeyRequestManager(\n baseApis, this._deviceId, this._cryptoStore,\n );\n\n // list of IncomingRoomKeyRequests/IncomingRoomKeyRequestCancellations\n // we received in the current sync.\n this._receivedRoomKeyRequests = [];\n this._receivedRoomKeyRequestCancellations = [];\n // true if we are currently processing received room key requests\n this._processingRoomKeyRequests = false;\n}\nutils.inherits(Crypto, EventEmitter);\n\n/**\n * Initialise the crypto module so that it is ready for use\n *\n * Returns a promise which resolves once the crypto module is ready for use.\n */\nCrypto.prototype.init = async function() {\n await this._olmDevice.init();\n\n // build our device keys: these will later be uploaded\n this._deviceKeys[\"ed25519:\" + this._deviceId] =\n this._olmDevice.deviceEd25519Key;\n this._deviceKeys[\"curve25519:\" + this._deviceId] =\n this._olmDevice.deviceCurve25519Key;\n\n let myDevices = this._sessionStore.getEndToEndDevicesForUser(\n this._userId,\n );\n\n if (!myDevices) {\n myDevices = {};\n }\n\n if (!myDevices[this._deviceId]) {\n // add our own deviceinfo to the sessionstore\n const deviceInfo = {\n keys: this._deviceKeys,\n algorithms: this._supportedAlgorithms,\n verified: DeviceVerification.VERIFIED,\n known: true,\n };\n\n myDevices[this._deviceId] = deviceInfo;\n this._sessionStore.storeEndToEndDevicesForUser(\n this._userId, myDevices,\n );\n }\n};\n\n/**\n * Tell the crypto module to register for MatrixClient events which it needs to\n * listen for\n *\n * @param {external:EventEmitter} eventEmitter event source where we can register\n * for event notifications\n */\nCrypto.prototype.registerEventHandlers = function(eventEmitter) {\n const crypto = this;\n\n eventEmitter.on(\"RoomMember.membership\", function(event, member, oldMembership) {\n try {\n crypto._onRoomMembership(event, member, oldMembership);\n } catch (e) {\n console.error(\"Error handling membership change:\", e);\n }\n });\n\n eventEmitter.on(\"toDeviceEvent\", function(event) {\n crypto._onToDeviceEvent(event);\n });\n};\n\n\n/** Start background processes related to crypto */\nCrypto.prototype.start = function() {\n this._outgoingRoomKeyRequestManager.start();\n};\n\n/** Stop background processes related to crypto */\nCrypto.prototype.stop = function() {\n this._outgoingRoomKeyRequestManager.stop();\n};\n\n/**\n * @return {string} The version of Olm.\n */\nCrypto.getOlmVersion = function() {\n return OlmDevice.getOlmVersion();\n};\n\n/**\n * Get the Ed25519 key for this device\n *\n * @return {string} base64-encoded ed25519 key.\n */\nCrypto.prototype.getDeviceEd25519Key = function() {\n return this._olmDevice.deviceEd25519Key;\n};\n\n/**\n * Set the global override for whether the client should ever send encrypted\n * messages to unverified devices. If false, it can still be overridden\n * per-room. If true, it overrides the per-room settings.\n *\n * @param {boolean} value whether to unilaterally blacklist all\n * unverified devices\n */\nCrypto.prototype.setGlobalBlacklistUnverifiedDevices = function(value) {\n this._globalBlacklistUnverifiedDevices = value;\n};\n\n/**\n * @return {boolean} whether to unilaterally blacklist all unverified devices\n */\nCrypto.prototype.getGlobalBlacklistUnverifiedDevices = function() {\n return this._globalBlacklistUnverifiedDevices;\n};\n\n/**\n * Upload the device keys to the homeserver.\n * @return {object} A promise that will resolve when the keys are uploaded.\n */\nCrypto.prototype.uploadDeviceKeys = function() {\n const crypto = this;\n const userId = crypto._userId;\n const deviceId = crypto._deviceId;\n\n const deviceKeys = {\n algorithms: crypto._supportedAlgorithms,\n device_id: deviceId,\n keys: crypto._deviceKeys,\n user_id: userId,\n };\n\n return crypto._signObject(deviceKeys).then(() => {\n crypto._baseApis.uploadKeysRequest({\n device_keys: deviceKeys,\n }, {\n // for now, we set the device id explicitly, as we may not be using the\n // same one as used in login.\n device_id: deviceId,\n });\n });\n};\n\n/**\n * Stores the current one_time_key count which will be handled later (in a call of\n * onSyncCompleted). The count is e.g. coming from a /sync response.\n *\n * @param {Number} currentCount The current count of one_time_keys to be stored\n */\nCrypto.prototype.updateOneTimeKeyCount = function(currentCount) {\n if (isFinite(currentCount)) {\n this._oneTimeKeyCount = currentCount;\n } else {\n throw new TypeError(\"Parameter for updateOneTimeKeyCount has to be a number\");\n }\n};\n\n// check if it's time to upload one-time keys, and do so if so.\nfunction _maybeUploadOneTimeKeys(crypto) {\n // frequency with which to check & upload one-time keys\n const uploadPeriod = 1000 * 60; // one minute\n\n // max number of keys to upload at once\n // Creating keys can be an expensive operation so we limit the\n // number we generate in one go to avoid blocking the application\n // for too long.\n const maxKeysPerCycle = 5;\n\n if (crypto._oneTimeKeyCheckInProgress) {\n return;\n }\n\n const now = Date.now();\n if (crypto._lastOneTimeKeyCheck !== null &&\n now - crypto._lastOneTimeKeyCheck < uploadPeriod\n ) {\n // we've done a key upload recently.\n return;\n }\n\n crypto._lastOneTimeKeyCheck = now;\n\n // We need to keep a pool of one time public keys on the server so that\n // other devices can start conversations with us. But we can only store\n // a finite number of private keys in the olm Account object.\n // To complicate things further then can be a delay between a device\n // claiming a public one time key from the server and it sending us a\n // message. We need to keep the corresponding private key locally until\n // we receive the message.\n // But that message might never arrive leaving us stuck with duff\n // private keys clogging up our local storage.\n // So we need some kind of enginering compromise to balance all of\n // these factors.\n\n // Check how many keys we can store in the Account object.\n const maxOneTimeKeys = crypto._olmDevice.maxNumberOfOneTimeKeys();\n // Try to keep at most half that number on the server. This leaves the\n // rest of the slots free to hold keys that have been claimed from the\n // server but we haven't recevied a message for.\n // If we run out of slots when generating new keys then olm will\n // discard the oldest private keys first. This will eventually clean\n // out stale private keys that won't receive a message.\n const keyLimit = Math.floor(maxOneTimeKeys / 2);\n\n function uploadLoop(keyCount) {\n if (keyLimit <= keyCount) {\n // If we don't need to generate any more keys then we are done.\n return Promise.resolve();\n }\n\n const keysThisLoop = Math.min(keyLimit - keyCount, maxKeysPerCycle);\n\n // Ask olm to generate new one time keys, then upload them to synapse.\n return crypto._olmDevice.generateOneTimeKeys(keysThisLoop).then(() => {\n return _uploadOneTimeKeys(crypto);\n }).then((res) => {\n if (res.one_time_key_counts && res.one_time_key_counts.signed_curve25519) {\n // if the response contains a more up to date value use this\n // for the next loop\n return uploadLoop(res.one_time_key_counts.signed_curve25519);\n } else {\n throw new Error(\"response for uploading keys does not contain \"\n + \"one_time_key_counts.signed_curve25519\");\n }\n });\n }\n\n crypto._oneTimeKeyCheckInProgress = true;\n Promise.resolve().then(() => {\n if (crypto._oneTimeKeyCount !== undefined) {\n // We already have the current one_time_key count from a /sync response.\n // Use this value instead of asking the server for the current key count.\n return Promise.resolve(crypto._oneTimeKeyCount);\n }\n // ask the server how many keys we have\n return crypto._baseApis.uploadKeysRequest({}, {\n device_id: crypto._deviceId,\n }).then((res) => {\n return res.one_time_key_counts.signed_curve25519 || 0;\n });\n }).then((keyCount) => {\n // Start the uploadLoop with the current keyCount. The function checks if\n // we need to upload new keys or not.\n // If there are too many keys on the server then we don't need to\n // create any more keys.\n return uploadLoop(keyCount);\n }).catch((e) => {\n console.error(\"Error uploading one-time keys\", e.stack || e);\n }).finally(() => {\n // reset _oneTimeKeyCount to prevent start uploading based on old data.\n // it will be set again on the next /sync-response\n crypto._oneTimeKeyCount = undefined;\n crypto._oneTimeKeyCheckInProgress = false;\n }).done();\n}\n\n// returns a promise which resolves to the response\nasync function _uploadOneTimeKeys(crypto) {\n const oneTimeKeys = await crypto._olmDevice.getOneTimeKeys();\n const oneTimeJson = {};\n\n const promises = [];\n\n for (const keyId in oneTimeKeys.curve25519) {\n if (oneTimeKeys.curve25519.hasOwnProperty(keyId)) {\n const k = {\n key: oneTimeKeys.curve25519[keyId],\n };\n oneTimeJson[\"signed_curve25519:\" + keyId] = k;\n promises.push(crypto._signObject(k));\n }\n }\n\n await Promise.all(promises);\n\n const res = await crypto._baseApis.uploadKeysRequest({\n one_time_keys: oneTimeJson,\n }, {\n // for now, we set the device id explicitly, as we may not be using the\n // same one as used in login.\n device_id: crypto._deviceId,\n });\n\n await crypto._olmDevice.markKeysAsPublished();\n return res;\n}\n\n/**\n * Download the keys for a list of users and stores the keys in the session\n * store.\n * @param {Array} userIds The users to fetch.\n * @param {bool} forceDownload Always download the keys even if cached.\n *\n * @return {Promise} A promise which resolves to a map userId->deviceId->{@link\n * module:crypto/deviceinfo|DeviceInfo}.\n */\nCrypto.prototype.downloadKeys = function(userIds, forceDownload) {\n return this._deviceList.downloadKeys(userIds, forceDownload);\n};\n\n/**\n * Get the stored device keys for a user id\n *\n * @param {string} userId the user to list keys for.\n *\n * @return {module:crypto/deviceinfo[]|null} list of devices, or null if we haven't\n * managed to get a list of devices for this user yet.\n */\nCrypto.prototype.getStoredDevicesForUser = function(userId) {\n return this._deviceList.getStoredDevicesForUser(userId);\n};\n\n/**\n * Get the stored keys for a single device\n *\n * @param {string} userId\n * @param {string} deviceId\n *\n * @return {module:crypto/deviceinfo?} device, or undefined\n * if we don't know about this device\n */\nCrypto.prototype.getStoredDevice = function(userId, deviceId) {\n return this._deviceList.getStoredDevice(userId, deviceId);\n};\n\n/**\n * Update the blocked/verified state of the given device\n *\n * @param {string} userId owner of the device\n * @param {string} deviceId unique identifier for the device\n *\n * @param {?boolean} verified whether to mark the device as verified. Null to\n * leave unchanged.\n *\n * @param {?boolean} blocked whether to mark the device as blocked. Null to\n * leave unchanged.\n *\n * @param {?boolean} known whether to mark that the user has been made aware of\n * the existence of this device. Null to leave unchanged\n *\n * @return {Promise} updated DeviceInfo\n */\nCrypto.prototype.setDeviceVerification = async function(\n userId, deviceId, verified, blocked, known,\n) {\n const devices = this._sessionStore.getEndToEndDevicesForUser(userId);\n if (!devices || !devices[deviceId]) {\n throw new Error(\"Unknown device \" + userId + \":\" + deviceId);\n }\n\n const dev = devices[deviceId];\n let verificationStatus = dev.verified;\n\n if (verified) {\n verificationStatus = DeviceVerification.VERIFIED;\n } else if (verified !== null && verificationStatus == DeviceVerification.VERIFIED) {\n verificationStatus = DeviceVerification.UNVERIFIED;\n }\n\n if (blocked) {\n verificationStatus = DeviceVerification.BLOCKED;\n } else if (blocked !== null && verificationStatus == DeviceVerification.BLOCKED) {\n verificationStatus = DeviceVerification.UNVERIFIED;\n }\n\n let knownStatus = dev.known;\n if (known !== null && known !== undefined) {\n knownStatus = known;\n }\n\n if (dev.verified !== verificationStatus || dev.known !== knownStatus) {\n dev.verified = verificationStatus;\n dev.known = knownStatus;\n this._sessionStore.storeEndToEndDevicesForUser(userId, devices);\n }\n return DeviceInfo.fromStorage(dev, deviceId);\n};\n\n\n/**\n * Get information on the active olm sessions with a user\n *

\n * Returns a map from device id to an object with keys 'deviceIdKey' (the\n * device's curve25519 identity key) and 'sessions' (an array of objects in the\n * same format as that returned by\n * {@link module:crypto/OlmDevice#getSessionInfoForDevice}).\n *

\n * This method is provided for debugging purposes.\n *\n * @param {string} userId id of user to inspect\n *\n * @return {Promise>}\n */\nCrypto.prototype.getOlmSessionsForUser = async function(userId) {\n const devices = this.getStoredDevicesForUser(userId) || [];\n const result = {};\n for (let j = 0; j < devices.length; ++j) {\n const device = devices[j];\n const deviceKey = device.getIdentityKey();\n const sessions = await this._olmDevice.getSessionInfoForDevice(deviceKey);\n\n result[device.deviceId] = {\n deviceIdKey: deviceKey,\n sessions: sessions,\n };\n }\n return result;\n};\n\n\n/**\n * Get the device which sent an event\n *\n * @param {module:models/event.MatrixEvent} event event to be checked\n *\n * @return {module:crypto/deviceinfo?}\n */\nCrypto.prototype.getEventSenderDeviceInfo = function(event) {\n const senderKey = event.getSenderKey();\n const algorithm = event.getWireContent().algorithm;\n\n if (!senderKey || !algorithm) {\n return null;\n }\n\n const forwardingChain = event.getForwardingCurve25519KeyChain();\n if (forwardingChain.length > 0) {\n // we got this event from somewhere else\n // TODO: check if we can trust the forwarders.\n return null;\n }\n\n // senderKey is the Curve25519 identity key of the device which the event\n // was sent from. In the case of Megolm, it's actually the Curve25519\n // identity key of the device which set up the Megolm session.\n\n const device = this._deviceList.getDeviceByIdentityKey(\n event.getSender(), algorithm, senderKey,\n );\n\n if (device === null) {\n // we haven't downloaded the details of this device yet.\n return null;\n }\n\n // so far so good, but now we need to check that the sender of this event\n // hadn't advertised someone else's Curve25519 key as their own. We do that\n // by checking the Ed25519 claimed by the event (or, in the case of megolm,\n // the event which set up the megolm session), to check that it matches the\n // fingerprint of the purported sending device.\n //\n // (see https://github.com/vector-im/vector-web/issues/2215)\n\n const claimedKey = event.getClaimedEd25519Key();\n if (!claimedKey) {\n console.warn(\"Event \" + event.getId() + \" claims no ed25519 key: \" +\n \"cannot verify sending device\");\n return null;\n }\n\n if (claimedKey !== device.getFingerprint()) {\n console.warn(\n \"Event \" + event.getId() + \" claims ed25519 key \" + claimedKey +\n \"but sender device has key \" + device.getFingerprint());\n return null;\n }\n\n return device;\n};\n\n\n/**\n * Configure a room to use encryption (ie, save a flag in the sessionstore).\n *\n * @param {string} roomId The room ID to enable encryption in.\n *\n * @param {object} config The encryption config for the room.\n *\n * @param {boolean=} inhibitDeviceQuery true to suppress device list query for\n * users in the room (for now)\n */\nCrypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDeviceQuery) {\n // if we already have encryption in this room, we should ignore this event\n // (for now at least. maybe we should alert the user somehow?)\n const existingConfig = this._sessionStore.getEndToEndRoom(roomId);\n if (existingConfig) {\n if (JSON.stringify(existingConfig) != JSON.stringify(config)) {\n console.error(\"Ignoring m.room.encryption event which requests \" +\n \"a change of config in \" + roomId);\n return;\n }\n }\n\n const AlgClass = algorithms.ENCRYPTION_CLASSES[config.algorithm];\n if (!AlgClass) {\n throw new Error(\"Unable to encrypt with \" + config.algorithm);\n }\n\n this._sessionStore.storeEndToEndRoom(roomId, config);\n\n const alg = new AlgClass({\n userId: this._userId,\n deviceId: this._deviceId,\n crypto: this,\n olmDevice: this._olmDevice,\n baseApis: this._baseApis,\n roomId: roomId,\n config: config,\n });\n this._roomEncryptors[roomId] = alg;\n\n // make sure we are tracking the device lists for all users in this room.\n console.log(\"Enabling encryption in \" + roomId + \"; \" +\n \"starting to track device lists for all users therein\");\n const room = this._clientStore.getRoom(roomId);\n if (!room) {\n throw new Error(`Unable to enable encryption in unknown room ${roomId}`);\n }\n\n const members = room.getJoinedMembers();\n members.forEach((m) => {\n this._deviceList.startTrackingDeviceList(m.userId);\n });\n if (!inhibitDeviceQuery) {\n this._deviceList.refreshOutdatedDeviceLists();\n }\n};\n\n\n/**\n * @typedef {Object} module:crypto~OlmSessionResult\n * @property {module:crypto/deviceinfo} device device info\n * @property {string?} sessionId base64 olm session id; null if no session\n * could be established\n */\n\n/**\n * Try to make sure we have established olm sessions for all known devices for\n * the given users.\n *\n * @param {string[]} users list of user ids\n *\n * @return {module:client.Promise} resolves once the sessions are complete, to\n * an Object mapping from userId to deviceId to\n * {@link module:crypto~OlmSessionResult}\n */\nCrypto.prototype.ensureOlmSessionsForUsers = function(users) {\n const devicesByUser = {};\n\n for (let i = 0; i < users.length; ++i) {\n const userId = users[i];\n devicesByUser[userId] = [];\n\n const devices = this.getStoredDevicesForUser(userId) || [];\n for (let j = 0; j < devices.length; ++j) {\n const deviceInfo = devices[j];\n\n const key = deviceInfo.getIdentityKey();\n if (key == this._olmDevice.deviceCurve25519Key) {\n // don't bother setting up session to ourself\n continue;\n }\n if (deviceInfo.verified == DeviceVerification.BLOCKED) {\n // don't bother setting up sessions with blocked users\n continue;\n }\n\n devicesByUser[userId].push(deviceInfo);\n }\n }\n\n return olmlib.ensureOlmSessionsForDevices(\n this._olmDevice, this._baseApis, devicesByUser,\n );\n};\n\n/**\n * Whether encryption is enabled for a room.\n * @param {string} roomId the room id to query.\n * @return {bool} whether encryption is enabled.\n */\nCrypto.prototype.isRoomEncrypted = function(roomId) {\n return Boolean(this._roomEncryptors[roomId]);\n};\n\n\n/**\n * Get a list containing all of the room keys\n *\n * @return {module:client.Promise} a promise which resolves to a list of\n * session export objects\n */\nCrypto.prototype.exportRoomKeys = function() {\n return Promise.map(\n this._sessionStore.getAllEndToEndInboundGroupSessionKeys(),\n (s) => {\n return this._olmDevice.exportInboundGroupSession(\n s.senderKey, s.sessionId,\n ).then((sess) => {\n sess.algorithm = olmlib.MEGOLM_ALGORITHM;\n return sess;\n });\n },\n );\n};\n\n/**\n * Import a list of room keys previously exported by exportRoomKeys\n *\n * @param {Object[]} keys a list of session export objects\n * @return {module:client.Promise} a promise which resolves once the keys have been imported\n */\nCrypto.prototype.importRoomKeys = function(keys) {\n return Promise.map(\n keys, (key) => {\n if (!key.room_id || !key.algorithm) {\n console.warn(\"ignoring room key entry with missing fields\", key);\n return null;\n }\n\n const alg = this._getRoomDecryptor(key.room_id, key.algorithm);\n return alg.importRoomKey(key);\n },\n );\n};\n\n/**\n * Encrypt an event according to the configuration of the room.\n *\n * @param {module:models/event.MatrixEvent} event event to be sent\n *\n * @param {module:models/room} room destination room.\n *\n * @return {module:client.Promise?} Promise which resolves when the event has been\n * encrypted, or null if nothing was needed\n */\nCrypto.prototype.encryptEvent = function(event, room) {\n if (!room) {\n throw new Error(\"Cannot send encrypted messages in unknown rooms\");\n }\n\n const roomId = event.getRoomId();\n\n const alg = this._roomEncryptors[roomId];\n if (!alg) {\n // MatrixClient has already checked that this room should be encrypted,\n // so this is an unexpected situation.\n throw new Error(\n \"Room was previously configured to use encryption, but is \" +\n \"no longer. Perhaps the homeserver is hiding the \" +\n \"configuration event.\",\n );\n }\n\n return alg.encryptMessage(\n room, event.getType(), event.getContent(),\n ).then((encryptedContent) => {\n event.makeEncrypted(\n \"m.room.encrypted\",\n encryptedContent,\n this._olmDevice.deviceCurve25519Key,\n this._olmDevice.deviceEd25519Key,\n );\n });\n};\n\n/**\n * Decrypt a received event\n *\n * @param {MatrixEvent} event\n *\n * @return {Promise} resolves once we have\n * finished decrypting. Rejects with an `algorithms.DecryptionError` if there\n * is a problem decrypting the event.\n */\nCrypto.prototype.decryptEvent = function(event) {\n if (event.isRedacted()) {\n return Promise.resolve({\n clearEvent: {\n room_id: event.getRoomId(),\n type: \"m.room.message\",\n content: {},\n },\n });\n }\n const content = event.getWireContent();\n const alg = this._getRoomDecryptor(event.getRoomId(), content.algorithm);\n return alg.decryptEvent(event);\n};\n\n/**\n * Handle the notification from /sync or /keys/changes that device lists have\n * been changed.\n *\n * @param {Object} deviceLists device_lists field from /sync, or response from\n * /keys/changes\n */\nCrypto.prototype.handleDeviceListChanges = async function(deviceLists) {\n if (deviceLists.changed && Array.isArray(deviceLists.changed)) {\n deviceLists.changed.forEach((u) => {\n this._deviceList.invalidateUserDeviceList(u);\n });\n }\n\n if (deviceLists.left && Array.isArray(deviceLists.left)) {\n deviceLists.left.forEach((u) => {\n this._deviceList.stopTrackingDeviceList(u);\n });\n }\n\n // don't flush the outdated device list yet - we do it once we finish\n // processing the sync.\n};\n\n/**\n * Send a request for some room keys, if we have not already done so\n *\n * @param {module:crypto~RoomKeyRequestBody} requestBody\n * @param {Array<{userId: string, deviceId: string}>} recipients\n */\nCrypto.prototype.requestRoomKey = function(requestBody, recipients) {\n this._outgoingRoomKeyRequestManager.sendRoomKeyRequest(\n requestBody, recipients,\n ).catch((e) => {\n // this normally means we couldn't talk to the store\n console.error(\n 'Error requesting key for event', e,\n );\n }).done();\n};\n\n/**\n * Cancel any earlier room key request\n *\n * @param {module:crypto~RoomKeyRequestBody} requestBody\n * parameters to match for cancellation\n */\nCrypto.prototype.cancelRoomKeyRequest = function(requestBody) {\n this._outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody)\n .catch((e) => {\n console.warn(\"Error clearing pending room key requests\", e);\n }).done();\n};\n\n/**\n * handle an m.room.encryption event\n *\n * @param {module:models/event.MatrixEvent} event encryption event\n */\nCrypto.prototype.onCryptoEvent = async function(event) {\n const roomId = event.getRoomId();\n const content = event.getContent();\n\n try {\n // inhibit the device list refresh for now - it will happen once we've\n // finished processing the sync, in onSyncCompleted.\n await this.setRoomEncryption(roomId, content, true);\n } catch (e) {\n console.error(\"Error configuring encryption in room \" + roomId +\n \":\", e);\n }\n};\n\n/**\n * handle the completion of a /sync\n *\n * This is called after the processing of each successful /sync response.\n * It is an opportunity to do a batch process on the information received.\n *\n * @param {Object} syncData the data from the 'MatrixClient.sync' event\n */\nCrypto.prototype.onSyncCompleted = async function(syncData) {\n const nextSyncToken = syncData.nextSyncToken;\n\n if (!syncData.oldSyncToken) {\n console.log(\"Completed initial sync\");\n\n // if we have a deviceSyncToken, we can tell the deviceList to\n // invalidate devices which have changed since then.\n const oldSyncToken = this._sessionStore.getEndToEndDeviceSyncToken();\n if (oldSyncToken !== null) {\n try {\n await this._invalidateDeviceListsSince(\n oldSyncToken, nextSyncToken,\n );\n } catch (e) {\n // if that failed, we fall back to invalidating everyone.\n console.warn(\"Error fetching changed device list\", e);\n this._deviceList.invalidateAllDeviceLists();\n }\n } else {\n // otherwise, we have to invalidate all devices for all users we\n // are tracking.\n console.log(\"Completed first initialsync; invalidating all \" +\n \"device list caches\");\n this._deviceList.invalidateAllDeviceLists();\n }\n }\n\n // we can now store our sync token so that we can get an update on\n // restart rather than having to invalidate everyone.\n //\n // (we don't really need to do this on every sync - we could just\n // do it periodically)\n this._sessionStore.storeEndToEndDeviceSyncToken(nextSyncToken);\n\n // catch up on any new devices we got told about during the sync.\n this._deviceList.lastKnownSyncToken = nextSyncToken;\n this._deviceList.refreshOutdatedDeviceLists();\n\n // we don't start uploading one-time keys until we've caught up with\n // to-device messages, to help us avoid throwing away one-time-keys that we\n // are about to receive messages for\n // (https://github.com/vector-im/riot-web/issues/2782).\n if (!syncData.catchingUp) {\n _maybeUploadOneTimeKeys(this);\n this._processReceivedRoomKeyRequests();\n }\n};\n\n/**\n * Ask the server which users have new devices since a given token,\n * and invalidate them\n *\n * @param {String} oldSyncToken\n * @param {String} lastKnownSyncToken\n *\n * Returns a Promise which resolves once the query is complete. Rejects if the\n * keyChange query fails.\n */\nCrypto.prototype._invalidateDeviceListsSince = async function(\n oldSyncToken, lastKnownSyncToken,\n) {\n const r = await this._baseApis.getKeyChanges(\n oldSyncToken, lastKnownSyncToken,\n );\n\n console.log(\"got key changes since\", oldSyncToken, \":\", r);\n\n await this.handleDeviceListChanges(r);\n};\n\n/**\n * Get a list of the e2e-enabled rooms we are members of\n *\n * @returns {module:models.Room[]}\n */\nCrypto.prototype._getE2eRooms = function() {\n return this._clientStore.getRooms().filter((room) => {\n // check for rooms with encryption enabled\n const alg = this._roomEncryptors[room.roomId];\n if (!alg) {\n return false;\n }\n\n // ignore any rooms which we have left\n const me = room.getMember(this._userId);\n if (!me || (\n me.membership !== \"join\" && me.membership !== \"invite\"\n )) {\n return false;\n }\n\n return true;\n });\n};\n\n\nCrypto.prototype._onToDeviceEvent = function(event) {\n try {\n if (event.getType() == \"m.room_key\"\n || event.getType() == \"m.forwarded_room_key\") {\n this._onRoomKeyEvent(event);\n } else if (event.getType() == \"m.room_key_request\") {\n this._onRoomKeyRequestEvent(event);\n } else if (event.isBeingDecrypted()) {\n // once the event has been decrypted, try again\n event.once('Event.decrypted', (ev) => {\n this._onToDeviceEvent(ev);\n });\n }\n } catch (e) {\n console.error(\"Error handling toDeviceEvent:\", e);\n }\n};\n\n/**\n * Handle a key event\n *\n * @private\n * @param {module:models/event.MatrixEvent} event key event\n */\nCrypto.prototype._onRoomKeyEvent = function(event) {\n const content = event.getContent();\n\n if (!content.room_id || !content.algorithm) {\n console.error(\"key event is missing fields\");\n return;\n }\n\n const alg = this._getRoomDecryptor(content.room_id, content.algorithm);\n alg.onRoomKeyEvent(event);\n};\n\n/**\n * Handle a change in the membership state of a member of a room\n *\n * @private\n * @param {module:models/event.MatrixEvent} event event causing the change\n * @param {module:models/room-member} member user whose membership changed\n * @param {string=} oldMembership previous membership\n */\nCrypto.prototype._onRoomMembership = function(event, member, oldMembership) {\n // this event handler is registered on the *client* (as opposed to the room\n // member itself), which means it is only called on changes to the *live*\n // membership state (ie, it is not called when we back-paginate, nor when\n // we load the state in the initialsync).\n //\n // Further, it is automatically registered and called when new members\n // arrive in the room.\n\n const roomId = member.roomId;\n\n const alg = this._roomEncryptors[roomId];\n if (!alg) {\n // not encrypting in this room\n return;\n }\n\n if (member.membership == 'join') {\n console.log('Join event for ' + member.userId + ' in ' + roomId);\n // make sure we are tracking the deviceList for this user\n this._deviceList.startTrackingDeviceList(member.userId);\n }\n\n alg.onRoomMembership(event, member, oldMembership);\n};\n\n\n/**\n * Called when we get an m.room_key_request event.\n *\n * @private\n * @param {module:models/event.MatrixEvent} event key request event\n */\nCrypto.prototype._onRoomKeyRequestEvent = function(event) {\n const content = event.getContent();\n if (content.action === \"request\") {\n // Queue it up for now, because they tend to arrive before the room state\n // events at initial sync, and we want to see if we know anything about the\n // room before passing them on to the app.\n const req = new IncomingRoomKeyRequest(event);\n this._receivedRoomKeyRequests.push(req);\n } else if (content.action === \"request_cancellation\") {\n const req = new IncomingRoomKeyRequestCancellation(event);\n this._receivedRoomKeyRequestCancellations.push(req);\n }\n};\n\n/**\n * Process any m.room_key_request events which were queued up during the\n * current sync.\n *\n * @private\n */\nCrypto.prototype._processReceivedRoomKeyRequests = async function() {\n if (this._processingRoomKeyRequests) {\n // we're still processing last time's requests; keep queuing new ones\n // up for now.\n return;\n }\n this._processingRoomKeyRequests = true;\n\n try {\n // we need to grab and clear the queues in the synchronous bit of this method,\n // so that we don't end up racing with the next /sync.\n const requests = this._receivedRoomKeyRequests;\n this._receivedRoomKeyRequests = [];\n const cancellations = this._receivedRoomKeyRequestCancellations;\n this._receivedRoomKeyRequestCancellations = [];\n\n // Process all of the requests, *then* all of the cancellations.\n //\n // This makes sure that if we get a request and its cancellation in the\n // same /sync result, then we process the request before the\n // cancellation (and end up with a cancelled request), rather than the\n // cancellation before the request (and end up with an outstanding\n // request which should have been cancelled.)\n await Promise.map(\n requests, (req) =>\n this._processReceivedRoomKeyRequest(req),\n );\n await Promise.map(\n cancellations, (cancellation) =>\n this._processReceivedRoomKeyRequestCancellation(cancellation),\n );\n } catch (e) {\n console.error(`Error processing room key requsts: ${e}`);\n } finally {\n this._processingRoomKeyRequests = false;\n }\n};\n\n/**\n * Helper for processReceivedRoomKeyRequests\n *\n * @param {IncomingRoomKeyRequest} req\n */\nCrypto.prototype._processReceivedRoomKeyRequest = async function(req) {\n const userId = req.userId;\n const deviceId = req.deviceId;\n\n const body = req.requestBody;\n const roomId = body.room_id;\n const alg = body.algorithm;\n\n console.log(`m.room_key_request from ${userId}:${deviceId}` +\n ` for ${roomId} / ${body.session_id} (id ${req.requestId})`);\n\n if (userId !== this._userId) {\n // TODO: determine if we sent this device the keys already: in\n // which case we can do so again.\n console.log(\"Ignoring room key request from other user for now\");\n return;\n }\n\n // todo: should we queue up requests we don't yet have keys for,\n // in case they turn up later?\n\n // if we don't have a decryptor for this room/alg, we don't have\n // the keys for the requested events, and can drop the requests.\n if (!this._roomDecryptors[roomId]) {\n console.log(`room key request for unencrypted room ${roomId}`);\n return;\n }\n\n const decryptor = this._roomDecryptors[roomId][alg];\n if (!decryptor) {\n console.log(`room key request for unknown alg ${alg} in room ${roomId}`);\n return;\n }\n\n if (!await decryptor.hasKeysForKeyRequest(req)) {\n console.log(\n `room key request for unknown session ${roomId} / ` +\n body.session_id,\n );\n return;\n }\n\n req.share = () => {\n decryptor.shareKeysWithDevice(req);\n };\n\n // if the device is is verified already, share the keys\n const device = this._deviceList.getStoredDevice(userId, deviceId);\n if (device && device.isVerified()) {\n console.log('device is already verified: sharing keys');\n req.share();\n return;\n }\n\n this.emit(\"crypto.roomKeyRequest\", req);\n};\n\n\n/**\n * Helper for processReceivedRoomKeyRequests\n *\n * @param {IncomingRoomKeyRequestCancellation} cancellation\n */\nCrypto.prototype._processReceivedRoomKeyRequestCancellation = async function(\n cancellation,\n) {\n console.log(\n `m.room_key_request cancellation for ${cancellation.userId}:` +\n `${cancellation.deviceId} (id ${cancellation.requestId})`,\n );\n\n // we should probably only notify the app of cancellations we told it\n // about, but we don't currently have a record of that, so we just pass\n // everything through.\n this.emit(\"crypto.roomKeyRequestCancellation\", cancellation);\n};\n\n/**\n * Get a decryptor for a given room and algorithm.\n *\n * If we already have a decryptor for the given room and algorithm, return\n * it. Otherwise try to instantiate it.\n *\n * @private\n *\n * @param {string?} roomId room id for decryptor. If undefined, a temporary\n * decryptor is instantiated.\n *\n * @param {string} algorithm crypto algorithm\n *\n * @return {module:crypto.algorithms.base.DecryptionAlgorithm}\n *\n * @raises {module:crypto.algorithms.DecryptionError} if the algorithm is\n * unknown\n */\nCrypto.prototype._getRoomDecryptor = function(roomId, algorithm) {\n let decryptors;\n let alg;\n\n roomId = roomId || null;\n if (roomId) {\n decryptors = this._roomDecryptors[roomId];\n if (!decryptors) {\n this._roomDecryptors[roomId] = decryptors = {};\n }\n\n alg = decryptors[algorithm];\n if (alg) {\n return alg;\n }\n }\n\n const AlgClass = algorithms.DECRYPTION_CLASSES[algorithm];\n if (!AlgClass) {\n throw new algorithms.DecryptionError(\n 'Unknown encryption algorithm \"' + algorithm + '\".',\n );\n }\n alg = new AlgClass({\n userId: this._userId,\n crypto: this,\n olmDevice: this._olmDevice,\n baseApis: this._baseApis,\n roomId: roomId,\n });\n\n if (decryptors) {\n decryptors[algorithm] = alg;\n }\n return alg;\n};\n\n\n/**\n * sign the given object with our ed25519 key\n *\n * @param {Object} obj Object to which we will add a 'signatures' property\n */\nCrypto.prototype._signObject = async function(obj) {\n const sigs = {};\n sigs[this._userId] = {};\n sigs[this._userId][\"ed25519:\" + this._deviceId] =\n await this._olmDevice.sign(anotherjson.stringify(obj));\n obj.signatures = sigs;\n};\n\n\n/**\n * The parameters of a room key request. The details of the request may\n * vary with the crypto algorithm, but the management and storage layers for\n * outgoing requests expect it to have 'room_id' and 'session_id' properties.\n *\n * @typedef {Object} RoomKeyRequestBody\n */\n\n/**\n * Represents a received m.room_key_request event\n *\n * @property {string} userId user requesting the key\n * @property {string} deviceId device requesting the key\n * @property {string} requestId unique id for the request\n * @property {module:crypto~RoomKeyRequestBody} requestBody\n * @property {function()} share callback which, when called, will ask\n * the relevant crypto algorithm implementation to share the keys for\n * this request.\n */\nclass IncomingRoomKeyRequest {\n constructor(event) {\n const content = event.getContent();\n\n this.userId = event.getSender();\n this.deviceId = content.requesting_device_id;\n this.requestId = content.request_id;\n this.requestBody = content.body || {};\n this.share = () => {\n throw new Error(\"don't know how to share keys for this request yet\");\n };\n }\n}\n\n/**\n * Represents a received m.room_key_request cancellation\n *\n * @property {string} userId user requesting the cancellation\n * @property {string} deviceId device requesting the cancellation\n * @property {string} requestId unique id for the request to be cancelled\n */\nclass IncomingRoomKeyRequestCancellation {\n constructor(event) {\n const content = event.getContent();\n\n this.userId = event.getSender();\n this.deviceId = content.requesting_device_id;\n this.requestId = content.request_id;\n }\n}\n\n/**\n * The result of a (successful) call to decryptEvent.\n *\n * @typedef {Object} EventDecryptionResult\n *\n * @property {Object} clearEvent The plaintext payload for the event\n * (typically containing type and content fields).\n *\n * @property {?string} senderCurve25519Key Key owned by the sender of this\n * event. See {@link module:models/event.MatrixEvent#getSenderKey}.\n *\n * @property {?string} claimedEd25519Key ed25519 key claimed by the sender of\n * this event. See\n * {@link module:models/event.MatrixEvent#getClaimedEd25519Key}.\n *\n * @property {?Array} forwardingCurve25519KeyChain list of curve25519\n * keys involved in telling us about the senderCurve25519Key and\n * claimedEd25519Key. See\n * {@link module:models/event.MatrixEvent#getForwardingCurve25519KeyChain}.\n */\n\n/**\n * Fires when we receive a room key request\n *\n * @event module:client~MatrixClient#\"crypto.roomKeyRequest\"\n * @param {module:crypto~IncomingRoomKeyRequest} req request details\n */\n\n/**\n * Fires when we receive a room key request cancellation\n *\n * @event module:client~MatrixClient#\"crypto.roomKeyRequestCancellation\"\n * @param {module:crypto~IncomingRoomKeyRequestCancellation} req\n */\n\n/** */\nmodule.exports = Crypto;\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * @module olmlib\n *\n * Utilities common to olm encryption algorithms\n */\n\nimport Promise from 'bluebird';\nconst anotherjson = require('another-json');\n\nconst utils = require(\"../utils\");\n\n/**\n * matrix algorithm tag for olm\n */\nmodule.exports.OLM_ALGORITHM = \"m.olm.v1.curve25519-aes-sha2\";\n\n/**\n * matrix algorithm tag for megolm\n */\nmodule.exports.MEGOLM_ALGORITHM = \"m.megolm.v1.aes-sha2\";\n\n\n/**\n * Encrypt an event payload for an Olm device\n *\n * @param {Object} resultsObject The `ciphertext` property\n * of the m.room.encrypted event to which to add our result\n *\n * @param {string} ourUserId\n * @param {string} ourDeviceId\n * @param {module:crypto/OlmDevice} olmDevice olm.js wrapper\n * @param {string} recipientUserId\n * @param {module:crypto/deviceinfo} recipientDevice\n * @param {object} payloadFields fields to include in the encrypted payload\n *\n * Returns a promise which resolves (to undefined) when the payload\n * has been encrypted into `resultsObject`\n */\nmodule.exports.encryptMessageForDevice = async function(\n resultsObject,\n ourUserId, ourDeviceId, olmDevice, recipientUserId, recipientDevice,\n payloadFields,\n) {\n const deviceKey = recipientDevice.getIdentityKey();\n const sessionId = await olmDevice.getSessionIdForDevice(deviceKey);\n if (sessionId === null) {\n // If we don't have a session for a device then\n // we can't encrypt a message for it.\n return;\n }\n\n console.log(\n \"Using sessionid \" + sessionId + \" for device \" +\n recipientUserId + \":\" + recipientDevice.deviceId,\n );\n\n const payload = {\n sender: ourUserId,\n sender_device: ourDeviceId,\n\n // Include the Ed25519 key so that the recipient knows what\n // device this message came from.\n // We don't need to include the curve25519 key since the\n // recipient will already know this from the olm headers.\n // When combined with the device keys retrieved from the\n // homeserver signed by the ed25519 key this proves that\n // the curve25519 key and the ed25519 key are owned by\n // the same device.\n keys: {\n \"ed25519\": olmDevice.deviceEd25519Key,\n },\n\n // include the recipient device details in the payload,\n // to avoid unknown key attacks, per\n // https://github.com/vector-im/vector-web/issues/2483\n recipient: recipientUserId,\n recipient_keys: {\n \"ed25519\": recipientDevice.getFingerprint(),\n },\n };\n\n // TODO: technically, a bunch of that stuff only needs to be included for\n // pre-key messages: after that, both sides know exactly which devices are\n // involved in the session. If we're looking to reduce data transfer in the\n // future, we could elide them for subsequent messages.\n\n utils.extend(payload, payloadFields);\n\n resultsObject[deviceKey] = await olmDevice.encryptMessage(\n deviceKey, sessionId, JSON.stringify(payload),\n );\n};\n\n/**\n * Try to make sure we have established olm sessions for the given devices.\n *\n * @param {module:crypto/OlmDevice} olmDevice\n *\n * @param {module:base-apis~MatrixBaseApis} baseApis\n *\n * @param {object} devicesByUser\n * map from userid to list of devices\n *\n * @return {module:client.Promise} resolves once the sessions are complete, to\n * an Object mapping from userId to deviceId to\n * {@link module:crypto~OlmSessionResult}\n */\nmodule.exports.ensureOlmSessionsForDevices = async function(\n olmDevice, baseApis, devicesByUser,\n) {\n const devicesWithoutSession = [\n // [userId, deviceId], ...\n ];\n const result = {};\n\n for (const userId in devicesByUser) {\n if (!devicesByUser.hasOwnProperty(userId)) {\n continue;\n }\n result[userId] = {};\n const devices = devicesByUser[userId];\n for (let j = 0; j < devices.length; j++) {\n const deviceInfo = devices[j];\n const deviceId = deviceInfo.deviceId;\n const key = deviceInfo.getIdentityKey();\n const sessionId = await olmDevice.getSessionIdForDevice(key);\n if (sessionId === null) {\n devicesWithoutSession.push([userId, deviceId]);\n }\n result[userId][deviceId] = {\n device: deviceInfo,\n sessionId: sessionId,\n };\n }\n }\n\n if (devicesWithoutSession.length === 0) {\n return result;\n }\n\n // TODO: this has a race condition - if we try to send another message\n // while we are claiming a key, we will end up claiming two and setting up\n // two sessions.\n //\n // That should eventually resolve itself, but it's poor form.\n\n const oneTimeKeyAlgorithm = \"signed_curve25519\";\n const res = await baseApis.claimOneTimeKeys(\n devicesWithoutSession, oneTimeKeyAlgorithm,\n );\n\n const otk_res = res.one_time_keys || {};\n const promises = [];\n for (const userId in devicesByUser) {\n if (!devicesByUser.hasOwnProperty(userId)) {\n continue;\n }\n const userRes = otk_res[userId] || {};\n const devices = devicesByUser[userId];\n for (let j = 0; j < devices.length; j++) {\n const deviceInfo = devices[j];\n const deviceId = deviceInfo.deviceId;\n if (result[userId][deviceId].sessionId) {\n // we already have a result for this device\n continue;\n }\n\n const deviceRes = userRes[deviceId] || {};\n let oneTimeKey = null;\n for (const keyId in deviceRes) {\n if (keyId.indexOf(oneTimeKeyAlgorithm + \":\") === 0) {\n oneTimeKey = deviceRes[keyId];\n }\n }\n\n if (!oneTimeKey) {\n console.warn(\n \"No one-time keys (alg=\" + oneTimeKeyAlgorithm +\n \") for device \" + userId + \":\" + deviceId,\n );\n continue;\n }\n\n promises.push(\n _verifyKeyAndStartSession(\n olmDevice, oneTimeKey, userId, deviceInfo,\n ).then((sid) => {\n result[userId][deviceId].sessionId = sid;\n }),\n );\n }\n }\n\n await Promise.all(promises);\n return result;\n};\n\nasync function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceInfo) {\n const deviceId = deviceInfo.deviceId;\n try {\n await _verifySignature(\n olmDevice, oneTimeKey, userId, deviceId,\n deviceInfo.getFingerprint(),\n );\n } catch (e) {\n console.error(\n \"Unable to verify signature on one-time key for device \" +\n userId + \":\" + deviceId + \":\", e,\n );\n return null;\n }\n\n let sid;\n try {\n sid = await olmDevice.createOutboundSession(\n deviceInfo.getIdentityKey(), oneTimeKey.key,\n );\n } catch (e) {\n // possibly a bad key\n console.error(\"Error starting session with device \" +\n userId + \":\" + deviceId + \": \" + e);\n return null;\n }\n\n console.log(\"Started new sessionid \" + sid +\n \" for device \" + userId + \":\" + deviceId);\n return sid;\n}\n\n\n/**\n * Verify the signature on an object\n *\n * @param {module:crypto/OlmDevice} olmDevice olm wrapper to use for verify op\n *\n * @param {Object} obj object to check signature on. Note that this will be\n * stripped of its 'signatures' and 'unsigned' properties.\n *\n * @param {string} signingUserId ID of the user whose signature should be checked\n *\n * @param {string} signingDeviceId ID of the device whose signature should be checked\n *\n * @param {string} signingKey base64-ed ed25519 public key\n *\n * Returns a promise which resolves (to undefined) if the the signature is good,\n * or rejects with an Error if it is bad.\n */\nconst _verifySignature = module.exports.verifySignature = async function(\n olmDevice, obj, signingUserId, signingDeviceId, signingKey,\n) {\n const signKeyId = \"ed25519:\" + signingDeviceId;\n const signatures = obj.signatures || {};\n const userSigs = signatures[signingUserId] || {};\n const signature = userSigs[signKeyId];\n if (!signature) {\n throw Error(\"No signature\");\n }\n\n // prepare the canonical json: remove unsigned and signatures, and stringify with\n // anotherjson\n delete obj.unsigned;\n delete obj.signatures;\n const json = anotherjson.stringify(obj);\n\n olmDevice.verifySignature(\n signingKey, json, signature,\n );\n};\n","import Promise from 'bluebird';\nimport utils from '../../utils';\n\nexport const VERSION = 1;\n\n/**\n * Implementation of a CryptoStore which is backed by an existing\n * IndexedDB connection. Generally you want IndexedDBCryptoStore\n * which connects to the database and defers to one of these.\n *\n * @implements {module:crypto/store/base~CryptoStore}\n */\nexport class Backend {\n /**\n * @param {IDBDatabase} db\n */\n constructor(db) {\n this._db = db;\n\n // make sure we close the db on `onversionchange` - otherwise\n // attempts to delete the database will block (and subsequent\n // attempts to re-create it will also block).\n db.onversionchange = (ev) => {\n console.log(`versionchange for indexeddb ${this._dbName}: closing`);\n db.close();\n };\n }\n\n /**\n * Look for an existing outgoing room key request, and if none is found,\n * add a new one\n *\n * @param {module:crypto/store/base~OutgoingRoomKeyRequest} request\n *\n * @returns {Promise} resolves to\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the\n * same instance as passed in, or the existing one.\n */\n getOrAddOutgoingRoomKeyRequest(request) {\n const requestBody = request.requestBody;\n\n const deferred = Promise.defer();\n const txn = this._db.transaction(\"outgoingRoomKeyRequests\", \"readwrite\");\n txn.onerror = deferred.reject;\n\n // first see if we already have an entry for this request.\n this._getOutgoingRoomKeyRequest(txn, requestBody, (existing) => {\n if (existing) {\n // this entry matches the request - return it.\n console.log(\n `already have key request outstanding for ` +\n `${requestBody.room_id} / ${requestBody.session_id}: ` +\n `not sending another`,\n );\n deferred.resolve(existing);\n return;\n }\n\n // we got to the end of the list without finding a match\n // - add the new request.\n console.log(\n `enqueueing key request for ${requestBody.room_id} / ` +\n requestBody.session_id,\n );\n const store = txn.objectStore(\"outgoingRoomKeyRequests\");\n store.add(request);\n txn.onsuccess = () => { deferred.resolve(request); };\n });\n\n return deferred.promise;\n }\n\n /**\n * Look for an existing room key request\n *\n * @param {module:crypto~RoomKeyRequestBody} requestBody\n * existing request to look for\n *\n * @return {Promise} resolves to the matching\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if\n * not found\n */\n getOutgoingRoomKeyRequest(requestBody) {\n const deferred = Promise.defer();\n\n const txn = this._db.transaction(\"outgoingRoomKeyRequests\", \"readonly\");\n txn.onerror = deferred.reject;\n\n this._getOutgoingRoomKeyRequest(txn, requestBody, (existing) => {\n deferred.resolve(existing);\n });\n return deferred.promise;\n }\n\n /**\n * look for an existing room key request in the db\n *\n * @private\n * @param {IDBTransaction} txn database transaction\n * @param {module:crypto~RoomKeyRequestBody} requestBody\n * existing request to look for\n * @param {Function} callback function to call with the results of the\n * search. Either passed a matching\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if\n * not found.\n */\n _getOutgoingRoomKeyRequest(txn, requestBody, callback) {\n const store = txn.objectStore(\"outgoingRoomKeyRequests\");\n\n const idx = store.index(\"session\");\n const cursorReq = idx.openCursor([\n requestBody.room_id,\n requestBody.session_id,\n ]);\n\n cursorReq.onsuccess = (ev) => {\n const cursor = ev.target.result;\n if(!cursor) {\n // no match found\n callback(null);\n return;\n }\n\n const existing = cursor.value;\n\n if (utils.deepCompare(existing.requestBody, requestBody)) {\n // got a match\n callback(existing);\n return;\n }\n\n // look at the next entry in the index\n cursor.continue();\n };\n }\n\n /**\n * Look for room key requests by state\n *\n * @param {Array} wantedStates list of acceptable states\n *\n * @return {Promise} resolves to the a\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if\n * there are no pending requests in those states. If there are multiple\n * requests in those states, an arbitrary one is chosen.\n */\n getOutgoingRoomKeyRequestByState(wantedStates) {\n if (wantedStates.length === 0) {\n return Promise.resolve(null);\n }\n\n // this is a bit tortuous because we need to make sure we do the lookup\n // in a single transaction, to avoid having a race with the insertion\n // code.\n\n // index into the wantedStates array\n let stateIndex = 0;\n let result;\n\n function onsuccess(ev) {\n const cursor = ev.target.result;\n if (cursor) {\n // got a match\n result = cursor.value;\n return;\n }\n\n // try the next state in the list\n stateIndex++;\n if (stateIndex >= wantedStates.length) {\n // no matches\n return;\n }\n\n const wantedState = wantedStates[stateIndex];\n const cursorReq = ev.target.source.openCursor(wantedState);\n cursorReq.onsuccess = onsuccess;\n }\n\n const txn = this._db.transaction(\"outgoingRoomKeyRequests\", \"readonly\");\n const store = txn.objectStore(\"outgoingRoomKeyRequests\");\n\n const wantedState = wantedStates[stateIndex];\n const cursorReq = store.index(\"state\").openCursor(wantedState);\n cursorReq.onsuccess = onsuccess;\n\n return promiseifyTxn(txn).then(() => result);\n }\n\n /**\n * Look for an existing room key request by id and state, and update it if\n * found\n *\n * @param {string} requestId ID of request to update\n * @param {number} expectedState state we expect to find the request in\n * @param {Object} updates name/value map of updates to apply\n *\n * @returns {Promise} resolves to\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}\n * updated request, or null if no matching row was found\n */\n updateOutgoingRoomKeyRequest(requestId, expectedState, updates) {\n let result = null;\n\n function onsuccess(ev) {\n const cursor = ev.target.result;\n if (!cursor) {\n return;\n }\n const data = cursor.value;\n if (data.state != expectedState) {\n console.warn(\n `Cannot update room key request from ${expectedState} ` +\n `as it was already updated to ${data.state}`,\n );\n return;\n }\n Object.assign(data, updates);\n cursor.update(data);\n result = data;\n }\n\n const txn = this._db.transaction(\"outgoingRoomKeyRequests\", \"readwrite\");\n const cursorReq = txn.objectStore(\"outgoingRoomKeyRequests\")\n .openCursor(requestId);\n cursorReq.onsuccess = onsuccess;\n return promiseifyTxn(txn).then(() => result);\n }\n\n /**\n * Look for an existing room key request by id and state, and delete it if\n * found\n *\n * @param {string} requestId ID of request to update\n * @param {number} expectedState state we expect to find the request in\n *\n * @returns {Promise} resolves once the operation is completed\n */\n deleteOutgoingRoomKeyRequest(requestId, expectedState) {\n const txn = this._db.transaction(\"outgoingRoomKeyRequests\", \"readwrite\");\n const cursorReq = txn.objectStore(\"outgoingRoomKeyRequests\")\n .openCursor(requestId);\n cursorReq.onsuccess = (ev) => {\n const cursor = ev.target.result;\n if (!cursor) {\n return;\n }\n const data = cursor.value;\n if (data.state != expectedState) {\n console.warn(\n `Cannot delete room key request in state ${data.state} `\n + `(expected ${expectedState})`,\n );\n return;\n }\n cursor.delete();\n };\n return promiseifyTxn(txn);\n }\n}\n\nexport function upgradeDatabase(db, oldVersion) {\n console.log(\n `Upgrading IndexedDBCryptoStore from version ${oldVersion}`\n + ` to ${VERSION}`,\n );\n if (oldVersion < 1) { // The database did not previously exist.\n createDatabase(db);\n }\n // Expand as needed.\n}\n\nfunction createDatabase(db) {\n const outgoingRoomKeyRequestsStore =\n db.createObjectStore(\"outgoingRoomKeyRequests\", { keyPath: \"requestId\" });\n\n // we assume that the RoomKeyRequestBody will have room_id and session_id\n // properties, to make the index efficient.\n outgoingRoomKeyRequestsStore.createIndex(\"session\",\n [\"requestBody.room_id\", \"requestBody.session_id\"],\n );\n\n outgoingRoomKeyRequestsStore.createIndex(\"state\", \"state\");\n}\n\nfunction promiseifyTxn(txn) {\n return new Promise((resolve, reject) => {\n txn.oncomplete = resolve;\n txn.onerror = reject;\n });\n}\n","/*\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport Promise from 'bluebird';\n\nimport MemoryCryptoStore from './memory-crypto-store';\nimport * as IndexedDBCryptoStoreBackend from './indexeddb-crypto-store-backend';\n\n/**\n * Internal module. indexeddb storage for e2e.\n *\n * @module\n */\n\n/**\n * An implementation of CryptoStore, which is normally backed by an indexeddb,\n * but with fallback to MemoryCryptoStore.\n *\n * @implements {module:crypto/store/base~CryptoStore}\n */\nexport default class IndexedDBCryptoStore {\n /**\n * Create a new IndexedDBCryptoStore\n *\n * @param {IDBFactory} indexedDB global indexedDB instance\n * @param {string} dbName name of db to connect to\n */\n constructor(indexedDB, dbName) {\n this._indexedDB = indexedDB;\n this._dbName = dbName;\n this._backendPromise = null;\n }\n\n /**\n * Ensure the database exists and is up-to-date, or fall back to\n * an in-memory store.\n *\n * @return {Promise} resolves to either an IndexedDBCryptoStoreBackend.Backend,\n * or a MemoryCryptoStore\n */\n _connect() {\n if (this._backendPromise) {\n return this._backendPromise;\n }\n\n this._backendPromise = new Promise((resolve, reject) => {\n if (!this._indexedDB) {\n reject(new Error('no indexeddb support available'));\n return;\n }\n\n console.log(`connecting to indexeddb ${this._dbName}`);\n\n const req = this._indexedDB.open(\n this._dbName, IndexedDBCryptoStoreBackend.VERSION,\n );\n\n req.onupgradeneeded = (ev) => {\n const db = ev.target.result;\n const oldVersion = ev.oldVersion;\n IndexedDBCryptoStoreBackend.upgradeDatabase(db, oldVersion);\n };\n\n req.onblocked = () => {\n console.log(\n `can't yet open IndexedDBCryptoStore because it is open elsewhere`,\n );\n };\n\n req.onerror = (ev) => {\n reject(ev.target.error);\n };\n\n req.onsuccess = (r) => {\n const db = r.target.result;\n\n console.log(`connected to indexeddb ${this._dbName}`);\n resolve(new IndexedDBCryptoStoreBackend.Backend(db));\n };\n }).catch((e) => {\n console.warn(\n `unable to connect to indexeddb ${this._dbName}` +\n `: falling back to in-memory store: ${e}`,\n );\n return new MemoryCryptoStore();\n });\n\n return this._backendPromise;\n }\n\n /**\n * Delete all data from this store.\n *\n * @returns {Promise} resolves when the store has been cleared.\n */\n deleteAllData() {\n return new Promise((resolve, reject) => {\n if (!this._indexedDB) {\n reject(new Error('no indexeddb support available'));\n return;\n }\n\n console.log(`Removing indexeddb instance: ${this._dbName}`);\n const req = this._indexedDB.deleteDatabase(this._dbName);\n\n req.onblocked = () => {\n console.log(\n `can't yet delete IndexedDBCryptoStore because it is open elsewhere`,\n );\n };\n\n req.onerror = (ev) => {\n reject(ev.target.error);\n };\n\n req.onsuccess = () => {\n console.log(`Removed indexeddb instance: ${this._dbName}`);\n resolve();\n };\n }).catch((e) => {\n // in firefox, with indexedDB disabled, this fails with a\n // DOMError. We treat this as non-fatal, so that people can\n // still use the app.\n console.warn(`unable to delete IndexedDBCryptoStore: ${e}`);\n });\n }\n\n /**\n * Look for an existing outgoing room key request, and if none is found,\n * add a new one\n *\n * @param {module:crypto/store/base~OutgoingRoomKeyRequest} request\n *\n * @returns {Promise} resolves to\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the\n * same instance as passed in, or the existing one.\n */\n getOrAddOutgoingRoomKeyRequest(request) {\n return this._connect().then((backend) => {\n return backend.getOrAddOutgoingRoomKeyRequest(request);\n });\n }\n\n /**\n * Look for an existing room key request\n *\n * @param {module:crypto~RoomKeyRequestBody} requestBody\n * existing request to look for\n *\n * @return {Promise} resolves to the matching\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if\n * not found\n */\n getOutgoingRoomKeyRequest(requestBody) {\n return this._connect().then((backend) => {\n return backend.getOutgoingRoomKeyRequest(requestBody);\n });\n }\n\n /**\n * Look for room key requests by state\n *\n * @param {Array} wantedStates list of acceptable states\n *\n * @return {Promise} resolves to the a\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if\n * there are no pending requests in those states. If there are multiple\n * requests in those states, an arbitrary one is chosen.\n */\n getOutgoingRoomKeyRequestByState(wantedStates) {\n return this._connect().then((backend) => {\n return backend.getOutgoingRoomKeyRequestByState(wantedStates);\n });\n }\n\n /**\n * Look for an existing room key request by id and state, and update it if\n * found\n *\n * @param {string} requestId ID of request to update\n * @param {number} expectedState state we expect to find the request in\n * @param {Object} updates name/value map of updates to apply\n *\n * @returns {Promise} resolves to\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}\n * updated request, or null if no matching row was found\n */\n updateOutgoingRoomKeyRequest(requestId, expectedState, updates) {\n return this._connect().then((backend) => {\n return backend.updateOutgoingRoomKeyRequest(\n requestId, expectedState, updates,\n );\n });\n }\n\n /**\n * Look for an existing room key request by id and state, and delete it if\n * found\n *\n * @param {string} requestId ID of request to update\n * @param {number} expectedState state we expect to find the request in\n *\n * @returns {Promise} resolves once the operation is completed\n */\n deleteOutgoingRoomKeyRequest(requestId, expectedState) {\n return this._connect().then((backend) => {\n return backend.deleteOutgoingRoomKeyRequest(requestId, expectedState);\n });\n }\n}\n","/*\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport Promise from 'bluebird';\n\nimport utils from '../../utils';\n\n/**\n * Internal module. in-memory storage for e2e.\n *\n * @module\n */\n\n/**\n * @implements {module:crypto/store/base~CryptoStore}\n */\nexport default class MemoryCryptoStore {\n constructor() {\n this._outgoingRoomKeyRequests = [];\n }\n\n /**\n * Delete all data from this store.\n *\n * @returns {Promise} Promise which resolves when the store has been cleared.\n */\n deleteAllData() {\n return Promise.resolve();\n }\n\n /**\n * Look for an existing outgoing room key request, and if none is found,\n * add a new one\n *\n * @param {module:crypto/store/base~OutgoingRoomKeyRequest} request\n *\n * @returns {Promise} resolves to\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the\n * same instance as passed in, or the existing one.\n */\n getOrAddOutgoingRoomKeyRequest(request) {\n const requestBody = request.requestBody;\n\n return Promise.try(() => {\n // first see if we already have an entry for this request.\n const existing = this._getOutgoingRoomKeyRequest(requestBody);\n\n if (existing) {\n // this entry matches the request - return it.\n console.log(\n `already have key request outstanding for ` +\n `${requestBody.room_id} / ${requestBody.session_id}: ` +\n `not sending another`,\n );\n return existing;\n }\n\n // we got to the end of the list without finding a match\n // - add the new request.\n console.log(\n `enqueueing key request for ${requestBody.room_id} / ` +\n requestBody.session_id,\n );\n this._outgoingRoomKeyRequests.push(request);\n return request;\n });\n }\n\n /**\n * Look for an existing room key request\n *\n * @param {module:crypto~RoomKeyRequestBody} requestBody\n * existing request to look for\n *\n * @return {Promise} resolves to the matching\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if\n * not found\n */\n getOutgoingRoomKeyRequest(requestBody) {\n return Promise.resolve(this._getOutgoingRoomKeyRequest(requestBody));\n }\n\n /**\n * Looks for existing room key request, and returns the result synchronously.\n *\n * @internal\n *\n * @param {module:crypto~RoomKeyRequestBody} requestBody\n * existing request to look for\n *\n * @return {module:crypto/store/base~OutgoingRoomKeyRequest?}\n * the matching request, or null if not found\n */\n _getOutgoingRoomKeyRequest(requestBody) {\n for (const existing of this._outgoingRoomKeyRequests) {\n if (utils.deepCompare(existing.requestBody, requestBody)) {\n return existing;\n }\n }\n return null;\n }\n\n /**\n * Look for room key requests by state\n *\n * @param {Array} wantedStates list of acceptable states\n *\n * @return {Promise} resolves to the a\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if\n * there are no pending requests in those states\n */\n getOutgoingRoomKeyRequestByState(wantedStates) {\n for (const req of this._outgoingRoomKeyRequests) {\n for (const state of wantedStates) {\n if (req.state === state) {\n return Promise.resolve(req);\n }\n }\n }\n return Promise.resolve(null);\n }\n\n /**\n * Look for an existing room key request by id and state, and update it if\n * found\n *\n * @param {string} requestId ID of request to update\n * @param {number} expectedState state we expect to find the request in\n * @param {Object} updates name/value map of updates to apply\n *\n * @returns {Promise} resolves to\n * {@link module:crypto/store/base~OutgoingRoomKeyRequest}\n * updated request, or null if no matching row was found\n */\n updateOutgoingRoomKeyRequest(requestId, expectedState, updates) {\n for (const req of this._outgoingRoomKeyRequests) {\n if (req.requestId !== requestId) {\n continue;\n }\n\n if (req.state != expectedState) {\n console.warn(\n `Cannot update room key request from ${expectedState} ` +\n `as it was already updated to ${req.state}`,\n );\n return Promise.resolve(null);\n }\n Object.assign(req, updates);\n return Promise.resolve(req);\n }\n\n return Promise.resolve(null);\n }\n\n /**\n * Look for an existing room key request by id and state, and delete it if\n * found\n *\n * @param {string} requestId ID of request to update\n * @param {number} expectedState state we expect to find the request in\n *\n * @returns {Promise} resolves once the operation is completed\n */\n deleteOutgoingRoomKeyRequest(requestId, expectedState) {\n for (let i = 0; i < this._outgoingRoomKeyRequests.length; i++) {\n const req = this._outgoingRoomKeyRequests[i];\n\n if (req.requestId !== requestId) {\n continue;\n }\n\n if (req.state != expectedState) {\n console.warn(\n `Cannot delete room key request in state ${req.state} `\n + `(expected ${expectedState})`,\n );\n return Promise.resolve(null);\n }\n\n this._outgoingRoomKeyRequests.splice(i, 1);\n return Promise.resolve(req);\n }\n\n return Promise.resolve(null);\n }\n}\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * @module filter-component\n */\n\n/**\n * Checks if a value matches a given field value, which may be a * terminated\n * wildcard pattern.\n * @param {String} actual_value The value to be compared\n * @param {String} filter_value The filter pattern to be compared\n * @return {bool} true if the actual_value matches the filter_value\n */\nfunction _matches_wildcard(actual_value, filter_value) {\n if (filter_value.endsWith(\"*\")) {\n const type_prefix = filter_value.slice(0, -1);\n return actual_value.substr(0, type_prefix.length) === type_prefix;\n } else {\n return actual_value === filter_value;\n }\n}\n\n/**\n * FilterComponent is a section of a Filter definition which defines the\n * types, rooms, senders filters etc to be applied to a particular type of resource.\n * This is all ported over from synapse's Filter object.\n *\n * N.B. that synapse refers to these as 'Filters', and what js-sdk refers to as\n * 'Filters' are referred to as 'FilterCollections'.\n *\n * @constructor\n * @param {Object} filter_json the definition of this filter JSON, e.g. { 'contains_url': true }\n */\nfunction FilterComponent(filter_json) {\n this.filter_json = filter_json;\n\n this.types = filter_json.types || null;\n this.not_types = filter_json.not_types || [];\n\n this.rooms = filter_json.rooms || null;\n this.not_rooms = filter_json.not_rooms || [];\n\n this.senders = filter_json.senders || null;\n this.not_senders = filter_json.not_senders || [];\n\n this.contains_url = filter_json.contains_url || null;\n}\n\n/**\n * Checks with the filter component matches the given event\n * @param {MatrixEvent} event event to be checked against the filter\n * @return {bool} true if the event matches the filter\n */\nFilterComponent.prototype.check = function(event) {\n return this._checkFields(\n event.getRoomId(),\n event.getSender(),\n event.getType(),\n event.getContent() ? event.getContent().url !== undefined : false,\n );\n};\n\n/**\n * Checks whether the filter component matches the given event fields.\n * @param {String} room_id the room_id for the event being checked\n * @param {String} sender the sender of the event being checked\n * @param {String} event_type the type of the event being checked\n * @param {String} contains_url whether the event contains a content.url field\n * @return {bool} true if the event fields match the filter\n */\nFilterComponent.prototype._checkFields =\n function(room_id, sender, event_type, contains_url) {\n const literal_keys = {\n \"rooms\": function(v) {\n return room_id === v;\n },\n \"senders\": function(v) {\n return sender === v;\n },\n \"types\": function(v) {\n return _matches_wildcard(event_type, v);\n },\n };\n\n const self = this;\n Object.keys(literal_keys).forEach(function(name) {\n const match_func = literal_keys[name];\n const not_name = \"not_\" + name;\n const disallowed_values = self[not_name];\n if (disallowed_values.map(match_func)) {\n return false;\n }\n\n const allowed_values = self[name];\n if (allowed_values) {\n if (!allowed_values.map(match_func)) {\n return false;\n }\n }\n });\n\n const contains_url_filter = this.filter_json.contains_url;\n if (contains_url_filter !== undefined) {\n if (contains_url_filter !== contains_url) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Filters a list of events down to those which match this filter component\n * @param {MatrixEvent[]} events Events to be checked againt the filter component\n * @return {MatrixEvent[]} events which matched the filter component\n */\nFilterComponent.prototype.filter = function(events) {\n return events.filter(this.check, this);\n};\n\n/**\n * Returns the limit field for a given filter component, providing a default of\n * 10 if none is otherwise specified. Cargo-culted from Synapse.\n * @return {Number} the limit for this filter component.\n */\nFilterComponent.prototype.limit = function() {\n return this.filter_json.limit !== undefined ? this.filter_json.limit : 10;\n};\n\n/** The FilterComponent class */\nmodule.exports = FilterComponent;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * @module filter\n */\n\nconst FilterComponent = require(\"./filter-component\");\n\n/**\n * @param {Object} obj\n * @param {string} keyNesting\n * @param {*} val\n */\nfunction setProp(obj, keyNesting, val) {\n const nestedKeys = keyNesting.split(\".\");\n let currentObj = obj;\n for (let i = 0; i < (nestedKeys.length - 1); i++) {\n if (!currentObj[nestedKeys[i]]) {\n currentObj[nestedKeys[i]] = {};\n }\n currentObj = currentObj[nestedKeys[i]];\n }\n currentObj[nestedKeys[nestedKeys.length - 1]] = val;\n}\n\n/**\n * Construct a new Filter.\n * @constructor\n * @param {string} userId The user ID for this filter.\n * @param {string=} filterId The filter ID if known.\n * @prop {string} userId The user ID of the filter\n * @prop {?string} filterId The filter ID\n */\nfunction Filter(userId, filterId) {\n this.userId = userId;\n this.filterId = filterId;\n this.definition = {};\n}\n\n/**\n * Get the ID of this filter on your homeserver (if known)\n * @return {?Number} The filter ID\n */\nFilter.prototype.getFilterId = function() {\n return this.filterId;\n};\n\n/**\n * Get the JSON body of the filter.\n * @return {Object} The filter definition\n */\nFilter.prototype.getDefinition = function() {\n return this.definition;\n};\n\n/**\n * Set the JSON body of the filter\n * @param {Object} definition The filter definition\n */\nFilter.prototype.setDefinition = function(definition) {\n this.definition = definition;\n\n // This is all ported from synapse's FilterCollection()\n\n // definitions look something like:\n // {\n // \"room\": {\n // \"rooms\": [\"!abcde:example.com\"],\n // \"not_rooms\": [\"!123456:example.com\"],\n // \"state\": {\n // \"types\": [\"m.room.*\"],\n // \"not_rooms\": [\"!726s6s6q:example.com\"],\n // },\n // \"timeline\": {\n // \"limit\": 10,\n // \"types\": [\"m.room.message\"],\n // \"not_rooms\": [\"!726s6s6q:example.com\"],\n // \"not_senders\": [\"@spam:example.com\"]\n // \"contains_url\": true\n // },\n // \"ephemeral\": {\n // \"types\": [\"m.receipt\", \"m.typing\"],\n // \"not_rooms\": [\"!726s6s6q:example.com\"],\n // \"not_senders\": [\"@spam:example.com\"]\n // }\n // },\n // \"presence\": {\n // \"types\": [\"m.presence\"],\n // \"not_senders\": [\"@alice:example.com\"]\n // },\n // \"event_format\": \"client\",\n // \"event_fields\": [\"type\", \"content\", \"sender\"]\n // }\n\n const room_filter_json = definition.room;\n\n // consider the top level rooms/not_rooms filter\n const room_filter_fields = {};\n if (room_filter_json) {\n if (room_filter_json.rooms) {\n room_filter_fields.rooms = room_filter_json.rooms;\n }\n if (room_filter_json.rooms) {\n room_filter_fields.not_rooms = room_filter_json.not_rooms;\n }\n\n this._include_leave = room_filter_json.include_leave || false;\n }\n\n this._room_filter = new FilterComponent(room_filter_fields);\n this._room_timeline_filter = new FilterComponent(\n room_filter_json ? (room_filter_json.timeline || {}) : {},\n );\n\n // don't bother porting this from synapse yet:\n // this._room_state_filter =\n // new FilterComponent(room_filter_json.state || {});\n // this._room_ephemeral_filter =\n // new FilterComponent(room_filter_json.ephemeral || {});\n // this._room_account_data_filter =\n // new FilterComponent(room_filter_json.account_data || {});\n // this._presence_filter =\n // new FilterComponent(definition.presence || {});\n // this._account_data_filter =\n // new FilterComponent(definition.account_data || {});\n};\n\n/**\n * Get the room.timeline filter component of the filter\n * @return {FilterComponent} room timeline filter component\n */\nFilter.prototype.getRoomTimelineFilterComponent = function() {\n return this._room_timeline_filter;\n};\n\n/**\n * Filter the list of events based on whether they are allowed in a timeline\n * based on this filter\n * @param {MatrixEvent[]} events the list of events being filtered\n * @return {MatrixEvent[]} the list of events which match the filter\n */\nFilter.prototype.filterRoomTimeline = function(events) {\n return this._room_timeline_filter.filter(this._room_filter.filter(events));\n};\n\n/**\n * Set the max number of events to return for each room's timeline.\n * @param {Number} limit The max number of events to return for each room.\n */\nFilter.prototype.setTimelineLimit = function(limit) {\n setProp(this.definition, \"room.timeline.limit\", limit);\n};\n\n/**\n * Control whether left rooms should be included in responses.\n * @param {boolean} includeLeave True to make rooms the user has left appear\n * in responses.\n */\nFilter.prototype.setIncludeLeaveRooms = function(includeLeave) {\n setProp(this.definition, \"room.include_leave\", includeLeave);\n};\n\n/**\n * Create a filter from existing data.\n * @static\n * @param {string} userId\n * @param {string} filterId\n * @param {Object} jsonObj\n * @return {Filter}\n */\nFilter.fromJson = function(userId, filterId, jsonObj) {\n const filter = new Filter(userId, filterId);\n filter.setDefinition(jsonObj);\n return filter;\n};\n\n/** The Filter class */\nmodule.exports = Filter;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * This is an internal module. See {@link MatrixHttpApi} for the public class.\n * @module http-api\n */\nimport Promise from 'bluebird';\nconst parseContentType = require('content-type').parse;\n\nconst utils = require(\"./utils\");\n\n// we use our own implementation of setTimeout, so that if we get suspended in\n// the middle of a /sync, we cancel the sync as soon as we awake, rather than\n// waiting for the delay to elapse.\nconst callbacks = require(\"./realtime-callbacks\");\n\n/*\nTODO:\n- CS: complete register function (doing stages)\n- Identity server: linkEmail, authEmail, bindEmail, lookup3pid\n*/\n\n/**\n * A constant representing the URI path for release 0 of the Client-Server HTTP API.\n */\nmodule.exports.PREFIX_R0 = \"/_matrix/client/r0\";\n\n/**\n * A constant representing the URI path for as-yet unspecified Client-Server HTTP APIs.\n */\nmodule.exports.PREFIX_UNSTABLE = \"/_matrix/client/unstable\";\n\n/**\n * URI path for the identity API\n */\nmodule.exports.PREFIX_IDENTITY_V1 = \"/_matrix/identity/api/v1\";\n\n/**\n * URI path for the media repo API\n */\nmodule.exports.PREFIX_MEDIA_R0 = \"/_matrix/media/r0\";\n\n/**\n * Construct a MatrixHttpApi.\n * @constructor\n * @param {EventEmitter} event_emitter The event emitter to use for emitting events\n * @param {Object} opts The options to use for this HTTP API.\n * @param {string} opts.baseUrl Required. The base client-server URL e.g.\n * 'http://localhost:8008'.\n * @param {Function} opts.request Required. The function to call for HTTP\n * requests. This function must look like function(opts, callback){ ... }.\n * @param {string} opts.prefix Required. The matrix client prefix to use, e.g.\n * '/_matrix/client/r0'. See PREFIX_R0 and PREFIX_UNSTABLE for constants.\n *\n * @param {boolean} opts.onlyData True to return only the 'data' component of the\n * response (e.g. the parsed HTTP body). If false, requests will return an\n * object with the properties code, headers and data.\n *\n * @param {string} opts.accessToken The access_token to send with requests. Can be\n * null to not send an access token.\n * @param {Object=} opts.extraParams Optional. Extra query parameters to send on\n * requests.\n * @param {Number=} opts.localTimeoutMs The default maximum amount of time to wait\n * before timing out the request. If not specified, there is no timeout.\n * @param {boolean} [opts.useAuthorizationHeader = false] Set to true to use\n * Authorization header instead of query param to send the access token to the server.\n */\nmodule.exports.MatrixHttpApi = function MatrixHttpApi(event_emitter, opts) {\n utils.checkObjectHasKeys(opts, [\"baseUrl\", \"request\", \"prefix\"]);\n opts.onlyData = opts.onlyData || false;\n this.event_emitter = event_emitter;\n this.opts = opts;\n this.useAuthorizationHeader = Boolean(opts.useAuthorizationHeader);\n this.uploads = [];\n};\n\nmodule.exports.MatrixHttpApi.prototype = {\n\n /**\n * Get the content repository url with query parameters.\n * @return {Object} An object with a 'base', 'path' and 'params' for base URL,\n * path and query parameters respectively.\n */\n getContentUri: function() {\n const params = {\n access_token: this.opts.accessToken,\n };\n return {\n base: this.opts.baseUrl,\n path: \"/_matrix/media/v1/upload\",\n params: params,\n };\n },\n\n /**\n * Upload content to the Home Server\n *\n * @param {object} file The object to upload. On a browser, something that\n * can be sent to XMLHttpRequest.send (typically a File). Under node.js,\n * a Buffer, String or ReadStream.\n *\n * @param {object} opts options object\n *\n * @param {string=} opts.name Name to give the file on the server. Defaults\n * to file.name.\n *\n * @param {string=} opts.type Content-type for the upload. Defaults to\n * file.type, or applicaton/octet-stream.\n *\n * @param {boolean=} opts.rawResponse Return the raw body, rather than\n * parsing the JSON. Defaults to false (except on node.js, where it\n * defaults to true for backwards compatibility).\n *\n * @param {boolean=} opts.onlyContentUri Just return the content URI,\n * rather than the whole body. Defaults to false (except on browsers,\n * where it defaults to true for backwards compatibility). Ignored if\n * opts.rawResponse is true.\n *\n * @param {Function=} opts.callback Deprecated. Optional. The callback to\n * invoke on success/failure. See the promise return values for more\n * information.\n *\n * @param {Function=} opts.progressHandler Optional. Called when a chunk of\n * data has been uploaded, with an object containing the fields `loaded`\n * (number of bytes transferred) and `total` (total size, if known).\n *\n * @return {module:client.Promise} Resolves to response object, as\n * determined by this.opts.onlyData, opts.rawResponse, and\n * opts.onlyContentUri. Rejects with an error (usually a MatrixError).\n */\n uploadContent: function(file, opts) {\n if (utils.isFunction(opts)) {\n // opts used to be callback\n opts = {\n callback: opts,\n };\n } else if (opts === undefined) {\n opts = {};\n }\n\n // if the file doesn't have a mime type, use a default since\n // the HS errors if we don't supply one.\n const contentType = opts.type || file.type || 'application/octet-stream';\n const fileName = opts.name || file.name;\n\n // we used to recommend setting file.stream to the thing to upload on\n // nodejs.\n const body = file.stream ? file.stream : file;\n\n // backwards-compatibility hacks where we used to do different things\n // between browser and node.\n let rawResponse = opts.rawResponse;\n if (rawResponse === undefined) {\n if (global.XMLHttpRequest) {\n rawResponse = false;\n } else {\n console.warn(\n \"Returning the raw JSON from uploadContent(). Future \" +\n \"versions of the js-sdk will change this default, to \" +\n \"return the parsed object. Set opts.rawResponse=false \" +\n \"to change this behaviour now.\",\n );\n rawResponse = true;\n }\n }\n\n let onlyContentUri = opts.onlyContentUri;\n if (!rawResponse && onlyContentUri === undefined) {\n if (global.XMLHttpRequest) {\n console.warn(\n \"Returning only the content-uri from uploadContent(). \" +\n \"Future versions of the js-sdk will change this \" +\n \"default, to return the whole response object. Set \" +\n \"opts.onlyContentUri=false to change this behaviour now.\",\n );\n onlyContentUri = true;\n } else {\n onlyContentUri = false;\n }\n }\n\n // browser-request doesn't support File objects because it deep-copies\n // the options using JSON.parse(JSON.stringify(options)). Instead of\n // loading the whole file into memory as a string and letting\n // browser-request base64 encode and then decode it again, we just\n // use XMLHttpRequest directly.\n // (browser-request doesn't support progress either, which is also kind\n // of important here)\n\n const upload = { loaded: 0, total: 0 };\n let promise;\n\n // XMLHttpRequest doesn't parse JSON for us. request normally does, but\n // we're setting opts.json=false so that it doesn't JSON-encode the\n // request, which also means it doesn't JSON-decode the response. Either\n // way, we have to JSON-parse the response ourselves.\n let bodyParser = null;\n if (!rawResponse) {\n bodyParser = function(rawBody) {\n let body = JSON.parse(rawBody);\n if (onlyContentUri) {\n body = body.content_uri;\n if (body === undefined) {\n throw Error('Bad response');\n }\n }\n return body;\n };\n }\n\n if (global.XMLHttpRequest) {\n const defer = Promise.defer();\n const xhr = new global.XMLHttpRequest();\n upload.xhr = xhr;\n const cb = requestCallback(defer, opts.callback, this.opts.onlyData);\n\n const timeout_fn = function() {\n xhr.abort();\n cb(new Error('Timeout'));\n };\n\n // set an initial timeout of 30s; we'll advance it each time we get\n // a progress notification\n xhr.timeout_timer = callbacks.setTimeout(timeout_fn, 30000);\n\n xhr.onreadystatechange = function() {\n switch (xhr.readyState) {\n case global.XMLHttpRequest.DONE:\n callbacks.clearTimeout(xhr.timeout_timer);\n var resp;\n try {\n if (!xhr.responseText) {\n throw new Error('No response body.');\n }\n resp = xhr.responseText;\n if (bodyParser) {\n resp = bodyParser(resp);\n }\n } catch (err) {\n err.http_status = xhr.status;\n cb(err);\n return;\n }\n cb(undefined, xhr, resp);\n break;\n }\n };\n xhr.upload.addEventListener(\"progress\", function(ev) {\n callbacks.clearTimeout(xhr.timeout_timer);\n upload.loaded = ev.loaded;\n upload.total = ev.total;\n xhr.timeout_timer = callbacks.setTimeout(timeout_fn, 30000);\n if (opts.progressHandler) {\n opts.progressHandler({\n loaded: ev.loaded,\n total: ev.total,\n });\n }\n });\n let url = this.opts.baseUrl + \"/_matrix/media/v1/upload\";\n url += \"?access_token=\" + encodeURIComponent(this.opts.accessToken);\n url += \"&filename=\" + encodeURIComponent(fileName);\n\n xhr.open(\"POST\", url);\n xhr.setRequestHeader(\"Content-Type\", contentType);\n xhr.send(body);\n promise = defer.promise;\n\n // dirty hack (as per _request) to allow the upload to be cancelled.\n promise.abort = xhr.abort.bind(xhr);\n } else {\n const queryParams = {\n filename: fileName,\n };\n\n promise = this.authedRequest(\n opts.callback, \"POST\", \"/upload\", queryParams, body, {\n prefix: \"/_matrix/media/v1\",\n headers: {\"Content-Type\": contentType},\n json: false,\n bodyParser: bodyParser,\n },\n );\n }\n\n const self = this;\n\n // remove the upload from the list on completion\n const promise0 = promise.finally(function() {\n for (let i = 0; i < self.uploads.length; ++i) {\n if (self.uploads[i] === upload) {\n self.uploads.splice(i, 1);\n return;\n }\n }\n });\n\n // copy our dirty abort() method to the new promise\n promise0.abort = promise.abort;\n\n upload.promise = promise0;\n this.uploads.push(upload);\n\n return promise0;\n },\n\n cancelUpload: function(promise) {\n if (promise.abort) {\n promise.abort();\n return true;\n }\n return false;\n },\n\n getCurrentUploads: function() {\n return this.uploads;\n },\n\n idServerRequest: function(callback, method, path, params, prefix) {\n const fullUri = this.opts.idBaseUrl + prefix + path;\n\n if (callback !== undefined && !utils.isFunction(callback)) {\n throw Error(\n \"Expected callback to be a function but got \" + typeof callback,\n );\n }\n\n const opts = {\n uri: fullUri,\n method: method,\n withCredentials: false,\n json: false,\n _matrix_opts: this.opts,\n };\n if (method == 'GET') {\n opts.qs = params;\n } else {\n opts.form = params;\n }\n\n const defer = Promise.defer();\n this.opts.request(\n opts,\n requestCallback(defer, callback, this.opts.onlyData),\n );\n // ID server does not always take JSON, so we can't use requests' 'json'\n // option as we do with the home server, but it does return JSON, so\n // parse it manually\n return defer.promise.then(function(response) {\n return JSON.parse(response);\n });\n },\n\n /**\n * Perform an authorised request to the homeserver.\n * @param {Function} callback Optional. The callback to invoke on\n * success/failure. See the promise return values for more information.\n * @param {string} method The HTTP method e.g. \"GET\".\n * @param {string} path The HTTP path after the supplied prefix e.g.\n * \"/createRoom\".\n *\n * @param {Object=} queryParams A dict of query params (these will NOT be\n * urlencoded). If unspecified, there will be no query params.\n *\n * @param {Object} data The HTTP JSON body.\n *\n * @param {Object|Number=} opts additional options. If a number is specified,\n * this is treated as `opts.localTimeoutMs`.\n *\n * @param {Number=} opts.localTimeoutMs The maximum amount of time to wait before\n * timing out the request. If not specified, there is no timeout.\n *\n * @param {sting=} opts.prefix The full prefix to use e.g.\n * \"/_matrix/client/v2_alpha\". If not specified, uses this.opts.prefix.\n *\n * @param {Object=} opts.headers map of additional request headers\n *\n * @return {module:client.Promise} Resolves to {data: {Object},\n * headers: {Object}, code: {Number}}.\n * If onlyData is set, this will resolve to the data\n * object only.\n * @return {module:http-api.MatrixError} Rejects with an error if a problem\n * occurred. This includes network problems and Matrix-specific error JSON.\n */\n authedRequest: function(callback, method, path, queryParams, data, opts) {\n if (!queryParams) {\n queryParams = {};\n }\n if (this.useAuthorizationHeader) {\n if (isFinite(opts)) {\n // opts used to be localTimeoutMs\n opts = {\n localTimeoutMs: opts,\n };\n }\n if (!opts) {\n opts = {};\n }\n if (!opts.headers) {\n opts.headers = {};\n }\n if (!opts.headers.Authorization) {\n opts.headers.Authorization = \"Bearer \" + this.opts.accessToken;\n }\n if (queryParams.access_token) {\n delete queryParams.access_token;\n }\n } else {\n if (!queryParams.access_token) {\n queryParams.access_token = this.opts.accessToken;\n }\n }\n\n const requestPromise = this.request(\n callback, method, path, queryParams, data, opts,\n );\n\n const self = this;\n requestPromise.catch(function(err) {\n if (err.errcode == 'M_UNKNOWN_TOKEN') {\n self.event_emitter.emit(\"Session.logged_out\");\n }\n });\n\n // return the original promise, otherwise tests break due to it having to\n // go around the event loop one more time to process the result of the request\n return requestPromise;\n },\n\n /**\n * Perform a request to the homeserver without any credentials.\n * @param {Function} callback Optional. The callback to invoke on\n * success/failure. See the promise return values for more information.\n * @param {string} method The HTTP method e.g. \"GET\".\n * @param {string} path The HTTP path after the supplied prefix e.g.\n * \"/createRoom\".\n *\n * @param {Object=} queryParams A dict of query params (these will NOT be\n * urlencoded). If unspecified, there will be no query params.\n *\n * @param {Object} data The HTTP JSON body.\n *\n * @param {Object=} opts additional options\n *\n * @param {Number=} opts.localTimeoutMs The maximum amount of time to wait before\n * timing out the request. If not specified, there is no timeout.\n *\n * @param {sting=} opts.prefix The full prefix to use e.g.\n * \"/_matrix/client/v2_alpha\". If not specified, uses this.opts.prefix.\n *\n * @param {Object=} opts.headers map of additional request headers\n *\n * @return {module:client.Promise} Resolves to {data: {Object},\n * headers: {Object}, code: {Number}}.\n * If onlyData is set, this will resolve to the data\n * object only.\n * @return {module:http-api.MatrixError} Rejects with an error if a problem\n * occurred. This includes network problems and Matrix-specific error JSON.\n */\n request: function(callback, method, path, queryParams, data, opts) {\n opts = opts || {};\n const prefix = opts.prefix !== undefined ? opts.prefix : this.opts.prefix;\n const fullUri = this.opts.baseUrl + prefix + path;\n\n return this.requestOtherUrl(\n callback, method, fullUri, queryParams, data, opts,\n );\n },\n\n /**\n * Perform an authorised request to the homeserver with a specific path\n * prefix which overrides the default for this call only. Useful for hitting\n * different Matrix Client-Server versions.\n * @param {Function} callback Optional. The callback to invoke on\n * success/failure. See the promise return values for more information.\n * @param {string} method The HTTP method e.g. \"GET\".\n * @param {string} path The HTTP path after the supplied prefix e.g.\n * \"/createRoom\".\n * @param {Object} queryParams A dict of query params (these will NOT be\n * urlencoded).\n * @param {Object} data The HTTP JSON body.\n * @param {string} prefix The full prefix to use e.g.\n * \"/_matrix/client/v2_alpha\".\n * @param {Number=} localTimeoutMs The maximum amount of time to wait before\n * timing out the request. If not specified, there is no timeout.\n * @return {module:client.Promise} Resolves to {data: {Object},\n * headers: {Object}, code: {Number}}.\n * If onlyData is set, this will resolve to the data\n * object only.\n * @return {module:http-api.MatrixError} Rejects with an error if a problem\n * occurred. This includes network problems and Matrix-specific error JSON.\n *\n * @deprecated prefer authedRequest with opts.prefix\n */\n authedRequestWithPrefix: function(callback, method, path, queryParams, data,\n prefix, localTimeoutMs) {\n return this.authedRequest(\n callback, method, path, queryParams, data, {\n localTimeoutMs: localTimeoutMs,\n prefix: prefix,\n },\n );\n },\n\n /**\n * Perform a request to the homeserver without any credentials but with a\n * specific path prefix which overrides the default for this call only.\n * Useful for hitting different Matrix Client-Server versions.\n * @param {Function} callback Optional. The callback to invoke on\n * success/failure. See the promise return values for more information.\n * @param {string} method The HTTP method e.g. \"GET\".\n * @param {string} path The HTTP path after the supplied prefix e.g.\n * \"/createRoom\".\n * @param {Object} queryParams A dict of query params (these will NOT be\n * urlencoded).\n * @param {Object} data The HTTP JSON body.\n * @param {string} prefix The full prefix to use e.g.\n * \"/_matrix/client/v2_alpha\".\n * @param {Number=} localTimeoutMs The maximum amount of time to wait before\n * timing out the request. If not specified, there is no timeout.\n * @return {module:client.Promise} Resolves to {data: {Object},\n * headers: {Object}, code: {Number}}.\n * If onlyData is set, this will resolve to the data\n * object only.\n * @return {module:http-api.MatrixError} Rejects with an error if a problem\n * occurred. This includes network problems and Matrix-specific error JSON.\n *\n * @deprecated prefer request with opts.prefix\n */\n requestWithPrefix: function(callback, method, path, queryParams, data, prefix,\n localTimeoutMs) {\n return this.request(\n callback, method, path, queryParams, data, {\n localTimeoutMs: localTimeoutMs,\n prefix: prefix,\n },\n );\n },\n\n /**\n * Perform a request to an arbitrary URL.\n * @param {Function} callback Optional. The callback to invoke on\n * success/failure. See the promise return values for more information.\n * @param {string} method The HTTP method e.g. \"GET\".\n * @param {string} uri The HTTP URI\n *\n * @param {Object=} queryParams A dict of query params (these will NOT be\n * urlencoded). If unspecified, there will be no query params.\n *\n * @param {Object} data The HTTP JSON body.\n *\n * @param {Object=} opts additional options\n *\n * @param {Number=} opts.localTimeoutMs The maximum amount of time to wait before\n * timing out the request. If not specified, there is no timeout.\n *\n * @param {sting=} opts.prefix The full prefix to use e.g.\n * \"/_matrix/client/v2_alpha\". If not specified, uses this.opts.prefix.\n *\n * @param {Object=} opts.headers map of additional request headers\n *\n * @return {module:client.Promise} Resolves to {data: {Object},\n * headers: {Object}, code: {Number}}.\n * If onlyData is set, this will resolve to the data\n * object only.\n * @return {module:http-api.MatrixError} Rejects with an error if a problem\n * occurred. This includes network problems and Matrix-specific error JSON.\n */\n requestOtherUrl: function(callback, method, uri, queryParams, data,\n opts) {\n if (opts === undefined || opts === null) {\n opts = {};\n } else if (isFinite(opts)) {\n // opts used to be localTimeoutMs\n opts = {\n localTimeoutMs: opts,\n };\n }\n\n return this._request(\n callback, method, uri, queryParams, data, opts,\n );\n },\n\n /**\n * Form and return a homeserver request URL based on the given path\n * params and prefix.\n * @param {string} path The HTTP path after the supplied prefix e.g.\n * \"/createRoom\".\n * @param {Object} queryParams A dict of query params (these will NOT be\n * urlencoded).\n * @param {string} prefix The full prefix to use e.g.\n * \"/_matrix/client/v2_alpha\".\n * @return {string} URL\n */\n getUrl: function(path, queryParams, prefix) {\n let queryString = \"\";\n if (queryParams) {\n queryString = \"?\" + utils.encodeParams(queryParams);\n }\n return this.opts.baseUrl + prefix + path + queryString;\n },\n\n /**\n * @private\n *\n * @param {function} callback\n * @param {string} method\n * @param {string} uri\n * @param {object} queryParams\n * @param {object|string} data\n * @param {object=} opts\n *\n * @param {boolean} [opts.json =true] Json-encode data before sending, and\n * decode response on receipt. (We will still json-decode error\n * responses, even if this is false.)\n *\n * @param {object=} opts.headers extra request headers\n *\n * @param {number=} opts.localTimeoutMs client-side timeout for the\n * request. Default timeout if falsy.\n *\n * @param {function=} opts.bodyParser function to parse the body of the\n * response before passing it to the promise and callback.\n *\n * @return {module:client.Promise} a promise which resolves to either the\n * response object (if this.opts.onlyData is truthy), or the parsed\n * body. Rejects\n */\n _request: function(callback, method, uri, queryParams, data, opts) {\n if (callback !== undefined && !utils.isFunction(callback)) {\n throw Error(\n \"Expected callback to be a function but got \" + typeof callback,\n );\n }\n opts = opts || {};\n\n const self = this;\n if (this.opts.extraParams) {\n for (const key in this.opts.extraParams) {\n if (!this.opts.extraParams.hasOwnProperty(key)) {\n continue;\n }\n queryParams[key] = this.opts.extraParams[key];\n }\n }\n\n const headers = utils.extend({}, opts.headers || {});\n const json = opts.json === undefined ? true : opts.json;\n let bodyParser = opts.bodyParser;\n\n // we handle the json encoding/decoding here, because request and\n // browser-request make a mess of it. Specifically, they attempt to\n // json-decode plain-text error responses, which in turn means that the\n // actual error gets swallowed by a SyntaxError.\n\n if (json) {\n if (data) {\n data = JSON.stringify(data);\n headers['content-type'] = 'application/json';\n }\n\n if (!headers['accept']) {\n headers['accept'] = 'application/json';\n }\n\n if (bodyParser === undefined) {\n bodyParser = function(rawBody) {\n return JSON.parse(rawBody);\n };\n }\n }\n\n const defer = Promise.defer();\n\n let timeoutId;\n let timedOut = false;\n let req;\n const localTimeoutMs = opts.localTimeoutMs || this.opts.localTimeoutMs;\n\n const resetTimeout = () => {\n if (localTimeoutMs) {\n if (timeoutId) {\n callbacks.clearTimeout(timeoutId);\n }\n timeoutId = callbacks.setTimeout(function() {\n timedOut = true;\n if (req && req.abort) {\n req.abort();\n }\n defer.reject(new module.exports.MatrixError({\n error: \"Locally timed out waiting for a response\",\n errcode: \"ORG.MATRIX.JSSDK_TIMEOUT\",\n timeout: localTimeoutMs,\n }));\n }, localTimeoutMs);\n }\n };\n resetTimeout();\n\n const reqPromise = defer.promise;\n\n try {\n req = this.opts.request(\n {\n uri: uri,\n method: method,\n withCredentials: false,\n qs: queryParams,\n body: data,\n json: false,\n timeout: localTimeoutMs,\n headers: opts.headers || {},\n _matrix_opts: this.opts,\n },\n function(err, response, body) {\n if (localTimeoutMs) {\n callbacks.clearTimeout(timeoutId);\n if (timedOut) {\n return; // already rejected promise\n }\n }\n\n const handlerFn = requestCallback(\n defer, callback, self.opts.onlyData,\n bodyParser,\n );\n handlerFn(err, response, body);\n },\n );\n if (req) {\n // This will only work in a browser, where opts.request is the\n // `browser-request` import. Currently `request` does not support progress\n // updates - see https://github.com/request/request/pull/2346.\n // `browser-request` returns an XHRHttpRequest which exposes `onprogress`\n if ('onprogress' in req) {\n req.onprogress = (e) => {\n // Prevent the timeout from rejecting the deferred promise if progress is\n // seen with the request\n resetTimeout();\n };\n }\n\n // FIXME: This is EVIL, but I can't think of a better way to expose\n // abort() operations on underlying HTTP requests :(\n if (req.abort) reqPromise.abort = req.abort.bind(req);\n }\n } catch (ex) {\n defer.reject(ex);\n if (callback) {\n callback(ex);\n }\n }\n return reqPromise;\n },\n};\n\n/*\n * Returns a callback that can be invoked by an HTTP request on completion,\n * that will either resolve or reject the given defer as well as invoke the\n * given userDefinedCallback (if any).\n *\n * HTTP errors are transformed into javascript errors and the deferred is rejected.\n *\n * If bodyParser is given, it is used to transform the body of the successful\n * responses before passing to the defer/callback.\n *\n * If onlyData is true, the defer/callback is invoked with the body of the\n * response, otherwise the result object (with `code` and `data` fields)\n *\n */\nconst requestCallback = function(\n defer, userDefinedCallback, onlyData,\n bodyParser,\n) {\n userDefinedCallback = userDefinedCallback || function() {};\n\n return function(err, response, body) {\n if (!err) {\n try {\n if (response.statusCode >= 400) {\n err = parseErrorResponse(response, body);\n } else if (bodyParser) {\n body = bodyParser(body);\n }\n } catch (e) {\n err = new Error(`Error parsing server response: ${e}`);\n }\n }\n\n if (err) {\n defer.reject(err);\n userDefinedCallback(err);\n } else {\n const res = {\n code: response.statusCode,\n\n // XXX: why do we bother with this? it doesn't work for\n // XMLHttpRequest, so clearly we don't use it.\n headers: response.headers,\n data: body,\n };\n defer.resolve(onlyData ? body : res);\n userDefinedCallback(null, onlyData ? body : res);\n }\n };\n};\n\n/**\n * Attempt to turn an HTTP error response into a Javascript Error.\n *\n * If it is a JSON response, we will parse it into a MatrixError. Otherwise\n * we return a generic Error.\n *\n * @param {XMLHttpRequest|http.IncomingMessage} response response object\n * @param {String} body raw body of the response\n * @returns {Error}\n */\nfunction parseErrorResponse(response, body) {\n const httpStatus = response.statusCode;\n const contentType = getResponseContentType(response);\n\n let err;\n if (contentType) {\n if (contentType.type === 'application/json') {\n err = new module.exports.MatrixError(JSON.parse(body));\n } else if (contentType.type === 'text/plain') {\n err = new Error(`Server returned ${httpStatus} error: ${body}`);\n }\n }\n\n if (!err) {\n err = new Error(`Server returned ${httpStatus} error`);\n }\n err.httpStatus = httpStatus;\n return err;\n}\n\n\n/**\n * extract the Content-Type header from the response object, and\n * parse it to a `{type, parameters}` object.\n *\n * returns null if no content-type header could be found.\n *\n * @param {XMLHttpRequest|http.IncomingMessage} response response object\n * @returns {{type: String, parameters: Object}?} parsed content-type header, or null if not found\n */\nfunction getResponseContentType(response) {\n let contentType;\n if (response.getResponseHeader) {\n // XMLHttpRequest provides getResponseHeader\n contentType = response.getResponseHeader(\"Content-Type\");\n } else if (response.headers) {\n // request provides http.IncomingMessage which has a message.headers map\n contentType = response.headers['content-type'] || null;\n }\n\n if (!contentType) {\n return null;\n }\n\n try {\n return parseContentType(contentType);\n } catch(e) {\n throw new Error(`Error parsing Content-Type '${contentType}': ${e}`);\n }\n}\n\n/**\n * Construct a Matrix error. This is a JavaScript Error with additional\n * information specific to the standard Matrix error response.\n * @constructor\n * @param {Object} errorJson The Matrix error JSON returned from the homeserver.\n * @prop {string} errcode The Matrix 'errcode' value, e.g. \"M_FORBIDDEN\".\n * @prop {string} name Same as MatrixError.errcode but with a default unknown string.\n * @prop {string} message The Matrix 'error' value, e.g. \"Missing token.\"\n * @prop {Object} data The raw Matrix error JSON used to construct this object.\n * @prop {integer} httpStatus The numeric HTTP status code given\n */\nmodule.exports.MatrixError = function MatrixError(errorJson) {\n errorJson = errorJson || {};\n this.errcode = errorJson.errcode;\n this.name = errorJson.errcode || \"Unknown error code\";\n this.message = errorJson.error || \"Unknown message\";\n this.data = errorJson;\n};\nmodule.exports.MatrixError.prototype = Object.create(Error.prototype);\n/** */\nmodule.exports.MatrixError.prototype.constructor = module.exports.MatrixError;\n","/*\nCopyright 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/** @module interactive-auth */\nimport Promise from 'bluebird';\nconst url = require(\"url\");\n\nconst utils = require(\"./utils\");\n\nconst EMAIL_STAGE_TYPE = \"m.login.email.identity\";\nconst MSISDN_STAGE_TYPE = \"m.login.msisdn\";\n\n/**\n * Abstracts the logic used to drive the interactive auth process.\n *\n *

Components implementing an interactive auth flow should instantiate one of\n * these, passing in the necessary callbacks to the constructor. They should\n * then call attemptAuth, which will return a promise which will resolve or\n * reject when the interactive-auth process completes.\n *\n *

Meanwhile, calls will be made to the startAuthStage and doRequest\n * callbacks, and information gathered from the user can be submitted with\n * submitAuthDict.\n *\n * @constructor\n * @alias module:interactive-auth\n *\n * @param {object} opts options object\n *\n * @param {object} opts.matrixClient A matrix client to use for the auth process\n *\n * @param {object?} opts.authData error response from the last request. If\n * null, a request will be made with no auth before starting.\n *\n * @param {function(object?, bool?): module:client.Promise} opts.doRequest\n * called with the new auth dict to submit the request and a flag set\n * to true if this request is a background request. Should return a\n * promise which resolves to the successful response or rejects with a\n * MatrixError.\n *\n * @param {function(string, object?)} opts.stateUpdated\n * called when the status of the UI auth changes, ie. when the state of\n * an auth stage changes of when the auth flow moves to a new stage.\n * The arguments are: the login type (eg m.login.password); and an object\n * which is either an error or an informational object specific to the\n * login type. If the 'errcode' key is defined, the object is an error,\n * and has keys:\n * errcode: string, the textual error code, eg. M_UNKNOWN\n * error: string, human readable string describing the error\n *\n * The login type specific objects are as follows:\n * m.login.email.identity:\n * * emailSid: string, the sid of the active email auth session\n *\n * @param {object?} opts.inputs Inputs provided by the user and used by different\n * stages of the auto process. The inputs provided will affect what flow is chosen.\n *\n * @param {string?} opts.inputs.emailAddress An email address. If supplied, a flow\n * using email verification will be chosen.\n *\n * @param {string?} opts.inputs.phoneCountry An ISO two letter country code. Gives\n * the country that opts.phoneNumber should be resolved relative to.\n *\n * @param {string?} opts.inputs.phoneNumber A phone number. If supplied, a flow\n * using phone number validation will be chosen.\n *\n * @param {string?} opts.sessionId If resuming an existing interactive auth session,\n * the sessionId of that session.\n *\n * @param {string?} opts.clientSecret If resuming an existing interactive auth session,\n * the client secret for that session\n *\n * @param {string?} opts.emailSid If returning from having completed m.login.email.identity\n * auth, the sid for the email verification session.\n *\n */\nfunction InteractiveAuth(opts) {\n this._matrixClient = opts.matrixClient;\n this._data = opts.authData || {};\n this._requestCallback = opts.doRequest;\n // startAuthStage included for backwards compat\n this._stateUpdatedCallback = opts.stateUpdated || opts.startAuthStage;\n this._completionDeferred = null;\n this._inputs = opts.inputs || {};\n\n if (opts.sessionId) this._data.session = opts.sessionId;\n this._clientSecret = opts.clientSecret || this._matrixClient.generateClientSecret();\n this._emailSid = opts.emailSid;\n if (this._emailSid === undefined) this._emailSid = null;\n\n this._currentStage = null;\n}\n\nInteractiveAuth.prototype = {\n /**\n * begin the authentication process.\n *\n * @return {module:client.Promise} which resolves to the response on success,\n * or rejects with the error on failure. Rejects with NoAuthFlowFoundError if\n * no suitable authentication flow can be found\n */\n attemptAuth: function() {\n this._completionDeferred = Promise.defer();\n\n // wrap in a promise so that if _startNextAuthStage\n // throws, it rejects the promise in a consistent way\n return Promise.resolve().then(() => {\n // if we have no flows, try a request (we'll have\n // just a session ID in _data if resuming)\n if (!this._data.flows) {\n this._doRequest(this._data);\n } else {\n this._startNextAuthStage();\n }\n return this._completionDeferred.promise;\n });\n },\n\n /**\n * Poll to check if the auth session or current stage has been\n * completed out-of-band. If so, the attemptAuth promise will\n * be resolved.\n */\n poll: function() {\n if (!this._data.session) return;\n\n let authDict = {};\n if (this._currentStage == EMAIL_STAGE_TYPE) {\n // The email can be validated out-of-band, but we need to provide the\n // creds so the HS can go & check it.\n if (this._emailSid) {\n const idServerParsedUrl = url.parse(\n this._matrixClient.getIdentityServerUrl(),\n );\n authDict = {\n type: EMAIL_STAGE_TYPE,\n threepid_creds: {\n sid: this._emailSid,\n client_secret: this._clientSecret,\n id_server: idServerParsedUrl.host,\n },\n };\n }\n }\n\n this.submitAuthDict(authDict, true);\n },\n\n /**\n * get the auth session ID\n *\n * @return {string} session id\n */\n getSessionId: function() {\n return this._data ? this._data.session : undefined;\n },\n\n /**\n * get the client secret used for validation sessions\n * with the ID server.\n *\n * @return {string} client secret\n */\n getClientSecret: function() {\n return this._clientSecret;\n },\n\n /**\n * get the server params for a given stage\n *\n * @param {string} loginType login type for the stage\n * @return {object?} any parameters from the server for this stage\n */\n getStageParams: function(loginType) {\n let params = {};\n if (this._data && this._data.params) {\n params = this._data.params;\n }\n return params[loginType];\n },\n\n /**\n * submit a new auth dict and fire off the request. This will either\n * make attemptAuth resolve/reject, or cause the startAuthStage callback\n * to be called for a new stage.\n *\n * @param {object} authData new auth dict to send to the server. Should\n * include a `type` propterty denoting the login type, as well as any\n * other params for that stage.\n * @param {bool} background If true, this request failing will not result\n * in the attemptAuth promise being rejected. This can be set to true\n * for requests that just poll to see if auth has been completed elsewhere.\n */\n submitAuthDict: function(authData, background) {\n if (!this._completionDeferred) {\n throw new Error(\"submitAuthDict() called before attemptAuth()\");\n }\n\n // use the sessionid from the last request.\n const auth = {\n session: this._data.session,\n };\n utils.extend(auth, authData);\n\n this._doRequest(auth, background);\n },\n\n /**\n * Gets the sid for the email validation session\n * Specific to m.login.email.identity\n *\n * @returns {string} The sid of the email auth session\n */\n getEmailSid: function() {\n return this._emailSid;\n },\n\n /**\n * Sets the sid for the email validation session\n * This must be set in order to successfully poll for completion\n * of the email validation.\n * Specific to m.login.email.identity\n *\n * @param {string} sid The sid for the email validation session\n */\n setEmailSid: function(sid) {\n this._emailSid = sid;\n },\n\n /**\n * Fire off a request, and either resolve the promise, or call\n * startAuthStage.\n *\n * @private\n * @param {object?} auth new auth dict, including session id\n * @param {bool?} background If true, this request is a background poll, so it\n * failing will not result in the attemptAuth promise being rejected.\n * This can be set to true for requests that just poll to see if auth has\n * been completed elsewhere.\n */\n _doRequest: function(auth, background) {\n const self = this;\n\n // hackery to make sure that synchronous exceptions end up in the catch\n // handler (without the additional event loop entailed by q.fcall or an\n // extra Promise.resolve().then)\n let prom;\n try {\n prom = this._requestCallback(auth, background);\n } catch (e) {\n prom = Promise.reject(e);\n }\n\n prom = prom.then(\n function(result) {\n console.log(\"result from request: \", result);\n self._completionDeferred.resolve(result);\n }, function(error) {\n // sometimes UI auth errors don't come with flows\n const errorFlows = error.data ? error.data.flows : null;\n const haveFlows = Boolean(self._data.flows) || Boolean(errorFlows);\n if (error.httpStatus !== 401 || !error.data || !haveFlows) {\n // doesn't look like an interactive-auth failure. fail the whole lot.\n throw error;\n }\n // if the error didn't come with flows, completed flows or session ID,\n // copy over the ones we have. Synapse sometimes sends responses without\n // any UI auth data (eg. when polling for email validation, if the email\n // has not yet been validated). This appears to be a Synapse bug, which\n // we workaround here.\n if (!error.data.flows && !error.data.completed && !error.data.session) {\n error.data.flows = self._data.flows;\n error.data.completed = self._data.completed;\n error.data.session = self._data.session;\n }\n self._data = error.data;\n self._startNextAuthStage();\n },\n );\n if (!background) {\n prom = prom.catch((e) => {\n this._completionDeferred.reject(e);\n });\n } else {\n // We ignore all failures here (even non-UI auth related ones)\n // since we don't want to suddenly fail if the internet connection\n // had a blip whilst we were polling\n prom = prom.catch((error) => {\n console.log(\"Ignoring error from UI auth: \" + error);\n });\n }\n prom.done();\n },\n\n /**\n * Pick the next stage and call the callback\n *\n * @private\n * @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found\n */\n _startNextAuthStage: function() {\n const nextStage = this._chooseStage();\n if (!nextStage) {\n throw new Error(\"No incomplete flows from the server\");\n }\n this._currentStage = nextStage;\n\n if (nextStage == 'm.login.dummy') {\n this.submitAuthDict({\n type: 'm.login.dummy',\n });\n return;\n }\n\n if (this._data.errcode || this._data.error) {\n this._stateUpdatedCallback(nextStage, {\n errcode: this._data.errcode || \"\",\n error: this._data.error || \"\",\n });\n return;\n }\n\n const stageStatus = {};\n if (nextStage == EMAIL_STAGE_TYPE) {\n stageStatus.emailSid = this._emailSid;\n }\n this._stateUpdatedCallback(nextStage, stageStatus);\n },\n\n /**\n * Pick the next auth stage\n *\n * @private\n * @return {string?} login type\n * @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found\n */\n _chooseStage: function() {\n const flow = this._chooseFlow();\n console.log(\"Active flow => %s\", JSON.stringify(flow));\n const nextStage = this._firstUncompletedStage(flow);\n console.log(\"Next stage: %s\", nextStage);\n return nextStage;\n },\n\n /**\n * Pick one of the flows from the returned list\n * If a flow using all of the inputs is found, it will\n * be returned, otherwise, null will be returned.\n *\n * Only flows using all given inputs are chosen because it\n * is likley to be surprising if the user provides a\n * credential and it is not used. For example, for registration,\n * this could result in the email not being used which would leave\n * the account with no means to reset a password.\n *\n * @private\n * @return {object} flow\n * @throws {NoAuthFlowFoundError} If no suitable authentication flow can be found\n */\n _chooseFlow: function() {\n const flows = this._data.flows || [];\n\n // we've been given an email or we've already done an email part\n const haveEmail = Boolean(this._inputs.emailAddress) || Boolean(this._emailSid);\n const haveMsisdn = (\n Boolean(this._inputs.phoneCountry) &&\n Boolean(this._inputs.phoneNumber)\n );\n\n for (const flow of flows) {\n let flowHasEmail = false;\n let flowHasMsisdn = false;\n for (const stage of flow.stages) {\n if (stage === EMAIL_STAGE_TYPE) {\n flowHasEmail = true;\n } else if (stage == MSISDN_STAGE_TYPE) {\n flowHasMsisdn = true;\n }\n }\n\n if (flowHasEmail == haveEmail && flowHasMsisdn == haveMsisdn) {\n return flow;\n }\n }\n // Throw an error with a fairly generic description, but with more\n // information such that the app can give a better one if so desired.\n const err = new Error(\"No appropriate authentication flow found\");\n err.name = 'NoAuthFlowFoundError';\n err.required_stages = [];\n if (haveEmail) err.required_stages.push(EMAIL_STAGE_TYPE);\n if (haveMsisdn) err.required_stages.push(MSISDN_STAGE_TYPE);\n err.available_flows = flows;\n throw err;\n },\n\n /**\n * Get the first uncompleted stage in the given flow\n *\n * @private\n * @param {object} flow\n * @return {string} login type\n */\n _firstUncompletedStage: function(flow) {\n const completed = (this._data || {}).completed || [];\n for (let i = 0; i < flow.stages.length; ++i) {\n const stageType = flow.stages[i];\n if (completed.indexOf(stageType) === -1) {\n return stageType;\n }\n }\n },\n};\n\n\n/** */\nmodule.exports = InteractiveAuth;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/** The {@link module:models/event.MatrixEvent|MatrixEvent} class. */\nmodule.exports.MatrixEvent = require(\"./models/event\").MatrixEvent;\n/** The {@link module:models/event.EventStatus|EventStatus} enum. */\nmodule.exports.EventStatus = require(\"./models/event\").EventStatus;\n/** The {@link module:store/memory.MatrixInMemoryStore|MatrixInMemoryStore} class. */\nmodule.exports.MatrixInMemoryStore = require(\"./store/memory\").MatrixInMemoryStore;\n/** The {@link module:store/indexeddb.IndexedDBStore|IndexedDBStore} class. */\nmodule.exports.IndexedDBStore = require(\"./store/indexeddb\").IndexedDBStore;\n/** The {@link module:store/indexeddb.IndexedDBStoreBackend|IndexedDBStoreBackend} class. */\nmodule.exports.IndexedDBStoreBackend = require(\"./store/indexeddb\").IndexedDBStoreBackend;\n/** The {@link module:sync-accumulator.SyncAccumulator|SyncAccumulator} class. */\nmodule.exports.SyncAccumulator = require(\"./sync-accumulator\");\n/** The {@link module:http-api.MatrixHttpApi|MatrixHttpApi} class. */\nmodule.exports.MatrixHttpApi = require(\"./http-api\").MatrixHttpApi;\n/** The {@link module:http-api.MatrixError|MatrixError} class. */\nmodule.exports.MatrixError = require(\"./http-api\").MatrixError;\n/** The {@link module:client.MatrixClient|MatrixClient} class. */\nmodule.exports.MatrixClient = require(\"./client\").MatrixClient;\n/** The {@link module:models/room|Room} class. */\nmodule.exports.Room = require(\"./models/room\");\n/** The {@link module:models/event-timeline~EventTimeline} class. */\nmodule.exports.EventTimeline = require(\"./models/event-timeline\");\n/** The {@link module:models/event-timeline-set~EventTimelineSet} class. */\nmodule.exports.EventTimelineSet = require(\"./models/event-timeline-set\");\n/** The {@link module:models/room-member|RoomMember} class. */\nmodule.exports.RoomMember = require(\"./models/room-member\");\n/** The {@link module:models/room-state~RoomState|RoomState} class. */\nmodule.exports.RoomState = require(\"./models/room-state\");\n/** The {@link module:models/user~User|User} class. */\nmodule.exports.User = require(\"./models/user\");\n/** The {@link module:scheduler~MatrixScheduler|MatrixScheduler} class. */\nmodule.exports.MatrixScheduler = require(\"./scheduler\");\n/** The {@link module:store/session/webstorage~WebStorageSessionStore|\n * WebStorageSessionStore} class. Work in progress; unstable. */\nmodule.exports.WebStorageSessionStore = require(\"./store/session/webstorage\");\n/** True if crypto libraries are being used on this client. */\nmodule.exports.CRYPTO_ENABLED = require(\"./client\").CRYPTO_ENABLED;\n/** {@link module:content-repo|ContentRepo} utility functions. */\nmodule.exports.ContentRepo = require(\"./content-repo\");\n/** The {@link module:filter~Filter|Filter} class. */\nmodule.exports.Filter = require(\"./filter\");\n/** The {@link module:timeline-window~TimelineWindow} class. */\nmodule.exports.TimelineWindow = require(\"./timeline-window\").TimelineWindow;\n/** The {@link module:interactive-auth} class. */\nmodule.exports.InteractiveAuth = require(\"./interactive-auth\");\n\n\nmodule.exports.MemoryCryptoStore =\n require(\"./crypto/store/memory-crypto-store\").default;\nmodule.exports.IndexedDBCryptoStore =\n require(\"./crypto/store/indexeddb-crypto-store\").default;\n\n/**\n * Create a new Matrix Call.\n * @function\n * @param {module:client.MatrixClient} client The MatrixClient instance to use.\n * @param {string} roomId The room the call is in.\n * @return {module:webrtc/call~MatrixCall} The Matrix call or null if the browser\n * does not support WebRTC.\n */\nmodule.exports.createNewMatrixCall = require(\"./webrtc/call\").createNewMatrixCall;\n\n\n/**\n * Set an audio input device to use for MatrixCalls\n * @function\n * @param {string=} deviceId the identifier for the device\n * undefined treated as unset\n */\nmodule.exports.setMatrixCallAudioInput = require('./webrtc/call').setAudioInput;\n/**\n * Set a video input device to use for MatrixCalls\n * @function\n * @param {string=} deviceId the identifier for the device\n * undefined treated as unset\n */\nmodule.exports.setMatrixCallVideoInput = require('./webrtc/call').setVideoInput;\n\n\n// expose the underlying request object so different environments can use\n// different request libs (e.g. request or browser-request)\nlet request;\n/**\n * The function used to perform HTTP requests. Only use this if you want to\n * use a different HTTP library, e.g. Angular's $http. This should\n * be set prior to calling {@link createClient}.\n * @param {requestFunction} r The request function to use.\n */\nmodule.exports.request = function(r) {\n request = r;\n};\n\n/**\n * Return the currently-set request function.\n * @return {requestFunction} The current request function.\n */\nmodule.exports.getRequest = function() {\n return request;\n};\n\n/**\n * Apply wrapping code around the request function. The wrapper function is\n * installed as the new request handler, and when invoked it is passed the\n * previous value, along with the options and callback arguments.\n * @param {requestWrapperFunction} wrapper The wrapping function.\n */\nmodule.exports.wrapRequest = function(wrapper) {\n const origRequest = request;\n request = function(options, callback) {\n return wrapper(origRequest, options, callback);\n };\n};\n\n\nlet cryptoStoreFactory = () => new module.exports.MemoryCryptoStore;\n\n/**\n * Configure a different factory to be used for creating crypto stores\n *\n * @param {Function} fac a function which will return a new\n * {@link module:crypto.store.base~CryptoStore}.\n */\nmodule.exports.setCryptoStoreFactory = function(fac) {\n cryptoStoreFactory = fac;\n};\n\n/**\n * Construct a Matrix Client. Similar to {@link module:client~MatrixClient}\n * except that the 'request', 'store' and 'scheduler' dependencies are satisfied.\n * @param {(Object|string)} opts The configuration options for this client. If\n * this is a string, it is assumed to be the base URL. These configuration\n * options will be passed directly to {@link module:client~MatrixClient}.\n * @param {Object} opts.store If not set, defaults to\n * {@link module:store/memory.MatrixInMemoryStore}.\n * @param {Object} opts.scheduler If not set, defaults to\n * {@link module:scheduler~MatrixScheduler}.\n * @param {requestFunction} opts.request If not set, defaults to the function\n * supplied to {@link request} which defaults to the request module from NPM.\n *\n * @param {module:crypto.store.base~CryptoStore=} opts.cryptoStore\n * crypto store implementation. Calls the factory supplied to\n * {@link setCryptoStoreFactory} if unspecified; or if no factory has been\n * specified, uses a default implementation (indexeddb in the browser,\n * in-memory otherwise).\n *\n * @return {MatrixClient} A new matrix client.\n * @see {@link module:client~MatrixClient} for the full list of options for\n * opts.\n */\nmodule.exports.createClient = function(opts) {\n if (typeof opts === \"string\") {\n opts = {\n \"baseUrl\": opts,\n };\n }\n opts.request = opts.request || request;\n opts.store = opts.store || new module.exports.MatrixInMemoryStore({\n localStorage: global.localStorage,\n });\n opts.scheduler = opts.scheduler || new module.exports.MatrixScheduler();\n opts.cryptoStore = opts.cryptoStore || cryptoStoreFactory();\n return new module.exports.MatrixClient(opts);\n};\n\n/**\n * The request function interface for performing HTTP requests. This matches the\n * API for the {@link https://github.com/request/request#requestoptions-callback|\n * request NPM module}. The SDK will attempt to call this function in order to\n * perform an HTTP request.\n * @callback requestFunction\n * @param {Object} opts The options for this HTTP request.\n * @param {string} opts.uri The complete URI.\n * @param {string} opts.method The HTTP method.\n * @param {Object} opts.qs The query parameters to append to the URI.\n * @param {Object} opts.body The JSON-serializable object.\n * @param {boolean} opts.json True if this is a JSON request.\n * @param {Object} opts._matrix_opts The underlying options set for\n * {@link MatrixHttpApi}.\n * @param {requestCallback} callback The request callback.\n */\n\n/**\n * A wrapper for the request function interface.\n * @callback requestWrapperFunction\n * @param {requestFunction} origRequest The underlying request function being\n * wrapped\n * @param {Object} opts The options for this HTTP request, given in the same\n * form as {@link requestFunction}.\n * @param {requestCallback} callback The request callback.\n */\n\n /**\n * The request callback interface for performing HTTP requests. This matches the\n * API for the {@link https://github.com/request/request#requestoptions-callback|\n * request NPM module}. The SDK will implement a callback which meets this\n * interface in order to handle the HTTP response.\n * @callback requestCallback\n * @param {Error} err The error if one occurred, else falsey.\n * @param {Object} response The HTTP response which consists of\n * {statusCode: {Number}, headers: {Object}}\n * @param {Object} body The parsed HTTP response body.\n */\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * @module models/event-context\n */\n\n/**\n * Construct a new EventContext\n *\n * An eventcontext is used for circumstances such as search results, when we\n * have a particular event of interest, and a bunch of events before and after\n * it.\n *\n * It also stores pagination tokens for going backwards and forwards in the\n * timeline.\n *\n * @param {MatrixEvent} ourEvent the event at the centre of this context\n *\n * @constructor\n */\nfunction EventContext(ourEvent) {\n this._timeline = [ourEvent];\n this._ourEventIndex = 0;\n this._paginateTokens = {b: null, f: null};\n\n // this is used by MatrixClient to keep track of active requests\n this._paginateRequests = {b: null, f: null};\n}\n\n/**\n * Get the main event of interest\n *\n * This is a convenience function for getTimeline()[getOurEventIndex()].\n *\n * @return {MatrixEvent} The event at the centre of this context.\n */\nEventContext.prototype.getEvent = function() {\n return this._timeline[this._ourEventIndex];\n};\n\n/**\n * Get the list of events in this context\n *\n * @return {Array} An array of MatrixEvents\n */\nEventContext.prototype.getTimeline = function() {\n return this._timeline;\n};\n\n/**\n * Get the index in the timeline of our event\n *\n * @return {Number}\n */\nEventContext.prototype.getOurEventIndex = function() {\n return this._ourEventIndex;\n};\n\n/**\n * Get a pagination token.\n *\n * @param {boolean} backwards true to get the pagination token for going\n * backwards in time\n * @return {string}\n */\nEventContext.prototype.getPaginateToken = function(backwards) {\n return this._paginateTokens[backwards ? 'b' : 'f'];\n};\n\n/**\n * Set a pagination token.\n *\n * Generally this will be used only by the matrix js sdk.\n *\n * @param {string} token pagination token\n * @param {boolean} backwards true to set the pagination token for going\n * backwards in time\n */\nEventContext.prototype.setPaginateToken = function(token, backwards) {\n this._paginateTokens[backwards ? 'b' : 'f'] = token;\n};\n\n/**\n * Add more events to the timeline\n *\n * @param {Array} events new events, in timeline order\n * @param {boolean} atStart true to insert new events at the start\n */\nEventContext.prototype.addEvents = function(events, atStart) {\n // TODO: should we share logic with Room.addEventsToTimeline?\n // Should Room even use EventContext?\n\n if (atStart) {\n this._timeline = events.concat(this._timeline);\n this._ourEventIndex += events.length;\n } else {\n this._timeline = this._timeline.concat(events);\n }\n};\n\n/**\n * The EventContext class\n */\nmodule.exports = EventContext;\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * @module models/event-timeline-set\n */\nconst EventEmitter = require(\"events\").EventEmitter;\nconst utils = require(\"../utils\");\nconst EventTimeline = require(\"./event-timeline\");\n\n// var DEBUG = false;\nconst DEBUG = true;\n\nlet debuglog;\nif (DEBUG) {\n // using bind means that we get to keep useful line numbers in the console\n debuglog = console.log.bind(console);\n} else {\n debuglog = function() {};\n}\n\n/**\n * Construct a set of EventTimeline objects, typically on behalf of a given\n * room. A room may have multiple EventTimelineSets for different levels\n * of filtering. The global notification list is also an EventTimelineSet, but\n * lacks a room.\n *\n *

This is an ordered sequence of timelines, which may or may not\n * be continuous. Each timeline lists a series of events, as well as tracking\n * the room state at the start and the end of the timeline (if appropriate).\n * It also tracks forward and backward pagination tokens, as well as containing\n * links to the next timeline in the sequence.\n *\n *

There is one special timeline - the 'live' timeline, which represents the\n * timeline to which events are being added in real-time as they are received\n * from the /sync API. Note that you should not retain references to this\n * timeline - even if it is the current timeline right now, it may not remain\n * so if the server gives us a timeline gap in /sync.\n *\n *

In order that we can find events from their ids later, we also maintain a\n * map from event_id to timeline and index.\n *\n * @constructor\n * @param {?Room} room the optional room for this timelineSet\n * @param {Object} opts hash of options inherited from Room.\n * opts.timelineSupport gives whether timeline support is enabled\n * opts.filter is the filter object, if any, for this timelineSet.\n */\nfunction EventTimelineSet(room, opts) {\n this.room = room;\n\n this._timelineSupport = Boolean(opts.timelineSupport);\n this._liveTimeline = new EventTimeline(this);\n\n // just a list - *not* ordered.\n this._timelines = [this._liveTimeline];\n this._eventIdToTimeline = {};\n\n this._filter = opts.filter || null;\n}\nutils.inherits(EventTimelineSet, EventEmitter);\n\n/**\n * Get the filter object this timeline set is filtered on, if any\n * @return {?Filter} the optional filter for this timelineSet\n */\nEventTimelineSet.prototype.getFilter = function() {\n return this._filter;\n};\n\n/**\n * Set the filter object this timeline set is filtered on\n * (passed to the server when paginating via /messages).\n * @param {Filter} filter the filter for this timelineSet\n */\nEventTimelineSet.prototype.setFilter = function(filter) {\n this._filter = filter;\n};\n\n/**\n * Get the list of pending sent events for this timelineSet's room, filtered\n * by the timelineSet's filter if appropriate.\n *\n * @return {module:models/event.MatrixEvent[]} A list of the sent events\n * waiting for remote echo.\n *\n * @throws If opts.pendingEventOrdering was not 'detached'\n */\nEventTimelineSet.prototype.getPendingEvents = function() {\n if (!this.room) {\n return [];\n }\n\n if (this._filter) {\n return this._filter.filterRoomTimeline(this.room.getPendingEvents());\n } else {\n return this.room.getPendingEvents();\n }\n};\n\n/**\n * Get the live timeline for this room.\n *\n * @return {module:models/event-timeline~EventTimeline} live timeline\n */\nEventTimelineSet.prototype.getLiveTimeline = function() {\n return this._liveTimeline;\n};\n\n/**\n * Return the timeline (if any) this event is in.\n * @param {String} eventId the eventId being sought\n * @return {module:models/event-timeline~EventTimeline} timeline\n */\nEventTimelineSet.prototype.eventIdToTimeline = function(eventId) {\n return this._eventIdToTimeline[eventId];\n};\n\n/**\n * Track a new event as if it were in the same timeline as an old event,\n * replacing it.\n * @param {String} oldEventId event ID of the original event\n * @param {String} newEventId event ID of the replacement event\n */\nEventTimelineSet.prototype.replaceEventId = function(oldEventId, newEventId) {\n const existingTimeline = this._eventIdToTimeline[oldEventId];\n if (existingTimeline) {\n delete this._eventIdToTimeline[oldEventId];\n this._eventIdToTimeline[newEventId] = existingTimeline;\n }\n};\n\n/**\n * Reset the live timeline, and start a new one.\n *\n *

This is used when /sync returns a 'limited' timeline.\n *\n * @param {string=} backPaginationToken token for back-paginating the new timeline\n * @param {string=} forwardPaginationToken token for forward-paginating the old live timeline,\n * if absent or null, all timelines are reset.\n *\n * @fires module:client~MatrixClient#event:\"Room.timelineReset\"\n */\nEventTimelineSet.prototype.resetLiveTimeline = function(\n backPaginationToken, forwardPaginationToken,\n) {\n // Each EventTimeline has RoomState objects tracking the state at the start\n // and end of that timeline. The copies at the end of the live timeline are\n // special because they will have listeners attached to monitor changes to\n // the current room state, so we move this RoomState from the end of the\n // current live timeline to the end of the new one and, if necessary,\n // replace it with a newly created one. We also make a copy for the start\n // of the new timeline.\n\n // if timeline support is disabled, forget about the old timelines\n const resetAllTimelines = !this._timelineSupport || !forwardPaginationToken;\n\n let newTimeline;\n if (resetAllTimelines) {\n newTimeline = new EventTimeline(this);\n this._timelines = [newTimeline];\n this._eventIdToTimeline = {};\n } else {\n newTimeline = this.addTimeline();\n }\n\n const oldTimeline = this._liveTimeline;\n\n // Collect the state events from the old timeline\n const evMap = oldTimeline.getState(EventTimeline.FORWARDS).events;\n const events = [];\n for (const evtype in evMap) {\n if (!evMap.hasOwnProperty(evtype)) {\n continue;\n }\n for (const stateKey in evMap[evtype]) {\n if (!evMap[evtype].hasOwnProperty(stateKey)) {\n continue;\n }\n events.push(evMap[evtype][stateKey]);\n }\n }\n\n // Use those events to initialise the state of the new live timeline\n newTimeline.initialiseState(events);\n\n const freshEndState = newTimeline._endState;\n // Now clobber the end state of the new live timeline with that from the\n // previous live timeline. It will be identical except that we'll keep\n // using the same RoomMember objects for the 'live' set of members with any\n // listeners still attached\n newTimeline._endState = oldTimeline._endState;\n\n // If we're not resetting all timelines, we need to fix up the old live timeline\n if (!resetAllTimelines) {\n // Firstly, we just stole the old timeline's end state, so it needs a new one.\n // Just swap them around and give it the one we just generated for the\n // new live timeline.\n oldTimeline._endState = freshEndState;\n\n // Now set the forward pagination token on the old live timeline\n // so it can be forward-paginated.\n oldTimeline.setPaginationToken(\n forwardPaginationToken, EventTimeline.FORWARDS,\n );\n }\n\n // make sure we set the pagination token before firing timelineReset,\n // otherwise clients which start back-paginating will fail, and then get\n // stuck without realising that they *can* back-paginate.\n newTimeline.setPaginationToken(backPaginationToken, EventTimeline.BACKWARDS);\n\n // Now we can swap the live timeline to the new one.\n this._liveTimeline = newTimeline;\n this.emit(\"Room.timelineReset\", this.room, this, resetAllTimelines);\n};\n\n/**\n * Get the timeline which contains the given event, if any\n *\n * @param {string} eventId event ID to look for\n * @return {?module:models/event-timeline~EventTimeline} timeline containing\n * the given event, or null if unknown\n */\nEventTimelineSet.prototype.getTimelineForEvent = function(eventId) {\n const res = this._eventIdToTimeline[eventId];\n return (res === undefined) ? null : res;\n};\n\n/**\n * Get an event which is stored in our timelines\n *\n * @param {string} eventId event ID to look for\n * @return {?module:models/event~MatrixEvent} the given event, or undefined if unknown\n */\nEventTimelineSet.prototype.findEventById = function(eventId) {\n const tl = this.getTimelineForEvent(eventId);\n if (!tl) {\n return undefined;\n }\n return utils.findElement(tl.getEvents(), function(ev) {\n return ev.getId() == eventId;\n });\n};\n\n/**\n * Add a new timeline to this timeline list\n *\n * @return {module:models/event-timeline~EventTimeline} newly-created timeline\n */\nEventTimelineSet.prototype.addTimeline = function() {\n if (!this._timelineSupport) {\n throw new Error(\"timeline support is disabled. Set the 'timelineSupport'\" +\n \" parameter to true when creating MatrixClient to enable\" +\n \" it.\");\n }\n\n const timeline = new EventTimeline(this);\n this._timelines.push(timeline);\n return timeline;\n};\n\n\n/**\n * Add events to a timeline\n *\n *

Will fire \"Room.timeline\" for each event added.\n *\n * @param {MatrixEvent[]} events A list of events to add.\n *\n * @param {boolean} toStartOfTimeline True to add these events to the start\n * (oldest) instead of the end (newest) of the timeline. If true, the oldest\n * event will be the last element of 'events'.\n *\n * @param {module:models/event-timeline~EventTimeline} timeline timeline to\n * add events to.\n *\n * @param {string=} paginationToken token for the next batch of events\n *\n * @fires module:client~MatrixClient#event:\"Room.timeline\"\n *\n */\nEventTimelineSet.prototype.addEventsToTimeline = function(events, toStartOfTimeline,\n timeline, paginationToken) {\n if (!timeline) {\n throw new Error(\n \"'timeline' not specified for EventTimelineSet.addEventsToTimeline\",\n );\n }\n\n if (!toStartOfTimeline && timeline == this._liveTimeline) {\n throw new Error(\n \"EventTimelineSet.addEventsToTimeline cannot be used for adding events to \" +\n \"the live timeline - use Room.addLiveEvents instead\",\n );\n }\n\n if (this._filter) {\n events = this._filter.filterRoomTimeline(events);\n if (!events.length) {\n return;\n }\n }\n\n const direction = toStartOfTimeline ? EventTimeline.BACKWARDS :\n EventTimeline.FORWARDS;\n const inverseDirection = toStartOfTimeline ? EventTimeline.FORWARDS :\n EventTimeline.BACKWARDS;\n\n // Adding events to timelines can be quite complicated. The following\n // illustrates some of the corner-cases.\n //\n // Let's say we start by knowing about four timelines. timeline3 and\n // timeline4 are neighbours:\n //\n // timeline1 timeline2 timeline3 timeline4\n // [M] [P] [S] <------> [T]\n //\n // Now we paginate timeline1, and get the following events from the server:\n // [M, N, P, R, S, T, U].\n //\n // 1. First, we ignore event M, since we already know about it.\n //\n // 2. Next, we append N to timeline 1.\n //\n // 3. Next, we don't add event P, since we already know about it,\n // but we do link together the timelines. We now have:\n //\n // timeline1 timeline2 timeline3 timeline4\n // [M, N] <---> [P] [S] <------> [T]\n //\n // 4. Now we add event R to timeline2:\n //\n // timeline1 timeline2 timeline3 timeline4\n // [M, N] <---> [P, R] [S] <------> [T]\n //\n // Note that we have switched the timeline we are working on from\n // timeline1 to timeline2.\n //\n // 5. We ignore event S, but again join the timelines:\n //\n // timeline1 timeline2 timeline3 timeline4\n // [M, N] <---> [P, R] <---> [S] <------> [T]\n //\n // 6. We ignore event T, and the timelines are already joined, so there\n // is nothing to do.\n //\n // 7. Finally, we add event U to timeline4:\n //\n // timeline1 timeline2 timeline3 timeline4\n // [M, N] <---> [P, R] <---> [S] <------> [T, U]\n //\n // The important thing to note in the above is what happened when we\n // already knew about a given event:\n //\n // - if it was appropriate, we joined up the timelines (steps 3, 5).\n // - in any case, we started adding further events to the timeline which\n // contained the event we knew about (steps 3, 5, 6).\n //\n //\n // So much for adding events to the timeline. But what do we want to do\n // with the pagination token?\n //\n // In the case above, we will be given a pagination token which tells us how to\n // get events beyond 'U' - in this case, it makes sense to store this\n // against timeline4. But what if timeline4 already had 'U' and beyond? in\n // that case, our best bet is to throw away the pagination token we were\n // given and stick with whatever token timeline4 had previously. In short,\n // we want to only store the pagination token if the last event we receive\n // is one we didn't previously know about.\n //\n // We make an exception for this if it turns out that we already knew about\n // *all* of the events, and we weren't able to join up any timelines. When\n // that happens, it means our existing pagination token is faulty, since it\n // is only telling us what we already know. Rather than repeatedly\n // paginating with the same token, we might as well use the new pagination\n // token in the hope that we eventually work our way out of the mess.\n\n let didUpdate = false;\n let lastEventWasNew = false;\n for (let i = 0; i < events.length; i++) {\n const event = events[i];\n const eventId = event.getId();\n\n const existingTimeline = this._eventIdToTimeline[eventId];\n\n if (!existingTimeline) {\n // we don't know about this event yet. Just add it to the timeline.\n this.addEventToTimeline(event, timeline, toStartOfTimeline);\n lastEventWasNew = true;\n didUpdate = true;\n continue;\n }\n\n lastEventWasNew = false;\n\n if (existingTimeline == timeline) {\n debuglog(\"Event \" + eventId + \" already in timeline \" + timeline);\n continue;\n }\n\n const neighbour = timeline.getNeighbouringTimeline(direction);\n if (neighbour) {\n // this timeline already has a neighbour in the relevant direction;\n // let's assume the timelines are already correctly linked up, and\n // skip over to it.\n //\n // there's probably some edge-case here where we end up with an\n // event which is in a timeline a way down the chain, and there is\n // a break in the chain somewhere. But I can't really imagine how\n // that would happen, so I'm going to ignore it for now.\n //\n if (existingTimeline == neighbour) {\n debuglog(\"Event \" + eventId + \" in neighbouring timeline - \" +\n \"switching to \" + existingTimeline);\n } else {\n debuglog(\"Event \" + eventId + \" already in a different \" +\n \"timeline \" + existingTimeline);\n }\n timeline = existingTimeline;\n continue;\n }\n\n // time to join the timelines.\n console.info(\"Already have timeline for \" + eventId +\n \" - joining timeline \" + timeline + \" to \" +\n existingTimeline);\n timeline.setNeighbouringTimeline(existingTimeline, direction);\n existingTimeline.setNeighbouringTimeline(timeline, inverseDirection);\n timeline = existingTimeline;\n didUpdate = true;\n }\n\n // see above - if the last event was new to us, or if we didn't find any\n // new information, we update the pagination token for whatever\n // timeline we ended up on.\n if (lastEventWasNew || !didUpdate) {\n timeline.setPaginationToken(paginationToken, direction);\n }\n};\n\n/**\n * Add an event to the end of this live timeline.\n *\n * @param {MatrixEvent} event Event to be added\n * @param {string?} duplicateStrategy 'ignore' or 'replace'\n */\nEventTimelineSet.prototype.addLiveEvent = function(event, duplicateStrategy) {\n if (this._filter) {\n const events = this._filter.filterRoomTimeline([event]);\n if (!events.length) {\n return;\n }\n }\n\n const timeline = this._eventIdToTimeline[event.getId()];\n if (timeline) {\n if (duplicateStrategy === \"replace\") {\n debuglog(\"EventTimelineSet.addLiveEvent: replacing duplicate event \" +\n event.getId());\n const tlEvents = timeline.getEvents();\n for (let j = 0; j < tlEvents.length; j++) {\n if (tlEvents[j].getId() === event.getId()) {\n // still need to set the right metadata on this event\n EventTimeline.setEventMetadata(\n event,\n timeline.getState(EventTimeline.FORWARDS),\n false,\n );\n\n if (!tlEvents[j].encryptedType) {\n tlEvents[j] = event;\n }\n\n // XXX: we need to fire an event when this happens.\n break;\n }\n }\n } else {\n debuglog(\"EventTimelineSet.addLiveEvent: ignoring duplicate event \" +\n event.getId());\n }\n return;\n }\n\n this.addEventToTimeline(event, this._liveTimeline, false);\n};\n\n/**\n * Add event to the given timeline, and emit Room.timeline. Assumes\n * we have already checked we don't know about this event.\n *\n * Will fire \"Room.timeline\" for each event added.\n *\n * @param {MatrixEvent} event\n * @param {EventTimeline} timeline\n * @param {boolean} toStartOfTimeline\n *\n * @fires module:client~MatrixClient#event:\"Room.timeline\"\n */\nEventTimelineSet.prototype.addEventToTimeline = function(event, timeline,\n toStartOfTimeline) {\n const eventId = event.getId();\n timeline.addEvent(event, toStartOfTimeline);\n this._eventIdToTimeline[eventId] = timeline;\n\n const data = {\n timeline: timeline,\n liveEvent: !toStartOfTimeline && timeline == this._liveTimeline,\n };\n this.emit(\"Room.timeline\", event, this.room,\n Boolean(toStartOfTimeline), false, data);\n};\n\n/**\n * Replaces event with ID oldEventId with one with newEventId, if oldEventId is\n * recognised. Otherwise, add to the live timeline. Used to handle remote echos.\n *\n * @param {MatrixEvent} localEvent the new event to be added to the timeline\n * @param {String} oldEventId the ID of the original event\n * @param {boolean} newEventId the ID of the replacement event\n *\n * @fires module:client~MatrixClient#event:\"Room.timeline\"\n */\nEventTimelineSet.prototype.handleRemoteEcho = function(localEvent, oldEventId,\n newEventId) {\n // XXX: why don't we infer newEventId from localEvent?\n const existingTimeline = this._eventIdToTimeline[oldEventId];\n if (existingTimeline) {\n delete this._eventIdToTimeline[oldEventId];\n this._eventIdToTimeline[newEventId] = existingTimeline;\n } else {\n if (this._filter) {\n if (this._filter.filterRoomTimeline([localEvent]).length) {\n this.addEventToTimeline(localEvent, this._liveTimeline, false);\n }\n } else {\n this.addEventToTimeline(localEvent, this._liveTimeline, false);\n }\n }\n};\n\n/**\n * Removes a single event from this room.\n *\n * @param {String} eventId The id of the event to remove\n *\n * @return {?MatrixEvent} the removed event, or null if the event was not found\n * in this room.\n */\nEventTimelineSet.prototype.removeEvent = function(eventId) {\n const timeline = this._eventIdToTimeline[eventId];\n if (!timeline) {\n return null;\n }\n\n const removed = timeline.removeEvent(eventId);\n if (removed) {\n delete this._eventIdToTimeline[eventId];\n const data = {\n timeline: timeline,\n };\n this.emit(\"Room.timeline\", removed, this.room, undefined, true, data);\n }\n return removed;\n};\n\n/**\n * Determine where two events appear in the timeline relative to one another\n *\n * @param {string} eventId1 The id of the first event\n * @param {string} eventId2 The id of the second event\n\n * @return {?number} a number less than zero if eventId1 precedes eventId2, and\n * greater than zero if eventId1 succeeds eventId2. zero if they are the\n * same event; null if we can't tell (either because we don't know about one\n * of the events, or because they are in separate timelines which don't join\n * up).\n */\nEventTimelineSet.prototype.compareEventOrdering = function(eventId1, eventId2) {\n if (eventId1 == eventId2) {\n // optimise this case\n return 0;\n }\n\n const timeline1 = this._eventIdToTimeline[eventId1];\n const timeline2 = this._eventIdToTimeline[eventId2];\n\n if (timeline1 === undefined) {\n return null;\n }\n if (timeline2 === undefined) {\n return null;\n }\n\n if (timeline1 === timeline2) {\n // both events are in the same timeline - figure out their\n // relative indices\n let idx1, idx2;\n const events = timeline1.getEvents();\n for (let idx = 0; idx < events.length &&\n (idx1 === undefined || idx2 === undefined); idx++) {\n const evId = events[idx].getId();\n if (evId == eventId1) {\n idx1 = idx;\n }\n if (evId == eventId2) {\n idx2 = idx;\n }\n }\n return idx1 - idx2;\n }\n\n // the events are in different timelines. Iterate through the\n // linkedlist to see which comes first.\n\n // first work forwards from timeline1\n let tl = timeline1;\n while (tl) {\n if (tl === timeline2) {\n // timeline1 is before timeline2\n return -1;\n }\n tl = tl.getNeighbouringTimeline(EventTimeline.FORWARDS);\n }\n\n // now try backwards from timeline1\n tl = timeline1;\n while (tl) {\n if (tl === timeline2) {\n // timeline2 is before timeline1\n return 1;\n }\n tl = tl.getNeighbouringTimeline(EventTimeline.BACKWARDS);\n }\n\n // the timelines are not contiguous.\n return null;\n};\n\n/**\n * The EventTimelineSet class.\n */\nmodule.exports = EventTimelineSet;\n\n/**\n * Fires whenever the timeline in a room is updated.\n * @event module:client~MatrixClient#\"Room.timeline\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {?Room} room The room, if any, whose timeline was updated.\n * @param {boolean} toStartOfTimeline True if this event was added to the start\n * @param {boolean} removed True if this event has just been removed from the timeline\n * (beginning; oldest) of the timeline e.g. due to pagination.\n *\n * @param {object} data more data about the event\n *\n * @param {module:event-timeline.EventTimeline} data.timeline the timeline the\n * event was added to/removed from\n *\n * @param {boolean} data.liveEvent true if the event was a real-time event\n * added to the end of the live timeline\n *\n * @example\n * matrixClient.on(\"Room.timeline\",\n * function(event, room, toStartOfTimeline, removed, data) {\n * if (!toStartOfTimeline && data.liveEvent) {\n * var messageToAppend = room.timeline.[room.timeline.length - 1];\n * }\n * });\n */\n\n/**\n * Fires whenever the live timeline in a room is reset.\n *\n * When we get a 'limited' sync (for example, after a network outage), we reset\n * the live timeline to be empty before adding the recent events to the new\n * timeline. This event is fired after the timeline is reset, and before the\n * new events are added.\n *\n * @event module:client~MatrixClient#\"Room.timelineReset\"\n * @param {Room} room The room whose live timeline was reset, if any\n * @param {EventTimelineSet} timelineSet timelineSet room whose live timeline was reset\n * @param {boolean} resetAllTimelines True if all timelines were reset.\n */\n","/*\nCopyright 2016, 2017 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * @module models/event-timeline\n */\n\nconst RoomState = require(\"./room-state\");\nconst utils = require(\"../utils\");\nconst MatrixEvent = require(\"./event\").MatrixEvent;\n\n/**\n * Construct a new EventTimeline\n *\n *

An EventTimeline represents a contiguous sequence of events in a room.\n *\n *

As well as keeping track of the events themselves, it stores the state of\n * the room at the beginning and end of the timeline, and pagination tokens for\n * going backwards and forwards in the timeline.\n *\n *

In order that clients can meaningfully maintain an index into a timeline,\n * the EventTimeline object tracks a 'baseIndex'. This starts at zero, but is\n * incremented when events are prepended to the timeline. The index of an event\n * relative to baseIndex therefore remains constant.\n *\n *

Once a timeline joins up with its neighbour, they are linked together into a\n * doubly-linked list.\n *\n * @param {EventTimelineSet} eventTimelineSet the set of timelines this is part of\n * @constructor\n */\nfunction EventTimeline(eventTimelineSet) {\n this._eventTimelineSet = eventTimelineSet;\n this._roomId = eventTimelineSet.room ? eventTimelineSet.room.roomId : null;\n this._events = [];\n this._baseIndex = 0;\n this._startState = new RoomState(this._roomId);\n this._startState.paginationToken = null;\n this._endState = new RoomState(this._roomId);\n this._endState.paginationToken = null;\n\n this._prevTimeline = null;\n this._nextTimeline = null;\n\n // this is used by client.js\n this._paginationRequests = {'b': null, 'f': null};\n\n this._name = this._roomId + \":\" + new Date().toISOString();\n}\n\n/**\n * Symbolic constant for methods which take a 'direction' argument:\n * refers to the start of the timeline, or backwards in time.\n */\nEventTimeline.BACKWARDS = \"b\";\n\n/**\n * Symbolic constant for methods which take a 'direction' argument:\n * refers to the end of the timeline, or forwards in time.\n */\nEventTimeline.FORWARDS = \"f\";\n\n/**\n * Initialise the start and end state with the given events\n *\n *

This can only be called before any events are added.\n *\n * @param {MatrixEvent[]} stateEvents list of state events to initialise the\n * state with.\n * @throws {Error} if an attempt is made to call this after addEvent is called.\n */\nEventTimeline.prototype.initialiseState = function(stateEvents) {\n if (this._events.length > 0) {\n throw new Error(\"Cannot initialise state after events are added\");\n }\n\n // we deep-copy the events here, in case they get changed later - we don't\n // want changes to the start state leaking through to the end state.\n const oldStateEvents = utils.map(\n utils.deepCopy(\n stateEvents.map(function(mxEvent) {\n return mxEvent.event;\n }),\n ),\n function(ev) {\n return new MatrixEvent(ev);\n });\n\n this._startState.setStateEvents(oldStateEvents);\n this._endState.setStateEvents(stateEvents);\n};\n\n/**\n * Get the ID of the room for this timeline\n * @return {string} room ID\n */\nEventTimeline.prototype.getRoomId = function() {\n return this._roomId;\n};\n\n/**\n * Get the filter for this timeline's timelineSet (if any)\n * @return {Filter} filter\n */\nEventTimeline.prototype.getFilter = function() {\n return this._eventTimelineSet.getFilter();\n};\n\n/**\n * Get the timelineSet for this timeline\n * @return {EventTimelineSet} timelineSet\n */\nEventTimeline.prototype.getTimelineSet = function() {\n return this._eventTimelineSet;\n};\n\n/**\n * Get the base index.\n *\n *

This is an index which is incremented when events are prepended to the\n * timeline. An individual event therefore stays at the same index in the array\n * relative to the base index (although note that a given event's index may\n * well be less than the base index, thus giving that event a negative relative\n * index).\n *\n * @return {number}\n */\nEventTimeline.prototype.getBaseIndex = function() {\n return this._baseIndex;\n};\n\n/**\n * Get the list of events in this context\n *\n * @return {MatrixEvent[]} An array of MatrixEvents\n */\nEventTimeline.prototype.getEvents = function() {\n return this._events;\n};\n\n/**\n * Get the room state at the start/end of the timeline\n *\n * @param {string} direction EventTimeline.BACKWARDS to get the state at the\n * start of the timeline; EventTimeline.FORWARDS to get the state at the end\n * of the timeline.\n *\n * @return {RoomState} state at the start/end of the timeline\n */\nEventTimeline.prototype.getState = function(direction) {\n if (direction == EventTimeline.BACKWARDS) {\n return this._startState;\n } else if (direction == EventTimeline.FORWARDS) {\n return this._endState;\n } else {\n throw new Error(\"Invalid direction '\" + direction + \"'\");\n }\n};\n\n/**\n * Get a pagination token\n *\n * @param {string} direction EventTimeline.BACKWARDS to get the pagination\n * token for going backwards in time; EventTimeline.FORWARDS to get the\n * pagination token for going forwards in time.\n *\n * @return {?string} pagination token\n */\nEventTimeline.prototype.getPaginationToken = function(direction) {\n return this.getState(direction).paginationToken;\n};\n\n/**\n * Set a pagination token\n *\n * @param {?string} token pagination token\n *\n * @param {string} direction EventTimeline.BACKWARDS to set the pagination\n * token for going backwards in time; EventTimeline.FORWARDS to set the\n * pagination token for going forwards in time.\n */\nEventTimeline.prototype.setPaginationToken = function(token, direction) {\n this.getState(direction).paginationToken = token;\n};\n\n/**\n * Get the next timeline in the series\n *\n * @param {string} direction EventTimeline.BACKWARDS to get the previous\n * timeline; EventTimeline.FORWARDS to get the next timeline.\n *\n * @return {?EventTimeline} previous or following timeline, if they have been\n * joined up.\n */\nEventTimeline.prototype.getNeighbouringTimeline = function(direction) {\n if (direction == EventTimeline.BACKWARDS) {\n return this._prevTimeline;\n } else if (direction == EventTimeline.FORWARDS) {\n return this._nextTimeline;\n } else {\n throw new Error(\"Invalid direction '\" + direction + \"'\");\n }\n};\n\n/**\n * Set the next timeline in the series\n *\n * @param {EventTimeline} neighbour previous/following timeline\n *\n * @param {string} direction EventTimeline.BACKWARDS to set the previous\n * timeline; EventTimeline.FORWARDS to set the next timeline.\n *\n * @throws {Error} if an attempt is made to set the neighbouring timeline when\n * it is already set.\n */\nEventTimeline.prototype.setNeighbouringTimeline = function(neighbour, direction) {\n if (this.getNeighbouringTimeline(direction)) {\n throw new Error(\"timeline already has a neighbouring timeline - \" +\n \"cannot reset neighbour\");\n }\n\n if (direction == EventTimeline.BACKWARDS) {\n this._prevTimeline = neighbour;\n } else if (direction == EventTimeline.FORWARDS) {\n this._nextTimeline = neighbour;\n } else {\n throw new Error(\"Invalid direction '\" + direction + \"'\");\n }\n\n // make sure we don't try to paginate this timeline\n this.setPaginationToken(null, direction);\n};\n\n/**\n * Add a new event to the timeline, and update the state\n *\n * @param {MatrixEvent} event new event\n * @param {boolean} atStart true to insert new event at the start\n */\nEventTimeline.prototype.addEvent = function(event, atStart) {\n const stateContext = atStart ? this._startState : this._endState;\n\n // only call setEventMetadata on the unfiltered timelineSets\n const timelineSet = this.getTimelineSet();\n if (timelineSet.room &&\n timelineSet.room.getUnfilteredTimelineSet() === timelineSet) {\n EventTimeline.setEventMetadata(event, stateContext, atStart);\n\n // modify state\n if (event.isState()) {\n stateContext.setStateEvents([event]);\n // it is possible that the act of setting the state event means we\n // can set more metadata (specifically sender/target props), so try\n // it again if the prop wasn't previously set. It may also mean that\n // the sender/target is updated (if the event set was a room member event)\n // so we want to use the *updated* member (new avatar/name) instead.\n //\n // However, we do NOT want to do this on member events if we're going\n // back in time, else we'll set the .sender value for BEFORE the given\n // member event, whereas we want to set the .sender value for the ACTUAL\n // member event itself.\n if (!event.sender || (event.getType() === \"m.room.member\" && !atStart)) {\n EventTimeline.setEventMetadata(event, stateContext, atStart);\n }\n }\n }\n\n let insertIndex;\n\n if (atStart) {\n insertIndex = 0;\n } else {\n insertIndex = this._events.length;\n }\n\n this._events.splice(insertIndex, 0, event); // insert element\n if (atStart) {\n this._baseIndex++;\n }\n};\n\n/**\n * Static helper method to set sender and target properties\n *\n * @param {MatrixEvent} event the event whose metadata is to be set\n * @param {RoomState} stateContext the room state to be queried\n * @param {bool} toStartOfTimeline if true the event's forwardLooking flag is set false\n */\nEventTimeline.setEventMetadata = function(event, stateContext, toStartOfTimeline) {\n // set sender and target properties\n event.sender = stateContext.getSentinelMember(\n event.getSender(),\n );\n if (event.getType() === \"m.room.member\") {\n event.target = stateContext.getSentinelMember(\n event.getStateKey(),\n );\n }\n if (event.isState()) {\n // room state has no concept of 'old' or 'current', but we want the\n // room state to regress back to previous values if toStartOfTimeline\n // is set, which means inspecting prev_content if it exists. This\n // is done by toggling the forwardLooking flag.\n if (toStartOfTimeline) {\n event.forwardLooking = false;\n }\n }\n};\n\n/**\n * Remove an event from the timeline\n *\n * @param {string} eventId ID of event to be removed\n * @return {?MatrixEvent} removed event, or null if not found\n */\nEventTimeline.prototype.removeEvent = function(eventId) {\n for (let i = this._events.length - 1; i >= 0; i--) {\n const ev = this._events[i];\n if (ev.getId() == eventId) {\n this._events.splice(i, 1);\n if (i < this._baseIndex) {\n this._baseIndex--;\n }\n return ev;\n }\n }\n return null;\n};\n\n/**\n * Return a string to identify this timeline, for debugging\n *\n * @return {string} name for this timeline\n */\nEventTimeline.prototype.toString = function() {\n return this._name;\n};\n\n\n/**\n * The EventTimeline class\n */\nmodule.exports = EventTimeline;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * This is an internal module. See {@link MatrixEvent} and {@link RoomEvent} for\n * the public classes.\n * @module models/event\n */\n\nimport Promise from 'bluebird';\nimport {EventEmitter} from 'events';\nimport utils from '../utils.js';\n\n/**\n * Enum for event statuses.\n * @readonly\n * @enum {string}\n */\nmodule.exports.EventStatus = {\n /** The event was not sent and will no longer be retried. */\n NOT_SENT: \"not_sent\",\n\n /** The message is being encrypted */\n ENCRYPTING: \"encrypting\",\n\n /** The event is in the process of being sent. */\n SENDING: \"sending\",\n /** The event is in a queue waiting to be sent. */\n QUEUED: \"queued\",\n /** The event has been sent to the server, but we have not yet received the\n * echo. */\n SENT: \"sent\",\n\n /** The event was cancelled before it was successfully sent. */\n CANCELLED: \"cancelled\",\n};\n\nconst interns = {};\n\n/**\n * Construct a Matrix Event object\n * @constructor\n *\n * @param {Object} event The raw event to be wrapped in this DAO\n *\n * @prop {Object} event The raw (possibly encrypted) event. Do not access\n * this property directly unless you absolutely have to. Prefer the getter\n * methods defined on this class. Using the getter methods shields your app\n * from changes to event JSON between Matrix versions.\n *\n * @prop {RoomMember} sender The room member who sent this event, or null e.g.\n * this is a presence event. This is only guaranteed to be set for events that\n * appear in a timeline, ie. do not guarantee that it will be set on state\n * events.\n * @prop {RoomMember} target The room member who is the target of this event, e.g.\n * the invitee, the person being banned, etc.\n * @prop {EventStatus} status The sending status of the event.\n * @prop {Error} error most recent error associated with sending the event, if any\n * @prop {boolean} forwardLooking True if this event is 'forward looking', meaning\n * that getDirectionalContent() will return event.content and not event.prev_content.\n * Default: true. This property is experimental and may change.\n */\nmodule.exports.MatrixEvent = function MatrixEvent(\n event,\n) {\n // intern the values of matrix events to force share strings and reduce the\n // amount of needless string duplication. This can save moderate amounts of\n // memory (~10% on a 350MB heap).\n [\"state_key\", \"type\", \"sender\", \"room_id\"].forEach((prop) => {\n if (!event[prop]) {\n return;\n }\n if (!interns[event[prop]]) {\n interns[event[prop]] = event[prop];\n }\n event[prop] = interns[event[prop]];\n });\n\n [\"membership\", \"avatar_url\", \"displayname\"].forEach((prop) => {\n if (!event.content || !event.content[prop]) {\n return;\n }\n if (!interns[event.content[prop]]) {\n interns[event.content[prop]] = event.content[prop];\n }\n event.content[prop] = interns[event.content[prop]];\n });\n\n this.event = event || {};\n\n this.sender = null;\n this.target = null;\n this.status = null;\n this.error = null;\n this.forwardLooking = true;\n this._pushActions = null;\n this._date = this.event.origin_server_ts ?\n new Date(this.event.origin_server_ts) : null;\n\n this._clearEvent = {};\n\n /* curve25519 key which we believe belongs to the sender of the event. See\n * getSenderKey()\n */\n this._senderCurve25519Key = null;\n\n /* ed25519 key which the sender of this event (for olm) or the creator of\n * the megolm session (for megolm) claims to own. See getClaimedEd25519Key()\n */\n this._claimedEd25519Key = null;\n\n /* curve25519 keys of devices involved in telling us about the\n * _senderCurve25519Key and _claimedEd25519Key.\n * See getForwardingCurve25519KeyChain().\n */\n this._forwardingCurve25519KeyChain = [];\n\n /* if we have a process decrypting this event, a Promise which resolves\n * when it is finished. Normally null.\n */\n this._decryptionPromise = null;\n\n /* flag to indicate if we should retry decrypting this event after the\n * first attempt (eg, we have received new data which means that a second\n * attempt may succeed)\n */\n this._retryDecryption = false;\n};\nutils.inherits(module.exports.MatrixEvent, EventEmitter);\n\n\nutils.extend(module.exports.MatrixEvent.prototype, {\n\n /**\n * Get the event_id for this event.\n * @return {string} The event ID, e.g. $143350589368169JsLZx:localhost\n * \n */\n getId: function() {\n return this.event.event_id;\n },\n\n /**\n * Get the user_id for this event.\n * @return {string} The user ID, e.g. @alice:matrix.org\n */\n getSender: function() {\n return this.event.sender || this.event.user_id; // v2 / v1\n },\n\n /**\n * Get the (decrypted, if necessary) type of event.\n *\n * @return {string} The event type, e.g. m.room.message\n */\n getType: function() {\n return this._clearEvent.type || this.event.type;\n },\n\n /**\n * Get the (possibly encrypted) type of the event that will be sent to the\n * homeserver.\n *\n * @return {string} The event type.\n */\n getWireType: function() {\n return this.event.type;\n },\n\n /**\n * Get the room_id for this event. This will return undefined\n * for m.presence events.\n * @return {string} The room ID, e.g. !cURbafjkfsMDVwdRDQ:matrix.org\n * \n */\n getRoomId: function() {\n return this.event.room_id;\n },\n\n /**\n * Get the timestamp of this event.\n * @return {Number} The event timestamp, e.g. 1433502692297\n */\n getTs: function() {\n return this.event.origin_server_ts;\n },\n\n /**\n * Get the timestamp of this event, as a Date object.\n * @return {Date} The event date, e.g. new Date(1433502692297)\n */\n getDate: function() {\n return this._date;\n },\n\n /**\n * Get the (decrypted, if necessary) event content JSON.\n *\n * @return {Object} The event content JSON, or an empty object.\n */\n getContent: function() {\n return this._clearEvent.content || this.event.content || {};\n },\n\n /**\n * Get the (possibly encrypted) event content JSON that will be sent to the\n * homeserver.\n *\n * @return {Object} The event content JSON, or an empty object.\n */\n getWireContent: function() {\n return this.event.content || {};\n },\n\n /**\n * Get the previous event content JSON. This will only return something for\n * state events which exist in the timeline.\n * @return {Object} The previous event content JSON, or an empty object.\n */\n getPrevContent: function() {\n // v2 then v1 then default\n return this.getUnsigned().prev_content || this.event.prev_content || {};\n },\n\n /**\n * Get either 'content' or 'prev_content' depending on if this event is\n * 'forward-looking' or not. This can be modified via event.forwardLooking.\n * In practice, this means we get the chronologically earlier content value\n * for this event (this method should surely be called getEarlierContent)\n * This method is experimental and may change.\n * @return {Object} event.content if this event is forward-looking, else\n * event.prev_content.\n */\n getDirectionalContent: function() {\n return this.forwardLooking ? this.getContent() : this.getPrevContent();\n },\n\n /**\n * Get the age of this event. This represents the age of the event when the\n * event arrived at the device, and not the age of the event when this\n * function was called.\n * @return {Number} The age of this event in milliseconds.\n */\n getAge: function() {\n return this.getUnsigned().age || this.event.age; // v2 / v1\n },\n\n /**\n * Get the event state_key if it has one. This will return undefined\n * for message events.\n * @return {string} The event's state_key.\n */\n getStateKey: function() {\n return this.event.state_key;\n },\n\n /**\n * Check if this event is a state event.\n * @return {boolean} True if this is a state event.\n */\n isState: function() {\n return this.event.state_key !== undefined;\n },\n\n /**\n * Replace the content of this event with encrypted versions.\n * (This is used when sending an event; it should not be used by applications).\n *\n * @internal\n *\n * @param {string} crypto_type type of the encrypted event - typically\n * \"m.room.encrypted\"\n *\n * @param {object} crypto_content raw 'content' for the encrypted event.\n *\n * @param {string} senderCurve25519Key curve25519 key to record for the\n * sender of this event.\n * See {@link module:models/event.MatrixEvent#getSenderKey}.\n *\n * @param {string} claimedEd25519Key claimed ed25519 key to record for the\n * sender if this event.\n * See {@link module:models/event.MatrixEvent#getClaimedEd25519Key}\n */\n makeEncrypted: function(\n crypto_type, crypto_content, senderCurve25519Key, claimedEd25519Key,\n ) {\n // keep the plain-text data for 'view source'\n this._clearEvent = {\n type: this.event.type,\n content: this.event.content,\n };\n this.event.type = crypto_type;\n this.event.content = crypto_content;\n this._senderCurve25519Key = senderCurve25519Key;\n this._claimedEd25519Key = claimedEd25519Key;\n },\n\n /**\n * Check if this event is currently being decrypted.\n *\n * @return {boolean} True if this event is currently being decrypted, else false.\n */\n isBeingDecrypted: function() {\n return this._decryptionPromise != null;\n },\n\n /**\n * Check if this event is an encrypted event which we failed to decrypt\n *\n * (This implies that we might retry decryption at some point in the future)\n *\n * @return {boolean} True if this event is an encrypted event which we\n * couldn't decrypt.\n */\n isDecryptionFailure: function() {\n return this._clearEvent && this._clearEvent.content &&\n this._clearEvent.content.msgtype === \"m.bad.encrypted\";\n },\n\n /**\n * Start the process of trying to decrypt this event.\n *\n * (This is used within the SDK: it isn't intended for use by applications)\n *\n * @internal\n *\n * @param {module:crypto} crypto crypto module\n *\n * @returns {Promise} promise which resolves (to undefined) when the decryption\n * attempt is completed.\n */\n attemptDecryption: async function(crypto) {\n // start with a couple of sanity checks.\n if (!this.isEncrypted()) {\n throw new Error(\"Attempt to decrypt event which isn't encrypted\");\n }\n\n if (\n this._clearEvent && this._clearEvent.content &&\n this._clearEvent.content.msgtype !== \"m.bad.encrypted\"\n ) {\n // we may want to just ignore this? let's start with rejecting it.\n throw new Error(\n \"Attempt to decrypt event which has already been encrypted\",\n );\n }\n\n // if we already have a decryption attempt in progress, then it may\n // fail because it was using outdated info. We now have reason to\n // succeed where it failed before, but we don't want to have multiple\n // attempts going at the same time, so just set a flag that says we have\n // new info.\n //\n if (this._decryptionPromise) {\n console.log(\n `Event ${this.getId()} already being decrypted; queueing a retry`,\n );\n this._retryDecryption = true;\n return this._decryptionPromise;\n }\n\n this._decryptionPromise = this._decryptionLoop(crypto);\n return this._decryptionPromise;\n },\n\n _decryptionLoop: async function(crypto) {\n // make sure that this method never runs completely synchronously.\n // (doing so would mean that we would clear _decryptionPromise *before*\n // it is set in attemptDecryption - and hence end up with a stuck\n // `_decryptionPromise`).\n await Promise.resolve();\n\n while (true) {\n this._retryDecryption = false;\n\n let res;\n try {\n if (!crypto) {\n res = this._badEncryptedMessage(\"Encryption not enabled\");\n } else {\n res = await crypto.decryptEvent(this);\n }\n } catch (e) {\n if (e.name !== \"DecryptionError\") {\n // not a decryption error: log the whole exception as an error\n // (and don't bother with a retry)\n console.error(\n `Error decrypting event (id=${this.getId()}): ${e.stack || e}`,\n );\n this._decryptionPromise = null;\n this._retryDecryption = false;\n return;\n }\n\n // see if we have a retry queued.\n //\n // NB: make sure to keep this check in the same tick of the\n // event loop as `_decryptionPromise = null` below - otherwise we\n // risk a race:\n //\n // * A: we check _retryDecryption here and see that it is\n // false\n // * B: we get a second call to attemptDecryption, which sees\n // that _decryptionPromise is set so sets\n // _retryDecryption\n // * A: we continue below, clear _decryptionPromise, and\n // never do the retry.\n //\n if (this._retryDecryption) {\n // decryption error, but we have a retry queued.\n console.log(\n `Got error decrypting event (id=${this.getId()}: ` +\n `${e.message}), but retrying`,\n );\n continue;\n }\n\n // decryption error, no retries queued. Warn about the error and\n // set it to m.bad.encrypted.\n console.warn(\n `Error decrypting event (id=${this.getId()}): ${e}`,\n );\n\n res = this._badEncryptedMessage(e.message);\n }\n\n // at this point, we've either successfully decrypted the event, or have given up\n // (and set res to a 'badEncryptedMessage'). Either way, we can now set the\n // cleartext of the event and raise Event.decrypted.\n //\n // make sure we clear '_decryptionPromise' before sending the 'Event.decrypted' event,\n // otherwise the app will be confused to see `isBeingDecrypted` still set when\n // there isn't an `Event.decrypted` on the way.\n //\n // see also notes on _retryDecryption above.\n //\n this._decryptionPromise = null;\n this._retryDecryption = false;\n this._setClearData(res);\n return;\n }\n },\n\n _badEncryptedMessage: function(reason) {\n return {\n clearEvent: {\n type: \"m.room.message\",\n content: {\n msgtype: \"m.bad.encrypted\",\n body: \"** Unable to decrypt: \" + reason + \" **\",\n },\n },\n };\n },\n\n /**\n * Update the cleartext data on this event.\n *\n * (This is used after decrypting an event; it should not be used by applications).\n *\n * @internal\n *\n * @fires module:models/event.MatrixEvent#\"Event.decrypted\"\n *\n * @param {module:crypto~EventDecryptionResult} decryptionResult\n * the decryption result, including the plaintext and some key info\n */\n _setClearData: function(decryptionResult) {\n this._clearEvent = decryptionResult.clearEvent;\n this._senderCurve25519Key =\n decryptionResult.senderCurve25519Key || null;\n this._claimedEd25519Key =\n decryptionResult.claimedEd25519Key || null;\n this._forwardingCurve25519KeyChain =\n decryptionResult.forwardingCurve25519KeyChain || [];\n this.emit(\"Event.decrypted\", this);\n },\n\n /**\n * Check if the event is encrypted.\n * @return {boolean} True if this event is encrypted.\n */\n isEncrypted: function() {\n return this.event.type === \"m.room.encrypted\";\n },\n\n /**\n * The curve25519 key for the device that we think sent this event\n *\n * For an Olm-encrypted event, this is inferred directly from the DH\n * exchange at the start of the session: the curve25519 key is involved in\n * the DH exchange, so only a device which holds the private part of that\n * key can establish such a session.\n *\n * For a megolm-encrypted event, it is inferred from the Olm message which\n * established the megolm session\n *\n * @return {string}\n */\n getSenderKey: function() {\n return this._senderCurve25519Key;\n },\n\n /**\n * The additional keys the sender of this encrypted event claims to possess.\n *\n * Just a wrapper for #getClaimedEd25519Key (q.v.)\n *\n * @return {Object}\n */\n getKeysClaimed: function() {\n return {\n ed25519: this._claimedEd25519Key,\n };\n },\n\n /**\n * Get the ed25519 the sender of this event claims to own.\n *\n * For Olm messages, this claim is encoded directly in the plaintext of the\n * event itself. For megolm messages, it is implied by the m.room_key event\n * which established the megolm session.\n *\n * Until we download the device list of the sender, it's just a claim: the\n * device list gives a proof that the owner of the curve25519 key used for\n * this event (and returned by #getSenderKey) also owns the ed25519 key by\n * signing the public curve25519 key with the ed25519 key.\n *\n * In general, applications should not use this method directly, but should\n * instead use MatrixClient.getEventSenderDeviceInfo.\n *\n * @return {string}\n */\n getClaimedEd25519Key: function() {\n return this._claimedEd25519Key;\n },\n\n /**\n * Get the curve25519 keys of the devices which were involved in telling us\n * about the claimedEd25519Key and sender curve25519 key.\n *\n * Normally this will be empty, but in the case of a forwarded megolm\n * session, the sender keys are sent to us by another device (the forwarding\n * device), which we need to trust to do this. In that case, the result will\n * be a list consisting of one entry.\n *\n * If the device that sent us the key (A) got it from another device which\n * it wasn't prepared to vouch for (B), the result will be [A, B]. And so on.\n *\n * @return {string[]} base64-encoded curve25519 keys, from oldest to newest.\n */\n getForwardingCurve25519KeyChain: function() {\n return this._forwardingCurve25519KeyChain;\n },\n\n getUnsigned: function() {\n return this.event.unsigned || {};\n },\n\n /**\n * Update the content of an event in the same way it would be by the server\n * if it were redacted before it was sent to us\n *\n * @param {module:models/event.MatrixEvent} redaction_event\n * event causing the redaction\n */\n makeRedacted: function(redaction_event) {\n // quick sanity-check\n if (!redaction_event.event) {\n throw new Error(\"invalid redaction_event in makeRedacted\");\n }\n\n // we attempt to replicate what we would see from the server if\n // the event had been redacted before we saw it.\n //\n // The server removes (most of) the content of the event, and adds a\n // \"redacted_because\" key to the unsigned section containing the\n // redacted event.\n if (!this.event.unsigned) {\n this.event.unsigned = {};\n }\n this.event.unsigned.redacted_because = redaction_event.event;\n\n let key;\n for (key in this.event) {\n if (!this.event.hasOwnProperty(key)) {\n continue;\n }\n if (!_REDACT_KEEP_KEY_MAP[key]) {\n delete this.event[key];\n }\n }\n\n const keeps = _REDACT_KEEP_CONTENT_MAP[this.getType()] || {};\n const content = this.getContent();\n for (key in content) {\n if (!content.hasOwnProperty(key)) {\n continue;\n }\n if (!keeps[key]) {\n delete content[key];\n }\n }\n },\n\n /**\n * Check if this event has been redacted\n *\n * @return {boolean} True if this event has been redacted\n */\n isRedacted: function() {\n return Boolean(this.getUnsigned().redacted_because);\n },\n\n /**\n * Get the push actions, if known, for this event\n *\n * @return {?Object} push actions\n */\n getPushActions: function() {\n return this._pushActions;\n },\n\n /**\n * Set the push actions for this event.\n *\n * @param {Object} pushActions push actions\n */\n setPushActions: function(pushActions) {\n this._pushActions = pushActions;\n },\n\n /**\n * Replace the `event` property and recalculate any properties based on it.\n * @param {Object} event the object to assign to the `event` property\n */\n handleRemoteEcho: function(event) {\n this.event = event;\n // successfully sent.\n this.status = null;\n this._date = new Date(this.event.origin_server_ts);\n },\n});\n\n\n/* _REDACT_KEEP_KEY_MAP gives the keys we keep when an event is redacted\n *\n * This is specified here:\n * http://matrix.org/speculator/spec/HEAD/client_server/unstable.html#redactions\n *\n * Also:\n * - We keep 'unsigned' since that is created by the local server\n * - We keep user_id for backwards-compat with v1\n */\nconst _REDACT_KEEP_KEY_MAP = [\n 'event_id', 'type', 'room_id', 'user_id', 'sender', 'state_key', 'prev_state',\n 'content', 'unsigned', 'origin_server_ts',\n].reduce(function(ret, val) {\n ret[val] = 1; return ret;\n}, {});\n\n// a map from event type to the .content keys we keep when an event is redacted\nconst _REDACT_KEEP_CONTENT_MAP = {\n 'm.room.member': {'membership': 1},\n 'm.room.create': {'creator': 1},\n 'm.room.join_rules': {'join_rule': 1},\n 'm.room.power_levels': {'ban': 1, 'events': 1, 'events_default': 1,\n 'kick': 1, 'redact': 1, 'state_default': 1,\n 'users': 1, 'users_default': 1,\n },\n 'm.room.aliases': {'aliases': 1},\n};\n\n\n/**\n * Fires when an event is decrypted\n *\n * @event module:models/event.MatrixEvent#\"Event.decrypted\"\n *\n * @param {module:models/event.MatrixEvent} event\n * The matrix event which has been decrypted\n */\n","/*\nCopyright 2017 New Vector Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * @module models/group\n */\nconst EventEmitter = require(\"events\").EventEmitter;\n\nconst utils = require(\"../utils\");\n\n/**\n * Construct a new Group.\n *\n * @param {string} groupId The ID of this group.\n *\n * @prop {string} groupId The ID of this group.\n * @prop {string} name The human-readable display name for this group.\n * @prop {string} avatarUrl The mxc URL for this group's avatar.\n * @prop {string} myMembership The logged in user's membership of this group\n * @prop {Object} inviter Infomation about the user who invited the logged in user\n * to the group, if myMembership is 'invite'.\n * @prop {string} inviter.userId The user ID of the inviter\n */\nfunction Group(groupId) {\n this.groupId = groupId;\n this.name = null;\n this.avatarUrl = null;\n this.myMembership = null;\n this.inviter = null;\n}\nutils.inherits(Group, EventEmitter);\n\nGroup.prototype.setProfile = function(name, avatarUrl) {\n if (this.name === name && this.avatarUrl === avatarUrl) return;\n\n this.name = name || this.groupId;\n this.avatarUrl = avatarUrl;\n\n this.emit(\"Group.profile\", this);\n};\n\nGroup.prototype.setMyMembership = function(membership) {\n if (this.myMembership === membership) return;\n\n this.myMembership = membership;\n\n this.emit(\"Group.myMembership\", this);\n};\n\n/**\n * Sets the 'inviter' property. This does not emit an event (the inviter\n * will only change when the user is revited / reinvited to a room),\n * so set this before setting myMembership.\n * @param {Object} inviter Infomation about who invited us to the room\n */\nGroup.prototype.setInviter = function(inviter) {\n this.inviter = inviter;\n};\n\nmodule.exports = Group;\n\n/**\n * Fires whenever a group's profile information is updated.\n * This means the 'name' and 'avatarUrl' properties.\n * @event module:client~MatrixClient#\"Group.profile\"\n * @param {Group} group The group whose profile was updated.\n * @example\n * matrixClient.on(\"Group.profile\", function(group){\n * var name = group.name;\n * });\n */\n\n/**\n * Fires whenever the logged in user's membership status of\n * the group is updated.\n * @event module:client~MatrixClient#\"Group.myMembership\"\n * @param {Group} group The group in which the user's membership changed\n * @example\n * matrixClient.on(\"Group.myMembership\", function(group){\n * var myMembership = group.myMembership;\n * });\n */\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * @module models/room-member\n */\nconst EventEmitter = require(\"events\").EventEmitter;\nconst ContentRepo = require(\"../content-repo\");\n\nconst utils = require(\"../utils\");\n\n/**\n * Construct a new room member.\n *\n * @constructor\n * @alias module:models/room-member\n *\n * @param {string} roomId The room ID of the member.\n * @param {string} userId The user ID of the member.\n * @prop {string} roomId The room ID for this member.\n * @prop {string} userId The user ID of this member.\n * @prop {boolean} typing True if the room member is currently typing.\n * @prop {string} name The human-readable name for this room member. This will be\n * disambiguated with a suffix of \" (@user_id:matrix.org)\" if another member shares the\n * same displayname.\n * @prop {string} rawDisplayName The ambiguous displayname of this room member.\n * @prop {Number} powerLevel The power level for this room member.\n * @prop {Number} powerLevelNorm The normalised power level (0-100) for this\n * room member.\n * @prop {User} user The User object for this room member, if one exists.\n * @prop {string} membership The membership state for this room member e.g. 'join'.\n * @prop {Object} events The events describing this RoomMember.\n * @prop {MatrixEvent} events.member The m.room.member event for this RoomMember.\n */\nfunction RoomMember(roomId, userId) {\n this.roomId = roomId;\n this.userId = userId;\n this.typing = false;\n this.name = userId;\n this.rawDisplayName = userId;\n this.powerLevel = 0;\n this.powerLevelNorm = 0;\n this.user = null;\n this.membership = null;\n this.events = {\n member: null,\n };\n this._updateModifiedTime();\n}\nutils.inherits(RoomMember, EventEmitter);\n\n/**\n * Update this room member's membership event. May fire \"RoomMember.name\" if\n * this event updates this member's name.\n * @param {MatrixEvent} event The m.room.member event\n * @param {RoomState} roomState Optional. The room state to take into account\n * when calculating (e.g. for disambiguating users with the same name).\n * @fires module:client~MatrixClient#event:\"RoomMember.name\"\n * @fires module:client~MatrixClient#event:\"RoomMember.membership\"\n */\nRoomMember.prototype.setMembershipEvent = function(event, roomState) {\n if (event.getType() !== \"m.room.member\") {\n return;\n }\n this.events.member = event;\n\n const oldMembership = this.membership;\n this.membership = event.getDirectionalContent().membership;\n\n const oldName = this.name;\n this.name = calculateDisplayName(this, event, roomState);\n this.rawDisplayName = event.getDirectionalContent().displayname || this.userId;\n if (oldMembership !== this.membership) {\n this._updateModifiedTime();\n this.emit(\"RoomMember.membership\", event, this, oldMembership);\n }\n if (oldName !== this.name) {\n this._updateModifiedTime();\n this.emit(\"RoomMember.name\", event, this, oldName);\n }\n};\n\n/**\n * Update this room member's power level event. May fire\n * \"RoomMember.powerLevel\" if this event updates this member's power levels.\n * @param {MatrixEvent} powerLevelEvent The m.room.power_levels\n * event\n * @fires module:client~MatrixClient#event:\"RoomMember.powerLevel\"\n */\nRoomMember.prototype.setPowerLevelEvent = function(powerLevelEvent) {\n if (powerLevelEvent.getType() !== \"m.room.power_levels\") {\n return;\n }\n\n const evContent = powerLevelEvent.getDirectionalContent();\n\n let maxLevel = evContent.users_default || 0;\n utils.forEach(utils.values(evContent.users), function(lvl) {\n maxLevel = Math.max(maxLevel, lvl);\n });\n const oldPowerLevel = this.powerLevel;\n const oldPowerLevelNorm = this.powerLevelNorm;\n\n if (evContent.users && evContent.users[this.userId] !== undefined) {\n this.powerLevel = evContent.users[this.userId];\n } else if (evContent.users_default !== undefined) {\n this.powerLevel = evContent.users_default;\n } else {\n this.powerLevel = 0;\n }\n this.powerLevelNorm = 0;\n if (maxLevel > 0) {\n this.powerLevelNorm = (this.powerLevel * 100) / maxLevel;\n }\n\n // emit for changes in powerLevelNorm as well (since the app will need to\n // redraw everyone's level if the max has changed)\n if (oldPowerLevel !== this.powerLevel || oldPowerLevelNorm !== this.powerLevelNorm) {\n this._updateModifiedTime();\n this.emit(\"RoomMember.powerLevel\", powerLevelEvent, this);\n }\n};\n\n/**\n * Update this room member's typing event. May fire \"RoomMember.typing\" if\n * this event changes this member's typing state.\n * @param {MatrixEvent} event The typing event\n * @fires module:client~MatrixClient#event:\"RoomMember.typing\"\n */\nRoomMember.prototype.setTypingEvent = function(event) {\n if (event.getType() !== \"m.typing\") {\n return;\n }\n const oldTyping = this.typing;\n this.typing = false;\n const typingList = event.getContent().user_ids;\n if (!utils.isArray(typingList)) {\n // malformed event :/ bail early. TODO: whine?\n return;\n }\n if (typingList.indexOf(this.userId) !== -1) {\n this.typing = true;\n }\n if (oldTyping !== this.typing) {\n this._updateModifiedTime();\n this.emit(\"RoomMember.typing\", event, this);\n }\n};\n\n/**\n * Update the last modified time to the current time.\n */\nRoomMember.prototype._updateModifiedTime = function() {\n this._modified = Date.now();\n};\n\n/**\n * Get the timestamp when this RoomMember was last updated. This timestamp is\n * updated when properties on this RoomMember are updated.\n * It is updated before firing events.\n * @return {number} The timestamp\n */\nRoomMember.prototype.getLastModifiedTime = function() {\n return this._modified;\n};\n\n/**\n * Get the avatar URL for a room member.\n * @param {string} baseUrl The base homeserver URL See\n * {@link module:client~MatrixClient#getHomeserverUrl}.\n * @param {Number} width The desired width of the thumbnail.\n * @param {Number} height The desired height of the thumbnail.\n * @param {string} resizeMethod The thumbnail resize method to use, either\n * \"crop\" or \"scale\".\n * @param {Boolean} allowDefault (optional) Passing false causes this method to\n * return null if the user has no avatar image. Otherwise, a default image URL\n * will be returned. Default: true.\n * @param {Boolean} allowDirectLinks (optional) If true, the avatar URL will be\n * returned even if it is a direct hyperlink rather than a matrix content URL.\n * If false, any non-matrix content URLs will be ignored. Setting this option to\n * true will expose URLs that, if fetched, will leak information about the user\n * to anyone who they share a room with.\n * @return {?string} the avatar URL or null.\n */\nRoomMember.prototype.getAvatarUrl =\n function(baseUrl, width, height, resizeMethod, allowDefault, allowDirectLinks) {\n if (allowDefault === undefined) {\n allowDefault = true;\n }\n if (!this.events.member && !allowDefault) {\n return null;\n }\n const rawUrl = this.events.member ? this.events.member.getContent().avatar_url : null;\n const httpUrl = ContentRepo.getHttpUriForMxc(\n baseUrl, rawUrl, width, height, resizeMethod, allowDirectLinks,\n );\n if (httpUrl) {\n return httpUrl;\n } else if (allowDefault) {\n return ContentRepo.getIdenticonUri(\n baseUrl, this.userId, width, height,\n );\n }\n return null;\n};\n\nfunction calculateDisplayName(member, event, roomState) {\n const displayName = event.getDirectionalContent().displayname;\n const selfUserId = member.userId;\n\n if (!displayName) {\n return selfUserId;\n }\n\n if (!roomState) {\n return displayName;\n }\n\n const userIds = roomState.getUserIdsWithDisplayName(displayName);\n const otherUsers = userIds.filter(function(u) {\n return u !== selfUserId;\n });\n if (otherUsers.length > 0) {\n return displayName + \" (\" + selfUserId + \")\";\n }\n return displayName;\n}\n\n/**\n * The RoomMember class.\n */\nmodule.exports = RoomMember;\n\n/**\n * Fires whenever any room member's name changes.\n * @event module:client~MatrixClient#\"RoomMember.name\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {RoomMember} member The member whose RoomMember.name changed.\n * @param {string?} oldName The previous name. Null if the member didn't have a\n * name previously.\n * @example\n * matrixClient.on(\"RoomMember.name\", function(event, member){\n * var newName = member.name;\n * });\n */\n\n/**\n * Fires whenever any room member's membership state changes.\n * @event module:client~MatrixClient#\"RoomMember.membership\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {RoomMember} member The member whose RoomMember.membership changed.\n * @param {string?} oldMembership The previous membership state. Null if it's a\n * new member.\n * @example\n * matrixClient.on(\"RoomMember.membership\", function(event, member, oldMembership){\n * var newState = member.membership;\n * });\n */\n\n/**\n * Fires whenever any room member's typing state changes.\n * @event module:client~MatrixClient#\"RoomMember.typing\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {RoomMember} member The member whose RoomMember.typing changed.\n * @example\n * matrixClient.on(\"RoomMember.typing\", function(event, member){\n * var isTyping = member.typing;\n * });\n */\n\n/**\n * Fires whenever any room member's power level changes.\n * @event module:client~MatrixClient#\"RoomMember.powerLevel\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {RoomMember} member The member whose RoomMember.powerLevel changed.\n * @example\n * matrixClient.on(\"RoomMember.powerLevel\", function(event, member){\n * var newPowerLevel = member.powerLevel;\n * var newNormPowerLevel = member.powerLevelNorm;\n * });\n */\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * @module models/room-state\n */\nconst EventEmitter = require(\"events\").EventEmitter;\n\nconst utils = require(\"../utils\");\nconst RoomMember = require(\"./room-member\");\n\n/**\n * Construct room state.\n * @constructor\n * @param {?string} roomId Optional. The ID of the room which has this state.\n * If none is specified it just tracks paginationTokens, useful for notifTimelineSet\n * @prop {Object.} members The room member dictionary, keyed\n * on the user's ID.\n * @prop {Object.>} events The state\n * events dictionary, keyed on the event type and then the state_key value.\n * @prop {string} paginationToken The pagination token for this state.\n */\nfunction RoomState(roomId) {\n this.roomId = roomId;\n this.members = {\n // userId: RoomMember\n };\n this.events = {\n // eventType: { stateKey: MatrixEvent }\n };\n this.paginationToken = null;\n\n this._sentinels = {\n // userId: RoomMember\n };\n this._updateModifiedTime();\n this._displayNameToUserIds = {};\n this._userIdsToDisplayNames = {};\n this._tokenToInvite = {}; // 3pid invite state_key to m.room.member invite\n}\nutils.inherits(RoomState, EventEmitter);\n\n/**\n * Get all RoomMembers in this room.\n * @return {Array} A list of RoomMembers.\n */\nRoomState.prototype.getMembers = function() {\n return utils.values(this.members);\n};\n\n/**\n * Get a room member by their user ID.\n * @param {string} userId The room member's user ID.\n * @return {RoomMember} The member or null if they do not exist.\n */\nRoomState.prototype.getMember = function(userId) {\n return this.members[userId] || null;\n};\n\n/**\n * Get a room member whose properties will not change with this room state. You\n * typically want this if you want to attach a RoomMember to a MatrixEvent which\n * may no longer be represented correctly by Room.currentState or Room.oldState.\n * The term 'sentinel' refers to the fact that this RoomMember is an unchanging\n * guardian for state at this particular point in time.\n * @param {string} userId The room member's user ID.\n * @return {RoomMember} The member or null if they do not exist.\n */\nRoomState.prototype.getSentinelMember = function(userId) {\n return this._sentinels[userId] || null;\n};\n\n/**\n * Get state events from the state of the room.\n * @param {string} eventType The event type of the state event.\n * @param {string} stateKey Optional. The state_key of the state event. If\n * this is undefined then all matching state events will be\n * returned.\n * @return {MatrixEvent[]|MatrixEvent} A list of events if state_key was\n * undefined, else a single event (or null if no match found).\n */\nRoomState.prototype.getStateEvents = function(eventType, stateKey) {\n if (!this.events[eventType]) {\n // no match\n return stateKey === undefined ? [] : null;\n }\n if (stateKey === undefined) { // return all values\n return utils.values(this.events[eventType]);\n }\n const event = this.events[eventType][stateKey];\n return event ? event : null;\n};\n\n/**\n * Add an array of one or more state MatrixEvents, overwriting\n * any existing state with the same {type, stateKey} tuple. Will fire\n * \"RoomState.events\" for every event added. May fire \"RoomState.members\"\n * if there are m.room.member events.\n * @param {MatrixEvent[]} stateEvents a list of state events for this room.\n * @fires module:client~MatrixClient#event:\"RoomState.members\"\n * @fires module:client~MatrixClient#event:\"RoomState.newMember\"\n * @fires module:client~MatrixClient#event:\"RoomState.events\"\n */\nRoomState.prototype.setStateEvents = function(stateEvents) {\n const self = this;\n this._updateModifiedTime();\n\n // update the core event dict\n utils.forEach(stateEvents, function(event) {\n if (event.getRoomId() !== self.roomId) {\n return;\n }\n if (!event.isState()) {\n return;\n }\n\n if (self.events[event.getType()] === undefined) {\n self.events[event.getType()] = {};\n }\n self.events[event.getType()][event.getStateKey()] = event;\n if (event.getType() === \"m.room.member\") {\n _updateDisplayNameCache(\n self, event.getStateKey(), event.getContent().displayname,\n );\n _updateThirdPartyTokenCache(self, event);\n }\n self.emit(\"RoomState.events\", event, self);\n });\n\n // update higher level data structures. This needs to be done AFTER the\n // core event dict as these structures may depend on other state events in\n // the given array (e.g. disambiguating display names in one go to do both\n // clashing names rather than progressively which only catches 1 of them).\n utils.forEach(stateEvents, function(event) {\n if (event.getRoomId() !== self.roomId) {\n return;\n }\n if (!event.isState()) {\n return;\n }\n\n if (event.getType() === \"m.room.member\") {\n const userId = event.getStateKey();\n\n // leave events apparently elide the displayname or avatar_url,\n // so let's fake one up so that we don't leak user ids\n // into the timeline\n if (event.getContent().membership === \"leave\" ||\n event.getContent().membership === \"ban\") {\n event.getContent().avatar_url =\n event.getContent().avatar_url ||\n event.getPrevContent().avatar_url;\n event.getContent().displayname =\n event.getContent().displayname ||\n event.getPrevContent().displayname;\n }\n\n let member = self.members[userId];\n if (!member) {\n member = new RoomMember(event.getRoomId(), userId);\n self.emit(\"RoomState.newMember\", event, self, member);\n }\n // Add a new sentinel for this change. We apply the same\n // operations to both sentinel and member rather than deep copying\n // so we don't make assumptions about the properties of RoomMember\n // (e.g. and manage to break it because deep copying doesn't do\n // everything).\n const sentinel = new RoomMember(event.getRoomId(), userId);\n utils.forEach([member, sentinel], function(roomMember) {\n roomMember.setMembershipEvent(event, self);\n // this member may have a power level already, so set it.\n const pwrLvlEvent = self.getStateEvents(\"m.room.power_levels\", \"\");\n if (pwrLvlEvent) {\n roomMember.setPowerLevelEvent(pwrLvlEvent);\n }\n });\n\n self._sentinels[userId] = sentinel;\n self.members[userId] = member;\n self.emit(\"RoomState.members\", event, self, member);\n } else if (event.getType() === \"m.room.power_levels\") {\n const members = utils.values(self.members);\n utils.forEach(members, function(member) {\n member.setPowerLevelEvent(event);\n self.emit(\"RoomState.members\", event, self, member);\n });\n\n // Go through the sentinel members and see if any of them would be\n // affected by the new power levels. If so, replace the sentinel.\n for (const userId of Object.keys(self._sentinels)) {\n const oldSentinel = self._sentinels[userId];\n const newSentinel = new RoomMember(event.getRoomId(), userId);\n newSentinel.setMembershipEvent(oldSentinel.events.member, self);\n newSentinel.setPowerLevelEvent(event);\n self._sentinels[userId] = newSentinel;\n }\n }\n });\n};\n\n/**\n * Set the current typing event for this room.\n * @param {MatrixEvent} event The typing event\n */\nRoomState.prototype.setTypingEvent = function(event) {\n utils.forEach(utils.values(this.members), function(member) {\n member.setTypingEvent(event);\n });\n};\n\n/**\n * Get the m.room.member event which has the given third party invite token.\n *\n * @param {string} token The token\n * @return {?MatrixEvent} The m.room.member event or null\n */\nRoomState.prototype.getInviteForThreePidToken = function(token) {\n return this._tokenToInvite[token] || null;\n};\n\n/**\n * Update the last modified time to the current time.\n */\nRoomState.prototype._updateModifiedTime = function() {\n this._modified = Date.now();\n};\n\n/**\n * Get the timestamp when this room state was last updated. This timestamp is\n * updated when this object has received new state events.\n * @return {number} The timestamp\n */\nRoomState.prototype.getLastModifiedTime = function() {\n return this._modified;\n};\n\n/**\n * Get user IDs with the specified display name.\n * @param {string} displayName The display name to get user IDs from.\n * @return {string[]} An array of user IDs or an empty array.\n */\nRoomState.prototype.getUserIdsWithDisplayName = function(displayName) {\n return this._displayNameToUserIds[displayName] || [];\n};\n\n/**\n * Returns true if userId is in room, event is not redacted and either sender of\n * mxEvent or has power level sufficient to redact events other than their own.\n * @param {MatrixEvent} mxEvent The event to test permission for\n * @param {string} userId The user ID of the user to test permission for\n * @return {boolean} true if the given used ID can redact given event\n */\nRoomState.prototype.maySendRedactionForEvent = function(mxEvent, userId) {\n const member = this.getMember(userId);\n if (!member || member.membership === 'leave') return false;\n\n if (mxEvent.status || mxEvent.isRedacted()) return false;\n if (mxEvent.getSender() === userId) return true;\n\n return this._hasSufficientPowerLevelFor('redact', member.powerLevel);\n};\n\n/**\n * Returns true if the given power level is sufficient for action\n * @param {string} action The type of power level to check\n * @param {number} powerLevel The power level of the member\n * @return {boolean} true if the given power level is sufficient\n */\nRoomState.prototype._hasSufficientPowerLevelFor = function(action, powerLevel) {\n const powerLevelsEvent = this.getStateEvents('m.room.power_levels', '');\n\n let powerLevels = {};\n if (powerLevelsEvent) {\n powerLevels = powerLevelsEvent.getContent();\n }\n\n let requiredLevel = 50;\n if (powerLevels[action] !== undefined) {\n requiredLevel = powerLevels[action];\n }\n\n return powerLevel >= requiredLevel;\n};\n\n/**\n * Short-form for maySendEvent('m.room.message', userId)\n * @param {string} userId The user ID of the user to test permission for\n * @return {boolean} true if the given user ID should be permitted to send\n * message events into the given room.\n */\nRoomState.prototype.maySendMessage = function(userId) {\n return this._maySendEventOfType('m.room.message', userId, false);\n};\n\n/**\n * Returns true if the given user ID has permission to send a normal\n * event of type `eventType` into this room.\n * @param {string} eventType The type of event to test\n * @param {string} userId The user ID of the user to test permission for\n * @return {boolean} true if the given user ID should be permitted to send\n * the given type of event into this room,\n * according to the room's state.\n */\nRoomState.prototype.maySendEvent = function(eventType, userId) {\n return this._maySendEventOfType(eventType, userId, false);\n};\n\n/**\n * Returns true if the given MatrixClient has permission to send a state\n * event of type `stateEventType` into this room.\n * @param {string} stateEventType The type of state events to test\n * @param {MatrixClient} cli The client to test permission for\n * @return {boolean} true if the given client should be permitted to send\n * the given type of state event into this room,\n * according to the room's state.\n */\nRoomState.prototype.mayClientSendStateEvent = function(stateEventType, cli) {\n if (cli.isGuest()) {\n return false;\n }\n return this.maySendStateEvent(stateEventType, cli.credentials.userId);\n};\n\n/**\n * Returns true if the given user ID has permission to send a state\n * event of type `stateEventType` into this room.\n * @param {string} stateEventType The type of state events to test\n * @param {string} userId The user ID of the user to test permission for\n * @return {boolean} true if the given user ID should be permitted to send\n * the given type of state event into this room,\n * according to the room's state.\n */\nRoomState.prototype.maySendStateEvent = function(stateEventType, userId) {\n return this._maySendEventOfType(stateEventType, userId, true);\n};\n\n/**\n * Returns true if the given user ID has permission to send a normal or state\n * event of type `eventType` into this room.\n * @param {string} eventType The type of event to test\n * @param {string} userId The user ID of the user to test permission for\n * @param {boolean} state If true, tests if the user may send a state\n event of this type. Otherwise tests whether\n they may send a regular event.\n * @return {boolean} true if the given user ID should be permitted to send\n * the given type of event into this room,\n * according to the room's state.\n */\nRoomState.prototype._maySendEventOfType = function(eventType, userId, state) {\n const member = this.getMember(userId);\n if (!member || member.membership == 'leave') {\n return false;\n }\n\n const power_levels_event = this.getStateEvents('m.room.power_levels', '');\n\n let power_levels;\n let events_levels = {};\n\n let state_default = 0;\n let events_default = 0;\n if (power_levels_event) {\n power_levels = power_levels_event.getContent();\n events_levels = power_levels.events || {};\n\n if (power_levels.state_default !== undefined) {\n state_default = power_levels.state_default;\n } else {\n state_default = 50;\n }\n if (power_levels.events_default !== undefined) {\n events_default = power_levels.events_default;\n }\n }\n\n let required_level = state ? state_default : events_default;\n if (events_levels[eventType] !== undefined) {\n required_level = events_levels[eventType];\n }\n return member.powerLevel >= required_level;\n};\n\n/**\n * Returns true if the given user ID has permission to trigger notification\n * of type `notifLevelKey`\n * @param {string} notifLevelKey The level of notification to test (eg. 'room')\n * @param {string} userId The user ID of the user to test permission for\n * @return {boolean} true if the given user ID has permission to trigger a\n * notification of this type.\n */\nRoomState.prototype.mayTriggerNotifOfType = function(notifLevelKey, userId) {\n const member = this.getMember(userId);\n if (!member) {\n return false;\n }\n\n const powerLevelsEvent = this.getStateEvents('m.room.power_levels', '');\n\n let notifLevel = 50;\n if (\n powerLevelsEvent &&\n powerLevelsEvent.getContent() &&\n powerLevelsEvent.getContent().notifications &&\n powerLevelsEvent.getContent().notifications[notifLevelKey]\n ) {\n notifLevel = powerLevelsEvent.getContent().notifications[notifLevelKey];\n }\n\n return member.powerLevel >= notifLevel;\n};\n\n/**\n * The RoomState class.\n */\nmodule.exports = RoomState;\n\n\nfunction _updateThirdPartyTokenCache(roomState, memberEvent) {\n if (!memberEvent.getContent().third_party_invite) {\n return;\n }\n const token = (memberEvent.getContent().third_party_invite.signed || {}).token;\n if (!token) {\n return;\n }\n const threePidInvite = roomState.getStateEvents(\n \"m.room.third_party_invite\", token,\n );\n if (!threePidInvite) {\n return;\n }\n roomState._tokenToInvite[token] = memberEvent;\n}\n\nfunction _updateDisplayNameCache(roomState, userId, displayName) {\n const oldName = roomState._userIdsToDisplayNames[userId];\n delete roomState._userIdsToDisplayNames[userId];\n if (oldName) {\n // Remove the old name from the cache.\n // We clobber the user_id > name lookup but the name -> [user_id] lookup\n // means we need to remove that user ID from that array rather than nuking\n // the lot.\n const existingUserIds = roomState._displayNameToUserIds[oldName] || [];\n for (let i = 0; i < existingUserIds.length; i++) {\n if (existingUserIds[i] === userId) {\n // remove this user ID from this array\n existingUserIds.splice(i, 1);\n i--;\n }\n }\n roomState._displayNameToUserIds[oldName] = existingUserIds;\n }\n\n roomState._userIdsToDisplayNames[userId] = displayName;\n if (!roomState._displayNameToUserIds[displayName]) {\n roomState._displayNameToUserIds[displayName] = [];\n }\n roomState._displayNameToUserIds[displayName].push(userId);\n}\n\n/**\n * Fires whenever the event dictionary in room state is updated.\n * @event module:client~MatrixClient#\"RoomState.events\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {RoomState} state The room state whose RoomState.events dictionary\n * was updated.\n * @example\n * matrixClient.on(\"RoomState.events\", function(event, state){\n * var newStateEvent = event;\n * });\n */\n\n/**\n * Fires whenever a member in the members dictionary is updated in any way.\n * @event module:client~MatrixClient#\"RoomState.members\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {RoomState} state The room state whose RoomState.members dictionary\n * was updated.\n * @param {RoomMember} member The room member that was updated.\n * @example\n * matrixClient.on(\"RoomState.members\", function(event, state, member){\n * var newMembershipState = member.membership;\n * });\n */\n\n /**\n * Fires whenever a member is added to the members dictionary. The RoomMember\n * will not be fully populated yet (e.g. no membership state).\n * @event module:client~MatrixClient#\"RoomState.newMember\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {RoomState} state The room state whose RoomState.members dictionary\n * was updated with a new entry.\n * @param {RoomMember} member The room member that was added.\n * @example\n * matrixClient.on(\"RoomState.newMember\", function(event, state, member){\n * // add event listeners on 'member'\n * });\n */\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * @module models/room-summary\n */\n\n/**\n * Construct a new Room Summary. A summary can be used for display on a recent\n * list, without having to load the entire room list into memory.\n * @constructor\n * @param {string} roomId Required. The ID of this room.\n * @param {Object} info Optional. The summary info. Additional keys are supported.\n * @param {string} info.title The title of the room (e.g. m.room.name)\n * @param {string} info.desc The description of the room (e.g.\n * m.room.topic)\n * @param {Number} info.numMembers The number of joined users.\n * @param {string[]} info.aliases The list of aliases for this room.\n * @param {Number} info.timestamp The timestamp for this room.\n */\nfunction RoomSummary(roomId, info) {\n this.roomId = roomId;\n this.info = info;\n}\n\n/**\n * The RoomSummary class.\n */\nmodule.exports = RoomSummary;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * @module models/room\n */\nconst EventEmitter = require(\"events\").EventEmitter;\n\nconst EventStatus = require(\"./event\").EventStatus;\nconst RoomSummary = require(\"./room-summary\");\nconst MatrixEvent = require(\"./event\").MatrixEvent;\nconst utils = require(\"../utils\");\nconst ContentRepo = require(\"../content-repo\");\nconst EventTimeline = require(\"./event-timeline\");\nconst EventTimelineSet = require(\"./event-timeline-set\");\n\nimport ReEmitter from '../ReEmitter';\n\nfunction synthesizeReceipt(userId, event, receiptType) {\n // console.log(\"synthesizing receipt for \"+event.getId());\n // This is really ugly because JS has no way to express an object literal\n // where the name of a key comes from an expression\n const fakeReceipt = {\n content: {},\n type: \"m.receipt\",\n room_id: event.getRoomId(),\n };\n fakeReceipt.content[event.getId()] = {};\n fakeReceipt.content[event.getId()][receiptType] = {};\n fakeReceipt.content[event.getId()][receiptType][userId] = {\n ts: event.getTs(),\n };\n return new MatrixEvent(fakeReceipt);\n}\n\n\n/**\n * Construct a new Room.\n *\n *

For a room, we store an ordered sequence of timelines, which may or may not\n * be continuous. Each timeline lists a series of events, as well as tracking\n * the room state at the start and the end of the timeline. It also tracks\n * forward and backward pagination tokens, as well as containing links to the\n * next timeline in the sequence.\n *\n *

There is one special timeline - the 'live' timeline, which represents the\n * timeline to which events are being added in real-time as they are received\n * from the /sync API. Note that you should not retain references to this\n * timeline - even if it is the current timeline right now, it may not remain\n * so if the server gives us a timeline gap in /sync.\n *\n *

In order that we can find events from their ids later, we also maintain a\n * map from event_id to timeline and index.\n *\n * @constructor\n * @alias module:models/room\n * @param {string} roomId Required. The ID of this room.\n * @param {Object=} opts Configuration options\n * @param {*} opts.storageToken Optional. The token which a data store can use\n * to remember the state of the room. What this means is dependent on the store\n * implementation.\n *\n * @param {String=} opts.pendingEventOrdering Controls where pending messages\n * appear in a room's timeline. If \"chronological\", messages will appear\n * in the timeline when the call to sendEvent was made. If\n * \"detached\", pending messages will appear in a separate list,\n * accessbile via {@link module:models/room#getPendingEvents}. Default:\n * \"chronological\".\n *\n * @param {boolean} [opts.timelineSupport = false] Set to true to enable improved\n * timeline support.\n *\n * @prop {string} roomId The ID of this room.\n * @prop {string} name The human-readable display name for this room.\n * @prop {Array} timeline The live event timeline for this room,\n * with the oldest event at index 0. Present for backwards compatibility -\n * prefer getLiveTimeline().getEvents().\n * @prop {object} tags Dict of room tags; the keys are the tag name and the values\n * are any metadata associated with the tag - e.g. { \"fav\" : { order: 1 } }\n * @prop {object} accountData Dict of per-room account_data events; the keys are the\n * event type and the values are the events.\n * @prop {RoomState} oldState The state of the room at the time of the oldest\n * event in the live timeline. Present for backwards compatibility -\n * prefer getLiveTimeline().getState(true).\n * @prop {RoomState} currentState The state of the room at the time of the\n * newest event in the timeline. Present for backwards compatibility -\n * prefer getLiveTimeline().getState(false).\n * @prop {RoomSummary} summary The room summary.\n * @prop {*} storageToken A token which a data store can use to remember\n * the state of the room.\n */\nfunction Room(roomId, opts) {\n opts = opts || {};\n opts.pendingEventOrdering = opts.pendingEventOrdering || \"chronological\";\n\n this.reEmitter = new ReEmitter(this);\n\n if ([\"chronological\", \"detached\"].indexOf(opts.pendingEventOrdering) === -1) {\n throw new Error(\n \"opts.pendingEventOrdering MUST be either 'chronological' or \" +\n \"'detached'. Got: '\" + opts.pendingEventOrdering + \"'\",\n );\n }\n\n this.roomId = roomId;\n this.name = roomId;\n this.tags = {\n // $tagName: { $metadata: $value },\n // $tagName: { $metadata: $value },\n };\n this.accountData = {\n // $eventType: $event\n };\n this.summary = null;\n this.storageToken = opts.storageToken;\n this._opts = opts;\n this._txnToEvent = {}; // Pending in-flight requests { string: MatrixEvent }\n // receipts should clobber based on receipt_type and user_id pairs hence\n // the form of this structure. This is sub-optimal for the exposed APIs\n // which pass in an event ID and get back some receipts, so we also store\n // a pre-cached list for this purpose.\n this._receipts = {\n // receipt_type: {\n // user_id: {\n // eventId: ,\n // data: \n // }\n // }\n };\n this._receiptCacheByEventId = {\n // $event_id: [{\n // type: $type,\n // userId: $user_id,\n // data: \n // }]\n };\n // only receipts that came from the server, not synthesized ones\n this._realReceipts = {};\n\n this._notificationCounts = {};\n\n // all our per-room timeline sets. the first one is the unfiltered ones;\n // the subsequent ones are the filtered ones in no particular order.\n this._timelineSets = [new EventTimelineSet(this, opts)];\n this.reEmitter.reEmit(this.getUnfilteredTimelineSet(),\n [\"Room.timeline\", \"Room.timelineReset\"]);\n\n this._fixUpLegacyTimelineFields();\n\n // any filtered timeline sets we're maintaining for this room\n this._filteredTimelineSets = {\n // filter_id: timelineSet\n };\n\n if (this._opts.pendingEventOrdering == \"detached\") {\n this._pendingEventList = [];\n }\n\n this._blacklistUnverifiedDevices = false; // read by megolm\n}\nutils.inherits(Room, EventEmitter);\n\n/**\n * Get the list of pending sent events for this room\n *\n * @return {module:models/event.MatrixEvent[]} A list of the sent events\n * waiting for remote echo.\n *\n * @throws If opts.pendingEventOrdering was not 'detached'\n */\nRoom.prototype.getPendingEvents = function() {\n if (this._opts.pendingEventOrdering !== \"detached\") {\n throw new Error(\n \"Cannot call getPendingEventList with pendingEventOrdering == \" +\n this._opts.pendingEventOrdering);\n }\n\n return this._pendingEventList;\n};\n\n/**\n * Get the live unfiltered timeline for this room.\n *\n * @return {module:models/event-timeline~EventTimeline} live timeline\n */\nRoom.prototype.getLiveTimeline = function() {\n return this.getUnfilteredTimelineSet().getLiveTimeline();\n};\n\n\n/**\n * Reset the live timeline of all timelineSets, and start new ones.\n *\n *

This is used when /sync returns a 'limited' timeline.\n *\n * @param {string=} backPaginationToken token for back-paginating the new timeline\n * @param {string=} forwardPaginationToken token for forward-paginating the old live timeline,\n * if absent or null, all timelines are reset, removing old ones (including the previous live\n * timeline which would otherwise be unable to paginate forwards without this token).\n * Removing just the old live timeline whilst preserving previous ones is not supported.\n */\nRoom.prototype.resetLiveTimeline = function(backPaginationToken, forwardPaginationToken) {\n for (let i = 0; i < this._timelineSets.length; i++) {\n this._timelineSets[i].resetLiveTimeline(\n backPaginationToken, forwardPaginationToken,\n );\n }\n\n this._fixUpLegacyTimelineFields();\n};\n\n/**\n * Fix up this.timeline, this.oldState and this.currentState\n *\n * @private\n */\nRoom.prototype._fixUpLegacyTimelineFields = function() {\n // maintain this.timeline as a reference to the live timeline,\n // and this.oldState and this.currentState as references to the\n // state at the start and end of that timeline. These are more\n // for backwards-compatibility than anything else.\n this.timeline = this.getLiveTimeline().getEvents();\n this.oldState = this.getLiveTimeline()\n .getState(EventTimeline.BACKWARDS);\n this.currentState = this.getLiveTimeline()\n .getState(EventTimeline.FORWARDS);\n};\n\n/**\n * Return the timeline sets for this room.\n * @return {EventTimelineSet[]} array of timeline sets for this room\n */\nRoom.prototype.getTimelineSets = function() {\n return this._timelineSets;\n};\n\n/**\n * Helper to return the main unfiltered timeline set for this room\n * @return {EventTimelineSet} room's unfiltered timeline set\n */\nRoom.prototype.getUnfilteredTimelineSet = function() {\n return this._timelineSets[0];\n};\n\n/**\n * Get the timeline which contains the given event from the unfiltered set, if any\n *\n * @param {string} eventId event ID to look for\n * @return {?module:models/event-timeline~EventTimeline} timeline containing\n * the given event, or null if unknown\n */\nRoom.prototype.getTimelineForEvent = function(eventId) {\n return this.getUnfilteredTimelineSet().getTimelineForEvent(eventId);\n};\n\n/**\n * Add a new timeline to this room's unfiltered timeline set\n *\n * @return {module:models/event-timeline~EventTimeline} newly-created timeline\n */\nRoom.prototype.addTimeline = function() {\n return this.getUnfilteredTimelineSet().addTimeline();\n};\n\n/**\n * Get an event which is stored in our unfiltered timeline set\n *\n * @param {string} eventId event ID to look for\n * @return {?module:models/event.MatrixEvent} the given event, or undefined if unknown\n */\nRoom.prototype.findEventById = function(eventId) {\n return this.getUnfilteredTimelineSet().findEventById(eventId);\n};\n\n/**\n * Get one of the notification counts for this room\n * @param {String} type The type of notification count to get. default: 'total'\n * @return {Number} The notification count, or undefined if there is no count\n * for this type.\n */\nRoom.prototype.getUnreadNotificationCount = function(type) {\n type = type || 'total';\n return this._notificationCounts[type];\n};\n\n/**\n * Set one of the notification counts for this room\n * @param {String} type The type of notification count to set.\n * @param {Number} count The new count\n */\nRoom.prototype.setUnreadNotificationCount = function(type, count) {\n this._notificationCounts[type] = count;\n};\n\n/**\n * Whether to send encrypted messages to devices within this room.\n * Will be ignored if MatrixClient's blacklistUnverifiedDevices setting is true.\n * @param {boolean} value if true, blacklist unverified devices.\n */\nRoom.prototype.setBlacklistUnverifiedDevices = function(value) {\n this._blacklistUnverifiedDevices = value;\n};\n\n/**\n * Whether to send encrypted messages to devices within this room.\n * Will be ignored if MatrixClient's blacklistUnverifiedDevices setting is true.\n * @return {boolean} true if blacklisting unverified devices.\n */\nRoom.prototype.getBlacklistUnverifiedDevices = function() {\n return this._blacklistUnverifiedDevices;\n};\n\n/**\n * Get the avatar URL for a room if one was set.\n * @param {String} baseUrl The homeserver base URL. See\n * {@link module:client~MatrixClient#getHomeserverUrl}.\n * @param {Number} width The desired width of the thumbnail.\n * @param {Number} height The desired height of the thumbnail.\n * @param {string} resizeMethod The thumbnail resize method to use, either\n * \"crop\" or \"scale\".\n * @param {boolean} allowDefault True to allow an identicon for this room if an\n * avatar URL wasn't explicitly set. Default: true.\n * @return {?string} the avatar URL or null.\n */\nRoom.prototype.getAvatarUrl = function(baseUrl, width, height, resizeMethod,\n allowDefault) {\n const roomAvatarEvent = this.currentState.getStateEvents(\"m.room.avatar\", \"\");\n if (allowDefault === undefined) {\n allowDefault = true;\n }\n if (!roomAvatarEvent && !allowDefault) {\n return null;\n }\n\n const mainUrl = roomAvatarEvent ? roomAvatarEvent.getContent().url : null;\n if (mainUrl) {\n return ContentRepo.getHttpUriForMxc(\n baseUrl, mainUrl, width, height, resizeMethod,\n );\n } else if (allowDefault) {\n return ContentRepo.getIdenticonUri(\n baseUrl, this.roomId, width, height,\n );\n }\n\n return null;\n};\n\n/**\n * Get the aliases this room has according to the room's state\n * The aliases returned by this function may not necessarily\n * still point to this room.\n * @return {array} The room's alias as an array of strings\n */\nRoom.prototype.getAliases = function() {\n const alias_strings = [];\n\n const alias_events = this.currentState.getStateEvents(\"m.room.aliases\");\n if (alias_events) {\n for (let i = 0; i < alias_events.length; ++i) {\n const alias_event = alias_events[i];\n if (utils.isArray(alias_event.getContent().aliases)) {\n Array.prototype.push.apply(\n alias_strings, alias_event.getContent().aliases,\n );\n }\n }\n }\n return alias_strings;\n};\n\n/**\n * Get this room's canonical alias\n * The alias returned by this function may not necessarily\n * still point to this room.\n * @return {?string} The room's canonical alias, or null if there is none\n */\nRoom.prototype.getCanonicalAlias = function() {\n const canonicalAlias = this.currentState.getStateEvents(\"m.room.canonical_alias\", \"\");\n if (canonicalAlias) {\n return canonicalAlias.getContent().alias;\n }\n return null;\n};\n\n/**\n * Add events to a timeline\n *\n *

Will fire \"Room.timeline\" for each event added.\n *\n * @param {MatrixEvent[]} events A list of events to add.\n *\n * @param {boolean} toStartOfTimeline True to add these events to the start\n * (oldest) instead of the end (newest) of the timeline. If true, the oldest\n * event will be the last element of 'events'.\n *\n * @param {module:models/event-timeline~EventTimeline} timeline timeline to\n * add events to.\n *\n * @param {string=} paginationToken token for the next batch of events\n *\n * @fires module:client~MatrixClient#event:\"Room.timeline\"\n *\n */\nRoom.prototype.addEventsToTimeline = function(events, toStartOfTimeline,\n timeline, paginationToken) {\n timeline.getTimelineSet().addEventsToTimeline(\n events, toStartOfTimeline,\n timeline, paginationToken,\n );\n};\n\n/**\n * Get a member from the current room state.\n * @param {string} userId The user ID of the member.\n * @return {RoomMember} The member or null.\n */\n Room.prototype.getMember = function(userId) {\n const member = this.currentState.members[userId];\n if (!member) {\n return null;\n }\n return member;\n };\n\n/**\n * Get a list of members whose membership state is \"join\".\n * @return {RoomMember[]} A list of currently joined members.\n */\n Room.prototype.getJoinedMembers = function() {\n return this.getMembersWithMembership(\"join\");\n };\n\n/**\n * Get a list of members with given membership state.\n * @param {string} membership The membership state.\n * @return {RoomMember[]} A list of members with the given membership state.\n */\n Room.prototype.getMembersWithMembership = function(membership) {\n return utils.filter(this.currentState.getMembers(), function(m) {\n return m.membership === membership;\n });\n };\n\n /**\n * Get the default room name (i.e. what a given user would see if the\n * room had no m.room.name)\n * @param {string} userId The userId from whose perspective we want\n * to calculate the default name\n * @return {string} The default room name\n */\n Room.prototype.getDefaultRoomName = function(userId) {\n return calculateRoomName(this, userId, true);\n };\n\n\n /**\n * Check if the given user_id has the given membership state.\n * @param {string} userId The user ID to check.\n * @param {string} membership The membership e.g. 'join'\n * @return {boolean} True if this user_id has the given membership state.\n */\n Room.prototype.hasMembershipState = function(userId, membership) {\n const member = this.getMember(userId);\n if (!member) {\n return false;\n }\n return member.membership === membership;\n };\n\n/**\n * Add a timelineSet for this room with the given filter\n * @param {Filter} filter The filter to be applied to this timelineSet\n * @return {EventTimelineSet} The timelineSet\n */\nRoom.prototype.getOrCreateFilteredTimelineSet = function(filter) {\n if (this._filteredTimelineSets[filter.filterId]) {\n return this._filteredTimelineSets[filter.filterId];\n }\n const opts = Object.assign({ filter: filter }, this._opts);\n const timelineSet = new EventTimelineSet(this, opts);\n this.reEmitter.reEmit(timelineSet, [\"Room.timeline\", \"Room.timelineReset\"]);\n this._filteredTimelineSets[filter.filterId] = timelineSet;\n this._timelineSets.push(timelineSet);\n\n // populate up the new timelineSet with filtered events from our live\n // unfiltered timeline.\n //\n // XXX: This is risky as our timeline\n // may have grown huge and so take a long time to filter.\n // see https://github.com/vector-im/vector-web/issues/2109\n\n const unfilteredLiveTimeline = this.getLiveTimeline();\n\n unfilteredLiveTimeline.getEvents().forEach(function(event) {\n timelineSet.addLiveEvent(event);\n });\n\n // find the earliest unfiltered timeline\n let timeline = unfilteredLiveTimeline;\n while (timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)) {\n timeline = timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS);\n }\n\n timelineSet.getLiveTimeline().setPaginationToken(\n timeline.getPaginationToken(EventTimeline.BACKWARDS),\n EventTimeline.BACKWARDS,\n );\n\n // alternatively, we could try to do something like this to try and re-paginate\n // in the filtered events from nothing, but Mark says it's an abuse of the API\n // to do so:\n //\n // timelineSet.resetLiveTimeline(\n // unfilteredLiveTimeline.getPaginationToken(EventTimeline.FORWARDS)\n // );\n\n return timelineSet;\n};\n\n/**\n * Forget the timelineSet for this room with the given filter\n *\n * @param {Filter} filter the filter whose timelineSet is to be forgotten\n */\nRoom.prototype.removeFilteredTimelineSet = function(filter) {\n const timelineSet = this._filteredTimelineSets[filter.filterId];\n delete this._filteredTimelineSets[filter.filterId];\n const i = this._timelineSets.indexOf(timelineSet);\n if (i > -1) {\n this._timelineSets.splice(i, 1);\n }\n};\n\n/**\n * Add an event to the end of this room's live timelines. Will fire\n * \"Room.timeline\".\n *\n * @param {MatrixEvent} event Event to be added\n * @param {string?} duplicateStrategy 'ignore' or 'replace'\n * @fires module:client~MatrixClient#event:\"Room.timeline\"\n * @private\n */\nRoom.prototype._addLiveEvent = function(event, duplicateStrategy) {\n let i;\n if (event.getType() === \"m.room.redaction\") {\n const redactId = event.event.redacts;\n\n // if we know about this event, redact its contents now.\n const redactedEvent = this.getUnfilteredTimelineSet().findEventById(redactId);\n if (redactedEvent) {\n redactedEvent.makeRedacted(event);\n this.emit(\"Room.redaction\", event, this);\n\n // TODO: we stash user displaynames (among other things) in\n // RoomMember objects which are then attached to other events\n // (in the sender and target fields). We should get those\n // RoomMember objects to update themselves when the events that\n // they are based on are changed.\n }\n\n // FIXME: apply redactions to notification list\n\n // NB: We continue to add the redaction event to the timeline so\n // clients can say \"so and so redacted an event\" if they wish to. Also\n // this may be needed to trigger an update.\n }\n\n if (event.getUnsigned().transaction_id) {\n const existingEvent = this._txnToEvent[event.getUnsigned().transaction_id];\n if (existingEvent) {\n // remote echo of an event we sent earlier\n this._handleRemoteEcho(event, existingEvent);\n return;\n }\n }\n\n // add to our timeline sets\n for (i = 0; i < this._timelineSets.length; i++) {\n this._timelineSets[i].addLiveEvent(event, duplicateStrategy);\n }\n\n // synthesize and inject implicit read receipts\n // Done after adding the event because otherwise the app would get a read receipt\n // pointing to an event that wasn't yet in the timeline\n if (event.sender) {\n this.addReceipt(synthesizeReceipt(\n event.sender.userId, event, \"m.read\",\n ), true);\n\n // Any live events from a user could be taken as implicit\n // presence information: evidence that they are currently active.\n // ...except in a world where we use 'user.currentlyActive' to reduce\n // presence spam, this isn't very useful - we'll get a transition when\n // they are no longer currently active anyway. So don't bother to\n // reset the lastActiveAgo and lastPresenceTs from the RoomState's user.\n }\n};\n\n\n/**\n * Add a pending outgoing event to this room.\n *\n *

The event is added to either the pendingEventList, or the live timeline,\n * depending on the setting of opts.pendingEventOrdering.\n *\n *

This is an internal method, intended for use by MatrixClient.\n *\n * @param {module:models/event.MatrixEvent} event The event to add.\n *\n * @param {string} txnId Transaction id for this outgoing event\n *\n * @fires module:client~MatrixClient#event:\"Room.localEchoUpdated\"\n *\n * @throws if the event doesn't have status SENDING, or we aren't given a\n * unique transaction id.\n */\nRoom.prototype.addPendingEvent = function(event, txnId) {\n if (event.status !== EventStatus.SENDING) {\n throw new Error(\"addPendingEvent called on an event with status \" +\n event.status);\n }\n\n if (this._txnToEvent[txnId]) {\n throw new Error(\"addPendingEvent called on an event with known txnId \" +\n txnId);\n }\n\n // call setEventMetadata to set up event.sender etc\n // as event is shared over all timelineSets, we set up its metadata based\n // on the unfiltered timelineSet.\n EventTimeline.setEventMetadata(\n event,\n this.getLiveTimeline().getState(EventTimeline.FORWARDS),\n false,\n );\n\n this._txnToEvent[txnId] = event;\n\n if (this._opts.pendingEventOrdering == \"detached\") {\n this._pendingEventList.push(event);\n } else {\n for (let i = 0; i < this._timelineSets.length; i++) {\n const timelineSet = this._timelineSets[i];\n if (timelineSet.getFilter()) {\n if (this._filter.filterRoomTimeline([event]).length) {\n timelineSet.addEventToTimeline(event,\n timelineSet.getLiveTimeline(), false);\n }\n } else {\n timelineSet.addEventToTimeline(event,\n timelineSet.getLiveTimeline(), false);\n }\n }\n }\n\n this.emit(\"Room.localEchoUpdated\", event, this, null, null);\n};\n\n/**\n * Deal with the echo of a message we sent.\n *\n *

We move the event to the live timeline if it isn't there already, and\n * update it.\n *\n * @param {module:models/event.MatrixEvent} remoteEvent The event received from\n * /sync\n * @param {module:models/event.MatrixEvent} localEvent The local echo, which\n * should be either in the _pendingEventList or the timeline.\n *\n * @fires module:client~MatrixClient#event:\"Room.localEchoUpdated\"\n * @private\n */\nRoom.prototype._handleRemoteEcho = function(remoteEvent, localEvent) {\n const oldEventId = localEvent.getId();\n const newEventId = remoteEvent.getId();\n const oldStatus = localEvent.status;\n\n // no longer pending\n delete this._txnToEvent[remoteEvent.transaction_id];\n\n // if it's in the pending list, remove it\n if (this._pendingEventList) {\n utils.removeElement(\n this._pendingEventList,\n function(ev) {\n return ev.getId() == oldEventId;\n }, false,\n );\n }\n\n // replace the event source (this will preserve the plaintext payload if\n // any, which is good, because we don't want to try decoding it again).\n localEvent.handleRemoteEcho(remoteEvent.event);\n\n for (let i = 0; i < this._timelineSets.length; i++) {\n const timelineSet = this._timelineSets[i];\n\n // if it's already in the timeline, update the timeline map. If it's not, add it.\n timelineSet.handleRemoteEcho(localEvent, oldEventId, newEventId);\n }\n\n this.emit(\"Room.localEchoUpdated\", localEvent, this,\n oldEventId, oldStatus);\n};\n\n/* a map from current event status to a list of allowed next statuses\n */\nconst ALLOWED_TRANSITIONS = {};\n\nALLOWED_TRANSITIONS[EventStatus.ENCRYPTING] = [\n EventStatus.SENDING,\n EventStatus.NOT_SENT,\n];\n\nALLOWED_TRANSITIONS[EventStatus.SENDING] = [\n EventStatus.ENCRYPTING,\n EventStatus.QUEUED,\n EventStatus.NOT_SENT,\n EventStatus.SENT,\n];\n\nALLOWED_TRANSITIONS[EventStatus.QUEUED] =\n [EventStatus.SENDING, EventStatus.CANCELLED];\n\nALLOWED_TRANSITIONS[EventStatus.SENT] =\n [];\n\nALLOWED_TRANSITIONS[EventStatus.NOT_SENT] =\n [EventStatus.SENDING, EventStatus.QUEUED, EventStatus.CANCELLED];\n\nALLOWED_TRANSITIONS[EventStatus.CANCELLED] =\n [];\n\n/**\n * Update the status / event id on a pending event, to reflect its transmission\n * progress.\n *\n *

This is an internal method.\n *\n * @param {MatrixEvent} event local echo event\n * @param {EventStatus} newStatus status to assign\n * @param {string} newEventId new event id to assign. Ignored unless\n * newStatus == EventStatus.SENT.\n * @fires module:client~MatrixClient#event:\"Room.localEchoUpdated\"\n */\nRoom.prototype.updatePendingEvent = function(event, newStatus, newEventId) {\n console.log(`setting pendingEvent status to ${newStatus} in ${event.getRoomId()}`);\n\n // if the message was sent, we expect an event id\n if (newStatus == EventStatus.SENT && !newEventId) {\n throw new Error(\"updatePendingEvent called with status=SENT, \" +\n \"but no new event id\");\n }\n\n // SENT races against /sync, so we have to special-case it.\n if (newStatus == EventStatus.SENT) {\n const timeline = this.getUnfilteredTimelineSet().eventIdToTimeline(newEventId);\n if (timeline) {\n // we've already received the event via the event stream.\n // nothing more to do here.\n return;\n }\n }\n\n const oldStatus = event.status;\n const oldEventId = event.getId();\n\n if (!oldStatus) {\n throw new Error(\"updatePendingEventStatus called on an event which is \" +\n \"not a local echo.\");\n }\n\n const allowed = ALLOWED_TRANSITIONS[oldStatus];\n if (!allowed || allowed.indexOf(newStatus) < 0) {\n throw new Error(\"Invalid EventStatus transition \" + oldStatus + \"->\" +\n newStatus);\n }\n\n event.status = newStatus;\n\n if (newStatus == EventStatus.SENT) {\n // update the event id\n event.event.event_id = newEventId;\n\n // if the event was already in the timeline (which will be the case if\n // opts.pendingEventOrdering==chronological), we need to update the\n // timeline map.\n for (let i = 0; i < this._timelineSets.length; i++) {\n this._timelineSets[i].replaceEventId(oldEventId, newEventId);\n }\n } else if (newStatus == EventStatus.CANCELLED) {\n // remove it from the pending event list, or the timeline.\n if (this._pendingEventList) {\n utils.removeElement(\n this._pendingEventList,\n function(ev) {\n return ev.getId() == oldEventId;\n }, false,\n );\n }\n this.removeEvent(oldEventId);\n }\n\n this.emit(\"Room.localEchoUpdated\", event, this, event.getId(), oldStatus);\n};\n\n\n/**\n * Add some events to this room. This can include state events, message\n * events and typing notifications. These events are treated as \"live\" so\n * they will go to the end of the timeline.\n *\n * @param {MatrixEvent[]} events A list of events to add.\n *\n * @param {string} duplicateStrategy Optional. Applies to events in the\n * timeline only. If this is 'replace' then if a duplicate is encountered, the\n * event passed to this function will replace the existing event in the\n * timeline. If this is not specified, or is 'ignore', then the event passed to\n * this function will be ignored entirely, preserving the existing event in the\n * timeline. Events are identical based on their event ID only.\n *\n * @throws If duplicateStrategy is not falsey, 'replace' or 'ignore'.\n */\nRoom.prototype.addLiveEvents = function(events, duplicateStrategy) {\n let i;\n if (duplicateStrategy && [\"replace\", \"ignore\"].indexOf(duplicateStrategy) === -1) {\n throw new Error(\"duplicateStrategy MUST be either 'replace' or 'ignore'\");\n }\n\n // sanity check that the live timeline is still live\n for (i = 0; i < this._timelineSets.length; i++) {\n const liveTimeline = this._timelineSets[i].getLiveTimeline();\n if (liveTimeline.getPaginationToken(EventTimeline.FORWARDS)) {\n throw new Error(\n \"live timeline \" + i + \" is no longer live - it has a pagination token \" +\n \"(\" + liveTimeline.getPaginationToken(EventTimeline.FORWARDS) + \")\",\n );\n }\n if (liveTimeline.getNeighbouringTimeline(EventTimeline.FORWARDS)) {\n throw new Error(\n \"live timeline \" + i + \" is no longer live - \" +\n \"it has a neighbouring timeline\",\n );\n }\n }\n\n for (i = 0; i < events.length; i++) {\n if (events[i].getType() === \"m.typing\") {\n this.currentState.setTypingEvent(events[i]);\n } else if (events[i].getType() === \"m.receipt\") {\n this.addReceipt(events[i]);\n }\n // N.B. account_data is added directly by /sync to avoid\n // having to maintain an event.isAccountData() here\n else {\n // TODO: We should have a filter to say \"only add state event\n // types X Y Z to the timeline\".\n this._addLiveEvent(events[i], duplicateStrategy);\n }\n }\n};\n\n/**\n * Removes events from this room.\n * @param {String[]} event_ids A list of event_ids to remove.\n */\nRoom.prototype.removeEvents = function(event_ids) {\n for (let i = 0; i < event_ids.length; ++i) {\n this.removeEvent(event_ids[i]);\n }\n};\n\n/**\n * Removes a single event from this room.\n *\n * @param {String} eventId The id of the event to remove\n *\n * @return {bool} true if the event was removed from any of the room's timeline sets\n */\nRoom.prototype.removeEvent = function(eventId) {\n let removedAny = false;\n for (let i = 0; i < this._timelineSets.length; i++) {\n const removed = this._timelineSets[i].removeEvent(eventId);\n if (removed) {\n removedAny = true;\n }\n }\n return removedAny;\n};\n\n\n/**\n * Recalculate various aspects of the room, including the room name and\n * room summary. Call this any time the room's current state is modified.\n * May fire \"Room.name\" if the room name is updated.\n * @param {string} userId The client's user ID.\n * @fires module:client~MatrixClient#event:\"Room.name\"\n */\nRoom.prototype.recalculate = function(userId) {\n // set fake stripped state events if this is an invite room so logic remains\n // consistent elsewhere.\n const self = this;\n const membershipEvent = this.currentState.getStateEvents(\n \"m.room.member\", userId,\n );\n if (membershipEvent && membershipEvent.getContent().membership === \"invite\") {\n const strippedStateEvents = membershipEvent.event.invite_room_state || [];\n utils.forEach(strippedStateEvents, function(strippedEvent) {\n const existingEvent = self.currentState.getStateEvents(\n strippedEvent.type, strippedEvent.state_key,\n );\n if (!existingEvent) {\n // set the fake stripped event instead\n self.currentState.setStateEvents([new MatrixEvent({\n type: strippedEvent.type,\n state_key: strippedEvent.state_key,\n content: strippedEvent.content,\n event_id: \"$fake\" + Date.now(),\n room_id: self.roomId,\n user_id: userId, // technically a lie\n })]);\n }\n });\n }\n\n const oldName = this.name;\n this.name = calculateRoomName(this, userId);\n this.summary = new RoomSummary(this.roomId, {\n title: this.name,\n });\n\n if (oldName !== this.name) {\n this.emit(\"Room.name\", this);\n }\n};\n\n\n/**\n * Get a list of user IDs who have read up to the given event.\n * @param {MatrixEvent} event the event to get read receipts for.\n * @return {String[]} A list of user IDs.\n */\nRoom.prototype.getUsersReadUpTo = function(event) {\n return this.getReceiptsForEvent(event).filter(function(receipt) {\n return receipt.type === \"m.read\";\n }).map(function(receipt) {\n return receipt.userId;\n });\n};\n\n/**\n * Get the ID of the event that a given user has read up to, or null if we\n * have received no read receipts from them.\n * @param {String} userId The user ID to get read receipt event ID for\n * @param {Boolean} ignoreSynthesized If true, return only receipts that have been\n * sent by the server, not implicit ones generated\n * by the JS SDK.\n * @return {String} ID of the latest event that the given user has read, or null.\n */\nRoom.prototype.getEventReadUpTo = function(userId, ignoreSynthesized) {\n let receipts = this._receipts;\n if (ignoreSynthesized) {\n receipts = this._realReceipts;\n }\n\n if (\n receipts[\"m.read\"] === undefined ||\n receipts[\"m.read\"][userId] === undefined\n ) {\n return null;\n }\n\n return receipts[\"m.read\"][userId].eventId;\n};\n\n/**\n * Get a list of receipts for the given event.\n * @param {MatrixEvent} event the event to get receipts for\n * @return {Object[]} A list of receipts with a userId, type and data keys or\n * an empty list.\n */\nRoom.prototype.getReceiptsForEvent = function(event) {\n return this._receiptCacheByEventId[event.getId()] || [];\n};\n\n/**\n * Add a receipt event to the room.\n * @param {MatrixEvent} event The m.receipt event.\n * @param {Boolean} fake True if this event is implicit\n */\nRoom.prototype.addReceipt = function(event, fake) {\n // event content looks like:\n // content: {\n // $event_id: {\n // $receipt_type: {\n // $user_id: {\n // ts: $timestamp\n // }\n // }\n // }\n // }\n if (fake === undefined) {\n fake = false;\n }\n if (!fake) {\n this._addReceiptsToStructure(event, this._realReceipts);\n // we don't bother caching real receipts by event ID\n // as there's nothing that would read it.\n }\n this._addReceiptsToStructure(event, this._receipts);\n this._receiptCacheByEventId = this._buildReceiptCache(this._receipts);\n\n // send events after we've regenerated the cache, otherwise things that\n // listened for the event would read from a stale cache\n this.emit(\"Room.receipt\", event, this);\n};\n\n/**\n * Add a receipt event to the room.\n * @param {MatrixEvent} event The m.receipt event.\n * @param {Object} receipts The object to add receipts to\n */\nRoom.prototype._addReceiptsToStructure = function(event, receipts) {\n const self = this;\n utils.keys(event.getContent()).forEach(function(eventId) {\n utils.keys(event.getContent()[eventId]).forEach(function(receiptType) {\n utils.keys(event.getContent()[eventId][receiptType]).forEach(\n function(userId) {\n const receipt = event.getContent()[eventId][receiptType][userId];\n\n if (!receipts[receiptType]) {\n receipts[receiptType] = {};\n }\n\n const existingReceipt = receipts[receiptType][userId];\n\n if (!existingReceipt) {\n receipts[receiptType][userId] = {};\n } else {\n // we only want to add this receipt if we think it is later\n // than the one we already have. (This is managed\n // server-side, but because we synthesize RRs locally we\n // have to do it here too.)\n const ordering = self.getUnfilteredTimelineSet().compareEventOrdering(\n existingReceipt.eventId, eventId);\n if (ordering !== null && ordering >= 0) {\n return;\n }\n }\n\n receipts[receiptType][userId] = {\n eventId: eventId,\n data: receipt,\n };\n });\n });\n });\n};\n\n/**\n * Build and return a map of receipts by event ID\n * @param {Object} receipts A map of receipts\n * @return {Object} Map of receipts by event ID\n */\nRoom.prototype._buildReceiptCache = function(receipts) {\n const receiptCacheByEventId = {};\n utils.keys(receipts).forEach(function(receiptType) {\n utils.keys(receipts[receiptType]).forEach(function(userId) {\n const receipt = receipts[receiptType][userId];\n if (!receiptCacheByEventId[receipt.eventId]) {\n receiptCacheByEventId[receipt.eventId] = [];\n }\n receiptCacheByEventId[receipt.eventId].push({\n userId: userId,\n type: receiptType,\n data: receipt.data,\n });\n });\n });\n return receiptCacheByEventId;\n};\n\n\n/**\n * Add a temporary local-echo receipt to the room to reflect in the\n * client the fact that we've sent one.\n * @param {string} userId The user ID if the receipt sender\n * @param {MatrixEvent} e The event that is to be acknowledged\n * @param {string} receiptType The type of receipt\n */\nRoom.prototype._addLocalEchoReceipt = function(userId, e, receiptType) {\n this.addReceipt(synthesizeReceipt(userId, e, receiptType), true);\n};\n\n/**\n * Update the room-tag event for the room. The previous one is overwritten.\n * @param {MatrixEvent} event the m.tag event\n */\nRoom.prototype.addTags = function(event) {\n // event content looks like:\n // content: {\n // tags: {\n // $tagName: { $metadata: $value },\n // $tagName: { $metadata: $value },\n // }\n // }\n\n // XXX: do we need to deep copy here?\n this.tags = event.getContent().tags;\n\n // XXX: we could do a deep-comparison to see if the tags have really\n // changed - but do we want to bother?\n this.emit(\"Room.tags\", event, this);\n};\n\n/**\n * Update the account_data events for this room, overwriting events of the same type.\n * @param {Array} events an array of account_data events to add\n */\nRoom.prototype.addAccountData = function(events) {\n for (let i = 0; i < events.length; i++) {\n const event = events[i];\n if (event.getType() === \"m.tag\") {\n this.addTags(event);\n }\n this.accountData[event.getType()] = event;\n this.emit(\"Room.accountData\", event, this);\n }\n};\n\n/**\n * Access account_data event of given event type for this room\n * @param {string} type the type of account_data event to be accessed\n * @return {?MatrixEvent} the account_data event in question\n */\nRoom.prototype.getAccountData = function(type) {\n return this.accountData[type];\n};\n\n/**\n * This is an internal method. Calculates the name of the room from the current\n * room state.\n * @param {Room} room The matrix room.\n * @param {string} userId The client's user ID. Used to filter room members\n * correctly.\n * @param {bool} ignoreRoomNameEvent Return the implicit room name that we'd see if there\n * was no m.room.name event.\n * @return {string} The calculated room name.\n */\nfunction calculateRoomName(room, userId, ignoreRoomNameEvent) {\n if (!ignoreRoomNameEvent) {\n // check for an alias, if any. for now, assume first alias is the\n // official one.\n const mRoomName = room.currentState.getStateEvents(\"m.room.name\", \"\");\n if (mRoomName && mRoomName.getContent() && mRoomName.getContent().name) {\n return mRoomName.getContent().name;\n }\n }\n\n let alias = room.getCanonicalAlias();\n\n if (!alias) {\n const aliases = room.getAliases();\n\n if (aliases.length) {\n alias = aliases[0];\n }\n }\n if (alias) {\n return alias;\n }\n\n // get members that are NOT ourselves and are actually in the room.\n const otherMembers = utils.filter(room.currentState.getMembers(), function(m) {\n return (\n m.userId !== userId && m.membership !== \"leave\" && m.membership !== \"ban\"\n );\n });\n const allMembers = utils.filter(room.currentState.getMembers(), function(m) {\n return (m.membership !== \"leave\");\n });\n const myMemberEventArray = utils.filter(room.currentState.getMembers(), function(m) {\n return (m.userId == userId);\n });\n const myMemberEvent = (\n (myMemberEventArray.length && myMemberEventArray[0].events) ?\n myMemberEventArray[0].events.member.event : undefined\n );\n\n // TODO: Localisation\n if (myMemberEvent && myMemberEvent.content.membership == \"invite\") {\n if (room.currentState.getMember(myMemberEvent.sender)) {\n // extract who invited us to the room\n return room.currentState.getMember(\n myMemberEvent.sender,\n ).name;\n } else if (allMembers[0].events.member) {\n // use the sender field from the invite event, although this only\n // gets us the mxid\n return myMemberEvent.sender;\n } else {\n return \"Room Invite\";\n }\n }\n\n\n if (otherMembers.length === 0) {\n if (allMembers.length === 1) {\n // self-chat, peeked room with 1 participant,\n // or inbound invite, or outbound 3PID invite.\n if (allMembers[0].userId === userId) {\n const thirdPartyInvites =\n room.currentState.getStateEvents(\"m.room.third_party_invite\");\n if (thirdPartyInvites && thirdPartyInvites.length > 0) {\n let name = \"Inviting \" +\n thirdPartyInvites[0].getContent().display_name;\n if (thirdPartyInvites.length > 1) {\n if (thirdPartyInvites.length == 2) {\n name += \" and \" +\n thirdPartyInvites[1].getContent().display_name;\n } else {\n name += \" and \" +\n thirdPartyInvites.length + \" others\";\n }\n }\n return name;\n } else {\n return \"Empty room\";\n }\n } else {\n return allMembers[0].name;\n }\n } else {\n // there really isn't anyone in this room...\n return \"Empty room\";\n }\n } else if (otherMembers.length === 1) {\n return otherMembers[0].name;\n } else if (otherMembers.length === 2) {\n return (\n otherMembers[0].name + \" and \" + otherMembers[1].name\n );\n } else {\n return (\n otherMembers[0].name + \" and \" + (otherMembers.length - 1) + \" others\"\n );\n }\n}\n\n/**\n * The Room class.\n */\nmodule.exports = Room;\n\n/**\n * Fires when an event we had previously received is redacted.\n *\n * (Note this is *not* fired when the redaction happens before we receive the\n * event).\n *\n * @event module:client~MatrixClient#\"Room.redaction\"\n * @param {MatrixEvent} event The matrix event which was redacted\n * @param {Room} room The room containing the redacted event\n */\n\n/**\n * Fires whenever the name of a room is updated.\n * @event module:client~MatrixClient#\"Room.name\"\n * @param {Room} room The room whose Room.name was updated.\n * @example\n * matrixClient.on(\"Room.name\", function(room){\n * var newName = room.name;\n * });\n */\n\n/**\n * Fires whenever a receipt is received for a room\n * @event module:client~MatrixClient#\"Room.receipt\"\n * @param {event} event The receipt event\n * @param {Room} room The room whose receipts was updated.\n * @example\n * matrixClient.on(\"Room.receipt\", function(event, room){\n * var receiptContent = event.getContent();\n * });\n */\n\n/**\n * Fires whenever a room's tags are updated.\n * @event module:client~MatrixClient#\"Room.tags\"\n * @param {event} event The tags event\n * @param {Room} room The room whose Room.tags was updated.\n * @example\n * matrixClient.on(\"Room.tags\", function(event, room){\n * var newTags = event.getContent().tags;\n * if (newTags[\"favourite\"]) showStar(room);\n * });\n */\n\n/**\n * Fires whenever a room's account_data is updated.\n * @event module:client~MatrixClient#\"Room.accountData\"\n * @param {event} event The account_data event\n * @param {Room} room The room whose account_data was updated.\n * @example\n * matrixClient.on(\"Room.accountData\", function(event, room){\n * if (event.getType() === \"m.room.colorscheme\") {\n * applyColorScheme(event.getContents());\n * }\n * });\n */\n\n/**\n * Fires when the status of a transmitted event is updated.\n *\n *

When an event is first transmitted, a temporary copy of the event is\n * inserted into the timeline, with a temporary event id, and a status of\n * 'SENDING'.\n *\n *

Once the echo comes back from the server, the content of the event\n * (MatrixEvent.event) is replaced by the complete event from the homeserver,\n * thus updating its event id, as well as server-generated fields such as the\n * timestamp. Its status is set to null.\n *\n *

Once the /send request completes, if the remote echo has not already\n * arrived, the event is updated with a new event id and the status is set to\n * 'SENT'. The server-generated fields are of course not updated yet.\n *\n *

If the /send fails, In this case, the event's status is set to\n * 'NOT_SENT'. If it is later resent, the process starts again, setting the\n * status to 'SENDING'. Alternatively, the message may be cancelled, which\n * removes the event from the room, and sets the status to 'CANCELLED'.\n *\n *

This event is raised to reflect each of the transitions above.\n *\n * @event module:client~MatrixClient#\"Room.localEchoUpdated\"\n *\n * @param {MatrixEvent} event The matrix event which has been updated\n *\n * @param {Room} room The room containing the redacted event\n *\n * @param {string} oldEventId The previous event id (the temporary event id,\n * except when updating a successfully-sent event when its echo arrives)\n *\n * @param {EventStatus} oldStatus The previous event status.\n */\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * @module models/search-result\n */\n\nconst EventContext = require(\"./event-context\");\nconst utils = require(\"../utils\");\n\n/**\n * Construct a new SearchResult\n *\n * @param {number} rank where this SearchResult ranks in the results\n * @param {event-context.EventContext} eventContext the matching event and its\n * context\n *\n * @constructor\n */\nfunction SearchResult(rank, eventContext) {\n this.rank = rank;\n this.context = eventContext;\n}\n\n/**\n * Create a SearchResponse from the response to /search\n * @static\n * @param {Object} jsonObj\n * @param {function} eventMapper\n * @return {SearchResult}\n */\n\nSearchResult.fromJson = function(jsonObj, eventMapper) {\n const jsonContext = jsonObj.context || {};\n const events_before = jsonContext.events_before || [];\n const events_after = jsonContext.events_after || [];\n\n const context = new EventContext(eventMapper(jsonObj.result));\n\n context.setPaginateToken(jsonContext.start, true);\n context.addEvents(utils.map(events_before, eventMapper), true);\n context.addEvents(utils.map(events_after, eventMapper), false);\n context.setPaginateToken(jsonContext.end, false);\n\n return new SearchResult(jsonObj.rank, context);\n};\n\n\n/**\n * The SearchResult class\n */\nmodule.exports = SearchResult;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * @module models/user\n */\n const EventEmitter = require(\"events\").EventEmitter;\n const utils = require(\"../utils\");\n\n/**\n * Construct a new User. A User must have an ID and can optionally have extra\n * information associated with it.\n * @constructor\n * @param {string} userId Required. The ID of this user.\n * @prop {string} userId The ID of the user.\n * @prop {Object} info The info object supplied in the constructor.\n * @prop {string} displayName The 'displayname' of the user if known.\n * @prop {string} avatarUrl The 'avatar_url' of the user if known.\n * @prop {string} presence The presence enum if known.\n * @prop {string} presenceStatusMsg The presence status message if known.\n * @prop {Number} lastActiveAgo The time elapsed in ms since the user interacted\n * proactively with the server, or we saw a message from the user\n * @prop {Number} lastPresenceTs Timestamp (ms since the epoch) for when we last\n * received presence data for this user. We can subtract\n * lastActiveAgo from this to approximate an absolute value for\n * when a user was last active.\n * @prop {Boolean} currentlyActive Whether we should consider lastActiveAgo to be\n * an approximation and that the user should be seen as active 'now'\n * @prop {Object} events The events describing this user.\n * @prop {MatrixEvent} events.presence The m.presence event for this user.\n */\nfunction User(userId) {\n this.userId = userId;\n this.presence = \"offline\";\n this.presenceStatusMsg = null;\n this.displayName = userId;\n this.rawDisplayName = userId;\n this.avatarUrl = null;\n this.lastActiveAgo = 0;\n this.lastPresenceTs = 0;\n this.currentlyActive = false;\n this.events = {\n presence: null,\n profile: null,\n };\n this._updateModifiedTime();\n}\nutils.inherits(User, EventEmitter);\n\n/**\n * Update this User with the given presence event. May fire \"User.presence\",\n * \"User.avatarUrl\" and/or \"User.displayName\" if this event updates this user's\n * properties.\n * @param {MatrixEvent} event The m.presence event.\n * @fires module:client~MatrixClient#event:\"User.presence\"\n * @fires module:client~MatrixClient#event:\"User.displayName\"\n * @fires module:client~MatrixClient#event:\"User.avatarUrl\"\n */\nUser.prototype.setPresenceEvent = function(event) {\n if (event.getType() !== \"m.presence\") {\n return;\n }\n const firstFire = this.events.presence === null;\n this.events.presence = event;\n\n const eventsToFire = [];\n if (event.getContent().presence !== this.presence || firstFire) {\n eventsToFire.push(\"User.presence\");\n }\n if (event.getContent().avatar_url &&\n event.getContent().avatar_url !== this.avatarUrl) {\n eventsToFire.push(\"User.avatarUrl\");\n }\n if (event.getContent().displayname &&\n event.getContent().displayname !== this.displayName) {\n eventsToFire.push(\"User.displayName\");\n }\n if (event.getContent().currently_active !== undefined &&\n event.getContent().currently_active !== this.currentlyActive) {\n eventsToFire.push(\"User.currentlyActive\");\n }\n\n this.presence = event.getContent().presence;\n eventsToFire.push(\"User.lastPresenceTs\");\n\n if (event.getContent().status_msg) {\n this.presenceStatusMsg = event.getContent().status_msg;\n }\n if (event.getContent().displayname) {\n this.displayName = event.getContent().displayname;\n }\n if (event.getContent().avatar_url) {\n this.avatarUrl = event.getContent().avatar_url;\n }\n this.lastActiveAgo = event.getContent().last_active_ago;\n this.lastPresenceTs = Date.now();\n this.currentlyActive = event.getContent().currently_active;\n\n this._updateModifiedTime();\n\n for (let i = 0; i < eventsToFire.length; i++) {\n this.emit(eventsToFire[i], event, this);\n }\n};\n\n/**\n * Manually set this user's display name. No event is emitted in response to this\n * as there is no underlying MatrixEvent to emit with.\n * @param {string} name The new display name.\n */\nUser.prototype.setDisplayName = function(name) {\n const oldName = this.displayName;\n this.displayName = name;\n if (name !== oldName) {\n this._updateModifiedTime();\n }\n};\n\n\n/**\n * Manually set this user's non-disambiguated display name. No event is emitted\n * in response to this as there is no underlying MatrixEvent to emit with.\n * @param {string} name The new display name.\n */\nUser.prototype.setRawDisplayName = function(name) {\n this.rawDisplayName = name;\n};\n\n\n/**\n * Manually set this user's avatar URL. No event is emitted in response to this\n * as there is no underlying MatrixEvent to emit with.\n * @param {string} url The new avatar URL.\n */\nUser.prototype.setAvatarUrl = function(url) {\n const oldUrl = this.avatarUrl;\n this.avatarUrl = url;\n if (url !== oldUrl) {\n this._updateModifiedTime();\n }\n};\n\n/**\n * Update the last modified time to the current time.\n */\nUser.prototype._updateModifiedTime = function() {\n this._modified = Date.now();\n};\n\n/**\n * Get the timestamp when this User was last updated. This timestamp is\n * updated when this User receives a new Presence event which has updated a\n * property on this object. It is updated before firing events.\n * @return {number} The timestamp\n */\nUser.prototype.getLastModifiedTime = function() {\n return this._modified;\n};\n\n/**\n * Get the absolute timestamp when this User was last known active on the server.\n * It is *NOT* accurate if this.currentlyActive is true.\n * @return {number} The timestamp\n */\nUser.prototype.getLastActiveTs = function() {\n return this.lastPresenceTs - this.lastActiveAgo;\n};\n\n/**\n * The User class.\n */\nmodule.exports = User;\n\n/**\n * Fires whenever any user's lastPresenceTs changes,\n * ie. whenever any presence event is received for a user.\n * @event module:client~MatrixClient#\"User.lastPresenceTs\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {User} user The user whose User.lastPresenceTs changed.\n * @example\n * matrixClient.on(\"User.lastPresenceTs\", function(event, user){\n * var newlastPresenceTs = user.lastPresenceTs;\n * });\n */\n\n/**\n * Fires whenever any user's presence changes.\n * @event module:client~MatrixClient#\"User.presence\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {User} user The user whose User.presence changed.\n * @example\n * matrixClient.on(\"User.presence\", function(event, user){\n * var newPresence = user.presence;\n * });\n */\n\n/**\n * Fires whenever any user's currentlyActive changes.\n * @event module:client~MatrixClient#\"User.currentlyActive\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {User} user The user whose User.currentlyActive changed.\n * @example\n * matrixClient.on(\"User.currentlyActive\", function(event, user){\n * var newCurrentlyActive = user.currentlyActive;\n * });\n */\n\n/**\n * Fires whenever any user's display name changes.\n * @event module:client~MatrixClient#\"User.displayName\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {User} user The user whose User.displayName changed.\n * @example\n * matrixClient.on(\"User.displayName\", function(event, user){\n * var newName = user.displayName;\n * });\n */\n\n/**\n * Fires whenever any user's avatar URL changes.\n * @event module:client~MatrixClient#\"User.avatarUrl\"\n * @param {MatrixEvent} event The matrix event which caused this event to fire.\n * @param {User} user The user whose User.avatarUrl changed.\n * @example\n * matrixClient.on(\"User.avatarUrl\", function(event, user){\n * var newUrl = user.avatarUrl;\n * });\n */\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 New Vector Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n/**\n * @module pushprocessor\n */\n\nconst RULEKINDS_IN_ORDER = ['override', 'content', 'room', 'sender', 'underride'];\n\n/**\n * Construct a Push Processor.\n * @constructor\n * @param {Object} client The Matrix client object to use\n */\nfunction PushProcessor(client) {\n const escapeRegExp = function(string) {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n const matchingRuleFromKindSet = (ev, kindset, device) => {\n for (let ruleKindIndex = 0;\n ruleKindIndex < RULEKINDS_IN_ORDER.length;\n ++ruleKindIndex) {\n const kind = RULEKINDS_IN_ORDER[ruleKindIndex];\n const ruleset = kindset[kind];\n\n for (let ruleIndex = 0; ruleIndex < ruleset.length; ++ruleIndex) {\n const rule = ruleset[ruleIndex];\n if (!rule.enabled) {\n continue;\n }\n\n const rawrule = templateRuleToRaw(kind, rule, device);\n if (!rawrule) {\n continue;\n }\n\n if (this.ruleMatchesEvent(rawrule, ev)) {\n rule.kind = kind;\n return rule;\n }\n }\n }\n return null;\n };\n\n const templateRuleToRaw = function(kind, tprule, device) {\n const rawrule = {\n 'rule_id': tprule.rule_id,\n 'actions': tprule.actions,\n 'conditions': [],\n };\n switch (kind) {\n case 'underride':\n case 'override':\n rawrule.conditions = tprule.conditions;\n break;\n case 'room':\n if (!tprule.rule_id) {\n return null;\n }\n rawrule.conditions.push({\n 'kind': 'event_match',\n 'key': 'room_id',\n 'pattern': tprule.rule_id,\n });\n break;\n case 'sender':\n if (!tprule.rule_id) {\n return null;\n }\n rawrule.conditions.push({\n 'kind': 'event_match',\n 'key': 'user_id',\n 'pattern': tprule.rule_id,\n });\n break;\n case 'content':\n if (!tprule.pattern) {\n return null;\n }\n rawrule.conditions.push({\n 'kind': 'event_match',\n 'key': 'content.body',\n 'pattern': tprule.pattern,\n });\n break;\n }\n if (device) {\n rawrule.conditions.push({\n 'kind': 'device',\n 'profile_tag': device,\n });\n }\n return rawrule;\n };\n\n const eventFulfillsCondition = function(cond, ev) {\n const condition_functions = {\n \"event_match\": eventFulfillsEventMatchCondition,\n \"device\": eventFulfillsDeviceCondition,\n \"contains_display_name\": eventFulfillsDisplayNameCondition,\n \"room_member_count\": eventFulfillsRoomMemberCountCondition,\n \"sender_notification_permission\": eventFulfillsSenderNotifPermCondition,\n };\n if (condition_functions[cond.kind]) {\n return condition_functions[cond.kind](cond, ev);\n }\n // unknown conditions: we previously matched all unknown conditions,\n // but given that rules can be added to the base rules on a server,\n // it's probably better to not match unknown conditions.\n return false;\n };\n\n const eventFulfillsSenderNotifPermCondition = function(cond, ev) {\n const notifLevelKey = cond['key'];\n if (!notifLevelKey) {\n return false;\n }\n\n const room = client.getRoom(ev.getRoomId());\n if (!room || !room.currentState) {\n return false;\n }\n\n // Note that this should not be the current state of the room but the state at\n // the point the event is in the DAG. Unfortunately the js-sdk does not store\n // this.\n return room.currentState.mayTriggerNotifOfType(notifLevelKey, ev.getSender());\n };\n\n const eventFulfillsRoomMemberCountCondition = function(cond, ev) {\n if (!cond.is) {\n return false;\n }\n\n const room = client.getRoom(ev.getRoomId());\n if (!room || !room.currentState || !room.currentState.members) {\n return false;\n }\n\n const memberCount = Object.keys(room.currentState.members).filter(function(m) {\n return room.currentState.members[m].membership == 'join';\n }).length;\n\n const m = cond.is.match(/^([=<>]*)([0-9]*)$/);\n if (!m) {\n return false;\n }\n const ineq = m[1];\n const rhs = parseInt(m[2]);\n if (isNaN(rhs)) {\n return false;\n }\n switch (ineq) {\n case '':\n case '==':\n return memberCount == rhs;\n case '<':\n return memberCount < rhs;\n case '>':\n return memberCount > rhs;\n case '<=':\n return memberCount <= rhs;\n case '>=':\n return memberCount >= rhs;\n default:\n return false;\n }\n };\n\n const eventFulfillsDisplayNameCondition = function(cond, ev) {\n const content = ev.getContent();\n if (!content || !content.body || typeof content.body != 'string') {\n return false;\n }\n\n const room = client.getRoom(ev.getRoomId());\n if (!room || !room.currentState || !room.currentState.members ||\n !room.currentState.getMember(client.credentials.userId)) {\n return false;\n }\n\n const displayName = room.currentState.getMember(client.credentials.userId).name;\n\n // N.B. we can't use \\b as it chokes on unicode. however \\W seems to be okay\n // as shorthand for [^0-9A-Za-z_].\n const pat = new RegExp(\"(^|\\\\W)\" + escapeRegExp(displayName) + \"(\\\\W|$)\", 'i');\n return content.body.search(pat) > -1;\n };\n\n const eventFulfillsDeviceCondition = function(cond, ev) {\n return false; // XXX: Allow a profile tag to be set for the web client instance\n };\n\n const eventFulfillsEventMatchCondition = function(cond, ev) {\n const val = valueForDottedKey(cond.key, ev);\n if (!val || typeof val != 'string') {\n return false;\n }\n\n let pat;\n if (cond.key == 'content.body') {\n pat = '(^|\\\\W)' + globToRegexp(cond.pattern) + '(\\\\W|$)';\n } else {\n pat = '^' + globToRegexp(cond.pattern) + '$';\n }\n const regex = new RegExp(pat, 'i');\n return !!val.match(regex);\n };\n\n const globToRegexp = function(glob) {\n // From\n // https://github.com/matrix-org/synapse/blob/abbee6b29be80a77e05730707602f3bbfc3f38cb/synapse/push/__init__.py#L132\n // Because micromatch is about 130KB with dependencies,\n // and minimatch is not much better.\n let pat = escapeRegExp(glob);\n pat = pat.replace(/\\\\\\*/g, '.*');\n pat = pat.replace(/\\?/g, '.');\n pat = pat.replace(/\\\\\\[(!|)(.*)\\\\]/g, function(match, p1, p2, offset, string) {\n const first = p1 && '^' || '';\n const second = p2.replace(/\\\\\\-/, '-');\n return '[' + first + second + ']';\n });\n return pat;\n };\n\n const valueForDottedKey = function(key, ev) {\n const parts = key.split('.');\n let val;\n\n // special-case the first component to deal with encrypted messages\n const firstPart = parts[0];\n if (firstPart == 'content') {\n val = ev.getContent();\n parts.shift();\n } else if (firstPart == 'type') {\n val = ev.getType();\n parts.shift();\n } else {\n // use the raw event for any other fields\n val = ev.event;\n }\n\n while (parts.length > 0) {\n const thispart = parts.shift();\n if (!val[thispart]) {\n return null;\n }\n val = val[thispart];\n }\n return val;\n };\n\n const matchingRuleForEventWithRulesets = function(ev, rulesets) {\n if (!rulesets || !rulesets.device) {\n return null;\n }\n if (ev.getSender() == client.credentials.userId) {\n return null;\n }\n\n const allDevNames = Object.keys(rulesets.device);\n for (let i = 0; i < allDevNames.length; ++i) {\n const devname = allDevNames[i];\n const devrules = rulesets.device[devname];\n\n const matchingRule = matchingRuleFromKindSet(devrules, devname);\n if (matchingRule) {\n return matchingRule;\n }\n }\n return matchingRuleFromKindSet(ev, rulesets.global);\n };\n\n const pushActionsForEventAndRulesets = function(ev, rulesets) {\n const rule = matchingRuleForEventWithRulesets(ev, rulesets);\n if (!rule) {\n return {};\n }\n\n const actionObj = PushProcessor.actionListToActionsObject(rule.actions);\n\n // Some actions are implicit in some situations: we add those here\n if (actionObj.tweaks.highlight === undefined) {\n // if it isn't specified, highlight if it's a content\n // rule but otherwise not\n actionObj.tweaks.highlight = (rule.kind == 'content');\n }\n\n return actionObj;\n };\n\n this.ruleMatchesEvent = function(rule, ev) {\n let ret = true;\n for (let i = 0; i < rule.conditions.length; ++i) {\n const cond = rule.conditions[i];\n ret &= eventFulfillsCondition(cond, ev);\n }\n //console.log(\"Rule \"+rule.rule_id+(ret ? \" matches\" : \" doesn't match\"));\n return ret;\n };\n\n\n /**\n * Get the user's push actions for the given event\n *\n * @param {module:models/event.MatrixEvent} ev\n *\n * @return {PushAction}\n */\n this.actionsForEvent = function(ev) {\n return pushActionsForEventAndRulesets(ev, client.pushRules);\n };\n\n /**\n * Get one of the users push rules by its ID\n *\n * @param {string} ruleId The ID of the rule to search for\n * @return {object} The push rule, or null if no such rule was found\n */\n this.getPushRuleById = function(ruleId) {\n for (const scope of ['device', 'global']) {\n if (client.pushRules[scope] === undefined) continue;\n\n for (const kind of RULEKINDS_IN_ORDER) {\n if (client.pushRules[scope][kind] === undefined) continue;\n\n for (const rule of client.pushRules[scope][kind]) {\n if (rule.rule_id === ruleId) return rule;\n }\n }\n }\n return null;\n };\n}\n\n/**\n * Convert a list of actions into a object with the actions as keys and their values\n * eg. [ 'notify', { set_tweak: 'sound', value: 'default' } ]\n * becomes { notify: true, tweaks: { sound: 'default' } }\n * @param {array} actionlist The actions list\n *\n * @return {object} A object with key 'notify' (true or false) and an object of actions\n */\nPushProcessor.actionListToActionsObject = function(actionlist) {\n const actionobj = { 'notify': false, 'tweaks': {} };\n for (let i = 0; i < actionlist.length; ++i) {\n const action = actionlist[i];\n if (action === 'notify') {\n actionobj.notify = true;\n } else if (typeof action === 'object') {\n if (action.value === undefined) {\n action.value = true;\n }\n actionobj.tweaks[action.set_tweak] = action.value;\n }\n }\n return actionobj;\n};\n\n/**\n * @typedef {Object} PushAction\n * @type {Object}\n * @property {boolean} notify Whether this event should notify the user or not.\n * @property {Object} tweaks How this event should be notified.\n * @property {boolean} tweaks.highlight Whether this event should be highlighted\n * on the UI.\n * @property {boolean} tweaks.sound Whether this notification should produce a\n * noise.\n */\n\n/** The PushProcessor class. */\nmodule.exports = PushProcessor;\n\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/* A re-implementation of the javascript callback functions (setTimeout,\n * clearTimeout; setInterval and clearInterval are not yet implemented) which\n * try to improve handling of large clock jumps (as seen when\n * suspending/resuming the system).\n *\n * In particular, if a timeout would have fired while the system was suspended,\n * it will instead fire as soon as possible after resume.\n */\n\n\"use strict\";\n\n// we schedule a callback at least this often, to check if we've missed out on\n// some wall-clock time due to being suspended.\nconst TIMER_CHECK_PERIOD_MS = 1000;\n\n// counter, for making up ids to return from setTimeout\nlet _count = 0;\n\n// the key for our callback with the real global.setTimeout\nlet _realCallbackKey;\n\n// a sorted list of the callbacks to be run.\n// each is an object with keys [runAt, func, params, key].\nconst _callbackList = [];\n\n// var debuglog = console.log.bind(console);\nconst debuglog = function() {};\n\n/**\n * Replace the function used by this module to get the current time.\n *\n * Intended for use by the unit tests.\n *\n * @param {function} f function which should return a millisecond counter\n *\n * @internal\n */\nmodule.exports.setNow = function(f) {\n _now = f || Date.now;\n};\nlet _now = Date.now;\n\n/**\n * reimplementation of window.setTimeout, which will call the callback if\n * the wallclock time goes past the deadline.\n *\n * @param {function} func callback to be called after a delay\n * @param {Number} delayMs number of milliseconds to delay by\n *\n * @return {Number} an identifier for this callback, which may be passed into\n * clearTimeout later.\n */\nmodule.exports.setTimeout = function(func, delayMs) {\n delayMs = delayMs || 0;\n if (delayMs < 0) {\n delayMs = 0;\n }\n\n const params = Array.prototype.slice.call(arguments, 2);\n const runAt = _now() + delayMs;\n const key = _count++;\n debuglog(\"setTimeout: scheduling cb\", key, \"at\", runAt,\n \"(delay\", delayMs, \")\");\n const data = {\n runAt: runAt,\n func: func,\n params: params,\n key: key,\n };\n\n // figure out where it goes in the list\n const idx = binarySearch(\n _callbackList, function(el) {\n return el.runAt - runAt;\n },\n );\n\n _callbackList.splice(idx, 0, data);\n _scheduleRealCallback();\n\n return key;\n};\n\n/**\n * reimplementation of window.clearTimeout, which mirrors setTimeout\n *\n * @param {Number} key result from an earlier setTimeout call\n */\nmodule.exports.clearTimeout = function(key) {\n if (_callbackList.length === 0) {\n return;\n }\n\n // remove the element from the list\n let i;\n for (i = 0; i < _callbackList.length; i++) {\n const cb = _callbackList[i];\n if (cb.key == key) {\n _callbackList.splice(i, 1);\n break;\n }\n }\n\n // iff it was the first one in the list, reschedule our callback.\n if (i === 0) {\n _scheduleRealCallback();\n }\n};\n\n// use the real global.setTimeout to schedule a callback to _runCallbacks.\nfunction _scheduleRealCallback() {\n if (_realCallbackKey) {\n global.clearTimeout(_realCallbackKey);\n }\n\n const first = _callbackList[0];\n\n if (!first) {\n debuglog(\"_scheduleRealCallback: no more callbacks, not rescheduling\");\n return;\n }\n\n const now = _now();\n const delayMs = Math.min(first.runAt - now, TIMER_CHECK_PERIOD_MS);\n\n debuglog(\"_scheduleRealCallback: now:\", now, \"delay:\", delayMs);\n _realCallbackKey = global.setTimeout(_runCallbacks, delayMs);\n}\n\nfunction _runCallbacks() {\n let cb;\n const now = _now();\n debuglog(\"_runCallbacks: now:\", now);\n\n // get the list of things to call\n const callbacksToRun = [];\n while (true) {\n const first = _callbackList[0];\n if (!first || first.runAt > now) {\n break;\n }\n cb = _callbackList.shift();\n debuglog(\"_runCallbacks: popping\", cb.key);\n callbacksToRun.push(cb);\n }\n\n // reschedule the real callback before running our functions, to\n // keep the codepaths the same whether or not our functions\n // register their own setTimeouts.\n _scheduleRealCallback();\n\n for (let i = 0; i < callbacksToRun.length; i++) {\n cb = callbacksToRun[i];\n try {\n cb.func.apply(global, cb.params);\n } catch (e) {\n console.error(\"Uncaught exception in callback function\",\n e.stack || e);\n }\n }\n}\n\n\n/* search in a sorted array.\n *\n * returns the index of the last element for which func returns\n * greater than zero, or array.length if no such element exists.\n */\nfunction binarySearch(array, func) {\n // min is inclusive, max exclusive.\n let min = 0,\n max = array.length;\n\n while (min < max) {\n const mid = (min + max) >> 1;\n const res = func(array[mid]);\n if (res > 0) {\n // the element at 'mid' is too big; set it as the new max.\n max = mid;\n } else {\n // the element at 'mid' is too small. 'min' is inclusive, so +1.\n min = mid + 1;\n }\n }\n // presumably, min==max now.\n return min;\n}\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * This is an internal module which manages queuing, scheduling and retrying\n * of requests.\n * @module scheduler\n */\nconst utils = require(\"./utils\");\nimport Promise from 'bluebird';\n\nconst DEBUG = false; // set true to enable console logging.\n\n/**\n * Construct a scheduler for Matrix. Requires\n * {@link module:scheduler~MatrixScheduler#setProcessFunction} to be provided\n * with a way of processing events.\n * @constructor\n * @param {module:scheduler~retryAlgorithm} retryAlgorithm Optional. The retry\n * algorithm to apply when determining when to try to send an event again.\n * Defaults to {@link module:scheduler~MatrixScheduler.RETRY_BACKOFF_RATELIMIT}.\n * @param {module:scheduler~queueAlgorithm} queueAlgorithm Optional. The queuing\n * algorithm to apply when determining which events should be sent before the\n * given event. Defaults to {@link module:scheduler~MatrixScheduler.QUEUE_MESSAGES}.\n */\nfunction MatrixScheduler(retryAlgorithm, queueAlgorithm) {\n this.retryAlgorithm = retryAlgorithm || MatrixScheduler.RETRY_BACKOFF_RATELIMIT;\n this.queueAlgorithm = queueAlgorithm || MatrixScheduler.QUEUE_MESSAGES;\n this._queues = {\n // queueName: [{\n // event: MatrixEvent, // event to send\n // defer: Deferred, // defer to resolve/reject at the END of the retries\n // attempts: Number // number of times we've called processFn\n // }, ...]\n };\n this._activeQueues = [];\n this._procFn = null;\n}\n\n/**\n * Retrieve a queue based on an event. The event provided does not need to be in\n * the queue.\n * @param {MatrixEvent} event An event to get the queue for.\n * @return {?Array} A shallow copy of events in the queue or null.\n * Modifying this array will not modify the list itself. Modifying events in\n * this array will modify the underlying event in the queue.\n * @see MatrixScheduler.removeEventFromQueue To remove an event from the queue.\n */\nMatrixScheduler.prototype.getQueueForEvent = function(event) {\n const name = this.queueAlgorithm(event);\n if (!name || !this._queues[name]) {\n return null;\n }\n return utils.map(this._queues[name], function(obj) {\n return obj.event;\n });\n};\n\n/**\n * Remove this event from the queue. The event is equal to another event if they\n * have the same ID returned from event.getId().\n * @param {MatrixEvent} event The event to remove.\n * @return {boolean} True if this event was removed.\n */\nMatrixScheduler.prototype.removeEventFromQueue = function(event) {\n const name = this.queueAlgorithm(event);\n if (!name || !this._queues[name]) {\n return false;\n }\n let removed = false;\n utils.removeElement(this._queues[name], function(element) {\n if (element.event.getId() === event.getId()) {\n // XXX we should probably reject the promise?\n // https://github.com/matrix-org/matrix-js-sdk/issues/496\n removed = true;\n return true;\n }\n });\n return removed;\n};\n\n\n/**\n * Set the process function. Required for events in the queue to be processed.\n * If set after events have been added to the queue, this will immediately start\n * processing them.\n * @param {module:scheduler~processFn} fn The function that can process events\n * in the queue.\n */\nMatrixScheduler.prototype.setProcessFunction = function(fn) {\n this._procFn = fn;\n _startProcessingQueues(this);\n};\n\n/**\n * Queue an event if it is required and start processing queues.\n * @param {MatrixEvent} event The event that may be queued.\n * @return {?Promise} A promise if the event was queued, which will be\n * resolved or rejected in due time, else null.\n */\nMatrixScheduler.prototype.queueEvent = function(event) {\n const queueName = this.queueAlgorithm(event);\n if (!queueName) {\n return null;\n }\n // add the event to the queue and make a deferred for it.\n if (!this._queues[queueName]) {\n this._queues[queueName] = [];\n }\n const defer = Promise.defer();\n this._queues[queueName].push({\n event: event,\n defer: defer,\n attempts: 0,\n });\n debuglog(\n \"Queue algorithm dumped event %s into queue '%s'\",\n event.getId(), queueName,\n );\n _startProcessingQueues(this);\n return defer.promise;\n};\n\n/**\n * Retries events up to 4 times using exponential backoff. This produces wait\n * times of 2, 4, 8, and 16 seconds (30s total) after which we give up. If the\n * failure was due to a rate limited request, the time specified in the error is\n * waited before being retried.\n * @param {MatrixEvent} event\n * @param {Number} attempts\n * @param {MatrixError} err\n * @return {Number}\n * @see module:scheduler~retryAlgorithm\n */\nMatrixScheduler.RETRY_BACKOFF_RATELIMIT = function(event, attempts, err) {\n if (err.httpStatus === 400 || err.httpStatus === 403 || err.httpStatus === 401) {\n // client error; no amount of retrying with save you now.\n return -1;\n }\n // we ship with browser-request which returns { cors: rejected } when trying\n // with no connection, so if we match that, give up since they have no conn.\n if (err.cors === \"rejected\") {\n return -1;\n }\n\n if (err.name === \"M_LIMIT_EXCEEDED\") {\n const waitTime = err.data.retry_after_ms;\n if (waitTime) {\n return waitTime;\n }\n }\n if (attempts > 4) {\n return -1; // give up\n }\n return (1000 * Math.pow(2, attempts));\n};\n\n/**\n * Queues m.room.message events and lets other events continue\n * concurrently.\n * @param {MatrixEvent} event\n * @return {string}\n * @see module:scheduler~queueAlgorithm\n */\nMatrixScheduler.QUEUE_MESSAGES = function(event) {\n if (event.getType() === \"m.room.message\") {\n // put these events in the 'message' queue.\n return \"message\";\n }\n // allow all other events continue concurrently.\n return null;\n};\n\nfunction _startProcessingQueues(scheduler) {\n if (!scheduler._procFn) {\n return;\n }\n // for each inactive queue with events in them\n utils.forEach(utils.filter(utils.keys(scheduler._queues), function(queueName) {\n return scheduler._activeQueues.indexOf(queueName) === -1 &&\n scheduler._queues[queueName].length > 0;\n }), function(queueName) {\n // mark the queue as active\n scheduler._activeQueues.push(queueName);\n // begin processing the head of the queue\n debuglog(\"Spinning up queue: '%s'\", queueName);\n _processQueue(scheduler, queueName);\n });\n}\n\nfunction _processQueue(scheduler, queueName) {\n // get head of queue\n const obj = _peekNextEvent(scheduler, queueName);\n if (!obj) {\n // queue is empty. Mark as inactive and stop recursing.\n const index = scheduler._activeQueues.indexOf(queueName);\n if (index >= 0) {\n scheduler._activeQueues.splice(index, 1);\n }\n debuglog(\"Stopping queue '%s' as it is now empty\", queueName);\n return;\n }\n debuglog(\n \"Queue '%s' has %s pending events\",\n queueName, scheduler._queues[queueName].length,\n );\n // fire the process function and if it resolves, resolve the deferred. Else\n // invoke the retry algorithm.\n scheduler._procFn(obj.event).done(function(res) {\n // remove this from the queue\n _removeNextEvent(scheduler, queueName);\n debuglog(\"Queue '%s' sent event %s\", queueName, obj.event.getId());\n obj.defer.resolve(res);\n // keep processing\n _processQueue(scheduler, queueName);\n }, function(err) {\n obj.attempts += 1;\n // ask the retry algorithm when/if we should try again\n const waitTimeMs = scheduler.retryAlgorithm(obj.event, obj.attempts, err);\n debuglog(\n \"retry(%s) err=%s event_id=%s waitTime=%s\",\n obj.attempts, err, obj.event.getId(), waitTimeMs,\n );\n if (waitTimeMs === -1) { // give up (you quitter!)\n debuglog(\n \"Queue '%s' giving up on event %s\", queueName, obj.event.getId(),\n );\n // remove this from the queue\n _removeNextEvent(scheduler, queueName);\n obj.defer.reject(err);\n // process next event\n _processQueue(scheduler, queueName);\n } else {\n setTimeout(function() {\n _processQueue(scheduler, queueName);\n }, waitTimeMs);\n }\n });\n}\n\nfunction _peekNextEvent(scheduler, queueName) {\n const queue = scheduler._queues[queueName];\n if (!utils.isArray(queue)) {\n return null;\n }\n return queue[0];\n}\n\nfunction _removeNextEvent(scheduler, queueName) {\n const queue = scheduler._queues[queueName];\n if (!utils.isArray(queue)) {\n return null;\n }\n return queue.shift();\n}\n\nfunction debuglog() {\n if (DEBUG) {\n console.log(...arguments);\n }\n}\n\n/**\n * The retry algorithm to apply when retrying events. To stop retrying, return\n * -1. If this event was part of a queue, it will be removed from\n * the queue.\n * @callback retryAlgorithm\n * @param {MatrixEvent} event The event being retried.\n * @param {Number} attempts The number of failed attempts. This will always be\n * >= 1.\n * @param {MatrixError} err The most recent error message received when trying\n * to send this event.\n * @return {Number} The number of milliseconds to wait before trying again. If\n * this is 0, the request will be immediately retried. If this is\n * -1, the event will be marked as\n * {@link module:models/event.EventStatus.NOT_SENT} and will not be retried.\n */\n\n/**\n * The queuing algorithm to apply to events. This function must be idempotent as\n * it may be called multiple times with the same event. All queues created are\n * serviced in a FIFO manner. To send the event ASAP, return null\n * which will not put this event in a queue. Events that fail to send that form\n * part of a queue will be removed from the queue and the next event in the\n * queue will be sent.\n * @callback queueAlgorithm\n * @param {MatrixEvent} event The event to be sent.\n * @return {string} The name of the queue to put the event into. If a queue with\n * this name does not exist, it will be created. If this is null,\n * the event is not put into a queue and will be sent concurrently.\n */\n\n /**\n * The function to invoke to process (send) events in the queue.\n * @callback processFn\n * @param {MatrixEvent} event The event to send.\n * @return {Promise} Resolved/rejected depending on the outcome of the request.\n */\n\n/**\n * The MatrixScheduler class.\n */\nmodule.exports = MatrixScheduler;\n","/*\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport Promise from 'bluebird';\nimport SyncAccumulator from \"../sync-accumulator\";\nimport utils from \"../utils\";\n\nconst VERSION = 1;\n\nfunction createDatabase(db) {\n // Make user store, clobber based on user ID. (userId property of User objects)\n db.createObjectStore(\"users\", { keyPath: [\"userId\"] });\n\n // Make account data store, clobber based on event type.\n // (event.type property of MatrixEvent objects)\n db.createObjectStore(\"accountData\", { keyPath: [\"type\"] });\n\n // Make /sync store (sync tokens, room data, etc), always clobber (const key).\n db.createObjectStore(\"sync\", { keyPath: [\"clobber\"] });\n}\n\n/**\n * Helper method to collect results from a Cursor and promiseify it.\n * @param {ObjectStore|Index} store The store to perform openCursor on.\n * @param {IDBKeyRange=} keyRange Optional key range to apply on the cursor.\n * @param {Function} resultMapper A function which is repeatedly called with a\n * Cursor.\n * Return the data you want to keep.\n * @return {Promise} Resolves to an array of whatever you returned from\n * resultMapper.\n */\nfunction selectQuery(store, keyRange, resultMapper) {\n const query = store.openCursor(keyRange);\n return new Promise((resolve, reject) => {\n const results = [];\n query.onerror = (event) => {\n reject(new Error(\"Query failed: \" + event.target.errorCode));\n };\n // collect results\n query.onsuccess = (event) => {\n const cursor = event.target.result;\n if (!cursor) {\n resolve(results);\n return; // end of results\n }\n results.push(resultMapper(cursor));\n cursor.continue();\n };\n });\n}\n\nfunction promiseifyTxn(txn) {\n return new Promise((resolve, reject) => {\n txn.oncomplete = function(event) {\n resolve(event);\n };\n txn.onerror = function(event) {\n reject(event);\n };\n });\n}\n\nfunction promiseifyRequest(req) {\n return new Promise((resolve, reject) => {\n req.onsuccess = function(event) {\n resolve(event);\n };\n req.onerror = function(event) {\n reject(event);\n };\n });\n}\n\n/**\n * Does the actual reading from and writing to the indexeddb\n *\n * Construct a new Indexed Database store backend. This requires a call to\n * connect() before this store can be used.\n * @constructor\n * @param {Object} indexedDBInterface The Indexed DB interface e.g\n * window.indexedDB\n * @param {string=} dbName Optional database name. The same name must be used\n * to open the same database.\n */\nconst LocalIndexedDBStoreBackend = function LocalIndexedDBStoreBackend(\n indexedDBInterface, dbName,\n) {\n this.indexedDB = indexedDBInterface;\n this._dbName = \"matrix-js-sdk:\" + (dbName || \"default\");\n this.db = null;\n this._syncAccumulator = new SyncAccumulator();\n};\n\n\nLocalIndexedDBStoreBackend.prototype = {\n /**\n * Attempt to connect to the database. This can fail if the user does not\n * grant permission.\n * @return {Promise} Resolves if successfully connected.\n */\n connect: function() {\n if (this.db) {\n console.log(\n `LocalIndexedDBStoreBackend.connect: already connected`,\n );\n return Promise.resolve();\n }\n\n console.log(\n `LocalIndexedDBStoreBackend.connect: connecting`,\n );\n const req = this.indexedDB.open(this._dbName, VERSION);\n req.onupgradeneeded = (ev) => {\n const db = ev.target.result;\n const oldVersion = ev.oldVersion;\n console.log(\n `LocalIndexedDBStoreBackend.connect: upgrading from ${oldVersion}`,\n );\n if (oldVersion < 1) { // The database did not previously exist.\n createDatabase(db);\n }\n // Expand as needed.\n };\n\n req.onblocked = () => {\n console.log(\n `can't yet open LocalIndexedDBStoreBackend because it is open elsewhere`,\n );\n };\n\n console.log(\n `LocalIndexedDBStoreBackend.connect: awaiting connection`,\n );\n return promiseifyRequest(req).then((ev) => {\n console.log(\n `LocalIndexedDBStoreBackend.connect: connected`,\n );\n this.db = ev.target.result;\n\n // add a poorly-named listener for when deleteDatabase is called\n // so we can close our db connections.\n this.db.onversionchange = () => {\n this.db.close();\n };\n\n return this._init();\n });\n },\n\n /**\n * Having connected, load initial data from the database and prepare for use\n * @return {Promise} Resolves on success\n */\n _init: function() {\n return Promise.all([\n this._loadAccountData(),\n this._loadSyncData(),\n ]).then(([accountData, syncData]) => {\n console.log(\n `LocalIndexedDBStoreBackend: loaded initial data`,\n );\n this._syncAccumulator.accumulate({\n next_batch: syncData.nextBatch,\n rooms: syncData.roomsData,\n groups: syncData.groupsData,\n account_data: {\n events: accountData,\n },\n });\n });\n },\n\n /**\n * Clear the entire database. This should be used when logging out of a client\n * to prevent mixing data between accounts.\n * @return {Promise} Resolved when the database is cleared.\n */\n clearDatabase: function() {\n return new Promise((resolve, reject) => {\n console.log(`Removing indexeddb instance: ${this._dbName}`);\n const req = this.indexedDB.deleteDatabase(this._dbName);\n\n req.onblocked = () => {\n console.log(\n `can't yet delete indexeddb ${this._dbName}` +\n ` because it is open elsewhere`,\n );\n };\n\n req.onerror = (ev) => {\n // in firefox, with indexedDB disabled, this fails with a\n // DOMError. We treat this as non-fatal, so that we can still\n // use the app.\n console.warn(\n `unable to delete js-sdk store indexeddb: ${ev.target.error}`,\n );\n resolve();\n };\n\n req.onsuccess = () => {\n console.log(`Removed indexeddb instance: ${this._dbName}`);\n resolve();\n };\n });\n },\n\n /**\n * @param {boolean=} copy If false, the data returned is from internal\n * buffers and must not be muated. Otherwise, a copy is made before\n * returning such that the data can be safely mutated. Default: true.\n *\n * @return {Promise} Resolves with a sync response to restore the\n * client state to where it was at the last save, or null if there\n * is no saved sync data.\n */\n getSavedSync: function(copy) {\n if (copy === undefined) copy = true;\n\n const data = this._syncAccumulator.getJSON();\n if (!data.nextBatch) return Promise.resolve(null);\n if (copy) {\n // We must deep copy the stored data so that the /sync processing code doesn't\n // corrupt the internal state of the sync accumulator (it adds non-clonable keys)\n return Promise.resolve(utils.deepCopy(data));\n } else {\n return Promise.resolve(data);\n }\n },\n\n setSyncData: function(syncData) {\n return Promise.resolve().then(() => {\n this._syncAccumulator.accumulate(syncData);\n });\n },\n\n syncToDatabase: function(userTuples) {\n const syncData = this._syncAccumulator.getJSON();\n\n return Promise.all([\n this._persistUserPresenceEvents(userTuples),\n this._persistAccountData(syncData.accountData),\n this._persistSyncData(\n syncData.nextBatch, syncData.roomsData, syncData.groupsData,\n ),\n ]);\n },\n\n /**\n * Persist rooms /sync data along with the next batch token.\n * @param {string} nextBatch The next_batch /sync value.\n * @param {Object} roomsData The 'rooms' /sync data from a SyncAccumulator\n * @param {Object} groupsData The 'groups' /sync data from a SyncAccumulator\n * @return {Promise} Resolves if the data was persisted.\n */\n _persistSyncData: function(nextBatch, roomsData, groupsData) {\n console.log(\"Persisting sync data up to \", nextBatch);\n return Promise.try(() => {\n const txn = this.db.transaction([\"sync\"], \"readwrite\");\n const store = txn.objectStore(\"sync\");\n store.put({\n clobber: \"-\", // constant key so will always clobber\n nextBatch: nextBatch,\n roomsData: roomsData,\n groupsData: groupsData,\n }); // put == UPSERT\n return promiseifyTxn(txn);\n });\n },\n\n /**\n * Persist a list of account data events. Events with the same 'type' will\n * be replaced.\n * @param {Object[]} accountData An array of raw user-scoped account data events\n * @return {Promise} Resolves if the events were persisted.\n */\n _persistAccountData: function(accountData) {\n return Promise.try(() => {\n const txn = this.db.transaction([\"accountData\"], \"readwrite\");\n const store = txn.objectStore(\"accountData\");\n for (let i = 0; i < accountData.length; i++) {\n store.put(accountData[i]); // put == UPSERT\n }\n return promiseifyTxn(txn);\n });\n },\n\n /**\n * Persist a list of [user id, presence event] they are for.\n * Users with the same 'userId' will be replaced.\n * Presence events should be the event in its raw form (not the Event\n * object)\n * @param {Object[]} tuples An array of [userid, event] tuples\n * @return {Promise} Resolves if the users were persisted.\n */\n _persistUserPresenceEvents: function(tuples) {\n return Promise.try(() => {\n const txn = this.db.transaction([\"users\"], \"readwrite\");\n const store = txn.objectStore(\"users\");\n for (const tuple of tuples) {\n store.put({\n userId: tuple[0],\n event: tuple[1],\n }); // put == UPSERT\n }\n return promiseifyTxn(txn);\n });\n },\n\n /**\n * Load all user presence events from the database. This is not cached.\n * FIXME: It would probably be more sensible to store the events in the\n * sync.\n * @return {Promise} A list of presence events in their raw form.\n */\n getUserPresenceEvents: function() {\n return Promise.try(() => {\n const txn = this.db.transaction([\"users\"], \"readonly\");\n const store = txn.objectStore(\"users\");\n return selectQuery(store, undefined, (cursor) => {\n return [cursor.value.userId, cursor.value.event];\n });\n });\n },\n\n /**\n * Load all the account data events from the database. This is not cached.\n * @return {Promise} A list of raw global account events.\n */\n _loadAccountData: function() {\n console.log(\n `LocalIndexedDBStoreBackend: loading account data`,\n );\n return Promise.try(() => {\n console.log(\n `LocalIndexedDBStoreBackend: loaded account data`,\n );\n const txn = this.db.transaction([\"accountData\"], \"readonly\");\n const store = txn.objectStore(\"accountData\");\n return selectQuery(store, undefined, (cursor) => {\n return cursor.value;\n });\n });\n },\n\n /**\n * Load the sync data from the database.\n * @return {Promise} An object with \"roomsData\" and \"nextBatch\" keys.\n */\n _loadSyncData: function() {\n console.log(\n `LocalIndexedDBStoreBackend: loaded sync data`,\n );\n return Promise.try(() => {\n console.log(\n `LocalIndexedDBStoreBackend: loaded sync data`,\n );\n const txn = this.db.transaction([\"sync\"], \"readonly\");\n const store = txn.objectStore(\"sync\");\n return selectQuery(store, undefined, (cursor) => {\n return cursor.value;\n }).then((results) => {\n if (results.length > 1) {\n console.warn(\"loadSyncData: More than 1 sync row found.\");\n }\n return (results.length > 0 ? results[0] : {});\n });\n });\n },\n};\n\nexport default LocalIndexedDBStoreBackend;\n","/*\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport Promise from 'bluebird';\n\n/**\n * An IndexedDB store backend where the actual backend sits in a web\n * worker.\n *\n * Construct a new Indexed Database store backend. This requires a call to\n * connect() before this store can be used.\n * @constructor\n * @param {string} workerScript URL to the worker script\n * @param {string=} dbName Optional database name. The same name must be used\n * to open the same database.\n * @param {Object} WorkerApi The web worker compatible interface object\n */\nconst RemoteIndexedDBStoreBackend = function RemoteIndexedDBStoreBackend(\n workerScript, dbName, WorkerApi,\n) {\n this._dbName = dbName;\n this._worker = new WorkerApi(workerScript);\n this._nextSeq = 0;\n // The currently in-flight requests to the actual backend\n this._inFlight = {\n // seq: promise,\n };\n\n this._worker.onmessage = this._onWorkerMessage.bind(this);\n\n // tell the worker the db name.\n this._startPromise = this._doCmd('_setupWorker', [this._dbName]).then(() => {\n console.log(\"IndexedDB worker is ready\");\n });\n};\n\n\nRemoteIndexedDBStoreBackend.prototype = {\n /**\n * Attempt to connect to the database. This can fail if the user does not\n * grant permission.\n * @return {Promise} Resolves if successfully connected.\n */\n connect: function() {\n return this._startPromise.then(() => this._doCmd('connect'));\n },\n\n /**\n * Clear the entire database. This should be used when logging out of a client\n * to prevent mixing data between accounts.\n * @return {Promise} Resolved when the database is cleared.\n */\n clearDatabase: function() {\n return this._startPromise.then(() => this._doCmd('clearDatabase'));\n },\n\n /**\n * @return {Promise} Resolves with a sync response to restore the\n * client state to where it was at the last save, or null if there\n * is no saved sync data.\n */\n getSavedSync: function() {\n return this._doCmd('getSavedSync');\n },\n\n setSyncData: function(syncData) {\n return this._doCmd('setSyncData', [syncData]);\n },\n\n syncToDatabase: function(users) {\n return this._doCmd('syncToDatabase', [users]);\n },\n\n\n /**\n * Load all user presence events from the database. This is not cached.\n * @return {Promise} A list of presence events in their raw form.\n */\n getUserPresenceEvents: function() {\n return this._doCmd('getUserPresenceEvents');\n },\n\n _doCmd: function(cmd, args) {\n // wrap in a q so if the postMessage throws,\n // the promise automatically gets rejected\n return Promise.resolve().then(() => {\n const seq = this._nextSeq++;\n const def = Promise.defer();\n\n this._inFlight[seq] = def;\n\n this._worker.postMessage({\n command: cmd,\n seq: seq,\n args: args,\n });\n\n return def.promise;\n });\n },\n\n _onWorkerMessage: function(ev) {\n const msg = ev.data;\n\n if (msg.command == 'cmd_success' || msg.command == 'cmd_fail') {\n if (msg.seq === undefined) {\n console.error(\"Got reply from worker with no seq\");\n return;\n }\n\n const def = this._inFlight[msg.seq];\n if (def === undefined) {\n console.error(\"Got reply for unknown seq \" + msg.seq);\n return;\n }\n delete this._inFlight[msg.seq];\n\n if (msg.command == 'cmd_success') {\n def.resolve(msg.result);\n } else {\n def.reject(msg.error);\n }\n } else {\n console.warn(\"Unrecognised message from worker: \" + msg);\n }\n },\n};\n\nexport default RemoteIndexedDBStoreBackend;\n","/*\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport Promise from 'bluebird';\nimport {MatrixInMemoryStore} from \"./memory\";\nimport utils from \"../utils\";\nimport LocalIndexedDBStoreBackend from \"./indexeddb-local-backend.js\";\nimport RemoteIndexedDBStoreBackend from \"./indexeddb-remote-backend.js\";\nimport User from \"../models/user\";\nimport {MatrixEvent} from \"../models/event\";\n\n/**\n * This is an internal module. See {@link IndexedDBStore} for the public class.\n * @module store/indexeddb\n */\n\n// If this value is too small we'll be writing very often which will cause\n// noticable stop-the-world pauses. If this value is too big we'll be writing\n// so infrequently that the /sync size gets bigger on reload. Writing more\n// often does not affect the length of the pause since the entire /sync\n// response is persisted each time.\nconst WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes\n\n\n/**\n * Construct a new Indexed Database store, which extends MatrixInMemoryStore.\n *\n * This store functions like a MatrixInMemoryStore except it periodically persists\n * the contents of the store to an IndexedDB backend.\n *\n * All data is still kept in-memory but can be loaded from disk by calling\n * startup(). This can make startup times quicker as a complete\n * sync from the server is not required. This does not reduce memory usage as all\n * the data is eagerly fetched when startup() is called.\n *
\n * let opts = { localStorage: window.localStorage };\n * let store = new IndexedDBStore();\n * await store.startup(); // load from indexed db\n * let client = sdk.createClient({\n *     store: store,\n * });\n * client.startClient();\n * client.on(\"sync\", function(state, prevState, data) {\n *     if (state === \"PREPARED\") {\n *         console.log(\"Started up, now with go faster stripes!\");\n *     }\n * });\n * 
\n *\n * @constructor\n * @extends MatrixInMemoryStore\n * @param {Object} opts Options object.\n * @param {Object} opts.indexedDB The Indexed DB interface e.g.\n * window.indexedDB\n * @param {string=} opts.dbName Optional database name. The same name must be used\n * to open the same database.\n * @param {string=} opts.workerScript Optional URL to a script to invoke a web\n * worker with to run IndexedDB queries on the web worker. The IndexedDbStoreWorker\n * class is provided for this purpose and requires the application to provide a\n * trivial wrapper script around it.\n * @param {Object=} opts.workerApi The webWorker API object. If omitted, the global Worker\n * object will be used if it exists.\n * @prop {IndexedDBStoreBackend} backend The backend instance. Call through to\n * this API if you need to perform specific indexeddb actions like deleting the\n * database.\n */\nconst IndexedDBStore = function IndexedDBStore(opts) {\n MatrixInMemoryStore.call(this, opts);\n\n if (!opts.indexedDB) {\n throw new Error('Missing required option: indexedDB');\n }\n\n if (opts.workerScript) {\n // try & find a webworker-compatible API\n let workerApi = opts.workerApi;\n if (!workerApi) {\n // default to the global Worker object (which is where it in a browser)\n workerApi = global.Worker;\n }\n this.backend = new RemoteIndexedDBStoreBackend(\n opts.workerScript, opts.dbName, workerApi,\n );\n } else {\n this.backend = new LocalIndexedDBStoreBackend(opts.indexedDB, opts.dbName);\n }\n\n this.startedUp = false;\n this._syncTs = 0;\n\n // Records the last-modified-time of each user at the last point we saved\n // the database, such that we can derive the set if users that have been\n // modified since we last saved.\n this._userModifiedMap = {\n // user_id : timestamp\n };\n};\nutils.inherits(IndexedDBStore, MatrixInMemoryStore);\n\n/**\n * @return {Promise} Resolved when loaded from indexed db.\n */\nIndexedDBStore.prototype.startup = function() {\n if (this.startedUp) {\n console.log(`IndexedDBStore.startup: already started`);\n return Promise.resolve();\n }\n\n console.log(`IndexedDBStore.startup: connecting to backend`);\n return this.backend.connect().then(() => {\n console.log(`IndexedDBStore.startup: loading presence events`);\n return this.backend.getUserPresenceEvents();\n }).then((userPresenceEvents) => {\n console.log(`IndexedDBStore.startup: processing presence events`);\n userPresenceEvents.forEach(([userId, rawEvent]) => {\n const u = new User(userId);\n if (rawEvent) {\n u.setPresenceEvent(new MatrixEvent(rawEvent));\n }\n this._userModifiedMap[u.userId] = u.getLastModifiedTime();\n this.storeUser(u);\n });\n });\n};\n\n/**\n * @return {Promise} Resolves with a sync response to restore the\n * client state to where it was at the last save, or null if there\n * is no saved sync data.\n */\nIndexedDBStore.prototype.getSavedSync = function() {\n return this.backend.getSavedSync();\n};\n\n/**\n * Delete all data from this store.\n * @return {Promise} Resolves if the data was deleted from the database.\n */\nIndexedDBStore.prototype.deleteAllData = function() {\n MatrixInMemoryStore.prototype.deleteAllData.call(this);\n return this.backend.clearDatabase().then(() => {\n console.log(\"Deleted indexeddb data.\");\n }, (err) => {\n console.error(`Failed to delete indexeddb data: ${err}`);\n throw err;\n });\n};\n\n/**\n * Possibly write data to the database.\n * @return {Promise} Promise resolves after the write completes.\n */\nIndexedDBStore.prototype.save = function() {\n const now = Date.now();\n if (now - this._syncTs > WRITE_DELAY_MS) {\n return this._reallySave();\n }\n return Promise.resolve();\n};\n\nIndexedDBStore.prototype._reallySave = function() {\n this._syncTs = Date.now(); // set now to guard against multi-writes\n\n // work out changed users (this doesn't handle deletions but you\n // can't 'delete' users as they are just presence events).\n const userTuples = [];\n for (const u of this.getUsers()) {\n if (this._userModifiedMap[u.userId] === u.getLastModifiedTime()) continue;\n if (!u.events.presence) continue;\n\n userTuples.push([u.userId, u.events.presence.event]);\n\n // note that we've saved this version of the user\n this._userModifiedMap[u.userId] = u.getLastModifiedTime();\n }\n\n return this.backend.syncToDatabase(userTuples).catch((err) => {\n console.error(\"sync fail:\", err);\n });\n};\n\nIndexedDBStore.prototype.setSyncData = function(syncData) {\n return this.backend.setSyncData(syncData);\n};\n\nmodule.exports.IndexedDBStore = IndexedDBStore;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * This is an internal module. See {@link MatrixInMemoryStore} for the public class.\n * @module store/memory\n */\nconst utils = require(\"../utils\");\nconst User = require(\"../models/user\");\nimport Promise from 'bluebird';\n\n/**\n * Construct a new in-memory data store for the Matrix Client.\n * @constructor\n * @param {Object=} opts Config options\n * @param {LocalStorage} opts.localStorage The local storage instance to persist\n * some forms of data such as tokens. Rooms will NOT be stored.\n */\nmodule.exports.MatrixInMemoryStore = function MatrixInMemoryStore(opts) {\n opts = opts || {};\n this.rooms = {\n // roomId: Room\n };\n this.groups = {\n // groupId: Group\n };\n this.users = {\n // userId: User\n };\n this.syncToken = null;\n this.filters = {\n // userId: {\n // filterId: Filter\n // }\n };\n this.accountData = {\n // type : content\n };\n this.localStorage = opts.localStorage;\n};\n\nmodule.exports.MatrixInMemoryStore.prototype = {\n\n /**\n * Retrieve the token to stream from.\n * @return {string} The token or null.\n */\n getSyncToken: function() {\n return this.syncToken;\n },\n\n\n /**\n * Set the token to stream from.\n * @param {string} token The token to stream from.\n */\n setSyncToken: function(token) {\n this.syncToken = token;\n },\n\n /**\n * Store the given room.\n * @param {Group} group The group to be stored\n */\n storeGroup: function(group) {\n this.groups[group.groupId] = group;\n },\n\n /**\n * Retrieve a group by its group ID.\n * @param {string} groupId The group ID.\n * @return {Group} The group or null.\n */\n getGroup: function(groupId) {\n return this.groups[groupId] || null;\n },\n\n /**\n * Retrieve all known groups.\n * @return {Group[]} A list of groups, which may be empty.\n */\n getGroups: function() {\n return utils.values(this.groups);\n },\n\n /**\n * Store the given room.\n * @param {Room} room The room to be stored. All properties must be stored.\n */\n storeRoom: function(room) {\n this.rooms[room.roomId] = room;\n // add listeners for room member changes so we can keep the room member\n // map up-to-date.\n room.currentState.on(\"RoomState.members\", this._onRoomMember.bind(this));\n // add existing members\n const self = this;\n room.currentState.getMembers().forEach(function(m) {\n self._onRoomMember(null, room.currentState, m);\n });\n },\n\n /**\n * Called when a room member in a room being tracked by this store has been\n * updated.\n * @param {MatrixEvent} event\n * @param {RoomState} state\n * @param {RoomMember} member\n */\n _onRoomMember: function(event, state, member) {\n if (member.membership === \"invite\") {\n // We do NOT add invited members because people love to typo user IDs\n // which would then show up in these lists (!)\n return;\n }\n\n const user = this.users[member.userId] || new User(member.userId);\n if (member.name) {\n user.setDisplayName(member.name);\n if (member.events.member) {\n user.setRawDisplayName(\n member.events.member.getDirectionalContent().displayname,\n );\n }\n }\n if (member.events.member && member.events.member.getContent().avatar_url) {\n user.setAvatarUrl(member.events.member.getContent().avatar_url);\n }\n this.users[user.userId] = user;\n },\n\n /**\n * Retrieve a room by its' room ID.\n * @param {string} roomId The room ID.\n * @return {Room} The room or null.\n */\n getRoom: function(roomId) {\n return this.rooms[roomId] || null;\n },\n\n /**\n * Retrieve all known rooms.\n * @return {Room[]} A list of rooms, which may be empty.\n */\n getRooms: function() {\n return utils.values(this.rooms);\n },\n\n /**\n * Permanently delete a room.\n * @param {string} roomId\n */\n removeRoom: function(roomId) {\n if (this.rooms[roomId]) {\n this.rooms[roomId].removeListener(\"RoomState.members\", this._onRoomMember);\n }\n delete this.rooms[roomId];\n },\n\n /**\n * Retrieve a summary of all the rooms.\n * @return {RoomSummary[]} A summary of each room.\n */\n getRoomSummaries: function() {\n return utils.map(utils.values(this.rooms), function(room) {\n return room.summary;\n });\n },\n\n /**\n * Store a User.\n * @param {User} user The user to store.\n */\n storeUser: function(user) {\n this.users[user.userId] = user;\n },\n\n /**\n * Retrieve a User by its' user ID.\n * @param {string} userId The user ID.\n * @return {User} The user or null.\n */\n getUser: function(userId) {\n return this.users[userId] || null;\n },\n\n /**\n * Retrieve all known users.\n * @return {User[]} A list of users, which may be empty.\n */\n getUsers: function() {\n return utils.values(this.users);\n },\n\n /**\n * Retrieve scrollback for this room.\n * @param {Room} room The matrix room\n * @param {integer} limit The max number of old events to retrieve.\n * @return {Array} An array of objects which will be at most 'limit'\n * length and at least 0. The objects are the raw event JSON.\n */\n scrollback: function(room, limit) {\n return [];\n },\n\n /**\n * Store events for a room. The events have already been added to the timeline\n * @param {Room} room The room to store events for.\n * @param {Array} events The events to store.\n * @param {string} token The token associated with these events.\n * @param {boolean} toStart True if these are paginated results.\n */\n storeEvents: function(room, events, token, toStart) {\n // no-op because they've already been added to the room instance.\n },\n\n /**\n * Store a filter.\n * @param {Filter} filter\n */\n storeFilter: function(filter) {\n if (!filter) {\n return;\n }\n if (!this.filters[filter.userId]) {\n this.filters[filter.userId] = {};\n }\n this.filters[filter.userId][filter.filterId] = filter;\n },\n\n /**\n * Retrieve a filter.\n * @param {string} userId\n * @param {string} filterId\n * @return {?Filter} A filter or null.\n */\n getFilter: function(userId, filterId) {\n if (!this.filters[userId] || !this.filters[userId][filterId]) {\n return null;\n }\n return this.filters[userId][filterId];\n },\n\n /**\n * Retrieve a filter ID with the given name.\n * @param {string} filterName The filter name.\n * @return {?string} The filter ID or null.\n */\n getFilterIdByName: function(filterName) {\n if (!this.localStorage) {\n return null;\n }\n try {\n return this.localStorage.getItem(\"mxjssdk_memory_filter_\" + filterName);\n } catch (e) {}\n return null;\n },\n\n /**\n * Set a filter name to ID mapping.\n * @param {string} filterName\n * @param {string} filterId\n */\n setFilterIdByName: function(filterName, filterId) {\n if (!this.localStorage) {\n return;\n }\n try {\n this.localStorage.setItem(\"mxjssdk_memory_filter_\" + filterName, filterId);\n } catch (e) {}\n },\n\n /**\n * Store user-scoped account data events.\n * N.B. that account data only allows a single event per type, so multiple\n * events with the same type will replace each other.\n * @param {Array} events The events to store.\n */\n storeAccountDataEvents: function(events) {\n const self = this;\n events.forEach(function(event) {\n self.accountData[event.getType()] = event;\n });\n },\n\n /**\n * Get account data event by event type\n * @param {string} eventType The event type being queried\n * @return {?MatrixEvent} the user account_data event of given type, if any\n */\n getAccountData: function(eventType) {\n return this.accountData[eventType];\n },\n\n /**\n * setSyncData does nothing as there is no backing data store.\n *\n * @param {Object} syncData The sync data\n * @return {Promise} An immediately resolved promise.\n */\n setSyncData: function(syncData) {\n return Promise.resolve();\n },\n\n /**\n * Save does nothing as there is no backing data store.\n */\n save: function() {},\n\n /**\n * Startup does nothing as this store doesn't require starting up.\n * @return {Promise} An immediately resolved promise.\n */\n startup: function() {\n return Promise.resolve();\n },\n\n /**\n * @return {Promise} Resolves with a sync response to restore the\n * client state to where it was at the last save, or null if there\n * is no saved sync data.\n */\n getSavedSync: function() {\n return Promise.resolve(null);\n },\n\n /**\n * Delete all data from this store.\n * @return {Promise} An immediately resolved promise.\n */\n deleteAllData: function() {\n this.rooms = {\n // roomId: Room\n };\n this.users = {\n // userId: User\n };\n this.syncToken = null;\n this.filters = {\n // userId: {\n // filterId: Filter\n // }\n };\n this.accountData = {\n // type : content\n };\n return Promise.resolve();\n },\n};\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/**\n * @module store/session/webstorage\n */\n\nconst utils = require(\"../../utils\");\n\nconst DEBUG = false; // set true to enable console logging.\nconst E2E_PREFIX = \"session.e2e.\";\n\n/**\n * Construct a web storage session store, capable of storing account keys,\n * session keys and access tokens.\n * @constructor\n * @param {WebStorage} webStore A web storage implementation, e.g.\n * 'window.localStorage' or 'window.sessionStorage' or a custom implementation.\n * @throws if the supplied 'store' does not meet the Storage interface of the\n * WebStorage API.\n */\nfunction WebStorageSessionStore(webStore) {\n this.store = webStore;\n if (!utils.isFunction(webStore.getItem) ||\n !utils.isFunction(webStore.setItem) ||\n !utils.isFunction(webStore.removeItem) ||\n !utils.isFunction(webStore.key) ||\n typeof(webStore.length) !== 'number'\n ) {\n throw new Error(\n \"Supplied webStore does not meet the WebStorage API interface\",\n );\n }\n}\n\nWebStorageSessionStore.prototype = {\n\n /**\n * Store the end to end account for the logged-in user.\n * @param {string} account Base64 encoded account.\n */\n storeEndToEndAccount: function(account) {\n this.store.setItem(KEY_END_TO_END_ACCOUNT, account);\n },\n\n /**\n * Load the end to end account for the logged-in user.\n * @return {?string} Base64 encoded account.\n */\n getEndToEndAccount: function() {\n return this.store.getItem(KEY_END_TO_END_ACCOUNT);\n },\n\n /**\n * Stores the known devices for a user.\n * @param {string} userId The user's ID.\n * @param {object} devices A map from device ID to keys for the device.\n */\n storeEndToEndDevicesForUser: function(userId, devices) {\n setJsonItem(this.store, keyEndToEndDevicesForUser(userId), devices);\n },\n\n /**\n * Retrieves the known devices for a user.\n * @param {string} userId The user's ID.\n * @return {object} A map from device ID to keys for the device.\n */\n getEndToEndDevicesForUser: function(userId) {\n return getJsonItem(this.store, keyEndToEndDevicesForUser(userId));\n },\n\n storeEndToEndDeviceTrackingStatus: function(statusMap) {\n setJsonItem(this.store, KEY_END_TO_END_DEVICE_LIST_TRACKING_STATUS, statusMap);\n },\n\n getEndToEndDeviceTrackingStatus: function() {\n return getJsonItem(this.store, KEY_END_TO_END_DEVICE_LIST_TRACKING_STATUS);\n },\n\n /**\n * Store the sync token corresponding to the device list.\n *\n * This is used when starting the client, to get a list of the users who\n * have changed their device list since the list time we were running.\n *\n * @param {String?} token\n */\n storeEndToEndDeviceSyncToken: function(token) {\n setJsonItem(this.store, KEY_END_TO_END_DEVICE_SYNC_TOKEN, token);\n },\n\n /**\n * Get the sync token corresponding to the device list.\n *\n * @return {String?} token\n */\n getEndToEndDeviceSyncToken: function() {\n return getJsonItem(this.store, KEY_END_TO_END_DEVICE_SYNC_TOKEN);\n },\n\n /**\n * Store a session between the logged-in user and another device\n * @param {string} deviceKey The public key of the other device.\n * @param {string} sessionId The ID for this end-to-end session.\n * @param {string} session Base64 encoded end-to-end session.\n */\n storeEndToEndSession: function(deviceKey, sessionId, session) {\n const sessions = this.getEndToEndSessions(deviceKey) || {};\n sessions[sessionId] = session;\n setJsonItem(\n this.store, keyEndToEndSessions(deviceKey), sessions,\n );\n },\n\n /**\n * Retrieve the end-to-end sessions between the logged-in user and another\n * device.\n * @param {string} deviceKey The public key of the other device.\n * @return {object} A map from sessionId to Base64 end-to-end session.\n */\n getEndToEndSessions: function(deviceKey) {\n return getJsonItem(this.store, keyEndToEndSessions(deviceKey));\n },\n\n /**\n * Retrieve a list of all known inbound group sessions\n *\n * @return {{senderKey: string, sessionId: string}}\n */\n getAllEndToEndInboundGroupSessionKeys: function() {\n const prefix = E2E_PREFIX + 'inboundgroupsessions/';\n const result = [];\n for (let i = 0; i < this.store.length; i++) {\n const key = this.store.key(i);\n if (!key.startsWith(prefix)) {\n continue;\n }\n // we can't use split, as the components we are trying to split out\n // might themselves contain '/' characters. We rely on the\n // senderKey being a (32-byte) curve25519 key, base64-encoded\n // (hence 43 characters long).\n\n result.push({\n senderKey: key.substr(prefix.length, 43),\n sessionId: key.substr(prefix.length + 44),\n });\n }\n return result;\n },\n\n getEndToEndInboundGroupSession: function(senderKey, sessionId) {\n const key = keyEndToEndInboundGroupSession(senderKey, sessionId);\n return this.store.getItem(key);\n },\n\n storeEndToEndInboundGroupSession: function(senderKey, sessionId, pickledSession) {\n const key = keyEndToEndInboundGroupSession(senderKey, sessionId);\n return this.store.setItem(key, pickledSession);\n },\n\n /**\n * Store the end-to-end state for a room.\n * @param {string} roomId The room's ID.\n * @param {object} roomInfo The end-to-end info for the room.\n */\n storeEndToEndRoom: function(roomId, roomInfo) {\n setJsonItem(this.store, keyEndToEndRoom(roomId), roomInfo);\n },\n\n /**\n * Get the end-to-end state for a room\n * @param {string} roomId The room's ID.\n * @return {object} The end-to-end info for the room.\n */\n getEndToEndRoom: function(roomId) {\n return getJsonItem(this.store, keyEndToEndRoom(roomId));\n },\n};\n\nconst KEY_END_TO_END_ACCOUNT = E2E_PREFIX + \"account\";\nconst KEY_END_TO_END_DEVICE_SYNC_TOKEN = E2E_PREFIX + \"device_sync_token\";\nconst KEY_END_TO_END_DEVICE_LIST_TRACKING_STATUS = E2E_PREFIX + \"device_tracking\";\n\nfunction keyEndToEndDevicesForUser(userId) {\n return E2E_PREFIX + \"devices/\" + userId;\n}\n\nfunction keyEndToEndSessions(deviceKey) {\n return E2E_PREFIX + \"sessions/\" + deviceKey;\n}\n\nfunction keyEndToEndInboundGroupSession(senderKey, sessionId) {\n return E2E_PREFIX + \"inboundgroupsessions/\" + senderKey + \"/\" + sessionId;\n}\n\nfunction keyEndToEndRoom(roomId) {\n return E2E_PREFIX + \"rooms/\" + roomId;\n}\n\nfunction getJsonItem(store, key) {\n try {\n // if the key is absent, store.getItem() returns null, and\n // JSON.parse(null) === null, so this returns null.\n return JSON.parse(store.getItem(key));\n } catch (e) {\n debuglog(\"Failed to get key %s: %s\", key, e);\n debuglog(e.stack);\n }\n return null;\n}\n\nfunction setJsonItem(store, key, val) {\n store.setItem(key, JSON.stringify(val));\n}\n\nfunction debuglog() {\n if (DEBUG) {\n console.log(...arguments);\n }\n}\n\n/** */\nmodule.exports = WebStorageSessionStore;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\nimport Promise from 'bluebird';\n/**\n * This is an internal module.\n * @module store/stub\n */\n\n/**\n * Construct a stub store. This does no-ops on most store methods.\n * @constructor\n */\nfunction StubStore() {\n this.fromToken = null;\n}\n\nStubStore.prototype = {\n\n /**\n * Get the sync token.\n * @return {string}\n */\n getSyncToken: function() {\n return this.fromToken;\n },\n\n /**\n * Set the sync token.\n * @param {string} token\n */\n setSyncToken: function(token) {\n this.fromToken = token;\n },\n\n /**\n * No-op.\n * @param {Group} group\n */\n storeGroup: function(group) {\n },\n\n /**\n * No-op.\n * @param {string} groupId\n * @return {null}\n */\n getGroup: function(groupId) {\n return null;\n },\n\n /**\n * No-op.\n * @return {Array} An empty array.\n */\n getGroups: function() {\n return [];\n },\n\n /**\n * No-op.\n * @param {Room} room\n */\n storeRoom: function(room) {\n },\n\n /**\n * No-op.\n * @param {string} roomId\n * @return {null}\n */\n getRoom: function(roomId) {\n return null;\n },\n\n /**\n * No-op.\n * @return {Array} An empty array.\n */\n getRooms: function() {\n return [];\n },\n\n /**\n * Permanently delete a room.\n * @param {string} roomId\n */\n removeRoom: function(roomId) {\n return;\n },\n\n /**\n * No-op.\n * @return {Array} An empty array.\n */\n getRoomSummaries: function() {\n return [];\n },\n\n /**\n * No-op.\n * @param {User} user\n */\n storeUser: function(user) {\n },\n\n /**\n * No-op.\n * @param {string} userId\n * @return {null}\n */\n getUser: function(userId) {\n return null;\n },\n\n /**\n * No-op.\n * @return {User[]}\n */\n getUsers: function() {\n return [];\n },\n\n /**\n * No-op.\n * @param {Room} room\n * @param {integer} limit\n * @return {Array}\n */\n scrollback: function(room, limit) {\n return [];\n },\n\n /**\n * Store events for a room.\n * @param {Room} room The room to store events for.\n * @param {Array} events The events to store.\n * @param {string} token The token associated with these events.\n * @param {boolean} toStart True if these are paginated results.\n */\n storeEvents: function(room, events, token, toStart) {\n },\n\n /**\n * Store a filter.\n * @param {Filter} filter\n */\n storeFilter: function(filter) {\n },\n\n /**\n * Retrieve a filter.\n * @param {string} userId\n * @param {string} filterId\n * @return {?Filter} A filter or null.\n */\n getFilter: function(userId, filterId) {\n return null;\n },\n\n /**\n * Retrieve a filter ID with the given name.\n * @param {string} filterName The filter name.\n * @return {?string} The filter ID or null.\n */\n getFilterIdByName: function(filterName) {\n return null;\n },\n\n /**\n * Set a filter name to ID mapping.\n * @param {string} filterName\n * @param {string} filterId\n */\n setFilterIdByName: function(filterName, filterId) {\n\n },\n\n /**\n * Store user-scoped account data events\n * @param {Array} events The events to store.\n */\n storeAccountDataEvents: function(events) {\n\n },\n\n /**\n * Get account data event by event type\n * @param {string} eventType The event type being queried\n */\n getAccountData: function(eventType) {\n\n },\n\n /**\n * setSyncData does nothing as there is no backing data store.\n *\n * @param {Object} syncData The sync data\n * @return {Promise} An immediately resolved promise.\n */\n setSyncData: function(syncData) {\n return Promise.resolve();\n },\n\n /**\n * Save does nothing as there is no backing data store.\n */\n save: function() {},\n\n /**\n * Startup does nothing.\n * @return {Promise} An immediately resolved promise.\n */\n startup: function() {\n return Promise.resolve();\n },\n\n /**\n * @return {Promise} Resolves with a sync response to restore the\n * client state to where it was at the last save, or null if there\n * is no saved sync data.\n */\n getSavedSync: function() {\n return Promise.resolve(null);\n },\n\n /**\n * Delete all data from this store. Does nothing since this store\n * doesn't store anything.\n * @return {Promise} An immediately resolved promise.\n */\n deleteAllData: function() {\n return Promise.resolve();\n },\n};\n\n/** Stub Store class. */\nmodule.exports = StubStore;\n","/*\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * This is an internal module. See {@link SyncAccumulator} for the public class.\n * @module sync-accumulator\n */\n\nimport utils from \"./utils\";\n\n\n/**\n * The purpose of this class is to accumulate /sync responses such that a\n * complete \"initial\" JSON response can be returned which accurately represents\n * the sum total of the /sync responses accumulated to date. It only handles\n * room data: that is, everything under the \"rooms\" top-level key.\n *\n * This class is used when persisting room data so a complete /sync response can\n * be loaded from disk and incremental syncs can be performed on the server,\n * rather than asking the server to do an initial sync on startup.\n */\nclass SyncAccumulator {\n\n /**\n * @param {Object} opts\n * @param {Number=} opts.maxTimelineEntries The ideal maximum number of\n * timeline entries to keep in the sync response. This is best-effort, as\n * clients do not always have a back-pagination token for each event, so\n * it's possible there may be slightly *less* than this value. There will\n * never be more. This cannot be 0 or else it makes it impossible to scroll\n * back in a room. Default: 50.\n */\n constructor(opts) {\n opts = opts || {};\n opts.maxTimelineEntries = opts.maxTimelineEntries || 50;\n this.opts = opts;\n this.accountData = {\n //$event_type: Object\n };\n this.inviteRooms = {\n //$roomId: { ... sync 'invite' json data ... }\n };\n this.joinRooms = {\n //$roomId: {\n // _currentState: { $event_type: { $state_key: json } },\n // _timeline: [\n // { event: $event, token: null|token },\n // { event: $event, token: null|token },\n // { event: $event, token: null|token },\n // ...\n // ],\n // _accountData: { $event_type: json },\n // _unreadNotifications: { ... unread_notifications JSON ... },\n // _readReceipts: { $user_id: { data: $json, eventId: $event_id }}\n //}\n };\n // the /sync token which corresponds to the last time rooms were\n // accumulated. We remember this so that any caller can obtain a\n // coherent /sync response and know at what point they should be\n // streaming from without losing events.\n this.nextBatch = null;\n\n // { ('invite'|'join'|'leave'): $groupId: { ... sync 'group' data } }\n this.groups = {\n invite: {},\n join: {},\n leave: {},\n };\n }\n\n accumulate(syncResponse) {\n this._accumulateRooms(syncResponse);\n this._accumulateGroups(syncResponse);\n this._accumulateAccountData(syncResponse);\n this.nextBatch = syncResponse.next_batch;\n }\n\n _accumulateAccountData(syncResponse) {\n if (!syncResponse.account_data || !syncResponse.account_data.events) {\n return;\n }\n // Clobbers based on event type.\n syncResponse.account_data.events.forEach((e) => {\n this.accountData[e.type] = e;\n });\n }\n\n /**\n * Accumulate incremental /sync room data.\n * @param {Object} syncResponse the complete /sync JSON\n */\n _accumulateRooms(syncResponse) {\n if (!syncResponse.rooms) {\n return;\n }\n if (syncResponse.rooms.invite) {\n Object.keys(syncResponse.rooms.invite).forEach((roomId) => {\n this._accumulateRoom(\n roomId, \"invite\", syncResponse.rooms.invite[roomId],\n );\n });\n }\n if (syncResponse.rooms.join) {\n Object.keys(syncResponse.rooms.join).forEach((roomId) => {\n this._accumulateRoom(\n roomId, \"join\", syncResponse.rooms.join[roomId],\n );\n });\n }\n if (syncResponse.rooms.leave) {\n Object.keys(syncResponse.rooms.leave).forEach((roomId) => {\n this._accumulateRoom(\n roomId, \"leave\", syncResponse.rooms.leave[roomId],\n );\n });\n }\n }\n\n _accumulateRoom(roomId, category, data) {\n // Valid /sync state transitions\n // +--------+ <======+ 1: Accept an invite\n // +== | INVITE | | (5) 2: Leave a room\n // | +--------+ =====+ | 3: Join a public room previously\n // |(1) (4) | | left (handle as if new room)\n // V (2) V | 4: Reject an invite\n // +------+ ========> +--------+ 5: Invite to a room previously\n // | JOIN | (3) | LEAVE* | left (handle as if new room)\n // +------+ <======== +--------+\n //\n // * equivalent to \"no state\"\n switch (category) {\n case \"invite\": // (5)\n this._accumulateInviteState(roomId, data);\n break;\n case \"join\":\n if (this.inviteRooms[roomId]) { // (1)\n // was previously invite, now join. We expect /sync to give\n // the entire state and timeline on 'join', so delete previous\n // invite state\n delete this.inviteRooms[roomId];\n }\n // (3)\n this._accumulateJoinState(roomId, data);\n break;\n case \"leave\":\n if (this.inviteRooms[roomId]) { // (4)\n delete this.inviteRooms[roomId];\n } else { // (2)\n delete this.joinRooms[roomId];\n }\n break;\n default:\n console.error(\"Unknown cateogory: \", category);\n }\n }\n\n _accumulateInviteState(roomId, data) {\n if (!data.invite_state || !data.invite_state.events) { // no new data\n return;\n }\n if (!this.inviteRooms[roomId]) {\n this.inviteRooms[roomId] = {\n invite_state: data.invite_state,\n };\n return;\n }\n // accumulate extra keys for invite->invite transitions\n // clobber based on event type / state key\n // We expect invite_state to be small, so just loop over the events\n const currentData = this.inviteRooms[roomId];\n data.invite_state.events.forEach((e) => {\n let hasAdded = false;\n for (let i = 0; i < currentData.invite_state.events.length; i++) {\n const current = currentData.invite_state.events[i];\n if (current.type === e.type && current.state_key == e.state_key) {\n currentData.invite_state.events[i] = e; // update\n hasAdded = true;\n }\n }\n if (!hasAdded) {\n currentData.invite_state.events.push(e);\n }\n });\n }\n\n // Accumulate timeline and state events in a room.\n _accumulateJoinState(roomId, data) {\n // We expect this function to be called a lot (every /sync) so we want\n // this to be fast. /sync stores events in an array but we often want\n // to clobber based on type/state_key. Rather than convert arrays to\n // maps all the time, just keep private maps which contain\n // the actual current accumulated sync state, and array-ify it when\n // getJSON() is called.\n\n // State resolution:\n // The 'state' key is the delta from the previous sync (or start of time\n // if no token was supplied), to the START of the timeline. To obtain\n // the current state, we need to \"roll forward\" state by reading the\n // timeline. We want to store the current state so we can drop events\n // out the end of the timeline based on opts.maxTimelineEntries.\n //\n // 'state' 'timeline' current state\n // |-------x<======================>x\n // T I M E\n //\n // When getJSON() is called, we 'roll back' the current state by the\n // number of entries in the timeline to work out what 'state' should be.\n\n // Back-pagination:\n // On an initial /sync, the server provides a back-pagination token for\n // the start of the timeline. When /sync deltas come down, they also\n // include back-pagination tokens for the start of the timeline. This\n // means not all events in the timeline have back-pagination tokens, as\n // it is only the ones at the START of the timeline which have them.\n // In order for us to have a valid timeline (and back-pagination token\n // to match), we need to make sure that when we remove old timeline\n // events, that we roll forward to an event which has a back-pagination\n // token. This means we can't keep a strict sliding-window based on\n // opts.maxTimelineEntries, and we may have a few less. We should never\n // have more though, provided that the /sync limit is less than or equal\n // to opts.maxTimelineEntries.\n\n if (!this.joinRooms[roomId]) {\n // Create truly empty objects so event types of 'hasOwnProperty' and co\n // don't cause this code to break.\n this.joinRooms[roomId] = {\n _currentState: Object.create(null),\n _timeline: [],\n _accountData: Object.create(null),\n _unreadNotifications: {},\n _readReceipts: {},\n };\n }\n const currentData = this.joinRooms[roomId];\n\n if (data.account_data && data.account_data.events) {\n // clobber based on type\n data.account_data.events.forEach((e) => {\n currentData._accountData[e.type] = e;\n });\n }\n\n // these probably clobber, spec is unclear.\n if (data.unread_notifications) {\n currentData._unreadNotifications = data.unread_notifications;\n }\n\n if (data.ephemeral && data.ephemeral.events) {\n data.ephemeral.events.forEach((e) => {\n // We purposefully do not persist m.typing events.\n // Technically you could refresh a browser before the timer on a\n // typing event is up, so it'll look like you aren't typing when\n // you really still are. However, the alternative is worse. If\n // we do persist typing events, it will look like people are\n // typing forever until someone really does start typing (which\n // will prompt Synapse to send down an actual m.typing event to\n // clobber the one we persisted).\n if (e.type !== \"m.receipt\" || !e.content) {\n // This means we'll drop unknown ephemeral events but that\n // seems okay.\n return;\n }\n // Handle m.receipt events. They clobber based on:\n // (user_id, receipt_type)\n // but they are keyed in the event as:\n // content:{ $event_id: { $receipt_type: { $user_id: {json} }}}\n // so store them in the former so we can accumulate receipt deltas\n // quickly and efficiently (we expect a lot of them). Fold the\n // receipt type into the key name since we only have 1 at the\n // moment (m.read) and nested JSON objects are slower and more\n // of a hassle to work with. We'll inflate this back out when\n // getJSON() is called.\n Object.keys(e.content).forEach((eventId) => {\n if (!e.content[eventId][\"m.read\"]) {\n return;\n }\n Object.keys(e.content[eventId][\"m.read\"]).forEach((userId) => {\n // clobber on user ID\n currentData._readReceipts[userId] = {\n data: e.content[eventId][\"m.read\"][userId],\n eventId: eventId,\n };\n });\n });\n });\n }\n\n // if we got a limited sync, we need to remove all timeline entries or else\n // we will have gaps in the timeline.\n if (data.timeline && data.timeline.limited) {\n currentData._timeline = [];\n }\n\n // Work out the current state. The deltas need to be applied in the order:\n // - existing state which didn't come down /sync.\n // - State events under the 'state' key.\n // - State events in the 'timeline'.\n if (data.state && data.state.events) {\n data.state.events.forEach((e) => {\n setState(currentData._currentState, e);\n });\n }\n if (data.timeline && data.timeline.events) {\n data.timeline.events.forEach((e, index) => {\n // this nops if 'e' isn't a state event\n setState(currentData._currentState, e);\n // append the event to the timeline. The back-pagination token\n // corresponds to the first event in the timeline\n currentData._timeline.push({\n event: e,\n token: index === 0 ? data.timeline.prev_batch : null,\n });\n });\n }\n\n // attempt to prune the timeline by jumping between events which have\n // pagination tokens.\n if (currentData._timeline.length > this.opts.maxTimelineEntries) {\n const startIndex = (\n currentData._timeline.length - this.opts.maxTimelineEntries\n );\n for (let i = startIndex; i < currentData._timeline.length; i++) {\n if (currentData._timeline[i].token) {\n // keep all events after this, including this one\n currentData._timeline = currentData._timeline.slice(\n i, currentData._timeline.length,\n );\n break;\n }\n }\n }\n }\n\n /**\n * Accumulate incremental /sync group data.\n * @param {Object} syncResponse the complete /sync JSON\n */\n _accumulateGroups(syncResponse) {\n if (!syncResponse.groups) {\n return;\n }\n if (syncResponse.groups.invite) {\n Object.keys(syncResponse.groups.invite).forEach((groupId) => {\n this._accumulateGroup(\n groupId, \"invite\", syncResponse.groups.invite[groupId],\n );\n });\n }\n if (syncResponse.groups.join) {\n Object.keys(syncResponse.groups.join).forEach((groupId) => {\n this._accumulateGroup(\n groupId, \"join\", syncResponse.groups.join[groupId],\n );\n });\n }\n if (syncResponse.groups.leave) {\n Object.keys(syncResponse.groups.leave).forEach((groupId) => {\n this._accumulateGroup(\n groupId, \"leave\", syncResponse.groups.leave[groupId],\n );\n });\n }\n }\n\n _accumulateGroup(groupId, category, data) {\n for (const cat of ['invite', 'join', 'leave']) {\n delete this.groups[cat][groupId];\n }\n this.groups[category][groupId] = data;\n }\n\n /**\n * Return everything under the 'rooms' key from a /sync response which\n * represents all room data that should be stored. This should be paired\n * with the sync token which represents the most recent /sync response\n * provided to accumulate().\n * @return {Object} An object with a \"nextBatch\", \"roomsData\" and \"accountData\"\n * keys.\n * The \"nextBatch\" key is a string which represents at what point in the\n * /sync stream the accumulator reached. This token should be used when\n * restarting a /sync stream at startup. Failure to do so can lead to missing\n * events. The \"roomsData\" key is an Object which represents the entire\n * /sync response from the 'rooms' key onwards. The \"accountData\" key is\n * a list of raw events which represent global account data.\n */\n getJSON() {\n const data = {\n join: {},\n invite: {},\n // always empty. This is set by /sync when a room was previously\n // in 'invite' or 'join'. On fresh startup, the client won't know\n // about any previous room being in 'invite' or 'join' so we can\n // just omit mentioning it at all, even if it has previously come\n // down /sync.\n // The notable exception is when a client is kicked or banned:\n // we may want to hold onto that room so the client can clearly see\n // why their room has disappeared. We don't persist it though because\n // it is unclear *when* we can safely remove the room from the DB.\n // Instead, we assume that if you're loading from the DB, you've\n // refreshed the page, which means you've seen the kick/ban already.\n leave: {},\n };\n Object.keys(this.inviteRooms).forEach((roomId) => {\n data.invite[roomId] = this.inviteRooms[roomId];\n });\n Object.keys(this.joinRooms).forEach((roomId) => {\n const roomData = this.joinRooms[roomId];\n const roomJson = {\n ephemeral: { events: [] },\n account_data: { events: [] },\n state: { events: [] },\n timeline: {\n events: [],\n prev_batch: null,\n },\n unread_notifications: roomData._unreadNotifications,\n };\n // Add account data\n Object.keys(roomData._accountData).forEach((evType) => {\n roomJson.account_data.events.push(roomData._accountData[evType]);\n });\n\n // Add receipt data\n const receiptEvent = {\n type: \"m.receipt\",\n room_id: roomId,\n content: {\n // $event_id: { \"m.read\": { $user_id: $json } }\n },\n };\n Object.keys(roomData._readReceipts).forEach((userId) => {\n const receiptData = roomData._readReceipts[userId];\n if (!receiptEvent.content[receiptData.eventId]) {\n receiptEvent.content[receiptData.eventId] = {\n \"m.read\": {},\n };\n }\n receiptEvent.content[receiptData.eventId][\"m.read\"][userId] = (\n receiptData.data\n );\n });\n // add only if we have some receipt data\n if (Object.keys(receiptEvent.content).length > 0) {\n roomJson.ephemeral.events.push(receiptEvent);\n }\n\n // Add timeline data\n roomData._timeline.forEach((msgData) => {\n if (!roomJson.timeline.prev_batch) {\n // the first event we add to the timeline MUST match up to\n // the prev_batch token.\n if (!msgData.token) {\n return; // this shouldn't happen as we prune constantly.\n }\n roomJson.timeline.prev_batch = msgData.token;\n }\n roomJson.timeline.events.push(msgData.event);\n });\n\n // Add state data: roll back current state to the start of timeline,\n // by \"reverse clobbering\" from the end of the timeline to the start.\n // Convert maps back into arrays.\n const rollBackState = Object.create(null);\n for (let i = roomJson.timeline.events.length - 1; i >=0; i--) {\n const timelineEvent = roomJson.timeline.events[i];\n if (timelineEvent.state_key === null ||\n timelineEvent.state_key === undefined) {\n continue; // not a state event\n }\n // since we're going back in time, we need to use the previous\n // state value else we'll break causality. We don't have the\n // complete previous state event, so we need to create one.\n const prevStateEvent = utils.deepCopy(timelineEvent);\n if (prevStateEvent.unsigned) {\n if (prevStateEvent.unsigned.prev_content) {\n prevStateEvent.content = prevStateEvent.unsigned.prev_content;\n }\n if (prevStateEvent.unsigned.prev_sender) {\n prevStateEvent.sender = prevStateEvent.unsigned.prev_sender;\n }\n }\n setState(rollBackState, prevStateEvent);\n }\n Object.keys(roomData._currentState).forEach((evType) => {\n Object.keys(roomData._currentState[evType]).forEach((stateKey) => {\n let ev = roomData._currentState[evType][stateKey];\n if (rollBackState[evType] && rollBackState[evType][stateKey]) {\n // use the reverse clobbered event instead.\n ev = rollBackState[evType][stateKey];\n }\n roomJson.state.events.push(ev);\n });\n });\n data.join[roomId] = roomJson;\n });\n\n // Add account data\n const accData = [];\n Object.keys(this.accountData).forEach((evType) => {\n accData.push(this.accountData[evType]);\n });\n\n return {\n nextBatch: this.nextBatch,\n roomsData: data,\n groupsData: this.groups,\n accountData: accData,\n };\n }\n}\n\nfunction setState(eventMap, event) {\n if (event.state_key === null || event.state_key === undefined || !event.type) {\n return;\n }\n if (!eventMap[event.type]) {\n eventMap[event.type] = Object.create(null);\n }\n eventMap[event.type][event.state_key] = event;\n}\n\nmodule.exports = SyncAccumulator;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\nCopyright 2017 Vector Creations Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/*\n * TODO:\n * This class mainly serves to take all the syncing logic out of client.js and\n * into a separate file. It's all very fluid, and this class gut wrenches a lot\n * of MatrixClient props (e.g. _http). Given we want to support WebSockets as\n * an alternative syncing API, we may want to have a proper syncing interface\n * for HTTP and WS at some point.\n */\nimport Promise from 'bluebird';\nconst User = require(\"./models/user\");\nconst Room = require(\"./models/room\");\nconst Group = require('./models/group');\nconst utils = require(\"./utils\");\nconst Filter = require(\"./filter\");\nconst EventTimeline = require(\"./models/event-timeline\");\n\nconst DEBUG = true;\n\n// /sync requests allow you to set a timeout= but the request may continue\n// beyond that and wedge forever, so we need to track how long we are willing\n// to keep open the connection. This constant is *ADDED* to the timeout= value\n// to determine the max time we're willing to wait.\nconst BUFFER_PERIOD_MS = 80 * 1000;\n\n// Number of consecutive failed syncs that will lead to a syncState of ERROR as opposed\n// to RECONNECTING. This is needed to inform the client of server issues when the\n// keepAlive is successful but the server /sync fails.\nconst FAILED_SYNC_ERROR_THRESHOLD = 3;\n\nfunction getFilterName(userId, suffix) {\n // scope this on the user ID because people may login on many accounts\n // and they all need to be stored!\n return \"FILTER_SYNC_\" + userId + (suffix ? \"_\" + suffix : \"\");\n}\n\nfunction debuglog(...params) {\n if (!DEBUG) {\n return;\n }\n console.log(...params);\n}\n\n\n/**\n * Internal class - unstable.\n * Construct an entity which is able to sync with a homeserver.\n * @constructor\n * @param {MatrixClient} client The matrix client instance to use.\n * @param {Object} opts Config options\n * @param {module:crypto=} opts.crypto Crypto manager\n * @param {Function=} opts.canResetEntireTimeline A function which is called\n * with a room ID and returns a boolean. It should return 'true' if the SDK can\n * SAFELY remove events from this room. It may not be safe to remove events if\n * there are other references to the timelines for this room.\n * Default: returns false.\n */\nfunction SyncApi(client, opts) {\n this.client = client;\n opts = opts || {};\n opts.initialSyncLimit = (\n opts.initialSyncLimit === undefined ? 8 : opts.initialSyncLimit\n );\n opts.resolveInvitesToProfiles = opts.resolveInvitesToProfiles || false;\n opts.pollTimeout = opts.pollTimeout || (30 * 1000);\n opts.pendingEventOrdering = opts.pendingEventOrdering || \"chronological\";\n if (!opts.canResetEntireTimeline) {\n opts.canResetEntireTimeline = function(roomId) {\n return false;\n };\n }\n this.opts = opts;\n this._peekRoomId = null;\n this._currentSyncRequest = null;\n this._syncState = null;\n this._catchingUp = false;\n this._running = false;\n this._keepAliveTimer = null;\n this._connectionReturnedDefer = null;\n this._notifEvents = []; // accumulator of sync events in the current sync response\n this._failedSyncCount = 0; // Number of consecutive failed /sync requests\n\n if (client.getNotifTimelineSet()) {\n client.reEmitter.reEmit(client.getNotifTimelineSet(),\n [\"Room.timeline\", \"Room.timelineReset\"]);\n }\n}\n\n/**\n * @param {string} roomId\n * @return {Room}\n */\nSyncApi.prototype.createRoom = function(roomId) {\n const client = this.client;\n const room = new Room(roomId, {\n pendingEventOrdering: this.opts.pendingEventOrdering,\n timelineSupport: client.timelineSupport,\n });\n client.reEmitter.reEmit(room, [\"Room.name\", \"Room.timeline\", \"Room.redaction\",\n \"Room.receipt\", \"Room.tags\",\n \"Room.timelineReset\",\n \"Room.localEchoUpdated\",\n \"Room.accountData\",\n ]);\n this._registerStateListeners(room);\n return room;\n};\n\n/**\n * @param {string} groupId\n * @return {Group}\n */\nSyncApi.prototype.createGroup = function(groupId) {\n const client = this.client;\n const group = new Group(groupId);\n client.reEmitter.reEmit(group, [\"Group.profile\", \"Group.myMembership\"]);\n client.store.storeGroup(group);\n return group;\n};\n\n/**\n * @param {Room} room\n * @private\n */\nSyncApi.prototype._registerStateListeners = function(room) {\n const client = this.client;\n // we need to also re-emit room state and room member events, so hook it up\n // to the client now. We need to add a listener for RoomState.members in\n // order to hook them correctly. (TODO: find a better way?)\n client.reEmitter.reEmit(room.currentState, [\n \"RoomState.events\", \"RoomState.members\", \"RoomState.newMember\",\n ]);\n room.currentState.on(\"RoomState.newMember\", function(event, state, member) {\n member.user = client.getUser(member.userId);\n client.reEmitter.reEmit(\n member,\n [\n \"RoomMember.name\", \"RoomMember.typing\", \"RoomMember.powerLevel\",\n \"RoomMember.membership\",\n ],\n );\n });\n};\n\n/**\n * @param {Room} room\n * @private\n */\nSyncApi.prototype._deregisterStateListeners = function(room) {\n // could do with a better way of achieving this.\n room.currentState.removeAllListeners(\"RoomState.events\");\n room.currentState.removeAllListeners(\"RoomState.members\");\n room.currentState.removeAllListeners(\"RoomState.newMember\");\n};\n\n\n/**\n * Sync rooms the user has left.\n * @return {Promise} Resolved when they've been added to the store.\n */\nSyncApi.prototype.syncLeftRooms = function() {\n const client = this.client;\n const self = this;\n\n // grab a filter with limit=1 and include_leave=true\n const filter = new Filter(this.client.credentials.userId);\n filter.setTimelineLimit(1);\n filter.setIncludeLeaveRooms(true);\n\n const localTimeoutMs = this.opts.pollTimeout + BUFFER_PERIOD_MS;\n const qps = {\n timeout: 0, // don't want to block since this is a single isolated req\n };\n\n return client.getOrCreateFilter(\n getFilterName(client.credentials.userId, \"LEFT_ROOMS\"), filter,\n ).then(function(filterId) {\n qps.filter = filterId;\n return client._http.authedRequest(\n undefined, \"GET\", \"/sync\", qps, undefined, localTimeoutMs,\n );\n }).then(function(data) {\n let leaveRooms = [];\n if (data.rooms && data.rooms.leave) {\n leaveRooms = self._mapSyncResponseToRoomArray(data.rooms.leave);\n }\n const rooms = [];\n leaveRooms.forEach(function(leaveObj) {\n const room = leaveObj.room;\n rooms.push(room);\n if (!leaveObj.isBrandNewRoom) {\n // the intention behind syncLeftRooms is to add in rooms which were\n // *omitted* from the initial /sync. Rooms the user were joined to\n // but then left whilst the app is running will appear in this list\n // and we do not want to bother with them since they will have the\n // current state already (and may get dupe messages if we add\n // yet more timeline events!), so skip them.\n // NB: When we persist rooms to localStorage this will be more\n // complicated...\n return;\n }\n leaveObj.timeline = leaveObj.timeline || {};\n const timelineEvents =\n self._mapSyncEventsFormat(leaveObj.timeline, room);\n const stateEvents = self._mapSyncEventsFormat(leaveObj.state, room);\n\n // set the back-pagination token. Do this *before* adding any\n // events so that clients can start back-paginating.\n room.getLiveTimeline().setPaginationToken(leaveObj.timeline.prev_batch,\n EventTimeline.BACKWARDS);\n\n self._processRoomEvents(room, stateEvents, timelineEvents);\n\n room.recalculate(client.credentials.userId);\n client.store.storeRoom(room);\n client.emit(\"Room\", room);\n\n self._processEventsForNotifs(room, timelineEvents);\n });\n return rooms;\n });\n};\n\n/**\n * Peek into a room. This will result in the room in question being synced so it\n * is accessible via getRooms(). Live updates for the room will be provided.\n * @param {string} roomId The room ID to peek into.\n * @return {Promise} A promise which resolves once the room has been added to the\n * store.\n */\nSyncApi.prototype.peek = function(roomId) {\n const self = this;\n const client = this.client;\n this._peekRoomId = roomId;\n return this.client.roomInitialSync(roomId, 20).then(function(response) {\n // make sure things are init'd\n response.messages = response.messages || {};\n response.messages.chunk = response.messages.chunk || [];\n response.state = response.state || [];\n\n const peekRoom = self.createRoom(roomId);\n\n // FIXME: Mostly duplicated from _processRoomEvents but not entirely\n // because \"state\" in this API is at the BEGINNING of the chunk\n const oldStateEvents = utils.map(\n utils.deepCopy(response.state), client.getEventMapper(),\n );\n const stateEvents = utils.map(\n response.state, client.getEventMapper(),\n );\n const messages = utils.map(\n response.messages.chunk, client.getEventMapper(),\n );\n\n // XXX: copypasted from /sync until we kill off this\n // minging v1 API stuff)\n // handle presence events (User objects)\n if (response.presence && utils.isArray(response.presence)) {\n response.presence.map(client.getEventMapper()).forEach(\n function(presenceEvent) {\n let user = client.store.getUser(presenceEvent.getContent().user_id);\n if (user) {\n user.setPresenceEvent(presenceEvent);\n } else {\n user = createNewUser(client, presenceEvent.getContent().user_id);\n user.setPresenceEvent(presenceEvent);\n client.store.storeUser(user);\n }\n client.emit(\"event\", presenceEvent);\n });\n }\n\n // set the pagination token before adding the events in case people\n // fire off pagination requests in response to the Room.timeline\n // events.\n if (response.messages.start) {\n peekRoom.oldState.paginationToken = response.messages.start;\n }\n\n // set the state of the room to as it was after the timeline executes\n peekRoom.oldState.setStateEvents(oldStateEvents);\n peekRoom.currentState.setStateEvents(stateEvents);\n\n self._resolveInvites(peekRoom);\n peekRoom.recalculate(self.client.credentials.userId);\n\n // roll backwards to diverge old state. addEventsToTimeline\n // will overwrite the pagination token, so make sure it overwrites\n // it with the right thing.\n peekRoom.addEventsToTimeline(messages.reverse(), true,\n peekRoom.getLiveTimeline(),\n response.messages.start);\n\n client.store.storeRoom(peekRoom);\n client.emit(\"Room\", peekRoom);\n\n self._peekPoll(peekRoom);\n return peekRoom;\n });\n};\n\n/**\n * Stop polling for updates in the peeked room. NOPs if there is no room being\n * peeked.\n */\nSyncApi.prototype.stopPeeking = function() {\n this._peekRoomId = null;\n};\n\n/**\n * Do a peek room poll.\n * @param {Room} peekRoom\n * @param {string} token from= token\n */\nSyncApi.prototype._peekPoll = function(peekRoom, token) {\n if (this._peekRoomId !== peekRoom.roomId) {\n debuglog(\"Stopped peeking in room %s\", peekRoom.roomId);\n return;\n }\n\n const self = this;\n // FIXME: gut wrenching; hard-coded timeout values\n this.client._http.authedRequest(undefined, \"GET\", \"/events\", {\n room_id: peekRoom.roomId,\n timeout: 30 * 1000,\n from: token,\n }, undefined, 50 * 1000).done(function(res) {\n if (self._peekRoomId !== peekRoom.roomId) {\n debuglog(\"Stopped peeking in room %s\", peekRoom.roomId);\n return;\n }\n // We have a problem that we get presence both from /events and /sync\n // however, /sync only returns presence for users in rooms\n // you're actually joined to.\n // in order to be sure to get presence for all of the users in the\n // peeked room, we handle presence explicitly here. This may result\n // in duplicate presence events firing for some users, which is a\n // performance drain, but such is life.\n // XXX: copypasted from /sync until we can kill this minging v1 stuff.\n\n res.chunk.filter(function(e) {\n return e.type === \"m.presence\";\n }).map(self.client.getEventMapper()).forEach(function(presenceEvent) {\n let user = self.client.store.getUser(presenceEvent.getContent().user_id);\n if (user) {\n user.setPresenceEvent(presenceEvent);\n } else {\n user = createNewUser(self.client, presenceEvent.getContent().user_id);\n user.setPresenceEvent(presenceEvent);\n self.client.store.storeUser(user);\n }\n self.client.emit(\"event\", presenceEvent);\n });\n\n // strip out events which aren't for the given room_id (e.g presence)\n const events = res.chunk.filter(function(e) {\n return e.room_id === peekRoom.roomId;\n }).map(self.client.getEventMapper());\n\n peekRoom.addLiveEvents(events);\n self._peekPoll(peekRoom, res.end);\n }, function(err) {\n console.error(\"[%s] Peek poll failed: %s\", peekRoom.roomId, err);\n setTimeout(function() {\n self._peekPoll(peekRoom, token);\n }, 30 * 1000);\n });\n};\n\n/**\n * Returns the current state of this sync object\n * @see module:client~MatrixClient#event:\"sync\"\n * @return {?String}\n */\nSyncApi.prototype.getSyncState = function() {\n return this._syncState;\n};\n\n/**\n * Main entry point\n */\nSyncApi.prototype.sync = function() {\n const client = this.client;\n const self = this;\n\n this._running = true;\n\n if (global.document) {\n this._onOnlineBound = this._onOnline.bind(this);\n global.document.addEventListener(\"online\", this._onOnlineBound, false);\n }\n\n // We need to do one-off checks before we can begin the /sync loop.\n // These are:\n // 1) We need to get push rules so we can check if events should bing as we get\n // them from /sync.\n // 2) We need to get/create a filter which we can use for /sync.\n\n function getPushRules() {\n client.getPushRules().done(function(result) {\n debuglog(\"Got push rules\");\n client.pushRules = result;\n getFilter(); // Now get the filter\n }, function(err) {\n self._startKeepAlives().done(function() {\n getPushRules();\n });\n self._updateSyncState(\"ERROR\", { error: err });\n });\n }\n\n function getFilter() {\n let filter;\n if (self.opts.filter) {\n filter = self.opts.filter;\n } else {\n filter = new Filter(client.credentials.userId);\n filter.setTimelineLimit(self.opts.initialSyncLimit);\n }\n\n client.getOrCreateFilter(\n getFilterName(client.credentials.userId), filter,\n ).done(function(filterId) {\n // reset the notifications timeline to prepare it to paginate from\n // the current point in time.\n // The right solution would be to tie /sync pagination tokens into\n // /notifications API somehow.\n client.resetNotifTimelineSet();\n\n self._sync({ filterId: filterId });\n }, function(err) {\n self._startKeepAlives().done(function() {\n getFilter();\n });\n self._updateSyncState(\"ERROR\", { error: err });\n });\n }\n\n if (client.isGuest()) {\n // no push rules for guests, no access to POST filter for guests.\n self._sync({});\n } else {\n getPushRules();\n }\n};\n\n/**\n * Stops the sync object from syncing.\n */\nSyncApi.prototype.stop = function() {\n debuglog(\"SyncApi.stop\");\n if (global.document) {\n global.document.removeEventListener(\"online\", this._onOnlineBound, false);\n this._onOnlineBound = undefined;\n }\n this._running = false;\n if (this._currentSyncRequest) {\n this._currentSyncRequest.abort();\n }\n if (this._keepAliveTimer) {\n clearTimeout(this._keepAliveTimer);\n this._keepAliveTimer = null;\n }\n};\n\n/**\n * Retry a backed off syncing request immediately. This should only be used when\n * the user explicitly attempts to retry their lost connection.\n * @return {boolean} True if this resulted in a request being retried.\n */\nSyncApi.prototype.retryImmediately = function() {\n if (!this._connectionReturnedDefer) {\n return false;\n }\n this._startKeepAlives(0);\n return true;\n};\n\n/**\n * Invoke me to do /sync calls\n * @param {Object} syncOptions\n * @param {string} syncOptions.filterId\n * @param {boolean} syncOptions.hasSyncedBefore\n */\nSyncApi.prototype._sync = async function(syncOptions) {\n const client = this.client;\n\n if (!this._running) {\n debuglog(\"Sync no longer running: exiting.\");\n if (this._connectionReturnedDefer) {\n this._connectionReturnedDefer.reject();\n this._connectionReturnedDefer = null;\n }\n this._updateSyncState(\"STOPPED\");\n return;\n }\n\n let filterId = syncOptions.filterId;\n if (client.isGuest() && !filterId) {\n filterId = this._getGuestFilter();\n }\n\n const syncToken = client.store.getSyncToken();\n\n let pollTimeout = this.opts.pollTimeout;\n\n if (this.getSyncState() !== 'SYNCING' || this._catchingUp) {\n // unless we are happily syncing already, we want the server to return\n // as quickly as possible, even if there are no events queued. This\n // serves two purposes:\n //\n // * When the connection dies, we want to know asap when it comes back,\n // so that we can hide the error from the user. (We don't want to\n // have to wait for an event or a timeout).\n //\n // * We want to know if the server has any to_device messages queued up\n // for us. We do that by calling it with a zero timeout until it\n // doesn't give us any more to_device messages.\n this._catchingUp = true;\n pollTimeout = 0;\n }\n\n // normal timeout= plus buffer time\n const clientSideTimeoutMs = pollTimeout + BUFFER_PERIOD_MS;\n\n const qps = {\n filter: filterId,\n timeout: pollTimeout,\n };\n\n if (syncToken) {\n qps.since = syncToken;\n } else {\n // use a cachebuster for initialsyncs, to make sure that\n // we don't get a stale sync\n // (https://github.com/vector-im/vector-web/issues/1354)\n qps._cacheBuster = Date.now();\n }\n\n if (this.getSyncState() == 'ERROR' || this.getSyncState() == 'RECONNECTING') {\n // we think the connection is dead. If it comes back up, we won't know\n // about it till /sync returns. If the timeout= is high, this could\n // be a long time. Set it to 0 when doing retries so we don't have to wait\n // for an event or a timeout before emiting the SYNCING event.\n qps.timeout = 0;\n }\n\n let savedSync;\n if (!syncOptions.hasSyncedBefore) {\n // Don't do an HTTP hit to /sync. Instead, load up the persisted /sync data,\n // if there is data there.\n savedSync = await client.store.getSavedSync();\n }\n\n let isCachedResponse = false;\n let data;\n\n if (savedSync) {\n debuglog(\"sync(): not doing HTTP hit, instead returning stored /sync data\");\n isCachedResponse = true;\n data = {\n next_batch: savedSync.nextBatch,\n rooms: savedSync.roomsData,\n groups: savedSync.groupsData,\n account_data: {\n events: savedSync.accountData,\n },\n };\n } else {\n try {\n //debuglog('Starting sync since=' + syncToken);\n this._currentSyncRequest = client._http.authedRequest(\n undefined, \"GET\", \"/sync\", qps, undefined, clientSideTimeoutMs,\n );\n data = await this._currentSyncRequest;\n } catch (e) {\n this._onSyncError(e, syncOptions);\n return;\n }\n }\n\n //debuglog('Completed sync, next_batch=' + data.next_batch);\n\n // set the sync token NOW *before* processing the events. We do this so\n // if something barfs on an event we can skip it rather than constantly\n // polling with the same token.\n client.store.setSyncToken(data.next_batch);\n\n // Reset after a successful sync\n this._failedSyncCount = 0;\n\n // We need to wait until the sync data has been sent to the backend\n // because it appears that the sync data gets modified somewhere in\n // processing it in such a way as to make it no longer cloneable.\n // XXX: Find out what is modifying it!\n if (!isCachedResponse) {\n // Don't give the store back its own cached data\n await client.store.setSyncData(data);\n }\n\n try {\n await this._processSyncResponse(syncToken, data, isCachedResponse);\n } catch(e) {\n // log the exception with stack if we have it, else fall back\n // to the plain description\n console.error(\"Caught /sync error\", e.stack || e);\n }\n\n // emit synced events\n const syncEventData = {\n oldSyncToken: syncToken,\n nextSyncToken: data.next_batch,\n catchingUp: this._catchingUp,\n };\n\n if (!syncOptions.hasSyncedBefore) {\n this._updateSyncState(\"PREPARED\", syncEventData);\n syncOptions.hasSyncedBefore = true;\n }\n\n if (!isCachedResponse) {\n // tell the crypto module to do its processing. It may block (to do a\n // /keys/changes request).\n if (this.opts.crypto) {\n await this.opts.crypto.onSyncCompleted(syncEventData);\n }\n\n // keep emitting SYNCING -> SYNCING for clients who want to do bulk updates\n this._updateSyncState(\"SYNCING\", syncEventData);\n\n // tell databases that everything is now in a consistent state and can be\n // saved (no point doing so if we only have the data we just got out of the\n // store).\n client.store.save();\n }\n\n // Begin next sync\n this._sync(syncOptions);\n};\n\nSyncApi.prototype._onSyncError = function(err, syncOptions) {\n if (!this._running) {\n debuglog(\"Sync no longer running: exiting\");\n if (this._connectionReturnedDefer) {\n this._connectionReturnedDefer.reject();\n this._connectionReturnedDefer = null;\n }\n this._updateSyncState(\"STOPPED\");\n return;\n }\n\n console.error(\"/sync error %s\", err);\n console.error(err);\n\n this._failedSyncCount++;\n console.log('Number of consecutive failed sync requests:', this._failedSyncCount);\n\n debuglog(\"Starting keep-alive\");\n // Note that we do *not* mark the sync connection as\n // lost yet: we only do this if a keepalive poke\n // fails, since long lived HTTP connections will\n // go away sometimes and we shouldn't treat this as\n // erroneous. We set the state to 'reconnecting'\n // instead, so that clients can onserve this state\n // if they wish.\n this._startKeepAlives().then(() => {\n this._sync(syncOptions);\n });\n\n this._currentSyncRequest = null;\n // Transition from RECONNECTING to ERROR after a given number of failed syncs\n this._updateSyncState(\n this._failedSyncCount >= FAILED_SYNC_ERROR_THRESHOLD ?\n \"ERROR\" : \"RECONNECTING\",\n );\n};\n\n/**\n * Process data returned from a sync response and propagate it\n * into the model objects\n *\n * @param {string} syncToken the old next_batch token sent to this\n * sync request.\n * @param {Object} data The response from /sync\n * @param {bool} isCachedResponse True if this response is from our local cache\n */\nSyncApi.prototype._processSyncResponse = async function(\n syncToken, data, isCachedResponse,\n) {\n const client = this.client;\n const self = this;\n\n // data looks like:\n // {\n // next_batch: $token,\n // presence: { events: [] },\n // account_data: { events: [] },\n // device_lists: { changed: [\"@user:server\", ... ]},\n // to_device: { events: [] },\n // device_one_time_keys_count: { signed_curve25519: 42 },\n // rooms: {\n // invite: {\n // $roomid: {\n // invite_state: { events: [] }\n // }\n // },\n // join: {\n // $roomid: {\n // state: { events: [] },\n // timeline: { events: [], prev_batch: $token, limited: true },\n // ephemeral: { events: [] },\n // account_data: { events: [] },\n // unread_notifications: {\n // highlight_count: 0,\n // notification_count: 0,\n // }\n // }\n // },\n // leave: {\n // $roomid: {\n // state: { events: [] },\n // timeline: { events: [], prev_batch: $token }\n // }\n // }\n // },\n // groups: {\n // invite: {\n // $groupId: {\n // inviter: $inviter,\n // profile: {\n // avatar_url: $avatarUrl,\n // name: $groupName,\n // },\n // },\n // },\n // join: {},\n // leave: {},\n // },\n // }\n\n // TODO-arch:\n // - Each event we pass through needs to be emitted via 'event', can we\n // do this in one place?\n // - The isBrandNewRoom boilerplate is boilerplatey.\n\n // handle presence events (User objects)\n if (data.presence && utils.isArray(data.presence.events)) {\n data.presence.events.map(client.getEventMapper()).forEach(\n function(presenceEvent) {\n let user = client.store.getUser(presenceEvent.getSender());\n if (user) {\n user.setPresenceEvent(presenceEvent);\n } else {\n user = createNewUser(client, presenceEvent.getSender());\n user.setPresenceEvent(presenceEvent);\n client.store.storeUser(user);\n }\n client.emit(\"event\", presenceEvent);\n });\n }\n\n // handle non-room account_data\n if (data.account_data && utils.isArray(data.account_data.events)) {\n const events = data.account_data.events.map(client.getEventMapper());\n client.store.storeAccountDataEvents(events);\n events.forEach(\n function(accountDataEvent) {\n // XXX: This is awful: ignore push rules from our cached sync. We fetch the\n // push rules before syncing so we actually have up-to-date ones. We do want\n // to honour new push rules that come down the sync but synapse doesn't\n // put new push rules in the sync stream when the base rules change, so\n // if the base rules change, we do need to refresh. We therefore ignore\n // the push rules in our cached sync response.\n if (accountDataEvent.getType() == 'm.push_rules' && !isCachedResponse) {\n client.pushRules = accountDataEvent.getContent();\n }\n client.emit(\"accountData\", accountDataEvent);\n return accountDataEvent;\n },\n );\n }\n\n // handle to-device events\n if (data.to_device && utils.isArray(data.to_device.events) &&\n data.to_device.events.length > 0\n ) {\n data.to_device.events\n .map(client.getEventMapper())\n .forEach(\n function(toDeviceEvent) {\n const content = toDeviceEvent.getContent();\n if (\n toDeviceEvent.getType() == \"m.room.message\" &&\n content.msgtype == \"m.bad.encrypted\"\n ) {\n // the mapper already logged a warning.\n console.log(\n 'Ignoring undecryptable to-device event from ' +\n toDeviceEvent.getSender(),\n );\n return;\n }\n\n client.emit(\"toDeviceEvent\", toDeviceEvent);\n },\n );\n } else {\n // no more to-device events: we can stop polling with a short timeout.\n this._catchingUp = false;\n }\n\n if (data.groups) {\n if (data.groups.invite) {\n this._processGroupSyncEntry(data.groups.invite, 'invite');\n }\n\n if (data.groups.join) {\n this._processGroupSyncEntry(data.groups.join, 'join');\n }\n\n if (data.groups.leave) {\n this._processGroupSyncEntry(data.groups.leave, 'leave');\n }\n }\n\n // the returned json structure is a bit crap, so make it into a\n // nicer form (array) after applying sanity to make sure we don't fail\n // on missing keys (on the off chance)\n let inviteRooms = [];\n let joinRooms = [];\n let leaveRooms = [];\n\n if (data.rooms) {\n if (data.rooms.invite) {\n inviteRooms = this._mapSyncResponseToRoomArray(data.rooms.invite);\n }\n if (data.rooms.join) {\n joinRooms = this._mapSyncResponseToRoomArray(data.rooms.join);\n }\n if (data.rooms.leave) {\n leaveRooms = this._mapSyncResponseToRoomArray(data.rooms.leave);\n }\n }\n\n this._notifEvents = [];\n\n // Handle invites\n inviteRooms.forEach(function(inviteObj) {\n const room = inviteObj.room;\n const stateEvents =\n self._mapSyncEventsFormat(inviteObj.invite_state, room);\n self._processRoomEvents(room, stateEvents);\n if (inviteObj.isBrandNewRoom) {\n room.recalculate(client.credentials.userId);\n client.store.storeRoom(room);\n client.emit(\"Room\", room);\n }\n stateEvents.forEach(function(e) {\n client.emit(\"event\", e);\n });\n });\n\n // Handle joins\n await Promise.mapSeries(joinRooms, async function(joinObj) {\n const room = joinObj.room;\n const stateEvents = self._mapSyncEventsFormat(joinObj.state, room);\n const timelineEvents = self._mapSyncEventsFormat(joinObj.timeline, room);\n const ephemeralEvents = self._mapSyncEventsFormat(joinObj.ephemeral);\n const accountDataEvents = self._mapSyncEventsFormat(joinObj.account_data);\n\n // we do this first so it's correct when any of the events fire\n if (joinObj.unread_notifications) {\n room.setUnreadNotificationCount(\n 'total', joinObj.unread_notifications.notification_count,\n );\n room.setUnreadNotificationCount(\n 'highlight', joinObj.unread_notifications.highlight_count,\n );\n }\n\n joinObj.timeline = joinObj.timeline || {};\n\n if (joinObj.isBrandNewRoom) {\n // set the back-pagination token. Do this *before* adding any\n // events so that clients can start back-paginating.\n room.getLiveTimeline().setPaginationToken(\n joinObj.timeline.prev_batch, EventTimeline.BACKWARDS);\n } else if (joinObj.timeline.limited) {\n let limited = true;\n\n // we've got a limited sync, so we *probably* have a gap in the\n // timeline, so should reset. But we might have been peeking or\n // paginating and already have some of the events, in which\n // case we just want to append any subsequent events to the end\n // of the existing timeline.\n //\n // This is particularly important in the case that we already have\n // *all* of the events in the timeline - in that case, if we reset\n // the timeline, we'll end up with an entirely empty timeline,\n // which we'll try to paginate but not get any new events (which\n // will stop us linking the empty timeline into the chain).\n //\n for (let i = timelineEvents.length - 1; i >= 0; i--) {\n const eventId = timelineEvents[i].getId();\n if (room.getTimelineForEvent(eventId)) {\n debuglog(\"Already have event \" + eventId + \" in limited \" +\n \"sync - not resetting\");\n limited = false;\n\n // we might still be missing some of the events before i;\n // we don't want to be adding them to the end of the\n // timeline because that would put them out of order.\n timelineEvents.splice(0, i);\n\n // XXX: there's a problem here if the skipped part of the\n // timeline modifies the state set in stateEvents, because\n // we'll end up using the state from stateEvents rather\n // than the later state from timelineEvents. We probably\n // need to wind stateEvents forward over the events we're\n // skipping.\n\n break;\n }\n }\n\n if (limited) {\n self._deregisterStateListeners(room);\n room.resetLiveTimeline(\n joinObj.timeline.prev_batch,\n self.opts.canResetEntireTimeline(room.roomId) ? null : syncToken,\n );\n\n // We have to assume any gap in any timeline is\n // reason to stop incrementally tracking notifications and\n // reset the timeline.\n client.resetNotifTimelineSet();\n\n self._registerStateListeners(room);\n }\n }\n\n self._processRoomEvents(room, stateEvents, timelineEvents);\n\n // XXX: should we be adding ephemeralEvents to the timeline?\n // It feels like that for symmetry with room.addAccountData()\n // there should be a room.addEphemeralEvents() or similar.\n room.addLiveEvents(ephemeralEvents);\n\n // we deliberately don't add accountData to the timeline\n room.addAccountData(accountDataEvents);\n\n room.recalculate(client.credentials.userId);\n if (joinObj.isBrandNewRoom) {\n client.store.storeRoom(room);\n client.emit(\"Room\", room);\n }\n\n self._processEventsForNotifs(room, timelineEvents);\n\n async function processRoomEvent(e) {\n client.emit(\"event\", e);\n if (e.isState() && e.getType() == \"m.room.encryption\" && self.opts.crypto) {\n await self.opts.crypto.onCryptoEvent(e);\n }\n }\n\n await Promise.mapSeries(stateEvents, processRoomEvent);\n await Promise.mapSeries(timelineEvents, processRoomEvent);\n ephemeralEvents.forEach(function(e) {\n client.emit(\"event\", e);\n });\n accountDataEvents.forEach(function(e) {\n client.emit(\"event\", e);\n });\n });\n\n // Handle leaves (e.g. kicked rooms)\n leaveRooms.forEach(function(leaveObj) {\n const room = leaveObj.room;\n const stateEvents =\n self._mapSyncEventsFormat(leaveObj.state, room);\n const timelineEvents =\n self._mapSyncEventsFormat(leaveObj.timeline, room);\n const accountDataEvents =\n self._mapSyncEventsFormat(leaveObj.account_data);\n\n self._processRoomEvents(room, stateEvents, timelineEvents);\n room.addAccountData(accountDataEvents);\n\n room.recalculate(client.credentials.userId);\n if (leaveObj.isBrandNewRoom) {\n client.store.storeRoom(room);\n client.emit(\"Room\", room);\n }\n\n self._processEventsForNotifs(room, timelineEvents);\n\n stateEvents.forEach(function(e) {\n client.emit(\"event\", e);\n });\n timelineEvents.forEach(function(e) {\n client.emit(\"event\", e);\n });\n accountDataEvents.forEach(function(e) {\n client.emit(\"event\", e);\n });\n });\n\n // update the notification timeline, if appropriate.\n // we only do this for live events, as otherwise we can't order them sanely\n // in the timeline relative to ones paginated in by /notifications.\n // XXX: we could fix this by making EventTimeline support chronological\n // ordering... but it doesn't, right now.\n if (syncToken && this._notifEvents.length) {\n this._notifEvents.sort(function(a, b) {\n return a.getTs() - b.getTs();\n });\n this._notifEvents.forEach(function(event) {\n client.getNotifTimelineSet().addLiveEvent(event);\n });\n }\n\n // Handle device list updates\n if (data.device_lists) {\n if (this.opts.crypto) {\n await this.opts.crypto.handleDeviceListChanges(data.device_lists);\n } else {\n // FIXME if we *don't* have a crypto module, we still need to\n // invalidate the device lists. But that would require a\n // substantial bit of rework :/.\n }\n }\n\n // Handle one_time_keys_count\n if (this.opts.crypto && data.device_one_time_keys_count) {\n const currentCount = data.device_one_time_keys_count.signed_curve25519 || 0;\n this.opts.crypto.updateOneTimeKeyCount(currentCount);\n }\n};\n\n/**\n * Starts polling the connectivity check endpoint\n * @param {number} delay How long to delay until the first poll.\n * defaults to a short, randomised interval (to prevent\n * tightlooping if /versions succeeds but /sync etc. fail).\n * @return {promise} which resolves once the connection returns\n */\nSyncApi.prototype._startKeepAlives = function(delay) {\n if (delay === undefined) {\n delay = 2000 + Math.floor(Math.random() * 5000);\n }\n\n if (this._keepAliveTimer !== null) {\n clearTimeout(this._keepAliveTimer);\n }\n const self = this;\n if (delay > 0) {\n self._keepAliveTimer = setTimeout(\n self._pokeKeepAlive.bind(self),\n delay,\n );\n } else {\n self._pokeKeepAlive();\n }\n if (!this._connectionReturnedDefer) {\n this._connectionReturnedDefer = Promise.defer();\n }\n return this._connectionReturnedDefer.promise;\n};\n\n/**\n * Make a dummy call to /_matrix/client/versions, to see if the HS is\n * reachable.\n *\n * On failure, schedules a call back to itself. On success, resolves\n * this._connectionReturnedDefer.\n */\nSyncApi.prototype._pokeKeepAlive = function() {\n const self = this;\n function success() {\n clearTimeout(self._keepAliveTimer);\n if (self._connectionReturnedDefer) {\n self._connectionReturnedDefer.resolve();\n self._connectionReturnedDefer = null;\n }\n }\n\n this.client._http.request(\n undefined, // callback\n \"GET\", \"/_matrix/client/versions\",\n undefined, // queryParams\n undefined, // data\n {\n prefix: '',\n localTimeoutMs: 15 * 1000,\n },\n ).done(function() {\n success();\n }, function(err) {\n if (err.httpStatus == 400) {\n // treat this as a success because the server probably just doesn't\n // support /versions: point is, we're getting a response.\n // We wait a short time though, just in case somehow the server\n // is in a mode where it 400s /versions responses and sync etc.\n // responses fail, this will mean we don't hammer in a loop.\n self._keepAliveTimer = setTimeout(success, 2000);\n } else {\n self._keepAliveTimer = setTimeout(\n self._pokeKeepAlive.bind(self),\n 5000 + Math.floor(Math.random() * 5000),\n );\n // A keepalive has failed, so we emit the\n // error state (whether or not this is the\n // first failure).\n // Note we do this after setting the timer:\n // this lets the unit tests advance the mock\n // clock when the get the error.\n self._updateSyncState(\"ERROR\", { error: err });\n }\n });\n};\n\n/**\n * @param {Object} groupsSection Groups section object, eg. response.groups.invite\n * @param {string} sectionName Which section this is ('invite', 'join' or 'leave')\n */\nSyncApi.prototype._processGroupSyncEntry = function(groupsSection, sectionName) {\n // Processes entries from 'groups' section of the sync stream\n for (const groupId of Object.keys(groupsSection)) {\n const groupInfo = groupsSection[groupId];\n let group = this.client.store.getGroup(groupId);\n const isBrandNew = group === null;\n if (group === null) {\n group = this.createGroup(groupId);\n }\n if (groupInfo.profile) {\n group.setProfile(\n groupInfo.profile.name, groupInfo.profile.avatar_url,\n );\n }\n if (groupInfo.inviter) {\n group.setInviter({userId: groupInfo.inviter});\n }\n group.setMyMembership(sectionName);\n if (isBrandNew) {\n // Now we've filled in all the fields, emit the Group event\n this.client.emit(\"Group\", group);\n }\n }\n};\n\n/**\n * @param {Object} obj\n * @return {Object[]}\n */\nSyncApi.prototype._mapSyncResponseToRoomArray = function(obj) {\n // Maps { roomid: {stuff}, roomid: {stuff} }\n // to\n // [{stuff+Room+isBrandNewRoom}, {stuff+Room+isBrandNewRoom}]\n const client = this.client;\n const self = this;\n return utils.keys(obj).map(function(roomId) {\n const arrObj = obj[roomId];\n let room = client.store.getRoom(roomId);\n let isBrandNewRoom = false;\n if (!room) {\n room = self.createRoom(roomId);\n isBrandNewRoom = true;\n }\n arrObj.room = room;\n arrObj.isBrandNewRoom = isBrandNewRoom;\n return arrObj;\n });\n};\n\n/**\n * @param {Object} obj\n * @param {Room} room\n * @return {MatrixEvent[]}\n */\nSyncApi.prototype._mapSyncEventsFormat = function(obj, room) {\n if (!obj || !utils.isArray(obj.events)) {\n return [];\n }\n const mapper = this.client.getEventMapper();\n return obj.events.map(function(e) {\n if (room) {\n e.room_id = room.roomId;\n }\n return mapper(e);\n });\n};\n\n/**\n * @param {Room} room\n */\nSyncApi.prototype._resolveInvites = function(room) {\n if (!room || !this.opts.resolveInvitesToProfiles) {\n return;\n }\n const client = this.client;\n // For each invited room member we want to give them a displayname/avatar url\n // if they have one (the m.room.member invites don't contain this).\n room.getMembersWithMembership(\"invite\").forEach(function(member) {\n if (member._requestedProfileInfo) {\n return;\n }\n member._requestedProfileInfo = true;\n // try to get a cached copy first.\n const user = client.getUser(member.userId);\n let promise;\n if (user) {\n promise = Promise.resolve({\n avatar_url: user.avatarUrl,\n displayname: user.displayName,\n });\n } else {\n promise = client.getProfileInfo(member.userId);\n }\n promise.done(function(info) {\n // slightly naughty by doctoring the invite event but this means all\n // the code paths remain the same between invite/join display name stuff\n // which is a worthy trade-off for some minor pollution.\n const inviteEvent = member.events.member;\n if (inviteEvent.getContent().membership !== \"invite\") {\n // between resolving and now they have since joined, so don't clobber\n return;\n }\n inviteEvent.getContent().avatar_url = info.avatar_url;\n inviteEvent.getContent().displayname = info.displayname;\n // fire listeners\n member.setMembershipEvent(inviteEvent, room.currentState);\n }, function(err) {\n // OH WELL.\n });\n });\n};\n\n/**\n * @param {Room} room\n * @param {MatrixEvent[]} stateEventList A list of state events. This is the state\n * at the *START* of the timeline list if it is supplied.\n * @param {MatrixEvent[]} [timelineEventList] A list of timeline events. Lower index\n * is earlier in time. Higher index is later.\n */\nSyncApi.prototype._processRoomEvents = function(room, stateEventList,\n timelineEventList) {\n timelineEventList = timelineEventList || [];\n const client = this.client;\n // \"old\" and \"current\" state are the same initially; they\n // start diverging if the user paginates.\n // We must deep copy otherwise membership changes in old state\n // will leak through to current state!\n const oldStateEvents = utils.map(\n utils.deepCopy(\n stateEventList.map(function(mxEvent) {\n return mxEvent.event;\n }),\n ), client.getEventMapper(),\n );\n const stateEvents = stateEventList;\n\n // set the state of the room to as it was before the timeline executes\n //\n // XXX: what if we've already seen (some of) the events in the timeline,\n // and they modify some of the state set in stateEvents? In that case we'll\n // end up with the state from stateEvents, instead of the more recent state\n // from the timeline.\n room.oldState.setStateEvents(oldStateEvents);\n room.currentState.setStateEvents(stateEvents);\n\n this._resolveInvites(room);\n\n // recalculate the room name at this point as adding events to the timeline\n // may make notifications appear which should have the right name.\n room.recalculate(this.client.credentials.userId);\n\n // execute the timeline events, this will begin to diverge the current state\n // if the timeline has any state events in it.\n // This also needs to be done before running push rules on the events as they need\n // to be decorated with sender etc.\n room.addLiveEvents(timelineEventList);\n};\n\n/**\n * Takes a list of timelineEvents and adds and adds to _notifEvents\n * as appropriate.\n * This must be called after the room the events belong to has been stored.\n *\n * @param {Room} room\n * @param {MatrixEvent[]} [timelineEventList] A list of timeline events. Lower index\n * is earlier in time. Higher index is later.\n */\nSyncApi.prototype._processEventsForNotifs = function(room, timelineEventList) {\n // gather our notifications into this._notifEvents\n if (this.client.getNotifTimelineSet()) {\n for (let i = 0; i < timelineEventList.length; i++) {\n const pushActions = this.client.getPushActionsForEvent(timelineEventList[i]);\n if (pushActions && pushActions.notify &&\n pushActions.tweaks && pushActions.tweaks.highlight) {\n this._notifEvents.push(timelineEventList[i]);\n }\n }\n }\n};\n\n/**\n * @return {string}\n */\nSyncApi.prototype._getGuestFilter = function() {\n const guestRooms = this.client._guestRooms; // FIXME: horrible gut-wrenching\n if (!guestRooms) {\n return \"{}\";\n }\n // we just need to specify the filter inline if we're a guest because guests\n // can't create filters.\n return JSON.stringify({\n room: {\n timeline: {\n limit: 20,\n },\n },\n });\n};\n\n/**\n * Sets the sync state and emits an event to say so\n * @param {String} newState The new state string\n * @param {Object} data Object of additional data to emit in the event\n */\nSyncApi.prototype._updateSyncState = function(newState, data) {\n const old = this._syncState;\n this._syncState = newState;\n this.client.emit(\"sync\", this._syncState, old, data);\n};\n\n/**\n * Event handler for the 'online' event\n * This event is generally unreliable and precise behaviour\n * varies between browsers, so we poll for connectivity too,\n * but this might help us reconnect a little faster.\n */\nSyncApi.prototype._onOnline = function() {\n debuglog(\"Browser thinks we are back online\");\n this._startKeepAlives(0);\n};\n\nfunction createNewUser(client, userId) {\n const user = new User(userId);\n client.reEmitter.reEmit(user, [\n \"User.avatarUrl\", \"User.displayName\", \"User.presence\",\n \"User.currentlyActive\", \"User.lastPresenceTs\",\n ]);\n return user;\n}\n\n/** */\nmodule.exports = SyncApi;\n","/*\nCopyright 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n\n/** @module timeline-window */\n\nimport Promise from 'bluebird';\nconst EventTimeline = require(\"./models/event-timeline\");\n\n/**\n * @private\n */\nconst DEBUG = false;\n\n/**\n * @private\n */\nconst debuglog = DEBUG ? console.log.bind(console) : function() {};\n\n/**\n * the number of times we ask the server for more events before giving up\n *\n * @private\n */\nconst DEFAULT_PAGINATE_LOOP_LIMIT = 5;\n\n/**\n * Construct a TimelineWindow.\n *\n *

This abstracts the separate timelines in a Matrix {@link\n * module:models/room|Room} into a single iterable thing. It keeps track of\n * the start and endpoints of the window, which can be advanced with the help\n * of pagination requests.\n *\n *

Before the window is useful, it must be initialised by calling {@link\n * module:timeline-window~TimelineWindow#load|load}.\n *\n *

Note that the window will not automatically extend itself when new events\n * are received from /sync; you should arrange to call {@link\n * module:timeline-window~TimelineWindow#paginate|paginate} on {@link\n * module:client~MatrixClient.event:\"Room.timeline\"|Room.timeline} events.\n *\n * @param {MatrixClient} client MatrixClient to be used for context/pagination\n * requests.\n *\n * @param {EventTimelineSet} timelineSet The timelineSet to track\n *\n * @param {Object} [opts] Configuration options for this window\n *\n * @param {number} [opts.windowLimit = 1000] maximum number of events to keep\n * in the window. If more events are retrieved via pagination requests,\n * excess events will be dropped from the other end of the window.\n *\n * @constructor\n */\nfunction TimelineWindow(client, timelineSet, opts) {\n opts = opts || {};\n this._client = client;\n this._timelineSet = timelineSet;\n\n // these will be TimelineIndex objects; they delineate the 'start' and\n // 'end' of the window.\n //\n // _start.index is inclusive; _end.index is exclusive.\n this._start = null;\n this._end = null;\n\n this._eventCount = 0;\n this._windowLimit = opts.windowLimit || 1000;\n}\n\n/**\n * Initialise the window to point at a given event, or the live timeline\n *\n * @param {string} [initialEventId] If given, the window will contain the\n * given event\n * @param {number} [initialWindowSize = 20] Size of the initial window\n *\n * @return {module:client.Promise}\n */\nTimelineWindow.prototype.load = function(initialEventId, initialWindowSize) {\n const self = this;\n initialWindowSize = initialWindowSize || 20;\n\n // given an EventTimeline, find the event we were looking for, and initialise our\n // fields so that the event in question is in the middle of the window.\n const initFields = function(timeline) {\n let eventIndex;\n\n const events = timeline.getEvents();\n\n if (!initialEventId) {\n // we were looking for the live timeline: initialise to the end\n eventIndex = events.length;\n } else {\n for (let i = 0; i < events.length; i++) {\n if (events[i].getId() == initialEventId) {\n eventIndex = i;\n break;\n }\n }\n\n if (eventIndex === undefined) {\n throw new Error(\"getEventTimeline result didn't include requested event\");\n }\n }\n\n const endIndex = Math.min(events.length,\n eventIndex + Math.ceil(initialWindowSize / 2));\n const startIndex = Math.max(0, endIndex - initialWindowSize);\n self._start = new TimelineIndex(timeline, startIndex - timeline.getBaseIndex());\n self._end = new TimelineIndex(timeline, endIndex - timeline.getBaseIndex());\n self._eventCount = endIndex - startIndex;\n };\n\n // We avoid delaying the resolution of the promise by a reactor tick if\n // we already have the data we need, which is important to keep room-switching\n // feeling snappy.\n //\n if (initialEventId) {\n const prom = this._client.getEventTimeline(this._timelineSet, initialEventId);\n\n if (prom.isFulfilled()) {\n initFields(prom.value());\n return Promise.resolve();\n } else {\n return prom.then(initFields);\n }\n } else {\n const tl = this._timelineSet.getLiveTimeline();\n initFields(tl);\n return Promise.resolve();\n }\n};\n\n/**\n * Check if this window can be extended\n *\n *

This returns true if we either have more events, or if we have a\n * pagination token which means we can paginate in that direction. It does not\n * necessarily mean that there are more events available in that direction at\n * this time.\n *\n * @param {string} direction EventTimeline.BACKWARDS to check if we can\n * paginate backwards; EventTimeline.FORWARDS to check if we can go forwards\n *\n * @return {boolean} true if we can paginate in the given direction\n */\nTimelineWindow.prototype.canPaginate = function(direction) {\n let tl;\n if (direction == EventTimeline.BACKWARDS) {\n tl = this._start;\n } else if (direction == EventTimeline.FORWARDS) {\n tl = this._end;\n } else {\n throw new Error(\"Invalid direction '\" + direction + \"'\");\n }\n\n if (!tl) {\n debuglog(\"TimelineWindow: no timeline yet\");\n return false;\n }\n\n if (direction == EventTimeline.BACKWARDS) {\n if (tl.index > tl.minIndex()) {\n return true;\n }\n } else {\n if (tl.index < tl.maxIndex()) {\n return true;\n }\n }\n\n return Boolean(tl.timeline.getNeighbouringTimeline(direction) ||\n tl.timeline.getPaginationToken(direction));\n};\n\n/**\n * Attempt to extend the window\n *\n * @param {string} direction EventTimeline.BACKWARDS to extend the window\n * backwards (towards older events); EventTimeline.FORWARDS to go forwards.\n *\n * @param {number} size number of events to try to extend by. If fewer than this\n * number are immediately available, then we return immediately rather than\n * making an API call.\n *\n * @param {boolean} [makeRequest = true] whether we should make API calls to\n * fetch further events if we don't have any at all. (This has no effect if\n * the room already knows about additional events in the relevant direction,\n * even if there are fewer than 'size' of them, as we will just return those\n * we already know about.)\n *\n * @param {number} [requestLimit = 5] limit for the number of API requests we\n * should make.\n *\n * @return {module:client.Promise} Resolves to a boolean which is true if more events\n * were successfully retrieved.\n */\nTimelineWindow.prototype.paginate = function(direction, size, makeRequest,\n requestLimit) {\n // Either wind back the message cap (if there are enough events in the\n // timeline to do so), or fire off a pagination request.\n\n if (makeRequest === undefined) {\n makeRequest = true;\n }\n\n if (requestLimit === undefined) {\n requestLimit = DEFAULT_PAGINATE_LOOP_LIMIT;\n }\n\n let tl;\n if (direction == EventTimeline.BACKWARDS) {\n tl = this._start;\n } else if (direction == EventTimeline.FORWARDS) {\n tl = this._end;\n } else {\n throw new Error(\"Invalid direction '\" + direction + \"'\");\n }\n\n if (!tl) {\n debuglog(\"TimelineWindow: no timeline yet\");\n return Promise.resolve(false);\n }\n\n if (tl.pendingPaginate) {\n return tl.pendingPaginate;\n }\n\n // try moving the cap\n const count = (direction == EventTimeline.BACKWARDS) ?\n tl.retreat(size) : tl.advance(size);\n\n if (count) {\n this._eventCount += count;\n debuglog(\"TimelineWindow: increased cap by \" + count +\n \" (now \" + this._eventCount + \")\");\n // remove some events from the other end, if necessary\n const excess = this._eventCount - this._windowLimit;\n if (excess > 0) {\n this.unpaginate(excess, direction != EventTimeline.BACKWARDS);\n }\n return Promise.resolve(true);\n }\n\n if (!makeRequest || requestLimit === 0) {\n // todo: should we return something different to indicate that there\n // might be more events out there, but we haven't found them yet?\n return Promise.resolve(false);\n }\n\n // try making a pagination request\n const token = tl.timeline.getPaginationToken(direction);\n if (!token) {\n debuglog(\"TimelineWindow: no token\");\n return Promise.resolve(false);\n }\n\n debuglog(\"TimelineWindow: starting request\");\n const self = this;\n\n const prom = this._client.paginateEventTimeline(tl.timeline, {\n backwards: direction == EventTimeline.BACKWARDS,\n limit: size,\n }).finally(function() {\n tl.pendingPaginate = null;\n }).then(function(r) {\n debuglog(\"TimelineWindow: request completed with result \" + r);\n if (!r) {\n // end of timeline\n return false;\n }\n\n // recurse to advance the index into the results.\n //\n // If we don't get any new events, we want to make sure we keep asking\n // the server for events for as long as we have a valid pagination\n // token. In particular, we want to know if we've actually hit the\n // start of the timeline, or if we just happened to know about all of\n // the events thanks to https://matrix.org/jira/browse/SYN-645.\n //\n // On the other hand, we necessarily want to wait forever for the\n // server to make its mind up about whether there are other events,\n // because it gives a bad user experience\n // (https://github.com/vector-im/vector-web/issues/1204).\n return self.paginate(direction, size, true, requestLimit - 1);\n });\n tl.pendingPaginate = prom;\n return prom;\n};\n\n\n/**\n * Remove `delta` events from the start or end of the timeline.\n *\n * @param {number} delta number of events to remove from the timeline\n * @param {boolean} startOfTimeline if events should be removed from the start\n * of the timeline.\n */\nTimelineWindow.prototype.unpaginate = function(delta, startOfTimeline) {\n const tl = startOfTimeline ? this._start : this._end;\n\n // sanity-check the delta\n if (delta > this._eventCount || delta < 0) {\n throw new Error(\"Attemting to unpaginate \" + delta + \" events, but \" +\n \"only have \" + this._eventCount + \" in the timeline\");\n }\n\n while (delta > 0) {\n const count = startOfTimeline ? tl.advance(delta) : tl.retreat(delta);\n if (count <= 0) {\n // sadness. This shouldn't be possible.\n throw new Error(\n \"Unable to unpaginate any further, but still have \" +\n this._eventCount + \" events\");\n }\n\n delta -= count;\n this._eventCount -= count;\n debuglog(\"TimelineWindow.unpaginate: dropped \" + count +\n \" (now \" + this._eventCount + \")\");\n }\n};\n\n\n/**\n * Get a list of the events currently in the window\n *\n * @return {MatrixEvent[]} the events in the window\n */\nTimelineWindow.prototype.getEvents = function() {\n if (!this._start) {\n // not yet loaded\n return [];\n }\n\n const result = [];\n\n // iterate through each timeline between this._start and this._end\n // (inclusive).\n let timeline = this._start.timeline;\n while (true) {\n const events = timeline.getEvents();\n\n // For the first timeline in the chain, we want to start at\n // this._start.index. For the last timeline in the chain, we want to\n // stop before this._end.index. Otherwise, we want to copy all of the\n // events in the timeline.\n //\n // (Note that both this._start.index and this._end.index are relative\n // to their respective timelines' BaseIndex).\n //\n let startIndex = 0, endIndex = events.length;\n if (timeline === this._start.timeline) {\n startIndex = this._start.index + timeline.getBaseIndex();\n }\n if (timeline === this._end.timeline) {\n endIndex = this._end.index + timeline.getBaseIndex();\n }\n\n for (let i = startIndex; i < endIndex; i++) {\n result.push(events[i]);\n }\n\n // if we're not done, iterate to the next timeline.\n if (timeline === this._end.timeline) {\n break;\n } else {\n timeline = timeline.getNeighbouringTimeline(EventTimeline.FORWARDS);\n }\n }\n\n return result;\n};\n\n\n/**\n * a thing which contains a timeline reference, and an index into it.\n *\n * @constructor\n * @param {EventTimeline} timeline\n * @param {number} index\n * @private\n */\nfunction TimelineIndex(timeline, index) {\n this.timeline = timeline;\n\n // the indexes are relative to BaseIndex, so could well be negative.\n this.index = index;\n}\n\n/**\n * @return {number} the minimum possible value for the index in the current\n * timeline\n */\nTimelineIndex.prototype.minIndex = function() {\n return this.timeline.getBaseIndex() * -1;\n};\n\n/**\n * @return {number} the maximum possible value for the index in the current\n * timeline (exclusive - ie, it actually returns one more than the index\n * of the last element).\n */\nTimelineIndex.prototype.maxIndex = function() {\n return this.timeline.getEvents().length - this.timeline.getBaseIndex();\n};\n\n/**\n * Try move the index forward, or into the neighbouring timeline\n *\n * @param {number} delta number of events to advance by\n * @return {number} number of events successfully advanced by\n */\nTimelineIndex.prototype.advance = function(delta) {\n if (!delta) {\n return 0;\n }\n\n // first try moving the index in the current timeline. See if there is room\n // to do so.\n let cappedDelta;\n if (delta < 0) {\n // we want to wind the index backwards.\n //\n // (this.minIndex() - this.index) is a negative number whose magnitude\n // is the amount of room we have to wind back the index in the current\n // timeline. We cap delta to this quantity.\n cappedDelta = Math.max(delta, this.minIndex() - this.index);\n if (cappedDelta < 0) {\n this.index += cappedDelta;\n return cappedDelta;\n }\n } else {\n // we want to wind the index forwards.\n //\n // (this.maxIndex() - this.index) is a (positive) number whose magnitude\n // is the amount of room we have to wind forward the index in the current\n // timeline. We cap delta to this quantity.\n cappedDelta = Math.min(delta, this.maxIndex() - this.index);\n if (cappedDelta > 0) {\n this.index += cappedDelta;\n return cappedDelta;\n }\n }\n\n // the index is already at the start/end of the current timeline.\n //\n // next see if there is a neighbouring timeline to switch to.\n const neighbour = this.timeline.getNeighbouringTimeline(\n delta < 0 ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS);\n if (neighbour) {\n this.timeline = neighbour;\n if (delta < 0) {\n this.index = this.maxIndex();\n } else {\n this.index = this.minIndex();\n }\n\n debuglog(\"paginate: switched to new neighbour\");\n\n // recurse, using the next timeline\n return this.advance(delta);\n }\n\n return 0;\n};\n\n/**\n * Try move the index backwards, or into the neighbouring timeline\n *\n * @param {number} delta number of events to retreat by\n * @return {number} number of events successfully retreated by\n */\nTimelineIndex.prototype.retreat = function(delta) {\n return this.advance(delta * -1) * -1;\n};\n\n/**\n * The TimelineWindow class.\n */\nmodule.exports.TimelineWindow = TimelineWindow;\n\n/**\n * The TimelineIndex class. exported here for unit testing.\n */\nmodule.exports.TimelineIndex = TimelineIndex;\n","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * This is an internal module.\n * @module utils\n */\n\n/**\n * Encode a dictionary of query parameters.\n * @param {Object} params A dict of key/values to encode e.g.\n * {\"foo\": \"bar\", \"baz\": \"taz\"}\n * @return {string} The encoded string e.g. foo=bar&baz=taz\n */\nmodule.exports.encodeParams = function(params) {\n let qs = \"\";\n for (const key in params) {\n if (!params.hasOwnProperty(key)) {\n continue;\n }\n qs += \"&\" + encodeURIComponent(key) + \"=\" +\n encodeURIComponent(params[key]);\n }\n return qs.substring(1);\n};\n\n/**\n * Encodes a URI according to a set of template variables. Variables will be\n * passed through encodeURIComponent.\n * @param {string} pathTemplate The path with template variables e.g. '/foo/$bar'.\n * @param {Object} variables The key/value pairs to replace the template\n * variables with. E.g. { \"$bar\": \"baz\" }.\n * @return {string} The result of replacing all template variables e.g. '/foo/baz'.\n */\nmodule.exports.encodeUri = function(pathTemplate, variables) {\n for (const key in variables) {\n if (!variables.hasOwnProperty(key)) {\n continue;\n }\n pathTemplate = pathTemplate.replace(\n key, encodeURIComponent(variables[key]),\n );\n }\n return pathTemplate;\n};\n\n/**\n * Applies a map function to the given array.\n * @param {Array} array The array to apply the function to.\n * @param {Function} fn The function that will be invoked for each element in\n * the array with the signature fn(element){...}\n * @return {Array} A new array with the results of the function.\n */\nmodule.exports.map = function(array, fn) {\n const results = new Array(array.length);\n for (let i = 0; i < array.length; i++) {\n results[i] = fn(array[i]);\n }\n return results;\n};\n\n/**\n * Applies a filter function to the given array.\n * @param {Array} array The array to apply the function to.\n * @param {Function} fn The function that will be invoked for each element in\n * the array. It should return true to keep the element. The function signature\n * looks like fn(element, index, array){...}.\n * @return {Array} A new array with the results of the function.\n */\nmodule.exports.filter = function(array, fn) {\n const results = [];\n for (let i = 0; i < array.length; i++) {\n if (fn(array[i], i, array)) {\n results.push(array[i]);\n }\n }\n return results;\n};\n\n/**\n * Get the keys for an object. Same as Object.keys().\n * @param {Object} obj The object to get the keys for.\n * @return {string[]} The keys of the object.\n */\nmodule.exports.keys = function(obj) {\n const keys = [];\n for (const key in obj) {\n if (!obj.hasOwnProperty(key)) {\n continue;\n }\n keys.push(key);\n }\n return keys;\n};\n\n/**\n * Get the values for an object.\n * @param {Object} obj The object to get the values for.\n * @return {Array<*>} The values of the object.\n */\nmodule.exports.values = function(obj) {\n const values = [];\n for (const key in obj) {\n if (!obj.hasOwnProperty(key)) {\n continue;\n }\n values.push(obj[key]);\n }\n return values;\n};\n\n/**\n * Invoke a function for each item in the array.\n * @param {Array} array The array.\n * @param {Function} fn The function to invoke for each element. Has the\n * function signature fn(element, index).\n */\nmodule.exports.forEach = function(array, fn) {\n for (let i = 0; i < array.length; i++) {\n fn(array[i], i);\n }\n};\n\n/**\n * The findElement() method returns a value in the array, if an element in the array\n * satisfies (returns true) the provided testing function. Otherwise undefined\n * is returned.\n * @param {Array} array The array.\n * @param {Function} fn Function to execute on each value in the array, with the\n * function signature fn(element, index, array)\n * @param {boolean} reverse True to search in reverse order.\n * @return {*} The first value in the array which returns true for\n * the given function.\n */\nmodule.exports.findElement = function(array, fn, reverse) {\n let i;\n if (reverse) {\n for (i = array.length - 1; i >= 0; i--) {\n if (fn(array[i], i, array)) {\n return array[i];\n }\n }\n } else {\n for (i = 0; i < array.length; i++) {\n if (fn(array[i], i, array)) {\n return array[i];\n }\n }\n }\n};\n\n/**\n * The removeElement() method removes the first element in the array that\n * satisfies (returns true) the provided testing function.\n * @param {Array} array The array.\n * @param {Function} fn Function to execute on each value in the array, with the\n * function signature fn(element, index, array). Return true to\n * remove this element and break.\n * @param {boolean} reverse True to search in reverse order.\n * @return {boolean} True if an element was removed.\n */\nmodule.exports.removeElement = function(array, fn, reverse) {\n let i;\n let removed;\n if (reverse) {\n for (i = array.length - 1; i >= 0; i--) {\n if (fn(array[i], i, array)) {\n removed = array[i];\n array.splice(i, 1);\n return removed;\n }\n }\n } else {\n for (i = 0; i < array.length; i++) {\n if (fn(array[i], i, array)) {\n removed = array[i];\n array.splice(i, 1);\n return removed;\n }\n }\n }\n return false;\n};\n\n/**\n * Checks if the given thing is a function.\n * @param {*} value The thing to check.\n * @return {boolean} True if it is a function.\n */\nmodule.exports.isFunction = function(value) {\n return Object.prototype.toString.call(value) == \"[object Function]\";\n};\n\n/**\n * Checks if the given thing is an array.\n * @param {*} value The thing to check.\n * @return {boolean} True if it is an array.\n */\nmodule.exports.isArray = function(value) {\n return Array.isArray ? Array.isArray(value) :\n Boolean(value && value.constructor === Array);\n};\n\n/**\n * Checks that the given object has the specified keys.\n * @param {Object} obj The object to check.\n * @param {string[]} keys The list of keys that 'obj' must have.\n * @throws If the object is missing keys.\n */\nmodule.exports.checkObjectHasKeys = function(obj, keys) {\n for (let i = 0; i < keys.length; i++) {\n if (!obj.hasOwnProperty(keys[i])) {\n throw new Error(\"Missing required key: \" + keys[i]);\n }\n }\n};\n\n/**\n * Checks that the given object has no extra keys other than the specified ones.\n * @param {Object} obj The object to check.\n * @param {string[]} allowedKeys The list of allowed key names.\n * @throws If there are extra keys.\n */\nmodule.exports.checkObjectHasNoAdditionalKeys = function(obj, allowedKeys) {\n for (const key in obj) {\n if (!obj.hasOwnProperty(key)) {\n continue;\n }\n if (allowedKeys.indexOf(key) === -1) {\n throw new Error(\"Unknown key: \" + key);\n }\n }\n};\n\n/**\n * Deep copy the given object. The object MUST NOT have circular references and\n * MUST NOT have functions.\n * @param {Object} obj The object to deep copy.\n * @return {Object} A copy of the object without any references to the original.\n */\nmodule.exports.deepCopy = function(obj) {\n return JSON.parse(JSON.stringify(obj));\n};\n\n/**\n * Compare two objects for equality. The objects MUST NOT have circular references.\n *\n * @param {Object} x The first object to compare.\n * @param {Object} y The second object to compare.\n *\n * @return {boolean} true if the two objects are equal\n */\nconst deepCompare = module.exports.deepCompare = function(x, y) {\n // Inspired by\n // http://stackoverflow.com/questions/1068834/object-comparison-in-javascript#1144249\n\n // Compare primitives and functions.\n // Also check if both arguments link to the same object.\n if (x === y) {\n return true;\n }\n\n if (typeof x !== typeof y) {\n return false;\n }\n\n // special-case NaN (since NaN !== NaN)\n if (typeof x === 'number' && isNaN(x) && isNaN(y)) {\n return true;\n }\n\n // special-case null (since typeof null == 'object', but null.constructor\n // throws)\n if (x === null || y === null) {\n return x === y;\n }\n\n // everything else is either an unequal primitive, or an object\n if (!(x instanceof Object)) {\n return false;\n }\n\n // check they are the same type of object\n if (x.constructor !== y.constructor || x.prototype !== y.prototype) {\n return false;\n }\n\n // special-casing for some special types of object\n if (x instanceof RegExp || x instanceof Date) {\n return x.toString() === y.toString();\n }\n\n // the object algorithm works for Array, but it's sub-optimal.\n if (x instanceof Array) {\n if (x.length !== y.length) {\n return false;\n }\n\n for (let i = 0; i < x.length; i++) {\n if (!deepCompare(x[i], y[i])) {\n return false;\n }\n }\n } else {\n // disable jshint \"The body of a for in should be wrapped in an if\n // statement\"\n /* jshint -W089 */\n\n // check that all of y's direct keys are in x\n let p;\n for (p in y) {\n if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {\n return false;\n }\n }\n\n // finally, compare each of x's keys with y\n for (p in y) {\n if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {\n return false;\n }\n if (!deepCompare(x[p], y[p])) {\n return false;\n }\n }\n }\n /* jshint +W089 */\n return true;\n};\n\n/**\n * Copy properties from one object to another.\n *\n * All enumerable properties, included inherited ones, are copied.\n *\n * This is approximately equivalent to ES6's Object.assign, except\n * that the latter doesn't copy inherited properties.\n *\n * @param {Object} target The object that will receive new properties\n * @param {...Object} source Objects from which to copy properties\n *\n * @return {Object} target\n */\nmodule.exports.extend = function() {\n const target = arguments[0] || {};\n for (let i = 1; i < arguments.length; i++) {\n const source = arguments[i];\n for (const propName in source) { // eslint-disable-line guard-for-in\n target[propName] = source[propName];\n }\n }\n return target;\n};\n\n/**\n * Run polyfills to add Array.map and Array.filter if they are missing.\n */\nmodule.exports.runPolyfills = function() {\n // Array.prototype.filter\n // ========================================================\n // SOURCE:\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter\n if (!Array.prototype.filter) {\n Array.prototype.filter = function(fun/*, thisArg*/) {\n if (this === void 0 || this === null) {\n throw new TypeError();\n }\n\n const t = Object(this);\n const len = t.length >>> 0;\n if (typeof fun !== 'function') {\n throw new TypeError();\n }\n\n const res = [];\n const thisArg = arguments.length >= 2 ? arguments[1] : void 0;\n for (let i = 0; i < len; i++) {\n if (i in t) {\n const val = t[i];\n\n // NOTE: Technically this should Object.defineProperty at\n // the next index, as push can be affected by\n // properties on Object.prototype and Array.prototype.\n // But that method's new, and collisions should be\n // rare, so use the more-compatible alternative.\n if (fun.call(thisArg, val, i, t)) {\n res.push(val);\n }\n }\n }\n\n return res;\n };\n }\n\n // Array.prototype.map\n // ========================================================\n // SOURCE:\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map\n // Production steps of ECMA-262, Edition 5, 15.4.4.19\n // Reference: http://es5.github.io/#x15.4.4.19\n if (!Array.prototype.map) {\n Array.prototype.map = function(callback, thisArg) {\n let T, k;\n\n if (this === null || this === undefined) {\n throw new TypeError(' this is null or not defined');\n }\n\n // 1. Let O be the result of calling ToObject passing the |this|\n // value as the argument.\n const O = Object(this);\n\n // 2. Let lenValue be the result of calling the Get internal\n // method of O with the argument \"length\".\n // 3. Let len be ToUint32(lenValue).\n const len = O.length >>> 0;\n\n // 4. If IsCallable(callback) is false, throw a TypeError exception.\n // See: http://es5.github.com/#x9.11\n if (typeof callback !== 'function') {\n throw new TypeError(callback + ' is not a function');\n }\n\n // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.\n if (arguments.length > 1) {\n T = thisArg;\n }\n\n // 6. Let A be a new array created as if by the expression new Array(len)\n // where Array is the standard built-in constructor with that name and\n // len is the value of len.\n const A = new Array(len);\n\n // 7. Let k be 0\n k = 0;\n\n // 8. Repeat, while k < len\n while (k < len) {\n var kValue, mappedValue;\n\n // a. Let Pk be ToString(k).\n // This is implicit for LHS operands of the in operator\n // b. Let kPresent be the result of calling the HasProperty internal\n // method of O with argument Pk.\n // This step can be combined with c\n // c. If kPresent is true, then\n if (k in O) {\n // i. Let kValue be the result of calling the Get internal\n // method of O with argument Pk.\n kValue = O[k];\n\n // ii. Let mappedValue be the result of calling the Call internal\n // method of callback with T as the this value and argument\n // list containing kValue, k, and O.\n mappedValue = callback.call(T, kValue, k, O);\n\n // iii. Call the DefineOwnProperty internal method of A with arguments\n // Pk, Property Descriptor\n // { Value: mappedValue,\n // Writable: true,\n // Enumerable: true,\n // Configurable: true },\n // and false.\n\n // In browsers that support Object.defineProperty, use the following:\n // Object.defineProperty(A, k, {\n // value: mappedValue,\n // writable: true,\n // enumerable: true,\n // configurable: true\n // });\n\n // For best browser support, use the following:\n A[k] = mappedValue;\n }\n // d. Increase k by 1.\n k++;\n }\n\n // 9. return A\n return A;\n };\n }\n\n // Array.prototype.forEach\n // ========================================================\n // SOURCE:\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach\n // Production steps of ECMA-262, Edition 5, 15.4.4.18\n // Reference: http://es5.github.io/#x15.4.4.18\n if (!Array.prototype.forEach) {\n Array.prototype.forEach = function(callback, thisArg) {\n let T, k;\n\n if (this === null || this === undefined) {\n throw new TypeError(' this is null or not defined');\n }\n\n // 1. Let O be the result of calling ToObject passing the |this| value as the\n // argument.\n const O = Object(this);\n\n // 2. Let lenValue be the result of calling the Get internal method of O with the\n // argument \"length\".\n // 3. Let len be ToUint32(lenValue).\n const len = O.length >>> 0;\n\n // 4. If IsCallable(callback) is false, throw a TypeError exception.\n // See: http://es5.github.com/#x9.11\n if (typeof callback !== \"function\") {\n throw new TypeError(callback + ' is not a function');\n }\n\n // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.\n if (arguments.length > 1) {\n T = thisArg;\n }\n\n // 6. Let k be 0\n k = 0;\n\n // 7. Repeat, while k < len\n while (k < len) {\n var kValue;\n\n // a. Let Pk be ToString(k).\n // This is implicit for LHS operands of the in operator\n // b. Let kPresent be the result of calling the HasProperty internal\n // method of O with\n // argument Pk.\n // This step can be combined with c\n // c. If kPresent is true, then\n if (k in O) {\n // i. Let kValue be the result of calling the Get internal method of O with\n // argument Pk\n kValue = O[k];\n\n // ii. Call the Call internal method of callback with T as the this value and\n // argument list containing kValue, k, and O.\n callback.call(T, kValue, k, O);\n }\n // d. Increase k by 1.\n k++;\n }\n // 8. return undefined\n };\n }\n};\n\n/**\n * Inherit the prototype methods from one constructor into another. This is a\n * port of the Node.js implementation with an Object.create polyfill.\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 */\nmodule.exports.inherits = function(ctor, superCtor) {\n // Add Object.create polyfill for IE8\n // Source:\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript\n // /Reference/Global_Objects/Object/create#Polyfill\n if (typeof Object.create != 'function') {\n // Production steps of ECMA-262, Edition 5, 15.2.3.5\n // Reference: http://es5.github.io/#x15.2.3.5\n Object.create = (function() {\n // To save on memory, use a shared constructor\n function Temp() {}\n\n // make a safe reference to Object.prototype.hasOwnProperty\n const hasOwn = Object.prototype.hasOwnProperty;\n\n return function(O) {\n // 1. If Type(O) is not Object or Null throw a TypeError exception.\n if (typeof O != 'object') {\n throw new TypeError('Object prototype may only be an Object or null');\n }\n\n // 2. Let obj be the result of creating a new object as if by the\n // expression new Object() where Object is the standard built-in\n // constructor with that name\n // 3. Set the [[Prototype]] internal property of obj to O.\n Temp.prototype = O;\n const obj = new Temp();\n Temp.prototype = null; // Let's not keep a stray reference to O...\n\n // 4. If the argument Properties is present and not undefined, add\n // own properties to obj as if by calling the standard built-in\n // function Object.defineProperties with arguments obj and\n // Properties.\n if (arguments.length > 1) {\n // Object.defineProperties does ToObject on its first argument.\n const Properties = Object(arguments[1]);\n for (const prop in Properties) {\n if (hasOwn.call(Properties, prop)) {\n obj[prop] = Properties[prop];\n }\n }\n }\n\n // 5. Return obj\n return obj;\n };\n })();\n }\n // END polyfill\n\n // Add util.inherits from Node.js\n // Source:\n // https://github.com/joyent/node/blob/master/lib/util.js\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 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","/*\nCopyright 2015, 2016 OpenMarket Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\"use strict\";\n/**\n * This is an internal module. See {@link createNewMatrixCall} for the public API.\n * @module webrtc/call\n */\nconst utils = require(\"../utils\");\nconst EventEmitter = require(\"events\").EventEmitter;\nconst DEBUG = true; // set true to enable console logging.\n\n// events: hangup, error(err), replaced(call), state(state, oldState)\n\n/**\n * Fires when the MatrixCall encounters an error when sending a Matrix event.\n *

\n * This is required to allow errors, which occur during sending of events, to bubble up.\n * (This is because call.js does a hangup when it encounters a normal `error`, which in\n * turn could lead to an UnknownDeviceError.)\n *

\n * To deal with an UnknownDeviceError when trying to send events, the application should let\n * users know that there are new devices in the encrypted room (into which the event was\n * sent) and give the user the options to resend unsent events or cancel them. Resending\n * is done using {@link module:client~MatrixClient#resendEvent} and cancelling can be done by using\n * {@link module:client~MatrixClient#cancelPendingEvent}.\n *

\n * MatrixCall will not do anything in response to an error that causes `send_event_error`\n * to be emitted with the exception of sending `m.call.candidates`, which is retried upon\n * failure when ICE candidates are being sent. This happens during call setup.\n *\n * @event module:webrtc/call~MatrixCall#\"send_event_error\"\n * @param {Error} err The error caught from calling client.sendEvent in call.js.\n * @example\n * matrixCall.on(\"send_event_error\", function(err){\n * console.error(err);\n * });\n */\n\n/**\n * Fires whenever an error occurs when call.js encounters an issue with setting up the call.\n *

\n * The error given will have a code equal to either `MatrixCall.ERR_LOCAL_OFFER_FAILED` or\n * `MatrixCall.ERR_NO_USER_MEDIA`. `ERR_LOCAL_OFFER_FAILED` is emitted when the local client\n * fails to create an offer. `ERR_NO_USER_MEDIA` is emitted when the user has denied access\n * to their audio/video hardware.\n *\n * @event module:webrtc/call~MatrixCall#\"error\"\n * @param {Error} err The error raised by MatrixCall.\n * @example\n * matrixCall.on(\"error\", function(err){\n * console.error(err.code, err);\n * });\n */\n\n/**\n * Construct a new Matrix Call.\n * @constructor\n * @param {Object} opts Config options.\n * @param {string} opts.roomId The room ID for this call.\n * @param {Object} opts.webRtc The WebRTC globals from the browser.\n * @param {boolean} opts.forceTURN whether relay through TURN should be forced.\n * @param {Object} opts.URL The URL global.\n * @param {Array} opts.turnServers Optional. A list of TURN servers.\n * @param {MatrixClient} opts.client The Matrix Client instance to send events to.\n */\nfunction MatrixCall(opts) {\n this.roomId = opts.roomId;\n this.client = opts.client;\n this.webRtc = opts.webRtc;\n this.forceTURN = opts.forceTURN;\n this.URL = opts.URL;\n // Array of Objects with urls, username, credential keys\n this.turnServers = opts.turnServers || [];\n if (this.turnServers.length === 0) {\n this.turnServers.push({\n urls: [MatrixCall.FALLBACK_STUN_SERVER],\n });\n }\n utils.forEach(this.turnServers, function(server) {\n utils.checkObjectHasKeys(server, [\"urls\"]);\n });\n\n this.callId = \"c\" + new Date().getTime() + Math.random();\n this.state = 'fledgling';\n this.didConnect = false;\n\n // A queue for candidates waiting to go out.\n // We try to amalgamate candidates into a single candidate message where\n // possible\n this.candidateSendQueue = [];\n this.candidateSendTries = 0;\n\n // Lookup from opaque queue ID to a promise for media element operations that\n // need to be serialised into a given queue. Store this per-MatrixCall on the\n // assumption that multiple matrix calls will never compete for control of the\n // same DOM elements.\n this.mediaPromises = Object.create(null);\n\n this.screenSharingStream = null;\n}\n/** The length of time a call can be ringing for. */\nMatrixCall.CALL_TIMEOUT_MS = 60000;\n/** The fallback server to use for STUN. */\nMatrixCall.FALLBACK_STUN_SERVER = 'stun:stun.l.google.com:19302';\n/** An error code when the local client failed to create an offer. */\nMatrixCall.ERR_LOCAL_OFFER_FAILED = \"local_offer_failed\";\n/**\n * An error code when there is no local mic/camera to use. This may be because\n * the hardware isn't plugged in, or the user has explicitly denied access.\n */\nMatrixCall.ERR_NO_USER_MEDIA = \"no_user_media\";\n\nutils.inherits(MatrixCall, EventEmitter);\n\n/**\n * Place a voice call to this room.\n * @throws If you have not specified a listener for 'error' events.\n */\nMatrixCall.prototype.placeVoiceCall = function() {\n debuglog(\"placeVoiceCall\");\n checkForErrorListener(this);\n _placeCallWithConstraints(this, _getUserMediaVideoContraints('voice'));\n this.type = 'voice';\n};\n\n/**\n * Place a video call to this room.\n * @param {Element} remoteVideoElement a <video> DOM element\n * to render video to.\n * @param {Element} localVideoElement a <video> DOM element\n * to render the local camera preview.\n * @throws If you have not specified a listener for 'error' events.\n */\nMatrixCall.prototype.placeVideoCall = function(remoteVideoElement, localVideoElement) {\n debuglog(\"placeVideoCall\");\n checkForErrorListener(this);\n this.localVideoElement = localVideoElement;\n this.remoteVideoElement = remoteVideoElement;\n _placeCallWithConstraints(this, _getUserMediaVideoContraints('video'));\n this.type = 'video';\n _tryPlayRemoteStream(this);\n};\n\n/**\n * Place a screen-sharing call to this room. This includes audio.\n * This method is EXPERIMENTAL and subject to change without warning. It\n * only works in Google Chrome and Firefox >= 44.\n * @param {Element} remoteVideoElement a <video> DOM element\n * to render video to.\n * @param {Element} localVideoElement a <video> DOM element\n * to render the local camera preview.\n * @throws If you have not specified a listener for 'error' events.\n */\nMatrixCall.prototype.placeScreenSharingCall =\n function(remoteVideoElement, localVideoElement) {\n debuglog(\"placeScreenSharingCall\");\n checkForErrorListener(this);\n const screenConstraints = _getScreenSharingConstraints(this);\n if (!screenConstraints) {\n return;\n }\n this.localVideoElement = localVideoElement;\n this.remoteVideoElement = remoteVideoElement;\n const self = this;\n this.webRtc.getUserMedia(screenConstraints, function(stream) {\n self.screenSharingStream = stream;\n debuglog(\"Got screen stream, requesting audio stream...\");\n const audioConstraints = _getUserMediaVideoContraints('voice');\n _placeCallWithConstraints(self, audioConstraints);\n }, function(err) {\n self.emit(\"error\",\n callError(\n MatrixCall.ERR_NO_USER_MEDIA,\n \"Failed to get screen-sharing stream: \" + err,\n ),\n );\n });\n this.type = 'video';\n _tryPlayRemoteStream(this);\n};\n\n/**\n * Play the given HTMLMediaElement, serialising the operation into a chain\n * of promises to avoid racing access to the element\n * @param {Element} element HTMLMediaElement element to play\n * @param {string} queueId Arbitrary ID to track the chain of promises to be used\n */\nMatrixCall.prototype.playElement = function(element, queueId) {\n console.log(\"queuing play on \" + queueId + \" and element \" + element);\n // XXX: FIXME: Does this leak elements, given the old promises\n // may hang around and retain a reference to them?\n if (this.mediaPromises[queueId]) {\n // XXX: these promises can fail (e.g. by