"use strict";
/* Socket Lib - Built with esbuild */
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var logger_exports = {};
__export(logger_exports, {
  LOG_SYMBOLS: () => LOG_SYMBOLS,
  Logger: () => Logger,
  getDefaultLogger: () => getDefaultLogger,
  incLogCallCountSymbol: () => incLogCallCountSymbol,
  lastWasBlankSymbol: () => lastWasBlankSymbol
});
module.exports = __toCommonJS(logger_exports);
var import_is_unicode_supported = __toESM(require("./external/@socketregistry/is-unicode-supported"));
var import_yoctocolors_cjs = __toESM(require("./external/yoctocolors-cjs"));
var import_strings = require("./strings");
var import_context = require("./themes/context");
var import_themes = require("./themes/themes");
const globalConsole = console;
const ReflectApply = Reflect.apply;
const ReflectConstruct = Reflect.construct;
let _Console;
// @__NO_SIDE_EFFECTS__
function constructConsole(...args) {
  if (_Console === void 0) {
    const nodeConsole = require("node:console");
    _Console = nodeConsole.Console;
  }
  return ReflectConstruct(
    _Console,
    // eslint-disable-line no-undef
    args
  );
}
// @__NO_SIDE_EFFECTS__
function getYoctocolors() {
  return import_yoctocolors_cjs.default;
}
// @__NO_SIDE_EFFECTS__
function applyColor(text, color, colors) {
  if (typeof color === "string") {
    return colors[color](text);
  }
  const { 0: r, 1: g, 2: b } = color;
  return `\x1B[38;2;${r};${g};${b}m${text}\x1B[39m`;
}
const LOG_SYMBOLS = /* @__PURE__ */ (() => {
  const target = {
    __proto__: null
  };
  let initialized = false;
  const handler = {
    __proto__: null
  };
  const updateSymbols = () => {
    const supported = (0, import_is_unicode_supported.default)();
    const colors = /* @__PURE__ */ getYoctocolors();
    const theme = (0, import_context.getTheme)();
    const successColor = theme.colors.success;
    const errorColor = theme.colors.error;
    const warningColor = theme.colors.warning;
    const infoColor = theme.colors.info;
    const stepColor = theme.colors.step;
    target.fail = /* @__PURE__ */ applyColor(supported ? "\u2716" : "\xD7", errorColor, colors);
    target.info = /* @__PURE__ */ applyColor(supported ? "\u2139" : "i", infoColor, colors);
    target.progress = /* @__PURE__ */ applyColor(supported ? "\u2234" : ":.", stepColor, colors);
    target.reason = colors.dim(
      /* @__PURE__ */ applyColor(supported ? "\u2234" : ":.", warningColor, colors)
    );
    target.skip = /* @__PURE__ */ applyColor(supported ? "\u21BB" : "@", stepColor, colors);
    target.step = /* @__PURE__ */ applyColor(supported ? "\u2192" : ">", stepColor, colors);
    target.success = /* @__PURE__ */ applyColor(supported ? "\u2714" : "\u221A", successColor, colors);
    target.warn = /* @__PURE__ */ applyColor(supported ? "\u26A0" : "\u203C", warningColor, colors);
  };
  const init = () => {
    if (initialized) {
      return;
    }
    updateSymbols();
    initialized = true;
    for (const trapName in handler) {
      delete handler[trapName];
    }
  };
  const reset = () => {
    if (!initialized) {
      return;
    }
    updateSymbols();
  };
  for (const trapName of Reflect.ownKeys(Reflect)) {
    const fn = Reflect[trapName];
    if (typeof fn === "function") {
      ;
      handler[trapName] = (...args) => {
        init();
        return fn(...args);
      };
    }
  }
  (0, import_context.onThemeChange)(() => {
    reset();
  });
  return new Proxy(target, handler);
})();
const boundConsoleEntries = [
  // Add bound properties from console[kBindProperties](ignoreErrors, colorMode, groupIndentation).
  // https://github.com/nodejs/node/blob/v24.0.1/lib/internal/console/constructor.js#L230-L265
  "_stderrErrorHandler",
  "_stdoutErrorHandler",
  // Add methods that need to be bound to function properly.
  "assert",
  "clear",
  "count",
  "countReset",
  "createTask",
  "debug",
  "dir",
  "dirxml",
  "error",
  // Skip group methods because in at least Node 20 with the Node --frozen-intrinsics
  // flag it triggers a readonly property for Symbol(kGroupIndent). Instead, we
  // implement these methods ourselves.
  //'group',
  //'groupCollapsed',
  //'groupEnd',
  "info",
  "log",
  "table",
  "time",
  "timeEnd",
  "timeLog",
  "trace",
  "warn"
].filter((n) => typeof globalConsole[n] === "function").map((n) => [n, globalConsole[n].bind(globalConsole)]);
const consolePropAttributes = {
  __proto__: null,
  writable: true,
  enumerable: false,
  configurable: true
};
const maxIndentation = 1e3;
const privateConsole = /* @__PURE__ */ new WeakMap();
const privateConstructorArgs = /* @__PURE__ */ new WeakMap();
let _consoleSymbols;
function getConsoleSymbols() {
  if (_consoleSymbols === void 0) {
    _consoleSymbols = Object.getOwnPropertySymbols(globalConsole);
  }
  return _consoleSymbols;
}
const incLogCallCountSymbol = Symbol.for("logger.logCallCount++");
let _kGroupIndentationWidthSymbol;
function getKGroupIndentationWidthSymbol() {
  if (_kGroupIndentationWidthSymbol === void 0) {
    _kGroupIndentationWidthSymbol = getConsoleSymbols().find((s) => s.label === "kGroupIndentWidth") ?? Symbol("kGroupIndentWidth");
  }
  return _kGroupIndentationWidthSymbol;
}
const lastWasBlankSymbol = Symbol.for("logger.lastWasBlank");
class Logger {
  /**
   * Static reference to log symbols for convenience.
   *
   * @example
   * ```typescript
   * console.log(`${Logger.LOG_SYMBOLS.success} Done`)
   * ```
   */
  static LOG_SYMBOLS = LOG_SYMBOLS;
  #parent;
  #boundStream;
  #stderrLogger;
  #stdoutLogger;
  #stderrIndention = "";
  #stdoutIndention = "";
  #stderrLastWasBlank = false;
  #stdoutLastWasBlank = false;
  #logCallCount = 0;
  #options;
  #originalStdout;
  #theme;
  /**
   * Creates a new Logger instance.
   *
   * When called without arguments, creates a logger using the default
   * `process.stdout` and `process.stderr` streams. Can accept custom
   * console constructor arguments for advanced use cases.
   *
   * @param args - Optional console constructor arguments
   *
   * @example
   * ```typescript
   * // Default logger
   * const logger = new Logger()
   *
   * // Custom streams (advanced)
   * const customLogger = new Logger({
   *   stdout: customWritableStream,
   *   stderr: customErrorStream
   * })
   * ```
   */
  constructor(...args) {
    privateConstructorArgs.set(this, args);
    const options = args["0"];
    if (typeof options === "object" && options !== null) {
      this.#options = { __proto__: null, ...options };
      this.#originalStdout = options.stdout;
      const themeOption = options.theme;
      if (themeOption) {
        if (typeof themeOption === "string") {
          this.#theme = import_themes.THEMES[themeOption];
        } else {
          this.#theme = themeOption;
        }
      }
    } else {
      this.#options = { __proto__: null };
    }
  }
  /**
   * Apply a console method with indentation.
   * @private
   */
  #apply(methodName, args, stream) {
    const con = this.#getConsole();
    const text = args.at(0);
    const hasText = typeof text === "string";
    const targetStream = stream || (methodName === "log" ? "stdout" : "stderr");
    const indent = this.#getIndent(targetStream);
    const logArgs = hasText ? [(0, import_strings.applyLinePrefix)(text, { prefix: indent }), ...args.slice(1)] : args;
    ReflectApply(
      con[methodName],
      con,
      logArgs
    );
    this[lastWasBlankSymbol](hasText && (0, import_strings.isBlankString)(logArgs[0]), targetStream);
    this[incLogCallCountSymbol]();
    return this;
  }
  /**
   * Get the Console instance for this logger, creating it lazily on first access.
   *
   * This lazy initialization allows the logger to be imported during early
   * Node.js bootstrap before stdout is ready, avoiding Console initialization
   * errors (ERR_CONSOLE_WRITABLE_STREAM).
   *
   * @private
   */
  #getConsole() {
    ensurePrototypeInitialized();
    let con = privateConsole.get(this);
    if (!con) {
      const ctorArgs = privateConstructorArgs.get(this) ?? [];
      if (ctorArgs.length) {
        con = /* @__PURE__ */ constructConsole(...ctorArgs);
      } else {
        con = /* @__PURE__ */ constructConsole({
          stdout: process.stdout,
          stderr: process.stderr
        });
        for (const { 0: key, 1: method } of boundConsoleEntries) {
          con[key] = method;
        }
      }
      privateConsole.set(this, con);
      privateConstructorArgs.delete(this);
    }
    return con;
  }
  /**
   * Get indentation for a specific stream.
   * @private
   */
  #getIndent(stream) {
    const root = this.#getRoot();
    return stream === "stderr" ? root.#stderrIndention : root.#stdoutIndention;
  }
  /**
   * Get lastWasBlank state for a specific stream.
   * @private
   */
  #getLastWasBlank(stream) {
    const root = this.#getRoot();
    return stream === "stderr" ? root.#stderrLastWasBlank : root.#stdoutLastWasBlank;
  }
  /**
   * Get the root logger (for accessing shared indentation state).
   * @private
   */
  #getRoot() {
    return this.#parent || this;
  }
  /**
   * Get logger-specific symbols using the resolved theme.
   * @private
   */
  #getSymbols() {
    const theme = this.#getTheme();
    const supported = (0, import_is_unicode_supported.default)();
    const colors = /* @__PURE__ */ getYoctocolors();
    return {
      __proto__: null,
      fail: /* @__PURE__ */ applyColor(supported ? "\u2716" : "\xD7", theme.colors.error, colors),
      info: /* @__PURE__ */ applyColor(supported ? "\u2139" : "i", theme.colors.info, colors),
      progress: /* @__PURE__ */ applyColor(supported ? "\u2234" : ":.", theme.colors.step, colors),
      skip: /* @__PURE__ */ applyColor(supported ? "\u21BB" : "@", theme.colors.step, colors),
      step: /* @__PURE__ */ applyColor(supported ? "\u2192" : ">", theme.colors.step, colors),
      success: /* @__PURE__ */ applyColor(supported ? "\u2714" : "\u221A", theme.colors.success, colors),
      warn: /* @__PURE__ */ applyColor(supported ? "\u26A0" : "\u203C", theme.colors.warning, colors)
    };
  }
  /**
   * Get the target stream for this logger instance.
   * @private
   */
  #getTargetStream() {
    return this.#boundStream || "stderr";
  }
  /**
   * Get the resolved theme for this logger instance.
   * Returns instance theme if set, otherwise falls back to context theme.
   * @private
   */
  #getTheme() {
    return this.#theme ?? (0, import_context.getTheme)();
  }
  /**
   * Set indentation for a specific stream.
   * @private
   */
  #setIndent(stream, value) {
    const root = this.#getRoot();
    if (stream === "stderr") {
      root.#stderrIndention = value;
    } else {
      root.#stdoutIndention = value;
    }
  }
  /**
   * Set lastWasBlank state for a specific stream.
   * @private
   */
  #setLastWasBlank(stream, value) {
    const root = this.#getRoot();
    if (stream === "stderr") {
      root.#stderrLastWasBlank = value;
    } else {
      root.#stdoutLastWasBlank = value;
    }
  }
  /**
   * Strip log symbols from the start of text.
   * @private
   */
  #stripSymbols(text) {
    return text.replace(/^(?:[✖✗×⚠‼✔✓√ℹ→∴↻]|:.)[\uFE0F\s]*/u, "");
  }
  /**
   * Apply a method with a symbol prefix.
   * @private
   */
  #symbolApply(symbolType, args) {
    const con = this.#getConsole();
    let text = args.at(0);
    let extras;
    if (typeof text === "string") {
      text = this.#stripSymbols(text);
      extras = args.slice(1);
    } else {
      extras = args;
      text = "";
    }
    const indent = this.#getIndent("stderr");
    const symbols = this.#getSymbols();
    con.error(
      (0, import_strings.applyLinePrefix)(`${symbols[symbolType]} ${text}`, {
        prefix: indent
      }),
      ...extras
    );
    this[lastWasBlankSymbol](false, "stderr");
    this[incLogCallCountSymbol]();
    return this;
  }
  /**
   * Gets a logger instance bound exclusively to stderr.
   *
   * All logging operations on this instance will write to stderr only.
   * Indentation is tracked separately from stdout. The instance is
   * cached and reused on subsequent accesses.
   *
   * @returns A logger instance bound to stderr
   *
   * @example
   * ```typescript
   * // Write errors to stderr
   * logger.stderr.error('Configuration invalid')
   * logger.stderr.warn('Using fallback settings')
   *
   * // Indent only affects stderr
   * logger.stderr.indent()
   * logger.stderr.error('Nested error details')
   * logger.stderr.dedent()
   * ```
   */
  get stderr() {
    if (!this.#stderrLogger) {
      const ctorArgs = privateConstructorArgs.get(this) ?? [];
      const instance = new Logger(...ctorArgs);
      instance.#parent = this;
      instance.#boundStream = "stderr";
      instance.#options = { __proto__: null, ...this.#options };
      instance.#theme = this.#theme;
      this.#stderrLogger = instance;
    }
    return this.#stderrLogger;
  }
  /**
   * Gets a logger instance bound exclusively to stdout.
   *
   * All logging operations on this instance will write to stdout only.
   * Indentation is tracked separately from stderr. The instance is
   * cached and reused on subsequent accesses.
   *
   * @returns A logger instance bound to stdout
   *
   * @example
   * ```typescript
   * // Write normal output to stdout
   * logger.stdout.log('Processing started')
   * logger.stdout.log('Items processed: 42')
   *
   * // Indent only affects stdout
   * logger.stdout.indent()
   * logger.stdout.log('Detailed output')
   * logger.stdout.dedent()
   * ```
   */
  get stdout() {
    if (!this.#stdoutLogger) {
      const ctorArgs = privateConstructorArgs.get(this) ?? [];
      const instance = new Logger(...ctorArgs);
      instance.#parent = this;
      instance.#boundStream = "stdout";
      instance.#options = { __proto__: null, ...this.#options };
      instance.#theme = this.#theme;
      this.#stdoutLogger = instance;
    }
    return this.#stdoutLogger;
  }
  /**
   * Gets the total number of log calls made on this logger instance.
   *
   * Tracks all logging method calls including `log()`, `error()`, `warn()`,
   * `success()`, `fail()`, etc. Useful for testing and monitoring logging activity.
   *
   * @returns The number of times logging methods have been called
   *
   * @example
   * ```typescript
   * logger.log('Message 1')
   * logger.error('Message 2')
   * console.log(logger.logCallCount) // 2
   * ```
   */
  get logCallCount() {
    const root = this.#getRoot();
    return root.#logCallCount;
  }
  /**
   * Increments the internal log call counter.
   *
   * This is called automatically by logging methods and should not
   * be called directly in normal usage.
   *
   * @returns The logger instance for chaining
   */
  [incLogCallCountSymbol]() {
    const root = this.#getRoot();
    root.#logCallCount += 1;
    return this;
  }
  /**
   * Sets whether the last logged line was blank.
   *
   * Used internally to track blank lines and prevent duplicate spacing.
   * This is called automatically by logging methods.
   *
   * @param value - Whether the last line was blank
   * @param stream - Optional stream to update (defaults to both streams if not bound, or target stream if bound)
   * @returns The logger instance for chaining
   */
  [lastWasBlankSymbol](value, stream) {
    if (stream) {
      this.#setLastWasBlank(stream, !!value);
    } else if (this.#boundStream) {
      this.#setLastWasBlank(this.#boundStream, !!value);
    } else {
      this.#setLastWasBlank("stderr", !!value);
      this.#setLastWasBlank("stdout", !!value);
    }
    return this;
  }
  /**
   * Logs an assertion failure message if the value is falsy.
   *
   * Works like `console.assert()` but returns the logger for chaining.
   * If the value is truthy, nothing is logged. If falsy, logs an error
   * message with an assertion failure.
   *
   * @param value - The value to test
   * @param message - Optional message and additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.assert(true, 'This will not log')
   * logger.assert(false, 'Assertion failed: value is false')
   * logger.assert(items.length > 0, 'No items found')
   * ```
   */
  assert(value, ...message) {
    const con = this.#getConsole();
    con.assert(value, message[0], ...message.slice(1));
    this[lastWasBlankSymbol](false);
    return value ? this : this[incLogCallCountSymbol]();
  }
  /**
   * Clears the current line in the terminal.
   *
   * Moves the cursor to the beginning of the line and clears all content.
   * Works in both TTY and non-TTY environments. Useful for clearing
   * progress indicators created with `progress()`.
   *
   * The stream to clear (stderr or stdout) depends on whether the logger
   * is stream-bound.
   *
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.progress('Loading...')
   * // ... do work ...
   * logger.clearLine()
   * logger.success('Loaded')
   *
   * // Clear multiple progress updates
   * for (const file of files) {
   *   logger.progress(`Processing ${file}`)
   *   processFile(file)
   *   logger.clearLine()
   * }
   * logger.success('All files processed')
   * ```
   */
  clearLine() {
    const con = this.#getConsole();
    const stream = this.#getTargetStream();
    const streamObj = stream === "stderr" ? con._stderr : con._stdout;
    if (streamObj.isTTY) {
      streamObj.cursorTo(0);
      streamObj.clearLine(0);
    } else {
      streamObj.write("\r\x1B[K");
    }
    return this;
  }
  /**
   * Clears the visible terminal screen.
   *
   * Only available on the main logger instance, not on stream-bound instances
   * (`.stderr` or `.stdout`). Resets the log call count and blank line tracking
   * if the output is a TTY.
   *
   * @returns The logger instance for chaining
   * @throws {Error} If called on a stream-bound logger instance
   *
   * @example
   * ```typescript
   * logger.log('Some output')
   * logger.clearVisible()  // Screen is now clear
   *
   * // Error: Can't call on stream-bound instance
   * logger.stderr.clearVisible()  // throws
   * ```
   */
  clearVisible() {
    if (this.#boundStream) {
      throw new Error(
        "clearVisible() is only available on the main logger instance, not on stream-bound instances"
      );
    }
    const con = this.#getConsole();
    con.clear();
    if (con._stdout.isTTY) {
      ;
      this[lastWasBlankSymbol](true);
      this.#logCallCount = 0;
    }
    return this;
  }
  /**
   * Increments and logs a counter for the given label.
   *
   * Each unique label maintains its own counter. Works like `console.count()`.
   *
   * @param label - Optional label for the counter
   * @default 'default'
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.count('requests')  // requests: 1
   * logger.count('requests')  // requests: 2
   * logger.count('errors')    // errors: 1
   * logger.count()            // default: 1
   * ```
   */
  count(label) {
    const con = this.#getConsole();
    con.count(label);
    this[lastWasBlankSymbol](false);
    return this[incLogCallCountSymbol]();
  }
  /**
   * Creates a task that logs start and completion messages automatically.
   *
   * Returns a task object with a `run()` method that executes the provided
   * function and logs "Starting task: {name}" before execution and
   * "Completed task: {name}" after completion.
   *
   * @param name - The name of the task
   * @returns A task object with a `run()` method
   *
   * @example
   * ```typescript
   * const task = logger.createTask('Database Migration')
   * const result = task.run(() => {
   *   // Logs: "Starting task: Database Migration"
   *   migrateDatabase()
   *   return 'success'
   *   // Logs: "Completed task: Database Migration"
   * })
   * console.log(result)  // 'success'
   * ```
   */
  createTask(name) {
    return {
      run: (f) => {
        this.log(`Starting task: ${name}`);
        const result = f();
        this.log(`Completed task: ${name}`);
        return result;
      }
    };
  }
  /**
   * Decreases the indentation level by removing spaces from the prefix.
   *
   * When called on the main logger, affects both stderr and stdout indentation.
   * When called on a stream-bound logger (`.stderr` or `.stdout`), affects
   * only that stream's indentation.
   *
   * @param spaces - Number of spaces to remove from indentation
   * @default 2
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.indent()
   * logger.log('Indented')
   * logger.dedent()
   * logger.log('Back to normal')
   *
   * // Remove custom amount
   * logger.indent(4)
   * logger.log('Four spaces')
   * logger.dedent(4)
   *
   * // Stream-specific dedent
   * logger.stdout.indent()
   * logger.stdout.log('Indented stdout')
   * logger.stdout.dedent()
   * ```
   */
  dedent(spaces = 2) {
    if (this.#boundStream) {
      const current = this.#getIndent(this.#boundStream);
      this.#setIndent(this.#boundStream, current.slice(0, -spaces));
    } else {
      const stderrCurrent = this.#getIndent("stderr");
      const stdoutCurrent = this.#getIndent("stdout");
      this.#setIndent("stderr", stderrCurrent.slice(0, -spaces));
      this.#setIndent("stdout", stdoutCurrent.slice(0, -spaces));
    }
    return this;
  }
  /**
   * Displays an object's properties in a formatted way.
   *
   * Works like `console.dir()` with customizable options for depth,
   * colors, etc. Useful for inspecting complex objects.
   *
   * @param obj - The object to display
   * @param options - Optional formatting options (Node.js inspect options)
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * const obj = { a: 1, b: { c: 2, d: { e: 3 } } }
   * logger.dir(obj)
   * logger.dir(obj, { depth: 1 })  // Limit nesting depth
   * logger.dir(obj, { colors: true })  // Enable colors
   * ```
   */
  dir(obj, options) {
    const con = this.#getConsole();
    con.dir(obj, options);
    this[lastWasBlankSymbol](false);
    return this[incLogCallCountSymbol]();
  }
  /**
   * Displays data as XML/HTML in a formatted way.
   *
   * Works like `console.dirxml()`. In Node.js, behaves the same as `dir()`.
   *
   * @param data - The data to display
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.dirxml(document.body)  // In browser environments
   * logger.dirxml(xmlObject)       // In Node.js
   * ```
   */
  dirxml(...data) {
    const con = this.#getConsole();
    con.dirxml(data);
    this[lastWasBlankSymbol](false);
    return this[incLogCallCountSymbol]();
  }
  /**
   * Logs a completion message with a success symbol (alias for `success()`).
   *
   * Provides semantic clarity when marking something as "done". Does NOT
   * automatically clear the current line - call `clearLine()` first if
   * needed after using `progress()`.
   *
   * @param args - Message and additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.done('Task completed')
   *
   * // After progress indicator
   * logger.progress('Processing...')
   * // ... do work ...
   * logger.clearLine()
   * logger.done('Processing complete')
   * ```
   */
  done(...args) {
    return this.#symbolApply("success", args);
  }
  /**
   * Logs an error message to stderr.
   *
   * Automatically applies current indentation. All arguments are formatted
   * and logged like `console.error()`.
   *
   * @param args - Message and additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.error('Build failed')
   * logger.error('Error code:', 500)
   * logger.error('Details:', { message: 'Not found' })
   * ```
   */
  error(...args) {
    return this.#apply("error", args);
  }
  /**
   * Logs a newline to stderr only if the last line wasn't already blank.
   *
   * Prevents multiple consecutive blank lines. Useful for adding spacing
   * between sections without creating excessive whitespace.
   *
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.error('Error message')
   * logger.errorNewline()  // Adds blank line
   * logger.errorNewline()  // Does nothing (already blank)
   * logger.error('Next section')
   * ```
   */
  errorNewline() {
    return this.#getLastWasBlank("stderr") ? this : this.error("");
  }
  /**
   * Logs a failure message with a red colored fail symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.fail` (red ✖).
   * Always outputs to stderr. If the message starts with an existing
   * symbol, it will be stripped and replaced.
   *
   * @param args - Message and additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.fail('Build failed')
   * logger.fail('Test suite failed:', { passed: 5, failed: 3 })
   * ```
   */
  fail(...args) {
    return this.#symbolApply("fail", args);
  }
  /**
   * Starts a new indented log group.
   *
   * If a label is provided, it's logged before increasing indentation.
   * Groups can be nested. Each group increases indentation by the
   * `kGroupIndentWidth` (default 2 spaces). Call `groupEnd()` to close.
   *
   * @param label - Optional label to display before the group
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.group('Processing files:')
   * logger.log('file1.js')
   * logger.log('file2.js')
   * logger.groupEnd()
   *
   * // Nested groups
   * logger.group('Outer')
   * logger.log('Outer content')
   * logger.group('Inner')
   * logger.log('Inner content')
   * logger.groupEnd()
   * logger.groupEnd()
   * ```
   */
  group(...label) {
    const { length } = label;
    if (length) {
      ReflectApply(this.log, this, label);
    }
    this.indent(this[getKGroupIndentationWidthSymbol()]);
    if (length) {
      ;
      this[lastWasBlankSymbol](false);
      this[incLogCallCountSymbol]();
    }
    return this;
  }
  /**
   * Starts a new collapsed log group (alias for `group()`).
   *
   * In browser consoles, this creates a collapsed group. In Node.js,
   * it behaves identically to `group()`.
   *
   * @param label - Optional label to display before the group
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.groupCollapsed('Details')
   * logger.log('Hidden by default in browsers')
   * logger.groupEnd()
   * ```
   */
  // groupCollapsed is an alias of group.
  // https://nodejs.org/api/console.html#consolegroupcollapsed
  groupCollapsed(...label) {
    return ReflectApply(this.group, this, label);
  }
  /**
   * Ends the current log group and decreases indentation.
   *
   * Must be called once for each `group()` or `groupCollapsed()` call
   * to properly close the group and restore indentation.
   *
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.group('Group 1')
   * logger.log('Content')
   * logger.groupEnd()  // Closes 'Group 1'
   * ```
   */
  groupEnd() {
    this.dedent(this[getKGroupIndentationWidthSymbol()]);
    return this;
  }
  /**
   * Increases the indentation level by adding spaces to the prefix.
   *
   * When called on the main logger, affects both stderr and stdout indentation.
   * When called on a stream-bound logger (`.stderr` or `.stdout`), affects
   * only that stream's indentation. Maximum indentation is 1000 spaces.
   *
   * @param spaces - Number of spaces to add to indentation
   * @default 2
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.log('Level 0')
   * logger.indent()
   * logger.log('Level 1')
   * logger.indent()
   * logger.log('Level 2')
   * logger.dedent()
   * logger.dedent()
   *
   * // Custom indent amount
   * logger.indent(4)
   * logger.log('Indented 4 spaces')
   * logger.dedent(4)
   *
   * // Stream-specific indent
   * logger.stdout.indent()
   * logger.stdout.log('Only stdout is indented')
   * ```
   */
  indent(spaces = 2) {
    const spacesToAdd = " ".repeat(Math.min(spaces, maxIndentation));
    if (this.#boundStream) {
      const current = this.#getIndent(this.#boundStream);
      this.#setIndent(this.#boundStream, current + spacesToAdd);
    } else {
      const stderrCurrent = this.#getIndent("stderr");
      const stdoutCurrent = this.#getIndent("stdout");
      this.#setIndent("stderr", stderrCurrent + spacesToAdd);
      this.#setIndent("stdout", stdoutCurrent + spacesToAdd);
    }
    return this;
  }
  /**
   * Logs an informational message with a blue colored info symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.info` (blue ℹ).
   * Always outputs to stderr. If the message starts with an existing
   * symbol, it will be stripped and replaced.
   *
   * @param args - Message and additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.info('Starting build process')
   * logger.info('Configuration loaded:', config)
   * logger.info('Using cache directory:', cacheDir)
   * ```
   */
  info(...args) {
    return this.#symbolApply("info", args);
  }
  /**
   * Logs a message to stdout.
   *
   * Automatically applies current indentation. All arguments are formatted
   * and logged like `console.log()`. This is the primary method for
   * standard output.
   *
   * @param args - Message and additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.log('Processing complete')
   * logger.log('Items processed:', 42)
   * logger.log('Results:', { success: true, count: 10 })
   *
   * // Method chaining
   * logger.log('Step 1').log('Step 2').log('Step 3')
   * ```
   */
  log(...args) {
    return this.#apply("log", args);
  }
  /**
   * Logs a newline to stdout only if the last line wasn't already blank.
   *
   * Prevents multiple consecutive blank lines. Useful for adding spacing
   * between sections without creating excessive whitespace.
   *
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.log('Section 1')
   * logger.logNewline()  // Adds blank line
   * logger.logNewline()  // Does nothing (already blank)
   * logger.log('Section 2')
   * ```
   */
  logNewline() {
    return this.#getLastWasBlank("stdout") ? this : this.log("");
  }
  /**
   * Shows a progress indicator that can be cleared with `clearLine()`.
   *
   * Displays a simple status message with a '∴' prefix. Does not include
   * animation or spinner. Intended to be cleared once the operation completes.
   * The output stream (stderr or stdout) depends on whether the logger is
   * stream-bound.
   *
   * @param text - The progress message to display
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.progress('Processing files...')
   * // ... do work ...
   * logger.clearLine()
   * logger.success('Files processed')
   *
   * // Stream-specific progress
   * logger.stdout.progress('Loading...')
   * // ... do work ...
   * logger.stdout.clearLine()
   * logger.stdout.log('Done')
   * ```
   */
  progress(text) {
    const con = this.#getConsole();
    const stream = this.#getTargetStream();
    const streamObj = stream === "stderr" ? con._stderr : con._stdout;
    const symbols = this.#getSymbols();
    streamObj.write(`${symbols.progress} ${text}`);
    this[lastWasBlankSymbol](false);
    return this;
  }
  /**
   * Resets all indentation to zero.
   *
   * When called on the main logger, resets both stderr and stdout indentation.
   * When called on a stream-bound logger (`.stderr` or `.stdout`), resets
   * only that stream's indentation.
   *
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.indent().indent().indent()
   * logger.log('Very indented')
   * logger.resetIndent()
   * logger.log('Back to zero indentation')
   *
   * // Reset only stdout
   * logger.stdout.resetIndent()
   * ```
   */
  resetIndent() {
    if (this.#boundStream) {
      this.#setIndent(this.#boundStream, "");
    } else {
      this.#setIndent("stderr", "");
      this.#setIndent("stdout", "");
    }
    return this;
  }
  /**
   * Logs a skip message with a cyan colored skip symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.skip` (cyan ↻).
   * Always outputs to stderr. If the message starts with an existing
   * symbol, it will be stripped and replaced.
   *
   * @param args - Message and additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.skip('Test skipped due to environment')
   * logger.skip('Skipping optional step')
   * logger.skip('Feature disabled, skipping')
   * ```
   */
  skip(...args) {
    return this.#symbolApply("skip", args);
  }
  /**
   * Logs a main step message with a cyan arrow symbol and blank line before it.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.step` (cyan →) and
   * adds a blank line before the message unless the last line was already blank.
   * Useful for marking major steps in a process with clear visual separation.
   * Always outputs to stdout. If the message starts with an existing symbol,
   * it will be stripped and replaced.
   *
   * @param msg - The step message to log
   * @param extras - Additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.step('Building project')
   * logger.log('Compiling TypeScript...')
   * logger.step('Running tests')
   * logger.log('Running test suite...')
   * // Output:
   * // [blank line]
   * // → Building project
   * // Compiling TypeScript...
   * // [blank line]
   * // → Running tests
   * // Running test suite...
   * ```
   */
  step(msg, ...extras) {
    if (!this.#getLastWasBlank("stdout")) {
      this.log("");
    }
    const text = this.#stripSymbols(msg);
    const indent = this.#getIndent("stdout");
    const symbols = this.#getSymbols();
    const con = this.#getConsole();
    con.log(
      (0, import_strings.applyLinePrefix)(`${symbols.step} ${text}`, {
        prefix: indent
      }),
      ...extras
    );
    this[lastWasBlankSymbol](false, "stdout");
    this[incLogCallCountSymbol]();
    return this;
  }
  /**
   * Logs an indented substep message (stateless).
   *
   * Adds a 2-space indent to the message without affecting the logger's
   * indentation state. Useful for showing sub-items under a main step.
   *
   * @param msg - The substep message to log
   * @param extras - Additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.log('Installing dependencies:')
   * logger.substep('Installing react')
   * logger.substep('Installing typescript')
   * logger.substep('Installing eslint')
   * // Output:
   * // Installing dependencies:
   * //   Installing react
   * //   Installing typescript
   * //   Installing eslint
   * ```
   */
  substep(msg, ...extras) {
    const indentedMsg = `  ${msg}`;
    return this.log(indentedMsg, ...extras);
  }
  /**
   * Logs a success message with a green colored success symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.success` (green ✔).
   * Always outputs to stderr. If the message starts with an existing
   * symbol, it will be stripped and replaced.
   *
   * @param args - Message and additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.success('Build completed')
   * logger.success('Tests passed:', { total: 42, passed: 42 })
   * logger.success('Deployment successful')
   * ```
   */
  success(...args) {
    return this.#symbolApply("success", args);
  }
  /**
   * Displays data in a table format.
   *
   * Works like `console.table()`. Accepts arrays of objects or
   * objects with nested objects. Optionally specify which properties
   * to include in the table.
   *
   * @param tabularData - The data to display as a table
   * @param properties - Optional array of property names to include
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * // Array of objects
   * logger.table([
   *   { name: 'Alice', age: 30 },
   *   { name: 'Bob', age: 25 }
   * ])
   *
   * // Specify properties to show
   * logger.table(users, ['name', 'email'])
   *
   * // Object with nested objects
   * logger.table({
   *   user1: { name: 'Alice', age: 30 },
   *   user2: { name: 'Bob', age: 25 }
   * })
   * ```
   */
  table(tabularData, properties) {
    const con = this.#getConsole();
    con.table(tabularData, properties);
    this[lastWasBlankSymbol](false);
    return this[incLogCallCountSymbol]();
  }
  /**
   * Starts a timer for measuring elapsed time.
   *
   * Creates a timer with the given label. Use `timeEnd()` with the same
   * label to stop the timer and log the elapsed time, or use `timeLog()`
   * to check the time without stopping the timer.
   *
   * @param label - Optional label for the timer
   * @default 'default'
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.time('operation')
   * // ... do work ...
   * logger.timeEnd('operation')
   * // Logs: "operation: 123.456ms"
   *
   * logger.time()
   * // ... do work ...
   * logger.timeEnd()
   * // Logs: "default: 123.456ms"
   * ```
   */
  time(label) {
    const con = this.#getConsole();
    con.time(label);
    return this;
  }
  /**
   * Ends a timer and logs the elapsed time.
   *
   * Logs the duration since `console.time()` or `logger.time()` was called
   * with the same label. The timer is stopped and removed.
   *
   * @param label - Optional label for the timer
   * @default 'default'
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.time('operation')
   * // ... do work ...
   * logger.timeEnd('operation')
   * // Logs: "operation: 123.456ms"
   *
   * logger.time()
   * // ... do work ...
   * logger.timeEnd()
   * // Logs: "default: 123.456ms"
   * ```
   */
  timeEnd(label) {
    const con = this.#getConsole();
    con.timeEnd(label);
    this[lastWasBlankSymbol](false);
    return this[incLogCallCountSymbol]();
  }
  /**
   * Logs the current value of a timer without stopping it.
   *
   * Logs the duration since `console.time()` was called with the same
   * label, but keeps the timer running. Can include additional data
   * to log alongside the time.
   *
   * @param label - Optional label for the timer
   * @param data - Additional data to log with the time
   * @default 'default'
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * console.time('process')
   * // ... partial work ...
   * logger.timeLog('process', 'Checkpoint 1')
   * // Logs: "process: 123.456ms Checkpoint 1"
   * // ... more work ...
   * logger.timeLog('process', 'Checkpoint 2')
   * // Logs: "process: 234.567ms Checkpoint 2"
   * console.timeEnd('process')
   * ```
   */
  timeLog(label, ...data) {
    const con = this.#getConsole();
    con.timeLog(label, ...data);
    this[lastWasBlankSymbol](false);
    return this[incLogCallCountSymbol]();
  }
  /**
   * Logs a stack trace to the console.
   *
   * Works like `console.trace()`. Shows the call stack leading to
   * where this method was called. Useful for debugging.
   *
   * @param message - Optional message to display with the trace
   * @param args - Additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * function debugFunction() {
   *   logger.trace('Debug point reached')
   * }
   *
   * logger.trace('Trace from here')
   * logger.trace('Error context:', { userId: 123 })
   * ```
   */
  trace(message, ...args) {
    const con = this.#getConsole();
    con.trace(message, ...args);
    this[lastWasBlankSymbol](false);
    return this[incLogCallCountSymbol]();
  }
  /**
   * Logs a warning message with a yellow colored warning symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.warn` (yellow ⚠).
   * Always outputs to stderr. If the message starts with an existing
   * symbol, it will be stripped and replaced.
   *
   * @param args - Message and additional arguments to log
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.warn('Deprecated API used')
   * logger.warn('Low memory:', { available: '100MB' })
   * logger.warn('Missing optional configuration')
   * ```
   */
  warn(...args) {
    return this.#symbolApply("warn", args);
  }
  /**
   * Writes text directly to stdout without a newline or indentation.
   *
   * Useful for progress indicators or custom formatting where you need
   * low-level control. Does not apply any indentation or formatting.
   *
   * @param text - The text to write
   * @returns The logger instance for chaining
   *
   * @example
   * ```typescript
   * logger.write('Processing... ')
   * // ... do work ...
   * logger.write('done\n')
   *
   * // Build a line incrementally
   * logger.write('Step 1')
   * logger.write('... Step 2')
   * logger.write('... Step 3\n')
   * ```
   */
  write(text) {
    const con = this.#getConsole();
    const ctorArgs = privateConstructorArgs.get(this) ?? [];
    const stdout = this.#originalStdout || ctorArgs[0]?.stdout || con._stdout;
    stdout.write(text);
    this[lastWasBlankSymbol](false);
    return this;
  }
}
let _prototypeInitialized = false;
function ensurePrototypeInitialized() {
  if (_prototypeInitialized) {
    return;
  }
  _prototypeInitialized = true;
  const entries = [
    [
      getKGroupIndentationWidthSymbol(),
      {
        ...consolePropAttributes,
        value: 2
      }
    ],
    [
      Symbol.toStringTag,
      {
        __proto__: null,
        configurable: true,
        value: "logger"
      }
    ]
  ];
  for (const { 0: key, 1: value } of Object.entries(globalConsole)) {
    if (!Logger.prototype[key] && typeof value === "function") {
      const { [key]: func } = {
        [key](...args) {
          let con = privateConsole.get(this);
          if (con === void 0) {
            const ctorArgs = privateConstructorArgs.get(this) ?? [];
            privateConstructorArgs.delete(this);
            if (ctorArgs.length) {
              con = /* @__PURE__ */ constructConsole(...ctorArgs);
            } else {
              con = /* @__PURE__ */ constructConsole({
                stdout: process.stdout,
                stderr: process.stderr
              });
              for (const { 0: k, 1: method } of boundConsoleEntries) {
                con[k] = method;
              }
            }
            privateConsole.set(this, con);
          }
          const result = con[key](...args);
          return result === void 0 || result === con ? this : result;
        }
      };
      entries.push([
        key,
        {
          ...consolePropAttributes,
          value: func
        }
      ]);
    }
  }
  Object.defineProperties(Logger.prototype, Object.fromEntries(entries));
}
let _logger;
function getDefaultLogger() {
  if (_logger === void 0) {
    _logger = new Logger();
  }
  return _logger;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  LOG_SYMBOLS,
  Logger,
  getDefaultLogger,
  incLogCallCountSymbol,
  lastWasBlankSymbol
});
