var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};

// data/system_template_esbuild/subscripts/drone_camera.ts
import { EntityComponentTypes, system as system8 } from "@minecraft/server";

// ../../node_modules/@bedrock-oss/bedrock-boost/dist/index.mjs
import { Direction } from "@minecraft/server";
import { system, world } from "@minecraft/server";
import { system as system2 } from "@minecraft/server";
import { BlockPermutation, world as world2 } from "@minecraft/server";
import { world as world3 } from "@minecraft/server";
import { Player } from "@minecraft/server";
import { system as system3 } from "@minecraft/server";
import { system as system4 } from "@minecraft/server";
import {
  system as system5,
  world as world4
} from "@minecraft/server";
import { Player as Player2, system as system6, world as world5 } from "@minecraft/server";
import {
  InputPermissionCategory
} from "@minecraft/server";
import { system as system7 } from "@minecraft/server";
import { Direction as Direction2 } from "@minecraft/server";
import { StructureSaveMode, world as world6 } from "@minecraft/server";
import { EntityEquippableComponent, EquipmentSlot, ItemDurabilityComponent, ItemEnchantableComponent } from "@minecraft/server";
var _a;
var ChatColor = (_a = class {
  /**
   * Class ChatColor Constructor.
   * @param code - The color code as a string.
   * @param color - The color code as a hexadecimal number. Can be undefined.
   */
  constructor(code, color) {
    __publicField(this, "r");
    __publicField(this, "g");
    __publicField(this, "b");
    this.code = code;
    this.color = color;
    if (color) {
      this.r = color >> 16 & 255;
      this.g = color >> 8 & 255;
      this.b = color & 255;
    }
  }
  /**
   * Returns the string representation of the ChatColor instance,
   * which includes the PREFIX followed by the color code.
   * @returns A string representing the ChatColor instance
   */
  toString() {
    return _a.PREFIX + this.code;
  }
  /**
   * Returns the color code of the ChatColor instance.
   * @returns The color code of this ChatColor instance.
   */
  toRGB() {
    return this.color;
  }
  /**
   * Returns the hexadecimal string representation of the color code
   * @returns {string | undefined} The hexadecimal representation of the color.
   */
  toHex() {
    return this.color?.toString(16);
  }
  /**
   * Retrieve the value of the red component.
   *
   * @returns {number | undefined} The value of the red component, or undefined if it is not set.
   */
  getRed() {
    return this.r;
  }
  /**
   * Retrieves the green value of the current color.
   *
   * @returns {number | undefined} The green value of the color, or undefined if it is not set.
   */
  getGreen() {
    return this.g;
  }
  /**
   * Retrieves the blue value of a color.
   *
   * @returns The blue value of the color.
   * @type {number | undefined}
   */
  getBlue() {
    return this.b;
  }
  /**
   * Retrieves the format code associated with the chat color.
   *
   * @returns {string} The format code of the chat color.
   */
  getCode() {
    return this.code;
  }
  /**
   * Removes color codes from the specified string
   * @param str - The string from which color codes will be removed.
   * @returns The string cleared from color codes.
   */
  static stripColor(str) {
    return str.replace(/§[0-9a-u]/g, "");
  }
  /**
   * Finds the closest ChatColor code for the given RGB values
   * @param r - Red part of the color.
   * @param g - Green part of the color.
   * @param b - Blue part of the color.
   * @returns The closest ChatColor for the given RGB values.
   */
  static findClosestColor(r, g, b) {
    let minDistance = Number.MAX_VALUE;
    let closestColor = _a.WHITE;
    for (const color of _a.ALL_COLORS) {
      if (color.r && color.g && color.b) {
        const distance = Math.sqrt(Math.pow(color.r - r, 2) + Math.pow(color.g - g, 2) + Math.pow(color.b - b, 2));
        if (distance < minDistance) {
          minDistance = distance;
          closestColor = color;
        }
      }
    }
    return closestColor;
  }
}, /**
 * Black color code. (0)
 */
__publicField(_a, "BLACK", new _a("0", 0)), /**
 * Dark blue color code. (1)
 */
__publicField(_a, "DARK_BLUE", new _a("1", 170)), /**
 * Dark green color code. (2)
 */
__publicField(_a, "DARK_GREEN", new _a("2", 43520)), /**
 * Dark aqua color code. (3)
 */
__publicField(_a, "DARK_AQUA", new _a("3", 43690)), /**
 * Dark red color code. (4)
 */
__publicField(_a, "DARK_RED", new _a("4", 11141120)), /**
 * Dark purple color code. (5)
 */
__publicField(_a, "DARK_PURPLE", new _a("5", 11141290)), /**
 * Gold color code. (6)
 */
__publicField(_a, "GOLD", new _a("6", 16755200)), /**
 * Gray color code. (7)
 */
__publicField(_a, "GRAY", new _a("7", 11184810)), /**
 * Dark gray color code. (8)
 */
__publicField(_a, "DARK_GRAY", new _a("8", 5592405)), /**
 * Blue color code. (9)
 */
__publicField(_a, "BLUE", new _a("9", 5592575)), /**
 * Green color code. (a)
 */
__publicField(_a, "GREEN", new _a("a", 5635925)), /**
 * Aqua color code. (b)
 */
__publicField(_a, "AQUA", new _a("b", 5636095)), /**
 * Red color code. (c)
 */
__publicField(_a, "RED", new _a("c", 16733525)), /**
 * Light purple color code. (d)
 */
__publicField(_a, "LIGHT_PURPLE", new _a("d", 16733695)), /**
 * Yellow color code. (e)
 */
__publicField(_a, "YELLOW", new _a("e", 16777045)), /**
 * White color code. (f)
 */
__publicField(_a, "WHITE", new _a("f", 16777215)), /**
 * MineCoin gold color code. (g)
 */
__publicField(_a, "MINECOIN_GOLD", new _a("g", 14603781)), /**
 * Material quartz color code. (h)
 */
__publicField(_a, "MATERIAL_QUARTZ", new _a("h", 14931153)), /**
 * Material iron color code. (i)
 */
__publicField(_a, "MATERIAL_IRON", new _a("i", 13552330)), /**
 * Material netherite color code. (j)
 */
__publicField(_a, "MATERIAL_NETHERITE", new _a("j", 4471355)), /**
 * Material redstone color code. (m)
 */
__publicField(_a, "MATERIAL_REDSTONE", new _a("m", 9901575)), /**
 * Material copper color code. (n)
 */
__publicField(_a, "MATERIAL_COPPER", new _a("n", 11823181)), /**
 * Material gold color code. (p)
 */
__publicField(_a, "MATERIAL_GOLD", new _a("p", 14594349)), /**
 * Material emerald color code. (q)
 */
__publicField(_a, "MATERIAL_EMERALD", new _a("q", 1155126)), /**
 * Material diamond color code. (s)
 */
__publicField(_a, "MATERIAL_DIAMOND", new _a("s", 2931368)), /**
 * Material lapis color code. (t)
 */
__publicField(_a, "MATERIAL_LAPIS", new _a("t", 2181499)), /**
 * Material amethyst color code. (u)
 */
__publicField(_a, "MATERIAL_AMETHYST", new _a("u", 10116294)), /**
 * Obfuscated color code. (k)
 */
__publicField(_a, "OBFUSCATED", new _a("k")), /**
 * Bold color code. (l)
 */
__publicField(_a, "BOLD", new _a("l")), /**
 * Italic color code. (o)
 */
__publicField(_a, "ITALIC", new _a("o")), /**
 * Reset color code. (r)
 */
__publicField(_a, "RESET", new _a("r")), /**
 * All available color codes.
 */
__publicField(_a, "VALUES", [
  _a.BLACK,
  _a.DARK_BLUE,
  _a.DARK_GREEN,
  _a.DARK_AQUA,
  _a.DARK_RED,
  _a.DARK_PURPLE,
  _a.GOLD,
  _a.GRAY,
  _a.DARK_GRAY,
  _a.BLUE,
  _a.GREEN,
  _a.AQUA,
  _a.RED,
  _a.LIGHT_PURPLE,
  _a.YELLOW,
  _a.WHITE,
  _a.MINECOIN_GOLD,
  _a.MATERIAL_QUARTZ,
  _a.MATERIAL_IRON,
  _a.MATERIAL_NETHERITE,
  _a.MATERIAL_REDSTONE,
  _a.MATERIAL_COPPER,
  _a.MATERIAL_GOLD,
  _a.MATERIAL_EMERALD,
  _a.MATERIAL_DIAMOND,
  _a.MATERIAL_LAPIS,
  _a.MATERIAL_AMETHYST,
  _a.OBFUSCATED,
  _a.BOLD,
  _a.ITALIC,
  _a.RESET
]), /**
 * All available color codes excluding the formatting codes.
 */
__publicField(_a, "ALL_COLORS", [
  _a.BLACK,
  _a.DARK_BLUE,
  _a.DARK_GREEN,
  _a.DARK_AQUA,
  _a.DARK_RED,
  _a.DARK_PURPLE,
  _a.GOLD,
  _a.GRAY,
  _a.DARK_GRAY,
  _a.BLUE,
  _a.GREEN,
  _a.AQUA,
  _a.RED,
  _a.LIGHT_PURPLE,
  _a.YELLOW,
  _a.WHITE,
  _a.MINECOIN_GOLD,
  _a.MATERIAL_QUARTZ,
  _a.MATERIAL_IRON,
  _a.MATERIAL_NETHERITE,
  _a.MATERIAL_REDSTONE,
  _a.MATERIAL_COPPER,
  _a.MATERIAL_GOLD,
  _a.MATERIAL_EMERALD,
  _a.MATERIAL_DIAMOND,
  _a.MATERIAL_LAPIS,
  _a.MATERIAL_AMETHYST
]), /**
 * PREFIX is the section sign (§) used in Minecraft color codes.
 */
__publicField(_a, "PREFIX", "\xA7"), _a);
var _a2;
var ColorJSON = (_a2 = class {
  constructor() {
    // Tokens
    __publicField(this, "OpenObject", "{");
    __publicField(this, "CloseObject", "}");
    __publicField(this, "OpenArray", "[");
    __publicField(this, "CloseArray", "]");
    __publicField(this, "Comma", ",");
    __publicField(this, "KeyValueSeparator", ":");
    __publicField(this, "StringDelimiter", '"');
    __publicField(this, "KeyDelimiter", "");
    __publicField(this, "Indent", "  ");
    __publicField(this, "NewLine", "\n");
    __publicField(this, "Space", " ");
    // Threshold for inline representation
    __publicField(this, "InlineThreshold", 60);
    // Maximum depth to which objects will be traversed
    __publicField(this, "MaxDepth", 1);
    // Whether to include class names
    __publicField(this, "IncludeClassNames", true);
    // Values
    __publicField(this, "FunctionValue", "\u0192");
    __publicField(this, "NullValue", "null");
    __publicField(this, "UndefinedValue", "undefined");
    __publicField(this, "TrueValue", "true");
    __publicField(this, "FalseValue", "false");
    __publicField(this, "CycleValue", "[...cycle...]");
    __publicField(this, "TruncatedObjectValue", "{...}");
    // Colors
    __publicField(this, "OpenCloseObjectColor", ChatColor.YELLOW);
    __publicField(this, "OpenCloseArrayColor", ChatColor.AQUA);
    __publicField(this, "NumberColor", ChatColor.DARK_AQUA);
    __publicField(this, "StringColor", ChatColor.DARK_GREEN);
    __publicField(this, "BooleanColor", ChatColor.GOLD);
    __publicField(this, "NullColor", ChatColor.GOLD);
    __publicField(this, "KeyColor", ChatColor.GRAY);
    __publicField(this, "EscapeColor", ChatColor.GOLD);
    __publicField(this, "FunctionColor", ChatColor.GRAY);
    __publicField(this, "ClassColor", ChatColor.GRAY);
    __publicField(this, "ClassStyle", ChatColor.BOLD);
    __publicField(this, "CycleColor", ChatColor.DARK_RED);
  }
  static createPlain() {
    const plain = new _a2();
    plain.OpenCloseObjectColor = "";
    plain.OpenCloseArrayColor = "";
    plain.NumberColor = "";
    plain.StringColor = "";
    plain.BooleanColor = "";
    plain.NullColor = "";
    plain.KeyColor = "";
    plain.EscapeColor = "";
    plain.FunctionColor = "";
    plain.ClassColor = "";
    plain.ClassStyle = "";
    plain.CycleColor = "";
    return plain;
  }
  /**
   * Transforms a value into a chat-friendly, colored JSON representation.
   * @param value - The value to transform.
   */
  stringify(value) {
    return this.stringifyValue(value, {
      indentLevel: 0,
      visited: /* @__PURE__ */ new WeakSet()
    });
  }
  /**
   * Transforms a string into a JSON representation.
   * @param value - The string to transform.
   */
  stringifyString(value) {
    return this.StringColor + this.StringDelimiter + this.escapeString(value) + this.StringDelimiter + ChatColor.RESET;
  }
  /**
   * Transforms a number into a JSON representation.
   * @param value - The number to transform.
   */
  stringifyNumber(value) {
    return this.NumberColor + value.toString() + ChatColor.RESET;
  }
  /**
   * Transforms a boolean into a JSON representation.
   * @param value - The boolean to transform.
   */
  stringifyBoolean(value) {
    return this.BooleanColor + (value ? this.TrueValue : this.FalseValue) + ChatColor.RESET;
  }
  /**
   * Transforms a function into a JSON representation.
   * @param value - The function to transform.
   */
  // eslint-disable-next-line @typescript-eslint/ban-types
  stringifyFunction(value) {
    return this.FunctionColor + this.FunctionValue + ChatColor.RESET;
  }
  /**
   * Returns a null JSON representation.
   */
  stringifyNull() {
    return this.NullColor + this.NullValue + ChatColor.RESET;
  }
  /**
   * Returns an undefined JSON representation.
   */
  stringifyUndefined() {
    return this.NullColor + this.UndefinedValue + ChatColor.RESET;
  }
  /**
   * Returns a cycle JSON representation.
   */
  stringifyCycle() {
    return this.CycleColor + this.CycleValue + ChatColor.RESET;
  }
  /**
   * Transforms an array into a JSON representation.
   * @param value - The array to transform.
   * @param indentLevel - The indentation level for pretty-printing.
   */
  stringifyArray(value, ctx) {
    const indentSpace = this.Indent.repeat(ctx.indentLevel);
    if (value.length === 0) {
      return this.OpenCloseArrayColor + this.OpenArray + this.CloseArray + ChatColor.RESET;
    }
    let result = this.OpenCloseArrayColor + this.OpenArray + ChatColor.RESET + this.NewLine;
    let compactResult = this.OpenCloseArrayColor + this.OpenArray + ChatColor.RESET;
    value.forEach((item, index) => {
      result += indentSpace + this.Indent + this.stringifyValue(item, this.indent(ctx));
      result += index < value.length - 1 ? this.Comma + this.NewLine : this.NewLine;
      compactResult += this.stringifyValue(item, this.indent(ctx));
      compactResult += index < value.length - 1 ? this.Comma + this.Space : "";
    });
    result += indentSpace + this.OpenCloseArrayColor + this.CloseArray + ChatColor.RESET;
    compactResult += this.OpenCloseArrayColor + this.CloseArray + ChatColor.RESET;
    if (compactResult.length < this.InlineThreshold) {
      return compactResult;
    }
    return result;
  }
  /**
   * Transforms an object into a truncated JSON representation.
   * @param value - The object to transform.
   * @param className - Class Name of the object.
   * @param indentLevel - The indentation level for pretty-printing.
   */
  stringifyTruncatedObject(value, className, ctx) {
    return (this.IncludeClassNames ? this.ClassColor + "" + this.ClassStyle + className + ChatColor.RESET + this.Space : "") + this.TruncatedObjectValue;
  }
  /**
   * Transforms an object into a JSON representation.
   * @param value - The object to transform.
   * @param className - Class Name of the object.
   * @param entries - Entries of the object to transform.
   * @param indentLevel - The indentation level for pretty-printing.
   */
  stringifyObject(value, className, entries, ctx) {
    const indentSpace = this.Indent.repeat(ctx.indentLevel);
    const prefix = this.IncludeClassNames && className !== "Object" ? this.ClassColor + "" + this.ClassStyle + className + ChatColor.RESET + this.Space : "";
    if (entries.length === 0) {
      return prefix + this.OpenCloseObjectColor + this.OpenObject + this.CloseObject + ChatColor.RESET;
    }
    let result = prefix + this.OpenCloseObjectColor + this.OpenObject + ChatColor.RESET + this.NewLine;
    let compactResult = prefix + this.OpenCloseObjectColor + this.OpenObject + ChatColor.RESET;
    entries.forEach(([key, val], index) => {
      const compactVal = this.stringifyValue(val, this.indent(ctx));
      result += indentSpace + this.Indent + this.KeyColor + this.KeyDelimiter + key + this.KeyDelimiter + ChatColor.RESET + this.KeyValueSeparator + this.Space + compactVal;
      result += index < entries.length - 1 ? this.Comma + this.NewLine : this.NewLine;
      compactResult += this.KeyColor + key + ChatColor.RESET + this.KeyValueSeparator + this.Space + compactVal;
      compactResult += index < entries.length - 1 ? this.Comma + this.Space : "";
    });
    result += indentSpace + this.OpenCloseObjectColor + this.CloseObject + ChatColor.RESET;
    compactResult += this.OpenCloseObjectColor + this.CloseObject + ChatColor.RESET;
    if (compactResult.length < this.InlineThreshold) {
      return compactResult;
    }
    return result;
  }
  shouldTruncateObject(value, className, ctx) {
    return !(className === "Object" || ctx.indentLevel <= this.MaxDepth || this.MaxDepth <= 0);
  }
  /**
   * Transforms a value of any type into a JSON representation. This function is not meant to be overridden.
   * @param value - The value to transform.
   * @param indentLevel - The indentation level for pretty-printing.
   */
  stringifyValue(value, ctx) {
    if (value === null)
      return this.stringifyNull();
    if (value === void 0)
      return this.stringifyUndefined();
    if (typeof value === "number")
      return this.stringifyNumber(value);
    if (typeof value === "string")
      return this.stringifyString(value);
    if (typeof value === "boolean")
      return this.stringifyBoolean(value);
    if (typeof value === "function")
      return this.stringifyFunction(value);
    if (this.isCycle(value, ctx)) {
      return this.stringifyCycle();
    }
    this.markCycle(value, ctx);
    if (Array.isArray(value)) {
      const result = this.stringifyArray(value, ctx.indentLevel ? this.indent(ctx) : ctx);
      this.clearCycle(value, ctx);
      return result;
    }
    if (typeof value === "object") {
      const name = value.constructor.name;
      if (!this.shouldTruncateObject(value, name, ctx)) {
        const keySet = /* @__PURE__ */ new Set();
        let prototype = Object.getPrototypeOf(value);
        let keys = Object.keys(prototype);
        while (keys.length > 0) {
          keys.forEach((key) => keySet.add(key));
          prototype = Object.getPrototypeOf(prototype);
          keys = Object.keys(prototype);
        }
        Object.keys(value).forEach((key) => keySet.add(key));
        keySet.delete("__cycleDetection__");
        const allKeys = [...keySet].sort();
        const entries = allKeys.map((key) => {
          try {
            return [key, value[key] ?? void 0];
          } catch (e) {
            return [key, void 0];
          }
        }).filter(([, val]) => typeof val !== "function" && val !== void 0);
        const result = this.stringifyObject(value, name, entries, ctx);
        this.clearCycle(value, ctx);
        return result;
      } else {
        const result = this.stringifyTruncatedObject(value, name, ctx);
        this.clearCycle(value, ctx);
        return result;
      }
    }
    this.clearCycle(value, ctx);
    return ChatColor.RESET + value.toString();
  }
  /**
   * Escapes a string for JSON.
   * @param str - The string to escape.
   */
  escapeString(str) {
    return str.replace(/\\/g, this.EscapeColor + "\\\\" + this.StringColor).replace(/"/g, this.EscapeColor + '\\"' + this.StringColor).replace(/\n/g, this.EscapeColor + "\\n" + this.StringColor).replace(/\r/g, this.EscapeColor + "\\r" + this.StringColor).replace(/\t/g, this.EscapeColor + "\\t" + this.StringColor);
  }
  markCycle(value, ctx) {
    ctx.visited.add(value);
  }
  isCycle(value, ctx) {
    return ctx.visited.has(value);
  }
  clearCycle(value, ctx) {
    ctx.visited.delete(value);
  }
  indent(ctx) {
    return { ...ctx, indentLevel: ctx.indentLevel + 1 };
  }
}, /**
 * The default ColorJSON instance
 */
__publicField(_a2, "DEFAULT", new _a2()), /**
 * A ColorJSON instance that does not colorize anything.
 */
__publicField(_a2, "PLAIN", _a2.createPlain()), _a2);
var sourceMapping = void 0;
try {
  sourceMapping = globalSourceMapping;
} catch (e) {
}
var _a3;
var LogLevel = (_a3 = class {
  /**
   * The constructor for each log level.
   *
   * @param {number} level - The numerical level for this logger.
   * @param {string} name - The string name for this logger.
   * @param {ChatColor} color - The color to use for this logger. Defaults to `ChatColor.RESET`.
   */
  constructor(level, name, color = ChatColor.RESET) {
    this.level = level;
    this.name = name;
    this.color = color;
  }
  /**
   * Return the logging level as a string.
   *
   * @returns {string} The string representation of the logging level.
   */
  toString() {
    return this.color + this.name.toUpperCase() + ChatColor.RESET;
  }
  /**
   * Parse a string to get the corresponding `LogLevel`.
   *
   * @param {string} str - The string to parse.
   * @returns {LogLevel} The corresponding `LogLevel`, or `undefined` if none was found.
   */
  static parse(str) {
    str = str.toLowerCase();
    for (const level of _a3.values) {
      if (level.name === str)
        return level;
    }
    const num = parseInt(str);
    if (!isNaN(num)) {
      for (const level of _a3.values) {
        if (level.level === num)
          return level;
      }
    }
    return void 0;
  }
}, __publicField(_a3, "All", new _a3(-2, "all")), __publicField(_a3, "Trace", new _a3(-2, "trace", ChatColor.DARK_AQUA)), __publicField(_a3, "Debug", new _a3(-1, "debug", ChatColor.AQUA)), __publicField(_a3, "Info", new _a3(0, "info", ChatColor.GREEN)), __publicField(_a3, "Warn", new _a3(1, "warn", ChatColor.GOLD)), __publicField(_a3, "Error", new _a3(2, "error", ChatColor.RED)), __publicField(_a3, "Fatal", new _a3(3, "fatal", ChatColor.DARK_RED)), __publicField(_a3, "Off", new _a3(100, "off")), /**
 * The list of all available log levels.
 */
__publicField(_a3, "values", [
  _a3.All,
  _a3.Trace,
  _a3.Debug,
  _a3.Info,
  _a3.Warn,
  _a3.Error,
  _a3.Fatal,
  _a3.Off
]), _a3);
function starMatch(pattern, str) {
  if (pattern === "*")
    return true;
  if (pattern.includes("*")) {
    if (pattern.startsWith("*")) {
      return str.endsWith(pattern.substring(1));
    }
    if (pattern.endsWith("*")) {
      return str.startsWith(pattern.substring(0, pattern.length - 1));
    }
    const regex = new RegExp(pattern.replace(/\*/g, ".*"));
    return regex.test(str);
  }
  return pattern === str;
}
var loggingSettings = {
  level: LogLevel.Info,
  filter: ["*"],
  outputTags: false,
  formatFunction: (level, logger, message, tags = void 0) => {
    const _tags = tags !== void 0 ? `\xA77${tags.map((tag) => `[${tag}]`).join("")}\xA7r` : "";
    return `[${level}][${ChatColor.MATERIAL_EMERALD}${logger.name}${ChatColor.RESET}]${_tags} ${message}`;
  },
  messagesJoinFunction: (messages) => {
    return messages.join(" ");
  },
  jsonFormatter: ColorJSON.DEFAULT,
  outputConfig: {
    [LogLevel.Trace.level]: [
      0,
      1
      /* ConsoleInfo */
    ],
    [LogLevel.Debug.level]: [
      0,
      1
      /* ConsoleInfo */
    ],
    [LogLevel.Info.level]: [
      0,
      1
      /* ConsoleInfo */
    ],
    [LogLevel.Warn.level]: [
      0,
      1,
      2
      /* ConsoleWarn */
    ],
    [LogLevel.Error.level]: [
      0,
      1,
      3
      /* ConsoleError */
    ],
    [LogLevel.Fatal.level]: [
      0,
      1,
      3
      /* ConsoleError */
    ]
  }
};
var _a4;
var Logger = (_a4 = class {
  /**
   * Construct a new Logger
   *
   * @param {string} name - The name of the Logger.
   * @param {string[]} tags - The tags for the logger as strings.
   */
  constructor(name, tags = []) {
    this.name = name;
    this.tags = tags;
  }
  /**
   *  Initialize logger class
   */
  static init() {
    LOGGING: {
      if (_a4.initialized)
        return;
      _a4.initialized = true;
      system.afterEvents.scriptEventReceive.subscribe((ev) => {
        if (ev.id === "logging:level" || ev.id === "log:level") {
          if (!ev.message) {
            loggingSettings.level = LogLevel.Info;
            world.sendMessage(
              `${ChatColor.AQUA}Logging level set to ${ChatColor.BOLD}${loggingSettings.level}`
            );
          } else {
            const level = LogLevel.parse(ev.message);
            if (level) {
              loggingSettings.level = level;
              world.sendMessage(
                `${ChatColor.AQUA}Logging level set to ${ChatColor.BOLD}${loggingSettings.level}`
              );
            } else {
              world.sendMessage(
                `${ChatColor.DARK_RED}Invalid logging level: ${ev.message}`
              );
            }
          }
        } else if (ev.id === "logging:filter" || ev.id === "log:filter") {
          if (!ev.message) {
            loggingSettings.filter = ["*"];
          } else {
            loggingSettings.filter = ev.message.split(",");
          }
          world.sendMessage(
            `${ChatColor.AQUA}Logging filter set to ${ChatColor.BOLD}${loggingSettings.filter.join(", ")}`
          );
        }
      });
    }
  }
  /**
   * @param {LogLevel} level - The level to set.
   */
  static setLevel(level) {
    loggingSettings.level = level;
  }
  /**
   * Filter the loggers by the given tags. Tags can use the `*` wildcard.
   * @param {'*' | string[]} filter - The filter to set.
   */
  static setFilter(filter) {
    loggingSettings.filter = filter;
  }
  /**
   * Set the format function for the logger.
   * @param {function} func - The function to set.
   */
  static setFormatFunction(func) {
    loggingSettings.formatFunction = func;
  }
  /**
   * Set the function, that joins multiple messages into one for the logger.
   * @param {function} func - The function to set.
   */
  static setMessagesJoinFunction(func) {
    loggingSettings.messagesJoinFunction = func;
  }
  /**
   * Set the tag visibility for the logger. When true, tags will be printed in the log. Disabled by default.
   * @param visible
   */
  static setTagsOutputVisibility(visible) {
    loggingSettings.outputTags = visible;
  }
  /**
   * Set the JSON formatter for the logger.
   * @param {ColorJSON} formatter - The json formatter to set.
   */
  static setJsonFormatter(formatter) {
    loggingSettings.jsonFormatter = formatter;
  }
  /**
   * Get the output configuration for the logger.
   * @returns {OutputConfig} The output configuration.
   */
  static getOutputConfig() {
    return loggingSettings.outputConfig;
  }
  /**
   * Returns a new Logger.
   *
   * @param {string} name - The name of the Logger.
   * @param {string[]} tags - The tags for the Logger as strings.
   *
   * @returns {Logger} A new Logger.
   */
  static getLogger(name, ...tags) {
    LOGGING: {
      if (!_a4.initialized) {
        _a4.init();
      }
    }
    return new _a4(name, tags);
  }
  /**
   * Log messages with the level set.
   *
   * @param {LogLevel} level - The LogLevel to log the messages at.
   * @param {array} message - An array of the messages to log.
   */
  log(level, ...message) {
    LOGGING: {
      if (level.level < loggingSettings.level.level)
        return;
      if (loggingSettings.filter.length === 0 || this.tags.length === 0) {
        this.logRaw(level, ...message);
        return;
      }
      for (const filter of loggingSettings.filter) {
        if (filter.startsWith("!")) {
          if (starMatch(filter.substring(1), this.name) || this.tags.some((tag) => starMatch(filter.substring(1), tag))) {
            return;
          }
        }
        if (starMatch(filter, this.name) || this.tags.some((tag) => starMatch(filter, tag))) {
          this.logRaw(level, ...message);
          return;
        }
      }
    }
  }
  stringifyError(x) {
    let stack = x.stack ?? "";
    if (sourceMapping) {
      const stackLineRegex = /\(([^)]+\.js):(\d+)(?::(\d+))?\)/;
      stack = stack.split("\n").map((line) => {
        const match = stackLineRegex.exec(line);
        if (match) {
          const filePath = match[1];
          const lineNumber = parseInt(match[2], 10) - sourceMapping.metadata.offset;
          if (filePath.includes(sourceMapping.metadata.filePath)) {
            const mappingEntry = globalSourceMapping[lineNumber];
            if (mappingEntry) {
              const replacement = `(${mappingEntry.source}:${mappingEntry.originalLine})`;
              return line.replace(stackLineRegex, replacement);
            }
          }
        }
        return line;
      }).join("\n");
    }
    return `${ChatColor.DARK_RED}${ChatColor.BOLD}${x.message}
${ChatColor.RESET}${ChatColor.GRAY}${ChatColor.ITALIC}${stack}${ChatColor.RESET}`;
  }
  /**
   * Internal function to log messages with the level set, that bypasses the filters.
   *
   * @param {LogLevel} level - The LogLevel to log the messages at.
   * @param {array} message - An array of the messages to log.
   */
  logRaw(level, ...message) {
    LOGGING: {
      const msgs = message.map((x) => {
        if (x === void 0) {
          return ChatColor.GOLD + "undefined" + ChatColor.RESET;
        }
        if (x === null) {
          return ChatColor.GOLD + "null" + ChatColor.RESET;
        }
        if (x && x instanceof Error) {
          return this.stringifyError(x);
        }
        if (typeof x === "object" || Array.isArray(x)) {
          return loggingSettings.jsonFormatter.stringify(x) + ChatColor.RESET;
        }
        return x.toString() + ChatColor.RESET;
      });
      const formatted = loggingSettings.formatFunction(
        level,
        this,
        loggingSettings.messagesJoinFunction(msgs),
        loggingSettings.outputTags ? this.tags : void 0
      );
      const outputs = loggingSettings.outputConfig[level.level] || [
        0,
        1
        /* ConsoleInfo */
      ];
      if (outputs.includes(
        0
        /* Chat */
      )) {
        try {
          world.sendMessage(formatted);
        } catch (_) {
          system.run(() => {
            world.sendMessage(formatted);
          });
        }
      }
      if (outputs.includes(
        1
        /* ConsoleInfo */
      )) {
        if (console.originalLog) {
          console.originalLog(ChatColor.stripColor(formatted));
        } else {
          console.log(ChatColor.stripColor(formatted));
        }
      }
      if (outputs.includes(
        2
        /* ConsoleWarn */
      )) {
        console.warn(formatted);
      }
      if (outputs.includes(
        3
        /* ConsoleError */
      )) {
        console.error(formatted);
      }
    }
  }
  /**
   * Logs a trace message.
   *
   * @param {...unknown} message - The message(s) to be logged.
   */
  trace(...message) {
    LOGGING:
      this.log(LogLevel.Trace, ...message);
  }
  /**
   * Logs debug message.
   *
   * @param {...unknown[]} message - The message(s) to be logged.
   */
  debug(...message) {
    LOGGING:
      this.log(LogLevel.Debug, ...message);
  }
  /**
   * Logs an informational message.
   *
   * @param {...unknown[]} message - The message(s) to be logged.
   */
  info(...message) {
    LOGGING:
      this.log(LogLevel.Info, ...message);
  }
  /**
   * Logs a warning message.
   *
   * @param {...unknown[]} message - The warning message or messages to be logged.
   */
  warn(...message) {
    LOGGING:
      this.log(LogLevel.Warn, ...message);
  }
  /**
   * Logs an error message.
   *
   * @param {...unknown[]} message - The error message(s) to log.
   */
  error(...message) {
    LOGGING:
      this.log(LogLevel.Error, ...message);
  }
  /**
   * Logs a fatal error.
   *
   * @param {unknown[]} message - The error message to log.
   */
  fatal(...message) {
    LOGGING:
      this.log(LogLevel.Fatal, ...message);
  }
}, __publicField(_a4, "initialized", false), _a4);
var _a5;
var Vec3 = (_a5 = class {
  constructor(x, y, z) {
    __publicField(this, "x");
    __publicField(this, "y");
    __publicField(this, "z");
    if (x === Direction.Down) {
      this.x = 0;
      this.y = -1;
      this.z = 0;
    } else if (x === Direction.Up) {
      this.x = 0;
      this.y = 1;
      this.z = 0;
    } else if (x === Direction.North) {
      this.x = 0;
      this.y = 0;
      this.z = -1;
    } else if (x === Direction.South) {
      this.x = 0;
      this.y = 0;
      this.z = 1;
    } else if (x === Direction.East) {
      this.x = 1;
      this.y = 0;
      this.z = 0;
    } else if (x === Direction.West) {
      this.x = -1;
      this.y = 0;
      this.z = 0;
    } else if (typeof x === "number") {
      this.x = x;
      this.y = y;
      this.z = z;
    } else if (Array.isArray(x)) {
      this.x = x[0];
      this.y = x[1];
      this.z = x[2];
    } else if (x instanceof _a5) {
      this.x = x.x;
      this.y = x.y;
      this.z = x.z;
    } else {
      if (!x || !x.x && x.x !== 0 || !x.y && x.y !== 0 || !x.z && x.z !== 0) {
        _a5.log.error(new Error("Invalid vector"), x);
        throw new Error("Invalid vector");
      }
      this.x = x.x;
      this.y = x.y;
      this.z = x.z;
    }
  }
  static from(x, y, z) {
    if (x instanceof _a5)
      return x;
    if (typeof x === "number" && y !== void 0 && z !== void 0) {
      return new _a5(x, y, z);
    }
    if (Array.isArray(x)) {
      return new _a5(x);
    }
    if (x === Direction.Down)
      return _a5.Down;
    if (x === Direction.Up)
      return _a5.Up;
    if (x === Direction.North)
      return _a5.North;
    if (x === Direction.South)
      return _a5.South;
    if (x === Direction.East)
      return _a5.East;
    if (x === Direction.West)
      return _a5.West;
    if (!x || !x.x && x.x !== 0 || !x.y && x.y !== 0 || !x.z && x.z !== 0) {
      _a5.log.error(new Error("Invalid arguments"), x, y, z);
      throw new Error("Invalid arguments");
    }
    return new _a5(
      x.x,
      x.y,
      x.z
    );
  }
  static _from(x, y, z) {
    if (x instanceof _a5)
      return x;
    if (typeof x === "number" && y !== void 0 && z !== void 0) {
      return new _a5(x, y, z);
    }
    if (Array.isArray(x)) {
      return new _a5(x);
    }
    if (x === Direction.Down)
      return _a5.Down;
    if (x === Direction.Up)
      return _a5.Up;
    if (x === Direction.North)
      return _a5.North;
    if (x === Direction.South)
      return _a5.South;
    if (x === Direction.East)
      return _a5.East;
    if (x === Direction.West)
      return _a5.West;
    if (!x || !x.x && x.x !== 0 || !x.y && x.y !== 0 || !x.z && x.z !== 0) {
      _a5.log.error(new Error("Invalid arguments"), x, y, z);
      throw new Error("Invalid arguments");
    }
    return new _a5(
      x.x,
      x.y,
      x.z
    );
  }
  /**
   * Creates a copy of the current vector.
   *
   * @returns A new vector with the same values as the current vector.
   */
  copy() {
    return new _a5(this.x, this.y, this.z);
  }
  static fromYawPitch(yawOrRotation, pitch) {
    let yaw;
    if (typeof yawOrRotation === "number") {
      yaw = yawOrRotation;
      pitch = pitch;
    } else {
      yaw = yawOrRotation.y;
      pitch = yawOrRotation.x;
    }
    const psi = yaw * (Math.PI / 180);
    const theta = pitch * (Math.PI / 180);
    const x = Math.cos(theta) * Math.sin(psi);
    const y = Math.sin(theta);
    const z = Math.cos(theta) * Math.cos(psi);
    return new _a5(x, y, z);
  }
  static fromRotation(yawOrRotation, pitch) {
    let yaw;
    if (typeof yawOrRotation === "number") {
      yaw = yawOrRotation;
      pitch = pitch;
    } else {
      yaw = yawOrRotation.y;
      pitch = yawOrRotation.x;
    }
    const psi = yaw * (Math.PI / 180);
    const theta = pitch * (Math.PI / 180);
    const x = -Math.cos(theta) * Math.sin(psi);
    const y = -Math.sin(theta);
    const z = Math.cos(theta) * Math.cos(psi);
    return new _a5(x, y, z);
  }
  /**
   * Converts the normal vector to yaw and pitch values.
   *
   * @returns A Vector2 containing the yaw and pitch values.
   * @deprecated Use toRotation() instead. This method returns inverted values and will be removed in the future.
   */
  toYawPitch() {
    if (this.isZero()) {
      _a5.log.error(
        new Error("Cannot convert zero-length vector to direction")
      );
      throw new Error("Cannot convert zero-length vector to direction");
    }
    const direction = this.normalize();
    const yaw = Math.atan2(direction.x, direction.z) * (180 / Math.PI);
    const pitch = Math.asin(direction.y) * (180 / Math.PI);
    return {
      x: pitch,
      y: yaw
    };
  }
  /**
   * Converts the normal vector to yaw and pitch values.
   *
   * @returns A Vector2 containing the yaw and pitch values.
   */
  toRotation() {
    if (this.isZero()) {
      _a5.log.error(
        new Error("Cannot convert zero-length vector to direction")
      );
      throw new Error("Cannot convert zero-length vector to direction");
    }
    const direction = this.normalize();
    const yaw = -Math.atan2(direction.x, direction.z) * (180 / Math.PI);
    const pitch = Math.asin(-direction.y) * (180 / Math.PI);
    return {
      x: pitch,
      y: yaw
    };
  }
  add(x, y, z) {
    const v = _a5._from(x, y, z);
    return _a5.from(v.x + this.x, v.y + this.y, v.z + this.z);
  }
  subtract(x, y, z) {
    const v = _a5._from(x, y, z);
    return _a5.from(this.x - v.x, this.y - v.y, this.z - v.z);
  }
  multiply(x, y, z) {
    if (typeof x === "number" && y === void 0 && z === void 0) {
      return _a5.from(this.x * x, this.y * x, this.z * x);
    }
    const v = _a5._from(x, y, z);
    return _a5.from(v.x * this.x, v.y * this.y, v.z * this.z);
  }
  /**
   * Scales the current vector by a scalar.
   *
   * @param scalar - The scalar to scale the vector by.
   * @returns The updated vector after scaling.
   */
  scale(scalar) {
    return _a5.from(this.x * scalar, this.y * scalar, this.z * scalar);
  }
  divide(x, y, z) {
    if (typeof x === "number" && y === void 0 && z === void 0) {
      if (x === 0)
        throw new Error("Cannot divide by zero");
      return _a5.from(this.x / x, this.y / x, this.z / x);
    }
    const v = _a5._from(x, y, z);
    if (v.x === 0 || v.y === 0 || v.z === 0)
      throw new Error("Cannot divide by zero");
    return _a5.from(this.x / v.x, this.y / v.y, this.z / v.z);
  }
  /**
   * Normalizes the vector to have a length (magnitude) of 1.
   * Normalized vectors are often used as a direction vectors.
   *
   * @returns The normalized vector.
   */
  normalize() {
    if (this.isZero()) {
      _a5.log.error(new Error("Cannot normalize zero-length vector"));
      throw new Error("Cannot normalize zero-length vector");
    }
    const len = this.length();
    return _a5.from(this.x / len, this.y / len, this.z / len);
  }
  /**
   * Computes the length (magnitude) of the vector.
   *
   * @returns The length of the vector.
   */
  length() {
    return Math.hypot(this.x, this.y, this.z);
  }
  /**
   * Computes the squared length of the vector.
   * This is faster than computing the actual length and can be useful for comparison purposes.
   *
   * @returns The squared length of the vector.
   */
  lengthSquared() {
    return this.x * this.x + this.y * this.y + this.z * this.z;
  }
  cross(x, y, z) {
    const v = _a5._from(x, y, z);
    return _a5.from(
      this.y * v.z - this.z * v.y,
      this.z * v.x - this.x * v.z,
      this.x * v.y - this.y * v.x
    );
  }
  distance(x, y, z) {
    const v = _a5._from(x, y, z);
    return this.subtract(v).length();
  }
  distanceSquared(x, y, z) {
    const v = _a5._from(x, y, z);
    return this.subtract(v).lengthSquared();
  }
  /**
   * Computes the linear interpolation between the current vector and another vector, when t is in the range [0, 1].
   * Computes the extrapolation when t is outside this range.
   *
   * @param v - The other vector.
   * @param t - The interpolation factor.
   * @returns A new vector after performing the lerp operation.
   */
  lerp(v, t) {
    if (!v || !t)
      return _a5.from(this);
    if (t === 1)
      return _a5.from(v);
    if (t === 0)
      return _a5.from(this);
    return _a5.from(
      this.x + (v.x - this.x) * t,
      this.y + (v.y - this.y) * t,
      this.z + (v.z - this.z) * t
    );
  }
  /**
   * Computes the spherical linear interpolation between the current vector and another vector, when t is in the range [0, 1].
   * Computes the extrapolation when t is outside this range.
   *
   * @param v - The other vector.
   * @param t - The interpolation factor.
   * @returns A new vector after performing the slerp operation.
   */
  slerp(v, t) {
    if (!v || !t)
      return _a5.from(this);
    if (t === 1)
      return _a5.from(v);
    if (t === 0)
      return _a5.from(this);
    const dot = this.dot(v);
    const theta = Math.acos(dot) * t;
    const relative = _a5.from(v).subtract(this.multiply(dot)).normalize();
    return this.multiply(Math.cos(theta)).add(
      relative.multiply(Math.sin(theta))
    );
  }
  dot(x, y, z) {
    const v = _a5._from(x, y, z);
    return this.x * v.x + this.y * v.y + this.z * v.z;
  }
  angleBetween(x, y, z) {
    const v = _a5._from(x, y, z);
    const dotProduct = this.dot(v);
    const lenSq1 = this.lengthSquared();
    if (lenSq1 === 0) {
      return 0;
    }
    const lenSq2 = v.lengthSquared();
    if (lenSq2 === 0) {
      return 0;
    }
    const denom = Math.sqrt(lenSq1 * lenSq2);
    const cosAngle = Math.min(1, Math.max(-1, dotProduct / denom));
    return Math.acos(cosAngle);
  }
  projectOnto(x, y, z) {
    const v = _a5._from(x, y, z);
    if (v.isZero()) {
      return _a5.Zero;
    }
    const denom = v.dot(v);
    if (denom === 0) {
      return _a5.Zero;
    }
    const scale = this.dot(v) / denom;
    return _a5.from(v.x * scale, v.y * scale, v.z * scale);
  }
  reflect(x, y, z) {
    const normal = _a5._from(x, y, z);
    const proj = this.projectOnto(normal);
    return this.subtract(proj.multiply(2));
  }
  /**
   * Rotates the current normalized vector by a given angle around a given axis.
   *
   * @param axis - The axis of rotation.
   * @param angle - The angle of rotation in degrees.
   * @returns The rotated vector.
   */
  rotate(axis, angle) {
    const halfAngle = angle * Math.PI / 180 / 2;
    const w = Math.cos(halfAngle);
    const x = axis.x * Math.sin(halfAngle);
    const y = axis.y * Math.sin(halfAngle);
    const z = axis.z * Math.sin(halfAngle);
    const v = this;
    const qv_x = w * w * v.x + 2 * y * w * v.z - 2 * z * w * v.y + x * x * v.x + 2 * y * x * v.y + 2 * z * x * v.z - z * z * v.x - y * y * v.x;
    const qv_y = 2 * x * y * v.x + y * y * v.y + 2 * z * y * v.z + 2 * w * z * v.x - z * z * v.y + w * w * v.y - 2 * x * w * v.z - x * x * v.y;
    const qv_z = 2 * x * z * v.x + 2 * y * z * v.y + z * z * v.z - 2 * w * y * v.x - y * y * v.z + 2 * w * x * v.y - x * x * v.z + w * w * v.z;
    return new _a5(qv_x, qv_y, qv_z);
  }
  /**
   * Updates the X, Y, and Z components of the vector.
   *
   * @param x - The function to use to update the X value.
   * @param y - The function to use to update the Y value.
   * @param z - The function to use to update the Z value.
   * @returns The updated vector with the new values.
   */
  update(x, y, z) {
    if (!x) {
      x = (value) => value;
    }
    if (!y) {
      y = (value) => value;
    }
    if (!z) {
      z = (value) => value;
    }
    return new _a5(x(this.x), y(this.y), z(this.z));
  }
  setX(value) {
    if (typeof value === "number") {
      return new _a5(value, this.y, this.z);
    }
    return new _a5(value(this.x), this.y, this.z);
  }
  setY(value) {
    if (typeof value === "number") {
      return new _a5(this.x, value, this.z);
    }
    return new _a5(this.x, value(this.y), this.z);
  }
  setZ(value) {
    if (typeof value === "number") {
      return new _a5(this.x, this.y, value);
    }
    return new _a5(this.x, this.y, value(this.z));
  }
  /**
   * Calculates the shortest distance between a point (represented by this Vector3 instance) and a line segment.
   *
   * This method finds the perpendicular projection of the point onto the line defined by the segment. If this
   * projection lies outside the line segment, then the method calculates the distance from the point to the
   * nearest segment endpoint.
   *
   * @param start - The starting point of the line segment.
   * @param end - The ending point of the line segment.
   * @returns The shortest distance between the point and the line segment.
   */
  distanceToLineSegment(start, end) {
    const lineDirection = _a5.from(end).subtract(start);
    if (lineDirection.lengthSquared() === 0) {
      return this.subtract(start).length();
    }
    const t = Math.max(
      0,
      Math.min(
        1,
        this.subtract(start).dot(lineDirection) / lineDirection.dot(lineDirection)
      )
    );
    const projection = _a5.from(start).add(lineDirection.multiply(t));
    return this.subtract(projection).length();
  }
  /**
   * Floors the X, Y, and Z components of the vector.
   * @returns A new vector with the floored components.
   */
  floor() {
    return this.update(Math.floor, Math.floor, Math.floor);
  }
  /**
   * Floors the X component of the vector.
   * @returns A new vector with the floored X component.
   */
  floorX() {
    return this.setX(Math.floor);
  }
  /**
   * Floors the Y component of the vector.
   * @returns A new vector with the floored Y component.
   */
  floorY() {
    return this.setY(Math.floor);
  }
  /**
   * Floors the Z component of the vector.
   * @returns A new vector with the floored Z component.
   */
  floorZ() {
    return this.setZ(Math.floor);
  }
  /**
   * Ceils the X, Y, and Z components of the vector.
   * @returns A new vector with the ceiled components.
   */
  ceil() {
    return new _a5(Math.ceil(this.x), Math.ceil(this.y), Math.ceil(this.z));
  }
  /**
   * Ceils the X component of the vector.
   * @returns A new vector with the ceiled X component.
   */
  ceilX() {
    return this.setX(Math.ceil);
  }
  /**
   * Ceils the Y component of the vector.
   * @returns A new vector with the ceiled Y component.
   */
  ceilY() {
    return this.setY(Math.ceil);
  }
  /**
   * Ceils the Z component of the vector.
   * @returns A new vector with the ceiled Z component.
   */
  ceilZ() {
    return this.setZ(Math.ceil);
  }
  /**
   * Rounds the X, Y, and Z components of the vector.
   * @returns A new vector with the rounded components.
   */
  round() {
    return this.update(Math.round, Math.round, Math.round);
  }
  /**
   * Rounds the X component of the vector.
   * @returns A new vector with the rounded X component.
   */
  roundX() {
    return this.setX(Math.round);
  }
  /**
   * Rounds the Y component of the vector.
   * @returns A new vector with the rounded Y component.
   */
  roundY() {
    return this.setY(Math.round);
  }
  /**
   * Rounds the Z component of the vector.
   * @returns A new vector with the rounded Z component.
   */
  roundZ() {
    return this.setZ(Math.round);
  }
  /**
   * Returns a new vector offset from the current vector up by 1 block.
   * @returns A new vector offset from the current vector up by 1 block.
   */
  up() {
    return this.add(_a5.Up);
  }
  /**
   * Returns a new vector offset from the current vector down by 1 block.
   * @returns A new vector offset from the current vector down by 1 block.
   */
  down() {
    return this.add(_a5.Down);
  }
  /**
   * Returns a new vector offset from the current vector north by 1 block.
   * @returns A new vector offset from the current vector north by 1 block.
   */
  north() {
    return this.add(_a5.North);
  }
  /**
   * Returns a new vector offset from the current vector south by 1 block.
   * @returns A new vector offset from the current vector south by 1 block.
   */
  south() {
    return this.add(_a5.South);
  }
  /**
   * Returns a new vector offset from the current vector east by 1 block.
   * @returns A new vector offset from the current vector east by 1 block.
   */
  east() {
    return this.add(_a5.East);
  }
  /**
   * Returns a new vector offset from the current vector west by 1 block.
   * @returns A new vector offset from the current vector west by 1 block.
   */
  west() {
    return this.add(_a5.West);
  }
  /**
   * Checks if the current vector is equal to the zero vector.
   * @returns true if the vector is equal to the zero vector, else returns false.
   */
  isZero() {
    return this.x === 0 && this.y === 0 && this.z === 0;
  }
  /**
   * Converts the vector to an array containing the X, Y, and Z components of the vector.
   * @returns An array containing the X, Y, and Z components of the vector.
   */
  toArray() {
    return [this.x, this.y, this.z];
  }
  /**
   * Converts the vector to a direction.
   * If the vector is not a unit vector, then it will be normalized and rounded to the nearest direction.
   */
  toDirection() {
    if (this.isZero()) {
      _a5.log.error(
        new Error("Cannot convert zero-length vector to direction")
      );
      throw new Error("Cannot convert zero-length vector to direction");
    }
    const normalized = this.normalize();
    const maxValue = Math.max(
      Math.abs(normalized.x),
      Math.abs(normalized.y),
      Math.abs(normalized.z)
    );
    if (maxValue === normalized.x)
      return Direction.East;
    if (maxValue === -normalized.x)
      return Direction.West;
    if (maxValue === normalized.y)
      return Direction.Up;
    if (maxValue === -normalized.y)
      return Direction.Down;
    if (maxValue === normalized.z)
      return Direction.South;
    if (maxValue === -normalized.z)
      return Direction.North;
    _a5.log.error(new Error("Cannot convert vector to direction"), this);
    throw new Error("Cannot convert vector to direction");
  }
  /**
   * Returns a new vector with the X, Y, and Z components rounded to the nearest block location.
   */
  toBlockLocation() {
    return _a5.from(
      (this.x << 0) - (this.x < 0 && this.x !== this.x << 0 ? 1 : 0),
      (this.y << 0) - (this.y < 0 && this.y !== this.y << 0 ? 1 : 0),
      (this.z << 0) - (this.z < 0 && this.z !== this.z << 0 ? 1 : 0)
    );
  }
  almostEqual(x, y, z, delta) {
    try {
      let other;
      if (typeof x !== "number" && z === void 0) {
        other = _a5._from(x, void 0, void 0);
        delta = y;
      } else {
        other = _a5._from(x, y, z);
      }
      return Math.abs(this.x - other.x) <= delta && Math.abs(this.y - other.y) <= delta && Math.abs(this.z - other.z) <= delta;
    } catch (e) {
      return false;
    }
  }
  equals(x, y, z) {
    try {
      const other = _a5._from(x, y, z);
      return this.x === other.x && this.y === other.y && this.z === other.z;
    } catch (e) {
      return false;
    }
  }
  /**
   * Converts the vector to a string representation.
   *
   * @param format - The format of the string representation. Defaults to "long".
   * @param separator - The separator to use between components. Defaults to ", ".
   * @returns The string representation of the vector.
   * @remarks
   * The "long" format is "Vec3(x, y, z)".
   * The "short" format is "x, y, z".
   */
  toString(format = "long", separator = ", ") {
    const result = `${this.x + separator + this.y + separator + this.z}`;
    return format === "long" ? `Vec3(${result})` : result;
  }
  /**
   * Parses a string representation of a vector.
   *
   * @param str - The string representation of the vector.
   * @param format - The format of the string representation. Defaults to "long".
   * @param separator - The separator to use between components. Defaults to ", ".
   * @returns The vector parsed from the string.
   * @throws {Error} If the string format is invalid.
   */
  static fromString(str, format = "long", separator = ", ") {
    if (format === "long") {
      const match = str.match(/^Vec3\((.*)\)$/);
      if (!match) {
        throw new Error("Invalid string format");
      }
      const components = match[1].split(separator);
      if (components.length !== 3) {
        throw new Error("Invalid string format");
      }
      return _a5.from(Number(components[0]), Number(components[1]), Number(components[2]));
    } else {
      const components = str.split(separator);
      if (components.length !== 3) {
        throw new Error("Invalid string format");
      }
      return _a5.from(Number(components[0]), Number(components[1]), Number(components[2]));
    }
  }
}, __publicField(_a5, "log", Logger.getLogger(
  "vec3",
  "vec3",
  "bedrock-boost"
)), /**
 * Zero vector
 */
__publicField(_a5, "Zero", new _a5(0, 0, 0)), /**
 * Down vector, negative towards Y
 */
__publicField(_a5, "Down", new _a5(Direction.Down)), /**
 * Up vector, positive towards Y
 */
__publicField(_a5, "Up", new _a5(Direction.Up)), /**
 * North vector, negative towards Z
 */
__publicField(_a5, "North", new _a5(Direction.North)), /**
 * South vector, positive towards Z
 */
__publicField(_a5, "South", new _a5(Direction.South)), /**
 * East vector, positive towards X
 */
__publicField(_a5, "East", new _a5(Direction.East)), /**
 * West vector, negative towards X
 */
__publicField(_a5, "West", new _a5(Direction.West)), _a5);
var _a6;
var Timings = (_a6 = class {
  /**
   * Begin measuring the time it takes to perform an operation.
   * @remarks
   * If another operation is already being measured, the measurement will be ended.
   * 
   * @param operation The name of the operation.
   */
  static begin(operation) {
    this.end();
    this.lastTime = (/* @__PURE__ */ new Date()).getTime();
    this.lastOperation = operation;
  }
  /**
   * End measuring the time it takes to perform an operation and log the result.
   * @remarks
   * If no operation is being measured, this method will do nothing.
   */
  static end() {
    const time = (/* @__PURE__ */ new Date()).getTime();
    if (this.lastTime > 0) {
      _a6.log.debug(`Operation ${this.lastOperation} took ${time - this.lastTime}ms`);
    }
    this.lastTime = -1;
  }
}, __publicField(_a6, "log", Logger.getLogger("Timings", "timings")), __publicField(_a6, "lastTime", -1), __publicField(_a6, "lastOperation", ""), _a6);
function isValid(entity) {
  const f = Object.getPrototypeOf(entity).isValid;
  if (typeof f === "function") {
    return f.call(entity);
  }
  return entity.isValid;
}
var log = Logger.getLogger("jobUtils", "bedrock-boost", "jobUtils");
var _a7;
var PulseScheduler = (_a7 = class {
  /**
   * Creates a new PulseScheduler instance.
   * @param period The period of the scheduler.
   */
  constructor(processor, period) {
    __publicField(this, "items", []);
    __publicField(this, "period");
    __publicField(this, "currentTick", 0);
    __publicField(this, "runId");
    __publicField(this, "nextIndex", 0);
    __publicField(this, "executionSchedule", []);
    __publicField(this, "processor");
    if (period <= 0) {
      throw new Error("Period must be a positive integer.");
    }
    if (!processor || typeof processor !== "function") {
      throw new Error("Processor function must be defined.");
    }
    this.period = period;
    this.processor = processor;
  }
  /**
   * Adds an item to the schedule.
   * @param item The item to be added.
   * @deprecated Use `push` instead.
   */
  add(item) {
    this.push(item);
  }
  /**
    * Adds multiple items to the schedule.
    * 
    * @param items - The items to be added.
    * @deprecated Use `push` instead.
    */
  addAll(items) {
    this.push(...items);
  }
  /**
   * Removes an item from the schedule at the specified index.
   * @param index - The index of the item to remove.
   */
  remove(index) {
    if (index >= 0 && index < this.items.length) {
      this.items.splice(index, 1);
      if (index < this.nextIndex) {
        this.nextIndex--;
      }
      this.recalculateExecutionSchedule();
    }
  }
  /**
   * Removes items from the schedule that satisfy the given predicate.
   * 
   * @param predicate - The predicate function used to determine if an item should be removed.
   */
  removeIf(predicate) {
    for (let i = this.items.length - 1; i >= 0; i--) {
      if (predicate(this.items[i])) {
        this.remove(i);
      }
    }
  }
  /**
   * Returns a list of the items in the schedule.
   */
  getItems() {
    return this.items;
  }
  /**
   * Starts the schedule.
   */
  start() {
    this.stop();
    this.currentTick = 0;
    this.nextIndex = 0;
    this.runId = system4.runInterval(() => this.tick(), 1);
  }
  /**
   * Stops the schedule.
   */
  stop() {
    if (this.runId !== void 0) {
      system4.clearRun(this.runId);
      this.runId = void 0;
    }
  }
  recalculateExecutionSchedule() {
    const totalExecutions = this.items.length;
    this.executionSchedule = new Array(this.period).fill(0);
    if (totalExecutions === 0) {
      return;
    }
    const interval = this.period / totalExecutions;
    for (let i = 0; i < totalExecutions; i++) {
      this.executionSchedule[Math.round(interval * i) % this.period]++;
    }
  }
  tick() {
    if (this.items.length === 0) {
      _a7.log.trace("No items to process.");
      return;
    }
    const scheduledExecutions = this.executionSchedule[this.currentTick];
    if (scheduledExecutions === 0) {
      _a7.log.trace("No items to process this tick.");
      this.currentTick = (this.currentTick + 1) % this.period;
      if (this.currentTick === 0) {
        this.nextIndex = 0;
      }
      return;
    }
    let executed = 0;
    for (; this.nextIndex < this.items.length && executed < scheduledExecutions; this.nextIndex++) {
      try {
        this.processor(this.items[this.nextIndex]);
      } catch (e) {
        _a7.log.error("Error processing item", e);
      }
      executed++;
    }
    this.currentTick = (this.currentTick + 1) % this.period;
    if (this.currentTick === 0) {
      this.nextIndex = 0;
    }
  }
  push(...items) {
    this.items.push(...items);
    this.recalculateExecutionSchedule();
    return this.items.length;
  }
  pop() {
    const item = this.items.pop();
    this.recalculateExecutionSchedule();
    return item;
  }
  shift() {
    const item = this.items.shift();
    this.recalculateExecutionSchedule();
    return item;
  }
  unshift(...items) {
    this.items.unshift(...items);
    this.recalculateExecutionSchedule();
    return this.items.length;
  }
  splice(start, deleteCount = 0, ...items) {
    const removed = this.items.splice(start, deleteCount, ...items);
    this.recalculateExecutionSchedule();
    return removed;
  }
}, __publicField(_a7, "log", Logger.getLogger("PulseScheduler", "bedrock-boost", "pulse-scheduler")), _a7);
var _a8;
var EntityPulseScheduler = (_a8 = class extends PulseScheduler {
  /**
   * Creates a new EntityPulseScheduler instance.
   * @param period The period of the scheduler.
   * @param queryOptions The query options to use when querying for entities.
   */
  constructor(processor, period, queryOptions) {
    super((t) => {
      if (isValid(t)) {
        processor(t);
      } else {
        this.removeIf((entity) => !isValid(entity));
      }
    }, period);
    this.queryOptions = queryOptions;
    this.push(
      ...world4.getDimension("minecraft:overworld").getEntities(this.queryOptions)
    );
    this.push(
      ...world4.getDimension("minecraft:nether").getEntities(this.queryOptions)
    );
    this.push(
      ...world4.getDimension("minecraft:the_end").getEntities(this.queryOptions)
    );
  }
  compareEntities(a, b) {
    return a.id === b.id;
  }
  start() {
    world4.afterEvents.entityLoad.subscribe((event) => {
      this.addIfMatchesWithRetry(event.entity);
    });
    world4.afterEvents.entitySpawn.subscribe((event) => {
      this.addIfMatchesWithRetry(event.entity);
    });
    world4.afterEvents.entityRemove.subscribe((event) => {
      this.removeIf(
        (entity) => !isValid(entity) || entity.id === event.removedEntityId
      );
    });
    super.start();
  }
  /**
   * Adds an entity to the scheduler if it matches the query options. In case the entity is not valid, it will retry a tick later.
   * @param entity The entity to add.
   */
  addIfMatchesWithRetry(entity) {
    try {
      if (!entity) {
        return;
      }
      if (!isValid(entity)) {
        system5.runInterval(() => {
          if (isValid(entity) && entity.matches(this.queryOptions)) {
            this.push(entity);
          }
        }, 1);
      } else if (entity.matches(this.queryOptions)) {
        this.push(entity);
      }
    } catch (e) {
      _a8.logger.debug(
        "Failed to push entity to scheduler.",
        e
      );
    }
  }
  push(...items) {
    const filtered = items.filter(
      (item) => isValid(item) && !this.items.some(
        (existingItem) => this.compareEntities(existingItem, item)
      )
    );
    return super.push(...filtered);
  }
  unshift(...items) {
    const filtered = items.filter(
      (item) => isValid(item) && !this.items.some(
        (existingItem) => this.compareEntities(existingItem, item)
      )
    );
    return super.unshift(...filtered);
  }
  splice(start, deleteCount, ...items) {
    if (deleteCount === void 0) {
      return super.splice(start);
    }
    const filtered = items.filter(
      (item) => !this.items.some(
        (existingItem) => this.compareEntities(existingItem, item)
      )
    );
    return super.splice(start, deleteCount, ...filtered);
  }
}, __publicField(_a8, "logger", Logger.getLogger(
  "EntityPulseScheduler",
  "bedrock-boost",
  "entity-pulse-scheduler"
)), _a8);
var _a9;
var PlayerPulseScheduler = (_a9 = class extends PulseScheduler {
  /**
   * Creates a new PlayerPulseScheduler instance.
   * @param period The period of the scheduler.
   */
  constructor(processor, period) {
    super((t) => {
      if (isValid(t)) {
        processor(t);
      } else {
        this.removeIf((entity) => !isValid(entity));
      }
    }, period);
    this.push(...world5.getAllPlayers());
  }
  compareEntities(a, b) {
    return a.id === b.id;
  }
  start() {
    world5.afterEvents.playerJoin.subscribe((event) => {
      let attempts = 0;
      const pushPlayer = () => {
        attempts++;
        if (attempts > 10) {
          _a9.logger.debug("Failed to push player to scheduler after 10 attempts.");
          return;
        }
        try {
          const player = world5.getEntity(event.playerId);
          if (player === void 0) {
            system6.runTimeout(pushPlayer, 1);
          }
          if (player instanceof Player2) {
            this.push(player);
          }
        } catch (e) {
          _a9.logger.debug("Failed to push player to scheduler.", e);
          system6.runTimeout(pushPlayer, 1);
        }
      };
      pushPlayer();
    });
    world5.afterEvents.playerLeave.subscribe((event) => {
      this.removeIf((entity) => !isValid(entity) || entity.id === event.playerId);
    });
    super.start();
  }
  push(...items) {
    const filtered = items.filter((item) => isValid(item) && !this.items.some((existingItem) => this.compareEntities(existingItem, item)));
    return super.push(...filtered);
  }
  unshift(...items) {
    const filtered = items.filter((item) => isValid(item) && !this.items.some((existingItem) => this.compareEntities(existingItem, item)));
    return super.unshift(...filtered);
  }
  splice(start, deleteCount, ...items) {
    if (deleteCount === void 0) {
      return super.splice(start);
    }
    const filtered = items.filter((item) => !this.items.some((existingItem) => this.compareEntities(existingItem, item)));
    return super.splice(start, deleteCount, ...filtered);
  }
}, __publicField(_a9, "logger", Logger.getLogger("PlayerPulseScheduler", "bedrock-boost", "player-pulse-scheduler")), _a9);
var _a10;
var DirectionUtils = (_a10 = class {
}, /**
 * The opposite directions of the given directions.
 */
__publicField(_a10, "Opposites", {
  [Direction2.Down]: Direction2.Up,
  [Direction2.Up]: Direction2.Down,
  [Direction2.North]: Direction2.South,
  [Direction2.South]: Direction2.North,
  [Direction2.East]: Direction2.West,
  [Direction2.West]: Direction2.East
}), /**
 * The positive perpendicular directions of the given directions.
 */
__publicField(_a10, "PositivePerpendiculars", {
  [Direction2.Down]: [Direction2.East, Direction2.North],
  [Direction2.Up]: [Direction2.East, Direction2.North],
  [Direction2.North]: [Direction2.East, Direction2.Up],
  [Direction2.South]: [Direction2.East, Direction2.Up],
  [Direction2.East]: [Direction2.North, Direction2.Up],
  [Direction2.West]: [Direction2.North, Direction2.Up]
}), /**
 * The negative perpendicular directions of the given directions.
 */
__publicField(_a10, "NegativePerpendiculars", {
  [Direction2.Down]: [Direction2.West, Direction2.South],
  [Direction2.Up]: [Direction2.West, Direction2.South],
  [Direction2.North]: [Direction2.West, Direction2.Down],
  [Direction2.South]: [Direction2.West, Direction2.Down],
  [Direction2.East]: [Direction2.South, Direction2.Down],
  [Direction2.West]: [Direction2.South, Direction2.Down]
}), /**
 * All directions.
 */
__publicField(_a10, "Values", [
  Direction2.Down,
  Direction2.Up,
  Direction2.North,
  Direction2.South,
  Direction2.East,
  Direction2.West
]), _a10);
var log2 = Logger.getLogger("itemUtils", "bedrock-boost", "itemUtils");

