@gradial/aci 0.1.52-rc.3 → 0.1.52-rc.34-e2e.1
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.
- package/CHANGELOG.md +80 -0
- package/README.md +86 -5
- package/dist/astro/error-page.js +1 -0
- package/dist/astro/index.js +4 -0
- package/dist/astro/page.d.ts +5 -2
- package/dist/astro/page.js +35 -23
- package/dist/astro/preview.js +2 -17
- package/dist/audience-data-models.d.ts +308 -194
- package/dist/audience-data-models.js +314 -51
- package/dist/cli/compile-registry.d.mts +5 -1
- package/dist/cli/compile-registry.mjs +31 -46
- package/dist/cli/mintlify-render.mjs +8 -0
- package/dist/cli/validate-content.d.mts +31 -1
- package/dist/cli/validate-content.mjs +50 -12
- package/dist/collect/aci.js +1 -1
- package/dist/collect/aci.js.sha256 +1 -1
- package/dist/collect/api.d.ts +6 -7
- package/dist/collect/api.js +21 -8
- package/dist/collect/assignments.d.ts +7 -9
- package/dist/collect/assignments.js +23 -32
- package/dist/collect/batcher.d.ts +9 -7
- package/dist/collect/batcher.js +6 -5
- package/dist/collect/consent/envelope.d.ts +7 -1
- package/dist/collect/consent/envelope.js +3 -1
- package/dist/collect/consent/mapping.d.ts +2 -0
- package/dist/collect/consent/mapping.js +1 -0
- package/dist/collect/consenthold.d.ts +38 -0
- package/dist/collect/consenthold.js +82 -0
- package/dist/collect/declarative.js +7 -5
- package/dist/collect/gapbuffer.d.ts +13 -4
- package/dist/collect/gapbuffer.js +21 -10
- package/dist/collect/index.js +67 -20
- package/dist/collect/pageviews.d.ts +11 -11
- package/dist/collect/pageviews.js +27 -22
- package/dist/consent-banner/index.d.ts +17 -0
- package/dist/consent-banner/index.js +23 -0
- package/dist/content/index.d.ts +2 -1
- package/dist/content/index.js +4 -1
- package/dist/content/provider.d.ts +16 -2
- package/dist/content/provider.js +5 -1
- package/dist/content/resolve-slots.d.ts +33 -4
- package/dist/content/resolve-slots.js +127 -19
- package/dist/content/types.d.ts +7 -1
- package/dist/edge/expression-capabilities.v1.d.ts +106 -0
- package/dist/edge/expression-capabilities.v1.js +165 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- package/dist/internal/domain/edge/compose.d.ts +24 -0
- package/dist/internal/domain/edge/compose.js +89 -0
- package/dist/internal/domain/edge/identity.d.ts +5 -0
- package/dist/internal/domain/edge/identity.js +50 -14
- package/dist/internal/domain/edge/index.d.ts +2 -0
- package/dist/internal/domain/edge/index.js +2 -0
- package/dist/internal/domain/edge/mimic_token.d.ts +14 -0
- package/dist/internal/domain/edge/mimic_token.js +125 -0
- package/dist/internal/domain/edge/personalization-core.d.ts +61 -22
- package/dist/internal/domain/edge/personalization-core.js +789 -198
- package/dist/internal/domain/edge/personalization_index.d.ts +17 -0
- package/dist/internal/domain/edge/personalization_index.js +56 -0
- package/dist/internal/domain/edge/record/codec.d.ts +6 -32
- package/dist/internal/domain/edge/record/codec.js +86 -168
- package/dist/internal/domain/edge/resolve.js +76 -39
- package/dist/internal/domain/edge/testdata/flat_only_validator_v1.d.ts +10 -0
- package/dist/internal/domain/edge/testdata/flat_only_validator_v1.js +253 -0
- package/dist/internal/domain/edge/types.d.ts +93 -41
- package/dist/internal/domain/edge/types.js +3 -3
- package/dist/internal/domain/edge/variant_key.d.ts +3 -0
- package/dist/internal/domain/edge/variant_key.js +44 -0
- package/dist/internal/platform/collectionstore/errors.d.ts +24 -0
- package/dist/internal/platform/collectionstore/errors.js +48 -0
- package/dist/mimic/core.d.ts +2 -0
- package/dist/mimic/core.js +31 -0
- package/dist/mintlify/blocks.d.ts +6 -0
- package/dist/mintlify/blocks.js +201 -0
- package/dist/mintlify/config.d.ts +3 -0
- package/dist/mintlify/config.js +77 -0
- package/dist/mintlify/index.d.ts +3 -0
- package/dist/mintlify/index.js +2 -0
- package/dist/mintlify/json.d.ts +8 -0
- package/dist/mintlify/json.js +37 -0
- package/dist/mintlify/materialize.d.ts +14 -0
- package/dist/mintlify/materialize.js +254 -0
- package/dist/mintlify/types.d.ts +74 -0
- package/dist/mintlify/types.js +1 -0
- package/dist/mintlify/validate.d.ts +7 -0
- package/dist/mintlify/validate.js +256 -0
- package/dist/next/assignments-navigation.d.ts +4 -0
- package/dist/next/assignments-navigation.js +18 -0
- package/dist/next/assignments-script.d.ts +3 -2
- package/dist/next/assignments-script.js +5 -5
- package/dist/next/error-pages.d.ts +4 -0
- package/dist/next/error-pages.js +4 -0
- package/dist/next/error-seat-payload.d.ts +2 -1
- package/dist/next/error-seat-payload.js +14 -24
- package/dist/next/error-seat.js +7 -2
- package/dist/next/hosted-page-target.d.ts +7 -0
- package/dist/next/hosted-page-target.js +39 -0
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +3 -1
- package/dist/next/page.d.ts +29 -6
- package/dist/next/page.js +47 -25
- package/dist/next/release-context.d.ts +29 -0
- package/dist/next/release-context.js +55 -0
- package/dist/next/render.d.ts +1 -1
- package/dist/next/render.js +15 -5
- package/dist/next/server.d.ts +8 -0
- package/dist/next/server.js +44 -3
- package/dist/next/vercel-edge-projection-v1.d.ts +0 -9
- package/dist/next/vercel-edge-projection-v1.js +9 -539
- package/dist/preview/core.d.ts +1 -0
- package/dist/preview/core.js +27 -0
- package/dist/react/VideoPlayer.d.ts +3 -3
- package/dist/react/VideoPlayer.js +2 -2
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.js +2 -3
- package/dist/registry.d.ts +4 -2
- package/dist/testing/conformance/checks.d.ts +2 -2
- package/dist/testing/conformance/checks.js +2 -0
- package/dist/testing/conformance/index.d.ts +1 -0
- package/dist/testing/conformance/index.js +1 -0
- package/dist/testing/conformance/next-stubs.d.ts +6 -0
- package/dist/testing/conformance/next-stubs.js +9 -0
- package/dist/testing/conformance/preset.d.ts +3 -2
- package/dist/testing/conformance/preset.js +15 -8
- package/dist/testing/conformance/root-identity.d.ts +31 -0
- package/dist/testing/conformance/root-identity.js +361 -0
- package/dist/testing/conformance/stubs/next-image.d.ts +7 -0
- package/dist/testing/conformance/stubs/next-image.js +5 -0
- package/dist/testing/conformance/stubs/next-link.d.ts +7 -0
- package/dist/testing/conformance/stubs/next-link.js +4 -0
- package/dist/testing/conformance/types.d.ts +5 -2
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +4 -3
- package/dist/types/block-ref.d.ts +2 -0
- package/dist/types/block-ref.js +3 -2
- package/dist/types/component.d.ts +9 -0
- package/dist/types/config.d.ts +0 -1
- package/dist/types/image.d.ts +54 -17
- package/dist/types/image.js +102 -18
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -1
- package/dist/types/media.d.ts +14 -6
- package/dist/types/page.d.ts +0 -1
- package/dist/types/video.d.ts +7 -3
- package/migrations/conformance-registry.md +22 -0
- package/package.json +21 -7
- package/src/cli/compile-registry.mjs +30 -42
- package/src/cli/mintlify-render.mjs +9 -0
- package/src/cli/validate-content.mjs +52 -13
- package/src/types/block-ref.test.ts +60 -0
- package/src/types/block-ref.ts +4 -2
- package/src/types/component.ts +10 -0
- package/src/types/config.ts +0 -1
- package/src/types/image.ts +133 -29
- package/src/types/index.ts +0 -1
- package/src/types/page.ts +0 -1
- package/src/types/video.ts +1 -1
- package/templates/astro/starter-content/src/components/chrome/Footer.astro +5 -3
- package/templates/astro/starter-content/src/components/chrome/Header.astro +5 -3
- package/templates/astro/starter-content/src/components/elements/Button.astro +5 -2
- package/templates/astro/starter-content/src/components/elements/ButtonBlock.astro +5 -3
- package/templates/astro/starter-content/src/components/sections/ContainerSection.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/FeatureCard.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/FeatureGrid.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/HomeHero.astro +5 -3
- package/templates/astro/starter-content/src/components/sections/PersonalizationChoice.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/StatsBar.astro +4 -3
- package/templates/astro/starter-content/src/fixtures/atomicBlocks.ts +7 -6
- package/templates/astro/starter-content/src/fixtures/composition.ts +3 -2
- package/templates/astro/starter-content/src/fixtures/sections.ts +3 -3
- package/templates/astro/starter-content/src/stories/CompositionStoryFrame.astro +7 -2
- package/templates/astro/template/.aci.yaml.tmpl +0 -1
- package/templates/astro/template/package.json.tmpl +5 -5
- package/templates/astro/template/src/layouts/SiteLayout.astro +2 -2
- package/templates/common/.agents/skills/aci/SKILL.md +58 -1
- package/templates/common/.agents/skills/authoring/SKILL.md +203 -43
- package/templates/common/.agents/skills/authoring/references/block-registry.md +19 -3
- package/templates/common/.agents/skills/authoring/references/block-slots.md +3 -0
- package/templates/common/.agents/skills/authoring/references/contracts.md +9 -30
- package/templates/common/.agents/skills/authoring/references/repo-structure.md +5 -4
- package/templates/common/.agents/skills/authoring/references/sdk-server-functions.md +3 -3
- package/templates/common/.agents/skills/dam-delivery/SKILL.md +217 -0
- package/templates/common/.agents/skills/dam-delivery/references/permalink-grammar.md +167 -0
- package/templates/common/.agents/skills/migration/references/canon-migration.md +18 -67
- package/templates/common/.agents/skills/migration/references/selector-map.md +1 -1
- package/templates/common/.content/fragments/navbar/_index.json +24 -0
- package/templates/common/.content/fragments/site-footer/_index.json +61 -0
- package/templates/common/.content/pages/404/_index.json +4 -2
- package/templates/common/.content/pages/{home/_index.json → _index.json} +10 -1
- package/templates/common/.content/pages/error/_index.json +4 -2
- package/templates/common/.content/schemas/site.schema.json +11 -1
- package/templates/common/.content/templates/error.json +24 -0
- package/templates/common/.content/templates/home.json +28 -0
- package/templates/common/.content/templates/site.json +8 -0
- package/templates/common/.content/templates/standard.json +24 -0
- package/templates/common/.nvmrc +1 -1
- package/templates/common/starter-content/.content/.rules-baseline.json +8 -0
- package/templates/common/starter-content/.content/config/site.json +1 -1
- package/templates/common/starter-content/.content/content-rules/no-public-resource-paths.json +6 -0
- package/templates/common/starter-content/.content/dam/README.md +74 -0
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/asset.json +1 -1
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000101}/governance.json +2 -1
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/asset.json +1 -1
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000102}/governance.json +2 -1
- package/templates/common/starter-content/.content/fragments/navbar/_index.json +23 -20
- package/templates/common/starter-content/.content/fragments/site-footer/_index.json +59 -56
- package/templates/common/starter-content/.content/pages/404/_index.json +2 -2
- package/templates/common/starter-content/.content/pages/{home/_index.json → _index.json} +23 -3
- package/templates/common/starter-content/.content/pages/about/_index.json +5 -2
- package/templates/common/starter-content/.content/pages/error/_index.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/button.json +55 -0
- package/templates/common/starter-content/.content/patterns/components/container.json +67 -0
- package/templates/common/starter-content/.content/patterns/components/feature_card.json +30 -0
- package/templates/common/starter-content/.content/patterns/components/feature_grid.json +59 -0
- package/templates/common/starter-content/.content/patterns/components/home_hero.json +151 -0
- package/templates/common/starter-content/.content/patterns/components/personalization_choice.json +42 -0
- package/templates/common/starter-content/.content/patterns/components/site-footer.json +203 -0
- package/templates/common/starter-content/.content/patterns/components/site-navigation.json +115 -0
- package/templates/common/starter-content/.content/patterns/components/stats_bar.json +45 -0
- package/templates/common/starter-content/.content/schemas/site.schema.json +11 -1
- package/templates/nextjs/starter-content/src/components/chrome/Footer.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/chrome/Header.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/elements/Button.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/elements/ButtonBlock.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/sections/ContainerSection.tsx +4 -2
- package/templates/nextjs/starter-content/src/components/sections/FeatureCard.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/sections/FeatureGrid.tsx +4 -2
- package/templates/nextjs/starter-content/src/components/sections/HomeHero.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/sections/PersonalizationChoice.tsx +4 -2
- package/templates/nextjs/starter-content/src/components/sections/StatsBar.tsx +4 -3
- package/templates/nextjs/template/.aci.yaml +9 -0
- package/templates/nextjs/template/.aci.yaml.tmpl +0 -1
- package/templates/nextjs/template/package.json.tmpl +4 -3
- package/templates/nextjs/template/src/app/_components/c15t-bridge.ts +30 -0
- package/templates/nextjs/template/src/app/_components/c15t-consent-ui.tsx +37 -0
- package/templates/nextjs/template/src/app/_components/consent-manager.css +63 -0
- package/templates/nextjs/template/src/app/_components/consent-manager.tsx +76 -0
- package/templates/nextjs/template/src/app/fonts/inter/OFL.txt +93 -0
- package/templates/nextjs/template/src/app/fonts/inter/inter-latin.woff2 +0 -0
- package/templates/nextjs/template/src/app/fonts/space-grotesk/OFL.txt +93 -0
- package/templates/nextjs/template/src/app/fonts/space-grotesk/space-grotesk-latin.woff2 +0 -0
- package/templates/nextjs/template/src/app/layout.tsx +12 -7
- package/templates/nextjs/template/tests/conformance.test.ts.tmpl +1 -0
- package/dist/define-layout.d.ts +0 -6
- package/dist/define-layout.js +0 -14
- package/dist/edge/personalization-core.d.ts +0 -11
- package/dist/edge/personalization-core.js +0 -269
- package/dist/next/collect-route.d.ts +0 -19
- package/dist/next/collect-route.js +0 -459
- package/dist/next/envelope-digest.d.ts +0 -21
- package/dist/next/envelope-digest.js +0 -58
- package/dist/next/middleware.d.ts +0 -40
- package/dist/next/middleware.js +0 -475
- package/dist/next/personalization-host.d.ts +0 -134
- package/dist/next/personalization-host.js +0 -270
- package/dist/next/root-layout.d.ts +0 -4
- package/dist/next/root-layout.js +0 -5
- package/dist/next/vercel-collect-sdk-route.d.ts +0 -27
- package/dist/next/vercel-collect-sdk-route.js +0 -181
- package/dist/next/vercel-personalization.d.ts +0 -4
- package/dist/next/vercel-personalization.js +0 -4
- package/dist/next/vercel-s3-personalization.d.ts +0 -79
- package/dist/next/vercel-s3-personalization.js +0 -570
- package/dist/types/layout.d.ts +0 -24
- package/src/types/layout.ts +0 -29
- package/templates/astro/starter-content/src/render/RenderPage.astro +0 -67
- package/templates/astro/template/src/cms/contracts/layouts/index.ts +0 -18
- package/templates/nextjs/starter-content/src/components/elements/AtomicBlock.tsx +0 -13
- package/templates/nextjs/template/src/cms/contracts/layouts/index.ts +0 -16
- /package/dist/{types/layout.js → cli/mintlify-render.d.mts} +0 -0
- /package/templates/common/.content/overlays/audience/preference-blue/pages/{home/_index.json → _index.json} +0 -0
- /package/templates/common/.content/overlays/audience/preference-red/pages/{home/_index.json → _index.json} +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/editorial.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/versions/v0001.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/editorial.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/versions/v0001.json +0 -0
|
@@ -19,21 +19,25 @@
|
|
|
19
19
|
* Uses the JSON schemas generated by compile-registry — portable, no React/CSS
|
|
20
20
|
* imports needed, same schemas usable by Go backend or other tools.
|
|
21
21
|
*/
|
|
22
|
+
import { realpathSync } from 'node:fs';
|
|
22
23
|
import { readdir, readFile } from 'node:fs/promises';
|
|
23
24
|
import path from 'node:path';
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
import { fileURLToPath } from 'node:url';
|
|
26
|
+
if (isMainModule()) {
|
|
27
|
+
const args = parseArgs(process.argv.slice(2));
|
|
28
|
+
try {
|
|
29
|
+
const result = await validateContent(args);
|
|
30
|
+
console.log(JSON.stringify(result, null, 2));
|
|
31
|
+
if (!result.success)
|
|
32
|
+
process.exitCode = 1;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error(JSON.stringify({
|
|
36
|
+
success: false,
|
|
37
|
+
errors: [{ message: String(error?.message ?? error) }],
|
|
38
|
+
}, null, 2));
|
|
29
39
|
process.exitCode = 1;
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
console.error(JSON.stringify({
|
|
33
|
-
success: false,
|
|
34
|
-
errors: [{ message: String(error?.message ?? error) }],
|
|
35
|
-
}, null, 2));
|
|
36
|
-
process.exitCode = 1;
|
|
40
|
+
}
|
|
37
41
|
}
|
|
38
42
|
// ---------------------------------------------------------------------------
|
|
39
43
|
// Main
|
|
@@ -86,6 +90,22 @@ async function validateContent(options) {
|
|
|
86
90
|
const blocks = collectBlocks(pageData);
|
|
87
91
|
for (const block of blocks) {
|
|
88
92
|
blocksValidated++;
|
|
93
|
+
if (!block || typeof block !== 'object') {
|
|
94
|
+
collector.push({
|
|
95
|
+
page: relativePath,
|
|
96
|
+
blockId: '<unknown>',
|
|
97
|
+
message: 'page region entry must be a component block',
|
|
98
|
+
});
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (block.$type !== 'component') {
|
|
102
|
+
collector.push({
|
|
103
|
+
page: relativePath,
|
|
104
|
+
blockId: block.id ?? '<unknown>',
|
|
105
|
+
path: '$type',
|
|
106
|
+
message: 'block "$type" must be "component"',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
89
109
|
if (!block.component) {
|
|
90
110
|
collector.push({
|
|
91
111
|
page: relativePath,
|
|
@@ -348,6 +368,13 @@ function validateNestedSlots(parentBlock, componentMap, schemaMap, path = 'props
|
|
|
348
368
|
issues.push({ path: nestedPath, message: `${parentBlock.component}: block ref child must be a block` });
|
|
349
369
|
continue;
|
|
350
370
|
}
|
|
371
|
+
if (nestedBlock.$type !== 'component') {
|
|
372
|
+
issues.push({
|
|
373
|
+
path: `${nestedPath}.$type`,
|
|
374
|
+
message: `${parentBlock.component}: block ref child "$type" must be "component"`,
|
|
375
|
+
});
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
351
378
|
if (!componentMap.has(nestedBlock.component)) {
|
|
352
379
|
issues.push({ path: `${nestedPath}.component`, message: `${parentBlock.component}: unknown nested component "${nestedBlock.component}"` });
|
|
353
380
|
continue;
|
|
@@ -424,3 +451,14 @@ function parseArgs(argv) {
|
|
|
424
451
|
}
|
|
425
452
|
return out;
|
|
426
453
|
}
|
|
454
|
+
function isMainModule() {
|
|
455
|
+
if (!process.argv[1])
|
|
456
|
+
return false;
|
|
457
|
+
try {
|
|
458
|
+
return realpathSync(fileURLToPath(import.meta.url)) === realpathSync(path.resolve(process.argv[1]));
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
export { validateContent };
|
package/dist/collect/aci.js
CHANGED
|
@@ -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 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}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(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)),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
|
-
|
|
1
|
+
f9c19e96f671a17edb4cd0a767da4233a1b7d859947092eaf84f4c3386773fd0
|
package/dist/collect/api.d.ts
CHANGED
|
@@ -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;
|
|
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
|
|
21
|
-
* over consent commands (manual mode only).
|
|
20
|
+
* commands are ignored after a debug record.
|
|
22
21
|
*/
|
|
23
|
-
export declare function installCommandQueue(win: AciHost,
|
|
22
|
+
export declare function installCommandQueue(win: AciHost, handlers: CommandHandlers, debug?: DebugFn): void;
|
|
24
23
|
export {};
|
package/dist/collect/api.js
CHANGED
|
@@ -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
|
|
13
|
-
* over consent commands (manual mode only).
|
|
13
|
+
* commands are ignored after a debug record.
|
|
14
14
|
*/
|
|
15
|
-
export function installCommandQueue(win,
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
51
|
-
* context onto an event that does not already carry
|
|
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
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
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
|
|
81
|
-
* context onto an event that does not already carry
|
|
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.
|
|
78
|
+
if (!handle || event.experiments !== undefined)
|
|
86
79
|
return event;
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
80
|
+
const experiments = handle.getActiveAssignments();
|
|
81
|
+
if (experiments.length === 0)
|
|
89
82
|
return event;
|
|
90
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
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). */
|
package/dist/collect/batcher.js
CHANGED
|
@@ -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
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
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
|
|
@@ -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;
|