@tma.js/sdk 0.13.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (426) hide show
  1. package/dist/dts/{components/BackButton → back-button}/BackButton.d.ts +12 -9
  2. package/dist/dts/back-button/index.d.ts +2 -0
  3. package/dist/dts/{components/BackButton → back-button}/types.d.ts +3 -2
  4. package/dist/dts/bridge/env/hasExternalNotify.d.ts +12 -0
  5. package/dist/dts/bridge/env/hasWebviewProxy.d.ts +12 -0
  6. package/dist/dts/bridge/env/index.d.ts +3 -0
  7. package/dist/dts/bridge/env/isIframe.d.ts +5 -0
  8. package/dist/dts/bridge/errors/MethodUnsupportedError.d.ts +8 -0
  9. package/dist/dts/bridge/errors/ParameterUnsupportedError.d.ts +8 -0
  10. package/dist/dts/bridge/errors/index.d.ts +2 -0
  11. package/dist/dts/bridge/events/createEmitter.d.ts +6 -0
  12. package/dist/dts/bridge/events/events.d.ts +130 -0
  13. package/dist/dts/bridge/events/index.d.ts +9 -0
  14. package/dist/dts/bridge/events/off.d.ts +7 -0
  15. package/dist/dts/bridge/events/on.d.ts +10 -0
  16. package/dist/dts/bridge/events/onTelegramEvent.d.ts +7 -0
  17. package/dist/dts/bridge/events/once.d.ts +9 -0
  18. package/dist/dts/bridge/events/parsers/clipboardTextReceived.d.ts +13 -0
  19. package/dist/dts/bridge/events/parsers/customMethodInvoked.d.ts +16 -0
  20. package/dist/dts/bridge/events/parsers/index.d.ts +9 -0
  21. package/dist/dts/bridge/events/parsers/invoiceClosed.d.ts +12 -0
  22. package/dist/dts/bridge/events/parsers/phoneRequested.d.ts +8 -0
  23. package/dist/dts/bridge/events/parsers/popupClosed.d.ts +8 -0
  24. package/dist/dts/bridge/events/parsers/qrTextReceived.d.ts +7 -0
  25. package/dist/dts/bridge/events/parsers/theme-changed.d.ts +42 -0
  26. package/dist/dts/bridge/events/parsers/viewportChanged.d.ts +19 -0
  27. package/dist/dts/bridge/events/parsers/writeAccessRequested.d.ts +8 -0
  28. package/dist/dts/bridge/events/singletonEmitter.d.ts +6 -0
  29. package/dist/dts/bridge/events/subscribe.d.ts +9 -0
  30. package/dist/dts/bridge/events/unsubscribe.d.ts +6 -0
  31. package/dist/dts/bridge/index.d.ts +5 -0
  32. package/dist/dts/bridge/methods/createPostEvent.d.ts +10 -0
  33. package/dist/dts/bridge/methods/haptic.d.ts +40 -0
  34. package/dist/dts/bridge/methods/index.d.ts +6 -0
  35. package/dist/dts/bridge/methods/invoke-custom-method.d.ts +24 -0
  36. package/dist/dts/bridge/methods/methods.d.ts +329 -0
  37. package/dist/dts/bridge/methods/popup.d.ts +49 -0
  38. package/dist/dts/bridge/methods/postEvent.d.ts +29 -0
  39. package/dist/dts/bridge/request.d.ts +65 -0
  40. package/dist/dts/classnames/classNames.d.ts +10 -0
  41. package/dist/dts/classnames/index.d.ts +2 -0
  42. package/dist/dts/classnames/mergeClassNames.d.ts +32 -0
  43. package/dist/dts/{components/ClosingBehaviour/ClosingBehaviour.d.ts → closing-behavior/ClosingBehavior.d.ts} +5 -4
  44. package/dist/dts/closing-behavior/index.d.ts +2 -0
  45. package/dist/dts/closing-behavior/types.d.ts +7 -0
  46. package/dist/dts/{components/CloudStorage → cloud-storage}/CloudStorage.d.ts +19 -11
  47. package/dist/dts/colors/index.d.ts +5 -0
  48. package/dist/dts/colors/isColorDark.d.ts +6 -0
  49. package/dist/dts/colors/isRGB.d.ts +6 -0
  50. package/dist/dts/colors/isRGBShort.d.ts +6 -0
  51. package/dist/dts/colors/toRGB.d.ts +11 -0
  52. package/dist/dts/colors/types.d.ts +8 -0
  53. package/dist/dts/event-emitter/EventEmitter.d.ts +64 -0
  54. package/dist/dts/event-emitter/index.d.ts +2 -0
  55. package/dist/dts/event-emitter/types.d.ts +44 -0
  56. package/dist/dts/globals.d.ts +22 -0
  57. package/dist/dts/{components/HapticFeedback → haptic-feedback}/HapticFeedback.d.ts +3 -3
  58. package/dist/dts/index.d.ts +24 -6
  59. package/dist/dts/init/catchCustomStyles.d.ts +4 -0
  60. package/dist/dts/init/creators/createBackButton.d.ts +2 -2
  61. package/dist/dts/init/creators/createClosingBehavior.d.ts +3 -3
  62. package/dist/dts/init/creators/createMainButton.d.ts +3 -3
  63. package/dist/dts/init/creators/createMiniApp.d.ts +14 -0
  64. package/dist/dts/init/creators/createRequestIdGenerator.d.ts +1 -1
  65. package/dist/dts/init/creators/createThemeParams.d.ts +2 -3
  66. package/dist/dts/init/creators/createViewport.d.ts +16 -9
  67. package/dist/dts/init/creators/index.d.ts +1 -1
  68. package/dist/dts/init/css/bindMiniAppCSSVars.d.ts +16 -0
  69. package/dist/dts/init/css/bindThemeCSSVars.d.ts +12 -0
  70. package/dist/dts/init/css/bindViewportCSSVars.d.ts +20 -0
  71. package/dist/dts/init/css/index.d.ts +1 -0
  72. package/dist/dts/init/css/processCSSVarsOption.d.ts +12 -0
  73. package/dist/dts/init/css/setCSSVar.d.ts +6 -0
  74. package/dist/dts/init/init.d.ts +5 -5
  75. package/dist/dts/init/types.d.ts +42 -69
  76. package/dist/dts/init-data/InitData.d.ts +53 -0
  77. package/dist/dts/init-data/chatParser.d.ts +5 -0
  78. package/dist/dts/init-data/index.d.ts +6 -0
  79. package/dist/dts/init-data/initDataParser.d.ts +5 -0
  80. package/dist/dts/init-data/parseInitData.d.ts +6 -0
  81. package/dist/dts/init-data/types.d.ts +133 -0
  82. package/dist/dts/init-data/userParser.d.ts +5 -0
  83. package/dist/dts/invoice/Invoice.d.ts +43 -0
  84. package/dist/dts/invoice/index.d.ts +2 -0
  85. package/dist/dts/invoice/types.d.ts +7 -0
  86. package/dist/dts/launch-params/computeLaunchData.d.ts +6 -0
  87. package/dist/dts/launch-params/computePageReload.d.ts +6 -0
  88. package/dist/dts/launch-params/getFirstNavigationEntry.d.ts +6 -0
  89. package/dist/dts/launch-params/index.d.ts +12 -0
  90. package/dist/dts/launch-params/launchParamsParser.d.ts +5 -0
  91. package/dist/dts/launch-params/parseLaunchParams.d.ts +6 -0
  92. package/dist/dts/launch-params/retrieveCurrent.d.ts +5 -0
  93. package/dist/dts/launch-params/retrieveFromLocation.d.ts +6 -0
  94. package/dist/dts/launch-params/retrieveFromPerformance.d.ts +8 -0
  95. package/dist/dts/launch-params/retrieveLaunchData.d.ts +6 -0
  96. package/dist/dts/launch-params/serializeLaunchParams.d.ts +6 -0
  97. package/dist/dts/launch-params/storage.d.ts +13 -0
  98. package/dist/dts/launch-params/types.d.ts +48 -0
  99. package/dist/dts/logger/Logger.d.ts +38 -0
  100. package/dist/dts/logger/index.d.ts +1 -0
  101. package/dist/dts/main-button/MainButton.d.ts +104 -0
  102. package/dist/dts/main-button/index.d.ts +2 -0
  103. package/dist/dts/main-button/types.d.ts +20 -0
  104. package/dist/dts/mini-app/MiniApp.d.ts +99 -0
  105. package/dist/dts/mini-app/index.d.ts +2 -0
  106. package/dist/dts/mini-app/types.d.ts +19 -0
  107. package/dist/dts/misc/index.d.ts +2 -0
  108. package/dist/dts/misc/isRecord.d.ts +5 -0
  109. package/dist/dts/misc/isTMA.d.ts +4 -0
  110. package/dist/dts/navigation/HashNavigator/HashNavigator.d.ts +43 -0
  111. package/dist/dts/navigation/HashNavigator/drop.d.ts +4 -0
  112. package/dist/dts/navigation/HashNavigator/go.d.ts +5 -0
  113. package/dist/dts/navigation/HashNavigator/index.d.ts +2 -0
  114. package/dist/dts/navigation/HashNavigator/types.d.ts +34 -0
  115. package/dist/dts/navigation/Navigator/Navigator.d.ts +104 -0
  116. package/dist/dts/navigation/Navigator/index.d.ts +2 -0
  117. package/dist/dts/navigation/Navigator/types.d.ts +44 -0
  118. package/dist/dts/navigation/ensurePrefix.d.ts +7 -0
  119. package/dist/dts/navigation/getHash.d.ts +14 -0
  120. package/dist/dts/navigation/index.d.ts +4 -0
  121. package/dist/dts/parsing/ArrayValueParser.d.ts +18 -0
  122. package/dist/dts/parsing/ParseError.d.ts +22 -0
  123. package/dist/dts/parsing/ParseSchemaFieldError.d.ts +17 -0
  124. package/dist/dts/parsing/ValueParser.d.ts +36 -0
  125. package/dist/dts/parsing/createValueParserGenerator.d.ts +9 -0
  126. package/dist/dts/parsing/index.d.ts +10 -0
  127. package/dist/dts/parsing/parseBySchema.d.ts +8 -0
  128. package/dist/dts/parsing/parsers/array.d.ts +6 -0
  129. package/dist/dts/parsing/parsers/boolean.d.ts +4 -0
  130. package/dist/dts/parsing/parsers/date.d.ts +4 -0
  131. package/dist/dts/parsing/parsers/index.d.ts +8 -0
  132. package/dist/dts/parsing/parsers/json.d.ts +8 -0
  133. package/dist/dts/parsing/parsers/number.d.ts +4 -0
  134. package/dist/dts/parsing/parsers/rgb.d.ts +4 -0
  135. package/dist/dts/parsing/parsers/searchParams.d.ts +8 -0
  136. package/dist/dts/parsing/parsers/string.d.ts +4 -0
  137. package/dist/dts/parsing/toRecord.d.ts +7 -0
  138. package/dist/dts/parsing/types.d.ts +30 -0
  139. package/dist/dts/parsing/unexpectedTypeError.d.ts +4 -0
  140. package/dist/dts/{components/Popup → popup}/Popup.d.ts +10 -9
  141. package/dist/dts/popup/index.d.ts +2 -0
  142. package/dist/dts/popup/preparePopupParams.d.ts +7 -0
  143. package/dist/dts/{components/Popup → popup}/types.d.ts +4 -4
  144. package/dist/dts/{components/QRScanner → qr-scanner}/QRScanner.d.ts +6 -5
  145. package/dist/dts/qr-scanner/index.d.ts +2 -0
  146. package/dist/dts/{components/QRScanner → qr-scanner}/types.d.ts +1 -1
  147. package/dist/dts/state/State.d.ts +19 -6
  148. package/dist/dts/state/types.d.ts +4 -7
  149. package/dist/dts/storage.d.ts +4 -4
  150. package/dist/dts/supports/createSupportsFunc.d.ts +10 -0
  151. package/dist/dts/supports/createSupportsParamFunc.d.ts +15 -0
  152. package/dist/dts/supports/index.d.ts +4 -0
  153. package/dist/dts/supports/supports.d.ts +15 -0
  154. package/dist/dts/supports/types.d.ts +1 -0
  155. package/dist/dts/theme-params/ThemeParams.d.ts +62 -0
  156. package/dist/dts/theme-params/index.d.ts +6 -0
  157. package/dist/dts/theme-params/keys.d.ts +11 -0
  158. package/dist/dts/theme-params/parseThemeParams.d.ts +6 -0
  159. package/dist/dts/theme-params/requestThemeParams.d.ts +7 -0
  160. package/dist/dts/theme-params/serializeThemeParams.d.ts +5 -0
  161. package/dist/dts/theme-params/themeParamsParser.d.ts +2 -0
  162. package/dist/dts/theme-params/types.d.ts +14 -0
  163. package/dist/dts/timeout/TimeoutError.d.ts +3 -0
  164. package/dist/dts/timeout/index.d.ts +3 -0
  165. package/dist/dts/timeout/isTimeoutError.d.ts +6 -0
  166. package/dist/dts/timeout/withTimeout.d.ts +14 -0
  167. package/dist/dts/types/index.d.ts +3 -0
  168. package/dist/dts/types/platform.d.ts +4 -0
  169. package/dist/dts/types/request-id.d.ts +9 -0
  170. package/dist/dts/types/utils.d.ts +36 -0
  171. package/dist/dts/utils/Utils.d.ts +45 -0
  172. package/dist/dts/utils/index.d.ts +1 -0
  173. package/dist/dts/version/compareVersions.d.ts +8 -0
  174. package/dist/dts/version/index.d.ts +2 -0
  175. package/dist/dts/version/types.d.ts +4 -0
  176. package/dist/dts/{components/Viewport → viewport}/Viewport.d.ts +16 -38
  177. package/dist/dts/viewport/index.d.ts +3 -0
  178. package/dist/dts/viewport/requestViewport.d.ts +12 -0
  179. package/dist/dts/{components/Viewport → viewport}/types.d.ts +9 -1
  180. package/dist/dts/viewport/utils.d.ts +5 -0
  181. package/dist/index.cjs +1 -1
  182. package/dist/index.cjs.map +1 -1
  183. package/dist/index.iife.js +1 -1
  184. package/dist/index.iife.js.map +1 -1
  185. package/dist/index.mjs +2249 -1036
  186. package/dist/index.mjs.map +1 -1
  187. package/package.json +7 -16
  188. package/src/{components/BackButton → back-button}/BackButton.ts +23 -21
  189. package/src/back-button/index.ts +2 -0
  190. package/src/{components/BackButton → back-button}/types.ts +3 -2
  191. package/src/bridge/env/hasExternalNotify.ts +19 -0
  192. package/src/bridge/env/hasWebviewProxy.ts +19 -0
  193. package/src/bridge/env/index.ts +3 -0
  194. package/src/bridge/env/isIframe.ts +11 -0
  195. package/src/bridge/errors/MethodUnsupportedError.ts +13 -0
  196. package/src/bridge/errors/ParameterUnsupportedError.ts +13 -0
  197. package/src/bridge/errors/index.ts +2 -0
  198. package/src/bridge/events/createEmitter.ts +108 -0
  199. package/src/bridge/events/events.ts +170 -0
  200. package/src/bridge/events/index.ts +9 -0
  201. package/src/bridge/events/off.ts +14 -0
  202. package/src/bridge/events/on.ts +19 -0
  203. package/src/bridge/events/onTelegramEvent.ts +83 -0
  204. package/src/bridge/events/once.ts +18 -0
  205. package/src/bridge/events/parsers/clipboardTextReceived.ts +26 -0
  206. package/src/bridge/events/parsers/customMethodInvoked.ts +25 -0
  207. package/src/bridge/events/parsers/index.ts +9 -0
  208. package/src/bridge/events/parsers/invoiceClosed.ts +26 -0
  209. package/src/bridge/events/parsers/phoneRequested.ts +14 -0
  210. package/src/bridge/events/parsers/popupClosed.ts +19 -0
  211. package/src/bridge/events/parsers/qrTextReceived.ts +14 -0
  212. package/src/bridge/events/parsers/theme-changed.ts +58 -0
  213. package/src/bridge/events/parsers/viewportChanged.ts +33 -0
  214. package/src/bridge/events/parsers/writeAccessRequested.ts +14 -0
  215. package/src/bridge/events/singletonEmitter.ts +19 -0
  216. package/src/bridge/events/subscribe.ts +15 -0
  217. package/src/bridge/events/unsubscribe.ts +10 -0
  218. package/src/bridge/index.ts +5 -0
  219. package/src/bridge/methods/createPostEvent.ts +40 -0
  220. package/src/bridge/methods/haptic.ts +52 -0
  221. package/src/bridge/methods/index.ts +6 -0
  222. package/src/bridge/methods/invoke-custom-method.ts +25 -0
  223. package/src/bridge/methods/methods.ts +372 -0
  224. package/src/bridge/methods/popup.ts +53 -0
  225. package/src/bridge/methods/postEvent.ts +101 -0
  226. package/src/bridge/request.ts +185 -0
  227. package/src/classnames/classNames.ts +34 -0
  228. package/src/classnames/index.ts +2 -0
  229. package/src/classnames/mergeClassNames.ts +68 -0
  230. package/src/{components/ClosingBehaviour/ClosingBehaviour.ts → closing-behavior/ClosingBehavior.ts} +12 -10
  231. package/src/closing-behavior/index.ts +2 -0
  232. package/src/closing-behavior/types.ts +12 -0
  233. package/src/{components/CloudStorage → cloud-storage}/CloudStorage.ts +50 -28
  234. package/src/colors/index.ts +5 -0
  235. package/src/colors/isColorDark.ts +22 -0
  236. package/src/colors/isRGB.ts +9 -0
  237. package/src/colors/isRGBShort.ts +9 -0
  238. package/src/colors/toRGB.ts +49 -0
  239. package/src/colors/types.ts +9 -0
  240. package/src/event-emitter/EventEmitter.ts +146 -0
  241. package/src/event-emitter/index.ts +2 -0
  242. package/src/event-emitter/types.ts +60 -0
  243. package/src/globals.ts +38 -0
  244. package/src/{components/HapticFeedback → haptic-feedback}/HapticFeedback.ts +16 -8
  245. package/src/index.ts +171 -6
  246. package/src/init/catchCustomStyles.ts +17 -0
  247. package/src/init/creators/createBackButton.ts +4 -6
  248. package/src/init/creators/createClosingBehavior.ts +6 -8
  249. package/src/init/creators/createMainButton.ts +13 -20
  250. package/src/init/creators/createMiniApp.ts +44 -0
  251. package/src/init/creators/createRequestIdGenerator.ts +1 -1
  252. package/src/init/creators/createThemeParams.ts +3 -6
  253. package/src/init/creators/createViewport.ts +92 -42
  254. package/src/init/creators/index.ts +1 -1
  255. package/src/init/css/bindMiniAppCSSVars.ts +48 -0
  256. package/src/init/css/bindThemeCSSVars.ts +31 -0
  257. package/src/init/css/bindViewportCSSVars.ts +36 -0
  258. package/src/init/css/index.ts +1 -0
  259. package/src/init/css/processCSSVarsOption.ts +57 -0
  260. package/src/init/css/setCSSVar.ts +8 -0
  261. package/src/init/init.ts +96 -138
  262. package/src/init/types.ts +42 -87
  263. package/src/init-data/InitData.ts +96 -0
  264. package/src/init-data/chatParser.ts +19 -0
  265. package/src/init-data/index.ts +6 -0
  266. package/src/init-data/initDataParser.ts +41 -0
  267. package/src/init-data/parseInitData.ts +10 -0
  268. package/src/init-data/types.ts +164 -0
  269. package/src/init-data/userParser.ts +45 -0
  270. package/src/invoice/Invoice.ts +123 -0
  271. package/src/invoice/index.ts +2 -0
  272. package/src/invoice/types.ts +11 -0
  273. package/src/launch-params/computeLaunchData.ts +81 -0
  274. package/src/launch-params/computePageReload.ts +13 -0
  275. package/src/launch-params/getFirstNavigationEntry.ts +10 -0
  276. package/src/launch-params/index.ts +12 -0
  277. package/src/launch-params/launchParamsParser.ts +41 -0
  278. package/src/launch-params/parseLaunchParams.ts +10 -0
  279. package/src/launch-params/retrieveCurrent.ts +27 -0
  280. package/src/launch-params/retrieveFromLocation.ts +10 -0
  281. package/src/launch-params/retrieveFromPerformance.ts +23 -0
  282. package/src/launch-params/retrieveLaunchData.ts +30 -0
  283. package/src/launch-params/serializeLaunchParams.ts +37 -0
  284. package/src/launch-params/storage.ts +33 -0
  285. package/src/launch-params/types.ts +57 -0
  286. package/src/logger/Logger.ts +72 -0
  287. package/src/logger/index.ts +1 -0
  288. package/src/main-button/MainButton.ts +239 -0
  289. package/src/main-button/index.ts +2 -0
  290. package/src/main-button/types.ts +26 -0
  291. package/src/mini-app/MiniApp.ts +237 -0
  292. package/src/mini-app/index.ts +2 -0
  293. package/src/mini-app/types.ts +25 -0
  294. package/src/misc/index.ts +2 -0
  295. package/src/misc/isRecord.ts +7 -0
  296. package/src/misc/isTMA.ts +13 -0
  297. package/src/navigation/HashNavigator/HashNavigator.ts +220 -0
  298. package/src/navigation/HashNavigator/drop.ts +36 -0
  299. package/src/navigation/HashNavigator/go.ts +28 -0
  300. package/src/navigation/HashNavigator/index.ts +2 -0
  301. package/src/navigation/HashNavigator/types.ts +41 -0
  302. package/src/navigation/Navigator/Navigator.ts +282 -0
  303. package/src/navigation/Navigator/index.ts +2 -0
  304. package/src/navigation/Navigator/types.ts +55 -0
  305. package/src/navigation/ensurePrefix.ts +9 -0
  306. package/src/navigation/getHash.ts +17 -0
  307. package/src/navigation/index.ts +4 -0
  308. package/src/parsing/ArrayValueParser.ts +79 -0
  309. package/src/parsing/ParseError.ts +27 -0
  310. package/src/parsing/ParseSchemaFieldError.ts +21 -0
  311. package/src/parsing/ValueParser.ts +71 -0
  312. package/src/parsing/createValueParserGenerator.ts +16 -0
  313. package/src/parsing/index.ts +10 -0
  314. package/src/parsing/parseBySchema.ts +65 -0
  315. package/src/parsing/parsers/array.ts +9 -0
  316. package/src/parsing/parsers/boolean.ts +22 -0
  317. package/src/parsing/parsers/date.ts +13 -0
  318. package/src/parsing/parsers/index.ts +8 -0
  319. package/src/parsing/parsers/json.ts +17 -0
  320. package/src/parsing/parsers/number.ts +21 -0
  321. package/src/parsing/parsers/rgb.ts +12 -0
  322. package/src/parsing/parsers/searchParams.ts +24 -0
  323. package/src/parsing/parsers/string.ts +12 -0
  324. package/src/parsing/toRecord.ts +27 -0
  325. package/src/parsing/types.ts +32 -0
  326. package/src/parsing/unexpectedTypeError.ts +6 -0
  327. package/src/{components/Popup → popup}/Popup.ts +38 -28
  328. package/src/popup/index.ts +2 -0
  329. package/src/{components/Popup/utils.ts → popup/preparePopupParams.ts} +3 -3
  330. package/src/{components/Popup → popup}/types.ts +4 -4
  331. package/src/{components/QRScanner → qr-scanner}/QRScanner.ts +18 -10
  332. package/src/qr-scanner/index.ts +2 -0
  333. package/src/{components/QRScanner → qr-scanner}/types.ts +1 -1
  334. package/src/state/State.ts +30 -16
  335. package/src/state/types.ts +5 -8
  336. package/src/storage.ts +6 -4
  337. package/src/supports/createSupportsFunc.ts +18 -0
  338. package/src/supports/createSupportsParamFunc.ts +27 -0
  339. package/src/supports/index.ts +4 -0
  340. package/src/supports/supports.ts +84 -0
  341. package/src/supports/types.ts +1 -0
  342. package/src/theme-params/ThemeParams.ts +131 -0
  343. package/src/theme-params/index.ts +6 -0
  344. package/src/theme-params/keys.ts +24 -0
  345. package/src/theme-params/parseThemeParams.ts +10 -0
  346. package/src/theme-params/requestThemeParams.ts +13 -0
  347. package/src/theme-params/serializeThemeParams.ts +20 -0
  348. package/src/theme-params/themeParamsParser.ts +20 -0
  349. package/src/theme-params/types.ts +33 -0
  350. package/src/timeout/TimeoutError.ts +6 -0
  351. package/src/timeout/index.ts +3 -0
  352. package/src/timeout/isTimeoutError.ts +9 -0
  353. package/src/timeout/withTimeout.ts +36 -0
  354. package/src/types/index.ts +3 -0
  355. package/src/types/platform.ts +14 -0
  356. package/src/types/request-id.ts +10 -0
  357. package/src/types/utils.ts +50 -0
  358. package/src/utils/Utils.ts +107 -0
  359. package/src/utils/index.ts +1 -0
  360. package/src/version/compareVersions.ts +28 -0
  361. package/src/version/index.ts +2 -0
  362. package/src/version/types.ts +4 -0
  363. package/src/{components/Viewport → viewport}/Viewport.ts +72 -98
  364. package/src/viewport/index.ts +3 -0
  365. package/src/viewport/requestViewport.ts +23 -0
  366. package/src/{components/Viewport → viewport}/types.ts +10 -1
  367. package/src/viewport/utils.ts +7 -0
  368. package/dist/dts/components/BackButton/index.d.ts +0 -2
  369. package/dist/dts/components/ClosingBehaviour/index.d.ts +0 -2
  370. package/dist/dts/components/ClosingBehaviour/types.d.ts +0 -7
  371. package/dist/dts/components/InitData/InitData.d.ts +0 -60
  372. package/dist/dts/components/InitData/index.d.ts +0 -1
  373. package/dist/dts/components/MainButton/MainButton.d.ts +0 -114
  374. package/dist/dts/components/MainButton/index.d.ts +0 -2
  375. package/dist/dts/components/MainButton/types.d.ts +0 -15
  376. package/dist/dts/components/Popup/index.d.ts +0 -2
  377. package/dist/dts/components/Popup/utils.d.ts +0 -7
  378. package/dist/dts/components/QRScanner/index.d.ts +0 -2
  379. package/dist/dts/components/ThemeParams/ThemeParams.d.ts +0 -73
  380. package/dist/dts/components/ThemeParams/index.d.ts +0 -2
  381. package/dist/dts/components/ThemeParams/types.d.ts +0 -9
  382. package/dist/dts/components/Viewport/index.d.ts +0 -2
  383. package/dist/dts/components/WebApp/WebApp.d.ts +0 -146
  384. package/dist/dts/components/WebApp/index.d.ts +0 -2
  385. package/dist/dts/components/WebApp/types.d.ts +0 -11
  386. package/dist/dts/components/index.d.ts +0 -11
  387. package/dist/dts/env.d.ts +0 -10
  388. package/dist/dts/errors/MethodNotSupportedError.d.ts +0 -6
  389. package/dist/dts/errors/ParameterNotSupportedError.d.ts +0 -6
  390. package/dist/dts/errors/index.d.ts +0 -2
  391. package/dist/dts/init/creators/createWebApp.d.ts +0 -16
  392. package/dist/dts/init/css.d.ts +0 -57
  393. package/dist/dts/supports.d.ts +0 -22
  394. package/dist/dts/types.d.ts +0 -10
  395. package/dist/dts/url.d.ts +0 -7
  396. package/src/components/BackButton/index.ts +0 -2
  397. package/src/components/ClosingBehaviour/index.ts +0 -6
  398. package/src/components/ClosingBehaviour/types.ts +0 -12
  399. package/src/components/InitData/InitData.ts +0 -139
  400. package/src/components/InitData/index.ts +0 -1
  401. package/src/components/MainButton/MainButton.ts +0 -242
  402. package/src/components/MainButton/index.ts +0 -2
  403. package/src/components/MainButton/types.ts +0 -20
  404. package/src/components/Popup/index.ts +0 -8
  405. package/src/components/QRScanner/index.ts +0 -2
  406. package/src/components/ThemeParams/ThemeParams.ts +0 -166
  407. package/src/components/ThemeParams/index.ts +0 -2
  408. package/src/components/ThemeParams/types.ts +0 -18
  409. package/src/components/Viewport/index.ts +0 -2
  410. package/src/components/WebApp/WebApp.ts +0 -311
  411. package/src/components/WebApp/index.ts +0 -2
  412. package/src/components/WebApp/types.ts +0 -17
  413. package/src/components/index.ts +0 -11
  414. package/src/env.ts +0 -22
  415. package/src/errors/MethodNotSupportedError.ts +0 -9
  416. package/src/errors/ParameterNotSupportedError.ts +0 -9
  417. package/src/errors/index.ts +0 -2
  418. package/src/init/creators/createWebApp.ts +0 -52
  419. package/src/init/css.ts +0 -166
  420. package/src/supports.ts +0 -44
  421. package/src/types.ts +0 -13
  422. package/src/url.ts +0 -23
  423. /package/dist/dts/{components/CloudStorage → cloud-storage}/index.d.ts +0 -0
  424. /package/dist/dts/{components/HapticFeedback → haptic-feedback}/index.d.ts +0 -0
  425. /package/src/{components/CloudStorage → cloud-storage}/index.ts +0 -0
  426. /package/src/{components/HapticFeedback → haptic-feedback}/index.ts +0 -0
