tweb/public/13.f0b27d519201c3d897b8.chunk.js.map
Eduard Kuzmenko e793a329d0 Build
2021-07-17 19:40:58 +03:00

1 line
120 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/pages/pageSignIn.ts","webpack:///./src/pages/pageSignQR.ts","webpack:///./src/pages/pageAuthCode.ts","webpack:///./src/helpers/dom/replaceContent.ts","webpack:///./src/components/inputField.ts","webpack:///./src/components/scrollable.ts","webpack:///./src/helpers/dom/getRichValue.ts","webpack:///./src/components/checkboxField.ts","webpack:///./src/helpers/dom/toggleDisability.ts","webpack:///./src/helpers/dom/findUpTag.ts","webpack:///./src/lib/mtproto/serverTimeManager.ts","webpack:///./src/helpers/dom/getRichElementValue.ts","webpack:///./src/helpers/dom/findUpAttribute.ts","webpack:///./src/helpers/dom/isInputEmpty.ts","webpack:///./src/helpers/bytes.ts","webpack:///./src/lib/filemanager.ts","webpack:///./src/lib/cacheStorage.ts","webpack:///./src/components/languageChangeButton.ts","webpack:///./src/components/monkeys/tracking.ts","webpack:///./src/components/codeInputField.ts"],"names":["btnQr","btnNext","page","test","push","name","phoneCode","code","emoji","pattern","console","log","countries","filter","c","sort","a","b","localeCompare","lastCountrySelected","inputWrapper","document","createElement","classList","add","countryInputField","label","plainText","container","countryInput","input","autocomplete","selectWrapper","arrowDown","append","selectList","appendChild","initSelect","forEach","liArr","split","li","wrapped","wrapEmojiText","emojiSupported","spanEmoji","innerHTML","span","innerText","addEventListener","e","button","target","tagName","selectCountryByTarget","countryName","childNodes","textContent","querySelector","value","find","telEl","lastValue","hidePicker","setTimeout","focus","hideTimeout","style","display","clearTimeout","undefined","remove","offsetWidth","select","pageEl","parentElement","mouseDownHandlerAttached","onMouseDown","capture","removeEventListener","window","ctrlKey","key","_value","this","toLowerCase","matches","good","indexOf","length","cancelBubble","preventDefault","blur","pasted","telInputField","type","loadLottieWorkers","formatted","country","Math","abs","setLabel","replace","o","visibility","metaKey","shiftKey","onSubmit","signedCheckboxField","text","withRipple","checked","keepSigned","pushToState","toggleStorage","getState","then","state","storage","isAvailable","toggle","phone_number","invokeApi","api_id","id","api_hash","hash","settings","_","m","default","mount","Object","assign","catch","err","setError","error","h4","subtitle","nearestDcResult","dcs","Set","done","this_dc","promise","nearest_dc","getNetworker","Promise","resolve","dcId","delete","_dcs","g","shift","dbKey","get","finally","removeAttribute","cachedPromise","imageDiv","preloader","btnBack","helpList","stop","QRCodeStyling","all","once","prevToken","options","ignoreErrors","iterate","isLoop","loginToken","except_ids","dc_id","setBaseDcId","token","authorization","setUserAuth","user","url","getComputedStyle","documentElement","surfaceColor","getPropertyValue","trim","textColor","primaryColor","logoUrl","fetch","res","blob","Blob","reader","FileReader","onload","result","readAsDataURL","qrCode","width","devicePixelRatio","height","data","image","dotsOptions","color","cornersSquareOptions","imageOptions","imageSize","margin","backgroundOptions","qrOptions","errorCorrectionLevel","lastChild","_drawingPromise","race","_canvas","_image","requestAnimationFrame","animation","children","Array","from","slice","el","timestamp","Date","now","diff","expires","serverTimeOffset","warn","handled","func","codeInput","authCode","headerElement","sentTypeElement","CODELENGTH","codeInputField","onFill","submitCode","cleanup","monkey","setAttribute","params","phone_code_hash","phone_code","response","size","isMobile","load","_authCode","evt","createEvent","initEvent","dispatchEvent","getElementsByClassName","args","sentCode","replaceContent","elem","node","firstChild","replaceWith","init","originalEvent","clipboardData","getData","entities","parseEntities","wrapRichText","noLinks","wrappingDraft","execCommand","InputState","maxLength","showLengthOn","round","placeholder","processInput","labelText","firstElementChild","observer","MutationObserver","inputFake","onFakeInput","observe","characterData","childList","subtree","animate","wasInputFakeClientHeight","showScrollDebounced","className","border","labelEl","lastElementChild","showingLength","wasError","contains","inputLength","isError","labelOptions","scrollHeight","clientHeight","setValueSilently","event","Event","bubbles","cancelable","fireFakeInput","originalValue","silent","wrapDraftText","Error","Valid","setState","ScrollableBase","logPrefix","onScrollMeasure","isHeavyAnimationInProgress","needCheckAfterAnimation","onScroll","passive","cancelAnimationFrame","element","position","maxDistance","forceDirection","forceDuration","axis","Scrollable","onScrollOffset","withPaddingContainer","super","onAdditionalScroll","onScrolledTop","onScrolledBottom","lastScrollTop","lastScrollDirection","loadedAll","top","bottom","splitUp","scrollTop","checkForTriggers","maxScrollTop","setListeners","elements","padding","prepend","offsetHeight","getDistanceToEnd","y","ScrollableX","splitCount","scrollHorizontally","deltaX","scrollWidth","clientWidth","scrollLeft","deltaY","getRichValue","field","withEntities","lines","line","join","combineSameEntities","CheckboxField","restriction","disabled","toggleDisability","stateKey","stateValue","stateValues","setByKey","textArgs","box","checkSvg","createElementNS","setAttributeNS","use","bg","withHover","disable","findUpTag","tag","closest","serverTimeManager","to","addTaskListener","task","payload","markdownTags","bold","match","entityName","underline","italic","monospace","strikethrough","link","mentionName","getRichElementValue","selNode","selOffset","offset","nodeType","nodeValue","substr","parentNode","getAttribute","href","user_id","dataset","follow","isSelected","isBlock","splice","alt","curChild","nextSibling","findUpAttribute","attribute","isInputEmpty","hasAttribute","bytesToHex","bytes","arr","i","toString","bytesFromHex","hexString","len","Uint8Array","ceil","start","parseInt","charAt","bytesToBase64","mod3","nLen","nUint24","nIdx","String","fromCharCode","uint6ToBase64","nUint6","bytesCmp","bytes1","bytes2","bufferConcats","reduce","acc","v","byteLength","tmp","lastLength","set","ArrayBuffer","blobSupported","fileWriter","write","mimeType","saveFileCallback","blobParts","part","truncate","finalize","saveToStorage","dbName","useStorage","STORAGES","openDatabase","openDbPromise","caches","open","entryName","timeoutOperation","cache","put","fileName","method","Response","headers","save","callback","reject","rejected","timeout","fakeWriter","getFakeFileWriter","saveFile","enabled","map","deleteAll","times","getLanguageChangeButton","appendTo","getConfig","config","suggested_lang_code","lastRequestedLangCode","getStrings","getCacheLangPack","strings","backup","string","backupString","btnChangeLanguage","getLangPack","TrackingMonkey","inputField","max","needFrame","playAnimation","frame","min","idleAnimation","canvas","direction","setDirection","setSpeed","play","loadPromise","loadAnimationFromURL","loop","autoplay","waitForFirstFrame","_animation","currentFrame","pause","CodeInputField"],"mappings":"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","file":"13.f0b27d519201c3d897b8.chunk.js","sourcesContent":["/*\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 { formatPhoneNumber, putPreloader } from \"../components/misc\";\r\nimport Scrollable from '../components/scrollable';\r\nimport Countries, { Country as _Country } from \"../countries\";\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 { isAppleMobile } from \"../helpers/userAgent\";\r\nimport fastSmoothScroll from \"../helpers/fastSmoothScroll\";\r\nimport { isTouchSupported } from \"../helpers/touchSupport\";\r\nimport App from \"../config/app\";\r\nimport Modes from \"../config/modes\";\r\nimport { _i18n, i18n } from \"../lib/langPack\";\r\nimport lottieLoader from \"../lib/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\n\r\ntype Country = _Country & {\r\n li?: HTMLLIElement[]\r\n};\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 name: 'Test Country',\r\n phoneCode: '999 66',\r\n code: 'TC',\r\n emoji: '🤔',\r\n pattern: '999 66 XXX XX'\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\r\n let lastCountrySelected: Country = null;\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 plainText: true\r\n });\r\n\r\n countryInputField.container.classList.add('input-select');\r\n\r\n const countryInput = countryInputField.input as HTMLInputElement;\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 = c.emoji;\r\n\r\n const liArr: Array<HTMLLIElement> = [];\r\n c.phoneCode.split(' and ').forEach((phoneCode: string) => {\r\n const li = document.createElement('li');\r\n\r\n let wrapped = RichTextProcessor.wrapEmojiText(emoji);\r\n if(RichTextProcessor.emojiSupported) {\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 li.append(c.name);\r\n\r\n const span = document.createElement('span');\r\n span.classList.add('phone-code');\r\n span.innerText = '+' + phoneCode;\r\n li.appendChild(span);\r\n\r\n liArr.push(li);\r\n selectList.append(li);\r\n });\r\n\r\n c.li = 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 let target = e.target as HTMLElement;\r\n if(target.tagName !== 'LI') target = findUpTag(target, 'LI');\r\n \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 countryName = target.childNodes[1].textContent;//target.innerText.split('\\n').shift();\r\n const phoneCode = target.querySelector<HTMLElement>('.phone-code').innerText;\r\n\r\n countryInput.value = countryName;\r\n lastCountrySelected = countries.find(c => c.name === countryName);\r\n \r\n telEl.value = lastValue = phoneCode;\r\n hidePicker();\r\n setTimeout(() => telEl.focus(), 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 c.li.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(page.pageEl.parentElement.parentElement, countryInput, 'start', 4);\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', function(this: typeof countryInput, e) {\r\n if(e.ctrlKey || e.key === 'Control') return false;\r\n\r\n //let i = new RegExp('^' + this.value, 'i');\r\n let _value = this.value.toLowerCase();\r\n let matches: Country[] = [];\r\n countries.forEach((c) => {\r\n let good = c.name.toLowerCase().indexOf(_value) !== -1/* === 0 */;//i.test(c.name);\r\n\r\n c.li.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 c.li.forEach(li => li.style.display = '');\r\n });\r\n } else if(matches.length === 1 && e.key === 'Enter') {\r\n selectCountryByTarget(matches[0].li[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 let pasted = false;\r\n let lastValue = '';\r\n \r\n const telInputField = new InputField({\r\n label: 'Login.PhoneLabel',\r\n plainText: true,\r\n name: 'phone'\r\n });\r\n let telEl = telInputField.input as HTMLInputElement;\r\n telEl.type = 'tel';\r\n telEl.autocomplete = 'rr55RandomRR55';\r\n telEl.addEventListener('input', function(this: typeof telEl, e) {\r\n //console.log('input', this.value);\r\n this.classList.remove('error');\r\n\r\n lottieLoader.loadLottieWorkers();\r\n\r\n const value = this.value;\r\n const diff = Math.abs(value.length - lastValue.length);\r\n if(diff > 1 && !pasted && isAppleMobile) {\r\n this.value = lastValue + value;\r\n }\r\n\r\n pasted = false;\r\n\r\n telInputField.setLabel();\r\n\r\n let formatted: string, country: Country;\r\n if(this.value.replace(/\\++/, '+') === '+') {\r\n this.value = '+';\r\n } else {\r\n const o = formatPhoneNumber(this.value);\r\n formatted = o.formatted;\r\n country = o.country;\r\n this.value = lastValue = formatted ? '+' + formatted : '';\r\n }\r\n\r\n //console.log(formatted, country);\r\n\r\n let countryName = country ? country.name : ''/* 'Unknown' */;\r\n if(countryName !== countryInput.value && (!lastCountrySelected || !country || lastCountrySelected.phoneCode !== country.phoneCode)) {\r\n countryInput.value = countryName;\r\n lastCountrySelected = country;\r\n }\r\n\r\n //if(country && (this.value.length - 1) >= (country.pattern ? country.pattern.length : 9)) {\r\n if(country || (this.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 telEl.addEventListener('paste', (e) => {\r\n pasted = true;\r\n //console.log('paste', telEl.value);\r\n });\r\n\r\n /* telEl.addEventListener('change', (e) => {\r\n console.log('change', telEl.value);\r\n }); */\r\n\r\n telEl.addEventListener('keypress', function(this: typeof telEl, 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 } else if(/\\D/.test(e.key) && !(e.metaKey || e.ctrlKey) && e.key !== 'Backspace' && !(e.key === '+' && e.shiftKey/* && !this.value */)) {\r\n e.preventDefault();\r\n return false;\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 = telEl.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 _i18n(h4, 'Login.Title');\r\n\r\n const subtitle = document.createElement('div');\r\n subtitle.classList.add('subtitle');\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 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 let country = countries.find((c) => c.code === nearestDcResult.country);\r\n if(country) {\r\n if(!countryInput.value.length && !telEl.value.length) {\r\n countryInput.value = country.name;\r\n lastCountrySelected = country;\r\n telEl.value = lastValue = '+' + country.phoneCode.split(' and ').shift();\r\n }\r\n }\r\n \r\n //console.log('woohoo', nearestDcResult, country);\r\n })//.catch(tryAgain);\r\n };\r\n\r\n if(!isTouchSupported) {\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 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 { pause } from '../helpers/schedulers';\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\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.setUserAuth(authorization.user.id);\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=\" + encoded.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/\\=+$/, \"\");\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.type) {\r\n case 'SESSION_PASSWORD_NEEDED':\r\n console.warn('pageSignQR: SESSION_PASSWORD_NEEDED');\r\n err.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 mediaSizes from '../helpers/mediaSizes';\r\nimport { AuthSentCode, AuthSentCodeType, AuthSignIn } from '../layer';\r\nimport appStateManager from '../lib/appManagers/appStateManager';\r\nimport apiManager from '../lib/mtproto/mtprotoworker';\r\nimport Page from './page';\r\nimport pageSignIn from './pageSignIn';\r\nimport TrackingMonkey from '../components/monkeys/tracking';\r\nimport CodeInputField from '../components/codeInputField';\r\nimport { i18n, LangPackKey } from '../lib/langPack';\r\nimport { randomLong } from '../helpers/random';\r\nimport replaceContent from '../helpers/dom/replaceContent';\r\n\r\nlet authCode: AuthSentCode.authSentCode = null;\r\n\r\nlet headerElement: HTMLHeadElement = null;\r\nlet sentTypeElement: HTMLParagraphElement = null;\r\nlet codeInput: HTMLInputElement;\r\n\r\nlet onFirstMount = (): Promise<any> => {\r\n const CODELENGTH = (authCode.type as AuthSentCodeType.authSentCodeTypeApp).length;\r\n\r\n const codeInputField = new CodeInputField({\r\n label: 'Code',\r\n name: randomLong(),\r\n length: CODELENGTH,\r\n onFill: (code) => {\r\n submitCode(code);\r\n }\r\n });\r\n\r\n codeInput = codeInputField.input as HTMLInputElement;\r\n\r\n page.pageEl.querySelector('.input-wrapper').append(codeInputField.container);\r\n\r\n const editButton = page.pageEl.querySelector('.phone-edit') as HTMLElement;\r\n\r\n editButton.addEventListener('click', function() {\r\n return pageSignIn.mount();\r\n });\r\n\r\n const cleanup = () => {\r\n setTimeout(() => {\r\n monkey.remove();\r\n }, 300);\r\n };\r\n\r\n const submitCode = (code: string) => {\r\n codeInput.setAttribute('disabled', 'true');\r\n\r\n const params: AuthSignIn = {\r\n phone_number: authCode.phone_number,\r\n phone_code_hash: authCode.phone_code_hash,\r\n phone_code: code\r\n };\r\n\r\n //console.log('invoking auth.signIn with params:', params);\r\n\r\n apiManager.invokeApi('auth.signIn', params, {ignoreErrors: true})\r\n .then((response) => {\r\n //console.log('auth.signIn response:', response);\r\n \r\n switch(response._) {\r\n case 'auth.authorization':\r\n apiManager.setUserAuth(response.user.id);\r\n\r\n import('./pageIm').then(m => {\r\n m.default.mount();\r\n });\r\n cleanup();\r\n break;\r\n case 'auth.authorizationSignUpRequired':\r\n //console.log('Registration needed!');\r\n\r\n import('./pageSignUp').then(m => {\r\n m.default.mount({\r\n 'phone_number': authCode.phone_number,\r\n 'phone_code_hash': authCode.phone_code_hash\r\n });\r\n });\r\n\r\n cleanup();\r\n break;\r\n /* default:\r\n codeInput.innerText = response._;\r\n break; */\r\n }\r\n }).catch(async(err) => {\r\n let good = false;\r\n switch(err.type) {\r\n case 'SESSION_PASSWORD_NEEDED':\r\n //console.warn('pageAuthCode: SESSION_PASSWORD_NEEDED');\r\n good = true;\r\n err.handled = true;\r\n await (await import('./pagePassword')).default.mount(); // lol\r\n setTimeout(() => {\r\n codeInput.value = '';\r\n }, 300);\r\n break;\r\n case 'PHONE_CODE_EXPIRED':\r\n codeInput.classList.add('error');\r\n replaceContent(codeInputField.label, i18n('PHONE_CODE_EXPIRED'));\r\n break;\r\n case 'PHONE_CODE_EMPTY':\r\n case 'PHONE_CODE_INVALID':\r\n codeInput.classList.add('error');\r\n replaceContent(codeInputField.label, i18n('PHONE_CODE_INVALID'));\r\n break;\r\n default:\r\n codeInputField.label.innerText = err.type;\r\n break;\r\n }\r\n\r\n if(!good) {\r\n codeInputField.select();\r\n }\r\n\r\n codeInput.removeAttribute('disabled');\r\n });\r\n };\r\n\r\n const imageDiv = page.pageEl.querySelector('.auth-image') as HTMLDivElement;\r\n const size = mediaSizes.isMobile ? 100 : 166;\r\n const monkey = new TrackingMonkey(codeInputField, size);\r\n imageDiv.append(monkey.container);\r\n return monkey.load();\r\n};\r\n\r\nconst page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof authCode) => {\r\n authCode = _authCode;\r\n\r\n if(!headerElement) {\r\n headerElement = page.pageEl.getElementsByClassName('phone')[0] as HTMLHeadElement;\r\n sentTypeElement = page.pageEl.getElementsByClassName('sent-type')[0] as HTMLParagraphElement;\r\n } else {\r\n codeInput.value = '';\r\n\r\n const evt = document.createEvent('HTMLEvents');\r\n evt.initEvent('input', false, true);\r\n codeInput.dispatchEvent(evt);\r\n }\r\n\r\n headerElement.innerText = authCode.phone_number;\r\n let key: LangPackKey, args: any[];\r\n switch(authCode.type._) {\r\n case 'auth.sentCodeTypeSms':\r\n key = 'Login.Code.SentSms';\r\n break;\r\n case 'auth.sentCodeTypeApp': \r\n key = 'Login.Code.SentInApp';\r\n break;\r\n case 'auth.sentCodeTypeCall': \r\n key = 'Login.Code.SentCall';\r\n break;\r\n default:\r\n key = 'Login.Code.SentUnknown';\r\n args = [authCode.type._];\r\n break;\r\n }\r\n\r\n replaceContent(sentTypeElement, i18n(key, args));\r\n\r\n appStateManager.pushToState('authState', {_: 'authStateAuthCode', sentCode: _authCode});\r\n}, () => {\r\n codeInput.focus();\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\nexport default function replaceContent(elem: HTMLElement, node: string | Node) {\r\n if(typeof(node) === 'string') {\r\n elem.innerHTML = node;\r\n return;\r\n }\r\n\r\n // * children.length doesn't count text nodes\r\n const firstChild = elem.firstChild;\r\n if(firstChild) {\r\n if(elem.lastChild === firstChild) {\r\n firstChild.replaceWith(node);\r\n } else {\r\n elem.textContent = '';\r\n elem.append(node);\r\n }\r\n } else {\r\n elem.append(node);\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 findUpAttribute from \"../helpers/dom/findUpAttribute\";\r\nimport getRichValue from \"../helpers/dom/getRichValue\";\r\nimport isInputEmpty from \"../helpers/dom/isInputEmpty\";\r\nimport { debounce } from \"../helpers/schedulers\";\r\nimport { i18n, LangPackKey, _i18n } from \"../lib/langPack\";\r\nimport RichTextProcessor from \"../lib/richtextprocessor\";\r\n\r\nlet init = () => {\r\n document.addEventListener('paste', (e) => {\r\n if(!findUpAttribute(e.target, 'contenteditable=\"true\"')) {\r\n return;\r\n }\r\n //console.log('document paste');\r\n\r\n //console.log('messageInput paste');\r\n\r\n e.preventDefault();\r\n // @ts-ignore\r\n let text = (e.originalEvent || e).clipboardData.getData('text/plain');\r\n\r\n let entities = RichTextProcessor.parseEntities(text);\r\n //console.log('messageInput paste', text, entities);\r\n entities = entities.filter(e => e._ === 'messageEntityEmoji' || e._ === 'messageEntityLinebreak');\r\n //text = RichTextProcessor.wrapEmojiText(text);\r\n text = RichTextProcessor.wrapRichText(text, {entities, noLinks: true, wrappingDraft: true});\r\n\r\n // console.log('messageInput paste after', text);\r\n\r\n // @ts-ignore\r\n //let html = (e.originalEvent || e).clipboardData.getData('text/html');\r\n\r\n // @ts-ignore\r\n //console.log('paste text', text, );\r\n window.document.execCommand('insertHTML', false, text);\r\n });\r\n\r\n init = null;\r\n};\r\n\r\n// ! it doesn't respect symbols other than strongs\r\n/* const checkAndSetRTL = (input: HTMLElement) => {\r\n //const isEmpty = isInputEmpty(input);\r\n //console.log('input', isEmpty);\r\n\r\n //const char = [...getRichValue(input)][0];\r\n const char = (input instanceof HTMLInputElement ? input.value : input.innerText)[0];\r\n let direction = 'ltr';\r\n if(char && checkRTL(char)) {\r\n direction = 'rtl';\r\n }\r\n\r\n //console.log('RTL', direction, char);\r\n\r\n input.style.direction = direction;\r\n}; */\r\n\r\nexport enum InputState {\r\n Neutral = 0,\r\n Valid = 1,\r\n Error = 2\r\n};\r\n\r\nexport type InputFieldOptions = {\r\n placeholder?: LangPackKey, \r\n label?: LangPackKey, \r\n labelOptions?: any[],\r\n labelText?: string,\r\n name?: string, \r\n maxLength?: number, \r\n showLengthOn?: number,\r\n plainText?: true,\r\n animate?: true\r\n};\r\n\r\nclass InputField {\r\n public container: HTMLElement;\r\n public input: HTMLElement;\r\n public inputFake: HTMLElement;\r\n public label: HTMLLabelElement;\r\n\r\n public originalValue: string;\r\n\r\n //public onLengthChange: (length: number, isOverflow: boolean) => void;\r\n protected wasInputFakeClientHeight: number;\r\n protected showScrollDebounced: () => void;\r\n\r\n constructor(public options: InputFieldOptions = {}) {\r\n this.container = document.createElement('div');\r\n this.container.classList.add('input-field');\r\n\r\n if(options.maxLength) {\r\n options.showLengthOn = Math.round(options.maxLength / 3);\r\n }\r\n\r\n const {placeholder, maxLength, showLengthOn, name, plainText} = options;\r\n\r\n let label = options.label || options.labelText;\r\n\r\n let input: HTMLElement;\r\n if(!plainText) {\r\n if(init) {\r\n init();\r\n }\r\n\r\n this.container.innerHTML = `\r\n <div contenteditable=\"true\" class=\"input-field-input\"></div>\r\n `;\r\n\r\n input = this.container.firstElementChild as HTMLElement;\r\n const observer = new MutationObserver(() => {\r\n //checkAndSetRTL(input);\r\n\r\n if(processInput) {\r\n processInput();\r\n }\r\n });\r\n\r\n // * because if delete all characters there will br left\r\n input.addEventListener('input', () => {\r\n if(isInputEmpty(input)) {\r\n input.innerHTML = '';\r\n }\r\n\r\n if(this.inputFake) {\r\n this.inputFake.innerHTML = input.innerHTML;\r\n this.onFakeInput();\r\n }\r\n });\r\n \r\n // ! childList for paste first symbol\r\n observer.observe(input, {characterData: true, childList: true, subtree: true});\r\n\r\n if(options.animate) {\r\n input.classList.add('scrollable', 'scrollable-y');\r\n this.wasInputFakeClientHeight = 0;\r\n this.showScrollDebounced = debounce(() => this.input.classList.remove('no-scrollbar'), 150, false, true);\r\n this.inputFake = document.createElement('div');\r\n this.inputFake.setAttribute('contenteditable', 'true');\r\n this.inputFake.className = input.className + ' input-field-input-fake';\r\n }\r\n } else {\r\n this.container.innerHTML = `\r\n <input type=\"text\" ${name ? `name=\"${name}\"` : ''} autocomplete=\"off\" ${label ? 'required=\"\"' : ''} class=\"input-field-input\">\r\n `;\r\n\r\n input = this.container.firstElementChild as HTMLElement;\r\n //input.addEventListener('input', () => checkAndSetRTL(input));\r\n }\r\n\r\n input.setAttribute('dir', 'auto');\r\n\r\n if(placeholder) {\r\n _i18n(input, placeholder, undefined, 'placeholder');\r\n\r\n if(this.inputFake) {\r\n _i18n(this.inputFake, placeholder, undefined, 'placeholder');\r\n }\r\n }\r\n\r\n if(label || placeholder) {\r\n const border = document.createElement('div');\r\n border.classList.add('input-field-border');\r\n this.container.append(border);\r\n }\r\n\r\n if(label) {\r\n this.label = document.createElement('label');\r\n this.setLabel();\r\n this.container.append(this.label);\r\n }\r\n\r\n let processInput: () => void;\r\n if(maxLength) {\r\n const labelEl = this.container.lastElementChild as HTMLLabelElement;\r\n let showingLength = false;\r\n\r\n processInput = () => {\r\n const wasError = input.classList.contains('error');\r\n // * https://stackoverflow.com/a/54369605 #2 to count emoji as 1 symbol\r\n const inputLength = plainText ? (input as HTMLInputElement).value.length : [...getRichValue(input, false).value].length;\r\n const diff = maxLength - inputLength;\r\n const isError = diff < 0;\r\n input.classList.toggle('error', isError);\r\n\r\n //this.onLengthChange && this.onLengthChange(inputLength, isError);\r\n\r\n if(isError || diff <= showLengthOn) {\r\n this.setLabel();\r\n labelEl.append(` (${maxLength - inputLength})`);\r\n if(!showingLength) showingLength = true;\r\n } else if((wasError && !isError) || showingLength) {\r\n this.setLabel();\r\n showingLength = false;\r\n }\r\n };\r\n\r\n input.addEventListener('input', processInput);\r\n }\r\n\r\n this.input = input;\r\n }\r\n\r\n public select() {\r\n if((this.input as HTMLInputElement).value) { // * avoid selecting whole empty field on iOS devices\r\n (this.input as HTMLInputElement).select(); // * select text\r\n }\r\n }\r\n\r\n public setLabel() {\r\n this.label.textContent = '';\r\n if(this.options.labelText) {\r\n this.label.innerHTML = this.options.labelText;\r\n } else {\r\n this.label.append(i18n(this.options.label, this.options.labelOptions));\r\n }\r\n }\r\n\r\n public onFakeInput() {\r\n const {scrollHeight, clientHeight} = this.inputFake;\r\n if(this.wasInputFakeClientHeight && this.wasInputFakeClientHeight !== clientHeight) {\r\n this.input.classList.add('no-scrollbar'); // ! в сафари может вообще не появиться скролл после анимации, так как ему нужен полный reflow блока с overflow.\r\n this.showScrollDebounced();\r\n }\r\n\r\n this.wasInputFakeClientHeight = clientHeight;\r\n this.input.style.height = scrollHeight ? scrollHeight + 'px' : '';\r\n }\r\n\r\n get value() {\r\n return this.options.plainText ? (this.input as HTMLInputElement).value : getRichValue(this.input, false).value;\r\n //return getRichValue(this.input);\r\n }\r\n\r\n set value(value: string) {\r\n this.setValueSilently(value, false);\r\n\r\n const event = new Event('input', {bubbles: true, cancelable: true});\r\n this.input.dispatchEvent(event);\r\n }\r\n\r\n public setValueSilently(value: string, fireFakeInput = true) {\r\n if(this.options.plainText) {\r\n (this.input as HTMLInputElement).value = value;\r\n } else {\r\n this.input.innerHTML = value;\r\n \r\n if(this.inputFake) {\r\n this.inputFake.innerHTML = value;\r\n\r\n if(fireFakeInput) {\r\n this.onFakeInput();\r\n }\r\n }\r\n }\r\n }\r\n\r\n public isValid() {\r\n return !this.input.classList.contains('error') && this.value !== this.originalValue;\r\n }\r\n\r\n public setOriginalValue(value: InputField['originalValue'] = '', silent = false) {\r\n this.originalValue = value;\r\n\r\n if(!this.options.plainText) {\r\n value = RichTextProcessor.wrapDraftText(value);\r\n }\r\n\r\n if(silent) {\r\n this.setValueSilently(value, false); \r\n } else {\r\n this.value = value;\r\n }\r\n }\r\n\r\n public setState(state: InputState, label?: LangPackKey) {\r\n if(label) {\r\n this.label.textContent = '';\r\n this.label.append(i18n(label, this.options.labelOptions));\r\n }\r\n\r\n this.input.classList.toggle('error', !!(state & InputState.Error));\r\n this.input.classList.toggle('valid', !!(state & InputState.Valid));\r\n }\r\n\r\n public setError(label?: LangPackKey) {\r\n this.setState(InputState.Error, label);\r\n }\r\n}\r\n\r\nexport default InputField;\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 { isTouchSupported } from \"../helpers/touchSupport\";\r\nimport { logger, LogTypes } from \"../lib/logger\";\r\nimport fastSmoothScroll, { FocusDirection } 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(\r\n element: HTMLElement,\r\n position: ScrollLogicalPosition,\r\n margin?: number,\r\n maxDistance?: number,\r\n forceDirection?: FocusDirection,\r\n forceDuration?: number,\r\n axis?: 'x' | 'y'\r\n ) {\r\n //return Promise.resolve();\r\n return fastSmoothScroll(this.container, element, position, margin, maxDistance, forceDirection, forceDuration, axis);\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 = null;\r\n public onScrolledTop: () => void = null;\r\n public onScrolledBottom: () => void = null;\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[]) {\r\n (this.splitUp || this.padding || this.container).prepend(...elements);\r\n }\r\n\r\n public append(...elements: HTMLElement[]) {\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(!isTouchSupported) {\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 * 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 { MOUNT_CLASS_TO } from \"../../config/debug\";\r\nimport { MessageEntity } from \"../../layer\";\r\nimport RichTextProcessor from \"../../lib/richtextprocessor\";\r\nimport getRichElementValue from \"./getRichElementValue\";\r\n\r\nexport default function getRichValue(field: HTMLElement, withEntities = true) {\r\n const lines: string[] = [];\r\n const line: string[] = [];\r\n\r\n const entities: MessageEntity[] = withEntities ? [] : undefined;\r\n getRichElementValue(field, lines, line, undefined, undefined, entities);\r\n if(line.length) {\r\n lines.push(line.join(''));\r\n }\r\n\r\n let value = lines.join('\\n');\r\n value = value.replace(/\\u00A0/g, ' ');\r\n\r\n if(entities) {\r\n RichTextProcessor.combineSameEntities(entities);\r\n }\r\n\r\n //console.log('getRichValue:', value, entities);\r\n\r\n return {value, entities};\r\n}\r\n\r\nMOUNT_CLASS_TO.getRichValue = getRichValue;\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.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) {\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\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 * 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 { MessageEntity } from \"../../layer\";\r\n\r\nexport type MarkdownType = 'bold' | 'italic' | 'underline' | 'strikethrough' | 'monospace' | 'link' | 'mentionName';\r\nexport type MarkdownTag = {\r\n match: string,\r\n entityName: 'messageEntityBold' | 'messageEntityUnderline' | 'messageEntityItalic' | 'messageEntityPre' | 'messageEntityStrike' | 'messageEntityTextUrl' | 'messageEntityMentionName';\r\n};\r\nexport const markdownTags: {[type in MarkdownType]: MarkdownTag} = {\r\n bold: {\r\n match: '[style*=\"font-weight\"], b',\r\n entityName: 'messageEntityBold'\r\n },\r\n underline: {\r\n match: '[style*=\"underline\"], u',\r\n entityName: 'messageEntityUnderline'\r\n },\r\n italic: {\r\n match: '[style*=\"italic\"], i',\r\n entityName: 'messageEntityItalic'\r\n },\r\n monospace: {\r\n match: '[style*=\"monospace\"], [face=\"monospace\"]',\r\n entityName: 'messageEntityPre'\r\n },\r\n strikethrough: {\r\n match: '[style*=\"line-through\"], strike',\r\n entityName: 'messageEntityStrike'\r\n },\r\n link: {\r\n match: 'A:not(.follow)',\r\n entityName: 'messageEntityTextUrl'\r\n },\r\n mentionName: {\r\n match: 'A.follow',\r\n entityName: 'messageEntityMentionName'\r\n }\r\n};\r\n\r\nexport default function getRichElementValue(node: HTMLElement, lines: string[], line: string[], selNode?: Node, selOffset?: number, entities?: MessageEntity[], offset = {offset: 0}) {\r\n if(node.nodeType === 3) { // TEXT\r\n const nodeValue = node.nodeValue;\r\n\r\n if(selNode === node) {\r\n line.push(nodeValue.substr(0, selOffset) + '\\x01' + nodeValue.substr(selOffset));\r\n } else {\r\n line.push(nodeValue);\r\n }\r\n\r\n if(entities && nodeValue.trim()) {\r\n if(node.parentNode) {\r\n const parentElement = node.parentElement;\r\n \r\n for(const type in markdownTags) {\r\n const tag = markdownTags[type as MarkdownType];\r\n const closest = parentElement.closest(tag.match + ', [contenteditable]');\r\n if(closest && closest.getAttribute('contenteditable') === null) {\r\n if(tag.entityName === 'messageEntityTextUrl') {\r\n entities.push({\r\n _: tag.entityName,\r\n url: (parentElement as HTMLAnchorElement).href,\r\n offset: offset.offset,\r\n length: nodeValue.length\r\n });\r\n } else if(tag.entityName === 'messageEntityMentionName') {\r\n entities.push({\r\n _: tag.entityName,\r\n offset: offset.offset,\r\n length: nodeValue.length,\r\n user_id: +parentElement.dataset.follow\r\n });\r\n } else {\r\n entities.push({\r\n _: tag.entityName as any,\r\n offset: offset.offset,\r\n length: nodeValue.length\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n offset.offset += nodeValue.length;\r\n\r\n return;\r\n }\r\n\r\n if(node.nodeType !== 1) { // NON-ELEMENT\r\n return;\r\n }\r\n\r\n const isSelected = (selNode === node);\r\n const isBlock = node.tagName === 'DIV' || node.tagName === 'P';\r\n if(isBlock && line.length || node.tagName === 'BR') {\r\n lines.push(line.join(''));\r\n line.splice(0, line.length);\r\n } else if(node.tagName === 'IMG') {\r\n const alt = (node as HTMLImageElement).alt;\r\n if(alt) {\r\n line.push(alt);\r\n offset.offset += alt.length;\r\n }\r\n }\r\n\r\n if(isSelected && !selOffset) {\r\n line.push('\\x01');\r\n }\r\n\r\n let curChild = node.firstChild as HTMLElement;\r\n while(curChild) {\r\n getRichElementValue(curChild, lines, line, selNode, selOffset, entities, offset);\r\n curChild = curChild.nextSibling as any;\r\n }\r\n\r\n if(isSelected && selOffset) {\r\n line.push('\\x01');\r\n }\r\n\r\n if(isBlock && line.length) {\r\n lines.push(line.join(''));\r\n line.splice(0, line.length);\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 findUpAttribute(el: any, attribute: string): HTMLElement {\r\n return el.closest(`[${attribute}]`);\r\n /* if(el.getAttribute(attribute) !== null) return el; // 03.02.2020\r\n\r\n while(el.parentElement) {\r\n el = el.parentElement;\r\n if(el.getAttribute(attribute) !== null) \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 getRichValue from \"./getRichValue\";\r\n\r\nexport default function isInputEmpty(element: HTMLElement) {\r\n if(element.hasAttribute('contenteditable') || element.tagName !== 'INPUT') {\r\n /* const value = element.innerText;\r\n\r\n return !value.trim() && !serializeNodes(Array.from(element.childNodes)).trim(); */\r\n return !getRichValue(element, false).value.trim();\r\n } else {\r\n return !(element as HTMLInputElement).value.trim();\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 * 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 arr: string[] = new Array(bytes.length);\r\n for(let i = 0; i < bytes.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","/*\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 { blobConstruct, readBlobAsUint8Array } from \"../helpers/blob\";\r\n\r\nexport class FileManager {\r\n public blobSupported = true;\r\n \r\n constructor() {\r\n try {\r\n blobConstruct([], '');\r\n } catch(e) {\r\n this.blobSupported = false;\r\n }\r\n }\r\n \r\n public isAvailable() {\r\n return this.blobSupported;\r\n }\r\n \r\n public write(fileWriter: ReturnType<FileManager['getFakeFileWriter']>, bytes: Uint8Array | Blob | string): Promise<void> {\r\n if(bytes instanceof Blob) { // is file bytes\r\n return readBlobAsUint8Array(bytes).then(arr => {\r\n return fileWriter.write(arr);\r\n });\r\n } else {\r\n return fileWriter.write(bytes);\r\n }\r\n }\r\n\r\n public getFakeFileWriter(mimeType: string, saveFileCallback?: (blob: Blob) => Promise<Blob>) {\r\n const blobParts: Array<Uint8Array | string> = [];\r\n const fakeFileWriter = {\r\n write: async(part: Uint8Array | string) => {\r\n if(!this.blobSupported) {\r\n throw false;\r\n }\r\n \r\n blobParts.push(part);\r\n },\r\n truncate: () => {\r\n blobParts.length = 0;\r\n },\r\n finalize: (saveToStorage = true) => {\r\n const blob = blobConstruct(blobParts, mimeType);\r\n\r\n if(saveToStorage && saveFileCallback) {\r\n saveFileCallback(blob);\r\n }\r\n \r\n return blob;\r\n }\r\n };\r\n \r\n return fakeFileWriter;\r\n }\r\n}\r\n\r\nexport default new FileManager();\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 Modes from '../config/modes';\r\nimport { blobConstruct } from '../helpers/blob';\r\nimport FileManager from './filemanager';\r\n//import { MOUNT_CLASS_TO } from './mtproto/mtproto_config';\r\n//import { logger } from './polyfill';\r\n\r\nexport type CacheStorageDbName = 'cachedFiles' | 'cachedStreamChunks' | 'cachedAssets';\r\n\r\nexport default class CacheStorageController {\r\n private static STORAGES: CacheStorageController[] = [];\r\n private openDbPromise: Promise<Cache>;\r\n\r\n private useStorage = true;\r\n\r\n //private log: ReturnType<typeof logger> = logger('CS');\r\n\r\n constructor(private dbName: CacheStorageDbName) {\r\n if(Modes.test) {\r\n this.dbName += '_test';\r\n }\r\n\r\n if(CacheStorageController.STORAGES.length) {\r\n this.useStorage = CacheStorageController.STORAGES[0].useStorage;\r\n }\r\n \r\n this.openDatabase();\r\n CacheStorageController.STORAGES.push(this);\r\n }\r\n\r\n private openDatabase(): Promise<Cache> {\r\n return this.openDbPromise ?? (this.openDbPromise = caches.open(this.dbName));\r\n }\r\n\r\n public delete(entryName: string) {\r\n return this.timeoutOperation((cache) => cache.delete('/' + entryName));\r\n }\r\n\r\n public deleteAll() {\r\n return caches.delete(this.dbName);\r\n }\r\n\r\n public get(entryName: string) {\r\n return this.timeoutOperation((cache) => cache.match('/' + entryName));\r\n }\r\n\r\n public save(entryName: string, response: Response) {\r\n // return new Promise((resolve) => {}); // DEBUG\r\n return this.timeoutOperation((cache) => cache.put('/' + entryName, response));\r\n }\r\n\r\n public getFile(fileName: string, method: 'blob' | 'json' | 'text' = 'blob'): Promise<any> {\r\n /* if(method === 'blob') {\r\n return Promise.reject();\r\n } */\r\n\r\n // const str = `get fileName: ${fileName}`;\r\n // console.time(str);\r\n return this.get(fileName).then((response) => {\r\n if(!response) {\r\n //console.warn('getFile:', response, fileName);\r\n throw 'NO_ENTRY_FOUND';\r\n }\r\n\r\n const promise = response[method]();\r\n // promise.then(() => {\r\n // console.timeEnd(str);\r\n // });\r\n return promise;\r\n });\r\n }\r\n\r\n public saveFile(fileName: string, blob: Blob | Uint8Array) {\r\n //return Promise.resolve(blobConstruct([blob]));\r\n if(!(blob instanceof Blob)) {\r\n blob = blobConstruct(blob) as Blob;\r\n }\r\n\r\n const response = new Response(blob, {\r\n headers: {\r\n 'Content-Length': '' + blob.size\r\n }\r\n });\r\n \r\n return this.save(fileName, response).then(() => blob as Blob);\r\n }\r\n\r\n public timeoutOperation<T>(callback: (cache: Cache) => Promise<T>) {\r\n if(!this.useStorage) {\r\n return Promise.reject('STORAGE_OFFLINE');\r\n }\r\n\r\n return new Promise<T>(async(resolve, reject) => {\r\n let rejected = false;\r\n const timeout = setTimeout(() => {\r\n reject();\r\n //console.warn('CACHESTORAGE TIMEOUT');\r\n rejected = true;\r\n }, 15e3);\r\n\r\n try {\r\n const cache = await this.openDatabase();\r\n if(!cache) {\r\n this.useStorage = false;\r\n this.openDbPromise = undefined;\r\n throw 'no cache?';\r\n }\r\n\r\n const res = await callback(cache);\r\n\r\n if(rejected) return;\r\n resolve(res);\r\n } catch(err) {\r\n reject(err);\r\n }\r\n\r\n clearTimeout(timeout);\r\n });\r\n }\r\n\r\n public getFileWriter(fileName: string, mimeType: string) {\r\n const fakeWriter = FileManager.getFakeFileWriter(mimeType, (blob) => {\r\n return this.saveFile(fileName, blob).catch(() => blob);\r\n });\r\n\r\n return Promise.resolve(fakeWriter);\r\n }\r\n\r\n public static toggleStorage(enabled: boolean) {\r\n return Promise.all(this.STORAGES.map(storage => {\r\n storage.useStorage = enabled;\r\n \r\n if(!enabled) {\r\n return storage.deleteAll();\r\n }\r\n }));\r\n }\r\n}\r\n\r\n//const cacheStorage = new CacheStorageController(); \r\n//MOUNT_CLASS_TO.cacheStorage = cacheStorage;\r\n//export default cacheStorage;\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 { cancelEvent } from \"../helpers/dom/cancelEvent\";\r\nimport { attachClickEvent } from \"../helpers/dom/clickEvent\";\r\nimport loadFonts from \"../helpers/dom/loadFonts\";\r\nimport { Config, LangPackDifference, LangPackString } from \"../layer\";\r\nimport I18n, { LangPackKey } from \"../lib/langPack\";\r\nimport apiManager from \"../lib/mtproto/mtprotoworker\";\r\nimport rootScope from \"../lib/rootScope\";\r\nimport Button from \"./button\";\r\nimport { putPreloader } from \"./misc\";\r\n\r\nlet set = false, times = 0;\r\nrootScope.addEventListener('language_change', () => {\r\n if(++times < 2) {\r\n return;\r\n }\r\n\r\n console.log('language_change');\r\n set = true;\r\n});\r\n\r\nfunction getLang(): Promise<[Config.config, LangPackString[], LangPackDifference.langPackDifference]> {\r\n if(cachedPromise) return cachedPromise;\r\n return cachedPromise = apiManager.getConfig().then(config => {\r\n if(config.suggested_lang_code !== I18n.lastRequestedLangCode) {\r\n //I18n.loadLangPack(config.suggested_lang_code);\r\n\r\n return Promise.all([\r\n config,\r\n I18n.getStrings(config.suggested_lang_code, ['Login.ContinueOnLanguage']),\r\n I18n.getCacheLangPack()\r\n ]);\r\n } else {\r\n return [] as any;\r\n }\r\n });\r\n}\r\n\r\nlet cachedPromise: ReturnType<typeof getLang>;\r\n\r\nexport default function getLanguageChangeButton(appendTo: HTMLElement) {\r\n if(set) return;\r\n getLang().then(([config, strings]) => {\r\n if(!config) {\r\n return;\r\n }\r\n\r\n const backup: LangPackString[] = [];\r\n strings.forEach(string => {\r\n const backupString = I18n.strings.get(string.key as LangPackKey);\r\n if(!backupString) {\r\n return;\r\n }\r\n \r\n backup.push(backupString);\r\n I18n.strings.set(string.key as LangPackKey, string);\r\n });\r\n\r\n const btnChangeLanguage = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.ContinueOnLanguage'});\r\n loadFonts().then(() => {\r\n window.requestAnimationFrame(() => {\r\n appendTo.append(btnChangeLanguage);\r\n });\r\n });\r\n\r\n rootScope.addEventListener('language_change', () => {\r\n btnChangeLanguage.remove();\r\n }, {once: true});\r\n\r\n backup.forEach(string => {\r\n I18n.strings.set(string.key as LangPackKey, string);\r\n });\r\n \r\n attachClickEvent(btnChangeLanguage, (e) => {\r\n cancelEvent(e);\r\n\r\n btnChangeLanguage.disabled = true;\r\n putPreloader(btnChangeLanguage);\r\n\r\n I18n.getLangPack(config.suggested_lang_code);\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 InputField from \"../inputField\";\r\nimport lottieLoader, { RLottiePlayer } from \"../../lib/lottieLoader\";\r\n\r\nexport default class TrackingMonkey {\r\n public container: HTMLElement;\r\n\r\n protected max = 45;\r\n protected needFrame = 0;\r\n\r\n protected animation: RLottiePlayer;\r\n protected idleAnimation: RLottiePlayer;\r\n\r\n protected loadPromise: Promise<any>;\r\n\r\n constructor(protected inputField: InputField, protected size: number) {\r\n this.container = document.createElement('div');\r\n this.container.classList.add('media-sticker-wrapper');\r\n\r\n const input = inputField.input;\r\n\r\n input.addEventListener('blur', () => {\r\n this.playAnimation(0);\r\n });\r\n\r\n input.addEventListener('input', (e) => {\r\n this.playAnimation(inputField.value.length);\r\n });\r\n\r\n /* codeInput.addEventListener('focus', () => {\r\n playAnimation(Math.max(codeInput.value.length, 1));\r\n }); */\r\n }\r\n\r\n // 1st symbol = frame 15\r\n // end symbol = frame 165\r\n public playAnimation(length: number) {\r\n if(!this.animation) return;\r\n\r\n length = Math.min(length, 30);\r\n let frame: number;\r\n if(length) {\r\n frame = Math.round(Math.min(this.max, length) * (165 / this.max) + 11.33);\r\n\r\n if(this.idleAnimation) {\r\n this.idleAnimation.stop(true);\r\n this.idleAnimation.canvas.style.display = 'none';\r\n }\r\n \r\n this.animation.canvas.style.display = '';\r\n } else {\r\n /* const cb = (frameNo: number) => {\r\n if(frameNo <= 1) { */\r\n /* idleAnimation.play();\r\n idleAnimation.canvas.style.display = '';\r\n animation.canvas.style.display = 'none'; */\r\n /* animation.removeListener('enterFrame', cb);\r\n }\r\n };\r\n animation.addListener('enterFrame', cb); */\r\n \r\n frame = 0;\r\n }\r\n //animation.playSegments([1, 2]);\r\n\r\n const direction = this.needFrame > frame ? -1 : 1;\r\n //console.log('keydown', length, frame, direction);\r\n\r\n this.animation.setDirection(direction);\r\n if(this.needFrame !== 0 && frame === 0) {\r\n this.animation.setSpeed(7);\r\n }\r\n /* let diff = Math.abs(needFrame - frame * direction);\r\n if((diff / 20) > 1) animation.setSpeed(diff / 20 | 0); */\r\n this.needFrame = frame;\r\n \r\n this.animation.play();\r\n\r\n /* animation.goToAndStop(15, true); */\r\n //animation.goToAndStop(length / max * );\r\n }\r\n\r\n public load() {\r\n if(this.loadPromise) return this.loadPromise;\r\n return this.loadPromise = Promise.all([\r\n lottieLoader.loadAnimationFromURL({\r\n container: this.container,\r\n loop: true,\r\n autoplay: true,\r\n width: this.size,\r\n height: this.size\r\n }, 'assets/img/TwoFactorSetupMonkeyIdle.tgs').then(animation => {\r\n this.idleAnimation = animation;\r\n\r\n // ! animationIntersector will stop animation instantly\r\n if(!this.inputField.value.length) {\r\n animation.play();\r\n }\r\n\r\n return lottieLoader.waitForFirstFrame(animation);\r\n }),\r\n\r\n lottieLoader.loadAnimationFromURL({\r\n container: this.container,\r\n loop: false,\r\n autoplay: false,\r\n width: this.size,\r\n height: this.size\r\n }, 'assets/img/TwoFactorSetupMonkeyTracking.tgs').then(_animation => {\r\n this.animation = _animation;\r\n\r\n if(!this.inputField.value.length) {\r\n this.animation.canvas.style.display = 'none';\r\n }\r\n\r\n this.animation.addEventListener('enterFrame', currentFrame => {\r\n //console.log('enterFrame', currentFrame, needFrame);\r\n //let currentFrame = Math.round(e.currentTime);\r\n \r\n if((this.animation.direction === 1 && currentFrame >= this.needFrame) ||\r\n (this.animation.direction === -1 && currentFrame <= this.needFrame)) {\r\n this.animation.setSpeed(1);\r\n this.animation.pause();\r\n }\r\n\r\n if(currentFrame === 0 && this.needFrame === 0) {\r\n //animation.curFrame = 0;\r\n \r\n if(this.idleAnimation) {\r\n this.idleAnimation.canvas.style.display = '';\r\n this.idleAnimation.play();\r\n this.animation.canvas.style.display = 'none';\r\n }\r\n }\r\n });\r\n //console.log(animation.getDuration(), animation.getDuration(true));\r\n\r\n return lottieLoader.waitForFirstFrame(_animation);\r\n })\r\n ]);\r\n }\r\n\r\n public remove() {\r\n if(this.animation) this.animation.remove();\r\n if(this.idleAnimation) this.idleAnimation.remove();\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 InputField, { InputFieldOptions } from \"./inputField\";\r\n\r\nexport default class CodeInputField extends InputField {\r\n constructor(options: InputFieldOptions & {\r\n length: number,\r\n onFill: (code: string) => void\r\n }) {\r\n super({\r\n plainText: true,\r\n ...options\r\n });\r\n\r\n const input = this.input as HTMLInputElement;\r\n input.type = 'tel';\r\n input.setAttribute('required', '');\r\n input.autocomplete = 'off';\r\n\r\n let lastLength = 0;\r\n this.input.addEventListener('input', (e) => {\r\n this.input.classList.remove('error');\r\n this.setLabel();\r\n \r\n const value = this.value.replace(/\\D/g, '').slice(0, options.length);\r\n this.setValueSilently(value);\r\n \r\n const length = this.value.length;\r\n if(length === options.length) { // submit code\r\n options.onFill(this.value);\r\n } else if(length === lastLength) {\r\n return;\r\n }\r\n \r\n lastLength = length;\r\n });\r\n }\r\n}\r\n"],"sourceRoot":""}