@monetize.software/sdk-extension 3.0.0-alpha.8 → 3.0.0-beta.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 (227) hide show
  1. package/dist/chunks/ar-CViBaj16.js +2 -0
  2. package/dist/chunks/ar-CViBaj16.js.map +1 -0
  3. package/dist/chunks/{ar-nh4l4WDE.js → ar-ClwBmll7.js} +9 -4
  4. package/dist/chunks/ar-ClwBmll7.js.map +1 -0
  5. package/dist/chunks/chrome-port-BEMjZQAH.js +2 -0
  6. package/dist/chunks/chrome-port-BEMjZQAH.js.map +1 -0
  7. package/dist/chunks/{chrome-port-CxW3Pwc2.js → chrome-port-bfTUUDz_.js} +174 -138
  8. package/dist/chunks/chrome-port-bfTUUDz_.js.map +1 -0
  9. package/dist/chunks/{cs-2UYO2rWf.js → cs-Cc_D0W4S.js} +7 -2
  10. package/dist/chunks/cs-Cc_D0W4S.js.map +1 -0
  11. package/dist/chunks/cs-DQJWP65K.js +2 -0
  12. package/dist/chunks/cs-DQJWP65K.js.map +1 -0
  13. package/dist/chunks/{da-BD0O_HfV.js → da-BtKcMSxH.js} +7 -2
  14. package/dist/chunks/da-BtKcMSxH.js.map +1 -0
  15. package/dist/chunks/da-Cyr_IXhb.js +2 -0
  16. package/dist/chunks/da-Cyr_IXhb.js.map +1 -0
  17. package/dist/chunks/de-BOCUj1pF.js +2 -0
  18. package/dist/chunks/de-BOCUj1pF.js.map +1 -0
  19. package/dist/chunks/{de-BkCiXPsn.js → de-iwQW5eYl.js} +8 -2
  20. package/dist/chunks/de-iwQW5eYl.js.map +1 -0
  21. package/dist/chunks/{el-cIcxTp07.js → el-BoH65CeJ.js} +7 -2
  22. package/dist/chunks/el-BoH65CeJ.js.map +1 -0
  23. package/dist/chunks/el-C6jLHiEF.js +2 -0
  24. package/dist/chunks/el-C6jLHiEF.js.map +1 -0
  25. package/dist/chunks/es-CARHLxHR.js +2 -0
  26. package/dist/chunks/es-CARHLxHR.js.map +1 -0
  27. package/dist/chunks/{es-CJBC_jrV.js → es-CkP16_8K.js} +8 -2
  28. package/dist/chunks/es-CkP16_8K.js.map +1 -0
  29. package/dist/chunks/fi-B8OhRbwY.js +2 -0
  30. package/dist/chunks/fi-B8OhRbwY.js.map +1 -0
  31. package/dist/chunks/{fi-DyV7ynBf.js → fi-yUXSmK1E.js} +7 -2
  32. package/dist/chunks/fi-yUXSmK1E.js.map +1 -0
  33. package/dist/chunks/fr-CoM18zzM.js +2 -0
  34. package/dist/chunks/fr-CoM18zzM.js.map +1 -0
  35. package/dist/chunks/{fr-BLQ4AIu7.js → fr-DSZRGsxI.js} +8 -2
  36. package/dist/chunks/fr-DSZRGsxI.js.map +1 -0
  37. package/dist/chunks/he-DTDVc3lA.js +2 -0
  38. package/dist/chunks/he-DTDVc3lA.js.map +1 -0
  39. package/dist/chunks/{he-Bg-Bqi7r.js → he-ZUo7cQjk.js} +9 -4
  40. package/dist/chunks/he-ZUo7cQjk.js.map +1 -0
  41. package/dist/chunks/hi-BjnS9UeE.js +2 -0
  42. package/dist/chunks/hi-BjnS9UeE.js.map +1 -0
  43. package/dist/chunks/{hi-wQeE43oY.js → hi-CEutBKiG.js} +9 -4
  44. package/dist/chunks/hi-CEutBKiG.js.map +1 -0
  45. package/dist/chunks/hu-CN06FMhV.js +2 -0
  46. package/dist/chunks/hu-CN06FMhV.js.map +1 -0
  47. package/dist/chunks/{hu-D9qxzu0r.js → hu-DvEAWGS7.js} +7 -2
  48. package/dist/chunks/hu-DvEAWGS7.js.map +1 -0
  49. package/dist/chunks/id-BITgaBxq.js +2 -0
  50. package/dist/chunks/id-BITgaBxq.js.map +1 -0
  51. package/dist/chunks/{id-Rx_wYvqy.js → id-_eEMrYMW.js} +7 -2
  52. package/dist/chunks/id-_eEMrYMW.js.map +1 -0
  53. package/dist/chunks/{it-B1SRPZ3e.js → it-BAmsQbIl.js} +8 -2
  54. package/dist/chunks/it-BAmsQbIl.js.map +1 -0
  55. package/dist/chunks/it-DVcsq015.js +2 -0
  56. package/dist/chunks/it-DVcsq015.js.map +1 -0
  57. package/dist/chunks/ja-Bim7Ok2e.js +2 -0
  58. package/dist/chunks/ja-Bim7Ok2e.js.map +1 -0
  59. package/dist/chunks/{ja-DiItm8te.js → ja-BqCZWVKK.js} +10 -4
  60. package/dist/chunks/ja-BqCZWVKK.js.map +1 -0
  61. package/dist/chunks/{ko-CdGFWAKX.js → ko-CkIzeOzb.js} +10 -4
  62. package/dist/chunks/ko-CkIzeOzb.js.map +1 -0
  63. package/dist/chunks/ko-DqEfcVCB.js +2 -0
  64. package/dist/chunks/ko-DqEfcVCB.js.map +1 -0
  65. package/dist/chunks/nl-DSNuJWIo.js +2 -0
  66. package/dist/chunks/nl-DSNuJWIo.js.map +1 -0
  67. package/dist/chunks/{nl-CmZ3vEvj.js → nl-Mu_KNzli.js} +8 -2
  68. package/dist/chunks/nl-Mu_KNzli.js.map +1 -0
  69. package/dist/chunks/{no-BuxByZpq.js → no-9HMjljBs.js} +7 -2
  70. package/dist/chunks/no-9HMjljBs.js.map +1 -0
  71. package/dist/chunks/no-B5HY_A8_.js +2 -0
  72. package/dist/chunks/no-B5HY_A8_.js.map +1 -0
  73. package/dist/chunks/{pl-jZFCnDb8.js → pl-Cbr2qDwv.js} +7 -2
  74. package/dist/chunks/pl-Cbr2qDwv.js.map +1 -0
  75. package/dist/chunks/pl-ChGLn9Sy.js +2 -0
  76. package/dist/chunks/pl-ChGLn9Sy.js.map +1 -0
  77. package/dist/chunks/port-name-CF4WQQ3-.js +2 -0
  78. package/dist/chunks/port-name-CF4WQQ3-.js.map +1 -0
  79. package/dist/chunks/port-name-ervLBWAQ.js +6 -0
  80. package/dist/chunks/port-name-ervLBWAQ.js.map +1 -0
  81. package/dist/chunks/pt-CDLEktT9.js +2 -0
  82. package/dist/chunks/pt-CDLEktT9.js.map +1 -0
  83. package/dist/chunks/{pt-Cld7MwIW.js → pt-_jirA6IR.js} +8 -2
  84. package/dist/chunks/pt-_jirA6IR.js.map +1 -0
  85. package/dist/chunks/ro-BHCHiXY3.js +2 -0
  86. package/dist/chunks/ro-BHCHiXY3.js.map +1 -0
  87. package/dist/chunks/{ro-CuKDqj3C.js → ro-oZLxhwHc.js} +7 -2
  88. package/dist/chunks/ro-oZLxhwHc.js.map +1 -0
  89. package/dist/chunks/ru-B6HgmINj.js +2 -0
  90. package/dist/chunks/ru-B6HgmINj.js.map +1 -0
  91. package/dist/chunks/{ru-B7cjqJUm.js → ru-C2-sqY7B.js} +15 -2
  92. package/dist/chunks/ru-C2-sqY7B.js.map +1 -0
  93. package/dist/chunks/sv-DoSs4a9n.js +2 -0
  94. package/dist/chunks/sv-DoSs4a9n.js.map +1 -0
  95. package/dist/chunks/{sv-D9y-M1Fo.js → sv-y385MWVy.js} +7 -2
  96. package/dist/chunks/sv-y385MWVy.js.map +1 -0
  97. package/dist/chunks/{th-D9umBjEy.js → th-Bjbv4M1s.js} +7 -2
  98. package/dist/chunks/th-Bjbv4M1s.js.map +1 -0
  99. package/dist/chunks/th-UeweOhwg.js +2 -0
  100. package/dist/chunks/th-UeweOhwg.js.map +1 -0
  101. package/dist/chunks/tr-BbBr5tyB.js +2 -0
  102. package/dist/chunks/tr-BbBr5tyB.js.map +1 -0
  103. package/dist/chunks/{tr-BddMywiw.js → tr-DmHo9F8i.js} +9 -4
  104. package/dist/chunks/tr-DmHo9F8i.js.map +1 -0
  105. package/dist/chunks/uk-CJTA1SJK.js +2 -0
  106. package/dist/chunks/uk-CJTA1SJK.js.map +1 -0
  107. package/dist/chunks/{uk-Dbd31hFt.js → uk-DwvAoTe5.js} +15 -2
  108. package/dist/chunks/uk-DwvAoTe5.js.map +1 -0
  109. package/dist/chunks/{vi-Do3BMOdh.js → vi-BEpwsVLR.js} +7 -2
  110. package/dist/chunks/vi-BEpwsVLR.js.map +1 -0
  111. package/dist/chunks/vi-ZvBo7PbB.js +2 -0
  112. package/dist/chunks/vi-ZvBo7PbB.js.map +1 -0
  113. package/dist/chunks/zh-CPZBEb3d.js +2 -0
  114. package/dist/chunks/zh-CPZBEb3d.js.map +1 -0
  115. package/dist/chunks/{zh-gQSYLZI3.js → zh-DrG18oGe.js} +9 -3
  116. package/dist/chunks/zh-DrG18oGe.js.map +1 -0
  117. package/dist/content/PaywallUI.d.ts +1 -1
  118. package/dist/content/RemoteAuthClient.d.ts +3 -3
  119. package/dist/content/RemoteBillingClient.d.ts +7 -3
  120. package/dist/content/RemoteBillingClient.d.ts.map +1 -1
  121. package/dist/content/RemoteTrialStore.d.ts +2 -2
  122. package/dist/content.cjs +3 -3
  123. package/dist/content.cjs.map +1 -1
  124. package/dist/content.js +1289 -893
  125. package/dist/content.js.map +1 -1
  126. package/dist/offscreen/server.d.ts +3 -3
  127. package/dist/offscreen/server.d.ts.map +1 -1
  128. package/dist/offscreen.cjs +1 -1
  129. package/dist/offscreen.cjs.map +1 -1
  130. package/dist/offscreen.js +9 -9
  131. package/dist/offscreen.js.map +1 -1
  132. package/dist/shared/messages.d.ts +4 -4
  133. package/dist/shared/port-name.d.ts +1 -0
  134. package/dist/shared/port-name.d.ts.map +1 -1
  135. package/dist/sw.cjs +1 -1
  136. package/dist/sw.cjs.map +1 -1
  137. package/dist/sw.js +14 -14
  138. package/dist/sw.js.map +1 -1
  139. package/package.json +3 -3
  140. package/dist/chunks/ar-BUQInJ5a.js +0 -2
  141. package/dist/chunks/ar-BUQInJ5a.js.map +0 -1
  142. package/dist/chunks/ar-nh4l4WDE.js.map +0 -1
  143. package/dist/chunks/chrome-port-CxW3Pwc2.js.map +0 -1
  144. package/dist/chunks/chrome-port-PhlW29BV.js +0 -2
  145. package/dist/chunks/chrome-port-PhlW29BV.js.map +0 -1
  146. package/dist/chunks/cs-2UYO2rWf.js.map +0 -1
  147. package/dist/chunks/cs-i5K4KTFV.js +0 -2
  148. package/dist/chunks/cs-i5K4KTFV.js.map +0 -1
  149. package/dist/chunks/da-BD0O_HfV.js.map +0 -1
  150. package/dist/chunks/da-CZbhtVJO.js +0 -2
  151. package/dist/chunks/da-CZbhtVJO.js.map +0 -1
  152. package/dist/chunks/de-Bc-GoLgC.js +0 -2
  153. package/dist/chunks/de-Bc-GoLgC.js.map +0 -1
  154. package/dist/chunks/de-BkCiXPsn.js.map +0 -1
  155. package/dist/chunks/el-CcMEbl_F.js +0 -2
  156. package/dist/chunks/el-CcMEbl_F.js.map +0 -1
  157. package/dist/chunks/el-cIcxTp07.js.map +0 -1
  158. package/dist/chunks/es-BvYmomAz.js +0 -2
  159. package/dist/chunks/es-BvYmomAz.js.map +0 -1
  160. package/dist/chunks/es-CJBC_jrV.js.map +0 -1
  161. package/dist/chunks/fi-DyV7ynBf.js.map +0 -1
  162. package/dist/chunks/fi-aZR-qmZN.js +0 -2
  163. package/dist/chunks/fi-aZR-qmZN.js.map +0 -1
  164. package/dist/chunks/fr-BLQ4AIu7.js.map +0 -1
  165. package/dist/chunks/fr-BgbFAgHx.js +0 -2
  166. package/dist/chunks/fr-BgbFAgHx.js.map +0 -1
  167. package/dist/chunks/he-Bg-Bqi7r.js.map +0 -1
  168. package/dist/chunks/he-CQ4yCuja.js +0 -2
  169. package/dist/chunks/he-CQ4yCuja.js.map +0 -1
  170. package/dist/chunks/hi-DtUsj1c-.js +0 -2
  171. package/dist/chunks/hi-DtUsj1c-.js.map +0 -1
  172. package/dist/chunks/hi-wQeE43oY.js.map +0 -1
  173. package/dist/chunks/hu-D9qxzu0r.js.map +0 -1
  174. package/dist/chunks/hu-DXtscQ8_.js +0 -2
  175. package/dist/chunks/hu-DXtscQ8_.js.map +0 -1
  176. package/dist/chunks/id-BByOYpeo.js +0 -2
  177. package/dist/chunks/id-BByOYpeo.js.map +0 -1
  178. package/dist/chunks/id-Rx_wYvqy.js.map +0 -1
  179. package/dist/chunks/it-52Ip42pa.js +0 -2
  180. package/dist/chunks/it-52Ip42pa.js.map +0 -1
  181. package/dist/chunks/it-B1SRPZ3e.js.map +0 -1
  182. package/dist/chunks/ja-CMC3Parn.js +0 -2
  183. package/dist/chunks/ja-CMC3Parn.js.map +0 -1
  184. package/dist/chunks/ja-DiItm8te.js.map +0 -1
  185. package/dist/chunks/ko-3qY21q40.js +0 -2
  186. package/dist/chunks/ko-3qY21q40.js.map +0 -1
  187. package/dist/chunks/ko-CdGFWAKX.js.map +0 -1
  188. package/dist/chunks/nl-Borc5nw1.js +0 -2
  189. package/dist/chunks/nl-Borc5nw1.js.map +0 -1
  190. package/dist/chunks/nl-CmZ3vEvj.js.map +0 -1
  191. package/dist/chunks/no-BuxByZpq.js.map +0 -1
  192. package/dist/chunks/no-Do2iGedg.js +0 -2
  193. package/dist/chunks/no-Do2iGedg.js.map +0 -1
  194. package/dist/chunks/pl-jZFCnDb8.js.map +0 -1
  195. package/dist/chunks/pl-mRaky_7k.js +0 -2
  196. package/dist/chunks/pl-mRaky_7k.js.map +0 -1
  197. package/dist/chunks/port-name-BPfQKtdb.js +0 -5
  198. package/dist/chunks/port-name-BPfQKtdb.js.map +0 -1
  199. package/dist/chunks/port-name-qwB109u9.js +0 -2
  200. package/dist/chunks/port-name-qwB109u9.js.map +0 -1
  201. package/dist/chunks/pt-Cld7MwIW.js.map +0 -1
  202. package/dist/chunks/pt-DilDTXfs.js +0 -2
  203. package/dist/chunks/pt-DilDTXfs.js.map +0 -1
  204. package/dist/chunks/ro-CuKDqj3C.js.map +0 -1
  205. package/dist/chunks/ro-DF2uzPIB.js +0 -2
  206. package/dist/chunks/ro-DF2uzPIB.js.map +0 -1
  207. package/dist/chunks/ru-B7cjqJUm.js.map +0 -1
  208. package/dist/chunks/ru-YeaXnTO-.js +0 -2
  209. package/dist/chunks/ru-YeaXnTO-.js.map +0 -1
  210. package/dist/chunks/sv-2pHEvuSe.js +0 -2
  211. package/dist/chunks/sv-2pHEvuSe.js.map +0 -1
  212. package/dist/chunks/sv-D9y-M1Fo.js.map +0 -1
  213. package/dist/chunks/th-D9umBjEy.js.map +0 -1
  214. package/dist/chunks/th-u2QSDF0G.js +0 -2
  215. package/dist/chunks/th-u2QSDF0G.js.map +0 -1
  216. package/dist/chunks/tr-BddMywiw.js.map +0 -1
  217. package/dist/chunks/tr-Bhgm6_ti.js +0 -2
  218. package/dist/chunks/tr-Bhgm6_ti.js.map +0 -1
  219. package/dist/chunks/uk-7vwqsaVK.js +0 -2
  220. package/dist/chunks/uk-7vwqsaVK.js.map +0 -1
  221. package/dist/chunks/uk-Dbd31hFt.js.map +0 -1
  222. package/dist/chunks/vi-CJefLP_g.js +0 -2
  223. package/dist/chunks/vi-CJefLP_g.js.map +0 -1
  224. package/dist/chunks/vi-Do3BMOdh.js.map +0 -1
  225. package/dist/chunks/zh-D5C3BzYL.js +0 -2
  226. package/dist/chunks/zh-D5C3BzYL.js.map +0 -1
  227. package/dist/chunks/zh-gQSYLZI3.js.map +0 -1
