make-mp-data 3.0.3 → 3.0.5

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 (70) hide show
  1. package/README.md +46 -0
  2. package/dungeons/array-of-object-lookup-schema.json +327 -0
  3. package/dungeons/array-of-object-lookup.js +29 -9
  4. package/dungeons/capstone/capstone-ic3.js +291 -0
  5. package/dungeons/capstone/capstone-ic4.js +598 -0
  6. package/dungeons/capstone/capstone-ic5.js +668 -0
  7. package/dungeons/capstone/generate-product-lookup.js +309 -0
  8. package/dungeons/ecommerce-schema.json +462 -0
  9. package/dungeons/{copilot.js → ecommerce.js} +79 -17
  10. package/dungeons/education-schema.json +2409 -0
  11. package/dungeons/education.js +226 -462
  12. package/dungeons/fintech-schema.json +14034 -0
  13. package/dungeons/fintech.js +134 -413
  14. package/dungeons/foobar-schema.json +403 -0
  15. package/dungeons/foobar.js +27 -4
  16. package/dungeons/food-delivery-schema.json +192 -0
  17. package/dungeons/food-delivery.js +602 -0
  18. package/dungeons/food-schema.json +1152 -0
  19. package/dungeons/food.js +173 -406
  20. package/dungeons/gaming-schema.json +1270 -0
  21. package/dungeons/gaming.js +182 -42
  22. package/dungeons/insurance-application-schema.json +204 -0
  23. package/dungeons/insurance-application.js +605 -0
  24. package/dungeons/media-schema.json +906 -0
  25. package/dungeons/media.js +250 -420
  26. package/dungeons/retention-cadence-schema.json +78 -0
  27. package/dungeons/retention-cadence.js +35 -1
  28. package/dungeons/rpg-schema.json +4526 -0
  29. package/dungeons/rpg.js +171 -429
  30. package/dungeons/sanity-schema.json +255 -0
  31. package/dungeons/sanity.js +21 -10
  32. package/dungeons/sass-schema.json +1291 -0
  33. package/dungeons/sass.js +241 -368
  34. package/dungeons/scd-schema.json +919 -0
  35. package/dungeons/scd.js +41 -13
  36. package/dungeons/simple-schema.json +608 -0
  37. package/dungeons/simple.js +52 -15
  38. package/dungeons/simplest-schema.json +1418 -0
  39. package/dungeons/simplest.js +392 -0
  40. package/dungeons/social-schema.json +1118 -0
  41. package/dungeons/social.js +150 -391
  42. package/dungeons/text-generation-schema.json +3096 -0
  43. package/dungeons/text-generation.js +71 -0
  44. package/index.js +8 -6
  45. package/lib/core/config-validator.js +28 -8
  46. package/lib/core/storage.js +5 -5
  47. package/lib/generators/events.js +4 -4
  48. package/lib/orchestrators/mixpanel-sender.js +16 -13
  49. package/lib/orchestrators/user-loop.js +14 -6
  50. package/lib/templates/soup-presets.js +188 -0
  51. package/lib/utils/utils.js +52 -6
  52. package/package.json +1 -1
  53. package/types.d.ts +20 -3
  54. package/dungeons/adspend.js +0 -130
  55. package/dungeons/anon.js +0 -128
  56. package/dungeons/benchmark-heavy.js +0 -240
  57. package/dungeons/benchmark-light.js +0 -140
  58. package/dungeons/big.js +0 -226
  59. package/dungeons/business.js +0 -391
  60. package/dungeons/complex.js +0 -428
  61. package/dungeons/experiments.js +0 -137
  62. package/dungeons/funnels.js +0 -309
  63. package/dungeons/mil.js +0 -323
  64. package/dungeons/mirror.js +0 -161
  65. package/dungeons/soup-test.js +0 -52
  66. package/dungeons/streaming.js +0 -372
  67. package/dungeons/strict-event-test.js +0 -30
  68. package/dungeons/student-teacher.js +0 -438
  69. package/dungeons/too-big-events.js +0 -203
  70. package/dungeons/user-agent.js +0 -209
