@gradial/aci 0.1.52-rc.21 → 0.1.52-rc.24

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 (143) hide show
  1. package/README.md +79 -5
  2. package/dist/astro/index.js +4 -0
  3. package/dist/audience-data-models.d.ts +12 -0
  4. package/dist/audience-data-models.js +3 -0
  5. package/dist/cli/mintlify-render.d.mts +1 -0
  6. package/dist/cli/mintlify-render.mjs +8 -0
  7. package/dist/collect/aci.js +1 -1
  8. package/dist/collect/aci.js.sha256 +1 -1
  9. package/dist/collect/api.d.ts +3 -0
  10. package/dist/collect/api.js +19 -0
  11. package/dist/collect/assignments.d.ts +7 -9
  12. package/dist/collect/assignments.js +23 -32
  13. package/dist/collect/batcher.d.ts +3 -2
  14. package/dist/collect/consent/envelope.d.ts +7 -1
  15. package/dist/collect/consent/envelope.js +3 -1
  16. package/dist/collect/consent/mapping.d.ts +2 -0
  17. package/dist/collect/consent/mapping.js +1 -0
  18. package/dist/collect/consenthold.d.ts +38 -0
  19. package/dist/collect/consenthold.js +82 -0
  20. package/dist/collect/declarative.js +7 -5
  21. package/dist/collect/gapbuffer.d.ts +13 -4
  22. package/dist/collect/gapbuffer.js +10 -4
  23. package/dist/collect/index.js +66 -19
  24. package/dist/collect/pageviews.d.ts +11 -11
  25. package/dist/collect/pageviews.js +27 -22
  26. package/dist/consent-banner/index.d.ts +17 -0
  27. package/dist/consent-banner/index.js +23 -0
  28. package/dist/content/provider.d.ts +8 -0
  29. package/dist/index.d.ts +1 -1
  30. package/dist/internal/domain/edge/identity.d.ts +5 -0
  31. package/dist/internal/domain/edge/identity.js +49 -13
  32. package/dist/internal/domain/edge/mimic_token.d.ts +1 -0
  33. package/dist/internal/domain/edge/mimic_token.js +74 -7
  34. package/dist/internal/domain/edge/personalization-core.d.ts +8 -33
  35. package/dist/internal/domain/edge/personalization-core.js +151 -195
  36. package/dist/internal/domain/edge/personalization_index.d.ts +17 -0
  37. package/dist/internal/domain/edge/personalization_index.js +56 -0
  38. package/dist/internal/domain/edge/record/codec.d.ts +1 -30
  39. package/dist/internal/domain/edge/record/codec.js +1 -156
  40. package/dist/internal/domain/edge/resolve.js +55 -38
  41. package/dist/internal/domain/edge/types.d.ts +41 -32
  42. package/dist/internal/domain/edge/variant_key.d.ts +3 -0
  43. package/dist/internal/domain/edge/variant_key.js +44 -0
  44. package/dist/internal/platform/collectionstore/errors.d.ts +13 -0
  45. package/dist/internal/platform/collectionstore/errors.js +28 -0
  46. package/dist/mintlify/blocks.d.ts +6 -0
  47. package/dist/mintlify/blocks.js +198 -0
  48. package/dist/mintlify/config.d.ts +3 -0
  49. package/dist/mintlify/config.js +77 -0
  50. package/dist/mintlify/index.d.ts +3 -0
  51. package/dist/mintlify/index.js +2 -0
  52. package/dist/mintlify/json.d.ts +8 -0
  53. package/dist/mintlify/json.js +37 -0
  54. package/dist/mintlify/materialize.d.ts +12 -0
  55. package/dist/mintlify/materialize.js +159 -0
  56. package/dist/mintlify/types.d.ts +69 -0
  57. package/dist/mintlify/types.js +1 -0
  58. package/dist/mintlify/validate.d.ts +7 -0
  59. package/dist/mintlify/validate.js +252 -0
  60. package/dist/next/assignments-navigation.d.ts +4 -0
  61. package/dist/next/assignments-navigation.js +18 -0
  62. package/dist/next/assignments-script.d.ts +3 -2
  63. package/dist/next/assignments-script.js +5 -5
  64. package/dist/next/error-seat.js +3 -0
  65. package/dist/next/index.d.ts +1 -0
  66. package/dist/next/index.js +3 -0
  67. package/dist/next/render.js +8 -1
  68. package/dist/react/VideoPlayer.d.ts +1 -1
  69. package/dist/react/index.d.ts +1 -1
  70. package/dist/registry.d.ts +4 -2
  71. package/dist/testing/conformance/checks.d.ts +2 -2
  72. package/dist/testing/conformance/checks.js +2 -0
  73. package/dist/testing/conformance/index.d.ts +1 -0
  74. package/dist/testing/conformance/index.js +1 -0
  75. package/dist/testing/conformance/next-stubs.d.ts +6 -0
  76. package/dist/testing/conformance/next-stubs.js +9 -0
  77. package/dist/testing/conformance/preset.d.ts +3 -2
  78. package/dist/testing/conformance/preset.js +12 -8
  79. package/dist/testing/conformance/root-identity.d.ts +31 -0
  80. package/dist/testing/conformance/root-identity.js +380 -0
  81. package/dist/testing/conformance/stubs/next-image.d.ts +7 -0
  82. package/dist/testing/conformance/stubs/next-image.js +5 -0
  83. package/dist/testing/conformance/stubs/next-link.d.ts +7 -0
  84. package/dist/testing/conformance/stubs/next-link.js +4 -0
  85. package/dist/testing/conformance/types.d.ts +2 -2
  86. package/dist/testing/index.js +2 -2
  87. package/dist/types/component.d.ts +9 -0
  88. package/package.json +11 -7
  89. package/src/cli/mintlify-render.mjs +9 -0
  90. package/src/types/component.ts +10 -0
  91. package/templates/astro/starter-content/src/components/chrome/Footer.astro +5 -3
  92. package/templates/astro/starter-content/src/components/chrome/Header.astro +5 -3
  93. package/templates/astro/starter-content/src/components/elements/Button.astro +5 -2
  94. package/templates/astro/starter-content/src/components/elements/ButtonBlock.astro +5 -3
  95. package/templates/astro/starter-content/src/components/sections/ContainerSection.astro +4 -3
  96. package/templates/astro/starter-content/src/components/sections/FeatureCard.astro +4 -3
  97. package/templates/astro/starter-content/src/components/sections/FeatureGrid.astro +4 -3
  98. package/templates/astro/starter-content/src/components/sections/HomeHero.astro +5 -3
  99. package/templates/astro/starter-content/src/components/sections/PersonalizationChoice.astro +4 -3
  100. package/templates/astro/starter-content/src/components/sections/StatsBar.astro +4 -3
  101. package/templates/astro/starter-content/src/fixtures/sections.ts +1 -1
  102. package/templates/astro/starter-content/src/stories/CompositionStoryFrame.astro +7 -2
  103. package/templates/astro/template/package.json.tmpl +4 -4
  104. package/templates/common/.agents/skills/aci/SKILL.md +50 -0
  105. package/templates/common/.agents/skills/authoring/SKILL.md +4 -3
  106. package/templates/common/.agents/skills/authoring/references/block-registry.md +15 -0
  107. package/templates/common/.agents/skills/migration/references/selector-map.md +1 -1
  108. package/templates/common/.content/schemas/site.schema.json +11 -1
  109. package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/asset.json +1 -1
  110. package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/asset.json +1 -1
  111. package/templates/common/starter-content/.content/pages/404/_index.json +1 -1
  112. package/templates/common/starter-content/.content/pages/{home/_index.json → _index.json} +2 -2
  113. package/templates/common/starter-content/.content/pages/about/_index.json +1 -1
  114. package/templates/common/starter-content/.content/pages/error/_index.json +1 -1
  115. package/templates/common/starter-content/.content/patterns/components/button.json +2 -2
  116. package/templates/common/starter-content/.content/patterns/components/container.json +2 -2
  117. package/templates/common/starter-content/.content/patterns/components/feature_card.json +2 -2
  118. package/templates/common/starter-content/.content/patterns/components/feature_grid.json +2 -2
  119. package/templates/common/starter-content/.content/patterns/components/home_hero.json +2 -2
  120. package/templates/common/starter-content/.content/patterns/components/site-footer.json +2 -2
  121. package/templates/common/starter-content/.content/patterns/components/site-navigation.json +2 -2
  122. package/templates/common/starter-content/.content/patterns/components/stats_bar.json +2 -2
  123. package/templates/common/starter-content/.content/patterns/layouts/default.json +2 -2
  124. package/templates/common/starter-content/.content/schemas/site.schema.json +11 -1
  125. package/templates/nextjs/starter-content/src/components/chrome/Footer.tsx +4 -3
  126. package/templates/nextjs/starter-content/src/components/chrome/Header.tsx +4 -3
  127. package/templates/nextjs/starter-content/src/components/elements/Button.tsx +4 -3
  128. package/templates/nextjs/starter-content/src/components/elements/ButtonBlock.tsx +4 -3
  129. package/templates/nextjs/starter-content/src/components/sections/ContainerSection.tsx +4 -2
  130. package/templates/nextjs/starter-content/src/components/sections/FeatureCard.tsx +4 -3
  131. package/templates/nextjs/starter-content/src/components/sections/FeatureGrid.tsx +4 -2
  132. package/templates/nextjs/starter-content/src/components/sections/HomeHero.tsx +4 -3
  133. package/templates/nextjs/starter-content/src/components/sections/PersonalizationChoice.tsx +4 -2
  134. package/templates/nextjs/starter-content/src/components/sections/StatsBar.tsx +4 -3
  135. package/templates/astro/starter-content/src/render/RenderPage.astro +0 -67
  136. package/templates/common/starter-content/.content/patterns/components/personalization_choice.json +0 -42
  137. package/templates/nextjs/starter-content/src/components/elements/AtomicBlock.tsx +0 -13
  138. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/editorial.json +0 -0
  139. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000101}/governance.json +0 -0
  140. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/versions/v0001.json +0 -0
  141. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/editorial.json +0 -0
  142. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000102}/governance.json +0 -0
  143. /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/versions/v0001.json +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agentic Content Infrastructure SDK
