{"version":3,"sources":["webpack:///./src/helpers/number/clamp.ts","webpack:///./src/helpers/object/getDeepProperty.ts","webpack:///./src/helpers/animation.ts","webpack:///./src/components/horizontalMenu.ts","webpack:///./src/helpers/object/validateInitObject.ts","webpack:///./src/components/transition.ts","webpack:///./src/helpers/compareVersion.ts","webpack:///./src/lib/appManagers/appStateManager.ts","webpack:///./src/helpers/getTimeFormat.ts","webpack:///./src/helpers/object/setDeepProperty.ts","webpack:///./src/environment/canUseTransferables.ts","webpack:///./src/lib/rlottie/rlottiePlayer.ts","webpack:///./src/helpers/schedulers.ts","webpack:///./src/lib/rlottie/rlottie.worker.ts","webpack:///./src/lib/rlottie/queryableWorker.ts","webpack:///./src/lib/rlottie/lottieLoader.ts","webpack:///./src/helpers/array/indexOfAndSplice.ts","webpack:///./src/components/animationIntersector.ts","webpack:///./src/helpers/array/forEachReverse.ts","webpack:///./src/pages/pagesManager.ts","webpack:///./src/pages/page.ts","webpack:///./src/hooks/useHeavyAnimationCheck.ts","webpack:///./src/helpers/fastSmoothScroll.ts","webpack:///./src/helpers/dom/isInDOM.ts","webpack:///./src/helpers/dom/whichChild.ts","webpack:///./src/helpers/dom/findUpAsChild.ts"],"names":["clamp","v","min","max","getDeepProperty","object","key","splitted","split","o","forEach","instances","Map","cancelAnimationByKey","instance","get","getAnimationInstance","isCancelled","deferred","resolve","animateSingle","tick","set","then","delete","createAnimationInstance","animate","horizontalMenu","tabs","content","onClick","onTransitionEnd","transitionTime","scrollableX","selectTab","dataset","animation","proxy","Proxy","apply","target","that","args","id","undefined","el","querySelector","children","selectTarget","tabContent","canChange","scrollIntoViewNew","element","parentElement","position","forceDirection","Static","forceDuration","axis","settings","animationsEnabled","prevId","classList","contains","prev","tagName","toLowerCase","remove","useStripe","indicator","currentIndicator","shiftLeft","offsetLeft","scaleFactor","clientWidth","style","transform","requestAnimationFrame","add","firstElementChild","addEventListener","e","tab","validateInitObject","initObject","currentObject","onReplace","previousKey","slideNavigation","prevTabContent","toRight","width","getBoundingClientRect","elements","reverse","filter","offsetWidth","slideTabs","TransitionSlider","type","isHeavy","animationFunction","Transition","once","withAnimationListener","onTransitionEndCallbacks","animationDeferred","from","listenerName","onEndEvent","callback","removeEventListener","clear","overrideFrom","HTMLElement","to","timeout","clearTimeout","window","setTimeout","onTransitionEndCallback","toggle","_from","compareVersion","v1","v2","s1","s2","i","length","STATE_VERSION","version","BUILD","build","STATE_INIT","allDialogsLoaded","pinnedOrders","contactsList","updates","filters","maxSeenMsgId","stateCreatedTime","Date","now","recentEmoji","topPeersCache","recentSearch","authState","_","hiddenPinnedMessages","messagesTextSize","distanceUnit","sendShortcut","autoDownload","photo","contacts","private","groups","channels","video","file","autoDownloadNew","file_size_max","pFlags","video_preload_large","audio_preload_next","photo_size_max","video_size_max","video_upload_maxbitrate","autoPlay","gifs","videos","stickers","suggest","loop","emoji","big","themes","name","background","blur","slug","color","highlightningColor","intensity","theme","notifications","sound","timeFormat","toLocaleString","match","keepSigned","chatContextMenuHintWasShown","stateId","notifySettings","ALL_KEYS","Object","keys","REFRESH_KEYS","super","log","logger","neededPeers","singlePeerMap","storages","users","chats","dialogs","storagesResults","storage","stateStorage","this","loadSavedState","rootScope","requestPeerSingle","myId","loaded","console","time","Promise","storagesKeys","storagesPromises","map","getAll","promises","concat","sessionStorage","all","arr","state","value","pushToState","copy","splice","auth","shift","shiftedWebKAuth","push","values","dcID","baseDcId","date","toPeerId","obj","idx","dispatchEvent","preserve","state_id","s","r","hasOwnProperty","nightTheme","find","t","autoDownloadSettings","oldTypes","mediaType","peerTypeSettings","peerType","missingKey","result","migrated","newTheme","newVersion","timeEnd","catch","slice","join","pop","setDeepProperty","first","direct","setKeyValueToStorage","peerId","limit","has","Set","keepPeerSingle","keepPeerIdSingle","requestPeer","existsPeerId","size","appStateManager","CAN_USE_TRANSFERABLES","navigator","userAgent","err","cache","frames","counter","height","toneIndex","Boolean","worker","options","reqId","paused","direction","speed","autoplay","group","cachingDelta","skipRatio","_loop","_autoplay","initFrame","inverseColor","skipFirstFrameRendering","needUpscale","skipDelta","pixelRatio","devicePixelRatio","Math","round","mediaSizes","isMobile","noCache","Infinity","canvas","document","createElement","context","getContext","clamped","Uint8ClampedArray","imageData","ImageData","cacheName","generateName","getCache","getCacheCounter","methodName","sendQuery","data","setMainLoop","clearPendingRAF","rafId","curFrame","minFrame","maxFrame","renderFirstFrame","pause","resetCurrentFrame","requestFrame","stop","play","lottieLoader","onDestroy","releaseCache","cleanup","frame","g","b","frameNo","applyColor","applyInversing","putImageData","error","frInterval","delta","frThen","renderFrame2","renderFrame","onLap","fps","method","mainLoopForwards","mainLoopBackwards","bind","currentMethod","frameListener","listenerResults","enterFrame","playToFrame","setDirection","setSpeed","bounds","setMinMax","playToFrameOnFrameCallback","renderIfPaused","frameCount","diff","parentNode","appendChild","fastRafCallbacks","fastRaf","currentCallbacks","cb","fastRafConventionalCallbacks","rafPromise","processing","fastRafConventional","fastRafPromise","doubleRaf","Worker_fn","Worker","onerror","terminate","onmessage","event","queryMethodListener","queryMethodArguments","message","postMessage","queryMethod","transfer","arg","ArrayBuffer","buffer","isWebAssemblySupported","loadPromise","reject","workersLimit","players","workers","curWorkerNum","Error","onPlayerLoaded","rlPlayer","debug","onLoad","warn","onFrame","onPlayerError","animationIntersector","getAnimations","checkAnimation","player","remain","params","loadAnimationFromURL","url","loadLottieWorkers","fetch","res","headers","blob","arrayBuffer","invokeCrypto","blobConstruct","newParams","assign","animationData","loadAnimationWorker","race","middleware","parseInt","container","initPlayer","addAnimation","loadFromData","indexOfAndSplice","array","item","indexOf","spliced","visible","byGroups","lockedGroups","onlyOnePlayableGroup","intersectionLockedGroups","videosLocked","observer","IntersectionObserver","entries","entry","p","isIntersecting","clearCache","overrideIdleGroups","doc","checkAnimations","override","found","HTMLVideoElement","src","load","unobserve","observe","blurred","destroy","animations","removeAnimation","idle","isIDLE","refreshGroup","forEachReverse","pagesManager","pageId","pagesDiv","getElementById","scrollableDiv","page","onShown","isAuthPage","display","whichChild","pageEl","fastSmoothScroll","className","onFirstMount","onMount","installed","body","setPage","isAnimating","heavyAnimationPromise","promisesInQueue","dispatchHeavyAnimationEvent","promise","finally","perf","performance","_heavyAnimationPromise","isFulfilled","onHeavyAnimationEnd","interruptHeavyAnimation","getHeavyAnimationPromise","handleAnimationStart","handleAnimationEnd","listenerSetter","removeManual","FocusDirection","margin","maxDistance","scrollWithJs","getNormalSize","rectStartKey","rectEndKey","sizeKey","scrollSizeKey","scrollPositionKey","elementRect","containerRect","elementPosition","elementSize","containerSize","rect","scrollPosition","scrollSize","path","fallbackToElementStartWhenCentering","abs","scrollTop","remainingPath","absPath","duration","startAt","transition","shortTransition","longTransition","currentPath","isInDOM","isConnected","elem","previousElementSibling","findUpAsChild","parent"],"mappings":"yFAAe,SAASA,EAAMC,EAAWC,EAAaC,GACpD,OAAOF,EAAIC,EAAMA,EAAQD,EAAIE,EAAOA,EAAMF,EAD5C,mC,iCCAe,SAASG,EAAgBC,EAAaC,GACnD,MAAMC,EAAWD,EAAIE,MAAM,KAC3B,IAAIC,EAASJ,EAUb,OATAE,EAASG,QAAQJ,IACXA,IAKJG,EAAIA,EAAEH,MAGDG,EAZT,mC,iCCAA,0HAiBA,MAAME,EAA0D,IAAIC,IAsB7D,SAASC,EAAqBP,GACnC,MAAMQ,EALD,SAA8BR,GACnC,OAAOK,EAAUI,IAAIT,GAIJU,CAAqBV,GACnCQ,IACDA,EAASG,aAAc,EACvBH,EAASI,SAASC,WAIf,SAASC,EAAcC,EAAgBf,EAA2BQ,GAiBvE,OAhBIA,IACFA,EA9BG,SAAiCR,GACtCO,EAAqBP,GAErB,MAAMQ,EAA8B,CAClCG,aAAa,EACbC,SAAU,eAQZ,OALAP,EAAUW,IAAIhB,EAAKQ,GACnBA,EAASI,SAASK,KAAK,KACrBZ,EAAUa,OAAOlB,KAGZQ,EAiBMW,CAAwBnB,IAGrC,YAAQ,KACHQ,EAASG,cAITI,IACDD,EAAcC,EAAMf,EAAKQ,GAEzBA,EAASI,SAASC,aAIfL,EAASI,SAGX,SAASQ,EAAQL,GACtB,YAAQ,KACHA,KACDK,EAAQL,O,iCCtEd,uFAcO,SAASM,EACdC,EACAC,EACAC,EACAC,EACAC,EAAiB,IACjBC,GAEA,MAAMC,EAAY,YAAiBL,EAASD,GAAsC,SAA9BC,EAAQM,QAAQC,UAAuB,OAAS,aAAcJ,EAAgBD,GAElI,GAAGH,EAAM,CACP,MAAMS,EAAQ,IAAIC,MAAMJ,EAAW,CACjCK,MAAO,CAACC,EAAQC,EAAMC,KACpB,MAAMC,GAAMD,EAAK,GACXhB,OAAsBkB,IAAZF,EAAK,IAAmBA,EAAK,GAEvCG,EAAMjB,EAAKkB,cAAc,cAAcH,QAAWf,EAAKmB,SAASJ,GACtEK,EAAaH,EAAIF,EAAIjB,MAInBsB,EAAe,CAACR,EAAqBG,EAAYjB,GAAU,KAC/D,MAAMuB,EAAapB,EAAQkB,SAASJ,GAEpC,GAAGb,EAAS,CACV,MAAMoB,EAAYpB,EAAQa,EAAIM,EAAYvB,GAC1C,QAAiBkB,IAAdM,IAA4BA,EAC7B,OAIDjB,GACDA,EAAYkB,kBAAkB,CAC5BC,QAASZ,EAAOa,cAAcN,SAASJ,GACvCW,SAAU,SACVC,eAAgB7B,OAAUkB,EAAY,IAAeY,OACrDC,cAAezB,EACf0B,KAAM,MAIN,UAAUC,SAASC,oBACrBlC,GAAU,GAGZ,MAAMmC,EAAS3B,EAAU2B,SACzB,GAAGrB,EAAOsB,UAAUC,SAAS,WAAapB,IAAOkB,EAC/C,OAAO,EAGT,MAAMG,EAAOpC,EAAKkB,cAAcmB,EAAQC,cAAgB,WAExD,YAAQ,KACNF,GAAQA,EAAKF,UAAUK,OAAO,YAI7BC,IAAyB,IAAZP,GAAiBnC,GAC/B,YAAQ,KACN,MAAM2C,EAAY7B,EAAOM,cAAc,KACjCwB,EAAmB9B,EAAOa,cAAcN,SAASc,GAAQf,cAAc,KAE7EwB,EAAiBR,UAAUK,OAAO,WAClCE,EAAUP,UAAUK,OAAO,WAG3B,MAAMI,EAAYD,EAAiBjB,cAAcA,cAAcmB,WAAaH,EAAUhB,cAAcA,cAAcmB,WAC5GC,EAAcH,EAAiBI,YAAcL,EAAUK,YAC7DL,EAAUM,MAAMC,UAAY,eAAeL,sBAA8BE,WAIzEI,sBAAsB,KAEpBR,EAAUP,UAAUgB,IAAI,WACxBT,EAAUM,MAAMC,UAAY,WAMlC,YAAQ,KACNpC,EAAOsB,UAAUgB,IAAI,YAGvB5C,EAAUS,EAAIjB,IAGV0C,GAAaxC,EAAKkC,UAAUC,SAAS,aAGrCE,EAAUrC,EAAKmD,kBAAkBd,QAuBvC,OAtBArC,EAAKoD,iBAAiB,SAAS,SAASC,GACtC,IAQItC,EARAH,EAASyC,EAAEzC,OAMf,GAJAA,EAAS,YAAcA,EAAQZ,IAI3BY,EAAQ,OAAO,EAGnB,GAAGA,EAAOL,QAAQ+C,KAEhB,GADAvC,GAAMH,EAAOL,QAAQ+C,KACV,IAARvC,EACD,OAAO,OAGTA,EAAK,YAAWH,GAGlBQ,EAAaR,EAAQG,MAGhBN,EAGT,OAAOH,I,iCCnIT,sDAGe,SAASiD,EAAmBC,EAAiBC,EAAoBC,EAAmCC,GACjH,IAAI,MAAMjF,KAAO8E,SACLC,EAAc/E,WAAiB8E,EAAW9E,IAClD+E,EAAc/E,GAAO,YAAK8E,EAAW9E,IACrCgF,GAAaA,EAAUC,GAAejF,IAC9B,YAAS8E,EAAW9E,KAC5B6E,EAAmBC,EAAW9E,GAAM+E,EAAc/E,GAAMgF,EAAWC,GAAejF,K,iCCTxF,6EAYA,SAASkF,EAAgBvC,EAAyBwC,EAA6BC,GAC7E,MAAMC,EAAQF,EAAeG,wBAAwBD,MAC/CE,EAAW,CAAC5C,EAAYwC,GAY9B,OAXGC,GAASG,EAASC,UACrBD,EAAS,GAAGlB,MAAMoB,OAAS,kBAC3BF,EAAS,GAAGlB,MAAMC,UAAY,eAAwB,KAARe,aAC9CE,EAAS,GAAGlB,MAAMC,UAAY,eAAee,aAE7C1C,EAAWa,UAAUgB,IAAI,UACpB7B,EAAW+C,YAEhB/C,EAAW0B,MAAMC,UAAY,GAC7B3B,EAAW0B,MAAMoB,OAAS,GAEnB,KACLN,EAAed,MAAMC,UAAYa,EAAed,MAAMoB,OAAS,IAInE,SAASE,EAAUhD,EAAyBwC,EAA6BC,GAWrE,MAAMC,EAAQF,EAAeG,wBAAwBD,MAM/CE,EAAW,CAAC5C,EAAYwC,GAWhC,OAVKC,GAASG,EAASC,UACrBD,EAAS,GAAGlB,MAAMC,UAAY,gBAAgBe,aAC9CE,EAAS,GAAGlB,MAAMC,UAAY,eAAee,aAE7C1C,EAAWa,UAAUgB,IAAI,UACpB7B,EAAW+C,YAEhB/C,EAAW0B,MAAMC,UAAY,GAGxB,KACLa,EAAed,MAAMC,UAAY,IAqB9B,MAAMsB,EAAmB,CAC9BrE,EACAsE,EACAnE,EACAD,EACAqE,GAAU,KAEV,IAAIC,EAAwC,KAE5C,OAAOF,GACL,IAAK,OACHE,EAAoBJ,EACpB,MACF,IAAK,aACHI,EAAoBb,EAQxB,OAFA3D,EAAQM,QAAQC,UAAY+D,EAErBG,EAAWzE,EAASwE,EAAmBrE,EAAgBD,EAAiBqE,IAK3EE,EAAa,CACjBzE,EACAwE,EACArE,EACAD,EACAqE,GAAU,EACVG,GAAO,EACPC,GAAwB,KAExB,MAAMC,EAAuD,IAAI7F,IACjE,IAAI8F,EAEAC,EAAoB,KAExB,GAAGH,EAAuB,CACxB,MAAMI,EAAeP,EAAoB,gBAAkB,eAErDQ,EAAc5B,IAGlB,GAFA,YAAYA,GAERA,EAAEzC,OAAuBa,gBAAkBxB,EAC7C,OAKF,MAAMiF,EAAWL,EAAyB1F,IAAIkE,EAAEzC,QAC7CsE,GAAUA,IAEV7B,EAAEzC,SAAWmE,KAIZD,GAAqBN,IAEtBM,IACDA,EAAkBvF,UAClBuF,OAAoB9D,GAGnBb,GACDA,EAAgBG,EAAU2B,UAG5BhC,EAAQiC,UAAUK,OAAO,YAAa,YAAa,iBAEhDoC,IACD1E,EAAQkF,oBAAoBH,EAAcC,GAC1CF,EAAOD,OAAoB9D,EAC3B6D,EAAyBO,YAK7BnF,EAAQmD,iBAAiB4B,EAAcC,GAGzC,SAAS3E,EAAUS,EAA0BjB,GAAU,EAAMuF,GACxDA,IACDN,EAAOM,GAGNtE,aAAcuE,cACfvE,EAAK,YAAWA,IAGlB,MAAMkB,EAAS3B,EAAU2B,SACzB,GAAGlB,IAAOkB,EAAQ,OAAO,EAIzB,MAAMsD,EAAKtF,EAAQkB,SAASJ,GAM5B,GAJI,UAAUgB,SAASC,oBAAiC,IAAZC,IAC1CnC,GAAU,IAGR8E,EAAuB,CACzB,MAAMY,EAAUvF,EAAQM,QAAQiF,aACjBxE,IAAZwE,GACDC,cAAcD,UAGTvF,EAAQM,QAAQiF,QAGzB,IAAI1F,EAAS,CACX,GAAGiF,EAAMA,EAAK7C,UAAUK,OAAO,SAAU,KAAM,aAC1C,GAAGgD,EAAI,CACV,MAAML,EAAWL,EAAyB1F,IAAIoG,GAC3CL,GACDA,IAcJ,OAVGK,IACDA,EAAGrD,UAAUK,OAAO,KAAM,QAC1BgD,EAAGrD,UAAUgB,IAAI,WAGnBjD,EAAQiC,UAAUK,OAAO,YAAa,YAAa,iBAEnDwC,EAAOQ,OAEJpF,GAAiBA,EAAgBY,IAIlC6D,IACF3E,EAAQM,QAAQiF,QAAU,GAAKE,OAAOC,WAAW,KAC/CJ,EAAGrD,UAAUK,OAAO,MACpBwC,GAAQA,EAAK7C,UAAUK,OAAO,QAC9BtC,EAAQiC,UAAUK,OAAO,YAAa,YAAa,wBAC5CtC,EAAQM,QAAQiF,SACtBpF,IAGF2E,IACDA,EAAK7C,UAAUK,OAAO,MACtBwC,EAAK7C,UAAUgB,IAAI,SAGrBjD,EAAQiC,UAAUgB,IAAI,aACtB,MAAMY,EAAU7B,EAASlB,EAGzB,IAAI6E,EAqBJ,GAvBA3F,EAAQiC,UAAU2D,OAAO,aAAc/B,GAGnCyB,IAGCd,EACDmB,EAA0BnB,EAAkBc,EAAIR,EAAMjB,GAEtDyB,EAAGrD,UAAUgB,IAAI,UAGnBqC,EAAGrD,UAAUK,OAAO,QACpBgD,EAAGrD,UAAUgB,IAAI,OAGhBqC,GACDV,EAAyBnF,IAAI6F,EAAI,KAC/BA,EAAGrD,UAAUK,OAAO,MACpBsC,EAAyBjF,OAAO2F,KAIjCR,EAAqB,CACtB,MAAMe,EAAQf,EACRG,EAAW,KACfY,EAAM5D,UAAUK,OAAO,SAAU,QAE9BqD,GACDA,IAGFf,EAAyBjF,OAAOkG,IAGlC,GAAGP,EACDV,EAAyBnF,IAAIoG,EAAOZ,OAC/B,CACL,MAAMM,EAAUE,OAAOC,WAAWT,EAAU9E,GAC5CyE,EAAyBnF,IAAIoG,EAAO,KAClCL,aAAaD,GACbX,EAAyBjF,OAAOkG,KAIjCtB,IACGM,IACFA,EAAoB,eAItB,YAA4BA,EAAoC,EAAjB1E,IAInD2E,EAAOQ,EAMT,OAFAjF,EAAU2B,OAAS,IAAM8C,EAAO,YAAWA,IAAS,EAE7CzE,I,sOCrSM,SAASyF,EAAeC,EAAYC,GACjDD,EAAKA,EAAGpH,MAAM,IAAK,GAAG,GACtBqH,EAAKA,EAAGrH,MAAM,IAAK,GAAG,GACtB,MAAMsH,EAAKF,EAAGpH,MAAM,KACduH,EAAKF,EAAGrH,MAAM,KAEpB,IAAI,IAAIwH,EAAI,EAAGA,EAAIF,EAAGG,SAAUD,EAAG,CACjC,MAAMJ,GAAME,EAAGE,GACTH,GAAME,EAAGC,GACf,GAAGJ,EAAKC,EAAI,OAAO,EACd,GAAGD,EAAKC,EAAI,OAAQ,EAG3B,OAAO,E,wUCiBT,MAGMK,EAAgB,IAAIC,QACpBC,EAAQ,IAAIC,MA0FLC,EAAoB,CAC/BC,iBAAkB,GAClBC,aAAc,GACdC,aAAc,GACdC,QAAS,GACTC,QAAS,GACTC,aAAc,EACdC,iBAAkBC,KAAKC,MACvBC,YAAa,GACbC,cAAe,GACfC,aAAc,GACdf,QAASD,EACTG,MAAOD,EACPe,UAAW,CACTC,EAAG,YAAY,kBAAoB,mBAErCC,qBAAsB,GACtB1F,SAAU,CACR2F,iBAAkB,GAClBC,aAAc,aACdC,aAAc,QACd5F,mBAAmB,EACnB6F,aAAc,CACZC,MAAO,CACLC,UAAU,EACVC,SAAS,EACTC,QAAQ,EACRC,UAAU,GAEZC,MAAO,CACLJ,UAAU,EACVC,SAAS,EACTC,QAAQ,EACRC,UAAU,GAEZE,KAAM,CACJL,UAAU,EACVC,SAAS,EACTC,QAAQ,EACRC,UAAU,IAGdG,gBAAiB,CACfb,EAAG,uBACHc,cAAe,QACfC,OAAQ,CACNC,qBAAqB,EACrBC,oBAAoB,GAEtBC,eAAgB,QAChBC,eAAgB,SAChBC,wBAAyB,KAE3BC,SAAU,CACRC,MAAM,EACNC,QAAQ,GAEVC,SAAU,CACRC,SAAS,EACTC,MAAM,GAERC,MAAO,CACLF,SAAS,EACTG,KAAK,GAEPC,OAAQ,CAAC,CACPC,KAAM,MACNC,WAAY,CACVC,MAAM,EACNC,KAAM,UACNC,MAAO,kCACPC,mBAAoB,yCACpBC,UAAW,GACX7I,GAAI,MAEL,CACDuI,KAAM,QACNC,WAAY,CACVC,MAAM,EACNC,KAAM,UAENC,MAAO,kCACPC,mBAAoB,+CACpBC,WAAY,GACZ7I,GAAI,QAGR8I,MAAO,SACPC,cAAe,CACbC,OAAO,GAETC,YC9MO,IAAI9C,MAAO+C,iBAAiBC,MAAM,aAAe,MAAQ,ODgNlEC,YAAY,EACZC,6BAA6B,EAC7BC,QAAS,YAAe,IACxBC,eAAgB,IAGZC,EAAWC,OAAOC,KAAK/D,GAEvBgE,EAAe,CAAC,eAAgB,mBACpC,eAAgB,UAAW,YAMtB,MAAM,UAAwB,IA8BnC,cACEC,QAxBM,KAAAC,IAAM,OAAAC,EAAA,GAAO,SAIb,KAAAC,YAAwC,IAAI9L,IAC5C,KAAA+L,cAAqC,IAAI/L,IAE1C,KAAAgM,SAAW,CAChBC,MAAO,IAAI,IAAwD,IAAgB,SACnFC,MAAO,IAAI,IAAwD,IAAgB,SACnFC,QAAS,IAAI,IAA0D,IAAgB,YAGlF,KAAAC,gBAIH,GAEG,KAAAC,QAAUC,EAAA,EAMfC,KAAKC,iBAELC,EAAA,QAAUrI,iBAAiB,YAAa,KACtCmI,KAAKG,kBAAkBD,EAAA,QAAUE,KAAM,UAIpC,iBACL,OAAGJ,KAAKK,SACRC,QAAQC,KAAK,cACbP,KAAKK,OAAS,IAAIG,QAASxM,IACzB,MAAMyM,EAAexB,OAAOC,KAAKc,KAAKP,UAChCiB,EAAmCD,EAAaE,IAAIxN,GAAO6M,KAAKP,SAAStM,GAAKyN,UAE9EC,EAAiC7B,EAAS2B,IAAIxN,GAAO4M,EAAA,EAAanM,IAAIT,IAC3E2N,OAAOC,EAAA,EAAenN,IAAI,aAAcmN,EAAA,EAAenN,IAAI,aAC3DkN,OAAOf,EAAA,EAAanM,IAAI,cACxBkN,OAAOJ,GAERF,QAAQQ,IAAIH,GAAUzM,KAAW6M,GAAQ,EAAD,gCAiCtC,IAAIC,EAAelB,KAAKkB,MAAQ,GAGhC,IAAI,IAAIrG,EAAI,EAAGC,EAASkE,EAASlE,OAAQD,EAAIC,IAAUD,EAAG,CACxD,MAAM1H,EAAM6L,EAASnE,GACfsG,EAAQF,EAAIpG,QACLpF,IAAV0L,EAEDD,EAAM/N,GAAOgO,EAEbnB,KAAKoB,YAAYjO,EAAK,OAAAkO,EAAA,GAAKlG,EAAWhI,KAI1C8N,EAAIK,OAAO,EAAGtC,EAASlE,QAGvB,IAAIyG,EAAON,EAAIO,QACf,MAAM1C,EAAUmC,EAAIO,QACdC,EAAkBR,EAAIO,QAC5B,IAAID,GAAQE,EAAiB,CAC3BF,EAAOE,EACP,MAAMvC,EAAiB,CAAC,KAAM,qBAAsB,eACpD,IAAI,IAAIrE,EAAI,EAAGA,GAAK,IAAKA,EACvBqE,EAAKwC,KAAK,KAAK7G,iBACfqE,EAAKwC,KAAK,KAAK7G,cAGjB,MAAM8G,QAAenB,QAAQQ,IAAI9B,EAAKyB,IAAIxN,GAAO4M,EAAA,EAAanM,IAAIT,KAClE+L,EAAKwC,KAAK,aACVC,EAAOD,KAAsB,iBAAX,GAAwC,iBAAX,EAAsB,CAACE,KAAMD,EAAO,IAAM,IAAIE,SAAUC,KAAMnG,KAAKC,MAAQ,IAAO,EAAGpG,GAAI+L,EAAKQ,UAAS,IAAsBR,GAE5K,IAAIS,EAAW,GACf9C,EAAK3L,QAAQ,CAACJ,EAAK8O,KACjBD,EAAI7O,GAAOwO,EAAOM,WAGdlB,EAAA,EAAe5M,IAAI6N,GA2BxBT,IAEDL,EAAMlF,UAAY,CAACC,EAAG,qBACtBiE,EAAA,QAAUgC,cAAc,YAA8B,iBAAX,GAAwC,iBAAX,EACtE,CAACN,KAAM,EAAGE,KAAMnG,KAAKC,MAAQ,IAAO,EAAGpG,GAAI+L,EAAKQ,UAAS,IACzDR,IAIJ,IAAI,IAAI1G,EAAI,EAAGC,EAAS2F,EAAa3F,OAAQD,EAAIC,IAAUD,EACzDmF,KAAKH,gBAAgBY,EAAa5F,IAAMoG,EAAIpG,GAK9C,GAFAoG,EAAIK,OAAO,EAAGb,EAAa3F,QAExBoG,EAAMpC,UAAYA,EAAS,CAC5B,QAAerJ,IAAZqJ,EAAuB,CACxB,MAAMqD,EAAiD,IAAI1O,IAAI,CAC7D,CAAC,iBAAagC,GACd,CAAC,eAAWA,KAGd0M,EAAS5O,QAAQ,CAAC0I,EAAG9I,KACnBgP,EAAShO,IAAIhB,EAAK,OAAAkO,EAAA,GAAKH,EAAM/N,OAG/B+N,EAAQlB,KAAKkB,MAAQ,OAAAG,EAAA,GAAKlG,GAE1BgH,EAAS5O,QAAQ,CAAC4N,EAAOhO,KAEvB+N,EAAM/N,GAAOgO,IAGf,IAAI,MAAMhO,KAAO6M,KAAKH,gBACpBG,KAAKH,gBAAgB1M,GAAiD2H,OAAS,EAGjFkF,KAAKF,QAAQ3L,IAAI+M,SAGbH,EAAA,EAAe5M,IAAI,CACvBiO,SAAUlB,EAAMpC,UAIpB,MAAMyB,EAAO5E,KAAKC,MAClB,GAAIsF,EAAMxF,iBA5YI,MA4YgC6E,EAAM,CAC/C,KACDP,KAAKX,IAAI,qBAAsB6B,EAAMxF,iBAAkB6E,GAG/C,CAACrB,IACTA,EAAK3L,QAAQJ,IACX6M,KAAKoB,YAAYjO,EAAK,OAAAkO,EAAA,GAAKlG,EAAWhI,KAGtC,MAAMkP,EAAIrC,KAAKH,gBAAgB1M,GAC5BkP,GAAKA,EAAEvH,SACRuH,EAAEvH,OAAS,MAKjBwH,CAAEnD,GAoBJ,IANI+B,EAAM1K,SAAS+L,eAAe,UAAYrB,EAAM1K,SAAS+L,eAAe,gBAC1ErB,EAAM1K,SAAS8H,MAAQ4C,EAAM1K,SAASgM,WAAa,QAAU,MAC7DxC,KAAKoB,YAAY,WAAYF,EAAM1K,YAIjC0K,EAAM1K,SAAS+L,eAAe,WAAarB,EAAM1K,SAASwH,WAAY,CACxEkD,EAAM1K,SAASsH,OAAS,OAAAuD,EAAA,GAAKlG,EAAW3E,SAASsH,QACjD,MAAMQ,EAAQ4C,EAAM1K,SAASsH,OAAO2E,KAAKC,GAAKA,EAAE3E,OAASmD,EAAM1K,SAAS8H,OACrEA,IACDA,EAAMN,WAAakD,EAAM1K,SAASwH,WAClCgC,KAAKoB,YAAY,WAAYF,EAAM1K,WAKvC,MAAMmM,EAAuBzB,EAAM1K,SAAS8F,aAC5C,QAAqC7G,KAAlCkN,aAAoB,EAApBA,EAAsBlG,SAAuB,CAC9C,MAAMmG,EAAW,CACf,WACA,UACA,SACA,YAGiB,CACjB,QACA,QACA,QAGSrP,QAAQsP,IACjB,MAAMC,EAAiDH,EAAqBE,GAAa,GACzFD,EAASrP,QAAQwP,IACfD,EAAiBC,GAAYJ,EAAqBI,OAItDH,EAASrP,QAAQwP,WACRJ,EAAqBI,KAG9B/C,KAAKoB,YAAY,WAAYF,EAAM1K,UAQrC,GALA,OAAAwB,EAAA,GAAmBmD,EAAY+F,EAAQ8B,IAErChD,KAAKoB,YAAY4B,EAAY9B,EAAM8B,MAGlC9B,EAAMlG,UAAYD,GAAiBmG,EAAMhG,QAAUD,EAAqB,CAEzE,IAA+C,IAA5CT,EAAe0G,EAAMlG,QAAS,SAAiB,CAChDgF,KAAKkB,MAAM9F,iBAAmB,OAAAiG,EAAA,GAAKlG,EAAWC,kBAC9C4E,KAAKkB,MAAM1F,QAAU,OAAA6F,EAAA,GAAKlG,EAAWK,SACrC,MAAMyH,EAASjD,KAAKH,gBAAgBD,SACjCqD,aAAM,EAANA,EAAQnI,UACTmI,EAAOnI,OAAS,GAKpB,IAA+C,IAA5CN,EAAe0G,EAAMlG,QAAS,SAAiB,CAChD,IAAIkI,GAAW,EACfhC,EAAM1K,SAASsH,OAAOvK,QAAQ,CAAC+K,EAAO2D,EAAKhB,KACzC,GACiB,QAAf3C,EAAMP,MACoB,gCAA1BO,EAAMN,WAAWE,MACS,UAA1BI,EAAMN,WAAWhF,MAEF,UAAfsF,EAAMP,MACqB,YAA3BO,EAAMN,WAAWG,OACS,UAA1BG,EAAMN,WAAWhF,KAChB,CACD,MAAMmK,EAAWhI,EAAW3E,SAASsH,OAAO2E,KAAKU,GAAYA,EAASpF,OAASO,EAAMP,MAClFoF,IACDlC,EAAIgB,GAAO,OAAAZ,EAAA,GAAK8B,GAChBD,GAAW,MAKdA,GACDlD,KAAKoB,YAAY,WAAYF,EAAM1K,UAIa,IAAjDgE,EAAe0G,EAAMlG,QAASD,KAC/BiF,KAAKoD,WAAarI,GAGpBiF,KAAKoB,YAAY,UAAWrG,GAC5BiF,KAAKoB,YAAY,QAASnG,GAI5BiF,EAAA,QAAU1J,SAAW0K,EAAM1K,SAExB,KACDwJ,KAAKX,IAAI,YAAa6B,EAAO,OAAAG,EAAA,GAAKH,IAKpCZ,QAAQ+C,QAAQ,cAChBrP,EAAQkN,OACPoC,MAAMtP,MAnSYgM,KAAKK,OAySvB,WACL,YAAsB5K,IAAfuK,KAAKkB,MAAsBlB,KAAKC,iBAAmBO,QAAQxM,QAAQgM,KAAKkB,OAG1E,SAAS/N,EAAagO,IE3jBhB,SAAyBjO,EAAaC,EAAagO,GAChE,MAAM/N,EAAWD,EAAIE,MAAM,KAC3B,OAAAJ,EAAA,GAAgBC,EAAQE,EAASmQ,MAAM,GAAI,GAAGC,KAAK,MAAMpQ,EAASqQ,OAAStC,EF0jBzEuC,CAAgB1D,KAAKkB,MAAO/N,EAAKgO,GACjCjB,EAAA,QAAUgC,cAAc,mBAAoB,CAAC/O,MAAKgO,UAElD,MAAMwC,EAAQxQ,EAAIE,MAAM,KAAK,GAE7B2M,KAAKoB,YAAYuC,EAAO3D,KAAKkB,MAAMyC,IAG9B,YAAmCxQ,EAAQgO,EAAiByC,GAAS,GACvEA,IACD5D,KAAKkB,MAAM/N,GAAOgO,GAGpBnB,KAAK6D,qBAAqB1Q,EAAKgO,GAG1B,qBAA4ChO,EAAQgO,EAAkBnB,KAAKkB,MAAM/N,IACtF6M,KAAKF,QAAQ3L,IAAI,CACf,CAAChB,GAAMgO,IAIJ,YAAY2C,EAAgB9K,EAAqB+K,GACtD,IAAI5P,EAAM6L,KAAKT,YAAY3L,IAAIkQ,GAC5B3P,GAAOA,EAAI6P,IAAIhL,KAId7E,IACFA,EAAM,IAAI8P,IACVjE,KAAKT,YAAYpL,IAAI2P,EAAQ3P,IAG/BA,EAAIwD,IAAIqB,GAERgH,KAAKkC,cAAc,aAAc4B,QAEpBrO,IAAVsO,GACD/D,KAAKkE,eAAeJ,EAAQ9K,IAIzB,kBAAkB8K,EAAgB9K,EAAqBmL,EAA2BL,GACvF,OAAO9D,KAAKoE,YAAYN,EAAQ9K,EAAO,IAAMmL,EAAyB,GAGjE,kBAAkBL,EAAgB9K,GACvC,OAAOgH,KAAKkE,eAAe,IAAclL,EAAO,IAAM8K,GAGjD,aAAaA,GAClB,OAAO9D,KAAKT,YAAYyE,IAAIF,GAGvB,eAAeA,EAAgB9K,GACpC,MAAMqL,EAAerE,KAAKR,cAAc5L,IAAIoF,GAC5C,GAAGqL,GAAgBA,IAAiBP,GAAU9D,KAAKT,YAAYyE,IAAIK,GAAe,CAChF,MAAMlQ,EAAM6L,KAAKT,YAAY3L,IAAIyQ,GACjClQ,EAAIE,OAAO2E,GAEP7E,EAAImQ,OACNtE,KAAKT,YAAYlL,OAAOgQ,GACxBrE,KAAKkC,cAAc,eAAgBmC,IAIpCP,EACD9D,KAAKR,cAAcrL,IAAI6E,EAAM8K,GAE7B9D,KAAKR,cAAcnL,OAAO2E,IAtZhB,EAAAmC,WAAaA,EAua7B,MAAMoJ,EAAkB,IAAI,EAC5B,IAAeA,gBAAkBA,EAClB,a,8EG5oBf,IAAIC,EACJ,GAAI,YAEF,IAEEA,GADcC,UAAUC,UAAU/F,MAAM,mBACT,IAAM,GACrC,MAAMgG,GACNH,GAAwB,OANbA,GAAwB,EAUxB,Q,uUC0Df,MAAMI,EAAQ,IA5Cd,MAGE,cACE5E,KAAK4E,MAAQ,IAAInR,IAGZ,SAASsK,GACd,IAAI6G,EAAQ5E,KAAK4E,MAAMhR,IAAImK,GAQ3B,OAPI6G,GACF5E,KAAK4E,MAAMzQ,IAAI4J,EAAM6G,EAAQ,CAACC,OAAQ,IAAIpR,IAAOqR,QAAS,MAK1DF,EAAME,QACDF,EAAMC,OAGR,aAAa9G,GAClB,MAAM6G,EAAQ5E,KAAK4E,MAAMhR,IAAImK,GAC1B6G,MAAYA,EAAME,SACnB9E,KAAK4E,MAAMvQ,OAAO0J,GAKf,gBAAgBA,GACrB,MAAM6G,EAAQ5E,KAAK4E,MAAMhR,IAAImK,GAC7B,OAAO6G,aAAK,EAALA,EAAOE,QAGT,aAAa/G,EAAcvF,EAAeuM,EAAgB5G,EAAqB6G,GACpF,MAAO,CACLjH,EACAvF,EACAuM,EAEA5G,EAAQ,UAAY,GACpB6G,GAAa,IACbpM,OAAOqM,SAASzB,KAAK,OAQZ,MAAM,UAAsB,IA8DzC,aAAY,GAAC9N,EAAE,OAAEwP,EAAM,QAAEC,IAKvB/F,OAAM,GA3DD,KAAAgG,MAAQ,EAWP,KAAA5M,MAAQ,EACR,KAAAuM,OAAS,EAMV,KAAAM,QAAS,EAET,KAAAC,UAAY,EACX,KAAAC,MAAQ,EACT,KAAAC,UAAW,EAEX,KAAA7H,MAAO,EAEN,KAAA8H,MAAQ,GAYR,KAAAC,aAAe,EAuBrB1F,KAAKoF,QAAU,EAAqB,MACpCpF,KAAKtK,GAAKA,EACVsK,KAAKkF,OAASA,EAEd,IAAI,IAAIrK,KAAKsK,EACRnF,KAAKuC,eAAe1H,KAErBmF,KAAKnF,GAAKsK,EAAQtK,IAgBtB,IAAI8K,EAZJ3F,KAAK4F,MAAQ5F,KAAKrC,KAClBqC,KAAK6F,UAAY7F,KAAKwF,SAGtBxF,KAAK8F,UAAYX,EAAQW,UACzB9F,KAAK7B,MAAQgH,EAAQhH,MACrB6B,KAAK+F,aAAeZ,EAAQY,aAC5B/F,KAAKjC,KAAOoH,EAAQpH,KACpBiC,KAAKgG,wBAA0Bb,EAAQa,wBACvChG,KAAKgF,UAAYG,EAAQH,eAIAvP,IAAtB0P,EAAQQ,UAAyBA,EAAYR,EAAQQ,WAC/C,cAAc,mBAAoB,aAAa,cAAe3F,KAAKxH,MAAQ,KAAOwH,KAAK+E,OAAS,MAAQI,EAAQc,cACvHN,EAAY,IAGd3F,KAAKkG,eAA0BzQ,IAAdkQ,EAA0B,EAAIA,EAAY,EAAI,EAM/D,MAAMQ,EAAa,OAAAtT,EAAA,GAAMsH,OAAOiM,iBAAkB,EAAG,GAClDD,EAAa,IAEXhB,EAAQc,aACTjG,KAAKxH,MAAQ6N,KAAKC,MAAMtG,KAAKxH,MAAQ2N,GACrCnG,KAAK+E,OAASsB,KAAKC,MAAMtG,KAAK+E,OAASoB,IAC/BA,EAAa,IAClBnG,KAAKxH,MAAQ,KAAOwH,KAAK+E,OAAS,IAChC,aAAawB,EAAA,EAAWC,UAGzBxG,KAAKxH,MAAQ6N,KAAKC,MAAMtG,KAAKxH,MAAQ2N,GACrCnG,KAAK+E,OAASsB,KAAKC,MAAMtG,KAAK+E,OAASoB,IAC/BA,EAAa,MACrBnG,KAAKxH,MAAQ6N,KAAKC,MAAMtG,KAAKxH,OAAS2N,EAAa,MACnDnG,KAAK+E,OAASsB,KAAKC,MAAMtG,KAAK+E,QAAUoB,EAAa,QAGvDnG,KAAKxH,MAAQ6N,KAAKC,MAAMtG,KAAKxH,MAAQ6N,KAAKrT,IAAI,IAAKmT,EAAa,MAChEnG,KAAK+E,OAASsB,KAAKC,MAAMtG,KAAK+E,OAASsB,KAAKrT,IAAI,IAAKmT,EAAa,SAQpEhB,EAAQsB,UAEP,YAAYzG,KAAKxH,MAAQ,KAAOwH,KAAK+E,OAAS,IAC/C/E,KAAK0F,aAAe,EACZ1F,KAAKxH,MAAQ,KAAOwH,KAAK+E,OAAS,IAC1C/E,KAAK0F,aAAegB,IAEpB1G,KAAK0F,aAAe,GAapB1F,KAAK2G,SACP3G,KAAK2G,OAASC,SAASC,cAAc,UACrC7G,KAAK2G,OAAOhQ,UAAUgB,IAAI,WAC1BqI,KAAK2G,OAAOnO,MAAQwH,KAAKxH,MACzBwH,KAAK2G,OAAO5B,OAAS/E,KAAK+E,QAG5B/E,KAAK8G,QAAU9G,KAAK2G,OAAOI,WAAW,MAEnC,IACD/G,KAAKgH,QAAU,IAAIC,kBAAkBjH,KAAKxH,MAAQwH,KAAK+E,OAAS,IAGlE/E,KAAKkH,UAAY,IAAIC,UAAUnH,KAAKxH,MAAOwH,KAAK+E,QAE7C/E,KAAKjC,MACNiC,KAAKoH,UAAYxC,EAAMyC,aAAarH,KAAKjC,KAAMiC,KAAKxH,MAAOwH,KAAK+E,OAAQ/E,KAAK7B,MAAO6B,KAAKgF,WACzFhF,KAAK6E,OAASD,EAAM0C,SAAStH,KAAKoH,YAElCpH,KAAK6E,OAAS,IAAIpR,IAIf,aACFuM,KAAK0F,eAAiBgB,MAItB1G,KAAKoH,WAAaxC,EAAM2C,gBAAgBvH,KAAKoH,WAAa,GAI7DpH,KAAK6E,OAAOhL,SAGP,UAAU2N,KAAuBjS,GAEtCyK,KAAKkF,OAAOuC,UAAUD,EAAYxH,KAAKoF,SAAU7P,GAG5C,aAAamS,GAClB1H,KAAKyH,UAAU,eAAgBC,EAAM1H,KAAKxH,MAAOwH,KAAK+E,OAAQ/E,KAAKgF,WAG9D,OACDhF,KAAKqF,SAQTrF,KAAKqF,QAAS,EACdrF,KAAK2H,eAGA,MAAMC,GAAkB,GAC1B5H,KAAKqF,SAIRrF,KAAKqF,QAAS,EACXuC,GACD1N,aAAa8F,KAAK6H,QAKd,oB,MACN,OAAO7H,KAAK8H,SAAyB,QAAd,EAAA9H,KAAK8F,iBAAS,QAAwB,IAAnB9F,KAAKsF,UAAkBtF,KAAK+H,SAAW/H,KAAKgI,SAGjF,KAAKC,GAAmB,GAC7BjI,KAAKkI,QAEL,MAAMJ,EAAW9H,KAAKmI,oBACnBF,GACDjI,KAAKoI,aAAaN,GAKf,UACL9H,KAAKqI,MAAK,GACVrI,KAAKsI,OAGA,SAAS/C,GACXvF,KAAKuF,QAAUA,IAIlBvF,KAAKuF,MAAQA,EAETvF,KAAKqF,QACPrF,KAAK2H,eAIF,aAAarC,GACftF,KAAKsF,YAAcA,IAItBtF,KAAKsF,UAAYA,EAEbtF,KAAKqF,QACPrF,KAAK2H,eAIF,SAELY,EAAA,EAAaC,UAAUxI,KAAKoF,OAC5BpF,KAAKkI,QACLlI,KAAKyH,UAAU,WACZzH,KAAKoH,WAAWxC,EAAM6D,aAAazI,KAAKoH,WAC3CpH,KAAK0I,UAIC,WAAWC,GACjB,MAAOrG,EAAGsG,EAAGC,GAAK7I,KAAK7B,MACvB,IAAI,IAAItD,EAAI,EAAGC,EAAS6N,EAAM7N,OAAQD,EAAIC,EAAQD,GAAK,EACjC,IAAjB8N,EAAM9N,EAAI,KACX8N,EAAM9N,GAAKyH,EACXqG,EAAM9N,EAAI,GAAK+N,EACfD,EAAM9N,EAAI,GAAKgO,GAKb,eAAeF,GACrB,MAAOrG,EAAGsG,EAAGC,GAAK7I,KAAK+F,aACvB,IAAI,IAAIlL,EAAI,EAAGC,EAAS6N,EAAM7N,OAAQD,EAAIC,EAAQD,GAAK,EACjC,IAAjB8N,EAAM9N,EAAI,IACX8N,EAAM9N,GAAKyH,EACXqG,EAAM9N,EAAI,GAAK+N,EACfD,EAAM9N,EAAI,GAAKgO,EACfF,EAAM9N,EAAI,GAAK,KAEf8N,EAAM9N,EAAI,GAAK,EAKd,aAAa8N,EAA0BG,GAI5C,IACK9I,KAAK7B,OACN6B,KAAK+I,WAAWJ,GAGf3I,KAAK+F,cACN/F,KAAKgJ,eAAeL,GAGtB3I,KAAKkH,UAAUQ,KAAKvT,IAAIwU,GAIxB3I,KAAK8G,QAAQmC,aAAajJ,KAAKkH,UAAW,EAAG,GAE7C,MAAMvC,GAIN,OAHArE,QAAQ4I,MAAM,mCAAoCvE,EAAkB3E,KAAKxH,MAAOwH,KAAK+E,QACrF/E,KAAKwF,UAAW,OAChBxF,KAAKkI,QAKPlI,KAAKkC,cAAc,aAAc4G,GAG5B,YAAYH,EAA0BG,GAe3C,GAbG9I,KAAK0F,eAAiBoD,EAAU9I,KAAK0F,eAAiBoD,KAAa9I,KAAK6E,OAAOb,IAAI8E,IACpF9I,KAAK6E,OAAO1Q,IAAI2U,EAAS,IAAI7B,kBAAkB0B,IAY9C3I,KAAKmJ,WAAY,CAClB,MAAwBC,EAAZzN,KAAKC,MAAqBoE,KAAKqJ,OAG3C,GAAGD,EAAQ,EAET,OADGpJ,KAAK6H,OAAO3N,aAAa8F,KAAK6H,OAC1B7H,KAAK6H,MAAQ1N,OAAOC,WAAW,KACpC4F,KAAKsJ,aAAaX,EAAOG,IACxB9I,KAAKmJ,YAAcC,GAASA,EAAQpJ,KAAKmJ,WAAanJ,KAAKmJ,YAKlEnJ,KAAKsJ,aAAaX,EAAOG,GAGpB,aAAaA,GAClB,MAAMH,EAAQ3I,KAAK6E,OAAOjR,IAAIkV,GAC3BH,EACD3I,KAAKuJ,YAAYZ,EAAOG,IAErB9I,KAAKgH,UAAYhH,KAAKgH,QAAQlM,SAC/BkF,KAAKgH,QAAU,IAAIC,kBAAkBjH,KAAKxH,MAAQwH,KAAK+E,OAAS,IAGlE/E,KAAKyH,UAAU,cAAeqB,EAAS9I,KAAKgH,UAIxC,QAGN,QAAIhH,KAAKrC,OACPqC,KAAKkI,OAAM,IACJ,GAMH,mBACN,MAAM,UAAChC,EAAS,SAAE8B,GAAYhI,KACxB2I,EAAS3I,KAAK8H,SAAW5B,EAAa8B,EAAWhI,KAAK8H,SAAY9H,KAAKrC,KAAOqC,KAAK+H,SAAW/H,KAAKgI,SAAYhI,KAAK8H,UAAY5B,EAItI,OADAlG,KAAKoI,aAAaO,KACdA,EAAQzC,EAAa8B,IAChBhI,KAAKwJ,QAMR,oBACN,MAAM,UAACtD,EAAS,SAAE6B,GAAY/H,KACxB2I,EAAS3I,KAAK8H,SAAW5B,EAAa6B,EAAW/H,KAAK8H,SAAY9H,KAAKrC,KAAOqC,KAAKgI,SAAWhI,KAAK+H,SAAY/H,KAAK8H,UAAY5B,EAItI,OADAlG,KAAKoI,aAAaO,KACdA,EAAQzC,EAAa6B,IAChB/H,KAAKwJ,QAMT,cAELtP,aAAa8F,KAAK6H,OAElB7H,KAAKmJ,WAAa,IAAOnJ,KAAKyJ,IAAMzJ,KAAKuF,MAAQvF,KAAKkG,UACtDlG,KAAKqJ,OAAS1N,KAAKC,MAAQoE,KAAKmJ,WAIhC,MAAMO,GAA6B,IAAnB1J,KAAKsF,UAAkBtF,KAAK2J,iBAAmB3J,KAAK4J,mBAAmBC,KAAK7J,MAQ5F,GAPAA,KAAK8J,cAAgBJ,EAOlB1J,KAAK+J,cAAe,MAEHtU,IADCuK,KAAKgK,gBAAgBC,YAEtCjK,KAAK+J,cAAc/J,KAAK8H,WASvB,SAAS3C,GAKdnF,KAAKkI,QAEL,MAAM,KAAC1O,EAAI,GAAEQ,EAAE,SAAEL,GAAYwL,EAG7B,OAFAnF,KAAK8H,SAAWtO,EAAO,EAEhBwG,KAAKkK,YAAY,CACtBvB,MAAO3O,EACPsL,UAAWtL,EAAKR,EAAO,GAAK,EAC5BG,aAIG,YAAYwL,GAMjBnF,KAAKkI,QAEL,MAAM,MAACS,EAAK,MAAEpD,EAAK,SAAE5L,EAAQ,UAAE2L,GAAaH,EAC5CnF,KAAKmK,kBAA2B1U,IAAd6P,EAA0BtF,KAAK8H,SAAWa,GAAS,EAAI,EAAIrD,QACnE7P,IAAV8P,GAAuBvF,KAAKoK,SAAS7E,GAErC,MAAM8E,EAAS,CAACrK,KAAK8H,SAAUa,IACR,IAApB3I,KAAKsF,WAAkB+E,EAAO1R,UAEjCqH,KAAKrC,MAAO,EACZqC,KAAKsK,UAAUD,EAAO,GAAIA,EAAO,IAE9BrK,KAAKuK,4BACNvK,KAAKpG,oBAAoB,aAAcoG,KAAKuK,4BAG3C5Q,IACDqG,KAAKuK,2BAA8BzB,IAC9BA,IAAYH,IACb3I,KAAKpG,oBAAoB,aAAcoG,KAAKuK,4BAC5C5Q,MAIJqG,KAAKnI,iBAAiB,aAAcmI,KAAKuK,6BAG3CvK,KAAKsI,OAGA,SAASnK,EAAqBqM,GACnCxK,KAAK7B,MAAQA,EAEVqM,GAAkBxK,KAAKqF,QACxBrF,KAAKsJ,aAAatJ,KAAKkH,UAAUQ,KAAM1H,KAAK8H,UAIzC,gBAAgB3J,GACrB6B,KAAK+F,aAAe5H,EAGd,UAAU4J,EAAW,EAAGC,EAAWhI,KAAKyK,WAAa,GAC3DzK,KAAK+H,SAAWA,EAChB/H,KAAKgI,SAAWA,EAGL,OAAOyC,EAAoBhB,G,yCACtCzJ,KAAKyK,WAAaA,EAClBzK,KAAKyJ,IAAMA,EACXzJ,KAAKsK,iBACiB7U,IAAnBuK,KAAK8F,YACN9F,KAAK8F,UAAY,OAAAjT,EAAA,GAAMmN,KAAK8F,UAAW9F,KAAK+H,SAAU/H,KAAKgI,WAG7D,MAAMF,EAAW9H,KAAKmI,oBAGtB,GAAGnI,KAAKyJ,IAAM,IAAyB,IAAnBzJ,KAAKkG,UAAiB,CACxC,MAAMwE,EAAO,GAAKjB,EAClBzJ,KAAKkG,UAAYlG,KAAKkG,UAAYwE,EAAO,EAG3C1K,KAAKmJ,WAAa,IAAOnJ,KAAKyJ,IAAMzJ,KAAKuF,MAAQvF,KAAKkG,UACtDlG,KAAKqJ,OAAS1N,KAAKC,MAAQoE,KAAKmJ,YAyB/BnJ,KAAKgG,yBAA2BhG,KAAKoI,aAAaN,GACnD9H,KAAKkC,cAAc,SACnBlC,KAAKnI,iBAAiB,aAAc,KAClCmI,KAAKkC,cAAc,eAEflC,KAAK2G,OAAOgE,YAAc3K,KAAKtK,IACjCsK,KAAKtK,GAAGkV,YAAY5K,KAAK2G,QAM3B3G,KAAK+J,cAAgB,KACnB,GAAG/J,KAAKqF,OACN,OAGF,MAAM9E,EAAO5E,KAAKC,MAQlBoE,KAAKqJ,OAAS9I,EAAOP,KAAKmJ,WACNnJ,KAAK8J,iBACL9J,KAAKrC,OAAQqC,KAAKwF,WACpCxF,KAAKwF,UAAW,IAIpBxF,KAAKnI,iBAAiB,aAAcmI,KAAK+J,eAGvB,SAAf/J,KAAKyF,OAAoBzF,KAAKwF,UAC/BxF,KAAKsI,QAEN,CAAClP,MAAM,QAtkBG,EAAAgM,MAAQ,G,gCC/DzB,IAAIyF,EACG,SAASC,EAAQnR,GAClBkR,EASFA,EAAiBnJ,KAAK/H,IARtBkR,EAAmB,CAAClR,GAEpBjC,sBAAsB,KACpB,MAAMqT,EAAmBF,EACzBA,OAAmBpV,EACnBsV,EAAiBxX,QAASyX,GAAOA,QAlCvC,wIAyCA,IAAIC,EAqBAC,EArBgEC,GAAa,EAC1E,SAASC,EAAoBzR,GAC9BsR,EAYME,EACRxR,IAEAsR,EAA6BvJ,KAAK/H,IAdlCsR,EAA+B,CAACtR,GAEhCjC,sBAAsB,KACpByT,GAAa,EACb,IAAI,IAAItQ,EAAI,EAAGA,EAAIoQ,EAA6BnQ,SAAUD,EACxDoQ,EAA6BpQ,KAG/BoQ,OAA+BxV,EAC/B0V,GAAa,KAUZ,SAASE,IACd,OAAGH,IAEHA,EAAa,IAAI1K,QAAQ9I,uBACzBwT,EAAW9W,KAAK,KACd8W,OAAazV,IAGRyV,GAGF,SAASI,IACd,OAAO,IAAI9K,QAAexM,IACxB8W,EAAQ,KACNA,EAAQ9W,S,gCC7EC,SAASuX,IACtB,OAAO,IAAIC,OAAO,IAA0B,wD,oECQ/B,MAAM,UAAwB,IAO3C,YAAoBtG,GAClB9F,QADkB,KAAA8F,SAGlBlF,KAAKkF,OAAOuG,QAAWvC,IACrB,IACElJ,KAAKkC,cAAc,cAAegH,GAClClJ,KAAK0I,UACL1I,KAAK0L,YACL,MAAM/G,MAKV3E,KAAKkF,OAAOyG,UAAaC,IACvB5L,KAAKkC,cAAc0J,EAAMlE,KAAKmE,uBAAwBD,EAAMlE,KAAKoE,uBAI9D,YAAYC,GACjB/L,KAAKkF,OAAO8G,YAAYD,GAGnB,YACL/L,KAAKkF,OAAOwG,YAGP,UAAUO,KAAwB1W,GACvC,GAAG,YACDyK,KAAKkF,OAAO8G,YAAY,CACtBC,YAAaA,EACbH,qBAAsBvW,QAEnB,CACL,MAAM2W,EAA8C,GACpD3W,EAAKhC,QAAQ4Y,IACRA,aAAeC,aAChBF,EAASxK,KAAKyK,GAGG,iBAAV,GAAsBA,EAAIE,kBAAkBD,aACnDF,EAASxK,KAAKyK,EAAIE,UAKtBrM,KAAKkF,OAAO8G,YAAY,CACtBC,YAAaA,EACbH,qBAAsBvW,GACrB2W,K,kTC6KT,MAAM3D,EAAe,IAvNd,MAAP,cACU,KAAA+D,uBAAiD,oBAAlB,YAC/B,KAAAC,YAA8BvM,KAAKsM,4BAA4C7W,EAAnB+K,QAAQgM,SACpE,KAAAnM,QAAS,EAET,KAAAoM,aAAe,EACf,KAAAC,QAA4C,GAE5C,KAAAC,QAA6B,GAC7B,KAAAC,aAAe,EAEf,KAAAvN,IAAM,OAAAC,EAAA,GAAO,SAAU,IAASuN,OAqIhC,KAAAC,eAAiB,CAAC1H,EAAeqF,EAAoBhB,KAC3D,MAAMsD,EAAW/M,KAAK0M,QAAQtH,GAC1B2H,GAKJ/M,KAAKX,IAAI2N,MAAM,kBACfD,EAASE,OAAOxC,EAAYhB,IAL1BzJ,KAAKX,IAAI6N,KAAK,sCAAuC9H,EAAOqF,IAWxD,KAAA0C,QAAU,CAAC/H,EAAe0D,EAAiBH,KACjD,MAAMoE,EAAW/M,KAAK0M,QAAQtH,GAC1B2H,QAKoBtX,IAArBsX,EAAS/F,UACV+F,EAAS/F,QAAU2B,GAGrBoE,EAASxD,YAAYZ,EAAOG,IAR1B9I,KAAKX,IAAI6N,KAAK,+BAAgC9H,EAAO0D,IAWjD,KAAAsE,cAAgB,CAAChI,EAAe8D,KACtC,MAAM6D,EAAW/M,KAAK0M,QAAQtH,GAC9B,GAAG2H,EAAU,CAEQM,EAAA,EAAqBC,cAAcP,EAASrX,IACpDnC,QAAQ0B,IACjBoY,EAAA,EAAqBE,eAAetY,GAAW,GAAM,OArKpD,aAAagB,GAClB,IAAI,MAAM4E,KAAKmF,KAAK0M,QAClB,GAAG1M,KAAK0M,QAAQ7R,GAAGnF,KAAOO,EACxB,OAAO+J,KAAK0M,QAAQ7R,GAIxB,OAAO,KAGF,QAAQ8C,GACb,IAAI,MAAM9C,KAAKmF,KAAK0M,QAAS,CAC3B,MAAMc,EAASxN,KAAK0M,QAAQ7R,GAC5B2S,EAAO7P,KAAOA,EACd6P,EAAOhI,SAAWgI,EAAO3H,WAItB,oBACL,OAAG7F,KAAKuM,YACCvM,KAAKuM,YAGPvM,KAAKuM,YAAc,IAAI/L,QAAQ,CAACxM,EAASwY,KAC9C,IAAIiB,EAASzN,KAAKyM,aAClB,IAAI,IAAI5R,EAAI,EAAGA,EAAImF,KAAKyM,eAAgB5R,EAAG,CACzC,MAAMqK,EAASlF,KAAK2M,QAAQ9R,GAAK,IAAI,EAAgB,IAAI,GAEzDqK,EAAOrN,iBAAiB,QAAS,KAC/BmI,KAAKX,IAAI,WAAaxE,EAAI,UAE1BqK,EAAOrN,iBAAiB,QAASmI,KAAKmN,SACtCjI,EAAOrN,iBAAiB,SAAUmI,KAAK8M,gBACvC5H,EAAOrN,iBAAiB,QAASmI,KAAKoN,iBAEpCK,EACEA,IACFzN,KAAKX,IAAI,iBACTrL,IACAgM,KAAKK,QAAS,IAEf,CAACjH,MAAM,IAEV8L,EAAOrN,iBAAiB,cAAgBqR,IACtCsD,EAAO,uBAAyBtD,EAAM6C,SACtC/L,KAAKK,QAAS,GACb,CAACjH,MAAM,OAKT,qBAAqBsU,EAAwD3P,GAElF,OADC2P,EAA0B3P,KAAOA,EAC3BiC,KAAK2N,qBAAqBD,EAAQ,cAAgB3P,EAAO,SAG3D,qBAAqB2P,EAA+CE,GACzE,OAAI5N,KAAKsM,wBAILtM,KAAKK,QACPL,KAAK6N,oBAGAC,MAAMF,GACZxZ,KAAK2Z,GACAA,EAAIC,SAA+C,6BAApCD,EAAIC,QAAQpa,IAAI,gBAG1Bma,EAAIE,OAFJF,EAAIG,cAAc9Z,KAAKsT,GAAQ,IAAWyG,aAAa,iBAAkBzG,IAAOtT,KAAK6M,GAAO,OAAAmN,EAAA,GAAc,CAACnN,GAAM,MAQ3H7M,KAAK6Z,IACJ,MAAMI,EAAYpP,OAAOqP,OAAOZ,EAAQ,CAACa,cAAeN,EAAMhI,aAAa,IAE3E,OADIoI,EAAUtQ,OAAMsQ,EAAUtQ,KAAO6P,GAC9B5N,KAAKwO,oBAAoBH,MArBzBrO,KAAKuM,YAyBT,kBAAkBiB,GACvB,OAAOhN,QAAQiO,KAAK,CAMlB,IAAIjO,QAAexM,IACjBwZ,EAAO3V,iBAAiB,aAAc7D,EAAS,CAACoF,MAAM,MAExD,OAAA8O,EAAA,GAAM,QACL9T,KAAK,IAAMoZ,GAGH,oBAAoBE,EAAwBjI,EAAQiI,EAAOjI,OAAS,GAAIiJ,G,yCACnF,IAAI1O,KAAKsM,uBACP,OAAOtM,KAAKuM,YAQd,GAJIvM,KAAKK,eACDL,KAAK6N,qBAGVa,IAAeA,IAChB,MAAM,IAAI7B,MAAM,cAQlB,GALIa,EAAOlV,OAAUkV,EAAO3I,SAC1B2I,EAAOlV,MAAQmW,SAASjB,EAAOkB,UAAUpX,MAAMgB,OAC/CkV,EAAO3I,OAAS4J,SAASjB,EAAOkB,UAAUpX,MAAMuN,UAG9C2I,EAAOlV,QAAUkV,EAAO3I,OAC1B,MAAM,IAAI8H,MAAM,wBAGlBa,EAAOjI,MAAQA,EAEf,MAAM+H,EAASxN,KAAK6O,WAAWnB,EAAOkB,UAAWlB,GAMjD,MAJa,SAAVjI,GACD4H,EAAA,EAAqByB,aAAatB,EAAQ/H,GAGrC+H,KA0CF,UAAUpI,UACRpF,KAAK0M,QAAQtH,GAGf,iBACLpF,KAAK2M,QAAQpZ,QAAQ,CAAC2R,EAAQjD,KAC5BiD,EAAOwG,YACP1L,KAAKX,IAAI,WAAa4C,EAAM,iBAG9BjC,KAAKX,IAAI,qBACTW,KAAK2M,QAAQ7R,OAAS,EAGhB,WAAWpF,EAAiByP,GAClC,MAAM4H,EAAW,IAAI,IAAc,CACjCrX,KACAwP,OAAQlF,KAAK2M,QAAQ3M,KAAK4M,gBAC1BzH,YAUF,OAPAnF,KAAK0M,QAAQK,EAAS3H,OAAS2H,EAC5B/M,KAAK4M,cAAgB5M,KAAK2M,QAAQ7R,SACnCkF,KAAK4M,aAAe,GAGtBG,EAASgC,aAAa5J,EAAQoJ,eAEvBxB,IAKX,IAAexE,aAAeA,EACf,O,gCC/OA,SAASyG,EAAoBC,EAAiBC,GAC3D,MAAMjN,EAAMgN,EAAME,QAAQD,GACpBE,GAAmB,IAATnN,GAAcgN,EAAM3N,OAAOW,EAAK,GAChD,OAAOmN,GAAWA,EAAQ,GAH5B,mC,gCCAA,4DA8NA,MAAM/B,EAAuB,IA1MtB,MAYL,cAVQ,KAAAgC,QAA8B,IAAIpL,IAGlC,KAAAqL,SAA+C,GAC/C,KAAAC,aAAwC,GACxC,KAAAC,qBAA+B,GAE/B,KAAAC,yBAAoD,GACpD,KAAAC,cAAe,EAGrB1P,KAAK2P,SAAW,IAAIC,qBAAsBC,IAGxC,IAAI,MAAMC,KAASD,EAAS,CAC1B,MAAMxa,EAASya,EAAMza,OAErB,IAAI,MAAMoQ,KAASzF,KAAKsP,SAAU,CAChC,GAAGtP,KAAKyP,yBAAyBhK,GAC/B,SAGF,MAAM+H,EAASxN,KAAKsP,SAAS7J,GAAOhD,KAAKsN,GAAKA,EAAEra,KAAOL,GACvD,GAAGmY,EAAQ,CACNsC,EAAME,gBACPhQ,KAAKqP,QAAQ1X,IAAI6V,GACjBxN,KAAKuN,eAAeC,GAAQ,KAE5BxN,KAAKqP,QAAQhb,OAAOmZ,GACpBxN,KAAKuN,eAAeC,GAAQ,GAEzBA,EAAOvY,qBAAqB,KAE7BuY,EAAOvY,UAAUgb,cAIrB,WAMRjQ,KAAKkQ,mBAAqB,IAAIjM,IAE9B,UAAUpM,iBAAiB,aAAc,EAAEsY,UACzB,UAAbA,EAAInX,OACLgH,KAAK0P,cAAe,EACpB1P,KAAKoQ,qBAIT,UAAUvY,iBAAiB,cAAe,KACrCmI,KAAK0P,eACN1P,KAAK0P,cAAe,EACpB1P,KAAKoQ,qBAKJ,qBAAqB3K,EAAe4K,GACtCA,EAAUrQ,KAAKkQ,mBAAmBvY,IAAI8N,GACpCzF,KAAKkQ,mBAAmB7b,OAAOoR,GAG/B,cAAcxP,GACnB,MAAMqa,EAAyB,GAC/B,IAAI,MAAM7K,KAASzF,KAAKsP,SACtB,IAAI,MAAM9B,KAAUxN,KAAKsP,SAAS7J,GAC7B+H,EAAO9X,KAAOO,GACfqa,EAAM5O,KAAK8L,GAKjB,OAAO8C,EAGF,gBAAgB9C,GAErB,MAAM,GAAC9X,EAAE,UAAET,GAAauY,EACxBvY,EAAU+B,SAEP/B,aAAqBsb,kBAAoB,aAC1CnW,WAAW,KACTnF,EAAUub,IAAM,GAChBvb,EAAUwb,QACT,KAGL,MAAMhL,EAAQzF,KAAKsP,SAAS9B,EAAO/H,OAChCA,IACD,YAAiBA,EAAO+H,GACpB/H,EAAM3K,eACDkF,KAAKsP,SAAS9B,EAAO/H,QAIhCzF,KAAK2P,SAASe,UAAUhb,GACxBsK,KAAKqP,QAAQhb,OAAOmZ,GAGf,aAAavY,EAA6CwQ,EAAQ,I,MACvE,MAAM+H,EAAS,CACb9X,GAAIT,aAAqB,IAAgBA,EAAUS,GAAKT,EACxDA,UAAWA,EACXwQ,SAGCxQ,aAAqB,MAClB,UAAUuB,SAASiH,SAASE,MAAQ1I,EAAU0I,OAChD1I,EAAU0I,KAAO,UAAUnH,SAASiH,SAASE,OAI5B,QAApB,EAAAqC,KAAKsP,SAAS7J,UAAM,QAAKzF,KAAKsP,SAAS7J,GAAS,IAAK/D,KAAK8L,GAC3DxN,KAAK2P,SAASgB,QAAQnD,EAAO9X,IAGxB,gBAAgBkb,EAAmBnL,EAAgBoL,GAAU,GAGlE,QAAapb,IAAVgQ,IAAwBzF,KAAKsP,SAAS7J,GAEvC,OAGF,MAAM/I,OAAmBjH,IAAVgQ,EAAqC,CAACA,GAASxG,OAAOC,KAAKc,KAAKsP,UAE/E,IAAI,MAAM7J,KAAS/I,EAAQ,CACzB,MAAMoU,EAAa9Q,KAAKsP,SAAS7J,GAEjC,YAAeqL,EAAatD,IAC1BxN,KAAKuN,eAAeC,EAAQoD,EAASC,MAKpC,eAAerD,EAAuBoD,GAAU,EAAOC,GAAU,GACtE,MAAM,GAACnb,EAAE,UAAET,EAAS,MAAEwQ,GAAS+H,EAE3BqD,IAAa,YAAQnb,KAAQsK,KAAKuP,aAAa9J,GACjDzF,KAAK+Q,gBAAgBvD,GAIpBoD,GAAY5Q,KAAKwP,sBAAwBxP,KAAKwP,uBAAyB/J,GAAWxQ,aAAqBsb,kBAAoBvQ,KAAK0P,aAC7Hza,EAAUoQ,QAEZpQ,EAAUiT,UAEJjT,EAAUoQ,QAClBrF,KAAKqP,QAAQrL,IAAIwJ,IACjBvY,EAAUuQ,WACRxF,KAAKwP,sBAAwBxP,KAAKwP,uBAAyB/J,GAC3D,UAAUuL,KAAKC,SAAUjR,KAAKkQ,mBAAmBlM,IAAIwJ,EAAO/H,QAG9DxQ,EAAUqT,OAIP,wBAAwB7C,GAC7BzF,KAAKwP,qBAAuB/J,EAGvB,UAAUA,GACfzF,KAAKuP,aAAa9J,IAAS,EAGtB,YAAYA,UACVzF,KAAKuP,aAAa9J,GACzBzF,KAAKoQ,qBAAgB3a,EAAWgQ,GAG3B,aAAaA,GAClB,MAAMqL,EAAa9Q,KAAKsP,SAAS7J,GAC9BqL,GAAcA,EAAWhW,SAC1BgW,EAAWvd,QAAQ0B,IACjB+K,KAAK2P,SAASe,UAAUzb,EAAUS,MAGpCyE,OAAOzC,sBAAsB,KAC3BoZ,EAAWvd,QAAQ0B,IACjB+K,KAAK2P,SAASgB,QAAQ1b,EAAUS,SAMjC,sBAAsB+P,GAC3BzF,KAAKyP,yBAAyBhK,IAAS,EAGlC,wBAAwBA,UACtBzF,KAAKyP,yBAAyBhK,GACrCzF,KAAKkR,aAAazL,KAKnB,MACD,IAAe4H,qBAAuBA,GAEzB,O,gCClOA,SAAS8D,EAAkBlC,EAAiBtV,GACzD,IAAI,IAA2BkB,EAAdoU,EAAMnU,OAAqB,EAAGD,GAAK,IAAKA,EACvDlB,EAASsV,EAAMpU,GAAIA,EAAGoU,GAF1B,mC,+GCkEA,MAAMmC,EAAe,IArDrB,MAQE,cAPQ,KAAAC,QAAU,EAQhBrR,KAAKsR,SAAW1K,SAAS2K,eAAe,cACxCvR,KAAKwR,cAAgBxR,KAAKsR,SAAS3b,cAAc,eACjDqK,KAAKjL,UAAY,OAAAP,EAAA,GAAe,KAAMwL,KAAKwR,cAAc7b,cAAc,mBAAsC,KAAM,K,OACrG,QAAT,EAAAqK,KAAKyR,YAAI,eAAEC,UACZ1R,KAAKyR,KAAKC,YAKT,QAAQD,GACb,GAAGA,EAAKE,WAAY,CAClB3R,KAAKsR,SAAS9Z,MAAMoa,QAAU,GAE9B,IAAIpc,EAAK,OAAAqc,EAAA,GAAWJ,EAAKK,QACzB,GAAG9R,KAAKqR,SAAW7b,EAAI,OAEvBwK,KAAKjL,UAAUS,IAEK,IAAjBwK,KAAKqR,QAAiB7b,EAAK,GAC5B+S,EAAA,EAAasF,oBAKf7N,KAAKqR,OAAS7b,EAEXwK,KAAKwR,eACN,OAAAO,EAAA,GAAiB,CACfnD,UAAW5O,KAAKwR,cAChBvb,QAAS+J,KAAKwR,cAAc5Z,kBAC5BzB,SAAU,eAId6J,KAAKsR,SAAS9Z,MAAMoa,QAAU,OAC9BH,EAAKK,OAAOta,MAAMoa,QAAU,GAE5B5R,KAAKqR,QAAU,EAGjBrR,KAAKyR,KAAOA,IAKhB,IAAeL,aAAeA,EACf,Q,sSC5DA,MAAM,EAInB,YAAYY,EAA0BL,EAA6BM,EAAgEC,EAA2CR,GAAxI,KAAAC,aAA6B,KAAAM,eAAgE,KAAAC,UAA2C,KAAAR,UAFtK,KAAAS,WAAY,EAGlBnS,KAAK8R,OAASlL,SAASwL,KAAKzc,cAAc,IAAMqc,GAGrC,SAASzc,G,yCAOpB,GAJGyK,KAAKkS,SACNlS,KAAKkS,WAAW3c,IAGdyK,KAAKmS,UAAW,CAClB,GAAGnS,KAAKiS,aACN,IACE,MAAMlE,EAAM/N,KAAKiS,gBAAgB1c,GAC9BwY,aAAevN,gBACVuN,GAER,MAAMpJ,GACNrE,QAAQ4I,MAAM,oBAAqBvE,GAIvC3E,KAAKmS,WAAY,EAGnB,EAAaE,QAAQrS,Y,gCCtCzB,0IAkBA,IAAIsS,GAAc,EACdC,EAAkD,cAClDC,EAAkB,EAEtBD,EAAsBve,UAEtB,MAAMqL,EAAMiB,QAAQjB,IAAIwK,KAAKvJ,QAAQjB,IAAK,sBAEnC,SAASoT,EAA4BC,EAAuBzY,GAC7DqY,IACFC,EAAwB,cACxB,UAAUrQ,cAdgB,+BAe1BoQ,GAAc,EACd,KAASjT,EAAI,YAGbmT,EACF,KAASnT,EAAI,0BAA2BmT,EAAiBvY,GAEzD,MAAM4G,EAAW,MACHpL,IAAZwE,EAAwB,YAAMA,QAAWxE,EACzCid,EAAQC,QAAQ,SAChB/Z,OAAOqM,SAEH2N,EAAOC,YAAYjX,MACnBkX,EAAyBP,EAa/B,OAZA/R,QAAQiO,KAAK5N,GAAUzM,KAAK,KACvBme,IAA0BO,GAA0BP,EAAsBQ,gBAI3EP,EACF,KAASnT,EAAI,uBAAwBmT,EAAiBK,YAAYjX,MAAQgX,GACvEJ,GAAmB,GACpBQ,OAIGT,EAGT,SAASS,IACJT,EAAsBQ,cAIzBT,GAAc,EACdE,EAAkB,EAClB,UAAUtQ,cAlDgB,6BAmD1BqQ,EAAsBve,UAEtB,KAASqL,EAAI,QAGR,SAAS4T,IACdD,IAGK,SAASE,IACd,OAAOX,EAGM,aACbY,EACAC,EACAC,GAGKf,GACDa,IAGF,MAAMxb,EAAM0b,EAAiBA,EAAe1b,IAAI,WAAa,UAAUE,iBAAiBgS,KAAK,WACvF7S,EAASqc,EAAiBA,EAAeC,aAAazJ,KAAKwJ,EAAgB,WAAa,UAAUzZ,oBAAoBiQ,KAAK,WAIjI,OAHAlS,EA7E0B,8BA6ECwb,GAC3Bxb,EA7EwB,4BA6ECyb,GAElB,KACLpc,EAhFsB,4BAgFMoc,GAC5Bpc,EAlFwB,8BAkFMmc,M,gCCjGpC,iHAmBA,IAAYI,EAqBG,SAASxB,EAAiB5M,GAkBvC,QAjBsB1P,IAAnB0P,EAAQqO,SACTrO,EAAQqO,OAAS,QAGQ/d,IAAxB0P,EAAQsO,cACTtO,EAAQsO,YA9ByB,WAiCfhe,IAAjB0P,EAAQ5O,OACT4O,EAAQ5O,KAAO,KAIb,UAAUC,SAASC,oBACrB0O,EAAQ/O,eAAiBmd,EAAeld,QAGvC8O,EAAQ/O,iBAAmBmd,EAAeld,OAE3C,OADA8O,EAAQ7O,cAAgB,EACjBod,EAAavO,GAStB,MAAMuN,EAAU,IAAIlS,QAAexM,IACjC,YAAQ,KACN0f,EAAavO,GAAS/Q,KAAKJ,OAI/B,MAAwB,MAAjBmR,EAAQ5O,KAAe,YAA4Bmc,GAAWA,EAGvE,SAASgB,EAAavO,GACpB,MAAM,QAAClP,EAAO,UAAE2Y,EAAS,cAAE+E,EAAa,KAAEpd,EAAI,OAAEid,EAAM,SAAErd,EAAQ,eAAEC,EAAc,YAAEqd,EAAW,cAAEnd,GAAiB6O,EAChH,IAAI,YAAQlP,GAEV,OADA,YAAqB2Y,GACdpO,QAAQxM,UAGjB,MAAM4f,EAAwB,MAATrd,EAAe,MAAQ,OACtCsd,EAAsB,MAATtd,EAAe,SAAW,QACvCud,EAAmB,MAATvd,EAAe,SAAW,QACpCwd,EAAyB,MAATxd,EAAe,eAAiB,cAChDyd,EAA6B,MAATzd,EAAe,YAAc,aAGjD0d,EAAche,EAAQwC,wBACtByb,EAAgBtF,EAAUnW,sBAAwBmW,EAAUnW,wBAA0BmO,SAASwL,KAAK3Z,wBAIpG0b,EAAkBF,EAAYL,GAAgBM,EAAcN,GAC5DQ,EAAcne,EAAQ8d,GAEtBM,EAAgBV,EAAgBA,EAAc,CAACW,KAAMJ,IAAkBA,EAAcJ,GAE3F,IAAIS,EAAiB3F,EAAUoF,GAC/B,MAAMQ,EAAa5F,EAAUmF,GAQ7B,IAAIU,EAEJ,OAAOte,GACL,IAAK,QACHse,EAAON,EAAkBX,EACzB,MACF,IAAK,MACHiB,EAAOR,EAAYJ,GAA2DK,EAAcL,GAAcL,EAC1G,MAEF,IAAK,UACL,IAAK,SACH,GAAGY,EAAcC,EACfI,EAAQN,EAAkBC,EAAc,EAAMC,EAAgB,MACzD,CACL,GAAGlP,EAAQuP,qCAAuCvP,EAAQuP,sCAAwCze,EAGhG,OAFAkP,EAAQlP,QAAUkP,EAAQuP,oCAC1BvP,EAAQhP,SAAW,QACZud,EAAavO,GAGtBsP,EAAON,EAAkBX,GAqB/B,GAAGnN,KAAKsO,IAAIF,GAAQjB,GAAU,IAAM,EAElC,OADA,YAAqB5E,GACdpO,QAAQxM,UA4BjB,GAzBY,MAATuC,QACqBd,IAAnBW,IACEqe,EAAOhB,GACRc,EAAiB3F,EAAUgG,WAAaH,EAAOhB,EAC/CgB,EAAOhB,GACCgB,GAAQhB,IAChBc,EAAiB3F,EAAUgG,WAAaH,EAAOhB,EAC/CgB,GAAQhB,IAkBXgB,EAAO,EAAG,CACX,MAAMI,GAAiBN,EACvBE,EAAOpO,KAAKrT,IAAIyhB,EAAMI,QACjB,GAAGJ,EAAO,EAAG,CAClB,MAAMI,EAAgBL,GAAcD,EAAiBF,GACrDI,EAAOpO,KAAKtT,IAAI0hB,EAAMI,GAGxB,MAAMxf,EAASuZ,EAAUoF,GAAqBS,EACxCK,EAAUzO,KAAKsO,IAAIF,GACnBM,EAAWze,UAnLK,IAoLDwe,EAlLc,KAkL4B,IAEzDE,EAAUrZ,KAAKC,MA0CfqZ,EAAaH,EA7NiB,IA6NyBI,EAAkBC,EACzEjhB,EAAO,KACX,MAAMwO,EAAIqS,EAAW1O,KAAKtT,KAAK4I,KAAKC,MAAQoZ,GAAWD,EAAU,GAAK,EAEhEK,EAAcX,GAAQ,EAAIQ,EAAWvS,IAG3C,OAFAkM,EAAUoF,GAAqB3N,KAAKC,MAAMjR,EAAS+f,GAE5C1S,EAAI,GAGb,OAAIqS,GAAaN,EAwBV,YAAcvgB,EAAM0a,IAvBzB,YAAqBA,GACrB1a,IACOsM,QAAQxM,WAwBnB,SAASmhB,EAAezS,GACtB,OAAO,EAAK,SAAC,EAAIA,EAAM,GAGzB,SAASwS,EAAgBxS,GACvB,OAAO,EAAK,SAAC,EAAIA,EAAM,MArQzB,SAAY6Q,GACV,eACA,mBACA,uBAHF,CAAYA,MAAc,M,gCCGX,SAAS8B,EAAQpf,GAC9B,OAAOA,aAAO,EAAPA,EAASqf,YAvBlB,mC,gCCMe,SAASzD,EAAW0D,GACjC,IAAIA,EAAK5K,WACP,OAAQ,EAGV,IAAI9P,EAAI,EAER,KAA+C,QAAxC0a,EAAOA,EAAKC,2BAAoC3a,EACvD,OAAOA,EAdT,mC,gCCMe,SAAS4a,EAAc/f,EAASggB,GAC7C,GAAGhgB,EAAGQ,gBAAkBwf,EAAQ,OAAOhgB,EAEvC,KAAMA,EAAGQ,eAEP,IADAR,EAAKA,EAAGQ,eACFA,gBAAkBwf,EACtB,OAAOhgB,EAIX,OAAO,KAhBT","file":"2.3d6b202e8d6ff37ebd0b.chunk.js","sourcesContent":["export default function clamp(v: number, min: number, max: number): number {\n return v < min ? min : ((v > max) ? max : v);\n}\n","export default function getDeepProperty(object: any, key: string) {\n const splitted = key.split('.');\n let o: any = object;\n splitted.forEach(key => {\n if(!key) {\n return;\n }\n \n // @ts-ignore\n o = o[key];\n });\n \n return o;\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n// * Jolly Cobra's animation.ts\r\n\r\nimport { fastRaf } from './schedulers';\r\nimport { CancellablePromise, deferredPromise } from './cancellablePromise';\r\n\r\ninterface AnimationInstance {\r\n isCancelled: boolean;\r\n deferred: CancellablePromise\r\n}\r\n\r\ntype AnimationInstanceKey = any;\r\nconst instances: Map = new Map();\r\n\r\nexport function createAnimationInstance(key: AnimationInstanceKey) {\r\n cancelAnimationByKey(key);\r\n\r\n const instance: AnimationInstance = {\r\n isCancelled: false, \r\n deferred: deferredPromise()\r\n };\r\n\r\n instances.set(key, instance);\r\n instance.deferred.then(() => {\r\n instances.delete(key);\r\n });\r\n\r\n return instance;\r\n}\r\n\r\nexport function getAnimationInstance(key: AnimationInstanceKey) {\r\n return instances.get(key);\r\n}\r\n\r\nexport function cancelAnimationByKey(key: AnimationInstanceKey) {\r\n const instance = getAnimationInstance(key);\r\n if(instance) {\r\n instance.isCancelled = true;\r\n instance.deferred.resolve();\r\n }\r\n}\r\n\r\nexport function animateSingle(tick: Function, key: AnimationInstanceKey, instance?: AnimationInstance) {\r\n if(!instance) {\r\n instance = createAnimationInstance(key);\r\n }\r\n\r\n fastRaf(() => {\r\n if(instance.isCancelled) {\r\n return;\r\n }\r\n \r\n if(tick()) {\r\n animateSingle(tick, key, instance);\r\n } else {\r\n instance.deferred.resolve();\r\n }\r\n });\r\n\r\n return instance.deferred;\r\n}\r\n\r\nexport function animate(tick: Function) {\r\n fastRaf(() => {\r\n if(tick()) {\r\n animate(tick);\r\n }\r\n });\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport { TransitionSlider } from \"./transition\";\r\nimport { ScrollableX } from \"./scrollable\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport { fastRaf } from \"../helpers/schedulers\";\r\nimport { FocusDirection } from \"../helpers/fastSmoothScroll\";\r\nimport findUpAsChild from \"../helpers/dom/findUpAsChild\";\r\nimport whichChild from \"../helpers/dom/whichChild\";\r\n\r\nexport function horizontalMenu(\r\n tabs: HTMLElement, \r\n content: HTMLElement, \r\n onClick?: (id: number, tabContent: HTMLDivElement, animate: boolean) => void | boolean, \r\n onTransitionEnd?: () => void, \r\n transitionTime = 250, \r\n scrollableX?: ScrollableX\r\n) {\r\n const selectTab = TransitionSlider(content, tabs || content.dataset.animation === 'tabs' ? 'tabs' : 'navigation', transitionTime, onTransitionEnd);\r\n\r\n if(tabs) {\r\n const proxy = new Proxy(selectTab, {\r\n apply: (target, that, args) => {\r\n const id = +args[0];\r\n const animate = args[1] !== undefined ? args[1] : true;\r\n \r\n const el = (tabs.querySelector(`[data-tab=\"${id}\"]`) || tabs.children[id]) as HTMLElement;\r\n selectTarget(el, id, animate);\r\n }\r\n });\r\n\r\n const selectTarget = (target: HTMLElement, id: number, animate = true) => {\r\n const tabContent = content.children[id] as HTMLDivElement;\r\n\r\n if(onClick) {\r\n const canChange = onClick(id, tabContent, animate);\r\n if(canChange !== undefined && !canChange) {\r\n return;\r\n }\r\n }\r\n\r\n if(scrollableX) {\r\n scrollableX.scrollIntoViewNew({\r\n element: target.parentElement.children[id] as HTMLElement, \r\n position: 'center', \r\n forceDirection: animate ? undefined : FocusDirection.Static, \r\n forceDuration: transitionTime, \r\n axis: 'x'\r\n });\r\n }\r\n\r\n if(!rootScope.settings.animationsEnabled) {\r\n animate = false;\r\n }\r\n\r\n const prevId = selectTab.prevId();\r\n if(target.classList.contains('active') || id === prevId) {\r\n return false;\r\n }\r\n \r\n const prev = tabs.querySelector(tagName.toLowerCase() + '.active') as HTMLElement;\r\n\r\n fastRaf(() => {\r\n prev && prev.classList.remove('active');\r\n });\r\n \r\n // stripe from ZINCHUK\r\n if(useStripe && prevId !== -1 && animate) {\r\n fastRaf(() => {\r\n const indicator = target.querySelector('i')!;\r\n const currentIndicator = target.parentElement.children[prevId].querySelector('i')!;\r\n \r\n currentIndicator.classList.remove('animate');\r\n indicator.classList.remove('animate');\r\n \r\n // We move and resize our indicator so it repeats the position and size of the previous one.\r\n const shiftLeft = currentIndicator.parentElement.parentElement.offsetLeft - indicator.parentElement.parentElement.offsetLeft;\r\n const scaleFactor = currentIndicator.clientWidth / indicator.clientWidth;\r\n indicator.style.transform = `translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`;\r\n \r\n //console.log(`translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`);\r\n \r\n requestAnimationFrame(() => {\r\n // Now we remove the transform to let it animate to its own position and size.\r\n indicator.classList.add('animate');\r\n indicator.style.transform = 'none';\r\n });\r\n });\r\n }\r\n // stripe END\r\n\r\n fastRaf(() => {\r\n target.classList.add('active');\r\n });\r\n \r\n selectTab(id, animate);\r\n };\r\n\r\n const useStripe = !tabs.classList.contains('no-stripe');\r\n\r\n //const tagName = tabs.classList.contains('menu-horizontal-div') ? 'BUTTON' : 'LI';\r\n const tagName = tabs.firstElementChild.tagName;\r\n tabs.addEventListener('click', function(e) {\r\n let target = e.target as HTMLElement;\r\n \r\n target = findUpAsChild(target, tabs);\r\n \r\n //console.log('tabs click:', target);\r\n \r\n if(!target) return false;\r\n\r\n let id: number;\r\n if(target.dataset.tab) {\r\n id = +target.dataset.tab;\r\n if(id === -1) {\r\n return false;\r\n }\r\n } else {\r\n id = whichChild(target);\r\n }\r\n\r\n selectTarget(target, id);\r\n });\r\n\r\n return proxy;\r\n }\r\n \r\n return selectTab;\r\n}\r\n","import copy from \"./copy\";\nimport isObject from \"./isObject\";\n\nexport default function validateInitObject(initObject: any, currentObject: any, onReplace?: (key: string) => void, previousKey?: string) {\n for(const key in initObject) {\n if(typeof(currentObject[key]) !== typeof(initObject[key])) {\n currentObject[key] = copy(initObject[key]);\n onReplace && onReplace(previousKey || key);\n } else if(isObject(initObject[key])) {\n validateInitObject(initObject[key], currentObject[key], onReplace, previousKey || key);\n }\n }\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport rootScope from \"../lib/rootScope\";\r\nimport { CancellablePromise, deferredPromise } from \"../helpers/cancellablePromise\";\r\nimport { dispatchHeavyAnimationEvent } from \"../hooks/useHeavyAnimationCheck\";\r\nimport whichChild from \"../helpers/dom/whichChild\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\n\r\nfunction slideNavigation(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {\r\n const width = prevTabContent.getBoundingClientRect().width;\r\n const elements = [tabContent, prevTabContent];\r\n if(toRight) elements.reverse();\r\n elements[0].style.filter = `brightness(80%)`;\r\n elements[0].style.transform = `translate3d(${-width * .25}px, 0, 0)`;\r\n elements[1].style.transform = `translate3d(${width}px, 0, 0)`;\r\n \r\n tabContent.classList.add('active');\r\n void tabContent.offsetWidth; // reflow\r\n\r\n tabContent.style.transform = '';\r\n tabContent.style.filter = '';\r\n\r\n return () => {\r\n prevTabContent.style.transform = prevTabContent.style.filter = '';\r\n };\r\n}\r\n\r\nfunction slideTabs(tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) {\r\n // Jolly Cobra's // Workaround for scrollable content flickering during animation.\r\n // const scrollableContainer = findUpClassName(tabContent, 'scrollable-y');\r\n // if(scrollableContainer && scrollableContainer.style.overflowY !== 'hidden') {\r\n // // const scrollBarWidth = scrollableContainer.offsetWidth - scrollableContainer.clientWidth;\r\n // scrollableContainer.style.overflowY = 'hidden';\r\n // // scrollableContainer.style.paddingRight = `${scrollBarWidth}px`;\r\n // // this.container.classList.add('sliding');\r\n // }\r\n\r\n //window.requestAnimationFrame(() => {\r\n const width = prevTabContent.getBoundingClientRect().width;\r\n /* tabContent.style.setProperty('--width', width + 'px');\r\n prevTabContent.style.setProperty('--width', width + 'px');\r\n\r\n tabContent.classList.add('active'); */\r\n //void tabContent.offsetWidth; // reflow\r\n const elements = [tabContent, prevTabContent];\r\n if(toRight) elements.reverse();\r\n elements[0].style.transform = `translate3d(${-width}px, 0, 0)`;\r\n elements[1].style.transform = `translate3d(${width}px, 0, 0)`;\r\n \r\n tabContent.classList.add('active');\r\n void tabContent.offsetWidth; // reflow\r\n \r\n tabContent.style.transform = '';\r\n //});\r\n \r\n return () => {\r\n prevTabContent.style.transform = '';\r\n\r\n // if(scrollableContainer) {\r\n // // Jolly Cobra's // Workaround for scrollable content flickering during animation.\r\n // if(isSafari) { // ! safari doesn't respect sticky header, so it flicks when overflow is changing\r\n // scrollableContainer.style.display = 'none';\r\n // }\r\n\r\n // scrollableContainer.style.overflowY = '';\r\n\r\n // if(isSafari) {\r\n // void scrollableContainer.offsetLeft; // reflow\r\n // scrollableContainer.style.display = '';\r\n // }\r\n\r\n // // scrollableContainer.style.paddingRight = '0';\r\n // // this.container.classList.remove('sliding');\r\n // }\r\n };\r\n}\r\n\r\nexport const TransitionSlider = (\r\n content: HTMLElement, \r\n type: 'tabs' | 'navigation' | 'zoom-fade' | 'slide-fade' | 'none'/* | 'counter' */, \r\n transitionTime: number, \r\n onTransitionEnd?: (id: number) => void, \r\n isHeavy = true\r\n) => {\r\n let animationFunction: TransitionFunction = null;\r\n\r\n switch(type) {\r\n case 'tabs':\r\n animationFunction = slideTabs;\r\n break;\r\n case 'navigation':\r\n animationFunction = slideNavigation;\r\n break;\r\n /* default:\r\n break; */\r\n }\r\n\r\n content.dataset.animation = type;\r\n \r\n return Transition(content, animationFunction, transitionTime, onTransitionEnd, isHeavy);\r\n};\r\n\r\ntype TransitionFunction = (tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) => void | (() => void);\r\n\r\nconst Transition = (\r\n content: HTMLElement, \r\n animationFunction: TransitionFunction, \r\n transitionTime: number, \r\n onTransitionEnd?: (id: number) => void, \r\n isHeavy = true,\r\n once = false,\r\n withAnimationListener = true\r\n) => {\r\n const onTransitionEndCallbacks: Map = new Map();\r\n let animationDeferred: CancellablePromise;\r\n // let animationStarted = 0;\r\n let from: HTMLElement = null;\r\n\r\n if(withAnimationListener) {\r\n const listenerName = animationFunction ? 'transitionend' : 'animationend';\r\n\r\n const onEndEvent = (e: TransitionEvent | AnimationEvent) => {\r\n cancelEvent(e);\r\n \r\n if((e.target as HTMLElement).parentElement !== content) {\r\n return;\r\n }\r\n \r\n //console.log('Transition: transitionend', /* content, */ e, selectTab.prevId, performance.now() - animationStarted);\r\n \r\n const callback = onTransitionEndCallbacks.get(e.target as HTMLElement);\r\n if(callback) callback();\r\n \r\n if(e.target !== from) {\r\n return;\r\n }\r\n \r\n if(!animationDeferred && isHeavy) return;\r\n \r\n if(animationDeferred) {\r\n animationDeferred.resolve();\r\n animationDeferred = undefined;\r\n }\r\n \r\n if(onTransitionEnd) {\r\n onTransitionEnd(selectTab.prevId());\r\n }\r\n \r\n content.classList.remove('animating', 'backwards', 'disable-hover');\r\n \r\n if(once) {\r\n content.removeEventListener(listenerName, onEndEvent/* , {capture: false} */);\r\n from = animationDeferred = undefined;\r\n onTransitionEndCallbacks.clear();\r\n }\r\n };\r\n \r\n // TODO: check for transition type (transform, etc) using by animationFunction\r\n content.addEventListener(listenerName, onEndEvent/* , {passive: true, capture: false} */);\r\n }\r\n\r\n function selectTab(id: number | HTMLElement, animate = true, overrideFrom?: typeof from) {\r\n if(overrideFrom) {\r\n from = overrideFrom;\r\n }\r\n\r\n if(id instanceof HTMLElement) {\r\n id = whichChild(id);\r\n }\r\n \r\n const prevId = selectTab.prevId();\r\n if(id === prevId) return false;\r\n\r\n //console.log('selectTab id:', id);\r\n\r\n const to = content.children[id] as HTMLElement;\r\n\r\n if(!rootScope.settings.animationsEnabled || prevId === -1) {\r\n animate = false;\r\n }\r\n\r\n if(!withAnimationListener) {\r\n const timeout = content.dataset.timeout;\r\n if(timeout !== undefined) {\r\n clearTimeout(+timeout);\r\n }\r\n\r\n delete content.dataset.timeout;\r\n }\r\n\r\n if(!animate) {\r\n if(from) from.classList.remove('active', 'to', 'from');\r\n else if(to) { // fix instant opening back from closed slider (e.g. instant closening and opening right sidebar)\r\n const callback = onTransitionEndCallbacks.get(to);\r\n if(callback) {\r\n callback();\r\n }\r\n }\r\n\r\n if(to) {\r\n to.classList.remove('to', 'from');\r\n to.classList.add('active');\r\n }\r\n\r\n content.classList.remove('animating', 'backwards', 'disable-hover');\r\n\r\n from = to;\r\n\r\n if(onTransitionEnd) onTransitionEnd(id);\r\n return;\r\n }\r\n\r\n if(!withAnimationListener) {\r\n content.dataset.timeout = '' + window.setTimeout(() => {\r\n to.classList.remove('to');\r\n from && from.classList.remove('from');\r\n content.classList.remove('animating', 'backwards', 'disable-hover');\r\n delete content.dataset.timeout;\r\n }, transitionTime);\r\n }\r\n\r\n if(from) {\r\n from.classList.remove('to');\r\n from.classList.add('from');\r\n }\r\n\r\n content.classList.add('animating'/* , 'disable-hover' */);\r\n const toRight = prevId < id;\r\n content.classList.toggle('backwards', !toRight);\r\n\r\n let onTransitionEndCallback: ReturnType;\r\n if(!to) {\r\n //prevTabContent.classList.remove('active');\r\n } else {\r\n if(animationFunction) {\r\n onTransitionEndCallback = animationFunction(to, from, toRight);\r\n } else {\r\n to.classList.add('active');\r\n }\r\n\r\n to.classList.remove('from');\r\n to.classList.add('to');\r\n }\r\n \r\n if(to) {\r\n onTransitionEndCallbacks.set(to, () => {\r\n to.classList.remove('to');\r\n onTransitionEndCallbacks.delete(to);\r\n });\r\n }\r\n\r\n if(from/* && false */) {\r\n const _from = from;\r\n const callback = () => {\r\n _from.classList.remove('active', 'from');\r\n\r\n if(onTransitionEndCallback) {\r\n onTransitionEndCallback();\r\n }\r\n\r\n onTransitionEndCallbacks.delete(_from);\r\n };\r\n\r\n if(to) {\r\n onTransitionEndCallbacks.set(_from, callback);\r\n } else {\r\n const timeout = window.setTimeout(callback, transitionTime);\r\n onTransitionEndCallbacks.set(_from, () => {\r\n clearTimeout(timeout);\r\n onTransitionEndCallbacks.delete(_from);\r\n });\r\n }\r\n\r\n if(isHeavy) {\r\n if(!animationDeferred) {\r\n animationDeferred = deferredPromise();\r\n // animationStarted = performance.now();\r\n }\r\n \r\n dispatchHeavyAnimationEvent(animationDeferred, transitionTime * 2);\r\n }\r\n }\r\n \r\n from = to;\r\n }\r\n\r\n //selectTab.prevId = -1;\r\n selectTab.prevId = () => from ? whichChild(from) : -1;\r\n \r\n return selectTab;\r\n};\r\n\r\nexport default Transition;\r\n","export default function compareVersion(v1: string, v2: string): number {\n v1 = v1.split(' ', 1)[0];\n v2 = v2.split(' ', 1)[0];\n const s1 = v1.split('.');\n const s2 = v2.split('.');\n\n for(let i = 0; i < s1.length; ++i) {\n const v1 = +s1[i];\n const v2 = +s2[i];\n if(v1 > v2) return 1;\n else if(v1 < v2) return -1;\n }\n\n return 0;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type { Dialog } from './appMessagesManager';\nimport { NULL_PEER_ID, UserAuth } from '../mtproto/mtproto_config';\nimport type { MyTopPeer, TopPeerType, User } from './appUsersManager';\nimport type { AuthState } from '../../types';\nimport type FiltersStorage from '../storages/filters';\nimport type DialogsStorage from '../storages/dialogs';\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport rootScope from '../rootScope';\nimport stateStorage from '../stateStorage';\nimport { logger } from '../logger';\nimport App from '../../config/app';\nimport DEBUG, { MOUNT_CLASS_TO } from '../../config/debug';\nimport AppStorage from '../storage';\nimport { AutoDownloadSettings, Chat, NotifyPeer, PeerNotifySettings } from '../../layer';\nimport { IS_MOBILE } from '../../environment/userAgent';\nimport DATABASE_STATE from '../../config/databases/state';\nimport sessionStorage from '../sessionStorage';\nimport { nextRandomUint } from '../../helpers/random';\nimport compareVersion from '../../helpers/compareVersion';\nimport getTimeFormat from '../../helpers/getTimeFormat';\nimport copy from '../../helpers/object/copy';\nimport setDeepProperty from '../../helpers/object/setDeepProperty';\nimport validateInitObject from '../../helpers/object/validateInitObject';\n\nconst REFRESH_EVERY = 24 * 60 * 60 * 1000; // 1 day\n// const REFRESH_EVERY = 1e3;\n//const REFRESH_EVERY_WEEK = 24 * 60 * 60 * 1000 * 7; // 7 days\nconst STATE_VERSION = App.version;\nconst BUILD = App.build;\n\nexport type Background = {\n type?: 'color' | 'image' | 'default', // ! DEPRECATED\n blur: boolean,\n highlightningColor?: string,\n color?: string, \n slug?: string, // image slug\n intensity?: number, // pattern intensity\n id: string | number, // wallpaper id\n};\n\nexport type Theme = {\n name: 'day' | 'night' | 'system',\n background: Background\n};\n\nexport type AutoDownloadPeerTypeSettings = {\n contacts: boolean,\n private: boolean,\n groups: boolean,\n channels: boolean\n};\n\nexport type State = {\n allDialogsLoaded: DialogsStorage['allDialogsLoaded'],\n pinnedOrders: DialogsStorage['pinnedOrders'],\n contactsList: UserId[],\n updates: Partial<{\n seq: number,\n pts: number,\n date: number\n }>,\n filters: FiltersStorage['filters'],\n maxSeenMsgId: number,\n stateCreatedTime: number,\n recentEmoji: string[],\n topPeersCache: {\n [type in TopPeerType]?: {\n peers: MyTopPeer[],\n cachedTime: number\n }\n },\n recentSearch: PeerId[],\n version: typeof STATE_VERSION,\n build: typeof BUILD,\n authState: AuthState,\n hiddenPinnedMessages: {[peerId: PeerId]: number},\n settings: {\n messagesTextSize: number,\n distanceUnit: 'kilometers' | 'miles',\n sendShortcut: 'enter' | 'ctrlEnter',\n animationsEnabled: boolean,\n autoDownload: {\n contacts?: boolean, // ! DEPRECATED\n private?: boolean, // ! DEPRECATED\n groups?: boolean, // ! DEPRECATED\n channels?: boolean, // ! DEPRECATED\n photo: AutoDownloadPeerTypeSettings,\n video: AutoDownloadPeerTypeSettings,\n file: AutoDownloadPeerTypeSettings\n },\n autoDownloadNew: AutoDownloadSettings,\n autoPlay: {\n gifs: boolean,\n videos: boolean\n },\n stickers: {\n suggest: boolean,\n loop: boolean\n },\n emoji: {\n suggest: boolean,\n big: boolean\n },\n background?: Background, // ! DEPRECATED\n themes: Theme[],\n theme: Theme['name'],\n notifications: {\n sound: boolean\n },\n nightTheme?: boolean, // ! DEPRECATED\n timeFormat: 'h12' | 'h23'\n },\n keepSigned: boolean,\n chatContextMenuHintWasShown: boolean,\n stateId: number,\n notifySettings: {[k in Exclude]?: PeerNotifySettings.peerNotifySettings}\n};\n\nexport const STATE_INIT: State = {\n allDialogsLoaded: {},\n pinnedOrders: {},\n contactsList: [],\n updates: {},\n filters: {},\n maxSeenMsgId: 0,\n stateCreatedTime: Date.now(),\n recentEmoji: [],\n topPeersCache: {},\n recentSearch: [],\n version: STATE_VERSION,\n build: BUILD,\n authState: {\n _: IS_MOBILE ? 'authStateSignIn' : 'authStateSignQr'\n },\n hiddenPinnedMessages: {},\n settings: {\n messagesTextSize: 16,\n distanceUnit: 'kilometers',\n sendShortcut: 'enter',\n animationsEnabled: true,\n autoDownload: {\n photo: {\n contacts: true,\n private: true,\n groups: true,\n channels: true\n },\n video: {\n contacts: true,\n private: true,\n groups: true,\n channels: true\n },\n file: {\n contacts: true,\n private: true,\n groups: true,\n channels: true\n }\n },\n autoDownloadNew: {\n _: 'autoDownloadSettings',\n file_size_max: 3145728,\n pFlags: {\n video_preload_large: true,\n audio_preload_next: true\n },\n photo_size_max: 1048576,\n video_size_max: 15728640,\n video_upload_maxbitrate: 100\n },\n autoPlay: {\n gifs: true,\n videos: true\n },\n stickers: {\n suggest: true,\n loop: true\n },\n emoji: {\n suggest: true,\n big: true\n },\n themes: [{\n name: 'day',\n background: {\n blur: false,\n slug: 'pattern',\n color: '#dbddbb,#6ba587,#d5d88d,#88b884',\n highlightningColor: 'hsla(86.4, 43.846153%, 45.117647%, .4)',\n intensity: 50,\n id: '1'\n }\n }, {\n name: 'night',\n background: {\n blur: false,\n slug: 'pattern',\n // color: '#dbddbb,#6ba587,#d5d88d,#88b884',\n color: '#fec496,#dd6cb9,#962fbf,#4f5bd5',\n highlightningColor: 'hsla(299.142857, 44.166666%, 37.470588%, .4)',\n intensity: -50,\n id: '-1'\n }\n }],\n theme: 'system',\n notifications: {\n sound: false\n },\n timeFormat: getTimeFormat()\n },\n keepSigned: true,\n chatContextMenuHintWasShown: false,\n stateId: nextRandomUint(32),\n notifySettings: {}\n};\n\nconst ALL_KEYS = Object.keys(STATE_INIT) as any as Array;\n\nconst REFRESH_KEYS = ['contactsList', 'stateCreatedTime',\n 'maxSeenMsgId', 'filters', 'topPeers'] as any as Array;\n\nexport type StatePeerType = 'recentSearch' | 'topPeer' | 'dialog' | 'contact' | 'topMessage' | 'self';\n\n//const REFRESH_KEYS_WEEK = ['dialogs', 'allDialogsLoaded', 'updates', 'pinnedOrders'] as any as Array;\n\nexport class AppStateManager extends EventListenerBase<{\n save: (state: State) => Promise,\n peerNeeded: (peerId: PeerId) => void,\n peerUnneeded: (peerId: PeerId) => void\n}> {\n public static STATE_INIT = STATE_INIT;\n private loaded: Promise;\n private log = logger('STATE'/* , LogLevels.error */);\n\n private state: State;\n\n private neededPeers: Map> = new Map();\n private singlePeerMap: Map = new Map();\n\n public storages = {\n users: new AppStorage, typeof DATABASE_STATE>(DATABASE_STATE, 'users'),\n chats: new AppStorage, typeof DATABASE_STATE>(DATABASE_STATE, 'chats'),\n dialogs: new AppStorage, typeof DATABASE_STATE>(DATABASE_STATE, 'dialogs')\n };\n\n public storagesResults: {\n users: User[],\n chats: Chat[],\n dialogs: Dialog[]\n } = {} as any;\n\n public storage = stateStorage;\n\n public newVersion: string;\n\n constructor() {\n super();\n this.loadSavedState();\n\n rootScope.addEventListener('user_auth', () => {\n this.requestPeerSingle(rootScope.myId, 'self');\n });\n }\n\n public loadSavedState(): Promise {\n if(this.loaded) return this.loaded;\n console.time('load state');\n this.loaded = new Promise((resolve) => {\n const storagesKeys = Object.keys(this.storages) as Array;\n const storagesPromises: Promise[] = storagesKeys.map(key => this.storages[key].getAll());\n\n const promises/* : Promise[] */ = ALL_KEYS.map(key => stateStorage.get(key))\n .concat(sessionStorage.get('user_auth'), sessionStorage.get('state_id'))\n .concat(stateStorage.get('user_auth')) // support old webk format\n .concat(storagesPromises);\n\n Promise.all(promises).then(async(arr) => {\n // await new Promise((resolve) => setTimeout(resolve, 3e3));\n /* const self = this;\n const skipHandleKeys = new Set(['isProxy', 'filters', 'drafts']);\n const getHandler = (path?: string) => {\n return {\n get(target: any, key: any) {\n if(key === 'isProxy') {\n return true;\n }\n\n const prop = target[key];\n\n if(prop !== undefined && !skipHandleKeys.has(key) && !prop.isProxy && typeof(prop) === 'object') {\n target[key] = new Proxy(prop, getHandler(path || key));\n return target[key];\n }\n \n return prop;\n },\n set(target: any, key: any, value: any) {\n console.log('Setting', target, `.${key} to equal`, value, path);\n \n target[key] = value;\n\n // @ts-ignore\n self.pushToState(path || key, path ? self.state[path] : value, false);\n\n return true;\n }\n };\n }; */\n\n let state: State = this.state = {} as any;\n\n // ! then can't store false values\n for(let i = 0, length = ALL_KEYS.length; i < length; ++i) {\n const key = ALL_KEYS[i];\n const value = arr[i];\n if(value !== undefined) {\n // @ts-ignore\n state[key] = value;\n } else {\n this.pushToState(key, copy(STATE_INIT[key]));\n }\n }\n\n arr.splice(0, ALL_KEYS.length);\n\n // * Read auth\n let auth = arr.shift() as UserAuth | number;\n const stateId = arr.shift() as number;\n const shiftedWebKAuth = arr.shift() as UserAuth | number;\n if(!auth && shiftedWebKAuth) { // support old webk auth\n auth = shiftedWebKAuth;\n const keys: string[] = ['dc', 'server_time_offset', 'xt_instance'];\n for(let i = 1; i <= 5; ++i) {\n keys.push(`dc${i}_server_salt`);\n keys.push(`dc${i}_auth_key`);\n }\n\n const values = await Promise.all(keys.map(key => stateStorage.get(key as any)));\n keys.push('user_auth');\n values.push(typeof(auth) === 'number' || typeof(auth) === 'string' ? {dcID: values[0] || App.baseDcId, date: Date.now() / 1000 | 0, id: auth.toPeerId(false)} as UserAuth : auth);\n\n let obj: any = {};\n keys.forEach((key, idx) => {\n obj[key] = values[idx];\n });\n\n await sessionStorage.set(obj);\n }\n \n /* if(!auth) { // try to read Webogram's session from localStorage\n try {\n const keys = Object.keys(localStorage);\n for(let i = 0; i < keys.length; ++i) {\n const key = keys[i];\n let value: any;\n try {\n value = localStorage.getItem(key);\n value = JSON.parse(value);\n } catch(err) {\n //console.error(err);\n }\n\n sessionStorage.set({\n [key as any]: value\n });\n }\n\n auth = sessionStorage.getFromCache('user_auth');\n } catch(err) {\n this.log.error('localStorage import error', err);\n }\n } */\n\n if(auth) {\n // ! Warning ! DON'T delete this\n state.authState = {_: 'authStateSignedIn'};\n rootScope.dispatchEvent('user_auth', typeof(auth) === 'number' || typeof(auth) === 'string' ? \n {dcID: 0, date: Date.now() / 1000 | 0, id: auth.toPeerId(false)} : \n auth); // * support old version\n }\n\n // * Read storages\n for(let i = 0, length = storagesKeys.length; i < length; ++i) {\n this.storagesResults[storagesKeys[i]] = arr[i] as any;\n }\n\n arr.splice(0, storagesKeys.length);\n\n if(state.stateId !== stateId) {\n if(stateId !== undefined) {\n const preserve: Map = new Map([\n ['authState', undefined],\n ['stateId', undefined]\n ]);\n \n preserve.forEach((_, key) => {\n preserve.set(key, copy(state[key]));\n });\n \n state = this.state = copy(STATE_INIT);\n \n preserve.forEach((value, key) => {\n // @ts-ignore\n state[key] = value;\n });\n\n for(const key in this.storagesResults) {\n this.storagesResults[key as keyof AppStateManager['storagesResults']].length = 0;\n }\n\n this.storage.set(state);\n }\n\n await sessionStorage.set({\n state_id: state.stateId\n });\n }\n\n const time = Date.now();\n if((state.stateCreatedTime + REFRESH_EVERY) < time) {\n if(DEBUG) {\n this.log('will refresh state', state.stateCreatedTime, time);\n }\n\n const r = (keys: typeof REFRESH_KEYS) => {\n keys.forEach(key => {\n this.pushToState(key, copy(STATE_INIT[key]));\n \n // @ts-ignore\n const s = this.storagesResults[key];\n if(s && s.length) {\n s.length = 0;\n }\n });\n };\n \n r(REFRESH_KEYS);\n\n /* if((state.stateCreatedTime + REFRESH_EVERY_WEEK) < time) {\n if(DEBUG) {\n this.log('will refresh updates');\n }\n\n r(REFRESH_KEYS_WEEK);\n } */\n }\n \n //state = this.state = new Proxy(state, getHandler());\n\n // * support old version\n if(!state.settings.hasOwnProperty('theme') && state.settings.hasOwnProperty('nightTheme')) {\n state.settings.theme = state.settings.nightTheme ? 'night' : 'day';\n this.pushToState('settings', state.settings);\n }\n\n // * support old version\n if(!state.settings.hasOwnProperty('themes') && state.settings.background) {\n state.settings.themes = copy(STATE_INIT.settings.themes);\n const theme = state.settings.themes.find(t => t.name === state.settings.theme);\n if(theme) {\n theme.background = state.settings.background;\n this.pushToState('settings', state.settings);\n }\n }\n\n // * migrate auto download settings\n const autoDownloadSettings = state.settings.autoDownload;\n if(autoDownloadSettings?.private !== undefined) {\n const oldTypes = [\n 'contacts' as const, \n 'private' as const, \n 'groups' as const, \n 'channels' as const\n ];\n\n const mediaTypes = [\n 'photo' as const,\n 'video' as const,\n 'file' as const\n ];\n\n mediaTypes.forEach(mediaType => {\n const peerTypeSettings: AutoDownloadPeerTypeSettings = autoDownloadSettings[mediaType] = {} as any;\n oldTypes.forEach(peerType => {\n peerTypeSettings[peerType] = autoDownloadSettings[peerType];\n });\n });\n\n oldTypes.forEach(peerType => {\n delete autoDownloadSettings[peerType];\n });\n\n this.pushToState('settings', state.settings);\n }\n\n validateInitObject(STATE_INIT, state, (missingKey) => {\n // @ts-ignore\n this.pushToState(missingKey, state[missingKey]);\n });\n\n if(state.version !== STATE_VERSION || state.build !== BUILD/* || true */) {\n // reset filters and dialogs if version is older\n if(compareVersion(state.version, '0.8.7') === -1) {\n this.state.allDialogsLoaded = copy(STATE_INIT.allDialogsLoaded);\n this.state.filters = copy(STATE_INIT.filters);\n const result = this.storagesResults.dialogs;\n if(result?.length) {\n result.length = 0;\n }\n }\n\n // * migrate backgrounds (March 13, 2022; to version 1.3.0)\n if(compareVersion(state.version, '1.3.0') === -1) {\n let migrated = false;\n state.settings.themes.forEach((theme, idx, arr) => {\n if((\n theme.name === 'day' && \n theme.background.slug === 'ByxGo2lrMFAIAAAAmkJxZabh8eM' && \n theme.background.type === 'image' \n ) || (\n theme.name === 'night' && \n theme.background.color === '#0f0f0f' && \n theme.background.type === 'color' \n )) {\n const newTheme = STATE_INIT.settings.themes.find(newTheme => newTheme.name === theme.name);\n if(newTheme) {\n arr[idx] = copy(newTheme);\n migrated = true;\n }\n }\n });\n\n if(migrated) {\n this.pushToState('settings', state.settings);\n }\n }\n \n if(compareVersion(state.version, STATE_VERSION) !== 0) {\n this.newVersion = STATE_VERSION;\n }\n\n this.pushToState('version', STATE_VERSION);\n this.pushToState('build', BUILD);\n }\n\n // ! probably there is better place for it\n rootScope.settings = state.settings;\n\n if(DEBUG) {\n this.log('state res', state, copy(state));\n }\n \n //return resolve();\n\n console.timeEnd('load state');\n resolve(state);\n }).catch(resolve);\n });\n\n return this.loaded;\n }\n\n public getState() {\n return this.state === undefined ? this.loadSavedState() : Promise.resolve(this.state);\n }\n\n public setByKey(key: string, value: any) {\n setDeepProperty(this.state, key, value);\n rootScope.dispatchEvent('settings_updated', {key, value});\n\n const first = key.split('.')[0];\n // @ts-ignore\n this.pushToState(first, this.state[first]);\n }\n\n public pushToState(key: T, value: State[T], direct = true) {\n if(direct) {\n this.state[key] = value;\n }\n\n this.setKeyValueToStorage(key, value);\n }\n\n public setKeyValueToStorage(key: T, value: State[T] = this.state[key]) {\n this.storage.set({\n [key]: value\n });\n }\n\n public requestPeer(peerId: PeerId, type: StatePeerType, limit?: number) {\n let set = this.neededPeers.get(peerId);\n if(set && set.has(type)) {\n return;\n }\n\n if(!set) {\n set = new Set();\n this.neededPeers.set(peerId, set);\n }\n\n set.add(type);\n\n this.dispatchEvent('peerNeeded', peerId);\n\n if(limit !== undefined) {\n this.keepPeerSingle(peerId, type);\n }\n }\n\n public requestPeerSingle(peerId: PeerId, type: StatePeerType, keepPeerIdSingle: PeerId = peerId) {\n return this.requestPeer(peerId, type + '_' + keepPeerIdSingle as any, 1);\n }\n\n public releaseSinglePeer(peerId: PeerId, type: StatePeerType) {\n return this.keepPeerSingle(NULL_PEER_ID, type + '_' + peerId as any);\n }\n\n public isPeerNeeded(peerId: PeerId) {\n return this.neededPeers.has(peerId);\n }\n\n public keepPeerSingle(peerId: PeerId, type: StatePeerType) {\n const existsPeerId = this.singlePeerMap.get(type);\n if(existsPeerId && existsPeerId !== peerId && this.neededPeers.has(existsPeerId)) {\n const set = this.neededPeers.get(existsPeerId);\n set.delete(type);\n\n if(!set.size) {\n this.neededPeers.delete(existsPeerId);\n this.dispatchEvent('peerUnneeded', existsPeerId);\n }\n }\n\n if(peerId) {\n this.singlePeerMap.set(type, peerId);\n } else {\n this.singlePeerMap.delete(type);\n }\n }\n\n /* public resetState() {\n for(let i in this.state) {\n // @ts-ignore\n this.state[i] = false;\n }\n sessionStorage.set(this.state).then(() => {\n location.reload();\n });\n } */\n}\n\n//console.trace('appStateManager include');\n\nconst appStateManager = new AppStateManager();\nMOUNT_CLASS_TO.appStateManager = appStateManager;\nexport default appStateManager;\n","export default function getTimeFormat(): 'h12' | 'h23' {\n // try {\n // const resolvedOptions = Intl.DateTimeFormat(navigator.language, {hour: 'numeric'}).resolvedOptions();\n // if('hourCycle' in resolvedOptions) {\n // return (resolvedOptions as any).hourCycle === 'h12' ? 'h12' : 'h23';\n // } else {\n // return resolvedOptions.hour12 ? 'h12' : 'h23';\n // }\n // } catch(err) {\n return new Date().toLocaleString().match(/\\s(AM|PM)/) ? 'h12' : 'h23';\n // }\n}\n","import getDeepProperty from \"./getDeepProperty\";\n\nexport default function setDeepProperty(object: any, key: string, value: any) {\n const splitted = key.split('.');\n getDeepProperty(object, splitted.slice(0, -1).join('.'))[splitted.pop()] = value;\n}\n","import { IS_SAFARI } from \"./userAgent\";\n\n/*\n * This is used as a workaround for a memory leak in Safari caused by using Transferable objects to\n * transfer data between WebWorkers and the main thread.\n * https://github.com/mapbox/mapbox-gl-js/issues/8771\n *\n * This should be removed once the underlying Safari issue is fixed.\n */\n\nlet CAN_USE_TRANSFERABLES: boolean;\nif(!IS_SAFARI) CAN_USE_TRANSFERABLES = true;\nelse {\n try {\n const match = navigator.userAgent.match(/Version\\/(.+?) /);\n CAN_USE_TRANSFERABLES = +match[1] >= 14;\n } catch(err) {\n CAN_USE_TRANSFERABLES = false;\n }\n}\n\nexport default CAN_USE_TRANSFERABLES;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport CAN_USE_TRANSFERABLES from \"../../environment/canUseTransferables\";\nimport { IS_ANDROID, IS_APPLE_MOBILE, IS_APPLE, IS_SAFARI } from \"../../environment/userAgent\";\nimport EventListenerBase from \"../../helpers/eventListenerBase\";\nimport mediaSizes from \"../../helpers/mediaSizes\";\nimport clamp from \"../../helpers/number/clamp\";\nimport lottieLoader from \"./lottieLoader\";\nimport QueryableWorker from \"./queryableWorker\";\n\nexport type RLottieOptions = {\n container: HTMLElement, \n canvas?: HTMLCanvasElement, \n autoplay?: boolean, \n animationData: Blob, \n loop?: boolean, \n width?: number,\n height?: number,\n group?: string,\n noCache?: boolean,\n needUpscale?: boolean,\n skipRatio?: number,\n initFrame?: number, // index\n color?: RLottieColor,\n inverseColor?: RLottieColor,\n name?: string,\n skipFirstFrameRendering?: boolean,\n toneIndex?: number\n};\n\ntype RLottieCacheMap = Map;\nclass RLottieCache {\n private cache: Map;\n \n constructor() {\n this.cache = new Map();\n }\n\n public getCache(name: string) {\n let cache = this.cache.get(name);\n if(!cache) {\n this.cache.set(name, cache = {frames: new Map(), counter: 0});\n } else {\n // console.warn('[RLottieCache] cache will be reused', cache);\n }\n\n ++cache.counter;\n return cache.frames;\n }\n\n public releaseCache(name: string) {\n const cache = this.cache.get(name);\n if(cache && !--cache.counter) {\n this.cache.delete(name);\n // console.warn('[RLottieCache] released cache', cache);\n }\n }\n\n public getCacheCounter(name: string) {\n const cache = this.cache.get(name);\n return cache?.counter;\n }\n\n public generateName(name: string, width: number, height: number, color: RLottieColor, toneIndex: number) {\n return [\n name, \n width, \n height, \n // color ? rgbaToHexa(color) : ''\n color ? 'colored' : '',\n toneIndex || ''\n ].filter(Boolean).join('-');\n }\n}\n\nconst cache = new RLottieCache();\n\nexport type RLottieColor = [number, number, number];\n\nexport default class RLottiePlayer extends EventListenerBase<{\n enterFrame: (frameNo: number) => void,\n ready: () => void,\n firstFrame: () => void,\n cached: () => void\n}> {\n private static reqId = 0;\n\n public reqId = 0;\n public curFrame: number;\n private frameCount: number;\n private fps: number;\n private skipDelta: number;\n private name: string;\n private cacheName: string;\n private toneIndex: number;\n\n private worker: QueryableWorker;\n \n private width = 0;\n private height = 0;\n\n public el: HTMLElement;\n public canvas: HTMLCanvasElement;\n private context: CanvasRenderingContext2D;\n\n public paused = true;\n //public paused = false;\n public direction = 1;\n private speed = 1;\n public autoplay = true;\n public _autoplay: boolean; // ! will be used to store original value for settings.stickers.loop\n public loop = true;\n private _loop: boolean; // ! will be used to store original value for settings.stickers.loop\n private group = '';\n\n private frInterval: number;\n private frThen: number;\n private rafId: number;\n\n //private caching = false;\n //private removed = false;\n\n private frames: RLottieCacheMap;\n private imageData: ImageData;\n public clamped: Uint8ClampedArray;\n private cachingDelta = 0;\n\n private initFrame: number;\n private color: RLottieColor;\n private inverseColor: RLottieColor;\n\n public minFrame: number;\n public maxFrame: number;\n\n //private playedTimes = 0;\n\n private currentMethod: RLottiePlayer['mainLoopForwards'] | RLottiePlayer['mainLoopBackwards'];\n private frameListener: (currentFrame: number) => void;\n private skipFirstFrameRendering: boolean;\n private playToFrameOnFrameCallback: (frameNo: number) => void;\n\n constructor({el, worker, options}: {\n el: HTMLElement,\n worker: QueryableWorker,\n options: RLottieOptions\n }) {\n super(true);\n\n this.reqId = ++RLottiePlayer['reqId'];\n this.el = el;\n this.worker = worker;\n\n for(let i in options) {\n if(this.hasOwnProperty(i)) {\n // @ts-ignore\n this[i] = options[i];\n }\n }\n\n this._loop = this.loop;\n this._autoplay = this.autoplay;\n\n // ! :(\n this.initFrame = options.initFrame;\n this.color = options.color;\n this.inverseColor = options.inverseColor;\n this.name = options.name;\n this.skipFirstFrameRendering = options.skipFirstFrameRendering;\n this.toneIndex = options.toneIndex;\n\n // * Skip ratio (30fps)\n let skipRatio: number;\n if(options.skipRatio !== undefined) skipRatio = options.skipRatio;\n else if((IS_ANDROID || IS_APPLE_MOBILE || (IS_APPLE && !IS_SAFARI)) && this.width < 100 && this.height < 100 && !options.needUpscale) {\n skipRatio = 0.5;\n }\n\n this.skipDelta = skipRatio !== undefined ? 1 / skipRatio | 0 : 1;\n\n //options.needUpscale = true;\n\n // * Pixel ratio\n //const pixelRatio = window.devicePixelRatio;\n const pixelRatio = clamp(window.devicePixelRatio, 1, 2);\n if(pixelRatio > 1) {\n //this.cachingEnabled = true;//this.width < 100 && this.height < 100;\n if(options.needUpscale) {\n this.width = Math.round(this.width * pixelRatio);\n this.height = Math.round(this.height * pixelRatio);\n } else if(pixelRatio > 1) {\n if(this.width > 100 && this.height > 100) {\n if(IS_APPLE || !mediaSizes.isMobile) {\n /* this.width = Math.round(this.width * (pixelRatio - 1));\n this.height = Math.round(this.height * (pixelRatio - 1)); */\n this.width = Math.round(this.width * pixelRatio);\n this.height = Math.round(this.height * pixelRatio);\n } else if(pixelRatio > 2.5) {\n this.width = Math.round(this.width * (pixelRatio - 1.5));\n this.height = Math.round(this.height * (pixelRatio - 1.5));\n }\n } else {\n this.width = Math.round(this.width * Math.max(1.5, pixelRatio - 1.5));\n this.height = Math.round(this.height * Math.max(1.5, pixelRatio - 1.5));\n }\n }\n }\n\n //options.noCache = true;\n \n // * Cache frames params\n if(!options.noCache/* && false */) {\n // проверка на размер уже после скейлинга, сделано для попапа и сайдбара, где стикеры 80х80 и 68х68, туда нужно 75%\n if(IS_APPLE && this.width > 100 && this.height > 100) {\n this.cachingDelta = 2; //2 // 50%\n } else if(this.width < 100 && this.height < 100) {\n this.cachingDelta = Infinity; // 100%\n } else {\n this.cachingDelta = 4; // 75%\n }\n }\n \n // this.cachingDelta = Infinity;\n // if(isApple) {\n // this.cachingDelta = 0; //2 // 50%\n // }\n\n /* this.width *= 0.8;\n this.height *= 0.8; */\n \n //console.log(\"RLottiePlayer width:\", this.width, this.height, options);\n if(!this.canvas) {\n this.canvas = document.createElement('canvas');\n this.canvas.classList.add('rlottie');\n this.canvas.width = this.width;\n this.canvas.height = this.height;\n }\n\n this.context = this.canvas.getContext('2d');\n\n if(CAN_USE_TRANSFERABLES) {\n this.clamped = new Uint8ClampedArray(this.width * this.height * 4);\n }\n\n this.imageData = new ImageData(this.width, this.height);\n\n if(this.name) {\n this.cacheName = cache.generateName(this.name, this.width, this.height, this.color, this.toneIndex);\n this.frames = cache.getCache(this.cacheName);\n } else {\n this.frames = new Map();\n }\n }\n\n public clearCache() {\n if(this.cachingDelta === Infinity) {\n return;\n }\n \n if(this.cacheName && cache.getCacheCounter(this.cacheName) > 1) { // skip clearing because same sticker can be still visible\n return;\n }\n \n this.frames.clear();\n }\n\n public sendQuery(methodName: string, ...args: any[]) {\n //console.trace('RLottie sendQuery:', methodName);\n this.worker.sendQuery(methodName, this.reqId, ...args);\n }\n\n public loadFromData(data: RLottieOptions['animationData']) {\n this.sendQuery('loadFromData', data, this.width, this.height, this.toneIndex/* , this.canvas.transferControlToOffscreen() */);\n }\n\n public play() {\n if(!this.paused) {\n return;\n }\n\n //return;\n\n //console.log('RLOTTIE PLAY' + this.reqId);\n\n this.paused = false;\n this.setMainLoop();\n }\n\n public pause(clearPendingRAF = true) {\n if(this.paused) {\n return;\n }\n\n this.paused = true;\n if(clearPendingRAF) {\n clearTimeout(this.rafId);\n }\n //window.cancelAnimationFrame(this.rafId);\n }\n\n private resetCurrentFrame() {\n return this.curFrame = this.initFrame ?? (this.direction === 1 ? this.minFrame : this.maxFrame);\n }\n\n public stop(renderFirstFrame = true) {\n this.pause();\n\n const curFrame = this.resetCurrentFrame();\n if(renderFirstFrame) {\n this.requestFrame(curFrame);\n //this.sendQuery('renderFrame', this.curFrame);\n }\n }\n\n public restart() {\n this.stop(false);\n this.play();\n }\n\n public setSpeed(speed: number) {\n if(this.speed === speed) {\n return;\n }\n\n this.speed = speed;\n\n if(!this.paused) {\n this.setMainLoop();\n }\n }\n\n public setDirection(direction: number) {\n if(this.direction === direction) {\n return;\n }\n\n this.direction = direction;\n \n if(!this.paused) {\n this.setMainLoop();\n }\n }\n\n public remove() {\n //alert('remove');\n lottieLoader.onDestroy(this.reqId);\n this.pause();\n this.sendQuery('destroy');\n if(this.cacheName) cache.releaseCache(this.cacheName);\n this.cleanup();\n //this.removed = true;\n }\n\n private applyColor(frame: Uint8ClampedArray) {\n const [r, g, b] = this.color;\n for(let i = 0, length = frame.length; i < length; i += 4) {\n if(frame[i + 3] !== 0) {\n frame[i] = r;\n frame[i + 1] = g;\n frame[i + 2] = b;\n }\n }\n }\n\n private applyInversing(frame: Uint8ClampedArray) {\n const [r, g, b] = this.inverseColor;\n for(let i = 0, length = frame.length; i < length; i += 4) {\n if(frame[i + 3] === 0) {\n frame[i] = r;\n frame[i + 1] = g;\n frame[i + 2] = b;\n frame[i + 3] = 255;\n } else {\n frame[i + 3] = 0;\n }\n }\n }\n\n public renderFrame2(frame: Uint8ClampedArray, frameNo: number) {\n /* this.setListenerResult('enterFrame', frameNo);\n return; */\n\n try {\n if(this.color) {\n this.applyColor(frame);\n }\n\n if(this.inverseColor) {\n this.applyInversing(frame);\n }\n\n this.imageData.data.set(frame);\n \n //this.context.putImageData(new ImageData(frame, this.width, this.height), 0, 0);\n //let perf = performance.now();\n this.context.putImageData(this.imageData, 0, 0);\n //console.log('renderFrame2 perf:', performance.now() - perf);\n } catch(err) {\n console.error('RLottiePlayer renderFrame error:', err/* , frame */, this.width, this.height);\n this.autoplay = false;\n this.pause();\n return;\n }\n \n //console.log('set result enterFrame', frameNo);\n this.dispatchEvent('enterFrame', frameNo);\n }\n\n public renderFrame(frame: Uint8ClampedArray, frameNo: number) {\n //console.log('renderFrame', frameNo, this);\n if(this.cachingDelta && (frameNo % this.cachingDelta || !frameNo) && !this.frames.has(frameNo)) {\n this.frames.set(frameNo, new Uint8ClampedArray(frame));//frame;\n }\n\n /* if(!this.listenerResults.hasOwnProperty('cached')) {\n this.setListenerResult('enterFrame', frameNo);\n if(frameNo === (this.frameCount - 1)) {\n this.setListenerResult('cached');\n }\n\n return;\n } */\n\n if(this.frInterval) {\n const now = Date.now(), delta = now - this.frThen;\n //console.log(`renderFrame delta${this.reqId}:`, this, delta, this.frInterval);\n\n if(delta < 0) {\n if(this.rafId) clearTimeout(this.rafId);\n return this.rafId = window.setTimeout(() => {\n this.renderFrame2(frame, frameNo);\n }, this.frInterval > -delta ? -delta % this.frInterval : this.frInterval);\n //await new Promise((resolve) => setTimeout(resolve, -delta % this.frInterval));\n }\n }\n\n this.renderFrame2(frame, frameNo);\n }\n\n public requestFrame(frameNo: number) {\n const frame = this.frames.get(frameNo);\n if(frame) {\n this.renderFrame(frame, frameNo);\n } else {\n if(this.clamped && !this.clamped.length) { // fix detached\n this.clamped = new Uint8ClampedArray(this.width * this.height * 4);\n }\n \n this.sendQuery('renderFrame', frameNo, this.clamped);\n }\n }\n\n private onLap() {\n //this.playedTimes++;\n\n if(!this.loop) {\n this.pause(false);\n return false;\n }\n\n return true;\n }\n\n private mainLoopForwards() {\n const {skipDelta, maxFrame} = this;\n const frame = (this.curFrame + skipDelta) > maxFrame ? this.curFrame = (this.loop ? this.minFrame : this.maxFrame) : this.curFrame += skipDelta;\n // console.log('mainLoopForwards', this.curFrame, skipDelta, frame);\n\n this.requestFrame(frame);\n if((frame + skipDelta) > maxFrame) {\n return this.onLap();\n }\n\n return true;\n }\n \n private mainLoopBackwards() {\n const {skipDelta, minFrame} = this;\n const frame = (this.curFrame - skipDelta) < minFrame ? this.curFrame = (this.loop ? this.maxFrame : this.minFrame) : this.curFrame -= skipDelta;\n // console.log('mainLoopBackwards', this.curFrame, skipDelta, frame);\n\n this.requestFrame(frame);\n if((frame - skipDelta) < minFrame) {\n return this.onLap();\n }\n\n return true;\n }\n\n public setMainLoop() {\n //window.cancelAnimationFrame(this.rafId);\n clearTimeout(this.rafId);\n\n this.frInterval = 1000 / this.fps / this.speed * this.skipDelta;\n this.frThen = Date.now() - this.frInterval;\n\n //console.trace('setMainLoop', this.frInterval, this.direction, this, JSON.stringify(this.listenerResults), this.listenerResults);\n\n const method = (this.direction === 1 ? this.mainLoopForwards : this.mainLoopBackwards).bind(this);\n this.currentMethod = method;\n //this.frameListener && this.removeListener('enterFrame', this.frameListener);\n\n //setTimeout(() => {\n //this.addListener('enterFrame', this.frameListener);\n //}, 0);\n\n if(this.frameListener) {\n const lastResult = this.listenerResults.enterFrame;\n if(lastResult !== undefined) {\n this.frameListener(this.curFrame);\n }\n }\n \n //this.mainLoop(method);\n //this.r(method);\n //method();\n }\n\n public playPart(options: {\n from: number, \n to: number, \n callback?: () => void\n }) {\n this.pause();\n\n const {from, to, callback} = options;\n this.curFrame = from - 1;\n\n return this.playToFrame({\n frame: to,\n direction: to > from ? 1 : -1,\n callback\n });\n }\n\n public playToFrame(options: {\n frame: number, \n speed?: number, \n direction?: number,\n callback?: () => void\n }) {\n this.pause();\n \n const {frame, speed, callback, direction} = options;\n this.setDirection(direction === undefined ? this.curFrame > frame ? -1 : 1 : direction);\n speed !== undefined && this.setSpeed(speed);\n\n const bounds = [this.curFrame, frame];\n if(this.direction === -1) bounds.reverse();\n \n this.loop = false;\n this.setMinMax(bounds[0], bounds[1]);\n\n if(this.playToFrameOnFrameCallback) {\n this.removeEventListener('enterFrame', this.playToFrameOnFrameCallback);\n }\n\n if(callback) {\n this.playToFrameOnFrameCallback = (frameNo: number) => {\n if(frameNo === frame) {\n this.removeEventListener('enterFrame', this.playToFrameOnFrameCallback);\n callback();\n }\n };\n\n this.addEventListener('enterFrame', this.playToFrameOnFrameCallback);\n }\n\n this.play();\n }\n\n public setColor(color: RLottieColor, renderIfPaused: boolean) {\n this.color = color;\n\n if(renderIfPaused && this.paused) {\n this.renderFrame2(this.imageData.data, this.curFrame);\n }\n }\n\n public setInverseColor(color: RLottieColor) {\n this.inverseColor = color;\n }\n\n private setMinMax(minFrame = 0, maxFrame = this.frameCount - 1) {\n this.minFrame = minFrame;\n this.maxFrame = maxFrame;\n }\n\n public async onLoad(frameCount: number, fps: number) {\n this.frameCount = frameCount;\n this.fps = fps;\n this.setMinMax();\n if(this.initFrame !== undefined) {\n this.initFrame = clamp(this.initFrame, this.minFrame, this.maxFrame);\n }\n\n const curFrame = this.resetCurrentFrame();\n\n // * Handle 30fps stickers if 30fps set\n if(this.fps < 60 && this.skipDelta !== 1) {\n const diff = 60 / fps;\n this.skipDelta = this.skipDelta / diff | 0;\n }\n\n this.frInterval = 1000 / this.fps / this.speed * this.skipDelta;\n this.frThen = Date.now() - this.frInterval;\n //this.sendQuery('renderFrame', 0);\n \n // Кешировать сразу не получится, рендер стикера (тайгер) занимает 519мс, \n // если рендерить 75% с получением каждого кадра из воркера, будет 475мс, т.е. при 100% было бы 593мс, потеря на передаче 84мс. \n\n /* console.time('cache' + this.reqId);\n for(let i = 0; i < frameCount; ++i) {\n //if(this.removed) return;\n \n if(i % 4) {\n await new Promise((resolve) => {\n delete this.listenerResults.enterFrame;\n this.addListener('enterFrame', resolve, true);\n this.requestFrame(i);\n }); \n }\n }\n \n console.timeEnd('cache' + this.reqId); */\n //console.log('cached');\n /* this.el.innerHTML = '';\n this.el.append(this.canvas);\n return; */\n\n !this.skipFirstFrameRendering && this.requestFrame(curFrame);\n this.dispatchEvent('ready');\n this.addEventListener('enterFrame', () => {\n this.dispatchEvent('firstFrame');\n\n if(!this.canvas.parentNode && this.el) {\n this.el.appendChild(this.canvas);\n }\n\n //console.log('enterFrame firstFrame');\n \n //let lastTime = this.frThen;\n this.frameListener = () => {\n if(this.paused) {\n return;\n }\n\n const time = Date.now();\n //console.log(`enterFrame handle${this.reqId}`, time, (time - lastTime), this.frInterval);\n /* if(Math.round(time - lastTime + this.frInterval * 0.25) < Math.round(this.frInterval)) {\n return;\n } */\n\n //lastTime = time;\n\n this.frThen = time + this.frInterval;\n const canContinue = this.currentMethod();\n if(!canContinue && !this.loop && this.autoplay) {\n this.autoplay = false;\n }\n };\n\n this.addEventListener('enterFrame', this.frameListener);\n\n // ! fix autoplaying since there will be no animationIntersector for it,\n if(this.group === 'none' && this.autoplay) {\n this.play();\n }\n }, {once: true});\n }\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n// * Jolly Cobra's schedulers\r\nimport { NoneToVoidFunction } from \"../types\";\r\n\r\n/*\r\nexport function throttleWithTickEnd(fn: F) {\r\n return throttleWith(onTickEnd, fn);\r\n}\r\n\r\nexport function throttleWithNow(fn: F) {\r\n return throttleWith(runNow, fn);\r\n}\r\n\r\nexport function onTickEnd(cb: NoneToVoidFunction) {\r\n Promise.resolve().then(cb);\r\n}\r\n\r\nfunction runNow(fn: NoneToVoidFunction) {\r\n fn();\r\n} */\r\n\r\nlet fastRafCallbacks: NoneToVoidFunction[] | undefined;\r\nexport function fastRaf(callback: NoneToVoidFunction) {\r\n if(!fastRafCallbacks) {\r\n fastRafCallbacks = [callback];\r\n\r\n requestAnimationFrame(() => {\r\n const currentCallbacks = fastRafCallbacks!;\r\n fastRafCallbacks = undefined;\r\n currentCallbacks.forEach((cb) => cb());\r\n });\r\n } else {\r\n fastRafCallbacks.push(callback);\r\n }\r\n}\r\n\r\nlet fastRafConventionalCallbacks: NoneToVoidFunction[] | undefined, processing = false;\r\nexport function fastRafConventional(callback: NoneToVoidFunction) {\r\n if(!fastRafConventionalCallbacks) {\r\n fastRafConventionalCallbacks = [callback];\r\n\r\n requestAnimationFrame(() => {\r\n processing = true;\r\n for(let i = 0; i < fastRafConventionalCallbacks.length; ++i) {\r\n fastRafConventionalCallbacks[i]();\r\n }\r\n\r\n fastRafConventionalCallbacks = undefined;\r\n processing = false;\r\n });\r\n } else if(processing) {\r\n callback();\r\n } else {\r\n fastRafConventionalCallbacks.push(callback);\r\n }\r\n}\r\n\r\nlet rafPromise: Promise;\r\nexport function fastRafPromise() {\r\n if(rafPromise) return rafPromise;\r\n\r\n rafPromise = new Promise(requestAnimationFrame);\r\n rafPromise.then(() => {\r\n rafPromise = undefined;\r\n });\r\n\r\n return rafPromise;\r\n}\r\n\r\nexport function doubleRaf() {\r\n return new Promise((resolve) => {\r\n fastRaf(() => {\r\n fastRaf(resolve);\r\n });\r\n });\r\n}\r\n","export default function Worker_fn() {\n return new Worker(__webpack_public_path__ + \"rlottie.worker.086dfed03cbca80766c6.bundle.worker.js\");\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport { IS_SAFARI } from \"../../environment/userAgent\";\nimport EventListenerBase from \"../../helpers/eventListenerBase\";\n\nexport default class QueryableWorker extends EventListenerBase<{\n ready: () => void,\n frame: (reqId: number, frameNo: number, frame: Uint8ClampedArray) => void,\n loaded: (reqId: number, frameCount: number, fps: number) => void,\n error: (reqId: number, error: Error) => void,\n workerError: (error: ErrorEvent) => void\n}> {\n constructor(private worker: Worker) {\n super();\n\n this.worker.onerror = (error) => {\n try {\n this.dispatchEvent('workerError', error);\n this.cleanup();\n this.terminate();\n } catch(err) {\n \n }\n };\n\n this.worker.onmessage = (event) => {\n this.dispatchEvent(event.data.queryMethodListener, ...event.data.queryMethodArguments);\n };\n }\n\n public postMessage(message: any) {\n this.worker.postMessage(message);\n }\n\n public terminate() {\n this.worker.terminate();\n }\n\n public sendQuery(queryMethod: string, ...args: any[]) {\n if(IS_SAFARI) {\n this.worker.postMessage({\n queryMethod: queryMethod,\n queryMethodArguments: args\n });\n } else {\n const transfer: (ArrayBuffer | OffscreenCanvas)[] = [];\n args.forEach(arg => {\n if(arg instanceof ArrayBuffer) {\n transfer.push(arg);\n }\n \n if(typeof(arg) === 'object' && arg.buffer instanceof ArrayBuffer) {\n transfer.push(arg.buffer);\n }\n });\n \n //console.log('transfer', transfer);\n this.worker.postMessage({\n queryMethod: queryMethod,\n queryMethodArguments: args\n }, transfer as Transferable[]);\n }\n }\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport RLottieWorker from 'worker-loader!./rlottie.worker';\r\nimport animationIntersector from \"../../components/animationIntersector\";\r\nimport { MOUNT_CLASS_TO } from '../../config/debug';\r\nimport { pause } from '../../helpers/schedulers/pause';\r\nimport { logger, LogTypes } from \"../logger\";\r\nimport apiManager from \"../mtproto/mtprotoworker\";\r\nimport RLottiePlayer, { RLottieOptions } from './rlottiePlayer';\r\nimport QueryableWorker from './queryableWorker';\r\nimport blobConstruct from '../../helpers/blob/blobConstruct';\r\n\r\nexport type LottieAssetName = 'EmptyFolder' | 'Folders_1' | 'Folders_2' | \r\n 'TwoFactorSetupMonkeyClose' | 'TwoFactorSetupMonkeyCloseAndPeek' | \r\n 'TwoFactorSetupMonkeyCloseAndPeekToIdle' | 'TwoFactorSetupMonkeyIdle' | \r\n 'TwoFactorSetupMonkeyPeek' | 'TwoFactorSetupMonkeyTracking' | \r\n 'voice_outlined2' | 'voip_filled' | 'voice_mini';\r\n\r\nexport class LottieLoader {\r\n private isWebAssemblySupported = typeof(WebAssembly) !== 'undefined';\r\n private loadPromise: Promise = !this.isWebAssemblySupported ? Promise.reject() : undefined;\r\n private loaded = false;\r\n\r\n private workersLimit = 4;\r\n private players: {[reqId: number]: RLottiePlayer} = {};\r\n\r\n private workers: QueryableWorker[] = [];\r\n private curWorkerNum = 0;\r\n\r\n private log = logger('LOTTIE', LogTypes.Error);\r\n\r\n public getAnimation(element: HTMLElement) {\r\n for(const i in this.players) {\r\n if(this.players[i].el === element) {\r\n return this.players[i];\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n public setLoop(loop: boolean) {\r\n for(const i in this.players) {\r\n const player = this.players[i];\r\n player.loop = loop;\r\n player.autoplay = player._autoplay;\r\n }\r\n }\r\n\r\n public loadLottieWorkers() {\r\n if(this.loadPromise) {\r\n return this.loadPromise;\r\n }\r\n\r\n return this.loadPromise = new Promise((resolve, reject) => {\r\n let remain = this.workersLimit;\r\n for(let i = 0; i < this.workersLimit; ++i) {\r\n const worker = this.workers[i] = new QueryableWorker(new RLottieWorker());\r\n\r\n worker.addEventListener('ready', () => {\r\n this.log('worker #' + i + ' ready');\r\n\r\n worker.addEventListener('frame', this.onFrame);\r\n worker.addEventListener('loaded', this.onPlayerLoaded);\r\n worker.addEventListener('error', this.onPlayerError);\r\n\r\n --remain;\r\n if(!remain) {\r\n this.log('workers ready');\r\n resolve();\r\n this.loaded = true;\r\n }\r\n }, {once: true});\r\n\r\n worker.addEventListener('workerError', (error) => {\r\n reject('rlottie load error: ' + error.message);\r\n this.loaded = false;\r\n }, {once: true});\r\n }\r\n });\r\n }\r\n\r\n public loadAnimationAsAsset(params: Omit, name: LottieAssetName) {\r\n (params as RLottieOptions).name = name;\r\n return this.loadAnimationFromURL(params, 'assets/tgs/' + name + '.json');\r\n }\r\n\r\n public loadAnimationFromURL(params: Omit, url: string): Promise {\r\n if(!this.isWebAssemblySupported) {\r\n return this.loadPromise as any;\r\n }\r\n \r\n if(!this.loaded) {\r\n this.loadLottieWorkers();\r\n }\r\n\r\n return fetch(url)\r\n .then(res => {\r\n if(!res.headers || res.headers.get('content-type') === 'application/octet-stream') {\r\n return res.arrayBuffer().then(data => apiManager.invokeCrypto('gzipUncompress', data)).then(arr => blobConstruct([arr], ''))\r\n } else {\r\n return res.blob();\r\n }\r\n })\r\n /* .then(str => {\r\n return new Promise((resolve) => setTimeout(() => resolve(str), 2e3));\r\n }) */\r\n .then(blob => {\r\n const newParams = Object.assign(params, {animationData: blob, needUpscale: true});\r\n if(!newParams.name) newParams.name = url;\r\n return this.loadAnimationWorker(newParams);\r\n });\r\n }\r\n\r\n public waitForFirstFrame(player: RLottiePlayer) {\r\n return Promise.race([\r\n /* new Promise((resolve) => {\r\n player.addEventListener('firstFrame', () => {\r\n setTimeout(() => resolve(), 1500);\r\n }, true);\r\n }) */\r\n new Promise((resolve) => {\r\n player.addEventListener('firstFrame', resolve, {once: true});\r\n }),\r\n pause(2500)\r\n ]).then(() => player);\r\n }\r\n\r\n public async loadAnimationWorker(params: RLottieOptions, group = params.group || '', middleware?: () => boolean): Promise {\r\n if(!this.isWebAssemblySupported) {\r\n return this.loadPromise as any;\r\n }\r\n //params.autoplay = true;\r\n\r\n if(!this.loaded) {\r\n await this.loadLottieWorkers();\r\n }\r\n\r\n if(middleware && !middleware()) {\r\n throw new Error('middleware');\r\n }\r\n\r\n if(!params.width || !params.height) {\r\n params.width = parseInt(params.container.style.width);\r\n params.height = parseInt(params.container.style.height);\r\n }\r\n\r\n if(!params.width || !params.height) {\r\n throw new Error('No size for sticker!');\r\n }\r\n\r\n params.group = group;\r\n\r\n const player = this.initPlayer(params.container, params);\r\n\r\n if(group !== 'none') {\r\n animationIntersector.addAnimation(player, group);\r\n }\r\n\r\n return player;\r\n }\r\n\r\n private onPlayerLoaded = (reqId: number, frameCount: number, fps: number) => {\r\n const rlPlayer = this.players[reqId];\r\n if(!rlPlayer) {\r\n this.log.warn('onPlayerLoaded on destroyed player:', reqId, frameCount);\r\n return;\r\n }\r\n\r\n this.log.debug('onPlayerLoaded');\r\n rlPlayer.onLoad(frameCount, fps);\r\n //rlPlayer.addListener('firstFrame', () => {\r\n //animationIntersector.addAnimation(player, group);\r\n //}, true);\r\n };\r\n\r\n private onFrame = (reqId: number, frameNo: number, frame: Uint8ClampedArray) => {\r\n const rlPlayer = this.players[reqId];\r\n if(!rlPlayer) {\r\n this.log.warn('onFrame on destroyed player:', reqId, frameNo);\r\n return;\r\n }\r\n\r\n if(rlPlayer.clamped !== undefined) {\r\n rlPlayer.clamped = frame;\r\n }\r\n \r\n rlPlayer.renderFrame(frame, frameNo);\r\n };\r\n\r\n private onPlayerError = (reqId: number, error: Error) => {\r\n const rlPlayer = this.players[reqId];\r\n if(rlPlayer) {\r\n // ! will need refactoring later, this is not the best way to remove the animation\r\n const animations = animationIntersector.getAnimations(rlPlayer.el);\r\n animations.forEach(animation => {\r\n animationIntersector.checkAnimation(animation, true, true);\r\n });\r\n }\r\n };\r\n\r\n public onDestroy(reqId: number) {\r\n delete this.players[reqId];\r\n }\r\n\r\n public destroyWorkers() {\r\n this.workers.forEach((worker, idx) => {\r\n worker.terminate();\r\n this.log('worker #' + idx + ' terminated');\r\n });\r\n\r\n this.log('workers destroyed');\r\n this.workers.length = 0;\r\n }\r\n\r\n private initPlayer(el: HTMLElement, options: RLottieOptions) {\r\n const rlPlayer = new RLottiePlayer({\r\n el, \r\n worker: this.workers[this.curWorkerNum++],\r\n options\r\n });\r\n\r\n this.players[rlPlayer.reqId] = rlPlayer;\r\n if(this.curWorkerNum >= this.workers.length) {\r\n this.curWorkerNum = 0;\r\n }\r\n\r\n rlPlayer.loadFromData(options.animationData);\r\n\r\n return rlPlayer;\r\n }\r\n}\r\n\r\nconst lottieLoader = new LottieLoader();\r\nMOUNT_CLASS_TO.lottieLoader = lottieLoader;\r\nexport default lottieLoader;\r\n","export default function indexOfAndSplice(array: Array, item: T) {\n const idx = array.indexOf(item);\n const spliced = idx !== -1 && array.splice(idx, 1);\n return spliced && spliced[0];\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport rootScope from \"../lib/rootScope\";\r\nimport { IS_SAFARI } from \"../environment/userAgent\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport isInDOM from \"../helpers/dom/isInDOM\";\r\nimport RLottiePlayer from \"../lib/rlottie/rlottiePlayer\";\r\nimport indexOfAndSplice from \"../helpers/array/indexOfAndSplice\";\r\nimport forEachReverse from \"../helpers/array/forEachReverse\";\r\n\r\nexport interface AnimationItem {\r\n el: HTMLElement,\r\n group: string,\r\n animation: RLottiePlayer | HTMLVideoElement\r\n};\r\n\r\nexport class AnimationIntersector {\r\n private observer: IntersectionObserver;\r\n private visible: Set = new Set();\r\n\r\n private overrideIdleGroups: Set;\r\n private byGroups: {[group: string]: AnimationItem[]} = {};\r\n private lockedGroups: {[group: string]: true} = {};\r\n private onlyOnePlayableGroup: string = '';\r\n \r\n private intersectionLockedGroups: {[group: string]: true} = {};\r\n private videosLocked = false;\r\n\r\n constructor() {\r\n this.observer = new IntersectionObserver((entries) => {\r\n // if(rootScope.idle.isIDLE) return;\r\n\r\n for(const entry of entries) {\r\n const target = entry.target;\r\n\r\n for(const group in this.byGroups) {\r\n if(this.intersectionLockedGroups[group]) {\r\n continue;\r\n }\r\n\r\n const player = this.byGroups[group].find(p => p.el === target);\r\n if(player) {\r\n if(entry.isIntersecting) {\r\n this.visible.add(player);\r\n this.checkAnimation(player, false);\r\n } else {\r\n this.visible.delete(player);\r\n this.checkAnimation(player, true);\r\n\r\n if(player.animation instanceof RLottiePlayer/* && player.animation.cachingDelta === 2 */) {\r\n //console.warn('will clear cache', player);\r\n player.animation.clearCache();\r\n }\r\n }\r\n\r\n break;\r\n }\r\n }\r\n }\r\n });\r\n\r\n this.overrideIdleGroups = new Set();\r\n\r\n rootScope.addEventListener('media_play', ({doc}) => {\r\n if(doc.type === 'round') {\r\n this.videosLocked = true;\r\n this.checkAnimations();\r\n }\r\n });\r\n\r\n rootScope.addEventListener('media_pause', () => {\r\n if(this.videosLocked) {\r\n this.videosLocked = false;\r\n this.checkAnimations();\r\n }\r\n });\r\n }\r\n\r\n public setOverrideIdleGroup(group: string, override: boolean) {\r\n if(override) this.overrideIdleGroups.add(group);\r\n else this.overrideIdleGroups.delete(group);\r\n }\r\n\r\n public getAnimations(element: HTMLElement) {\r\n const found: AnimationItem[] = [];\r\n for(const group in this.byGroups) {\r\n for(const player of this.byGroups[group]) {\r\n if(player.el === element) {\r\n found.push(player);\r\n }\r\n }\r\n }\r\n\r\n return found;\r\n }\r\n\r\n public removeAnimation(player: AnimationItem) {\r\n //console.log('destroy animation');\r\n const {el, animation} = player;\r\n animation.remove();\r\n\r\n if(animation instanceof HTMLVideoElement && IS_SAFARI) {\r\n setTimeout(() => { // TODO: очистка по очереди, а не все вместе с этим таймаутом\r\n animation.src = '';\r\n animation.load();\r\n }, 1e3);\r\n }\r\n\r\n const group = this.byGroups[player.group];\r\n if(group) {\r\n indexOfAndSplice(group, player);\r\n if(!group.length) {\r\n delete this.byGroups[player.group];\r\n }\r\n }\r\n \r\n this.observer.unobserve(el);\r\n this.visible.delete(player);\r\n }\r\n\r\n public addAnimation(animation: RLottiePlayer | HTMLVideoElement, group = '') {\r\n const player = {\r\n el: animation instanceof RLottiePlayer ? animation.el : animation, \r\n animation: animation, \r\n group\r\n };\r\n\r\n if(animation instanceof RLottiePlayer) {\r\n if(!rootScope.settings.stickers.loop && animation.loop) {\r\n animation.loop = rootScope.settings.stickers.loop;\r\n }\r\n }\r\n\r\n (this.byGroups[group] ?? (this.byGroups[group] = [])).push(player);\r\n this.observer.observe(player.el);\r\n }\r\n\r\n public checkAnimations(blurred?: boolean, group?: string, destroy = false) {\r\n // if(rootScope.idle.isIDLE) return;\r\n\r\n if(group !== undefined && !this.byGroups[group]) {\r\n //console.warn('no animation group:', group);\r\n return;\r\n }\r\n \r\n const groups = group !== undefined /* && false */ ? [group] : Object.keys(this.byGroups);\r\n\r\n for(const group of groups) {\r\n const animations = this.byGroups[group];\r\n\r\n forEachReverse(animations, (player) => {\r\n this.checkAnimation(player, blurred, destroy);\r\n });\r\n }\r\n }\r\n\r\n public checkAnimation(player: AnimationItem, blurred = false, destroy = false) {\r\n const {el, animation, group} = player;\r\n //return;\r\n if((destroy || (!isInDOM(el) && !this.lockedGroups[group]))/* && false */) {\r\n this.removeAnimation(player);\r\n return;\r\n }\r\n\r\n if(blurred || (this.onlyOnePlayableGroup && this.onlyOnePlayableGroup !== group) || (animation instanceof HTMLVideoElement && this.videosLocked)) {\r\n if(!animation.paused) {\r\n //console.warn('pause animation:', animation);\r\n animation.pause();\r\n }\r\n } else if(animation.paused && \r\n this.visible.has(player) && \r\n animation.autoplay && \r\n (!this.onlyOnePlayableGroup || this.onlyOnePlayableGroup === group) &&\r\n (!rootScope.idle.isIDLE || this.overrideIdleGroups.has(player.group))\r\n ) {\r\n //console.warn('play animation:', animation);\r\n animation.play();\r\n }\r\n }\r\n\r\n public setOnlyOnePlayableGroup(group: string) {\r\n this.onlyOnePlayableGroup = group;\r\n }\r\n\r\n public lockGroup(group: string) {\r\n this.lockedGroups[group] = true;\r\n }\r\n\r\n public unlockGroup(group: string) {\r\n delete this.lockedGroups[group];\r\n this.checkAnimations(undefined, group);\r\n }\r\n\r\n public refreshGroup(group: string) {\r\n const animations = this.byGroups[group];\r\n if(animations && animations.length) {\r\n animations.forEach(animation => {\r\n this.observer.unobserve(animation.el);\r\n });\r\n\r\n window.requestAnimationFrame(() => {\r\n animations.forEach(animation => {\r\n this.observer.observe(animation.el);\r\n });\r\n });\r\n }\r\n }\r\n\r\n public lockIntersectionGroup(group: string) {\r\n this.intersectionLockedGroups[group] = true;\r\n }\r\n\r\n public unlockIntersectionGroup(group: string) {\r\n delete this.intersectionLockedGroups[group];\r\n this.refreshGroup(group);\r\n }\r\n}\r\n\r\nconst animationIntersector = new AnimationIntersector();\r\nif(MOUNT_CLASS_TO) {\r\n MOUNT_CLASS_TO.animationIntersector = animationIntersector;\r\n}\r\nexport default animationIntersector;\r\n","export default function forEachReverse(array: Array, callback: (value: T, index?: number, array?: Array) => void) {\n for(let length = array.length, i = length - 1; i >= 0; --i) {\n callback(array[i], i, array);\n }\n};\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport Page from \"./page\";\r\nimport lottieLoader from \"../lib/rlottie/lottieLoader\";\r\nimport { horizontalMenu } from \"../components/horizontalMenu\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport fastSmoothScroll from \"../helpers/fastSmoothScroll\";\r\nimport whichChild from \"../helpers/dom/whichChild\";\r\n\r\nclass PagesManager {\r\n private pageId = -1;\r\n private page: Page;\r\n\r\n private selectTab: ReturnType;\r\n public pagesDiv: HTMLDivElement;\r\n public scrollableDiv: HTMLElement;\r\n\r\n constructor() {\r\n this.pagesDiv = document.getElementById('auth-pages') as HTMLDivElement;\r\n this.scrollableDiv = this.pagesDiv.querySelector('.scrollable') as HTMLElement;\r\n this.selectTab = horizontalMenu(null, this.scrollableDiv.querySelector('.tabs-container') as HTMLDivElement, null, () => {\r\n if(this.page?.onShown) {\r\n this.page.onShown();\r\n }\r\n });\r\n }\r\n\r\n public setPage(page: Page) {\r\n if(page.isAuthPage) {\r\n this.pagesDiv.style.display = '';\r\n\r\n let id = whichChild(page.pageEl);\r\n if(this.pageId === id) return;\r\n\r\n this.selectTab(id);\r\n\r\n if(this.pageId !== -1 && id > 1) {\r\n lottieLoader.loadLottieWorkers();\r\n }\r\n\r\n\r\n\r\n this.pageId = id;\r\n\r\n if(this.scrollableDiv) {\r\n fastSmoothScroll({\r\n container: this.scrollableDiv, \r\n element: this.scrollableDiv.firstElementChild as HTMLElement, \r\n position: 'start'\r\n });\r\n }\r\n } else {\r\n this.pagesDiv.style.display = 'none';\r\n page.pageEl.style.display = '';\r\n\r\n this.pageId = -1;\r\n }\r\n\r\n this.page = page;\r\n }\r\n}\r\n\r\nconst pagesManager = new PagesManager();\r\nMOUNT_CLASS_TO.pagesManager = pagesManager;\r\nexport default pagesManager;\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nimport pagesManager from \"./pagesManager\";\r\n\r\nexport default class Page {\r\n public pageEl: HTMLDivElement;\r\n private installed = false;\r\n\r\n constructor(className: string, public isAuthPage: boolean, private onFirstMount?: (...args: any[]) => Promise | void, private onMount?: (...args: any[]) => void, public onShown?: () => void) {\r\n this.pageEl = document.body.querySelector('.' + className) as HTMLDivElement;\r\n }\r\n\r\n public async mount(...args: any[]) {\r\n //this.pageEl.style.display = '';\r\n\r\n if(this.onMount) {\r\n this.onMount(...args);\r\n }\r\n\r\n if(!this.installed) {\r\n if(this.onFirstMount) {\r\n try {\r\n const res = this.onFirstMount(...args);\r\n if(res instanceof Promise) {\r\n await res;\r\n }\r\n } catch(err) {\r\n console.error('PAGE MOUNT ERROR:', err);\r\n }\r\n }\r\n \r\n this.installed = true;\r\n }\r\n\r\n pagesManager.setPage(this);\r\n }\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n// * Jolly Cobra's useHeavyAnimationCheck.ts, patched\r\n\r\nimport { AnyToVoidFunction } from '../types';\r\nimport ListenerSetter from '../helpers/listenerSetter';\r\nimport { CancellablePromise, deferredPromise } from '../helpers/cancellablePromise';\r\nimport rootScope from '../lib/rootScope';\r\nimport DEBUG from '../config/debug';\r\nimport { pause } from '../helpers/schedulers/pause';\r\n\r\nconst ANIMATION_START_EVENT = 'event-heavy-animation-start';\r\nconst ANIMATION_END_EVENT = 'event-heavy-animation-end';\r\n\r\nlet isAnimating = false;\r\nlet heavyAnimationPromise: CancellablePromise = deferredPromise();\r\nlet promisesInQueue = 0;\r\n\r\nheavyAnimationPromise.resolve();\r\n\r\nconst log = console.log.bind(console.log, '[HEAVY-ANIMATION]:');\r\n\r\nexport function dispatchHeavyAnimationEvent(promise: Promise, timeout?: number) {\r\n if(!isAnimating) {\r\n heavyAnimationPromise = deferredPromise();\r\n rootScope.dispatchEvent(ANIMATION_START_EVENT);\r\n isAnimating = true;\r\n DEBUG && log('start');\r\n }\r\n \r\n ++promisesInQueue;\r\n DEBUG && log('attach promise, length:', promisesInQueue, timeout);\r\n\r\n const promises = [\r\n timeout !== undefined ? pause(timeout) : undefined,\r\n promise.finally(() => {})\r\n ].filter(Boolean);\r\n\r\n const perf = performance.now();\r\n const _heavyAnimationPromise = heavyAnimationPromise;\r\n Promise.race(promises).then(() => {\r\n if(heavyAnimationPromise !== _heavyAnimationPromise || heavyAnimationPromise.isFulfilled) { // interrupted\r\n return;\r\n }\r\n\r\n --promisesInQueue;\r\n DEBUG && log('promise end, length:', promisesInQueue, performance.now() - perf);\r\n if(promisesInQueue <= 0) {\r\n onHeavyAnimationEnd();\r\n }\r\n });\r\n\r\n return heavyAnimationPromise;\r\n}\r\n\r\nfunction onHeavyAnimationEnd() {\r\n if(heavyAnimationPromise.isFulfilled) {\r\n return;\r\n }\r\n\r\n isAnimating = false;\r\n promisesInQueue = 0;\r\n rootScope.dispatchEvent(ANIMATION_END_EVENT);\r\n heavyAnimationPromise.resolve();\r\n\r\n DEBUG && log('end');\r\n}\r\n\r\nexport function interruptHeavyAnimation() {\r\n onHeavyAnimationEnd();\r\n}\r\n\r\nexport function getHeavyAnimationPromise() {\r\n return heavyAnimationPromise;\r\n}\r\n\r\nexport default function(\r\n handleAnimationStart: AnyToVoidFunction,\r\n handleAnimationEnd: AnyToVoidFunction,\r\n listenerSetter?: ListenerSetter\r\n) {\r\n //useEffect(() => {\r\n if(isAnimating) {\r\n handleAnimationStart();\r\n }\r\n\r\n const add = listenerSetter ? listenerSetter.add(rootScope) : rootScope.addEventListener.bind(rootScope);\r\n const remove = listenerSetter ? listenerSetter.removeManual.bind(listenerSetter, rootScope) : rootScope.removeEventListener.bind(rootScope);\r\n add(ANIMATION_START_EVENT, handleAnimationStart);\r\n add(ANIMATION_END_EVENT, handleAnimationEnd);\r\n\r\n return () => {\r\n remove(ANIMATION_END_EVENT, handleAnimationEnd);\r\n remove(ANIMATION_START_EVENT, handleAnimationStart);\r\n };\r\n //}, [handleAnimationEnd, handleAnimationStart]);\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n// * Jolly Cobra's fastSmoothScroll slightly patched\r\n\r\nimport { dispatchHeavyAnimationEvent } from '../hooks/useHeavyAnimationCheck';\r\nimport { fastRaf } from './schedulers';\r\nimport { animateSingle, cancelAnimationByKey } from './animation';\r\nimport rootScope from '../lib/rootScope';\r\nimport isInDOM from './dom/isInDOM';\r\n\r\nconst MIN_JS_DURATION = 250;\r\nconst MAX_JS_DURATION = 600;\r\nconst LONG_TRANSITION_MAX_DISTANCE = 1500;\r\nconst SHORT_TRANSITION_MAX_DISTANCE = 500;\r\n\r\nexport enum FocusDirection {\r\n Up,\r\n Down,\r\n Static,\r\n};\r\n\r\nexport type ScrollGetNormalSizeCallback = (options: {rect: DOMRect}) => number;\r\n\r\nexport type ScrollOptions = {\r\n container: HTMLElement,\r\n element: HTMLElement,\r\n position: ScrollLogicalPosition,\r\n margin?: number,\r\n maxDistance?: number,\r\n forceDirection?: FocusDirection,\r\n forceDuration?: number,\r\n axis?: 'x' | 'y',\r\n getNormalSize?: ScrollGetNormalSizeCallback,\r\n fallbackToElementStartWhenCentering?: HTMLElement\r\n};\r\n\r\nexport default function fastSmoothScroll(options: ScrollOptions) {\r\n if(options.margin === undefined) {\r\n options.margin = 0;\r\n }\r\n\r\n if(options.maxDistance === undefined) {\r\n options.maxDistance = LONG_TRANSITION_MAX_DISTANCE;\r\n }\r\n\r\n if(options.axis === undefined) {\r\n options.axis = 'y';\r\n }\r\n //return;\r\n\r\n if(!rootScope.settings.animationsEnabled) {\r\n options.forceDirection = FocusDirection.Static;\r\n }\r\n\r\n if(options.forceDirection === FocusDirection.Static) {\r\n options.forceDuration = 0;\r\n return scrollWithJs(options);\r\n /* return Promise.resolve();\r\n\r\n element.scrollIntoView({ block: position });\r\n\r\n cancelAnimationByKey(container);\r\n return Promise.resolve(); */\r\n }\r\n\r\n const promise = new Promise((resolve) => {\r\n fastRaf(() => {\r\n scrollWithJs(options).then(resolve);\r\n });\r\n });\r\n\r\n return options.axis === 'y' ? dispatchHeavyAnimationEvent(promise) : promise;\r\n}\r\n\r\nfunction scrollWithJs(options: ScrollOptions): Promise {\r\n const {element, container, getNormalSize, axis, margin, position, forceDirection, maxDistance, forceDuration} = options;\r\n if(!isInDOM(element)) {\r\n cancelAnimationByKey(container);\r\n return Promise.resolve();\r\n }\r\n \r\n const rectStartKey = axis === 'y' ? 'top' : 'left';\r\n const rectEndKey = axis === 'y' ? 'bottom' : 'right';\r\n const sizeKey = axis === 'y' ? 'height' : 'width';\r\n const scrollSizeKey = axis === 'y' ? 'scrollHeight' : 'scrollWidth';\r\n const scrollPositionKey = axis === 'y' ? 'scrollTop' : 'scrollLeft';\r\n\r\n //const { offsetTop: elementTop, offsetHeight: elementHeight } = element;\r\n const elementRect = element.getBoundingClientRect();\r\n const containerRect = container.getBoundingClientRect ? container.getBoundingClientRect() : document.body.getBoundingClientRect();\r\n\r\n //const transformable = container.firstElementChild as HTMLElement;\r\n\r\n const elementPosition = elementRect[rectStartKey] - containerRect[rectStartKey];\r\n const elementSize = element[scrollSizeKey]; // margin is exclusive in DOMRect\r\n\r\n const containerSize = getNormalSize ? getNormalSize({rect: containerRect}) : containerRect[sizeKey];\r\n\r\n let scrollPosition = container[scrollPositionKey];\r\n const scrollSize = container[scrollSizeKey];\r\n /* const elementPosition = element.offsetTop;\r\n const elementSize = element.offsetHeight;\r\n\r\n const scrollPosition = container[scrollPositionKey];\r\n const scrollSize = container[scrollSizeKey];\r\n const containerSize = container.offsetHeight; */\r\n\r\n let path!: number;\r\n\r\n switch(position) {\r\n case 'start':\r\n path = elementPosition - margin;\r\n break;\r\n case 'end':\r\n path = elementRect[rectEndKey] /* + (elementSize - elementRect[sizeKey]) */ - containerRect[rectEndKey] + margin;\r\n break;\r\n // 'nearest' is not supported yet\r\n case 'nearest':\r\n case 'center':\r\n if(elementSize < containerSize) {\r\n path = (elementPosition + elementSize / 2) - (containerSize / 2);\r\n } else {\r\n if(options.fallbackToElementStartWhenCentering && options.fallbackToElementStartWhenCentering !== element) {\r\n options.element = options.fallbackToElementStartWhenCentering;\r\n options.position = 'start';\r\n return scrollWithJs(options);\r\n }\r\n\r\n path = elementPosition - margin;\r\n }\r\n\r\n break;\r\n }\r\n /* switch (position) {\r\n case 'start':\r\n path = (elementPosition - margin) - scrollPosition;\r\n break;\r\n case 'end':\r\n path = (elementPosition + elementSize + margin) - (scrollPosition + containerSize);\r\n break;\r\n // 'nearest' is not supported yet\r\n case 'nearest':\r\n case 'center':\r\n path = elementSize < containerSize\r\n ? (elementPosition + elementSize / 2) - (scrollPosition + containerSize / 2)\r\n : (elementPosition - margin) - scrollPosition;\r\n break;\r\n } */\r\n\r\n if(Math.abs(path - (margin || 0)) < 1) {\r\n cancelAnimationByKey(container);\r\n return Promise.resolve();\r\n }\r\n\r\n if(axis === 'y') {\r\n if(forceDirection === undefined) {\r\n if(path > maxDistance) {\r\n scrollPosition = container.scrollTop += path - maxDistance;\r\n path = maxDistance;\r\n } else if(path < -maxDistance) {\r\n scrollPosition = container.scrollTop += path + maxDistance;\r\n path = -maxDistance;\r\n }\r\n }/* else if(forceDirection === FocusDirection.Up) { // * not tested yet\r\n container.scrollTop = offsetTop + container.scrollTop + maxDistance;\r\n } else if(forceDirection === FocusDirection.Down) { // * not tested yet\r\n container.scrollTop = Math.max(0, offsetTop + container.scrollTop - maxDistance);\r\n } */\r\n }\r\n\r\n // console.log('scrollWithJs: will scroll path:', path, element);\r\n\r\n /* let existsTransform = 0;\r\n const currentTransform = transformable.style.transform;\r\n if(currentTransform) {\r\n existsTransform = parseInt(currentTransform.match(/\\((.+?), (.+?), .+\\)/)[2]);\r\n //path += existsTransform;\r\n } */\r\n\r\n if(path < 0) {\r\n const remainingPath = -scrollPosition;\r\n path = Math.max(path, remainingPath);\r\n } else if(path > 0) {\r\n const remainingPath = scrollSize - (scrollPosition + containerSize);\r\n path = Math.min(path, remainingPath);\r\n }\r\n\r\n const target = container[scrollPositionKey] + path;\r\n const absPath = Math.abs(path);\r\n const duration = forceDuration ?? (\r\n MIN_JS_DURATION + (absPath / LONG_TRANSITION_MAX_DISTANCE) * (MAX_JS_DURATION - MIN_JS_DURATION)\r\n );\r\n const startAt = Date.now();\r\n\r\n /* transformable.classList.add('no-transition');\r\n\r\n const tickTransform = () => {\r\n const t = duration ? Math.min((Date.now() - startAt) / duration, 1) : 1;\r\n const currentPath = path * transition(t);\r\n\r\n transformable.style.transform = `translate3d(0, ${-currentPath}px, 0)`;\r\n container.dataset.translate = '' + -currentPath;\r\n\r\n const willContinue = t < 1;\r\n if(!willContinue) {\r\n fastRaf(() => {\r\n delete container.dataset.transform;\r\n container.dataset.transform = '';\r\n transformable.style.transform = '';\r\n void transformable.offsetLeft; // reflow\r\n transformable.classList.remove('no-transition');\r\n void transformable.offsetLeft; // reflow\r\n container[scrollPositionKey] = Math.round(target);\r\n });\r\n }\r\n\r\n return willContinue;\r\n };\r\n \r\n return animateSingle(tickTransform, container); */\r\n\r\n /* return new Promise((resolve) => {\r\n fastRaf(() => {\r\n transformable.style.transform = '';\r\n transformable.style.transition = '';\r\n\r\n setTimeout(resolve, duration);\r\n });\r\n });\r\n\r\n const transformableHeight = transformable.scrollHeight;\r\n //transformable.style.minHeight = `${transformableHeight}px`;\r\n */\r\n\r\n const transition = absPath < SHORT_TRANSITION_MAX_DISTANCE ? shortTransition : longTransition;\r\n const tick = () => {\r\n const t = duration ? Math.min((Date.now() - startAt) / duration, 1) : 1;\r\n\r\n const currentPath = path * (1 - transition(t));\r\n container[scrollPositionKey] = Math.round(target - currentPath);\r\n \r\n return t < 1;\r\n };\r\n\r\n if(!duration || !path) {\r\n cancelAnimationByKey(container);\r\n tick();\r\n return Promise.resolve();\r\n }\r\n\r\n /* return new Promise((resolve) => {\r\n setTimeout(resolve, duration);\r\n }).then(() => {\r\n transformable.classList.add('no-transition');\r\n void transformable.offsetLeft; // reflow\r\n transformable.style.transform = '';\r\n transformable.style.transition = '';\r\n void transformable.offsetLeft; // reflow\r\n transformable.classList.remove('no-transition');\r\n void transformable.offsetLeft; // reflow\r\n fastRaf(() => {\r\n \r\n container[scrollPositionKey] = Math.round(target);\r\n //transformable.style.minHeight = ``;\r\n });\r\n \r\n }); */\r\n\r\n return animateSingle(tick, container);\r\n}\r\n\r\nfunction longTransition(t: number) {\r\n return 1 - ((1 - t) ** 5);\r\n}\r\n\r\nfunction shortTransition(t: number) {\r\n return 1 - ((1 - t) ** 3.5);\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n * \r\n * Originally from:\r\n * https://github.com/zhukov/webogram\r\n * Copyright (C) 2014 Igor Zhukov \r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\n/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {\r\n if(!element) {\r\n return false;\r\n }\r\n\r\n parentNode = parentNode || document.body;\r\n if(element === parentNode) {\r\n return true;\r\n }\r\n return isInDOM(element.parentNode as HTMLElement, parentNode);\r\n} */\r\nexport default function isInDOM(element: Element): boolean {\r\n return element?.isConnected;\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nexport default function whichChild(elem: Node) {\r\n if(!elem.parentNode) {\r\n return -1;\r\n }\r\n \r\n let i = 0;\r\n // @ts-ignore\r\n while((elem = elem.previousElementSibling) !== null) ++i;\r\n return i;\r\n}\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\nexport default function findUpAsChild(el: any, parent: any) {\r\n if(el.parentElement === parent) return el;\r\n \r\n while(el.parentElement) {\r\n el = el.parentElement;\r\n if(el.parentElement === parent) {\r\n return el;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n"],"sourceRoot":""}