import { z } from 'zod';
import { spawn, execSync } from 'child_process';
import kill from 'tree-kill';
import { join } from 'path';
import { existsSync } from 'fs';
import { stderr } from 'stderr-lib';
import { XMLParser } from 'fast-xml-parser';

// src/tools/dcm2xml.ts

// src/types.ts
function ok(value) {
  return { ok: true, value };
}
function err(error) {
  return { ok: false, error };
}

// src/constants.ts
var DEFAULT_TIMEOUT_MS = 3e4;
var WINDOWS_SEARCH_PATHS = ["C:\\Program Files\\DCMTK\\bin", "C:\\Program Files (x86)\\DCMTK\\bin", "C:\\ProgramData\\chocolatey\\bin"];
var UNIX_SEARCH_PATHS = ["/usr/local/bin", "/usr/bin", "/opt/local/bin", "/opt/homebrew/bin"];
var REQUIRED_BINARIES = ["dcm2json", "dcm2xml", "dcmodify", "dcmdump", "dcmrecv", "dcmsend", "echoscu"];
var MAX_OUTPUT_BYTES = 100 * 1024 * 1024;

// src/exec.ts
function killTree(pid) {
  try {
    kill(pid);
  } catch {
  }
}
async function execCommand(binary, args, options) {
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  return new Promise((resolve) => {
    const child = spawn(binary, [...args], {
      cwd: options?.cwd,
      windowsHide: true,
      signal: options?.signal
    });
    wireSpawnListeners(child, timeoutMs, resolve);
  });
}
function wireSpawnListeners(child, timeoutMs, resolve) {
  let stdout = "";
  let stderr3 = "";
  let settled = false;
  const settle = (result) => {
    if (settled) return;
    settled = true;
    clearTimeout(timer);
    resolve(result);
  };
  const timer = setTimeout(() => {
    if (child.pid !== void 0 && child.pid !== null) killTree(child.pid);
    settle(err(new Error(`Process timed out after ${timeoutMs}ms`)));
  }, timeoutMs);
  child.stdout?.on("data", (chunk) => {
    stdout += String(chunk);
    if (stdout.length + stderr3.length > MAX_OUTPUT_BYTES) {
      if (child.pid !== void 0 && child.pid !== null) killTree(child.pid);
      settle(err(new Error(`Process output exceeded ${MAX_OUTPUT_BYTES} bytes`)));
    }
  });
  child.stderr?.on("data", (chunk) => {
    stderr3 += String(chunk);
    if (stdout.length + stderr3.length > MAX_OUTPUT_BYTES) {
      if (child.pid !== void 0 && child.pid !== null) killTree(child.pid);
      settle(err(new Error(`Process output exceeded ${MAX_OUTPUT_BYTES} bytes`)));
    }
  });
  child.on("error", (error) => {
    if (child.pid !== void 0 && child.pid !== null) killTree(child.pid);
    settle(err(new Error(`Process error: ${error.message}`)));
  });
  child.on("close", (code) => {
    settle(ok({ stdout, stderr: stderr3, exitCode: code ?? 1 }));
  });
}
async function spawnCommand(binary, args, options) {
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  return new Promise((resolve) => {
    const child = spawn(binary, [...args], {
      cwd: options?.cwd,
      env: options?.env ? { ...process.env, ...options.env } : void 0,
      windowsHide: true,
      signal: options?.signal
    });
    wireSpawnListeners(child, timeoutMs, resolve);
  });
}

// src/patterns.ts
var AE_TITLE_PATTERN = /^[A-Za-z0-9 -]+$/;
var DICOM_QUERY_KEY_PATTERN = /^[0-9A-Fa-f]{4},[0-9A-Fa-f]{4}(?:[\[.\]0-9A-Fa-f,]*)?(?:=.*)?$/;
function isValidDicomKey(key) {
  return DICOM_QUERY_KEY_PATTERN.test(key);
}
var PATH_TRAVERSAL_PATTERN = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
function isValidAETitle(value) {
  return AE_TITLE_PATTERN.test(value);
}
function isSafePath(p) {
  return !PATH_TRAVERSAL_PATTERN.test(p);
}

// src/findDcmtkPath.ts
var cachedPath;
var isWindows = process.platform === "win32";
function binaryName(name) {
  return isWindows ? `${name}.exe` : name;
}
function hasRequiredBinaries(dir) {
  for (const bin of REQUIRED_BINARIES) {
    if (!existsSync(join(dir, binaryName(bin)))) {
      return false;
    }
  }
  return true;
}
function findViaSystemPath(name) {
  try {
    const cmd = isWindows ? `where ${binaryName(name)}` : `which ${name}`;
    const result = execSync(cmd, { encoding: "utf-8", timeout: 5e3, windowsHide: true }).trim();
    const firstLine = result.split("\n")[0]?.trim();
    if (firstLine) {
      const lastSep = firstLine.lastIndexOf(isWindows ? "\\" : "/");
      if (lastSep >= 0) {
        return firstLine.substring(0, lastSep);
      }
    }
  } catch {
  }
  return void 0;
}
function searchEnvPath() {
  const envPath = process.env["DCMTK_PATH"];
  if (envPath === void 0 || envPath.length === 0) {
    return void 0;
  }
  if (!isSafePath(envPath)) {
    return err(new Error(`DCMTK_PATH="${envPath}" contains path traversal sequences`));
  }
  if (hasRequiredBinaries(envPath)) {
    return ok(envPath);
  }
  return err(new Error(`DCMTK_PATH="${envPath}" is set but required binaries are missing`));
}
function searchKnownPaths() {
  const searchPaths = isWindows ? WINDOWS_SEARCH_PATHS : UNIX_SEARCH_PATHS;
  for (const candidate of searchPaths) {
    if (hasRequiredBinaries(candidate)) {
      return candidate;
    }
  }
  return void 0;
}
function searchSystemPath() {
  const systemDir = findViaSystemPath(REQUIRED_BINARIES[0] ?? "dcm2json");
  if (systemDir !== void 0 && hasRequiredBinaries(systemDir)) {
    return systemDir;
  }
  return void 0;
}
function findDcmtkPath(options) {
  if (cachedPath !== void 0 && true) {
    return ok(cachedPath);
  }
  const envResult = searchEnvPath();
  if (envResult !== void 0) {
    if (envResult.ok) {
      cachedPath = envResult.value;
    }
    return envResult;
  }
  const knownPath = searchKnownPaths();
  if (knownPath !== void 0) {
    cachedPath = knownPath;
    return ok(knownPath);
  }
  const systemPath = searchSystemPath();
  if (systemPath !== void 0) {
    cachedPath = systemPath;
    return ok(systemPath);
  }
  return err(
    new Error(
      "DCMTK binaries not found. Install DCMTK and either:\n  - Set the DCMTK_PATH environment variable, or\n  - Install DCMTK to a standard location, or\n  - Ensure DCMTK binaries are on the system PATH"
    )
  );
}

// src/tools/_resolveBinary.ts
var isWindows2 = process.platform === "win32";
function resolveBinary(toolName) {
  const pathResult = findDcmtkPath();
  if (!pathResult.ok) {
    return err(pathResult.error);
  }
  const binaryName2 = isWindows2 ? `${toolName}.exe` : toolName;
  return ok(join(pathResult.value, binaryName2));
}