// data/system_template_esbuild/subscripts/drone_camera.ts
var DATA = { "speed_horizontal_modifier": 1, "speed_vertical_modifier": 0.25 };
var dronesList = /* @__PURE__ */ new Set();
system8.afterEvents.scriptEventReceive.subscribe((event) => {
  const { message, id, sourceEntity } = event;
  if (id === "cbcl_secam:drone_camera" && message === "rider" && sourceEntity) {
    dronesList.add(sourceEntity);
  }
});
system8.afterEvents.scriptEventReceive.subscribe((event) => {
  const { message, id, sourceEntity } = event;
  if (id === "cbcl_secam:drone_camera" && message === "no_rider" && sourceEntity) {
    dronesList.delete(sourceEntity);
  }
});
system8.runInterval(() => {
  dronesList.forEach((droneCamera) => {
    const rideableComp = droneCamera.getComponent(EntityComponentTypes.Rideable);
    if (droneCamera && rideableComp.getRiders().length > 0) {
      if (droneCamera.isOnGround) {
        droneCamera.addEffect("slowness", 1, {
          amplifier: Math.round(4 * DATA.speed_horizontal_modifier),
          showParticles: false
        });
      }
      const controllingRider = rideableComp.getRiders()[0];
      droneCamera.addEffect("levitation", 2, {
        amplifier: 0,
        showParticles: false
      });
      const direction = Vec3.from(controllingRider.getViewDirection()).setX(0).setZ(0).multiply(0.25).multiply(DATA.speed_vertical_modifier);
      droneCamera.applyImpulse(direction);
    }
  });
}, 1);

