@jsprismarine/spawning 0.0.0 → 0.16.0-unstable-20261029140140

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.
@@ -0,0 +1,278 @@
1
+ import { SPAWN_CONSTANTS, poolCapFor } from "./constants.es.js";
2
+ import { SpawnDelays, evaluateSpawnCondition } from "./conditions.es.js";
3
+ import { VANILLA_ENGINE_SPAWN_RULES } from "./engineRules.es.js";
4
+ // src/spawner.ts
5
+ /** Splits `minecraft:pillager<minecraft:spawn_as_patrol_follower>` into its two halves. */
6
+ var splitSpawnType = (value) => {
7
+ const match = /^(?<identifier>[^<]+)<(?<event>[^>]+)>$/.exec(value);
8
+ if (match?.groups === void 0) return { identifier: value };
9
+ return {
10
+ identifier: match.groups.identifier,
11
+ event: match.groups.event
12
+ };
13
+ };
14
+ /** Draws an integer in the inclusive range, which is how every size and offset is picked. */
15
+ var between = (random, min, max) => max <= min ? min : min + random.nextInt(max - min + 1);
16
+ /**
17
+ * Builds the permutation each herd member spawns as.
18
+ *
19
+ * `min_guaranteed` members take their permutation before the weighted draw
20
+ * runs, which is what makes the pillager patrol's captain and the zombie
21
+ * herd's one villager certain.
22
+ */
23
+ var permutationsFor = (permutations, size, random) => {
24
+ const members = [];
25
+ for (const permutation of permutations) for (let index = 0; index < permutation.minGuaranteed && members.length < size; index += 1) members.push(permutation);
26
+ const total = permutations.reduce((sum, permutation) => sum + Math.max(0, permutation.weight), 0);
27
+ while (members.length < size) {
28
+ if (total <= 0) {
29
+ members.push(void 0);
30
+ continue;
31
+ }
32
+ let roll = random.nextFloat() * total;
33
+ let chosen;
34
+ for (const permutation of permutations) {
35
+ roll -= Math.max(0, permutation.weight);
36
+ if (roll < 0) {
37
+ chosen = permutation;
38
+ break;
39
+ }
40
+ }
41
+ members.push(chosen ?? permutations[permutations.length - 1]);
42
+ }
43
+ return members;
44
+ };
45
+ /**
46
+ * The event one herd member runs.
47
+ *
48
+ * `initial_event` wins for the first `initial_event_count` members, `event`
49
+ * takes every member past `event_skip_count`, and a permutation's `<event>`
50
+ * suffix or the condition's `minecraft:spawn_event` fills in for the rest.
51
+ */
52
+ var eventForMember = (index, herd, permutationEvent, condition) => {
53
+ if (herd?.initialEvent !== void 0 && index < herd.initialEventCount) return herd.initialEvent;
54
+ if (herd?.event !== void 0 && index >= herd.eventSkipCount) return herd.event;
55
+ return permutationEvent ?? condition.spawnEvent;
56
+ };
57
+ /** Runs the spawn loop for one world. */
58
+ var Spawner = class {
59
+ rulesByPool = /* @__PURE__ */ new Map();
60
+ world;
61
+ random;
62
+ constants;
63
+ delays;
64
+ engineRules;
65
+ onUnanswered;
66
+ constructor(options) {
67
+ this.world = options.world;
68
+ this.random = options.random;
69
+ this.constants = options.constants ?? SPAWN_CONSTANTS;
70
+ this.delays = options.delays ?? new SpawnDelays();
71
+ this.engineRules = options.engineRules ?? VANILLA_ENGINE_SPAWN_RULES;
72
+ this.onUnanswered = options.onUnanswered;
73
+ for (const rule of options.rules) {
74
+ const pool = rule.populationControl;
75
+ if (pool === void 0) continue;
76
+ const existing = this.rulesByPool.get(pool);
77
+ if (existing === void 0) this.rulesByPool.set(pool, [rule]);
78
+ else existing.push(rule);
79
+ }
80
+ }
81
+ /** The pools the loaded rules name, which is what {@link tick} cycles. */
82
+ get pools() {
83
+ return [...this.rulesByPool.keys()];
84
+ }
85
+ /**
86
+ * Runs every pool whose cadence falls on this tick.
87
+ *
88
+ * @returns Every entity to create, in the order the cycles produced them.
89
+ */
90
+ tick(tick) {
91
+ const requests = [];
92
+ for (const pool of this.rulesByPool.keys()) {
93
+ const cadence = this.constants.pools[pool]?.cycleTicks;
94
+ if (cadence === void 0 || cadence <= 0 || tick % cadence !== 0) continue;
95
+ requests.push(...this.cycle(pool, tick));
96
+ }
97
+ return requests;
98
+ }
99
+ /**
100
+ * Runs one cycle of one pool, whatever the cadence says.
101
+ *
102
+ * @returns Every entity to create, never more than the pool's remaining cap.
103
+ */
104
+ cycle(pool, tick) {
105
+ const rules = this.rulesByPool.get(pool);
106
+ if (rules === void 0 || rules.length === 0) return [];
107
+ const players = this.world.players();
108
+ if (players.length === 0) return [];
109
+ const cap = poolCapFor(pool, players.length, this.constants);
110
+ let remaining = cap === void 0 ? Number.POSITIVE_INFINITY : cap - this.world.poolCount(pool);
111
+ if (remaining <= 0) return [];
112
+ const requests = [];
113
+ const { spawnRadiusChunks, chunksPerCycle, positionsPerChunk } = this.constants;
114
+ for (const player of players) {
115
+ const playerChunkX = Math.floor(player.position.x / 16);
116
+ const playerChunkZ = Math.floor(player.position.z / 16);
117
+ for (let sample = 0; sample < chunksPerCycle && remaining > 0; sample += 1) {
118
+ const chunkX = playerChunkX + between(this.random, -spawnRadiusChunks, spawnRadiusChunks);
119
+ const chunkZ = playerChunkZ + between(this.random, -spawnRadiusChunks, spawnRadiusChunks);
120
+ for (let attempt = 0; attempt < positionsPerChunk && remaining > 0; attempt += 1) for (const pass of ["surface", "underground"]) {
121
+ if (remaining <= 0) break;
122
+ const position = this.positionIn(chunkX, chunkZ, pass);
123
+ if (position === void 0) continue;
124
+ const spawned = this.attemptAt(pool, rules, position, pass, tick, remaining);
125
+ remaining -= spawned.length;
126
+ requests.push(...spawned);
127
+ }
128
+ }
129
+ }
130
+ return requests;
131
+ }
132
+ /**
133
+ * Draws one position inside a chunk for one pass.
134
+ *
135
+ * @returns The position, or undefined when the column is unloaded or the draw landed
136
+ * somewhere no entity fits.
137
+ */
138
+ positionIn(chunkX, chunkZ, pass) {
139
+ const x = chunkX * 16 + this.random.nextInt(16);
140
+ const z = chunkZ * 16 + this.random.nextInt(16);
141
+ if (pass === "surface") return this.surfacePosition(x, z);
142
+ const top = this.world.surfaceY(x, z);
143
+ if (top === void 0) return void 0;
144
+ const floor = this.world.minY();
145
+ if (top - 1 < floor) return void 0;
146
+ const at = {
147
+ x,
148
+ y: between(this.random, floor, top - 1),
149
+ z
150
+ };
151
+ return this.fits(at) ? at : void 0;
152
+ }
153
+ /** The top spawn position in a column, using the water surface when one covers the terrain. */
154
+ surfacePosition(x, z) {
155
+ const top = this.world.surfaceY(x, z);
156
+ if (top === void 0) return void 0;
157
+ const surface = {
158
+ x,
159
+ y: top,
160
+ z
161
+ };
162
+ if (this.world.site("underwater", surface)) return surface;
163
+ const waterSurface = {
164
+ ...surface,
165
+ y: top - 1
166
+ };
167
+ return this.world.site("underwater", waterSurface) ? waterSurface : surface;
168
+ }
169
+ /** Whether an entity fits at a position: its own block and the one over its head are free. */
170
+ fits(at) {
171
+ return !this.world.solid(at) && !this.world.solid({
172
+ ...at,
173
+ y: at.y + 1
174
+ });
175
+ }
176
+ /**
177
+ * Runs one attempt: collect the rules that pass here, draw one, and build
178
+ * its herd.
179
+ *
180
+ * A rule with an engine condition is asked that first, because a condition
181
+ * Bedrock keeps in code is a condition the file was never able to state.
182
+ * `minecraft:slime` is the rule this matters to: its file names no
183
+ * brightness and no height, so without the engine condition it is the only
184
+ * monster that passes in daylight and it fills the pool on its own.
185
+ */
186
+ attemptAt(pool, rules, position, pass, tick, remaining) {
187
+ const candidates = [];
188
+ let totalWeight = 0;
189
+ for (const rule of rules) {
190
+ if (this.world.structureSpawnOverrideAt?.(rule.identifier, position) === false) continue;
191
+ const engineRule = this.engineRules.get(rule.identifier);
192
+ if (engineRule !== void 0 && !engineRule(position, {
193
+ world: this.world,
194
+ random: this.random
195
+ })) continue;
196
+ for (const condition of rule.conditions) {
197
+ if (!evaluateSpawnCondition(condition, position, this.contextFor(rule, tick), pass).passed) continue;
198
+ candidates.push({
199
+ rule,
200
+ condition
201
+ });
202
+ totalWeight += Math.max(0, condition.weight.default);
203
+ }
204
+ }
205
+ if (candidates.length === 0 || totalWeight <= 0) return [];
206
+ let roll = this.random.nextFloat() * totalWeight;
207
+ let chosen = candidates[candidates.length - 1];
208
+ for (const candidate of candidates) {
209
+ roll -= Math.max(0, candidate.condition.weight.default);
210
+ if (roll < 0) {
211
+ chosen = candidate;
212
+ break;
213
+ }
214
+ }
215
+ const { rarity } = chosen.condition.weight;
216
+ if (rarity > 0 && this.random.nextFloat() * rarity >= 1) return [];
217
+ if (chosen.condition.delay !== void 0) this.delays.scheduleFrom(chosen.condition.delay, tick, this.random);
218
+ return this.herdAt(pool, chosen, position, pass, remaining);
219
+ }
220
+ /** Builds one herd around an anchor position. */
221
+ herdAt(pool, candidate, anchor, pass, remaining) {
222
+ const { condition, rule } = candidate;
223
+ const herd = condition.herd.length === 0 ? void 0 : condition.herd[this.random.nextInt(condition.herd.length)];
224
+ const drawn = herd === void 0 ? 1 : between(this.random, herd.minSize, herd.maxSize);
225
+ const size = Math.max(0, Math.min(drawn, remaining));
226
+ if (size === 0) return [];
227
+ const permutations = condition.permutations === void 0 ? void 0 : permutationsFor(condition.permutations, size, this.random);
228
+ const requests = [];
229
+ for (let index = 0; index < size; index += 1) {
230
+ const permutation = permutations?.[index];
231
+ const swapped = permutation?.entityType === void 0 ? void 0 : splitSpawnType(permutation.entityType);
232
+ const position = index === 0 ? anchor : this.herdMemberPosition(anchor, pass);
233
+ const identifier = swapped?.identifier ?? rule.identifier;
234
+ if (this.world.structureSpawnOverrideAt?.(identifier, position) === false) continue;
235
+ const event = eventForMember(index, herd, swapped?.event, condition);
236
+ const request = {
237
+ identifier,
238
+ position,
239
+ pool,
240
+ rule: rule.identifier,
241
+ pass
242
+ };
243
+ if (event !== void 0) request.spawnEvent = event;
244
+ requests.push(request);
245
+ }
246
+ return requests;
247
+ }
248
+ /** Places one herd member around the anchor, following the terrain on the surface pass. */
249
+ herdMemberPosition(anchor, pass) {
250
+ const radius = this.constants.herdRadius;
251
+ const x = anchor.x + between(this.random, -radius, radius);
252
+ const z = anchor.z + between(this.random, -radius, radius);
253
+ if (pass !== "surface") return {
254
+ x,
255
+ y: anchor.y,
256
+ z
257
+ };
258
+ const position = this.surfacePosition(x, z);
259
+ if (position === void 0) return anchor;
260
+ if (this.world.site("underwater", anchor) && !this.world.site("underwater", position)) return anchor;
261
+ return position;
262
+ }
263
+ contextFor(rule, tick) {
264
+ const context = {
265
+ world: this.world,
266
+ identifier: rule.identifier,
267
+ random: this.random,
268
+ tick,
269
+ constants: this.constants,
270
+ delays: this.delays
271
+ };
272
+ if (this.onUnanswered !== void 0) context.onUnanswered = this.onUnanswered;
273
+ return context;
274
+ }
275
+ };
276
+ export { Spawner };
277
+
278
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bhd25lci5lcy5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi9zcmMvc3Bhd25lci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEV2YWx1YXRlRmlsdGVyT3B0aW9ucyB9IGZyb20gJ0Bqc3ByaXNtYXJpbmUvZW50aXRpZXMnO1xuaW1wb3J0IHR5cGUgeyBSYW5kb21Tb3VyY2UgfSBmcm9tICdAanNwcmlzbWFyaW5lL3ByZWRpY2F0ZXMnO1xuXG5pbXBvcnQgdHlwZSB7IFNwYXduQ29uZGl0aW9uQ29udGV4dCB9IGZyb20gJy4vY29uZGl0aW9ucyc7XG5pbXBvcnQgeyBTcGF3bkRlbGF5cywgZXZhbHVhdGVTcGF3bkNvbmRpdGlvbiB9IGZyb20gJy4vY29uZGl0aW9ucyc7XG5pbXBvcnQgdHlwZSB7IFNwYXduQ29uc3RhbnRzIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgU1BBV05fQ09OU1RBTlRTLCBwb29sQ2FwRm9yIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHR5cGUgeyBFbmdpbmVTcGF3blJ1bGUgfSBmcm9tICcuL2VuZ2luZVJ1bGVzJztcbmltcG9ydCB7IFZBTklMTEFfRU5HSU5FX1NQQVdOX1JVTEVTIH0gZnJvbSAnLi9lbmdpbmVSdWxlcyc7XG5pbXBvcnQgdHlwZSB7IEhlcmRSdWxlLCBTcGF3bkNvbmRpdGlvbiwgU3Bhd25QZXJtdXRhdGlvbiwgU3Bhd25SdWxlIH0gZnJvbSAnLi9ydWxlcyc7XG5pbXBvcnQgdHlwZSB7IFNwYXduUGFzcywgU3Bhd25Qb3NpdGlvbiwgU3Bhd25Xb3JsZCB9IGZyb20gJy4vd29ybGQnO1xuXG4vKipcbiAqIFRoZSBzcGF3biBsb29wLlxuICpcbiAqIE1vamFuZydzIHNwYXduIGN5Y2xlIGRpYWdyYW0gbmFtZXMgc2l4IHN0ZXBzLCBcImNoZWNrIHNwYXduIGNvbmRpdGlvbnMsIGZpbmRcbiAqIHZhbGlkIHNwYXduIGxvY2F0aW9ucywgY2hlY2sgcG9wdWxhdGlvbiBjYXBzLCBldmFsdWF0ZSBzcGF3biB3ZWlnaHQsIHNwYXduXG4gKiBlbnRpdHksIGFuZCBydW4gc3Bhd24gZXZlbnRcIiwgYW5kIHB1Ymxpc2hlcyBubyBudW1iZXIgYmVoaW5kIGFueSBvZiB0aGVtLlxuICogVGhpcyBsb29wIGltcGxlbWVudHMgdGhvc2Ugc2l4IHN0ZXBzIG92ZXIgdGhlIGNvbnN0YW50cyBpblxuICogYHNyYy90YWJsZXMvc3Bhd25Db25zdGFudHMuanNvbmAsIGFuZCBldmVyeSBkcmF3IGdvZXMgdGhyb3VnaCBhbiBpbmplY3RlZFxuICoge0BsaW5rIFJhbmRvbVNvdXJjZX0sIHNvIG9uZSBzZWVkIHJlcHJvZHVjZXMgb25lIHNldCBvZiBzcGF3bnMuXG4gKlxuICogT25lIGN5Y2xlIG9mIG9uZSBwb29sIHNhbXBsZXMgYGNodW5rc1BlckN5Y2xlYCBjaHVua3MgYXJvdW5kIGVhY2ggcGxheWVyLFxuICogdHJpZXMgYHBvc2l0aW9uc1BlckNodW5rYCBwb3NpdGlvbnMgaW4gZWFjaCBjaHVuayBmb3IgdGhlIHN1cmZhY2UgcGFzcyBhbmRcbiAqIHRoZSBzYW1lIG51bWJlciBmb3IgdGhlIHVuZGVyZ3JvdW5kIHBhc3MsIGFuZCBhdCBlYWNoIHBvc2l0aW9uIGRyYXdzIG9uZSBvZlxuICogdGhlIGNvbmRpdGlvbnMgdGhhdCBwYXNzZWQsIHdlaWdodGVkIGJ5IGBtaW5lY3JhZnQ6d2VpZ2h0YC5cbiAqL1xuXG4vKiogT25lIGVudGl0eSB0aGUgc3Bhd25lciBhc2tzIHRoZSBzZXJ2ZXIgdG8gY3JlYXRlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcGF3blJlcXVlc3Qge1xuICAgIC8qKiBUaGUgZW50aXR5IHR5cGUsIHdpdGggYW55IGA8ZXZlbnQ+YCBzdWZmaXggYWxyZWFkeSBzcGxpdCBvZmYuICovXG4gICAgcmVhZG9ubHkgaWRlbnRpZmllcjogc3RyaW5nO1xuICAgIC8qKiBUaGUgZXZlbnQgdG8gcnVuIGluc3RlYWQgb2YgYG1pbmVjcmFmdDplbnRpdHlfc3Bhd25lZGAsIHdoZW4gdGhlIHJ1bGUgbmFtZXMgb25lLiAqL1xuICAgIHJlYWRvbmx5IHNwYXduRXZlbnQ/OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgcG9zaXRpb246IFNwYXduUG9zaXRpb247XG4gICAgLyoqIFRoZSBwb29sIHdob3NlIGNhcCB0aGlzIHNwYXduIGNvdW50cyBhZ2FpbnN0LiAqL1xuICAgIHJlYWRvbmx5IHBvb2w6IHN0cmluZztcbiAgICAvKiogVGhlIHJ1bGUgdGhhdCBwcm9kdWNlZCB0aGUgc3Bhd24sIHdoaWNoIGlzIHRoZSBpZGVudGlmaWVyIG9mIGl0cyBmaWxlLiAqL1xuICAgIHJlYWRvbmx5IHJ1bGU6IHN0cmluZztcbiAgICByZWFkb25seSBwYXNzOiBTcGF3blBhc3M7XG59XG5cbi8qKiBIb3cgdG8gYnVpbGQgYSB7QGxpbmsgU3Bhd25lcn0uICovXG5leHBvcnQgaW50ZXJmYWNlIFNwYXduZXJPcHRpb25zIHtcbiAgICByZWFkb25seSBydWxlczogSXRlcmFibGU8U3Bhd25SdWxlPjtcbiAgICByZWFkb25seSB3b3JsZDogU3Bhd25Xb3JsZDtcbiAgICByZWFkb25seSByYW5kb206IFJhbmRvbVNvdXJjZTtcbiAgICByZWFkb25seSBjb25zdGFudHM/OiBTcGF3bkNvbnN0YW50cztcbiAgICAvKiogVGhlIGBtaW5lY3JhZnQ6ZGVsYXlfZmlsdGVyYCBjb29sZG93bnMsIHNvIGEgY2FsbGVyIGNhbiBwZXJzaXN0IHRoZW0gYWNyb3NzIGEgcmVzdGFydC4gKi9cbiAgICByZWFkb25seSBkZWxheXM/OiBTcGF3bkRlbGF5cztcbiAgICAvKipcbiAgICAgKiBUaGUgY29uZGl0aW9ucyBCZWRyb2NrIGtlZXBzIGluIGVuZ2luZSBjb2RlLCBrZXllZCBieSB0aGUgZW50aXR5IGVhY2hcbiAgICAgKiBvbmUgZ2F0ZXMuIERlZmF1bHRzIHRvIHtAbGluayBWQU5JTExBX0VOR0lORV9TUEFXTl9SVUxFU307IHBhc3MgYW4gZW1wdHlcbiAgICAgKiBtYXAgdG8gcnVuIHRoZSBKU09OIGNvbmRpdGlvbnMgYWxvbmUuXG4gICAgICovXG4gICAgcmVhZG9ubHkgZW5naW5lUnVsZXM/OiBSZWFkb25seU1hcDxzdHJpbmcsIEVuZ2luZVNwYXduUnVsZT47XG4gICAgLyoqIFJlY2VpdmVzIGV2ZXJ5IGJpb21lIGZpbHRlciB0ZXN0IHRoZSBldmFsdWF0b3IgY291bGQgbm90IGFuc3dlci4gKi9cbiAgICByZWFkb25seSBvblVuYW5zd2VyZWQ/OiBFdmFsdWF0ZUZpbHRlck9wdGlvbnNbJ29uVW5hbnN3ZXJlZCddO1xufVxuXG4vKiogT25lIHJ1bGUgYW5kIHRoZSBvbmUgb2YgaXRzIGNvbmRpdGlvbnMgdGhhdCBwYXNzZWQgYXQgYSBwb3NpdGlvbi4gKi9cbmludGVyZmFjZSBDYW5kaWRhdGUge1xuICAgIHJlYWRvbmx5IHJ1bGU6IFNwYXduUnVsZTtcbiAgICByZWFkb25seSBjb25kaXRpb246IFNwYXduQ29uZGl0aW9uO1xufVxuXG4vKiogU3BsaXRzIGBtaW5lY3JhZnQ6cGlsbGFnZXI8bWluZWNyYWZ0OnNwYXduX2FzX3BhdHJvbF9mb2xsb3dlcj5gIGludG8gaXRzIHR3byBoYWx2ZXMuICovXG5jb25zdCBzcGxpdFNwYXduVHlwZSA9ICh2YWx1ZTogc3RyaW5nKTogeyByZWFkb25seSBpZGVudGlmaWVyOiBzdHJpbmc7IHJlYWRvbmx5IGV2ZW50Pzogc3RyaW5nIH0gPT4ge1xuICAgIGNvbnN0IG1hdGNoID0gL14oPzxpZGVudGlmaWVyPltePF0rKTwoPzxldmVudD5bXj5dKyk+JC8uZXhlYyh2YWx1ZSk7XG4gICAgaWYgKG1hdGNoPy5ncm91cHMgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHsgaWRlbnRpZmllcjogdmFsdWUgfTtcbiAgICByZXR1cm4geyBpZGVudGlmaWVyOiBtYXRjaC5ncm91cHMuaWRlbnRpZmllciEsIGV2ZW50OiBtYXRjaC5ncm91cHMuZXZlbnQhIH07XG59O1xuXG4vKiogRHJhd3MgYW4gaW50ZWdlciBpbiB0aGUgaW5jbHVzaXZlIHJhbmdlLCB3aGljaCBpcyBob3cgZXZlcnkgc2l6ZSBhbmQgb2Zmc2V0IGlzIHBpY2tlZC4gKi9cbmNvbnN0IGJldHdlZW4gPSAocmFuZG9tOiBSYW5kb21Tb3VyY2UsIG1pbjogbnVtYmVyLCBtYXg6IG51bWJlcik6IG51bWJlciA9PlxuICAgIG1heCA8PSBtaW4gPyBtaW4gOiBtaW4gKyByYW5kb20ubmV4dEludChtYXggLSBtaW4gKyAxKTtcblxuLyoqXG4gKiBCdWlsZHMgdGhlIHBlcm11dGF0aW9uIGVhY2ggaGVyZCBtZW1iZXIgc3Bhd25zIGFzLlxuICpcbiAqIGBtaW5fZ3VhcmFudGVlZGAgbWVtYmVycyB0YWtlIHRoZWlyIHBlcm11dGF0aW9uIGJlZm9yZSB0aGUgd2VpZ2h0ZWQgZHJhd1xuICogcnVucywgd2hpY2ggaXMgd2hhdCBtYWtlcyB0aGUgcGlsbGFnZXIgcGF0cm9sJ3MgY2FwdGFpbiBhbmQgdGhlIHpvbWJpZVxuICogaGVyZCdzIG9uZSB2aWxsYWdlciBjZXJ0YWluLlxuICovXG5jb25zdCBwZXJtdXRhdGlvbnNGb3IgPSAoXG4gICAgcGVybXV0YXRpb25zOiByZWFkb25seSBTcGF3blBlcm11dGF0aW9uW10sXG4gICAgc2l6ZTogbnVtYmVyLFxuICAgIHJhbmRvbTogUmFuZG9tU291cmNlXG4pOiByZWFkb25seSAoU3Bhd25QZXJtdXRhdGlvbiB8IHVuZGVmaW5lZClbXSA9PiB7XG4gICAgY29uc3QgbWVtYmVyczogKFNwYXduUGVybXV0YXRpb24gfCB1bmRlZmluZWQpW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHBlcm11dGF0aW9uIG9mIHBlcm11dGF0aW9ucykge1xuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcGVybXV0YXRpb24ubWluR3VhcmFudGVlZCAmJiBtZW1iZXJzLmxlbmd0aCA8IHNpemU7IGluZGV4ICs9IDEpXG4gICAgICAgICAgICBtZW1iZXJzLnB1c2gocGVybXV0YXRpb24pO1xuICAgIH1cblxuICAgIGNvbnN0IHRvdGFsID0gcGVybXV0YXRpb25zLnJlZHVjZSgoc3VtLCBwZXJtdXRhdGlvbikgPT4gc3VtICsgTWF0aC5tYXgoMCwgcGVybXV0YXRpb24ud2VpZ2h0KSwgMCk7XG4gICAgd2hpbGUgKG1lbWJlcnMubGVuZ3RoIDwgc2l6ZSkge1xuICAgICAgICBpZiAodG90YWwgPD0gMCkge1xuICAgICAgICAgICAgbWVtYmVycy5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcm9sbCA9IHJhbmRvbS5uZXh0RmxvYXQoKSAqIHRvdGFsO1xuICAgICAgICBsZXQgY2hvc2VuOiBTcGF3blBlcm11dGF0aW9uIHwgdW5kZWZpbmVkO1xuICAgICAgICBmb3IgKGNvbnN0IHBlcm11dGF0aW9uIG9mIHBlcm11dGF0aW9ucykge1xuICAgICAgICAgICAgcm9sbCAtPSBNYXRoLm1heCgwLCBwZXJtdXRhdGlvbi53ZWlnaHQpO1xuICAgICAgICAgICAgaWYgKHJvbGwgPCAwKSB7XG4gICAgICAgICAgICAgICAgY2hvc2VuID0gcGVybXV0YXRpb247XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbWVtYmVycy5wdXNoKGNob3NlbiA/PyBwZXJtdXRhdGlvbnNbcGVybXV0YXRpb25zLmxlbmd0aCAtIDFdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWVtYmVycztcbn07XG5cbi8qKlxuICogVGhlIGV2ZW50IG9uZSBoZXJkIG1lbWJlciBydW5zLlxuICpcbiAqIGBpbml0aWFsX2V2ZW50YCB3aW5zIGZvciB0aGUgZmlyc3QgYGluaXRpYWxfZXZlbnRfY291bnRgIG1lbWJlcnMsIGBldmVudGBcbiAqIHRha2VzIGV2ZXJ5IG1lbWJlciBwYXN0IGBldmVudF9za2lwX2NvdW50YCwgYW5kIGEgcGVybXV0YXRpb24ncyBgPGV2ZW50PmBcbiAqIHN1ZmZpeCBvciB0aGUgY29uZGl0aW9uJ3MgYG1pbmVjcmFmdDpzcGF3bl9ldmVudGAgZmlsbHMgaW4gZm9yIHRoZSByZXN0LlxuICovXG5jb25zdCBldmVudEZvck1lbWJlciA9IChcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIGhlcmQ6IEhlcmRSdWxlIHwgdW5kZWZpbmVkLFxuICAgIHBlcm11dGF0aW9uRXZlbnQ6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICBjb25kaXRpb246IFNwYXduQ29uZGl0aW9uXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICAgIGlmIChoZXJkPy5pbml0aWFsRXZlbnQgIT09IHVuZGVmaW5lZCAmJiBpbmRleCA8IGhlcmQuaW5pdGlhbEV2ZW50Q291bnQpIHJldHVybiBoZXJkLmluaXRpYWxFdmVudDtcbiAgICBpZiAoaGVyZD8uZXZlbnQgIT09IHVuZGVmaW5lZCAmJiBpbmRleCA+PSBoZXJkLmV2ZW50U2tpcENvdW50KSByZXR1cm4gaGVyZC5ldmVudDtcbiAgICByZXR1cm4gcGVybXV0YXRpb25FdmVudCA/PyBjb25kaXRpb24uc3Bhd25FdmVudDtcbn07XG5cbi8qKiBSdW5zIHRoZSBzcGF3biBsb29wIGZvciBvbmUgd29ybGQuICovXG5leHBvcnQgY2xhc3MgU3Bhd25lciB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBydWxlc0J5UG9vbCA9IG5ldyBNYXA8c3RyaW5nLCBTcGF3blJ1bGVbXT4oKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHdvcmxkOiBTcGF3bldvcmxkO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcmFuZG9tOiBSYW5kb21Tb3VyY2U7XG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25zdGFudHM6IFNwYXduQ29uc3RhbnRzO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVsYXlzOiBTcGF3bkRlbGF5cztcbiAgICBwcml2YXRlIHJlYWRvbmx5IGVuZ2luZVJ1bGVzOiBSZWFkb25seU1hcDxzdHJpbmcsIEVuZ2luZVNwYXduUnVsZT47XG4gICAgcHJpdmF0ZSByZWFkb25seSBvblVuYW5zd2VyZWQ6IEV2YWx1YXRlRmlsdGVyT3B0aW9uc1snb25VbmFuc3dlcmVkJ10gfCB1bmRlZmluZWQ7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogU3Bhd25lck9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy53b3JsZCA9IG9wdGlvbnMud29ybGQ7XG4gICAgICAgIHRoaXMucmFuZG9tID0gb3B0aW9ucy5yYW5kb207XG4gICAgICAgIHRoaXMuY29uc3RhbnRzID0gb3B0aW9ucy5jb25zdGFudHMgPz8gU1BBV05fQ09OU1RBTlRTO1xuICAgICAgICB0aGlzLmRlbGF5cyA9IG9wdGlvbnMuZGVsYXlzID8/IG5ldyBTcGF3bkRlbGF5cygpO1xuICAgICAgICB0aGlzLmVuZ2luZVJ1bGVzID0gb3B0aW9ucy5lbmdpbmVSdWxlcyA/PyBWQU5JTExBX0VOR0lORV9TUEFXTl9SVUxFUztcbiAgICAgICAgdGhpcy5vblVuYW5zd2VyZWQgPSBvcHRpb25zLm9uVW5hbnN3ZXJlZDtcblxuICAgICAgICBmb3IgKGNvbnN0IHJ1bGUgb2Ygb3B0aW9ucy5ydWxlcykge1xuICAgICAgICAgICAgY29uc3QgcG9vbCA9IHJ1bGUucG9wdWxhdGlvbkNvbnRyb2w7XG4gICAgICAgICAgICBpZiAocG9vbCA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5ydWxlc0J5UG9vbC5nZXQocG9vbCk7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmcgPT09IHVuZGVmaW5lZCkgdGhpcy5ydWxlc0J5UG9vbC5zZXQocG9vbCwgW3J1bGVdKTtcbiAgICAgICAgICAgIGVsc2UgZXhpc3RpbmcucHVzaChydWxlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBUaGUgcG9vbHMgdGhlIGxvYWRlZCBydWxlcyBuYW1lLCB3aGljaCBpcyB3aGF0IHtAbGluayB0aWNrfSBjeWNsZXMuICovXG4gICAgcHVibGljIGdldCBwb29scygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiBbLi4udGhpcy5ydWxlc0J5UG9vbC5rZXlzKCldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJ1bnMgZXZlcnkgcG9vbCB3aG9zZSBjYWRlbmNlIGZhbGxzIG9uIHRoaXMgdGljay5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEV2ZXJ5IGVudGl0eSB0byBjcmVhdGUsIGluIHRoZSBvcmRlciB0aGUgY3ljbGVzIHByb2R1Y2VkIHRoZW0uXG4gICAgICovXG4gICAgcHVibGljIHRpY2sodGljazogbnVtYmVyKTogcmVhZG9ubHkgU3Bhd25SZXF1ZXN0W10ge1xuICAgICAgICBjb25zdCByZXF1ZXN0czogU3Bhd25SZXF1ZXN0W10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBwb29sIG9mIHRoaXMucnVsZXNCeVBvb2wua2V5cygpKSB7XG4gICAgICAgICAgICBjb25zdCBjYWRlbmNlID0gdGhpcy5jb25zdGFudHMucG9vbHNbcG9vbF0/LmN5Y2xlVGlja3M7XG4gICAgICAgICAgICBpZiAoY2FkZW5jZSA9PT0gdW5kZWZpbmVkIHx8IGNhZGVuY2UgPD0gMCB8fCB0aWNrICUgY2FkZW5jZSAhPT0gMCkgY29udGludWU7XG4gICAgICAgICAgICByZXF1ZXN0cy5wdXNoKC4uLnRoaXMuY3ljbGUocG9vbCwgdGljaykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXF1ZXN0cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW5zIG9uZSBjeWNsZSBvZiBvbmUgcG9vbCwgd2hhdGV2ZXIgdGhlIGNhZGVuY2Ugc2F5cy5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEV2ZXJ5IGVudGl0eSB0byBjcmVhdGUsIG5ldmVyIG1vcmUgdGhhbiB0aGUgcG9vbCdzIHJlbWFpbmluZyBjYXAuXG4gICAgICovXG4gICAgcHVibGljIGN5Y2xlKHBvb2w6IHN0cmluZywgdGljazogbnVtYmVyKTogcmVhZG9ubHkgU3Bhd25SZXF1ZXN0W10ge1xuICAgICAgICBjb25zdCBydWxlcyA9IHRoaXMucnVsZXNCeVBvb2wuZ2V0KHBvb2wpO1xuICAgICAgICBpZiAocnVsZXMgPT09IHVuZGVmaW5lZCB8fCBydWxlcy5sZW5ndGggPT09IDApIHJldHVybiBbXTtcblxuICAgICAgICBjb25zdCBwbGF5ZXJzID0gdGhpcy53b3JsZC5wbGF5ZXJzKCk7XG4gICAgICAgIGlmIChwbGF5ZXJzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xuXG4gICAgICAgIGNvbnN0IGNhcCA9IHBvb2xDYXBGb3IocG9vbCwgcGxheWVycy5sZW5ndGgsIHRoaXMuY29uc3RhbnRzKTtcbiAgICAgICAgbGV0IHJlbWFpbmluZyA9IGNhcCA9PT0gdW5kZWZpbmVkID8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZIDogY2FwIC0gdGhpcy53b3JsZC5wb29sQ291bnQocG9vbCk7XG4gICAgICAgIGlmIChyZW1haW5pbmcgPD0gMCkgcmV0dXJuIFtdO1xuXG4gICAgICAgIGNvbnN0IHJlcXVlc3RzOiBTcGF3blJlcXVlc3RbXSA9IFtdO1xuICAgICAgICBjb25zdCB7IHNwYXduUmFkaXVzQ2h1bmtzLCBjaHVua3NQZXJDeWNsZSwgcG9zaXRpb25zUGVyQ2h1bmsgfSA9IHRoaXMuY29uc3RhbnRzO1xuXG4gICAgICAgIGZvciAoY29uc3QgcGxheWVyIG9mIHBsYXllcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBsYXllckNodW5rWCA9IE1hdGguZmxvb3IocGxheWVyLnBvc2l0aW9uLnggLyAxNik7XG4gICAgICAgICAgICBjb25zdCBwbGF5ZXJDaHVua1ogPSBNYXRoLmZsb29yKHBsYXllci5wb3NpdGlvbi56IC8gMTYpO1xuXG4gICAgICAgICAgICBmb3IgKGxldCBzYW1wbGUgPSAwOyBzYW1wbGUgPCBjaHVua3NQZXJDeWNsZSAmJiByZW1haW5pbmcgPiAwOyBzYW1wbGUgKz0gMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNodW5rWCA9IHBsYXllckNodW5rWCArIGJldHdlZW4odGhpcy5yYW5kb20sIC1zcGF3blJhZGl1c0NodW5rcywgc3Bhd25SYWRpdXNDaHVua3MpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNodW5rWiA9IHBsYXllckNodW5rWiArIGJldHdlZW4odGhpcy5yYW5kb20sIC1zcGF3blJhZGl1c0NodW5rcywgc3Bhd25SYWRpdXNDaHVua3MpO1xuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPCBwb3NpdGlvbnNQZXJDaHVuayAmJiByZW1haW5pbmcgPiAwOyBhdHRlbXB0ICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBwYXNzIG9mIFsnc3VyZmFjZScsICd1bmRlcmdyb3VuZCddIGFzIGNvbnN0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVtYWluaW5nIDw9IDApIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLnBvc2l0aW9uSW4oY2h1bmtYLCBjaHVua1osIHBhc3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3Bhd25lZCA9IHRoaXMuYXR0ZW1wdEF0KHBvb2wsIHJ1bGVzLCBwb3NpdGlvbiwgcGFzcywgdGljaywgcmVtYWluaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbWFpbmluZyAtPSBzcGF3bmVkLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzLnB1c2goLi4uc3Bhd25lZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVxdWVzdHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRHJhd3Mgb25lIHBvc2l0aW9uIGluc2lkZSBhIGNodW5rIGZvciBvbmUgcGFzcy5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBwb3NpdGlvbiwgb3IgdW5kZWZpbmVkIHdoZW4gdGhlIGNvbHVtbiBpcyB1bmxvYWRlZCBvciB0aGUgZHJhdyBsYW5kZWRcbiAgICAgKiAgIHNvbWV3aGVyZSBubyBlbnRpdHkgZml0cy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHBvc2l0aW9uSW4oY2h1bmtYOiBudW1iZXIsIGNodW5rWjogbnVtYmVyLCBwYXNzOiBTcGF3blBhc3MpOiBTcGF3blBvc2l0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgY29uc3QgeCA9IGNodW5rWCAqIDE2ICsgdGhpcy5yYW5kb20ubmV4dEludCgxNik7XG4gICAgICAgIGNvbnN0IHogPSBjaHVua1ogKiAxNiArIHRoaXMucmFuZG9tLm5leHRJbnQoMTYpO1xuICAgICAgICBpZiAocGFzcyA9PT0gJ3N1cmZhY2UnKSByZXR1cm4gdGhpcy5zdXJmYWNlUG9zaXRpb24oeCwgeik7XG5cbiAgICAgICAgY29uc3QgdG9wID0gdGhpcy53b3JsZC5zdXJmYWNlWSh4LCB6KTtcbiAgICAgICAgaWYgKHRvcCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIGNvbnN0IGZsb29yID0gdGhpcy53b3JsZC5taW5ZKCk7XG4gICAgICAgIGlmICh0b3AgLSAxIDwgZmxvb3IpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgLy8gVGhlIGRyYXcgaXMgdW5pZm9ybSBvdmVyIHRoZSBjb2x1bW4sIHNvIGluIGEgd29ybGQgd2l0aCBmZXcgY2F2ZXMgbW9zdCBvZiBpdCBpc1xuICAgICAgICAvLyBpbnNpZGUgcm9jay4gT25lIGF0dGVtcHQsIG9uZSBkcmF3LCB0aGUgd2F5IEphdmEncyBgTmF0dXJhbFNwYXduZXJgIHJlamVjdHMgYVxuICAgICAgICAvLyBwb3NpdGlvbiByYXRoZXIgdGhhbiBzZWFyY2hpbmcgZm9yIGEgYmV0dGVyIG9uZTogYSBzcGF3biBpbnNpZGUgYSBibG9jayBpcyBhIG1vYlxuICAgICAgICAvLyB0aGF0IGNhbiBwYXRoIG5vd2hlcmUsIG5ldmVyIGRlc3Bhd25zIGFuZCBmaWxscyB0aGUgcG9vbCBzbyBub3RoaW5nIGVsc2UgY2FuIHNwYXduLlxuICAgICAgICBjb25zdCBhdCA9IHsgeCwgeTogYmV0d2Vlbih0aGlzLnJhbmRvbSwgZmxvb3IsIHRvcCAtIDEpLCB6IH07XG4gICAgICAgIHJldHVybiB0aGlzLmZpdHMoYXQpID8gYXQgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqIFRoZSB0b3Agc3Bhd24gcG9zaXRpb24gaW4gYSBjb2x1bW4sIHVzaW5nIHRoZSB3YXRlciBzdXJmYWNlIHdoZW4gb25lIGNvdmVycyB0aGUgdGVycmFpbi4gKi9cbiAgICBwcml2YXRlIHN1cmZhY2VQb3NpdGlvbih4OiBudW1iZXIsIHo6IG51bWJlcik6IFNwYXduUG9zaXRpb24gfCB1bmRlZmluZWQge1xuICAgICAgICBjb25zdCB0b3AgPSB0aGlzLndvcmxkLnN1cmZhY2VZKHgsIHopO1xuICAgICAgICBpZiAodG9wID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgY29uc3Qgc3VyZmFjZSA9IHsgeCwgeTogdG9wLCB6IH07XG4gICAgICAgIGlmICh0aGlzLndvcmxkLnNpdGUoJ3VuZGVyd2F0ZXInLCBzdXJmYWNlKSkgcmV0dXJuIHN1cmZhY2U7XG5cbiAgICAgICAgLy8gQSBoZWlnaHQgbWFwIHRoYXQgY291bnRzIHdhdGVyIHB1dHMgaXRzIHN1cmZhY2Ugb25lIGJsb2NrIGFib3ZlIHRoZSBmbHVpZC4gRmlzaCBydWxlc1xuICAgICAgICAvLyBhc2sgZm9yIGJvdGggdGhlIHN1cmZhY2UgcGFzcyBhbmQgYW4gdW5kZXJ3YXRlciBwb3NpdGlvbiwgc28gc2FtcGxlIHRoZSB0b3Agd2F0ZXJcbiAgICAgICAgLy8gYmxvY2sgaW5zdGVhZCBvZiB0aGUgYWlyIGFib3ZlIGl0LlxuICAgICAgICBjb25zdCB3YXRlclN1cmZhY2UgPSB7IC4uLnN1cmZhY2UsIHk6IHRvcCAtIDEgfTtcbiAgICAgICAgcmV0dXJuIHRoaXMud29ybGQuc2l0ZSgndW5kZXJ3YXRlcicsIHdhdGVyU3VyZmFjZSkgPyB3YXRlclN1cmZhY2UgOiBzdXJmYWNlO1xuICAgIH1cblxuICAgIC8qKiBXaGV0aGVyIGFuIGVudGl0eSBmaXRzIGF0IGEgcG9zaXRpb246IGl0cyBvd24gYmxvY2sgYW5kIHRoZSBvbmUgb3ZlciBpdHMgaGVhZCBhcmUgZnJlZS4gKi9cbiAgICBwcml2YXRlIGZpdHMoYXQ6IFNwYXduUG9zaXRpb24pOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLndvcmxkLnNvbGlkKGF0KSAmJiAhdGhpcy53b3JsZC5zb2xpZCh7IC4uLmF0LCB5OiBhdC55ICsgMSB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW5zIG9uZSBhdHRlbXB0OiBjb2xsZWN0IHRoZSBydWxlcyB0aGF0IHBhc3MgaGVyZSwgZHJhdyBvbmUsIGFuZCBidWlsZFxuICAgICAqIGl0cyBoZXJkLlxuICAgICAqXG4gICAgICogQSBydWxlIHdpdGggYW4gZW5naW5lIGNvbmRpdGlvbiBpcyBhc2tlZCB0aGF0IGZpcnN0LCBiZWNhdXNlIGEgY29uZGl0aW9uXG4gICAgICogQmVkcm9jayBrZWVwcyBpbiBjb2RlIGlzIGEgY29uZGl0aW9uIHRoZSBmaWxlIHdhcyBuZXZlciBhYmxlIHRvIHN0YXRlLlxuICAgICAqIGBtaW5lY3JhZnQ6c2xpbWVgIGlzIHRoZSBydWxlIHRoaXMgbWF0dGVycyB0bzogaXRzIGZpbGUgbmFtZXMgbm9cbiAgICAgKiBicmlnaHRuZXNzIGFuZCBubyBoZWlnaHQsIHNvIHdpdGhvdXQgdGhlIGVuZ2luZSBjb25kaXRpb24gaXQgaXMgdGhlIG9ubHlcbiAgICAgKiBtb25zdGVyIHRoYXQgcGFzc2VzIGluIGRheWxpZ2h0IGFuZCBpdCBmaWxscyB0aGUgcG9vbCBvbiBpdHMgb3duLlxuICAgICAqL1xuICAgIHByaXZhdGUgYXR0ZW1wdEF0KFxuICAgICAgICBwb29sOiBzdHJpbmcsXG4gICAgICAgIHJ1bGVzOiByZWFkb25seSBTcGF3blJ1bGVbXSxcbiAgICAgICAgcG9zaXRpb246IFNwYXduUG9zaXRpb24sXG4gICAgICAgIHBhc3M6IFNwYXduUGFzcyxcbiAgICAgICAgdGljazogbnVtYmVyLFxuICAgICAgICByZW1haW5pbmc6IG51bWJlclxuICAgICk6IHJlYWRvbmx5IFNwYXduUmVxdWVzdFtdIHtcbiAgICAgICAgY29uc3QgY2FuZGlkYXRlczogQ2FuZGlkYXRlW10gPSBbXTtcbiAgICAgICAgbGV0IHRvdGFsV2VpZ2h0ID0gMDtcblxuICAgICAgICBmb3IgKGNvbnN0IHJ1bGUgb2YgcnVsZXMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLndvcmxkLnN0cnVjdHVyZVNwYXduT3ZlcnJpZGVBdD8uKHJ1bGUuaWRlbnRpZmllciwgcG9zaXRpb24pID09PSBmYWxzZSkgY29udGludWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGVuZ2luZVJ1bGUgPSB0aGlzLmVuZ2luZVJ1bGVzLmdldChydWxlLmlkZW50aWZpZXIpO1xuICAgICAgICAgICAgaWYgKGVuZ2luZVJ1bGUgIT09IHVuZGVmaW5lZCAmJiAhZW5naW5lUnVsZShwb3NpdGlvbiwgeyB3b3JsZDogdGhpcy53b3JsZCwgcmFuZG9tOiB0aGlzLnJhbmRvbSB9KSkgY29udGludWU7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgY29uZGl0aW9uIG9mIHJ1bGUuY29uZGl0aW9ucykge1xuICAgICAgICAgICAgICAgIGlmICghZXZhbHVhdGVTcGF3bkNvbmRpdGlvbihjb25kaXRpb24sIHBvc2l0aW9uLCB0aGlzLmNvbnRleHRGb3IocnVsZSwgdGljayksIHBhc3MpLnBhc3NlZCkgY29udGludWU7XG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlcy5wdXNoKHsgcnVsZSwgY29uZGl0aW9uIH0pO1xuICAgICAgICAgICAgICAgIHRvdGFsV2VpZ2h0ICs9IE1hdGgubWF4KDAsIGNvbmRpdGlvbi53ZWlnaHQuZGVmYXVsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2FuZGlkYXRlcy5sZW5ndGggPT09IDAgfHwgdG90YWxXZWlnaHQgPD0gMCkgcmV0dXJuIFtdO1xuXG4gICAgICAgIGxldCByb2xsID0gdGhpcy5yYW5kb20ubmV4dEZsb2F0KCkgKiB0b3RhbFdlaWdodDtcbiAgICAgICAgbGV0IGNob3NlbiA9IGNhbmRpZGF0ZXNbY2FuZGlkYXRlcy5sZW5ndGggLSAxXSE7XG4gICAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICAgIHJvbGwgLT0gTWF0aC5tYXgoMCwgY2FuZGlkYXRlLmNvbmRpdGlvbi53ZWlnaHQuZGVmYXVsdCk7XG4gICAgICAgICAgICBpZiAocm9sbCA8IDApIHtcbiAgICAgICAgICAgICAgICBjaG9zZW4gPSBjYW5kaWRhdGU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBgcmFyaXR5YCBpcyBkb2N1bWVudGVkIGJ5IG5hbWUgb25seS4gVGhpcyBwcm9qZWN0IHJlYWRzIGl0IGFzIGFcbiAgICAgICAgLy8gb25lLWluLU4gcm9sbCBvbiB0b3Agb2YgdGhlIHdlaWdodCwgd2hpY2ggaXMgdGhlIG9ubHkgcmVhZGluZyB0aGF0XG4gICAgICAgIC8vIG1ha2VzIGEgcmFyaXR5IG9mIDIgb3IgMyByYXJlciByYXRoZXIgdGhhbiBtb3JlIGNvbW1vbi5cbiAgICAgICAgY29uc3QgeyByYXJpdHkgfSA9IGNob3Nlbi5jb25kaXRpb24ud2VpZ2h0O1xuICAgICAgICBpZiAocmFyaXR5ID4gMCAmJiB0aGlzLnJhbmRvbS5uZXh0RmxvYXQoKSAqIHJhcml0eSA+PSAxKSByZXR1cm4gW107XG5cbiAgICAgICAgaWYgKGNob3Nlbi5jb25kaXRpb24uZGVsYXkgIT09IHVuZGVmaW5lZCkgdGhpcy5kZWxheXMuc2NoZWR1bGVGcm9tKGNob3Nlbi5jb25kaXRpb24uZGVsYXksIHRpY2ssIHRoaXMucmFuZG9tKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5oZXJkQXQocG9vbCwgY2hvc2VuLCBwb3NpdGlvbiwgcGFzcywgcmVtYWluaW5nKTtcbiAgICB9XG5cbiAgICAvKiogQnVpbGRzIG9uZSBoZXJkIGFyb3VuZCBhbiBhbmNob3IgcG9zaXRpb24uICovXG4gICAgcHJpdmF0ZSBoZXJkQXQoXG4gICAgICAgIHBvb2w6IHN0cmluZyxcbiAgICAgICAgY2FuZGlkYXRlOiBDYW5kaWRhdGUsXG4gICAgICAgIGFuY2hvcjogU3Bhd25Qb3NpdGlvbixcbiAgICAgICAgcGFzczogU3Bhd25QYXNzLFxuICAgICAgICByZW1haW5pbmc6IG51bWJlclxuICAgICk6IHJlYWRvbmx5IFNwYXduUmVxdWVzdFtdIHtcbiAgICAgICAgY29uc3QgeyBjb25kaXRpb24sIHJ1bGUgfSA9IGNhbmRpZGF0ZTtcbiAgICAgICAgY29uc3QgaGVyZCA9XG4gICAgICAgICAgICBjb25kaXRpb24uaGVyZC5sZW5ndGggPT09IDAgPyB1bmRlZmluZWQgOiBjb25kaXRpb24uaGVyZFt0aGlzLnJhbmRvbS5uZXh0SW50KGNvbmRpdGlvbi5oZXJkLmxlbmd0aCldO1xuICAgICAgICBjb25zdCBkcmF3biA9IGhlcmQgPT09IHVuZGVmaW5lZCA/IDEgOiBiZXR3ZWVuKHRoaXMucmFuZG9tLCBoZXJkLm1pblNpemUsIGhlcmQubWF4U2l6ZSk7XG4gICAgICAgIGNvbnN0IHNpemUgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihkcmF3biwgcmVtYWluaW5nKSk7XG4gICAgICAgIGlmIChzaXplID09PSAwKSByZXR1cm4gW107XG5cbiAgICAgICAgY29uc3QgcGVybXV0YXRpb25zID1cbiAgICAgICAgICAgIGNvbmRpdGlvbi5wZXJtdXRhdGlvbnMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgOiBwZXJtdXRhdGlvbnNGb3IoY29uZGl0aW9uLnBlcm11dGF0aW9ucywgc2l6ZSwgdGhpcy5yYW5kb20pO1xuXG4gICAgICAgIGNvbnN0IHJlcXVlc3RzOiBTcGF3blJlcXVlc3RbXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgc2l6ZTsgaW5kZXggKz0gMSkge1xuICAgICAgICAgICAgY29uc3QgcGVybXV0YXRpb24gPSBwZXJtdXRhdGlvbnM/LltpbmRleF07XG4gICAgICAgICAgICBjb25zdCBzd2FwcGVkID0gcGVybXV0YXRpb24/LmVudGl0eVR5cGUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHNwbGl0U3Bhd25UeXBlKHBlcm11dGF0aW9uLmVudGl0eVR5cGUpO1xuICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSBpbmRleCA9PT0gMCA/IGFuY2hvciA6IHRoaXMuaGVyZE1lbWJlclBvc2l0aW9uKGFuY2hvciwgcGFzcyk7XG4gICAgICAgICAgICBjb25zdCBpZGVudGlmaWVyID0gc3dhcHBlZD8uaWRlbnRpZmllciA/PyBydWxlLmlkZW50aWZpZXI7XG4gICAgICAgICAgICBpZiAodGhpcy53b3JsZC5zdHJ1Y3R1cmVTcGF3bk92ZXJyaWRlQXQ/LihpZGVudGlmaWVyLCBwb3NpdGlvbikgPT09IGZhbHNlKSBjb250aW51ZTtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gZXZlbnRGb3JNZW1iZXIoaW5kZXgsIGhlcmQsIHN3YXBwZWQ/LmV2ZW50LCBjb25kaXRpb24pO1xuXG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0OiB7IC1yZWFkb25seSBbS2V5IGluIGtleW9mIFNwYXduUmVxdWVzdF06IFNwYXduUmVxdWVzdFtLZXldIH0gPSB7XG4gICAgICAgICAgICAgICAgaWRlbnRpZmllcixcbiAgICAgICAgICAgICAgICBwb3NpdGlvbixcbiAgICAgICAgICAgICAgICBwb29sLFxuICAgICAgICAgICAgICAgIHJ1bGU6IHJ1bGUuaWRlbnRpZmllcixcbiAgICAgICAgICAgICAgICBwYXNzXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGV2ZW50ICE9PSB1bmRlZmluZWQpIHJlcXVlc3Quc3Bhd25FdmVudCA9IGV2ZW50O1xuICAgICAgICAgICAgcmVxdWVzdHMucHVzaChyZXF1ZXN0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXF1ZXN0cztcbiAgICB9XG5cbiAgICAvKiogUGxhY2VzIG9uZSBoZXJkIG1lbWJlciBhcm91bmQgdGhlIGFuY2hvciwgZm9sbG93aW5nIHRoZSB0ZXJyYWluIG9uIHRoZSBzdXJmYWNlIHBhc3MuICovXG4gICAgcHJpdmF0ZSBoZXJkTWVtYmVyUG9zaXRpb24oYW5jaG9yOiBTcGF3blBvc2l0aW9uLCBwYXNzOiBTcGF3blBhc3MpOiBTcGF3blBvc2l0aW9uIHtcbiAgICAgICAgY29uc3QgcmFkaXVzID0gdGhpcy5jb25zdGFudHMuaGVyZFJhZGl1cztcbiAgICAgICAgY29uc3QgeCA9IGFuY2hvci54ICsgYmV0d2Vlbih0aGlzLnJhbmRvbSwgLXJhZGl1cywgcmFkaXVzKTtcbiAgICAgICAgY29uc3QgeiA9IGFuY2hvci56ICsgYmV0d2Vlbih0aGlzLnJhbmRvbSwgLXJhZGl1cywgcmFkaXVzKTtcbiAgICAgICAgaWYgKHBhc3MgIT09ICdzdXJmYWNlJykgcmV0dXJuIHsgeCwgeTogYW5jaG9yLnksIHogfTtcblxuICAgICAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuc3VyZmFjZVBvc2l0aW9uKHgsIHopO1xuICAgICAgICBpZiAocG9zaXRpb24gPT09IHVuZGVmaW5lZCkgcmV0dXJuIGFuY2hvcjtcbiAgICAgICAgaWYgKHRoaXMud29ybGQuc2l0ZSgndW5kZXJ3YXRlcicsIGFuY2hvcikgJiYgIXRoaXMud29ybGQuc2l0ZSgndW5kZXJ3YXRlcicsIHBvc2l0aW9uKSkgcmV0dXJuIGFuY2hvcjtcbiAgICAgICAgcmV0dXJuIHBvc2l0aW9uO1xuICAgIH1cblxuICAgIHByaXZhdGUgY29udGV4dEZvcihydWxlOiBTcGF3blJ1bGUsIHRpY2s6IG51bWJlcik6IFNwYXduQ29uZGl0aW9uQ29udGV4dCB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQ6IHsgLXJlYWRvbmx5IFtLZXkgaW4ga2V5b2YgU3Bhd25Db25kaXRpb25Db250ZXh0XTogU3Bhd25Db25kaXRpb25Db250ZXh0W0tleV0gfSA9IHtcbiAgICAgICAgICAgIHdvcmxkOiB0aGlzLndvcmxkLFxuICAgICAgICAgICAgaWRlbnRpZmllcjogcnVsZS5pZGVudGlmaWVyLFxuICAgICAgICAgICAgcmFuZG9tOiB0aGlzLnJhbmRvbSxcbiAgICAgICAgICAgIHRpY2ssXG4gICAgICAgICAgICBjb25zdGFudHM6IHRoaXMuY29uc3RhbnRzLFxuICAgICAgICAgICAgZGVsYXlzOiB0aGlzLmRlbGF5c1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5vblVuYW5zd2VyZWQgIT09IHVuZGVmaW5lZCkgY29udGV4dC5vblVuYW5zd2VyZWQgPSB0aGlzLm9uVW5hbnN3ZXJlZDtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7OztBQW1FQSxJQUFNLGtCQUFrQixVQUE0RTtDQUNoRyxNQUFNLFFBQVEsMENBQTBDLEtBQUssS0FBSztDQUNsRSxJQUFJLE9BQU8sV0FBVyxLQUFBLEdBQVcsT0FBTyxFQUFFLFlBQVksTUFBTTtDQUM1RCxPQUFPO0VBQUUsWUFBWSxNQUFNLE9BQU87RUFBYSxPQUFPLE1BQU0sT0FBTztDQUFPO0FBQzlFOztBQUdBLElBQU0sV0FBVyxRQUFzQixLQUFhLFFBQ2hELE9BQU8sTUFBTSxNQUFNLE1BQU0sT0FBTyxRQUFRLE1BQU0sTUFBTSxDQUFDOzs7Ozs7OztBQVN6RCxJQUFNLG1CQUNGLGNBQ0EsTUFDQSxXQUM0QztDQUM1QyxNQUFNLFVBQTRDLENBQUM7Q0FDbkQsS0FBSyxNQUFNLGVBQWUsY0FDdEIsS0FBSyxJQUFJLFFBQVEsR0FBRyxRQUFRLFlBQVksaUJBQWlCLFFBQVEsU0FBUyxNQUFNLFNBQVMsR0FDckYsUUFBUSxLQUFLLFdBQVc7Q0FHaEMsTUFBTSxRQUFRLGFBQWEsUUFBUSxL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
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, {
3
+ __esModule: { value: true },
4
+ [Symbol.toStringTag]: { value: "Module" }
5
+ });
6
+ // src/tables/spawnConstants.json
7
+ var provenance = "Mojang publishes no spawn attempt rate, no cap value, no spawn radius and no light algorithm for Bedrock Edition. The only published numbers are the tilde-hedged 'Typical Cap' column of EntitySpawningDeepDive.md. Every number below is therefore this project's choice; the `source` string on each one says where it came from, and a host may replace the whole table.";
8
+ var pools = {
9
+ "animal": {
10
+ "cap": 10,
11
+ "scope": "per_player",
12
+ "cycleTicks": 400,
13
+ "source": "EntitySpawningDeepDive.md gives '~10 per player'. The 400-tick cadence is Java's animal pass, because Bedrock publishes none."
14
+ },
15
+ "water_animal": {
16
+ "cap": 5,
17
+ "scope": "per_player",
18
+ "cycleTicks": 400,
19
+ "source": "EntitySpawningDeepDive.md gives '~5 per water body'. This project counts per player instead, because a water body is not a quantity the server tracks."
20
+ },
21
+ "water_ambient": {
22
+ "cap": 20,
23
+ "scope": "per_player",
24
+ "cycleTicks": 400,
25
+ "source": "EntitySpawningDeepDive.md gives '~20 per water body'. No vanilla spawn rule names this pool."
26
+ },
27
+ "ambient": {
28
+ "cap": 15,
29
+ "scope": "per_player",
30
+ "cycleTicks": 400,
31
+ "source": "EntitySpawningDeepDive.md gives '~15 in caves'. Only the bat uses this pool."
32
+ },
33
+ "monster": {
34
+ "cap": 70,
35
+ "scope": "per_region",
36
+ "cycleTicks": 20,
37
+ "source": "EntitySpawningDeepDive.md gives '~70 in loaded chunks', so the cap covers the whole spawn region rather than scaling with players. The 20-tick cadence is this project's choice; Java runs the monster pass every tick, which costs more than this server wants to pay."
38
+ },
39
+ "cat": {
40
+ "cap": 5,
41
+ "scope": "per_region",
42
+ "cycleTicks": 1200,
43
+ "source": "DataDrivenSpawning.md says only that cat limits are 'based upon the amount within a village' and gives no number. Five per region and one cycle per minute are this project's choice."
44
+ },
45
+ "pillager": {
46
+ "cap": null,
47
+ "scope": "per_region",
48
+ "cycleTicks": 20,
49
+ "source": "EntitySpawningDeepDive.md says 'Limited by patrols', so this pool has no cap of its own and `minecraft:delay_filter` plus `minecraft:mob_event_filter` gate it."
50
+ },
51
+ "villager": {
52
+ "cap": null,
53
+ "scope": "per_region",
54
+ "cycleTicks": 400,
55
+ "source": "DataDrivenSpawning.md says the pool exists in the game files and no entity uses it."
56
+ }
57
+ };
58
+ var spawnRadiusChunks = 4;
59
+ var spawnRadiusSource = "Bedrock's documented default simulation distance is 4 chunks, and the ticking area documentation says 'all forms of mob spawning attempts are done in a radius centered on a player'. Mojang publishes no spawn radius, so this project uses the simulation distance.";
60
+ var chunksPerCycle = 8;
61
+ var positionsPerChunk = 3;
62
+ var attemptSource = "Mojang publishes no attempt rate. Eight chunks per player per cycle with three positions in each is this project's budget, picked so one player standing in an empty plains biome reaches the animal cap of 10 within a few animal cycles.";
63
+ var herdRadius = 5;
64
+ var herdRadiusSource = "Mojang publishes no herd placement rule. Five blocks is the horizontal spread Java gives a pack spawn.";
65
+ var densityRadius = 16;
66
+ var densityRadiusSource = "Mojang says `minecraft:density_limit` caps 'the amount of mobs to spawn in certain locations' and names no radius. One chunk's width is this project's reading of 'location'.";
67
+ var rainDarkening = 5;
68
+ var thunderDarkening = 10;
69
+ var darkeningSource = "Mojang publishes neither the light value `minecraft:brightness_filter` compares nor what `adjust_for_weather` does to it. Java's `Level.getSkyDarken` subtracts 5 under rain and 10 under thunder, so this project subtracts the same amounts from the light the world reports.";
70
+ var despawnRadiusChunks = 8;
71
+ var despawnFloorY = -128;
72
+ var despawnSource = "128 blocks is the documented default of `minecraft:despawn.despawn_from_distance.max_distance`, which is 8 chunks, and is the only published spawning distance. The Y floor is published: all mobs despawn at Y=-128 and below in both editions.";
73
+ var spawnConstants_default = {
74
+ provenance,
75
+ pools,
76
+ spawnRadiusChunks: 4,
77
+ spawnRadiusSource,
78
+ chunksPerCycle: 8,
79
+ positionsPerChunk: 3,
80
+ attemptSource,
81
+ herdRadius: 5,
82
+ herdRadiusSource,
83
+ densityRadius: 16,
84
+ densityRadiusSource,
85
+ rainDarkening: 5,
86
+ thunderDarkening: 10,
87
+ darkeningSource,
88
+ despawnRadiusChunks: 8,
89
+ despawnFloorY,
90
+ despawnSource
91
+ };
92
+ exports.attemptSource = attemptSource;
93
+ exports.chunksPerCycle = chunksPerCycle;
94
+ exports.darkeningSource = darkeningSource;
95
+ exports.default = spawnConstants_default;
96
+ exports.densityRadius = densityRadius;
97
+ exports.densityRadiusSource = densityRadiusSource;
98
+ exports.despawnFloorY = despawnFloorY;
99
+ exports.despawnRadiusChunks = despawnRadiusChunks;
100
+ exports.despawnSource = despawnSource;
101
+ exports.herdRadius = herdRadius;
102
+ exports.herdRadiusSource = herdRadiusSource;
103
+ exports.pools = pools;
104
+ exports.positionsPerChunk = positionsPerChunk;
105
+ exports.provenance = provenance;
106
+ exports.rainDarkening = rainDarkening;
107
+ exports.spawnRadiusChunks = spawnRadiusChunks;
108
+ exports.spawnRadiusSource = spawnRadiusSource;
109
+ exports.thunderDarkening = thunderDarkening;
110
+
111
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bhd25Db25zdGFudHMuY2pzLmNqcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdGFibGVzL3NwYXduQ29uc3RhbnRzLmpzb24iXSwic291cmNlc0NvbnRlbnQiOlsie1xuICAgIFwicHJvdmVuYW5jZVwiOiBcIk1vamFuZyBwdWJsaXNoZXMgbm8gc3Bhd24gYXR0ZW1wdCByYXRlLCBubyBjYXAgdmFsdWUsIG5vIHNwYXduIHJhZGl1cyBhbmQgbm8gbGlnaHQgYWxnb3JpdGhtIGZvciBCZWRyb2NrIEVkaXRpb24uIFRoZSBvbmx5IHB1Ymxpc2hlZCBudW1iZXJzIGFyZSB0aGUgdGlsZGUtaGVkZ2VkICdUeXBpY2FsIENhcCcgY29sdW1uIG9mIEVudGl0eVNwYXduaW5nRGVlcERpdmUubWQuIEV2ZXJ5IG51bWJlciBiZWxvdyBpcyB0aGVyZWZvcmUgdGhpcyBwcm9qZWN0J3MgY2hvaWNlOyB0aGUgYHNvdXJjZWAgc3RyaW5nIG9uIGVhY2ggb25lIHNheXMgd2hlcmUgaXQgY2FtZSBmcm9tLCBhbmQgYSBob3N0IG1heSByZXBsYWNlIHRoZSB3aG9sZSB0YWJsZS5cIixcbiAgICBcInBvb2xzXCI6IHtcbiAgICAgICAgXCJhbmltYWxcIjoge1xuICAgICAgICAgICAgXCJjYXBcIjogMTAsXG4gICAgICAgICAgICBcInNjb3BlXCI6IFwicGVyX3BsYXllclwiLFxuICAgICAgICAgICAgXCJjeWNsZVRpY2tzXCI6IDQwMCxcbiAgICAgICAgICAgIFwic291cmNlXCI6IFwiRW50aXR5U3Bhd25pbmdEZWVwRGl2ZS5tZCBnaXZlcyAnfjEwIHBlciBwbGF5ZXInLiBUaGUgNDAwLXRpY2sgY2FkZW5jZSBpcyBKYXZhJ3MgYW5pbWFsIHBhc3MsIGJlY2F1c2UgQmVkcm9jayBwdWJsaXNoZXMgbm9uZS5cIlxuICAgICAgICB9LFxuICAgICAgICBcIndhdGVyX2FuaW1hbFwiOiB7XG4gICAgICAgICAgICBcImNhcFwiOiA1LFxuICAgICAgICAgICAgXCJzY29wZVwiOiBcInBlcl9wbGF5ZXJcIixcbiAgICAgICAgICAgIFwiY3ljbGVUaWNrc1wiOiA0MDAsXG4gICAgICAgICAgICBcInNvdXJjZVwiOiBcIkVudGl0eVNwYXduaW5nRGVlcERpdmUubWQgZ2l2ZXMgJ341IHBlciB3YXRlciBib2R5Jy4gVGhpcyBwcm9qZWN0IGNvdW50cyBwZXIgcGxheWVyIGluc3RlYWQsIGJlY2F1c2UgYSB3YXRlciBib2R5IGlzIG5vdCBhIHF1YW50aXR5IHRoZSBzZXJ2ZXIgdHJhY2tzLlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwid2F0ZXJfYW1iaWVudFwiOiB7XG4gICAgICAgICAgICBcImNhcFwiOiAyMCxcbiAgICAgICAgICAgIFwic2NvcGVcIjogXCJwZXJfcGxheWVyXCIsXG4gICAgICAgICAgICBcImN5Y2xlVGlja3NcIjogNDAwLFxuICAgICAgICAgICAgXCJzb3VyY2VcIjogXCJFbnRpdHlTcGF3bmluZ0RlZXBEaXZlLm1kIGdpdmVzICd+MjAgcGVyIHdhdGVyIGJvZHknLiBObyB2YW5pbGxhIHNwYXduIHJ1bGUgbmFtZXMgdGhpcyBwb29sLlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwiYW1iaWVudFwiOiB7XG4gICAgICAgICAgICBcImNhcFwiOiAxNSxcbiAgICAgICAgICAgIFwic2NvcGVcIjogXCJwZXJfcGxheWVyXCIsXG4gICAgICAgICAgICBcImN5Y2xlVGlja3NcIjogNDAwLFxuICAgICAgICAgICAgXCJzb3VyY2VcIjogXCJFbnRpdHlTcGF3bmluZ0RlZXBEaXZlLm1kIGdpdmVzICd+MTUgaW4gY2F2ZXMnLiBPbmx5IHRoZSBiYXQgdXNlcyB0aGlzIHBvb2wuXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJtb25zdGVyXCI6IHtcbiAgICAgICAgICAgIFwiY2FwXCI6IDcwLFxuICAgICAgICAgICAgXCJzY29wZVwiOiBcInBlcl9yZWdpb25cIixcbiAgICAgICAgICAgIFwiY3ljbGVUaWNrc1wiOiAyMCxcbiAgICAgICAgICAgIFwic291cmNlXCI6IFwiRW50aXR5U3Bhd25pbmdEZWVwRGl2ZS5tZCBnaXZlcyAnfjcwIGluIGxvYWRlZCBjaHVua3MnLCBzbyB0aGUgY2FwIGNvdmVycyB0aGUgd2hvbGUgc3Bhd24gcmVnaW9uIHJhdGhlciB0aGFuIHNjYWxpbmcgd2l0aCBwbGF5ZXJzLiBUaGUgMjAtdGljayBjYWRlbmNlIGlzIHRoaXMgcHJvamVjdCdzIGNob2ljZTsgSmF2YSBydW5zIHRoZSBtb25zdGVyIHBhc3MgZXZlcnkgdGljaywgd2hpY2ggY29zdHMgbW9yZSB0aGFuIHRoaXMgc2VydmVyIHdhbnRzIHRvIHBheS5cIlxuICAgICAgICB9LFxuICAgICAgICBcImNhdFwiOiB7XG4gICAgICAgICAgICBcImNhcFwiOiA1LFxuICAgICAgICAgICAgXCJzY29wZVwiOiBcInBlcl9yZWdpb25cIixcbiAgICAgICAgICAgIFwiY3ljbGVUaWNrc1wiOiAxMjAwLFxuICAgICAgICAgICAgXCJzb3VyY2VcIjogXCJEYXRhRHJpdmVuU3Bhd25pbmcubWQgc2F5cyBvbmx5IHRoYXQgY2F0IGxpbWl0cyBhcmUgJ2Jhc2VkIHVwb24gdGhlIGFtb3VudCB3aXRoaW4gYSB2aWxsYWdlJyBhbmQgZ2l2ZXMgbm8gbnVtYmVyLiBGaXZlIHBlciByZWdpb24gYW5kIG9uZSBjeWNsZSBwZXIgbWludXRlIGFyZSB0aGlzIHByb2plY3QncyBjaG9pY2UuXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJwaWxsYWdlclwiOiB7XG4gICAgICAgICAgICBcImNhcFwiOiBudWxsLFxuICAgICAgICAgICAgXCJzY29wZVwiOiBcInBlcl9yZWdpb25cIixcbiAgICAgICAgICAgIFwiY3ljbGVUaWNrc1wiOiAyMCxcbiAgICAgICAgICAgIFwic291cmNlXCI6IFwiRW50aXR5U3Bhd25pbmdEZWVwRGl2ZS5tZCBzYXlzICdMaW1pdGVkIGJ5IHBhdHJvbHMnLCBzbyB0aGlzIHBvb2wgaGFzIG5vIGNhcCBvZiBpdHMgb3duIGFuZCBgbWluZWNyYWZ0OmRlbGF5X2ZpbHRlcmAgcGx1cyBgbWluZWNyYWZ0Om1vYl9ldmVudF9maWx0ZXJgIGdhdGUgaXQuXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJ2aWxsYWdlclwiOiB7XG4gICAgICAgICAgICBcImNhcFwiOiBudWxsLFxuICAgICAgICAgICAgXCJzY29wZVwiOiBcInBlcl9yZWdpb25cIixcbiAgICAgICAgICAgIFwiY3ljbGVUaWNrc1wiOiA0MDAsXG4gICAgICAgICAgICBcInNvdXJjZVwiOiBcIkRhdGFEcml2ZW5TcGF3bmluZy5tZCBzYXlzIHRoZSBwb29sIGV4aXN0cyBpbiB0aGUgZ2FtZSBmaWxlcyBhbmQgbm8gZW50aXR5IHVzZXMgaXQuXCJcbiAgICAgICAgfVxuICAgIH0sXG4gICAgXCJzcGF3blJhZGl1c0NodW5rc1wiOiA0LFxuICAgIFwic3Bhd25SYWRpdXNTb3VyY2VcIjogXCJCZWRyb2NrJ3MgZG9jdW1lbnRlZCBkZWZhdWx0IHNpbXVsYXRpb24gZGlzdGFuY2UgaXMgNCBjaHVua3MsIGFuZCB0aGUgdGlja2luZyBhcmVhIGRvY3VtZW50YXRpb24gc2F5cyAnYWxsIGZvcm1zIG9mIG1vYiBzcGF3bmluZyBhdHRlbXB0cyBhcmUgZG9uZSBpbiBhIHJhZGl1cyBjZW50ZXJlZCBvbiBhIHBsYXllcicuIE1vamFuZyBwdWJsaXNoZXMgbm8gc3Bhd24gcmFkaXVzLCBzbyB0aGlzIHByb2plY3QgdXNlcyB0aGUgc2ltdWxhdGlvbiBkaXN0YW5jZS5cIixcbiAgICBcImNodW5rc1BlckN5Y2xlXCI6IDgsXG4gICAgXCJwb3NpdGlvbnNQZXJDaHVua1wiOiAzLFxuICAgIFwiYXR0ZW1wdFNvdXJjZVwiOiBcIk1vamFuZyBwdWJsaXNoZXMgbm8gYXR0ZW1wdCByYXRlLiBFaWdodCBjaHVua3MgcGVyIHBsYXllciBwZXIgY3ljbGUgd2l0aCB0aHJlZSBwb3NpdGlvbnMgaW4gZWFjaCBpcyB0aGlzIHByb2plY3QncyBidWRnZXQsIHBpY2tlZCBzbyBvbmUgcGxheWVyIHN0YW5kaW5nIGluIGFuIGVtcHR5IHBsYWlucyBiaW9tZSByZWFjaGVzIHRoZSBhbmltYWwgY2FwIG9mIDEwIHdpdGhpbiBhIGZldyBhbmltYWwgY3ljbGVzLlwiLFxuICAgIFwiaGVyZFJhZGl1c1wiOiA1LFxuICAgIFwiaGVyZFJhZGl1c1NvdXJjZVwiOiBcIk1vamFuZyBwdWJsaXNoZXMgbm8gaGVyZCBwbGFjZW1lbnQgcnVsZS4gRml2ZSBibG9ja3MgaXMgdGhlIGhvcml6b250YWwgc3ByZWFkIEphdmEgZ2l2ZXMgYSBwYWNrIHNwYXduLlwiLFxuICAgIFwiZGVuc2l0eVJhZGl1c1wiOiAxNixcbiAgICBcImRlbnNpdHlSYWRpdXNTb3VyY2VcIjogXCJNb2phbmcgc2F5cyBgbWluZWNyYWZ0OmRlbnNpdHlfbGltaXRgIGNhcHMgJ3RoZSBhbW91bnQgb2YgbW9icyB0byBzcGF3biBpbiBjZXJ0YWluIGxvY2F0aW9ucycgYW5kIG5hbWVzIG5vIHJhZGl1cy4gT25lIGNodW5rJ3Mgd2lkdGggaXMgdGhpcyBwcm9qZWN0J3MgcmVhZGluZyBvZiAnbG9jYXRpb24nLlwiLFxuICAgIFwicmFpbkRhcmtlbmluZ1wiOiA1LFxuICAgIFwidGh1bmRlckRhcmtlbmluZ1wiOiAxMCxcbiAgICBcImRhcmtlbmluZ1NvdXJjZVwiOiBcIk1vamFuZyBwdWJsaXNoZXMgbmVpdGhlciB0aGUgbGlnaHQgdmFsdWUgYG1pbmVjcmFmdDpicmlnaHRuZXNzX2ZpbHRlcmAgY29tcGFyZXMgbm9yIHdoYXQgYGFkanVzdF9mb3Jfd2VhdGhlcmAgZG9lcyB0byBpdC4gSmF2YSdzIGBMZXZlbC5nZXRTa3lEYXJrZW5gIHN1YnRyYWN0cyA1IHVuZGVyIHJhaW4gYW5kIDEwIHVuZGVyIHRodW5kZXIsIHNvIHRoaXMgcHJvamVjdCBzdWJ0cmFjdHMgdGhlIHNhbWUgYW1vdW50cyBmcm9tIHRoZSBsaWdodCB0aGUgd29ybGQgcmVwb3J0cy5cIixcbiAgICBcImRlc3Bhd25SYWRpdXNDaHVua3NcIjogOCxcbiAgICBcImRlc3Bhd25GbG9vcllcIjogLTEyOCxcbiAgICBcImRlc3Bhd25Tb3VyY2VcIjogXCIxMjggYmxvY2tzIGlzIHRoZSBkb2N1bWVudGVkIGRlZmF1bHQgb2YgYG1pbmVjcmFmdDpkZXNwYXduLmRlc3Bhd25fZnJvbV9kaXN0YW5jZS5tYXhfZGlzdGFuY2VgLCB3aGljaCBpcyA4IGNodW5rcywgYW5kIGlzIHRoZSBvbmx5IHB1Ymxpc2hlZCBzcGF3bmluZyBkaXN0YW5jZS4gVGhlIFkgZmxvb3IgaXMgcHVibGlzaGVkOiBhbGwgbW9icyBkZXNwYXduIGF0IFk9LTEyOCBhbmQgYmVsb3cgaW4gYm90aCBlZGl0aW9ucy5cIlxufVxuIl0sIm1hcHBpbmdzIjoiIn0=
@@ -0,0 +1,2 @@
1
+ declare const _default: { "provenance": string; "pools": { "animal": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "water_animal": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "water_ambient": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "ambient": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "monster": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "cat": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "pillager": { "cap": null; "scope": string; "cycleTicks": number; "source": string }; "villager": { "cap": null; "scope": string; "cycleTicks": number; "source": string } }; "spawnRadiusChunks": number; "spawnRadiusSource": string; "chunksPerCycle": number; "positionsPerChunk": number; "attemptSource": string; "herdRadius": number; "herdRadiusSource": string; "densityRadius": number; "densityRadiusSource": string; "rainDarkening": number; "thunderDarkening": number; "darkeningSource": string; "despawnRadiusChunks": number; "despawnFloorY": number; "despawnSource": string };
2
+ export default _default;
@@ -0,0 +1,89 @@
1
+ // src/tables/spawnConstants.json
2
+ var provenance = "Mojang publishes no spawn attempt rate, no cap value, no spawn radius and no light algorithm for Bedrock Edition. The only published numbers are the tilde-hedged 'Typical Cap' column of EntitySpawningDeepDive.md. Every number below is therefore this project's choice; the `source` string on each one says where it came from, and a host may replace the whole table.";
3
+ var pools = {
4
+ "animal": {
5
+ "cap": 10,
6
+ "scope": "per_player",
7
+ "cycleTicks": 400,
8
+ "source": "EntitySpawningDeepDive.md gives '~10 per player'. The 400-tick cadence is Java's animal pass, because Bedrock publishes none."
9
+ },
10
+ "water_animal": {
11
+ "cap": 5,
12
+ "scope": "per_player",
13
+ "cycleTicks": 400,
14
+ "source": "EntitySpawningDeepDive.md gives '~5 per water body'. This project counts per player instead, because a water body is not a quantity the server tracks."
15
+ },
16
+ "water_ambient": {
17
+ "cap": 20,
18
+ "scope": "per_player",
19
+ "cycleTicks": 400,
20
+ "source": "EntitySpawningDeepDive.md gives '~20 per water body'. No vanilla spawn rule names this pool."
21
+ },
22
+ "ambient": {
23
+ "cap": 15,
24
+ "scope": "per_player",
25
+ "cycleTicks": 400,
26
+ "source": "EntitySpawningDeepDive.md gives '~15 in caves'. Only the bat uses this pool."
27
+ },
28
+ "monster": {
29
+ "cap": 70,
30
+ "scope": "per_region",
31
+ "cycleTicks": 20,
32
+ "source": "EntitySpawningDeepDive.md gives '~70 in loaded chunks', so the cap covers the whole spawn region rather than scaling with players. The 20-tick cadence is this project's choice; Java runs the monster pass every tick, which costs more than this server wants to pay."
33
+ },
34
+ "cat": {
35
+ "cap": 5,
36
+ "scope": "per_region",
37
+ "cycleTicks": 1200,
38
+ "source": "DataDrivenSpawning.md says only that cat limits are 'based upon the amount within a village' and gives no number. Five per region and one cycle per minute are this project's choice."
39
+ },
40
+ "pillager": {
41
+ "cap": null,
42
+ "scope": "per_region",
43
+ "cycleTicks": 20,
44
+ "source": "EntitySpawningDeepDive.md says 'Limited by patrols', so this pool has no cap of its own and `minecraft:delay_filter` plus `minecraft:mob_event_filter` gate it."
45
+ },
46
+ "villager": {
47
+ "cap": null,
48
+ "scope": "per_region",
49
+ "cycleTicks": 400,
50
+ "source": "DataDrivenSpawning.md says the pool exists in the game files and no entity uses it."
51
+ }
52
+ };
53
+ var spawnRadiusChunks = 4;
54
+ var spawnRadiusSource = "Bedrock's documented default simulation distance is 4 chunks, and the ticking area documentation says 'all forms of mob spawning attempts are done in a radius centered on a player'. Mojang publishes no spawn radius, so this project uses the simulation distance.";
55
+ var chunksPerCycle = 8;
56
+ var positionsPerChunk = 3;
57
+ var attemptSource = "Mojang publishes no attempt rate. Eight chunks per player per cycle with three positions in each is this project's budget, picked so one player standing in an empty plains biome reaches the animal cap of 10 within a few animal cycles.";
58
+ var herdRadius = 5;
59
+ var herdRadiusSource = "Mojang publishes no herd placement rule. Five blocks is the horizontal spread Java gives a pack spawn.";
60
+ var densityRadius = 16;
61
+ var densityRadiusSource = "Mojang says `minecraft:density_limit` caps 'the amount of mobs to spawn in certain locations' and names no radius. One chunk's width is this project's reading of 'location'.";
62
+ var rainDarkening = 5;
63
+ var thunderDarkening = 10;
64
+ var darkeningSource = "Mojang publishes neither the light value `minecraft:brightness_filter` compares nor what `adjust_for_weather` does to it. Java's `Level.getSkyDarken` subtracts 5 under rain and 10 under thunder, so this project subtracts the same amounts from the light the world reports.";
65
+ var despawnRadiusChunks = 8;
66
+ var despawnFloorY = -128;
67
+ var despawnSource = "128 blocks is the documented default of `minecraft:despawn.despawn_from_distance.max_distance`, which is 8 chunks, and is the only published spawning distance. The Y floor is published: all mobs despawn at Y=-128 and below in both editions.";
68
+ var spawnConstants_default = {
69
+ provenance,
70
+ pools,
71
+ spawnRadiusChunks: 4,
72
+ spawnRadiusSource,
73
+ chunksPerCycle: 8,
74
+ positionsPerChunk: 3,
75
+ attemptSource,
76
+ herdRadius: 5,
77
+ herdRadiusSource,
78
+ densityRadius: 16,
79
+ densityRadiusSource,
80
+ rainDarkening: 5,
81
+ thunderDarkening: 10,
82
+ darkeningSource,
83
+ despawnRadiusChunks: 8,
84
+ despawnFloorY,
85
+ despawnSource
86
+ };
87
+ export { attemptSource, chunksPerCycle, darkeningSource, spawnConstants_default as default, densityRadius, densityRadiusSource, despawnFloorY, despawnRadiusChunks, despawnSource, herdRadius, herdRadiusSource, pools, positionsPerChunk, provenance, rainDarkening, spawnRadiusChunks, spawnRadiusSource, thunderDarkening };
88
+
89
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bhd25Db25zdGFudHMuZXMuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RhYmxlcy9zcGF3bkNvbnN0YW50cy5qc29uIl0sInNvdXJjZXNDb250ZW50IjpbIntcbiAgICBcInByb3ZlbmFuY2VcIjogXCJNb2phbmcgcHVibGlzaGVzIG5vIHNwYXduIGF0dGVtcHQgcmF0ZSwgbm8gY2FwIHZhbHVlLCBubyBzcGF3biByYWRpdXMgYW5kIG5vIGxpZ2h0IGFsZ29yaXRobSBmb3IgQmVkcm9jayBFZGl0aW9uLiBUaGUgb25seSBwdWJsaXNoZWQgbnVtYmVycyBhcmUgdGhlIHRpbGRlLWhlZGdlZCAnVHlwaWNhbCBDYXAnIGNvbHVtbiBvZiBFbnRpdHlTcGF3bmluZ0RlZXBEaXZlLm1kLiBFdmVyeSBudW1iZXIgYmVsb3cgaXMgdGhlcmVmb3JlIHRoaXMgcHJvamVjdCdzIGNob2ljZTsgdGhlIGBzb3VyY2VgIHN0cmluZyBvbiBlYWNoIG9uZSBzYXlzIHdoZXJlIGl0IGNhbWUgZnJvbSwgYW5kIGEgaG9zdCBtYXkgcmVwbGFjZSB0aGUgd2hvbGUgdGFibGUuXCIsXG4gICAgXCJwb29sc1wiOiB7XG4gICAgICAgIFwiYW5pbWFsXCI6IHtcbiAgICAgICAgICAgIFwiY2FwXCI6IDEwLFxuICAgICAgICAgICAgXCJzY29wZVwiOiBcInBlcl9wbGF5ZXJcIixcbiAgICAgICAgICAgIFwiY3ljbGVUaWNrc1wiOiA0MDAsXG4gICAgICAgICAgICBcInNvdXJjZVwiOiBcIkVudGl0eVNwYXduaW5nRGVlcERpdmUubWQgZ2l2ZXMgJ34xMCBwZXIgcGxheWVyJy4gVGhlIDQwMC10aWNrIGNhZGVuY2UgaXMgSmF2YSdzIGFuaW1hbCBwYXNzLCBiZWNhdXNlIEJlZHJvY2sgcHVibGlzaGVzIG5vbmUuXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJ3YXRlcl9hbmltYWxcIjoge1xuICAgICAgICAgICAgXCJjYXBcIjogNSxcbiAgICAgICAgICAgIFwic2NvcGVcIjogXCJwZXJfcGxheWVyXCIsXG4gICAgICAgICAgICBcImN5Y2xlVGlja3NcIjogNDAwLFxuICAgICAgICAgICAgXCJzb3VyY2VcIjogXCJFbnRpdHlTcGF3bmluZ0RlZXBEaXZlLm1kIGdpdmVzICd+NSBwZXIgd2F0ZXIgYm9keScuIFRoaXMgcHJvamVjdCBjb3VudHMgcGVyIHBsYXllciBpbnN0ZWFkLCBiZWNhdXNlIGEgd2F0ZXIgYm9keSBpcyBub3QgYSBxdWFudGl0eSB0aGUgc2VydmVyIHRyYWNrcy5cIlxuICAgICAgICB9LFxuICAgICAgICBcIndhdGVyX2FtYmllbnRcIjoge1xuICAgICAgICAgICAgXCJjYXBcIjogMjAsXG4gICAgICAgICAgICBcInNjb3BlXCI6IFwicGVyX3BsYXllclwiLFxuICAgICAgICAgICAgXCJjeWNsZVRpY2tzXCI6IDQwMCxcbiAgICAgICAgICAgIFwic291cmNlXCI6IFwiRW50aXR5U3Bhd25pbmdEZWVwRGl2ZS5tZCBnaXZlcyAnfjIwIHBlciB3YXRlciBib2R5Jy4gTm8gdmFuaWxsYSBzcGF3biBydWxlIG5hbWVzIHRoaXMgcG9vbC5cIlxuICAgICAgICB9LFxuICAgICAgICBcImFtYmllbnRcIjoge1xuICAgICAgICAgICAgXCJjYXBcIjogMTUsXG4gICAgICAgICAgICBcInNjb3BlXCI6IFwicGVyX3BsYXllclwiLFxuICAgICAgICAgICAgXCJjeWNsZVRpY2tzXCI6IDQwMCxcbiAgICAgICAgICAgIFwic291cmNlXCI6IFwiRW50aXR5U3Bhd25pbmdEZWVwRGl2ZS5tZCBnaXZlcyAnfjE1IGluIGNhdmVzJy4gT25seSB0aGUgYmF0IHVzZXMgdGhpcyBwb29sLlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwibW9uc3RlclwiOiB7XG4gICAgICAgICAgICBcImNhcFwiOiA3MCxcbiAgICAgICAgICAgIFwic2NvcGVcIjogXCJwZXJfcmVnaW9uXCIsXG4gICAgICAgICAgICBcImN5Y2xlVGlja3NcIjogMjAsXG4gICAgICAgICAgICBcInNvdXJjZVwiOiBcIkVudGl0eVNwYXduaW5nRGVlcERpdmUubWQgZ2l2ZXMgJ343MCBpbiBsb2FkZWQgY2h1bmtzJywgc28gdGhlIGNhcCBjb3ZlcnMgdGhlIHdob2xlIHNwYXduIHJlZ2lvbiByYXRoZXIgdGhhbiBzY2FsaW5nIHdpdGggcGxheWVycy4gVGhlIDIwLXRpY2sgY2FkZW5jZSBpcyB0aGlzIHByb2plY3QncyBjaG9pY2U7IEphdmEgcnVucyB0aGUgbW9uc3RlciBwYXNzIGV2ZXJ5IHRpY2ssIHdoaWNoIGNvc3RzIG1vcmUgdGhhbiB0aGlzIHNlcnZlciB3YW50cyB0byBwYXkuXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJjYXRcIjoge1xuICAgICAgICAgICAgXCJjYXBcIjogNSxcbiAgICAgICAgICAgIFwic2NvcGVcIjogXCJwZXJfcmVnaW9uXCIsXG4gICAgICAgICAgICBcImN5Y2xlVGlja3NcIjogMTIwMCxcbiAgICAgICAgICAgIFwic291cmNlXCI6IFwiRGF0YURyaXZlblNwYXduaW5nLm1kIHNheXMgb25seSB0aGF0IGNhdCBsaW1pdHMgYXJlICdiYXNlZCB1cG9uIHRoZSBhbW91bnQgd2l0aGluIGEgdmlsbGFnZScgYW5kIGdpdmVzIG5vIG51bWJlci4gRml2ZSBwZXIgcmVnaW9uIGFuZCBvbmUgY3ljbGUgcGVyIG1pbnV0ZSBhcmUgdGhpcyBwcm9qZWN0J3MgY2hvaWNlLlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwicGlsbGFnZXJcIjoge1xuICAgICAgICAgICAgXCJjYXBcIjogbnVsbCxcbiAgICAgICAgICAgIFwic2NvcGVcIjogXCJwZXJfcmVnaW9uXCIsXG4gICAgICAgICAgICBcImN5Y2xlVGlja3NcIjogMjAsXG4gICAgICAgICAgICBcInNvdXJjZVwiOiBcIkVudGl0eVNwYXduaW5nRGVlcERpdmUubWQgc2F5cyAnTGltaXRlZCBieSBwYXRyb2xzJywgc28gdGhpcyBwb29sIGhhcyBubyBjYXAgb2YgaXRzIG93biBhbmQgYG1pbmVjcmFmdDpkZWxheV9maWx0ZXJgIHBsdXMgYG1pbmVjcmFmdDptb2JfZXZlbnRfZmlsdGVyYCBnYXRlIGl0LlwiXG4gICAgICAgIH0sXG4gICAgICAgIFwidmlsbGFnZXJcIjoge1xuICAgICAgICAgICAgXCJjYXBcIjogbnVsbCxcbiAgICAgICAgICAgIFwic2NvcGVcIjogXCJwZXJfcmVnaW9uXCIsXG4gICAgICAgICAgICBcImN5Y2xlVGlja3NcIjogNDAwLFxuICAgICAgICAgICAgXCJzb3VyY2VcIjogXCJEYXRhRHJpdmVuU3Bhd25pbmcubWQgc2F5cyB0aGUgcG9vbCBleGlzdHMgaW4gdGhlIGdhbWUgZmlsZXMgYW5kIG5vIGVudGl0eSB1c2VzIGl0LlwiXG4gICAgICAgIH1cbiAgICB9LFxuICAgIFwic3Bhd25SYWRpdXNDaHVua3NcIjogNCxcbiAgICBcInNwYXduUmFkaXVzU291cmNlXCI6IFwiQmVkcm9jaydzIGRvY3VtZW50ZWQgZGVmYXVsdCBzaW11bGF0aW9uIGRpc3RhbmNlIGlzIDQgY2h1bmtzLCBhbmQgdGhlIHRpY2tpbmcgYXJlYSBkb2N1bWVudGF0aW9uIHNheXMgJ2FsbCBmb3JtcyBvZiBtb2Igc3Bhd25pbmcgYXR0ZW1wdHMgYXJlIGRvbmUgaW4gYSByYWRpdXMgY2VudGVyZWQgb24gYSBwbGF5ZXInLiBNb2phbmcgcHVibGlzaGVzIG5vIHNwYXduIHJhZGl1cywgc28gdGhpcyBwcm9qZWN0IHVzZXMgdGhlIHNpbXVsYXRpb24gZGlzdGFuY2UuXCIsXG4gICAgXCJjaHVua3NQZXJDeWNsZVwiOiA4LFxuICAgIFwicG9zaXRpb25zUGVyQ2h1bmtcIjogMyxcbiAgICBcImF0dGVtcHRTb3VyY2VcIjogXCJNb2phbmcgcHVibGlzaGVzIG5vIGF0dGVtcHQgcmF0ZS4gRWlnaHQgY2h1bmtzIHBlciBwbGF5ZXIgcGVyIGN5Y2xlIHdpdGggdGhyZWUgcG9zaXRpb25zIGluIGVhY2ggaXMgdGhpcyBwcm9qZWN0J3MgYnVkZ2V0LCBwaWNrZWQgc28gb25lIHBsYXllciBzdGFuZGluZyBpbiBhbiBlbXB0eSBwbGFpbnMgYmlvbWUgcmVhY2hlcyB0aGUgYW5pbWFsIGNhcCBvZiAxMCB3aXRoaW4gYSBmZXcgYW5pbWFsIGN5Y2xlcy5cIixcbiAgICBcImhlcmRSYWRpdXNcIjogNSxcbiAgICBcImhlcmRSYWRpdXNTb3VyY2VcIjogXCJNb2phbmcgcHVibGlzaGVzIG5vIGhlcmQgcGxhY2VtZW50IHJ1bGUuIEZpdmUgYmxvY2tzIGlzIHRoZSBob3Jpem9udGFsIHNwcmVhZCBKYXZhIGdpdmVzIGEgcGFjayBzcGF3bi5cIixcbiAgICBcImRlbnNpdHlSYWRpdXNcIjogMTYsXG4gICAgXCJkZW5zaXR5UmFkaXVzU291cmNlXCI6IFwiTW9qYW5nIHNheXMgYG1pbmVjcmFmdDpkZW5zaXR5X2xpbWl0YCBjYXBzICd0aGUgYW1vdW50IG9mIG1vYnMgdG8gc3Bhd24gaW4gY2VydGFpbiBsb2NhdGlvbnMnIGFuZCBuYW1lcyBubyByYWRpdXMuIE9uZSBjaHVuaydzIHdpZHRoIGlzIHRoaXMgcHJvamVjdCdzIHJlYWRpbmcgb2YgJ2xvY2F0aW9uJy5cIixcbiAgICBcInJhaW5EYXJrZW5pbmdcIjogNSxcbiAgICBcInRodW5kZXJEYXJrZW5pbmdcIjogMTAsXG4gICAgXCJkYXJrZW5pbmdTb3VyY2VcIjogXCJNb2phbmcgcHVibGlzaGVzIG5laXRoZXIgdGhlIGxpZ2h0IHZhbHVlIGBtaW5lY3JhZnQ6YnJpZ2h0bmVzc19maWx0ZXJgIGNvbXBhcmVzIG5vciB3aGF0IGBhZGp1c3RfZm9yX3dlYXRoZXJgIGRvZXMgdG8gaXQuIEphdmEncyBgTGV2ZWwuZ2V0U2t5RGFya2VuYCBzdWJ0cmFjdHMgNSB1bmRlciByYWluIGFuZCAxMCB1bmRlciB0aHVuZGVyLCBzbyB0aGlzIHByb2plY3Qgc3VidHJhY3RzIHRoZSBzYW1lIGFtb3VudHMgZnJvbSB0aGUgbGlnaHQgdGhlIHdvcmxkIHJlcG9ydHMuXCIsXG4gICAgXCJkZXNwYXduUmFkaXVzQ2h1bmtzXCI6IDgsXG4gICAgXCJkZXNwYXduRmxvb3JZXCI6IC0xMjgsXG4gICAgXCJkZXNwYXduU291cmNlXCI6IFwiMTI4IGJsb2NrcyBpcyB0aGUgZG9jdW1lbnRlZCBkZWZhdWx0IG9mIGBtaW5lY3JhZnQ6ZGVzcGF3bi5kZXNwYXduX2Zyb21fZGlzdGFuY2UubWF4X2Rpc3RhbmNlYCwgd2hpY2ggaXMgOCBjaHVua3MsIGFuZCBpcyB0aGUgb25seSBwdWJsaXNoZWQgc3Bhd25pbmcgZGlzdGFuY2UuIFRoZSBZIGZsb29yIGlzIHB1Ymxpc2hlZDogYWxsIG1vYnMgZGVzcGF3biBhdCBZPS0xMjggYW5kIGJlbG93IGluIGJvdGggZWRpdGlvbnMuXCJcbn1cbiJdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,2 @@
1
+ declare const _default: { "provenance": string; "pools": { "animal": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "water_animal": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "water_ambient": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "ambient": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "monster": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "cat": { "cap": number; "scope": string; "cycleTicks": number; "source": string }; "pillager": { "cap": null; "scope": string; "cycleTicks": number; "source": string }; "villager": { "cap": null; "scope": string; "cycleTicks": number; "source": string } }; "spawnRadiusChunks": number; "spawnRadiusSource": string; "chunksPerCycle": number; "positionsPerChunk": number; "attemptSource": string; "herdRadius": number; "herdRadiusSource": string; "densityRadius": number; "densityRadiusSource": string; "rainDarkening": number; "thunderDarkening": number; "darkeningSource": string; "despawnRadiusChunks": number; "despawnFloorY": number; "despawnSource": string };
2
+ export default _default;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ // src/world.ts
4
+ /**
5
+ * The boolean facts about one position, each named by the rule component or
6
+ * filter test that reads it.
7
+ *
8
+ * `surface` and `underground` select the pass; `underwater` and `lava` are the
9
+ * medium the position sits in; `bubble_column` answers
10
+ * `minecraft:disallow_spawns_in_bubble`; `snow_covered` answers the one
11
+ * `is_snow_covered` test a vanilla biome filter writes.
12
+ */
13
+ var SPAWN_SITE_FLAGS = [
14
+ "surface",
15
+ "underground",
16
+ "underwater",
17
+ "lava",
18
+ "bubble_column",
19
+ "snow_covered"
20
+ ];
21
+ /** The weather names `adjust_for_weather` reads. */
22
+ var SPAWN_WEATHER = [
23
+ "clear",
24
+ "rain",
25
+ "thunder"
26
+ ];
27
+ /** The squared distance between two positions, which is what the range checks compare. */
28
+ var distanceSquared = (from, to) => {
29
+ const dx = from.x - to.x;
30
+ const dy = from.y - to.y;
31
+ const dz = from.z - to.z;
32
+ return dx * dx + dy * dy + dz * dz;
33
+ };
34
+ /**
35
+ * The squared distance between two positions on the X and Z axes alone, which
36
+ * is what a chunk radius such as the simulation distance measures.
37
+ */
38
+ var horizontalDistanceSquared = (from, to) => {
39
+ const dx = from.x - to.x;
40
+ const dz = from.z - to.z;
41
+ return dx * dx + dz * dz;
42
+ };
43
+ /** Which pass a position belongs to, which the world decides and the conditions read. */
44
+ var passAt = (world, at) => world.site("underground", at) ? "underground" : "surface";
45
+ exports.SPAWN_SITE_FLAGS = SPAWN_SITE_FLAGS;
46
+ exports.SPAWN_WEATHER = SPAWN_WEATHER;
47
+ exports.distanceSquared = distanceSquared;
48
+ exports.horizontalDistanceSquared = horizontalDistanceSquared;
49
+ exports.passAt = passAt;
50
+
51
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ybGQuY2pzLmNqcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi9zcmMvd29ybGQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBEaWZmaWN1bHR5IH0gZnJvbSAnLi9ydWxlcyc7XG5cbi8qKlxuICogV2hhdCB0aGUgc3Bhd25lciByZWFkcyBhYm91dCB0aGUgd29ybGQuXG4gKlxuICogRXZlcnkgZmFjdCBhIHNwYXduIHJ1bGUgYXNrcyBmb3IgYXJyaXZlcyB0aHJvdWdoIHRoaXMgb25lIGludGVyZmFjZSwgc28gYVxuICogdGVzdCBkcml2ZXMgdGhlIHdob2xlIGFsZ29yaXRobSB3aXRoIGEgdHlwZWQgZG91YmxlIGFuZCBhIHNlcnZlciBpbXBsZW1lbnRzXG4gKiBpdCBvbmNlIGFnYWluc3QgaXRzIG93biBjaHVua3MsIGxpZ2h0IGVuZ2luZSBhbmQgZW50aXR5IGluZGV4LlxuICovXG5cbi8qKiBBIGJsb2NrIHBvc2l0aW9uLiBTcGF3biBwb3NpdGlvbnMgYXJlIGludGVnZXJzOyBkaXN0YW5jZXMgYXJlIG1lYXN1cmVkIGJldHdlZW4gY2VudGVycy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3Bhd25Qb3NpdGlvbiB7XG4gICAgcmVhZG9ubHkgeDogbnVtYmVyO1xuICAgIHJlYWRvbmx5IHk6IG51bWJlcjtcbiAgICByZWFkb25seSB6OiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIGJvb2xlYW4gZmFjdHMgYWJvdXQgb25lIHBvc2l0aW9uLCBlYWNoIG5hbWVkIGJ5IHRoZSBydWxlIGNvbXBvbmVudCBvclxuICogZmlsdGVyIHRlc3QgdGhhdCByZWFkcyBpdC5cbiAqXG4gKiBgc3VyZmFjZWAgYW5kIGB1bmRlcmdyb3VuZGAgc2VsZWN0IHRoZSBwYXNzOyBgdW5kZXJ3YXRlcmAgYW5kIGBsYXZhYCBhcmUgdGhlXG4gKiBtZWRpdW0gdGhlIHBvc2l0aW9uIHNpdHMgaW47IGBidWJibGVfY29sdW1uYCBhbnN3ZXJzXG4gKiBgbWluZWNyYWZ0OmRpc2FsbG93X3NwYXduc19pbl9idWJibGVgOyBgc25vd19jb3ZlcmVkYCBhbnN3ZXJzIHRoZSBvbmVcbiAqIGBpc19zbm93X2NvdmVyZWRgIHRlc3QgYSB2YW5pbGxhIGJpb21lIGZpbHRlciB3cml0ZXMuXG4gKi9cbmV4cG9ydCBjb25zdCBTUEFXTl9TSVRFX0ZMQUdTID0gW1xuICAgICdzdXJmYWNlJyxcbiAgICAndW5kZXJncm91bmQnLFxuICAgICd1bmRlcndhdGVyJyxcbiAgICAnbGF2YScsXG4gICAgJ2J1YmJsZV9jb2x1bW4nLFxuICAgICdzbm93X2NvdmVyZWQnXG5dIGFzIGNvbnN0O1xuXG4vKiogT25lIG9mIHtAbGluayBTUEFXTl9TSVRFX0ZMQUdTfS4gKi9cbmV4cG9ydCB0eXBlIFNwYXduU2l0ZUZsYWcgPSAodHlwZW9mIFNQQVdOX1NJVEVfRkxBR1MpW251bWJlcl07XG5cbi8qKiBXaGljaCBvZiB0aGUgdHdvIHBhc3NlcyBhIHBvc2l0aW9uIGJlbG9uZ3MgdG8uICovXG5leHBvcnQgdHlwZSBTcGF3blBhc3MgPSAnc3VyZmFjZScgfCAndW5kZXJncm91bmQnO1xuXG4vKiogVGhlIHdlYXRoZXIgbmFtZXMgYGFkanVzdF9mb3Jfd2VhdGhlcmAgcmVhZHMuICovXG5leHBvcnQgY29uc3QgU1BBV05fV0VBVEhFUiA9IFsnY2xlYXInLCAncmFpbicsICd0aHVuZGVyJ10gYXMgY29uc3Q7XG5cbi8qKiBPbmUgb2Yge0BsaW5rIFNQQVdOX1dFQVRIRVJ9LiAqL1xuZXhwb3J0IHR5cGUgU3Bhd25XZWF0aGVyID0gKHR5cGVvZiBTUEFXTl9XRUFUSEVSKVtudW1iZXJdO1xuXG4vKiogT25lIHBsYXllciB0aGUgc3Bhd25lciBzcGF3bnMgYXJvdW5kLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcGF3blBsYXllciB7XG4gICAgcmVhZG9ubHkgcG9zaXRpb246IFNwYXduUG9zaXRpb247XG59XG5cbi8qKiBFdmVyeXRoaW5nIG9uZSBzcGF3biBjeWNsZSByZWFkcyBhYm91dCB0aGUgd29ybGQuICovXG5leHBvcnQgaW50ZXJmYWNlIFNwYXduV29ybGQge1xuICAgIC8qKiBBIGJvb2xlYW4gZmFjdCBhYm91dCBvbmUgcG9zaXRpb24sIG5hbWVkIGJ5IHRoZSBjb21wb25lbnQgdGhhdCByZWFkcyBpdC4gKi9cbiAgICBzaXRlKGZsYWc6IFNwYXduU2l0ZUZsYWcsIGF0OiBTcGF3blBvc2l0aW9uKTogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBUaGUgYmxvY2sgaWRlbnRpZmllciBhdCBvbmUgcG9zaXRpb24sIG9yIHVuZGVmaW5lZCB3aGVuIHRoZSBjaHVuayBpcyBub3RcbiAgICAgKiBsb2FkZWQsIHdoaWNoIHN0b3BzIHRoZSBhdHRlbXB0LlxuICAgICAqL1xuICAgIGJsb2NrKGF0OiBTcGF3blBvc2l0aW9uKTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGJsb2NrIGF0IG9uZSBwb3NpdGlvbiBzdG9wcyBhbiBlbnRpdHkgc3RhbmRpbmcgaW4gaXQuXG4gICAgICpcbiAgICAgKiBUaGUgdW5kZXJncm91bmQgcGFzcyBkcmF3cyBhIHkgdW5pZm9ybWx5IGJldHdlZW4gdGhlIHdvcmxkIGZsb29yIGFuZCB0aGVcbiAgICAgKiBzdXJmYWNlLCBzbyBtb3N0IG9mIHdoYXQgaXQgZHJhd3MgaXMgaW5zaWRlIHJvY2suIEphdmEgcmVqZWN0cyBzdWNoIGFcbiAgICAgKiBkcmF3IGluIGBOYXR1cmFsU3Bhd25lci5pc1NwYXduUG9zaXRpb25Pa2A7IHdpdGhvdXQgdGhpcyB0aGUgc3Bhd25lclxuICAgICAqIHB1dHMgYSB6b21iaWUgaW5zaWRlIGEgc3RvbmUgYmxvY2ssIHdoZXJlIGl0IGNhbiBwYXRoIG5vd2hlcmUgYW5kIG5ldmVyXG4gICAgICogZGVzcGF3bnMuXG4gICAgICovXG4gICAgc29saWQoYXQ6IFNwYXduUG9zaXRpb24pOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFRoZSBsaWdodCBsZXZlbCBhdCBvbmUgcG9zaXRpb24sIDAgdG8gMTUsIGJlZm9yZSB0aGlzIHBhY2thZ2UgYXBwbGllcyB0aGVcbiAgICAgKiB3ZWF0aGVyIGRhcmtlbmluZyB0aGF0IGBhZGp1c3RfZm9yX3dlYXRoZXJgIGFza3MgZm9yLlxuICAgICAqL1xuICAgIGxpZ2h0KGF0OiBTcGF3blBvc2l0aW9uKTogbnVtYmVyO1xuICAgIC8qKiBUaGUgYmlvbWUgdGFncyBhdCBvbmUgcG9zaXRpb24sIHdoaWNoIGlzIHdoYXQgYGhhc19iaW9tZV90YWdgIGNvbXBhcmVzLiAqL1xuICAgIGJpb21lVGFncyhhdDogU3Bhd25Qb3NpdGlvbik6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICAgIC8qKiBUaGUgYmlvbWUgbmFtZSBhdCBvbmUgcG9zaXRpb24sIGZvciBgaXNfYmlvbWVgLiAqL1xuICAgIGJpb21lPyhhdDogU3Bhd25Qb3NpdGlvbik6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBUaGUgbG93ZXN0IHkgYW4gZW50aXR5IG1heSBzdGFuZCBvbiBpbiBvbmUgY29sdW1uLCB3aGljaCBpcyB0aGUgcG9zaXRpb25cbiAgICAgKiB0aGUgc3VyZmFjZSBwYXNzIHRyaWVzLiBVbmRlZmluZWQgd2hlbiB0aGUgY29sdW1uIGlzIG5vdCBsb2FkZWQsIHdoaWNoXG4gICAgICogc2tpcHMgdGhlIGF0dGVtcHQuXG4gICAgICovXG4gICAgc3VyZmFjZVkoeDogbnVtYmVyLCB6OiBudW1iZXIpOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgLyoqIFRoZSBsb3dlc3QgeSB0aGUgd29ybGQgZ2VuZXJhdGVzLCB3aGljaCBib3VuZHMgdGhlIHVuZGVyZ3JvdW5kIHBhc3MuICovXG4gICAgbWluWSgpOiBudW1iZXI7XG4gICAgLyoqIFRoZSBwbGF5ZXJzIHRoZSBzcGF3bmVyIHNwYXducyBhcm91bmQsIHdoaWNoIGlzIGV2ZXJ5IHBsYXllciBpbiB0aGUgc3Bhd24gcmVnaW9uLiAqL1xuICAgIHBsYXllcnMoKTogcmVhZG9ubHkgU3Bhd25QbGF5ZXJbXTtcbiAgICAvKiogSG93IG1hbnkgZW50aXRpZXMgb2Ygb25lIHBvcHVsYXRpb24gcG9vbCBzdGFuZCBpbiB0aGUgc3Bhd24gcmVnaW9uIG5vdy4gKi9cbiAgICBwb29sQ291bnQocG9vbDogc3RyaW5nKTogbnVtYmVyO1xuICAgIC8qKiBIb3cgbWFueSBlbnRpdGllcyBvZiBvbmUgdHlwZSBzdGFuZCB3aXRoaW4gYHJhZGl1c2AgYmxvY2tzIG9mIGEgcG9zaXRpb24uICovXG4gICAgdHlwZUNvdW50KGlkZW50aWZpZXI6IHN0cmluZywgYXQ6IFNwYXduUG9zaXRpb24sIHJhZGl1czogbnVtYmVyKTogbnVtYmVyO1xuICAgIGRpZmZpY3VsdHkoKTogRGlmZmljdWx0eTtcbiAgICB3ZWF0aGVyKCk6IFNwYXduV2VhdGhlcjtcbiAgICAvKiogVGhlIHdvcmxkJ3MgYWdlIGluIHRpY2tzLCB3aGljaCBpcyB3aGF0IGBtaW5lY3JhZnQ6d29ybGRfYWdlX2ZpbHRlcmAgY29tcGFyZXMuICovXG4gICAgYWdlKCk6IG51bWJlcjtcbiAgICAvKiogV2hldGhlciBhIG5hbWVkIG1vYiBldmVudCwgc3VjaCBhcyBgbWluZWNyYWZ0OnBpbGxhZ2VyX3BhdHJvbHNfZXZlbnRgLCBpcyBydW5uaW5nLiAqL1xuICAgIG1vYkV2ZW50QWN0aXZlKGV2ZW50OiBzdHJpbmcpOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIEhvdyBmYXIgYSBwb3NpdGlvbiBpcyBmcm9tIHRoZSBuZWFyZXN0IHZpbGxhZ2UgYm9yZGVyLCBuZWdhdGl2ZSBpbnNpZGUgaXRcbiAgICAgKiBhbmQgdW5kZWZpbmVkIHdoZW4gbm8gdmlsbGFnZSBpcyBuZWFyLiBgbWluZWNyYWZ0OnBsYXllcl9pbl92aWxsYWdlX2ZpbHRlcmBcbiAgICAgKiByZWFkcyBpdC5cbiAgICAgKi9cbiAgICB2aWxsYWdlQm9yZGVyRGlzdGFuY2U/KGF0OiBTcGF3blBvc2l0aW9uKTogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgSmF2YSByZXN0cmljdHMgdGhpcyBlbnRpdHkgdHlwZSB0byBhIHN0cnVjdHVyZSBzcGF3biBvdmVycmlkZSBhdCB0aGlzIHBvc2l0aW9uLlxuICAgICAqXG4gICAgICogYGZhbHNlYCBtZWFucyB0aGUgSmF2YSBkYXRhIGRlY2xhcmVzIGF0IGxlYXN0IG9uZSBzdHJ1Y3R1cmUgb3ZlcnJpZGUgZm9yIHRoZSBlbnRpdHksIGJ1dFxuICAgICAqIHRoaXMgcG9zaXRpb24gaXMgb3V0c2lkZSBldmVyeSBhY3RpdmUgb3ZlcnJpZGUuIGB0cnVlYCBtZWFucyBhIG1hdGNoaW5nIG92ZXJyaWRlIGNvdmVyc1xuICAgICAqIHRoaXMgcG9zaXRpb24uIGB1bmRlZmluZWRgIG1lYW5zIEphdmEncyBiaW9tZSBkYXRhIGFsc28gcGVybWl0cyB0aGlzIGVudGl0eSB0byBzcGF3blxuICAgICAqIG91dHNpZGUgc3RydWN0dXJlcywgb3IgdGhhdCB0aGUgd29ybGQgaGFzIG5vIEphdmEgb3ZlcnJpZGUgZGF0YSBmb3IgaXQsIHNvIHRoZSBzcGF3biBydWxlXG4gICAgICogZGVjaWRlcyBhcyB1c3VhbC5cbiAgICAgKi9cbiAgICBzdHJ1Y3R1cmVTcGF3bk92ZXJyaWRlQXQ/KGlkZW50aWZpZXI6IHN0cmluZywgYXQ6IFNwYXduUG9zaXRpb24pOiBib29sZWFuIHwgdW5kZWZpbmVkO1xufVxuXG4vKiogVGhlIHNxdWFyZWQgZGlzdGFuY2UgYmV0d2VlbiB0d28gcG9zaXRpb25zLCB3aGljaCBpcyB3aGF0IHRoZSByYW5nZSBjaGVja3MgY29tcGFyZS4gKi9cbmV4cG9ydCBjb25zdCBkaXN0YW5jZVNxdWFyZWQgPSAoZnJvbTogU3Bhd25Qb3NpdGlvbiwgdG86IFNwYXduUG9zaXRpb24pOiBudW1iZXIgPT4ge1xuICAgIGNvbnN0IGR4ID0gZnJvbS54IC0gdG8ueDtcbiAgICBjb25zdCBkeSA9IGZyb20ueSAtIHRvLnk7XG4gICAgY29uc3QgZHogPSBmcm9tLnogLSB0by56O1xuICAgIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeSArIGR6ICogZHo7XG59O1xuXG4vKipcbiAqIFRoZSBzcXVhcmVkIGRpc3RhbmNlIGJldHdlZW4gdHdvIHBvc2l0aW9ucyBvbiB0aGUgWCBhbmQgWiBheGVzIGFsb25lLCB3aGljaFxuICogaXMgd2hhdCBhIGNodW5rIHJhZGl1cyBzdWNoIGFzIHRoZSBzaW11bGF0aW9uIGRpc3RhbmNlIG1lYXN1cmVzLlxuICovXG5leHBvcnQgY29uc3QgaG9yaXpvbnRhbERpc3RhbmNlU3F1YXJlZCA9IChmcm9tOiBTcGF3blBvc2l0aW9uLCB0bzogU3Bhd25Qb3NpdGlvbik6IG51bWJlciA9PiB7XG4gICAgY29uc3QgZHggPSBmcm9tLnggLSB0by54O1xuICAgIGNvbnN0IGR6ID0gZnJvbS56IC0gdG8uejtcbiAgICByZXR1cm4gZHggKiBkeCArIGR6ICogZHo7XG59O1xuXG4vKiogV2hpY2ggcGFzcyBhIHBvc2l0aW9uIGJlbG9uZ3MgdG8sIHdoaWNoIHRoZSB3b3JsZCBkZWNpZGVzIGFuZCB0aGUgY29uZGl0aW9ucyByZWFkLiAqL1xuZXhwb3J0IGNvbnN0IHBhc3NBdCA9ICh3b3JsZDogU3Bhd25Xb3JsZCwgYXQ6IFNwYXduUG9zaXRpb24pOiBTcGF3blBhc3MgPT5cbiAgICB3b3JsZC5zaXRlKCd1bmRlcmdyb3VuZCcsIGF0KSA/ICd1bmRlcmdyb3VuZCcgOiAnc3VyZmFjZSc7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQTBCQSxJQUFhLG1CQUFtQjtDQUM1QjtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7QUFDSjs7QUFTQSxJQUFhLGdCQUFnQjtDQUFDO0NBQVM7Q0FBUTtBQUFTOztBQTZFeEQsSUFBYSxtQkFBbUIsTUFBcUIsT0FBOEI7Q0FDL0UsTUFBTSxLQUFLLEtBQUssSUFBSSxHQUFHO0NBQ3ZCLE1BQU0sS0FBSyxLQUFLLElBQUksR0FBRztDQUN2QixNQUFNLEtBQUssS0FBSyxJQUFJLEdBQUc7Q0FDdkIsT0FBTyxLQUFLLEtBQUssS0FBSyxLQUFLLEtBQUs7QUFDcEM7Ozs7O0FBTUEsSUFBYSw2QkFBNkIsTUFBcUIsT0FBOEI7Q0FDekYsTUFBTSxLQUFLLEtBQUssSUFBSSxHQUFHO0NBQ3ZCLE1BQU0sS0FBSyxLQUFLLElBQUksR0FBRztDQUN2QixPQUFPLEtBQUssS0FBSyxLQUFLO0FBQzFCOztBQUdBLElBQWEsVUFBVSxPQUFtQixPQUN0QyxNQUFNLEtBQUssZUFBZSxFQUFFLElBQUksZ0JBQWdCIn0=