coh-content-db 2.0.0-rc.4 → 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 (64) hide show
  1. package/README.md +31 -7
  2. package/dist/coh-content-db.d.ts +353 -185
  3. package/dist/coh-content-db.js +460 -300
  4. package/dist/coh-content-db.js.map +1 -1
  5. package/dist/coh-content-db.mjs +448 -294
  6. package/dist/coh-content-db.mjs.map +1 -1
  7. package/package.json +1 -4
  8. package/src/main/api/alternate-data.ts +2 -2
  9. package/src/main/api/badge-data.ts +21 -19
  10. package/src/main/api/badge-requirement-data.ts +82 -0
  11. package/src/main/api/badge-requirement-type.ts +11 -0
  12. package/src/main/api/change.ts +5 -2
  13. package/src/main/api/contact-data.ts +46 -0
  14. package/src/main/api/content-bundle.ts +12 -7
  15. package/src/main/api/markdown-string.ts +4 -0
  16. package/src/main/api/zone-data.ts +20 -0
  17. package/src/main/changelog.ts +7 -2
  18. package/src/main/db/alignments.ts +17 -0
  19. package/src/main/db/alternates.ts +8 -14
  20. package/src/main/db/badge-index.ts +93 -0
  21. package/src/main/db/badge-requirement.ts +102 -0
  22. package/src/main/db/badge-search-options.ts +51 -0
  23. package/src/main/db/badge.ts +55 -48
  24. package/src/main/db/bundle-metadata.ts +5 -6
  25. package/src/main/db/coh-content-database.ts +65 -40
  26. package/src/main/db/contact.ts +59 -0
  27. package/src/main/db/paged.ts +7 -0
  28. package/src/main/db/zone.ts +28 -0
  29. package/src/main/index.ts +15 -11
  30. package/src/main/util.ts +68 -7
  31. package/src/test/api/alignments.test.ts +40 -0
  32. package/src/test/api/badge-data.fixture.ts +9 -7
  33. package/src/test/api/badge-requirement-data.fixture.ts +17 -0
  34. package/src/test/api/badge-requirement-type.test.ts +31 -0
  35. package/src/test/api/contact-data.fixture.ts +13 -0
  36. package/src/test/api/content-bundle.fixture.ts +2 -2
  37. package/src/test/api/content-bundle.test.ts +1 -1
  38. package/src/test/api/zone-data.fixture.ts +8 -0
  39. package/src/test/db/alternates.test.ts +16 -74
  40. package/src/test/db/badge-index.test.ts +520 -0
  41. package/src/test/db/badge-requirement.test.ts +180 -0
  42. package/src/test/db/badge.test.ts +190 -15
  43. package/src/test/db/coh-content-database.test.ts +125 -18
  44. package/src/test/db/contact.test.ts +96 -0
  45. package/src/test/db/zone.test.ts +36 -0
  46. package/src/test/index.test.ts +6 -2
  47. package/src/test/util.test.ts +91 -18
  48. package/src/main/api/badge-partial-data.ts +0 -65
  49. package/src/main/api/badge-partial-type.ts +0 -8
  50. package/src/main/api/game-map-data.ts +0 -26
  51. package/src/main/api/vidiot-map-data.ts +0 -18
  52. package/src/main/api/vidiot-map-point-of-interest-data.ts +0 -30
  53. package/src/main/db/badge-partial.ts +0 -35
  54. package/src/main/db/badge-search-document.ts +0 -16
  55. package/src/main/db/game-map.ts +0 -33
  56. package/src/main/db/vidiot-map-point-of-interest.ts +0 -40
  57. package/src/main/db/vidiot-map.ts +0 -25
  58. package/src/test/api/badge-partial-data.fixture.ts +0 -17
  59. package/src/test/api/badge-partial-type.test.ts +0 -31
  60. package/src/test/api/game-map-data.fixture.ts +0 -10
  61. package/src/test/api/vidiot-map-point-of-interest.fixture.ts +0 -10
  62. package/src/test/api/vidiot-map.fixture.ts +0 -9
  63. package/src/test/db/badge-search-document.test.ts +0 -35
  64. package/src/test/db/coh-content-database-search.test.ts +0 -119
@@ -1,11 +1,15 @@
1
- import MiniSearch from 'minisearch';
2
-
3
1
  const ALIGNMENT = ["H", "V", "P"];
4
2
 
