fundus 0.28.1 → 0.29.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 (179) hide show
  1. package/README.md +41 -33
  2. package/build/client/_app/immutable/chunks/{OL1Dh1oP.js → BCmR1_e0.js} +1 -1
  3. package/build/client/_app/immutable/chunks/BCmR1_e0.js.br +0 -0
  4. package/build/client/_app/immutable/chunks/BCmR1_e0.js.gz +0 -0
  5. package/build/client/_app/immutable/chunks/{apKHI4vq.js → C0uU_Rhe.js} +2 -2
  6. package/build/client/_app/immutable/chunks/C0uU_Rhe.js.br +0 -0
  7. package/build/client/_app/immutable/chunks/C0uU_Rhe.js.gz +0 -0
  8. package/build/client/_app/immutable/chunks/{g2rma9Ym.js → CMJ10zbJ.js} +1 -1
  9. package/build/client/_app/immutable/chunks/CMJ10zbJ.js.br +0 -0
  10. package/build/client/_app/immutable/chunks/CMJ10zbJ.js.gz +0 -0
  11. package/build/client/_app/immutable/chunks/{QlQ-jeIO.js → kkVEh3_1.js} +1 -1
  12. package/build/client/_app/immutable/chunks/kkVEh3_1.js.br +2 -0
  13. package/build/client/_app/immutable/chunks/kkVEh3_1.js.gz +0 -0
  14. package/build/client/_app/immutable/chunks/wBLhaPea.js +1 -0
  15. package/build/client/_app/immutable/chunks/wBLhaPea.js.br +0 -0
  16. package/build/client/_app/immutable/chunks/wBLhaPea.js.gz +0 -0
  17. package/build/client/_app/immutable/entry/{app.DpZM49_s.js → app.DCXSqiQ1.js} +2 -2
  18. package/build/client/_app/immutable/entry/app.DCXSqiQ1.js.br +0 -0
  19. package/build/client/_app/immutable/entry/app.DCXSqiQ1.js.gz +0 -0
  20. package/build/client/_app/immutable/entry/start.BOUpxuMU.js +1 -0
  21. package/build/client/_app/immutable/entry/start.BOUpxuMU.js.br +0 -0
  22. package/build/client/_app/immutable/entry/start.BOUpxuMU.js.gz +0 -0
  23. package/build/client/_app/immutable/nodes/{0.Wqvn8XD-.js → 0.CsqkK05g.js} +1 -1
  24. package/build/client/_app/immutable/nodes/0.CsqkK05g.js.br +0 -0
  25. package/build/client/_app/immutable/nodes/0.CsqkK05g.js.gz +0 -0
  26. package/build/client/_app/immutable/nodes/{1.Z-UvvLkP.js → 1.BVSXvtU9.js} +1 -1
  27. package/build/client/_app/immutable/nodes/1.BVSXvtU9.js.br +2 -0
  28. package/build/client/_app/immutable/nodes/1.BVSXvtU9.js.gz +0 -0
  29. package/build/client/_app/immutable/nodes/{2.lu89W_qJ.js → 2.BJEXWmrT.js} +1 -1
  30. package/build/client/_app/immutable/nodes/2.BJEXWmrT.js.br +0 -0
  31. package/build/client/_app/immutable/nodes/2.BJEXWmrT.js.gz +0 -0
  32. package/build/client/_app/immutable/nodes/{3.Dt32EAoq.js → 3.BDMmDyL1.js} +1 -1
  33. package/build/client/_app/immutable/nodes/3.BDMmDyL1.js.br +0 -0
  34. package/build/client/_app/immutable/nodes/3.BDMmDyL1.js.gz +0 -0
  35. package/build/client/_app/immutable/nodes/{4.WipzcX8_.js → 4.dd49_qQE.js} +1 -1
  36. package/build/client/_app/immutable/nodes/4.dd49_qQE.js.br +0 -0
  37. package/build/client/_app/immutable/nodes/4.dd49_qQE.js.gz +0 -0
  38. package/build/client/_app/version.json +1 -1
  39. package/build/client/_app/version.json.br +0 -0
  40. package/build/client/_app/version.json.gz +0 -0
  41. package/build/handler.js +7 -7
  42. package/build/index.js +7 -7
  43. package/build/server/chunks/chunks/{context.js-BZSZNuAd.js → context.js-DFZgDxCD.js} +157 -95
  44. package/build/server/chunks/chunks/context.js-DFZgDxCD.js.map +1 -0
  45. package/build/server/chunks/chunks/{contract.js-B4JdXFgm.js → contract.js-DGZXpcNX.js} +7 -7
  46. package/build/server/chunks/chunks/{contract.js-B4JdXFgm.js.map → contract.js-DGZXpcNX.js.map} +1 -1
  47. package/build/server/chunks/chunks/{core.js-BHxa3VBo.js → core.js-AGKlECJ0.js} +32 -32
  48. package/build/server/chunks/chunks/core.js-AGKlECJ0.js.map +1 -0
  49. package/build/server/chunks/chunks/{exports.js-D0dALD2Q.js → exports.js-BsVKSGJk.js} +2 -2
  50. package/build/server/chunks/chunks/{exports.js-D0dALD2Q.js.map → exports.js-BsVKSGJk.js.map} +1 -1
  51. package/build/server/chunks/chunks/{http.js-DYYKvppy.js → http.js-BQhjMaW9.js} +2 -2
  52. package/build/server/chunks/chunks/{http.js-DYYKvppy.js.map → http.js-BQhjMaW9.js.map} +1 -1
  53. package/build/server/chunks/chunks/{internal.js-CJkB_gzV.js → internal.js-DJGcNryj.js} +3 -3
  54. package/build/server/chunks/chunks/{internal.js-CJkB_gzV.js.map → internal.js-DJGcNryj.js.map} +1 -1
  55. package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
  56. package/build/server/chunks/chunks/{manifest-membership.js-BkrPsM_r.js → manifest-membership.js-DkHaPk2F.js} +2 -2
  57. package/build/server/chunks/chunks/{manifest-membership.js-BkrPsM_r.js.map → manifest-membership.js-DkHaPk2F.js.map} +1 -1
  58. package/build/server/chunks/chunks/{raw-reconciliation.js-DPnNXe0b.js → raw-reconciliation.js-D2sI2C-t.js} +3 -3
  59. package/build/server/chunks/chunks/raw-reconciliation.js-D2sI2C-t.js.map +1 -0
  60. package/build/server/chunks/chunks/{raw-reconciliation2.js-DKOpJ8if.js → raw-reconciliation2.js-CMpUvuMd.js} +2 -2
  61. package/build/server/chunks/chunks/{raw-reconciliation2.js-DKOpJ8if.js.map → raw-reconciliation2.js-CMpUvuMd.js.map} +1 -1
  62. package/build/server/chunks/chunks/{shared.js-D3ZDVUlh.js → shared.js-BtmYg0tL.js} +2 -2
  63. package/build/server/chunks/chunks/{shared.js-D3ZDVUlh.js.map → shared.js-BtmYg0tL.js.map} +1 -1
  64. package/build/server/chunks/chunks/{utils.js-CqWW_v-5.js → utils.js-CqXk0Ug6.js} +3 -3
  65. package/build/server/chunks/chunks/{utils.js-CqWW_v-5.js.map → utils.js-CqXk0Ug6.js.map} +1 -1
  66. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Dw2MW5Tm.js → _server.ts.js-DKGD9Jk2.js} +6 -6
  67. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Dw2MW5Tm.js.map → _server.ts.js-DKGD9Jk2.js.map} +1 -1
  68. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-GQDuJGug.js → _server.ts.js-C1UfF0EO.js} +7 -7
  69. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-GQDuJGug.js.map → _server.ts.js-C1UfF0EO.js.map} +1 -1
  70. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-JbLSv7Xx.js → _server.ts.js-DpASkk00.js} +7 -7
  71. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-JbLSv7Xx.js.map → _server.ts.js-DpASkk00.js.map} +1 -1
  72. package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-BPae-BYF.js → _server.ts.js-C3jU2vC8.js} +7 -7
  73. package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-BPae-BYF.js.map → _server.ts.js-C3jU2vC8.js.map} +1 -1
  74. package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-BafrrUxu.js → _server.ts.js-B7OwufF3.js} +7 -7
  75. package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-BafrrUxu.js.map → _server.ts.js-B7OwufF3.js.map} +1 -1
  76. package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-UOlSNEi9.js → _server.ts.js-COhg1nYk.js} +7 -7
  77. package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-UOlSNEi9.js.map → _server.ts.js-COhg1nYk.js.map} +1 -1
  78. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-QE1vUuAx.js → _server.ts.js-DAEE17eM.js} +7 -7
  79. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-QE1vUuAx.js.map → _server.ts.js-DAEE17eM.js.map} +1 -1
  80. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DIVfppGt.js → _server.ts.js-BrZSS4gm.js} +7 -7
  81. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DIVfppGt.js.map → _server.ts.js-BrZSS4gm.js.map} +1 -1
  82. package/build/server/chunks/entries/endpoints/api/events/{_server.ts.js-B6R_kqP8.js → _server.ts.js-Cfst-Brd.js} +7 -7
  83. package/build/server/chunks/entries/endpoints/api/events/{_server.ts.js-B6R_kqP8.js.map → _server.ts.js-Cfst-Brd.js.map} +1 -1
  84. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CertbDsH.js → _server.ts.js-aN_h2Ifo.js} +7 -7
  85. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CertbDsH.js.map → _server.ts.js-aN_h2Ifo.js.map} +1 -1
  86. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DEIF3Hu2.js → _server.ts.js-CX2A66ij.js} +7 -7
  87. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DEIF3Hu2.js.map → _server.ts.js-CX2A66ij.js.map} +1 -1
  88. package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DNFsNGr4.js → _server.ts.js-CwTiaheP.js} +7 -7
  89. package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DNFsNGr4.js.map → _server.ts.js-CwTiaheP.js.map} +1 -1
  90. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DDW8XRPe.js → _server.ts.js-fIbsr_2e.js} +7 -7
  91. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DDW8XRPe.js.map → _server.ts.js-fIbsr_2e.js.map} +1 -1
  92. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-C222-xli.js → _server.ts.js-Dvo1bsLi.js} +7 -7
  93. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-C222-xli.js.map → _server.ts.js-Dvo1bsLi.js.map} +1 -1
  94. package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-CI1P1uyd.js → _server.ts.js-VLg1G3mN.js} +7 -7
  95. package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-CI1P1uyd.js.map → _server.ts.js-VLg1G3mN.js.map} +1 -1
  96. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-DpiUwaSh.js → _server.ts.js-DqctsOop.js} +7 -7
  97. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-DpiUwaSh.js.map → _server.ts.js-DqctsOop.js.map} +1 -1
  98. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DT0VPqPT.js → _server.ts.js-CoxSU5iO.js} +7 -7
  99. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DT0VPqPT.js.map → _server.ts.js-CoxSU5iO.js.map} +1 -1
  100. package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DBpHM42g.js → _server.ts.js-wUxsLZdr.js} +7 -7
  101. package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DBpHM42g.js.map → _server.ts.js-wUxsLZdr.js.map} +1 -1
  102. package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Cxu5b6Au.js → _server.ts.js-BKsF0Oit.js} +7 -7
  103. package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Cxu5b6Au.js.map → _server.ts.js-BKsF0Oit.js.map} +1 -1
  104. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-W4dhMo8Y.js → _server.ts.js-Dk9oOZwM.js} +7 -7
  105. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-W4dhMo8Y.js.map → _server.ts.js-Dk9oOZwM.js.map} +1 -1
  106. package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-DJ_adxbT.js → _server.ts.js-DxjNmmtL.js} +7 -7
  107. package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-DJ_adxbT.js.map → _server.ts.js-DxjNmmtL.js.map} +1 -1
  108. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-BisoHihD.js → _server.ts.js-DD0b38VV.js} +6 -6
  109. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-BisoHihD.js.map → _server.ts.js-DD0b38VV.js.map} +1 -1
  110. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-D4jLLuko.js → _server.ts.js-DId6F2i_.js} +7 -7
  111. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-D4jLLuko.js.map → _server.ts.js-DId6F2i_.js.map} +1 -1
  112. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-Dfv2ItjT.js → _server.ts.js-DKKkGoK2.js} +7 -7
  113. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-Dfv2ItjT.js.map → _server.ts.js-DKKkGoK2.js.map} +1 -1
  114. package/build/server/chunks/entries/{hooks.server.js-oHJX5INm.js → hooks.server.js-B5Ctvorj.js} +6 -6
  115. package/build/server/chunks/entries/{hooks.server.js-oHJX5INm.js.map → hooks.server.js-B5Ctvorj.js.map} +1 -1
  116. package/build/server/chunks/{handler-BAe0c9yw.js → handler-DwVfBx6r.js} +5 -5
  117. package/build/server/chunks/{handler-BAe0c9yw.js.map → handler-DwVfBx6r.js.map} +1 -1
  118. package/build/server/chunks/{index.js-DUYD4JB0.js → index.js-DgPuPQJn.js} +5 -5
  119. package/build/server/chunks/{index.js-DUYD4JB0.js.map → index.js-DgPuPQJn.js.map} +1 -1
  120. package/build/server/chunks/{manifest.js-zwun-T7O.js → manifest.js-B054EcAf.js} +31 -31
  121. package/build/server/chunks/{manifest.js-zwun-T7O.js.map → manifest.js-B054EcAf.js.map} +1 -1
  122. package/build/server/chunks/nodes/{0.js-BmkXwDRY.js → 0.js-DoHZTmnT.js} +2 -2
  123. package/build/server/chunks/nodes/{0.js-BmkXwDRY.js.map → 0.js-DoHZTmnT.js.map} +1 -1
  124. package/build/server/chunks/nodes/1.js-BcPlsloO.js +7 -0
  125. package/build/server/chunks/nodes/{1.js-xbOwEHCW.js.map → 1.js-BcPlsloO.js.map} +1 -1
  126. package/build/server/chunks/nodes/{2.js-BuNw1vTZ.js → 2.js-5qCXkvzl.js} +2 -2
  127. package/build/server/chunks/nodes/{2.js-BuNw1vTZ.js.map → 2.js-5qCXkvzl.js.map} +1 -1
  128. package/build/server/chunks/nodes/3.js-D6fAMX1w.js +7 -0
  129. package/build/server/chunks/nodes/{3.js-Dpr_DvNU.js.map → 3.js-D6fAMX1w.js.map} +1 -1
  130. package/build/server/chunks/nodes/4.js-CGkeT0SQ.js +7 -0
  131. package/build/server/chunks/nodes/{4.js-14Lypd4o.js.map → 4.js-CGkeT0SQ.js.map} +1 -1
  132. package/dist/cli.js +3 -4
  133. package/dist/core/figma-tag-links.d.ts +66 -0
  134. package/dist/core/figma-tag-links.js +97 -0
  135. package/dist/core/index.d.ts +2 -2
  136. package/dist/core/index.js +1 -1
  137. package/dist/server/cli-commands.d.ts +1 -1
  138. package/dist/server/cli-commands.js +1 -1
  139. package/dist/server/cli-figma-tags.d.ts +1 -1
  140. package/dist/server/cli-figma-tags.js +149 -88
  141. package/dist/server/figma-tags.d.ts +72 -24
  142. package/dist/server/figma-tags.js +130 -79
  143. package/dist/server/importers/figma.d.ts +20 -15
  144. package/dist/server/importers/figma.js +172 -92
  145. package/package.json +1 -1
  146. package/build/client/_app/immutable/chunks/Bsj1ssvc.js +0 -1
  147. package/build/client/_app/immutable/chunks/Bsj1ssvc.js.br +0 -0
  148. package/build/client/_app/immutable/chunks/Bsj1ssvc.js.gz +0 -0
  149. package/build/client/_app/immutable/chunks/OL1Dh1oP.js.br +0 -0
  150. package/build/client/_app/immutable/chunks/OL1Dh1oP.js.gz +0 -0
  151. package/build/client/_app/immutable/chunks/QlQ-jeIO.js.br +0 -2
  152. package/build/client/_app/immutable/chunks/QlQ-jeIO.js.gz +0 -0
  153. package/build/client/_app/immutable/chunks/apKHI4vq.js.br +0 -0
  154. package/build/client/_app/immutable/chunks/apKHI4vq.js.gz +0 -0
  155. package/build/client/_app/immutable/chunks/g2rma9Ym.js.br +0 -0
  156. package/build/client/_app/immutable/chunks/g2rma9Ym.js.gz +0 -0
  157. package/build/client/_app/immutable/entry/app.DpZM49_s.js.br +0 -0
  158. package/build/client/_app/immutable/entry/app.DpZM49_s.js.gz +0 -0
  159. package/build/client/_app/immutable/entry/start.B3EMVPEN.js +0 -1
  160. package/build/client/_app/immutable/entry/start.B3EMVPEN.js.br +0 -0
  161. package/build/client/_app/immutable/entry/start.B3EMVPEN.js.gz +0 -0
  162. package/build/client/_app/immutable/nodes/0.Wqvn8XD-.js.br +0 -0
  163. package/build/client/_app/immutable/nodes/0.Wqvn8XD-.js.gz +0 -0
  164. package/build/client/_app/immutable/nodes/1.Z-UvvLkP.js.br +0 -0
  165. package/build/client/_app/immutable/nodes/1.Z-UvvLkP.js.gz +0 -0
  166. package/build/client/_app/immutable/nodes/2.lu89W_qJ.js.br +0 -0
  167. package/build/client/_app/immutable/nodes/2.lu89W_qJ.js.gz +0 -0
  168. package/build/client/_app/immutable/nodes/3.Dt32EAoq.js.br +0 -0
  169. package/build/client/_app/immutable/nodes/3.Dt32EAoq.js.gz +0 -0
  170. package/build/client/_app/immutable/nodes/4.WipzcX8_.js.br +0 -0
  171. package/build/client/_app/immutable/nodes/4.WipzcX8_.js.gz +0 -0
  172. package/build/server/chunks/chunks/context.js-BZSZNuAd.js.map +0 -1
  173. package/build/server/chunks/chunks/core.js-BHxa3VBo.js.map +0 -1
  174. package/build/server/chunks/chunks/raw-reconciliation.js-DPnNXe0b.js.map +0 -1
  175. package/build/server/chunks/nodes/1.js-xbOwEHCW.js +0 -7
  176. package/build/server/chunks/nodes/3.js-Dpr_DvNU.js +0 -7
  177. package/build/server/chunks/nodes/4.js-14Lypd4o.js +0 -7
  178. package/dist/core/figma-tag-script.d.ts +0 -154
  179. package/dist/core/figma-tag-script.js +0 -248
