@paygentic/wrap 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plan.d.ts +35 -0
- package/dist/plan.d.ts.map +1 -1
- package/dist/plan.js +53 -21
- package/dist/plan.js.map +1 -1
- package/dist/plan.test.d.ts +2 -0
- package/dist/plan.test.d.ts.map +1 -0
- package/dist/plan.test.js +148 -0
- package/dist/plan.test.js.map +1 -0
- package/package.json +1 -1
package/dist/plan.d.ts
CHANGED
|
@@ -23,5 +23,40 @@ export declare function createPlanMethods(api: ApiClient): {
|
|
|
23
23
|
wrap: (customerId: string) => (params: QueryParams) => Promise<Query>;
|
|
24
24
|
}>;
|
|
25
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Calculate the budget threshold for splitting usage events.
|
|
28
|
+
* For dynamic: maxPrice
|
|
29
|
+
* For percentage: maxBudgetUsd (maxCharge / percentage)
|
|
30
|
+
*/
|
|
31
|
+
export declare function getMaxBudget(context: {
|
|
32
|
+
model: 'dynamic';
|
|
33
|
+
maxPrice: number;
|
|
34
|
+
} | {
|
|
35
|
+
model: 'percentage';
|
|
36
|
+
maxBudgetUsd: number;
|
|
37
|
+
}): number;
|
|
38
|
+
/**
|
|
39
|
+
* Calculate maxBudgetUsd for percentage pricing.
|
|
40
|
+
* maxBudgetUsd = maxCharge / percentage
|
|
41
|
+
* where percentage is a multiplier (e.g., 1.5 for 150% pricing)
|
|
42
|
+
*/
|
|
43
|
+
export declare function calculateMaxBudgetUsd(maxCharge: number, percentage: number): number;
|
|
44
|
+
/**
|
|
45
|
+
* Calculate usage events based on total cost and pricing context.
|
|
46
|
+
* Returns an array of { cost, useEntitlement } describing the events to create.
|
|
47
|
+
*
|
|
48
|
+
* For percentage model: splits at maxBudgetUsd, reports raw cost
|
|
49
|
+
* For dynamic model: splits at maxPrice, reports raw cost
|
|
50
|
+
*/
|
|
51
|
+
export declare function calculateUsageEvents(totalCost: number, context: {
|
|
52
|
+
model: 'dynamic';
|
|
53
|
+
maxPrice: number;
|
|
54
|
+
} | {
|
|
55
|
+
model: 'percentage';
|
|
56
|
+
maxBudgetUsd: number;
|
|
57
|
+
}): Array<{
|
|
58
|
+
cost: number;
|
|
59
|
+
useEntitlement: boolean;
|
|
60
|
+
}>;
|
|
26
61
|
export {};
|
|
27
62
|
//# sourceMappingURL=plan.d.ts.map
|
package/dist/plan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAgC,MAAM,gCAAgC,CAAC;AAC5F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKtD,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/C,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAMpD,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAoGD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS;IAE5C;;;;;;;;OAQG;qBACmB,eAAe;
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAgC,MAAM,gCAAgC,CAAC;AAC5F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKtD,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/C,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAMpD,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAoGD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS;IAE5C;;;;;;;;OAQG;qBACmB,eAAe;2BAuId,MAAM,cAyDY,WAAW,KAAG,OAAO,CAAC,KAAK,CAAC;;EArDxE;AAMD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEpI;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC9F,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,CAAC,CAWlD"}
|
package/dist/plan.js
CHANGED
|
@@ -163,9 +163,10 @@ export function createPlanMethods(api) {
|
|
|
163
163
|
if (maxCharge < 0.20) {
|
|
164
164
|
throw new Error(`maxCharge must be >= $0.20, got: $${maxCharge}`);
|
|
165
165
|
}
|
|
166
|
-
// Calculate maxBudgetUsd: usage_cost *
|
|
167
|
-
// So: usage_cost <= maxCharge /
|
|
168
|
-
|
|
166
|
+
// Calculate maxBudgetUsd: usage_cost * percentage <= maxCharge
|
|
167
|
+
// So: usage_cost <= maxCharge / percentage
|
|
168
|
+
// (percentage is a multiplier, e.g., 1.5 for 150% pricing)
|
|
169
|
+
const maxBudgetUsd = maxCharge / percentage;
|
|
169
170
|
const safeCost = Math.min(maxBudgetUsd * 0.9, maxBudgetUsd - 0.10);
|
|
170
171
|
context = {
|
|
171
172
|
model: 'percentage',
|
|
@@ -187,16 +188,42 @@ export function createPlanMethods(api) {
|
|
|
187
188
|
},
|
|
188
189
|
};
|
|
189
190
|
}
|
|
190
|
-
function calculateCharge(totalCost, context) {
|
|
191
|
-
if (context.model === 'dynamic') {
|
|
192
|
-
return totalCost;
|
|
193
|
-
}
|
|
194
|
-
const rawCharge = totalCost * (1 + context.percentage);
|
|
195
|
-
return Math.min(Math.max(rawCharge, context.minCharge), context.maxCharge);
|
|
196
|
-
}
|
|
197
191
|
function getMaxCharge(context) {
|
|
198
192
|
return context.model === 'dynamic' ? context.maxPrice : context.maxCharge;
|
|
199
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Calculate the budget threshold for splitting usage events.
|
|
196
|
+
* For dynamic: maxPrice
|
|
197
|
+
* For percentage: maxBudgetUsd (maxCharge / percentage)
|
|
198
|
+
*/
|
|
199
|
+
export function getMaxBudget(context) {
|
|
200
|
+
return context.model === 'dynamic' ? context.maxPrice : context.maxBudgetUsd;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Calculate maxBudgetUsd for percentage pricing.
|
|
204
|
+
* maxBudgetUsd = maxCharge / percentage
|
|
205
|
+
* where percentage is a multiplier (e.g., 1.5 for 150% pricing)
|
|
206
|
+
*/
|
|
207
|
+
export function calculateMaxBudgetUsd(maxCharge, percentage) {
|
|
208
|
+
return maxCharge / percentage;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Calculate usage events based on total cost and pricing context.
|
|
212
|
+
* Returns an array of { cost, useEntitlement } describing the events to create.
|
|
213
|
+
*
|
|
214
|
+
* For percentage model: splits at maxBudgetUsd, reports raw cost
|
|
215
|
+
* For dynamic model: splits at maxPrice, reports raw cost
|
|
216
|
+
*/
|
|
217
|
+
export function calculateUsageEvents(totalCost, context) {
|
|
218
|
+
const maxBudget = getMaxBudget(context);
|
|
219
|
+
if (totalCost > maxBudget) {
|
|
220
|
+
return [
|
|
221
|
+
{ cost: maxBudget, useEntitlement: true },
|
|
222
|
+
{ cost: totalCost - maxBudget, useEntitlement: false },
|
|
223
|
+
];
|
|
224
|
+
}
|
|
225
|
+
return [{ cost: totalCost, useEntitlement: true }];
|
|
226
|
+
}
|
|
200
227
|
function createWrappedQuery(api, customerId, planId, context) {
|
|
201
228
|
return async function wrappedQuery(params) {
|
|
202
229
|
const subscriptionMethods = createSubscriptionMethods(api);
|
|
@@ -238,19 +265,24 @@ function createWrappedQuery(api, customerId, planId, context) {
|
|
|
238
265
|
if (message.type === "result") {
|
|
239
266
|
const result = message;
|
|
240
267
|
const totalCost = result.total_cost_usd;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
268
|
+
// Determine the max budget threshold for splitting events
|
|
269
|
+
// For dynamic: split at maxPrice
|
|
270
|
+
// For percentage: split at maxBudgetUsd (maxCharge / percentage)
|
|
271
|
+
const maxBudget = context.model === 'dynamic'
|
|
272
|
+
? context.maxPrice
|
|
273
|
+
: context.maxBudgetUsd;
|
|
274
|
+
// Handle overage: if totalCost > maxBudget, split into two usage events
|
|
275
|
+
// Events report raw cost (not charge) - billing system applies percentage
|
|
276
|
+
if (totalCost > maxBudget) {
|
|
277
|
+
const overageCost = totalCost - maxBudget;
|
|
278
|
+
// First event: cost up to maxBudget (against entitlement)
|
|
279
|
+
await createUsageEvent(api, customerId, context.merchantId, context.billableMetricId, maxBudget, entitlement?.id);
|
|
280
|
+
// Second event: overage cost (no entitlement)
|
|
281
|
+
await createUsageEvent(api, customerId, context.merchantId, context.billableMetricId, overageCost);
|
|
250
282
|
}
|
|
251
283
|
else {
|
|
252
|
-
// Single usage event for the
|
|
253
|
-
await createUsageEvent(api, customerId, context.merchantId, context.billableMetricId,
|
|
284
|
+
// Single usage event for the total cost
|
|
285
|
+
await createUsageEvent(api, customerId, context.merchantId, context.billableMetricId, totalCost, entitlement?.id);
|
|
254
286
|
}
|
|
255
287
|
}
|
|
256
288
|
yield message;
|
package/dist/plan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.test.d.ts","sourceRoot":"","sources":["../src/plan.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { calculateMaxBudgetUsd, calculateUsageEvents, getMaxBudget } from './plan.js';
|
|
3
|
+
describe('calculateMaxBudgetUsd', () => {
|
|
4
|
+
it('calculates maxBudgetUsd correctly for 150% pricing (percentage = 1.5)', () => {
|
|
5
|
+
// percentage = 1.5 means charge = cost * 1.5
|
|
6
|
+
// maxCharge = 2
|
|
7
|
+
// maxBudgetUsd = maxCharge / percentage = 2 / 1.5 = 1.333333...
|
|
8
|
+
const maxBudgetUsd = calculateMaxBudgetUsd(2, 1.5);
|
|
9
|
+
expect(maxBudgetUsd).toBeCloseTo(1.333333, 5);
|
|
10
|
+
});
|
|
11
|
+
it('calculates maxBudgetUsd for 200% pricing (percentage = 2.0)', () => {
|
|
12
|
+
// percentage = 2.0 means charge = cost * 2
|
|
13
|
+
// maxCharge = 10
|
|
14
|
+
// maxBudgetUsd = 10 / 2 = 5
|
|
15
|
+
const maxBudgetUsd = calculateMaxBudgetUsd(10, 2.0);
|
|
16
|
+
expect(maxBudgetUsd).toBe(5);
|
|
17
|
+
});
|
|
18
|
+
it('calculates maxBudgetUsd for 100% pricing (no markup)', () => {
|
|
19
|
+
// percentage = 1.0 means charge = cost * 1 (pass-through)
|
|
20
|
+
// maxCharge = 5
|
|
21
|
+
// maxBudgetUsd = 5 / 1 = 5
|
|
22
|
+
const maxBudgetUsd = calculateMaxBudgetUsd(5, 1.0);
|
|
23
|
+
expect(maxBudgetUsd).toBe(5);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe('getMaxBudget', () => {
|
|
27
|
+
it('returns maxPrice for dynamic model', () => {
|
|
28
|
+
const maxBudget = getMaxBudget({ model: 'dynamic', maxPrice: 3.0 });
|
|
29
|
+
expect(maxBudget).toBe(3.0);
|
|
30
|
+
});
|
|
31
|
+
it('returns maxBudgetUsd for percentage model', () => {
|
|
32
|
+
const maxBudget = getMaxBudget({ model: 'percentage', maxBudgetUsd: 1.333333 });
|
|
33
|
+
expect(maxBudget).toBeCloseTo(1.333333, 5);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe('calculateUsageEvents - percentage model', () => {
|
|
37
|
+
/**
|
|
38
|
+
* User's exact case:
|
|
39
|
+
* - percentage: 1.5 (150% multiplier, meaning charge = cost * 1.5)
|
|
40
|
+
* - minCharge: 0
|
|
41
|
+
* - maxCharge: 2
|
|
42
|
+
* - maxBudgetUsd = maxCharge / percentage = 2 / 1.5 = 1.333333...
|
|
43
|
+
* - totalCost from agent: 2.1390795
|
|
44
|
+
*
|
|
45
|
+
* Expected events (raw cost, split at maxBudgetUsd):
|
|
46
|
+
* - Event 1: 1.333333 (maxBudgetUsd) - against entitlement
|
|
47
|
+
* - Event 2: 0.8057462 (totalCost - maxBudgetUsd) - overage
|
|
48
|
+
*/
|
|
49
|
+
it('splits cost at maxBudgetUsd when totalCost exceeds it', () => {
|
|
50
|
+
const totalCost = 2.1390795;
|
|
51
|
+
const maxBudgetUsd = calculateMaxBudgetUsd(2, 1.5); // 1.333333...
|
|
52
|
+
const events = calculateUsageEvents(totalCost, { model: 'percentage', maxBudgetUsd });
|
|
53
|
+
expect(events).toHaveLength(2);
|
|
54
|
+
// Event 1: maxBudgetUsd = 2 / 1.5 = 1.333333...
|
|
55
|
+
expect(events[0].cost).toBeCloseTo(1.333333, 5);
|
|
56
|
+
expect(events[0].useEntitlement).toBe(true);
|
|
57
|
+
// Event 2: overage = 2.1390795 - 1.333333 = 0.8057465
|
|
58
|
+
expect(events[1].cost).toBeCloseTo(0.8057462, 5);
|
|
59
|
+
expect(events[1].useEntitlement).toBe(false);
|
|
60
|
+
// Total should equal original totalCost
|
|
61
|
+
const totalEventCost = events[0].cost + events[1].cost;
|
|
62
|
+
expect(totalEventCost).toBeCloseTo(totalCost, 6);
|
|
63
|
+
});
|
|
64
|
+
it('creates single event when cost is within budget', () => {
|
|
65
|
+
const totalCost = 1.0; // Within maxBudgetUsd of 1.333333
|
|
66
|
+
const maxBudgetUsd = calculateMaxBudgetUsd(2, 1.5);
|
|
67
|
+
const events = calculateUsageEvents(totalCost, { model: 'percentage', maxBudgetUsd });
|
|
68
|
+
expect(events).toHaveLength(1);
|
|
69
|
+
expect(events[0].cost).toBe(1.0);
|
|
70
|
+
expect(events[0].useEntitlement).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
it('creates single event when cost exactly equals maxBudgetUsd', () => {
|
|
73
|
+
const maxBudgetUsd = calculateMaxBudgetUsd(2, 1.5); // 1.333333...
|
|
74
|
+
const totalCost = maxBudgetUsd;
|
|
75
|
+
const events = calculateUsageEvents(totalCost, { model: 'percentage', maxBudgetUsd });
|
|
76
|
+
expect(events).toHaveLength(1);
|
|
77
|
+
expect(events[0].cost).toBeCloseTo(maxBudgetUsd, 6);
|
|
78
|
+
expect(events[0].useEntitlement).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
it('handles very small overage correctly', () => {
|
|
81
|
+
const maxBudgetUsd = calculateMaxBudgetUsd(2, 1.5); // 1.333333...
|
|
82
|
+
const totalCost = maxBudgetUsd + 0.000001; // Just barely over
|
|
83
|
+
const events = calculateUsageEvents(totalCost, { model: 'percentage', maxBudgetUsd });
|
|
84
|
+
expect(events).toHaveLength(2);
|
|
85
|
+
expect(events[0].cost).toBeCloseTo(maxBudgetUsd, 6);
|
|
86
|
+
expect(events[1].cost).toBeCloseTo(0.000001, 6);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe('calculateUsageEvents - dynamic model', () => {
|
|
90
|
+
it('splits at maxPrice for dynamic model', () => {
|
|
91
|
+
const totalCost = 5.0;
|
|
92
|
+
const maxPrice = 3.0;
|
|
93
|
+
const events = calculateUsageEvents(totalCost, { model: 'dynamic', maxPrice });
|
|
94
|
+
expect(events).toHaveLength(2);
|
|
95
|
+
expect(events[0].cost).toBe(3.0);
|
|
96
|
+
expect(events[0].useEntitlement).toBe(true);
|
|
97
|
+
expect(events[1].cost).toBe(2.0);
|
|
98
|
+
expect(events[1].useEntitlement).toBe(false);
|
|
99
|
+
});
|
|
100
|
+
it('creates single event when within maxPrice', () => {
|
|
101
|
+
const totalCost = 2.0;
|
|
102
|
+
const maxPrice = 3.0;
|
|
103
|
+
const events = calculateUsageEvents(totalCost, { model: 'dynamic', maxPrice });
|
|
104
|
+
expect(events).toHaveLength(1);
|
|
105
|
+
expect(events[0].cost).toBe(2.0);
|
|
106
|
+
expect(events[0].useEntitlement).toBe(true);
|
|
107
|
+
});
|
|
108
|
+
it('creates single event when cost exactly equals maxPrice', () => {
|
|
109
|
+
const totalCost = 3.0;
|
|
110
|
+
const maxPrice = 3.0;
|
|
111
|
+
const events = calculateUsageEvents(totalCost, { model: 'dynamic', maxPrice });
|
|
112
|
+
expect(events).toHaveLength(1);
|
|
113
|
+
expect(events[0].cost).toBe(3.0);
|
|
114
|
+
expect(events[0].useEntitlement).toBe(true);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
describe('billing verification', () => {
|
|
118
|
+
it('verifies total charge equals expected for overage case', () => {
|
|
119
|
+
const totalCost = 2.1390795;
|
|
120
|
+
const percentage = 1.5;
|
|
121
|
+
const maxCharge = 2;
|
|
122
|
+
const maxBudgetUsd = calculateMaxBudgetUsd(maxCharge, percentage);
|
|
123
|
+
const events = calculateUsageEvents(totalCost, { model: 'percentage', maxBudgetUsd });
|
|
124
|
+
// Event 1 charge (capped at maxCharge): maxBudgetUsd * percentage = maxCharge
|
|
125
|
+
const event1Charge = Math.min(events[0].cost * percentage, maxCharge);
|
|
126
|
+
expect(event1Charge).toBeCloseTo(maxCharge, 6);
|
|
127
|
+
// Event 2 charge (overage, not capped): overage * percentage
|
|
128
|
+
const event2Charge = events[1].cost * percentage;
|
|
129
|
+
expect(event2Charge).toBeCloseTo((totalCost - maxBudgetUsd) * percentage, 6);
|
|
130
|
+
// Total charge = maxCharge + overage charge
|
|
131
|
+
const totalCharge = event1Charge + event2Charge;
|
|
132
|
+
// This equals totalCost * percentage (the full raw charge)
|
|
133
|
+
expect(totalCharge).toBeCloseTo(totalCost * percentage, 6);
|
|
134
|
+
});
|
|
135
|
+
it('verifies event costs sum to total cost', () => {
|
|
136
|
+
const testCases = [
|
|
137
|
+
{ totalCost: 2.1390795, maxBudgetUsd: 1.333333 },
|
|
138
|
+
{ totalCost: 5.0, maxBudgetUsd: 3.0 },
|
|
139
|
+
{ totalCost: 10.0, maxBudgetUsd: 2.5 },
|
|
140
|
+
];
|
|
141
|
+
for (const { totalCost, maxBudgetUsd } of testCases) {
|
|
142
|
+
const events = calculateUsageEvents(totalCost, { model: 'percentage', maxBudgetUsd });
|
|
143
|
+
const sum = events.reduce((acc, e) => acc + e.cost, 0);
|
|
144
|
+
expect(sum).toBeCloseTo(totalCost, 6);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
//# sourceMappingURL=plan.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.test.js","sourceRoot":"","sources":["../src/plan.test.ts"],"names":[],"mappings":"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"}
|