@gradial/aci 0.1.52-rc.8 → 0.1.52

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 (254) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +86 -5
  3. package/dist/astro/error-page.js +1 -0
  4. package/dist/astro/index.js +4 -0
  5. package/dist/astro/page.d.ts +5 -2
  6. package/dist/astro/page.js +35 -23
  7. package/dist/astro/preview.js +2 -17
  8. package/dist/audience-data-models.d.ts +308 -197
  9. package/dist/audience-data-models.js +313 -51
  10. package/dist/cli/compile-registry.mjs +6 -34
  11. package/dist/cli/mintlify-render.mjs +8 -0
  12. package/dist/collect/aci.js +1 -1
  13. package/dist/collect/aci.js.sha256 +1 -1
  14. package/dist/collect/api.d.ts +6 -7
  15. package/dist/collect/api.js +21 -8
  16. package/dist/collect/assignments.d.ts +7 -9
  17. package/dist/collect/assignments.js +23 -32
  18. package/dist/collect/batcher.d.ts +9 -7
  19. package/dist/collect/batcher.js +6 -5
  20. package/dist/collect/consent/envelope.d.ts +7 -1
  21. package/dist/collect/consent/envelope.js +3 -1
  22. package/dist/collect/consent/mapping.d.ts +2 -0
  23. package/dist/collect/consent/mapping.js +1 -0
  24. package/dist/collect/consenthold.d.ts +38 -0
  25. package/dist/collect/consenthold.js +82 -0
  26. package/dist/collect/declarative.js +7 -5
  27. package/dist/collect/gapbuffer.d.ts +13 -4
  28. package/dist/collect/gapbuffer.js +21 -10
  29. package/dist/collect/index.js +78 -21
  30. package/dist/collect/pageviews.d.ts +11 -11
  31. package/dist/collect/pageviews.js +27 -22
  32. package/dist/consent-banner/index.d.ts +17 -0
  33. package/dist/consent-banner/index.js +23 -0
  34. package/dist/content/index.d.ts +2 -1
  35. package/dist/content/index.js +4 -1
  36. package/dist/content/provider.d.ts +16 -2
  37. package/dist/content/provider.js +5 -1
  38. package/dist/content/resolve-slots.d.ts +24 -2
  39. package/dist/content/resolve-slots.js +127 -21
  40. package/dist/content/types.d.ts +5 -1
  41. package/dist/edge/expression-capabilities.v1.d.ts +106 -0
  42. package/dist/edge/expression-capabilities.v1.js +165 -0
  43. package/dist/index.d.ts +1 -2
  44. package/dist/index.js +0 -1
  45. package/dist/internal/domain/edge/identity.d.ts +47 -4
  46. package/dist/internal/domain/edge/identity.js +130 -26
  47. package/dist/internal/domain/edge/index.d.ts +1 -1
  48. package/dist/internal/domain/edge/index.js +1 -1
  49. package/dist/internal/domain/edge/mimic_token.d.ts +14 -0
  50. package/dist/internal/domain/edge/mimic_token.js +125 -0
  51. package/dist/internal/domain/edge/personalization-core.d.ts +61 -22
  52. package/dist/internal/domain/edge/personalization-core.js +790 -200
  53. package/dist/internal/domain/edge/personalization_index.d.ts +17 -0
  54. package/dist/internal/domain/edge/personalization_index.js +55 -0
  55. package/dist/internal/domain/edge/resolve.js +76 -39
  56. package/dist/internal/domain/edge/testdata/flat_only_validator_v1.d.ts +10 -0
  57. package/dist/internal/domain/edge/testdata/flat_only_validator_v1.js +253 -0
  58. package/dist/internal/domain/edge/types.d.ts +82 -78
  59. package/dist/internal/domain/edge/types.js +3 -3
  60. package/dist/internal/domain/edge/variant_key.d.ts +4 -0
  61. package/dist/internal/domain/edge/variant_key.js +56 -0
  62. package/dist/internal/platform/collectionstore/errors.d.ts +24 -0
  63. package/dist/internal/platform/collectionstore/errors.js +48 -0
  64. package/dist/mintlify/blocks.d.ts +6 -0
  65. package/dist/mintlify/blocks.js +201 -0
  66. package/dist/mintlify/config.d.ts +3 -0
  67. package/dist/mintlify/config.js +77 -0
  68. package/dist/mintlify/index.d.ts +3 -0
  69. package/dist/mintlify/index.js +2 -0
  70. package/dist/mintlify/json.d.ts +8 -0
  71. package/dist/mintlify/json.js +37 -0
  72. package/dist/mintlify/materialize.d.ts +14 -0
  73. package/dist/mintlify/materialize.js +254 -0
  74. package/dist/mintlify/types.d.ts +74 -0
  75. package/dist/mintlify/types.js +1 -0
  76. package/dist/mintlify/validate.d.ts +7 -0
  77. package/dist/mintlify/validate.js +256 -0
  78. package/dist/next/assignments-navigation.d.ts +4 -0
  79. package/dist/next/assignments-navigation.js +18 -0
  80. package/dist/next/assignments-script.d.ts +3 -2
  81. package/dist/next/assignments-script.js +5 -5
  82. package/dist/next/error-pages.d.ts +4 -0
  83. package/dist/next/error-pages.js +4 -0
  84. package/dist/next/error-seat-payload.d.ts +2 -1
  85. package/dist/next/error-seat-payload.js +14 -24
  86. package/dist/next/error-seat.js +7 -2
  87. package/dist/next/index.d.ts +1 -1
  88. package/dist/next/index.js +3 -1
  89. package/dist/next/page.d.ts +2 -1
  90. package/dist/next/page.js +15 -4
  91. package/dist/next/release-context.d.ts +30 -0
  92. package/dist/next/release-context.js +56 -0
  93. package/dist/next/render.d.ts +1 -1
  94. package/dist/next/render.js +15 -5
  95. package/dist/next/server.d.ts +9 -3
  96. package/dist/next/server.js +17 -32
  97. package/dist/preview/core.d.ts +1 -0
  98. package/dist/preview/core.js +27 -0
  99. package/dist/react/VideoPlayer.d.ts +3 -3
  100. package/dist/react/index.d.ts +3 -3
  101. package/dist/registry.d.ts +4 -2
  102. package/dist/testing/conformance/checks.d.ts +2 -2
  103. package/dist/testing/conformance/checks.js +2 -0
  104. package/dist/testing/conformance/index.d.ts +1 -0
  105. package/dist/testing/conformance/index.js +1 -0
  106. package/dist/testing/conformance/next-stubs.d.ts +6 -0
  107. package/dist/testing/conformance/next-stubs.js +9 -0
  108. package/dist/testing/conformance/preset.d.ts +3 -2
  109. package/dist/testing/conformance/preset.js +15 -8
  110. package/dist/testing/conformance/root-identity.d.ts +31 -0
  111. package/dist/testing/conformance/root-identity.js +361 -0
  112. package/dist/testing/conformance/stubs/next-image.d.ts +7 -0
  113. package/dist/testing/conformance/stubs/next-image.js +5 -0
  114. package/dist/testing/conformance/stubs/next-link.d.ts +7 -0
  115. package/dist/testing/conformance/stubs/next-link.js +4 -0
  116. package/dist/testing/conformance/types.d.ts +5 -2
  117. package/dist/testing/index.d.ts +1 -1
  118. package/dist/testing/index.js +4 -3
  119. package/dist/types/block-ref.js +2 -2
  120. package/dist/types/component.d.ts +9 -0
  121. package/dist/types/config.d.ts +0 -1
  122. package/dist/types/index.d.ts +0 -1
  123. package/dist/types/index.js +0 -1
  124. package/dist/types/page.d.ts +0 -1
  125. package/migrations/conformance-registry.md +22 -0
  126. package/migrations/experiment-goal-ids.md +43 -0
  127. package/package.json +21 -7
  128. package/src/cli/compile-registry.mjs +6 -30
  129. package/src/cli/mintlify-render.mjs +9 -0
  130. package/src/types/block-ref.test.ts +16 -1
  131. package/src/types/block-ref.ts +2 -2
  132. package/src/types/component.ts +10 -0
  133. package/src/types/config.ts +0 -1
  134. package/src/types/index.ts +0 -1
  135. package/src/types/page.ts +0 -1
  136. package/templates/astro/starter-content/src/components/chrome/Footer.astro +5 -3
  137. package/templates/astro/starter-content/src/components/chrome/Header.astro +5 -3
  138. package/templates/astro/starter-content/src/components/elements/Button.astro +5 -2
  139. package/templates/astro/starter-content/src/components/elements/ButtonBlock.astro +5 -3
  140. package/templates/astro/starter-content/src/components/sections/ContainerSection.astro +4 -3
  141. package/templates/astro/starter-content/src/components/sections/FeatureCard.astro +4 -3
  142. package/templates/astro/starter-content/src/components/sections/FeatureGrid.astro +4 -3
  143. package/templates/astro/starter-content/src/components/sections/HomeHero.astro +5 -3
  144. package/templates/astro/starter-content/src/components/sections/PersonalizationChoice.astro +4 -3
  145. package/templates/astro/starter-content/src/components/sections/StatsBar.astro +4 -3
  146. package/templates/astro/starter-content/src/fixtures/sections.ts +1 -1
  147. package/templates/astro/starter-content/src/stories/CompositionStoryFrame.astro +7 -2
  148. package/templates/astro/template/.aci.yaml.tmpl +0 -1
  149. package/templates/astro/template/package.json.tmpl +5 -5
  150. package/templates/astro/template/src/layouts/SiteLayout.astro +2 -2
  151. package/templates/common/.agents/skills/aci/SKILL.md +58 -1
  152. package/templates/common/.agents/skills/authoring/SKILL.md +194 -42
  153. package/templates/common/.agents/skills/authoring/references/block-registry.md +19 -3
  154. package/templates/common/.agents/skills/authoring/references/contracts.md +9 -30
  155. package/templates/common/.agents/skills/authoring/references/repo-structure.md +5 -4
  156. package/templates/common/.agents/skills/authoring/references/sdk-server-functions.md +3 -3
  157. package/templates/common/.agents/skills/dam-delivery/SKILL.md +216 -0
  158. package/templates/common/.agents/skills/dam-delivery/references/permalink-grammar.md +167 -0
  159. package/templates/common/.agents/skills/migration/references/canon-migration.md +18 -67
  160. package/templates/common/.agents/skills/migration/references/selector-map.md +1 -1
  161. package/templates/common/.content/fragments/navbar/_index.json +24 -0
  162. package/templates/common/.content/fragments/site-footer/_index.json +61 -0
  163. package/templates/common/.content/pages/404/_index.json +4 -2
  164. package/templates/common/.content/pages/_index.json +0 -1
  165. package/templates/common/.content/pages/error/_index.json +4 -2
  166. package/templates/common/.content/schemas/site.schema.json +11 -1
  167. package/templates/common/.content/templates/error.json +24 -0
  168. package/templates/common/.content/templates/home.json +28 -0
  169. package/templates/common/.content/templates/site.json +8 -0
  170. package/templates/common/.content/templates/standard.json +24 -0
  171. package/templates/common/.nvmrc +1 -1
  172. package/templates/common/starter-content/.content/config/site.json +1 -1
  173. package/templates/common/starter-content/.content/dam/README.md +74 -0
  174. package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000101}/asset.json +1 -1
  175. package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000102}/asset.json +1 -1
  176. package/templates/common/starter-content/.content/pages/404/_index.json +1 -2
  177. package/templates/common/starter-content/.content/pages/{home/_index.json → _index.json} +14 -3
  178. package/templates/common/starter-content/.content/pages/about/_index.json +2 -2
  179. package/templates/common/starter-content/.content/pages/error/_index.json +1 -2
  180. package/templates/common/starter-content/.content/patterns/components/button.json +2 -2
  181. package/templates/common/starter-content/.content/patterns/components/container.json +8 -3
  182. package/templates/common/starter-content/.content/patterns/components/feature_card.json +2 -2
  183. package/templates/common/starter-content/.content/patterns/components/feature_grid.json +5 -3
  184. package/templates/common/starter-content/.content/patterns/components/home_hero.json +2 -2
  185. package/templates/common/starter-content/.content/patterns/components/personalization_choice.json +2 -2
  186. package/templates/common/starter-content/.content/patterns/components/site-footer.json +2 -2
  187. package/templates/common/starter-content/.content/patterns/components/site-navigation.json +2 -2
  188. package/templates/common/starter-content/.content/patterns/components/stats_bar.json +2 -2
  189. package/templates/common/starter-content/.content/schemas/site.schema.json +11 -1
  190. package/templates/nextjs/starter-content/src/components/chrome/Footer.tsx +4 -3
  191. package/templates/nextjs/starter-content/src/components/chrome/Header.tsx +4 -3
  192. package/templates/nextjs/starter-content/src/components/elements/Button.tsx +4 -3
  193. package/templates/nextjs/starter-content/src/components/elements/ButtonBlock.tsx +4 -3
  194. package/templates/nextjs/starter-content/src/components/sections/ContainerSection.tsx +4 -2
  195. package/templates/nextjs/starter-content/src/components/sections/FeatureCard.tsx +4 -3
  196. package/templates/nextjs/starter-content/src/components/sections/FeatureGrid.tsx +4 -2
  197. package/templates/nextjs/starter-content/src/components/sections/HomeHero.tsx +4 -3
  198. package/templates/nextjs/starter-content/src/components/sections/PersonalizationChoice.tsx +4 -2
  199. package/templates/nextjs/starter-content/src/components/sections/StatsBar.tsx +4 -3
  200. package/templates/nextjs/template/.aci.yaml +0 -1
  201. package/templates/nextjs/template/.aci.yaml.tmpl +0 -1
  202. package/templates/nextjs/template/package.json.tmpl +4 -3
  203. package/templates/nextjs/template/src/app/_components/c15t-bridge.ts +30 -0
  204. package/templates/nextjs/template/src/app/_components/c15t-consent-ui.tsx +37 -0
  205. package/templates/nextjs/template/src/app/_components/consent-manager.css +63 -0
  206. package/templates/nextjs/template/src/app/_components/consent-manager.tsx +76 -0
  207. package/templates/nextjs/template/src/app/fonts/inter/OFL.txt +93 -0
  208. package/templates/nextjs/template/src/app/fonts/inter/inter-latin.woff2 +0 -0
  209. package/templates/nextjs/template/src/app/fonts/space-grotesk/OFL.txt +93 -0
  210. package/templates/nextjs/template/src/app/fonts/space-grotesk/space-grotesk-latin.woff2 +0 -0
  211. package/templates/nextjs/template/src/app/layout.tsx +12 -7
  212. package/templates/nextjs/template/tests/conformance.test.ts.tmpl +1 -0
  213. package/dist/define-layout.d.ts +0 -6
  214. package/dist/define-layout.js +0 -14
  215. package/dist/edge/personalization-core.d.ts +0 -11
  216. package/dist/edge/personalization-core.js +0 -269
  217. package/dist/internal/domain/edge/compose.d.ts +0 -24
  218. package/dist/internal/domain/edge/compose.js +0 -89
  219. package/dist/internal/domain/edge/record/codec.d.ts +0 -71
  220. package/dist/internal/domain/edge/record/codec.js +0 -401
  221. package/dist/next/collect-route.d.ts +0 -19
  222. package/dist/next/collect-route.js +0 -459
  223. package/dist/next/edge-config.d.ts +0 -1
  224. package/dist/next/edge-config.js +0 -92
  225. package/dist/next/envelope-digest.d.ts +0 -21
  226. package/dist/next/envelope-digest.js +0 -58
  227. package/dist/next/middleware.d.ts +0 -40
  228. package/dist/next/middleware.js +0 -475
  229. package/dist/next/personalization-host.d.ts +0 -134
  230. package/dist/next/personalization-host.js +0 -270
  231. package/dist/next/root-layout.d.ts +0 -4
  232. package/dist/next/root-layout.js +0 -5
  233. package/dist/next/vercel-collect-sdk-route.d.ts +0 -27
  234. package/dist/next/vercel-collect-sdk-route.js +0 -181
  235. package/dist/next/vercel-edge-projection-v1.d.ts +0 -24
  236. package/dist/next/vercel-edge-projection-v1.js +0 -880
  237. package/dist/next/vercel-personalization.d.ts +0 -4
  238. package/dist/next/vercel-personalization.js +0 -4
  239. package/dist/next/vercel-s3-personalization.d.ts +0 -79
  240. package/dist/next/vercel-s3-personalization.js +0 -570
  241. package/dist/types/layout.d.ts +0 -24
  242. package/src/types/layout.ts +0 -29
  243. package/templates/astro/starter-content/src/render/RenderPage.astro +0 -67
  244. package/templates/astro/template/src/cms/contracts/layouts/index.ts +0 -18
  245. package/templates/common/starter-content/.content/patterns/layouts/default.json +0 -14
  246. package/templates/nextjs/starter-content/src/components/elements/AtomicBlock.tsx +0 -13
  247. package/templates/nextjs/template/src/cms/contracts/layouts/index.ts +0 -16
  248. /package/dist/{types/layout.js → cli/mintlify-render.d.mts} +0 -0
  249. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/editorial.json +0 -0
  250. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000101}/governance.json +0 -0
  251. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/versions/v0001.json +0 -0
  252. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/editorial.json +0 -0
  253. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000102}/governance.json +0 -0
  254. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/versions/v0001.json +0 -0
