@stackedapp/utils 1.23.2 → 1.23.4
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/conditions/handlers.d.ts +41 -0
- package/dist/conditions/handlers.js +763 -0
- package/dist/conditions/helpers.d.ts +11 -0
- package/dist/conditions/helpers.js +256 -0
- package/dist/conditions/index.d.ts +97 -0
- package/dist/conditions/index.js +338 -0
- package/dist/dynamic.d.ts +2 -2
- package/dist/template.d.ts +2 -2
- package/package.json +1 -1
- package/dist/conditions.d.ts +0 -130
- package/dist/conditions.js +0 -1746
|
@@ -0,0 +1,763 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.evaluateDaysInGame = evaluateDaysInGame;
|
|
4
|
+
exports.evaluateTrustScore = evaluateTrustScore;
|
|
5
|
+
exports.evaluateLevel = evaluateLevel;
|
|
6
|
+
exports.evaluateCurrency = evaluateCurrency;
|
|
7
|
+
exports.evaluateStakedTokens = evaluateStakedTokens;
|
|
8
|
+
exports.evaluateLoginStreak = evaluateLoginStreak;
|
|
9
|
+
exports.evaluateAchievement = evaluateAchievement;
|
|
10
|
+
exports.evaluateMembership = evaluateMembership;
|
|
11
|
+
exports.evaluateQuest = evaluateQuest;
|
|
12
|
+
exports.evaluateEntityLink = evaluateEntityLink;
|
|
13
|
+
exports.evaluateDynamic = evaluateDynamic;
|
|
14
|
+
exports.evaluateIdentifiers = evaluateIdentifiers;
|
|
15
|
+
exports.evaluateTokenBalance = evaluateTokenBalance;
|
|
16
|
+
exports.evaluateStackedAccount = evaluateStackedAccount;
|
|
17
|
+
exports.evaluateUserSettings = evaluateUserSettings;
|
|
18
|
+
exports.evaluateCompletionContext = evaluateCompletionContext;
|
|
19
|
+
exports.evaluateBuyItem = evaluateBuyItem;
|
|
20
|
+
exports.evaluateSpendCurrency = evaluateSpendCurrency;
|
|
21
|
+
exports.evaluateDepositCurrency = evaluateDepositCurrency;
|
|
22
|
+
exports.evaluateLogin = evaluateLogin;
|
|
23
|
+
exports.evaluateSocial = evaluateSocial;
|
|
24
|
+
exports.evaluateLinkedCompletions = evaluateLinkedCompletions;
|
|
25
|
+
exports.evaluateDynamicTracker = evaluateDynamicTracker;
|
|
26
|
+
exports.evaluateContractInteraction = evaluateContractInteraction;
|
|
27
|
+
const types_1 = require("@stackedapp/types");
|
|
28
|
+
const template_1 = require("../template");
|
|
29
|
+
const dynamic_1 = require("../dynamic");
|
|
30
|
+
const helpers_1 = require("./helpers");
|
|
31
|
+
const blockchain_utils_1 = require("../blockchain_utils");
|
|
32
|
+
// ─── Base Condition Handlers ─────────────────────────────────────────────────
|
|
33
|
+
function evaluateDaysInGame(cond, ctx) {
|
|
34
|
+
const details = [];
|
|
35
|
+
let isMet = true;
|
|
36
|
+
if (cond.min) {
|
|
37
|
+
const trackerAmount = ctx.snap.daysInGame || 0;
|
|
38
|
+
const trackerGoal = cond.min;
|
|
39
|
+
const met = trackerAmount >= trackerGoal;
|
|
40
|
+
if (!met)
|
|
41
|
+
isMet = false;
|
|
42
|
+
details.push({
|
|
43
|
+
isMet: met, kind: 'daysInGame', trackerAmount, trackerGoal,
|
|
44
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
45
|
+
text: `More than ${trackerGoal} Days in Game`,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (cond.max) {
|
|
49
|
+
const trackerAmount = ctx.snap.daysInGame || 0;
|
|
50
|
+
const met = trackerAmount <= cond.max;
|
|
51
|
+
if (!met)
|
|
52
|
+
isMet = false;
|
|
53
|
+
details.push({
|
|
54
|
+
isMet: met, kind: 'daysInGame', trackerAmount, trackerGoal: cond.max,
|
|
55
|
+
percentCompleted: met ? 100 : 0,
|
|
56
|
+
text: `Less than ${cond.max} Days in Game`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return { isMet, details };
|
|
60
|
+
}
|
|
61
|
+
function evaluateTrustScore(cond, ctx) {
|
|
62
|
+
const details = [];
|
|
63
|
+
let isMet = true;
|
|
64
|
+
if (cond.min) {
|
|
65
|
+
const trackerAmount = ctx.snap.trustScore || 0;
|
|
66
|
+
const trackerGoal = cond.min;
|
|
67
|
+
const met = trackerAmount >= trackerGoal;
|
|
68
|
+
if (!met)
|
|
69
|
+
isMet = false;
|
|
70
|
+
details.push({
|
|
71
|
+
isMet: met, kind: 'trustScore', trackerAmount, trackerGoal,
|
|
72
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
73
|
+
text: `More than ${trackerGoal} Rep`,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (cond.max) {
|
|
77
|
+
const trackerAmount = ctx.snap.trustScore || 0;
|
|
78
|
+
const met = trackerAmount <= cond.max;
|
|
79
|
+
if (!met)
|
|
80
|
+
isMet = false;
|
|
81
|
+
details.push({
|
|
82
|
+
isMet: met, kind: 'trustScore', trackerAmount, trackerGoal: cond.max,
|
|
83
|
+
percentCompleted: met ? 100 : 0,
|
|
84
|
+
text: `Less than ${cond.max} Rep`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return { isMet, details };
|
|
88
|
+
}
|
|
89
|
+
function evaluateLevel(cond, ctx) {
|
|
90
|
+
const playerLevelData = ctx.snap.levels?.[cond.id];
|
|
91
|
+
const details = [];
|
|
92
|
+
let isMet = true;
|
|
93
|
+
if (cond.min) {
|
|
94
|
+
const trackerAmount = playerLevelData?.level || 0;
|
|
95
|
+
const trackerGoal = cond.min;
|
|
96
|
+
const met = trackerAmount >= trackerGoal;
|
|
97
|
+
if (!met)
|
|
98
|
+
isMet = false;
|
|
99
|
+
details.push({
|
|
100
|
+
isMet: met, kind: 'level', trackerAmount, trackerGoal,
|
|
101
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
102
|
+
text: `Be above level ${trackerGoal} ${cond.name}`,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
if (cond.max) {
|
|
106
|
+
const trackerAmount = playerLevelData?.level || 0;
|
|
107
|
+
const met = trackerAmount <= cond.max;
|
|
108
|
+
if (!met)
|
|
109
|
+
isMet = false;
|
|
110
|
+
details.push({
|
|
111
|
+
isMet: met, kind: 'level', trackerAmount, trackerGoal: cond.max,
|
|
112
|
+
percentCompleted: met ? 100 : 0,
|
|
113
|
+
text: `Be under level ${cond.max} ${cond.name}`,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return { isMet, details };
|
|
117
|
+
}
|
|
118
|
+
function evaluateCurrency(cond, ctx) {
|
|
119
|
+
const playerCurrencyData = ctx.snap.currencies?.[cond.id];
|
|
120
|
+
const details = [];
|
|
121
|
+
let isMet = true;
|
|
122
|
+
if (cond.min) {
|
|
123
|
+
const trackerAmount = playerCurrencyData?.balance || 0;
|
|
124
|
+
const trackerGoal = cond.min;
|
|
125
|
+
const met = trackerAmount >= trackerGoal;
|
|
126
|
+
if (!met)
|
|
127
|
+
isMet = false;
|
|
128
|
+
details.push({
|
|
129
|
+
isMet: met, kind: 'currency', trackerAmount, trackerGoal,
|
|
130
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
131
|
+
text: `Have more than ${trackerGoal} ${cond.name}`,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (cond.max) {
|
|
135
|
+
const trackerAmount = playerCurrencyData?.balance || 0;
|
|
136
|
+
const met = trackerAmount <= cond.max;
|
|
137
|
+
if (!met)
|
|
138
|
+
isMet = false;
|
|
139
|
+
details.push({
|
|
140
|
+
isMet: met, kind: 'currency', trackerAmount, trackerGoal: cond.max,
|
|
141
|
+
percentCompleted: met ? 100 : 0,
|
|
142
|
+
text: `Have less than ${cond.max} ${cond.name}`,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (cond.in) {
|
|
146
|
+
const trackerAmount = playerCurrencyData?.in || 0;
|
|
147
|
+
const trackerGoal = cond.in;
|
|
148
|
+
const met = trackerAmount >= trackerGoal;
|
|
149
|
+
if (!met)
|
|
150
|
+
isMet = false;
|
|
151
|
+
details.push({
|
|
152
|
+
isMet: met, kind: 'currency', trackerAmount, trackerGoal,
|
|
153
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
154
|
+
text: `Deposit at least ${trackerGoal} ${cond.name}`,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (cond.out) {
|
|
158
|
+
const trackerAmount = playerCurrencyData?.out || 0;
|
|
159
|
+
const trackerGoal = cond.out;
|
|
160
|
+
const met = trackerAmount >= trackerGoal;
|
|
161
|
+
if (!met)
|
|
162
|
+
isMet = false;
|
|
163
|
+
details.push({
|
|
164
|
+
isMet: met, kind: 'currency', trackerAmount, trackerGoal,
|
|
165
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
166
|
+
text: `Withdraw at least ${trackerGoal} ${cond.name}`,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return { isMet, details };
|
|
170
|
+
}
|
|
171
|
+
function evaluateStakedTokens(cond, ctx) {
|
|
172
|
+
const playerStakedData = ctx.snap.stakedTokens?.[cond.id];
|
|
173
|
+
let isMet = true;
|
|
174
|
+
const details = [];
|
|
175
|
+
if (cond.min) {
|
|
176
|
+
const trackerAmount = playerStakedData?.balance || 0;
|
|
177
|
+
const trackerGoal = cond.min;
|
|
178
|
+
const met = trackerAmount >= trackerGoal;
|
|
179
|
+
if (!met)
|
|
180
|
+
isMet = false;
|
|
181
|
+
details.push({
|
|
182
|
+
isMet: met, kind: 'stakedTokens', trackerAmount, trackerGoal,
|
|
183
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
184
|
+
text: `Have at least ${trackerGoal} ${cond.name} staked`,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return { isMet, details };
|
|
188
|
+
}
|
|
189
|
+
function evaluateLoginStreak(cond, ctx) {
|
|
190
|
+
let trackerAmount;
|
|
191
|
+
if (ctx.completionTrackers?.currentLoginStreak != null) {
|
|
192
|
+
// Completion context: streak gained since offer surfaced
|
|
193
|
+
trackerAmount = (ctx.snap.loginStreak || 0) - (ctx.completionTrackers.currentLoginStreak || 0) + 1;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// Surfacing context: absolute streak
|
|
197
|
+
trackerAmount = ctx.snap.loginStreak || 0;
|
|
198
|
+
}
|
|
199
|
+
const trackerGoal = cond.days;
|
|
200
|
+
const isMet = trackerAmount >= trackerGoal;
|
|
201
|
+
return {
|
|
202
|
+
isMet,
|
|
203
|
+
details: [{
|
|
204
|
+
isMet, kind: 'loginStreak', trackerAmount, trackerGoal,
|
|
205
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, isMet),
|
|
206
|
+
text: `Login streak of ${trackerGoal || 0} days`,
|
|
207
|
+
}],
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function evaluateAchievement(cond, ctx) {
|
|
211
|
+
const playerAchData = ctx.snap.achievements?.[cond.id];
|
|
212
|
+
const details = [];
|
|
213
|
+
let isMet = true;
|
|
214
|
+
if (!playerAchData) {
|
|
215
|
+
isMet = false;
|
|
216
|
+
details.push({
|
|
217
|
+
isMet: false, kind: 'achievement', trackerAmount: 0, trackerGoal: 1,
|
|
218
|
+
percentCompleted: 0,
|
|
219
|
+
text: `Have the achievement ${cond.name}`,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (cond.minCount) {
|
|
223
|
+
const trackerAmount = playerAchData?.count || 0;
|
|
224
|
+
const trackerGoal = cond.minCount;
|
|
225
|
+
const met = trackerAmount >= trackerGoal;
|
|
226
|
+
if (!met)
|
|
227
|
+
isMet = false;
|
|
228
|
+
details.push({
|
|
229
|
+
isMet: met, kind: 'achievement', trackerAmount, trackerGoal,
|
|
230
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
231
|
+
text: `Have the achievement ${cond.name} more than ${trackerGoal} times`,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return { isMet, details };
|
|
235
|
+
}
|
|
236
|
+
function evaluateMembership(cond, ctx) {
|
|
237
|
+
const playerData = ctx.snap.memberships?.[cond.id];
|
|
238
|
+
const details = [];
|
|
239
|
+
let isMet = true;
|
|
240
|
+
if (cond.minCount) {
|
|
241
|
+
const trackerAmount = playerData?.count || 0;
|
|
242
|
+
const trackerGoal = cond.minCount;
|
|
243
|
+
const met = trackerAmount >= trackerGoal;
|
|
244
|
+
if (!met)
|
|
245
|
+
isMet = false;
|
|
246
|
+
details.push({
|
|
247
|
+
isMet: met, kind: 'membership', trackerAmount, trackerGoal,
|
|
248
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
249
|
+
text: trackerGoal > 1 ? `Have at least ${trackerGoal} ${cond.name} memberships` : `Have a ${cond.name} membership`,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (cond.maxCount) {
|
|
253
|
+
const trackerAmount = playerData?.count || 0;
|
|
254
|
+
const met = trackerAmount <= cond.maxCount;
|
|
255
|
+
if (!met)
|
|
256
|
+
isMet = false;
|
|
257
|
+
details.push({
|
|
258
|
+
isMet: met, kind: 'membership', trackerAmount, trackerGoal: cond.maxCount,
|
|
259
|
+
percentCompleted: met ? 100 : 0,
|
|
260
|
+
text: `Have less than ${cond.maxCount} ${cond.name} memberships`,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
const timeOwned = (playerData?.expiresAt || 0) - Date.now();
|
|
264
|
+
if (cond.minMs) {
|
|
265
|
+
const trackerAmount = Number((timeOwned / (1000 * 60 * 60 * 24)).toFixed(1));
|
|
266
|
+
const trackerGoal = Number((cond.minMs / (1000 * 60 * 60 * 24)).toFixed(1));
|
|
267
|
+
const met = timeOwned >= cond.minMs;
|
|
268
|
+
if (!met)
|
|
269
|
+
isMet = false;
|
|
270
|
+
details.push({
|
|
271
|
+
isMet: met, kind: 'membership', trackerAmount, trackerGoal,
|
|
272
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, met),
|
|
273
|
+
text: `Own ${cond.name} membership for at least ${trackerGoal} days`,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
if (cond.maxMs) {
|
|
277
|
+
const trackerAmount = Number((timeOwned / (1000 * 60 * 60 * 24)).toFixed(1));
|
|
278
|
+
const met = timeOwned <= cond.maxMs;
|
|
279
|
+
if (!met)
|
|
280
|
+
isMet = false;
|
|
281
|
+
details.push({
|
|
282
|
+
isMet: met, kind: 'membership', trackerAmount,
|
|
283
|
+
trackerGoal: Number((cond.maxMs / (1000 * 60 * 60 * 24)).toFixed(1)),
|
|
284
|
+
percentCompleted: met ? 100 : 0,
|
|
285
|
+
text: `Own ${cond.name} membership for less than ${(cond.maxMs / (1000 * 60 * 60 * 24)).toFixed(1)} days`,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
return { isMet, details };
|
|
289
|
+
}
|
|
290
|
+
function evaluateQuest(cond, ctx) {
|
|
291
|
+
const playerQuestData = ctx.snap.quests?.[cond.id];
|
|
292
|
+
const trackerAmount = playerQuestData?.completions || 0;
|
|
293
|
+
const trackerGoal = cond.completions || 1;
|
|
294
|
+
const isMet = playerQuestData ? trackerAmount >= (cond.completions || 0) : false;
|
|
295
|
+
return {
|
|
296
|
+
isMet,
|
|
297
|
+
details: [{
|
|
298
|
+
isMet, kind: 'quest', trackerAmount, trackerGoal,
|
|
299
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, isMet),
|
|
300
|
+
text: cond.completions === 1
|
|
301
|
+
? `Complete the quest ${cond.name}`
|
|
302
|
+
: (cond.completions || 0) < 1
|
|
303
|
+
? `Start the quest ${cond.name}`
|
|
304
|
+
: `Complete the quest ${cond.name} ${cond.completions} times`,
|
|
305
|
+
}],
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function evaluateEntityLink(cond, ctx) {
|
|
309
|
+
const linkCount = ctx.snap.entityLinks?.filter((link) => (link.kind || types_1.DEFAULT_ENTITY_KIND) === cond.linkKind).length || 0;
|
|
310
|
+
const details = [];
|
|
311
|
+
let isMet = true;
|
|
312
|
+
const makeText = (fallback) => cond.template
|
|
313
|
+
? (0, template_1.renderTemplate)(cond.template, {
|
|
314
|
+
current: linkCount, min: cond.min ?? 0, max: cond.max ?? 0, type: cond.linkKind,
|
|
315
|
+
})
|
|
316
|
+
: fallback;
|
|
317
|
+
if (cond.min !== undefined) {
|
|
318
|
+
const met = linkCount >= cond.min;
|
|
319
|
+
if (!met)
|
|
320
|
+
isMet = false;
|
|
321
|
+
details.push({
|
|
322
|
+
isMet: met, kind: 'entityLink', trackerAmount: linkCount, trackerGoal: cond.min,
|
|
323
|
+
percentCompleted: (0, helpers_1.calculatePercent)(linkCount, cond.min, met),
|
|
324
|
+
text: makeText(`At least ${cond.min} ${cond.linkKind} link(s)`),
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
if (cond.max !== undefined) {
|
|
328
|
+
const met = linkCount <= cond.max;
|
|
329
|
+
if (!met)
|
|
330
|
+
isMet = false;
|
|
331
|
+
details.push({
|
|
332
|
+
isMet: met, kind: 'entityLink', trackerAmount: linkCount, trackerGoal: cond.max,
|
|
333
|
+
percentCompleted: met ? 100 : 0,
|
|
334
|
+
text: makeText(`At most ${cond.max} ${cond.linkKind} link(s)`),
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return { isMet, details };
|
|
338
|
+
}
|
|
339
|
+
function evaluateDynamic(cond, ctx) {
|
|
340
|
+
const resolvedConditions = (0, template_1.replaceDynamicConditionKeys)(cond.conditions, ctx.offerTrackers || {});
|
|
341
|
+
const dynamicObj = (ctx.snap.dynamic || {});
|
|
342
|
+
const dynamicResult = (0, helpers_1.meetsDynamicConditions)(dynamicObj, { ...cond, conditions: resolvedConditions });
|
|
343
|
+
let trackerAmount;
|
|
344
|
+
let trackerGoal;
|
|
345
|
+
if (resolvedConditions.length > 0) {
|
|
346
|
+
const firstCond = resolvedConditions[0];
|
|
347
|
+
if (typeof firstCond.compareTo === 'number')
|
|
348
|
+
trackerGoal = firstCond.compareTo;
|
|
349
|
+
const val = dynamicObj[firstCond.key];
|
|
350
|
+
trackerAmount = typeof val === 'number' ? val : 0;
|
|
351
|
+
}
|
|
352
|
+
const percentCompleted = (0, helpers_1.calculateDynamicGroupPercent)(dynamicObj, { ...cond, conditions: resolvedConditions });
|
|
353
|
+
return {
|
|
354
|
+
isMet: dynamicResult,
|
|
355
|
+
details: [{
|
|
356
|
+
isMet: dynamicResult, kind: 'dynamic', trackerAmount, trackerGoal, percentCompleted,
|
|
357
|
+
text: (0, template_1.renderTemplate)((0, template_1.replaceDynamicConditionKey)(cond.template || '', ctx.offerTrackers || {}), dynamicObj) || 'Dynamic conditions',
|
|
358
|
+
}],
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
function evaluateIdentifiers(cond, ctx) {
|
|
362
|
+
const playerPlatforms = new Set(ctx.snap.identifiers?.map((i) => i.platform.toLowerCase()) || []);
|
|
363
|
+
const platformsToCheck = cond.platforms;
|
|
364
|
+
const platformsMap = {
|
|
365
|
+
sms: 'SMS', email: 'Email', apple: 'Apple', google: 'Google', tiktok: 'TikTok',
|
|
366
|
+
};
|
|
367
|
+
const metPlatforms = platformsToCheck.filter((p) => playerPlatforms.has(p.toLowerCase()));
|
|
368
|
+
const platforms = platformsToCheck.map((p) => platformsMap[p.toLowerCase()] ?? p);
|
|
369
|
+
let isMet;
|
|
370
|
+
let displayText;
|
|
371
|
+
let percentCompleted;
|
|
372
|
+
if (cond.behaviour === 'AND') {
|
|
373
|
+
isMet = metPlatforms.length === platformsToCheck.length;
|
|
374
|
+
displayText = platformsToCheck.length > 1
|
|
375
|
+
? `Link your ${(0, helpers_1.formatList)(platforms)} accounts`
|
|
376
|
+
: `Link your ${platforms[0]} account`;
|
|
377
|
+
percentCompleted = (0, helpers_1.calculatePercent)(metPlatforms.length, platformsToCheck.length, isMet);
|
|
378
|
+
}
|
|
379
|
+
else if (cond.behaviour === 'NOT') {
|
|
380
|
+
isMet = metPlatforms.length === 0;
|
|
381
|
+
displayText = `Must not have ${(0, helpers_1.formatList)(platforms)} linked`;
|
|
382
|
+
percentCompleted = isMet ? 100 : 0;
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
isMet = platformsToCheck.some((p) => playerPlatforms.has(p.toLowerCase()));
|
|
386
|
+
displayText = `Link any of your ${(0, helpers_1.formatList)(platforms)} accounts`;
|
|
387
|
+
percentCompleted = isMet ? 100 : 0;
|
|
388
|
+
}
|
|
389
|
+
return {
|
|
390
|
+
isMet,
|
|
391
|
+
details: [{
|
|
392
|
+
isMet, kind: 'identifiers',
|
|
393
|
+
trackerAmount: isMet ? 1 : 0, trackerGoal: 1,
|
|
394
|
+
percentCompleted,
|
|
395
|
+
text: displayText,
|
|
396
|
+
}],
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function evaluateTokenBalance(cond, ctx) {
|
|
400
|
+
const contracts = cond.contracts || [];
|
|
401
|
+
let totalBalance = 0;
|
|
402
|
+
const fetchedBalances = (0, helpers_1.aggregateTokenBalances)(ctx.additionalData);
|
|
403
|
+
for (const contract of contracts) {
|
|
404
|
+
const balanceKey = (0, blockchain_utils_1.addressNetworkId)(contract.contractAddress, contract.network);
|
|
405
|
+
totalBalance += fetchedBalances[balanceKey] || 0;
|
|
406
|
+
}
|
|
407
|
+
const details = [];
|
|
408
|
+
let isMet = true;
|
|
409
|
+
if (cond.min !== undefined) {
|
|
410
|
+
const met = totalBalance >= cond.min;
|
|
411
|
+
if (!met)
|
|
412
|
+
isMet = false;
|
|
413
|
+
details.push({
|
|
414
|
+
isMet: met, kind: 'tokenBalance', trackerAmount: totalBalance, trackerGoal: cond.min,
|
|
415
|
+
percentCompleted: (0, helpers_1.calculatePercent)(totalBalance, cond.min, met),
|
|
416
|
+
text: `Have at least ${cond.min} ${cond.name || 'tokens'}`,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
if (cond.max !== undefined) {
|
|
420
|
+
const met = totalBalance <= cond.max;
|
|
421
|
+
if (!met)
|
|
422
|
+
isMet = false;
|
|
423
|
+
details.push({
|
|
424
|
+
isMet: met, kind: 'tokenBalance', trackerAmount: totalBalance, trackerGoal: cond.max,
|
|
425
|
+
percentCompleted: met ? 100 : 0,
|
|
426
|
+
text: `Have at most ${cond.max} ${cond.name || 'tokens'}`,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
return { isMet, details };
|
|
430
|
+
}
|
|
431
|
+
function evaluateStackedAccount(cond, ctx) {
|
|
432
|
+
const details = [];
|
|
433
|
+
let isMet = true;
|
|
434
|
+
if (cond.hasLinkedAccount !== undefined) {
|
|
435
|
+
const playerHasAccount = ctx.additionalData?.hasStackedAccount ?? false;
|
|
436
|
+
const met = cond.hasLinkedAccount === playerHasAccount;
|
|
437
|
+
if (!met)
|
|
438
|
+
isMet = false;
|
|
439
|
+
details.push({
|
|
440
|
+
isMet: met, kind: 'stackedAccount',
|
|
441
|
+
trackerAmount: playerHasAccount ? 1 : 0, trackerGoal: 1,
|
|
442
|
+
percentCompleted: met ? 100 : 0,
|
|
443
|
+
text: cond.hasLinkedAccount ? 'Link a Stacked account' : 'Must not have Stacked account linked',
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
if (cond.cryptoWallets) {
|
|
447
|
+
const walletCount = ctx.additionalData?.cryptoWallets?.length || 0;
|
|
448
|
+
if (cond.cryptoWallets.min !== undefined) {
|
|
449
|
+
const met = walletCount >= cond.cryptoWallets.min;
|
|
450
|
+
if (!met)
|
|
451
|
+
isMet = false;
|
|
452
|
+
details.push({
|
|
453
|
+
isMet: met, kind: 'stackedAccount',
|
|
454
|
+
trackerAmount: walletCount, trackerGoal: cond.cryptoWallets.min,
|
|
455
|
+
percentCompleted: (0, helpers_1.calculatePercent)(walletCount, cond.cryptoWallets.min, met),
|
|
456
|
+
text: `Link at least ${cond.cryptoWallets.min} crypto wallet${cond.cryptoWallets.min === 1 ? '' : 's'}`,
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
if (cond.cryptoWallets.max !== undefined) {
|
|
460
|
+
const met = walletCount <= cond.cryptoWallets.max;
|
|
461
|
+
if (!met)
|
|
462
|
+
isMet = false;
|
|
463
|
+
details.push({
|
|
464
|
+
isMet: met, kind: 'stackedAccount',
|
|
465
|
+
trackerAmount: walletCount, trackerGoal: cond.cryptoWallets.max,
|
|
466
|
+
percentCompleted: met ? 100 : 0,
|
|
467
|
+
text: `Have at most ${cond.cryptoWallets.max} crypto wallet${cond.cryptoWallets.max === 1 ? '' : 's'}`,
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return { isMet, details };
|
|
472
|
+
}
|
|
473
|
+
function evaluateUserSettings(cond, ctx) {
|
|
474
|
+
const details = [];
|
|
475
|
+
let isMet = true;
|
|
476
|
+
if (cond.emailNewsletter !== undefined) {
|
|
477
|
+
const playerHasNewsletter = ctx.additionalData?.emailNewsletter ?? false;
|
|
478
|
+
const met = cond.emailNewsletter === playerHasNewsletter;
|
|
479
|
+
if (!met)
|
|
480
|
+
isMet = false;
|
|
481
|
+
details.push({
|
|
482
|
+
isMet: met, kind: 'userSettings',
|
|
483
|
+
trackerAmount: playerHasNewsletter ? 1 : 0, trackerGoal: 1,
|
|
484
|
+
percentCompleted: met ? 100 : 0,
|
|
485
|
+
text: cond.emailNewsletter ? 'Subscribe to email newsletter' : 'Must not be subscribed to email newsletter',
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
return { isMet, details };
|
|
489
|
+
}
|
|
490
|
+
// ─── Completion-Only Condition Handlers ──────────────────────────────────────
|
|
491
|
+
function evaluateCompletionContext(cond, ctx) {
|
|
492
|
+
const hasTrackedContext = ctx.completionTrackers?.context && cond.id === ctx.completionTrackers.context;
|
|
493
|
+
const isMet = !!hasTrackedContext;
|
|
494
|
+
return {
|
|
495
|
+
isMet,
|
|
496
|
+
details: [{
|
|
497
|
+
isMet, kind: 'completionContext',
|
|
498
|
+
trackerAmount: isMet ? 1 : 0, trackerGoal: 1,
|
|
499
|
+
percentCompleted: isMet ? 100 : 0,
|
|
500
|
+
text: cond.name,
|
|
501
|
+
}],
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
function evaluateBuyItem(cond, ctx) {
|
|
505
|
+
const baseAmount = cond.amount || 1;
|
|
506
|
+
const scaledAmount = baseAmount * ctx.claimMultiplier;
|
|
507
|
+
const trackerValue = ctx.completionTrackers?.buyItem || 0;
|
|
508
|
+
const isMet = trackerValue >= scaledAmount;
|
|
509
|
+
return {
|
|
510
|
+
isMet,
|
|
511
|
+
details: [{
|
|
512
|
+
isMet, kind: 'buyItem', trackerAmount: trackerValue, trackerGoal: scaledAmount,
|
|
513
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerValue, scaledAmount, isMet),
|
|
514
|
+
text: `Buy ${scaledAmount} ${cond.name}`,
|
|
515
|
+
}],
|
|
516
|
+
maxClaims: ctx.shouldScale && baseAmount > 0 ? Math.floor(trackerValue / baseAmount) : undefined,
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
function evaluateSpendCurrency(cond, ctx) {
|
|
520
|
+
const baseAmount = cond.amount || 1;
|
|
521
|
+
const scaledAmount = baseAmount * ctx.claimMultiplier;
|
|
522
|
+
const trackerValue = ctx.completionTrackers?.spendCurrency || 0;
|
|
523
|
+
const isMet = trackerValue >= scaledAmount;
|
|
524
|
+
return {
|
|
525
|
+
isMet,
|
|
526
|
+
details: [{
|
|
527
|
+
isMet, kind: 'spendCurrency', trackerAmount: trackerValue, trackerGoal: scaledAmount,
|
|
528
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerValue, scaledAmount, isMet),
|
|
529
|
+
text: `Spend ${scaledAmount} ${cond.name}`,
|
|
530
|
+
}],
|
|
531
|
+
maxClaims: ctx.shouldScale && baseAmount > 0 ? Math.floor(trackerValue / baseAmount) : undefined,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function evaluateDepositCurrency(cond, ctx) {
|
|
535
|
+
const baseAmount = cond.amount || 1;
|
|
536
|
+
const scaledAmount = baseAmount * ctx.claimMultiplier;
|
|
537
|
+
const trackerValue = ctx.completionTrackers?.depositCurrency || 0;
|
|
538
|
+
const isMet = trackerValue >= scaledAmount;
|
|
539
|
+
return {
|
|
540
|
+
isMet,
|
|
541
|
+
details: [{
|
|
542
|
+
isMet, kind: 'depositCurrency', trackerAmount: trackerValue, trackerGoal: scaledAmount,
|
|
543
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerValue, scaledAmount, isMet),
|
|
544
|
+
text: `Deposit ${scaledAmount} ${cond.name}`,
|
|
545
|
+
}],
|
|
546
|
+
maxClaims: ctx.shouldScale && baseAmount > 0 ? Math.floor(trackerValue / baseAmount) : undefined,
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
function evaluateLogin(_cond, ctx) {
|
|
550
|
+
const isMet = new Date(ctx.snap.snapshotLastUpdated || 0).getTime() > new Date(ctx.offerCreatedAt || 0).getTime();
|
|
551
|
+
return {
|
|
552
|
+
isMet,
|
|
553
|
+
details: [{
|
|
554
|
+
isMet, kind: 'login',
|
|
555
|
+
trackerAmount: isMet ? 1 : 0, trackerGoal: 1,
|
|
556
|
+
percentCompleted: isMet ? 100 : 0,
|
|
557
|
+
text: 'Login to the game',
|
|
558
|
+
}],
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
function evaluateSocial(cond, ctx) {
|
|
562
|
+
const tSocialAccumulate = ctx.completionTrackers?.social;
|
|
563
|
+
const tSocialAttach = ctx.completionTrackers?.social;
|
|
564
|
+
const mode = cond.mode || 'attach';
|
|
565
|
+
const tSocial = mode === 'accumulate' ? tSocialAccumulate : tSocialAttach;
|
|
566
|
+
const hasContent = Boolean(mode === 'accumulate' ? (tSocialAccumulate?.matchCount ?? 0) > 0 : tSocialAttach?.videoId);
|
|
567
|
+
const socialMultiplier = mode === 'accumulate' ? ctx.claimMultiplier : 1;
|
|
568
|
+
const minLikes = (cond.minLikes || 0) * socialMultiplier;
|
|
569
|
+
const minViews = (cond.minViews || 0) * socialMultiplier;
|
|
570
|
+
const minComments = (cond.minComments || 0) * socialMultiplier;
|
|
571
|
+
const likes = tSocial?.likes || 0;
|
|
572
|
+
const views = tSocial?.views || 0;
|
|
573
|
+
const comments = tSocial?.comments || 0;
|
|
574
|
+
let isMet = hasContent;
|
|
575
|
+
if (likes < minLikes || views < minViews || comments < minComments)
|
|
576
|
+
isMet = false;
|
|
577
|
+
// Max claims for accumulate mode
|
|
578
|
+
let maxClaims;
|
|
579
|
+
if (ctx.shouldScale && mode === 'accumulate' && hasContent) {
|
|
580
|
+
let mc = Infinity;
|
|
581
|
+
if (cond.minLikes && cond.minLikes > 0)
|
|
582
|
+
mc = Math.min(mc, Math.floor(likes / cond.minLikes));
|
|
583
|
+
if (cond.minViews && cond.minViews > 0)
|
|
584
|
+
mc = Math.min(mc, Math.floor(views / cond.minViews));
|
|
585
|
+
if (cond.minComments && cond.minComments > 0)
|
|
586
|
+
mc = Math.min(mc, Math.floor(comments / cond.minComments));
|
|
587
|
+
if (mc !== Infinity)
|
|
588
|
+
maxClaims = mc;
|
|
589
|
+
}
|
|
590
|
+
// Calculate social percentage - average of applicable metrics
|
|
591
|
+
const socialPercentages = [];
|
|
592
|
+
if (minLikes > 0)
|
|
593
|
+
socialPercentages.push((0, helpers_1.calculatePercent)(likes, minLikes, likes >= minLikes));
|
|
594
|
+
if (minViews > 0)
|
|
595
|
+
socialPercentages.push((0, helpers_1.calculatePercent)(views, minViews, views >= minViews));
|
|
596
|
+
if (minComments > 0)
|
|
597
|
+
socialPercentages.push((0, helpers_1.calculatePercent)(comments, minComments, comments >= minComments));
|
|
598
|
+
if (!hasContent)
|
|
599
|
+
socialPercentages.push(0);
|
|
600
|
+
const socialPercent = socialPercentages.length > 0
|
|
601
|
+
? socialPercentages.reduce((a, b) => a + b, 0) / socialPercentages.length
|
|
602
|
+
: hasContent ? 100 : 0;
|
|
603
|
+
const platformMap = { tiktok: 'TikTok', instagram: 'Instagram', youtube: 'YouTube' };
|
|
604
|
+
const platformText = cond.platforms.map((p) => platformMap[p] || p).join(' | ');
|
|
605
|
+
const requiredWords = cond.requiredWords ?? [];
|
|
606
|
+
const details = [];
|
|
607
|
+
if (mode === 'accumulate') {
|
|
608
|
+
const matchCount = tSocialAccumulate?.matchCount || 0;
|
|
609
|
+
details.push({
|
|
610
|
+
isMet: hasContent && isMet, kind: 'social', trackerAmount: matchCount, trackerGoal: 1,
|
|
611
|
+
percentCompleted: socialPercent,
|
|
612
|
+
text: hasContent
|
|
613
|
+
? `Found ${matchCount} matching ${platformText} post${matchCount !== 1 ? 's' : ''}`
|
|
614
|
+
: requiredWords.length > 0
|
|
615
|
+
? `Post ${platformText} content with ${requiredWords.map((w) => `"${w}"`).join(', ')}`
|
|
616
|
+
: `Post ${platformText} content`,
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
const title = tSocialAttach?.title;
|
|
621
|
+
details.push({
|
|
622
|
+
isMet: hasContent && isMet, kind: 'social',
|
|
623
|
+
trackerAmount: hasContent ? 1 : 0, trackerGoal: 1,
|
|
624
|
+
percentCompleted: socialPercent,
|
|
625
|
+
text: !hasContent
|
|
626
|
+
? requiredWords.length > 0
|
|
627
|
+
? `Attach a ${platformText} post with ${requiredWords.map((w) => `"${w}"`).join(', ')} in the title`
|
|
628
|
+
: `Attach a ${platformText} post`
|
|
629
|
+
: `Attached: ${title}`,
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
if (minLikes > 0) {
|
|
633
|
+
details.push({
|
|
634
|
+
isMet: hasContent && likes >= minLikes, kind: 'social',
|
|
635
|
+
trackerAmount: likes, trackerGoal: minLikes,
|
|
636
|
+
percentCompleted: (0, helpers_1.calculatePercent)(likes, minLikes, hasContent && likes >= minLikes),
|
|
637
|
+
text: mode === 'accumulate' ? `Combined ${minLikes} Likes` : `Reach ${minLikes} Likes`,
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
if (minViews > 0) {
|
|
641
|
+
details.push({
|
|
642
|
+
isMet: hasContent && views >= minViews, kind: 'social',
|
|
643
|
+
trackerAmount: views, trackerGoal: minViews,
|
|
644
|
+
percentCompleted: (0, helpers_1.calculatePercent)(views, minViews, hasContent && views >= minViews),
|
|
645
|
+
text: mode === 'accumulate' ? `Combined ${minViews} Views` : `Reach ${minViews} Views`,
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
if (minComments > 0) {
|
|
649
|
+
details.push({
|
|
650
|
+
isMet: hasContent && comments >= minComments, kind: 'social',
|
|
651
|
+
trackerAmount: comments, trackerGoal: minComments,
|
|
652
|
+
percentCompleted: (0, helpers_1.calculatePercent)(comments, minComments, hasContent && comments >= minComments),
|
|
653
|
+
text: mode === 'accumulate' ? `Combined ${minComments} Comments` : `Reach ${minComments} Comments`,
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
return { isMet, details, maxClaims };
|
|
657
|
+
}
|
|
658
|
+
function evaluateLinkedCompletions(cond, ctx) {
|
|
659
|
+
const baseMin = cond.min;
|
|
660
|
+
const trackerAmount = ctx.completionTrackers?.linkedCompletions || 0;
|
|
661
|
+
const trackerGoal = baseMin * ctx.claimMultiplier;
|
|
662
|
+
const isMet = trackerAmount >= trackerGoal;
|
|
663
|
+
return {
|
|
664
|
+
isMet,
|
|
665
|
+
details: [{
|
|
666
|
+
isMet, kind: 'linkedCompletions', trackerAmount, trackerGoal,
|
|
667
|
+
percentCompleted: (0, helpers_1.calculatePercent)(trackerAmount, trackerGoal, isMet),
|
|
668
|
+
text: cond.template
|
|
669
|
+
? (0, template_1.renderTemplate)(cond.template, { current: trackerAmount, required: trackerGoal })
|
|
670
|
+
: `Wait for ${trackerGoal} linked ${trackerGoal === 1 ? 'entity' : 'entities'} to complete`,
|
|
671
|
+
}],
|
|
672
|
+
maxClaims: ctx.shouldScale && baseMin > 0 ? Math.floor(trackerAmount / baseMin) : undefined,
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
function evaluateDynamicTracker(cond, ctx) {
|
|
676
|
+
const resolvedConditions = (0, template_1.replaceDynamicConditionKeys)(cond.conditions, ctx.offerTrackers || {});
|
|
677
|
+
const primitiveTrackers = (0, dynamic_1.dynamicTrackerToPrimitive)(ctx.completionTrackers?.dynamicTracker || {});
|
|
678
|
+
const dynamicResult = (0, helpers_1.meetsDynamicConditions)(primitiveTrackers, { ...cond, conditions: resolvedConditions }, ctx.claimMultiplier);
|
|
679
|
+
let maxClaims;
|
|
680
|
+
if (ctx.shouldScale) {
|
|
681
|
+
maxClaims = (0, helpers_1.getMaxClaimsForDynamicGroup)(primitiveTrackers, { ...cond, conditions: resolvedConditions }, ctx.offerTrackers?.claimedCount || 0);
|
|
682
|
+
}
|
|
683
|
+
let trackerAmount;
|
|
684
|
+
let trackerGoal;
|
|
685
|
+
if (resolvedConditions.length > 0) {
|
|
686
|
+
const firstCond = resolvedConditions[0];
|
|
687
|
+
if (typeof firstCond.compareTo === 'number')
|
|
688
|
+
trackerGoal = firstCond.compareTo;
|
|
689
|
+
const val = primitiveTrackers[firstCond.key];
|
|
690
|
+
trackerAmount = typeof val === 'number' ? val : 0;
|
|
691
|
+
}
|
|
692
|
+
const percentCompleted = (0, helpers_1.calculateDynamicGroupPercent)(primitiveTrackers, {
|
|
693
|
+
...cond, conditions: resolvedConditions,
|
|
694
|
+
});
|
|
695
|
+
return {
|
|
696
|
+
isMet: dynamicResult,
|
|
697
|
+
details: [{
|
|
698
|
+
isMet: dynamicResult, kind: 'dynamicTracker', trackerAmount, trackerGoal, percentCompleted,
|
|
699
|
+
text: (0, template_1.renderTemplate)((0, template_1.replaceDynamicConditionKey)(cond.template || '', ctx.offerTrackers || {}), primitiveTrackers) || 'Dynamic conditions',
|
|
700
|
+
}],
|
|
701
|
+
maxClaims,
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
function evaluateContractInteraction(cond, ctx) {
|
|
705
|
+
const rawTracker = ctx.completionTrackers?.contractInteractions?.[cond.id];
|
|
706
|
+
const trackerData = rawTracker || { amount: 0, count: 0 };
|
|
707
|
+
const trackerAmount = trackerData.amount || 0;
|
|
708
|
+
const trackerCount = trackerData.count || 0;
|
|
709
|
+
const minAmount = cond.minAmount ? cond.minAmount * ctx.claimMultiplier : 0;
|
|
710
|
+
const maxAmount = cond.maxAmount ? cond.maxAmount * ctx.claimMultiplier : undefined;
|
|
711
|
+
const minCount = cond.minCount ? cond.minCount * ctx.claimMultiplier : 0;
|
|
712
|
+
const maxCount = cond.maxCount ? cond.maxCount * ctx.claimMultiplier : undefined;
|
|
713
|
+
let isMet = true;
|
|
714
|
+
if (minAmount > 0 && trackerAmount < minAmount)
|
|
715
|
+
isMet = false;
|
|
716
|
+
if (maxAmount !== undefined && trackerAmount > maxAmount)
|
|
717
|
+
isMet = false;
|
|
718
|
+
if (minCount > 0 && trackerCount < minCount)
|
|
719
|
+
isMet = false;
|
|
720
|
+
if (maxCount !== undefined && trackerCount > maxCount)
|
|
721
|
+
isMet = false;
|
|
722
|
+
let maxClaims;
|
|
723
|
+
if (ctx.shouldScale && (cond.minAmount || cond.minCount)) {
|
|
724
|
+
const byAmount = cond.minAmount ? Math.floor(trackerAmount / cond.minAmount) : Number.MAX_SAFE_INTEGER;
|
|
725
|
+
const byCount = cond.minCount ? Math.floor(trackerCount / cond.minCount) : Number.MAX_SAFE_INTEGER;
|
|
726
|
+
maxClaims = Math.min(byAmount, byCount);
|
|
727
|
+
}
|
|
728
|
+
// Calculate display percentage
|
|
729
|
+
const hasMin = minAmount > 0 || minCount > 0;
|
|
730
|
+
const hasMax = (maxAmount !== undefined && maxAmount > 0) || (maxCount !== undefined && maxCount > 0);
|
|
731
|
+
let percent = 0;
|
|
732
|
+
if (!hasMin && hasMax) {
|
|
733
|
+
const pcts = [];
|
|
734
|
+
if (maxAmount !== undefined && maxAmount > 0)
|
|
735
|
+
pcts.push(trackerAmount > 0 ? 100 : 0);
|
|
736
|
+
if (maxCount !== undefined && maxCount > 0)
|
|
737
|
+
pcts.push(trackerCount > 0 ? 100 : 0);
|
|
738
|
+
percent = pcts.length > 0 ? pcts.reduce((a, b) => a + b, 0) / pcts.length : 0;
|
|
739
|
+
}
|
|
740
|
+
else if (minAmount > 0 && minCount > 0) {
|
|
741
|
+
percent = ((0, helpers_1.calculatePercent)(trackerAmount, minAmount, true) + (0, helpers_1.calculatePercent)(trackerCount, minCount, true)) / 2;
|
|
742
|
+
}
|
|
743
|
+
else if (minCount > 0) {
|
|
744
|
+
percent = (0, helpers_1.calculatePercent)(trackerCount, minCount, isMet);
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
percent = (0, helpers_1.calculatePercent)(trackerAmount, minAmount || 0, isMet);
|
|
748
|
+
}
|
|
749
|
+
return {
|
|
750
|
+
isMet,
|
|
751
|
+
details: [{
|
|
752
|
+
isMet, kind: 'contractInteraction', trackerAmount,
|
|
753
|
+
percentCompleted: percent,
|
|
754
|
+
text: (0, template_1.renderTemplate)(cond.template, {
|
|
755
|
+
currentAmount: trackerAmount || 0, currentCount: trackerCount || 0,
|
|
756
|
+
minAmount: minAmount || 0, maxAmount: maxAmount || 0,
|
|
757
|
+
minCount: minCount || 0, maxCount: maxCount || 0,
|
|
758
|
+
}),
|
|
759
|
+
}],
|
|
760
|
+
maxClaims,
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
//# sourceMappingURL=handlers.js.map
|