5
- const BADGE_PARTIAL_TYPE = [
3
+ const BADGE_REQUIREMENT_TYPE = [
6
4
  "PLAQUE",
7
5
  "BADGE",
8
6
  "INVENTION",
7
+ "MISSION",
8
+ // Complete a mission
9
+ "ARC",
10
+ // Complete a story arc
11
+ "TASK_FORCE",
12
+ // Complete a task force
9
13
  "INVENTION_PLUS_ONE"
10
14
  // Some invention badges require you to build x of two different invention levels, 'plus one of either level'.
11
15
  ];
@@ -64,115 +68,60 @@ const PLAQUE_TYPE = [
64
68
 
65
69
  const SEX = ["M", "F"];
66
70
 
67
- var __typeError$3 = (msg) => {
68
- throw TypeError(msg);
69
- };
70
- var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
71
- var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
72
- var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$3("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
73
- var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
74
- var __privateMethod$1 = (obj, member, method) => (__accessCheck$3(obj, member, "access private method"), method);
75
- var _value, _Key_instances, validateKey_fn;
76
- const INVALID_KEY_PATTERN = /[^a-z0-9-]/;
77
- class Key {
78
- constructor(value) {
79
- __privateAdd$3(this, _Key_instances);
80
- __privateAdd$3(this, _value);
81
- __privateMethod$1(this, _Key_instances, validateKey_fn).call(this, value);
82
- __privateSet$2(this, _value, value);
83
- }
84
- get value() {
85
- return __privateGet$3(this, _value);
86
- }
87
- }
88
- _value = new WeakMap();
89
- _Key_instances = new WeakSet();
90
- validateKey_fn = function(key) {
91
- if (INVALID_KEY_PATTERN.test(key)) throw new Error(`Invalid key: [${key}]; Keys can only contain lowercase characters, numbers and dashes.`);
92
- };
93
-
94
- var __defProp$8 = Object.defineProperty;
95
- var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
96
- var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
97
- class Archetype {
98
- constructor(data) {
99
- __publicField$8(this, "key");
100
- __publicField$8(this, "name");
101
- __publicField$8(this, "description");
102
- this.key = new Key(data.key).value;
103
- this.name = data.name;
104
- this.description = data.description;
105
- }
106
- }
107
-
108
71
  var __defProp$7 = Object.defineProperty;
109
72
  var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
110
73
  var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
111
- class BadgePartial {
112
- constructor(data) {
113
- __publicField$7(this, "key");
114
- __publicField$7(this, "type");
115
- __publicField$7(this, "mapKey");
116
- __publicField$7(this, "loc");
117
- __publicField$7(this, "plaqueType");
118
- __publicField$7(this, "inscription");
119
- __publicField$7(this, "vidiotMapKey");
120
- __publicField$7(this, "badgeKey");
121
- __publicField$7(this, "inventionLevel");
122
- __publicField$7(this, "inventionTypes");
123
- __publicField$7(this, "inventionCount");
124
- __publicField$7(this, "notes");
125
- this.key = new Key(data.key).value;
126
- this.type = data.type;
127
- this.mapKey = data.mapKey;
128
- this.loc = data.loc;
129
- this.plaqueType = data.plaqueType;
130
- this.inscription = data.inscription;
131
- this.vidiotMapKey = data.vidiotMapKey;
132
- this.badgeKey = data.badgeKey;
133
- this.inventionLevel = data.inventionLevel;
134
- this.inventionTypes = data.inventionTypes;
135
- this.inventionCount = data.inventionCount;
136
- this.notes = data.notes;
74
+ class Alignments {
75
+ constructor(raw) {
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");
81
+ this.items = raw;
82
+ this.hero = raw.includes("H");
83
+ this.villain = raw.includes("V");
84
+ this.praetorian = raw.includes("P");
85
+ this.primal = !this.praetorian && (this.hero || this.villain);
137
86
  }
138
87
  }
139
88
 
140
- var __typeError$2 = (msg) => {
89
+ var __typeError$4 = (msg) => {
141
90
  throw TypeError(msg);
142
91
  };
143
- var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
144
- var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
145
- 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);
146
- var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$2(obj, member, "write to private field"), member.set(obj, value), value);
147
- var __privateMethod = (obj, member, method) => (__accessCheck$2(obj, member, "access private method"), method);
92
+ var __accessCheck$4 = (obj, member, msg) => member.has(obj) || __typeError$4("Cannot " + msg);
93
+ var __privateGet$4 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
94
+ var __privateAdd$4 = (obj, member, value) => member.has(obj) ? __typeError$4("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
95
+ var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
96
+ var __privateMethod$2 = (obj, member, method) => (__accessCheck$4(obj, member, "access private method"), method);
148
97
  var _sortedValues, _Alternates_instances, compareAlternates_fn, compareAlignment_fn, compareSex_fn;
149
98
  const ALIGNMENT_SORT = { H: 2, V: 1, P: 0 };
150
99
  const SEX_SORT = { M: 1, F: 0 };
151
100
  class Alternates {
152
101
  constructor(values) {
153
- __privateAdd$2(this, _Alternates_instances);
154
- __privateAdd$2(this, _sortedValues, []);
155
- __privateSet$1(this, _sortedValues, values.sort());
156
- __privateGet$2(this, _sortedValues).sort((a, b) => __privateMethod(this, _Alternates_instances, compareAlternates_fn).call(this, a, b));
102
+ __privateAdd$4(this, _Alternates_instances);
103
+ __privateAdd$4(this, _sortedValues, []);
104
+ __privateSet$3(this, _sortedValues, values.sort());
105
+ __privateGet$4(this, _sortedValues).sort((a, b) => __privateMethod$2(this, _Alternates_instances, compareAlternates_fn).call(this, a, b));
157
106
  }
158
107
  getValue(alignment, sex) {
159
- for (let index = __privateGet$2(this, _sortedValues).length; index--; ) {
160
- const entry = __privateGet$2(this, _sortedValues)[index];
108
+ for (let index = __privateGet$4(this, _sortedValues).length; index--; ) {
109
+ const entry = __privateGet$4(this, _sortedValues)[index];
161
110
  if ((entry.alignment === void 0 || entry.alignment === alignment) && (entry.sex === void 0 || entry.sex === sex)) return entry.value;
162
111
  }
163
- return this.default;
112
+ return this.default?.value;
164
113
  }
165
114
  /**
166
115
  * Get the default value for this list of alternates, the value with the highest priority and lowest specificity.
167
116
  */
168
117
  get default() {
169
- return __privateGet$2(this, _sortedValues)[0]?.value;
118
+ return __privateGet$4(this, _sortedValues)[0];
170
119
  }
171
120
  /**
172
121
  * Get the list of alternates sorted in canonical order (alignment then sex, low to high specificity).
173
122
  */
174
123
  get canonical() {
175
- return __privateGet$2(this, _sortedValues);
124
+ return __privateGet$4(this, _sortedValues);
176
125
  }
177
126
  /**
178
127
  * Create a joined string from the alternate values in canonical order.
@@ -188,9 +137,9 @@ compareAlternates_fn = function(a, b) {
188
137
  const aSpecificity = (a.alignment ? 2 : 0) + (a.sex ? 1 : 0);
189
138
  const bSpecificity = (b.alignment ? 2 : 0) + (b.sex ? 1 : 0);
190
139
  if (aSpecificity !== bSpecificity) return aSpecificity - bSpecificity;
191
- const alignmentComparison = __privateMethod(this, _Alternates_instances, compareAlignment_fn).call(this, a.alignment, b.alignment);
140
+ const alignmentComparison = __privateMethod$2(this, _Alternates_instances, compareAlignment_fn).call(this, a.alignment, b.alignment);
192
141
  if (alignmentComparison !== 0) return alignmentComparison;
193
- const sexComparison = __privateMethod(this, _Alternates_instances, compareSex_fn).call(this, a.sex, b.sex);
142
+ const sexComparison = __privateMethod$2(this, _Alternates_instances, compareSex_fn).call(this, a.sex, b.sex);
194
143
  if (sexComparison !== 0) return sexComparison;
195
144
  return String(a.value).localeCompare(String(b.value));
196
145
  };
@@ -200,8 +149,7 @@ compareAlignment_fn = function(a, b) {
200
149
  if (b === void 0 && a !== void 0) return 1;
201
150
  const aSort = a === void 0 ? -1 : ALIGNMENT_SORT[a] ?? -1;
202
151
  const bSort = b === void 0 ? -1 : ALIGNMENT_SORT[b] ?? -1;
203
- if (aSort !== bSort) return bSort - aSort;
204
- return a?.localeCompare(b ?? "") ?? 0;
152
+ return bSort - aSort;
205
153
  };
206
154
  compareSex_fn = function(a, b) {
207
155
  if (a === b) return 0;
@@ -209,242 +157,353 @@ compareSex_fn = function(a, b) {
209
157
  if (b === void 0 && a !== void 0) return 1;
210
158
  const aSort = SEX_SORT[a ?? -1] ?? -1;
211
159
  const bSort = SEX_SORT[b ?? -1] ?? -1;
212
- if (aSort !== bSort) return bSort - aSort;
213
- return a?.localeCompare(b ?? "") ?? 0;
160
+ return bSort - aSort;
214
161
  };
215
162
 
216
- var __defProp$6 = Object.defineProperty;
217
- var __typeError$1 = (msg) => {
163
+ var __typeError$3 = (msg) => {
218
164
  throw TypeError(msg);
219
165
  };
166
+ var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
167
+ var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
168
+ var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$3("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
169
+ var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
170
+ var __privateMethod$1 = (obj, member, method) => (__accessCheck$3(obj, member, "access private method"), method);
171
+ var _value, _Key_instances, validateKey_fn;
172
+ const INVALID_KEY_PATTERN = /[^a-z0-9-]/;
173
+ class Key {
174
+ constructor(value) {
175
+ __privateAdd$3(this, _Key_instances);
176
+ __privateAdd$3(this, _value);
177
+ __privateMethod$1(this, _Key_instances, validateKey_fn).call(this, value);
178
+ __privateSet$2(this, _value, value);
179
+ }
180
+ get value() {
181
+ return __privateGet$3(this, _value);
182
+ }
183
+ }
184
+ _value = new WeakMap();
185
+ _Key_instances = new WeakSet();
186
+ validateKey_fn = function(key) {
187
+ if (INVALID_KEY_PATTERN.test(key)) throw new Error(`Invalid key: [${key}]; Keys can only contain lowercase characters, numbers and dashes.`);
188
+ };
189
+
190
+ var __defProp$6 = Object.defineProperty;
220
191
  var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
221
192
  var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
222
- var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
223
- var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
224
- 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);
225
- var _partialsIndex;
226
- class Badge {
193
+ class Archetype {
227
194
  constructor(data) {
228
- __privateAdd$1(this, _partialsIndex, {});
229
- /**
230
- * The database key for this badge.
231
- */
232
195
  __publicField$6(this, "key");
196
+ __publicField$6(this, "name");
197
+ __publicField$6(this, "description");
198
+ this.key = new Key(data.key).value;
199
+ this.name = data.name;
200
+ this.description = data.description;
201
+ }
202
+ }
203
+
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 {
208
+ constructor(data) {
233
209
  /**
234
- * The type of badge.
210
+ * Key.
235
211
  */
236
- __publicField$6(this, "type");
212
+ __publicField$5(this, "key");
237
213
  /**
238
- * The name of this badge.
239
- *
240
- * May vary by character sex or alignment.
214
+ * Type of requirement.
241
215
  */
242
- __publicField$6(this, "name");
216
+ __publicField$5(this, "type");
243
217
  /**
244
- * The character alignments that this badge is available to.
218
+ * Zone the requirement is located in.
245
219
  */
246
- __publicField$6(this, "alignment");
220
+ __publicField$5(this, "zoneKey");
247
221
  /**
248
- * The badge text as it appears in-game. May vary by character sex or alignment.
222
+ * /loc coordinates.
249
223
  */
250
- __publicField$6(this, "badgeText");
224
+ __publicField$5(this, "loc");
251
225
  /**
252
- * Description of how to acquire the badge.
253
- *
254
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
226
+ * Is it a wall plaque or a physical monument?
255
227
  */
256
- __publicField$6(this, "acquisition");
228
+ __publicField$5(this, "plaqueType");
257
229
  /**
258
- * Absolute URL to this badge's icon.
259
- *
260
- * May vary by character sex or alignment.
230
+ * Plaque inscription.
261
231
  */
262
- __publicField$6(this, "icon");
232
+ __publicField$5(this, "plaqueInscription");
263
233
  /**
264
- * Freeform notes or tips about the badge.
265
- *
266
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
234
+ * The number or letter the plaque appears as on Vidiot Maps.
267
235
  */
268
- __publicField$6(this, "notes");
236
+ __publicField$5(this, "vidiotMapKey");
269
237
  /**
270
- * List of external links for this Badge. Wiki, forums, etc.
238
+ * The key of the badge for this requirement.
271
239
  */
272
- __publicField$6(this, "links");
240
+ __publicField$5(this, "badgeKey");
273
241
  /**
274
- * For exploration badges, the key of the {@link GameMap} that this badge is found on.
242
+ * Mission name.
275
243
  */
276
- __publicField$6(this, "mapKey");
244
+ __publicField$5(this, "missionName");
277
245
  /**
278
- * For exploration badges, the `/loc` coordinates of the badge on the in-game map.
246
+ * {@link Contact} key for the story arc.
279
247
  */
280
- __publicField$6(this, "loc");
248
+ __publicField$5(this, "contactKey");
281
249
  /**
282
- * For badges that appear on a Vidiot Map, the number or letter the badge appears as.
250
+ * Level of the invention required.
283
251
  */
284
- __publicField$6(this, "vidiotMapKey");
252
+ __publicField$5(this, "inventionLevel");
285
253
  /**
286
- * ID used with the in-game `/settitle` command to apply the badge.
254
+ * The types of enhancements required to be crafted.
287
255
  */
288
- __publicField$6(this, "setTitle");
256
+ __publicField$5(this, "inventionTypes");
289
257
  /**
290
- * A description of the effect the badge will have, such as a buff or granting a temporary power.
291
- *
292
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
258
+ * Number of invention crafts required.
293
259
  */
294
- __publicField$6(this, "effect");
260
+ __publicField$5(this, "inventionCount");
295
261
  /**
296
- * 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.
262
+ * Any additional notes.
297
263
  */
298
- __publicField$6(this, "partials");
264
+ __publicField$5(this, "notes");
299
265
  /**
300
- * 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.
266
+ * List of external links. Wiki, forums, etc.
301
267
  */
302
- __publicField$6(this, "ignoreInTotals");
268
+ __publicField$5(this, "links");
303
269
  this.key = new Key(data.key).value;
304
270
  this.type = data.type;
305
- this.name = new Alternates(data.name);
306
- this.alignment = data.alignment;
307
- this.badgeText = new Alternates(data.badgeText ?? []);
308
- this.acquisition = data.acquisition;
309
- this.icon = new Alternates(data.icon ?? []);
310
- this.notes = data.notes;
311
- this.links = data.links;
312
- this.mapKey = data.mapKey;
271
+ this.zoneKey = data.zoneKey;
313
272
  this.loc = data.loc;
314
- this.effect = data.effect;
273
+ this.plaqueType = data.plaqueType;
274
+ this.plaqueInscription = data.plaqueInscription;
315
275
  this.vidiotMapKey = data.vidiotMapKey;
316
- this.setTitle = data.setTitle;
317
- this.ignoreInTotals = data.ignoreInTotals ?? false;
318
- this.partials = data.partials?.map((data2) => {
319
- if (__privateGet$1(this, _partialsIndex)[data2.key] !== void 0) throw new Error(`Duplicate badge partial key [${data2.key}]`);
320
- const badge = new BadgePartial(data2);
321
- __privateGet$1(this, _partialsIndex)[badge.key] = badge;
322
- return badge;
323
- });
324
- }
325
- getPartial(key) {
326
- const result = __privateGet$1(this, _partialsIndex)[key];
327
- if (result === void 0) throw new Error(`Unknown badge partial key [${key}]`);
328
- return result;
276
+ this.badgeKey = data.badgeKey;
277
+ this.missionName = data.missionName;
278
+ this.contactKey = data.contactKey;
279
+ this.inventionLevel = data.inventionLevel;
280
+ this.inventionTypes = data.inventionTypes;
281
+ this.inventionCount = data.inventionCount;
282
+ this.notes = data.notes;
283
+ this.links = data.links ?? [];
329
284
  }
330
285
  }
331
- _partialsIndex = new WeakMap();
332
286
 
333
- var __defProp$5 = Object.defineProperty;
334
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
335
- var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
336
- class VidiotMapPointOfInterest {
337
- constructor(data) {
287
+ var __defProp$4 = Object.defineProperty;
288
+ var __typeError$2 = (msg) => {
289
+ throw TypeError(msg);
290
+ };
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);
293
+ var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
294
+ var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
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);
296
+ var _requirementsIndex;
297
+ class Badge {
298
+ constructor(badgeData) {
299
+ __privateAdd$2(this, _requirementsIndex, {});
338
300
  /**
339
- * The pixel-space position of the PoI on the map graphic.
340
- *
341
- * Screen-space, pixels from top-left `[0, 0]`.
301
+ * The database key for this badge.
342
302
  */
343
- __publicField$5(this, "pos");
303
+ __publicField$4(this, "key");
344
304
  /**
345
- * Freeform notes about the PoI.
305
+ * The type of badge.
306
+ */
307
+ __publicField$4(this, "type");
308
+ /**
309
+ * The name of this badge.
346
310
  *
347
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
311
+ * May vary by character sex or alignment.
348
312
  */
349
- __publicField$5(this, "notes");
313
+ __publicField$4(this, "name");
350
314
  /**
351
- * If the POI is a zone transfer, the map it transfers to.
315
+ * The character alignments that this badge is available to.
352
316
  */
353
- __publicField$5(this, "mapKey");
317
+ __publicField$4(this, "alignment");
354
318
  /**
355
- * If the POI is a badge, the badge.
319
+ * The badge text as it appears in-game. May vary by character sex or alignment.
356
320
  */
357
- __publicField$5(this, "badgeKey");
321
+ __publicField$4(this, "badgeText");
358
322
  /**
359
- * If the POI is a partial for a badge, the partial key.
323
+ * Short description of how to acquire the badge. Detailed instructions will be in the notes field.
360
324
  */
361
- __publicField$5(this, "badgePartialKey");
362
- this.pos = data.pos;
363
- this.notes = data.notes;
364
- this.mapKey = data.mapKey;
365
- this.badgeKey = data.badgeKey;
366
- this.badgePartialKey = data.badgePartialKey;
367
- }
368
- }
369
-
370
- var __defProp$4 = Object.defineProperty;
371
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
372
- var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
373
- class VidiotMap {
374
- constructor(data) {
325
+ __publicField$4(this, "acquisition");
375
326
  /**
376
- * URL of the map image.
327
+ * Absolute URL to this badge's icon.
328
+ *
329
+ * May vary by character sex or alignment.
377
330
  */
378
- __publicField$4(this, "imageUrl");
331
+ __publicField$4(this, "icon");
379
332
  /**
380
- * Name to display for the Vidiot map.
333
+ * Freeform notes or tips about the badge.
381
334
  */
382
- __publicField$4(this, "name");
335
+ __publicField$4(this, "notes");
383
336
  /**
384
- * List of Points of Interest labelled on the image.
337
+ * List of external links. Wiki, forums, etc.
385
338
  */
386
- __publicField$4(this, "pointsOfInterest");
387
- this.imageUrl = data.imageUrl;
388
- this.name = data.name;
389
- this.pointsOfInterest = data.pointsOfInterest?.map((data2) => new VidiotMapPointOfInterest(data2));
390
- }
391
- }
392
-
393
- var __defProp$3 = Object.defineProperty;
394
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
395
- var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
396
- class GameMap {
397
- constructor(data) {
339
+ __publicField$4(this, "links");
398
340
  /**
399
- * The database key for this map.
341
+ * For exploration badges, the key of the {@link Zone} that this badge is found on.
400
342
  */
401
- __publicField$3(this, "key");
343
+ __publicField$4(this, "zoneKey");
402
344
  /**
403
- * The name of the map as it appears in-game.
345
+ * For exploration badges, the `/loc` coordinates of the badge.
404
346
  */
405
- __publicField$3(this, "name");
347
+ __publicField$4(this, "loc");
406
348
  /**
407
- * List of external links for this Map. Wiki, forums, etc.
349
+ * For plaques that appear on a Vidiot Map, the number or letter the badge appears as.
408
350
  */
409
- __publicField$3(this, "links");
351
+ __publicField$4(this, "vidiotMapKey");
410
352
  /**
411
- * List of Vidiot Map assets for this map.
353
+ * ID used with the in-game `/settitle` command to apply the badge.
412
354
  */
413
- __publicField$3(this, "vidiotMaps");
414
- this.key = new Key(data.key).value;
415
- this.name = data.name;
416
- this.links = data.links;
417
- this.vidiotMaps = data.vidiotMaps?.map((data2) => new VidiotMap(data2));
355
+ __publicField$4(this, "setTitle");
356
+ /**
357
+ * A description of the effect the badge will have, such as a buff or granting a temporary power.
358
+ */
359
+ __publicField$4(this, "effect");
360
+ /**
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.
369
+ */
370
+ __publicField$4(this, "requirements");
371
+ /**
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.
373
+ */
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
+ });
399
+ });
400
+ }
401
+ getRequirement(key) {
402
+ const result = __privateGet$2(this, _requirementsIndex)[key];
403
+ if (result === void 0) throw new Error(`Unknown badge requirement key [${key}]`);
404
+ return result;
418
405
  }
419
406
  }
407
+ _requirementsIndex = new WeakMap();
420
408
 
421
- var __defProp$2 = Object.defineProperty;
422
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
423
- var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
409
+ var __typeError$1 = (msg) => {
410
+ throw TypeError(msg);
411
+ };
412
+ var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
413
+ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
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);
415
+ var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
416
+ var __privateMethod = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
417
+ var _badges, _badgeIndex$1, _zoneOrder, _BadgeIndex_instances, satisfiesQueryPredicate_fn, satisfiesFilterPredicate_fn, sort_fn;
418
+ class BadgeIndex {
419
+ constructor(badges, zones) {
420
+ __privateAdd$1(this, _BadgeIndex_instances);
421
+ __privateAdd$1(this, _badges, []);
422
+ __privateAdd$1(this, _badgeIndex$1, {});
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]) ?? []
426
+ ));
427
+ __privateSet$1(this, _badges, badges);
428
+ for (const badge of badges) {
429
+ if (__privateGet$1(this, _badgeIndex$1)[badge.key] !== void 0) throw new Error(`Duplicate badge key [${badge.key}]`);
430
+ __privateGet$1(this, _badgeIndex$1)[badge.key] = badge;
431
+ }
432
+ }
433
+ getBadge(key) {
434
+ const result = __privateGet$1(this, _badgeIndex$1)[key];
435
+ if (result === void 0) throw new Error(`Unknown badge key [${key}]`);
436
+ return result;
437
+ }
438
+ badgeExists(key) {
439
+ return !!__privateGet$1(this, _badgeIndex$1)[key];
440
+ }
441
+ searchBadges(options) {
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);
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;
446
+ const sorted = __privateMethod(this, _BadgeIndex_instances, sort_fn).call(this, paged, options?.sort);
447
+ return {
448
+ items: sorted,
449
+ page,
450
+ pageSize: options?.pageSize,
451
+ totalItems: filtered.length,
452
+ totalPages
453
+ };
454
+ }
455
+ }
456
+ _badges = new WeakMap();
457
+ _badgeIndex$1 = new WeakMap();
458
+ _zoneOrder = new WeakMap();
459
+ _BadgeIndex_instances = new WeakSet();
460
+ satisfiesQueryPredicate_fn = function(badge, query) {
461
+ const queryString = query?.str?.toLowerCase() ?? "";
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)));
463
+ };
464
+ satisfiesFilterPredicate_fn = function(badge, filter) {
465
+ return (!filter?.type || badge.type === filter.type) && (!filter?.zoneKey || badge.zoneKey === filter.zoneKey) && (!filter?.alignment || badge.alignment.items.includes(filter.alignment));
466
+ };
467
+ sort_fn = function(badges, sort) {
468
+ if (!sort) return badges;
469
+ const ascending = sort.dir !== "DESC";
470
+ if (!sort.by || sort.by === "CANONICAL") return sort.dir === "DESC" ? badges.reverse() : badges;
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);
472
+ return badges.sort((a, b) => {
473
+ const aIndex = __privateGet$1(this, _zoneOrder)[a.zoneKey ?? ""];
474
+ const bIndex = __privateGet$1(this, _zoneOrder)[b.zoneKey ?? ""];
475
+ if (aIndex === bIndex) return 0;
476
+ if (aIndex === void 0) return ascending ? 1 : -1;
477
+ if (bIndex === void 0) return ascending ? -1 : 1;
478
+ return ascending ? aIndex - bIndex : bIndex - aIndex;
479
+ });
480
+ };
481
+
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);
424
485
  class BundleMetadata {
425
486
  constructor(bundle) {
426
487
  /**
427
- * Name of the server group.
488
+ * Name of the content bundle.
428
489
  */
429
- __publicField$2(this, "name");
490
+ __publicField$3(this, "name");
430
491
  /**
431
- * Description of the server group.
432
- *
433
- * Supports {@link https://www.markdownguide.org/|Markdown} format.
492
+ * Description of the fork.
434
493
  */
435
- __publicField$2(this, "description");
494
+ __publicField$3(this, "description");
436
495
  /**
437
496
  * Repository where the db content package is maintained.
438
497
  */
439
- __publicField$2(this, "repository");
498
+ __publicField$3(this, "repository");
440
499
  /**
441
- * List of external links for this Server Group. Wiki, forums, etc.
500
+ * List of external links. Wiki, forums, etc.
442
501
  */
443
- __publicField$2(this, "links");
502
+ __publicField$3(this, "links");
444
503
  /**
445
504
  * Change log for this data package.
446
505
  */
447
- __publicField$2(this, "changelog");
506
+ __publicField$3(this, "changelog");
448
507
  this.name = bundle.name;
449
508
  this.description = bundle.description;
450
509
  this.repository = bundle.repository;
@@ -453,20 +512,78 @@ class BundleMetadata {
453
512
  }
454
513
  }
455
514
 
515
+ var __defProp$2 = Object.defineProperty;
516
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
517
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
518
+ class Zone {
519
+ constructor(data) {
520
+ /**
521
+ * Unique key used to reference this zone.
522
+ *
523
+ * Keys can only contain lowercase letters, numbers and hyphens (`-`).
524
+ */
525
+ __publicField$2(this, "key");
526
+ /**
527
+ * The name of the zone as it appears in-game.
528
+ */
529
+ __publicField$2(this, "name");
530
+ /**
531
+ * List of external links. Wiki, forums, etc.
532
+ */
533
+ __publicField$2(this, "links");
534
+ this.key = new Key(data.key).value;
535
+ this.name = data.name;
536
+ this.links = data.links ?? [];
537
+ }
538
+ }
539
+
456
540
  var __defProp$1 = Object.defineProperty;
457
541
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
458
542
  var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
459
- class BadgeSearchDocument {
460
- constructor(badge) {
461
- __publicField$1(this, "id");
543
+ class Contact {
544
+ constructor(contactData) {
545
+ /**
546
+ * Unique key used to reference this contact.
547
+ *
548
+ * Keys can only contain lowercase letters, numbers and hyphens (`-`).
549
+ */
462
550
  __publicField$1(this, "key");
551
+ /**
552
+ * The name of this contact.
553
+ */
463
554
  __publicField$1(this, "name");
464
- __publicField$1(this, "badgeText");
465
- __publicField$1(this, "acquisition");
466
- this.id = this.key = badge.key;
467
- this.name = badge.name.toString(", ");
468
- this.badgeText = badge.badgeText.toString(", ");
469
- this.acquisition = badge.acquisition ?? "";
555
+ /**
556
+ * The contact's title.
557
+ */
558
+ __publicField$1(this, "title");
559
+ /**
560
+ * The zone this character is located in.
561
+ */
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 ?? [];
470
587
  }
471
588
  }
472
589
 
@@ -480,7 +597,7 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
480
597
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
481
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);
482
599
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
483
- var _archetypeIndex, _mapIndex, _badgeIndex, _badgeSearch;
600
+ var _archetypeIndex, _zoneIndex, _contactIndex, _badgeIndex;
484
601
  class CohContentDatabase {
485
602
  /**
486
603
  * Initialize the database with a content bundle.
@@ -488,83 +605,99 @@ class CohContentDatabase {
488
605
  */
489
606
  constructor(bundle) {
490
607
  __privateAdd(this, _archetypeIndex, {});
491
- __privateAdd(this, _mapIndex, {});
492
- __privateAdd(this, _badgeIndex, {});
493
- __privateAdd(this, _badgeSearch);
608
+ __privateAdd(this, _zoneIndex, {});
609
+ __privateAdd(this, _contactIndex, {});
610
+ __privateAdd(this, _badgeIndex);
494
611
  /**
495
612
  * Metadata about the content bundle.
496
613
  */
497
614
  __publicField(this, "metadata");
498
615
  /**
499
- * List of the game server names in this server group.
616
+ * List of the game server names.
617
+ *
500
618
  * Torchbearer, Excelsior, etc.
501
619
  */
502
620
  __publicField(this, "servers");
503
621
  /**
504
- * List of archetypes available in this server group.
622
+ * List of archetypes.
505
623
  */
506
624
  __publicField(this, "archetypes");
507
625
  /**
508
- * List of game maps supported by this server group.
626
+ * List of game zones.
627
+ */
628
+ __publicField(this, "zones");
629
+ /**
630
+ * List of contacts.
509
631
  */
510
- __publicField(this, "maps");
632
+ __publicField(this, "contacts");
511
633
  /**
512
- * List of badges available on this server group.
634
+ * List of badges.
513
635
  */
514
636
  __publicField(this, "badges");
515
637
  this.metadata = new BundleMetadata(bundle);
516
638
  this.servers = bundle.servers ?? [];
517
639
  this.archetypes = bundle.archetypes?.map((data) => {
518
- 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}'`);
519
641
  const archetype = new Archetype(data);
520
642
  __privateGet(this, _archetypeIndex)[archetype.key] = archetype;
521
643
  return archetype;
522
644
  }) ?? [];
523
- this.maps = bundle.maps?.map((data) => {
524
- if (__privateGet(this, _mapIndex)[data.key] !== void 0) throw new Error(`Duplicate map key [${data.key}]`);
525
- const map = new GameMap(data);
526
- __privateGet(this, _mapIndex)[map.key] = map;
527
- 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;
528
650
  }) ?? [];
529
- this.badges = bundle.badges?.map((data) => {
530
- if (__privateGet(this, _badgeIndex)[data.key] !== void 0) throw new Error(`Duplicate badge key [${data.key}]`);
531
- const badge = new Badge(data);
532
- __privateGet(this, _badgeIndex)[badge.key] = badge;
533
- return badge;
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;
534
656
  }) ?? [];
535
- __privateSet(this, _badgeSearch, new MiniSearch({
536
- fields: ["key", "name", "badgeText", "acquisition"],
537
- storeFields: ["key"]
538
- }));
539
- for (const badge of this.badges) {
540
- __privateGet(this, _badgeSearch).add(new BadgeSearchDocument(badge));
541
- }
657
+ this.badges = bundle.badges?.map((data) => new Badge(data)) ?? [];
658
+ __privateSet(this, _badgeIndex, new BadgeIndex(this.badges, this.zones));
542
659
  }
543
660
  getArchetype(key) {
544
661
  const result = __privateGet(this, _archetypeIndex)[key];
545
- if (result === void 0) throw new Error(`Unknown archetype key [${key}]`);
662
+ if (result === void 0) throw new Error(`Unknown archetype key '${key}'`);
546
663
  return result;
547
664
  }
548
- getMap(key) {
549
- const result = __privateGet(this, _mapIndex)[key];
550
- 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}'`);
551
668
  return result;
552
669
  }
553
- getBadge(key) {
554
- const result = __privateGet(this, _badgeIndex)[key];
555
- if (result === void 0) throw new Error(`Unknown badge key [${key}]`);
670
+ getContact(key) {
671
+ const result = __privateGet(this, _contactIndex)[key];
672
+ if (result === void 0) throw new Error(`Unknown contact key '${key}'`);
556
673
  return result;
557
674
  }
558
- searchBadges(query) {
559
- if (!query) return this.badges;
560
- const keys = __privateGet(this, _badgeSearch).search(query, { prefix: true, fuzzy: true });
561
- return keys.map((result) => this.getBadge(result["key"]));
675
+ zoneExists(key) {
676
+ return !!__privateGet(this, _zoneIndex)[key];
677
+ }
678
+ contactExists(key) {
679
+ return !!__privateGet(this, _contactIndex)[key];
680
+ }
681
+ getBadge(key) {
682
+ return __privateGet(this, _badgeIndex).getBadge(key);
683
+ }
684
+ badgeExists(key) {
685
+ return __privateGet(this, _badgeIndex).badgeExists(key);
686
+ }
687
+ /**
688
+ * Search, sort and filter the badge list.
689
+ * This is a fairly brute-forced approach and will not be as performant as loading the badge data into a traditional
690
+ * database engine, but is sufficient for most operations.
691
+ * @param options {@link BadgeSearchOptions}
692
+ */
693
+ searchBadges(options) {
694
+ return __privateGet(this, _badgeIndex).searchBadges(options);
562
695
  }
563
696
  }
564
697
  _archetypeIndex = new WeakMap();
565
- _mapIndex = new WeakMap();
698
+ _zoneIndex = new WeakMap();
699
+ _contactIndex = new WeakMap();
566
700
  _badgeIndex = new WeakMap();
567
- _badgeSearch = new WeakMap();
568
701
 
569
702
  const CHANGELOG = [
570
703
  {
@@ -572,14 +705,19 @@ const CHANGELOG = [
572
705
  date: /* @__PURE__ */ new Date("2025-03-12"),
573
706
  description: `* Replaced redundant interfaces with their concrete equivalents.
574
707
  * Server groups are now referred to as 'forks'.
575
- * Replaced enums with extensible union types; Forks with new badge types, enhancement types, etc. can now extend them locally.
708
+ * Replaced enums with union types.
576
709
  * \`IServerGroupData\` is now \`ContentBundle\` and each database instance is now designed to accept only a single server group.
710
+ * \`GameMap\` is now \`Zone\`.
577
711
  * Removed the \`serverGroup\` property from entities to simplify the object tree given that only a single context can exist per db now.
578
712
  * Added a simple indexing and search function for badge names, text and acquisition info.
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.
579
717
  * Standardized pluralization of some field names (name, icon).
580
718
  * Combined \`settitle\` ids into a single tuple field.
581
719
  * Change from GNU to The Unlicense.
582
- * Removed dependency on lodash.
720
+ * Removed all third-party dependencies.
583
721
  * Moved from webpack to rollup for packaging.
584
722
  * Add eslint for linting.
585
723
  * Add jest for unit tests.
@@ -588,14 +726,30 @@ const CHANGELOG = [
588
726
  }
589
727
  ];
590
728
 
591
- function createBadgeReference(target) {
729
+ function badgeUri(target) {
730
+ const key = typeof target === "string" ? target : target.key;
731
+ return `badge://${key}`;
732
+ }
733
+ function badgeLink(target) {
734
+ const key = typeof target === "string" ? target : target.key;
735
+ return `[${key}](${badgeUri(target)})`;
736
+ }
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) {
592
746
  const key = typeof target === "string" ? target : target.key;
593
- return `[badge:${key}]`;
747
+ return `zone://${key}`;
594
748
  }
595
- function createMapReference(target) {
749
+ function zoneLink(target) {
596
750
  const key = typeof target === "string" ? target : target.key;
597
- return `[map:${key}]`;
751
+ return `[${key}](${zoneUri(target)})`;
598
752
  }
599
753
 
600
- export { ALIGNMENT, Archetype, BADGE_PARTIAL_TYPE, BADGE_TYPE, Badge, BadgePartial, BundleMetadata, CHANGELOG, CohContentDatabase, ENHANCEMENT_CATEGORY, GameMap, Key, PLAQUE_TYPE, SEX, VidiotMap, VidiotMapPointOfInterest, createBadgeReference, createMapReference };
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 };
601
755
  //# sourceMappingURL=coh-content-db.mjs.map