2
2
 
3
- `@gradial/aci` `0.1.52-rc.21` is a pre-1.0 public-surface reset for the ACI
3
+ `@gradial/aci` `0.1.52-rc.24` is a pre-1.0 public-surface reset for the ACI
4
4
  client SDK. Breaking changes from the old `0.1.x` accidental surface are
5
5
  intentional: the root import is framework-neutral, framework runtime behavior is
6
6
  behind explicit subpaths, and the first required customer path is React/Next.
@@ -8,7 +8,7 @@ behind explicit subpaths, and the first required customer path is React/Next.
8
8
  ## Install
9
9
 
10
10
  ```bash
11
- npm install @gradial/aci@0.1.52-rc.21 zod@^4
11
+ npm install @gradial/aci@0.1.52-rc.24 zod@^4
12
12
  ```
13
13
 
14
14
  ## Root Import
@@ -62,6 +62,58 @@ export default withAci(nextConfig, {
62
62
 
63
63
  Astro public subpath is `@gradial/aci/astro`.
64
64
 
65
+ ## Block Root Identity
66
+
67
+ The renderer passes every block two props, `data-aci-block` (the authored
68
+ block id) and `data-aci-component`. A component extends `RootIdentityProps`
69
+ and spreads the rest of its props onto its root element, so analytics can join
70
+ events to content by (page path, block id):
71
+
72
+ ```tsx
73
+ import type { RootIdentityProps } from '@gradial/aci';
74
+
75
+ export function StatsBar({ stats = [], ...root }: ContentProps & RootIdentityProps) {
76
+ return <section {...root} className="…">…</section>;
77
+ }
78
+ ```
79
+
80
+ Three checks make this required: `createRegistry` fails typecheck for a
81
+ component whose props type lacks the keys, the default `rootIdentity`
82
+ conformance check renders every registered component and fails when the root
83
+ lacks the attributes, and publish rejects a release whose rendered HTML is
84
+ missing a block id. `runConformanceChecks` is async; `await` it before reading
85
+ `.passed`.
86
+
87
+ ## Mintlify
88
+
89
+ `@gradial/aci/mintlify` is the Mintlify adapter used automatically by the ACI
90
+ CLI. Mintlify remains the renderer; ACI owns the standard `.content` tree.
91
+ Documents use stable ACI component IDs and an
92
+ ordered recursive block tree: Markdown slices for prose, typed nested Mintlify
93
+ components and stable accessibility-safe anchors for common structures, and
94
+ explicit `mintlify.mdx` nodes for native syntax that has not been promoted to a
95
+ typed contract.
96
+
97
+ The source tree may also contain independently governed snippets, recursive
98
+ `docs.json` `$ref` fragments, and OpenAPI, AsyncAPI, or GraphQL descriptions:
99
+
100
+ ```text
101
+ .content/
102
+ config/site.json
103
+ config/mintlify.json
104
+ pages/**/_index.json
105
+ fragments/**/_index.json
106
+ ```
107
+
108
+ ```bash
109
+ aci content compile
110
+ ```
111
+
112
+ See `starters/mintlify/` for the smallest runnable site. `.aci.yaml` selects
113
+ `framework: mintlify`; no renderer or validation flag is needed. The command
114
+ validates the graph and writes the native project to
115
+ `.aci/compiled/renderers/mintlify/` beside the ordinary compiled manifest.
116
+
65
117
  ## Build-Time Content Provider
66
118
 
67
119
  The file provider reads compiler output while generating complete static pages:
@@ -78,13 +130,13 @@ host bundles select and serve immutable release artifacts.
78
130
  The first RC scaffold path is Next:
79
131
 
80
132
  ```bash
81
- npx @gradial/aci@0.1.52-rc.21 init my-site --template next-starter
133
+ npx @gradial/aci@0.1.52-rc.24 init my-site --template next-starter
82
134
  ```
83
135
 
84
136
  List available templates:
85
137
 
86
138
  ```bash
87
- npx @gradial/aci@0.1.52-rc.21 init --list
139
+ npx @gradial/aci@0.1.52-rc.24 init --list
88
140
  ```
89
141
 
90
142
  ## Personalization: The One-Tag Install
@@ -107,7 +159,7 @@ Tag attributes (the tag is the only per-site configuration surface):
107
159
 
108
160
  | Attribute | Meaning |
109
161
  | --- | --- |
110
- | `data-aci-consent` | CMP preset: `c15t`, `onetrust`, `cookiebot`, `trustarc`, or `manual` (default `manual` — only the JS consent API `aci('consent', …)` writes envelopes) |
162
+ | `data-aci-consent` | CMP preset: `c15t`, `onetrust`, `cookiebot`, `trustarc`, or `manual` (default `manual` — only the JS consent API `aci('consent', …)` writes envelopes). A CMP preset tells the SDK the CMP will decide: until it writes consent, a first-time visitor's events (the exposure and page view included) wait in page memory, are sent once consent is granted, and are dropped on denial or when the page closes undecided. Only name a preset whose CMP is actually wired. Under `manual`, ACI's own consent banner (`ConsentBanner.astro`) plays that role: while it awaits the visitor, first views are held the same way. |
111
163
  | `data-aci-consent-categories` | Flat comma list of CMP categories that imply the personalization purpose (e.g. `measurement,marketing`); each preset ships a sane default |
112
164
  | `data-aci-site` | Optional site ID, debug only — the edge binding is the site authority |
113
165
  | `data-aci-debug` | `1` enables structured `console.debug` diagnostics |
@@ -134,6 +186,28 @@ has no Astro UI package, so the Astro kit ships the bridge only (in
134
186
  `@c15t/react`) or any setup built on c15t's store and the bridge picks it
135
187
  up; until then only the `manual` JS consent API writes envelopes.
136
188
 
189
+ ### Client-side navigation and experiment attribution
190
+
191
+ Next `createPage` includes the completion hook. Custom Next pages must render
192
+ `<AssignmentsScript page={page} />` on every page, including pages without
193
+ experiments. Astro client routing uses `astro:page-load` after the document swap.
194
+ Rebuild sites using the SDK framework integration when upgrading this contract.
195
+
196
+ For another client router, call this command after committing the destination
197
+ page. Pass the new page's complete assignment set, or `[]` for a base page:
198
+
199
+ ```js
200
+ window.aci('navigation-complete', {
201
+ url: window.location.href,
202
+ assignments: page.experiments ?? [],
203
+ });
204
+ ```
205
+
206
+ Changing the URL immediately clears attribution. Events during the transition
207
+ carry no experiment context; the completion hook emits the new exposures and
208
+ page view before subsequent conversions. Query changes count as navigation;
209
+ hash-only changes and duplicate completions do not create another page view.
210
+
137
211
  ## Verify Locally
138
212
 
139
213
  From `packages/sdk`:
@@ -61,6 +61,10 @@ export function createRenderChildren(registry) {
61
61
  if (hasBlockSlots) {
62
62
  props.renderChildren = renderChildren;
63
63
  }
64
+ // sdk I-19 (ADR 0051): root identity props are applied last so content
65
+ // props cannot overwrite them. The template spreads them onto the root.
66
+ props['data-aci-block'] = block.id;
67
+ props['data-aci-component'] = block.component;
64
68
  return { Component: entry?.component, props };
65
69
  });
66
70
  }
