tweb/public/0.2da18beaed4bd7796d8f.chun...

1 line
85 KiB
Plaintext

{"version":3,"sources":["webpack:///./src/lib/idb.ts","webpack:///./src/lib/storage.ts","webpack:///./src/config/databases/state.ts","webpack:///./src/lib/rootScope.ts","webpack:///./src/helpers/context.ts","webpack:///./src/config/debug.ts","webpack:///./src/lib/logger.ts","webpack:///./src/helpers/object/safeAssign.ts","webpack:///./src/lib/mtproto/mtproto_config.ts","webpack:///./src/helpers/eventListenerBase.ts","webpack:///./src/helpers/cancellablePromise.ts","webpack:///./src/helpers/object/copy.ts","webpack:///./src/helpers/random.ts","webpack:///./src/lib/localStorage.ts","webpack:///./src/lib/sessionStorage.ts","webpack:///./src/config/modes.ts","webpack:///./src/helpers/noop.ts","webpack:///./src/helpers/object/isObject.ts","webpack:///./src/lib/stateStorage.ts","webpack:///./src/helpers/blob/blobConstruct.ts","webpack:///./src/helpers/blob/blobSafeMimeType.ts","webpack:///./src/helpers/schedulers/throttle.ts"],"names":["db","storeName","storageIsAvailable","safeAssign","this","test","name","log","logger","openDatabase","STORAGES","push","preserve","forEach","storage","onclose","close","createNew","openDbPromise","request","indexedDB","open","version","Promise","reject","error","message","finished","setTimeout","onerror","type","resolve","onsuccess","event","result","calledNew","e","onabort","transaction","target","onversionchange","onupgradeneeded","warn","oldVersion","newVersion","stores","store","objectStoreNames","contains","os","createObjectStore","indexes","length","index","createIndex","indexName","keyPath","objectParameters","entryName","Array","isArray","concat","getObjectStore","objectStore","map","delete","clear","value","idx","put","fileName","blob","Blob","blobConstruct","save","get","mode","perf","performance","now","then","clearTimeout","timeout","oncomplete","results","r","requests","getAll","noop","cache","getPromises","Map","keysToSet","Set","saveDeferred","keysToDelete","deleteDeferred","useStorage","savingFreezed","saveThrottled","throttle","deferred","set","size","keys","from","values","key","console","deleteThrottled","getThrottled","i","includes","undefined","finally","useCache","hasOwnProperty","getFromCache","p","catch","obj","onlyLocal","canUseStorage","setToCache","add","saveLocal","enabled","all","callback","names","err","RootScope","super","overlaysActive","idle","isIDLE","deactivated","focusPromise","focusResolve","connectionStatus","filterId","config","forwarded_count_max","edit_time_limit","pinned_dialogs_count_max","pinned_infolder_count_max","message_length_max","caption_length_max","addEventListener","peerId","document","body","classList","toggle","id","myId","status","_themeColorElem","head","querySelector","color","themeColor","isNight","themeColorElem","setAttribute","darkModeMediaQuery","window","matchMedia","checkDarkMode","systemTheme","matches","dispatchEvent","setTheme","addListener","colorScheme","documentElement","setThemeColor","isOverlayActive","getTheme","settings","theme","themes","find","t","rootScope","IS_SERVICE_WORKER","ServiceWorkerGlobalScope","self","IS_WEB_WORKER","WorkerGlobalScope","IS_WORKER","notifyServiceWorker","args","clients","matchAll","includeUncontrolled","listeners","slice","listener","postMessage","notifyWorker","notifySomeone","bind","DEBUG","debug","MOUNT_CLASS_TO","LogTypes","LOG_LEVELS","None","Error","Warn","Log","Debug","_logTimer","Date","dT","toFixed","getCallerFunctionNameFromLine","IS_WEBKIT","line","split","splitted","trim","lastIndexOf","STYLES_SUPPORTED","LINE_INDEX","getCallerFunctionName","lines","stack","LOGGER_STYLES","black","red","green","yellow","blue","magenta","cyan","white","methods","prefix","ignoreDebugReset","style","originalPrefix","originalStyle","method","logType","setPrefix","newPrefix","setLevel","level","reduce","acc","v","bindPrefix","object","fromObject","NULL_PEER_ID","REPLIES_PEER_ID","SERVICE_PEER_ID","MUTE_UNTIL","BOT_START_PARAM","EventListenerBase","reuseResults","_constructor","listenerResults","options","once","pop","findAndSplice","l","collectResults","arr","findIndex","removeEventListener","_dispatchEvent","deferredPromise","deferredHelper","isFulfilled","isRejected","notify","notifyAll","lastNotify","addNotifyListener","cancel","Object","assign","copy","getTime","el","clonedObj","constructor","prop","arrays","8","Uint8Array","16","Uint16Array","32","Uint32Array","nextRandomUint","bits","array","crypto","getRandomValues","randomLong","localStorage","getItem","JSON","parse","stringified","stringify","setItem","removeItem","taskId","tasks","task","payload","prototype","call","apply","proxy","sessionStorage","appStorage","Modes","location","search","indexOf","http","ssl","multipleConnections","asServiceWorker","transport","isObject","stateStorage","blobParts","mimeType","safeMimeType","blobSafeMimeType","bb","BlobBuilder","blobPart","append","getBlob","fn","ms","shouldRunFirst","isPending","interval","_args","setInterval","clearInterval"],"mappings":"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","file":"0.2da18beaed4bd7796d8f.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 * 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 { Database } from '../config/databases';\r\nimport Modes from '../config/modes';\r\nimport blobConstruct from '../helpers/blob/blobConstruct';\r\nimport safeAssign from '../helpers/object/safeAssign';\r\nimport { logger } from './logger';\r\n\r\n/**\r\n * https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/createIndex\r\n */\r\nexport type IDBIndex = {\r\n indexName: string,\r\n keyPath: string,\r\n objectParameters: IDBIndexParameters\r\n};\r\n\r\nexport type IDBStore = {\r\n name: string, \r\n indexes?: IDBIndex[]\r\n};\r\n\r\nexport type IDBOptions = {\r\n name?: string,\r\n storeName: string,\r\n stores?: IDBStore[],\r\n version?: number\r\n};\r\n\r\nconst DEBUG = false;\r\n\r\nexport default class IDBStorage<T extends Database<any>> {\r\n private static STORAGES: IDBStorage<Database<any>>[] = [];\r\n private openDbPromise: Promise<IDBDatabase>;\r\n private db: IDBDatabase;\r\n private storageIsAvailable = true;\r\n\r\n private log: ReturnType<typeof logger>;\r\n \r\n private name: string;\r\n private version: number;\r\n private stores: IDBStore[];\r\n private storeName: T['stores'][0]['name'];\r\n\r\n constructor(db: T, storeName: typeof db['stores'][0]['name']) {\r\n safeAssign(this, db);\r\n\r\n if(Modes.test) {\r\n this.name += '_test';\r\n }\r\n\r\n this.storeName = storeName;\r\n\r\n this.log = logger('IDB-' + this.storeName);\r\n\r\n this.openDatabase(true);\r\n\r\n IDBStorage.STORAGES.push(this);\r\n }\r\n\r\n public static closeDatabases(preserve?: IDBStorage<Database<any>>) {\r\n this.STORAGES.forEach(storage => {\r\n if(preserve && preserve === storage) {\r\n return;\r\n }\r\n\r\n const db = storage.db;\r\n if(db) {\r\n db.onclose = () => {};\r\n db.close();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * ! WARNING ! function requires at least one opened connection\r\n */\r\n /* public static clearObjectStores() {\r\n const storage = this.STORAGES[0];\r\n this.closeDatabases(storage);\r\n\r\n const names = Array.from(storage.db.objectStoreNames);\r\n const promises = names.map(name => storage.clear(name));\r\n return Promise.all(promises);\r\n } */\r\n\r\n /* public static deleteDatabase() {\r\n this.closeDatabases();\r\n\r\n const storages = this.STORAGES;\r\n const dbNames = Array.from(new Set(storages.map(storage => storage.name)));\r\n const promises = dbNames.map(dbName => {\r\n return new Promise<void>((resolve, reject) => {\r\n const deleteRequest = indexedDB.deleteDatabase(dbName);\r\n \r\n deleteRequest.onerror = () => {\r\n reject();\r\n };\r\n \r\n deleteRequest.onsuccess = () => {\r\n resolve();\r\n };\r\n });\r\n });\r\n\r\n return Promise.all(promises);\r\n } */\r\n\r\n public isAvailable() {\r\n return this.storageIsAvailable;\r\n }\r\n\r\n public openDatabase(createNew = false): Promise<IDBDatabase> {\r\n if(this.openDbPromise && !createNew) {\r\n return this.openDbPromise;\r\n }\r\n\r\n const createObjectStore = (db: IDBDatabase, store: IDBStore) => {\r\n const os = db.createObjectStore(store.name);\r\n\r\n if(store.indexes?.length) {\r\n for(const index of store.indexes) {\r\n os.createIndex(index.indexName, index.keyPath, index.objectParameters);\r\n }\r\n }\r\n };\r\n\r\n try {\r\n var request = indexedDB.open(this.name, this.version);\r\n\r\n if(!request) {\r\n return Promise.reject();\r\n }\r\n } catch(error) {\r\n this.log.error('error opening db', (error as Error).message);\r\n this.storageIsAvailable = false;\r\n return Promise.reject(error);\r\n }\r\n\r\n let finished = false;\r\n setTimeout(() => {\r\n if(!finished) {\r\n request.onerror({type: 'IDB_CREATE_TIMEOUT'} as Event);\r\n }\r\n }, 3000);\r\n\r\n return this.openDbPromise = new Promise<IDBDatabase>((resolve, reject) => {\r\n request.onsuccess = (event) => {\r\n finished = true;\r\n const db = request.result;\r\n let calledNew = false;\r\n\r\n this.log('Opened');\r\n \r\n db.onerror = (error) => {\r\n this.storageIsAvailable = false;\r\n this.log.error('Error creating/accessing IndexedDB database', error);\r\n reject(error);\r\n };\r\n\r\n db.onclose = (e) => {\r\n this.log.error('closed:', e);\r\n !calledNew && this.openDatabase();\r\n };\r\n\r\n db.onabort = (e) => {\r\n this.log.error('abort:', e);\r\n const transaction = e.target as IDBTransaction;\r\n \r\n this.openDatabase(calledNew = true);\r\n\r\n if(transaction.onerror) {\r\n transaction.onerror(e);\r\n }\r\n\r\n db.close();\r\n };\r\n\r\n db.onversionchange = (e) => {\r\n this.log.error('onversionchange, lol?');\r\n };\r\n\r\n resolve(this.db = db);\r\n };\r\n \r\n request.onerror = (event) => {\r\n finished = true;\r\n this.storageIsAvailable = false;\r\n this.log.error('Error creating/accessing IndexedDB database', event);\r\n reject(event);\r\n };\r\n \r\n request.onupgradeneeded = (event) => {\r\n finished = true;\r\n this.log.warn('performing idb upgrade from', event.oldVersion, 'to', event.newVersion);\r\n\r\n // @ts-ignore\r\n var db = event.target.result as IDBDatabase;\r\n this.stores.forEach((store) => {\r\n /* if(db.objectStoreNames.contains(store.name)) {\r\n //if(event.oldVersion === 1) {\r\n db.deleteObjectStore(store.name);\r\n //}\r\n } */\r\n \r\n if(!db.objectStoreNames.contains(store.name)) {\r\n createObjectStore(db, store);\r\n }\r\n });\r\n };\r\n });\r\n }\r\n\r\n public delete(entryName: string | string[]): Promise<void> {\r\n //return Promise.resolve();\r\n if(!Array.isArray(entryName)) {\r\n entryName = [].concat(entryName);\r\n }\r\n\r\n return this.getObjectStore('readwrite', (objectStore) => {\r\n return (entryName as string[]).map((entryName) => objectStore.delete(entryName));\r\n }, DEBUG ? 'delete: ' + entryName.join(', ') : '');\r\n }\r\n\r\n public clear(storeName?: IDBStorage<T>['storeName']) {\r\n return this.getObjectStore('readwrite', (objectStore) => objectStore.clear(), DEBUG ? 'clear' : '', storeName);\r\n }\r\n\r\n public save(entryName: string | string[], value: any | any[]) {\r\n // const handleError = (error: Error) => {\r\n // this.log.error('save: transaction error:', entryName, value, db, error, error && error.name);\r\n // if((!error || error.name === 'InvalidStateError')/* && false */) {\r\n // setTimeout(() => {\r\n // this.save(entryName, value);\r\n // }, 2e3);\r\n // } else {\r\n // //console.error('IndexedDB saveFile transaction error:', error, error && error.name);\r\n // }\r\n // };\r\n\r\n if(!Array.isArray(entryName)) {\r\n entryName = [].concat(entryName);\r\n value = [].concat(value);\r\n }\r\n \r\n return this.getObjectStore('readwrite', (objectStore) => {\r\n return (entryName as string[]).map((entryName, idx) => objectStore.put(value[idx], entryName));\r\n }, DEBUG ? 'save: ' + entryName.join(', ') : '');\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 return this.save(fileName, blob);\r\n }\r\n\r\n /* public saveFileBase64(db: IDBDatabase, fileName: string, blob: Blob | any): Promise<Blob> {\r\n if(this.getBlobSize(blob) > 10 * 1024 * 1024) {\r\n return Promise.reject();\r\n }\r\n\r\n if(!(blob instanceof Blob)) {\r\n var safeMimeType = blobSafeMimeType(blob.type || 'image/jpeg');\r\n var address = 'data:' + safeMimeType + ';base64,' + bytesToBase64(blob);\r\n return this.storagePutB64String(db, fileName, address).then(() => {\r\n return blob;\r\n });\r\n }\r\n\r\n try {\r\n var reader = new FileReader();\r\n } catch (e) {\r\n this.storageIsAvailable = false;\r\n return Promise.reject();\r\n }\r\n\r\n let promise = new Promise<Blob>((resolve, reject) => {\r\n reader.onloadend = () => {\r\n this.storagePutB64String(db, fileName, reader.result as string).then(() => {\r\n resolve(blob);\r\n }, reject);\r\n }\r\n \r\n reader.onerror = reject;\r\n });\r\n \r\n\r\n try {\r\n reader.readAsDataURL(blob);\r\n } catch (e) {\r\n this.storageIsAvailable = false;\r\n return Promise.reject();\r\n }\r\n\r\n return promise;\r\n }\r\n\r\n public storagePutB64String(db: IDBDatabase, fileName: string, b64string: string) {\r\n try {\r\n var objectStore = db.transaction([this.storeName], 'readwrite')\r\n .objectStore(this.storeName);\r\n var request = objectStore.put(b64string, fileName);\r\n } catch(error) {\r\n this.storageIsAvailable = false;\r\n return Promise.reject(error);\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n request.onsuccess = function(event) {\r\n resolve();\r\n };\r\n \r\n request.onerror = reject;\r\n });\r\n }\r\n\r\n public getBlobSize(blob: any) {\r\n return blob.size || blob.byteLength || blob.length;\r\n } */\r\n\r\n public get<T>(entryName: string[]): Promise<T[]>;\r\n public get<T>(entryName: string): Promise<T>;\r\n public get<T>(entryName: string | string[]): Promise<T> | Promise<T[]> {\r\n //return Promise.reject();\r\n\r\n if(!Array.isArray(entryName)) {\r\n entryName = [].concat(entryName);\r\n }\r\n\r\n return this.getObjectStore<T>('readonly', (objectStore) => {\r\n return (entryName as string[]).map((entryName) => objectStore.get(entryName));\r\n }, DEBUG ? 'get: ' + entryName.join(', ') : '');\r\n }\r\n\r\n private getObjectStore<T>(mode: IDBTransactionMode, objectStore: (objectStore: IDBObjectStore) => IDBRequest | IDBRequest[], log?: string, storeName = this.storeName) {\r\n let perf: number;\r\n\r\n if(log) {\r\n perf = performance.now();\r\n this.log(log + ': start');\r\n }\r\n\r\n return this.openDatabase().then((db) => {\r\n return new Promise<T>((resolve, reject) => {\r\n /* if(mode === 'readwrite') {\r\n return;\r\n } */\r\n\r\n const transaction = db.transaction([storeName], mode);\r\n\r\n transaction.onerror = (e) => {\r\n clearTimeout(timeout);\r\n reject(transaction.error);\r\n };\r\n \r\n transaction.oncomplete = (e) => {\r\n clearTimeout(timeout);\r\n\r\n if(log) {\r\n this.log(log + ': end', performance.now() - perf);\r\n }\r\n\r\n const results = r.map(r => r.result);\r\n resolve(isArray ? results : results[0]);\r\n };\r\n \r\n const timeout = setTimeout(() => {\r\n this.log.error('transaction not finished', transaction);\r\n }, 10000);\r\n \r\n /* transaction.addEventListener('abort', (e) => {\r\n //handleError();\r\n this.log.error('IndexedDB: transaction abort!', transaction.error);\r\n }); */\r\n \r\n const requests = objectStore(transaction.objectStore(storeName));\r\n\r\n const isArray = Array.isArray(requests);\r\n const r: IDBRequest[] = isArray ? requests : [].concat(requests) as any;\r\n\r\n // const length = r.length;\r\n // /* let left = length;\r\n\r\n // const onRequestFinished = (error?: Error) => {\r\n // if(!--left) {\r\n // resolve(result);\r\n // clearTimeout(timeout);\r\n // }\r\n // }; */\r\n\r\n // for(let i = 0; i < length; ++i) {\r\n // const request = r[i];\r\n // request.onsuccess = () => {\r\n // onRequestFinished();\r\n // };\r\n\r\n // request.onerror = (e) => {\r\n // onRequestFinished(transaction.error);\r\n // };\r\n // }\r\n });\r\n });\r\n }\r\n\r\n public getAll<T>(): Promise<T[]> {\r\n return this.getObjectStore<T[]>('readonly', (objectStore) => objectStore.getAll(), DEBUG ? 'getAll' : '');\r\n }\r\n\r\n /* public getAllKeys(): Promise<Array<string>> {\r\n console.time('getAllEntries');\r\n return this.openDatabase().then((db) => {\r\n var objectStore = db.transaction([this.storeName], 'readonly')\r\n .objectStore(this.storeName);\r\n var request = objectStore.getAllKeys();\r\n\r\n return new Promise((resolve, reject) => {\r\n request.onsuccess = function(event) {\r\n // @ts-ignore\r\n var result = event.target.result;\r\n resolve(result);\r\n console.timeEnd('getAllEntries');\r\n }\r\n \r\n request.onerror = reject;\r\n });\r\n });\r\n } */\r\n\r\n /* public isFileExists(fileName: string): Promise<boolean> {\r\n console.time('isFileExists');\r\n return this.openDatabase().then((db) => {\r\n var objectStore = db.transaction([this.storeName], 'readonly')\r\n .objectStore(this.storeName);\r\n var request = objectStore.openCursor(fileName);\r\n\r\n return new Promise((resolve, reject) => {\r\n request.onsuccess = function(event) {\r\n // @ts-ignore\r\n var cursor = event.target.result;\r\n resolve(!!cursor);\r\n console.timeEnd('isFileExists');\r\n }\r\n \r\n request.onerror = reject;\r\n });\r\n });\r\n } */\r\n\r\n /* public getFileWriter(fileName: string, mimeType: string) {\r\n var fakeWriter = FileManager.getFakeFileWriter(mimeType, (blob) => {\r\n return this.saveFile(fileName, blob);\r\n });\r\n\r\n return Promise.resolve(fakeWriter);\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 { Database } from \"../config/databases\";\r\n//import DATABASE_SESSION from \"../config/databases/session\";\r\nimport { CancellablePromise, deferredPromise } from \"../helpers/cancellablePromise\";\r\nimport throttle from \"../helpers/schedulers/throttle\";\r\n//import { WorkerTaskTemplate } from \"../types\";\r\nimport IDBStorage from \"./idb\";\r\n\r\nfunction noop() {}\r\n\r\n/* export interface LocalStorageProxySetTask extends WorkerTaskTemplate {\r\n type: 'localStorageProxy',\r\n payload: {\r\n type: 'set',\r\n keys: string[],\r\n values: any[]\r\n }\r\n};\r\n\r\nexport interface LocalStorageProxyDeleteTask extends WorkerTaskTemplate {\r\n type: 'localStorageProxy',\r\n payload: {\r\n type: 'delete',\r\n keys: string[]\r\n }\r\n}; */\r\n\r\nexport default class AppStorage<Storage extends Record<string, any>, T extends Database<any>/* Storage extends {[name: string]: any} *//* Storage extends Record<string, any> */> {\r\n private static STORAGES: AppStorage<any, Database<any>>[] = [];\r\n private storage: IDBStorage<T>;//new CacheStorageController('session');\r\n\r\n //private cache: Partial<{[key: string]: Storage[typeof key]}> = {};\r\n private cache: Partial<Storage> = {};\r\n private useStorage: boolean;\r\n private savingFreezed: boolean;\r\n\r\n private getPromises: Map<keyof Storage, CancellablePromise<Storage[keyof Storage]>> = new Map();\r\n private getThrottled: () => void;\r\n\r\n private keysToSet: Set<keyof Storage> = new Set();\r\n private saveThrottled: () => void;\r\n private saveDeferred = deferredPromise<void>();\r\n\r\n private keysToDelete: Set<keyof Storage> = new Set();\r\n private deleteThrottled: () => void;\r\n private deleteDeferred = deferredPromise<void>();\r\n\r\n constructor(private db: T, private storeName: typeof db['stores'][number]['name']) {\r\n this.storage = new IDBStorage<T>(db, storeName);\r\n\r\n if(AppStorage.STORAGES.length) {\r\n this.useStorage = AppStorage.STORAGES[0].useStorage;\r\n } else {\r\n this.useStorage = true;\r\n }\r\n\r\n this.savingFreezed = false;\r\n\r\n AppStorage.STORAGES.push(this);\r\n\r\n this.saveThrottled = throttle(async() => {\r\n const deferred = this.saveDeferred;\r\n this.saveDeferred = deferredPromise<void>();\r\n\r\n const set = this.keysToSet;\r\n if(set.size) {\r\n const keys = Array.from(set.values()) as string[];\r\n set.clear();\r\n\r\n try {\r\n //console.log('setItem: will set', key/* , value */);\r\n //await this.cacheStorage.delete(key); // * try to prevent memory leak in Chrome leading to 'Unexpected internal error.'\r\n //await this.storage.save(key, new Response(value, {headers: {'Content-Type': 'application/json'}}));\r\n\r\n const values = keys.map(key => this.cache[key]);\r\n /* if(db === DATABASE_SESSION && !('localStorage' in self)) { // * support legacy Webogram's localStorage\r\n self.postMessage({\r\n type: 'localStorageProxy', \r\n payload: {\r\n type: 'set',\r\n keys,\r\n values\r\n }\r\n } as LocalStorageProxySetTask);\r\n } */\r\n\r\n await this.storage.save(keys, values);\r\n //console.log('setItem: have set', key/* , value */);\r\n } catch(e) {\r\n //this.useCS = false;\r\n console.error('[AS]: set error:', e, keys/* , value */);\r\n }\r\n }\r\n\r\n deferred.resolve();\r\n\r\n if(set.size) {\r\n this.saveThrottled();\r\n }\r\n }, 16, false);\r\n\r\n this.deleteThrottled = throttle(async() => {\r\n const deferred = this.deleteDeferred;\r\n this.deleteDeferred = deferredPromise<void>();\r\n\r\n const set = this.keysToDelete;\r\n if(set.size) {\r\n const keys = Array.from(set.values()) as string[];\r\n set.clear();\r\n\r\n try {\r\n /* if(db === DATABASE_SESSION && !('localStorage' in self)) { // * support legacy Webogram's localStorage\r\n self.postMessage({\r\n type: 'localStorageProxy', \r\n payload: {\r\n type: 'delete',\r\n keys\r\n }\r\n } as LocalStorageProxyDeleteTask);\r\n } */\r\n\r\n await this.storage.delete(keys);\r\n } catch(e) {\r\n console.error('[AS]: delete error:', e, keys);\r\n }\r\n }\r\n\r\n deferred.resolve();\r\n\r\n if(set.size) {\r\n this.deleteThrottled();\r\n }\r\n }, 16, false);\r\n\r\n this.getThrottled = throttle(async() => {\r\n const keys = Array.from(this.getPromises.keys());\r\n\r\n // const perf = performance.now();\r\n this.storage.get(keys as string[]).then(values => {\r\n for(let i = 0, length = keys.length; i < length; ++i) {\r\n const key = keys[i];\r\n const deferred = this.getPromises.get(key);\r\n if(deferred) {\r\n // @ts-ignore\r\n deferred.resolve(this.cache[key] = values[i]);\r\n this.getPromises.delete(key);\r\n }\r\n }\r\n\r\n // console.log('[AS]: get time', keys, performance.now() - perf);\r\n }, (error) => {\r\n if(!['NO_ENTRY_FOUND', 'STORAGE_OFFLINE'].includes(error)) {\r\n this.useStorage = false;\r\n console.error('[AS]: get error:', error, keys, storeName);\r\n }\r\n\r\n for(let i = 0, length = keys.length; i < length; ++i) {\r\n const key = keys[i];\r\n const deferred = this.getPromises.get(key);\r\n if(deferred) {\r\n //deferred.reject(error);\r\n deferred.resolve(undefined);\r\n this.getPromises.delete(key);\r\n }\r\n }\r\n }).finally(() => {\r\n if(this.getPromises.size) {\r\n this.getThrottled();\r\n }\r\n });\r\n }, 16, false);\r\n }\r\n\r\n public isAvailable() {\r\n return this.useStorage;\r\n }\r\n\r\n public getCache() {\r\n return this.cache;\r\n }\r\n\r\n public getFromCache<T extends keyof Storage>(key: T) {\r\n return this.cache[key];\r\n }\r\n\r\n public setToCache(key: keyof Storage, value: Storage[typeof key]) {\r\n return this.cache[key] = value;\r\n }\r\n\r\n public async get<T extends keyof Storage>(key: T, useCache = true): Promise<Storage[T]> {\r\n if(this.cache.hasOwnProperty(key) && useCache) {\r\n return this.getFromCache(key);\r\n } else if(this.useStorage) {\r\n const r = this.getPromises.get(key);\r\n if(r) return r as any;\r\n\r\n const p = deferredPromise<Storage[T]>();\r\n this.getPromises.set(key, p as any);\r\n\r\n this.getThrottled();\r\n\r\n return p;\r\n }/* else {\r\n throw 'something went wrong';\r\n } */\r\n }\r\n\r\n public getAll() {\r\n return this.storage.getAll().catch(() => []);\r\n }\r\n\r\n public set(obj: Partial<Storage>, onlyLocal = false) {\r\n //console.log('storageSetValue', obj, callback, arguments);\r\n\r\n const canUseStorage = this.useStorage && !onlyLocal && !this.savingFreezed;\r\n for(const key in obj) {\r\n if(obj.hasOwnProperty(key)) {\r\n const value = obj[key];\r\n this.setToCache(key, value);\r\n\r\n // let perf = /* DEBUG */false ? performance.now() : 0;\r\n // value = JSON.stringify(value);\r\n\r\n // if(perf) {\r\n // let elapsedTime = performance.now() - perf;\r\n // if(elapsedTime > 10) {\r\n // console.warn('LocalStorage set: stringify time by JSON.stringify:', elapsedTime, key);\r\n // }\r\n // }\r\n \r\n /* perf = performance.now();\r\n value = stringify(value);\r\n console.log('LocalStorage set: stringify time by own stringify:', performance.now() - perf); */\r\n\r\n if(canUseStorage) {\r\n this.keysToSet.add(key);\r\n this.keysToDelete.delete(key);\r\n this.saveThrottled();\r\n }\r\n }\r\n }\r\n\r\n return canUseStorage ? this.saveDeferred : Promise.resolve();\r\n }\r\n\r\n public delete(key: keyof Storage, saveLocal = false) {\r\n /* if(!this.cache.hasOwnProperty(key)) {\r\n return;\r\n } */\r\n\r\n // ! it is needed here\r\n key = '' + key;\r\n\r\n if(!saveLocal) {\r\n delete this.cache[key];\r\n }\r\n \r\n if(this.useStorage) {\r\n this.keysToSet.delete(key);\r\n this.keysToDelete.add(key);\r\n this.deleteThrottled();\r\n }\r\n\r\n return this.useStorage ? this.deleteDeferred : Promise.resolve();\r\n }\r\n\r\n public clear(saveLocal = false) {\r\n if(!saveLocal) {\r\n for(const i in this.cache) {\r\n delete this.cache[i];\r\n }\r\n }\r\n\r\n return this.storage.clear().catch(noop);\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 storage.keysToSet.clear();\r\n storage.keysToDelete.clear();\r\n storage.getPromises.forEach((deferred) => deferred.resolve(undefined));\r\n storage.getPromises.clear();\r\n return storage.clear(true);\r\n } else {\r\n return storage.set(storage.cache);\r\n }\r\n })).catch(noop);\r\n }\r\n\r\n public static freezeSaving<T extends Database<any>>(callback: () => any, names: T['stores'][number]['name'][]) {\r\n this.STORAGES.forEach(storage => storage.savingFreezed = true);\r\n try {\r\n callback();\r\n } catch(err) {}\r\n this.STORAGES.forEach(storage => storage.savingFreezed = false);\r\n }\r\n\r\n /* public deleteDatabase() {\r\n return IDBStorage.deleteDatabase().catch(noop);\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 { Database } from '.';\r\n\r\nconst DATABASE_STATE: Database<'session' | 'stickerSets' | 'users' | 'chats' | 'messages' | 'dialogs'> = {\r\n name: 'tweb',\r\n version: 7,\r\n stores: [{\r\n name: 'session'\r\n }, {\r\n name: 'stickerSets'\r\n }, {\r\n name: 'users'\r\n }, {\r\n name: 'chats'\r\n }, {\r\n name: 'dialogs'\r\n }, {\r\n name: 'messages'\r\n }]\r\n};\r\n\r\nexport default DATABASE_STATE;\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 type { Message, StickerSet, Update, NotifyPeer, PeerNotifySettings, ConstructorDeclMap, Config, PollResults, Poll, WebPage, GroupCall, GroupCallParticipant, PhoneCall, MethodDeclMap, MessageReactions, ReactionCount } from \"../layer\";\nimport type { MyDocument } from \"./appManagers/appDocsManager\";\nimport type { AppMessagesManager, Dialog, MessagesStorage, MyMessage } from \"./appManagers/appMessagesManager\";\nimport type { MyDialogFilter } from \"./storages/filters\";\nimport type { Folder } from \"./storages/dialogs\";\nimport type { UserTyping } from \"./appManagers/appProfileManager\";\nimport type { State, Theme } from \"./appManagers/appStateManager\";\nimport type { MyDraftMessage } from \"./appManagers/appDraftsManager\";\nimport type { PushSubscriptionNotify } from \"./mtproto/webPushApiManager\";\nimport type { PushNotificationObject } from \"./serviceWorker/push\";\nimport type { ConnectionStatusChange } from \"./mtproto/connectionStatus\";\nimport type { GroupCallId } from \"./appManagers/appGroupCallsManager\";\nimport type GroupCallInstance from \"./calls/groupCallInstance\";\nimport type CallInstance from \"./calls/callInstance\";\nimport type { StreamAmplitude } from \"./calls/streamManager\";\nimport type Chat from \"../components/chat/chat\";\nimport { NULL_PEER_ID, UserAuth } from \"./mtproto/mtproto_config\";\nimport EventListenerBase from \"../helpers/eventListenerBase\";\nimport { MOUNT_CLASS_TO } from \"../config/debug\";\nimport { MTAppConfig } from \"./mtproto/appConfig\";\n\nexport type BroadcastEvents = {\n 'chat_full_update': ChatId,\n 'chat_update': ChatId,\n\n 'channel_update': ChatId,\n \n 'user_update': UserId,\n 'user_auth': UserAuth,\n 'user_full_update': UserId,\n\n 'chat_changing': {from: Chat, to: Chat},\n\n 'peer_changed': PeerId,\n 'peer_changing': Chat,\n 'peer_pinned_messages': {peerId: PeerId, mids?: number[], pinned?: boolean, unpinAll?: true},\n 'peer_pinned_hidden': {peerId: PeerId, maxId: number},\n 'peer_typings': {peerId: PeerId, typings: UserTyping[]},\n 'peer_block': {peerId: PeerId, blocked: boolean},\n 'peer_title_edit': PeerId,\n 'peer_bio_edit': PeerId,\n 'peer_deleted': PeerId, // left chat, deleted user dialog, left channel\n 'peer_full_update': PeerId,\n\n 'filter_delete': MyDialogFilter,\n 'filter_update': MyDialogFilter,\n 'filter_new': MyDialogFilter,\n 'filter_order': number[],\n\n 'folder_unread': Folder,\n \n 'dialog_draft': {peerId: PeerId, dialog: Dialog, drop: boolean, draft: MyDraftMessage | undefined, index: number},\n 'dialog_unread': {peerId: PeerId},\n 'dialog_flush': {peerId: PeerId},\n 'dialog_drop': {peerId: PeerId, dialog?: Dialog},\n 'dialog_migrate': {migrateFrom: PeerId, migrateTo: PeerId},\n //'dialog_top': Dialog,\n 'dialog_notify_settings': Dialog,\n // 'dialog_order': {dialog: Dialog, pos: number},\n 'dialogs_multiupdate': {[peerId: PeerId]: Dialog},\n \n 'history_append': {storage: MessagesStorage, peerId: PeerId, mid: number},\n 'history_update': {storage: MessagesStorage, peerId: PeerId, mid: number},\n 'history_reply_markup': {peerId: PeerId},\n 'history_multiappend': AppMessagesManager['newMessagesToHandle'],\n 'history_delete': {peerId: PeerId, msgs: Set<number>},\n 'history_forbidden': PeerId,\n 'history_reload': PeerId,\n 'history_focus': {peerId: PeerId, threadId?: number, mid?: number, startParam?: string},\n //'history_request': void,\n \n 'message_edit': {storage: MessagesStorage, peerId: PeerId, mid: number},\n 'message_views': {peerId: PeerId, mid: number, views: number},\n 'message_sent': {storage: MessagesStorage, tempId: number, tempMessage: any, mid: number, message: MyMessage},\n 'message_reactions': {message: Message.message, changedResults: ReactionCount[]},\n 'messages_pending': void,\n 'messages_read': void,\n 'messages_downloaded': {peerId: PeerId, mids: number[]},\n 'messages_media_read': {peerId: PeerId, mids: number[]},\n\n 'replies_updated': Message.message,\n\n 'scheduled_new': {peerId: PeerId, mid: number},\n 'scheduled_delete': {peerId: PeerId, mids: number[]},\n\n 'album_edit': {peerId: PeerId, groupId: string, deletedMids: number[]},\n\n 'stickers_installed': StickerSet.stickerSet,\n 'stickers_deleted': StickerSet.stickerSet,\n\n 'media_play': {doc: MyDocument, message: Message.message, media: HTMLMediaElement},\n 'media_pause': void,\n 'media_playback_params': {volume: number, muted: boolean, playbackRate: number},\n 'media_stop': void,\n \n 'state_cleared': void,\n 'state_synchronized': ChatId | void,\n 'state_synchronizing': ChatId | void,\n \n 'contacts_update': UserId,\n 'avatar_update': PeerId,\n 'poll_update': {poll: Poll, results: PollResults},\n 'invalidate_participants': ChatId,\n //'channel_settings': {channelId: number},\n 'webpage_updated': {id: WebPage.webPage['id'], msgs: {peerId: PeerId, mid: number, isScheduled: boolean}[]},\n\n 'connection_status_change': ConnectionStatusChange,\n 'settings_updated': {key: string, value: any},\n 'draft_updated': {peerId: PeerId, threadId: number, draft: MyDraftMessage | undefined, force?: boolean},\n \n 'event-heavy-animation-start': void,\n 'event-heavy-animation-end': void,\n \n 'im_mount': void,\n 'im_tab_change': number,\n \n 'idle': boolean,\n \n 'overlay_toggle': boolean,\n \n 'background_change': void,\n \n 'privacy_update': Update.updatePrivacy,\n \n 'notify_settings': Update.updateNotifySettings,\n 'notify_peer_type_settings': {key: Exclude<NotifyPeer['_'], 'notifyPeer'>, settings: PeerNotifySettings},\n \n 'language_change': string,\n \n 'theme_change': void,\n \n 'instance_activated': void,\n 'instance_deactivated': void,\n \n 'push_notification_click': PushNotificationObject,\n 'push_init': PushSubscriptionNotify,\n 'push_subscribe': PushSubscriptionNotify,\n 'push_unsubscribe': PushSubscriptionNotify,\n \n 'emoji_recent': string,\n \n 'download_start': DocId,\n 'download_progress': any,\n 'document_downloaded': MyDocument,\n\n 'context_menu_toggle': boolean,\n 'choosing_sticker': boolean\n\n 'group_call_instance': GroupCallInstance,\n 'group_call_update': GroupCall,\n 'group_call_amplitude': {amplitudes: StreamAmplitude[], type: 'all' | 'input'},\n 'group_call_participant': {groupCallId: GroupCallId, participant: GroupCallParticipant},\n // 'group_call_video_track_added': {instance: GroupCallInstance}\n\n 'call_instance': {hasCurrent: boolean, instance: CallInstance},\n 'call_accepting': CallInstance, // это костыль. используется при параллельном вызове, чтобы заменить звонок в topbarCall\n\n 'quick_reaction': string,\n\n 'missed_reactions_element': {message: Message.message, changedResults: ReactionCount[]}\n};\n\nexport class RootScope extends EventListenerBase<{\n [name in Update['_']]: (update: ConstructorDeclMap[name]) => void\n} & {\n [name in keyof BroadcastEvents]: (e: BroadcastEvents[name]) => void\n}> {\n public overlaysActive = 0;\n public myId: PeerId;\n public idle = {\n isIDLE: true,\n deactivated: false,\n focusPromise: Promise.resolve(),\n focusResolve: () => {}\n };\n public connectionStatus: {[name: string]: ConnectionStatusChange} = {};\n public settings: State['settings'];\n public peerId: PeerId;\n public filterId = 0;\n public systemTheme: Theme['name'];\n public config: Partial<Config.config> = {\n forwarded_count_max: 100,\n edit_time_limit: 86400 * 2,\n pinned_dialogs_count_max: 5,\n pinned_infolder_count_max: 100,\n message_length_max: 4096,\n caption_length_max: 1024,\n };\n public appConfig: MTAppConfig;\n\n public themeColor: string;\n private _themeColorElem: Element;\n\n constructor() {\n super();\n\n this.addEventListener('peer_changed', (peerId) => {\n this.peerId = peerId;\n document.body.classList.toggle('has-chat', !!peerId);\n });\n\n this.addEventListener('user_auth', ({id}) => {\n // @ts-ignore\n this.myId = typeof(NULL_PEER_ID) === 'number' ? +id : '' + id;\n });\n\n this.addEventListener('connection_status_change', (status) => {\n this.connectionStatus[status.name] = status;\n });\n\n this.addEventListener('idle', (isIDLE) => {\n if(isIDLE) {\n this.idle.focusPromise = new Promise((resolve) => {\n this.idle.focusResolve = resolve;\n });\n } else {\n this.idle.focusResolve();\n }\n });\n }\n\n get themeColorElem() {\n if(this._themeColorElem !== undefined) {\n return this._themeColorElem;\n }\n\n return this._themeColorElem = document.head.querySelector('[name=\"theme-color\"]') as Element || null;\n }\n\n public setThemeColor(color = this.themeColor) {\n if(!color) {\n color = this.isNight() ? '#212121' : '#ffffff';\n }\n\n const themeColorElem = this.themeColorElem;\n if(themeColorElem) {\n themeColorElem.setAttribute('content', color);\n }\n }\n\n public setThemeListener() {\n try {\n const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const checkDarkMode = () => {\n //const theme = this.getTheme();\n this.systemTheme = darkModeMediaQuery.matches ? 'night' : 'day';\n //const newTheme = this.getTheme();\n\n if(this.myId) {\n this.dispatchEvent('theme_change');\n } else {\n this.setTheme();\n }\n };\n\n if('addEventListener' in darkModeMediaQuery) {\n darkModeMediaQuery.addEventListener('change', checkDarkMode);\n } else if('addListener' in darkModeMediaQuery) {\n (darkModeMediaQuery as any).addListener(checkDarkMode);\n }\n\n checkDarkMode();\n } catch(err) {\n\n }\n }\n\n public setTheme() {\n const isNight = this.isNight();\n const colorScheme = document.head.querySelector('[name=\"color-scheme\"]');\n if(colorScheme) {\n colorScheme.setAttribute('content', isNight ? 'dark' : 'light');\n }\n\n document.documentElement.classList.toggle('night', isNight);\n this.setThemeColor();\n }\n\n get isOverlayActive() {\n return this.overlaysActive > 0;\n }\n\n set isOverlayActive(value: boolean) {\n this.overlaysActive += value ? 1 : -1;\n this.dispatchEvent('overlay_toggle', this.isOverlayActive);\n }\n\n public isNight() {\n return this.getTheme().name === 'night';\n }\n\n public getTheme(name: Theme['name'] = this.settings.theme === 'system' ? this.systemTheme : this.settings.theme) {\n return this.settings.themes.find(t => t.name === name);\n }\n}\n\nconst rootScope = new RootScope();\nMOUNT_CLASS_TO.rootScope = rootScope;\nexport default rootScope;\n\n/* rootScope.addEventListener('album_edit', (e) => {\n \n});\n\nrootScope.addEventListener<'album_edit'>('album_edit', (e) => {\n \n}); */\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n// в SW может быть сразу две переменных TRUE\r\nexport const IS_SERVICE_WORKER = typeof ServiceWorkerGlobalScope !== 'undefined' && self instanceof ServiceWorkerGlobalScope;\r\nexport const IS_WEB_WORKER = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope && !IS_SERVICE_WORKER;\r\nexport const IS_WORKER = IS_WEB_WORKER || IS_SERVICE_WORKER;\r\n\r\nexport const getWindowClients = () => {\r\n return (self as any as ServiceWorkerGlobalScope)\r\n .clients\r\n .matchAll({ includeUncontrolled: false, type: 'window' });\r\n};\r\n\r\nconst notifyServiceWorker = (all: boolean, ...args: any[]) => {\r\n (self as any as ServiceWorkerGlobalScope)\r\n .clients\r\n .matchAll({ includeUncontrolled: false, type: 'window' })\r\n .then((listeners) => {\r\n if(!listeners.length) {\r\n //console.trace('no listeners?', self, listeners);\r\n return;\r\n }\r\n\r\n listeners.slice(all ? 0 : -1).forEach(listener => {\r\n // @ts-ignore\r\n listener.postMessage(...args);\r\n });\r\n });\r\n};\r\n\r\nconst notifyWorker = (...args: any[]) => {\r\n // @ts-ignore\r\n (self as any as DedicatedWorkerGlobalScope).postMessage(...args);\r\n};\r\n\r\nconst noop = () => {};\r\n\r\nexport const notifySomeone = IS_SERVICE_WORKER ? notifyServiceWorker.bind(null, false) : (IS_WEB_WORKER ? notifyWorker : noop);\r\nexport const notifyAll = IS_SERVICE_WORKER ? notifyServiceWorker.bind(null, true) : (IS_WEB_WORKER ? notifyWorker : noop);\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 \"./modes\";\r\n\r\nexport const DEBUG = process.env.NODE_ENV !== 'production' || Modes.debug;\r\nconst ctx: any = typeof(window) !== 'undefined' ? window : self;\r\nexport const MOUNT_CLASS_TO: any = DEBUG || true/* && false */ ? ctx : {};\r\nexport default DEBUG;\r\n\r\n//let m = DEBUG;\r\n/* if(!DEBUG) {\r\n ctx.sandpitTurtle = () => {\r\n //if(!m) {\r\n for(let i in MOUNT_CLASS_TO) {\r\n ctx[i] = MOUNT_CLASS_TO[i];\r\n }\r\n //m = true;\r\n //}\r\n \r\n //DEBUG = !DEBUG;\r\n };\r\n} */\r\n\r\n/* export const superDebug = (object: any, key: string) => {\r\n var d = object[key];\r\n var beforeStr = '', afterStr = '';\r\n for(var r of d) {\r\n beforeStr += r.before.hex + '\\n';\r\n afterStr += r.after.hex + '\\n';\r\n }\r\n\r\n beforeStr = beforeStr.trim();\r\n afterStr = afterStr.trim();\r\n //var beforeStr = d.map(r => r.before.hex).join('\\n');\r\n //var afterStr = d.map(r => r.after.hex).join('\\n');\r\n\r\n var dada = (name: string, str: string) => {\r\n var a = document.createElement('a');\r\n a.target = '_blank';\r\n a.download = name + '.txt';\r\n a.href = URL.createObjectURL(new Blob([str], {\r\n type: 'text/plain'\r\n }));\r\n document.body.append(a);\r\n a.click();\r\n };\r\n\r\n dada(key + '_' + 'before', beforeStr);\r\n dada(key + '_' + 'after', afterStr);\r\n}\r\n\r\nMOUNT_CLASS_TO.superDebug = superDebug; */\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 DEBUG from \"../config/debug\";\nimport { IS_FIREFOX, IS_SAFARI } from \"../environment/userAgent\";\nimport { IS_SERVICE_WORKER, IS_WEB_WORKER } from \"../helpers/context\";\n\nexport enum LogTypes {\n None = 0,\n Error = 1,\n Warn = 2,\n Log = 4,\n Debug = 8\n};\n\nexport const LOG_LEVELS = [LogTypes.None, LogTypes.Error, LogTypes.Warn, LogTypes.Log, LogTypes.Debug];\n\nconst _logTimer = Date.now();\nfunction dT() {\n return '[' + ((Date.now() - _logTimer) / 1000).toFixed(3) + ']';\n}\n\nlet getCallerFunctionNameFromLine: (line: string) => string;\n\nconst IS_WEBKIT = IS_SAFARI || IS_FIREFOX;\n\nif(IS_WEBKIT) {\n getCallerFunctionNameFromLine = (line) => {\n const splitted = line.split('@');\n return splitted[0];\n };\n} else {\n getCallerFunctionNameFromLine = (line: string) => {\n const splitted = line.trim().split(' ');\n if(splitted.length === 3) {\n return splitted[1].slice(splitted[1].lastIndexOf('.') + 1);\n }\n };\n}\n\nconst STYLES_SUPPORTED = !IS_WEBKIT;\nconst LINE_INDEX = IS_WEBKIT ? 2 : 3;\n\nfunction getCallerFunctionName() {\n const stack = new Error().stack;\n const lines = stack.split('\\n');\n const line = lines[LINE_INDEX] || lines[lines.length - 1];\n // const match = line.match(/\\.([^\\.]+?)\\s/);\n // line = match ? match[1] : line.trim();\n const caller = getCallerFunctionNameFromLine(line) || '<anonymous>';\n return '[' + caller + ']';\n}\n\nexport const LOGGER_STYLES = {\n reset: \"\\x1b[0m\",\n bright: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n underscore: \"\\x1b[4m\",\n blink: \"\\x1b[5m\",\n reverse: \"\\x1b[7m\",\n hidden: \"\\x1b[8m\",\n // Foreground (text) colors\n fg: {\n black: \"\\x1b[30m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\"\n },\n // Background colors\n bg: {\n black: \"\\x1b[40m\",\n red: \"\\x1b[41m\",\n green: \"\\x1b[42m\",\n yellow: \"\\x1b[43m\",\n blue: \"\\x1b[44m\",\n magenta: \"\\x1b[45m\",\n cyan: \"\\x1b[46m\",\n white: \"\\x1b[47m\"\n }\n};\n\nexport type Logger = {\n (...args: any[]): void;\n warn(...args: any[]): void;\n info(...args: any[]): void;\n error(...args: any[]): void;\n trace(...args: any[]): void;\n debug(...args: any[]): void;\n assert(...args: any[]): void;\n // log(...args: any[]): void;\n setPrefix(newPrefix: string): void;\n setLevel(level: 0 | 1 | 2 | 3 | 4): void;\n bindPrefix(prefix: string): Logger;\n};\n\nconst methods: ['debug' | 'info' | 'warn' | 'error' | 'assert' | 'trace'/* | 'log' */, LogTypes][] = [\n [\"debug\", LogTypes.Debug], \n [\"info\", LogTypes.Log], \n [\"warn\", LogTypes.Warn], \n [\"error\", LogTypes.Error], \n [\"assert\", LogTypes.Error],\n [\"trace\", LogTypes.Log],\n // [\"log\", LogTypes.Log]\n];\n\nexport function logger(prefix: string, type: LogTypes = LogTypes.Log | LogTypes.Warn | LogTypes.Error, ignoreDebugReset = false, style = ''): Logger {\n let originalPrefix: string;\n if(!DEBUG && !ignoreDebugReset/* || true */) {\n type = LogTypes.Error;\n }\n\n if(!STYLES_SUPPORTED) {\n style = '';\n } else if(!style) {\n if(IS_SERVICE_WORKER) style = LOGGER_STYLES.fg.yellow;\n else if(IS_WEB_WORKER) style = LOGGER_STYLES.fg.cyan;\n }\n\n let originalStyle = style;\n if(style) style = `%s ${style}%s`;\n else style = '%s';\n\n //level = LogLevels.log | LogLevels.warn | LogLevels.error | LogLevels.debug\n\n const log: Logger = function(...args: any[]) {\n return type & LogTypes.Log && console.log(style, dT(), prefix, getCallerFunctionName(), ...args);\n } as any;\n\n methods.forEach(([method, logType]) => {\n log[method] = function(...args: any[]) {\n return type & logType && console[method](style, dT(), prefix, getCallerFunctionName(), ...args);\n };\n });\n\n log.setPrefix = function(newPrefix: string) {\n originalPrefix = newPrefix;\n prefix = '[' + newPrefix + ']';\n };\n\n log.setPrefix(prefix);\n\n log.setLevel = function(level: 0 | 1 | 2 | 3 | 4) {\n type = LOG_LEVELS.slice(0, level + 1).reduce((acc, v) => acc | v, 0) as any;\n };\n\n log.bindPrefix = function(prefix: string) {\n return logger(`${originalPrefix}] [${prefix}`, type, ignoreDebugReset, originalStyle);\n };\n\n return log;\n};\n","export default function safeAssign<T>(object: T, fromObject: any) {\n if(fromObject) {\n for(let i in fromObject) {\n if(fromObject[i] !== undefined) {\n // @ts-ignore\n object[i] = fromObject[i];\n }\n }\n }\n\n return object;\n}\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n\r\n/**\r\n * Legacy Webogram's format, don't change dcID to camelCase. date is timestamp\r\n */\r\nexport type UserAuth = {dcID: number | string, date: number, id: PeerId};\r\n\r\nexport const NULL_PEER_ID: PeerId = 0;\r\nexport const REPLIES_PEER_ID: PeerId = 1271266957;\r\nexport const SERVICE_PEER_ID: PeerId = 777000;\r\nexport const MUTE_UNTIL = 0x7FFFFFFF;\r\nexport const BOT_START_PARAM = '';\r\n","/*\r\n * https://github.com/morethanwords/tweb\r\n * Copyright (C) 2019-2021 Eduard Kuzmenko\r\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\r\n */\r\n\r\n//import { MOUNT_CLASS_TO } from \"../config/debug\";\r\nimport type { ArgumentTypes, SuperReturnType } from \"../types\";\r\n\r\n// class EventSystem {\r\n// wm: WeakMap<any, Record<any, Set<any>>> = new WeakMap();\r\n\r\n// add(target: any, event: any, listener: any) {\r\n// let listeners = this.wm.get(target);\r\n// if (listeners === undefined) {\r\n// listeners = {};\r\n// }\r\n// let listenersForEvent = listeners[event];\r\n// if (listenersForEvent === undefined) {\r\n// listenersForEvent = new Set();\r\n// }\r\n// listenersForEvent.add(listener);\r\n// listeners[event] = listenersForEvent;\r\n// //target.addEventListener(event, listener);\r\n// this.wm.set(target, listeners);\r\n// };\r\n\r\n// remove(target: any, event: any, listener: any) {\r\n// let listeners = this.wm.get(target);\r\n// if (!listeners) return;\r\n// let listenersForEvent = listeners[event];\r\n// if (!listenersForEvent) return;\r\n// listenersForEvent.delete(listener);\r\n// };\r\n \r\n// /* fire(target, event) {\r\n// let listeners = this.wm.get(target);\r\n// if (!listeners) return;\r\n// let listenersForEvent = listeners[event];\r\n// if (!listenersForEvent) return;\r\n// for (let handler of handlers) {\r\n// setTimeout(handler, 0, event, target); // we use a setTimeout here because we want event triggering to be asynchronous. \r\n// }\r\n// }; */\r\n// }\r\n\r\n// console.log = () => {};\r\n\r\n// const e = new EventSystem();\r\n// MOUNT_CLASS_TO.e = e;\r\n\r\nexport type EventListenerListeners = Record<string, Function>;\r\n// export type EventListenerListeners = Record<string, (...args: any[]) => any>;\r\n// export type EventListenerListeners = {[name in string]: Function};\r\n\r\n/**\r\n * Better not to remove listeners during setting\r\n * Should add listener callback only once\r\n */\r\n\r\n// type EventLitenerCallback<T> = (data: T) => \r\n// export default class EventListenerBase<Listeners extends {[name: string]: Function}> {\r\nexport default class EventListenerBase<Listeners extends EventListenerListeners> {\r\n protected listeners: Partial<{\r\n [k in keyof Listeners]: Array<{callback: Listeners[k], options: boolean | AddEventListenerOptions}>\r\n }>;\r\n protected listenerResults: Partial<{\r\n [k in keyof Listeners]: ArgumentTypes<Listeners[k]>\r\n }>;\r\n\r\n private reuseResults: boolean;\r\n\r\n constructor(reuseResults?: boolean) {\r\n this._constructor(reuseResults);\r\n }\r\n\r\n public _constructor(reuseResults = false): any {\r\n this.reuseResults = reuseResults;\r\n this.listeners = {};\r\n this.listenerResults = {};\r\n }\r\n\r\n public addEventListener<T extends keyof Listeners>(name: T, callback: Listeners[T], options?: boolean | AddEventListenerOptions) {\r\n (this.listeners[name] ?? (this.listeners[name] = [])).push({callback, options}); // ! add before because if you don't, you won't be able to delete it from callback\r\n\r\n if(this.listenerResults.hasOwnProperty(name)) {\r\n callback(...this.listenerResults[name]);\r\n \r\n if((options as AddEventListenerOptions)?.once) {\r\n this.listeners[name].pop();\r\n return;\r\n }\r\n }\r\n \r\n //e.add(this, name, {callback, once});\r\n }\r\n\r\n public addMultipleEventsListeners(obj: {\r\n [name in keyof Listeners]?: Listeners[name]\r\n }) {\r\n for(const i in obj) {\r\n this.addEventListener(i, obj[i]);\r\n }\r\n }\r\n\r\n public removeEventListener<T extends keyof Listeners>(name: T, callback: Listeners[T], options?: boolean | AddEventListenerOptions) {\r\n if(this.listeners[name]) {\r\n this.listeners[name].findAndSplice(l => l.callback === callback);\r\n }\r\n //e.remove(this, name, callback);\r\n }\r\n\r\n // * must be protected, but who cares\r\n private _dispatchEvent<T extends keyof Listeners>(name: T, collectResults: boolean, ...args: ArgumentTypes<Listeners[T]>) {\r\n if(this.reuseResults) {\r\n this.listenerResults[name] = args;\r\n }\r\n\r\n const arr: Array<SuperReturnType<Listeners[typeof name]>> = collectResults && [];\r\n\r\n const listeners = this.listeners[name];\r\n if(listeners) {\r\n // ! this one will guarantee execution even if delete another listener during setting\r\n const left = listeners.slice();\r\n left.forEach((listener) => {\r\n const index = listeners.findIndex((l) => l.callback === listener.callback);\r\n if(index === -1) {\r\n return;\r\n }\r\n\r\n let result: any;\r\n try {\r\n result = listener.callback(...args);\r\n } catch(err) {\r\n console.error(err);\r\n }\r\n\r\n if(arr) {\r\n arr.push(result);\r\n }\r\n\r\n if((listener.options as AddEventListenerOptions)?.once) {\r\n this.removeEventListener(name, listener.callback);\r\n }\r\n });\r\n }\r\n\r\n return arr;\r\n }\r\n\r\n public dispatchResultableEvent<T extends keyof Listeners>(name: T, ...args: ArgumentTypes<Listeners[T]>) {\r\n return this._dispatchEvent(name, true, ...args);\r\n }\r\n\r\n // * must be protected, but who cares\r\n public dispatchEvent<L extends EventListenerListeners = Listeners, T extends keyof L = keyof L>(name: T, ...args: ArgumentTypes<L[T]>) {\r\n // @ts-ignore\r\n this._dispatchEvent(name, false, ...args);\r\n }\r\n\r\n public cleanup() {\r\n this.listeners = {}; \r\n this.listenerResults = {};\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 noop from \"./noop\";\r\n\r\nexport interface CancellablePromise<T> extends Promise<T> {\r\n resolve?: (value: T) => void,\r\n reject?: (...args: any[]) => void,\r\n cancel?: () => void,\r\n\r\n notify?: (...args: any[]) => void,\r\n notifyAll?: (...args: any[]) => void,\r\n lastNotify?: any,\r\n listeners?: Array<(...args: any[]) => void>,\r\n addNotifyListener?: (callback: (...args: any[]) => void) => void,\r\n\r\n isFulfilled?: boolean,\r\n isRejected?: boolean\r\n}\r\n\r\nexport function deferredPromise<T>() {\r\n let deferredHelper: any = {\r\n isFulfilled: false, \r\n isRejected: false,\r\n\r\n notify: () => {}, \r\n notifyAll: (...args: any[]) => {\r\n deferredHelper.lastNotify = args;\r\n deferredHelper.listeners.forEach((callback: any) => callback(...args));\r\n }, \r\n\r\n listeners: [],\r\n addNotifyListener: (callback: (...args: any[]) => void) => {\r\n if(deferredHelper.lastNotify) {\r\n callback(...deferredHelper.lastNotify);\r\n }\r\n\r\n deferredHelper.listeners.push(callback);\r\n }\r\n };\r\n\r\n let deferred: CancellablePromise<T> = new Promise<T>((resolve, reject) => {\r\n deferredHelper.resolve = (value: T) => {\r\n if(deferred.isFulfilled || deferred.isRejected) return;\r\n\r\n deferred.isFulfilled = true;\r\n resolve(value);\r\n };\r\n \r\n deferredHelper.reject = (...args: any[]) => {\r\n if(deferred.isRejected || deferred.isFulfilled) return;\r\n \r\n deferred.isRejected = true;\r\n reject(...args);\r\n };\r\n });\r\n\r\n // @ts-ignore\r\n /* deferred.then = (resolve: (value: T) => any, reject: (...args: any[]) => any) => {\r\n const n = deferredPromise<ReturnType<typeof resolve>>();\r\n \r\n }; */\r\n\r\n deferred.catch(noop).finally(() => {\r\n deferred.notify = deferred.notifyAll = deferred.lastNotify = null;\r\n deferred.listeners.length = 0;\r\n\r\n if(deferred.cancel) {\r\n deferred.cancel = () => {};\r\n }\r\n });\r\n\r\n Object.assign(deferred, deferredHelper);\r\n\r\n return deferred;\r\n}","export default function copy<T>(obj: T): T {\n //in case of premitives\n if(obj === null || typeof(obj) !== \"object\") {\n return obj;\n }\n \n //date objects should be \n if(obj instanceof Date) {\n return new Date(obj.getTime()) as any;\n }\n \n //handle Array\n if(Array.isArray(obj)) {\n // @ts-ignore\n const clonedArr: T = obj.map(el => copy(el)) as any as T;\n return clonedArr;\n }\n \n //lastly, handle objects\n // @ts-ignore\n let clonedObj = new obj.constructor();\n for(var prop in obj){\n if(obj.hasOwnProperty(prop)) {\n clonedObj[prop] = copy(obj[prop]);\n }\n }\n return clonedObj;\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\nconst arrays = {\n 8: new Uint8Array(1),\n 16: new Uint16Array(1),\n 32: new Uint32Array(1),\n};\nexport function nextRandomUint(bits: 8 | 16 | 32) {\n const array = arrays[bits];\n crypto.getRandomValues(array);\n return array[0];\n}\n\nexport function randomLong() {\n return '' + nextRandomUint(32) + nextRandomUint(32) % 0xFFFFFF;\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 * 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 Modes from '../config/modes';\r\nimport { notifySomeone, IS_WORKER } from '../helpers/context';\r\nimport { WorkerTaskTemplate } from '../types';\r\n//import { stringify } from '../helpers/json';\r\n\r\nclass LocalStorage<Storage extends Record<string, any>> {\r\n private prefix = '';\r\n private cache: Partial<Storage> = {};\r\n private useStorage = true;\r\n\r\n constructor(/* private preserveKeys: (keyof Storage)[] */) {\r\n if(Modes.test) {\r\n this.prefix = 't_';\r\n }\r\n }\r\n\r\n public get<T extends keyof Storage>(key: T, useCache = true): Storage[T] {\r\n if(this.cache.hasOwnProperty(key) && useCache) {\r\n return this.cache[key];\r\n } else if(this.useStorage) {\r\n let value: Storage[T];\r\n try {\r\n value = localStorage.getItem(this.prefix + key as string) as any;\r\n } catch(err) {\r\n this.useStorage = false;\r\n }\r\n\r\n if(value !== null) {\r\n try {\r\n value = JSON.parse(value);\r\n } catch(err) {\r\n //console.error(err);\r\n }\r\n } else {\r\n value = undefined;\r\n }\r\n\r\n return value;\r\n }/* else {\r\n throw 'something went wrong';\r\n } */\r\n }\r\n\r\n public set(obj: Partial<Storage>, onlyLocal = false) {\r\n for(const key in obj) {\r\n if(obj.hasOwnProperty(key)) {\r\n const value = obj[key];\r\n this.cache[key] = value;\r\n\r\n if(this.useStorage && !onlyLocal) {\r\n try {\r\n const stringified = JSON.stringify(value);\r\n localStorage.setItem(this.prefix + key, stringified);\r\n } catch(err) {\r\n this.useStorage = false;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public delete(key: keyof Storage, saveLocal = false) {\r\n // ! it is needed here\r\n key = '' + key;\r\n\r\n if(!saveLocal) {\r\n delete this.cache[key];\r\n }\r\n \r\n //if(this.useStorage) {\r\n try {\r\n localStorage.removeItem(this.prefix + key);\r\n } catch(err) {\r\n \r\n }\r\n //}\r\n }\r\n\r\n /* public clear(preserveKeys: (keyof Storage)[] = this.preserveKeys) {\r\n // if(this.useStorage) {\r\n try {\r\n let obj: Partial<Storage> = {};\r\n if(preserveKeys) {\r\n preserveKeys.forEach(key => {\r\n const value = this.get(key);\r\n if(value !== undefined) {\r\n obj[key] = value;\r\n }\r\n });\r\n }\r\n \r\n localStorage.clear();\r\n\r\n if(preserveKeys) {\r\n this.set(obj);\r\n }\r\n } catch(err) {\r\n\r\n }\r\n // }\r\n } */\r\n\r\n public clear() {\r\n const keys: string[] = ['dc', 'server_time_offset', 'xt_instance', 'user_auth', 'state_id'];\r\n for(let i = 1; i <= 5; ++i) {\r\n keys.push(`dc${i}_server_salt`);\r\n keys.push(`dc${i}_auth_key`);\r\n }\r\n\r\n for(let key of keys) {\r\n this.delete(key, true);\r\n }\r\n }\r\n\r\n public toggleStorage(enabled: boolean) {\r\n this.useStorage = enabled;\r\n\r\n if(!enabled) {\r\n this.clear();\r\n } else {\r\n return this.set(this.cache);\r\n }\r\n }\r\n}\r\n\r\nexport interface LocalStorageProxyTask extends WorkerTaskTemplate {\r\n type: 'localStorageProxy',\r\n payload: {\r\n type: 'set' | 'get' | 'delete' | 'clear' | 'toggleStorage',\r\n args: any[]\r\n }\r\n};\r\n\r\nexport interface LocalStorageProxyTaskResponse extends WorkerTaskTemplate {\r\n type: 'localStorageProxy',\r\n payload: any\r\n};\r\n\r\nexport default class LocalStorageController<Storage extends Record<string, any>> {\r\n private static STORAGES: LocalStorageController<any>[] = [];\r\n private taskId = 0;\r\n private tasks: {[taskID: number]: (result: any) => void} = {};\r\n //private log = (...args: any[]) => console.log('[SW LS]', ...args);\r\n //private log = (...args: any[]) => {};\r\n\r\n private storage: LocalStorage<Storage>;\r\n\r\n constructor(/* private preserveKeys: (keyof Storage)[] = [] */) {\r\n LocalStorageController.STORAGES.push(this);\r\n\r\n if(!IS_WORKER) {\r\n this.storage = new LocalStorage(/* preserveKeys */);\r\n }\r\n }\r\n\r\n public finishTask(taskId: number, result: any) {\r\n //this.log('finishTask:', taskID, result, Object.keys(this.tasks));\r\n\r\n if(!this.tasks.hasOwnProperty(taskId)) {\r\n //this.log('no such task:', taskID, result);\r\n return;\r\n }\r\n\r\n this.tasks[taskId](result);\r\n delete this.tasks[taskId];\r\n }\r\n\r\n private proxy<T>(type: LocalStorageProxyTask['payload']['type'], ...args: LocalStorageProxyTask['payload']['args']) {\r\n return new Promise<T>((resolve, reject) => {\r\n if(IS_WORKER) {\r\n const taskId = this.taskId++;\r\n\r\n this.tasks[taskId] = resolve;\r\n const task: LocalStorageProxyTask = {\r\n type: 'localStorageProxy', \r\n id: taskId,\r\n payload: {\r\n type,\r\n args\r\n }\r\n };\r\n\r\n notifySomeone(task);\r\n } else {\r\n args = Array.prototype.slice.call(args);\r\n\r\n // @ts-ignore\r\n const result: any = this.storage[type].apply(this.storage, args as any);\r\n resolve(result);\r\n }\r\n });\r\n }\r\n\r\n public get<T extends keyof Storage>(key: T, useCache?: boolean) {\r\n return this.proxy<Storage[T]>('get', key, useCache);\r\n }\r\n\r\n public set(obj: Partial<Storage>, onlyLocal?: boolean) {\r\n return this.proxy<void>('set', obj, onlyLocal);\r\n }\r\n\r\n public delete(key: keyof Storage, saveLocal?: boolean) {\r\n return this.proxy<void>('delete', key, saveLocal);\r\n }\r\n\r\n public clear(/* preserveKeys?: (keyof Storage)[] */) {\r\n return this.proxy<void>('clear'/* , preserveKeys */);\r\n }\r\n\r\n public toggleStorage(enabled: boolean) {\r\n return this.proxy<void>('toggleStorage', enabled);\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 type { AppInstance } from './mtproto/singleInstance';\r\nimport type { UserAuth } from './mtproto/mtproto_config';\r\nimport type { DcId } from '../types';\r\nimport { MOUNT_CLASS_TO } from '../config/debug';\r\nimport LocalStorageController from './localStorage';\r\n\r\nconst sessionStorage = new LocalStorageController<{\r\n dc: DcId,\r\n user_auth: UserAuth,\r\n state_id: number,\r\n dc1_auth_key: string,\r\n dc2_auth_key: string,\r\n dc3_auth_key: string,\r\n dc4_auth_key: string,\r\n dc5_auth_key: string,\r\n dc1_server_salt: string,\r\n dc2_server_salt: string,\r\n dc3_server_salt: string,\r\n dc4_server_salt: string,\r\n dc5_server_salt: string,\r\n server_time_offset: number,\r\n xt_instance: AppInstance,\r\n kz_version: 'K' | 'Z',\r\n tgme_sync: {\r\n canRedirect: boolean,\r\n ts: number\r\n }\r\n}>(/* ['kz_version'] */);\r\nMOUNT_CLASS_TO.appStorage = sessionStorage;\r\nexport default sessionStorage;\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 { TransportType } from \"../lib/mtproto/dcConfigurator\";\r\n\r\nconst Modes = {\r\n test: location.search.indexOf('test=1') > 0/* || true */,\r\n debug: location.search.indexOf('debug=1') > 0,\r\n http: false,\r\n ssl: true, // location.search.indexOf('ssl=1') > 0 || location.protocol === 'https:' && location.search.indexOf('ssl=0') === -1,\r\n multipleConnections: true,\r\n asServiceWorker: false,\r\n transport: 'websocket' as TransportType\r\n};\r\n\r\n \r\nModes.http = location.search.indexOf('http=1') > 0;\r\n \r\n\r\n \r\n \r\n \r\n\r\nif(Modes.http) {\r\n Modes.transport = 'https';\r\n}\r\n\r\n \r\n \r\n \r\n\r\nexport default Modes;\r\n","export default function noop() {}\r\n","export default function isObject<T extends Record<any, any>>(object: any): object is T {\n return typeof(object) === 'object' && object !== null;\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 type { ChatSavedPosition } from './appManagers/appImManager';\r\nimport type { State } from './appManagers/appStateManager';\r\nimport type { AppDraftsManager } from './appManagers/appDraftsManager';\r\nimport { MOUNT_CLASS_TO } from '../config/debug';\r\nimport { LangPackDifference } from '../layer';\r\nimport AppStorage from './storage';\r\nimport DATABASE_STATE from '../config/databases/state';\r\n\r\nconst stateStorage = new AppStorage<{\r\n chatPositions: {\r\n [peerId_threadId: string]: ChatSavedPosition\r\n },\r\n langPack: LangPackDifference,\r\n drafts: AppDraftsManager['drafts'],\r\n user_auth: any, // support old webk format\r\n} & State, typeof DATABASE_STATE>(DATABASE_STATE, 'session');\r\nMOUNT_CLASS_TO.stateStorage = stateStorage;\r\nexport default stateStorage;\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 * Originally from:\n * https://github.com/zhukov/webogram\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\n * https://github.com/zhukov/webogram/blob/master/LICENSE\n */\n\nimport blobSafeMimeType from \"./blobSafeMimeType\";\n\nexport default function blobConstruct(blobParts: any, mimeType: string = ''): Blob {\n let blob;\n const safeMimeType = blobSafeMimeType(mimeType);\n try {\n blob = new Blob(blobParts, {type: safeMimeType});\n } catch(e) {\n // @ts-ignore\n let bb = new BlobBuilder;\n blobParts.forEach((blobPart: any) => {\n bb.append(blobPart);\n });\n blob = bb.getBlob(safeMimeType);\n }\n return blob;\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 * Originally from:\n * https://github.com/zhukov/webogram\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\n * https://github.com/zhukov/webogram/blob/master/LICENSE\n */\n\n// https://www.iana.org/assignments/media-types/media-types.xhtml\nexport default function blobSafeMimeType(mimeType: string) {\n if([\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/svg+xml',\n 'image/webp',\n 'image/bmp',\n 'video/mp4',\n 'video/webm',\n 'video/quicktime',\n 'audio/ogg',\n 'audio/mpeg',\n 'audio/mp4',\n 'application/json',\n 'application/pdf'\n ].indexOf(mimeType) === -1) {\n return 'application/octet-stream';\n }\n\n return mimeType;\n}\n","// * Jolly Cobra's schedulers\r\n\r\nimport { AnyToVoidFunction } from \"../../types\";\r\n\r\nexport default function throttle<F extends AnyToVoidFunction>(\r\n fn: F,\r\n ms: number,\r\n shouldRunFirst = true,\r\n) {\r\n let interval: number | null = null;\r\n let isPending: boolean;\r\n let args: Parameters<F>;\r\n\r\n return (..._args: Parameters<F>) => {\r\n isPending = true;\r\n args = _args;\r\n\r\n if(!interval) {\r\n if(shouldRunFirst) {\r\n isPending = false;\r\n // @ts-ignore\r\n fn(...args);\r\n }\r\n\r\n interval = setInterval(() => {\r\n if (!isPending) {\r\n clearInterval(interval!);\r\n interval = null;\r\n return;\r\n }\r\n\r\n isPending = false;\r\n // @ts-ignore\r\n fn(...args);\r\n }, ms) as any;\r\n }\r\n };\r\n}\r\n"],"sourceRoot":""}