// src/tools/_toolError.ts
var MAX_ARGS_LENGTH = 200;
var MAX_STDERR_LENGTH = 500;
function truncate(value, maxLength) {
  if (value.length <= maxLength) {
    return value;
  }
  return `${value.substring(0, maxLength)}...`;
}
function createToolError(toolName, args, exitCode, stderr3) {
  const argsStr = truncate(args.join(" "), MAX_ARGS_LENGTH);
  const stderrStr = truncate(stderr3.trim(), MAX_STDERR_LENGTH);
  const parts = [`${toolName} failed (exit code ${String(exitCode)})`];
  if (argsStr.length > 0) {
    parts.push(`args: ${argsStr}`);
  }
  if (stderrStr.length > 0) {
    parts.push(`stderr: ${stderrStr}`);
  }
  return new Error(parts.join(" | "));
}
function createValidationError(toolName, zodError) {
  const parts = [];
  for (let i = 0; i < zodError.issues.length; i++) {
    const issue = zodError.issues[i];
    if (issue === void 0) continue;
    const path = issue.path.length > 0 ? issue.path.map(String).join(".") : "(root)";
    parts.push(`${path}: ${issue.message}`);
  }
  const detail = parts.length > 0 ? parts.join("; ") : "unknown validation error";
  return new Error(`${toolName}: invalid options \u2014 ${detail}`);
}

// src/tools/dcm2xml.ts
var Dcm2xmlCharset = {
  /** Use UTF-8 encoding (default). */
  UTF8: "utf8",
  /** Use Latin-1 encoding. */
  LATIN1: "latin1",
  /** Use ASCII encoding. */
  ASCII: "ascii"
};
var Dcm2xmlOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  namespace: z.boolean().optional(),
  charset: z.enum(["utf8", "latin1", "ascii"]).optional(),
  writeBinaryData: z.boolean().optional(),
  encodeBinaryBase64: z.boolean().optional()
}).strict().optional();
function buildArgs(inputPath, options) {
  const args = [];
  if (options?.namespace === true) {
    args.push("+Xn");
  }
  if (options?.charset === "latin1") {
    args.push("+Cl");
  } else if (options?.charset === "ascii") {
    args.push("+Ca");
  }
  if (options?.writeBinaryData === true) {
    args.push("+Wb");
    if (options.encodeBinaryBase64 !== false) {
      args.push("+Eb");
    }
  }
  args.push(inputPath);
  return args;
}
async function dcm2xml(inputPath, options) {
  const validation = Dcm2xmlOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcm2xml", validation.error));
  }
  const binaryResult = resolveBinary("dcm2xml");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs(inputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcm2xml", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ xml: result.value.stdout });
}
var PN_REPS = ["Alphabetic", "Ideographic", "Phonetic"];
var ARRAY_TAG_NAMES = /* @__PURE__ */ new Set(["DicomAttribute", "Value", "PersonName", "Item"]);
var KNOWN_VR_CODES = /* @__PURE__ */ new Set([
  "AE",
  "AS",
  "AT",
  "CS",
  "DA",
  "DS",
  "DT",
  "FD",
  "FL",
  "IS",
  "LO",
  "LT",
  "OB",
  "OD",
  "OF",
  "OL",
  "OV",
  "OW",
  "PN",
  "SH",
  "SL",
  "SQ",
  "SS",
  "ST",
  "SV",
  "TM",
  "UC",
  "UI",
  "UL",
  "UN",
  "UR",
  "US",
  "UT",
  "UV"
]);
function buildPnString(comp) {
  const parts = [comp.FamilyName ?? "", comp.GivenName ?? "", comp.MiddleName ?? "", comp.NamePrefix ?? "", comp.NameSuffix ?? ""];
  let last = parts.length - 1;
  for (; last >= 0; last--) {
    if (parts[last] !== "") break;
  }
  return parts.slice(0, last + 1).join("^");
}
function toArray(val) {
  if (Array.isArray(val)) return val;
  if (val === void 0 || val === null) return [];
  return [val];
}
function convertPersonName(pnNode) {
  const result = {};
  if (typeof pnNode !== "object" || pnNode === null) return result;
  const pn = pnNode;
  for (const rep of PN_REPS) {
    const repNode = pn[rep];
    if (repNode !== void 0 && typeof repNode === "object" && repNode !== null) {
      const str = buildPnString(repNode);
      if (str.length > 0) {
        result[rep] = str;
      }
    }
  }
  return result;
}
function safeString(val) {
  if (typeof val === "string") return val;
  if (typeof val === "number" || typeof val === "boolean") return String(val);
  return "";
}
function convertInlineBinary(attr, element) {
  element.InlineBinary = safeString(attr.InlineBinary);
}
function convertBulkDataURI(attr, element) {
  const bulkArray = toArray(attr.BulkDataURI);
  const firstBulk = bulkArray[0];
  if (typeof firstBulk === "object" && firstBulk !== null && "@_uri" in firstBulk) {
    element.BulkDataURI = safeString(firstBulk["@_uri"]);
  } else {
    element.BulkDataURI = safeString(firstBulk);
  }
}
function convertPNValue(attr, element) {
  const pnArray = toArray(attr.PersonName);
  const values = [];
  for (const pn of pnArray) {
    values.push(convertPersonName(pn));
  }
  if (values.length > 0) element.Value = values;
}
function convertSequence(attr, element) {
  const items = toArray(attr.Item);
  const values = [];
  for (const item of items) {
    if (typeof item !== "object" || item === null) continue;
    values.push(convertAttributes(item));
  }
  if (values.length > 0) element.Value = values;
}
function convertRegularValue(attr, element) {
  const valArray = toArray(attr.Value);
  const values = [];
  for (const v of valArray) {
    if (typeof v === "object" && v !== null && "#text" in v) {
      values.push(v["#text"]);
    } else {
      values.push(v);
    }
  }
  if (values.length > 0) element.Value = values;
}
function convertElement(attr) {
  const rawVr = attr["@_vr"];
  const vr = KNOWN_VR_CODES.has(rawVr) ? rawVr : "UN";
  const element = { vr };
  if (attr.InlineBinary !== void 0) {
    convertInlineBinary(attr, element);
  } else if (attr.BulkDataURI !== void 0) {
    convertBulkDataURI(attr, element);
  } else if (element.vr === "PN" && attr.PersonName !== void 0) {
    convertPNValue(attr, element);
  } else if (element.vr === "SQ" && attr.Item !== void 0) {
    convertSequence(attr, element);
  } else if (attr.Value !== void 0) {
    convertRegularValue(attr, element);
  }
  return Object.freeze(element);
}
function convertAttributes(obj) {
  const result = {};
  const attrs = toArray(obj["DicomAttribute"]);
  for (const attr of attrs) {
    if (typeof attr !== "object" || attr === null) continue;
    const xmlAttr = attr;
    const tag = xmlAttr["@_tag"];
    if (tag === void 0) continue;
    result[tag] = convertElement(xmlAttr);
  }
  return result;
}
var parser = new XMLParser({
  ignoreAttributes: false,
  attributeNamePrefix: "@_",
  parseTagValue: false,
  isArray: (name) => ARRAY_TAG_NAMES.has(name)
});
function xmlToJson(xml) {
  try {
    const parsed = parser.parse(xml);
    const root = parsed["NativeDicomModel"];
    if (root === void 0) {
      return err(new Error("Invalid dcm2xml output: missing NativeDicomModel root element"));
    }
    if (typeof root !== "object" || root === null) {
      return ok({});
    }
    return ok(convertAttributes(root));
  } catch (error) {
    return err(new Error(`Failed to parse dcm2xml XML: ${stderr(error).message}`));
  }
}

