@sentientui/policy 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ var f=Object.defineProperty;var d=Object.getOwnPropertySymbols;var g=Object.prototype.hasOwnProperty,h=Object.prototype.propertyIsEnumerable;var e=(c,a,b)=>a in c?f(c,a,{enumerable:!0,configurable:!0,writable:!0,value:b}):c[a]=b,i=(c,a)=>{for(var b in a||(a={}))g.call(a,b)&&e(c,b,a[b]);if(d)for(var b of d(a))h.call(a,b)&&e(c,b,a[b]);return c};export{i as a};
package/dist/index.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import { SectionRole } from './taxonomy.cjs';
2
+
1
3
  declare const PERSONAS: readonly ["buyer", "researcher", "deal_seeker", "browser"];
2
4
  type Persona = (typeof PERSONAS)[number];
3
5
  declare const UNKNOWN_PERSONA: "unknown";
@@ -25,8 +27,16 @@ declare const CLUSTER_PRIORITY: Record<Persona, string[]>;
25
27
  * persona (declared/discovered): those have no semantic prior, so they serve
26
28
  * the natural order until the layout bandit has learned rows, the same
27
29
  * cold-start posture 'unknown' gets.
30
+ *
31
+ * With `sectionRoles` (spec 2026-09-04 §1, phase 2d) the ordering projection is
32
+ * `(role, parent)`: structural sections are PINNED at their original index and
33
+ * only converters/persuaders re-rank around them. The pin is not cosmetic —
34
+ * 'navigation' ranks near last in every persona priority, so an unpinned navbar
35
+ * or footer would sort to the bottom of the page, exactly the visible damage a
36
+ * reorder must never do. Callers without role data (the client-local fallback)
37
+ * omit the map and get the pre-2d behaviour unchanged.
28
38
  */
29
- declare function applyClusterHeuristic(sections: string[], sectionTypes: Map<string, string>, persona: string): string[];
39
+ declare function applyClusterHeuristic(sections: string[], sectionTypes: Map<string, string>, persona: string, sectionRoles?: Map<string, SectionRole>): string[];
30
40
  /**
31
41
  * The candidate layout orderings for a page — the distinct section orders
32
42
  * produced by every persona's semantic priority (plus the requesting
@@ -34,7 +44,7 @@ declare function applyClusterHeuristic(sections: string[], sectionTypes: Map<str
34
44
  * "arms" the layout bandit explores. Returned as hash → order so it joins
35
45
  * directly against layout_weights rows keyed by the same hashLayout.
36
46
  */
37
- declare function candidateLayouts(sections: string[], sectionTypes: Map<string, string>, persona: string): Map<string, string[]>;
47
+ declare function candidateLayouts(sections: string[], sectionTypes: Map<string, string>, persona: string, sectionRoles?: Map<string, SectionRole>): Map<string, string[]>;
38
48
 
39
49
  /**
40
50
  * Stable 16-char SHA-256 prefix for a section order array.
@@ -64,8 +74,68 @@ type LearnedLayout = {
64
74
  * @param rand Uniform [0,1) source. Defaults to `Math.random`, which is
65
75
  * NON-DETERMINISTIC. Pass a seeded PRNG when you need a reproducible layout
66
76
  * (tests, replayable decisions) — otherwise the sampled order varies per call.
77
+ * @param sectionRoles Optional role map (phase 2d): structural sections are
78
+ * pinned in place across every candidate; see `applyClusterHeuristic`.
79
+ */
80
+ declare function chooseLayout(sections: string[], sectionTypes: Map<string, string>, persona: string, learned: Map<string, LearnedLayout>, rand?: () => number, sectionRoles?: Map<string, SectionRole>): string[];
81
+
82
+ /**
83
+ * Factored layout value model (spec 2026-09-04 §3a).
84
+ *
85
+ * `layout_weights` gives every distinct order an independent Beta posterior
86
+ * sharing NOTHING with an order that differs by one swap — so more candidate
87
+ * diversity (exactly what the semantic work creates) splits the same thin
88
+ * traffic across more independent posteriors and convergence gets worse, not
89
+ * better. This model replaces one-parameter-per-permutation with
90
+ *
91
+ * V(order | persona) = Σ_p w[parent(section at p), bucket(p)]
92
+ * + δ[persona, parent, bucket]
93
+ *
94
+ * 10 parents × 4 position buckets = 40 global parameters, so every trial
95
+ * teaches every candidate that shares its structure: a conversion under order
96
+ * A updates "pricing above the fold", which transfers to every order that also
97
+ * puts pricing high. δ is the persona deviation, shrunk toward the global cell
98
+ * by the same mean-only-crossing machinery variants use (CONTRACTS §4) —
99
+ * a thin persona collapses to the global model instead of estimating noise.
100
+ *
101
+ * It improves sample efficiency; it does not manufacture signal. With a
102
+ * handful of conversions no model learns a ranking — which is what the
103
+ * feasibility gate exists to say out loud before this one runs.
104
+ */
105
+ /** Position buckets: above-fold / early / mid / late. Coarse on purpose — the
106
+ * bucket count bounds the parameter space, and 4 is the pinned value. */
107
+ declare const LAYOUT_FACTOR_BUCKETS = 4;
108
+ /** Persona key of the pooled global cells. Reserved — never a real persona. */
109
+ declare const GLOBAL_FACTOR_PERSONA = "__global__";
110
+ /** Length-invariant bucket for a section's position in an order. */
111
+ declare function layoutBucketOf(index: number, length: number): number;
112
+ type LayoutFactorCell = {
113
+ persona: string;
114
+ parent: string;
115
+ bucket: number;
116
+ exposures: number;
117
+ conversions: number;
118
+ };
119
+ /** The (parent, bucket) cells one served order contributes to — the write-side
120
+ * projection close-out uses. Sections with no known type count as 'generic'. */
121
+ declare function factorCellsForOrder(order: string[], sectionTypes: Map<string, string>): Array<{
122
+ parent: string;
123
+ bucket: number;
124
+ }>;
125
+ /**
126
+ * Thompson-style selection over the factored model: ONE Beta draw per
127
+ * (parent, bucket) cell — shared across every candidate, so candidates are
128
+ * compared under the same sampled world (a fresh draw per candidate would add
129
+ * pure comparison noise) — then argmax of the summed position values.
130
+ *
131
+ * Persona cells are consulted only when `persona` is known and shrink toward
132
+ * the global cell (mean crosses, sample size never — CONTRACTS §4). Cold
133
+ * start degrades gracefully: empty cells draw from Beta(1,1), which still
134
+ * randomises across candidates, so exploration survives the switch.
135
+ *
136
+ * Falls back to the persona's heuristic prior when there are no candidates.
67
137
  */
68
- declare function chooseLayout(sections: string[], sectionTypes: Map<string, string>, persona: string, learned: Map<string, LearnedLayout>, rand?: () => number): string[];
138
+ declare function chooseLayoutFactored(sections: string[], sectionTypes: Map<string, string>, persona: string, cells: LayoutFactorCell[], rand?: () => number, sectionRoles?: Map<string, SectionRole>): string[];
69
139
 
70
140
  /** Learned Beta(alpha, beta) posterior for one arm. */