// data/system_template_esbuild/subscripts/events.ts
import {
  system as system12,
  world as world11,
  Player as Player7,
  EntityComponentTypes as EntityComponentTypes5,
  Direction as Direction3,
  EntityDamageCause,
  TicksPerSecond
} from "@minecraft/server";

// data/system_template_esbuild/subscripts/camera.ts
import {
  world as world9,
  system as system10,
  EntityComponentTypes as EntityComponentTypes3,
  InputPermissionCategory as InputPermissionCategory3,
  EquipmentSlot as EquipmentSlot3,
  ItemLockMode as ItemLockMode2,
  ItemStack as ItemStack2,
  GameMode as GameMode2
} from "@minecraft/server";

// data/system_template_esbuild/subscripts/interfaces.ts
var GlobalSettingsTemplate = {
  // These need to be simple types. If you use objects, updating might break
  allowTeleport: true
};

// data/system_template_esbuild/subscripts/utilities.ts
import {
  PlayerPermissionLevel,
  world as world8,
  Player as Player4,
  EntityComponentTypes as EntityComponentTypes2,
  EquipmentSlot as EquipmentSlot2,
  ItemStack,
  ItemLockMode,
  InputPermissionCategory as InputPermissionCategory2,
  system as system9,
  GameMode
} from "@minecraft/server";