// src/tools/_repairJson.ts
var VALUE_ARRAY_PATTERN = /("Value"\s*:\s*\[)([\s\S]*?)(\])/g;
var BARE_NUMBER = /^-?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
function quoteIfBareNumber(token) {
  const trimmed = token.trim();
  if (BARE_NUMBER.test(trimmed)) {
    return `"${trimmed}"`;
  }
  return trimmed;
}
function repairInner(inner) {
  const trimmed = inner.trim();
  if (trimmed.length === 0) return inner;
  const tokens = [];
  let current = "";
  let inString = false;
  for (let i = 0; i < trimmed.length; i++) {
    const ch = trimmed[i];
    if (ch === '"' && (i === 0 || trimmed[i - 1] !== "\\")) {
      inString = !inString;
      current += ch;
    } else if (ch === "," && !inString) {
      tokens.push(current);
      current = "";
    } else {
      current += ch;
    }
  }
  tokens.push(current);
  return tokens.map(quoteIfBareNumber).join(", ");
}
function repairJson(raw) {
  return raw.replace(VALUE_ARRAY_PATTERN, (_match, prefix, inner, suffix) => {
    return `${prefix}${repairInner(inner)}${suffix}`;
  });
}

// src/tools/dcm2json.ts
var Dcm2jsonOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  directOnly: z.boolean().optional()
}).strict().optional();
async function tryXmlPath(inputPath, timeoutMs, signal) {
  const xmlBinary = resolveBinary("dcm2xml");
  if (!xmlBinary.ok) {
    return err(xmlBinary.error);
  }
  const xmlResult = await execCommand(xmlBinary.value, ["-nat", inputPath], { timeoutMs, signal });
  if (!xmlResult.ok) {
    return err(xmlResult.error);
  }
  if (xmlResult.value.exitCode !== 0) {
    return err(createToolError("dcm2xml", ["-nat", inputPath], xmlResult.value.exitCode, xmlResult.value.stderr));
  }
  const jsonResult = xmlToJson(xmlResult.value.stdout);
  if (!jsonResult.ok) {
    return err(jsonResult.error);
  }
  return ok({ data: jsonResult.value, source: "xml" });
}
async function tryDirectPath(inputPath, timeoutMs, signal) {
  const jsonBinary = resolveBinary("dcm2json");
  if (!jsonBinary.ok) {
    return err(jsonBinary.error);
  }
  const result = await execCommand(jsonBinary.value, [inputPath], { timeoutMs, signal });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcm2json", [inputPath], result.value.exitCode, result.value.stderr));
  }
  try {
    const repaired = repairJson(result.value.stdout);
    const data = JSON.parse(repaired);
    return ok({ data, source: "direct" });
  } catch (parseError) {
    return err(createToolError("dcm2json", [inputPath], 1, `Parse error: ${stderr(parseError).message}`));
  }
}
async function dcm2json(inputPath, options) {
  const validation = Dcm2jsonOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcm2json", validation.error));
  }
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const signal = options?.signal;
  if (options?.directOnly === true) {
    return tryDirectPath(inputPath, timeoutMs, signal);
  }
  const xmlResult = await tryXmlPath(inputPath, timeoutMs, signal);
  if (xmlResult.ok) {
    return xmlResult;
  }
  return tryDirectPath(inputPath, timeoutMs, signal);
}
var DcmdumpFormat = {
  /** Print standard DCMTK format. */
  STANDARD: "standard",
  /** Print tag and value only. */
  SHORT: "short"
};
var DcmdumpOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  format: z.enum(["standard", "short"]).optional(),
  allTags: z.boolean().optional(),
  searchTag: z.string().regex(/^\([0-9A-Fa-f]{4},[0-9A-Fa-f]{4}\)$/).optional(),
  printValues: z.boolean().optional()
}).strict().optional();
function buildArgs2(inputPath, options) {
  const args = [];
  if (options?.format === "short") {
    args.push("+L");
  }
  if (options?.allTags === true) {
    args.push("+P", "all");
  }
  if (options?.searchTag !== void 0) {
    const tag = options.searchTag.replace(/[()]/g, "");
    args.push("+P", tag);
  }
  if (options?.printValues === true) {
    args.push("+Vr");
  }
  args.push(inputPath);
  return args;
}
async function dcmdump(inputPath, options) {
  const validation = DcmdumpOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmdump", validation.error));
  }
  const binaryResult = resolveBinary("dcmdump");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs2(inputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmdump", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ text: result.value.stdout });
}
var TransferSyntax = {
  /** Implicit VR Little Endian. */
  IMPLICIT_LITTLE: "+ti",
  /** Explicit VR Little Endian. */
  EXPLICIT_LITTLE: "+te",
  /** Explicit VR Big Endian (deprecated in DICOM). */
  EXPLICIT_BIG: "+tb",
  /** JPEG Lossless. */
  JPEG_LOSSLESS: "+tl",
  /** JPEG 2000 Lossless. */
  JPEG2K_LOSSLESS: "+t2",
  /** RLE Lossless. */
  RLE: "+tr",
  /** Deflated Explicit VR Little Endian. */
  DEFLATED: "+td"
};
var VALID_TRANSFER_SYNTAXES = ["+ti", "+te", "+tb", "+tl", "+t2", "+tr", "+td"];
var DcmconvOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  transferSyntax: z.enum(VALID_TRANSFER_SYNTAXES)
}).strict();
async function dcmconv(inputPath, outputPath, options) {
  const validation = DcmconvOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmconv", validation.error));
  }
  const binaryResult = resolveBinary("dcmconv");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [options.transferSyntax, inputPath, outputPath];
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmconv", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var TAG_OR_PATH_PATTERN = /^\([0-9A-Fa-f]{4},[0-9A-Fa-f]{4}\)(\[\d+\](\.\([0-9A-Fa-f]{4},[0-9A-Fa-f]{4}\)(\[\d+\])?)*)?$/;
var TagModificationSchema = z.object({
  tag: z.string().regex(TAG_OR_PATH_PATTERN),
  value: z.string()
});
var DcmodifyOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  modifications: z.array(TagModificationSchema).optional().default([]),
  erasures: z.array(z.string()).optional(),
  erasePrivateTags: z.boolean().optional(),
  noBackup: z.boolean().optional(),
  insertIfMissing: z.boolean().optional(),
  ignoreMissingTags: z.boolean().optional()
}).strict().refine((data) => data.modifications.length > 0 || data.erasures !== void 0 && data.erasures.length > 0 || data.erasePrivateTags === true, {
  message: "At least one of modifications, erasures, or erasePrivateTags is required"
});
function buildArgs3(inputPath, options) {
  const args = [];
  if (options.noBackup !== false) {
    args.push("-nb");
  }
  if (options.ignoreMissingTags === true) {
    args.push("-imt");
  }
  const flag = options.insertIfMissing === true ? "-i" : "-m";
  const modifications = options.modifications ?? [];
  for (const mod of modifications) {
    args.push(flag, `${mod.tag}=${mod.value}`);
  }
  if (options.erasures !== void 0) {
    for (const erasure of options.erasures) {
      args.push("-e", erasure);
    }
  }
  if (options.erasePrivateTags === true) {
    args.push("-ep");
  }
  args.push(inputPath);
  return args;
}
async function dcmodify(inputPath, options) {
  const validation = DcmodifyOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmodify", validation.error));
  }
  const binaryResult = resolveBinary("dcmodify");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs3(inputPath, options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await spawnCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmodify", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ filePath: inputPath });
}
var DcmftestOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function dcmftest(inputPath, options) {
  const validation = DcmftestOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmftest", validation.error));
  }
  const binaryResult = resolveBinary("dcmftest");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmftest", args, result.value.exitCode, result.value.stderr));
  }
  const isDicom = result.value.stdout.includes("yes:");
  return ok({ isDicom });
}
var DEFAULT_DICOMDIR = "DICOMDIR";
var DcmgpdirOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  inputFiles: z.array(z.string().min(1)).min(1),
  outputFile: z.string().min(1).optional(),
  filesetId: z.string().min(1).optional(),
  inputDirectory: z.string().min(1).optional(),
  mapFilenames: z.boolean().optional(),
  inventAttributes: z.boolean().optional()
}).strict();
function buildArgs4(options) {
  const args = [];
  if (options.outputFile !== void 0) {
    args.push("+D", options.outputFile);
  }
  if (options.filesetId !== void 0) {
    args.push("+F", options.filesetId);
  }
  if (options.inputDirectory !== void 0) {
    args.push("+id", options.inputDirectory);
  }
  if (options.mapFilenames === true) {
    args.push("+m");
  }
  if (options.inventAttributes === true) {
    args.push("+I");
  }
  args.push(...options.inputFiles);
  return args;
}
async function dcmgpdir(options) {
  const validation = DcmgpdirOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmgpdir", validation.error));
  }
  const binaryResult = resolveBinary("dcmgpdir");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs4(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmgpdir", args, result.value.exitCode, result.value.stderr));
  }
  const outputPath = options.outputFile ?? DEFAULT_DICOMDIR;
  return ok({ outputPath });
}
var DEFAULT_DICOMDIR2 = "DICOMDIR";
var DcmmkdirOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  inputFiles: z.array(z.string().min(1)).min(1),
  outputFile: z.string().min(1).optional(),
  filesetId: z.string().min(1).optional(),
  append: z.boolean().optional(),
  inputDirectory: z.string().min(1).optional(),
  mapFilenames: z.boolean().optional(),
  inventAttributes: z.boolean().optional()
}).strict();
function buildArgs5(options) {
  const args = [];
  if (options.outputFile !== void 0) {
    args.push("+D", options.outputFile);
  }
  if (options.filesetId !== void 0) {
    args.push("+F", options.filesetId);
  }
  if (options.inputDirectory !== void 0) {
    args.push("+id", options.inputDirectory);
  }
  if (options.mapFilenames === true) {
    args.push("+m");
  }
  if (options.inventAttributes === true) {
    args.push("+I");
  }
  if (options.append === true) {
    args.push("+A");
  }
  args.push(...options.inputFiles);
  return args;
}
async function dcmmkdir(options) {
  const validation = DcmmkdirOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmmkdir", validation.error));
  }
  const binaryResult = resolveBinary("dcmmkdir");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs5(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmmkdir", args, result.value.exitCode, result.value.stderr));
  }
  const outputPath = options.outputFile ?? DEFAULT_DICOMDIR2;
  return ok({ outputPath });
}
var DcmqridxOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  indexDirectory: z.string().min(1),
  inputFiles: z.array(z.string().min(1)).min(1).optional(),
  print: z.boolean().optional(),
  notNew: z.boolean().optional()
}).strict().refine((data) => data.inputFiles !== void 0 && data.inputFiles.length > 0 || data.print === true, {
  message: "Either inputFiles (non-empty) or print must be specified"
});
function buildArgs6(options) {
  const args = [];
  if (options.print === true) {
    args.push("-p");
  }
  if (options.notNew === true) {
    args.push("-n");
  }
  args.push(options.indexDirectory);
  if (options.inputFiles !== void 0) {
    args.push(...options.inputFiles);
  }
  return args;
}
async function dcmqridx(options) {
  const validation = DcmqridxOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmqridx", validation.error));
  }
  const binaryResult = resolveBinary("dcmqridx");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs6(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmqridx", args, result.value.exitCode, result.value.stderr));
  }
  if (options.print === true) {
    return ok({ mode: "print", output: result.value.stdout });
  }
  return ok({ mode: "register" });
}
var Xml2dcmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  generateNewUIDs: z.boolean().optional(),
  validateDocument: z.boolean().optional()
}).strict().optional();
function buildArgs7(inputPath, outputPath, options) {
  const args = [];
  if (options?.generateNewUIDs === true) {
    args.push("+Ug");
  }
  if (options?.validateDocument === true) {
    args.push("+Vd");
  }
  args.push(inputPath, outputPath);
  return args;
}
async function xml2dcm(inputPath, outputPath, options) {
  const validation = Xml2dcmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("xml2dcm", validation.error));
  }
  const binaryResult = resolveBinary("xml2dcm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs7(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("xml2dcm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Json2dcmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function json2dcm(inputPath, outputPath, options) {
  const validation = Json2dcmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("json2dcm", validation.error));
  }
  const binaryResult = resolveBinary("json2dcm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("json2dcm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Dump2dcmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  generateNewUIDs: z.boolean().optional(),
  writeFileFormat: z.boolean().optional()
}).strict().optional();
function buildArgs8(inputPath, outputPath, options) {
  const args = [];
  if (options?.generateNewUIDs === true) {
    args.push("+Ug");
  }
  if (options?.writeFileFormat === true) {
    args.push("-F");
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dump2dcm(inputPath, outputPath, options) {
  const validation = Dump2dcmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dump2dcm", validation.error));
  }
  const binaryResult = resolveBinary("dump2dcm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs8(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dump2dcm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Img2dcmInputFormat = {
  /** JPEG image. */
  JPEG: "jpeg",
  /** BMP image. */
  BMP: "bmp"
};
var Img2dcmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  inputFormat: z.enum(["jpeg", "bmp"]).optional(),
  datasetFrom: z.string().min(1).optional()
}).strict().optional();
var FORMAT_FLAG_MAP = {
  jpeg: "JPEG",
  bmp: "BMP"
};
function buildArgs9(inputPath, outputPath, options) {
  const args = [];
  if (options?.inputFormat !== void 0) {
    args.push("-i", FORMAT_FLAG_MAP[options.inputFormat]);
  }
  if (options?.datasetFrom !== void 0) {
    args.push("-df", options.datasetFrom);
  }
  args.push(inputPath, outputPath);
  return args;
}
async function img2dcm(inputPath, outputPath, options) {
  const validation = Img2dcmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("img2dcm", validation.error));
  }
  const binaryResult = resolveBinary("img2dcm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs9(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("img2dcm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Pdf2dcmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function pdf2dcm(inputPath, outputPath, options) {
  const validation = Pdf2dcmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("pdf2dcm", validation.error));
  }
  const binaryResult = resolveBinary("pdf2dcm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("pdf2dcm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Dcm2pdfOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function dcm2pdf(inputPath, outputPath, options) {
  const validation = Dcm2pdfOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcm2pdf", validation.error));
  }
  const binaryResult = resolveBinary("dcm2pdf");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcm2pdf", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Cda2dcmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function cda2dcm(inputPath, outputPath, options) {
  const validation = Cda2dcmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("cda2dcm", validation.error));
  }
  const binaryResult = resolveBinary("cda2dcm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("cda2dcm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Dcm2cdaOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function dcm2cda(inputPath, outputPath, options) {
  const validation = Dcm2cdaOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcm2cda", validation.error));
  }
  const binaryResult = resolveBinary("dcm2cda");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcm2cda", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Stl2dcmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function stl2dcm(inputPath, outputPath, options) {
  const validation = Stl2dcmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("stl2dcm", validation.error));
  }
  const binaryResult = resolveBinary("stl2dcm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("stl2dcm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmcrleOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  uidAlways: z.boolean().optional()
}).strict().optional();
function buildArgs10(inputPath, outputPath, options) {
  const args = [];
  if (options?.uidAlways === true) {
    args.push("+ua");
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmcrle(inputPath, outputPath, options) {
  const validation = DcmcrleOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmcrle", validation.error));
  }
  const binaryResult = resolveBinary("dcmcrle");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs10(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmcrle", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmdrleOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  uidAlways: z.boolean().optional()
}).strict().optional();
function buildArgs11(inputPath, outputPath, options) {
  const args = [];
  if (options?.uidAlways === true) {
    args.push("+ua");
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmdrle(inputPath, outputPath, options) {
  const validation = DcmdrleOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmdrle", validation.error));
  }
  const binaryResult = resolveBinary("dcmdrle");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs11(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmdrle", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmencapOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  documentTitle: z.string().optional()
}).strict().optional();
function buildArgs12(inputPath, outputPath, options) {
  const args = [];
  if (options?.documentTitle !== void 0) {
    args.push("--title", options.documentTitle);
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmencap(inputPath, outputPath, options) {
  const validation = DcmencapOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmencap", validation.error));
  }
  const binaryResult = resolveBinary("dcmencap");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs12(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmencap", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmdecapOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function dcmdecap(inputPath, outputPath, options) {
  const validation = DcmdecapOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmdecap", validation.error));
  }
  const binaryResult = resolveBinary("dcmdecap");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmdecap", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmcjpegOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  quality: z.number().int().min(1).max(100).optional(),
  lossless: z.boolean().optional()
}).strict().optional();
function buildArgs13(inputPath, outputPath, options) {
  const args = [];
  if (options?.lossless === true) {
    args.push("+e1");
  }
  if (options?.quality !== void 0) {
    args.push("+q", String(options.quality));
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmcjpeg(inputPath, outputPath, options) {
  const validation = DcmcjpegOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmcjpeg", validation.error));
  }
  const binaryResult = resolveBinary("dcmcjpeg");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs13(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmcjpeg", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var ColorConversion = {
  /** Use photometric interpretation from the dataset. */
  PHOTOMETRIC: "photometric",
  /** Always convert to RGB. */
  ALWAYS: "always",
  /** Never convert color space. */
  NEVER: "never"
};
var COLOR_CONVERSION_FLAGS = {
  photometric: "+cp",
  always: "+ca",
  never: "+cn"
};
var DcmdjpegOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  colorConversion: z.enum(["photometric", "always", "never"]).optional()
}).strict().optional();
function buildArgs14(inputPath, outputPath, options) {
  const args = [];
  if (options?.colorConversion !== void 0) {
    args.push(COLOR_CONVERSION_FLAGS[options.colorConversion]);
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmdjpeg(inputPath, outputPath, options) {
  const validation = DcmdjpegOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmdjpeg", validation.error));
  }
  const binaryResult = resolveBinary("dcmdjpeg");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs14(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmdjpeg", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmcjplsOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  lossless: z.boolean().optional(),
  maxDeviation: z.number().int().min(0).optional()
}).strict().optional();
function buildArgs15(inputPath, outputPath, options) {
  const args = [];
  if (options?.lossless === false) {
    args.push("+en");
  } else if (options?.lossless === true) {
    args.push("+el");
  }
  if (options?.maxDeviation !== void 0) {
    args.push("+md", String(options.maxDeviation));
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmcjpls(inputPath, outputPath, options) {
  const validation = DcmcjplsOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmcjpls", validation.error));
  }
  const binaryResult = resolveBinary("dcmcjpls");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs15(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmcjpls", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var JplsColorConversion = {
  /** Use photometric interpretation from the dataset. */
  PHOTOMETRIC: "photometric",
  /** Always convert to RGB. */
  ALWAYS: "always",
  /** Never convert color space. */
  NEVER: "never"
};
var JPLS_COLOR_CONVERSION_FLAGS = {
  photometric: "+cp",
  always: "+ca",
  never: "+cn"
};
var DcmdjplsOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  colorConversion: z.enum(["photometric", "always", "never"]).optional()
}).strict().optional();
function buildArgs16(inputPath, outputPath, options) {
  const args = [];
  if (options?.colorConversion !== void 0) {
    args.push(JPLS_COLOR_CONVERSION_FLAGS[options.colorConversion]);
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmdjpls(inputPath, outputPath, options) {
  const validation = DcmdjplsOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmdjpls", validation.error));
  }
  const binaryResult = resolveBinary("dcmdjpls");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs16(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmdjpls", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Dcmj2pnmOutputFormat = {
  /** Portable aNy Map format. */
  PNM: "pnm",
  /** PNG format. */
  PNG: "png",
  /** BMP format. */
  BMP: "bmp",
  /** TIFF format. */
  TIFF: "tiff",
  /** JPEG format. */
  JPEG: "jpeg"
};
var OUTPUT_FORMAT_FLAGS = {
  pnm: "+op",
  png: "+on",
  bmp: "+ob",
  tiff: "+ot",
  jpeg: "+oj"
};
var Dcmj2pnmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  outputFormat: z.enum(["pnm", "png", "bmp", "tiff", "jpeg"]).optional(),
  frame: z.number().int().min(0).max(65535).optional()
}).strict().optional();
function buildArgs17(inputPath, outputPath, options) {
  const args = [];
  if (options?.outputFormat !== void 0) {
    args.push(OUTPUT_FORMAT_FLAGS[options.outputFormat]);
  }
  if (options?.frame !== void 0) {
    args.push("+F", String(options.frame));
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmj2pnm(inputPath, outputPath, options) {
  const validation = Dcmj2pnmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmj2pnm", validation.error));
  }
  const binaryResult = resolveBinary("dcmj2pnm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs17(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmj2pnm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var Dcm2pnmOutputFormat = {
  /** Portable aNy Map format. */
  PNM: "pnm",
  /** PNG format. */
  PNG: "png",
  /** BMP format. */
  BMP: "bmp",
  /** TIFF format. */
  TIFF: "tiff"
};
var DCM2PNM_FORMAT_FLAGS = {
  pnm: "+op",
  png: "+on",
  bmp: "+ob",
  tiff: "+ot"
};
var Dcm2pnmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  outputFormat: z.enum(["pnm", "png", "bmp", "tiff"]).optional(),
  frame: z.number().int().min(0).max(65535).optional()
}).strict().optional();
function buildArgs18(inputPath, outputPath, options) {
  const args = [];
  if (options?.outputFormat !== void 0) {
    args.push(DCM2PNM_FORMAT_FLAGS[options.outputFormat]);
  }
  if (options?.frame !== void 0) {
    args.push("+F", String(options.frame));
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcm2pnm(inputPath, outputPath, options) {
  const validation = Dcm2pnmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcm2pnm", validation.error));
  }
  const binaryResult = resolveBinary("dcm2pnm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs18(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcm2pnm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmscaleOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  xFactor: z.number().positive().max(100).optional(),
  yFactor: z.number().positive().max(100).optional(),
  xSize: z.number().int().positive().optional(),
  ySize: z.number().int().positive().optional()
}).strict().optional();
function buildArgs19(inputPath, outputPath, options) {
  const args = [];
  if (options?.xFactor !== void 0) {
    args.push("+Sxf", String(options.xFactor));
  }
  if (options?.yFactor !== void 0) {
    args.push("+Syf", String(options.yFactor));
  }
  if (options?.xSize !== void 0) {
    args.push("+Sxv", String(options.xSize));
  }
  if (options?.ySize !== void 0) {
    args.push("+Syv", String(options.ySize));
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmscale(inputPath, outputPath, options) {
  const validation = DcmscaleOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmscale", validation.error));
  }
  const binaryResult = resolveBinary("dcmscale");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs19(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmscale", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmquantOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  colors: z.number().int().min(2).max(65536).optional(),
  frame: z.number().int().min(0).max(65535).optional()
}).strict().optional();
function buildArgs20(inputPath, outputPath, options) {
  const args = [];
  if (options?.colors !== void 0) {
    args.push("+pc", String(options.colors));
  }
  if (options?.frame !== void 0) {
    args.push("+F", String(options.frame));
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmquant(inputPath, outputPath, options) {
  const validation = DcmquantOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmquant", validation.error));
  }
  const binaryResult = resolveBinary("dcmquant");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs20(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmquant", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmdspfnOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  monitorFile: z.string().min(1).optional(),
  cameraFile: z.string().min(1).optional(),
  printerFile: z.string().min(1).optional(),
  ambientLight: z.number().positive().optional()
}).strict().optional();
function buildArgs21(options) {
  const args = [];
  if (options?.monitorFile !== void 0) {
    args.push("+Im", options.monitorFile);
  }
  if (options?.cameraFile !== void 0) {
    args.push("+Ic", options.cameraFile);
  }
  if (options?.printerFile !== void 0) {
    args.push("+Ip", options.printerFile);
  }
  if (options?.ambientLight !== void 0) {
    args.push("+Ca", String(options.ambientLight));
  }
  return args;
}
async function dcmdspfn(options) {
  const validation = DcmdspfnOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmdspfn", validation.error));
  }
  const binaryResult = resolveBinary("dcmdspfn");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs21(options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmdspfn", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ text: result.value.stdout });
}
var Dcod2lumOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function dcod2lum(inputPath, outputPath, options) {
  const validation = Dcod2lumOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcod2lum", validation.error));
  }
  const binaryResult = resolveBinary("dcod2lum");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcod2lum", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DconvlumOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  ambientLight: z.number().positive().optional()
}).strict().optional();
function buildArgs22(inputPath, outputPath, options) {
  const args = [];
  if (options?.ambientLight !== void 0) {
    args.push("+Ca", String(options.ambientLight));
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dconvlum(inputPath, outputPath, options) {
  const validation = DconvlumOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dconvlum", validation.error));
  }
  const binaryResult = resolveBinary("dconvlum");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs22(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dconvlum", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var EchoscuOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  host: z.string().min(1),
  port: z.number().int().min(1).max(65535),
  callingAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  calledAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional()
}).strict();
function buildArgs23(options) {
  const args = [];
  if (options.callingAETitle !== void 0) {
    args.push("-aet", options.callingAETitle);
  }
  if (options.calledAETitle !== void 0) {
    args.push("-aec", options.calledAETitle);
  }
  args.push(options.host, String(options.port));
  return args;
}
async function echoscu(options) {
  const validation = EchoscuOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("echoscu", validation.error));
  }
  const binaryResult = resolveBinary("echoscu");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs23(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("echoscu", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ success: true, stderr: result.value.stderr });
}
var DcmsendOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  host: z.string().min(1),
  port: z.number().int().min(1).max(65535),
  files: z.array(z.string().min(1).refine(isSafePath, { message: "path traversal detected in file path" })).min(1),
  callingAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  calledAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  scanDirectory: z.boolean().optional()
}).strict();
function buildArgs24(options) {
  const args = [];
  if (options.callingAETitle !== void 0) {
    args.push("-aet", options.callingAETitle);
  }
  if (options.calledAETitle !== void 0) {
    args.push("-aec", options.calledAETitle);
  }
  if (options.scanDirectory === true) {
    args.push("--scan-directories");
  }
  args.push(options.host, String(options.port));
  args.push(...options.files);
  return args;
}
async function dcmsend(options) {
  const validation = DcmsendOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmsend", validation.error));
  }
  const binaryResult = resolveBinary("dcmsend");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs24(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmsend", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ success: true, stderr: result.value.stderr });
}
var ProposedTransferSyntax = {
  UNCOMPRESSED: "uncompressed",
  LITTLE_ENDIAN: "littleEndian",
  BIG_ENDIAN: "bigEndian",
  IMPLICIT_VR: "implicitVR",
  JPEG_LOSSLESS: "jpegLossless",
  JPEG_8BIT: "jpeg8Bit",
  JPEG_12BIT: "jpeg12Bit",
  J2K_LOSSLESS: "j2kLossless",
  J2K_LOSSY: "j2kLossy",
  JLS_LOSSLESS: "jlsLossless",
  JLS_LOSSY: "jlsLossy"
};
var PROPOSED_TS_FLAG_MAP = {
  [ProposedTransferSyntax.UNCOMPRESSED]: "-x=",
  [ProposedTransferSyntax.LITTLE_ENDIAN]: "-xe",
  [ProposedTransferSyntax.BIG_ENDIAN]: "-xb",
  [ProposedTransferSyntax.IMPLICIT_VR]: "-xi",
  [ProposedTransferSyntax.JPEG_LOSSLESS]: "-xs",
  [ProposedTransferSyntax.JPEG_8BIT]: "-xy",
  [ProposedTransferSyntax.JPEG_12BIT]: "-xx",
  [ProposedTransferSyntax.J2K_LOSSLESS]: "-xv",
  [ProposedTransferSyntax.J2K_LOSSY]: "-xw",
  [ProposedTransferSyntax.JLS_LOSSLESS]: "-xt",
  [ProposedTransferSyntax.JLS_LOSSY]: "-xu"
};
var StorescuOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  host: z.string().min(1),
  port: z.number().int().min(1).max(65535),
  files: z.array(z.string().min(1).refine(isSafePath, { message: "path traversal detected in file path" })).min(1),
  callingAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  calledAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  scanDirectories: z.boolean().optional(),
  recurse: z.boolean().optional(),
  proposedTransferSyntax: z.enum([
    "uncompressed",
    "littleEndian",
    "bigEndian",
    "implicitVR",
    "jpegLossless",
    "jpeg8Bit",
    "jpeg12Bit",
    "j2kLossless",
    "j2kLossy",
    "jlsLossless",
    "jlsLossy"
  ]).optional()
}).strict();
function buildArgs25(options) {
  const args = [];
  if (options.callingAETitle !== void 0) {
    args.push("-aet", options.callingAETitle);
  }
  if (options.calledAETitle !== void 0) {
    args.push("-aec", options.calledAETitle);
  }
  if (options.scanDirectories === true) {
    args.push("+sd");
  }
  if (options.recurse === true) {
    args.push("+r");
  }
  if (options.proposedTransferSyntax !== void 0) {
    args.push(PROPOSED_TS_FLAG_MAP[options.proposedTransferSyntax]);
  }
  args.push(options.host, String(options.port));
  args.push(...options.files);
  return args;
}
async function storescu(options) {
  const validation = StorescuOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("storescu", validation.error));
  }
  const binaryResult = resolveBinary("storescu");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs25(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("storescu", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ success: true, stderr: result.value.stderr });
}
var QueryModel = {
  WORKLIST: "worklist",
  PATIENT: "patient",
  STUDY: "study"
};
var QUERY_MODEL_FLAGS = {
  worklist: "-W",
  patient: "-P",
  study: "-S"
};
var FindscuOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  host: z.string().min(1),
  port: z.number().int().min(1).max(65535),
  callingAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  calledAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  queryModel: z.enum(["worklist", "patient", "study"]).optional(),
  keys: z.array(z.string().min(1).refine(isValidDicomKey, { message: "invalid DICOM query key format (expected XXXX,XXXX[=value])" })).optional(),
  extract: z.boolean().optional(),
  outputDirectory: z.string().min(1).refine(isSafePath, { message: "path traversal detected in outputDirectory" }).optional()
}).strict().refine((data) => data.extract !== true || data.outputDirectory !== void 0, {
  message: "outputDirectory is required when extract is true"
});
function buildArgs26(options) {
  const args = [];
  if (options.callingAETitle !== void 0) {
    args.push("-aet", options.callingAETitle);
  }
  if (options.calledAETitle !== void 0) {
    args.push("-aec", options.calledAETitle);
  }
  if (options.queryModel !== void 0) {
    args.push(QUERY_MODEL_FLAGS[options.queryModel]);
  }
  if (options.extract === true) {
    args.push("--extract");
  }
  if (options.outputDirectory !== void 0) {
    args.push("--output-directory", options.outputDirectory);
  }
  if (options.keys !== void 0) {
    for (const key of options.keys) {
      args.push("-k", key);
    }
  }
  args.push(options.host, String(options.port));
  return args;
}
async function findscu(options) {
  const validation = FindscuOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("findscu", validation.error));
  }
  const binaryResult = resolveBinary("findscu");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs26(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("findscu", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ success: true, stderr: result.value.stderr });
}
var MoveQueryModel = {
  PATIENT: "patient",
  STUDY: "study"
};
var MOVE_QUERY_MODEL_FLAGS = {
  patient: "-P",
  study: "-S"
};
var MovescuOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  host: z.string().min(1),
  port: z.number().int().min(1).max(65535),
  callingAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  calledAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  queryModel: z.enum(["patient", "study"]).optional(),
  keys: z.array(z.string().min(1).refine(isValidDicomKey, { message: "invalid DICOM query key format (expected XXXX,XXXX[=value])" })).optional(),
  moveDestination: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  outputDirectory: z.string().min(1).refine(isSafePath, { message: "path traversal detected in outputDirectory" }).optional()
}).strict();
function buildArgs27(options) {
  const args = [];
  if (options.callingAETitle !== void 0) {
    args.push("-aet", options.callingAETitle);
  }
  if (options.calledAETitle !== void 0) {
    args.push("-aec", options.calledAETitle);
  }
  if (options.queryModel !== void 0) {
    args.push(MOVE_QUERY_MODEL_FLAGS[options.queryModel]);
  }
  if (options.moveDestination !== void 0) {
    args.push("-aem", options.moveDestination);
  }
  if (options.outputDirectory !== void 0) {
    args.push("-od", options.outputDirectory);
  }
  if (options.keys !== void 0) {
    for (const key of options.keys) {
      args.push("-k", key);
    }
  }
  args.push(options.host, String(options.port));
  return args;
}
async function movescu(options) {
  const validation = MovescuOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("movescu", validation.error));
  }
  const binaryResult = resolveBinary("movescu");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs27(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("movescu", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ success: true, stderr: result.value.stderr });
}
var GetQueryModel = {
  PATIENT: "patient",
  STUDY: "study"
};
var GET_QUERY_MODEL_FLAGS = {
  patient: "-P",
  study: "-S"
};
var GetscuOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  host: z.string().min(1),
  port: z.number().int().min(1).max(65535),
  callingAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  calledAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  queryModel: z.enum(["patient", "study"]).optional(),
  keys: z.array(z.string().min(1).refine(isValidDicomKey, { message: "invalid DICOM query key format (expected XXXX,XXXX[=value])" })).optional(),
  outputDirectory: z.string().min(1).refine(isSafePath, { message: "path traversal detected in outputDirectory" }).optional()
}).strict();
function buildArgs28(options) {
  const args = [];
  if (options.callingAETitle !== void 0) {
    args.push("-aet", options.callingAETitle);
  }
  if (options.calledAETitle !== void 0) {
    args.push("-aec", options.calledAETitle);
  }
  if (options.queryModel !== void 0) {
    args.push(GET_QUERY_MODEL_FLAGS[options.queryModel]);
  }
  if (options.outputDirectory !== void 0) {
    args.push("-od", options.outputDirectory);
  }
  if (options.keys !== void 0) {
    for (const key of options.keys) {
      args.push("-k", key);
    }
  }
  args.push(options.host, String(options.port));
  return args;
}
async function getscu(options) {
  const validation = GetscuOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("getscu", validation.error));
  }
  const binaryResult = resolveBinary("getscu");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs28(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("getscu", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ success: true, stderr: result.value.stderr });
}
var TermscuOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  host: z.string().min(1),
  port: z.number().int().min(1).max(65535),
  callingAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  calledAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional()
}).strict();
function buildArgs29(options) {
  const args = [];
  if (options.callingAETitle !== void 0) {
    args.push("-aet", options.callingAETitle);
  }
  if (options.calledAETitle !== void 0) {
    args.push("-aec", options.calledAETitle);
  }
  args.push(options.host, String(options.port));
  return args;
}
async function termscu(options) {
  const validation = TermscuOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("termscu", validation.error));
  }
  const binaryResult = resolveBinary("termscu");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs29(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("termscu", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ success: true, stderr: result.value.stderr });
}
var DsrdumpOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  printFilename: z.boolean().optional(),
  printLong: z.boolean().optional(),
  printCodes: z.boolean().optional()
}).strict().optional();
function buildArgs30(inputPath, options) {
  const args = [];
  if (options?.printFilename === true) {
    args.push("+Pf");
  }
  if (options?.printLong === true) {
    args.push("+Pl");
  }
  if (options?.printCodes === true) {
    args.push("+Pc");
  }
  args.push(inputPath);
  return args;
}
async function dsrdump(inputPath, options) {
  const validation = DsrdumpOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dsrdump", validation.error));
  }
  const binaryResult = resolveBinary("dsrdump");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs30(inputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dsrdump", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ text: result.value.stdout });
}
var Dsr2xmlOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  useNamespace: z.boolean().optional(),
  addSchemaRef: z.boolean().optional()
}).strict().optional();
function buildArgs31(inputPath, options) {
  const args = [];
  if (options?.useNamespace === true) {
    args.push("+Xn");
  }
  if (options?.addSchemaRef === true) {
    args.push("+Xs");
  }
  args.push(inputPath);
  return args;
}
async function dsr2xml(inputPath, options) {
  const validation = Dsr2xmlOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dsr2xml", validation.error));
  }
  const binaryResult = resolveBinary("dsr2xml");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs31(inputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dsr2xml", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ text: result.value.stdout });
}
var Xml2dsrOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  generateNewUIDs: z.boolean().optional(),
  validateDocument: z.boolean().optional()
}).strict().optional();
function buildArgs32(inputPath, outputPath, options) {
  const args = [];
  if (options?.generateNewUIDs === true) {
    args.push("+Ug");
  }
  if (options?.validateDocument === true) {
    args.push("+Vd");
  }
  args.push(inputPath, outputPath);
  return args;
}
async function xml2dsr(inputPath, outputPath, options) {
  const validation = Xml2dsrOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("xml2dsr", validation.error));
  }
  const binaryResult = resolveBinary("xml2dsr");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs32(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("xml2dsr", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DrtdumpOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  printFilename: z.boolean().optional()
}).strict().optional();
function buildArgs33(inputPath, options) {
  const args = [];
  if (options?.printFilename === true) {
    args.push("+Pf");
  }
  args.push(inputPath);
  return args;
}
async function drtdump(inputPath, options) {
  const validation = DrtdumpOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("drtdump", validation.error));
  }
  const binaryResult = resolveBinary("drtdump");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs33(inputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("drtdump", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ text: result.value.stdout });
}
var DcmpsmkOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function dcmpsmk(inputPath, outputPath, options) {
  const validation = DcmpsmkOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmpsmk", validation.error));
  }
  const binaryResult = resolveBinary("dcmpsmk");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmpsmk", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmpschkOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function dcmpschk(inputPath, options) {
  const validation = DcmpschkOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmpschk", validation.error));
  }
  const binaryResult = resolveBinary("dcmpschk");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmpschk", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ text: result.value.stdout });
}
var DcmprscuOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  host: z.string().min(1),
  port: z.number().int().min(1).max(65535),
  callingAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  calledAETitle: z.string().min(1).max(16).refine(isValidAETitle, { message: "AE Title contains invalid characters" }).optional(),
  configFile: z.string().min(1).optional()
}).strict();
function buildArgs34(options) {
  const args = [];
  if (options.callingAETitle !== void 0) {
    args.push("-aet", options.callingAETitle);
  }
  if (options.calledAETitle !== void 0) {
    args.push("-aec", options.calledAETitle);
  }
  if (options.configFile !== void 0) {
    args.push("-c", options.configFile);
  }
  args.push(options.host, String(options.port));
  return args;
}
async function dcmprscu(options) {
  const validation = DcmprscuOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmprscu", validation.error));
  }
  const binaryResult = resolveBinary("dcmprscu");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs34(options);
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmprscu", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ success: true, stderr: result.value.stderr });
}
var DcmpsprtOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  configFile: z.string().min(1).optional()
}).strict().optional();
function buildArgs35(inputPath, options) {
  const args = [];
  if (options?.configFile !== void 0) {
    args.push("-c", options.configFile);
  }
  args.push(inputPath);
  return args;
}
async function dcmpsprt(inputPath, options) {
  const validation = DcmpsprtOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmpsprt", validation.error));
  }
  const binaryResult = resolveBinary("dcmpsprt");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs35(inputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmpsprt", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ text: result.value.stdout });
}
var Dcmp2pgmOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  presentationState: z.string().min(1).optional(),
  frame: z.number().int().min(0).max(65535).optional()
}).strict().optional();
function buildArgs36(inputPath, outputPath, options) {
  const args = [];
  if (options?.presentationState !== void 0) {
    args.push("-p", options.presentationState);
  }
  if (options?.frame !== void 0) {
    args.push("-f", String(options.frame));
  }
  args.push(inputPath, outputPath);
  return args;
}
async function dcmp2pgm(inputPath, outputPath, options) {
  const validation = Dcmp2pgmOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmp2pgm", validation.error));
  }
  const binaryResult = resolveBinary("dcmp2pgm");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs36(inputPath, outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmp2pgm", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var DcmmkcrvOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional()
}).strict().optional();
async function dcmmkcrv(inputPath, outputPath, options) {
  const validation = DcmmkcrvOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmmkcrv", validation.error));
  }
  const binaryResult = resolveBinary("dcmmkcrv");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = [inputPath, outputPath];
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmmkcrv", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}
var LutType = {
  /** Modality LUT. */
  MODALITY: "modality",
  /** Presentation LUT. */
  PRESENTATION: "presentation",
  /** VOI LUT. */
  VOI: "voi"
};
var LUT_TYPE_FLAGS = {
  modality: "+Tm",
  presentation: "+Tp",
  voi: "+Tv"
};
var DcmmklutOptionsSchema = z.object({
  timeoutMs: z.number().int().positive().optional(),
  signal: z.instanceof(AbortSignal).optional(),
  lutType: z.enum(["modality", "presentation", "voi"]).optional(),
  gamma: z.number().positive().optional(),
  entries: z.number().int().positive().optional(),
  bits: z.number().int().min(8).max(16).optional()
}).strict().optional();
function buildArgs37(outputPath, options) {
  const args = [];
  if (options?.lutType !== void 0) {
    args.push(LUT_TYPE_FLAGS[options.lutType]);
  }
  if (options?.gamma !== void 0) {
    args.push("+Cg", String(options.gamma));
  }
  if (options?.entries !== void 0) {
    args.push("-e", String(options.entries));
  }
  if (options?.bits !== void 0) {
    args.push("-b", String(options.bits));
  }
  args.push(outputPath);
  return args;
}
async function dcmmklut(outputPath, options) {
  const validation = DcmmklutOptionsSchema.safeParse(options);
  if (!validation.success) {
    return err(createValidationError("dcmmklut", validation.error));
  }
  const binaryResult = resolveBinary("dcmmklut");
  if (!binaryResult.ok) {
    return err(binaryResult.error);
  }
  const args = buildArgs37(outputPath, options);
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const result = await execCommand(binaryResult.value, args, {
    timeoutMs,
    signal: options?.signal
  });
  if (!result.ok) {
    return err(result.error);
  }
  if (result.value.exitCode !== 0) {
    return err(createToolError("dcmmklut", args, result.value.exitCode, result.value.stderr));
  }
  return ok({ outputPath });
}

export { ColorConversion, Dcm2pnmOutputFormat, Dcm2xmlCharset, DcmdumpFormat, Dcmj2pnmOutputFormat, GetQueryModel, Img2dcmInputFormat, JplsColorConversion, LutType, MoveQueryModel, ProposedTransferSyntax, QueryModel, TransferSyntax, cda2dcm, dcm2cda, dcm2json, dcm2pdf, dcm2pnm, dcm2xml, dcmcjpeg, dcmcjpls, dcmconv, dcmcrle, dcmdecap, dcmdjpeg, dcmdjpls, dcmdrle, dcmdspfn, dcmdump, dcmencap, dcmftest, dcmgpdir, dcmj2pnm, dcmmkcrv, dcmmkdir, dcmmklut, dcmodify, dcmp2pgm, dcmprscu, dcmpschk, dcmpsmk, dcmpsprt, dcmqridx, dcmquant, dcmscale, dcmsend, dcod2lum, dconvlum, drtdump, dsr2xml, dsrdump, dump2dcm, echoscu, findscu, getscu, img2dcm, json2dcm, movescu, pdf2dcm, stl2dcm, storescu, termscu, xml2dcm, xml2dsr };
//# sourceMappingURL=tools.js.map
//# sourceMappingURL=tools.js.map