"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../_virtual/_rolldown/runtime.js');
const require_primordials_string = require('../primordials/string.js');
const require_primordials_math = require('../primordials/math.js');
const require_primordials_date = require('../primordials/date.js');
const require_primordials_object = require('../primordials/object.js');
const require_ansi_strip = require('../ansi/strip.js');
const require_strings_format = require('../strings/format.js');
let node_process = require("node:process");
node_process = require_runtime.__toESM(node_process);
let src_external_yoctocolors_cjs = require("../external/yoctocolors-cjs");
src_external_yoctocolors_cjs = require_runtime.__toESM(src_external_yoctocolors_cjs);

//#region src/stdio/progress.ts
/**
* @file Progress bar utilities for CLI applications. Provides various progress
*   indicators including bars, percentages, and spinners.
*/
var ProgressBar = class {
	current = 0;
	total;
	startTime;
	lastRender = 0;
	stream;
	options;
	terminated = false;
	lastDrawnWidth = 0;
	/**
	* Create a new progress bar instance.
	*
	* @example
	*   ;```ts
	*   const bar = new ProgressBar(100, {
	*     width: 50,
	*     format: ':bar :percent :current/:total :eta',
	*     color: 'green',
	*   })
	*   ```
	*
	* @param total - Total number of units for the progress bar.
	* @param options - Configuration options for the progress bar.
	*/
	constructor(total, options) {
		this.total = total;
		this.startTime = require_primordials_date.DateNow();
		this.stream = options?.stream || node_process.default.stderr;
		this.options = {
			width: 40,
			format: ":bar :percent :current/:total",
			complete: "█",
			incomplete: "░",
			head: "",
			clear: false,
			renderThrottle: 16,
			stream: this.stream,
			color: "cyan",
			...options
		};
	}
	/**
	* Update progress to a specific value and redraw the bar. Updates are
	* throttled to prevent excessive rendering (default ~60fps).
	*
	* @example
	*   ;```ts
	*   bar.update(50)
	*   bar.update(75, { status: 'Processing...' })
	*   ```
	*
	* @param current - Current progress value (will be clamped to total)
	* @param tokens - Optional custom tokens to replace in format string.
	*/
	update(current, tokens) {
		if (this.terminated) return;
		this.current = require_primordials_math.MathMin(current, this.total);
		/* c8 ignore start */
		const now = require_primordials_date.DateNow();
		if (now - this.lastRender < (this.options.renderThrottle ?? 16) && this.current < this.total) return;
		/* c8 ignore stop */
		this.lastRender = now;
		this.render(tokens);
		if (this.current >= this.total) this.terminate();
	}
	/**
	* Increment progress by a specified amount. Convenience method for
	* `update(current + amount)`.
	*
	* @example
	*   ;```ts
	*   bar.tick() // Increment by 1
	*   bar.tick(5) // Increment by 5
	*   bar.tick(1, { file: 'data.json' })
	*   ```
	*
	* @default amount 1
	*
	* @param amount - Amount to increment by.
	* @param tokens - Optional custom tokens to replace in format string.
	*/
	tick(amount = 1, tokens) {
		this.update(this.current + amount, tokens);
	}
	/**
	* Render the progress bar.
	*/
	render(tokens) {
		const colorFn = src_external_yoctocolors_cjs.default[this.options.color ?? "cyan"] || ((s) => s);
		const percent = this.total === 0 ? 0 : require_primordials_math.MathFloor(this.current / this.total * 100);
		const elapsed = require_primordials_date.DateNow() - this.startTime;
		const eta = this.current === 0 ? 0 : elapsed / this.current * (this.total - this.current);
		const availableWidth = this.options.width ?? 40;
		const filledWidth = this.total === 0 ? 0 : require_primordials_math.MathMin(availableWidth, Math.floor(this.current / this.total * availableWidth));
		const emptyWidth = require_primordials_math.MathMax(0, availableWidth - filledWidth);
		const filled = /* @__PURE__ */ require_strings_format.repeatString(this.options.complete ?? "█", filledWidth);
		const empty = /* @__PURE__ */ require_strings_format.repeatString(this.options.incomplete ?? "░", emptyWidth);
		const bar = colorFn(filled) + empty;
		let output = this.options.format ?? ":bar :percent :current/:total";
		/* c8 ignore stop */
		output = require_primordials_string.StringPrototypeReplace(output, ":bar", bar);
		output = output.replace(":percent", `${percent}%`);
		output = output.replace(":current", String(this.current));
		output = output.replace(":total", String(this.total));
		output = output.replace(":elapsed", this.formatTime(elapsed));
		output = output.replace(":eta", this.formatTime(eta));
		if (tokens) for (const [key, value] of require_primordials_object.ObjectEntries(tokens)) output = output.replace(`:${key}`, String(value));
		this.clearLine();
		this.stream.write(output);
		this.lastDrawnWidth = (/* @__PURE__ */ require_ansi_strip.stripAnsi(output)).length;
	}
	/**
	* Clear the current line.
	*/
	clearLine() {
		if (this.stream.isTTY) {
			this.stream.cursorTo(0);
			this.stream.clearLine(0);
		} else if (this.lastDrawnWidth > 0) this.stream.write(`\r${/* @__PURE__ */ require_strings_format.repeatString(" ", this.lastDrawnWidth)}\r`);
	}
	/**
	* Format time in seconds to human readable.
	*/
	formatTime(ms) {
		const seconds = require_primordials_math.MathMax(0, Math.round(ms / 1e3));
		if (seconds < 60) return `${seconds}s`;
		return `${require_primordials_math.MathFloor(seconds / 60)}m${seconds % 60}s`;
	}
	/**
	* Terminate the progress bar and optionally clear it. Called automatically
	* when progress reaches 100%. If `clear` option is true, removes the bar from
	* terminal. Otherwise, moves to next line to preserve the final state.
	*/
	terminate() {
		/* c8 ignore start */
		if (this.terminated) return;
		this.terminated = true;
		if (this.options.clear) this.clearLine();
		else this.stream.write("\n");
		/* c8 ignore stop */
	}
};
/**
* Create a simple progress indicator without a graphical bar. Returns a
* formatted string showing progress as percentage and fraction.
*
* @example
*   ;```ts
*   createProgressIndicator(50, 100)
*   // Returns: '[50%] 50/100'
*
*   createProgressIndicator(3, 10, 'Files')
*   // Returns: 'Files: [30%] 3/10'
*   ```
*
* @param current - Current progress value.
* @param total - Total progress value.
* @param label - Optional label prefix.
*
* @returns Formatted progress indicator string
*/
function createProgressIndicator(current, total, label) {
	const percent = total === 0 ? 0 : require_primordials_math.MathFloor(current / total * 100);
	const progress = `${current}/${total}`;
	let output = "";
	if (label) output += `${label}: `;
	output += `${src_external_yoctocolors_cjs.default.cyan(`[${percent}%]`)} ${progress}`;
	return output;
}

//#endregion
exports.ProgressBar = ProgressBar;
exports.createProgressIndicator = createProgressIndicator;