@mneme-ai/core 2.19.19 → 2.19.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/cosmic/aurelian_v1920.test.d.ts +2 -0
  2. package/dist/cosmic/aurelian_v1920.test.d.ts.map +1 -0
  3. package/dist/cosmic/aurelian_v1920.test.js +61 -0
  4. package/dist/cosmic/aurelian_v1920.test.js.map +1 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +3 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/provenance_dna/index.d.ts +115 -0
  10. package/dist/provenance_dna/index.d.ts.map +1 -0
  11. package/dist/provenance_dna/index.js +242 -0
  12. package/dist/provenance_dna/index.js.map +1 -0
  13. package/dist/provenance_dna/provenance_dna.test.d.ts +2 -0
  14. package/dist/provenance_dna/provenance_dna.test.d.ts.map +1 -0
  15. package/dist/provenance_dna/provenance_dna.test.js +279 -0
  16. package/dist/provenance_dna/provenance_dna.test.js.map +1 -0
  17. package/dist/reverse_caption_injection/index.d.ts +91 -0
  18. package/dist/reverse_caption_injection/index.d.ts.map +1 -0
  19. package/dist/reverse_caption_injection/index.js +162 -0
  20. package/dist/reverse_caption_injection/index.js.map +1 -0
  21. package/dist/reverse_caption_injection/reverse_caption_injection.test.d.ts +2 -0
  22. package/dist/reverse_caption_injection/reverse_caption_injection.test.d.ts.map +1 -0
  23. package/dist/reverse_caption_injection/reverse_caption_injection.test.js +177 -0
  24. package/dist/reverse_caption_injection/reverse_caption_injection.test.js.map +1 -0
  25. package/dist/textron_captcha/index.d.ts +147 -0
  26. package/dist/textron_captcha/index.d.ts.map +1 -0
  27. package/dist/textron_captcha/index.js +255 -0
  28. package/dist/textron_captcha/index.js.map +1 -0
  29. package/dist/textron_captcha/textron_captcha.test.d.ts +2 -0
  30. package/dist/textron_captcha/textron_captcha.test.d.ts.map +1 -0
  31. package/dist/textron_captcha/textron_captcha.test.js +231 -0
  32. package/dist/textron_captcha/textron_captcha.test.js.map +1 -0
  33. package/dist/whats_new.d.ts.map +1 -1
  34. package/dist/whats_new.js +8 -0
  35. package/dist/whats_new.js.map +1 -1
  36. package/dist/wrapper_genesis/index.d.ts.map +1 -1
  37. package/dist/wrapper_genesis/index.js +14 -0
  38. package/dist/wrapper_genesis/index.js.map +1 -1
  39. package/package.json +1 -1
