coh-content-db 2.0.0-rc.5 → 2.0.0-rc.6

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 (51) hide show
  1. package/README.md +4 -4
  2. package/dist/coh-content-db.d.ts +203 -156
  3. package/dist/coh-content-db.js +263 -197
  4. package/dist/coh-content-db.js.map +1 -1
  5. package/dist/coh-content-db.mjs +256 -191
  6. package/dist/coh-content-db.mjs.map +1 -1
  7. package/package.json +1 -1
  8. package/src/main/api/badge-data.ts +16 -9
  9. package/src/main/api/{badge-partial-data.ts → badge-requirement-data.ts} +24 -8
  10. package/src/main/api/badge-requirement-type.ts +11 -0
  11. package/src/main/api/contact-data.ts +46 -0
  12. package/src/main/api/content-bundle.ts +10 -4
  13. package/src/main/api/zone-data.ts +20 -0
  14. package/src/main/changelog.ts +5 -1
  15. package/src/main/db/badge-index.ts +17 -11
  16. package/src/main/db/{badge-partial.ts → badge-requirement.ts} +30 -11
  17. package/src/main/db/badge-search-options.ts +2 -2
  18. package/src/main/db/badge.ts +48 -36
  19. package/src/main/db/bundle-metadata.ts +3 -3
  20. package/src/main/db/coh-content-database.ts +51 -18
  21. package/src/main/db/contact.ts +59 -0
  22. package/src/main/db/zone.ts +28 -0
  23. package/src/main/index.ts +8 -10
  24. package/src/main/util.ts +44 -13
  25. package/src/test/api/badge-data.fixture.ts +9 -7
  26. package/src/test/api/badge-requirement-data.fixture.ts +17 -0
  27. package/src/test/api/badge-requirement-type.test.ts +31 -0
  28. package/src/test/api/contact-data.fixture.ts +13 -0
  29. package/src/test/api/content-bundle.fixture.ts +2 -2
  30. package/src/test/api/content-bundle.test.ts +1 -1
  31. package/src/test/api/zone-data.fixture.ts +8 -0
  32. package/src/test/db/badge-index.test.ts +73 -41
  33. package/src/test/db/badge-requirement.test.ts +180 -0
  34. package/src/test/db/badge.test.ts +190 -15
  35. package/src/test/db/coh-content-database.test.ts +110 -18
  36. package/src/test/db/contact.test.ts +96 -0
  37. package/src/test/db/zone.test.ts +36 -0
  38. package/src/test/index.test.ts +4 -2
  39. package/src/test/util.test.ts +59 -22
  40. package/src/main/api/badge-partial-type.ts +0 -8
  41. package/src/main/api/game-map-data.ts +0 -26
  42. package/src/main/api/vidiot-map-data.ts +0 -18
  43. package/src/main/api/vidiot-map-point-of-interest-data.ts +0 -30
  44. package/src/main/db/game-map.ts +0 -33
  45. package/src/main/db/vidiot-map-point-of-interest.ts +0 -39
  46. package/src/main/db/vidiot-map.ts +0 -25
  47. package/src/test/api/badge-partial-data.fixture.ts +0 -17
  48. package/src/test/api/badge-partial-type.test.ts +0 -31
  49. package/src/test/api/game-map-data.fixture.ts +0 -10
  50. package/src/test/api/vidiot-map-point-of-interest.fixture.ts +0 -10
  51. package/src/test/api/vidiot-map.fixture.ts +0 -9
@@ -1,9 +1,15 @@
1
1
  const ALIGNMENT = ["H", "V", "P"];
2
2
 
