@jsprismarine/prismarine
Version:
Dedicated Minecraft Bedrock Edition server written in TypeScript
289 lines (288 loc) • 27 kB
JavaScript
import { NetworkUtil } from "../network/NetworkUtil.es.js";
//#region src/entity/Metadata.ts
var MetadataFlag = /* @__PURE__ */ function(MetadataFlag) {
MetadataFlag[MetadataFlag["INDEX"] = 0] = "INDEX";
MetadataFlag[MetadataFlag["HEALTH"] = 1] = "HEALTH";
MetadataFlag[MetadataFlag["VARIANT"] = 2] = "VARIANT";
MetadataFlag[MetadataFlag["COLOR"] = 3] = "COLOR";
MetadataFlag[MetadataFlag["NAMETAG"] = 4] = "NAMETAG";
MetadataFlag[MetadataFlag["OWNER_ENTITY_ID"] = 5] = "OWNER_ENTITY_ID";
MetadataFlag[MetadataFlag["TARGET_ENTITY_ID"] = 6] = "TARGET_ENTITY_ID";
MetadataFlag[MetadataFlag["AIR"] = 7] = "AIR";
MetadataFlag[MetadataFlag["POTION_COLOR"] = 8] = "POTION_COLOR";
MetadataFlag[MetadataFlag["AMBIENT"] = 9] = "AMBIENT";
MetadataFlag[MetadataFlag["HURT_TIME"] = 10] = "HURT_TIME";
MetadataFlag[MetadataFlag["HURT_DIRECTION"] = 11] = "HURT_DIRECTION";
MetadataFlag[MetadataFlag["PADDLE_TIME_LEFT"] = 12] = "PADDLE_TIME_LEFT";
MetadataFlag[MetadataFlag["PADDLE_TIME_RIGHT"] = 13] = "PADDLE_TIME_RIGHT";
MetadataFlag[MetadataFlag["EXPERIENCE_VALUE"] = 14] = "EXPERIENCE_VALUE";
MetadataFlag[MetadataFlag["PLAYER_INDEX"] = 27] = "PLAYER_INDEX";
MetadataFlag[MetadataFlag["ENTITY_LEAD_HOLDER_ID"] = 37] = "ENTITY_LEAD_HOLDER_ID";
MetadataFlag[MetadataFlag["SCALE"] = 38] = "SCALE";
MetadataFlag[MetadataFlag["MAX_AIR"] = 42] = "MAX_AIR";
MetadataFlag[MetadataFlag["SPRINTING"] = 3] = "SPRINTING";
MetadataFlag[MetadataFlag["CAN_CLIMB"] = 19] = "CAN_CLIMB";
MetadataFlag[MetadataFlag["CAN_FLY"] = 21] = "CAN_FLY";
MetadataFlag[MetadataFlag["HAS_COLLISION"] = 48] = "HAS_COLLISION";
MetadataFlag[MetadataFlag["AFFECTED_BY_GRAVITY"] = 49] = "AFFECTED_BY_GRAVITY";
MetadataFlag[MetadataFlag["BOUNDINGBOX_WIDTH"] = 53] = "BOUNDINGBOX_WIDTH";
MetadataFlag[MetadataFlag["BOUNDINGBOX_HEIGHT"] = 54] = "BOUNDINGBOX_HEIGHT";
return MetadataFlag;
}({});
var FlagType = /* @__PURE__ */ function(FlagType) {
FlagType[FlagType["BYTE"] = 0] = "BYTE";
FlagType[FlagType["SHORT"] = 1] = "SHORT";
FlagType[FlagType["INT"] = 2] = "INT";
FlagType[FlagType["FLOAT"] = 3] = "FLOAT";
FlagType[FlagType["STRING"] = 4] = "STRING";
FlagType[FlagType["ITEM"] = 5] = "ITEM";
FlagType[FlagType["POSITION"] = 6] = "POSITION";
FlagType[FlagType["LONG"] = 7] = "LONG";
FlagType[FlagType["VECTOR"] = 8] = "VECTOR";
return FlagType;
}({});
var MetadataWriter = class {
metadata = /* @__PURE__ */ new Map();
getPropertyValue(key) {
return this.metadata.has(key) ? this.metadata.get(key)[1] : null;
}
setPropertyValue(key, type, value) {
this.metadata.set(key, [type, value]);
}
setLong(key, value) {
this.setPropertyValue(key, 7, value);
}
setShort(key, value) {
this.setPropertyValue(key, 1, value);
}
/**
* Set the property value as a string.
* @param {number} key - The property id.
* @param {string} value - The property value.
*/
setString(key, value) {
this.setPropertyValue(key, 4, value);
}
/**
* Get the property value as a string.
* @param {number} key - The property id.
* @returns {string} The property value.
*/
getString(key) {
return this.metadata.get(key);
}
/**
* Set the property value as a float.
* @param {number} key - The property id.
* @param {number} value - The property value.
*/
setFloat(key, value) {
this.setPropertyValue(key, 3, value);
}
/**
* Get the property value as a float.
* @param {number} key - The property id.
* @returns {number}
*/
getFloat(key) {
return this.metadata.get(key);
}
/**
* Set a flag value.
* @param {number} propertyId - The property id.
* @param {number} flagId - The flag id.
* @param {boolean} [value=true] - The flag value.
* @param {FlagType} [propertyType=FlagType.LONG] - The property type.
*/
setDataFlag(propertyId, flagId, value = true, propertyType = 7) {
const flagId64 = BigInt(flagId);
if (this.getDataFlag(propertyId, flagId64) !== value) {
const flags = this.getPropertyValue(propertyId);
this.setPropertyValue(propertyId, propertyType, flags ^ 1n << flagId64);
}
}
/**
* Get the property value as a boolean.
* @param {number} propertyId - The property id.
* @param {bigint} flagId - The flag id.
* @returns {boolean} The flag value.
*/
getDataFlag(propertyId, flagId) {
return (this.getPropertyValue(propertyId) & 1n << flagId) > 0;
}
/**
* @param {number} flagId - The flag id.
* @param {boolean} [value=true] - The flag value.
*/
setGenericFlag(flagId, value = true) {
this.setDataFlag(flagId >= 64 ? 94 : 0, flagId % 64, value, 7);
}
/**
* Get the property value as a boolean.
* @returns {typeof metadata} The metadata object.
*/
getData() {
return this.metadata;
}
networkSerialize(stream) {
stream.writeUnsignedVarInt(this.getData().size);
for (const [index, value] of this.getData()) {
stream.writeUnsignedVarInt(index);
stream.writeSignedByte(value[0]);
switch (value[0]) {
case 0:
stream.writeByte(Number(value[1]));
break;
case 3:
stream.writeFloatLE(value[1]);
break;
case 7:
stream.writeVarLong(value[1]);
break;
case 4:
NetworkUtil.writeString(stream, value[1]);
break;
case 1:
stream.writeUnsignedShortLE(value[1]);
break;
default: throw new Error(`Metadata type ${value[0]} not supported`);
}
}
}
};
/**
* Represents the metadata of an entity.
*/
var Metadata = class extends MetadataWriter {
/**
* Create a new metadata object.
* @param {boolean} [setDefaults=true]
* @returns {Metadata} the metadata object.
*/
constructor(setDefaults = true) {
super();
if (!setDefaults) return;
this.setDefaults();
}
/**
* Set the default metadata values.
* @remarks This method is called when the metadata object is created.
* @TODO: Add missing functions.
*/
setDefaults() {
this.setLong(0, 0n);
this.setShort(42, 300);
this.setLong(37, -1n);
this.setFloat(53, .6);
this.setFloat(54, 1.8);
this.setShort(7, 0);
this.setScale();
this.setAffectedByGravity();
this.setCollidable();
}
/**
* Set the entity's name tag.
* @param {string} name - The name tag.
* @example
* ```typescript
* entity.setNameTag('Steve');
* ```
*/
setNameTag(name) {
this.setString(4, name);
}
/**
* Get the entity's name tag.
* @returns {string} The entity's name tag.
*/
get nameTag() {
return this.getString(4);
}
/**
* Set the entity's scale.
* @param {number} [scale=1] - The entity's scale.
*/
setScale(scale = 1) {
this.setFloat(38, scale);
}
/**
* Get the entity's scale.
* @returns {number} The entity's scale.
*/
getScale() {
return this.getPropertyValue(38);
}
/**
* Set if the entity should be affected by gravity.
* @param {boolean} [affected=true] - if the entity should be affected by gravity.
*/
setAffectedByGravity(affected = true) {
this.setGenericFlag(49, affected);
}
/**
* Get if the entity is affected by gravity.
* @returns {boolean} if the entity is affected by gravity.
*/
get affectedByGravity() {
return this.getDataFlag(0, BigInt(49));
}
/**
* Set if the entity should be collidable.
* @param {boolean} [collidable=true] - if the entity should be collidable.
*/
setCollidable(collidable = true) {
this.setGenericFlag(48, collidable);
}
/**
* Get entity's collidable state.
* @returns {boolean} if the entity is collidable.
*/
get collidable() {
return this.getDataFlag(0, BigInt(48));
}
/**
* Set the entity's sprinting state.
* @param {boolean} [sprinting=true] - if the entity is sprinting.
*/
setSprinting(sprinting = true) {
this.setDataFlag(0, 3, sprinting, 0);
}
/**
* Get entity's sprinting state.
* @returns {boolean} if the entity is sprinting.
*/
get sprinting() {
return this.getDataFlag(0, BigInt(3));
}
/**
* Set the entity's can fly state.
* @param {boolean} [canFly=true] - if the entity can fly.
*/
setCanFly(canFly = true) {
this.setDataFlag(0, 21, canFly, 0);
}
/**
* Get entity's can fly state.
* @returns {boolean} if the entity can fly.
*/
get canFly() {
return this.getDataFlag(0, BigInt(21));
}
/**
* Set the entity's can climb state.
* @param {boolean} [canClimb=true] - if the entity can climb.
*/
setCanClimb(canClimb = true) {
this.setDataFlag(0, 19, canClimb, 0);
}
/**
* Get entity's can climb state.
* @returns {boolean} if the entity can climb.
*/
get canClimb() {
return this.getDataFlag(0, BigInt(19));
}
};
//#endregion
export { FlagType, Metadata, MetadataFlag, MetadataWriter };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWV0YWRhdGEuZXMuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VudGl0eS9NZXRhZGF0YS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSBCaW5hcnlTdHJlYW0gZnJvbSAnQGpzcHJpc21hcmluZS9qc2JpbmFyeXV0aWxzJztcbmltcG9ydCB7IE5ldHdvcmtVdGlsIH0gZnJvbSAnLi4vbmV0d29yay9OZXR3b3JrVXRpbCc7XG5cbi8vIFRPRE86IFN0aWxsIG1pc3NpbmcgZmxhZ3NcbmV4cG9ydCBlbnVtIE1ldGFkYXRhRmxhZyB7XG4gICAgSU5ERVgsXG4gICAgSEVBTFRILFxuICAgIFZBUklBTlQsXG4gICAgQ09MT1IsXG4gICAgTkFNRVRBRyxcbiAgICBPV05FUl9FTlRJVFlfSUQsXG4gICAgVEFSR0VUX0VOVElUWV9JRCxcbiAgICBBSVIsXG4gICAgUE9USU9OX0NPTE9SLFxuICAgIEFNQklFTlQsXG4gICAgSFVSVF9USU1FLFxuICAgIEhVUlRfRElSRUNUSU9OLFxuICAgIFBBRERMRV9USU1FX0xFRlQsXG4gICAgUEFERExFX1RJTUVfUklHSFQsXG4gICAgRVhQRVJJRU5DRV9WQUxVRSxcbiAgICBQTEFZRVJfSU5ERVggPSAyNyxcbiAgICBFTlRJVFlfTEVBRF9IT0xERVJfSUQgPSAzNyxcbiAgICBTQ0FMRSxcbiAgICBNQVhfQUlSID0gNDIsXG5cbiAgICAvLyBmbGFnc1xuICAgIFNQUklOVElORyA9IDMsXG4gICAgQ0FOX0NMSU1CID0gMTksXG4gICAgQ0FOX0ZMWSA9IDIxLFxuICAgIEhBU19DT0xMSVNJT04gPSA0OCxcbiAgICBBRkZFQ1RFRF9CWV9HUkFWSVRZID0gNDksXG4gICAgQk9VTkRJTkdCT1hfV0lEVEggPSA1MyxcbiAgICBCT1VORElOR0JPWF9IRUlHSFRcbn1cblxuZXhwb3J0IGVudW0gRmxhZ1R5cGUge1xuICAgIEJZVEUsXG4gICAgU0hPUlQsXG4gICAgSU5ULFxuICAgIEZMT0FULFxuICAgIFNUUklORyxcbiAgICBJVEVNLFxuICAgIFBPU0lUSU9OLFxuICAgIExPTkcsXG4gICAgVkVDVE9SXG59XG5cbmV4cG9ydCB0eXBlIE1ldGFkYXRhQ29udGFpbmVyID0gTWFwPG51bWJlciwgW251bWJlciwgYmlnaW50IHwgbnVtYmVyIHwgYm9vbGVhbiB8IHN0cmluZ10+O1xuZXhwb3J0IGNsYXNzIE1ldGFkYXRhV3JpdGVyIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1ldGFkYXRhOiBNZXRhZGF0YUNvbnRhaW5lciA9IG5ldyBNYXAoKTtcblxuICAgIHB1YmxpYyBnZXRQcm9wZXJ0eVZhbHVlKGtleTogbnVtYmVyKTogYmlnaW50IHwgbnVtYmVyIHwgYm9vbGVhbiB8IHN0cmluZyB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YS5oYXMoa2V5KSA/IHRoaXMubWV0YWRhdGEuZ2V0KGtleSkhWzFdIDogbnVsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0UHJvcGVydHlWYWx1ZShrZXk6IG51bWJlciwgdHlwZTogbnVtYmVyLCB2YWx1ZTogYmlnaW50IHwgbnVtYmVyIHwgYm9vbGVhbiB8IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aGlzLm1ldGFkYXRhLnNldChrZXksIFt0eXBlLCB2YWx1ZV0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRMb25nKGtleTogbnVtYmVyLCB2YWx1ZTogYmlnaW50KTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0UHJvcGVydHlWYWx1ZShrZXksIEZsYWdUeXBlLkxPTkcsIHZhbHVlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0U2hvcnQoa2V5OiBudW1iZXIsIHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRQcm9wZXJ0eVZhbHVlKGtleSwgRmxhZ1R5cGUuU0hPUlQsIHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHByb3BlcnR5IHZhbHVlIGFzIGEgc3RyaW5nLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBrZXkgLSBUaGUgcHJvcGVydHkgaWQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVGhlIHByb3BlcnR5IHZhbHVlLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXRTdHJpbmcoa2V5OiBudW1iZXIsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRQcm9wZXJ0eVZhbHVlKGtleSwgRmxhZ1R5cGUuU1RSSU5HLCB2YWx1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcHJvcGVydHkgdmFsdWUgYXMgYSBzdHJpbmcuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGtleSAtIFRoZSBwcm9wZXJ0eSBpZC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgcHJvcGVydHkgdmFsdWUuXG4gICAgICovXG4gICAgcHVibGljIGdldFN0cmluZyhrZXk6IG51bWJlcik6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhLmdldChrZXkpISBhcyBhbnk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBwcm9wZXJ0eSB2YWx1ZSBhcyBhIGZsb2F0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBrZXkgLSBUaGUgcHJvcGVydHkgaWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gVGhlIHByb3BlcnR5IHZhbHVlLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXRGbG9hdChrZXk6IG51bWJlciwgdmFsdWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnNldFByb3BlcnR5VmFsdWUoa2V5LCBGbGFnVHlwZS5GTE9BVCwgdmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHByb3BlcnR5IHZhbHVlIGFzIGEgZmxvYXQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGtleSAtIFRoZSBwcm9wZXJ0eSBpZC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRGbG9hdChrZXk6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhLmdldChrZXkpISBhcyBhbnk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGEgZmxhZyB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcHJvcGVydHlJZCAtIFRoZSBwcm9wZXJ0eSBpZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZmxhZ0lkIC0gVGhlIGZsYWcgaWQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbdmFsdWU9dHJ1ZV0gLSBUaGUgZmxhZyB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge0ZsYWdUeXBlfSBbcHJvcGVydHlUeXBlPUZsYWdUeXBlLkxPTkddIC0gVGhlIHByb3BlcnR5IHR5cGUuXG4gICAgICovXG4gICAgcHVibGljIHNldERhdGFGbGFnKHByb3BlcnR5SWQ6IG51bWJlciwgZmxhZ0lkOiBudW1iZXIsIHZhbHVlID0gdHJ1ZSwgcHJvcGVydHlUeXBlID0gRmxhZ1R5cGUuTE9ORyk6IHZvaWQge1xuICAgICAgICAvLyBBbGwgZ2VuZXJpYyBmbGFncyBhcmUgd3JpdHRlbiBhcyBMb25ncyAoYmlnaW50cykgNjRiaXRcbiAgICAgICAgY29uc3QgZmxhZ0lkNjQgPSBCaWdJbnQoZmxhZ0lkKTtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHNhbWUgdmFsdWUgaXMgYWxyZWFkeSBzZXRcbiAgICAgICAgaWYgKHRoaXMuZ2V0RGF0YUZsYWcocHJvcGVydHlJZCwgZmxhZ0lkNjQpICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3QgZmxhZ3MgPSB0aGlzLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHlJZCkgYXMgYmlnaW50O1xuICAgICAgICAgICAgdGhpcy5zZXRQcm9wZXJ0eVZhbHVlKHByb3BlcnR5SWQsIHByb3BlcnR5VHlwZSwgZmxhZ3MgXiAoMW4gPDwgZmxhZ0lkNjQpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHByb3BlcnR5IHZhbHVlIGFzIGEgYm9vbGVhbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcHJvcGVydHlJZCAtIFRoZSBwcm9wZXJ0eSBpZC5cbiAgICAgKiBAcGFyYW0ge2JpZ2ludH0gZmxhZ0lkIC0gVGhlIGZsYWcgaWQuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRoZSBmbGFnIHZhbHVlLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXREYXRhRmxhZyhwcm9wZXJ0eUlkOiBudW1iZXIsIGZsYWdJZDogYmlnaW50KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoKHRoaXMuZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eUlkKSBhcyBiaWdpbnQpICYgKDFuIDw8IGZsYWdJZCkpID4gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZmxhZ0lkIC0gVGhlIGZsYWcgaWQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbdmFsdWU9dHJ1ZV0gLSBUaGUgZmxhZyB2YWx1ZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0R2VuZXJpY0ZsYWcoZmxhZ0lkOiBudW1iZXIsIHZhbHVlID0gdHJ1ZSk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldERhdGFGbGFnKGZsYWdJZCA+PSA2NCA/IDk0IDogTWV0YWRhdGFGbGFnLklOREVYLCBmbGFnSWQgJSA2NCwgdmFsdWUsIEZsYWdUeXBlLkxPTkcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcHJvcGVydHkgdmFsdWUgYXMgYSBib29sZWFuLlxuICAgICAqIEByZXR1cm5zIHt0eXBlb2YgbWV0YWRhdGF9IFRoZSBtZXRhZGF0YSBvYmplY3QuXG4gICAgICovXG4gICAgcHVibGljIGdldERhdGEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZXR3b3JrU2VyaWFsaXplKHN0cmVhbTogQmluYXJ5U3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS53cml0ZVVuc2lnbmVkVmFySW50KHRoaXMuZ2V0RGF0YSgpLnNpemUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtpbmRleCwgdmFsdWVdIG9mIHRoaXMuZ2V0RGF0YSgpIGFzIGFueSkge1xuICAgICAgICAgICAgc3RyZWFtLndyaXRlVW5zaWduZWRWYXJJbnQoaW5kZXgpO1xuICAgICAgICAgICAgc3RyZWFtLndyaXRlU2lnbmVkQnl0ZSh2YWx1ZVswXSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHZhbHVlWzBdKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBGbGFnVHlwZS5CWVRFOlxuICAgICAgICAgICAgICAgICAgICBzdHJlYW0ud3JpdGVCeXRlKE51bWJlcih2YWx1ZVsxXSkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIEZsYWdUeXBlLkZMT0FUOlxuICAgICAgICAgICAgICAgICAgICBzdHJlYW0ud3JpdGVGbG9hdExFKHZhbHVlWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBGbGFnVHlwZS5MT05HOlxuICAgICAgICAgICAgICAgICAgICBzdHJlYW0ud3JpdGVWYXJMb25nKHZhbHVlWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBGbGFnVHlwZS5TVFJJTkc6XG4gICAgICAgICAgICAgICAgICAgIE5ldHdvcmtVdGlsLndyaXRlU3RyaW5nKHN0cmVhbSwgdmFsdWVbMV0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIEZsYWdUeXBlLlNIT1JUOlxuICAgICAgICAgICAgICAgICAgICBzdHJlYW0ud3JpdGVVbnNpZ25lZFNob3J0TEUodmFsdWVbMV0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1ldGFkYXRhIHR5cGUgJHt2YWx1ZVswXX0gbm90IHN1cHBvcnRlZGApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIG1ldGFkYXRhIG9mIGFuIGVudGl0eS5cbiAqL1xuZXhwb3J0IGNsYXNzIE1ldGFkYXRhIGV4dGVuZHMgTWV0YWRhdGFXcml0ZXIge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBtZXRhZGF0YSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbc2V0RGVmYXVsdHM9dHJ1ZV1cbiAgICAgKiBAcmV0dXJucyB7TWV0YWRhdGF9IHRoZSBtZXRhZGF0YSBvYmplY3QuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2V0RGVmYXVsdHMgPSB0cnVlKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgaWYgKCFzZXREZWZhdWx0cykgcmV0dXJuO1xuICAgICAgICB0aGlzLnNldERlZmF1bHRzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBkZWZhdWx0IG1ldGFkYXRhIHZhbHVlcy5cbiAgICAgKiBAcmVtYXJrcyBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0aGUgbWV0YWRhdGEgb2JqZWN0IGlzIGNyZWF0ZWQuXG4gICAgICogQFRPRE86IEFkZCBtaXNzaW5nIGZ1bmN0aW9ucy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgc2V0RGVmYXVsdHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0TG9uZyhNZXRhZGF0YUZsYWcuSU5ERVgsIDBuKTtcblxuICAgICAgICB0aGlzLnNldFNob3J0KE1ldGFkYXRhRmxhZy5NQVhfQUlSLCAzMDApO1xuICAgICAgICB0aGlzLnNldExvbmcoTWV0YWRhdGFGbGFnLkVOVElUWV9MRUFEX0hPTERFUl9JRCwgLTFuKTtcbiAgICAgICAgdGhpcy5zZXRGbG9hdChNZXRhZGF0YUZsYWcuQk9VTkRJTkdCT1hfV0lEVEgsIDAuNik7XG4gICAgICAgIHRoaXMuc2V0RmxvYXQoTWV0YWRhdGFGbGFnLkJPVU5ESU5HQk9YX0hFSUdIVCwgMS44KTtcbiAgICAgICAgdGhpcy5zZXRTaG9ydChNZXRhZGF0YUZsYWcuQUlSLCAwKTtcblxuICAgICAgICB0aGlzLnNldFNjYWxlKCk7XG4gICAgICAgIHRoaXMuc2V0QWZmZWN0ZWRCeUdyYXZpdHkoKTtcbiAgICAgICAgdGhpcy5zZXRDb2xsaWRhYmxlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBlbnRpdHkncyBuYW1lIHRhZy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIHRhZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBlbnRpdHkuc2V0TmFtZVRhZygnU3RldmUnKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0TmFtZVRhZyhuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRTdHJpbmcoTWV0YWRhdGFGbGFnLk5BTUVUQUcsIG5hbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGVudGl0eSdzIG5hbWUgdGFnLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBlbnRpdHkncyBuYW1lIHRhZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IG5hbWVUYWcoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RyaW5nKE1ldGFkYXRhRmxhZy5OQU1FVEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGVudGl0eSdzIHNjYWxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc2NhbGU9MV0gLSBUaGUgZW50aXR5J3Mgc2NhbGUuXG4gICAgICovXG4gICAgcHVibGljIHNldFNjYWxlKHNjYWxlOiBudW1iZXIgPSAxKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0RmxvYXQoTWV0YWRhdGFGbGFnLlNDQUxFLCBzY2FsZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZW50aXR5J3Mgc2NhbGUuXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIGVudGl0eSdzIHNjYWxlLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRTY2FsZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRQcm9wZXJ0eVZhbHVlKE1ldGFkYXRhRmxhZy5TQ0FMRSkgYXMgbnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBpZiB0aGUgZW50aXR5IHNob3VsZCBiZSBhZmZlY3RlZCBieSBncmF2aXR5LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FmZmVjdGVkPXRydWVdIC0gaWYgdGhlIGVudGl0eSBzaG91bGQgYmUgYWZmZWN0ZWQgYnkgZ3Jhdml0eS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0QWZmZWN0ZWRCeUdyYXZpdHkoYWZmZWN0ZWQ6IGJvb2xlYW4gPSB0cnVlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0R2VuZXJpY0ZsYWcoTWV0YWRhdGFGbGFnLkFGRkVDVEVEX0JZX0dSQVZJVFksIGFmZmVjdGVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGlmIHRoZSBlbnRpdHkgaXMgYWZmZWN0ZWQgYnkgZ3Jhdml0eS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gaWYgdGhlIGVudGl0eSBpcyBhZmZlY3RlZCBieSBncmF2aXR5LlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgYWZmZWN0ZWRCeUdyYXZpdHkoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldERhdGFGbGFnKE1ldGFkYXRhRmxhZy5JTkRFWCwgQmlnSW50KE1ldGFkYXRhRmxhZy5BRkZFQ1RFRF9CWV9HUkFWSVRZKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IGlmIHRoZSBlbnRpdHkgc2hvdWxkIGJlIGNvbGxpZGFibGUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbY29sbGlkYWJsZT10cnVlXSAtIGlmIHRoZSBlbnRpdHkgc2hvdWxkIGJlIGNvbGxpZGFibGUuXG4gICAgICovXG4gICAgcHVibGljIHNldENvbGxpZGFibGUoY29sbGlkYWJsZTogYm9vbGVhbiA9IHRydWUpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRHZW5lcmljRmxhZyhNZXRhZGF0YUZsYWcuSEFTX0NPTExJU0lPTiwgY29sbGlkYWJsZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBlbnRpdHkncyBjb2xsaWRhYmxlIHN0YXRlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBpZiB0aGUgZW50aXR5IGlzIGNvbGxpZGFibGUuXG4gICAgICovXG4gICAgcHVibGljIGdldCBjb2xsaWRhYmxlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXREYXRhRmxhZyhNZXRhZGF0YUZsYWcuSU5ERVgsIEJpZ0ludChNZXRhZGF0YUZsYWcuSEFTX0NPTExJU0lPTikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgZW50aXR5J3Mgc3ByaW50aW5nIHN0YXRlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3NwcmludGluZz10cnVlXSAtIGlmIHRoZSBlbnRpdHkgaXMgc3ByaW50aW5nLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXRTcHJpbnRpbmcoc3ByaW50aW5nOiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldERhdGFGbGFnKE1ldGFkYXRhRmxhZy5JTkRFWCwgTWV0YWRhdGFGbGFnLlNQUklOVElORywgc3ByaW50aW5nLCBGbGFnVHlwZS5CWVRFKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGVudGl0eSdzIHNwcmludGluZyBzdGF0ZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gaWYgdGhlIGVudGl0eSBpcyBzcHJpbnRpbmcuXG4gICAgICovXG4gICAgcHVibGljIGdldCBzcHJpbnRpbmcoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldERhdGFGbGFnKE1ldGFkYXRhRmxhZy5JTkRFWCwgQmlnSW50KE1ldGFkYXRhRmxhZy5TUFJJTlRJTkcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGVudGl0eSdzIGNhbiBmbHkgc3RhdGUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbY2FuRmx5PXRydWVdIC0gaWYgdGhlIGVudGl0eSBjYW4gZmx5LlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXRDYW5GbHkoY2FuRmx5OiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldERhdGFGbGFnKE1ldGFkYXRhRmxhZy5JTkRFWCwgTWV0YWRhdGFGbGFnLkNBTl9GTFksIGNhbkZseSwgRmxhZ1R5cGUuQllURSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBlbnRpdHkncyBjYW4gZmx5IHN0YXRlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBpZiB0aGUgZW50aXR5IGNhbiBmbHkuXG4gICAgICovXG4gICAgcHVibGljIGdldCBjYW5GbHkoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldERhdGFGbGFnKE1ldGFkYXRhRmxhZy5JTkRFWCwgQmlnSW50KE1ldGFkYXRhRmxhZy5DQU5fRkxZKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBlbnRpdHkncyBjYW4gY2xpbWIgc3RhdGUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbY2FuQ2xpbWI9dHJ1ZV0gLSBpZiB0aGUgZW50aXR5IGNhbiBjbGltYi5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0Q2FuQ2xpbWIoY2FuQ2xpbWI6IGJvb2xlYW4gPSB0cnVlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0RGF0YUZsYWcoTWV0YWRhdGFGbGFnLklOREVYLCBNZXRhZGF0YUZsYWcuQ0FOX0NMSU1CLCBjYW5DbGltYiwgRmxhZ1R5cGUuQllURSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBlbnRpdHkncyBjYW4gY2xpbWIgc3RhdGUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IGlmIHRoZSBlbnRpdHkgY2FuIGNsaW1iLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgY2FuQ2xpbWIoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldERhdGFGbGFnKE1ldGFkYXRhRmxhZy5JTkRFWCwgQmlnSW50KE1ldGFkYXRhRmxhZy5DQU5fQ0xJTUIpKTtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBSUEsSUFBWSxlQUFMLHlCQUFBLGNBQUE7Q0FDSCxhQUFBLGFBQUEsV0FBQSxLQUFBO0NBQ0EsYUFBQSxhQUFBLFlBQUEsS0FBQTtDQUNBLGFBQUEsYUFBQSxhQUFBLEtBQUE7Q0FDQSxhQUFBLGFBQUEsV0FBQSxLQUFBO0NBQ0EsYUFBQSxhQUFBLGFBQUEsS0FBQTtDQUNBLGFBQUEsYUFBQSxxQkFBQSxLQUFBO0NBQ0EsYUFBQSxhQUFBLHNCQUFBLEtBQUE7Q0FDQSxhQUFBLGFBQUEsU0FBQSxLQUFBO0NBQ0EsYUFBQSxhQUFBLGtCQUFBLEtBQUE7Q0FDQSxhQUFBLGFBQUEsYUFBQSxLQUFBO0NBQ0EsYUFBQSxhQUFBLGVBQUEsTUFBQTtDQUNBLGFBQUEsYUFBQSxvQkFBQSxNQUFBO0NBQ0EsYUFBQSxhQUFBLHNCQUFBLE1BQUE7Q0FDQSxhQUFBLGFBQUEsdUJBQUEsTUFBQTtDQUNBLGFBQUEsYUFBQSxzQkFBQSxNQUFBO0NBQ0EsYUFBQSxhQUFBLGtCQUFBLE1BQUE7Q0FDQSxhQUFBLGFBQUEsMkJBQUEsTUFBQTtDQUNBLGFBQUEsYUFBQSxXQUFBLE1BQUE7Q0FDQSxhQUFBLGFBQUEsYUFBQSxNQUFBO0NBR0EsYUFBQSxhQUFBLGVBQUEsS0FBQTtDQUNBLGFBQUEsYUFBQSxlQUFBLE1BQUE7Q0FDQSxhQUFBLGFBQUEsYUFBQSxNQUFBO0NBQ0EsYUFBQSxhQUFBLG1CQUFBLE1BQUE7Q0FDQSxhQUFBLGFB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