package/dist/index.mjs CHANGED
@@ -1,852 +1,1739 @@
1
- var ot = Object.defineProperty;
2
- var nt = (s, t, e) => t in s ? ot(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
- var i = (s, t, e) => (nt(s, typeof t != "symbol" ? t + "" : t, e), e);
4
- import { retrieveLaunchData as z, parse as rt } from "@tma.js/launch-params";
5
- import { EventEmitter as w } from "@tma.js/event-emitter";
6
- import { supports as P, postEvent as g, on as E, off as W, request as f, setDebug as it, setTargetOrigin as at, createPostEvent as ct, isIframe as ht } from "@tma.js/bridge";
7
- import { array as ut, string as U, json as lt } from "@tma.js/parsing";
8
- import { parse as D } from "@tma.js/theme-params";
9
- import { isColorDark as K, isRGB as pt } from "@tma.js/colors";
10
- import { compareVersions as dt, withTimeout as gt } from "@tma.js/utils";
11
- function C(s, t) {
12
- return (e) => P(t[e], s);
13
- }
14
- function bt(s, t) {
15
- return (e) => {
16
- const [o, n] = t[e];
17
- return P(o, n, s);
18
- };
1
+ var $t = Object.defineProperty;
2
+ var Vt = (r, t, e) => t in r ? $t(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
+ var o = (r, t, e) => (Vt(r, typeof t != "symbol" ? t + "" : t, e), e);
4
+ function D(r) {
5
+ return typeof r == "object" && r !== null && !Array.isArray(r);
19
6
  }
20
- class m {
21
- constructor(t, e) {
22
- this.state = t, this.ee = e;
23
- }
24
- emit(t, e) {
25
- this.ee && this.ee.emit(t, e);
26
- }
27
- internalSet(t, e) {
28
- return this.state[t] === e ? !1 : (this.state[t] = e, this.emit(`${t}Changed`, e), !0);
7
+ function ct() {
8
+ return performance.getEntriesByType("navigation")[0] || null;
9
+ }
10
+ function Tt() {
11
+ const r = ct();
12
+ return r ? r.type === "reload" : null;
13
+ }
14
+ function L() {
15
+ return new TypeError("Value has unexpected type");
16
+ }
17
+ class G extends Error {
18
+ constructor(e, { cause: n, type: s } = {}) {
19
+ super(`Unable to parse value${s ? ` as ${s}` : ""}`, { cause: n });
20
+ /**
21
+ * Parser name.
22
+ */
23
+ o(this, "type");
24
+ this.value = e, Object.setPrototypeOf(this, G.prototype), this.type = s;
29
25
  }
30
- set(t, e) {
31
- let o = !1;
32
- if (typeof t == "string")
33
- o = this.internalSet(t, e);
34
- else
35
- for (const n in t)
36
- this.internalSet(n, t[n]) && (o = !0);
37
- o && this.emit("changed");
26
+ }
27
+ class F {
28
+ constructor(t, e, n) {
29
+ this.parser = t, this.isOptional = e, this.type = n;
30
+ }
31
+ parse(t) {
32
+ if (!(this.isOptional && t === void 0))
33
+ try {
34
+ return this.parser(t);
35
+ } catch (e) {
36
+ throw new G(t, { type: this.type, cause: e });
37
+ }
38
38
  }
39
- get(t) {
40
- return this.state[t];
39
+ optional() {
40
+ return this.isOptional = !0, this;
41
41
  }
42
42
  }
43
- class _t {
44
- constructor(t, e, o = g) {
45
- i(this, "ee", new w());
46
- i(this, "state");
47
- /**
48
- * Adds event listener.
49
- * @param event - event name.
50
- * @param listener - event listener.
51
- */
52
- i(this, "on", (t, e) => t === "click" ? E("back_button_pressed", e) : this.ee.on(t, e));
53
- /**
54
- * Removes event listener.
55
- * @param event - event name.
56
- * @param listener - event listener.
57
- */
58
- i(this, "off", (t, e) => {
59
- if (t === "click")
60
- return W("back_button_pressed", e);
61
- this.ee.off(t, e);
62
- });
63
- /**
64
- * Checks if specified method is supported by current component.
65
- */
66
- i(this, "supports");
67
- this.postEvent = o, this.state = new m({ isVisible: t }, this.ee), this.supports = C(e, {
68
- show: "web_app_setup_back_button",
69
- hide: "web_app_setup_back_button"
70
- });
43
+ function It(r) {
44
+ if (Array.isArray(r))
45
+ return r;
46
+ if (typeof r == "string")
47
+ try {
48
+ const t = JSON.parse(r);
49
+ if (Array.isArray(t))
50
+ return t;
51
+ } catch {
52
+ }
53
+ throw L();
54
+ }
55
+ class Rt extends F {
56
+ constructor(e, n, s) {
57
+ super(It, n, s);
58
+ o(this, "itemParser");
59
+ this.itemParser = typeof e == "function" ? e : e.parse.bind(e);
71
60
  }
72
- set isVisible(t) {
73
- this.state.set("isVisible", t), this.postEvent("web_app_setup_back_button", { is_visible: t });
61
+ parse(e) {
62
+ const n = super.parse(e);
63
+ return n === void 0 ? n : n.map(this.itemParser);
74
64
  }
75
- /**
76
- * True if BackButton is currently visible.
77
- */
78
- get isVisible() {
79
- return this.state.get("isVisible");
65
+ of(e) {
66
+ return this.itemParser = typeof e == "function" ? e : e.parse.bind(e), this;
80
67
  }
81
- /**
82
- * Hides the BackButton.
83
- */
84
- hide() {
85
- this.isVisible = !1;
68
+ }
69
+ function $(r, t) {
70
+ return () => new F(r, !1, t);
71
+ }
72
+ class U extends Error {
73
+ constructor(t, { cause: e, type: n } = {}) {
74
+ super(`Unable to parse field "${t}"${n ? ` as ${n}` : ""}`, { cause: e }), Object.setPrototypeOf(this, U.prototype);
86
75
  }
87
- /**
88
- * Shows the BackButton.
89
- */
90
- show() {
91
- this.isVisible = !0;
76
+ }
77
+ function ht(r, t) {
78
+ const e = {};
79
+ for (const n in r) {
80
+ const s = r[n];
81
+ if (!s)
82
+ continue;
83
+ let i, a;
84
+ if (typeof s == "function" || "parse" in s)
85
+ i = n, a = typeof s == "function" ? s : s.parse.bind(s);
86
+ else {
87
+ const { type: l } = s;
88
+ i = s.from || n, a = typeof l == "function" ? l : l.parse.bind(l);
89
+ }
90
+ let c;
91
+ const u = t(i);
92
+ try {
93
+ c = a(u);
94
+ } catch (l) {
95
+ throw l instanceof G ? new U(i, {
96
+ type: l.type,
97
+ cause: l
98
+ }) : new U(i, { cause: l });
99
+ }
100
+ c !== void 0 && (e[n] = c);
92
101
  }
102
+ return e;
93
103
  }
94
- class ft {
95
- constructor(t, e = g) {
96
- i(this, "ee", new w());
97
- i(this, "state");
98
- /**
99
- * Adds new event listener.
100
- */
101
- i(this, "on", this.ee.on.bind(this.ee));
102
- /**
103
- * Removes event listener.
104
- */
105
- i(this, "off", this.ee.off.bind(this.ee));
106
- this.postEvent = e, this.state = new m({ isConfirmationNeeded: t }, this.ee);
104
+ function Bt(r) {
105
+ return new Rt((t) => t, !1, r);
106
+ }
107
+ const C = $((r) => {
108
+ if (typeof r == "boolean")
109
+ return r;
110
+ const t = String(r);
111
+ if (t === "1" || t === "true")
112
+ return !0;
113
+ if (t === "0" || t === "false")
114
+ return !1;
115
+ throw L();
116
+ }, "boolean"), A = $((r) => {
117
+ if (typeof r == "number")
118
+ return r;
119
+ if (typeof r == "string") {
120
+ const t = Number(r);
121
+ if (!Number.isNaN(t))
122
+ return t;
123
+ }
124
+ throw L();
125
+ }, "number"), Dt = A(), Ht = $((r) => r instanceof Date ? r : new Date(Dt.parse(r) * 1e3), "Date");
126
+ function Z(r) {
127
+ let t = r;
128
+ if (typeof t == "string" && (t = JSON.parse(t)), typeof t != "object" || t === null || Array.isArray(t))
129
+ throw L();
130
+ return t;
131
+ }
132
+ function g(r, t) {
133
+ return new F((e) => {
134
+ const n = Z(e);
135
+ return ht(r, (s) => n[s]);
136
+ }, !1, t);
137
+ }
138
+ function ut(r) {
139
+ return /^#[\da-f]{6}$/i.test(r);
140
+ }
141
+ function Nt(r) {
142
+ return /^#[\da-f]{3}$/i.test(r);
143
+ }
144
+ function pt(r) {
145
+ const t = r.replace(/\s/g, "").toLowerCase();
146
+ if (ut(t))
147
+ return t;
148
+ if (Nt(t)) {
149
+ let n = "#";
150
+ for (let s = 0; s < 3; s += 1)
151
+ n += t[1 + s].repeat(2);
152
+ return n;
107
153
  }
108
- set isConfirmationNeeded(t) {
109
- this.state.set("isConfirmationNeeded", t), this.postEvent("web_app_setup_closing_behavior", { need_confirmation: t });
154
+ const e = 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}\)$/);
155
+ if (e === null)
156
+ throw new Error(`Value "${r}" does not satisfy any of known RGB formats.`);
157
+ return e.slice(1).reduce((n, s) => {
158
+ const i = parseInt(s, 10).toString(16);
159
+ return n + (i.length === 1 ? "0" : "") + i;
160
+ }, "#");
161
+ }
162
+ function lt(r) {
163
+ const t = pt(r);
164
+ return Math.sqrt(
165
+ [0.299, 0.587, 0.114].reduce((n, s, i) => {
166
+ const a = parseInt(t.slice(1 + i * 2, 1 + (i + 1) * 2), 16);
167
+ return n + a * a * s;
168
+ }, 0)
169
+ ) < 120;
170
+ }
171
+ const h = $((r) => {
172
+ if (typeof r == "string" || typeof r == "number")
173
+ return r.toString();
174
+ throw L();
175
+ }, "string"), Ot = h(), dt = $((r) => pt(Ot.parse(r)), "rgb");
176
+ function ft(r, t) {
177
+ return new F((e) => {
178
+ if (typeof e != "string" && !(e instanceof URLSearchParams))
179
+ throw L();
180
+ const n = typeof e == "string" ? new URLSearchParams(e) : e;
181
+ return ht(r, (s) => {
182
+ const i = n.get(s);
183
+ return i === null ? void 0 : i;
184
+ });
185
+ }, !1, t);
186
+ }
187
+ function Wt() {
188
+ return g({
189
+ id: A(),
190
+ type: h(),
191
+ title: h(),
192
+ photoUrl: {
193
+ type: h().optional(),
194
+ from: "photo_url"
195
+ },
196
+ username: h().optional()
197
+ }, "Chat");
198
+ }
199
+ class Mt {
200
+ constructor(t) {
201
+ this.initData = t;
110
202
  }
111
203
  /**
112
- * Returns true, if the confirmation dialog enabled while the user is trying
113
- * to close the Mini App.
204
+ * @see InitDataParsed.authDate
114
205
  */
115
- get isConfirmationNeeded() {
116
- return this.state.get("isConfirmationNeeded");
206
+ get authDate() {
207
+ return this.initData.authDate;
117
208
  }
118
209
  /**
119
- * Disables the confirmation dialog while the user is trying to close the
120
- * Mini App.
210
+ * @see InitDataParsed.canSendAfter
121
211
  */
122
- disableConfirmation() {
123
- this.isConfirmationNeeded = !1;
212
+ get canSendAfter() {
213
+ return this.initData.canSendAfter;
124
214
  }
125
215
  /**
126
- * Enables the confirmation dialog while the user is trying to close the
127
- * Mini App.
216
+ * Date after which it is allowed to call
217
+ * the [answerWebAppQuery](https://core.telegram.org/bots/api#answerwebappquery) method.
128
218
  */
129
- enableConfirmation() {
130
- this.isConfirmationNeeded = !0;
131
- }
132
- }
133
- const mt = ut().of(U());
134
- function L(s, t) {
135
- return s.reduce((e, o) => (e[o] = t, e), {});
136
- }
137
- class wt {
138
- constructor(t, e, o = g) {
139
- /**
140
- * Checks if specified method is supported by current component.
141
- */
142
- i(this, "supports");
143
- this.createRequestId = e, this.postEvent = o, this.supports = C(t, {
144
- deleteKeys: "web_app_invoke_custom_method",
145
- getKeys: "web_app_invoke_custom_method",
146
- getValues: "web_app_invoke_custom_method",
147
- saveValue: "web_app_invoke_custom_method"
148
- });
219
+ get canSendAfterDate() {
220
+ const { canSendAfter: t } = this;
221
+ return t === void 0 ? void 0 : new Date(this.authDate.getTime() + t * 1e3);
149
222
  }
150
223
  /**
151
- * Invokes custom method related to CloudStorage.
152
- * @param method - method name.
153
- * @param params - method parameters.
154
- * @param options - execution options.
224
+ * @see InitDataParsed.chat
155
225
  */
156
- async invokeCustomMethod(t, e, o = {}) {
157
- const { result: n, error: r } = await f(
158
- "web_app_invoke_custom_method",
159
- { method: t, params: e, req_id: this.createRequestId() },
160
- "custom_method_invoked",
161
- { ...o, postEvent: this.postEvent }
162
- );
163
- if (r)
164
- throw new Error(typeof r == "string" ? r : `Unknown error: ${JSON.stringify(r)}`);
165
- return n;
226
+ get chat() {
227
+ return this.initData.chat;
166
228
  }
167
229
  /**
168
- * Deletes specified keys from the CloudStorage.
169
- * @param keys - keys list.
170
- * @param options - request execution options.
230
+ * @see InitDataParsed.chatType
171
231
  */
172
- async deleteKeys(t, e) {
173
- t.length !== 0 && await this.invokeCustomMethod("deleteStorageValues", { keys: t }, e);
232
+ get chatType() {
233
+ return this.initData.chatType;
174
234
  }
175
235
  /**
176
- * Returns list of all keys presented in CloudStorage.
177
- * @param options - request execution options.
236
+ * @see InitDataParsed.chatInstance
178
237
  */
179
- async getKeys(t) {
180
- const e = await this.invokeCustomMethod("getStorageKeys", {}, t);
181
- return mt.parse(e);
238
+ get chatInstance() {
239
+ return this.initData.chatInstance;
182
240
  }
183
241
  /**
184
- * Returns map, where key is one of the specified in keys argument, and value is according
185
- * storage value.
186
- * @param keys - keys list.
187
- * @param options - request execution options.
242
+ * @see InitDataParsed.hash
188
243
  */
189
- async getValues(t, e) {
190
- if (t.length === 0)
191
- return L(t, "");
192
- const o = lt(
193
- L(t, U())
194
- // fixme
195
- ), n = await this.invokeCustomMethod("getStorageValues", { keys: t }, e);
196
- return o.parse(n);
244
+ get hash() {
245
+ return this.initData.hash;
197
246
  }
198
247
  /**
199
- * Saves specified value by key.
200
- * @param key - storage key.
201
- * @param value - storage value.
202
- * @param options - request execution options.
248
+ * @see InitDataParsed.queryId
203
249
  */
204
- async saveValue(t, e, o) {
205
- await this.invokeCustomMethod("saveStorageValue", { key: t, value: e }, o);
206
- }
207
- }
208
- class Ct {
209
- constructor(t, e = g) {
210
- /**
211
- * Checks if specified method is supported by current component.
212
- */
213
- i(this, "supports");
214
- this.postEvent = e, this.supports = C(t, {
215
- impactOccurred: "web_app_trigger_haptic_feedback",
216
- notificationOccurred: "web_app_trigger_haptic_feedback",
217
- selectionChanged: "web_app_trigger_haptic_feedback"
218
- });
250
+ get queryId() {
251
+ return this.initData.queryId;
219
252
  }
220
253
  /**
221
- * A method tells that an impact occurred. The Telegram app may play the
222
- * appropriate haptics based on style value passed.
223
- * @param style - impact style.
254
+ * @see InitDataParsed.receiver
224
255
  */
225
- impactOccurred(t) {
226
- this.postEvent("web_app_trigger_haptic_feedback", { type: "impact", impact_style: t });
256
+ get receiver() {
257
+ return this.initData.receiver;
227
258
  }
228
259
  /**
229
- * A method tells that a task or action has succeeded, failed, or produced
230
- * a warning. The Telegram app may play the appropriate haptics based on
231
- * type value passed.
232
- * @param type - notification type.
260
+ * @see InitDataParsed.startParam
233
261
  */
234
- notificationOccurred(t) {
235
- this.postEvent("web_app_trigger_haptic_feedback", {
236
- type: "notification",
237
- notification_type: t
238
- });
262
+ get startParam() {
263
+ return this.initData.startParam;
239
264
  }
240
265
  /**
241
- * A method tells that the user has changed a selection. The Telegram app
242
- * may play the appropriate haptics.
243
- *
244
- * Do not use this feedback when the user makes or confirms a selection;
245
- * use it only when the selection changes.
266
+ * @see InitDataParsed.user
246
267
  */
247
- selectionChanged() {
248
- this.postEvent("web_app_trigger_haptic_feedback", { type: "selection_change" });
268
+ get user() {
269
+ return this.initData.user;
249
270
  }
250
271
  }
251
- class vt {
252
- constructor(t, e, o = {}) {
253
- i(this, "state");
254
- const {
255
- chat: n = null,
256
- canSendAfter: r = null,
257
- chatType: a = null,
258
- chatInstance: h = null,
259
- user: c = null,
260
- queryId: l = null,
261
- receiver: u = null,
262
- startParam: p = null
263
- } = o;
264
- this.state = new m({
265
- authDate: t,
266
- canSendAfter: r === null ? null : new Date(t.getTime() + r * 1e3),
267
- chat: n,
268
- chatType: a,
269
- chatInstance: h,
270
- user: c,
271
- queryId: l,
272
- receiver: u,
273
- startParam: p,
274
- hash: e
272
+ function tt() {
273
+ return g({
274
+ addedToAttachmentMenu: {
275
+ type: C().optional(),
276
+ from: "added_to_attachment_menu"
277
+ },
278
+ allowsWriteToPm: {
279
+ type: C().optional(),
280
+ from: "allows_write_to_pm"
281
+ },
282
+ firstName: {
283
+ type: h(),
284
+ from: "first_name"
285
+ },
286
+ id: A(),
287
+ isBot: {
288
+ type: C().optional(),
289
+ from: "is_bot"
290
+ },
291
+ isPremium: {
292
+ type: C().optional(),
293
+ from: "is_premium"
294
+ },
295
+ languageCode: {
296
+ type: h().optional(),
297
+ from: "language_code"
298
+ },
299
+ lastName: {
300
+ type: h().optional(),
301
+ from: "last_name"
302
+ },
303
+ photoUrl: {
304
+ type: h().optional(),
305
+ from: "photo_url"
306
+ },
307
+ username: h().optional()
308
+ }, "User");
309
+ }
310
+ function gt() {
311
+ return ft({
312
+ authDate: {
313
+ type: Ht(),
314
+ from: "auth_date"
315
+ },
316
+ canSendAfter: {
317
+ type: A().optional(),
318
+ from: "can_send_after"
319
+ },
320
+ chat: Wt().optional(),
321
+ chatInstance: {
322
+ type: h().optional(),
323
+ from: "chat_instance"
324
+ },
325
+ chatType: {
326
+ type: h().optional(),
327
+ from: "chat_type"
328
+ },
329
+ hash: h(),
330
+ queryId: {
331
+ type: h().optional(),
332
+ from: "query_id"
333
+ },
334
+ receiver: tt().optional(),
335
+ startParam: {
336
+ type: h().optional(),
337
+ from: "start_param"
338
+ },
339
+ user: tt().optional()
340
+ }, "InitData");
341
+ }
342
+ function Xe(r) {
343
+ return gt().parse(r);
344
+ }
345
+ function Ut(r) {
346
+ return r.replace(/(^|_)bg/, (t, e) => `${e}background`).replace(/_([a-z])/g, (t, e) => e.toUpperCase());
347
+ }
348
+ function jt(r) {
349
+ return r.replace(/[A-Z]/g, (t) => `_${t.toLowerCase()}`).replace(/(^|_)background/, (t, e) => `${e}bg`);
350
+ }
351
+ const Gt = dt().optional(), wt = $(
352
+ (r) => Object.entries(Z(r)).reduce((t, [e, n]) => (t[Ut(e)] = Gt.parse(n), t), {}),
353
+ "ThemeParams"
354
+ );
355
+ function _t(r) {
356
+ return wt().parse(r);
357
+ }
358
+ function tr(r = {}) {
359
+ return _("web_app_request_theme", "theme_changed", r).then(_t);
360
+ }
361
+ function Ft(r) {
362
+ return JSON.stringify(
363
+ Object.entries(r).reduce((t, [e, n]) => (n && (t[jt(e)] = n), t), {})
364
+ );
365
+ }
366
+ class w {
367
+ constructor() {
368
+ o(this, "listeners", /* @__PURE__ */ new Map());
369
+ o(this, "subscribeListeners", []);
370
+ }
371
+ /**
372
+ * Adds specified event listener.
373
+ * @param event - event name.
374
+ * @param listener - event listener.
375
+ * @param once - should listener called only once.
376
+ */
377
+ addListener(t, e, n) {
378
+ let s = this.listeners.get(t);
379
+ return s || (s = [], this.listeners.set(t, s)), s.push([e, n]), () => this.off(t, e);
380
+ }
381
+ emit(t, ...e) {
382
+ this.subscribeListeners.forEach((s) => s(t, ...e));
383
+ const n = this.listeners.get(t);
384
+ n && n.forEach(([s, i], a) => {
385
+ s(...e), i && n.splice(a, 1);
275
386
  });
276
387
  }
277
388
  /**
278
- * Init data generation date.
389
+ * Adds event listener.
390
+ * @param event - event name.
391
+ * @param listener - event listener.
392
+ * @returns Function to remove event listener.
279
393
  */
280
- get authDate() {
281
- return this.state.get("authDate");
394
+ on(t, e) {
395
+ return this.addListener(t, e, !1);
282
396
  }
283
397
  /**
284
- * Date after which a message can be sent via the
285
- * [answerWebAppQuery](https://core.telegram.org/bots/api#answerwebappquery) method.
398
+ * Adds event listener following the logic, described in `on` method, but calls specified
399
+ * listener only once, removing it after.
400
+ * @param event - event name.
401
+ * @param listener - event listener.
402
+ * @returns Function to remove event listener.
403
+ * @see on
286
404
  */
287
- get canSendAfter() {
288
- return this.state.get("canSendAfter");
405
+ once(t, e) {
406
+ return this.addListener(t, e, !0);
289
407
  }
290
408
  /**
291
- * An object containing data about the chat where the bot was launched via the attachment
292
- * menu. Returned for supergroups, channels and group chats – only for Mini Apps launched via
293
- * the attachment menu.
409
+ * Removes event listener. In case, specified listener was bound several times, it removes
410
+ * only a single one.
411
+ * @param event - event name.
412
+ * @param listener - event listener.
294
413
  */
295
- get chat() {
296
- return this.state.get("chat");
414
+ off(t, e) {
415
+ const n = this.listeners.get(t);
416
+ if (n) {
417
+ for (let s = 0; s < n.length; s += 1)
418
+ if (e === n[s][0]) {
419
+ n.splice(s, 1);
420
+ return;
421
+ }
422
+ }
297
423
  }
298
424
  /**
299
- * The type of chat from which Mini App was opened.
425
+ * Adds event listener to all events.
426
+ * @param listener - events listener.
427
+ * @returns Function to remove event listener.
428
+ * @see on
429
+ * @see once
300
430
  */
301
- get chatType() {
302
- return this.state.get("chatType");
431
+ subscribe(t) {
432
+ return this.subscribeListeners.push(t), () => this.unsubscribe(t);
303
433
  }
304
434
  /**
305
- * A global identifier indicating the chat from which Mini App was opened. Returned only for
306
- * applications opened by direct link.
435
+ * Removes global event listener. In case, specified listener was bound several times, it removes
436
+ * only a single one.
437
+ * @param listener - events listener.
438
+ * @returns Function to remove event listener.
307
439
  */
308
- get chatInstance() {
309
- return this.state.get("chatInstance");
440
+ unsubscribe(t) {
441
+ for (let e = 0; e < this.subscribeListeners.length; e += 1)
442
+ if (this.subscribeListeners[e] === t) {
443
+ this.subscribeListeners.splice(e, 1);
444
+ return;
445
+ }
310
446
  }
311
- /**
312
- * A hash of all passed parameters, which the bot server can use to
313
- * check their validity.
314
- * @see https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app
315
- */
316
- get hash() {
317
- return this.state.get("hash");
447
+ }
448
+ class b {
449
+ constructor(t, e) {
450
+ this.state = t, this.ee = e;
318
451
  }
319
- /**
320
- * A unique identifier for the Mini App session, required for sending
321
- * messages via the `answerWebAppQuery` method.
322
- * @see https://core.telegram.org/bots/api#answerwebappquery
323
- */
324
- get queryId() {
325
- return this.state.get("queryId");
452
+ internalSet(t, e) {
453
+ return this.state[t] === e || e === void 0 ? !1 : (this.state[t] = e, this.ee.emit(`change:${t}`, e), !0);
326
454
  }
327
455
  /**
328
- * An object containing data about the chat partner of the current
329
- * user in the chat where the bot was launched via the attachment menu.
330
- * Returned only for private chats and only for Mini Apps launched
331
- * via the attachment menu.
456
+ * Returns copy of current state.
332
457
  */
333
- get receiver() {
334
- return this.state.get("receiver");
458
+ clone() {
459
+ return { ...this.state };
335
460
  }
336
- /**
337
- * The value of the `startattach` parameter, passed via link. Only
338
- * returned for Mini Apps when launched from the attachment menu via link.
339
- */
340
- get startParam() {
341
- return this.state.get("startParam");
461
+ set(t, e) {
462
+ let n = !1;
463
+ if (typeof t == "string")
464
+ n = this.internalSet(t, e);
465
+ else
466
+ for (const s in t)
467
+ this.internalSet(s, t[s]) && (n = !0);
468
+ n && this.ee.emit("change");
342
469
  }
343
470
  /**
344
- * An object containing data about the current user.
471
+ * Returns value by specified key.
472
+ * @param key - state key.
345
473
  */
346
- get user() {
347
- return this.state.get("user");
474
+ get(t) {
475
+ return this.state[t];
348
476
  }
349
477
  }
350
- class yt {
351
- constructor(t, e, o, n, r, a, h = g) {
352
- i(this, "ee", new w());
353
- i(this, "state");
478
+ class zt {
479
+ constructor(t) {
480
+ o(this, "ee", new w());
481
+ o(this, "state");
354
482
  /**
355
483
  * Adds new event listener.
356
- * FIXME: Event 'main_button_pressed' is still being received on Android
357
- * even if the main button is disabled.
358
- * Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/3
359
- * @param event - event name.
360
- * @param listener - event listener.
361
484
  */
362
- i(this, "on", (t, e) => t === "click" ? E("main_button_pressed", e) : this.ee.on(t, e));
485
+ o(this, "on", this.ee.on.bind(this.ee));
363
486
  /**
364
487
  * Removes event listener.
365
- * @param event - event name.
366
- * @param listener - event listener.
367
488
  */
368
- i(this, "off", (t, e) => {
369
- if (t === "click")
370
- return W("main_button_pressed", e);
371
- this.ee.off(t, e);
372
- });
373
- this.postEvent = h, this.state = new m({
374
- backgroundColor: t,
375
- isEnabled: e,
376
- isVisible: o,
377
- isProgressVisible: n,
378
- text: r,
379
- textColor: a
380
- }, this.ee);
381
- }
382
- set isEnabled(t) {
383
- this.state.set("isEnabled", t), this.commit();
489
+ o(this, "off", this.ee.off.bind(this.ee));
490
+ this.state = new b(t, this.ee);
384
491
  }
385
492
  /**
386
- * Returns true in case, MainButton is currently enabled.
493
+ * @since v6.10
387
494
  */
388
- get isEnabled() {
389
- return this.state.get("isEnabled");
495
+ get accentTextColor() {
496
+ return this.get("accentTextColor");
390
497
  }
391
- set isProgressVisible(t) {
392
- this.state.set("isProgressVisible", t), this.commit();
498
+ get backgroundColor() {
499
+ return this.get("backgroundColor");
393
500
  }
394
- /**
395
- * Returns true in case, MainButton loading progress is currently visible.
396
- */
397
- get isProgressVisible() {
398
- return this.state.get("isProgressVisible");
501
+ get buttonColor() {
502
+ return this.get("buttonColor");
399
503
  }
400
- set isVisible(t) {
401
- this.state.set("isVisible", t), this.commit();
504
+ get buttonTextColor() {
505
+ return this.get("buttonTextColor");
402
506
  }
403
- /**
404
- * Returns true in case, MainButton is currently visible.
405
- */
406
- get isVisible() {
407
- return this.state.get("isVisible");
507
+ get destructiveTextColor() {
508
+ return this.get("destructiveTextColor");
408
509
  }
409
510
  /**
410
- * Sends current local button state to Telegram application.
511
+ * Retrieves palette color value by its name.
512
+ * @param key - palette key name.
411
513
  */
412
- commit() {
413
- this.text !== "" && this.postEvent("web_app_setup_main_button", {
414
- is_visible: this.isVisible,
415
- is_active: this.isEnabled,
416
- is_progress_visible: this.isProgressVisible,
417
- text: this.text,
418
- color: this.backgroundColor,
419
- text_color: this.textColor
420
- });
514
+ get(t) {
515
+ return this.state.get(t);
421
516
  }
422
517
  /**
423
- * Returns current main button background color.
518
+ * Returns the copy of the internal state of the current component instance.
424
519
  */
425
- get backgroundColor() {
426
- return this.state.get("backgroundColor");
520
+ getState() {
521
+ return this.state.clone();
427
522
  }
428
523
  /**
429
- * Returns current main button text.
524
+ * @since v6.10
430
525
  */
431
- get text() {
432
- return this.state.get("text");
526
+ get headerBackgroundColor() {
527
+ return this.get("headerBackgroundColor");
433
528
  }
434
- /**
435
- * Returns current main button text color.
436
- */
437
- get textColor() {
438
- return this.state.get("textColor");
529
+ get hintColor() {
530
+ return this.get("hintColor");
439
531
  }
440
532
  /**
441
- * Disables button. Returns current button instance for chaining.
533
+ * Returns true in case, current color scheme is recognized as dark. This
534
+ * value is calculated according to theme background color.
442
535
  */
443
- disable() {
444
- return this.isEnabled = !1, this;
536
+ get isDark() {
537
+ return !this.backgroundColor || lt(this.backgroundColor);
445
538
  }
446
- /**
447
- * Enables button. Returns current button instance for chaining.
448
- */
449
- enable() {
450
- return this.isEnabled = !0, this;
539
+ get linkColor() {
540
+ return this.get("linkColor");
541
+ }
542
+ get secondaryBackgroundColor() {
543
+ return this.get("secondaryBackgroundColor");
451
544
  }
452
545
  /**
453
- * Hides button. Returns current button instance for chaining.
546
+ * @since v6.10
454
547
  */
455
- hide() {
456
- return this.isVisible = !1, this;
548
+ get sectionBackgroundColor() {
549
+ return this.get("sectionBackgroundColor");
457
550
  }
458
551
  /**
459
- * Hides button progress. Returns current button instance for chaining.
552
+ * @since v6.10
460
553
  */
461
- hideProgress() {
462
- return this.isProgressVisible = !1, this;
554
+ get sectionHeaderTextColor() {
555
+ return this.get("sectionHeaderTextColor");
463
556
  }
464
557
  /**
465
- * Shows the button. Note that opening the Mini App from the attachment
466
- * menu hides the main button until the user interacts with the Mini App
467
- * interface.
468
- *
469
- * Returns current button instance for chaining.
558
+ * Starts listening to theme changes and applies them.
559
+ * @returns Function to stop listening.
470
560
  */
471
- show() {
472
- return this.isVisible = !0, this;
561
+ listen() {
562
+ return k("theme_changed", (t) => {
563
+ this.state.set(_t(t.theme_params));
564
+ });
473
565
  }
474
566
  /**
475
- * A method to show a loading indicator on the button.
476
- * It is recommended to display loading progress if the action tied to the
477
- * button may take a long time.
478
- *
479
- * Returns current button instance for chaining.
567
+ * @since v6.10
480
568
  */
481
- showProgress() {
482
- return this.isProgressVisible = !0, this;
569
+ get subtitleTextColor() {
570
+ return this.get("subtitleTextColor");
571
+ }
572
+ get textColor() {
573
+ return this.get("textColor");
574
+ }
575
+ }
576
+ function bt() {
577
+ return ft({
578
+ botInline: {
579
+ type: C().optional(),
580
+ from: "tgWebAppBotInline"
581
+ },
582
+ initData: {
583
+ type: gt().optional(),
584
+ from: "tgWebAppData"
585
+ },
586
+ initDataRaw: {
587
+ type: h().optional(),
588
+ from: "tgWebAppData"
589
+ },
590
+ platform: {
591
+ type: h(),
592
+ from: "tgWebAppPlatform"
593
+ },
594
+ showSettings: {
595
+ type: C().optional(),
596
+ from: "tgWebAppShowSettings"
597
+ },
598
+ themeParams: {
599
+ type: wt(),
600
+ from: "tgWebAppThemeParams"
601
+ },
602
+ version: {
603
+ type: h(),
604
+ from: "tgWebAppVersion"
605
+ }
606
+ }, "LaunchParams");
607
+ }
608
+ function mt(r) {
609
+ return bt().parse(r);
610
+ }
611
+ function Jt() {
612
+ return mt(window.location.hash.slice(1));
613
+ }
614
+ function Qt() {
615
+ const r = ct();
616
+ if (!r)
617
+ throw new Error("Unable to get first navigation entry.");
618
+ const t = r.name.match(/#(.*)/);
619
+ if (!t)
620
+ throw new Error("First navigation entry does not contain hash part.");
621
+ return mt(t[1]);
622
+ }
623
+ function Zt() {
624
+ try {
625
+ return Qt();
626
+ } catch {
627
+ }
628
+ try {
629
+ return Jt();
630
+ } catch {
631
+ }
632
+ return null;
633
+ }
634
+ function Kt(r) {
635
+ const {
636
+ initDataRaw: t,
637
+ themeParams: e,
638
+ platform: n,
639
+ version: s,
640
+ showSettings: i,
641
+ botInline: a
642
+ } = r, c = new URLSearchParams();
643
+ return t && c.set("tgWebAppData", t), c.set("tgWebAppPlatform", n), c.set("tgWebAppThemeParams", Ft(e)), c.set("tgWebAppVersion", s), typeof i == "boolean" && c.set("tgWebAppShowSettings", i ? "1" : "0"), typeof a == "boolean" && c.set("tgWebAppBotInline", a ? "1" : "0"), c.toString();
644
+ }
645
+ const yt = "telegram-mini-apps-launch-params";
646
+ function Yt() {
647
+ const r = sessionStorage.getItem(yt);
648
+ return r ? bt().parse(r) : null;
649
+ }
650
+ function Xt(r) {
651
+ sessionStorage.setItem(yt, Kt(r));
652
+ }
653
+ function te() {
654
+ try {
655
+ return window.self !== window.top;
656
+ } catch {
657
+ return !0;
658
+ }
659
+ }
660
+ function ee() {
661
+ const r = Yt(), t = Zt(), e = Tt();
662
+ if (r) {
663
+ if (t)
664
+ return {
665
+ launchParams: t,
666
+ isPageReload: te() ? e || r.initDataRaw === t.initDataRaw : !0
667
+ };
668
+ if (e)
669
+ return {
670
+ launchParams: r,
671
+ isPageReload: e
672
+ };
673
+ throw new Error("Unable to retrieve current launch parameters, which must exist.");
674
+ }
675
+ if (t)
676
+ return {
677
+ launchParams: t,
678
+ isPageReload: !1
679
+ };
680
+ throw new Error("Unable to retrieve any launch parameters.");
681
+ }
682
+ const et = "tmajsLaunchData";
683
+ function Et() {
684
+ const r = window[et];
685
+ if (r)
686
+ return r;
687
+ const t = ee();
688
+ return window[et] = t, Xt(t.launchParams), t;
689
+ }
690
+ function er() {
691
+ try {
692
+ return Et(), !0;
693
+ } catch {
694
+ return !1;
695
+ }
696
+ }
697
+ function re(r) {
698
+ return "external" in r && D(r.external) && "notify" in r.external && typeof r.external.notify == "function";
699
+ }
700
+ function ne(r) {
701
+ return "TelegramWebviewProxy" in r && D(r.TelegramWebviewProxy) && "postEvent" in r.TelegramWebviewProxy && typeof r.TelegramWebviewProxy.postEvent == "function";
702
+ }
703
+ function Ct() {
704
+ try {
705
+ return window.self !== window.top;
706
+ } catch {
707
+ return !0;
708
+ }
709
+ }
710
+ class K extends Error {
711
+ constructor(t, e) {
712
+ super(`Method "${t}" is unsupported in the Mini Apps version ${e}.`), Object.setPrototypeOf(this, K.prototype);
713
+ }
714
+ }
715
+ class Y extends Error {
716
+ constructor(t, e, n) {
717
+ super(`Parameter "${e}" in method "${t}" is unsupported in the Mini Apps version ${n}.`), Object.setPrototypeOf(this, Y.prototype);
718
+ }
719
+ }
720
+ class vt {
721
+ constructor(t, e) {
722
+ this.prefix = t, this.enabled = e;
483
723
  }
484
724
  /**
485
- * Sets new main button text. Returns current button instance for chaining.
486
- * Minimal length for text is 1 symbol, and maximum is 64 symbols.
487
- *
488
- * Returns current button instance for chaining.
489
- * @param value - new text.
725
+ * Prints message into a console in case, logger is currently enabled.
726
+ * @param level - log level.
727
+ * @param args - arguments.
490
728
  */
491
- setText(t) {
492
- return this.state.set("text", t), this.commit(), this;
729
+ print(t, ...e) {
730
+ if (!this.enabled)
731
+ return;
732
+ const n = /* @__PURE__ */ new Date(), s = Intl.DateTimeFormat("en-GB", {
733
+ hour: "2-digit",
734
+ minute: "2-digit",
735
+ second: "2-digit",
736
+ fractionalSecondDigits: 3,
737
+ timeZone: "UTC"
738
+ }).format(n);
739
+ console[t](`[${s}]`, this.prefix, ...e);
493
740
  }
494
741
  /**
495
- * Sets new main button text color. Returns current button instance for
496
- * chaining.
497
- *
498
- * Returns current button instance for chaining.
499
- * @param value - new text color.
742
+ * Disables the logger.
500
743
  */
501
- setTextColor(t) {
502
- return this.state.set("textColor", t), this.commit(), this;
744
+ disable() {
745
+ this.enabled = !1;
503
746
  }
504
747
  /**
505
- * Updates current button color. Returns current button instance for
506
- * chaining.
507
- *
508
- * Returns current button instance for chaining.
509
- * @param value - color to set.
748
+ * Prints error message into a console.
749
+ * @param args
510
750
  */
511
- setBackgroundColor(t) {
512
- return this.state.set("backgroundColor", t), this.commit(), this;
751
+ error(...t) {
752
+ this.print("error", ...t);
753
+ }
754
+ /**
755
+ * Enables the logger.
756
+ */
757
+ enable() {
758
+ this.enabled = !0;
759
+ }
760
+ /**
761
+ * Prints log message into a console.
762
+ * @param args
763
+ */
764
+ log(...t) {
765
+ this.print("log", ...t);
766
+ }
767
+ /**
768
+ * Prints warning message into a console.
769
+ * @param args
770
+ */
771
+ warn(...t) {
772
+ this.print("warn", ...t);
513
773
  }
514
774
  }
515
- function kt(s) {
516
- const t = s.message.trim(), e = (s.title || "").trim(), o = s.buttons || [];
517
- let n;
518
- if (e.length > 64)
519
- throw new Error(`Title has incorrect size: ${e.length}`);
520
- if (t.length === 0 || t.length > 256)
521
- throw new Error(`Message has incorrect size: ${t.length}`);
522
- if (o.length > 3)
523
- throw new Error(`Buttons have incorrect size: ${o.length}`);
524
- return o.length === 0 ? n = [{ type: "close", id: "" }] : n = o.map((r) => {
525
- const { id: a = "" } = r;
526
- if (a.length > 64)
527
- throw new Error(`Button ID has incorrect size: ${a}`);
528
- if (r.type === void 0 || r.type === "default" || r.type === "destructive") {
529
- const h = r.text.trim();
530
- if (h.length === 0 || h.length > 64) {
531
- const c = r.type || "default";
532
- throw new Error(`Button text with type "${c}" has incorrect size: ${r.text.length}`);
775
+ let kt = "https://web.telegram.org";
776
+ const P = new vt("[SDK]", !1);
777
+ function rr(r) {
778
+ if (r) {
779
+ P.enable();
780
+ return;
781
+ }
782
+ P.disable();
783
+ }
784
+ function nr(r) {
785
+ kt = r;
786
+ }
787
+ function se() {
788
+ return kt;
789
+ }
790
+ const ie = g({
791
+ eventType: h(),
792
+ eventData: (r) => r
793
+ });
794
+ function oe(r, t) {
795
+ window.dispatchEvent(new MessageEvent("message", {
796
+ data: JSON.stringify({ eventType: r, eventData: t })
797
+ }));
798
+ }
799
+ function ae() {
800
+ const r = window;
801
+ "TelegramGameProxy_receiveEvent" in r || [
802
+ ["TelegramGameProxy_receiveEvent"],
803
+ // Windows Phone.
804
+ ["TelegramGameProxy", "receiveEvent"],
805
+ // Desktop.
806
+ ["Telegram", "WebView", "receiveEvent"]
807
+ // Android and iOS.
808
+ ].forEach((t) => {
809
+ let e = r;
810
+ t.forEach((n, s, i) => {
811
+ if (s === i.length - 1) {
812
+ e[n] = oe;
813
+ return;
533
814
  }
534
- return { ...r, text: h, id: a };
815
+ n in e || (e[n] = {}), e = e[n];
816
+ });
817
+ });
818
+ }
819
+ function ce(r) {
820
+ ae(), window.addEventListener("message", (t) => {
821
+ try {
822
+ const { eventType: e, eventData: n } = ie.parse(t.data);
823
+ r(e, n);
824
+ } catch {
535
825
  }
536
- return { ...r, id: a };
537
- }), { title: e, message: t, buttons: n };
826
+ });
827
+ }
828
+ function he() {
829
+ return g({
830
+ req_id: h(),
831
+ data: (r) => r === null ? r : h().optional().parse(r)
832
+ });
833
+ }
834
+ function ue() {
835
+ return g({
836
+ req_id: h(),
837
+ result: (r) => r,
838
+ error: h().optional()
839
+ });
840
+ }
841
+ function pe() {
842
+ return g({
843
+ slug: h(),
844
+ status: h()
845
+ });
846
+ }
847
+ function le() {
848
+ return g({ status: h() });
849
+ }
850
+ function de() {
851
+ return g({
852
+ button_id: (r) => r == null ? void 0 : h().parse(r)
853
+ });
854
+ }
855
+ function fe() {
856
+ return g({
857
+ data: h().optional()
858
+ });
859
+ }
860
+ function ge() {
861
+ return g({
862
+ theme_params: (r) => {
863
+ const t = dt().optional();
864
+ return Object.entries(Z(r)).reduce((e, [n, s]) => (e[n] = t.parse(s), e), {});
865
+ }
866
+ });
867
+ }
868
+ function we() {
869
+ return g({
870
+ height: A(),
871
+ width: (r) => r == null ? window.innerWidth : A().parse(r),
872
+ is_state_stable: C(),
873
+ is_expanded: C()
874
+ });
875
+ }
876
+ function _e() {
877
+ return g({ status: h() });
878
+ }
879
+ function be() {
880
+ const r = new w(), t = (e, ...n) => {
881
+ P.log("Emitting processed event:", e, ...n), r.emit(e, ...n);
882
+ };
883
+ return window.addEventListener("resize", () => {
884
+ t("viewport_changed", {
885
+ width: window.innerWidth,
886
+ height: window.innerHeight,
887
+ is_state_stable: !0,
888
+ is_expanded: !0
889
+ });
890
+ }), ce((e, n) => {
891
+ P.log("Received raw event:", e, n);
892
+ try {
893
+ switch (e) {
894
+ case "viewport_changed":
895
+ return t(e, we().parse(n));
896
+ case "theme_changed":
897
+ return t(e, ge().parse(n));
898
+ case "popup_closed":
899
+ return (
900
+ // Sent on desktop.
901
+ n == null ? t(e, {}) : t(e, de().parse(n))
902
+ );
903
+ case "set_custom_style":
904
+ return t(e, h().parse(n));
905
+ case "qr_text_received":
906
+ return t(e, fe().parse(n));
907
+ case "clipboard_text_received":
908
+ return t(e, he().parse(n));
909
+ case "invoice_closed":
910
+ return t(e, pe().parse(n));
911
+ case "phone_requested":
912
+ return t("phone_requested", le().parse(n));
913
+ case "custom_method_invoked":
914
+ return t("custom_method_invoked", ue().parse(n));
915
+ case "write_access_requested":
916
+ return t("write_access_requested", _e().parse(n));
917
+ case "main_button_pressed":
918
+ case "back_button_pressed":
919
+ case "settings_button_pressed":
920
+ case "scan_qr_popup_closed":
921
+ case "reload_iframe":
922
+ return t(e);
923
+ default:
924
+ return t(e, n);
925
+ }
926
+ } catch (s) {
927
+ P.error("Error processing event:", s);
928
+ }
929
+ }), r;
930
+ }
931
+ const z = "telegram-mini-apps-cached-emitter";
932
+ function H() {
933
+ const r = window;
934
+ return r[z] === void 0 && (r[z] = be()), r[z];
935
+ }
936
+ function N(r, t) {
937
+ H().off(r, t);
938
+ }
939
+ function k(r, t) {
940
+ return H().on(r, t), () => N(r, t);
941
+ }
942
+ function sr(r, t) {
943
+ return H().once(r, t), () => N(r, t);
944
+ }
945
+ function me(r) {
946
+ H().unsubscribe(r);
947
+ }
948
+ function ir(r) {
949
+ return H().subscribe(r), () => me(r);
950
+ }
951
+ function ye(r, t) {
952
+ const e = r.split("."), n = t.split("."), s = Math.max(e.length, n.length);
953
+ for (let i = 0; i < s; i += 1) {
954
+ const a = parseInt(e[i] || "0", 10), c = parseInt(n[i] || "0", 10);
955
+ if (a !== c)
956
+ return a > c ? 1 : -1;
957
+ }
958
+ return 0;
959
+ }
960
+ function E(r, t) {
961
+ return ye(r, t) <= 0;
962
+ }
963
+ function q(r, t, e) {
964
+ if (typeof e == "string") {
965
+ if (r === "web_app_open_link" && t === "try_instant_view")
966
+ return E("6.4", e);
967
+ if (r === "web_app_set_header_color" && t === "color")
968
+ return E("6.9", e);
969
+ }
970
+ switch (r) {
971
+ case "web_app_open_tg_link":
972
+ case "web_app_open_invoice":
973
+ case "web_app_setup_back_button":
974
+ case "web_app_set_background_color":
975
+ case "web_app_set_header_color":
976
+ case "web_app_trigger_haptic_feedback":
977
+ return E("6.1", t);
978
+ case "web_app_open_popup":
979
+ return E("6.2", t);
980
+ case "web_app_close_scan_qr_popup":
981
+ case "web_app_open_scan_qr_popup":
982
+ case "web_app_read_text_from_clipboard":
983
+ return E("6.4", t);
984
+ case "web_app_switch_inline_query":
985
+ return E("6.7", t);
986
+ case "web_app_invoke_custom_method":
987
+ case "web_app_request_write_access":
988
+ case "web_app_request_phone":
989
+ return E("6.9", t);
990
+ case "web_app_setup_settings_button":
991
+ return E("6.10", t);
992
+ default:
993
+ return !0;
994
+ }
995
+ }
996
+ function S(r, t) {
997
+ return (e) => q(t[e], r);
998
+ }
999
+ function St(r, t) {
1000
+ return (e) => {
1001
+ const [n, s] = t[e];
1002
+ return q(n, s, r);
1003
+ };
1004
+ }
1005
+ function f(r, t, e) {
1006
+ let n = {}, s;
1007
+ t === void 0 && e === void 0 ? n = {} : t !== void 0 && e !== void 0 ? (n = e, s = t) : t !== void 0 && ("targetOrigin" in t ? n = t : s = t);
1008
+ const { targetOrigin: i = se() } = n;
1009
+ if (P.log(`Calling method "${r}"`, s), Ct()) {
1010
+ window.parent.postMessage(JSON.stringify({
1011
+ eventType: r,
1012
+ eventData: s
1013
+ }), i);
1014
+ return;
1015
+ }
1016
+ if (re(window)) {
1017
+ window.external.notify(JSON.stringify({ eventType: r, eventData: s }));
1018
+ return;
1019
+ }
1020
+ if (ne(window)) {
1021
+ window.TelegramWebviewProxy.postEvent(r, JSON.stringify(s));
1022
+ return;
1023
+ }
1024
+ throw new Error(
1025
+ "Unable to determine current environment and possible way to send event."
1026
+ );
1027
+ }
1028
+ function Ee(r) {
1029
+ return (t, e) => {
1030
+ if (!q(t, r))
1031
+ throw new K(t, r);
1032
+ if (D(e)) {
1033
+ let n;
1034
+ if (t === "web_app_open_link" && "try_instant_view" in e ? n = "try_instant_view" : t === "web_app_set_header_color" && "color" in e && (n = "color"), n && !q(t, n, r))
1035
+ throw new Y(t, n, r);
1036
+ }
1037
+ return f(t, e);
1038
+ };
1039
+ }
1040
+ class X extends Error {
1041
+ constructor(t) {
1042
+ super(`Async call timeout exceeded. Timeout: ${t}`), Object.setPrototypeOf(this, X.prototype);
1043
+ }
1044
+ }
1045
+ function rt(r) {
1046
+ return new Promise((t, e) => {
1047
+ setTimeout(e, r, new X(r));
1048
+ });
1049
+ }
1050
+ function Ce(r, t) {
1051
+ return typeof r == "function" ? (...e) => Promise.race([
1052
+ r(...e),
1053
+ rt(t)
1054
+ ]) : Promise.race([r, rt(t)]);
1055
+ }
1056
+ function _(r, t, e, n) {
1057
+ let s, i, a, c;
1058
+ typeof t == "string" || Array.isArray(t) ? (a = Array.isArray(t) ? t : [t], s = e) : (i = t, a = Array.isArray(e) ? e : [e], s = n), D(i) && typeof i.req_id == "string" && (c = i.req_id);
1059
+ const { postEvent: u = f, timeout: l } = s || {}, p = s && "capture" in s ? s.capture : null, m = new Promise((d, y) => {
1060
+ const x = a.map((T) => k(T, (M) => {
1061
+ typeof c == "string" && (!D(M) || M.req_id !== c) || typeof p == "function" && !p(M) || (V(), d(M));
1062
+ })), V = () => x.forEach((T) => T());
1063
+ try {
1064
+ u(r, i);
1065
+ } catch (T) {
1066
+ V(), y(T);
1067
+ }
1068
+ });
1069
+ return typeof l == "number" ? Ce(m, l) : m;
1070
+ }
1071
+ class ve {
1072
+ constructor(t, e, n = f) {
1073
+ o(this, "ee", new w());
1074
+ o(this, "state");
1075
+ /**
1076
+ * Adds event listener.
1077
+ * @param event - event name.
1078
+ * @param listener - event listener.
1079
+ */
1080
+ o(this, "on", (t, e) => t === "click" ? k("back_button_pressed", e) : this.ee.on(t, e));
1081
+ /**
1082
+ * Removes event listener.
1083
+ * @param event - event name.
1084
+ * @param listener - event listener.
1085
+ */
1086
+ o(this, "off", (t, e) => t === "click" ? N("back_button_pressed", e) : this.ee.off(t, e));
1087
+ /**
1088
+ * Checks if specified method is supported by current component.
1089
+ */
1090
+ o(this, "supports");
1091
+ this.postEvent = n, this.state = new b({ isVisible: t }, this.ee), this.supports = S(e, {
1092
+ show: "web_app_setup_back_button",
1093
+ hide: "web_app_setup_back_button"
1094
+ });
1095
+ }
1096
+ set isVisible(t) {
1097
+ this.state.set("isVisible", t), this.postEvent("web_app_setup_back_button", { is_visible: t });
1098
+ }
1099
+ /**
1100
+ * True if BackButton is currently visible.
1101
+ */
1102
+ get isVisible() {
1103
+ return this.state.get("isVisible");
1104
+ }
1105
+ /**
1106
+ * Hides the BackButton.
1107
+ */
1108
+ hide() {
1109
+ this.isVisible = !1;
1110
+ }
1111
+ /**
1112
+ * Shows the BackButton.
1113
+ */
1114
+ show() {
1115
+ this.isVisible = !0;
1116
+ }
1117
+ }
1118
+ function nt(r, t) {
1119
+ return r + (r.length > 0 && t.length > 0 ? ` ${t}` : t);
1120
+ }
1121
+ function ke(...r) {
1122
+ return r.reduce((t, e) => {
1123
+ let n = "";
1124
+ return typeof e == "string" ? n = e : typeof e == "object" && e !== null && (n = Object.entries(e).reduce((s, [i, a]) => a ? nt(s, i) : s, "")), nt(t, n);
1125
+ }, "");
538
1126
  }
539
- class Et {
540
- constructor(t, e = g) {
541
- i(this, "ee", new w());
542
- i(this, "state");
1127
+ function Se(r) {
1128
+ return typeof r == "object" && r !== null && !Array.isArray(null);
1129
+ }
1130
+ function or(...r) {
1131
+ return r.reduce((t, e) => (Se(e) && Object.entries(e).forEach(([n, s]) => {
1132
+ const i = ke(t[n], s);
1133
+ i.length > 0 && (t[n] = i);
1134
+ }), t), {});
1135
+ }
1136
+ class xe {
1137
+ constructor(t, e = f) {
1138
+ o(this, "ee", new w());
1139
+ o(this, "state");
543
1140
  /**
544
1141
  * Adds new event listener.
545
1142
  */
546
- i(this, "on", this.ee.on.bind(this.ee));
1143
+ o(this, "on", this.ee.on.bind(this.ee));
547
1144
  /**
548
1145
  * Removes event listener.
549
1146
  */
550
- i(this, "off", this.ee.off.bind(this.ee));
1147
+ o(this, "off", this.ee.off.bind(this.ee));
1148
+ this.postEvent = e, this.state = new b({ isConfirmationNeeded: t }, this.ee);
1149
+ }
1150
+ set isConfirmationNeeded(t) {
1151
+ this.state.set("isConfirmationNeeded", t), this.postEvent("web_app_setup_closing_behavior", { need_confirmation: t });
1152
+ }
1153
+ /**
1154
+ * Returns true, if the confirmation dialog enabled while the user is trying
1155
+ * to close the Mini App.
1156
+ */
1157
+ get isConfirmationNeeded() {
1158
+ return this.state.get("isConfirmationNeeded");
1159
+ }
1160
+ /**
1161
+ * Disables the confirmation dialog while the user is trying to close the
1162
+ * Mini App.
1163
+ */
1164
+ disableConfirmation() {
1165
+ this.isConfirmationNeeded = !1;
1166
+ }
1167
+ /**
1168
+ * Enables the confirmation dialog while the user is trying to close the
1169
+ * Mini App.
1170
+ */
1171
+ enableConfirmation() {
1172
+ this.isConfirmationNeeded = !0;
1173
+ }
1174
+ }
1175
+ const Pe = Bt().of(h());
1176
+ function st(r, t) {
1177
+ return r.reduce((e, n) => (e[n] = t, e), {});
1178
+ }
1179
+ class Ae {
1180
+ constructor(t, e, n = f) {
1181
+ /**
1182
+ * Checks if specified method is supported by current component.
1183
+ */
1184
+ o(this, "supports");
1185
+ this.createRequestId = e, this.postEvent = n, this.supports = S(t, {
1186
+ delete: "web_app_invoke_custom_method",
1187
+ get: "web_app_invoke_custom_method",
1188
+ getKeys: "web_app_invoke_custom_method",
1189
+ set: "web_app_invoke_custom_method"
1190
+ });
1191
+ }
1192
+ /**
1193
+ * Invokes custom method related to CloudStorage.
1194
+ * @param method - method name.
1195
+ * @param params - method parameters.
1196
+ * @param options - execution options.
1197
+ */
1198
+ async invokeCustomMethod(t, e, n = {}) {
1199
+ const { result: s, error: i } = await _(
1200
+ "web_app_invoke_custom_method",
1201
+ { method: t, params: e, req_id: this.createRequestId() },
1202
+ "custom_method_invoked",
1203
+ { ...n, postEvent: this.postEvent }
1204
+ );
1205
+ if (i)
1206
+ throw new Error(i);
1207
+ return s;
1208
+ }
1209
+ /**
1210
+ * Deletes specified key or keys from the cloud storage.
1211
+ * @param keyOrKeys - key or keys to delete.
1212
+ * @param options - request execution options.
1213
+ */
1214
+ async delete(t, e) {
1215
+ const n = Array.isArray(t) ? t : [t];
1216
+ n.length !== 0 && await this.invokeCustomMethod("deleteStorageValues", { keys: n }, e);
1217
+ }
1218
+ /**
1219
+ * Returns list of all keys presented in the cloud storage.
1220
+ * @param options - request execution options.
1221
+ */
1222
+ async getKeys(t) {
1223
+ const e = await this.invokeCustomMethod("getStorageKeys", {}, t);
1224
+ return Pe.parse(e);
1225
+ }
1226
+ async get(t, e) {
1227
+ const n = Array.isArray(t) ? t : [t];
1228
+ if (n.length === 0)
1229
+ return st(n, "");
1230
+ const s = g(
1231
+ st(n, h())
1232
+ ), i = await this.invokeCustomMethod("getStorageValues", { keys: n }, e).then((a) => s.parse(a));
1233
+ return Array.isArray(t) ? i : i[t];
1234
+ }
1235
+ /**
1236
+ * Saves specified value by key.
1237
+ * @param key - storage key.
1238
+ * @param value - storage value.
1239
+ * @param options - request execution options.
1240
+ */
1241
+ async set(t, e, n) {
1242
+ await this.invokeCustomMethod("saveStorageValue", { key: t, value: e }, n);
1243
+ }
1244
+ }
1245
+ class qe {
1246
+ constructor(t, e = f) {
551
1247
  /**
552
1248
  * Checks if specified method is supported by current component.
553
1249
  */
554
- i(this, "supports");
555
- this.postEvent = e, this.state = new m({ isOpened: !1 }, this.ee), this.supports = C(t, { open: "web_app_open_popup" });
1250
+ o(this, "supports");
1251
+ this.postEvent = e, this.supports = S(t, {
1252
+ impactOccurred: "web_app_trigger_haptic_feedback",
1253
+ notificationOccurred: "web_app_trigger_haptic_feedback",
1254
+ selectionChanged: "web_app_trigger_haptic_feedback"
1255
+ });
1256
+ }
1257
+ /**
1258
+ * A method tells that an impact occurred. The Telegram app may play the
1259
+ * appropriate haptics based on style value passed.
1260
+ * @param style - impact style.
1261
+ */
1262
+ impactOccurred(t) {
1263
+ this.postEvent("web_app_trigger_haptic_feedback", {
1264
+ type: "impact",
1265
+ impact_style: t
1266
+ });
1267
+ }
1268
+ /**
1269
+ * A method tells that a task or action has succeeded, failed, or produced
1270
+ * a warning. The Telegram app may play the appropriate haptics based on
1271
+ * type value passed.
1272
+ * @param type - notification type.
1273
+ */
1274
+ notificationOccurred(t) {
1275
+ this.postEvent("web_app_trigger_haptic_feedback", {
1276
+ type: "notification",
1277
+ notification_type: t
1278
+ });
1279
+ }
1280
+ /**
1281
+ * A method tells that the user has changed a selection. The Telegram app
1282
+ * may play the appropriate haptics.
1283
+ *
1284
+ * Do not use this feedback when the user makes or confirms a selection;
1285
+ * use it only when the selection changes.
1286
+ */
1287
+ selectionChanged() {
1288
+ this.postEvent("web_app_trigger_haptic_feedback", { type: "selection_change" });
1289
+ }
1290
+ }
1291
+ function Le() {
1292
+ const r = document.createElement("style");
1293
+ r.id = "telegram-custom-styles", document.head.appendChild(r), k("set_custom_style", (t) => {
1294
+ r.innerHTML = t;
1295
+ });
1296
+ }
1297
+ function xt(r) {
1298
+ return `telegram-mini-apps-${r}`;
1299
+ }
1300
+ function O(r, t) {
1301
+ sessionStorage.setItem(xt(r), JSON.stringify(t));
1302
+ }
1303
+ function W(r) {
1304
+ const t = sessionStorage.getItem(xt(r));
1305
+ return t ? JSON.parse(t) : null;
1306
+ }
1307
+ function $e(r, t, e) {
1308
+ const { isVisible: n = !1 } = r ? W("back-button") || {} : {}, s = new ve(n, t, e);
1309
+ return s.on("change", () => {
1310
+ O("back-button", { isVisible: s.isVisible });
1311
+ }), s;
1312
+ }
1313
+ function Ve(r, t) {
1314
+ const { isConfirmationNeeded: e = !1 } = r ? W("closing-behavior") || {} : {}, n = new xe(e, t);
1315
+ return n.on("change", () => O("closing-behavior", {
1316
+ isConfirmationNeeded: n.isConfirmationNeeded
1317
+ })), n;
1318
+ }
1319
+ class Te {
1320
+ constructor(t) {
1321
+ o(this, "ee", new w());
1322
+ o(this, "state");
1323
+ o(this, "postEvent");
1324
+ /**
1325
+ * Adds new event listener.
1326
+ * @param event - event name.
1327
+ * @param listener - event listener.
1328
+ */
1329
+ o(this, "on", (t, e) => (
1330
+ // FIXME: Event 'main_button_pressed' is still being received on Android
1331
+ // even if the main button is disabled.
1332
+ // Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/3
1333
+ t === "click" ? k("main_button_pressed", e) : this.ee.on(t, e)
1334
+ ));
1335
+ /**
1336
+ * Removes event listener.
1337
+ * @param event - event name.
1338
+ * @param listener - event listener.
1339
+ */
1340
+ o(this, "off", (t, e) => t === "click" ? N("main_button_pressed", e) : this.ee.off(t, e));
1341
+ const {
1342
+ postEvent: e = f,
1343
+ text: n,
1344
+ textColor: s,
1345
+ backgroundColor: i,
1346
+ isEnabled: a,
1347
+ isVisible: c,
1348
+ isLoaderVisible: u
1349
+ } = t;
1350
+ this.postEvent = e, this.state = new b({
1351
+ backgroundColor: i,
1352
+ isEnabled: a,
1353
+ isVisible: c,
1354
+ isLoaderVisible: u,
1355
+ text: n,
1356
+ textColor: s
1357
+ }, this.ee);
1358
+ }
1359
+ /**
1360
+ * Sends current local state to Telegram application.
1361
+ */
1362
+ commit() {
1363
+ this.text !== "" && this.postEvent("web_app_setup_main_button", {
1364
+ is_visible: this.isVisible,
1365
+ is_active: this.isEnabled,
1366
+ is_progress_visible: this.isLoaderVisible,
1367
+ text: this.text,
1368
+ color: this.backgroundColor,
1369
+ text_color: this.textColor
1370
+ });
1371
+ }
1372
+ set isEnabled(t) {
1373
+ this.setParams({ isEnabled: t });
1374
+ }
1375
+ /**
1376
+ * True if the Main Button is currently enabled.
1377
+ */
1378
+ get isEnabled() {
1379
+ return this.state.get("isEnabled");
1380
+ }
1381
+ set isLoaderVisible(t) {
1382
+ this.setParams({ isLoaderVisible: t });
1383
+ }
1384
+ /**
1385
+ * True if the Main Button loader is currently visible.
1386
+ */
1387
+ get isLoaderVisible() {
1388
+ return this.state.get("isLoaderVisible");
1389
+ }
1390
+ set isVisible(t) {
1391
+ this.setParams({ isVisible: t });
1392
+ }
1393
+ /**
1394
+ * True if the Main Button is currently visible.
1395
+ */
1396
+ get isVisible() {
1397
+ return this.state.get("isVisible");
1398
+ }
1399
+ /**
1400
+ * The Main Button background color.
1401
+ */
1402
+ get backgroundColor() {
1403
+ return this.state.get("backgroundColor");
1404
+ }
1405
+ /**
1406
+ * The Main Button text.
1407
+ */
1408
+ get text() {
1409
+ return this.state.get("text");
1410
+ }
1411
+ /**
1412
+ * The Main Button text color.
1413
+ */
1414
+ get textColor() {
1415
+ return this.state.get("textColor");
556
1416
  }
557
1417
  /**
558
- * Shows whether popup is currently opened.
1418
+ * Disables the Main Button.
559
1419
  */
560
- get isOpened() {
561
- return this.state.get("isOpened");
1420
+ disable() {
1421
+ return this.isEnabled = !1, this;
562
1422
  }
563
1423
  /**
564
- * A method that shows a native popup described by the `params` argument.
565
- * Promise will be resolved when popup is closed. Resolved value will have
566
- * an identifier of pressed button.
567
- *
568
- * In case, user clicked outside the popup or clicked top right popup close
569
- * button, null will be returned.
570
- *
571
- * FIXME: In desktop, this function may work incorrectly.
572
- * Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/7
573
- * @param params - popup parameters.
574
- * @throws {Error} Popup is already opened.
1424
+ * Enables the Main Button.
575
1425
  */
576
- async open(t) {
577
- if (this.isOpened)
578
- throw new Error("Popup is already opened.");
579
- this.state.set("isOpened", !0);
580
- try {
581
- const { button_id: e = null } = await f(
582
- "web_app_open_popup",
583
- kt(t),
584
- "popup_closed",
585
- { postEvent: this.postEvent }
586
- );
587
- return e;
588
- } finally {
589
- this.state.set("isOpened", !1);
590
- }
1426
+ enable() {
1427
+ return this.isEnabled = !0, this;
591
1428
  }
592
- }
593
- class xt {
594
- constructor(t, e = g) {
595
- i(this, "ee", new w());
596
- i(this, "state");
597
- /**
598
- * Adds new event listener.
599
- */
600
- i(this, "on", this.ee.on.bind(this.ee));
601
- /**
602
- * Removes event listener.
603
- */
604
- i(this, "off", this.ee.off.bind(this.ee));
605
- /**
606
- * Checks if specified method is supported by current component.
607
- */
608
- i(this, "supports");
609
- this.postEvent = e, this.state = new m({ isOpened: !1 }, this.ee), this.supports = C(t, {
610
- close: "web_app_close_scan_qr_popup",
611
- open: "web_app_open_scan_qr_popup"
612
- });
1429
+ /**
1430
+ * Hides the Main Button.
1431
+ */
1432
+ hide() {
1433
+ return this.isVisible = !1, this;
613
1434
  }
614
1435
  /**
615
- * Closes scanner.
1436
+ * Hides the Main Button loader.
616
1437
  */
617
- close() {
618
- this.postEvent("web_app_close_scan_qr_popup"), this.isOpened = !1;
1438
+ hideLoader() {
1439
+ return this.isLoaderVisible = !1, this;
619
1440
  }
620
- set isOpened(t) {
621
- this.state.set("isOpened", t);
1441
+ /**
1442
+ * Shows the Main Button. Note that opening the Mini App from the attachment menu hides the
1443
+ * main button until the user interacts with the Mini App interface.
1444
+ */
1445
+ show() {
1446
+ return this.isVisible = !0, this;
622
1447
  }
623
1448
  /**
624
- * Returns true in case, QR scanner is currently opened.
1449
+ * A method to show a loading indicator on the Main Button. It is recommended to display
1450
+ * loader if the action tied to the button may take a long time.
625
1451
  */
626
- get isOpened() {
627
- return this.state.get("isOpened");
1452
+ showLoader() {
1453
+ return this.isLoaderVisible = !0, this;
628
1454
  }
629
1455
  /**
630
- * Opens scanner with specified title shown to user. Method returns promise
631
- * with scanned QR content in case, it was scanned. It will contain null in
632
- * case, scanner was closed.
633
- * @param text - title to display.
1456
+ * Sets new Main Button text. Minimal length for text is 1 symbol, and maximum is 64 symbols.
1457
+ * @param text - new text.
634
1458
  */
635
- async open(t) {
636
- if (this.isOpened)
637
- throw new Error("QR scanner is already opened.");
638
- this.isOpened = !0;
639
- try {
640
- const e = await f(
641
- "web_app_open_scan_qr_popup",
642
- { text: t },
643
- ["qr_text_received", "scan_qr_popup_closed"],
644
- { postEvent: this.postEvent }
645
- );
646
- return typeof e == "object" && typeof e.data == "string" ? e.data : null;
647
- } finally {
648
- this.isOpened = !1;
649
- }
1459
+ setText(t) {
1460
+ return this.setParams({ text: t });
1461
+ }
1462
+ /**
1463
+ * Sets new Main Button text color.
1464
+ * @param textColor - new text color.
1465
+ */
1466
+ setTextColor(t) {
1467
+ return this.setParams({ textColor: t });
1468
+ }
1469
+ /**
1470
+ * Updates current Main Button color.
1471
+ * @param backgroundColor - color to set.
1472
+ */
1473
+ setBackgroundColor(t) {
1474
+ return this.setParams({ backgroundColor: t });
1475
+ }
1476
+ /**
1477
+ * Allows setting multiple Main Button parameters.
1478
+ * @param params - Main Button parameters.
1479
+ */
1480
+ setParams(t) {
1481
+ return this.state.set(t), this.commit(), this;
650
1482
  }
651
1483
  }
652
- function M(s) {
1484
+ function Ie(r, t, e, n) {
653
1485
  const {
654
- accentTextColor: t = null,
655
- backgroundColor: e = null,
656
- buttonColor: o = null,
657
- buttonTextColor: n = null,
658
- destructiveTextColor: r = null,
659
- headerBackgroundColor: a = null,
660
- hintColor: h = null,
661
- linkColor: c = null,
662
- secondaryBackgroundColor: l = null,
663
- sectionBackgroundColor: u = null,
664
- sectionHeaderTextColor: p = null,
665
- subtitleTextColor: b = null,
666
- textColor: S = null
667
- } = s;
668
- return {
669
- accentTextColor: t,
670
- backgroundColor: e,
671
- buttonColor: o,
672
- buttonTextColor: n,
673
- destructiveTextColor: r,
674
- headerBackgroundColor: a,
675
- hintColor: h,
676
- linkColor: c,
677
- secondaryBackgroundColor: l,
678
- sectionBackgroundColor: u,
679
- sectionHeaderTextColor: p,
680
- subtitleTextColor: b,
681
- textColor: S
682
- };
1486
+ backgroundColor: s = t,
1487
+ isEnabled: i = !1,
1488
+ isVisible: a = !1,
1489
+ isLoaderVisible: c = !1,
1490
+ textColor: u = e,
1491
+ text: l = ""
1492
+ } = r ? W("main-button") || {} : {}, p = new Te({
1493
+ backgroundColor: s,
1494
+ isEnabled: i,
1495
+ isLoaderVisible: c,
1496
+ isVisible: a,
1497
+ postEvent: n,
1498
+ text: l,
1499
+ textColor: u
1500
+ }), m = () => O("main-button", {
1501
+ backgroundColor: p.backgroundColor,
1502
+ isEnabled: p.isEnabled,
1503
+ isLoaderVisible: p.isLoaderVisible,
1504
+ isVisible: p.isVisible,
1505
+ text: p.text,
1506
+ textColor: p.textColor
1507
+ });
1508
+ return p.on("change", m), p;
683
1509
  }
684
- class q {
1510
+ class Re {
685
1511
  constructor(t) {
686
- i(this, "ee", new w());
687
- i(this, "state");
1512
+ o(this, "ee", new w());
1513
+ o(this, "state");
1514
+ o(this, "botInline");
1515
+ o(this, "postEvent");
688
1516
  /**
689
1517
  * Adds new event listener.
690
1518
  */
691
- i(this, "on", this.ee.on.bind(this.ee));
1519
+ o(this, "on", this.ee.on.bind(this.ee));
692
1520
  /**
693
1521
  * Removes event listener.
694
1522
  */
695
- i(this, "off", this.ee.off.bind(this.ee));
696
- this.state = new m(M(t), this.ee);
1523
+ o(this, "off", this.ee.off.bind(this.ee));
1524
+ /**
1525
+ * Checks if specified method is supported by current component.
1526
+ */
1527
+ o(this, "supports");
1528
+ /**
1529
+ * Checks if specified method parameter is supported by current component.
1530
+ */
1531
+ o(this, "supportsParam");
1532
+ const {
1533
+ postEvent: e = f,
1534
+ headerColor: n,
1535
+ backgroundColor: s,
1536
+ version: i,
1537
+ botInline: a
1538
+ } = t, c = S(i, {
1539
+ requestPhoneAccess: "web_app_request_phone",
1540
+ requestWriteAccess: "web_app_request_write_access",
1541
+ switchInlineQuery: "web_app_switch_inline_query",
1542
+ setHeaderColor: "web_app_set_header_color",
1543
+ setBackgroundColor: "web_app_set_background_color"
1544
+ });
1545
+ this.postEvent = e, this.botInline = a, this.supports = (u) => !(!c(u) || u === "switchInlineQuery" && !a), this.state = new b({ backgroundColor: s, headerColor: n }, this.ee), this.supportsParam = St(i, {
1546
+ "setHeaderColor.color": ["web_app_set_header_color", "color"]
1547
+ });
697
1548
  }
698
1549
  /**
699
- * Requests fresh information about current theme.
700
- * FIXME: Be careful using this function in desktop version of Telegram as
701
- * long as method web_app_request_theme does not work on `macos` platform.
702
- * @param options - method options.
1550
+ * The Mini App background color.
703
1551
  */
704
- static async request(t = {}) {
705
- const { timeout: e = 1e3, ...o } = t, n = await f("web_app_request_theme", "theme_changed", {
706
- ...o,
707
- timeout: e
708
- });
709
- return D(n.theme_params);
1552
+ get backgroundColor() {
1553
+ return this.state.get("backgroundColor");
710
1554
  }
711
1555
  /**
712
- * Synchronizes specified instance of ThemeParams with the actual value in the native
713
- * application.
714
- * @param themeParams - ThemeParams instance.
1556
+ * Closes the Mini App.
715
1557
  */
716
- static sync(t) {
717
- E("theme_changed", (e) => {
718
- t.state.set(M(D(e.theme_params)));
719
- });
1558
+ close() {
1559
+ this.postEvent("web_app_close");
720
1560
  }
721
1561
  /**
722
- * Returns instance of ThemeParams which is synchronized with external
723
- * environment.
724
- * @param options - method options.
1562
+ * The Mini App header color. Could either be a header color key or RGB color.
725
1563
  */
726
- static async synced(t) {
727
- const e = await this.request(t), o = new q(e);
728
- return this.sync(o), o;
1564
+ get headerColor() {
1565
+ return this.state.get("headerColor");
729
1566
  }
730
1567
  /**
731
- * Returns background color.
1568
+ * True if Mini App is currently launched in bot inline mode.
732
1569
  */
733
- get backgroundColor() {
734
- return this.state.get("backgroundColor");
1570
+ get isBotInline() {
1571
+ return this.botInline;
735
1572
  }
736
1573
  /**
737
- * Returns button color.
1574
+ * True if current Mini App background color recognized as dark.
738
1575
  */
739
- get buttonColor() {
740
- return this.state.get("buttonColor");
1576
+ get isDark() {
1577
+ return lt(this.backgroundColor);
741
1578
  }
742
1579
  /**
743
- * Returns button text color.
1580
+ * Informs the Telegram app that the Mini App is ready to be displayed.
1581
+ *
1582
+ * It is recommended to call this method as early as possible, as soon as all essential
1583
+ * interface elements loaded. Once this method called, the loading placeholder is hidden
1584
+ * and the Mini App shown.
1585
+ *
1586
+ * If the method not called, the placeholder will be hidden only when the page fully loaded.
744
1587
  */
745
- get buttonTextColor() {
746
- return this.state.get("buttonTextColor");
1588
+ ready() {
1589
+ this.postEvent("web_app_ready");
747
1590
  }
748
1591
  /**
749
- * Returns hint color.
1592
+ * Requests current user phone access.
750
1593
  */
751
- get hintColor() {
752
- return this.state.get("hintColor");
1594
+ requestPhoneAccess() {
1595
+ return _(
1596
+ "web_app_request_phone",
1597
+ "phone_requested",
1598
+ { postEvent: this.postEvent }
1599
+ ).then((t) => t.status);
753
1600
  }
754
1601
  /**
755
- * Returns true in case, current color scheme is recognized as dark. This
756
- * value is calculated according to theme background color.
1602
+ * Requests write message access to current user.
757
1603
  */
758
- get isDark() {
759
- return this.backgroundColor === null || K(this.backgroundColor);
1604
+ requestWriteAccess() {
1605
+ return _(
1606
+ "web_app_request_write_access",
1607
+ "write_access_requested",
1608
+ { postEvent: this.postEvent }
1609
+ ).then((t) => t.status);
760
1610
  }
761
1611
  /**
762
- * Returns current link color.
1612
+ * A method used to send data to the bot. When this method called, a service message sent to
1613
+ * the bot containing the data of the length up to 4096 bytes, and the Mini App closed. See the
1614
+ * field `web_app_data` in the class [Message](https://core.telegram.org/bots/api#message).
1615
+ *
1616
+ * This method is only available for Mini Apps launched via a Keyboard button.
1617
+ * @param data - data to send to bot.
1618
+ * @throws {Error} data has incorrect size.
763
1619
  */
764
- get linkColor() {
765
- return this.state.get("linkColor");
1620
+ sendData(t) {
1621
+ const { size: e } = new Blob([t]);
1622
+ if (e === 0 || e > 4096)
1623
+ throw new Error(`Passed data has incorrect size: ${e}`);
1624
+ this.postEvent("web_app_data_send", { data: t });
766
1625
  }
767
1626
  /**
768
- * Returns secondary background color.
1627
+ * Updates current Mini App header color.
1628
+ * @param color - color key or RGB color.
769
1629
  */
770
- get secondaryBackgroundColor() {
771
- return this.state.get("secondaryBackgroundColor");
1630
+ setHeaderColor(t) {
1631
+ this.postEvent("web_app_set_header_color", ut(t) ? { color: t } : { color_key: t }), this.state.set("headerColor", t);
772
1632
  }
773
1633
  /**
774
- * Returns text color.
1634
+ * Updates current Mini App background color.
1635
+ * @param color - RGB color.
775
1636
  */
776
- get textColor() {
777
- return this.state.get("textColor");
1637
+ setBackgroundColor(t) {
1638
+ this.postEvent("web_app_set_background_color", { color: t }), this.state.set("backgroundColor", t);
1639
+ }
1640
+ /**
1641
+ * Inserts the bot's username and the specified inline query in the current chat's input field.
1642
+ * Query may be empty, in which case only the bot's username will be inserted. The client prompts
1643
+ * the user to choose a specific chat, then opens that chat and inserts the bot's username and
1644
+ * the specified inline query in the input field.
1645
+ * @param text - text which should be inserted in the input after the current bot name. Max
1646
+ * length is 256 symbols.
1647
+ * @param chatTypes - List of chat types which could be chosen to send the message. Could be
1648
+ * empty list.
1649
+ */
1650
+ switchInlineQuery(t, e = []) {
1651
+ if (!this.supports("switchInlineQuery") && !this.isBotInline)
1652
+ throw new Error("Method is unsupported because Mini App should be launched in inline mode.");
1653
+ this.postEvent("web_app_switch_inline_query", {
1654
+ query: t,
1655
+ chat_types: e
1656
+ });
778
1657
  }
779
1658
  }
780
- function y(s) {
781
- return s < 0 ? 0 : s;
1659
+ function Be(r, t, e, n, s) {
1660
+ const {
1661
+ backgroundColor: i = t,
1662
+ headerColor: a = "bg_color"
1663
+ } = r ? W("mini-app") || {} : {}, c = new Re({
1664
+ headerColor: a,
1665
+ backgroundColor: i,
1666
+ version: e,
1667
+ botInline: n,
1668
+ postEvent: s
1669
+ }), u = () => O("mini-app", {
1670
+ backgroundColor: c.backgroundColor,
1671
+ headerColor: c.headerColor
1672
+ });
1673
+ return c.on("change", u), c;
1674
+ }
1675
+ function De() {
1676
+ let r = 0;
1677
+ return () => (r += 1, r.toString());
1678
+ }
1679
+ function He(r) {
1680
+ const t = new zt(r);
1681
+ return t.listen(), t;
1682
+ }
1683
+ async function Pt(r) {
1684
+ const t = await _("web_app_request_viewport", "viewport_changed", r);
1685
+ return {
1686
+ height: t.height,
1687
+ width: t.width,
1688
+ isExpanded: t.is_expanded,
1689
+ isStateStable: t.is_state_stable
1690
+ };
1691
+ }
1692
+ function I(r) {
1693
+ return r < 0 ? 0 : r;
782
1694
  }
783
- class k {
784
- constructor(t, e, o, n, r = g) {
785
- i(this, "ee", new w());
786
- i(this, "state");
1695
+ class j {
1696
+ constructor(t) {
1697
+ o(this, "ee", new w());
1698
+ o(this, "state");
1699
+ o(this, "postEvent");
787
1700
  /**
788
1701
  * Adds new event listener.
789
1702
  */
790
- i(this, "on", this.ee.on.bind(this.ee));
1703
+ o(this, "on", this.ee.on.bind(this.ee));
791
1704
  /**
792
1705
  * Removes event listener.
793
1706
  */
794
- i(this, "off", this.ee.off.bind(this.ee));
795
- this.postEvent = r, this.state = new m({
796
- height: y(t),
1707
+ o(this, "off", this.ee.off.bind(this.ee));
1708
+ const {
1709
+ height: e,
797
1710
  isExpanded: n,
798
- stableHeight: y(o),
799
- width: y(e)
1711
+ width: s,
1712
+ stableHeight: i,
1713
+ postEvent: a = f
1714
+ } = t;
1715
+ this.postEvent = a, this.state = new b({
1716
+ height: I(e),
1717
+ isExpanded: n,
1718
+ stableHeight: I(i),
1719
+ width: I(s)
800
1720
  }, this.ee);
801
1721
  }
802
1722
  /**
803
- * Requests fresh information about current viewport.
804
- * FIXME: Be careful using this function in desktop version of Telegram as
805
- * long as method web_app_request_viewport does not work on `macos` platform.
806
- * @see Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/5
807
- * @param options - method options.
808
- */
809
- static async request(t = {}) {
810
- const { timeout: e = 1e3, ...o } = t, {
811
- is_expanded: n,
812
- is_state_stable: r,
813
- ...a
814
- } = await f("web_app_request_viewport", "viewport_changed", {
815
- ...o,
816
- timeout: e
817
- });
818
- return { ...a, isExpanded: n, isStateStable: r };
819
- }
820
- /**
821
- * Synchronizes specified instance of Viewport with the actual value in the native
822
- * application.
823
- * @param viewport - Viewport instance.
1723
+ * Request viewport information from the Telegram application and updates current Viewport
1724
+ * instance.
1725
+ * @param options - options to request fresh data.
824
1726
  */
825
- static sync(t) {
826
- E("viewport_changed", (e) => {
827
- const {
828
- height: o,
829
- width: n,
830
- is_expanded: r,
831
- is_state_stable: a
832
- } = e, h = y(o);
833
- t.state.set({
834
- height: h,
835
- isExpanded: r,
836
- width: y(n),
837
- stableHeight: a ? h : void 0
1727
+ sync(t) {
1728
+ return Pt(t).then(({ height: e, isExpanded: n, width: s, isStateStable: i }) => {
1729
+ this.state.set({
1730
+ height: e,
1731
+ width: s,
1732
+ isExpanded: n,
1733
+ stableHeight: i ? e : this.state.get("stableHeight")
838
1734
  });
839
1735
  });
840
1736
  }
841
- /**
842
- * Returns initialized instance of Viewport which is synchronized with
843
- * its actual state in Mini Apps.
844
- * @param options - method options.
845
- */
846
- static async synced(t = {}) {
847
- const { height: e, isExpanded: o, width: n } = await this.request(t), r = new k(e, n, e, o, t.postEvent);
848
- return this.sync(r), r;
849
- }
850
1737
  /**
851
1738
  * The current height of the visible area of the Mini App.
852
1739
  *
@@ -862,10 +1749,6 @@ class k {
862
1749
  * used to pin interface elements to the bottom of the visible area. It's
863
1750
  * more appropriate to use the value of the `stableHeight`
864
1751
  * field for this purpose.
865
- *
866
- * @see init
867
- * @see expand
868
- * @see stableHeight
869
1752
  */
870
1753
  get height() {
871
1754
  return this.state.get("height");
@@ -883,14 +1766,29 @@ class k {
883
1766
  * gestures or during animations. The value of `stableHeight`
884
1767
  * will be updated after all gestures and animations are completed and
885
1768
  * the Mini App reaches its final size.
886
- *
887
- * @see init
888
- * @see expand
889
- * @see height
890
1769
  */
891
1770
  get stableHeight() {
892
1771
  return this.state.get("stableHeight");
893
1772
  }
1773
+ /**
1774
+ * Starts listening to viewport changes and applies them.
1775
+ * @returns Function to stop listening.
1776
+ */
1777
+ listen() {
1778
+ return k("viewport_changed", (t) => {
1779
+ const {
1780
+ height: e,
1781
+ width: n,
1782
+ is_expanded: s,
1783
+ is_state_stable: i
1784
+ } = t, a = {
1785
+ height: I(e),
1786
+ isExpanded: s,
1787
+ width: I(n)
1788
+ };
1789
+ i && (a.stableHeight = a.height), this.state.set(a);
1790
+ });
1791
+ }
894
1792
  /**
895
1793
  * Returns true if the Mini App is expanded to the maximum available height.
896
1794
  * Otherwise, if the Mini App occupies part of the screen and can be expanded
@@ -900,104 +1798,323 @@ class k {
900
1798
  get isExpanded() {
901
1799
  return this.state.get("isExpanded");
902
1800
  }
903
- /**
904
- * Current viewport width.
905
- */
906
- get width() {
907
- return this.state.get("width");
1801
+ /**
1802
+ * Current viewport width.
1803
+ */
1804
+ get width() {
1805
+ return this.state.get("width");
1806
+ }
1807
+ /**
1808
+ * A method that expands the Mini App to the maximum available height. To
1809
+ * find out if the Mini App is expanded to the maximum height, refer to the
1810
+ * value of the `isExpanded`.
1811
+ * @see isExpanded
1812
+ */
1813
+ expand() {
1814
+ this.postEvent("web_app_expand"), this.state.set("isExpanded", !0);
1815
+ }
1816
+ /**
1817
+ * Returns true in case current viewport height is stable and is not going to
1818
+ * change in the next moment.
1819
+ */
1820
+ get isStable() {
1821
+ return this.stableHeight === this.height;
1822
+ }
1823
+ }
1824
+ function At(r, t, e) {
1825
+ if (r || t === "macos" || t === "web" || t === "weba")
1826
+ return new j({
1827
+ height: window.innerHeight,
1828
+ isExpanded: !0,
1829
+ postEvent: e,
1830
+ stableHeight: window.innerHeight,
1831
+ width: window.innerWidth
1832
+ });
1833
+ const n = W("viewport");
1834
+ return n ? new j({ ...n, postEvent: e }) : null;
1835
+ }
1836
+ function qt(r) {
1837
+ return r.listen(), r.on("change", () => O("viewport", {
1838
+ height: r.height,
1839
+ isExpanded: r.isExpanded,
1840
+ stableHeight: r.stableHeight,
1841
+ width: r.width
1842
+ })), r;
1843
+ }
1844
+ function Ne(r, t, e) {
1845
+ const n = qt(
1846
+ At(r, t, e) || new j({
1847
+ width: 0,
1848
+ height: 0,
1849
+ isExpanded: !1,
1850
+ postEvent: e,
1851
+ stableHeight: 0
1852
+ })
1853
+ );
1854
+ return n.sync({ postEvent: e, timeout: 100 }).catch((s) => {
1855
+ console.error("Unable to actualize viewport state", s);
1856
+ }), n;
1857
+ }
1858
+ async function Oe(r, t, e) {
1859
+ return qt(
1860
+ At(r, t, e) || await Pt({ postEvent: e, timeout: 100 }).then(({ height: n, isStateStable: s, ...i }) => new j({
1861
+ ...i,
1862
+ height: n,
1863
+ stableHeight: s ? n : 0
1864
+ }))
1865
+ );
1866
+ }
1867
+ function v(r, t) {
1868
+ document.documentElement.style.setProperty(r, t);
1869
+ }
1870
+ function We(r, t) {
1871
+ const e = () => {
1872
+ v("--tg-background-color", r.backgroundColor);
1873
+ }, n = () => {
1874
+ const {
1875
+ backgroundColor: s,
1876
+ secondaryBackgroundColor: i
1877
+ } = t;
1878
+ r.headerColor === "bg_color" ? s && v("--tg-header-color", s) : r.headerColor === "secondary_bg_color" ? i && v("--tg-header-color", i) : v("--tg-header-color", r.headerColor);
1879
+ };
1880
+ t.on("change", n), r.on("change:backgroundColor", e), r.on("change:headerColor", n), e(), n();
1881
+ }
1882
+ function Me(r) {
1883
+ const t = () => {
1884
+ const e = r.getState();
1885
+ Object.entries(e).forEach(([n, s]) => {
1886
+ if (s) {
1887
+ const i = n.replace(/[A-Z]/g, (a) => `-${a.toLowerCase()}`);
1888
+ v(`--tg-theme-${i}`, s);
1889
+ }
1890
+ });
1891
+ };
1892
+ r.on("change", t), t();
1893
+ }
1894
+ function it(r) {
1895
+ const t = () => v("--tg-viewport-height", `${r.height}px`), e = () => v("--tg-viewport-width", `${r.width}px`), n = () => v("--tg-viewport-height", `${r.stableHeight}px`);
1896
+ r.on("change:height", t), r.on("change:width", e), r.on("change:stableHeight", n), t(), e(), n();
1897
+ }
1898
+ function Ue(r) {
1899
+ return typeof r == "object" ? r : r ? {
1900
+ themeParams: !0,
1901
+ viewport: !0,
1902
+ miniApp: !0
1903
+ } : {};
1904
+ }
1905
+ function ot(r, t, e, n) {
1906
+ const s = Ue(r);
1907
+ s.miniApp && We(t, e), s.themeParams && Me(e), s.viewport && (n instanceof Promise ? n.then(it) : it(n));
1908
+ }
1909
+ function je(r) {
1910
+ const { hostname: t, pathname: e } = new URL(r, window.location.href);
1911
+ if (t !== "t.me")
1912
+ throw new Error(`Incorrect hostname: ${t}`);
1913
+ const n = e.match(/^\/(\$|invoice\/)([A-Za-z0-9\-_=]+)$/);
1914
+ if (n === null)
1915
+ throw new Error('Link pathname has incorrect format. Expected to receive "/invoice/{slug}" or "/${slug}"');
1916
+ return n[2];
1917
+ }
1918
+ class Ge {
1919
+ constructor(t, e = f) {
1920
+ o(this, "ee", new w());
1921
+ o(this, "state");
1922
+ /**
1923
+ * Adds new event listener.
1924
+ */
1925
+ o(this, "on", this.ee.on.bind(this.ee));
1926
+ /**
1927
+ * Removes event listener.
1928
+ */
1929
+ o(this, "off", this.ee.off.bind(this.ee));
1930
+ /**
1931
+ * Checks if specified method is supported by current component.
1932
+ */
1933
+ o(this, "supports");
1934
+ this.postEvent = e, this.state = new b({ isOpened: !1 }, this.ee), this.supports = S(t, { open: "web_app_open_invoice" });
1935
+ }
1936
+ set isOpened(t) {
1937
+ this.state.set("isOpened", t);
1938
+ }
1939
+ /**
1940
+ * True if invoice is currently opened.
1941
+ */
1942
+ get isOpened() {
1943
+ return this.state.get("isOpened");
1944
+ }
1945
+ async open(t, e) {
1946
+ if (this.isOpened)
1947
+ throw new Error("Invoice is already opened");
1948
+ const n = e ? je(t) : t;
1949
+ this.isOpened = !0;
1950
+ try {
1951
+ return (await _(
1952
+ "web_app_open_invoice",
1953
+ { slug: n },
1954
+ "invoice_closed",
1955
+ {
1956
+ postEvent: this.postEvent,
1957
+ capture(i) {
1958
+ return n === i.slug;
1959
+ }
1960
+ }
1961
+ )).status;
1962
+ } finally {
1963
+ this.isOpened = !1;
1964
+ }
1965
+ }
1966
+ }
1967
+ function Fe(r) {
1968
+ const t = r.message.trim(), e = (r.title || "").trim(), n = r.buttons || [];
1969
+ let s;
1970
+ if (e.length > 64)
1971
+ throw new Error(`Title has incorrect size: ${e.length}`);
1972
+ if (t.length === 0 || t.length > 256)
1973
+ throw new Error(`Message has incorrect size: ${t.length}`);
1974
+ if (n.length > 3)
1975
+ throw new Error(`Buttons have incorrect size: ${n.length}`);
1976
+ return n.length === 0 ? s = [{ type: "close", id: "" }] : s = n.map((i) => {
1977
+ const { id: a = "" } = i;
1978
+ if (a.length > 64)
1979
+ throw new Error(`Button ID has incorrect size: ${a}`);
1980
+ if (i.type === void 0 || i.type === "default" || i.type === "destructive") {
1981
+ const c = i.text.trim();
1982
+ if (c.length === 0 || c.length > 64) {
1983
+ const u = i.type || "default";
1984
+ throw new Error(`Button text with type "${u}" has incorrect size: ${i.text.length}`);
1985
+ }
1986
+ return { ...i, text: c, id: a };
1987
+ }
1988
+ return { ...i, id: a };
1989
+ }), { title: e, message: t, buttons: s };
1990
+ }
1991
+ class ze {
1992
+ constructor(t, e = f) {
1993
+ o(this, "ee", new w());
1994
+ o(this, "state");
1995
+ /**
1996
+ * Adds new event listener.
1997
+ */
1998
+ o(this, "on", this.ee.on.bind(this.ee));
1999
+ /**
2000
+ * Removes event listener.
2001
+ */
2002
+ o(this, "off", this.ee.off.bind(this.ee));
2003
+ /**
2004
+ * Checks if specified method is supported by current component.
2005
+ */
2006
+ o(this, "supports");
2007
+ this.postEvent = e, this.state = new b({ isOpened: !1 }, this.ee), this.supports = S(t, { open: "web_app_open_popup" });
2008
+ }
2009
+ set isOpened(t) {
2010
+ this.state.set("isOpened", t);
908
2011
  }
909
2012
  /**
910
- * A method that expands the Mini App to the maximum available height. To
911
- * find out if the Mini App is expanded to the maximum height, refer to the
912
- * value of the `isExpanded`.
913
- * @see isExpanded
2013
+ * True if popup is currently opened.
914
2014
  */
915
- expand() {
916
- this.state.set("isExpanded", !0), this.postEvent("web_app_expand");
2015
+ get isOpened() {
2016
+ return this.state.get("isOpened");
917
2017
  }
918
2018
  /**
919
- * Returns true in case current viewport height is stable and is not going to
920
- * change in the next moment.
2019
+ * A method that shows a native popup described by the `params` argument.
2020
+ * Promise will be resolved when popup is closed. Resolved value will have
2021
+ * an identifier of pressed button.
2022
+ *
2023
+ * In case, user clicked outside the popup or clicked top right popup close
2024
+ * button, null will be returned.
2025
+ *
2026
+ * FIXME: In desktop, this function may work incorrectly.
2027
+ * Issue: https://github.com/Telegram-Mini-Apps/tma.js/issues/7
2028
+ * @param options - popup parameters.
2029
+ * @throws {Error} Popup is already opened.
921
2030
  */
922
- get isStable() {
923
- return this.stableHeight === this.height;
2031
+ open(t) {
2032
+ if (this.isOpened)
2033
+ throw new Error("Popup is already opened.");
2034
+ return this.isOpened = !0, _(
2035
+ "web_app_open_popup",
2036
+ Fe(t),
2037
+ "popup_closed",
2038
+ { postEvent: this.postEvent }
2039
+ ).then(({ button_id: e = null }) => e).finally(() => {
2040
+ this.isOpened = !1;
2041
+ });
924
2042
  }
925
2043
  }
926
- function I(s) {
927
- const t = document.createElement("a");
928
- if (t.href = s, t.protocol !== "http:" && t.protocol !== "https:")
929
- throw Error(
930
- `URL protocol is not supported by OS, or link has not allowed protocol: ${t.protocol}`
931
- );
932
- return t.href;
933
- }
934
- class Vt {
935
- constructor(t, e, o, n, r, a = g) {
936
- i(this, "ee", new w());
937
- i(this, "state");
2044
+ class Je {
2045
+ constructor(t, e = f) {
2046
+ o(this, "ee", new w());
2047
+ o(this, "state");
938
2048
  /**
939
2049
  * Adds new event listener.
940
2050
  */
941
- i(this, "on", this.ee.on.bind(this.ee));
2051
+ o(this, "on", this.ee.on.bind(this.ee));
942
2052
  /**
943
2053
  * Removes event listener.
944
2054
  */
945
- i(this, "off", this.ee.off.bind(this.ee));
2055
+ o(this, "off", this.ee.off.bind(this.ee));
946
2056
  /**
947
2057
  * Checks if specified method is supported by current component.
948
2058
  */
949
- i(this, "supports");
950
- /**
951
- * Checks if specified method parameter is supported by current component.
952
- */
953
- i(this, "supportsParam");
954
- this.currentVersion = o, this.currentPlatform = n, this.createRequestId = r, this.postEvent = a, this.state = new m({
955
- backgroundColor: e,
956
- headerColor: t
957
- }, this.ee), this.supports = C(o, {
958
- openInvoice: "web_app_open_invoice",
959
- readTextFromClipboard: "web_app_read_text_from_clipboard",
960
- setHeaderColor: "web_app_set_header_color",
961
- setBackgroundColor: "web_app_set_background_color",
962
- requestPhoneAccess: "web_app_request_phone",
963
- requestWriteAccess: "web_app_request_write_access"
964
- }), this.supportsParam = bt(o, {
965
- "setHeaderColor.color": ["web_app_set_header_color", "color"],
966
- "openLink.tryInstantView": ["web_app_open_link", "try_instant_view"]
2059
+ o(this, "supports");
2060
+ this.postEvent = e, this.state = new b({ isOpened: !1 }, this.ee), this.supports = S(t, {
2061
+ close: "web_app_close_scan_qr_popup",
2062
+ open: "web_app_open_scan_qr_popup"
967
2063
  });
968
2064
  }
969
2065
  /**
970
- * Returns current application background color.
2066
+ * Closes scanner.
971
2067
  */
972
- get backgroundColor() {
973
- return this.state.get("backgroundColor");
2068
+ close() {
2069
+ this.postEvent("web_app_close_scan_qr_popup"), this.isOpened = !1;
974
2070
  }
975
- /**
976
- * Returns current application color scheme. This value is
977
- * computed based on the current background color.
978
- */
979
- get colorScheme() {
980
- return K(this.backgroundColor) ? "dark" : "light";
2071
+ set isOpened(t) {
2072
+ this.state.set("isOpened", t);
981
2073
  }
982
2074
  /**
983
- * Closes the Mini App.
2075
+ * Returns true in case, QR scanner is currently opened.
984
2076
  */
985
- close() {
986
- this.postEvent("web_app_close");
2077
+ get isOpened() {
2078
+ return this.state.get("isOpened");
987
2079
  }
988
2080
  /**
989
- * Returns current application header color.
2081
+ * Opens scanner with specified title shown to user. Method returns promise
2082
+ * with scanned QR content in case, it was scanned. It will contain null in
2083
+ * case, scanner was closed.
2084
+ * @param text - title to display.
990
2085
  */
991
- get headerColor() {
992
- return this.state.get("headerColor");
2086
+ async open(t) {
2087
+ if (this.isOpened)
2088
+ throw new Error("QR scanner is already opened.");
2089
+ this.isOpened = !0;
2090
+ try {
2091
+ const e = await _(
2092
+ "web_app_open_scan_qr_popup",
2093
+ { text: t },
2094
+ ["qr_text_received", "scan_qr_popup_closed"],
2095
+ { postEvent: this.postEvent }
2096
+ );
2097
+ return typeof e == "object" && typeof e.data == "string" ? e.data : null;
2098
+ } finally {
2099
+ this.isOpened = !1;
2100
+ }
993
2101
  }
994
- /**
995
- * Returns true if passed version is more than or equal to current
996
- * Mini App version.
997
- * @param version - compared version.
998
- */
999
- isVersionAtLeast(t) {
1000
- return dt(t, this.version) >= 0;
2102
+ }
2103
+ class Qe {
2104
+ constructor(t, e, n = f) {
2105
+ /**
2106
+ * Checks if specified method is supported by current component.
2107
+ */
2108
+ o(this, "supports");
2109
+ /**
2110
+ * Checks if specified method parameter is supported by current component.
2111
+ */
2112
+ o(this, "supportsParam");
2113
+ this.version = t, this.createRequestId = e, this.postEvent = n, this.supports = S(t, {
2114
+ readTextFromClipboard: "web_app_read_text_from_clipboard"
2115
+ }), this.supportsParam = St(t, {
2116
+ "openLink.tryInstantView": ["web_app_open_link", "try_instant_view"]
2117
+ });
1001
2118
  }
1002
2119
  /**
1003
2120
  * Opens a link in an external browser. The Mini App will not be closed.
@@ -1009,384 +2126,480 @@ class Vt {
1009
2126
  * @param tryInstantView
1010
2127
  */
1011
2128
  openLink(t, e) {
1012
- const o = I(t);
1013
- if (!P("web_app_open_link", this.version)) {
1014
- window.open(o, "_blank");
2129
+ const n = new URL(t, window.location.href).toString();
2130
+ if (!q("web_app_open_link", this.version)) {
2131
+ window.open(n, "_blank");
1015
2132
  return;
1016
2133
  }
1017
- return this.postEvent("web_app_open_link", {
1018
- url: o,
2134
+ this.postEvent("web_app_open_link", {
2135
+ url: n,
1019
2136
  ...typeof e == "boolean" ? { try_instant_view: e } : {}
1020
2137
  });
1021
2138
  }
1022
2139
  /**
1023
- * Opens a Telegram link inside Telegram app. The Mini App will be closed.
1024
- * It expects passing link in full format, with hostname "t.me".
2140
+ * Opens a Telegram link inside Telegram app. The Mini App will be closed. It expects passing
2141
+ * link in full format, with hostname "t.me".
1025
2142
  * @param url - URL to be opened.
1026
2143
  * @throws {Error} URL has not allowed hostname.
1027
2144
  */
1028
2145
  openTelegramLink(t) {
1029
- const { hostname: e, pathname: o, search: n } = new URL(I(t));
2146
+ const {
2147
+ hostname: e,
2148
+ pathname: n,
2149
+ search: s
2150
+ } = new URL(t, window.location.href);
1030
2151
  if (e !== "t.me")
1031
2152
  throw new Error(`URL has not allowed hostname: ${e}. Only "t.me" is allowed`);
1032
- if (!P("web_app_open_tg_link", this.version)) {
2153
+ if (!q("web_app_open_tg_link", this.version)) {
1033
2154
  window.location.href = t;
1034
2155
  return;
1035
2156
  }
1036
- return this.postEvent("web_app_open_tg_link", { path_full: o + n });
2157
+ this.postEvent("web_app_open_tg_link", { path_full: n + s });
1037
2158
  }
1038
2159
  /**
1039
- * Opens an invoice using its url. It expects passing link in full format,
1040
- * with hostname "t.me".
1041
- * @param url - invoice URL.
2160
+ * Reads text from clipboard and returns string or null. null is returned
2161
+ * in cases:
2162
+ * - Value in clipboard is not text
2163
+ * - Access to clipboard is not allowed
1042
2164
  */
1043
- async openInvoice(t) {
1044
- const { hostname: e, pathname: o } = new URL(I(t));
1045
- if (e !== "t.me")
1046
- throw new Error(`Incorrect hostname: ${e}`);
1047
- const n = o.match(/^\/(\$|invoice\/)([A-Za-z0-9\-_=]+)$/);
1048
- if (n === null)
1049
- throw new Error('Link pathname has incorrect format. Expected to receive "/invoice/slug" or "/$slug"');
1050
- const [, , r] = n;
1051
- return (await f("web_app_open_invoice", { slug: r }, "invoice_closed", {
1052
- postEvent: this.postEvent,
1053
- capture: ({ slug: h }) => r === h
1054
- })).status;
2165
+ readTextFromClipboard() {
2166
+ return _(
2167
+ "web_app_read_text_from_clipboard",
2168
+ { req_id: this.createRequestId() },
2169
+ "clipboard_text_received",
2170
+ { postEvent: this.postEvent }
2171
+ ).then(({ data: t = null }) => t);
2172
+ }
2173
+ }
2174
+ function ar(r) {
2175
+ const {
2176
+ async: t = !1,
2177
+ cssVars: e = !1,
2178
+ acceptCustomStyles: n = !1
2179
+ } = r, {
2180
+ launchParams: {
2181
+ initData: s,
2182
+ initDataRaw: i,
2183
+ version: a,
2184
+ platform: c,
2185
+ themeParams: u,
2186
+ botInline: l = !1
2187
+ },
2188
+ isPageReload: p
2189
+ } = Et(), m = De(), d = Ee(a);
2190
+ Ct() && (n && Le(), d("iframe_ready", { reload_supported: !0 }), k("reload_iframe", () => window.location.reload()));
2191
+ const y = {
2192
+ backButton: $e(p, a, d),
2193
+ closingBehavior: Ve(p, d),
2194
+ cloudStorage: new Ae(a, m, d),
2195
+ createRequestId: m,
2196
+ hapticFeedback: new qe(a, d),
2197
+ invoice: new Ge(a, d),
2198
+ mainButton: Ie(
2199
+ p,
2200
+ u.buttonColor || "#000000",
2201
+ u.buttonTextColor || "#ffffff",
2202
+ d
2203
+ ),
2204
+ miniApp: Be(
2205
+ p,
2206
+ u.backgroundColor || "#ffffff",
2207
+ a,
2208
+ l,
2209
+ d
2210
+ ),
2211
+ popup: new ze(a, d),
2212
+ postEvent: d,
2213
+ qrScanner: new Je(a, d),
2214
+ themeParams: He(u),
2215
+ utils: new Qe(a, m, d),
2216
+ ...s ? {
2217
+ initData: new Mt(s),
2218
+ initDataRaw: i
2219
+ } : {}
2220
+ }, x = t ? Oe(p, c, d) : Ne(p, c, d);
2221
+ return x instanceof Promise ? x.then((V) => (ot(
2222
+ e,
2223
+ y.miniApp,
2224
+ y.themeParams,
2225
+ V
2226
+ ), {
2227
+ ...y,
2228
+ viewport: V
2229
+ })) : (ot(
2230
+ e,
2231
+ y.miniApp,
2232
+ y.themeParams,
2233
+ x
2234
+ ), { ...y, viewport: x });
2235
+ }
2236
+ function R(r, t) {
2237
+ return r.startsWith(t) ? r : `${t}${r}`;
2238
+ }
2239
+ function cr(r) {
2240
+ const t = r.match(/#(.+)/);
2241
+ return t ? t[1] : null;
2242
+ }
2243
+ async function B(r) {
2244
+ return r === 0 ? !0 : Promise.race([
2245
+ new Promise((t) => {
2246
+ window.addEventListener("popstate", function e() {
2247
+ window.removeEventListener("popstate", e), t(!0);
2248
+ }), window.history.go(r);
2249
+ }),
2250
+ // Usually, it takes about 1ms to emit this event, but we use some buffer.
2251
+ new Promise((t) => {
2252
+ setTimeout(t, 50, !1);
2253
+ })
2254
+ ]);
2255
+ }
2256
+ async function Ze() {
2257
+ if (window.history.length <= 1 || (window.history.pushState(null, ""), await B(1 - window.history.length)))
2258
+ return;
2259
+ let t = await B(-1);
2260
+ for (; t; )
2261
+ t = await B(-1);
2262
+ }
2263
+ class Ke {
2264
+ constructor(t, e, {
2265
+ debug: n = !1,
2266
+ loggerPrefix: s = "Navigator"
2267
+ }) {
2268
+ o(this, "logger");
2269
+ o(this, "entries");
2270
+ if (this.entriesCursor = e, t.length === 0)
2271
+ throw new Error("Entries list should not be empty.");
2272
+ if (e >= t.length)
2273
+ throw new Error("Cursor should be less than entries count.");
2274
+ this.entries = t.map(({ pathname: i = "", search: a, hash: c }) => {
2275
+ if (!i.startsWith("/") && i.length > 0)
2276
+ throw new Error('Pathname should start with "/"');
2277
+ return {
2278
+ pathname: R(i, "/"),
2279
+ search: a ? R(a, "?") : "",
2280
+ hash: c ? R(c, "#") : ""
2281
+ };
2282
+ }), this.logger = new vt(`[${s}]`, n);
2283
+ }
2284
+ /**
2285
+ * Converts entry to the navigation entry.
2286
+ * @param entry - entry data
2287
+ */
2288
+ formatEntry(t) {
2289
+ let e;
2290
+ if (typeof t == "string")
2291
+ e = t;
2292
+ else {
2293
+ const {
2294
+ pathname: a = "",
2295
+ search: c,
2296
+ hash: u
2297
+ } = t;
2298
+ e = a + (c ? R(c, "?") : "") + (u ? R(u, "#") : "");
2299
+ }
2300
+ const {
2301
+ pathname: n,
2302
+ search: s,
2303
+ hash: i
2304
+ } = new URL(e, `https://localhost${this.path}`);
2305
+ return {
2306
+ pathname: n,
2307
+ search: s,
2308
+ hash: i
2309
+ };
1055
2310
  }
1056
2311
  /**
1057
- * Returns current Mini App platform.
2312
+ * Current entry.
1058
2313
  */
1059
- get platform() {
1060
- return this.currentPlatform;
2314
+ get entry() {
2315
+ return this.entries[this.entriesCursor];
1061
2316
  }
1062
2317
  /**
1063
- * Informs the Telegram app that the Mini App is ready to be displayed.
1064
- *
1065
- * It is recommended to call this method as early as possible, as soon as
1066
- * all essential interface elements loaded. Once this method called,
1067
- * the loading placeholder is hidden and the Mini App shown.
1068
- *
1069
- * If the method not called, the placeholder will be hidden only when
1070
- * the page fully loaded.
2318
+ * Goes back in history.
1071
2319
  */
1072
- ready() {
1073
- this.postEvent("web_app_ready");
2320
+ back() {
2321
+ return this.go(-1);
1074
2322
  }
1075
2323
  /**
1076
- * Reads text from clipboard and returns string or null. null is returned
1077
- * in cases:
1078
- * - Value in clipboard is not text
1079
- * - Access to clipboard is not allowed
2324
+ * Current entries cursor.
1080
2325
  */
1081
- async readTextFromClipboard() {
1082
- const { data: t = null } = await f(
1083
- "web_app_read_text_from_clipboard",
1084
- { req_id: this.createRequestId() },
1085
- "clipboard_text_received",
1086
- { postEvent: this.postEvent }
1087
- );
1088
- return t;
2326
+ get cursor() {
2327
+ return this.entriesCursor;
1089
2328
  }
1090
2329
  /**
1091
- * Requests current user phone access.
2330
+ * True if navigator can go back.
1092
2331
  */
1093
- async requestPhoneAccess() {
1094
- const { status: t } = await f("web_app_request_phone", "phone_requested", {
1095
- postEvent: this.postEvent
1096
- });
1097
- return t;
2332
+ get canGoBack() {
2333
+ return this.entriesCursor > 0;
1098
2334
  }
1099
2335
  /**
1100
- * Requests write message access to current user.
2336
+ * True if navigator can go forward.
2337
+ */
2338
+ get canGoForward() {
2339
+ return this.entriesCursor !== this.entries.length - 1;
2340
+ }
2341
+ /**
2342
+ * Goes forward in history.
2343
+ */
2344
+ forward() {
2345
+ return this.go(1);
2346
+ }
2347
+ /**
2348
+ * Moves entries cursor by specified delta.
2349
+ * @param delta - cursor delta.
1101
2350
  */
1102
- async requestWriteAccess() {
1103
- const { status: t } = await f("web_app_request_write_access", "write_access_requested", {
1104
- postEvent: this.postEvent
2351
+ go(t) {
2352
+ this.logger.log(`called go(${t})`);
2353
+ const e = Math.min(
2354
+ this.entries.length - 1,
2355
+ Math.max(this.entriesCursor + t, 0)
2356
+ );
2357
+ if (this.entriesCursor === e)
2358
+ return this.performGo({
2359
+ updated: !1,
2360
+ delta: t
2361
+ });
2362
+ const n = this.entry;
2363
+ this.entriesCursor = e;
2364
+ const s = this.entry;
2365
+ return this.logger.log("State changed", { before: n, after: s }), this.performGo({
2366
+ updated: !0,
2367
+ delta: t,
2368
+ before: n,
2369
+ after: s
1105
2370
  });
1106
- return t;
1107
2371
  }
1108
2372
  /**
1109
- * A method used to send data to the bot. When this method called, a
1110
- * service message sent to the bot containing the data of the
1111
- * length up to 4096 bytes, and the Mini App closed. See the field
1112
- * `web_app_data` in the class Message.
2373
+ * Returns copy of navigator entries.
2374
+ */
2375
+ getEntries() {
2376
+ return this.entries.map((t) => ({ ...t }));
2377
+ }
2378
+ /**
2379
+ * Current hash.
2380
+ * @example
2381
+ * "", "#", "#hash"
2382
+ */
2383
+ get hash() {
2384
+ return this.entry.hash;
2385
+ }
2386
+ /**
2387
+ * Pushes new entry. Method replaces all entries after the current one with the inserted.
2388
+ * @param entry - entry data.
1113
2389
  *
1114
- * This method is only available for Mini Apps launched via a Keyboard button.
1115
- * @param data - data to send to bot.
1116
- * @throws {Error} data has incorrect size.
2390
+ * @example Pushing absolute pathname.
2391
+ * push("/absolute-path"); // "/absolute-path"
2392
+ *
2393
+ * @example Pushing relative pathname.
2394
+ * // Pushing relative path replaces N last path parts, where N is pushed pathname parts count.
2395
+ * // Pushing empty path is recognized as relative, but not replacing the last pathname part.
2396
+ * push("relative"); // "/home/root" -> "/home/relative"
2397
+ *
2398
+ * @example Pushing query parameters.
2399
+ * push("/absolute?my-param=1"); // "/home" -> "/absolute?my-param=1"
2400
+ * push("relative?my-param=1"); // "/home/root" -> "/home/relative?my-param=1"
2401
+ * push("?my-param=1"); // "/home" -> "/home?my-param=1"
2402
+ *
2403
+ * @example Pushing hash.
2404
+ * push("#my-hash"); // "/home" -> "/home#my-hash"
2405
+ * push("johny#my-hash"); // "/home/root" -> "/home/johny#my-hash"
2406
+ */
2407
+ push(t) {
2408
+ this.entriesCursor !== this.entries.length - 1 && this.entries.splice(this.entriesCursor + 1);
2409
+ const e = this.formatEntry(t), n = this.entry;
2410
+ this.entriesCursor += 1, this.entries[this.entriesCursor] = e;
2411
+ const s = this.entry;
2412
+ return this.logger.log("State changed", { before: n, after: s }), this.performPush({
2413
+ before: n,
2414
+ after: s
2415
+ });
2416
+ }
2417
+ /**
2418
+ * Current full path including pathname, query parameters and hash.
1117
2419
  */
1118
- sendData(t) {
1119
- const { size: e } = new Blob([t]);
1120
- if (e === 0 || e > 4096)
1121
- throw new Error(`Passed data has incorrect size: ${e}`);
1122
- this.postEvent("web_app_data_send", { data: t });
2420
+ get path() {
2421
+ return `${this.pathname}${this.search}${this.hash}`;
1123
2422
  }
1124
2423
  /**
1125
- * Updates current application header color.
1126
- * FIXME: Has no effect on desktop, works incorrectly on Android.
1127
- * Issues:
1128
- * https://github.com/Telegram-Mini-Apps/tma.js/issues/9
1129
- * https://github.com/Telegram-Mini-Apps/tma.js/issues/8
1130
- * @param color - color key or RGB color.
2424
+ * Current pathname.
2425
+ * @example
2426
+ * "/", "/abc"
1131
2427
  */
1132
- setHeaderColor(t) {
1133
- this.postEvent("web_app_set_header_color", pt(t) ? { color: t } : { color_key: t }), this.state.set("headerColor", t);
2428
+ get pathname() {
2429
+ return this.entry.pathname;
1134
2430
  }
1135
2431
  /**
1136
- * Updates current application background color.
1137
- * FIXME: Has no effect on desktop, works incorrectly in Android.
1138
- * Issues:
1139
- * https://github.com/Telegram-Mini-Apps/tma.js/issues/9
1140
- * https://github.com/Telegram-Mini-Apps/tma.js/issues/8
1141
- * @param color - RGB color.
2432
+ * Replaces current entry. Has the same logic as `push` method.
2433
+ * @param entry - entry data.
2434
+ * @see push
2435
+ * @returns True if changes were done.
1142
2436
  */
1143
- setBackgroundColor(t) {
1144
- this.postEvent("web_app_set_background_color", { color: t }), this.state.set("backgroundColor", t);
2437
+ replace(t) {
2438
+ const e = this.formatEntry(t);
2439
+ if (this.search === e.search && this.pathname === e.pathname && this.hash === e.hash)
2440
+ return this.performReplace({
2441
+ updated: !1,
2442
+ entry: e
2443
+ });
2444
+ const n = this.entry;
2445
+ this.entries[this.entriesCursor] = e;
2446
+ const s = this.entry;
2447
+ return this.logger.log("State changed", { before: n, after: s }), this.performReplace({
2448
+ updated: !0,
2449
+ before: n,
2450
+ after: s
2451
+ });
1145
2452
  }
1146
2453
  /**
1147
- * Current Mini App version. This property is used by other components to check if
1148
- * some functionality is available on current device.
2454
+ * Current query parameters.
2455
+ * @example
2456
+ * "", "?", "?a=1"
1149
2457
  */
1150
- get version() {
1151
- return this.currentVersion;
2458
+ get search() {
2459
+ return this.entry.search;
1152
2460
  }
1153
2461
  }
1154
- class F extends Error {
1155
- constructor(t, e) {
1156
- super(`Method "${t}" is not supported in the Mini Apps version ${e}.`), Object.setPrototypeOf(this, F.prototype);
2462
+ const at = 0, J = 1, Q = 2;
2463
+ class Lt extends Ke {
2464
+ constructor(e, n, s = {}) {
2465
+ super(e, n, {
2466
+ ...s,
2467
+ loggerPrefix: "HashNavigator"
2468
+ });
2469
+ o(this, "ee", new w());
2470
+ o(this, "attached", !1);
2471
+ /**
2472
+ * Handles window "popstate" event.
2473
+ * @param state - event state.
2474
+ */
2475
+ o(this, "onPopState", async ({ state: e }) => {
2476
+ if (this.logger.log('"popstate" event received. State:', e), e === null)
2477
+ return this.push(window.location.hash.slice(1));
2478
+ if (e === at) {
2479
+ this.logger.log("Void reached. Moving history forward"), window.history.forward();
2480
+ return;
2481
+ }
2482
+ if (e === J)
2483
+ return this.back();
2484
+ if (e === Q)
2485
+ return this.forward();
2486
+ });
2487
+ o(this, "back", () => super.back());
2488
+ /**
2489
+ * Adds new event listener.
2490
+ */
2491
+ o(this, "on", this.ee.on.bind(this.ee));
2492
+ /**
2493
+ * Removes event listener.
2494
+ */
2495
+ o(this, "off", this.ee.off.bind(this.ee));
1157
2496
  }
1158
- }
1159
- class j extends Error {
1160
- constructor(t, e, o) {
1161
- super(`Parameter "${e}" in method "${t}" is not supported in the Mini Apps version ${o}.`), Object.setPrototypeOf(this, j.prototype);
2497
+ /**
2498
+ * Creates navigator from current window location hash.
2499
+ * @param options - options passed to constructor.
2500
+ */
2501
+ static fromLocation(e) {
2502
+ const {
2503
+ search: n,
2504
+ pathname: s,
2505
+ hash: i
2506
+ } = new URL(
2507
+ window.location.hash.slice(1),
2508
+ window.location.href
2509
+ );
2510
+ return new Lt([{ search: n, pathname: s, hash: i }], 0, e);
1162
2511
  }
1163
- }
1164
- function J(s, t) {
1165
- document.documentElement.style.setProperty(s, t);
1166
- }
1167
- function _(s, t) {
1168
- t !== null && J(s, t);
1169
- }
1170
- function N(s, t) {
1171
- J(s, `${t}px`);
1172
- }
1173
- function St(s) {
1174
- const {
1175
- backgroundColor: t,
1176
- buttonTextColor: e,
1177
- secondaryBackgroundColor: o,
1178
- hintColor: n,
1179
- buttonColor: r,
1180
- linkColor: a,
1181
- textColor: h
1182
- } = s;
1183
- _("--tg-theme-bg-color", t), _("--tg-theme-button-color", r), _("--tg-theme-button-text-color", e), _("--tg-theme-hint-color", n), _("--tg-theme-link-color", a), _("--tg-theme-secondary-bg-color", o), _("--tg-theme-text-color", h);
1184
- }
1185
- function Pt(s, t) {
1186
- const { backgroundColor: e, secondaryBackgroundColor: o } = t, { backgroundColor: n, headerColor: r } = s;
1187
- _("--tg-bg-color", n), _("--tg-header-color", r === "bg_color" ? e : o);
1188
- }
1189
- function qt(s) {
1190
- const t = () => St(s);
1191
- s.on("changed", t), t();
1192
- }
1193
- function Ot(s, t) {
1194
- const e = () => Pt(s, t);
1195
- t.on("changed", e), s.on("backgroundColorChanged", e), s.on("headerColorChanged", e), e();
1196
- }
1197
- function Tt(s) {
1198
- const t = () => {
1199
- N("--tg-viewport-height", s.height);
1200
- }, e = () => {
1201
- N("--tg-viewport-stable-height", s.stableHeight);
1202
- };
1203
- s.on("heightChanged", t), s.on("stableHeightChanged", e), t(), e();
1204
- }
1205
- function Bt(s) {
1206
- return typeof s == "boolean" ? s ? { themeParams: !0, viewport: !0, webApp: !0 } : {} : s;
1207
- }
1208
- function G(s) {
1209
- return `telegram-mini-apps-${s}`;
1210
- }
1211
- function x(s, t) {
1212
- sessionStorage.setItem(G(s), JSON.stringify(t));
1213
- }
1214
- function V(s) {
1215
- const t = sessionStorage.getItem(G(s));
1216
- return t ? JSON.parse(t) : null;
1217
- }
1218
- function It(s, t, e) {
1219
- const { isVisible: o = !1 } = s ? V("back-button") || {} : {}, n = new _t(o, t, e);
1220
- return n.on("isVisibleChanged", () => {
1221
- x("back-button", { isVisible: n.isVisible });
1222
- }), n;
1223
- }
1224
- function $t(s, t) {
1225
- const { isConfirmationNeeded: e = !1 } = s ? V("closing-behavior") || {} : {}, o = new ft(e, t);
1226
- return o.on("isConfirmationNeededChanged", () => x("closing-behavior", {
1227
- isConfirmationNeeded: o.isConfirmationNeeded
1228
- })), o;
1229
- }
1230
- function At(s, t, e, o) {
1231
- const {
1232
- backgroundColor: n = t,
1233
- isEnabled: r = !1,
1234
- isVisible: a = !1,
1235
- isProgressVisible: h = !1,
1236
- textColor: c = e,
1237
- text: l = ""
1238
- } = s ? V("main-button") || {} : {}, u = new yt(
1239
- n,
1240
- r,
1241
- a,
1242
- h,
1243
- l,
1244
- c,
1245
- o
1246
- ), p = () => x("main-button", {
1247
- backgroundColor: u.backgroundColor,
1248
- isEnabled: u.isEnabled,
1249
- isVisible: u.isVisible,
1250
- isProgressVisible: u.isProgressVisible,
1251
- text: u.text,
1252
- textColor: u.textColor
1253
- });
1254
- return u.on("backgroundColorChanged", p), u.on("isEnabledChanged", p), u.on("isVisibleChanged", p), u.on("isProgressVisibleChanged", p), u.on("textColorChanged", p), u.on("textChanged", p), u;
1255
- }
1256
- function Ht() {
1257
- let s = 0;
1258
- return () => (s += 1, s.toString());
1259
- }
1260
- function Rt(s) {
1261
- const t = new q(s);
1262
- return q.sync(t), t;
1263
- }
1264
- async function Dt(s, t, e) {
1265
- const {
1266
- height: o = window.innerHeight,
1267
- stableHeight: n = window.innerHeight,
1268
- width: r = window.innerWidth,
1269
- isExpanded: a = !1
1270
- } = s ? V("viewport") || {} : {}, c = t === "macos" || t === "web" ? (() => {
1271
- const u = new k(o, r, n, a, e);
1272
- return k.sync(u), u;
1273
- })() : await k.synced({ postEvent: e }), l = () => x("viewport", {
1274
- height: c.height,
1275
- isExpanded: c.isExpanded,
1276
- stableHeight: c.stableHeight,
1277
- width: c.width
1278
- });
1279
- return c.on("heightChanged", l), c.on("isExpandedChanged", l), c.on("stableHeightChanged", l), c.on("widthChanged", l), c;
1280
- }
1281
- function Lt(s, t, e, o, n, r) {
1282
- const {
1283
- backgroundColor: a = t,
1284
- headerColor: h = "bg_color"
1285
- } = s ? V("web-app") || {} : {}, c = new Vt(
1286
- h,
1287
- a,
1288
- e,
1289
- o,
1290
- n,
1291
- r
1292
- ), l = () => x("web-app", {
1293
- backgroundColor: c.backgroundColor,
1294
- headerColor: c.headerColor
1295
- });
1296
- return c.on("backgroundColorChanged", l), c.on("headerColorChanged", l), c;
1297
- }
1298
- async function Mt(s = {}) {
1299
- const {
1300
- checkCompat: t = !0,
1301
- cssVars: e = !1,
1302
- acceptScrollbarStyle: o = !0,
1303
- acceptCustomStyles: n = o,
1304
- targetOrigin: r,
1305
- launchParams: a,
1306
- debug: h = !1
1307
- } = s;
1308
- h && it(h), typeof r == "string" && at(r);
1309
- const { launchParams: c, isPageReload: l } = z({
1310
- currentLaunchParams: typeof a == "string" || a instanceof URLSearchParams ? rt(a) : a
1311
- }), {
1312
- initData: u,
1313
- initDataRaw: p,
1314
- version: b,
1315
- platform: S,
1316
- themeParams: $
1317
- } = c, {
1318
- backgroundColor: Q = "#ffffff",
1319
- buttonColor: Z = "#000000",
1320
- buttonTextColor: X = "#ffffff"
1321
- } = $, A = Ht(), d = t ? ct(b) : g, O = Rt($), H = Lt(
1322
- l,
1323
- Q,
1324
- b,
1325
- S,
1326
- A,
1327
- d
1328
- ), {
1329
- themeParams: Y,
1330
- viewport: tt,
1331
- webApp: et
1332
- } = Bt(e);
1333
- et && Ot(H, O), Y && qt(O);
1334
- const R = await Dt(l, S, d);
1335
- if (tt && Tt(R), n && ht()) {
1336
- const v = document.createElement("style");
1337
- v.id = "telegram-custom-styles", document.head.appendChild(v), E("set_custom_style", (B) => {
1338
- v.innerHTML = B;
1339
- }), d("iframe_ready");
1340
- }
1341
- const T = {
1342
- backButton: It(l, b, d),
1343
- closingBehavior: $t(l, d),
1344
- cloudStorage: new wt(b, A, d),
1345
- haptic: new Ct(b, d),
1346
- mainButton: At(l, Z, X, d),
1347
- popup: new Et(b, d),
1348
- postEvent: d,
1349
- qrScanner: new xt(b, d),
1350
- themeParams: O,
1351
- viewport: R,
1352
- webApp: H
1353
- };
1354
- if (u !== void 0) {
1355
- const { authDate: v, hash: B, ...st } = u;
1356
- T.initData = new vt(v, B, st), T.initDataRaw = p;
2512
+ async performGo(e) {
2513
+ e.updated && (this.attached && await this.syncHistory(), this.emitChanged(e.before, e.after));
1357
2514
  }
1358
- return T;
1359
- }
1360
- function Qt(s = {}) {
1361
- return gt(Mt(s), s.timeout || 1e3);
1362
- }
1363
- function Nt() {
1364
- try {
1365
- return z(), !0;
1366
- } catch {
1367
- return !1;
2515
+ async performPush({ before: e, after: n }) {
2516
+ this.attached && await this.syncHistory(), this.emitChanged(e, n);
2517
+ }
2518
+ async performReplace(e) {
2519
+ e.updated && (this.attached && window.history.replaceState(null, "", `#${this.path}`), this.emitChanged(e.before, e.after));
2520
+ }
2521
+ /**
2522
+ * Synchronizes current navigator state with browser history.
2523
+ */
2524
+ async syncHistory() {
2525
+ window.removeEventListener("popstate", this.onPopState);
2526
+ const e = `#${this.path}`;
2527
+ await Ze(), f("web_app_setup_back_button", { is_visible: this.canGoBack }), this.canGoBack && this.canGoForward ? (this.logger.log("Setting up history: [<-, *, ->]"), window.history.replaceState(J, ""), window.history.pushState(null, "", e), window.history.pushState(Q, ""), await B(-1)) : this.canGoBack ? (this.logger.log("Setting up history: [<-, *]"), window.history.replaceState(J, ""), window.history.pushState(null, "", e)) : this.canGoForward ? (this.logger.log("Setting up history: [*, ->]"), window.history.replaceState(null, e), window.history.pushState(Q, ""), await B(-1)) : (this.logger.log("Setting up history: [~, *]"), window.history.replaceState(at, ""), window.history.pushState(null, "", e)), window.addEventListener("popstate", this.onPopState);
2528
+ }
2529
+ emitChanged(e, n) {
2530
+ this.ee.emit("change", {
2531
+ navigator: this,
2532
+ from: e,
2533
+ to: n
2534
+ });
2535
+ }
2536
+ /**
2537
+ * Attaches current navigator to the browser history allowing navigator to manipulate it.
2538
+ */
2539
+ async attach() {
2540
+ if (!this.attached)
2541
+ return this.logger.log("Attaching", this), this.attached = !0, k("back_button_pressed", this.back), this.syncHistory();
2542
+ }
2543
+ /**
2544
+ * Detaches current navigator from the browser history.
2545
+ */
2546
+ detach() {
2547
+ this.attached && (this.logger.log("Detaching", this), this.attached = !1, window.removeEventListener("popstate", this.onPopState), N("back_button_pressed", this.back));
1368
2548
  }
1369
- }
1370
- function Zt() {
1371
- return Nt();
1372
2549
  }
1373
2550
  export {
1374
- _t as BackButton,
1375
- ft as ClosingBehaviour,
1376
- wt as CloudStorage,
1377
- Ct as HapticFeedback,
1378
- vt as InitData,
1379
- yt as MainButton,
1380
- F as MethodNotSupportedError,
1381
- j as ParameterUnsupportedError,
1382
- Et as Popup,
1383
- xt as QRScanner,
1384
- q as ThemeParams,
1385
- k as Viewport,
1386
- Vt as WebApp,
1387
- I as formatURL,
1388
- Qt as init,
1389
- Nt as isTMA,
1390
- Zt as isTWA
2551
+ ve as BackButton,
2552
+ xe as ClosingBehavior,
2553
+ Ae as CloudStorage,
2554
+ qe as HapticFeedback,
2555
+ Lt as HashNavigator,
2556
+ Mt as InitData,
2557
+ Ge as Invoice,
2558
+ Te as MainButton,
2559
+ K as MethodUnsupportedError,
2560
+ Re as MiniApp,
2561
+ Ke as Navigator,
2562
+ Y as ParameterUnsupportedError,
2563
+ ze as Popup,
2564
+ Je as QRScanner,
2565
+ zt as ThemeParams,
2566
+ Qe as Utils,
2567
+ j as Viewport,
2568
+ Wt as chatParser,
2569
+ ke as classNames,
2570
+ ye as compareVersions,
2571
+ Ee as createPostEvent,
2572
+ cr as getHash,
2573
+ ar as init,
2574
+ gt as initDataParser,
2575
+ lt as isColorDark,
2576
+ Ct as isIframe,
2577
+ ut as isRGB,
2578
+ Nt as isRGBShort,
2579
+ D as isRecord,
2580
+ er as isTMA,
2581
+ bt as launchParamsParser,
2582
+ or as mergeClassNames,
2583
+ N as off,
2584
+ k as on,
2585
+ sr as once,
2586
+ Xe as parseInitData,
2587
+ mt as parseLaunchParams,
2588
+ _t as parseThemeParams,
2589
+ f as postEvent,
2590
+ _ as request,
2591
+ tr as requestThemeParams,
2592
+ Pt as requestViewport,
2593
+ Et as retrieveLaunchData,
2594
+ Kt as serializeLaunchParams,
2595
+ Ft as serializeThemeParams,
2596
+ rr as setDebug,
2597
+ nr as setTargetOrigin,
2598
+ ir as subscribe,
2599
+ q as supports,
2600
+ wt as themeParamsParser,
2601
+ pt as toRGB,
2602
+ me as unsubscribe,
2603
+ tt as userParser
1391
2604
  };
1392
2605
  //# sourceMappingURL=index.mjs.map