// data/system_template_esbuild/subscripts/data.ts
var ACTIVITY_LOG_COOLDOWN = 30 * 20;
var ACTIVITY_LOG_LENGTH = 100;
var DATA2 = [{ "identifier": "block_camera", "ui_color_code": "\xA71", "placing_position": "floor", "recipe": { "pattern": ["AAA", "ABA", "AAA"], "key": { "A": { "item": "minecraft:glass" }, "B": { "item": "cbcl_secam:lens" } }, "unlock": [{ "item": "minecraft:glass" }, { "item": "cbcl_secam:lens" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0], "lock_rider_rotation": 90, "rotate_rider_by": 0 }, "distance": 20, "max_y_rotation": 90, "max_x_rotation": 60, "has_gravity": false }, { "identifier": "dome_camera", "ui_color_code": "\xA77", "placing_position": "floor_and_ceiling", "recipe": { "pattern": ["BCB", "ABA", "   "], "key": { "A": { "item": "cbcl_secam:copper_wire" }, "B": { "item": "cbcl_secam:iron_casing" }, "C": { "item": "cbcl_secam:lens" } }, "unlock": [{ "item": "cbcl_secam:copper_wire" }, { "item": "cbcl_secam:iron_casing" }, { "item": "cbcl_secam:lens" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0], "lock_rider_rotation": 360, "rotate_rider_by": 0 }, "distance": 20, "max_y_rotation": 180, "max_x_rotation": 90, "has_gravity": false }, { "identifier": "drone_camera", "ui_color_code": "\xA78", "placing_position": "floor", "recipe": { "pattern": ["ABA", "BBB", "BCB"], "key": { "A": { "item": "cbcl_secam:propeller" }, "B": { "item": "cbcl_secam:iron_casing" }, "C": { "item": "cbcl_secam:lens" } }, "unlock": [{ "item": "cbcl_secam:propeller" }, { "item": "cbcl_secam:iron_casing" }, { "item": "cbcl_secam:lens" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0] }, "distance": 20, "max_y_rotation": 180, "max_x_rotation": 90, "has_gravity": true }, { "identifier": "mob_camera", "ui_color_code": "\xA73", "placing_position": "floor", "recipe": { "pattern": ["ABA", "DCD", "DDD"], "key": { "A": { "item": "minecraft:bone" }, "B": { "item": "minecraft:slime_ball" }, "C": { "item": "cbcl_secam:lens" }, "D": { "item": "minecraft:leather" } }, "unlock": [{ "item": "minecraft:bone" }, { "item": "minecraft:slime_ball" }, { "item": "cbcl_secam:lens" }, { "item": "minecraft:leather" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0], "rotate_rider_by": 0 }, "distance": 20, "max_y_rotation": 180, "max_x_rotation": 90, "has_gravity": false }, { "identifier": "night_vision_camera", "ui_color_code": "\xA76", "placing_position": "wall", "recipe": { "pattern": ["A  ", "CB ", "BD "], "key": { "A": { "item": "minecraft:glow_ink_sac" }, "B": { "item": "cbcl_secam:iron_casing" }, "C": { "item": "cbcl_secam:lens" }, "D": { "item": "cbcl_secam:copper_wire" } }, "unlock": [{ "item": "minecraft:glow_ink_sac" }, { "item": "cbcl_secam:iron_casing" }, { "item": "cbcl_secam:lens" }, { "item": "cbcl_secam:copper_wire" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0], "lock_rider_rotation": 90, "rotate_rider_by": 0 }, "distance": 20, "max_y_rotation": 90, "max_x_rotation": 60, "has_gravity": false }, { "identifier": "plushie_camera", "ui_color_code": "\xA7b", "placing_position": "floor", "recipe": { "pattern": ["AAA", "ABA", "AAA"], "key": { "A": { "item": "minecraft:wool" }, "B": { "item": "cbcl_secam:lens" } }, "unlock": [{ "item": "minecraft:wool" }, { "item": "cbcl_secam:lens" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0], "lock_rider_rotation": 90, "rotate_rider_by": 0 }, "distance": 20, "max_y_rotation": 90, "max_x_rotation": 60, "has_gravity": false }, { "identifier": "sentry_camera", "ui_color_code": "\xA79", "placing_position": "ceiling", "recipe": { "pattern": ["DAD", "BCB", "EBE"], "key": { "A": { "item": "cbcl_secam:processor" }, "B": { "item": "cbcl_secam:iron_casing" }, "C": { "item": "cbcl_secam:lens" }, "D": { "item": "cbcl_secam:copper_wire" }, "E": { "item": "minecraft:dispenser" } }, "unlock": [{ "item": "cbcl_secam:processor" }, { "item": "cbcl_secam:iron_casing" }, { "item": "cbcl_secam:lens" }, { "item": "cbcl_secam:copper_wire" }, { "item": "minecraft:dispenser" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0], "rotate_rider_by": 0 }, "distance": 20, "max_y_rotation": 180, "max_x_rotation": 90, "has_gravity": false }, { "identifier": "standard_camera", "ui_color_code": "\xA7e", "placing_position": "wall", "recipe": { "pattern": ["BA ", "CB ", "B  "], "key": { "A": { "item": "cbcl_secam:copper_wire" }, "B": { "item": "cbcl_secam:iron_casing" }, "C": { "item": "cbcl_secam:lens" } }, "unlock": [{ "item": "cbcl_secam:copper_wire" }, { "item": "cbcl_secam:iron_casing" }, { "item": "cbcl_secam:lens" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0], "lock_rider_rotation": 90, "rotate_rider_by": 0 }, "distance": 20, "max_y_rotation": 90, "max_x_rotation": 60, "has_gravity": false }, { "identifier": "thermal_camera", "ui_color_code": "\xA7c", "placing_position": "wall", "recipe": { "pattern": ["AB ", "CCB", "BB "], "key": { "A": { "item": "cbcl_secam:processor" }, "B": { "item": "cbcl_secam:iron_casing" }, "C": { "item": "cbcl_secam:lens" } }, "unlock": [{ "item": "cbcl_secam:processor" }, { "item": "cbcl_secam:iron_casing" }, { "item": "cbcl_secam:lens" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0], "lock_rider_rotation": 90, "rotate_rider_by": 0 }, "distance": 20, "max_y_rotation": 90, "max_x_rotation": 60, "has_gravity": false }, { "identifier": "uv_camera", "ui_color_code": "\xA7d", "placing_position": "wall", "recipe": { "pattern": ["AB ", "CDB", "BB "], "key": { "A": { "item": "cbcl_secam:processor" }, "B": { "item": "cbcl_secam:iron_casing" }, "C": { "item": "cbcl_secam:lens" }, "D": { "item": "minecraft:amethyst_shard" } }, "unlock": [{ "item": "cbcl_secam:processor" }, { "item": "cbcl_secam:iron_casing" }, { "item": "cbcl_secam:lens" }, { "item": "minecraft:amethyst_shard" }, { "item": "cbcl_secam:fabricator" }] }, "custom_hit_test": { "hitboxes": [{ "width": 1, "height": 1, "pivot": [0, 0.5, 0] }] }, "rideable_seats": { "position": [0, -0.5, 0], "lock_rider_rotation": 90, "rotate_rider_by": 0 }, "distance": 20, "max_y_rotation": 90, "max_x_rotation": 60, "has_gravity": false }];
var BLOCK_CAMERA_BLOCKS = [{ "identifier": "planks_acacia", "command_identifier": "acacia_planks", "lang_key": "tile.planks.acacia.name", "top": "textures/blocks/planks_acacia", "bottom": "textures/blocks/planks_acacia", "north": "textures/blocks/planks_acacia", "south": "textures/blocks/planks_acacia", "east": "textures/blocks/planks_acacia", "west": "textures/blocks/planks_acacia" }, { "identifier": "planks_big_oak", "command_identifier": "dark_oak_planks", "lang_key": "tile.planks.big_oak.name", "top": "textures/blocks/planks_big_oak", "bottom": "textures/blocks/planks_big_oak", "north": "textures/blocks/planks_big_oak", "south": "textures/blocks/planks_big_oak", "east": "textures/blocks/planks_big_oak", "west": "textures/blocks/planks_big_oak" }, { "identifier": "planks_birch", "command_identifier": "birch_planks", "lang_key": "tile.planks.birch.name", "top": "textures/blocks/planks_birch", "bottom": "textures/blocks/planks_birch", "north": "textures/blocks/planks_birch", "south": "textures/blocks/planks_birch", "east": "textures/blocks/planks_birch", "west": "textures/blocks/planks_birch" }, { "identifier": "planks_jungle", "command_identifier": "jungle_planks", "lang_key": "tile.planks.jungle.name", "top": "textures/blocks/planks_jungle", "bottom": "textures/blocks/planks_jungle", "north": "textures/blocks/planks_jungle", "south": "textures/blocks/planks_jungle", "east": "textures/blocks/planks_jungle", "west": "textures/blocks/planks_jungle" }, { "identifier": "planks_oak", "command_identifier": "oak_planks", "lang_key": "tile.planks.oak.name", "top": "textures/blocks/planks_oak", "bottom": "textures/blocks/planks_oak", "north": "textures/blocks/planks_oak", "south": "textures/blocks/planks_oak", "east": "textures/blocks/planks_oak", "west": "textures/blocks/planks_oak" }, { "identifier": "planks_spruce", "command_identifier": "spruce_planks", "lang_key": "tile.planks.spruce.name", "top": "textures/blocks/planks_spruce", "bottom": "textures/blocks/planks_spruce", "north": "textures/blocks/planks_spruce", "south": "textures/blocks/planks_spruce", "east": "textures/blocks/planks_spruce", "west": "textures/blocks/planks_spruce" }, { "identifier": "mangrove_planks", "command_identifier": "mangrove_planks", "lang_key": "tile.mangrove_planks.name", "top": "textures/blocks/mangrove_planks", "bottom": "textures/blocks/mangrove_planks", "north": "textures/blocks/mangrove_planks", "south": "textures/blocks/mangrove_planks", "east": "textures/blocks/mangrove_planks", "west": "textures/blocks/mangrove_planks" }, { "identifier": "cherry_planks", "command_identifier": "cherry_planks", "lang_key": "tile.cherry_planks.name", "top": "textures/blocks/cherry_planks", "bottom": "textures/blocks/cherry_planks", "north": "textures/blocks/cherry_planks", "south": "textures/blocks/cherry_planks", "east": "textures/blocks/cherry_planks", "west": "textures/blocks/cherry_planks" }, { "identifier": "pale_oak_planks", "command_identifier": "pale_oak_planks", "lang_key": "tile.pale_oak_planks.name", "top": "textures/blocks/pale_oak_planks", "bottom": "textures/blocks/pale_oak_planks", "north": "textures/blocks/pale_oak_planks", "south": "textures/blocks/pale_oak_planks", "east": "textures/blocks/pale_oak_planks", "west": "textures/blocks/pale_oak_planks" }, { "identifier": "bamboo_planks", "command_identifier": "bamboo_planks", "lang_key": "tile.bamboo_planks.name", "top": "textures/blocks/bamboo_planks", "bottom": "textures/blocks/bamboo_planks", "north": "textures/blocks/bamboo_planks", "south": "textures/blocks/bamboo_planks", "east": "textures/blocks/bamboo_planks", "west": "textures/blocks/bamboo_planks" }, { "identifier": "crimson_planks", "command_identifier": "crimson_planks", "lang_key": "tile.crimson_planks.name", "top": "textures/blocks/huge_fungus/crimson_planks", "bottom": "textures/blocks/huge_fungus/crimson_planks", "north": "textures/blocks/huge_fungus/crimson_planks", "south": "textures/blocks/huge_fungus/crimson_planks", "east": "textures/blocks/huge_fungus/crimson_planks", "west": "textures/blocks/huge_fungus/crimson_planks" }, { "identifier": "warped_planks", "command_identifier": "warped_planks", "lang_key": "tile.warped_planks.name", "top": "textures/blocks/huge_fungus/warped_planks", "bottom": "textures/blocks/huge_fungus/warped_planks", "north": "textures/blocks/huge_fungus/warped_planks", "south": "textures/blocks/huge_fungus/warped_planks", "east": "textures/blocks/huge_fungus/warped_planks", "west": "textures/blocks/huge_fungus/warped_planks" }, { "identifier": "dirt", "command_identifier": "dirt", "lang_key": "tile.dirt.name", "top": "textures/blocks/dirt", "bottom": "textures/blocks/dirt", "north": "textures/blocks/dirt", "south": "textures/blocks/dirt", "east": "textures/blocks/dirt", "west": "textures/blocks/dirt" }, { "identifier": "sand", "command_identifier": "sand", "lang_key": "tile.sand.name", "top": "textures/blocks/sand", "bottom": "textures/blocks/sand", "north": "textures/blocks/sand", "south": "textures/blocks/sand", "east": "textures/blocks/sand", "west": "textures/blocks/sand" }, { "identifier": "stone", "command_identifier": "stone", "lang_key": "tile.stone.stone.name", "top": "textures/blocks/stone", "bottom": "textures/blocks/stone", "north": "textures/blocks/stone", "south": "textures/blocks/stone", "east": "textures/blocks/stone", "west": "textures/blocks/stone" }, { "identifier": "cobblestone", "command_identifier": "cobblestone", "lang_key": "tile.cobblestone.name", "top": "textures/blocks/cobblestone", "bottom": "textures/blocks/cobblestone", "north": "textures/blocks/cobblestone", "south": "textures/blocks/cobblestone", "east": "textures/blocks/cobblestone", "west": "textures/blocks/cobblestone" }, { "identifier": "cobblestone_mossy", "command_identifier": "mossy_cobblestone", "lang_key": "tile.mossy_cobblestone.name", "top": "textures/blocks/cobblestone_mossy", "bottom": "textures/blocks/cobblestone_mossy", "north": "textures/blocks/cobblestone_mossy", "south": "textures/blocks/cobblestone_mossy", "east": "textures/blocks/cobblestone_mossy", "west": "textures/blocks/cobblestone_mossy" }, { "identifier": "granite", "command_identifier": "granite", "lang_key": "tile.stone.granite.name", "top": "textures/blocks/stone_granite", "bottom": "textures/blocks/stone_granite", "north": "textures/blocks/stone_granite", "south": "textures/blocks/stone_granite", "east": "textures/blocks/stone_granite", "west": "textures/blocks/stone_granite" }, { "identifier": "diorite", "command_identifier": "diorite", "lang_key": "tile.stone.diorite.name", "top": "textures/blocks/stone_diorite", "bottom": "textures/blocks/stone_diorite", "north": "textures/blocks/stone_diorite", "south": "textures/blocks/stone_diorite", "east": "textures/blocks/stone_diorite", "west": "textures/blocks/stone_diorite" }, { "identifier": "granite_smooth", "command_identifier": "polished_granite", "lang_key": "tile.stone.graniteSmooth.name", "top": "textures/blocks/stone_granite_smooth", "bottom": "textures/blocks/stone_granite_smooth", "north": "textures/blocks/stone_granite_smooth", "south": "textures/blocks/stone_granite_smooth", "east": "textures/blocks/stone_granite_smooth", "west": "textures/blocks/stone_granite_smooth" }, { "identifier": "diorite_smooth", "command_identifier": "polished_diorite", "lang_key": "tile.stone.dioriteSmooth.name", "top": "textures/blocks/stone_diorite_smooth", "bottom": "textures/blocks/stone_diorite_smooth", "north": "textures/blocks/stone_diorite_smooth", "south": "textures/blocks/stone_diorite_smooth", "east": "textures/blocks/stone_diorite_smooth", "west": "textures/blocks/stone_diorite_smooth" }, { "identifier": "andesite", "command_identifier": "andesite", "lang_key": "tile.stone.andesite.name", "top": "textures/blocks/stone_andesite", "bottom": "textures/blocks/stone_andesite", "north": "textures/blocks/stone_andesite", "south": "textures/blocks/stone_andesite", "east": "textures/blocks/stone_andesite", "west": "textures/blocks/stone_andesite" }, { "identifier": "andesite_smooth", "command_identifier": "polished_andesite", "lang_key": "tile.stone.andesiteSmooth.name", "top": "textures/blocks/stone_andesite_smooth", "bottom": "textures/blocks/stone_andesite_smooth", "north": "textures/blocks/stone_andesite_smooth", "south": "textures/blocks/stone_andesite_smooth", "east": "textures/blocks/stone_andesite_smooth", "west": "textures/blocks/stone_andesite_smooth" }, { "identifier": "log_acacia", "command_identifier": "acacia_log", "lang_key": "tile.log.acacia.name", "top": "textures/blocks/log_acacia_top", "bottom": "textures/blocks/log_acacia_top", "north": "textures/blocks/log_acacia", "south": "textures/blocks/log_acacia", "east": "textures/blocks/log_acacia", "west": "textures/blocks/log_acacia" }, { "identifier": "log_birch", "command_identifier": "birch_log", "lang_key": "tile.log.birch.name", "top": "textures/blocks/log_birch_top", "bottom": "textures/blocks/log_birch_top", "north": "textures/blocks/log_birch", "south": "textures/blocks/log_birch", "east": "textures/blocks/log_birch", "west": "textures/blocks/log_birch" }, { "identifier": "log_jungle", "command_identifier": "jungle_log", "lang_key": "tile.log.jungle.name", "top": "textures/blocks/log_jungle_top", "bottom": "textures/blocks/log_jungle_top", "north": "textures/blocks/log_jungle", "south": "textures/blocks/log_jungle", "east": "textures/blocks/log_jungle", "west": "textures/blocks/log_jungle" }, { "identifier": "log_oak", "command_identifier": "oak_log", "lang_key": "tile.log.oak.name", "top": "textures/blocks/log_oak_top", "bottom": "textures/blocks/log_oak_top", "north": "textures/blocks/log_oak", "south": "textures/blocks/log_oak", "east": "textures/blocks/log_oak", "west": "textures/blocks/log_oak" }, { "identifier": "log_spruce", "command_identifier": "spruce_log", "lang_key": "tile.log.spruce.name", "top": "textures/blocks/log_spruce_top", "bottom": "textures/blocks/log_spruce_top", "north": "textures/blocks/log_spruce", "south": "textures/blocks/log_spruce", "east": "textures/blocks/log_spruce", "west": "textures/blocks/log_spruce" }, { "identifier": "cherry_log", "command_identifier": "cherry_log", "lang_key": "tile.cherry_log.name", "top": "textures/blocks/cherry_log_top", "bottom": "textures/blocks/cherry_log_top", "north": "textures/blocks/cherry_log_side", "south": "textures/blocks/cherry_log_side", "east": "textures/blocks/cherry_log_side", "west": "textures/blocks/cherry_log_side" }, { "identifier": "mangrove_log", "command_identifier": "mangrove_log", "lang_key": "tile.mangrove_log.name", "top": "textures/blocks/mangrove_log_top", "bottom": "textures/blocks/mangrove_log_top", "north": "textures/blocks/mangrove_log_side", "south": "textures/blocks/mangrove_log_side", "east": "textures/blocks/mangrove_log_side", "west": "textures/blocks/mangrove_log_side" }, { "identifier": "log_big_oak", "command_identifier": "dark_oak_log", "lang_key": "tile.log.big_oak.name", "top": "textures/blocks/log_big_oak_top", "bottom": "textures/blocks/log_big_oak_top", "north": "textures/blocks/log_big_oak", "south": "textures/blocks/log_big_oak", "east": "textures/blocks/log_big_oak", "west": "textures/blocks/log_big_oak" }, { "identifier": "pale_oak_log", "command_identifier": "pale_oak_log", "lang_key": "tile.pale_oak_log.name", "top": "textures/blocks/pale_oak_log_top", "bottom": "textures/blocks/pale_oak_log_top", "north": "textures/blocks/pale_oak_log_side", "south": "textures/blocks/pale_oak_log_side", "east": "textures/blocks/pale_oak_log_side", "west": "textures/blocks/pale_oak_log_side" }, { "identifier": "bookshelf", "command_identifier": "bookshelf", "lang_key": "tile.bookshelf.name", "top": "textures/blocks/planks_oak", "bottom": "textures/blocks/planks_oak", "north": "textures/blocks/bookshelf", "south": "textures/blocks/bookshelf", "east": "textures/blocks/bookshelf", "west": "textures/blocks/bookshelf" }, { "identifier": "chiseled_bookshelf", "command_identifier": "chiseled_bookshelf", "lang_key": "tile.chiseled_bookshelf.name", "top": "textures/blocks/chiseled_bookshelf_top", "bottom": "textures/blocks/chiseled_bookshelf_top", "north": "textures/blocks/chiseled_bookshelf_occupied", "south": "textures/blocks/chiseled_bookshelf_side", "east": "textures/blocks/chiseled_bookshelf_side", "west": "textures/blocks/chiseled_bookshelf_side" }, { "identifier": "barrel", "command_identifier": "barrel", "lang_key": "tile.barrel.name", "top": "textures/blocks/barrel_top", "bottom": "textures/blocks/barrel_bottom", "north": "textures/blocks/barrel_side", "south": "textures/blocks/barrel_side", "east": "textures/blocks/barrel_side", "west": "textures/blocks/barrel_side" }];
var MOB_CAMERA_MOBS = [{ "identifier": "chicken", "lang_key": "entity.chicken.name" }, { "identifier": "cow", "lang_key": "entity.cow.name" }, { "identifier": "pig", "lang_key": "entity.pig.name" }, { "identifier": "sheep", "lang_key": "entity.sheep.name" }, { "identifier": "rabbit", "lang_key": "entity.rabbit.name" }, { "identifier": "creeper", "lang_key": "entity.creeper.name" }, { "identifier": "villager", "lang_key": "entity.villager.name" }];
var PLUSHIE_CAMERA_PLUSHIES = [{ "identifier": "panda", "lang_key": "cbcl_secam.ui.specific_security_camera_settings_plushie_type_menu.panda" }, { "identifier": "bunny", "lang_key": "cbcl_secam.ui.specific_security_camera_settings_plushie_type_menu.bunny" }, { "identifier": "bear", "lang_key": "cbcl_secam.ui.specific_security_camera_settings_plushie_type_menu.bear" }];
var SENTRY_CAMERA_PROJECTILES = [{ "identifier": "cbcl_secam:sentry_proj_0", "lang_key": "entity.cbcl_secam:sentry_proj_0.name" }, { "identifier": "cbcl_secam:sentry_proj_1", "lang_key": "entity.cbcl_secam:sentry_proj_1.name" }, { "identifier": "cbcl_secam:sentry_proj_2", "lang_key": "entity.cbcl_secam:sentry_proj_2.name" }];

// data/system_template_esbuild/subscripts/utilities.ts
var OFFHAND_ITEMS = /* @__PURE__ */ new Map();
function getHeldItem(player) {
  const equipmentCompPlayer = player.getComponent(EntityComponentTypes2.Equippable);
  if (!equipmentCompPlayer)
    return;
  return equipmentCompPlayer.getEquipment(EquipmentSlot2.Mainhand);
}
function getOffhandItem(player) {
  const equipmentCompPlayer = player.getComponent(EntityComponentTypes2.Equippable);
  if (!equipmentCompPlayer)
    return;
  return equipmentCompPlayer.getEquipment(EquipmentSlot2.Offhand);
}
function lockCameraTablets(player) {
  let inventory = player.getComponent("inventory");
  if (!inventory)
    return;
  const container = inventory.container;
  if (!container)
    return;
  for (let i = 0; i < container.size; i++) {
    let item = container.getItem(i);
    if (item === void 0)
      continue;
    if (item.typeId === "cbcl_secam:camera_tablet") {
      const newItem = new ItemStack(`cbcl_secam:camera_tablet`, 1);
      newItem.lockMode = ItemLockMode.slot;
      container.setItem(i, newItem);
    }
  }
}
function unlockCameraTablets(player) {
  let inventory = player.getComponent("inventory");
  if (!inventory)
    return;
  const container = inventory.container;
  if (!container)
    return;
  for (let i = 0; i < container.size; i++) {
    let item = container.getItem(i);
    if (item === void 0)
      continue;
    if (item.typeId === "cbcl_secam:camera_tablet") {
      const newItem = new ItemStack(`cbcl_secam:camera_tablet`, 1);
      newItem.lockMode = ItemLockMode.none;
      container.setItem(i, newItem);
    }
  }
}
function replaceItem(player, slot, itemStack, lockMode) {
  const equipmentCompPlayer = player.getComponent(EntityComponentTypes2.Equippable);
  if (!equipmentCompPlayer)
    return;
  if (itemStack instanceof ItemStack) {
    itemStack.lockMode = lockMode;
  } else {
    itemStack = void 0;
  }
  equipmentCompPlayer.setEquipment(slot, itemStack);
}
function getInviteProperty(player) {
  let property = world8.getDynamicProperty(`${player.id}_invitations`);
  if (!property) {
    return void 0;
  }
  let invitationsArray = [];
  try {
    invitationsArray = JSON.parse(property);
  } catch {
  }
  if (invitationsArray.length > 0) {
    return invitationsArray[0];
  }
  return void 0;
}
function checkRank(securityCamera, player) {
  let members = securityCamera.getMembers();
  if (members.size != 0 && members.has(player.id)) {
    return members.get(player.id)?.rank;
  } else {
    return "no_access" /* NoAccess */;
  }
}
function checkInviteProperty(player, securityCameraID) {
  let property = world8.getDynamicProperty(`${player.id}_invitations`);
  if (!property) {
    return false;
  }
  let invitationsArray = [];
  try {
    invitationsArray = JSON.parse(property);
  } catch {
  }
  return invitationsArray.some((invite) => invite.id === securityCameraID);
}
function inviteVFX(invitingPlayer, invitedPlayer, securityCameraName) {
  invitingPlayer.playSound("note.bell");
  invitedPlayer.playSound("note.bell");
  invitingPlayer.sendMessage({
    translate: "cbcl_secam.ui.specific_security_camera_settings_members_invite_confirm_menu.inviting_0"
  });
  invitingPlayer.sendMessage([
    `\xA7a${invitedPlayer.name}\xA7r`,
    ` `,
    {
      translate: `cbcl_secam.ui.specific_security_camera_settings_members_invite_confirm_menu.inviting_1`
    }
  ]);
  invitedPlayer.sendMessage({
    translate: "cbcl_secam.ui.specific_security_camera_settings_members_invite_confirm_menu.invited_0"
  });
  invitedPlayer.sendMessage([
    {
      translate: "cbcl_secam.ui.specific_security_camera_settings_members_invite_confirm_menu.invited_1"
    },
    ` `,
    `\xA7e${securityCameraName}\xA7r`,
    ` `,
    {
      translate: "cbcl_secam.ui.specific_security_camera_settings_members_invite_confirm_menu.invited_2"
    },
    ` `,
    `\xA7e${invitingPlayer.name}\xA7r`,
    ` `,
    {
      translate: "cbcl_secam.ui.specific_security_camera_settings_members_invite_confirm_menu.invited_3"
    }
  ]);
}
function addInviteProperty(player, chosenRank, securityCameraID) {
  let property = world8.getDynamicProperty(`${player.id}_invitations`);
  let invitationsArray = [];
  if (!property) {
    invitationsArray = [];
  } else {
    try {
      invitationsArray = JSON.parse(property);
    } catch {
    }
  }
  if (!checkInviteProperty(player, securityCameraID)) {
    invitationsArray.push({
      id: securityCameraID,
      name: player.name,
      rank: chosenRank
    });
    let invitationsArrayString = JSON.stringify(invitationsArray);
    world8.setDynamicProperty(`${player.id}_invitations`, invitationsArrayString);
  }
}
function removeInviteProperty(player, securityCameraID) {
  let property = world8.getDynamicProperty(`${player.id}_invitations`);
  if (property === void 0) {
    return;
  }
  let invitationsArray = [];
  try {
    invitationsArray = JSON.parse(property);
  } catch {
  }
  invitationsArray = invitationsArray.filter((invite) => invite.id !== securityCameraID);
  let invitationsArrayString = JSON.stringify(invitationsArray);
  world8.setDynamicProperty(`${player.id}_invitations`, invitationsArrayString);
}
function exitCamera(player, viewSettingsObject, viewSettingsPropertyID) {
  let block;
  try {
    block = player.dimension.getBlock(player.location);
  } catch {
    system9.runTimeout(() => {
      if (player) {
        exitCamera(player, viewSettingsObject, viewSettingsPropertyID);
      }
    }, 5);
    return;
  }
  if (!block) {
    system9.runTimeout(() => {
      if (player) {
        exitCamera(player, viewSettingsObject, viewSettingsPropertyID);
      }
    }, 5);
    return;
  }
  const fadeTime = {
    fadeInTime: 0.25,
    holdTime: 0.5,
    fadeOutTime: 0.25
  };
  const delay = (fadeTime.fadeInTime + 0.25) * 20;
  const color = {
    red: 0,
    green: 0,
    blue: 0
  };
  player.camera.fade({
    fadeColor: color,
    fadeTime
  });
  system9.runTimeout(() => {
    if (!player)
      return;
    let gameMode = GameMode.Survival;
    switch (viewSettingsObject.gameMode) {
      case "survival":
        gameMode = GameMode.Survival;
        break;
      case "creative":
        gameMode = GameMode.Creative;
        break;
      case "spectator":
        gameMode = GameMode.Spectator;
        break;
      case "adventure":
        gameMode = GameMode.Adventure;
        break;
    }
    player.setGameMode(gameMode);
    player.extinguishFire();
    player.onScreenDisplay.resetHudElementsVisibility();
    player.removeTag("cbcl_secam_VIEWING_CAMERA");
    player.runCommand(`/ride @s stop_riding`);
    const { location, rotation, dimensionID } = viewSettingsObject;
    const dimension = world8.getDimension(dimensionID);
    player.teleport(location, { rotation, dimension });
    let oldItemStack = void 0;
    if (OFFHAND_ITEMS.has(player.id)) {
      oldItemStack = OFFHAND_ITEMS.get(player.id);
    } else {
      if (viewSettingsObject.itemTypeId !== void 0) {
        oldItemStack = new ItemStack(viewSettingsObject.itemTypeId, 1);
      }
    }
    replaceItem(player, EquipmentSlot2.Offhand, oldItemStack, ItemLockMode.none);
    unlockCameraTablets(player);
    player.inputPermissions.setPermissionCategory(InputPermissionCategory2.Dismount, true);
    player.inputPermissions.setPermissionCategory(InputPermissionCategory2.Jump, true);
    player.inputPermissions.setPermissionCategory(InputPermissionCategory2.Sneak, true);
    player.inputPermissions.setPermissionCategory(InputPermissionCategory2.Movement, true);
    player.inputPermissions.setPermissionCategory(InputPermissionCategory2.LateralMovement, true);
    player.camera.clear();
    player.removeEffect("minecraft:night_vision");
    player.removeEffect("minecraft:resistance");
    player.removeEffect("minecraft:invisibility");
    player.playSound(`cbcl_secam.exit_camera`, {
      location: player.location,
      volume: 1,
      pitch: 1
    });
    world8.setDynamicProperty(viewSettingsPropertyID, void 0);
    system9.runTimeout(() => {
      if (player.isValid) {
        player.applyKnockback({ x: 0, z: 0 }, 0.1);
      }
    }, 1);
  }, delay);
}
function getNextCamera(player, currentCameraID) {
  let camerasIDs = SecurityCamera.getPlayerSecurityCameras(player, false, false);
  const index = camerasIDs.findIndex((cameraID) => cameraID === currentCameraID);
  let nextIndex = index + 1 > camerasIDs.length - 1 ? 0 : index + 1;
  const propertyValue = world8.getDynamicProperty(camerasIDs[nextIndex]);
  return SecurityCamera.fromJSON(propertyValue);
}
function getPreviousCamera(player, currentCameraID) {
  let camerasIDs = SecurityCamera.getPlayerSecurityCameras(player, false, false);
  const index = camerasIDs.findIndex((cameraID) => cameraID === currentCameraID);
  let previousIndex = index - 1 < 0 ? camerasIDs.length - 1 : index - 1;
  const propertyValue = world8.getDynamicProperty(camerasIDs[previousIndex]);
  return SecurityCamera.fromJSON(propertyValue);
}
function setViewSettings(player, currentCameraID, currentCameraType, dimensionID, itemTypeId, location, rotation, gameMode) {
  const viewSettings = {
    currentCameraID,
    currentCameraType,
    dimensionID,
    itemTypeId,
    location,
    rotation,
    gameMode
  };
  const viewSettingsString = JSON.stringify(viewSettings);
  world8.setDynamicProperty(`player_(${player.id})_view_settings_EXCLUDE`, viewSettingsString);
}
function activityLog(sourceEntity, DEBUG2) {
  const { id, typeId } = sourceEntity;
  const cameraData = DATA2.find((data) => data.identifier === typeId.replace("cbcl_secam:", "")) ?? DATA2[0];
  const entities = sourceEntity.getEntitiesFromViewDirection({
    maxDistance: cameraData.distance
  });
  if (entities.length === 0)
    return;
  const localPlayersList = sourceEntity.getDynamicProperty(`${id}_activity_players_list_EXCLUDE`);
  let noticedPlayers = [];
  if (localPlayersList) {
    noticedPlayers = JSON.parse(localPlayersList);
  }
  let changed = false;
  let securityCameraObject = getCameraObject(sourceEntity);
  if (!securityCameraObject)
    return;
  let cameraShoot = false;
  for (const { entity } of entities) {
    if (entity instanceof Player4) {
      const playerId = entity.id;
      const player = entity;
      const existing = noticedPlayers.find((p) => p.id === playerId);
      const isWhitelisted = securityCameraObject.getMembers().has(player.name);
      if (securityCameraObject.checkOwnerOrAdmin(player) || securityCameraObject.getMovementNotifications().excludeWhitelist === true && isWhitelisted) {
        continue;
      }
      if (securityCameraObject.getShootPlayers()) {
        cameraShoot = true;
      }
      if (existing !== void 0 && system9.currentTick - existing.currentTick > ACTIVITY_LOG_COOLDOWN) {
        noticedPlayers = noticedPlayers.filter((p) => p.id !== playerId);
        changed = true;
      } else if (existing === void 0) {
        changed = true;
        if (DEBUG2)
          world8.sendMessage("NOTICED PLAYER");
        const activityLogProperty = world8.getDynamicProperty(`${securityCameraObject.getOwnerID()}_activity_logs_EXCLUDE`);
        if (securityCameraObject.getMovementNotifications().message) {
          const playerToMessage = world8.getEntity(securityCameraObject.getOwnerID());
          if (playerToMessage) {
            playerToMessage.playSound("note.bass", {
              location: playerToMessage.location
            });
            playerToMessage.sendMessage([
              {
                translate: `cbcl_secam.ui.activity_logs.camera_type.` + securityCameraObject.getEntityTypeID()
              },
              { text: " " },
              { text: '"' },
              { translate: securityCameraObject.getSecurityCameraName() },
              { text: '"' },
              { text: " " },
              { translate: `cbcl_secam.ui.activity_logs.log.0` },
              { text: "\n\n" }
            ]);
          }
        }
        if (securityCameraObject.getMovementNotifications().logs) {
          let logs = [];
          if (activityLogProperty !== void 0) {
            logs = JSON.parse(activityLogProperty);
          }
          const newActivityLog = {
            time: (/* @__PURE__ */ new Date()).toISOString(),
            cameraName: securityCameraObject.getSecurityCameraName(),
            cameraType: securityCameraObject.getEntityTypeID()
          };
          logs.unshift(newActivityLog);
          if (logs.length > ACTIVITY_LOG_LENGTH)
            logs.length = ACTIVITY_LOG_LENGTH;
          world8.setDynamicProperty(`${securityCameraObject.getOwnerID()}_activity_logs_EXCLUDE`, JSON.stringify(logs));
        }
        noticedPlayers.push({
          id: playerId,
          currentTick: system9.currentTick
        });
      }
    } else {
      const familiesToShoot = ["monster", "hoglin", "zoglin"];
      if (securityCameraObject.getShootFriendlyMobs()) {
        familiesToShoot.push("mob");
        familiesToShoot.push("animal");
      } else {
      }
      const familyComp = entity.getComponent(EntityComponentTypes2.TypeFamily);
      for (const family of familiesToShoot) {
        if (familyComp?.hasTypeFamily(family) && !familyComp?.hasTypeFamily("inanimate") && !familyComp?.hasTypeFamily("projectile") && !familyComp?.hasTypeFamily("dummy") && !familyComp?.hasTypeFamily("furniture")) {
          cameraShoot = true;
          break;
        }
      }
    }
  }
  if (DEBUG2)
    world8.sendMessage(JSON.stringify(noticedPlayers));
  if (changed) {
    sourceEntity.setDynamicProperty(`${id}_activity_players_list_EXCLUDE`, JSON.stringify(noticedPlayers));
  }
  if (typeId.includes("sentry") && cameraShoot) {
    sentryCameraShoot(sourceEntity, securityCameraObject);
  }
}
function getCameraObject(sourceEntity) {
  const propertyIDs = world8.getDynamicPropertyIds();
  let securityCameraObject;
  for (const propertyID of propertyIDs) {
    if (propertyID.includes(sourceEntity.id) && !propertyID.includes("_EXCLUDE") && !propertyID.includes("_invitations")) {
      const propertyValue = world8.getDynamicProperty(propertyID);
      if (propertyValue !== void 0) {
        securityCameraObject = SecurityCamera.fromJSON(propertyValue);
      }
    }
  }
  return securityCameraObject;
}
function sentryCameraShoot(sourceEntity, securityCameraObject) {
  if (securityCameraObject === void 0)
    return;
  sourceEntity.runCommand(`playanimation @s animation.cbcl_secam.sentry_camera.shoot null 0.25`);
  sourceEntity.dimension.playSound(`cbcl_secam.sentry_camera.shoot`, sourceEntity.location, {
    volume: 2,
    pitch: 0.9 + Math.random() * (1.1 - 0.9)
  });
  const dimension = sourceEntity.dimension;
  const location = sourceEntity.location;
  const viewDir = Vec3.from(sourceEntity.getViewDirection());
  const leftRight = new Vec3(-viewDir.z, 0, viewDir.x).normalize();
  const offsetAmount = 0.35;
  const leftOffset = leftRight.multiply(offsetAmount);
  const rightOffset = leftRight.multiply(-offsetAmount);
  const impulseVector = Vec3.from(viewDir).multiply(1);
  const projectile1 = dimension.spawnEntity(
    securityCameraObject.getProjectileType(),
    Vec3.from({ x: location.x, y: location.y + 0.2, z: location.z }).add(leftOffset)
  );
  const projectile2 = dimension.spawnEntity(
    securityCameraObject.getProjectileType(),
    Vec3.from({ x: location.x, y: location.y + 0.2, z: location.z }).add(rightOffset)
  );
  projectile1.applyImpulse(impulseVector);
  projectile2.applyImpulse(impulseVector);
}
function getTimeAgo(savedDateString) {
  const savedDate = new Date(savedDateString);
  const now = /* @__PURE__ */ new Date();
  const diffMs = now.getTime() - savedDate.getTime();
  const minutes = Math.floor(diffMs / (1e3 * 60)) % 60;
  const hours = Math.floor(diffMs / (1e3 * 60 * 60)) % 24;
  const days = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
  const daysString = `cbcl_secam.ui.activity_logs.log.day`;
  const hoursString = `cbcl_secam.ui.activity_logs.log.hour`;
  const minutesString = `cbcl_secam.ui.activity_logs.log.minute`;
  const agoString = `cbcl_secam.ui.activity_logs.log.ago`;
  if (days > 0) {
    return [
      { text: `${days}` },
      { text: ` ` },
      { translate: `${daysString}` },
      { text: ` ` },
      { text: `${hours}` },
      { text: ` ` },
      { translate: `${hoursString}` },
      { text: ` ` },
      { translate: `${agoString}` }
    ];
  } else {
    return [
      { text: `${hours}` },
      { text: ` ` },
      { translate: `${hoursString}` },
      { text: ` ` },
      { text: `${minutes}` },
      { text: ` ` },
      { translate: `${minutesString}` },
      { text: ` ` },
      { translate: `${agoString}` }
    ];
  }
}
function wrongSpawnPosition(cameraEntity, message) {
  const players = cameraEntity.dimension.getEntities({
    location: cameraEntity.location,
    maxDistance: 7,
    type: "minecraft:player"
  });
  for (const player of players) {
    player.sendMessage(message);
    player.playSound("note.bass", {
      location: player.location
    });
  }
  const spawnEgg = new ItemStack(cameraEntity.typeId + "_spawn_egg", 1);
  cameraEntity.dimension.spawnItem(spawnEgg, cameraEntity.location);
  cameraEntity.triggerEvent("cbcl_secam:despawn");
}
function removeCamera(player, securityCameraObject) {
  const owner = world8.getEntity(securityCameraObject.getOwnerID());
  if (owner !== void 0 && player.hasTag(ADMIN_TAG) && player.id !== owner.id) {
    owner.sendMessage([
      {
        translate: `cbcl_secam.ui.remove_security_camera_menu.deleted_0`
      },
      ` `,
      `\xA7a${securityCameraObject.getSecurityCameraName()}\xA7r`,
      ` `,
      {
        translate: `cbcl_secam.ui.remove_security_camera_menu.deleted_1`
      },
      ` `,
      {
        translate: `cbcl_secam.ui.remove_security_camera_menu.deleted_2`
      },
      ` `,
      `\xA7d${player.name}\xA7r`
    ]);
    owner.playSound("note.bell", {
      location: owner.location
    });
  }
  const cameraSpawnEgg = new ItemStack(`cbcl_secam:` + securityCameraObject.getEntityTypeID() + "_spawn_egg", 1);
  player.dimension.spawnItem(cameraSpawnEgg, player.location);
  player.sendMessage([
    {
      translate: `cbcl_secam.ui.remove_security_camera_menu.deleted_0`
    },
    ` `,
    `\xA7a${securityCameraObject.getSecurityCameraName()}\xA7r`,
    ` `,
    {
      translate: `cbcl_secam.ui.remove_security_camera_menu.deleted_1`
    },
    `.`
  ]);
  player.playSound("note.bell", {
    location: player.location
  });
  const entityToRemove = world8.getEntity(securityCameraObject.getEntityID());
  if (entityToRemove) {
    const players = entityToRemove.dimension.getEntities({
      location: entityToRemove.location,
      type: "minecraft:player",
      maxDistance: 0.5
    });
    for (const playerToExit of players) {
      const viewSettingsPropertyID = `player_(${playerToExit.id})_view_settings_EXCLUDE`;
      const propertyValue = world8.getDynamicProperty(viewSettingsPropertyID);
      let viewSettingsObject = JSON.parse(propertyValue);
      exitCamera(playerToExit, viewSettingsObject, viewSettingsPropertyID);
    }
    try {
      entityToRemove.dimension.setBlockType(entityToRemove.location, `minecraft:air`);
    } catch {
    }
    entityToRemove.triggerEvent("cbcl_secam:despawn");
  }
  world8.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, void 0);
}
function hideArmorWhenInvisible(player) {
  const playerObjects = world8.getAllPlayers().filter((p) => p.id !== player.id);
  player.playAnimation("animation.camera_tablet.player.scale", {
    blendOutTime: 0.01,
    controller: "test",
    nextState: "null",
    stopExpression: "!q.is_riding",
    players: playerObjects
  });
}
function pushBackHostileMobs(player) {
  const entities_0 = player.dimension.getEntities({
    location: player.location,
    maxDistance: 4,
    families: ["monster"]
  });
  const entities_1 = player.dimension.getEntities({
    location: player.location,
    maxDistance: 4,
    families: ["hoglin"]
  });
  const entities_2 = player.dimension.getEntities({
    location: player.location,
    maxDistance: 4,
    families: ["zoglin"]
  });
  const allEntities = [...entities_0, ...entities_1, ...entities_2];
  const playerVector = Vec3.from(player.location);
  for (const entity of allEntities) {
    const viewDir = Vec3.from(entity.location);
    const impulseVector = Vec3.from(viewDir).subtract(playerVector).normalize().multiply(2);
    entity.applyImpulse(impulseVector);
  }
}
function checkPermissions() {
  const players = world8.getPlayers();
  for (const player of players) {
    if (player.playerPermissionLevel === PlayerPermissionLevel.Operator && !player.hasTag(ADMIN_TAG)) {
      player.addTag(ADMIN_TAG);
    } else if (player.playerPermissionLevel !== PlayerPermissionLevel.Operator && player.hasTag(ADMIN_TAG)) {
      player.removeTag(ADMIN_TAG);
    }
  }
}
function getGlobalSettings() {
  const property = world8.getDynamicProperty("super_admin_global_settings_EXCLUDE");
  let propertyValue;
  try {
    propertyValue = JSON.parse(property);
  } catch {
    propertyValue = GlobalSettingsTemplate;
  }
  for (const key in GlobalSettingsTemplate) {
    if (propertyValue[key] === void 0 || typeof propertyValue[key] !== typeof GlobalSettingsTemplate[key]) {
      propertyValue[key] = GlobalSettingsTemplate[key];
    }
  }
  for (const key in propertyValue) {
    if (GlobalSettingsTemplate[key] === void 0) {
      delete propertyValue[key];
    }
  }
  return propertyValue;
}
function insertUnderscoreBeforeTitleCase(input) {
  return input.replace(/([A-Z])([A-Z])/g, "$1_$2").replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/\s+/g, "_").trim().toLowerCase();
}

// data/system_template_esbuild/subscripts/camera.ts
var ADMIN_TAG = "cbcl_secam_ADMIN";
var DEBUG = false;
var SecurityCamera = class _SecurityCamera {
  constructor(cameraEntity, player) {
    // Properties
    // TODO: Add  _EXCLUDE to the properties that are meant to be in general excluded
    __publicField(this, "name");
    __publicField(this, "entityID");
    __publicField(this, "entityTypeID");
    __publicField(this, "cameraID");
    __publicField(this, "dimensionID");
    __publicField(this, "position");
    __publicField(this, "members", /* @__PURE__ */ new Map());
    __publicField(this, "ownerID");
    __publicField(this, "blockType");
    __publicField(this, "mobType");
    __publicField(this, "plushieType");
    __publicField(this, "movementNotifications");
    __publicField(this, "ownerName");
    __publicField(this, "projectileType");
    __publicField(this, "shootPlayers");
    __publicField(this, "shootFriendlyMobs");
    this.entityID = cameraEntity.id;
    this.entityTypeID = cameraEntity.typeId.replace("cbcl_secam:", "");
    this.dimensionID = cameraEntity.dimension.id;
    this.position = {
      location: cameraEntity.location,
      rotation: cameraEntity.getRotation()
    };
    this.blockType = 0;
    this.mobType = 0;
    this.plushieType = 0;
    this.projectileType = SENTRY_CAMERA_PROJECTILES[0].identifier;
    this.shootPlayers = false;
    this.shootFriendlyMobs = false;
    this.movementNotifications = { logs: true, message: false, excludeWhitelist: true };
    this.ownerID = player.id;
    this.ownerName = player.name;
    this.setSecurityCameraName(void 0);
    this.members = /* @__PURE__ */ new Map([]);
  }
  /**
   * Creates a dummy object of SecurityCamera class using random player as an input data. Used for fromJSON function.
   */
  static dummyConstructor() {
    const player = world9.getPlayers()[0];
    return new _SecurityCamera(player, player);
  }
  /**
   * Template for the setter
   * @param player set value
   */
  setterTemplate(setterValue) {
  }
  /**
   * Template for the getter
   * @returns {string} Return value
   */
  getterTemplate() {
    return this.name;
  }
  /**
   * Retrieves the ID of the owner of the camera
   * @returns {string} Owner's ID
   *
   */
  getOwnerID() {
    return this.ownerID;
  }
  /**
   * Retrieves the name of the owner of the camera
   * @returns {string} Owner's name
   *
   */
  getOwnerName() {
    return this.ownerName;
  }
  /**
   * Retrieves the members of the camera.
   * @returns {Map<string, Rank>} The members of the camera.
   *
   */
  getMembers() {
    return this.members;
  }
  /**
   * Sets the member of the camera along with its rank. Modifies if it exists
   */
  setMember(memberID, memberName, rank) {
    this.members.set(memberID, { name: memberName, rank });
  }
  /**
   * Retrieves the position property of the camera
   * @returns {{ location: Vector3; rotation: Vector2 }} The position property of the camera
   *
   */
  getPosition() {
    return this.position;
  }
  /**
   * Sets the position of the camera
   */
  setPosition(location, rotation) {
    this.position = { location, rotation };
  }
  /**
   * Retrieves the block type for the block camera.
   * @returns { number } Index of the block type in the list from the scope
   *
   */
  getBlockType() {
    return this.blockType;
  }
  /**
   * Sets the block type for the block camera.
   * @param {number} newBlockType The block type for the block camera.
   */
  setBlockType(newBlockType) {
    this.blockType = newBlockType;
  }
  /**
   * Retrieves the mob type for the mob camera.
   * @returns { number } Index of the mob type in the list from the scope
   *
   */
  getMobType() {
    return this.mobType;
  }
  /**
   * Sets the mob type for the mob camera.
   * @param {number} newMobType The mob type for the block camera.
   */
  setMobType(newMobType) {
    this.mobType = newMobType;
  }
  /**
   * Retrieves the plushie type for the plushie camera.
   * @returns { number } Index of the plushie type in the list from the scope
   *
   */
  getPlushieType() {
    return this.plushieType;
  }
  /**
   * Sets the plushie type for the plushie camera.
   * @param {number} newPlushieType The plushie type for the block camera.
   */
  setPlushieType(newPlushieType) {
    this.plushieType = newPlushieType;
  }
  /**
   * Retrieves the projectileType for the sentry camera.
   * @returns { number } Index of the projectileType in the list from the scope
   *
   */
  getProjectileType() {
    return this.projectileType;
  }
  /**
   * Sets the projectile ID for the sentry camera.
   * @param {number} newProjectileType The projectile ID for the block camera.
   */
  setProjectileType(newProjectileType) {
    this.projectileType = newProjectileType;
  }
  /**
   * Retrieves the shootPlayers for the sentry camera.
   * @returns { boolean } shootPlayers property for the camera. Valid only for sentry camera.
   *
   */
  getShootPlayers() {
    return this.shootPlayers;
  }
  /**
   * Sets the shootPlayers property for the sentry camera.
   * @param {boolean} newShootPlayersValue Value that decides whether the camera should shoot players or not. Valid only for sentry camera.
   */
  setShootPlayers(newShootPlayersValue) {
    this.shootPlayers = newShootPlayersValue;
  }
  /**
   * Retrieves the shootFriendlyMobs for the sentry camera.
   * @returns { boolean } shootFriendlyMobs property for the camera. Valid only for sentry camera.
   *
   */
  getShootFriendlyMobs() {
    return this.shootFriendlyMobs;
  }
  /**
   * Sets the shootFriendlyMobs property for the sentry camera.
   * @param {boolean} newShootFriendlyMobsValue Value that decides whether the camera should shoot players or not. Valid only for sentry camera.
   */
  setShootFriendlyMobs(newShootFriendlyMobsValue) {
    this.shootFriendlyMobs = newShootFriendlyMobsValue;
  }
  /**
   * Retrieves movement messages setting for the camera
   * @returns { { logs: boolean; message: boolean } } Movement messages object
   *
   */
  getMovementNotifications() {
    return this.movementNotifications;
  }
  /**
   * Sets the logs setting for movement messages for the camera
   * @param {boolean} newLogSetting New movements logs setting
   */
  setMovementNotificationsLogs(newLogSetting) {
    this.movementNotifications = {
      logs: newLogSetting,
      message: this.movementNotifications.message,
      excludeWhitelist: this.movementNotifications.excludeWhitelist
    };
  }
  /**
   * Sets the logs setting for movement messages for the camera
   * @param {boolean} newMessageSetting New movements logs setting
   */
  setMovementNotificationsMessage(newMessageSetting) {
    this.movementNotifications = {
      logs: this.movementNotifications.logs,
      message: newMessageSetting,
      excludeWhitelist: this.movementNotifications.excludeWhitelist
    };
  }
  /**
   * Sets the logs setting for excluding whitelist for the camera
   * @param {boolean} newExcludeWhitelistSetting New excluding whitelist setting
   */
  setMovementNotificationsExcludeWhitelist(newExcludeWhitelistSetting) {
    this.movementNotifications = {
      logs: this.movementNotifications.logs,
      message: this.movementNotifications.message,
      excludeWhitelist: newExcludeWhitelistSetting
    };
  }
  /**
   * Retrieves the ID of the entity
   * @returns {string} The ID of the entity.
   *
   */
  getEntityID() {
    return this.entityID;
  }
  /**
   * Retrieves the type ID of the entity
   * @returns {string} The type ID of the entity.
   *
   */
  getEntityTypeID() {
    return this.entityTypeID;
  }
  /**
   * Retrieves the ID of the camera.
   * @returns {string} The ID of the camera.
   *
   */
  getSecurityCameraID() {
    return this.cameraID;
  }
  /**
   * Sets the camera's ID based on entity ID and player ID.
   * @param player Player that the camera is binded to.
   */
  setSecurityCameraID() {
    let cameraNum = world9.getDynamicProperty(`${this.ownerID}_cameras_num_EXCLUDE`);
    if (cameraNum === void 0) {
      cameraNum = 1;
      world9.setDynamicProperty(`${this.ownerID}_cameras_num_EXCLUDE`, cameraNum);
    } else {
      cameraNum++;
      world9.setDynamicProperty(`${this.ownerID}_cameras_num_EXCLUDE`, cameraNum);
    }
    this.cameraID = `player_(${this.ownerID})_camera(${this.entityID})_type(${this.entityTypeID})_num(${cameraNum})`;
  }
  /**
   * Retrieves the name of the camera.
   * @returns {string} The name of the camera.
   *
   */
  getSecurityCameraName() {
    return this.name;
  }
  /**
   * Sets the camera's default name based on the amount of cameras player currently has. TODO: If camera with that number already exists, increase the number
   * @param player Player that the camera is binded to.
   */
  setSecurityCameraName(newName) {
    if (newName !== void 0) {
      newName = newName.trim();
      this.name = newName;
    } else {
      if (!this.ownerID)
        return;
      let player = world9.getEntity(this.ownerID);
      if (!player)
        return;
      let playerSecurityCameras = [];
      let dynamicPropertiesList = world9.getDynamicPropertyIds();
      dynamicPropertiesList.forEach((propertyID) => {
        if (!propertyID.includes("_invitations") && !propertyID.includes("_EXCLUDE") && propertyID.includes(`${player.id}`)) {
          playerSecurityCameras.push(propertyID);
        }
      });
      this.name = `Camera ${playerSecurityCameras.length + 1}`;
    }
  }
  /**
   * Teleports players to the camera
   * @param player Player to teleport.
   * @param location Location of the camera
   * @param rotation Rotation of the camera
   * @param vfx Boolean that decides whether to display visual and audio effects. Used in recursive calling of the function.
   */
  teleportHome(player, location, rotation, vfx) {
    if (vfx) {
      player.playSound(`cbcl_secam.teleport`, {
        location: player.location
      });
      player.sendMessage([
        {
          translate: `cbcl_secam.ui.specific_security_camera_menu.teleport.teleported`
        },
        ` `,
        `${this.name}`
      ]);
    }
    let dimension = world9.getDimension(this.dimensionID);
    player.tryTeleport(location, {
      checkForBlocks: true,
      dimension,
      rotation
    });
    system10.runTimeout(() => {
      let blockToCheck;
      try {
        blockToCheck = player.dimension.getBlock(player.location);
      } catch {
      }
      if (!blockToCheck) {
        this.teleportHome(player, location, rotation, false);
        return;
      }
      let newHomeLocation = location;
      if (!blockToCheck?.isAir && !blockToCheck?.isLiquid && blockToCheck?.typeId !== "minecraft:light_block") {
        for (let i = 0; i < 1e3; i++) {
          let blockAbove = blockToCheck?.above(i);
          if (blockAbove?.isAir || blockAbove?.isLiquid || blockAbove?.typeId === "minecraft:light_block") {
            newHomeLocation = {
              x: location.x,
              y: location.y + i,
              z: location.z
            };
            break;
          }
        }
        this.teleportHome(player, newHomeLocation, rotation, false);
      }
    }, 5);
  }
  // **************************************** STATIC FUNCTIONS ****************************************
  /**
   * Retrieves camera object from JSON. Separate function is needed because of lack of JSON class support for certain TS types.
   */
  static fromJSON(json) {
    let parsedData;
    if (!json) {
      return void 0;
    } else {
      parsedData = JSON.parse(json);
    }
    const camera = this.dummyConstructor();
    camera.dimensionID = parsedData.dimensionID;
    camera.entityID = parsedData.entityID;
    camera.entityTypeID = parsedData.entityTypeID;
    camera.cameraID = parsedData.cameraID;
    camera.name = parsedData.name;
    camera.position = parsedData.position;
    camera.movementNotifications = parsedData.movementNotifications;
    camera.ownerID = parsedData.ownerID;
    camera.blockType = parsedData.blockType;
    camera.mobType = parsedData.mobType;
    camera.plushieType = parsedData.plushieType;
    camera.projectileType = parsedData.projectileType;
    camera.shootPlayers = parsedData.shootPlayers;
    camera.shootFriendlyMobs = parsedData.shootFriendlyMobs;
    camera.ownerName = parsedData.ownerName;
    camera.name = parsedData.name;
    camera.members = new Map(parsedData.members);
    return camera;
  }
  /**
   * Turning the SecurityCamera object into a JSON string
   */
  static toJSON(camera) {
    let cameraString = JSON.stringify(camera, (key, value) => {
      if (value instanceof Map || value instanceof Set) {
        return Array.from(value);
      }
      return value;
    });
    return cameraString;
  }
  /**
   * Checkes given players rank in the given camera
   *
   * @param {Player} player - The player to check the rank
   *
   * @returns {Rank} Rank of the player in the given camera
   *
   */
  static checkRank(camera, player) {
    let members = camera.getMembers();
    if (members.size != 0 && members.has(player.id)) {
      return members.get(player.id)?.rank;
    } else {
      return "no_access" /* NoAccess */;
    }
  }
  /**
   * Retrieves a list of dynamic property IDs associated with a specific player.
   *
   * @param {Player} player - The player whose cameras (dynamic properties) are to be retrieved.
   * @param {boolean} ownership - Whether the cameras that has the given player as a member should be counted (false) or not (true).
   * @param {boolean} superAdmin - Whether players is a super admin or not. If true, all cameras are returned.
   *
   * @returns {string[]} An array of strings representing the property IDs associated with the player.
   *
   */
  static getPlayerSecurityCameras(player, ownership, superAdmin) {
    let playerProperties = [];
    let dynamicPropertiesList = world9.getDynamicPropertyIds();
    for (const propertyID of dynamicPropertiesList) {
      if (propertyID.includes("_invitations") || propertyID.includes("_EXCLUDE"))
        continue;
      if (superAdmin) {
        playerProperties.push(propertyID);
        continue;
      }
      if (propertyID.includes(`${player.id}`)) {
        playerProperties.push(propertyID);
      } else {
        let cameraObject = this.fromJSON(world9.getDynamicProperty(propertyID));
        if (!ownership && cameraObject) {
          let members = cameraObject.getMembers();
          if (members.size != 0 && members.has(player.id)) {
            playerProperties.push(propertyID);
          }
        }
      }
    }
    let camerasSorted = [];
    let camerasOwner = [];
    let camerasNotOwner = [];
    for (const cameraID of playerProperties) {
      const propertyValue = world9.getDynamicProperty(cameraID);
      let securityCameraObject = _SecurityCamera.fromJSON(propertyValue);
      if (securityCameraObject === void 0)
        continue;
      if (player.id === securityCameraObject.getOwnerID()) {
        camerasOwner.push({
          id: cameraID,
          number: parseInt(cameraID.match(/_num\((\d+)\)/)[1])
        });
      } else {
        camerasNotOwner.push({
          id: cameraID,
          number: parseInt(cameraID.match(/_num\((\d+)\)/)[1])
        });
      }
    }
    let camerasOwnerSorted = camerasOwner.sort((a, b) => a.number - b.number);
    let camerasNotOwnerSorted = camerasNotOwner.sort((a, b) => a.number - b.number);
    camerasSorted.push(...camerasOwnerSorted.map((camera) => camera.id));
    camerasSorted.push(...camerasNotOwnerSorted.map((camera) => camera.id));
    return camerasSorted;
  }
  /**
   * Checks whether provided player is an owner or admin of the considered security camera.
   * @returns {boolean} True if player is the owner or has admin tag.
   *
   */
  checkOwnerOrAdmin(player) {
    if (player.id === this.ownerID || player.hasTag(ADMIN_TAG)) {
      return true;
    } else {
      return false;
    }
  }
  /**
   * Kicks the member of the security camera if it matches provided ID.
   * @param {string} memberID - ID of the member to kick
   */
  kickMember(memberID) {
    this.members.delete(memberID);
  }
  /**
   * Function that starts camera viewing. It calls itself recursively 10 times every second. If it doesn't find the camera, cancels the operation
   * @param {Player} player - Player to teleport
   * @param {boolean} inititalTeleport - Boolean flag to mark the initial teleport - so the blackout is there only for the first time
   * @param {number} rescursiveIndex - Index that increases by 1 every time this functions is called. Eventually it causes function to just stop calling itself
   */
  viewCamera(player, inititalTeleport, rescursiveIndex) {
    player.onScreenDisplay.setHudVisibility(0, [9, 1, 4, 6, 10, 8, 12, 0, 7, 11, 2, 3]);
    player.addEffect("minecraft:resistance", 999999, {
      showParticles: false,
      amplifier: 255
    });
    player.addEffect("minecraft:invisibility", 999999, {
      showParticles: false,
      amplifier: 255
    });
    rescursiveIndex++;
    if (DEBUG) {
      world9.sendMessage(JSON.stringify(rescursiveIndex));
    }
    if (rescursiveIndex > 10) {
      const viewSettingsPropertyID = `player_(${player.id})_view_settings_EXCLUDE`;
      const propertyValue = world9.getDynamicProperty(viewSettingsPropertyID);
      let viewSettingsObject = JSON.parse(propertyValue);
      exitCamera(player, viewSettingsObject, viewSettingsPropertyID);
      removeCamera(player, this);
      return;
    }
    const recursiveDelay = 10;
    const fadeTime = {
      fadeInTime: inititalTeleport ? 0.25 : 0,
      holdTime: inititalTeleport ? 0.5 : 0,
      fadeOutTime: inititalTeleport ? 0.25 : 0
    };
    const delay = (fadeTime.fadeInTime + 0.25) * 20;
    const color = {
      red: 0,
      green: 0,
      blue: 0
    };
    if (inititalTeleport) {
      player.camera.fade({
        fadeColor: color,
        fadeTime
      });
    }
    lockCameraTablets(player);
    system10.runTimeout(() => {
      if (!player)
        return;
      const dimension = world9.getDimension(this.dimensionID);
      player.teleport(this.position.location, {
        rotation: this.position.rotation,
        dimension
      });
    }, fadeTime.fadeInTime * 20 + 1);
    system10.runTimeout(() => {
      if (!player)
        return;
      player.setGameMode(GameMode2.Adventure);
      const oldItemStack = getOffhandItem(player);
      if (oldItemStack !== void 0 && !oldItemStack.typeId.includes("cbcl_secam:overlay_")) {
        OFFHAND_ITEMS.set(player.id, oldItemStack);
        const viewSettingsPropertyID = `player_(${player.id})_view_settings_EXCLUDE`;
        const propertyValue = world9.getDynamicProperty(viewSettingsPropertyID);
        let viewSettingsObject = JSON.parse(propertyValue);
        setViewSettings(
          player,
          viewSettingsObject.currentCameraID,
          viewSettingsObject.currentCameraType,
          viewSettingsObject.dimensionID,
          oldItemStack.typeId,
          viewSettingsObject.location,
          viewSettingsObject.rotation,
          viewSettingsObject.gameMode
        );
      }
      replaceItem(
        player,
        EquipmentSlot3.Offhand,
        new ItemStack2(`cbcl_secam:overlay_${this.entityTypeID}`, 1),
        ItemLockMode2.slot
      );
      const cameraEntity = world9.getEntity(this.entityID);
      if (cameraEntity === void 0) {
        system10.runTimeout(() => {
          if (!player)
            return;
          this.viewCamera(player, false, rescursiveIndex);
        }, recursiveDelay);
        return;
      }
      const rideableComponent = cameraEntity.getComponent(EntityComponentTypes3.Rideable);
      rideableComponent?.addRider(player);
      player.addTag("cbcl_secam_VIEWING_CAMERA");
      player.camera.setCamera("minecraft:first_person");
      player.playSound(`cbcl_secam.view_camera`, {
        location: player.location,
        volume: 1,
        pitch: 1
      });
      player.inputPermissions.setPermissionCategory(InputPermissionCategory3.Dismount, false);
      player.inputPermissions.setPermissionCategory(InputPermissionCategory3.Jump, false);
      player.inputPermissions.setPermissionCategory(InputPermissionCategory3.Sneak, false);
      if (!this.entityTypeID.includes("drone_camera")) {
        player.inputPermissions.setPermissionCategory(InputPermissionCategory3.Movement, false);
        player.inputPermissions.setPermissionCategory(InputPermissionCategory3.LateralMovement, false);
      }
      if (this.entityTypeID.includes("night_vision")) {
        player.addEffect("minecraft:night_vision", 999999, {
          showParticles: false,
          amplifier: 255
        });
      }
      player.sendMessage({
        rawtext: [
          { translate: `cbcl_secam.ui.general.view_tip` },
          { text: ` \xA7e` },
          { translate: `entity.cbcl_secam:${this.getEntityTypeID()}.name` },
          { text: ` \xA7r` },
          { text: `"${this.getSecurityCameraName()}"` }
        ]
      });
    }, delay);
  }
};

// data/system_template_esbuild/subscripts/ui.ts
import { system as system11, world as world10, EntityComponentTypes as EntityComponentTypes4 } from "@minecraft/server";
import { ActionFormData, ModalFormData } from "@minecraft/server-ui";
var SecurityCameraUI = class {
  // **************************************************************************** VIEW CAMERA
  static viewCameraMenu(player, viewSettingsObject) {
    const securityCameraID = viewSettingsObject.currentCameraID;
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let buttons = [];
    buttons.push({
      langKey: "cbcl_secam.ui.view_camera_menu.next_camera",
      iconKey: "next_camera",
      callback: () => {
        const nextCamera = getNextCamera(player, viewSettingsObject.currentCameraID);
        if (!nextCamera) {
          this.turnOffCameraTablet(player);
          return;
        }
        setViewSettings(
          player,
          nextCamera.getSecurityCameraID(),
          nextCamera.getEntityTypeID(),
          viewSettingsObject.dimensionID,
          viewSettingsObject.itemTypeId,
          viewSettingsObject.location,
          viewSettingsObject.rotation,
          viewSettingsObject.gameMode
        );
        nextCamera.viewCamera(player, true, 0);
      }
    });
    buttons.push({
      langKey: "cbcl_secam.ui.view_camera_menu.previous_camera",
      iconKey: "previous_camera",
      callback: () => {
        const previousCamera = getPreviousCamera(player, viewSettingsObject.currentCameraID);
        if (!previousCamera) {
          this.turnOffCameraTablet(player);
          return;
        }
        setViewSettings(
          player,
          previousCamera.getSecurityCameraID(),
          previousCamera.getEntityTypeID(),
          viewSettingsObject.dimensionID,
          viewSettingsObject.itemTypeId,
          viewSettingsObject.location,
          viewSettingsObject.rotation,
          viewSettingsObject.gameMode
        );
        previousCamera.viewCamera(player, true, 0);
      }
    });
    buttons.push({
      langKey: "cbcl_secam.ui.view_camera_menu.exit_camera",
      iconKey: "exit_camera",
      callback: () => {
        const viewSettingsPropertyID = `player_(${player.id})_view_settings_EXCLUDE`;
        const propertyValue = world10.getDynamicProperty(viewSettingsPropertyID);
        let viewSettingsObject2 = JSON.parse(propertyValue);
        exitCamera(player, viewSettingsObject2, viewSettingsPropertyID);
      }
    });
    if (securityCameraObject.getEntityTypeID().includes("uv_camera")) {
      buttons.push({
        langKey: "cbcl_secam.ui.view_camera_menu.uv_camera.kill_mobs",
        iconKey: "kill_mobs",
        callback: () => {
          const familiesToKill = ["monster", "hoglin", "zoglin"];
          const entities = player.dimension.getEntities({
            location: player.location,
            maxDistance: 20
          });
          const index = 0;
          for (const entity of entities) {
            system11.runTimeout(() => {
              if (entity && entity.isValid) {
                const familyComp = entity.getComponent(EntityComponentTypes4.TypeFamily);
                for (const family of familiesToKill) {
                  if (familyComp?.hasTypeFamily(family) && !familyComp?.hasTypeFamily("inanimate") && !familyComp?.hasTypeFamily("projectile") && !familyComp?.hasTypeFamily("dummy") && !familyComp?.hasTypeFamily("furniture")) {
                    entity.applyDamage(1e3);
                  }
                }
              }
            }, index);
          }
          player.sendMessage({ rawtext: [{ translate: `cbcl_secam.ui.view_camera_menu.uv_camera.mobs_killed` }] });
          player.playSound("note.bell", {
            location: player.location
          });
        }
      });
    }
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}`).body({
      translate: `cbcl_secam.ui.view_camera_menu.body`
    });
    for (const button of buttons) {
      form.button(
        {
          translate: `${button.langKey}`
        },
        `${this.ICON_PATH}/${button.iconKey}.png`
      );
    }
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      buttons[response.selection].callback();
    });
  }
  // **************************************************************************** INVITED PLAYERS
  static invitedMenu(invitedPlayer, securityCameraID, chosenRank) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(invitedPlayer);
      return;
    }
    let form = new ActionFormData().title({
      rawtext: [
        {
          translate: "cbcl_secam.ui.invited_menu.title_0",
          text: ` ${securityCameraObject.getSecurityCameraName()}`
        }
      ]
    }).body({
      translate: "cbcl_secam.ui.invited_menu.body",
      with: ["\n"]
    }).button({ translate: "cbcl_secam.ui.general.accept" }).button({ translate: "cbcl_secam.ui.general.deny" });
    form.show(invitedPlayer).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(invitedPlayer);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(invitedPlayer);
        return;
      }
      switch (response.selection) {
        case 0:
          let currentSecurityCameraName = securityCameraObject.getSecurityCameraName();
          let members = securityCameraObject.getMembers();
          let owner = world10.getEntity(securityCameraObject.getOwnerID());
          if (owner) {
            owner.sendMessage([
              `\xA7a${invitedPlayer.name}\xA7r`,
              ` `,
              {
                translate: `cbcl_secam.ui.invited_menu.accepted_owner`
              },
              ` `,
              `\xA7e${currentSecurityCameraName}\xA7r`
            ]);
            owner.playSound("note.bell", {
              location: owner.location
            });
          }
          members.forEach((playerData, id) => {
            let player = world10.getEntity(id);
            if (player) {
              player.sendMessage([
                `\xA7a${invitedPlayer.name}\xA7r`,
                ` `,
                {
                  translate: `cbcl_secam.ui.invited_menu.accepted_owner`
                },
                ` `,
                `\xA7e${currentSecurityCameraName}\xA7r`
              ]);
              player.playSound("note.bell", {
                location: player.location
              });
            }
          });
          invitedPlayer.sendMessage([
            {
              translate: `cbcl_secam.ui.invited_menu.accepted_invited`
            },
            ` `,
            `\xA7e${securityCameraObject.getSecurityCameraName()}`
          ]);
          invitedPlayer.playSound("note.bell", {
            location: invitedPlayer.location
          });
          removeInviteProperty(invitedPlayer, securityCameraID);
          securityCameraObject.setMember(invitedPlayer.id, invitedPlayer.name, chosenRank);
          let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
          world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
          this.mainMenu(invitedPlayer);
          break;
        case 1:
          removeInviteProperty(invitedPlayer, securityCameraID);
          this.mainMenu(invitedPlayer);
          break;
      }
    });
  }
  // **************************************************************************** MAIN MENU AND GENERAL SETTINGS
  static mainMenu(player) {
    let form = new ActionFormData().title({ translate: "cbcl_secam.ui.main_menu.title" }).body({ translate: "cbcl_secam.ui.main_menu.body" });
    let camerasIDs = SecurityCamera.getPlayerSecurityCameras(player, false, false);
    let buttons = [];
    if (player.hasTag(ADMIN_TAG)) {
      buttons.push({
        langKey: "cbcl_secam.ui.super_admin_menu.title",
        iconKey: `${this.ICON_PATH}/super_admin_menu`,
        callback: () => {
          this.superAdminMenu(player);
        }
      });
    }
    buttons.push({
      langKey: "cbcl_secam.ui.main_menu.activity_logs",
      iconKey: `${this.ICON_PATH}/activity_logs`,
      callback: () => {
        this.activityLogs(player);
      }
    });
    for (const cameraID of camerasIDs) {
      const propertyValue = world10.getDynamicProperty(cameraID);
      let securityCameraObject = SecurityCamera.fromJSON(propertyValue);
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      const cameraType = securityCameraObject.getEntityTypeID();
      buttons.push({
        langKey: securityCameraObject.getSecurityCameraName(),
        iconKey: `${this.ITEM_ICON_PATH}/${cameraType}`,
        callback: () => {
          this.specificSecurityCameraMenu(player, cameraID);
        }
      });
    }
    for (const button of buttons) {
      if (button.iconKey === void 0) {
        form.button({
          translate: `${button.langKey}`
        });
      } else {
        form.button(
          {
            translate: `${button.langKey}`
          },
          `${button.iconKey}.png`
        );
      }
    }
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      buttons[response.selection].callback();
    });
  }
  static superAdminMenu(player) {
    let form = new ActionFormData().title({ translate: "cbcl_secam.ui.super_admin_menu.title" }).body({ translate: "cbcl_secam.ui.super_admin_menu.body" });
    let buttons = [];
    buttons.push({
      langKey: "cbcl_secam.ui.super_admin_all_cameras_menu.title",
      iconKey: void 0,
      callback: () => {
        this.superAdminAllCamerasMenu(player);
      }
    });
    buttons.push({
      langKey: "cbcl_secam.ui.super_admin_global_settings_menu.title",
      iconKey: void 0,
      callback: () => {
        this.superAdminOptionsMenu(player);
      }
    });
    buttons.push({
      langKey: "cbcl_secam.ui.general.back",
      iconKey: `${this.ICON_PATH}/back`,
      callback: () => {
        this.mainMenu(player);
      }
    });
    for (const button of buttons) {
      if (button.iconKey === void 0) {
        form.button({
          translate: `${button.langKey}`
        });
      } else {
        form.button(
          {
            translate: `${button.langKey}`
          },
          `${button.iconKey}.png`
        );
      }
    }
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      buttons[response.selection].callback();
    });
  }
  static superAdminOptionsMenu(player) {
    let form = new ModalFormData().title(`cbcl_secam.ui.super_admin_global_settings_menu.title`);
    let globalSettings = getGlobalSettings();
    let toggles = [];
    for (const toggleKey in globalSettings) {
      const toggle = globalSettings[toggleKey];
      toggles.push({
        labelLangKey: `cbcl_secam.ui.super_admin_global_settings_menu.${insertUnderscoreBeforeTitleCase(toggleKey)}`,
        defaultValue: toggle,
        callback: (response) => {
          globalSettings[toggleKey] = response;
          world10.setDynamicProperty(`super_admin_global_settings_EXCLUDE`, JSON.stringify(globalSettings));
        }
      });
    }
    for (const toggle of toggles) {
      form.toggle(toggle.labelLangKey, { defaultValue: toggle.defaultValue });
    }
    form.show(player).then((formData) => {
      if (formData.formValues === void 0 || formData.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      let index = 0;
      for (const result of formData.formValues) {
        if (result === void 0)
          continue;
        toggles[index].callback(result);
        index++;
      }
      this.turnOffCameraTablet(player);
    });
  }
  static superAdminAllCamerasMenu(player) {
    let form = new ActionFormData().title({ translate: "cbcl_secam.ui.super_admin_all_cameras_menu.title" }).body({ translate: "cbcl_secam.ui.super_admin_all_cameras_menu.body" });
    let camerasIDs = SecurityCamera.getPlayerSecurityCameras(player, false, true);
    let buttons = [];
    for (const cameraID of camerasIDs) {
      const propertyValue = world10.getDynamicProperty(cameraID);
      let securityCameraObject = SecurityCamera.fromJSON(propertyValue);
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      const cameraType = securityCameraObject.getEntityTypeID();
      buttons.push({
        langKey: `${securityCameraObject.getOwnerName()} - ${securityCameraObject.getSecurityCameraName()}`,
        iconKey: `${this.ITEM_ICON_PATH}/${cameraType}`,
        callback: () => {
          this.specificSecurityCameraMenu(player, cameraID);
        }
      });
    }
    buttons.push({
      langKey: "cbcl_secam.ui.general.back",
      iconKey: `${this.ICON_PATH}/back`,
      callback: () => {
        this.superAdminMenu(player);
      }
    });
    for (const button of buttons) {
      if (button.iconKey === void 0) {
        form.button({
          translate: `${button.langKey}`
        });
      } else {
        form.button(
          {
            translate: `${button.langKey}`
          },
          `${button.iconKey}.png`
        );
      }
    }
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      buttons[response.selection].callback();
    });
  }
  static specificSecurityCameraMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let buttons = [];
    if (securityCameraObject.checkOwnerOrAdmin(player)) {
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_menu.view",
        iconKey: "view",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          setViewSettings(
            player,
            securityCameraObject.getSecurityCameraID(),
            securityCameraObject.getEntityTypeID(),
            player.dimension.id,
            void 0,
            player.location,
            player.getRotation(),
            player.getGameMode().toString()
          );
          securityCameraObject.viewCamera(player, true, 0);
        }
      });
      if (getGlobalSettings().allowTeleport || player.hasTag(ADMIN_TAG)) {
        buttons.push({
          langKey: "cbcl_secam.ui.specific_security_camera_menu.teleport",
          iconKey: "teleport",
          callback: () => {
            if (securityCameraObject === void 0) {
              this.securityCameraUndefined(player);
              return;
            }
            const location = securityCameraObject.getPosition().location;
            const rotation = securityCameraObject.getPosition().rotation;
            securityCameraObject.teleportHome(player, location, rotation, true);
          }
        });
      }
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_menu.settings",
        iconKey: "settings",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          this.specificSecurityCameraSettingsMenu(player, securityCameraObject.getSecurityCameraID());
        }
      });
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_menu.remove_camera",
        iconKey: "remove_camera",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          this.removeCameraMenu(player, securityCameraObject.getSecurityCameraID());
        }
      });
    } else {
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_menu.view",
        iconKey: "view",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          setViewSettings(
            player,
            securityCameraObject.getSecurityCameraID(),
            securityCameraObject.getEntityTypeID(),
            player.dimension.id,
            void 0,
            player.location,
            player.getRotation(),
            player.getGameMode().toString()
          );
          securityCameraObject.viewCamera(player, true, 0);
        }
      });
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_menu.remove_access",
        iconKey: "remove_access",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          this.specificSecurityCameraSettingsRemoveAccess(player, securityCameraObject.getSecurityCameraID());
        }
      });
    }
    buttons.push({
      langKey: "cbcl_secam.ui.general.back",
      iconKey: "back",
      callback: () => {
        this.mainMenu(player);
      }
    });
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}`).body({
      rawtext: [
        { translate: `cbcl_secam.ui.specific_security_camera_menu.body` },
        { text: `

` },
        { translate: `cbcl_secam.ui.specific_security_camera_menu.body_camera_type` },
        { text: ` \xA7e` },
        { translate: `entity.cbcl_secam:${securityCameraObject.getEntityTypeID()}.name` }
      ]
    });
    for (const button of buttons) {
      form.button(
        {
          translate: `${button.langKey}`
        },
        `${this.ICON_PATH}/${button.iconKey}.png`
      );
    }
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      buttons[response.selection].callback();
    });
  }
  static specificSecurityCameraSettingsMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let buttons = [];
    buttons.push({
      langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.rename_camera",
      iconKey: "rename_camera",
      callback: () => {
        if (securityCameraObject === void 0) {
          this.securityCameraUndefined(player);
          return;
        }
        this.specificSecurityCameraSettingsRenameCameraMenu(player, securityCameraObject.getSecurityCameraID());
      }
    });
    buttons.push({
      langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.movement_notifications",
      iconKey: "movement_notifications",
      callback: () => {
        if (securityCameraObject === void 0) {
          this.securityCameraUndefined(player);
          return;
        }
        this.specificSecurityCameraSettingsMovementMenu(player, securityCameraObject.getSecurityCameraID());
      }
    });
    buttons.push({
      langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.members",
      iconKey: "members",
      callback: () => {
        if (securityCameraObject === void 0) {
          this.securityCameraUndefined(player);
          return;
        }
        this.specificSecurityCameraSettingsMembersMenu(player, securityCameraObject.getSecurityCameraID());
      }
    });
    if (securityCameraObject.getEntityTypeID().includes("block_camera")) {
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.block_type",
        iconKey: "block_type",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          this.specificSecurityCameraSettingsBlockTypeMenu(player, securityCameraObject.getSecurityCameraID());
        }
      });
    }
    if (securityCameraObject.getEntityTypeID().includes("mob_camera")) {
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.mob_type",
        iconKey: "mob_type",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          this.specificSecurityCameraSettingsMobTypeMenu(player, securityCameraObject.getSecurityCameraID());
        }
      });
    }
    if (securityCameraObject.getEntityTypeID().includes("plushie_camera")) {
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.plushie_type",
        iconKey: "plushie_type",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          this.specificSecurityCameraSettingsPlushieTypeMenu(player, securityCameraObject.getSecurityCameraID());
        }
      });
    }
    if (securityCameraObject.getEntityTypeID().includes("sentry_camera")) {
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.projectile_type",
        iconKey: "projectile_type",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          this.specificSecurityCameraSettingsProjectileTypeMenu(player, securityCameraObject.getSecurityCameraID());
        }
      });
      if (securityCameraObject.getShootPlayers()) {
        buttons.push({
          langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.shoot_players.true",
          iconKey: "shoot_players",
          callback: () => {
            if (securityCameraObject === void 0) {
              this.securityCameraUndefined(player);
              return;
            }
            securityCameraObject.setShootPlayers(false);
            let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
            world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
            this.specificSecurityCameraSettingsMenu(player, securityCameraObject.getSecurityCameraID());
          }
        });
      } else {
        buttons.push({
          langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.shoot_players.false",
          iconKey: "shoot_players",
          callback: () => {
            if (securityCameraObject === void 0) {
              this.securityCameraUndefined(player);
              return;
            }
            securityCameraObject.setShootPlayers(true);
            let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
            world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
            this.specificSecurityCameraSettingsMenu(player, securityCameraObject.getSecurityCameraID());
          }
        });
      }
      if (securityCameraObject.getShootFriendlyMobs()) {
        buttons.push({
          langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.shoot_friendly_mobs.true",
          iconKey: "shoot_friendly_mobs",
          callback: () => {
            if (securityCameraObject === void 0) {
              this.securityCameraUndefined(player);
              return;
            }
            securityCameraObject.setShootFriendlyMobs(false);
            let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
            world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
            this.specificSecurityCameraSettingsMenu(player, securityCameraObject.getSecurityCameraID());
          }
        });
      } else {
        buttons.push({
          langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.shoot_friendly_mobs.false",
          iconKey: "shoot_friendly_mobs",
          callback: () => {
            if (securityCameraObject === void 0) {
              this.securityCameraUndefined(player);
              return;
            }
            securityCameraObject.setShootFriendlyMobs(true);
            let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
            world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
            this.specificSecurityCameraSettingsMenu(player, securityCameraObject.getSecurityCameraID());
          }
        });
      }
    }
    if (securityCameraObject.getEntityTypeID().includes("drone_camera")) {
      buttons.push({
        langKey: "cbcl_secam.ui.specific_security_camera_settings_menu.teleport_to_me",
        iconKey: "teleport_to_me",
        callback: () => {
          if (securityCameraObject === void 0) {
            this.securityCameraUndefined(player);
            return;
          }
          if (!player)
            return;
          const droneEntity = world10.getEntity(securityCameraObject.getEntityID());
          if (droneEntity) {
            droneEntity.teleport(player.location, { rotation: player.getRotation(), dimension: player.dimension });
            player.playSound(`note.bell`, { location: player.location });
            player.sendMessage({
              rawtext: [
                { translate: `cbcl_secam.ui.specific_security_camera_settings_menu.teleport_to_me.drone_found` }
              ]
            });
          } else {
            const droneLocation = securityCameraObject.getPosition().location;
            player.playSound(`note.bass`, { location: player.location });
            player.sendMessage({
              rawtext: [
                { translate: `cbcl_secam.ui.specific_security_camera_settings_menu.teleport_to_me.drone_not_found` },
                { text: ` x: ${droneLocation.x}, y: ${droneLocation.y}, z: ${droneLocation.z}` }
              ]
            });
          }
          this.turnOffCameraTablet(player);
        }
      });
    }
    buttons.push({
      langKey: "cbcl_secam.ui.general.back",
      iconKey: "back",
      callback: () => {
        if (securityCameraObject === void 0) {
          this.securityCameraUndefined(player);
          return;
        }
        this.specificSecurityCameraMenu(player, securityCameraObject.getSecurityCameraID());
      }
    });
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}`).body({
      translate: `cbcl_secam.ui.specific_security_camera_settings_menu.body`
    });
    for (const button of buttons) {
      form.button(
        {
          translate: `${button.langKey}`
        },
        `${this.ICON_PATH}/${button.iconKey}.png`
      );
    }
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      buttons[response.selection].callback();
    });
  }
  static specificSecurityCameraSettingsMovementMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let toggles = [];
    toggles.push({
      labelLangKey: "cbcl_secam.ui.specific_security_camera_settings_movement_menu.logs",
      defaultValue: securityCameraObject.getMovementNotifications().logs,
      callback: (response) => {
        if (securityCameraObject === void 0) {
          this.securityCameraUndefined(player);
          return;
        }
        if (typeof response === "boolean") {
          securityCameraObject.setMovementNotificationsLogs(response);
        } else {
          world10.sendMessage("[ERROR] Value is not boolean for setMovementNotificationsLogs callback");
        }
      }
    });
    toggles.push({
      labelLangKey: "cbcl_secam.ui.specific_security_camera_settings_movement_menu.message",
      defaultValue: securityCameraObject.getMovementNotifications().message,
      callback: (response) => {
        if (securityCameraObject === void 0) {
          this.securityCameraUndefined(player);
          return;
        }
        if (typeof response === "boolean") {
          securityCameraObject.setMovementNotificationsMessage(response);
        } else {
          world10.sendMessage("[ERROR] Value is not boolean for setMovementNotificationsMessage callback");
        }
      }
    });
    toggles.push({
      labelLangKey: "cbcl_secam.ui.specific_security_camera_settings_movement_menu.exclude_whitelist",
      defaultValue: securityCameraObject.getMovementNotifications().excludeWhitelist,
      callback: (response) => {
        if (securityCameraObject === void 0) {
          this.securityCameraUndefined(player);
          return;
        }
        if (typeof response === "boolean") {
          securityCameraObject.setMovementNotificationsExcludeWhitelist(response);
        } else {
          world10.sendMessage("[ERROR] Value is not boolean for setMovementNotificationsExcludeWhitelist callback");
        }
      }
    });
    let form = new ModalFormData().title(`${securityCameraObject.getSecurityCameraName()}`);
    for (const toggle of toggles) {
      form.toggle(toggle.labelLangKey, { defaultValue: toggle.defaultValue });
    }
    form.submitButton({
      translate: `cbcl_secam.ui.specific_security_camera_settings_movement_menu.submit`
    });
    form.show(player).then((response) => {
      if (response.formValues === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      let index = 0;
      for (const result of response.formValues) {
        toggles[index].callback(!result);
        index++;
      }
      let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
      world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
      this.specificSecurityCameraSettingsMenu(player, securityCameraObject.getSecurityCameraID());
    });
  }
  static specificSecurityCameraSettingsBlockTypeMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let dropdownList = [];
    for (const block of BLOCK_CAMERA_BLOCKS) {
      dropdownList.push({ translate: `${block.lang_key}` });
    }
    let defaultIndex = securityCameraObject.getBlockType();
    let form = new ModalFormData().title({
      rawtext: [
        { translate: `cbcl_secam.ui.specific_security_camera_settings_block_type_menu.title_0`, with: ["\n"] },
        {
          text: ` `
        },
        {
          text: `${securityCameraObject.getSecurityCameraName()}`
        }
      ]
    }).dropdown(
      { translate: `cbcl_secam.ui.specific_security_camera_settings_block_type_menu.label`, with: ["\n"] },
      dropdownList,
      { defaultValueIndex: defaultIndex }
    );
    form.submitButton({
      translate: `cbcl_secam.ui.specific_security_camera_settings_block_type_menu.submit`
    });
    form.show(player).then((response) => {
      if (response.formValues === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      const entity = world10.getEntity(securityCameraObject.getEntityID());
      if (entity) {
        const eventName = BLOCK_CAMERA_BLOCKS[response.formValues[0]].identifier;
        entity.triggerEvent(`cbcl_secam:` + eventName);
      }
      securityCameraObject.setBlockType(response.formValues[0]);
      let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
      world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
      this.turnOffCameraTablet(player);
    });
  }
  static specificSecurityCameraSettingsMobTypeMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let dropdownList = [];
    for (const mob of MOB_CAMERA_MOBS) {
      dropdownList.push({ translate: `${mob.lang_key}` });
    }
    let defaultIndex = securityCameraObject.getMobType();
    let form = new ModalFormData().title({
      rawtext: [
        { translate: `cbcl_secam.ui.specific_security_camera_settings_mob_type_menu.title_0`, with: ["\n"] },
        {
          text: ` `
        },
        {
          text: `${securityCameraObject.getSecurityCameraName()}`
        }
      ]
    }).dropdown(
      { translate: `cbcl_secam.ui.specific_security_camera_settings_mob_type_menu.label`, with: ["\n"] },
      dropdownList,
      { defaultValueIndex: defaultIndex }
    );
    form.submitButton({
      translate: `cbcl_secam.ui.specific_security_camera_settings_mob_type_menu.submit`
    });
    form.show(player).then((response) => {
      if (response.formValues === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      const entity = world10.getEntity(securityCameraObject.getEntityID());
      if (entity) {
        entity.runCommand("/event entity @e[r=1,family=cbcl_secam_mob_camera_mob] cbcl_secam:despawn");
        const newEntityName = MOB_CAMERA_MOBS[response.formValues[0]].identifier;
        const newEntity = entity.dimension.spawnEntity(`cbcl_secam:mob_camera_${newEntityName}`, entity.location);
        newEntity.setRotation(entity.getRotation());
      }
      securityCameraObject.setMobType(response.formValues[0]);
      let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
      world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
      this.turnOffCameraTablet(player);
    });
  }
  static specificSecurityCameraSettingsPlushieTypeMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let dropdownList = [];
    for (const plushie of PLUSHIE_CAMERA_PLUSHIES) {
      dropdownList.push({ translate: `${plushie.lang_key}` });
    }
    let defaultIndex = securityCameraObject.getPlushieType();
    let form = new ModalFormData().title({
      rawtext: [
        { translate: `cbcl_secam.ui.specific_security_camera_settings_plushie_type_menu.title_0`, with: ["\n"] },
        {
          text: ` `
        },
        {
          text: `${securityCameraObject.getSecurityCameraName()}`
        }
      ]
    }).dropdown(
      { translate: `cbcl_secam.ui.specific_security_camera_settings_plushie_type_menu.label`, with: ["\n"] },
      dropdownList,
      { defaultValueIndex: defaultIndex }
    );
    form.submitButton({
      translate: `cbcl_secam.ui.specific_security_camera_settings_plushie_type_menu.submit`
    });
    form.show(player).then((response) => {
      if (response.formValues === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      const entity = world10.getEntity(securityCameraObject.getEntityID());
      if (entity) {
        const eventName = PLUSHIE_CAMERA_PLUSHIES[response.formValues[0]].identifier;
        entity.triggerEvent(`cbcl_secam:` + eventName);
      }
      securityCameraObject.setPlushieType(response.formValues[0]);
      let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
      world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
      this.turnOffCameraTablet(player);
    });
  }
  static specificSecurityCameraSettingsProjectileTypeMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let dropdownList = [];
    for (const projectile of SENTRY_CAMERA_PROJECTILES) {
      dropdownList.push({ translate: `${projectile.lang_key}` });
    }
    let defaultIndex = SENTRY_CAMERA_PROJECTILES.findIndex(
      (p) => p.identifier === securityCameraObject?.getProjectileType()
    );
    let form = new ModalFormData().title({
      rawtext: [
        { translate: `cbcl_secam.ui.specific_security_camera_settings_projectile_type_menu.title_0`, with: ["\n"] },
        {
          text: ` `
        },
        {
          text: `${securityCameraObject.getSecurityCameraName()}`
        }
      ]
    }).dropdown(
      { translate: `cbcl_secam.ui.specific_security_camera_settings_projectile_type_menu.label`, with: ["\n"] },
      dropdownList,
      { defaultValueIndex: defaultIndex }
    );
    form.submitButton({
      translate: `cbcl_secam.ui.specific_security_camera_settings_projectile_type_menu.submit`
    });
    form.show(player).then((response) => {
      if (response.formValues === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      securityCameraObject.setProjectileType(SENTRY_CAMERA_PROJECTILES[response.formValues[0]].identifier);
      let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
      world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
      this.turnOffCameraTablet(player);
      return;
    });
  }
  // **************************************************************************** RENAME
  static specificSecurityCameraSettingsRenameCameraMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let modalForm = new ModalFormData().title(`${securityCameraObject.getSecurityCameraName()}: Name Settings`).textField(
      {
        translate: "cbcl_secam.ui.specific_security_camera_settings_rename_menu.button"
      },
      ""
    );
    modalForm.show(player).then((formData) => {
      if (formData.formValues === void 0 || formData.canceled) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      if (formData.formValues !== void 0) {
        if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
          this.turnOffCameraTablet(player);
          return;
        }
        if (formData.formValues.join("").length > 30) {
          this.specificSecurityCameraSettingsNameTooLongMenu(player, securityCameraObject.getSecurityCameraID());
          return;
        }
        let input = formData.formValues.join("");
        if (input === void 0) {
          input = " ";
        }
        securityCameraObject.setSecurityCameraName(input);
        let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
        world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
        this.turnOffCameraTablet(player);
        return;
      }
    });
  }
  static specificSecurityCameraSettingsNameTooLongMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}: Name Settings`).body({
      translate: `cbcl_secam.ui.specific_security_camera_settings_name_too_long_menu.body`,
      with: ["\n"]
    }).button({ translate: "cbcl_secam.ui.general.back" }, `${this.ICON_PATH}/back.png`);
    form.show(player).then((response) => {
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      } else {
        this.specificSecurityCameraSettingsRenameCameraMenu(player, securityCameraObject.getSecurityCameraID());
        return;
      }
    });
  }
  // ****************************************************************************  MEMBERS
  static specificSecurityCameraSettingsMembersMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}: Manage Access`).body({
      translate: "cbcl_secam.ui.specific_security_camera_settings_members.body"
    }).button(
      {
        translate: "cbcl_secam.ui.specific_security_camera_settings_members.invite"
      },
      `${this.ICON_PATH}/invite.png`
    );
    let members = securityCameraObject.getMembers();
    members.forEach((playerData) => {
      form = form.button(`${playerData.name}`);
    });
    form = form.button({ translate: "cbcl_secam.ui.general.back" }, `${this.ICON_PATH}/back.png`);
    form.show(player).then((response) => {
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      let membersArray = Array.from(members);
      if (response.selection !== void 0 && response.canceled == false) {
        let selection = response.selection;
        if (selection === 0) {
          this.specificSecurityCameraSettingsMembersInviteMenu(player, securityCameraObject.getSecurityCameraID());
        } else if (selection > 0 && selection < membersArray.length + 1) {
          for (let i = 0; i < membersArray.length; i++) {
            if (selection === i + 1) {
              this.specificSecurityCameraSettingsMembersMemberMenu(
                player,
                securityCameraObject.getSecurityCameraID(),
                membersArray[i]
              );
              break;
            }
          }
        } else if (selection >= membersArray.length + 1) {
          this.specificSecurityCameraSettingsMenu(player, securityCameraObject.getSecurityCameraID());
        }
      }
    });
  }
  static specificSecurityCameraSettingsMembersMemberMenu(player, securityCameraID, member) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}: ${member[1].name}`).body({
      translate: "cbcl_secam.ui.specific_security_camera_settings_members_member_menu.body"
    }).button(
      {
        rawtext: [
          {
            translate: "cbcl_secam.ui.specific_security_camera_settings_members_member_menu.kick",
            text: ` ${member[1].name}`
          }
        ]
      },
      `${this.ICON_PATH}/kick.png`
    ).button({ translate: "cbcl_secam.ui.general.back" }, `${this.ICON_PATH}/back.png`);
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      switch (response.selection) {
        case 0:
          if (securityCameraObject.checkOwnerOrAdmin(player)) {
            this.specificSecurityCameraSettingsMembersMemberKickMenu(
              player,
              securityCameraObject.getSecurityCameraID(),
              member
            );
          }
          break;
        case 1:
          this.specificSecurityCameraSettingsMembersMenu(player, securityCameraObject.getSecurityCameraID());
          break;
        default:
          break;
      }
    });
  }
  static specificSecurityCameraSettingsRemoveAccess(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}`).body({ translate: "cbcl_secam.ui.leave_camera_menu.body", with: ["\n"] }).button({ translate: "cbcl_secam.ui.general.confirm" }).button({ translate: "cbcl_secam.ui.general.cancel" });
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      if (!securityCameraObject.checkOwnerOrAdmin(player)) {
        this.turnOffCameraTablet(player);
        return;
      }
      switch (response.selection) {
        case 0:
          securityCameraObject.kickMember(player.id);
          let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
          world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
          let currentCameraName = securityCameraObject.getSecurityCameraName();
          let members = securityCameraObject.getMembers();
          let owner = world10.getEntity(securityCameraObject.getOwnerID());
          if (owner) {
            owner.sendMessage([
              `\xA7a${player.name}\xA7r`,
              ` `,
              {
                translate: `cbcl_secam.ui.leave_camera_menu.player_left`
              },
              ` `,
              `\xA7e${currentCameraName}\xA7r`
            ]);
            owner.playSound("note.bell", {
              location: owner.location
            });
          }
          members.forEach((playerData, id) => {
            let member = world10.getEntity(id);
            if (member) {
              member.sendMessage([
                `\xA7a${player.name}\xA7r`,
                ` `,
                {
                  translate: `cbcl_secam.ui.leave_camera_menu.player_left`
                },
                ` `,
                `\xA7e${currentCameraName}\xA7r`
              ]);
              member.playSound("note.bell", {
                location: member.location
              });
            }
          });
          return;
        case 1:
          this.specificSecurityCameraSettingsMenu(player, securityCameraObject.getSecurityCameraID());
          break;
        default:
          break;
      }
    });
  }
  static specificSecurityCameraSettingsMembersMemberKickMenu(player, securityCameraID, member) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}: ${member[1].name}`).body({
      rawtext: [
        {
          translate: "cbcl_secam.ui.specific_security_camera_settings_members_member_kick_menu.body",
          text: ` ${member[1].name}`
        }
      ]
    }).button({ translate: `cbcl_secam.ui.general.confirm` }).button({
      translate: `cbcl_secam.ui.general.cancel`
    });
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      if (!securityCameraObject.checkOwnerOrAdmin(player)) {
        this.turnOffCameraTablet(player);
        return;
      }
      switch (response.selection) {
        case 0:
          if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
            this.turnOffCameraTablet(player);
            return;
          }
          if (securityCameraObject.checkOwnerOrAdmin(player)) {
            player.playSound("note.bass", {
              location: player.location
            });
            player.sendMessage([
              `\xA7c${member[1].name}\xA7r`,
              ` `,
              {
                translate: `cbcl_secam.ui.specific_security_camera_settings_members_member_kick_menu.kicked.owner_message_0`
              },
              ` `,
              `\xA7a${securityCameraObject.getSecurityCameraName()}\xA7r`,
              ` `,
              {
                translate: `cbcl_secam.ui.specific_security_camera_settings_members_member_kick_menu.kicked.owner_message_1`
              }
            ]);
            let kickedPlayer = world10.getEntity(member[0]);
            if (kickedPlayer !== void 0) {
              kickedPlayer.playSound("note.bass", {
                location: kickedPlayer.location
              });
              kickedPlayer.sendMessage([
                {
                  translate: `cbcl_secam.ui.specific_security_camera_settings_members_member_kick_menu.kicked.kicked_player_message_0`
                },
                ` `,
                `\xA7a${securityCameraObject.getSecurityCameraName()}\xA7r`,
                ` `,
                {
                  translate: `cbcl_secam.ui.specific_security_camera_settings_members_member_kick_menu.kicked.kicked_player_message_1`
                },
                ` `,
                `\xA7a${securityCameraObject.getOwnerName()}\xA7r`,
                ` `
              ]);
              const viewSettingsPropertyID = `player_(${kickedPlayer.id})_view_settings_EXCLUDE`;
              const propertyValue = world10.getDynamicProperty(viewSettingsPropertyID);
              let viewSettingsObject = void 0;
              try {
                viewSettingsObject = JSON.parse(propertyValue);
              } catch {
                viewSettingsObject = void 0;
              }
              if (viewSettingsObject !== void 0) {
                exitCamera(kickedPlayer, viewSettingsObject, viewSettingsPropertyID);
              }
            }
            securityCameraObject.kickMember(member[0]);
            let securityCameraObjectJSON = SecurityCamera.toJSON(securityCameraObject);
            world10.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, securityCameraObjectJSON);
            this.turnOffCameraTablet(player);
            return;
          } else {
            this.turnOffCameraTablet(player);
            return;
          }
        case 1:
          this.specificSecurityCameraSettingsMembersMemberMenu(
            player,
            securityCameraObject.getSecurityCameraID(),
            member
          );
          break;
        default:
          break;
      }
    });
  }
  static specificSecurityCameraSettingsMembersInviteMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let pendingInvites = [];
    let pendingInvitesString = "";
    let properties = world10.getDynamicPropertyIds();
    for (const property of properties) {
      if (!property.includes("_invitations"))
        continue;
      try {
        let propertyValueList;
        propertyValueList = JSON.parse(world10.getDynamicProperty(property));
        for (const propertyValue of propertyValueList) {
          if (securityCameraObject.getSecurityCameraID() === propertyValue.id) {
            pendingInvites.push(propertyValue.name);
            break;
          }
        }
      } catch {
      }
    }
    if (pendingInvites.length === 0) {
      pendingInvitesString = " None";
    } else {
      pendingInvites.forEach((pendingInvite, index) => {
        if (index === 0) {
          pendingInvitesString = `\xA7a${pendingInvite}\xA7r`;
        } else {
          pendingInvitesString = `\xA7a${pendingInvitesString}\xA7r, \xA7a${pendingInvite}\xA7r`;
        }
      });
    }
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}: Grant Access`).body({
      rawtext: [
        {
          translate: "cbcl_secam.ui.specific_security_camera_settings_members_invite_menu.body",
          with: ["\n"]
        },
        {
          text: `${pendingInvitesString}`
        }
      ]
    });
    let onlinePlayers = [];
    world10.getAllPlayers().forEach((localPlayer) => {
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      if (!securityCameraObject.getMembers().has(localPlayer.id) && securityCameraObject.getOwnerID() !== localPlayer.id && !checkInviteProperty(localPlayer, securityCameraObject.getSecurityCameraID())) {
        form = form.button(`${localPlayer.name}`);
        onlinePlayers.push(localPlayer);
      }
    });
    form = form.button({ translate: "cbcl_secam.ui.general.back" }, `${this.ICON_PATH}/back.png`);
    form.show(player).then((response) => {
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      if (response.selection !== void 0 && response.canceled == false) {
        let selection = response.selection;
        if (selection >= 0 && selection < onlinePlayers.length) {
          for (let i = 0; i < onlinePlayers.length; i++) {
            if (selection === i) {
              if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
                this.turnOffCameraTablet(player);
                return;
              }
              this.specificSecurityCameraSettingsMembersInviteConfirmMenu(
                player,
                securityCameraObject.getSecurityCameraID(),
                onlinePlayers[i].id
              );
              this.turnOffCameraTablet(player);
              return;
            }
          }
        } else if (selection >= onlinePlayers.length) {
          this.specificSecurityCameraSettingsMembersMenu(player, securityCameraObject.getSecurityCameraID());
        }
      }
    });
  }
  static specificSecurityCameraSettingsMembersInviteConfirmMenu(player, securityCameraID, invitedPlayerID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let invitedPlayer = world10.getEntity(invitedPlayerID);
    if (!invitedPlayer) {
      this.turnOffCameraTablet(player);
      return;
    }
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}: ${invitedPlayer.name}`).body({
      translate: "cbcl_secam.ui.specific_security_camera_settings_members_invite_confirm_menu.body"
    }).button({
      translate: "cbcl_secam.ui.general.confirm"
    }).button({
      translate: "cbcl_secam.ui.general.cancel"
    });
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      if (response.selection === 0) {
        inviteVFX(player, invitedPlayer, securityCameraObject.getSecurityCameraName());
        addInviteProperty(invitedPlayer, "access" /* Access */, securityCameraObject.getSecurityCameraID());
      }
      if (response.selection === 1) {
        this.turnOffCameraTablet(player);
        return;
      }
    });
  }
  // **************************************************************************** DELETE CAMERA
  static removeCameraMenu(player, securityCameraID) {
    let securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
    if (securityCameraObject === void 0) {
      this.securityCameraUndefined(player);
      return;
    }
    if (checkRank(securityCameraObject, player) === "no_access" /* NoAccess */ && !securityCameraObject.checkOwnerOrAdmin(player)) {
      this.turnOffCameraTablet(player);
      return;
    }
    let form = new ActionFormData().title(`${securityCameraObject.getSecurityCameraName()}`).body({
      translate: "cbcl_secam.ui.remove_security_camera_menu.body",
      with: ["\n"]
    }).button({ translate: "cbcl_secam.ui.general.confirm" }).button({ translate: "cbcl_secam.ui.general.cancel" });
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      securityCameraObject = SecurityCamera.fromJSON(world10.getDynamicProperty(securityCameraID));
      if (securityCameraObject === void 0) {
        this.securityCameraUndefined(player);
        return;
      }
      switch (response.selection) {
        case 0:
          removeCamera(player, securityCameraObject);
          this.turnOffCameraTablet(player);
          break;
        case 1:
          this.specificSecurityCameraMenu(player, securityCameraObject.getSecurityCameraID());
          break;
      }
    });
  }
  // **************************************************************************** OTHER
  static securityCameraUndefined(player) {
    let form = new ActionFormData().title(`${player.name}`).body({
      translate: `cbcl_secam.ui.general.security_camera_undefined`,
      with: ["\n"]
    }).button({ translate: "cbcl_secam.ui.general.back" }, `${this.ICON_PATH}/back.png`);
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      if (response.selection) {
        this.turnOffCameraTablet(player);
        return;
      }
    });
  }
  static activityLogs(player) {
    let form = new ActionFormData().title({
      translate: `cbcl_secam.ui.activity_logs.title`
    });
    const activityLogsString = world10.getDynamicProperty(`${player.id}_activity_logs_EXCLUDE`);
    let activityLogs = [];
    if (activityLogsString !== void 0) {
      activityLogs = JSON.parse(activityLogsString);
    }
    let bodyRawText = [];
    if (activityLogs.length > 0) {
      for (const log3 of activityLogs) {
        let time = getTimeAgo(log3.time);
        let cameraType = `cbcl_secam.ui.activity_logs.camera_type.` + log3.cameraType;
        let cameraName = log3.cameraName;
        let ending = `cbcl_secam.ui.activity_logs.log.0`;
        bodyRawText.push(...time);
        bodyRawText.push({ text: " - " });
        bodyRawText.push({ translate: cameraType });
        bodyRawText.push({ text: " " });
        bodyRawText.push({ text: '"' });
        bodyRawText.push({ translate: cameraName });
        bodyRawText.push({ text: '"' });
        bodyRawText.push({ text: " " });
        bodyRawText.push({ translate: ending });
        bodyRawText.push({ text: "\n\n" });
      }
    } else {
      bodyRawText.push({ translate: "cbcl_secam.ui.activity_logs.no_logs" });
    }
    form.body({
      rawtext: bodyRawText
    });
    form.button({ translate: "cbcl_secam.ui.activity_logs.reset_activity_logs" }).button({ translate: "cbcl_secam.ui.general.back" });
    form.show(player).then((response) => {
      if (response.selection === void 0 || response.canceled == true) {
        this.turnOffCameraTablet(player);
        return;
      }
      switch (response.selection) {
        case 0:
          world10.setDynamicProperty(`${player.id}_activity_logs_EXCLUDE`, void 0);
          this.activityLogs(player);
          break;
        case 1:
          this.mainMenu(player);
          break;
      }
    });
  }
  static turnOffCameraTablet(player) {
    system11.runTimeout(() => {
      if (player.isValid) {
        player.playSound(`cbcl_secam.close_tablet`, { location: player.location, volume: 0.5 });
        player.applyKnockback({ x: 0, z: 0 }, 0.1);
      }
    }, 1);
  }
};
// Path to the icons
__publicField(SecurityCameraUI, "ICON_PATH", "textures/cbcl/secam/ui");
__publicField(SecurityCameraUI, "ITEM_ICON_PATH", "textures/cbcl/secam/spawn_egg");