3
- const BADGE_PARTIAL_TYPE = [
3
+ const BADGE_REQUIREMENT_TYPE = [
4
4
  "PLAQUE",
5
5
  "BADGE",
6
6
  "INVENTION",
7
+ "MISSION",
8
+ // Complete a mission
9
+ "ARC",
10
+ // Complete a story arc
11
+ "TASK_FORCE",
12
+ // Complete a task force
7
13
  "INVENTION_PLUS_ONE"
8
14
  // Some invention badges require you to build x of two different invention levels, 'plus one of either level'.
9
15
  ];
@@ -62,16 +68,16 @@ const PLAQUE_TYPE = [
62
68
 
63
69
  const SEX = ["M", "F"];
64
70
 
65
- var __defProp$8 = Object.defineProperty;
66
- var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
67
- var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
71
+ var __defProp$7 = Object.defineProperty;
72
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
73
+ var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
68
74
  class Alignments {
69
75
  constructor(raw) {
70
- __publicField$8(this, "items");
71
- __publicField$8(this, "hero");
72
- __publicField$8(this, "villain");
73
- __publicField$8(this, "praetorian");
74
- __publicField$8(this, "primal");
76
+ __publicField$7(this, "items");
77
+ __publicField$7(this, "hero");
78
+ __publicField$7(this, "villain");
79
+ __publicField$7(this, "praetorian");
80
+ __publicField$7(this, "primal");
75
81
  this.items = raw;
76
82
  this.hero = raw.includes("H");
77
83
  this.villain = raw.includes("V");
@@ -181,198 +187,224 @@ validateKey_fn = function(key) {
181
187
  if (INVALID_KEY_PATTERN.test(key)) throw new Error(`Invalid key: [${key}]; Keys can only contain lowercase characters, numbers and dashes.`);
182
188
  };
183
189
 
184
- var __defProp$7 = Object.defineProperty;
185
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
186
- var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
190
+ var __defProp$6 = Object.defineProperty;
191
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
192
+ var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
187
193
  class Archetype {
188
194
  constructor(data) {
189
- __publicField$7(this, "key");
190
- __publicField$7(this, "name");
191
- __publicField$7(this, "description");
195
+ __publicField$6(this, "key");
196
+ __publicField$6(this, "name");
197
+ __publicField$6(this, "description");
192
198
  this.key = new Key(data.key).value;
193
199
  this.name = data.name;
194
200
  this.description = data.description;
195
201
  }
196
202
  }
197
203
 
198
- var __defProp$6 = Object.defineProperty;
199
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
200
- var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
201
- class BadgePartial {
204
+ var __defProp$5 = Object.defineProperty;
205
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
206
+ var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
207
+ class BadgeRequirement {
202
208
  constructor(data) {
203
209
  /**
204
210
  * Key.
205
211
  */
206
- __publicField$6(this, "key");
212
+ __publicField$5(this, "key");
207
213
  /**
208
- * Type of partial.
214
+ * Type of requirement.
209
215
  */
210
- __publicField$6(this, "type");
216
+ __publicField$5(this, "type");
211
217
  /**
212
- * Map the partial is located on.
218
+ * Zone the requirement is located in.
213
219
  */
214
- __publicField$6(this, "mapKey");
220
+ __publicField$5(this, "zoneKey");
215
221
  /**
216
222
  * /loc coordinates.
217
223
  */
218
- __publicField$6(this, "loc");
224
+ __publicField$5(this, "loc");
219
225
  /**
220
226
  * Is it a wall plaque or a physical monument?
221
227
  */
222
- __publicField$6(this, "plaqueType");
228
+ __publicField$5(this, "plaqueType");
223
229
  /**
224
230
  * Plaque inscription.
225
231
  */
226
- __publicField$6(this, "plaqueInscription");
232
+ __publicField$5(this, "plaqueInscription");
233
+ /**
234
+ * The number or letter the plaque appears as on Vidiot Maps.
235
+ */
236
+ __publicField$5(this, "vidiotMapKey");
237
+ /**
238
+ * The key of the badge for this requirement.
239
+ */
240
+ __publicField$5(this, "badgeKey");
227
241
  /**
228
- * The number or letter the partial appears as on Vidiot Maps.
242
+ * Mission name.
229
243
  */
230
- __publicField$6(this, "vidiotMapKey");
244
+ __publicField$5(this, "missionName");
231
245
  /**
232
- * The badge required for this partial.
246
+ * {@link Contact} key for the story arc.
233
247
  */
234
- __publicField$6(this, "badgeKey");
248
+ __publicField$5(this, "contactKey");
235
249
  /**
236
250
  * Level of the invention required.
237
251
  */
238
- __publicField$6(this, "inventionLevel");
252
+ __publicField$5(this, "inventionLevel");
239
253
  /**
240
254
  * The types of enhancements required to be crafted.
241
255
  */
242
- __publicField$6(this, "inventionTypes");
256
+ __publicField$5(this, "inventionTypes");
243
257
  /**
244
258
  * Number of invention crafts required.
245
259
  */
246
- __publicField$6(this, "inventionCount");
260
+ __publicField$5(this, "inventionCount");
247
261
  /**
248
262
  * Any additional notes.
249
263
  */
250
- __publicField$6(this, "notes");
264
+ __publicField$5(this, "notes");
265
+ /**
266
+ * List of external links. Wiki, forums, etc.
267
+ */
268
+ __publicField$5(this, "links");
251
269
  this.key = new Key(data.key).value;
252
270
  this.type = data.type;
253
- this.mapKey = data.mapKey;
271
+ this.zoneKey = data.zoneKey;
254
272
  this.loc = data.loc;
255
273
  this.plaqueType = data.plaqueType;
256
274
  this.plaqueInscription = data.plaqueInscription;
257
275
  this.vidiotMapKey = data.vidiotMapKey;
258
276
  this.badgeKey = data.badgeKey;
277
+ this.missionName = data.missionName;
278
+ this.contactKey = data.contactKey;
259
279
  this.inventionLevel = data.inventionLevel;
260
280
  this.inventionTypes = data.inventionTypes;
261
281
  this.inventionCount = data.inventionCount;
262
282
  this.notes = data.notes;
283
+ this.links = data.links ?? [];
263
284
  }
264
285
  }
265
286
 
266
- var __defProp$5 = Object.defineProperty;
287
+ var __defProp$4 = Object.defineProperty;
267
288
  var __typeError$2 = (msg) => {
268
289
  throw TypeError(msg);
269
290
  };
270
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
271
- var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
291
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
292
+ var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
272
293
  var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
273
294
  var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
274
295
  var __privateAdd$2 = (obj, member, value) => member.has(obj) ? __typeError$2("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
275
- var _partialsIndex;
296
+ var _requirementsIndex;
276
297
  class Badge {
277
- constructor(data) {
278
- __privateAdd$2(this, _partialsIndex, {});
298
+ constructor(badgeData) {
299
+ __privateAdd$2(this, _requirementsIndex, {});
279
300
  /**
280
301
  * The database key for this badge.
281
302
  */
282
- __publicField$5(this, "key");
303
+ __publicField$4(this, "key");
283
304
  /**
284
305
  * The type of badge.
285
306
  */
286
- __publicField$5(this, "type");
307
+ __publicField$4(this, "type");
287
308
  /**
288
309
  * The name of this badge.
289
310
  *
290
311
  * May vary by character sex or alignment.
291
312
  */
292
- __publicField$5(this, "name");
313
+ __publicField$4(this, "name");
293
314
  /**
294
315
  * The character alignments that this badge is available to.
295
316
  */
296
- __publicField$5(this, "alignment");
317
+ __publicField$4(this, "alignment");
297
318
  /**
298
319
  * The badge text as it appears in-game. May vary by character sex or alignment.
299
320
  */
300
- __publicField$5(this, "badgeText");
321
+ __publicField$4(this, "badgeText");
301
322
  /**
302
- * Description of how to acquire the badge.
323
+ * Short description of how to acquire the badge. Detailed instructions will be in the notes field.
303
324
  */
304
- __publicField$5(this, "acquisition");
325
+ __publicField$4(this, "acquisition");
305
326
  /**
306
327
  * Absolute URL to this badge's icon.
307
328
  *
308
329
  * May vary by character sex or alignment.
309
330
  */
310
- __publicField$5(this, "icon");
331
+ __publicField$4(this, "icon");
311
332
  /**
312
333
  * Freeform notes or tips about the badge.
313
334
  */
314
- __publicField$5(this, "notes");
335
+ __publicField$4(this, "notes");
315
336
  /**
316
- * List of external links for this Badge. Wiki, forums, etc.
337
+ * List of external links. Wiki, forums, etc.
317
338
  */
318
- __publicField$5(this, "links");
339
+ __publicField$4(this, "links");
319
340
  /**
320
- * For exploration badges, the key of the {@link GameMap} that this badge is found on.
341
+ * For exploration badges, the key of the {@link Zone} that this badge is found on.
321
342
  */
322
- __publicField$5(this, "mapKey");
343
+ __publicField$4(this, "zoneKey");
323
344
  /**
324
- * For exploration badges, the `/loc` coordinates of the badge on the in-game map.
345
+ * For exploration badges, the `/loc` coordinates of the badge.
325
346
  */
326
- __publicField$5(this, "loc");
347
+ __publicField$4(this, "loc");
327
348
  /**
328
- * For badges that appear on a Vidiot Map, the number or letter the badge appears as.
349
+ * For plaques that appear on a Vidiot Map, the number or letter the badge appears as.
329
350
  */
330
- __publicField$5(this, "vidiotMapKey");
351
+ __publicField$4(this, "vidiotMapKey");
331
352
  /**
332
353
  * ID used with the in-game `/settitle` command to apply the badge.
333
354
  */
334
- __publicField$5(this, "setTitle");
355
+ __publicField$4(this, "setTitle");
335
356
  /**
336
357
  * A description of the effect the badge will have, such as a buff or granting a temporary power.
337
358
  */
338
- __publicField$5(this, "effect");
359
+ __publicField$4(this, "effect");
339
360
  /**
340
- * A list of requirements for badges that have partial fulfilment steps, such as visiting plaques for history badges, or collecting other badges for meta-badges like accolades.
361
+ * Represents the layered requirements for badges with multiple fulfillment steps,
362
+ * such as visiting plaques for history badges or collecting other badges.
363
+ *
364
+ * The outer array represents groups of requirements evaluated with OR logic —
365
+ * fulfilling any group satisfies the badge.
366
+ *
367
+ * Each inner array represents individual requirements evaluated with AND logic —
368
+ * all conditions in the group must be met.
341
369
  */
342
- __publicField$5(this, "partials");
370
+ __publicField$4(this, "requirements");
343
371
  /**
344
372
  * Some badges are not included in the badge total count... such as Flames of Prometheus, which can be removed by redeeming it for a Notice of the Well.
345
373
  */
346
- __publicField$5(this, "ignoreInTotals");
347
- this.key = new Key(data.key).value;
348
- this.type = data.type;
349
- this.name = new Alternates(data.name);
350
- this.alignment = new Alignments(data.alignment);
351
- this.badgeText = new Alternates(data.badgeText ?? []);
352
- this.acquisition = data.acquisition;
353
- this.icon = new Alternates(data.icon ?? []);
354
- this.notes = data.notes;
355
- this.links = data.links;
356
- this.mapKey = data.mapKey;
357
- this.loc = data.loc;
358
- this.effect = data.effect;
359
- this.vidiotMapKey = data.vidiotMapKey;
360
- this.setTitle = data.setTitle;
361
- this.ignoreInTotals = data.ignoreInTotals ?? false;
362
- this.partials = data.partials?.map((data2) => {
363
- if (__privateGet$2(this, _partialsIndex)[data2.key] !== void 0) throw new Error(`Duplicate badge partial key [${data2.key}]`);
364
- const badge = new BadgePartial(data2);
365
- __privateGet$2(this, _partialsIndex)[badge.key] = badge;
366
- return badge;
374
+ __publicField$4(this, "ignoreInTotals");
375
+ this.key = new Key(badgeData.key).value;
376
+ this.type = badgeData.type;
377
+ this.name = new Alternates(badgeData.name);
378
+ this.alignment = new Alignments(badgeData.alignment);
379
+ this.badgeText = new Alternates(badgeData.badgeText ?? []);
380
+ this.acquisition = badgeData.acquisition;
381
+ this.icon = new Alternates(badgeData.icon ?? []);
382
+ this.notes = badgeData.notes;
383
+ this.links = badgeData.links ?? [];
384
+ this.zoneKey = badgeData.zoneKey;
385
+ this.loc = badgeData.loc;
386
+ this.effect = badgeData.effect;
387
+ this.vidiotMapKey = badgeData.vidiotMapKey;
388
+ this.setTitle = badgeData.setTitle;
389
+ this.ignoreInTotals = badgeData.ignoreInTotals ?? false;
390
+ this.requirements = badgeData.requirements?.map((groups, index) => {
391
+ const existingKeysInGroup = /* @__PURE__ */ new Set();
392
+ return groups.map((requirementData) => {
393
+ if (existingKeysInGroup.has(requirementData.key)) throw new Error(`Duplicate badge requirement key [${badgeData.key}:${requirementData.key}] in group [${index + 1}]`);
394
+ existingKeysInGroup.add(requirementData.key);
395
+ const badge = new BadgeRequirement(requirementData);
396
+ __privateGet$2(this, _requirementsIndex)[badge.key] = badge;
397
+ return badge;
398
+ });
367
399
  });
368
400
  }
369
- getPartial(key) {
370
- const result = __privateGet$2(this, _partialsIndex)[key];
371
- if (result === void 0) throw new Error(`Unknown badge partial key [${key}]`);
401
+ getRequirement(key) {
402
+ const result = __privateGet$2(this, _requirementsIndex)[key];
403
+ if (result === void 0) throw new Error(`Unknown badge requirement key [${key}]`);
372
404
  return result;
373
405
  }
374
406
  }
375
- _partialsIndex = new WeakMap();
407
+ _requirementsIndex = new WeakMap();
376
408
 
377
409
  var __typeError$1 = (msg) => {
378
410
  throw TypeError(msg);
@@ -382,15 +414,15 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
382
414
  var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
383
415
  var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
384
416
  var __privateMethod = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
385
- var _badges, _badgeIndex$1, _mapOrder, _BadgeIndex_instances, satisfiesQueryPredicate_fn, satisfiesFilterPredicate_fn, sort_fn;
417
+ var _badges, _badgeIndex$1, _zoneOrder, _BadgeIndex_instances, satisfiesQueryPredicate_fn, satisfiesFilterPredicate_fn, sort_fn;
386
418
  class BadgeIndex {
387
- constructor(badges, maps) {
419
+ constructor(badges, zones) {
388
420
  __privateAdd$1(this, _BadgeIndex_instances);
389
421
  __privateAdd$1(this, _badges, []);
390
422
  __privateAdd$1(this, _badgeIndex$1, {});
391
- __privateAdd$1(this, _mapOrder, {});
392
- __privateSet$1(this, _mapOrder, Object.fromEntries(
393
- maps?.sort((a, b) => a.name.localeCompare(b.name))?.map((x, index) => [x.key, index]) ?? []
423
+ __privateAdd$1(this, _zoneOrder, {});
424
+ __privateSet$1(this, _zoneOrder, Object.fromEntries(
425
+ zones?.sort((a, b) => a.name.localeCompare(b.name))?.map((x, index) => [x.key, index]) ?? []
394
426
  ));
395
427
  __privateSet$1(this, _badges, badges);
396
428
  for (const badge of badges) {
@@ -403,29 +435,34 @@ class BadgeIndex {
403
435
  if (result === void 0) throw new Error(`Unknown badge key [${key}]`);
404
436
  return result;
405
437
  }
438
+ badgeExists(key) {
439
+ return !!__privateGet$1(this, _badgeIndex$1)[key];
440
+ }
406
441
  searchBadges(options) {
407
442
  const filtered = options?.query || options?.filter ? __privateGet$1(this, _badges).filter((badge) => __privateMethod(this, _BadgeIndex_instances, satisfiesQueryPredicate_fn).call(this, badge, options?.query) && __privateMethod(this, _BadgeIndex_instances, satisfiesFilterPredicate_fn).call(this, badge, options?.filter)) : __privateGet$1(this, _badges);
408
- const paged = options?.pageSize ? filtered.slice(((options?.page ?? 1) - 1) * options.pageSize, (options?.page ?? 1) * options?.pageSize) : filtered;
443
+ const totalPages = options?.pageSize ? Math.ceil(filtered.length / options?.pageSize) : 1;
444
+ const page = Math.max(1, Math.min(totalPages, options?.page ?? 1));
445
+ const paged = options?.pageSize ? filtered.slice((page - 1) * options.pageSize, page * options?.pageSize) : filtered;
409
446
  const sorted = __privateMethod(this, _BadgeIndex_instances, sort_fn).call(this, paged, options?.sort);
410
447
  return {
411
448
  items: sorted,
412
- page: options?.page ?? 1,
449
+ page,
413
450
  pageSize: options?.pageSize,
414
451
  totalItems: filtered.length,
415
- totalPages: options?.pageSize ? Math.ceil(filtered.length / options?.pageSize) : 1
452
+ totalPages
416
453
  };
417
454
  }
418
455
  }
419
456
  _badges = new WeakMap();
420
457
  _badgeIndex$1 = new WeakMap();
421
- _mapOrder = new WeakMap();
458
+ _zoneOrder = new WeakMap();
422
459
  _BadgeIndex_instances = new WeakSet();
423
460
  satisfiesQueryPredicate_fn = function(badge, query) {
424
461
  const queryString = query?.str?.toLowerCase() ?? "";
425
462
  return !!((query?.on?.name ?? true) && badge.name.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || query?.on?.badgeText && badge.badgeText.canonical.some((x) => x.value.toLowerCase().includes(queryString)) || query?.on?.acquisition && badge.acquisition?.toLowerCase().includes(queryString) || query?.on?.effect && badge.effect?.toLowerCase().includes(queryString) || query?.on?.notes && badge.notes?.toLowerCase().includes(queryString) || query?.on?.setTitle && (badge.setTitle?.id?.toString().includes(queryString) || badge.setTitle?.praetorianId?.toString().includes(queryString)));
426
463
  };
427
464
  satisfiesFilterPredicate_fn = function(badge, filter) {
428
- return (!filter?.type || badge.type === filter.type) && (!filter?.mapKey || badge.mapKey === filter.mapKey) && (!filter?.alignment || badge.alignment.items.includes(filter.alignment));
465
+ return (!filter?.type || badge.type === filter.type) && (!filter?.zoneKey || badge.zoneKey === filter.zoneKey) && (!filter?.alignment || badge.alignment.items.includes(filter.alignment));
429
466
  };
430
467
  sort_fn = function(badges, sort) {
431
468
  if (!sort) return badges;
@@ -433,8 +470,8 @@ sort_fn = function(badges, sort) {
433
470
  if (!sort.by || sort.by === "CANONICAL") return sort.dir === "DESC" ? badges.reverse() : badges;
434
471
  if (sort.by === "BADGE_NAME") return ascending ? badges.sort((a, b) => a.name.default?.value.localeCompare(b.name.default?.value ?? "") ?? 0) : badges.sort((a, b) => b.name.default?.value.localeCompare(a.name.default?.value ?? "") ?? 0);
435
472
  return badges.sort((a, b) => {
436
- const aIndex = __privateGet$1(this, _mapOrder)[a.mapKey ?? ""];
437
- const bIndex = __privateGet$1(this, _mapOrder)[b.mapKey ?? ""];
473
+ const aIndex = __privateGet$1(this, _zoneOrder)[a.zoneKey ?? ""];
474
+ const bIndex = __privateGet$1(this, _zoneOrder)[b.zoneKey ?? ""];
438
475
  if (aIndex === bIndex) return 0;
439
476
  if (aIndex === void 0) return ascending ? 1 : -1;
440
477
  if (bIndex === void 0) return ascending ? -1 : 1;
@@ -442,31 +479,31 @@ sort_fn = function(badges, sort) {
442
479
  });
443
480
  };
444
481
 
445
- var __defProp$4 = Object.defineProperty;
446
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
447
- var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
482
+ var __defProp$3 = Object.defineProperty;
483
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
484
+ var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
448
485
  class BundleMetadata {
449
486
  constructor(bundle) {
450
487
  /**
451
- * Name of the server group.
488
+ * Name of the content bundle.
452
489
  */
453
- __publicField$4(this, "name");
490
+ __publicField$3(this, "name");
454
491
  /**
455
- * Description of the server group.
492
+ * Description of the fork.
456
493
  */
457
- __publicField$4(this, "description");
494
+ __publicField$3(this, "description");
458
495
  /**
459
496
  * Repository where the db content package is maintained.
460
497
  */
461
- __publicField$4(this, "repository");
498
+ __publicField$3(this, "repository");
462
499
  /**
463
- * List of external links for this Server Group. Wiki, forums, etc.
500
+ * List of external links. Wiki, forums, etc.
464
501
  */
465
- __publicField$4(this, "links");
502
+ __publicField$3(this, "links");
466
503
  /**
467
504
  * Change log for this data package.
468
505
  */
469
- __publicField$4(this, "changelog");
506
+ __publicField$3(this, "changelog");
470
507
  this.name = bundle.name;
471
508
  this.description = bundle.description;
472
509
  this.repository = bundle.repository;
@@ -475,89 +512,78 @@ class BundleMetadata {
475
512
  }
476
513
  }
477
514
 
478
- var __defProp$3 = Object.defineProperty;
479
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
480
- var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
481
- class VidiotMapPointOfInterest {
482
- constructor(data) {
483
- /**
484
- * The pixel-space position of the PoI on the map graphic.
485
- *
486
- * Screen-space, pixels from top-left `[0, 0]`.
487
- */
488
- __publicField$3(this, "pos");
489
- /**
490
- * Freeform notes about the PoI.
491
- */
492
- __publicField$3(this, "notes");
493
- /**
494
- * If the POI is a zone transfer, the map it transfers to.
495
- */
496
- __publicField$3(this, "mapKey");
497
- /**
498
- * If the POI is a badge, the badge.
499
- */
500
- __publicField$3(this, "badgeKey");
501
- /**
502
- * If the POI is a partial for a badge, the partial key.
503
- */
504
- __publicField$3(this, "badgePartialKey");
505
- this.pos = data.pos;
506
- this.notes = data.notes;
507
- this.mapKey = data.mapKey;
508
- this.badgeKey = data.badgeKey;
509
- this.badgePartialKey = data.badgePartialKey;
510
- }
511
- }
512
-
513
515
  var __defProp$2 = Object.defineProperty;
514
516
  var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
515
517
  var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
516
- class VidiotMap {
518
+ class Zone {
517
519
  constructor(data) {
518
520
  /**
519
- * URL of the map image.
521
+ * Unique key used to reference this zone.
522
+ *
523
+ * Keys can only contain lowercase letters, numbers and hyphens (`-`).
520
524
  */
521
- __publicField$2(this, "imageUrl");
525
+ __publicField$2(this, "key");
522
526
  /**
523
- * Name to display for the Vidiot map.
527
+ * The name of the zone as it appears in-game.
524
528
  */
525
529
  __publicField$2(this, "name");
526
530
  /**
527
- * List of Points of Interest labelled on the image.
531
+ * List of external links. Wiki, forums, etc.
528
532
  */
529
- __publicField$2(this, "pointsOfInterest");
530
- this.imageUrl = data.imageUrl;
533
+ __publicField$2(this, "links");
534
+ this.key = new Key(data.key).value;
531
535
  this.name = data.name;
532
- this.pointsOfInterest = data.pointsOfInterest?.map((data2) => new VidiotMapPointOfInterest(data2));
536
+ this.links = data.links ?? [];
533
537
  }
534
538
  }
535
539
 
536
540
  var __defProp$1 = Object.defineProperty;
537
541
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
538
542
  var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
539
- class GameMap {
540
- constructor(data) {
543
+ class Contact {
544
+ constructor(contactData) {
541
545
  /**
542
- * The database key for this map.
546
+ * Unique key used to reference this contact.
547
+ *
548
+ * Keys can only contain lowercase letters, numbers and hyphens (`-`).
543
549
  */
544
550
  __publicField$1(this, "key");
545
551
  /**
546
- * The name of the map as it appears in-game.
552
+ * The name of this contact.
547
553
  */
548
554
  __publicField$1(this, "name");
549
555
  /**
550
- * List of external links for this Map. Wiki, forums, etc.
556
+ * The contact's title.
551
557
  */
552
- __publicField$1(this, "links");
558
+ __publicField$1(this, "title");
553
559
  /**
554
- * List of Vidiot Map assets for this map.
560
+ * The zone this character is located in.
555
561
  */
556
- __publicField$1(this, "vidiotMaps");
557
- this.key = new Key(data.key).value;
558
- this.name = data.name;
559
- this.links = data.links;
560
- this.vidiotMaps = data.vidiotMaps?.map((data2) => new VidiotMap(data2));
562
+ __publicField$1(this, "zoneKey");
563
+ /**
564
+ * The `/loc` coordinates of the contact.
565
+ */
566
+ __publicField$1(this, "loc");
567
+ /**
568
+ * The level range this contact will offer missions for.
569
+ */
570
+ __publicField$1(this, "levelRange");
571
+ /**
572
+ * Freeform notes or tips about the contact.
573
+ */
574
+ __publicField$1(this, "notes");
575
+ /**
576
+ * List of external links. Wiki, forums, etc.
577
+ */
578
+ __publicField$1(this, "links");
579
+ this.key = new Key(contactData.key).value;
580
+ this.name = contactData.name;
581
+ this.title = contactData.title;
582
+ this.zoneKey = contactData.zoneKey;
583
+ this.loc = contactData.loc;
584
+ this.levelRange = contactData.levelRange;
585
+ this.notes = contactData.notes;
586
+ this.links = contactData.links ?? [];
561
587
  }
562
588
  }
563
589
 
@@ -571,7 +597,7 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
571
597
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
572
598
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
573
599
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
574
- var _archetypeIndex, _mapIndex, _badgeIndex;
600
+ var _archetypeIndex, _zoneIndex, _contactIndex, _badgeIndex;
575
601
  class CohContentDatabase {
576
602
  /**
577
603
  * Initialize the database with a content bundle.
@@ -579,59 +605,85 @@ class CohContentDatabase {
579
605
  */
580
606
  constructor(bundle) {
581
607
  __privateAdd(this, _archetypeIndex, {});
582
- __privateAdd(this, _mapIndex, {});
608
+ __privateAdd(this, _zoneIndex, {});
609
+ __privateAdd(this, _contactIndex, {});
583
610
  __privateAdd(this, _badgeIndex);
584
611
  /**
585
612
  * Metadata about the content bundle.
586
613
  */
587
614
  __publicField(this, "metadata");
588
615
  /**
589
- * List of the game server names in this server group.
616
+ * List of the game server names.
617
+ *
590
618
  * Torchbearer, Excelsior, etc.
591
619
  */
592
620
  __publicField(this, "servers");
593
621
  /**
594
- * List of archetypes available in this server group.
622
+ * List of archetypes.
595
623
  */
596
624
  __publicField(this, "archetypes");
597
625
  /**
598
- * List of game maps supported by this server group.
626
+ * List of game zones.
627
+ */
628
+ __publicField(this, "zones");
629
+ /**
630
+ * List of contacts.
599
631
  */
600
- __publicField(this, "maps");
632
+ __publicField(this, "contacts");
601
633
  /**
602
- * List of badges available on this server group.
634
+ * List of badges.
603
635
  */
604
636
  __publicField(this, "badges");
605
637
  this.metadata = new BundleMetadata(bundle);
606
638
  this.servers = bundle.servers ?? [];
607
639
  this.archetypes = bundle.archetypes?.map((data) => {
608
- if (__privateGet(this, _archetypeIndex)[data.key] !== void 0) throw new Error(`Duplicate archetype key [${data.key}]`);
640
+ if (__privateGet(this, _archetypeIndex)[data.key] !== void 0) throw new Error(`Duplicate archetype key '${data.key}'`);
609
641
  const archetype = new Archetype(data);
610
642
  __privateGet(this, _archetypeIndex)[archetype.key] = archetype;
611
643
  return archetype;
612
644
  }) ?? [];
613
- this.maps = bundle.maps?.map((data) => {
614
- if (__privateGet(this, _mapIndex)[data.key] !== void 0) throw new Error(`Duplicate map key [${data.key}]`);
615
- const map = new GameMap(data);
616
- __privateGet(this, _mapIndex)[map.key] = map;
617
- return map;
645
+ this.zones = bundle.zones?.map((data) => {
646
+ if (__privateGet(this, _zoneIndex)[data.key] !== void 0) throw new Error(`Duplicate zone key '${data.key}'`);
647
+ const zone = new Zone(data);
648
+ __privateGet(this, _zoneIndex)[zone.key] = zone;
649
+ return zone;
650
+ }) ?? [];
651
+ this.contacts = bundle.contacts?.map((data) => {
652
+ if (__privateGet(this, _contactIndex)[data.key] !== void 0) throw new Error(`Duplicate contact key '${data.key}'`);
653
+ const contact = new Contact(data);
654
+ __privateGet(this, _contactIndex)[contact.key] = contact;
655
+ return contact;
618
656
  }) ?? [];
619
657
  this.badges = bundle.badges?.map((data) => new Badge(data)) ?? [];
620
- __privateSet(this, _badgeIndex, new BadgeIndex(this.badges, this.maps));
658
+ __privateSet(this, _badgeIndex, new BadgeIndex(this.badges, this.zones));
621
659
  }
622
660
  getArchetype(key) {
623
661
  const result = __privateGet(this, _archetypeIndex)[key];
624
- if (result === void 0) throw new Error(`Unknown archetype key [${key}]`);
662
+ if (result === void 0) throw new Error(`Unknown archetype key '${key}'`);
625
663
  return result;
626
664
  }
627
- getMap(key) {
628
- const result = __privateGet(this, _mapIndex)[key];
629
- if (result === void 0) throw new Error(`Unknown map key [${key}]`);
665
+ getZone(key) {
666
+ const result = __privateGet(this, _zoneIndex)[key];
667
+ if (result === void 0) throw new Error(`Unknown zone key '${key}'`);
630
668
  return result;
631
669
  }
670
+ getContact(key) {
671
+ const result = __privateGet(this, _contactIndex)[key];
672
+ if (result === void 0) throw new Error(`Unknown contact key '${key}'`);
673
+ return result;
674
+ }
675
+ zoneExists(key) {
676
+ return !!__privateGet(this, _zoneIndex)[key];
677
+ }
678
+ contactExists(key) {
679
+ return !!__privateGet(this, _contactIndex)[key];
680
+ }
632
681
  getBadge(key) {
633
682
  return __privateGet(this, _badgeIndex).getBadge(key);
634
683
  }
684
+ badgeExists(key) {
685
+ return __privateGet(this, _badgeIndex).badgeExists(key);
686
+ }
635
687
  /**
636
688
  * Search, sort and filter the badge list.
637
689
  * This is a fairly brute-forced approach and will not be as performant as loading the badge data into a traditional
@@ -643,7 +695,8 @@ class CohContentDatabase {
643
695
  }
644
696
  }
645
697
  _archetypeIndex = new WeakMap();
646
- _mapIndex = new WeakMap();
698
+ _zoneIndex = new WeakMap();
699
+ _contactIndex = new WeakMap();
647
700
  _badgeIndex = new WeakMap();
648
701
 
649
702
  const CHANGELOG = [
@@ -654,9 +707,13 @@ const CHANGELOG = [
654
707
  * Server groups are now referred to as 'forks'.
655
708
  * Replaced enums with union types.
656
709
  * \`IServerGroupData\` is now \`ContentBundle\` and each database instance is now designed to accept only a single server group.
710
+ * \`GameMap\` is now \`Zone\`.
657
711
  * Removed the \`serverGroup\` property from entities to simplify the object tree given that only a single context can exist per db now.
658
712
  * Added a simple indexing and search function for badge names, text and acquisition info.
659
- * Map and badge references now follow a standard Markdown link format with a \`badge://\` or \`map://\` protocol.
713
+ * Zone and badge references now follow a standard Markdown link format with a \`badge://\` or \`map://\` protocol.
714
+ * Badge partials are now known as badge requirements and support both AND and OR groups of requirements.
715
+ * Removed the \`VidiotMap\` API as it was never used or fleshed out properly.
716
+ * Added support for story arcs to badge requirements including a link to the contact.
660
717
  * Standardized pluralization of some field names (name, icon).
661
718
  * Combined \`settitle\` ids into a single tuple field.
662
719
  * Change from GNU to The Unlicense.
@@ -677,14 +734,22 @@ function badgeLink(target) {
677
734
  const key = typeof target === "string" ? target : target.key;
678
735
  return `[${key}](${badgeUri(target)})`;
679
736
  }
680
- function mapUri(target) {
737
+ function contactUri(target) {
738
+ const key = typeof target === "string" ? target : target.key;
739
+ return `contact://${key}`;
740
+ }
741
+ function contactLink(target) {
742
+ const key = typeof target === "string" ? target : target.key;
743
+ return `[${key}](${contactUri(target)})`;
744
+ }
745
+ function zoneUri(target) {
681
746
  const key = typeof target === "string" ? target : target.key;
682
- return `map://${key}`;
747
+ return `zone://${key}`;
683
748
  }
684
- function mapLink(target) {
749
+ function zoneLink(target) {
685
750
  const key = typeof target === "string" ? target : target.key;
686
- return `[${key}](${mapUri(target)})`;
751
+ return `[${key}](${zoneUri(target)})`;
687
752
  }
688
753
 
689
- export { ALIGNMENT, Alignments, Alternates, Archetype, BADGE_PARTIAL_TYPE, BADGE_TYPE, Badge, BadgeIndex, BadgePartial, BundleMetadata, CHANGELOG, CohContentDatabase, ENHANCEMENT_CATEGORY, GameMap, Key, PLAQUE_TYPE, SEX, VidiotMap, VidiotMapPointOfInterest, badgeLink, badgeUri, mapLink, mapUri };
754
+ export { ALIGNMENT, Alignments, Alternates, Archetype, BADGE_REQUIREMENT_TYPE, BADGE_TYPE, Badge, BadgeIndex, BadgeRequirement, BundleMetadata, CHANGELOG, CohContentDatabase, Contact, ENHANCEMENT_CATEGORY, Key, PLAQUE_TYPE, SEX, Zone, badgeLink, badgeUri, contactLink, contactUri, zoneLink, zoneUri };
690
755
  //# sourceMappingURL=coh-content-db.mjs.map