tweb/public/15.b14001265d6da1e62429.chunk.js.map
Eduard Kuzmenko 10b7307141 Build
2022-01-25 10:36:42 +04:00

1 line
127 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"version":3,"sources":["webpack:///./src/components/languageChangeButton.ts","webpack:///./src/helpers/fixBase64String.ts","webpack:///./src/components/telInputField.ts","webpack:///./src/components/ripple.ts","webpack:///./src/pages/pageSignIn.ts","webpack:///./src/pages/pageSignQR.ts","webpack:///./src/helpers/dom/clickEvent.ts","webpack:///./src/components/button.ts","webpack:///./src/components/misc.ts","webpack:///./src/components/scrollable.ts","webpack:///./src/components/appNavigationController.ts","webpack:///./src/components/checkboxField.ts","webpack:///./src/helpers/dom/toggleDisability.ts","webpack:///./src/helpers/bytes.ts","webpack:///./src/helpers/dom/dispatchEvent.ts","webpack:///./src/helpers/dom/findUpTag.ts","webpack:///./src/helpers/sequentialDom.ts","webpack:///./src/lib/mtproto/serverTimeManager.ts","webpack:///./src/helpers/dom/placeCaretAtEnd.ts","webpack:///./src/helpers/dom/isSwipingBackSafari.ts","webpack:///./src/helpers/formatPhoneNumber.ts"],"names":["cachedPromise","set","getLanguageChangeButton","appendTo","getConfig","then","config","suggested_lang_code","lastRequestedLangCode","Promise","all","getStrings","getCacheLangPack","strings","backup","forEach","string","backupString","get","key","push","btnChangeLanguage","text","lastElementChild","classList","remove","window","requestAnimationFrame","append","addEventListener","once","e","disabled","getLangPack","fixBase64String","str","toUrl","replace","TelInputField","options","super","label","name","pasted","lastValue","this","container","add","telEl","input","HTMLInputElement","type","autocomplete","inputMode","pixelRatio","devicePixelRatio","letterSpacing","style","setProperty","originalFunc","setValueSilently","bind","value","formattedPhoneNumber","Math","abs","length","setLabel","formatted","country","countryCode","leftPattern","code","dataset","onInput","test","metaKey","ctrlKey","shiftKey","preventDefault","rippleClickId","ripple","elem","callback","resolve","onEnd","prepend","attachListenerTo","querySelector","r","document","createElement","handler","contains","drawRipple","clientX","clientY","startTime","Date","now","clickId","duration","getComputedStyle","getPropertyValue","elapsedTime","cb","mutate","delay","max","setTimeout","removeEventListener","touchStartFired","rect","getBoundingClientRect","clickX","left","clickY","top","size","sqrt","height","width","x","y","isRippleUnneeded","target","includes","tagName","touchEnd","settings","animationsEnabled","touches","cancelBubble","stopPropagation","passive","button","btnQr","btnNext","page","setCountries","countries","countriesList","filter","pFlags","hidden","sort","a","b","default_name","localeCompare","liMap","Map","lastCountrySelected","lastCountryCodeSelected","inputWrapper","countryInputField","countryInput","selectWrapper","arrowDown","selectList","appendChild","initSelect","c","emoji","iso2","liArr","country_codes","li","wrapped","wrapEmojiText","spanEmoji","innerHTML","el","defaultName","span","innerText","country_code","selectCountryByTarget","childNodes","phoneCode","find","_countryCode","telInputField","hidePicker","focus","hideTimeout","display","clearTimeout","undefined","offsetWidth","select","pageEl","parentElement","element","position","margin","mouseDownHandlerAttached","onMouseDown","capture","_value","toLowerCase","matches","good","Boolean","indexOf","blur","loadLottieWorkers","countryName","visibility","onSubmit","signedCheckboxField","withRipple","checked","keepSigned","pushToState","toggleStorage","getState","state","storage","isAvailable","toggle","phone_number","invokeApi","api_id","id","api_hash","hash","_","m","default","mount","Object","assign","catch","err","setError","console","error","h4","subtitle","nearestDcResult","langPack","getFromCache","lang_code","dcs","Set","done","this_dc","promise","nearest_dc","getNetworker","dcId","delete","_dcs","g","shift","dbKey","finally","removeAttribute","imageDiv","preloader","btnBack","helpList","stop","QRCodeStyling","prevToken","ignoreErrors","iterate","isLoop","loginToken","except_ids","dc_id","setBaseDcId","token","authorization","setUser","user","encoded","url","documentElement","surfaceColor","trim","textColor","primaryColor","logoUrl","fetch","res","blob","Blob","reader","FileReader","onload","result","readAsDataURL","qrCode","data","image","dotsOptions","color","cornersSquareOptions","imageOptions","imageSize","backgroundOptions","qrOptions","errorCorrectionLevel","lastChild","_drawingPromise","race","_canvas","_image","animation","children","Array","from","slice","timestamp","diff","expires","serverTimeOffset","warn","handled","func","CLICK_EVENT_NAME","attachClickEvent","listenerSetter","touchMouseDown","detachClickEvent","simulateClickEvent","className","asDiv","icon","noRipple","rippleSquare","onlyMobile","setAttribute","putPreloader","returnDiv","html","div","insertAdjacentHTML","setButtonLoader","onMouseMove","openedMenu","diffX","right","diffY","bottom","closeBtnMenu","onClick","menuOverlay","dispatchEvent","openedMenuOnClose","removeByType","openBtnMenu","menuElement","onClose","pushItem","onPop","canAnimate","insertBefore","positionMenu","pageX","pageY","side","scrollWidth","menuWidth","scrollHeight","menuHeight","body","windowWidth","windowHeight","isMobile","verticalSide","sides","intermediateX","intermediateY","possibleSides","_cancelContextMenuOpening","_cancelContextMenuOpeningTimeout","cancelContextMenuOpening","attachContextMenuListener","removeManual","timeout","onCancel","ScrollableBase","logPrefix","onScrollMeasure","isHeavyAnimationInProgress","needCheckAfterAnimation","log","Error","onScroll","cancelAnimationFrame","Scrollable","onScrollOffset","withPaddingContainer","lastScrollTop","lastScrollDirection","loadedAll","onScrolledTop","onScrolledBottom","splitUp","onAdditionalScroll","scrollTop","checkForTriggers","maxScrollTop","clientHeight","setListeners","elements","padding","round","offsetHeight","getDistanceToEnd","ScrollableX","splitCount","scrollHorizontally","deltaX","clientWidth","scrollLeft","deltaY","appNavigationController","navigations","manual","debug","currentHash","location","isPossibleSwipe","onHashChange","replaceState","pushState","item","pop","handleItem","onEscape","back","history","scrollRestoration","noBlurOnPop","i","index","ret","findItemByType","backByItem","splice","noHistory","origin","pathname","single","CheckboxField","restriction","toggleDisability","stateKey","stateValue","stateValues","setByKey","textArgs","box","checkSvg","createElementNS","setAttributeNS","use","bg","border","withHover","event","Event","bubbles","cancelable","disable","bytesToHex","bytes","arr","toString","join","bytesFromHex","hexString","len","Uint8Array","ceil","start","parseInt","charAt","substr","bytesToBase64","mod3","nLen","nUint24","nIdx","String","fromCharCode","uint6ToBase64","nUint6","bytesCmp","bytes1","bytes2","bytesXor","convertToUint8Array","TextEncoder","encode","bufferConcats","args","reduce","acc","v","byteLength","tmp","lastLength","ArrayBuffer","bytesFromWordss","o","bytesToWordss","words","Uint32Array","simulateEvent","findUpTag","tag","closest","sequentialDom","promises","raf","scheduled","kind","scheduleFlush","do","read","write","serverTimeManager","to","addTaskListener","task","payload","placeCaretAtEnd","ignoreTouchCheck","activeElement","getSelection","createRange","range","selectNodeContents","collapse","sel","removeAllRanges","addRange","createTextRange","textRange","moveToElementText","isSwipingBackSafari","TouchEvent","prefixes","maxPrefixLength","setPrefix","prefix","formatPhoneNumber","originalStr","prefixCountry","patterns","searchForPattern","pattern","mostMatchedPatternMatches","mostMatchedPattern","_pattern","patternMatches","k","min","split","symbol","idx"],"mappings":"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","file":"15.b14001265d6da1e62429.chunk.js","sourcesContent":["/*\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 { cancelEvent } from \"../helpers/dom/cancelEvent\";\nimport { attachClickEvent } from \"../helpers/dom/clickEvent\";\nimport loadFonts from \"../helpers/dom/loadFonts\";\nimport { Config, LangPackDifference, LangPackString } from \"../layer\";\nimport I18n, { LangPackKey } from \"../lib/langPack\";\nimport apiManager from \"../lib/mtproto/mtprotoworker\";\nimport rootScope from \"../lib/rootScope\";\nimport Button from \"./button\";\nimport { putPreloader } from \"./misc\";\n\nlet set = false;\n\nfunction getLang(): Promise<[Config.config, LangPackString[], LangPackDifference.langPackDifference]> {\n if(cachedPromise) return cachedPromise;\n return cachedPromise = apiManager.getConfig().then(config => {\n if(config.suggested_lang_code !== I18n.lastRequestedLangCode) {\n //I18n.loadLangPack(config.suggested_lang_code);\n\n return Promise.all([\n config,\n I18n.getStrings(config.suggested_lang_code, ['Login.ContinueOnLanguage']),\n I18n.getCacheLangPack()\n ]);\n } else {\n return [] as any;\n }\n });\n}\n\nlet cachedPromise: ReturnType<typeof getLang>;\n\nexport default function getLanguageChangeButton(appendTo: HTMLElement) {\n if(set) return;\n getLang().then(([config, strings]) => {\n if(!config) {\n return;\n }\n\n const backup: LangPackString[] = [];\n strings.forEach(string => {\n const backupString = I18n.strings.get(string.key as LangPackKey);\n if(!backupString) {\n return;\n }\n \n backup.push(backupString);\n I18n.strings.set(string.key as LangPackKey, string);\n });\n\n const btnChangeLanguage = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.ContinueOnLanguage'});\n btnChangeLanguage.lastElementChild.classList.remove('i18n'); // prevent changing language\n loadFonts().then(() => {\n window.requestAnimationFrame(() => {\n appendTo.append(btnChangeLanguage);\n });\n });\n\n rootScope.addEventListener('language_change', () => {\n btnChangeLanguage.remove();\n }, {once: true});\n\n backup.forEach(string => {\n I18n.strings.set(string.key as LangPackKey, string);\n });\n \n attachClickEvent(btnChangeLanguage, (e) => {\n cancelEvent(e);\n\n set = true;\n\n btnChangeLanguage.disabled = true;\n putPreloader(btnChangeLanguage);\n\n I18n.getLangPack(config.suggested_lang_code);\n });\n });\n}\n","export default function fixBase64String(str: string, toUrl: boolean) {\n if(toUrl) {\n return str.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/\\=+$/, '');\n } else {\n return str.replace(/-/g, '+').replace(/_/g, '/');\n }\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 placeCaretAtEnd from \"../helpers/dom/placeCaretAtEnd\";\nimport { formatPhoneNumber } from \"../helpers/formatPhoneNumber\";\nimport { IS_APPLE, IS_ANDROID, IS_APPLE_MOBILE } from \"../environment/userAgent\";\nimport { HelpCountry, HelpCountryCode } from \"../layer\";\nimport InputField, { InputFieldOptions } from \"./inputField\";\n\nexport default class TelInputField extends InputField {\n private pasted = false;\n public lastValue = '';\n \n constructor(options: InputFieldOptions & {\n onInput?: (formatted: ReturnType<typeof formatPhoneNumber>) => void\n } = {}) {\n super({\n label: 'Contacts.PhoneNumber.Placeholder',\n //plainText: true,\n name: 'phone',\n ...options\n });\n\n this.container.classList.add('input-field-phone');\n\n let telEl = this.input;\n if(telEl instanceof HTMLInputElement) {\n telEl.type = 'tel';\n telEl.autocomplete = 'rr55RandomRR55';\n } else {\n telEl.inputMode = 'decimal';\n\n const pixelRatio = window.devicePixelRatio;\n if(pixelRatio > 1) {\n let letterSpacing: number;\n if(IS_APPLE) {\n letterSpacing = pixelRatio * -.16;\n } else if(IS_ANDROID) {\n letterSpacing = 0;\n }\n\n telEl.style.setProperty('--letter-spacing', letterSpacing + 'px');\n }\n\n const originalFunc = this.setValueSilently.bind(this);\n this.setValueSilently = (value) => {\n originalFunc(value);\n placeCaretAtEnd(this.input, true);\n };\n }\n\n telEl.addEventListener('input', () => {\n //console.log('input', this.value);\n telEl.classList.remove('error');\n \n const value = this.value;\n const diff = Math.abs(value.length - this.lastValue.length);\n if(diff > 1 && !this.pasted && IS_APPLE_MOBILE) {\n this.setValueSilently(this.lastValue + value);\n }\n \n this.pasted = false;\n \n this.setLabel();\n \n let formattedPhoneNumber: ReturnType<typeof formatPhoneNumber>;\n let formatted: string, country: HelpCountry, countryCode: HelpCountryCode, leftPattern = '';\n if(this.value.replace(/\\++/, '+') === '+') {\n this.setValueSilently('+');\n } else {\n formattedPhoneNumber = formatPhoneNumber(this.value);\n formatted = formattedPhoneNumber.formatted;\n country = formattedPhoneNumber.country;\n leftPattern = formattedPhoneNumber.leftPattern;\n countryCode = formattedPhoneNumber.code;\n this.setValueSilently(this.lastValue = formatted ? '+' + formatted : '');\n }\n \n telEl.dataset.leftPattern = leftPattern/* .replace(/X/g, '0') */;\n \n //console.log(formatted, country);\n\n options.onInput && options.onInput(formattedPhoneNumber);\n });\n \n telEl.addEventListener('paste', () => {\n this.pasted = true;\n //console.log('paste', telEl.value);\n });\n \n /* telEl.addEventListener('change', (e) => {\n console.log('change', telEl.value);\n }); */\n \n telEl.addEventListener('keypress', (e) => {\n //console.log('keypress', this.value);\n const key = e.key;\n if(/\\D/.test(key) && !(e.metaKey || e.ctrlKey) && key !== 'Backspace' && !(key === '+' && e.shiftKey/* && !this.value */)) {\n e.preventDefault();\n return false;\n }\n });\n \n /* telEl.addEventListener('focus', function(this: typeof telEl, e) {\n this.removeAttribute('readonly'); // fix autocomplete\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 findUpClassName from \"../helpers/dom/findUpClassName\";\r\nimport sequentialDom from \"../helpers/sequentialDom\";\r\nimport {IS_TOUCH_SUPPORTED} from \"../environment/touchSupport\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport findUpAsChild from \"../helpers/dom/findUpAsChild\";\r\n\r\nlet rippleClickId = 0;\r\nexport function ripple(\r\n elem: HTMLElement, \r\n callback: (id: number) => Promise<boolean | void> = () => Promise.resolve(), \r\n onEnd: (id: number) => void = null, \r\n prepend = false,\r\n attachListenerTo = elem\r\n) {\r\n //return;\r\n if(elem.querySelector('.c-ripple')) return;\r\n elem.classList.add('rp');\r\n \r\n let r = document.createElement('div');\r\n r.classList.add('c-ripple');\r\n\r\n const isSquare = elem.classList.contains('rp-square');\r\n if(isSquare) {\r\n r.classList.add('is-square');\r\n }\r\n\r\n elem[prepend ? 'prepend' : 'append'](r);\r\n\r\n let handler: () => void;\r\n //let animationEndPromise: Promise<number>;\r\n const drawRipple = (clientX: number, clientY: number) => {\r\n const startTime = Date.now();\r\n const elem = document.createElement('div');\r\n\r\n const clickId = rippleClickId++;\r\n \r\n //console.log('ripple drawRipple');\r\n \r\n const duration = +window.getComputedStyle(r).getPropertyValue('--ripple-duration').replace('s', '') * 1000;\r\n //console.log('ripple duration', duration);\r\n\r\n handler = () => {\r\n //handler = () => animationEndPromise.then((duration) => {\r\n //console.log('ripple animation was:', duration);\r\n\r\n //const duration = isSquare || mediaSizes.isMobile ? 200 : 700;\r\n //return;\r\n let elapsedTime = Date.now() - startTime;\r\n const cb = () => {\r\n //console.log('ripple elapsedTime total pre-remove:', Date.now() - startTime);\r\n sequentialDom.mutate(() => {\r\n elem.remove();\r\n });\r\n \r\n if(onEnd) onEnd(clickId);\r\n };\r\n if(elapsedTime < duration) {\r\n let delay = Math.max(duration - elapsedTime, duration / 2);\r\n setTimeout(() => elem.classList.add('hiding'), Math.max(delay - duration / 2, 0));\r\n\r\n setTimeout(cb, delay);\r\n } else {\r\n elem.classList.add('hiding');\r\n setTimeout(cb, duration / 2);\r\n }\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.removeEventListener('contextmenu', handler);\r\n }\r\n\r\n handler = null;\r\n touchStartFired = false;\r\n };\r\n //});\r\n\r\n callback && callback(clickId);\r\n\r\n /* callback().then((bad) => {\r\n if(bad) {\r\n span.remove();\r\n return;\r\n } */\r\n \r\n //console.log('ripple after promise', Date.now() - startTime);\r\n //console.log('ripple tooSlow:', tooSlow);\r\n /* if(tooSlow) {\r\n span.remove();\r\n return;\r\n } */\r\n\r\n window.requestAnimationFrame(() => {\r\n const rect = r.getBoundingClientRect();\r\n elem.classList.add('c-ripple__circle');\r\n\r\n const clickX = clientX - rect.left;\r\n const clickY = clientY - rect.top;\r\n\r\n const radius = Math.sqrt((Math.abs(clickY - rect.height / 2) + rect.height / 2) ** 2 + (Math.abs(clickX - rect.width / 2) + rect.width / 2) ** 2);\r\n const size = radius;\r\n\r\n // center of circle\r\n const x = clickX - size / 2;\r\n const y = clickY - size / 2;\r\n\r\n //console.log('ripple click', offsetFromCenter, size, clickX, clickY);\r\n\r\n elem.style.width = elem.style.height = size + 'px';\r\n elem.style.left = x + 'px';\r\n elem.style.top = y + 'px';\r\n\r\n // нижний код выполняется с задержкой\r\n /* animationEndPromise = new Promise((resolve) => {\r\n span.addEventListener('animationend', () => {\r\n // 713 -> 700\r\n resolve(((Date.now() - startTime) / 100 | 0) * 100);\r\n }, {once: true});\r\n }); */\r\n \r\n // нижний код не всегда включает анимацию ПРИ КЛИКЕ НА ТАЧПАД БЕЗ ТАПТИК ЭНЖИНА\r\n /* span.style.display = 'none';\r\n r.append(span);\r\n duration = +window.getComputedStyle(span).getPropertyValue('animation-duration').replace('s', '') * 1000;\r\n span.style.display = ''; */\r\n\r\n r.append(elem);\r\n\r\n //r.classList.add('active');\r\n //handler();\r\n });\r\n //});\r\n };\r\n\r\n const isRippleUnneeded = (e: Event) => e.target !== elem && (\r\n ['BUTTON', 'A'].includes((e.target as HTMLElement).tagName) \r\n || findUpClassName(e.target as HTMLElement, 'c-ripple') !== r\r\n ) && (\r\n attachListenerTo === elem \r\n || !findUpAsChild(e.target, attachListenerTo)\r\n );\r\n\r\n // TODO: rename this variable\r\n let touchStartFired = false;\r\n if(IS_TOUCH_SUPPORTED) {\r\n let touchEnd = () => {\r\n handler && handler();\r\n };\r\n \r\n attachListenerTo.addEventListener('touchstart', (e) => {\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n\r\n //console.log('ripple touchstart', e);\r\n if(e.touches.length > 1 || touchStartFired || isRippleUnneeded(e)) {\r\n return;\r\n }\r\n \r\n //console.log('touchstart', e);\r\n touchStartFired = true;\r\n \r\n let {clientX, clientY} = e.touches[0];\r\n drawRipple(clientX, clientY);\r\n attachListenerTo.addEventListener('touchend', touchEnd, {once: true});\r\n \r\n window.addEventListener('touchmove', (e) => {\r\n e.cancelBubble = true;\r\n e.stopPropagation();\r\n touchEnd();\r\n attachListenerTo.removeEventListener('touchend', touchEnd);\r\n }, {once: true});\r\n }, {passive: true});\r\n } else {\r\n attachListenerTo.addEventListener('mousedown', (e) => {\r\n if(![0, 2].includes(e.button)) { // only left and right buttons\r\n return;\r\n }\r\n\r\n if(!rootScope.settings.animationsEnabled) {\r\n return;\r\n }\r\n //console.log('ripple mousedown', e, e.target, findUpClassName(e.target as HTMLElement, 'c-ripple') === r);\r\n\r\n if(attachListenerTo.dataset.ripple === '0' || isRippleUnneeded(e)) {\r\n return;\r\n } else if(touchStartFired) {\r\n touchStartFired = false;\r\n return;\r\n }\r\n \r\n let {clientX, clientY} = e;\r\n drawRipple(clientX, clientY);\r\n window.addEventListener('mouseup', handler, {once: true, passive: true});\r\n window.addEventListener('contextmenu', handler, {once: true, passive: true});\r\n }, {passive: true});\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 { putPreloader } from \"../components/misc\";\r\nimport Scrollable from '../components/scrollable';\r\nimport appStateManager from \"../lib/appManagers/appStateManager\";\r\nimport apiManager from \"../lib/mtproto/mtprotoworker\";\r\nimport { RichTextProcessor } from '../lib/richtextprocessor';\r\nimport Page from \"./page\";\r\nimport InputField from \"../components/inputField\";\r\nimport CheckboxField from \"../components/checkboxField\";\r\nimport Button from \"../components/button\";\r\nimport fastSmoothScroll from \"../helpers/fastSmoothScroll\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport App from \"../config/app\";\r\nimport I18n, { _i18n, i18n } from \"../lib/langPack\";\r\nimport lottieLoader from \"../lib/rlottie/lottieLoader\";\r\nimport { ripple } from \"../components/ripple\";\r\nimport findUpTag from \"../helpers/dom/findUpTag\";\r\nimport findUpClassName from \"../helpers/dom/findUpClassName\";\r\nimport { randomLong } from \"../helpers/random\";\r\nimport AppStorage from \"../lib/storage\";\r\nimport CacheStorageController from \"../lib/cacheStorage\";\r\nimport pageSignQR from \"./pageSignQR\";\r\nimport getLanguageChangeButton from \"../components/languageChangeButton\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { attachClickEvent } from \"../helpers/dom/clickEvent\";\r\nimport replaceContent from \"../helpers/dom/replaceContent\";\r\nimport toggleDisability from \"../helpers/dom/toggleDisability\";\r\nimport sessionStorage from \"../lib/sessionStorage\";\r\nimport { DcAuthKey } from \"../types\";\r\nimport placeCaretAtEnd from \"../helpers/dom/placeCaretAtEnd\";\r\nimport { HelpCountry, HelpCountryCode } from \"../layer\";\r\nimport { getCountryEmoji } from \"../vendor/emoji\";\r\nimport simulateEvent from \"../helpers/dom/dispatchEvent\";\r\nimport stateStorage from \"../lib/stateStorage\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport TelInputField from \"../components/telInputField\";\r\nimport IS_EMOJI_SUPPORTED from \"../environment/emojiSupport\";\r\n\r\n//import _countries from '../countries_pretty.json';\r\nlet btnNext: HTMLButtonElement = null, btnQr: HTMLButtonElement;\r\n\r\nlet onFirstMount = () => {\r\n /* if(Modes.test) {\r\n Countries.push({\r\n _: 'help.country',\r\n default_name: 'Test Country',\r\n country_codes: [{\r\n _: 'help.countryCode',\r\n country_code: '999 66',\r\n patterns: ['999 66 XXX XX']\r\n }],\r\n iso2: 'KK'\r\n });\r\n \r\n console.log('Added test country to list!');\r\n } */\r\n\r\n //const countries: Country[] = _countries.default.filter(c => c.emoji);\r\n // const countries: Country[] = Countries.filter(c => c.emoji).sort((a, b) => a.name.localeCompare(b.name));\r\n // const countries = I18n.countriesList.filter(country => !country.pFlags?.hidden);\r\n const setCountries = () => {\r\n countries = I18n.countriesList\r\n .filter(country => !country.pFlags?.hidden)\r\n .sort((a, b) => (a.name || a.default_name).localeCompare(b.name || b.default_name));\r\n };\r\n let countries: HelpCountry.helpCountry[]; \r\n\r\n setCountries();\r\n\r\n rootScope.addEventListener('language_change', () => {\r\n setCountries();\r\n });\r\n\r\n const liMap: Map<string, HTMLLIElement[]> = new Map();\r\n\r\n let lastCountrySelected: HelpCountry, lastCountryCodeSelected: HelpCountryCode;\r\n\r\n const inputWrapper = document.createElement('div');\r\n inputWrapper.classList.add('input-wrapper');\r\n\r\n const countryInputField = new InputField({\r\n label: 'Login.CountrySelectorLabel',\r\n name: randomLong()\r\n });\r\n\r\n countryInputField.container.classList.add('input-select');\r\n\r\n const countryInput = countryInputField.input;\r\n // countryInput.autocomplete = randomLong();\r\n\r\n const selectWrapper = document.createElement('div');\r\n selectWrapper.classList.add('select-wrapper', 'z-depth-3', 'hide');\r\n\r\n const arrowDown = document.createElement('span');\r\n arrowDown.classList.add('arrow', 'arrow-down');\r\n countryInputField.container.append(arrowDown);\r\n\r\n const selectList = document.createElement('ul');\r\n selectWrapper.appendChild(selectList);\r\n\r\n const scroll = new Scrollable(selectWrapper);\r\n\r\n let initSelect = () => {\r\n initSelect = null;\r\n\r\n countries.forEach((c) => {\r\n const emoji = getCountryEmoji(c.iso2);\r\n\r\n const liArr: Array<HTMLLIElement> = [];\r\n c.country_codes.forEach((countryCode) => {\r\n const li = document.createElement('li');\r\n\r\n let wrapped = RichTextProcessor.wrapEmojiText(emoji);\r\n if(IS_EMOJI_SUPPORTED) {\r\n const spanEmoji = document.createElement('span');\r\n spanEmoji.innerHTML = wrapped;\r\n li.append(spanEmoji);\r\n } else {\r\n li.innerHTML = wrapped;\r\n }\r\n \r\n const el = i18n(c.default_name as any);\r\n el.dataset.defaultName = c.default_name;\r\n li.append(el);\r\n\r\n const span = document.createElement('span');\r\n span.classList.add('phone-code');\r\n span.innerText = '+' + countryCode.country_code;\r\n li.appendChild(span);\r\n\r\n liArr.push(li);\r\n selectList.append(li);\r\n });\r\n\r\n liMap.set(c.iso2, liArr);\r\n });\r\n \r\n selectList.addEventListener('mousedown', (e) => {\r\n if(e.button !== 0) { // other buttons but left shall not pass\r\n return;\r\n }\r\n \r\n const target = findUpTag(e.target, 'LI')\r\n selectCountryByTarget(target);\r\n //console.log('clicked', e, countryName, phoneCode);\r\n });\r\n\r\n countryInputField.container.appendChild(selectWrapper);\r\n };\r\n\r\n const selectCountryByTarget = (target: HTMLElement) => {\r\n const defaultName = (target.childNodes[1] as HTMLElement).dataset.defaultName;\r\n const phoneCode = target.querySelector<HTMLElement>('.phone-code').innerText;\r\n const countryCode = phoneCode.replace(/\\D/g, '');\r\n\r\n replaceContent(countryInput, i18n(defaultName as any));\r\n simulateEvent(countryInput, 'input');\r\n lastCountrySelected = countries.find(c => c.default_name === defaultName);\r\n lastCountryCodeSelected = lastCountrySelected.country_codes.find(_countryCode => _countryCode.country_code === countryCode);\r\n \r\n telInputField.value = telInputField.lastValue = phoneCode;\r\n hidePicker();\r\n setTimeout(() => {\r\n telEl.focus();\r\n placeCaretAtEnd(telEl, true);\r\n }, 0);\r\n };\r\n \r\n initSelect();\r\n\r\n let hideTimeout: number;\r\n\r\n countryInput.addEventListener('focus', function(this: typeof countryInput, e) {\r\n if(initSelect) {\r\n initSelect();\r\n } else {\r\n countries.forEach((c) => {\r\n liMap.get(c.iso2).forEach(li => li.style.display = '');\r\n });\r\n }\r\n\r\n clearTimeout(hideTimeout);\r\n hideTimeout = undefined;\r\n\r\n selectWrapper.classList.remove('hide');\r\n void selectWrapper.offsetWidth; // reflow\r\n selectWrapper.classList.add('active');\r\n\r\n countryInputField.select();\r\n\r\n fastSmoothScroll({\r\n container: page.pageEl.parentElement.parentElement, \r\n element: countryInput, \r\n position: 'start', \r\n margin: 4\r\n });\r\n\r\n setTimeout(() => {\r\n if(!mouseDownHandlerAttached) {\r\n document.addEventListener('mousedown', onMouseDown, {capture: true});\r\n mouseDownHandlerAttached = true;\r\n }\r\n }, 0);\r\n });\r\n\r\n let mouseDownHandlerAttached = false;\r\n const onMouseDown = (e: MouseEvent) => {\r\n if(findUpClassName(e.target, 'input-select')) {\r\n return;\r\n }\r\n if(e.target === countryInput) {\r\n return;\r\n }\r\n\r\n hidePicker();\r\n document.removeEventListener('mousedown', onMouseDown, {capture: true});\r\n mouseDownHandlerAttached = false;\r\n };\r\n\r\n const hidePicker = () => {\r\n if(hideTimeout !== undefined) return;\r\n selectWrapper.classList.remove('active');\r\n hideTimeout = window.setTimeout(() => {\r\n selectWrapper.classList.add('hide');\r\n hideTimeout = undefined;\r\n }, 200);\r\n };\r\n /* false && countryInput.addEventListener('blur', function(this: typeof countryInput, e) {\r\n hidePicker();\r\n \r\n e.cancelBubble = true;\r\n }, {capture: true}); */\r\n\r\n countryInput.addEventListener('keyup', (e) => {\r\n const key = e.key;\r\n if(e.ctrlKey || key === 'Control') return false;\r\n\r\n //let i = new RegExp('^' + this.value, 'i');\r\n let _value = countryInputField.value.toLowerCase();\r\n let matches: HelpCountry[] = [];\r\n countries.forEach((c) => {\r\n let good = !![c.name, c.default_name].filter(Boolean).find(str => str.toLowerCase().indexOf(_value) !== -1)/* === 0 */;//i.test(c.name);\r\n\r\n liMap.get(c.iso2).forEach(li => li.style.display = good ? '' : 'none');\r\n if(good) matches.push(c);\r\n });\r\n\r\n // Код ниже автоматически выберет страну если она осталась одна при поиске\r\n /* if(matches.length === 1 && matches[0].li.length === 1) {\r\n if(matches[0].name === lastCountrySelected) return false;\r\n //console.log('clicking', matches[0]);\r\n\r\n var clickEvent = document.createEvent('MouseEvents');\r\n clickEvent.initEvent('mousedown', true, true);\r\n matches[0].li[0].dispatchEvent(clickEvent);\r\n return false;\r\n } else */if(matches.length === 0) {\r\n countries.forEach((c) => {\r\n liMap.get(c.iso2).forEach(li => li.style.display = '');\r\n });\r\n } else if(matches.length === 1 && key === 'Enter') {\r\n selectCountryByTarget(liMap.get(matches[0].iso2)[0]);\r\n }\r\n });\r\n\r\n arrowDown.addEventListener('mousedown', function(this: typeof arrowDown, e) {\r\n e.cancelBubble = true;\r\n e.preventDefault();\r\n if(countryInput.matches(':focus')) countryInput.blur();\r\n else countryInput.focus();\r\n });\r\n\r\n const telInputField = new TelInputField({\r\n onInput: (formatted) => {\r\n lottieLoader.loadLottieWorkers();\r\n\r\n const {country, code} = formatted || {};\r\n let countryName = country ? country.name || country.default_name : ''/* 'Unknown' */;\r\n if(countryName !== countryInputField.value && (\r\n !lastCountrySelected || \r\n !country ||\r\n !code || (\r\n lastCountrySelected !== country && \r\n lastCountryCodeSelected.country_code !== code.country_code\r\n )\r\n )\r\n ) {\r\n replaceContent(countryInput, country ? i18n(country.default_name as any) : countryName);\r\n lastCountrySelected = country;\r\n lastCountryCodeSelected = code;\r\n }\r\n \r\n //if(country && (telInputField.value.length - 1) >= (country.pattern ? country.pattern.length : 9)) {\r\n if(country || (telInputField.value.length - 1) > 1) {\r\n btnNext.style.visibility = '';\r\n } else {\r\n btnNext.style.visibility = 'hidden';\r\n }\r\n }\r\n });\r\n\r\n const telEl = telInputField.input;\r\n\r\n telEl.addEventListener('keypress', (e) => {\r\n //console.log('keypress', this.value);\r\n if(!btnNext.style.visibility &&/* this.value.length >= 9 && */ e.key === 'Enter') {\r\n return onSubmit();\r\n }\r\n });\r\n\r\n /* telEl.addEventListener('focus', function(this: typeof telEl, e) {\r\n this.removeAttribute('readonly'); // fix autocomplete\r\n });*/\r\n\r\n const signedCheckboxField = new CheckboxField({\r\n text: 'Login.KeepSigned', \r\n name: 'keepSession',\r\n withRipple: true,\r\n checked: true\r\n });\r\n\r\n signedCheckboxField.input.addEventListener('change', () => {\r\n const keepSigned = signedCheckboxField.checked;\r\n appStateManager.pushToState('keepSigned', keepSigned);\r\n \r\n AppStorage.toggleStorage(keepSigned);\r\n CacheStorageController.toggleStorage(keepSigned);\r\n apiManager.toggleStorage(keepSigned);\r\n sessionStorage.toggleStorage(keepSigned);\r\n });\r\n\r\n appStateManager.getState().then(state => {\r\n if(!appStateManager.storage.isAvailable()) {\r\n signedCheckboxField.checked = false;\r\n signedCheckboxField.label.classList.add('checkbox-disabled');\r\n } else {\r\n signedCheckboxField.checked = state.keepSigned;\r\n }\r\n });\r\n\r\n btnNext = Button('btn-primary btn-color-primary', {text: 'Login.Next'});\r\n btnNext.style.visibility = 'hidden';\r\n\r\n const onSubmit = (e?: Event) => {\r\n if(e) {\r\n cancelEvent(e);\r\n }\r\n\r\n const toggle = toggleDisability([/* telEl, countryInput, */btnNext, btnQr], true);\r\n\r\n replaceContent(btnNext, i18n('PleaseWait'));\r\n putPreloader(btnNext);\r\n\r\n //return;\r\n\r\n let phone_number = telInputField.value;\r\n apiManager.invokeApi('auth.sendCode', {\r\n phone_number: phone_number,\r\n api_id: App.id,\r\n api_hash: App.hash,\r\n settings: {\r\n _: 'codeSettings' // that's how we sending Type\r\n }\r\n //lang_code: navigator.language || 'en'\r\n }).then((code) => {\r\n //console.log('got code', code);\r\n\r\n import('./pageAuthCode').then(m => m.default.mount(Object.assign(code, {phone_number: phone_number})));\r\n }).catch(err => {\r\n toggle();\r\n\r\n switch(err.type) {\r\n case 'PHONE_NUMBER_INVALID':\r\n telInputField.setError();\r\n replaceContent(telInputField.label, i18n('Login.PhoneLabelInvalid'));\r\n telEl.classList.add('error');\r\n replaceContent(btnNext, i18n('Login.Next'));\r\n break;\r\n default:\r\n console.error('auth.sendCode error:', err);\r\n btnNext.innerText = err.type;\r\n break;\r\n }\r\n });\r\n };\r\n\r\n attachClickEvent(btnNext, onSubmit);\r\n\r\n btnQr = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Login'});\r\n\r\n let qrMounted = false;\r\n btnQr.addEventListener('click', () => {\r\n pageSignQR.mount();\r\n /* const promise = import('./pageSignQR');\r\n btnQr.disabled = true;\r\n\r\n let preloaderDiv: HTMLElement;\r\n if(!qrMounted) {\r\n preloaderDiv = putPreloader(btnQr);\r\n qrMounted = true;\r\n }\r\n\r\n promise.then(module => {\r\n module.default.mount();\r\n\r\n setTimeout(() => {\r\n btnQr.removeAttribute('disabled');\r\n if(preloaderDiv) {\r\n preloaderDiv.remove();\r\n }\r\n }, 200);\r\n }); */\r\n });\r\n\r\n inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, btnQr);\r\n\r\n const h4 = document.createElement('h4');\r\n h4.classList.add('text-center');\r\n _i18n(h4, 'Login.Title');\r\n\r\n const subtitle = document.createElement('div');\r\n subtitle.classList.add('subtitle', 'text-center');\r\n _i18n(subtitle, 'Login.StartText');\r\n\r\n page.pageEl.querySelector('.container').append(h4, subtitle, inputWrapper);\r\n\r\n let tryAgain = () => {\r\n apiManager.invokeApi('help.getNearestDc').then((nearestDcResult) => {\r\n const langPack = stateStorage.getFromCache('langPack');\r\n if(langPack && !langPack.countries?.hash) {\r\n I18n.getLangPack(langPack.lang_code).then(() => {\r\n simulateEvent(telEl, 'input');\r\n });\r\n }\r\n\r\n const dcs = new Set([1, 2, 3, 4, 5]);\r\n const done: number[] = [nearestDcResult.this_dc];\r\n\r\n let promise: Promise<any>;\r\n if(nearestDcResult.nearest_dc !== nearestDcResult.this_dc) {\r\n promise = apiManager.getNetworker(nearestDcResult.nearest_dc).then(() => {\r\n done.push(nearestDcResult.nearest_dc);\r\n });\r\n }\r\n\r\n (promise || Promise.resolve()).then(() => {\r\n done.forEach(dcId => {\r\n dcs.delete(dcId);\r\n });\r\n\r\n const _dcs = [...dcs];\r\n const g = async(): Promise<void> => {\r\n const dcId = _dcs.shift();\r\n if(!dcId) return;\r\n\r\n const dbKey: DcAuthKey = `dc${dcId}_auth_key` as any;\r\n const key = await sessionStorage.get(dbKey);\r\n if(key) {\r\n return g();\r\n }\r\n\r\n setTimeout(() => { // * если одновременно запросить все нетворкеры, не будет проходить запрос на код\r\n apiManager.getNetworker(dcId/* , {fileDownload: true} */).finally(g);\r\n }, /* done.includes(dcId) ? 0 : */3000);\r\n };\r\n \r\n g();\r\n });\r\n \r\n return nearestDcResult;\r\n }).then((nearestDcResult) => {\r\n if(!countryInputField.value.length && !telInputField.value.length) {\r\n selectCountryByTarget(liMap.get(nearestDcResult.country)[0]);\r\n }\r\n \r\n //console.log('woohoo', nearestDcResult, country);\r\n })//.catch(tryAgain);\r\n };\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n setTimeout(() => {\r\n telEl.focus();\r\n }, 0);\r\n }\r\n\r\n getLanguageChangeButton(inputWrapper);\r\n\r\n tryAgain();\r\n};\r\n\r\nconst page = new Page('page-sign', true, onFirstMount, () => {\r\n if(btnNext) {\r\n replaceContent(btnNext, i18n('Login.Next'));\r\n ripple(btnNext, undefined, undefined, true);\r\n btnNext.removeAttribute('disabled');\r\n }\r\n\r\n if(btnQr) {\r\n btnQr.removeAttribute('disabled');\r\n }\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateSignIn'});\r\n});\r\n\r\nexport default page;\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 type { DcId } from '../types';\r\nimport type { ApiError } from '../lib/mtproto/apiManager';\r\nimport apiManager from '../lib/mtproto/mtprotoworker';\r\nimport Page from './page';\r\nimport serverTimeManager from '../lib/mtproto/serverTimeManager';\r\nimport { AuthAuthorization, AuthLoginToken } from '../layer';\r\nimport { bytesCmp, bytesToBase64 } from '../helpers/bytes';\r\nimport App from '../config/app';\r\nimport Button from '../components/button';\r\nimport { _i18n, i18n, LangPackKey } from '../lib/langPack';\r\nimport appStateManager from '../lib/appManagers/appStateManager';\r\nimport rootScope from '../lib/rootScope';\r\nimport { putPreloader } from '../components/misc';\r\nimport getLanguageChangeButton from '../components/languageChangeButton';\r\nimport { pause } from '../helpers/schedulers/pause';\r\nimport fixBase64String from '../helpers/fixBase64String';\r\n\r\nconst FETCH_INTERVAL = 3;\r\n\r\nlet onFirstMount = async() => {\r\n const pageElement = page.pageEl;\r\n const imageDiv = pageElement.querySelector('.auth-image') as HTMLDivElement;\r\n\r\n let preloader = putPreloader(imageDiv, true);\r\n\r\n const inputWrapper = document.createElement('div');\r\n inputWrapper.classList.add('input-wrapper');\r\n\r\n const btnBack = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Cancel'});\r\n inputWrapper.append(btnBack);\r\n\r\n getLanguageChangeButton(inputWrapper);\r\n\r\n const container = imageDiv.parentElement;\r\n\r\n const h4 = document.createElement('h4');\r\n _i18n(h4, 'Login.QR.Title');\r\n\r\n const helpList = document.createElement('ol');\r\n helpList.classList.add('qr-description');\r\n (['Login.QR.Help1', 'Login.QR.Help2', 'Login.QR.Help3'] as LangPackKey[]).forEach((key) => {\r\n const li = document.createElement('li');\r\n li.append(i18n(key));\r\n helpList.append(li);\r\n });\r\n\r\n container.append(h4, helpList, inputWrapper);\r\n\r\n btnBack.addEventListener('click', () => {\r\n import('./pageSignIn').then(m => m.default.mount());\r\n stop = true;\r\n });\r\n \r\n const results = await Promise.all([\r\n import('qr-code-styling' as any)\r\n ]);\r\n const QRCodeStyling = results[0].default;\r\n\r\n let stop = false;\r\n rootScope.addEventListener('user_auth', () => {\r\n stop = true;\r\n cachedPromise = null;\r\n }, {once: true});\r\n \r\n let options: {dcId?: DcId, ignoreErrors: true} = {ignoreErrors: true};\r\n let prevToken: Uint8Array | number[];\r\n\r\n const iterate = async(isLoop: boolean) => {\r\n try {\r\n let loginToken = await apiManager.invokeApi('auth.exportLoginToken', {\r\n api_id: App.id,\r\n api_hash: App.hash,\r\n except_ids: []\r\n }, {ignoreErrors: true});\r\n \r\n if(loginToken._ === 'auth.loginTokenMigrateTo') {\r\n if(!options.dcId) {\r\n options.dcId = loginToken.dc_id as DcId;\r\n apiManager.setBaseDcId(loginToken.dc_id);\r\n //continue;\r\n }\r\n \r\n loginToken = await apiManager.invokeApi('auth.importLoginToken', {\r\n token: loginToken.token\r\n }, options) as AuthLoginToken.authLoginToken;\r\n }\r\n\r\n if(loginToken._ === 'auth.loginTokenSuccess') {\r\n const authorization = loginToken.authorization as any as AuthAuthorization.authAuthorization;\r\n apiManager.setUser(authorization.user);\r\n import('./pageIm').then(m => m.default.mount());\r\n return true;\r\n }\r\n\r\n /* // to base64\r\n var decoder = new TextDecoder('utf8');\r\n var b64encoded = btoa(String.fromCharCode.apply(null, [...loginToken.token])); */\r\n\r\n if(!prevToken || !bytesCmp(prevToken, loginToken.token)) {\r\n prevToken = loginToken.token;\r\n\r\n let encoded = bytesToBase64(loginToken.token);\r\n let url = \"tg://login?token=\" + fixBase64String(encoded, true);\r\n\r\n const style = window.getComputedStyle(document.documentElement);\r\n const surfaceColor = style.getPropertyValue('--surface-color').trim();\r\n const textColor = style.getPropertyValue('--primary-text-color').trim();\r\n const primaryColor = style.getPropertyValue('--primary-color').trim();\r\n\r\n const logoUrl = await fetch('assets/img/logo_padded.svg')\r\n .then(res => res.text())\r\n .then(text => {\r\n text = text.replace(/(fill:).+?(;)/, `$1${primaryColor}$2`);\r\n const blob = new Blob([text], {type: 'image/svg+xml;charset=utf-8'});\r\n\r\n // * because iOS Safari doesn't want to eat objectURL\r\n return new Promise<string>((resolve) => {\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n resolve(e.target.result as string);\r\n };\r\n reader.readAsDataURL(blob);\r\n });\r\n //return URL.createObjectURL(blob);\r\n });\r\n\r\n const qrCode = new QRCodeStyling({\r\n width: 240 * window.devicePixelRatio,\r\n height: 240 * window.devicePixelRatio,\r\n data: url,\r\n image: logoUrl,\r\n dotsOptions: {\r\n color: textColor,\r\n type: 'rounded'\r\n },\r\n cornersSquareOptions: {\r\n type: 'extra-rounded'\r\n },\r\n imageOptions: {\r\n imageSize: 1,\r\n margin: 0\r\n },\r\n backgroundOptions: {\r\n color: surfaceColor\r\n },\r\n qrOptions: {\r\n errorCorrectionLevel: \"L\"\r\n }\r\n });\r\n\r\n qrCode.append(imageDiv);\r\n (imageDiv.lastChild as HTMLCanvasElement).classList.add('qr-canvas');\r\n\r\n let promise: Promise<void>;\r\n if(qrCode._drawingPromise) {\r\n promise = qrCode._drawingPromise;\r\n } else {\r\n promise = Promise.race([\r\n pause(1000),\r\n new Promise<void>((resolve) => {\r\n qrCode._canvas._image.addEventListener('load', () => {\r\n window.requestAnimationFrame(() => resolve());\r\n }, {once: true});\r\n })\r\n ]);\r\n }\r\n\r\n // * это костыль, но библиотека не предоставляет никаких событий\r\n await promise.then(() => {\r\n if(preloader) {\r\n preloader.style.animation = 'hide-icon .4s forwards';\r\n\r\n const c = imageDiv.children[1] as HTMLElement;\r\n c.style.display = 'none';\r\n c.style.animation = 'grow-icon .4s forwards';\r\n setTimeout(() => {\r\n c.style.display = '';\r\n }, 150);\r\n\r\n setTimeout(() => {\r\n c.style.animation = '';\r\n }, 500);\r\n preloader = undefined;\r\n } else {\r\n Array.from(imageDiv.children).slice(0, -1).forEach(el => {\r\n el.remove();\r\n });\r\n }\r\n });\r\n }\r\n\r\n if(isLoop) {\r\n let timestamp = Date.now() / 1000;\r\n let diff = loginToken.expires - timestamp - serverTimeManager.serverTimeOffset;\r\n \r\n await pause(diff > FETCH_INTERVAL ? 1e3 * FETCH_INTERVAL : 1e3 * diff | 0);\r\n }\r\n } catch(err) {\r\n switch((err as ApiError).type) {\r\n case 'SESSION_PASSWORD_NEEDED':\r\n console.warn('pageSignQR: SESSION_PASSWORD_NEEDED');\r\n (err as ApiError).handled = true;\r\n import('./pagePassword').then(m => m.default.mount());\r\n stop = true;\r\n cachedPromise = null;\r\n break;\r\n default:\r\n console.error('pageSignQR: default error:', err);\r\n stop = true;\r\n break;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n //await iterate(false);\r\n\r\n return async() => {\r\n stop = false;\r\n\r\n do {\r\n if(stop) {\r\n break;\r\n }\r\n \r\n const needBreak = await iterate(true);\r\n if(needBreak) {\r\n break;\r\n }\r\n } while(true);\r\n };\r\n};\r\n\r\nlet cachedPromise: Promise<() => Promise<void>>;\r\nconst page = new Page('page-signQR', true, () => {\r\n return cachedPromise;\r\n}, () => {\r\n //console.log('onMount');\r\n if(!cachedPromise) cachedPromise = onFirstMount();\r\n cachedPromise.then(func => {\r\n func();\r\n });\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateSignQr'});\r\n});\r\n\r\nexport default page;\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 type ListenerSetter from \"../listenerSetter\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../../environment/touchSupport\";\r\nimport simulateEvent from \"./dispatchEvent\";\r\n\r\nexport const CLICK_EVENT_NAME: 'mousedown' /* | 'touchend' */ | 'click' = (IS_TOUCH_SUPPORTED ? 'mousedown' : 'click') as any;\r\nexport type AttachClickOptions = AddEventListenerOptions & Partial<{listenerSetter: ListenerSetter, touchMouseDown: true}>;\r\nexport function attachClickEvent(elem: HTMLElement | Window, callback: (e: /* TouchEvent | */MouseEvent) => void, options: AttachClickOptions = {}) {\r\n const add = options.listenerSetter ? options.listenerSetter.add(elem) : elem.addEventListener.bind(elem);\r\n // const remove = options.listenerSetter ? options.listenerSetter.removeManual.bind(options.listenerSetter, elem) : elem.removeEventListener.bind(elem);\r\n\r\n options.touchMouseDown = true;\r\n /* if(options.touchMouseDown && CLICK_EVENT_NAME === 'touchend') {\r\n add('mousedown', callback, options);\r\n } else if(CLICK_EVENT_NAME === 'touchend') {\r\n const o = {...options, once: true};\r\n\r\n const onTouchStart = (e: TouchEvent) => {\r\n const onTouchMove = (e: TouchEvent) => {\r\n remove('touchmove', onTouchMove, o);\r\n remove('touchend', onTouchEnd, o);\r\n };\r\n \r\n const onTouchEnd = (e: TouchEvent) => {\r\n remove('touchmove', onTouchMove, o);\r\n callback(e);\r\n if(options.once) {\r\n remove('touchstart', onTouchStart);\r\n }\r\n };\r\n \r\n add('touchend', onTouchEnd, o);\r\n add('touchmove', onTouchMove, o);\r\n };\r\n\r\n add('touchstart', onTouchStart);\r\n } else {\r\n add(CLICK_EVENT_NAME, callback, options);\r\n } */\r\n add(CLICK_EVENT_NAME, callback, options);\r\n}\r\n\r\nexport function detachClickEvent(elem: HTMLElement, callback: (e: TouchEvent | MouseEvent) => void, options?: AddEventListenerOptions) {\r\n // if(CLICK_EVENT_NAME === 'touchend') {\r\n // elem.removeEventListener('touchstart', callback, options);\r\n // } else {\r\n elem.removeEventListener(CLICK_EVENT_NAME, callback, options);\r\n // }\r\n}\r\n\r\nexport function simulateClickEvent(elem: HTMLElement) {\r\n simulateEvent(elem, CLICK_EVENT_NAME);\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 { i18n, LangPackKey } from \"../lib/langPack\";\r\nimport { ripple } from \"./ripple\";\r\n\r\nexport type ButtonOptions = Partial<{\r\n noRipple: true, \r\n onlyMobile: true, \r\n icon: string, \r\n rippleSquare: true, \r\n text: LangPackKey, \r\n disabled: boolean,\r\n asDiv: boolean\r\n}>;\r\n\r\nconst Button = (className: string, options: ButtonOptions = {}) => {\r\n const button: HTMLButtonElement = document.createElement(options.asDiv ? 'div' : 'button') as any;\r\n button.className = className + (options.icon ? ' tgico-' + options.icon : '');\r\n\r\n if(!options.noRipple) {\r\n if(options.rippleSquare) {\r\n button.classList.add('rp-square');\r\n }\r\n\r\n ripple(button);\r\n }\r\n\r\n if(options.onlyMobile) {\r\n button.classList.add('only-handhelds');\r\n }\r\n\r\n if(options.disabled) {\r\n button.setAttribute('disabled', 'true');\r\n }\r\n\r\n if(options.text) {\r\n button.append(i18n(options.text));\r\n }\r\n\r\n return button;\r\n};\r\n\r\nexport default Button;\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 { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { CLICK_EVENT_NAME } from \"../helpers/dom/clickEvent\";\r\nimport ListenerSetter from \"../helpers/listenerSetter\";\r\nimport mediaSizes from \"../helpers/mediaSizes\";\r\nimport { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport { IS_APPLE, IS_MOBILE_SAFARI } from \"../environment/userAgent\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport appNavigationController from \"./appNavigationController\";\r\n\r\nexport function putPreloader(elem: Element, returnDiv = false): HTMLElement {\r\n const html = `\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"preloader-circular\" viewBox=\"25 25 50 50\">\r\n <circle class=\"preloader-path\" cx=\"50\" cy=\"50\" r=\"20\" fill=\"none\" stroke-miterlimit=\"10\"/>\r\n </svg>`;\r\n\r\n if(returnDiv) {\r\n const div = document.createElement('div');\r\n div.classList.add('preloader');\r\n div.innerHTML = html;\r\n\r\n if(elem) {\r\n elem.appendChild(div);\r\n }\r\n\r\n return div;\r\n }\r\n \r\n elem.insertAdjacentHTML('beforeend', html);\r\n return elem.lastElementChild as HTMLElement;\r\n}\r\n\r\nMOUNT_CLASS_TO.putPreloader = putPreloader;\r\n\r\nexport function setButtonLoader(elem: HTMLButtonElement, icon = 'check') {\r\n elem.classList.remove('tgico-' + icon);\r\n elem.disabled = true;\r\n putPreloader(elem);\r\n\r\n return () => {\r\n elem.innerHTML = '';\r\n elem.classList.add('tgico-' + icon);\r\n elem.removeAttribute('disabled');\r\n };\r\n}\r\n\r\n/* export function parseMenuButtonsTo(to: {[name: string]: HTMLElement}, elements: HTMLCollection | NodeListOf<HTMLElement>) {\r\n Array.from(elements).forEach(el => {\r\n const match = el.className.match(/(?:^|\\s)menu-(.+?)(?:$|\\s)/);\r\n if(!match) return;\r\n to[match[1]] = el as HTMLElement;\r\n });\r\n} */\r\n\r\nlet onMouseMove = (e: MouseEvent) => {\r\n let rect = openedMenu.getBoundingClientRect();\r\n let {clientX, clientY} = e;\r\n \r\n let diffX = clientX >= rect.right ? clientX - rect.right : rect.left - clientX;\r\n let diffY = clientY >= rect.bottom ? clientY - rect.bottom : rect.top - clientY;\r\n \r\n if(diffX >= 100 || diffY >= 100) {\r\n closeBtnMenu();\r\n //openedMenu.parentElement.click();\r\n }\r\n //console.log('mousemove', diffX, diffY);\r\n};\r\n\r\nconst onClick = (e: MouseEvent | TouchEvent) => {\r\n //cancelEvent(e);\r\n closeBtnMenu();\r\n};\r\n\r\n// ! no need in this due to the same handler in appNavigationController\r\n/* const onKeyDown = (e: KeyboardEvent) => {\r\n if(e.key === 'Escape') {\r\n closeBtnMenu();\r\n cancelEvent(e);\r\n }\r\n}; */\r\n\r\nexport const closeBtnMenu = () => {\r\n if(openedMenu) {\r\n openedMenu.classList.remove('active');\r\n openedMenu.parentElement.classList.remove('menu-open');\r\n //openedMenu.previousElementSibling.remove(); // remove overlay\r\n if(menuOverlay) menuOverlay.remove();\r\n openedMenu = null;\r\n\r\n rootScope.dispatchEvent('context_menu_toggle', false);\r\n }\r\n \r\n if(openedMenuOnClose) {\r\n openedMenuOnClose();\r\n openedMenuOnClose = null;\r\n }\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.removeEventListener('mousemove', onMouseMove);\r\n //window.removeEventListener('keydown', onKeyDown, {capture: true});\r\n window.removeEventListener('contextmenu', onClick);\r\n }\r\n\r\n document.removeEventListener(CLICK_EVENT_NAME, onClick);\r\n\r\n if(!IS_MOBILE_SAFARI) {\r\n appNavigationController.removeByType('menu');\r\n }\r\n};\r\n\r\nwindow.addEventListener('resize', () => {\r\n if(openedMenu) {\r\n closeBtnMenu();\r\n }\r\n \r\n /* if(openedMenu && (openedMenu.style.top || openedMenu.style.left)) {\r\n const rect = openedMenu.getBoundingClientRect();\r\n const {innerWidth, innerHeight} = window;\r\n\r\n console.log(innerWidth, innerHeight, rect);\r\n } */\r\n});\r\n\r\nlet openedMenu: HTMLElement = null, openedMenuOnClose: () => void = null, menuOverlay: HTMLElement = null;\r\nexport function openBtnMenu(menuElement: HTMLElement, onClose?: () => void) {\r\n closeBtnMenu();\r\n\r\n if(!IS_MOBILE_SAFARI) {\r\n appNavigationController.pushItem({\r\n type: 'menu',\r\n onPop: (canAnimate) => {\r\n closeBtnMenu();\r\n }\r\n });\r\n }\r\n \r\n openedMenu = menuElement;\r\n openedMenu.classList.add('active');\r\n openedMenu.parentElement.classList.add('menu-open');\r\n\r\n if(!menuOverlay) {\r\n menuOverlay = document.createElement('div');\r\n menuOverlay.classList.add('btn-menu-overlay');\r\n\r\n // ! because this event must be canceled, and can't cancel on menu click (below)\r\n menuOverlay.addEventListener(CLICK_EVENT_NAME, (e) => {\r\n cancelEvent(e);\r\n onClick(e);\r\n });\r\n }\r\n\r\n openedMenu.parentElement.insertBefore(menuOverlay, openedMenu);\r\n\r\n //document.body.classList.add('disable-hover');\r\n \r\n openedMenuOnClose = onClose;\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n window.addEventListener('mousemove', onMouseMove);\r\n //window.addEventListener('keydown', onKeyDown, {capture: true});\r\n window.addEventListener('contextmenu', onClick, {once: true});\r\n }\r\n\r\n /* // ! because this event must be canceled, and can't cancel on menu click (below)\r\n overlay.addEventListener(CLICK_EVENT_NAME, (e) => {\r\n cancelEvent(e);\r\n onClick(e);\r\n }); */\r\n \r\n // ! safari iOS doesn't handle window click event on overlay, idk why\r\n document.addEventListener(CLICK_EVENT_NAME, onClick);\r\n\r\n rootScope.dispatchEvent('context_menu_toggle', true);\r\n}\r\n\r\nconst PADDING_TOP = 8;\r\nconst PADDING_LEFT = 8;\r\nexport function positionMenu({pageX, pageY}: MouseEvent | Touch, elem: HTMLElement, side?: 'left' | 'right' | 'center') {\r\n //let {clientX, clientY} = e;\r\n\r\n // * side mean the OPEN side\r\n\r\n let {scrollWidth: menuWidth, scrollHeight: menuHeight} = elem;\r\n //let {innerWidth: windowWidth, innerHeight: windowHeight} = window;\r\n const rect = document.body.getBoundingClientRect();\r\n const windowWidth = rect.width;\r\n const windowHeight = rect.height;\r\n\r\n side = mediaSizes.isMobile ? 'right' : 'left';\r\n let verticalSide: 'top' /* | 'bottom' */ | 'center' = 'top';\r\n\r\n const getSides = () => {\r\n return {\r\n x: {\r\n left: pageX,\r\n right: pageX - menuWidth\r\n },\r\n intermediateX: side === 'right' ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,\r\n //intermediateX: clientX < windowWidth / 2 ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,\r\n y: {\r\n top: pageY,\r\n bottom: pageY - menuHeight\r\n },\r\n //intermediateY: verticalSide === 'top' ? PADDING_TOP : windowHeight - menuHeight - PADDING_TOP,\r\n intermediateY: pageY < windowHeight / 2 ? PADDING_TOP : windowHeight - menuHeight - PADDING_TOP,\r\n };\r\n };\r\n\r\n const sides = getSides();\r\n\r\n const possibleSides = {\r\n x: {\r\n left: sides.x.left + menuWidth + PADDING_LEFT <= windowWidth,\r\n right: sides.x.right >= PADDING_LEFT\r\n },\r\n y: {\r\n top: sides.y.top + menuHeight + PADDING_TOP <= windowHeight,\r\n bottom: sides.y.bottom - PADDING_TOP >= PADDING_TOP\r\n }\r\n };\r\n\r\n /* if(side === undefined) {\r\n if((clientX + menuWidth + PADDING_LEFT) > windowWidth) {\r\n side = 'right';\r\n }\r\n } */\r\n\r\n {\r\n /* const x = sides.x;\r\n\r\n const s = Object.keys(x) as (keyof typeof possibleSides.x)[];\r\n if(side) {\r\n s.findAndSplice(s => s === side);\r\n s.unshift(side);\r\n }\r\n\r\n const possibleSide = s.find(s => possibleSides.x[s]); */\r\n let left: number;\r\n /* if(possibleSide) {\r\n left = x[possibleSide];\r\n side = possibleSide;\r\n } else {\r\n left = sides.intermediateX;\r\n side = undefined;\r\n } */\r\n left = possibleSides.x[side] ? sides.x[side] : (side = 'center', sides.intermediateX);\r\n \r\n elem.style.left = left + 'px';\r\n }\r\n\r\n /* if((clientY + menuHeight + PADDING_TOP) > windowHeight) {\r\n elem.style.top = clamp(clientY - menuHeight, PADDING_TOP, windowHeight - menuHeight - PADDING_TOP) + 'px';\r\n // elem.style.top = (innerHeight - scrollHeight - PADDING_TOP) + 'px';\r\n verticalSide = 'bottom';\r\n } else {\r\n elem.style.top = Math.max(PADDING_TOP, clientY) + 'px';\r\n verticalSide = 'top';\r\n } */\r\n\r\n {\r\n let top: number;\r\n\r\n top = possibleSides.y[verticalSide] ? sides.y[verticalSide] : (verticalSide = 'center', sides.intermediateY);\r\n \r\n elem.style.top = top + 'px';\r\n }\r\n \r\n elem.className = elem.className.replace(/(top|center|bottom)-(left|center|right)/g, '');\r\n elem.classList.add(\r\n //(verticalSide === 'center' ? verticalSide : (verticalSide === 'bottom' ? 'top' : 'bottom')) +\r\n (verticalSide === 'center' ? verticalSide : 'bottom') +\r\n '-' +\r\n (side === 'center' ? side : (side === 'left' ? 'right' : 'left')));\r\n}\r\n\r\nlet _cancelContextMenuOpening = false, _cancelContextMenuOpeningTimeout = 0;\r\nexport function cancelContextMenuOpening() {\r\n if(_cancelContextMenuOpeningTimeout) {\r\n clearTimeout(_cancelContextMenuOpeningTimeout);\r\n }\r\n \r\n _cancelContextMenuOpeningTimeout = window.setTimeout(() => {\r\n _cancelContextMenuOpeningTimeout = 0;\r\n _cancelContextMenuOpening = false;\r\n }, .4e3);\r\n\r\n _cancelContextMenuOpening = true;\r\n}\r\n\r\nexport function attachContextMenuListener(element: HTMLElement, callback: (e: Touch | MouseEvent) => void, listenerSetter?: ListenerSetter) {\r\n const add = listenerSetter ? listenerSetter.add(element) : element.addEventListener.bind(element);\r\n const remove = listenerSetter ? listenerSetter.removeManual.bind(listenerSetter, element) : element.removeEventListener.bind(element);\r\n\r\n if(IS_APPLE && IS_TOUCH_SUPPORTED) {\r\n let timeout: number;\r\n\r\n const options: EventListenerOptions = {capture: true};\r\n\r\n const onCancel = () => {\r\n clearTimeout(timeout);\r\n // @ts-ignore\r\n remove('touchmove', onCancel, options);\r\n // @ts-ignore\r\n remove('touchend', onCancel, options);\r\n // @ts-ignore\r\n remove('touchcancel', onCancel, options);\r\n };\r\n\r\n add('touchstart', (e: TouchEvent) => {\r\n if(e.touches.length > 1) {\r\n onCancel();\r\n return;\r\n }\r\n \r\n add('touchmove', onCancel, options);\r\n add('touchend', onCancel, options);\r\n add('touchcancel', onCancel, options);\r\n\r\n timeout = window.setTimeout(() => {\r\n if(_cancelContextMenuOpening) {\r\n onCancel();\r\n return;\r\n }\r\n\r\n callback(e.touches[0]);\r\n onCancel();\r\n\r\n if(openedMenu) {\r\n element.addEventListener('touchend', cancelEvent, {once: true}); // * fix instant closing\r\n }\r\n }, .4e3);\r\n });\r\n\r\n /* if(!isSafari) {\r\n add('contextmenu', (e: any) => {\r\n cancelEvent(e);\r\n }, {passive: false, capture: true});\r\n } */\r\n } else {\r\n add('contextmenu', IS_TOUCH_SUPPORTED ? (e: any) => {\r\n callback(e);\r\n\r\n if(openedMenu) {\r\n element.addEventListener('touchend', cancelEvent, {once: true}); // * fix instant closing\r\n }\r\n } : callback);\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 { IS_TOUCH_SUPPORTED } from \"../environment/touchSupport\";\r\nimport { logger, LogTypes } from \"../lib/logger\";\r\nimport fastSmoothScroll, { ScrollOptions } from \"../helpers/fastSmoothScroll\";\r\nimport useHeavyAnimationCheck from \"../hooks/useHeavyAnimationCheck\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\n/*\r\nvar el = $0;\r\nvar height = 0;\r\nvar checkUp = false;\r\n\r\ndo {\r\n height += el.scrollHeight;\r\n} while(el = (checkUp ? el.previousElementSibling : el.nextElementSibling));\r\nconsole.log(height);\r\n*/\r\n\r\n/*\r\nArray.from($0.querySelectorAll('.bubble-content')).forEach(_el => {\r\n\t//_el.style.display = '';\t\r\n\t//return;\r\n\r\n\tlet el = _el.parentElement;\r\n\tlet height = el.scrollHeight;\r\n\tlet width = el.scrollWidth;\r\n\tel.style.width = width + 'px';\r\n\tel.style.height = height + 'px';\r\n\t_el.style.display = 'none';\r\n});\r\n*/\r\n\r\n/* const scrollables: Map<HTMLElement, Scrollable> = new Map();\r\nconst scrollsIntersector = new IntersectionObserver(entries => {\r\n for(let entry of entries) {\r\n const scrollable = scrollables.get(entry.target as HTMLElement);\r\n\r\n if(entry.isIntersecting) {\r\n scrollable.isVisible = true;\r\n } else {\r\n scrollable.isVisible = false;\r\n\r\n if(!isInDOM(entry.target)) {\r\n scrollsIntersector.unobserve(scrollable.container);\r\n scrollables.delete(scrollable.container);\r\n }\r\n }\r\n }\r\n}); */\r\n\r\nexport class ScrollableBase {\r\n protected log: ReturnType<typeof logger>;\r\n\r\n public onScrollMeasure: number = 0;\r\n protected onScroll: () => void;\r\n\r\n public isHeavyAnimationInProgress = false;\r\n protected needCheckAfterAnimation = false;\r\n\r\n constructor(public el: HTMLElement, logPrefix = '', public container: HTMLElement = document.createElement('div')) {\r\n this.container.classList.add('scrollable');\r\n\r\n this.log = logger('SCROLL' + (logPrefix ? '-' + logPrefix : ''), LogTypes.Error);\r\n\r\n if(el) {\r\n Array.from(el.children).forEach(c => this.container.append(c));\r\n\r\n el.append(this.container);\r\n }\r\n //this.onScroll();\r\n }\r\n\r\n protected setListeners() {\r\n window.addEventListener('resize', this.onScroll, {passive: true});\r\n this.container.addEventListener('scroll', this.onScroll, {passive: true, capture: true});\r\n\r\n useHeavyAnimationCheck(() => {\r\n this.isHeavyAnimationInProgress = true;\r\n\r\n if(this.onScrollMeasure) {\r\n this.needCheckAfterAnimation = true;\r\n window.cancelAnimationFrame(this.onScrollMeasure);\r\n }\r\n }, () => {\r\n this.isHeavyAnimationInProgress = false;\r\n\r\n if(this.needCheckAfterAnimation) {\r\n this.onScroll();\r\n this.needCheckAfterAnimation = false;\r\n }\r\n });\r\n }\r\n\r\n public append(element: HTMLElement) {\r\n this.container.append(element);\r\n }\r\n\r\n public scrollIntoViewNew(options: Omit<ScrollOptions, 'container'>) {\r\n //return Promise.resolve();\r\n return fastSmoothScroll({\r\n ...options,\r\n container: this.container\r\n });\r\n }\r\n}\r\n\r\nexport type SliceSides = 'top' | 'bottom';\r\nexport type SliceSidesContainer = {[k in SliceSides]: boolean};\r\n\r\nexport default class Scrollable extends ScrollableBase {\r\n public splitUp: HTMLElement;\r\n public padding: HTMLElement;\r\n \r\n public onAdditionalScroll: () => void;\r\n public onScrolledTop: () => void;\r\n public onScrolledBottom: () => void;\r\n \r\n public lastScrollTop: number = 0;\r\n public lastScrollDirection: number = 0;\r\n\r\n public loadedAll: SliceSidesContainer = {top: true, bottom: false};\r\n\r\n constructor(el: HTMLElement, logPrefix = '', public onScrollOffset = 300, withPaddingContainer?: boolean) {\r\n super(el, logPrefix);\r\n\r\n /* if(withPaddingContainer) {\r\n this.padding = document.createElement('div');\r\n this.padding.classList.add('scrollable-padding');\r\n Array.from(this.container.children).forEach(c => this.padding.append(c));\r\n this.container.append(this.padding);\r\n } */\r\n\r\n this.container.classList.add('scrollable-y');\r\n this.setListeners();\r\n }\r\n\r\n public setVirtualContainer(el?: HTMLElement) {\r\n this.splitUp = el;\r\n this.log('setVirtualContainer:', el, this);\r\n }\r\n\r\n public onScroll = () => {\r\n //if(this.debug) {\r\n //this.log('onScroll call', this.onScrollMeasure);\r\n //}\r\n\r\n //return;\r\n\r\n if(this.isHeavyAnimationInProgress) {\r\n if(this.onScrollMeasure) {\r\n window.cancelAnimationFrame(this.onScrollMeasure);\r\n }\r\n\r\n this.needCheckAfterAnimation = true;\r\n return;\r\n }\r\n\r\n //if(this.onScrollMeasure || ((this.scrollLocked || (!this.onScrolledTop && !this.onScrolledBottom)) && !this.splitUp && !this.onAdditionalScroll)) return;\r\n if((!this.onScrolledTop && !this.onScrolledBottom) && !this.splitUp && !this.onAdditionalScroll) return;\r\n if(this.onScrollMeasure) window.cancelAnimationFrame(this.onScrollMeasure);\r\n this.onScrollMeasure = window.requestAnimationFrame(() => {\r\n this.onScrollMeasure = 0;\r\n\r\n const scrollTop = this.container.scrollTop;\r\n this.lastScrollDirection = this.lastScrollTop === scrollTop ? 0 : (this.lastScrollTop < scrollTop ? 1 : -1); // * 1 - bottom, -1 - top\r\n this.lastScrollTop = scrollTop;\r\n\r\n if(this.onAdditionalScroll && this.lastScrollDirection !== 0) {\r\n this.onAdditionalScroll();\r\n }\r\n \r\n if(this.checkForTriggers) {\r\n this.checkForTriggers();\r\n }\r\n });\r\n };\r\n\r\n public checkForTriggers = () => {\r\n if((!this.onScrolledTop && !this.onScrolledBottom)) return;\r\n\r\n if(this.isHeavyAnimationInProgress) {\r\n this.onScroll();\r\n return;\r\n }\r\n\r\n const scrollHeight = this.container.scrollHeight;\r\n if(!scrollHeight) { // незачем вызывать триггеры если блок пустой или не виден\r\n return;\r\n }\r\n\r\n const clientHeight = this.container.clientHeight;\r\n const maxScrollTop = scrollHeight - clientHeight;\r\n const scrollTop = this.lastScrollTop;\r\n\r\n //this.log('checkForTriggers:', scrollTop, maxScrollTop);\r\n\r\n if(this.onScrolledTop && scrollTop <= this.onScrollOffset && this.lastScrollDirection <= 0/* && direction === -1 */) {\r\n this.onScrolledTop();\r\n }\r\n\r\n if(this.onScrolledBottom && (maxScrollTop - scrollTop) <= this.onScrollOffset && this.lastScrollDirection >= 0/* && direction === 1 */) {\r\n this.onScrolledBottom();\r\n }\r\n };\r\n\r\n public prepend(...elements: (HTMLElement | DocumentFragment)[]) {\r\n (this.splitUp || this.padding || this.container).prepend(...elements);\r\n }\r\n\r\n public append(...elements: (HTMLElement | DocumentFragment)[]) {\r\n (this.splitUp || this.padding || this.container).append(...elements);\r\n }\r\n\r\n public getDistanceToEnd() {\r\n return this.scrollHeight - Math.round(this.scrollTop + this.container.offsetHeight);\r\n }\r\n\r\n get isScrolledDown() {\r\n return this.getDistanceToEnd() <= 1;\r\n }\r\n\r\n set scrollTop(y: number) {\r\n this.container.scrollTop = y;\r\n }\r\n \r\n get scrollTop() {\r\n //this.log.trace('get scrollTop');\r\n return this.container.scrollTop;\r\n }\r\n \r\n get scrollHeight() {\r\n return this.container.scrollHeight;\r\n }\r\n}\r\n\r\nexport class ScrollableX extends ScrollableBase {\r\n constructor(el: HTMLElement, logPrefix = '', public onScrollOffset = 300, public splitCount = 15, public container: HTMLElement = document.createElement('div')) {\r\n super(el, logPrefix, container);\r\n\r\n this.container.classList.add('scrollable-x');\r\n\r\n if(!IS_TOUCH_SUPPORTED) {\r\n const scrollHorizontally = (e: any) => {\r\n if(!e.deltaX && this.container.scrollWidth > this.container.clientWidth) {\r\n this.container.scrollLeft += e.deltaY / 4;\r\n cancelEvent(e);\r\n }\r\n };\r\n \r\n this.container.addEventListener('wheel', scrollHorizontally, {passive: false});\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 { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport { IS_MOBILE_SAFARI } from \"../environment/userAgent\";\r\nimport { logger } from \"../lib/logger\";\r\nimport { doubleRaf } from \"../helpers/schedulers\";\r\nimport blurActiveElement from \"../helpers/dom/blurActiveElement\";\r\nimport { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { indexOfAndSplice } from \"../helpers/array\";\r\nimport isSwipingBackSafari from \"../helpers/dom/isSwipingBackSafari\";\r\n\r\nexport type NavigationItem = {\r\n type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' | \r\n 'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' | \r\n 'global-search' | 'voice' | 'mobile-search',\r\n onPop: (canAnimate: boolean) => boolean | void,\r\n onEscape?: () => boolean,\r\n noHistory?: boolean,\r\n noBlurOnPop?: boolean,\r\n};\r\n\r\nexport class AppNavigationController {\r\n private navigations: Array<NavigationItem> = [];\r\n private id = Date.now();\r\n private manual = false;\r\n private log = logger('NC');\r\n private debug = true;\r\n private currentHash = window.location.hash;\r\n public onHashChange: () => void;\r\n\r\n constructor() {\r\n let isPossibleSwipe = false;\r\n window.addEventListener('popstate', (e) => {\r\n this.debug && this.log('popstate', e, isPossibleSwipe);\r\n\r\n if(window.location.hash !== this.currentHash) {\r\n this.onHashChange && this.onHashChange();\r\n this.replaceState();\r\n return;\r\n }\r\n this.currentHash = window.location.hash;\r\n\r\n const id: number = e.state;\r\n if(id !== this.id/* && !this.navigations.length */) {\r\n this.pushState();\r\n return;\r\n }\r\n\r\n const item = this.navigations.pop();\r\n if(!item) {\r\n this.pushState();\r\n return;\r\n }\r\n\r\n this.manual = !isPossibleSwipe;\r\n this.handleItem(item);\r\n //this.pushState(); // * prevent adding forward arrow\r\n });\r\n\r\n window.addEventListener('keydown', (e) => {\r\n const item = this.navigations[this.navigations.length - 1];\r\n if(!item) return;\r\n if(e.key === 'Escape' && (item.onEscape ? item.onEscape() : true)) {\r\n cancelEvent(e);\r\n this.back(item.type);\r\n }\r\n }, {capture: true, passive: false});\r\n\r\n if(IS_MOBILE_SAFARI) {\r\n const options = {passive: true};\r\n window.addEventListener('touchstart', (e) => {\r\n if(e.touches.length > 1) return;\r\n this.debug && this.log('touchstart');\r\n\r\n if(isSwipingBackSafari(e)) {\r\n isPossibleSwipe = true;\r\n\r\n window.addEventListener('touchend', () => {\r\n setTimeout(() => {\r\n isPossibleSwipe = false;\r\n }, 100);\r\n }, {passive: true, once: true});\r\n }\r\n\r\n /* const detach = () => {\r\n window.removeEventListener('touchend', onTouchEnd);\r\n window.removeEventListener('touchmove', onTouchMove);\r\n };\r\n\r\n let moved = false;\r\n const onTouchMove = (e: TouchEvent) => {\r\n this.debug && this.log('touchmove');\r\n if(e.touches.length > 1) {\r\n detach();\r\n return;\r\n }\r\n\r\n moved = true;\r\n };\r\n\r\n const onTouchEnd = (e: TouchEvent) => {\r\n this.debug && this.log('touchend');\r\n if(e.touches.length > 1 || !moved) {\r\n detach();\r\n return;\r\n }\r\n\r\n isPossibleSwipe = true;\r\n doubleRaf().then(() => {\r\n isPossibleSwipe = false;\r\n });\r\n\r\n detach();\r\n };\r\n\r\n window.addEventListener('touchend', onTouchEnd, options);\r\n window.addEventListener('touchmove', onTouchMove, options); */\r\n }, options);\r\n }\r\n\r\n history.scrollRestoration = 'manual';\r\n\r\n this.pushState(); // * push init state\r\n }\r\n\r\n private handleItem(item: NavigationItem) {\r\n const good = item.onPop(!this.manual ? false : undefined);\r\n this.debug && this.log('popstate, navigation:', item, this.navigations);\r\n if(good === false) {\r\n this.pushItem(item);\r\n } else if(!item.noBlurOnPop) {\r\n blurActiveElement(); // no better place for it\r\n }\r\n\r\n this.manual = false;\r\n }\r\n\r\n public findItemByType(type: NavigationItem['type']) {\r\n for(let i = this.navigations.length - 1; i >= 0; --i) {\r\n const item = this.navigations[i];\r\n if(item.type === type) {\r\n return {item, index: i};\r\n }\r\n }\r\n }\r\n\r\n public back(type?: NavigationItem['type']) {\r\n if(type) {\r\n const ret = this.findItemByType(type);\r\n if(ret) {\r\n this.backByItem(ret.item, ret.index);\r\n return;\r\n }\r\n }\r\n\r\n history.back();\r\n }\r\n\r\n public backByItem(item: NavigationItem, index = this.navigations.indexOf(item)) {\r\n this.manual = true;\r\n // ! commented because 'popstate' event will be fired with delay\r\n //if(index !== (this.navigations.length - 1)) {\r\n this.navigations.splice(index, 1);\r\n this.handleItem(item);\r\n //}\r\n }\r\n\r\n public pushItem(item: NavigationItem) {\r\n this.navigations.push(item);\r\n this.debug && this.log('pushstate', item, this.navigations);\r\n\r\n if(!item.noHistory) {\r\n this.pushState();\r\n }\r\n }\r\n\r\n private pushState() {\r\n this.manual = false;\r\n history.pushState(this.id, '');\r\n }\r\n\r\n public replaceState() {\r\n history.replaceState(this.id, '', location.origin + location.pathname);\r\n }\r\n\r\n public removeItem(item: NavigationItem) {\r\n if(!item) {\r\n return;\r\n }\r\n \r\n indexOfAndSplice(this.navigations, item);\r\n }\r\n\r\n public removeByType(type: NavigationItem['type'], single = false) {\r\n for(let i = this.navigations.length - 1; i >= 0; --i) {\r\n const item = this.navigations[i];\r\n if(item.type === type) {\r\n this.navigations.splice(i, 1);\r\n\r\n if(single) {\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst appNavigationController = new AppNavigationController();\r\nMOUNT_CLASS_TO.appNavigationController = appNavigationController;\r\nexport default appNavigationController;\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 appStateManager from \"../lib/appManagers/appStateManager\";\r\nimport { getDeepProperty } from \"../helpers/object\";\r\nimport { ripple } from \"./ripple\";\r\nimport { LangPackKey, _i18n } from \"../lib/langPack\";\r\n\r\nexport type CheckboxFieldOptions = {\r\n text?: LangPackKey,\r\n textArgs?: any[],\r\n name?: string, \r\n round?: boolean, \r\n toggle?: boolean,\r\n stateKey?: string,\r\n stateValues?: any[],\r\n disabled?: boolean,\r\n checked?: boolean,\r\n restriction?: boolean,\r\n withRipple?: boolean,\r\n withHover?: boolean,\r\n};\r\nexport default class CheckboxField {\r\n public input: HTMLInputElement;\r\n public label: HTMLLabelElement;\r\n public span: HTMLSpanElement;\r\n\r\n constructor(options: CheckboxFieldOptions = {}) {\r\n const label = this.label = document.createElement('label');\r\n label.classList.add('checkbox-field');\r\n\r\n if(options.restriction) {\r\n label.classList.add('checkbox-field-restriction');\r\n }\r\n\r\n if(options.round) {\r\n label.classList.add('checkbox-field-round');\r\n }\r\n\r\n if(options.disabled) {\r\n this.toggleDisability(true);\r\n }\r\n\r\n const input = this.input = document.createElement('input');\r\n input.classList.add('checkbox-field-input');\r\n input.type = 'checkbox';\r\n if(options.name) {\r\n input.id = 'input-' + options.name;\r\n }\r\n\r\n if(options.checked) {\r\n input.checked = true;\r\n }\r\n\r\n if(options.stateKey) {\r\n appStateManager.getState().then(state => {\r\n const stateValue = getDeepProperty(state, options.stateKey);\r\n let checked: boolean;\r\n if(options.stateValues) {\r\n checked = options.stateValues.indexOf(stateValue) === 1;\r\n } else {\r\n checked = stateValue;\r\n }\r\n\r\n this.setValueSilently(checked);\r\n\r\n input.addEventListener('change', () => {\r\n let value: any;\r\n if(options.stateValues) {\r\n value = options.stateValues[input.checked ? 1 : 0];\r\n } else {\r\n value = input.checked;\r\n }\r\n\r\n appStateManager.setByKey(options.stateKey, value);\r\n });\r\n });\r\n }\r\n\r\n let span: HTMLSpanElement;\r\n if(options.text) {\r\n span = this.span = document.createElement('span');\r\n span.classList.add('checkbox-caption');\r\n _i18n(span, options.text, options.textArgs);\r\n } else {\r\n label.classList.add('checkbox-without-caption');\r\n }\r\n\r\n label.append(input);\r\n\r\n if(options.toggle) {\r\n label.classList.add('checkbox-field-toggle');\r\n\r\n const toggle = document.createElement('div');\r\n toggle.classList.add('checkbox-toggle');\r\n label.append(toggle);\r\n } else {\r\n const box = document.createElement('div');\r\n box.classList.add('checkbox-box');\r\n \r\n const checkSvg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n checkSvg.classList.add('checkbox-box-check');\r\n checkSvg.setAttributeNS(null, 'viewBox', '0 0 24 24');\r\n const use = document.createElementNS(\"http://www.w3.org/2000/svg\", \"use\");\r\n use.setAttributeNS(null, 'href', '#check');\r\n use.setAttributeNS(null, 'x', '-1');\r\n checkSvg.append(use);\r\n \r\n const bg = document.createElement('div');\r\n bg.classList.add('checkbox-box-background');\r\n \r\n const border = document.createElement('div');\r\n border.classList.add('checkbox-box-border');\r\n \r\n box.append(border, bg, checkSvg);\r\n \r\n label.append(box);\r\n }\r\n\r\n if(span) {\r\n label.append(span);\r\n }\r\n\r\n if(options.withRipple) {\r\n label.classList.add('checkbox-ripple', 'hover-effect');\r\n ripple(label, undefined, undefined, true);\r\n //label.prepend(input);\r\n } else if(options.withHover) {\r\n label.classList.add('hover-effect');\r\n }\r\n }\r\n\r\n get checked() {\r\n return this.input.checked;\r\n }\r\n\r\n set checked(checked: boolean) {\r\n /* if(this.checked === checked) {\r\n return;\r\n } */\r\n \r\n this.setValueSilently(checked);\r\n\r\n const event = new Event('change', {bubbles: true, cancelable: true});\r\n this.input.dispatchEvent(event);\r\n }\r\n\r\n public setValueSilently(checked: boolean) {\r\n this.input.checked = checked;\r\n }\r\n\r\n public toggleDisability(disable: boolean) {\r\n this.label.classList.toggle('checkbox-disabled', disable);\r\n return () => this.toggleDisability(!disable);\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\nexport default function toggleDisability(elements: HTMLElement[], disable: boolean): () => void {\r\n if(disable) {\r\n elements.forEach(el => el.setAttribute('disabled', 'true'));\r\n } else {\r\n elements.forEach(el => el.removeAttribute('disabled'));\r\n }\r\n\r\n return () => toggleDisability(elements, !disable);\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 <igor.beatle@gmail.com>\r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nexport function bytesToHex(bytes: ArrayLike<number>) {\r\n const length = bytes.length;\r\n const arr: string[] = new Array(length);\r\n for(let i = 0; i < length; ++i) {\r\n arr[i] = (bytes[i] < 16 ? '0' : '') + (bytes[i] || 0).toString(16);\r\n }\r\n return arr.join('');\r\n}\r\n\r\nexport function bytesFromHex(hexString: string) {\r\n const len = hexString.length;\r\n const bytes = new Uint8Array(Math.ceil(len / 2));\r\n let start = 0;\r\n\r\n if(len % 2) { // read 0x581 as 0x0581\r\n bytes[start++] = parseInt(hexString.charAt(0), 16);\r\n }\r\n\r\n for(let i = start; i < len; i += 2) {\r\n bytes[start++] = parseInt(hexString.substr(i, 2), 16);\r\n }\r\n\r\n return bytes;\r\n}\r\n\r\nexport function bytesToBase64(bytes: number[] | Uint8Array) {\r\n let mod3: number;\r\n let result = '';\r\n\r\n for(let nLen = bytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; ++nIdx) {\r\n mod3 = nIdx % 3;\r\n nUint24 |= bytes[nIdx] << (16 >>> mod3 & 24);\r\n if(mod3 === 2 || nLen - nIdx === 1) {\r\n result += String.fromCharCode(\r\n uint6ToBase64(nUint24 >>> 18 & 63),\r\n uint6ToBase64(nUint24 >>> 12 & 63),\r\n uint6ToBase64(nUint24 >>> 6 & 63),\r\n uint6ToBase64(nUint24 & 63)\r\n );\r\n nUint24 = 0;\r\n }\r\n }\r\n\r\n return result.replace(/A(?=A$|$)/g, '=');\r\n}\r\n\r\nexport function uint6ToBase64(nUint6: number) {\r\n return nUint6 < 26\r\n ? nUint6 + 65\r\n : nUint6 < 52\r\n ? nUint6 + 71\r\n : nUint6 < 62\r\n ? nUint6 - 4\r\n : nUint6 === 62\r\n ? 43\r\n : nUint6 === 63\r\n ? 47\r\n : 65;\r\n}\r\n\r\nexport function bytesCmp(bytes1: number[] | Uint8Array, bytes2: number[] | Uint8Array) {\r\n const len = bytes1.length;\r\n if(len !== bytes2.length) {\r\n return false;\r\n }\r\n\r\n for(let i = 0; i < len; ++i) {\r\n if(bytes1[i] !== bytes2[i]) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function bytesXor(bytes1: Uint8Array, bytes2: Uint8Array) {\r\n const len = bytes1.length;\r\n const bytes = new Uint8Array(len);\r\n\r\n for(let i = 0; i < len; ++i) {\r\n bytes[i] = bytes1[i] ^ bytes2[i];\r\n }\r\n\r\n return bytes;\r\n}\r\n\r\n/* export function bytesToArrayBuffer(b: number[]) {\r\n return (new Uint8Array(b)).buffer;\r\n}\r\n\r\nexport function convertToArrayBuffer(bytes: any | ArrayBuffer | Uint8Array) {\r\n // Be careful with converting subarrays!!\r\n if(bytes instanceof ArrayBuffer) {\r\n return bytes;\r\n }\r\n if(bytes.buffer !== undefined &&\r\n bytes.buffer.byteLength === bytes.length * bytes.BYTES_PER_ELEMENT) {\r\n return bytes.buffer;\r\n }\r\n return bytesToArrayBuffer(bytes);\r\n} */\r\n\r\nexport function convertToUint8Array(bytes: Uint8Array | ArrayBuffer | number[] | string): Uint8Array {\r\n if(bytes instanceof Uint8Array) {\r\n return bytes;\r\n } else if(typeof(bytes) === 'string') {\r\n return new TextEncoder().encode(bytes);\r\n }\r\n\r\n return new Uint8Array(bytes);\r\n}\r\n\r\n/* export function bytesFromArrayBuffer(buffer: ArrayBuffer) {\r\n const len = buffer.byteLength;\r\n const byteView = new Uint8Array(buffer);\r\n const bytes: number[] = [];\r\n\r\n for(let i = 0; i < len; ++i) {\r\n bytes[i] = byteView[i];\r\n }\r\n\r\n return bytes;\r\n}\r\n\r\nexport function bufferConcat(buffer1: any, buffer2: any) {\r\n const l1 = buffer1.byteLength || buffer1.length;\r\n const l2 = buffer2.byteLength || buffer2.length;\r\n const tmp = new Uint8Array(l1 + l2);\r\n tmp.set(buffer1 instanceof ArrayBuffer ? new Uint8Array(buffer1) : buffer1, 0);\r\n tmp.set(buffer2 instanceof ArrayBuffer ? new Uint8Array(buffer2) : buffer2, l1);\r\n\r\n return tmp.buffer;\r\n} */\r\n\r\nexport function bufferConcats(...args: (ArrayBuffer | Uint8Array | number[])[]) {\r\n const length = args.reduce((acc, v) => acc + ((v as ArrayBuffer).byteLength || (v as Uint8Array).length), 0);\r\n\r\n const tmp = new Uint8Array(length);\r\n \r\n let lastLength = 0;\r\n args.forEach(b => {\r\n tmp.set(b instanceof ArrayBuffer ? new Uint8Array(b) : b, lastLength);\r\n lastLength += (b as ArrayBuffer).byteLength || (b as Uint8Array).length;\r\n });\r\n\r\n return tmp/* .buffer */;\r\n}\r\n\r\nexport function bytesFromWordss(input: Uint32Array) {\r\n const o = new Uint8Array(input.byteLength);\r\n for(let i = 0, length = input.length * 4; i < length; ++i) {\r\n o[i] = ((input[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff);\r\n }\r\n\r\n return o;\r\n}\r\n\r\nexport function bytesToWordss(input: Parameters<typeof convertToUint8Array>[0]) {\r\n const bytes = convertToUint8Array(input);\r\n\r\n const words: number[] = [];\r\n for(let i = 0, len = bytes.length; i < len; ++i) {\r\n words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8);\r\n }\r\n\r\n return new Uint32Array(words);\r\n}\r\n\r\n// * https://stackoverflow.com/a/52827031\r\n/* export const isBigEndian = (() => {\r\n const array = new Uint8Array(4);\r\n const view = new Uint32Array(array.buffer);\r\n return !((view[0] = 1) & array[0]);\r\n})(); */\r\n","export default function simulateEvent(elem: EventTarget, name: string) {\n const event = new Event(name, {bubbles: true, cancelable: true});\n elem.dispatchEvent(event);\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\nexport default function findUpTag(el: any, tag: string): HTMLElement {\r\n return el.closest(tag);\r\n /* if(el.tagName === tag) return el; // 03.02.2020\r\n\r\n while(el.parentElement) {\r\n el = el.parentElement;\r\n if(el.tagName === tag) \r\n return el;\r\n }\r\n return null; */\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 { fastRaf } from \"./schedulers\";\r\nimport { CancellablePromise, deferredPromise } from \"./cancellablePromise\";\r\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport isInDOM from \"./dom/isInDOM\";\r\n\r\nclass SequentialDom {\r\n private promises: Partial<{\r\n read: CancellablePromise<void>,\r\n write: CancellablePromise<void>\r\n }> = {};\r\n private raf = fastRaf.bind(null);\r\n private scheduled = false;\r\n\r\n private do(kind: keyof SequentialDom['promises'], callback?: VoidFunction) {\r\n let promise = this.promises[kind];\r\n if(!promise) {\r\n this.scheduleFlush();\r\n promise = this.promises[kind] = deferredPromise<void>();\r\n }\r\n\r\n if(callback !== undefined) {\r\n promise.then(() => callback());\r\n }\r\n \r\n return promise;\r\n }\r\n\r\n public measure(callback?: VoidFunction) {\r\n return this.do('read', callback);\r\n }\r\n\r\n public mutate(callback?: VoidFunction) {\r\n return this.do('write', callback);\r\n }\r\n\r\n /**\r\n * Will fire instantly if element is not connected\r\n * @param element \r\n * @param callback \r\n */\r\n public mutateElement(element: HTMLElement, callback?: VoidFunction) {\r\n const promise = isInDOM(element) ? this.mutate() : Promise.resolve();\r\n\r\n if(callback !== undefined) {\r\n promise.then(() => callback());\r\n }\r\n\r\n return promise;\r\n }\r\n\r\n private scheduleFlush() {\r\n if(!this.scheduled) {\r\n this.scheduled = true;\r\n\r\n this.raf(() => {\r\n this.promises.read && this.promises.read.resolve();\r\n this.promises.write && this.promises.write.resolve();\r\n\r\n this.scheduled = false;\r\n this.promises = {};\r\n });\r\n }\r\n }\r\n}\r\n\r\nconst sequentialDom = new SequentialDom();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.sequentialDom = sequentialDom);\r\nexport default sequentialDom;\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 <igor.beatle@gmail.com>\r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nimport type { ApplyServerTimeOffsetTask } from './timeManager';\r\nimport { MOUNT_CLASS_TO } from '../../config/debug';\r\n// import { tsNow } from '../../helpers/date';\r\nimport sessionStorage from '../sessionStorage';\r\nimport apiManager from './mtprotoworker';\r\n\r\nexport class ServerTimeManager {\r\n /* private midnightNoOffset: number;\r\n private midnightOffseted: Date;\r\n\r\n private midnightOffset: number; */\r\n\r\n public serverTimeOffset: number; // in seconds\r\n /* private timeParams: {\r\n midnightOffset: number,\r\n serverTimeOffset: number\r\n }; */\r\n\r\n constructor() {\r\n /* const timestampNow = tsNow(true);\r\n this.midnightNoOffset = timestampNow - (timestampNow % 86400);\r\n this.midnightOffseted = new Date();\r\n this.midnightOffseted.setHours(0, 0, 0, 0);\r\n \r\n this.midnightOffset = this.midnightNoOffset - (Math.floor(+this.midnightOffseted / 1000)); */\r\n\r\n this.serverTimeOffset = 0;\r\n /* this.timeParams = {\r\n midnightOffset: this.midnightOffset,\r\n serverTimeOffset: this.serverTimeOffset\r\n }; */\r\n\r\n sessionStorage.get('server_time_offset').then((to) => {\r\n if(to) {\r\n this.serverTimeOffset = to;\r\n // this.timeParams.serverTimeOffset = to;\r\n }\r\n });\r\n\r\n apiManager.addTaskListener('applyServerTimeOffset', (task: ApplyServerTimeOffsetTask) => {\r\n this.serverTimeOffset = task.payload;\r\n });\r\n }\r\n}\r\n\r\nconst serverTimeManager = new ServerTimeManager();\r\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.serverTimeManager = serverTimeManager);\r\nexport default serverTimeManager;\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 <igor.beatle@gmail.com>\r\n * https://github.com/zhukov/webogram/blob/master/LICENSE\r\n */\r\n\r\nimport { IS_TOUCH_SUPPORTED } from \"../../environment/touchSupport\";\r\n\r\nexport default function placeCaretAtEnd(el: HTMLElement, ignoreTouchCheck = false) {\r\n if(IS_TOUCH_SUPPORTED && (!ignoreTouchCheck || document.activeElement !== el)) {\r\n return;\r\n }\r\n \r\n el.focus();\r\n if(typeof window.getSelection !== \"undefined\" && typeof document.createRange !== \"undefined\") {\r\n var range = document.createRange();\r\n range.selectNodeContents(el);\r\n range.collapse(false);\r\n var sel = window.getSelection();\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n // @ts-ignore\r\n } else if(typeof document.body.createTextRange !== \"undefined\") {\r\n // @ts-ignore\r\n var textRange = document.body.createTextRange();\r\n textRange.moveToElementText(el);\r\n textRange.collapse(false);\r\n textRange.select();\r\n }\r\n}\r\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_MOBILE_SAFARI } from \"../../environment/userAgent\";\n\nexport default function isSwipingBackSafari(e: TouchEvent | MouseEvent) {\n return IS_MOBILE_SAFARI && e instanceof TouchEvent && e.touches[0].clientX < 30;\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 { HelpCountry, HelpCountryCode } from \"../layer\";\nimport I18n from \"../lib/langPack\";\n\nlet sortedCountries: HelpCountry[];\ntype PrefixCountry = {country: HelpCountry, code: HelpCountryCode};\nconst prefixes: Map<string, PrefixCountry> = new Map();\nlet maxPrefixLength = 0;\nconst setPrefix = (country: HelpCountry, code: HelpCountryCode, prefix: string = '') => {\n prefix = code.country_code + prefix;\n /* if(prefixes.has(prefix)) {\n console.error('asdasdasd', prefixes.get(prefix), country, code);\n } */\n maxPrefixLength = Math.max(maxPrefixLength, prefix.length);\n prefixes.set(prefix, {country, code});\n};\n\nexport function formatPhoneNumber(originalStr: string): {\n formatted: string,\n country: HelpCountry,\n code: HelpCountryCode,\n leftPattern: string\n} {\n originalStr = originalStr || '';\n \n if(!prefixes.size) {\n I18n.countriesList.forEach(country => {\n country.country_codes.forEach(code => {\n const s = {country, code};\n\n if(code.prefixes) {\n code.prefixes.forEach(prefix => {\n setPrefix(country, code, prefix);\n });\n } else {\n setPrefix(country, code);\n }\n });\n });\n }\n\n // return {formatted: originalStr, country: undefined as any, leftPattern: ''};\n let str = originalStr.replace(/\\D/g, '');\n let phoneCode = str.slice(0, maxPrefixLength);\n \n ////console.log('str', str, phoneCode);\n // if(!sortedCountries) {\n // sortedCountries = I18n.countriesList.slice().sort((a, b) => b.country_codes[0].country_code.length - a.country_codes[0].country_code.length);\n // }\n \n // let country = sortedCountries.find((c) => {\n // return c.country_codes.find((c) => phoneCode.indexOf(c.replace(/\\D/g, '')) === 0);\n // });\n\n let prefixCountry: PrefixCountry;\n for(let i = phoneCode.length - 1; i >= 0; --i) { // lookup for country by prefix\n prefixCountry = prefixes.get(phoneCode.slice(0, i + 1));\n if(prefixCountry) {\n break;\n }\n }\n\n if(!prefixCountry) {\n return {\n formatted: str, \n country: undefined, \n code: undefined, \n leftPattern: ''\n };\n }\n\n // country = /* PhoneCodesMain[country.phoneCode] || */country;\n const country = prefixCountry.country;\n \n const patterns = prefixCountry.code.patterns || [];\n const searchForPattern = str.slice(prefixCountry.code.country_code.length); // splice country code\n let pattern = '', mostMatchedPatternMatches = 0, mostMatchedPattern = '';\n for(let i = patterns.length - 1; i >= 0; --i) {\n pattern = patterns[i];\n\n const _pattern = pattern.replace(/ /g, '');\n let patternMatches = 0;\n for(let k = 0, length = Math.min(searchForPattern.length, _pattern.length); k < length; ++k) {\n if(searchForPattern[k] === _pattern[k] || _pattern[k] === 'X') {\n ++patternMatches;\n } else {\n patternMatches = 0;\n break;\n }\n }\n\n if(patternMatches > mostMatchedPatternMatches) {\n mostMatchedPatternMatches = patternMatches;\n mostMatchedPattern = pattern;\n }\n }\n\n pattern = mostMatchedPattern || pattern;\n pattern = pattern.replace(/\\d/g, 'X');\n\n pattern = prefixCountry.code.country_code + ' ' + pattern;\n // let pattern = country.pattern || country.phoneCode;\n pattern.split('').forEach((symbol, idx) => {\n if(symbol === ' ' && str[idx] !== ' ' && str.length > idx) {\n str = str.slice(0, idx) + ' ' + str.slice(idx);\n }\n });\n \n /* if(country.pattern) {\n str = str.slice(0, country.pattern.length);\n } */\n\n let leftPattern = pattern && pattern.length > str.length ? pattern.slice(str.length) : '';\n if(leftPattern) {\n /* const length = str.length;\n leftPattern = leftPattern.split('').map((_, idx) => (length + idx).toString().slice(-1)).join(''); */\n leftPattern = leftPattern.replace(/X/g, '');\n // leftPattern = leftPattern.replace(/X/g, '0');\n }\n \n return {formatted: str, country, code: prefixCountry.code, leftPattern};\n}\n"],"sourceRoot":""}