// data/system_template_esbuild/subscripts/events.ts
import { uiManager } from "@minecraft/server-ui";
var UI_TAG = "cbcl_secam_UI_MENU";
var HIT_COUNT = 5;
var camerasHit = /* @__PURE__ */ new Map();
world11.beforeEvents.playerInteractWithBlock.subscribe((event) => {
  const { player, itemStack, block, blockFace } = event;
  const dimension = block.dimension;
  if (!itemStack || !itemStack.typeId.includes("cbcl_secam:") || !itemStack.typeId.includes("camera") || !itemStack.typeId.includes("spawn_egg"))
    return;
  event.cancel = true;
  let blockToEvaluate = block;
  if (blockToEvaluate.typeId === "minecraft:snow_layer" && blockFace === Direction3.Up) {
    const blockBelow = blockToEvaluate.below(1);
    if (blockBelow) {
      blockToEvaluate = blockBelow;
    }
  }
  let location = blockToEvaluate.center();
  let spawnRotation = void 0;
  const offset = 0.5;
  switch (blockFace) {
    case Direction3.Down:
      location = {
        x: blockToEvaluate.below(1).center().x,
        y: blockToEvaluate.below(1).center().y - offset,
        // This makes sure camera is in the middle of the bottom of the block, so like spawned with spawn egg
        z: blockToEvaluate.below(1).center().z
      };
      break;
    case Direction3.Up:
      location = {
        x: blockToEvaluate.above(1).center().x,
        y: blockToEvaluate.above(1).center().y - offset,
        // This makes sure camera is in the middle of the bottom of the block, so like spawned with spawn egg
        z: blockToEvaluate.above(1).center().z
      };
      break;
    case Direction3.North:
      spawnRotation = 180;
      location = {
        x: blockToEvaluate.north(1).center().x,
        y: blockToEvaluate.north(1).center().y - offset,
        // This makes sure camera is in the middle of the bottom of the block, so like spawned with spawn egg
        z: blockToEvaluate.north(1).center().z
      };
      break;
    case Direction3.South:
      spawnRotation = 0;
      location = {
        x: blockToEvaluate.south(1).center().x,
        y: blockToEvaluate.south(1).center().y - offset,
        // This makes sure camera is in the middle of the bottom of the block, so like spawned with spawn egg
        z: blockToEvaluate.south(1).center().z
      };
      break;
    case Direction3.West:
      spawnRotation = 90;
      location = {
        x: blockToEvaluate.west(1).center().x,
        y: blockToEvaluate.west(1).center().y - offset,
        // This makes sure camera is in the middle of the bottom of the block, so like spawned with spawn egg
        z: blockToEvaluate.west(1).center().z
      };
      break;
    case Direction3.East:
      spawnRotation = -90;
      location = {
        x: blockToEvaluate.east(1).center().x,
        y: blockToEvaluate.east(1).center().y - offset,
        // This makes sure camera is in the middle of the bottom of the block, so like spawned with spawn egg
        z: blockToEvaluate.east(1).center().z
      };
      break;
    default:
      break;
  }
  let entities = dimension.getEntities({
    location,
    maxDistance: 0.5
  });
  for (const entity of entities) {
    if (entity.typeId.includes("cbcl_secam:") && entity.typeId.includes("camera"))
      return;
    if (!event.isFirstEvent)
      return;
  }
  system12.run(() => {
    let entity = dimension.spawnEntity(itemStack.typeId.replace("_spawn_egg", ""), location);
    let roundedRotation;
    let rotationCap = 90;
    if (entity.typeId.includes("plushie"))
      rotationCap = 45;
    if (spawnRotation !== void 0) {
      roundedRotation = spawnRotation;
    } else {
      let initRotation = (player.getRotation().y + 180) % 360;
      if (initRotation > 180) {
        initRotation -= 360;
      }
      if (initRotation > 0) {
        roundedRotation = Math.round(initRotation / rotationCap) * rotationCap;
      } else {
        roundedRotation = -Math.round(-initRotation / rotationCap) * rotationCap;
      }
    }
    entity.setRotation({ x: 0, y: roundedRotation });
    entity.setProperty("cbcl_secam:spawn_rotation", roundedRotation);
    const cameraData = DATA2.find((data) => data.identifier === entity.typeId.replace("cbcl_secam:", "")) ?? DATA2[0];
    player.runCommand(`clear @s ${itemStack.typeId} 0 1`);
    switch (cameraData.placing_position) {
      case "floor":
        if (blockFace !== Direction3.Up) {
          wrongSpawnPosition(entity, { translate: "cbcl_secam.placing_camera.message.floor" });
          return;
        }
        break;
      case "ceiling":
        if (blockFace !== Direction3.Down) {
          wrongSpawnPosition(entity, { translate: "cbcl_secam.placing_camera.message.ceiling" });
          return;
        }
        break;
      case "wall":
        if (blockFace === Direction3.Down || blockFace === Direction3.Up) {
          wrongSpawnPosition(entity, { translate: "cbcl_secam.placing_camera.message.wall" });
          return;
        }
        break;
      case "floor_and_ceiling":
        if (blockFace !== Direction3.Down && blockFace !== Direction3.Up) {
          wrongSpawnPosition(entity, { translate: "cbcl_secam.placing_camera.message.floor_and_ceiling" });
          return;
        }
        break;
      default:
        break;
    }
    entity.getComponent(EntityComponentTypes5.TameMount)?.tameToPlayer(false, player);
    let newSecurityCameraObject = new SecurityCamera(entity, player);
    newSecurityCameraObject.setSecurityCameraID();
    let newSecurityCameraString = SecurityCamera.toJSON(newSecurityCameraObject);
    world11.setDynamicProperty(`${newSecurityCameraObject.getSecurityCameraID()}`, `${newSecurityCameraString}`);
    if (entity.typeId !== "cbcl_secam:block_camera" && entity.typeId !== "cbcl_secam:drone_camera") {
      dimension.setBlockType(location, `cbcl_secam:fake_barrier`);
    } else if (entity.typeId === "cbcl_secam:block_camera") {
      dimension.setBlockType(location, `cbcl_secam:fake_barrier_solid`);
    }
    if (entity.typeId === "cbcl_secam:mob_camera") {
      const newEntityName = MOB_CAMERA_MOBS[newSecurityCameraObject.getMobType()].identifier;
      const newEntity = entity.dimension.spawnEntity(`cbcl_secam:mob_camera_${newEntityName}`, entity.location);
      newEntity.setRotation(entity.getRotation());
    }
    if (entity.typeId === "cbcl_secam:block_camera") {
      const blockBelow = entity.dimension.getBlock(entity.location)?.below();
      if (blockBelow) {
        let index = 0;
        for (const block2 of BLOCK_CAMERA_BLOCKS) {
          if (block2.command_identifier === blockBelow.typeId.replace("minecraft:", "")) {
            entity.triggerEvent(`cbcl_secam:${block2.identifier}`);
            newSecurityCameraObject.setBlockType(index);
            let newSecurityCameraString2 = SecurityCamera.toJSON(newSecurityCameraObject);
            world11.setDynamicProperty(`${newSecurityCameraObject.getSecurityCameraID()}`, `${newSecurityCameraString2}`);
          }
          index++;
        }
      }
    }
    if (entity.typeId === "cbcl_secam:dome_camera") {
      if (blockFace === Direction3.Up) {
        entity.setProperty(`cbcl_secam:dome_camera_floor`, true);
      }
    }
    if (entity.typeId === "cbcl_secam:plushie_camera" && !player.hasTag("cbcl_secam_PLUSHIE_CAMERA_HINT")) {
      player.sendMessage({
        translate: `cbcl_secam.ui.specific_security_camera_settings_plushie_type_menu.rotation_hint`
      });
      player.playSound(`note.bell`, { location: player.location, pitch: 1.3 });
      player.addTag("cbcl_secam_PLUSHIE_CAMERA_HINT");
    }
    if (!player.hasTag("cbcl_secam_REMOVE_CAMERA_HINT")) {
      player.sendMessage({
        translate: `cbcl_secam.ui.general.remove_hint`
      });
      player.playSound(`note.bell`, { location: player.location, pitch: 1.3 });
      player.addTag("cbcl_secam_REMOVE_CAMERA_HINT");
    }
  });
});
system12.afterEvents.scriptEventReceive.subscribe((event) => {
  const { message, id, sourceEntity } = event;
  if (id === "cbcl_secam:thermal_camera" && message === "show_entities" && sourceEntity) {
    const entities = sourceEntity.dimension.getEntities({
      location: sourceEntity.location,
      excludeTags: ["cbcl_secam_VIEWING_CAMERA"],
      excludeFamilies: ["cbcl_secam_camera", "projectile"],
      excludeTypes: ["minecraft:item"],
      maxDistance: 70,
      minDistance: 1
    });
    for (const entity of entities) {
      try {
        const target = entity.dimension.spawnEntity("cbcl_secam:thermal_camera_target", entity.location);
        target.addTag(`thermal_camera_target_${entity.id}`);
      } catch {
        continue;
      }
    }
  }
  if (id === "cbcl_secam:thermal_camera_target" && message === "teleport" && sourceEntity) {
    const tag = sourceEntity.getTags().find((t) => t.includes("thermal_camera_target_"));
    if (tag) {
      const teleportEntity = world11.getEntity(tag.replace("thermal_camera_target_", ""));
      if (teleportEntity) {
        try {
          sourceEntity.teleport(
            {
              x: teleportEntity.location.x,
              y: teleportEntity.location.y,
              z: teleportEntity.location.z
            },
            {
              rotation: { x: 0, y: 0 }
            }
          );
        } catch {
          sourceEntity.remove();
        }
      } else {
        sourceEntity.triggerEvent("cbcl_secam:despawn");
      }
    }
  }
});
world11.afterEvents.entityHitEntity.subscribe((event) => {
  const { damagingEntity, hitEntity } = event;
  if (damagingEntity instanceof Player7 && hitEntity.typeId === "cbcl_secam:plushie_camera") {
    const oldValue = hitEntity.getProperty(`cbcl_secam:spawn_rotation`);
    let newValue = oldValue + 45;
    if (oldValue + 45 > 180) {
      newValue = -180 + (oldValue + 45 - 180);
    }
    hitEntity.setProperty(`cbcl_secam:spawn_rotation`, newValue);
  }
});
world11.afterEvents.projectileHitBlock.subscribe((event) => {
  const projectile = event.projectile;
  if (!projectile.typeId.includes("cbcl_secam:sentry_proj_") || !projectile || !projectile.isValid)
    return;
  projectile.remove();
});
world11.afterEvents.projectileHitEntity.subscribe((event) => {
  const projectile = event.projectile;
  if (!projectile.typeId.includes("cbcl_secam:sentry_proj_"))
    return;
  const { dimension, hitVector, location, source } = event;
  const hitEntity = event.getEntityHit().entity;
  if (!hitEntity || !hitEntity.isValid)
    return;
  if (projectile.typeId === "cbcl_secam:cbcl_secam:sentry_proj_0") {
    hitEntity.applyDamage(3, {
      damagingEntity: source,
      cause: EntityDamageCause.sonicBoom
    });
  }
  if (projectile.typeId === "cbcl_secam:sentry_proj_1") {
    try {
      hitEntity.setOnFire(2, true);
    } catch {
    }
    hitEntity.applyDamage(3, {
      damagingEntity: source,
      cause: EntityDamageCause.fire
    });
  }
  if (projectile.typeId === "cbcl_secam:sentry_proj_2") {
    hitEntity.addEffect("slowness", 3 * TicksPerSecond, {
      amplifier: 1,
      showParticles: true
    });
    hitEntity.applyDamage(3, {
      damagingEntity: source,
      cause: EntityDamageCause.freezing
    });
  }
});
world11.afterEvents.entityHitEntity.subscribe((event) => {
  const { damagingEntity, hitEntity } = event;
  if (!(damagingEntity instanceof Player7) || !hitEntity.typeId.includes("cbcl_secam"))
    return;
  if (!hitEntity.typeId.includes("camera") || hitEntity.typeId.includes("plushie"))
    return;
  const player = damagingEntity;
  const id = hitEntity.id;
  if (camerasHit.has(id)) {
    const newHitAmount = camerasHit.get(id).hitAmount + 1;
    if (newHitAmount >= HIT_COUNT) {
      let securityCameraObject = void 0;
      for (const propertyID of world11.getDynamicPropertyIds()) {
        if (propertyID.includes(id)) {
          const propertyValue = world11.getDynamicProperty(propertyID);
          securityCameraObject = SecurityCamera.fromJSON(propertyValue);
          break;
        }
      }
      if (securityCameraObject === void 0)
        return;
      const ownerID = securityCameraObject.getOwnerID();
      const whitelistedPlayers = securityCameraObject.getMembers();
      if (player.id === ownerID) {
        player.sendMessage({
          rawtext: [{ translate: `cbcl_secam.ui.general.remove_hit_tip.owner` }]
        });
        player.playSound(`note.bass`, { location: player.location });
      } else if (whitelistedPlayers.has(player.id)) {
        player.sendMessage({
          rawtext: [{ translate: `cbcl_secam.ui.general.remove_hit_tip.member` }]
        });
        player.playSound(`note.bass`, { location: player.location });
      }
      camerasHit.delete(id);
    } else {
      camerasHit.set(id, { timeStamp: system12.currentTick, hitAmount: newHitAmount });
    }
  } else {
    camerasHit.set(id, { timeStamp: system12.currentTick, hitAmount: 1 });
  }
});
system12.afterEvents.scriptEventReceive.subscribe((event) => {
  const { message, id, sourceEntity } = event;
  if (id.includes("cbcl_secam:") && message === "activity_logs" && sourceEntity) {
    activityLog(sourceEntity);
  }
});
system12.afterEvents.scriptEventReceive.subscribe((event) => {
  const { message, id, sourceEntity } = event;
  if (id.includes("cbcl_secam:") && message === "has_rider" && sourceEntity && sourceEntity.typeId !== "cbcl_secam:drone_camera") {
    const Yrotation = sourceEntity.getProperty(`cbcl_secam:spawn_rotation`);
    sourceEntity.setRotation({ x: 0, y: Yrotation });
  }
});
world11.afterEvents.itemUse.subscribe((event) => {
  let item = event.itemStack;
  let player = event.source;
  if (item?.typeId === "cbcl_secam:camera_tablet") {
    if (player.hasTag(UI_TAG))
      return;
    const uiDelay = 12;
    player.addTag(UI_TAG);
    player.playSound(`cbcl_secam.open_tablet`, { location: player.location, volume: 0.5 });
    system12.runTimeout(() => {
      if (!player || !item)
        return;
      if (getHeldItem(player)?.typeId !== "cbcl_secam:camera_tablet") {
        player.removeTag(UI_TAG);
        return;
      }
      player.runCommand(`/playanimation @a animation.camera_tablet.player.counter_bobbing null 1 q.is_moving test`);
      if (player.hasTag(`cbcl_secam_VIEWING_CAMERA`)) {
        hideArmorWhenInvisible(player);
      }
      let invitation = getInviteProperty(player);
      const viewSettingsProperty = world11.getDynamicProperty(`player_(${player.id})_view_settings_EXCLUDE`);
      if (viewSettingsProperty !== void 0) {
        let viewSettingsObject = JSON.parse(viewSettingsProperty);
        SecurityCameraUI.viewCameraMenu(player, viewSettingsObject);
      } else if (invitation !== void 0) {
        let securityCameraObject = SecurityCamera.fromJSON(world11.getDynamicProperty(invitation.id));
        if (securityCameraObject !== void 0) {
          SecurityCameraUI.invitedMenu(player, invitation.id, invitation.rank);
        } else {
          removeInviteProperty(player, invitation.id);
          SecurityCameraUI.mainMenu(player);
        }
      } else {
        SecurityCameraUI.mainMenu(player);
      }
      player.removeTag(UI_TAG);
    }, uiDelay);
  }
});
world11.afterEvents.playerSpawn.subscribe((event) => {
  const { player, initialSpawn } = event;
  player.removeTag(UI_TAG);
  if (!initialSpawn)
    return;
  let dynamicPropertiesList = world11.getDynamicPropertyIds();
  for (const propertyID of dynamicPropertiesList) {
    if (propertyID.includes("view_settings") && propertyID.includes(player.id)) {
      const propertyValue = world11.getDynamicProperty(propertyID);
      let viewSettingsObject = JSON.parse(propertyValue);
      if (viewSettingsObject === void 0)
        continue;
      exitCamera(player, viewSettingsObject, propertyID);
      return;
    }
  }
});
world11.afterEvents.entityDie.subscribe((event) => {
  const { deadEntity } = event;
  if (!(deadEntity instanceof Player7))
    return;
  const player = deadEntity;
  uiManager.closeAllForms(player);
});
world11.afterEvents.entityHitEntity.subscribe((event) => {
  const { hitEntity } = event;
  if (!(hitEntity instanceof Player7))
    return;
  const player = hitEntity;
  uiManager.closeAllForms(player);
});
system12.afterEvents.scriptEventReceive.subscribe((event) => {
  const { message, id, sourceEntity } = event;
  if (id.includes("cbcl_secam:") && message === "property_update" && sourceEntity) {
    const propertyIDs = world11.getDynamicPropertyIds();
    let securityCameraObject;
    for (const propertyID of propertyIDs) {
      if (propertyID.includes(sourceEntity.id) && !propertyID.includes("_EXCLUDE") && !propertyID.includes("_invitations")) {
        const propertyValue = world11.getDynamicProperty(propertyID);
        if (propertyValue !== void 0) {
          securityCameraObject = SecurityCamera.fromJSON(propertyValue);
        }
      }
    }
    if (!securityCameraObject) {
      if (sourceEntity.typeId === "cbcl_secam:mob_camera") {
        sourceEntity.runCommand("/event entity @e[r=1,family=cbcl_secam_mob_camera_mob] cbcl_secam:despawn");
      }
      sourceEntity.triggerEvent("cbcl_secam:despawn");
      return;
    }
    const currentPosition = sourceEntity.location;
    const currentRotation = sourceEntity.getRotation();
    securityCameraObject.setPosition(currentPosition, currentRotation);
    if (sourceEntity.typeId === "cbcl_secam:mob_camera") {
      const mobs = sourceEntity.dimension.getEntities({
        families: ["cbcl_secam_mob_camera_mob"],
        maxDistance: 0.5,
        location: sourceEntity.location
      });
      if (mobs.length === 0) {
        const newEntityName = MOB_CAMERA_MOBS[securityCameraObject.getMobType()].identifier;
        const newEntity = sourceEntity.dimension.spawnEntity(
          `cbcl_secam:mob_camera_${newEntityName}`,
          sourceEntity.location
        );
        newEntity.setRotation(sourceEntity.getRotation());
      }
    }
    try {
      const blockToCheck = sourceEntity.dimension.getBlock(sourceEntity.location);
      const location = { x: sourceEntity.location.x, y: sourceEntity.location.y + 0.25, z: sourceEntity.location.z };
      if (blockToCheck && blockToCheck.typeId !== "cbcl_secam:fake_barrier" && blockToCheck.typeId !== "cbcl_secam:fake_barrier_solid" && sourceEntity.typeId !== "cbcl_secam:drone_camera") {
        if (sourceEntity.typeId !== "cbcl_secam:block_camera") {
          sourceEntity.dimension.setBlockType(location, `cbcl_secam:fake_barrier`);
        } else {
          sourceEntity.dimension.setBlockType(location, `cbcl_secam:fake_barrier_solid`);
        }
      }
    } catch {
    }
    if (id.includes("block_camera")) {
      sourceEntity.setProperty("cbcl_secam:block_camera_block", securityCameraObject.getBlockType());
    }
    if (id.includes("plushie_type")) {
      sourceEntity.setProperty("cbcl_secam:plushie_camera_plushie", securityCameraObject.getPlushieType());
    }
    let newSecurityCameraString = SecurityCamera.toJSON(securityCameraObject);
    world11.setDynamicProperty(`${securityCameraObject.getSecurityCameraID()}`, `${newSecurityCameraString}`);
  }
  if (id.includes("cbcl_secam:") && message === "check_for_camera" && sourceEntity) {
    const entities = sourceEntity.dimension.getEntities({ location: sourceEntity.location, maxDistance: 0.5 });
    for (const entity of entities) {
      if (entity.typeId === "cbcl_secam:mob_camera")
        return;
    }
    sourceEntity.triggerEvent("cbcl_secam:despawn");
  }
});
system12.beforeEvents.startup.subscribe((event) => {
  event.blockComponentRegistry.registerCustomComponent("cbcl_secam:check_for_despawn", {
    onTick(event2) {
      try {
        const { block, dimension } = event2;
        const location = { x: block.center().x, y: block.center().y - 0.25, z: block.center().z };
        const entities = dimension.getEntities({ location, maxDistance: 0.5 });
        for (const entity of entities) {
          if (entity.typeId.includes("cbcl_secam:") && entity.typeId.includes("camera"))
            return;
        }
        dimension.setBlockType(block.location, "minecraft:air");
      } catch {
      }
    }
  });
});
world11.beforeEvents.explosion.subscribe((event) => {
  for (const block of event.getImpactedBlocks()) {
    if (block.typeId === "cbcl_secam:fake_barrier" || block.typeId === "cbcl_secam:fake_barrier_solid") {
      event.cancel = true;
      return;
    }
  }
});
system12.runInterval(() => {
  if (system12.currentTick % 30 === 0) {
    const players = world11.getAllPlayers();
    for (const player of players) {
      if (getHeldItem(player)?.typeId === "cbcl_secam:camera_tablet") {
        player.onScreenDisplay.setActionBar({ translate: `cbcl_secam.ui.camera_tablet.held_hint` });
      } else if (player.hasTag(`cbcl_secam_VIEWING_CAMERA`)) {
        player.onScreenDisplay.setActionBar({ translate: `cbcl_secam.ui.camera_tablet.view_hint` });
      }
      if (player.hasTag(`cbcl_secam_VIEWING_CAMERA`)) {
        hideArmorWhenInvisible(player);
      }
    }
  }
  if (system12.currentTick % 15 === 0) {
    const players = world11.getAllPlayers();
    for (const player of players) {
      if (player.hasTag(`cbcl_secam_VIEWING_CAMERA`)) {
        pushBackHostileMobs(player);
      }
    }
  }
  if (system12.currentTick % 10 === 0 && camerasHit.size > 0) {
    for (const camera of camerasHit) {
      if (system12.currentTick - camera[1].timeStamp > 60) {
        camerasHit.delete(camera[0]);
      }
    }
  }
}, 1);
system12.runInterval(() => {
  checkPermissions();
}, 17);