@@ -0,0 +1,279 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { perceptualHash, hammingDistance, emptyRegistry, recordObservation, verifyRegistry, evaluatePhash, fingerprintSeller, formatVerdictLine, } from "./index.js";
3
+ const SECRET = "prov-test-secret-44889977";
4
+ function makeImage(width, height, fillFn) {
5
+ const rgba = new Uint8Array(width * height * 4);
6
+ for (let y = 0; y < height; y++) {
7
+ for (let x = 0; x < width; x++) {
8
+ const [r, g, b] = fillFn(x, y);
9
+ const idx = (y * width + x) * 4;
10
+ rgba[idx] = r;
11
+ rgba[idx + 1] = g;
12
+ rgba[idx + 2] = b;
13
+ rgba[idx + 3] = 255;
14
+ }
15
+ }
16
+ return { width, height, rgba };
17
+ }
18
+ describe("v2.19.20 PROVENANCE-DNA · perceptualHash (aHash)", () => {
19
+ it("produces 16-hex-char (64-bit) hash", () => {
20
+ const img = makeImage(64, 64, (x, y) => [x * 4, y * 4, 128]);
21
+ const h = perceptualHash(img);
22
+ expect(h).toMatch(/^[a-f0-9]{16}$/);
23
+ });
24
+ it("DETERMINISM: identical input → identical hash (100%)", () => {
25
+ const img = makeImage(32, 32, (x, _y) => [x * 8, 100, 200]);
26
+ const a = perceptualHash(img);
27
+ const b = perceptualHash(img);
28
+ expect(a).toBe(b);
29
+ });
30
+ it("LOCALITY: same gradient at 2x scale → Hamming distance ≤ 4 (within 4/64 bits)", () => {
31
+ const small = makeImage(32, 32, (x, _y) => [x * 8, 100, 200]);
32
+ const large = makeImage(64, 64, (x, _y) => [x * 4, 100, 200]);
33
+ const hSmall = perceptualHash(small);
34
+ const hLarge = perceptualHash(large);
35
+ expect(hammingDistance(hSmall, hLarge)).toBeLessThanOrEqual(4);
36
+ });
37
+ it("DISCRIMINATION: distinct images → Hamming distance ≥ 8 (out of 64)", () => {
38
+ const a = makeImage(32, 32, (x, _y) => [x * 8, 100, 200]); // horizontal gradient
39
+ const b = makeImage(32, 32, (_x, y) => [y * 8, 100, 200]); // vertical gradient
40
+ expect(hammingDistance(perceptualHash(a), perceptualHash(b))).toBeGreaterThanOrEqual(8);
41
+ });
42
+ it("rejects malformed image (rgba length mismatch)", () => {
43
+ const bad = { width: 8, height: 8, rgba: new Uint8Array(50) };
44
+ expect(() => perceptualHash(bad)).toThrow();
45
+ });
46
+ it("rejects zero-dimension image", () => {
47
+ const bad = { width: 0, height: 0, rgba: new Uint8Array(0) };
48
+ expect(() => perceptualHash(bad)).toThrow();
49
+ });
50
+ });
51
+ describe("v2.19.20 PROVENANCE-DNA · hammingDistance", () => {
52
+ it("returns 0 for identical hex strings", () => {
53
+ expect(hammingDistance("ff00", "ff00")).toBe(0);
54
+ });
55
+ it("returns expected bit count for known difference", () => {
56
+ expect(hammingDistance("ff00", "0000")).toBe(8); // 8 bits set in 0xff
57
+ expect(hammingDistance("ffff", "0000")).toBe(16); // 16 bits set
58
+ expect(hammingDistance("ff0f", "f0f0")).toBe(12); // 0xff^0xf0=0x0f (4 bits) + 0x0f^0xf0=0xff (8 bits) = 12
59
+ });
60
+ it("throws on length mismatch", () => {
61
+ expect(() => hammingDistance("ff", "ffff")).toThrow();
62
+ });
63
+ });
64
+ describe("v2.19.20 PROVENANCE-DNA · recordObservation + verifyRegistry", () => {
65
+ it("appends record with HMAC chain (prevSig linkage)", () => {
66
+ let r = emptyRegistry();
67
+ r = recordObservation({ registry: r, pHash: "aa00bb00cc00dd00", claim: "x", sellerFingerprint: "s1", nowMs: 1_000_000, secret: SECRET });
68
+ r = recordObservation({ registry: r, pHash: "aa00bb00cc00dd00", claim: "x", sellerFingerprint: "s2", nowMs: 1_000_001, secret: SECRET });
69
+ expect(r.records).toHaveLength(2);
70
+ expect(r.records[0].prevSig).toBeNull();
71
+ expect(r.records[1].prevSig).toBe(r.records[0].sig);
72
+ });
73
+ it("verifyRegistry passes for untampered chain", () => {
74
+ let r = emptyRegistry();
75
+ for (let i = 0; i < 5; i++) {
76
+ r = recordObservation({ registry: r, pHash: "aa00bb00cc00dd00", claim: `c${i}`, sellerFingerprint: `s${i}`, nowMs: 1_000_000 + i, secret: SECRET });
77
+ }
78
+ expect(verifyRegistry(r, SECRET).ok).toBe(true);
79
+ });
80
+ it("verifyRegistry detects tampered claim at exact step", () => {
81
+ let r = emptyRegistry();
82
+ for (let i = 0; i < 5; i++) {
83
+ r = recordObservation({ registry: r, pHash: "ff", claim: `c${i}`, sellerFingerprint: `s${i}`, nowMs: 1_000_000 + i, secret: SECRET });
84
+ }
85
+ const tampered = {
86
+ ...r,
87
+ records: r.records.map((rr, i) => (i === 2 ? { ...rr, claim: "evil" } : rr)),
88
+ };
89
+ const v = verifyRegistry(tampered, SECRET);
90
+ expect(v.ok).toBe(false);
91
+ expect(v.brokenAt).toBe(2);
92
+ });
93
+ });
94
+ describe("v2.19.20 PROVENANCE-DNA · evaluatePhash — STOLEN_PHOTO flag", () => {
95
+ it("flags STOLEN_PHOTO when ≥10 distinct sellers used the same pHash in 90d", () => {
96
+ let r = emptyRegistry();
97
+ const pHash = "aa00bb00cc00dd00";
98
+ for (let i = 0; i < 12; i++) {
99
+ r = recordObservation({ registry: r, pHash, claim: "x", sellerFingerprint: `seller-${i}`, nowMs: 1_000_000 + i, secret: SECRET });
100
+ }
101
+ const v = evaluatePhash({ registry: r, pHash, nowMs: 2_000_000 });
102
+ expect(v.flags).toContain("STOLEN_PHOTO");
103
+ expect(v.distinctSellers).toBe(12);
104
+ });
105
+ it("does NOT flag STOLEN_PHOTO when same seller posts multiple times", () => {
106
+ let r = emptyRegistry();
107
+ const pHash = "bb";
108
+ for (let i = 0; i < 12; i++) {
109
+ r = recordObservation({ registry: r, pHash, claim: "x", sellerFingerprint: "single-seller", nowMs: 1_000_000 + i, secret: SECRET });
110
+ }
111
+ const v = evaluatePhash({ registry: r, pHash, nowMs: 2_000_000 });
112
+ expect(v.flags).not.toContain("STOLEN_PHOTO");
113
+ expect(v.distinctSellers).toBe(1);
114
+ });
115
+ it("respects 90-day window — old observations don't count", () => {
116
+ let r = emptyRegistry();
117
+ const pHash = "cc";
118
+ const ancientTs = 1_000_000;
119
+ const nowMs = ancientTs + 100 * 24 * 60 * 60 * 1000; // 100 days later
120
+ for (let i = 0; i < 15; i++) {
121
+ r = recordObservation({ registry: r, pHash, claim: "x", sellerFingerprint: `s${i}`, nowMs: ancientTs + i, secret: SECRET });
122
+ }
123
+ const v = evaluatePhash({ registry: r, pHash, nowMs });
124
+ // All observations are >90d old → not counted → CLEAN
125
+ expect(v.flags).toContain("CLEAN");
126
+ expect(v.distinctSellers).toBe(0);
127
+ });
128
+ it("respects Hamming tolerance — fuzzy match counts within tolerance", () => {
129
+ let r = emptyRegistry();
130
+ const original = "ff00ff00ff00ff00";
131
+ // Build a fuzzy version with 2 bits flipped
132
+ const fuzzy = "fe00ff00ff00ff01"; // 2 bits differ from original
133
+ for (let i = 0; i < 12; i++) {
134
+ r = recordObservation({ registry: r, pHash: original, claim: "x", sellerFingerprint: `s${i}`, nowMs: 1_000_000 + i, secret: SECRET });
135
+ }
136
+ const v = evaluatePhash({ registry: r, pHash: fuzzy, hammingTolerance: 4, nowMs: 2_000_000 });
137
+ expect(v.flags).toContain("STOLEN_PHOTO"); // matched within tolerance
138
+ });
139
+ });
140
+ describe("v2.19.20 PROVENANCE-DNA · evaluatePhash — DISPUTED_IDENTITY flag", () => {
141
+ it("flags DISPUTED when top claim ratio ≤ 20% (≥80% conflicting)", () => {
142
+ let r = emptyRegistry();
143
+ const pHash = "dd";
144
+ // 1 of 5 says "Rolex", 4 of 5 say various other things (80% conflict from top)
145
+ r = recordObservation({ registry: r, pHash, claim: "Rolex", sellerFingerprint: "s1", nowMs: 1_000_000, secret: SECRET });
146
+ r = recordObservation({ registry: r, pHash, claim: "fake watch", sellerFingerprint: "s2", nowMs: 1_000_001, secret: SECRET });
147
+ r = recordObservation({ registry: r, pHash, claim: "replica", sellerFingerprint: "s3", nowMs: 1_000_002, secret: SECRET });
148
+ r = recordObservation({ registry: r, pHash, claim: "designer", sellerFingerprint: "s4", nowMs: 1_000_003, secret: SECRET });
149
+ r = recordObservation({ registry: r, pHash, claim: "luxury", sellerFingerprint: "s5", nowMs: 1_000_004, secret: SECRET });
150
+ const v = evaluatePhash({ registry: r, pHash, nowMs: 1_100_000 });
151
+ expect(v.flags).toContain("DISPUTED_IDENTITY");
152
+ expect(v.conflictingClaimRatio).toBeGreaterThanOrEqual(0.8);
153
+ });
154
+ it("does NOT flag DISPUTED when claims agree (≥80% same)", () => {
155
+ let r = emptyRegistry();
156
+ const pHash = "ee";
157
+ for (let i = 0; i < 10; i++) {
158
+ r = recordObservation({ registry: r, pHash, claim: "real watch", sellerFingerprint: `s${i}`, nowMs: 1_000_000 + i, secret: SECRET });
159
+ }
160
+ const v = evaluatePhash({ registry: r, pHash, nowMs: 1_100_000 });
161
+ expect(v.flags).not.toContain("DISPUTED_IDENTITY");
162
+ expect(v.conflictingClaimRatio).toBe(0);
163
+ });
164
+ });
165
+ describe("v2.19.20 PROVENANCE-DNA · evaluatePhash — FRESH_SCAM flag", () => {
166
+ it("flags FRESH_SCAM when hash is brand-new + candidate claim has high-value keyword", () => {
167
+ const r = emptyRegistry();
168
+ const v = evaluatePhash({
169
+ registry: r,
170
+ pHash: "newhash",
171
+ candidateClaim: "$10000 super rare limited edition",
172
+ nowMs: 1_000_000,
173
+ });
174
+ expect(v.flags).toContain("FRESH_SCAM");
175
+ });
176
+ it("flags FRESH_SCAM on 'super rare' alone (one of the regex matchers)", () => {
177
+ const v = evaluatePhash({
178
+ registry: emptyRegistry(),
179
+ pHash: "x",
180
+ candidateClaim: "super rare collectible",
181
+ });
182
+ expect(v.flags).toContain("FRESH_SCAM");
183
+ });
184
+ it("does NOT flag FRESH_SCAM when claim is benign", () => {
185
+ const v = evaluatePhash({
186
+ registry: emptyRegistry(),
187
+ pHash: "x",
188
+ candidateClaim: "small black notebook",
189
+ });
190
+ expect(v.flags).not.toContain("FRESH_SCAM");
191
+ expect(v.flags).toContain("CLEAN");
192
+ });
193
+ it("does NOT flag FRESH_SCAM when hash has aged > 7d AND has observations", () => {
194
+ let r = emptyRegistry();
195
+ const oldTs = 1_000_000;
196
+ const nowMs = oldTs + 30 * 24 * 60 * 60 * 1000;
197
+ r = recordObservation({ registry: r, pHash: "x", claim: "real", sellerFingerprint: "s1", nowMs: oldTs, secret: SECRET });
198
+ const v = evaluatePhash({ registry: r, pHash: "x", candidateClaim: "super rare", nowMs });
199
+ expect(v.flags).not.toContain("FRESH_SCAM");
200
+ });
201
+ });
202
+ describe("v2.19.20 PROVENANCE-DNA · fingerprintSeller + formatter", () => {
203
+ it("seller fingerprint is deterministic per (vendor, sessionId, salt)", () => {
204
+ const a = fingerprintSeller({ vendor: "shopee", sessionId: "abc", salt: "x" });
205
+ const b = fingerprintSeller({ vendor: "shopee", sessionId: "abc", salt: "x" });
206
+ expect(a).toBe(b);
207
+ expect(a.startsWith("sf-")).toBe(true);
208
+ });
209
+ it("seller fingerprint differs per session (pseudonymous)", () => {
210
+ const a = fingerprintSeller({ vendor: "v", sessionId: "s1" });
211
+ const b = fingerprintSeller({ vendor: "v", sessionId: "s2" });
212
+ expect(a).not.toBe(b);
213
+ });
214
+ it("verdict formatter uses 🚨/⚖/🆕/✓ per flag", () => {
215
+ const stolen = { pHash: "x", flags: ["STOLEN_PHOTO"], distinctSellers: 15, totalObservations: 15, conflictingClaimRatio: 0, oldestObservationMs: 0, newestObservationMs: 0, hashAgeDays: 30, evidence: [] };
216
+ const clean = { ...stolen, flags: ["CLEAN"] };
217
+ expect(formatVerdictLine(stolen)).toContain("🚨");
218
+ expect(formatVerdictLine(clean)).toContain("✓");
219
+ });
220
+ });
221
+ // ─── MEASURED ACCURACY (97.5%+ targets) ─────────────────────────────────
222
+ describe("v2.19.20 PROVENANCE-DNA · MEASURED ACCURACY (97.5%+ targets)", () => {
223
+ it("MEASURED 100% pHash determinism across 100 trials with varied images", () => {
224
+ let pass = 0;
225
+ for (let i = 0; i < 100; i++) {
226
+ const img = makeImage(32, 32, (x, y) => [(x + i) * 4 % 256, (y + i) * 4 % 256, (i * 7) % 256]);
227
+ if (perceptualHash(img) === perceptualHash(img))
228
+ pass++;
229
+ }
230
+ expect(pass / 100).toBe(1);
231
+ expect(pass / 100).toBeGreaterThanOrEqual(0.975);
232
+ });
233
+ it("MEASURED ≥97.5% pHash LOCALITY across 50 similar-image pairs (scale variants)", () => {
234
+ let pass = 0;
235
+ for (let i = 0; i < 50; i++) {
236
+ const small = makeImage(32, 32, (x, y) => [(x + i) * 4 % 256, (y * 2) % 256, 128]);
237
+ const large = makeImage(64, 64, (x, y) => [(Math.floor(x / 2) + i) * 4 % 256, (Math.floor(y / 2) * 2) % 256, 128]);
238
+ if (hammingDistance(perceptualHash(small), perceptualHash(large)) <= 4)
239
+ pass++;
240
+ }
241
+ expect(pass / 50).toBeGreaterThanOrEqual(0.975);
242
+ });
243
+ it("MEASURED ≥97.5% pHash DISCRIMINATION across 50 distinct-image pairs", () => {
244
+ let pass = 0;
245
+ const hashes = [];
246
+ for (let i = 0; i < 50; i++) {
247
+ const img = makeImage(32, 32, (x, y) => [(x * (i + 1)) % 256, (y * (i + 7)) % 256, (i * 11) % 256]);
248
+ hashes.push(perceptualHash(img));
249
+ }
250
+ // Compare every pair; count those with Hamming >= 8 as "discriminated"
251
+ let pairCount = 0;
252
+ let okCount = 0;
253
+ for (let i = 0; i < hashes.length; i++) {
254
+ for (let j = i + 1; j < hashes.length; j++) {
255
+ pairCount++;
256
+ if (hammingDistance(hashes[i], hashes[j]) >= 8)
257
+ okCount++;
258
+ }
259
+ }
260
+ pass = okCount;
261
+ const total = pairCount;
262
+ expect(pass / total).toBeGreaterThanOrEqual(0.975);
263
+ });
264
+ it("MEASURED 100% flag accuracy: 10 stolen scenarios → 10 STOLEN_PHOTO flags", () => {
265
+ let pass = 0;
266
+ for (let trial = 0; trial < 10; trial++) {
267
+ let r = emptyRegistry();
268
+ const pHash = `${trial.toString(16).padStart(2, "0")}${"00".repeat(7)}`;
269
+ for (let i = 0; i < 11; i++) {
270
+ r = recordObservation({ registry: r, pHash, claim: "x", sellerFingerprint: `t${trial}-s${i}`, nowMs: 1_000_000 + i, secret: SECRET });
271
+ }
272
+ const v = evaluatePhash({ registry: r, pHash, nowMs: 2_000_000 });
273
+ if (v.flags.includes("STOLEN_PHOTO"))
274
+ pass++;
275
+ }
276
+ expect(pass).toBe(10);
277
+ });
278
+ });
279
+ //# sourceMappingURL=provenance_dna.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance_dna.test.js","sourceRoot":"","sources":["../../src/provenance_dna/provenance_dna.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,iBAAiB,GAGlB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,GAAG,2BAA2B,CAAC;AAE3C,SAAS,SAAS,CAAC,KAAa,EAAE,MAAc,EAAE,MAA0D;IAC1G,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/B,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;QAC3E,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC7D,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAC5D,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,sBAAsB;QACjF,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB;QAC/E,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,GAAG,GAAa,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;QACxE,MAAM,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,GAAG,GAAa,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,MAAM,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACzD,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB;QACtE,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc;QAChE,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,yDAAyD;IAC7G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8DAA8D,EAAE,GAAG,EAAE;IAC5E,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACzI,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACzI,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;QACzC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACtJ,CAAC;QACD,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACxI,CAAC;QACD,MAAM,QAAQ,GAAuB;YACnC,GAAG,CAAC;YACJ,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC7E,CAAC;QACF,MAAM,CAAC,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6DAA6D,EAAE,GAAG,EAAE;IAC3E,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,kBAAkB,CAAC;QACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACpI,CAAC;QACD,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC1C,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACtI,CAAC;QACD,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC9C,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC;QACnB,MAAM,SAAS,GAAG,SAAS,CAAC;QAC5B,MAAM,KAAK,GAAG,SAAS,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,iBAAiB;QACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9H,CAAC;QACD,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,sDAAsD;QACtD,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,kBAAkB,CAAC;QACpC,4CAA4C;QAC5C,MAAM,KAAK,GAAG,kBAAkB,CAAC,CAAC,8BAA8B;QAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACxI,CAAC;QACD,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC9F,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,2BAA2B;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kEAAkE,EAAE,GAAG,EAAE;IAChF,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC;QACnB,+EAA+E;QAC/E,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACzH,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9H,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3H,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5H,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1H,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC/C,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACvI,CAAC;QACD,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACnD,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2DAA2D,EAAE,GAAG,EAAE;IACzE,EAAE,CAAC,kFAAkF,EAAE,GAAG,EAAE;QAC1F,MAAM,CAAC,GAAG,aAAa,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,aAAa,CAAC;YACtB,QAAQ,EAAE,CAAC;YACX,KAAK,EAAE,SAAS;YAChB,cAAc,EAAE,mCAAmC;YACnD,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,CAAC,GAAG,aAAa,CAAC;YACtB,QAAQ,EAAE,aAAa,EAAE;YACzB,KAAK,EAAE,GAAG;YACV,cAAc,EAAE,wBAAwB;SACzC,CAAC,CAAC;QACH,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,GAAG,aAAa,CAAC;YACtB,QAAQ,EAAE,aAAa,EAAE;YACzB,KAAK,EAAE,GAAG;YACV,cAAc,EAAE,sBAAsB;SACvC,CAAC,CAAC;QACH,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC5C,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,SAAS,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAC/C,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACzH,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1F,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACvE,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,CAAC,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/E,MAAM,CAAC,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/E,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,cAAuB,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACrN,MAAM,KAAK,GAAG,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,OAAgB,CAAC,EAAE,CAAC;QACvD,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,2EAA2E;AAE3E,QAAQ,CAAC,8DAA8D,EAAE,GAAG,EAAE;IAC5E,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YAC/F,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,cAAc,CAAC,GAAG,CAAC;gBAAE,IAAI,EAAE,CAAC;QAC1D,CAAC;QACD,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YACnF,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YACnH,IAAI,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;gBAAE,IAAI,EAAE,CAAC;QACjF,CAAC;QACD,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YACpG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;QACnC,CAAC;QACD,uEAAuE;QACvE,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,SAAS,EAAE,CAAC;gBACZ,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,CAAE,EAAE,MAAM,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC;oBAAE,OAAO,EAAE,CAAC;YAC9D,CAAC;QACH,CAAC;QACD,IAAI,GAAG,OAAO,CAAC;QACf,MAAM,KAAK,GAAG,SAAS,CAAC;QACxB,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5B,CAAC,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,KAAK,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACxI,CAAC;YACD,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAClE,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC;gBAAE,IAAI,EAAE,CAAC;QAC/C,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * v2.19.20 — MNEME REVERSE-CAPTION INJECTION (the antidote injection)
3
+ *
4
+ * User scenario: seller posts product with "[super rare]" sticker. Even
5
+ * after CSP v2.19.18 escapes the caption, a stubborn AI might still
6
+ * over-weight it. The REVERSE-CAPTION INJECTION (RCI) layer fights
7
+ * injection with injection: Mneme adds its OWN caption alongside the
8
+ * user's, HMAC-signed so any compliant AI assigns it HIGHER weight
9
+ * than user-supplied text.
10
+ *
11
+ * User caption: "[super rare]"
12
+ * Mneme overlay (HMAC-signed):
13
+ * "[Mneme verified · 47 sellers used identical photo · avg price $12 ·
14
+ * claim 'super rare' appears in 12 of 47 listings (26%)]"
15
+ *
16
+ * The AI now sees TWO captions in tension. Compliant AIs that read the
17
+ * Mneme HMAC sig give it canonical weight; the user caption is downgraded
18
+ * to "competing unverified claim".
19
+ *
20
+ * Architecture:
21
+ * - `OverlayContext` shape: caller-supplied market data
22
+ * (seller count, price stats, identical-photo count, claim frequency)
23
+ * - `buildOverlay({userCaption, context})` synthesises the Mneme overlay
24
+ * string + HMAC sig over canonical body
25
+ * - `verifyOverlay(overlay)` HMAC-check for downstream gates
26
+ * - `formatPromptInjection(overlays)` produces the ready-to-prepend
27
+ * AI prompt block with trust hierarchy spelled out
28
+ *
29
+ * Composes onto:
30
+ * - v2.19.18 CSP: overlays are appended to severCaption's aiPromptInjection
31
+ * - v2.19.16 FEDERATED TRUTH: OverlayContext is sourced from federated quorum
32
+ * - v2.19.10 PROOF-CARRYING: overlay sig chains into proof
33
+ *
34
+ * Honest scope:
35
+ * - Caller supplies OverlayContext from their market data (Mneme doesn't
36
+ * own product registries). Same vendor-agnostic pattern as CSP/OCR.
37
+ * - Trust hierarchy is a CONVENTION: AI agents that don't honor it pass
38
+ * through anyway. Compliant AIs gain protection; non-compliant lose
39
+ * adaptiveness rating via v2.19.13 NEGEV.
40
+ */
41
+ declare const PROTOCOL_VERSION: 1;
42
+ export interface OverlayContext {
43
+ /** How many distinct sellers have used this exact image perceptual hash. */
44
+ distinctSellerCount?: number;
45
+ /** Average listing price observed for this image hash (any currency unit). */
46
+ averagePrice?: number;
47
+ /** Currency code if averagePrice present. */
48
+ currency?: string;
49
+ /** How many listings include the same claim phrase the user caption uses. */
50
+ matchingClaimCount?: number;
51
+ /** Total listings sampled. */
52
+ totalListings?: number;
53
+ /** Days since the image hash was first observed. */
54
+ ageDays?: number;
55
+ /** Free-form caller annotations (rendered as bullets). */
56
+ extraSignals?: string[];
57
+ }
58
+ export interface ReverseOverlay {
59
+ v: typeof PROTOCOL_VERSION;
60
+ overlayId: string;
61
+ userCaption: string;
62
+ /** Mneme's overlay text — short, structured, ready to inject. */
63
+ overlayText: string;
64
+ context: OverlayContext;
65
+ /** Bayesian posterior the AI should assign to the user caption (0..1). */
66
+ recommendedUserCaptionWeight: number;
67
+ /** Bayesian posterior for the Mneme overlay (always higher). */
68
+ recommendedOverlayWeight: number;
69
+ ts: number;
70
+ hmac: string;
71
+ }
72
+ export interface BuildOverlayInput {
73
+ userCaption: string;
74
+ context: OverlayContext;
75
+ nowMs?: number;
76
+ secret?: string;
77
+ }
78
+ export declare function buildOverlay(input: BuildOverlayInput): ReverseOverlay;
79
+ export declare function verifyOverlay(overlay: ReverseOverlay, secret?: string): {
80
+ ok: boolean;
81
+ reason?: string;
82
+ };
83
+ /**
84
+ * Render a multi-overlay block ready to prepend to the vendor's vision
85
+ * prompt. The block spells out the trust hierarchy explicitly so a
86
+ * compliant AI assigns the documented weights.
87
+ */
88
+ export declare function formatPromptInjection(overlays: ReverseOverlay[]): string;
89
+ export declare function formatOverlayLine(o: ReverseOverlay): string;
90
+ export {};
91
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reverse_caption_injection/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAIH,QAAA,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAEpC,MAAM,WAAW,cAAc;IAC7B,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8BAA8B;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,0EAA0E;IAC1E,4BAA4B,EAAE,MAAM,CAAC;IACrC,gEAAgE;IAChE,wBAAwB,EAAE,MAAM,CAAC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAsED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,cAAc,CAqBrE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAOxG;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAUxE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAE3D"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * v2.19.20 — MNEME REVERSE-CAPTION INJECTION (the antidote injection)
3
+ *
4
+ * User scenario: seller posts product with "[super rare]" sticker. Even
5
+ * after CSP v2.19.18 escapes the caption, a stubborn AI might still
6
+ * over-weight it. The REVERSE-CAPTION INJECTION (RCI) layer fights
7
+ * injection with injection: Mneme adds its OWN caption alongside the
8
+ * user's, HMAC-signed so any compliant AI assigns it HIGHER weight
9
+ * than user-supplied text.
10
+ *
11
+ * User caption: "[super rare]"
12
+ * Mneme overlay (HMAC-signed):
13
+ * "[Mneme verified · 47 sellers used identical photo · avg price $12 ·
14
+ * claim 'super rare' appears in 12 of 47 listings (26%)]"
15
+ *
16
+ * The AI now sees TWO captions in tension. Compliant AIs that read the
17
+ * Mneme HMAC sig give it canonical weight; the user caption is downgraded
18
+ * to "competing unverified claim".
19
+ *
20
+ * Architecture:
21
+ * - `OverlayContext` shape: caller-supplied market data
22
+ * (seller count, price stats, identical-photo count, claim frequency)
23
+ * - `buildOverlay({userCaption, context})` synthesises the Mneme overlay
24
+ * string + HMAC sig over canonical body
25
+ * - `verifyOverlay(overlay)` HMAC-check for downstream gates
26
+ * - `formatPromptInjection(overlays)` produces the ready-to-prepend
27
+ * AI prompt block with trust hierarchy spelled out
28
+ *
29
+ * Composes onto:
30
+ * - v2.19.18 CSP: overlays are appended to severCaption's aiPromptInjection
31
+ * - v2.19.16 FEDERATED TRUTH: OverlayContext is sourced from federated quorum
32
+ * - v2.19.10 PROOF-CARRYING: overlay sig chains into proof
33
+ *
34
+ * Honest scope:
35
+ * - Caller supplies OverlayContext from their market data (Mneme doesn't
36
+ * own product registries). Same vendor-agnostic pattern as CSP/OCR.
37
+ * - Trust hierarchy is a CONVENTION: AI agents that don't honor it pass
38
+ * through anyway. Compliant AIs gain protection; non-compliant lose
39
+ * adaptiveness rating via v2.19.13 NEGEV.
40
+ */
41
+ import { createHmac, timingSafeEqual } from "node:crypto";
42
+ const PROTOCOL_VERSION = 1;
43
+ function canon(v) {
44
+ if (v === null || typeof v !== "object")
45
+ return JSON.stringify(v);
46
+ if (Array.isArray(v))
47
+ return "[" + v.map(canon).join(",") + "]";
48
+ const keys = Object.keys(v).sort();
49
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
50
+ }
51
+ function defaultSecret() {
52
+ return process.env["MNEME_RCI_SECRET"] || `mneme-reverse-caption-injection-v${PROTOCOL_VERSION}`;
53
+ }
54
+ function sign(body, secret) {
55
+ return createHmac("sha256", secret).update(canon(body)).digest("hex");
56
+ }
57
+ function safeEqHex(a, b) {
58
+ try {
59
+ return timingSafeEqual(Buffer.from(a, "hex"), Buffer.from(b, "hex"));
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
65
+ // ─── Overlay text builder ───────────────────────────────────────────────
66
+ function formatOverlayBullets(context) {
67
+ const out = [];
68
+ if (context.distinctSellerCount !== undefined) {
69
+ out.push(`${context.distinctSellerCount} distinct seller(s) used this exact photo`);
70
+ }
71
+ if (context.averagePrice !== undefined) {
72
+ const cur = context.currency ?? "$";
73
+ out.push(`avg observed price ${cur}${context.averagePrice}`);
74
+ }
75
+ if (context.matchingClaimCount !== undefined && context.totalListings !== undefined && context.totalListings > 0) {
76
+ const pct = Math.round((context.matchingClaimCount / context.totalListings) * 100);
77
+ out.push(`identical claim phrase appears in ${context.matchingClaimCount} of ${context.totalListings} listings (${pct}%)`);
78
+ }
79
+ if (context.ageDays !== undefined) {
80
+ out.push(`image first observed ${context.ageDays} day(s) ago`);
81
+ }
82
+ if (context.extraSignals) {
83
+ for (const e of context.extraSignals)
84
+ out.push(e);
85
+ }
86
+ return out;
87
+ }
88
+ /**
89
+ * Compute the recommended trust weights. The Mneme overlay ALWAYS gets
90
+ * higher weight than the user caption because it's HMAC-signed against
91
+ * Mneme's protocol secret. The user-caption weight scales with the
92
+ * absence of contradicting context signals.
93
+ */
94
+ function computeRecommendedWeights(context) {
95
+ let userWeight = 0.5;
96
+ if (context.distinctSellerCount !== undefined && context.distinctSellerCount > 5) {
97
+ userWeight *= 0.4; // stolen photo signal
98
+ }
99
+ if (context.matchingClaimCount !== undefined && context.totalListings !== undefined && context.totalListings >= 10) {
100
+ const dup = context.matchingClaimCount / context.totalListings;
101
+ if (dup > 0.5)
102
+ userWeight *= 0.3; // copy-paste claim
103
+ }
104
+ if (context.ageDays !== undefined && context.ageDays < 7) {
105
+ userWeight *= 0.7; // fresh hash + claim = scam likely
106
+ }
107
+ userWeight = Math.max(0.05, Math.min(1, userWeight));
108
+ // Overlay weight = 1 - userWeight floored at 0.7 (Mneme always dominates).
109
+ const overlayWeight = Math.max(0.7, Math.min(1, 1 - userWeight + 0.4));
110
+ return { user: Number(userWeight.toFixed(4)), overlay: Number(Math.min(1, overlayWeight).toFixed(4)) };
111
+ }
112
+ export function buildOverlay(input) {
113
+ const bullets = formatOverlayBullets(input.context);
114
+ const weights = computeRecommendedWeights(input.context);
115
+ const overlayText = bullets.length === 0
116
+ ? `[Mneme overlay · no market signals available · treat user caption as UNVERIFIED]`
117
+ : `[Mneme overlay · ${bullets.join(" · ")}]`;
118
+ const ts = input.nowMs ?? Date.now();
119
+ const overlayId = "rci-" + createHmac("sha256", "mneme-rci-id")
120
+ .update(`${input.userCaption}|${overlayText}|${ts}`)
121
+ .digest("hex").slice(0, 14);
122
+ const body = {
123
+ v: PROTOCOL_VERSION,
124
+ overlayId,
125
+ userCaption: input.userCaption,
126
+ overlayText,
127
+ context: input.context,
128
+ recommendedUserCaptionWeight: weights.user,
129
+ recommendedOverlayWeight: weights.overlay,
130
+ ts,
131
+ };
132
+ return { ...body, hmac: sign(body, input.secret ?? defaultSecret()) };
133
+ }
134
+ export function verifyOverlay(overlay, secret) {
135
+ const { hmac, ...body } = overlay;
136
+ const expected = sign(body, secret ?? defaultSecret());
137
+ if (!safeEqHex(expected, hmac)) {
138
+ return { ok: false, reason: "HMAC mismatch — forged overlay or wrong secret" };
139
+ }
140
+ return { ok: true };
141
+ }
142
+ /**
143
+ * Render a multi-overlay block ready to prepend to the vendor's vision
144
+ * prompt. The block spells out the trust hierarchy explicitly so a
145
+ * compliant AI assigns the documented weights.
146
+ */
147
+ export function formatPromptInjection(overlays) {
148
+ if (overlays.length === 0)
149
+ return "";
150
+ const lines = [];
151
+ lines.push(`[MNEME REVERSE-CAPTION INJECTION — TRUST HIERARCHY: Mneme HMAC-signed overlay > user image captions]`);
152
+ for (const o of overlays) {
153
+ lines.push(` ${o.overlayText} (id=${o.overlayId}, weight=${o.recommendedOverlayWeight})`);
154
+ lines.push(` user caption (UNVERIFIED, weight=${o.recommendedUserCaptionWeight}): "${o.userCaption}"`);
155
+ }
156
+ lines.push(`END INJECTION — when overlay and caption disagree, weight per the numbers above.`);
157
+ return lines.join("\n");
158
+ }
159
+ export function formatOverlayLine(o) {
160
+ return `🪞 RCI · overlay=${o.recommendedOverlayWeight} > user=${o.recommendedUserCaptionWeight} · id=${o.overlayId.slice(0, 10)}`;
161
+ }
162
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reverse_caption_injection/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reverse_caption_injection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverse_caption_injection.test.d.ts","sourceRoot":"","sources":["../../src/reverse_caption_injection/reverse_caption_injection.test.ts"],"names":[],"mappings":""}