UNPKG

@jsprismarine/prismarine

Version:

Dedicated Minecraft Bedrock Edition server written in TypeScript

147 lines (144 loc) • 18.4 kB
import { BlockMappings } from '../../block/BlockMappings.es.js'; import BinaryStream from '@jsprismarine/jsbinaryutils'; import { Vector3 } from '@jsprismarine/math'; import SubChunk from './SubChunk.es.js'; const MAX_SUBCHUNKS = 16; class Chunk { x; z; hasChanged; subChunks = /* @__PURE__ */ new Map(); static EMPTY_SUBCHUNK = new SubChunk(); constructor(chunkX = 0, chunkZ = 0, _subChunks = /* @__PURE__ */ new Map()) { this.x = chunkX; this.z = chunkZ; this.hasChanged = false; } getX() { return this.x; } getZ() { return this.z; } getHasChanged() { return this.hasChanged; } getHeight() { return this.subChunks.size; } /** * Returns the highest empty sub chunk (so we don't send empty sub chunks). * @returns {number} The highest empty sub chunk. */ getTopEmpty() { let topEmpty = MAX_SUBCHUNKS - 1; while (topEmpty >= 0 && !this.subChunks.has(topEmpty) || this.subChunks.has(topEmpty) && this.subChunks.get(topEmpty).isEmpty()) { topEmpty--; } return ++topEmpty; } /** * Returns the Chunk slice at the given layer. * @param {number} y - The layer to get. */ getSubChunk(y) { if (y < 0 || y > MAX_SUBCHUNKS) { throw new Error(`Invalid subchunk height: ${y}`); } return this.subChunks.get(y) ?? null; } getOrCreateSubChunk(y) { const subChunk = new SubChunk(); this.subChunks.set(y, subChunk); return subChunk; } getSubChunks() { return this.subChunks; } getHighestBlockAt(_x, _z) { return 100; } /** * Returns block legacy id (DATA) in the corresponding sub chunk. * Use world to get the actual block instance (this is to keep code clean). * @param {Vector3 | number} x - block x. * @param {number} [y=0] - block y. * @param {number} [z=0] - block z. * @param {number} [layer=0] - block storage layer (0 for blocks, 1 for liquids). */ getBlock(x, y = 0, z = 0, layer = 0) { if (x instanceof Vector3) { return this.getBlock(x.getX(), x.getY(), x.getZ(), layer); } const subChunk = this.getSubChunk(Math.floor(y / 16)); if (!subChunk) return BlockMappings.getLegacyId(BlockMappings.getRuntimeId("minecraft:air")); return subChunk.getBlock(x, y & 15, z, layer); } /** * Sets a block into the chunk by its runtime Id. * @param {number} x - block x * @param {number} y - block y * @param {number} z - block z * @param {Block} block - block to set * @param {number} [layer=0] - block storage layer (0 for blocks, 1 for liquids) */ setBlock(x, y, z, block, layer = 0) { let subChunk = this.getSubChunk(Math.floor(y / 16)); if (!subChunk) subChunk = this.getOrCreateSubChunk(y >> 4); subChunk.setBlock(x, y & 15, z, BlockMappings.getRuntimeId(block.getName()), layer); this.hasChanged = true; } /** * Helper method used to hash into a single 64 bits integer * both Chunk X and Z coordinates. * @param {number} chunkX - Target Chunk X coordinate. * @param {number} chunkZ - Target Chunk Z coordinate. * @returns {bigint} A 64 bit intger containing a hash of X and Z. */ static packXZ(chunkX, chunkZ) { return (BigInt(chunkX) & 0xffffffffn) << 32n | BigInt(chunkZ) & 0xffffffffn; } /** * Helper method used to decode a 64 bit hash containing * both Chunk X and Z coordinates. * @param {bigint} packed - Target Chunk coordinate hash. * @returns {number[]} An array containing decoded Chunk X and Z coordinates. */ static unpackXZ(packed) { return [Number(BigInt.asIntN(32, packed >> 32n)), Number(BigInt.asIntN(32, packed & 0xffffffffn))]; } networkSerialize() { const stream = new BinaryStream(); for (let y = 0; y < 4; ++y) { stream.writeByte(8); stream.writeByte(0); } for (let y = 0; y < this.getTopEmpty(); ++y) { (this.subChunks.get(y) ?? Chunk.EMPTY_SUBCHUNK).networkSerialize(stream); } for (let i = 0; i < 24; i++) { stream.writeByte(0); stream.writeUnsignedVarInt(1 << 1); } stream.writeByte(0); return stream.getBuffer(); } /** * Deserialize network stream into chunk * useful for client applications and/or our Filesystem impl * @param {BinaryStream} stream - the network stream * @param {number} [x] - the chunk x coordinate * @param {number} [z] - the chunk z coordinate */ static networkDeserialize(stream, x, z) { stream.read(8); const subChunks = /* @__PURE__ */ new Map(); for (let i = 0; i < MAX_SUBCHUNKS; i++) { subChunks.set(i, SubChunk.networkDeserialize(stream)); } const chunk = new Chunk(x, z, subChunks); return chunk; } } export { Chunk as default }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2h1bmsuZXMuanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy93b3JsZC9jaHVuay9DaHVuay50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IExlZ2FjeUlkIH0gZnJvbSAnLi4vLi4vYmxvY2svQmxvY2tNYXBwaW5ncyc7XG5pbXBvcnQgeyBCbG9ja01hcHBpbmdzIH0gZnJvbSAnLi4vLi4vYmxvY2svQmxvY2tNYXBwaW5ncyc7XG5cbmltcG9ydCBCaW5hcnlTdHJlYW0gZnJvbSAnQGpzcHJpc21hcmluZS9qc2JpbmFyeXV0aWxzJztcbmltcG9ydCB7IFZlY3RvcjMgfSBmcm9tICdAanNwcmlzbWFyaW5lL21hdGgnO1xuaW1wb3J0IHR5cGUgeyBCbG9jayB9IGZyb20gJy4uLy4uL2Jsb2NrL0Jsb2NrJztcbmltcG9ydCBTdWJDaHVuayBmcm9tICcuL1N1YkNodW5rJztcblxuY29uc3QgTUFYX1NVQkNIVU5LUyA9IDE2O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDaHVuayB7XG4gICAgcHJpdmF0ZSB4OiBudW1iZXI7XG4gICAgcHJpdmF0ZSB6OiBudW1iZXI7XG4gICAgcHJpdmF0ZSBoYXNDaGFuZ2VkOiBib29sZWFuO1xuXG4gICAgcHJpdmF0ZSBzdWJDaHVua3M6IE1hcDxudW1iZXIsIFN1YkNodW5rPiA9IG5ldyBNYXAoKTtcbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBFTVBUWV9TVUJDSFVOSyA9IG5ldyBTdWJDaHVuaygpO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGNodW5rWCA9IDAsIGNodW5rWiA9IDAsIF9zdWJDaHVua3M6IE1hcDxudW1iZXIsIFN1YkNodW5rPiA9IG5ldyBNYXAoKSkge1xuICAgICAgICB0aGlzLnggPSBjaHVua1g7XG4gICAgICAgIHRoaXMueiA9IGNodW5rWjtcbiAgICAgICAgdGhpcy5oYXNDaGFuZ2VkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFgoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMueDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0WigpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy56O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRIYXNDaGFuZ2VkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNDaGFuZ2VkO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRIZWlnaHQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViQ2h1bmtzLnNpemU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaGlnaGVzdCBlbXB0eSBzdWIgY2h1bmsgKHNvIHdlIGRvbid0IHNlbmQgZW1wdHkgc3ViIGNodW5rcykuXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIGhpZ2hlc3QgZW1wdHkgc3ViIGNodW5rLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRUb3BFbXB0eSgpOiBudW1iZXIge1xuICAgICAgICBsZXQgdG9wRW1wdHkgPSBNQVhfU1VCQ0hVTktTIC0gMTtcbiAgICAgICAgd2hpbGUgKFxuICAgICAgICAgICAgKHRvcEVtcHR5ID49IDAgJiYgIXRoaXMuc3ViQ2h1bmtzLmhhcyh0b3BFbXB0eSkpIHx8XG4gICAgICAgICAgICAodGhpcy5zdWJDaHVua3MuaGFzKHRvcEVtcHR5KSAmJiB0aGlzLnN1YkNodW5rcy5nZXQodG9wRW1wdHkpIS5pc0VtcHR5KCkpXG4gICAgICAgICkge1xuICAgICAgICAgICAgdG9wRW1wdHktLTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKyt0b3BFbXB0eTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBDaHVuayBzbGljZSBhdCB0aGUgZ2l2ZW4gbGF5ZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkgLSBUaGUgbGF5ZXIgdG8gZ2V0LlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRTdWJDaHVuayh5OiBudW1iZXIpOiBTdWJDaHVuayB8IG51bGwge1xuICAgICAgICBpZiAoeSA8IDAgfHwgeSA+IE1BWF9TVUJDSFVOS1MpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBzdWJjaHVuayBoZWlnaHQ6ICR7eX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5zdWJDaHVua3MuZ2V0KHkpID8/IG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIGdldE9yQ3JlYXRlU3ViQ2h1bmsoeTogbnVtYmVyKTogU3ViQ2h1bmsge1xuICAgICAgICBjb25zdCBzdWJDaHVuayA9IG5ldyBTdWJDaHVuaygpO1xuICAgICAgICB0aGlzLnN1YkNodW5rcy5zZXQoeSwgc3ViQ2h1bmspO1xuICAgICAgICByZXR1cm4gc3ViQ2h1bms7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFN1YkNodW5rcygpOiBNYXA8bnVtYmVyLCBTdWJDaHVuaz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zdWJDaHVua3M7XG4gICAgfVxuXG4gICAgcHVibGljIGdldEhpZ2hlc3RCbG9ja0F0KF94OiBudW1iZXIsIF96OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gMTAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYmxvY2sgbGVnYWN5IGlkIChEQVRBKSBpbiB0aGUgY29ycmVzcG9uZGluZyBzdWIgY2h1bmsuXG4gICAgICogVXNlIHdvcmxkIHRvIGdldCB0aGUgYWN0dWFsIGJsb2NrIGluc3RhbmNlICh0aGlzIGlzIHRvIGtlZXAgY29kZSBjbGVhbikuXG4gICAgICogQHBhcmFtIHtWZWN0b3IzIHwgbnVtYmVyfSB4IC0gYmxvY2sgeC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3k9MF0gLSBibG9jayB5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbej0wXSAtIGJsb2NrIHouXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsYXllcj0wXSAtIGJsb2NrIHN0b3JhZ2UgbGF5ZXIgKDAgZm9yIGJsb2NrcywgMSBmb3IgbGlxdWlkcykuXG4gICAgICovXG4gICAgcHVibGljIGdldEJsb2NrKHg6IFZlY3RvcjMgfCBudW1iZXIsIHk6IG51bWJlciA9IDAsIHo6IG51bWJlciA9IDAsIGxheWVyID0gMCk6IExlZ2FjeUlkIHtcbiAgICAgICAgaWYgKHggaW5zdGFuY2VvZiBWZWN0b3IzKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRCbG9jayh4LmdldFgoKSwgeC5nZXRZKCksIHguZ2V0WigpLCBsYXllcik7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdWJDaHVuayA9IHRoaXMuZ2V0U3ViQ2h1bmsoTWF0aC5mbG9vcih5IC8gMTYpKTtcbiAgICAgICAgaWYgKCFzdWJDaHVuaykgcmV0dXJuIEJsb2NrTWFwcGluZ3MuZ2V0TGVnYWN5SWQoQmxvY2tNYXBwaW5ncy5nZXRSdW50aW1lSWQoJ21pbmVjcmFmdDphaXInKSk7XG4gICAgICAgIHJldHVybiBzdWJDaHVuay5nZXRCbG9jayh4LCB5ICYgMHhmLCB6LCBsYXllcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBhIGJsb2NrIGludG8gdGhlIGNodW5rIGJ5IGl0cyBydW50aW1lIElkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4IC0gYmxvY2sgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5IC0gYmxvY2sgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB6IC0gYmxvY2sgelxuICAgICAqIEBwYXJhbSB7QmxvY2t9IGJsb2NrIC0gYmxvY2sgdG8gc2V0XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsYXllcj0wXSAtIGJsb2NrIHN0b3JhZ2UgbGF5ZXIgKDAgZm9yIGJsb2NrcywgMSBmb3IgbGlxdWlkcylcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0QmxvY2soeDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlciwgYmxvY2s6IEJsb2NrLCBsYXllciA9IDApOiB2b2lkIHtcbiAgICAgICAgbGV0IHN1YkNodW5rID0gdGhpcy5nZXRTdWJDaHVuayhNYXRoLmZsb29yKHkgLyAxNikpO1xuICAgICAgICBpZiAoIXN1YkNodW5rKSBzdWJDaHVuayA9IHRoaXMuZ2V0T3JDcmVhdGVTdWJDaHVuayh5ID4+IDQpO1xuICAgICAgICBzdWJDaHVuay5zZXRCbG9jayh4LCB5ICYgMHhmLCB6LCBCbG9ja01hcHBpbmdzLmdldFJ1bnRpbWVJZChibG9jay5nZXROYW1lKCkpLCBsYXllcik7XG5cbiAgICAgICAgdGhpcy5oYXNDaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIZWxwZXIgbWV0aG9kIHVzZWQgdG8gaGFzaCBpbnRvIGEgc2luZ2xlIDY0IGJpdHMgaW50ZWdlclxuICAgICAqIGJvdGggQ2h1bmsgWCBhbmQgWiBjb29yZGluYXRlcy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2h1bmtYIC0gVGFyZ2V0IENodW5rIFggY29vcmRpbmF0ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2h1bmtaIC0gVGFyZ2V0IENodW5rIFogY29vcmRpbmF0ZS5cbiAgICAgKiBAcmV0dXJucyB7YmlnaW50fSBBIDY0IGJpdCBpbnRnZXIgY29udGFpbmluZyBhIGhhc2ggb2YgWCBhbmQgWi5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHBhY2tYWihjaHVua1g6IG51bWJlciwgY2h1bmtaOiBudW1iZXIpOiBiaWdpbnQge1xuICAgICAgICByZXR1cm4gKChCaWdJbnQoY2h1bmtYKSAmIDB4ZmZmZmZmZmZuKSA8PCAzMm4pIHwgKEJpZ0ludChjaHVua1opICYgMHhmZmZmZmZmZm4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhlbHBlciBtZXRob2QgdXNlZCB0byBkZWNvZGUgYSA2NCBiaXQgaGFzaCBjb250YWluaW5nXG4gICAgICogYm90aCBDaHVuayBYIGFuZCBaIGNvb3JkaW5hdGVzLlxuICAgICAqIEBwYXJhbSB7YmlnaW50fSBwYWNrZWQgLSBUYXJnZXQgQ2h1bmsgY29vcmRpbmF0ZSBoYXNoLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJbXX0gQW4gYXJyYXkgY29udGFpbmluZyBkZWNvZGVkIENodW5rIFggYW5kIFogY29vcmRpbmF0ZXMuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyB1bnBhY2tYWihwYWNrZWQ6IGJpZ2ludCk6IG51bWJlcltdIHtcbiAgICAgICAgcmV0dXJuIFtOdW1iZXIoQmlnSW50LmFzSW50TigzMiwgcGFja2VkID4+IDMybikpLCBOdW1iZXIoQmlnSW50LmFzSW50TigzMiwgcGFja2VkICYgMHhmZmZmZmZmZm4pKV07XG4gICAgfVxuXG4gICAgcHVibGljIG5ldHdvcmtTZXJpYWxpemUoKTogQnVmZmVyIHtcbiAgICAgICAgY29uc3Qgc3RyZWFtID0gbmV3IEJpbmFyeVN0cmVhbSgpO1xuXG4gICAgICAgIC8vIEZvciBzb21lIHJlYXNvbnMgd2UgbmVlZCB0aGlzIGhhY2sgc2luY2UgMS4xOCxcbiAgICAgICAgLy8gc2VlbXMgbGlrZSB0aGUgY2xpZW50IG5vdyBoYXMgc29tZSBuZWdhdGl2ZSBzcGFjZS5cbiAgICAgICAgLy8gVE9ETzogZmlndXJlIG91dCB3aGF0IGlzIHRoaXNcbiAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCA0OyArK3kpIHtcbiAgICAgICAgICAgIHN0cmVhbS53cml0ZUJ5dGUoOCk7IC8vIHN1YmNodW5rIHZlcnNpb24gOFxuICAgICAgICAgICAgc3RyZWFtLndyaXRlQnl0ZSgwKTsgLy8gMCBsYXllcnMgKGFsbCBhaXIpXG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHRoaXMuZ2V0VG9wRW1wdHkoKTsgKyt5KSB7XG4gICAgICAgICAgICAodGhpcy5zdWJDaHVua3MuZ2V0KHkpID8/IENodW5rLkVNUFRZX1NVQkNIVU5LKS5uZXR3b3JrU2VyaWFsaXplKHN0cmVhbSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUT0RPOiAzRCBiaW9tZXNcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyNDsgaSsrKSB7XG4gICAgICAgICAgICBzdHJlYW0ud3JpdGVCeXRlKDApOyAvLyBmYWtlIGJpb21lIHBhbGV0dGUsIG5vbiBwZXJzaXN0ZW50XG4gICAgICAgICAgICBzdHJlYW0ud3JpdGVVbnNpZ25lZFZhckludCgxIDw8IDEpOyAvLyBwbGFpbnNcbiAgICAgICAgfVxuXG4gICAgICAgIHN0cmVhbS53cml0ZUJ5dGUoMCk7IC8vIGJvcmRlciA/XG5cbiAgICAgICAgLy8gVE9ETzogdGlsZXNcbiAgICAgICAgcmV0dXJuIHN0cmVhbS5nZXRCdWZmZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXNlcmlhbGl6ZSBuZXR3b3JrIHN0cmVhbSBpbnRvIGNodW5rXG4gICAgICogdXNlZnVsIGZvciBjbGllbnQgYXBwbGljYXRpb25zIGFuZC9vciBvdXIgRmlsZXN5c3RlbSBpbXBsXG4gICAgICogQHBhcmFtIHtCaW5hcnlTdHJlYW19IHN0cmVhbSAtIHRoZSBuZXR3b3JrIHN0cmVhbVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbeF0gLSB0aGUgY2h1bmsgeCBjb29yZGluYXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFt6XSAtIHRoZSBjaHVuayB6IGNvb3JkaW5hdGVcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIG5ldHdvcmtEZXNlcmlhbGl6ZShzdHJlYW06IEJpbmFyeVN0cmVhbSwgeD86IG51bWJlciwgej86IG51bWJlcik6IENodW5rIHtcbiAgICAgICAgc3RyZWFtLnJlYWQoOCk7IC8vIHNraXAgZmFrZSBzdWJjaHVua3NcblxuICAgICAgICBjb25zdCBzdWJDaHVua3M6IE1hcDxudW1iZXIsIFN1YkNodW5rPiA9IG5ldyBNYXAoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNQVhfU1VCQ0hVTktTOyBpKyspIHtcbiAgICAgICAgICAgIHN1YkNodW5rcy5zZXQoaSwgU3ViQ2h1bmsubmV0d29ya0Rlc2VyaWFsaXplKHN0cmVhbSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2h1bmsgPSBuZXcgQ2h1bmsoeCwgeiwgc3ViQ2h1bmtzKTtcbiAgICAgICAgcmV0dXJuIGNodW5rO1xuICAgIH1cbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVFBLE1BQU0sYUFBZ0IsR0FBQSxFQUFBO0FBRXRCLE1BQXFCLEtBQU0sQ0FBQTtBQUFBLEVBQ2YsQ0FBQTtBQUFBLEVBQ0EsQ0FBQTtBQUFBLEVBQ0EsVUFBQTtBQUFBLEVBRUEsU0FBQSx1QkFBdUMsR0FBSSxFQUFBO0FBQUEsRUFDbkQsT0FBd0IsY0FBaUIsR0FBQSxJQUFJLFFBQVMsRUFBQTtBQUFBLEVBRS9DLFdBQUEsQ0FBWSxTQUFTLENBQUcsRUFBQSxNQUFBLEdBQVMsR0FBRyxVQUFvQyxtQkFBQSxJQUFJLEtBQU8sRUFBQTtBQUN0RixJQUFBLElBQUEsQ0FBSyxDQUFJLEdBQUEsTUFBQTtBQUNULElBQUEsSUFBQSxDQUFLLENBQUksR0FBQSxNQUFBO0FBQ1QsSUFBQSxJQUFBLENBQUssVUFBYSxHQUFBLEtBQUE7QUFBQTtBQUN0QixFQUVPLElBQWUsR0FBQTtBQUNsQixJQUFBLE9BQU8sSUFBSyxDQUFBLENBQUE7QUFBQTtBQUNoQixFQUVPLElBQWUsR0FBQTtBQUNsQixJQUFBLE9BQU8sSUFBSyxDQUFBLENBQUE7QUFBQTtBQUNoQixFQUVPLGFBQXlCLEdBQUE7QUFDNUIsSUFBQSxPQUFPLElBQUssQ0FBQSxVQUFBO0FBQUE7QUFDaEIsRUFFTyxTQUFvQixHQUFBO0FBQ3ZCLElBQUEsT0FBTyxLQUFLLFNBQVUsQ0FBQSxJQUFBO0FBQUE7QUFDMUI7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU1PLFdBQXNCLEdBQUE7QUFDekIsSUFBQSxJQUFJLFdBQVcsYUFBZ0IsR0FBQSxDQUFBO0FBQy9CLElBQUEsT0FDSyxZQUFZLENBQUssSUFBQSxDQUFDLEtBQUssU0FBVSxDQUFBLEdBQUEsQ0FBSSxRQUFRLENBQzdDLElBQUEsSUFBQSxDQUFLLFVBQVUsR0FBSSxDQUFBLFFBQVEsS0FBSyxJ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