// data/system_template_esbuild/subscripts/debug_events.ts
import { system as system13, world as world12, Player as Player8 } from "@minecraft/server";
system13.afterEvents.scriptEventReceive.subscribe((event) => {
  const { id, sourceEntity } = event;
  const player = sourceEntity;
  if (id === "cbcl_secam:player_debug_exit_camera") {
    const viewSettingsPropertyID = `player_(${player.id})_view_settings_EXCLUDE`;
    const propertyValue = world12.getDynamicProperty(viewSettingsPropertyID);
    let viewSettingsObject = JSON.parse(propertyValue);
    exitCamera(player, viewSettingsObject, viewSettingsPropertyID);
  }
});
system13.afterEvents.scriptEventReceive.subscribe((event) => {
  const { id, sourceEntity } = event;
  const player = sourceEntity;
  if (id === "cbcl_secam:player_debug_remove_nearest_camera") {
    const entities = player.dimension.getEntities({ location: player.location, maxDistance: 40 });
    for (const entity of entities) {
      if (entity.typeId.includes("cbcl_secam:") && entity.typeId.includes("camera")) {
        const dynamicPropertyIDs = world12.getDynamicPropertyIds();
        for (const propertyID of dynamicPropertyIDs) {
          if (propertyID.includes(`camera(${entity.id})`)) {
            let securityCameraObject = void 0;
            const propertyValue = world12.getDynamicProperty(propertyID);
            if (propertyValue !== void 0) {
              securityCameraObject = SecurityCamera.fromJSON(propertyValue);
            }
            if (securityCameraObject !== void 0) {
              removeCamera(player, securityCameraObject);
            }
          }
        }
        return;
      }
    }
  }
});
system13.afterEvents.scriptEventReceive.subscribe((event) => {
  const { id } = event;
  if (id === "cbcl_secam:dynamic_properties_reset") {
    world12.getDynamicPropertyIds().forEach((propertyID) => {
      world12.setDynamicProperty(propertyID, void 0);
    });
  }
});
system13.afterEvents.scriptEventReceive.subscribe((event) => {
  const { id } = event;
  if (id === "cbcl_secam:display_all_dynamic_properties") {
    world12.getDynamicPropertyIds().forEach((propertyID) => {
      world12.sendMessage(JSON.stringify(world12.getDynamicProperty(propertyID)));
    });
  }
});
system13.afterEvents.scriptEventReceive.subscribe((event) => {
  const { id, sourceEntity } = event;
  if (id === "cbcl_secam:add_dummy_camera") {
    let newSecurityCameraObject = new SecurityCamera(sourceEntity, sourceEntity);
    newSecurityCameraObject.setSecurityCameraID();
    let newSecurityCameraString = SecurityCamera.toJSON(newSecurityCameraObject);
    world12.setDynamicProperty(`${newSecurityCameraObject.getSecurityCameraID()}`, `${newSecurityCameraString}`);
  }
});
system13.afterEvents.scriptEventReceive.subscribe((event) => {
  const { id, sourceEntity } = event;
  if (id === "cbcl_secam:debug_armor_visibility" && sourceEntity instanceof Player8) {
    const playerObjects = world12.getAllPlayers().filter((p) => p.id !== sourceEntity.id);
    sourceEntity.playAnimation("animation.camera_tablet.player.scale", {
      blendOutTime: 0.5,
      controller: "test",
      nextState: "null",
      stopExpression: "q.is_moving",
      players: playerObjects
    });
  }
});

