@tma.js/sdk 1.2.0 → 1.3.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.
- package/dist/dts/index.d.ts +1 -1
- package/dist/dts/init/creators/createViewport.d.ts +2 -9
- package/dist/dts/init/init.d.ts +2 -0
- package/dist/dts/init/types.d.ts +7 -4
- package/dist/dts/mini-app/types.d.ts +1 -1
- package/dist/dts/types/platform.d.ts +1 -1
- package/dist/dts/viewport/index.d.ts +1 -0
- package/dist/dts/viewport/isStableViewportPlatform.d.ts +7 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.iife.js +1 -1
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +407 -410
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/init/creators/createViewport.ts +60 -81
- package/src/init/init.ts +13 -15
- package/src/init/types.ts +8 -4
- package/src/mini-app/contactParser.ts +1 -1
- package/src/mini-app/types.ts +1 -1
- package/src/types/platform.ts +2 -2
- package/src/viewport/index.ts +1 -0
- package/src/viewport/isStableViewportPlatform.ts +10 -0
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/misc/isRecord.ts","../src/launch-params/getFirstNavigationEntry.ts","../src/launch-params/computePageReload.ts","../src/parsing/unexpectedTypeError.ts","../src/parsing/ParseError.ts","../src/parsing/ValueParser.ts","../src/parsing/ArrayValueParser.ts","../src/parsing/createValueParserGenerator.ts","../src/parsing/ParseSchemaFieldError.ts","../src/parsing/parseBySchema.ts","../src/parsing/parsers/array.ts","../src/parsing/parsers/boolean.ts","../src/parsing/parsers/number.ts","../src/parsing/parsers/date.ts","../src/parsing/toRecord.ts","../src/parsing/parsers/json.ts","../src/colors/isRGB.ts","../src/colors/isRGBShort.ts","../src/colors/toRGB.ts","../src/colors/isColorDark.ts","../src/parsing/parsers/string.ts","../src/parsing/parsers/rgb.ts","../src/parsing/parsers/searchParams.ts","../src/init-data/chatParser.ts","../src/init-data/InitData.ts","../src/init-data/userParser.ts","../src/init-data/initDataParser.ts","../src/init-data/parseInitData.ts","../src/theme-params/keys.ts","../src/theme-params/themeParamsParser.ts","../src/theme-params/parseThemeParams.ts","../src/theme-params/requestThemeParams.ts","../src/theme-params/serializeThemeParams.ts","../src/event-emitter/EventEmitter.ts","../src/state/State.ts","../src/theme-params/ThemeParams.ts","../src/launch-params/launchParamsParser.ts","../src/launch-params/parseLaunchParams.ts","../src/launch-params/retrieveFromLocation.ts","../src/launch-params/retrieveFromPerformance.ts","../src/launch-params/retrieveCurrent.ts","../src/launch-params/serializeLaunchParams.ts","../src/launch-params/storage.ts","../src/launch-params/computeLaunchData.ts","../src/launch-params/retrieveLaunchData.ts","../src/misc/isTMA.ts","../src/bridge/env/hasExternalNotify.ts","../src/bridge/env/hasWebviewProxy.ts","../src/bridge/env/isIframe.ts","../src/bridge/errors/MethodUnsupportedError.ts","../src/bridge/errors/ParameterUnsupportedError.ts","../src/logger/Logger.ts","../src/globals.ts","../src/bridge/events/onTelegramEvent.ts","../src/bridge/events/parsers/clipboardTextReceived.ts","../src/bridge/events/parsers/customMethodInvoked.ts","../src/bridge/events/parsers/invoiceClosed.ts","../src/bridge/events/parsers/phoneRequested.ts","../src/bridge/events/parsers/popupClosed.ts","../src/bridge/events/parsers/qrTextReceived.ts","../src/bridge/events/parsers/theme-changed.ts","../src/bridge/events/parsers/viewportChanged.ts","../src/bridge/events/parsers/writeAccessRequested.ts","../src/bridge/events/createEmitter.ts","../src/bridge/events/singletonEmitter.ts","../src/bridge/events/off.ts","../src/bridge/events/on.ts","../src/bridge/events/once.ts","../src/bridge/events/unsubscribe.ts","../src/bridge/events/subscribe.ts","../src/version/compareVersions.ts","../src/supports/supports.ts","../src/supports/createSupportsFunc.ts","../src/supports/createSupportsParamFunc.ts","../src/bridge/methods/postEvent.ts","../src/bridge/methods/createPostEvent.ts","../src/timeout/TimeoutError.ts","../src/timeout/isTimeoutError.ts","../src/timeout/sleep.ts","../src/timeout/withTimeout.ts","../src/bridge/request.ts","../src/bridge/invoke-custom-method.ts","../src/back-button/BackButton.ts","../src/classnames/classNames.ts","../src/classnames/mergeClassNames.ts","../src/closing-behavior/ClosingBehavior.ts","../src/cloud-storage/CloudStorage.ts","../src/haptic-feedback/HapticFeedback.ts","../src/init/catchCustomStyles.ts","../src/storage.ts","../src/init/creators/createBackButton.ts","../src/init/creators/createClosingBehavior.ts","../src/main-button/MainButton.ts","../src/init/creators/createMainButton.ts","../src/mini-app/contactParser.ts","../src/mini-app/MiniApp.ts","../src/init/creators/createMiniApp.ts","../src/init/creators/createRequestIdGenerator.ts","../src/settings-button/SettingsButton.ts","../src/init/creators/createSettingsButton.ts","../src/init/creators/createThemeParams.ts","../src/viewport/requestViewport.ts","../src/viewport/utils.ts","../src/viewport/Viewport.ts","../src/init/creators/createViewport.ts","../src/init/css/setCSSVar.ts","../src/init/css/bindMiniAppCSSVars.ts","../src/init/css/bindThemeCSSVars.ts","../src/init/css/bindViewportCSSVars.ts","../src/init/css/processCSSVarsOption.ts","../src/invoice/Invoice.ts","../src/popup/preparePopupParams.ts","../src/popup/Popup.ts","../src/qr-scanner/QRScanner.ts","../src/utils/Utils.ts","../src/init/init.ts","../src/navigation/ensurePrefix.ts","../src/navigation/getHash.ts","../src/navigation/HashNavigator/go.ts","../src/navigation/HashNavigator/drop.ts","../src/navigation/Navigator/Navigator.ts","../src/navigation/HashNavigator/HashNavigator.ts"],"sourcesContent":["/**\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","/**\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 | null {\n return (\n performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming | undefined\n ) || null;\n}\n","import { getFirstNavigationEntry } from './getFirstNavigationEntry.js';\n\n/**\n * Determines if current page was reloaded.\n * @returns Boolean if function was able to compute any valid value. Null in case, no\n * navigation entries were found.\n */\nexport function computePageReload(): boolean | null {\n const firstNavigationEntry = getFirstNavigationEntry();\n return firstNavigationEntry\n ? firstNavigationEntry.type === 'reload'\n : null;\n}\n","/**\n * Creates instance of TypeError stating, that value has unexpected type.\n */\nexport function unexpectedTypeError(): TypeError {\n return new TypeError('Value has unexpected type');\n}\n","interface Options {\n /**\n * Type name.\n */\n type?: string;\n\n /**\n * Original occurred error.\n */\n cause?: unknown;\n}\n\n/**\n * Error thrown in case, there was an error during parsing.\n */\nexport class ParseError extends Error {\n /**\n * Parser name.\n */\n public readonly type?: string;\n\n constructor(public readonly value: unknown, { cause, type }: Options = {}) {\n super(`Unable to parse value${type ? ` as ${type}` : ''}`, { cause });\n Object.setPrototypeOf(this, ParseError.prototype);\n this.type = type;\n }\n}\n","import type { If } from '~/types/index.js';\n\nimport { ParseError } from './ParseError.js';\nimport type { Parser } from './types.js';\n\n/**\n * Result of \"parse\" function.\n */\nexport type ParseResult<ResultType, IsOptional extends boolean> =\n | ResultType\n | If<IsOptional, undefined, never>;\n\n/**\n * Result of \"optional\" function in ValueParser.\n */\nexport type OptionalResult<BaseClass, ResultType> = ValueParserType<\nBaseClass,\nResultType,\ntrue\n>;\n\nexport interface ValueParserOverrides<BaseClass, ResultType, IsOptional extends boolean> {\n /**\n * Parses incoming value applying parsing function passed via constructor.\n * @param value - value to parse.\n */\n parse(value: unknown): ParseResult<ResultType, IsOptional>;\n\n /**\n * Marks this parser result as optional. This makes the parser to check if passed value\n * is empty. If so, parser will return undefined value instead of passing it to the actual\n * parser.\n */\n optional(): OptionalResult<BaseClass, ResultType>;\n}\n\n/**\n * Describes generated ValueParser interface. Shortly saying, this type overrides BaseClass\n * properties defined in ValueParser.\n */\nexport type ValueParserType<BaseClass, ResultType, IsOptional extends boolean> =\n Omit<BaseClass, keyof ValueParserOverrides<any, any, any>>\n & ValueParserOverrides<BaseClass, ResultType, IsOptional>;\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 parse(value: unknown): ParseResult<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 ParseResult<ResultType, IsOptional>;\n }\n\n try {\n return this.parser(value) as ParseResult<ResultType, IsOptional>;\n } catch (cause) {\n throw new ParseError(value, { type: this.type, cause });\n }\n }\n\n optional(): OptionalResult<this, ResultType> {\n this.isOptional = true as IsOptional;\n return this as OptionalResult<this, ResultType>;\n }\n}\n","import type { AnyParser, Parser } from './types.js';\nimport { unexpectedTypeError } from './unexpectedTypeError.js';\nimport type { ParseResult, ValueParserOverrides } from './ValueParser.js';\nimport { ValueParser } from './ValueParser.js';\n\nexport type OfResult<BaseClass, ItemType, IsOptional extends boolean> = ArrayParserType<\nBaseClass,\nItemType,\nIsOptional\n>;\n\nexport interface ArrayParserOverrides<\n BaseClass,\n ItemType,\n IsOptional extends boolean,\n> extends ValueParserOverrides<BaseClass, ItemType[], IsOptional> {\n /**\n * Specifies parser for each array item.\n * @param parser - item parser.\n */\n of<Item>(parser: AnyParser<Item>): OfResult<BaseClass, Item, IsOptional>;\n}\n\nexport type ArrayParserType<BaseClass, ItemType, IsOptional extends boolean> =\n Omit<BaseClass, keyof ArrayParserOverrides<any, any, any>>\n & ArrayParserOverrides<BaseClass, ItemType, IsOptional>;\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 unexpectedTypeError();\n}\n\nexport class ArrayValueParser<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 override parse(value: unknown): ParseResult<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>): OfResult<this, Item, IsOptional> {\n this.itemParser = typeof itemParser === 'function'\n ? itemParser\n : itemParser.parse.bind(itemParser);\n\n return this as OfResult<this, Item, IsOptional>;\n }\n}\n","import type { Parser } from './types.js';\nimport { ValueParser } from './ValueParser.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","interface Options {\n /**\n * Type name.\n */\n type?: string;\n\n /**\n * Original occurred error.\n */\n cause?: unknown;\n}\n\n/**\n * Error thrown in case, there was an error during parse.\n */\nexport class ParseSchemaFieldError extends Error {\n constructor(field: string, { cause, type }: Options = {}) {\n super(`Unable to parse field \"${field}\"${type ? ` as ${type}` : ''}`, { cause });\n Object.setPrototypeOf(this, ParseSchemaFieldError.prototype);\n }\n}\n","import { ParseError } from './ParseError.js';\nimport { ParseSchemaFieldError } from './ParseSchemaFieldError.js';\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 } = definition;\n\n from = definition.from || field;\n parser = typeof type === 'function' ? type : type.parse.bind(type);\n }\n\n let parsedValue: unknown;\n const originalValue = getField(from);\n\n try {\n parsedValue = parser(originalValue);\n } catch (error) {\n // If error is not instance of ParseError, we have nothing additional to do with the error.\n if (!(error instanceof ParseError)) {\n throw new ParseSchemaFieldError(from, { cause: error });\n }\n\n // Otherwise, we are going to rethrow the error with extended data.\n throw new ParseSchemaFieldError(from, {\n type: error.type,\n cause: error,\n });\n }\n\n if (parsedValue === undefined) {\n continue;\n }\n\n (result as any)[field] = parsedValue;\n }\n\n return result;\n}\n","import { ArrayValueParser } from '../ArrayValueParser.js';\n\n/**\n * Parses incoming value as an array.\n * @param type - parser type name.\n */\nexport function array(type?: string): ArrayValueParser<unknown, false> {\n return new ArrayValueParser((value) => value, false, type);\n}\n","import { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { unexpectedTypeError } from '../unexpectedTypeError.js';\n\n/**\n * Returns parser to parse value as boolean.\n */\nexport const boolean = createValueParserGenerator<boolean>((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 unexpectedTypeError();\n}, 'boolean');\n","import { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { unexpectedTypeError } from '../unexpectedTypeError.js';\n\n/**\n * Returns parser to parse value as number.\n */\nexport const number = createValueParserGenerator<number>((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 unexpectedTypeError();\n}, 'number');\n","import { number } from './number.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as Date.\n */\nexport const date = createValueParserGenerator<Date>((value) => (\n value instanceof Date\n ? value\n : new Date(number().parse(value) * 1000)\n), 'Date');\n","import { unexpectedTypeError } from './unexpectedTypeError.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 unexpectedTypeError();\n }\n\n return formattedValue;\n}\n","import { parseBySchema } from '../parseBySchema.js';\nimport { toRecord } from '../toRecord.js';\nimport type { Schema } from '../types.js';\nimport { ValueParser } from '../ValueParser.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\n return parseBySchema(schema, (field) => record[field]);\n }, false, type);\n}\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 = '#';\n\n for (let i = 0; i < 3; i += 1) {\n color += clean[1 + i].repeat(2);\n }\n return color as RGB;\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 === null) {\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 { 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 const hsp = 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 );\n return hsp < 120;\n}\n","import { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { unexpectedTypeError } from '../unexpectedTypeError.js';\n\n/**\n * Returns parser to parse value as string.\n */\nexport const string = createValueParserGenerator<string>((value) => {\n if (typeof value === 'string' || typeof value === 'number') {\n return value.toString();\n }\n throw unexpectedTypeError();\n}, 'string');\n","import { toRGB } from '~/colors/index.js';\nimport type { RGB } from '~/colors/index.js';\n\nimport { string } from './string.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as RGB color.\n */\nexport const rgb = createValueParserGenerator<RGB>((value) => toRGB(string().parse(value)), 'rgb');\n","import { parseBySchema } from '../parseBySchema.js';\nimport type { Schema } from '../types.js';\nimport { unexpectedTypeError } from '../unexpectedTypeError.js';\nimport { ValueParser } from '../ValueParser.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 unexpectedTypeError();\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, number, string } from '~/parsing/index.js';\n\nimport type { Chat } from './types.js';\n\n/**\n * Returns parser used to parse chat data.\n */\nexport function chatParser() {\n return 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}\n","import type {\n Chat,\n ChatType,\n InitDataParsed,\n User,\n} from './types.js';\n\n/**\n * Class which is responsible for displaying Mini Apps 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 === undefined\n ? undefined\n : new Date(this.authDate.getTime() + canSendAfter * 1000);\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 { boolean, json, number, string } from '~/parsing/index.js';\n\nimport type { User } from './types.js';\n\n/**\n * Returns parser used to parse user data.\n */\nexport function userParser() {\n return 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}\n","import { date, number, searchParams, string } from '~/parsing/index.js';\n\nimport { chatParser } from './chatParser.js';\nimport type { InitDataParsed } from './types.js';\nimport { userParser } from './userParser.js';\n\n/**\n * Returns parser used to parse init data, presented as search params.\n */\nexport function initDataParser() {\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: chatParser().optional(),\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: userParser().optional(),\n startParam: {\n type: string().optional(),\n from: 'start_param',\n },\n user: userParser().optional(),\n }, 'InitData');\n}\n","import { initDataParser } from './initDataParser.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 initDataParser().parse(value);\n}\n","/**\n * Converts palette key from Telegram application to representation used by the package.\n * @param key - palette key.\n */\nexport function keyToLocal(key: string): string {\n return key\n // Replace all \"background\" strings to \"bg\".\n .replace(/(^|_)bg/, (_, prefix) => `${prefix}background`)\n // Convert camel case to snake case.\n .replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase());\n}\n\n/**\n * Converts palette key from local representation to representation sent from the Telegram\n * application.\n * @param key - palette key.\n */\nexport function keyToExternal(key: string): string {\n return key\n // Convert camel case to snake case.\n .replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`)\n // Replace all \"background\" strings to \"bg\".\n .replace(/(^|_)background/, (_, prefix) => `${prefix}bg`);\n}\n","import {\n createValueParserGenerator,\n rgb,\n toRecord,\n} from '~/parsing/index.js';\n\nimport { keyToLocal } from './keys.js';\nimport type { ThemeParamsParsed } from './types.js';\n\nexport const themeParamsParser = createValueParserGenerator<ThemeParamsParsed>(\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 { themeParamsParser } from './themeParamsParser.js';\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 themeParamsParser().parse(value);\n}\n","import { request, type RequestOptions } from '~/bridge/index.js';\n\nimport { parseThemeParams } from './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: RequestOptions = {}): Promise<ThemeParamsParsed> {\n return request('web_app_request_theme', 'theme_changed', options)\n .then(parseThemeParams);\n}\n","import type { RGB } from '~/colors/index.js';\n\nimport { 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\n .entries(themeParams)\n .reduce<Record<string, RGB>>((acc, [key, value]) => {\n if (value) {\n acc[keyToExternal(key)] = value;\n }\n return acc;\n }, {}),\n );\n}\n","import type {\n AnySubscribeListener,\n EmptyEventName,\n EventListener, EventName,\n EventParams, NonEmptyEventName, RemoveEventListener,\n} from './types.js';\n\ntype AddedEventListener = [listener: EventListener<any>, once: boolean];\n\n/**\n * Opinionated event emitter implementation.\n */\nexport class EventEmitter<Schema> {\n private readonly listeners: Map<string, AddedEventListener[]> = new Map();\n\n private readonly subscribeListeners: AnySubscribeListener<Schema>[] = [];\n\n /**\n * Adds specified event listener.\n * @param event - event name.\n * @param listener - event listener.\n * @param once - should listener called only once.\n */\n private addListener<E extends EventName<Schema>>(\n event: E,\n listener: EventListener<Schema[E]>,\n once: boolean,\n ): RemoveEventListener {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n listeners = [];\n this.listeners.set(event, listeners);\n }\n\n listeners.push([listener, once]);\n\n return () => this.off(event, listener);\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>>(\n event: E,\n ...args: EventParams<Schema[E]>\n ): void;\n\n emit(event: EventName<Schema>, ...args: any[]): void {\n this.subscribeListeners.forEach((l) => (l as any)(event, ...args));\n\n const listeners = this.listeners.get(event);\n if (!listeners) {\n return;\n }\n\n listeners.forEach(([listener, once], idx) => {\n listener(...args);\n if (once) {\n listeners.splice(idx, 1);\n }\n });\n }\n\n /**\n * Adds event listener.\n * @param event - event name.\n * @param listener - event listener.\n * @returns Function to remove event listener.\n */\n on<E extends EventName<Schema>>(\n event: E,\n listener: EventListener<Schema[E]>,\n ): RemoveEventListener {\n return this.addListener(event, listener, false);\n }\n\n /**\n * Adds event listener following the logic, described in `on` method, but calls specified\n * listener only once, removing it after.\n * @param event - event name.\n * @param listener - event listener.\n * @returns Function to remove event listener.\n * @see on\n */\n once<E extends EventName<Schema>>(\n event: E,\n listener: EventListener<Schema[E]>,\n ): RemoveEventListener {\n return this.addListener(event, listener, true);\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 if (!listeners) {\n return;\n }\n\n for (let i = 0; i < listeners.length; i += 1) {\n if (listener === listeners[i][0]) {\n listeners.splice(i, 1);\n return;\n }\n }\n }\n\n /**\n * Adds event listener to all events.\n * @param listener - events listener.\n * @returns Function to remove event listener.\n * @see on\n * @see once\n */\n subscribe(listener: AnySubscribeListener<Schema>): RemoveEventListener {\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 - events listener.\n * @returns Function to remove event listener.\n */\n unsubscribe(listener: AnySubscribeListener<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 { EventEmitter } from '~/event-emitter/index.js';\nimport type { StringKeys } from '~/types/index.js';\n\nimport type { StateEvents } from './types.js';\n\n/**\n * Represents state which is observable via passed EventEmitter.\n */\nexport class State<S extends object> {\n constructor(\n private readonly state: S,\n private readonly ee: Pick<EventEmitter<StateEvents<S>>, 'on' | 'off' | 'emit'>,\n ) {\n }\n\n private internalSet<K extends StringKeys<S>>(key: K, value: S[K]): boolean {\n if (this.state[key] === value || value === undefined) {\n return false;\n }\n\n this.state[key] = value;\n (this.ee as any).emit(`change:${key}`, value);\n\n return true;\n }\n\n /**\n * Returns copy of current state.\n */\n clone(): S {\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<S>>(key: K, value: S[K]): void;\n set(state: Partial<S>): void;\n set(keyOrState: StringKeys<S> | Partial<S>, value?: S[keyof S]): void {\n let didChange = false;\n\n if (typeof keyOrState === 'string') {\n didChange = this.internalSet(keyOrState, value as any);\n } else {\n // eslint-disable-next-line\n for (const key in keyOrState) {\n if (this.internalSet(key, keyOrState[key] as any)) {\n didChange = true;\n }\n }\n }\n\n if (didChange) {\n (this.ee as any).emit('change');\n }\n }\n\n /**\n * Returns value by specified key.\n * @param key - state key.\n */\n get<K extends StringKeys<S>>(key: K): S[K] {\n return this.state[key];\n }\n}\n","import { on } from '~/bridge/index.js';\nimport { isColorDark, type RGB } from '~/colors/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\n\nimport { parseThemeParams } from './parseThemeParams.js';\nimport type {\n ThemeParamsEvents,\n ThemeParamsParsed,\n ThemeParamsState,\n} from './types.js';\n\nexport class ThemeParams {\n private readonly ee = new EventEmitter<ThemeParamsEvents>();\n\n private readonly state: State<ThemeParamsState>;\n\n constructor(params: ThemeParamsParsed) {\n this.state = new State(params, this.ee);\n }\n\n /**\n * @since v6.10\n */\n get accentTextColor(): RGB | undefined {\n return this.get('accentTextColor');\n }\n\n get backgroundColor(): RGB | undefined {\n return this.get('backgroundColor');\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 * Retrieves palette color value by its name.\n * @param key - palette key name.\n */\n get(key: Extract<keyof ThemeParamsParsed, string>): RGB | undefined {\n return this.state.get(key);\n }\n\n /**\n * Returns the copy of the internal state of the current component instance.\n */\n getState(): ThemeParamsParsed {\n return this.state.clone();\n }\n\n /**\n * @since v6.10\n */\n get headerBackgroundColor(): RGB | undefined {\n return this.get('headerBackgroundColor');\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 background color.\n */\n get isDark(): boolean {\n return !this.backgroundColor || isColorDark(this.backgroundColor);\n }\n\n get linkColor(): RGB | undefined {\n return this.get('linkColor');\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n\n get secondaryBackgroundColor(): RGB | undefined {\n return this.get('secondaryBackgroundColor');\n }\n\n /**\n * @since v6.10\n */\n get sectionBackgroundColor(): RGB | undefined {\n return this.get('sectionBackgroundColor');\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 theme changes and applies them.\n * @returns Function to stop listening.\n */\n listen() {\n return on('theme_changed', (event) => {\n this.state.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 { initDataParser } from '~/init-data/index.js';\nimport { boolean, searchParams, string } from '~/parsing/index.js';\nimport { themeParamsParser } from '~/theme-params/index.js';\n\nimport type { LaunchParams } from './types.js';\n\n/**\n * Returns parser used to parse launch params.\n */\nexport function launchParamsParser() {\n return searchParams<LaunchParams>({\n botInline: {\n type: boolean().optional(),\n from: 'tgWebAppBotInline',\n },\n initData: {\n type: initDataParser().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 themeParams: {\n type: themeParamsParser(),\n from: 'tgWebAppThemeParams',\n },\n version: {\n type: string(),\n from: 'tgWebAppVersion',\n },\n }, 'LaunchParams');\n}\n","import { launchParamsParser } from './launchParamsParser.js';\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 launchParamsParser().parse(value);\n}\n","import { parseLaunchParams } from './parseLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * Attempts to extract launch parameters from the current window location hash.\n * @throws {Error} window.location.hash contains invalid data.\n */\nexport function retrieveFromLocation(): LaunchParams {\n return parseLaunchParams(window.location.hash.slice(1));\n}\n","import { getFirstNavigationEntry } from './getFirstNavigationEntry.js';\nimport { parseLaunchParams } from './parseLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * Attempts to read launch parameters using window.performance data.\n * @throws {Error} Unable to get first navigation entry.\n * @throws {Error} First navigation entry does not contain hash part.\n * @throws {TypeError} Unable to parse value.\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 const hashMatch = navigationEntry.name.match(/#(.*)/);\n if (!hashMatch) {\n throw new Error('First navigation entry does not contain hash part.');\n }\n\n return parseLaunchParams(hashMatch[1]);\n}\n","import { retrieveFromLocation } from './retrieveFromLocation.js';\nimport { retrieveFromPerformance } from './retrieveFromPerformance.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * Attempts to retrieve launch parameters using every known way.\n */\nexport function retrieveCurrent(): LaunchParams | null {\n // First of all, attempt to retrieve launch parameters from the window.performance as long as\n // this way is considered the most stable. Nevertheless, this method can return nothing in case,\n // location was changed and then page was reloaded.\n try {\n return retrieveFromPerformance();\n // eslint-disable-next-line no-empty\n } catch (e) {\n }\n\n // In case, usage of window.performance was unsuccessful, try to retrieve launch parameters\n // from the window.location.\n try {\n return retrieveFromLocation();\n // eslint-disable-next-line no-empty\n } catch (e) {\n }\n\n return null;\n}\n","import { serializeThemeParams } from '~/theme-params/index.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 botInline,\n } = value;\n\n const params = new URLSearchParams();\n\n if (initDataRaw) {\n params.set('tgWebAppData', initDataRaw);\n }\n params.set('tgWebAppPlatform', platform);\n params.set('tgWebAppThemeParams', serializeThemeParams(themeParams));\n params.set('tgWebAppVersion', version);\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 { launchParamsParser } from '~/launch-params/launchParamsParser.js';\n\nimport { serializeLaunchParams } from './serializeLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\nconst SESSION_STORAGE_KEY = 'telegram-mini-apps-launch-params';\n\n/**\n * Attempts to extract launch parameters directly from the session storage.\n * @returns Launch parameters in case, they were stored before or null, if there is no launch\n * parameters key in the session storage.\n * @throws {Error} Data stored in the session storage is invalid.\n */\nexport function retrieveFromStorage(): LaunchParams | null {\n const raw = sessionStorage.getItem(SESSION_STORAGE_KEY);\n\n return raw\n // We are not handling the error on purpose as long as we are waiting for data stored by\n // this session storage key to contain the valid launch parameters.\n ? launchParamsParser().parse(raw)\n : null;\n}\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 // TODO: We probably don't need serialize here. We used it only to correctly serialize Date\n // values which being converted strings. To solve the problem we could improve date parser\n // to allows parsing such invalid (Dates, converted to strings) values.\n sessionStorage.setItem(SESSION_STORAGE_KEY, serializeLaunchParams(value));\n}\n","import { computePageReload } from './computePageReload.js';\nimport { retrieveCurrent } from './retrieveCurrent.js';\nimport { retrieveFromStorage } from './storage.js';\nimport type { LaunchData } from './types.js';\n\n/**\n * Returns true in case, current environment is iframe.\n * @see https://stackoverflow.com/a/326076\n */\nfunction isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n\n/**\n * Computes launch data information. Extracts both previous and current launch parameters\n * to compute current list of them. Additionally, computes if page was reloaded.\n */\nexport function computeLaunchData(): LaunchData {\n // Retrieve launch parameters from the session storage. We consider this value as the launch\n // parameters saved previously, in the previous runtime session (before the page reload).\n const lpPrevious = retrieveFromStorage();\n\n // Currently used launch parameters passed to the Mini App.\n const lpCurrent = retrieveCurrent();\n\n const isPageReload = computePageReload();\n\n if (lpPrevious) {\n if (lpCurrent) {\n return {\n launchParams: lpCurrent,\n isPageReload: isIframe()\n // In iframes we should check page reload via 2 ways:\n // 1. Native one via navigation entry.\n // 2. By comparing raw init data representations, when the first step did not return\n // explicit true.\n //\n // The reason is Telegram provides the horrible way of reloading current iframes which\n // does not guarantee, that reload will be proceeded properly.\n // Issue: https://github.com/morethanwords/tweb/issues/271\n //\n // We trust isPageReload variable value only in case it is \"true\". Otherwise, it can be\n // wrong. That's why we compare raw init data raw representations, which is unstable\n // also. This will not work as expected in cases, user launches applications via\n // KeyboardButton-s which can lack of init data. So, this code will not differ reload\n // from the fresh start.\n ? isPageReload || lpPrevious.initDataRaw === lpCurrent.initDataRaw\n\n // In environments different from iframe, when we have both previous and current launch\n // parameters it is guaranteed that page was reloaded as long as session is created only\n // for the Mini App launch and will be automatically disposed after it is closed.\n : true,\n };\n }\n\n // Explicit page reload allows us to trust previously saved launch parameters.\n if (isPageReload) {\n return {\n launchParams: lpPrevious,\n isPageReload,\n };\n }\n\n // We can't trust previously saved launch parameters as long as we don't really know if\n // current session was born due to restart. It is better to throw an error.\n throw new Error('Unable to retrieve current launch parameters, which must exist.');\n }\n\n if (lpCurrent) {\n return {\n launchParams: lpCurrent,\n isPageReload: false,\n };\n }\n\n throw new Error('Unable to retrieve any launch parameters.');\n}\n","import { computeLaunchData } from './computeLaunchData.js';\nimport { saveToStorage } from './storage.js';\nimport type { LaunchData } from './types.js';\n\nconst WINDOW_KEY = 'tmajsLaunchData';\n\n/**\n * Returns launch data information. Function ignores passed options in case, it was already\n * called. It caches the last returned value.\n */\nexport function retrieveLaunchData(): LaunchData {\n // Return previously cached value.\n const cached = (window as any)[WINDOW_KEY];\n if (cached) {\n return cached;\n }\n\n // Get current launch data.\n const launchData = computeLaunchData();\n\n // To prevent the additional computation of launch data and possible break of the code\n // logic, we store this data in the window. Several calls of retrieveLaunchData will surely\n // break something.\n (window as any)[WINDOW_KEY] = launchData;\n\n // Save launch parameters in the session storage. We will need them during page reloads.\n saveToStorage(launchData.launchParams);\n\n return launchData;\n}\n","import { retrieveLaunchData } from '~/launch-params/index.js';\n\n/**\n * Returns true in case, current environment is Telegram Mini Apps.\n */\nexport function isTMA(): boolean {\n try {\n retrieveLaunchData();\n return true;\n } catch (e) {\n return false;\n }\n}\n","import { isRecord } from '~/misc/index.js';\n\ntype WithExternalNotify<T> = T & {\n external: {\n notify: (...args: any) => any;\n };\n};\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 {}>(value: T): value is WithExternalNotify<T> {\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/index.js';\n\ntype WithWebviewProxy<T> = T & {\n TelegramWebviewProxy: {\n postEvent: (...args: any) => any;\n }\n};\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 WithWebviewProxy<T> {\n return 'TelegramWebviewProxy' in value\n && isRecord(value.TelegramWebviewProxy)\n && 'postEvent' in value.TelegramWebviewProxy\n && typeof value.TelegramWebviewProxy.postEvent === 'function';\n}\n","/**\n * Returns true in case, current environment is iframe.\n * @see https://stackoverflow.com/a/326076\n */\nexport function isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n","import type { Version } from '~/version/index.js';\n\nimport type { MiniAppsMethodName } from '../methods/index.js';\n\n/**\n * Error thrown in case, unsupported method was called.\n */\nexport class MethodUnsupportedError extends Error {\n constructor(method: MiniAppsMethodName, version: Version) {\n super(`Method \"${method}\" is unsupported in the Mini Apps version ${version}.`);\n Object.setPrototypeOf(this, MethodUnsupportedError.prototype);\n }\n}\n","import type { Version } from '~/version/index.js';\n\nimport type { MiniAppsMethodName } from '../methods/index.js';\n\n/**\n * Error thrown in case, unsupported parameter was used.\n */\nexport class ParameterUnsupportedError extends Error {\n constructor(method: MiniAppsMethodName, param: string, version: Version) {\n super(`Parameter \"${param}\" in method \"${method}\" is unsupported in the Mini Apps version ${version}.`);\n Object.setPrototypeOf(this, ParameterUnsupportedError.prototype);\n }\n}\n","/**\n * Message log level.\n */\nexport type LogLevel = 'log' | 'error' | 'warn';\n\nexport class Logger {\n constructor(private readonly prefix: string, private enabled: boolean) {\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 if (!this.enabled) {\n return;\n }\n\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 // eslint-disable-next-line no-console\n console[level](`[${date}]`, this.prefix, ...args);\n }\n\n /**\n * Disables the logger.\n */\n disable() {\n this.enabled = false;\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 * Enables the logger.\n */\n enable() {\n this.enabled = true;\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 /**\n * Prints warning message into a console.\n * @param args\n */\n warn(...args: any[]): void {\n this.print('warn', ...args);\n }\n}\n","import { Logger } from '~/logger/index.js';\n\nlet currentTargetOrigin = 'https://web.telegram.org';\n\nexport const logger = new Logger('[SDK]', false);\n\n/**\n * Sets new debug mode. Enabling debug mode leads to printing\n * additional messages in console, related to the processes\n * inside the package.\n * @param value - should debug mode be enabled.\n */\nexport function setDebug(value: boolean): void {\n if (value) {\n logger.enable();\n return;\n }\n logger.disable();\n}\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 { json, string } from '~/parsing/index.js';\n\n/**\n * Extracts event data from native application event.\n */\nconst eventDataJson = json<{ eventType: string; eventData?: unknown }>({\n eventType: string(),\n eventData: (value) => value,\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 parent iframe.\n * @param eventType - event name.\n * @param eventData - event payload.\n */\nfunction emitEvent(eventType: string, eventData: unknown): void {\n window.dispatchEvent(new MessageEvent('message', {\n data: JSON.stringify({ eventType, eventData }),\n }));\n}\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 */\nfunction defineEventHandlers(): void {\n const wnd: any = window;\n\n // Prevent from duplicate event handlers definition.\n if ('TelegramGameProxy_receiveEvent' in wnd) {\n return;\n }\n\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 \"window\" object.\n let pointer = wnd;\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] = emitEvent;\n return;\n }\n\n if (!(item in pointer)) {\n pointer[item] = {};\n }\n pointer = pointer[item];\n });\n });\n}\n\n/**\n * Adds listener to window \"message\" event assuming, that this event could\n * be sent by Telegram native application. Calls passed callback with event\n * type and data.\n * @param cb - callback to call.\n */\nexport function onTelegramEvent(cb: (eventType: string, eventData: unknown) => void): void {\n // Define event handlers to make sure, message handler will work correctly.\n defineEventHandlers();\n\n // We expect Telegram to send us new event through \"message\" event.\n window.addEventListener('message', (event) => {\n try {\n const { eventType, eventData } = eventDataJson.parse(event.data);\n cb(eventType, eventData);\n } catch {\n // We ignore incorrect messages as they could be generated by any other code.\n }\n });\n}\n","import { json, string } from '~/parsing/index.js';\nimport type { RequestId } from '~/types/index.js';\n\nexport interface ClipboardTextReceivedPayload {\n /**\n * Passed during the `web_app_read_text_from_clipboard` method invocation `req_id` value.\n */\n req_id: RequestId;\n\n /**\n * Data extracted from the clipboard. The returned value will have the type `string` only in\n * the case, application has access to the clipboard.\n */\n data?: string | null;\n}\n\nexport function clipboardTextReceived() {\n return json<ClipboardTextReceivedPayload>({\n req_id: string(),\n data: (value) => (\n value === null\n ? value\n : string().optional().parse(value)\n ),\n });\n}\n","import { json, string } from '~/parsing/index.js';\nimport type { RequestId } from '~/types/index.js';\n\nexport interface CustomMethodInvokedPayload<R = unknown> {\n /**\n * Unique identifier of this invocation.\n */\n req_id: RequestId;\n /**\n * Method invocation successful result.\n */\n result?: R;\n /**\n * Method invocation error code.\n */\n error?: string;\n}\n\nexport function customMethodInvoked() {\n return json<CustomMethodInvokedPayload>({\n req_id: string(),\n result: (value) => value,\n error: string().optional(),\n });\n}\n","import { json, string } from '~/parsing/index.js';\n\nexport type InvoiceStatus =\n | 'paid'\n | 'failed'\n | 'pending'\n | 'cancelled'\n | string;\n\nexport interface InvoiceClosedPayload {\n /**\n * Passed during the `web_app_open_invoice` method invocation `slug` value.\n */\n slug: string;\n /**\n * Invoice status\n */\n status: InvoiceStatus;\n}\n\nexport function invoiceClosed() {\n return json<InvoiceClosedPayload>({\n slug: string(),\n status: string(),\n });\n}\n","import { json, string } from '~/parsing/index.js';\n\nexport type PhoneRequestedStatus = 'sent' | 'cancelled' | string;\n\nexport interface PhoneRequestedPayload {\n /**\n * Request status.\n */\n status: PhoneRequestedStatus;\n}\n\nexport function phoneRequested() {\n return json<PhoneRequestedPayload>({ status: string() });\n}\n","import { json, string } from '~/parsing/index.js';\n\nexport interface PopupClosedPayload {\n /**\n * Identifier of the clicked button. In case, the popup was closed without clicking any button,\n * this property will be omitted.\n */\n button_id?: string;\n}\n\nexport function popupClosed() {\n return json<PopupClosedPayload>({\n button_id: (value) => (\n value === null || value === undefined\n ? undefined\n : string().parse(value)\n ),\n });\n}\n","import { json, string } from '~/parsing/index.js';\n\nexport interface QrTextReceivedPayload {\n /**\n * Data extracted from the QR.\n */\n data?: string;\n}\n\nexport function qrTextReceived() {\n return json<QrTextReceivedPayload>({\n data: string().optional(),\n });\n}\n","import { json, rgb, toRecord } from '~/parsing/index.js';\nimport type { RGB } from '~/colors/index.js';\n\nexport interface ThemeChangedPayload {\n /**\n * Map where the key is a theme stylesheet key and value is the corresponding color in\n * `#RRGGBB` format.\n */\n theme_params: {\n /**\n * @since v6.10\n */\n accent_text_color?: RGB;\n bg_color?: RGB;\n button_color?: RGB;\n button_text_color?: RGB;\n /**\n * @since v6.10\n */\n destructive_text_color?: RGB;\n /**\n * @since v6.10\n */\n header_bg_color?: RGB;\n hint_color?: RGB;\n link_color?: RGB;\n secondary_bg_color?: RGB;\n /**\n * @since v6.10\n */\n section_bg_color?: RGB;\n /**\n * @since v6.10\n */\n section_header_text_color?: RGB;\n /**\n * @since v6.10\n */\n subtitle_text_color?: RGB;\n text_color?: RGB;\n [key: string]: RGB | undefined; // Future unknown palette keys.\n };\n}\n\nexport function themeChanged() {\n return json<ThemeChangedPayload>({\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}\n","import { boolean, json, number } from '~/parsing/index.js';\n\nexport interface ViewportChangedPayload {\n /**\n * The viewport height.\n */\n height: number;\n /**\n * The viewport width.\n */\n width: number;\n /**\n * Is the viewport currently expanded.\n */\n is_expanded: boolean;\n /**\n * Is the viewport current state stable and not going to change in the next moment.\n */\n is_state_stable: boolean;\n}\n\nexport function viewportChanged() {\n return json<ViewportChangedPayload>({\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}\n","import { json, string } from '~/parsing/index.js';\n\nexport type WriteAccessRequestedStatus = 'allowed' | string;\n\nexport interface WriteAccessRequestedPayload {\n /**\n * Request status.\n */\n status: WriteAccessRequestedStatus;\n}\n\nexport function writeAccessRequested() {\n return json<WriteAccessRequestedPayload>({ status: string() });\n}\n","import { EventEmitter } from '~/event-emitter/index.js';\nimport { logger } from '~/globals.js';\nimport { string } from '~/parsing/index.js';\n\nimport type { MiniAppsEventEmitter, MiniAppsEventName } from './events.js';\nimport { onTelegramEvent } from './onTelegramEvent.js';\nimport {\n clipboardTextReceived,\n customMethodInvoked,\n invoiceClosed,\n phoneRequested,\n popupClosed,\n qrTextReceived,\n themeChanged,\n viewportChanged,\n writeAccessRequested,\n} from './parsers/index.js';\n\n/**\n * Returns event emitter which could be safely used, to process events from\n * Telegram native application.\n */\nexport function createEmitter(): MiniAppsEventEmitter {\n const emitter: MiniAppsEventEmitter = new EventEmitter();\n const emit: MiniAppsEventEmitter['emit'] = (event: any, ...data: any[]) => {\n logger.log('Emitting processed event:', event, ...data);\n emitter.emit(event, ...data);\n };\n\n // Desktop version of Telegram is sometimes not sending the viewport_changed\n // event. For example, when main button 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 window.addEventListener('resize', () => {\n emit('viewport_changed', {\n width: window.innerWidth,\n height: window.innerHeight,\n is_state_stable: true,\n is_expanded: true,\n });\n });\n\n // In case, any Telegram event was received, we should prepare data before\n // passing it to emitter.\n onTelegramEvent((eventType: MiniAppsEventName | string, eventData): void => {\n logger.log('Received raw event:', eventType, eventData);\n\n try {\n switch (eventType) {\n case 'viewport_changed':\n return emit(eventType, viewportChanged().parse(eventData));\n\n case 'theme_changed':\n return emit(eventType, themeChanged().parse(eventData));\n\n case 'popup_closed':\n // FIXME: Payloads are different on different platforms.\n // Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/2\n if (\n // Sent on desktop.\n eventData === undefined\n // Sent on iOS.\n || eventData === null\n ) {\n return emit(eventType, {});\n }\n return emit(eventType, popupClosed().parse(eventData));\n\n case 'set_custom_style':\n return emit(eventType, string().parse(eventData));\n\n case 'qr_text_received':\n return emit(eventType, qrTextReceived().parse(eventData));\n\n case 'clipboard_text_received':\n return emit(eventType, clipboardTextReceived().parse(eventData));\n\n case 'invoice_closed':\n return emit(eventType, invoiceClosed().parse(eventData));\n\n case 'phone_requested':\n return emit('phone_requested', phoneRequested().parse(eventData));\n\n case 'custom_method_invoked':\n return emit('custom_method_invoked', customMethodInvoked().parse(eventData));\n\n case 'write_access_requested':\n return emit('write_access_requested', writeAccessRequested().parse(eventData));\n\n // Events which have no parameters.\n case 'main_button_pressed':\n case 'back_button_pressed':\n case 'settings_button_pressed':\n case 'scan_qr_popup_closed':\n case 'reload_iframe':\n return emit(eventType);\n\n // All other event listeners will receive unknown type of data.\n default:\n return emit(eventType as any, eventData);\n }\n } catch (cause) {\n logger.error('Error processing event:', cause);\n }\n });\n\n return emitter;\n}\n","import { createEmitter } from '~/bridge/events/createEmitter.js';\nimport type { MiniAppsEventEmitter } from '~/bridge/index.js';\n\nconst CACHED_EMITTER = 'telegram-mini-apps-cached-emitter';\n\n/**\n * Returns singleton instance of bridge EventEmitter. Also, defines\n * Telegram event handlers.\n */\nexport function singletonEmitter(): MiniAppsEventEmitter {\n const wnd: any = window;\n const cachedEmitter = wnd[CACHED_EMITTER];\n\n if (cachedEmitter === undefined) {\n wnd[CACHED_EMITTER] = createEmitter();\n }\n\n return wnd[CACHED_EMITTER];\n}\n","import type { MiniAppsEventListener, MiniAppsEventName } from './events.js';\nimport { singletonEmitter } from './singletonEmitter.js';\n\n/**\n * Removes listener from specified event.\n * @param event - event to listen.\n * @param listener - event listener.\n */\nexport function off<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n): void {\n singletonEmitter().off(event, listener);\n}\n","import type { MiniAppsEventListener, MiniAppsEventName } from './events.js';\nimport { off } from './off.js';\nimport { singletonEmitter } from './singletonEmitter.js';\n\ntype StopListening = () => void;\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 */\nexport function on<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n): StopListening {\n singletonEmitter().on(event, listener);\n return () => off(event, listener);\n}\n","import type { MiniAppsEventListener, MiniAppsEventName } from './events.js';\nimport { off } from './off.js';\nimport { singletonEmitter } from './singletonEmitter.js';\n\ntype StopListening = () => void;\n\n/**\n * Works the same as \"on\" method, but after catching the event, will remove event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function once<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n): StopListening {\n singletonEmitter().once(event, listener);\n return () => off(event, listener);\n}\n","import type { MiniAppsGlobalEventListener } from './events.js';\nimport { singletonEmitter } from './singletonEmitter.js';\n\n/**\n * Removes global event listener.\n * @param listener - event listener.\n */\nexport function unsubscribe(listener: MiniAppsGlobalEventListener): void {\n singletonEmitter().unsubscribe(listener);\n}\n","import type { MiniAppsGlobalEventListener } from './events.js';\nimport { singletonEmitter } from './singletonEmitter.js';\nimport { unsubscribe } from './unsubscribe.js';\n\ntype StopListening = () => void;\n\n/**\n * Subscribes to all events sent from the native Telegram application.\n * Returns function used to remove added event listener.\n * @param listener - event listener.\n */\nexport function subscribe(listener: MiniAppsGlobalEventListener): StopListening {\n singletonEmitter().subscribe(listener);\n return () => unsubscribe(listener);\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: string, b: string): 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 {\n compareVersions,\n type Version,\n} from '~/version/index.js';\nimport type {\n MiniAppsMethodName,\n MiniAppsMethodVersionedParams,\n MiniAppsMethodWithVersionedParams,\n} from '~/bridge/methods/index.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 default:\n return true;\n }\n}\n","import type { MiniAppsMethodName } from '~/bridge/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport { supports } from './supports.js';\nimport type { SupportsFunc } from './types.js';\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 createSupportsFunc<M extends string>(\n version: Version,\n schema: Record<M, MiniAppsMethodName>,\n): SupportsFunc<M> {\n return (method) => supports(schema[method], version);\n}\n","import type { MiniAppsMethodVersionedParams, MiniAppsMethodWithVersionedParams } from '~/bridge/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport { supports } from './supports.js';\nimport type { SupportsFunc } from './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 createSupportsParamFunc<P extends string>(\n version: Version,\n schema: Record<P, HasCheckSupportMethodTuple>,\n): SupportsFunc<P> {\n return (method) => {\n const [tmaMethod, param] = schema[method];\n\n return supports(tmaMethod, param, version);\n };\n}\n","import type {\n MiniAppsEmptyMethodName,\n MiniAppsMethodName,\n MiniAppsMethodParams,\n MiniAppsNonEmptyMethodName,\n} from './methods.js';\nimport { logger, targetOrigin as globalTargetOrigin } from '../../globals.js';\nimport {\n hasExternalNotify,\n hasWebviewProxy,\n isIframe,\n} from '../env/index.js';\n\ninterface PostEventOptions {\n /**\n * Origin used while posting message. This option is only used in case,\n * current environment is browser (Web version of Telegram) and could\n * 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 * Sends event to native application which launched Mini App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param params - event parameters.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current environment and possible way to send event.\n */\nexport function postEvent<E extends MiniAppsNonEmptyMethodName>(\n eventType: E,\n params: MiniAppsMethodParams<E>,\n options?: PostEventOptions,\n): void;\n\n/**\n * Sends event to native application which launched Mini App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current environment and possible way to send event.\n */\nexport function postEvent(eventType: MiniAppsEmptyMethodName, options?: PostEventOptions): 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 = globalTargetOrigin() } = postOptions;\n\n logger.log(`Calling method \"${eventType}\"`, eventData);\n\n // Telegram Web.\n if (isIframe()) {\n window.parent.postMessage(JSON.stringify({\n eventType,\n eventData,\n }), 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 new Error(\n 'Unable to determine current environment and possible way to send event.',\n );\n}\n","import { isRecord } from '~/misc/index.js';\nimport { supports } from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport { type PostEvent, postEvent } from './postEvent.js';\nimport { MethodUnsupportedError, ParameterUnsupportedError } from '../errors/index.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 {MethodUnsupportedError} Method is unsupported.\n * @throws {ParameterUnsupportedError} Method parameter is 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 new MethodUnsupportedError(method, 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 new ParameterUnsupportedError(method, validateParam, version);\n }\n }\n\n return postEvent(method, params);\n };\n}\n","export class TimeoutError extends Error {\n constructor(timeout: number) {\n super(`Async call timeout exceeded. Timeout: ${timeout}`);\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n","import { TimeoutError } from './TimeoutError.js';\n\n/**\n * Returns true in case, passed value is TimeoutError.\n * @param value - checked value.\n */\nexport function isTimeoutError(value: unknown): value is TimeoutError {\n return value instanceof TimeoutError;\n}\n","/**\n * Awaits for specified amount of time.\n * @param duration - duration to await.\n */\nexport function sleep(duration: number): Promise<void> {\n // eslint-disable-next-line no-await-in-loop,@typescript-eslint/no-loop-func\n return new Promise((res) => {\n setTimeout(res, duration);\n });\n}\n","import { TimeoutError } from './TimeoutError.js';\n\n/**\n * Creates promise which rejects after timeout milliseconds.\n * @param timeout - timeout in milliseconds.\n */\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, rej) => {\n setTimeout(rej, timeout, new TimeoutError(timeout));\n });\n}\n\n/**\n * Accepts specified function and instantly executes. It waits for timeout milliseconds for\n * it to complete and throws an error in case, deadline was reached.\n * @param func - function to execute.\n * @param timeout - completion timeout.\n */\nexport function withTimeout<T>(func: () => Promise<T>, timeout: number): Promise<T> {\n return Promise.race([\n func(),\n createTimeoutPromise(timeout),\n ]);\n}\n","import { isRecord } from '~/misc/index.js';\nimport { withTimeout } from '~/timeout/index.js';\nimport type { And, ExecuteWithOptions, If, IsNever } from '~/types/index.js';\n\nimport {\n type MiniAppsEventHasParams,\n type MiniAppsEventName,\n type MiniAppsEventParams,\n on,\n} from './events/index.js';\nimport {\n type MiniAppsEmptyMethodName,\n type MiniAppsMethodAcceptParams,\n type MiniAppsMethodName,\n type MiniAppsMethodParams,\n type MiniAppsNonEmptyMethodName,\n postEvent as defaultPostEvent,\n} from './methods/index.js';\n\n/**\n * Names of methods, which require passing \"req_id\" parameter.\n */\ntype MethodWithRequestId = {\n [M in MiniAppsMethodName]: If<\n And<\n MiniAppsMethodAcceptParams<M>,\n MiniAppsMethodParams<M> extends { req_id: string } ? true : false\n >,\n M,\n never\n >;\n}[MiniAppsMethodName];\n\n/**\n * Names of events, which contain \"req_id\" parameter.\n */\ntype EventWithRequestId = {\n [E in MiniAppsEventName]: If<\n And<MiniAppsEventHasParams<E>, MiniAppsEventParams<E> extends {\n req_id: string\n } ? true : false>,\n E,\n never\n >;\n}[MiniAppsEventName];\n\nexport interface RequestOptions extends ExecuteWithOptions {\n}\n\nexport interface RequestOptionsAdvanced<EventPayload> extends RequestOptions {\n /**\n * Should return true in case, this event should be captured. If not specified,\n * request is not skipping captured events.\n */\n capture?: If<IsNever<EventPayload>, () => boolean, (payload: EventPayload) => boolean>;\n}\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, event with specified in method request identifier\n * was captured.\n * @param method - method to execute.\n * @param params - method parameters.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<M extends MethodWithRequestId, E extends EventWithRequestId>(\n method: M,\n params: MiniAppsMethodParams<M>,\n event: E | E[],\n options?: RequestOptions,\n): Promise<MiniAppsEventParams<E>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<M extends MiniAppsEmptyMethodName, E extends MiniAppsEventName>(\n method: M,\n event: E | E[],\n options?: RequestOptionsAdvanced<MiniAppsEventParams<E>>,\n): Promise<MiniAppsEventParams<E>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute\n * @param params - method parameters.\n * @param event - event or events to listen\n * @param options - additional execution options.\n */\nexport function request<M extends MiniAppsNonEmptyMethodName, E extends MiniAppsEventName>(\n method: M,\n params: MiniAppsMethodParams<M>,\n event: E | E[],\n options?: RequestOptionsAdvanced<MiniAppsEventParams<E>>,\n): Promise<MiniAppsEventParams<E>>;\n\nexport function request(\n method: MiniAppsMethodName,\n eventOrParams: MiniAppsEventName | MiniAppsEventName[] | MiniAppsEventParams<any>,\n eventOrOptions?:\n | MiniAppsEventName\n | MiniAppsEventName[]\n | RequestOptions\n | RequestOptionsAdvanced<any>,\n options?: RequestOptions | RequestOptionsAdvanced<any>,\n): Promise<any> {\n let executionOptions: RequestOptions | RequestOptionsAdvanced<any> | undefined;\n let methodParams: MiniAppsEventParams<any> | undefined;\n let events: MiniAppsEventName[];\n let requestId: string | undefined;\n\n if (typeof eventOrParams === 'string' || Array.isArray(eventOrParams)) {\n // Override: [method, event, options?]\n events = Array.isArray(eventOrParams) ? eventOrParams : [eventOrParams] as MiniAppsEventName[];\n executionOptions = eventOrOptions as (RequestOptionsAdvanced<any> | undefined);\n } else {\n // Override: [method, params, event, options?]\n methodParams = eventOrParams as MiniAppsEventParams<any>;\n events = Array.isArray(eventOrOptions)\n ? eventOrOptions\n : [eventOrOptions] as MiniAppsEventName[];\n executionOptions = options;\n }\n\n // In case, method parameters were passed, and they contained request identifier, we should store\n // it and wait for the event with this identifier to occur.\n if (isRecord(methodParams) && typeof methodParams.req_id === 'string') {\n requestId = methodParams.req_id;\n }\n\n const { postEvent = defaultPostEvent, timeout } = executionOptions || {};\n const capture = executionOptions && 'capture' in executionOptions\n ? executionOptions.capture\n : null;\n\n const execute = () => {\n return new Promise((res, rej) => {\n // Iterate over each event and create event listener.\n const stoppers = events.map((ev) => on(ev, (data?) => {\n // If request identifier was specified, we are waiting for event with the same value\n // to occur.\n if (requestId && (!isRecord(data) || data.req_id !== requestId)) {\n return;\n }\n\n if (typeof capture === 'function' && !capture(data)) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n stopListening();\n res(data);\n }));\n\n // Function which removes all event listeners.\n const stopListening = () => stoppers.forEach((stop) => stop());\n\n try {\n // We are wrapping this call in try catch, because it can throw errors in case,\n // compatibility check was enabled. We want an error to be captured by promise, not by\n // another one external try catch.\n postEvent(method as any, methodParams);\n } catch (e) {\n stopListening();\n rej(e);\n }\n });\n };\n\n return typeof timeout === 'number' ? withTimeout(execute, timeout) : execute();\n}\n","import type { ExecuteWithOptions } from '~/types/index.js';\n\nimport type { CustomMethodName, CustomMethodParams } from './methods/index.js';\nimport { request } from './request.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 */\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 */\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 { result, error } = await request(\n 'web_app_invoke_custom_method',\n {\n method,\n params,\n req_id: requestId,\n },\n 'custom_method_invoked',\n options,\n );\n\n if (error) {\n throw new Error(error);\n }\n\n return result;\n}\n","import {\n off,\n on,\n type PostEvent,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport { createSupportsFunc, type SupportsFunc } from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport type { BackButtonEvents, BackButtonState } from './types.js';\n\ntype Emitter = EventEmitter<BackButtonEvents>;\n\n/**\n * Class which controls the back button displayed in the header of the Mini App in the Telegram\n * interface. It is mostly used in case, when you want to provide a way to go bach in routing\n * history or \"rollback\" some action.\n */\nexport class BackButton {\n private readonly ee: Emitter = new EventEmitter();\n\n private readonly state: State<BackButtonState>;\n\n constructor(\n isVisible: boolean,\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isVisible }, this.ee);\n this.supports = createSupportsFunc(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.state.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.state.get('isVisible');\n }\n\n /**\n * Hides the BackButton.\n */\n hide(): void {\n this.isVisible = false;\n }\n\n /**\n * Adds event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('back_button_pressed', listener)\n : this.ee.on(event, listener)\n );\n\n /**\n * Removes event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('back_button_pressed', listener)\n : this.ee.off(event, listener)\n );\n\n /**\n * Shows the BackButton.\n */\n show(): void {\n this.isVisible = true;\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'show' | 'hide'>;\n}\n","/**\n * Inserts a space between a and b in case both of them are\n * non-empty strings.\n * @param a\n * @param b\n */\nfunction space(a: string, b: string): string {\n return a + (a.length > 0 && b.length > 0 ? ` ${b}` : b);\n}\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. All other values are ignored.\n *\n * You can find this function to similar one from package {@link https://www.npmjs.com/package/classnames|classnames}.\n * @param values - values array.\n */\nexport function classNames(...values: any[]): string {\n return values.reduce<string>((acc, value) => {\n let formattedValue = '';\n\n if (typeof value === 'string') {\n formattedValue = value;\n } else if (typeof value === 'object' && value !== null) {\n formattedValue = Object\n .entries(value)\n .reduce<string>((valueAcc, [className, enable]) => (enable ? space(valueAcc, className) : valueAcc), '');\n }\n\n return space(acc, formattedValue);\n }, '');\n}\n","import { classNames } from './classNames.js';\n\ntype FilterUnion<U> = Exclude<U, number | string | null | undefined | any[] | boolean>;\n\n/**\n * Returns union keys removing those, which values are not strings.\n */\ntype UnionFilteredKeys<U> = U extends U\n ? {\n [K in keyof U]: U[K] extends string ? K : never\n }[keyof U]\n : never;\n\n/**\n * Returns union required keys.\n */\ntype UnionRequiredKeys<U> = U extends U\n ? {\n [K in UnionFilteredKeys<U>]-?: ({} extends { [P in K]: U[K] } ? never : K)\n }[UnionFilteredKeys<U>]\n : never;\n\n/**\n * Returns union optional keys.\n */\ntype UnionOptionalKeys<U> = Exclude<UnionFilteredKeys<U>, UnionRequiredKeys<U>>;\n\ntype MergeClassNames<Tuple extends any[]> = Tuple[number] extends infer Union\n ? FilterUnion<Union> extends infer UnionFiltered\n ? {\n [K in UnionRequiredKeys<UnionFiltered>]: string;\n } & {\n [K in UnionOptionalKeys<UnionFiltered>]?: string;\n }\n : never\n : never;\n\n/**\n * Returns true in case, passed value is Record.\n * @param value\n */\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(null);\n}\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 (!isObject(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 > 0) {\n (acc as any)[key] = className;\n }\n });\n\n return acc;\n }, {} as MergeClassNames<T>);\n}\n","import { type PostEvent, postEvent as defaultPostEvent } from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\n\nimport type {\n ClosingBehaviorEvents,\n ClosingBehaviorState,\n} from './types.js';\n\n/**\n * Component responsible for controlling current closing confirmation\n * status.\n */\nexport class ClosingBehavior {\n private readonly ee = new EventEmitter<ClosingBehaviorEvents>();\n\n private readonly state: State<ClosingBehaviorState>;\n\n constructor(\n isConfirmationNeeded: boolean,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isConfirmationNeeded }, this.ee);\n }\n\n private set isConfirmationNeeded(value: boolean) {\n this.state.set('isConfirmationNeeded', value);\n this.postEvent('web_app_setup_closing_behavior', { need_confirmation: value });\n }\n\n /**\n * Returns true, if the confirmation dialog enabled while the user is trying\n * to close the Mini App.\n */\n get isConfirmationNeeded(): boolean {\n return this.state.get('isConfirmationNeeded');\n }\n\n /**\n * Disables the confirmation dialog while the user is trying to close the\n * Mini App.\n */\n disableConfirmation(): void {\n this.isConfirmationNeeded = false;\n }\n\n /**\n * Enables the confirmation dialog while the user is trying to close the\n * Mini App.\n */\n enableConfirmation(): void {\n this.isConfirmationNeeded = true;\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n}\n","import {\n invokeCustomMethod,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport {\n array,\n json,\n string,\n} from '~/parsing/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { CreateRequestIdFunc, ExecuteWithTimeout } from '~/types/index.js';\nimport type { Version } from '~/version/index.js';\n\nfunction objectFromKeys<K extends string, V>(keys: K[], value: V): Record<K, V> {\n return keys.reduce<Record<K, V>>((acc, key) => {\n acc[key] = value;\n return acc;\n }, {} as Record<K, V>);\n}\n\nexport class CloudStorage {\n constructor(\n version: Version,\n private readonly createRequestId: CreateRequestIdFunc,\n private readonly postEvent = defaultPostEvent,\n ) {\n this.supports = createSupportsFunc(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 === 0) {\n return;\n }\n\n await invokeCustomMethod(\n 'deleteStorageValues',\n { keys },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\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 const result = await invokeCustomMethod(\n 'getStorageKeys',\n {},\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n );\n\n return array().of(string()).parse(result);\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>(\n keys: K[],\n options?: ExecuteWithTimeout,\n ): 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 === 0) {\n return objectFromKeys<string, string>(keys, '');\n }\n\n const schema = json(\n objectFromKeys(keys, string()),\n );\n const result = await invokeCustomMethod(\n 'getStorageValues',\n { keys },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n ).then((data) => schema.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 /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<\n | 'delete'\n | 'get'\n | 'getKeys'\n | 'set'\n >;\n}\n","import {\n type ImpactHapticFeedbackStyle,\n type NotificationHapticFeedbackType,\n type PostEvent,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\n/**\n * Class which controls haptic feedback. It allows calling different types of\n * haptic notifications which usually occur after user interaction with\n * application.\n */\nexport class HapticFeedback {\n constructor(\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.supports = createSupportsFunc(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 /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'impactOccurred' | 'notificationOccurred' | 'selectionChanged'>;\n}\n","import { on } from '~/bridge/index.js';\n\n/**\n * Creates style html element which contains styles sent from the Telegram application.\n */\nexport function catchCustomStyles(): void {\n const element = document.createElement('style');\n element.id = 'telegram-custom-styles';\n document.head.appendChild(element);\n\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 element.innerHTML = html;\n });\n}\n","import type { HeaderColorKey } from '~/bridge/index.js';\nimport type { RGB } from '~/colors/index.js';\n\n// fixme: components-related. Should probably rename\n\n/**\n * Describes storage keys and according values.\n */\ninterface StorageParams {\n 'back-button': {\n isVisible: boolean\n };\n 'closing-behavior': {\n isConfirmationNeeded: boolean;\n };\n 'main-button': {\n backgroundColor: RGB;\n isEnabled: boolean;\n isLoaderVisible: boolean;\n isVisible: boolean;\n text: string;\n textColor: RGB;\n };\n 'settings-button': {\n isVisible: boolean\n };\n viewport: {\n height: number;\n isExpanded: boolean;\n stableHeight: number;\n width: number;\n };\n 'mini-app': {\n backgroundColor: RGB;\n headerColor: HeaderColorKey | RGB;\n };\n}\n\n/**\n * Key which could be used to store data in storage.\n */\ntype StorageKey = keyof StorageParams;\n\n/**\n * Formats key which could be used during the communication with the storage.\n * @param key - session storage key.\n */\nfunction formatKey(key: StorageKey): string {\n return `telegram-mini-apps-${key}`;\n}\n\n/**\n * Saves value in sessionStorage.\n * @param key - storage key.\n * @param value - storage value.\n */\nexport function saveStorageValue<K extends StorageKey>(key: K, value: StorageParams[K]): void {\n sessionStorage.setItem(formatKey(key), JSON.stringify(value));\n}\n\n/**\n * Extracts value from the sessionStorage.\n * @param key - storage key.\n */\nexport function getStorageValue<K extends StorageKey>(key: K): StorageParams[K] | null {\n const value = sessionStorage.getItem(formatKey(key));\n\n return value ? JSON.parse(value) : null;\n}\n","import { BackButton } from '~/back-button/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\n\n/**\n * Creates BackButton instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param version - platform version.\n * @param postEvent - Bridge postEvent function\n */\nexport function createBackButton(\n isPageReload: boolean,\n version: string,\n postEvent: PostEvent,\n): BackButton {\n const { isVisible = false } = isPageReload ? getStorageValue('back-button') || {} : {};\n const component = new BackButton(isVisible, version, postEvent);\n\n component.on('change', () => {\n saveStorageValue('back-button', { isVisible: component.isVisible });\n });\n\n return component;\n}\n","import { ClosingBehavior } from '~/closing-behavior/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\n\n/**\n * Creates ClosingBehaviour instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param postEvent - Bridge postEvent function\n */\nexport function createClosingBehavior(\n isPageReload: boolean,\n postEvent: PostEvent,\n): ClosingBehavior {\n const { isConfirmationNeeded = false } = isPageReload ? getStorageValue('closing-behavior') || {} : {};\n\n const component = new ClosingBehavior(isConfirmationNeeded, postEvent);\n\n component.on('change', () => saveStorageValue('closing-behavior', {\n isConfirmationNeeded: component.isConfirmationNeeded,\n }));\n\n return component;\n}\n","import {\n off,\n on,\n type PostEvent,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport type { RGB } from '~/colors/index.js';\n\nimport type {\n MainButtonEvents,\n MainButtonParams,\n MainButtonProps,\n MainButtonState,\n} from './types.js';\n\ntype Emitter = EventEmitter<MainButtonEvents>;\n\n/**\n * Controls the main button, which is displayed at the bottom\n * of the Mini App in the Telegram interface.\n */\nexport class MainButton {\n private readonly ee: Emitter = new EventEmitter();\n\n private readonly state: State<MainButtonState>;\n\n private readonly postEvent: PostEvent;\n\n constructor(props: MainButtonProps) {\n const {\n postEvent = defaultPostEvent,\n text,\n textColor,\n backgroundColor,\n isEnabled,\n isVisible,\n isLoaderVisible,\n } = props;\n\n this.postEvent = postEvent;\n this.state = new State({\n backgroundColor,\n isEnabled,\n isVisible,\n isLoaderVisible,\n text,\n textColor,\n }, this.ee);\n }\n\n /**\n * Sends current local state to 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 behaviour 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.backgroundColor,\n text_color: this.textColor,\n });\n }\n\n private set isEnabled(isEnabled: boolean) {\n this.setParams({ isEnabled });\n }\n\n /**\n * True if the Main Button is currently enabled.\n */\n get isEnabled(): boolean {\n return this.state.get('isEnabled');\n }\n\n private set isLoaderVisible(isLoaderVisible: boolean) {\n this.setParams({ isLoaderVisible });\n }\n\n /**\n * True if the Main Button loader is currently visible.\n */\n get isLoaderVisible(): boolean {\n return this.state.get('isLoaderVisible');\n }\n\n private set isVisible(isVisible: boolean) {\n this.setParams({ isVisible });\n }\n\n /**\n * True if the Main Button is currently visible.\n */\n get isVisible(): boolean {\n return this.state.get('isVisible');\n }\n\n /**\n * The Main Button background color.\n */\n get backgroundColor(): RGB {\n return this.state.get('backgroundColor');\n }\n\n /**\n * The Main Button text.\n */\n get text(): string {\n return this.state.get('text');\n }\n\n /**\n * The Main Button text color.\n */\n get textColor(): RGB {\n return this.state.get('textColor');\n }\n\n /**\n * Disables the Main Button.\n */\n disable(): this {\n // FIXME: This method does not work on Android. Event \"main_button_pressed\"\n // keeps getting received even in case, button is disabled.\n // Issue: https://github.com/Telegram-Mini-Apps/documentation/issues/1\n this.isEnabled = false;\n return this;\n }\n\n /**\n * Enables the Main Button.\n */\n enable(): this {\n this.isEnabled = true;\n return this;\n }\n\n /**\n * Hides the Main Button.\n */\n hide(): this {\n this.isVisible = false;\n return this;\n }\n\n /**\n * Hides the Main Button loader.\n */\n hideLoader(): this {\n this.isLoaderVisible = false;\n return this;\n }\n\n /**\n * Adds new event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n on: Emitter['on'] = (event, listener) => (\n // FIXME: Event 'main_button_pressed' is still being received on Android\n // even if the main button is disabled.\n // Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/3\n event === 'click'\n ? on('main_button_pressed', listener)\n : this.ee.on(event, listener)\n );\n\n /**\n * Removes event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('main_button_pressed', listener)\n : this.ee.off(event, listener)\n );\n\n /**\n * Shows the Main Button. Note that opening the Mini App from the attachment menu hides the\n * main button until the user interacts with the Mini App interface.\n */\n show(): this {\n this.isVisible = true;\n return this;\n }\n\n /**\n * A method to show a loading indicator on the Main Button. It is recommended to display\n * loader if the action tied to the button may take a long time.\n */\n showLoader(): this {\n this.isLoaderVisible = true;\n return this;\n }\n\n /**\n * Sets new Main Button text. Minimal length for text is 1 symbol, and maximum is 64 symbols.\n * @param text - new text.\n */\n setText(text: string): this {\n return this.setParams({ text });\n }\n\n /**\n * Sets 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 backgroundColor - color to set.\n */\n setBackgroundColor(backgroundColor: RGB): this {\n return this.setParams({ backgroundColor });\n }\n\n /**\n * Allows setting multiple Main Button parameters.\n * @param params - Main Button parameters.\n */\n setParams(params: MainButtonParams): this {\n this.state.set(params);\n this.commit();\n return this;\n }\n}\n","import { MainButton } from '~/main-button/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\nimport type { RGB } from '~/colors/index.js';\n\n/**\n * Creates MainButton instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param backgroundColor - background color.\n * @param textColor - text color.\n * @param postEvent - Bridge postEvent function\n */\nexport function createMainButton(\n isPageReload: boolean,\n backgroundColor: RGB,\n textColor: RGB,\n postEvent: PostEvent,\n): MainButton {\n const {\n backgroundColor: stateBackgroundColor = backgroundColor,\n isEnabled = false,\n isVisible = false,\n isLoaderVisible = false,\n textColor: stateTextColor = textColor,\n text = '',\n } = isPageReload ? getStorageValue('main-button') || {} : {};\n\n const component = new MainButton({\n backgroundColor: stateBackgroundColor,\n isEnabled,\n isLoaderVisible,\n isVisible,\n postEvent,\n text,\n textColor: stateTextColor,\n });\n\n const saveState = () => saveStorageValue('main-button', {\n backgroundColor: component.backgroundColor,\n isEnabled: component.isEnabled,\n isLoaderVisible: component.isLoaderVisible,\n isVisible: component.isVisible,\n text: component.text,\n textColor: component.textColor,\n });\n\n component.on('change', saveState);\n\n return component;\n}\n","import { date, json, number, searchParams, string } from '~/parsing/index.js';\n\nimport type { RequestedContact } from './types.js';\n\nexport const contactParser = searchParams<RequestedContact>({\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(),\n from: 'last_name',\n },\n }),\n authDate: {\n type: date(),\n from: 'auth_date',\n },\n hash: string(),\n});\n","import {\n invokeCustomMethod,\n type PhoneRequestedStatus,\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n type SwitchInlineQueryChatType,\n type WriteAccessRequestedStatus,\n} from '~/bridge/index.js';\nimport {\n isColorDark,\n isRGB,\n type RGB,\n} from '~/colors/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport {\n createSupportsFunc,\n createSupportsParamFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport { sleep, withTimeout } from '~/timeout/index.js';\nimport type { CreateRequestIdFunc, ExecuteWithTimeout } from '~/types/index.js';\n\nimport { contactParser } from './contactParser.js';\nimport type {\n MiniAppEvents,\n MiniAppHeaderColor, MiniAppProps,\n MiniAppState, RequestedContact,\n} from './types.js';\n\n/**\n * Provides common Mini Apps functionality not covered by other system components.\n */\nexport class MiniApp {\n private readonly ee = new EventEmitter<MiniAppEvents>();\n\n private readonly state: State<MiniAppState>;\n\n private readonly botInline: boolean;\n\n private readonly postEvent: PostEvent;\n\n private readonly createRequestId: CreateRequestIdFunc;\n\n private requestingPhoneAccess = false;\n\n private requestingWriteAccess = false;\n\n constructor(props: MiniAppProps) {\n const {\n postEvent = defaultPostEvent,\n headerColor,\n backgroundColor,\n version,\n botInline,\n createRequestId,\n } = props;\n\n const isSupported = createSupportsFunc(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.postEvent = postEvent;\n this.botInline = botInline;\n this.createRequestId = createRequestId;\n this.supports = (method) => {\n if (!isSupported(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 if (method === 'switchInlineQuery' && !botInline) {\n return false;\n }\n return true;\n };\n\n this.state = new State({ backgroundColor, headerColor }, this.ee);\n this.supportsParam = createSupportsParamFunc(version, {\n 'setHeaderColor.color': ['web_app_set_header_color', 'color'],\n });\n }\n\n /**\n * Attempts to get requested contact.\n */\n private async getRequestedContact(): Promise<RequestedContact> {\n return invokeCustomMethod(\n 'getRequestedContact',\n {},\n this.createRequestId(),\n {\n postEvent: this.postEvent,\n timeout: 10000,\n },\n )\n .then((data) => contactParser.parse(data));\n }\n\n /**\n * The Mini App background color.\n */\n get backgroundColor(): RGB {\n return this.state.get('backgroundColor');\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. Could either be a header color key or RGB color.\n */\n get headerColor(): MiniAppHeaderColor {\n return this.state.get('headerColor');\n }\n\n /**\n * True if 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 recognized as dark.\n */\n get isDark(): boolean {\n return isColorDark(this.backgroundColor);\n }\n\n /**\n * True if phone access is currently being requested.\n */\n get isRequestingPhoneAccess(): boolean {\n return this.requestingPhoneAccess;\n }\n\n /**\n * True if write access is currently being requested.\n */\n get isRequestingWriteAccess(): boolean {\n return this.requestingWriteAccess;\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\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 (e) { /* 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 return withTimeout(async () => {\n // We are trying to retrieve the requested contact until deadline was reached.\n while (Date.now() < deadlineAt) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await this.getRequestedContact();\n } catch (e) { /* empty */\n }\n\n // Sleep for some time.\n // eslint-disable-next-line no-await-in-loop\n await sleep(sleepTime);\n\n // Increase the sleep time not to kill the backend service.\n sleepTime += 50;\n }\n\n throw new Error('Unable to retrieve requested contact.');\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 requestPhoneAccess(options: ExecuteWithTimeout = {}): Promise<PhoneRequestedStatus> {\n if (this.requestingPhoneAccess) {\n throw new Error('Phone access is already being requested.');\n }\n this.requestingPhoneAccess = true;\n\n return request('web_app_request_phone', 'phone_requested', {\n ...options,\n postEvent: this.postEvent,\n })\n .then((data) => data.status)\n .finally(() => {\n this.requestingPhoneAccess = false;\n });\n }\n\n /**\n * Requests write message access to current user.\n * @param options - additional options.\n */\n requestWriteAccess(options: ExecuteWithTimeout = {}): Promise<WriteAccessRequestedStatus> {\n if (this.requestingWriteAccess) {\n throw new Error('Write access is already being requested.');\n }\n this.requestingWriteAccess = true;\n\n return request('web_app_request_write_access', 'write_access_requested', {\n ...options,\n postEvent: this.postEvent,\n })\n .then((data) => data.status)\n .finally(() => {\n this.requestingWriteAccess = false;\n });\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 === 0 || 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 * @param color - color key or RGB color.\n */\n setHeaderColor(color: MiniAppHeaderColor): void {\n // FIXME: Has no effect on desktop, works incorrectly on Android.\n // Issues:\n // https://github.com/Telegram-Mini-Apps/tma.js/issues/9\n // https://github.com/Telegram-Mini-Apps/tma.js/issues/8\n this.postEvent('web_app_set_header_color', isRGB(color) ? { color } : { color_key: color });\n this.state.set('headerColor', color);\n }\n\n /**\n * Updates current Mini App background color.\n * @param color - RGB color.\n */\n setBackgroundColor(color: RGB): void {\n // FIXME: Has no effect on desktop, works incorrectly in Android.\n // Issues:\n // https://github.com/Telegram-Mini-Apps/tma.js/issues/9\n // https://github.com/Telegram-Mini-Apps/tma.js/issues/8\n this.postEvent('web_app_set_background_color', { color });\n this.state.set('backgroundColor', color);\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<\n | 'requestWriteAccess'\n | 'requestPhoneAccess'\n | 'switchInlineQuery'\n | 'setHeaderColor'\n | 'setBackgroundColor'\n >;\n\n /**\n * Checks if specified method parameter is supported by current component.\n */\n supportsParam: SupportsFunc<'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', {\n query: text,\n chat_types: chatTypes,\n });\n }\n}\n","import { MiniApp } from '~/mini-app/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\nimport type { RGB } from '~/colors/index.js';\nimport type { CreateRequestIdFunc } from '~/types/index.js';\nimport type { Version } from '~/version/index.js';\n\n/**\n * Creates MiniApp instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param backgroundColor - web app background color.\n * @param version - platform version.\n * @param botInline - is Mini App launched in inline mode.\n * @param createRequestId - function which generates request identifiers.\n * @param postEvent - Bridge postEvent function\n */\nexport function createMiniApp(\n isPageReload: boolean,\n backgroundColor: RGB,\n version: Version,\n botInline: boolean,\n createRequestId: CreateRequestIdFunc,\n postEvent: PostEvent,\n): MiniApp {\n const {\n backgroundColor: stateBackgroundColor = backgroundColor,\n headerColor = 'bg_color',\n } = isPageReload ? getStorageValue('mini-app') || {} : {};\n\n const component = new MiniApp({\n headerColor,\n backgroundColor: stateBackgroundColor,\n version,\n botInline,\n createRequestId,\n postEvent,\n });\n\n const saveState = () => saveStorageValue('mini-app', {\n backgroundColor: component.backgroundColor,\n headerColor: component.headerColor,\n });\n\n component.on('change', saveState);\n\n return component;\n}\n","import type { CreateRequestIdFunc } from '~/types/index.js';\n\n/**\n * Creates function which generated request identifiers.\n */\nexport function createRequestIdGenerator(): CreateRequestIdFunc {\n let requestId = 0;\n\n return () => {\n requestId += 1;\n return requestId.toString();\n };\n}\n","import {\n off,\n on,\n type PostEvent,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport { createSupportsFunc, type SupportsFunc } from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport type { SettingsButtonEvents, SettingsButtonState } from './types.js';\n\ntype Emitter = EventEmitter<SettingsButtonEvents>;\n\nexport class SettingsButton {\n private readonly ee: Emitter = new EventEmitter();\n\n private readonly state: State<SettingsButtonState>;\n\n constructor(\n isVisible: boolean,\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isVisible }, this.ee);\n this.supports = createSupportsFunc(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.state.set('isVisible', visible);\n this.postEvent('web_app_setup_settings_button', { is_visible: visible });\n }\n\n /**\n * True if SettingsButton is currently visible.\n */\n get isVisible(): boolean {\n return this.state.get('isVisible');\n }\n\n /**\n * Hides the SettingsButton.\n */\n hide(): void {\n this.isVisible = false;\n }\n\n /**\n * Adds event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('settings_button_pressed', listener)\n : this.ee.on(event, listener)\n );\n\n /**\n * Removes event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('settings_button_pressed', listener)\n : this.ee.off(event, listener)\n );\n\n /**\n * Shows the SettingsButton.\n */\n show(): void {\n this.isVisible = true;\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'show' | 'hide'>;\n}\n","import { SettingsButton } from '~/settings-button/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\n\n/**\n * Creates SettingsButton instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param version - platform version.\n * @param postEvent - Bridge postEvent function\n */\nexport function createSettingsButton(\n isPageReload: boolean,\n version: string,\n postEvent: PostEvent,\n): SettingsButton {\n const { isVisible = false } = isPageReload ? getStorageValue('settings-button') || {} : {};\n const component = new SettingsButton(isVisible, version, postEvent);\n\n component.on('change', () => {\n saveStorageValue('settings-button', { isVisible: component.isVisible });\n });\n\n return component;\n}\n","import { ThemeParams, type ThemeParamsParsed } from '~/theme-params/index.js';\n\n/**\n * Creates synced instance of ThemeParams.\n * @param params - theme parameters.\n */\nexport function createThemeParams(params: ThemeParamsParsed): ThemeParams {\n const themeParams = new ThemeParams(params);\n themeParams.listen();\n return themeParams;\n}\n","import { request, type RequestOptions } from '~/bridge/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(options?: RequestOptions): Promise<RequestViewportResult> {\n const data = await request('web_app_request_viewport', 'viewport_changed', options);\n\n return {\n height: data.height,\n width: data.width,\n isExpanded: data.is_expanded,\n isStateStable: data.is_state_stable,\n };\n}\n","/**\n * Formats value to make it stay in bounds [0, +Inf).\n * @param value - value to format.\n */\nexport function truncate(value: number): number {\n return value < 0 ? 0 : value;\n}\n","import {\n on,\n type PostEvent,\n postEvent as defaultPostEvent,\n type RequestOptions,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport { requestViewport } from '~/viewport/requestViewport.js';\n\nimport type {\n ViewportEvents,\n ViewportProps,\n ViewportState,\n} from './types.js';\nimport { truncate } from './utils.js';\n\n/**\n * Contains information about current WebApp device viewport, its dimensions\n * and state.\n */\nexport class Viewport {\n private readonly ee = new EventEmitter<ViewportEvents>();\n\n private readonly state: State<ViewportState>;\n\n private readonly postEvent: PostEvent;\n\n constructor(props: ViewportProps) {\n const {\n height,\n isExpanded,\n width,\n stableHeight,\n postEvent = defaultPostEvent,\n } = props;\n this.postEvent = postEvent;\n this.state = new State({\n height: truncate(height),\n isExpanded,\n stableHeight: truncate(stableHeight),\n width: truncate(width),\n }, this.ee);\n }\n\n /**\n * Request viewport information from the Telegram application and updates current Viewport\n * instance.\n * @param options - options to request fresh data.\n */\n sync(options?: RequestOptions): Promise<void> {\n return requestViewport(options).then(({ height, isExpanded, width, isStateStable }) => {\n this.state.set({\n height,\n width,\n isExpanded,\n stableHeight: isStateStable ? height : this.state.get('stableHeight'),\n });\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\n * lower part remaining outside the screen area. From this position, the\n * user can \"pull\" the Mini App to its maximum height, while the bot can do\n * the same by calling `expand` method. As the position of the Mini App\n * changes, the current height value of the visible area will be updated\n * in real time.\n *\n * Please note that the refresh rate of this value is not sufficient\n * to smoothly follow the lower border of the window. It should not be\n * used to pin interface elements to the bottom of the visible area. It's\n * more appropriate to use the value of the `stableHeight`\n * field for this purpose.\n */\n get height(): number {\n return this.state.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\n * lower part remaining outside the screen area. From this position,\n * the user can \"pull\" the Mini App to its maximum height, while the bot can\n * do the same by calling `expand` method.\n *\n * Unlike the value of `height`, the value of `stableHeight`\n * does not change as the position of the Mini App changes with user\n * 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 get stableHeight(): number {\n return this.state.get('stableHeight');\n }\n\n /**\n * Starts listening to viewport changes and applies them.\n * @returns Function to stop listening.\n */\n listen() {\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 state: Partial<ViewportState> = {\n height: truncate(height),\n isExpanded,\n width: truncate(width),\n };\n\n if (isStateStable) {\n state.stableHeight = state.height;\n }\n\n this.state.set(state);\n });\n }\n\n /**\n * Returns true if the Mini App is expanded to the maximum available height.\n * Otherwise, if the Mini App occupies part of the screen and can be expanded\n * to the full height using `expand` method.\n * @see expand\n */\n get isExpanded(): boolean {\n return this.state.get('isExpanded');\n }\n\n /**\n * Current viewport width.\n */\n get width(): number {\n return this.state.get('width');\n }\n\n /**\n * A method that expands the Mini App to the maximum available height. To\n * find out if the Mini App is expanded to the maximum height, refer to the\n * value of the `isExpanded`.\n * @see isExpanded\n */\n expand(): void {\n this.postEvent('web_app_expand');\n this.state.set('isExpanded', true);\n }\n\n /**\n * Returns true in case current viewport height is stable and is not going to\n * change in the next moment.\n */\n get isStable(): boolean {\n return this.stableHeight === this.height;\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n}\n","import { getStorageValue, saveStorageValue } from '~/storage.js';\nimport { requestViewport, Viewport } from '~/viewport/index.js';\nimport type { PostEvent } from '~/bridge/index.js';\nimport type { Platform } from '~/types/index.js';\n\n/**\n * Returns true in case, specified platform supports calling Mini Apps\n * \"web_app_request_viewport\" method.\n * @param platform - platform identifier.\n */\nfunction isRequestSupportedPlatform(platform: Platform): boolean {\n return !['macos', 'web', 'weba'].includes(platform);\n}\n\n/**\n * Attempts to create Viewport instance using known parameters and local storage.\n * @param isPageReload - was page reloaded.\n * @param platform - platform identifier.\n * @param postEvent - Bridge postEvent function.\n */\nfunction tryCreate(\n isPageReload: boolean,\n platform: Platform,\n postEvent: PostEvent,\n): Viewport | null {\n if (isPageReload || !isRequestSupportedPlatform(platform)) {\n return new Viewport({\n height: window.innerHeight,\n isExpanded: true,\n postEvent,\n stableHeight: window.innerHeight,\n width: window.innerWidth,\n });\n }\n\n const state = getStorageValue('viewport');\n if (state) {\n return new Viewport({ ...state, postEvent });\n }\n\n return null;\n}\n\n/**\n * Synchronizes specified Viewport instance with Telegram application and always saves its state\n * in local storage.\n * @param viewport - Viewport instance.\n */\nfunction bind(viewport: Viewport): Viewport {\n viewport.listen();\n\n // TODO: Should probably use throttle for height.\n viewport.on('change', () => saveStorageValue('viewport', {\n height: viewport.height,\n isExpanded: viewport.isExpanded,\n stableHeight: viewport.stableHeight,\n width: viewport.width,\n }));\n\n return viewport;\n}\n\n/**\n * Creates Viewport instance using its actual state from the storage. Otherwise, creates it\n * with default parameters.\n * @param isPageReload - was page reloaded.\n * @param platform - platform identifier.\n * @param postEvent - Bridge postEvent function.\n */\nexport function createViewportSync(\n isPageReload: boolean,\n platform: Platform,\n postEvent: PostEvent,\n): Viewport {\n const viewport = bind(\n tryCreate(isPageReload, platform, postEvent) || new Viewport({\n width: 0,\n height: 0,\n isExpanded: false,\n postEvent,\n stableHeight: 0,\n }),\n );\n\n if (isRequestSupportedPlatform(platform)) {\n viewport.sync({ postEvent, timeout: 100 }).catch((e) => {\n // eslint-disable-next-line no-console\n console.error('Unable to actualize viewport state', e);\n });\n }\n\n return viewport;\n}\n\n/**\n * Creates Viewport instance using its actual state from the Telegram application.\n * @param isPageReload - was page reloaded.\n * @param platform - platform identifier.\n * @param postEvent - Bridge postEvent function.\n */\nexport async function createViewportAsync(\n isPageReload: boolean,\n platform: Platform,\n postEvent: PostEvent,\n): Promise<Viewport> {\n return bind(\n tryCreate(isPageReload, platform, postEvent)\n || await requestViewport({ postEvent, timeout: 100 })\n .then(({ height, isStateStable, ...rest }) => new Viewport({\n ...rest,\n height,\n stableHeight: isStateStable ? height : 0,\n })),\n );\n}\n","/**\n * Sets CSS variable.\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 { setCSSVar } from '~/init/css/setCSSVar.js';\nimport type { MiniApp } from '~/mini-app/index.js';\nimport type { ThemeParams } from '~/theme-params/index.js';\n\n/**\n * Creates CSS variables connected with WebApp background and header colors based on\n * passed WebApp and ThemeParams instances.\n *\n * Created variables:\n * - `--tg-background-color`\n * - `--tg-header-color`\n *\n * Variables are being automatically updated in case, corresponding properties are updating.\n *\n * @param miniApp - MiniApp instance.\n * @param themeParams - ThemeParams instance.\n */\nexport function bindMiniAppCSSVars(miniApp: MiniApp, themeParams: ThemeParams): void {\n const actualizeBackground = () => {\n setCSSVar('--tg-background-color', miniApp.backgroundColor);\n };\n\n const actualizeHeader = () => {\n const {\n backgroundColor,\n secondaryBackgroundColor,\n } = themeParams;\n\n if (miniApp.headerColor === 'bg_color') {\n if (backgroundColor) {\n setCSSVar('--tg-header-color', backgroundColor);\n }\n } else if (miniApp.headerColor === 'secondary_bg_color') {\n if (secondaryBackgroundColor) {\n setCSSVar('--tg-header-color', secondaryBackgroundColor);\n }\n } else {\n setCSSVar('--tg-header-color', miniApp.headerColor);\n }\n };\n\n themeParams.on('change', actualizeHeader);\n miniApp.on('change:backgroundColor', actualizeBackground);\n miniApp.on('change:headerColor', actualizeHeader);\n\n actualizeBackground();\n actualizeHeader();\n}\n","import type { ThemeParams } from '~/theme-params/index.js';\n\nimport { setCSSVar } from './setCSSVar.js';\n\n/**\n * Creates CSS variables connected with theme parameters. Created CSS variables names are\n * following the pattern \"--tg-theme-{name}\". {name} is a theme parameters key name converted\n * from snake to kebab case.\n *\n * Variables are being automatically updated in case, corresponding properties\n * updated in passed ThemeParams instance.\n *\n * @param themeParams - ThemeParams instance.\n */\nexport function bindThemeCSSVars(themeParams: ThemeParams): void {\n const actualize = () => {\n const state = themeParams.getState();\n\n Object.entries(state).forEach(([k, v]) => {\n if (v) {\n const key = k\n .replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n setCSSVar(`--tg-theme-${key}`, v);\n }\n });\n };\n\n themeParams.on('change', actualize);\n\n actualize();\n}\n","import type { Viewport } from '~/viewport/index.js';\n\nimport { setCSSVar } from './setCSSVar.js';\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 */\nexport function bindViewportCSSVars(viewport: Viewport): void {\n const setHeight = () => setCSSVar('--tg-viewport-height', `${viewport.height}px`);\n const setWidth = () => setCSSVar('--tg-viewport-width', `${viewport.width}px`);\n const setStableHeight = () => setCSSVar('--tg-viewport-height', `${viewport.stableHeight}px`);\n\n // TODO: Should probably add debounce or throttle.\n viewport.on('change:height', setHeight);\n viewport.on('change:width', setWidth);\n viewport.on('change:stableHeight', setStableHeight);\n\n setHeight();\n setWidth();\n setStableHeight();\n}\n","import type { MiniApp } from '~/mini-app/index.js';\nimport type { ThemeParams } from '~/theme-params/index.js';\nimport type { Viewport } from '~/viewport/index.js';\n\nimport { bindMiniAppCSSVars } from './bindMiniAppCSSVars.js';\nimport { bindThemeCSSVars } from './bindThemeCSSVars.js';\nimport { bindViewportCSSVars } from './bindViewportCSSVars.js';\nimport type { InitCSSVarsOption, InitCSSVarsSpecificOption } from '../types.js';\n\n/**\n * Converts init cssVars option to more narrow type.\n * @param option - option value.\n */\nfunction parseCSSVarsOptions(option: InitCSSVarsOption): InitCSSVarsSpecificOption {\n if (typeof option === 'object') {\n return option;\n }\n return option\n ? {\n themeParams: true,\n viewport: true,\n miniApp: true,\n }\n : {};\n}\n\n/**\n * Process initialization CSS vars option.\n * @param option - option value.\n * @param miniApp - MiniApp instance.\n * @param themeParams - ThemeParams instance.\n * @param viewportOrPromise - Viewport instance or promise resolving it.\n */\nexport function processCSSVars(\n option: InitCSSVarsOption,\n miniApp: MiniApp,\n themeParams: ThemeParams,\n viewportOrPromise: Viewport | Promise<Viewport>,\n): void {\n const cssVarsOptions = parseCSSVarsOptions(option);\n\n if (cssVarsOptions.miniApp) {\n bindMiniAppCSSVars(miniApp, themeParams);\n }\n\n if (cssVarsOptions.themeParams) {\n bindThemeCSSVars(themeParams);\n }\n\n if (cssVarsOptions.viewport) {\n if (viewportOrPromise instanceof Promise) {\n viewportOrPromise.then(bindViewportCSSVars);\n } else {\n bindViewportCSSVars(viewportOrPromise);\n }\n }\n}\n","import {\n type InvoiceStatus,\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport type { InvoiceEvents, InvoiceState } from './types.js';\n\n/**\n * Extracts invoice slug from URL.\n * @param url - url to extract slug from.\n */\nfunction slugFromUrl(url: string): string {\n const { hostname, pathname } = new URL(url, 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\n if (match === null) {\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 return match[2];\n}\n\n/**\n * Controls currently displayed invoice.\n */\nexport class Invoice {\n private readonly ee = new EventEmitter<InvoiceEvents>();\n\n private readonly state: State<InvoiceState>;\n\n constructor(\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isOpened: false }, this.ee);\n this.supports = createSupportsFunc(version, { open: 'web_app_open_invoice' });\n }\n\n private set isOpened(value) {\n this.state.set('isOpened', value);\n }\n\n /**\n * True if invoice is currently opened.\n */\n get isOpened(): boolean {\n return this.state.get('isOpened');\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\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 const slug = type ? slugFromUrl(urlOrSlug) : urlOrSlug;\n\n this.isOpened = true;\n\n try {\n const result = await request(\n 'web_app_open_invoice',\n { slug },\n 'invoice_closed',\n {\n postEvent: this.postEvent,\n capture(data) {\n return slug === data.slug;\n },\n },\n );\n\n return result.status;\n } finally {\n this.isOpened = false;\n }\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'open'>;\n}\n","import type { PopupButton, PopupParams as BridgePopupParams } from '~/bridge/index.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 === 0 || 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 === 0) {\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 === undefined || b.type === 'default' || b.type === 'destructive') {\n const text = b.text.trim();\n\n if (text.length === 0 || 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 {\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport { preparePopupParams } from './preparePopupParams.js';\nimport type { OpenPopupOptions, PopupEvents, PopupState } from './types.js';\n\n/**\n * Controls currently displayed application popup. It allows developers to\n * open new custom popups and detect popup-connected events.\n */\nexport class Popup {\n private readonly ee = new EventEmitter<PopupEvents>();\n\n private readonly state: State<PopupState>;\n\n constructor(\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isOpened: false }, this.ee);\n this.supports = createSupportsFunc(version, { open: 'web_app_open_popup' });\n }\n\n private set isOpened(value) {\n this.state.set('isOpened', value);\n }\n\n /**\n * True if popup is currently opened.\n */\n get isOpened(): boolean {\n return this.state.get('isOpened');\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\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 * FIXME: In desktop, this function may work incorrectly.\n * Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/7\n * @param options - popup parameters.\n * @throws {Error} Popup is already opened.\n */\n 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 return request(\n 'web_app_open_popup',\n preparePopupParams(options),\n 'popup_closed',\n { postEvent: this.postEvent },\n )\n .then(({ button_id = null }) => button_id)\n .finally(() => {\n this.isOpened = false;\n });\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'open'>;\n}\n","import {\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport type { QRScannerEvents, QRScannerState } from './types.js';\n\n/**\n * Provides QR scanner functionality.\n */\nexport class QRScanner {\n private readonly ee = new EventEmitter<QRScannerEvents>();\n\n private readonly state: State<QRScannerState>;\n\n constructor(\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isOpened: false }, this.ee);\n this.supports = createSupportsFunc(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.state.set('isOpened', value);\n }\n\n /**\n * Returns true in case, QR scanner is currently opened.\n */\n get isOpened(): boolean {\n return this.state.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 'web_app_open_scan_qr_popup',\n { text },\n ['qr_text_received', 'scan_qr_popup_closed'],\n { postEvent: this.postEvent },\n );\n\n return typeof result === 'object' && typeof result.data === 'string' ? result.data : null;\n } finally {\n this.isOpened = false;\n }\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'open' | 'close'>;\n}\n","import {\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n} from '~/bridge/index.js';\nimport {\n createSupportsFunc,\n createSupportsParamFunc,\n supports,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { CreateRequestIdFunc } from '~/types/index.js';\nimport type { Version } from '~/version/index.js';\n\n/**\n * Provides common Mini Apps functionality not covered by other system components.\n */\nexport class Utils {\n constructor(\n private readonly version: Version,\n private readonly createRequestId: CreateRequestIdFunc,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.supports = createSupportsFunc(version, {\n readTextFromClipboard: 'web_app_read_text_from_clipboard',\n });\n\n this.supportsParam = createSupportsParamFunc(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 {\n hostname,\n pathname,\n search,\n } = new URL(url, window.location.href);\n\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 readTextFromClipboard(): Promise<string | null> {\n return request(\n 'web_app_read_text_from_clipboard',\n { req_id: this.createRequestId() },\n 'clipboard_text_received',\n { postEvent: this.postEvent },\n ).then(({ data = null }) => data);\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'readTextFromClipboard'>;\n\n /**\n * Checks if specified method parameter is supported by current component.\n */\n supportsParam: SupportsFunc<'openLink.tryInstantView'>;\n}\n","import { createPostEvent, isIframe, on } from '~/bridge/index.js';\nimport { CloudStorage } from '~/cloud-storage/index.js';\nimport { HapticFeedback } from '~/haptic-feedback/index.js';\nimport { catchCustomStyles } from '~/init/catchCustomStyles.js';\nimport {\n createBackButton,\n createClosingBehavior,\n createMainButton,\n createMiniApp,\n createRequestIdGenerator, createSettingsButton,\n createThemeParams, createViewportAsync,\n createViewportSync,\n} from '~/init/creators/index.js';\nimport { processCSSVars } from '~/init/css/index.js';\nimport { InitData } from '~/init-data/index.js';\nimport { Invoice } from '~/invoice/index.js';\nimport { retrieveLaunchData } from '~/launch-params/index.js';\nimport { Popup } from '~/popup/index.js';\nimport { QRScanner } from '~/qr-scanner/index.js';\nimport { Utils } from '~/utils/index.js';\n\nimport type { InitOptions, InitResult } from './types.js';\n\ntype ComputedInitResult<O> = O extends { async: true } ? Promise<InitResult> : InitResult;\n\nexport function init(): InitResult;\nexport function init<O extends InitOptions>(options: O): ComputedInitResult<O>;\nexport function init(options: InitOptions = {}): InitResult | Promise<InitResult> {\n const {\n async = false,\n cssVars = false,\n acceptCustomStyles = false,\n } = options;\n\n try {\n // Retrieve launch data.\n const {\n launchParams: {\n initData,\n initDataRaw,\n version,\n platform,\n themeParams,\n botInline = false,\n },\n isPageReload,\n } = retrieveLaunchData();\n\n const createRequestId = createRequestIdGenerator();\n const postEvent = createPostEvent(version);\n\n // In Telegram web version we should listen to special event sent from the Telegram application\n // to know, when we should reload the Mini App.\n if (isIframe()) {\n if (acceptCustomStyles) {\n catchCustomStyles();\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 on('reload_iframe', () => window.location.reload());\n }\n\n const result: Omit<InitResult, 'viewport'> = {\n backButton: createBackButton(isPageReload, version, postEvent),\n closingBehavior: createClosingBehavior(isPageReload, postEvent),\n cloudStorage: new CloudStorage(version, createRequestId, postEvent),\n createRequestId,\n hapticFeedback: new HapticFeedback(version, postEvent),\n invoice: new Invoice(version, postEvent),\n mainButton: createMainButton(\n isPageReload,\n themeParams.buttonColor || '#000000',\n themeParams.buttonTextColor || '#ffffff',\n postEvent,\n ),\n miniApp: createMiniApp(\n isPageReload,\n themeParams.backgroundColor || '#ffffff',\n version,\n botInline,\n createRequestId,\n postEvent,\n ),\n popup: new Popup(version, postEvent),\n postEvent,\n qrScanner: new QRScanner(version, postEvent),\n settingsButton: createSettingsButton(isPageReload, version, postEvent),\n themeParams: createThemeParams(themeParams),\n utils: new Utils(version, createRequestId, postEvent),\n ...(initData\n // Init data could be missing in case, application was launched via InlineKeyboardButton.\n ? {\n initData: new InitData(initData),\n initDataRaw,\n }\n : {}),\n };\n\n const viewport = async\n ? createViewportAsync(isPageReload, platform, postEvent)\n : createViewportSync(isPageReload, platform, postEvent);\n\n if (viewport instanceof Promise) {\n return viewport.then((vp) => {\n processCSSVars(\n cssVars,\n result.miniApp,\n result.themeParams,\n vp,\n );\n\n return {\n ...result,\n viewport: vp,\n };\n });\n }\n\n processCSSVars(\n cssVars,\n result.miniApp,\n result.themeParams,\n viewport,\n );\n\n return { ...result, viewport };\n } catch (e) {\n if (async) {\n return Promise.reject(e);\n }\n throw e;\n }\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","/**\n * Returns string after first met \"#\" symbol.\n * @param value - string to take hash part from.\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","/**\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 window.addEventListener('popstate', function listener() {\n window.removeEventListener('popstate', listener);\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 './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.\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 { Logger } from '~/logger/index.js';\n\nimport type {\n AnyEntry,\n NavigationEntry,\n NavigatorConEntry,\n NavigatorOptions,\n PerformGoOptions,\n PerformPushOptions,\n PerformReplaceOptions,\n} from './types.js';\nimport { ensurePrefix } from '../ensurePrefix.js';\n\n/**\n * Represents basic navigator implementation which uses only memory to store and control\n * navigation state.\n */\nexport abstract class Navigator<T> {\n protected logger: Logger;\n\n protected readonly entries: NavigationEntry[];\n\n constructor(\n entries: NavigatorConEntry[],\n protected entriesCursor: number,\n {\n debug = false,\n loggerPrefix = 'Navigator',\n }: NavigatorOptions,\n ) {\n if (entries.length === 0) {\n throw new Error('Entries list should not be empty.');\n }\n\n if (entriesCursor >= entries.length) {\n throw new Error('Cursor should be less than entries count.');\n }\n\n this.entries = entries.map(({ pathname = '', search, hash }) => {\n if (!pathname.startsWith('/') && pathname.length > 0) {\n throw new Error('Pathname should start with \"/\"');\n }\n\n return {\n pathname: ensurePrefix(pathname, '/'),\n search: search ? ensurePrefix(search, '?') : '',\n hash: hash ? ensurePrefix(hash, '#') : '',\n };\n });\n this.logger = new Logger(`[${loggerPrefix}]`, debug);\n }\n\n protected abstract performGo(options: PerformGoOptions): T;\n\n protected abstract performPush(options: PerformPushOptions): T;\n\n protected abstract performReplace(options: PerformReplaceOptions): T;\n\n /**\n * Converts entry to the navigation entry.\n * @param entry - entry data\n */\n private formatEntry(entry: AnyEntry): NavigationEntry {\n let path: string;\n\n if (typeof entry === 'string') {\n path = entry;\n } else {\n const {\n pathname = '',\n search,\n hash,\n } = entry;\n\n path = pathname\n + (search ? ensurePrefix(search, '?') : '')\n + (hash ? ensurePrefix(hash, '#') : '');\n }\n\n const {\n pathname,\n search,\n hash,\n } = new URL(path, `https://localhost${this.path}`);\n return {\n pathname,\n search,\n hash,\n };\n }\n\n /**\n * Current entry.\n */\n protected get entry(): NavigationEntry {\n return this.entries[this.entriesCursor];\n }\n\n /**\n * Goes back in history.\n */\n back(): T {\n return this.go(-1);\n }\n\n /**\n * Current entries cursor.\n */\n get cursor(): number {\n return this.entriesCursor;\n }\n\n /**\n * True if navigator can go back.\n */\n get canGoBack(): boolean {\n return this.entriesCursor > 0;\n }\n\n /**\n * True if navigator can go forward.\n */\n get canGoForward(): boolean {\n return this.entriesCursor !== this.entries.length - 1;\n }\n\n /**\n * Goes forward in history.\n */\n forward(): T {\n return this.go(1);\n }\n\n /**\n * Moves entries cursor by specified delta.\n * @param delta - cursor delta.\n */\n go(delta: number): T {\n this.logger.log(`called go(${delta})`);\n\n // Cursor should be in bounds: [0, this.entries).\n const cursor = Math.min(\n this.entries.length - 1,\n Math.max(this.entriesCursor + delta, 0),\n );\n\n if (this.entriesCursor === cursor) {\n return this.performGo({\n updated: false,\n delta,\n });\n }\n\n const before = this.entry;\n this.entriesCursor = cursor;\n const after = this.entry;\n\n this.logger.log('State changed', { before, after });\n\n return this.performGo({\n updated: true,\n delta,\n before,\n after,\n });\n }\n\n /**\n * Returns copy of navigator entries.\n */\n getEntries(): NavigationEntry[] {\n return this.entries.map((entry) => ({ ...entry }));\n }\n\n /**\n * Current hash.\n * @example\n * \"\", \"#\", \"#hash\"\n */\n get hash(): string {\n return this.entry.hash;\n }\n\n /**\n * Pushes new entry. Method replaces all entries after the current one with the inserted.\n * @param entry - entry data.\n *\n * @example Pushing absolute pathname.\n * push(\"/absolute-path\"); // \"/absolute-path\"\n *\n * @example Pushing relative pathname.\n * // Pushing relative path replaces N last path parts, where N is pushed pathname parts count.\n * // Pushing empty path is recognized as relative, but not replacing the last pathname part.\n * push(\"relative\"); // \"/home/root\" -> \"/home/relative\"\n *\n * @example Pushing query parameters.\n * push(\"/absolute?my-param=1\"); // \"/home\" -> \"/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(\"johny#my-hash\"); // \"/home/root\" -> \"/home/johny#my-hash\"\n */\n push(entry: AnyEntry): T {\n // In case, current cursor refers not to the last one element in the history, we should\n // remove everything after the cursor.\n if (this.entriesCursor !== this.entries.length - 1) {\n this.entries.splice(this.entriesCursor + 1);\n }\n\n const formatted = this.formatEntry(entry);\n const before = this.entry;\n this.entriesCursor += 1;\n this.entries[this.entriesCursor] = formatted;\n const after = this.entry;\n\n this.logger.log('State changed', { before, after });\n\n return this.performPush({\n before,\n after,\n });\n }\n\n /**\n * Current full path including pathname, query parameters and hash.\n */\n get path(): string {\n return `${this.pathname}${this.search}${this.hash}`;\n }\n\n /**\n * Current pathname.\n * @example\n * \"/\", \"/abc\"\n */\n get pathname(): string {\n return this.entry.pathname;\n }\n\n /**\n * Replaces current entry. Has the same logic as `push` method.\n * @param entry - entry data.\n * @see push\n * @returns True if changes were done.\n */\n replace(entry: AnyEntry): T {\n const formattedEntry = this.formatEntry(entry);\n if (\n this.search === formattedEntry.search\n && this.pathname === formattedEntry.pathname\n && this.hash === formattedEntry.hash\n ) {\n return this.performReplace({\n updated: false,\n entry: formattedEntry,\n });\n }\n\n const before = this.entry;\n this.entries[this.entriesCursor] = formattedEntry;\n const after = this.entry;\n\n this.logger.log('State changed', { before, after });\n\n return this.performReplace({\n updated: true,\n before,\n after,\n });\n }\n\n /**\n * Current query parameters.\n * @example\n * \"\", \"?\", \"?a=1\"\n */\n get search(): string {\n return this.entry.search;\n }\n}\n","import { off, on, postEvent } from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\n\nimport { drop } from './drop.js';\nimport { go } from './go.js';\nimport type {\n HashNavigatorEventsMap,\n HashNavigatorOptions,\n} from './types.js';\nimport { Navigator } from '../Navigator/index.js';\nimport type {\n NavigationEntry,\n NavigatorConEntry,\n PerformGoOptions,\n PerformPushOptions,\n PerformReplaceOptions,\n} from '../Navigator/types.js';\n\nconst CURSOR_VOID = 0;\nconst CURSOR_BACK = 1;\nconst CURSOR_FORWARD = 2;\n\nexport class HashNavigator extends Navigator<Promise<void>> {\n /**\n * Creates navigator from current window location hash.\n * @param options - options passed to constructor.\n */\n static fromLocation(options?: HashNavigatorOptions): HashNavigator {\n const {\n search,\n pathname,\n hash,\n } = new URL(\n window.location.hash.slice(1),\n window.location.href,\n );\n\n return new HashNavigator([{ search, pathname, hash }], 0, options);\n }\n\n private readonly ee = new EventEmitter<HashNavigatorEventsMap>();\n\n private attached = false;\n\n constructor(\n entries: NavigatorConEntry[],\n entriesCursor: number,\n options: HashNavigatorOptions = {},\n ) {\n super(entries, entriesCursor, {\n ...options,\n loggerPrefix: 'HashNavigator',\n });\n }\n\n /**\n * Handles window \"popstate\" event.\n * @param state - event state.\n */\n private onPopState = async ({ state }: PopStateEvent) => {\n this.logger.log('\"popstate\" event received. State:', state);\n\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(window.location.hash.slice(1));\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 this.logger.log('Void reached. Moving history forward');\n window.history.forward();\n return;\n }\n\n // User pressed Back button.\n if (state === CURSOR_BACK) {\n return this.back();\n }\n\n // User pressed Forward button.\n if (state === CURSOR_FORWARD) {\n return this.forward();\n }\n };\n\n protected async performGo(options: PerformGoOptions): Promise<void> {\n if (!options.updated) {\n return;\n }\n\n if (this.attached) {\n await this.syncHistory();\n }\n\n this.emitChanged(options.before, options.after);\n }\n\n protected async performPush({ before, after }: PerformPushOptions): Promise<void> {\n if (this.attached) {\n await this.syncHistory();\n }\n\n this.emitChanged(before, after);\n }\n\n protected async performReplace(options: PerformReplaceOptions): Promise<void> {\n if (!options.updated) {\n return;\n }\n\n if (this.attached) {\n window.history.replaceState(null, '', `#${this.path}`);\n }\n\n this.emitChanged(options.before, options.after);\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 possible\n // future calls of history.go.\n window.removeEventListener('popstate', this.onPopState);\n\n const hash = `#${this.path}`;\n\n // Drop the browser history and work with the clean one.\n await drop();\n\n // Actualize Telegram Mini Apps BackButton state.\n postEvent('web_app_setup_back_button', { is_visible: this.canGoBack });\n\n if (this.canGoBack && this.canGoForward) {\n // We have both previous and next elements. History should be:\n // [back, *current*, forward]\n this.logger.log('Setting up history: [<-, *, ->]');\n\n window.history.replaceState(CURSOR_BACK, '');\n window.history.pushState(null, '', hash);\n window.history.pushState(CURSOR_FORWARD, '');\n\n await go(-1);\n } else if (this.canGoBack) {\n // We have only previous element. History should be:\n // [back, *current*]\n this.logger.log('Setting up history: [<-, *]');\n\n window.history.replaceState(CURSOR_BACK, '');\n window.history.pushState(null, '', hash);\n } else if (this.canGoForward) {\n // We have only next element. History should be:\n // [*current*, forward]\n this.logger.log('Setting up history: [*, ->]');\n\n window.history.replaceState(null, hash);\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 this.logger.log('Setting up history: [~, *]');\n\n window.history.replaceState(CURSOR_VOID, '');\n window.history.pushState(null, '', hash);\n }\n\n window.addEventListener('popstate', this.onPopState);\n }\n\n private emitChanged(from: NavigationEntry, to: NavigationEntry) {\n this.ee.emit('change', {\n navigator: this,\n from,\n to,\n });\n }\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 return;\n }\n this.logger.log('Attaching', this);\n this.attached = true;\n on('back_button_pressed', this.back);\n return this.syncHistory();\n }\n\n back = () => super.back();\n\n /**\n * Detaches current navigator from the browser history.\n */\n detach() {\n if (!this.attached) {\n return;\n }\n this.logger.log('Detaching', this);\n this.attached = false;\n window.removeEventListener('popstate', this.onPopState);\n off('back_button_pressed', this.back);\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n}\n"],"names":["isRecord","value","getFirstNavigationEntry","computePageReload","firstNavigationEntry","unexpectedTypeError","ParseError","cause","type","__publicField","ValueParser","parser","isOptional","parseArray","json","ArrayValueParser","itemParser","arr","createValueParserGenerator","ParseSchemaFieldError","field","parseBySchema","schema","getField","result","definition","from","parsedValue","originalValue","error","array","boolean","asString","number","num","date","toRecord","formattedValue","record","isRGB","isRGBShort","toRGB","clean","color","i","match","acc","component","formatted","isColorDark","rgb","modifier","idx","dec","string","searchParams","params","paramValue","chatParser","InitData","initData","canSendAfter","userParser","initDataParser","parseInitData","keyToLocal","key","_","prefix","_match","letter","keyToExternal","themeParamsParser","rgbOptional","k","v","parseThemeParams","requestThemeParams","options","request","serializeThemeParams","themeParams","EventEmitter","event","listener","once","listeners","args","l","State","state","ee","keyOrState","didChange","ThemeParams","on","launchParamsParser","parseLaunchParams","retrieveFromLocation","retrieveFromPerformance","navigationEntry","hashMatch","retrieveCurrent","serializeLaunchParams","initDataRaw","platform","version","showSettings","botInline","SESSION_STORAGE_KEY","retrieveFromStorage","raw","saveToStorage","isIframe","computeLaunchData","lpPrevious","lpCurrent","isPageReload","WINDOW_KEY","retrieveLaunchData","cached","launchData","isTMA","hasExternalNotify","hasWebviewProxy","MethodUnsupportedError","method","ParameterUnsupportedError","param","Logger","enabled","level","now","currentTargetOrigin","logger","setDebug","setTargetOrigin","targetOrigin","eventDataJson","emitEvent","eventType","eventData","defineEventHandlers","wnd","path","pointer","item","onTelegramEvent","cb","clipboardTextReceived","customMethodInvoked","invoiceClosed","phoneRequested","popupClosed","qrTextReceived","themeChanged","viewportChanged","writeAccessRequested","createEmitter","emitter","emit","data","CACHED_EMITTER","singletonEmitter","off","unsubscribe","subscribe","compareVersions","a","b","aParts","bParts","len","aVal","bVal","versionLessOrEqual","supports","paramOrVersion","inVersion","createSupportsFunc","createSupportsParamFunc","tmaMethod","postEvent","paramsOrOptions","postOptions","globalTargetOrigin","createPostEvent","validateParam","TimeoutError","timeout","isTimeoutError","sleep","duration","res","createTimeoutPromise","rej","withTimeout","func","eventOrParams","eventOrOptions","executionOptions","methodParams","events","requestId","defaultPostEvent","capture","execute","stoppers","ev","stopListening","stop","e","invokeCustomMethod","BackButton","isVisible","visible","space","classNames","values","valueAcc","className","enable","isObject","mergeClassNames","partials","partial","ClosingBehavior","isConfirmationNeeded","objectFromKeys","keys","CloudStorage","createRequestId","keyOrKeys","HapticFeedback","style","catchCustomStyles","element","html","formatKey","saveStorageValue","getStorageValue","createBackButton","createClosingBehavior","MainButton","props","text","textColor","backgroundColor","isEnabled","isLoaderVisible","createMainButton","stateBackgroundColor","stateTextColor","saveState","contactParser","MiniApp","headerColor","isSupported","deadlineAt","sleepTime","size","chatTypes","createMiniApp","createRequestIdGenerator","SettingsButton","createSettingsButton","createThemeParams","requestViewport","truncate","Viewport","height","isExpanded","width","stableHeight","isStateStable","isRequestSupportedPlatform","tryCreate","bind","viewport","createViewportSync","createViewportAsync","rest","setCSSVar","name","bindMiniAppCSSVars","miniApp","actualizeBackground","actualizeHeader","secondaryBackgroundColor","bindThemeCSSVars","actualize","bindViewportCSSVars","setHeight","setWidth","setStableHeight","parseCSSVarsOptions","option","processCSSVars","viewportOrPromise","cssVarsOptions","slugFromUrl","url","hostname","pathname","Invoice","urlOrSlug","slug","preparePopupParams","message","title","buttons","preparedButtons","id","Popup","button_id","QRScanner","Utils","tryInstantView","formattedUrl","search","init","async","cssVars","acceptCustomStyles","vp","ensurePrefix","getHash","go","delta","drop","shouldGoBack","Navigator","entries","entriesCursor","debug","loggerPrefix","hash","entry","cursor","before","after","formattedEntry","CURSOR_VOID","CURSOR_BACK","CURSOR_FORWARD","HashNavigator","to"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/misc/isRecord.ts","../src/launch-params/getFirstNavigationEntry.ts","../src/launch-params/computePageReload.ts","../src/parsing/unexpectedTypeError.ts","../src/parsing/ParseError.ts","../src/parsing/ValueParser.ts","../src/parsing/ArrayValueParser.ts","../src/parsing/createValueParserGenerator.ts","../src/parsing/ParseSchemaFieldError.ts","../src/parsing/parseBySchema.ts","../src/parsing/parsers/array.ts","../src/parsing/parsers/boolean.ts","../src/parsing/parsers/number.ts","../src/parsing/parsers/date.ts","../src/parsing/toRecord.ts","../src/parsing/parsers/json.ts","../src/colors/isRGB.ts","../src/colors/isRGBShort.ts","../src/colors/toRGB.ts","../src/colors/isColorDark.ts","../src/parsing/parsers/string.ts","../src/parsing/parsers/rgb.ts","../src/parsing/parsers/searchParams.ts","../src/init-data/chatParser.ts","../src/init-data/InitData.ts","../src/init-data/userParser.ts","../src/init-data/initDataParser.ts","../src/init-data/parseInitData.ts","../src/theme-params/keys.ts","../src/theme-params/themeParamsParser.ts","../src/theme-params/parseThemeParams.ts","../src/theme-params/requestThemeParams.ts","../src/theme-params/serializeThemeParams.ts","../src/event-emitter/EventEmitter.ts","../src/state/State.ts","../src/theme-params/ThemeParams.ts","../src/launch-params/launchParamsParser.ts","../src/launch-params/parseLaunchParams.ts","../src/launch-params/retrieveFromLocation.ts","../src/launch-params/retrieveFromPerformance.ts","../src/launch-params/retrieveCurrent.ts","../src/launch-params/serializeLaunchParams.ts","../src/launch-params/storage.ts","../src/launch-params/computeLaunchData.ts","../src/launch-params/retrieveLaunchData.ts","../src/misc/isTMA.ts","../src/bridge/env/hasExternalNotify.ts","../src/bridge/env/hasWebviewProxy.ts","../src/bridge/env/isIframe.ts","../src/bridge/errors/MethodUnsupportedError.ts","../src/bridge/errors/ParameterUnsupportedError.ts","../src/logger/Logger.ts","../src/globals.ts","../src/bridge/events/onTelegramEvent.ts","../src/bridge/events/parsers/clipboardTextReceived.ts","../src/bridge/events/parsers/customMethodInvoked.ts","../src/bridge/events/parsers/invoiceClosed.ts","../src/bridge/events/parsers/phoneRequested.ts","../src/bridge/events/parsers/popupClosed.ts","../src/bridge/events/parsers/qrTextReceived.ts","../src/bridge/events/parsers/theme-changed.ts","../src/bridge/events/parsers/viewportChanged.ts","../src/bridge/events/parsers/writeAccessRequested.ts","../src/bridge/events/createEmitter.ts","../src/bridge/events/singletonEmitter.ts","../src/bridge/events/off.ts","../src/bridge/events/on.ts","../src/bridge/events/once.ts","../src/bridge/events/unsubscribe.ts","../src/bridge/events/subscribe.ts","../src/version/compareVersions.ts","../src/supports/supports.ts","../src/supports/createSupportsFunc.ts","../src/supports/createSupportsParamFunc.ts","../src/bridge/methods/postEvent.ts","../src/bridge/methods/createPostEvent.ts","../src/timeout/TimeoutError.ts","../src/timeout/isTimeoutError.ts","../src/timeout/sleep.ts","../src/timeout/withTimeout.ts","../src/bridge/request.ts","../src/bridge/invoke-custom-method.ts","../src/back-button/BackButton.ts","../src/classnames/classNames.ts","../src/classnames/mergeClassNames.ts","../src/closing-behavior/ClosingBehavior.ts","../src/cloud-storage/CloudStorage.ts","../src/haptic-feedback/HapticFeedback.ts","../src/init/catchCustomStyles.ts","../src/storage.ts","../src/init/creators/createBackButton.ts","../src/init/creators/createClosingBehavior.ts","../src/main-button/MainButton.ts","../src/init/creators/createMainButton.ts","../src/mini-app/contactParser.ts","../src/mini-app/MiniApp.ts","../src/init/creators/createMiniApp.ts","../src/init/creators/createRequestIdGenerator.ts","../src/settings-button/SettingsButton.ts","../src/init/creators/createSettingsButton.ts","../src/init/creators/createThemeParams.ts","../src/viewport/isStableViewportPlatform.ts","../src/viewport/requestViewport.ts","../src/viewport/utils.ts","../src/viewport/Viewport.ts","../src/init/creators/createViewport.ts","../src/init/css/setCSSVar.ts","../src/init/css/bindMiniAppCSSVars.ts","../src/init/css/bindThemeCSSVars.ts","../src/init/css/bindViewportCSSVars.ts","../src/init/css/processCSSVarsOption.ts","../src/invoice/Invoice.ts","../src/popup/preparePopupParams.ts","../src/popup/Popup.ts","../src/qr-scanner/QRScanner.ts","../src/utils/Utils.ts","../src/init/init.ts","../src/navigation/ensurePrefix.ts","../src/navigation/getHash.ts","../src/navigation/HashNavigator/go.ts","../src/navigation/HashNavigator/drop.ts","../src/navigation/Navigator/Navigator.ts","../src/navigation/HashNavigator/HashNavigator.ts"],"sourcesContent":["/**\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","/**\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 | null {\n return (\n performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming | undefined\n ) || null;\n}\n","import { getFirstNavigationEntry } from './getFirstNavigationEntry.js';\n\n/**\n * Determines if current page was reloaded.\n * @returns Boolean if function was able to compute any valid value. Null in case, no\n * navigation entries were found.\n */\nexport function computePageReload(): boolean | null {\n const firstNavigationEntry = getFirstNavigationEntry();\n return firstNavigationEntry\n ? firstNavigationEntry.type === 'reload'\n : null;\n}\n","/**\n * Creates instance of TypeError stating, that value has unexpected type.\n */\nexport function unexpectedTypeError(): TypeError {\n return new TypeError('Value has unexpected type');\n}\n","interface Options {\n /**\n * Type name.\n */\n type?: string;\n\n /**\n * Original occurred error.\n */\n cause?: unknown;\n}\n\n/**\n * Error thrown in case, there was an error during parsing.\n */\nexport class ParseError extends Error {\n /**\n * Parser name.\n */\n public readonly type?: string;\n\n constructor(public readonly value: unknown, { cause, type }: Options = {}) {\n super(`Unable to parse value${type ? ` as ${type}` : ''}`, { cause });\n Object.setPrototypeOf(this, ParseError.prototype);\n this.type = type;\n }\n}\n","import type { If } from '~/types/index.js';\n\nimport { ParseError } from './ParseError.js';\nimport type { Parser } from './types.js';\n\n/**\n * Result of \"parse\" function.\n */\nexport type ParseResult<ResultType, IsOptional extends boolean> =\n | ResultType\n | If<IsOptional, undefined, never>;\n\n/**\n * Result of \"optional\" function in ValueParser.\n */\nexport type OptionalResult<BaseClass, ResultType> = ValueParserType<\nBaseClass,\nResultType,\ntrue\n>;\n\nexport interface ValueParserOverrides<BaseClass, ResultType, IsOptional extends boolean> {\n /**\n * Parses incoming value applying parsing function passed via constructor.\n * @param value - value to parse.\n */\n parse(value: unknown): ParseResult<ResultType, IsOptional>;\n\n /**\n * Marks this parser result as optional. This makes the parser to check if passed value\n * is empty. If so, parser will return undefined value instead of passing it to the actual\n * parser.\n */\n optional(): OptionalResult<BaseClass, ResultType>;\n}\n\n/**\n * Describes generated ValueParser interface. Shortly saying, this type overrides BaseClass\n * properties defined in ValueParser.\n */\nexport type ValueParserType<BaseClass, ResultType, IsOptional extends boolean> =\n Omit<BaseClass, keyof ValueParserOverrides<any, any, any>>\n & ValueParserOverrides<BaseClass, ResultType, IsOptional>;\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 parse(value: unknown): ParseResult<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 ParseResult<ResultType, IsOptional>;\n }\n\n try {\n return this.parser(value) as ParseResult<ResultType, IsOptional>;\n } catch (cause) {\n throw new ParseError(value, { type: this.type, cause });\n }\n }\n\n optional(): OptionalResult<this, ResultType> {\n this.isOptional = true as IsOptional;\n return this as OptionalResult<this, ResultType>;\n }\n}\n","import type { AnyParser, Parser } from './types.js';\nimport { unexpectedTypeError } from './unexpectedTypeError.js';\nimport type { ParseResult, ValueParserOverrides } from './ValueParser.js';\nimport { ValueParser } from './ValueParser.js';\n\nexport type OfResult<BaseClass, ItemType, IsOptional extends boolean> = ArrayParserType<\nBaseClass,\nItemType,\nIsOptional\n>;\n\nexport interface ArrayParserOverrides<\n BaseClass,\n ItemType,\n IsOptional extends boolean,\n> extends ValueParserOverrides<BaseClass, ItemType[], IsOptional> {\n /**\n * Specifies parser for each array item.\n * @param parser - item parser.\n */\n of<Item>(parser: AnyParser<Item>): OfResult<BaseClass, Item, IsOptional>;\n}\n\nexport type ArrayParserType<BaseClass, ItemType, IsOptional extends boolean> =\n Omit<BaseClass, keyof ArrayParserOverrides<any, any, any>>\n & ArrayParserOverrides<BaseClass, ItemType, IsOptional>;\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 unexpectedTypeError();\n}\n\nexport class ArrayValueParser<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 override parse(value: unknown): ParseResult<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>): OfResult<this, Item, IsOptional> {\n this.itemParser = typeof itemParser === 'function'\n ? itemParser\n : itemParser.parse.bind(itemParser);\n\n return this as OfResult<this, Item, IsOptional>;\n }\n}\n","import type { Parser } from './types.js';\nimport { ValueParser } from './ValueParser.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","interface Options {\n /**\n * Type name.\n */\n type?: string;\n\n /**\n * Original occurred error.\n */\n cause?: unknown;\n}\n\n/**\n * Error thrown in case, there was an error during parse.\n */\nexport class ParseSchemaFieldError extends Error {\n constructor(field: string, { cause, type }: Options = {}) {\n super(`Unable to parse field \"${field}\"${type ? ` as ${type}` : ''}`, { cause });\n Object.setPrototypeOf(this, ParseSchemaFieldError.prototype);\n }\n}\n","import { ParseError } from './ParseError.js';\nimport { ParseSchemaFieldError } from './ParseSchemaFieldError.js';\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 } = definition;\n\n from = definition.from || field;\n parser = typeof type === 'function' ? type : type.parse.bind(type);\n }\n\n let parsedValue: unknown;\n const originalValue = getField(from);\n\n try {\n parsedValue = parser(originalValue);\n } catch (error) {\n // If error is not instance of ParseError, we have nothing additional to do with the error.\n if (!(error instanceof ParseError)) {\n throw new ParseSchemaFieldError(from, { cause: error });\n }\n\n // Otherwise, we are going to rethrow the error with extended data.\n throw new ParseSchemaFieldError(from, {\n type: error.type,\n cause: error,\n });\n }\n\n if (parsedValue === undefined) {\n continue;\n }\n\n (result as any)[field] = parsedValue;\n }\n\n return result;\n}\n","import { ArrayValueParser } from '../ArrayValueParser.js';\n\n/**\n * Parses incoming value as an array.\n * @param type - parser type name.\n */\nexport function array(type?: string): ArrayValueParser<unknown, false> {\n return new ArrayValueParser((value) => value, false, type);\n}\n","import { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { unexpectedTypeError } from '../unexpectedTypeError.js';\n\n/**\n * Returns parser to parse value as boolean.\n */\nexport const boolean = createValueParserGenerator<boolean>((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 unexpectedTypeError();\n}, 'boolean');\n","import { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { unexpectedTypeError } from '../unexpectedTypeError.js';\n\n/**\n * Returns parser to parse value as number.\n */\nexport const number = createValueParserGenerator<number>((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 unexpectedTypeError();\n}, 'number');\n","import { number } from './number.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as Date.\n */\nexport const date = createValueParserGenerator<Date>((value) => (\n value instanceof Date\n ? value\n : new Date(number().parse(value) * 1000)\n), 'Date');\n","import { unexpectedTypeError } from './unexpectedTypeError.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 unexpectedTypeError();\n }\n\n return formattedValue;\n}\n","import { parseBySchema } from '../parseBySchema.js';\nimport { toRecord } from '../toRecord.js';\nimport type { Schema } from '../types.js';\nimport { ValueParser } from '../ValueParser.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\n return parseBySchema(schema, (field) => record[field]);\n }, false, type);\n}\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 = '#';\n\n for (let i = 0; i < 3; i += 1) {\n color += clean[1 + i].repeat(2);\n }\n return color as RGB;\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 === null) {\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 { 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 const hsp = 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 );\n return hsp < 120;\n}\n","import { createValueParserGenerator } from '../createValueParserGenerator.js';\nimport { unexpectedTypeError } from '../unexpectedTypeError.js';\n\n/**\n * Returns parser to parse value as string.\n */\nexport const string = createValueParserGenerator<string>((value) => {\n if (typeof value === 'string' || typeof value === 'number') {\n return value.toString();\n }\n throw unexpectedTypeError();\n}, 'string');\n","import { toRGB } from '~/colors/index.js';\nimport type { RGB } from '~/colors/index.js';\n\nimport { string } from './string.js';\nimport { createValueParserGenerator } from '../createValueParserGenerator.js';\n\n/**\n * Returns parser to parse value as RGB color.\n */\nexport const rgb = createValueParserGenerator<RGB>((value) => toRGB(string().parse(value)), 'rgb');\n","import { parseBySchema } from '../parseBySchema.js';\nimport type { Schema } from '../types.js';\nimport { unexpectedTypeError } from '../unexpectedTypeError.js';\nimport { ValueParser } from '../ValueParser.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 unexpectedTypeError();\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, number, string } from '~/parsing/index.js';\n\nimport type { Chat } from './types.js';\n\n/**\n * Returns parser used to parse chat data.\n */\nexport function chatParser() {\n return 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}\n","import type {\n Chat,\n ChatType,\n InitDataParsed,\n User,\n} from './types.js';\n\n/**\n * Class which is responsible for displaying Mini Apps 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 === undefined\n ? undefined\n : new Date(this.authDate.getTime() + canSendAfter * 1000);\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 { boolean, json, number, string } from '~/parsing/index.js';\n\nimport type { User } from './types.js';\n\n/**\n * Returns parser used to parse user data.\n */\nexport function userParser() {\n return 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}\n","import { date, number, searchParams, string } from '~/parsing/index.js';\n\nimport { chatParser } from './chatParser.js';\nimport type { InitDataParsed } from './types.js';\nimport { userParser } from './userParser.js';\n\n/**\n * Returns parser used to parse init data, presented as search params.\n */\nexport function initDataParser() {\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: chatParser().optional(),\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: userParser().optional(),\n startParam: {\n type: string().optional(),\n from: 'start_param',\n },\n user: userParser().optional(),\n }, 'InitData');\n}\n","import { initDataParser } from './initDataParser.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 initDataParser().parse(value);\n}\n","/**\n * Converts palette key from Telegram application to representation used by the package.\n * @param key - palette key.\n */\nexport function keyToLocal(key: string): string {\n return key\n // Replace all \"background\" strings to \"bg\".\n .replace(/(^|_)bg/, (_, prefix) => `${prefix}background`)\n // Convert camel case to snake case.\n .replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase());\n}\n\n/**\n * Converts palette key from local representation to representation sent from the Telegram\n * application.\n * @param key - palette key.\n */\nexport function keyToExternal(key: string): string {\n return key\n // Convert camel case to snake case.\n .replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`)\n // Replace all \"background\" strings to \"bg\".\n .replace(/(^|_)background/, (_, prefix) => `${prefix}bg`);\n}\n","import {\n createValueParserGenerator,\n rgb,\n toRecord,\n} from '~/parsing/index.js';\n\nimport { keyToLocal } from './keys.js';\nimport type { ThemeParamsParsed } from './types.js';\n\nexport const themeParamsParser = createValueParserGenerator<ThemeParamsParsed>(\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 { themeParamsParser } from './themeParamsParser.js';\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 themeParamsParser().parse(value);\n}\n","import { request, type RequestOptions } from '~/bridge/index.js';\n\nimport { parseThemeParams } from './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: RequestOptions = {}): Promise<ThemeParamsParsed> {\n return request('web_app_request_theme', 'theme_changed', options)\n .then(parseThemeParams);\n}\n","import type { RGB } from '~/colors/index.js';\n\nimport { 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\n .entries(themeParams)\n .reduce<Record<string, RGB>>((acc, [key, value]) => {\n if (value) {\n acc[keyToExternal(key)] = value;\n }\n return acc;\n }, {}),\n );\n}\n","import type {\n AnySubscribeListener,\n EmptyEventName,\n EventListener, EventName,\n EventParams, NonEmptyEventName, RemoveEventListener,\n} from './types.js';\n\ntype AddedEventListener = [listener: EventListener<any>, once: boolean];\n\n/**\n * Opinionated event emitter implementation.\n */\nexport class EventEmitter<Schema> {\n private readonly listeners: Map<string, AddedEventListener[]> = new Map();\n\n private readonly subscribeListeners: AnySubscribeListener<Schema>[] = [];\n\n /**\n * Adds specified event listener.\n * @param event - event name.\n * @param listener - event listener.\n * @param once - should listener called only once.\n */\n private addListener<E extends EventName<Schema>>(\n event: E,\n listener: EventListener<Schema[E]>,\n once: boolean,\n ): RemoveEventListener {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n listeners = [];\n this.listeners.set(event, listeners);\n }\n\n listeners.push([listener, once]);\n\n return () => this.off(event, listener);\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>>(\n event: E,\n ...args: EventParams<Schema[E]>\n ): void;\n\n emit(event: EventName<Schema>, ...args: any[]): void {\n this.subscribeListeners.forEach((l) => (l as any)(event, ...args));\n\n const listeners = this.listeners.get(event);\n if (!listeners) {\n return;\n }\n\n listeners.forEach(([listener, once], idx) => {\n listener(...args);\n if (once) {\n listeners.splice(idx, 1);\n }\n });\n }\n\n /**\n * Adds event listener.\n * @param event - event name.\n * @param listener - event listener.\n * @returns Function to remove event listener.\n */\n on<E extends EventName<Schema>>(\n event: E,\n listener: EventListener<Schema[E]>,\n ): RemoveEventListener {\n return this.addListener(event, listener, false);\n }\n\n /**\n * Adds event listener following the logic, described in `on` method, but calls specified\n * listener only once, removing it after.\n * @param event - event name.\n * @param listener - event listener.\n * @returns Function to remove event listener.\n * @see on\n */\n once<E extends EventName<Schema>>(\n event: E,\n listener: EventListener<Schema[E]>,\n ): RemoveEventListener {\n return this.addListener(event, listener, true);\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 if (!listeners) {\n return;\n }\n\n for (let i = 0; i < listeners.length; i += 1) {\n if (listener === listeners[i][0]) {\n listeners.splice(i, 1);\n return;\n }\n }\n }\n\n /**\n * Adds event listener to all events.\n * @param listener - events listener.\n * @returns Function to remove event listener.\n * @see on\n * @see once\n */\n subscribe(listener: AnySubscribeListener<Schema>): RemoveEventListener {\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 - events listener.\n * @returns Function to remove event listener.\n */\n unsubscribe(listener: AnySubscribeListener<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 { EventEmitter } from '~/event-emitter/index.js';\nimport type { StringKeys } from '~/types/index.js';\n\nimport type { StateEvents } from './types.js';\n\n/**\n * Represents state which is observable via passed EventEmitter.\n */\nexport class State<S extends object> {\n constructor(\n private readonly state: S,\n private readonly ee: Pick<EventEmitter<StateEvents<S>>, 'on' | 'off' | 'emit'>,\n ) {\n }\n\n private internalSet<K extends StringKeys<S>>(key: K, value: S[K]): boolean {\n if (this.state[key] === value || value === undefined) {\n return false;\n }\n\n this.state[key] = value;\n (this.ee as any).emit(`change:${key}`, value);\n\n return true;\n }\n\n /**\n * Returns copy of current state.\n */\n clone(): S {\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<S>>(key: K, value: S[K]): void;\n set(state: Partial<S>): void;\n set(keyOrState: StringKeys<S> | Partial<S>, value?: S[keyof S]): void {\n let didChange = false;\n\n if (typeof keyOrState === 'string') {\n didChange = this.internalSet(keyOrState, value as any);\n } else {\n // eslint-disable-next-line\n for (const key in keyOrState) {\n if (this.internalSet(key, keyOrState[key] as any)) {\n didChange = true;\n }\n }\n }\n\n if (didChange) {\n (this.ee as any).emit('change');\n }\n }\n\n /**\n * Returns value by specified key.\n * @param key - state key.\n */\n get<K extends StringKeys<S>>(key: K): S[K] {\n return this.state[key];\n }\n}\n","import { on } from '~/bridge/index.js';\nimport { isColorDark, type RGB } from '~/colors/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\n\nimport { parseThemeParams } from './parseThemeParams.js';\nimport type {\n ThemeParamsEvents,\n ThemeParamsParsed,\n ThemeParamsState,\n} from './types.js';\n\nexport class ThemeParams {\n private readonly ee = new EventEmitter<ThemeParamsEvents>();\n\n private readonly state: State<ThemeParamsState>;\n\n constructor(params: ThemeParamsParsed) {\n this.state = new State(params, this.ee);\n }\n\n /**\n * @since v6.10\n */\n get accentTextColor(): RGB | undefined {\n return this.get('accentTextColor');\n }\n\n get backgroundColor(): RGB | undefined {\n return this.get('backgroundColor');\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 * Retrieves palette color value by its name.\n * @param key - palette key name.\n */\n get(key: Extract<keyof ThemeParamsParsed, string>): RGB | undefined {\n return this.state.get(key);\n }\n\n /**\n * Returns the copy of the internal state of the current component instance.\n */\n getState(): ThemeParamsParsed {\n return this.state.clone();\n }\n\n /**\n * @since v6.10\n */\n get headerBackgroundColor(): RGB | undefined {\n return this.get('headerBackgroundColor');\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 background color.\n */\n get isDark(): boolean {\n return !this.backgroundColor || isColorDark(this.backgroundColor);\n }\n\n get linkColor(): RGB | undefined {\n return this.get('linkColor');\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n\n get secondaryBackgroundColor(): RGB | undefined {\n return this.get('secondaryBackgroundColor');\n }\n\n /**\n * @since v6.10\n */\n get sectionBackgroundColor(): RGB | undefined {\n return this.get('sectionBackgroundColor');\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 theme changes and applies them.\n * @returns Function to stop listening.\n */\n listen() {\n return on('theme_changed', (event) => {\n this.state.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 { initDataParser } from '~/init-data/index.js';\nimport { boolean, searchParams, string } from '~/parsing/index.js';\nimport { themeParamsParser } from '~/theme-params/index.js';\n\nimport type { LaunchParams } from './types.js';\n\n/**\n * Returns parser used to parse launch params.\n */\nexport function launchParamsParser() {\n return searchParams<LaunchParams>({\n botInline: {\n type: boolean().optional(),\n from: 'tgWebAppBotInline',\n },\n initData: {\n type: initDataParser().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 themeParams: {\n type: themeParamsParser(),\n from: 'tgWebAppThemeParams',\n },\n version: {\n type: string(),\n from: 'tgWebAppVersion',\n },\n }, 'LaunchParams');\n}\n","import { launchParamsParser } from './launchParamsParser.js';\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 launchParamsParser().parse(value);\n}\n","import { parseLaunchParams } from './parseLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * Attempts to extract launch parameters from the current window location hash.\n * @throws {Error} window.location.hash contains invalid data.\n */\nexport function retrieveFromLocation(): LaunchParams {\n return parseLaunchParams(window.location.hash.slice(1));\n}\n","import { getFirstNavigationEntry } from './getFirstNavigationEntry.js';\nimport { parseLaunchParams } from './parseLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * Attempts to read launch parameters using window.performance data.\n * @throws {Error} Unable to get first navigation entry.\n * @throws {Error} First navigation entry does not contain hash part.\n * @throws {TypeError} Unable to parse value.\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 const hashMatch = navigationEntry.name.match(/#(.*)/);\n if (!hashMatch) {\n throw new Error('First navigation entry does not contain hash part.');\n }\n\n return parseLaunchParams(hashMatch[1]);\n}\n","import { retrieveFromLocation } from './retrieveFromLocation.js';\nimport { retrieveFromPerformance } from './retrieveFromPerformance.js';\nimport type { LaunchParams } from './types.js';\n\n/**\n * Attempts to retrieve launch parameters using every known way.\n */\nexport function retrieveCurrent(): LaunchParams | null {\n // First of all, attempt to retrieve launch parameters from the window.performance as long as\n // this way is considered the most stable. Nevertheless, this method can return nothing in case,\n // location was changed and then page was reloaded.\n try {\n return retrieveFromPerformance();\n // eslint-disable-next-line no-empty\n } catch (e) {\n }\n\n // In case, usage of window.performance was unsuccessful, try to retrieve launch parameters\n // from the window.location.\n try {\n return retrieveFromLocation();\n // eslint-disable-next-line no-empty\n } catch (e) {\n }\n\n return null;\n}\n","import { serializeThemeParams } from '~/theme-params/index.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 botInline,\n } = value;\n\n const params = new URLSearchParams();\n\n if (initDataRaw) {\n params.set('tgWebAppData', initDataRaw);\n }\n params.set('tgWebAppPlatform', platform);\n params.set('tgWebAppThemeParams', serializeThemeParams(themeParams));\n params.set('tgWebAppVersion', version);\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 { launchParamsParser } from '~/launch-params/launchParamsParser.js';\n\nimport { serializeLaunchParams } from './serializeLaunchParams.js';\nimport type { LaunchParams } from './types.js';\n\nconst SESSION_STORAGE_KEY = 'telegram-mini-apps-launch-params';\n\n/**\n * Attempts to extract launch parameters directly from the session storage.\n * @returns Launch parameters in case, they were stored before or null, if there is no launch\n * parameters key in the session storage.\n * @throws {Error} Data stored in the session storage is invalid.\n */\nexport function retrieveFromStorage(): LaunchParams | null {\n const raw = sessionStorage.getItem(SESSION_STORAGE_KEY);\n\n return raw\n // We are not handling the error on purpose as long as we are waiting for data stored by\n // this session storage key to contain the valid launch parameters.\n ? launchParamsParser().parse(raw)\n : null;\n}\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 // TODO: We probably don't need serialize here. We used it only to correctly serialize Date\n // values which being converted strings. To solve the problem we could improve date parser\n // to allows parsing such invalid (Dates, converted to strings) values.\n sessionStorage.setItem(SESSION_STORAGE_KEY, serializeLaunchParams(value));\n}\n","import { computePageReload } from './computePageReload.js';\nimport { retrieveCurrent } from './retrieveCurrent.js';\nimport { retrieveFromStorage } from './storage.js';\nimport type { LaunchData } from './types.js';\n\n/**\n * Returns true in case, current environment is iframe.\n * @see https://stackoverflow.com/a/326076\n */\nfunction isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n\n/**\n * Computes launch data information. Extracts both previous and current launch parameters\n * to compute current list of them. Additionally, computes if page was reloaded.\n */\nexport function computeLaunchData(): LaunchData {\n // Retrieve launch parameters from the session storage. We consider this value as the launch\n // parameters saved previously, in the previous runtime session (before the page reload).\n const lpPrevious = retrieveFromStorage();\n\n // Currently used launch parameters passed to the Mini App.\n const lpCurrent = retrieveCurrent();\n\n const isPageReload = computePageReload();\n\n if (lpPrevious) {\n if (lpCurrent) {\n return {\n launchParams: lpCurrent,\n isPageReload: isIframe()\n // In iframes we should check page reload via 2 ways:\n // 1. Native one via navigation entry.\n // 2. By comparing raw init data representations, when the first step did not return\n // explicit true.\n //\n // The reason is Telegram provides the horrible way of reloading current iframes which\n // does not guarantee, that reload will be proceeded properly.\n // Issue: https://github.com/morethanwords/tweb/issues/271\n //\n // We trust isPageReload variable value only in case it is \"true\". Otherwise, it can be\n // wrong. That's why we compare raw init data raw representations, which is unstable\n // also. This will not work as expected in cases, user launches applications via\n // KeyboardButton-s which can lack of init data. So, this code will not differ reload\n // from the fresh start.\n ? isPageReload || lpPrevious.initDataRaw === lpCurrent.initDataRaw\n\n // In environments different from iframe, when we have both previous and current launch\n // parameters it is guaranteed that page was reloaded as long as session is created only\n // for the Mini App launch and will be automatically disposed after it is closed.\n : true,\n };\n }\n\n // Explicit page reload allows us to trust previously saved launch parameters.\n if (isPageReload) {\n return {\n launchParams: lpPrevious,\n isPageReload,\n };\n }\n\n // We can't trust previously saved launch parameters as long as we don't really know if\n // current session was born due to restart. It is better to throw an error.\n throw new Error('Unable to retrieve current launch parameters, which must exist.');\n }\n\n if (lpCurrent) {\n return {\n launchParams: lpCurrent,\n isPageReload: false,\n };\n }\n\n throw new Error('Unable to retrieve any launch parameters.');\n}\n","import { computeLaunchData } from './computeLaunchData.js';\nimport { saveToStorage } from './storage.js';\nimport type { LaunchData } from './types.js';\n\nconst WINDOW_KEY = 'tmajsLaunchData';\n\n/**\n * Returns launch data information. Function ignores passed options in case, it was already\n * called. It caches the last returned value.\n */\nexport function retrieveLaunchData(): LaunchData {\n // Return previously cached value.\n const cached = (window as any)[WINDOW_KEY];\n if (cached) {\n return cached;\n }\n\n // Get current launch data.\n const launchData = computeLaunchData();\n\n // To prevent the additional computation of launch data and possible break of the code\n // logic, we store this data in the window. Several calls of retrieveLaunchData will surely\n // break something.\n (window as any)[WINDOW_KEY] = launchData;\n\n // Save launch parameters in the session storage. We will need them during page reloads.\n saveToStorage(launchData.launchParams);\n\n return launchData;\n}\n","import { retrieveLaunchData } from '~/launch-params/index.js';\n\n/**\n * Returns true in case, current environment is Telegram Mini Apps.\n */\nexport function isTMA(): boolean {\n try {\n retrieveLaunchData();\n return true;\n } catch (e) {\n return false;\n }\n}\n","import { isRecord } from '~/misc/index.js';\n\ntype WithExternalNotify<T> = T & {\n external: {\n notify: (...args: any) => any;\n };\n};\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 {}>(value: T): value is WithExternalNotify<T> {\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/index.js';\n\ntype WithWebviewProxy<T> = T & {\n TelegramWebviewProxy: {\n postEvent: (...args: any) => any;\n }\n};\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 WithWebviewProxy<T> {\n return 'TelegramWebviewProxy' in value\n && isRecord(value.TelegramWebviewProxy)\n && 'postEvent' in value.TelegramWebviewProxy\n && typeof value.TelegramWebviewProxy.postEvent === 'function';\n}\n","/**\n * Returns true in case, current environment is iframe.\n * @see https://stackoverflow.com/a/326076\n */\nexport function isIframe(): boolean {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n}\n","import type { Version } from '~/version/index.js';\n\nimport type { MiniAppsMethodName } from '../methods/index.js';\n\n/**\n * Error thrown in case, unsupported method was called.\n */\nexport class MethodUnsupportedError extends Error {\n constructor(method: MiniAppsMethodName, version: Version) {\n super(`Method \"${method}\" is unsupported in the Mini Apps version ${version}.`);\n Object.setPrototypeOf(this, MethodUnsupportedError.prototype);\n }\n}\n","import type { Version } from '~/version/index.js';\n\nimport type { MiniAppsMethodName } from '../methods/index.js';\n\n/**\n * Error thrown in case, unsupported parameter was used.\n */\nexport class ParameterUnsupportedError extends Error {\n constructor(method: MiniAppsMethodName, param: string, version: Version) {\n super(`Parameter \"${param}\" in method \"${method}\" is unsupported in the Mini Apps version ${version}.`);\n Object.setPrototypeOf(this, ParameterUnsupportedError.prototype);\n }\n}\n","/**\n * Message log level.\n */\nexport type LogLevel = 'log' | 'error' | 'warn';\n\nexport class Logger {\n constructor(private readonly prefix: string, private enabled: boolean) {\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 if (!this.enabled) {\n return;\n }\n\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 // eslint-disable-next-line no-console\n console[level](`[${date}]`, this.prefix, ...args);\n }\n\n /**\n * Disables the logger.\n */\n disable() {\n this.enabled = false;\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 * Enables the logger.\n */\n enable() {\n this.enabled = true;\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 /**\n * Prints warning message into a console.\n * @param args\n */\n warn(...args: any[]): void {\n this.print('warn', ...args);\n }\n}\n","import { Logger } from '~/logger/index.js';\n\nlet currentTargetOrigin = 'https://web.telegram.org';\n\nexport const logger = new Logger('[SDK]', false);\n\n/**\n * Sets new debug mode. Enabling debug mode leads to printing\n * additional messages in console, related to the processes\n * inside the package.\n * @param value - should debug mode be enabled.\n */\nexport function setDebug(value: boolean): void {\n if (value) {\n logger.enable();\n return;\n }\n logger.disable();\n}\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 { json, string } from '~/parsing/index.js';\n\n/**\n * Extracts event data from native application event.\n */\nconst eventDataJson = json<{ eventType: string; eventData?: unknown }>({\n eventType: string(),\n eventData: (value) => value,\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 parent iframe.\n * @param eventType - event name.\n * @param eventData - event payload.\n */\nfunction emitEvent(eventType: string, eventData: unknown): void {\n window.dispatchEvent(new MessageEvent('message', {\n data: JSON.stringify({ eventType, eventData }),\n }));\n}\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 */\nfunction defineEventHandlers(): void {\n const wnd: any = window;\n\n // Prevent from duplicate event handlers definition.\n if ('TelegramGameProxy_receiveEvent' in wnd) {\n return;\n }\n\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 \"window\" object.\n let pointer = wnd;\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] = emitEvent;\n return;\n }\n\n if (!(item in pointer)) {\n pointer[item] = {};\n }\n pointer = pointer[item];\n });\n });\n}\n\n/**\n * Adds listener to window \"message\" event assuming, that this event could\n * be sent by Telegram native application. Calls passed callback with event\n * type and data.\n * @param cb - callback to call.\n */\nexport function onTelegramEvent(cb: (eventType: string, eventData: unknown) => void): void {\n // Define event handlers to make sure, message handler will work correctly.\n defineEventHandlers();\n\n // We expect Telegram to send us new event through \"message\" event.\n window.addEventListener('message', (event) => {\n try {\n const { eventType, eventData } = eventDataJson.parse(event.data);\n cb(eventType, eventData);\n } catch {\n // We ignore incorrect messages as they could be generated by any other code.\n }\n });\n}\n","import { json, string } from '~/parsing/index.js';\nimport type { RequestId } from '~/types/index.js';\n\nexport interface ClipboardTextReceivedPayload {\n /**\n * Passed during the `web_app_read_text_from_clipboard` method invocation `req_id` value.\n */\n req_id: RequestId;\n\n /**\n * Data extracted from the clipboard. The returned value will have the type `string` only in\n * the case, application has access to the clipboard.\n */\n data?: string | null;\n}\n\nexport function clipboardTextReceived() {\n return json<ClipboardTextReceivedPayload>({\n req_id: string(),\n data: (value) => (\n value === null\n ? value\n : string().optional().parse(value)\n ),\n });\n}\n","import { json, string } from '~/parsing/index.js';\nimport type { RequestId } from '~/types/index.js';\n\nexport interface CustomMethodInvokedPayload<R = unknown> {\n /**\n * Unique identifier of this invocation.\n */\n req_id: RequestId;\n /**\n * Method invocation successful result.\n */\n result?: R;\n /**\n * Method invocation error code.\n */\n error?: string;\n}\n\nexport function customMethodInvoked() {\n return json<CustomMethodInvokedPayload>({\n req_id: string(),\n result: (value) => value,\n error: string().optional(),\n });\n}\n","import { json, string } from '~/parsing/index.js';\n\nexport type InvoiceStatus =\n | 'paid'\n | 'failed'\n | 'pending'\n | 'cancelled'\n | string;\n\nexport interface InvoiceClosedPayload {\n /**\n * Passed during the `web_app_open_invoice` method invocation `slug` value.\n */\n slug: string;\n /**\n * Invoice status\n */\n status: InvoiceStatus;\n}\n\nexport function invoiceClosed() {\n return json<InvoiceClosedPayload>({\n slug: string(),\n status: string(),\n });\n}\n","import { json, string } from '~/parsing/index.js';\n\nexport type PhoneRequestedStatus = 'sent' | 'cancelled' | string;\n\nexport interface PhoneRequestedPayload {\n /**\n * Request status.\n */\n status: PhoneRequestedStatus;\n}\n\nexport function phoneRequested() {\n return json<PhoneRequestedPayload>({ status: string() });\n}\n","import { json, string } from '~/parsing/index.js';\n\nexport interface PopupClosedPayload {\n /**\n * Identifier of the clicked button. In case, the popup was closed without clicking any button,\n * this property will be omitted.\n */\n button_id?: string;\n}\n\nexport function popupClosed() {\n return json<PopupClosedPayload>({\n button_id: (value) => (\n value === null || value === undefined\n ? undefined\n : string().parse(value)\n ),\n });\n}\n","import { json, string } from '~/parsing/index.js';\n\nexport interface QrTextReceivedPayload {\n /**\n * Data extracted from the QR.\n */\n data?: string;\n}\n\nexport function qrTextReceived() {\n return json<QrTextReceivedPayload>({\n data: string().optional(),\n });\n}\n","import { json, rgb, toRecord } from '~/parsing/index.js';\nimport type { RGB } from '~/colors/index.js';\n\nexport interface ThemeChangedPayload {\n /**\n * Map where the key is a theme stylesheet key and value is the corresponding color in\n * `#RRGGBB` format.\n */\n theme_params: {\n /**\n * @since v6.10\n */\n accent_text_color?: RGB;\n bg_color?: RGB;\n button_color?: RGB;\n button_text_color?: RGB;\n /**\n * @since v6.10\n */\n destructive_text_color?: RGB;\n /**\n * @since v6.10\n */\n header_bg_color?: RGB;\n hint_color?: RGB;\n link_color?: RGB;\n secondary_bg_color?: RGB;\n /**\n * @since v6.10\n */\n section_bg_color?: RGB;\n /**\n * @since v6.10\n */\n section_header_text_color?: RGB;\n /**\n * @since v6.10\n */\n subtitle_text_color?: RGB;\n text_color?: RGB;\n [key: string]: RGB | undefined; // Future unknown palette keys.\n };\n}\n\nexport function themeChanged() {\n return json<ThemeChangedPayload>({\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}\n","import { boolean, json, number } from '~/parsing/index.js';\n\nexport interface ViewportChangedPayload {\n /**\n * The viewport height.\n */\n height: number;\n /**\n * The viewport width.\n */\n width: number;\n /**\n * Is the viewport currently expanded.\n */\n is_expanded: boolean;\n /**\n * Is the viewport current state stable and not going to change in the next moment.\n */\n is_state_stable: boolean;\n}\n\nexport function viewportChanged() {\n return json<ViewportChangedPayload>({\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}\n","import { json, string } from '~/parsing/index.js';\n\nexport type WriteAccessRequestedStatus = 'allowed' | string;\n\nexport interface WriteAccessRequestedPayload {\n /**\n * Request status.\n */\n status: WriteAccessRequestedStatus;\n}\n\nexport function writeAccessRequested() {\n return json<WriteAccessRequestedPayload>({ status: string() });\n}\n","import { EventEmitter } from '~/event-emitter/index.js';\nimport { logger } from '~/globals.js';\nimport { string } from '~/parsing/index.js';\n\nimport type { MiniAppsEventEmitter, MiniAppsEventName } from './events.js';\nimport { onTelegramEvent } from './onTelegramEvent.js';\nimport {\n clipboardTextReceived,\n customMethodInvoked,\n invoiceClosed,\n phoneRequested,\n popupClosed,\n qrTextReceived,\n themeChanged,\n viewportChanged,\n writeAccessRequested,\n} from './parsers/index.js';\n\n/**\n * Returns event emitter which could be safely used, to process events from\n * Telegram native application.\n */\nexport function createEmitter(): MiniAppsEventEmitter {\n const emitter: MiniAppsEventEmitter = new EventEmitter();\n const emit: MiniAppsEventEmitter['emit'] = (event: any, ...data: any[]) => {\n logger.log('Emitting processed event:', event, ...data);\n emitter.emit(event, ...data);\n };\n\n // Desktop version of Telegram is sometimes not sending the viewport_changed\n // event. For example, when main button 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 window.addEventListener('resize', () => {\n emit('viewport_changed', {\n width: window.innerWidth,\n height: window.innerHeight,\n is_state_stable: true,\n is_expanded: true,\n });\n });\n\n // In case, any Telegram event was received, we should prepare data before\n // passing it to emitter.\n onTelegramEvent((eventType: MiniAppsEventName | string, eventData): void => {\n logger.log('Received raw event:', eventType, eventData);\n\n try {\n switch (eventType) {\n case 'viewport_changed':\n return emit(eventType, viewportChanged().parse(eventData));\n\n case 'theme_changed':\n return emit(eventType, themeChanged().parse(eventData));\n\n case 'popup_closed':\n // FIXME: Payloads are different on different platforms.\n // Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/2\n if (\n // Sent on desktop.\n eventData === undefined\n // Sent on iOS.\n || eventData === null\n ) {\n return emit(eventType, {});\n }\n return emit(eventType, popupClosed().parse(eventData));\n\n case 'set_custom_style':\n return emit(eventType, string().parse(eventData));\n\n case 'qr_text_received':\n return emit(eventType, qrTextReceived().parse(eventData));\n\n case 'clipboard_text_received':\n return emit(eventType, clipboardTextReceived().parse(eventData));\n\n case 'invoice_closed':\n return emit(eventType, invoiceClosed().parse(eventData));\n\n case 'phone_requested':\n return emit('phone_requested', phoneRequested().parse(eventData));\n\n case 'custom_method_invoked':\n return emit('custom_method_invoked', customMethodInvoked().parse(eventData));\n\n case 'write_access_requested':\n return emit('write_access_requested', writeAccessRequested().parse(eventData));\n\n // Events which have no parameters.\n case 'main_button_pressed':\n case 'back_button_pressed':\n case 'settings_button_pressed':\n case 'scan_qr_popup_closed':\n case 'reload_iframe':\n return emit(eventType);\n\n // All other event listeners will receive unknown type of data.\n default:\n return emit(eventType as any, eventData);\n }\n } catch (cause) {\n logger.error('Error processing event:', cause);\n }\n });\n\n return emitter;\n}\n","import { createEmitter } from '~/bridge/events/createEmitter.js';\nimport type { MiniAppsEventEmitter } from '~/bridge/index.js';\n\nconst CACHED_EMITTER = 'telegram-mini-apps-cached-emitter';\n\n/**\n * Returns singleton instance of bridge EventEmitter. Also, defines\n * Telegram event handlers.\n */\nexport function singletonEmitter(): MiniAppsEventEmitter {\n const wnd: any = window;\n const cachedEmitter = wnd[CACHED_EMITTER];\n\n if (cachedEmitter === undefined) {\n wnd[CACHED_EMITTER] = createEmitter();\n }\n\n return wnd[CACHED_EMITTER];\n}\n","import type { MiniAppsEventListener, MiniAppsEventName } from './events.js';\nimport { singletonEmitter } from './singletonEmitter.js';\n\n/**\n * Removes listener from specified event.\n * @param event - event to listen.\n * @param listener - event listener.\n */\nexport function off<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n): void {\n singletonEmitter().off(event, listener);\n}\n","import type { MiniAppsEventListener, MiniAppsEventName } from './events.js';\nimport { off } from './off.js';\nimport { singletonEmitter } from './singletonEmitter.js';\n\ntype StopListening = () => void;\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 */\nexport function on<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n): StopListening {\n singletonEmitter().on(event, listener);\n return () => off(event, listener);\n}\n","import type { MiniAppsEventListener, MiniAppsEventName } from './events.js';\nimport { off } from './off.js';\nimport { singletonEmitter } from './singletonEmitter.js';\n\ntype StopListening = () => void;\n\n/**\n * Works the same as \"on\" method, but after catching the event, will remove event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\nexport function once<E extends MiniAppsEventName>(\n event: E,\n listener: MiniAppsEventListener<E>,\n): StopListening {\n singletonEmitter().once(event, listener);\n return () => off(event, listener);\n}\n","import type { MiniAppsGlobalEventListener } from './events.js';\nimport { singletonEmitter } from './singletonEmitter.js';\n\n/**\n * Removes global event listener.\n * @param listener - event listener.\n */\nexport function unsubscribe(listener: MiniAppsGlobalEventListener): void {\n singletonEmitter().unsubscribe(listener);\n}\n","import type { MiniAppsGlobalEventListener } from './events.js';\nimport { singletonEmitter } from './singletonEmitter.js';\nimport { unsubscribe } from './unsubscribe.js';\n\ntype StopListening = () => void;\n\n/**\n * Subscribes to all events sent from the native Telegram application.\n * Returns function used to remove added event listener.\n * @param listener - event listener.\n */\nexport function subscribe(listener: MiniAppsGlobalEventListener): StopListening {\n singletonEmitter().subscribe(listener);\n return () => unsubscribe(listener);\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: string, b: string): 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 {\n compareVersions,\n type Version,\n} from '~/version/index.js';\nimport type {\n MiniAppsMethodName,\n MiniAppsMethodVersionedParams,\n MiniAppsMethodWithVersionedParams,\n} from '~/bridge/methods/index.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 default:\n return true;\n }\n}\n","import type { MiniAppsMethodName } from '~/bridge/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport { supports } from './supports.js';\nimport type { SupportsFunc } from './types.js';\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 createSupportsFunc<M extends string>(\n version: Version,\n schema: Record<M, MiniAppsMethodName>,\n): SupportsFunc<M> {\n return (method) => supports(schema[method], version);\n}\n","import type { MiniAppsMethodVersionedParams, MiniAppsMethodWithVersionedParams } from '~/bridge/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport { supports } from './supports.js';\nimport type { SupportsFunc } from './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 createSupportsParamFunc<P extends string>(\n version: Version,\n schema: Record<P, HasCheckSupportMethodTuple>,\n): SupportsFunc<P> {\n return (method) => {\n const [tmaMethod, param] = schema[method];\n\n return supports(tmaMethod, param, version);\n };\n}\n","import type {\n MiniAppsEmptyMethodName,\n MiniAppsMethodName,\n MiniAppsMethodParams,\n MiniAppsNonEmptyMethodName,\n} from './methods.js';\nimport { logger, targetOrigin as globalTargetOrigin } from '../../globals.js';\nimport {\n hasExternalNotify,\n hasWebviewProxy,\n isIframe,\n} from '../env/index.js';\n\ninterface PostEventOptions {\n /**\n * Origin used while posting message. This option is only used in case,\n * current environment is browser (Web version of Telegram) and could\n * 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 * Sends event to native application which launched Mini App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param params - event parameters.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current environment and possible way to send event.\n */\nexport function postEvent<E extends MiniAppsNonEmptyMethodName>(\n eventType: E,\n params: MiniAppsMethodParams<E>,\n options?: PostEventOptions,\n): void;\n\n/**\n * Sends event to native application which launched Mini App. This function\n * accepts only events, which require arguments.\n * @param eventType - event name.\n * @param options - posting options.\n * @throws {Error} Bridge could not determine current environment and possible way to send event.\n */\nexport function postEvent(eventType: MiniAppsEmptyMethodName, options?: PostEventOptions): 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 = globalTargetOrigin() } = postOptions;\n\n logger.log(`Calling method \"${eventType}\"`, eventData);\n\n // Telegram Web.\n if (isIframe()) {\n window.parent.postMessage(JSON.stringify({\n eventType,\n eventData,\n }), 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 new Error(\n 'Unable to determine current environment and possible way to send event.',\n );\n}\n","import { isRecord } from '~/misc/index.js';\nimport { supports } from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport { type PostEvent, postEvent } from './postEvent.js';\nimport { MethodUnsupportedError, ParameterUnsupportedError } from '../errors/index.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 {MethodUnsupportedError} Method is unsupported.\n * @throws {ParameterUnsupportedError} Method parameter is 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 new MethodUnsupportedError(method, 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 new ParameterUnsupportedError(method, validateParam, version);\n }\n }\n\n return postEvent(method, params);\n };\n}\n","export class TimeoutError extends Error {\n constructor(timeout: number) {\n super(`Async call timeout exceeded. Timeout: ${timeout}`);\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n","import { TimeoutError } from './TimeoutError.js';\n\n/**\n * Returns true in case, passed value is TimeoutError.\n * @param value - checked value.\n */\nexport function isTimeoutError(value: unknown): value is TimeoutError {\n return value instanceof TimeoutError;\n}\n","/**\n * Awaits for specified amount of time.\n * @param duration - duration to await.\n */\nexport function sleep(duration: number): Promise<void> {\n // eslint-disable-next-line no-await-in-loop,@typescript-eslint/no-loop-func\n return new Promise((res) => {\n setTimeout(res, duration);\n });\n}\n","import { TimeoutError } from './TimeoutError.js';\n\n/**\n * Creates promise which rejects after timeout milliseconds.\n * @param timeout - timeout in milliseconds.\n */\nfunction createTimeoutPromise(timeout: number): Promise<never> {\n return new Promise((_, rej) => {\n setTimeout(rej, timeout, new TimeoutError(timeout));\n });\n}\n\n/**\n * Accepts specified function and instantly executes. It waits for timeout milliseconds for\n * it to complete and throws an error in case, deadline was reached.\n * @param func - function to execute.\n * @param timeout - completion timeout.\n */\nexport function withTimeout<T>(func: () => Promise<T>, timeout: number): Promise<T> {\n return Promise.race([\n func(),\n createTimeoutPromise(timeout),\n ]);\n}\n","import { isRecord } from '~/misc/index.js';\nimport { withTimeout } from '~/timeout/index.js';\nimport type { And, ExecuteWithOptions, If, IsNever } from '~/types/index.js';\n\nimport {\n type MiniAppsEventHasParams,\n type MiniAppsEventName,\n type MiniAppsEventParams,\n on,\n} from './events/index.js';\nimport {\n type MiniAppsEmptyMethodName,\n type MiniAppsMethodAcceptParams,\n type MiniAppsMethodName,\n type MiniAppsMethodParams,\n type MiniAppsNonEmptyMethodName,\n postEvent as defaultPostEvent,\n} from './methods/index.js';\n\n/**\n * Names of methods, which require passing \"req_id\" parameter.\n */\ntype MethodWithRequestId = {\n [M in MiniAppsMethodName]: If<\n And<\n MiniAppsMethodAcceptParams<M>,\n MiniAppsMethodParams<M> extends { req_id: string } ? true : false\n >,\n M,\n never\n >;\n}[MiniAppsMethodName];\n\n/**\n * Names of events, which contain \"req_id\" parameter.\n */\ntype EventWithRequestId = {\n [E in MiniAppsEventName]: If<\n And<MiniAppsEventHasParams<E>, MiniAppsEventParams<E> extends {\n req_id: string\n } ? true : false>,\n E,\n never\n >;\n}[MiniAppsEventName];\n\nexport interface RequestOptions extends ExecuteWithOptions {\n}\n\nexport interface RequestOptionsAdvanced<EventPayload> extends RequestOptions {\n /**\n * Should return true in case, this event should be captured. If not specified,\n * request is not skipping captured events.\n */\n capture?: If<IsNever<EventPayload>, () => boolean, (payload: EventPayload) => boolean>;\n}\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, event with specified in method request identifier\n * was captured.\n * @param method - method to execute.\n * @param params - method parameters.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<M extends MethodWithRequestId, E extends EventWithRequestId>(\n method: M,\n params: MiniAppsMethodParams<M>,\n event: E | E[],\n options?: RequestOptions,\n): Promise<MiniAppsEventParams<E>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute.\n * @param event - event or events to listen.\n * @param options - additional execution options.\n */\nexport function request<M extends MiniAppsEmptyMethodName, E extends MiniAppsEventName>(\n method: M,\n event: E | E[],\n options?: RequestOptionsAdvanced<MiniAppsEventParams<E>>,\n): Promise<MiniAppsEventParams<E>>;\n\n/**\n * Calls specified TWA method and captures one of the specified events. Returns promise\n * which will be resolved in case, specified event was captured.\n * @param method - method to execute\n * @param params - method parameters.\n * @param event - event or events to listen\n * @param options - additional execution options.\n */\nexport function request<M extends MiniAppsNonEmptyMethodName, E extends MiniAppsEventName>(\n method: M,\n params: MiniAppsMethodParams<M>,\n event: E | E[],\n options?: RequestOptionsAdvanced<MiniAppsEventParams<E>>,\n): Promise<MiniAppsEventParams<E>>;\n\nexport function request(\n method: MiniAppsMethodName,\n eventOrParams: MiniAppsEventName | MiniAppsEventName[] | MiniAppsEventParams<any>,\n eventOrOptions?:\n | MiniAppsEventName\n | MiniAppsEventName[]\n | RequestOptions\n | RequestOptionsAdvanced<any>,\n options?: RequestOptions | RequestOptionsAdvanced<any>,\n): Promise<any> {\n let executionOptions: RequestOptions | RequestOptionsAdvanced<any> | undefined;\n let methodParams: MiniAppsEventParams<any> | undefined;\n let events: MiniAppsEventName[];\n let requestId: string | undefined;\n\n if (typeof eventOrParams === 'string' || Array.isArray(eventOrParams)) {\n // Override: [method, event, options?]\n events = Array.isArray(eventOrParams) ? eventOrParams : [eventOrParams] as MiniAppsEventName[];\n executionOptions = eventOrOptions as (RequestOptionsAdvanced<any> | undefined);\n } else {\n // Override: [method, params, event, options?]\n methodParams = eventOrParams as MiniAppsEventParams<any>;\n events = Array.isArray(eventOrOptions)\n ? eventOrOptions\n : [eventOrOptions] as MiniAppsEventName[];\n executionOptions = options;\n }\n\n // In case, method parameters were passed, and they contained request identifier, we should store\n // it and wait for the event with this identifier to occur.\n if (isRecord(methodParams) && typeof methodParams.req_id === 'string') {\n requestId = methodParams.req_id;\n }\n\n const { postEvent = defaultPostEvent, timeout } = executionOptions || {};\n const capture = executionOptions && 'capture' in executionOptions\n ? executionOptions.capture\n : null;\n\n const execute = () => {\n return new Promise((res, rej) => {\n // Iterate over each event and create event listener.\n const stoppers = events.map((ev) => on(ev, (data?) => {\n // If request identifier was specified, we are waiting for event with the same value\n // to occur.\n if (requestId && (!isRecord(data) || data.req_id !== requestId)) {\n return;\n }\n\n if (typeof capture === 'function' && !capture(data)) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-use-before-define\n stopListening();\n res(data);\n }));\n\n // Function which removes all event listeners.\n const stopListening = () => stoppers.forEach((stop) => stop());\n\n try {\n // We are wrapping this call in try catch, because it can throw errors in case,\n // compatibility check was enabled. We want an error to be captured by promise, not by\n // another one external try catch.\n postEvent(method as any, methodParams);\n } catch (e) {\n stopListening();\n rej(e);\n }\n });\n };\n\n return typeof timeout === 'number' ? withTimeout(execute, timeout) : execute();\n}\n","import type { ExecuteWithOptions } from '~/types/index.js';\n\nimport type { CustomMethodName, CustomMethodParams } from './methods/index.js';\nimport { request } from './request.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 */\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 */\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 { result, error } = await request(\n 'web_app_invoke_custom_method',\n {\n method,\n params,\n req_id: requestId,\n },\n 'custom_method_invoked',\n options,\n );\n\n if (error) {\n throw new Error(error);\n }\n\n return result;\n}\n","import {\n off,\n on,\n type PostEvent,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport { createSupportsFunc, type SupportsFunc } from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport type { BackButtonEvents, BackButtonState } from './types.js';\n\ntype Emitter = EventEmitter<BackButtonEvents>;\n\n/**\n * Class which controls the back button displayed in the header of the Mini App in the Telegram\n * interface. It is mostly used in case, when you want to provide a way to go bach in routing\n * history or \"rollback\" some action.\n */\nexport class BackButton {\n private readonly ee: Emitter = new EventEmitter();\n\n private readonly state: State<BackButtonState>;\n\n constructor(\n isVisible: boolean,\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isVisible }, this.ee);\n this.supports = createSupportsFunc(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.state.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.state.get('isVisible');\n }\n\n /**\n * Hides the BackButton.\n */\n hide(): void {\n this.isVisible = false;\n }\n\n /**\n * Adds event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('back_button_pressed', listener)\n : this.ee.on(event, listener)\n );\n\n /**\n * Removes event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('back_button_pressed', listener)\n : this.ee.off(event, listener)\n );\n\n /**\n * Shows the BackButton.\n */\n show(): void {\n this.isVisible = true;\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'show' | 'hide'>;\n}\n","/**\n * Inserts a space between a and b in case both of them are\n * non-empty strings.\n * @param a\n * @param b\n */\nfunction space(a: string, b: string): string {\n return a + (a.length > 0 && b.length > 0 ? ` ${b}` : b);\n}\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. All other values are ignored.\n *\n * You can find this function to similar one from package {@link https://www.npmjs.com/package/classnames|classnames}.\n * @param values - values array.\n */\nexport function classNames(...values: any[]): string {\n return values.reduce<string>((acc, value) => {\n let formattedValue = '';\n\n if (typeof value === 'string') {\n formattedValue = value;\n } else if (typeof value === 'object' && value !== null) {\n formattedValue = Object\n .entries(value)\n .reduce<string>((valueAcc, [className, enable]) => (enable ? space(valueAcc, className) : valueAcc), '');\n }\n\n return space(acc, formattedValue);\n }, '');\n}\n","import { classNames } from './classNames.js';\n\ntype FilterUnion<U> = Exclude<U, number | string | null | undefined | any[] | boolean>;\n\n/**\n * Returns union keys removing those, which values are not strings.\n */\ntype UnionFilteredKeys<U> = U extends U\n ? {\n [K in keyof U]: U[K] extends string ? K : never\n }[keyof U]\n : never;\n\n/**\n * Returns union required keys.\n */\ntype UnionRequiredKeys<U> = U extends U\n ? {\n [K in UnionFilteredKeys<U>]-?: ({} extends { [P in K]: U[K] } ? never : K)\n }[UnionFilteredKeys<U>]\n : never;\n\n/**\n * Returns union optional keys.\n */\ntype UnionOptionalKeys<U> = Exclude<UnionFilteredKeys<U>, UnionRequiredKeys<U>>;\n\ntype MergeClassNames<Tuple extends any[]> = Tuple[number] extends infer Union\n ? FilterUnion<Union> extends infer UnionFiltered\n ? {\n [K in UnionRequiredKeys<UnionFiltered>]: string;\n } & {\n [K in UnionOptionalKeys<UnionFiltered>]?: string;\n }\n : never\n : never;\n\n/**\n * Returns true in case, passed value is Record.\n * @param value\n */\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(null);\n}\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 (!isObject(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 > 0) {\n (acc as any)[key] = className;\n }\n });\n\n return acc;\n }, {} as MergeClassNames<T>);\n}\n","import { type PostEvent, postEvent as defaultPostEvent } from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\n\nimport type {\n ClosingBehaviorEvents,\n ClosingBehaviorState,\n} from './types.js';\n\n/**\n * Component responsible for controlling current closing confirmation\n * status.\n */\nexport class ClosingBehavior {\n private readonly ee = new EventEmitter<ClosingBehaviorEvents>();\n\n private readonly state: State<ClosingBehaviorState>;\n\n constructor(\n isConfirmationNeeded: boolean,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isConfirmationNeeded }, this.ee);\n }\n\n private set isConfirmationNeeded(value: boolean) {\n this.state.set('isConfirmationNeeded', value);\n this.postEvent('web_app_setup_closing_behavior', { need_confirmation: value });\n }\n\n /**\n * Returns true, if the confirmation dialog enabled while the user is trying\n * to close the Mini App.\n */\n get isConfirmationNeeded(): boolean {\n return this.state.get('isConfirmationNeeded');\n }\n\n /**\n * Disables the confirmation dialog while the user is trying to close the\n * Mini App.\n */\n disableConfirmation(): void {\n this.isConfirmationNeeded = false;\n }\n\n /**\n * Enables the confirmation dialog while the user is trying to close the\n * Mini App.\n */\n enableConfirmation(): void {\n this.isConfirmationNeeded = true;\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n}\n","import {\n invokeCustomMethod,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport {\n array,\n json,\n string,\n} from '~/parsing/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { CreateRequestIdFunc, ExecuteWithTimeout } from '~/types/index.js';\nimport type { Version } from '~/version/index.js';\n\nfunction objectFromKeys<K extends string, V>(keys: K[], value: V): Record<K, V> {\n return keys.reduce<Record<K, V>>((acc, key) => {\n acc[key] = value;\n return acc;\n }, {} as Record<K, V>);\n}\n\nexport class CloudStorage {\n constructor(\n version: Version,\n private readonly createRequestId: CreateRequestIdFunc,\n private readonly postEvent = defaultPostEvent,\n ) {\n this.supports = createSupportsFunc(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 === 0) {\n return;\n }\n\n await invokeCustomMethod(\n 'deleteStorageValues',\n { keys },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\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 const result = await invokeCustomMethod(\n 'getStorageKeys',\n {},\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n );\n\n return array().of(string()).parse(result);\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>(\n keys: K[],\n options?: ExecuteWithTimeout,\n ): 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 === 0) {\n return objectFromKeys<string, string>(keys, '');\n }\n\n const schema = json(\n objectFromKeys(keys, string()),\n );\n const result = await invokeCustomMethod(\n 'getStorageValues',\n { keys },\n this.createRequestId(),\n { ...options, postEvent: this.postEvent },\n ).then((data) => schema.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 /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<\n | 'delete'\n | 'get'\n | 'getKeys'\n | 'set'\n >;\n}\n","import {\n type ImpactHapticFeedbackStyle,\n type NotificationHapticFeedbackType,\n type PostEvent,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\n/**\n * Class which controls haptic feedback. It allows calling different types of\n * haptic notifications which usually occur after user interaction with\n * application.\n */\nexport class HapticFeedback {\n constructor(\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.supports = createSupportsFunc(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 /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'impactOccurred' | 'notificationOccurred' | 'selectionChanged'>;\n}\n","import { on } from '~/bridge/index.js';\n\n/**\n * Creates style html element which contains styles sent from the Telegram application.\n */\nexport function catchCustomStyles(): void {\n const element = document.createElement('style');\n element.id = 'telegram-custom-styles';\n document.head.appendChild(element);\n\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 element.innerHTML = html;\n });\n}\n","import type { HeaderColorKey } from '~/bridge/index.js';\nimport type { RGB } from '~/colors/index.js';\n\n// fixme: components-related. Should probably rename\n\n/**\n * Describes storage keys and according values.\n */\ninterface StorageParams {\n 'back-button': {\n isVisible: boolean\n };\n 'closing-behavior': {\n isConfirmationNeeded: boolean;\n };\n 'main-button': {\n backgroundColor: RGB;\n isEnabled: boolean;\n isLoaderVisible: boolean;\n isVisible: boolean;\n text: string;\n textColor: RGB;\n };\n 'settings-button': {\n isVisible: boolean\n };\n viewport: {\n height: number;\n isExpanded: boolean;\n stableHeight: number;\n width: number;\n };\n 'mini-app': {\n backgroundColor: RGB;\n headerColor: HeaderColorKey | RGB;\n };\n}\n\n/**\n * Key which could be used to store data in storage.\n */\ntype StorageKey = keyof StorageParams;\n\n/**\n * Formats key which could be used during the communication with the storage.\n * @param key - session storage key.\n */\nfunction formatKey(key: StorageKey): string {\n return `telegram-mini-apps-${key}`;\n}\n\n/**\n * Saves value in sessionStorage.\n * @param key - storage key.\n * @param value - storage value.\n */\nexport function saveStorageValue<K extends StorageKey>(key: K, value: StorageParams[K]): void {\n sessionStorage.setItem(formatKey(key), JSON.stringify(value));\n}\n\n/**\n * Extracts value from the sessionStorage.\n * @param key - storage key.\n */\nexport function getStorageValue<K extends StorageKey>(key: K): StorageParams[K] | null {\n const value = sessionStorage.getItem(formatKey(key));\n\n return value ? JSON.parse(value) : null;\n}\n","import { BackButton } from '~/back-button/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\n\n/**\n * Creates BackButton instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param version - platform version.\n * @param postEvent - Bridge postEvent function\n */\nexport function createBackButton(\n isPageReload: boolean,\n version: string,\n postEvent: PostEvent,\n): BackButton {\n const { isVisible = false } = isPageReload ? getStorageValue('back-button') || {} : {};\n const component = new BackButton(isVisible, version, postEvent);\n\n component.on('change', () => {\n saveStorageValue('back-button', { isVisible: component.isVisible });\n });\n\n return component;\n}\n","import { ClosingBehavior } from '~/closing-behavior/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\n\n/**\n * Creates ClosingBehaviour instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param postEvent - Bridge postEvent function\n */\nexport function createClosingBehavior(\n isPageReload: boolean,\n postEvent: PostEvent,\n): ClosingBehavior {\n const { isConfirmationNeeded = false } = isPageReload ? getStorageValue('closing-behavior') || {} : {};\n\n const component = new ClosingBehavior(isConfirmationNeeded, postEvent);\n\n component.on('change', () => saveStorageValue('closing-behavior', {\n isConfirmationNeeded: component.isConfirmationNeeded,\n }));\n\n return component;\n}\n","import {\n off,\n on,\n type PostEvent,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport type { RGB } from '~/colors/index.js';\n\nimport type {\n MainButtonEvents,\n MainButtonParams,\n MainButtonProps,\n MainButtonState,\n} from './types.js';\n\ntype Emitter = EventEmitter<MainButtonEvents>;\n\n/**\n * Controls the main button, which is displayed at the bottom\n * of the Mini App in the Telegram interface.\n */\nexport class MainButton {\n private readonly ee: Emitter = new EventEmitter();\n\n private readonly state: State<MainButtonState>;\n\n private readonly postEvent: PostEvent;\n\n constructor(props: MainButtonProps) {\n const {\n postEvent = defaultPostEvent,\n text,\n textColor,\n backgroundColor,\n isEnabled,\n isVisible,\n isLoaderVisible,\n } = props;\n\n this.postEvent = postEvent;\n this.state = new State({\n backgroundColor,\n isEnabled,\n isVisible,\n isLoaderVisible,\n text,\n textColor,\n }, this.ee);\n }\n\n /**\n * Sends current local state to 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 behaviour 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.backgroundColor,\n text_color: this.textColor,\n });\n }\n\n private set isEnabled(isEnabled: boolean) {\n this.setParams({ isEnabled });\n }\n\n /**\n * True if the Main Button is currently enabled.\n */\n get isEnabled(): boolean {\n return this.state.get('isEnabled');\n }\n\n private set isLoaderVisible(isLoaderVisible: boolean) {\n this.setParams({ isLoaderVisible });\n }\n\n /**\n * True if the Main Button loader is currently visible.\n */\n get isLoaderVisible(): boolean {\n return this.state.get('isLoaderVisible');\n }\n\n private set isVisible(isVisible: boolean) {\n this.setParams({ isVisible });\n }\n\n /**\n * True if the Main Button is currently visible.\n */\n get isVisible(): boolean {\n return this.state.get('isVisible');\n }\n\n /**\n * The Main Button background color.\n */\n get backgroundColor(): RGB {\n return this.state.get('backgroundColor');\n }\n\n /**\n * The Main Button text.\n */\n get text(): string {\n return this.state.get('text');\n }\n\n /**\n * The Main Button text color.\n */\n get textColor(): RGB {\n return this.state.get('textColor');\n }\n\n /**\n * Disables the Main Button.\n */\n disable(): this {\n // FIXME: This method does not work on Android. Event \"main_button_pressed\"\n // keeps getting received even in case, button is disabled.\n // Issue: https://github.com/Telegram-Mini-Apps/documentation/issues/1\n this.isEnabled = false;\n return this;\n }\n\n /**\n * Enables the Main Button.\n */\n enable(): this {\n this.isEnabled = true;\n return this;\n }\n\n /**\n * Hides the Main Button.\n */\n hide(): this {\n this.isVisible = false;\n return this;\n }\n\n /**\n * Hides the Main Button loader.\n */\n hideLoader(): this {\n this.isLoaderVisible = false;\n return this;\n }\n\n /**\n * Adds new event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n on: Emitter['on'] = (event, listener) => (\n // FIXME: Event 'main_button_pressed' is still being received on Android\n // even if the main button is disabled.\n // Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/3\n event === 'click'\n ? on('main_button_pressed', listener)\n : this.ee.on(event, listener)\n );\n\n /**\n * Removes event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('main_button_pressed', listener)\n : this.ee.off(event, listener)\n );\n\n /**\n * Shows the Main Button. Note that opening the Mini App from the attachment menu hides the\n * main button until the user interacts with the Mini App interface.\n */\n show(): this {\n this.isVisible = true;\n return this;\n }\n\n /**\n * A method to show a loading indicator on the Main Button. It is recommended to display\n * loader if the action tied to the button may take a long time.\n */\n showLoader(): this {\n this.isLoaderVisible = true;\n return this;\n }\n\n /**\n * Sets new Main Button text. Minimal length for text is 1 symbol, and maximum is 64 symbols.\n * @param text - new text.\n */\n setText(text: string): this {\n return this.setParams({ text });\n }\n\n /**\n * Sets 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 backgroundColor - color to set.\n */\n setBackgroundColor(backgroundColor: RGB): this {\n return this.setParams({ backgroundColor });\n }\n\n /**\n * Allows setting multiple Main Button parameters.\n * @param params - Main Button parameters.\n */\n setParams(params: MainButtonParams): this {\n this.state.set(params);\n this.commit();\n return this;\n }\n}\n","import { MainButton } from '~/main-button/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\nimport type { RGB } from '~/colors/index.js';\n\n/**\n * Creates MainButton instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param backgroundColor - background color.\n * @param textColor - text color.\n * @param postEvent - Bridge postEvent function\n */\nexport function createMainButton(\n isPageReload: boolean,\n backgroundColor: RGB,\n textColor: RGB,\n postEvent: PostEvent,\n): MainButton {\n const {\n backgroundColor: stateBackgroundColor = backgroundColor,\n isEnabled = false,\n isVisible = false,\n isLoaderVisible = false,\n textColor: stateTextColor = textColor,\n text = '',\n } = isPageReload ? getStorageValue('main-button') || {} : {};\n\n const component = new MainButton({\n backgroundColor: stateBackgroundColor,\n isEnabled,\n isLoaderVisible,\n isVisible,\n postEvent,\n text,\n textColor: stateTextColor,\n });\n\n const saveState = () => saveStorageValue('main-button', {\n backgroundColor: component.backgroundColor,\n isEnabled: component.isEnabled,\n isLoaderVisible: component.isLoaderVisible,\n isVisible: component.isVisible,\n text: component.text,\n textColor: component.textColor,\n });\n\n component.on('change', saveState);\n\n return component;\n}\n","import { date, json, number, searchParams, string } from '~/parsing/index.js';\n\nimport type { RequestedContact } from './types.js';\n\nexport const contactParser = searchParams<RequestedContact>({\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});\n","import {\n invokeCustomMethod,\n type PhoneRequestedStatus,\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n type SwitchInlineQueryChatType,\n type WriteAccessRequestedStatus,\n} from '~/bridge/index.js';\nimport {\n isColorDark,\n isRGB,\n type RGB,\n} from '~/colors/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport {\n createSupportsFunc,\n createSupportsParamFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport { sleep, withTimeout } from '~/timeout/index.js';\nimport type { CreateRequestIdFunc, ExecuteWithTimeout } from '~/types/index.js';\n\nimport { contactParser } from './contactParser.js';\nimport type {\n MiniAppEvents,\n MiniAppHeaderColor, MiniAppProps,\n MiniAppState, RequestedContact,\n} from './types.js';\n\n/**\n * Provides common Mini Apps functionality not covered by other system components.\n */\nexport class MiniApp {\n private readonly ee = new EventEmitter<MiniAppEvents>();\n\n private readonly state: State<MiniAppState>;\n\n private readonly botInline: boolean;\n\n private readonly postEvent: PostEvent;\n\n private readonly createRequestId: CreateRequestIdFunc;\n\n private requestingPhoneAccess = false;\n\n private requestingWriteAccess = false;\n\n constructor(props: MiniAppProps) {\n const {\n postEvent = defaultPostEvent,\n headerColor,\n backgroundColor,\n version,\n botInline,\n createRequestId,\n } = props;\n\n const isSupported = createSupportsFunc(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.postEvent = postEvent;\n this.botInline = botInline;\n this.createRequestId = createRequestId;\n this.supports = (method) => {\n if (!isSupported(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 if (method === 'switchInlineQuery' && !botInline) {\n return false;\n }\n return true;\n };\n\n this.state = new State({ backgroundColor, headerColor }, this.ee);\n this.supportsParam = createSupportsParamFunc(version, {\n 'setHeaderColor.color': ['web_app_set_header_color', 'color'],\n });\n }\n\n /**\n * Attempts to get requested contact.\n */\n private async getRequestedContact(): Promise<RequestedContact> {\n return invokeCustomMethod(\n 'getRequestedContact',\n {},\n this.createRequestId(),\n {\n postEvent: this.postEvent,\n timeout: 10000,\n },\n )\n .then((data) => contactParser.parse(data));\n }\n\n /**\n * The Mini App background color.\n */\n get backgroundColor(): RGB {\n return this.state.get('backgroundColor');\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. Could either be a header color key or RGB color.\n */\n get headerColor(): MiniAppHeaderColor {\n return this.state.get('headerColor');\n }\n\n /**\n * True if 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 recognized as dark.\n */\n get isDark(): boolean {\n return isColorDark(this.backgroundColor);\n }\n\n /**\n * True if phone access is currently being requested.\n */\n get isRequestingPhoneAccess(): boolean {\n return this.requestingPhoneAccess;\n }\n\n /**\n * True if write access is currently being requested.\n */\n get isRequestingWriteAccess(): boolean {\n return this.requestingWriteAccess;\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\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 (e) { /* 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 return withTimeout(async () => {\n // We are trying to retrieve the requested contact until deadline was reached.\n while (Date.now() < deadlineAt) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await this.getRequestedContact();\n } catch (e) { /* empty */\n }\n\n // Sleep for some time.\n // eslint-disable-next-line no-await-in-loop\n await sleep(sleepTime);\n\n // Increase the sleep time not to kill the backend service.\n sleepTime += 50;\n }\n\n throw new Error('Unable to retrieve requested contact.');\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 requestPhoneAccess(options: ExecuteWithTimeout = {}): Promise<PhoneRequestedStatus> {\n if (this.requestingPhoneAccess) {\n throw new Error('Phone access is already being requested.');\n }\n this.requestingPhoneAccess = true;\n\n return request('web_app_request_phone', 'phone_requested', {\n ...options,\n postEvent: this.postEvent,\n })\n .then((data) => data.status)\n .finally(() => {\n this.requestingPhoneAccess = false;\n });\n }\n\n /**\n * Requests write message access to current user.\n * @param options - additional options.\n */\n requestWriteAccess(options: ExecuteWithTimeout = {}): Promise<WriteAccessRequestedStatus> {\n if (this.requestingWriteAccess) {\n throw new Error('Write access is already being requested.');\n }\n this.requestingWriteAccess = true;\n\n return request('web_app_request_write_access', 'write_access_requested', {\n ...options,\n postEvent: this.postEvent,\n })\n .then((data) => data.status)\n .finally(() => {\n this.requestingWriteAccess = false;\n });\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 === 0 || 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 * @param color - color key or RGB color.\n */\n setHeaderColor(color: MiniAppHeaderColor): void {\n // FIXME: Has no effect on desktop, works incorrectly on Android.\n // Issues:\n // https://github.com/Telegram-Mini-Apps/tma.js/issues/9\n // https://github.com/Telegram-Mini-Apps/tma.js/issues/8\n this.postEvent('web_app_set_header_color', isRGB(color) ? { color } : { color_key: color });\n this.state.set('headerColor', color);\n }\n\n /**\n * Updates current Mini App background color.\n * @param color - RGB color.\n */\n setBackgroundColor(color: RGB): void {\n // FIXME: Has no effect on desktop, works incorrectly in Android.\n // Issues:\n // https://github.com/Telegram-Mini-Apps/tma.js/issues/9\n // https://github.com/Telegram-Mini-Apps/tma.js/issues/8\n this.postEvent('web_app_set_background_color', { color });\n this.state.set('backgroundColor', color);\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<\n | 'requestWriteAccess'\n | 'requestPhoneAccess'\n | 'switchInlineQuery'\n | 'setHeaderColor'\n | 'setBackgroundColor'\n >;\n\n /**\n * Checks if specified method parameter is supported by current component.\n */\n supportsParam: SupportsFunc<'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', {\n query: text,\n chat_types: chatTypes,\n });\n }\n}\n","import { MiniApp } from '~/mini-app/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\nimport type { RGB } from '~/colors/index.js';\nimport type { CreateRequestIdFunc } from '~/types/index.js';\nimport type { Version } from '~/version/index.js';\n\n/**\n * Creates MiniApp instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param backgroundColor - web app background color.\n * @param version - platform version.\n * @param botInline - is Mini App launched in inline mode.\n * @param createRequestId - function which generates request identifiers.\n * @param postEvent - Bridge postEvent function\n */\nexport function createMiniApp(\n isPageReload: boolean,\n backgroundColor: RGB,\n version: Version,\n botInline: boolean,\n createRequestId: CreateRequestIdFunc,\n postEvent: PostEvent,\n): MiniApp {\n const {\n backgroundColor: stateBackgroundColor = backgroundColor,\n headerColor = 'bg_color',\n } = isPageReload ? getStorageValue('mini-app') || {} : {};\n\n const component = new MiniApp({\n headerColor,\n backgroundColor: stateBackgroundColor,\n version,\n botInline,\n createRequestId,\n postEvent,\n });\n\n const saveState = () => saveStorageValue('mini-app', {\n backgroundColor: component.backgroundColor,\n headerColor: component.headerColor,\n });\n\n component.on('change', saveState);\n\n return component;\n}\n","import type { CreateRequestIdFunc } from '~/types/index.js';\n\n/**\n * Creates function which generated request identifiers.\n */\nexport function createRequestIdGenerator(): CreateRequestIdFunc {\n let requestId = 0;\n\n return () => {\n requestId += 1;\n return requestId.toString();\n };\n}\n","import {\n off,\n on,\n type PostEvent,\n postEvent as defaultPostEvent,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport { createSupportsFunc, type SupportsFunc } from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport type { SettingsButtonEvents, SettingsButtonState } from './types.js';\n\ntype Emitter = EventEmitter<SettingsButtonEvents>;\n\nexport class SettingsButton {\n private readonly ee: Emitter = new EventEmitter();\n\n private readonly state: State<SettingsButtonState>;\n\n constructor(\n isVisible: boolean,\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isVisible }, this.ee);\n this.supports = createSupportsFunc(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.state.set('isVisible', visible);\n this.postEvent('web_app_setup_settings_button', { is_visible: visible });\n }\n\n /**\n * True if SettingsButton is currently visible.\n */\n get isVisible(): boolean {\n return this.state.get('isVisible');\n }\n\n /**\n * Hides the SettingsButton.\n */\n hide(): void {\n this.isVisible = false;\n }\n\n /**\n * Adds event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n on: Emitter['on'] = (event, listener) => (\n event === 'click'\n ? on('settings_button_pressed', listener)\n : this.ee.on(event, listener)\n );\n\n /**\n * Removes event listener.\n * @param event - event name.\n * @param listener - event listener.\n */\n off: Emitter['off'] = (event, listener) => (\n event === 'click'\n ? off('settings_button_pressed', listener)\n : this.ee.off(event, listener)\n );\n\n /**\n * Shows the SettingsButton.\n */\n show(): void {\n this.isVisible = true;\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'show' | 'hide'>;\n}\n","import { SettingsButton } from '~/settings-button/index.js';\nimport { getStorageValue, saveStorageValue } from '~/storage.js';\nimport type { PostEvent } from '~/bridge/index.js';\n\n/**\n * Creates SettingsButton instance using last locally saved data also saving each state in\n * the storage.\n * @param isPageReload - was current page reloaded.\n * @param version - platform version.\n * @param postEvent - Bridge postEvent function\n */\nexport function createSettingsButton(\n isPageReload: boolean,\n version: string,\n postEvent: PostEvent,\n): SettingsButton {\n const { isVisible = false } = isPageReload ? getStorageValue('settings-button') || {} : {};\n const component = new SettingsButton(isVisible, version, postEvent);\n\n component.on('change', () => {\n saveStorageValue('settings-button', { isVisible: component.isVisible });\n });\n\n return component;\n}\n","import { ThemeParams, type ThemeParamsParsed } from '~/theme-params/index.js';\n\n/**\n * Creates synced instance of ThemeParams.\n * @param params - theme parameters.\n */\nexport function createThemeParams(params: ThemeParamsParsed): ThemeParams {\n const themeParams = new ThemeParams(params);\n themeParams.listen();\n return themeParams;\n}\n","import type { Platform } from '~/types/index.js';\n\n/**\n * Returns true if specified platform has stable viewport. Stable means not changing from time to\n * time.\n * @param platform - platform identifier.\n */\nexport function isStableViewportPlatform(platform: Platform): boolean {\n return ['macos', 'tdesktop', 'unigram', 'web', 'weba'].includes(platform);\n}\n","import { request, type RequestOptions } from '~/bridge/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(options?: RequestOptions): Promise<RequestViewportResult> {\n const data = await request('web_app_request_viewport', 'viewport_changed', options);\n\n return {\n height: data.height,\n width: data.width,\n isExpanded: data.is_expanded,\n isStateStable: data.is_state_stable,\n };\n}\n","/**\n * Formats value to make it stay in bounds [0, +Inf).\n * @param value - value to format.\n */\nexport function truncate(value: number): number {\n return value < 0 ? 0 : value;\n}\n","import {\n on,\n type PostEvent,\n postEvent as defaultPostEvent,\n type RequestOptions,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport { requestViewport } from '~/viewport/requestViewport.js';\n\nimport type {\n ViewportEvents,\n ViewportProps,\n ViewportState,\n} from './types.js';\nimport { truncate } from './utils.js';\n\n/**\n * Contains information about current WebApp device viewport, its dimensions\n * and state.\n */\nexport class Viewport {\n private readonly ee = new EventEmitter<ViewportEvents>();\n\n private readonly state: State<ViewportState>;\n\n private readonly postEvent: PostEvent;\n\n constructor(props: ViewportProps) {\n const {\n height,\n isExpanded,\n width,\n stableHeight,\n postEvent = defaultPostEvent,\n } = props;\n this.postEvent = postEvent;\n this.state = new State({\n height: truncate(height),\n isExpanded,\n stableHeight: truncate(stableHeight),\n width: truncate(width),\n }, this.ee);\n }\n\n /**\n * Request viewport information from the Telegram application and updates current Viewport\n * instance.\n * @param options - options to request fresh data.\n */\n sync(options?: RequestOptions): Promise<void> {\n return requestViewport(options).then(({ height, isExpanded, width, isStateStable }) => {\n this.state.set({\n height,\n width,\n isExpanded,\n stableHeight: isStateStable ? height : this.state.get('stableHeight'),\n });\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\n * lower part remaining outside the screen area. From this position, the\n * user can \"pull\" the Mini App to its maximum height, while the bot can do\n * the same by calling `expand` method. As the position of the Mini App\n * changes, the current height value of the visible area will be updated\n * in real time.\n *\n * Please note that the refresh rate of this value is not sufficient\n * to smoothly follow the lower border of the window. It should not be\n * used to pin interface elements to the bottom of the visible area. It's\n * more appropriate to use the value of the `stableHeight`\n * field for this purpose.\n */\n get height(): number {\n return this.state.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\n * lower part remaining outside the screen area. From this position,\n * the user can \"pull\" the Mini App to its maximum height, while the bot can\n * do the same by calling `expand` method.\n *\n * Unlike the value of `height`, the value of `stableHeight`\n * does not change as the position of the Mini App changes with user\n * 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 get stableHeight(): number {\n return this.state.get('stableHeight');\n }\n\n /**\n * Starts listening to viewport changes and applies them.\n * @returns Function to stop listening.\n */\n listen() {\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 state: Partial<ViewportState> = {\n height: truncate(height),\n isExpanded,\n width: truncate(width),\n };\n\n if (isStateStable) {\n state.stableHeight = state.height;\n }\n\n this.state.set(state);\n });\n }\n\n /**\n * Returns true if the Mini App is expanded to the maximum available height.\n * Otherwise, if the Mini App occupies part of the screen and can be expanded\n * to the full height using `expand` method.\n * @see expand\n */\n get isExpanded(): boolean {\n return this.state.get('isExpanded');\n }\n\n /**\n * Current viewport width.\n */\n get width(): number {\n return this.state.get('width');\n }\n\n /**\n * A method that expands the Mini App to the maximum available height. To\n * find out if the Mini App is expanded to the maximum height, refer to the\n * value of the `isExpanded`.\n * @see isExpanded\n */\n expand(): void {\n this.postEvent('web_app_expand');\n this.state.set('isExpanded', true);\n }\n\n /**\n * Returns true in case current viewport height is stable and is not going to\n * change in the next moment.\n */\n get isStable(): boolean {\n return this.stableHeight === this.height;\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n}\n","import { getStorageValue, saveStorageValue } from '~/storage.js';\nimport {\n isStableViewportPlatform,\n requestViewport,\n Viewport,\n type ViewportProps,\n} from '~/viewport/index.js';\nimport type { PostEvent } from '~/bridge/index.js';\nimport type { Platform } from '~/types/index.js';\n\n/**\n * Creates new bound instance of the Viewport component.\n * @param props - properties to create new instance.\n */\nfunction instantiate(props: ViewportProps): Viewport {\n const viewport = new Viewport(props);\n\n // TODO: Should probably use throttle for height.\n viewport.on('change', () => saveStorageValue('viewport', {\n height: viewport.height,\n isExpanded: viewport.isExpanded,\n stableHeight: viewport.stableHeight,\n width: viewport.width,\n }));\n\n viewport.listen();\n\n return viewport;\n}\n\n/**\n * Creates Viewport instance using its actual state from the Telegram application.\n * @param isPageReload - was page reloaded.\n * @param platform - platform identifier.\n * @param postEvent - Bridge postEvent function.\n * @param complete - is initialization complete.\n */\nexport function createViewport(\n isPageReload: boolean,\n platform: Platform,\n postEvent: PostEvent,\n complete: boolean,\n): Viewport | Promise<Viewport> {\n // If page was reloaded, we expect viewport to be restored from the storage.\n const state = isPageReload ? getStorageValue('viewport') : null;\n if (state) {\n return instantiate({ ...state, postEvent });\n }\n\n // If platform has a stable viewport, it means we could instantiate Viewport using\n // the window global object properties.\n if (isStableViewportPlatform(platform)) {\n return instantiate({\n height: window.innerHeight,\n isExpanded: true,\n postEvent,\n stableHeight: window.innerHeight,\n width: window.innerWidth,\n });\n }\n\n // If initialization is complete, we have to create Viewport instance using its actual\n // state from the Telegram application.\n if (complete) {\n return requestViewport({\n postEvent,\n timeout: 5000,\n })\n .then(({ height, isStateStable, ...rest }) => instantiate({\n ...rest,\n height,\n stableHeight: isStateStable ? height : 0,\n }));\n }\n\n // Otherwise we have no sources to get viewport properties from. In this case we just\n // return some \"empty\" Viewport instance and synchronize it in the background.\n const viewport = instantiate({\n width: 0,\n height: 0,\n isExpanded: false,\n postEvent,\n stableHeight: 0,\n });\n\n /* c8 ignore start */\n viewport.sync({ postEvent, timeout: 5000 }).catch((e) => {\n // eslint-disable-next-line no-console\n console.error('Unable to actualize viewport state', e);\n });\n /* c8 ignore stop */\n\n return viewport;\n}\n","/**\n * Sets CSS variable.\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 { setCSSVar } from '~/init/css/setCSSVar.js';\nimport type { MiniApp } from '~/mini-app/index.js';\nimport type { ThemeParams } from '~/theme-params/index.js';\n\n/**\n * Creates CSS variables connected with WebApp background and header colors based on\n * passed WebApp and ThemeParams instances.\n *\n * Created variables:\n * - `--tg-background-color`\n * - `--tg-header-color`\n *\n * Variables are being automatically updated in case, corresponding properties are updating.\n *\n * @param miniApp - MiniApp instance.\n * @param themeParams - ThemeParams instance.\n */\nexport function bindMiniAppCSSVars(miniApp: MiniApp, themeParams: ThemeParams): void {\n const actualizeBackground = () => {\n setCSSVar('--tg-background-color', miniApp.backgroundColor);\n };\n\n const actualizeHeader = () => {\n const {\n backgroundColor,\n secondaryBackgroundColor,\n } = themeParams;\n\n if (miniApp.headerColor === 'bg_color') {\n if (backgroundColor) {\n setCSSVar('--tg-header-color', backgroundColor);\n }\n } else if (miniApp.headerColor === 'secondary_bg_color') {\n if (secondaryBackgroundColor) {\n setCSSVar('--tg-header-color', secondaryBackgroundColor);\n }\n } else {\n setCSSVar('--tg-header-color', miniApp.headerColor);\n }\n };\n\n themeParams.on('change', actualizeHeader);\n miniApp.on('change:backgroundColor', actualizeBackground);\n miniApp.on('change:headerColor', actualizeHeader);\n\n actualizeBackground();\n actualizeHeader();\n}\n","import type { ThemeParams } from '~/theme-params/index.js';\n\nimport { setCSSVar } from './setCSSVar.js';\n\n/**\n * Creates CSS variables connected with theme parameters. Created CSS variables names are\n * following the pattern \"--tg-theme-{name}\". {name} is a theme parameters key name converted\n * from snake to kebab case.\n *\n * Variables are being automatically updated in case, corresponding properties\n * updated in passed ThemeParams instance.\n *\n * @param themeParams - ThemeParams instance.\n */\nexport function bindThemeCSSVars(themeParams: ThemeParams): void {\n const actualize = () => {\n const state = themeParams.getState();\n\n Object.entries(state).forEach(([k, v]) => {\n if (v) {\n const key = k\n .replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n setCSSVar(`--tg-theme-${key}`, v);\n }\n });\n };\n\n themeParams.on('change', actualize);\n\n actualize();\n}\n","import type { Viewport } from '~/viewport/index.js';\n\nimport { setCSSVar } from './setCSSVar.js';\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 */\nexport function bindViewportCSSVars(viewport: Viewport): void {\n const setHeight = () => setCSSVar('--tg-viewport-height', `${viewport.height}px`);\n const setWidth = () => setCSSVar('--tg-viewport-width', `${viewport.width}px`);\n const setStableHeight = () => setCSSVar('--tg-viewport-height', `${viewport.stableHeight}px`);\n\n // TODO: Should probably add debounce or throttle.\n viewport.on('change:height', setHeight);\n viewport.on('change:width', setWidth);\n viewport.on('change:stableHeight', setStableHeight);\n\n setHeight();\n setWidth();\n setStableHeight();\n}\n","import type { MiniApp } from '~/mini-app/index.js';\nimport type { ThemeParams } from '~/theme-params/index.js';\nimport type { Viewport } from '~/viewport/index.js';\n\nimport { bindMiniAppCSSVars } from './bindMiniAppCSSVars.js';\nimport { bindThemeCSSVars } from './bindThemeCSSVars.js';\nimport { bindViewportCSSVars } from './bindViewportCSSVars.js';\nimport type { InitCSSVarsOption, InitCSSVarsSpecificOption } from '../types.js';\n\n/**\n * Converts init cssVars option to more narrow type.\n * @param option - option value.\n */\nfunction parseCSSVarsOptions(option: InitCSSVarsOption): InitCSSVarsSpecificOption {\n if (typeof option === 'object') {\n return option;\n }\n return option\n ? {\n themeParams: true,\n viewport: true,\n miniApp: true,\n }\n : {};\n}\n\n/**\n * Process initialization CSS vars option.\n * @param option - option value.\n * @param miniApp - MiniApp instance.\n * @param themeParams - ThemeParams instance.\n * @param viewportOrPromise - Viewport instance or promise resolving it.\n */\nexport function processCSSVars(\n option: InitCSSVarsOption,\n miniApp: MiniApp,\n themeParams: ThemeParams,\n viewportOrPromise: Viewport | Promise<Viewport>,\n): void {\n const cssVarsOptions = parseCSSVarsOptions(option);\n\n if (cssVarsOptions.miniApp) {\n bindMiniAppCSSVars(miniApp, themeParams);\n }\n\n if (cssVarsOptions.themeParams) {\n bindThemeCSSVars(themeParams);\n }\n\n if (cssVarsOptions.viewport) {\n if (viewportOrPromise instanceof Promise) {\n viewportOrPromise.then(bindViewportCSSVars);\n } else {\n bindViewportCSSVars(viewportOrPromise);\n }\n }\n}\n","import {\n type InvoiceStatus,\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport type { InvoiceEvents, InvoiceState } from './types.js';\n\n/**\n * Extracts invoice slug from URL.\n * @param url - url to extract slug from.\n */\nfunction slugFromUrl(url: string): string {\n const { hostname, pathname } = new URL(url, 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\n if (match === null) {\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 return match[2];\n}\n\n/**\n * Controls currently displayed invoice.\n */\nexport class Invoice {\n private readonly ee = new EventEmitter<InvoiceEvents>();\n\n private readonly state: State<InvoiceState>;\n\n constructor(\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isOpened: false }, this.ee);\n this.supports = createSupportsFunc(version, { open: 'web_app_open_invoice' });\n }\n\n private set isOpened(value) {\n this.state.set('isOpened', value);\n }\n\n /**\n * True if invoice is currently opened.\n */\n get isOpened(): boolean {\n return this.state.get('isOpened');\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\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 const slug = type ? slugFromUrl(urlOrSlug) : urlOrSlug;\n\n this.isOpened = true;\n\n try {\n const result = await request(\n 'web_app_open_invoice',\n { slug },\n 'invoice_closed',\n {\n postEvent: this.postEvent,\n capture(data) {\n return slug === data.slug;\n },\n },\n );\n\n return result.status;\n } finally {\n this.isOpened = false;\n }\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'open'>;\n}\n","import type { PopupButton, PopupParams as BridgePopupParams } from '~/bridge/index.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 === 0 || 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 === 0) {\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 === undefined || b.type === 'default' || b.type === 'destructive') {\n const text = b.text.trim();\n\n if (text.length === 0 || 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 {\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport { preparePopupParams } from './preparePopupParams.js';\nimport type { OpenPopupOptions, PopupEvents, PopupState } from './types.js';\n\n/**\n * Controls currently displayed application popup. It allows developers to\n * open new custom popups and detect popup-connected events.\n */\nexport class Popup {\n private readonly ee = new EventEmitter<PopupEvents>();\n\n private readonly state: State<PopupState>;\n\n constructor(\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isOpened: false }, this.ee);\n this.supports = createSupportsFunc(version, { open: 'web_app_open_popup' });\n }\n\n private set isOpened(value) {\n this.state.set('isOpened', value);\n }\n\n /**\n * True if popup is currently opened.\n */\n get isOpened(): boolean {\n return this.state.get('isOpened');\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\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 * FIXME: In desktop, this function may work incorrectly.\n * Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/7\n * @param options - popup parameters.\n * @throws {Error} Popup is already opened.\n */\n 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 return request(\n 'web_app_open_popup',\n preparePopupParams(options),\n 'popup_closed',\n { postEvent: this.postEvent },\n )\n .then(({ button_id = null }) => button_id)\n .finally(() => {\n this.isOpened = false;\n });\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'open'>;\n}\n","import {\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n} from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\nimport { State } from '~/state/index.js';\nimport {\n createSupportsFunc,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { Version } from '~/version/index.js';\n\nimport type { QRScannerEvents, QRScannerState } from './types.js';\n\n/**\n * Provides QR scanner functionality.\n */\nexport class QRScanner {\n private readonly ee = new EventEmitter<QRScannerEvents>();\n\n private readonly state: State<QRScannerState>;\n\n constructor(\n version: Version,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.state = new State({ isOpened: false }, this.ee);\n this.supports = createSupportsFunc(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.state.set('isOpened', value);\n }\n\n /**\n * Returns true in case, QR scanner is currently opened.\n */\n get isOpened(): boolean {\n return this.state.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 'web_app_open_scan_qr_popup',\n { text },\n ['qr_text_received', 'scan_qr_popup_closed'],\n { postEvent: this.postEvent },\n );\n\n return typeof result === 'object' && typeof result.data === 'string' ? result.data : null;\n } finally {\n this.isOpened = false;\n }\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'open' | 'close'>;\n}\n","import {\n type PostEvent,\n postEvent as defaultPostEvent,\n request,\n} from '~/bridge/index.js';\nimport {\n createSupportsFunc,\n createSupportsParamFunc,\n supports,\n type SupportsFunc,\n} from '~/supports/index.js';\nimport type { CreateRequestIdFunc } from '~/types/index.js';\nimport type { Version } from '~/version/index.js';\n\n/**\n * Provides common Mini Apps functionality not covered by other system components.\n */\nexport class Utils {\n constructor(\n private readonly version: Version,\n private readonly createRequestId: CreateRequestIdFunc,\n private readonly postEvent: PostEvent = defaultPostEvent,\n ) {\n this.supports = createSupportsFunc(version, {\n readTextFromClipboard: 'web_app_read_text_from_clipboard',\n });\n\n this.supportsParam = createSupportsParamFunc(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 {\n hostname,\n pathname,\n search,\n } = new URL(url, window.location.href);\n\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 readTextFromClipboard(): Promise<string | null> {\n return request(\n 'web_app_read_text_from_clipboard',\n { req_id: this.createRequestId() },\n 'clipboard_text_received',\n { postEvent: this.postEvent },\n ).then(({ data = null }) => data);\n }\n\n /**\n * Checks if specified method is supported by current component.\n */\n supports: SupportsFunc<'readTextFromClipboard'>;\n\n /**\n * Checks if specified method parameter is supported by current component.\n */\n supportsParam: SupportsFunc<'openLink.tryInstantView'>;\n}\n","import { createPostEvent, isIframe, on } from '~/bridge/index.js';\nimport { CloudStorage } from '~/cloud-storage/index.js';\nimport { HapticFeedback } from '~/haptic-feedback/index.js';\nimport { catchCustomStyles } from '~/init/catchCustomStyles.js';\nimport {\n createBackButton,\n createClosingBehavior,\n createMainButton,\n createMiniApp,\n createRequestIdGenerator,\n createSettingsButton,\n createThemeParams,\n createViewport,\n} from '~/init/creators/index.js';\nimport { processCSSVars } from '~/init/css/index.js';\nimport { InitData } from '~/init-data/index.js';\nimport { Invoice } from '~/invoice/index.js';\nimport { retrieveLaunchData } from '~/launch-params/index.js';\nimport { Popup } from '~/popup/index.js';\nimport { QRScanner } from '~/qr-scanner/index.js';\nimport { Utils } from '~/utils/index.js';\n\nimport type { InitOptions, InitResult } from './types.js';\n\ntype ComputedInitResult<O> = O extends { async: true } | { complete: true }\n ? Promise<InitResult>\n : InitResult;\n\nexport function init(): InitResult;\nexport function init<O extends InitOptions>(options: O): ComputedInitResult<O>;\nexport function init(options: InitOptions = {}): InitResult | Promise<InitResult> {\n const {\n async = false,\n complete = async,\n cssVars = false,\n acceptCustomStyles = false,\n } = options;\n\n try {\n // Retrieve launch data.\n const {\n launchParams: {\n initData,\n initDataRaw,\n version,\n platform,\n themeParams,\n botInline = false,\n },\n isPageReload,\n } = retrieveLaunchData();\n\n const createRequestId = createRequestIdGenerator();\n const postEvent = createPostEvent(version);\n\n // In Telegram web version we should listen to special event sent from the Telegram application\n // to know, when we should reload the Mini App.\n if (isIframe()) {\n if (acceptCustomStyles) {\n catchCustomStyles();\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 on('reload_iframe', () => window.location.reload());\n }\n\n const result: Omit<InitResult, 'viewport'> = {\n backButton: createBackButton(isPageReload, version, postEvent),\n closingBehavior: createClosingBehavior(isPageReload, postEvent),\n cloudStorage: new CloudStorage(version, createRequestId, postEvent),\n createRequestId,\n hapticFeedback: new HapticFeedback(version, postEvent),\n invoice: new Invoice(version, postEvent),\n mainButton: createMainButton(\n isPageReload,\n themeParams.buttonColor || '#000000',\n themeParams.buttonTextColor || '#ffffff',\n postEvent,\n ),\n miniApp: createMiniApp(\n isPageReload,\n themeParams.backgroundColor || '#ffffff',\n version,\n botInline,\n createRequestId,\n postEvent,\n ),\n popup: new Popup(version, postEvent),\n postEvent,\n qrScanner: new QRScanner(version, postEvent),\n settingsButton: createSettingsButton(isPageReload, version, postEvent),\n themeParams: createThemeParams(themeParams),\n utils: new Utils(version, createRequestId, postEvent),\n ...(initData\n // Init data could be missing in case, application was launched via InlineKeyboardButton.\n ? {\n initData: new InitData(initData),\n initDataRaw,\n }\n : {}),\n };\n\n const viewport = createViewport(isPageReload, platform, postEvent, complete);\n if (viewport instanceof Promise || complete) {\n return Promise.resolve(viewport).then((vp) => {\n processCSSVars(\n cssVars,\n result.miniApp,\n result.themeParams,\n vp,\n );\n\n return { ...result, viewport: vp };\n });\n }\n\n processCSSVars(\n cssVars,\n result.miniApp,\n result.themeParams,\n viewport,\n );\n\n return { ...result, viewport };\n } catch (e) {\n if (complete) {\n return Promise.reject(e);\n }\n throw e;\n }\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","/**\n * Returns string after first met \"#\" symbol.\n * @param value - string to take hash part from.\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","/**\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 window.addEventListener('popstate', function listener() {\n window.removeEventListener('popstate', listener);\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 './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.\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 { Logger } from '~/logger/index.js';\n\nimport type {\n AnyEntry,\n NavigationEntry,\n NavigatorConEntry,\n NavigatorOptions,\n PerformGoOptions,\n PerformPushOptions,\n PerformReplaceOptions,\n} from './types.js';\nimport { ensurePrefix } from '../ensurePrefix.js';\n\n/**\n * Represents basic navigator implementation which uses only memory to store and control\n * navigation state.\n */\nexport abstract class Navigator<T> {\n protected logger: Logger;\n\n protected readonly entries: NavigationEntry[];\n\n constructor(\n entries: NavigatorConEntry[],\n protected entriesCursor: number,\n {\n debug = false,\n loggerPrefix = 'Navigator',\n }: NavigatorOptions,\n ) {\n if (entries.length === 0) {\n throw new Error('Entries list should not be empty.');\n }\n\n if (entriesCursor >= entries.length) {\n throw new Error('Cursor should be less than entries count.');\n }\n\n this.entries = entries.map(({ pathname = '', search, hash }) => {\n if (!pathname.startsWith('/') && pathname.length > 0) {\n throw new Error('Pathname should start with \"/\"');\n }\n\n return {\n pathname: ensurePrefix(pathname, '/'),\n search: search ? ensurePrefix(search, '?') : '',\n hash: hash ? ensurePrefix(hash, '#') : '',\n };\n });\n this.logger = new Logger(`[${loggerPrefix}]`, debug);\n }\n\n protected abstract performGo(options: PerformGoOptions): T;\n\n protected abstract performPush(options: PerformPushOptions): T;\n\n protected abstract performReplace(options: PerformReplaceOptions): T;\n\n /**\n * Converts entry to the navigation entry.\n * @param entry - entry data\n */\n private formatEntry(entry: AnyEntry): NavigationEntry {\n let path: string;\n\n if (typeof entry === 'string') {\n path = entry;\n } else {\n const {\n pathname = '',\n search,\n hash,\n } = entry;\n\n path = pathname\n + (search ? ensurePrefix(search, '?') : '')\n + (hash ? ensurePrefix(hash, '#') : '');\n }\n\n const {\n pathname,\n search,\n hash,\n } = new URL(path, `https://localhost${this.path}`);\n return {\n pathname,\n search,\n hash,\n };\n }\n\n /**\n * Current entry.\n */\n protected get entry(): NavigationEntry {\n return this.entries[this.entriesCursor];\n }\n\n /**\n * Goes back in history.\n */\n back(): T {\n return this.go(-1);\n }\n\n /**\n * Current entries cursor.\n */\n get cursor(): number {\n return this.entriesCursor;\n }\n\n /**\n * True if navigator can go back.\n */\n get canGoBack(): boolean {\n return this.entriesCursor > 0;\n }\n\n /**\n * True if navigator can go forward.\n */\n get canGoForward(): boolean {\n return this.entriesCursor !== this.entries.length - 1;\n }\n\n /**\n * Goes forward in history.\n */\n forward(): T {\n return this.go(1);\n }\n\n /**\n * Moves entries cursor by specified delta.\n * @param delta - cursor delta.\n */\n go(delta: number): T {\n this.logger.log(`called go(${delta})`);\n\n // Cursor should be in bounds: [0, this.entries).\n const cursor = Math.min(\n this.entries.length - 1,\n Math.max(this.entriesCursor + delta, 0),\n );\n\n if (this.entriesCursor === cursor) {\n return this.performGo({\n updated: false,\n delta,\n });\n }\n\n const before = this.entry;\n this.entriesCursor = cursor;\n const after = this.entry;\n\n this.logger.log('State changed', { before, after });\n\n return this.performGo({\n updated: true,\n delta,\n before,\n after,\n });\n }\n\n /**\n * Returns copy of navigator entries.\n */\n getEntries(): NavigationEntry[] {\n return this.entries.map((entry) => ({ ...entry }));\n }\n\n /**\n * Current hash.\n * @example\n * \"\", \"#\", \"#hash\"\n */\n get hash(): string {\n return this.entry.hash;\n }\n\n /**\n * Pushes new entry. Method replaces all entries after the current one with the inserted.\n * @param entry - entry data.\n *\n * @example Pushing absolute pathname.\n * push(\"/absolute-path\"); // \"/absolute-path\"\n *\n * @example Pushing relative pathname.\n * // Pushing relative path replaces N last path parts, where N is pushed pathname parts count.\n * // Pushing empty path is recognized as relative, but not replacing the last pathname part.\n * push(\"relative\"); // \"/home/root\" -> \"/home/relative\"\n *\n * @example Pushing query parameters.\n * push(\"/absolute?my-param=1\"); // \"/home\" -> \"/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(\"johny#my-hash\"); // \"/home/root\" -> \"/home/johny#my-hash\"\n */\n push(entry: AnyEntry): T {\n // In case, current cursor refers not to the last one element in the history, we should\n // remove everything after the cursor.\n if (this.entriesCursor !== this.entries.length - 1) {\n this.entries.splice(this.entriesCursor + 1);\n }\n\n const formatted = this.formatEntry(entry);\n const before = this.entry;\n this.entriesCursor += 1;\n this.entries[this.entriesCursor] = formatted;\n const after = this.entry;\n\n this.logger.log('State changed', { before, after });\n\n return this.performPush({\n before,\n after,\n });\n }\n\n /**\n * Current full path including pathname, query parameters and hash.\n */\n get path(): string {\n return `${this.pathname}${this.search}${this.hash}`;\n }\n\n /**\n * Current pathname.\n * @example\n * \"/\", \"/abc\"\n */\n get pathname(): string {\n return this.entry.pathname;\n }\n\n /**\n * Replaces current entry. Has the same logic as `push` method.\n * @param entry - entry data.\n * @see push\n * @returns True if changes were done.\n */\n replace(entry: AnyEntry): T {\n const formattedEntry = this.formatEntry(entry);\n if (\n this.search === formattedEntry.search\n && this.pathname === formattedEntry.pathname\n && this.hash === formattedEntry.hash\n ) {\n return this.performReplace({\n updated: false,\n entry: formattedEntry,\n });\n }\n\n const before = this.entry;\n this.entries[this.entriesCursor] = formattedEntry;\n const after = this.entry;\n\n this.logger.log('State changed', { before, after });\n\n return this.performReplace({\n updated: true,\n before,\n after,\n });\n }\n\n /**\n * Current query parameters.\n * @example\n * \"\", \"?\", \"?a=1\"\n */\n get search(): string {\n return this.entry.search;\n }\n}\n","import { off, on, postEvent } from '~/bridge/index.js';\nimport { EventEmitter } from '~/event-emitter/index.js';\n\nimport { drop } from './drop.js';\nimport { go } from './go.js';\nimport type {\n HashNavigatorEventsMap,\n HashNavigatorOptions,\n} from './types.js';\nimport { Navigator } from '../Navigator/index.js';\nimport type {\n NavigationEntry,\n NavigatorConEntry,\n PerformGoOptions,\n PerformPushOptions,\n PerformReplaceOptions,\n} from '../Navigator/types.js';\n\nconst CURSOR_VOID = 0;\nconst CURSOR_BACK = 1;\nconst CURSOR_FORWARD = 2;\n\nexport class HashNavigator extends Navigator<Promise<void>> {\n /**\n * Creates navigator from current window location hash.\n * @param options - options passed to constructor.\n */\n static fromLocation(options?: HashNavigatorOptions): HashNavigator {\n const {\n search,\n pathname,\n hash,\n } = new URL(\n window.location.hash.slice(1),\n window.location.href,\n );\n\n return new HashNavigator([{ search, pathname, hash }], 0, options);\n }\n\n private readonly ee = new EventEmitter<HashNavigatorEventsMap>();\n\n private attached = false;\n\n constructor(\n entries: NavigatorConEntry[],\n entriesCursor: number,\n options: HashNavigatorOptions = {},\n ) {\n super(entries, entriesCursor, {\n ...options,\n loggerPrefix: 'HashNavigator',\n });\n }\n\n /**\n * Handles window \"popstate\" event.\n * @param state - event state.\n */\n private onPopState = async ({ state }: PopStateEvent) => {\n this.logger.log('\"popstate\" event received. State:', state);\n\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(window.location.hash.slice(1));\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 this.logger.log('Void reached. Moving history forward');\n window.history.forward();\n return;\n }\n\n // User pressed Back button.\n if (state === CURSOR_BACK) {\n return this.back();\n }\n\n // User pressed Forward button.\n if (state === CURSOR_FORWARD) {\n return this.forward();\n }\n };\n\n protected async performGo(options: PerformGoOptions): Promise<void> {\n if (!options.updated) {\n return;\n }\n\n if (this.attached) {\n await this.syncHistory();\n }\n\n this.emitChanged(options.before, options.after);\n }\n\n protected async performPush({ before, after }: PerformPushOptions): Promise<void> {\n if (this.attached) {\n await this.syncHistory();\n }\n\n this.emitChanged(before, after);\n }\n\n protected async performReplace(options: PerformReplaceOptions): Promise<void> {\n if (!options.updated) {\n return;\n }\n\n if (this.attached) {\n window.history.replaceState(null, '', `#${this.path}`);\n }\n\n this.emitChanged(options.before, options.after);\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 possible\n // future calls of history.go.\n window.removeEventListener('popstate', this.onPopState);\n\n const hash = `#${this.path}`;\n\n // Drop the browser history and work with the clean one.\n await drop();\n\n // Actualize Telegram Mini Apps BackButton state.\n postEvent('web_app_setup_back_button', { is_visible: this.canGoBack });\n\n if (this.canGoBack && this.canGoForward) {\n // We have both previous and next elements. History should be:\n // [back, *current*, forward]\n this.logger.log('Setting up history: [<-, *, ->]');\n\n window.history.replaceState(CURSOR_BACK, '');\n window.history.pushState(null, '', hash);\n window.history.pushState(CURSOR_FORWARD, '');\n\n await go(-1);\n } else if (this.canGoBack) {\n // We have only previous element. History should be:\n // [back, *current*]\n this.logger.log('Setting up history: [<-, *]');\n\n window.history.replaceState(CURSOR_BACK, '');\n window.history.pushState(null, '', hash);\n } else if (this.canGoForward) {\n // We have only next element. History should be:\n // [*current*, forward]\n this.logger.log('Setting up history: [*, ->]');\n\n window.history.replaceState(null, hash);\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 this.logger.log('Setting up history: [~, *]');\n\n window.history.replaceState(CURSOR_VOID, '');\n window.history.pushState(null, '', hash);\n }\n\n window.addEventListener('popstate', this.onPopState);\n }\n\n private emitChanged(from: NavigationEntry, to: NavigationEntry) {\n this.ee.emit('change', {\n navigator: this,\n from,\n to,\n });\n }\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 return;\n }\n this.logger.log('Attaching', this);\n this.attached = true;\n on('back_button_pressed', this.back);\n return this.syncHistory();\n }\n\n back = () => super.back();\n\n /**\n * Detaches current navigator from the browser history.\n */\n detach() {\n if (!this.attached) {\n return;\n }\n this.logger.log('Detaching', this);\n this.attached = false;\n window.removeEventListener('popstate', this.onPopState);\n off('back_button_pressed', this.back);\n }\n\n /**\n * Adds new event listener.\n */\n on = this.ee.on.bind(this.ee);\n\n /**\n * Removes event listener.\n */\n off = this.ee.off.bind(this.ee);\n}\n"],"names":["isRecord","value","getFirstNavigationEntry","computePageReload","firstNavigationEntry","unexpectedTypeError","ParseError","cause","type","__publicField","ValueParser","parser","isOptional","parseArray","json","ArrayValueParser","itemParser","arr","createValueParserGenerator","ParseSchemaFieldError","field","parseBySchema","schema","getField","result","definition","from","parsedValue","originalValue","error","array","boolean","asString","number","num","date","toRecord","formattedValue","record","isRGB","isRGBShort","toRGB","clean","color","i","match","acc","component","formatted","isColorDark","rgb","modifier","idx","dec","string","searchParams","params","paramValue","chatParser","InitData","initData","canSendAfter","userParser","initDataParser","parseInitData","keyToLocal","key","_","prefix","_match","letter","keyToExternal","themeParamsParser","rgbOptional","k","v","parseThemeParams","requestThemeParams","options","request","serializeThemeParams","themeParams","EventEmitter","event","listener","once","listeners","args","l","State","state","ee","keyOrState","didChange","ThemeParams","on","launchParamsParser","parseLaunchParams","retrieveFromLocation","retrieveFromPerformance","navigationEntry","hashMatch","retrieveCurrent","serializeLaunchParams","initDataRaw","platform","version","showSettings","botInline","SESSION_STORAGE_KEY","retrieveFromStorage","raw","saveToStorage","isIframe","computeLaunchData","lpPrevious","lpCurrent","isPageReload","WINDOW_KEY","retrieveLaunchData","cached","launchData","isTMA","hasExternalNotify","hasWebviewProxy","MethodUnsupportedError","method","ParameterUnsupportedError","param","Logger","enabled","level","now","currentTargetOrigin","logger","setDebug","setTargetOrigin","targetOrigin","eventDataJson","emitEvent","eventType","eventData","defineEventHandlers","wnd","path","pointer","item","onTelegramEvent","cb","clipboardTextReceived","customMethodInvoked","invoiceClosed","phoneRequested","popupClosed","qrTextReceived","themeChanged","viewportChanged","writeAccessRequested","createEmitter","emitter","emit","data","CACHED_EMITTER","singletonEmitter","off","unsubscribe","subscribe","compareVersions","a","b","aParts","bParts","len","aVal","bVal","versionLessOrEqual","supports","paramOrVersion","inVersion","createSupportsFunc","createSupportsParamFunc","tmaMethod","postEvent","paramsOrOptions","postOptions","globalTargetOrigin","createPostEvent","validateParam","TimeoutError","timeout","isTimeoutError","sleep","duration","res","createTimeoutPromise","rej","withTimeout","func","eventOrParams","eventOrOptions","executionOptions","methodParams","events","requestId","defaultPostEvent","capture","execute","stoppers","ev","stopListening","stop","e","invokeCustomMethod","BackButton","isVisible","visible","space","classNames","values","valueAcc","className","enable","isObject","mergeClassNames","partials","partial","ClosingBehavior","isConfirmationNeeded","objectFromKeys","keys","CloudStorage","createRequestId","keyOrKeys","HapticFeedback","style","catchCustomStyles","element","html","formatKey","saveStorageValue","getStorageValue","createBackButton","createClosingBehavior","MainButton","props","text","textColor","backgroundColor","isEnabled","isLoaderVisible","createMainButton","stateBackgroundColor","stateTextColor","saveState","contactParser","MiniApp","headerColor","isSupported","deadlineAt","sleepTime","size","chatTypes","createMiniApp","createRequestIdGenerator","SettingsButton","createSettingsButton","createThemeParams","isStableViewportPlatform","requestViewport","truncate","Viewport","height","isExpanded","width","stableHeight","isStateStable","instantiate","viewport","createViewport","complete","rest","setCSSVar","name","bindMiniAppCSSVars","miniApp","actualizeBackground","actualizeHeader","secondaryBackgroundColor","bindThemeCSSVars","actualize","bindViewportCSSVars","setHeight","setWidth","setStableHeight","parseCSSVarsOptions","option","processCSSVars","viewportOrPromise","cssVarsOptions","slugFromUrl","url","hostname","pathname","Invoice","urlOrSlug","slug","preparePopupParams","message","title","buttons","preparedButtons","id","Popup","button_id","QRScanner","Utils","tryInstantView","formattedUrl","search","init","async","cssVars","acceptCustomStyles","vp","ensurePrefix","getHash","go","delta","drop","shouldGoBack","Navigator","entries","entriesCursor","debug","loggerPrefix","hash","entry","cursor","before","after","formattedEntry","CURSOR_VOID","CURSOR_BACK","CURSOR_FORWARD","HashNavigator","to"],"mappings":"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"}
|