@@ -1,7 +1,7 @@
1
1
  import { lookup } from 'node:dns/promises';
2
2
  import { isIP } from 'node:net';
3
3
  import sharp from 'sharp';
4
- import { isInstanceSublayerId, isValidAssetId } from '../../core/index.js';
4
+ import { figmaLinksFromRest, figmaTagEntries, fundusTagLink, isValidAssetId } from '../../core/index.js';
5
5
  import { SourceImportError, invalidInput } from './contract.js';
6
6
  import { requestPinnedHttps } from './pinned-https.js';
7
7
  const MAX_DOWNLOAD_BYTES = 50 * 1024 * 1024;
@@ -9,6 +9,9 @@ const MAX_PIXELS = 32_000_000;
9
9
  const MAX_REDIRECTS = 3;
10
10
  const REQUEST_TIMEOUT_MS = 30_000;
11
11
  const PNG_SIGNATURE = Uint8Array.from([137, 80, 78, 71, 13, 10, 26, 10]);
12
+ /** Worst case per API call: 3 attempts × 30 s timeout + 2 waits × 10 s = 110 s. */
13
+ const FIGMA_RATE_LIMIT_ATTEMPTS = 3;
14
+ const FIGMA_RATE_LIMIT_MAX_WAIT_SECONDS = 10;
12
15
  function record(value) {
13
16
  return typeof value === 'object' && value !== null && !Array.isArray(value)
14
17
  ? value
@@ -130,17 +133,19 @@ function retryAfter(response) {
130
133
  const seconds = Number(raw);
131
134
  return Number.isSafeInteger(seconds) ? seconds : undefined;
132
135
  }
133
- function upstreamStatusError(response) {
136
+ function upstreamStatusError(response, scope) {
134
137
  if (response.status === 401)
135
138
  return new SourceImportError('unauthorized', 'Figma authentication failed.');
136
139
  if (response.status === 403)
137
- return new SourceImportError('forbidden', 'Figma authentication or access failed. The token may be invalid or expired, or it may not have access to this file.');
140
+ return new SourceImportError('forbidden', scope
141
+ ? `Figma authentication or access failed. The token may be invalid or expired, may lack the ${scope} scope, or may not have access to this file.`
142
+ : 'Figma authentication or access failed. The token may be invalid or expired, or it may not have access to this file.');
138
143
  if (response.status === 404)
139
144
  return new SourceImportError('not-found', 'The Figma file or node was not found.');
140
145
  if (response.status === 429) {
141
146
  return new SourceImportError('rate-limited', 'Figma rate-limited this request.', retryAfter(response));
142
147
  }
143
- return new SourceImportError('upstream-failed', `Figma export failed with status ${response.status}.`);
148
+ return new SourceImportError('upstream-failed', `Figma request failed with status ${response.status}.`);
144
149
  }
145
150
  function isForbiddenIpv4(address) {
146
151
  const parts = address.split('.').map(Number);
@@ -248,22 +253,22 @@ export async function resolveSafeDownloadTarget(value) {
248
253
  export async function assertSafeDownloadUrl(value) {
249
254
  return (await resolveSafeDownloadTarget(value)).url;
250
255
  }
251
- async function fetchWithDeadline(fetcher, url, init, consume) {
256
+ async function fetchWithDeadline(fetcher, url, init, scope) {
252
257
  const controller = new AbortController();
253
258
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
254
259
  try {
255
260
  const response = await fetcher(url, { ...init, signal: controller.signal });
256
261
  if (!response.ok)
257
- throw upstreamStatusError(response);
258
- return await consume(response);
262
+ throw upstreamStatusError(response, scope);
263
+ return new Uint8Array(await response.arrayBuffer());
259
264
  }
260
265
  catch (cause) {
261
266
  if (controller.signal.aborted || (cause instanceof Error && cause.name === 'AbortError')) {
262
- throw new SourceImportError('download-timeout', 'Figma export timed out.');
267
+ throw new SourceImportError('download-timeout', 'Figma request timed out.');
263
268
  }
264
269
  if (cause instanceof SourceImportError)
265
270
  throw cause;
266
- throw new SourceImportError('upstream-failed', 'Figma export request failed.');
271
+ throw new SourceImportError('upstream-failed', 'Figma request failed.');
267
272
  }
268
273
  finally {
269
274
  clearTimeout(timeout);
@@ -383,50 +388,40 @@ async function validatePng(bytes) {
383
388
  throw new SourceImportError('image-too-large', 'Figma export exceeds the 32 megapixel limit.');
384
389
  }
385
390
  }
386
- /**
387
- * Every taggable node in a REST document tree (`plugin_data=shared`), in
388
- * document order. Nodes inside instances are skipped: they echo the main
389
- * component node's tag, and Fundus imports only plain `12:34` node ids.
390
- */
391
- export function figmaDocumentNodes(document) {
392
- const nodes = [];
393
- const visit = (value, page) => {
394
- const current = record(value);
395
- if (!current)
396
- return;
397
- const name = typeof current.name === 'string' ? current.name : '';
398
- const pageName = current.type === 'CANVAS' ? name : page;
399
- if (typeof current.id === 'string' &&
400
- current.type !== 'DOCUMENT' &&
401
- current.type !== 'CANVAS' &&
402
- !isInstanceSublayerId(current.id)) {
403
- const shared = record(current.sharedPluginData);
404
- const fundus = shared ? record(shared.fundus) : null;
405
- const tag = fundus && typeof fundus.assetId === 'string' ? fundus.assetId : '';
406
- nodes.push({
407
- nodeId: current.id,
408
- nodeName: name,
409
- page: pageName,
410
- tag: tag === '' ? null : tag
411
- });
391
+ async function fetchFigmaApiBytes(endpoint, init, scope, context) {
392
+ for (let attempt = 1;; attempt++) {
393
+ try {
394
+ return await fetchWithDeadline(context.fetch, endpoint, init, scope);
412
395
  }
413
- if (Array.isArray(current.children)) {
414
- for (const child of current.children)
415
- visit(child, pageName);
396
+ catch (cause) {
397
+ const wait = cause instanceof SourceImportError && cause.code === 'rate-limited'
398
+ ? cause.retryAfterSeconds
399
+ : undefined;
400
+ if (wait === undefined ||
401
+ wait > FIGMA_RATE_LIMIT_MAX_WAIT_SECONDS ||
402
+ attempt >= FIGMA_RATE_LIMIT_ATTEMPTS) {
403
+ throw cause;
404
+ }
405
+ await new Promise((resolve) => setTimeout(resolve, wait * 1000));
416
406
  }
417
- };
418
- visit(record(document), '');
419
- return nodes;
407
+ }
420
408
  }
421
- /** The whole document tree of a Figma file, including every node's shared plugin data. */
422
- export async function fetchFigmaDocument(fileKey, context) {
409
+ async function requestFigmaApi(endpoint, context, request) {
423
410
  const token = context.config.import.figma.token;
424
411
  if (!token) {
425
412
  throw new SourceImportError('not-configured', 'Figma access is not configured.');
426
413
  }
427
- const endpoint = new URL(`https://api.figma.com/v1/files/${encodeURIComponent(fileKey)}`);
428
- endpoint.searchParams.set('plugin_data', 'shared');
429
- const jsonBytes = await fetchWithDeadline(context.fetch, endpoint, { redirect: 'error', headers: { 'X-Figma-Token': token } }, async (response) => new Uint8Array(await response.arrayBuffer()));
414
+ const jsonBytes = await fetchFigmaApiBytes(endpoint, {
415
+ method: request.method ?? 'GET',
416
+ redirect: 'error',
417
+ headers: {
418
+ 'X-Figma-Token': token,
419
+ ...(request.body !== undefined ? { 'Content-Type': 'application/json' } : {})
420
+ },
421
+ ...(request.body !== undefined ? { body: JSON.stringify(request.body) } : {})
422
+ }, request.scope, context);
423
+ if (jsonBytes.byteLength === 0)
424
+ return {};
430
425
  let payload;
431
426
  try {
432
427
  payload = JSON.parse(new TextDecoder().decode(jsonBytes));
@@ -435,56 +430,144 @@ export async function fetchFigmaDocument(fileKey, context) {
435
430
  throw new SourceImportError('invalid-response', 'Figma returned an invalid response.');
436
431
  }
437
432
  const body = record(payload);
438
- if (!body || body.err || (typeof body.status === 'number' && body.status >= 400)) {
433
+ if (!body ||
434
+ body.err ||
435
+ body.error === true ||
436
+ (typeof body.status === 'number' && body.status >= 400)) {
437
+ throw new SourceImportError('invalid-response', request.errorMessage);
438
+ }
439
+ // Figma reports rejected batch entries (e.g. "Url already exists") in `errors` with HTTP 200.
440
+ if (Array.isArray(body.errors) && body.errors.length > 0) {
441
+ const reasons = body.errors.map((entry) => {
442
+ const reason = record(entry)?.error;
443
+ return typeof reason === 'string' ? reason : 'unknown error';
444
+ });
445
+ throw new SourceImportError('upstream-failed', `Figma rejected the request: ${reasons.join('; ')}`);
446
+ }
447
+ return body;
448
+ }
449
+ function figmaFileEndpoint(fileKey, path) {
450
+ return new URL(`https://api.figma.com/v1/files/${encodeURIComponent(fileKey)}${path}`);
451
+ }
452
+ /** Every Fundus tag link in the file (orphaned ones included); each entry has its `linkId`. */
453
+ export async function listFigmaTagEntries(fileKey, context) {
454
+ const body = await requestFigmaApi(figmaFileEndpoint(fileKey, '/dev_resources'), context, {
455
+ scope: 'file_dev_resources:read',
456
+ errorMessage: 'Figma returned an invalid response.'
457
+ });
458
+ const links = figmaLinksFromRest(body);
459
+ if (!links) {
460
+ throw new SourceImportError('invalid-response', 'Figma returned an invalid Dev Resources list.');
461
+ }
462
+ return figmaTagEntries(links).filter((entry) => entry.linkId !== undefined);
463
+ }
464
+ /** The requested nodes that exist; Figma answers deleted or unknown ids with `null` (dropped). */
465
+ export async function fetchFigmaNodeSummaries(fileKey, nodeIds, context) {
466
+ if (nodeIds.length === 0)
467
+ return [];
468
+ const endpoint = figmaFileEndpoint(fileKey, '/nodes');
469
+ endpoint.searchParams.set('ids', nodeIds.join(','));
470
+ endpoint.searchParams.set('depth', '1');
471
+ const body = await requestFigmaApi(endpoint, context, {
472
+ scope: 'file_content:read',
473
+ errorMessage: 'Figma returned an invalid response.'
474
+ });
475
+ const nodes = record(body.nodes);
476
+ if (!nodes)
439
477
  throw new SourceImportError('invalid-response', 'Figma returned an invalid response.');
478
+ const summaries = [];
479
+ for (const nodeId of nodeIds) {
480
+ if (nodes[nodeId] === null)
481
+ continue;
482
+ const document = record(record(nodes[nodeId])?.document);
483
+ if (!document || typeof document.name !== 'string' || typeof document.type !== 'string') {
484
+ throw new SourceImportError('invalid-response', 'Figma did not return the requested node.');
485
+ }
486
+ summaries.push({ nodeId, nodeName: document.name, nodeType: document.type });
440
487
  }
441
- return body.document;
488
+ return summaries;
442
489
  }
443
- export async function resolveTagToNode(fileKey, tag, context) {
444
- const document = await fetchFigmaDocument(fileKey, context);
445
- const matches = figmaDocumentNodes(document).filter((node) => node.tag === tag);
446
- if (matches.length === 0) {
447
- throw new SourceImportError('not-found', `No Figma node is tagged "${tag}" in this file.`);
448
- }
449
- if (matches.length > 1) {
450
- throw new SourceImportError('ambiguous-tag', `More than one Figma node is tagged "${tag}" in this file.`);
451
- }
452
- return matches[0].nodeId;
490
+ export async function createFigmaTagLink(fileKey, nodeId, tag, context) {
491
+ await requestFigmaApi(new URL('https://api.figma.com/v1/dev_resources'), context, {
492
+ scope: 'file_dev_resources:write',
493
+ errorMessage: 'Figma could not create the tag link.',
494
+ method: 'POST',
495
+ body: { dev_resources: [{ ...fundusTagLink(tag), file_key: fileKey, node_id: nodeId }] }
496
+ });
453
497
  }
454
- async function materialize(source, context) {
455
- const token = context.config.import.figma.token;
456
- if (!token) {
457
- throw new SourceImportError('not-configured', 'Figma access is not configured.');
458
- }
459
- const endpoint = new URL(`https://api.figma.com/v1/images/${encodeURIComponent(source.fileKey)}`);
460
- endpoint.searchParams.set('ids', source.nodeId);
461
- endpoint.searchParams.set('format', source.format);
462
- endpoint.searchParams.set('scale', String(source.scale));
463
- const jsonBytes = await fetchWithDeadline(context.fetch, endpoint, { redirect: 'error', headers: { 'X-Figma-Token': token } }, async (response) => new Uint8Array(await response.arrayBuffer()));
464
- let payload;
465
- try {
466
- payload = JSON.parse(new TextDecoder().decode(jsonBytes));
467
- }
468
- catch {
469
- throw new SourceImportError('invalid-response', 'Figma returned an invalid response.');
498
+ export async function deleteFigmaDevResource(fileKey, linkId, context) {
499
+ await requestFigmaApi(figmaFileEndpoint(fileKey, `/dev_resources/${encodeURIComponent(linkId)}`), context, {
500
+ scope: 'file_dev_resources:write',
501
+ errorMessage: 'Figma could not delete the tag link.',
502
+ method: 'DELETE'
503
+ });
504
+ }
505
+ /** Export URLs for the nodes in one `/images` call; `null` for a node Figma cannot render. */
506
+ async function exportImageUrls(fileKey, nodeIds, scale, context) {
507
+ const endpoint = new URL(`https://api.figma.com/v1/images/${encodeURIComponent(fileKey)}`);
508
+ endpoint.searchParams.set('ids', nodeIds.join(','));
509
+ endpoint.searchParams.set('format', 'png');
510
+ endpoint.searchParams.set('scale', String(scale));
511
+ const body = await requestFigmaApi(endpoint, context, {
512
+ scope: 'file_content:read',
513
+ errorMessage: 'Figma could not render this node.'
514
+ });
515
+ const images = record(body.images);
516
+ const urls = {};
517
+ for (const nodeId of nodeIds) {
518
+ if (!images || !Object.hasOwn(images, nodeId)) {
519
+ throw new SourceImportError('invalid-response', 'Figma did not return the requested node.');
520
+ }
521
+ const imageUrl = images[nodeId];
522
+ urls[nodeId] = typeof imageUrl === 'string' && imageUrl.length > 0 ? imageUrl : null;
470
523
  }
471
- const body = record(payload);
472
- if (!body || body.err || (typeof body.status === 'number' && body.status >= 400)) {
473
- throw new SourceImportError('invalid-response', 'Figma could not render this node.');
524
+ return urls;
525
+ }
526
+ /**
527
+ * The one renderable node carrying `tag`. All candidates go into a single
528
+ * `/images` call, which answers deleted nodes with `null`; a live but
529
+ * unrenderable second candidate therefore goes unnoticed.
530
+ */
531
+ export async function resolveTaggedNode(fileKey, tag, scale, context) {
532
+ const candidates = [
533
+ ...new Set((await listFigmaTagEntries(fileKey, context))
534
+ .filter((entry) => entry.tag === tag)
535
+ .map((entry) => entry.nodeId))
536
+ ];
537
+ if (candidates.length === 0) {
538
+ throw new SourceImportError('not-found', `No Figma node is tagged "${tag}" in this file.`);
474
539
  }
475
- const images = record(body.images);
476
- if (!images || !Object.hasOwn(images, source.nodeId)) {
477
- throw new SourceImportError('invalid-response', 'Figma did not return the requested node.');
540
+ const urls = await exportImageUrls(fileKey, candidates, scale, context);
541
+ const live = candidates.flatMap((nodeId) => {
542
+ const imageUrl = urls[nodeId];
543
+ return imageUrl ? [{ nodeId, imageUrl }] : [];
544
+ });
545
+ if (live.length === 0) {
546
+ throw new SourceImportError('not-found', `Every Figma node tagged "${tag}" (${candidates.join(', ')}) is deleted or cannot be rendered.`);
478
547
  }
479
- const imageUrl = images[source.nodeId];
480
- if (typeof imageUrl !== 'string' || imageUrl.length === 0) {
481
- throw new SourceImportError('invalid-response', 'Figma could not render the requested node.');
548
+ if (live.length > 1) {
549
+ throw new SourceImportError('ambiguous-tag', `More than one Figma node is tagged "${tag}" in this file (${live.map((node) => node.nodeId).join(', ')}).`);
482
550
  }
551
+ return live[0];
552
+ }
553
+ async function downloadRaw(source, imageUrl, context) {
483
554
  const bytes = await downloadExport(context.httpsTransport ?? requestPinnedHttps, imageUrl);
484
555
  await validatePng(bytes);
485
556
  const importSource = { importer: 'figma', parameters: source };
486
557
  return { bytes, extension: 'png', importSource };
487
558
  }
559
+ async function importNode(source, context) {
560
+ const urls = await exportImageUrls(source.fileKey, [source.nodeId], source.scale, context);
561
+ const imageUrl = urls[source.nodeId];
562
+ if (!imageUrl) {
563
+ throw new SourceImportError('invalid-response', 'Figma could not render the requested node.');
564
+ }
565
+ return downloadRaw(source, imageUrl, context);
566
+ }
567
+ async function importTag(source, context) {
568
+ const { nodeId, imageUrl } = await resolveTaggedNode(source.fileKey, source.fundusTag, source.scale, context);
569
+ return downloadRaw({ ...source, nodeId }, imageUrl, context);
570
+ }
488
571
  export const figmaSourceImporter = {
489
572
  kind: 'figma',
490
573
  label: 'Figma',
@@ -495,18 +578,16 @@ export const figmaSourceImporter = {
495
578
  if (!fileKey) {
496
579
  throw new SourceImportError('not-configured', 'Figma tag import needs a fileKey or import.figma.defaultFileKey in fundus.config.');
497
580
  }
498
- const nodeId = await resolveTagToNode(fileKey, input.tag, context);
499
- return materialize({
581
+ return importTag({
500
582
  mode: 'tag',
501
583
  fileKey,
502
584
  fundusTag: input.tag,
503
- nodeId,
504
585
  format: 'png',
505
586
  scale: input.scale ?? context.config.import.figma.defaults.scale
506
587
  }, context);
507
588
  }
508
589
  const parsed = parseFigmaSelectionUrl(input.url);
509
- return materialize({
590
+ return importNode({
510
591
  fileKey: parsed.fileKey,
511
592
  nodeId: parsed.nodeId,
512
593
  format: 'png',
@@ -515,10 +596,9 @@ export const figmaSourceImporter = {
515
596
  },
516
597
  validateSourceParameters: validateFigmaSourceParameters,
517
598
  async reimportRaw(source, context) {
518
- if (source.mode === 'tag') {
519
- const nodeId = await resolveTagToNode(source.fileKey, source.fundusTag, context);
520
- return materialize({ ...source, nodeId }, context);
521
- }
522
- return materialize(source, context);
599
+ // The stored nodeId is not consulted: the tag link decides where the tag lives now.
600
+ if (source.mode === 'tag')
601
+ return importTag(source, context);
602
+ return importNode(source, context);
523
603
  }
524
604
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fundus",
3
- "version": "0.28.1",
3
+ "version": "0.29.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1 +0,0 @@
1
- import{H as e,U as t,V as n,it as r,nt as i,r as a,t as o,tt as s}from"./DLEDBLL1.js";var c=class{constructor(e,t){this.status=e,typeof t==`string`?this.body={message:t}:t?this.body=t:this.body={message:`Error: ${e}`}}toString(){return JSON.stringify(this.body)}},l=class{constructor(e,t){try{new Headers({location:t})}catch{throw Error(`Invalid redirect location ${JSON.stringify(t)}: this string contains characters that cannot be used in HTTP headers`)}this.status=e,this.location=t}},u=class extends Error{constructor(e,t,n){super(n),this.status=e,this.text=t}};new URL(`sveltekit-internal://`);function d(e,t){return e===`/`||t===`ignore`?e:t===`never`?e.endsWith(`/`)?e.slice(0,-1):e:t===`always`&&!e.endsWith(`/`)?e+`/`:e}function f(e){return e.split(`%25`).map(decodeURI).join(`%25`)}function p(e){for(let t in e)e[t]=decodeURIComponent(e[t]);return e}function m({href:e}){return e.split(`#`)[0]}function h(){}function ee(...e){let t=5381;for(let n of e)if(typeof n==`string`){let e=n.length;for(;e;)t=t*33^n.charCodeAt(--e)}else if(ArrayBuffer.isView(n)){let e=new Uint8Array(n.buffer,n.byteOffset,n.byteLength),r=e.length;for(;r;)t=t*33^e[--r]}else throw TypeError(`value must be a string or TypedArray`);return(t>>>0).toString(36)}new TextEncoder;function g(e){let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}var _=window.fetch;window.fetch=(e,t)=>((e instanceof Request?e.method:t?.method||`GET`)!==`GET`&&v.delete(b(e)),_(e,t));var v=new Map;function te(e,t){let n=b(e,t),r=document.querySelector(n);if(r?.textContent){r.remove();let{body:e,...t}=JSON.parse(r.textContent);r.getAttribute(`data-b64`)!==null&&(e=g(e));let i=r.getAttribute(`data-ttl`);return i&&v.set(n,{body:e,init:t,ttl:1e3*Number(i)}),Promise.resolve(new Response(e,t))}return window.fetch(e,t)}function y(e,t,n){if(v.size>0){let t=b(e,n),r=v.get(t);if(r){if(performance.now()<r.ttl&&[`default`,`force-cache`,`only-if-cached`,void 0].includes(n?.cache))return new Response(r.body,r.init);v.delete(t)}}return window.fetch(t,n)}function b(e,t){let n=`script[data-sveltekit-fetched][data-url=${JSON.stringify(e instanceof Request?e.url:e)}]`;if(t?.headers||t?.body){let e=[];t.headers&&e.push([...new Headers(t.headers)].join(`,`)),t.body&&(typeof t.body==`string`||ArrayBuffer.isView(t.body))&&e.push(t.body),n+=`[data-hash="${ee(...e)}"]`}return n}var ne=/^(\[)?(\.\.\.)?(\w+)(?:=(\w+))?(\])?$/,re=/^\/\((?:[^)]+)\)$/;function x(e){let t=[];return{pattern:e===`/`||re.test(e)?/^\/$/:RegExp(`^${ae(e).map(e=>{let n=/^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(e);if(n)return t.push({name:n[1],matcher:n[2],optional:!1,rest:!0,chained:!0}),`(?:/([^]*))?`;let r=/^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(e);if(r)return t.push({name:r[1],matcher:r[2],optional:!0,rest:!1,chained:!0}),`(?:/([^/]+))?`;if(!e)return;let i=e.split(/\[(.+?)\](?!\])/);return`/`+i.map((e,n)=>{if(n%2){if(e.startsWith(`x+`))return se(String.fromCharCode(parseInt(e.slice(2),16)));if(e.startsWith(`u+`))return se(String.fromCharCode(...e.slice(2).split(`-`).map(e=>parseInt(e,16))));let[,r,a,o,s]=ne.exec(e);return t.push({name:o,matcher:s,optional:!!r,rest:!!a,chained:a?n===1&&i[0]===``:!1}),a?`([^]*?)`:r?`([^/]*)?`:`([^/]+?)`}return se(e)}).join(``)}).join(``)}/?$`),params:t}}function ie(e){return e!==``&&!/^\([^)]+\)$/.test(e)}function ae(e){return e.slice(1).split(`/`).filter(ie)}function oe(e,t,n){let r={},i=e.slice(1),a=i.filter(e=>e!==void 0),o=0;for(let e=0;e<t.length;e+=1){let s=t[e],c=i[e-o];if(s.chained&&s.rest&&o&&(c=i.slice(e-o,e+1).filter(e=>e).join(`/`),o=0),c===void 0)if(s.rest)c=``;else continue;if(!s.matcher||n[s.matcher](c)){r[s.name]=c;let n=t[e+1],l=i[e+1];n&&!n.rest&&n.optional&&l&&s.chained&&(o=0),!n&&!l&&Object.keys(r).length===a.length&&(o=0);continue}if(s.optional&&s.chained){o++;continue}return}if(!o)return r}function se(e){return e.normalize().replace(/[[\]]/g,`\\$&`).replace(/%/g,`%25`).replace(/\//g,`%2[Ff]`).replace(/\?/g,`%3[Ff]`).replace(/#/g,`%23`).replace(/[.*+?^${}()|\\]/g,`\\$&`)}var ce=/\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;function le(e,t){let n=ae(e),r=e!=`/`&&e.endsWith(`/`);return`/`+n.map(n=>n.replace(ce,(n,r,i,a)=>{let o=t[a];if(!o){if(r||i&&o!==void 0)return``;throw Error(`Missing parameter '${a}' in route ${e}`)}if(o.startsWith(`/`)||o.endsWith(`/`))throw Error(`Parameter '${a}' in route ${e} cannot start or end with a slash -- this would cause an invalid route like foo//bar`);return o})).filter(Boolean).join(`/`)+(r?`/`:``)}function ue({nodes:e,server_loads:t,dictionary:n,matchers:r}){let i=new Set(t);return Object.entries(n).map(([t,[n,i,s]])=>{let{pattern:c,params:l}=x(t),u={id:t,exec:e=>{let t=c.exec(e);if(t)return oe(t,l,r)},errors:[1,...s||[]].map(t=>e[t]),layouts:[0,...i||[]].map(o),leaf:a(n)};return u.errors.length=u.layouts.length=Math.max(u.errors.length,u.layouts.length),u});function a(t){let n=t<0;return n&&(t=~t),[n,e[t]]}function o(t){return t===void 0?t:[i.has(t),e[t]]}}function de(e,t=JSON.parse){try{return t(sessionStorage[e])}catch{}}function fe(e,t,n=JSON.stringify){let r=n(t);try{sessionStorage[e]=r}catch{}}var S=globalThis.__sveltekit_lq9pg8?.base??``,pe=globalThis.__sveltekit_lq9pg8?.assets??S??``,me=``;function he(...e){if(!e[0].startsWith(`/`))throw Error(`Cannot use \`resolve(...)\` with a non-absolute pathname or route ID (got "${e[0]}"). \`resolve\` is only for internal pathnames and route IDs; external URLs should be used directly.`);return S+me+le(e[0],e[1])}var ge=`1790688620154`,_e=`sveltekit:snapshot`,ve=`sveltekit:scroll`,ye=`sveltekit:states`,C=`sveltekit:history`,w=`sveltekit:navigation`,T={tap:1,hover:2,viewport:3,eager:4,off:-1,false:-1},E=location.origin;function be(e){if(e instanceof URL)return e;let t=document.baseURI;if(!t){let e=document.getElementsByTagName(`base`);t=e.length?e[0].href:document.URL}return new URL(e,t)}function D(){return{x:pageXOffset,y:pageYOffset}}function O(e,t){return e.getAttribute(`data-sveltekit-${t}`)}var xe={...T,"":T.hover};function Se(e){let t=e.assignedSlot??e.parentNode;return t?.nodeType===11&&(t=t.host),t}function Ce(e,t){for(;e&&e!==t;){if(e.nodeName.toUpperCase()===`A`&&e.hasAttribute(`href`))return e;e=Se(e)}}function we(e,t,n){let r;try{if(r=new URL(e instanceof SVGAElement?e.href.baseVal:e.href,document.baseURI),n&&r.hash.match(/^#[^/]/)){let e=location.hash.split(`#`)[1]||`/`;r.hash=`#${e}${r.hash}`}}catch{}let i=e instanceof SVGAElement?e.target.baseVal:e.target,a=!r||!!i||A(r,t,n)||(e.getAttribute(`rel`)||``).split(/\s+/).includes(`external`),o=r?.origin===E&&e.hasAttribute(`download`);return{url:r,external:a,target:i,download:o}}function k(e){let t=null,n=null,r=null,i=null,a=null,o=null,s=e;for(;s&&s!==document.documentElement;)r===null&&(r=O(s,`preload-code`)),i===null&&(i=O(s,`preload-data`)),t===null&&(t=O(s,`keepfocus`)),n===null&&(n=O(s,`noscroll`)),a===null&&(a=O(s,`reload`)),o===null&&(o=O(s,`replacestate`)),s=Se(s);function c(e){switch(e){case``:case`true`:return!0;case`off`:case`false`:return!1;default:return}}return{preload_code:xe[r??`off`],preload_data:xe[i??`off`],keepfocus:c(t),noscroll:c(n),reload:c(a),replace_state:c(o)}}function Te(e){let t=r(e),n=!0;function i(){n=!0,t.update(e=>e)}function a(e){n=!1,t.set(e)}function o(e){let r;return t.subscribe(t=>{(r===void 0||n&&t!==r)&&e(r=t)})}return{notify:i,set:a,subscribe:o}}var Ee={v:h};function De(){let{set:e,subscribe:t}=r(!1);async function n(){clearTimeout(void 0);try{let t=await fetch(`${pe}/_app/version.json`,{headers:{pragma:`no-cache`,"cache-control":`no-cache`}});if(!t.ok)return!1;let n=(await t.json()).version!==ge;return n&&(e(!0),Ee.v(),clearTimeout(void 0)),n}catch{return!1}}return{subscribe:t,check:n}}function A(e,t,n){return e.origin!==E||!e.pathname.startsWith(t)?!0:n?e.pathname!==location.pathname:!1}function Oe(e){}var ke=new Set([`load`,`prerender`,`csr`,`ssr`,`trailingSlash`,`config`]);[...ke],[...new Set([...ke])];function Ae(e){return e.filter(e=>e!=null)}function j(e,t){return e+`/`+t}function je(e){return e instanceof c||e instanceof u?e.status:500}function Me(e){return e instanceof u?e.text:`Internal Error`}var M,N,P,Ne=a.toString().includes(`$$`)||/function \w+\(\) \{\}/.test(a.toString()),Pe=`a:`;Ne?(M={data:{},form:null,error:null,params:{},route:{id:null},state:{},status:-1,url:new URL(Pe)},N={current:null},P={current:!1}):(M=new class{#e=i({});get data(){return n(this.#e)}set data(e){s(this.#e,e)}#t=i(null);get form(){return n(this.#t)}set form(e){s(this.#t,e)}#n=i(null);get error(){return n(this.#n)}set error(e){s(this.#n,e)}#r=i({});get params(){return n(this.#r)}set params(e){s(this.#r,e)}#i=i({id:null});get route(){return n(this.#i)}set route(e){s(this.#i,e)}#a=i({});get state(){return n(this.#a)}set state(e){s(this.#a,e)}#o=i(-1);get status(){return n(this.#o)}set status(e){s(this.#o,e)}#s=i(new URL(Pe));get url(){return n(this.#s)}set url(e){s(this.#s,e)}},N=new class{#e=i(null);get current(){return n(this.#e)}set current(e){s(this.#e,e)}},P=new class{#e=i(!1);get current(){return n(this.#e)}set current(e){s(this.#e,e)}},Ee.v=()=>P.current=!0);function Fe(e){Object.assign(M,e)}var{onMount:Ie,tick:Le}=o,Re=new Set([`icon`,`shortcut icon`,`apple-touch-icon`]),F=null,I=de(`sveltekit:scroll`)??{},L=de(`sveltekit:snapshot`)??{},R={url:Te({}),page:Te({}),navigating:r(null),updated:De()};function ze(e){I[e]=D()}function Be(e,t){let n=e+1;for(;I[n];)delete I[n],n+=1;for(n=t+1;L[n];)delete L[n],n+=1}function z(e,t=!1){return t?location.replace(e.href):location.href=e.href,new Promise(h)}async function Ve(){if(`serviceWorker`in navigator){let e=await navigator.serviceWorker.getRegistration(S||`/`);e&&await e.update()}}var He,Ue,We,B,Ge,V,Ke={},qe={},Je=[],Ye=[],H=null;function Xe(){H?.fork?.then(e=>e?.discard()),H=null,Q={element:void 0,href:void 0}}var Ze=new Map,Qe=new Set,$e=new Set,U=new Set,W={branch:[],error:null,url:null,nav:null},et=!1,tt=!1,nt=!0,G=!1,K=!1,rt=!1,it=!1,at,q,J,Y,ot=new Set,st=new Map,ct=new Map;async function lt(e,t,n){if(globalThis.__sveltekit_lq9pg8.data){let{q:e={},p:t={},l:n={},f:r={}}=globalThis.__sveltekit_lq9pg8.data;for(let t in e)Ke[t]=e[t];for(let e in n)Ke[e]=n[e];for(let e in r)Ke[e]=r[e];for(let e in t)qe[e]=t[e]}document.URL!==location.href&&(location.href=location.href),V=e,await e.hooks.init?.(),He=ue(e),B=document.documentElement,Ge=t,Ue=e.nodes[0],We=e.nodes[1],Ue(),We(),q=history.state?.[C],J=history.state?.[w],q||(q=J=Date.now(),history.replaceState({...history.state,[C]:q,[w]:J},``));let r=I[q];function i(){r&&(history.scrollRestoration=`manual`,scrollTo(r.x,r.y))}n?(i(),await zt(Ge,n)):(await Z({type:`enter`,url:be(V.hash?Gt(new URL(location.href)):location.href),replace_state:!0}),i()),Rt()}function ut(){Je.length=0,it=!1}function dt(e){Ye.some(e=>e?.snapshot)&&(L[e]=Ye.map(e=>e?.snapshot?.capture()))}function ft(e){L[e]?.forEach((e,t)=>{Ye[t]?.snapshot?.restore(e)})}function pt(){ze(q),fe(ve,I),dt(J),fe(_e,L)}async function mt(e,n,r,i){let a,o;n.invalidateAll&&Xe(),await Z({type:`goto`,url:be(e),keepfocus:n.keepFocus,noscroll:n.noScroll,replace_state:n.replaceState,state:n.state,redirect_count:r,nav_token:i,accept:()=>{if(n.invalidateAll){it=!0,a=new Set;for(let[e,t]of st)for(let[n,r]of t)r.resource?.reset(),a.add(j(e,n));o=new Set;for(let[e,t]of ct)for(let n of t.keys())o.add(j(e,n))}n.invalidate&&n.invalidate.forEach(Lt)}}),n.invalidateAll&&t().then(t).then(()=>{for(let[e,t]of st)for(let[n,{resource:r}]of t)a?.has(j(e,n))&&r.start();for(let[e,t]of ct)for(let[n,{resource:r}]of t)o?.has(j(e,n))&&r.reconnect()})}async function ht(e){if(e.id!==H?.id){Xe();let t={};ot.add(t),H={id:e.id,token:t,promise:Tt({...e,preload:t}).then(e=>(ot.delete(t),e.type===`loaded`&&e.state.error&&Xe(),e)),fork:null}}return H.promise}async function gt(e){let t=(await X(e,!1))?.route;t&&await Promise.all([...t.layouts,t.leaf].filter(Boolean).map(e=>e[1]()))}async function _t(e,t,n){let r={params:W.params,route:{id:W.route?.id??null},url:new URL(location.href)};if(W={...e.state,nav:r},Fe(e.props.page),at=new V.root({target:t,props:{...e.props,stores:R,components:Ye},hydrate:n,sync:!1,transformError:void 0}),await Promise.resolve(),n){let e={from:null,to:{...r,scroll:I[q]??D()},willUnload:!1,type:`enter`,complete:Promise.resolve()};U.forEach(t=>t(e))}ft(J),tt=!0}async function vt({url:e,params:t,branch:n,errors:r,status:i,error:a,route:o,form:s}){let c=`never`;if(S&&(e.pathname===S||e.pathname===S+`/`))c=`always`;else for(let e of n)e?.slash!==void 0&&(c=e.slash);e.pathname=d(e.pathname,c),e.search=e.search;let l={type:`loaded`,state:{url:e,params:t,branch:n,error:a,route:o},props:{constructors:Ae(n).map(e=>e.node.component),page:Wt(M)}};s!==void 0&&(l.props.form=s);let u={},f=!M,p=0;for(let e=0;e<Math.max(n.length,W.branch.length);e+=1){let t=n[e],r=W.branch[e];t?.data!==r?.data&&(f=!0),t&&(u={...u,...t.data},f&&(l.props[`data_${p}`]=u),p+=1)}return(!W.url||e.href!==W.url.href||W.error!==a||s!==void 0&&s!==M.form||f)&&(l.props.page={error:a,params:t,route:{id:o?.id??null},state:{},status:i,url:new URL(e),form:s??null,data:f?u:M.data}),l}async function yt({loader:e,parent:t,url:n,params:r,route:i,server_data_node:a}){let o={dependencies:new Set,params:new Set,parent:!1,route:!1,url:!1,search_params:new Set},s=await e();return{node:s,loader:e,server:a,universal:s.universal?.load?{type:`data`,data:null,uses:o}:null,data:a?.data??null,slash:s.universal?.trailingSlash??a?.slash}}function bt(e,t,n){let r=e instanceof Request?e.url:e,i=new URL(r,n);return i.origin===n.origin&&(r=i.href.slice(n.origin.length)),{resolved:i,promise:tt?y(r,i.href,t):te(r,t)}}function xt(e,t,n,r,i,a){if(it)return!0;if(!i)return!1;if(i.parent&&e||i.route&&t||i.url&&n)return!0;for(let e of i.search_params)if(r.has(e))return!0;for(let e of i.params)if(a[e]!==W.params[e])return!0;for(let e of i.dependencies)if(Je.some(t=>t(new URL(e))))return!0;return!1}function St(e,t){return e?.type===`data`?e:e?.type===`skip`?t??null:null}function Ct(e,t){if(!e)return new Set(t.searchParams.keys());let n=new Set([...e.searchParams.keys(),...t.searchParams.keys()]);for(let r of n){let i=e.searchParams.getAll(r),a=t.searchParams.getAll(r);i.every(e=>a.includes(e))&&a.every(e=>i.includes(e))&&n.delete(r)}return n}function wt({error:e,url:t,route:n,params:r}){return{type:`loaded`,state:{error:e,url:t,route:n,params:r,branch:[]},props:{page:Wt(M),constructors:[]}}}async function Tt({id:e,invalidating:t,url:n,params:r,route:i,preload:a}){if(H?.id===e)return ot.delete(H.token),H.promise;let{errors:o,layouts:s,leaf:u}=i,d=[...s,u];o.forEach(e=>e?.().catch(h)),d.forEach(e=>e?.[1]().catch(h));let f=W.url?e!==At(W.url):!1,p=W.route?i.id!==W.route.id:!1,m=Ct(W.url,n),ee=!1,g=d.map(async(e,t)=>{if(!e)return;let a=W.branch[t];return e[1]===a?.loader&&!xt(ee,p,f,m,a.universal?.uses,r)?a:(ee=!0,yt({loader:e[1],url:n,params:r,route:i,parent:async()=>{let e={};for(let n=0;n<t;n+=1)Object.assign(e,(await g[n])?.data);return e},server_data_node:St(e[0]?{type:`skip`}:null,e[0]?a?.server:void 0)}))});for(let e of g)e.catch(h);let _=[];for(let e=0;e<d.length;e+=1)if(d[e])try{_.push(await g[e])}catch(t){if(t instanceof l)return{type:`redirect`,location:t.location};if(a&&ot.has(a))return wt({error:await $(t,{params:r,url:n,route:{id:i.id}}),url:n,params:r,route:i});let s=je(t),u;if(t instanceof c)u=t.body;else{if(await R.updated.check())return await Ve(),await z(n);u=await $(t,{params:r,url:n,route:{id:i.id}})}let d=await Et(e,_,o);return d?vt({url:n,params:r,branch:_.slice(0,d.idx).concat(d.node),errors:o,status:s,error:u,route:i}):await Mt(n,{id:i.id},u,s)}else _.push(void 0);return vt({url:n,params:r,branch:_,errors:o,status:200,error:null,route:i,form:t?void 0:null})}async function Et(e,t,n){for(;e--;)if(n[e]){let r=e;for(;!t[r];)--r;try{return{idx:r+1,node:{node:await n[e](),loader:n[e],data:{},server:null,universal:null}}}catch{continue}}}async function Dt({status:e,error:t,url:n,route:r}){let i={};try{return vt({url:n,params:i,branch:[await yt({loader:Ue,url:n,params:i,route:r,parent:()=>Promise.resolve({}),server_data_node:St(null)}),{node:await We(),loader:We,universal:null,server:null,data:null}],status:e,error:t,errors:[],route:null})}catch(t){if(t instanceof l){await mt(new URL(t.location,location.href),{},0);return}let a=await V.get_error_template(),o=await $(t,{url:n,params:i,route:r}),s=a({status:e,message:String(o?.message??``).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}),c=new DOMParser().parseFromString(s,`text/html`);throw document.documentElement.replaceChild(document.adoptNode(c.head),document.head),document.documentElement.replaceChild(document.adoptNode(c.body),document.body),t}}async function Ot(e){let t=e.href;if(Ze.has(t))return Ze.get(t);let n;try{let r=(async()=>{let t=await V.hooks.reroute({url:new URL(e),fetch:async(t,n)=>bt(t,n,e).promise})??e;if(typeof t==`string`){let n=new URL(e);V.hash?n.hash=t:n.pathname=t,t=n}return t})();Ze.set(t,r),n=await r}catch{Ze.delete(t);return}return n}async function X(e,t){if(e&&!A(e,S,V.hash)){let n=await Ot(e);if(!n)return;let r=kt(n);for(let n of He){let i=n.exec(r);if(i)return{id:At(e),invalidating:t,route:n,params:p(i),url:e}}}}function kt(e){return f(V.hash?e.hash.replace(/^#/,``).replace(/[?#].+/,``):e.pathname.slice(S.length))||`/`}function At(e){return(V.hash?e.hash.replace(/^#/,``):e.pathname)+e.search}function jt({url:e,type:t,intent:n,delta:r,event:i,scroll:a}){let o=!1,s=Ut(W,n,e,t,a??null);r!==void 0&&(s.navigation.delta=r),i!==void 0&&(s.navigation.event=i);let c={...s.navigation,cancel:()=>{o=!0,s.reject(Error(`navigation cancelled`))}};return G||Qe.forEach(e=>e(c)),o?null:s}async function Z({type:n,url:r,popped:i,keepfocus:a,noscroll:o,replace_state:s,state:c={},redirect_count:l=0,nav_token:d={},accept:f=h,block:p=h,event:m}){let ee=Y;Y=d;let g=await X(r,!1),_=n===`enter`?Ut(W,g,r,n):jt({url:r,type:n,delta:i?.delta,intent:g,scroll:i?.scroll,event:m});if(!_){p(),Y===d&&(Y=ee);return}let v=q,te=J;f(),G=!0,tt&&_.navigation.type!==`enter`&&R.navigating.set(N.current=_.navigation);let y=g&&await Tt(g);if(!y){if(A(r,S,V.hash))return await z(r,s);y=await Mt(r,{id:null},await $(new u(404,`Not Found`,`Not found: ${r.pathname}`),{url:r,params:{},route:{id:null}}),404,s)}if(r=g?.url||r,Y!==d){_.reject(Error(`navigation aborted`));return}if(!y)return;if(y.type===`redirect`){if(l<20){await Z({type:n,url:new URL(y.location,r),popped:i,keepfocus:a,noscroll:o,replace_state:s,state:c,redirect_count:l+1,nav_token:d}),_.fulfil(void 0);return}if(y=await Dt({status:500,error:await $(Error(`Redirect loop`),{url:r,params:{},route:{id:null}}),url:r,route:{id:null}}),!y)return}else if(y.props.page.status>=400&&await R.updated.check())return await Ve(),await z(r,s);if(ut(),ze(v),dt(te),y.props.page.url.pathname!==r.pathname&&(r.pathname=y.props.page.url.pathname),c=i?i.state:c,!i){let e=+!s,t={[C]:q+=e,[w]:J+=e,[ye]:c};(s?history.replaceState:history.pushState).call(history,t,``,r),s||Be(q,J)}let b=g&&H?.id===g.id?H.fork:null;H?.fork&&!b?Xe():(H=null,Q={element:void 0,href:void 0}),y.props.page.state=c;let ne;if(tt){let t=(await Promise.all(Array.from($e,e=>e(_.navigation)))).filter(e=>typeof e==`function`);if(t.length>0){function e(){t.forEach(e=>{U.delete(e)})}t.push(e),t.forEach(e=>{U.add(e)})}let n=_.navigation.to;W={...y.state,nav:{params:n.params,route:n.route,url:n.url}},y.props.page&&(y.props.page.url=r),!a&&document.activeElement instanceof HTMLElement&&document.activeElement!==document.body&&document.activeElement.blur();let i=b&&await b;i?ne=i.commit():(F=null,at.$set(y.props),F&&Object.assign(y.props.page,F),Fe(y.props.page),ne=e?.()),rt=!0}else await _t(y,Ge,!1);let{activeElement:re}=document;if(await ne,await t(),await t(),Y!==d){_.reject(Error(`navigation aborted`));return}y.props.page&&F&&Object.assign(y.props.page,F);let x=null;if(nt){let e=i?i.scroll:o?D():null;e?scrollTo(e.x,e.y):(x=r.hash&&document.getElementById(Kt(r)))?x.scrollIntoView():scrollTo(0,0)}let ie=document.activeElement!==re&&document.activeElement!==document.body;!a&&!ie&&Ht(r,!x),nt=!0,G=!1,_.fulfil(void 0),_.navigation.to&&(_.navigation.to.scroll=D()),U.forEach(e=>e(_.navigation)),n===`popstate`&&ft(J),R.navigating.set(N.current=null)}async function Mt(e,t,n,r,i){return e.origin===E&&e.pathname===location.pathname&&!et?await Dt({status:r,error:n,url:e,route:t}):await z(e,i)}var Q={element:void 0,href:void 0};function Nt(){let e,t;B.addEventListener(`mousemove`,t=>{let n=t.target;clearTimeout(e),e=setTimeout(()=>{i(n,T.hover)},20)});function n(e){e.defaultPrevented||i(e.composedPath()[0],T.tap)}B.addEventListener(`mousedown`,n),B.addEventListener(`touchstart`,n,{passive:!0});let r=new IntersectionObserver(e=>{for(let t of e)t.isIntersecting&&(gt(new URL(t.target.href)),r.unobserve(t.target))},{threshold:0});async function i(e,n){let r=Ce(e,B),i=r===Q.element&&r?.href===Q.href&&n>=t;if(!r||i)return;let{url:a,external:o,download:s}=we(r,S,V.hash);if(o||s)return;let c=k(r),l=a&&At(W.url)===At(a);if(!(c.reload||l))if(n<=c.preload_data){Q={element:r,href:r.href},t=T.tap;let e=await X(a,!1);if(!e)return;ht(e)}else n<=c.preload_code&&(Q={element:r,href:r.href},t=n,gt(a))}function a(){r.disconnect();for(let e of B.querySelectorAll(`a`)){let{url:t,external:n,download:i}=we(e,S,V.hash);if(n||i)continue;let a=k(e);a.reload||(a.preload_code===T.viewport&&r.observe(e),a.preload_code===T.eager&&gt(t))}}U.add(a),a()}function $(e,t){if(e instanceof c)return e.body;let n=je(e),r=Me(e);return V.hooks.handleError({error:e,event:t,status:n,message:r})??{message:r}}function Pt(e,t){Ie(()=>(e.add(t),()=>{e.delete(t)}))}function Ft(e){Pt(U,e)}function It(e,t={}){return e=new URL(be(e)),e.origin===E?mt(e,t,0):Promise.reject(Error(`goto: invalid URL`))}function Lt(e){if(typeof e==`function`)Je.push(e);else{let{href:t}=new URL(e,location.href);Je.push(e=>e.href===t)}}function Rt(){history.scrollRestoration=`manual`,addEventListener(`beforeunload`,e=>{let t=!1;if(pt(),!G){let e=Ut(W,void 0,null,`leave`),n={...e.navigation,cancel:()=>{t=!0,e.reject(Error(`navigation cancelled`))}};Qe.forEach(e=>e(n))}t?(e.preventDefault(),e.returnValue=``):history.scrollRestoration=`auto`}),addEventListener(`visibilitychange`,()=>{document.visibilityState===`hidden`&&pt()}),navigator.connection?.saveData||Nt(),B.addEventListener(`click`,async t=>{if(t.button||t.which!==1||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.defaultPrevented)return;let n=Ce(t.composedPath()[0],B);if(!n)return;let{url:r,external:i,target:a,download:o}=we(n,S,V.hash);if(!r)return;if(a===`_parent`||a===`_top`){if(window.parent!==window)return}else if(a&&a!==`_self`)return;let s=k(n);if(!(n instanceof SVGAElement)&&r.protocol!==location.protocol&&!(r.protocol===`https:`||r.protocol===`http:`)||o)return;let[c,l]=(V.hash?r.hash.replace(/^#/,``):r.href).split(`#`),u=c===m(location);if(i||s.reload&&(!u||!l)){jt({url:r,type:`link`,event:t})?G=!0:t.preventDefault();return}if(l!==void 0&&u){let[,i]=W.url.href.split(`#`);if(i===l){if(t.preventDefault(),l===``||l===`top`&&n.ownerDocument.getElementById(`top`)===null)scrollTo({top:0});else{let e=n.ownerDocument.getElementById(decodeURIComponent(l));e&&(e.scrollIntoView(),e.focus())}return}if(K=!0,ze(q),e(r),!s.replace_state)return;K=!1}t.preventDefault(),await new Promise(e=>{requestAnimationFrame(()=>{setTimeout(e,0)}),setTimeout(e,100)}),await Z({type:`link`,url:r,keepfocus:s.keepfocus,noscroll:s.noscroll,replace_state:s.replace_state??r.href===location.href,event:t})}),B.addEventListener(`submit`,e=>{if(e.defaultPrevented)return;let t=HTMLFormElement.prototype.cloneNode.call(e.target),n=e.submitter;if((n?.formTarget||t.target)===`_blank`||(n?.formMethod||t.method)!==`get`)return;let r=new URL(n?.hasAttribute(`formaction`)&&n?.formAction||t.action);if(A(r,S,!1))return;let i=e.target,a=k(i);if(a.reload)return;e.preventDefault(),e.stopPropagation();let o=new FormData(i,n);r.search=new URLSearchParams(o).toString(),Z({type:`form`,url:r,keepfocus:a.keepfocus,noscroll:a.noscroll,replace_state:a.replace_state??r.href===location.href,event:e})}),addEventListener(`popstate`,async t=>{if(!Vt)if(t.state?.[`sveltekit:history`]){let n=t.state[C];if(Y={},n===q)return;let r=I[n],i=t.state[`sveltekit:states`]??{},a=new URL(t.state[`sveltekit:pageurl`]??location.href),o=t.state[w],s=W.url?m(location)===m(W.url):!1;if(o===J&&(rt||s)){i!==M.state&&(M.state=i),e(a),I[q]=D(),r&&scrollTo(r.x,r.y),q=n;return}let c=n-q;await Z({type:`popstate`,url:a,popped:{state:i,scroll:r,delta:c},accept:()=>{q=n,J=o},block:()=>{history.go(-c)},nav_token:Y,event:t})}else K||(e(new URL(location.href)),V.hash&&location.reload())}),addEventListener(`hashchange`,()=>{K&&(K=!1,history.replaceState({...history.state,[C]:++q,[w]:J},``,location.href))});for(let e of document.querySelectorAll(`link`))Re.has(e.rel)&&(e.href=e.href);addEventListener(`pageshow`,e=>{e.persisted&&R.navigating.set(N.current=null)});function e(e){W.url=M.url=e,R.page.set(Wt(M)),R.page.notify()}}async function zt(e,{status:t=200,error:n,node_ids:r,params:i,route:a,server_route:o,data:s,form:c}){et=!0;let u=new URL(location.href),d;({params:i={},route:a={id:null}}=await X(u,!1)||{}),d=He.find(({id:e})=>e===a.id);let f,p=!0;try{let e=r.map(async(t,n)=>{let r=s[n];return r?.uses&&(r.uses=Bt(r.uses)),yt({loader:V.nodes[t],url:u,params:i,route:a,parent:async()=>{let t={};for(let r=0;r<n;r+=1)Object.assign(t,(await e[r]).data);return t},server_data_node:St(r)})}),o=await Promise.all(e);if(d){let e=d.layouts;for(let t=0;t<e.length;t++)e[t]||o.splice(t,0,void 0)}f=await vt({url:u,params:i,branch:o,status:t,error:n,errors:d?.errors,form:c,route:d??null})}catch(t){if(t instanceof l)return await z(new URL(t.location,location.href));f=await Dt({status:je(t),error:await $(t,{url:u,params:i,route:a}),url:u,route:a}),e.textContent=``,p=!1}f&&(f.props.page&&(f.props.page.state={}),await _t(f,e,p))}function Bt(e){return{dependencies:new Set(e?.dependencies??[]),params:new Set(e?.params??[]),parent:!!e?.parent,route:!!e?.route,url:!!e?.url,search_params:new Set(e?.search_params??[])}}var Vt=!1;function Ht(e,t=!0){let n=document.querySelector(`[autofocus]`);if(n)n.focus();else{let n=Kt(e);if(n&&document.getElementById(n)){let{x:r,y:i}=D();setTimeout(()=>{let a=history.state;Vt=!0,location.replace(new URL(`#${n}`,location.href)),history.replaceState(a,``,e),t&&scrollTo(r,i),Vt=!1})}else{let e=document.body,t=e.getAttribute(`tabindex`);e.tabIndex=-1,e.focus({preventScroll:!0,focusVisible:!1}),t===null?e.removeAttribute(`tabindex`):e.setAttribute(`tabindex`,t)}let r=getSelection();if(r&&r.type!==`None`){let e=[];for(let t=0;t<r.rangeCount;t+=1)e.push(r.getRangeAt(t));setTimeout(()=>{if(r.rangeCount===e.length){for(let t=0;t<r.rangeCount;t+=1){let n=e[t],i=r.getRangeAt(t);if(n.commonAncestorContainer!==i.commonAncestorContainer||n.startContainer!==i.startContainer||n.endContainer!==i.endContainer||n.startOffset!==i.startOffset||n.endOffset!==i.endOffset)return}r.removeAllRanges()}})}}}function Ut(e,t,n,r,i=null){let a,o,s=new Promise((e,t)=>{a=e,o=t});return s.catch(h),{navigation:{from:{params:e.params,route:{id:e.route?.id??null},url:e.url,scroll:D()},to:n&&{params:t?.params??null,route:{id:t?.route?.id??null},url:n,scroll:i},willUnload:!t,type:r,complete:s},fulfil:a,reject:o}}function Wt(e){return{data:e.data,error:e.error,form:e.form,params:e.params,route:e.route,state:e.state,status:e.status,url:e.url}}function Gt(e){let t=new URL(e);return t.hash=decodeURIComponent(e.hash),t}function Kt(e){let t;if(V.hash){let[,,n]=e.hash.split(`#`,3);t=n??``}else t=e.hash.slice(1);return decodeURIComponent(t)}export{N as a,Oe as c,R as i,he as l,It as n,M as o,lt as r,P as s,Ft as t};
@@ -1,2 +0,0 @@
1
- I@�v�Ǖ�K�՘�Jo�Teia8�e-ȑs8;���%D�sjL#T��r�Q���Qm�/�0 ��B��Uc�I~Gkn�E
2
- �
@@ -1 +0,0 @@
1
- import{c as e,r as t}from"../chunks/Bsj1ssvc.js";export{e as load_css,t as start};