// data/system_template_esbuild/subscripts/guide_book.ts
import {
  world as world13,
  system as system14,
  ItemStack as ItemStack4,
  EntityComponentTypes as EntityComponentTypes6,
  EquipmentSlot as EquipmentSlot4
} from "@minecraft/server";
var PROJECT_NAME = "cbcl_secam";
var LORE = "\xA7r\xA76Security Cameras Add-On";
world13.afterEvents.itemStartUse.subscribe((event) => {
  let player = event.source;
  let itemStack = event.itemStack;
  if (!itemStack || itemStack.typeId !== `${PROJECT_NAME}:guide_book`)
    return;
  player.playSound("item.book.page_turn");
});
world13.afterEvents.playerJoin.subscribe((event) => {
  let player = world13.getEntity(event.playerId);
  if (!player)
    return;
  checkIfLoaded(player);
});
function checkIfLoaded(player) {
  let location = player.location;
  try {
    let blockToCheck = player.dimension?.getBlock(location);
    if (!blockToCheck) {
      system14.runTimeout(() => {
        if (!player.isValid)
          return;
        checkIfLoaded(player);
      }, 10);
      return;
    } else {
      addonLoaded(player, location);
    }
  } catch (error) {
    system14.runTimeout(() => {
      if (!player.isValid)
        return;
      checkIfLoaded(player);
    }, 10);
  }
}
function addonLoaded(player, originalLocation) {
  if (Math.abs(originalLocation.x - player.location.x) > 0.5 || Math.abs(originalLocation.z - player.location.z) > 0.5) {
    system14.runTimeout(() => {
      if (!player.isValid)
        return;
      if (!player.hasTag(`${PROJECT_NAME}_REGISTERED_PLAYER`)) {
        player.playSound("note.bell");
        player.sendMessage({ translate: `${PROJECT_NAME}.addon_applied` });
        player.addTag(`${PROJECT_NAME}_REGISTERED_PLAYER`);
        let cameraTablet = new ItemStack4("cbcl_secam:camera_tablet", 1);
        let fabricator = new ItemStack4("cbcl_secam:fabricator", 1);
        let guidebook = new ItemStack4(`${PROJECT_NAME}:guide_book`, 1);
        guidebook.setLore([`${LORE}`]);
        player.dimension.spawnItem(guidebook, player.location);
        player.dimension.spawnItem(cameraTablet, player.location);
        player.dimension.spawnItem(fabricator, player.location);
        guidebook.setLore([`${LORE}`]);
      }
    }, 5);
  } else {
    system14.runTimeout(() => {
      if (!player.isValid)
        return;
      addonLoaded(player, originalLocation);
    }, 5);
    return;
  }
}
function getItemHeld(player) {
  const playerEquippableComp = player.getComponent(EntityComponentTypes6.Equippable);
  if (!playerEquippableComp)
    return;
  let heldItem = playerEquippableComp.getEquipment(EquipmentSlot4.Mainhand);
  return heldItem;
}
function displayHint(player) {
  if (!player)
    return;
  const holdingItem = getItemHeld(player);
  if (holdingItem == void 0)
    return;
  if (holdingItem.typeId.includes(`${PROJECT_NAME}:guide_book`)) {
    player.runCommand(`/titleraw @s actionbar {"rawtext":[{"translate":"${PROJECT_NAME}.guide_book.actionbar_hint"}]}`);
  }
}
function addLore(player) {
  let itemStack = getItemHeld(player);
  if (itemStack === void 0)
    return;
  if (itemStack?.typeId.includes(`${PROJECT_NAME}:guide_book`) && itemStack.getLore().length === 0) {
    itemStack.setLore([`${LORE}`]);
    const playerEquippableComp = player.getComponent(EntityComponentTypes6.Equippable);
    playerEquippableComp.setEquipment(EquipmentSlot4.Mainhand, itemStack);
  }
}
system14.runInterval(() => {
  world13.getAllPlayers().forEach((player) => {
    displayHint(player);
    addLore(player);
  });
}, 20);
