@idl3/claude-control 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/sessions.js CHANGED
@@ -18,11 +18,14 @@ import { parsePanePrompt } from './prompt.js';
18
18
  import { assignTranscripts, parseEtime, fingerprintScore, shouldRebind } from './match.js';
19
19
  import { pinKey } from './pins.js';
20
20
  import { readPaneRegistry, gcPaneRegistry } from './pane-registry.js';
21
+ import { matchesProcess as codexMatchesProcess, buildTranscriptIndex as buildCodexIndex } from './codex.js';
21
22
 
22
23
  const execFile = promisify(_execFile);
23
24
 
24
25
  // Matches Claude Code's executable basename (e.g. /Users/x/.local/bin/claude).
25
26
  const CLAUDE_COMM_RE = /(^|\/)claude$/;
27
+ // Matches Codex CLI executable basename.
28
+ const CODEX_COMM_RE = /(^|\/)codex$/;
26
29
 
27
30
  // A pane is a Claude Code session when its process title is the Claude version
28
31
  // (e.g. "2.1.162") — shells report zsh/bash/etc. A linked transcript also counts.
@@ -337,11 +340,12 @@ export async function listRecentTranscripts({ projectsRoot, limit = 60 }) {
337
340
 
338
341
  export class SessionRegistry extends EventEmitter {
339
342
  /**
340
- * @param {{ projectsRoot: string, tmux: object, debounceMs?: number }} opts
343
+ * @param {{ projectsRoot: string, codexSessionsRoot?: string, tmux: object, debounceMs?: number }} opts
341
344
  */
342
- constructor({ projectsRoot, tmux, debounceMs = 1000 } = {}) {
345
+ constructor({ projectsRoot, codexSessionsRoot, tmux, debounceMs = 1000 } = {}) {
343
346
  super();
344
347
  this._projectsRoot = projectsRoot;
348
+ this._codexSessionsRoot = codexSessionsRoot;
345
349
  this._tmux = tmux;
346
350
  this._debounceMs = debounceMs;
347
351
 
@@ -451,14 +455,21 @@ export class SessionRegistry extends EventEmitter {
451
455
  return true;
452
456
  });
453
457
 
454
- // Classify every pane by its process subtree (a `claude` descendant) and get
455
- // its claude start time in one ps snapshot. Falls back to the cmd heuristic
458
+ // Classify every pane by its process subtree (a `claude` or `codex` descendant)
459
+ // and get its start time in one ps snapshot. Falls back to the cmd heuristic
456
460
  // only when ps is unavailable.
457
461
  const paneProc = await this._buildPaneProc(panes);
458
462
  const isClaudePane = (p) => {
459
463
  const info = paneProc.get(p.target);
460
464
  return info ? info.isClaude : isClaudeCmd(p.cmd);
461
465
  };
466
+ const paneKind = (p) => {
467
+ const info = paneProc.get(p.target);
468
+ if (info?.kind) return info.kind;
469
+ if (isClaudeCmd(p.cmd)) return 'claude';
470
+ if (codexMatchesProcess(p.cmd)) return 'codex';
471
+ return 'terminal';
472
+ };
462
473
  const claudePanes = panes.filter(isClaudePane);
463
474
 
464
475
  // The exact pane→transcript map authored by the SessionStart hook. This is
@@ -564,9 +575,54 @@ export class SessionRegistry extends EventEmitter {
564
575
  }
565
576
  // ── End self-heal ─────────────────────────────────────────────────────────
566
577
 
578
+ // ── Codex pane → transcript matching ────────────────────────────────────
579
+ // Discover Codex session transcripts and match them to Codex panes.
580
+ // The Claude assignment above is computed first and left untouched;
581
+ // codex results are merged in after.
582
+ const codexPanes = panes.filter((p) => paneKind(p) === 'codex');
583
+ if (codexPanes.length > 0) {
584
+ const codexIndex = await buildCodexIndex({ codexSessionsRoot: this._codexSessionsRoot });
585
+ const codexCandidates = [];
586
+ for (const rec of codexIndex.byCwd.values()) {
587
+ codexCandidates.push({
588
+ transcriptPath: rec.transcriptPath,
589
+ cwd: rec.cwd,
590
+ projectDir: null, // triggers isCwdConsistent scope fallback in match.js
591
+ birthtimeMs: rec.mtime,
592
+ mtimeMs: rec.mtime,
593
+ lastActivityMs: rec.mtime,
594
+ customTitle: rec.customTitle,
595
+ aiTitle: rec.aiTitle,
596
+ recentText: null,
597
+ // Pass through for later session assembly
598
+ sessionId: rec.sessionId,
599
+ lastActivity: rec.lastActivity,
600
+ model: rec.model,
601
+ transcriptPending: rec.transcriptPending,
602
+ pendingToolUseId: rec.pendingToolUseId,
603
+ pendingQuestion: rec.pendingQuestion,
604
+ agentType: rec.agentType,
605
+ mtime: rec.mtime,
606
+ });
607
+ }
608
+ const codexPaneInputs = codexPanes.map((p) => ({
609
+ target: p.target,
610
+ windowName: p.windowName,
611
+ cwd: p.cwd,
612
+ projectDir: null,
613
+ procStartMs: paneProc.get(p.target)?.startMs ?? null,
614
+ capturedText: this._paneTextCache.get(p.target) ?? null,
615
+ }));
616
+ const codexAssignment = assignTranscripts(codexPaneInputs, codexCandidates);
617
+ for (const [t, rec] of codexAssignment) assignment.set(t, rec);
618
+ }
619
+ // ── End Codex matching ───────────────────────────────────────────────────
620
+
567
621
  const sessions = panes.map((win) => {
568
622
  const isClaude = isClaudePane(win);
569
- const transcript = isClaude ? assignment.get(win.target) ?? null : null;
623
+ const kind = paneKind(win);
624
+ const hasTranscript = kind === 'claude' || kind === 'codex';
625
+ const transcript = hasTranscript ? assignment.get(win.target) ?? null : null;
570
626
  const isPinned = pinnedByTarget.has(win.target);
571
627
  const id = win.target;
572
628
  // Pending = subscribed-tailer pending (live modal) OR transcript-derived
@@ -603,7 +659,7 @@ export class SessionRegistry extends EventEmitter {
603
659
  pendingQuestion: transcript?.pendingQuestion ?? panePrompt?.question ?? null,
604
660
  cmd: win.cmd,
605
661
  isClaude,
606
- kind: isClaude ? 'claude' : 'terminal',
662
+ kind,
607
663
  ccShell: !!win.ccShell, // a composer >_ sister shell pane
608
664
 
609
665
  model: ctx.model || prettyModel(transcript?.model) || null,
@@ -854,7 +910,7 @@ export class SessionRegistry extends EventEmitter {
854
910
  }
855
911
 
856
912
  const now = Date.now();
857
- // BFS from the pane shell pid for a `claude` descendant; return its start.
913
+ // BFS from the pane shell pid for a `claude` or `codex` descendant; return its start.
858
914
  const findClaude = (rootPid) => {
859
915
  const queue = [rootPid];
860
916
  const seen = new Set();
@@ -865,15 +921,19 @@ export class SessionRegistry extends EventEmitter {
865
921
  const meta = info.get(pid);
866
922
  if (meta && CLAUDE_COMM_RE.test(meta.comm)) {
867
923
  const sec = parseEtime(meta.etime);
868
- return { isClaude: true, startMs: sec == null ? null : now - sec * 1000 };
924
+ return { isClaude: true, isCodex: false, kind: 'claude', startMs: sec == null ? null : now - sec * 1000 };
925
+ }
926
+ if (meta && CODEX_COMM_RE.test(meta.comm)) {
927
+ const sec = parseEtime(meta.etime);
928
+ return { isClaude: false, isCodex: true, kind: 'codex', startMs: sec == null ? null : now - sec * 1000 };
869
929
  }
870
930
  for (const c of children.get(pid) ?? []) queue.push(c);
871
931
  }
872
- return { isClaude: false, startMs: null };
932
+ return { isClaude: false, isCodex: false, kind: null, startMs: null };
873
933
  };
874
934
 
875
935
  for (const p of allPanes) {
876
- out.set(p.target, p.panePid ? findClaude(p.panePid) : { isClaude: false, startMs: null });
936
+ out.set(p.target, p.panePid ? findClaude(p.panePid) : { isClaude: false, isCodex: false, kind: null, startMs: null });
877
937
  }
878
938
  return out;
879
939
  }
package/lib/transcript.js CHANGED
@@ -194,13 +194,14 @@ export function parseRecord(line) {
194
194
  export class TranscriptTailer extends EventEmitter {
195
195
  /**
196
196
  * @param {string} filePath
197
- * @param {{ maxBuffer?: number, debounceMs?: number }} options
197
+ * @param {{ maxBuffer?: number, debounceMs?: number, parser?: Function }} options
198
198
  */
199
- constructor(filePath, { maxBuffer = DEFAULT_MAX_BUFFER, debounceMs = 150 } = {}) {
199
+ constructor(filePath, { maxBuffer = DEFAULT_MAX_BUFFER, debounceMs = 150, parser = parseRecord } = {}) {
200
200
  super();
201
201
  this._filePath = filePath;
202
202
  this._maxBuffer = maxBuffer;
203
203
  this._debounceMs = debounceMs;
204
+ this._parse = parser;
204
205
 
205
206
  /** @type {import('./transcript.js').NormalizedMessage[]} */
206
207
  this._messages = [];
@@ -340,7 +341,7 @@ export class TranscriptTailer extends EventEmitter {
340
341
 
341
342
  const parsed = [];
342
343
  for (const line of lines) {
343
- const msg = parseRecord(line);
344
+ const msg = this._parse(line);
344
345
  if (msg) {
345
346
  parsed.push(msg);
346
347
  this._trackPending(msg);
@@ -413,7 +414,7 @@ export class TranscriptTailer extends EventEmitter {
413
414
 
414
415
  const newMsgs = [];
415
416
  for (const line of complete) {
416
- const msg = parseRecord(line);
417
+ const msg = this._parse(line);
417
418
  if (msg) {
418
419
  newMsgs.push(msg);
419
420
  this._trackPending(msg);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idl3/claude-control",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "description": "Local web UI to watch and drive your Claude Code sessions running in tmux — live transcripts, reply, answer AskUserQuestion, attach files, from a browser or phone.",
6
6
  "keywords": [
package/server.js CHANGED
@@ -10,7 +10,11 @@ import fs from 'node:fs';
10
10
  import path from 'node:path';
11
11
  import { fileURLToPath } from 'node:url';
12
12
  import os from 'node:os';
13
- import { spawn } from 'node:child_process';
13
+ import { spawn, execFile as _execFileRaw } from 'node:child_process';
14
+ import { promisify } from 'node:util';
15
+ import fsp from 'node:fs/promises';
16
+
17
+ const _execFile = promisify(_execFileRaw);
14
18
  import { WebSocketServer } from 'ws';
15
19
 
16
20
  import * as tmux from './lib/tmux.js';
@@ -27,6 +31,7 @@ import { sweepUploads, resolveUploadPath } from './lib/uploads.js';
27
31
  import { getVersionInfo, currentVersion } from './lib/version.js';
28
32
  import * as push from './lib/push.js';
29
33
  import { readConfig, writeConfig } from './lib/config.js';
34
+ import { parseCodexRecord, parseCodexPrompt, buildSpawnCommand } from './lib/codex.js';
30
35
  import { optimizePrompt, rulesOptimize } from './lib/optimize.js';
31
36
  import * as mlx from './lib/mlx.js';
32
37
  import {
@@ -76,6 +81,8 @@ const CONFIG = {
76
81
  host: env('HOST') || '127.0.0.1',
77
82
  projectsRoot:
78
83
  env('PROJECTS') || path.join(os.homedir(), '.claude', 'projects'),
84
+ codexSessionsRoot:
85
+ env('CODEX_SESSIONS') || path.join(os.homedir(), '.codex', 'sessions'),
79
86
  // 768MB: a long-running Node server (WS + transcript tailing + the bundled
80
87
  // web app) baselines ~300-450MB of V8 heap + RSS, so the old 350MB budget
81
88
  // tripped "over limit" permanently. Override with CLAUDE_CONTROL_RSS_LIMIT_MB.
@@ -123,7 +130,7 @@ const IMAGE_MIME = {
123
130
  };
124
131
 
125
132
  // --- shared state -----------------------------------------------------------
126
- const registry = new SessionRegistry({ projectsRoot: CONFIG.projectsRoot, tmux });
133
+ const registry = new SessionRegistry({ projectsRoot: CONFIG.projectsRoot, codexSessionsRoot: CONFIG.codexSessionsRoot, tmux });
127
134
  const resources = new ResourceMonitor({ rssLimitMB: CONFIG.rssLimitMB });
128
135
 
129
136
  // Manual transcript pins (windowId.paneIndex -> transcript path). Loaded at boot,
@@ -347,6 +354,33 @@ const _handler = (req, res) => {
347
354
  if (!checkToken(req)) return endJson(res, 401, { error: 'unauthorized' });
348
355
  return handleTranscribe(req, res, u);
349
356
  }
357
+ // GET /api/spawn-agents — agent-type availability (claude vs codex).
358
+ // Returns which agent binaries are resolvable on this machine so the UI can
359
+ // disable an unavailable agent picker option and show a reason.
360
+ // Token-gated + localhost, same as other GET endpoints.
361
+ if (u.pathname === '/api/spawn-agents') {
362
+ if (!checkToken(req)) return endJson(res, 401, { error: 'unauthorized' });
363
+ const cfg = readConfig();
364
+ return Promise.all([
365
+ resolveBin(cfg.claudeBin || cfg.launchCommand),
366
+ resolveBin(cfg.codexBin || cfg.codexLaunchCommand),
367
+ ]).then(([claudeResult, codexResult]) => {
368
+ return endJson(res, 200, {
369
+ agents: [
370
+ {
371
+ id: 'claude',
372
+ available: claudeResult.available,
373
+ ...(claudeResult.available ? {} : { reason: claudeResult.reason }),
374
+ },
375
+ {
376
+ id: 'codex',
377
+ available: codexResult.available,
378
+ ...(codexResult.available ? {} : { reason: codexResult.reason }),
379
+ },
380
+ ],
381
+ });
382
+ }).catch((err) => endJson(res, 500, { error: String(err?.message || err) }));
383
+ }
350
384
  if (u.pathname === '/api/session/new') {
351
385
  if (req.method !== 'POST') return endJson(res, 405, { error: 'method not allowed' });
352
386
  if (!checkToken(req)) return endJson(res, 401, { error: 'unauthorized' });
@@ -672,6 +706,40 @@ function handleTranscribe(req, res, u) {
672
706
  });
673
707
  }
674
708
 
709
+ // ---------------------------------------------------------------------------
710
+ // resolveBin — async PATH lookup for a binary name or absolute path.
711
+ //
712
+ // If `bin` is an absolute path, checks it is executable directly.
713
+ // Otherwise runs `which <bin>` on PATH.
714
+ //
715
+ // Returns { available: true, path } on success, { available: false, reason }
716
+ // on failure. Never throws.
717
+ // ---------------------------------------------------------------------------
718
+ async function resolveBin(bin) {
719
+ if (!bin || typeof bin !== 'string' || !bin.trim()) {
720
+ return { available: false, reason: 'no binary configured' };
721
+ }
722
+ const b = bin.trim();
723
+ // Absolute path: check existence + execute permission directly.
724
+ if (b.startsWith('/')) {
725
+ try {
726
+ await fsp.access(b, fsp.constants?.X_OK ?? 1);
727
+ return { available: true, path: b };
728
+ } catch {
729
+ return { available: false, reason: `binary not found or not executable: ${b}` };
730
+ }
731
+ }
732
+ // Relative / bare name: resolve via `which`.
733
+ try {
734
+ const { stdout } = await _execFile('which', [b], { timeout: 5000 });
735
+ const resolved = stdout.trim();
736
+ if (resolved) return { available: true, path: resolved };
737
+ return { available: false, reason: `${b} not found on PATH` };
738
+ } catch {
739
+ return { available: false, reason: `${b} not found on PATH` };
740
+ }
741
+ }
742
+
675
743
  // POST /api/session/new — create a new tmux window in the configured (or
676
744
  // body-overridden) cwd, then type the launch command into it via send-keys so
677
745
  // the interactive shell resolves aliases. Security: the command is operator
@@ -687,23 +755,66 @@ async function handleSessionNew(req, res) {
687
755
  const config = readConfig();
688
756
  const cwd =
689
757
  typeof body.cwd === 'string' && body.cwd.trim() ? body.cwd : config.defaultCwd;
758
+
759
+ // agent ∈ {'claude','codex'}, default 'claude'.
760
+ const agent = body.agent === 'codex' ? 'codex' : 'claude';
761
+
690
762
  // Name is required-with-default: sanitize the requested name, falling back to
691
763
  // `session-<short-ts>` so a session is ALWAYS named (the rail reads the tmux
692
764
  // window name until a transcript title exists).
693
765
  const name = tmux.sanitizeName(body.name) || tmux.defaultSessionName();
766
+
767
+ // --- Pre-validation: binary resolution + cwd check BEFORE creating any window ---
768
+
769
+ // (i) Resolve the agent binary and return 400 if unavailable.
770
+ const agentBin = agent === 'codex'
771
+ ? (config.codexBin || config.codexLaunchCommand)
772
+ : (config.claudeBin || config.launchCommand);
773
+ const binCheck = await resolveBin(agentBin);
774
+ if (!binCheck.available) {
775
+ return endJson(res, 400, { error: `agent binary unavailable: ${binCheck.reason}` });
776
+ }
777
+
778
+ // (ii) For codex: pre-validate cwd exists and is a directory BEFORE createWindow,
779
+ // so a bad request creates NO window (400 not 500, window-leak prevention).
780
+ if (agent === 'codex') {
781
+ try {
782
+ const st = await fsp.stat(cwd);
783
+ if (!st.isDirectory()) {
784
+ return endJson(res, 400, { error: `cwd is not a directory: ${cwd}` });
785
+ }
786
+ } catch {
787
+ return endJson(res, 400, { error: `cwd does not exist: ${cwd}` });
788
+ }
789
+ }
790
+
694
791
  try {
695
792
  // (1) Reliable named path: the tmux window name. createWindow sets it via
696
- // `new-window -n`, so the rail shows the name immediately.
793
+ // `new-window -n` and the `-c cwd` flag cwd flows through tmux's own
794
+ // working-directory flag, never a shell `cd`.
697
795
  const target = await tmux.createWindow({ cwd, name });
698
- // (2) Claude's own session title: `claude --help` exposes `-n/--name`
699
- // (display name in the prompt box, /resume picker, terminal title), so
700
- // we append it to the launch command rather than relying on a delayed
701
- // `/rename`. The name is shell-quoted (sanitizeName already stripped
702
- // control chars/newlines) since the command is typed into an interactive
703
- // shell so aliases like `yolo` resolve. sendText appends Enter runs it.
704
- const launch = `${config.launchCommand} --name ${tmux.shellQuoteName(name)}`;
796
+
797
+ let launch;
798
+ if (agent === 'codex') {
799
+ // Codex path: uses -C <cwd> (its own cwd flag). No --name flag — Codex
800
+ // has none. The tmux window is still named (above) so the rail shows it.
801
+ // cwd is shell-quoted (same quoting as names) since the command is typed
802
+ // into an interactive shell via sendText.
803
+ void buildSpawnCommand({ cwd, bin: config.codexLaunchCommand }); // validate shape
804
+ launch = `${config.codexLaunchCommand} -C ${tmux.shellQuoteName(cwd)}`;
805
+ } else {
806
+ // Claude path: BYTE-IDENTICAL to the pre-Phase-D implementation.
807
+ // (2) Claude's own session title: `claude --help` exposes `-n/--name`
808
+ // (display name in the prompt box, /resume picker, terminal title), so
809
+ // we append it to the launch command rather than relying on a delayed
810
+ // `/rename`. The name is shell-quoted (sanitizeName already stripped
811
+ // control chars/newlines) since the command is typed into an interactive
812
+ // shell so aliases like `yolo` resolve. sendText appends Enter → runs it.
813
+ launch = `${config.launchCommand} --name ${tmux.shellQuoteName(name)}`;
814
+ }
815
+
705
816
  await tmux.sendText(target, launch);
706
- return endJson(res, 200, { ok: true, target, name });
817
+ return endJson(res, 200, { ok: true, target, name, agent });
707
818
  } catch (err) {
708
819
  return endJson(res, 500, { error: String(err?.message || err) });
709
820
  }
@@ -1135,7 +1246,7 @@ function ensureSubscription(id) {
1135
1246
  return sub;
1136
1247
  }
1137
1248
 
1138
- const tailer = new TranscriptTailer(session.transcriptPath, { maxBuffer: CONFIG.maxBuffer });
1249
+ const tailer = new TranscriptTailer(session.transcriptPath, { maxBuffer: CONFIG.maxBuffer, parser: session.kind === 'codex' ? parseCodexRecord : undefined });
1139
1250
  // Watch this session's sub-agent transcripts (Task/Agent). Discovery is polled
1140
1251
  // when the parent transcript grows (when sub-agents spawn) + once at subscribe.
1141
1252
  const subagents = new SubAgentsWatcher(session.transcriptPath);
@@ -1201,7 +1312,7 @@ function startPromptPoller(id, sub) {
1201
1312
  let prompt = null;
1202
1313
  try {
1203
1314
  const cap = await tmux.capturePane(session.target, 40);
1204
- prompt = parsePanePrompt(cap);
1315
+ prompt = session.kind === 'codex' ? parseCodexPrompt(cap) : parsePanePrompt(cap);
1205
1316
  } catch {
1206
1317
  return;
1207
1318
  }
@@ -1,3 +1,3 @@
1
- import{g as Ve}from"./index-DFru8Gzx.js";function xe(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach(t=>{const i=e[t],u=typeof i;(u==="object"||u==="function")&&!Object.isFrozen(i)&&xe(i)}),e}class he{constructor(t){t.data===void 0&&(t.data={}),this.data=t.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function we(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}function B(e,...t){const i=Object.create(null);for(const u in e)i[u]=e[u];return t.forEach(function(u){for(const b in u)i[b]=u[b]}),i}const qe="</span>",pe=e=>!!e.scope,Qe=(e,{prefix:t})=>{if(e.startsWith("language:"))return e.replace("language:","language-");if(e.includes(".")){const i=e.split(".");return[`${t}${i.shift()}`,...i.map((u,b)=>`${u}${"_".repeat(b+1)}`)].join(" ")}return`${t}${e}`};class me{constructor(t,i){this.buffer="",this.classPrefix=i.classPrefix,t.walk(this)}addText(t){this.buffer+=we(t)}openNode(t){if(!pe(t))return;const i=Qe(t.scope,{prefix:this.classPrefix});this.span(i)}closeNode(t){pe(t)&&(this.buffer+=qe)}value(){return this.buffer}span(t){this.buffer+=`<span class="${t}">`}}const de=(e={})=>{const t={children:[]};return Object.assign(t,e),t};class te{constructor(){this.rootNode=de(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(t){this.top.children.push(t)}openNode(t){const i=de({scope:t});this.add(i),this.stack.push(i)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(t){return this.constructor._walk(t,this.rootNode)}static _walk(t,i){return typeof i=="string"?t.addText(i):i.children&&(t.openNode(i),i.children.forEach(u=>this._walk(t,u)),t.closeNode(i)),t}static _collapse(t){typeof t!="string"&&t.children&&(t.children.every(i=>typeof i=="string")?t.children=[t.children.join("")]:t.children.forEach(i=>{te._collapse(i)}))}}class et extends te{constructor(t){super(),this.options=t}addText(t){t!==""&&this.add(t)}startScope(t){this.openNode(t)}endScope(){this.closeNode()}__addSublanguage(t,i){const u=t.root;i&&(u.scope=`language:${i}`),this.add(u)}toHTML(){return new me(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}}function P(e){return e?typeof e=="string"?e:e.source:null}function Oe(e){return C("(?=",e,")")}function tt(e){return C("(?:",e,")*")}function nt(e){return C("(?:",e,")?")}function C(...e){return e.map(i=>P(i)).join("")}function it(e){const t=e[e.length-1];return typeof t=="object"&&t.constructor===Object?(e.splice(e.length-1,1),t):{}}function ne(...e){return"("+(it(e).capture?"":"?:")+e.map(u=>P(u)).join("|")+")"}function Re(e){return new RegExp(e.toString()+"|").exec("").length-1}function st(e,t){const i=e&&e.exec(t);return i&&i.index===0}const rt=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function ie(e,{joinWith:t}){let i=0;return e.map(u=>{i+=1;const b=i;let _=P(u),c="";for(;_.length>0;){const r=rt.exec(_);if(!r){c+=_;break}c+=_.substring(0,r.index),_=_.substring(r.index+r[0].length),r[0][0]==="\\"&&r[1]?c+="\\"+String(Number(r[1])+b):(c+=r[0],r[0]==="("&&i++)}return c}).map(u=>`(${u})`).join(t)}const ct=/\b\B/,ye="[a-zA-Z]\\w*",se="[a-zA-Z_]\\w*",Se="\\b\\d+(\\.\\d+)?",Ne="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",Ae="\\b(0b[01]+)",ot="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",at=(e={})=>{const t=/^#![ ]*\//;return e.binary&&(e.begin=C(t,/.*\b/,e.binary,/\b.*/)),B({scope:"meta",begin:t,end:/$/,relevance:0,"on:begin":(i,u)=>{i.index!==0&&u.ignoreMatch()}},e)},U={begin:"\\\\[\\s\\S]",relevance:0},lt={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[U]},ut={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[U]},ft={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},Y=function(e,t,i={}){const u=B({scope:"comment",begin:e,end:t,contains:[]},i);u.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});const b=ne("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return u.contains.push({begin:C(/[ ]+/,"(",b,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),u},gt=Y("//","$"),ht=Y("/\\*","\\*/"),pt=Y("#","$"),dt={scope:"number",begin:Se,relevance:0},Et={scope:"number",begin:Ne,relevance:0},bt={scope:"number",begin:Ae,relevance:0},_t={scope:"regexp",begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[U,{begin:/\[/,end:/\]/,relevance:0,contains:[U]}]},Mt={scope:"title",begin:ye,relevance:0},xt={scope:"title",begin:se,relevance:0},wt={begin:"\\.\\s*"+se,relevance:0},Ot=function(e){return Object.assign(e,{"on:begin":(t,i)=>{i.data._beginMatch=t[1]},"on:end":(t,i)=>{i.data._beginMatch!==t[1]&&i.ignoreMatch()}})};var z=Object.freeze({__proto__:null,APOS_STRING_MODE:lt,BACKSLASH_ESCAPE:U,BINARY_NUMBER_MODE:bt,BINARY_NUMBER_RE:Ae,COMMENT:Y,C_BLOCK_COMMENT_MODE:ht,C_LINE_COMMENT_MODE:gt,C_NUMBER_MODE:Et,C_NUMBER_RE:Ne,END_SAME_AS_BEGIN:Ot,HASH_COMMENT_MODE:pt,IDENT_RE:ye,MATCH_NOTHING_RE:ct,METHOD_GUARD:wt,NUMBER_MODE:dt,NUMBER_RE:Se,PHRASAL_WORDS_MODE:ft,QUOTE_STRING_MODE:ut,REGEXP_MODE:_t,RE_STARTERS_RE:ot,SHEBANG:at,TITLE_MODE:Mt,UNDERSCORE_IDENT_RE:se,UNDERSCORE_TITLE_MODE:xt});function Rt(e,t){e.input[e.index-1]==="."&&t.ignoreMatch()}function yt(e,t){e.className!==void 0&&(e.scope=e.className,delete e.className)}function St(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=Rt,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,e.relevance===void 0&&(e.relevance=0))}function Nt(e,t){Array.isArray(e.illegal)&&(e.illegal=ne(...e.illegal))}function At(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function kt(e,t){e.relevance===void 0&&(e.relevance=1)}const Tt=(e,t)=>{if(!e.beforeMatch)return;if(e.starts)throw new Error("beforeMatch cannot be used with starts");const i=Object.assign({},e);Object.keys(e).forEach(u=>{delete e[u]}),e.keywords=i.keywords,e.begin=C(i.beforeMatch,Oe(i.begin)),e.starts={relevance:0,contains:[Object.assign(i,{endsParent:!0})]},e.relevance=0,delete i.beforeMatch},It=["of","and","for","in","not","or","if","then","parent","list","value"],Bt="keyword";function ke(e,t,i=Bt){const u=Object.create(null);return typeof e=="string"?b(i,e.split(" ")):Array.isArray(e)?b(i,e):Object.keys(e).forEach(function(_){Object.assign(u,ke(e[_],t,_))}),u;function b(_,c){t&&(c=c.map(r=>r.toLowerCase())),c.forEach(function(r){const l=r.split("|");u[l[0]]=[_,Dt(l[0],l[1])]})}}function Dt(e,t){return t?Number(t):vt(e)?0:1}function vt(e){return It.includes(e.toLowerCase())}const Ee={},v=e=>{console.error(e)},be=(e,...t)=>{console.log(`WARN: ${e}`,...t)},L=(e,t)=>{Ee[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),Ee[`${e}/${t}`]=!0)},X=new Error;function Te(e,t,{key:i}){let u=0;const b=e[i],_={},c={};for(let r=1;r<=t.length;r++)c[r+u]=b[r],_[r+u]=!0,u+=Re(t[r-1]);e[i]=c,e[i]._emit=_,e[i]._multi=!0}function Ct(e){if(Array.isArray(e.begin)){if(e.skip||e.excludeBegin||e.returnBegin)throw v("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),X;if(typeof e.beginScope!="object"||e.beginScope===null)throw v("beginScope must be object"),X;Te(e,e.begin,{key:"beginScope"}),e.begin=ie(e.begin,{joinWith:""})}}function Lt(e){if(Array.isArray(e.end)){if(e.skip||e.excludeEnd||e.returnEnd)throw v("skip, excludeEnd, returnEnd not compatible with endScope: {}"),X;if(typeof e.endScope!="object"||e.endScope===null)throw v("endScope must be object"),X;Te(e,e.end,{key:"endScope"}),e.end=ie(e.end,{joinWith:""})}}function Ht(e){e.scope&&typeof e.scope=="object"&&e.scope!==null&&(e.beginScope=e.scope,delete e.scope)}function jt(e){Ht(e),typeof e.beginScope=="string"&&(e.beginScope={_wrap:e.beginScope}),typeof e.endScope=="string"&&(e.endScope={_wrap:e.endScope}),Ct(e),Lt(e)}function Pt(e){function t(c,r){return new RegExp(P(c),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(r?"g":""))}class i{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(r,l){l.position=this.position++,this.matchIndexes[this.matchAt]=l,this.regexes.push([l,r]),this.matchAt+=Re(r)+1}compile(){this.regexes.length===0&&(this.exec=()=>null);const r=this.regexes.map(l=>l[1]);this.matcherRe=t(ie(r,{joinWith:"|"}),!0),this.lastIndex=0}exec(r){this.matcherRe.lastIndex=this.lastIndex;const l=this.matcherRe.exec(r);if(!l)return null;const w=l.findIndex((j,Z)=>Z>0&&j!==void 0),M=this.matchIndexes[w];return l.splice(0,w),Object.assign(l,M)}}class u{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(r){if(this.multiRegexes[r])return this.multiRegexes[r];const l=new i;return this.rules.slice(r).forEach(([w,M])=>l.addRule(w,M)),l.compile(),this.multiRegexes[r]=l,l}resumingScanAtSamePosition(){return this.regexIndex!==0}considerAll(){this.regexIndex=0}addRule(r,l){this.rules.push([r,l]),l.type==="begin"&&this.count++}exec(r){const l=this.getMatcher(this.regexIndex);l.lastIndex=this.lastIndex;let w=l.exec(r);if(this.resumingScanAtSamePosition()&&!(w&&w.index===this.lastIndex)){const M=this.getMatcher(0);M.lastIndex=this.lastIndex+1,w=M.exec(r)}return w&&(this.regexIndex+=w.position+1,this.regexIndex===this.count&&this.considerAll()),w}}function b(c){const r=new u;return c.contains.forEach(l=>r.addRule(l.begin,{rule:l,type:"begin"})),c.terminatorEnd&&r.addRule(c.terminatorEnd,{type:"end"}),c.illegal&&r.addRule(c.illegal,{type:"illegal"}),r}function _(c,r){const l=c;if(c.isCompiled)return l;[yt,At,jt,Tt].forEach(M=>M(c,r)),e.compilerExtensions.forEach(M=>M(c,r)),c.__beforeBegin=null,[St,Nt,kt].forEach(M=>M(c,r)),c.isCompiled=!0;let w=null;return typeof c.keywords=="object"&&c.keywords.$pattern&&(c.keywords=Object.assign({},c.keywords),w=c.keywords.$pattern,delete c.keywords.$pattern),w=w||/\w+/,c.keywords&&(c.keywords=ke(c.keywords,e.case_insensitive)),l.keywordPatternRe=t(w,!0),r&&(c.begin||(c.begin=/\B|\b/),l.beginRe=t(l.begin),!c.end&&!c.endsWithParent&&(c.end=/\B|\b/),c.end&&(l.endRe=t(l.end)),l.terminatorEnd=P(l.end)||"",c.endsWithParent&&r.terminatorEnd&&(l.terminatorEnd+=(c.end?"|":"")+r.terminatorEnd)),c.illegal&&(l.illegalRe=t(c.illegal)),c.contains||(c.contains=[]),c.contains=[].concat(...c.contains.map(function(M){return Ut(M==="self"?c:M)})),c.contains.forEach(function(M){_(M,l)}),c.starts&&_(c.starts,r),l.matcher=b(l),l}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=B(e.classNameAliases||{}),_(e)}function Ie(e){return e?e.endsWithParent||Ie(e.starts):!1}function Ut(e){return e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map(function(t){return B(e,{variants:null},t)})),e.cachedVariants?e.cachedVariants:Ie(e)?B(e,{starts:e.starts?B(e.starts):null}):Object.isFrozen(e)?B(e):e}var $t="11.11.1";class Gt extends Error{constructor(t,i){super(t),this.name="HTMLInjectionError",this.html=i}}const ee=we,_e=B,Me=Symbol("nomatch"),Wt=7,Be=function(e){const t=Object.create(null),i=Object.create(null),u=[];let b=!0;const _="Could not find the language '{}', did you forget to load/include a language module?",c={disableAutodetect:!0,name:"Plain text",contains:[]};let r={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:et};function l(n){return r.noHighlightRe.test(n)}function w(n){let a=n.className+" ";a+=n.parentNode?n.parentNode.className:"";const h=r.languageDetectRe.exec(a);if(h){const d=T(h[1]);return d||(be(_.replace("{}",h[1])),be("Falling back to no-highlight mode for this block.",n)),d?h[1]:"no-highlight"}return a.split(/\s+/).find(d=>l(d)||T(d))}function M(n,a,h){let d="",x="";typeof a=="object"?(d=n,h=a.ignoreIllegals,x=a.language):(L("10.7.0","highlight(lang, code, ...args) has been deprecated."),L("10.7.0",`Please use highlight(code, options) instead.
1
+ import{g as Ve}from"./index-CxhR0MPg.js";function xe(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach(t=>{const i=e[t],u=typeof i;(u==="object"||u==="function")&&!Object.isFrozen(i)&&xe(i)}),e}class he{constructor(t){t.data===void 0&&(t.data={}),this.data=t.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function we(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}function B(e,...t){const i=Object.create(null);for(const u in e)i[u]=e[u];return t.forEach(function(u){for(const b in u)i[b]=u[b]}),i}const qe="</span>",pe=e=>!!e.scope,Qe=(e,{prefix:t})=>{if(e.startsWith("language:"))return e.replace("language:","language-");if(e.includes(".")){const i=e.split(".");return[`${t}${i.shift()}`,...i.map((u,b)=>`${u}${"_".repeat(b+1)}`)].join(" ")}return`${t}${e}`};class me{constructor(t,i){this.buffer="",this.classPrefix=i.classPrefix,t.walk(this)}addText(t){this.buffer+=we(t)}openNode(t){if(!pe(t))return;const i=Qe(t.scope,{prefix:this.classPrefix});this.span(i)}closeNode(t){pe(t)&&(this.buffer+=qe)}value(){return this.buffer}span(t){this.buffer+=`<span class="${t}">`}}const de=(e={})=>{const t={children:[]};return Object.assign(t,e),t};class te{constructor(){this.rootNode=de(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(t){this.top.children.push(t)}openNode(t){const i=de({scope:t});this.add(i),this.stack.push(i)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(t){return this.constructor._walk(t,this.rootNode)}static _walk(t,i){return typeof i=="string"?t.addText(i):i.children&&(t.openNode(i),i.children.forEach(u=>this._walk(t,u)),t.closeNode(i)),t}static _collapse(t){typeof t!="string"&&t.children&&(t.children.every(i=>typeof i=="string")?t.children=[t.children.join("")]:t.children.forEach(i=>{te._collapse(i)}))}}class et extends te{constructor(t){super(),this.options=t}addText(t){t!==""&&this.add(t)}startScope(t){this.openNode(t)}endScope(){this.closeNode()}__addSublanguage(t,i){const u=t.root;i&&(u.scope=`language:${i}`),this.add(u)}toHTML(){return new me(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}}function P(e){return e?typeof e=="string"?e:e.source:null}function Oe(e){return C("(?=",e,")")}function tt(e){return C("(?:",e,")*")}function nt(e){return C("(?:",e,")?")}function C(...e){return e.map(i=>P(i)).join("")}function it(e){const t=e[e.length-1];return typeof t=="object"&&t.constructor===Object?(e.splice(e.length-1,1),t):{}}function ne(...e){return"("+(it(e).capture?"":"?:")+e.map(u=>P(u)).join("|")+")"}function Re(e){return new RegExp(e.toString()+"|").exec("").length-1}function st(e,t){const i=e&&e.exec(t);return i&&i.index===0}const rt=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function ie(e,{joinWith:t}){let i=0;return e.map(u=>{i+=1;const b=i;let _=P(u),c="";for(;_.length>0;){const r=rt.exec(_);if(!r){c+=_;break}c+=_.substring(0,r.index),_=_.substring(r.index+r[0].length),r[0][0]==="\\"&&r[1]?c+="\\"+String(Number(r[1])+b):(c+=r[0],r[0]==="("&&i++)}return c}).map(u=>`(${u})`).join(t)}const ct=/\b\B/,ye="[a-zA-Z]\\w*",se="[a-zA-Z_]\\w*",Se="\\b\\d+(\\.\\d+)?",Ne="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",Ae="\\b(0b[01]+)",ot="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",at=(e={})=>{const t=/^#![ ]*\//;return e.binary&&(e.begin=C(t,/.*\b/,e.binary,/\b.*/)),B({scope:"meta",begin:t,end:/$/,relevance:0,"on:begin":(i,u)=>{i.index!==0&&u.ignoreMatch()}},e)},U={begin:"\\\\[\\s\\S]",relevance:0},lt={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[U]},ut={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[U]},ft={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},Y=function(e,t,i={}){const u=B({scope:"comment",begin:e,end:t,contains:[]},i);u.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});const b=ne("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return u.contains.push({begin:C(/[ ]+/,"(",b,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),u},gt=Y("//","$"),ht=Y("/\\*","\\*/"),pt=Y("#","$"),dt={scope:"number",begin:Se,relevance:0},Et={scope:"number",begin:Ne,relevance:0},bt={scope:"number",begin:Ae,relevance:0},_t={scope:"regexp",begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[U,{begin:/\[/,end:/\]/,relevance:0,contains:[U]}]},Mt={scope:"title",begin:ye,relevance:0},xt={scope:"title",begin:se,relevance:0},wt={begin:"\\.\\s*"+se,relevance:0},Ot=function(e){return Object.assign(e,{"on:begin":(t,i)=>{i.data._beginMatch=t[1]},"on:end":(t,i)=>{i.data._beginMatch!==t[1]&&i.ignoreMatch()}})};var z=Object.freeze({__proto__:null,APOS_STRING_MODE:lt,BACKSLASH_ESCAPE:U,BINARY_NUMBER_MODE:bt,BINARY_NUMBER_RE:Ae,COMMENT:Y,C_BLOCK_COMMENT_MODE:ht,C_LINE_COMMENT_MODE:gt,C_NUMBER_MODE:Et,C_NUMBER_RE:Ne,END_SAME_AS_BEGIN:Ot,HASH_COMMENT_MODE:pt,IDENT_RE:ye,MATCH_NOTHING_RE:ct,METHOD_GUARD:wt,NUMBER_MODE:dt,NUMBER_RE:Se,PHRASAL_WORDS_MODE:ft,QUOTE_STRING_MODE:ut,REGEXP_MODE:_t,RE_STARTERS_RE:ot,SHEBANG:at,TITLE_MODE:Mt,UNDERSCORE_IDENT_RE:se,UNDERSCORE_TITLE_MODE:xt});function Rt(e,t){e.input[e.index-1]==="."&&t.ignoreMatch()}function yt(e,t){e.className!==void 0&&(e.scope=e.className,delete e.className)}function St(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=Rt,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,e.relevance===void 0&&(e.relevance=0))}function Nt(e,t){Array.isArray(e.illegal)&&(e.illegal=ne(...e.illegal))}function At(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function kt(e,t){e.relevance===void 0&&(e.relevance=1)}const Tt=(e,t)=>{if(!e.beforeMatch)return;if(e.starts)throw new Error("beforeMatch cannot be used with starts");const i=Object.assign({},e);Object.keys(e).forEach(u=>{delete e[u]}),e.keywords=i.keywords,e.begin=C(i.beforeMatch,Oe(i.begin)),e.starts={relevance:0,contains:[Object.assign(i,{endsParent:!0})]},e.relevance=0,delete i.beforeMatch},It=["of","and","for","in","not","or","if","then","parent","list","value"],Bt="keyword";function ke(e,t,i=Bt){const u=Object.create(null);return typeof e=="string"?b(i,e.split(" ")):Array.isArray(e)?b(i,e):Object.keys(e).forEach(function(_){Object.assign(u,ke(e[_],t,_))}),u;function b(_,c){t&&(c=c.map(r=>r.toLowerCase())),c.forEach(function(r){const l=r.split("|");u[l[0]]=[_,Dt(l[0],l[1])]})}}function Dt(e,t){return t?Number(t):vt(e)?0:1}function vt(e){return It.includes(e.toLowerCase())}const Ee={},v=e=>{console.error(e)},be=(e,...t)=>{console.log(`WARN: ${e}`,...t)},L=(e,t)=>{Ee[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),Ee[`${e}/${t}`]=!0)},X=new Error;function Te(e,t,{key:i}){let u=0;const b=e[i],_={},c={};for(let r=1;r<=t.length;r++)c[r+u]=b[r],_[r+u]=!0,u+=Re(t[r-1]);e[i]=c,e[i]._emit=_,e[i]._multi=!0}function Ct(e){if(Array.isArray(e.begin)){if(e.skip||e.excludeBegin||e.returnBegin)throw v("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),X;if(typeof e.beginScope!="object"||e.beginScope===null)throw v("beginScope must be object"),X;Te(e,e.begin,{key:"beginScope"}),e.begin=ie(e.begin,{joinWith:""})}}function Lt(e){if(Array.isArray(e.end)){if(e.skip||e.excludeEnd||e.returnEnd)throw v("skip, excludeEnd, returnEnd not compatible with endScope: {}"),X;if(typeof e.endScope!="object"||e.endScope===null)throw v("endScope must be object"),X;Te(e,e.end,{key:"endScope"}),e.end=ie(e.end,{joinWith:""})}}function Ht(e){e.scope&&typeof e.scope=="object"&&e.scope!==null&&(e.beginScope=e.scope,delete e.scope)}function jt(e){Ht(e),typeof e.beginScope=="string"&&(e.beginScope={_wrap:e.beginScope}),typeof e.endScope=="string"&&(e.endScope={_wrap:e.endScope}),Ct(e),Lt(e)}function Pt(e){function t(c,r){return new RegExp(P(c),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(r?"g":""))}class i{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(r,l){l.position=this.position++,this.matchIndexes[this.matchAt]=l,this.regexes.push([l,r]),this.matchAt+=Re(r)+1}compile(){this.regexes.length===0&&(this.exec=()=>null);const r=this.regexes.map(l=>l[1]);this.matcherRe=t(ie(r,{joinWith:"|"}),!0),this.lastIndex=0}exec(r){this.matcherRe.lastIndex=this.lastIndex;const l=this.matcherRe.exec(r);if(!l)return null;const w=l.findIndex((j,Z)=>Z>0&&j!==void 0),M=this.matchIndexes[w];return l.splice(0,w),Object.assign(l,M)}}class u{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(r){if(this.multiRegexes[r])return this.multiRegexes[r];const l=new i;return this.rules.slice(r).forEach(([w,M])=>l.addRule(w,M)),l.compile(),this.multiRegexes[r]=l,l}resumingScanAtSamePosition(){return this.regexIndex!==0}considerAll(){this.regexIndex=0}addRule(r,l){this.rules.push([r,l]),l.type==="begin"&&this.count++}exec(r){const l=this.getMatcher(this.regexIndex);l.lastIndex=this.lastIndex;let w=l.exec(r);if(this.resumingScanAtSamePosition()&&!(w&&w.index===this.lastIndex)){const M=this.getMatcher(0);M.lastIndex=this.lastIndex+1,w=M.exec(r)}return w&&(this.regexIndex+=w.position+1,this.regexIndex===this.count&&this.considerAll()),w}}function b(c){const r=new u;return c.contains.forEach(l=>r.addRule(l.begin,{rule:l,type:"begin"})),c.terminatorEnd&&r.addRule(c.terminatorEnd,{type:"end"}),c.illegal&&r.addRule(c.illegal,{type:"illegal"}),r}function _(c,r){const l=c;if(c.isCompiled)return l;[yt,At,jt,Tt].forEach(M=>M(c,r)),e.compilerExtensions.forEach(M=>M(c,r)),c.__beforeBegin=null,[St,Nt,kt].forEach(M=>M(c,r)),c.isCompiled=!0;let w=null;return typeof c.keywords=="object"&&c.keywords.$pattern&&(c.keywords=Object.assign({},c.keywords),w=c.keywords.$pattern,delete c.keywords.$pattern),w=w||/\w+/,c.keywords&&(c.keywords=ke(c.keywords,e.case_insensitive)),l.keywordPatternRe=t(w,!0),r&&(c.begin||(c.begin=/\B|\b/),l.beginRe=t(l.begin),!c.end&&!c.endsWithParent&&(c.end=/\B|\b/),c.end&&(l.endRe=t(l.end)),l.terminatorEnd=P(l.end)||"",c.endsWithParent&&r.terminatorEnd&&(l.terminatorEnd+=(c.end?"|":"")+r.terminatorEnd)),c.illegal&&(l.illegalRe=t(c.illegal)),c.contains||(c.contains=[]),c.contains=[].concat(...c.contains.map(function(M){return Ut(M==="self"?c:M)})),c.contains.forEach(function(M){_(M,l)}),c.starts&&_(c.starts,r),l.matcher=b(l),l}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=B(e.classNameAliases||{}),_(e)}function Ie(e){return e?e.endsWithParent||Ie(e.starts):!1}function Ut(e){return e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map(function(t){return B(e,{variants:null},t)})),e.cachedVariants?e.cachedVariants:Ie(e)?B(e,{starts:e.starts?B(e.starts):null}):Object.isFrozen(e)?B(e):e}var $t="11.11.1";class Gt extends Error{constructor(t,i){super(t),this.name="HTMLInjectionError",this.html=i}}const ee=we,_e=B,Me=Symbol("nomatch"),Wt=7,Be=function(e){const t=Object.create(null),i=Object.create(null),u=[];let b=!0;const _="Could not find the language '{}', did you forget to load/include a language module?",c={disableAutodetect:!0,name:"Plain text",contains:[]};let r={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:et};function l(n){return r.noHighlightRe.test(n)}function w(n){let a=n.className+" ";a+=n.parentNode?n.parentNode.className:"";const h=r.languageDetectRe.exec(a);if(h){const d=T(h[1]);return d||(be(_.replace("{}",h[1])),be("Falling back to no-highlight mode for this block.",n)),d?h[1]:"no-highlight"}return a.split(/\s+/).find(d=>l(d)||T(d))}function M(n,a,h){let d="",x="";typeof a=="object"?(d=n,h=a.ignoreIllegals,x=a.language):(L("10.7.0","highlight(lang, code, ...args) has been deprecated."),L("10.7.0",`Please use highlight(code, options) instead.
2
2
  https://github.com/highlightjs/highlight.js/issues/2277`),x=n,d=a),h===void 0&&(h=!0);const S={code:d,language:x};G("before:highlight",S);const I=S.result?S.result:j(S.language,S.code,h);return I.code=S.code,G("after:highlight",I),I}function j(n,a,h,d){const x=Object.create(null);function S(s,o){return s.keywords[o]}function I(){if(!f.keywords){O.addText(E);return}let s=0;f.keywordPatternRe.lastIndex=0;let o=f.keywordPatternRe.exec(E),g="";for(;o;){g+=E.substring(s,o.index);const p=A.case_insensitive?o[0].toLowerCase():o[0],R=S(f,p);if(R){const[k,Ze]=R;if(O.addText(g),g="",x[p]=(x[p]||0)+1,x[p]<=Wt&&(F+=Ze),k.startsWith("_"))g+=o[0];else{const Je=A.classNameAliases[k]||k;N(o[0],Je)}}else g+=o[0];s=f.keywordPatternRe.lastIndex,o=f.keywordPatternRe.exec(E)}g+=E.substring(s),O.addText(g)}function W(){if(E==="")return;let s=null;if(typeof f.subLanguage=="string"){if(!t[f.subLanguage]){O.addText(E);return}s=j(f.subLanguage,E,!0,ge[f.subLanguage]),ge[f.subLanguage]=s._top}else s=J(E,f.subLanguage.length?f.subLanguage:null);f.relevance>0&&(F+=s.relevance),O.__addSublanguage(s._emitter,s.language)}function y(){f.subLanguage!=null?W():I(),E=""}function N(s,o){s!==""&&(O.startScope(o),O.addText(s),O.endScope())}function ae(s,o){let g=1;const p=o.length-1;for(;g<=p;){if(!s._emit[g]){g++;continue}const R=A.classNameAliases[s[g]]||s[g],k=o[g];R?N(k,R):(E=k,I(),E=""),g++}}function le(s,o){return s.scope&&typeof s.scope=="string"&&O.openNode(A.classNameAliases[s.scope]||s.scope),s.beginScope&&(s.beginScope._wrap?(N(E,A.classNameAliases[s.beginScope._wrap]||s.beginScope._wrap),E=""):s.beginScope._multi&&(ae(s.beginScope,o),E="")),f=Object.create(s,{parent:{value:f}}),f}function ue(s,o,g){let p=st(s.endRe,g);if(p){if(s["on:end"]){const R=new he(s);s["on:end"](o,R),R.isMatchIgnored&&(p=!1)}if(p){for(;s.endsParent&&s.parent;)s=s.parent;return s}}if(s.endsWithParent)return ue(s.parent,o,g)}function Ke(s){return f.matcher.regexIndex===0?(E+=s[0],1):(m=!0,0)}function Fe(s){const o=s[0],g=s.rule,p=new he(g),R=[g.__beforeBegin,g["on:begin"]];for(const k of R)if(k&&(k(s,p),p.isMatchIgnored))return Ke(o);return g.skip?E+=o:(g.excludeBegin&&(E+=o),y(),!g.returnBegin&&!g.excludeBegin&&(E=o)),le(g,s),g.returnBegin?0:o.length}function ze(s){const o=s[0],g=a.substring(s.index),p=ue(f,s,g);if(!p)return Me;const R=f;f.endScope&&f.endScope._wrap?(y(),N(o,f.endScope._wrap)):f.endScope&&f.endScope._multi?(y(),ae(f.endScope,s)):R.skip?E+=o:(R.returnEnd||R.excludeEnd||(E+=o),y(),R.excludeEnd&&(E=o));do f.scope&&O.closeNode(),!f.skip&&!f.subLanguage&&(F+=f.relevance),f=f.parent;while(f!==p.parent);return p.starts&&le(p.starts,s),R.returnEnd?0:o.length}function Xe(){const s=[];for(let o=f;o!==A;o=o.parent)o.scope&&s.unshift(o.scope);s.forEach(o=>O.openNode(o))}let K={};function fe(s,o){const g=o&&o[0];if(E+=s,g==null)return y(),0;if(K.type==="begin"&&o.type==="end"&&K.index===o.index&&g===""){if(E+=a.slice(o.index,o.index+1),!b){const p=new Error(`0 width match regex (${n})`);throw p.languageName=n,p.badRule=K.rule,p}return 1}if(K=o,o.type==="begin")return Fe(o);if(o.type==="illegal"&&!h){const p=new Error('Illegal lexeme "'+g+'" for mode "'+(f.scope||"<unnamed>")+'"');throw p.mode=f,p}else if(o.type==="end"){const p=ze(o);if(p!==Me)return p}if(o.type==="illegal"&&g==="")return E+=`
3
3
  `,1;if(Q>1e5&&Q>o.index*3)throw new Error("potential infinite loop, way more iterations than matches");return E+=g,g.length}const A=T(n);if(!A)throw v(_.replace("{}",n)),new Error('Unknown language: "'+n+'"');const Ye=Pt(A);let q="",f=d||Ye;const ge={},O=new r.__emitter(r);Xe();let E="",F=0,D=0,Q=0,m=!1;try{if(A.__emitTokens)A.__emitTokens(a,O);else{for(f.matcher.considerAll();;){Q++,m?m=!1:f.matcher.considerAll(),f.matcher.lastIndex=D;const s=f.matcher.exec(a);if(!s)break;const o=a.substring(D,s.index),g=fe(o,s);D=s.index+g}fe(a.substring(D))}return O.finalize(),q=O.toHTML(),{language:n,value:q,relevance:F,illegal:!1,_emitter:O,_top:f}}catch(s){if(s.message&&s.message.includes("Illegal"))return{language:n,value:ee(a),illegal:!0,relevance:0,_illegalBy:{message:s.message,index:D,context:a.slice(D-100,D+100),mode:s.mode,resultSoFar:q},_emitter:O};if(b)return{language:n,value:ee(a),illegal:!1,relevance:0,errorRaised:s,_emitter:O,_top:f};throw s}}function Z(n){const a={value:ee(n),illegal:!1,relevance:0,_top:c,_emitter:new r.__emitter(r)};return a._emitter.addText(n),a}function J(n,a){a=a||r.languages||Object.keys(t);const h=Z(n),d=a.filter(T).filter(oe).map(y=>j(y,n,!1));d.unshift(h);const x=d.sort((y,N)=>{if(y.relevance!==N.relevance)return N.relevance-y.relevance;if(y.language&&N.language){if(T(y.language).supersetOf===N.language)return 1;if(T(N.language).supersetOf===y.language)return-1}return 0}),[S,I]=x,W=S;return W.secondBest=I,W}function De(n,a,h){const d=a&&i[a]||h;n.classList.add("hljs"),n.classList.add(`language-${d}`)}function V(n){let a=null;const h=w(n);if(l(h))return;if(G("before:highlightElement",{el:n,language:h}),n.dataset.highlighted){console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",n);return}if(n.children.length>0&&(r.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),console.warn("The element with unescaped HTML:"),console.warn(n)),r.throwUnescapedHTML))throw new Gt("One of your code blocks includes unescaped HTML.",n.innerHTML);a=n;const d=a.textContent,x=h?M(d,{language:h,ignoreIllegals:!0}):J(d);n.innerHTML=x.value,n.dataset.highlighted="yes",De(n,h,x.language),n.result={language:x.language,re:x.relevance,relevance:x.relevance},x.secondBest&&(n.secondBest={language:x.secondBest.language,relevance:x.secondBest.relevance}),G("after:highlightElement",{el:n,result:x,text:d})}function ve(n){r=_e(r,n)}const Ce=()=>{$(),L("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")};function Le(){$(),L("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")}let re=!1;function $(){function n(){$()}if(document.readyState==="loading"){re||window.addEventListener("DOMContentLoaded",n,!1),re=!0;return}document.querySelectorAll(r.cssSelector).forEach(V)}function He(n,a){let h=null;try{h=a(e)}catch(d){if(v("Language definition for '{}' could not be registered.".replace("{}",n)),b)v(d);else throw d;h=c}h.name||(h.name=n),t[n]=h,h.rawDefinition=a.bind(null,e),h.aliases&&ce(h.aliases,{languageName:n})}function je(n){delete t[n];for(const a of Object.keys(i))i[a]===n&&delete i[a]}function Pe(){return Object.keys(t)}function T(n){return n=(n||"").toLowerCase(),t[n]||t[i[n]]}function ce(n,{languageName:a}){typeof n=="string"&&(n=[n]),n.forEach(h=>{i[h.toLowerCase()]=a})}function oe(n){const a=T(n);return a&&!a.disableAutodetect}function Ue(n){n["before:highlightBlock"]&&!n["before:highlightElement"]&&(n["before:highlightElement"]=a=>{n["before:highlightBlock"](Object.assign({block:a.el},a))}),n["after:highlightBlock"]&&!n["after:highlightElement"]&&(n["after:highlightElement"]=a=>{n["after:highlightBlock"](Object.assign({block:a.el},a))})}function $e(n){Ue(n),u.push(n)}function Ge(n){const a=u.indexOf(n);a!==-1&&u.splice(a,1)}function G(n,a){const h=n;u.forEach(function(d){d[h]&&d[h](a)})}function We(n){return L("10.7.0","highlightBlock will be removed entirely in v12.0"),L("10.7.0","Please use highlightElement now."),V(n)}Object.assign(e,{highlight:M,highlightAuto:J,highlightAll:$,highlightElement:V,highlightBlock:We,configure:ve,initHighlighting:Ce,initHighlightingOnLoad:Le,registerLanguage:He,unregisterLanguage:je,listLanguages:Pe,getLanguage:T,registerAliases:ce,autoDetection:oe,inherit:_e,addPlugin:$e,removePlugin:Ge}),e.debugMode=function(){b=!1},e.safeMode=function(){b=!0},e.versionString=$t,e.regex={concat:C,lookahead:Oe,either:ne,optional:nt,anyNumberOfTimes:tt};for(const n in z)typeof z[n]=="object"&&xe(z[n]);return Object.assign(e,z),e},H=Be({});H.newInstance=()=>Be({});var Kt=H;H.HighlightJS=H;H.default=H;const zt=Ve(Kt);export{zt as HighlightJS,zt as default};