@@ -427,6 +427,10 @@ export declare const experimentDataModel: import("./index.js").DataModelContract
427
427
  }, z.core.$strip>;
428
428
  eligibility: z.ZodOptional<z.ZodObject<{
429
429
  audienceRef: z.ZodString;
430
+ mode: z.ZodOptional<z.ZodEnum<{
431
+ claims: "claims";
432
+ selected: "selected";
433
+ }>>;
430
434
  }, z.core.$strict>>;
431
435
  primaryGoalRef: z.ZodOptional<z.ZodString>;
432
436
  primaryGoalId: z.ZodOptional<z.ZodString>;
@@ -564,6 +568,10 @@ export declare const experimentationDataModels: (import("./index.js").DataModelC
564
568
  }, z.core.$strip>;
565
569
  eligibility: z.ZodOptional<z.ZodObject<{
566
570
  audienceRef: z.ZodString;
571
+ mode: z.ZodOptional<z.ZodEnum<{
572
+ claims: "claims";
573
+ selected: "selected";
574
+ }>>;
567
575
  }, z.core.$strict>>;
568
576
  primaryGoalRef: z.ZodOptional<z.ZodString>;
569
577
  primaryGoalId: z.ZodOptional<z.ZodString>;
@@ -1044,6 +1052,10 @@ export declare const audienceDataModels: (import("./index.js").DataModelContract
1044
1052
  }, z.core.$strip>;
1045
1053
  eligibility: z.ZodOptional<z.ZodObject<{
1046
1054
  audienceRef: z.ZodString;
1055
+ mode: z.ZodOptional<z.ZodEnum<{
1056
+ claims: "claims";
1057
+ selected: "selected";
1058
+ }>>;
1047
1059
  }, z.core.$strict>>;
1048
1060
  primaryGoalRef: z.ZodOptional<z.ZodString>;
1049
1061
  primaryGoalId: z.ZodOptional<z.ZodString>;
@@ -220,8 +220,11 @@ export const experimentDataModel = defineDataModel({
220
220
  routes: z.array(z.string().min(1)).optional(),
221
221
  fragments: z.array(z.string().min(1)).optional(),
222
222
  }),
223
+ // ADR 0050: mode is claims or selected; absent means claims. The object
224
+ // stays strict so an unknown mode value — or an unknown key — is refused.
223
225
  eligibility: z.object({
224
226
  audienceRef: z.string().min(1),
227
+ mode: z.enum(['claims', 'selected']).optional(),
225
228
  }).strict().optional(),
226
229
  primaryGoalRef: z.string().optional(),