@@ -1 +1 @@
1
- "use strict";(()=>{var Ne=Object.defineProperty;var Le=(t,e,n)=>e in t?Ne(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var y=(t,e,n)=>Le(t,typeof e!="symbol"?e+"":e,n);var x="data-aci-event",Oe="data-aci-on",H="data-aci-prop-",De="data-aci-refresh",q="custom.";function D(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();if(!(e===""||/[\s/]/.test(e)))return e.startsWith(q)?e:q+e}function Re(t){let e;for(let n of Array.from(t.attributes)){if(!n.name.startsWith(H))continue;let r=n.name.slice(H.length);r!==""&&((e!=null?e:e={})[r]=n.value)}return e}function U(t,e){let n=D(t.getAttribute(x));if(n===void 0){e==null||e("capture",{reason:"malformed_declaration",attr:x});return}return{eventName:n,properties:Re(t)}}function X(t){var e,n;return(n=(e=t.getAttribute(Oe))==null?void 0:e.trim().toLowerCase())!=null?n:"click"}function $(t,e,n){let{document:r,debug:o}=e;r.addEventListener("click",f=>{var l,p;try{let u=f.target;if((l=u==null?void 0:u.closest)==null?void 0:l.call(u,`[${De}]`)){n==null||n();return}let m=(p=u==null?void 0:u.closest)==null?void 0:p.call(u,`[${x}]`);if(!m||X(m)!=="click")return;let g=U(m,o);g&&t(g)}catch(u){o==null||o("capture",{reason:"click_handler_failed",error:String(u)})}});let i=e.intersectionObserver;if(typeof i!="function")return;let s=Array.from(r.querySelectorAll(`[${x}]`)).filter(f=>X(f)==="visible");if(s.length===0)return;let a=new WeakSet,c=new i((f,l)=>{try{for(let p of f){if(!p.isIntersecting||p.intersectionRatio<.5||a.has(p.target))continue;a.add(p.target),l.unobserve(p.target);let u=U(p.target,o);u&&t(u)}}catch(p){o==null||o("capture",{reason:"visible_handler_failed",error:String(p)})}},{threshold:.5});for(let f of s)c.observe(f)}function K(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Y(t,e,n,r){let o=(...a)=>{try{let[c,...f]=a;if(c==="track"){let l=D(f[0]);if(l===void 0){r==null||r("capture",{reason:"malformed_track_name",name:f[0]});return}let p=f[1];if(p!==void 0&&!K(p)){r==null||r("capture",{reason:"malformed_track_properties",name:l});return}n.track(l,p);return}if(c==="consent"){if(e.preset!=="manual"){r==null||r("consent",{reason:"preset_authoritative",preset:e.preset});return}let l=f[0];if(!K(l)){r==null||r("consent",{reason:"malformed_consent_envelope"});return}n.consent({p:l.p,src:l.src});return}r==null||r("capture",{reason:"unknown_command",command:c})}catch(c){r==null||r("capture",{reason:"command_failed",error:String(c)})}},i=t.aci,s=i==null?void 0:i.q;if(t.aci=o,s!=null)for(let a of Array.from(s)){let c=Array.from(a);o(...c)}}var Be="experiment.exposure",Fe='script[type="application/json"][data-aci-assignments]';function Ve(t){if(typeof t!="object"||t===null)return null;let e=t,n=e.experimentId,r=e.armId,o=e.allocationVersion;return typeof n!="string"||n===""||typeof r!="string"||r===""||typeof o!="string"?null:{experimentId:n,armId:r,allocationVersion:o}}function Me(t,e){try{let n=t.querySelector(Fe);if(!n)return[];let r=n.textContent;if(r==null||r.trim()==="")return[];let o=JSON.parse(r);if(typeof o!="object"||o===null)return e==null||e("capture",{reason:"assignments_malformed"}),[];let i=o;if(i.v!==1||!Array.isArray(i.experiments))return e==null||e("capture",{reason:"assignments_malformed"}),[];let s=[];for(let a of i.experiments){let c=Ve(a);c&&s.push(c)}return s}catch(n){return e==null||e("capture",{reason:"assignments_parse_failed",error:String(n)}),[]}}function J(t,e){if(!e||t.experiment!==void 0)return t;let n=e.getActiveAssignments()[0];if(!n)return t;let r={experimentId:n.experimentId,armId:n.armId,allocationVersion:n.allocationVersion};return{...t,experiment:r}}function Q(t){let e=[],n=new Set,r,o=()=>{e=Me(t.document,t.debug);for(let i of e)n.has(i.experimentId)||(n.add(i.experimentId),r==null||r({eventName:Be,url:t.window.location.href,experiment:{experimentId:i.experimentId,armId:i.armId,allocationVersion:i.allocationVersion}}))};return{getActiveAssignments:()=>e.map(i=>({...i})),start(i){r=i,o()},rearm(){n.clear(),o()}}}var Z="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function We(t){globalThis.crypto.getRandomValues(t)}function S(t,e){let n=t!=null?t:Date.now(),r="";for(let c=0;c<10;c++)r=Z[n%32]+r,n=Math.floor(n/32);let o=new Uint8Array(10);(e!=null?e:We)(o);let i="",s=0,a=0;for(let c of o)for(s=s<<8|c,a+=8;a>=5;)i+=Z[s>>>a-5&31],a-=5;return r+i}var Ge=60*1024,je=100,ze=5e3,ee='{"envelopeId":"',te='","events":[',ne="]}",He=26,A=ee.length+He+te.length+ne.length,qe=new TextEncoder,Ue=t=>qe.encode(t).length,T=class{constructor(e){y(this,"options");y(this,"maxBytes");y(this,"queue",[]);y(this,"queuedBytes",0);y(this,"flushing",!1);y(this,"intervalId");var n;this.options=e,this.maxBytes=(n=e.maxBatchBytes)!=null?n:Ge}get pending(){return this.queue.length}push(e){let n=JSON.stringify(e),r=Ue(n);this.queue.push({json:n,bytes:r,eventId:e.eventId}),this.queuedBytes+=r,!this.flushing&&this.envelopeBytes()>=this.maxBytes&&this.flush()}flush(){var e,n;if(!this.flushing){this.flushing=!0;try{(n=(e=this.options).onTick)==null||n.call(e),this.drain()}finally{this.flushing=!1}}}start(){var o,i,s,a;let e=(o=this.options.timers)!=null?o:{setInterval:(c,f)=>setInterval(c,f),clearInterval:c=>clearInterval(c)};this.intervalId=e.setInterval(()=>this.flush(),(i=this.options.flushIntervalMs)!=null?i:ze);let n=(s=this.options.documentTarget)!=null?s:typeof document!="undefined"?document:void 0;n==null||n.addEventListener("visibilitychange",()=>{n.visibilityState==="hidden"&&this.flush()});let r=(a=this.options.windowTarget)!=null?a:typeof window!="undefined"?window:void 0;r==null||r.addEventListener("pagehide",()=>this.flush()),this.flush()}stop(){if(this.intervalId!==void 0){let e=this.options.timers;e?e.clearInterval(this.intervalId):clearInterval(this.intervalId),this.intervalId=void 0}}envelopeBytes(){let e=this.queue.length>1?this.queue.length-1:0;return A+this.queuedBytes+e}drain(){var e,n,r;for(;this.queue.length>0;){let o=this.queue[0];if(A+o.bytes>this.maxBytes){this.queue.shift(),this.queuedBytes-=o.bytes,(n=(e=this.options).debug)==null||n.call(e,"flush",{reason:"oversize_event",eventId:o.eventId,bytes:o.bytes});continue}let i=[],s=A;for(;this.queue.length>0;){let c=this.queue[0];if(A+c.bytes>this.maxBytes||i.length>=je)break;let f=s+c.bytes+(i.length>0?1:0);if(f>this.maxBytes)break;i.push(c.json),s=f,this.queue.shift(),this.queuedBytes-=c.bytes}if(i.length===0)continue;let a=((r=this.options.createEnvelopeId)!=null?r:S)();this.options.send(ee+a+te+i.join(",")+ne)}}};var Xe=new Set(["c15t","onetrust","cookiebot","trustarc","manual"]);function P(t,e){var o;let n=(o=t==null?void 0:t.getAttribute)==null?void 0:o.call(t,e);if(n==null)return;let r=n.trim();return r===""?void 0:r}function re(t){var r;let e=(r=P(t,"data-aci-consent"))==null?void 0:r.toLowerCase(),n=e!==void 0&&Xe.has(e)?e:"manual";return{site:P(t,"data-aci-site"),preset:n,categories:P(t,"data-aci-consent-categories"),debug:P(t,"data-aci-debug")==="1"}}function oe(t,e,n){if(!t)return()=>{};let r=e!=null?e:(i=>console.debug("[aci]",i)),o=n!=null?n:Date.now;return(i,s)=>{try{r({t:o(),kind:i,detail:s})}catch{}}}var R=new TextEncoder,$e=2048,Ke=32,Ye=128,Je=512,Qe=2147483647,Ze=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/,et=/^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g,tt=new Set(["true","all","granted","yes","personalization","personalized"]);function _(t,e=!0){let n=w(t);if(!n)return null;if(e)try{n=decodeURIComponent(n)}catch{}if(n=w(n),!n||R.encode(n).byteLength>$e)return null;if(tt.has(n.toLowerCase()))return{version:0,purposes:["personalization"],grantedAt:""};try{let r=JSON.parse(n),o=typeof r.t=="string"?r.t:"";return!Number.isInteger(r.v)||r.v<0||r.v>Qe||!Array.isArray(r.p)||r.p.length>Ke||!r.p.every(i=>typeof i=="string")||r.p.some(i=>R.encode(i).byteLength>Ye)||r.t!==void 0&&r.t!==null&&(typeof r.t!="string"||r.t===""||!nt(r.t))||r.src!==void 0&&r.src!==null&&typeof r.src!="string"||typeof r.src=="string"&&R.encode(r.src).byteLength>Je?null:{version:r.v,purposes:r.p,grantedAt:o,source:typeof r.src=="string"?r.src:void 0}}catch{return null}}function B(t){return(t==null?void 0:t.purposes.some(e=>w(e).toLowerCase()==="personalization"))||!1}function w(t){return t.replace(et,"")}function nt(t){let e=Ze.exec(t);if(!e||Number.isNaN(Date.parse(t)))return!1;let n=Number(e[1]),r=Number(e[2]),o=Number(e[3]),i=Number(e[4]),s=Number(e[5]),a=Number(e[6]);if(r<1||r>12||o<1||o>rt(n,r)||i>23||s>59||a>59)return!1;let c=e[8];return c==="Z"||Number(c.slice(1,3))<=23&&Number(c.slice(4,6))<=59}function rt(t,e){return e===2?t%4===0&&(t%100!==0||t%400===0)?29:28:[4,6,9,11].includes(e)?30:31}var ie="personalization",F="aci_consent",V=1,ot=365*24*60*60;function it(t,e){var r;let n=`${F}=${t.encoded}; Path=/; Max-Age=${ot}; SameSite=Lax`;((r=e.document.location)==null?void 0:r.protocol)==="https:"&&(n+="; Secure"),e.document.cookie=n}function I(t,e,n){var o;let r=st(t,e,n.now);return r===null?!1:(B(r.snapshot)||(o=n.gapBuffer)==null||o.purge(),it(r,n),!0)}function se(t){for(let e of t.cookie.split(";")){let n=w(e);if(n.startsWith(F+"="))return n.slice(F.length+1)}}function ae(t){return t===void 0||t===""?!1:B(_(t,!0))}function ce(t){var r;if(!Array.isArray(t))return;let e=[];for(let o of t){if(typeof o!="string")return;e.push(w(o))}let n=JSON.stringify({v:V,p:e});return(r=_(n,!1))==null?void 0:r.purposes}function ue(t){var o;if(t!==void 0&&typeof t!="string")return;let e=typeof t=="string"?w(t):"",r=JSON.stringify({v:V,p:[],src:e===""?"manual":e});return(o=_(r,!1))==null?void 0:o.source}function st(t,e,n){try{let r=JSON.stringify({v:V,p:t,t:new Date((n!=null?n:Date.now)()).toISOString(),src:e}),o=_(r,!1);return o===null?null:{encoded:encodeURIComponent(r),snapshot:o}}catch{return null}}var at="cmp-",ct=/^[a-z0-9._-]+$/,ut={c15t:"measurement,marketing",onetrust:"c0002,c0004",cookiebot:"statistics,marketing",trustarc:"functional,advertising"};function M(t,e){let n=e!=null?e:ut[t];if(n===void 0)return null;let r=n.split(",").map(o=>o.trim().toLowerCase()).filter(o=>o!=="");if(r.length===0)return null;for(let o of r)if(!ct.test(o))return null;return r}function ft(t,e){return e.filter(r=>r in t.categories).some(r=>t.categories[r]===!0)?[ie]:[]}function k(t,e,n){var r,o,i,s;try{let a=M(e,n.categories);if(a===null){(r=n.debug)==null||r.call(n,"consent",{reason:"unparseable_mapping",preset:e});return}if(a.filter(l=>l in t.categories).length===0){(o=n.debug)==null||o.call(n,"consent",{reason:"unmappable_cmp_state",preset:e});return}let f=ft(t,a);I(f,at+e,{document:n.document,gapBuffer:n.gapBuffer,now:n.now}),(i=n.debug)==null||i.call(n,"consent",{reason:"written",preset:e,purposes:f})}catch(a){(s=n.debug)==null||s.call(n,"consent",{reason:"consent_bridge_failed",preset:e,error:String(a)})}}var fe=250,lt=1e4;function C(t,e,n){var s;let r=(s=n==null?void 0:n.scheduler)!=null?s:{setTimeout:(a,c)=>setTimeout(a,c),clearTimeout:a=>clearTimeout(a)},o=Math.floor(lt/fe),i=()=>{var c,f;let a;try{a=t()}catch(l){(c=n==null?void 0:n.debug)==null||c.call(n,"consent",{reason:"cmp_read_failed",error:String(l)});return}if(a!==void 0){e(a);return}if(o-=1,o<=0){(f=n==null?void 0:n.debug)==null||f.call(n,"consent",{reason:"cmp_not_found"});return}r.setTimeout(i,fe)};i()}function b(t,e){try{e()}catch(n){t==null||t("consent",{reason:"adapter_failed",error:String(n)})}}var dt="c15t";function pt(t){if(typeof t!="object"||t===null)return;let e={};for(let[n,r]of Object.entries(t))typeof r=="boolean"&&(e[n.toLowerCase()]=r);return{categories:e}}function mt(t,e){return typeof t=="object"&&t!==null?"consents"in t?t.consents:t:e.consents}function le(t){C(()=>{let e=t.window.c15t;return typeof e=="object"&&e!==null?e:void 0},e=>{b(t.debug,()=>{var r;let n=o=>{let i=pt(o);i&&k(i,dt,t)};n(e.consents),(r=e.onConsentChange)==null||r.call(e,o=>b(t.debug,()=>n(mt(o,e))))})},t)}var gt="cookiebot",vt=["CookiebotOnConsentReady","CookiebotOnAccept","CookiebotOnDecline"];function de(t){let e=t.Cookiebot;return typeof e=="object"&&e!==null?e:void 0}function ht(t){if(typeof t!="object"||t===null)return;let e={};for(let[n,r]of Object.entries(t))typeof r=="boolean"&&(e[n.toLowerCase()]=r);return{categories:e}}function pe(t){let e=()=>{let r=de(t.window);if(!r||r.hasResponse!==!0)return;let o=ht(r.consent);o&&k(o,gt,t)},n=t.window;if(typeof n.addEventListener=="function")for(let r of vt)n.addEventListener(r,()=>b(t.debug,e));C(()=>de(t.window),()=>b(t.debug,e),t)}var me="onetrust",bt=/^c\d{4}$/;function yt(t,e){let n={};for(let r of t.split(",")){let o=r.trim().toLowerCase();o!==""&&(n[o]=!0)}for(let r of e!=null?e:[])!(r in n)&&bt.test(r)&&(n[r]=!1);return{categories:n}}function ge(t){let e=t.window,n=()=>{let o=e.OnetrustActiveGroups;if(typeof o!="string")return;let i=M(me,t.categories);k(yt(o,i),me,t)},r=e.OptanonWrapper;e.OptanonWrapper=()=>{if(typeof r=="function")try{r()}catch{}b(t.debug,n)},C(()=>{let o=e.OnetrustActiveGroups;return typeof o=="string"?o:void 0},()=>b(t.debug,n),t)}var Et="trustarc",kt={required:1,functional:2,advertising:3},ve="PrivacyManagerAPI";function he(t){let e=t.truste,n=e==null?void 0:e.cma,r=n==null?void 0:n.callApi;return typeof r=="function"?r.bind(n):void 0}function Ct(t){if(typeof t!="object"||t===null)return;let e=t.consentDecision;if(typeof e!="number"||!Number.isFinite(e)||e<1)return;let n={};for(let[r,o]of Object.entries(kt))n[r]=e>=o;return{categories:n}}function wt(t){return typeof t=="string"?t.includes(ve):typeof t=="object"&&t!==null&&ve in t}function St(t){let e=t.location;return typeof(e==null?void 0:e.hostname)=="string"?e.hostname:void 0}function be(t){let e=()=>{let r=he(t.window);if(!r)return;let o=Ct(r("getConsentDecision",St(t.window)));o&&k(o,Et,t)},n=t.window;typeof n.addEventListener=="function"&&n.addEventListener("message",r=>b(t.debug,()=>{wt(r==null?void 0:r.data)&&e()})),C(()=>he(t.window),()=>b(t.debug,e),t)}var N="aci:buf";var ye="aci_m",L=class{constructor(e){y(this,"events");y(this,"storage");y(this,"debug");this.debug=e==null?void 0:e.debug,this.storage=e==null?void 0:e.storage,this.events=this.restore()}push(e){var n;this.events.push(e),this.events.length>50&&(this.events.splice(0,this.events.length-50),(n=this.debug)==null||n.call(this,"buffer",{reason:"cap_drop_oldest"})),this.persist()}drain(){let e=this.events;return this.events=[],this.persist(),e}purge(){var e;this.events.length>0&&((e=this.debug)==null||e.call(this,"buffer",{reason:"purged",count:this.events.length})),this.events=[],this.persist()}size(){return this.events.length}restore(){var r;let e=this.storage;if(!e)return[];let n;try{n=e.getItem(N)}catch(o){return this.storage=void 0,(r=this.debug)==null||r.call(this,"buffer",{reason:"storage_unavailable",error:String(o)}),[]}if(n==null)return[];try{let o=JSON.parse(n);if(Array.isArray(o))return o}catch{}try{e.removeItem(N)}catch{this.storage=void 0}return[]}persist(){var n;let e=this.storage;if(e)try{this.events.length===0?e.removeItem(N):e.setItem(N,JSON.stringify(this.events))}catch(r){this.storage=void 0,(n=this.debug)==null||n.call(this,"buffer",{reason:"storage_unavailable",error:String(r)})}}};function Ee(t){for(let e of t.cookie.split(";")){let n=e.trim();if(n.startsWith(ye+"="))return n.slice(ye.length+1)!==""}return!1}function ke(t,e){if(e.grants()&&!e.marker()){e.gapBuffer.push(t);return}e.batcher.push(t)}function W(t,e,n,r){if(t.size()===0||!n())return;let o=t.drain();for(let i of o)e.push(i);r==null||r("buffer",{reason:"flushed",count:o.length})}var _t="rum.link_click";function Ce(t,e){var i;let{document:n,debug:r}=e,o=(i=n.defaultView)==null?void 0:i.location;n.addEventListener("click",s=>{var a,c,f;try{let l=s.target,p=(a=l==null?void 0:l.closest)==null?void 0:a.call(l,"a[href]");if(!p)return;let u=p;t({eventName:_t,url:o==null?void 0:o.href,properties:{linkText:(f=(c=u.textContent)==null?void 0:c.trim())!=null?f:"",linkHref:u.href}})}catch(l){r==null||r("capture",{reason:"link_click_failed",error:String(l)})}},{capture:!0})}var xt="rum.page_view";function we(t){let e=t.indexOf("#");return e===-1?t:t.slice(0,e)}function Se(t,e){let n=we(t.location.href),r=()=>{let s=we(t.location.href);if(s!==n){n=s;for(let a of e)a()}},o=t.history,i=s=>{let a=o[s].bind(o);o[s]=(...c)=>{let f=a(...c);return r(),f}};i("pushState"),i("replaceState"),t.addEventListener("popstate",r)}function _e(t,e){let n=()=>t({eventName:xt,url:e.location.href,referrer:e.document.referrer});return n(),n}var G="/collect";function xe(t,e){let n=e==null?void 0:e.debug,r=e!==void 0&&"navigator"in e?e.navigator:globalThis.navigator,o=e!==void 0&&"fetch"in e?e.fetch:globalThis.fetch,i;try{i=new Blob([t],{type:"text/plain"})}catch{n==null||n("flush",{reason:"no_blob"});return}if(r!=null&&r.sendBeacon)try{if(r.sendBeacon(G,i))return}catch{}if(!o){n==null||n("flush",{reason:"no_transport"});return}try{o(G,{method:"POST",body:i,keepalive:!0}).catch(s=>{n==null||n("flush",{reason:"fetch_failed",error:String(s)})})}catch(s){n==null||n("flush",{reason:"fetch_failed",error:String(s)})}}function Ae(t){var n,r;let e=t!==void 0&&"fetch"in t?t.fetch:globalThis.fetch;if(!e)return Promise.resolve(!1);try{let o=((n=t==null?void 0:t.createEnvelopeId)!=null?n:S)(),i=new Blob([`{"envelopeId":"${o}","events":[]}`],{type:"text/plain"});return e(G,{method:"POST",body:i,keepalive:!0,credentials:"same-origin"}).then(s=>{var a;return typeof s=="object"&&s!==null&&"ok"in s&&s.ok===!1?((a=t==null?void 0:t.debug)==null||a.call(t,"flush",{reason:"refresh_failed",status:"not_ok"}),!1):!0}).catch(s=>{var a;return(a=t==null?void 0:t.debug)==null||a.call(t,"flush",{reason:"refresh_failed",error:String(s)}),!1})}catch(o){return(r=t==null?void 0:t.debug)==null||r.call(t,"flush",{reason:"refresh_failed",error:String(o)}),Promise.resolve(!1)}}var At="rum.variation_view",j="data-aci-variation";function Te(t,e){var f,l,p;let{document:n,debug:r}=e,o=e.MutationObserver;if(typeof o!="function")return;let i=(f=n.defaultView)==null?void 0:f.location,s=new WeakSet,a=u=>{let h=u.getAttribute(j);h!=null&&(s.has(u)||(s.add(u),t({eventName:At,url:i==null?void 0:i.href,properties:{variantKey:h}})))},c=u=>{try{u.hasAttribute(j)&&a(u);for(let h of Array.from(u.querySelectorAll(`[${j}]`)))a(h)}catch(h){r==null||r("capture",{reason:"variation_scan_failed",error:String(h)})}};try{let u=(l=n.body)!=null?l:n.documentElement;u&&c(u)}catch(u){r==null||r("capture",{reason:"variation_initial_scan_failed",error:String(u)})}try{let u=(p=n.body)!=null?p:n.documentElement;if(!u)return;new o(m=>{try{for(let g of m)for(let d=0;d<g.addedNodes.length;d++){let v=g.addedNodes[d];if((v==null?void 0:v.nodeType)!==1)continue;let E=v.element;E&&c(E)}}catch(g){r==null||r("capture",{reason:"variation_observer_failed",error:String(g)})}}).observe(u,{subtree:!0,childList:!0})}catch(u){r==null||r("capture",{reason:"variation_observe_failed",error:String(u)})}}var Tt="rum.web_vital";function Pe(t,e){var h,m,g;let n=e.PerformanceObserver;if(typeof n!="function")return;let{performance:r,debug:o}=e,i=(m=(h=e.window)==null?void 0:h.location)==null?void 0:m.href,s=e.document,a=new Set,c=(d,v)=>{a.has(d)||(a.add(d),t({eventName:Tt,url:i,properties:{vitalName:d,vitalValue:v}}))};try{let d=r==null?void 0:r.getEntriesByType("navigation")[0];d&&typeof d.responseStart=="number"&&typeof d.requestStart=="number"&&c("TTFB",d.responseStart-d.requestStart)}catch(d){o==null||o("capture",{reason:"ttfb_failed",error:String(d)})}let f=0,l=0,p=(d,v)=>{try{new n(Ie=>{try{for(let O of Ie.getEntries())v(O)}catch(O){o==null||o("capture",{reason:`${d}_handler_failed`,error:String(O)})}}).observe({type:d,buffered:!0})}catch(E){o==null||o("capture",{reason:`${d}_observe_failed`,error:String(E)})}};p("largest-contentful-paint",d=>{c("LCP",d.startTime)}),p("first-input",d=>{c("FID",d.startTime)}),p("layout-shift",d=>{var v;d.hadRecentInput||(f+=(v=d.value)!=null?v:0)}),p("event",d=>{var E;let v=(E=d.value)!=null?E:0;v>l&&(l=v)}),p("paint",d=>{d.name==="first-contentful-paint"&&c("FCP",d.startTime)});let u=()=>{try{a.has("CLS")||c("CLS",f),a.has("INP")||c("INP",l)}catch(d){o==null||o("capture",{reason:"visibility_handler_failed",error:String(d)})}};s&&s.addEventListener("visibilitychange",()=>{s.visibilityState==="hidden"&&u()}),(g=e.window)==null||g.addEventListener("pagehide",u)}var z={c15t:le,onetrust:ge,cookiebot:pe,trustarc:be};function Pt(t){var e,n;return typeof((e=t.navigator)==null?void 0:e.sendBeacon)=="function"&&typeof t.IntersectionObserver=="function"&&typeof((n=t.crypto)==null?void 0:n.getRandomValues)=="function"}function It(t){try{return t.sessionStorage}catch{return}}function Nt(t){var o;let e=t!=null?t:typeof window!="undefined"?window:void 0;if(!e||e.__aci_loaded||(e.__aci_loaded=!0,!Pt(e)))return;let n=re(e.document.currentScript),r=oe(n.debug);try{let i=e.document,s=new L({storage:It(e),debug:r}),a=()=>{try{return ae(se(i))}catch{return!1}},c=()=>{try{return Ee(i)}catch{return!1}},f={navigator:e.navigator,fetch:typeof e.fetch=="function"?e.fetch.bind(e):void 0,debug:r},l;l=new T({send:m=>xe(m,f),debug:r,onTick:()=>W(s,l,c,r),timers:{setInterval:(m,g)=>e.setInterval(m,g),clearInterval:m=>e.clearInterval(m)},documentTarget:i,windowTarget:e});let p=Q({document:i,window:e,debug:r}),u=m=>{ke({...J(m,p),eventId:S(void 0,g=>e.crypto.getRandomValues(g))},{grants:a,marker:c,gapBuffer:s,batcher:l})};p.start(u),Y(e,n,{track:(m,g)=>u({eventName:m,properties:g}),consent:({p:m,src:g})=>{let d=ce(m);if(d===void 0){r("consent",{reason:"malformed_purposes"});return}let v=ue(g);if(v===void 0){r("consent",{reason:"malformed_source"});return}I(d,v,{document:i,gapBuffer:s})||r("consent",{reason:"oversized_envelope"})}},r);let h=_e(u,e);Se(e,[()=>p.rearm(),h]),$(u,{document:i,intersectionObserver:e.IntersectionObserver,debug:r},()=>{Ae(f).then(m=>{m&&e.location.reload()})}),Ce(u,{document:i,debug:r}),Pe(u,{performance:e.performance,PerformanceObserver:e.PerformanceObserver,window:e,document:i,debug:r}),Te(u,{document:i,MutationObserver:e.MutationObserver,debug:r}),n.preset!=="manual"&&((o=z[n.preset])==null||o.call(z,{window:e,document:i,categories:n.categories,gapBuffer:s,debug:r,scheduler:{setTimeout:(m,g)=>e.setTimeout(m,g),clearTimeout:m=>e.clearTimeout(m)}})),l.start(),W(s,l,c,r),r("init",{config:n})}catch(i){r("init",{error:String(i)})}}Nt();})();
1
+ "use strict";(()=>{var je=Object.defineProperty;var We=(t,e,n)=>e in t?je(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var E=(t,e,n)=>We(t,typeof e!="symbol"?e+"":e,n);var Ge="experiment.exposure",ze='script[type="application/json"][data-aci-assignments]';function M(t){if(typeof t!="object"||t===null)return null;let e=t,n=e.experimentId,r=e.armId,o=e.allocationVersion;return typeof n!="string"||n===""||typeof r!="string"||r===""||typeof o!="string"?null:{experimentId:n,armId:r,allocationVersion:o}}function j(t,e){try{let n=t.querySelector(ze);if(!n)return[];let r=n.textContent;if(r==null||r.trim()==="")return[];let o=JSON.parse(r);if(typeof o!="object"||o===null)return e==null||e("capture",{reason:"assignments_malformed"}),[];let i=o;if(i.v!==1||!Array.isArray(i.experiments))return e==null||e("capture",{reason:"assignments_malformed"}),[];let s=[];for(let a of i.experiments){let c=M(a);c&&!s.some(u=>u.experimentId===c.experimentId)&&s.push(c)}return s}catch(n){return e==null||e("capture",{reason:"assignments_parse_failed",error:String(n)}),[]}}function te(t,e){if(!e||t.experiments!==void 0)return t;let n=e.getActiveAssignments();return n.length===0?t:{...t,experiments:n}}function re(t){let e=[],n=new Set,r,o=i=>{e=(i!=null?i:j(t.document,t.debug)).map(s=>({...s}));for(let s of e)n.has(s.experimentId)||(n.add(s.experimentId),r==null||r({eventName:Ge,url:t.window.location.href,experiments:[{experimentId:s.experimentId,armId:s.armId,allocationVersion:s.allocationVersion}]}))};return{getActiveAssignments:()=>e.map(i=>({...i})),start(i){r=i,o()},clear(){e=[]},rearm(i){n.clear(),o(i)}}}var I="data-aci-event",qe="data-aci-on",oe="data-aci-prop-",$e="data-aci-refresh",ie="custom.";function W(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();if(!(e===""||/[\s/]/.test(e)))return e.startsWith(ie)?e:ie+e}function Ue(t){let e;for(let n of Array.from(t.attributes)){if(!n.name.startsWith(oe))continue;let r=n.name.slice(oe.length);r!==""&&((e!=null?e:e={})[r]=n.value)}return e}function se(t,e,n){let r=W(t.getAttribute(I));if(r===void 0){n==null||n("capture",{reason:"malformed_declaration",attr:I});return}return{eventName:r,url:e,properties:Ue(t)}}function ae(t){var e,n;return(n=(e=t.getAttribute(qe))==null?void 0:e.trim().toLowerCase())!=null?n:"click"}function ce(t,e,n){var d;let{document:r,debug:o}=e,i=(d=r.defaultView)==null?void 0:d.location;r.addEventListener("click",p=>{var f,m;try{let v=p.target;if((f=v==null?void 0:v.closest)==null?void 0:f.call(v,`[${$e}]`)){n==null||n();return}let l=(m=v==null?void 0:v.closest)==null?void 0:m.call(v,`[${I}]`);if(!l||ae(l)!=="click")return;let g=se(l,i==null?void 0:i.href,o);g&&t(g)}catch(v){o==null||o("capture",{reason:"click_handler_failed",error:String(v)})}});let s=e.intersectionObserver;if(typeof s!="function")return;let a=Array.from(r.querySelectorAll(`[${I}]`)).filter(p=>ae(p)==="visible");if(a.length===0)return;let c=new WeakSet,u=new s((p,f)=>{try{for(let m of p){if(!m.isIntersecting||m.intersectionRatio<.5||c.has(m.target))continue;c.add(m.target),f.unobserve(m.target);let v=se(m.target,i==null?void 0:i.href,o);v&&t(v)}}catch(m){o==null||o("capture",{reason:"visible_handler_failed",error:String(m)})}},{threshold:.5});for(let p of a)u.observe(p)}function G(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function ue(t,e,n){let r=(...s)=>{try{let[a,...c]=s;if(a==="navigation-complete"){let u=c[0];if(!G(u)||typeof u.url!="string"||!/^https?:\/\//.test(u.url)||!Array.isArray(u.assignments)||u.assignments.length>16){n==null||n("capture",{reason:"malformed_navigation_completion"});return}let d=[];for(let p of u.assignments){let f=M(p);if(!f||d.some(m=>m.experimentId===f.experimentId)){n==null||n("capture",{reason:"malformed_navigation_completion"});return}d.push(f)}e.navigationComplete({url:u.url,assignments:d});return}if(a==="track"){let u=W(c[0]);if(u===void 0){n==null||n("capture",{reason:"malformed_track_name",name:c[0]});return}let d=c[1];if(d!==void 0&&!G(d)){n==null||n("capture",{reason:"malformed_track_properties",name:u});return}e.track(u,d);return}if(a==="consent"){let u=c[0];if(!G(u)){n==null||n("consent",{reason:"malformed_consent_envelope"});return}e.consent({p:u.p,src:u.src});return}n==null||n("capture",{reason:"unknown_command",command:a})}catch(a){n==null||n("capture",{reason:"command_failed",error:String(a)})}},o=t.aci,i=o==null?void 0:o.q;if(t.aci=r,i!=null)for(let s of Array.from(i)){let a=Array.from(s);r(...a)}}var le="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Xe(t){globalThis.crypto.getRandomValues(t)}function x(t,e){let n=t!=null?t:Date.now(),r="";for(let c=0;c<10;c++)r=le[n%32]+r,n=Math.floor(n/32);let o=new Uint8Array(10);(e!=null?e:Xe)(o);let i="",s=0,a=0;for(let c of o)for(s=s<<8|c,a+=8;a>=5;)i+=le[s>>>a-5&31],a-=5;return r+i}var Ke=60*1024,Ye=100,Je=5e3,de='{"envelopeId":"',fe='","events":[',pe="]}",Ze=26,O=de.length+Ze+fe.length+pe.length,Qe=new TextEncoder,en=t=>Qe.encode(t).length,D=class{constructor(e){E(this,"options");E(this,"maxBytes");E(this,"queue",[]);E(this,"queuedBytes",0);E(this,"flushing",!1);E(this,"intervalId");var n;this.options=e,this.maxBytes=(n=e.maxBatchBytes)!=null?n:Ke}get pending(){return this.queue.length}push(e){let n=JSON.stringify(e),r=en(n);this.queue.push({json:n,bytes:r,eventId:e.eventId}),this.queuedBytes+=r,!this.flushing&&this.envelopeBytes()>=this.maxBytes&&this.flush()}flush(){var e,n;if(!this.flushing){this.flushing=!0;try{(n=(e=this.options).onTick)==null||n.call(e),this.drain()}finally{this.flushing=!1}}}start(){var o,i,s,a;let e=(o=this.options.timers)!=null?o:{setInterval:(c,u)=>setInterval(c,u),clearInterval:c=>clearInterval(c)};this.intervalId=e.setInterval(()=>this.flush(),(i=this.options.flushIntervalMs)!=null?i:Je);let n=(s=this.options.documentTarget)!=null?s:typeof document!="undefined"?document:void 0;n==null||n.addEventListener("visibilitychange",()=>{n.visibilityState==="hidden"&&this.flush()});let r=(a=this.options.windowTarget)!=null?a:typeof window!="undefined"?window:void 0;r==null||r.addEventListener("pagehide",()=>this.flush()),this.flush()}stop(){if(this.intervalId!==void 0){let e=this.options.timers;e?e.clearInterval(this.intervalId):clearInterval(this.intervalId),this.intervalId=void 0}}envelopeBytes(){let e=this.queue.length>1?this.queue.length-1:0;return O+this.queuedBytes+e}drain(){var e,n,r;for(;this.queue.length>0;){let o=this.queue[0];if(O+o.bytes>this.maxBytes){this.queue.shift(),this.queuedBytes-=o.bytes,(n=(e=this.options).debug)==null||n.call(e,"flush",{reason:"oversize_event",eventId:o.eventId,bytes:o.bytes});continue}let i=[],s=O;for(;this.queue.length>0;){let c=this.queue[0];if(O+c.bytes>this.maxBytes||i.length>=Ye)break;let u=s+c.bytes+(i.length>0?1:0);if(u>this.maxBytes)break;i.push(c.json),s=u,this.queue.shift(),this.queuedBytes-=c.bytes}if(i.length===0)continue;let a=((r=this.options.createEnvelopeId)!=null?r:x)();this.options.send(de+a+fe+i.join(",")+pe)}}};var z=new TextEncoder,nn=2048,tn=32,rn=128,on=512,sn=2147483647,an=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/,cn=/^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g,un=new Set(["true","all","granted","yes","personalization","personalized"]);function N(t,e=!0){let n=S(t);if(!n)return null;if(e)try{n=decodeURIComponent(n)}catch{}if(n=S(n),!n||z.encode(n).byteLength>nn)return null;if(un.has(n.toLowerCase()))return{version:0,purposes:["personalization"],grantedAt:""};try{let r=JSON.parse(n),o=typeof r.t=="string"?r.t:"";return!Number.isInteger(r.v)||r.v<0||r.v>sn||!Array.isArray(r.p)||r.p.length>tn||!r.p.every(i=>typeof i=="string")||r.p.some(i=>z.encode(i).byteLength>rn)||r.t!==void 0&&r.t!==null&&(typeof r.t!="string"||r.t===""||!ln(r.t))||r.src!==void 0&&r.src!==null&&typeof r.src!="string"||typeof r.src=="string"&&z.encode(r.src).byteLength>on?null:{version:r.v,purposes:r.p,grantedAt:o,source:typeof r.src=="string"?r.src:void 0}}catch{return null}}function q(t){return(t==null?void 0:t.purposes.some(e=>S(e).toLowerCase()==="personalization"))||!1}function S(t){return t.replace(cn,"")}function ln(t){let e=an.exec(t);if(!e||Number.isNaN(Date.parse(t)))return!1;let n=Number(e[1]),r=Number(e[2]),o=Number(e[3]),i=Number(e[4]),s=Number(e[5]),a=Number(e[6]);if(r<1||r>12||o<1||o>dn(n,r)||i>23||s>59||a>59)return!1;let c=e[8];return c==="Z"||Number(c.slice(1,3))<=23&&Number(c.slice(4,6))<=59}function dn(t,e){return e===2?t%4===0&&(t%100!==0||t%400===0)?29:28:[4,6,9,11].includes(e)?30:31}var U="personalization",$="aci_consent",X=1,fn=365*24*60*60;function pn(t,e){var r;let n=`${$}=${t.encoded}; Path=/; Max-Age=${fn}; SameSite=Lax`;((r=e.document.location)==null?void 0:r.protocol)==="https:"&&(n+="; Secure"),e.document.cookie=n}function P(t,e,n){var o,i;let r=mn(t,e,n.now);return r===null?!1:(q(r.snapshot)||(o=n.gapBuffer)==null||o.purge(),pn(r,n),(i=n.onDecision)==null||i.call(n),!0)}function T(t){for(let e of t.cookie.split(";")){let n=S(e);if(n.startsWith($+"="))return n.slice($.length+1)}}function me(t){return t===void 0||t===""?!1:q(N(t,!0))}function ge(t){var r;if(!Array.isArray(t))return;let e=[];for(let o of t){if(typeof o!="string")return;e.push(S(o))}let n=JSON.stringify({v:X,p:e});return(r=N(n,!1))==null?void 0:r.purposes}function ve(t){var o;if(t!==void 0&&typeof t!="string")return;let e=typeof t=="string"?S(t):"",r=JSON.stringify({v:X,p:[],src:e===""?"manual":e});return(o=N(r,!1))==null?void 0:o.source}function mn(t,e,n){try{let r=JSON.stringify({v:X,p:t,t:new Date((n!=null?n:Date.now)()).toISOString(),src:e}),o=N(r,!1);return o===null?null:{encoded:encodeURIComponent(r),snapshot:o}}catch{return null}}var gn="data-aci-consent-banner";var vn="data-aci-consent-banner-mount",he="aci:consent-banner-decided";function hn(t){return T(t)!==void 0}function be(t){return hn(t)?!1:t.querySelector(`[${vn}], [${gn}]`)!==null}var bn=new Set(["c15t","onetrust","cookiebot","trustarc","manual"]);function R(t,e){var o;let n=(o=t==null?void 0:t.getAttribute)==null?void 0:o.call(t,e);if(n==null)return;let r=n.trim();return r===""?void 0:r}function Ee(t){var r;let e=(r=R(t,"data-aci-consent"))==null?void 0:r.toLowerCase(),n=e!==void 0&&bn.has(e)?e:"manual";return{site:R(t,"data-aci-site"),preset:n,categories:R(t,"data-aci-consent-categories"),debug:R(t,"data-aci-debug")==="1"}}function ye(t,e,n){if(!t)return()=>{};let r=e!=null?e:(i=>console.debug("[aci]",i)),o=n!=null?n:Date.now;return(i,s)=>{try{r({t:o(),kind:i,detail:s})}catch{}}}var B=class{constructor(e){E(this,"events",[]);E(this,"now");E(this,"debug");var n;this.now=(n=e==null?void 0:e.now)!=null?n:Date.now,this.debug=e==null?void 0:e.debug}push(e){var n;if(this.expire(),this.events.length>=50){(n=this.debug)==null||n.call(this,"buffer",{reason:"consent_hold_cap_drop_newest",eventId:e.eventId});return}this.events.push({event:e,heldAt:this.now()})}size(){return this.events.length}release(){this.expire();let e=this.events.map(n=>n.event);return this.events=[],e}discard(e){var n;this.events.length>0&&((n=this.debug)==null||n.call(this,"buffer",{reason:`consent_hold_discarded_${e}`,count:this.events.length})),this.events=[]}expire(){var r;let e=this.now()-18e5,n=0;for(;n<this.events.length&&this.events[n].heldAt<e;)n+=1;n>0&&(this.events.splice(0,n),(r=this.debug)==null||r.call(this,"buffer",{reason:"consent_hold_expired",count:n}))}};function Ce(t,e){var r;if(t.size()===0||!e.decided())return;if(!e.grants()){t.discard("denied");return}let n=t.release();for(let o of n)e.batcher.push(o);(r=e.debug)==null||r.call(e,"buffer",{reason:"consent_hold_released",count:n.length})}var En="cmp-",yn=/^[a-z0-9._-]+$/,Cn={c15t:"measurement,marketing",onetrust:"c0002,c0004",cookiebot:"statistics,marketing",trustarc:"functional,advertising"};function K(t,e){let n=e!=null?e:Cn[t];if(n===void 0)return null;let r=n.split(",").map(o=>o.trim().toLowerCase()).filter(o=>o!=="");if(r.length===0)return null;for(let o of r)if(!yn.test(o))return null;return r}function kn(t,e){return e.filter(r=>r in t.categories).some(r=>t.categories[r]===!0)?[U]:[]}function _(t,e,n){var r,o,i,s;try{let a=K(e,n.categories);if(a===null){(r=n.debug)==null||r.call(n,"consent",{reason:"unparseable_mapping",preset:e});return}if(a.filter(d=>d in t.categories).length===0){(o=n.debug)==null||o.call(n,"consent",{reason:"unmappable_cmp_state",preset:e});return}let u=kn(t,a);P(u,En+e,{document:n.document,gapBuffer:n.gapBuffer,now:n.now,onDecision:n.onDecision}),(i=n.debug)==null||i.call(n,"consent",{reason:"written",preset:e,purposes:u})}catch(a){(s=n.debug)==null||s.call(n,"consent",{reason:"consent_bridge_failed",preset:e,error:String(a)})}}var ke=250,_n=1e4;function w(t,e,n){var s;let r=(s=n==null?void 0:n.scheduler)!=null?s:{setTimeout:(a,c)=>setTimeout(a,c),clearTimeout:a=>clearTimeout(a)},o=Math.floor(_n/ke),i=()=>{var c,u;let a;try{a=t()}catch(d){(c=n==null?void 0:n.debug)==null||c.call(n,"consent",{reason:"cmp_read_failed",error:String(d)});return}if(a!==void 0){e(a);return}if(o-=1,o<=0){(u=n==null?void 0:n.debug)==null||u.call(n,"consent",{reason:"cmp_not_found"});return}r.setTimeout(i,ke)};i()}function C(t,e){try{e()}catch(n){t==null||t("consent",{reason:"adapter_failed",error:String(n)})}}var wn="c15t";function Sn(t){if(typeof t!="object"||t===null)return;let e={};for(let[n,r]of Object.entries(t))typeof r=="boolean"&&(e[n.toLowerCase()]=r);return{categories:e}}function An(t,e){return typeof t=="object"&&t!==null?"consents"in t?t.consents:t:e.consents}function _e(t){w(()=>{let e=t.window.c15t;return typeof e=="object"&&e!==null?e:void 0},e=>{C(t.debug,()=>{var r;let n=o=>{let i=Sn(o);i&&_(i,wn,t)};n(e.consents),(r=e.onConsentChange)==null||r.call(e,o=>C(t.debug,()=>n(An(o,e))))})},t)}var xn="cookiebot",Nn=["CookiebotOnConsentReady","CookiebotOnAccept","CookiebotOnDecline"];function we(t){let e=t.Cookiebot;return typeof e=="object"&&e!==null?e:void 0}function Pn(t){if(typeof t!="object"||t===null)return;let e={};for(let[n,r]of Object.entries(t))typeof r=="boolean"&&(e[n.toLowerCase()]=r);return{categories:e}}function Se(t){let e=()=>{let r=we(t.window);if(!r||r.hasResponse!==!0)return;let o=Pn(r.consent);o&&_(o,xn,t)},n=t.window;if(typeof n.addEventListener=="function")for(let r of Nn)n.addEventListener(r,()=>C(t.debug,e));w(()=>we(t.window),()=>C(t.debug,e),t)}var Ae="onetrust",Tn=/^c\d{4}$/;function Ln(t,e){let n={};for(let r of t.split(",")){let o=r.trim().toLowerCase();o!==""&&(n[o]=!0)}for(let r of e!=null?e:[])!(r in n)&&Tn.test(r)&&(n[r]=!1);return{categories:n}}function xe(t){let e=t.window,n=()=>{let o=e.OnetrustActiveGroups;if(typeof o!="string")return;let i=K(Ae,t.categories);_(Ln(o,i),Ae,t)},r=e.OptanonWrapper;e.OptanonWrapper=()=>{if(typeof r=="function")try{r()}catch{}C(t.debug,n)},w(()=>{let o=e.OnetrustActiveGroups;return typeof o=="string"?o:void 0},()=>C(t.debug,n),t)}var In="trustarc",On={required:1,functional:2,advertising:3},Ne="PrivacyManagerAPI";function Pe(t){let e=t.truste,n=e==null?void 0:e.cma,r=n==null?void 0:n.callApi;return typeof r=="function"?r.bind(n):void 0}function Dn(t){if(typeof t!="object"||t===null)return;let e=t.consentDecision;if(typeof e!="number"||!Number.isFinite(e)||e<1)return;let n={};for(let[r,o]of Object.entries(On))n[r]=e>=o;return{categories:n}}function Rn(t){return typeof t=="string"?t.includes(Ne):typeof t=="object"&&t!==null&&Ne in t}function Bn(t){let e=t.location;return typeof(e==null?void 0:e.hostname)=="string"?e.hostname:void 0}function Te(t){let e=()=>{let r=Pe(t.window);if(!r)return;let o=Dn(r("getConsentDecision",Bn(t.window)));o&&_(o,In,t)},n=t.window;typeof n.addEventListener=="function"&&n.addEventListener("message",r=>C(t.debug,()=>{Rn(r==null?void 0:r.data)&&e()})),w(()=>Pe(t.window),()=>C(t.debug,e),t)}var F="aci:buf";var Le="aci_m",V=class{constructor(e){E(this,"events",[]);E(this,"storage");E(this,"debug");this.debug=e==null?void 0:e.debug,this.storage=e==null?void 0:e.storage}push(e){var n;this.events=this.restore(),this.events.push(e),this.events.length>50&&(this.events.splice(0,this.events.length-50),(n=this.debug)==null||n.call(this,"buffer",{reason:"cap_drop_oldest"})),this.persist()}drain(){let e=this.restore();return this.events=[],this.persist(),e}purge(){var e;this.events=this.restore(),this.events.length>0&&((e=this.debug)==null||e.call(this,"buffer",{reason:"purged",count:this.events.length})),this.events=[],this.persist()}size(){return this.restore().length}restore(){var r;let e=this.storage;if(!e)return this.events;let n;try{n=e.getItem(F)}catch(o){return this.storage=void 0,(r=this.debug)==null||r.call(this,"buffer",{reason:"storage_unavailable",error:String(o)}),[]}if(n==null)return[];try{let o=JSON.parse(n);if(Array.isArray(o))return o}catch{}try{e.removeItem(F)}catch{this.storage=void 0}return[]}persist(){var n;let e=this.storage;if(e)try{this.events.length===0?e.removeItem(F):e.setItem(F,JSON.stringify(this.events)),this.events=[]}catch(r){this.storage=void 0,(n=this.debug)==null||n.call(this,"buffer",{reason:"storage_unavailable",error:String(r)})}}};function Ie(t){for(let e of t.cookie.split(";")){let n=e.trim();if(n.startsWith(Le+"="))return n.slice(Le.length+1)!==""}return!1}function Oe(t,e){var n;if(e.consentHold&&((n=e.consentPending)!=null&&n.call(e))){e.consentHold.push(t);return}if(e.grants()&&!e.marker()){e.gapBuffer.push(t);return}e.batcher.push(t)}function Y(t,e,n,r){if(t.size()===0||!n())return;let o=t.drain();for(let i of o)e.push(i);r==null||r("buffer",{reason:"flushed",count:o.length})}var Fn="rum.link_click";function De(t,e){var i;let{document:n,debug:r}=e,o=(i=n.defaultView)==null?void 0:i.location;n.addEventListener("click",s=>{var a,c,u;try{let d=s.target,p=(a=d==null?void 0:d.closest)==null?void 0:a.call(d,"a[href]");if(!p)return;let f=p;t({eventName:Fn,url:o==null?void 0:o.href,properties:{linkText:(u=(c=f.textContent)==null?void 0:c.trim())!=null?u:"",linkHref:f.href}})}catch(d){r==null||r("capture",{reason:"link_click_failed",error:String(d)})}},{capture:!0})}var Vn="rum.page_view";function H(t){let e=t.indexOf("#");return e===-1?t:t.slice(0,e)}function Re(t,e,n=()=>{}){let r=H(t.location.href),o=r,i=!1,s=()=>{let c=H(t.location.href);c!==r&&(r=c,i=!0,n())},a=t.history;for(let c of["pushState","replaceState"]){let u=a[c].bind(a);a[c]=(...d)=>{let p=u(...d);return s(),p}}return t.addEventListener("popstate",s),{complete({url:c,assignments:u}){let d=H(t.location.href);if(H(c)===d&&(s(),!(!i&&o===d))){i=!1,o=d;for(let p of e)p(u)}}}}function Be(t,e){let n=()=>t({eventName:Vn,url:e.location.href,referrer:e.document.referrer});return n(),n}var J="/collect";function Fe(t,e){let n=e==null?void 0:e.debug,r=e!==void 0&&"navigator"in e?e.navigator:globalThis.navigator,o=e!==void 0&&"fetch"in e?e.fetch:globalThis.fetch,i;try{i=new Blob([t],{type:"text/plain"})}catch{n==null||n("flush",{reason:"no_blob"});return}if(r!=null&&r.sendBeacon)try{if(r.sendBeacon(J,i))return}catch{}if(!o){n==null||n("flush",{reason:"no_transport"});return}try{o(J,{method:"POST",body:i,keepalive:!0}).catch(s=>{n==null||n("flush",{reason:"fetch_failed",error:String(s)})})}catch(s){n==null||n("flush",{reason:"fetch_failed",error:String(s)})}}function Ve(t){var n,r;let e=t!==void 0&&"fetch"in t?t.fetch:globalThis.fetch;if(!e)return Promise.resolve(!1);try{let o=((n=t==null?void 0:t.createEnvelopeId)!=null?n:x)(),i=new Blob([`{"envelopeId":"${o}","events":[]}`],{type:"text/plain"});return e(J,{method:"POST",body:i,keepalive:!0,credentials:"same-origin"}).then(s=>{var a;return typeof s=="object"&&s!==null&&"ok"in s&&s.ok===!1?((a=t==null?void 0:t.debug)==null||a.call(t,"flush",{reason:"refresh_failed",status:"not_ok"}),!1):!0}).catch(s=>{var a;return(a=t==null?void 0:t.debug)==null||a.call(t,"flush",{reason:"refresh_failed",error:String(s)}),!1})}catch(o){return(r=t==null?void 0:t.debug)==null||r.call(t,"flush",{reason:"refresh_failed",error:String(o)}),Promise.resolve(!1)}}var Hn="rum.variation_view",Z="data-aci-variation";function He(t,e){var u,d,p;let{document:n,debug:r}=e,o=e.MutationObserver;if(typeof o!="function")return;let i=(u=n.defaultView)==null?void 0:u.location,s=new WeakSet,a=f=>{let m=f.getAttribute(Z);m!=null&&(s.has(f)||(s.add(f),t({eventName:Hn,url:i==null?void 0:i.href,properties:{variantKey:m}})))},c=f=>{try{f.hasAttribute(Z)&&a(f);for(let m of Array.from(f.querySelectorAll(`[${Z}]`)))a(m)}catch(m){r==null||r("capture",{reason:"variation_scan_failed",error:String(m)})}};try{let f=(d=n.body)!=null?d:n.documentElement;f&&c(f)}catch(f){r==null||r("capture",{reason:"variation_initial_scan_failed",error:String(f)})}try{let f=(p=n.body)!=null?p:n.documentElement;if(!f)return;new o(v=>{try{for(let b of v)for(let l=0;l<b.addedNodes.length;l++){let g=b.addedNodes[l];if((g==null?void 0:g.nodeType)!==1)continue;let y=g.element;y&&c(y)}}catch(b){r==null||r("capture",{reason:"variation_observer_failed",error:String(b)})}}).observe(f,{subtree:!0,childList:!0})}catch(f){r==null||r("capture",{reason:"variation_observe_failed",error:String(f)})}}var Mn="rum.web_vital";function Me(t,e){var m,v,b;let n=e.PerformanceObserver;if(typeof n!="function")return;let{performance:r,debug:o}=e,i=(v=(m=e.window)==null?void 0:m.location)==null?void 0:v.href,s=e.document,a=new Set,c=(l,g)=>{a.has(l)||(a.add(l),t({eventName:Mn,url:i,properties:{vitalName:l,vitalValue:g}}))};try{let l=r==null?void 0:r.getEntriesByType("navigation")[0];l&&typeof l.responseStart=="number"&&typeof l.requestStart=="number"&&c("TTFB",l.responseStart-l.requestStart)}catch(l){o==null||o("capture",{reason:"ttfb_failed",error:String(l)})}let u=0,d=0,p=(l,g)=>{try{new n(L=>{try{for(let A of L.getEntries())g(A)}catch(A){o==null||o("capture",{reason:`${l}_handler_failed`,error:String(A)})}}).observe({type:l,buffered:!0})}catch(y){o==null||o("capture",{reason:`${l}_observe_failed`,error:String(y)})}};p("largest-contentful-paint",l=>{c("LCP",l.startTime)}),p("first-input",l=>{c("FID",l.startTime)}),p("layout-shift",l=>{var g;l.hadRecentInput||(u+=(g=l.value)!=null?g:0)}),p("event",l=>{var y;let g=(y=l.value)!=null?y:0;g>d&&(d=g)}),p("paint",l=>{l.name==="first-contentful-paint"&&c("FCP",l.startTime)});let f=()=>{try{a.has("CLS")||c("CLS",u),a.has("INP")||c("INP",d)}catch(l){o==null||o("capture",{reason:"visibility_handler_failed",error:String(l)})}};s&&s.addEventListener("visibilitychange",()=>{s.visibilityState==="hidden"&&f()}),(b=e.window)==null||b.addEventListener("pagehide",f)}var Q={c15t:_e,onetrust:xe,cookiebot:Se,trustarc:Te};function jn(t){var e,n;return typeof((e=t.navigator)==null?void 0:e.sendBeacon)=="function"&&typeof t.IntersectionObserver=="function"&&typeof((n=t.crypto)==null?void 0:n.getRandomValues)=="function"}function Wn(t){try{return t.sessionStorage}catch{return}}function Gn(t){var i;let e=t!=null?t:typeof window!="undefined"?window:void 0;if(!e||e.__aci_loaded||(e.__aci_loaded=!0,!jn(e)))return;let n=e.__aci_measurement_disabled===!0,r=Ee(e.document.currentScript),o=ye(r.debug);try{let s=e.document,a=new V({storage:Wn(e),debug:o}),c=()=>{try{return me(T(s))}catch{return!1}},u=()=>{try{return Ie(s)}catch{return!1}},d=()=>{try{return T(s)!==void 0}catch{return!1}},p=r.preset==="manual"?()=>{try{return be(s)}catch{return!1}}:()=>!0,f=new B({debug:o}),m=()=>!d()&&!u()&&p(),v={navigator:e.navigator,fetch:typeof e.fetch=="function"?e.fetch.bind(e):void 0,debug:o},b;b=new D({send:h=>Fe(h,v),debug:o,onTick:()=>{n||(Ce(f,{decided:d,grants:c,batcher:b,debug:o}),Y(a,b,u,o))},timers:{setInterval:(h,k)=>e.setInterval(h,k),clearInterval:h=>e.clearInterval(h)},documentTarget:s,windowTarget:e});let l=re({document:s,window:e,debug:o}),g=h=>{n||Oe({...te(h,l),eventId:x(void 0,k=>e.crypto.getRandomValues(k))},{grants:c,marker:u,gapBuffer:a,batcher:b,consentHold:f,consentPending:m})},y=()=>b.flush();s.addEventListener(he,y),l.start(g);let L=()=>{},A=Re(e,[h=>l.rearm(h),()=>L()],()=>l.clear());s.addEventListener("astro:page-load",()=>A.complete({url:e.location.href,assignments:j(s,o)})),ue(e,{navigationComplete:h=>A.complete(h),track:(h,k)=>g({eventName:h,properties:k,url:e.location.href}),consent:({p:h,src:k})=>{let ee=ge(h);if(ee===void 0){o("consent",{reason:"malformed_purposes"});return}let ne=ve(k);if(ne===void 0){o("consent",{reason:"malformed_source"});return}P(ee,ne,{document:s,gapBuffer:a,onDecision:y})||o("consent",{reason:"oversized_envelope"})}},o),L=Be(g,e),ce(g,{document:s,intersectionObserver:e.IntersectionObserver,debug:o},()=>{n||Ve(v).then(h=>{h&&e.location.reload()})}),De(g,{document:s,debug:o}),Me(g,{performance:e.performance,PerformanceObserver:e.PerformanceObserver,window:e,document:s,debug:o}),He(g,{document:s,MutationObserver:e.MutationObserver,debug:o}),r.preset!=="manual"&&((i=Q[r.preset])==null||i.call(Q,{window:e,document:s,categories:r.categories,gapBuffer:a,onDecision:y,debug:o,scheduler:{setTimeout:(h,k)=>e.setTimeout(h,k),clearTimeout:h=>e.clearTimeout(h)}})),b.start(),e.addEventListener("pagehide",()=>f.discard("unload")),n||Y(a,b,u,o),o("init",{config:r})}catch(s){o("init",{error:String(s)})}}Gn();})();
@@ -1 +1 @@
1
- 46f87bbce4c938e9540939102be1094f5cd956d0f3a5836e9af5c3b0b8c582ad
1
+ c330eb304d6a7aa01375646c97c67be0f68ce9137974da03aa339696e0f01de6
@@ -1,24 +1,23 @@
1
+ import type { NavigationCompletion } from "./pageviews.js";
1
2
  import type { DebugFn } from "./config.js";
2
3
  export interface CommandHandlers {
4
+ /** Called by framework hooks only after committing the destination page. */
5
+ navigationComplete: (completion: NavigationCompletion) => void;
3
6
  /** Receives the normalized custom.* event name. */
4
7
  track: (name: string, properties?: Record<string, unknown>) => void;
5
- /** Manual consent write; only reachable under the manual preset. */
8
+ /** Manual consent write; reachable under every preset — with no CMP installed the JS API is the only writer. */
6
9
  consent: (envelope: {
7
10
  p: unknown;
8
11
  src: unknown;
9
12
  }) => void;
10
13
  }
11
- export interface CommandQueueConfig {
12
- preset: string;
13
- }
14
14
  interface AciHost {
15
15
  aci?: unknown;
16
16
  }
17
17
  /**
18
18
  * installCommandQueue replaces any pre-load stub on window.aci with the live
19
19
  * dispatcher, draining queued calls in order first. Malformed or unknown
20
- * commands are ignored after a debug record; the CMP preset is authoritative
21
- * over consent commands (manual mode only).
20
+ * commands are ignored after a debug record.
22
21
  */
23
- export declare function installCommandQueue(win: AciHost, cfg: CommandQueueConfig, handlers: CommandHandlers, debug?: DebugFn): void;
22
+ export declare function installCommandQueue(win: AciHost, handlers: CommandHandlers, debug?: DebugFn): void;
24
23
  export {};
@@ -2,6 +2,7 @@
2
2
  // queue. Pre-load calls push onto aci.q via the documented array-push stub;
3
3
  // installCommandQueue drains that queue in order and becomes the live
4
4
  // dispatcher. Commands return undefined — nothing is readable back.
5
+ import { parseAssignment } from "./assignments.js";
5
6
  import { toCustomEventName } from "./declarative.js";
6
7
  function isPlainObjectLike(value) {
7
8
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -9,13 +10,30 @@ function isPlainObjectLike(value) {
9
10
  /**
10
11
  * installCommandQueue replaces any pre-load stub on window.aci with the live
11
12
  * dispatcher, draining queued calls in order first. Malformed or unknown
12
- * commands are ignored after a debug record; the CMP preset is authoritative
13
- * over consent commands (manual mode only).
13
+ * commands are ignored after a debug record.
14
14
  */
15
- export function installCommandQueue(win, cfg, handlers, debug) {
15
+ export function installCommandQueue(win, handlers, debug) {
16
16
  const dispatch = (...args) => {
17
17
  try {
18
18
  const [command, ...rest] = args;
19
+ if (command === "navigation-complete") {
20
+ const value = rest[0];
21
+ if (!isPlainObjectLike(value) || typeof value.url !== "string" || !/^https?:\/\//.test(value.url) || !Array.isArray(value.assignments) || value.assignments.length > 16) {
22
+ debug?.("capture", { reason: "malformed_navigation_completion" });
23
+ return undefined;
24
+ }
25
+ const assignments = [];
26
+ for (const candidate of value.assignments) {
27
+ const assignment = parseAssignment(candidate);
28
+ if (!assignment || assignments.some(item => item.experimentId === assignment.experimentId)) {
29
+ debug?.("capture", { reason: "malformed_navigation_completion" });
30
+ return undefined;
31
+ }
32
+ assignments.push(assignment);
33
+ }
34
+ handlers.navigationComplete({ url: value.url, assignments });
35
+ return undefined;
36
+ }
19
37
  if (command === "track") {
20
38
  const name = toCustomEventName(rest[0]);
21
39
  if (name === undefined) {
@@ -31,11 +49,6 @@ export function installCommandQueue(win, cfg, handlers, debug) {
31
49
  return undefined;
32
50
  }
33
51
  if (command === "consent") {
34
- if (cfg.preset !== "manual") {
35
- // The CMP is authoritative (design/04 consent-writer precedence).
36
- debug?.("consent", { reason: "preset_authoritative", preset: cfg.preset });
37
- return undefined;
38
- }
39
52
  const envelope = rest[0];
40
53
  if (!isPlainObjectLike(envelope)) {
41
54
  debug?.("consent", { reason: "malformed_consent_envelope" });
@@ -12,6 +12,7 @@ interface DocumentLike {
12
12
  textContent: string | null;
13
13
  } | null;
14
14
  }
15
+ export declare function parseAssignment(value: unknown): ExperimentAssignment | null;
15
16
  /**
16
17
  * readAssignments parses the page's data-aci-assignments tag. Absence, a
17
18
  * malformed body, or an unknown version are tolerated as "no assignments"
@@ -38,17 +39,14 @@ export interface AssignmentsHandle {
38
39
  * emit's withAssignmentContext dependency exists before emit can run.
39
40
  */
40
41
  start(emit: (event: PendingEvent) => void): void;
41
- /**
42
- * rearm resets the per-page-view exposure dedupe and re-reads the tag.
43
- * Wired by init into the shared navigation hook, ORDERED BEFORE the SPA
44
- * page-view emitter so rum.page_view is stamped with the new page's
45
- * context (REQ-2/3; see the module-header stale-tag limitation).
46
- */
47
- rearm(): void;
42
+ /** Clear attribution while a client navigation is awaiting its page commit. */
43
+ clear(): void;
44
+ /** Reset exposure deduplication from the committed page payload. */
45
+ rearm(assignments?: ExperimentAssignment[]): void;
48
46
  }
49
47
  /**
50
- * withAssignmentContext stamps the first active assignment's experiment
51
- * context onto an event that does not already carry one (REQ-3). Events with
48
+ * withAssignmentContext stamps every active assignment's experiment
49
+ * context onto an event that does not already carry a list (REQ-3). Events with
52
50
  * explicit context (exposures, explicit conversions) are never overwritten.
53
51
  */
54
52
  export declare function withAssignmentContext(event: PendingEvent, handle: AssignmentsHandle | undefined): PendingEvent;
@@ -8,20 +8,13 @@
8
8
  // is active (REQ-3). Absent or malformed tags are a silent no-op with a
9
9
  // debug record; the page is never affected.
10
10
  //
11
- // KNOWN LIMITATION — SPA client-side routing reads a stale tag. The re-arm
12
- // (AssignmentsHandle.rearm, wired to the shared navigation hook in init)
13
- // runs synchronously when pushState/replaceState returns, but client
14
- // routers (e.g. the Next app router) swap the page's DOM — including the
15
- // assignments tag — AFTER pushState returns. The re-arm therefore reads the
16
- // PREVIOUS page's tag. The design assumption is MPA / full-SSR-first
17
- // navigation, where every page view is a fresh document load and the tag is
18
- // always current; under pure client-side transitions, exposures and context
19
- // stamping for the newly routed page lag one navigation behind. Accepted
20
- // for now — do not "fix" with a MutationObserver.
11
+ // History changes clear attribution immediately. Framework completion supplies
12
+ // the committed page's assignments before exposures and its page-view event.
13
+ // No DOM observer or assumed router/DOM timing participates in attribution.
21
14
  export const EXPERIMENT_EXPOSURE_EVENT = "experiment.exposure";
22
15
  const ASSIGNMENTS_SELECTOR = 'script[type="application/json"][data-aci-assignments]';
23
16
  const ASSIGNMENTS_VERSION = 1;
24
- function parseAssignment(value) {
17
+ export function parseAssignment(value) {
25
18
  if (typeof value !== "object" || value === null)
26
19
  return null;
27
20
  const record = value;
@@ -63,7 +56,7 @@ export function readAssignments(doc, debug) {
63
56
  const assignments = [];
64
57
  for (const entry of body.experiments) {
65
58
  const assignment = parseAssignment(entry);
66
- if (assignment)
59
+ if (assignment && !assignments.some(existing => existing.experimentId === assignment.experimentId))
67
60
  assignments.push(assignment);
68
61
  }
69
62
  return assignments;
@@ -77,22 +70,17 @@ export function readAssignments(doc, debug) {
77
70
  }
78
71
  }
79
72
  /**
80
- * withAssignmentContext stamps the first active assignment's experiment
81
- * context onto an event that does not already carry one (REQ-3). Events with
73
+ * withAssignmentContext stamps every active assignment's experiment
74
+ * context onto an event that does not already carry a list (REQ-3). Events with
82
75
  * explicit context (exposures, explicit conversions) are never overwritten.
83
76
  */
84
77
  export function withAssignmentContext(event, handle) {
85
- if (!handle || event.experiment !== undefined)
78
+ if (!handle || event.experiments !== undefined)
86
79
  return event;
87
- const first = handle.getActiveAssignments()[0];
88
- if (!first)
80
+ const experiments = handle.getActiveAssignments();
81
+ if (experiments.length === 0)
89
82
  return event;
90
- const experiment = {
91
- experimentId: first.experimentId,
92
- armId: first.armId,
93
- allocationVersion: first.allocationVersion,
94
- };
95
- return { ...event, experiment };
83
+ return { ...event, experiments };
96
84
  }
97
85
  /**
98
86
  * createAssignments builds the assignments collector without emitting
@@ -107,8 +95,8 @@ export function createAssignments(env) {
107
95
  let active = [];
108
96
  const exposed = new Set();
109
97
  let emit;
110
- const arm = () => {
111
- active = readAssignments(env.document, env.debug);
98
+ const arm = (assignments) => {
99
+ active = (assignments ?? readAssignments(env.document, env.debug)).map(assignment => ({ ...assignment }));
112
100
  for (const assignment of active) {
113
101
  if (exposed.has(assignment.experimentId))
114
102
  continue;
@@ -116,11 +104,11 @@ export function createAssignments(env) {
116
104
  emit?.({
117
105
  eventName: EXPERIMENT_EXPOSURE_EVENT,
118
106
  url: env.window.location.href,
119
- experiment: {
120
- experimentId: assignment.experimentId,
121
- armId: assignment.armId,
122
- allocationVersion: assignment.allocationVersion,
123
- },
107
+ experiments: [{
108
+ experimentId: assignment.experimentId,
109
+ armId: assignment.armId,
110
+ allocationVersion: assignment.allocationVersion,
111
+ }],
124
112
  });
125
113
  }
126
114
  };
@@ -130,9 +118,12 @@ export function createAssignments(env) {
130
118
  emit = emitFn;
131
119
  arm();
132
120
  },
133
- rearm() {
121
+ clear() {
122
+ active = [];
123
+ },
124
+ rearm(assignments) {
134
125
  exposed.clear();
135
- arm();
126
+ arm(assignments);
136
127
  },
137
128
  };
138
129
  }
@@ -8,8 +8,9 @@ import type { DebugFn } from "./config.js";
8
8
  export interface ExperimentContext {
9
9
  experimentId: string;
10
10
  armId: string;
11
- allocationVersion: string;
11
+ allocationVersion?: string;
12
12
  goalId?: string;
13
+ assignmentBucket?: number;
13
14
  }
14
15
  /** One collect event on the wire (personalization-data-plane design/04). */
15
16
  export interface CollectEvent {
@@ -19,18 +20,19 @@ export interface CollectEvent {
19
20
  properties?: Record<string, unknown>;
20
21
  url?: string;
21
22
  referrer?: string;
22
- experiment?: ExperimentContext;
23
+ experiments?: ExperimentContext[];
23
24
  }
24
25
  /** An event at capture time, before the eventId is stamped. */
25
26
  export type PendingEvent = Omit<CollectEvent, "eventId">;
26
27
  /** Planning threshold: full serialized envelope, UTF-8 bytes. */
27
28
  export declare const MAX_BATCH_BYTES: number;
28
29
  /**
29
- * Hard event-count cap per envelope. The Next collect-route imports this
30
- * constant and rejects larger envelopes (the Go handler enforces only the
31
- * 64KiB body cap today), so a byte-capped-only batch of small events (~400
32
- * fit in 60KiB) would 400 on that host and silently lose the whole flush.
33
- * The client caps at the strictest host.
30
+ * Hard event-count cap per envelope. The provider-neutral runtime collector
31
+ * (internal/domain/audience/runtime/collect.ts MAX_BATCH_EVENTS) enforces the
32
+ * same bound server-side (the Go handler enforces only the 64KiB body cap
33
+ * today), so a byte-capped-only batch of small events (~400 fit in 60KiB)
34
+ * would 400 on that host and silently lose the whole flush. The client caps
35
+ * at the strictest host; keep the two constants equal.
34
36
  */
35
37
  export declare const MAX_BATCH_EVENTS = 100;
36
38
  /** Flush interval (build-time constant, design/04 config table). */
@@ -7,11 +7,12 @@ import { ulid } from "./ulid.js";
7
7
  /** Planning threshold: full serialized envelope, UTF-8 bytes. */
8
8
  export const MAX_BATCH_BYTES = 60 * 1024;
9
9
  /**
10
- * Hard event-count cap per envelope. The Next collect-route imports this
11
- * constant and rejects larger envelopes (the Go handler enforces only the
12
- * 64KiB body cap today), so a byte-capped-only batch of small events (~400
13
- * fit in 60KiB) would 400 on that host and silently lose the whole flush.
14
- * The client caps at the strictest host.
10
+ * Hard event-count cap per envelope. The provider-neutral runtime collector
11
+ * (internal/domain/audience/runtime/collect.ts MAX_BATCH_EVENTS) enforces the
12
+ * same bound server-side (the Go handler enforces only the 64KiB body cap
13
+ * today), so a byte-capped-only batch of small events (~400 fit in 60KiB)
14
+ * would 400 on that host and silently lose the whole flush. The client caps
15
+ * at the strictest host; keep the two constants equal.
15
16
  */
16
17
  export const MAX_BATCH_EVENTS = 100;
17
18
  /** Flush interval (build-time constant, design/04 config table). */
@@ -18,6 +18,11 @@ export interface Purgeable {
18
18
  }
19
19
  export interface ApplyConsentDeps extends ConsentWriteDeps {
20
20
  gapBuffer?: Purgeable;
21
+ /**
22
+ * Runs after the envelope is written: the collect SDK resolves its
23
+ * consent-pending hold against the new decision (consenthold.ts).
24
+ */
25
+ onDecision?: () => void;
21
26
  }
22
27
  /**
23
28
  * writeConsent builds the {v:1, p, t, src} envelope, URL-encodes it and sets
@@ -29,7 +34,8 @@ export declare function writeConsent(purposes: string[], src: string, deps: Cons
29
34
  * applyConsent is the single write path for every consent decision — CMP
30
35
  * adapters and the manual JS API alike. Any decision where personalization
31
36
  * is absent purges the gap buffer (REQ-8), and the envelope is still
32
- * written: withdrawal must reach the server.
37
+ * written: withdrawal must reach the server. onDecision runs after the write
38
+ * so events held while the decision was pending see the envelope (REQ-15).
33
39
  */
34
40
  export declare function applyConsent(purposes: string[], src: string, deps: ApplyConsentDeps): boolean;
35
41
  /** readConsentCookie returns the raw (still URL-encoded) cookie value. */
@@ -31,7 +31,8 @@ function writePreparedConsent(prepared, deps) {
31
31
  * applyConsent is the single write path for every consent decision — CMP
32
32
  * adapters and the manual JS API alike. Any decision where personalization
33
33
  * is absent purges the gap buffer (REQ-8), and the envelope is still
34
- * written: withdrawal must reach the server.
34
+ * written: withdrawal must reach the server. onDecision runs after the write
35
+ * so events held while the decision was pending see the envelope (REQ-15).
35
36
  */
36
37
  export function applyConsent(purposes, src, deps) {
37
38
  const prepared = prepareConsentEnvelope(purposes, src, deps.now);
@@ -41,6 +42,7 @@ export function applyConsent(purposes, src, deps) {
41
42
  deps.gapBuffer?.purge();
42
43
  }
43
44
  writePreparedConsent(prepared, deps);
45
+ deps.onDecision?.();
44
46
  return true;
45
47
  }
46
48
  /** readConsentCookie returns the raw (still URL-encoded) cookie value. */
@@ -25,6 +25,8 @@ export interface ConsentTargetDeps {
25
25
  gapBuffer?: Purgeable | undefined;
26
26
  debug?: DebugFn | undefined;
27
27
  now?: (() => number) | undefined;
28
+ /** Runs after a decision is written (applyConsent onDecision). */
29
+ onDecision?: (() => void) | undefined;
28
30
  }
29
31
  /**
30
32
  * handleCmpState is the shared onCmpChange: resolve the mapping, reject the
@@ -67,6 +67,7 @@ export function handleCmpState(state, preset, deps) {
67
67
  document: deps.document,
68
68
  gapBuffer: deps.gapBuffer,
69
69
  now: deps.now,
70
+ onDecision: deps.onDecision,
70
71
  });
71
72
  deps.debug?.("consent", { reason: "written", preset, purposes });
72
73
  }
@@ -0,0 +1,38 @@
1
+ import type { CollectEvent } from "./batcher.js";
2
+ import type { DebugFn } from "./config.js";
3
+ import type { EventSink } from "./gapbuffer.js";
4
+ export declare const CONSENT_HOLD_CAP = 50;
5
+ export declare const CONSENT_HOLD_MAX_AGE_MS: number;
6
+ export interface ConsentHoldEnv {
7
+ now?: () => number;
8
+ debug?: DebugFn | undefined;
9
+ }
10
+ export declare class ConsentHold {
11
+ private events;
12
+ private readonly now;
13
+ private readonly debug;
14
+ constructor(env?: ConsentHoldEnv);
15
+ push(event: CollectEvent): void;
16
+ size(): number;
17
+ /** release returns and clears the unexpired held events, in capture order. */
18
+ release(): CollectEvent[];
19
+ /** discard drops every held event; nothing is ever sent for them. */
20
+ discard(reason: "denied" | "unload"): void;
21
+ private expire;
22
+ }
23
+ export interface ConsentHoldDecisionDeps {
24
+ /** Whether an aci_consent envelope exists (any decision, grant or not). */
25
+ decided: () => boolean;
26
+ /** Whether that envelope grants personalization. */
27
+ grants: () => boolean;
28
+ batcher: EventSink;
29
+ debug?: DebugFn | undefined;
30
+ }
31
+ /**
32
+ * resolveConsentHold applies a consent decision to the hold: nothing while
33
+ * undecided; a grant releases every held event into the batcher; any other
34
+ * decision discards them. Runs from the consent write path and on every
35
+ * batcher flush tick, so a decision written by another tab or by site code
36
+ * is noticed too.
37
+ */
38
+ export declare function resolveConsentHold(hold: ConsentHold, deps: ConsentHoldDecisionDeps): void;
@@ -0,0 +1,82 @@
1
+ // Consent-pending hold (personalization-onboarding REQ-15, D-ONB-13): on a
2
+ // site whose tag names a CMP preset, a consent integration will write the
3
+ // aci_consent envelope — often after hydration. Until it does, and while no
4
+ // identity exists (no aci_m marker), the collector can only drop what the SDK
5
+ // sends (no identity cookie, no identity-tier consent). Rather than transmit
6
+ // a first view's exposure and page view to be discarded, emit holds them:
7
+ //
8
+ // - in page memory only — never sessionStorage, never transmitted;
9
+ // - bounded: CONSENT_HOLD_CAP events (the newest are refused, so the
10
+ // first-view exposure and page view survive) and CONSENT_HOLD_MAX_AGE_MS;
11
+ // - a granting decision releases them, in capture order with their capture-
12
+ // time eventIds, into the batcher so they leave in the next envelope under
13
+ // the just-written consent envelope (they were never enveloped before, so
14
+ // no eventId is reused across envelopes);
15
+ // - a non-granting decision, or pagehide without a decision, discards them.
16
+ export const CONSENT_HOLD_CAP = 50;
17
+ export const CONSENT_HOLD_MAX_AGE_MS = 30 * 60 * 1000;
18
+ export class ConsentHold {
19
+ events = [];
20
+ now;
21
+ debug;
22
+ constructor(env) {
23
+ this.now = env?.now ?? Date.now;
24
+ this.debug = env?.debug;
25
+ }
26
+ push(event) {
27
+ this.expire();
28
+ if (this.events.length >= CONSENT_HOLD_CAP) {
29
+ this.debug?.("buffer", { reason: "consent_hold_cap_drop_newest", eventId: event.eventId });
30
+ return;
31
+ }
32
+ this.events.push({ event, heldAt: this.now() });
33
+ }
34
+ size() {
35
+ return this.events.length;
36
+ }
37
+ /** release returns and clears the unexpired held events, in capture order. */
38
+ release() {
39
+ this.expire();
40
+ const released = this.events.map((held) => held.event);
41
+ this.events = [];
42
+ return released;
43
+ }
44
+ /** discard drops every held event; nothing is ever sent for them. */
45
+ discard(reason) {
46
+ if (this.events.length > 0) {
47
+ this.debug?.("buffer", { reason: `consent_hold_discarded_${reason}`, count: this.events.length });
48
+ }
49
+ this.events = [];
50
+ }
51
+ expire() {
52
+ const cutoff = this.now() - CONSENT_HOLD_MAX_AGE_MS;
53
+ let expired = 0;
54
+ while (expired < this.events.length && this.events[expired].heldAt < cutoff) {
55
+ expired += 1;
56
+ }
57
+ if (expired > 0) {
58
+ this.events.splice(0, expired);
59
+ this.debug?.("buffer", { reason: "consent_hold_expired", count: expired });
60
+ }
61
+ }
62
+ }
63
+ /**
64
+ * resolveConsentHold applies a consent decision to the hold: nothing while
65
+ * undecided; a grant releases every held event into the batcher; any other
66
+ * decision discards them. Runs from the consent write path and on every
67
+ * batcher flush tick, so a decision written by another tab or by site code
68
+ * is noticed too.
69
+ */
70
+ export function resolveConsentHold(hold, deps) {
71
+ if (hold.size() === 0 || !deps.decided())
72
+ return;
73
+ if (!deps.grants()) {
74
+ hold.discard("denied");
75
+ return;
76
+ }
77
+ const events = hold.release();
78
+ for (const event of events) {
79
+ deps.batcher.push(event);
80
+ }
81
+ deps.debug?.("buffer", { reason: "consent_hold_released", count: events.length });
82
+ }