@@ -0,0 +1,919 @@
1
+ {
2
+ "schema": {
3
+ "token": "",
4
+ "seed": "simple is best",
5
+ "numDays": 30,
6
+ "numEvents": 50000,
7
+ "numUsers": 500,
8
+ "format": "csv",
9
+ "region": "US",
10
+ "hasAnonIds": false,
11
+ "hasSessionIds": false,
12
+ "hasAdSpend": false,
13
+ "hasLocation": true,
14
+ "hasAndroidDevices": true,
15
+ "hasIOSDevices": true,
16
+ "hasDesktopDevices": true,
17
+ "hasBrowser": true,
18
+ "hasCampaigns": true,
19
+ "isAnonymous": false,
20
+ "events": [
21
+ {
22
+ "event": "checkout",
23
+ "weight": 2,
24
+ "properties": {
25
+ "amount": [
26
+ 110,
27
+ 153,
28
+ 209,
29
+ 398,
30
+ 119,
31
+ 131,
32
+ 160,
33
+ 180,
34
+ 393,
35
+ 362,
36
+ 112,
37
+ 298,
38
+ 349,
39
+ 136,
40
+ 370,
41
+ 131,
42
+ 142,
43
+ 127,
44
+ 151,
45
+ 385,
46
+ 339,
47
+ 362,
48
+ 111,
49
+ 148,
50
+ 336,
51
+ 158,
52
+ 188,
53
+ 159,
54
+ 119,
55
+ 340,
56
+ 369,
57
+ 127,
58
+ 125,
59
+ 379,
60
+ 166,
61
+ 129,
62
+ 390,
63
+ 126,
64
+ 155,
65
+ 124,
66
+ 345,
67
+ 196,
68
+ 159,
69
+ 131,
70
+ 253,
71
+ 149,
72
+ 155,
73
+ 161,
74
+ 149,
75
+ 333
76
+ ],
77
+ "currency": [
78
+ "USD",
79
+ "CAD",
80
+ "EUR",
81
+ "BTC",
82
+ "ETH",
83
+ "JPY"
84
+ ],
85
+ "coupon": {
86
+ "functionName": "arrow",
87
+ "body": "function generateWeightedArray() {\n\t\tconst weightedArray = [];\n\n\t\t// Add each value to the array the number of times specified by its weight\n\t\tweightedItems.forEach(({ value, weight }) => {\n\t\t\tif (!weight) weight = 1;\n\t\t\tfor (let i = 0; i < weight; i++) {\n\t\t\t\tweightedArray.push(value);\n\t\t\t}\n\t\t});\n\n\t\treturn weightedArray;\n\t}"
88
+ },
89
+ "numItems": [
90
+ 5,
91
+ 5,
92
+ 4,
93
+ 3,
94
+ 5,
95
+ 5,
96
+ 6,
97
+ 3,
98
+ 5,
99
+ 4,
100
+ 9,
101
+ 3,
102
+ 8,
103
+ 8,
104
+ 7,
105
+ 3,
106
+ 8,
107
+ 4,
108
+ 6,
109
+ 9,
110
+ 7,
111
+ 5,
112
+ 8,
113
+ 4,
114
+ 4,
115
+ 5,
116
+ 5,
117
+ 3,
118
+ 5,
119
+ 5,
120
+ 4,
121
+ 4,
122
+ 3,
123
+ 6,
124
+ 1,
125
+ 1,
126
+ 5,
127
+ 5,
128
+ 6,
129
+ 5,
130
+ 6,
131
+ 7,
132
+ 4,
133
+ 4,
134
+ 2,
135
+ 3,
136
+ 2,
137
+ 5,
138
+ 8,
139
+ 3
140
+ ]
141
+ }
142
+ },
143
+ {
144
+ "event": "add to cart",
145
+ "weight": 4,
146
+ "properties": {
147
+ "amount": [
148
+ 131,
149
+ 112,
150
+ 138,
151
+ 145,
152
+ 160,
153
+ 371,
154
+ 146,
155
+ 163,
156
+ 386,
157
+ 160,
158
+ 128,
159
+ 141,
160
+ 137,
161
+ 116,
162
+ 139,
163
+ 383,
164
+ 186,
165
+ 201,
166
+ 349,
167
+ 136,
168
+ 125,
169
+ 136,
170
+ 363,
171
+ 129,
172
+ 151,
173
+ 130,
174
+ 148,
175
+ 158,
176
+ 375,
177
+ 383,
178
+ 137,
179
+ 117,
180
+ 326,
181
+ 337,
182
+ 191,
183
+ 127,
184
+ 127,
185
+ 167,
186
+ 129,
187
+ 253,
188
+ 371,
189
+ 169,
190
+ 123,
191
+ 392,
192
+ 171,
193
+ 123,
194
+ 346,
195
+ 362,
196
+ 223,
197
+ 360
198
+ ],
199
+ "rating": [
200
+ 2,
201
+ 2,
202
+ 2,
203
+ 3,
204
+ 3,
205
+ 3,
206
+ 2,
207
+ 1,
208
+ 2,
209
+ 5,
210
+ 2,
211
+ 2,
212
+ 2,
213
+ 2,
214
+ 2,
215
+ 2,
216
+ 3,
217
+ 2,
218
+ 4,
219
+ 3,
220
+ 2,
221
+ 2,
222
+ 3,
223
+ 3,
224
+ 2,
225
+ 4,
226
+ 3,
227
+ 4,
228
+ 2,
229
+ 2,
230
+ 3,
231
+ 5,
232
+ 5,
233
+ 2,
234
+ 2,
235
+ 2,
236
+ 2,
237
+ 4,
238
+ 2,
239
+ 2,
240
+ 3,
241
+ 4,
242
+ 3,
243
+ 1,
244
+ 2,
245
+ 3,
246
+ 3,
247
+ 2,
248
+ 5,
249
+ 4
250
+ ],
251
+ "reviews": [
252
+ 9,
253
+ 27,
254
+ 20,
255
+ 16,
256
+ 16,
257
+ 4,
258
+ 23,
259
+ 9,
260
+ 17,
261
+ 22,
262
+ 15,
263
+ 8,
264
+ 12,
265
+ 13,
266
+ 9,
267
+ 15,
268
+ 18,
269
+ 10,
270
+ 14,
271
+ 16,
272
+ 10,
273
+ 9,
274
+ 6,
275
+ 9,
276
+ 15,
277
+ 18,
278
+ 28,
279
+ 14,
280
+ 6,
281
+ 20,
282
+ 23,
283
+ 26,
284
+ 9,
285
+ 20,
286
+ 3,
287
+ 14,
288
+ 26,
289
+ 13,
290
+ 19,
291
+ 14,
292
+ 10,
293
+ 18,
294
+ 20,
295
+ 29,
296
+ 8,
297
+ 8,
298
+ 12,
299
+ 8,
300
+ 8,
301
+ 19
302
+ ],
303
+ "isFeaturedItem": [
304
+ true,
305
+ false,
306
+ false
307
+ ],
308
+ "itemCategory": {
309
+ "functionName": "arrow",
310
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
311
+ },
312
+ "dateItemListed": {
313
+ "functionName": "integer",
314
+ "args": []
315
+ }
316
+ }
317
+ },
318
+ {
319
+ "event": "page view",
320
+ "weight": 10,
321
+ "properties": {
322
+ "page": {
323
+ "functionName": "arrow",
324
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
325
+ },
326
+ "utm_source": {
327
+ "functionName": "arrow",
328
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
329
+ }
330
+ }
331
+ },
332
+ {
333
+ "event": "watch video",
334
+ "weight": 8,
335
+ "properties": {
336
+ "videoCategory": {
337
+ "functionName": "arrow",
338
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
339
+ },
340
+ "isFeaturedItem": [
341
+ true,
342
+ false,
343
+ false
344
+ ],
345
+ "watchTimeSec": [
346
+ 433,
347
+ 466,
348
+ 143,
349
+ 178,
350
+ 159,
351
+ 449,
352
+ 170,
353
+ 145,
354
+ 170,
355
+ 168,
356
+ 159,
357
+ 161,
358
+ 173,
359
+ 240,
360
+ 131,
361
+ 424,
362
+ 180,
363
+ 431,
364
+ 197,
365
+ 305,
366
+ 156,
367
+ 183,
368
+ 466,
369
+ 149,
370
+ 453,
371
+ 440,
372
+ 207,
373
+ 161,
374
+ 158,
375
+ 159,
376
+ 437,
377
+ 159,
378
+ 156,
379
+ 180,
380
+ 384,
381
+ 404,
382
+ 149,
383
+ 458,
384
+ 136,
385
+ 168,
386
+ 453,
387
+ 415,
388
+ 148,
389
+ 187,
390
+ 155,
391
+ 305,
392
+ 161,
393
+ 175,
394
+ 161,
395
+ 195
396
+ ],
397
+ "quality": [
398
+ "2160p",
399
+ "1440p",
400
+ "1080p",
401
+ "720p",
402
+ "480p",
403
+ "360p",
404
+ "240p"
405
+ ],
406
+ "format": [
407
+ "mp4",
408
+ "avi",
409
+ "mov",
410
+ "mpg"
411
+ ],
412
+ "uploader_id": {
413
+ "functionName": "arrow",
414
+ "body": "function () { [native code] }"
415
+ }
416
+ }
417
+ },
418
+ {
419
+ "event": "view item",
420
+ "weight": 8,
421
+ "properties": {
422
+ "isFeaturedItem": [
423
+ true,
424
+ false,
425
+ false
426
+ ],
427
+ "itemCategory": {
428
+ "functionName": "arrow",
429
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
430
+ },
431
+ "dateItemListed": {
432
+ "functionName": "integer",
433
+ "args": []
434
+ }
435
+ }
436
+ },
437
+ {
438
+ "event": "save item",
439
+ "weight": 5,
440
+ "properties": {
441
+ "isFeaturedItem": [
442
+ true,
443
+ false,
444
+ false
445
+ ],
446
+ "itemCategory": {
447
+ "functionName": "arrow",
448
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
449
+ },
450
+ "dateItemListed": {
451
+ "functionName": "integer",
452
+ "args": []
453
+ }
454
+ }
455
+ },
456
+ {
457
+ "event": "sign up",
458
+ "isFirstEvent": true,
459
+ "weight": 0,
460
+ "properties": {
461
+ "variants": [
462
+ "A",
463
+ "B",
464
+ "C",
465
+ "Control"
466
+ ],
467
+ "flows": [
468
+ "new",
469
+ "existing",
470
+ "loyal",
471
+ "churned"
472
+ ],
473
+ "flags": [
474
+ "on",
475
+ "off"
476
+ ],
477
+ "experiment_ids": [
478
+ "1234",
479
+ "5678",
480
+ "9012",
481
+ "3456",
482
+ "7890"
483
+ ],
484
+ "multiVariate": [
485
+ true,
486
+ false
487
+ ]
488
+ }
489
+ }
490
+ ],
491
+ "superProps": {
492
+ "platform": [
493
+ "web",
494
+ "mobile",
495
+ "web",
496
+ "mobile",
497
+ "web",
498
+ "web",
499
+ "kiosk",
500
+ "smartTV"
501
+ ],
502
+ "currentTheme": {
503
+ "functionName": "arrow",
504
+ "body": "function generateWeightedArray() {\n\t\tconst weightedArray = [];\n\n\t\t// Add each value to the array the number of times specified by its weight\n\t\tweightedItems.forEach(({ value, weight }) => {\n\t\t\tif (!weight) weight = 1;\n\t\t\tfor (let i = 0; i < weight; i++) {\n\t\t\t\tweightedArray.push(value);\n\t\t\t}\n\t\t});\n\n\t\treturn weightedArray;\n\t}"
505
+ }
506
+ },
507
+ "userProps": {
508
+ "title": {
509
+ "functionName": "arrow",
510
+ "body": "function () { [native code] }"
511
+ },
512
+ "luckyNumber": [
513
+ 317,
514
+ 311,
515
+ 170,
516
+ 315,
517
+ 146,
518
+ 313,
519
+ 167,
520
+ 146,
521
+ 153,
522
+ 185,
523
+ 129,
524
+ 174,
525
+ 231,
526
+ 184,
527
+ 328,
528
+ 297,
529
+ 146,
530
+ 253,
531
+ 140,
532
+ 152,
533
+ 165,
534
+ 147,
535
+ 314,
536
+ 305,
537
+ 127,
538
+ 122,
539
+ 144,
540
+ 335,
541
+ 314,
542
+ 148,
543
+ 154,
544
+ 311,
545
+ 158,
546
+ 144,
547
+ 309,
548
+ 152,
549
+ 311,
550
+ 136,
551
+ 145,
552
+ 231,
553
+ 162,
554
+ 145,
555
+ 331,
556
+ 331,
557
+ 136,
558
+ 162,
559
+ 144,
560
+ 138,
561
+ 142,
562
+ 117
563
+ ],
564
+ "spiritAnimal": {
565
+ "functionName": "arrow",
566
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
567
+ }
568
+ },
569
+ "scdProps": {
570
+ "role": {
571
+ "type": "user",
572
+ "frequency": "week",
573
+ "values": [
574
+ "admin",
575
+ "collaborator",
576
+ "user",
577
+ "view only",
578
+ "no access"
579
+ ],
580
+ "timing": "fuzzy",
581
+ "max": 10
582
+ },
583
+ "NPS": {
584
+ "type": "user",
585
+ "frequency": "day",
586
+ "values": [
587
+ 6,
588
+ 3,
589
+ 3,
590
+ 5,
591
+ 5,
592
+ 4,
593
+ 6,
594
+ 5,
595
+ 3,
596
+ 9,
597
+ 4,
598
+ 8,
599
+ 5,
600
+ 6,
601
+ 7,
602
+ 3,
603
+ 5,
604
+ 7,
605
+ 3,
606
+ 5,
607
+ 5,
608
+ 3,
609
+ 5,
610
+ 5,
611
+ 3,
612
+ 5,
613
+ 5,
614
+ 5,
615
+ 4,
616
+ 5,
617
+ 5,
618
+ 6,
619
+ 8,
620
+ 9,
621
+ 7,
622
+ 5,
623
+ 5,
624
+ 6,
625
+ 5,
626
+ 9,
627
+ 5,
628
+ 4,
629
+ 5,
630
+ 5,
631
+ 7,
632
+ 4,
633
+ 3,
634
+ 4,
635
+ 6,
636
+ 6,
637
+ 2,
638
+ 6,
639
+ 6,
640
+ 6,
641
+ 5,
642
+ 6,
643
+ 5,
644
+ 4,
645
+ 3,
646
+ 3,
647
+ 2,
648
+ 3,
649
+ 3,
650
+ 4,
651
+ 5,
652
+ 1,
653
+ 7,
654
+ 3,
655
+ 6,
656
+ 5,
657
+ 5,
658
+ 8,
659
+ 5,
660
+ 2,
661
+ 9,
662
+ 2,
663
+ 4,
664
+ 2,
665
+ 5,
666
+ 6,
667
+ 5,
668
+ 8,
669
+ 6,
670
+ 5,
671
+ 2,
672
+ 3,
673
+ 6,
674
+ 5,
675
+ 5,
676
+ 6,
677
+ 6,
678
+ 3,
679
+ 3,
680
+ 6,
681
+ 3,
682
+ 5,
683
+ 4,
684
+ 8,
685
+ 5,
686
+ 5,
687
+ 5,
688
+ 5,
689
+ 4,
690
+ 6,
691
+ 5,
692
+ 5,
693
+ 6,
694
+ 6,
695
+ 4,
696
+ 7,
697
+ 3,
698
+ 9,
699
+ 6,
700
+ 4,
701
+ 5,
702
+ 5,
703
+ 6,
704
+ 6,
705
+ 7,
706
+ 5,
707
+ 6,
708
+ 5,
709
+ 3,
710
+ 5,
711
+ 4,
712
+ 4,
713
+ 5,
714
+ 8,
715
+ 4,
716
+ 6,
717
+ 6,
718
+ 5,
719
+ 6,
720
+ 5,
721
+ 6,
722
+ 5,
723
+ 7,
724
+ 4,
725
+ 1,
726
+ 5,
727
+ 5,
728
+ 8,
729
+ 5,
730
+ 6,
731
+ 7,
732
+ 5,
733
+ 10,
734
+ 6,
735
+ 3,
736
+ 5
737
+ ],
738
+ "timing": "fuzzy",
739
+ "max": 10
740
+ },
741
+ "MRR": {
742
+ "type": "company_id",
743
+ "frequency": "month",
744
+ "values": [
745
+ 6654,
746
+ 2862,
747
+ 3571,
748
+ 2527,
749
+ 2534,
750
+ 6981,
751
+ 3429,
752
+ 2845,
753
+ 2720,
754
+ 2442,
755
+ 2609,
756
+ 2279,
757
+ 7677,
758
+ 2867,
759
+ 2605,
760
+ 6859,
761
+ 6998,
762
+ 6329,
763
+ 2384,
764
+ 6926,
765
+ 2472,
766
+ 7445,
767
+ 2449,
768
+ 7529,
769
+ 2494,
770
+ 2686,
771
+ 2820,
772
+ 7322,
773
+ 2430,
774
+ 7362,
775
+ 2562,
776
+ 2916,
777
+ 2487,
778
+ 7255,
779
+ 7341,
780
+ 2906,
781
+ 7460,
782
+ 2767,
783
+ 2498,
784
+ 7439,
785
+ 2901,
786
+ 2542,
787
+ 2696,
788
+ 6468,
789
+ 7199,
790
+ 7611,
791
+ 2911,
792
+ 2262,
793
+ 7466,
794
+ 2594
795
+ ],
796
+ "timing": "fixed",
797
+ "max": 10
798
+ },
799
+ "AccountHealthScore": {
800
+ "type": "company_id",
801
+ "frequency": "week",
802
+ "values": [
803
+ 3,
804
+ 4,
805
+ 4,
806
+ 7,
807
+ 3,
808
+ 3,
809
+ 4,
810
+ 4,
811
+ 8,
812
+ 7,
813
+ 3,
814
+ 8,
815
+ 7,
816
+ 7,
817
+ 8,
818
+ 3,
819
+ 8,
820
+ 3,
821
+ 8,
822
+ 3,
823
+ 3,
824
+ 4,
825
+ 3,
826
+ 3,
827
+ 4,
828
+ 4,
829
+ 3,
830
+ 3,
831
+ 7,
832
+ 7,
833
+ 4,
834
+ 3,
835
+ 6,
836
+ 8,
837
+ 3,
838
+ 8,
839
+ 8,
840
+ 8,
841
+ 4,
842
+ 3,
843
+ 3,
844
+ 7,
845
+ 8,
846
+ 3,
847
+ 8,
848
+ 4,
849
+ 7,
850
+ 8,
851
+ 4,
852
+ 3
853
+ ],
854
+ "timing": "fixed",
855
+ "max": 40
856
+ },
857
+ "plan": {
858
+ "type": "company_id",
859
+ "frequency": "month",
860
+ "values": [
861
+ "free",
862
+ "basic",
863
+ "premium",
864
+ "enterprise"
865
+ ],
866
+ "timing": "fixed",
867
+ "max": 10
868
+ }
869
+ },
870
+ "groupKeys": [
871
+ [
872
+ "company_id",
873
+ 1000
874
+ ]
875
+ ],
876
+ "groupProps": {
877
+ "company_id": {
878
+ "name": {
879
+ "functionName": "arrow",
880
+ "body": "() => { return chance.name(); }"
881
+ },
882
+ "email": {
883
+ "functionName": "arrow",
884
+ "body": "() => { return `CSM: ${chance.pickone([\"AK\", \"Neha\", \"Rajiv\", \"Deepak\", \"Justin\", \"Hans\", \"Katie\", \"Somya\", \"Tony\", \"Kaan\"])}`; }"
885
+ },
886
+ "industry": [
887
+ "technology",
888
+ "education",
889
+ "finance",
890
+ "healthcare",
891
+ "retail",
892
+ "manufacturing",
893
+ "transportation",
894
+ "entertainment",
895
+ "media",
896
+ "real estate",
897
+ "construction",
898
+ "hospitality",
899
+ "energy",
900
+ "utilities",
901
+ "agriculture",
902
+ "other"
903
+ ],
904
+ "segment": [
905
+ "SMB",
906
+ "SMB",
907
+ "SMB",
908
+ "Mid Market",
909
+ "Mid Market",
910
+ "Enterprise"
911
+ ],
912
+ "# active users": 20
913
+ }
914
+ }
915
+ },
916
+ "hooks": "function (record, type, meta) {\n\t\t// --- user hook: classify users into spending tiers ---\n\t\tif (type === \"user\") {\n\t\t\trecord.spendTier = record.luckyNumber > 250 ? \"high_spender\" : \"budget\";\n\t\t\treturn record;\n\t\t}\n\n\t\t// --- event hook: coupon users get discounted checkout amounts ---\n\t\tif (type === \"event\") {\n\t\t\tif (record.event === \"checkout\" && record.coupon && record.coupon !== \"none\") {\n\t\t\t\tconst discountPct = parseInt(record.coupon) || 10;\n\t\t\t\trecord.amount = Math.round(record.amount * (1 - discountPct / 100));\n\t\t\t\trecord.discount_applied = true;\n\t\t\t}\n\t\t\t// weekend watchers get longer watch times\n\t\t\tif (record.event === \"watch video\" && record.time) {\n\t\t\t\tconst day = dayjs(record.time).day();\n\t\t\t\tif (day === 0 || day === 6) {\n\t\t\t\t\trecord.watchTimeSec = Math.round((record.watchTimeSec || 60) * 1.5);\n\t\t\t\t\trecord.is_weekend = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn record;\n\t\t}\n\n\t\t// --- everything hook: simulate cart abandonment ---\n\t\tif (type === \"everything\") {\n\t\t\tconst hasAddToCart = record.some(e => e.event === \"add to cart\");\n\t\t\tconst hasCheckout = record.some(e => e.event === \"checkout\");\n\t\t\t// users who added to cart but never checked out: remove checkout events (if any slipped through)\n\t\t\t// and mark them as abandoned\n\t\t\tif (hasAddToCart && !hasCheckout && record.length > 2) {\n\t\t\t\tconst lastAdd = record.filter(e => e.event === \"add to cart\").pop();\n\t\t\t\tif (lastAdd) {\n\t\t\t\t\trecord.push({\n\t\t\t\t\t\tevent: \"cart_abandoned\",\n\t\t\t\t\t\ttime: dayjs(lastAdd.time).add(30, \"minute\").toISOString(),\n\t\t\t\t\t\tuser_id: lastAdd.user_id,\n\t\t\t\t\t\tplatform: lastAdd.platform,\n\t\t\t\t\t\tamount: lastAdd.amount\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn record;\n\t\t}\n\n\t\treturn record;\n\t}",
917
+ "timestamp": "2026-04-10T01:39:07.491Z",
918
+ "version": "4.0"
919
+ }