227
230
  primaryGoalId: z.string().optional(),
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import path from 'node:path';
2
+ import { loadCompiledMintlifySource, materializeMintlifySite } from '../../dist/mintlify/index.js';
3
+ const [sourceArg, compiledArg, outputArg] = process.argv.slice(2);
4
+ if (!sourceArg || !compiledArg || !outputArg) {
5
+ throw new Error('Mintlify renderer requires content, compiled, and output directories');
6
+ }
7
+ const source = await loadCompiledMintlifySource(path.resolve(sourceArg), path.resolve(compiledArg));
8
+ await materializeMintlifySite({ ...source, outputDir: path.resolve(outputArg) });
@@ -1 +1 @@
1
- "use strict";(()=>{var Ne=Object.defineProperty;var Le=(n,e,t)=>e in n?Ne(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var y=(n,e,t)=>Le(n,typeof e!="symbol"?e+"":e,t);var x="data-aci-event",Oe="data-aci-on",H="data-aci-prop-",De="data-aci-refresh",q="custom.";function D(n){if(typeof n!="string")return;let e=n.trim().toLowerCase();if(!(e===""||/[\s/]/.test(e)))return e.startsWith(q)?e:q+e}function Re(n){let e;for(let t of Array.from(n.attributes)){if(!t.name.startsWith(H))continue;let r=t.name.slice(H.length);r!==""&&((e!=null?e:e={})[r]=t.value)}return e}function U(n,e){let t=D(n.getAttribute(x));if(t===void 0){e==null||e("capture",{reason:"malformed_declaration",attr:x});return}return{eventName:t,properties:Re(n)}}function X(n){var e,t;return(t=(e=n.getAttribute(Oe))==null?void 0:e.trim().toLowerCase())!=null?t:"click"}function $(n,e,t){let{document:r,debug:o}=e;r.addEventListener("click",f=>{var d,p;try{let u=f.target;if((d=u==null?void 0:u.closest)==null?void 0:d.call(u,`[${De}]`)){t==null||t();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&&n(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,d)=>{try{for(let p of f){if(!p.isIntersecting||p.intersectionRatio<.5||a.has(p.target))continue;a.add(p.target),d.unobserve(p.target);let u=U(p.target,o);u&&n(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(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function Y(n,e,t){let r=(...s)=>{try{let[a,...c]=s;if(a==="track"){let f=D(c[0]);if(f===void 0){t==null||t("capture",{reason:"malformed_track_name",name:c[0]});return}let d=c[1];if(d!==void 0&&!K(d)){t==null||t("capture",{reason:"malformed_track_properties",name:f});return}e.track(f,d);return}if(a==="consent"){let f=c[0];if(!K(f)){t==null||t("consent",{reason:"malformed_consent_envelope"});return}e.consent({p:f.p,src:f.src});return}t==null||t("capture",{reason:"unknown_command",command:a})}catch(a){t==null||t("capture",{reason:"command_failed",error:String(a)})}},o=n.aci,i=o==null?void 0:o.q;if(n.aci=r,i!=null)for(let s of Array.from(i)){let a=Array.from(s);r(...a)}}var Be="experiment.exposure",Fe='script[type="application/json"][data-aci-assignments]';function Ve(n){if(typeof n!="object"||n===null)return null;let e=n,t=e.experimentId,r=e.armId,o=e.allocationVersion;return typeof t!="string"||t===""||typeof r!="string"||r===""||typeof o!="string"?null:{experimentId:t,armId:r,allocationVersion:o}}function Me(n,e){try{let t=n.querySelector(Fe);if(!t)return[];let r=t.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(t){return e==null||e("capture",{reason:"assignments_parse_failed",error:String(t)}),[]}}function J(n,e){if(!e||n.experiment!==void 0)return n;let t=e.getActiveAssignments()[0];if(!t)return n;let r={experimentId:t.experimentId,armId:t.armId,allocationVersion:t.allocationVersion};return{...n,experiment:r}}function Q(n){let e=[],t=new Set,r,o=()=>{e=Me(n.document,n.debug);for(let i of e)t.has(i.experimentId)||(t.add(i.experimentId),r==null||r({eventName:Be,url:n.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(){t.clear(),o()}}}var Z="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function We(n){globalThis.crypto.getRandomValues(n)}function S(n,e){let t=n!=null?n:Date.now(),r="";for(let c=0;c<10;c++)r=Z[t%32]+r,t=Math.floor(t/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=n=>qe.encode(n).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 t;this.options=e,this.maxBytes=(t=e.maxBatchBytes)!=null?t:Ge}get pending(){return this.queue.length}push(e){let t=JSON.stringify(e),r=Ue(t);this.queue.push({json:t,bytes:r,eventId:e.eventId}),this.queuedBytes+=r,!this.flushing&&this.envelopeBytes()>=this.maxBytes&&this.flush()}flush(){var e,t;if(!this.flushing){this.flushing=!0;try{(t=(e=this.options).onTick)==null||t.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 t=(s=this.options.documentTarget)!=null?s:typeof document!="undefined"?document:void 0;t==null||t.addEventListener("visibilitychange",()=>{t.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,t,r;for(;this.queue.length>0;){let o=this.queue[0];if(A+o.bytes>this.maxBytes){this.queue.shift(),this.queuedBytes-=o.bytes,(t=(e=this.options).debug)==null||t.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(n,e){var o;let t=(o=n==null?void 0:n.getAttribute)==null?void 0:o.call(n,e);if(t==null)return;let r=t.trim();return r===""?void 0:r}function re(n){var r;let e=(r=P(n,"data-aci-consent"))==null?void 0:r.toLowerCase(),t=e!==void 0&&Xe.has(e)?e:"manual";return{site:P(n,"data-aci-site"),preset:t,categories:P(n,"data-aci-consent-categories"),debug:P(n,"data-aci-debug")==="1"}}function oe(n,e,t){if(!n)return()=>{};let r=e!=null?e:(i=>console.debug("[aci]",i)),o=t!=null?t: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 _(n,e=!0){let t=w(n);if(!t)return null;if(e)try{t=decodeURIComponent(t)}catch{}if(t=w(t),!t||R.encode(t).byteLength>$e)return null;if(tt.has(t.toLowerCase()))return{version:0,purposes:["personalization"],grantedAt:""};try{let r=JSON.parse(t),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(n){return(n==null?void 0:n.purposes.some(e=>w(e).toLowerCase()==="personalization"))||!1}function w(n){return n.replace(et,"")}function nt(n){let e=Ze.exec(n);if(!e||Number.isNaN(Date.parse(n)))return!1;let t=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(t,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(n,e){return e===2?n%4===0&&(n%100!==0||n%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(n,e){var r;let t=`${F}=${n.encoded}; Path=/; Max-Age=${ot}; SameSite=Lax`;((r=e.document.location)==null?void 0:r.protocol)==="https:"&&(t+="; Secure"),e.document.cookie=t}function I(n,e,t){var o;let r=st(n,e,t.now);return r===null?!1:(B(r.snapshot)||(o=t.gapBuffer)==null||o.purge(),it(r,t),!0)}function se(n){for(let e of n.cookie.split(";")){let t=w(e);if(t.startsWith(F+"="))return t.slice(F.length+1)}}function ae(n){return n===void 0||n===""?!1:B(_(n,!0))}function ce(n){var r;if(!Array.isArray(n))return;let e=[];for(let o of n){if(typeof o!="string")return;e.push(w(o))}let t=JSON.stringify({v:V,p:e});return(r=_(t,!1))==null?void 0:r.purposes}function ue(n){var o;if(n!==void 0&&typeof n!="string")return;let e=typeof n=="string"?w(n):"",r=JSON.stringify({v:V,p:[],src:e===""?"manual":e});return(o=_(r,!1))==null?void 0:o.source}function st(n,e,t){try{let r=JSON.stringify({v:V,p:n,t:new Date((t!=null?t: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(n,e){let t=e!=null?e:ut[n];if(t===void 0)return null;let r=t.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(n,e){return e.filter(r=>r in n.categories).some(r=>n.categories[r]===!0)?[ie]:[]}function k(n,e,t){var r,o,i,s;try{let a=M(e,t.categories);if(a===null){(r=t.debug)==null||r.call(t,"consent",{reason:"unparseable_mapping",preset:e});return}if(a.filter(d=>d in n.categories).length===0){(o=t.debug)==null||o.call(t,"consent",{reason:"unmappable_cmp_state",preset:e});return}let f=ft(n,a);I(f,at+e,{document:t.document,gapBuffer:t.gapBuffer,now:t.now}),(i=t.debug)==null||i.call(t,"consent",{reason:"written",preset:e,purposes:f})}catch(a){(s=t.debug)==null||s.call(t,"consent",{reason:"consent_bridge_failed",preset:e,error:String(a)})}}var fe=250,lt=1e4;function C(n,e,t){var s;let r=(s=t==null?void 0:t.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=n()}catch(d){(c=t==null?void 0:t.debug)==null||c.call(t,"consent",{reason:"cmp_read_failed",error:String(d)});return}if(a!==void 0){e(a);return}if(o-=1,o<=0){(f=t==null?void 0:t.debug)==null||f.call(t,"consent",{reason:"cmp_not_found"});return}r.setTimeout(i,fe)};i()}function b(n,e){try{e()}catch(t){n==null||n("consent",{reason:"adapter_failed",error:String(t)})}}var dt="c15t";function pt(n){if(typeof n!="object"||n===null)return;let e={};for(let[t,r]of Object.entries(n))typeof r=="boolean"&&(e[t.toLowerCase()]=r);return{categories:e}}function mt(n,e){return typeof n=="object"&&n!==null?"consents"in n?n.consents:n:e.consents}function le(n){C(()=>{let e=n.window.c15t;return typeof e=="object"&&e!==null?e:void 0},e=>{b(n.debug,()=>{var r;let t=o=>{let i=pt(o);i&&k(i,dt,n)};t(e.consents),(r=e.onConsentChange)==null||r.call(e,o=>b(n.debug,()=>t(mt(o,e))))})},n)}var gt="cookiebot",vt=["CookiebotOnConsentReady","CookiebotOnAccept","CookiebotOnDecline"];function de(n){let e=n.Cookiebot;return typeof e=="object"&&e!==null?e:void 0}function ht(n){if(typeof n!="object"||n===null)return;let e={};for(let[t,r]of Object.entries(n))typeof r=="boolean"&&(e[t.toLowerCase()]=r);return{categories:e}}function pe(n){let e=()=>{let r=de(n.window);if(!r||r.hasResponse!==!0)return;let o=ht(r.consent);o&&k(o,gt,n)},t=n.window;if(typeof t.addEventListener=="function")for(let r of vt)t.addEventListener(r,()=>b(n.debug,e));C(()=>de(n.window),()=>b(n.debug,e),n)}var me="onetrust",bt=/^c\d{4}$/;function yt(n,e){let t={};for(let r of n.split(",")){let o=r.trim().toLowerCase();o!==""&&(t[o]=!0)}for(let r of e!=null?e:[])!(r in t)&&bt.test(r)&&(t[r]=!1);return{categories:t}}function ge(n){let e=n.window,t=()=>{let o=e.OnetrustActiveGroups;if(typeof o!="string")return;let i=M(me,n.categories);k(yt(o,i),me,n)},r=e.OptanonWrapper;e.OptanonWrapper=()=>{if(typeof r=="function")try{r()}catch{}b(n.debug,t)},C(()=>{let o=e.OnetrustActiveGroups;return typeof o=="string"?o:void 0},()=>b(n.debug,t),n)}var Et="trustarc",kt={required:1,functional:2,advertising:3},ve="PrivacyManagerAPI";function he(n){let e=n.truste,t=e==null?void 0:e.cma,r=t==null?void 0:t.callApi;return typeof r=="function"?r.bind(t):void 0}function Ct(n){if(typeof n!="object"||n===null)return;let e=n.consentDecision;if(typeof e!="number"||!Number.isFinite(e)||e<1)return;let t={};for(let[r,o]of Object.entries(kt))t[r]=e>=o;return{categories:t}}function wt(n){return typeof n=="string"?n.includes(ve):typeof n=="object"&&n!==null&&ve in n}function St(n){let e=n.location;return typeof(e==null?void 0:e.hostname)=="string"?e.hostname:void 0}function be(n){let e=()=>{let r=he(n.window);if(!r)return;let o=Ct(r("getConsentDecision",St(n.window)));o&&k(o,Et,n)},t=n.window;typeof t.addEventListener=="function"&&t.addEventListener("message",r=>b(n.debug,()=>{wt(r==null?void 0:r.data)&&e()})),C(()=>he(n.window),()=>b(n.debug,e),n)}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 t;this.events.push(e),this.events.length>50&&(this.events.splice(0,this.events.length-50),(t=this.debug)==null||t.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 t;try{t=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(t==null)return[];try{let o=JSON.parse(t);if(Array.isArray(o))return o}catch{}try{e.removeItem(N)}catch{this.storage=void 0}return[]}persist(){var t;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,(t=this.debug)==null||t.call(this,"buffer",{reason:"storage_unavailable",error:String(r)})}}};function Ee(n){for(let e of n.cookie.split(";")){let t=e.trim();if(t.startsWith(ye+"="))return t.slice(ye.length+1)!==""}return!1}function ke(n,e){if(e.grants()&&!e.marker()){e.gapBuffer.push(n);return}e.batcher.push(n)}function W(n,e,t,r){if(n.size()===0||!t())return;let o=n.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(n,e){var i;let{document:t,debug:r}=e,o=(i=t.defaultView)==null?void 0:i.location;t.addEventListener("click",s=>{var a,c,f;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 u=p;n({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(d){r==null||r("capture",{reason:"link_click_failed",error:String(d)})}},{capture:!0})}var xt="rum.page_view";function we(n){let e=n.indexOf("#");return e===-1?n:n.slice(0,e)}function Se(n,e){let t=we(n.location.href),r=()=>{let s=we(n.location.href);if(s!==t){t=s;for(let a of e)a()}},o=n.history,i=s=>{let a=o[s].bind(o);o[s]=(...c)=>{let f=a(...c);return r(),f}};i("pushState"),i("replaceState"),n.addEventListener("popstate",r)}function _e(n,e){let t=()=>n({eventName:xt,url:e.location.href,referrer:e.document.referrer});return t(),t}var G="/collect";function xe(n,e){let t=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([n],{type:"text/plain"})}catch{t==null||t("flush",{reason:"no_blob"});return}if(r!=null&&r.sendBeacon)try{if(r.sendBeacon(G,i))return}catch{}if(!o){t==null||t("flush",{reason:"no_transport"});return}try{o(G,{method:"POST",body:i,keepalive:!0}).catch(s=>{t==null||t("flush",{reason:"fetch_failed",error:String(s)})})}catch(s){t==null||t("flush",{reason:"fetch_failed",error:String(s)})}}function Ae(n){var t,r;let e=n!==void 0&&"fetch"in n?n.fetch:globalThis.fetch;if(!e)return Promise.resolve(!1);try{let o=((t=n==null?void 0:n.createEnvelopeId)!=null?t: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=n==null?void 0:n.debug)==null||a.call(n,"flush",{reason:"refresh_failed",status:"not_ok"}),!1):!0}).catch(s=>{var a;return(a=n==null?void 0:n.debug)==null||a.call(n,"flush",{reason:"refresh_failed",error:String(s)}),!1})}catch(o){return(r=n==null?void 0:n.debug)==null||r.call(n,"flush",{reason:"refresh_failed",error:String(o)}),Promise.resolve(!1)}}var At="rum.variation_view",j="data-aci-variation";function Te(n,e){var f,d,p;let{document:t,debug:r}=e,o=e.MutationObserver;if(typeof o!="function")return;let i=(f=t.defaultView)==null?void 0:f.location,s=new WeakSet,a=u=>{let h=u.getAttribute(j);h!=null&&(s.has(u)||(s.add(u),n({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=(d=t.body)!=null?d:t.documentElement;u&&c(u)}catch(u){r==null||r("capture",{reason:"variation_initial_scan_failed",error:String(u)})}try{let u=(p=t.body)!=null?p:t.documentElement;if(!u)return;new o(m=>{try{for(let g of m)for(let l=0;l<g.addedNodes.length;l++){let v=g.addedNodes[l];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(n,e){var h,m,g;let t=e.PerformanceObserver;if(typeof t!="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=(l,v)=>{a.has(l)||(a.add(l),n({eventName:Tt,url:i,properties:{vitalName:l,vitalValue:v}}))};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 f=0,d=0,p=(l,v)=>{try{new t(Ie=>{try{for(let O of Ie.getEntries())v(O)}catch(O){o==null||o("capture",{reason:`${l}_handler_failed`,error:String(O)})}}).observe({type:l,buffered:!0})}catch(E){o==null||o("capture",{reason:`${l}_observe_failed`,error:String(E)})}};p("largest-contentful-paint",l=>{c("LCP",l.startTime)}),p("first-input",l=>{c("FID",l.startTime)}),p("layout-shift",l=>{var v;l.hadRecentInput||(f+=(v=l.value)!=null?v:0)}),p("event",l=>{var E;let v=(E=l.value)!=null?E:0;v>d&&(d=v)}),p("paint",l=>{l.name==="first-contentful-paint"&&c("FCP",l.startTime)});let u=()=>{try{a.has("CLS")||c("CLS",f),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"&&u()}),(g=e.window)==null||g.addEventListener("pagehide",u)}var z={c15t:le,onetrust:ge,cookiebot:pe,trustarc:be};function Pt(n){var e,t;return typeof((e=n.navigator)==null?void 0:e.sendBeacon)=="function"&&typeof n.IntersectionObserver=="function"&&typeof((t=n.crypto)==null?void 0:t.getRandomValues)=="function"}function It(n){try{return n.sessionStorage}catch{return}}function Nt(n){var o;let e=n!=null?n:typeof window!="undefined"?window:void 0;if(!e||e.__aci_loaded||(e.__aci_loaded=!0,!Pt(e)))return;let t=re(e.document.currentScript),r=oe(t.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},d;d=new T({send:m=>xe(m,f),debug:r,onTick:()=>W(s,d,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:d})};p.start(u),Y(e,{track:(m,g)=>u({eventName:m,properties:g}),consent:({p:m,src:g})=>{let l=ce(m);if(l===void 0){r("consent",{reason:"malformed_purposes"});return}let v=ue(g);if(v===void 0){r("consent",{reason:"malformed_source"});return}I(l,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}),t.preset!=="manual"&&((o=z[t.preset])==null||o.call(z,{window:e,document:i,categories:t.categories,gapBuffer:s,debug:r,scheduler:{setTimeout:(m,g)=>e.setTimeout(m,g),clearTimeout:m=>e.clearTimeout(m)}})),d.start(),W(s,d,c,r),r("init",{config:t})}catch(i){r("init",{error:String(i)})}}Nt();})();
1
+ "use strict";(()=>{var Me=Object.defineProperty;var je=(t,e,n)=>e in t?Me(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var b=(t,e,n)=>je(t,typeof e!="symbol"?e+"":e,n);var We="experiment.exposure",Ge='script[type="application/json"][data-aci-assignments]';function H(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 M(t,e){try{let n=t.querySelector(Ge);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=H(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 ne(t,e){if(!e||t.experiments!==void 0)return t;let n=e.getActiveAssignments();return n.length===0?t:{...t,experiments:n}}function te(t){let e=[],n=new Set,r,o=i=>{e=(i!=null?i:M(t.document,t.debug)).map(s=>({...s}));for(let s of e)n.has(s.experimentId)||(n.add(s.experimentId),r==null||r({eventName:We,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 L="data-aci-event",ze="data-aci-on",re="data-aci-prop-",qe="data-aci-refresh",oe="custom.";function j(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();if(!(e===""||/[\s/]/.test(e)))return e.startsWith(oe)?e:oe+e}function $e(t){let e;for(let n of Array.from(t.attributes)){if(!n.name.startsWith(re))continue;let r=n.name.slice(re.length);r!==""&&((e!=null?e:e={})[r]=n.value)}return e}function ie(t,e,n){let r=j(t.getAttribute(L));if(r===void 0){n==null||n("capture",{reason:"malformed_declaration",attr:L});return}return{eventName:r,url:e,properties:$e(t)}}function se(t){var e,n;return(n=(e=t.getAttribute(ze))==null?void 0:e.trim().toLowerCase())!=null?n:"click"}function ae(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,g;try{let m=p.target;if((f=m==null?void 0:m.closest)==null?void 0:f.call(m,`[${qe}]`)){n==null||n();return}let l=(g=m==null?void 0:m.closest)==null?void 0:g.call(m,`[${L}]`);if(!l||se(l)!=="click")return;let h=ie(l,i==null?void 0:i.href,o);h&&t(h)}catch(m){o==null||o("capture",{reason:"click_handler_failed",error:String(m)})}});let s=e.intersectionObserver;if(typeof s!="function")return;let a=Array.from(r.querySelectorAll(`[${L}]`)).filter(p=>se(p)==="visible");if(a.length===0)return;let c=new WeakSet,u=new s((p,f)=>{try{for(let g of p){if(!g.isIntersecting||g.intersectionRatio<.5||c.has(g.target))continue;c.add(g.target),f.unobserve(g.target);let m=ie(g.target,i==null?void 0:i.href,o);m&&t(m)}}catch(g){o==null||o("capture",{reason:"visible_handler_failed",error:String(g)})}},{threshold:.5});for(let p of a)u.observe(p)}function W(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function ce(t,e,n){let r=(...s)=>{try{let[a,...c]=s;if(a==="navigation-complete"){let u=c[0];if(!W(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=H(p);if(!f||d.some(g=>g.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=j(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&&!W(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(!W(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 ue="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function Ue(t){globalThis.crypto.getRandomValues(t)}function A(t,e){let n=t!=null?t:Date.now(),r="";for(let c=0;c<10;c++)r=ue[n%32]+r,n=Math.floor(n/32);let o=new Uint8Array(10);(e!=null?e:Ue)(o);let i="",s=0,a=0;for(let c of o)for(s=s<<8|c,a+=8;a>=5;)i+=ue[s>>>a-5&31],a-=5;return r+i}var Xe=60*1024,Ke=100,Ye=5e3,le='{"envelopeId":"',de='","events":[',fe="]}",Je=26,I=le.length+Je+de.length+fe.length,Ze=new TextEncoder,Qe=t=>Ze.encode(t).length,O=class{constructor(e){b(this,"options");b(this,"maxBytes");b(this,"queue",[]);b(this,"queuedBytes",0);b(this,"flushing",!1);b(this,"intervalId");var n;this.options=e,this.maxBytes=(n=e.maxBatchBytes)!=null?n:Xe}get pending(){return this.queue.length}push(e){let n=JSON.stringify(e),r=Qe(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:Ye);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 I+this.queuedBytes+e}drain(){var e,n,r;for(;this.queue.length>0;){let o=this.queue[0];if(I+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=I;for(;this.queue.length>0;){let c=this.queue[0];if(I+c.bytes>this.maxBytes||i.length>=Ke)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:A)();this.options.send(le+a+de+i.join(",")+fe)}}};var G=new TextEncoder,en=2048,nn=32,tn=128,rn=512,on=2147483647,sn=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/,an=/^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g,cn=new Set(["true","all","granted","yes","personalization","personalized"]);function x(t,e=!0){let n=S(t);if(!n)return null;if(e)try{n=decodeURIComponent(n)}catch{}if(n=S(n),!n||G.encode(n).byteLength>en)return null;if(cn.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>on||!Array.isArray(r.p)||r.p.length>nn||!r.p.every(i=>typeof i=="string")||r.p.some(i=>G.encode(i).byteLength>tn)||r.t!==void 0&&r.t!==null&&(typeof r.t!="string"||r.t===""||!un(r.t))||r.src!==void 0&&r.src!==null&&typeof r.src!="string"||typeof r.src=="string"&&G.encode(r.src).byteLength>rn?null:{version:r.v,purposes:r.p,grantedAt:o,source:typeof r.src=="string"?r.src:void 0}}catch{return null}}function z(t){return(t==null?void 0:t.purposes.some(e=>S(e).toLowerCase()==="personalization"))||!1}function S(t){return t.replace(an,"")}function un(t){let e=sn.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>ln(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 ln(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 $="personalization",q="aci_consent",U=1,dn=365*24*60*60;function fn(t,e){var r;let n=`${q}=${t.encoded}; Path=/; Max-Age=${dn}; SameSite=Lax`;((r=e.document.location)==null?void 0:r.protocol)==="https:"&&(n+="; Secure"),e.document.cookie=n}function N(t,e,n){var o,i;let r=pn(t,e,n.now);return r===null?!1:(z(r.snapshot)||(o=n.gapBuffer)==null||o.purge(),fn(r,n),(i=n.onDecision)==null||i.call(n),!0)}function P(t){for(let e of t.cookie.split(";")){let n=S(e);if(n.startsWith(q+"="))return n.slice(q.length+1)}}function pe(t){return t===void 0||t===""?!1:z(x(t,!0))}function me(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:U,p:e});return(r=x(n,!1))==null?void 0:r.purposes}function ge(t){var o;if(t!==void 0&&typeof t!="string")return;let e=typeof t=="string"?S(t):"",r=JSON.stringify({v:U,p:[],src:e===""?"manual":e});return(o=x(r,!1))==null?void 0:o.source}function pn(t,e,n){try{let r=JSON.stringify({v:U,p:t,t:new Date((n!=null?n:Date.now)()).toISOString(),src:e}),o=x(r,!1);return o===null?null:{encoded:encodeURIComponent(r),snapshot:o}}catch{return null}}var mn="data-aci-consent-banner";var gn="data-aci-consent-banner-mount",ve="aci:consent-banner-decided";function vn(t){return P(t)!==void 0}function he(t){return vn(t)?!1:t.querySelector(`[${gn}], [${mn}]`)!==null}var hn=new Set(["c15t","onetrust","cookiebot","trustarc","manual"]);function D(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 be(t){var r;let e=(r=D(t,"data-aci-consent"))==null?void 0:r.toLowerCase(),n=e!==void 0&&hn.has(e)?e:"manual";return{site:D(t,"data-aci-site"),preset:n,categories:D(t,"data-aci-consent-categories"),debug:D(t,"data-aci-debug")==="1"}}function Ee(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=class{constructor(e){b(this,"events",[]);b(this,"now");b(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 ye(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 bn="cmp-",En=/^[a-z0-9._-]+$/,yn={c15t:"measurement,marketing",onetrust:"c0002,c0004",cookiebot:"statistics,marketing",trustarc:"functional,advertising"};function X(t,e){let n=e!=null?e:yn[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(!En.test(o))return null;return r}function Cn(t,e){return e.filter(r=>r in t.categories).some(r=>t.categories[r]===!0)?[$]:[]}function _(t,e,n){var r,o,i,s;try{let a=X(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=Cn(t,a);N(u,bn+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 Ce=250,kn=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(kn/Ce),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,Ce)};i()}function y(t,e){try{e()}catch(n){t==null||t("consent",{reason:"adapter_failed",error:String(n)})}}var _n="c15t";function wn(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 Sn(t,e){return typeof t=="object"&&t!==null?"consents"in t?t.consents:t:e.consents}function ke(t){w(()=>{let e=t.window.c15t;return typeof e=="object"&&e!==null?e:void 0},e=>{y(t.debug,()=>{var r;let n=o=>{let i=wn(o);i&&_(i,_n,t)};n(e.consents),(r=e.onConsentChange)==null||r.call(e,o=>y(t.debug,()=>n(Sn(o,e))))})},t)}var An="cookiebot",xn=["CookiebotOnConsentReady","CookiebotOnAccept","CookiebotOnDecline"];function _e(t){let e=t.Cookiebot;return typeof e=="object"&&e!==null?e:void 0}function Nn(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 we(t){let e=()=>{let r=_e(t.window);if(!r||r.hasResponse!==!0)return;let o=Nn(r.consent);o&&_(o,An,t)},n=t.window;if(typeof n.addEventListener=="function")for(let r of xn)n.addEventListener(r,()=>y(t.debug,e));w(()=>_e(t.window),()=>y(t.debug,e),t)}var Se="onetrust",Pn=/^c\d{4}$/;function Tn(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)&&Pn.test(r)&&(n[r]=!1);return{categories:n}}function Ae(t){let e=t.window,n=()=>{let o=e.OnetrustActiveGroups;if(typeof o!="string")return;let i=X(Se,t.categories);_(Tn(o,i),Se,t)},r=e.OptanonWrapper;e.OptanonWrapper=()=>{if(typeof r=="function")try{r()}catch{}y(t.debug,n)},w(()=>{let o=e.OnetrustActiveGroups;return typeof o=="string"?o:void 0},()=>y(t.debug,n),t)}var Ln="trustarc",In={required:1,functional:2,advertising:3},xe="PrivacyManagerAPI";function Ne(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 On(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(In))n[r]=e>=o;return{categories:n}}function Dn(t){return typeof t=="string"?t.includes(xe):typeof t=="object"&&t!==null&&xe in t}function Rn(t){let e=t.location;return typeof(e==null?void 0:e.hostname)=="string"?e.hostname:void 0}function Pe(t){let e=()=>{let r=Ne(t.window);if(!r)return;let o=On(r("getConsentDecision",Rn(t.window)));o&&_(o,Ln,t)},n=t.window;typeof n.addEventListener=="function"&&n.addEventListener("message",r=>y(t.debug,()=>{Dn(r==null?void 0:r.data)&&e()})),w(()=>Ne(t.window),()=>y(t.debug,e),t)}var B="aci:buf";var Te="aci_m",F=class{constructor(e){b(this,"events");b(this,"storage");b(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(B)}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(B)}catch{this.storage=void 0}return[]}persist(){var n;let e=this.storage;if(e)try{this.events.length===0?e.removeItem(B):e.setItem(B,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 Le(t){for(let e of t.cookie.split(";")){let n=e.trim();if(n.startsWith(Te+"="))return n.slice(Te.length+1)!==""}return!1}function Ie(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 K(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 Bn="rum.link_click";function Oe(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:Bn,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 Fn="rum.page_view";function V(t){let e=t.indexOf("#");return e===-1?t:t.slice(0,e)}function De(t,e,n=()=>{}){let r=V(t.location.href),o=r,i=!1,s=()=>{let c=V(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=V(t.location.href);if(V(c)===d&&(s(),!(!i&&o===d))){i=!1,o=d;for(let p of e)p(u)}}}}function Re(t,e){let n=()=>t({eventName:Fn,url:e.location.href,referrer:e.document.referrer});return n(),n}var Y="/collect";function Be(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(Y,i))return}catch{}if(!o){n==null||n("flush",{reason:"no_transport"});return}try{o(Y,{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 Fe(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:A)(),i=new Blob([`{"envelopeId":"${o}","events":[]}`],{type:"text/plain"});return e(Y,{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 Vn="rum.variation_view",J="data-aci-variation";function Ve(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 g=f.getAttribute(J);g!=null&&(s.has(f)||(s.add(f),t({eventName:Vn,url:i==null?void 0:i.href,properties:{variantKey:g}})))},c=f=>{try{f.hasAttribute(J)&&a(f);for(let g of Array.from(f.querySelectorAll(`[${J}]`)))a(g)}catch(g){r==null||r("capture",{reason:"variation_scan_failed",error:String(g)})}};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(m=>{try{for(let E of m)for(let l=0;l<E.addedNodes.length;l++){let h=E.addedNodes[l];if((h==null?void 0:h.nodeType)!==1)continue;let C=h.element;C&&c(C)}}catch(E){r==null||r("capture",{reason:"variation_observer_failed",error:String(E)})}}).observe(f,{subtree:!0,childList:!0})}catch(f){r==null||r("capture",{reason:"variation_observe_failed",error:String(f)})}}var Hn="rum.web_vital";function He(t,e){var g,m,E;let n=e.PerformanceObserver;if(typeof n!="function")return;let{performance:r,debug:o}=e,i=(m=(g=e.window)==null?void 0:g.location)==null?void 0:m.href,s=e.document,a=new Set,c=(l,h)=>{a.has(l)||(a.add(l),t({eventName:Hn,url:i,properties:{vitalName:l,vitalValue:h}}))};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,h)=>{try{new n(T=>{try{for(let v of T.getEntries())h(v)}catch(v){o==null||o("capture",{reason:`${l}_handler_failed`,error:String(v)})}}).observe({type:l,buffered:!0})}catch(C){o==null||o("capture",{reason:`${l}_observe_failed`,error:String(C)})}};p("largest-contentful-paint",l=>{c("LCP",l.startTime)}),p("first-input",l=>{c("FID",l.startTime)}),p("layout-shift",l=>{var h;l.hadRecentInput||(u+=(h=l.value)!=null?h:0)}),p("event",l=>{var C;let h=(C=l.value)!=null?C:0;h>d&&(d=h)}),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()}),(E=e.window)==null||E.addEventListener("pagehide",f)}var Z={c15t:ke,onetrust:Ae,cookiebot:we,trustarc:Pe};function Mn(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 jn(t){try{return t.sessionStorage}catch{return}}function Wn(t){var o;let e=t!=null?t:typeof window!="undefined"?window:void 0;if(!e||e.__aci_loaded||(e.__aci_loaded=!0,!Mn(e)))return;let n=be(e.document.currentScript),r=Ee(n.debug);try{let i=e.document,s=new F({storage:jn(e),debug:r}),a=()=>{try{return pe(P(i))}catch{return!1}},c=()=>{try{return Le(i)}catch{return!1}},u=()=>{try{return P(i)!==void 0}catch{return!1}},d=n.preset==="manual"?()=>{try{return he(i)}catch{return!1}}:()=>!0,p=new R({debug:r}),f=()=>!u()&&!c()&&d(),g={navigator:e.navigator,fetch:typeof e.fetch=="function"?e.fetch.bind(e):void 0,debug:r},m;m=new O({send:v=>Be(v,g),debug:r,onTick:()=>{ye(p,{decided:u,grants:a,batcher:m,debug:r}),K(s,m,c,r)},timers:{setInterval:(v,k)=>e.setInterval(v,k),clearInterval:v=>e.clearInterval(v)},documentTarget:i,windowTarget:e});let E=te({document:i,window:e,debug:r}),l=v=>{Ie({...ne(v,E),eventId:A(void 0,k=>e.crypto.getRandomValues(k))},{grants:a,marker:c,gapBuffer:s,batcher:m,consentHold:p,consentPending:f})},h=()=>m.flush();i.addEventListener(ve,h),E.start(l);let C=()=>{},T=De(e,[v=>E.rearm(v),()=>C()],()=>E.clear());i.addEventListener("astro:page-load",()=>T.complete({url:e.location.href,assignments:M(i,r)})),ce(e,{navigationComplete:v=>T.complete(v),track:(v,k)=>l({eventName:v,properties:k,url:e.location.href}),consent:({p:v,src:k})=>{let Q=me(v);if(Q===void 0){r("consent",{reason:"malformed_purposes"});return}let ee=ge(k);if(ee===void 0){r("consent",{reason:"malformed_source"});return}N(Q,ee,{document:i,gapBuffer:s,onDecision:h})||r("consent",{reason:"oversized_envelope"})}},r),C=Re(l,e),ae(l,{document:i,intersectionObserver:e.IntersectionObserver,debug:r},()=>{Fe(g).then(v=>{v&&e.location.reload()})}),Oe(l,{document:i,debug:r}),He(l,{performance:e.performance,PerformanceObserver:e.PerformanceObserver,window:e,document:i,debug:r}),Ve(l,{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,onDecision:h,debug:r,scheduler:{setTimeout:(v,k)=>e.setTimeout(v,k),clearTimeout:v=>e.clearTimeout(v)}})),m.start(),e.addEventListener("pagehide",()=>p.discard("unload")),K(s,m,c,r),r("init",{config:n})}catch(i){r("init",{error:String(i)})}}Wn();})();
@@ -1 +1 @@
1
- 71dca62a909ba063d17ff8e8af11d33c755fb4e192e4e469ad212dc72498f4ac
1
+ 077e8018d58378083548af96d4fb122cf37f3658e7d269f514a67e6f91193e3a
@@ -1,5 +1,8 @@
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
8
  /** Manual consent write; reachable under every preset — with no CMP installed the JS API is the only writer. */
@@ -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);
@@ -15,6 +16,24 @@ export function installCommandQueue(win, handlers, debug) {
15
16
  const dispatch = (...args) => {
16
17
  try {
17
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
+ }
18
37
  if (command === "track") {
19
38
  const name = toCustomEventName(rest[0]);
20
39
  if (name === undefined) {
@@ -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,7 +20,7 @@ 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">;
@@ -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;