@telegram-apps/sdk
Advanced tools
Comparing version 2.1.0 to 2.3.0
@@ -19,8 +19,4 @@ export { classNames } from './classnames/classNames.js'; | ||
export { isSupported as isInvoiceSupported, isOpened as isInvoiceOpened, open as openInvoice, } from './scopes/components/invoice/invoice.js'; | ||
export * as mainButton from './scopes/components/main-button/instance.js'; | ||
export { backgroundColor as mainButtonBackgroundColor, hasShineEffect as mainButtonHasShineEffect, isMounted as isMainButtonMounted, isVisible as isMainButtonVisible, isEnabled as isMainButtonEnabled, isLoaderVisible as isMainButtonLoaderVisible, mount as mountMainButton, onClick as onMainButtonClick, offClick as offMainButtonClick, setParams as setMainButtonParams, state as mainButtonState, textColor as mainButtonTextColor, text as mainButtonText, unmount as unmountMainButton, } from './scopes/components/main-button/instance.js'; | ||
export * as MainButton from './scopes/components/main-button/static.js'; | ||
export * as miniApp from './scopes/components/mini-app/instance.js'; | ||
export { backgroundColor as miniAppBackgroundColor, bindCssVars as bindMiniAppCssVars, close as closeMiniApp, headerColor as miniAppHeaderColor, isMounted as isMiniAppMounted, isCssVarsBound as isMiniAppCssVarsBound, isDark as isMiniAppDark, mount as mountMiniApp, ready as miniAppReady, state as miniAppState, setHeaderColor as setMiniAppHeaderColor, setBackgroundColor as setMiniAppBackgroundColor, unmount as unmountMiniApp, } from './scopes/components/mini-app/instance.js'; | ||
export * as MiniApp from './scopes/components/main-button/static.js'; | ||
export * from './scopes/components/main-button/exports.js'; | ||
export * from './scopes/components/mini-app/exports.js'; | ||
export * as popup from './scopes/components/popup/instance.js'; | ||
@@ -31,2 +27,3 @@ export { isOpened as isPopupOpened, isSupported as isPopupSupported, open as openPopup, } from './scopes/components/popup/instance.js'; | ||
export { close as closeQrScanner, isSupported as isQrScannerSupported, isOpened as isQrScannerOpened, open as openQrScanner, } from './scopes/components/qr-scanner/qr-scanner.js'; | ||
export * from './scopes/components/secondary-button/exports.js'; | ||
export * as settingsButton from './scopes/components/settings-button/settings-button.js'; | ||
@@ -33,0 +30,0 @@ export { hide as hideSettingsButton, isVisible as isSettingsButtonVisible, isMounted as isSettingsButtonMounted, isSupported as isSettingsButtonSupported, mount as mountSettingsButton, onClick as onSettingsButtonClick, offClick as offSettingsButtonClick, show as showSettingsButton, unmount as unmountSettingsButton, } from './scopes/components/settings-button/settings-button.js'; |
import { EventListener } from '@telegram-apps/bridge'; | ||
import { State } from './types.js'; | ||
/** | ||
* Mounts the component. | ||
* | ||
* This function restores the component state and is automatically saving it in the local storage | ||
* if it changed. | ||
*/ | ||
export declare function mount(): void; | ||
/** | ||
* Adds a new main button click listener. | ||
@@ -15,9 +22,2 @@ * @param fn - event listener. | ||
/** | ||
* Mounts the component. | ||
* | ||
* This function restores the component state and is automatically saving it in the local storage | ||
* if it changed. | ||
*/ | ||
export declare function mount(): void; | ||
/** | ||
* Updates the main button state. | ||
@@ -24,0 +24,0 @@ * @param updates - state changes to perform. |
import { Computed } from '@telegram-apps/signals'; | ||
import { State } from './types.js'; | ||
export declare const internalState: import('@telegram-apps/signals').Signal<State>; | ||
/** | ||
* Complete component state. | ||
*/ | ||
export declare const state: import('@telegram-apps/signals').Signal<State>; | ||
export declare const state: Computed<Required<State>>; | ||
/** | ||
@@ -8,0 +9,0 @@ * True if the component is currently mounted. |
@@ -5,4 +5,6 @@ import { RGB } from '@telegram-apps/bridge'; | ||
* The main button background color. | ||
* | ||
* This value may be missing in case, some specific RGB color was not yet set. | ||
*/ | ||
backgroundColor: RGB; | ||
backgroundColor?: RGB; | ||
/** | ||
@@ -30,4 +32,6 @@ * True if the Main Button has a shining effect. | ||
* The main button text color. | ||
* | ||
* This value may be missing in case, some specific RGB color was not yet set. | ||
*/ | ||
textColor: RGB; | ||
textColor?: RGB; | ||
} |
@@ -1,2 +0,2 @@ | ||
import { RGB } from '@telegram-apps/bridge'; | ||
import { RGB, BottomBarColor } from '@telegram-apps/bridge'; | ||
import { GetCssVarNameFn, HeaderColor } from './types.js'; | ||
@@ -9,2 +9,3 @@ /** | ||
* - `--tg-header-color` | ||
* - `--tg-bottom-bar-color` | ||
* | ||
@@ -15,3 +16,2 @@ * Variables are being automatically updated if theme parameters were changed. | ||
* mini app key. | ||
* MiniApp property. | ||
* @returns Function to stop updating variables. | ||
@@ -31,2 +31,5 @@ * @throws {TypedError} ERR_ALREADY_CALLED | ||
* if it changed. | ||
* | ||
* Internally, the function mounts the Theme Params component to work with correctly extracted | ||
* theme palette values. | ||
*/ | ||
@@ -50,2 +53,6 @@ export declare function mount(): void; | ||
/** | ||
* Updates the bottom bar background color. | ||
*/ | ||
export declare const setBottomBarColor: import('../../withIsSupported.js').WithIsSupported<(color: BottomBarColor) => void>; | ||
/** | ||
* Updates the header color. | ||
@@ -52,0 +59,0 @@ */ |
@@ -0,14 +1,38 @@ | ||
import { Computed } from '@telegram-apps/signals'; | ||
import { BackgroundColor, BottomBarColor } from '@telegram-apps/bridge'; | ||
import { HeaderColor, State } from './types.js'; | ||
/** | ||
* The Mini App background color. | ||
* @example "#ffaabb" | ||
*/ | ||
export declare const backgroundColor: import('@telegram-apps/signals').Signal<`#${string}`>; | ||
export declare const backgroundColor: import('@telegram-apps/signals').Signal<BackgroundColor>; | ||
/** | ||
* RGB representation of the background color. | ||
* | ||
* This value requires the Theme Params component to be mounted to extract a valid RGB value | ||
* of the color key. | ||
*/ | ||
export declare const backgroundColorRGB: Computed<`#${string}` | undefined>; | ||
/** | ||
* The Mini App bottom bar background color. | ||
*/ | ||
export declare const bottomBarColor: import('@telegram-apps/signals').Signal<BottomBarColor>; | ||
/** | ||
* RGB representation of the bottom bar background color. | ||
* | ||
* This value requires the Theme Params component to be mounted to extract a valid RGB value | ||
* of the color key. | ||
*/ | ||
export declare const bottomBarColorRGB: Computed<`#${string}` | undefined>; | ||
/** | ||
* The Mini App header color. | ||
* @example "#ffaabb" | ||
* @example "bg_color" | ||
*/ | ||
export declare const headerColor: import('@telegram-apps/signals').Signal<HeaderColor>; | ||
/** | ||
* RGB representation of the header color. | ||
* | ||
* This value requires the Theme Params component to be mounted to extract a valid RGB value | ||
* of the color key. | ||
*/ | ||
export declare const headerColorRGB: Computed<`#${string}` | undefined>; | ||
/** | ||
* True if the component is currently mounted. | ||
@@ -24,6 +48,6 @@ */ | ||
*/ | ||
export declare const isDark: import('@telegram-apps/signals').Computed<boolean>; | ||
export declare const isDark: Computed<boolean>; | ||
/** | ||
* Complete component state. | ||
*/ | ||
export declare const state: import('@telegram-apps/signals').Computed<State>; | ||
export declare const state: Computed<State>; |
@@ -1,2 +0,2 @@ | ||
import { HeaderColorKey, RGB } from '@telegram-apps/bridge'; | ||
import { HeaderColorKey, BottomBarColor, RGB, BackgroundColor } from '@telegram-apps/bridge'; | ||
/** | ||
@@ -7,3 +7,4 @@ * Mini App header color. | ||
export interface State { | ||
backgroundColor: RGB; | ||
backgroundColor: BackgroundColor; | ||
bottomBarColor: BottomBarColor; | ||
headerColor: HeaderColor; | ||
@@ -16,3 +17,3 @@ } | ||
*/ | ||
(property: 'bgColor' | 'headerColor'): string; | ||
(property: 'bgColor' | 'bottomBarColor' | 'headerColor'): string; | ||
} |
@@ -8,2 +8,9 @@ import { EventListener } from '@telegram-apps/bridge'; | ||
/** | ||
* Mounts the component. | ||
* | ||
* This function restores the component state and is automatically saving it in the local storage | ||
* if it changed. | ||
*/ | ||
export declare function mount(): void; | ||
/** | ||
* Adds a new main button click listener. | ||
@@ -20,9 +27,2 @@ * @param fn - event listener. | ||
/** | ||
* Mounts the component. | ||
* | ||
* This function restores the component state and is automatically saving it in the local storage | ||
* if it changed. | ||
*/ | ||
export declare function mount(): void; | ||
/** | ||
* Updates the main button state. | ||
@@ -29,0 +29,0 @@ * @param updates - state changes to perform. |
import { Computed } from '@telegram-apps/signals'; | ||
import { State } from './types.js'; | ||
export declare const internalState: import('@telegram-apps/signals').Signal<State>; | ||
/** | ||
* Complete component state. | ||
*/ | ||
export declare const state: import('@telegram-apps/signals').Signal<State>; | ||
export declare const state: Computed<Required<State>>; | ||
/** | ||
@@ -32,2 +33,6 @@ * True if the component is currently mounted. | ||
/** | ||
* @see State.position | ||
*/ | ||
export declare const position: Computed<import('@telegram-apps/bridge').SecondaryButtonPosition>; | ||
/** | ||
* @see State.text | ||
@@ -34,0 +39,0 @@ */ |
@@ -1,7 +0,9 @@ | ||
import { RGB } from '@telegram-apps/bridge'; | ||
import { RGB, SecondaryButtonPosition } from '@telegram-apps/bridge'; | ||
export interface State { | ||
/** | ||
* The Secondary Button background color. | ||
* | ||
* This value may be missing in case, some specific RGB color was not yet set. | ||
*/ | ||
backgroundColor: RGB; | ||
backgroundColor?: RGB; | ||
/** | ||
@@ -24,2 +26,6 @@ * True if the Secondary Button has a shining effect. | ||
/** | ||
* The button position relative to the main one. | ||
*/ | ||
position: SecondaryButtonPosition; | ||
/** | ||
* The Secondary Button text. | ||
@@ -30,4 +36,6 @@ */ | ||
* The Secondary Button text color. | ||
* | ||
* This value may be missing in case, some specific RGB color was not yet set. | ||
*/ | ||
textColor: RGB; | ||
textColor?: RGB; | ||
} |
@@ -1,5 +0,5 @@ | ||
this.telegramApps=this.telegramApps||{};this.telegramApps.sdk=function(o){"use strict";let re=class fi extends Error{constructor(t,n,r){super(typeof n=="object"?n.message:n||t,{cause:typeof n=="object"?n.cause:r}),this.type=t,Object.setPrototypeOf(this,fi.prototype)}};function Mt(e){return e.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}function pi(e){return e.replace(/_[a-z]/g,t=>t[1].toUpperCase())}const Bt="ERR_INVALID_VALUE",It="ERR_UNEXPECTED_VALUE",kt="ERR_UNEXPECTED_TYPE",qe="ERR_PARSE";function Nt(e,t){const n={};for(const r in e){const i=e[r];if(!i)continue;let a,s;typeof i=="function"?(a=r,s=i):[a,s]=i;try{const c=s(t(a));c!==void 0&&(n[r]=c)}catch(c){throw new re(qe,`Parser for "${r}" property failed${a===r?"":`. Source field: "${a}"`}`,c)}}return n}function Ue(e){let t=e;if(typeof t=="string")try{t=JSON.parse(t)}catch(n){throw new re(Bt,{cause:n})}if(typeof t!="object"||!t||Array.isArray(t))throw new re(It);return t}function I(e,t){return n=>{const r=i=>{if(!(n&&i===void 0))try{return t(i)}catch(a){throw new re(qe,{message:`"${e}" transformer failed to parse the value`,cause:a})}};return Object.assign(r,{isValid(i){try{return r(i),!0}catch{return!1}}})}}function Ae(e,t){return I(t||"object",n=>{const r=Ue(n);return Nt(e,i=>r[i])})}function ie(e){throw new re(kt,`Unexpected value received: ${JSON.stringify(e)}`)}const hi=I("boolean",e=>{if(typeof e=="boolean")return e;const t=String(e);if(t==="1"||t==="true")return!0;if(t==="0"||t==="false")return!1;ie(e)}),k=I("string",e=>{if(typeof e=="string"||typeof e=="number")return e.toString();ie(e)}),Re=I("number",e=>{if(typeof e=="number")return e;if(typeof e=="string"){const t=Number(e);if(!Number.isNaN(t))return t}ie(e)}),Vt=I("date",e=>e instanceof Date?e:new Date(Re()(e)*1e3));function jt(e,t){return I(t||"searchParams",n=>{typeof n!="string"&&!(n instanceof URLSearchParams)&&ie(n);const r=typeof n=="string"?new URLSearchParams(n):n;return Nt(e,i=>{const a=r.get(i);return a===null?void 0:a})})}function We(e){for(const t in e)e[t]=[Mt(t),e[t]];return e}const mi=e=>{const t=Re(),n=Re(!0),r=k(),i=k(!0),a=hi(!0),s=Ae(We({addedToAttachmentMenu:a,allowsWriteToPm:a,firstName:r,id:t,isBot:a,isPremium:a,languageCode:i,lastName:i,photoUrl:i,username:i}),"User")(!0);return jt(We({authDate:Vt(),canSendAfter:n,chat:Ae(We({id:t,type:r,title:r,photoUrl:i,username:i}),"Chat")(!0),chatInstance:i,chatType:i,hash:r,queryId:i,receiver:s,startParam:i,user:s}),"initData")(e)};function $e(e){return/^#[\da-f]{6}$/i.test(e)}function Lt(e){return/^#[\da-f]{3}$/i.test(e)}function ze(e){const t=e.replace(/\s/g,"").toLowerCase();if($e(t))return t;if(Lt(t)){let r="#";for(let i=0;i<3;i+=1)r+=t[1+i].repeat(2);return r}const n=t.match(/^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/)||t.match(/^rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),\d{1,3}\)$/);if(!n)throw new Error(`Value "${e}" does not satisfy any of known RGB formats.`);return n.slice(1).reduce((r,i)=>{const a=parseInt(i,10).toString(16);return r+(a.length===1?"0":"")+a},"#")}const bi=I("rgb",e=>ze(k()(e))),gi=I("themeParams",e=>{const t=bi(!0);return Object.entries(Ue(e)).reduce((n,[r,i])=>(n[pi(r)]=t(i),n),{})});function Ge(e){return JSON.stringify(Object.fromEntries(Object.entries(e).map(([t,n])=>[Mt(t),n])))}function wi(e){const{initDataRaw:t,startParam:n,showSettings:r,botInline:i}=e,a=new URLSearchParams;return a.set("tgWebAppPlatform",e.platform),a.set("tgWebAppThemeParams",Ge(e.themeParams)),a.set("tgWebAppVersion",e.version),t&&a.set("tgWebAppData",t),n&&a.set("tgWebAppStartParam",n),typeof r=="boolean"&&a.set("tgWebAppShowSettings",r?"1":"0"),typeof i=="boolean"&&a.set("tgWebAppBotInline",i?"1":"0"),a.toString()}function Ei(e,t){return I("array",n=>{let r;if(Array.isArray(n))r=n;else if(typeof n=="string")try{const i=JSON.parse(n);Array.isArray(i)&&(r=i)}catch{}return r||ie(n),r.map(e)})}function Fe(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Pe(...e){return e.map(t=>{if(typeof t=="string")return t;if(Fe(t))return Pe(Object.entries(t).map(n=>n[1]&&n[0]));if(Array.isArray(t))return Pe(...t)}).filter(Boolean).join(" ")}function yi(...e){return e.reduce((t,n)=>(Fe(n)&&Object.entries(n).forEach(([r,i])=>{const a=Pe(t[r],i);a&&(t[r]=a)}),t),{})}let ae=class _i extends Error{constructor(t,n,r){super(typeof n=="object"?n.message:n||t,{cause:typeof n=="object"?n.cause:r}),this.type=t,Object.setPrototypeOf(this,_i.prototype)}};function Ht(e){return e.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}function Si(e){return e.replace(/_[a-z]/g,t=>t[1].toUpperCase())}const vi="ERR_INVALID_VALUE",Ci="ERR_UNEXPECTED_VALUE",Ti="ERR_UNEXPECTED_TYPE",qt="ERR_PARSE";function Ut(e,t){const n={};for(const r in e){const i=e[r];if(!i)continue;let a,s;typeof i=="function"?(a=r,s=i):[a,s]=i;try{const c=s(t(a));c!==void 0&&(n[r]=c)}catch(c){throw new ae(qt,`Parser for "${r}" property failed${a===r?"":`. Source field: "${a}"`}`,c)}}return n}function Wt(e){let t=e;if(typeof t=="string")try{t=JSON.parse(t)}catch(n){throw new ae(vi,{cause:n})}if(typeof t!="object"||!t||Array.isArray(t))throw new ae(Ci);return t}function R(e,t){return n=>{const r=i=>{if(!(n&&i===void 0))try{return t(i)}catch(a){throw new ae(qt,{message:`"${e}" transformer failed to parse the value`,cause:a})}};return Object.assign(r,{isValid(i){try{return r(i),!0}catch{return!1}}})}}function $(e,t){return R(t||"object",n=>{const r=Wt(n);return Ut(e,i=>r[i])})}function se(e){throw new ae(Ti,`Unexpected value received: ${JSON.stringify(e)}`)}const Oe=R("boolean",e=>{if(typeof e=="boolean")return e;const t=String(e);if(t==="1"||t==="true")return!0;if(t==="0"||t==="false")return!1;se(e)}),T=R("string",e=>{if(typeof e=="string"||typeof e=="number")return e.toString();se(e)}),ce=R("number",e=>{if(typeof e=="number")return e;if(typeof e=="string"){const t=Number(e);if(!Number.isNaN(t))return t}se(e)}),Ai=R("date",e=>e instanceof Date?e:new Date(ce()(e)*1e3));function zt(e,t){return R(t||"searchParams",n=>{typeof n!="string"&&!(n instanceof URLSearchParams)&&se(n);const r=typeof n=="string"?new URLSearchParams(n):n;return Ut(e,i=>{const a=r.get(i);return a===null?void 0:a})})}function Ye(e){for(const t in e)e[t]=[Ht(t),e[t]];return e}const Ri=e=>{const t=ce(),n=ce(!0),r=T(),i=T(!0),a=Oe(!0),s=$(Ye({addedToAttachmentMenu:a,allowsWriteToPm:a,firstName:r,id:t,isBot:a,isPremium:a,languageCode:i,lastName:i,photoUrl:i,username:i}),"User")(!0);return zt(Ye({authDate:Ai(),canSendAfter:n,chat:$(Ye({id:t,type:r,title:r,photoUrl:i,username:i}),"Chat")(!0),chatInstance:i,chatType:i,hash:r,queryId:i,receiver:s,startParam:i,user:s}),"initData")(e)};function $i(e){return/^#[\da-f]{6}$/i.test(e)}function Pi(e){return/^#[\da-f]{3}$/i.test(e)}function Oi(e){const t=e.replace(/\s/g,"").toLowerCase();if($i(t))return t;if(Pi(t)){let r="#";for(let i=0;i<3;i+=1)r+=t[1+i].repeat(2);return r}const n=t.match(/^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/)||t.match(/^rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),\d{1,3}\)$/);if(!n)throw new Error(`Value "${e}" does not satisfy any of known RGB formats.`);return n.slice(1).reduce((r,i)=>{const a=parseInt(i,10).toString(16);return r+(a.length===1?"0":"")+a},"#")}const Di=R("rgb",e=>Oi(T()(e))),Mi=R("themeParams",e=>{const t=Di(!0);return Object.entries(Wt(e)).reduce((n,[r,i])=>(n[Si(r)]=t(i),n),{})});function Gt(e){return JSON.stringify(Object.fromEntries(Object.entries(e).map(([t,n])=>[Ht(t),n])))}const Bi=e=>{const t=T(),n=T(!0),r=Oe(!0);return zt({botInline:["tgWebAppBotInline",r],initData:["tgWebAppData",Ri(!0)],initDataRaw:["tgWebAppData",n],platform:["tgWebAppPlatform",t],showSettings:["tgWebAppShowSettings",r],startParam:["tgWebAppStartParam",n],themeParams:["tgWebAppThemeParams",Mi()],version:["tgWebAppVersion",t]},"launchParams")(e)};function Ii(e){const{initDataRaw:t,startParam:n,showSettings:r,botInline:i}=e,a=new URLSearchParams;return a.set("tgWebAppPlatform",e.platform),a.set("tgWebAppThemeParams",Gt(e.themeParams)),a.set("tgWebAppVersion",e.version),t&&a.set("tgWebAppData",t),n&&a.set("tgWebAppStartParam",n),typeof r=="boolean"&&a.set("tgWebAppShowSettings",r?"1":"0"),typeof i=="boolean"&&a.set("tgWebAppBotInline",i?"1":"0"),a.toString()}const Ft=$({eventType:T(),eventData:e=>e},"miniAppsMessage"),Yt=R("fn",e=>{if(typeof e=="function")return e;se(e)});function ki(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const Ni=$({TelegramWebviewProxy:$({postEvent:Yt()})()});function Jt(e){return Ni().isValid(e)}function Kt(){try{return window.self!==window.top}catch{return!0}}var Vi=Object.defineProperty,ji=(e,t,n)=>t in e?Vi(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Qt=(e,t,n)=>ji(e,typeof t!="symbol"?t+"":t,n);let _=class di extends Error{constructor(t,n,r){super(typeof n=="object"?n.message:n||t,{cause:typeof n=="object"?n.cause:r}),this.type=t,Object.setPrototypeOf(this,di.prototype)}};function De(e,t,n){return e.addEventListener(t,n),()=>e.removeEventListener(t,n)}function X(...e){const t=e.flat(1);return[t.push.bind(t),()=>{t.forEach(n=>{n()})}]}function Li(e,t){return e instanceof _&&e.type===t}function Je(e){return t=>Li(t,e)}const Ke="ERR_ABORTED",Qe="ERR_CANCELED",Ze="ERR_TIMED_OUT";function Zt(e){return new _(Ke,{cause:e})}const Hi=Je(Ze),qi=Je(Ke),Ui=Je(Qe);function Xt(e,t){return e.reject=t.reject,e}class h extends Promise{constructor(t,n){let r,i;typeof t=="function"?(r=t,i=n):i=t;let a,s;super((c,f)=>{i||(i={});const{abortSignal:u}=i;if(u&&u.aborted)return f(Zt(u.reason));const[p,y]=X(),C=oe=>(...Za)=>(y(),oe(...Za)),ne=new AbortController,{signal:Z}=ne;s=C(oe=>{ne.abort(oe),f(oe)}),a=C(c),u&&p(De(u,"abort",()=>{s(Zt(u.reason))}));const{timeout:Dt}=i;if(Dt){const oe=setTimeout(()=>{s(new _(Ze,`Timeout reached: ${Dt}ms`))},Dt);p(()=>{clearTimeout(oe)})}r&&r(a,s,Z)}),Qt(this,"reject"),this.reject=s}static withFn(t,n){return new h((r,i,a)=>{try{const s=t(a);return s instanceof Promise?s.then(r,i):r(s)}catch(s){i(s)}},n)}static resolve(t){return new h(n=>{n(t)})}static reject(t){return new h((n,r)=>{r(t)})}cancel(){this.reject(new _(Qe))}catch(t){return this.then(void 0,t)}finally(t){return Xt(super.finally(t),this)}then(t,n){return Xt(super.then(t,n),this)}}function xt(e,t){return e.resolve=t.resolve,e}class ue extends h{constructor(t,n){let r,i;typeof t=="function"?(r=t,i=n):i=t;let a;super((s,c,f)=>{a=s,r&&r(s,c,f)},i),Qt(this,"resolve"),this.resolve=a}static withFn(t,n){return new ue((r,i,a)=>h.withFn(t,{abortSignal:a}).then(r,i),n)}static resolve(t){return new ue(n=>{n(t)})}static reject(t){return new ue((n,r)=>{r(t)})}catch(t){return this.then(void 0,t)}finally(t){return xt(super.finally(t),this)}then(t,n){return xt(super.then(t,n),this)}}function Wi(e,t){return new h(n=>{setTimeout(n,e)},{abortSignal:t})}function en(e){return`tapps/${e}`}function P(e,t){sessionStorage.setItem(en(e),JSON.stringify(t))}function O(e){const t=sessionStorage.getItem(en(e));try{return t?JSON.parse(t):void 0}catch{}}function Xe(e){return e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`)}function zi(e,t){t||(t={});const{textColor:n,bgColor:r,shouldLog:i=!0}=t;function a(s,...c){if(!i||typeof i=="function"&&!i())return;const f="font-weight:bold;padding:0 5px;border-radius:5px";console[s](`%c${Intl.DateTimeFormat("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3,timeZone:"UTC"}).format(new Date)}%c / %c${e}`,`${f};background-color: lightblue;color:black`,"",`${f};${n?`color:${n};`:""}${r?`background-color:${r}`:""}`,...c)}return[function(...s){a("log",...s)},function(...s){a("error",...s)}]}function U(e,t){document.documentElement.style.setProperty(e,t)}function Me(e){document.documentElement.style.removeProperty(e)}function Gi(e,t){t()}function x(e,t){t||(t={});const n=t.equals||Object.is;let r=[],i=e;const a=u=>{if(!n(i,u)){const p=i;i=u,Gi(f,()=>{[...r].forEach(([y,C])=>{y(u,p),C&&c(y,!0)})})}};function s(u){const p=typeof u!="object"?{once:u}:u;return{once:p.once||!1,signal:p.signal||!1}}const c=(u,p)=>{const y=s(p),C=r.findIndex(([ne,Z])=>ne===u&&Z.once===y.once&&Z.signal===y.signal);C>=0&&r.splice(C,1)},f=Object.assign(function(){return Fi(f),i},{destroy(){r=[]},set:a,reset(){a(e)},sub(u,p){return r.push([u,s(p)]),()=>c(u,p)},unsub:c,unsubAll(){r=r.filter(u=>u[1].signal)}});return f}const xe=[];function Fi(e){xe.length&&xe[xe.length-1].add(e)}const tn=x(!1),[et,Yi]=zi("Bridge",{bgColor:"#9147ff",textColor:"white",shouldLog:tn}),Ji={clipboard_text_received:$({req_id:T(),data:e=>e===null?e:T(!0)(e)},"clipboard_text_received"),custom_method_invoked:$({req_id:T(),result:e=>e,error:T(!0)},"custom_method_invoked"),popup_closed:R("popup_closed",e=>e?$({button_id:t=>t==null?void 0:T()(t)})()(e):{}),viewport_changed:$({height:ce(),width:e=>e==null?window.innerWidth:ce()(e),is_state_stable:Oe(),is_expanded:Oe()},"viewport_changed")};function Ki(e){const t=window,[,n]=X(De(t,"resize",()=>{e(["viewport_changed",{width:window.innerWidth,height:window.innerHeight,is_state_stable:!0,is_expanded:!0}])}),De(t,"message",r=>{if(r.source!==t.parent)return;let i;try{i=Ft()(r.data)}catch{return}const{eventType:a,eventData:s}=i,c=Ji[a];try{const f=c?c()(s):s;et("Event received:",f?{eventType:a,eventData:f}:{eventType:a}),e([a,f])}catch(f){Yi([`An error occurred processing the "${a}" event from the Telegram application.`,"Please, file an issue here:","https://github.com/Telegram-Mini-Apps/telegram-apps/issues/new/choose"].join(` | ||
`),i,f)}}));return n}const tt=x(),nn=x();function on(){return nn()||nn.set(Ki(tt.set)),tt}const nt=x({});function rn(e){let t=nt()[e];return t||(t=x(void 0,{equals(){return!1}}),on().sub(n=>{n&&n[0]===e&&t.set(n[1])}),nt.set({...nt(),[e]:t})),t}function S(e,t,n){return rn(e).sub(t,n)}const an="ERR_METHOD_UNSUPPORTED",sn="ERR_RETRIEVE_LP_FAILED",cn="ERR_METHOD_PARAMETER_UNSUPPORTED",un="ERR_UNKNOWN_ENV",ln="ERR_INVOKE_CUSTOM_METHOD_RESPONSE",fn=x("https://web.telegram.org");function Be(e,t){et("Posting event:",t?{eventType:e,eventData:t}:{eventType:e});const n=window;if(Jt(n)){n.TelegramWebviewProxy.postEvent(e,JSON.stringify(t));return}const r=JSON.stringify({eventType:e,eventData:t});if(Kt())return n.parent.postMessage(r,fn());const{external:i}=n;if($({notify:Yt()})().isValid(i)){i.notify(r);return}throw new _(un)}function Ie(e,t,n){n||(n={});const{capture:r}=n,[i,a]=X();return new h(s=>{(Array.isArray(t)?t:[t]).forEach(c=>{i(S(c,f=>{(!r||(Array.isArray(t)?r({event:c,payload:f}):r(f)))&&s(f)}))}),(n.postEvent||Be)(e,n.params)},n).finally(a)}function ot(e){return Bi()(e)}function _n(e){return ot(e.replace(/^[^?#]*[?#]/,"").replace(/[?#]/g,"&"))}function Qi(){return _n(window.location.href)}function Zi(){const e=performance.getEntriesByType("navigation")[0];if(!e)throw new Error("Unable to get first navigation entry.");return _n(e.name)}const Xi="launchParams";function xi(){return ot(O(Xi)||"")}function dn(e){P("launchParams",Ii(e))}function pn(e){return e instanceof Error?e.message+(e.cause?` | ||
${pn(e.cause)}`:""):JSON.stringify(e)}function W(){const e=[];for(const t of[Qi,Zi,xi])try{const n=t();return dn(n),n}catch(n){e.push(n)}throw new _(sn,["Unable to retrieve launch parameters from any known source. Perhaps, you have opened your app outside Telegram?","📖 Refer to docs for more information:","https://docs.telegram-mini-apps.com/packages/telegram-apps-sdk/environment","Collected errors:",...e.map(t=>`— ${pn(t)}`)].join(` | ||
`))}function ea(e){if(e==="simple")try{return W(),!0}catch{return!1}return h.withFn(async()=>{if(Jt(window))return!0;try{return await Ie("web_app_request_theme","theme_changed",{timeout:100}),!0}catch{return!1}},e)}function ke(e,t){window.dispatchEvent(new MessageEvent("message",{data:JSON.stringify({eventType:e,eventData:t}),source:window.parent}))}function ta(e,t){if(typeof t=="string")try{const{eventType:n}=Ft()(t);n==="web_app_request_theme"&&ke("theme_changed",{theme_params:JSON.parse(Gt(e))}),n==="web_app_request_viewport"&&ke("viewport_changed",{width:window.innerWidth,height:window.innerHeight,is_state_stable:!0,is_expanded:!0})}catch{}}function na(e){var t;const n=typeof e=="string"?ot(e):e;dn(n);const r=(t=window.TelegramWebviewProxy)==null?void 0:t.postEvent;window.TelegramWebviewProxy={postEvent(i,a){ta(n.themeParams,JSON.stringify({eventType:i,eventData:a})),r==null||r(i,a)}},et("Environment was mocked by the mockTelegramEnv function")}function hn(){[["TelegramGameProxy_receiveEvent"],["TelegramGameProxy","receiveEvent"],["Telegram","WebView","receiveEvent"]].forEach(e=>{let t=window;e.forEach((n,r,i)=>{if(r===i.length-1){t[n]=ke;return}n in t||(t[n]={}),t=t[n]})})}function mn(){["TelegramGameProxy_receiveEvent","TelegramGameProxy","Telegram"].forEach(e=>{delete window[e]})}function z(e,t,n){rn(e).unsub(t,n)}function oa(e,t){return on().sub(e,t)}function ra(e,t){tt.unsub(e,t)}function bn(e){return({req_id:t})=>t===e}function gn(e){return e.split(".").map(Number)}function wn(e,t){const n=gn(e),r=gn(t),i=Math.max(n.length,r.length);for(let a=0;a<i;a+=1){const s=n[a]||0,c=r[a]||0;if(s!==c)return s>c?1:-1}return 0}function g(e,t){return wn(e,t)<=0}function m(e,t,n){if(typeof n=="string"){if(e==="web_app_open_link"){if(t==="try_instant_view")return g("6.4",n);if(t==="try_browser")return g("7.6",n)}if(e==="web_app_set_header_color"&&t==="color")return g("6.9",n);if(e==="web_app_close"&&t==="return_back")return g("7.6",n);if(e==="web_app_setup_main_button"&&t==="has_shine_effect")return g("7.10",n)}switch(e){case"web_app_open_tg_link":case"web_app_open_invoice":case"web_app_setup_back_button":case"web_app_set_background_color":case"web_app_set_header_color":case"web_app_trigger_haptic_feedback":return g("6.1",t);case"web_app_open_popup":return g("6.2",t);case"web_app_close_scan_qr_popup":case"web_app_open_scan_qr_popup":case"web_app_read_text_from_clipboard":return g("6.4",t);case"web_app_switch_inline_query":return g("6.7",t);case"web_app_invoke_custom_method":case"web_app_request_write_access":case"web_app_request_phone":return g("6.9",t);case"web_app_setup_settings_button":return g("6.10",t);case"web_app_biometry_get_info":case"web_app_biometry_open_settings":case"web_app_biometry_request_access":case"web_app_biometry_request_auth":case"web_app_biometry_update_token":return g("7.2",t);case"web_app_setup_swipe_behavior":return g("7.7",t);case"web_app_setup_secondary_button":return g("7.10",t);default:return["iframe_ready","iframe_will_reload","web_app_close","web_app_data_send","web_app_expand","web_app_open_link","web_app_ready","web_app_request_theme","web_app_request_viewport","web_app_setup_main_button","web_app_setup_closing_behavior"].includes(e)}}function En(e,t){t||(t="strict");const n=typeof t=="function"?t:r=>{const{method:i,version:a}=r;let s,c;if("param"in r?(s=`Parameter "${r.param}" of "${i}" method is unsupported in Mini Apps version ${a}`,c=cn):(s=`Method "${i}" is unsupported in Mini Apps version ${a}`,c=an),t==="strict")throw new _(c,s);return console.warn(s)};return(r,i)=>m(r,e)?ki(i)&&r==="web_app_set_header_color"&&"color"in i&&!m(r,"color",e)?n({version:e,method:r,param:"color"}):Be(r,i):n({version:e,method:r})}function yn(e,t,n,r){return Ie("web_app_invoke_custom_method","custom_method_invoked",{...r||{},params:{method:e,params:t,req_id:n},capture:bn(n)}).then(({result:i,error:a})=>{if(a)throw new _(ln,a);return i})}function ia(){return performance.getEntriesByType("navigation")[0]}function N(){const e=ia();return!!e&&e.type==="reload"}function Sn(e,t){return e.startsWith(t)?e:`${t}${e}`}function aa(e){return new URL(typeof e=="string"?e:[e.pathname||"",Sn(e.search||"","?"),Sn(e.hash||"","#")].join(""),"http://a")}let ee;function sa(e,t){ee&&ee.set(e,t)||t()}function ca(e){if(ee)return e();ee=new Map;try{e()}finally{ee.forEach(t=>t()),ee=void 0}}function l(e,t){t||(t={});const n=t.equals||Object.is;let r=[],i=e;const a=u=>{if(!n(i,u)){const p=i;i=u,sa(f,()=>{[...r].forEach(([y,C])=>{y(u,p),C&&c(y,!0)})})}};function s(u){const p=typeof u!="object"?{once:u}:u;return{once:p.once||!1,signal:p.signal||!1}}const c=(u,p)=>{const y=s(p),C=r.findIndex(([ne,Z])=>ne===u&&Z.once===y.once&&Z.signal===y.signal);C>=0&&r.splice(C,1)},f=Object.assign(function(){return ua(f),i},{destroy(){r=[]},set:a,reset(){a(e)},sub(u,p){return r.push([u,s(p)]),()=>c(u,p)},unsub:c,unsubAll(){r=r.filter(u=>u[1].signal)}});return f}const le=[];function ua(e){le.length&&le[le.length-1].add(e)}function V(e,t){let n=new Set;const r=l(a(),t);function i(){r.set(a())}function a(){n.forEach(f=>f.unsub(i,{signal:!0}));const s=new Set;let c;le.push(s);try{c=e()}finally{le.pop()}return s.forEach(f=>{f.sub(i,{signal:!0})}),n=s,c}return Object.assign(function(){return r()},{destroy:r.destroy,sub:r.sub,unsub:r.unsub,unsubAll:r.unsubAll})}const vn=l((()=>{let e=0;return()=>(e+=1).toString()})()),rt=l(Be),w=l("0.0");function la(e){e||(e={});const{postEvent:t}=e,n=e.version||W().version;w.set(n),rt.set(typeof t=="function"?t:En(n,t))}function Cn(){return vn()()}function fe(e,t,n){return yn(e,t,Cn(),{...n||{},postEvent:d})}const D=(e,t,n)=>(n||(n={}),n.postEvent||(n.postEvent=d),Ie(e,t,n)),d=(e,t)=>rt()(e,t),Tn="web_app_setup_back_button",An="back_button_pressed",Rn="backButton";function $n(){G.set(!1)}function Pn(){return m(Tn,w())}const G=l(!1),_e=l(!1);function On(){_e()||(G.set(N()&&O(Rn)||!1),G.sub(Dn),_e.set(!0))}function Dn(e){d(Tn,{is_visible:e}),P(Rn,e)}function Mn(e){return S(An,e)}function Bn(e){z(An,e)}function In(){G.set(!0)}function kn(){G.unsub(Dn),_e.set(!1)}const fa=Object.freeze(Object.defineProperty({__proto__:null,hide:$n,isMounted:_e,isSupported:Pn,isVisible:G,mount:On,offClick:Bn,onClick:Mn,show:In,unmount:kn},Symbol.toStringTag,{value:"Module"})),te="ERR_POPUP_INVALID_PARAMS",it="ERR_INVALID_HOSTNAME",Nn="ERR_INVALID_SLUG",Vn="ERR_DATA_INVALID_SIZE",jn="ERR_ACCESS_DENIED",v="ERR_ALREADY_CALLED",at="ERR_NOT_AVAILABLE";function Ln(e,t,{isMounting:n,isMounted:r,mountError:i}){return function(s){if(r())return h.resolve();if(n())throw new _(v);return n.set(!0),h.withFn(c=>e({abortSignal:c}),s).then(c=>[!0,c],c=>[!1,c]).then(c=>{ca(()=>{if(n.set(!1),r.set(!0),c[0])t(c[1]);else{const f=c[1];throw i.set(f),f}})})}}const j=l(),de=l(!1),pe=l(!1),st=l(!1),ct=l(!1),ut=l(void 0);function L(e,t,n){return Object.assign(e,{isSupported(){return m(t,w())&&(!n||n())}})}function lt(e){return e.available?{available:!0,tokenSaved:e.token_saved,deviceId:e.device_id,accessRequested:e.access_requested,type:e.type,accessGranted:e.access_granted}:{available:!1}}const Hn="web_app_biometry_get_info",qn=L(e=>D(Hn,"biometry_info_received",e).then(lt),Hn),_a=Object.freeze(Object.defineProperty({__proto__:null,request:qn},Symbol.toStringTag,{value:"Module"})),Un="web_app_biometry_request_auth",da="web_app_biometry_request_access",pa="web_app_biometry_open_settings",ha="web_app_biometry_update_token",ft="biometry_info_received",Wn="biometry";function zn(e){if(de())return h.reject(new _(v));const t=j();return!t||!t.available?h.reject(new _(at)):(de.set(!0),e||(e={}),D(Un,"biometry_auth_requested",{...e,params:{reason:(e.reason||"").trim()}}).then(n=>{const{token:r}=n;return typeof r=="string"&&j.set({...t,token:r}),n}).finally(()=>{de.set(!1)}))}function _t(){return m(Un,w())}function Gn(){d(pa)}function Fn(e){return pe()?h.reject(new _(v)):(pe.set(!0),e||(e={}),D(da,ft,{...e,params:{reason:e.reason||""}}).then(lt).then(t=>{if(!t.available)throw new _(at);return j.set(t),t.accessGranted}).finally(()=>{pe.set(!1)}))}const Yn=Ln(e=>{if(!_t())return{available:!1};const t=N()&&O(Wn);return t||qn(e)},e=>{S(ft,Jn),j.sub(Kn),j.set(e)},{isMounted:st,mountError:ut,isMounting:ct}),Jn=e=>{j.set(lt(e))};function Kn(e){e&&P(Wn,e)}function Qn(){z(ft,Jn),j.unsub(Kn)}function Zn(e){return e||(e={}),D(ha,"biometry_token_updated",{...e,params:{token:e.token||"",reason:e.reason}}).then(t=>t.status)}const ma=Object.freeze(Object.defineProperty({__proto__:null,authenticate:zn,isAuthenticating:de,isMounted:st,isMounting:ct,isRequestingAccess:pe,isSupported:_t,mount:Yn,mountError:ut,openSettings:Gn,requestAccess:Fn,state:j,unmount:Qn,updateToken:Zn},Symbol.toStringTag,{value:"Module"})),Xn="closingConfirmation";function xn(){F.set(!1)}const he=l(!1),F=l(!1);function eo(){F.set(!0)}function to(){he()||(F.set(N()&&O(Xn)||!1),F.sub(no),he.set(!0))}function no(e){d("web_app_setup_closing_behavior",{need_confirmation:e}),P(Xn,e)}function oo(){F.unsub(no),he.set(!1)}const ba=Object.freeze(Object.defineProperty({__proto__:null,disableConfirmation:xn,enableConfirmation:eo,isConfirmationEnabled:F,isMounted:he,mount:to,unmount:oo},Symbol.toStringTag,{value:"Module"})),ga="web_app_invoke_custom_method";function ro(e,t){const n=Array.isArray(e)?e:[e];return n.length?fe("deleteStorageValues",{keys:n},t).then():h.resolve()}function io(e,t){const n=Array.isArray(e)?e:[e];return n.length?fe("getStorageValues",{keys:n},t).then(r=>{const i=Ae(Object.fromEntries(n.map(a=>[a,k()])))()(r);return Array.isArray(e)?i:i[e]}):h.resolve(typeof e=="string"?"":{})}function ao(e){return fe("getStorageKeys",{},e).then(Ei(k())())}function so(){return m(ga,w())}function co(e,t,n){return fe("saveStorageValue",{key:e,value:t},n).then()}const wa=Object.freeze(Object.defineProperty({__proto__:null,deleteItem:ro,getItem:io,getKeys:ao,isSupported:so,setItem:co},Symbol.toStringTag,{value:"Module"})),Ne="web_app_trigger_haptic_feedback";function uo(e){d(Ne,{type:"impact",impact_style:e})}function lo(){return m(Ne,w())}function fo(e){d(Ne,{type:"notification",notification_type:e})}function _o(){d(Ne,{type:"selection_change"})}const Ea=Object.freeze(Object.defineProperty({__proto__:null,impactOccurred:uo,isSupported:lo,notificationOccurred:fo,selectionChanged:_o},Symbol.toStringTag,{value:"Module"})),Ve=l(void 0);function M(e){return V(()=>{const t=Ve();return t?t[e]:void 0})}const dt=M("authDate"),pt=M("canSendAfter"),po=V(()=>{const e=dt(),t=pt();return t&&e?new Date(e.getTime()+t*1e3):void 0}),ho=M("chat"),mo=M("chatType"),bo=M("chatInstance"),go=M("hash"),wo=M("queryId"),ht=l(),Eo=M("receiver"),yo=M("startParam"),So=M("user");function vo(){const e=W();Ve.set(e.initData),ht.set(e.initDataRaw)}const ya=Object.freeze(Object.defineProperty({__proto__:null,authDate:dt,canSendAfter:pt,canSendAfterDate:po,chat:ho,chatInstance:bo,chatType:mo,hash:go,queryId:wo,raw:ht,receiver:Eo,restore:vo,startParam:yo,state:Ve,user:So},Symbol.toStringTag,{value:"Module"}));function Sa(e){return mi()(e)}const va=Object.freeze(Object.defineProperty({__proto__:null,parse:Sa},Symbol.toStringTag,{value:"Module"})),Co="web_app_open_invoice",me=l(!1);function To(){return m(Co,w())}async function Ao(e,t,n){if(me())throw new _(v);let r;if(t==="url"){const{hostname:i,pathname:a}=new URL(e,window.location.href);if(i!=="t.me")throw new _(it);const s=a.match(/^\/(\$|invoice\/)([A-Za-z0-9\-_=]+)$/);if(!s)throw new _(Nn);[,,r]=s}else r=e,n=t;return me.set(!0),D(Co,"invoice_closed",{...n,params:{slug:r},capture:i=>r===i.slug}).then(i=>i.status).finally(()=>{me.set(!1)})}const Ca=Object.freeze(Object.defineProperty({__proto__:null,isOpened:me,isSupported:To,open:Ao},Symbol.toStringTag,{value:"Module"}));function mt(e){const t=ze(e);return Math.sqrt([.299,.587,.114].reduce((n,r,i)=>{const a=parseInt(t.slice(1+i*2,1+(i+1)*2),16);return n+a*a*r},0))<120}const be=l(!1),ge=l(!1),A=l({});function b(e){return V(()=>A()[e])}const Ro=b("accentTextColor"),bt=b("bgColor"),gt=b("buttonColor"),wt=b("buttonTextColor"),$o=b("bottomBarBgColor"),Po=b("destructiveTextColor"),Et=b("headerBgColor"),Oo=b("hintColor"),Do=V(()=>{const{bgColor:e}=A();return!e||mt(e)}),Mo=b("linkColor"),Bo=b("secondaryBgColor"),Io=b("sectionBgColor"),ko=b("sectionHeaderTextColor"),No=b("sectionSeparatorColor"),Vo=b("subtitleTextColor"),jo=b("textColor");function Lo(e){return gi()(e)}const Ta=Object.freeze(Object.defineProperty({__proto__:null,parse:Lo,serialize:Ge},Symbol.toStringTag,{value:"Module"})),Ho="themeParams",qo="theme_changed";function Uo(e){if(ge())throw new _(v);e||(e=r=>`--tg-theme-${Xe(r)}`);function t(r){Object.entries(A()).forEach(([i,a])=>{a&&r(i,a)})}function n(){t((r,i)=>{U(e(r),i)})}return n(),A.sub(n),ge.set(!0),()=>{t(Me),A.unsub(n),ge.set(!1)}}function je(){be()||(S(qo,Wo),A.set(N()&&O(Ho)||W().themeParams),be.set(!0))}const Wo=e=>{const t=Lo(e.theme_params);A.set(t),P(Ho,t)};function zo(){z(qo,Wo),be.set(!1)}const Aa=Object.freeze(Object.defineProperty({__proto__:null,accentTextColor:Ro,backgroundColor:bt,bindCssVars:Uo,bottomBarBgColor:$o,buttonColor:gt,buttonTextColor:wt,destructiveTextColor:Po,headerBackgroundColor:Et,hintColor:Oo,isCssVarsBound:ge,isDark:Do,isMounted:be,linkColor:Mo,mount:je,secondaryBackgroundColor:Bo,sectionBackgroundColor:Io,sectionHeaderTextColor:ko,sectionSeparatorColor:No,state:A,subtitleTextColor:Vo,textColor:jo,unmount:zo},Symbol.toStringTag,{value:"Module"})),q=l({backgroundColor:"#2481cc",hasShineEffect:!1,isEnabled:!0,isLoaderVisible:!1,isVisible:!1,text:"Continue",textColor:"#ffffff"}),we=l(!1);function Y(e){return V(()=>q()[e])}const Go=Y("backgroundColor"),Fo=Y("hasShineEffect"),Yo=Y("isEnabled"),Jo=Y("isLoaderVisible"),Ko=Y("isVisible"),Qo=Y("text"),Zo=Y("textColor"),Xo="main_button_pressed",xo="mainButton";function er(e){return S(Xo,e)}function tr(e){z(Xo,e)}function nr(){if(!we()){const e=N()&&O(xo);e?q.set(e):(je(),yt({backgroundColor:gt(),textColor:wt()})),q.sub(or),we.set(!0)}}function or(e){e.text&&d("web_app_setup_main_button",{has_shine_effect:e.hasShineEffect,is_visible:e.isVisible,is_active:e.isEnabled,is_progress_visible:e.isLoaderVisible,text:e.text,color:e.backgroundColor,text_color:e.textColor}),P(xo,e)}function yt(e){q.set({...q(),...Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))})}function rr(){q.unsub(or),we.set(!1)}const Ra=Object.freeze(Object.defineProperty({__proto__:null,backgroundColor:Go,hasShineEffect:Fo,isEnabled:Yo,isLoaderVisible:Jo,isMounted:we,isVisible:Ko,mount:nr,offClick:tr,onClick:er,setParams:yt,state:q,text:Qo,textColor:Zo,unmount:rr},Symbol.toStringTag,{value:"Module"})),ir=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));function $a(e,t){return Object.assign(e,{supports(n){const r=t[n];return m(r[0],r[1],w())}})}const B=l("#000000"),H=l("bg_color"),Ee=l(!1),ye=l(!1),ar=V(()=>mt(B())),St=V(()=>({backgroundColor:B(),headerColor:H()})),sr="web_app_set_background_color",vt="web_app_set_header_color",cr="miniApp";function ur(e){if(ye())throw new _(v);e||(e=s=>`--tg-${Xe(s)}`);const t=e("bgColor"),n=e("headerColor");function r(){const s=A(),c=H();if($e(c))return U(n,c);const{secondaryBgColor:f,bgColor:u}=s;if(c==="bg_color"&&u)return U(n,u);c==="secondary_bg_color"&&f&&U(n,f)}function i(){U(t,B())}i(),r();const[,a]=X(B.sub(i),[H,A].map(s=>s.sub(r)));return ye.set(!0),()=>{[n,t].forEach(Me),a(),ye.set(!1)}}function lr(e){d("web_app_close",{return_back:e})}function fr(){if(!Ee()){const e=N()&&O(cr);je(),B.set(e?e.backgroundColor:bt()||"#000000"),B.sub(dr),H.set(e?e.headerColor:Et()||"bg_color"),H.sub(_r),Ee.set(!0)}}function _r(e){hr(),d(vt,$e(e)?{color:e}:{color_key:e})}function dr(e){hr(),d(sr,{color:e})}function pr(){d("web_app_ready")}function hr(){P(cr,St())}const mr=L(e=>{B.set(e)},sr),br=$a(L(e=>{H.set(e)},vt),{color:[vt,"color"]});function gr(){B.unsub(dr),H.unsub(_r),Ee.set(!1)}const Pa=Object.freeze(Object.defineProperty({__proto__:null,backgroundColor:B,bindCssVars:ur,close:lr,headerColor:H,isCssVarsBound:ye,isDark:ar,isMounted:Ee,mount:fr,ready:pr,setBackgroundColor:mr,setHeaderColor:br,state:St,unmount:gr},Symbol.toStringTag,{value:"Module"})),Se=l(!1);function Oa(e){const t=e.message.trim(),n=(e.title||"").trim(),r=e.buttons||[];if(n.length>64)throw new _(te,`Invalid title: ${n}`);if(!t||t.length>256)throw new _(te,`Invalid message: ${t}`);if(r.length>3)throw new _(te,`Invalid buttons count: ${r.length}`);return{title:n,message:t,buttons:r.length?r.map((i,a)=>{const s=i.id||"";if(s.length>64)throw new _(te,`Button with index ${a} has invalid id: ${s}`);if(!i.type||i.type==="default"||i.type==="destructive"){const c=i.text.trim();if(!c||c.length>64)throw new _(te,`Button with index ${a} has invalid text: ${c}`);return{type:i.type,text:c,id:s}}return{type:i.type,id:s}}):[{type:"close",id:""}]}}const wr="web_app_open_popup";function Er(){return m(wr,w())}async function yr(e){if(Se())throw new _(v);Se.set(!0);try{const{button_id:t=null}=await D(wr,"popup_closed",{...e,params:Oa(e)});return t}finally{Se.set(!1)}}const Da=Object.freeze(Object.defineProperty({__proto__:null,isOpened:Se,isSupported:Er,open:yr},Symbol.toStringTag,{value:"Module"})),Ma=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),Ba="web_app_close_scan_qr_popup",Sr="web_app_open_scan_qr_popup",Ia="scan_qr_popup_closed",ka="qr_text_received";function Le(){J.set(!1),d(Ba)}const J=l(!1);function vr(){return m(Sr,w())}function Cr(e){return h.withFn(t=>{if(J())throw new _(v);J.set(!0),e||(e={});const{onCaptured:n,text:r,capture:i}=e,[,a]=X(J.sub(()=>{s.resolve()}),S(Ia,()=>{J.set(!1)}),S(ka,c=>{n?n(c.data):i&&i(c.data)&&(s.resolve(c.data),Le())})),s=new ue({abortSignal:t}).catch(Le).finally(a);return(e.postEvent||d)(Sr,{text:r}),s},e)}const Na=Object.freeze(Object.defineProperty({__proto__:null,close:Le,isOpened:J,isSupported:vr,open:Cr},Symbol.toStringTag,{value:"Module"})),Tr="web_app_setup_settings_button",Ar="settings_button_pressed",Rr="settingsButton";function $r(){K.set(!1)}const K=l(!1),ve=l(!1);function Pr(){return m(Tr,w())}function Or(){ve()||(K.set(N()&&O(Rr)||!1),K.sub(Dr),ve.set(!0))}function Dr(e){d(Tr,{is_visible:e}),P(Rr,e)}function Mr(e){return S(Ar,e)}function Br(e){z(Ar,e)}function Ir(){K.set(!0)}function kr(){K.unsub(Dr),ve.set(!1)}const Va=Object.freeze(Object.defineProperty({__proto__:null,hide:$r,isMounted:ve,isSupported:Pr,isVisible:K,mount:Or,offClick:Br,onClick:Mr,show:Ir,unmount:kr},Symbol.toStringTag,{value:"Module"})),Nr="web_app_setup_swipe_behavior",Vr="swipeBehavior";function jr(){Q.set(!1)}function Lr(){Q.set(!0)}const Ce=l(!1),Q=l(!1);function Hr(){return m(Nr,w())}function qr(){Ce()||(Q.set(N()&&O(Vr)||!1),Q.sub(Ur),Ce.set(!0))}function Ur(e){d(Nr,{allow_vertical_swipe:e}),P(Vr,e)}function Wr(){Q.unsub(Ur),Ce.set(!1)}const ja=Object.freeze(Object.defineProperty({__proto__:null,disableVertical:jr,enableVertical:Lr,isMounted:Ce,isSupported:Hr,isVerticalEnabled:Q,mount:qr,unmount:Wr},Symbol.toStringTag,{value:"Module"})),E=l({height:0,width:0,isExpanded:!1,stableHeight:0}),Ct=l(!1),Te=l(!1),Tt=l(!1),At=l(void 0);function He(e){return V(()=>E()[e])}const zr=He("height"),Gr=He("isExpanded"),Fr=V(()=>{const e=E();return e.height===e.stableHeight}),Yr=He("stableHeight"),Jr=He("width");function Kr(e){return D("web_app_request_viewport","viewport_changed",e).then(t=>({height:t.height,width:t.width,isExpanded:t.is_expanded,isStable:t.is_state_stable}))}const La=Object.freeze(Object.defineProperty({__proto__:null,request:Kr},Symbol.toStringTag,{value:"Module"}));function Qr(e){if(Te())throw new _(v);e||(e=r=>`--tg-viewport-${Xe(r)}`);const t=["height","width","stableHeight"];function n(){t.forEach(r=>{U(e(r),`${E()[r]}px`)})}return n(),E.sub(n),Te.set(!0),()=>{t.forEach(Me),E.unsub(n),Te.set(!1)}}function Zr(){d("web_app_expand")}function Xr(e){return{isExpanded:e.isExpanded,height:Rt(e.height),width:Rt(e.width),stableHeight:Rt(e.stableHeight)}}const xr=Ln(e=>{const t=N()&&O("viewport");if(t)return t;if(["macos","tdesktop","unigram","webk","weba","web"].includes(W().platform)){const n=window;return{isExpanded:!0,height:n.innerHeight,width:n.innerWidth,stableHeight:n.innerHeight}}return e.timeout||(e.timeout=1e3),Kr(e).then(n=>({height:n.height,isExpanded:n.isExpanded,stableHeight:n.isStable?n.height:E().stableHeight,width:n.width}))},e=>{S("viewport_changed",ei),E.sub(ti),E.set(Xr(e))},{isMounted:Ct,isMounting:Tt,mountError:At}),ei=e=>{E.set(Xr({height:e.height,width:e.width,isExpanded:e.is_expanded,stableHeight:e.is_state_stable?e.height:E().stableHeight}))};function ti(e){P("viewport",e)}function Rt(e){return Math.max(e,0)}function ni(){z("viewport_changed",ei),E.unsub(ti)}const Ha=Object.freeze(Object.defineProperty({__proto__:null,bindCssVars:Qr,expand:Zr,height:zr,isCssVarsBound:Te,isExpanded:Gr,isMounted:Ct,isMounting:Tt,isStable:Fr,mount:xr,mountError:At,stableHeight:Yr,state:E,unmount:ni,width:Jr},Symbol.toStringTag,{value:"Module"})),oi="web_app_open_tg_link";function qa(e,t){t||(t={}),d("web_app_open_link",{url:aa(e).toString(),try_browser:t.tryBrowser,try_instant_view:t.tryInstantView})}function ri(e){const{hostname:t,pathname:n,search:r}=new URL(e,"https://t.me");if(t!=="t.me")throw new _(it);if(!m(oi,w())){window.location.href=e;return}d(oi,{path_full:n+r})}function Ua(e,t){ri("https://t.me/share/url?"+new URLSearchParams({url:e,text:t||""}).toString().replace(/\+/g,"%20"))}const $t="web_app_request_phone",ii="web_app_request_write_access";let Pt,Ot;function ai(e){return e||(e={}),fe("getRequestedContact",{},{...e,timeout:e.timeout||5e3}).then(jt({contact:Ae({userId:["user_id",Re()],phoneNumber:["phone_number",k()],firstName:["first_name",k()],lastName:["last_name",k(!0)]})(),authDate:["auth_date",Vt()],hash:k()})())}const Wa=L(e=>new h(async(t,n,r)=>{const i={postEvent:(e||{}).postEvent,abortSignal:r};try{return t(await ai(i))}catch{}if(await si(i)!=="sent")throw new _(jn);let s=50;for(;!r.aborted;){try{return t(await ai(i))}catch{}await Wi(s),s+=50}},e),$t),si=L(e=>{if(Pt)throw new _(v);return Pt=!0,D($t,"phone_requested",e).then(t=>t.status).finally(()=>{Pt=void 0})},$t),za=L(e=>{if(Ot)throw new _(v);return Ot=!0,D(ii,"write_access_requested",e).then(t=>t.status).finally(()=>{Ot=void 0})},ii),ci="web_app_read_text_from_clipboard",ui="web_app_switch_inline_query",li="web_app_share_to_story",Ga=L(e=>{const t=Cn();return D(ci,"clipboard_text_received",{...e,params:{req_id:t},capture:bn(t)}).then(({data:n=null})=>n)},ci);function Fa(e){const{size:t}=new Blob([e]);if(!t||t>4096)throw new _(Vn);d("web_app_data_send",{data:e})}const Ya=L((e,t)=>{t||(t={}),(t.postEvent||d)(li,{text:t.text,media_url:e,widget_link:t.widgetLink})},li),Ja=L((e,t)=>{d(ui,{query:e,chat_types:t||[]})},ui,()=>!!W().botInline);function Ka(){return typeof window>"u"}function Qa(e){la(e),hn();const[t,n]=X(S("reload_iframe",()=>{d("iframe_will_reload"),window.location.reload()}),mn),{acceptCustomStyles:r=!0}=e||{};if(r){const i=document.createElement("style");i.id="telegram-custom-styles",document.head.appendChild(i),t(S("set_custom_style",a=>{i.innerHTML=a}),()=>{document.head.removeChild(i)})}return d("iframe_ready",{reload_supported:!0}),n}return o.$createRequestId=vn,o.$debug=tn,o.$postEvent=rt,o.$targetOrigin=fn,o.$version=w,o.Biometry=_a,o.CancelablePromise=h,o.ERR_ABORTED=Ke,o.ERR_ACCESS_DENIED=jn,o.ERR_ALREADY_CALLED=v,o.ERR_CANCELED=Qe,o.ERR_CUSTOM_METHOD_ERR_RESPONSE=ln,o.ERR_DATA_INVALID_SIZE=Vn,o.ERR_INVALID_HOSTNAME=it,o.ERR_INVALID_SLUG=Nn,o.ERR_INVALID_VALUE=Bt,o.ERR_METHOD_PARAMETER_UNSUPPORTED=cn,o.ERR_METHOD_UNSUPPORTED=an,o.ERR_NOT_AVAILABLE=at,o.ERR_PARSE=qe,o.ERR_POPUP_INVALID_PARAMS=te,o.ERR_RETRIEVE_LP_FAILED=sn,o.ERR_TIMED_OUT=Ze,o.ERR_UNEXPECTED_TYPE=kt,o.ERR_UNEXPECTED_VALUE=It,o.ERR_UNKNOWN_ENV=un,o.InitData=va,o.MainButton=ir,o.MiniApp=ir,o.Popup=Ma,o.ThemeParams=Ta,o.TypedError=_,o.Viewport=La,o.addEventListener=De,o.authenticateBiometry=zn,o.backButton=fa,o.bindMiniAppCssVars=ur,o.bindThemeParamsCssVars=Uo,o.bindViewportCssVars=Qr,o.biometry=ma,o.biometryMountError=ut,o.biometryState=j,o.classNames=Pe,o.closeMiniApp=lr,o.closeQrScanner=Le,o.closingBehavior=ba,o.cloudStorage=wa,o.compareVersions=wn,o.createPostEvent=En,o.defineEventHandlers=hn,o.deleteCloudStorageItem=ro,o.deleteCssVar=Me,o.disableClosingConfirmation=xn,o.disableVerticalSwipes=jr,o.emitMiniAppsEvent=ke,o.enableClosingConfirmation=eo,o.enableVerticalSwipes=Lr,o.expandViewport=Zr,o.getCloudStorageItem=io,o.getCloudStorageKeys=ao,o.hapticFeedback=Ea,o.hapticFeedbackImpactOccurred=uo,o.hapticFeedbackNotificationOccurred=fo,o.hapticFeedbackSelectionChanged=_o,o.hideBackButton=$n,o.hideSettingsButton=$r,o.init=Qa,o.initData=ya,o.initDataAuthDate=dt,o.initDataCanSendAfter=pt,o.initDataCanSendAfterDate=po,o.initDataChat=ho,o.initDataChatInstance=bo,o.initDataChatType=mo,o.initDataHash=go,o.initDataQueryId=wo,o.initDataRaw=ht,o.initDataReceiver=Eo,o.initDataStartParam=yo,o.initDataState=Ve,o.initDataUser=So,o.invoice=Ca,o.invokeCustomMethod=yn,o.isAbortError=qi,o.isAuthenticatingBiometry=de,o.isBackButtonMounted=_e,o.isBackButtonSupported=Pn,o.isBackButtonVisible=G,o.isBiometryMounted=st,o.isBiometryMounting=ct,o.isBiometrySupported=_t,o.isCanceledError=Ui,o.isClosingBehaviorMounted=he,o.isClosingConfirmationEnabled=F,o.isCloudStorageSupported=so,o.isColorDark=mt,o.isHapticFeedbackSupported=lo,o.isIframe=Kt,o.isInvoiceOpened=me,o.isInvoiceSupported=To,o.isMainButtonEnabled=Yo,o.isMainButtonLoaderVisible=Jo,o.isMainButtonMounted=we,o.isMainButtonVisible=Ko,o.isMiniAppCssVarsBound=ye,o.isMiniAppDark=ar,o.isMiniAppMounted=Ee,o.isPopupOpened=Se,o.isPopupSupported=Er,o.isQrScannerOpened=J,o.isQrScannerSupported=vr,o.isRGB=$e,o.isRGBShort=Lt,o.isRecord=Fe,o.isRequestingBiometryAccess=pe,o.isSSR=Ka,o.isSettingsButtonMounted=ve,o.isSettingsButtonSupported=Pr,o.isSettingsButtonVisible=K,o.isSwipeBehaviorMounted=Ce,o.isSwipeBehaviorSupported=Hr,o.isTMA=ea,o.isThemeParamsCssVarsBound=ge,o.isThemeParamsDark=Do,o.isThemeParamsMounted=be,o.isTimeoutError=Hi,o.isVerticalSwipesEnabled=Q,o.isViewportCssVarsBound=Te,o.isViewportExpanded=Gr,o.isViewportMounted=Ct,o.isViewportMounting=Tt,o.isViewportStable=Fr,o.mainButton=Ra,o.mainButtonBackgroundColor=Go,o.mainButtonHasShineEffect=Fo,o.mainButtonState=q,o.mainButtonText=Qo,o.mainButtonTextColor=Zo,o.mergeClassNames=yi,o.miniApp=Pa,o.miniAppBackgroundColor=B,o.miniAppHeaderColor=H,o.miniAppReady=pr,o.miniAppState=St,o.mockTelegramEnv=na,o.mountBackButton=On,o.mountBiometry=Yn,o.mountClosingBehavior=to,o.mountMainButton=nr,o.mountMiniApp=fr,o.mountSettingsButton=Or,o.mountSwipeBehavior=qr,o.mountThemeParams=je,o.mountViewport=xr,o.off=z,o.offBackButtonClick=Bn,o.offMainButtonClick=tr,o.offSettingsButtonClick=Br,o.on=S,o.onBackButtonClick=Mn,o.onMainButtonClick=er,o.onSettingsButtonClick=Mr,o.openBiometrySettings=Gn,o.openInvoice=Ao,o.openLink=qa,o.openPopup=yr,o.openQrScanner=Cr,o.openTelegramLink=ri,o.popup=Da,o.postEvent=Be,o.qrScanner=Na,o.readTextFromClipboard=Ga,o.removeEventHandlers=mn,o.request=Ie,o.requestBiometryAccess=Fn,o.requestContact=Wa,o.requestPhoneAccess=si,o.requestWriteAccess=za,o.restoreInitData=vo,o.retrieveLaunchParams=W,o.sendData=Fa,o.serializeLaunchParams=wi,o.serializeThemeParams=Ge,o.setCloudStorageItem=co,o.setCssVar=U,o.setMainButtonParams=yt,o.setMiniAppBackgroundColor=mr,o.setMiniAppHeaderColor=br,o.settingsButton=Va,o.shareStory=Ya,o.shareURL=Ua,o.showBackButton=In,o.showSettingsButton=Ir,o.subscribe=oa,o.supports=m,o.swipeBehavior=ja,o.switchInlineQuery=Ja,o.themeParams=Aa,o.themeParamsAccentTextColor=Ro,o.themeParamsBackgroundColor=bt,o.themeParamsBottomBarBgColor=$o,o.themeParamsButtonColor=gt,o.themeParamsButtonTextColor=wt,o.themeParamsDestructiveTextColor=Po,o.themeParamsHeaderBackgroundColor=Et,o.themeParamsHintColor=Oo,o.themeParamsLinkColor=Mo,o.themeParamsSecondaryBackgroundColor=Bo,o.themeParamsSectionBackgroundColor=Io,o.themeParamsSectionHeaderTextColor=ko,o.themeParamsSectionSeparatorColor=No,o.themeParamsState=A,o.themeParamsSubtitleTextColor=Vo,o.themeParamsTextColor=jo,o.toRGB=ze,o.toRecord=Ue,o.unmountBackButton=kn,o.unmountBiometry=Qn,o.unmountClosingBehavior=oo,o.unmountMainButton=rr,o.unmountMiniApp=gr,o.unmountSettingsButton=kr,o.unmountSwipeBehavior=Wr,o.unmountThemeParams=zo,o.unmountViewport=ni,o.unsubscribe=ra,o.updateBiometryToken=Zn,o.viewport=Ha,o.viewportHeight=zr,o.viewportMountError=At,o.viewportStableHeight=Yr,o.viewportState=E,o.viewportWidth=Jr,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),o}({}); | ||
this.telegramApps=this.telegramApps||{};this.telegramApps.sdk=function(o){"use strict";let ae=class Wi extends Error{constructor(t,n,r){super(typeof n=="object"?n.message:n||t,{cause:typeof n=="object"?n.cause:r}),this.type=t,Object.setPrototypeOf(this,Wi.prototype)}};function Wt(e){return e.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}function Fi(e){return e.replace(/_[a-z]/g,t=>t[1].toUpperCase())}const Gt="ERR_INVALID_VALUE",zt="ERR_UNEXPECTED_VALUE",Ft="ERR_UNEXPECTED_TYPE",Qe="ERR_PARSE";function Yt(e,t){const n={};for(const r in e){const i=e[r];if(!i)continue;let a,s;typeof i=="function"?(a=r,s=i):[a,s]=i;try{const c=s(t(a));c!==void 0&&(n[r]=c)}catch(c){throw new ae(Qe,`Parser for "${r}" property failed${a===r?"":`. Source field: "${a}"`}`,c)}}return n}function Ze(e){let t=e;if(typeof t=="string")try{t=JSON.parse(t)}catch(n){throw new ae(Gt,{cause:n})}if(typeof t!="object"||!t||Array.isArray(t))throw new ae(zt);return t}function k(e,t){return n=>{const r=i=>{if(!(n&&i===void 0))try{return t(i)}catch(a){throw new ae(Qe,{message:`"${e}" transformer failed to parse the value`,cause:a})}};return Object.assign(r,{isValid(i){try{return r(i),!0}catch{return!1}}})}}function De(e,t){return k(t||"object",n=>{const r=Ze(n);return Yt(e,i=>r[i])})}function se(e){throw new ae(Ft,`Unexpected value received: ${JSON.stringify(e)}`)}const Yi=k("boolean",e=>{if(typeof e=="boolean")return e;const t=String(e);if(t==="1"||t==="true")return!0;if(t==="0"||t==="false")return!1;se(e)}),N=k("string",e=>{if(typeof e=="string"||typeof e=="number")return e.toString();se(e)}),Ie=k("number",e=>{if(typeof e=="number")return e;if(typeof e=="string"){const t=Number(e);if(!Number.isNaN(t))return t}se(e)}),Jt=k("date",e=>e instanceof Date?e:new Date(Ie()(e)*1e3));function Kt(e,t){return k(t||"searchParams",n=>{typeof n!="string"&&!(n instanceof URLSearchParams)&&se(n);const r=typeof n=="string"?new URLSearchParams(n):n;return Yt(e,i=>{const a=r.get(i);return a===null?void 0:a})})}function Xe(e){for(const t in e)e[t]=[Wt(t),e[t]];return e}const Ji=e=>{const t=Ie(),n=Ie(!0),r=N(),i=N(!0),a=Yi(!0),s=De(Xe({addedToAttachmentMenu:a,allowsWriteToPm:a,firstName:r,id:t,isBot:a,isPremium:a,languageCode:i,lastName:i,photoUrl:i,username:i}),"User")(!0);return Kt(Xe({authDate:Jt(),canSendAfter:n,chat:De(Xe({id:t,type:r,title:r,photoUrl:i,username:i}),"Chat")(!0),chatInstance:i,chatType:i,hash:r,queryId:i,receiver:s,startParam:i,user:s}),"initData")(e)};function ce(e){return/^#[\da-f]{6}$/i.test(e)}function Qt(e){return/^#[\da-f]{3}$/i.test(e)}function xe(e){const t=e.replace(/\s/g,"").toLowerCase();if(ce(t))return t;if(Qt(t)){let r="#";for(let i=0;i<3;i+=1)r+=t[1+i].repeat(2);return r}const n=t.match(/^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/)||t.match(/^rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),\d{1,3}\)$/);if(!n)throw new Error(`Value "${e}" does not satisfy any of known RGB formats.`);return n.slice(1).reduce((r,i)=>{const a=parseInt(i,10).toString(16);return r+(a.length===1?"0":"")+a},"#")}const Ki=k("rgb",e=>xe(N()(e))),Qi=k("themeParams",e=>{const t=Ki(!0);return Object.entries(Ze(e)).reduce((n,[r,i])=>(n[Fi(r)]=t(i),n),{})});function et(e){return JSON.stringify(Object.fromEntries(Object.entries(e).map(([t,n])=>[Wt(t),n])))}function Zi(e){const{initDataRaw:t,startParam:n,showSettings:r,botInline:i}=e,a=new URLSearchParams;return a.set("tgWebAppPlatform",e.platform),a.set("tgWebAppThemeParams",et(e.themeParams)),a.set("tgWebAppVersion",e.version),t&&a.set("tgWebAppData",t),n&&a.set("tgWebAppStartParam",n),typeof r=="boolean"&&a.set("tgWebAppShowSettings",r?"1":"0"),typeof i=="boolean"&&a.set("tgWebAppBotInline",i?"1":"0"),a.toString()}function Xi(e,t){return k("array",n=>{let r;if(Array.isArray(n))r=n;else if(typeof n=="string")try{const i=JSON.parse(n);Array.isArray(i)&&(r=i)}catch{}return r||se(n),r.map(e)})}function tt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function ke(...e){return e.map(t=>{if(typeof t=="string")return t;if(tt(t))return ke(Object.entries(t).map(n=>n[1]&&n[0]));if(Array.isArray(t))return ke(...t)}).filter(Boolean).join(" ")}function xi(...e){return e.reduce((t,n)=>(tt(n)&&Object.entries(n).forEach(([r,i])=>{const a=ke(t[r],i);a&&(t[r]=a)}),t),{})}let ue=class Gi extends Error{constructor(t,n,r){super(typeof n=="object"?n.message:n||t,{cause:typeof n=="object"?n.cause:r}),this.type=t,Object.setPrototypeOf(this,Gi.prototype)}};function Zt(e){return e.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}function ea(e){return e.replace(/_[a-z]/g,t=>t[1].toUpperCase())}const ta="ERR_INVALID_VALUE",na="ERR_UNEXPECTED_VALUE",oa="ERR_UNEXPECTED_TYPE",Xt="ERR_PARSE";function xt(e,t){const n={};for(const r in e){const i=e[r];if(!i)continue;let a,s;typeof i=="function"?(a=r,s=i):[a,s]=i;try{const c=s(t(a));c!==void 0&&(n[r]=c)}catch(c){throw new ue(Xt,`Parser for "${r}" property failed${a===r?"":`. Source field: "${a}"`}`,c)}}return n}function en(e){let t=e;if(typeof t=="string")try{t=JSON.parse(t)}catch(n){throw new ue(ta,{cause:n})}if(typeof t!="object"||!t||Array.isArray(t))throw new ue(na);return t}function P(e,t){return n=>{const r=i=>{if(!(n&&i===void 0))try{return t(i)}catch(a){throw new ue(Xt,{message:`"${e}" transformer failed to parse the value`,cause:a})}};return Object.assign(r,{isValid(i){try{return r(i),!0}catch{return!1}}})}}function O(e,t){return P(t||"object",n=>{const r=en(n);return xt(e,i=>r[i])})}function le(e){throw new ue(oa,`Unexpected value received: ${JSON.stringify(e)}`)}const Ne=P("boolean",e=>{if(typeof e=="boolean")return e;const t=String(e);if(t==="1"||t==="true")return!0;if(t==="0"||t==="false")return!1;le(e)}),$=P("string",e=>{if(typeof e=="string"||typeof e=="number")return e.toString();le(e)}),fe=P("number",e=>{if(typeof e=="number")return e;if(typeof e=="string"){const t=Number(e);if(!Number.isNaN(t))return t}le(e)}),ra=P("date",e=>e instanceof Date?e:new Date(fe()(e)*1e3));function tn(e,t){return P(t||"searchParams",n=>{typeof n!="string"&&!(n instanceof URLSearchParams)&&le(n);const r=typeof n=="string"?new URLSearchParams(n):n;return xt(e,i=>{const a=r.get(i);return a===null?void 0:a})})}function nt(e){for(const t in e)e[t]=[Zt(t),e[t]];return e}const ia=e=>{const t=fe(),n=fe(!0),r=$(),i=$(!0),a=Ne(!0),s=O(nt({addedToAttachmentMenu:a,allowsWriteToPm:a,firstName:r,id:t,isBot:a,isPremium:a,languageCode:i,lastName:i,photoUrl:i,username:i}),"User")(!0);return tn(nt({authDate:ra(),canSendAfter:n,chat:O(nt({id:t,type:r,title:r,photoUrl:i,username:i}),"Chat")(!0),chatInstance:i,chatType:i,hash:r,queryId:i,receiver:s,startParam:i,user:s}),"initData")(e)};function aa(e){return/^#[\da-f]{6}$/i.test(e)}function sa(e){return/^#[\da-f]{3}$/i.test(e)}function ca(e){const t=e.replace(/\s/g,"").toLowerCase();if(aa(t))return t;if(sa(t)){let r="#";for(let i=0;i<3;i+=1)r+=t[1+i].repeat(2);return r}const n=t.match(/^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/)||t.match(/^rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),\d{1,3}\)$/);if(!n)throw new Error(`Value "${e}" does not satisfy any of known RGB formats.`);return n.slice(1).reduce((r,i)=>{const a=parseInt(i,10).toString(16);return r+(a.length===1?"0":"")+a},"#")}const ua=P("rgb",e=>ca($()(e))),la=P("themeParams",e=>{const t=ua(!0);return Object.entries(en(e)).reduce((n,[r,i])=>(n[ea(r)]=t(i),n),{})});function nn(e){return JSON.stringify(Object.fromEntries(Object.entries(e).map(([t,n])=>[Zt(t),n])))}const fa=e=>{const t=$(),n=$(!0),r=Ne(!0);return tn({botInline:["tgWebAppBotInline",r],initData:["tgWebAppData",ia(!0)],initDataRaw:["tgWebAppData",n],platform:["tgWebAppPlatform",t],showSettings:["tgWebAppShowSettings",r],startParam:["tgWebAppStartParam",n],themeParams:["tgWebAppThemeParams",la()],version:["tgWebAppVersion",t]},"launchParams")(e)};function _a(e){const{initDataRaw:t,startParam:n,showSettings:r,botInline:i}=e,a=new URLSearchParams;return a.set("tgWebAppPlatform",e.platform),a.set("tgWebAppThemeParams",nn(e.themeParams)),a.set("tgWebAppVersion",e.version),t&&a.set("tgWebAppData",t),n&&a.set("tgWebAppStartParam",n),typeof r=="boolean"&&a.set("tgWebAppShowSettings",r?"1":"0"),typeof i=="boolean"&&a.set("tgWebAppBotInline",i?"1":"0"),a.toString()}const on=O({eventType:$(),eventData:e=>e},"miniAppsMessage"),rn=P("fn",e=>{if(typeof e=="function")return e;le(e)});function da(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const ba=O({TelegramWebviewProxy:O({postEvent:rn()})()});function an(e){return ba().isValid(e)}function sn(){try{return window.self!==window.top}catch{return!0}}var ha=Object.defineProperty,pa=(e,t,n)=>t in e?ha(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,cn=(e,t,n)=>pa(e,typeof t!="symbol"?t+"":t,n);let f=class zi extends Error{constructor(t,n,r){super(typeof n=="object"?n.message:n||t,{cause:typeof n=="object"?n.cause:r}),this.type=t,Object.setPrototypeOf(this,zi.prototype)}};function Ve(e,t,n){return e.addEventListener(t,n),()=>e.removeEventListener(t,n)}function X(...e){const t=e.flat(1);return[t.push.bind(t),()=>{t.forEach(n=>{n()})}]}function ma(e,t){return e instanceof f&&e.type===t}function ot(e){return t=>ma(t,e)}const rt="ERR_ABORTED",it="ERR_CANCELED",at="ERR_TIMED_OUT";function un(e){return new f(rt,{cause:e})}const ga=ot(at),wa=ot(rt),Ea=ot(it);function ln(e,t){return e.reject=t.reject,e}class h extends Promise{constructor(t,n){let r,i;typeof t=="function"?(r=t,i=n):i=t;let a,s;super((c,_)=>{i||(i={});const{abortSignal:l}=i;if(l&&l.aborted)return _(un(l.reason));const[b,C]=X(),T=ie=>(...Bs)=>(C(),ie(...Bs)),re=new AbortController,{signal:Z}=re;s=T(ie=>{re.abort(ie),_(ie)}),a=T(c),l&&b(Ve(l,"abort",()=>{s(un(l.reason))}));const{timeout:Ut}=i;if(Ut){const ie=setTimeout(()=>{s(new f(at,`Timeout reached: ${Ut}ms`))},Ut);b(()=>{clearTimeout(ie)})}r&&r(a,s,Z)}),cn(this,"reject"),this.reject=s}static withFn(t,n){return new h((r,i,a)=>{try{const s=t(a);return s instanceof Promise?s.then(r,i):r(s)}catch(s){i(s)}},n)}static resolve(t){return new h(n=>{n(t)})}static reject(t){return new h((n,r)=>{r(t)})}cancel(){this.reject(new f(it))}catch(t){return this.then(void 0,t)}finally(t){return ln(super.finally(t),this)}then(t,n){return ln(super.then(t,n),this)}}function fn(e,t){return e.resolve=t.resolve,e}class _e extends h{constructor(t,n){let r,i;typeof t=="function"?(r=t,i=n):i=t;let a;super((s,c,_)=>{a=s,r&&r(s,c,_)},i),cn(this,"resolve"),this.resolve=a}static withFn(t,n){return new _e((r,i,a)=>h.withFn(t,{abortSignal:a}).then(r,i),n)}static resolve(t){return new _e(n=>{n(t)})}static reject(t){return new _e((n,r)=>{r(t)})}catch(t){return this.then(void 0,t)}finally(t){return fn(super.finally(t),this)}then(t,n){return fn(super.then(t,n),this)}}function ya(e,t){return new h(n=>{setTimeout(n,e)},{abortSignal:t})}function _n(e){return`tapps/${e}`}function A(e,t){sessionStorage.setItem(_n(e),JSON.stringify(t))}function R(e){const t=sessionStorage.getItem(_n(e));try{return t?JSON.parse(t):void 0}catch{}}function st(e){return e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`)}function Sa(e,t){t||(t={});const{textColor:n,bgColor:r,shouldLog:i=!0}=t;function a(s,...c){if(!i||typeof i=="function"&&!i())return;const _="font-weight:bold;padding:0 5px;border-radius:5px";console[s](`%c${Intl.DateTimeFormat("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3,timeZone:"UTC"}).format(new Date)}%c / %c${e}`,`${_};background-color: lightblue;color:black`,"",`${_};${n?`color:${n};`:""}${r?`background-color:${r}`:""}`,...c)}return[function(...s){a("log",...s)},function(...s){a("error",...s)}]}function je(e,t){document.documentElement.style.setProperty(e,t)}function Le(e){document.documentElement.style.removeProperty(e)}function Ca(e,t){t()}function x(e,t){t||(t={});const n=t.equals||Object.is;let r=[],i=e;const a=l=>{if(!n(i,l)){const b=i;i=l,Ca(_,()=>{[...r].forEach(([C,T])=>{C(l,b),T&&c(C,!0)})})}};function s(l){const b=typeof l!="object"?{once:l}:l;return{once:b.once||!1,signal:b.signal||!1}}const c=(l,b)=>{const C=s(b),T=r.findIndex(([re,Z])=>re===l&&Z.once===C.once&&Z.signal===C.signal);T>=0&&r.splice(T,1)},_=Object.assign(function(){return va(_),i},{destroy(){r=[]},set:a,reset(){a(e)},sub(l,b){return r.push([l,s(b)]),()=>c(l,b)},unsub:c,unsubAll(){r=r.filter(l=>l[1].signal)}});return _}const ct=[];function va(e){ct.length&&ct[ct.length-1].add(e)}const dn=x(!1),[ut,Ta]=Sa("Bridge",{bgColor:"#9147ff",textColor:"white",shouldLog:dn}),$a={clipboard_text_received:O({req_id:$(),data:e=>e===null?e:$(!0)(e)},"clipboard_text_received"),custom_method_invoked:O({req_id:$(),result:e=>e,error:$(!0)},"custom_method_invoked"),popup_closed:P("popup_closed",e=>e?O({button_id:t=>t==null?void 0:$()(t)})()(e):{}),viewport_changed:O({height:fe(),width:e=>e==null?window.innerWidth:fe()(e),is_state_stable:Ne(),is_expanded:Ne()},"viewport_changed")};function Aa(e){const t=window,[,n]=X(Ve(t,"resize",()=>{e(["viewport_changed",{width:window.innerWidth,height:window.innerHeight,is_state_stable:!0,is_expanded:!0}])}),Ve(t,"message",r=>{if(r.source!==t.parent)return;let i;try{i=on()(r.data)}catch{return}const{eventType:a,eventData:s}=i,c=$a[a];try{const _=c?c()(s):s;ut("Event received:",_?{eventType:a,eventData:_}:{eventType:a}),e([a,_])}catch(_){Ta([`An error occurred processing the "${a}" event from the Telegram application.`,"Please, file an issue here:","https://github.com/Telegram-Mini-Apps/telegram-apps/issues/new/choose"].join(` | ||
`),i,_)}}));return n}const lt=x(),bn=x();function hn(){return bn()||bn.set(Aa(lt.set)),lt}const ft=x({});function pn(e){let t=ft()[e];return t||(t=x(void 0,{equals(){return!1}}),hn().sub(n=>{n&&n[0]===e&&t.set(n[1])}),ft.set({...ft(),[e]:t})),t}function y(e,t,n){return pn(e).sub(t,n)}const mn="ERR_METHOD_UNSUPPORTED",gn="ERR_RETRIEVE_LP_FAILED",wn="ERR_METHOD_PARAMETER_UNSUPPORTED",En="ERR_UNKNOWN_ENV",yn="ERR_INVOKE_CUSTOM_METHOD_RESPONSE",Sn=x("https://web.telegram.org");function He(e,t){ut("Posting event:",t?{eventType:e,eventData:t}:{eventType:e});const n=window;if(an(n)){n.TelegramWebviewProxy.postEvent(e,JSON.stringify(t));return}const r=JSON.stringify({eventType:e,eventData:t});if(sn())return n.parent.postMessage(r,Sn());const{external:i}=n;if(O({notify:rn()})().isValid(i)){i.notify(r);return}throw new f(En)}function qe(e,t,n){n||(n={});const{capture:r}=n,[i,a]=X();return new h(s=>{(Array.isArray(t)?t:[t]).forEach(c=>{i(y(c,_=>{(!r||(Array.isArray(t)?r({event:c,payload:_}):r(_)))&&s(_)}))}),(n.postEvent||He)(e,n.params)},n).finally(a)}function _t(e){return fa()(e)}function Cn(e){return _t(e.replace(/^[^?#]*[?#]/,"").replace(/[?#]/g,"&"))}function Ra(){return Cn(window.location.href)}function Pa(){const e=performance.getEntriesByType("navigation")[0];if(!e)throw new Error("Unable to get first navigation entry.");return Cn(e.name)}const Oa="launchParams";function Ba(){return _t(R(Oa)||"")}function vn(e){A("launchParams",_a(e))}function Tn(e){return e instanceof Error?e.message+(e.cause?` | ||
${Tn(e.cause)}`:""):JSON.stringify(e)}function G(){const e=[];for(const t of[Ra,Pa,Ba])try{const n=t();return vn(n),n}catch(n){e.push(n)}throw new f(gn,["Unable to retrieve launch parameters from any known source. Perhaps, you have opened your app outside Telegram?","📖 Refer to docs for more information:","https://docs.telegram-mini-apps.com/packages/telegram-apps-sdk/environment","Collected errors:",...e.map(t=>`— ${Tn(t)}`)].join(` | ||
`))}function Ma(e){if(e==="simple")try{return G(),!0}catch{return!1}return h.withFn(async()=>{if(an(window))return!0;try{return await qe("web_app_request_theme","theme_changed",{timeout:100}),!0}catch{return!1}},e)}function Ue(e,t){window.dispatchEvent(new MessageEvent("message",{data:JSON.stringify({eventType:e,eventData:t}),source:window.parent}))}function Da(e,t){if(typeof t=="string")try{const{eventType:n}=on()(t);n==="web_app_request_theme"&&Ue("theme_changed",{theme_params:JSON.parse(nn(e))}),n==="web_app_request_viewport"&&Ue("viewport_changed",{width:window.innerWidth,height:window.innerHeight,is_state_stable:!0,is_expanded:!0})}catch{}}function Ia(e){var t;const n=typeof e=="string"?_t(e):e;vn(n);const r=(t=window.TelegramWebviewProxy)==null?void 0:t.postEvent;window.TelegramWebviewProxy={postEvent(i,a){Da(n.themeParams,JSON.stringify({eventType:i,eventData:a})),r==null||r(i,a)}},ut("Environment was mocked by the mockTelegramEnv function")}function $n(){[["TelegramGameProxy_receiveEvent"],["TelegramGameProxy","receiveEvent"],["Telegram","WebView","receiveEvent"]].forEach(e=>{let t=window;e.forEach((n,r,i)=>{if(r===i.length-1){t[n]=Ue;return}n in t||(t[n]={}),t=t[n]})})}function An(){["TelegramGameProxy_receiveEvent","TelegramGameProxy","Telegram"].forEach(e=>{delete window[e]})}function L(e,t,n){pn(e).unsub(t,n)}function ka(e,t){return hn().sub(e,t)}function Na(e,t){lt.unsub(e,t)}function Rn(e){return({req_id:t})=>t===e}function Pn(e){return e.split(".").map(Number)}function On(e,t){const n=Pn(e),r=Pn(t),i=Math.max(n.length,r.length);for(let a=0;a<i;a+=1){const s=n[a]||0,c=r[a]||0;if(s!==c)return s>c?1:-1}return 0}function w(e,t){return On(e,t)<=0}function p(e,t,n){if(typeof n=="string"){if(e==="web_app_open_link"){if(t==="try_instant_view")return w("6.4",n);if(t==="try_browser")return w("7.6",n)}if(e==="web_app_set_header_color"&&t==="color")return w("6.9",n);if(e==="web_app_close"&&t==="return_back")return w("7.6",n);if(e==="web_app_setup_main_button"&&t==="has_shine_effect")return w("7.10",n)}switch(e){case"web_app_open_tg_link":case"web_app_open_invoice":case"web_app_setup_back_button":case"web_app_set_background_color":case"web_app_set_header_color":case"web_app_trigger_haptic_feedback":return w("6.1",t);case"web_app_open_popup":return w("6.2",t);case"web_app_close_scan_qr_popup":case"web_app_open_scan_qr_popup":case"web_app_read_text_from_clipboard":return w("6.4",t);case"web_app_switch_inline_query":return w("6.7",t);case"web_app_invoke_custom_method":case"web_app_request_write_access":case"web_app_request_phone":return w("6.9",t);case"web_app_setup_settings_button":return w("6.10",t);case"web_app_biometry_get_info":case"web_app_biometry_open_settings":case"web_app_biometry_request_access":case"web_app_biometry_request_auth":case"web_app_biometry_update_token":return w("7.2",t);case"web_app_setup_swipe_behavior":return w("7.7",t);case"web_app_setup_secondary_button":case"web_app_set_bottom_bar_color":return w("7.10",t);default:return["iframe_ready","iframe_will_reload","web_app_close","web_app_data_send","web_app_expand","web_app_open_link","web_app_ready","web_app_request_theme","web_app_request_viewport","web_app_setup_main_button","web_app_setup_closing_behavior"].includes(e)}}function Bn(e,t){t||(t="strict");const n=typeof t=="function"?t:r=>{const{method:i,version:a}=r;let s,c;if("param"in r?(s=`Parameter "${r.param}" of "${i}" method is unsupported in Mini Apps version ${a}`,c=wn):(s=`Method "${i}" is unsupported in Mini Apps version ${a}`,c=mn),t==="strict")throw new f(c,s);return console.warn(s)};return(r,i)=>p(r,e)?da(i)&&r==="web_app_set_header_color"&&"color"in i&&!p(r,"color",e)?n({version:e,method:r,param:"color"}):He(r,i):n({version:e,method:r})}function Mn(e,t,n,r){return qe("web_app_invoke_custom_method","custom_method_invoked",{...r||{},params:{method:e,params:t,req_id:n},capture:Rn(n)}).then(({result:i,error:a})=>{if(a)throw new f(yn,a);return i})}function Va(){return performance.getEntriesByType("navigation")[0]}function B(){const e=Va();return!!e&&e.type==="reload"}function Dn(e,t){return e.startsWith(t)?e:`${t}${e}`}function ja(e){return new URL(typeof e=="string"?e:[e.pathname||"",Dn(e.search||"","?"),Dn(e.hash||"","#")].join(""),"http://a")}let ee;function La(e,t){ee&&ee.set(e,t)||t()}function Ha(e){if(ee)return e();ee=new Map;try{e()}finally{ee.forEach(t=>t()),ee=void 0}}function u(e,t){t||(t={});const n=t.equals||Object.is;let r=[],i=e;const a=l=>{if(!n(i,l)){const b=i;i=l,La(_,()=>{[...r].forEach(([C,T])=>{C(l,b),T&&c(C,!0)})})}};function s(l){const b=typeof l!="object"?{once:l}:l;return{once:b.once||!1,signal:b.signal||!1}}const c=(l,b)=>{const C=s(b),T=r.findIndex(([re,Z])=>re===l&&Z.once===C.once&&Z.signal===C.signal);T>=0&&r.splice(T,1)},_=Object.assign(function(){return qa(_),i},{destroy(){r=[]},set:a,reset(){a(e)},sub(l,b){return r.push([l,s(b)]),()=>c(l,b)},unsub:c,unsubAll(){r=r.filter(l=>l[1].signal)}});return _}const de=[];function qa(e){de.length&&de[de.length-1].add(e)}function E(e,t){let n=new Set;const r=u(a(),t);function i(){r.set(a())}function a(){n.forEach(_=>_.unsub(i,{signal:!0}));const s=new Set;let c;de.push(s);try{c=e()}finally{de.pop()}return s.forEach(_=>{_.sub(i,{signal:!0})}),n=s,c}return Object.assign(function(){return r()},{destroy:r.destroy,sub:r.sub,unsub:r.unsub,unsubAll:r.unsubAll})}const In=u((()=>{let e=0;return()=>(e+=1).toString()})()),dt=u(He),m=u("0.0");function Ua(e){e||(e={});const{postEvent:t}=e,n=e.version||G().version;m.set(n),dt.set(typeof t=="function"?t:Bn(n,t))}function kn(){return In()()}function be(e,t,n){return Mn(e,t,kn(),{...n||{},postEvent:d})}const M=(e,t,n)=>(n||(n={}),n.postEvent||(n.postEvent=d),qe(e,t,n)),d=(e,t)=>dt()(e,t),Nn="web_app_setup_back_button",Vn="back_button_pressed",jn="backButton";function Ln(){z.set(!1)}function Hn(){return p(Nn,m())}const z=u(!1),he=u(!1);function qn(){he()||(z.set(B()&&R(jn)||!1),z.sub(Un),he.set(!0))}function Un(e){d(Nn,{is_visible:e}),A(jn,e)}function Wn(e){return y(Vn,e)}function Gn(e){L(Vn,e)}function zn(){z.set(!0)}function Fn(){z.unsub(Un),he.set(!1)}const Wa=Object.freeze(Object.defineProperty({__proto__:null,hide:Ln,isMounted:he,isSupported:Hn,isVisible:z,mount:qn,offClick:Gn,onClick:Wn,show:zn,unmount:Fn},Symbol.toStringTag,{value:"Module"})),te="ERR_POPUP_INVALID_PARAMS",bt="ERR_INVALID_HOSTNAME",Yn="ERR_INVALID_SLUG",Jn="ERR_DATA_INVALID_SIZE",Kn="ERR_ACCESS_DENIED",v="ERR_ALREADY_CALLED",ht="ERR_NOT_AVAILABLE";function Qn(e,t,{isMounting:n,isMounted:r,mountError:i}){return function(s){if(r())return h.resolve();if(n())throw new f(v);return n.set(!0),h.withFn(c=>e({abortSignal:c}),s).then(c=>[!0,c],c=>[!1,c]).then(c=>{Ha(()=>{if(n.set(!1),r.set(!0),c[0])t(c[1]);else{const _=c[1];throw i.set(_),_}})})}}const V=u(),pe=u(!1),me=u(!1),pt=u(!1),mt=u(!1),gt=u(void 0);function D(e,t,n){return Object.assign(e,{isSupported(){return p(t,m())&&(!n||n())}})}function wt(e){return e.available?{available:!0,tokenSaved:e.token_saved,deviceId:e.device_id,accessRequested:e.access_requested,type:e.type,accessGranted:e.access_granted}:{available:!1}}const Zn="web_app_biometry_get_info",Xn=D(e=>M(Zn,"biometry_info_received",e).then(wt),Zn),Ga=Object.freeze(Object.defineProperty({__proto__:null,request:Xn},Symbol.toStringTag,{value:"Module"})),xn="web_app_biometry_request_auth",za="web_app_biometry_request_access",Fa="web_app_biometry_open_settings",Ya="web_app_biometry_update_token",Et="biometry_info_received",eo="biometry";function to(e){if(pe())return h.reject(new f(v));const t=V();return!t||!t.available?h.reject(new f(ht)):(pe.set(!0),e||(e={}),M(xn,"biometry_auth_requested",{...e,params:{reason:(e.reason||"").trim()}}).then(n=>{const{token:r}=n;return typeof r=="string"&&V.set({...t,token:r}),n}).finally(()=>{pe.set(!1)}))}function yt(){return p(xn,m())}function no(){d(Fa)}function oo(e){return me()?h.reject(new f(v)):(me.set(!0),e||(e={}),M(za,Et,{...e,params:{reason:e.reason||""}}).then(wt).then(t=>{if(!t.available)throw new f(ht);return V.set(t),t.accessGranted}).finally(()=>{me.set(!1)}))}const ro=Qn(e=>{if(!yt())return{available:!1};const t=B()&&R(eo);return t||Xn(e)},e=>{y(Et,io),V.sub(ao),V.set(e)},{isMounted:pt,mountError:gt,isMounting:mt}),io=e=>{V.set(wt(e))};function ao(e){e&&A(eo,e)}function so(){L(Et,io),V.unsub(ao)}function co(e){return e||(e={}),M(Ya,"biometry_token_updated",{...e,params:{token:e.token||"",reason:e.reason}}).then(t=>t.status)}const Ja=Object.freeze(Object.defineProperty({__proto__:null,authenticate:to,isAuthenticating:pe,isMounted:pt,isMounting:mt,isRequestingAccess:me,isSupported:yt,mount:ro,mountError:gt,openSettings:no,requestAccess:oo,state:V,unmount:so,updateToken:co},Symbol.toStringTag,{value:"Module"})),uo="closingConfirmation";function lo(){F.set(!1)}const ge=u(!1),F=u(!1);function fo(){F.set(!0)}function _o(){ge()||(F.set(B()&&R(uo)||!1),F.sub(bo),ge.set(!0))}function bo(e){d("web_app_setup_closing_behavior",{need_confirmation:e}),A(uo,e)}function ho(){F.unsub(bo),ge.set(!1)}const Ka=Object.freeze(Object.defineProperty({__proto__:null,disableConfirmation:lo,enableConfirmation:fo,isConfirmationEnabled:F,isMounted:ge,mount:_o,unmount:ho},Symbol.toStringTag,{value:"Module"})),Qa="web_app_invoke_custom_method";function po(e,t){const n=Array.isArray(e)?e:[e];return n.length?be("deleteStorageValues",{keys:n},t).then():h.resolve()}function mo(e,t){const n=Array.isArray(e)?e:[e];return n.length?be("getStorageValues",{keys:n},t).then(r=>{const i=De(Object.fromEntries(n.map(a=>[a,N()])))()(r);return Array.isArray(e)?i:i[e]}):h.resolve(typeof e=="string"?"":{})}function go(e){return be("getStorageKeys",{},e).then(Xi(N())())}function wo(){return p(Qa,m())}function Eo(e,t,n){return be("saveStorageValue",{key:e,value:t},n).then()}const Za=Object.freeze(Object.defineProperty({__proto__:null,deleteItem:po,getItem:mo,getKeys:go,isSupported:wo,setItem:Eo},Symbol.toStringTag,{value:"Module"})),We="web_app_trigger_haptic_feedback";function yo(e){d(We,{type:"impact",impact_style:e})}function So(){return p(We,m())}function Co(e){d(We,{type:"notification",notification_type:e})}function vo(){d(We,{type:"selection_change"})}const Xa=Object.freeze(Object.defineProperty({__proto__:null,impactOccurred:yo,isSupported:So,notificationOccurred:Co,selectionChanged:vo},Symbol.toStringTag,{value:"Module"})),Ge=u(void 0);function I(e){return E(()=>{const t=Ge();return t?t[e]:void 0})}const St=I("authDate"),Ct=I("canSendAfter"),To=E(()=>{const e=St(),t=Ct();return t&&e?new Date(e.getTime()+t*1e3):void 0}),$o=I("chat"),Ao=I("chatType"),Ro=I("chatInstance"),Po=I("hash"),Oo=I("queryId"),vt=u(),Bo=I("receiver"),Mo=I("startParam"),Do=I("user");function Io(){const e=G();Ge.set(e.initData),vt.set(e.initDataRaw)}const xa=Object.freeze(Object.defineProperty({__proto__:null,authDate:St,canSendAfter:Ct,canSendAfterDate:To,chat:$o,chatInstance:Ro,chatType:Ao,hash:Po,queryId:Oo,raw:vt,receiver:Bo,restore:Io,startParam:Mo,state:Ge,user:Do},Symbol.toStringTag,{value:"Module"}));function es(e){return Ji()(e)}const ts=Object.freeze(Object.defineProperty({__proto__:null,parse:es},Symbol.toStringTag,{value:"Module"})),ko="web_app_open_invoice",we=u(!1);function No(){return p(ko,m())}async function Vo(e,t,n){if(we())throw new f(v);let r;if(t==="url"){const{hostname:i,pathname:a}=new URL(e,window.location.href);if(i!=="t.me")throw new f(bt);const s=a.match(/^\/(\$|invoice\/)([A-Za-z0-9\-_=]+)$/);if(!s)throw new f(Yn);[,,r]=s}else r=e,n=t;return we.set(!0),M(ko,"invoice_closed",{...n,params:{slug:r},capture:i=>r===i.slug}).then(i=>i.status).finally(()=>{we.set(!1)})}const ns=Object.freeze(Object.defineProperty({__proto__:null,isOpened:we,isSupported:No,open:Vo},Symbol.toStringTag,{value:"Module"}));function Tt(e){const t=xe(e);return Math.sqrt([.299,.587,.114].reduce((n,r,i)=>{const a=parseInt(t.slice(1+i*2,1+(i+1)*2),16);return n+a*a*r},0))<120}const Ee=u(!1),ye=u(!1),j=u({});function g(e){return E(()=>j()[e])}const jo=g("accentTextColor"),ze=g("bgColor"),Fe=g("buttonColor"),$t=g("buttonTextColor"),At=g("bottomBarBgColor"),Lo=g("destructiveTextColor"),Rt=g("headerBgColor"),Ho=g("hintColor"),qo=E(()=>{const{bgColor:e}=j();return!e||Tt(e)}),Uo=g("linkColor"),Se=g("secondaryBgColor"),Wo=g("sectionBgColor"),Go=g("sectionHeaderTextColor"),zo=g("sectionSeparatorColor"),Fo=g("subtitleTextColor"),Yo=g("textColor");function Y(e){return E(()=>Ce()[e])}const ne=u({hasShineEffect:!1,isEnabled:!0,isLoaderVisible:!1,isVisible:!1,text:"Continue"}),Ce=E(()=>{const e=ne();return{...e,backgroundColor:e.backgroundColor||Fe()||"#2481cc",textColor:e.textColor||$t()||"#ffffff"}}),ve=u(!1),Jo=Y("backgroundColor"),Ko=Y("hasShineEffect"),Qo=Y("isEnabled"),Zo=Y("isLoaderVisible"),Xo=Y("isVisible"),xo=Y("text"),er=Y("textColor"),os="web_app_setup_main_button",tr="main_button_pressed",nr="mainButton";function or(){if(!ve()){const e=B()&&R(nr);e&&ne.set(e),ne.sub(ar),Ce.sub(sr),ve.set(!0)}}function rr(e){return y(tr,e)}function ir(e){L(tr,e)}function ar(e){A(nr,e)}function sr(e){e.text&&d(os,{color:e.backgroundColor,has_shine_effect:e.hasShineEffect,is_active:e.isEnabled,is_progress_visible:e.isLoaderVisible,is_visible:e.isVisible,text:e.text,text_color:e.textColor})}function cr(e){ne.set({...ne(),...Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))})}function ur(){ne.unsub(ar),Ce.unsub(sr),ve.set(!1)}const rs=Object.freeze(Object.defineProperty({__proto__:null,backgroundColor:Jo,hasShineEffect:Ko,isEnabled:Qo,isLoaderVisible:Zo,isMounted:ve,isVisible:Xo,mount:or,offClick:ir,onClick:rr,setParams:cr,state:Ce,text:xo,textColor:er,unmount:ur},Symbol.toStringTag,{value:"Module"}));function is(e,t){return Object.assign(e,{supports(n){const r=t[n];return p(r[0],r[1],m())}})}function lr(e){return Qi()(e)}const as=Object.freeze(Object.defineProperty({__proto__:null,parse:lr,serialize:et},Symbol.toStringTag,{value:"Module"})),fr="themeParams",_r="theme_changed";function dr(e){if(ye())throw new f(v);e||(e=r=>`--tg-theme-${st(r)}`);function t(r){Object.entries(j()).forEach(([i,a])=>{a&&r(i,a)})}function n(){t((r,i)=>{je(e(r),i)})}return n(),j.sub(n),ye.set(!0),()=>{t(Le),j.unsub(n),ye.set(!1)}}function Pt(){Ee()||(y(_r,br),j.set(B()&&R(fr)||G().themeParams),Ee.set(!0))}const br=e=>{const t=lr(e.theme_params);j.set(t),A(fr,t)};function hr(){L(_r,br),Ee.set(!1)}const ss=Object.freeze(Object.defineProperty({__proto__:null,accentTextColor:jo,backgroundColor:ze,bindCssVars:dr,bottomBarBgColor:At,buttonColor:Fe,buttonTextColor:$t,destructiveTextColor:Lo,headerBackgroundColor:Rt,hintColor:Ho,isCssVarsBound:ye,isDark:qo,isMounted:Ee,linkColor:Uo,mount:Pt,secondaryBackgroundColor:Se,sectionBackgroundColor:Wo,sectionHeaderTextColor:Go,sectionSeparatorColor:zo,state:j,subtitleTextColor:Fo,textColor:Yo,unmount:hr},Symbol.toStringTag,{value:"Module"}));function pr(e){return E(()=>{const t=e();return ce(t)?t:t==="bg_color"?ze():Se()})}const H=u("bg_color"),Ot=pr(H),q=u("bottom_bar_bg_color"),Ye=E(()=>{const e=q();return ce(e)?e:e==="bottom_bar_bg_color"?At()||Se():e==="secondary_bg_color"?Se():ze()}),U=u("bg_color"),Bt=pr(U),Te=u(!1),$e=u(!1),mr=E(()=>{const e=Ot();return e?Tt(e):!1}),Mt=E(()=>({backgroundColor:H(),bottomBarColor:q(),headerColor:U()})),gr="web_app_set_background_color",wr="web_app_set_bottom_bar_color",Dt="web_app_set_header_color",Er="miniApp";function yr(e){if($e())throw new f(v);const[t,n]=X();function r(i,a){function s(){je(i,a()||null)}s(),t(a.sub(s),Le.bind(null,i))}return e||(e=i=>`--tg-${st(i)}`),r(e("bgColor"),Ot),r(e("bottomBarColor"),Ye),r(e("headerColor"),Bt),t(()=>{$e.set(!1)}),$e.set(!0),n}function Sr(e){d("web_app_close",{return_back:e})}function Cr(){if(!Te()){const e=B()&&R(Er);Pt(),H.set(e?e.backgroundColor:"bg_color"),H.sub(vr),q.set(e?e.bottomBarColor:"bottom_bar_bg_color"),q.sub(Tr),U.set(e?e.headerColor:Rt()||"bg_color"),U.sub($r),Te.set(!0)}}function vr(e){It(),d(gr,{color:e})}function Tr(e){It(),d(wr,{color:e})}function $r(e){It(),d(Dt,ce(e)?{color:e}:{color_key:e})}function Ar(){d("web_app_ready")}function It(){A(Er,Mt())}const Rr=D(e=>{H.set(e)},gr),Pr=D(e=>{q.set(e)},wr),Or=is(D(e=>{U.set(e)},Dt),{color:[Dt,"color"]});function Br(){H.unsub(vr),q.unsub(Tr),U.unsub($r),Te.set(!1)}const cs=Object.freeze(Object.defineProperty({__proto__:null,backgroundColor:H,backgroundColorRGB:Ot,bindCssVars:yr,bottomBarColor:q,bottomBarColorRGB:Ye,close:Sr,headerColor:U,headerColorRGB:Bt,isCssVarsBound:$e,isDark:mr,isMounted:Te,mount:Cr,ready:Ar,setBackgroundColor:Rr,setBottomBarColor:Pr,setHeaderColor:Or,state:Mt,unmount:Br},Symbol.toStringTag,{value:"Module"})),Ae=u(!1);function us(e){const t=e.message.trim(),n=(e.title||"").trim(),r=e.buttons||[];if(n.length>64)throw new f(te,`Invalid title: ${n}`);if(!t||t.length>256)throw new f(te,`Invalid message: ${t}`);if(r.length>3)throw new f(te,`Invalid buttons count: ${r.length}`);return{title:n,message:t,buttons:r.length?r.map((i,a)=>{const s=i.id||"";if(s.length>64)throw new f(te,`Button with index ${a} has invalid id: ${s}`);if(!i.type||i.type==="default"||i.type==="destructive"){const c=i.text.trim();if(!c||c.length>64)throw new f(te,`Button with index ${a} has invalid text: ${c}`);return{type:i.type,text:c,id:s}}return{type:i.type,id:s}}):[{type:"close",id:""}]}}const Mr="web_app_open_popup";function Dr(){return p(Mr,m())}async function Ir(e){if(Ae())throw new f(v);Ae.set(!0);try{const{button_id:t=null}=await M(Mr,"popup_closed",{...e,params:us(e)});return t}finally{Ae.set(!1)}}const ls=Object.freeze(Object.defineProperty({__proto__:null,isOpened:Ae,isSupported:Dr,open:Ir},Symbol.toStringTag,{value:"Module"})),fs=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),_s="web_app_close_scan_qr_popup",kr="web_app_open_scan_qr_popup",ds="scan_qr_popup_closed",bs="qr_text_received";function Je(){J.set(!1),d(_s)}const J=u(!1);function Nr(){return p(kr,m())}function Vr(e){return h.withFn(t=>{if(J())throw new f(v);J.set(!0),e||(e={});const{onCaptured:n,text:r,capture:i}=e,[,a]=X(J.sub(()=>{s.resolve()}),y(ds,()=>{J.set(!1)}),y(bs,c=>{n?n(c.data):i&&i(c.data)&&(s.resolve(c.data),Je())})),s=new _e({abortSignal:t}).catch(Je).finally(a);return(e.postEvent||d)(kr,{text:r}),s},e)}const hs=Object.freeze(Object.defineProperty({__proto__:null,close:Je,isOpened:J,isSupported:Nr,open:Vr},Symbol.toStringTag,{value:"Module"}));function W(e){return E(()=>Re()[e])}const oe=u({hasShineEffect:!1,isEnabled:!0,isLoaderVisible:!1,isVisible:!1,position:"left",text:"Cancel"}),Re=E(()=>{const e=oe();return{...e,backgroundColor:e.backgroundColor||Ye()||"#000000",textColor:e.textColor||Fe()||"#2481cc"}}),Pe=u(!1),jr=W("backgroundColor"),Lr=W("hasShineEffect"),Hr=W("isEnabled"),qr=W("isLoaderVisible"),Ur=W("isVisible"),Wr=W("position"),Gr=W("text"),zr=W("textColor"),Fr="web_app_setup_secondary_button",Yr="secondary_button_pressed",Jr="secondaryButton";function Kr(){return p(Fr,m())}function Qr(){if(!Pe()){const e=B()&&R(Jr);e&&oe.set(e),oe.sub(xr),Re.sub(ei),Pe.set(!0)}}function Zr(e){return y(Yr,e)}function Xr(e){L(Yr,e)}function xr(e){A(Jr,e)}function ei(e){e.text&&d(Fr,{color:e.backgroundColor,has_shine_effect:e.hasShineEffect,is_active:e.isEnabled,is_progress_visible:e.isLoaderVisible,is_visible:e.isVisible,position:e.position,text:e.text,text_color:e.textColor})}function ti(e){oe.set({...oe(),...Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))})}function ni(){oe.unsub(xr),Re.unsub(ei),Pe.set(!1)}const ps=Object.freeze(Object.defineProperty({__proto__:null,backgroundColor:jr,hasShineEffect:Lr,isEnabled:Hr,isLoaderVisible:qr,isMounted:Pe,isSupported:Kr,isVisible:Ur,mount:Qr,offClick:Xr,onClick:Zr,position:Wr,setParams:ti,state:Re,text:Gr,textColor:zr,unmount:ni},Symbol.toStringTag,{value:"Module"})),oi="web_app_setup_settings_button",ri="settings_button_pressed",ii="settingsButton";function ai(){K.set(!1)}const K=u(!1),Oe=u(!1);function si(){return p(oi,m())}function ci(){Oe()||(K.set(B()&&R(ii)||!1),K.sub(ui),Oe.set(!0))}function ui(e){d(oi,{is_visible:e}),A(ii,e)}function li(e){return y(ri,e)}function fi(e){L(ri,e)}function _i(){K.set(!0)}function di(){K.unsub(ui),Oe.set(!1)}const ms=Object.freeze(Object.defineProperty({__proto__:null,hide:ai,isMounted:Oe,isSupported:si,isVisible:K,mount:ci,offClick:fi,onClick:li,show:_i,unmount:di},Symbol.toStringTag,{value:"Module"})),bi="web_app_setup_swipe_behavior",hi="swipeBehavior";function pi(){Q.set(!1)}function mi(){Q.set(!0)}const Be=u(!1),Q=u(!1);function gi(){return p(bi,m())}function wi(){Be()||(Q.set(B()&&R(hi)||!1),Q.sub(Ei),Be.set(!0))}function Ei(e){d(bi,{allow_vertical_swipe:e}),A(hi,e)}function yi(){Q.unsub(Ei),Be.set(!1)}const gs=Object.freeze(Object.defineProperty({__proto__:null,disableVertical:pi,enableVertical:mi,isMounted:Be,isSupported:gi,isVerticalEnabled:Q,mount:wi,unmount:yi},Symbol.toStringTag,{value:"Module"})),S=u({height:0,width:0,isExpanded:!1,stableHeight:0}),kt=u(!1),Me=u(!1),Nt=u(!1),Vt=u(void 0);function Ke(e){return E(()=>S()[e])}const Si=Ke("height"),Ci=Ke("isExpanded"),vi=E(()=>{const e=S();return e.height===e.stableHeight}),Ti=Ke("stableHeight"),$i=Ke("width");function Ai(e){return M("web_app_request_viewport","viewport_changed",e).then(t=>({height:t.height,width:t.width,isExpanded:t.is_expanded,isStable:t.is_state_stable}))}const ws=Object.freeze(Object.defineProperty({__proto__:null,request:Ai},Symbol.toStringTag,{value:"Module"}));function Ri(e){if(Me())throw new f(v);e||(e=r=>`--tg-viewport-${st(r)}`);const t=["height","width","stableHeight"];function n(){t.forEach(r=>{je(e(r),`${S()[r]}px`)})}return n(),S.sub(n),Me.set(!0),()=>{t.forEach(Le),S.unsub(n),Me.set(!1)}}function Pi(){d("web_app_expand")}function Oi(e){return{isExpanded:e.isExpanded,height:jt(e.height),width:jt(e.width),stableHeight:jt(e.stableHeight)}}const Bi=Qn(e=>{const t=B()&&R("viewport");if(t)return t;if(["macos","tdesktop","unigram","webk","weba","web"].includes(G().platform)){const n=window;return{isExpanded:!0,height:n.innerHeight,width:n.innerWidth,stableHeight:n.innerHeight}}return e.timeout||(e.timeout=1e3),Ai(e).then(n=>({height:n.height,isExpanded:n.isExpanded,stableHeight:n.isStable?n.height:S().stableHeight,width:n.width}))},e=>{y("viewport_changed",Mi),S.sub(Di),S.set(Oi(e))},{isMounted:kt,isMounting:Nt,mountError:Vt}),Mi=e=>{S.set(Oi({height:e.height,width:e.width,isExpanded:e.is_expanded,stableHeight:e.is_state_stable?e.height:S().stableHeight}))};function Di(e){A("viewport",e)}function jt(e){return Math.max(e,0)}function Ii(){L("viewport_changed",Mi),S.unsub(Di)}const Es=Object.freeze(Object.defineProperty({__proto__:null,bindCssVars:Ri,expand:Pi,height:Si,isCssVarsBound:Me,isExpanded:Ci,isMounted:kt,isMounting:Nt,isStable:vi,mount:Bi,mountError:Vt,stableHeight:Ti,state:S,unmount:Ii,width:$i},Symbol.toStringTag,{value:"Module"})),ki="web_app_open_tg_link";function ys(e,t){t||(t={}),d("web_app_open_link",{url:ja(e).toString(),try_browser:t.tryBrowser,try_instant_view:t.tryInstantView})}function Ni(e){const{hostname:t,pathname:n,search:r}=new URL(e,"https://t.me");if(t!=="t.me")throw new f(bt);if(!p(ki,m())){window.location.href=e;return}d(ki,{path_full:n+r})}function Ss(e,t){Ni("https://t.me/share/url?"+new URLSearchParams({url:e,text:t||""}).toString().replace(/\+/g,"%20"))}const Lt="web_app_request_phone",Vi="web_app_request_write_access";let Ht,qt;function ji(e){return e||(e={}),be("getRequestedContact",{},{...e,timeout:e.timeout||5e3}).then(Kt({contact:De({userId:["user_id",Ie()],phoneNumber:["phone_number",N()],firstName:["first_name",N()],lastName:["last_name",N(!0)]})(),authDate:["auth_date",Jt()],hash:N()})())}const Cs=D(e=>new h(async(t,n,r)=>{const i={postEvent:(e||{}).postEvent,abortSignal:r};try{return t(await ji(i))}catch{}if(await Li(i)!=="sent")throw new f(Kn);let s=50;for(;!r.aborted;){try{return t(await ji(i))}catch{}await ya(s),s+=50}},e),Lt),Li=D(e=>{if(Ht)throw new f(v);return Ht=!0,M(Lt,"phone_requested",e).then(t=>t.status).finally(()=>{Ht=void 0})},Lt),vs=D(e=>{if(qt)throw new f(v);return qt=!0,M(Vi,"write_access_requested",e).then(t=>t.status).finally(()=>{qt=void 0})},Vi),Hi="web_app_read_text_from_clipboard",qi="web_app_switch_inline_query",Ui="web_app_share_to_story",Ts=D(e=>{const t=kn();return M(Hi,"clipboard_text_received",{...e,params:{req_id:t},capture:Rn(t)}).then(({data:n=null})=>n)},Hi);function $s(e){const{size:t}=new Blob([e]);if(!t||t>4096)throw new f(Jn);d("web_app_data_send",{data:e})}const As=D((e,t)=>{t||(t={}),(t.postEvent||d)(Ui,{text:t.text,media_url:e,widget_link:t.widgetLink})},Ui),Rs=D((e,t)=>{d(qi,{query:e,chat_types:t||[]})},qi,()=>!!G().botInline);function Ps(){return typeof window>"u"}function Os(e){Ua(e),$n();const[t,n]=X(y("reload_iframe",()=>{d("iframe_will_reload"),window.location.reload()}),An),{acceptCustomStyles:r=!0}=e||{};if(r){const i=document.createElement("style");i.id="telegram-custom-styles",document.head.appendChild(i),t(y("set_custom_style",a=>{i.innerHTML=a}),()=>{document.head.removeChild(i)})}return d("iframe_ready",{reload_supported:!0}),n}return o.$createRequestId=In,o.$debug=dn,o.$postEvent=dt,o.$targetOrigin=Sn,o.$version=m,o.Biometry=Ga,o.CancelablePromise=h,o.ERR_ABORTED=rt,o.ERR_ACCESS_DENIED=Kn,o.ERR_ALREADY_CALLED=v,o.ERR_CANCELED=it,o.ERR_CUSTOM_METHOD_ERR_RESPONSE=yn,o.ERR_DATA_INVALID_SIZE=Jn,o.ERR_INVALID_HOSTNAME=bt,o.ERR_INVALID_SLUG=Yn,o.ERR_INVALID_VALUE=Gt,o.ERR_METHOD_PARAMETER_UNSUPPORTED=wn,o.ERR_METHOD_UNSUPPORTED=mn,o.ERR_NOT_AVAILABLE=ht,o.ERR_PARSE=Qe,o.ERR_POPUP_INVALID_PARAMS=te,o.ERR_RETRIEVE_LP_FAILED=gn,o.ERR_TIMED_OUT=at,o.ERR_UNEXPECTED_TYPE=Ft,o.ERR_UNEXPECTED_VALUE=zt,o.ERR_UNKNOWN_ENV=En,o.InitData=ts,o.Popup=fs,o.ThemeParams=as,o.TypedError=f,o.Viewport=ws,o.addEventListener=Ve,o.authenticateBiometry=to,o.backButton=Wa,o.bindMiniAppCssVars=yr,o.bindThemeParamsCssVars=dr,o.bindViewportCssVars=Ri,o.biometry=Ja,o.biometryMountError=gt,o.biometryState=V,o.classNames=ke,o.closeMiniApp=Sr,o.closeQrScanner=Je,o.closingBehavior=Ka,o.cloudStorage=Za,o.compareVersions=On,o.createPostEvent=Bn,o.defineEventHandlers=$n,o.deleteCloudStorageItem=po,o.deleteCssVar=Le,o.disableClosingConfirmation=lo,o.disableVerticalSwipes=pi,o.emitMiniAppsEvent=Ue,o.enableClosingConfirmation=fo,o.enableVerticalSwipes=mi,o.expandViewport=Pi,o.getCloudStorageItem=mo,o.getCloudStorageKeys=go,o.hapticFeedback=Xa,o.hapticFeedbackImpactOccurred=yo,o.hapticFeedbackNotificationOccurred=Co,o.hapticFeedbackSelectionChanged=vo,o.hideBackButton=Ln,o.hideSettingsButton=ai,o.init=Os,o.initData=xa,o.initDataAuthDate=St,o.initDataCanSendAfter=Ct,o.initDataCanSendAfterDate=To,o.initDataChat=$o,o.initDataChatInstance=Ro,o.initDataChatType=Ao,o.initDataHash=Po,o.initDataQueryId=Oo,o.initDataRaw=vt,o.initDataReceiver=Bo,o.initDataStartParam=Mo,o.initDataState=Ge,o.initDataUser=Do,o.invoice=ns,o.invokeCustomMethod=Mn,o.isAbortError=wa,o.isAuthenticatingBiometry=pe,o.isBackButtonMounted=he,o.isBackButtonSupported=Hn,o.isBackButtonVisible=z,o.isBiometryMounted=pt,o.isBiometryMounting=mt,o.isBiometrySupported=yt,o.isCanceledError=Ea,o.isClosingBehaviorMounted=ge,o.isClosingConfirmationEnabled=F,o.isCloudStorageSupported=wo,o.isColorDark=Tt,o.isHapticFeedbackSupported=So,o.isIframe=sn,o.isInvoiceOpened=we,o.isInvoiceSupported=No,o.isMainButtonEnabled=Qo,o.isMainButtonLoaderVisible=Zo,o.isMainButtonMounted=ve,o.isMainButtonVisible=Xo,o.isMiniAppCssVarsBound=$e,o.isMiniAppDark=mr,o.isMiniAppMounted=Te,o.isPopupOpened=Ae,o.isPopupSupported=Dr,o.isQrScannerOpened=J,o.isQrScannerSupported=Nr,o.isRGB=ce,o.isRGBShort=Qt,o.isRecord=tt,o.isRequestingBiometryAccess=me,o.isSSR=Ps,o.isSecondaryButtonEnabled=Hr,o.isSecondaryButtonLoaderVisible=qr,o.isSecondaryButtonMounted=Pe,o.isSecondaryButtonSupported=Kr,o.isSecondaryButtonVisible=Ur,o.isSettingsButtonMounted=Oe,o.isSettingsButtonSupported=si,o.isSettingsButtonVisible=K,o.isSwipeBehaviorMounted=Be,o.isSwipeBehaviorSupported=gi,o.isTMA=Ma,o.isThemeParamsCssVarsBound=ye,o.isThemeParamsDark=qo,o.isThemeParamsMounted=Ee,o.isTimeoutError=ga,o.isVerticalSwipesEnabled=Q,o.isViewportCssVarsBound=Me,o.isViewportExpanded=Ci,o.isViewportMounted=kt,o.isViewportMounting=Nt,o.isViewportStable=vi,o.mainButton=rs,o.mainButtonBackgroundColor=Jo,o.mainButtonHasShineEffect=Ko,o.mainButtonState=Ce,o.mainButtonText=xo,o.mainButtonTextColor=er,o.mergeClassNames=xi,o.miniApp=cs,o.miniAppBackgroundColor=H,o.miniAppBottomBarColor=q,o.miniAppBottomBarColorRGB=Ye,o.miniAppHeaderColor=U,o.miniAppHeaderColorRGB=Bt,o.miniAppReady=Ar,o.miniAppState=Mt,o.mockTelegramEnv=Ia,o.mountBackButton=qn,o.mountBiometry=ro,o.mountClosingBehavior=_o,o.mountMainButton=or,o.mountMiniApp=Cr,o.mountSecondaryButton=Qr,o.mountSettingsButton=ci,o.mountSwipeBehavior=wi,o.mountThemeParams=Pt,o.mountViewport=Bi,o.off=L,o.offBackButtonClick=Gn,o.offMainButtonClick=ir,o.offSecondaryButtonClick=Xr,o.offSettingsButtonClick=fi,o.on=y,o.onBackButtonClick=Wn,o.onMainButtonClick=rr,o.onSecondaryButtonClick=Zr,o.onSettingsButtonClick=li,o.openBiometrySettings=no,o.openInvoice=Vo,o.openLink=ys,o.openPopup=Ir,o.openQrScanner=Vr,o.openTelegramLink=Ni,o.popup=ls,o.postEvent=He,o.qrScanner=hs,o.readTextFromClipboard=Ts,o.removeEventHandlers=An,o.request=qe,o.requestBiometryAccess=oo,o.requestContact=Cs,o.requestPhoneAccess=Li,o.requestWriteAccess=vs,o.restoreInitData=Io,o.retrieveLaunchParams=G,o.secondaryButton=ps,o.secondaryButtonBackgroundColor=jr,o.secondaryButtonHasShineEffect=Lr,o.secondaryButtonPosition=Wr,o.secondaryButtonState=Re,o.secondaryButtonText=Gr,o.secondaryButtonTextColor=zr,o.sendData=$s,o.serializeLaunchParams=Zi,o.serializeThemeParams=et,o.setCloudStorageItem=Eo,o.setCssVar=je,o.setMainButtonParams=cr,o.setMiniAppBackgroundColor=Rr,o.setMiniAppBottomBarColor=Pr,o.setMiniAppHeaderColor=Or,o.setSecondaryButtonParams=ti,o.settingsButton=ms,o.shareStory=As,o.shareURL=Ss,o.showBackButton=zn,o.showSettingsButton=_i,o.subscribe=ka,o.supports=p,o.swipeBehavior=gs,o.switchInlineQuery=Rs,o.themeParams=ss,o.themeParamsAccentTextColor=jo,o.themeParamsBackgroundColor=ze,o.themeParamsBottomBarBgColor=At,o.themeParamsButtonColor=Fe,o.themeParamsButtonTextColor=$t,o.themeParamsDestructiveTextColor=Lo,o.themeParamsHeaderBackgroundColor=Rt,o.themeParamsHintColor=Ho,o.themeParamsLinkColor=Uo,o.themeParamsSecondaryBackgroundColor=Se,o.themeParamsSectionBackgroundColor=Wo,o.themeParamsSectionHeaderTextColor=Go,o.themeParamsSectionSeparatorColor=zo,o.themeParamsState=j,o.themeParamsSubtitleTextColor=Fo,o.themeParamsTextColor=Yo,o.toRGB=xe,o.toRecord=Ze,o.unmountBackButton=Fn,o.unmountBiometry=so,o.unmountClosingBehavior=ho,o.unmountMainButton=ur,o.unmountMiniApp=Br,o.unmountSecondaryButton=ni,o.unmountSettingsButton=di,o.unmountSwipeBehavior=yi,o.unmountThemeParams=hr,o.unmountViewport=Ii,o.unsubscribe=Na,o.updateBiometryToken=co,o.viewport=Es,o.viewportHeight=Si,o.viewportMountError=Vt,o.viewportStableHeight=Ti,o.viewportState=S,o.viewportWidth=$i,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),o}({}); | ||
//# sourceMappingURL=index.iife.js.map |
{ | ||
"name": "@telegram-apps/sdk", | ||
"version": "2.1.0", | ||
"version": "2.3.0", | ||
"description": "TypeScript Source Development Kit for Telegram Mini Apps client application.", | ||
@@ -41,4 +41,4 @@ "author": "Vladislav Kibenko <wolfram.deus@gmail.com>", | ||
"@telegram-apps/transformers": "^1.0.1", | ||
"@telegram-apps/bridge": "^1.1.0", | ||
"@telegram-apps/navigation": "^1.0.1", | ||
"@telegram-apps/bridge": "^1.2.0", | ||
"@telegram-apps/navigation": "^1.0.2", | ||
"@telegram-apps/signals": "^1.0.0" | ||
@@ -45,0 +45,0 @@ }, |
@@ -88,39 +88,5 @@ export { classNames } from '@/classnames/classNames.js'; | ||
export * as mainButton from '@/scopes/components/main-button/instance.js'; | ||
export { | ||
backgroundColor as mainButtonBackgroundColor, | ||
hasShineEffect as mainButtonHasShineEffect, | ||
isMounted as isMainButtonMounted, | ||
isVisible as isMainButtonVisible, | ||
isEnabled as isMainButtonEnabled, | ||
isLoaderVisible as isMainButtonLoaderVisible, | ||
mount as mountMainButton, | ||
onClick as onMainButtonClick, | ||
offClick as offMainButtonClick, | ||
setParams as setMainButtonParams, | ||
state as mainButtonState, | ||
textColor as mainButtonTextColor, | ||
text as mainButtonText, | ||
unmount as unmountMainButton, | ||
} from '@/scopes/components/main-button/instance.js'; | ||
export * as MainButton from '@/scopes/components/main-button/static.js'; | ||
export * from '@/scopes/components/main-button/exports.js'; | ||
export * from '@/scopes/components/mini-app/exports.js'; | ||
export * as miniApp from '@/scopes/components/mini-app/instance.js'; | ||
export { | ||
backgroundColor as miniAppBackgroundColor, | ||
bindCssVars as bindMiniAppCssVars, | ||
close as closeMiniApp, | ||
headerColor as miniAppHeaderColor, | ||
isMounted as isMiniAppMounted, | ||
isCssVarsBound as isMiniAppCssVarsBound, | ||
isDark as isMiniAppDark, | ||
mount as mountMiniApp, | ||
ready as miniAppReady, | ||
state as miniAppState, | ||
setHeaderColor as setMiniAppHeaderColor, | ||
setBackgroundColor as setMiniAppBackgroundColor, | ||
unmount as unmountMiniApp, | ||
} from '@/scopes/components/mini-app/instance.js'; | ||
export * as MiniApp from '@/scopes/components/main-button/static.js'; | ||
export * as popup from '@/scopes/components/popup/instance.js'; | ||
@@ -142,2 +108,4 @@ export { | ||
export * from '@/scopes/components/secondary-button/exports.js'; | ||
export * as settingsButton from '@/scopes/components/settings-button/settings-button.js'; | ||
@@ -144,0 +112,0 @@ export { |
@@ -17,5 +17,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; | ||
isVisible, | ||
state, | ||
internalState, | ||
backgroundColor, | ||
hasShineEffect, | ||
state, | ||
} from './signals.js'; | ||
@@ -44,4 +45,12 @@ import { onClick, offClick, setParams, mount, unmount } from './methods.js'; | ||
themeParams.state, | ||
text, | ||
textColor, | ||
isMounted, | ||
isEnabled, | ||
isLoaderVisible, | ||
isVisible, | ||
internalState, | ||
backgroundColor, | ||
hasShineEffect, | ||
state, | ||
isMounted, | ||
].forEach(resetSignal); | ||
@@ -61,3 +70,3 @@ mockPostEvent(); | ||
beforeEach(() => { | ||
state.set({ | ||
internalState.set({ | ||
backgroundColor: '#123456', | ||
@@ -74,3 +83,3 @@ hasShineEffect: true, | ||
it(`should use "${name}" property from state`, () => { | ||
expect(signal()).toBe(state()[name]); | ||
expect(signal()).toBe(internalState()[name]); | ||
}); | ||
@@ -85,3 +94,3 @@ }); | ||
it('should save the state in storage key tapps/mainButton', () => { | ||
state.set({ | ||
internalState.set({ | ||
backgroundColor: '#123456', | ||
@@ -107,3 +116,3 @@ hasShineEffect: true, | ||
const spy = mockPostEvent(); | ||
state.set({ | ||
internalState.set({ | ||
backgroundColor: '#123456', | ||
@@ -241,3 +250,3 @@ hasShineEffect: false, | ||
it('should merge passed object with the state', () => { | ||
state.set({ | ||
internalState.set({ | ||
backgroundColor: '#123456', | ||
@@ -260,3 +269,3 @@ hasShineEffect: true, | ||
expect(state()).toStrictEqual({ | ||
expect(internalState()).toStrictEqual({ | ||
backgroundColor: '#111111', | ||
@@ -279,3 +288,3 @@ hasShineEffect: true, | ||
const storageSpy = mockSessionStorageSetItem(); | ||
state.set({ ...state(), text: 'Hello!' }); | ||
internalState.set({ ...internalState(), text: 'Hello!' }); | ||
expect(postEventSpy).toHaveBeenCalledTimes(1); | ||
@@ -288,3 +297,3 @@ expect(storageSpy).toHaveBeenCalledTimes(1); | ||
unmount(); | ||
state.set({ ...state() }); | ||
internalState.set({ ...internalState() }); | ||
@@ -291,0 +300,0 @@ expect(postEventSpy).toHaveBeenCalledTimes(0); |
@@ -11,9 +11,4 @@ import { | ||
import { postEvent } from '@/scopes/globals.js'; | ||
import { | ||
mount as tpMount, | ||
buttonColor as tpButtonColor, | ||
buttonTextColor as tpButtonTextColor, | ||
} from '@/scopes/components/theme-params/instance.js'; | ||
import { state, isMounted } from './signals.js'; | ||
import { internalState, isMounted, state } from './signals.js'; | ||
import type { State } from './types.js'; | ||
@@ -23,2 +18,3 @@ | ||
const MINI_APPS_METHOD = 'web_app_setup_main_button'; | ||
const CLICK_EVENT = 'main_button_pressed'; | ||
@@ -28,2 +24,19 @@ const STORAGE_KEY = 'mainButton'; | ||
/** | ||
* Mounts the component. | ||
* | ||
* This function restores the component state and is automatically saving it in the local storage | ||
* if it changed. | ||
*/ | ||
export function mount(): void { | ||
if (!isMounted()) { | ||
const prev = isPageReload() && getStorageValue<StorageValue>(STORAGE_KEY); | ||
prev && internalState.set(prev); | ||
internalState.sub(onInternalStateChanged); | ||
state.sub(onStateChanged); | ||
isMounted.set(true); | ||
} | ||
} | ||
/** | ||
* Adds a new main button click listener. | ||
@@ -45,41 +58,18 @@ * @param fn - event listener. | ||
/** | ||
* Mounts the component. | ||
* | ||
* This function restores the component state and is automatically saving it in the local storage | ||
* if it changed. | ||
*/ | ||
export function mount(): void { | ||
if (!isMounted()) { | ||
const prev = isPageReload() && getStorageValue<StorageValue>(STORAGE_KEY); | ||
if (prev) { | ||
state.set(prev); | ||
} else { | ||
tpMount(); | ||
setParams({ | ||
backgroundColor: tpButtonColor(), | ||
textColor: tpButtonTextColor(), | ||
}); | ||
} | ||
state.sub(onStateChanged); | ||
isMounted.set(true); | ||
} | ||
function onInternalStateChanged(state: State): void { | ||
setStorageValue<StorageValue>(STORAGE_KEY, state); | ||
} | ||
function onStateChanged(s: State): void { | ||
// We should not commit changes until the payload is correct. Some version of Telegram will | ||
// crash due to the empty value of the text. | ||
if (s.text) { | ||
postEvent('web_app_setup_main_button', { | ||
has_shine_effect: s.hasShineEffect, | ||
is_visible: s.isVisible, | ||
is_active: s.isEnabled, | ||
is_progress_visible: s.isLoaderVisible, | ||
text: s.text, | ||
color: s.backgroundColor, | ||
text_color: s.textColor, | ||
}); | ||
} | ||
setStorageValue<StorageValue>(STORAGE_KEY, s); | ||
function onStateChanged(s: Required<State>): void { | ||
// We should not commit changes until the payload is correct. | ||
// Some version of Telegram will crash due to the empty value of the text. | ||
s.text && postEvent(MINI_APPS_METHOD, { | ||
color: s.backgroundColor, | ||
has_shine_effect: s.hasShineEffect, | ||
is_active: s.isEnabled, | ||
is_progress_visible: s.isLoaderVisible, | ||
is_visible: s.isVisible, | ||
text: s.text, | ||
text_color: s.textColor, | ||
}); | ||
} | ||
@@ -92,4 +82,4 @@ | ||
export function setParams(updates: Partial<State>): void { | ||
state.set({ | ||
...state(), | ||
internalState.set({ | ||
...internalState(), | ||
...Object.fromEntries( | ||
@@ -108,4 +98,5 @@ Object.entries(updates).filter(([, v]) => v !== undefined), | ||
export function unmount(): void { | ||
internalState.unsub(onInternalStateChanged); | ||
state.unsub(onStateChanged); | ||
isMounted.set(false); | ||
} |
import { computed, type Computed, signal } from '@telegram-apps/signals'; | ||
import { buttonColor, buttonTextColor } from '@/scopes/components/theme-params/signals.js'; | ||
import type { State } from './types.js'; | ||
/* USUAL */ | ||
function fromState<K extends keyof Required<State>>(key: K): Computed<Required<State>[K]> { | ||
return computed(() => state()[key]); | ||
} | ||
/** | ||
* Complete component state. | ||
*/ | ||
export const state = signal<State>({ | ||
backgroundColor: '#2481cc', | ||
export const internalState = signal<State>({ | ||
hasShineEffect: false, | ||
@@ -17,6 +17,17 @@ isEnabled: true, | ||
text: 'Continue', | ||
textColor: '#ffffff', | ||
}); | ||
/** | ||
* Complete component state. | ||
*/ | ||
export const state = computed<Required<State>>(() => { | ||
const s = internalState(); | ||
return { | ||
...s, | ||
backgroundColor: s.backgroundColor || buttonColor() || '#2481cc', | ||
textColor: s.textColor || buttonTextColor() || '#ffffff', | ||
}; | ||
}); | ||
/** | ||
* True if the component is currently mounted. | ||
@@ -26,12 +37,6 @@ */ | ||
/* COMPUTED */ | ||
function createStateComputed<K extends keyof State>(key: K): Computed<State[K]> { | ||
return computed(() => state()[key]); | ||
} | ||
/** | ||
* @see State.backgroundColor | ||
*/ | ||
export const backgroundColor = createStateComputed('backgroundColor'); | ||
export const backgroundColor = fromState('backgroundColor'); | ||
@@ -41,3 +46,3 @@ /** | ||
*/ | ||
export const hasShineEffect = createStateComputed('hasShineEffect'); | ||
export const hasShineEffect = fromState('hasShineEffect'); | ||
@@ -47,3 +52,3 @@ /** | ||
*/ | ||
export const isEnabled = createStateComputed('isEnabled'); | ||
export const isEnabled = fromState('isEnabled'); | ||
@@ -53,3 +58,3 @@ /** | ||
*/ | ||
export const isLoaderVisible = createStateComputed('isLoaderVisible'); | ||
export const isLoaderVisible = fromState('isLoaderVisible'); | ||
@@ -59,3 +64,3 @@ /** | ||
*/ | ||
export const isVisible = createStateComputed('isVisible'); | ||
export const isVisible = fromState('isVisible'); | ||
@@ -65,3 +70,3 @@ /** | ||
*/ | ||
export const text = createStateComputed('text'); | ||
export const text = fromState('text'); | ||
@@ -71,2 +76,2 @@ /** | ||
*/ | ||
export const textColor = createStateComputed('textColor'); | ||
export const textColor = fromState('textColor'); |
@@ -6,4 +6,6 @@ import type { RGB } from '@telegram-apps/bridge'; | ||
* The main button background color. | ||
* | ||
* This value may be missing in case, some specific RGB color was not yet set. | ||
*/ | ||
backgroundColor: RGB; | ||
backgroundColor?: RGB; | ||
/** | ||
@@ -31,4 +33,6 @@ * True if the Main Button has a shining effect. | ||
* The main button text color. | ||
* | ||
* This value may be missing in case, some specific RGB color was not yet set. | ||
*/ | ||
textColor: RGB; | ||
} | ||
textColor?: RGB; | ||
} |
@@ -1,2 +0,2 @@ | ||
import { beforeEach, describe, expect, it, Mock, MockInstance, vi } from 'vitest'; | ||
import { beforeEach, describe, expect, it, MockInstance, vi } from 'vitest'; | ||
import { createWindow } from 'test-utils'; | ||
@@ -8,2 +8,3 @@ import type { ThemeParams } from '@telegram-apps/bridge'; | ||
import * as themeParams from '@/scopes/components/theme-params/instance.js'; | ||
import { $version } from '@/scopes/globals.js'; | ||
@@ -17,4 +18,16 @@ import { | ||
isCssVarsBound, | ||
bottomBarColor, | ||
bottomBarColorRGB, | ||
backgroundColorRGB, | ||
headerColorRGB, | ||
} from './signals.js'; | ||
import { bindCssVars, mount, setBackgroundColor, setHeaderColor } from './methods.js'; | ||
import { | ||
bindCssVars, | ||
close, | ||
mount, | ||
ready, | ||
setBackgroundColor, | ||
setBottomBarColor, | ||
setHeaderColor, | ||
} from './methods.js'; | ||
@@ -50,2 +63,6 @@ type SetPropertyFn = typeof document.documentElement.style.setProperty; | ||
isCssVarsBound, | ||
bottomBarColor, | ||
bottomBarColorRGB, | ||
backgroundColorRGB, | ||
headerColorRGB, | ||
].forEach(resetSignal); | ||
@@ -62,34 +79,27 @@ | ||
describe('bindCssVars', () => { | ||
describe('backgroundColor', () => { | ||
it('should set --tg-bg-color == backgroundColor()', () => { | ||
backgroundColor.set('#abcdef'); | ||
describe('background color', () => { | ||
it('should set --tg-bg-color == backgroundColorRGB()', () => { | ||
backgroundColor.set('#fedcba'); | ||
bindCssVars(); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bg-color', '#abcdef'); | ||
expect(setPropertySpy).toHaveBeenCalledTimes(3); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bg-color', '#fedcba'); | ||
}); | ||
}); | ||
describe('headerColor', () => { | ||
it('should set --tg-header-color == headerColor() if header color is RGB', () => { | ||
describe('header color', () => { | ||
it('should set --tg-header-color == headerColorRGB()', () => { | ||
headerColor.set('#fedcba'); | ||
bindCssVars(); | ||
expect(setPropertySpy).toHaveBeenCalledTimes(2); | ||
expect(setPropertySpy).toHaveBeenCalledTimes(3); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-header-color', '#fedcba'); | ||
}); | ||
}); | ||
it('should set --tg-header-color equal to theme params bgColor if headerColor is bg_color', () => { | ||
headerColor.set('bg_color'); | ||
themeParams.state.set({ bgColor: '#aaaaaa' }); | ||
describe('bottom bar color', () => { | ||
it('should set --tg-bottom-bar-color == bottomBarColorRGB()', () => { | ||
bottomBarColor.set('#fedcba'); | ||
bindCssVars(); | ||
expect(setPropertySpy).toHaveBeenCalledTimes(2); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-header-color', '#aaaaaa'); | ||
expect(setPropertySpy).toHaveBeenCalledTimes(3); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bottom-bar-color', '#fedcba'); | ||
}); | ||
it('should set --tg-header-color equal to theme params secondaryBgColor if headerColor is secondary_bg_color', () => { | ||
headerColor.set('secondary_bg_color'); | ||
themeParams.state.set({ secondaryBgColor: '#dddddd' }); | ||
bindCssVars(); | ||
expect(setPropertySpy).toHaveBeenCalledTimes(2); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-header-color', '#dddddd'); | ||
}); | ||
}); | ||
@@ -100,62 +110,184 @@ | ||
describe('backgroundColor', () => { | ||
it('should set --tg-bg-color == backgroundColor() when background color changed', () => { | ||
describe('background color', () => { | ||
it('should set --tg-bg-color == backgroundColorRGB() when theme changes', () => { | ||
bindCssVars(); | ||
themeParams.state.set({ secondaryBgColor: '#ddddaa' }); | ||
setPropertySpy.mockClear(); | ||
backgroundColor.set('#aaaaaa'); | ||
backgroundColor.set('secondary_bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bg-color', '#aaaaaa'); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bg-color', '#ddddaa'); | ||
themeParams.state.set({ bgColor: '#aafedd' }); | ||
setPropertySpy.mockClear(); | ||
backgroundColor.set('bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bg-color', '#aafedd'); | ||
setPropertySpy.mockClear(); | ||
backgroundColor.set('secondary_bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bg-color', null); | ||
}); | ||
}); | ||
describe('headerColor', () => { | ||
it('should update --tg-header-color each time headerColor or related theme param changes', () => { | ||
describe('header color', () => { | ||
it('should set --tg-header-color == headerColorRGB() when theme changes', () => { | ||
bindCssVars(); | ||
themeParams.state.set({ | ||
bgColor: '#ffffff', | ||
secondaryBgColor: '#eeeeee', | ||
}); | ||
themeParams.state.set({ secondaryBgColor: '#ddddaa' }); | ||
setPropertySpy.mockClear(); | ||
headerColor.set('secondary_bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-header-color', '#eeeeee'); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-header-color', '#ddddaa'); | ||
themeParams.state.set({ bgColor: '#aafedd' }); | ||
setPropertySpy.mockClear(); | ||
headerColor.set('bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-header-color', '#ffffff'); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-header-color', '#aafedd'); | ||
setPropertySpy.mockClear(); | ||
themeParams.state.set({ | ||
bgColor: '#aaaaaa', | ||
}); | ||
headerColor.set('secondary_bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-header-color', '#aaaaaa'); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-header-color', null); | ||
}); | ||
}); | ||
let spy: Mock; | ||
describe('bottom bar color', () => { | ||
it('should set --tg-bottom-bar-color == bottomBarColorRGB() when theme changes', () => { | ||
bindCssVars(); | ||
themeParams.state.set({ bgColor: '#aafedd' }); | ||
setPropertySpy.mockClear(); | ||
bottomBarColor.set('bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bottom-bar-color', '#aafedd'); | ||
beforeEach(() => { | ||
spy = mockPostEvent(); | ||
}); | ||
themeParams.state.set({ secondaryBgColor: '#ddddaa' }); | ||
setPropertySpy.mockClear(); | ||
bottomBarColor.set('secondary_bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bottom-bar-color', '#ddddaa'); | ||
describe('setBackgroundColor', () => { | ||
it('should call "web_app_set_background_color" method with { color: {{color}} }', () => { | ||
expect(spy).toHaveBeenCalledTimes(0); | ||
setBackgroundColor('#abcdef'); | ||
expect(spy).toHaveBeenCalledTimes(1); | ||
expect(spy).toHaveBeenCalledWith('web_app_set_background_color', { color: '#abcdef' }); | ||
themeParams.state.set({ bottomBarBgColor: '#ddaacc' }); | ||
setPropertySpy.mockClear(); | ||
bottomBarColor.set('bottom_bar_bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bottom-bar-color', '#ddaacc'); | ||
setPropertySpy.mockClear(); | ||
bottomBarColor.set('bg_color'); | ||
expect(setPropertySpy).toHaveBeenCalledOnce(); | ||
expect(setPropertySpy).toHaveBeenCalledWith('--tg-bottom-bar-color', null); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('setHeaderColor', () => { | ||
it('should call "web_app_set_header_color" method with { color_key: {{color_key}} }', () => { | ||
expect(spy).toHaveBeenCalledTimes(0); | ||
setHeaderColor('secondary_bg_color'); | ||
expect(spy).toHaveBeenCalledTimes(1); | ||
expect(spy).toHaveBeenCalledWith('web_app_set_header_color', { color_key: 'secondary_bg_color' }); | ||
}); | ||
describe('mounted', () => { | ||
beforeEach(mount); | ||
describe('setBackgroundColor', () => { | ||
it('should call "web_app_set_background_color" method with { color: {{color}} }', () => { | ||
const spy = mockPostEvent(); | ||
expect(spy).toHaveBeenCalledTimes(0); | ||
setBackgroundColor('#abcdef'); | ||
expect(spy).toHaveBeenCalledTimes(1); | ||
expect(spy).toHaveBeenCalledWith('web_app_set_background_color', { color: '#abcdef' }); | ||
}); | ||
}); | ||
describe('setBottomBarColor', () => { | ||
it('should call "web_app_set_bottom_bar_color" method with { color: {{color}} }', () => { | ||
const spy = mockPostEvent(); | ||
expect(spy).toHaveBeenCalledTimes(0); | ||
setBottomBarColor('#abcdef'); | ||
expect(spy).toHaveBeenCalledTimes(1); | ||
expect(spy).toHaveBeenCalledWith('web_app_set_bottom_bar_color', { color: '#abcdef' }); | ||
}); | ||
}); | ||
describe('setHeaderColor', () => { | ||
it('should call "web_app_set_header_color" method with { color_key: {{color_key}} }', () => { | ||
const spy = mockPostEvent(); | ||
expect(spy).toHaveBeenCalledTimes(0); | ||
setHeaderColor('secondary_bg_color'); | ||
expect(spy).toHaveBeenCalledTimes(1); | ||
expect(spy).toHaveBeenCalledWith('web_app_set_header_color', { color_key: 'secondary_bg_color' }); | ||
}); | ||
}); | ||
}); | ||
describe('close', () => { | ||
it('should call "web_app_close" with "return_back" option', () => { | ||
const spy = mockPostEvent(); | ||
close(false); | ||
expect(spy).toHaveBeenCalledOnce(); | ||
expect(spy).toHaveBeenCalledWith('web_app_close', { return_back: false }); | ||
}); | ||
}); | ||
describe('ready', () => { | ||
it('should call "web_app_ready"', () => { | ||
const spy = mockPostEvent(); | ||
ready(); | ||
expect(spy).toHaveBeenCalledOnce(); | ||
expect(spy).toHaveBeenCalledWith('web_app_ready', undefined); | ||
}); | ||
}); | ||
describe('setBackgroundColor', () => { | ||
describe('isSupported', () => { | ||
it('should return false if version is less than 6.1. True otherwise', () => { | ||
$version.set('6.0'); | ||
expect(setBackgroundColor.isSupported()).toBe(false); | ||
$version.set('6.1'); | ||
expect(setBackgroundColor.isSupported()).toBe(true); | ||
$version.set('6.2'); | ||
expect(setBackgroundColor.isSupported()).toBe(true); | ||
}); | ||
}); | ||
}); | ||
describe('setBottomBarColor', () => { | ||
describe('isSupported', () => { | ||
it('should return false if version is less than 7.10. True otherwise', () => { | ||
$version.set('7.9'); | ||
expect(setBottomBarColor.isSupported()).toBe(false); | ||
$version.set('7.10'); | ||
expect(setBottomBarColor.isSupported()).toBe(true); | ||
$version.set('7.11'); | ||
expect(setBottomBarColor.isSupported()).toBe(true); | ||
}); | ||
}); | ||
}); | ||
describe('setHeaderColor', () => { | ||
describe('isSupported', () => { | ||
it('should return false if version is less than 6.1. True otherwise', () => { | ||
$version.set('6.0'); | ||
expect(setHeaderColor.isSupported()).toBe(false); | ||
$version.set('6.1'); | ||
expect(setHeaderColor.isSupported()).toBe(true); | ||
$version.set('6.2'); | ||
expect(setHeaderColor.isSupported()).toBe(true); | ||
}); | ||
}); | ||
describe('supports "color"', () => { | ||
it('should return false if version is less than 6.9. True otherwise', () => { | ||
$version.set('6.8'); | ||
expect(setHeaderColor.supports('color')).toBe(false); | ||
$version.set('6.9'); | ||
expect(setHeaderColor.supports('color')).toBe(true); | ||
$version.set('6.10'); | ||
expect(setHeaderColor.supports('color')).toBe(true); | ||
}); | ||
}); | ||
}); |
@@ -10,5 +10,7 @@ import { | ||
type RGB, | ||
type BottomBarColor, BackgroundColor, | ||
} from '@telegram-apps/bridge'; | ||
import { isRGB } from '@telegram-apps/transformers'; | ||
import { isPageReload } from '@telegram-apps/navigation'; | ||
import type { Computed } from '@telegram-apps/signals'; | ||
@@ -21,4 +23,2 @@ import { postEvent } from '@/scopes/globals.js'; | ||
mount as tpMount, | ||
state as tpState, | ||
backgroundColor as tpBackgroundColor, | ||
headerBackgroundColor as tpHeaderBackgroundColor, | ||
@@ -33,2 +33,6 @@ } from '@/scopes/components/theme-params/instance.js'; | ||
isMounted, | ||
bottomBarColor, | ||
headerColorRGB, | ||
bottomBarColorRGB, | ||
backgroundColorRGB, | ||
} from './signals.js'; | ||
@@ -40,2 +44,3 @@ import type { GetCssVarNameFn, HeaderColor, State } from './types.js'; | ||
const SET_BG_COLOR_METHOD = 'web_app_set_background_color'; | ||
const SET_BOTTOM_BAR_BG_COLOR_METHOD = 'web_app_set_bottom_bar_color'; | ||
const SET_HEADER_COLOR_METHOD = 'web_app_set_header_color'; | ||
@@ -50,2 +55,3 @@ const STORAGE_KEY = 'miniApp'; | ||
* - `--tg-header-color` | ||
* - `--tg-bottom-bar-color` | ||
* | ||
@@ -56,3 +62,2 @@ * Variables are being automatically updated if theme parameters were changed. | ||
* mini app key. | ||
* MiniApp property. | ||
* @returns Function to stop updating variables. | ||
@@ -65,41 +70,32 @@ * @throws {TypedError} ERR_ALREADY_CALLED | ||
} | ||
getCSSVarName ||= (prop) => `--tg-${camelToKebab(prop)}`; | ||
const bgVar = getCSSVarName('bgColor'); | ||
const headerVar = getCSSVarName('headerColor'); | ||
const [addCleanup, cleanup] = createCbCollector(); | ||
function updateHeaderColor() { | ||
const tp = tpState(); | ||
const h = headerColor(); | ||
if (isRGB(h)) { | ||
return setCssVar(headerVar, h); | ||
/** | ||
* Binds specified CSS variable to a signal. | ||
* @param cssVar - CSS variable name. | ||
* @param signal - signal to listen changes to. | ||
*/ | ||
function bind(cssVar: string, signal: Computed<RGB | undefined>) { | ||
function update() { | ||
setCssVar(cssVar, signal() || null); | ||
} | ||
const { secondaryBgColor, bgColor } = tp; | ||
if (h === 'bg_color' && bgColor) { | ||
return setCssVar(headerVar, bgColor); | ||
} | ||
if (h === 'secondary_bg_color' && secondaryBgColor) { | ||
setCssVar(headerVar, secondaryBgColor); | ||
} | ||
} | ||
// Instantly set CSS variable. | ||
update(); | ||
function updateBgColor() { | ||
setCssVar(bgVar, backgroundColor()); | ||
// Remember to clean this relation up. | ||
addCleanup(signal.sub(update), deleteCssVar.bind(null, cssVar)); | ||
} | ||
updateBgColor(); | ||
updateHeaderColor(); | ||
getCSSVarName ||= (prop) => `--tg-${camelToKebab(prop)}`; | ||
bind(getCSSVarName('bgColor'), backgroundColorRGB); | ||
bind(getCSSVarName('bottomBarColor'), bottomBarColorRGB); | ||
bind(getCSSVarName('headerColor'), headerColorRGB); | ||
addCleanup(() => { | ||
isCssVarsBound.set(false); | ||
}); | ||
const [, cleanup] = createCbCollector( | ||
backgroundColor.sub(updateBgColor), | ||
[headerColor, tpState].map(s => s.sub(updateHeaderColor)), | ||
); | ||
isCssVarsBound.set(true); | ||
return () => { | ||
[headerVar, bgVar].forEach(deleteCssVar); | ||
cleanup(); | ||
isCssVarsBound.set(false); | ||
}; | ||
return cleanup; | ||
} | ||
@@ -120,2 +116,5 @@ | ||
* if it changed. | ||
* | ||
* Internally, the function mounts the Theme Params component to work with correctly extracted | ||
* theme palette values. | ||
*/ | ||
@@ -126,4 +125,6 @@ export function mount(): void { | ||
tpMount(); | ||
backgroundColor.set(s ? s.backgroundColor : tpBackgroundColor() || '#000000'); | ||
backgroundColor.set(s ? s.backgroundColor : 'bg_color'); | ||
backgroundColor.sub(onBgColorChanged); | ||
bottomBarColor.set(s ? s.bottomBarColor : 'bottom_bar_bg_color'); | ||
bottomBarColor.sub(onBottomBarBgColorChanged); | ||
headerColor.set(s ? s.headerColor : tpHeaderBackgroundColor() || 'bg_color'); | ||
@@ -135,12 +136,17 @@ headerColor.sub(onHeaderColorChanged); | ||
function onHeaderColorChanged(color: HeaderColor): void { | ||
function onBgColorChanged(color: BackgroundColor): void { | ||
saveState(); | ||
postEvent(SET_HEADER_COLOR_METHOD, isRGB(color) ? { color } : { color_key: color }); | ||
postEvent(SET_BG_COLOR_METHOD, { color }); | ||
} | ||
function onBgColorChanged(color: RGB): void { | ||
function onBottomBarBgColorChanged(color: BottomBarColor): void { | ||
saveState(); | ||
postEvent(SET_BG_COLOR_METHOD, { color }); | ||
postEvent(SET_BOTTOM_BAR_BG_COLOR_METHOD, { color }); | ||
} | ||
function onHeaderColorChanged(color: HeaderColor): void { | ||
saveState(); | ||
postEvent(SET_HEADER_COLOR_METHOD, isRGB(color) ? { color } : { color_key: color }); | ||
} | ||
/** | ||
@@ -172,2 +178,9 @@ * Informs the Telegram app that the Mini App is ready to be displayed. | ||
/** | ||
* Updates the bottom bar background color. | ||
*/ | ||
export const setBottomBarColor = withIsSupported((color: BottomBarColor) => { | ||
bottomBarColor.set(color); | ||
}, SET_BOTTOM_BAR_BG_COLOR_METHOD); | ||
/** | ||
* Updates the header color. | ||
@@ -187,4 +200,5 @@ */ | ||
backgroundColor.unsub(onBgColorChanged); | ||
bottomBarColor.unsub(onBottomBarBgColorChanged); | ||
headerColor.unsub(onHeaderColorChanged); | ||
isMounted.set(false); | ||
} |
@@ -1,20 +0,65 @@ | ||
import { computed, signal } from '@telegram-apps/signals'; | ||
import type { RGB } from '@telegram-apps/bridge'; | ||
import { Computed, computed, signal } from '@telegram-apps/signals'; | ||
import { isRGB } from '@telegram-apps/transformers'; | ||
import type { BackgroundColor, BottomBarColor, RGB } from '@telegram-apps/bridge'; | ||
import { isColorDark } from '@/utils/isColorDark.js'; | ||
import { | ||
backgroundColor as themeBgColor, | ||
secondaryBackgroundColor as themeSecondaryBgColor, | ||
bottomBarBgColor as themeBottomBarBgColor, | ||
} from '@/scopes/components/theme-params/signals.js'; | ||
import type { HeaderColor, State } from './types.js'; | ||
/* USUAL */ | ||
// #__NO_SIDE_EFFECTS__ | ||
function colorBasedOn(signal: Computed<'bg_color' | 'secondary_bg_color' | RGB>) { | ||
return computed<RGB | undefined>(() => { | ||
const color = signal(); | ||
return isRGB(color) ? color : color === 'bg_color' | ||
? themeBgColor() | ||
: themeSecondaryBgColor(); | ||
}); | ||
} | ||
/** | ||
* The Mini App background color. | ||
* @example "#ffaabb" | ||
*/ | ||
export const backgroundColor = signal<RGB>('#000000'); | ||
export const backgroundColor = signal<BackgroundColor>('bg_color'); | ||
/** | ||
* RGB representation of the background color. | ||
* | ||
* This value requires the Theme Params component to be mounted to extract a valid RGB value | ||
* of the color key. | ||
*/ | ||
export const backgroundColorRGB = colorBasedOn(backgroundColor); | ||
/** | ||
* The Mini App bottom bar background color. | ||
*/ | ||
export const bottomBarColor = signal<BottomBarColor>('bottom_bar_bg_color'); | ||
/** | ||
* RGB representation of the bottom bar background color. | ||
* | ||
* This value requires the Theme Params component to be mounted to extract a valid RGB value | ||
* of the color key. | ||
*/ | ||
export const bottomBarColorRGB = computed<RGB | undefined>(() => { | ||
const color = bottomBarColor(); | ||
return isRGB(color) | ||
? color | ||
: color === 'bottom_bar_bg_color' | ||
// Following the logic from the Telegram SDK. | ||
// I removed "|| '#ffffff'" because this seems too strange to me. This is just not right. | ||
? themeBottomBarBgColor() || themeSecondaryBgColor() | ||
: color === 'secondary_bg_color' | ||
? themeSecondaryBgColor() | ||
: themeBgColor(); | ||
}); | ||
/** | ||
* The Mini App header color. | ||
* @example "#ffaabb" | ||
* @example "bg_color" | ||
*/ | ||
@@ -24,2 +69,10 @@ export const headerColor = signal<HeaderColor>('bg_color'); | ||
/** | ||
* RGB representation of the header color. | ||
* | ||
* This value requires the Theme Params component to be mounted to extract a valid RGB value | ||
* of the color key. | ||
*/ | ||
export const headerColorRGB = colorBasedOn(headerColor); | ||
/** | ||
* True if the component is currently mounted. | ||
@@ -39,3 +92,6 @@ */ | ||
*/ | ||
export const isDark = computed(() => isColorDark(backgroundColor())); | ||
export const isDark = computed(() => { | ||
const color = backgroundColorRGB(); | ||
return color ? isColorDark(color) : false; | ||
}); | ||
@@ -47,3 +103,4 @@ /** | ||
backgroundColor: backgroundColor(), | ||
bottomBarColor: bottomBarColor(), | ||
headerColor: headerColor(), | ||
})); |
@@ -1,2 +0,2 @@ | ||
import type { HeaderColorKey, RGB } from '@telegram-apps/bridge'; | ||
import type { HeaderColorKey, BottomBarColor, RGB, BackgroundColor } from '@telegram-apps/bridge'; | ||
@@ -9,3 +9,4 @@ /** | ||
export interface State { | ||
backgroundColor: RGB; | ||
backgroundColor: BackgroundColor; | ||
bottomBarColor: BottomBarColor; | ||
headerColor: HeaderColor; | ||
@@ -19,3 +20,3 @@ } | ||
*/ | ||
(property: 'bgColor' | 'headerColor'): string; | ||
(property: 'bgColor' | 'bottomBarColor' | 'headerColor'): string; | ||
} |
@@ -18,5 +18,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; | ||
isVisible, | ||
state, | ||
internalState, | ||
backgroundColor, | ||
hasShineEffect, | ||
state, | ||
position, | ||
} from './signals.js'; | ||
@@ -45,4 +47,13 @@ import { onClick, offClick, setParams, mount, unmount, isSupported } from './methods.js'; | ||
themeParams.state, | ||
text, | ||
textColor, | ||
isMounted, | ||
isEnabled, | ||
isLoaderVisible, | ||
isVisible, | ||
internalState, | ||
backgroundColor, | ||
hasShineEffect, | ||
state, | ||
isMounted, | ||
position, | ||
].forEach(resetSignal); | ||
@@ -58,2 +69,3 @@ mockPostEvent(); | ||
{ signal: isVisible, name: 'isVisible' }, | ||
{ signal: position, name: 'position' }, | ||
{ signal: text, name: 'text' }, | ||
@@ -63,3 +75,3 @@ { signal: textColor, name: 'textColor' }, | ||
beforeEach(() => { | ||
state.set({ | ||
internalState.set({ | ||
backgroundColor: '#123456', | ||
@@ -70,2 +82,3 @@ hasShineEffect: true, | ||
isVisible: true, | ||
position: 'right', | ||
text: 'TEXT', | ||
@@ -77,3 +90,3 @@ textColor: '#789abc', | ||
it(`should use "${name}" property from state`, () => { | ||
expect(signal()).toBe(state()[name]); | ||
expect(signal()).toBe(internalState()[name]); | ||
}); | ||
@@ -101,3 +114,3 @@ }); | ||
it('should save the state in storage key tapps/secondaryButton', () => { | ||
state.set({ | ||
internalState.set({ | ||
backgroundColor: '#123456', | ||
@@ -108,2 +121,3 @@ hasShineEffect: true, | ||
isVisible: true, | ||
position: 'top', | ||
text: 'TEXT', | ||
@@ -119,3 +133,3 @@ textColor: '#789abc', | ||
expect(spy).toHaveBeenCalledTimes(1); | ||
expect(spy).toHaveBeenCalledWith('tapps/secondaryButton', '{"backgroundColor":"#111111","hasShineEffect":true,"isEnabled":true,"isLoaderVisible":true,"isVisible":true,"text":"TEXT","textColor":"#789abc"}'); | ||
expect(spy).toHaveBeenCalledWith('tapps/secondaryButton', '{"backgroundColor":"#111111","hasShineEffect":true,"isEnabled":true,"isLoaderVisible":true,"isVisible":true,"position":"top","text":"TEXT","textColor":"#789abc"}'); | ||
}); | ||
@@ -125,3 +139,3 @@ | ||
const spy = mockPostEvent(); | ||
state.set({ | ||
internalState.set({ | ||
backgroundColor: '#123456', | ||
@@ -132,2 +146,3 @@ hasShineEffect: false, | ||
isVisible: true, | ||
position: 'bottom', | ||
text: '', | ||
@@ -142,8 +157,9 @@ textColor: '#789abc', | ||
expect(spy).toHaveBeenCalledWith('web_app_setup_secondary_button', { | ||
color: '#123456', | ||
has_shine_effect: false, | ||
is_visible: true, | ||
is_active: true, | ||
is_progress_visible: true, | ||
is_visible: true, | ||
position: 'bottom', | ||
text: 'abc', | ||
color: '#123456', | ||
text_color: '#789abc', | ||
@@ -261,3 +277,3 @@ }); | ||
it('should merge passed object with the state', () => { | ||
state.set({ | ||
internalState.set({ | ||
backgroundColor: '#123456', | ||
@@ -268,2 +284,3 @@ hasShineEffect: true, | ||
isVisible: true, | ||
position: 'right', | ||
text: 'TEXT', | ||
@@ -281,3 +298,3 @@ textColor: '#789abc', | ||
expect(state()).toStrictEqual({ | ||
expect(internalState()).toStrictEqual({ | ||
backgroundColor: '#111111', | ||
@@ -288,2 +305,3 @@ hasShineEffect: true, | ||
isVisible: true, | ||
position: 'right', | ||
text: 'TEXT UPDATED', | ||
@@ -301,3 +319,3 @@ textColor: '#000000', | ||
const storageSpy = mockSessionStorageSetItem(); | ||
state.set({ ...state(), text: 'Hello!' }); | ||
internalState.set({ ...internalState(), text: 'Hello!' }); | ||
expect(postEventSpy).toHaveBeenCalledTimes(1); | ||
@@ -310,3 +328,3 @@ expect(storageSpy).toHaveBeenCalledTimes(1); | ||
unmount(); | ||
state.set({ ...state() }); | ||
internalState.set({ ...internalState() }); | ||
@@ -313,0 +331,0 @@ expect(postEventSpy).toHaveBeenCalledTimes(0); |
@@ -11,9 +11,4 @@ import { | ||
import { $version, postEvent } from '@/scopes/globals.js'; | ||
import { | ||
mount as tpMount, | ||
buttonColor as tpButtonColor, | ||
buttonTextColor as tpButtonTextColor, | ||
} from '@/scopes/components/theme-params/instance.js'; | ||
import { state, isMounted } from './signals.js'; | ||
import { internalState, isMounted, state } from './signals.js'; | ||
import type { State } from './types.js'; | ||
@@ -35,2 +30,19 @@ | ||
/** | ||
* Mounts the component. | ||
* | ||
* This function restores the component state and is automatically saving it in the local storage | ||
* if it changed. | ||
*/ | ||
export function mount(): void { | ||
if (!isMounted()) { | ||
const prev = isPageReload() && getStorageValue<StorageValue>(STORAGE_KEY); | ||
prev && internalState.set(prev); | ||
internalState.sub(onInternalStateChanged); | ||
state.sub(onStateChanged); | ||
isMounted.set(true); | ||
} | ||
} | ||
/** | ||
* Adds a new main button click listener. | ||
@@ -52,41 +64,19 @@ * @param fn - event listener. | ||
/** | ||
* Mounts the component. | ||
* | ||
* This function restores the component state and is automatically saving it in the local storage | ||
* if it changed. | ||
*/ | ||
export function mount(): void { | ||
if (!isMounted()) { | ||
const prev = isPageReload() && getStorageValue<StorageValue>(STORAGE_KEY); | ||
if (prev) { | ||
state.set(prev); | ||
} else { | ||
tpMount(); | ||
setParams({ | ||
backgroundColor: tpButtonColor(), | ||
textColor: tpButtonTextColor(), | ||
}); | ||
} | ||
state.sub(onStateChanged); | ||
isMounted.set(true); | ||
} | ||
function onInternalStateChanged(s: State): void { | ||
setStorageValue<StorageValue>(STORAGE_KEY, s); | ||
} | ||
function onStateChanged(s: State): void { | ||
function onStateChanged(s: Required<State>): void { | ||
// We should not commit changes until the payload is correct. Some version of Telegram will | ||
// crash due to the empty value of the text. | ||
if (s.text) { | ||
postEvent(MINI_APPS_METHOD, { | ||
has_shine_effect: s.hasShineEffect, | ||
is_visible: s.isVisible, | ||
is_active: s.isEnabled, | ||
is_progress_visible: s.isLoaderVisible, | ||
text: s.text, | ||
color: s.backgroundColor, | ||
text_color: s.textColor, | ||
}); | ||
} | ||
setStorageValue<StorageValue>(STORAGE_KEY, s); | ||
s.text && postEvent(MINI_APPS_METHOD, { | ||
color: s.backgroundColor, | ||
has_shine_effect: s.hasShineEffect, | ||
is_active: s.isEnabled, | ||
is_progress_visible: s.isLoaderVisible, | ||
is_visible: s.isVisible, | ||
position: s.position, | ||
text: s.text, | ||
text_color: s.textColor, | ||
}); | ||
} | ||
@@ -99,4 +89,4 @@ | ||
export function setParams(updates: Partial<State>): void { | ||
state.set({ | ||
...state(), | ||
internalState.set({ | ||
...internalState(), | ||
...Object.fromEntries( | ||
@@ -115,4 +105,5 @@ Object.entries(updates).filter(([, v]) => v !== undefined), | ||
export function unmount(): void { | ||
internalState.unsub(onInternalStateChanged); | ||
state.unsub(onStateChanged); | ||
isMounted.set(false); | ||
} |
import { computed, type Computed, signal } from '@telegram-apps/signals'; | ||
import { buttonColor } from '@/scopes/components/theme-params/signals.js'; | ||
import { bottomBarColorRGB } from '@/scopes/components/mini-app/signals.js'; | ||
import type { State } from './types.js'; | ||
/* USUAL */ | ||
function fromState<K extends keyof Required<State>>(key: K): Computed<Required<State>[K]> { | ||
return computed(() => state()[key]); | ||
} | ||
/** | ||
* Complete component state. | ||
*/ | ||
export const state = signal<State>({ | ||
backgroundColor: '#000000', | ||
export const internalState = signal<State>({ | ||
hasShineEffect: false, | ||
@@ -16,7 +17,19 @@ isEnabled: true, | ||
isVisible: false, | ||
position: 'left', | ||
text: 'Cancel', | ||
textColor: '#2481cc', | ||
}); | ||
/** | ||
* Complete component state. | ||
*/ | ||
export const state = computed<Required<State>>(() => { | ||
const s = internalState(); | ||
return { | ||
...s, | ||
backgroundColor: s.backgroundColor || bottomBarColorRGB() || '#000000', | ||
textColor: s.textColor || buttonColor() || '#2481cc', | ||
}; | ||
}); | ||
/** | ||
* True if the component is currently mounted. | ||
@@ -26,12 +39,6 @@ */ | ||
/* COMPUTED */ | ||
function createStateComputed<K extends keyof State>(key: K): Computed<State[K]> { | ||
return computed(() => state()[key]); | ||
} | ||
/** | ||
* @see State.backgroundColor | ||
*/ | ||
export const backgroundColor = createStateComputed('backgroundColor'); | ||
export const backgroundColor = fromState('backgroundColor'); | ||
@@ -41,3 +48,3 @@ /** | ||
*/ | ||
export const hasShineEffect = createStateComputed('hasShineEffect'); | ||
export const hasShineEffect = fromState('hasShineEffect'); | ||
@@ -47,3 +54,3 @@ /** | ||
*/ | ||
export const isEnabled = createStateComputed('isEnabled'); | ||
export const isEnabled = fromState('isEnabled'); | ||
@@ -53,3 +60,3 @@ /** | ||
*/ | ||
export const isLoaderVisible = createStateComputed('isLoaderVisible'); | ||
export const isLoaderVisible = fromState('isLoaderVisible'); | ||
@@ -59,8 +66,13 @@ /** | ||
*/ | ||
export const isVisible = createStateComputed('isVisible'); | ||
export const isVisible = fromState('isVisible'); | ||
/** | ||
* @see State.position | ||
*/ | ||
export const position = fromState('position'); | ||
/** | ||
* @see State.text | ||
*/ | ||
export const text = createStateComputed('text'); | ||
export const text = fromState('text'); | ||
@@ -70,2 +82,2 @@ /** | ||
*/ | ||
export const textColor = createStateComputed('textColor'); | ||
export const textColor = fromState('textColor'); |
@@ -1,2 +0,2 @@ | ||
import type { RGB } from '@telegram-apps/bridge'; | ||
import type { RGB, SecondaryButtonPosition } from '@telegram-apps/bridge'; | ||
@@ -6,4 +6,6 @@ export interface State { | ||
* The Secondary Button background color. | ||
* | ||
* This value may be missing in case, some specific RGB color was not yet set. | ||
*/ | ||
backgroundColor: RGB; | ||
backgroundColor?: RGB; | ||
/** | ||
@@ -26,2 +28,6 @@ * True if the Secondary Button has a shining effect. | ||
/** | ||
* The button position relative to the main one. | ||
*/ | ||
position: SecondaryButtonPosition; | ||
/** | ||
* The Secondary Button text. | ||
@@ -32,4 +38,6 @@ */ | ||
* The Secondary Button text color. | ||
* | ||
* This value may be missing in case, some specific RGB color was not yet set. | ||
*/ | ||
textColor: RGB; | ||
textColor?: RGB; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
975305
162
10377