package/dist/sw.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sw.js","sources":["../src/sw/ensure-offscreen.ts","../src/sw/forwarder.ts","../src/sw/index.ts"],"sourcesContent":["// Singleton-страж offscreen-документа. Chrome 116+ имеет\n// chrome.runtime.getContexts (Promise-overload в MV3); используем его как\n// основной путь. Race: несколько параллельных onConnect'ов в одном tick'е\n// могут вызвать ensureOffscreen одновременно — запоминаем in-flight promise,\n// чтобы каждый следующий ждал общий create.\n\ninterface EnsureOffscreenOptions {\n url: string;\n reasons: chrome.offscreen.Reason[];\n justification: string;\n}\n\nlet inflight: Promise<void> | null = null;\n\nexport async function ensureOffscreen(opts: EnsureOffscreenOptions): Promise<void> {\n if (inflight) return inflight;\n inflight = doEnsure(opts).finally(() => {\n inflight = null;\n });\n return inflight;\n}\n\nasync function doEnsure(opts: EnsureOffscreenOptions): Promise<void> {\n if (await offscreenExists(opts.url)) return;\n try {\n await chrome.offscreen.createDocument({\n url: opts.url,\n reasons: opts.reasons,\n justification: opts.justification\n });\n } catch (e) {\n // Гонка: между нашим check'ом и create'ом другой onConnect успел создать.\n // Chrome бросает 'Only a single offscreen document may be created' — это\n // OK, документ есть. Любая другая ошибка — пробрасываем.\n if (e instanceof Error && /single offscreen document/i.test(e.message)) return;\n throw e;\n }\n}\n\nasync function offscreenExists(url: string): Promise<boolean> {\n if (typeof chrome.runtime.getContexts === 'function') {\n const contexts = await chrome.runtime.getContexts({\n contextTypes: [chrome.runtime.ContextType.OFFSCREEN_DOCUMENT],\n documentUrls: [url]\n });\n return contexts.length > 0;\n }\n return false;\n}\n","// Service worker forwarder. Stateless по дизайну — единственная задача\n// маршрутизировать port'ы content↔offscreen. SW можеть умирать в любой момент\n// (после 30с idle); reconnect происходит органически: следующий content\n// runtime.connect разбудит SW, тот пересоздаст offscreen (если умер — а он\n// обычно нет) и поднимет свежий pipe.\n\nimport type { RouterOptions } from './types';\nimport { ensureOffscreen } from './ensure-offscreen';\nimport { PORT_NAME } from '../shared/port-name';\n\nconst DEFAULT_REASONS: chrome.offscreen.Reason[] = [chrome.offscreen.Reason.LOCAL_STORAGE];\nconst DEFAULT_JUSTIFICATION =\n 'Persist auth session and bootstrap cache across all extension surfaces ' +\n 'via localStorage, which is unavailable in service workers.';\n\nexport function installForwarder(opts: RouterOptions): void {\n const reasons = opts.offscreenReasons ?? DEFAULT_REASONS;\n const justification = opts.offscreenJustification ?? DEFAULT_JUSTIFICATION;\n\n chrome.runtime.onConnect.addListener((contentPort) => {\n if (contentPort.name !== PORT_NAME) return;\n\n // Поднимаем offscreen и проксируем. ensureOffscreen async — content успел\n // отправить request'ы до её резолва: буферим в queue до создания offscreen\n // port'а. Это лучше чем потерять — content всё равно тащит абсолютно всё\n // через нас.\n void connectAndPipe(contentPort, opts.offscreenUrl, reasons, justification);\n });\n}\n\nasync function connectAndPipe(\n contentPort: chrome.runtime.Port,\n offscreenUrlOrResolver: string | (() => string | Promise<string>),\n reasons: chrome.offscreen.Reason[],\n justification: string\n): Promise<void> {\n const queue: unknown[] = [];\n const queueListener = (msg: unknown): void => {\n queue.push(msg);\n };\n contentPort.onMessage.addListener(queueListener);\n\n let disconnected = false;\n contentPort.onDisconnect.addListener(() => {\n disconnected = true;\n });\n\n try {\n const offscreenUrl =\n typeof offscreenUrlOrResolver === 'function'\n ? await offscreenUrlOrResolver()\n : offscreenUrlOrResolver;\n await ensureOffscreen({ url: offscreenUrl, reasons, justification });\n } catch (e) {\n console.error('[sdk-extension/sw] ensureOffscreen failed', e);\n contentPort.disconnect();\n return;\n }\n\n if (disconnected) return;\n\n let offscreenPort: chrome.runtime.Port;\n try {\n offscreenPort = chrome.runtime.connect({ name: PORT_NAME });\n } catch (e) {\n console.error('[sdk-extension/sw] connect to offscreen failed', e);\n contentPort.disconnect();\n return;\n }\n\n // Снимаем буфер-listener, ставим прямой forwarder.\n contentPort.onMessage.removeListener(queueListener);\n contentPort.onMessage.addListener((msg) => {\n try {\n offscreenPort.postMessage(msg);\n } catch {\n /* offscreen уже отвалился — disconnect-каскад поднимет content */\n }\n });\n offscreenPort.onMessage.addListener((msg) => {\n try {\n contentPort.postMessage(msg);\n } catch {\n /* content уже отвалился */\n }\n });\n\n contentPort.onDisconnect.addListener(() => {\n try {\n offscreenPort.disconnect();\n } catch {\n /* ignore */\n }\n });\n offscreenPort.onDisconnect.addListener(() => {\n try {\n contentPort.disconnect();\n } catch {\n /* ignore */\n }\n });\n\n // Сливаем накопившийся буфер.\n for (const msg of queue) {\n try {\n offscreenPort.postMessage(msg);\n } catch {\n break;\n }\n }\n}\n","// Service worker entry. Тонкий forwarder между content-script'ами и offscreen.\n// State не держит — вся правда в offscreen, SW только маршрут. SW может\n// умирать в любой момент; следующий content runtime.connect разбудит его и\n// pipe пересоздастся.\n//\n// OAuth не проксируем — auth-flow на extension'е использует тот же\n// web-вариант, что и на сайтах: window.open на наш домен → callback в новой\n// вкладке передаёт code в offscreen через chrome.runtime сообщение.\n// chrome.identity намеренно не используется (требует chrome-extension://\n// redirect URL у провайдеров, ломает совместимость с web).\n//\n// Использование в host'е:\n// import { installRouter } from '@monetize.software/sdk-extension/sw';\n// installRouter({ offscreenUrl: chrome.runtime.getURL('offscreen.html') });\n\nimport { installForwarder } from './forwarder';\nimport type { RouterOptions } from './types';\n\nexport type { RouterOptions };\n\nexport function installRouter(opts: RouterOptions): void {\n if (typeof chrome === 'undefined' || !chrome.runtime) {\n throw new Error('@monetize.software/sdk-extension/sw requires chrome.runtime');\n }\n installForwarder(opts);\n}\n"],"names":["inflight","ensureOffscreen","opts","doEnsure","offscreenExists","e","url","DEFAULT_REASONS","DEFAULT_JUSTIFICATION","installForwarder","reasons","justification","contentPort","PORT_NAME","connectAndPipe","offscreenUrlOrResolver","queue","queueListener","msg","disconnected","offscreenUrl","offscreenPort","installRouter"],"mappings":"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"}
1
+ {"version":3,"file":"sw.js","sources":["../src/sw/ensure-offscreen.ts","../src/sw/forwarder.ts","../src/sw/index.ts"],"sourcesContent":["// Singleton-страж offscreen-документа. Chrome 116+ имеет\n// chrome.runtime.getContexts (Promise-overload в MV3); используем его как\n// основной путь. Race: несколько параллельных onConnect'ов в одном tick'е\n// могут вызвать ensureOffscreen одновременно — запоминаем in-flight promise,\n// чтобы каждый следующий ждал общий create.\n\ninterface EnsureOffscreenOptions {\n url: string;\n reasons: chrome.offscreen.Reason[];\n justification: string;\n}\n\nlet inflight: Promise<void> | null = null;\n\nexport async function ensureOffscreen(opts: EnsureOffscreenOptions): Promise<void> {\n if (inflight) return inflight;\n inflight = doEnsure(opts).finally(() => {\n inflight = null;\n });\n return inflight;\n}\n\nasync function doEnsure(opts: EnsureOffscreenOptions): Promise<void> {\n if (await offscreenExists(opts.url)) return;\n try {\n await chrome.offscreen.createDocument({\n url: opts.url,\n reasons: opts.reasons,\n justification: opts.justification\n });\n } catch (e) {\n // Гонка: между нашим check'ом и create'ом другой onConnect успел создать.\n // Chrome бросает 'Only a single offscreen document may be created' — это\n // OK, документ есть. Любая другая ошибка — пробрасываем.\n if (e instanceof Error && /single offscreen document/i.test(e.message)) return;\n throw e;\n }\n}\n\nasync function offscreenExists(url: string): Promise<boolean> {\n if (typeof chrome.runtime.getContexts === 'function') {\n const contexts = await chrome.runtime.getContexts({\n contextTypes: [chrome.runtime.ContextType.OFFSCREEN_DOCUMENT],\n documentUrls: [url]\n });\n return contexts.length > 0;\n }\n return false;\n}\n","// Service worker forwarder. Stateless по дизайну — единственная задача\n// маршрутизировать port'ы content↔offscreen. SW можеть умирать в любой момент\n// (после 30с idle); reconnect происходит органически: следующий content\n// runtime.connect разбудит SW, тот пересоздаст offscreen (если умер — а он\n// обычно нет) и поднимет свежий pipe.\n\nimport type { RouterOptions } from './types';\nimport { ensureOffscreen } from './ensure-offscreen';\nimport { PORT_NAME, RELAY_PORT_NAME } from '../shared/port-name';\n\nconst DEFAULT_REASONS: chrome.offscreen.Reason[] = [chrome.offscreen.Reason.LOCAL_STORAGE];\nconst DEFAULT_JUSTIFICATION =\n 'Persist auth session and bootstrap cache across all extension surfaces ' +\n 'via localStorage, which is unavailable in service workers.';\n\nexport function installForwarder(opts: RouterOptions): void {\n const reasons = opts.offscreenReasons ?? DEFAULT_REASONS;\n const justification = opts.offscreenJustification ?? DEFAULT_JUSTIFICATION;\n\n chrome.runtime.onConnect.addListener((contentPort) => {\n if (contentPort.name !== PORT_NAME) return;\n\n // Поднимаем offscreen и проксируем. ensureOffscreen async — content успел\n // отправить request'ы до её резолва: буферим в queue до создания offscreen\n // port'а. Это лучше чем потерять — content всё равно тащит абсолютно всё\n // через нас.\n void connectAndPipe(contentPort, opts.offscreenUrl, reasons, justification);\n });\n}\n\nasync function connectAndPipe(\n contentPort: chrome.runtime.Port,\n offscreenUrlOrResolver: string | (() => string | Promise<string>),\n reasons: chrome.offscreen.Reason[],\n justification: string\n): Promise<void> {\n const queue: unknown[] = [];\n const queueListener = (msg: unknown): void => {\n queue.push(msg);\n };\n contentPort.onMessage.addListener(queueListener);\n\n let disconnected = false;\n contentPort.onDisconnect.addListener(() => {\n disconnected = true;\n });\n\n try {\n const offscreenUrl =\n typeof offscreenUrlOrResolver === 'function'\n ? await offscreenUrlOrResolver()\n : offscreenUrlOrResolver;\n await ensureOffscreen({ url: offscreenUrl, reasons, justification });\n } catch (e) {\n console.error('[sdk-extension/sw] ensureOffscreen failed', e);\n contentPort.disconnect();\n return;\n }\n\n if (disconnected) return;\n\n let offscreenPort: chrome.runtime.Port;\n try {\n // Используем отдельное имя relay-порта (не PORT_NAME), чтобы offscreen\n // принимал только SW-relay подключения и игнорировал direct connect'ы\n // от popup/content (которые тоже триггерят onConnect в offscreen — в MV3\n // chrome.runtime.connect доставляется во ВСЕ extension contexts с\n // onConnect listener'ом, не только в SW).\n offscreenPort = chrome.runtime.connect({ name: RELAY_PORT_NAME });\n } catch (e) {\n console.error('[sdk-extension/sw] connect to offscreen failed', e);\n contentPort.disconnect();\n return;\n }\n\n // Снимаем буфер-listener, ставим прямой forwarder.\n contentPort.onMessage.removeListener(queueListener);\n contentPort.onMessage.addListener((msg) => {\n try {\n offscreenPort.postMessage(msg);\n } catch {\n /* offscreen уже отвалился — disconnect-каскад поднимет content */\n }\n });\n offscreenPort.onMessage.addListener((msg) => {\n try {\n contentPort.postMessage(msg);\n } catch {\n /* content уже отвалился */\n }\n });\n\n contentPort.onDisconnect.addListener(() => {\n try {\n offscreenPort.disconnect();\n } catch {\n /* ignore */\n }\n });\n offscreenPort.onDisconnect.addListener(() => {\n try {\n contentPort.disconnect();\n } catch {\n /* ignore */\n }\n });\n\n // Сливаем накопившийся буфер.\n for (const msg of queue) {\n try {\n offscreenPort.postMessage(msg);\n } catch {\n break;\n }\n }\n}\n","// Service worker entry. Тонкий forwarder между content-script'ами и offscreen.\n// State не держит — вся правда в offscreen, SW только маршрут. SW может\n// умирать в любой момент; следующий content runtime.connect разбудит его и\n// pipe пересоздастся.\n//\n// OAuth не проксируем — auth-flow на extension'е использует тот же\n// web-вариант, что и на сайтах: window.open на наш домен → callback в новой\n// вкладке передаёт code в offscreen через chrome.runtime сообщение.\n// chrome.identity намеренно не используется (требует chrome-extension://\n// redirect URL у провайдеров, ломает совместимость с web).\n//\n// Использование в host'е:\n// import { installRouter } from '@monetize.software/sdk-extension/sw';\n// installRouter({ offscreenUrl: chrome.runtime.getURL('offscreen.html') });\n\nimport { installForwarder } from './forwarder';\nimport type { RouterOptions } from './types';\n\nexport type { RouterOptions };\n\nexport function installRouter(opts: RouterOptions): void {\n if (typeof chrome === 'undefined' || !chrome.runtime) {\n throw new Error('@monetize.software/sdk-extension/sw requires chrome.runtime');\n }\n installForwarder(opts);\n}\n"],"names":["inflight","ensureOffscreen","opts","doEnsure","offscreenExists","e","url","DEFAULT_REASONS","DEFAULT_JUSTIFICATION","installForwarder","reasons","justification","contentPort","PORT_NAME","connectAndPipe","offscreenUrlOrResolver","queue","queueListener","msg","disconnected","offscreenUrl","offscreenPort","RELAY_PORT_NAME","installRouter"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monetize.software/sdk-extension",
3
- "version": "3.0.0-alpha.8",
3
+ "version": "3.0.0-beta.0",
4
4
  "description": "Monetize SDK for Chrome extensions — single source of truth via offscreen document, drop-in compatible with @monetize.software/sdk public API",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -40,7 +40,7 @@
40
40
  "preact": "^10.24.0"
41
41
  },
42
42
  "peerDependencies": {
43
- "@monetize.software/sdk": "3.0.0-alpha.7"
43
+ "@monetize.software/sdk": "3.0.0-beta.0"
44
44
  },
45
45
  "peerDependenciesMeta": {
46
46
  "@monetize.software/sdk": {
@@ -58,7 +58,7 @@
58
58
  "vite": "^6.0.5",
59
59
  "vite-plugin-dts": "^4.3.0",
60
60
  "vitest": "^2.1.8",
61
- "@monetize.software/sdk": "3.0.0-alpha.7"
61
+ "@monetize.software/sdk": "3.0.0-beta.0"
62
62
  },
63
63
  "scripts": {
64
64
  "dev": "vite",
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e={"anon.heading_default":"متابعة كضيف","anon.try_again":"حاول مرة أخرى","auth.check_email_message":"تحقق من بريدك الإلكتروني للحصول على رمز التأكيد.","auth.check_email_title":"تحقق من بريدك الإلكتروني","auth.confirmation_code":"رمز التأكيد","auth.continue_with_apple":"المتابعة مع Apple","auth.continue_with_facebook":"متابعة مع Facebook","auth.continue_with_github":"متابعة مع GitHub","auth.continue_with_google":"المتابعة مع Google","auth.create_account":"إنشاء حساب","auth.default_subtitle":"سجّل الدخول للوصول إلى جميع الميزات ومزامنة بياناتك.","auth.email":"عنوان البريد الإلكتروني","auth.email_exists":"يوجد حساب بهذا البريد الإلكتروني بالفعل.","auth.email_not_confirmed":"يرجى تأكيد بريدك الإلكتروني أولاً.","auth.forgot_password":"هل نسيت كلمة المرور؟","auth.forgot_password_title":"هل نسيت كلمة المرور؟","auth.forgot_subtitle":"أدخل بريدك الإلكتروني وسنرسل لك رابط إعادة تعيين كلمة المرور.","auth.generic_error":"حدث خطأ ما","auth.have_account":"لديك حساب؟","auth.hide_password":"إخفاء كلمة المرور","auth.invalid_credentials":"البريد الإلكتروني أو كلمة المرور غير صحيحة","auth.invalid_otp":"الرمز غير صالح أو منتهي الصلاحية.","auth.last_used_no_email":"الأخير","auth.link_purchase_subheading":"سنربط الشراء بحسابك للحفاظ على الوصول.","auth.log_in":"تسجيل الدخول","auth.log_in_link":"تسجيل الدخول","auth.login_continue_purchase":"سجّل الدخول لمتابعة عملية الشراء","auth.network_error":"خطأ في الشبكة. تحقق من اتصالك وحاول مرة أخرى.","auth.no_account":"ليس لديك حساب؟","auth.or":"أو","auth.password":"كلمة المرور","auth.passwords_mismatch":"كلمتا المرور غير متطابقتين","auth.rate_limited":"طلبات كثيرة جدًا. حاول مرة أخرى بعد قليل.","auth.repeat_password":"كرّر كلمة المرور","auth.reset_password_title":"إعادة تعيين كلمة المرور","auth.reset_sent_message":"إذا كان هذا البريد موجودًا، فقد تم إرسال رمز إعادة التعيين.","auth.restore_purchases_heading":"استعادة المشتريات","auth.restore_purchases_subheading":"يُرجى تسجيل الدخول لاستعادة مشترياتك.","auth.send_reset":"إرسال بريد إعادة التعيين","auth.service_unavailable":"الخدمة غير متاحة مؤقتًا. حاول لاحقًا.","auth.show_password":"إظهار كلمة المرور","auth.sign_out":"تسجيل الخروج","auth.sign_up":"إنشاء حساب","auth.sign_up_link":"إنشاء حساب","auth.signed_in":"تم تسجيل الدخول","auth.signin_failed":"فشل تسجيل الدخول","auth.signup_failed":"فشل التسجيل","auth.verify":"تأكيد","auth.weak_password":"كلمة المرور ضعيفة جدًا.","auth.welcome":"مرحباً!","auth.welcome_signup":"مرحبًا!","countdown.d":"ي","countdown.h":"س","countdown.m":"د","countdown.s":"ث","cta.close":"إغلاق","cta.continue":"متابعة","cta.get_lifetime_access":"احصل على وصول مدى الحياة","cta.get_plan_daily":"احصل على الخطة اليومية","cta.get_plan_monthly":"احصل على الخطة الشهرية","cta.get_plan_weekly":"احصل على الخطة الأسبوعية","cta.get_plan_yearly":"احصل على الخطة السنوية","cta.start_trial":"ابدأ تجربة مجانية لمدة {days} يوم","modal.close_aria":"إغلاق","modal.continue":"متابعة","modal.error_generic":"حدث خطأ ما","modal.loading":"جارٍ التحميل…","modal.purchase_restored_subtitle":"مرحبًا بعودتك — اشتراكك نشط بالفعل.","modal.purchase_restored_title":"تمت استعادة الاشتراك","modal.purchase_success_subtitle":"اشتراكك نشط الآن.","modal.purchase_success_title":"تم استلام الدفع","modal.verifying_subscription":"جارٍ التحقق من اشتراكك…","nav.back":"→ رجوع","nav.back_aria":"رجوع","offer.limited_time":"عرض لفترة محدودة","payment.awaiting_title":"أكمل الدفع في علامة التبويب الجديدة","payment.checking":"جارٍ التحقق…","payment.ive_paid":"لقد دفعت","payment.open_checkout_again":"افتح الدفع مرة أخرى","payment.open_checkout_button":"افتح الدفع","pricing.free_trial_days":"تجربة مجانية لمدة {days} يومًا","pricing.included_per":"متضمن لكل {interval}:","pricing.interval.day":"يوم","pricing.interval.lifetime_short":"مدى الحياة","pricing.interval.month":"شهر","pricing.interval.period":"فترة","pricing.interval.week":"أسبوع","pricing.interval.year":"سنة","pricing.money_back":"ضمان استرداد الأموال لمدة 30 يومًا","pricing.most_popular":"الأكثر شعبية","pricing.no_prices":"لا توجد أسعار متاحة.","pricing.plan_label.daily":"الخطة اليومية","pricing.plan_label.lifetime":"مدى الحياة","pricing.plan_label.monthly":"خطة شهرية","pricing.plan_label.weekly":"خطة أسبوعية","pricing.plan_label.yearly":"خطة سنوية","pricing.plans_aria":"الخطط","session.contact_support":"اتصل بالدعم","session.restore_purchases":"استعادة المشتريات","session.sign_out":"تسجيل الخروج","session.signed_in_as_prefix":"تم تسجيل الدخول باسم","session.signing_out":"جارٍ تسجيل الخروج…","support.attachments_label":"المرفقات","support.close_button":"إغلاق","support.done_button":"تم","support.email_placeholder":"أدخل بريدك الإلكتروني","support.heading":"الدعم","support.instruction":"يُرجى ملء النموذج أدناه لإرسال طلب الدعم.","support.invalid_email":"بريد إلكتروني غير صالح","support.message_length":"1-5000 حرفاً","support.message_placeholder":"أدخل رسالتك","support.required":"مطلوب","support.send_another":"إرسال طلب آخر","support.send_button":"إرسال","support.sending":"جارٍ الإرسال…","support.subject_length":"3-200 حرفاً","support.subject_placeholder":"أدخل الموضوع","support.success_heading":"تم إرسال الطلب","support.success_message_prefix":"لقد تلقينا رسالتك وسنرد على"};exports.default=e;
2
- //# sourceMappingURL=ar-BUQInJ5a.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ar-BUQInJ5a.js","sources":["../../../sdk/src/ui/i18n/locales/ar.ts"],"sourcesContent":["/**\n * Static-translations для ar. Сгенерировано из:\n * - `online/lang/static-translations.ts` (legacy, через KEY_MAP)\n * - `tools/sdk-translations.mjs` (SDK-specific строки)\n *\n * Не править вручную — изменения теряются при следующем `node tools/gen-locales.mjs`.\n * Чтобы исправить перевод — править legacy/sdk-translations.mjs и регенерить.\n */\nconst ar = {\n 'anon.heading_default': 'متابعة كضيف',\n 'anon.try_again': 'حاول مرة أخرى',\n 'auth.check_email_message': 'تحقق من بريدك الإلكتروني للحصول على رمز التأكيد.',\n 'auth.check_email_title': 'تحقق من بريدك الإلكتروني',\n 'auth.confirmation_code': 'رمز التأكيد',\n 'auth.continue_with_apple': 'المتابعة مع Apple',\n 'auth.continue_with_facebook': 'متابعة مع Facebook',\n 'auth.continue_with_github': 'متابعة مع GitHub',\n 'auth.continue_with_google': 'المتابعة مع Google',\n 'auth.create_account': 'إنشاء حساب',\n 'auth.default_subtitle': 'سجّل الدخول للوصول إلى جميع الميزات ومزامنة بياناتك.',\n 'auth.email': 'عنوان البريد الإلكتروني',\n 'auth.email_exists': 'يوجد حساب بهذا البريد الإلكتروني بالفعل.',\n 'auth.email_not_confirmed': 'يرجى تأكيد بريدك الإلكتروني أولاً.',\n 'auth.forgot_password': 'هل نسيت كلمة المرور؟',\n 'auth.forgot_password_title': 'هل نسيت كلمة المرور؟',\n 'auth.forgot_subtitle': 'أدخل بريدك الإلكتروني وسنرسل لك رابط إعادة تعيين كلمة المرور.',\n 'auth.generic_error': 'حدث خطأ ما',\n 'auth.have_account': 'لديك حساب؟',\n 'auth.hide_password': 'إخفاء كلمة المرور',\n 'auth.invalid_credentials': 'البريد الإلكتروني أو كلمة المرور غير صحيحة',\n 'auth.invalid_otp': 'الرمز غير صالح أو منتهي الصلاحية.',\n 'auth.last_used_no_email': 'الأخير',\n 'auth.link_purchase_subheading': 'سنربط الشراء بحسابك للحفاظ على الوصول.',\n 'auth.log_in': 'تسجيل الدخول',\n 'auth.log_in_link': 'تسجيل الدخول',\n 'auth.login_continue_purchase': 'سجّل الدخول لمتابعة عملية الشراء',\n 'auth.network_error': 'خطأ في الشبكة. تحقق من اتصالك وحاول مرة أخرى.',\n 'auth.no_account': 'ليس لديك حساب؟',\n 'auth.or': 'أو',\n 'auth.password': 'كلمة المرور',\n 'auth.passwords_mismatch': 'كلمتا المرور غير متطابقتين',\n 'auth.rate_limited': 'طلبات كثيرة جدًا. حاول مرة أخرى بعد قليل.',\n 'auth.repeat_password': 'كرّر كلمة المرور',\n 'auth.reset_password_title': 'إعادة تعيين كلمة المرور',\n 'auth.reset_sent_message': 'إذا كان هذا البريد موجودًا، فقد تم إرسال رمز إعادة التعيين.',\n 'auth.restore_purchases_heading': 'استعادة المشتريات',\n 'auth.restore_purchases_subheading': 'يُرجى تسجيل الدخول لاستعادة مشترياتك.',\n 'auth.send_reset': 'إرسال بريد إعادة التعيين',\n 'auth.service_unavailable': 'الخدمة غير متاحة مؤقتًا. حاول لاحقًا.',\n 'auth.show_password': 'إظهار كلمة المرور',\n 'auth.sign_out': 'تسجيل الخروج',\n 'auth.sign_up': 'إنشاء حساب',\n 'auth.sign_up_link': 'إنشاء حساب',\n 'auth.signed_in': 'تم تسجيل الدخول',\n 'auth.signin_failed': 'فشل تسجيل الدخول',\n 'auth.signup_failed': 'فشل التسجيل',\n 'auth.verify': 'تأكيد',\n 'auth.weak_password': 'كلمة المرور ضعيفة جدًا.',\n 'auth.welcome': 'مرحباً!',\n 'auth.welcome_signup': 'مرحبًا!',\n 'countdown.d': 'ي',\n 'countdown.h': 'س',\n 'countdown.m': 'د',\n 'countdown.s': 'ث',\n 'cta.close': 'إغلاق',\n 'cta.continue': 'متابعة',\n 'cta.get_lifetime_access': 'احصل على وصول مدى الحياة',\n 'cta.get_plan_daily': 'احصل على الخطة اليومية',\n 'cta.get_plan_monthly': 'احصل على الخطة الشهرية',\n 'cta.get_plan_weekly': 'احصل على الخطة الأسبوعية',\n 'cta.get_plan_yearly': 'احصل على الخطة السنوية',\n 'cta.start_trial': 'ابدأ تجربة مجانية لمدة {days} يوم',\n 'modal.close_aria': 'إغلاق',\n 'modal.continue': 'متابعة',\n 'modal.error_generic': 'حدث خطأ ما',\n 'modal.loading': 'جارٍ التحميل…',\n 'modal.purchase_restored_subtitle': 'مرحبًا بعودتك — اشتراكك نشط بالفعل.',\n 'modal.purchase_restored_title': 'تمت استعادة الاشتراك',\n 'modal.purchase_success_subtitle': 'اشتراكك نشط الآن.',\n 'modal.purchase_success_title': 'تم استلام الدفع',\n 'modal.verifying_subscription': 'جارٍ التحقق من اشتراكك…',\n 'nav.back': '→ رجوع',\n 'nav.back_aria': 'رجوع',\n 'offer.limited_time': 'عرض لفترة محدودة',\n 'payment.awaiting_title': 'أكمل الدفع في علامة التبويب الجديدة',\n 'payment.checking': 'جارٍ التحقق…',\n 'payment.ive_paid': 'لقد دفعت',\n 'payment.open_checkout_again': 'افتح الدفع مرة أخرى',\n 'payment.open_checkout_button': 'افتح الدفع',\n 'pricing.free_trial_days': 'تجربة مجانية لمدة {days} يومًا',\n 'pricing.included_per': 'متضمن لكل {interval}:',\n 'pricing.interval.day': 'يوم',\n 'pricing.interval.lifetime_short': 'مدى الحياة',\n 'pricing.interval.month': 'شهر',\n 'pricing.interval.period': 'فترة',\n 'pricing.interval.week': 'أسبوع',\n 'pricing.interval.year': 'سنة',\n 'pricing.money_back': 'ضمان استرداد الأموال لمدة 30 يومًا',\n 'pricing.most_popular': 'الأكثر شعبية',\n 'pricing.no_prices': 'لا توجد أسعار متاحة.',\n 'pricing.plan_label.daily': 'الخطة اليومية',\n 'pricing.plan_label.lifetime': 'مدى الحياة',\n 'pricing.plan_label.monthly': 'خطة شهرية',\n 'pricing.plan_label.weekly': 'خطة أسبوعية',\n 'pricing.plan_label.yearly': 'خطة سنوية',\n 'pricing.plans_aria': 'الخطط',\n 'session.contact_support': 'اتصل بالدعم',\n 'session.restore_purchases': 'استعادة المشتريات',\n 'session.sign_out': 'تسجيل الخروج',\n 'session.signed_in_as_prefix': 'تم تسجيل الدخول باسم',\n 'session.signing_out': 'جارٍ تسجيل الخروج…',\n 'support.attachments_label': 'المرفقات',\n 'support.close_button': 'إغلاق',\n 'support.done_button': 'تم',\n 'support.email_placeholder': 'أدخل بريدك الإلكتروني',\n 'support.heading': 'الدعم',\n 'support.instruction': 'يُرجى ملء النموذج أدناه لإرسال طلب الدعم.',\n 'support.invalid_email': 'بريد إلكتروني غير صالح',\n 'support.message_length': '1-5000 حرفاً',\n 'support.message_placeholder': 'أدخل رسالتك',\n 'support.required': 'مطلوب',\n 'support.send_another': 'إرسال طلب آخر',\n 'support.send_button': 'إرسال',\n 'support.sending': 'جارٍ الإرسال…',\n 'support.subject_length': '3-200 حرفاً',\n 'support.subject_placeholder': 'أدخل الموضوع',\n 'support.success_heading': 'تم إرسال الطلب',\n 'support.success_message_prefix': 'لقد تلقينا رسالتك وسنرد على'\n} as const;\n\nexport default ar;\n"],"names":["ar"],"mappings":"gFAQA,MAAMA,EAAK,CACT,uBAAwB,cACxB,iBAAkB,gBAClB,2BAA4B,mDAC5B,yBAA0B,2BAC1B,yBAA0B,cAC1B,2BAA4B,oBAC5B,8BAA+B,qBAC/B,4BAA6B,mBAC7B,4BAA6B,qBAC7B,sBAAuB,aACvB,wBAAyB,uDACzB,aAAc,0BACd,oBAAqB,2CACrB,2BAA4B,qCAC5B,uBAAwB,uBACxB,6BAA8B,uBAC9B,uBAAwB,gEACxB,qBAAsB,aACtB,oBAAqB,aACrB,qBAAsB,oBACtB,2BAA4B,6CAC5B,mBAAoB,oCACpB,0BAA2B,SAC3B,gCAAiC,yCACjC,cAAe,eACf,mBAAoB,eACpB,+BAAgC,mCAChC,qBAAsB,gDACtB,kBAAmB,iBACnB,UAAW,KACX,gBAAiB,cACjB,0BAA2B,6BAC3B,oBAAqB,4CACrB,uBAAwB,mBACxB,4BAA6B,0BAC7B,0BAA2B,8DAC3B,iCAAkC,oBAClC,oCAAqC,wCACrC,kBAAmB,2BACnB,2BAA4B,wCAC5B,qBAAsB,oBACtB,gBAAiB,eACjB,eAAgB,aAChB,oBAAqB,aACrB,iBAAkB,kBAClB,qBAAsB,mBACtB,qBAAsB,cACtB,cAAe,QACf,qBAAsB,0BACtB,eAAgB,UAChB,sBAAuB,UACvB,cAAe,IACf,cAAe,IACf,cAAe,IACf,cAAe,IACf,YAAa,QACb,eAAgB,SAChB,0BAA2B,2BAC3B,qBAAsB,yBACtB,uBAAwB,yBACxB,sBAAuB,2BACvB,sBAAuB,yBACvB,kBAAmB,oCACnB,mBAAoB,QACpB,iBAAkB,SAClB,sBAAuB,aACvB,gBAAiB,gBACjB,mCAAoC,sCACpC,gCAAiC,uBACjC,kCAAmC,oBACnC,+BAAgC,kBAChC,+BAAgC,0BAChC,WAAY,SACZ,gBAAiB,OACjB,qBAAsB,mBACtB,yBAA0B,sCAC1B,mBAAoB,eACpB,mBAAoB,WACpB,8BAA+B,sBAC/B,+BAAgC,aAChC,0BAA2B,iCAC3B,uBAAwB,wBACxB,uBAAwB,MACxB,kCAAmC,aACnC,yBAA0B,MAC1B,0BAA2B,OAC3B,wBAAyB,QACzB,wBAAyB,MACzB,qBAAsB,qCACtB,uBAAwB,eACxB,oBAAqB,uBACrB,2BAA4B,gBAC5B,8BAA+B,aAC/B,6BAA8B,YAC9B,4BAA6B,cAC7B,4BAA6B,YAC7B,qBAAsB,QACtB,0BAA2B,cAC3B,4BAA6B,oBAC7B,mBAAoB,eACpB,8BAA+B,uBAC/B,sBAAuB,qBACvB,4BAA6B,WAC7B,uBAAwB,QACxB,sBAAuB,KACvB,4BAA6B,wBAC7B,kBAAmB,QACnB,sBAAuB,4CACvB,wBAAyB,yBACzB,yBAA0B,eAC1B,8BAA+B,cAC/B,mBAAoB,QACpB,uBAAwB,gBACxB,sBAAuB,QACvB,kBAAmB,gBACnB,yBAA0B,cAC1B,8BAA+B,eAC/B,0BAA2B,iBAC3B,iCAAkC,6BACpC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ar-nh4l4WDE.js","sources":["../../../sdk/src/ui/i18n/locales/ar.ts"],"sourcesContent":["/**\n * Static-translations для ar. Сгенерировано из:\n * - `online/lang/static-translations.ts` (legacy, через KEY_MAP)\n * - `tools/sdk-translations.mjs` (SDK-specific строки)\n *\n * Не править вручную — изменения теряются при следующем `node tools/gen-locales.mjs`.\n * Чтобы исправить перевод — править legacy/sdk-translations.mjs и регенерить.\n */\nconst ar = {\n 'anon.heading_default': 'متابعة كضيف',\n 'anon.try_again': 'حاول مرة أخرى',\n 'auth.check_email_message': 'تحقق من بريدك الإلكتروني للحصول على رمز التأكيد.',\n 'auth.check_email_title': 'تحقق من بريدك الإلكتروني',\n 'auth.confirmation_code': 'رمز التأكيد',\n 'auth.continue_with_apple': 'المتابعة مع Apple',\n 'auth.continue_with_facebook': 'متابعة مع Facebook',\n 'auth.continue_with_github': 'متابعة مع GitHub',\n 'auth.continue_with_google': 'المتابعة مع Google',\n 'auth.create_account': 'إنشاء حساب',\n 'auth.default_subtitle': 'سجّل الدخول للوصول إلى جميع الميزات ومزامنة بياناتك.',\n 'auth.email': 'عنوان البريد الإلكتروني',\n 'auth.email_exists': 'يوجد حساب بهذا البريد الإلكتروني بالفعل.',\n 'auth.email_not_confirmed': 'يرجى تأكيد بريدك الإلكتروني أولاً.',\n 'auth.forgot_password': 'هل نسيت كلمة المرور؟',\n 'auth.forgot_password_title': 'هل نسيت كلمة المرور؟',\n 'auth.forgot_subtitle': 'أدخل بريدك الإلكتروني وسنرسل لك رابط إعادة تعيين كلمة المرور.',\n 'auth.generic_error': 'حدث خطأ ما',\n 'auth.have_account': 'لديك حساب؟',\n 'auth.hide_password': 'إخفاء كلمة المرور',\n 'auth.invalid_credentials': 'البريد الإلكتروني أو كلمة المرور غير صحيحة',\n 'auth.invalid_otp': 'الرمز غير صالح أو منتهي الصلاحية.',\n 'auth.last_used_no_email': 'الأخير',\n 'auth.link_purchase_subheading': 'سنربط الشراء بحسابك للحفاظ على الوصول.',\n 'auth.log_in': 'تسجيل الدخول',\n 'auth.log_in_link': 'تسجيل الدخول',\n 'auth.login_continue_purchase': 'سجّل الدخول لمتابعة عملية الشراء',\n 'auth.network_error': 'خطأ في الشبكة. تحقق من اتصالك وحاول مرة أخرى.',\n 'auth.no_account': 'ليس لديك حساب؟',\n 'auth.or': 'أو',\n 'auth.password': 'كلمة المرور',\n 'auth.passwords_mismatch': 'كلمتا المرور غير متطابقتين',\n 'auth.rate_limited': 'طلبات كثيرة جدًا. حاول مرة أخرى بعد قليل.',\n 'auth.repeat_password': 'كرّر كلمة المرور',\n 'auth.reset_password_title': 'إعادة تعيين كلمة المرور',\n 'auth.reset_sent_message': 'إذا كان هذا البريد موجودًا، فقد تم إرسال رمز إعادة التعيين.',\n 'auth.restore_purchases_heading': 'استعادة المشتريات',\n 'auth.restore_purchases_subheading': 'يُرجى تسجيل الدخول لاستعادة مشترياتك.',\n 'auth.send_reset': 'إرسال بريد إعادة التعيين',\n 'auth.service_unavailable': 'الخدمة غير متاحة مؤقتًا. حاول لاحقًا.',\n 'auth.show_password': 'إظهار كلمة المرور',\n 'auth.sign_out': 'تسجيل الخروج',\n 'auth.sign_up': 'إنشاء حساب',\n 'auth.sign_up_link': 'إنشاء حساب',\n 'auth.signed_in': 'تم تسجيل الدخول',\n 'auth.signin_failed': 'فشل تسجيل الدخول',\n 'auth.signup_failed': 'فشل التسجيل',\n 'auth.verify': 'تأكيد',\n 'auth.weak_password': 'كلمة المرور ضعيفة جدًا.',\n 'auth.welcome': 'مرحباً!',\n 'auth.welcome_signup': 'مرحبًا!',\n 'countdown.d': 'ي',\n 'countdown.h': 'س',\n 'countdown.m': 'د',\n 'countdown.s': 'ث',\n 'cta.close': 'إغلاق',\n 'cta.continue': 'متابعة',\n 'cta.get_lifetime_access': 'احصل على وصول مدى الحياة',\n 'cta.get_plan_daily': 'احصل على الخطة اليومية',\n 'cta.get_plan_monthly': 'احصل على الخطة الشهرية',\n 'cta.get_plan_weekly': 'احصل على الخطة الأسبوعية',\n 'cta.get_plan_yearly': 'احصل على الخطة السنوية',\n 'cta.start_trial': 'ابدأ تجربة مجانية لمدة {days} يوم',\n 'modal.close_aria': 'إغلاق',\n 'modal.continue': 'متابعة',\n 'modal.error_generic': 'حدث خطأ ما',\n 'modal.loading': 'جارٍ التحميل…',\n 'modal.purchase_restored_subtitle': 'مرحبًا بعودتك — اشتراكك نشط بالفعل.',\n 'modal.purchase_restored_title': 'تمت استعادة الاشتراك',\n 'modal.purchase_success_subtitle': 'اشتراكك نشط الآن.',\n 'modal.purchase_success_title': 'تم استلام الدفع',\n 'modal.verifying_subscription': 'جارٍ التحقق من اشتراكك…',\n 'nav.back': '→ رجوع',\n 'nav.back_aria': 'رجوع',\n 'offer.limited_time': 'عرض لفترة محدودة',\n 'payment.awaiting_title': 'أكمل الدفع في علامة التبويب الجديدة',\n 'payment.checking': 'جارٍ التحقق…',\n 'payment.ive_paid': 'لقد دفعت',\n 'payment.open_checkout_again': 'افتح الدفع مرة أخرى',\n 'payment.open_checkout_button': 'افتح الدفع',\n 'pricing.free_trial_days': 'تجربة مجانية لمدة {days} يومًا',\n 'pricing.included_per': 'متضمن لكل {interval}:',\n 'pricing.interval.day': 'يوم',\n 'pricing.interval.lifetime_short': 'مدى الحياة',\n 'pricing.interval.month': 'شهر',\n 'pricing.interval.period': 'فترة',\n 'pricing.interval.week': 'أسبوع',\n 'pricing.interval.year': 'سنة',\n 'pricing.money_back': 'ضمان استرداد الأموال لمدة 30 يومًا',\n 'pricing.most_popular': 'الأكثر شعبية',\n 'pricing.no_prices': 'لا توجد أسعار متاحة.',\n 'pricing.plan_label.daily': 'الخطة اليومية',\n 'pricing.plan_label.lifetime': 'مدى الحياة',\n 'pricing.plan_label.monthly': 'خطة شهرية',\n 'pricing.plan_label.weekly': 'خطة أسبوعية',\n 'pricing.plan_label.yearly': 'خطة سنوية',\n 'pricing.plans_aria': 'الخطط',\n 'session.contact_support': 'اتصل بالدعم',\n 'session.restore_purchases': 'استعادة المشتريات',\n 'session.sign_out': 'تسجيل الخروج',\n 'session.signed_in_as_prefix': 'تم تسجيل الدخول باسم',\n 'session.signing_out': 'جارٍ تسجيل الخروج…',\n 'support.attachments_label': 'المرفقات',\n 'support.close_button': 'إغلاق',\n 'support.done_button': 'تم',\n 'support.email_placeholder': 'أدخل بريدك الإلكتروني',\n 'support.heading': 'الدعم',\n 'support.instruction': 'يُرجى ملء النموذج أدناه لإرسال طلب الدعم.',\n 'support.invalid_email': 'بريد إلكتروني غير صالح',\n 'support.message_length': '1-5000 حرفاً',\n 'support.message_placeholder': 'أدخل رسالتك',\n 'support.required': 'مطلوب',\n 'support.send_another': 'إرسال طلب آخر',\n 'support.send_button': 'إرسال',\n 'support.sending': 'جارٍ الإرسال…',\n 'support.subject_length': '3-200 حرفاً',\n 'support.subject_placeholder': 'أدخل الموضوع',\n 'support.success_heading': 'تم إرسال الطلب',\n 'support.success_message_prefix': 'لقد تلقينا رسالتك وسنرد على'\n} as const;\n\nexport default ar;\n"],"names":["ar"],"mappings":"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"}