71
141
  type ArmPosterior = {
@@ -439,4 +509,4 @@ declare function resolvePersona(input: {
439
509
  */
440
510
  declare function decisionPersona(label: string | null | undefined): string;
441
511
 
442
- export { type ArmPosterior, CLUSTER_PRIORITY, DEFAULT_PERSONA_VOCABULARY, EV_SHRINK_K, type EvArm, LEGACY_PERSONA_MAP, type LearnedLayout, PERSONAS, PERSONA_DISPLAY, PERSONA_KEY_RE, POOL_ALL, type Persona, type PersonaKey, type PersonaResolution, type PersonaVocabularyMember, type PoolCells, type PoolCounts, RESERVED_PERSONA_KEYS, SHRINKAGE_M, type SlotDecl, type SlotResult, UNKNOWN_PERSONA, type ValueCell, type ValueCellRow, WEIGHTS_FALLBACK_PRIOR_PULLS, type WeightsFallbackArm, applyClusterHeuristic, broadestValueCell, candidateLayouts, canonicalArm, canonicalPersona, chooseLayout, confidenceBand, decisionPersona, fnv1a, hashLayout, marginalArmKey, normalizeDeclaredPersona, parseArm, pickDeterministicArm, pickFromWeights, pooledPosterior, posteriorOfCounts, resolvePersona, sampleArm, sampleArmEv, sampleBeta, shrunkAvgValue, shrunkPosterior, slotBaselineArm, slotResultFor, validateSlotDecl, weightCellsFor };
512
+ export { type ArmPosterior, CLUSTER_PRIORITY, DEFAULT_PERSONA_VOCABULARY, EV_SHRINK_K, type EvArm, GLOBAL_FACTOR_PERSONA, LAYOUT_FACTOR_BUCKETS, LEGACY_PERSONA_MAP, type LayoutFactorCell, type LearnedLayout, PERSONAS, PERSONA_DISPLAY, PERSONA_KEY_RE, POOL_ALL, type Persona, type PersonaKey, type PersonaResolution, type PersonaVocabularyMember, type PoolCells, type PoolCounts, RESERVED_PERSONA_KEYS, SHRINKAGE_M, type SlotDecl, type SlotResult, UNKNOWN_PERSONA, type ValueCell, type ValueCellRow, WEIGHTS_FALLBACK_PRIOR_PULLS, type WeightsFallbackArm, applyClusterHeuristic, broadestValueCell, candidateLayouts, canonicalArm, canonicalPersona, chooseLayout, chooseLayoutFactored, confidenceBand, decisionPersona, factorCellsForOrder, fnv1a, hashLayout, layoutBucketOf, marginalArmKey, normalizeDeclaredPersona, parseArm, pickDeterministicArm, pickFromWeights, pooledPosterior, posteriorOfCounts, resolvePersona, sampleArm, sampleArmEv, sampleBeta, shrunkAvgValue, shrunkPosterior, slotBaselineArm, slotResultFor, validateSlotDecl, weightCellsFor };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { SectionRole } from './taxonomy.js';
2
+
1
3
  declare const PERSONAS: readonly ["buyer", "researcher", "deal_seeker", "browser"];
2
4
  type Persona = (typeof PERSONAS)[number];
3
5
  declare const UNKNOWN_PERSONA: "unknown";
@@ -25,8 +27,16 @@ declare const CLUSTER_PRIORITY: Record<Persona, string[]>;
25
27
  * persona (declared/discovered): those have no semantic prior, so they serve
26
28
  * the natural order until the layout bandit has learned rows, the same
27
29
  * cold-start posture 'unknown' gets.
30
+ *
31
+ * With `sectionRoles` (spec 2026-09-04 §1, phase 2d) the ordering projection is
32
+ * `(role, parent)`: structural sections are PINNED at their original index and
33
+ * only converters/persuaders re-rank around them. The pin is not cosmetic —
34
+ * 'navigation' ranks near last in every persona priority, so an unpinned navbar
35
+ * or footer would sort to the bottom of the page, exactly the visible damage a
36
+ * reorder must never do. Callers without role data (the client-local fallback)
37
+ * omit the map and get the pre-2d behaviour unchanged.
28
38
  */
29
- declare function applyClusterHeuristic(sections: string[], sectionTypes: Map<string, string>, persona: string): string[];
39
+ declare function applyClusterHeuristic(sections: string[], sectionTypes: Map<string, string>, persona: string, sectionRoles?: Map<string, SectionRole>): string[];
30
40
  /**
31
41
  * The candidate layout orderings for a page — the distinct section orders
32
42
  * produced by every persona's semantic priority (plus the requesting
@@ -34,7 +44,7 @@ declare function applyClusterHeuristic(sections: string[], sectionTypes: Map<str
34
44
  * "arms" the layout bandit explores. Returned as hash → order so it joins
35
45
  * directly against layout_weights rows keyed by the same hashLayout.
36
46
  */
37
- declare function candidateLayouts(sections: string[], sectionTypes: Map<string, string>, persona: string): Map<string, string[]>;
47
+ declare function candidateLayouts(sections: string[], sectionTypes: Map<string, string>, persona: string, sectionRoles?: Map<string, SectionRole>): Map<string, string[]>;
38
48
 
39
49
  /**
40
50
  * Stable 16-char SHA-256 prefix for a section order array.
@@ -64,8 +74,68 @@ type LearnedLayout = {
64
74
  * @param rand Uniform [0,1) source. Defaults to `Math.random`, which is
65
75
  * NON-DETERMINISTIC. Pass a seeded PRNG when you need a reproducible layout
66
76
  * (tests, replayable decisions) — otherwise the sampled order varies per call.
77
+ * @param sectionRoles Optional role map (phase 2d): structural sections are
78
+ * pinned in place across every candidate; see `applyClusterHeuristic`.
79
+ */
80
+ declare function chooseLayout(sections: string[], sectionTypes: Map<string, string>, persona: string, learned: Map<string, LearnedLayout>, rand?: () => number, sectionRoles?: Map<string, SectionRole>): string[];
81
+
82
+ /**
83
+ * Factored layout value model (spec 2026-09-04 §3a).
84
+ *
85
+ * `layout_weights` gives every distinct order an independent Beta posterior
86
+ * sharing NOTHING with an order that differs by one swap — so more candidate
87
+ * diversity (exactly what the semantic work creates) splits the same thin
88
+ * traffic across more independent posteriors and convergence gets worse, not
89
+ * better. This model replaces one-parameter-per-permutation with
90
+ *
91
+ * V(order | persona) = Σ_p w[parent(section at p), bucket(p)]
92
+ * + δ[persona, parent, bucket]
93
+ *
94
+ * 10 parents × 4 position buckets = 40 global parameters, so every trial
95
+ * teaches every candidate that shares its structure: a conversion under order
96
+ * A updates "pricing above the fold", which transfers to every order that also
97
+ * puts pricing high. δ is the persona deviation, shrunk toward the global cell
98
+ * by the same mean-only-crossing machinery variants use (CONTRACTS §4) —
99
+ * a thin persona collapses to the global model instead of estimating noise.
100
+ *
101
+ * It improves sample efficiency; it does not manufacture signal. With a
102
+ * handful of conversions no model learns a ranking — which is what the
103
+ * feasibility gate exists to say out loud before this one runs.
104
+ */
105
+ /** Position buckets: above-fold / early / mid / late. Coarse on purpose — the
106
+ * bucket count bounds the parameter space, and 4 is the pinned value. */
107
+ declare const LAYOUT_FACTOR_BUCKETS = 4;
108
+ /** Persona key of the pooled global cells. Reserved — never a real persona. */
109
+ declare const GLOBAL_FACTOR_PERSONA = "__global__";
110
+ /** Length-invariant bucket for a section's position in an order. */
111
+ declare function layoutBucketOf(index: number, length: number): number;
112
+ type LayoutFactorCell = {
113
+ persona: string;
114
+ parent: string;
115
+ bucket: number;
116
+ exposures: number;
117
+ conversions: number;
118
+ };
119
+ /** The (parent, bucket) cells one served order contributes to — the write-side
120
+ * projection close-out uses. Sections with no known type count as 'generic'. */
121
+ declare function factorCellsForOrder(order: string[], sectionTypes: Map<string, string>): Array<{
122
+ parent: string;
123
+ bucket: number;
124
+ }>;
125
+ /**
126
+ * Thompson-style selection over the factored model: ONE Beta draw per
127
+ * (parent, bucket) cell — shared across every candidate, so candidates are
128
+ * compared under the same sampled world (a fresh draw per candidate would add
129
+ * pure comparison noise) — then argmax of the summed position values.
130
+ *
131
+ * Persona cells are consulted only when `persona` is known and shrink toward
132
+ * the global cell (mean crosses, sample size never — CONTRACTS §4). Cold
133
+ * start degrades gracefully: empty cells draw from Beta(1,1), which still
134
+ * randomises across candidates, so exploration survives the switch.
135
+ *
136
+ * Falls back to the persona's heuristic prior when there are no candidates.
67
137
  */
68
- declare function chooseLayout(sections: string[], sectionTypes: Map<string, string>, persona: string, learned: Map<string, LearnedLayout>, rand?: () => number): string[];
138
+ declare function chooseLayoutFactored(sections: string[], sectionTypes: Map<string, string>, persona: string, cells: LayoutFactorCell[], rand?: () => number, sectionRoles?: Map<string, SectionRole>): string[];
69
139
 
70
140
  /** Learned Beta(alpha, beta) posterior for one arm. */
71
141
  type ArmPosterior = {
@@ -439,4 +509,4 @@ declare function resolvePersona(input: {
439
509
  */
440
510
  declare function decisionPersona(label: string | null | undefined): string;
441
511
 
442
- export { type ArmPosterior, CLUSTER_PRIORITY, DEFAULT_PERSONA_VOCABULARY, EV_SHRINK_K, type EvArm, LEGACY_PERSONA_MAP, type LearnedLayout, PERSONAS, PERSONA_DISPLAY, PERSONA_KEY_RE, POOL_ALL, type Persona, type PersonaKey, type PersonaResolution, type PersonaVocabularyMember, type PoolCells, type PoolCounts, RESERVED_PERSONA_KEYS, SHRINKAGE_M, type SlotDecl, type SlotResult, UNKNOWN_PERSONA, type ValueCell, type ValueCellRow, WEIGHTS_FALLBACK_PRIOR_PULLS, type WeightsFallbackArm, applyClusterHeuristic, broadestValueCell, candidateLayouts, canonicalArm, canonicalPersona, chooseLayout, confidenceBand, decisionPersona, fnv1a, hashLayout, marginalArmKey, normalizeDeclaredPersona, parseArm, pickDeterministicArm, pickFromWeights, pooledPosterior, posteriorOfCounts, resolvePersona, sampleArm, sampleArmEv, sampleBeta, shrunkAvgValue, shrunkPosterior, slotBaselineArm, slotResultFor, validateSlotDecl, weightCellsFor };
512
+ export { type ArmPosterior, CLUSTER_PRIORITY, DEFAULT_PERSONA_VOCABULARY, EV_SHRINK_K, type EvArm, GLOBAL_FACTOR_PERSONA, LAYOUT_FACTOR_BUCKETS, LEGACY_PERSONA_MAP, type LayoutFactorCell, type LearnedLayout, PERSONAS, PERSONA_DISPLAY, PERSONA_KEY_RE, POOL_ALL, type Persona, type PersonaKey, type PersonaResolution, type PersonaVocabularyMember, type PoolCells, type PoolCounts, RESERVED_PERSONA_KEYS, SHRINKAGE_M, type SlotDecl, type SlotResult, UNKNOWN_PERSONA, type ValueCell, type ValueCellRow, WEIGHTS_FALLBACK_PRIOR_PULLS, type WeightsFallbackArm, applyClusterHeuristic, broadestValueCell, candidateLayouts, canonicalArm, canonicalPersona, chooseLayout, chooseLayoutFactored, confidenceBand, decisionPersona, factorCellsForOrder, fnv1a, hashLayout, layoutBucketOf, marginalArmKey, normalizeDeclaredPersona, parseArm, pickDeterministicArm, pickFromWeights, pooledPosterior, posteriorOfCounts, resolvePersona, sampleArm, sampleArmEv, sampleBeta, shrunkAvgValue, shrunkPosterior, slotBaselineArm, slotResultFor, validateSlotDecl, weightCellsFor };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var L=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames,T=Object.getOwnPropertySymbols;var X=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var Z=(e,r,n)=>r in e?L(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,$=(e,r)=>{for(var n in r||(r={}))X.call(r,n)&&Z(e,n,r[n]);if(T)for(var n of T(r))be.call(r,n)&&Z(e,n,r[n]);return e};var ge=(e,r)=>{for(var n in r)L(e,n,{get:r[n],enumerable:!0})},de=(e,r,n,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of pe(r))!X.call(e,s)&&s!==n&&L(e,s,{get:()=>r[s],enumerable:!(t=me(r,s))||t.enumerable});return e};var xe=e=>de(L({},"__esModule",{value:!0}),e);var Ke={};ge(Ke,{CLUSTER_PRIORITY:()=>Q,DEFAULT_PERSONA_VOCABULARY:()=>ue,EV_SHRINK_K:()=>oe,LEGACY_PERSONA_MAP:()=>M,PERSONAS:()=>R,PERSONA_DISPLAY:()=>H,PERSONA_KEY_RE:()=>ae,POOL_ALL:()=>g,RESERVED_PERSONA_KEYS:()=>ie,SHRINKAGE_M:()=>re,UNKNOWN_PERSONA:()=>y,WEIGHTS_FALLBACK_PRIOR_PULLS:()=>ne,applyClusterHeuristic:()=>N,broadestValueCell:()=>_e,candidateLayouts:()=>z,canonicalArm:()=>Y,canonicalPersona:()=>O,chooseLayout:()=>Pe,confidenceBand:()=>Ee,decisionPersona:()=>De,fnv1a:()=>te,hashLayout:()=>j,marginalArmKey:()=>Ae,normalizeDeclaredPersona:()=>Me,parseArm:()=>F,pickDeterministicArm:()=>we,pickFromWeights:()=>Re,pooledPosterior:()=>Se,posteriorOfCounts:()=>C,resolvePersona:()=>Ie,sampleArm:()=>G,sampleArmEv:()=>Le,sampleBeta:()=>S,shrunkAvgValue:()=>se,shrunkPosterior:()=>_,slotBaselineArm:()=>ee,slotResultFor:()=>ve,validateSlotDecl:()=>ke,weightCellsFor:()=>Ce});module.exports=xe(Ke);var R=["buyer","researcher","deal_seeker","browser"],y="unknown",H={buyer:"Buyer",researcher:"Researcher",deal_seeker:"Deal seeker",browser:"Browser",unknown:"Unknown"},M={buyers:"buyer",researchers:"researcher","deal-seekers":"deal_seeker",browsers:"browser",buyer:"buyer",researcher:"researcher",deal_seeker:"deal_seeker",browser:"browser"};function O(e){var n;if(e==null)return y;let r=e.trim().toLowerCase();return(n=M[r])!=null?n:y}var he=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function d(e,r){return e>>>r|e<<32-r}function J(e){return(e>>>0).toString(16).padStart(8,"0")}function ye(e){let r=new TextEncoder().encode(e),n=r.length,t=n*8,s=(n+8>>6)+1<<6,o=new Uint8Array(s);o.set(r),o[n]=128;let a=new DataView(o.buffer);a.setUint32(s-8,Math.floor(t/4294967296),!1),a.setUint32(s-4,t>>>0,!1);let i=1779033703,u=3144134277,f=1013904242,c=2773480762,b=1359893119,m=2600822924,P=528734635,A=1541459225,p=new Uint32Array(64);for(let D=0;D<s;D+=64){for(let l=0;l<16;l++)p[l]=a.getUint32(D+l*4,!1);for(let l=16;l<64;l++){let U=d(p[l-15],7)^d(p[l-15],18)^p[l-15]>>>3,q=d(p[l-2],17)^d(p[l-2],19)^p[l-2]>>>10;p[l]=p[l-16]+U+p[l-7]+q>>>0}let x=i,k=u,v=f,K=c,h=b,w=m,E=P,V=A;for(let l=0;l<64;l++){let U=d(h,6)^d(h,11)^d(h,25),q=h&w^~h&E,W=V+U+q+he[l]+p[l]>>>0,le=d(x,2)^d(x,13)^d(x,22),ce=x&k^x&v^k&v,fe=le+ce>>>0;V=E,E=w,w=h,h=K+W>>>0,K=v,v=k,k=x,x=W+fe>>>0}i=i+x>>>0,u=u+k>>>0,f=f+v>>>0,c=c+K>>>0,b=b+h>>>0,m=m+w>>>0,P=P+E>>>0,A=A+V>>>0}return J(i)+J(u)}function j(e){return ye(e.join("|"))}var Q={buyer:["pricing","cta","hero","comparison","social_proof","trust","features","faq","navigation","generic"],researcher:["features","comparison","faq","hero","trust","social_proof","pricing","cta","navigation","generic"],deal_seeker:["pricing","comparison","social_proof","trust","cta","hero","features","faq","navigation","generic"],browser:["hero","features","social_proof","pricing","cta","trust","faq","comparison","navigation","generic"]};function N(e,r,n){let t=Q[n];if(!t)return e;let s=t.indexOf("generic"),o=a=>{let i=t.indexOf(a);return i===-1?s:i};return[...e].sort((a,i)=>{var c,b;let u=(c=r.get(a))!=null?c:"generic",f=(b=r.get(i))!=null?b:"generic";return o(u)-o(f)})}function z(e,r,n){let t=new Map;for(let s of[...R,n]){let o=N(e,r,s);t.set(j(o),o)}return t}function B(e,r){if(e<1)return B(1+e,r)*Math.pow(Math.max(1e-15,r()),1/e);let n=e-1/3,t=1/Math.sqrt(9*n);for(;;){let s,o;do{let i=Math.max(1e-15,r()),u=r();s=Math.sqrt(-2*Math.log(i))*Math.cos(2*Math.PI*u),o=1+t*s}while(o<=0);o=o*o*o;let a=r();if(a<1-.0331*s*s*s*s||Math.log(a)<.5*s*s+n*(1-o+Math.log(o)))return n*o}}function S(e,r,n=Math.random){let t=B(e,n),s=B(r,n),o=t+s;return o<=0?e/(e+r):t/o}function G(e,r=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let n=e[0],t=S(n.alpha,n.beta,r);for(let s=1;s<e.length;s++){let o=e[s],a=S(o.alpha,o.beta,r);a>t&&(n=o,t=a)}return n.arm}function Pe(e,r,n,t,s=Math.random){var f,c;let o=z(e,r,n),a=[];for(let b of o.keys()){let m=t.get(b);a.push({arm:b,alpha:(f=m==null?void 0:m.alpha)!=null?f:1,beta:(c=m==null?void 0:m.beta)!=null?c:1})}let i=G(a,s),u=i?o.get(i):void 0;return u!=null?u:N(e,r,n)}function Y(e){return Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("|")}function F(e){if(e.length===0)return null;let r={};for(let n of e.split("|")){let t=n.indexOf("=");if(t<=0||t!==n.lastIndexOf("=")||t===n.length-1)return null;let s=n.slice(0,t);if(s in r)return null;r[s]=n.slice(t+1)}return r}function Ae(e,r){return`${e}=${r}`}function ee(e){var n,t,s;if(e.arms)return typeof e.baseline=="string"?e.baseline:(n=e.arms[0])!=null?n:"";if(e.baseline!==void 0&&typeof e.baseline=="object")return Y(e.baseline);if(typeof e.baseline=="string")return e.baseline;let r={};for(let[o,a]of Object.entries((t=e.dims)!=null?t:{}))r[o]=(s=a[0])!=null?s:"";return Y(r)}function ke(e){let r=Array.isArray(e.arms),n=e.dims!=null;if(r&&n)return{ok:!1,reason:"declare exactly one of arms or dims (got both)"};if(!r&&!n)return{ok:!1,reason:"declare exactly one of arms or dims (got neither)"};if(r){let o=e.arms;if(o.length<2)return{ok:!1,reason:"arms requires at least 2 entries"};if(o.length>12)return{ok:!1,reason:"arms allows at most 12 entries"};if(new Set(o).size!==o.length)return{ok:!1,reason:"arms must be unique"};if(o.some(a=>a.includes("=")))return{ok:!1,reason:"enumerated arm ids may not contain '=' (reserved for dims encoding)"};if(e.baseline!==void 0){if(typeof e.baseline!="string")return{ok:!1,reason:"baseline for an arms slot must be a string"};if(!o.includes(e.baseline))return{ok:!1,reason:"baseline must be one of the declared arms"}}return{ok:!0}}let t=Object.entries(e.dims);if(t.length<1)return{ok:!1,reason:"dims requires at least 1 dimension"};if(t.length>4)return{ok:!1,reason:"dims allows at most 4 dimensions"};let s=1;for(let[o,a]of t){if(a.length<2)return{ok:!1,reason:`dim "${o}" requires at least 2 values`};if(a.length>6)return{ok:!1,reason:`dim "${o}" allows at most 6 values`};if(new Set(a).size!==a.length)return{ok:!1,reason:`dim "${o}" has duplicate values`};s*=a.length}if(s>64)return{ok:!1,reason:`declared space of ${s} combinations exceeds the 64 maximum`};if(e.baseline!==void 0){if(typeof e.baseline=="string")return{ok:!1,reason:"baseline for a dims slot must be a per-dim record"};let o=e.baseline,a=t.map(([u])=>u).sort(),i=Object.keys(o).sort();if(a.join(" ")!==i.join(" "))return{ok:!1,reason:"baseline must set every declared dim exactly once"};for(let[u,f]of t)if(!f.includes(o[u]))return{ok:!1,reason:`baseline value for dim "${u}" is not declared`}}return{ok:!0}}function ve(e,r){var n,t;return e.dims!=null?(t=(n=F(r))!=null?n:F(ee(e)))!=null?t:{}:r}var re=20;function _(e,r,n=20){let t=r.alpha+r.beta;if(t<=0||n<=0)return{alpha:e.alpha,beta:e.beta};let s=r.alpha/t,o=n*t/(t+n);return{alpha:e.alpha+o*s,beta:e.beta+o*(1-s)}}var ne=5;function Re(e,r){var t,s;let n=null;for(let o of e){if(!r.includes(o.variantId))continue;let a=(t=o.pulls)!=null?t:0,i=a>0?a*o.avgReward/(a+ne):0;(!n||i>n.score)&&(n={variantId:o.variantId,score:i})}return(s=n==null?void 0:n.variantId)!=null?s:null}var g="__all__",I={exposures:0,conversions:0};function C(e){return{alpha:e.conversions+1,beta:Math.max(0,e.exposures-e.conversions)+1}}function Se(e,r,n=20){var m,P,A,p;let t=(m=e.segment)!=null?m:I,s=(P=e.global)!=null?P:I,o=C(s),a=_(C(t),o,n);if(!r)return a;let i=(A=e.persona)!=null?A:I,u=(p=e.child)!=null?p:I,f=_(C(i),o,n),c=(t.exposures+1)/(t.exposures+i.exposures+2),b={alpha:c*a.alpha+(1-c)*f.alpha,beta:c*a.beta+(1-c)*f.beta};return _(C(u),b,n)}function _e(e){var t,s;let r=null,n=-1;for(let o of e){let a=o.segment===g,i=o.persona===g,u=a&&i?3:a||i?2:1;u>n&&(n=u,r=o)}return{valueSum:(t=r==null?void 0:r.valueSum)!=null?t:0,valueCount:(s=r==null?void 0:r.valueCount)!=null?s:0}}function Ce(e,r){return r==="unknown"||r===g||r===""?[{segment:e,persona:g},{segment:g,persona:g}]:[{segment:e,persona:r},{segment:e,persona:g},{segment:g,persona:r},{segment:g,persona:g}]}function te(e){let r=2166136261;for(let n=0;n<e.length;n++)r^=e.charCodeAt(n),r=r+((r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24))>>>0;return r}function we(e,r,n){if(n.length===0)throw new Error("pickDeterministicArm requires at least one arm");let t=[...n].sort();return t[te(`${e}:${r}`)%t.length]}function Ee(e){return e>=.3?e<.7?"medium":"high":"low"}var oe=20;function se(e,r,n=oe){let t=e.valueCount>0?e.valueSum/e.valueCount:0;if(r<=0)return t;if(e.valueCount<=0)return r;let s=e.valueCount/(e.valueCount+n);return s*t+(1-s)*r}function Le(e,r,n=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let t=null,s=-1/0;for(let o of e){let a=S(o.alpha,o.beta,n)*se(o,r);a>s&&(t=o,s=a)}return t.arm}var ae=/^[a-z0-9][a-z0-9_-]{0,31}$/;function Me(e){if(typeof e!="string")return null;let r=e.trim().toLowerCase();return r&&ae.test(r)?r:null}var ie=["unknown","__all__","buyers","researchers","deal-seekers","browsers"],ue=R.map(e=>({key:e,displayName:H[e]})),Oe=64;function Ne(e){var n;let r=new Map;for(let t of e)if(t.status!=="retired"){r.set(t.key,t.key);for(let s of(n=t.aliases)!=null?n:[])ie.includes(s)||r.set(s,t.key)}return r}function Ie(e,r=ue){var i,u,f;let n=Ne(r),t=(i=e.inferredConfidence)!=null?i:0,s,o=(f=(u=e.declared)==null?void 0:u.trim().toLowerCase())!=null?f:"";if(o!==""){let c=n.get(o),b=c===void 0?n.get(O(o)):void 0,m=c!=null?c:b;if(m!==void 0)return{persona:m,source:"declared",confidence:1};s=o.slice(0,Oe)}let a=O(e.clusterLabel);return a!==y&&n.has(a)?$({persona:n.get(a),source:"inferred",confidence:t},s!==void 0&&{unrecognizedDeclared:s}):$({persona:y,source:"none",confidence:t},s!==void 0&&{unrecognizedDeclared:s})}function De(e){var n;if(e==null)return y;let r=e.trim().toLowerCase();return r===""?y:(n=M[r])!=null?n:r}0&&(module.exports={CLUSTER_PRIORITY,DEFAULT_PERSONA_VOCABULARY,EV_SHRINK_K,LEGACY_PERSONA_MAP,PERSONAS,PERSONA_DISPLAY,PERSONA_KEY_RE,POOL_ALL,RESERVED_PERSONA_KEYS,SHRINKAGE_M,UNKNOWN_PERSONA,WEIGHTS_FALLBACK_PRIOR_PULLS,applyClusterHeuristic,broadestValueCell,candidateLayouts,canonicalArm,canonicalPersona,chooseLayout,confidenceBand,decisionPersona,fnv1a,hashLayout,marginalArmKey,normalizeDeclaredPersona,parseArm,pickDeterministicArm,pickFromWeights,pooledPosterior,posteriorOfCounts,resolvePersona,sampleArm,sampleArmEv,sampleBeta,shrunkAvgValue,shrunkPosterior,slotBaselineArm,slotResultFor,validateSlotDecl,weightCellsFor});
1
+ "use strict";var F=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var xe=Object.getOwnPropertyNames,J=Object.getOwnPropertySymbols;var ee=Object.prototype.hasOwnProperty,he=Object.prototype.propertyIsEnumerable;var Q=(e,r,t)=>r in e?F(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,B=(e,r)=>{for(var t in r||(r={}))ee.call(r,t)&&Q(e,t,r[t]);if(J)for(var t of J(r))he.call(r,t)&&Q(e,t,r[t]);return e};var ye=(e,r)=>{for(var t in r)F(e,t,{get:r[t],enumerable:!0})},ve=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of xe(r))!ee.call(e,o)&&o!==t&&F(e,o,{get:()=>r[o],enumerable:!(n=de(r,o))||n.enumerable});return e};var Pe=e=>ve(F({},"__esModule",{value:!0}),e);var qe={};ye(qe,{CLUSTER_PRIORITY:()=>te,DEFAULT_PERSONA_VOCABULARY:()=>me,EV_SHRINK_K:()=>ue,GLOBAL_FACTOR_PERSONA:()=>se,LAYOUT_FACTOR_BUCKETS:()=>Y,LEGACY_PERSONA_MAP:()=>U,PERSONAS:()=>K,PERSONA_DISPLAY:()=>q,PERSONA_KEY_RE:()=>ce,POOL_ALL:()=>P,RESERVED_PERSONA_KEYS:()=>fe,SHRINKAGE_M:()=>ne,UNKNOWN_PERSONA:()=>R,WEIGHTS_FALLBACK_PRIOR_PULLS:()=>oe,applyClusterHeuristic:()=>L,broadestValueCell:()=>_e,candidateLayouts:()=>D,canonicalArm:()=>T,canonicalPersona:()=>V,chooseLayout:()=>Se,chooseLayoutFactored:()=>Me,confidenceBand:()=>Ke,decisionPersona:()=>Be,factorCellsForOrder:()=>we,fnv1a:()=>ie,hashLayout:()=>H,layoutBucketOf:()=>W,marginalArmKey:()=>Ee,normalizeDeclaredPersona:()=>Fe,parseArm:()=>Z,pickDeterministicArm:()=>Ie,pickFromWeights:()=>Re,pooledPosterior:()=>Ce,posteriorOfCounts:()=>A,resolvePersona:()=>$e,sampleArm:()=>z,sampleArmEv:()=>De,sampleBeta:()=>w,shrunkAvgValue:()=>le,shrunkPosterior:()=>C,slotBaselineArm:()=>ae,slotResultFor:()=>Ne,validateSlotDecl:()=>Oe,weightCellsFor:()=>Le});module.exports=Pe(qe);var K=["buyer","researcher","deal_seeker","browser"],R="unknown",q={buyer:"Buyer",researcher:"Researcher",deal_seeker:"Deal seeker",browser:"Browser",unknown:"Unknown"},U={buyers:"buyer",researchers:"researcher","deal-seekers":"deal_seeker",browsers:"browser",buyer:"buyer",researcher:"researcher",deal_seeker:"deal_seeker",browser:"browser"};function V(e){var t;if(e==null)return R;let r=e.trim().toLowerCase();return(t=U[r])!=null?t:R}var ke=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function k(e,r){return e>>>r|e<<32-r}function re(e){return(e>>>0).toString(16).padStart(8,"0")}function Ae(e){let r=new TextEncoder().encode(e),t=r.length,n=t*8,o=(t+8>>6)+1<<6,s=new Uint8Array(o);s.set(r),s[t]=128;let a=new DataView(s.buffer);a.setUint32(o-8,Math.floor(n/4294967296),!1),a.setUint32(o-4,n>>>0,!1);let i=1779033703,u=3144134277,l=1013904242,f=2773480762,h=1359893119,g=2600822924,p=528734635,y=1541459225,b=new Uint32Array(64);for(let M=0;M<o;M+=64){for(let m=0;m<16;m++)b[m]=a.getUint32(M+m*4,!1);for(let m=16;m<64;m++){let N=k(b[m-15],7)^k(b[m-15],18)^b[m-15]>>>3,I=k(b[m-2],17)^k(b[m-2],19)^b[m-2]>>>10;b[m]=b[m-16]+N+b[m-7]+I>>>0}let c=i,v=u,d=l,E=f,x=h,_=g,S=p,O=y;for(let m=0;m<64;m++){let N=k(x,6)^k(x,11)^k(x,25),I=x&_^~x&S,X=O+N+I+ke[m]+b[m]>>>0,pe=k(c,2)^k(c,13)^k(c,22),ge=c&v^c&d^v&d,be=pe+ge>>>0;O=S,S=_,_=x,x=E+X>>>0,E=d,d=v,v=c,c=X+be>>>0}i=i+c>>>0,u=u+v>>>0,l=l+d>>>0,f=f+E>>>0,h=h+x>>>0,g=g+_>>>0,p=p+S>>>0,y=y+O>>>0}return re(i)+re(u)}function H(e){return Ae(e.join("|"))}var te={buyer:["pricing","cta","hero","comparison","social_proof","trust","features","faq","navigation","generic"],researcher:["features","comparison","faq","hero","trust","social_proof","pricing","cta","navigation","generic"],deal_seeker:["pricing","comparison","social_proof","trust","cta","hero","features","faq","navigation","generic"],browser:["hero","features","social_proof","pricing","cta","trust","faq","comparison","navigation","generic"]};function L(e,r,t,n){let o=te[t];if(!o)return e;let s=o.indexOf("generic"),a=l=>{let f=o.indexOf(l);return f===-1?s:f},i=n?e.filter(l=>n.get(l)!=="structural"):[...e];if(i.sort((l,f)=>{var p,y;let h=(p=r.get(l))!=null?p:"generic",g=(y=r.get(f))!=null?y:"generic";return a(h)-a(g)}),!n)return i;let u=0;return e.map(l=>n.get(l)==="structural"?l:i[u++])}function D(e,r,t,n){let o=new Map;for(let s of[...K,t]){let a=L(e,r,s,n);o.set(H(a),a)}return o}function j(e,r){if(e<1)return j(1+e,r)*Math.pow(Math.max(1e-15,r()),1/e);let t=e-1/3,n=1/Math.sqrt(9*t);for(;;){let o,s;do{let i=Math.max(1e-15,r()),u=r();o=Math.sqrt(-2*Math.log(i))*Math.cos(2*Math.PI*u),s=1+n*o}while(s<=0);s=s*s*s;let a=r();if(a<1-.0331*o*o*o*o||Math.log(a)<.5*o*o+t*(1-s+Math.log(s)))return t*s}}function w(e,r,t=Math.random){let n=j(e,t),o=j(r,t),s=n+o;return s<=0?e/(e+r):n/s}function z(e,r=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let t=e[0],n=w(t.alpha,t.beta,r);for(let o=1;o<e.length;o++){let s=e[o],a=w(s.alpha,s.beta,r);a>n&&(t=s,n=a)}return t.arm}function Se(e,r,t,n,o=Math.random,s){var f,h;let a=D(e,r,t,s),i=[];for(let g of a.keys()){let p=n.get(g);i.push({arm:g,alpha:(f=p==null?void 0:p.alpha)!=null?f:1,beta:(h=p==null?void 0:p.beta)!=null?h:1})}let u=z(i,o),l=u?a.get(u):void 0;return l!=null?l:L(e,r,t,s)}var ne=20;function C(e,r,t=20){let n=r.alpha+r.beta;if(n<=0||t<=0)return{alpha:e.alpha,beta:e.beta};let o=r.alpha/n,s=t*n/(n+t);return{alpha:e.alpha+s*o,beta:e.beta+s*(1-o)}}var oe=5;function Re(e,r){var n,o;let t=null;for(let s of e){if(!r.includes(s.variantId))continue;let a=(n=s.pulls)!=null?n:0,i=a>0?a*s.avgReward/(a+oe):0;(!t||i>t.score)&&(t={variantId:s.variantId,score:i})}return(o=t==null?void 0:t.variantId)!=null?o:null}var P="__all__",$={exposures:0,conversions:0};function A(e){return{alpha:e.conversions+1,beta:Math.max(0,e.exposures-e.conversions)+1}}function Ce(e,r,t=20){var g,p,y,b;let n=(g=e.segment)!=null?g:$,o=(p=e.global)!=null?p:$,s=A(o),a=C(A(n),s,t);if(!r)return a;let i=(y=e.persona)!=null?y:$,u=(b=e.child)!=null?b:$,l=C(A(i),s,t),f=(n.exposures+1)/(n.exposures+i.exposures+2),h={alpha:f*a.alpha+(1-f)*l.alpha,beta:f*a.beta+(1-f)*l.beta};return C(A(u),h,t)}function _e(e){var n,o;let r=null,t=-1;for(let s of e){let a=s.segment===P,i=s.persona===P,u=a&&i?3:a||i?2:1;u>t&&(t=u,r=s)}return{valueSum:(n=r==null?void 0:r.valueSum)!=null?n:0,valueCount:(o=r==null?void 0:r.valueCount)!=null?o:0}}function Le(e,r){return r==="unknown"||r===P||r===""?[{segment:e,persona:P},{segment:P,persona:P}]:[{segment:e,persona:r},{segment:e,persona:P},{segment:P,persona:r},{segment:P,persona:P}]}var Y=4,se="__global__";function W(e,r){return r<=0?0:Math.min(Y-1,Math.floor(e*Y/r))}function we(e,r){return e.map((t,n)=>{var o;return{parent:(o=r.get(t))!=null?o:"generic",bucket:W(n,e.length)}})}var G=(e,r)=>`${e}#${r}`;function Me(e,r,t,n,o=Math.random,s){var M;let a=D(e,r,t,s);if(a.size===0)return L(e,r,t,s);let i=new Map,u=new Map,l=0,f=0;for(let c of n)c.persona===se?(i.set(G(c.parent,c.bucket),c),l+=c.exposures,f+=c.conversions):c.persona===t&&u.set(G(c.parent,c.bucket),c);let h=A({exposures:l,conversions:f}),g=new Map,p=(c,v)=>{var N,I;let d=G(c,v),E=g.get(d);if(E!==void 0)return E;let x=i.get(d),_=C(A({exposures:(N=x==null?void 0:x.exposures)!=null?N:0,conversions:(I=x==null?void 0:x.conversions)!=null?I:0}),h),S=u.get(d),O=S?C(A({exposures:S.exposures,conversions:S.conversions}),_):_,m=w(O.alpha,O.beta,o);return g.set(d,m),m},y=null,b=-1/0;for(let c of a.values()){let v=0;for(let d=0;d<c.length;d++)v+=p((M=r.get(c[d]))!=null?M:"generic",W(d,c.length));v>b&&(b=v,y=c)}return y!=null?y:L(e,r,t,s)}function T(e){return Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("|")}function Z(e){if(e.length===0)return null;let r={};for(let t of e.split("|")){let n=t.indexOf("=");if(n<=0||n!==t.lastIndexOf("=")||n===t.length-1)return null;let o=t.slice(0,n);if(o in r)return null;r[o]=t.slice(n+1)}return r}function Ee(e,r){return`${e}=${r}`}function ae(e){var t,n,o;if(e.arms)return typeof e.baseline=="string"?e.baseline:(t=e.arms[0])!=null?t:"";if(e.baseline!==void 0&&typeof e.baseline=="object")return T(e.baseline);if(typeof e.baseline=="string")return e.baseline;let r={};for(let[s,a]of Object.entries((n=e.dims)!=null?n:{}))r[s]=(o=a[0])!=null?o:"";return T(r)}function Oe(e){let r=Array.isArray(e.arms),t=e.dims!=null;if(r&&t)return{ok:!1,reason:"declare exactly one of arms or dims (got both)"};if(!r&&!t)return{ok:!1,reason:"declare exactly one of arms or dims (got neither)"};if(r){let s=e.arms;if(s.length<2)return{ok:!1,reason:"arms requires at least 2 entries"};if(s.length>12)return{ok:!1,reason:"arms allows at most 12 entries"};if(new Set(s).size!==s.length)return{ok:!1,reason:"arms must be unique"};if(s.some(a=>a.includes("=")))return{ok:!1,reason:"enumerated arm ids may not contain '=' (reserved for dims encoding)"};if(e.baseline!==void 0){if(typeof e.baseline!="string")return{ok:!1,reason:"baseline for an arms slot must be a string"};if(!s.includes(e.baseline))return{ok:!1,reason:"baseline must be one of the declared arms"}}return{ok:!0}}let n=Object.entries(e.dims);if(n.length<1)return{ok:!1,reason:"dims requires at least 1 dimension"};if(n.length>4)return{ok:!1,reason:"dims allows at most 4 dimensions"};let o=1;for(let[s,a]of n){if(a.length<2)return{ok:!1,reason:`dim "${s}" requires at least 2 values`};if(a.length>6)return{ok:!1,reason:`dim "${s}" allows at most 6 values`};if(new Set(a).size!==a.length)return{ok:!1,reason:`dim "${s}" has duplicate values`};o*=a.length}if(o>64)return{ok:!1,reason:`declared space of ${o} combinations exceeds the 64 maximum`};if(e.baseline!==void 0){if(typeof e.baseline=="string")return{ok:!1,reason:"baseline for a dims slot must be a per-dim record"};let s=e.baseline,a=n.map(([u])=>u).sort(),i=Object.keys(s).sort();if(a.join(" ")!==i.join(" "))return{ok:!1,reason:"baseline must set every declared dim exactly once"};for(let[u,l]of n)if(!l.includes(s[u]))return{ok:!1,reason:`baseline value for dim "${u}" is not declared`}}return{ok:!0}}function Ne(e,r){var t,n;return e.dims!=null?(n=(t=Z(r))!=null?t:Z(ae(e)))!=null?n:{}:r}function ie(e){let r=2166136261;for(let t=0;t<e.length;t++)r^=e.charCodeAt(t),r=r+((r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24))>>>0;return r}function Ie(e,r,t){if(t.length===0)throw new Error("pickDeterministicArm requires at least one arm");let n=[...t].sort();return n[ie(`${e}:${r}`)%n.length]}function Ke(e){return e>=.3?e<.7?"medium":"high":"low"}var ue=20;function le(e,r,t=ue){let n=e.valueCount>0?e.valueSum/e.valueCount:0;if(r<=0)return n;if(e.valueCount<=0)return r;let o=e.valueCount/(e.valueCount+t);return o*n+(1-o)*r}function De(e,r,t=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let n=null,o=-1/0;for(let s of e){let a=w(s.alpha,s.beta,t)*le(s,r);a>o&&(n=s,o=a)}return n.arm}var ce=/^[a-z0-9][a-z0-9_-]{0,31}$/;function Fe(e){if(typeof e!="string")return null;let r=e.trim().toLowerCase();return r&&ce.test(r)?r:null}var fe=["unknown","__all__","buyers","researchers","deal-seekers","browsers"],me=K.map(e=>({key:e,displayName:q[e]})),Ue=64;function Ve(e){var t;let r=new Map;for(let n of e)if(n.status!=="retired"){r.set(n.key,n.key);for(let o of(t=n.aliases)!=null?t:[])fe.includes(o)||r.set(o,n.key)}return r}function $e(e,r=me){var i,u,l;let t=Ve(r),n=(i=e.inferredConfidence)!=null?i:0,o,s=(l=(u=e.declared)==null?void 0:u.trim().toLowerCase())!=null?l:"";if(s!==""){let f=t.get(s),h=f===void 0?t.get(V(s)):void 0,g=f!=null?f:h;if(g!==void 0)return{persona:g,source:"declared",confidence:1};o=s.slice(0,Ue)}let a=V(e.clusterLabel);return a!==R&&t.has(a)?B({persona:t.get(a),source:"inferred",confidence:n},o!==void 0&&{unrecognizedDeclared:o}):B({persona:R,source:"none",confidence:n},o!==void 0&&{unrecognizedDeclared:o})}function Be(e){var t;if(e==null)return R;let r=e.trim().toLowerCase();return r===""?R:(t=U[r])!=null?t:r}0&&(module.exports={CLUSTER_PRIORITY,DEFAULT_PERSONA_VOCABULARY,EV_SHRINK_K,GLOBAL_FACTOR_PERSONA,LAYOUT_FACTOR_BUCKETS,LEGACY_PERSONA_MAP,PERSONAS,PERSONA_DISPLAY,PERSONA_KEY_RE,POOL_ALL,RESERVED_PERSONA_KEYS,SHRINKAGE_M,UNKNOWN_PERSONA,WEIGHTS_FALLBACK_PRIOR_PULLS,applyClusterHeuristic,broadestValueCell,candidateLayouts,canonicalArm,canonicalPersona,chooseLayout,chooseLayoutFactored,confidenceBand,decisionPersona,factorCellsForOrder,fnv1a,hashLayout,layoutBucketOf,marginalArmKey,normalizeDeclaredPersona,parseArm,pickDeterministicArm,pickFromWeights,pooledPosterior,posteriorOfCounts,resolvePersona,sampleArm,sampleArmEv,sampleBeta,shrunkAvgValue,shrunkPosterior,slotBaselineArm,slotResultFor,validateSlotDecl,weightCellsFor});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var re=Object.defineProperty;var j=Object.getOwnPropertySymbols;var ne=Object.prototype.hasOwnProperty,te=Object.prototype.propertyIsEnumerable;var z=(e,r,n)=>r in e?re(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,K=(e,r)=>{for(var n in r||(r={}))ne.call(r,n)&&z(e,n,r[n]);if(j)for(var n of j(r))te.call(r,n)&&z(e,n,r[n]);return e};var _=["buyer","researcher","deal_seeker","browser"],y="unknown",B={buyer:"Buyer",researcher:"Researcher",deal_seeker:"Deal seeker",browser:"Browser",unknown:"Unknown"},V={buyers:"buyer",researchers:"researcher","deal-seekers":"deal_seeker",browsers:"browser",buyer:"buyer",researcher:"researcher",deal_seeker:"deal_seeker",browser:"browser"};function U(e){var n;if(e==null)return y;let r=e.trim().toLowerCase();return(n=V[r])!=null?n:y}var oe=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function g(e,r){return e>>>r|e<<32-r}function G(e){return(e>>>0).toString(16).padStart(8,"0")}function se(e){let r=new TextEncoder().encode(e),n=r.length,o=n*8,s=(n+8>>6)+1<<6,t=new Uint8Array(s);t.set(r),t[n]=128;let a=new DataView(t.buffer);a.setUint32(s-8,Math.floor(o/4294967296),!1),a.setUint32(s-4,o>>>0,!1);let i=1779033703,u=3144134277,f=1013904242,c=2773480762,b=1359893119,m=2600822924,P=528734635,A=1541459225,p=new Uint32Array(64);for(let M=0;M<s;M+=64){for(let l=0;l<16;l++)p[l]=a.getUint32(M+l*4,!1);for(let l=16;l<64;l++){let I=g(p[l-15],7)^g(p[l-15],18)^p[l-15]>>>3,D=g(p[l-2],17)^g(p[l-2],19)^p[l-2]>>>10;p[l]=p[l-16]+I+p[l-7]+D>>>0}let x=i,k=u,v=f,O=c,h=b,R=m,S=P,N=A;for(let l=0;l<64;l++){let I=g(h,6)^g(h,11)^g(h,25),D=h&R^~h&S,H=N+I+D+oe[l]+p[l]>>>0,J=g(x,2)^g(x,13)^g(x,22),Q=x&k^x&v^k&v,ee=J+Q>>>0;N=S,S=R,R=h,h=O+H>>>0,O=v,v=k,k=x,x=H+ee>>>0}i=i+x>>>0,u=u+k>>>0,f=f+v>>>0,c=c+O>>>0,b=b+h>>>0,m=m+R>>>0,P=P+S>>>0,A=A+N>>>0}return G(i)+G(u)}function Y(e){return se(e.join("|"))}var ae={buyer:["pricing","cta","hero","comparison","social_proof","trust","features","faq","navigation","generic"],researcher:["features","comparison","faq","hero","trust","social_proof","pricing","cta","navigation","generic"],deal_seeker:["pricing","comparison","social_proof","trust","cta","hero","features","faq","navigation","generic"],browser:["hero","features","social_proof","pricing","cta","trust","faq","comparison","navigation","generic"]};function q(e,r,n){let o=ae[n];if(!o)return e;let s=o.indexOf("generic"),t=a=>{let i=o.indexOf(a);return i===-1?s:i};return[...e].sort((a,i)=>{var c,b;let u=(c=r.get(a))!=null?c:"generic",f=(b=r.get(i))!=null?b:"generic";return t(u)-t(f)})}function F(e,r,n){let o=new Map;for(let s of[..._,n]){let t=q(e,r,s);o.set(Y(t),t)}return o}function $(e,r){if(e<1)return $(1+e,r)*Math.pow(Math.max(1e-15,r()),1/e);let n=e-1/3,o=1/Math.sqrt(9*n);for(;;){let s,t;do{let i=Math.max(1e-15,r()),u=r();s=Math.sqrt(-2*Math.log(i))*Math.cos(2*Math.PI*u),t=1+o*s}while(t<=0);t=t*t*t;let a=r();if(a<1-.0331*s*s*s*s||Math.log(a)<.5*s*s+n*(1-t+Math.log(t)))return n*t}}function C(e,r,n=Math.random){let o=$(e,n),s=$(r,n),t=o+s;return t<=0?e/(e+r):o/t}function W(e,r=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let n=e[0],o=C(n.alpha,n.beta,r);for(let s=1;s<e.length;s++){let t=e[s],a=C(t.alpha,t.beta,r);a>o&&(n=t,o=a)}return n.arm}function _e(e,r,n,o,s=Math.random){var f,c;let t=F(e,r,n),a=[];for(let b of t.keys()){let m=o.get(b);a.push({arm:b,alpha:(f=m==null?void 0:m.alpha)!=null?f:1,beta:(c=m==null?void 0:m.beta)!=null?c:1})}let i=W(a,s),u=i?t.get(i):void 0;return u!=null?u:q(e,r,n)}function T(e){return Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("|")}function Z(e){if(e.length===0)return null;let r={};for(let n of e.split("|")){let o=n.indexOf("=");if(o<=0||o!==n.lastIndexOf("=")||o===n.length-1)return null;let s=n.slice(0,o);if(s in r)return null;r[s]=n.slice(o+1)}return r}function we(e,r){return`${e}=${r}`}function ie(e){var n,o,s;if(e.arms)return typeof e.baseline=="string"?e.baseline:(n=e.arms[0])!=null?n:"";if(e.baseline!==void 0&&typeof e.baseline=="object")return T(e.baseline);if(typeof e.baseline=="string")return e.baseline;let r={};for(let[t,a]of Object.entries((o=e.dims)!=null?o:{}))r[t]=(s=a[0])!=null?s:"";return T(r)}function Ee(e){let r=Array.isArray(e.arms),n=e.dims!=null;if(r&&n)return{ok:!1,reason:"declare exactly one of arms or dims (got both)"};if(!r&&!n)return{ok:!1,reason:"declare exactly one of arms or dims (got neither)"};if(r){let t=e.arms;if(t.length<2)return{ok:!1,reason:"arms requires at least 2 entries"};if(t.length>12)return{ok:!1,reason:"arms allows at most 12 entries"};if(new Set(t).size!==t.length)return{ok:!1,reason:"arms must be unique"};if(t.some(a=>a.includes("=")))return{ok:!1,reason:"enumerated arm ids may not contain '=' (reserved for dims encoding)"};if(e.baseline!==void 0){if(typeof e.baseline!="string")return{ok:!1,reason:"baseline for an arms slot must be a string"};if(!t.includes(e.baseline))return{ok:!1,reason:"baseline must be one of the declared arms"}}return{ok:!0}}let o=Object.entries(e.dims);if(o.length<1)return{ok:!1,reason:"dims requires at least 1 dimension"};if(o.length>4)return{ok:!1,reason:"dims allows at most 4 dimensions"};let s=1;for(let[t,a]of o){if(a.length<2)return{ok:!1,reason:`dim "${t}" requires at least 2 values`};if(a.length>6)return{ok:!1,reason:`dim "${t}" allows at most 6 values`};if(new Set(a).size!==a.length)return{ok:!1,reason:`dim "${t}" has duplicate values`};s*=a.length}if(s>64)return{ok:!1,reason:`declared space of ${s} combinations exceeds the 64 maximum`};if(e.baseline!==void 0){if(typeof e.baseline=="string")return{ok:!1,reason:"baseline for a dims slot must be a per-dim record"};let t=e.baseline,a=o.map(([u])=>u).sort(),i=Object.keys(t).sort();if(a.join(" ")!==i.join(" "))return{ok:!1,reason:"baseline must set every declared dim exactly once"};for(let[u,f]of o)if(!f.includes(t[u]))return{ok:!1,reason:`baseline value for dim "${u}" is not declared`}}return{ok:!0}}function Le(e,r){var n,o;return e.dims!=null?(o=(n=Z(r))!=null?n:Z(ie(e)))!=null?o:{}:r}var X=20;function w(e,r,n=20){let o=r.alpha+r.beta;if(o<=0||n<=0)return{alpha:e.alpha,beta:e.beta};let s=r.alpha/o,t=n*o/(o+n);return{alpha:e.alpha+t*s,beta:e.beta+t*(1-s)}}var ue=5;function Oe(e,r){var o,s;let n=null;for(let t of e){if(!r.includes(t.variantId))continue;let a=(o=t.pulls)!=null?o:0,i=a>0?a*t.avgReward/(a+ue):0;(!n||i>n.score)&&(n={variantId:t.variantId,score:i})}return(s=n==null?void 0:n.variantId)!=null?s:null}var d="__all__",E={exposures:0,conversions:0};function L(e){return{alpha:e.conversions+1,beta:Math.max(0,e.exposures-e.conversions)+1}}function De(e,r,n=20){var m,P,A,p;let o=(m=e.segment)!=null?m:E,s=(P=e.global)!=null?P:E,t=L(s),a=w(L(o),t,n);if(!r)return a;let i=(A=e.persona)!=null?A:E,u=(p=e.child)!=null?p:E,f=w(L(i),t,n),c=(o.exposures+1)/(o.exposures+i.exposures+2),b={alpha:c*a.alpha+(1-c)*f.alpha,beta:c*a.beta+(1-c)*f.beta};return w(L(u),b,n)}function Ke(e){var o,s;let r=null,n=-1;for(let t of e){let a=t.segment===d,i=t.persona===d,u=a&&i?3:a||i?2:1;u>n&&(n=u,r=t)}return{valueSum:(o=r==null?void 0:r.valueSum)!=null?o:0,valueCount:(s=r==null?void 0:r.valueCount)!=null?s:0}}function Ve(e,r){return r==="unknown"||r===d||r===""?[{segment:e,persona:d},{segment:d,persona:d}]:[{segment:e,persona:r},{segment:e,persona:d},{segment:d,persona:r},{segment:d,persona:d}]}function le(e){let r=2166136261;for(let n=0;n<e.length;n++)r^=e.charCodeAt(n),r=r+((r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24))>>>0;return r}function qe(e,r,n){if(n.length===0)throw new Error("pickDeterministicArm requires at least one arm");let o=[...n].sort();return o[le(`${e}:${r}`)%o.length]}function $e(e){return e>=.3?e<.7?"medium":"high":"low"}var ce=20;function fe(e,r,n=ce){let o=e.valueCount>0?e.valueSum/e.valueCount:0;if(r<=0)return o;if(e.valueCount<=0)return r;let s=e.valueCount/(e.valueCount+n);return s*o+(1-s)*r}function ze(e,r,n=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let o=null,s=-1/0;for(let t of e){let a=C(t.alpha,t.beta,n)*fe(t,r);a>s&&(o=t,s=a)}return o.arm}var me=/^[a-z0-9][a-z0-9_-]{0,31}$/;function Ye(e){if(typeof e!="string")return null;let r=e.trim().toLowerCase();return r&&me.test(r)?r:null}var pe=["unknown","__all__","buyers","researchers","deal-seekers","browsers"],be=_.map(e=>({key:e,displayName:B[e]})),ge=64;function de(e){var n;let r=new Map;for(let o of e)if(o.status!=="retired"){r.set(o.key,o.key);for(let s of(n=o.aliases)!=null?n:[])pe.includes(s)||r.set(s,o.key)}return r}function Fe(e,r=be){var i,u,f;let n=de(r),o=(i=e.inferredConfidence)!=null?i:0,s,t=(f=(u=e.declared)==null?void 0:u.trim().toLowerCase())!=null?f:"";if(t!==""){let c=n.get(t),b=c===void 0?n.get(U(t)):void 0,m=c!=null?c:b;if(m!==void 0)return{persona:m,source:"declared",confidence:1};s=t.slice(0,ge)}let a=U(e.clusterLabel);return a!==y&&n.has(a)?K({persona:n.get(a),source:"inferred",confidence:o},s!==void 0&&{unrecognizedDeclared:s}):K({persona:y,source:"none",confidence:o},s!==void 0&&{unrecognizedDeclared:s})}function We(e){var n;if(e==null)return y;let r=e.trim().toLowerCase();return r===""?y:(n=V[r])!=null?n:r}export{ae as CLUSTER_PRIORITY,be as DEFAULT_PERSONA_VOCABULARY,ce as EV_SHRINK_K,V as LEGACY_PERSONA_MAP,_ as PERSONAS,B as PERSONA_DISPLAY,me as PERSONA_KEY_RE,d as POOL_ALL,pe as RESERVED_PERSONA_KEYS,X as SHRINKAGE_M,y as UNKNOWN_PERSONA,ue as WEIGHTS_FALLBACK_PRIOR_PULLS,q as applyClusterHeuristic,Ke as broadestValueCell,F as candidateLayouts,T as canonicalArm,U as canonicalPersona,_e as chooseLayout,$e as confidenceBand,We as decisionPersona,le as fnv1a,Y as hashLayout,we as marginalArmKey,Ye as normalizeDeclaredPersona,Z as parseArm,qe as pickDeterministicArm,Oe as pickFromWeights,De as pooledPosterior,L as posteriorOfCounts,Fe as resolvePersona,W as sampleArm,ze as sampleArmEv,C as sampleBeta,fe as shrunkAvgValue,w as shrunkPosterior,ie as slotBaselineArm,Le as slotResultFor,Ee as validateSlotDecl,Ve as weightCellsFor};
1
+ import{a as U}from"./chunk-HBG7RQ56.mjs";var K=["buyer","researcher","deal_seeker","browser"],C="unknown",j={buyer:"Buyer",researcher:"Researcher",deal_seeker:"Deal seeker",browser:"Browser",unknown:"Unknown"},V={buyers:"buyer",researchers:"researcher","deal-seekers":"deal_seeker",browsers:"browser",buyer:"buyer",researcher:"researcher",deal_seeker:"deal_seeker",browser:"browser"};function $(e){var t;if(e==null)return C;let r=e.trim().toLowerCase();return(t=V[r])!=null?t:C}var te=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function P(e,r){return e>>>r|e<<32-r}function z(e){return(e>>>0).toString(16).padStart(8,"0")}function ne(e){let r=new TextEncoder().encode(e),t=r.length,n=t*8,s=(t+8>>6)+1<<6,o=new Uint8Array(s);o.set(r),o[t]=128;let a=new DataView(o.buffer);a.setUint32(s-8,Math.floor(n/4294967296),!1),a.setUint32(s-4,n>>>0,!1);let i=1779033703,u=3144134277,l=1013904242,f=2773480762,h=1359893119,g=2600822924,p=528734635,y=1541459225,b=new Uint32Array(64);for(let L=0;L<s;L+=64){for(let m=0;m<16;m++)b[m]=a.getUint32(L+m*4,!1);for(let m=16;m<64;m++){let E=P(b[m-15],7)^P(b[m-15],18)^b[m-15]>>>3,O=P(b[m-2],17)^P(b[m-2],19)^b[m-2]>>>10;b[m]=b[m-16]+E+b[m-7]+O>>>0}let c=i,v=u,d=l,w=f,x=h,R=g,A=p,M=y;for(let m=0;m<64;m++){let E=P(x,6)^P(x,11)^P(x,25),O=x&R^~x&A,H=M+E+O+te[m]+b[m]>>>0,Q=P(c,2)^P(c,13)^P(c,22),ee=c&v^c&d^v&d,re=Q+ee>>>0;M=A,A=R,R=x,x=w+H>>>0,w=d,d=v,v=c,c=H+re>>>0}i=i+c>>>0,u=u+v>>>0,l=l+d>>>0,f=f+w>>>0,h=h+x>>>0,g=g+R>>>0,p=p+A>>>0,y=y+M>>>0}return z(i)+z(u)}function G(e){return ne(e.join("|"))}var oe={buyer:["pricing","cta","hero","comparison","social_proof","trust","features","faq","navigation","generic"],researcher:["features","comparison","faq","hero","trust","social_proof","pricing","cta","navigation","generic"],deal_seeker:["pricing","comparison","social_proof","trust","cta","hero","features","faq","navigation","generic"],browser:["hero","features","social_proof","pricing","cta","trust","faq","comparison","navigation","generic"]};function N(e,r,t,n){let s=oe[t];if(!s)return e;let o=s.indexOf("generic"),a=l=>{let f=s.indexOf(l);return f===-1?o:f},i=n?e.filter(l=>n.get(l)!=="structural"):[...e];if(i.sort((l,f)=>{var p,y;let h=(p=r.get(l))!=null?p:"generic",g=(y=r.get(f))!=null?y:"generic";return a(h)-a(g)}),!n)return i;let u=0;return e.map(l=>n.get(l)==="structural"?l:i[u++])}function D(e,r,t,n){let s=new Map;for(let o of[...K,t]){let a=N(e,r,o,n);s.set(G(a),a)}return s}function B(e,r){if(e<1)return B(1+e,r)*Math.pow(Math.max(1e-15,r()),1/e);let t=e-1/3,n=1/Math.sqrt(9*t);for(;;){let s,o;do{let i=Math.max(1e-15,r()),u=r();s=Math.sqrt(-2*Math.log(i))*Math.cos(2*Math.PI*u),o=1+n*s}while(o<=0);o=o*o*o;let a=r();if(a<1-.0331*s*s*s*s||Math.log(a)<.5*s*s+t*(1-o+Math.log(o)))return t*o}}function I(e,r,t=Math.random){let n=B(e,t),s=B(r,t),o=n+s;return o<=0?e/(e+r):n/o}function Y(e,r=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let t=e[0],n=I(t.alpha,t.beta,r);for(let s=1;s<e.length;s++){let o=e[s],a=I(o.alpha,o.beta,r);a>n&&(t=o,n=a)}return t.arm}function Se(e,r,t,n,s=Math.random,o){var f,h;let a=D(e,r,t,o),i=[];for(let g of a.keys()){let p=n.get(g);i.push({arm:g,alpha:(f=p==null?void 0:p.alpha)!=null?f:1,beta:(h=p==null?void 0:p.beta)!=null?h:1})}let u=Y(i,s),l=u?a.get(u):void 0;return l!=null?l:N(e,r,t,o)}var W=20;function _(e,r,t=20){let n=r.alpha+r.beta;if(n<=0||t<=0)return{alpha:e.alpha,beta:e.beta};let s=r.alpha/n,o=t*n/(n+t);return{alpha:e.alpha+o*s,beta:e.beta+o*(1-s)}}var se=5;function Ce(e,r){var n,s;let t=null;for(let o of e){if(!r.includes(o.variantId))continue;let a=(n=o.pulls)!=null?n:0,i=a>0?a*o.avgReward/(a+se):0;(!t||i>t.score)&&(t={variantId:o.variantId,score:i})}return(s=t==null?void 0:t.variantId)!=null?s:null}var k="__all__",F={exposures:0,conversions:0};function S(e){return{alpha:e.conversions+1,beta:Math.max(0,e.exposures-e.conversions)+1}}function we(e,r,t=20){var g,p,y,b;let n=(g=e.segment)!=null?g:F,s=(p=e.global)!=null?p:F,o=S(s),a=_(S(n),o,t);if(!r)return a;let i=(y=e.persona)!=null?y:F,u=(b=e.child)!=null?b:F,l=_(S(i),o,t),f=(n.exposures+1)/(n.exposures+i.exposures+2),h={alpha:f*a.alpha+(1-f)*l.alpha,beta:f*a.beta+(1-f)*l.beta};return _(S(u),h,t)}function Me(e){var n,s;let r=null,t=-1;for(let o of e){let a=o.segment===k,i=o.persona===k,u=a&&i?3:a||i?2:1;u>t&&(t=u,r=o)}return{valueSum:(n=r==null?void 0:r.valueSum)!=null?n:0,valueCount:(s=r==null?void 0:r.valueCount)!=null?s:0}}function Ee(e,r){return r==="unknown"||r===k||r===""?[{segment:e,persona:k},{segment:k,persona:k}]:[{segment:e,persona:r},{segment:e,persona:k},{segment:k,persona:r},{segment:k,persona:k}]}var T=4,ae="__global__";function Z(e,r){return r<=0?0:Math.min(T-1,Math.floor(e*T/r))}function Fe(e,r){return e.map((t,n)=>{var s;return{parent:(s=r.get(t))!=null?s:"generic",bucket:Z(n,e.length)}})}var q=(e,r)=>`${e}#${r}`;function Ue(e,r,t,n,s=Math.random,o){var L;let a=D(e,r,t,o);if(a.size===0)return N(e,r,t,o);let i=new Map,u=new Map,l=0,f=0;for(let c of n)c.persona===ae?(i.set(q(c.parent,c.bucket),c),l+=c.exposures,f+=c.conversions):c.persona===t&&u.set(q(c.parent,c.bucket),c);let h=S({exposures:l,conversions:f}),g=new Map,p=(c,v)=>{var E,O;let d=q(c,v),w=g.get(d);if(w!==void 0)return w;let x=i.get(d),R=_(S({exposures:(E=x==null?void 0:x.exposures)!=null?E:0,conversions:(O=x==null?void 0:x.conversions)!=null?O:0}),h),A=u.get(d),M=A?_(S({exposures:A.exposures,conversions:A.conversions}),R):R,m=I(M.alpha,M.beta,s);return g.set(d,m),m},y=null,b=-1/0;for(let c of a.values()){let v=0;for(let d=0;d<c.length;d++)v+=p((L=r.get(c[d]))!=null?L:"generic",Z(d,c.length));v>b&&(b=v,y=c)}return y!=null?y:N(e,r,t,o)}function X(e){return Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("|")}function J(e){if(e.length===0)return null;let r={};for(let t of e.split("|")){let n=t.indexOf("=");if(n<=0||n!==t.lastIndexOf("=")||n===t.length-1)return null;let s=t.slice(0,n);if(s in r)return null;r[s]=t.slice(n+1)}return r}function $e(e,r){return`${e}=${r}`}function ie(e){var t,n,s;if(e.arms)return typeof e.baseline=="string"?e.baseline:(t=e.arms[0])!=null?t:"";if(e.baseline!==void 0&&typeof e.baseline=="object")return X(e.baseline);if(typeof e.baseline=="string")return e.baseline;let r={};for(let[o,a]of Object.entries((n=e.dims)!=null?n:{}))r[o]=(s=a[0])!=null?s:"";return X(r)}function Be(e){let r=Array.isArray(e.arms),t=e.dims!=null;if(r&&t)return{ok:!1,reason:"declare exactly one of arms or dims (got both)"};if(!r&&!t)return{ok:!1,reason:"declare exactly one of arms or dims (got neither)"};if(r){let o=e.arms;if(o.length<2)return{ok:!1,reason:"arms requires at least 2 entries"};if(o.length>12)return{ok:!1,reason:"arms allows at most 12 entries"};if(new Set(o).size!==o.length)return{ok:!1,reason:"arms must be unique"};if(o.some(a=>a.includes("=")))return{ok:!1,reason:"enumerated arm ids may not contain '=' (reserved for dims encoding)"};if(e.baseline!==void 0){if(typeof e.baseline!="string")return{ok:!1,reason:"baseline for an arms slot must be a string"};if(!o.includes(e.baseline))return{ok:!1,reason:"baseline must be one of the declared arms"}}return{ok:!0}}let n=Object.entries(e.dims);if(n.length<1)return{ok:!1,reason:"dims requires at least 1 dimension"};if(n.length>4)return{ok:!1,reason:"dims allows at most 4 dimensions"};let s=1;for(let[o,a]of n){if(a.length<2)return{ok:!1,reason:`dim "${o}" requires at least 2 values`};if(a.length>6)return{ok:!1,reason:`dim "${o}" allows at most 6 values`};if(new Set(a).size!==a.length)return{ok:!1,reason:`dim "${o}" has duplicate values`};s*=a.length}if(s>64)return{ok:!1,reason:`declared space of ${s} combinations exceeds the 64 maximum`};if(e.baseline!==void 0){if(typeof e.baseline=="string")return{ok:!1,reason:"baseline for a dims slot must be a per-dim record"};let o=e.baseline,a=n.map(([u])=>u).sort(),i=Object.keys(o).sort();if(a.join(" ")!==i.join(" "))return{ok:!1,reason:"baseline must set every declared dim exactly once"};for(let[u,l]of n)if(!l.includes(o[u]))return{ok:!1,reason:`baseline value for dim "${u}" is not declared`}}return{ok:!0}}function qe(e,r){var t,n;return e.dims!=null?(n=(t=J(r))!=null?t:J(ie(e)))!=null?n:{}:r}function ue(e){let r=2166136261;for(let t=0;t<e.length;t++)r^=e.charCodeAt(t),r=r+((r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24))>>>0;return r}function je(e,r,t){if(t.length===0)throw new Error("pickDeterministicArm requires at least one arm");let n=[...t].sort();return n[ue(`${e}:${r}`)%n.length]}function ze(e){return e>=.3?e<.7?"medium":"high":"low"}var le=20;function ce(e,r,t=le){let n=e.valueCount>0?e.valueSum/e.valueCount:0;if(r<=0)return n;if(e.valueCount<=0)return r;let s=e.valueCount/(e.valueCount+t);return s*n+(1-s)*r}function We(e,r,t=Math.random){if(e.length===0)return null;if(e.length===1)return e[0].arm;let n=null,s=-1/0;for(let o of e){let a=I(o.alpha,o.beta,t)*ce(o,r);a>s&&(n=o,s=a)}return n.arm}var fe=/^[a-z0-9][a-z0-9_-]{0,31}$/;function Xe(e){if(typeof e!="string")return null;let r=e.trim().toLowerCase();return r&&fe.test(r)?r:null}var me=["unknown","__all__","buyers","researchers","deal-seekers","browsers"],pe=K.map(e=>({key:e,displayName:j[e]})),ge=64;function be(e){var t;let r=new Map;for(let n of e)if(n.status!=="retired"){r.set(n.key,n.key);for(let s of(t=n.aliases)!=null?t:[])me.includes(s)||r.set(s,n.key)}return r}function Je(e,r=pe){var i,u,l;let t=be(r),n=(i=e.inferredConfidence)!=null?i:0,s,o=(l=(u=e.declared)==null?void 0:u.trim().toLowerCase())!=null?l:"";if(o!==""){let f=t.get(o),h=f===void 0?t.get($(o)):void 0,g=f!=null?f:h;if(g!==void 0)return{persona:g,source:"declared",confidence:1};s=o.slice(0,ge)}let a=$(e.clusterLabel);return a!==C&&t.has(a)?U({persona:t.get(a),source:"inferred",confidence:n},s!==void 0&&{unrecognizedDeclared:s}):U({persona:C,source:"none",confidence:n},s!==void 0&&{unrecognizedDeclared:s})}function Qe(e){var t;if(e==null)return C;let r=e.trim().toLowerCase();return r===""?C:(t=V[r])!=null?t:r}export{oe as CLUSTER_PRIORITY,pe as DEFAULT_PERSONA_VOCABULARY,le as EV_SHRINK_K,ae as GLOBAL_FACTOR_PERSONA,T as LAYOUT_FACTOR_BUCKETS,V as LEGACY_PERSONA_MAP,K as PERSONAS,j as PERSONA_DISPLAY,fe as PERSONA_KEY_RE,k as POOL_ALL,me as RESERVED_PERSONA_KEYS,W as SHRINKAGE_M,C as UNKNOWN_PERSONA,se as WEIGHTS_FALLBACK_PRIOR_PULLS,N as applyClusterHeuristic,Me as broadestValueCell,D as candidateLayouts,X as canonicalArm,$ as canonicalPersona,Se as chooseLayout,Ue as chooseLayoutFactored,ze as confidenceBand,Qe as decisionPersona,Fe as factorCellsForOrder,ue as fnv1a,G as hashLayout,Z as layoutBucketOf,$e as marginalArmKey,Xe as normalizeDeclaredPersona,J as parseArm,je as pickDeterministicArm,Ce as pickFromWeights,we as pooledPosterior,S as posteriorOfCounts,Je as resolvePersona,Y as sampleArm,We as sampleArmEv,I as sampleBeta,ce as shrunkAvgValue,_ as shrunkPosterior,ie as slotBaselineArm,qe as slotResultFor,Be as validateSlotDecl,Ee as weightCellsFor};
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Two-layer section vocabulary (spec 2026-09-04).
3
+ *
4
+ * `parent` is the existing 10-value enum. It is the ONLY layer the layout
5
+ * bandit orders on, so the arm space stays bounded however rich `topic` grows —
6
+ * adding `carbon_fibre` buys understanding and zero extra bandit arms. That
7
+ * bound is load-bearing: a low-traffic project cannot support more arms (see
8
+ * the feasibility analysis in the spec), so widening the ordering vocabulary
9
+ * would make the statistics worse, not better.
10
+ *
11
+ * `topic` is the real semantics. The shipped classifier was tuned on SaaS
12
+ * marketing pages and returns `generic` for 8 of 9 sections on a car-body-repair
13
+ * site (measured — see the spec), which is why `services`, `gallery`, `process`
14
+ * and `insurance` exist here at all.
15
+ *
16
+ * `role` is orthogonal to both and describes what a section is FOR:
17
+ * - converter — carries a reward trigger (declared goal, form, tel:, booking)
18
+ * - persuader — no trigger; earns its place through dwell, feeds persona dims
19
+ * - structural — nav/footer/breadcrumb; evidence for neither, and reordering
20
+ * it would visibly damage the page
21
+ * Only converters and persuaders are reorderable; structural sections are pinned.
22
+ *
23
+ * NOTE: `role` here is the topic's DEFAULT. Phase 2b overrides it per section
24
+ * from real evidence (a declared goal's locator resolving inside the section),
25
+ * because a `services` band containing a "Book now" button really is a converter.
26
+ */
27
+ declare const SEMANTIC_PARENTS: readonly ["pricing", "hero", "social_proof", "cta", "features", "faq", "comparison", "trust", "navigation", "generic"];
28
+ type SemanticParent = (typeof SEMANTIC_PARENTS)[number];
29
+ type SectionRole = 'converter' | 'persuader' | 'structural';
30
+ declare const TOPICS: ReadonlyArray<{
31
+ topic: string;
32
+ parent: SemanticParent;
33
+ role: SectionRole;
34
+ }>;
35
+ /** Project a topic onto the parent the bandit orders on. Unknown → 'generic':
36
+ * an unrecognised topic must never hijack an ordering slot — the same reasoning
37
+ * as the off-vocabulary guard in layout-heuristics.ts, where a present-but-
38
+ * unrecognised type yielded indexOf === -1 and sorted ahead of everything. */
39
+ declare function parentOfTopic(topic: string): SemanticParent;
40
+ /** Default role for a topic. Unknown → 'persuader', never 'structural':
41
+ * structural sections are PINNED and never reordered, so defaulting an unknown
42
+ * topic to structural would silently freeze real content in place — failing
43
+ * closed in the direction that does the least harm. */
44
+ declare function roleOfTopic(topic: string): SectionRole;
45
+
46
+ export { SEMANTIC_PARENTS, type SectionRole, type SemanticParent, TOPICS, parentOfTopic, roleOfTopic };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Two-layer section vocabulary (spec 2026-09-04).
3
+ *
4
+ * `parent` is the existing 10-value enum. It is the ONLY layer the layout
5
+ * bandit orders on, so the arm space stays bounded however rich `topic` grows —
6
+ * adding `carbon_fibre` buys understanding and zero extra bandit arms. That
7
+ * bound is load-bearing: a low-traffic project cannot support more arms (see
8
+ * the feasibility analysis in the spec), so widening the ordering vocabulary
9
+ * would make the statistics worse, not better.
10
+ *
11
+ * `topic` is the real semantics. The shipped classifier was tuned on SaaS
12
+ * marketing pages and returns `generic` for 8 of 9 sections on a car-body-repair
13
+ * site (measured — see the spec), which is why `services`, `gallery`, `process`
14
+ * and `insurance` exist here at all.
15
+ *
16
+ * `role` is orthogonal to both and describes what a section is FOR:
17
+ * - converter — carries a reward trigger (declared goal, form, tel:, booking)
18
+ * - persuader — no trigger; earns its place through dwell, feeds persona dims
19
+ * - structural — nav/footer/breadcrumb; evidence for neither, and reordering
20
+ * it would visibly damage the page
21
+ * Only converters and persuaders are reorderable; structural sections are pinned.
22
+ *
23
+ * NOTE: `role` here is the topic's DEFAULT. Phase 2b overrides it per section
24
+ * from real evidence (a declared goal's locator resolving inside the section),
25
+ * because a `services` band containing a "Book now" button really is a converter.
26
+ */
27
+ declare const SEMANTIC_PARENTS: readonly ["pricing", "hero", "social_proof", "cta", "features", "faq", "comparison", "trust", "navigation", "generic"];
28
+ type SemanticParent = (typeof SEMANTIC_PARENTS)[number];
29
+ type SectionRole = 'converter' | 'persuader' | 'structural';
30
+ declare const TOPICS: ReadonlyArray<{
31
+ topic: string;
32
+ parent: SemanticParent;
33
+ role: SectionRole;
34
+ }>;
35
+ /** Project a topic onto the parent the bandit orders on. Unknown → 'generic':
36
+ * an unrecognised topic must never hijack an ordering slot — the same reasoning
37
+ * as the off-vocabulary guard in layout-heuristics.ts, where a present-but-
38
+ * unrecognised type yielded indexOf === -1 and sorted ahead of everything. */
39
+ declare function parentOfTopic(topic: string): SemanticParent;
40
+ /** Default role for a topic. Unknown → 'persuader', never 'structural':
41
+ * structural sections are PINNED and never reordered, so defaulting an unknown
42
+ * topic to structural would silently freeze real content in place — failing
43
+ * closed in the direction that does the least harm. */
44
+ declare function roleOfTopic(topic: string): SectionRole;
45
+
46
+ export { SEMANTIC_PARENTS, type SectionRole, type SemanticParent, TOPICS, parentOfTopic, roleOfTopic };
@@ -0,0 +1 @@
1
+ "use strict";var a=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var l=(r,e)=>{for(var t in e)a(r,t,{get:e[t],enumerable:!0})},d=(r,e,t,p)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of s(e))!u.call(r,o)&&o!==t&&a(r,o,{get:()=>e[o],enumerable:!(p=i(e,o))||p.enumerable});return r};var f=r=>d(a({},"__esModule",{value:!0}),r);var m={};l(m,{SEMANTIC_PARENTS:()=>g,TOPICS:()=>n,parentOfTopic:()=>v,roleOfTopic:()=>_});module.exports=f(m);var g=["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"],n=[{topic:"pricing_plans",parent:"pricing",role:"converter"},{topic:"financing",parent:"pricing",role:"persuader"},{topic:"quote",parent:"pricing",role:"converter"},{topic:"hero",parent:"hero",role:"converter"},{topic:"reviews",parent:"social_proof",role:"persuader"},{topic:"testimonials",parent:"social_proof",role:"persuader"},{topic:"case_study",parent:"social_proof",role:"persuader"},{topic:"brands",parent:"social_proof",role:"persuader"},{topic:"awards",parent:"social_proof",role:"persuader"},{topic:"press",parent:"social_proof",role:"persuader"},{topic:"stats",parent:"social_proof",role:"persuader"},{topic:"gallery",parent:"social_proof",role:"persuader"},{topic:"cta",parent:"cta",role:"converter"},{topic:"booking",parent:"cta",role:"converter"},{topic:"contact_form",parent:"cta",role:"converter"},{topic:"newsletter",parent:"cta",role:"converter"},{topic:"hours",parent:"cta",role:"persuader"},{topic:"location",parent:"cta",role:"persuader"},{topic:"services",parent:"features",role:"persuader"},{topic:"features",parent:"features",role:"persuader"},{topic:"process",parent:"features",role:"persuader"},{topic:"capabilities",parent:"features",role:"persuader"},{topic:"specialties",parent:"features",role:"persuader"},{topic:"menu",parent:"features",role:"persuader"},{topic:"inventory",parent:"features",role:"converter"},{topic:"integrations",parent:"features",role:"persuader"},{topic:"faq",parent:"faq",role:"persuader"},{topic:"comparison",parent:"comparison",role:"persuader"},{topic:"insurance",parent:"trust",role:"persuader"},{topic:"warranty",parent:"trust",role:"persuader"},{topic:"certifications",parent:"trust",role:"persuader"},{topic:"security",parent:"trust",role:"persuader"},{topic:"guarantee",parent:"trust",role:"persuader"},{topic:"about",parent:"trust",role:"persuader"},{topic:"team",parent:"trust",role:"persuader"},{topic:"navigation",parent:"navigation",role:"structural"},{topic:"footer",parent:"navigation",role:"structural"},{topic:"breadcrumb",parent:"navigation",role:"structural"},{topic:"cookie_banner",parent:"navigation",role:"structural"},{topic:"generic",parent:"generic",role:"persuader"},{topic:"blog",parent:"generic",role:"persuader"},{topic:"resources",parent:"generic",role:"persuader"},{topic:"careers",parent:"generic",role:"persuader"},{topic:"legal",parent:"generic",role:"persuader"}],c=new Map(n.map(r=>[r.topic,r]));function v(r){var e,t;return(t=(e=c.get(r))==null?void 0:e.parent)!=null?t:"generic"}function _(r){var e,t;return(t=(e=c.get(r))==null?void 0:e.role)!=null?t:"persuader"}0&&(module.exports={SEMANTIC_PARENTS,TOPICS,parentOfTopic,roleOfTopic});
@@ -0,0 +1 @@
1
+ import"./chunk-HBG7RQ56.mjs";var p=["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"],a=[{topic:"pricing_plans",parent:"pricing",role:"converter"},{topic:"financing",parent:"pricing",role:"persuader"},{topic:"quote",parent:"pricing",role:"converter"},{topic:"hero",parent:"hero",role:"converter"},{topic:"reviews",parent:"social_proof",role:"persuader"},{topic:"testimonials",parent:"social_proof",role:"persuader"},{topic:"case_study",parent:"social_proof",role:"persuader"},{topic:"brands",parent:"social_proof",role:"persuader"},{topic:"awards",parent:"social_proof",role:"persuader"},{topic:"press",parent:"social_proof",role:"persuader"},{topic:"stats",parent:"social_proof",role:"persuader"},{topic:"gallery",parent:"social_proof",role:"persuader"},{topic:"cta",parent:"cta",role:"converter"},{topic:"booking",parent:"cta",role:"converter"},{topic:"contact_form",parent:"cta",role:"converter"},{topic:"newsletter",parent:"cta",role:"converter"},{topic:"hours",parent:"cta",role:"persuader"},{topic:"location",parent:"cta",role:"persuader"},{topic:"services",parent:"features",role:"persuader"},{topic:"features",parent:"features",role:"persuader"},{topic:"process",parent:"features",role:"persuader"},{topic:"capabilities",parent:"features",role:"persuader"},{topic:"specialties",parent:"features",role:"persuader"},{topic:"menu",parent:"features",role:"persuader"},{topic:"inventory",parent:"features",role:"converter"},{topic:"integrations",parent:"features",role:"persuader"},{topic:"faq",parent:"faq",role:"persuader"},{topic:"comparison",parent:"comparison",role:"persuader"},{topic:"insurance",parent:"trust",role:"persuader"},{topic:"warranty",parent:"trust",role:"persuader"},{topic:"certifications",parent:"trust",role:"persuader"},{topic:"security",parent:"trust",role:"persuader"},{topic:"guarantee",parent:"trust",role:"persuader"},{topic:"about",parent:"trust",role:"persuader"},{topic:"team",parent:"trust",role:"persuader"},{topic:"navigation",parent:"navigation",role:"structural"},{topic:"footer",parent:"navigation",role:"structural"},{topic:"breadcrumb",parent:"navigation",role:"structural"},{topic:"cookie_banner",parent:"navigation",role:"structural"},{topic:"generic",parent:"generic",role:"persuader"},{topic:"blog",parent:"generic",role:"persuader"},{topic:"resources",parent:"generic",role:"persuader"},{topic:"careers",parent:"generic",role:"persuader"},{topic:"legal",parent:"generic",role:"persuader"}],o=new Map(a.map(e=>[e.topic,e]));function n(e){var r,t;return(t=(r=o.get(e))==null?void 0:r.parent)!=null?t:"generic"}function c(e){var r,t;return(t=(r=o.get(e))==null?void 0:r.role)!=null?t:"persuader"}export{p as SEMANTIC_PARENTS,a as TOPICS,n as parentOfTopic,c as roleOfTopic};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentientui/policy",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "private": false,
5
5
  "description": "Pure decision-policy functions shared by the SentientUI API and the keyless local engine",
6
6
  "license": "MIT",
@@ -21,6 +21,11 @@
21
21
  "types": "./dist/index.d.ts",
22
22
  "import": "./dist/index.mjs",
23
23
  "require": "./dist/index.js"
24
+ },
25
+ "./taxonomy": {
26
+ "types": "./dist/taxonomy.d.ts",
27
+ "import": "./dist/taxonomy.mjs",
28
+ "require": "./dist/taxonomy.js"
24
29
  }
25
30
  },
26
31
  "files": [