@tma.js/sdk 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/misc/createSingleton.ts","../src/bridge/events/listening/unsubscribe.ts","../src/bridge/events/listening/subscribe.ts","../src/logger/Logger.ts","../src/debug/debug.ts","../src/events/event-emitter/EventEmitter.ts","../src/events/onWindow.ts","../src/misc/createCleanup.ts","../src/errors/SDKError.ts","../src/errors/createError.ts","../src/errors/errors.ts","../src/parsing/createTypeError.ts","../src/parsing/ValueParser/ValueParser.ts","../src/parsing/createValueParserGenerator.ts","../src/parsing/parsers/boolean.ts","../src/parsing/parseBySchema.ts","../src/parsing/toRecord.ts","../src/parsing/parsers/json.ts","../src/parsing/parsers/number.ts","../src/colors/isRGB.ts","../src/colors/isRGBShort.ts","../src/colors/toRGB.ts","../src/parsing/parsers/string.ts","../src/parsing/parsers/rgb.ts","../src/bridge/parseMessage.ts","../src/bridge/events/event-handlers/cleanupEventHandlers.ts","../src/bridge/events/event-handlers/emitMiniAppsEvent.ts","../src/bridge/events/event-handlers/defineEventHandlers.ts","../src/bridge/events/event-emitter/createMiniAppsEventEmitter.ts","../src/bridge/events/event-emitter/singleton.ts","../src/bridge/events/listening/off.ts","../src/bridge/events/listening/on.ts","../src/misc/isRecord.ts","../src/version/compareVersions.ts","../src/supports/supports.ts","../src/env/hasExternalNotify.ts","../src/env/hasWebviewProxy.ts","../src/env/isIframe.ts","../src/bridge/target-origin.ts","../src/bridge/methods/postEvent.ts","../src/bridge/methods/createPostEvent.ts","../src/bridge/utils/captureSameReq.ts","../src/timeout/createTimeoutError.ts","../src/timeout/withTimeout.ts","../src/bridge/utils/request.ts","../src/bridge/utils/invokeCustomMethod.ts","../src/classnames/classNames.ts","../src/classnames/mergeClassNames.ts","../src/colors/isColorDark.ts","../src/classes/State/State.ts","../src/classes/WithStateUtils.ts","../src/supports/createSupportsFn.ts","../src/classes/WithSupportsAndStateUtils.ts","../src/components/BackButton/BackButton.ts","../src/parsing/parsers/date.ts","../src/parsing/parsers/searchParams.ts","../src/components/InitData/parsers/chat.ts","../src/components/InitData/parsers/user.ts","../src/components/InitData/parsers/initData.ts","../src/components/ThemeParams/keys.ts","../src/components/ThemeParams/parsing/themeParams.ts","../src/launch-params/parseLaunchParams.ts","../src/launch-params/retrieveFromUrl.ts","../src/launch-params/retrieveFromLocation.ts","../src/navigation/getFirstNavigationEntry.ts","../src/launch-params/retrieveFromPerformance.ts","../src/storage/storage.ts","../src/launch-params/retrieveFromStorage.ts","../src/components/ThemeParams/parsing/serializeThemeParams.ts","../src/launch-params/serializeLaunchParams.ts","../src/launch-params/saveToStorage.ts","../src/launch-params/retrieveLaunchParams.ts","../src/navigation/isPageReload.ts","../src/request-id/createRequestIdGenerator.ts","../src/misc/createComponentInitFn/createComponentInitFn.ts","../src/components/BackButton/initBackButton.ts","../src/classes/WithSupportsAndTrackableState.ts","../src/components/BiometryManager/formatEvent.ts","../src/components/BiometryManager/BiometryManager.ts","../src/components/BiometryManager/requestBiometryInfo.ts","../src/components/BiometryManager/initBiometryManager.ts","../src/classes/WithTrackableState.ts","../src/components/ClosingBehavior/ClosingBehavior.ts","../src/components/ClosingBehavior/initClosingBehavior.ts","../src/classes/WithSupports.ts","../src/parsing/ArrayParser/ArrayParser.ts","../src/parsing/parsers/array.ts","../src/components/CloudStorage/CloudStorage.ts","../src/components/CloudStorage/initCloudStorage.ts","../src/components/HapticFeedback/HapticFeedback.ts","../src/components/HapticFeedback/initHapticFeedback.ts","../src/components/InitData/InitData.ts","../src/components/InitData/initInitData.ts","../src/components/InitData/parseInitData.ts","../src/components/Invoice/Invoice.ts","../src/components/Invoice/initInvoice.ts","../src/components/MainButton/MainButton.ts","../src/components/MainButton/initMainButton.ts","../src/components/MiniApp/parsing/contact.ts","../src/supports/createSupportsParamFn.ts","../src/timeout/sleep.ts","../src/components/MiniApp/MiniApp.ts","../src/components/MiniApp/initMiniApp.ts","../src/components/Popup/preparePopupParams.ts","../src/components/Popup/Popup.ts","../src/components/Popup/initPopup.ts","../src/components/QRScanner/QRScanner.ts","../src/components/QRScanner/initQRScanner.ts","../src/components/SettingsButton/SettingsButton.ts","../src/components/SettingsButton/initSettingsButton.ts","../src/components/ThemeParams/parsing/parseThemeParams.ts","../src/components/ThemeParams/ThemeParams.ts","../src/components/ThemeParams/initThemeParams.ts","../src/components/ThemeParams/requestThemeParams.ts","../src/components/Utils/Utils.ts","../src/components/Utils/initUtils.ts","../src/components/Viewport/requestViewport.ts","../src/components/Viewport/Viewport.ts","../src/components/Viewport/initViewport.ts","../src/css-vars/setCSSVar.ts","../src/css-vars/bindMiniAppCSSVars.ts","../src/css-vars/bindThemeParamsCSSVars.ts","../src/css-vars/bindViewportCSSVars.ts","../src/env/initWeb.ts","../src/env/isSSR.ts","../src/env/isTMA.ts","../src/errors/isSDKError.ts","../src/errors/isSDKErrorOfType.ts","../src/navigation/BasicNavigator/prepareItem.ts","../src/navigation/BasicNavigator/BasicNavigator.ts","../src/navigation/BrowserNavigator/basicItemToBrowser.ts","../src/navigation/ensurePrefix.ts","../src/navigation/createSafeURL.ts","../src/navigation/urlToPath.ts","../src/navigation/BrowserNavigator/prepareItem.ts","../src/navigation/go.ts","../src/navigation/drop.ts","../src/navigation/getPathname.ts","../src/navigation/BrowserNavigator/BrowserNavigator.ts","../src/navigation/BrowserNavigator/createBrowserNavigatorFromLocation.ts","../src/navigation/getHash.ts","../src/navigation/initNavigator.ts"],"sourcesContent":["/**\n * Creates resettable singleton. We mostly need it for test purposes.\n * @param create - function which creates singleton entity.\n * @param onReset - function which will be called in case, singleton was reset.\n */\nexport function createSingleton<T>(\n create: (reset: () => void) => T,\n onReset?: (entity: T) => void,\n): [\n /**\n * Returns singleton entity.\n */\n get: () => T,\n /**\n * Resets last stored entity.\n */\n reset: () => void,\n] {\n let cached: T | undefined;\n const reset = () => {\n cached !== undefined && onReset && onReset(cached);\n cached = undefined;\n };\n\n return [() => (cached === undefined ? cached = create(reset) : cached), reset];\n}\n","import { miniAppsEventEmitter, resetMiniAppsEventEmitter } from '../event-emitter/singleton.js';\nimport type { MiniAppsSubscribeListener } from '../types.js';\n\n/**\n * Removes global event listener.\n * @param listener - event listener.\n */\nexport function unsubscribe(listener: MiniAppsSubscribeListener): void {\n const ee = miniAppsEventEmitter();\n const { count } = ee;\n ee.unsubscribe(listener);\n\n // If event emitter now has no listeners, we can make a cleanup.\n if (count && !ee.count) {\n resetMiniAppsEventEmitter();\n }\n}\n","import type { RemoveEventListenerFn } from '@/events/types.js';\n\nimport { miniAppsEventEmitter } from '../event-emitter/singleton.js';\nimport { unsubscribe } from '../listening/unsubscribe.js';\nimport type { MiniAppsSubscribeListener } from '../types.js';\n\n/**\n * Subscribes to all events sent from the native Telegram application.\n * @param listener - event listener to bind.\n * @returns Function to remove bound event listener.\n */\nexport function subscribe(listener: MiniAppsSubscribeListener): RemoveEventListenerFn {\n miniAppsEventEmitter().subscribe(listener);\n return () => unsubscribe(listener);\n}\n","/**\n * Message log level.\n */\nexport type LogLevel = 'log' | 'error';\n\nexport interface LoggerOptions {\n bgColor?: string;\n textColor?: string;\n}\n\nexport class Logger implements Pick<Console, 'log' | 'error'> {\n constructor(\n private readonly scope: string,\n private readonly options: LoggerOptions = {},\n ) {\n }\n\n /**\n * Prints message into a console in case, logger is currently enabled.\n * @param level - log level.\n * @param args - arguments.\n */\n private print(level: LogLevel, ...args: any[]): void {\n const now = new Date();\n const date = Intl\n .DateTimeFormat('en-GB', {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n fractionalSecondDigits: 3,\n timeZone: 'UTC',\n })\n .format(now);\n\n const { textColor, bgColor } = this.options;\n const commonCss = 'font-weight: bold;padding: 0 5px;border-radius:5px';\n\n console[level](\n `%c${date}%c / %c${this.scope}`,\n `${commonCss};background-color: lightblue;color:black`,\n '',\n `${commonCss};${textColor ? `color:${textColor};` : ''}${bgColor ? `background-color:${bgColor}` : ''}`,\n ...args,\n );\n }\n\n /**\n * Prints error message into a console.\n * @param args\n */\n error(...args: any[]): void {\n this.print('error', ...args);\n }\n\n /**\n * Prints log message into a console.\n * @param args\n */\n log(...args: any[]): void {\n this.print('log', ...args);\n }\n}\n","import { subscribe } from '@/bridge/events/listening/subscribe.js';\nimport { unsubscribe } from '@/bridge/events/listening/unsubscribe.js';\nimport { Logger } from '@/logger/Logger.js';\nimport type { MiniAppsSubscribeListener } from '@/bridge/events/types.js';\n\nexport const logger = new Logger('SDK', {\n bgColor: 'forestgreen',\n textColor: 'white',\n});\n\nlet debugEnabled = false;\n\nconst onEvent: MiniAppsSubscribeListener = ({ name, payload }) => {\n logger.log('Event received:', payload ? { name, payload } : { name });\n};\n\n/**\n * Sets new debug mode. Enabling debug mode leads to printing additional messages in the console,\n * related to the processes inside the package.\n * @param enable - should debug be enabled.\n */\nexport function setDebug(enable: boolean): void {\n if (debugEnabled !== enable) {\n debugEnabled = enable;\n enable ? subscribe(onEvent) : unsubscribe(onEvent);\n }\n}\n\n/**\n * Logs info message into the console.\n * @param args - additional arguments.\n */\nexport function log(...args: any[]): void {\n if (debugEnabled) {\n logger.log(...args);\n }\n}\n","import type { RemoveEventListenerFn } from '../types.js';\nimport type {\n EmptyEventName,\n EventListener,\n EventName,\n EventParams,\n NonEmptyEventName,\n SubscribeListener,\n} from './types.js';\n\nexport class EventEmitter<Schema> {\n private readonly listeners: Map<\n string,\n [listener: EventListener<any>, once?: boolean][]\n > = new Map();\n\n private listenersCount = 0;\n\n private subscribeListeners: SubscribeListener<Schema>[] = [];\n\n /**\n * Removes all event listeners.\n */\n clear() {\n this.listeners.clear();\n this.subscribeListeners = [];\n }\n\n /**\n * Returns count of bound listeners.\n */\n get count(): number {\n return this.listenersCount + this.subscribeListeners.length;\n }\n\n /**\n * Emits known event which has no parameters.\n * @param event - event name.\n */\n emit<E extends EmptyEventName<Schema>>(event: E): void;\n\n /**\n * Emits known event which has parameters.\n * @param event - event name.\n * @param args - list of event listener arguments.\n */\n emit<E extends NonEmptyEventName<Schema>>(event: E, ...args: EventParams<Schema[E]>): void;\n\n emit(event: EventName<Schema>, ...args: any[]): void {\n this.subscribeListeners.forEach((l) => l({\n event,\n args: args as EventParams<Schema[EventName<Schema>]>,\n }));\n\n const listeners = this.listeners.get(event) || [];\n\n listeners.forEach(([listener, once]) => {\n listener(...args);\n if (once) {\n this.off(event, listener);\n }\n });\n }\n\n /**\n * Adds new event listener.\n * @param event - event name.\n * @param listener - event listener.\n * @param once - should listener be called only once.\n * @returns Function to remove bound event listener.\n */\n on<E extends EventName<Schema>>(\n event: E,\n listener: EventListener<Schema[E]>,\n once?: boolean,\n ): RemoveEventListenerFn {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n this.listeners.set(event, listeners = []);\n }\n\n listeners.push([listener, once]);\n this.listenersCount += 1;\n\n return () => this.off(event, listener);\n }\n\n /**\n * Removes event listener. In case, specified listener was bound several times, it removes\n * only a single one.\n * @param event - event name.\n * @param listener - event listener.\n */\n off<E extends EventName<Schema>>(event: E, listener: EventListener<Schema[E]>): void {\n const listeners = this.listeners.get(event) || [];\n for (let i = 0; i < listeners.length; i += 1) {\n if (listener === listeners[i][0]) {\n listeners.splice(i, 1);\n this.listenersCount -= 1;\n return;\n }\n }\n }\n\n /**\n * Adds a new event listener for all events.\n * @param listener - event listener.\n * @returns Function to remove event listener.\n */\n subscribe(listener: SubscribeListener<Schema>): RemoveEventListenerFn {\n this.subscribeListeners.push(listener);\n return () => this.unsubscribe(listener);\n }\n\n /**\n * Removes global event listener. In case, specified listener was bound several times, it removes\n * only a single one.\n * @param listener - event listener.\n */\n unsubscribe(listener: SubscribeListener<Schema>): void {\n for (let i = 0; i < this.subscribeListeners.length; i += 1) {\n if (this.subscribeListeners[i] === listener) {\n this.subscribeListeners.splice(i, 1);\n return;\n }\n }\n }\n}\n","import type { RemoveEventListenerFn } from './types.js';\n\n/**\n * Adds new event listener using window.addEventListener.\n * @param type - event name.\n * @param listener - event listener.\n * @param options - listening options.\n * @returns Function to remove event listener.\n */\nexport function onWindow<K extends keyof WindowEventMap>(\n type: K,\n listener: (this: Window, ev: WindowEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n): RemoveEventListenerFn {\n window.addEventListener(type, listener, options);\n return () => window.removeEventListener(type, listener, options);\n}\n","import { CleanupFn } from '@/types/index.js';\n\n/**\n * Returns a tuple, containing function to add cleanup, call cleanup, and flag showing whether\n * cleanup was called. Cleanup will not be performed in case, it was done before.\n */\nexport function createCleanup(...fns: CleanupFn[]): [\n add: (fn: CleanupFn) => void,\n call: () => void,\n cleanedUp: boolean,\n] {\n let called = false;\n const cache: CleanupFn[] = [...fns];\n\n return [\n (fn) => !called && cache.push(fn),\n () => {\n if (!called) {\n called = true;\n cache.forEach(clean => clean());\n }\n },\n called,\n ];\n}","import type { ErrorType } from './errors.js';\n\n/**\n * Error used across the SDK.\n */\nexport class SDKError extends Error {\n constructor(public readonly type: ErrorType, message?: string, cause?: unknown) {\n super(message, { cause });\n Object.setPrototypeOf(this, SDKError.prototype);\n }\n}\n","import { SDKError } from './SDKError.js';\nimport type { ErrorType } from './errors.js';\n\n/**\n * Creates new error using specified type and message.\n * @param type - error code.\n * @param message - error message.\n * @param cause - original error.\n */\nexport function createError(type: ErrorType, message: string, cause?: unknown): SDKError {\n return new SDKError(type, message, cause);\n}\n","/**\n * Specified Mini Apps method is unsupported.\n */\nexport const ERR_METHOD_UNSUPPORTED = 'ERR_METHOD_UNSUPPORTED';\n\n/**\n * Specified Mini Apps method parameter is unsupported.\n */\nexport const ERR_METHOD_PARAMETER_UNSUPPORTED = 'ERR_METHOD_PARAMETER_UNSUPPORTED';\n\n/**\n * Current environment is not Telegram application.\n */\nexport const ERR_UNKNOWN_ENV = 'ERR_UNKNOWN_ENV';\n\n/**\n * Telegram application returned and error while invoking custom method.\n */\nexport const ERR_INVOKE_CUSTOM_METHOD_RESPONSE = 'ERR_INVOKE_CUSTOM_METHOD_RESPONSE';\n\n/**\n * Timeout reached.\n */\nexport const ERR_TIMED_OUT = 'ERR_TIMED_OUT';\n\n/**\n * Value has unexpected type.\n */\nexport const ERR_UNEXPECTED_TYPE = 'ERR_UNEXPECTED_TYPE';\n\n/**\n * Something went wrong during value parsing.\n */\nexport const ERR_PARSE = 'ERR_PARSE';\n\n/**\n * Navigation entries list is empty.\n */\nexport const ERR_NAVIGATION_HISTORY_EMPTY = 'ERR_NAVIGATION_LIST_EMPTY';\n\n/**\n * Navigation entries cursor is invalid.\n */\nexport const ERR_NAVIGATION_INDEX_INVALID = 'ERR_NAVIGATION_CURSOR_INVALID';\n\n/**\n * Navigation entries item is invalid.\n */\nexport const ERR_NAVIGATION_ITEM_INVALID = 'ERR_NAVIGATION_ITEM_INVALID';\n\n/**\n * SSR component initialization failed.\n */\nexport const ERR_SSR_INIT = 'ERR_SSR_INIT';\n\n/**\n * Path starts from the invalid base.\n */\nexport const ERR_INVALID_PATH_BASE = 'ERR_INVALID_PATH_BASE';\n\nexport type ErrorType =\n | typeof ERR_METHOD_UNSUPPORTED\n | typeof ERR_METHOD_PARAMETER_UNSUPPORTED\n | typeof ERR_UNKNOWN_ENV\n | typeof ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n | typeof ERR_TIMED_OUT\n | typeof ERR_PARSE\n | typeof ERR_UNEXPECTED_TYPE\n | typeof ERR_NAVIGATION_HISTORY_EMPTY\n | typeof ERR_NAVIGATION_INDEX_INVALID\n | typeof ERR_NAVIGATION_ITEM_INVALID\n | typeof ERR_SSR_INIT\n | typeof ERR_INVALID_PATH_BASE;\n","import { createError } from '@/errors/createError.js';\nimport { ERR_UNEXPECTED_TYPE } from '@/errors/errors.js';\nimport type { SDKError } from '@/errors/SDKError.js';\n\n/**\n * Creates instance of TypeError stating, that value has unexpected type.\n */\nexport function createTypeError(): SDKError {\n return createError(ERR_UNEXPECTED_TYPE, 'Value has unexpected type');\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_PARSE } from '@/errors/errors.js';\n\nimport type { Parser } from '../types.js';\nimport type { ValueParserOptionalResult, ValueParserParseResult } from './types.js';\n\nexport class ValueParser<ResultType, IsOptional extends boolean> {\n constructor(\n protected parser: Parser<ResultType>,\n protected isOptional: IsOptional,\n protected type?: string,\n ) {\n }\n\n /**\n * Attempts to parse passed value\n * @param value - value to parse.\n * @throws {SDKError} ERR_PARSE\n * @see ERR_PARSE\n */\n parse(value: unknown): ValueParserParseResult<ResultType, IsOptional> {\n // In case, parsing result is specified as optional, and passed value is considered as empty,\n // we can return undefined. Otherwise, pass to parser.\n if (this.isOptional && value === undefined) {\n return undefined as ValueParserParseResult<ResultType, IsOptional>;\n }\n\n try {\n return this.parser(value) as ValueParserParseResult<ResultType, IsOptional>;\n } catch (cause) {\n throw createError(\n ERR_PARSE,\n `Unable to parse value${this.type ? ` as ${this.type}` : ''}`,\n cause,\n );\n }\n }\n\n optional(): ValueParserOptionalResult<this, ResultType> {\n this.isOptional = true as IsOptional;\n return this as ValueParserOptionalResult<this, ResultType>;\n }\n}\n","import { ValueParser } from './ValueParser/ValueParser.js';\nimport type { Parser } from './types.js';\n\nexport type ValueParserGenerator<T> = () => ValueParser<T, false>;\n\n/**\n * Creates function which generates new scalar value parser based on the specified one.\n * @param parser - parser to use as basic.\n * @param type - type name.\n */\nexport function createValueParserGenerator<T>(\n parser: Parser<T>,\n type?: string,\n): ValueParserGenerator<T> {\n return () => new ValueParser(parser, false, type);\n}\n","import { createTypeError } from '../createTypeError.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as boolean.\n */\nexport const boolean: ValueParserGenerator<boolean> = createValueParserGenerator((value) => {\n if (typeof value === 'boolean') {\n return value;\n }\n const asString = String(value);\n\n if (asString === '1' || asString === 'true') {\n return true;\n }\n\n if (asString === '0' || asString === 'false') {\n return false;\n }\n\n throw createTypeError();\n}, 'boolean');\n","import { createError } from '@/errors/createError.js';\nimport { ERR_PARSE } from '@/errors/errors.js';\n\nimport type { Parser, Schema } from './types.js';\n\n/**\n * Parses external value by specified schema. Functions iterates over each schema field\n * and uses getField function to get its value from the external source.\n * @param schema - object schema.\n * @param getField - function which gets external value by its field name.\n */\nexport function parseBySchema<T>(\n schema: Schema<T>,\n getField: (field: string) => unknown,\n): T {\n const result = {} as T;\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const field in schema) {\n const definition = schema[field];\n if (!definition) {\n continue;\n }\n\n let from: string;\n let parser: Parser<any>;\n\n // In case, definition has \"type\" property, then SchemaFieldDetailed was passed.\n if (typeof definition === 'function' || 'parse' in definition) {\n // Otherwise we are working with either parser function or instance.\n from = field;\n parser = typeof definition === 'function' ? definition : definition.parse.bind(definition);\n } else {\n const { type: definitionType } = definition;\n\n from = definition.from || field;\n parser = typeof definitionType === 'function'\n ? definitionType\n : definitionType.parse.bind(definitionType);\n }\n\n try {\n const parsedValue = parser(getField(from));\n if (parsedValue !== undefined) {\n (result as any)[field] = parsedValue;\n }\n } catch (error) {\n throw createError(ERR_PARSE, `Unable to parse field \"${field}\"`, error);\n }\n }\n\n return result;\n}\n","import { createTypeError } from './createTypeError.js';\n\n/**\n * Converts value to record.\n * @param value - value to convert.\n * @throws {Error} Value passed as a string does not represent JSON object.\n * @throws {Error} Value is not convertable.\n */\nexport function toRecord(value: unknown): Record<string, unknown> {\n let formattedValue: any = value;\n\n // Convert value to JSON in case, it is string. We expect value to be JSON string.\n if (typeof formattedValue === 'string') {\n formattedValue = JSON.parse(formattedValue);\n }\n\n // We expect json to be usual object.\n if (\n typeof formattedValue !== 'object'\n || formattedValue === null\n || Array.isArray(formattedValue)\n ) {\n throw createTypeError();\n }\n\n return formattedValue;\n}\n","import { parseBySchema } from '../parseBySchema.js';\nimport { toRecord } from '../toRecord.js';\nimport { ValueParser } from '../ValueParser/ValueParser.js';\nimport type { Schema } from '../types.js';\n\n/**\n * Creates new Json parser according to passed schema.\n * @param schema - object schema.\n * @param type - parser type name.\n */\nexport function json<T>(schema: Schema<T>, type?: string): ValueParser<T, false> {\n return new ValueParser((value) => {\n const record = toRecord(value);\n return parseBySchema(schema, (field) => record[field]);\n }, false, type);\n}\n","import { createTypeError } from '../createTypeError.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as number.\n */\nexport const number: ValueParserGenerator<number> = createValueParserGenerator((value) => {\n if (typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'string') {\n const num = Number(value);\n\n if (!Number.isNaN(num)) {\n return num;\n }\n }\n\n throw createTypeError();\n}, 'number');\n","import type { RGB } from './types.js';\n\n/**\n * Returns true in case, passed value has #RRGGBB format.\n * @param value - value to check.\n */\nexport function isRGB(value: string): value is RGB {\n return /^#[\\da-f]{6}$/i.test(value);\n}\n","import type { RGBShort } from './types.js';\n\n/**\n * Returns true in case, passed value has #RGB format.\n * @param value - value to check.\n */\nexport function isRGBShort(value: string): value is RGBShort {\n return /^#[\\da-f]{3}$/i.test(value);\n}\n","import { isRGB } from './isRGB.js';\nimport { isRGBShort } from './isRGBShort.js';\nimport type { RGB } from './types.js';\n\n/**\n * Converts passed value to #RRGGBB format. Accepts following color formats:\n * - `#RGB`\n * - `#RRGGBB`\n * - `rgb(1,2,3)`\n * - `rgba(1,2,3,4)`\n * @param value - value to convert.\n * @throws {Error} Passed value does not satisfy any of known RGB formats.\n */\nexport function toRGB(value: string): RGB {\n // Remove all spaces.\n const clean = value.replace(/\\s/g, '').toLowerCase();\n\n // Value already has required format.\n if (isRGB(clean)) {\n return clean;\n }\n\n // Convert from #RGB.\n if (isRGBShort(clean)) {\n let color: RGB = '#';\n for (let i = 0; i < 3; i += 1) {\n color += clean[1 + i].repeat(2);\n }\n return color;\n }\n\n // Example valid values: rgb(0,3,10) rgba(32,114,8,0)\n const match = clean.match(/^rgb\\((\\d{1,3}),(\\d{1,3}),(\\d{1,3})\\)$/)\n || clean.match(/^rgba\\((\\d{1,3}),(\\d{1,3}),(\\d{1,3}),\\d{1,3}\\)$/);\n\n // In case, this didn't work as well, we can't extract RGB color from passed\n // text.\n if (!match) {\n throw new Error(`Value \"${value}\" does not satisfy any of known RGB formats.`);\n }\n\n // Otherwise, take R, G and B components, convert to hex and create #RRGGBB\n // string.\n return match.slice(1).reduce((acc, component) => {\n const formatted = parseInt(component, 10).toString(16);\n return acc + (formatted.length === 1 ? '0' : '') + formatted;\n }, '#') as RGB;\n}\n","import { createTypeError } from '../createTypeError.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as string.\n */\nexport const string: ValueParserGenerator<string> = createValueParserGenerator((value) => {\n if (typeof value === 'string' || typeof value === 'number') {\n return value.toString();\n }\n throw createTypeError();\n}, 'string');\n","import { toRGB } from '@/colors/toRGB.js';\nimport type { RGB } from '@/colors/types.js';\n\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { string } from './string.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as RGB color.\n */\nexport const rgb: ValueParserGenerator<RGB> = createValueParserGenerator((value) => toRGB(string().parse(value)), 'rgb');\n","import { json } from '@/parsing/parsers/json.js';\nimport { string } from '@/parsing/parsers/string.js';\n\n/**\n * Message format used in communication between client and Telegram applications.\n */\nexport interface MiniAppsMessage {\n /**\n * Event name.\n */\n eventType: string;\n /**\n * Event parameters.\n */\n eventData?: unknown;\n}\n\n/**\n * Parses value as a message between client and Telegram applications.\n * @param value - value to parse.\n */\nexport function parseMessage(value: unknown): MiniAppsMessage {\n return json({\n eventType: string(),\n eventData: (v) => v,\n }).parse(value);\n}\n","/**\n * Removes global event handlers, used by the package.\n */\nexport function cleanupEventHandlers(): void {\n ['TelegramGameProxy_receiveEvent', 'TelegramGameProxy', 'Telegram'].forEach((prop) => {\n delete window[prop as keyof Window];\n });\n}\n","/**\n * Emits event sent from Telegram native application like it was sent in\n * default web environment between 2 iframes. It dispatches new MessageEvent\n * and expects it to be handled via `window.addEventListener('message', ...)`\n * as developer would do it to handle messages sent from the parent iframe.\n * @param eventType - event name.\n * @param eventData - event payload.\n */\nexport function emitMiniAppsEvent(eventType: string, eventData: unknown): void {\n window.dispatchEvent(new MessageEvent('message', {\n data: JSON.stringify({ eventType, eventData }),\n // We specify window.parent to imitate the case, the parent iframe sent us this event.\n source: window.parent,\n }));\n}\n","import { emitMiniAppsEvent } from './emitMiniAppsEvent.js';\n\n/**\n * Defines special handlers by known paths, which are recognized by\n * Telegram as ports to receive events. This function also sets special\n * function in global window object to prevent duplicate declaration.\n */\nexport function defineEventHandlers() {\n // Iterate over each path, where \"receiveEvent\" function should be\n // defined. This function is called by external environment in case,\n // it wants to emit some event.\n [\n ['TelegramGameProxy_receiveEvent'], // Windows Phone.\n ['TelegramGameProxy', 'receiveEvent'], // Desktop.\n ['Telegram', 'WebView', 'receiveEvent'], // Android and iOS.\n ].forEach((path) => {\n // Path starts from the \"window\" object.\n let pointer = window as any;\n\n path.forEach((item, idx, arr) => {\n // We are on the last iteration, where function property name is passed.\n if (idx === arr.length - 1) {\n pointer[item] = emitMiniAppsEvent;\n return;\n }\n\n if (!(item in pointer)) {\n pointer[item] = {};\n }\n pointer = pointer[item];\n });\n });\n}\n","import { logger } from '@/debug/debug.js';\nimport { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport { onWindow } from '@/events/onWindow.js';\nimport { createCleanup } from '@/misc/createCleanup.js';\nimport { boolean } from '@/parsing/parsers/boolean.js';\nimport { json } from '@/parsing/parsers/json.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { rgb } from '@/parsing/parsers/rgb.js';\nimport { string } from '@/parsing/parsers/string.js';\nimport { toRecord } from '@/parsing/toRecord.js';\nimport type { RGB } from '@/colors/types.js';\n\nimport { type MiniAppsMessage, parseMessage } from '../../parseMessage.js';\nimport { cleanupEventHandlers } from '../event-handlers/cleanupEventHandlers.js';\nimport { defineEventHandlers } from '../event-handlers/defineEventHandlers.js';\nimport type {\n MiniAppsEventName,\n MiniAppsEventPayload,\n MiniAppsEventEmitter,\n MiniAppsEvents,\n} from '../types.js';\n\n/**\n * Parsers for each Mini Apps event.\n *\n * This map should be cleaned\n */\nconst parsers: {\n [E in MiniAppsEventName]?: {\n parse(value: unknown): MiniAppsEventPayload<E>;\n }\n} = {\n clipboard_text_received: json({\n req_id: string(),\n data: (value) => (value === null ? value : string().optional().parse(value)),\n }),\n custom_method_invoked: json({\n req_id: string(),\n result: (value) => value,\n error: string().optional(),\n }),\n invoice_closed: json({ slug: string(), status: string() }),\n phone_requested: json({ status: string() }),\n popup_closed: {\n parse(value) {\n return json({\n button_id: (value) => (\n value === null || value === undefined\n ? undefined\n : string().parse(value)\n ),\n }).parse(value ?? {});\n },\n },\n qr_text_received: json({ data: string().optional() }),\n theme_changed: json({\n theme_params: (value) => {\n const parser = rgb().optional();\n\n return Object\n .entries(toRecord(value))\n .reduce<Partial<Record<string, RGB>>>((acc, [k, v]) => {\n acc[k] = parser.parse(v);\n return acc;\n }, {});\n },\n }),\n viewport_changed: json({\n height: number(),\n width: (value) => (\n value === null || value === undefined\n ? window.innerWidth\n : number().parse(value)\n ),\n is_state_stable: boolean(),\n is_expanded: boolean(),\n }),\n write_access_requested: json({ status: string() }),\n};\n\n/**\n * Creates new event emitter, which handles events from the Telegram application.\n */\nexport function createMiniAppsEventEmitter(): [\n /**\n * Created event emitter.\n */\n emitter: MiniAppsEventEmitter,\n /**\n * Function to dispose created emitter.\n */\n dispose: () => void,\n] {\n // We use this event emitter for better developer experience, using the subscribe method.\n const subEmitter = new EventEmitter<{ event: any[] }>();\n\n // Event emitter processing all the incoming events.\n const mainEmitter = new EventEmitter<MiniAppsEvents>();\n\n mainEmitter.subscribe(event => {\n subEmitter.emit('event', { name: event.event, payload: event.args[0] });\n });\n\n // Define event handles, which will proxy native method calls to their web version.\n defineEventHandlers();\n\n // List of cleanup functions, which should be called on dispose.\n const [, cleanup] = createCleanup(\n // Don't forget to remove created handlers.\n cleanupEventHandlers,\n // Add \"resize\" event listener to make sure, we always have fresh viewport information.\n // Desktop version of Telegram is sometimes not sending the viewport_changed\n // event. For example, when the MainButton is shown. That's why we should\n // add our own listener to make sure, viewport information is always fresh.\n // Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/10\n onWindow('resize', () => {\n mainEmitter.emit('viewport_changed', {\n width: window.innerWidth,\n height: window.innerHeight,\n is_state_stable: true,\n is_expanded: true,\n });\n }),\n // Add listener, which handles events sent from the Telegram web application and also events\n // generated by the local emitEvent function.\n onWindow('message', (event) => {\n // Ignore non-parent window messages.\n if (event.source !== window.parent) {\n return;\n }\n\n // Parse incoming event data.\n let message: MiniAppsMessage;\n try {\n message = parseMessage(event.data);\n } catch {\n // We ignore incorrect messages as they could be generated by any other code.\n return;\n }\n\n const { eventType, eventData } = message;\n const parser = parsers[eventType as keyof typeof parsers];\n\n try {\n const data = parser ? parser.parse(eventData) : eventData;\n mainEmitter.emit(...(data ? [eventType, data] : [eventType]) as [any, any]);\n } catch (cause) {\n logger.error(\n `An error occurred processing the \"${eventType}\" event from the Telegram application. Please, file an issue here: https://github.com/Telegram-Mini-Apps/tma.js/issues/new/choose`,\n message,\n cause,\n );\n }\n }),\n // Clear emitters.\n () => subEmitter.clear(),\n () => mainEmitter.clear(),\n );\n\n return [{\n on: mainEmitter.on.bind(mainEmitter),\n off: mainEmitter.off.bind(mainEmitter),\n subscribe(listener) {\n return subEmitter.on('event', listener);\n },\n unsubscribe(listener) {\n subEmitter.off('event', listener);\n },\n get count() {\n return mainEmitter.count + subEmitter.count;\n },\n }, cleanup];\n}\n","import { createSingleton } from '@/misc/createSingleton.js';\n\nimport { createMiniAppsEventEmitter } from './createMiniAppsEventEmitter.js';\nimport type { MiniAppsEventEmitter } from '../types.js';\n\nconst [get, resetMiniAppsEventEmitter] = createSingleton(\n (reset) => {\n const [emitter, cleanup] = createMiniAppsEventEmitter();\n\n // Rewire \"off\" method and make it reset singleton if no event listeners left.\n const off = emitter.off.bind(emitter);\n emitter.off = (event, listener) => {\n const { count } = emitter;\n off(event, listener);\n\n // If event emitter now has no listeners, we can perform a reset.\n if (count && !emitter.count) {\n reset();\n }\n };\n\n return [emitter, cleanup] as const;\n },\n ([, cleanup]) => cleanup(),\n);\n\n/**\n * Returns Mini Apps event emitter singleton.\n */\nexport function miniAppsEventEmitter(): MiniAppsEventEmitter {\n return get()[0];\n}\n\nexport { resetMiniAppsEventEmitter };\n","import { miniAppsEventEmitter } from '../event-emitter/singleton.js';\nimport type { MiniAppsEventListener, MiniAppsEventName } from '../types.js';\n\n/**\n * Removes listener from specified event.\n * @param event - event to listen.\n * @param listener - event listener to remove.\n */\nexport function off<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n): void {\n miniAppsEventEmitter().off(event, listener);\n}\n","import type { RemoveEventListenerFn } from '@/events/types.js';\n\nimport { miniAppsEventEmitter } from '../event-emitter/singleton.js';\nimport type { MiniAppsEventListener, MiniAppsEventName } from '../types.js';\n\n/**\n * Adds new listener to the specified event. Returns handler\n * which allows to stop listening to event.\n * @param event - event name.\n * @param listener - event listener.\n * @param once - should listener be called only once.\n * @returns Function to remove bound event listener.\n */\nexport function on<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n once?: boolean,\n): RemoveEventListenerFn {\n return miniAppsEventEmitter().on(event, listener, once);\n}\n","/**\n * States that passed value is Record and not Array.\n * @param value - value to check.\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import type { Version } from './types.js';\n\n/**\n * Returns 1 in case, version \"a\" is greater than \"b\".\n * Returns 0 in case, version \"a\" equal to \"b\".\n * Returns -1 in case, version \"a\" is lower than \"b\".\n * @param a - first version.\n * @param b - second version.\n */\nexport function compareVersions(a: Version, b: Version): number {\n // Split both of the version by dot.\n const aParts = a.split('.');\n const bParts = b.split('.');\n\n // Compute maximum length.\n const len = Math.max(aParts.length, bParts.length);\n\n // Iterate over each part of version and compare them. In case, part is\n // missing, assume its value is equal to 0.\n for (let i = 0; i < len; i += 1) {\n const aVal = parseInt(aParts[i] || '0', 10);\n const bVal = parseInt(bParts[i] || '0', 10);\n\n if (aVal === bVal) {\n continue;\n }\n return aVal > bVal ? 1 : -1;\n }\n return 0;\n}\n","import { compareVersions } from '@/version/compareVersions.js';\nimport type {\n MiniAppsMethodName,\n MiniAppsMethodVersionedParams,\n MiniAppsMethodWithVersionedParams,\n} from '@/bridge/methods/types/methods.js';\nimport type { Version } from '@/version/types.js';\n\n/**\n * Returns true if \"a\" version is less than or equal to \"b\" version.\n * @param a\n * @param b\n */\nfunction versionLessOrEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) <= 0;\n}\n\n/**\n * Returns true in case, passed parameter in specified method is supported.\n * @param method - method name\n * @param param - method parameter\n * @param inVersion - platform version.\n */\nexport function supports<M extends MiniAppsMethodWithVersionedParams>(\n method: M,\n param: MiniAppsMethodVersionedParams<M>,\n inVersion: Version,\n): boolean;\n\n/**\n * Returns true in case, specified method is supported in passed version.\n * @param method - method name.\n * @param inVersion - platform version.\n */\nexport function supports(method: MiniAppsMethodName, inVersion: Version): boolean;\n\nexport function supports(\n method: MiniAppsMethodName,\n paramOrVersion: Version | string,\n inVersion?: string,\n): boolean {\n // Method name, parameter, target version.\n if (typeof inVersion === 'string') {\n if (method === 'web_app_open_link') {\n if (paramOrVersion === 'try_instant_view') {\n return versionLessOrEqual('6.4', inVersion);\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if (paramOrVersion === 'color') {\n return versionLessOrEqual('6.9', inVersion);\n }\n }\n }\n\n switch (method) {\n case 'web_app_open_tg_link':\n case 'web_app_open_invoice':\n case 'web_app_setup_back_button':\n case 'web_app_set_background_color':\n case 'web_app_set_header_color':\n case 'web_app_trigger_haptic_feedback':\n return versionLessOrEqual('6.1', paramOrVersion);\n case 'web_app_open_popup':\n return versionLessOrEqual('6.2', paramOrVersion);\n case 'web_app_close_scan_qr_popup':\n case 'web_app_open_scan_qr_popup':\n case 'web_app_read_text_from_clipboard':\n return versionLessOrEqual('6.4', paramOrVersion);\n case 'web_app_switch_inline_query':\n return versionLessOrEqual('6.7', paramOrVersion);\n case 'web_app_invoke_custom_method':\n case 'web_app_request_write_access':\n case 'web_app_request_phone':\n return versionLessOrEqual('6.9', paramOrVersion);\n case 'web_app_setup_settings_button':\n return versionLessOrEqual('6.10', paramOrVersion);\n case 'web_app_biometry_get_info':\n case 'web_app_biometry_open_settings':\n case 'web_app_biometry_request_access':\n case 'web_app_biometry_request_auth':\n case 'web_app_biometry_update_token':\n return versionLessOrEqual('7.2', paramOrVersion);\n default:\n return [\n 'iframe_ready',\n 'iframe_will_reload',\n 'web_app_close',\n 'web_app_data_send',\n 'web_app_expand',\n 'web_app_open_link',\n 'web_app_ready',\n 'web_app_request_theme',\n 'web_app_request_viewport',\n 'web_app_setup_main_button',\n 'web_app_setup_closing_behavior',\n ].includes(method);\n }\n}\n","import { isRecord } from '@/misc/isRecord.js';\n\n/**\n * Returns true in case, passed value contains path `external.notify` property and `notify` is a\n * function.\n * @param value - value to check.\n */\nexport function hasExternalNotify<T extends object>(value: T): value is (\n T & {\n external: {\n notify: (...args: any) => any;\n };\n}) {\n return 'external' in value\n && isRecord(value.external)\n && 'notify' in value.external\n && typeof value.external.notify === 'function';\n}\n","import { isRecord } from '@/misc/isRecord.js';\n\n/**\n * Returns true in case, passed value contains path `TelegramWebviewProxy.postEvent` property and\n * `postEvent` is a function.\n * @param value - value to check.\n */\nexport function hasWebviewProxy<T extends {}>(value: T): value is (\n T & {\n TelegramWebviewProxy: {\n postEvent: (...args: any) => any;\n }\n}) {\n return 'TelegramWebviewProxy' in value\n && isRecord(value.TelegramWebviewProxy)\n && 'postEvent' in value.TelegramWebviewProxy\n && typeof value.TelegramWebviewProxy.postEvent === 'function';\n}\n","/**\n * @see https://stackoverflow.com/a/326076\n * @returns True, if current environment is iframe.\n */\nexport function isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n","let currentTargetOrigin = 'https://web.telegram.org';\n\n/**\n * Sets new global targetOrigin, used by `postEvent` method.\n * Default value is \"https://web.telegram.org\". You don't need to\n * use this method until you know what you are doing.\n *\n * This method could be used for test purposes.\n * @param value - new target origin.\n */\nexport function setTargetOrigin(value: string): void {\n currentTargetOrigin = value;\n}\n\n/**\n * Returns current global target origin.\n */\nexport function targetOrigin(): string {\n return currentTargetOrigin;\n}\n","import { log } from '@/debug/debug.js';\nimport { hasExternalNotify } from '@/env/hasExternalNotify.js';\nimport { hasWebviewProxy } from '@/env/hasWebviewProxy.js';\nimport { isIframe } from '@/env/isIframe.js';\nimport { createError } from '@/errors/createError.js';\nimport { ERR_UNKNOWN_ENV } from '@/errors/errors.js';\n\nimport { targetOrigin as targetOriginFn } from '../target-origin.js';\nimport type {\n MiniAppsMethodName,\n MiniAppsMethodParams,\n MiniAppsMethodWithOptionalParams,\n MiniAppsMethodWithoutParams,\n MiniAppsMethodWithRequiredParams,\n} from './types/methods.js';\n\ninterface PostEventOptions {\n /**\n * Origin used while posting message. This option is only used in case, current environment\n * is browser (Web version of Telegram) and could be used for test purposes.\n * @default 'https://web.telegram.org'\n */\n targetOrigin?: string;\n}\n\nexport type PostEvent = typeof postEvent;\n\n/**\n * Calls Mini Apps method with optional parameters.\n * @param method - method name.\n * @param params - method parameters.\n * @param options - posting options.\n * @throws {SDKError} ERR_UNKNOWN_ENV\n * @see ERR_UNKNOWN_ENV\n */\nexport function postEvent<Method extends MiniAppsMethodWithOptionalParams>(\n method: Method,\n params?: MiniAppsMethodParams<Method>,\n options?: PostEventOptions,\n): void;\n\n/**\n * Calls Mini Apps method without parameters.\n * @param method - method name.\n * @param options - posting options.\n * @throws {SDKError} ERR_UNKNOWN_ENV\n * @see ERR_UNKNOWN_ENV\n */\nexport function postEvent(method: MiniAppsMethodWithoutParams, options?: PostEventOptions): void;\n\n/**\n * Calls Mini Apps method with parameters.\n * @param method - method name.\n * @param params - method parameters.\n * @param options - posting options.\n * @throws {SDKError} ERR_UNKNOWN_ENV\n * @see ERR_UNKNOWN_ENV\n */\nexport function postEvent<Method extends MiniAppsMethodWithRequiredParams>(\n method: Method,\n params: MiniAppsMethodParams<Method>,\n options?: PostEventOptions,\n): void;\n\nexport function postEvent(\n eventType: MiniAppsMethodName,\n paramsOrOptions?: MiniAppsMethodParams<MiniAppsMethodName> | PostEventOptions,\n options?: PostEventOptions,\n): void {\n let postOptions: PostEventOptions = {};\n let eventData: any;\n\n if (paramsOrOptions === undefined && options === undefined) {\n // Parameters and options were not passed.\n postOptions = {};\n } else if (paramsOrOptions !== undefined && options !== undefined) {\n // Both parameters and options passed.\n postOptions = options;\n eventData = paramsOrOptions;\n } else if (paramsOrOptions !== undefined) {\n // Only parameters were passed.\n if ('targetOrigin' in paramsOrOptions) {\n postOptions = paramsOrOptions;\n } else {\n eventData = paramsOrOptions;\n }\n }\n const { targetOrigin = targetOriginFn() } = postOptions;\n\n log('Posting event:', eventData\n ? { event: eventType, data: eventData }\n : { event: eventType });\n\n // Telegram Web.\n if (isIframe()) {\n window.parent.postMessage(JSON.stringify({ eventType, eventData }), targetOrigin);\n return;\n }\n\n // Telegram for Windows Phone or Android.\n if (hasExternalNotify(window)) {\n window.external.notify(JSON.stringify({ eventType, eventData }));\n return;\n }\n\n // Telegram for iOS and macOS.\n if (hasWebviewProxy(window)) {\n window.TelegramWebviewProxy.postEvent(eventType, JSON.stringify(eventData));\n return;\n }\n\n // Otherwise current environment is unknown, and we are not able to send event.\n throw createError(\n ERR_UNKNOWN_ENV,\n 'Unable to determine current environment and possible way to send event. You are probably trying to use Mini Apps method outside of Telegram application environment.',\n );\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_METHOD_PARAMETER_UNSUPPORTED, ERR_METHOD_UNSUPPORTED } from '@/errors/errors.js';\nimport { isRecord } from '@/misc/isRecord.js';\nimport { supports } from '@/supports/supports.js';\nimport type { Version } from '@/version/types.js';\n\nimport { type PostEvent, postEvent } from './postEvent.js';\n\n/**\n * Creates function which checks if specified method and parameters are supported. In case,\n * method or parameters are unsupported, an error will be thrown.\n * @param version - Telegram Mini Apps version.\n * @throws {SDKError} ERR_METHOD_UNSUPPORTED\n * @throws {SDKError} ERR_METHOD_PARAMETER_UNSUPPORTED\n * @see ERR_METHOD_UNSUPPORTED\n * @see ERR_METHOD_PARAMETER_UNSUPPORTED\n */\nexport function createPostEvent(version: Version): PostEvent {\n return (method: any, params: any) => {\n // Firstly, check if method itself is supported.\n if (!supports(method, version)) {\n throw createError(ERR_METHOD_UNSUPPORTED, `Method \"${method}\" is unsupported in Mini Apps version ${version}`);\n }\n\n // Method could use parameters, which are supported only in specific versions of Telegram\n // Mini Apps.\n if (isRecord(params)) {\n let validateParam: string | undefined;\n\n if (method === 'web_app_open_link' && 'try_instant_view' in params) {\n validateParam = 'try_instant_view';\n } else if (method === 'web_app_set_header_color' && 'color' in params) {\n validateParam = 'color';\n }\n\n if (validateParam && !supports(method, validateParam, version)) {\n throw createError(\n ERR_METHOD_PARAMETER_UNSUPPORTED,\n `Parameter \"${validateParam}\" of \"${method}\" method is unsupported in Mini Apps version ${version}`,\n );\n }\n }\n\n return postEvent(method, params);\n };\n}\n","type CaptureSameReqFn = (payload: { req_id: string }) => boolean;\n\n/**\n * Returns a function which can be used in `request` function `capture` property to capture\n * the event with the same request identifier.\n * @param reqId - request identifier.\n */\nexport function captureSameReq(reqId: string): CaptureSameReqFn {\n return ({ req_id }) => req_id === reqId;\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_TIMED_OUT } from '@/errors/errors.js';\nimport type { SDKError } from '@/errors/SDKError.js';\n\n/**\n * Creates new timeout error.\n * @param timeout - timeout in ms.\n */\nexport function createTimeoutError(timeout: number): SDKError {\n return createError(ERR_TIMED_OUT, `Timeout reached: ${timeout}ms`);\n}\n","import { createTimeoutError } from '@/timeout/createTimeoutError.js';\n\n/**\n * Runs passed function or promise with specified deadline presented via timeout argument.\n * @param funcOrPromise - function to execute or pending promise.\n * @param timeout - completion timeout.\n */\nexport function withTimeout<T>(\n funcOrPromise: Promise<T> | (() => Promise<T>),\n timeout: number,\n): Promise<T> {\n return Promise.race([\n typeof funcOrPromise === 'function' ? funcOrPromise() : funcOrPromise,\n new Promise<never>((_, rej) => {\n setTimeout(() => {\n rej(createTimeoutError(timeout));\n }, timeout);\n }),\n ]);\n}\n","import { withTimeout } from '@/timeout/withTimeout.js';\nimport type { ExecuteWithOptions, If, IsNever } from '@/types/index.js';\n\nimport { on } from '../events/listening/on.js';\nimport { postEvent as defaultPostEvent } from '../methods/postEvent.js';\nimport type {\n MiniAppsEventListener,\n MiniAppsEventName,\n MiniAppsEventPayload,\n} from '../events/types.js';\nimport type { MiniAppsMethodName, MiniAppsMethodParams } from '../methods/types/index.js';\n\ninterface BasicOptions<Method extends MiniAppsMethodName, Event extends MiniAppsEventName>\n extends ExecuteWithOptions {\n /**\n * Mini Apps method name.\n */\n method: Method;\n /**\n * One or many tracked Mini Apps events.\n */\n event: Event | Event[];\n /**\n * Should return true in case, this event should be captured. If not specified,\n * request will be captured automatically.\n */\n capture?: If<\n IsNever<MiniAppsEventListener<Event>>,\n () => boolean,\n (payload: MiniAppsEventPayload<Event>) => boolean\n >;\n}\n\n/**\n * `request` method options.\n */\nexport type RequestOptions<Method extends MiniAppsMethodName, Event extends MiniAppsEventName> =\n & BasicOptions<Method, Event>\n & If<IsNever<MiniAppsMethodParams<Method>>, {}, {\n /**\n * List of method parameters.\n */\n params: MiniAppsMethodParams<Method>\n}>;\n\n/**\n * Calls specified Mini Apps method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param options - method options.\n */\nexport async function request<Method extends MiniAppsMethodName, Event extends MiniAppsEventName>(\n options: RequestOptions<Method, Event>,\n): Promise<MiniAppsEventPayload<Event>> {\n let resolve: (payload: MiniAppsEventPayload<Event>) => void;\n const promise = new Promise<MiniAppsEventPayload<Event>>((res) => {\n resolve = res;\n });\n\n const {\n method,\n event,\n capture,\n postEvent = defaultPostEvent,\n timeout,\n } = options;\n\n const stoppers = (Array.isArray(event) ? event : [event]).map(\n (ev) => on(ev, (payload: any) => {\n return (!capture || capture(payload)) && resolve(payload);\n }),\n );\n\n try {\n postEvent(method as any, (options as any).params);\n return await (timeout ? withTimeout(promise, timeout) : promise);\n } finally {\n // After promise execution was completed, don't forget to remove all the listeners.\n stoppers.forEach((stop) => stop());\n }\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_INVOKE_CUSTOM_METHOD_RESPONSE } from '@/errors/errors.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nimport { captureSameReq } from './captureSameReq.js';\nimport { request } from './request.js';\nimport type { CustomMethodName, CustomMethodParams } from '../methods/types/custom-methods.js';\n\n/**\n * Invokes known custom method. Returns method execution result.\n * @param method - method name.\n * @param params - method parameters.\n * @param requestId - request identifier.\n * @param options - additional options.\n * @throws {SDKError} ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n * @see ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n */\nexport async function invokeCustomMethod<M extends CustomMethodName>(\n method: M,\n params: CustomMethodParams<M>,\n requestId: string,\n options?: ExecuteWithOptions,\n): Promise<unknown>;\n\n/**\n * Invokes unknown custom method. Returns method execution result.\n * @param method - method name.\n * @param params - method parameters.\n * @param requestId - request identifier.\n * @param options - additional options.\n * @throws {SDKError} ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n * @see ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n */\nexport function invokeCustomMethod(\n method: string,\n params: object,\n requestId: string,\n options?: ExecuteWithOptions,\n): Promise<unknown>;\n\nexport async function invokeCustomMethod(\n method: string,\n params: object,\n requestId: string,\n options: ExecuteWithOptions = {},\n): Promise<unknown> {\n const {\n result,\n error,\n } = await request({\n ...options,\n method: 'web_app_invoke_custom_method',\n event: 'custom_method_invoked',\n params: {\n method,\n params,\n req_id: requestId,\n },\n capture: captureSameReq(requestId),\n });\n\n if (error) {\n throw createError(ERR_INVOKE_CUSTOM_METHOD_RESPONSE, error);\n }\n\n return result;\n}\n","import { isRecord } from '@/misc/isRecord.js';\n\n/**\n * Function which joins passed values with space following these rules:\n * 1. If value is non-empty string, it will be added to output.\n * 2. If value is object, only those keys will be added, which values are truthy.\n * 3. If value is array, classNames will be called with this value spread.\n * 4. All other values are ignored.\n *\n * You can find this function to similar one from the package {@link https://www.npmjs.com/package/classnames|classnames}.\n * @param values - values array.\n * @returns Final class name.\n */\nexport function classNames(...values: any[]): string {\n return values\n // eslint-disable-next-line array-callback-return\n .map((value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (isRecord(value)) {\n return classNames(Object.entries(value).map((entry) => entry[1] && entry[0]));\n }\n\n if (Array.isArray(value)) {\n return classNames(...value);\n }\n })\n .filter(Boolean)\n .join(' ');\n}\n","import { isRecord } from '@/misc/isRecord.js';\nimport type { UnionOptionalKeys, UnionRequiredKeys } from '@/types/unions.js';\n\nimport { classNames } from './classNames.js';\n\nexport type MergeClassNames<Tuple extends any[]> =\n // Removes all types from union which will be ignored by the mergeClassNames function.\n Exclude<Tuple[number], number | string | null | undefined | any[] | boolean> extends infer Union\n ? {\n [K in UnionRequiredKeys<Union>]: string;\n } & {\n [K in UnionOptionalKeys<Union>]?: string;\n }\n : never;\n\n/**\n * Merges 2 sets of parameters. Function expects passing an array of objects with values, which\n * could be passed to `classNames` function. As the result, it returns an object with keys\n * from all objects with merged values.\n * @see classNames\n */\nexport function mergeClassNames<T extends any[]>(...partials: T): MergeClassNames<T> {\n return partials.reduce<MergeClassNames<T>>((acc, partial) => {\n if (!isRecord(partial)) {\n return acc;\n }\n\n Object.entries(partial).forEach(([key, value]) => {\n const className = classNames((acc as any)[key], value);\n\n if (className.length) {\n (acc as any)[key] = className;\n }\n });\n\n return acc;\n }, {} as MergeClassNames<T>);\n}\n","import { toRGB } from './toRGB.js';\n\n/**\n * Returns true in case, the color is recognized as dark.\n * @param color - color in any format acceptable by toRGB function.\n * @see toRGB\n */\nexport function isColorDark(color: string): boolean {\n // Convert color to RGB.\n const rgb = toRGB(color);\n\n // Real formula: hsp = Math.sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b)\n // See: https://stackoverflow.com/a/596243\n return Math.sqrt(\n [0.299, 0.587, 0.114].reduce<number>((acc, modifier, idx) => {\n // Extract part of #RRGGBB pattern and convert it to DEC.\n const dec = parseInt(rgb.slice(1 + idx * 2, 1 + (idx + 1) * 2), 16);\n return acc + dec * dec * modifier;\n }, 0),\n ) < 120;\n}\n","import { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport type { StateEvents } from '@/classes/State/types.js';\nimport type { StringKeys } from '@/types/utils.js';\n\ntype Emitter<State extends object> = EventEmitter<StateEvents<State>>;\n\nexport class State<State extends object> {\n private readonly ee: Emitter<State> = new EventEmitter();\n\n constructor(\n /**\n * Initial state.\n */\n private readonly state: State,\n ) {\n }\n\n /**\n * Clones current state and returns its copy.\n */\n clone(): State {\n return { ...this.state };\n }\n\n /**\n * Sets value by key.\n * @param key - state key.\n * @param value - value to set.\n */\n set<K extends StringKeys<State>>(key: K, value: State[K]): void;\n /**\n * Sets several values simultaneously.\n * @param state - partial state.\n */\n set(state: Partial<State>): void;\n set(keyOrState: StringKeys<State> | Partial<State>, keyValue?: State[keyof State]): void {\n const didChange = Object\n .entries(typeof keyOrState === 'string' ? { [keyOrState]: keyValue } : keyOrState)\n .reduce((acc, [key, value]) => {\n // If value is the same or missing at all, we skip it.\n if (this.state[key as keyof State] === value || value === undefined) {\n return acc;\n }\n\n // Otherwise set new value and emit change event.\n this.state[key as keyof State] = value;\n (this.ee as any).emit(`change:${key}`, value);\n\n return true;\n }, false);\n\n if (didChange) {\n (this.ee as any).emit('change', this.state);\n }\n }\n\n /**\n * Returns value by specified key.\n * @param key - state key.\n */\n get<K extends StringKeys<State>>(key: K): State[K] {\n return this.state[key];\n }\n\n /**\n * Adds new event listener.\n */\n on: Emitter<State>['on'] = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off: Emitter<State>['off'] = this.ee.off.bind(this.ee);\n}\n","import { State } from '@/classes/State/State.js';\n\nexport class WithStateUtils<Shape extends object> {\n protected state: State<Shape>;\n\n constructor(shape: Shape) {\n this.state = new State(shape);\n this.set = this.state.set.bind(this.state);\n this.get = this.state.get.bind(this.state);\n this.clone = this.state.clone.bind(this.state);\n }\n\n /**\n * Gets the state value.\n */\n protected get: State<Shape>['get'];\n\n /**\n * Sets the state value.\n */\n protected set: State<Shape>['set'];\n\n /**\n * Clones the current state.\n */\n protected clone: State<Shape>['clone'];\n}\n","import { supports } from '@/supports/supports.js';\nimport type { MiniAppsMethodName } from '@/bridge/methods/types/methods.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\nexport type SupportsSchema<Method extends string> = Record<Method, MiniAppsMethodName>;\n\n/**\n * Returns function, which accepts predefined method name and checks if it is supported\n * via passed schema and version.\n * @param schema - object which contains methods names and TWA method as a dependency.\n * @param version - platform version.\n */\nexport function createSupportsFn<Method extends string>(\n version: Version,\n schema: SupportsSchema<Method>,\n): SupportsFn<Method> {\n return (method) => supports(schema[method], version);\n}\n","import { WithStateUtils } from '@/classes/WithStateUtils.js';\nimport { createSupportsFn } from '@/supports/createSupportsFn.js';\nimport type { MiniAppsMethodName } from '@/bridge/methods/types/methods.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\nexport class WithSupportsAndStateUtils<StateShape extends object, SupportsMethod extends string>\nextends WithStateUtils<StateShape> {\n constructor(\n /**\n * Initial state.\n */\n stateShape: StateShape,\n /**\n * Mini Apps version.\n */\n version: Version,\n /**\n * Supports method schema.\n */\n supportsSchema: Record<SupportsMethod, MiniAppsMethodName>,\n ) {\n super(stateShape);\n this.supports = createSupportsFn(version, supportsSchema);\n }\n\n /**\n * @returns True, if specified method is supported by the current component.\n */\n supports: SupportsFn<SupportsMethod>;\n}\n","import { off } from '@/bridge/events/listening/off.js';\nimport { on } from '@/bridge/events/listening/on.js';\nimport { WithSupportsAndStateUtils } from '@/classes/WithSupportsAndStateUtils.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { BackButtonEvents, BackButtonState } from '@/components/BackButton/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport type { Version } from '@/version/types.js';\n\ntype Emitter = EventEmitter<BackButtonEvents>;\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/back-button\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/back-button\n */\nexport class BackButton extends WithSupportsAndStateUtils<BackButtonState, 'show' | 'hide'> {\n constructor(isVisible: boolean, version: Version, private readonly postEvent: PostEvent) {\n super({ isVisible }, version, {\n show: 'web_app_setup_back_button',\n hide: 'web_app_setup_back_button',\n });\n }\n\n private set isVisible(visible: boolean) {\n this.set('isVisible', visible);\n this.postEvent('web_app_setup_back_button', { is_visible: visible });\n }\n\n /**\n * True if BackButton is currently visible.\n */\n get isVisible(): boolean {\n return this.get('isVisible');\n }\n\n /**\n * Hides the BackButton.\n */\n hide(): void {\n this.isVisible = false;\n }\n\n /**\n * Adds a new event listener.\n * @param event - event to listen.\n * @param listener - listener to add.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('back_button_pressed', listener)\n : this.state.on(event, listener as any)\n );\n\n /**\n * Removes the event listener.\n * @param event - event to listen.\n * @param listener - listener to remove.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('back_button_pressed', listener)\n : this.state.off(event, listener as any)\n );\n\n /**\n * Shows the BackButton.\n */\n show(): void {\n this.isVisible = true;\n }\n}\n","import { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { number } from './number.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as Date.\n */\nexport const date: ValueParserGenerator<Date> = createValueParserGenerator((value) => (\n value instanceof Date\n ? value\n : new Date(number().parse(value) * 1000)\n), 'Date');\n","import { createTypeError } from '../createTypeError.js';\nimport { parseBySchema } from '../parseBySchema.js';\nimport { ValueParser } from '../ValueParser/ValueParser.js';\nimport type { Schema } from '../types.js';\n\n/**\n * Creates new search params parser according to passed schema.\n * @param schema - object schema.\n * @param type - parser type name.\n */\nexport function searchParams<T>(schema: Schema<T>, type?: string): ValueParser<T, false> {\n return new ValueParser((value) => {\n if (typeof value !== 'string' && !(value instanceof URLSearchParams)) {\n throw createTypeError();\n }\n\n const params = typeof value === 'string' ? new URLSearchParams(value) : value;\n\n return parseBySchema(schema, (field) => {\n const paramValue = params.get(field);\n return paramValue === null ? undefined : paramValue;\n });\n }, false, type);\n}\n","import { json } from '@/parsing/parsers/json.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { string } from '@/parsing/parsers/string.js';\n\nimport type { Chat } from '../types.js';\n\nexport const chat = json<Chat>({\n id: number(),\n type: string(),\n title: string(),\n photoUrl: {\n type: string().optional(),\n from: 'photo_url',\n },\n username: string().optional(),\n}, 'Chat')\n .optional();\n","import { boolean } from '@/parsing/parsers/boolean.js';\nimport { json } from '@/parsing/parsers/json.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { string } from '@/parsing/parsers/string.js';\n\nimport type { User } from '../types.js';\n\nexport const user = json<User>({\n addedToAttachmentMenu: {\n type: boolean().optional(),\n from: 'added_to_attachment_menu',\n },\n allowsWriteToPm: {\n type: boolean().optional(),\n from: 'allows_write_to_pm',\n },\n firstName: {\n type: string(),\n from: 'first_name',\n },\n id: number(),\n isBot: {\n type: boolean().optional(),\n from: 'is_bot',\n },\n isPremium: {\n type: boolean().optional(),\n from: 'is_premium',\n },\n languageCode: {\n type: string().optional(),\n from: 'language_code',\n },\n lastName: {\n type: string().optional(),\n from: 'last_name',\n },\n photoUrl: {\n type: string().optional(),\n from: 'photo_url',\n },\n username: string().optional(),\n}, 'User')\n .optional();\n","import { date } from '@/parsing/parsers/date.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { searchParams } from '@/parsing/parsers/searchParams.js';\nimport { string } from '@/parsing/parsers/string.js';\nimport type { ValueParser } from '@/parsing/ValueParser/ValueParser.js';\n\nimport { chat } from './chat.js';\nimport { user } from './user.js';\nimport type { InitDataParsed } from '../types.js';\n\n/**\n * Returns parser used to parse init data, presented as search params.\n */\nexport function initData(): ValueParser<InitDataParsed, false> {\n return searchParams<InitDataParsed>({\n authDate: {\n type: date(),\n from: 'auth_date',\n },\n canSendAfter: {\n type: number().optional(),\n from: 'can_send_after',\n },\n chat,\n chatInstance: {\n type: string().optional(),\n from: 'chat_instance',\n },\n chatType: {\n type: string().optional(),\n from: 'chat_type',\n },\n hash: string(),\n queryId: {\n type: string().optional(),\n from: 'query_id',\n },\n receiver: user,\n startParam: {\n type: string().optional(),\n from: 'start_param',\n },\n user,\n }, 'InitData');\n}\n","/**\n * Converts a palette key from the Telegram application to the representation used by the package.\n * @param key - palette key.\n */\nexport function keyToLocal(key: string): string {\n return key.replace(/_[a-z]/g, (match) => match[1].toUpperCase());\n}\n\n/**\n * Converts palette key from the local representation to the representation sent from the\n * Telegram application.\n * @param key - palette key.\n */\nexport function keyToExternal(key: string): string {\n return key.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);\n}\n","import { createValueParserGenerator, type ValueParserGenerator } from '@/parsing/createValueParserGenerator.js';\nimport { rgb } from '@/parsing/parsers/rgb.js';\nimport { toRecord } from '@/parsing/toRecord.js';\n\nimport { keyToLocal } from '../keys.js';\nimport type { ThemeParamsParsed } from '../types.js';\n\nexport const themeParams: ValueParserGenerator<ThemeParamsParsed> = createValueParserGenerator(\n (value) => {\n const rgbOptional = rgb().optional();\n\n return Object\n .entries(toRecord(value))\n .reduce<ThemeParamsParsed>((acc, [k, v]) => {\n acc[keyToLocal(k)] = rgbOptional.parse(v);\n return acc;\n }, {});\n },\n 'ThemeParams',\n);\n","import { initData } from '@/components/InitData/parsers/initData.js';\nimport { themeParams } from '@/components/ThemeParams/parsing/themeParams.js';\nimport { boolean } from '@/parsing/parsers/boolean.js';\nimport { searchParams } from '@/parsing/parsers/searchParams.js';\nimport { string } from '@/parsing/parsers/string.js';\n\nimport type { LaunchParams } from './types.js';\n\n/**\n * Parses value as launch parameters.\n * @param value - value to parse.\n */\nexport function parseLaunchParams(value: unknown): LaunchParams {\n return searchParams({\n botInline: {\n type: boolean().optional(),\n from: 'tgWebAppBotInline',\n },\n initData: {\n type: initData().optional(),\n from: 'tgWebAppData',\n },\n initDataRaw: {\n type: string().optional(),\n from: 'tgWebAppData',\n },\n platform: {\n type: string(),\n from: 'tgWebAppPlatform',\n },\n showSettings: {\n type: boolean().optional(),\n from: 'tgWebAppShowSettings',\n },\n startParam: {\n type: string().optional(),\n from: 'tgWebAppStartParam',\n },\n themeParams: {\n type: themeParams(),\n from: 'tgWebAppThemeParams',\n },\n version: {\n type: string(),\n from: 'tgWebAppVersion',\n },\n }).parse(value);\n}\n","import { parseLaunchParams } from './parseLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * @param urlString - URL to extract launch parameters from.\n * @returns Launch parameters from the specified URL.\n * @throws Error if function was unable to extract launch parameters from the passed URL.\n */\nexport function retrieveFromUrl(urlString: string): LaunchParams {\n return parseLaunchParams(\n urlString\n // Replace everything before this first hashtag or question sign.\n .replace(/^[^?#]*[?#]/, '')\n // Replace all hashtags and question signs to make it look like some search params.\n .replace(/[?#]/g, '&'),\n );\n}\n","import { retrieveFromUrl } from './retrieveFromUrl.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * @returns Launch parameters from the current window location hash.\n * @throws Error if function was unable to extract launch parameters from the window location hash.\n */\nexport function retrieveFromLocation(): LaunchParams {\n return retrieveFromUrl(window.location.href);\n}\n","/**\n * Returns the first navigation entry from window.performance.\n * @returns First navigation entry or null, in case performance functionality is not supported\n * or navigation entry was not found.\n */\nexport function getFirstNavigationEntry(): PerformanceNavigationTiming | undefined {\n return performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming | undefined;\n}\n","import { getFirstNavigationEntry } from '@/navigation/getFirstNavigationEntry.js';\n\nimport { retrieveFromUrl } from './retrieveFromUrl.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * @returns Launch parameters based on the first navigation entry.\n * @throws Error if function was unable to extract launch parameters from the navigation entry.\n */\nexport function retrieveFromPerformance(): LaunchParams {\n const navigationEntry = getFirstNavigationEntry();\n if (!navigationEntry) {\n throw new Error('Unable to get first navigation entry.');\n }\n\n return retrieveFromUrl(navigationEntry.name);\n}\n","import type { BackButtonState } from '@/components/BackButton/types.js';\nimport type { BiometryManagerState } from '@/components/BiometryManager/types.js';\nimport type { ClosingBehaviorState } from '@/components/ClosingBehavior/types.js';\nimport type { MainButtonState } from '@/components/MainButton/types.js';\nimport type { MiniAppState } from '@/components/MiniApp/types.js';\nimport type { SettingsButtonState } from '@/components/SettingsButton/types.js';\nimport type { ThemeParamsParsed } from '@/components/ThemeParams/types.js';\nimport type { ViewportState } from '@/components/Viewport/types.js';\n\n/**\n * Describes storage keys and according values.\n */\nexport interface StorageParams {\n backButton: BackButtonState;\n biometryManager: BiometryManagerState;\n closingBehavior: ClosingBehaviorState;\n launchParams: string;\n mainButton: MainButtonState;\n miniApp: MiniAppState;\n settingsButton: SettingsButtonState;\n themeParams: ThemeParamsParsed;\n viewport: ViewportState;\n}\n\n/**\n * Key which could be used to store data in the storage.\n */\nexport type StorageKey = keyof StorageParams;\n\n/**\n * Type specific to the specified storage key.\n */\nexport type StorageValue<K extends StorageKey> = StorageParams[K];\n\n/**\n * Converts passed storage key to the formatted state.\n * @param key - storage key.\n */\nfunction formatKey(key: StorageKey): string {\n return `tma.js/${key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)}`;\n}\n\n/**\n * Saves value in the storage.\n * @param key - storage key.\n * @param value - storage value.\n */\nexport function setStorageValue<K extends StorageKey>(key: K, value: StorageValue<K>): void {\n sessionStorage.setItem(formatKey(key), JSON.stringify(value));\n}\n\n/**\n * Extracts value from the storage.\n * @param key - storage key.\n */\nexport function getStorageValue<K extends StorageKey>(key: K): StorageValue<K> | undefined {\n const value = sessionStorage.getItem(formatKey(key));\n try {\n return value ? JSON.parse(value) : undefined;\n } catch { /* empty */ }\n}\n","import { parseLaunchParams } from '@/launch-params/parseLaunchParams.js';\nimport { getStorageValue } from '@/storage/storage.js';\nimport type { LaunchParams } from '@/launch-params/types.js';\n\n/**\n * @returns Launch parameters stored in the session storage.\n * @throws Error if function was unable to extract launch parameters from the window location hash.\n */\nexport function retrieveFromStorage(): LaunchParams {\n return parseLaunchParams(getStorageValue('launchParams') || '');\n}\n","import { keyToExternal } from '../keys.js';\nimport type { ThemeParamsParsed } from '../types.js';\n\n/**\n * Serializes theme parameters to representation sent from the Telegram application.\n */\nexport function serializeThemeParams(themeParams: ThemeParamsParsed): string {\n return JSON.stringify(\n Object.fromEntries(\n Object\n .entries(themeParams)\n .map(([key, value]) => [keyToExternal(key), value]),\n ),\n );\n}\n","import { serializeThemeParams } from '@/components/ThemeParams/parsing/serializeThemeParams.js';\n\nimport type { LaunchParams } from './types.js';\n\n/**\n * Converts launch parameters to its initial representation.\n * @param value - launch parameters.\n */\nexport function serializeLaunchParams(value: LaunchParams): string {\n const {\n initDataRaw,\n themeParams,\n platform,\n version,\n showSettings,\n startParam,\n botInline,\n } = value;\n\n const params = new URLSearchParams();\n\n params.set('tgWebAppPlatform', platform);\n params.set('tgWebAppThemeParams', serializeThemeParams(themeParams));\n params.set('tgWebAppVersion', version);\n\n if (initDataRaw) {\n params.set('tgWebAppData', initDataRaw);\n }\n\n if (startParam) {\n params.set('tgWebAppStartParam', startParam);\n }\n\n if (typeof showSettings === 'boolean') {\n params.set('tgWebAppShowSettings', showSettings ? '1' : '0');\n }\n\n if (typeof botInline === 'boolean') {\n params.set('tgWebAppBotInline', botInline ? '1' : '0');\n }\n\n return params.toString();\n}\n","import { setStorageValue } from '@/storage/storage.js';\n\nimport { serializeLaunchParams } from './serializeLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * Saves specified launch parameters in the session storage.\n * @param value - launch params to save.\n */\nexport function saveToStorage(value: LaunchParams): void {\n setStorageValue('launchParams', serializeLaunchParams(value));\n}\n","import { retrieveFromLocation } from './retrieveFromLocation.js';\nimport { retrieveFromPerformance } from './retrieveFromPerformance.js';\nimport { retrieveFromStorage } from './retrieveFromStorage.js';\nimport { saveToStorage } from './saveToStorage.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * @returns Launch parameters from any known source.\n * @throws Error if extraction was unsuccessful.\n */\nexport function retrieveLaunchParams(): LaunchParams {\n const errors: unknown[] = [];\n\n // eslint-disable-next-line no-restricted-syntax\n for (const retrieve of [\n // Try to retrieve launch parameters from the current location. This method can return\n // nothing in case, location was changed and then page was reloaded.\n retrieveFromLocation,\n // Then, try using the lower level API - window.performance.\n retrieveFromPerformance,\n // Finally, try to extract launch parameters from the session storage.\n retrieveFromStorage,\n ]) {\n try {\n const lp = retrieve();\n saveToStorage(lp);\n return lp;\n } catch (e) {\n errors.push(e);\n }\n }\n\n throw new Error('Unable to retrieve launch parameters from any known source.');\n}\n","import { getFirstNavigationEntry } from './getFirstNavigationEntry.js';\n\n/**\n * @returns True, if current page was reloaded.\n * @see https://stackoverflow.com/a/36444134/11894710\n */\nexport function isPageReload(): boolean {\n const entry = getFirstNavigationEntry();\n return !!(entry && entry.type === 'reload');\n}\n","import type { CreateRequestIdFn } from './types.js';\n\n/**\n * Creates function which generated request identifiers.\n */\nexport function createRequestIdGenerator(): CreateRequestIdFn {\n let requestId = 0;\n return () => (requestId += 1).toString();\n}\n","import { createPostEvent } from '@/bridge/methods/createPostEvent.js';\nimport { retrieveLaunchParams } from '@/launch-params/retrieveLaunchParams.js';\nimport { createSingleton } from '@/misc/createSingleton.js';\nimport { isPageReload } from '@/navigation/isPageReload.js';\nimport { createRequestIdGenerator } from '@/request-id/createRequestIdGenerator.js';\nimport type { StorageKey, StorageValue } from '@/storage/storage.js';\nimport { getStorageValue, setStorageValue } from '@/storage/storage.js';\nimport { createCleanup } from '@/misc/createCleanup.js';\n\nimport {\n FactoryDynamic,\n FactoryStatic,\n InitStaticComponentFn,\n InitDynamicComponentFn,\n WithOnChange,\n} from './types.js';\n\nconst [createReqId] = createSingleton(createRequestIdGenerator);\n\n/**\n * Creates a new init function based on factory, creating a component, not synchronizing its\n * state with the session storage.\n * @param factory - function creating new component instance.\n */\nexport function createComponentInitFn<R>(factory: FactoryStatic<R>): InitStaticComponentFn<R>;\n\n/**\n * Creates a new init function based on factory, creating a component, synchronizing its\n * state with the session storage.\n * @param factory - function creating new component instance.\n * @param storageKey - storage key to restore component from.\n */\nexport function createComponentInitFn<\n SK extends StorageKey,\n R extends WithOnChange<StorageValue<SK>> | Promise<WithOnChange<StorageValue<SK>>>,\n>(\n storageKey: SK,\n factory: FactoryDynamic<R, SK>,\n): InitDynamicComponentFn<R>;\n\nexport function createComponentInitFn<\n R extends WithOnChange<StorageValue<SK>> | Promise<WithOnChange<StorageValue<SK>>>,\n SK extends StorageKey,\n>(\n factoryStaticOrSK: FactoryStatic<R> | SK,\n factoryDynamic?: FactoryDynamic<R, SK>,\n): InitStaticComponentFn<R> | InitDynamicComponentFn<R> {\n return () => {\n const lp = retrieveLaunchParams();\n const factoryOptions = {\n ...lp,\n postEvent: createPostEvent(lp.version),\n createRequestId: createReqId(),\n };\n\n // In static init mode we have no reason to use the storage to restore the state. In this\n // case we should just call the factory.\n if (typeof factoryStaticOrSK === 'function') {\n return factoryStaticOrSK(factoryOptions);\n }\n\n // Otherwise, we create a new component instance from the storage if possible and add\n // required change listeners.\n const [addCleanup, cleanup, cleanedUp] = createCleanup();\n\n const result = factoryDynamic!({\n ...factoryOptions,\n // State should only be passed only in case, current page was reloaded. If we don't add\n // this check, state restoration will work improperly in the web version of Telegram,\n // when we are always working in the same \"session\" (tab).\n state: isPageReload() ? getStorageValue(factoryStaticOrSK) : undefined,\n addCleanup,\n });\n\n const bindChange = (value: WithOnChange<StorageValue<SK>>) => {\n if (!cleanedUp) {\n addCleanup(\n value.on('change', (state) => {\n setStorageValue(factoryStaticOrSK, state);\n }),\n );\n }\n return value;\n };\n\n return [\n result instanceof Promise ? result.then(bindChange) : bindChange(result),\n cleanup,\n ] as unknown as R;\n };\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { BackButton } from './BackButton.js';\n\n/**\n * @returns A new initialized instance of the `BackButton` class.\n * @see BackButton\n */\nexport const initBackButton = createComponentInitFn('backButton', ({\n postEvent,\n version,\n state = { isVisible: false },\n}) => new BackButton(state.isVisible, version, postEvent));\n","import { WithSupportsAndStateUtils } from '@/classes/WithSupportsAndStateUtils.js';\nimport type { StateEvents } from '@/classes/State/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\n\ntype Emitter<StateShape extends object> = EventEmitter<StateEvents<StateShape>>;\n\nexport class WithSupportsAndTrackableState<StateShape extends object, SupportsMethod extends string>\n extends WithSupportsAndStateUtils<StateShape, SupportsMethod> {\n /**\n * Adds a new event listener.\n */\n on: Emitter<StateShape>['on'] = this.state.on.bind(this.state);\n\n /**\n * Removes the event listener.\n */\n off: Emitter<StateShape>['off'] = this.state.off.bind(this.state);\n}\n","import type { BiometryType, MiniAppsEventPayload } from '@/bridge/events/types.js';\n\nexport interface FormatBiometryInfoResult {\n /**\n * Shows whether biometry is available.\n */\n available: boolean;\n /**\n * Shows whether permission to use biometrics has been requested.\n */\n accessRequested: boolean;\n /**\n * Shows whether permission to use biometrics has been granted.\n */\n accessGranted: boolean;\n /**\n * A unique device identifier that can be used to match the token to the device.\n */\n deviceId: string;\n /**\n * Show whether local storage contains previously saved token.\n */\n tokenSaved: boolean;\n /**\n * The type of biometrics currently available on the device.\n */\n type: BiometryType;\n}\n\n/**\n * Converts `biometry_info_received` to some common shape.\n * @param event - event payload.\n * @see biometry_info_received\n */\nexport function formatEvent(\n event: MiniAppsEventPayload<'biometry_info_received'>,\n): FormatBiometryInfoResult {\n const data = event.available ? event : {\n available: false,\n device_id: '',\n token_saved: false,\n access_requested: false,\n access_granted: false,\n type: '',\n };\n\n return {\n available: true,\n type: data.type,\n deviceId: data.device_id,\n tokenSaved: data.token_saved,\n accessRequested: data.access_requested,\n accessGranted: data.access_granted,\n };\n}\n","import { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport { formatEvent } from '@/components/BiometryManager/formatEvent.js';\nimport type { BiometryType } from '@/bridge/events/types.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type {\n BiometryManagerAuthenticateOptions,\n BiometryManagerProps,\n BiometryManagerRequestAccessOptions,\n BiometryManagerState,\n BiometryManagerUpdateTokenOptions,\n} from '@/components/BiometryManager/types.js';\n\nexport class BiometryManager extends WithSupportsAndTrackableState<BiometryManagerState,\n | 'auth'\n | 'openSettings'\n | 'requestAccess'\n | 'updateToken'\n> {\n private readonly postEvent: PostEvent;\n\n private authPromise?: Promise<string | undefined>;\n\n private accessPromise?: Promise<boolean>;\n\n constructor({ postEvent, version, ...rest }: BiometryManagerProps) {\n super(rest, version, {\n auth: 'web_app_biometry_request_auth',\n openSettings: 'web_app_biometry_open_settings',\n requestAccess: 'web_app_biometry_request_access',\n updateToken: 'web_app_biometry_update_token',\n });\n this.postEvent = postEvent;\n }\n\n /**\n * Shows whether biometry is available.\n */\n get available(): boolean {\n return this.get('available');\n }\n\n /**\n * Shows whether permission to use biometrics has been granted.\n */\n get accessGranted(): boolean {\n return this.get('accessGranted');\n }\n\n /**\n * Shows whether if permission to use biometrics has been requested.\n */\n get accessRequested(): boolean {\n return this.get('accessRequested');\n }\n\n /**\n * Authenticates the user using biometrics.\n * @param options - method options.\n * @since 7.2\n * @returns Token from the local secure storage, if authentication was successful.\n */\n async authenticate({\n reason,\n ...rest\n }: BiometryManagerAuthenticateOptions): Promise<string | undefined> {\n if (!this.authPromise) {\n this.authPromise = request({\n ...rest,\n method: 'web_app_biometry_request_auth',\n event: 'biometry_auth_requested',\n postEvent: this.postEvent,\n params: {\n // TODO: Check if reason is empty works fine.\n reason: (reason || '').trim(),\n },\n })\n .then(({ token }) => token)\n .finally(() => this.authPromise = undefined);\n }\n return this.authPromise;\n }\n\n /**\n * A unique device identifier that can be used to match the token to the device.\n */\n get deviceId(): string {\n return this.get('deviceId');\n }\n\n /**\n * Opens the biometric access settings for bots. Useful when you need to request biometrics\n * access to users who haven't granted it yet.\n *\n * _Note that this method can be called only in response to user interaction with the Mini App\n * interface (e.g. a click inside the Mini App or on the main button)_.\n * @since 7.2\n */\n openSettings(): void {\n this.postEvent('web_app_biometry_open_settings');\n }\n\n /**\n * Requests permission to use biometrics.\n * @since 7.2\n * @returns Promise with true, if access was granted.\n */\n requestAccess({ reason, ...rest }: BiometryManagerRequestAccessOptions = {}): Promise<boolean> {\n if (!this.accessPromise) {\n this.accessPromise = request({\n ...rest,\n postEvent: this.postEvent,\n method: 'web_app_biometry_request_access',\n event: 'biometry_info_received',\n params: { reason: reason || '' },\n })\n .then((response) => {\n // Actualize local state.\n const formatted = formatEvent(response);\n this.set(formatted);\n\n return formatted.accessGranted;\n })\n .finally(() => this.accessPromise = undefined);\n }\n return this.accessPromise;\n }\n\n /**\n * The type of biometrics currently available on the device.\n */\n get biometryType(): BiometryType | undefined {\n return this.get('biometryType');\n }\n\n /**\n * Shows whether token was saved previously in the local secure storage.\n */\n get tokenSaved(): boolean {\n return this.get('tokenSaved');\n }\n\n /**\n * Updates the biometric token in a secure storage on the device.\n * @returns Promise with `true`, if token was updated.\n */\n async updateToken({ token, ...rest }: BiometryManagerUpdateTokenOptions = {}): Promise<boolean> {\n return ['removed', 'updated'].includes(\n (\n await request({\n ...rest,\n postEvent: this.postEvent,\n method: 'web_app_biometry_update_token',\n event: 'biometry_token_updated',\n params: { token: token || '' },\n })\n ).status,\n );\n }\n}\n","import { request } from '@/bridge/utils/request.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nimport { formatEvent } from './formatEvent.js';\nimport type { FormatBiometryInfoResult } from './formatEvent.js';\n\n/**\n * Requests biometry information.\n * @param options - additional execution options.\n */\nexport async function requestBiometryInfo(\n options?: ExecuteWithOptions,\n): Promise<FormatBiometryInfoResult> {\n return formatEvent(\n await request({\n ...(options || {}),\n method: 'web_app_biometry_get_info',\n event: 'biometry_info_received',\n }),\n );\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\nimport { supports } from '@/supports/supports.js';\n\nimport { BiometryManager } from './BiometryManager.js';\nimport { requestBiometryInfo } from './requestBiometryInfo.js';\n\n/**\n * @returns A promise with a new initialized instance of the `BiometryManager` class.\n * @see BiometryManager\n */\nexport const initBiometryManager = createComponentInitFn(\n 'biometryManager',\n async ({ postEvent, version, state }) => {\n return new BiometryManager({\n ...(state || supports('web_app_biometry_get_info', version)\n ? state || await requestBiometryInfo({ timeout: 1000 })\n : {\n available: false,\n accessGranted: false,\n accessRequested: false,\n tokenSaved: false,\n deviceId: '',\n }),\n version,\n postEvent,\n });\n },\n);\n","import { WithStateUtils } from '@/classes/WithStateUtils.js';\nimport type { StateEvents } from '@/classes/State/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\n\ntype Emitter<StateShape extends object> = EventEmitter<StateEvents<StateShape>>;\n\nexport class WithTrackableState<StateShape extends object>\n extends WithStateUtils<StateShape> {\n /**\n * Adds a new event listener.\n */\n on: Emitter<StateShape>['on'] = this.state.on.bind(this.state);\n\n /**\n * Removes the event listener.\n */\n off: Emitter<StateShape>['off'] = this.state.off.bind(this.state);\n}\n","import { WithTrackableState } from '@/classes/WithTrackableState.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { ClosingBehaviorState } from '@/components/ClosingBehavior/types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/closing-behavior\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/closing-behavior\n */\nexport class ClosingBehavior extends WithTrackableState<ClosingBehaviorState> {\n constructor(isConfirmationNeeded: boolean, private readonly postEvent: PostEvent) {\n super({ isConfirmationNeeded });\n }\n\n private set isConfirmationNeeded(value: boolean) {\n this.set('isConfirmationNeeded', value);\n this.postEvent('web_app_setup_closing_behavior', { need_confirmation: value });\n }\n\n /**\n * True, if the confirmation dialog should be shown while the user is trying to close\n * the Mini App.\n */\n get isConfirmationNeeded(): boolean {\n return this.get('isConfirmationNeeded');\n }\n\n /**\n * Disables the confirmation dialog when closing the Mini App.\n */\n disableConfirmation(): void {\n this.isConfirmationNeeded = false;\n }\n\n /**\n * Enables the confirmation dialog when closing the Mini App.\n */\n enableConfirmation(): void {\n this.isConfirmationNeeded = true;\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { ClosingBehavior } from './ClosingBehavior.js';\n\n/**\n * @returns A new initialized instance of the `ClosingBehavior` class.\n * @see ClosingBehavior\n */\nexport const initClosingBehavior = createComponentInitFn(\n 'closingBehavior',\n ({\n postEvent,\n state = { isConfirmationNeeded: false },\n }) => new ClosingBehavior(state.isConfirmationNeeded, postEvent),\n);\n","import { createSupportsFn } from '@/supports/createSupportsFn.js';\nimport type { MiniAppsMethodName } from '@/bridge/methods/types/methods.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\nexport class WithSupports<SupportsMethod extends string> {\n constructor(\n /**\n * Mini Apps version.\n */\n version: Version,\n /**\n * Supports method schema.\n */\n supportsSchema: Record<SupportsMethod, MiniAppsMethodName>,\n ) {\n this.supports = createSupportsFn(version, supportsSchema);\n }\n\n /**\n * @returns True, if specified method is supported by the current component.\n */\n supports: SupportsFn<SupportsMethod>;\n}\n","import { createTypeError } from '../createTypeError.js';\nimport { ValueParser } from '../ValueParser/ValueParser.js';\nimport type { ArrayParserOfResult } from '../ArrayParser/types.js';\nimport type { AnyParser, Parser } from '../types.js';\nimport type { ValueParserParseResult } from '../ValueParser/types.js';\n\n/**\n * Parses incoming value as array.\n * @param value - value to parse.\n */\nfunction parseArray(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value;\n }\n\n if (typeof value === 'string') {\n try {\n const json = JSON.parse(value);\n\n if (Array.isArray(json)) {\n return json;\n }\n // eslint-disable-next-line no-empty\n } catch (e) {\n }\n }\n throw createTypeError();\n}\n\nexport class ArrayParser<ItemType, IsOptional extends boolean>\n extends ValueParser<unknown[], IsOptional> {\n private itemParser: Parser<any>;\n\n constructor(\n itemParser: AnyParser<ItemType>,\n isOptional: IsOptional,\n type?: string,\n ) {\n super(parseArray, isOptional, type);\n\n this.itemParser = typeof itemParser === 'function'\n ? itemParser\n : itemParser.parse.bind(itemParser);\n }\n\n /**\n * Attempts to parse passed value\n * @param value - value to parse.\n * @throws {SDKError} ERR_PARSE\n * @see ERR_PARSE\n */\n override parse(value: unknown): ValueParserParseResult<ItemType[], IsOptional> {\n const arr = super.parse(value);\n return arr === undefined ? arr : arr.map(this.itemParser);\n }\n\n of<Item>(itemParser: AnyParser<Item>): ArrayParserOfResult<this, Item, IsOptional> {\n this.itemParser = typeof itemParser === 'function'\n ? itemParser\n : itemParser.parse.bind(itemParser);\n\n return this as ArrayParserOfResult<this, Item, IsOptional>;\n }\n}\n","import { ArrayParser } from '@/parsing/ArrayParser/ArrayParser.js';\n\n/**\n * Parses incoming value as an array.\n * @param parserTypeName - parser type name.\n */\nexport function array(parserTypeName?: string): ArrayParser<unknown, false> {\n return new ArrayParser((value) => value, false, parserTypeName);\n}\n","import { invokeCustomMethod } from '@/bridge/utils/invokeCustomMethod.js';\nimport { WithSupports } from '@/classes/WithSupports.js';\nimport { array } from '@/parsing/parsers/array.js';\nimport { json } from '@/parsing/parsers/json.js';\nimport { string } from '@/parsing/parsers/string.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { CreateRequestIdFn } from '@/request-id/types.js';\nimport type { ExecuteWithTimeout } from '@/types/methods.js';\nimport type { Version } from '@/version/types.js';\n\nfunction objectFromKeys<K extends string, V>(keys: K[], value: V): Record<K, V> {\n return Object.fromEntries(keys.map((k) => [k, value])) as Record<K, V>;\n}\n\n// TODO: Usage.\n\n/**\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/cloud-storage\n */\nexport class CloudStorage extends WithSupports<'delete' | 'get' | 'getKeys' | 'set'> {\n constructor(\n version: Version,\n private readonly createRequestId: CreateRequestIdFn,\n private readonly postEvent: PostEvent,\n ) {\n super(version, {\n delete: 'web_app_invoke_custom_method',\n get: 'web_app_invoke_custom_method',\n getKeys: 'web_app_invoke_custom_method',\n set: 'web_app_invoke_custom_method',\n });\n }\n\n /**\n * Deletes specified key or keys from the cloud storage.\n * @param keyOrKeys - key or keys to delete.\n * @param options - request execution options.\n */\n async delete(keyOrKeys: string | string[], options: ExecuteWithTimeout = {}): Promise<void> {\n const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];\n if (keys.length) {\n await invokeCustomMethod(\n 'deleteStorageValues',\n { keys },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n );\n }\n }\n\n /**\n * Returns list of all keys presented in the cloud storage.\n * @param options - request execution options.\n */\n async getKeys(options: ExecuteWithTimeout = {}): Promise<string[]> {\n return array().of(string()).parse(\n await invokeCustomMethod(\n 'getStorageKeys',\n {},\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n ),\n );\n }\n\n /**\n * Returns map, where key is one of the specified in keys argument, and value is according\n * storage value.\n * @param keys - keys list.\n * @param options - request execution options.\n */\n get<K extends string>(keys: K[], options?: ExecuteWithTimeout): Promise<Record<K, string>>;\n\n /**\n * Returns value of the specified key.\n * @param key - cloud storage key.\n * @param options - request execution options.\n * @return Value of the specified key. In case, key was not created previously, function\n * will return empty string.\n */\n get(key: string, options?: ExecuteWithTimeout): Promise<string>;\n\n async get(\n keyOrKeys: string | string[],\n options: ExecuteWithTimeout = {},\n ): Promise<string | Record<string, string>> {\n const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];\n if (!keys.length) {\n return objectFromKeys(keys, '');\n }\n\n const data = await invokeCustomMethod(\n 'getStorageValues',\n { keys },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n );\n const result = json(objectFromKeys(keys, string()), 'CloudStorageData').parse(data);\n\n return Array.isArray(keyOrKeys) ? result : result[keyOrKeys];\n }\n\n /**\n * Saves specified value by key.\n * @param key - storage key.\n * @param value - storage value.\n * @param options - request execution options.\n */\n async set(key: string, value: string, options: ExecuteWithTimeout = {}): Promise<void> {\n await invokeCustomMethod(\n 'saveStorageValue',\n { key, value },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n );\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { CloudStorage } from './CloudStorage.js';\n\n/**\n * @returns A new initialized instance of the `CloudStorage` class.\n * @see CloudStorage\n */\nexport const initCloudStorage = createComponentInitFn(\n ({ createRequestId, postEvent, version }) => {\n return new CloudStorage(version, createRequestId, postEvent);\n },\n);\n","import { WithSupports } from '@/classes/WithSupports.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type {\n ImpactHapticFeedbackStyle,\n NotificationHapticFeedbackType,\n} from '@/bridge/methods/types/haptic.js';\nimport type { Version } from '@/version/types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/haptic-feedback\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/haptic-feedback\n */\nexport class HapticFeedback\n extends WithSupports<'impactOccurred' | 'notificationOccurred' | 'selectionChanged'> {\n constructor(version: Version, private readonly postEvent: PostEvent) {\n super(version, {\n impactOccurred: 'web_app_trigger_haptic_feedback',\n notificationOccurred: 'web_app_trigger_haptic_feedback',\n selectionChanged: 'web_app_trigger_haptic_feedback',\n });\n }\n\n /**\n * A method tells that an impact occurred. The Telegram app may play the\n * appropriate haptics based on style value passed.\n * @param style - impact style.\n */\n impactOccurred(style: ImpactHapticFeedbackStyle): void {\n this.postEvent('web_app_trigger_haptic_feedback', {\n type: 'impact',\n impact_style: style,\n });\n }\n\n /**\n * A method tells that a task or action has succeeded, failed, or produced\n * a warning. The Telegram app may play the appropriate haptics based on\n * type value passed.\n * @param type - notification type.\n */\n notificationOccurred(type: NotificationHapticFeedbackType): void {\n this.postEvent('web_app_trigger_haptic_feedback', {\n type: 'notification',\n notification_type: type,\n });\n }\n\n /**\n * A method tells that the user has changed a selection. The Telegram app\n * may play the appropriate haptics.\n *\n * Do not use this feedback when the user makes or confirms a selection;\n * use it only when the selection changes.\n */\n selectionChanged(): void {\n this.postEvent('web_app_trigger_haptic_feedback', { type: 'selection_change' });\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { HapticFeedback } from './HapticFeedback.js';\n\n/**\n * @returns A new initialized instance of the `HapticFeedback` class.\n * @see HapticFeedback\n */\nexport const initHapticFeedback = createComponentInitFn(\n ({ version, postEvent }) => new HapticFeedback(version, postEvent),\n);\n","import type {\n Chat,\n ChatType,\n InitDataParsed,\n User,\n} from './types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/init-data\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/init-data\n */\nexport class InitData {\n constructor(private readonly initData: InitDataParsed) {\n }\n\n /**\n * @see InitDataParsed.authDate\n */\n get authDate(): Date {\n return this.initData.authDate;\n }\n\n /**\n * @see InitDataParsed.canSendAfter\n */\n get canSendAfter(): number | undefined {\n return this.initData.canSendAfter;\n }\n\n /**\n * Date after which it is allowed to call\n * the [answerWebAppQuery](https://core.telegram.org/bots/api#answerwebappquery) method.\n */\n get canSendAfterDate(): Date | undefined {\n const { canSendAfter } = this;\n\n return canSendAfter\n ? new Date(this.authDate.getTime() + canSendAfter * 1000)\n : undefined;\n }\n\n /**\n * @see InitDataParsed.chat\n */\n get chat(): Chat | undefined {\n return this.initData.chat;\n }\n\n /**\n * @see InitDataParsed.chatType\n */\n get chatType(): ChatType | undefined {\n return this.initData.chatType;\n }\n\n /**\n * @see InitDataParsed.chatInstance\n */\n get chatInstance(): string | undefined {\n return this.initData.chatInstance;\n }\n\n /**\n * @see InitDataParsed.hash\n */\n get hash(): string {\n return this.initData.hash;\n }\n\n /**\n * @see InitDataParsed.queryId\n */\n get queryId(): string | undefined {\n return this.initData.queryId;\n }\n\n /**\n * @see InitDataParsed.receiver\n */\n get receiver(): User | undefined {\n return this.initData.receiver;\n }\n\n /**\n * @see InitDataParsed.startParam\n */\n get startParam(): string | undefined {\n return this.initData.startParam;\n }\n\n /**\n * @see InitDataParsed.user\n */\n get user(): User | undefined {\n return this.initData.user;\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { InitData } from './InitData.js';\n\n/**\n * @returns A new initialized instance of the `InitData` class or undefined.\n * @see InitData\n */\nexport const initInitData = createComponentInitFn(\n ({ initData }) => (initData ? new InitData(initData) : undefined),\n);\n","import { initData } from './parsers/initData.js';\nimport type { InitDataParsed } from './types.js';\n\n/**\n * Parses incoming value as init data.\n * @param value - value to parse.\n */\nexport function parseInitData(value: unknown): InitDataParsed {\n return initData().parse(value);\n}\n","import { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport type { InvoiceStatus } from '@/bridge/events/types.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { Version } from '@/version/types.js';\n\nimport type { InvoiceState } from './types.js';\n\n// TODO: Usage.\n\n/**\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/invoice\n */\nexport class Invoice extends WithSupportsAndTrackableState<InvoiceState, 'open'> {\n constructor(\n isOpened: boolean,\n version: Version,\n private readonly postEvent: PostEvent,\n ) {\n super({ isOpened }, version, { open: 'web_app_open_invoice' });\n }\n\n private set isOpened(value) {\n this.set('isOpened', value);\n }\n\n /**\n * True if invoice is currently opened.\n */\n get isOpened(): boolean {\n return this.get('isOpened');\n }\n\n /**\n * Opens an invoice using its slug.\n * @param slug - invoice slug.\n * @throws {Error} Invoice is already opened.\n */\n open(slug: string): Promise<InvoiceStatus>;\n\n /**\n * Opens an invoice using its url. It expects passing link in full format, with hostname \"t.me\".\n * @param url - invoice URL.\n * @param type - value type.\n * @throws {Error} Invoice is already opened.\n */\n open(url: string, type: 'url'): Promise<InvoiceStatus>;\n\n async open(urlOrSlug: string, type?: 'url'): Promise<InvoiceStatus> {\n if (this.isOpened) {\n throw new Error('Invoice is already opened');\n }\n\n let slug: string;\n if (!type) {\n slug = urlOrSlug;\n } else {\n const { hostname, pathname } = new URL(urlOrSlug, window.location.href);\n if (hostname !== 't.me') {\n throw new Error(`Incorrect hostname: ${hostname}`);\n }\n\n // Valid examples:\n // \"/invoice/my-slug\"\n // \"/$my-slug\"\n const match = pathname.match(/^\\/(\\$|invoice\\/)([A-Za-z0-9\\-_=]+)$/);\n if (!match) {\n // eslint-disable-next-line no-template-curly-in-string\n throw new Error('Link pathname has incorrect format. Expected to receive \"/invoice/{slug}\" or \"/${slug}\"');\n }\n [, , slug] = match;\n }\n\n this.isOpened = true;\n\n try {\n const result = await request({\n method: 'web_app_open_invoice',\n event: 'invoice_closed',\n params: { slug },\n postEvent: this.postEvent,\n capture(data) {\n return slug === data.slug;\n },\n });\n\n return result.status;\n } finally {\n this.isOpened = false;\n }\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { Invoice } from './Invoice.js';\n\n/**\n * @returns A new initialized instance of the `Invoice` class.\n * @see Invoice\n */\nexport const initInvoice = createComponentInitFn(\n ({ version, postEvent }) => new Invoice(false, version, postEvent),\n);\n","import { off } from '@/bridge/events/listening/off.js';\nimport { on } from '@/bridge/events/listening/on.js';\nimport { WithStateUtils } from '@/classes/WithStateUtils.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { RGB } from '@/colors/types.js';\nimport type {\n MainButtonEvents,\n MainButtonParams,\n MainButtonProps,\n MainButtonState,\n} from '@/components/MainButton/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\n\ntype Emitter = EventEmitter<MainButtonEvents>;\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/main-button\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/main-button\n */\nexport class MainButton extends WithStateUtils<MainButtonState> {\n private readonly postEvent: PostEvent;\n\n constructor({ postEvent, ...rest }: MainButtonProps) {\n super(rest);\n this.postEvent = postEvent;\n }\n\n /**\n * The MainButton background color.\n */\n get bgColor(): RGB {\n return this.get('bgColor');\n }\n\n /**\n * Sends current local state to the Telegram application.\n */\n private commit(): void {\n // We should not commit changes until payload is correct. We could\n // have some invalid values in case, button instance was created\n // with empty values. Otherwise, an unexpected behavior could be received.\n if (this.text === '') {\n return;\n }\n\n this.postEvent('web_app_setup_main_button', {\n is_visible: this.isVisible,\n is_active: this.isEnabled,\n is_progress_visible: this.isLoaderVisible,\n text: this.text,\n color: this.bgColor,\n text_color: this.textColor,\n });\n }\n\n /**\n * Disables the MainButton.\n * @see Does not work on Android: https://github.com/Telegram-Mini-Apps/issues/issues/1\n */\n disable(): this {\n this.isEnabled = false;\n return this;\n }\n\n /**\n * Enables the MainButton.\n */\n enable(): this {\n this.isEnabled = true;\n return this;\n }\n\n /**\n * Hides the MainButton.\n */\n hide(): this {\n this.isVisible = false;\n return this;\n }\n\n /**\n * Hides the MainButton loading indicator.\n */\n hideLoader(): this {\n this.isLoaderVisible = false;\n return this;\n }\n\n private set isEnabled(isEnabled: boolean) {\n this.setParams({ isEnabled });\n }\n\n /**\n * True if the MainButton is enabled.\n */\n get isEnabled(): boolean {\n return this.get('isEnabled');\n }\n\n private set isLoaderVisible(isLoaderVisible: boolean) {\n this.setParams({ isLoaderVisible });\n }\n\n /**\n * True if the MainButton loader is visible.\n */\n get isLoaderVisible(): boolean {\n return this.get('isLoaderVisible');\n }\n\n private set isVisible(isVisible: boolean) {\n this.setParams({ isVisible });\n }\n\n /**\n * True if the MainButton is visible.\n */\n get isVisible(): boolean {\n return this.get('isVisible');\n }\n\n /**\n * Adds a new event listener.\n * @param event - event to listen.\n * @param listener - listener to add.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('main_button_pressed', listener)\n : this.state.on(event, listener as any)\n );\n\n /**\n * Removes the event listener.\n * @param event - event to listen.\n * @param listener - listener to remove.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('main_button_pressed', listener)\n : this.state.off(event, listener as any)\n );\n\n /**\n * Shows the MainButton.\n *\n * Note that opening the Mini App from the attachment menu hides the main button until the\n * user interacts with the Mini App interface.\n */\n show(): this {\n this.isVisible = true;\n return this;\n }\n\n /**\n * Shows a loading indicator on the Main Button.\n */\n showLoader(): this {\n this.isLoaderVisible = true;\n return this;\n }\n\n /**\n * Sets a new MainButton text. Minimal length for the text is 1 symbol, and maximum is 64 symbols.\n * @param text - a new text.\n */\n setText(text: string): this {\n return this.setParams({ text });\n }\n\n /**\n * Sets a new Main Button text color.\n * @param textColor - new text color.\n */\n setTextColor(textColor: RGB): this {\n return this.setParams({ textColor });\n }\n\n /**\n * Updates current Main Button color.\n * @param bgColor - color to set.\n */\n setBgColor(bgColor: RGB): this {\n return this.setParams({ bgColor });\n }\n\n /**\n * Allows setting multiple Main Button parameters.\n * @param params - Main Button parameters.\n */\n setParams(params: Partial<MainButtonParams>): this {\n this.set(params);\n this.commit();\n return this;\n }\n\n /**\n * The MainButton text.\n */\n get text(): string {\n return this.get('text');\n }\n\n /**\n * The MainButton text color.\n */\n get textColor(): RGB {\n return this.get('textColor');\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { MainButton } from './MainButton.js';\n\n/**\n * @returns A new initialized instance of the `MainButton` class.\n * @see MainButton\n */\nexport const initMainButton = createComponentInitFn(\n 'mainButton',\n ({\n postEvent,\n themeParams,\n state = {\n isVisible: false,\n isEnabled: false,\n text: '',\n isLoaderVisible: false,\n textColor: themeParams.buttonTextColor || '#ffffff',\n bgColor: themeParams.buttonColor || '#000000',\n },\n }) => new MainButton({ ...state, postEvent }),\n);\n","import { date } from '@/parsing/parsers/date.js';\nimport { json } from '@/parsing/parsers/json.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { searchParams } from '@/parsing/parsers/searchParams.js';\nimport { string } from '@/parsing/parsers/string.js';\nimport type { ValueParser } from '@/parsing/ValueParser/ValueParser.js';\n\nimport type { RequestedContact } from '../types.js';\n\n/**\n * Returns function which parses incoming value as a contact information.\n */\nexport function contact(): ValueParser<RequestedContact, false> {\n return searchParams({\n contact: json({\n userId: {\n type: number(),\n from: 'user_id',\n },\n phoneNumber: {\n type: string(),\n from: 'phone_number',\n },\n firstName: {\n type: string(),\n from: 'first_name',\n },\n lastName: {\n type: string().optional(),\n from: 'last_name',\n },\n }),\n authDate: {\n type: date(),\n from: 'auth_date',\n },\n hash: string(),\n }, 'RequestedContact');\n}\n","import { supports } from '@/supports/supports.js';\nimport type {\n MiniAppsMethodVersionedParams,\n MiniAppsMethodWithVersionedParams,\n} from '@/bridge/methods/types/methods.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\ntype HasCheckSupportMethodTuple = {\n [M in MiniAppsMethodWithVersionedParams]: [M, MiniAppsMethodVersionedParams<M>]\n}[MiniAppsMethodWithVersionedParams];\n\n/**\n * Returns function, which accepts predefined method name and checks if it is supported\n * via passed schema and version.\n * @param schema - object which contains methods names and TWA methods with specified parameter\n * as a dependency.\n * @param version - platform version.\n */\nexport function createSupportsParamFn<Method extends string>(\n version: Version,\n schema: Record<Method, HasCheckSupportMethodTuple>,\n): SupportsFn<Method> {\n return (method) => {\n const [tmaMethod, param] = schema[method];\n\n return supports(tmaMethod, param, version);\n };\n}\n","/**\n * Awaits for specified amount of time.\n * @param duration - duration in ms to await.\n */\nexport function sleep(duration: number): Promise<void> {\n return new Promise((res) => {\n setTimeout(res, duration);\n });\n}\n","import { invokeCustomMethod } from '@/bridge/utils/invokeCustomMethod.js';\nimport { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport { isColorDark } from '@/colors/isColorDark.js';\nimport { isRGB } from '@/colors/isRGB.js';\nimport { contact } from '@/components/MiniApp/parsing/contact.js';\nimport { createSupportsParamFn } from '@/supports/createSupportsParamFn.js';\nimport { createTimeoutError } from '@/timeout/createTimeoutError.js';\nimport { sleep } from '@/timeout/sleep.js';\nimport { withTimeout } from '@/timeout/withTimeout.js';\nimport type { PhoneRequestedStatus, WriteAccessRequestedStatus } from '@/bridge/events/types.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { SwitchInlineQueryChatType } from '@/bridge/methods/types/methods.js';\nimport type { RGB } from '@/colors/types.js';\nimport type { MiniAppHeaderColor, MiniAppProps, MiniAppState, RequestedContact } from '@/components/MiniApp/types.js';\nimport type { CreateRequestIdFn } from '@/request-id/types.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { ExecuteWithTimeout } from '@/types/methods.js';\n\n/**\n * Provides common Mini Apps functionality not covered by other system components.\n */\nexport class MiniApp extends WithSupportsAndTrackableState<\n MiniAppState,\n | 'requestPhoneAccess'\n | 'requestWriteAccess'\n | 'switchInlineQuery'\n | 'setHeaderColor'\n | 'setBackgroundColor'\n> {\n private readonly botInline: boolean;\n\n private readonly postEvent: PostEvent;\n\n private readonly createRequestId: CreateRequestIdFn;\n\n private requestPhoneAccessPromise: Promise<PhoneRequestedStatus> | undefined;\n\n private requestWriteAccessPromise: Promise<WriteAccessRequestedStatus> | undefined;\n\n constructor({ postEvent, createRequestId, version, botInline, ...rest }: MiniAppProps) {\n super(rest, version, {\n requestPhoneAccess: 'web_app_request_phone',\n requestWriteAccess: 'web_app_request_write_access',\n switchInlineQuery: 'web_app_switch_inline_query',\n setHeaderColor: 'web_app_set_header_color',\n setBackgroundColor: 'web_app_set_background_color',\n });\n\n this.createRequestId = createRequestId;\n this.postEvent = postEvent;\n this.botInline = botInline;\n\n const supportsOriginal = this.supports.bind(this);\n this.supports = (method) => {\n if (!supportsOriginal(method)) {\n return false;\n }\n\n // web_app_switch_inline_query requires a Mini App to be in inline mode, that's why we\n // add 1 more check here.\n return method !== 'switchInlineQuery' || botInline;\n };\n\n this.supportsParam = createSupportsParamFn(version, {\n 'setHeaderColor.color': ['web_app_set_header_color', 'color'],\n });\n }\n\n /**\n * Attempts to get requested contact.\n * @param timeout - request timeout.\n */\n private async getRequestedContact({\n timeout = 10000,\n }: ExecuteWithTimeout = {}): Promise<RequestedContact> {\n return contact().parse(\n await invokeCustomMethod(\n 'getRequestedContact',\n {},\n this.createRequestId(),\n { postEvent: this.postEvent, timeout },\n ),\n );\n }\n\n /**\n * The Mini App background color.\n * @example \"#ffaabb\"\n */\n get bgColor(): RGB {\n return this.get('bgColor');\n }\n\n /**\n * Closes the Mini App.\n */\n close(): void {\n this.postEvent('web_app_close');\n }\n\n /**\n * The Mini App header color.\n * @example \"#ffaabb\"\n * @example \"bg_color\"\n */\n get headerColor(): MiniAppHeaderColor {\n return this.get('headerColor');\n }\n\n /**\n * True if the Mini App is currently launched in bot inline mode.\n */\n get isBotInline(): boolean {\n return this.botInline;\n }\n\n /**\n * True if current Mini App background color is recognized as dark.\n */\n get isDark(): boolean {\n return isColorDark(this.bgColor);\n }\n\n /**\n * Informs the Telegram app that the Mini App is ready to be displayed.\n *\n * It is recommended to call this method as early as possible, as soon as all essential\n * interface elements loaded. Once this method called, the loading placeholder is hidden\n * and the Mini App shown.\n *\n * If the method not called, the placeholder will be hidden only when the page fully loaded.\n */\n ready(): void {\n this.postEvent('web_app_ready');\n }\n\n /**\n * Requests current user contact information. In contrary to requestPhoneAccess, this method\n * returns promise with contact information that rejects in case, user denied access, or request\n * failed.\n * @param options - additional options.\n */\n async requestContact({ timeout = 5000 }: ExecuteWithTimeout = {}): Promise<RequestedContact> {\n // First of all, let's try to get the requested contact. Probably, we already requested\n // it before.\n try {\n return await this.getRequestedContact();\n } catch { /* empty */\n }\n\n // Then, request access to user's phone.\n const status = await this.requestPhoneAccess();\n if (status !== 'sent') {\n throw new Error('Access denied.');\n }\n\n // Expected deadline.\n const deadlineAt = Date.now() + timeout;\n\n // Time to wait before executing the next request.\n let sleepTime = 50;\n\n // We are trying to retrieve the requested contact until deadline was reached.\n return withTimeout(async () => {\n while (Date.now() < deadlineAt) {\n try {\n return await this.getRequestedContact();\n } catch (e) { /* empty */\n }\n\n // Sleep for some time.\n await sleep(sleepTime);\n\n // Increase the sleep time not to kill the backend service.\n sleepTime += 50;\n }\n\n throw createTimeoutError(timeout);\n }, timeout);\n }\n\n /**\n * Requests current user phone access. Method returns promise, which resolves\n * status of the request. In case, user accepted the request, Mini App bot will receive\n * the according notification.\n *\n * To obtain the retrieved information instead, utilize the `requestContact` method.\n * @param options - additional options.\n * @see requestContact\n */\n async requestPhoneAccess(options: ExecuteWithTimeout = {}): Promise<PhoneRequestedStatus> {\n if (!this.requestPhoneAccessPromise) {\n this.requestPhoneAccessPromise = request({\n ...options,\n method: 'web_app_request_phone',\n event: 'phone_requested',\n postEvent: this.postEvent,\n })\n .then(({ status }) => status)\n .finally(() => this.requestPhoneAccessPromise = undefined);\n }\n return this.requestPhoneAccessPromise;\n }\n\n /**\n * Requests write message access to current user.\n * @param options - additional options.\n */\n async requestWriteAccess(options: ExecuteWithTimeout = {}): Promise<WriteAccessRequestedStatus> {\n if (!this.requestWriteAccessPromise) {\n this.requestWriteAccessPromise = request({\n ...options,\n method: 'web_app_request_write_access',\n event: 'write_access_requested',\n postEvent: this.postEvent,\n })\n .then(({ status }) => status)\n .finally(() => this.requestWriteAccessPromise = undefined);\n }\n return this.requestWriteAccessPromise;\n }\n\n /**\n * A method used to send data to the bot. When this method called, a service message sent to\n * the bot containing the data of the length up to 4096 bytes, and the Mini App closed. See the\n * field `web_app_data` in the class [Message](https://core.telegram.org/bots/api#message).\n *\n * This method is only available for Mini Apps launched via a Keyboard button.\n * @param data - data to send to bot.\n * @throws {Error} data has incorrect size.\n */\n sendData(data: string): void {\n const { size } = new Blob([data]);\n if (!size || size > 4096) {\n throw new Error(`Passed data has incorrect size: ${size}`);\n }\n this.postEvent('web_app_data_send', { data });\n }\n\n /**\n * Updates current Mini App header color.\n *\n * @see No effect on desktop: https://github.com/Telegram-Mini-Apps/tma.js/issues/9\n * @see Works incorrectly in Android: https://github.com/Telegram-Mini-Apps/tma.js/issues/8\n * @param color - color key or RGB color.\n */\n setHeaderColor(color: MiniAppHeaderColor): void {\n this.postEvent('web_app_set_header_color', isRGB(color) ? { color } : { color_key: color });\n this.set('headerColor', color);\n }\n\n /**\n * Updates current Mini App background color.\n *\n * @see No effect on desktop: https://github.com/Telegram-Mini-Apps/tma.js/issues/9\n * @see Works incorrectly in Android: https://github.com/Telegram-Mini-Apps/tma.js/issues/8\n * @param color - RGB color.\n */\n setBgColor(color: RGB): void {\n this.postEvent('web_app_set_background_color', { color });\n this.set('bgColor', color);\n }\n\n /**\n * Checks if specified method parameter is supported by current component.\n */\n supportsParam: SupportsFn<'setHeaderColor.color'>;\n\n /**\n * Inserts the bot's username and the specified inline query in the current chat's input field.\n * Query may be empty, in which case only the bot's username will be inserted. The client prompts\n * the user to choose a specific chat, then opens that chat and inserts the bot's username and\n * the specified inline query in the input field.\n * @param text - text which should be inserted in the input after the current bot name. Max\n * length is 256 symbols.\n * @param chatTypes - List of chat types which could be chosen to send the message. Could be\n * empty list.\n */\n switchInlineQuery(text: string, chatTypes: SwitchInlineQueryChatType[] = []): void {\n if (!this.supports('switchInlineQuery') && !this.isBotInline) {\n throw new Error('Method is unsupported because Mini App should be launched in inline mode.');\n }\n this.postEvent('web_app_switch_inline_query', { query: text, chat_types: chatTypes });\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { MiniApp } from './MiniApp.js';\n\n/**\n * @returns A new initialized instance of the `MiniApp` class.\n * @see MiniApp\n */\nexport const initMiniApp = createComponentInitFn(\n 'miniApp',\n ({\n themeParams,\n botInline = false,\n state = {\n bgColor: themeParams.bgColor || '#ffffff',\n headerColor: themeParams.headerBgColor || '#000000',\n },\n ...rest\n }) => new MiniApp({ ...rest, ...state, botInline }),\n);\n","import type { PopupButton, PopupParams as BridgePopupParams } from '@/bridge/methods/types/popup.js';\n\nimport type { OpenPopupOptions } from './types.js';\n\n/**\n * Prepares popup parameters before sending them to native app.\n * @param params - popup parameters.\n */\nexport function preparePopupParams(params: OpenPopupOptions): BridgePopupParams {\n const message = params.message.trim();\n const title = (params.title || '').trim();\n const buttons = params.buttons || [];\n let preparedButtons: PopupButton[];\n\n // Check title.\n if (title.length > 64) {\n throw new Error(`Title has incorrect size: ${title.length}`);\n }\n\n // Check message.\n if (!message.length || message.length > 256) {\n throw new Error(`Message has incorrect size: ${message.length}`);\n }\n\n // Check buttons.\n if (buttons.length > 3) {\n throw new Error(`Buttons have incorrect size: ${buttons.length}`);\n }\n\n // Append button in case, there are no buttons passed.\n if (!buttons.length) {\n preparedButtons = [{ type: 'close', id: '' }];\n } else {\n // Otherwise, check all the buttons.\n preparedButtons = buttons.map((b) => {\n const { id = '' } = b;\n\n // Check button ID.\n if (id.length > 64) {\n throw new Error(`Button ID has incorrect size: ${id}`);\n }\n\n if (!b.type || b.type === 'default' || b.type === 'destructive') {\n const text = b.text.trim();\n\n if (!text.length || text.length > 64) {\n const type = b.type || 'default';\n\n throw new Error(`Button text with type \"${type}\" has incorrect size: ${b.text.length}`);\n }\n\n return { ...b, text, id };\n }\n\n return { ...b, id };\n });\n }\n return { title, message, buttons: preparedButtons };\n}\n","import { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport { preparePopupParams } from '@/components/Popup/preparePopupParams.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { OpenPopupOptions, PopupState } from '@/components/Popup/types.js';\nimport type { Version } from '@/version/types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/popup\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/popup\n */\nexport class Popup extends WithSupportsAndTrackableState<PopupState, 'open'> {\n constructor(isOpened: boolean, version: Version, private readonly postEvent: PostEvent) {\n super({ isOpened }, version, { open: 'web_app_open_popup' });\n }\n\n private set isOpened(value) {\n this.set('isOpened', value);\n }\n\n /**\n * True if the Popup is opened.\n */\n get isOpened(): boolean {\n return this.get('isOpened');\n }\n\n /**\n * A method that shows a native popup described by the `params` argument.\n * Promise will be resolved when popup is closed. Resolved value will have\n * an identifier of pressed button.\n *\n * In case, user clicked outside the popup or clicked top right popup close\n * button, null will be returned.\n *\n * @param options - popup parameters.\n * @throws {Error} Popup is already opened.\n */\n async open(options: OpenPopupOptions): Promise<string | null> {\n if (this.isOpened) {\n throw new Error('Popup is already opened.');\n }\n\n this.isOpened = true;\n\n try {\n const { button_id: buttonId = null } = await request({\n event: 'popup_closed',\n method: 'web_app_open_popup',\n postEvent: this.postEvent,\n params: preparePopupParams(options),\n });\n return buttonId;\n } finally {\n this.isOpened = false;\n }\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { Popup } from './Popup.js';\n\n/**\n * @returns A new initialized instance of the `Popup` class.\n * @see Popup\n */\nexport const initPopup = createComponentInitFn(\n ({ postEvent, version }) => new Popup(false, version, postEvent),\n);\n","import { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { Version } from '@/version/types.js';\n\nimport type { QRScannerState } from './types.js';\n\n// TODO: Usage\n\n/**\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/qr-scanner\n */\nexport class QRScanner extends WithSupportsAndTrackableState<QRScannerState, 'close' | 'open'> {\n constructor(isOpened: boolean, version: Version, private readonly postEvent: PostEvent) {\n super({ isOpened }, version, {\n close: 'web_app_close_scan_qr_popup',\n open: 'web_app_open_scan_qr_popup',\n });\n }\n\n /**\n * Closes scanner.\n */\n close(): void {\n this.postEvent('web_app_close_scan_qr_popup');\n this.isOpened = false;\n }\n\n private set isOpened(value) {\n this.set('isOpened', value);\n }\n\n /**\n * Returns true in case, QR scanner is currently opened.\n */\n get isOpened(): boolean {\n return this.get('isOpened');\n }\n\n /**\n * Opens scanner with specified title shown to user. Method returns promise\n * with scanned QR content in case, it was scanned. It will contain null in\n * case, scanner was closed.\n * @param text - title to display.\n */\n async open(text?: string): Promise<string | null> {\n if (this.isOpened) {\n throw new Error('QR scanner is already opened.');\n }\n\n this.isOpened = true;\n\n try {\n const result = await request({\n method: 'web_app_open_scan_qr_popup',\n event: ['qr_text_received', 'scan_qr_popup_closed'],\n postEvent: this.postEvent,\n params: { text },\n }) || {};\n\n return result.data || null;\n } finally {\n this.isOpened = false;\n }\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { QRScanner } from './QRScanner.js';\n\n/**\n * @returns A new initialized instance of the `QRScanner` class.\n * @see QRScanner\n */\nexport const initQRScanner = createComponentInitFn(\n ({ version, postEvent }) => new QRScanner(false, version, postEvent),\n);\n","import { off } from '@/bridge/events/listening/off.js';\nimport { on } from '@/bridge/events/listening/on.js';\nimport { WithSupportsAndStateUtils } from '@/classes/WithSupportsAndStateUtils.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type {\n SettingsButtonEvents,\n SettingsButtonState,\n} from '@/components/SettingsButton/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport type { Version } from '@/version/types.js';\n\ntype Emitter = EventEmitter<SettingsButtonEvents>;\n\nexport class SettingsButton extends WithSupportsAndStateUtils<SettingsButtonState, 'show' | 'hide'> {\n constructor(isVisible: boolean, version: Version, private readonly postEvent: PostEvent) {\n super({ isVisible }, version, {\n show: 'web_app_setup_settings_button',\n hide: 'web_app_setup_settings_button',\n });\n }\n\n private set isVisible(visible: boolean) {\n this.set('isVisible', visible);\n this.postEvent('web_app_setup_settings_button', { is_visible: visible });\n }\n\n /**\n * True if the SettingsButton is visible.\n */\n get isVisible(): boolean {\n return this.get('isVisible');\n }\n\n /**\n * Hides the SettingsButton.\n */\n hide(): void {\n this.isVisible = false;\n }\n\n /**\n * Adds a new event listener.\n * @param event - event to listen.\n * @param listener - listener to add.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('settings_button_pressed', listener)\n : this.state.on(event, listener as any)\n );\n\n /**\n * Removes the event listener.\n * @param event - event to listen.\n * @param listener - listener to remove.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('settings_button_pressed', listener)\n : this.state.off(event, listener as any)\n );\n\n /**\n * Shows the SettingsButton.\n */\n show(): void {\n this.isVisible = true;\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { SettingsButton } from './SettingsButton.js';\n\n/**\n * @returns A new initialized instance of the `SettingsButton` class.\n * @see SettingsButton\n */\nexport const initSettingsButton = createComponentInitFn(\n 'settingsButton',\n ({\n version,\n postEvent,\n state = { isVisible: false },\n }) => new SettingsButton(state.isVisible, version, postEvent),\n);\n","import { themeParams } from '@/components/ThemeParams/parsing/themeParams.js';\n\nimport type { ThemeParamsParsed } from '../types.js';\n\n/**\n * Parses incoming value as theme parameters.\n * @param value - value to parse.\n */\nexport function parseThemeParams(value: unknown): ThemeParamsParsed {\n return themeParams().parse(value);\n}\n","import { on } from '@/bridge/events/listening/on.js';\nimport { WithTrackableState } from '@/classes/WithTrackableState.js';\nimport { isColorDark } from '@/colors/isColorDark.js';\nimport type { RGB } from '@/colors/types.js';\nimport type { RemoveEventListenerFn } from '@/events/types.js';\n\nimport { parseThemeParams } from './parsing/parseThemeParams.js';\nimport type { ThemeParamsParsed, ThemeParamsState } from './types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/theming\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/theme-params\n */\nexport class ThemeParams extends WithTrackableState<ThemeParamsState> {\n /**\n * @since v6.10\n */\n get accentTextColor(): RGB | undefined {\n return this.get('accentTextColor');\n }\n\n get bgColor(): RGB | undefined {\n return this.get('bgColor');\n }\n\n get buttonColor(): RGB | undefined {\n return this.get('buttonColor');\n }\n\n get buttonTextColor(): RGB | undefined {\n return this.get('buttonTextColor');\n }\n\n get destructiveTextColor(): RGB | undefined {\n return this.get('destructiveTextColor');\n }\n\n /**\n * Returns the copy of the internal state of the current component instance.\n */\n getState(): ThemeParamsParsed {\n return this.clone();\n }\n\n /**\n * @since v6.10\n */\n get headerBgColor(): RGB | undefined {\n return this.get('headerBgColor');\n }\n\n get hintColor(): RGB | undefined {\n return this.get('hintColor');\n }\n\n /**\n * @returns True in case, current color scheme is recognized as dark. This\n * value is calculated according to theme bg color.\n */\n get isDark(): boolean {\n return !this.bgColor || isColorDark(this.bgColor);\n }\n\n get linkColor(): RGB | undefined {\n return this.get('linkColor');\n }\n\n get secondaryBgColor(): RGB | undefined {\n return this.get('secondaryBgColor');\n }\n\n /**\n * @since v6.10\n */\n get sectionBgColor(): RGB | undefined {\n return this.get('sectionBgColor');\n }\n\n /**\n * @since v6.10\n */\n get sectionHeaderTextColor(): RGB | undefined {\n return this.get('sectionHeaderTextColor');\n }\n\n /**\n * Starts listening to the external theme changes and applies them.\n * @returns Function to stop listening.\n */\n listen(): RemoveEventListenerFn {\n return on('theme_changed', (event) => {\n this.set(parseThemeParams(event.theme_params));\n });\n }\n\n /**\n * @since v6.10\n */\n get subtitleTextColor(): RGB | undefined {\n return this.get('subtitleTextColor');\n }\n\n get textColor(): RGB | undefined {\n return this.get('textColor');\n }\n}\n","import { ThemeParams } from '@/components/ThemeParams/ThemeParams.js';\nimport { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\n/**\n * @returns A new initialized instance of the `ThemeParams` class.\n * @see ThemeParams\n */\nexport const initThemeParams = createComponentInitFn(\n 'themeParams',\n ({ themeParams, state = themeParams, addCleanup }) => {\n const tp = new ThemeParams(state);\n addCleanup(tp.listen());\n return tp;\n },\n);\n","import { request } from '@/bridge/utils/request.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nimport { parseThemeParams } from './parsing/parseThemeParams.js';\nimport type { ThemeParamsParsed } from './types.js';\n\n/**\n * Requests current theme parameters from the Telegram application.\n * @param options - request options.\n */\nexport function requestThemeParams(options: ExecuteWithOptions = {}): Promise<ThemeParamsParsed> {\n return request({\n ...options,\n method: 'web_app_request_theme',\n event: 'theme_changed',\n }).then(parseThemeParams);\n}\n","import { captureSameReq } from '@/bridge/utils/captureSameReq.js';\nimport { request } from '@/bridge/utils/request.js';\nimport { WithSupports } from '@/classes/WithSupports.js';\nimport { createSupportsParamFn } from '@/supports/createSupportsParamFn.js';\nimport { supports } from '@/supports/supports.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { CreateRequestIdFn } from '@/request-id/types.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\n/**\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/utils\n */\nexport class Utils extends WithSupports<'readTextFromClipboard'> {\n constructor(\n private readonly version: Version,\n private readonly createRequestId: CreateRequestIdFn,\n private readonly postEvent: PostEvent,\n ) {\n super(version, { readTextFromClipboard: 'web_app_read_text_from_clipboard' });\n\n this.supportsParam = createSupportsParamFn(version, {\n 'openLink.tryInstantView': ['web_app_open_link', 'try_instant_view'],\n });\n }\n\n /**\n * Opens a link in an external browser. The Mini App will not be closed.\n *\n * Note that this method can be called only in response to the user\n * interaction with the Mini App interface (e.g. click inside the Mini App\n * or on the main button).\n * @param url - URL to be opened.\n * @param tryInstantView\n */\n openLink(url: string, tryInstantView?: boolean): void {\n const formattedUrl = new URL(url, window.location.href).toString();\n\n // If method is not supported, we are doing it in legacy way.\n if (!supports('web_app_open_link', this.version)) {\n window.open(formattedUrl, '_blank');\n return;\n }\n\n // Otherwise, do it normally.\n this.postEvent('web_app_open_link', {\n url: formattedUrl,\n ...(typeof tryInstantView === 'boolean' ? { try_instant_view: tryInstantView } : {}),\n });\n }\n\n /**\n * Opens a Telegram link inside Telegram app. The Mini App will be closed. It expects passing\n * link in full format, with hostname \"t.me\".\n * @param url - URL to be opened.\n * @throws {Error} URL has not allowed hostname.\n */\n openTelegramLink(url: string): void {\n const { hostname, pathname, search } = new URL(url, window.location.href);\n if (hostname !== 't.me') {\n throw new Error(`URL has not allowed hostname: ${hostname}. Only \"t.me\" is allowed`);\n }\n\n if (!supports('web_app_open_tg_link', this.version)) {\n window.location.href = url;\n return;\n }\n\n this.postEvent('web_app_open_tg_link', { path_full: pathname + search });\n }\n\n /**\n * Reads text from clipboard and returns string or null. null is returned\n * in cases:\n * - Value in clipboard is not text\n * - Access to clipboard is not allowed\n */\n async readTextFromClipboard(): Promise<string | null> {\n const reqId = this.createRequestId();\n const {\n data = null,\n } = await request({\n method: 'web_app_read_text_from_clipboard',\n event: 'clipboard_text_received',\n postEvent: this.postEvent,\n params: { req_id: reqId },\n capture: captureSameReq(reqId),\n });\n\n return data;\n }\n\n /**\n * Checks if specified method parameter is supported by current component.\n */\n supportsParam: SupportsFn<'openLink.tryInstantView'>;\n}\n","import { Utils } from '@/components/Utils/Utils.js';\nimport { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\n/**\n * @returns A new initialized instance of the `Utils` class.\n * @see Utils\n */\nexport const initUtils = createComponentInitFn(\n ({ version, postEvent, createRequestId }) => {\n return new Utils(version, createRequestId, postEvent);\n },\n);\n","import { request } from '@/bridge/utils/request.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nexport interface RequestViewportResult {\n height: number;\n isStateStable: boolean;\n isExpanded: boolean;\n width: number;\n}\n\n/**\n * Requests viewport actual information from the Telegram application.\n * @param options - request options.\n */\nexport async function requestViewport(\n options: ExecuteWithOptions = {},\n): Promise<RequestViewportResult> {\n const {\n is_expanded: isExpanded,\n is_state_stable: isStateStable,\n ...rest\n } = await request({\n ...options,\n method: 'web_app_request_viewport',\n event: 'viewport_changed',\n });\n\n return { ...rest, isExpanded, isStateStable };\n}\n","import { on } from '@/bridge/events/listening/on.js';\nimport { WithTrackableState } from '@/classes/WithTrackableState.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { RemoveEventListenerFn } from '@/events/types.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nimport { requestViewport } from './requestViewport.js';\nimport type { ViewportProps, ViewportState } from './types.js';\n\n/**\n * Formats value to make it stay in bounds [0, +Inf).\n * @param value - value to format.\n */\nfunction truncate(value: number): number {\n return value < 0 ? 0 : value;\n}\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/viewport\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/viewport\n */\nexport class Viewport extends WithTrackableState<ViewportState> {\n private readonly postEvent: PostEvent;\n\n constructor({ postEvent, stableHeight, height, width, isExpanded }: ViewportProps) {\n super({\n height: truncate(height),\n isExpanded,\n stableHeight: truncate(stableHeight),\n width: truncate(width),\n });\n this.postEvent = postEvent;\n }\n\n /**\n * Requests viewport information from the Telegram application and updates current Viewport\n * instance.\n * @param options - options to request fresh data.\n */\n async sync(options?: ExecuteWithOptions): Promise<void> {\n const { isStateStable, ...rest } = await requestViewport(options);\n this.set({\n ...rest,\n stableHeight: isStateStable ? rest.height : this.get('stableHeight'),\n });\n }\n\n /**\n * The current height of the **visible area** of the Mini App.\n *\n * The application can display just the top part of the Mini App, with its lower part remaining\n * outside the screen area. From this position, the user can \"pull\" the Mini App to its\n * maximum height, while the bot can do the same by calling `expand` method. As the position of\n * the Mini App changes, the current height value of the visible area will be updated in real\n * time.\n *\n * Please note that the refresh rate of this value is not sufficient to smoothly follow the\n * lower border of the window. It should not be used to pin interface elements to the bottom\n * of the visible area. It's more appropriate to use the value of the `stableHeight`\n * field for this purpose.\n *\n * @see stableHeight\n */\n get height(): number {\n return this.get('height');\n }\n\n /**\n * The height of the visible area of the Mini App in its last stable state.\n *\n * The application can display just the top part of the Mini App, with its lower part remaining\n * outside the screen area. From this position, the user can \"pull\" the Mini App to its\n * maximum height, while the application can do the same by calling `expand` method.\n *\n * Unlike the value of `height`, the value of `stableHeight` does not change as the position\n * of the Mini App changes with user gestures or during animations. The value of `stableHeight`\n * will be updated after all gestures and animations are completed and\n * the Mini App reaches its final size.\n *\n * @see height\n */\n get stableHeight(): number {\n return this.get('stableHeight');\n }\n\n /**\n * Starts listening to viewport changes and applies them.\n * @returns Function to stop listening.\n */\n listen(): RemoveEventListenerFn {\n return on('viewport_changed', (event) => {\n const {\n height,\n width,\n is_expanded: isExpanded,\n is_state_stable: isStateStable,\n } = event;\n const truncatedHeight = truncate(height);\n\n this.set({\n height: truncatedHeight,\n isExpanded,\n width: truncate(width),\n ...(isStateStable ? { stableHeight: truncatedHeight } : {}),\n });\n });\n }\n\n /**\n * True if the Mini App is expanded to the maximum available height. Otherwise, if\n * the Mini App occupies part of the screen and can be expanded to the full height using\n * `expand` method.\n * @see expand\n */\n get isExpanded(): boolean {\n return this.get('isExpanded');\n }\n\n /**\n * Current visible area width.\n */\n get width(): number {\n return this.get('width');\n }\n\n /**\n * A method that expands the Mini App to the maximum available height. To find out if the Mini\n * App is expanded to the maximum height, refer to the value of the `isExpanded`.\n * @see isExpanded\n */\n expand(): void {\n this.postEvent('web_app_expand');\n this.set('isExpanded', true);\n }\n\n /**\n * True if the current viewport height is stable and is not going to change in the next moment.\n */\n get isStable(): boolean {\n return this.stableHeight === this.height;\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { Viewport } from './Viewport.js';\nimport { requestViewport } from '@/components/Viewport/requestViewport.js';\n\n/**\n * @returns A promise with a new initialized instance of the `Viewport` class.\n * @see Viewport\n */\nexport const initViewport = createComponentInitFn(\n 'viewport',\n async ({ state, platform, postEvent, addCleanup }) => {\n let isExpanded = false;\n let height = 0;\n let width = 0;\n let stableHeight = 0;\n\n // State was saved previously, we restore the Viewport from this state.\n if (state) {\n isExpanded = state.isExpanded;\n height = state.height;\n width = state.width;\n stableHeight = state.stableHeight;\n } else if (['macos', 'tdesktop', 'unigram', 'webk', 'weba', 'web'].includes(platform)) {\n // If platform has a stable viewport, it means we could instantiate Viewport using\n // the window global object properties.\n isExpanded = true;\n height = window.innerHeight;\n width = window.innerWidth;\n stableHeight = window.innerHeight;\n } else {\n // We were unable to retrieve data locally. In this case we are sending a request returning\n // a viewport information.\n const response = await requestViewport({ timeout: 1000, postEvent });\n isExpanded = response.isExpanded;\n height = response.height;\n width = response.width;\n stableHeight = response.isStateStable ? height : 0;\n }\n\n // Otherwise, Viewport instance will be created using zero values.\n const viewport = new Viewport({\n postEvent,\n height,\n width,\n stableHeight,\n isExpanded,\n });\n\n // Listen to the viewport external changes and actualize local instance.\n addCleanup(viewport.listen());\n\n return viewport;\n },\n);\n","/**\n * Sets CSS variable globally.\n * @param name - variable name.\n * @param value - variable value.\n */\nexport function setCSSVar(name: string, value: string): void {\n document.documentElement.style.setProperty(name, value);\n}\n","import { isRGB } from '@/colors/isRGB.js';\nimport { setCSSVar } from '@/css-vars/setCSSVar.js';\nimport type { ThemeParams } from '@/components/ThemeParams/ThemeParams.js';\nimport type { MiniApp } from '@/components/MiniApp/MiniApp.js';\nimport type { CleanupFn } from '@/types/index.js';\n\nexport interface GetMiniAppCSSVarNameFn {\n /**\n * @param property - MiniApp property.\n * @returns Computed complete CSS variable name.\n */\n (property: 'bg' | 'header'): string;\n}\n\n/**\n * Creates CSS variables connected with the MiniApps class instance background and header colors\n * based on the passed MiniApp and ThemeParams instances.\n *\n * Created variables by default:\n * - `--tg-bg-color`\n * - `--tg-header-color`\n *\n * Variables are being automatically updated in case, corresponding MiniApp and ThemeParams\n * properties were updated.\n *\n * @param miniApp - MiniApp instance.\n * @param themeParams - ThemeParams instance.\n * @param getVarName - function, returning complete CSS variable name for the specified\n * MiniApp property.\n * @returns Function to stop updating variables.\n */\nexport function bindMiniAppCSSVars(\n miniApp: MiniApp,\n themeParams: ThemeParams,\n getVarName?: GetMiniAppCSSVarNameFn,\n): CleanupFn {\n getVarName ||= (property) => `--tg-${property}-color`;\n\n const headerVar = getVarName('header');\n const bgVar = getVarName('bg');\n\n const actualize = () => {\n const { headerColor } = miniApp;\n\n if (isRGB(headerColor)) {\n setCSSVar(headerVar, headerColor);\n } else {\n const { bgColor, secondaryBgColor } = themeParams;\n\n if (headerColor === 'bg_color' && bgColor) {\n setCSSVar(headerVar, bgColor);\n } else if (headerColor === 'secondary_bg_color' && secondaryBgColor) {\n setCSSVar(headerVar, secondaryBgColor);\n }\n }\n\n setCSSVar(bgVar, miniApp.bgColor)\n };\n\n const listeners = [\n themeParams.on('change', actualize),\n miniApp.on('change', actualize),\n ];\n\n actualize();\n\n return () => listeners.forEach(off => off());\n}\n","import { setCSSVar } from '@/css-vars/setCSSVar.js';\nimport type { ThemeParams } from '@/components/ThemeParams/ThemeParams.js';\nimport type { CleanupFn } from '@/types/index.js';\n\nexport interface GetThemeParamsCSSVarNameFn {\n /**\n * @param property - ThemeParams property.\n * @returns Computed complete CSS variable name.\n */\n (property: string): string;\n}\n\n/**\n * Creates CSS variables connected with the passed instance of the ThemeParams class.\n *\n * By default, created CSS variables names are following the pattern \"--tg-theme-{name}\", where\n * {name} is a theme parameters key name converted from camel case to kebab case.\n *\n * Example:\n * --tg-theme-bg-color\n * --tg-theme-secondary-text-color\n *\n * Variables are being automatically updated in case, corresponding properties updated in\n * the passed ThemeParams instance.\n *\n * @param themeParams - ThemeParams instance.\n * @param getCSSVarName - function, returning complete CSS variable name for the specified\n * ThemeParams property.\n * @returns Function to stop updating variables.\n */\nexport function bindThemeParamsCSSVars(\n themeParams: ThemeParams,\n getCSSVarName?: GetThemeParamsCSSVarNameFn,\n): CleanupFn {\n getCSSVarName ||= (property) => {\n return `--tg-theme-${property.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)}`;\n };\n\n const actualize = () => {\n Object.entries(themeParams.getState()).forEach(([k, v]) => {\n if (v) {\n setCSSVar(getCSSVarName(k), v);\n }\n });\n };\n\n actualize();\n\n return themeParams.on('change', actualize);\n}\n","import { setCSSVar } from '@/css-vars/setCSSVar.js';\nimport type { Viewport } from '@/components/Viewport/Viewport.js';\nimport type { CleanupFn } from '@/types/index.js';\n\nexport interface GetViewportCSSVarNameFn {\n /**\n * @param property - Viewport property.\n * @returns Computed complete CSS variable name.\n */\n (property: 'width' | 'height' | 'stable-height'): string;\n}\n\n/**\n * Accepts Viewport instance and sets CSS variables connected with viewport\n * sizes.\n *\n * Be careful using this function as long as it can impact application\n * performance. Viewport size is changing rather often, this makes CSS\n * variables update, which leads to possible layout redraw.\n *\n * Variables:\n * - `--tg-viewport-height`\n * - `--tg-viewport-width`\n * - `--tg-viewport-stable-height`\n *\n * Variables are being automatically updated in case, corresponding properties\n * updated in passed Viewport instance.\n *\n * @param viewport - Viewport instance.\n * @param getCSSVarName - function, returning complete CSS variable name for the specified\n * Viewport property.\n * @returns Function to stop updating variables.\n */\nexport function bindViewportCSSVars(\n viewport: Viewport,\n getCSSVarName?: GetViewportCSSVarNameFn,\n): CleanupFn {\n getCSSVarName ||= (property) => `--tg-viewport-${property}`;\n const [\n heightVar,\n widthVar,\n stableHeightVar,\n ] = (['height', 'width', 'stable-height'] as const).map((prop) => getCSSVarName(prop));\n const setHeight = () => setCSSVar(heightVar, `${viewport.height}px`);\n const setWidth = () => setCSSVar(widthVar, `${viewport.width}px`);\n const setStableHeight = () => setCSSVar(stableHeightVar, `${viewport.stableHeight}px`);\n\n // TODO: Should probably add debounce or throttle.\n const listeners = [\n viewport.on('change:height', setHeight),\n viewport.on('change:width', setWidth),\n viewport.on('change:stableHeight', setStableHeight),\n ];\n\n setHeight();\n setWidth();\n setStableHeight();\n\n return () => listeners.forEach(off => off());\n}\n","import { on } from '@/bridge/events/listening/on.js';\nimport { postEvent } from '@/bridge/methods/postEvent.js';\n\ninterface CleanupFn {\n (): void;\n}\n\n/**\n * Performs initialization process in the web version of Telegram.\n * @returns Function, which performs cleanup removing all created elements and listeners.\n * @param acceptCustomStyles - true if SDK should accept styles sent from the Telegram web\n * application. This option is only used in web versions of Telegram. Default: false.\n */\nexport function initWeb(acceptCustomStyles = true): CleanupFn {\n const listeners: CleanupFn[] = [\n on('reload_iframe', () => {\n postEvent('iframe_will_reload');\n window.location.reload();\n }),\n ];\n const cleanup: CleanupFn = () => listeners.forEach((l) => l());\n\n if (acceptCustomStyles) {\n const style = document.createElement('style');\n style.id = 'telegram-custom-styles';\n document.head.appendChild(style);\n\n listeners.push(\n on('set_custom_style', (html) => {\n // It is safe to use innerHTML here as long as style tag has a special behavior related\n // to the specified content. In case, any script will be passed here, it will not be\n // executed.\n style.innerHTML = html;\n }),\n () => document.head.removeChild(style),\n );\n }\n\n // Notify Telegram, iframe is ready. This will result in sending style tag html from native\n // application which is used in catchCustomStyles function. We should call this method also\n // to start receiving \"reload_iframe\" events from the Telegram application.\n postEvent('iframe_ready', { reload_supported: true });\n\n return cleanup;\n}\n","/**\n * @returns True, if current environment is server.\n */\nexport function isSSR(): boolean {\n return typeof window === 'undefined';\n}\n","import { request } from '@/bridge/utils/request.js';\nimport { hasWebviewProxy } from '@/env/hasWebviewProxy.js';\n\n/**\n * Returns true in case, current environment is Telegram Mini Apps.\n */\nexport async function isTMA(): Promise<boolean> {\n if (hasWebviewProxy(window)) {\n return true;\n }\n try {\n await request({ method: 'web_app_request_theme', event: 'theme_changed', timeout: 100 });\n return true;\n } catch (e) {\n return false;\n }\n}\n","import { SDKError } from './SDKError.js';\n\n/**\n * @returns True, if passed value is an instance of SDKError.\n * @param value - value to check.\n */\nexport function isSDKError(value: unknown): value is SDKError {\n return value instanceof SDKError;\n}\n","import { isSDKError } from './isSDKError.js';\nimport type { ErrorType } from './errors.js';\n\n/**\n * Returns true if passed value is an SDK error of specified type.\n * @param value - value to check.\n * @param type - error type.\n */\nexport function isSDKErrorOfType(value: unknown, type: ErrorType): boolean {\n return isSDKError(value) && value.type === type;\n}\n","import type {\n BasicNavigatorAnyHistoryItem,\n BasicNavigatorHistoryItem,\n} from '@/navigation/BasicNavigator/types.js';\n\n/**\n * Converts any known history item type to the local one.\n * @param item - history item presented as a string or an object.\n * @param relativePathname - relative pathname.\n */\nexport function prepareItem<Params>(\n item: BasicNavigatorAnyHistoryItem<Params>,\n relativePathname: string,\n): Readonly<BasicNavigatorHistoryItem<Params>> {\n let pathname: string;\n let params: Params | undefined;\n let id: string | undefined;\n\n if (typeof item === 'string') {\n pathname = item;\n } else {\n pathname = item.pathname === undefined\n ? relativePathname\n : item.pathname;\n params = item.params;\n id = item.id;\n }\n\n return Object.freeze({\n id: id || ((Math.random() * 2 ** 14) | 0).toString(16),\n pathname,\n params,\n });\n}\n","import { off } from '@/bridge/events/listening/off.js';\nimport { on } from '@/bridge/events/listening/on.js';\nimport { type PostEvent, postEvent as defaultPostEvent } from '@/bridge/methods/postEvent.js';\nimport { createError } from '@/errors/createError.js';\nimport {\n ERR_NAVIGATION_HISTORY_EMPTY,\n ERR_NAVIGATION_INDEX_INVALID,\n} from '@/errors/errors.js';\nimport { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport { prepareItem } from '@/navigation/BasicNavigator/prepareItem.js';\nimport type {\n BasicNavigatorAnyHistoryItem,\n BasicNavigatorEvents,\n BasicNavigatorHistoryItem,\n} from '@/navigation/BasicNavigator/types.js';\n\ntype Emitter<Params> = EventEmitter<BasicNavigatorEvents<Params>>;\n\nexport class BasicNavigator<Params = {}> {\n /**\n * Navigation history.\n */\n readonly history: Readonly<BasicNavigatorHistoryItem<Params>>[];\n\n private readonly ee: Emitter<Params> = new EventEmitter();\n\n constructor(\n /**\n * Navigation history.\n */\n history: readonly BasicNavigatorAnyHistoryItem<Params>[],\n /**\n * Currently active history item.\n */\n private _index: number,\n /**\n * Function to call Mini Apps methods.\n * @default Global `postEvent` function.\n */\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n if (history.length === 0) {\n throw createError(ERR_NAVIGATION_HISTORY_EMPTY, 'History should not be empty.');\n }\n\n if (_index < 0 || _index >= history.length) {\n throw createError(\n ERR_NAVIGATION_INDEX_INVALID,\n 'Index should not be zero and higher or equal than history size.',\n );\n }\n this.history = history.map((item) => prepareItem(item, ''));\n }\n\n /**\n * True, if current navigator is currently attached.\n */\n private attached = false;\n\n /**\n * Allows this navigator to control the `BackButton` visibility state. It also tracks the\n * `BackButton` clicks and calls the `back` method.\n */\n attach(): void {\n if (!this.attached) {\n this.attached = true;\n this.sync();\n on('back_button_pressed', this.back);\n }\n }\n\n /**\n * Goes to the previous history item.\n */\n back = (): void => this.go(-1);\n\n /**\n * Currently active history item.\n */\n get current(): Readonly<BasicNavigatorHistoryItem<Params>> {\n return this.history[this.index];\n }\n\n /**\n * Prevents current navigator from controlling the BackButton visibility state.\n */\n detach(): void {\n this.attached = false;\n off('back_button_pressed', this.back);\n }\n\n /**\n * Goes to the next history item.\n */\n forward(): void {\n this.go(1);\n }\n\n /**\n * Changes currently active history item index by the specified delta. This method doesn't\n * change index in case, the updated index points to the non-existing history item. This behavior\n * is preserved until the `fit` argument is specified.\n * @param delta - index delta.\n * @param fit - cuts the delta argument to fit the bounds `[0, history.length - 1]`.\n */\n go(delta: number, fit?: boolean): void {\n // Compute the next index.\n const index = this.index + delta;\n\n // Cut the index to be in bounds [0, history.length - 1].\n const fitIndex = Math.min(\n Math.max(0, index),\n this.history.length - 1,\n );\n\n // We perform \"go\" only in case, computed and cut indexes are equal or \"fit\" option was\n // specified.\n if (index === fitIndex || fit) {\n // We are just calling setter to update the index and emit all related events.\n this.replaceAndMove(fitIndex, this.history[fitIndex]);\n }\n }\n\n /**\n * Goes to the specified index. Method does nothing in case, passed index is out of bounds.\n *\n * If \"fit\" option was specified and index is out of bounds, it will be cut to the nearest\n * bound.\n * @param index - target index.\n * @param fit - cuts the index argument to fit the bounds `[0, history.length - 1]`.\n */\n goTo(index: number, fit?: boolean): void {\n this.go(index - this.index, fit);\n }\n\n /**\n * True if navigator has items before the current item.\n */\n get hasPrev(): boolean {\n return this.index > 0;\n }\n\n /**\n * True if navigator has items after the current item.\n */\n get hasNext(): boolean {\n return this.index !== this.history.length - 1;\n }\n\n /**\n * Currently active history item index.\n */\n get index(): number {\n return this._index;\n }\n\n /**\n * Adds new event listener.\n */\n on: Emitter<Params>['on'] = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off: Emitter<Params>['off'] = this.ee.off.bind(this.ee);\n\n /**\n * Adds a new history item removing all after the current one.\n * @param item - item to add.\n */\n push(item: BasicNavigatorAnyHistoryItem<Params>): void {\n if (this.hasNext) {\n this.history.splice(this.index + 1);\n }\n this.replaceAndMove(this.index + 1, prepareItem(item, this.current.pathname));\n }\n\n /**\n * Replaces the current history item.\n * @param item - item to replace the current item with.\n */\n replace(item: BasicNavigatorAnyHistoryItem<Params>): void {\n this.replaceAndMove(this.index, prepareItem(item, this.current.pathname));\n }\n\n /**\n * Sets history item by the specified index.\n * @param index - history item index to replace.\n * @param historyItem - history item to set.\n */\n private replaceAndMove(index: number, historyItem: BasicNavigatorHistoryItem<Params>): void {\n const delta = index - this.index;\n if (!delta && this.current === historyItem) {\n // Nothing changed.\n return;\n }\n\n const from = this.current;\n\n if (this.index !== index) {\n const prevIndex = this._index;\n this._index = index;\n\n // If navigator is attached and back button local visibility state changed, we should\n // notify Telegram app about it.\n if (this.attached && prevIndex > 0 !== index > 0) {\n this.sync();\n }\n }\n\n this.history[index] = historyItem;\n this.ee.emit('change', {\n navigator: this,\n from,\n to: this.current,\n delta,\n });\n }\n\n /**\n * Actualizes the `BackButton` visibility state.\n */\n private sync(): void {\n this.postEvent('web_app_setup_back_button', { is_visible: !!this.index });\n }\n}\n","import type { BasicNavigatorHistoryItem } from '@/navigation/BasicNavigator/types.js';\nimport type {\n BrowserNavigatorHistoryItem,\n BrowserNavigatorHistoryItemParams,\n} from '@/navigation/BrowserNavigator/types.js';\n\n/**\n * Converts basic navigator entry to browser navigator entry.\n */\nexport function basicItemToBrowser<State>(\n {\n params,\n ...rest\n }: BasicNavigatorHistoryItem<BrowserNavigatorHistoryItemParams<State>>,\n): BrowserNavigatorHistoryItem<State> {\n return { ...(params || { hash: '', search: '' }), ...rest };\n}\n","/**\n * Ensures, that specified value starts with the specified prefix. If it doesn't, function appends\n * prefix.\n * @param value - value to check.\n * @param prefix - prefix to add.\n */\nexport function ensurePrefix(value: string, prefix: string): string {\n return value.startsWith(prefix) ? value : `${prefix}${value}`;\n}\n","import { ensurePrefix } from '@/navigation/ensurePrefix.js';\nimport type { URLLike } from '@/navigation/BrowserNavigator/types.js';\n\n/**\n * Safely creates new instance of URL with some predefined protocol and hostname.\n * @param urlOrPath - URL instance or path.\n */\nexport function createSafeURL(urlOrPath: string | Partial<URLLike>): URL {\n return new URL(\n typeof urlOrPath === 'string'\n ? urlOrPath\n : `${urlOrPath.pathname || ''}${ensurePrefix(urlOrPath.search || '', '?')}${ensurePrefix(urlOrPath.hash || '', '#')}`,\n 'http://a',\n );\n}\n","import { createSafeURL } from '@/navigation/createSafeURL.js';\nimport type { URLLike } from '@/navigation/BrowserNavigator/types.js';\n\n/**\n * Extracts path part from a URL.\n * @param urlOrPath - URL instance or path.\n */\nexport function urlToPath(urlOrPath: string | Partial<URLLike>): string {\n const isAbsolute = typeof urlOrPath === 'string'\n ? urlOrPath.startsWith('/')\n : !!(urlOrPath.pathname && urlOrPath.pathname.startsWith('/'));\n const url = createSafeURL(urlOrPath);\n\n return `${isAbsolute ? url.pathname : url.pathname.slice(1)}${url.search}${url.hash}`;\n}\n","import { ensurePrefix } from '@/navigation/ensurePrefix.js';\nimport { urlToPath } from '@/navigation/urlToPath.js';\nimport type { BrowserNavigatorAnyHistoryItem } from '@/navigation/BrowserNavigator/types.js';\n\ninterface PrepareItemResult<State> {\n id?: string;\n pathname: string;\n params: {\n hash: string;\n search: string;\n state?: State;\n };\n}\n\n/**\n * Converts a path, presented as a string to a basic navigator appropriate form.\n * @param path - full path.\n * @param relativePath - relative path.\n * @param state - history item state.\n */\nexport function prepareItem<State>(\n path: string,\n relativePath: string,\n state?: State,\n): PrepareItemResult<State>;\n\n/**\n * Converts a path, presented as an object to a basic navigator appropriate form.\n * @param item - history item data.\n * @param relativePath - relative path.\n */\nexport function prepareItem<State>(\n item: BrowserNavigatorAnyHistoryItem<State>,\n relativePath: string,\n): PrepareItemResult<State>;\n\nexport function prepareItem<State>(\n itemOrPath: string | BrowserNavigatorAnyHistoryItem<State>,\n relativePath: string,\n state?: State,\n): PrepareItemResult<State> {\n let path: string;\n let id: string | undefined;\n\n if (typeof itemOrPath === 'string') {\n path = itemOrPath;\n } else {\n path = urlToPath(itemOrPath);\n state = itemOrPath.state;\n id = itemOrPath.id;\n }\n\n const { pathname, search, hash } = new URL(path, `http://a${ensurePrefix(relativePath, '/')}`);\n return { id, pathname, params: { hash, search, state } };\n}\n","import { onWindow } from '@/events/onWindow.js';\n\n/**\n * Performs window.history.go operation waiting for it to be completed.\n * @param delta - history change delta.\n */\nexport async function go(delta: number): Promise<boolean> {\n if (delta === 0) {\n return true;\n }\n\n // We expect popstate event to occur during some time. Yeah, this seems tricky and not stable,\n // but it seems like we have no other way out. Waiting for Navigation API to be implemented in\n // browsers.\n return Promise.race<boolean>([\n new Promise((res) => {\n const remove = onWindow('popstate', () => {\n remove();\n res(true);\n });\n\n window.history.go(delta);\n }),\n\n // Usually, it takes about 1ms to emit this event, but we use some buffer.\n new Promise((res) => {\n setTimeout(res, 50, false);\n }),\n ]);\n}\n","import { go } from '@/navigation/go.js';\n\n/**\n * Drops current browser history switching browser history cursor to the first one entry.\n */\nexport async function drop(): Promise<void> {\n if (window.history.length <= 1) {\n return;\n }\n\n // Push empty state to cut states we have no access to, placed after the current one.\n window.history.pushState(null, '');\n\n // By this line of code we cover the most recent case, when application is opened in WebView,\n // but not in iframe. Applications opened in WebView have simple browser history containing\n // only entries belonging to the current web application.\n const goPerformed = await go(1 - window.history.length);\n if (goPerformed) {\n return;\n }\n\n // Nevertheless, iframe works a bit different in context of browser history. Calling\n // window.history.length in iframe will return browser history information related to the\n // external web environment too (e.g. browser tab). So, iframe shares the browser history with\n // the external application, but has no access to its history entries. Calling window.history.go\n // pointing out to the entry belonging to the external application will have no impact, so the\n // previous idea with go(1 - ...) will not work.\n //\n // This is the reason why we iteratively call go(-1) to meet the entry which is recognized as\n // the initial one for the current iframe.\n let shouldGoBack = await go(-1);\n while (shouldGoBack) {\n // eslint-disable-next-line no-await-in-loop\n shouldGoBack = await go(-1);\n }\n}\n","import { createSafeURL } from '@/navigation/createSafeURL.js';\nimport type { URLLike } from '@/navigation/BrowserNavigator/types.js';\n\n/**\n * Extracts pathname from the value.\n * @param value - source value.\n */\nexport function getPathname(value: string | Partial<URLLike>): string {\n return createSafeURL(value).pathname;\n}\n","import { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport { BasicNavigator } from '@/navigation/BasicNavigator/BasicNavigator.js';\nimport { basicItemToBrowser } from '@/navigation/BrowserNavigator/basicItemToBrowser.js';\nimport { prepareItem } from '@/navigation/BrowserNavigator/prepareItem.js';\nimport { createSafeURL } from '@/navigation/createSafeURL.js';\nimport { drop } from '@/navigation/drop.js';\nimport { ensurePrefix } from '@/navigation/ensurePrefix.js';\nimport { getPathname } from '@/navigation/getPathname.js';\nimport { go } from '@/navigation/go.js';\nimport { urlToPath } from '@/navigation/urlToPath.js';\nimport type { BasicNavigatorEvents } from '@/navigation/BasicNavigator/types.js';\nimport type {\n BrowserNavigatorAnyHistoryItem,\n BrowserNavigatorConOptions,\n BrowserNavigatorEvents,\n BrowserNavigatorHashMode,\n BrowserNavigatorHistoryItem,\n BrowserNavigatorHistoryItemParams,\n URLLike,\n} from '@/navigation/BrowserNavigator/types.js';\n\nconst CURSOR_VOID = 0;\nconst CURSOR_BACK = 1;\nconst CURSOR_FORWARD = 2;\n\ntype Navigator<State> = BasicNavigator<BrowserNavigatorHistoryItemParams<State>>;\ntype Emitter<State> = EventEmitter<BrowserNavigatorEvents<State>>;\n\nexport class BrowserNavigator<State = {}> {\n private readonly navigator: Navigator<State>;\n\n private readonly ee: Emitter<State> = new EventEmitter();\n\n readonly hashMode: BrowserNavigatorHashMode | null;\n\n readonly base: string;\n\n constructor(\n /**\n * Navigation history.\n */\n history: readonly BrowserNavigatorAnyHistoryItem<State>[],\n /**\n * Currently active history item index.\n */\n index: number,\n { postEvent, hashMode = 'classic', base }: BrowserNavigatorConOptions = {},\n ) {\n this.navigator = new BasicNavigator(\n history.map((item) => prepareItem(item, '/')),\n index,\n postEvent,\n );\n this.navigator.on('change', this.onNavigatorChange);\n this.hashMode = hashMode;\n this.base = getPathname(base || '');\n }\n\n /**\n * Shows whether the navigator is currently attached to the browser history.\n */\n private attached = false;\n\n /**\n * Attaches current navigator to the browser history allowing navigator to manipulate it.\n */\n async attach(): Promise<void> {\n if (!this.attached) {\n this.attached = true;\n this.navigator.attach();\n window.addEventListener('popstate', this.onPopState);\n await this.syncHistory();\n }\n }\n\n /**\n * Goes back in history by 1.\n */\n back(): void {\n this.navigator.back();\n }\n\n /**\n * Detaches current navigator from the browser history.\n */\n detach() {\n this.attached = false;\n this.navigator.detach();\n window.removeEventListener('popstate', this.onPopState);\n }\n\n /**\n * Goes forward in history.\n */\n forward(): void {\n return this.navigator.forward();\n }\n\n /**\n * Current history cursor.\n */\n get index(): number {\n return this.navigator.index;\n }\n\n /**\n * Current history item identifier.\n */\n get id(): string {\n return this.navigator.current.id;\n }\n\n /**\n * Changes currently active history item index by the specified delta. This method doesn't\n * change index in case, the updated index points to the non-existing history item. This behavior\n * is preserved until the `fit` argument is specified.\n * @param delta - index delta.\n * @param fit - cuts the delta argument to fit the bounds `[0, history.length - 1]`.\n */\n go(delta: number, fit?: boolean): void {\n return this.navigator.go(delta, fit);\n }\n\n /**\n * Goes to the specified index. Method does nothing in case, passed index is out of bounds.\n *\n * If \"fit\" option was specified and index is out of bounds, it will be cut to the nearest\n * bound.\n * @param index - target index.\n * @param fit - cuts the index argument to fit the bounds `[0, history.length - 1]`.\n */\n goTo(index: number, fit?: boolean): void {\n this.navigator.goTo(index, fit);\n }\n\n /**\n * Current history item hash.\n * @see URL.hash\n * @example\n * \"\", \"#my-hash\"\n */\n get hash(): string {\n return (this.navigator.current.params || {}).hash || '';\n }\n\n /**\n * True if navigator has items before the current item.\n */\n get hasPrev(): boolean {\n return this.navigator.hasPrev;\n }\n\n /**\n * True if navigator has items after the current item.\n */\n get hasNext(): boolean {\n return this.navigator.hasNext;\n }\n\n /**\n * Navigation history.\n */\n get history(): BrowserNavigatorHistoryItem<State>[] {\n return this.navigator.history.map(basicItemToBrowser);\n }\n\n /**\n * Handles the window \"popstate\" event.\n * @param state - event state.\n */\n private onPopState = ({ state }: PopStateEvent) => {\n // In case state is null, we recognize current event as occurring whenever user clicks\n // any anchor.\n // TODO: Should we do it?\n if (state === null) {\n return this.push(this.parsePath(window.location.href));\n }\n\n // There is only one case when state can be CURSOR_VOID - when history contains\n // only one element. In this case, we should return user to the current history element.\n if (state === CURSOR_VOID) {\n window.history.forward();\n } else if (state === CURSOR_BACK) {\n this.back();\n }\n if (state === CURSOR_FORWARD) {\n this.forward();\n }\n };\n\n /**\n * Underlying navigator change event listener.\n */\n private onNavigatorChange = async ({\n to,\n from,\n delta,\n }: BasicNavigatorEvents<BrowserNavigatorHistoryItemParams<State>>['change']) => {\n // If this navigator is attached to the browser history, we should synchronize.\n if (this.attached) {\n await this.syncHistory();\n }\n this.ee.emit('change', {\n delta,\n from: basicItemToBrowser(from),\n to: basicItemToBrowser(to),\n navigator: this,\n });\n };\n\n /**\n * Adds new event listener.\n */\n on: Emitter<State>['on'] = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off: Emitter<State>['off'] = this.ee.off.bind(this.ee);\n\n /**\n * Path, including pathname, search and hash.\n * @example Pathname only.\n * \"/pathname\"\n * @example Pathname + search.\n * \"/pathname?search\"\n * @example Pathname + hash.\n * \"/pathname#hash\"\n * @example Pathname + search + hash.\n * \"/pathname?search#hash\"\n */\n get path(): string {\n return urlToPath(this);\n }\n\n /**\n * Current pathname. Always starts with the slash.\n * @see URL.pathname\n * @example\n * \"/\", \"/abc\"\n */\n get pathname(): string {\n return this.navigator.current.pathname;\n }\n\n /**\n * Depending on the current navigation type, parses incoming path and returns it presented as\n * an object. In other words, this method parses the passed path and returns object, describing\n * how the navigator \"sees\" it.\n *\n * @example Hash mode is omitted.\n * parsePath('/abc?a=1#hash');\n * // { pathname: '/abc', search: '?a=1', hash: '#hash' }\n * parsePath('http://example.com/abc?a=1#hash');\n * // { pathname: '/abc', search: '?a=1', hash: '#hash' }\n *\n * @example Hash mode is enabled.\n * parsePath('/abc?a=1#tma?is=cool#yeah');\n * // { pathname: '/tma', search: '?is=cool', hash: '#yeah' }\n * parsePath('http://example.com/abc?a=1#tma?is=cool#yeah');\n * // { pathname: '/tma', search: '?is=cool', hash: '#yeah' }\n */\n parsePath(path: string | URL): URLLike {\n let url = createSafeURL(path);\n if (this.hashMode) {\n url = createSafeURL(url.hash.slice(1));\n }\n\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash,\n };\n }\n\n /**\n * Pushes new history item. Method replaces all entries after the current one with the one\n * being pushed. Take a note, that passed item is always relative. In case, you want to use\n * it as an absolute one, use the \"/\" prefix. Example: \"/absolute\", { pathname: \"/absolute\" }.\n *\n * To create a final path, navigator uses a method, used in the URL class constructor, resolving\n * a path based on the current one.\n * @param path - entry path.\n * @param state - entry state.\n *\n * @example Pushing an absolute path.\n * push(\"/absolute\"); // \"/absolute\"\n *\n * @example Pushing a relative path.\n * push(\"relative\"); // \"/home/root\" -> \"/home/relative\"\n *\n * @example Pushing query parameters.\n * push(\"/absolute?my-param=1\"); // \"/home/root\" -> \"/absolute?my-param=1\"\n * push(\"relative?my-param=1\"); // \"/home/root\" -> \"/home/relative?my-param=1\"\n * push(\"?my-param=1\"); // \"/home\" -> \"/home?my-param=1\"\n *\n * @example Pushing hash.\n * push(\"#my-hash\"); // \"/home\" -> \"/home#my-hash\"\n * push(\"relative#my-hash\"); // \"/home/root\" -> \"/home/relative#my-hash\"\n *\n * @example Pushing state.\n * push(\"\", { state: 'my-state' }); \"/home/root\" -> \"/home/root\"\n * push({ state: 'my-state' }); \"/home/root\" -> \"/home/root\"\n */\n push(path: string, state?: State): void;\n push(item: BrowserNavigatorAnyHistoryItem<State>): void;\n push(itemOrPath: string | BrowserNavigatorAnyHistoryItem<State>, fnState?: State): void {\n const item = prepareItem(itemOrPath, this.path);\n const { state = fnState } = item.params;\n this.navigator.push({ ...item, params: { ...item.params, state } });\n }\n\n /**\n * Replaces the current history item. Has the same logic as the `push` method.\n * @param path - entry path.\n * @param state - entry state.\n * @see push\n */\n replace(path: string, state?: State): void;\n replace(item: BrowserNavigatorAnyHistoryItem<State>): void;\n replace(itemOrPath: string | BrowserNavigatorAnyHistoryItem<State>, fnState?: State): void {\n const item = prepareItem(itemOrPath, this.path);\n const { state = fnState } = item.params;\n this.navigator.replace({ ...item, params: { ...item.params, state } });\n }\n\n /**\n * Combines the navigator `base` property with the passed path data applying the navigator\n * navigation mode.\n * @param value - path presented as string or URLLike.\n */\n renderPath(value: string | URLLike): string {\n const path = (this.base.length === 1 ? '' : this.base)\n + ensurePrefix(urlToPath(value), '/');\n\n return this.hashMode\n ? ensurePrefix(path.slice(1), this.hashMode === 'classic' ? '#' : '#/')\n : path;\n }\n\n /**\n * Synchronizes current navigator state with browser history.\n */\n private async syncHistory(): Promise<void> {\n // Remove history change event listener to get rid of side effects related to the possible\n // future calls of history.go.\n window.removeEventListener('popstate', this.onPopState);\n\n const { state } = this;\n const path = this.renderPath(this);\n\n // Drop the browser history and work with the clean one.\n await drop();\n\n if (this.hasPrev && this.hasNext) {\n // We have both previous and next elements. History should be:\n // [back, *current*, forward]\n window.history.replaceState(CURSOR_BACK, '');\n window.history.pushState(state, '', path);\n window.history.pushState(CURSOR_FORWARD, '');\n\n await go(-1);\n } else if (this.hasPrev) {\n // We have only previous element. History should be:\n // [back, *current*]\n window.history.replaceState(CURSOR_BACK, '');\n window.history.pushState(state, '', path);\n } else if (this.hasNext) {\n // We have only next element. History should be:\n // [*current*, forward]\n window.history.replaceState(state, path);\n window.history.pushState(CURSOR_FORWARD, '');\n\n await go(-1);\n } else {\n // We have no back and next elements. History should be:\n // [void, *current*]\n window.history.replaceState(CURSOR_VOID, '');\n window.history.pushState(state, '', path);\n }\n\n window.addEventListener('popstate', this.onPopState);\n }\n\n /**\n * Current query parameters.\n * @see URL.search\n * @example\n * \"\", \"?\", \"?a=1\"\n */\n get search(): string {\n return (this.navigator.current.params || {}).search || '';\n }\n\n /**\n * Current history item state.\n */\n get state(): State | undefined {\n return (this.navigator.current.params || {}).state;\n }\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_INVALID_PATH_BASE } from '@/errors/errors.js';\nimport { BrowserNavigator } from '@/navigation/BrowserNavigator/BrowserNavigator.js';\nimport { getPathname } from '@/navigation/getPathname.js';\nimport { urlToPath } from '@/navigation/urlToPath.js';\nimport type { BrowserNavigatorConOptions } from '@/navigation/BrowserNavigator/types.js';\n\nexport function createBrowserNavigatorFromLocation<State>(\n options?: BrowserNavigatorConOptions,\n): BrowserNavigator<State> {\n options ||= {};\n const { href, hash } = window.location;\n\n let path = urlToPath(\n options.hashMode === null\n // Hash mode is explicitly disabled. We are working with the usual location path.\n ? href\n // If hash mode is enabled, we should create a navigator based on the location's hash.\n // In this case we have 2 possible situations:\n // 1. Hash contains only launch parameters. Example:\n // #tgWebAppData=...&tgWebAppPlatform=...&...\n // Here we should mark the launch parameters as query parameters and have pathname \"/\" as\n // the initial one.\n //\n // 2. Hash contains value, passed from above and launch parameters as query parameters.\n // For instance, we could have such a URL:\n // https://t.me/mybot/myapp#my-hash\n // In this case, the Mini App will be opened with this URL:\n // https://example.com/#my-hash?tgWebAppData=...&tgWebAppPlatform=...&...\n : hash.includes('?') ? hash.slice(1) : `?${hash.slice(1)}`,\n );\n\n // If some base was specified, we should check if computed path starts with this base. In\n // case it does, it should be removed from the path. Otherwise, an error must be thrown.\n const base = options.base ? getPathname(options.base) : undefined;\n if (base) {\n if (!path.startsWith(base)) {\n throw createError(\n ERR_INVALID_PATH_BASE,\n `Path \"${path}\" expected to be starting with \"${base}\"`,\n );\n }\n path = path.slice(base.length);\n }\n\n return new BrowserNavigator<State>([path], 0, options);\n}\n","/**\n * @param value - string to take hash part from.\n * @returns String after the first met \"#\" symbol. In case, value doesn't contain hashtag, the\n * function will return null.\n *\n * @example No hash.\n * getHash('/path'); // null\n *\n * @example Has hash.\n * getHash('/path#abc'); // 'abc'\n *\n * @example Has double hash.\n * getHash('/path#abc#another'); // 'abc#another'\n */\nexport function getHash(value: string): string | null {\n const match = value.match(/#(.+)/);\n return match ? match[1] : null;\n}\n","import { BrowserNavigatorConOptions } from '@/navigation/BrowserNavigator/types.js';\nimport { BrowserNavigator } from '@/navigation/BrowserNavigator/BrowserNavigator.js';\nimport { isPageReload } from '@/navigation/isPageReload.js';\nimport {\n createBrowserNavigatorFromLocation\n} from '@/navigation/BrowserNavigator/createBrowserNavigatorFromLocation.js';\n\n\nfunction instantiate<State>(\n sessionStorageKey: string,\n options?: BrowserNavigatorConOptions,\n): BrowserNavigator<State> {\n // If page was reloaded, we assume that navigator had to previously save its state in the\n // session storage.\n if (isPageReload()) {\n const stateRaw = sessionStorage.getItem(sessionStorageKey);\n if (stateRaw) {\n try {\n const { index, history } = JSON.parse(stateRaw);\n return new BrowserNavigator(history, index, options);\n } catch (e) {\n console.error('Unable to restore hash navigator state.', e);\n }\n }\n }\n\n // In case, we could not restore its state, or it is a fresh start, we can create an empty\n // navigator. We are creating BrowserNavigator from the window.location.\n return createBrowserNavigatorFromLocation(options);\n}\n\n/**\n * Initializes a standard Mini Apps navigator.\n * @param sessionStorageKey - session storage key, containing the navigator state.\n * @param options - additional BrowserNavigator options.\n */\nexport function initNavigator<State>(\n sessionStorageKey: string,\n options?: BrowserNavigatorConOptions,\n): BrowserNavigator<State> {\n const navigator = instantiate<State>(sessionStorageKey, options);\n\n const saveState = () => sessionStorage.setItem(sessionStorageKey, JSON.stringify({\n index: navigator.index,\n history: navigator.history,\n }));\n\n // Whenever navigator changes its state, we save it in the session storage.\n navigator.on('change', saveState);\n\n // Save the initial state to make sure nothing will break when the page was reloaded.\n saveState();\n\n return navigator;\n}\n"],"names":["createSingleton","create","onReset","cached","reset","unsubscribe","listener","ee","miniAppsEventEmitter","count","resetMiniAppsEventEmitter","subscribe","Logger","scope","options","level","args","now","date","textColor","bgColor","commonCss","logger","debugEnabled","onEvent","name","payload","setDebug","enable","log","EventEmitter","__publicField","event","l","once","listeners","i","onWindow","type","createCleanup","fns","called","cache","fn","clean","SDKError","message","cause","createError","ERR_METHOD_UNSUPPORTED","ERR_METHOD_PARAMETER_UNSUPPORTED","ERR_UNKNOWN_ENV","ERR_INVOKE_CUSTOM_METHOD_RESPONSE","ERR_TIMED_OUT","ERR_UNEXPECTED_TYPE","ERR_PARSE","ERR_NAVIGATION_HISTORY_EMPTY","ERR_NAVIGATION_INDEX_INVALID","ERR_NAVIGATION_ITEM_INVALID","ERR_SSR_INIT","ERR_INVALID_PATH_BASE","createTypeError","ValueParser","parser","isOptional","value","createValueParserGenerator","boolean","asString","parseBySchema","schema","getField","result","field","definition","from","definitionType","parsedValue","error","toRecord","formattedValue","json","record","number","num","isRGB","isRGBShort","toRGB","color","match","acc","component","formatted","string","rgb","parseMessage","v","cleanupEventHandlers","prop","emitMiniAppsEvent","eventType","eventData","defineEventHandlers","path","pointer","item","idx","arr","parsers","k","createMiniAppsEventEmitter","subEmitter","mainEmitter","cleanup","data","get","emitter","off","on","isRecord","compareVersions","a","b","aParts","bParts","len","aVal","bVal","versionLessOrEqual","supports","method","paramOrVersion","inVersion","hasExternalNotify","hasWebviewProxy","isIframe","currentTargetOrigin","setTargetOrigin","targetOrigin","postEvent","paramsOrOptions","postOptions","targetOriginFn","createPostEvent","version","params","validateParam","captureSameReq","reqId","req_id","createTimeoutError","timeout","withTimeout","funcOrPromise","_","rej","request","resolve","promise","res","capture","defaultPostEvent","stoppers","ev","stop","invokeCustomMethod","requestId","classNames","values","entry","mergeClassNames","partials","partial","key","className","isColorDark","modifier","dec","State","state","keyOrState","keyValue","WithStateUtils","shape","createSupportsFn","WithSupportsAndStateUtils","stateShape","supportsSchema","BackButton","isVisible","visible","searchParams","paramValue","chat","user","initData","keyToLocal","keyToExternal","themeParams","rgbOptional","parseLaunchParams","retrieveFromUrl","urlString","retrieveFromLocation","getFirstNavigationEntry","retrieveFromPerformance","navigationEntry","formatKey","m","setStorageValue","getStorageValue","retrieveFromStorage","serializeThemeParams","serializeLaunchParams","initDataRaw","platform","showSettings","startParam","botInline","saveToStorage","retrieveLaunchParams","retrieve","lp","isPageReload","createRequestIdGenerator","createReqId","createComponentInitFn","factoryStaticOrSK","factoryDynamic","factoryOptions","addCleanup","cleanedUp","bindChange","initBackButton","WithSupportsAndTrackableState","formatEvent","BiometryManager","rest","reason","token","response","requestBiometryInfo","initBiometryManager","WithTrackableState","ClosingBehavior","isConfirmationNeeded","initClosingBehavior","WithSupports","parseArray","ArrayParser","itemParser","array","parserTypeName","objectFromKeys","keys","CloudStorage","createRequestId","keyOrKeys","initCloudStorage","HapticFeedback","style","initHapticFeedback","InitData","canSendAfter","initInitData","parseInitData","Invoice","isOpened","urlOrSlug","slug","hostname","pathname","initInvoice","MainButton","isEnabled","isLoaderVisible","text","initMainButton","contact","createSupportsParamFn","tmaMethod","param","sleep","duration","MiniApp","supportsOriginal","deadlineAt","sleepTime","status","size","chatTypes","initMiniApp","preparePopupParams","title","buttons","preparedButtons","id","Popup","buttonId","initPopup","QRScanner","initQRScanner","SettingsButton","initSettingsButton","parseThemeParams","ThemeParams","initThemeParams","tp","requestThemeParams","Utils","url","tryInstantView","formattedUrl","search","initUtils","requestViewport","isExpanded","isStateStable","truncate","Viewport","stableHeight","height","width","truncatedHeight","initViewport","viewport","setCSSVar","bindMiniAppCSSVars","miniApp","getVarName","property","headerVar","bgVar","actualize","headerColor","secondaryBgColor","bindThemeParamsCSSVars","getCSSVarName","bindViewportCSSVars","heightVar","widthVar","stableHeightVar","setHeight","setWidth","setStableHeight","initWeb","acceptCustomStyles","html","isSSR","isTMA","isSDKError","isSDKErrorOfType","prepareItem","relativePathname","BasicNavigator","history","_index","delta","fit","index","fitIndex","historyItem","prevIndex","basicItemToBrowser","ensurePrefix","prefix","createSafeURL","urlOrPath","urlToPath","isAbsolute","itemOrPath","relativePath","hash","go","remove","drop","shouldGoBack","getPathname","CURSOR_VOID","CURSOR_BACK","CURSOR_FORWARD","BrowserNavigator","hashMode","base","to","fnState","createBrowserNavigatorFromLocation","href","getHash","instantiate","sessionStorageKey","stateRaw","e","initNavigator","navigator","saveState"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/misc/createSingleton.ts","../src/bridge/events/listening/unsubscribe.ts","../src/bridge/events/listening/subscribe.ts","../src/logger/Logger.ts","../src/debug/debug.ts","../src/events/event-emitter/EventEmitter.ts","../src/events/onWindow.ts","../src/misc/createCleanup.ts","../src/errors/SDKError.ts","../src/errors/createError.ts","../src/errors/errors.ts","../src/parsing/createTypeError.ts","../src/parsing/ValueParser/ValueParser.ts","../src/parsing/createValueParserGenerator.ts","../src/parsing/parsers/boolean.ts","../src/parsing/parseBySchema.ts","../src/parsing/toRecord.ts","../src/parsing/parsers/json.ts","../src/parsing/parsers/number.ts","../src/colors/isRGB.ts","../src/colors/isRGBShort.ts","../src/colors/toRGB.ts","../src/parsing/parsers/string.ts","../src/parsing/parsers/rgb.ts","../src/bridge/parseMessage.ts","../src/bridge/events/event-handlers/cleanupEventHandlers.ts","../src/bridge/events/event-handlers/emitMiniAppsEvent.ts","../src/bridge/events/event-handlers/defineEventHandlers.ts","../src/bridge/events/event-emitter/createMiniAppsEventEmitter.ts","../src/bridge/events/event-emitter/singleton.ts","../src/bridge/events/listening/off.ts","../src/bridge/events/listening/on.ts","../src/misc/isRecord.ts","../src/version/compareVersions.ts","../src/supports/supports.ts","../src/env/hasExternalNotify.ts","../src/env/hasWebviewProxy.ts","../src/env/isIframe.ts","../src/bridge/target-origin.ts","../src/bridge/methods/postEvent.ts","../src/bridge/methods/createPostEvent.ts","../src/bridge/utils/captureSameReq.ts","../src/timeout/createTimeoutError.ts","../src/timeout/withTimeout.ts","../src/bridge/utils/request.ts","../src/bridge/utils/invokeCustomMethod.ts","../src/classnames/classNames.ts","../src/classnames/mergeClassNames.ts","../src/colors/isColorDark.ts","../src/classes/State/State.ts","../src/classes/WithStateUtils.ts","../src/supports/createSupportsFn.ts","../src/classes/WithSupportsAndStateUtils.ts","../src/components/BackButton/BackButton.ts","../src/parsing/parsers/date.ts","../src/parsing/parsers/searchParams.ts","../src/components/InitData/parsers/chat.ts","../src/components/InitData/parsers/user.ts","../src/components/InitData/parsers/initData.ts","../src/components/ThemeParams/keys.ts","../src/components/ThemeParams/parsing/themeParams.ts","../src/launch-params/parseLaunchParams.ts","../src/launch-params/retrieveFromUrl.ts","../src/launch-params/retrieveFromLocation.ts","../src/navigation/getFirstNavigationEntry.ts","../src/launch-params/retrieveFromPerformance.ts","../src/storage/storage.ts","../src/launch-params/retrieveFromStorage.ts","../src/components/ThemeParams/parsing/serializeThemeParams.ts","../src/launch-params/serializeLaunchParams.ts","../src/launch-params/saveToStorage.ts","../src/launch-params/retrieveLaunchParams.ts","../src/navigation/isPageReload.ts","../src/request-id/createRequestIdGenerator.ts","../src/misc/createComponentInitFn/createComponentInitFn.ts","../src/components/BackButton/initBackButton.ts","../src/classes/WithSupportsAndTrackableState.ts","../src/components/BiometryManager/formatEvent.ts","../src/components/BiometryManager/BiometryManager.ts","../src/components/BiometryManager/requestBiometryInfo.ts","../src/components/BiometryManager/initBiometryManager.ts","../src/classes/WithTrackableState.ts","../src/components/ClosingBehavior/ClosingBehavior.ts","../src/components/ClosingBehavior/initClosingBehavior.ts","../src/classes/WithSupports.ts","../src/parsing/ArrayParser/ArrayParser.ts","../src/parsing/parsers/array.ts","../src/components/CloudStorage/CloudStorage.ts","../src/components/CloudStorage/initCloudStorage.ts","../src/components/HapticFeedback/HapticFeedback.ts","../src/components/HapticFeedback/initHapticFeedback.ts","../src/components/InitData/InitData.ts","../src/components/InitData/initInitData.ts","../src/components/InitData/parseInitData.ts","../src/components/Invoice/Invoice.ts","../src/components/Invoice/initInvoice.ts","../src/components/MainButton/MainButton.ts","../src/components/MainButton/initMainButton.ts","../src/components/MiniApp/parsing/contact.ts","../src/supports/createSupportsParamFn.ts","../src/timeout/sleep.ts","../src/components/MiniApp/MiniApp.ts","../src/components/MiniApp/initMiniApp.ts","../src/components/Popup/preparePopupParams.ts","../src/components/Popup/Popup.ts","../src/components/Popup/initPopup.ts","../src/components/QRScanner/QRScanner.ts","../src/components/QRScanner/initQRScanner.ts","../src/components/SettingsButton/SettingsButton.ts","../src/components/SettingsButton/initSettingsButton.ts","../src/components/ThemeParams/parsing/parseThemeParams.ts","../src/components/ThemeParams/ThemeParams.ts","../src/components/ThemeParams/initThemeParams.ts","../src/components/ThemeParams/requestThemeParams.ts","../src/components/Utils/Utils.ts","../src/components/Utils/initUtils.ts","../src/components/Viewport/requestViewport.ts","../src/components/Viewport/Viewport.ts","../src/components/Viewport/initViewport.ts","../src/css-vars/setCSSVar.ts","../src/css-vars/bindMiniAppCSSVars.ts","../src/css-vars/bindThemeParamsCSSVars.ts","../src/css-vars/bindViewportCSSVars.ts","../src/env/initWeb.ts","../src/env/isSSR.ts","../src/env/isTMA.ts","../src/env/mockTelegramEnv.ts","../src/errors/isSDKError.ts","../src/errors/isSDKErrorOfType.ts","../src/navigation/BasicNavigator/prepareItem.ts","../src/navigation/BasicNavigator/BasicNavigator.ts","../src/navigation/BrowserNavigator/basicItemToBrowser.ts","../src/navigation/ensurePrefix.ts","../src/navigation/createSafeURL.ts","../src/navigation/urlToPath.ts","../src/navigation/BrowserNavigator/prepareItem.ts","../src/navigation/go.ts","../src/navigation/drop.ts","../src/navigation/getPathname.ts","../src/navigation/BrowserNavigator/BrowserNavigator.ts","../src/navigation/BrowserNavigator/createBrowserNavigatorFromLocation.ts","../src/navigation/getHash.ts","../src/navigation/initNavigator.ts"],"sourcesContent":["/**\n * Creates resettable singleton. We mostly need it for test purposes.\n * @param create - function which creates singleton entity.\n * @param onReset - function which will be called in case, singleton was reset.\n */\nexport function createSingleton<T>(\n create: (reset: () => void) => T,\n onReset?: (entity: T) => void,\n): [\n /**\n * Returns singleton entity.\n */\n get: () => T,\n /**\n * Resets last stored entity.\n */\n reset: () => void,\n] {\n let cached: T | undefined;\n const reset = () => {\n cached !== undefined && onReset && onReset(cached);\n cached = undefined;\n };\n\n return [() => (cached === undefined ? cached = create(reset) : cached), reset];\n}\n","import { miniAppsEventEmitter, resetMiniAppsEventEmitter } from '../event-emitter/singleton.js';\nimport type { MiniAppsSubscribeListener } from '../types.js';\n\n/**\n * Removes global event listener.\n * @param listener - event listener.\n */\nexport function unsubscribe(listener: MiniAppsSubscribeListener): void {\n const ee = miniAppsEventEmitter();\n const { count } = ee;\n ee.unsubscribe(listener);\n\n // If event emitter now has no listeners, we can make a cleanup.\n if (count && !ee.count) {\n resetMiniAppsEventEmitter();\n }\n}\n","import type { RemoveEventListenerFn } from '@/events/types.js';\n\nimport { miniAppsEventEmitter } from '../event-emitter/singleton.js';\nimport { unsubscribe } from '../listening/unsubscribe.js';\nimport type { MiniAppsSubscribeListener } from '../types.js';\n\n/**\n * Subscribes to all events sent from the native Telegram application.\n * @param listener - event listener to bind.\n * @returns Function to remove bound event listener.\n */\nexport function subscribe(listener: MiniAppsSubscribeListener): RemoveEventListenerFn {\n miniAppsEventEmitter().subscribe(listener);\n return () => unsubscribe(listener);\n}\n","/**\n * Message log level.\n */\nexport type LogLevel = 'log' | 'error';\n\nexport interface LoggerOptions {\n bgColor?: string;\n textColor?: string;\n}\n\nexport class Logger implements Pick<Console, 'log' | 'error'> {\n constructor(\n private readonly scope: string,\n private readonly options: LoggerOptions = {},\n ) {\n }\n\n /**\n * Prints message into a console in case, logger is currently enabled.\n * @param level - log level.\n * @param args - arguments.\n */\n private print(level: LogLevel, ...args: any[]): void {\n const now = new Date();\n const date = Intl\n .DateTimeFormat('en-GB', {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n fractionalSecondDigits: 3,\n timeZone: 'UTC',\n })\n .format(now);\n\n const { textColor, bgColor } = this.options;\n const commonCss = 'font-weight: bold;padding: 0 5px;border-radius:5px';\n\n console[level](\n `%c${date}%c / %c${this.scope}`,\n `${commonCss};background-color: lightblue;color:black`,\n '',\n `${commonCss};${textColor ? `color:${textColor};` : ''}${bgColor ? `background-color:${bgColor}` : ''}`,\n ...args,\n );\n }\n\n /**\n * Prints error message into a console.\n * @param args\n */\n error(...args: any[]): void {\n this.print('error', ...args);\n }\n\n /**\n * Prints log message into a console.\n * @param args\n */\n log(...args: any[]): void {\n this.print('log', ...args);\n }\n}\n","import { subscribe } from '@/bridge/events/listening/subscribe.js';\nimport { unsubscribe } from '@/bridge/events/listening/unsubscribe.js';\nimport { Logger } from '@/logger/Logger.js';\nimport type { MiniAppsSubscribeListener } from '@/bridge/events/types.js';\n\nexport const logger = new Logger('SDK', {\n bgColor: 'forestgreen',\n textColor: 'white',\n});\n\nlet debugEnabled = false;\n\nconst onEvent: MiniAppsSubscribeListener = ({ name, payload }) => {\n logger.log('Event received:', payload ? { name, payload } : { name });\n};\n\n/**\n * Sets new debug mode. Enabling debug mode leads to printing additional messages in the console,\n * related to the processes inside the package.\n * @param enable - should debug be enabled.\n */\nexport function setDebug(enable: boolean): void {\n if (debugEnabled !== enable) {\n debugEnabled = enable;\n enable ? subscribe(onEvent) : unsubscribe(onEvent);\n }\n}\n\n/**\n * Logs info message into the console.\n * @param args - additional arguments.\n */\nexport function log(...args: any[]): void {\n if (debugEnabled) {\n logger.log(...args);\n }\n}\n","import type { RemoveEventListenerFn } from '../types.js';\nimport type {\n EmptyEventName,\n EventListener,\n EventName,\n EventParams,\n NonEmptyEventName,\n SubscribeListener,\n} from './types.js';\n\nexport class EventEmitter<Schema> {\n private readonly listeners: Map<\n string,\n [listener: EventListener<any>, once?: boolean][]\n > = new Map();\n\n private listenersCount = 0;\n\n private subscribeListeners: SubscribeListener<Schema>[] = [];\n\n /**\n * Removes all event listeners.\n */\n clear() {\n this.listeners.clear();\n this.subscribeListeners = [];\n }\n\n /**\n * Returns count of bound listeners.\n */\n get count(): number {\n return this.listenersCount + this.subscribeListeners.length;\n }\n\n /**\n * Emits known event which has no parameters.\n * @param event - event name.\n */\n emit<E extends EmptyEventName<Schema>>(event: E): void;\n\n /**\n * Emits known event which has parameters.\n * @param event - event name.\n * @param args - list of event listener arguments.\n */\n emit<E extends NonEmptyEventName<Schema>>(event: E, ...args: EventParams<Schema[E]>): void;\n\n emit(event: EventName<Schema>, ...args: any[]): void {\n this.subscribeListeners.forEach((l) => l({\n event,\n args: args as EventParams<Schema[EventName<Schema>]>,\n }));\n\n const listeners = this.listeners.get(event) || [];\n\n listeners.forEach(([listener, once]) => {\n listener(...args);\n if (once) {\n this.off(event, listener);\n }\n });\n }\n\n /**\n * Adds new event listener.\n * @param event - event name.\n * @param listener - event listener.\n * @param once - should listener be called only once.\n * @returns Function to remove bound event listener.\n */\n on<E extends EventName<Schema>>(\n event: E,\n listener: EventListener<Schema[E]>,\n once?: boolean,\n ): RemoveEventListenerFn {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n this.listeners.set(event, listeners = []);\n }\n\n listeners.push([listener, once]);\n this.listenersCount += 1;\n\n return () => this.off(event, listener);\n }\n\n /**\n * Removes event listener. In case, specified listener was bound several times, it removes\n * only a single one.\n * @param event - event name.\n * @param listener - event listener.\n */\n off<E extends EventName<Schema>>(event: E, listener: EventListener<Schema[E]>): void {\n const listeners = this.listeners.get(event) || [];\n for (let i = 0; i < listeners.length; i += 1) {\n if (listener === listeners[i][0]) {\n listeners.splice(i, 1);\n this.listenersCount -= 1;\n return;\n }\n }\n }\n\n /**\n * Adds a new event listener for all events.\n * @param listener - event listener.\n * @returns Function to remove event listener.\n */\n subscribe(listener: SubscribeListener<Schema>): RemoveEventListenerFn {\n this.subscribeListeners.push(listener);\n return () => this.unsubscribe(listener);\n }\n\n /**\n * Removes global event listener. In case, specified listener was bound several times, it removes\n * only a single one.\n * @param listener - event listener.\n */\n unsubscribe(listener: SubscribeListener<Schema>): void {\n for (let i = 0; i < this.subscribeListeners.length; i += 1) {\n if (this.subscribeListeners[i] === listener) {\n this.subscribeListeners.splice(i, 1);\n return;\n }\n }\n }\n}\n","import type { RemoveEventListenerFn } from './types.js';\n\n/**\n * Adds new event listener using window.addEventListener.\n * @param type - event name.\n * @param listener - event listener.\n * @param options - listening options.\n * @returns Function to remove event listener.\n */\nexport function onWindow<K extends keyof WindowEventMap>(\n type: K,\n listener: (this: Window, ev: WindowEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n): RemoveEventListenerFn {\n window.addEventListener(type, listener, options);\n return () => window.removeEventListener(type, listener, options);\n}\n","import { CleanupFn } from '@/types/index.js';\n\n/**\n * Returns a tuple, containing function to add cleanup, call cleanup, and flag showing whether\n * cleanup was called. Cleanup will not be performed in case, it was done before.\n */\nexport function createCleanup(...fns: CleanupFn[]): [\n add: (fn: CleanupFn) => void,\n call: () => void,\n cleanedUp: boolean,\n] {\n let called = false;\n const cache: CleanupFn[] = [...fns];\n\n return [\n (fn) => !called && cache.push(fn),\n () => {\n if (!called) {\n called = true;\n cache.forEach(clean => clean());\n }\n },\n called,\n ];\n}","import type { ErrorType } from './errors.js';\n\n/**\n * Error used across the SDK.\n */\nexport class SDKError extends Error {\n constructor(public readonly type: ErrorType, message?: string, cause?: unknown) {\n super(message, { cause });\n Object.setPrototypeOf(this, SDKError.prototype);\n }\n}\n","import { SDKError } from './SDKError.js';\nimport type { ErrorType } from './errors.js';\n\n/**\n * Creates new error using specified type and message.\n * @param type - error code.\n * @param message - error message.\n * @param cause - original error.\n */\nexport function createError(type: ErrorType, message: string, cause?: unknown): SDKError {\n return new SDKError(type, message, cause);\n}\n","/**\n * Specified Mini Apps method is unsupported.\n */\nexport const ERR_METHOD_UNSUPPORTED = 'ERR_METHOD_UNSUPPORTED';\n\n/**\n * Specified Mini Apps method parameter is unsupported.\n */\nexport const ERR_METHOD_PARAMETER_UNSUPPORTED = 'ERR_METHOD_PARAMETER_UNSUPPORTED';\n\n/**\n * Current environment is not Telegram application.\n */\nexport const ERR_UNKNOWN_ENV = 'ERR_UNKNOWN_ENV';\n\n/**\n * Telegram application returned and error while invoking custom method.\n */\nexport const ERR_INVOKE_CUSTOM_METHOD_RESPONSE = 'ERR_INVOKE_CUSTOM_METHOD_RESPONSE';\n\n/**\n * Timeout reached.\n */\nexport const ERR_TIMED_OUT = 'ERR_TIMED_OUT';\n\n/**\n * Value has unexpected type.\n */\nexport const ERR_UNEXPECTED_TYPE = 'ERR_UNEXPECTED_TYPE';\n\n/**\n * Something went wrong during value parsing.\n */\nexport const ERR_PARSE = 'ERR_PARSE';\n\n/**\n * Navigation entries list is empty.\n */\nexport const ERR_NAVIGATION_HISTORY_EMPTY = 'ERR_NAVIGATION_LIST_EMPTY';\n\n/**\n * Navigation entries cursor is invalid.\n */\nexport const ERR_NAVIGATION_INDEX_INVALID = 'ERR_NAVIGATION_CURSOR_INVALID';\n\n/**\n * Navigation entries item is invalid.\n */\nexport const ERR_NAVIGATION_ITEM_INVALID = 'ERR_NAVIGATION_ITEM_INVALID';\n\n/**\n * SSR component initialization failed.\n */\nexport const ERR_SSR_INIT = 'ERR_SSR_INIT';\n\n/**\n * Path starts from the invalid base.\n */\nexport const ERR_INVALID_PATH_BASE = 'ERR_INVALID_PATH_BASE';\n\nexport type ErrorType =\n | typeof ERR_METHOD_UNSUPPORTED\n | typeof ERR_METHOD_PARAMETER_UNSUPPORTED\n | typeof ERR_UNKNOWN_ENV\n | typeof ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n | typeof ERR_TIMED_OUT\n | typeof ERR_PARSE\n | typeof ERR_UNEXPECTED_TYPE\n | typeof ERR_NAVIGATION_HISTORY_EMPTY\n | typeof ERR_NAVIGATION_INDEX_INVALID\n | typeof ERR_NAVIGATION_ITEM_INVALID\n | typeof ERR_SSR_INIT\n | typeof ERR_INVALID_PATH_BASE;\n","import { createError } from '@/errors/createError.js';\nimport { ERR_UNEXPECTED_TYPE } from '@/errors/errors.js';\nimport type { SDKError } from '@/errors/SDKError.js';\n\n/**\n * Creates instance of TypeError stating, that value has unexpected type.\n */\nexport function createTypeError(): SDKError {\n return createError(ERR_UNEXPECTED_TYPE, 'Value has unexpected type');\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_PARSE } from '@/errors/errors.js';\n\nimport type { Parser } from '../types.js';\nimport type { ValueParserOptionalResult, ValueParserParseResult } from './types.js';\n\nexport class ValueParser<ResultType, IsOptional extends boolean> {\n constructor(\n protected parser: Parser<ResultType>,\n protected isOptional: IsOptional,\n protected type?: string,\n ) {\n }\n\n /**\n * Attempts to parse passed value\n * @param value - value to parse.\n * @throws {SDKError} ERR_PARSE\n * @see ERR_PARSE\n */\n parse(value: unknown): ValueParserParseResult<ResultType, IsOptional> {\n // In case, parsing result is specified as optional, and passed value is considered as empty,\n // we can return undefined. Otherwise, pass to parser.\n if (this.isOptional && value === undefined) {\n return undefined as ValueParserParseResult<ResultType, IsOptional>;\n }\n\n try {\n return this.parser(value) as ValueParserParseResult<ResultType, IsOptional>;\n } catch (cause) {\n throw createError(\n ERR_PARSE,\n `Unable to parse value${this.type ? ` as ${this.type}` : ''}`,\n cause,\n );\n }\n }\n\n optional(): ValueParserOptionalResult<this, ResultType> {\n this.isOptional = true as IsOptional;\n return this as ValueParserOptionalResult<this, ResultType>;\n }\n}\n","import { ValueParser } from './ValueParser/ValueParser.js';\nimport type { Parser } from './types.js';\n\nexport type ValueParserGenerator<T> = () => ValueParser<T, false>;\n\n/**\n * Creates function which generates new scalar value parser based on the specified one.\n * @param parser - parser to use as basic.\n * @param type - type name.\n */\nexport function createValueParserGenerator<T>(\n parser: Parser<T>,\n type?: string,\n): ValueParserGenerator<T> {\n return () => new ValueParser(parser, false, type);\n}\n","import { createTypeError } from '../createTypeError.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as boolean.\n */\nexport const boolean: ValueParserGenerator<boolean> = createValueParserGenerator((value) => {\n if (typeof value === 'boolean') {\n return value;\n }\n const asString = String(value);\n\n if (asString === '1' || asString === 'true') {\n return true;\n }\n\n if (asString === '0' || asString === 'false') {\n return false;\n }\n\n throw createTypeError();\n}, 'boolean');\n","import { createError } from '@/errors/createError.js';\nimport { ERR_PARSE } from '@/errors/errors.js';\n\nimport type { Parser, Schema } from './types.js';\n\n/**\n * Parses external value by specified schema. Functions iterates over each schema field\n * and uses getField function to get its value from the external source.\n * @param schema - object schema.\n * @param getField - function which gets external value by its field name.\n */\nexport function parseBySchema<T>(\n schema: Schema<T>,\n getField: (field: string) => unknown,\n): T {\n const result = {} as T;\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const field in schema) {\n const definition = schema[field];\n if (!definition) {\n continue;\n }\n\n let from: string;\n let parser: Parser<any>;\n\n // In case, definition has \"type\" property, then SchemaFieldDetailed was passed.\n if (typeof definition === 'function' || 'parse' in definition) {\n // Otherwise we are working with either parser function or instance.\n from = field;\n parser = typeof definition === 'function' ? definition : definition.parse.bind(definition);\n } else {\n const { type: definitionType } = definition;\n\n from = definition.from || field;\n parser = typeof definitionType === 'function'\n ? definitionType\n : definitionType.parse.bind(definitionType);\n }\n\n try {\n const parsedValue = parser(getField(from));\n if (parsedValue !== undefined) {\n (result as any)[field] = parsedValue;\n }\n } catch (error) {\n throw createError(ERR_PARSE, `Unable to parse field \"${field}\"`, error);\n }\n }\n\n return result;\n}\n","import { createTypeError } from './createTypeError.js';\n\n/**\n * Converts value to record.\n * @param value - value to convert.\n * @throws {Error} Value passed as a string does not represent JSON object.\n * @throws {Error} Value is not convertable.\n */\nexport function toRecord(value: unknown): Record<string, unknown> {\n let formattedValue: any = value;\n\n // Convert value to JSON in case, it is string. We expect value to be JSON string.\n if (typeof formattedValue === 'string') {\n formattedValue = JSON.parse(formattedValue);\n }\n\n // We expect json to be usual object.\n if (\n typeof formattedValue !== 'object'\n || formattedValue === null\n || Array.isArray(formattedValue)\n ) {\n throw createTypeError();\n }\n\n return formattedValue;\n}\n","import { parseBySchema } from '../parseBySchema.js';\nimport { toRecord } from '../toRecord.js';\nimport { ValueParser } from '../ValueParser/ValueParser.js';\nimport type { Schema } from '../types.js';\n\n/**\n * Creates new Json parser according to passed schema.\n * @param schema - object schema.\n * @param type - parser type name.\n */\nexport function json<T>(schema: Schema<T>, type?: string): ValueParser<T, false> {\n return new ValueParser((value) => {\n const record = toRecord(value);\n return parseBySchema(schema, (field) => record[field]);\n }, false, type);\n}\n","import { createTypeError } from '../createTypeError.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as number.\n */\nexport const number: ValueParserGenerator<number> = createValueParserGenerator((value) => {\n if (typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'string') {\n const num = Number(value);\n\n if (!Number.isNaN(num)) {\n return num;\n }\n }\n\n throw createTypeError();\n}, 'number');\n","import type { RGB } from './types.js';\n\n/**\n * Returns true in case, passed value has #RRGGBB format.\n * @param value - value to check.\n */\nexport function isRGB(value: string): value is RGB {\n return /^#[\\da-f]{6}$/i.test(value);\n}\n","import type { RGBShort } from './types.js';\n\n/**\n * Returns true in case, passed value has #RGB format.\n * @param value - value to check.\n */\nexport function isRGBShort(value: string): value is RGBShort {\n return /^#[\\da-f]{3}$/i.test(value);\n}\n","import { isRGB } from './isRGB.js';\nimport { isRGBShort } from './isRGBShort.js';\nimport type { RGB } from './types.js';\n\n/**\n * Converts passed value to #RRGGBB format. Accepts following color formats:\n * - `#RGB`\n * - `#RRGGBB`\n * - `rgb(1,2,3)`\n * - `rgba(1,2,3,4)`\n * @param value - value to convert.\n * @throws {Error} Passed value does not satisfy any of known RGB formats.\n */\nexport function toRGB(value: string): RGB {\n // Remove all spaces.\n const clean = value.replace(/\\s/g, '').toLowerCase();\n\n // Value already has required format.\n if (isRGB(clean)) {\n return clean;\n }\n\n // Convert from #RGB.\n if (isRGBShort(clean)) {\n let color: RGB = '#';\n for (let i = 0; i < 3; i += 1) {\n color += clean[1 + i].repeat(2);\n }\n return color;\n }\n\n // Example valid values: rgb(0,3,10) rgba(32,114,8,0)\n const match = clean.match(/^rgb\\((\\d{1,3}),(\\d{1,3}),(\\d{1,3})\\)$/)\n || clean.match(/^rgba\\((\\d{1,3}),(\\d{1,3}),(\\d{1,3}),\\d{1,3}\\)$/);\n\n // In case, this didn't work as well, we can't extract RGB color from passed\n // text.\n if (!match) {\n throw new Error(`Value \"${value}\" does not satisfy any of known RGB formats.`);\n }\n\n // Otherwise, take R, G and B components, convert to hex and create #RRGGBB\n // string.\n return match.slice(1).reduce((acc, component) => {\n const formatted = parseInt(component, 10).toString(16);\n return acc + (formatted.length === 1 ? '0' : '') + formatted;\n }, '#') as RGB;\n}\n","import { createTypeError } from '../createTypeError.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as string.\n */\nexport const string: ValueParserGenerator<string> = createValueParserGenerator((value) => {\n if (typeof value === 'string' || typeof value === 'number') {\n return value.toString();\n }\n throw createTypeError();\n}, 'string');\n","import { toRGB } from '@/colors/toRGB.js';\nimport type { RGB } from '@/colors/types.js';\n\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { string } from './string.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as RGB color.\n */\nexport const rgb: ValueParserGenerator<RGB> = createValueParserGenerator((value) => toRGB(string().parse(value)), 'rgb');\n","import { json } from '@/parsing/parsers/json.js';\nimport { string } from '@/parsing/parsers/string.js';\n\n/**\n * Message format used in communication between client and Telegram applications.\n */\nexport interface MiniAppsMessage {\n /**\n * Event name.\n */\n eventType: string;\n /**\n * Event parameters.\n */\n eventData?: unknown;\n}\n\n/**\n * Parses value as a message between client and Telegram applications.\n * @param value - value to parse.\n */\nexport function parseMessage(value: unknown): MiniAppsMessage {\n return json({\n eventType: string(),\n eventData: (v) => v,\n }).parse(value);\n}\n","/**\n * Removes global event handlers, used by the package.\n */\nexport function cleanupEventHandlers(): void {\n ['TelegramGameProxy_receiveEvent', 'TelegramGameProxy', 'Telegram'].forEach((prop) => {\n delete window[prop as keyof Window];\n });\n}\n","/**\n * Emits event sent from Telegram native application like it was sent in\n * default web environment between 2 iframes. It dispatches new MessageEvent\n * and expects it to be handled via `window.addEventListener('message', ...)`\n * as developer would do it to handle messages sent from the parent iframe.\n * @param eventType - event name.\n * @param eventData - event payload.\n */\nexport function emitMiniAppsEvent(eventType: string, eventData: unknown): void {\n window.dispatchEvent(new MessageEvent('message', {\n data: JSON.stringify({ eventType, eventData }),\n // We specify window.parent to imitate the case, the parent iframe sent us this event.\n source: window.parent,\n }));\n}\n","import { emitMiniAppsEvent } from './emitMiniAppsEvent.js';\n\n/**\n * Defines special handlers by known paths, which are recognized by\n * Telegram as ports to receive events. This function also sets special\n * function in global window object to prevent duplicate declaration.\n */\nexport function defineEventHandlers() {\n // Iterate over each path, where \"receiveEvent\" function should be\n // defined. This function is called by external environment in case,\n // it wants to emit some event.\n [\n ['TelegramGameProxy_receiveEvent'], // Windows Phone.\n ['TelegramGameProxy', 'receiveEvent'], // Desktop.\n ['Telegram', 'WebView', 'receiveEvent'], // Android and iOS.\n ].forEach((path) => {\n // Path starts from the \"window\" object.\n let pointer = window as any;\n\n path.forEach((item, idx, arr) => {\n // We are on the last iteration, where function property name is passed.\n if (idx === arr.length - 1) {\n pointer[item] = emitMiniAppsEvent;\n return;\n }\n\n if (!(item in pointer)) {\n pointer[item] = {};\n }\n pointer = pointer[item];\n });\n });\n}\n","import { logger } from '@/debug/debug.js';\nimport { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport { onWindow } from '@/events/onWindow.js';\nimport { createCleanup } from '@/misc/createCleanup.js';\nimport { boolean } from '@/parsing/parsers/boolean.js';\nimport { json } from '@/parsing/parsers/json.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { rgb } from '@/parsing/parsers/rgb.js';\nimport { string } from '@/parsing/parsers/string.js';\nimport { toRecord } from '@/parsing/toRecord.js';\nimport type { RGB } from '@/colors/types.js';\n\nimport { type MiniAppsMessage, parseMessage } from '../../parseMessage.js';\nimport { cleanupEventHandlers } from '../event-handlers/cleanupEventHandlers.js';\nimport { defineEventHandlers } from '../event-handlers/defineEventHandlers.js';\nimport type {\n MiniAppsEventName,\n MiniAppsEventPayload,\n MiniAppsEventEmitter,\n MiniAppsEvents,\n} from '../types.js';\n\n/**\n * Parsers for each Mini Apps event.\n *\n * This map should be cleaned\n */\nconst parsers: {\n [E in MiniAppsEventName]?: {\n parse(value: unknown): MiniAppsEventPayload<E>;\n }\n} = {\n clipboard_text_received: json({\n req_id: string(),\n data: (value) => (value === null ? value : string().optional().parse(value)),\n }),\n custom_method_invoked: json({\n req_id: string(),\n result: (value) => value,\n error: string().optional(),\n }),\n invoice_closed: json({ slug: string(), status: string() }),\n phone_requested: json({ status: string() }),\n popup_closed: {\n parse(value) {\n return json({\n button_id: (value) => (\n value === null || value === undefined\n ? undefined\n : string().parse(value)\n ),\n }).parse(value ?? {});\n },\n },\n qr_text_received: json({ data: string().optional() }),\n theme_changed: json({\n theme_params: (value) => {\n const parser = rgb().optional();\n\n return Object\n .entries(toRecord(value))\n .reduce<Partial<Record<string, RGB>>>((acc, [k, v]) => {\n acc[k] = parser.parse(v);\n return acc;\n }, {});\n },\n }),\n viewport_changed: json({\n height: number(),\n width: (value) => (\n value === null || value === undefined\n ? window.innerWidth\n : number().parse(value)\n ),\n is_state_stable: boolean(),\n is_expanded: boolean(),\n }),\n write_access_requested: json({ status: string() }),\n};\n\n/**\n * Creates new event emitter, which handles events from the Telegram application.\n */\nexport function createMiniAppsEventEmitter(): [\n /**\n * Created event emitter.\n */\n emitter: MiniAppsEventEmitter,\n /**\n * Function to dispose created emitter.\n */\n dispose: () => void,\n] {\n // We use this event emitter for better developer experience, using the subscribe method.\n const subEmitter = new EventEmitter<{ event: any[] }>();\n\n // Event emitter processing all the incoming events.\n const mainEmitter = new EventEmitter<MiniAppsEvents>();\n\n mainEmitter.subscribe(event => {\n subEmitter.emit('event', { name: event.event, payload: event.args[0] });\n });\n\n // Define event handles, which will proxy native method calls to their web version.\n defineEventHandlers();\n\n // List of cleanup functions, which should be called on dispose.\n const [, cleanup] = createCleanup(\n // Don't forget to remove created handlers.\n cleanupEventHandlers,\n // Add \"resize\" event listener to make sure, we always have fresh viewport information.\n // Desktop version of Telegram is sometimes not sending the viewport_changed\n // event. For example, when the MainButton is shown. That's why we should\n // add our own listener to make sure, viewport information is always fresh.\n // Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/10\n onWindow('resize', () => {\n mainEmitter.emit('viewport_changed', {\n width: window.innerWidth,\n height: window.innerHeight,\n is_state_stable: true,\n is_expanded: true,\n });\n }),\n // Add listener, which handles events sent from the Telegram web application and also events\n // generated by the local emitEvent function.\n onWindow('message', (event) => {\n // Ignore non-parent window messages.\n if (event.source !== window.parent) {\n return;\n }\n\n // Parse incoming event data.\n let message: MiniAppsMessage;\n try {\n message = parseMessage(event.data);\n } catch {\n // We ignore incorrect messages as they could be generated by any other code.\n return;\n }\n\n const { eventType, eventData } = message;\n const parser = parsers[eventType as keyof typeof parsers];\n\n try {\n const data = parser ? parser.parse(eventData) : eventData;\n mainEmitter.emit(...(data ? [eventType, data] : [eventType]) as [any, any]);\n } catch (cause) {\n logger.error(\n `An error occurred processing the \"${eventType}\" event from the Telegram application. Please, file an issue here: https://github.com/Telegram-Mini-Apps/tma.js/issues/new/choose`,\n message,\n cause,\n );\n }\n }),\n // Clear emitters.\n () => subEmitter.clear(),\n () => mainEmitter.clear(),\n );\n\n return [{\n on: mainEmitter.on.bind(mainEmitter),\n off: mainEmitter.off.bind(mainEmitter),\n subscribe(listener) {\n return subEmitter.on('event', listener);\n },\n unsubscribe(listener) {\n subEmitter.off('event', listener);\n },\n get count() {\n return mainEmitter.count + subEmitter.count;\n },\n }, cleanup];\n}\n","import { createSingleton } from '@/misc/createSingleton.js';\n\nimport { createMiniAppsEventEmitter } from './createMiniAppsEventEmitter.js';\nimport type { MiniAppsEventEmitter } from '../types.js';\n\nconst [get, resetMiniAppsEventEmitter] = createSingleton(\n (reset) => {\n const [emitter, cleanup] = createMiniAppsEventEmitter();\n\n // Rewire \"off\" method and make it reset singleton if no event listeners left.\n const off = emitter.off.bind(emitter);\n emitter.off = (event, listener) => {\n const { count } = emitter;\n off(event, listener);\n\n // If event emitter now has no listeners, we can perform a reset.\n if (count && !emitter.count) {\n reset();\n }\n };\n\n return [emitter, cleanup] as const;\n },\n ([, cleanup]) => cleanup(),\n);\n\n/**\n * Returns Mini Apps event emitter singleton.\n */\nexport function miniAppsEventEmitter(): MiniAppsEventEmitter {\n return get()[0];\n}\n\nexport { resetMiniAppsEventEmitter };\n","import { miniAppsEventEmitter } from '../event-emitter/singleton.js';\nimport type { MiniAppsEventListener, MiniAppsEventName } from '../types.js';\n\n/**\n * Removes listener from specified event.\n * @param event - event to listen.\n * @param listener - event listener to remove.\n */\nexport function off<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n): void {\n miniAppsEventEmitter().off(event, listener);\n}\n","import type { RemoveEventListenerFn } from '@/events/types.js';\n\nimport { miniAppsEventEmitter } from '../event-emitter/singleton.js';\nimport type { MiniAppsEventListener, MiniAppsEventName } from '../types.js';\n\n/**\n * Adds new listener to the specified event. Returns handler\n * which allows to stop listening to event.\n * @param event - event name.\n * @param listener - event listener.\n * @param once - should listener be called only once.\n * @returns Function to remove bound event listener.\n */\nexport function on<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n once?: boolean,\n): RemoveEventListenerFn {\n return miniAppsEventEmitter().on(event, listener, once);\n}\n","/**\n * States that passed value is Record and not Array.\n * @param value - value to check.\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import type { Version } from './types.js';\n\n/**\n * Returns 1 in case, version \"a\" is greater than \"b\".\n * Returns 0 in case, version \"a\" equal to \"b\".\n * Returns -1 in case, version \"a\" is lower than \"b\".\n * @param a - first version.\n * @param b - second version.\n */\nexport function compareVersions(a: Version, b: Version): number {\n // Split both of the version by dot.\n const aParts = a.split('.');\n const bParts = b.split('.');\n\n // Compute maximum length.\n const len = Math.max(aParts.length, bParts.length);\n\n // Iterate over each part of version and compare them. In case, part is\n // missing, assume its value is equal to 0.\n for (let i = 0; i < len; i += 1) {\n const aVal = parseInt(aParts[i] || '0', 10);\n const bVal = parseInt(bParts[i] || '0', 10);\n\n if (aVal === bVal) {\n continue;\n }\n return aVal > bVal ? 1 : -1;\n }\n return 0;\n}\n","import { compareVersions } from '@/version/compareVersions.js';\nimport type {\n MiniAppsMethodName,\n MiniAppsMethodVersionedParams,\n MiniAppsMethodWithVersionedParams,\n} from '@/bridge/methods/types/methods.js';\nimport type { Version } from '@/version/types.js';\n\n/**\n * Returns true if \"a\" version is less than or equal to \"b\" version.\n * @param a\n * @param b\n */\nfunction versionLessOrEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) <= 0;\n}\n\n/**\n * Returns true in case, passed parameter in specified method is supported.\n * @param method - method name\n * @param param - method parameter\n * @param inVersion - platform version.\n */\nexport function supports<M extends MiniAppsMethodWithVersionedParams>(\n method: M,\n param: MiniAppsMethodVersionedParams<M>,\n inVersion: Version,\n): boolean;\n\n/**\n * Returns true in case, specified method is supported in passed version.\n * @param method - method name.\n * @param inVersion - platform version.\n */\nexport function supports(method: MiniAppsMethodName, inVersion: Version): boolean;\n\nexport function supports(\n method: MiniAppsMethodName,\n paramOrVersion: Version | string,\n inVersion?: string,\n): boolean {\n // Method name, parameter, target version.\n if (typeof inVersion === 'string') {\n if (method === 'web_app_open_link') {\n if (paramOrVersion === 'try_instant_view') {\n return versionLessOrEqual('6.4', inVersion);\n }\n }\n\n if (method === 'web_app_set_header_color') {\n if (paramOrVersion === 'color') {\n return versionLessOrEqual('6.9', inVersion);\n }\n }\n }\n\n switch (method) {\n case 'web_app_open_tg_link':\n case 'web_app_open_invoice':\n case 'web_app_setup_back_button':\n case 'web_app_set_background_color':\n case 'web_app_set_header_color':\n case 'web_app_trigger_haptic_feedback':\n return versionLessOrEqual('6.1', paramOrVersion);\n case 'web_app_open_popup':\n return versionLessOrEqual('6.2', paramOrVersion);\n case 'web_app_close_scan_qr_popup':\n case 'web_app_open_scan_qr_popup':\n case 'web_app_read_text_from_clipboard':\n return versionLessOrEqual('6.4', paramOrVersion);\n case 'web_app_switch_inline_query':\n return versionLessOrEqual('6.7', paramOrVersion);\n case 'web_app_invoke_custom_method':\n case 'web_app_request_write_access':\n case 'web_app_request_phone':\n return versionLessOrEqual('6.9', paramOrVersion);\n case 'web_app_setup_settings_button':\n return versionLessOrEqual('6.10', paramOrVersion);\n case 'web_app_biometry_get_info':\n case 'web_app_biometry_open_settings':\n case 'web_app_biometry_request_access':\n case 'web_app_biometry_request_auth':\n case 'web_app_biometry_update_token':\n return versionLessOrEqual('7.2', paramOrVersion);\n default:\n return [\n 'iframe_ready',\n 'iframe_will_reload',\n 'web_app_close',\n 'web_app_data_send',\n 'web_app_expand',\n 'web_app_open_link',\n 'web_app_ready',\n 'web_app_request_theme',\n 'web_app_request_viewport',\n 'web_app_setup_main_button',\n 'web_app_setup_closing_behavior',\n ].includes(method);\n }\n}\n","import { isRecord } from '@/misc/isRecord.js';\n\n/**\n * Returns true in case, passed value contains path `external.notify` property and `notify` is a\n * function.\n * @param value - value to check.\n */\nexport function hasExternalNotify<T extends object>(value: T): value is (\n T & {\n external: {\n notify: (...args: any) => any;\n };\n}) {\n return 'external' in value\n && isRecord(value.external)\n && 'notify' in value.external\n && typeof value.external.notify === 'function';\n}\n","import { isRecord } from '@/misc/isRecord.js';\n\n/**\n * Returns true in case, passed value contains path `TelegramWebviewProxy.postEvent` property and\n * `postEvent` is a function.\n * @param value - value to check.\n */\nexport function hasWebviewProxy<T extends {}>(value: T): value is (\n T & {\n TelegramWebviewProxy: {\n postEvent: (...args: any) => any;\n }\n}) {\n return 'TelegramWebviewProxy' in value\n && isRecord(value.TelegramWebviewProxy)\n && 'postEvent' in value.TelegramWebviewProxy\n && typeof value.TelegramWebviewProxy.postEvent === 'function';\n}\n","/**\n * @see https://stackoverflow.com/a/326076\n * @returns True, if current environment is iframe.\n */\nexport function isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n","let currentTargetOrigin = 'https://web.telegram.org';\n\n/**\n * Sets new global targetOrigin, used by `postEvent` method.\n * Default value is \"https://web.telegram.org\". You don't need to\n * use this method until you know what you are doing.\n *\n * This method could be used for test purposes.\n * @param value - new target origin.\n */\nexport function setTargetOrigin(value: string): void {\n currentTargetOrigin = value;\n}\n\n/**\n * Returns current global target origin.\n */\nexport function targetOrigin(): string {\n return currentTargetOrigin;\n}\n","import { log } from '@/debug/debug.js';\nimport { hasExternalNotify } from '@/env/hasExternalNotify.js';\nimport { hasWebviewProxy } from '@/env/hasWebviewProxy.js';\nimport { isIframe } from '@/env/isIframe.js';\nimport { createError } from '@/errors/createError.js';\nimport { ERR_UNKNOWN_ENV } from '@/errors/errors.js';\n\nimport { targetOrigin as targetOriginFn } from '../target-origin.js';\nimport type {\n MiniAppsMethodName,\n MiniAppsMethodParams,\n MiniAppsMethodWithOptionalParams,\n MiniAppsMethodWithoutParams,\n MiniAppsMethodWithRequiredParams,\n} from './types/methods.js';\n\ninterface PostEventOptions {\n /**\n * Origin used while posting message. This option is only used in case, current environment\n * is browser (Web version of Telegram) and could be used for test purposes.\n * @default 'https://web.telegram.org'\n */\n targetOrigin?: string;\n}\n\nexport type PostEvent = typeof postEvent;\n\n/**\n * Calls Mini Apps method with optional parameters.\n * @param method - method name.\n * @param params - method parameters.\n * @param options - posting options.\n * @throws {SDKError} ERR_UNKNOWN_ENV\n * @see ERR_UNKNOWN_ENV\n */\nexport function postEvent<Method extends MiniAppsMethodWithOptionalParams>(\n method: Method,\n params?: MiniAppsMethodParams<Method>,\n options?: PostEventOptions,\n): void;\n\n/**\n * Calls Mini Apps method without parameters.\n * @param method - method name.\n * @param options - posting options.\n * @throws {SDKError} ERR_UNKNOWN_ENV\n * @see ERR_UNKNOWN_ENV\n */\nexport function postEvent(method: MiniAppsMethodWithoutParams, options?: PostEventOptions): void;\n\n/**\n * Calls Mini Apps method with parameters.\n * @param method - method name.\n * @param params - method parameters.\n * @param options - posting options.\n * @throws {SDKError} ERR_UNKNOWN_ENV\n * @see ERR_UNKNOWN_ENV\n */\nexport function postEvent<Method extends MiniAppsMethodWithRequiredParams>(\n method: Method,\n params: MiniAppsMethodParams<Method>,\n options?: PostEventOptions,\n): void;\n\nexport function postEvent(\n eventType: MiniAppsMethodName,\n paramsOrOptions?: MiniAppsMethodParams<MiniAppsMethodName> | PostEventOptions,\n options?: PostEventOptions,\n): void {\n let postOptions: PostEventOptions = {};\n let eventData: any;\n\n if (paramsOrOptions === undefined && options === undefined) {\n // Parameters and options were not passed.\n postOptions = {};\n } else if (paramsOrOptions !== undefined && options !== undefined) {\n // Both parameters and options passed.\n postOptions = options;\n eventData = paramsOrOptions;\n } else if (paramsOrOptions !== undefined) {\n // Only parameters were passed.\n if ('targetOrigin' in paramsOrOptions) {\n postOptions = paramsOrOptions;\n } else {\n eventData = paramsOrOptions;\n }\n }\n const { targetOrigin = targetOriginFn() } = postOptions;\n\n log('Posting event:', eventData\n ? { event: eventType, data: eventData }\n : { event: eventType });\n\n // Telegram Web.\n if (isIframe()) {\n window.parent.postMessage(JSON.stringify({ eventType, eventData }), targetOrigin);\n return;\n }\n\n // Telegram for Windows Phone or Android.\n if (hasExternalNotify(window)) {\n window.external.notify(JSON.stringify({ eventType, eventData }));\n return;\n }\n\n // Telegram for iOS and macOS.\n if (hasWebviewProxy(window)) {\n window.TelegramWebviewProxy.postEvent(eventType, JSON.stringify(eventData));\n return;\n }\n\n // Otherwise current environment is unknown, and we are not able to send event.\n throw createError(\n ERR_UNKNOWN_ENV,\n 'Unable to determine current environment and possible way to send event. You are probably trying to use Mini Apps method outside of Telegram application environment.',\n );\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_METHOD_PARAMETER_UNSUPPORTED, ERR_METHOD_UNSUPPORTED } from '@/errors/errors.js';\nimport { isRecord } from '@/misc/isRecord.js';\nimport { supports } from '@/supports/supports.js';\nimport type { Version } from '@/version/types.js';\n\nimport { type PostEvent, postEvent } from './postEvent.js';\n\n/**\n * Creates function which checks if specified method and parameters are supported. In case,\n * method or parameters are unsupported, an error will be thrown.\n * @param version - Telegram Mini Apps version.\n * @throws {SDKError} ERR_METHOD_UNSUPPORTED\n * @throws {SDKError} ERR_METHOD_PARAMETER_UNSUPPORTED\n * @see ERR_METHOD_UNSUPPORTED\n * @see ERR_METHOD_PARAMETER_UNSUPPORTED\n */\nexport function createPostEvent(version: Version): PostEvent {\n return (method: any, params: any) => {\n // Firstly, check if method itself is supported.\n if (!supports(method, version)) {\n throw createError(ERR_METHOD_UNSUPPORTED, `Method \"${method}\" is unsupported in Mini Apps version ${version}`);\n }\n\n // Method could use parameters, which are supported only in specific versions of Telegram\n // Mini Apps.\n if (isRecord(params)) {\n let validateParam: string | undefined;\n\n if (method === 'web_app_open_link' && 'try_instant_view' in params) {\n validateParam = 'try_instant_view';\n } else if (method === 'web_app_set_header_color' && 'color' in params) {\n validateParam = 'color';\n }\n\n if (validateParam && !supports(method, validateParam, version)) {\n throw createError(\n ERR_METHOD_PARAMETER_UNSUPPORTED,\n `Parameter \"${validateParam}\" of \"${method}\" method is unsupported in Mini Apps version ${version}`,\n );\n }\n }\n\n return postEvent(method, params);\n };\n}\n","type CaptureSameReqFn = (payload: { req_id: string }) => boolean;\n\n/**\n * Returns a function which can be used in `request` function `capture` property to capture\n * the event with the same request identifier.\n * @param reqId - request identifier.\n */\nexport function captureSameReq(reqId: string): CaptureSameReqFn {\n return ({ req_id }) => req_id === reqId;\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_TIMED_OUT } from '@/errors/errors.js';\nimport type { SDKError } from '@/errors/SDKError.js';\n\n/**\n * Creates new timeout error.\n * @param timeout - timeout in ms.\n */\nexport function createTimeoutError(timeout: number): SDKError {\n return createError(ERR_TIMED_OUT, `Timeout reached: ${timeout}ms`);\n}\n","import { createTimeoutError } from '@/timeout/createTimeoutError.js';\n\n/**\n * Runs passed function or promise with specified deadline presented via timeout argument.\n * @param funcOrPromise - function to execute or pending promise.\n * @param timeout - completion timeout.\n */\nexport function withTimeout<T>(\n funcOrPromise: Promise<T> | (() => Promise<T>),\n timeout: number,\n): Promise<T> {\n return Promise.race([\n typeof funcOrPromise === 'function' ? funcOrPromise() : funcOrPromise,\n new Promise<never>((_, rej) => {\n setTimeout(() => {\n rej(createTimeoutError(timeout));\n }, timeout);\n }),\n ]);\n}\n","import { withTimeout } from '@/timeout/withTimeout.js';\nimport type { ExecuteWithOptions, If, IsNever } from '@/types/index.js';\n\nimport { on } from '../events/listening/on.js';\nimport { postEvent as defaultPostEvent } from '../methods/postEvent.js';\nimport type { MiniAppsEventName, MiniAppsEventPayload } from '../events/types.js';\nimport type { MiniAppsMethodName, MiniAppsMethodParams } from '../methods/types/index.js';\nimport { createCleanup } from '@/misc/createCleanup.js';\n\n/**\n * `request` method `capture` option.\n * @see request\n */\nexport type RequestCapture<T extends MiniAppsEventName | MiniAppsEventName[]> =\n T extends (infer U extends MiniAppsEventName)[]\n ? If<\n IsNever<MiniAppsEventPayload<U>>,\n () => boolean,\n (payload: {\n [K in U]: If<\n IsNever<MiniAppsEventPayload<K>>,\n { event: K; },\n { event: K; payload: MiniAppsEventPayload<K> }\n >\n }[U]) => boolean\n >\n : T extends MiniAppsEventName\n ? If<\n IsNever<MiniAppsEventPayload<T>>,\n () => boolean,\n (payload: MiniAppsEventPayload<T>) => boolean\n >\n : never;\n\n/**\n * `request` method options.\n * @see request\n */\nexport type RequestOptions<\n Method extends MiniAppsMethodName,\n Event extends MiniAppsEventName | MiniAppsEventName[]\n> = {\n /**\n * Mini Apps method name.\n */\n method: Method;\n /**\n * Tracked Mini Apps events.\n */\n event: Event;\n /**\n * Should return true in case, this event should be captured. If not specified,\n * request will be captured automatically.\n */\n capture?: RequestCapture<Event>;\n }\n & ExecuteWithOptions\n & If<IsNever<MiniAppsMethodParams<Method>>, {}, {\n /**\n * List of method parameters.\n */\n params: MiniAppsMethodParams<Method>\n}>;\n\nexport type RequestResult<Event extends MiniAppsEventName | MiniAppsEventName[]> =\n Event extends (infer T extends MiniAppsEventName)[]\n ? MiniAppsEventPayload<T>\n : Event extends MiniAppsEventName\n ? MiniAppsEventPayload<Event>\n : never;\n\n/**\n * Calls specified Mini Apps method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param options - method options.\n */\nexport async function request<\n Method extends MiniAppsMethodName,\n Event extends MiniAppsEventName | MiniAppsEventName[]\n>(\n options: RequestOptions<Method, Event>,\n): Promise<RequestResult<Event>> {\n let resolve: (payload: RequestResult<Event>) => void;\n const promise = new Promise<RequestResult<Event>>((res) => {\n resolve = res;\n });\n\n const { event, capture, timeout } = options;\n const [, cleanup] = createCleanup(\n ...(Array.isArray(event) ? event : [event]).map(\n (ev) => on(ev, (payload: any) => {\n return (!capture || capture(payload)) && resolve(payload);\n }),\n )\n );\n\n try {\n (options.postEvent || defaultPostEvent)(options.method as any, (options as any).params);\n return await (timeout ? withTimeout(promise, timeout) : promise);\n } finally {\n // After promise execution was completed, don't forget to remove all the listeners.\n cleanup();\n }\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_INVOKE_CUSTOM_METHOD_RESPONSE } from '@/errors/errors.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nimport { captureSameReq } from './captureSameReq.js';\nimport { request } from './request.js';\nimport type { CustomMethodName, CustomMethodParams } from '../methods/types/custom-methods.js';\n\n/**\n * Invokes known custom method. Returns method execution result.\n * @param method - method name.\n * @param params - method parameters.\n * @param requestId - request identifier.\n * @param options - additional options.\n * @throws {SDKError} ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n * @see ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n */\nexport async function invokeCustomMethod<M extends CustomMethodName>(\n method: M,\n params: CustomMethodParams<M>,\n requestId: string,\n options?: ExecuteWithOptions,\n): Promise<unknown>;\n\n/**\n * Invokes unknown custom method. Returns method execution result.\n * @param method - method name.\n * @param params - method parameters.\n * @param requestId - request identifier.\n * @param options - additional options.\n * @throws {SDKError} ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n * @see ERR_INVOKE_CUSTOM_METHOD_RESPONSE\n */\nexport function invokeCustomMethod(\n method: string,\n params: object,\n requestId: string,\n options?: ExecuteWithOptions,\n): Promise<unknown>;\n\nexport async function invokeCustomMethod(\n method: string,\n params: object,\n requestId: string,\n options: ExecuteWithOptions = {},\n): Promise<unknown> {\n const {\n result,\n error,\n } = await request({\n ...options,\n method: 'web_app_invoke_custom_method',\n event: 'custom_method_invoked',\n params: {\n method,\n params,\n req_id: requestId,\n },\n capture: captureSameReq(requestId),\n });\n\n if (error) {\n throw createError(ERR_INVOKE_CUSTOM_METHOD_RESPONSE, error);\n }\n\n return result;\n}\n","import { isRecord } from '@/misc/isRecord.js';\n\n/**\n * Function which joins passed values with space following these rules:\n * 1. If value is non-empty string, it will be added to output.\n * 2. If value is object, only those keys will be added, which values are truthy.\n * 3. If value is array, classNames will be called with this value spread.\n * 4. All other values are ignored.\n *\n * You can find this function to similar one from the package {@link https://www.npmjs.com/package/classnames|classnames}.\n * @param values - values array.\n * @returns Final class name.\n */\nexport function classNames(...values: any[]): string {\n return values\n // eslint-disable-next-line array-callback-return\n .map((value) => {\n if (typeof value === 'string') {\n return value;\n }\n\n if (isRecord(value)) {\n return classNames(Object.entries(value).map((entry) => entry[1] && entry[0]));\n }\n\n if (Array.isArray(value)) {\n return classNames(...value);\n }\n })\n .filter(Boolean)\n .join(' ');\n}\n","import { isRecord } from '@/misc/isRecord.js';\nimport type { UnionOptionalKeys, UnionRequiredKeys } from '@/types/unions.js';\n\nimport { classNames } from './classNames.js';\n\nexport type MergeClassNames<Tuple extends any[]> =\n // Removes all types from union which will be ignored by the mergeClassNames function.\n Exclude<Tuple[number], number | string | null | undefined | any[] | boolean> extends infer Union\n ? {\n [K in UnionRequiredKeys<Union>]: string;\n } & {\n [K in UnionOptionalKeys<Union>]?: string;\n }\n : never;\n\n/**\n * Merges 2 sets of parameters. Function expects passing an array of objects with values, which\n * could be passed to `classNames` function. As the result, it returns an object with keys\n * from all objects with merged values.\n * @see classNames\n */\nexport function mergeClassNames<T extends any[]>(...partials: T): MergeClassNames<T> {\n return partials.reduce<MergeClassNames<T>>((acc, partial) => {\n if (!isRecord(partial)) {\n return acc;\n }\n\n Object.entries(partial).forEach(([key, value]) => {\n const className = classNames((acc as any)[key], value);\n\n if (className.length) {\n (acc as any)[key] = className;\n }\n });\n\n return acc;\n }, {} as MergeClassNames<T>);\n}\n","import { toRGB } from './toRGB.js';\n\n/**\n * Returns true in case, the color is recognized as dark.\n * @param color - color in any format acceptable by toRGB function.\n * @see toRGB\n */\nexport function isColorDark(color: string): boolean {\n // Convert color to RGB.\n const rgb = toRGB(color);\n\n // Real formula: hsp = Math.sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b)\n // See: https://stackoverflow.com/a/596243\n return Math.sqrt(\n [0.299, 0.587, 0.114].reduce<number>((acc, modifier, idx) => {\n // Extract part of #RRGGBB pattern and convert it to DEC.\n const dec = parseInt(rgb.slice(1 + idx * 2, 1 + (idx + 1) * 2), 16);\n return acc + dec * dec * modifier;\n }, 0),\n ) < 120;\n}\n","import { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport type { StateEvents } from '@/classes/State/types.js';\nimport type { StringKeys } from '@/types/utils.js';\n\ntype Emitter<State extends object> = EventEmitter<StateEvents<State>>;\n\nexport class State<State extends object> {\n private readonly ee: Emitter<State> = new EventEmitter();\n\n constructor(\n /**\n * Initial state.\n */\n private readonly state: State,\n ) {\n }\n\n /**\n * Clones current state and returns its copy.\n */\n clone(): State {\n return { ...this.state };\n }\n\n /**\n * Sets value by key.\n * @param key - state key.\n * @param value - value to set.\n */\n set<K extends StringKeys<State>>(key: K, value: State[K]): void;\n /**\n * Sets several values simultaneously.\n * @param state - partial state.\n */\n set(state: Partial<State>): void;\n set(keyOrState: StringKeys<State> | Partial<State>, keyValue?: State[keyof State]): void {\n const didChange = Object\n .entries(typeof keyOrState === 'string' ? { [keyOrState]: keyValue } : keyOrState)\n .reduce((acc, [key, value]) => {\n // If value is the same or missing at all, we skip it.\n if (this.state[key as keyof State] === value || value === undefined) {\n return acc;\n }\n\n // Otherwise set new value and emit change event.\n this.state[key as keyof State] = value;\n (this.ee as any).emit(`change:${key}`, value);\n\n return true;\n }, false);\n\n if (didChange) {\n (this.ee as any).emit('change', this.state);\n }\n }\n\n /**\n * Returns value by specified key.\n * @param key - state key.\n */\n get<K extends StringKeys<State>>(key: K): State[K] {\n return this.state[key];\n }\n\n /**\n * Adds new event listener.\n */\n on: Emitter<State>['on'] = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off: Emitter<State>['off'] = this.ee.off.bind(this.ee);\n}\n","import { State } from '@/classes/State/State.js';\n\nexport class WithStateUtils<Shape extends object> {\n protected state: State<Shape>;\n\n constructor(shape: Shape) {\n this.state = new State(shape);\n this.set = this.state.set.bind(this.state);\n this.get = this.state.get.bind(this.state);\n this.clone = this.state.clone.bind(this.state);\n }\n\n /**\n * Gets the state value.\n */\n protected get: State<Shape>['get'];\n\n /**\n * Sets the state value.\n */\n protected set: State<Shape>['set'];\n\n /**\n * Clones the current state.\n */\n protected clone: State<Shape>['clone'];\n}\n","import { supports } from '@/supports/supports.js';\nimport type { MiniAppsMethodName } from '@/bridge/methods/types/methods.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\nexport type SupportsSchema<Method extends string> = Record<Method, MiniAppsMethodName>;\n\n/**\n * Returns function, which accepts predefined method name and checks if it is supported\n * via passed schema and version.\n * @param schema - object which contains methods names and TWA method as a dependency.\n * @param version - platform version.\n */\nexport function createSupportsFn<Method extends string>(\n version: Version,\n schema: SupportsSchema<Method>,\n): SupportsFn<Method> {\n return (method) => supports(schema[method], version);\n}\n","import { WithStateUtils } from '@/classes/WithStateUtils.js';\nimport { createSupportsFn } from '@/supports/createSupportsFn.js';\nimport type { MiniAppsMethodName } from '@/bridge/methods/types/methods.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\nexport class WithSupportsAndStateUtils<StateShape extends object, SupportsMethod extends string>\nextends WithStateUtils<StateShape> {\n constructor(\n /**\n * Initial state.\n */\n stateShape: StateShape,\n /**\n * Mini Apps version.\n */\n version: Version,\n /**\n * Supports method schema.\n */\n supportsSchema: Record<SupportsMethod, MiniAppsMethodName>,\n ) {\n super(stateShape);\n this.supports = createSupportsFn(version, supportsSchema);\n }\n\n /**\n * @returns True, if specified method is supported by the current component.\n */\n supports: SupportsFn<SupportsMethod>;\n}\n","import { off } from '@/bridge/events/listening/off.js';\nimport { on } from '@/bridge/events/listening/on.js';\nimport { WithSupportsAndStateUtils } from '@/classes/WithSupportsAndStateUtils.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { BackButtonEvents, BackButtonState } from '@/components/BackButton/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport type { Version } from '@/version/types.js';\n\ntype Emitter = EventEmitter<BackButtonEvents>;\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/back-button\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/back-button\n */\nexport class BackButton extends WithSupportsAndStateUtils<BackButtonState, 'show' | 'hide'> {\n constructor(isVisible: boolean, version: Version, private readonly postEvent: PostEvent) {\n super({ isVisible }, version, {\n show: 'web_app_setup_back_button',\n hide: 'web_app_setup_back_button',\n });\n }\n\n private set isVisible(visible: boolean) {\n this.set('isVisible', visible);\n this.postEvent('web_app_setup_back_button', { is_visible: visible });\n }\n\n /**\n * True if BackButton is currently visible.\n */\n get isVisible(): boolean {\n return this.get('isVisible');\n }\n\n /**\n * Hides the BackButton.\n */\n hide(): void {\n this.isVisible = false;\n }\n\n /**\n * Adds a new event listener.\n * @param event - event to listen.\n * @param listener - listener to add.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('back_button_pressed', listener)\n : this.state.on(event, listener as any)\n );\n\n /**\n * Removes the event listener.\n * @param event - event to listen.\n * @param listener - listener to remove.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('back_button_pressed', listener)\n : this.state.off(event, listener as any)\n );\n\n /**\n * Shows the BackButton.\n */\n show(): void {\n this.isVisible = true;\n }\n}\n","import { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { number } from './number.js';\nimport type { ValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as Date.\n */\nexport const date: ValueParserGenerator<Date> = createValueParserGenerator((value) => (\n value instanceof Date\n ? value\n : new Date(number().parse(value) * 1000)\n), 'Date');\n","import { createTypeError } from '../createTypeError.js';\nimport { parseBySchema } from '../parseBySchema.js';\nimport { ValueParser } from '../ValueParser/ValueParser.js';\nimport type { Schema } from '../types.js';\n\n/**\n * Creates new search params parser according to passed schema.\n * @param schema - object schema.\n * @param type - parser type name.\n */\nexport function searchParams<T>(schema: Schema<T>, type?: string): ValueParser<T, false> {\n return new ValueParser((value) => {\n if (typeof value !== 'string' && !(value instanceof URLSearchParams)) {\n throw createTypeError();\n }\n\n const params = typeof value === 'string' ? new URLSearchParams(value) : value;\n\n return parseBySchema(schema, (field) => {\n const paramValue = params.get(field);\n return paramValue === null ? undefined : paramValue;\n });\n }, false, type);\n}\n","import { json } from '@/parsing/parsers/json.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { string } from '@/parsing/parsers/string.js';\n\nimport type { Chat } from '../types.js';\n\nexport const chat = json<Chat>({\n id: number(),\n type: string(),\n title: string(),\n photoUrl: {\n type: string().optional(),\n from: 'photo_url',\n },\n username: string().optional(),\n}, 'Chat')\n .optional();\n","import { boolean } from '@/parsing/parsers/boolean.js';\nimport { json } from '@/parsing/parsers/json.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { string } from '@/parsing/parsers/string.js';\n\nimport type { User } from '../types.js';\n\nexport const user = json<User>({\n addedToAttachmentMenu: {\n type: boolean().optional(),\n from: 'added_to_attachment_menu',\n },\n allowsWriteToPm: {\n type: boolean().optional(),\n from: 'allows_write_to_pm',\n },\n firstName: {\n type: string(),\n from: 'first_name',\n },\n id: number(),\n isBot: {\n type: boolean().optional(),\n from: 'is_bot',\n },\n isPremium: {\n type: boolean().optional(),\n from: 'is_premium',\n },\n languageCode: {\n type: string().optional(),\n from: 'language_code',\n },\n lastName: {\n type: string().optional(),\n from: 'last_name',\n },\n photoUrl: {\n type: string().optional(),\n from: 'photo_url',\n },\n username: string().optional(),\n}, 'User')\n .optional();\n","import { date } from '@/parsing/parsers/date.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { searchParams } from '@/parsing/parsers/searchParams.js';\nimport { string } from '@/parsing/parsers/string.js';\nimport type { ValueParser } from '@/parsing/ValueParser/ValueParser.js';\n\nimport { chat } from './chat.js';\nimport { user } from './user.js';\nimport type { InitDataParsed } from '../types.js';\n\n/**\n * Returns parser used to parse init data, presented as search params.\n */\nexport function initData(): ValueParser<InitDataParsed, false> {\n return searchParams<InitDataParsed>({\n authDate: {\n type: date(),\n from: 'auth_date',\n },\n canSendAfter: {\n type: number().optional(),\n from: 'can_send_after',\n },\n chat,\n chatInstance: {\n type: string().optional(),\n from: 'chat_instance',\n },\n chatType: {\n type: string().optional(),\n from: 'chat_type',\n },\n hash: string(),\n queryId: {\n type: string().optional(),\n from: 'query_id',\n },\n receiver: user,\n startParam: {\n type: string().optional(),\n from: 'start_param',\n },\n user,\n }, 'InitData');\n}\n","/**\n * Converts a palette key from the Telegram application to the representation used by the package.\n * @param key - palette key.\n */\nexport function keyToLocal(key: string): string {\n return key.replace(/_[a-z]/g, (match) => match[1].toUpperCase());\n}\n\n/**\n * Converts palette key from the local representation to the representation sent from the\n * Telegram application.\n * @param key - palette key.\n */\nexport function keyToExternal(key: string): string {\n return key.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);\n}\n","import { createValueParserGenerator, type ValueParserGenerator } from '@/parsing/createValueParserGenerator.js';\nimport { rgb } from '@/parsing/parsers/rgb.js';\nimport { toRecord } from '@/parsing/toRecord.js';\n\nimport { keyToLocal } from '../keys.js';\nimport type { ThemeParamsParsed } from '../types.js';\n\nexport const themeParams: ValueParserGenerator<ThemeParamsParsed> = createValueParserGenerator(\n (value) => {\n const rgbOptional = rgb().optional();\n\n return Object\n .entries(toRecord(value))\n .reduce<ThemeParamsParsed>((acc, [k, v]) => {\n acc[keyToLocal(k)] = rgbOptional.parse(v);\n return acc;\n }, {});\n },\n 'ThemeParams',\n);\n","import { initData } from '@/components/InitData/parsers/initData.js';\nimport { themeParams } from '@/components/ThemeParams/parsing/themeParams.js';\nimport { boolean } from '@/parsing/parsers/boolean.js';\nimport { searchParams } from '@/parsing/parsers/searchParams.js';\nimport { string } from '@/parsing/parsers/string.js';\n\nimport type { LaunchParams } from './types.js';\n\n/**\n * Parses value as launch parameters.\n * @param value - value to parse.\n */\nexport function parseLaunchParams(value: unknown): LaunchParams {\n return searchParams({\n botInline: {\n type: boolean().optional(),\n from: 'tgWebAppBotInline',\n },\n initData: {\n type: initData().optional(),\n from: 'tgWebAppData',\n },\n initDataRaw: {\n type: string().optional(),\n from: 'tgWebAppData',\n },\n platform: {\n type: string(),\n from: 'tgWebAppPlatform',\n },\n showSettings: {\n type: boolean().optional(),\n from: 'tgWebAppShowSettings',\n },\n startParam: {\n type: string().optional(),\n from: 'tgWebAppStartParam',\n },\n themeParams: {\n type: themeParams(),\n from: 'tgWebAppThemeParams',\n },\n version: {\n type: string(),\n from: 'tgWebAppVersion',\n },\n }).parse(value);\n}\n","import { parseLaunchParams } from './parseLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * @param urlString - URL to extract launch parameters from.\n * @returns Launch parameters from the specified URL.\n * @throws Error if function was unable to extract launch parameters from the passed URL.\n */\nexport function retrieveFromUrl(urlString: string): LaunchParams {\n return parseLaunchParams(\n urlString\n // Replace everything before this first hashtag or question sign.\n .replace(/^[^?#]*[?#]/, '')\n // Replace all hashtags and question signs to make it look like some search params.\n .replace(/[?#]/g, '&'),\n );\n}\n","import { retrieveFromUrl } from './retrieveFromUrl.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * @returns Launch parameters from the current window location hash.\n * @throws Error if function was unable to extract launch parameters from the window location hash.\n */\nexport function retrieveFromLocation(): LaunchParams {\n return retrieveFromUrl(window.location.href);\n}\n","/**\n * Returns the first navigation entry from window.performance.\n * @returns First navigation entry or null, in case performance functionality is not supported\n * or navigation entry was not found.\n */\nexport function getFirstNavigationEntry(): PerformanceNavigationTiming | undefined {\n return performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming | undefined;\n}\n","import { getFirstNavigationEntry } from '@/navigation/getFirstNavigationEntry.js';\n\nimport { retrieveFromUrl } from './retrieveFromUrl.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * @returns Launch parameters based on the first navigation entry.\n * @throws Error if function was unable to extract launch parameters from the navigation entry.\n */\nexport function retrieveFromPerformance(): LaunchParams {\n const navigationEntry = getFirstNavigationEntry();\n if (!navigationEntry) {\n throw new Error('Unable to get first navigation entry.');\n }\n\n return retrieveFromUrl(navigationEntry.name);\n}\n","import type { BackButtonState } from '@/components/BackButton/types.js';\nimport type { BiometryManagerState } from '@/components/BiometryManager/types.js';\nimport type { ClosingBehaviorState } from '@/components/ClosingBehavior/types.js';\nimport type { MainButtonState } from '@/components/MainButton/types.js';\nimport type { MiniAppState } from '@/components/MiniApp/types.js';\nimport type { SettingsButtonState } from '@/components/SettingsButton/types.js';\nimport type { ThemeParamsParsed } from '@/components/ThemeParams/types.js';\nimport type { ViewportState } from '@/components/Viewport/types.js';\n\n/**\n * Describes storage keys and according values.\n */\nexport interface StorageParams {\n backButton: BackButtonState;\n biometryManager: BiometryManagerState;\n closingBehavior: ClosingBehaviorState;\n launchParams: string;\n mainButton: MainButtonState;\n miniApp: MiniAppState;\n settingsButton: SettingsButtonState;\n themeParams: ThemeParamsParsed;\n viewport: ViewportState;\n}\n\n/**\n * Key which could be used to store data in the storage.\n */\nexport type StorageKey = keyof StorageParams;\n\n/**\n * Type specific to the specified storage key.\n */\nexport type StorageValue<K extends StorageKey> = StorageParams[K];\n\n/**\n * Converts passed storage key to the formatted state.\n * @param key - storage key.\n */\nfunction formatKey(key: StorageKey): string {\n return `tma.js/${key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)}`;\n}\n\n/**\n * Saves value in the storage.\n * @param key - storage key.\n * @param value - storage value.\n */\nexport function setStorageValue<K extends StorageKey>(key: K, value: StorageValue<K>): void {\n sessionStorage.setItem(formatKey(key), JSON.stringify(value));\n}\n\n/**\n * Extracts value from the storage.\n * @param key - storage key.\n */\nexport function getStorageValue<K extends StorageKey>(key: K): StorageValue<K> | undefined {\n const value = sessionStorage.getItem(formatKey(key));\n try {\n return value ? JSON.parse(value) : undefined;\n } catch { /* empty */ }\n}\n","import { parseLaunchParams } from '@/launch-params/parseLaunchParams.js';\nimport { getStorageValue } from '@/storage/storage.js';\nimport type { LaunchParams } from '@/launch-params/types.js';\n\n/**\n * @returns Launch parameters stored in the session storage.\n * @throws Error if function was unable to extract launch parameters from the window location hash.\n */\nexport function retrieveFromStorage(): LaunchParams {\n return parseLaunchParams(getStorageValue('launchParams') || '');\n}\n","import { keyToExternal } from '../keys.js';\nimport type { ThemeParamsParsed } from '../types.js';\n\n/**\n * Serializes theme parameters to representation sent from the Telegram application.\n */\nexport function serializeThemeParams(themeParams: ThemeParamsParsed): string {\n return JSON.stringify(\n Object.fromEntries(\n Object\n .entries(themeParams)\n .map(([key, value]) => [keyToExternal(key), value]),\n ),\n );\n}\n","import { serializeThemeParams } from '@/components/ThemeParams/parsing/serializeThemeParams.js';\n\nimport type { LaunchParams } from './types.js';\n\n/**\n * Converts launch parameters to its initial representation.\n * @param value - launch parameters.\n */\nexport function serializeLaunchParams(value: LaunchParams): string {\n const {\n initDataRaw,\n themeParams,\n platform,\n version,\n showSettings,\n startParam,\n botInline,\n } = value;\n\n const params = new URLSearchParams();\n\n params.set('tgWebAppPlatform', platform);\n params.set('tgWebAppThemeParams', serializeThemeParams(themeParams));\n params.set('tgWebAppVersion', version);\n\n if (initDataRaw) {\n params.set('tgWebAppData', initDataRaw);\n }\n\n if (startParam) {\n params.set('tgWebAppStartParam', startParam);\n }\n\n if (typeof showSettings === 'boolean') {\n params.set('tgWebAppShowSettings', showSettings ? '1' : '0');\n }\n\n if (typeof botInline === 'boolean') {\n params.set('tgWebAppBotInline', botInline ? '1' : '0');\n }\n\n return params.toString();\n}\n","import { setStorageValue } from '@/storage/storage.js';\n\nimport { serializeLaunchParams } from './serializeLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * Saves specified launch parameters in the session storage.\n * @param value - launch params to save.\n */\nexport function saveToStorage(value: LaunchParams): void {\n setStorageValue('launchParams', serializeLaunchParams(value));\n}\n","import { retrieveFromLocation } from './retrieveFromLocation.js';\nimport { retrieveFromPerformance } from './retrieveFromPerformance.js';\nimport { retrieveFromStorage } from './retrieveFromStorage.js';\nimport { saveToStorage } from './saveToStorage.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * @returns Launch parameters from any known source.\n * @throws Error if extraction was unsuccessful.\n */\nexport function retrieveLaunchParams(): LaunchParams {\n const errors: unknown[] = [];\n\n // eslint-disable-next-line no-restricted-syntax\n for (const retrieve of [\n // Try to retrieve launch parameters from the current location. This method can return\n // nothing in case, location was changed and then page was reloaded.\n retrieveFromLocation,\n // Then, try using the lower level API - window.performance.\n retrieveFromPerformance,\n // Finally, try to extract launch parameters from the session storage.\n retrieveFromStorage,\n ]) {\n try {\n const lp = retrieve();\n saveToStorage(lp);\n return lp;\n } catch (e) {\n errors.push(e);\n }\n }\n\n throw new Error('Unable to retrieve launch parameters from any known source.');\n}\n","import { getFirstNavigationEntry } from './getFirstNavigationEntry.js';\n\n/**\n * @returns True, if current page was reloaded.\n * @see https://stackoverflow.com/a/36444134/11894710\n */\nexport function isPageReload(): boolean {\n const entry = getFirstNavigationEntry();\n return !!(entry && entry.type === 'reload');\n}\n","import type { CreateRequestIdFn } from './types.js';\n\n/**\n * Creates function which generated request identifiers.\n */\nexport function createRequestIdGenerator(): CreateRequestIdFn {\n let requestId = 0;\n return () => (requestId += 1).toString();\n}\n","import { createPostEvent } from '@/bridge/methods/createPostEvent.js';\nimport { retrieveLaunchParams } from '@/launch-params/retrieveLaunchParams.js';\nimport { createSingleton } from '@/misc/createSingleton.js';\nimport { isPageReload } from '@/navigation/isPageReload.js';\nimport { createRequestIdGenerator } from '@/request-id/createRequestIdGenerator.js';\nimport type { StorageKey, StorageValue } from '@/storage/storage.js';\nimport { getStorageValue, setStorageValue } from '@/storage/storage.js';\nimport { createCleanup } from '@/misc/createCleanup.js';\n\nimport {\n FactoryDynamic,\n FactoryStatic,\n InitStaticComponentFn,\n InitDynamicComponentFn,\n WithOnChange,\n} from './types.js';\n\nconst [createReqId] = createSingleton(createRequestIdGenerator);\n\n/**\n * Creates a new init function based on factory, creating a component, not synchronizing its\n * state with the session storage.\n * @param factory - function creating new component instance.\n */\nexport function createComponentInitFn<R>(factory: FactoryStatic<R>): InitStaticComponentFn<R>;\n\n/**\n * Creates a new init function based on factory, creating a component, synchronizing its\n * state with the session storage.\n * @param factory - function creating new component instance.\n * @param storageKey - storage key to restore component from.\n */\nexport function createComponentInitFn<\n SK extends StorageKey,\n R extends WithOnChange<StorageValue<SK>> | Promise<WithOnChange<StorageValue<SK>>>,\n>(\n storageKey: SK,\n factory: FactoryDynamic<R, SK>,\n): InitDynamicComponentFn<R>;\n\nexport function createComponentInitFn<\n R extends WithOnChange<StorageValue<SK>> | Promise<WithOnChange<StorageValue<SK>>>,\n SK extends StorageKey,\n>(\n factoryStaticOrSK: FactoryStatic<R> | SK,\n factoryDynamic?: FactoryDynamic<R, SK>,\n): InitStaticComponentFn<R> | InitDynamicComponentFn<R> {\n return () => {\n const lp = retrieveLaunchParams();\n const factoryOptions = {\n ...lp,\n postEvent: createPostEvent(lp.version),\n createRequestId: createReqId(),\n };\n\n // In static init mode we have no reason to use the storage to restore the state. In this\n // case we should just call the factory.\n if (typeof factoryStaticOrSK === 'function') {\n return factoryStaticOrSK(factoryOptions);\n }\n\n // Otherwise, we create a new component instance from the storage if possible and add\n // required change listeners.\n const [addCleanup, cleanup, cleanedUp] = createCleanup();\n\n const result = factoryDynamic!({\n ...factoryOptions,\n // State should only be passed only in case, current page was reloaded. If we don't add\n // this check, state restoration will work improperly in the web version of Telegram,\n // when we are always working in the same \"session\" (tab).\n state: isPageReload() ? getStorageValue(factoryStaticOrSK) : undefined,\n addCleanup,\n });\n\n const bindChange = (value: WithOnChange<StorageValue<SK>>) => {\n if (!cleanedUp) {\n addCleanup(\n value.on('change', (state) => {\n setStorageValue(factoryStaticOrSK, state);\n }),\n );\n }\n return value;\n };\n\n return [\n result instanceof Promise ? result.then(bindChange) : bindChange(result),\n cleanup,\n ] as unknown as R;\n };\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { BackButton } from './BackButton.js';\n\n/**\n * @returns A new initialized instance of the `BackButton` class.\n * @see BackButton\n */\nexport const initBackButton = createComponentInitFn('backButton', ({\n postEvent,\n version,\n state = { isVisible: false },\n}) => new BackButton(state.isVisible, version, postEvent));\n","import { WithSupportsAndStateUtils } from '@/classes/WithSupportsAndStateUtils.js';\nimport type { StateEvents } from '@/classes/State/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\n\ntype Emitter<StateShape extends object> = EventEmitter<StateEvents<StateShape>>;\n\nexport class WithSupportsAndTrackableState<StateShape extends object, SupportsMethod extends string>\n extends WithSupportsAndStateUtils<StateShape, SupportsMethod> {\n /**\n * Adds a new event listener.\n */\n on: Emitter<StateShape>['on'] = this.state.on.bind(this.state);\n\n /**\n * Removes the event listener.\n */\n off: Emitter<StateShape>['off'] = this.state.off.bind(this.state);\n}\n","import type { BiometryType, MiniAppsEventPayload } from '@/bridge/events/types.js';\n\nexport interface FormatBiometryInfoResult {\n /**\n * Shows whether biometry is available.\n */\n available: boolean;\n /**\n * Shows whether permission to use biometrics has been requested.\n */\n accessRequested: boolean;\n /**\n * Shows whether permission to use biometrics has been granted.\n */\n accessGranted: boolean;\n /**\n * A unique device identifier that can be used to match the token to the device.\n */\n deviceId: string;\n /**\n * Show whether local storage contains previously saved token.\n */\n tokenSaved: boolean;\n /**\n * The type of biometrics currently available on the device.\n */\n type: BiometryType;\n}\n\n/**\n * Converts `biometry_info_received` to some common shape.\n * @param event - event payload.\n * @see biometry_info_received\n */\nexport function formatEvent(\n event: MiniAppsEventPayload<'biometry_info_received'>,\n): FormatBiometryInfoResult {\n const data = event.available ? event : {\n available: false,\n device_id: '',\n token_saved: false,\n access_requested: false,\n access_granted: false,\n type: '',\n };\n\n return {\n available: true,\n type: data.type,\n deviceId: data.device_id,\n tokenSaved: data.token_saved,\n accessRequested: data.access_requested,\n accessGranted: data.access_granted,\n };\n}\n","import { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport { formatEvent } from '@/components/BiometryManager/formatEvent.js';\nimport type { BiometryType } from '@/bridge/events/types.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type {\n BiometryManagerAuthenticateOptions,\n BiometryManagerProps,\n BiometryManagerRequestAccessOptions,\n BiometryManagerState,\n BiometryManagerUpdateTokenOptions,\n} from '@/components/BiometryManager/types.js';\n\nexport class BiometryManager extends WithSupportsAndTrackableState<BiometryManagerState,\n | 'auth'\n | 'openSettings'\n | 'requestAccess'\n | 'updateToken'\n> {\n private readonly postEvent: PostEvent;\n\n private authPromise?: Promise<string | undefined>;\n\n private accessPromise?: Promise<boolean>;\n\n constructor({ postEvent, version, ...rest }: BiometryManagerProps) {\n super(rest, version, {\n auth: 'web_app_biometry_request_auth',\n openSettings: 'web_app_biometry_open_settings',\n requestAccess: 'web_app_biometry_request_access',\n updateToken: 'web_app_biometry_update_token',\n });\n this.postEvent = postEvent;\n }\n\n /**\n * Shows whether biometry is available.\n */\n get available(): boolean {\n return this.get('available');\n }\n\n /**\n * Shows whether permission to use biometrics has been granted.\n */\n get accessGranted(): boolean {\n return this.get('accessGranted');\n }\n\n /**\n * Shows whether if permission to use biometrics has been requested.\n */\n get accessRequested(): boolean {\n return this.get('accessRequested');\n }\n\n /**\n * Authenticates the user using biometrics.\n * @param options - method options.\n * @since 7.2\n * @returns Token from the local secure storage, if authentication was successful.\n */\n async authenticate({\n reason,\n ...rest\n }: BiometryManagerAuthenticateOptions): Promise<string | undefined> {\n if (!this.authPromise) {\n this.authPromise = request({\n ...rest,\n method: 'web_app_biometry_request_auth',\n event: 'biometry_auth_requested',\n postEvent: this.postEvent,\n params: {\n // TODO: Check if reason is empty works fine.\n reason: (reason || '').trim(),\n },\n })\n .then(({ token }) => token)\n .finally(() => this.authPromise = undefined);\n }\n return this.authPromise;\n }\n\n /**\n * A unique device identifier that can be used to match the token to the device.\n */\n get deviceId(): string {\n return this.get('deviceId');\n }\n\n /**\n * Opens the biometric access settings for bots. Useful when you need to request biometrics\n * access to users who haven't granted it yet.\n *\n * _Note that this method can be called only in response to user interaction with the Mini App\n * interface (e.g. a click inside the Mini App or on the main button)_.\n * @since 7.2\n */\n openSettings(): void {\n this.postEvent('web_app_biometry_open_settings');\n }\n\n /**\n * Requests permission to use biometrics.\n * @since 7.2\n * @returns Promise with true, if access was granted.\n */\n requestAccess({ reason, ...rest }: BiometryManagerRequestAccessOptions = {}): Promise<boolean> {\n if (!this.accessPromise) {\n this.accessPromise = request({\n ...rest,\n postEvent: this.postEvent,\n method: 'web_app_biometry_request_access',\n event: 'biometry_info_received',\n params: { reason: reason || '' },\n })\n .then((response) => {\n // Actualize local state.\n const formatted = formatEvent(response);\n this.set(formatted);\n\n return formatted.accessGranted;\n })\n .finally(() => this.accessPromise = undefined);\n }\n return this.accessPromise;\n }\n\n /**\n * The type of biometrics currently available on the device.\n */\n get biometryType(): BiometryType | undefined {\n return this.get('biometryType');\n }\n\n /**\n * Shows whether token was saved previously in the local secure storage.\n */\n get tokenSaved(): boolean {\n return this.get('tokenSaved');\n }\n\n /**\n * Updates the biometric token in a secure storage on the device.\n * @returns Promise with `true`, if token was updated.\n */\n async updateToken({ token, ...rest }: BiometryManagerUpdateTokenOptions = {}): Promise<boolean> {\n return ['removed', 'updated'].includes(\n (\n await request({\n ...rest,\n postEvent: this.postEvent,\n method: 'web_app_biometry_update_token',\n event: 'biometry_token_updated',\n params: { token: token || '' },\n })\n ).status,\n );\n }\n}\n","import { request } from '@/bridge/utils/request.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nimport { formatEvent } from './formatEvent.js';\nimport type { FormatBiometryInfoResult } from './formatEvent.js';\n\n/**\n * Requests biometry information.\n * @param options - additional execution options.\n */\nexport async function requestBiometryInfo(\n options?: ExecuteWithOptions,\n): Promise<FormatBiometryInfoResult> {\n return formatEvent(\n await request({\n ...(options || {}),\n method: 'web_app_biometry_get_info',\n event: 'biometry_info_received',\n }),\n );\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\nimport { supports } from '@/supports/supports.js';\n\nimport { BiometryManager } from './BiometryManager.js';\nimport { requestBiometryInfo } from './requestBiometryInfo.js';\n\n/**\n * @returns A promise with a new initialized instance of the `BiometryManager` class.\n * @see BiometryManager\n */\nexport const initBiometryManager = createComponentInitFn(\n 'biometryManager',\n async ({ postEvent, version, state }) => {\n return new BiometryManager({\n ...(state || supports('web_app_biometry_get_info', version)\n ? state || await requestBiometryInfo({ timeout: 1000 })\n : {\n available: false,\n accessGranted: false,\n accessRequested: false,\n tokenSaved: false,\n deviceId: '',\n }),\n version,\n postEvent,\n });\n },\n);\n","import { WithStateUtils } from '@/classes/WithStateUtils.js';\nimport type { StateEvents } from '@/classes/State/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\n\ntype Emitter<StateShape extends object> = EventEmitter<StateEvents<StateShape>>;\n\nexport class WithTrackableState<StateShape extends object>\n extends WithStateUtils<StateShape> {\n /**\n * Adds a new event listener.\n */\n on: Emitter<StateShape>['on'] = this.state.on.bind(this.state);\n\n /**\n * Removes the event listener.\n */\n off: Emitter<StateShape>['off'] = this.state.off.bind(this.state);\n}\n","import { WithTrackableState } from '@/classes/WithTrackableState.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { ClosingBehaviorState } from '@/components/ClosingBehavior/types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/closing-behavior\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/closing-behavior\n */\nexport class ClosingBehavior extends WithTrackableState<ClosingBehaviorState> {\n constructor(isConfirmationNeeded: boolean, private readonly postEvent: PostEvent) {\n super({ isConfirmationNeeded });\n }\n\n private set isConfirmationNeeded(value: boolean) {\n this.set('isConfirmationNeeded', value);\n this.postEvent('web_app_setup_closing_behavior', { need_confirmation: value });\n }\n\n /**\n * True, if the confirmation dialog should be shown while the user is trying to close\n * the Mini App.\n */\n get isConfirmationNeeded(): boolean {\n return this.get('isConfirmationNeeded');\n }\n\n /**\n * Disables the confirmation dialog when closing the Mini App.\n */\n disableConfirmation(): void {\n this.isConfirmationNeeded = false;\n }\n\n /**\n * Enables the confirmation dialog when closing the Mini App.\n */\n enableConfirmation(): void {\n this.isConfirmationNeeded = true;\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { ClosingBehavior } from './ClosingBehavior.js';\n\n/**\n * @returns A new initialized instance of the `ClosingBehavior` class.\n * @see ClosingBehavior\n */\nexport const initClosingBehavior = createComponentInitFn(\n 'closingBehavior',\n ({\n postEvent,\n state = { isConfirmationNeeded: false },\n }) => new ClosingBehavior(state.isConfirmationNeeded, postEvent),\n);\n","import { createSupportsFn } from '@/supports/createSupportsFn.js';\nimport type { MiniAppsMethodName } from '@/bridge/methods/types/methods.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\nexport class WithSupports<SupportsMethod extends string> {\n constructor(\n /**\n * Mini Apps version.\n */\n version: Version,\n /**\n * Supports method schema.\n */\n supportsSchema: Record<SupportsMethod, MiniAppsMethodName>,\n ) {\n this.supports = createSupportsFn(version, supportsSchema);\n }\n\n /**\n * @returns True, if specified method is supported by the current component.\n */\n supports: SupportsFn<SupportsMethod>;\n}\n","import { createTypeError } from '../createTypeError.js';\nimport { ValueParser } from '../ValueParser/ValueParser.js';\nimport type { ArrayParserOfResult } from '../ArrayParser/types.js';\nimport type { AnyParser, Parser } from '../types.js';\nimport type { ValueParserParseResult } from '../ValueParser/types.js';\n\n/**\n * Parses incoming value as array.\n * @param value - value to parse.\n */\nfunction parseArray(value: unknown): unknown[] {\n if (Array.isArray(value)) {\n return value;\n }\n\n if (typeof value === 'string') {\n try {\n const json = JSON.parse(value);\n\n if (Array.isArray(json)) {\n return json;\n }\n // eslint-disable-next-line no-empty\n } catch (e) {\n }\n }\n throw createTypeError();\n}\n\nexport class ArrayParser<ItemType, IsOptional extends boolean>\n extends ValueParser<unknown[], IsOptional> {\n private itemParser: Parser<any>;\n\n constructor(\n itemParser: AnyParser<ItemType>,\n isOptional: IsOptional,\n type?: string,\n ) {\n super(parseArray, isOptional, type);\n\n this.itemParser = typeof itemParser === 'function'\n ? itemParser\n : itemParser.parse.bind(itemParser);\n }\n\n /**\n * Attempts to parse passed value\n * @param value - value to parse.\n * @throws {SDKError} ERR_PARSE\n * @see ERR_PARSE\n */\n override parse(value: unknown): ValueParserParseResult<ItemType[], IsOptional> {\n const arr = super.parse(value);\n return arr === undefined ? arr : arr.map(this.itemParser);\n }\n\n of<Item>(itemParser: AnyParser<Item>): ArrayParserOfResult<this, Item, IsOptional> {\n this.itemParser = typeof itemParser === 'function'\n ? itemParser\n : itemParser.parse.bind(itemParser);\n\n return this as ArrayParserOfResult<this, Item, IsOptional>;\n }\n}\n","import { ArrayParser } from '@/parsing/ArrayParser/ArrayParser.js';\n\n/**\n * Parses incoming value as an array.\n * @param parserTypeName - parser type name.\n */\nexport function array(parserTypeName?: string): ArrayParser<unknown, false> {\n return new ArrayParser((value) => value, false, parserTypeName);\n}\n","import { invokeCustomMethod } from '@/bridge/utils/invokeCustomMethod.js';\nimport { WithSupports } from '@/classes/WithSupports.js';\nimport { array } from '@/parsing/parsers/array.js';\nimport { json } from '@/parsing/parsers/json.js';\nimport { string } from '@/parsing/parsers/string.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { CreateRequestIdFn } from '@/request-id/types.js';\nimport type { ExecuteWithTimeout } from '@/types/methods.js';\nimport type { Version } from '@/version/types.js';\n\nfunction objectFromKeys<K extends string, V>(keys: K[], value: V): Record<K, V> {\n return Object.fromEntries(keys.map((k) => [k, value])) as Record<K, V>;\n}\n\n// TODO: Usage.\n\n/**\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/cloud-storage\n */\nexport class CloudStorage extends WithSupports<'delete' | 'get' | 'getKeys' | 'set'> {\n constructor(\n version: Version,\n private readonly createRequestId: CreateRequestIdFn,\n private readonly postEvent: PostEvent,\n ) {\n super(version, {\n delete: 'web_app_invoke_custom_method',\n get: 'web_app_invoke_custom_method',\n getKeys: 'web_app_invoke_custom_method',\n set: 'web_app_invoke_custom_method',\n });\n }\n\n /**\n * Deletes specified key or keys from the cloud storage.\n * @param keyOrKeys - key or keys to delete.\n * @param options - request execution options.\n */\n async delete(keyOrKeys: string | string[], options: ExecuteWithTimeout = {}): Promise<void> {\n const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];\n if (keys.length) {\n await invokeCustomMethod(\n 'deleteStorageValues',\n { keys },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n );\n }\n }\n\n /**\n * Returns list of all keys presented in the cloud storage.\n * @param options - request execution options.\n */\n async getKeys(options: ExecuteWithTimeout = {}): Promise<string[]> {\n return array().of(string()).parse(\n await invokeCustomMethod(\n 'getStorageKeys',\n {},\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n ),\n );\n }\n\n /**\n * Returns map, where key is one of the specified in keys argument, and value is according\n * storage value.\n * @param keys - keys list.\n * @param options - request execution options.\n */\n get<K extends string>(keys: K[], options?: ExecuteWithTimeout): Promise<Record<K, string>>;\n\n /**\n * Returns value of the specified key.\n * @param key - cloud storage key.\n * @param options - request execution options.\n * @return Value of the specified key. In case, key was not created previously, function\n * will return empty string.\n */\n get(key: string, options?: ExecuteWithTimeout): Promise<string>;\n\n async get(\n keyOrKeys: string | string[],\n options: ExecuteWithTimeout = {},\n ): Promise<string | Record<string, string>> {\n const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];\n if (!keys.length) {\n return objectFromKeys(keys, '');\n }\n\n const data = await invokeCustomMethod(\n 'getStorageValues',\n { keys },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n );\n const result = json(objectFromKeys(keys, string()), 'CloudStorageData').parse(data);\n\n return Array.isArray(keyOrKeys) ? result : result[keyOrKeys];\n }\n\n /**\n * Saves specified value by key.\n * @param key - storage key.\n * @param value - storage value.\n * @param options - request execution options.\n */\n async set(key: string, value: string, options: ExecuteWithTimeout = {}): Promise<void> {\n await invokeCustomMethod(\n 'saveStorageValue',\n { key, value },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n );\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { CloudStorage } from './CloudStorage.js';\n\n/**\n * @returns A new initialized instance of the `CloudStorage` class.\n * @see CloudStorage\n */\nexport const initCloudStorage = createComponentInitFn(\n ({ createRequestId, postEvent, version }) => {\n return new CloudStorage(version, createRequestId, postEvent);\n },\n);\n","import { WithSupports } from '@/classes/WithSupports.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type {\n ImpactHapticFeedbackStyle,\n NotificationHapticFeedbackType,\n} from '@/bridge/methods/types/haptic.js';\nimport type { Version } from '@/version/types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/haptic-feedback\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/haptic-feedback\n */\nexport class HapticFeedback\n extends WithSupports<'impactOccurred' | 'notificationOccurred' | 'selectionChanged'> {\n constructor(version: Version, private readonly postEvent: PostEvent) {\n super(version, {\n impactOccurred: 'web_app_trigger_haptic_feedback',\n notificationOccurred: 'web_app_trigger_haptic_feedback',\n selectionChanged: 'web_app_trigger_haptic_feedback',\n });\n }\n\n /**\n * A method tells that an impact occurred. The Telegram app may play the\n * appropriate haptics based on style value passed.\n * @param style - impact style.\n */\n impactOccurred(style: ImpactHapticFeedbackStyle): void {\n this.postEvent('web_app_trigger_haptic_feedback', {\n type: 'impact',\n impact_style: style,\n });\n }\n\n /**\n * A method tells that a task or action has succeeded, failed, or produced\n * a warning. The Telegram app may play the appropriate haptics based on\n * type value passed.\n * @param type - notification type.\n */\n notificationOccurred(type: NotificationHapticFeedbackType): void {\n this.postEvent('web_app_trigger_haptic_feedback', {\n type: 'notification',\n notification_type: type,\n });\n }\n\n /**\n * A method tells that the user has changed a selection. The Telegram app\n * may play the appropriate haptics.\n *\n * Do not use this feedback when the user makes or confirms a selection;\n * use it only when the selection changes.\n */\n selectionChanged(): void {\n this.postEvent('web_app_trigger_haptic_feedback', { type: 'selection_change' });\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { HapticFeedback } from './HapticFeedback.js';\n\n/**\n * @returns A new initialized instance of the `HapticFeedback` class.\n * @see HapticFeedback\n */\nexport const initHapticFeedback = createComponentInitFn(\n ({ version, postEvent }) => new HapticFeedback(version, postEvent),\n);\n","import type {\n Chat,\n ChatType,\n InitDataParsed,\n User,\n} from './types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/init-data\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/init-data\n */\nexport class InitData {\n constructor(private readonly initData: InitDataParsed) {\n }\n\n /**\n * @see InitDataParsed.authDate\n */\n get authDate(): Date {\n return this.initData.authDate;\n }\n\n /**\n * @see InitDataParsed.canSendAfter\n */\n get canSendAfter(): number | undefined {\n return this.initData.canSendAfter;\n }\n\n /**\n * Date after which it is allowed to call\n * the [answerWebAppQuery](https://core.telegram.org/bots/api#answerwebappquery) method.\n */\n get canSendAfterDate(): Date | undefined {\n const { canSendAfter } = this;\n\n return canSendAfter\n ? new Date(this.authDate.getTime() + canSendAfter * 1000)\n : undefined;\n }\n\n /**\n * @see InitDataParsed.chat\n */\n get chat(): Chat | undefined {\n return this.initData.chat;\n }\n\n /**\n * @see InitDataParsed.chatType\n */\n get chatType(): ChatType | undefined {\n return this.initData.chatType;\n }\n\n /**\n * @see InitDataParsed.chatInstance\n */\n get chatInstance(): string | undefined {\n return this.initData.chatInstance;\n }\n\n /**\n * @see InitDataParsed.hash\n */\n get hash(): string {\n return this.initData.hash;\n }\n\n /**\n * @see InitDataParsed.queryId\n */\n get queryId(): string | undefined {\n return this.initData.queryId;\n }\n\n /**\n * @see InitDataParsed.receiver\n */\n get receiver(): User | undefined {\n return this.initData.receiver;\n }\n\n /**\n * @see InitDataParsed.startParam\n */\n get startParam(): string | undefined {\n return this.initData.startParam;\n }\n\n /**\n * @see InitDataParsed.user\n */\n get user(): User | undefined {\n return this.initData.user;\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { InitData } from './InitData.js';\n\n/**\n * @returns A new initialized instance of the `InitData` class or undefined.\n * @see InitData\n */\nexport const initInitData = createComponentInitFn(\n ({ initData }) => (initData ? new InitData(initData) : undefined),\n);\n","import { initData } from './parsers/initData.js';\nimport type { InitDataParsed } from './types.js';\n\n/**\n * Parses incoming value as init data.\n * @param value - value to parse.\n */\nexport function parseInitData(value: unknown): InitDataParsed {\n return initData().parse(value);\n}\n","import { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport type { InvoiceStatus } from '@/bridge/events/types.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { Version } from '@/version/types.js';\n\nimport type { InvoiceState } from './types.js';\n\n// TODO: Usage.\n\n/**\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/invoice\n */\nexport class Invoice extends WithSupportsAndTrackableState<InvoiceState, 'open'> {\n constructor(\n isOpened: boolean,\n version: Version,\n private readonly postEvent: PostEvent,\n ) {\n super({ isOpened }, version, { open: 'web_app_open_invoice' });\n }\n\n private set isOpened(value) {\n this.set('isOpened', value);\n }\n\n /**\n * True if invoice is currently opened.\n */\n get isOpened(): boolean {\n return this.get('isOpened');\n }\n\n /**\n * Opens an invoice using its slug.\n * @param slug - invoice slug.\n * @throws {Error} Invoice is already opened.\n */\n open(slug: string): Promise<InvoiceStatus>;\n\n /**\n * Opens an invoice using its url. It expects passing link in full format, with hostname \"t.me\".\n * @param url - invoice URL.\n * @param type - value type.\n * @throws {Error} Invoice is already opened.\n */\n open(url: string, type: 'url'): Promise<InvoiceStatus>;\n\n async open(urlOrSlug: string, type?: 'url'): Promise<InvoiceStatus> {\n if (this.isOpened) {\n throw new Error('Invoice is already opened');\n }\n\n let slug: string;\n if (!type) {\n slug = urlOrSlug;\n } else {\n const { hostname, pathname } = new URL(urlOrSlug, window.location.href);\n if (hostname !== 't.me') {\n throw new Error(`Incorrect hostname: ${hostname}`);\n }\n\n // Valid examples:\n // \"/invoice/my-slug\"\n // \"/$my-slug\"\n const match = pathname.match(/^\\/(\\$|invoice\\/)([A-Za-z0-9\\-_=]+)$/);\n if (!match) {\n // eslint-disable-next-line no-template-curly-in-string\n throw new Error('Link pathname has incorrect format. Expected to receive \"/invoice/{slug}\" or \"/${slug}\"');\n }\n [, , slug] = match;\n }\n\n this.isOpened = true;\n\n try {\n const result = await request({\n method: 'web_app_open_invoice',\n event: 'invoice_closed',\n params: { slug },\n postEvent: this.postEvent,\n capture(data) {\n return slug === data.slug;\n },\n });\n\n return result.status;\n } finally {\n this.isOpened = false;\n }\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { Invoice } from './Invoice.js';\n\n/**\n * @returns A new initialized instance of the `Invoice` class.\n * @see Invoice\n */\nexport const initInvoice = createComponentInitFn(\n ({ version, postEvent }) => new Invoice(false, version, postEvent),\n);\n","import { off } from '@/bridge/events/listening/off.js';\nimport { on } from '@/bridge/events/listening/on.js';\nimport { WithStateUtils } from '@/classes/WithStateUtils.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { RGB } from '@/colors/types.js';\nimport type {\n MainButtonEvents,\n MainButtonParams,\n MainButtonProps,\n MainButtonState,\n} from '@/components/MainButton/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\n\ntype Emitter = EventEmitter<MainButtonEvents>;\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/main-button\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/main-button\n */\nexport class MainButton extends WithStateUtils<MainButtonState> {\n private readonly postEvent: PostEvent;\n\n constructor({ postEvent, ...rest }: MainButtonProps) {\n super(rest);\n this.postEvent = postEvent;\n }\n\n /**\n * The MainButton background color.\n */\n get bgColor(): RGB {\n return this.get('bgColor');\n }\n\n /**\n * Sends current local state to the Telegram application.\n */\n private commit(): void {\n // We should not commit changes until payload is correct. We could\n // have some invalid values in case, button instance was created\n // with empty values. Otherwise, an unexpected behavior could be received.\n if (this.text === '') {\n return;\n }\n\n this.postEvent('web_app_setup_main_button', {\n is_visible: this.isVisible,\n is_active: this.isEnabled,\n is_progress_visible: this.isLoaderVisible,\n text: this.text,\n color: this.bgColor,\n text_color: this.textColor,\n });\n }\n\n /**\n * Disables the MainButton.\n * @see Does not work on Android: https://github.com/Telegram-Mini-Apps/issues/issues/1\n */\n disable(): this {\n this.isEnabled = false;\n return this;\n }\n\n /**\n * Enables the MainButton.\n */\n enable(): this {\n this.isEnabled = true;\n return this;\n }\n\n /**\n * Hides the MainButton.\n */\n hide(): this {\n this.isVisible = false;\n return this;\n }\n\n /**\n * Hides the MainButton loading indicator.\n */\n hideLoader(): this {\n this.isLoaderVisible = false;\n return this;\n }\n\n private set isEnabled(isEnabled: boolean) {\n this.setParams({ isEnabled });\n }\n\n /**\n * True if the MainButton is enabled.\n */\n get isEnabled(): boolean {\n return this.get('isEnabled');\n }\n\n private set isLoaderVisible(isLoaderVisible: boolean) {\n this.setParams({ isLoaderVisible });\n }\n\n /**\n * True if the MainButton loader is visible.\n */\n get isLoaderVisible(): boolean {\n return this.get('isLoaderVisible');\n }\n\n private set isVisible(isVisible: boolean) {\n this.setParams({ isVisible });\n }\n\n /**\n * True if the MainButton is visible.\n */\n get isVisible(): boolean {\n return this.get('isVisible');\n }\n\n /**\n * Adds a new event listener.\n * @param event - event to listen.\n * @param listener - listener to add.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('main_button_pressed', listener)\n : this.state.on(event, listener as any)\n );\n\n /**\n * Removes the event listener.\n * @param event - event to listen.\n * @param listener - listener to remove.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('main_button_pressed', listener)\n : this.state.off(event, listener as any)\n );\n\n /**\n * Shows the MainButton.\n *\n * Note that opening the Mini App from the attachment menu hides the main button until the\n * user interacts with the Mini App interface.\n */\n show(): this {\n this.isVisible = true;\n return this;\n }\n\n /**\n * Shows a loading indicator on the Main Button.\n */\n showLoader(): this {\n this.isLoaderVisible = true;\n return this;\n }\n\n /**\n * Sets a new MainButton text. Minimal length for the text is 1 symbol, and maximum is 64 symbols.\n * @param text - a new text.\n */\n setText(text: string): this {\n return this.setParams({ text });\n }\n\n /**\n * Sets a new Main Button text color.\n * @param textColor - new text color.\n */\n setTextColor(textColor: RGB): this {\n return this.setParams({ textColor });\n }\n\n /**\n * Updates current Main Button color.\n * @param bgColor - color to set.\n */\n setBgColor(bgColor: RGB): this {\n return this.setParams({ bgColor });\n }\n\n /**\n * Allows setting multiple Main Button parameters.\n * @param params - Main Button parameters.\n */\n setParams(params: Partial<MainButtonParams>): this {\n this.set(params);\n this.commit();\n return this;\n }\n\n /**\n * The MainButton text.\n */\n get text(): string {\n return this.get('text');\n }\n\n /**\n * The MainButton text color.\n */\n get textColor(): RGB {\n return this.get('textColor');\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { MainButton } from './MainButton.js';\n\n/**\n * @returns A new initialized instance of the `MainButton` class.\n * @see MainButton\n */\nexport const initMainButton = createComponentInitFn(\n 'mainButton',\n ({\n postEvent,\n themeParams,\n state = {\n isVisible: false,\n isEnabled: false,\n text: '',\n isLoaderVisible: false,\n textColor: themeParams.buttonTextColor || '#ffffff',\n bgColor: themeParams.buttonColor || '#000000',\n },\n }) => new MainButton({ ...state, postEvent }),\n);\n","import { date } from '@/parsing/parsers/date.js';\nimport { json } from '@/parsing/parsers/json.js';\nimport { number } from '@/parsing/parsers/number.js';\nimport { searchParams } from '@/parsing/parsers/searchParams.js';\nimport { string } from '@/parsing/parsers/string.js';\nimport type { ValueParser } from '@/parsing/ValueParser/ValueParser.js';\n\nimport type { RequestedContact } from '../types.js';\n\n/**\n * Returns function which parses incoming value as a contact information.\n */\nexport function contact(): ValueParser<RequestedContact, false> {\n return searchParams({\n contact: json({\n userId: {\n type: number(),\n from: 'user_id',\n },\n phoneNumber: {\n type: string(),\n from: 'phone_number',\n },\n firstName: {\n type: string(),\n from: 'first_name',\n },\n lastName: {\n type: string().optional(),\n from: 'last_name',\n },\n }),\n authDate: {\n type: date(),\n from: 'auth_date',\n },\n hash: string(),\n }, 'RequestedContact');\n}\n","import { supports } from '@/supports/supports.js';\nimport type {\n MiniAppsMethodVersionedParams,\n MiniAppsMethodWithVersionedParams,\n} from '@/bridge/methods/types/methods.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\ntype HasCheckSupportMethodTuple = {\n [M in MiniAppsMethodWithVersionedParams]: [M, MiniAppsMethodVersionedParams<M>]\n}[MiniAppsMethodWithVersionedParams];\n\n/**\n * Returns function, which accepts predefined method name and checks if it is supported\n * via passed schema and version.\n * @param schema - object which contains methods names and TWA methods with specified parameter\n * as a dependency.\n * @param version - platform version.\n */\nexport function createSupportsParamFn<Method extends string>(\n version: Version,\n schema: Record<Method, HasCheckSupportMethodTuple>,\n): SupportsFn<Method> {\n return (method) => {\n const [tmaMethod, param] = schema[method];\n\n return supports(tmaMethod, param, version);\n };\n}\n","/**\n * Awaits for specified amount of time.\n * @param duration - duration in ms to await.\n */\nexport function sleep(duration: number): Promise<void> {\n return new Promise((res) => {\n setTimeout(res, duration);\n });\n}\n","import { invokeCustomMethod } from '@/bridge/utils/invokeCustomMethod.js';\nimport { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport { isColorDark } from '@/colors/isColorDark.js';\nimport { isRGB } from '@/colors/isRGB.js';\nimport { contact } from '@/components/MiniApp/parsing/contact.js';\nimport { createSupportsParamFn } from '@/supports/createSupportsParamFn.js';\nimport { createTimeoutError } from '@/timeout/createTimeoutError.js';\nimport { sleep } from '@/timeout/sleep.js';\nimport { withTimeout } from '@/timeout/withTimeout.js';\nimport type { PhoneRequestedStatus, WriteAccessRequestedStatus } from '@/bridge/events/types.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { SwitchInlineQueryChatType } from '@/bridge/methods/types/methods.js';\nimport type { RGB } from '@/colors/types.js';\nimport type { MiniAppHeaderColor, MiniAppProps, MiniAppState, RequestedContact } from '@/components/MiniApp/types.js';\nimport type { CreateRequestIdFn } from '@/request-id/types.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { ExecuteWithTimeout } from '@/types/methods.js';\n\n/**\n * Provides common Mini Apps functionality not covered by other system components.\n */\nexport class MiniApp extends WithSupportsAndTrackableState<\n MiniAppState,\n | 'requestPhoneAccess'\n | 'requestWriteAccess'\n | 'switchInlineQuery'\n | 'setHeaderColor'\n | 'setBackgroundColor'\n> {\n private readonly botInline: boolean;\n\n private readonly postEvent: PostEvent;\n\n private readonly createRequestId: CreateRequestIdFn;\n\n private requestPhoneAccessPromise: Promise<PhoneRequestedStatus> | undefined;\n\n private requestWriteAccessPromise: Promise<WriteAccessRequestedStatus> | undefined;\n\n constructor({ postEvent, createRequestId, version, botInline, ...rest }: MiniAppProps) {\n super(rest, version, {\n requestPhoneAccess: 'web_app_request_phone',\n requestWriteAccess: 'web_app_request_write_access',\n switchInlineQuery: 'web_app_switch_inline_query',\n setHeaderColor: 'web_app_set_header_color',\n setBackgroundColor: 'web_app_set_background_color',\n });\n\n this.createRequestId = createRequestId;\n this.postEvent = postEvent;\n this.botInline = botInline;\n\n const supportsOriginal = this.supports.bind(this);\n this.supports = (method) => {\n if (!supportsOriginal(method)) {\n return false;\n }\n\n // web_app_switch_inline_query requires a Mini App to be in inline mode, that's why we\n // add 1 more check here.\n return method !== 'switchInlineQuery' || botInline;\n };\n\n this.supportsParam = createSupportsParamFn(version, {\n 'setHeaderColor.color': ['web_app_set_header_color', 'color'],\n });\n }\n\n /**\n * Attempts to get requested contact.\n * @param timeout - request timeout.\n */\n private async getRequestedContact({\n timeout = 10000,\n }: ExecuteWithTimeout = {}): Promise<RequestedContact> {\n return contact().parse(\n await invokeCustomMethod(\n 'getRequestedContact',\n {},\n this.createRequestId(),\n { postEvent: this.postEvent, timeout },\n ),\n );\n }\n\n /**\n * The Mini App background color.\n * @example \"#ffaabb\"\n */\n get bgColor(): RGB {\n return this.get('bgColor');\n }\n\n /**\n * Closes the Mini App.\n */\n close(): void {\n this.postEvent('web_app_close');\n }\n\n /**\n * The Mini App header color.\n * @example \"#ffaabb\"\n * @example \"bg_color\"\n */\n get headerColor(): MiniAppHeaderColor {\n return this.get('headerColor');\n }\n\n /**\n * True if the Mini App is currently launched in bot inline mode.\n */\n get isBotInline(): boolean {\n return this.botInline;\n }\n\n /**\n * True if current Mini App background color is recognized as dark.\n */\n get isDark(): boolean {\n return isColorDark(this.bgColor);\n }\n\n /**\n * Informs the Telegram app that the Mini App is ready to be displayed.\n *\n * It is recommended to call this method as early as possible, as soon as all essential\n * interface elements loaded. Once this method called, the loading placeholder is hidden\n * and the Mini App shown.\n *\n * If the method not called, the placeholder will be hidden only when the page fully loaded.\n */\n ready(): void {\n this.postEvent('web_app_ready');\n }\n\n /**\n * Requests current user contact information. In contrary to requestPhoneAccess, this method\n * returns promise with contact information that rejects in case, user denied access, or request\n * failed.\n * @param options - additional options.\n */\n async requestContact({ timeout = 5000 }: ExecuteWithTimeout = {}): Promise<RequestedContact> {\n // First of all, let's try to get the requested contact. Probably, we already requested\n // it before.\n try {\n return await this.getRequestedContact();\n } catch { /* empty */\n }\n\n // Then, request access to user's phone.\n const status = await this.requestPhoneAccess();\n if (status !== 'sent') {\n throw new Error('Access denied.');\n }\n\n // Expected deadline.\n const deadlineAt = Date.now() + timeout;\n\n // Time to wait before executing the next request.\n let sleepTime = 50;\n\n // We are trying to retrieve the requested contact until deadline was reached.\n return withTimeout(async () => {\n while (Date.now() < deadlineAt) {\n try {\n return await this.getRequestedContact();\n } catch (e) { /* empty */\n }\n\n // Sleep for some time.\n await sleep(sleepTime);\n\n // Increase the sleep time not to kill the backend service.\n sleepTime += 50;\n }\n\n throw createTimeoutError(timeout);\n }, timeout);\n }\n\n /**\n * Requests current user phone access. Method returns promise, which resolves\n * status of the request. In case, user accepted the request, Mini App bot will receive\n * the according notification.\n *\n * To obtain the retrieved information instead, utilize the `requestContact` method.\n * @param options - additional options.\n * @see requestContact\n */\n async requestPhoneAccess(options: ExecuteWithTimeout = {}): Promise<PhoneRequestedStatus> {\n if (!this.requestPhoneAccessPromise) {\n this.requestPhoneAccessPromise = request({\n ...options,\n method: 'web_app_request_phone',\n event: 'phone_requested',\n postEvent: this.postEvent,\n })\n .then(({ status }) => status)\n .finally(() => this.requestPhoneAccessPromise = undefined);\n }\n return this.requestPhoneAccessPromise;\n }\n\n /**\n * Requests write message access to current user.\n * @param options - additional options.\n */\n async requestWriteAccess(options: ExecuteWithTimeout = {}): Promise<WriteAccessRequestedStatus> {\n if (!this.requestWriteAccessPromise) {\n this.requestWriteAccessPromise = request({\n ...options,\n method: 'web_app_request_write_access',\n event: 'write_access_requested',\n postEvent: this.postEvent,\n })\n .then(({ status }) => status)\n .finally(() => this.requestWriteAccessPromise = undefined);\n }\n return this.requestWriteAccessPromise;\n }\n\n /**\n * A method used to send data to the bot. When this method called, a service message sent to\n * the bot containing the data of the length up to 4096 bytes, and the Mini App closed. See the\n * field `web_app_data` in the class [Message](https://core.telegram.org/bots/api#message).\n *\n * This method is only available for Mini Apps launched via a Keyboard button.\n * @param data - data to send to bot.\n * @throws {Error} data has incorrect size.\n */\n sendData(data: string): void {\n const { size } = new Blob([data]);\n if (!size || size > 4096) {\n throw new Error(`Passed data has incorrect size: ${size}`);\n }\n this.postEvent('web_app_data_send', { data });\n }\n\n /**\n * Updates current Mini App header color.\n *\n * @see No effect on desktop: https://github.com/Telegram-Mini-Apps/tma.js/issues/9\n * @see Works incorrectly in Android: https://github.com/Telegram-Mini-Apps/tma.js/issues/8\n * @param color - color key or RGB color.\n */\n setHeaderColor(color: MiniAppHeaderColor): void {\n this.postEvent('web_app_set_header_color', isRGB(color) ? { color } : { color_key: color });\n this.set('headerColor', color);\n }\n\n /**\n * Updates current Mini App background color.\n *\n * @see No effect on desktop: https://github.com/Telegram-Mini-Apps/tma.js/issues/9\n * @see Works incorrectly in Android: https://github.com/Telegram-Mini-Apps/tma.js/issues/8\n * @param color - RGB color.\n */\n setBgColor(color: RGB): void {\n this.postEvent('web_app_set_background_color', { color });\n this.set('bgColor', color);\n }\n\n /**\n * Checks if specified method parameter is supported by current component.\n */\n supportsParam: SupportsFn<'setHeaderColor.color'>;\n\n /**\n * Inserts the bot's username and the specified inline query in the current chat's input field.\n * Query may be empty, in which case only the bot's username will be inserted. The client prompts\n * the user to choose a specific chat, then opens that chat and inserts the bot's username and\n * the specified inline query in the input field.\n * @param text - text which should be inserted in the input after the current bot name. Max\n * length is 256 symbols.\n * @param chatTypes - List of chat types which could be chosen to send the message. Could be\n * empty list.\n */\n switchInlineQuery(text: string, chatTypes: SwitchInlineQueryChatType[] = []): void {\n if (!this.supports('switchInlineQuery') && !this.isBotInline) {\n throw new Error('Method is unsupported because Mini App should be launched in inline mode.');\n }\n this.postEvent('web_app_switch_inline_query', { query: text, chat_types: chatTypes });\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { MiniApp } from './MiniApp.js';\n\n/**\n * @returns A new initialized instance of the `MiniApp` class.\n * @see MiniApp\n */\nexport const initMiniApp = createComponentInitFn(\n 'miniApp',\n ({\n themeParams,\n botInline = false,\n state = {\n bgColor: themeParams.bgColor || '#ffffff',\n headerColor: themeParams.headerBgColor || '#000000',\n },\n ...rest\n }) => new MiniApp({ ...rest, ...state, botInline }),\n);\n","import type { PopupButton, PopupParams as BridgePopupParams } from '@/bridge/methods/types/popup.js';\n\nimport type { OpenPopupOptions } from './types.js';\n\n/**\n * Prepares popup parameters before sending them to native app.\n * @param params - popup parameters.\n */\nexport function preparePopupParams(params: OpenPopupOptions): BridgePopupParams {\n const message = params.message.trim();\n const title = (params.title || '').trim();\n const buttons = params.buttons || [];\n let preparedButtons: PopupButton[];\n\n // Check title.\n if (title.length > 64) {\n throw new Error(`Title has incorrect size: ${title.length}`);\n }\n\n // Check message.\n if (!message.length || message.length > 256) {\n throw new Error(`Message has incorrect size: ${message.length}`);\n }\n\n // Check buttons.\n if (buttons.length > 3) {\n throw new Error(`Buttons have incorrect size: ${buttons.length}`);\n }\n\n // Append button in case, there are no buttons passed.\n if (!buttons.length) {\n preparedButtons = [{ type: 'close', id: '' }];\n } else {\n // Otherwise, check all the buttons.\n preparedButtons = buttons.map((b) => {\n const { id = '' } = b;\n\n // Check button ID.\n if (id.length > 64) {\n throw new Error(`Button ID has incorrect size: ${id}`);\n }\n\n if (!b.type || b.type === 'default' || b.type === 'destructive') {\n const text = b.text.trim();\n\n if (!text.length || text.length > 64) {\n const type = b.type || 'default';\n\n throw new Error(`Button text with type \"${type}\" has incorrect size: ${b.text.length}`);\n }\n\n return { ...b, text, id };\n }\n\n return { ...b, id };\n });\n }\n return { title, message, buttons: preparedButtons };\n}\n","import { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport { preparePopupParams } from '@/components/Popup/preparePopupParams.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { OpenPopupOptions, PopupState } from '@/components/Popup/types.js';\nimport type { Version } from '@/version/types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/popup\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/popup\n */\nexport class Popup extends WithSupportsAndTrackableState<PopupState, 'open'> {\n constructor(isOpened: boolean, version: Version, private readonly postEvent: PostEvent) {\n super({ isOpened }, version, { open: 'web_app_open_popup' });\n }\n\n private set isOpened(value) {\n this.set('isOpened', value);\n }\n\n /**\n * True if the Popup is opened.\n */\n get isOpened(): boolean {\n return this.get('isOpened');\n }\n\n /**\n * A method that shows a native popup described by the `params` argument.\n * Promise will be resolved when popup is closed. Resolved value will have\n * an identifier of pressed button.\n *\n * In case, user clicked outside the popup or clicked top right popup close\n * button, null will be returned.\n *\n * @param options - popup parameters.\n * @throws {Error} Popup is already opened.\n */\n async open(options: OpenPopupOptions): Promise<string | null> {\n if (this.isOpened) {\n throw new Error('Popup is already opened.');\n }\n\n this.isOpened = true;\n\n try {\n const { button_id: buttonId = null } = await request({\n event: 'popup_closed',\n method: 'web_app_open_popup',\n postEvent: this.postEvent,\n params: preparePopupParams(options),\n });\n return buttonId;\n } finally {\n this.isOpened = false;\n }\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { Popup } from './Popup.js';\n\n/**\n * @returns A new initialized instance of the `Popup` class.\n * @see Popup\n */\nexport const initPopup = createComponentInitFn(\n ({ postEvent, version }) => new Popup(false, version, postEvent),\n);\n","import { request } from '@/bridge/utils/request.js';\nimport { WithSupportsAndTrackableState } from '@/classes/WithSupportsAndTrackableState.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { Version } from '@/version/types.js';\n\nimport { QRScannerOpenOptions, QRScannerState } from './types.js';\n\n// TODO: Usage\n\n/**\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/qr-scanner\n */\nexport class QRScanner extends WithSupportsAndTrackableState<QRScannerState, 'close' | 'open'> {\n constructor(isOpened: boolean, version: Version, private readonly postEvent: PostEvent) {\n super({ isOpened }, version, {\n close: 'web_app_close_scan_qr_popup',\n open: 'web_app_open_scan_qr_popup',\n });\n }\n\n /**\n * Closes scanner.\n */\n close(): void {\n this.postEvent('web_app_close_scan_qr_popup');\n this.isOpened = false;\n }\n\n private set isOpened(value) {\n this.set('isOpened', value);\n }\n\n /**\n * Returns true in case, QR scanner is currently opened.\n */\n get isOpened(): boolean {\n return this.get('isOpened');\n }\n\n /**\n * Opens scanner with specified title shown to user. Method returns promise\n * with scanned QR content in case, it was scanned. It will contain null in\n * case, scanner was closed.\n * @param options - method options.\n */\n async open(options?: QRScannerOpenOptions): Promise<string | null>;\n /**\n * Opens scanner with specified title shown to user. Method returns promise\n * with scanned QR content in case, it was scanned. It will contain null in\n * case, scanner was closed.\n * @param text - title to display.\n */\n async open(text?: string): Promise<string | null>;\n async open(textOrOptions?: QRScannerOpenOptions | string): Promise<string | null> {\n if (this.isOpened) {\n throw new Error('QR scanner is already opened.');\n }\n\n const { text, capture }: QRScannerOpenOptions = (\n typeof textOrOptions === 'string'\n ? { text: textOrOptions }\n : textOrOptions\n ) || {};\n this.isOpened = true;\n\n try {\n const result = await request({\n method: 'web_app_open_scan_qr_popup',\n event: ['qr_text_received', 'scan_qr_popup_closed'],\n postEvent: this.postEvent,\n params: { text },\n capture(ev) {\n return ev.event === 'scan_qr_popup_closed' || !capture || capture(ev.payload);\n },\n }) || {};\n\n const qr = result.data || null;\n if (qr) {\n this.close();\n }\n return qr;\n } catch(e) {\n this.isOpened = false;\n throw e;\n }\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { QRScanner } from './QRScanner.js';\n\n/**\n * @returns A new initialized instance of the `QRScanner` class.\n * @see QRScanner\n */\nexport const initQRScanner = createComponentInitFn(\n ({ version, postEvent }) => new QRScanner(false, version, postEvent),\n);\n","import { off } from '@/bridge/events/listening/off.js';\nimport { on } from '@/bridge/events/listening/on.js';\nimport { WithSupportsAndStateUtils } from '@/classes/WithSupportsAndStateUtils.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type {\n SettingsButtonEvents,\n SettingsButtonState,\n} from '@/components/SettingsButton/types.js';\nimport type { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport type { Version } from '@/version/types.js';\n\ntype Emitter = EventEmitter<SettingsButtonEvents>;\n\nexport class SettingsButton extends WithSupportsAndStateUtils<SettingsButtonState, 'show' | 'hide'> {\n constructor(isVisible: boolean, version: Version, private readonly postEvent: PostEvent) {\n super({ isVisible }, version, {\n show: 'web_app_setup_settings_button',\n hide: 'web_app_setup_settings_button',\n });\n }\n\n private set isVisible(visible: boolean) {\n this.set('isVisible', visible);\n this.postEvent('web_app_setup_settings_button', { is_visible: visible });\n }\n\n /**\n * True if the SettingsButton is visible.\n */\n get isVisible(): boolean {\n return this.get('isVisible');\n }\n\n /**\n * Hides the SettingsButton.\n */\n hide(): void {\n this.isVisible = false;\n }\n\n /**\n * Adds a new event listener.\n * @param event - event to listen.\n * @param listener - listener to add.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('settings_button_pressed', listener)\n : this.state.on(event, listener as any)\n );\n\n /**\n * Removes the event listener.\n * @param event - event to listen.\n * @param listener - listener to remove.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('settings_button_pressed', listener)\n : this.state.off(event, listener as any)\n );\n\n /**\n * Shows the SettingsButton.\n */\n show(): void {\n this.isVisible = true;\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { SettingsButton } from './SettingsButton.js';\n\n/**\n * @returns A new initialized instance of the `SettingsButton` class.\n * @see SettingsButton\n */\nexport const initSettingsButton = createComponentInitFn(\n 'settingsButton',\n ({\n version,\n postEvent,\n state = { isVisible: false },\n }) => new SettingsButton(state.isVisible, version, postEvent),\n);\n","import { themeParams } from '@/components/ThemeParams/parsing/themeParams.js';\n\nimport type { ThemeParamsParsed } from '../types.js';\n\n/**\n * Parses incoming value as theme parameters.\n * @param value - value to parse.\n */\nexport function parseThemeParams(value: unknown): ThemeParamsParsed {\n return themeParams().parse(value);\n}\n","import { on } from '@/bridge/events/listening/on.js';\nimport { WithTrackableState } from '@/classes/WithTrackableState.js';\nimport { isColorDark } from '@/colors/isColorDark.js';\nimport type { RGB } from '@/colors/types.js';\nimport type { RemoveEventListenerFn } from '@/events/types.js';\n\nimport { parseThemeParams } from './parsing/parseThemeParams.js';\nimport type { ThemeParamsParsed, ThemeParamsState } from './types.js';\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/theming\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/theme-params\n */\nexport class ThemeParams extends WithTrackableState<ThemeParamsState> {\n /**\n * @since v6.10\n */\n get accentTextColor(): RGB | undefined {\n return this.get('accentTextColor');\n }\n\n get bgColor(): RGB | undefined {\n return this.get('bgColor');\n }\n\n get buttonColor(): RGB | undefined {\n return this.get('buttonColor');\n }\n\n get buttonTextColor(): RGB | undefined {\n return this.get('buttonTextColor');\n }\n\n get destructiveTextColor(): RGB | undefined {\n return this.get('destructiveTextColor');\n }\n\n /**\n * Returns the copy of the internal state of the current component instance.\n */\n getState(): ThemeParamsParsed {\n return this.clone();\n }\n\n /**\n * @since v6.10\n */\n get headerBgColor(): RGB | undefined {\n return this.get('headerBgColor');\n }\n\n get hintColor(): RGB | undefined {\n return this.get('hintColor');\n }\n\n /**\n * @returns True in case, current color scheme is recognized as dark. This\n * value is calculated according to theme bg color.\n */\n get isDark(): boolean {\n return !this.bgColor || isColorDark(this.bgColor);\n }\n\n get linkColor(): RGB | undefined {\n return this.get('linkColor');\n }\n\n get secondaryBgColor(): RGB | undefined {\n return this.get('secondaryBgColor');\n }\n\n /**\n * @since v6.10\n */\n get sectionBgColor(): RGB | undefined {\n return this.get('sectionBgColor');\n }\n\n /**\n * @since v6.10\n */\n get sectionHeaderTextColor(): RGB | undefined {\n return this.get('sectionHeaderTextColor');\n }\n\n /**\n * Starts listening to the external theme changes and applies them.\n * @returns Function to stop listening.\n */\n listen(): RemoveEventListenerFn {\n return on('theme_changed', (event) => {\n this.set(parseThemeParams(event.theme_params));\n });\n }\n\n /**\n * @since v6.10\n */\n get subtitleTextColor(): RGB | undefined {\n return this.get('subtitleTextColor');\n }\n\n get textColor(): RGB | undefined {\n return this.get('textColor');\n }\n}\n","import { ThemeParams } from '@/components/ThemeParams/ThemeParams.js';\nimport { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\n/**\n * @returns A new initialized instance of the `ThemeParams` class.\n * @see ThemeParams\n */\nexport const initThemeParams = createComponentInitFn(\n 'themeParams',\n ({ themeParams, state = themeParams, addCleanup }) => {\n const tp = new ThemeParams(state);\n addCleanup(tp.listen());\n return tp;\n },\n);\n","import { request } from '@/bridge/utils/request.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nimport { parseThemeParams } from './parsing/parseThemeParams.js';\nimport type { ThemeParamsParsed } from './types.js';\n\n/**\n * Requests current theme parameters from the Telegram application.\n * @param options - request options.\n */\nexport function requestThemeParams(options: ExecuteWithOptions = {}): Promise<ThemeParamsParsed> {\n return request({\n ...options,\n method: 'web_app_request_theme',\n event: 'theme_changed',\n }).then(parseThemeParams);\n}\n","import { captureSameReq } from '@/bridge/utils/captureSameReq.js';\nimport { request } from '@/bridge/utils/request.js';\nimport { WithSupports } from '@/classes/WithSupports.js';\nimport { createSupportsParamFn } from '@/supports/createSupportsParamFn.js';\nimport { supports } from '@/supports/supports.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { CreateRequestIdFn } from '@/request-id/types.js';\nimport type { SupportsFn } from '@/supports/types.js';\nimport type { Version } from '@/version/types.js';\n\n/**\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/utils\n */\nexport class Utils extends WithSupports<'readTextFromClipboard'> {\n constructor(\n private readonly version: Version,\n private readonly createRequestId: CreateRequestIdFn,\n private readonly postEvent: PostEvent,\n ) {\n super(version, { readTextFromClipboard: 'web_app_read_text_from_clipboard' });\n\n this.supportsParam = createSupportsParamFn(version, {\n 'openLink.tryInstantView': ['web_app_open_link', 'try_instant_view'],\n });\n }\n\n /**\n * Opens a link in an external browser. The Mini App will not be closed.\n *\n * Note that this method can be called only in response to the user\n * interaction with the Mini App interface (e.g. click inside the Mini App\n * or on the main button).\n * @param url - URL to be opened.\n * @param tryInstantView\n */\n openLink(url: string, tryInstantView?: boolean): void {\n const formattedUrl = new URL(url, window.location.href).toString();\n\n // If method is not supported, we are doing it in legacy way.\n if (!supports('web_app_open_link', this.version)) {\n window.open(formattedUrl, '_blank');\n return;\n }\n\n // Otherwise, do it normally.\n this.postEvent('web_app_open_link', {\n url: formattedUrl,\n ...(typeof tryInstantView === 'boolean' ? { try_instant_view: tryInstantView } : {}),\n });\n }\n\n /**\n * Opens a Telegram link inside Telegram app. The Mini App will be closed. It expects passing\n * link in full format, with hostname \"t.me\".\n * @param url - URL to be opened.\n * @throws {Error} URL has not allowed hostname.\n */\n openTelegramLink(url: string): void {\n const { hostname, pathname, search } = new URL(url, window.location.href);\n if (hostname !== 't.me') {\n throw new Error(`URL has not allowed hostname: ${hostname}. Only \"t.me\" is allowed`);\n }\n\n if (!supports('web_app_open_tg_link', this.version)) {\n window.location.href = url;\n return;\n }\n\n this.postEvent('web_app_open_tg_link', { path_full: pathname + search });\n }\n\n /**\n * Reads text from clipboard and returns string or null. null is returned\n * in cases:\n * - Value in clipboard is not text\n * - Access to clipboard is not allowed\n */\n async readTextFromClipboard(): Promise<string | null> {\n const reqId = this.createRequestId();\n const {\n data = null,\n } = await request({\n method: 'web_app_read_text_from_clipboard',\n event: 'clipboard_text_received',\n postEvent: this.postEvent,\n params: { req_id: reqId },\n capture: captureSameReq(reqId),\n });\n\n return data;\n }\n\n /**\n * Checks if specified method parameter is supported by current component.\n */\n supportsParam: SupportsFn<'openLink.tryInstantView'>;\n}\n","import { Utils } from '@/components/Utils/Utils.js';\nimport { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\n/**\n * @returns A new initialized instance of the `Utils` class.\n * @see Utils\n */\nexport const initUtils = createComponentInitFn(\n ({ version, postEvent, createRequestId }) => {\n return new Utils(version, createRequestId, postEvent);\n },\n);\n","import { request } from '@/bridge/utils/request.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nexport interface RequestViewportResult {\n height: number;\n isStateStable: boolean;\n isExpanded: boolean;\n width: number;\n}\n\n/**\n * Requests viewport actual information from the Telegram application.\n * @param options - request options.\n */\nexport async function requestViewport(\n options: ExecuteWithOptions = {},\n): Promise<RequestViewportResult> {\n const {\n is_expanded: isExpanded,\n is_state_stable: isStateStable,\n ...rest\n } = await request({\n ...options,\n method: 'web_app_request_viewport',\n event: 'viewport_changed',\n });\n\n return { ...rest, isExpanded, isStateStable };\n}\n","import { on } from '@/bridge/events/listening/on.js';\nimport { WithTrackableState } from '@/classes/WithTrackableState.js';\nimport type { PostEvent } from '@/bridge/methods/postEvent.js';\nimport type { RemoveEventListenerFn } from '@/events/types.js';\nimport type { ExecuteWithOptions } from '@/types/index.js';\n\nimport { requestViewport } from './requestViewport.js';\nimport type { ViewportProps, ViewportState } from './types.js';\n\n/**\n * Formats value to make it stay in bounds [0, +Inf).\n * @param value - value to format.\n */\nfunction truncate(value: number): number {\n return value < 0 ? 0 : value;\n}\n\n/**\n * @see Usage: https://docs.telegram-mini-apps.com/platform/viewport\n * @see API: https://docs.telegram-mini-apps.com/packages/tma-js-sdk/components/viewport\n */\nexport class Viewport extends WithTrackableState<ViewportState> {\n private readonly postEvent: PostEvent;\n\n constructor({ postEvent, stableHeight, height, width, isExpanded }: ViewportProps) {\n super({\n height: truncate(height),\n isExpanded,\n stableHeight: truncate(stableHeight),\n width: truncate(width),\n });\n this.postEvent = postEvent;\n }\n\n /**\n * Requests viewport information from the Telegram application and updates current Viewport\n * instance.\n * @param options - options to request fresh data.\n */\n async sync(options?: ExecuteWithOptions): Promise<void> {\n const { isStateStable, ...rest } = await requestViewport(options);\n this.set({\n ...rest,\n stableHeight: isStateStable ? rest.height : this.get('stableHeight'),\n });\n }\n\n /**\n * The current height of the **visible area** of the Mini App.\n *\n * The application can display just the top part of the Mini App, with its lower part remaining\n * outside the screen area. From this position, the user can \"pull\" the Mini App to its\n * maximum height, while the bot can do the same by calling `expand` method. As the position of\n * the Mini App changes, the current height value of the visible area will be updated in real\n * time.\n *\n * Please note that the refresh rate of this value is not sufficient to smoothly follow the\n * lower border of the window. It should not be used to pin interface elements to the bottom\n * of the visible area. It's more appropriate to use the value of the `stableHeight`\n * field for this purpose.\n *\n * @see stableHeight\n */\n get height(): number {\n return this.get('height');\n }\n\n /**\n * The height of the visible area of the Mini App in its last stable state.\n *\n * The application can display just the top part of the Mini App, with its lower part remaining\n * outside the screen area. From this position, the user can \"pull\" the Mini App to its\n * maximum height, while the application can do the same by calling `expand` method.\n *\n * Unlike the value of `height`, the value of `stableHeight` does not change as the position\n * of the Mini App changes with user gestures or during animations. The value of `stableHeight`\n * will be updated after all gestures and animations are completed and\n * the Mini App reaches its final size.\n *\n * @see height\n */\n get stableHeight(): number {\n return this.get('stableHeight');\n }\n\n /**\n * Starts listening to viewport changes and applies them.\n * @returns Function to stop listening.\n */\n listen(): RemoveEventListenerFn {\n return on('viewport_changed', (event) => {\n const {\n height,\n width,\n is_expanded: isExpanded,\n is_state_stable: isStateStable,\n } = event;\n const truncatedHeight = truncate(height);\n\n this.set({\n height: truncatedHeight,\n isExpanded,\n width: truncate(width),\n ...(isStateStable ? { stableHeight: truncatedHeight } : {}),\n });\n });\n }\n\n /**\n * True if the Mini App is expanded to the maximum available height. Otherwise, if\n * the Mini App occupies part of the screen and can be expanded to the full height using\n * `expand` method.\n * @see expand\n */\n get isExpanded(): boolean {\n return this.get('isExpanded');\n }\n\n /**\n * Current visible area width.\n */\n get width(): number {\n return this.get('width');\n }\n\n /**\n * A method that expands the Mini App to the maximum available height. To find out if the Mini\n * App is expanded to the maximum height, refer to the value of the `isExpanded`.\n * @see isExpanded\n */\n expand(): void {\n this.postEvent('web_app_expand');\n this.set('isExpanded', true);\n }\n\n /**\n * True if the current viewport height is stable and is not going to change in the next moment.\n */\n get isStable(): boolean {\n return this.stableHeight === this.height;\n }\n}\n","import { createComponentInitFn } from '@/misc/createComponentInitFn/createComponentInitFn.js';\n\nimport { Viewport } from './Viewport.js';\nimport { requestViewport } from '@/components/Viewport/requestViewport.js';\n\n/**\n * @returns A promise with a new initialized instance of the `Viewport` class.\n * @see Viewport\n */\nexport const initViewport = createComponentInitFn(\n 'viewport',\n async ({ state, platform, postEvent, addCleanup }) => {\n let isExpanded = false;\n let height = 0;\n let width = 0;\n let stableHeight = 0;\n\n // State was saved previously, we restore the Viewport from this state.\n if (state) {\n isExpanded = state.isExpanded;\n height = state.height;\n width = state.width;\n stableHeight = state.stableHeight;\n } else if (['macos', 'tdesktop', 'unigram', 'webk', 'weba', 'web'].includes(platform)) {\n // If platform has a stable viewport, it means we could instantiate Viewport using\n // the window global object properties.\n isExpanded = true;\n height = window.innerHeight;\n width = window.innerWidth;\n stableHeight = window.innerHeight;\n } else {\n // We were unable to retrieve data locally. In this case we are sending a request returning\n // a viewport information.\n const response = await requestViewport({ timeout: 1000, postEvent });\n isExpanded = response.isExpanded;\n height = response.height;\n width = response.width;\n stableHeight = response.isStateStable ? height : 0;\n }\n\n // Otherwise, Viewport instance will be created using zero values.\n const viewport = new Viewport({\n postEvent,\n height,\n width,\n stableHeight,\n isExpanded,\n });\n\n // Listen to the viewport external changes and actualize local instance.\n addCleanup(viewport.listen());\n\n return viewport;\n },\n);\n","/**\n * Sets CSS variable globally.\n * @param name - variable name.\n * @param value - variable value.\n */\nexport function setCSSVar(name: string, value: string): void {\n document.documentElement.style.setProperty(name, value);\n}\n","import { isRGB } from '@/colors/isRGB.js';\nimport { setCSSVar } from '@/css-vars/setCSSVar.js';\nimport type { ThemeParams } from '@/components/ThemeParams/ThemeParams.js';\nimport type { MiniApp } from '@/components/MiniApp/MiniApp.js';\nimport type { CleanupFn } from '@/types/index.js';\n\nexport interface GetMiniAppCSSVarNameFn {\n /**\n * @param property - MiniApp property.\n * @returns Computed complete CSS variable name.\n */\n (property: 'bg' | 'header'): string;\n}\n\n/**\n * Creates CSS variables connected with the MiniApps class instance background and header colors\n * based on the passed MiniApp and ThemeParams instances.\n *\n * Created variables by default:\n * - `--tg-bg-color`\n * - `--tg-header-color`\n *\n * Variables are being automatically updated in case, corresponding MiniApp and ThemeParams\n * properties were updated.\n *\n * @param miniApp - MiniApp instance.\n * @param themeParams - ThemeParams instance.\n * @param getVarName - function, returning complete CSS variable name for the specified\n * MiniApp property.\n * @returns Function to stop updating variables.\n */\nexport function bindMiniAppCSSVars(\n miniApp: MiniApp,\n themeParams: ThemeParams,\n getVarName?: GetMiniAppCSSVarNameFn,\n): CleanupFn {\n getVarName ||= (property) => `--tg-${property}-color`;\n\n const headerVar = getVarName('header');\n const bgVar = getVarName('bg');\n\n const actualize = () => {\n const { headerColor } = miniApp;\n\n if (isRGB(headerColor)) {\n setCSSVar(headerVar, headerColor);\n } else {\n const { bgColor, secondaryBgColor } = themeParams;\n\n if (headerColor === 'bg_color' && bgColor) {\n setCSSVar(headerVar, bgColor);\n } else if (headerColor === 'secondary_bg_color' && secondaryBgColor) {\n setCSSVar(headerVar, secondaryBgColor);\n }\n }\n\n setCSSVar(bgVar, miniApp.bgColor)\n };\n\n const listeners = [\n themeParams.on('change', actualize),\n miniApp.on('change', actualize),\n ];\n\n actualize();\n\n return () => listeners.forEach(off => off());\n}\n","import { setCSSVar } from '@/css-vars/setCSSVar.js';\nimport type { ThemeParams } from '@/components/ThemeParams/ThemeParams.js';\nimport type { CleanupFn } from '@/types/index.js';\n\nexport interface GetThemeParamsCSSVarNameFn {\n /**\n * @param property - ThemeParams property.\n * @returns Computed complete CSS variable name.\n */\n (property: string): string;\n}\n\n/**\n * Creates CSS variables connected with the passed instance of the ThemeParams class.\n *\n * By default, created CSS variables names are following the pattern \"--tg-theme-{name}\", where\n * {name} is a theme parameters key name converted from camel case to kebab case.\n *\n * Example:\n * --tg-theme-bg-color\n * --tg-theme-secondary-text-color\n *\n * Variables are being automatically updated in case, corresponding properties updated in\n * the passed ThemeParams instance.\n *\n * @param themeParams - ThemeParams instance.\n * @param getCSSVarName - function, returning complete CSS variable name for the specified\n * ThemeParams property.\n * @returns Function to stop updating variables.\n */\nexport function bindThemeParamsCSSVars(\n themeParams: ThemeParams,\n getCSSVarName?: GetThemeParamsCSSVarNameFn,\n): CleanupFn {\n getCSSVarName ||= (property) => {\n return `--tg-theme-${property.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)}`;\n };\n\n const actualize = () => {\n Object.entries(themeParams.getState()).forEach(([k, v]) => {\n if (v) {\n setCSSVar(getCSSVarName(k), v);\n }\n });\n };\n\n actualize();\n\n return themeParams.on('change', actualize);\n}\n","import { setCSSVar } from '@/css-vars/setCSSVar.js';\nimport type { Viewport } from '@/components/Viewport/Viewport.js';\nimport type { CleanupFn } from '@/types/index.js';\n\nexport interface GetViewportCSSVarNameFn {\n /**\n * @param property - Viewport property.\n * @returns Computed complete CSS variable name.\n */\n (property: 'width' | 'height' | 'stable-height'): string;\n}\n\n/**\n * Accepts Viewport instance and sets CSS variables connected with viewport\n * sizes.\n *\n * Be careful using this function as long as it can impact application\n * performance. Viewport size is changing rather often, this makes CSS\n * variables update, which leads to possible layout redraw.\n *\n * Variables:\n * - `--tg-viewport-height`\n * - `--tg-viewport-width`\n * - `--tg-viewport-stable-height`\n *\n * Variables are being automatically updated in case, corresponding properties\n * updated in passed Viewport instance.\n *\n * @param viewport - Viewport instance.\n * @param getCSSVarName - function, returning complete CSS variable name for the specified\n * Viewport property.\n * @returns Function to stop updating variables.\n */\nexport function bindViewportCSSVars(\n viewport: Viewport,\n getCSSVarName?: GetViewportCSSVarNameFn,\n): CleanupFn {\n getCSSVarName ||= (property) => `--tg-viewport-${property}`;\n const [\n heightVar,\n widthVar,\n stableHeightVar,\n ] = (['height', 'width', 'stable-height'] as const).map((prop) => getCSSVarName(prop));\n const setHeight = () => setCSSVar(heightVar, `${viewport.height}px`);\n const setWidth = () => setCSSVar(widthVar, `${viewport.width}px`);\n const setStableHeight = () => setCSSVar(stableHeightVar, `${viewport.stableHeight}px`);\n\n // TODO: Should probably add debounce or throttle.\n const listeners = [\n viewport.on('change:height', setHeight),\n viewport.on('change:width', setWidth),\n viewport.on('change:stableHeight', setStableHeight),\n ];\n\n setHeight();\n setWidth();\n setStableHeight();\n\n return () => listeners.forEach(off => off());\n}\n","import { on } from '@/bridge/events/listening/on.js';\nimport { postEvent } from '@/bridge/methods/postEvent.js';\n\ninterface CleanupFn {\n (): void;\n}\n\n/**\n * Performs initialization process in the web version of Telegram.\n * @returns Function, which performs cleanup removing all created elements and listeners.\n * @param acceptCustomStyles - true if SDK should accept styles sent from the Telegram web\n * application. This option is only used in web versions of Telegram. Default: false.\n */\nexport function initWeb(acceptCustomStyles = true): CleanupFn {\n const listeners: CleanupFn[] = [\n on('reload_iframe', () => {\n postEvent('iframe_will_reload');\n window.location.reload();\n }),\n ];\n const cleanup: CleanupFn = () => listeners.forEach((l) => l());\n\n if (acceptCustomStyles) {\n const style = document.createElement('style');\n style.id = 'telegram-custom-styles';\n document.head.appendChild(style);\n\n listeners.push(\n on('set_custom_style', (html) => {\n // It is safe to use innerHTML here as long as style tag has a special behavior related\n // to the specified content. In case, any script will be passed here, it will not be\n // executed.\n style.innerHTML = html;\n }),\n () => document.head.removeChild(style),\n );\n }\n\n // Notify Telegram, iframe is ready. This will result in sending style tag html from native\n // application which is used in catchCustomStyles function. We should call this method also\n // to start receiving \"reload_iframe\" events from the Telegram application.\n postEvent('iframe_ready', { reload_supported: true });\n\n return cleanup;\n}\n","/**\n * @returns True, if current environment is server.\n */\nexport function isSSR(): boolean {\n return typeof window === 'undefined';\n}\n","import { request } from '@/bridge/utils/request.js';\nimport { hasWebviewProxy } from '@/env/hasWebviewProxy.js';\n\n/**\n * Returns true in case, current environment is Telegram Mini Apps.\n */\nexport async function isTMA(): Promise<boolean> {\n if (hasWebviewProxy(window)) {\n return true;\n }\n try {\n await request({ method: 'web_app_request_theme', event: 'theme_changed', timeout: 100 });\n return true;\n } catch (e) {\n return false;\n }\n}\n","import { saveToStorage } from '@/launch-params/saveToStorage.js';\nimport { parseMessage } from '@/bridge/parseMessage.js';\nimport { isIframe } from '@/env/isIframe.js';\nimport { hasExternalNotify } from '@/env/hasExternalNotify.js';\nimport { emitMiniAppsEvent } from '@/bridge/events/event-handlers/emitMiniAppsEvent.js';\nimport { serializeThemeParams } from '@/components/ThemeParams/parsing/serializeThemeParams.js';\nimport { parseLaunchParams } from '@/launch-params/parseLaunchParams.js';\nimport type { LaunchParams } from '@/launch-params/types.js';\nimport type { MiniAppsEventPayload } from '@/bridge/events/types.js';\n\n/**\n * Mocks a Telegram application environment.\n * @param launchParamsRaw - launch parameters presented as a string or query parameters.\n */\nexport function mockTelegramEnv(launchParamsRaw: LaunchParams | string): void {\n const lp = typeof launchParamsRaw === 'string'\n ? parseLaunchParams(launchParamsRaw)\n : launchParamsRaw;\n\n // Save launch params in the storage, so retrieveLaunchParams will return them.\n saveToStorage(lp);\n\n function wiredPostMessage(data: unknown): void {\n if (typeof data !== 'string') {\n return;\n }\n try {\n const { eventType } = parseMessage(data);\n\n if (eventType === 'web_app_request_theme') {\n emitMiniAppsEvent('theme_changed', {\n theme_params: JSON.parse(serializeThemeParams(lp.themeParams)),\n } satisfies MiniAppsEventPayload<'theme_changed'>);\n }\n\n if (eventType === 'web_app_request_viewport') {\n emitMiniAppsEvent('viewport_changed', {\n width: window.innerWidth,\n height: window.innerHeight,\n is_state_stable: true,\n is_expanded: true,\n } satisfies MiniAppsEventPayload<'viewport_changed'>);\n }\n } catch {\n }\n }\n\n // Override all possible ways of calling a Mini Apps method.\n if (isIframe()) {\n const postMessage = window.parent.postMessage.bind(window.parent);\n window.parent.postMessage = data => {\n void wiredPostMessage(data);\n postMessage(data);\n };\n return;\n }\n\n if (hasExternalNotify(window)) {\n const notify = window.external.notify.bind(window.external);\n window.external.notify = data => {\n void wiredPostMessage(data);\n notify(data);\n };\n return;\n }\n\n const proxy = (window as any).TelegramWebviewProxy;\n (window as any).TelegramWebviewProxy = {\n ...(proxy || {}),\n postEvent(...args: any) {\n void wiredPostMessage(JSON.stringify({ eventType: args[0], eventData: args[1] }));\n proxy && proxy.postEvent(...args);\n },\n };\n}\n","import { SDKError } from './SDKError.js';\n\n/**\n * @returns True, if passed value is an instance of SDKError.\n * @param value - value to check.\n */\nexport function isSDKError(value: unknown): value is SDKError {\n return value instanceof SDKError;\n}\n","import { isSDKError } from './isSDKError.js';\nimport type { ErrorType } from './errors.js';\n\n/**\n * Returns true if passed value is an SDK error of specified type.\n * @param value - value to check.\n * @param type - error type.\n */\nexport function isSDKErrorOfType(value: unknown, type: ErrorType): boolean {\n return isSDKError(value) && value.type === type;\n}\n","import type {\n BasicNavigatorAnyHistoryItem,\n BasicNavigatorHistoryItem,\n} from '@/navigation/BasicNavigator/types.js';\n\n/**\n * Converts any known history item type to the local one.\n * @param item - history item presented as a string or an object.\n * @param relativePathname - relative pathname.\n */\nexport function prepareItem<Params>(\n item: BasicNavigatorAnyHistoryItem<Params>,\n relativePathname: string,\n): Readonly<BasicNavigatorHistoryItem<Params>> {\n let pathname: string;\n let params: Params | undefined;\n let id: string | undefined;\n\n if (typeof item === 'string') {\n pathname = item;\n } else {\n pathname = item.pathname === undefined\n ? relativePathname\n : item.pathname;\n params = item.params;\n id = item.id;\n }\n\n return Object.freeze({\n id: id || ((Math.random() * 2 ** 14) | 0).toString(16),\n pathname,\n params,\n });\n}\n","import { off } from '@/bridge/events/listening/off.js';\nimport { on } from '@/bridge/events/listening/on.js';\nimport { type PostEvent, postEvent as defaultPostEvent } from '@/bridge/methods/postEvent.js';\nimport { createError } from '@/errors/createError.js';\nimport {\n ERR_NAVIGATION_HISTORY_EMPTY,\n ERR_NAVIGATION_INDEX_INVALID,\n} from '@/errors/errors.js';\nimport { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport { prepareItem } from '@/navigation/BasicNavigator/prepareItem.js';\nimport type {\n BasicNavigatorAnyHistoryItem,\n BasicNavigatorEvents,\n BasicNavigatorHistoryItem,\n} from '@/navigation/BasicNavigator/types.js';\n\ntype Emitter<Params> = EventEmitter<BasicNavigatorEvents<Params>>;\n\nexport class BasicNavigator<Params = {}> {\n /**\n * Navigation history.\n */\n readonly history: Readonly<BasicNavigatorHistoryItem<Params>>[];\n\n private readonly ee: Emitter<Params> = new EventEmitter();\n\n constructor(\n /**\n * Navigation history.\n */\n history: readonly BasicNavigatorAnyHistoryItem<Params>[],\n /**\n * Currently active history item.\n */\n private _index: number,\n /**\n * Function to call Mini Apps methods.\n * @default Global `postEvent` function.\n */\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n if (history.length === 0) {\n throw createError(ERR_NAVIGATION_HISTORY_EMPTY, 'History should not be empty.');\n }\n\n if (_index < 0 || _index >= history.length) {\n throw createError(\n ERR_NAVIGATION_INDEX_INVALID,\n 'Index should not be zero and higher or equal than history size.',\n );\n }\n this.history = history.map((item) => prepareItem(item, ''));\n }\n\n /**\n * True, if current navigator is currently attached.\n */\n private attached = false;\n\n /**\n * Allows this navigator to control the `BackButton` visibility state. It also tracks the\n * `BackButton` clicks and calls the `back` method.\n */\n attach(): void {\n if (!this.attached) {\n this.attached = true;\n this.sync();\n on('back_button_pressed', this.back);\n }\n }\n\n /**\n * Goes to the previous history item.\n */\n back = (): void => this.go(-1);\n\n /**\n * Currently active history item.\n */\n get current(): Readonly<BasicNavigatorHistoryItem<Params>> {\n return this.history[this.index];\n }\n\n /**\n * Prevents current navigator from controlling the BackButton visibility state.\n */\n detach(): void {\n this.attached = false;\n off('back_button_pressed', this.back);\n }\n\n /**\n * Goes to the next history item.\n */\n forward(): void {\n this.go(1);\n }\n\n /**\n * Changes currently active history item index by the specified delta. This method doesn't\n * change index in case, the updated index points to the non-existing history item. This behavior\n * is preserved until the `fit` argument is specified.\n * @param delta - index delta.\n * @param fit - cuts the delta argument to fit the bounds `[0, history.length - 1]`.\n */\n go(delta: number, fit?: boolean): void {\n // Compute the next index.\n const index = this.index + delta;\n\n // Cut the index to be in bounds [0, history.length - 1].\n const fitIndex = Math.min(\n Math.max(0, index),\n this.history.length - 1,\n );\n\n // We perform \"go\" only in case, computed and cut indexes are equal or \"fit\" option was\n // specified.\n if (index === fitIndex || fit) {\n // We are just calling setter to update the index and emit all related events.\n this.replaceAndMove(fitIndex, this.history[fitIndex]);\n }\n }\n\n /**\n * Goes to the specified index. Method does nothing in case, passed index is out of bounds.\n *\n * If \"fit\" option was specified and index is out of bounds, it will be cut to the nearest\n * bound.\n * @param index - target index.\n * @param fit - cuts the index argument to fit the bounds `[0, history.length - 1]`.\n */\n goTo(index: number, fit?: boolean): void {\n this.go(index - this.index, fit);\n }\n\n /**\n * True if navigator has items before the current item.\n */\n get hasPrev(): boolean {\n return this.index > 0;\n }\n\n /**\n * True if navigator has items after the current item.\n */\n get hasNext(): boolean {\n return this.index !== this.history.length - 1;\n }\n\n /**\n * Currently active history item index.\n */\n get index(): number {\n return this._index;\n }\n\n /**\n * Adds new event listener.\n */\n on: Emitter<Params>['on'] = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off: Emitter<Params>['off'] = this.ee.off.bind(this.ee);\n\n /**\n * Adds a new history item removing all after the current one.\n * @param item - item to add.\n */\n push(item: BasicNavigatorAnyHistoryItem<Params>): void {\n if (this.hasNext) {\n this.history.splice(this.index + 1);\n }\n this.replaceAndMove(this.index + 1, prepareItem(item, this.current.pathname));\n }\n\n /**\n * Replaces the current history item.\n * @param item - item to replace the current item with.\n */\n replace(item: BasicNavigatorAnyHistoryItem<Params>): void {\n this.replaceAndMove(this.index, prepareItem(item, this.current.pathname));\n }\n\n /**\n * Sets history item by the specified index.\n * @param index - history item index to replace.\n * @param historyItem - history item to set.\n */\n private replaceAndMove(index: number, historyItem: BasicNavigatorHistoryItem<Params>): void {\n const delta = index - this.index;\n if (!delta && this.current === historyItem) {\n // Nothing changed.\n return;\n }\n\n const from = this.current;\n\n if (this.index !== index) {\n const prevIndex = this._index;\n this._index = index;\n\n // If navigator is attached and back button local visibility state changed, we should\n // notify Telegram app about it.\n if (this.attached && prevIndex > 0 !== index > 0) {\n this.sync();\n }\n }\n\n this.history[index] = historyItem;\n this.ee.emit('change', {\n navigator: this,\n from,\n to: this.current,\n delta,\n });\n }\n\n /**\n * Actualizes the `BackButton` visibility state.\n */\n private sync(): void {\n this.postEvent('web_app_setup_back_button', { is_visible: !!this.index });\n }\n}\n","import type { BasicNavigatorHistoryItem } from '@/navigation/BasicNavigator/types.js';\nimport type {\n BrowserNavigatorHistoryItem,\n BrowserNavigatorHistoryItemParams,\n} from '@/navigation/BrowserNavigator/types.js';\n\n/**\n * Converts basic navigator entry to browser navigator entry.\n */\nexport function basicItemToBrowser<State>(\n {\n params,\n ...rest\n }: BasicNavigatorHistoryItem<BrowserNavigatorHistoryItemParams<State>>,\n): BrowserNavigatorHistoryItem<State> {\n return { ...(params || { hash: '', search: '' }), ...rest };\n}\n","/**\n * Ensures, that specified value starts with the specified prefix. If it doesn't, function appends\n * prefix.\n * @param value - value to check.\n * @param prefix - prefix to add.\n */\nexport function ensurePrefix(value: string, prefix: string): string {\n return value.startsWith(prefix) ? value : `${prefix}${value}`;\n}\n","import { ensurePrefix } from '@/navigation/ensurePrefix.js';\nimport type { URLLike } from '@/navigation/BrowserNavigator/types.js';\n\n/**\n * Safely creates new instance of URL with some predefined protocol and hostname.\n * @param urlOrPath - URL instance or path.\n */\nexport function createSafeURL(urlOrPath: string | Partial<URLLike>): URL {\n return new URL(\n typeof urlOrPath === 'string'\n ? urlOrPath\n : `${urlOrPath.pathname || ''}${ensurePrefix(urlOrPath.search || '', '?')}${ensurePrefix(urlOrPath.hash || '', '#')}`,\n 'http://a',\n );\n}\n","import { createSafeURL } from '@/navigation/createSafeURL.js';\nimport type { URLLike } from '@/navigation/BrowserNavigator/types.js';\n\n/**\n * Extracts path part from a URL.\n * @param urlOrPath - URL instance or path.\n */\nexport function urlToPath(urlOrPath: string | Partial<URLLike>): string {\n const isAbsolute = typeof urlOrPath === 'string'\n ? urlOrPath.startsWith('/')\n : !!(urlOrPath.pathname && urlOrPath.pathname.startsWith('/'));\n const url = createSafeURL(urlOrPath);\n\n return `${isAbsolute ? url.pathname : url.pathname.slice(1)}${url.search}${url.hash}`;\n}\n","import { ensurePrefix } from '@/navigation/ensurePrefix.js';\nimport { urlToPath } from '@/navigation/urlToPath.js';\nimport type { BrowserNavigatorAnyHistoryItem } from '@/navigation/BrowserNavigator/types.js';\n\ninterface PrepareItemResult<State> {\n id?: string;\n pathname: string;\n params: {\n hash: string;\n search: string;\n state?: State;\n };\n}\n\n/**\n * Converts a path, presented as a string to a basic navigator appropriate form.\n * @param path - full path.\n * @param relativePath - relative path.\n * @param state - history item state.\n */\nexport function prepareItem<State>(\n path: string,\n relativePath: string,\n state?: State,\n): PrepareItemResult<State>;\n\n/**\n * Converts a path, presented as an object to a basic navigator appropriate form.\n * @param item - history item data.\n * @param relativePath - relative path.\n */\nexport function prepareItem<State>(\n item: BrowserNavigatorAnyHistoryItem<State>,\n relativePath: string,\n): PrepareItemResult<State>;\n\nexport function prepareItem<State>(\n itemOrPath: string | BrowserNavigatorAnyHistoryItem<State>,\n relativePath: string,\n state?: State,\n): PrepareItemResult<State> {\n let path: string;\n let id: string | undefined;\n\n if (typeof itemOrPath === 'string') {\n path = itemOrPath;\n } else {\n path = urlToPath(itemOrPath);\n state = itemOrPath.state;\n id = itemOrPath.id;\n }\n\n const { pathname, search, hash } = new URL(path, `http://a${ensurePrefix(relativePath, '/')}`);\n return { id, pathname, params: { hash, search, state } };\n}\n","import { onWindow } from '@/events/onWindow.js';\n\n/**\n * Performs window.history.go operation waiting for it to be completed.\n * @param delta - history change delta.\n */\nexport async function go(delta: number): Promise<boolean> {\n if (delta === 0) {\n return true;\n }\n\n // We expect popstate event to occur during some time. Yeah, this seems tricky and not stable,\n // but it seems like we have no other way out. Waiting for Navigation API to be implemented in\n // browsers.\n return Promise.race<boolean>([\n new Promise((res) => {\n const remove = onWindow('popstate', () => {\n remove();\n res(true);\n });\n\n window.history.go(delta);\n }),\n\n // Usually, it takes about 1ms to emit this event, but we use some buffer.\n new Promise((res) => {\n setTimeout(res, 50, false);\n }),\n ]);\n}\n","import { go } from '@/navigation/go.js';\n\n/**\n * Drops current browser history switching browser history cursor to the first one entry.\n */\nexport async function drop(): Promise<void> {\n if (window.history.length <= 1) {\n return;\n }\n\n // Push empty state to cut states we have no access to, placed after the current one.\n window.history.pushState(null, '');\n\n // By this line of code we cover the most recent case, when application is opened in WebView,\n // but not in iframe. Applications opened in WebView have simple browser history containing\n // only entries belonging to the current web application.\n const goPerformed = await go(1 - window.history.length);\n if (goPerformed) {\n return;\n }\n\n // Nevertheless, iframe works a bit different in context of browser history. Calling\n // window.history.length in iframe will return browser history information related to the\n // external web environment too (e.g. browser tab). So, iframe shares the browser history with\n // the external application, but has no access to its history entries. Calling window.history.go\n // pointing out to the entry belonging to the external application will have no impact, so the\n // previous idea with go(1 - ...) will not work.\n //\n // This is the reason why we iteratively call go(-1) to meet the entry which is recognized as\n // the initial one for the current iframe.\n let shouldGoBack = await go(-1);\n while (shouldGoBack) {\n // eslint-disable-next-line no-await-in-loop\n shouldGoBack = await go(-1);\n }\n}\n","import { createSafeURL } from '@/navigation/createSafeURL.js';\nimport type { URLLike } from '@/navigation/BrowserNavigator/types.js';\n\n/**\n * Extracts pathname from the value.\n * @param value - source value.\n */\nexport function getPathname(value: string | Partial<URLLike>): string {\n return createSafeURL(value).pathname;\n}\n","import { EventEmitter } from '@/events/event-emitter/EventEmitter.js';\nimport { BasicNavigator } from '@/navigation/BasicNavigator/BasicNavigator.js';\nimport { basicItemToBrowser } from '@/navigation/BrowserNavigator/basicItemToBrowser.js';\nimport { prepareItem } from '@/navigation/BrowserNavigator/prepareItem.js';\nimport { createSafeURL } from '@/navigation/createSafeURL.js';\nimport { drop } from '@/navigation/drop.js';\nimport { ensurePrefix } from '@/navigation/ensurePrefix.js';\nimport { getPathname } from '@/navigation/getPathname.js';\nimport { go } from '@/navigation/go.js';\nimport { urlToPath } from '@/navigation/urlToPath.js';\nimport type { BasicNavigatorEvents } from '@/navigation/BasicNavigator/types.js';\nimport type {\n BrowserNavigatorAnyHistoryItem,\n BrowserNavigatorConOptions,\n BrowserNavigatorEvents,\n BrowserNavigatorHashMode,\n BrowserNavigatorHistoryItem,\n BrowserNavigatorHistoryItemParams,\n URLLike,\n} from '@/navigation/BrowserNavigator/types.js';\n\nconst CURSOR_VOID = 0;\nconst CURSOR_BACK = 1;\nconst CURSOR_FORWARD = 2;\n\ntype Navigator<State> = BasicNavigator<BrowserNavigatorHistoryItemParams<State>>;\ntype Emitter<State> = EventEmitter<BrowserNavigatorEvents<State>>;\n\nexport class BrowserNavigator<State = {}> {\n private readonly navigator: Navigator<State>;\n\n private readonly ee: Emitter<State> = new EventEmitter();\n\n readonly hashMode: BrowserNavigatorHashMode | null;\n\n readonly base: string;\n\n constructor(\n /**\n * Navigation history.\n */\n history: readonly BrowserNavigatorAnyHistoryItem<State>[],\n /**\n * Currently active history item index.\n */\n index: number,\n { postEvent, hashMode = 'classic', base }: BrowserNavigatorConOptions = {},\n ) {\n this.navigator = new BasicNavigator(\n history.map((item) => prepareItem(item, '/')),\n index,\n postEvent,\n );\n this.navigator.on('change', this.onNavigatorChange);\n this.hashMode = hashMode;\n this.base = getPathname(base || '');\n }\n\n /**\n * Shows whether the navigator is currently attached to the browser history.\n */\n private attached = false;\n\n /**\n * Attaches current navigator to the browser history allowing navigator to manipulate it.\n */\n async attach(): Promise<void> {\n if (!this.attached) {\n this.attached = true;\n this.navigator.attach();\n window.addEventListener('popstate', this.onPopState);\n await this.syncHistory();\n }\n }\n\n /**\n * Goes back in history by 1.\n */\n back(): void {\n this.navigator.back();\n }\n\n /**\n * Detaches current navigator from the browser history.\n */\n detach() {\n this.attached = false;\n this.navigator.detach();\n window.removeEventListener('popstate', this.onPopState);\n }\n\n /**\n * Goes forward in history.\n */\n forward(): void {\n return this.navigator.forward();\n }\n\n /**\n * Current history cursor.\n */\n get index(): number {\n return this.navigator.index;\n }\n\n /**\n * Current history item identifier.\n */\n get id(): string {\n return this.navigator.current.id;\n }\n\n /**\n * Changes currently active history item index by the specified delta. This method doesn't\n * change index in case, the updated index points to the non-existing history item. This behavior\n * is preserved until the `fit` argument is specified.\n * @param delta - index delta.\n * @param fit - cuts the delta argument to fit the bounds `[0, history.length - 1]`.\n */\n go(delta: number, fit?: boolean): void {\n return this.navigator.go(delta, fit);\n }\n\n /**\n * Goes to the specified index. Method does nothing in case, passed index is out of bounds.\n *\n * If \"fit\" option was specified and index is out of bounds, it will be cut to the nearest\n * bound.\n * @param index - target index.\n * @param fit - cuts the index argument to fit the bounds `[0, history.length - 1]`.\n */\n goTo(index: number, fit?: boolean): void {\n this.navigator.goTo(index, fit);\n }\n\n /**\n * Current history item hash.\n * @see URL.hash\n * @example\n * \"\", \"#my-hash\"\n */\n get hash(): string {\n return (this.navigator.current.params || {}).hash || '';\n }\n\n /**\n * True if navigator has items before the current item.\n */\n get hasPrev(): boolean {\n return this.navigator.hasPrev;\n }\n\n /**\n * True if navigator has items after the current item.\n */\n get hasNext(): boolean {\n return this.navigator.hasNext;\n }\n\n /**\n * Navigation history.\n */\n get history(): BrowserNavigatorHistoryItem<State>[] {\n return this.navigator.history.map(basicItemToBrowser);\n }\n\n /**\n * Handles the window \"popstate\" event.\n * @param state - event state.\n */\n private onPopState = ({ state }: PopStateEvent) => {\n // In case state is null, we recognize current event as occurring whenever user clicks\n // any anchor.\n // TODO: Should we do it?\n if (state === null) {\n return this.push(this.parsePath(window.location.href));\n }\n\n // There is only one case when state can be CURSOR_VOID - when history contains\n // only one element. In this case, we should return user to the current history element.\n if (state === CURSOR_VOID) {\n window.history.forward();\n } else if (state === CURSOR_BACK) {\n this.back();\n }\n if (state === CURSOR_FORWARD) {\n this.forward();\n }\n };\n\n /**\n * Underlying navigator change event listener.\n */\n private onNavigatorChange = async ({\n to,\n from,\n delta,\n }: BasicNavigatorEvents<BrowserNavigatorHistoryItemParams<State>>['change']) => {\n // If this navigator is attached to the browser history, we should synchronize.\n if (this.attached) {\n await this.syncHistory();\n }\n this.ee.emit('change', {\n delta,\n from: basicItemToBrowser(from),\n to: basicItemToBrowser(to),\n navigator: this,\n });\n };\n\n /**\n * Adds new event listener.\n */\n on: Emitter<State>['on'] = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off: Emitter<State>['off'] = this.ee.off.bind(this.ee);\n\n /**\n * Path, including pathname, search and hash.\n * @example Pathname only.\n * \"/pathname\"\n * @example Pathname + search.\n * \"/pathname?search\"\n * @example Pathname + hash.\n * \"/pathname#hash\"\n * @example Pathname + search + hash.\n * \"/pathname?search#hash\"\n */\n get path(): string {\n return urlToPath(this);\n }\n\n /**\n * Current pathname. Always starts with the slash.\n * @see URL.pathname\n * @example\n * \"/\", \"/abc\"\n */\n get pathname(): string {\n return this.navigator.current.pathname;\n }\n\n /**\n * Depending on the current navigation type, parses incoming path and returns it presented as\n * an object. In other words, this method parses the passed path and returns object, describing\n * how the navigator \"sees\" it.\n *\n * @example Hash mode is omitted.\n * parsePath('/abc?a=1#hash');\n * // { pathname: '/abc', search: '?a=1', hash: '#hash' }\n * parsePath('http://example.com/abc?a=1#hash');\n * // { pathname: '/abc', search: '?a=1', hash: '#hash' }\n *\n * @example Hash mode is enabled.\n * parsePath('/abc?a=1#tma?is=cool#yeah');\n * // { pathname: '/tma', search: '?is=cool', hash: '#yeah' }\n * parsePath('http://example.com/abc?a=1#tma?is=cool#yeah');\n * // { pathname: '/tma', search: '?is=cool', hash: '#yeah' }\n */\n parsePath(path: string | URL): URLLike {\n let url = createSafeURL(path);\n if (this.hashMode) {\n url = createSafeURL(url.hash.slice(1));\n }\n\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash,\n };\n }\n\n /**\n * Pushes new history item. Method replaces all entries after the current one with the one\n * being pushed. Take a note, that passed item is always relative. In case, you want to use\n * it as an absolute one, use the \"/\" prefix. Example: \"/absolute\", { pathname: \"/absolute\" }.\n *\n * To create a final path, navigator uses a method, used in the URL class constructor, resolving\n * a path based on the current one.\n * @param path - entry path.\n * @param state - entry state.\n *\n * @example Pushing an absolute path.\n * push(\"/absolute\"); // \"/absolute\"\n *\n * @example Pushing a relative path.\n * push(\"relative\"); // \"/home/root\" -> \"/home/relative\"\n *\n * @example Pushing query parameters.\n * push(\"/absolute?my-param=1\"); // \"/home/root\" -> \"/absolute?my-param=1\"\n * push(\"relative?my-param=1\"); // \"/home/root\" -> \"/home/relative?my-param=1\"\n * push(\"?my-param=1\"); // \"/home\" -> \"/home?my-param=1\"\n *\n * @example Pushing hash.\n * push(\"#my-hash\"); // \"/home\" -> \"/home#my-hash\"\n * push(\"relative#my-hash\"); // \"/home/root\" -> \"/home/relative#my-hash\"\n *\n * @example Pushing state.\n * push(\"\", { state: 'my-state' }); \"/home/root\" -> \"/home/root\"\n * push({ state: 'my-state' }); \"/home/root\" -> \"/home/root\"\n */\n push(path: string, state?: State): void;\n push(item: BrowserNavigatorAnyHistoryItem<State>): void;\n push(itemOrPath: string | BrowserNavigatorAnyHistoryItem<State>, fnState?: State): void {\n const item = prepareItem(itemOrPath, this.path);\n const { state = fnState } = item.params;\n this.navigator.push({ ...item, params: { ...item.params, state } });\n }\n\n /**\n * Replaces the current history item. Has the same logic as the `push` method.\n * @param path - entry path.\n * @param state - entry state.\n * @see push\n */\n replace(path: string, state?: State): void;\n replace(item: BrowserNavigatorAnyHistoryItem<State>): void;\n replace(itemOrPath: string | BrowserNavigatorAnyHistoryItem<State>, fnState?: State): void {\n const item = prepareItem(itemOrPath, this.path);\n const { state = fnState } = item.params;\n this.navigator.replace({ ...item, params: { ...item.params, state } });\n }\n\n /**\n * Combines the navigator `base` property with the passed path data applying the navigator\n * navigation mode.\n * @param value - path presented as string or URLLike.\n */\n renderPath(value: string | URLLike): string {\n const path = (this.base.length === 1 ? '' : this.base)\n + ensurePrefix(urlToPath(value), '/');\n\n return this.hashMode\n ? ensurePrefix(path.slice(1), this.hashMode === 'classic' ? '#' : '#/')\n : path;\n }\n\n /**\n * Synchronizes current navigator state with browser history.\n */\n private async syncHistory(): Promise<void> {\n // Remove history change event listener to get rid of side effects related to the possible\n // future calls of history.go.\n window.removeEventListener('popstate', this.onPopState);\n\n const { state } = this;\n const path = this.renderPath(this);\n\n // Drop the browser history and work with the clean one.\n await drop();\n\n if (this.hasPrev && this.hasNext) {\n // We have both previous and next elements. History should be:\n // [back, *current*, forward]\n window.history.replaceState(CURSOR_BACK, '');\n window.history.pushState(state, '', path);\n window.history.pushState(CURSOR_FORWARD, '');\n\n await go(-1);\n } else if (this.hasPrev) {\n // We have only previous element. History should be:\n // [back, *current*]\n window.history.replaceState(CURSOR_BACK, '');\n window.history.pushState(state, '', path);\n } else if (this.hasNext) {\n // We have only next element. History should be:\n // [*current*, forward]\n window.history.replaceState(state, path);\n window.history.pushState(CURSOR_FORWARD, '');\n\n await go(-1);\n } else {\n // We have no back and next elements. History should be:\n // [void, *current*]\n window.history.replaceState(CURSOR_VOID, '');\n window.history.pushState(state, '', path);\n }\n\n window.addEventListener('popstate', this.onPopState);\n }\n\n /**\n * Current query parameters.\n * @see URL.search\n * @example\n * \"\", \"?\", \"?a=1\"\n */\n get search(): string {\n return (this.navigator.current.params || {}).search || '';\n }\n\n /**\n * Current history item state.\n */\n get state(): State | undefined {\n return (this.navigator.current.params || {}).state;\n }\n}\n","import { createError } from '@/errors/createError.js';\nimport { ERR_INVALID_PATH_BASE } from '@/errors/errors.js';\nimport { BrowserNavigator } from '@/navigation/BrowserNavigator/BrowserNavigator.js';\nimport { getPathname } from '@/navigation/getPathname.js';\nimport { urlToPath } from '@/navigation/urlToPath.js';\nimport type { BrowserNavigatorConOptions } from '@/navigation/BrowserNavigator/types.js';\n\nexport function createBrowserNavigatorFromLocation<State>(\n options?: BrowserNavigatorConOptions,\n): BrowserNavigator<State> {\n options ||= {};\n const { href, hash } = window.location;\n\n let path = urlToPath(\n options.hashMode === null\n // Hash mode is explicitly disabled. We are working with the usual location path.\n ? href\n // If hash mode is enabled, we should create a navigator based on the location's hash.\n // In this case we have 2 possible situations:\n // 1. Hash contains only launch parameters. Example:\n // #tgWebAppData=...&tgWebAppPlatform=...&...\n // Here we should mark the launch parameters as query parameters and have pathname \"/\" as\n // the initial one.\n //\n // 2. Hash contains value, passed from above and launch parameters as query parameters.\n // For instance, we could have such a URL:\n // https://t.me/mybot/myapp#my-hash\n // In this case, the Mini App will be opened with this URL:\n // https://example.com/#my-hash?tgWebAppData=...&tgWebAppPlatform=...&...\n : hash.includes('?') ? hash.slice(1) : `?${hash.slice(1)}`,\n );\n\n // If some base was specified, we should check if computed path starts with this base. In\n // case it does, it should be removed from the path. Otherwise, an error must be thrown.\n const base = options.base ? getPathname(options.base) : undefined;\n if (base) {\n if (!path.startsWith(base)) {\n throw createError(\n ERR_INVALID_PATH_BASE,\n `Path \"${path}\" expected to be starting with \"${base}\"`,\n );\n }\n path = path.slice(base.length);\n }\n\n return new BrowserNavigator<State>([path], 0, options);\n}\n","/**\n * @param value - string to take hash part from.\n * @returns String after the first met \"#\" symbol. In case, value doesn't contain hashtag, the\n * function will return null.\n *\n * @example No hash.\n * getHash('/path'); // null\n *\n * @example Has hash.\n * getHash('/path#abc'); // 'abc'\n *\n * @example Has double hash.\n * getHash('/path#abc#another'); // 'abc#another'\n */\nexport function getHash(value: string): string | null {\n const match = value.match(/#(.+)/);\n return match ? match[1] : null;\n}\n","import { BrowserNavigatorConOptions } from '@/navigation/BrowserNavigator/types.js';\nimport { BrowserNavigator } from '@/navigation/BrowserNavigator/BrowserNavigator.js';\nimport { isPageReload } from '@/navigation/isPageReload.js';\nimport {\n createBrowserNavigatorFromLocation\n} from '@/navigation/BrowserNavigator/createBrowserNavigatorFromLocation.js';\n\n\nfunction instantiate<State>(\n sessionStorageKey: string,\n options?: BrowserNavigatorConOptions,\n): BrowserNavigator<State> {\n // If page was reloaded, we assume that navigator had to previously save its state in the\n // session storage.\n if (isPageReload()) {\n const stateRaw = sessionStorage.getItem(sessionStorageKey);\n if (stateRaw) {\n try {\n const { index, history } = JSON.parse(stateRaw);\n return new BrowserNavigator(history, index, options);\n } catch (e) {\n console.error('Unable to restore hash navigator state.', e);\n }\n }\n }\n\n // In case, we could not restore its state, or it is a fresh start, we can create an empty\n // navigator. We are creating BrowserNavigator from the window.location.\n return createBrowserNavigatorFromLocation(options);\n}\n\n/**\n * Initializes a standard Mini Apps navigator.\n * @param sessionStorageKey - session storage key, containing the navigator state.\n * @param options - additional BrowserNavigator options.\n */\nexport function initNavigator<State>(\n sessionStorageKey: string,\n options?: BrowserNavigatorConOptions,\n): BrowserNavigator<State> {\n const navigator = instantiate<State>(sessionStorageKey, options);\n\n const saveState = () => sessionStorage.setItem(sessionStorageKey, JSON.stringify({\n index: navigator.index,\n history: navigator.history,\n }));\n\n // Whenever navigator changes its state, we save it in the session storage.\n navigator.on('change', saveState);\n\n // Save the initial state to make sure nothing will break when the page was reloaded.\n saveState();\n\n return navigator;\n}\n"],"names":["createSingleton","create","onReset","cached","reset","unsubscribe","listener","ee","miniAppsEventEmitter","count","resetMiniAppsEventEmitter","subscribe","Logger","scope","options","level","args","now","date","textColor","bgColor","commonCss","logger","debugEnabled","onEvent","name","payload","setDebug","enable","log","EventEmitter","__publicField","event","l","once","listeners","i","onWindow","type","createCleanup","fns","called","cache","fn","clean","SDKError","message","cause","createError","ERR_METHOD_UNSUPPORTED","ERR_METHOD_PARAMETER_UNSUPPORTED","ERR_UNKNOWN_ENV","ERR_INVOKE_CUSTOM_METHOD_RESPONSE","ERR_TIMED_OUT","ERR_UNEXPECTED_TYPE","ERR_PARSE","ERR_NAVIGATION_HISTORY_EMPTY","ERR_NAVIGATION_INDEX_INVALID","ERR_NAVIGATION_ITEM_INVALID","ERR_SSR_INIT","ERR_INVALID_PATH_BASE","createTypeError","ValueParser","parser","isOptional","value","createValueParserGenerator","boolean","asString","parseBySchema","schema","getField","result","field","definition","from","definitionType","parsedValue","error","toRecord","formattedValue","json","record","number","num","isRGB","isRGBShort","toRGB","color","match","acc","component","formatted","string","rgb","parseMessage","v","cleanupEventHandlers","prop","emitMiniAppsEvent","eventType","eventData","defineEventHandlers","path","pointer","item","idx","arr","parsers","k","createMiniAppsEventEmitter","subEmitter","mainEmitter","cleanup","data","get","emitter","off","on","isRecord","compareVersions","a","b","aParts","bParts","len","aVal","bVal","versionLessOrEqual","supports","method","paramOrVersion","inVersion","hasExternalNotify","hasWebviewProxy","isIframe","currentTargetOrigin","setTargetOrigin","targetOrigin","postEvent","paramsOrOptions","postOptions","targetOriginFn","createPostEvent","version","params","validateParam","captureSameReq","reqId","req_id","createTimeoutError","timeout","withTimeout","funcOrPromise","_","rej","request","resolve","promise","res","capture","ev","defaultPostEvent","invokeCustomMethod","requestId","classNames","values","entry","mergeClassNames","partials","partial","key","className","isColorDark","modifier","dec","State","state","keyOrState","keyValue","WithStateUtils","shape","createSupportsFn","WithSupportsAndStateUtils","stateShape","supportsSchema","BackButton","isVisible","visible","searchParams","paramValue","chat","user","initData","keyToLocal","keyToExternal","themeParams","rgbOptional","parseLaunchParams","retrieveFromUrl","urlString","retrieveFromLocation","getFirstNavigationEntry","retrieveFromPerformance","navigationEntry","formatKey","m","setStorageValue","getStorageValue","retrieveFromStorage","serializeThemeParams","serializeLaunchParams","initDataRaw","platform","showSettings","startParam","botInline","saveToStorage","retrieveLaunchParams","retrieve","lp","isPageReload","createRequestIdGenerator","createReqId","createComponentInitFn","factoryStaticOrSK","factoryDynamic","factoryOptions","addCleanup","cleanedUp","bindChange","initBackButton","WithSupportsAndTrackableState","formatEvent","BiometryManager","rest","reason","token","response","requestBiometryInfo","initBiometryManager","WithTrackableState","ClosingBehavior","isConfirmationNeeded","initClosingBehavior","WithSupports","parseArray","ArrayParser","itemParser","array","parserTypeName","objectFromKeys","keys","CloudStorage","createRequestId","keyOrKeys","initCloudStorage","HapticFeedback","style","initHapticFeedback","InitData","canSendAfter","initInitData","parseInitData","Invoice","isOpened","urlOrSlug","slug","hostname","pathname","initInvoice","MainButton","isEnabled","isLoaderVisible","text","initMainButton","contact","createSupportsParamFn","tmaMethod","param","sleep","duration","MiniApp","supportsOriginal","deadlineAt","sleepTime","status","size","chatTypes","initMiniApp","preparePopupParams","title","buttons","preparedButtons","id","Popup","buttonId","initPopup","QRScanner","textOrOptions","qr","e","initQRScanner","SettingsButton","initSettingsButton","parseThemeParams","ThemeParams","initThemeParams","tp","requestThemeParams","Utils","url","tryInstantView","formattedUrl","search","initUtils","requestViewport","isExpanded","isStateStable","truncate","Viewport","stableHeight","height","width","truncatedHeight","initViewport","viewport","setCSSVar","bindMiniAppCSSVars","miniApp","getVarName","property","headerVar","bgVar","actualize","headerColor","secondaryBgColor","bindThemeParamsCSSVars","getCSSVarName","bindViewportCSSVars","heightVar","widthVar","stableHeightVar","setHeight","setWidth","setStableHeight","initWeb","acceptCustomStyles","html","isSSR","isTMA","mockTelegramEnv","launchParamsRaw","wiredPostMessage","postMessage","notify","proxy","isSDKError","isSDKErrorOfType","prepareItem","relativePathname","BasicNavigator","history","_index","delta","fit","index","fitIndex","historyItem","prevIndex","basicItemToBrowser","ensurePrefix","prefix","createSafeURL","urlOrPath","urlToPath","isAbsolute","itemOrPath","relativePath","hash","go","remove","drop","shouldGoBack","getPathname","CURSOR_VOID","CURSOR_BACK","CURSOR_FORWARD","BrowserNavigator","hashMode","base","to","fnState","createBrowserNavigatorFromLocation","href","getHash","instantiate","sessionStorageKey","stateRaw","initNavigator","navigator","saveState"],"mappings":"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"}