@codady/coax 0.0.3 → 0.0.5

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/dist/coax.esm.js CHANGED
@@ -1,10 +1,10 @@
1
1
 
2
2
  /*!
3
- * @since Last modified: 2026-1-12 9:47:5
3
+ * @since Last modified: 2026-1-12 15:14:48
4
4
  * @name Coax event management system.
5
- * @version 0.0.3
5
+ * @version 0.0.5
6
6
  * @author AXUI development team <3217728223@qq.com>
7
- * @description Coax is a custom web component that enables syntax highlighting for various programming languages inside your HTML documents.
7
+ * @description Coax is a lightweight web component for elegant code display with syntax highlighting, typewriter effects, and theme switching. Supports JavaScript, HTML, CSS, TypeScript, and Markdown with copy tools and customization.
8
8
  * @see {@link https://coax.axui.cn|Official website}
9
9
  * @see {@link https://github.com/codady/coax/issues|github issues}
10
10
  * @see {@link https://gitee.com/codady/coax/issues|Gitee issues}
@@ -266,36 +266,35 @@ const createTools = (data) => {
266
266
  return toolsEl;
267
267
  };
268
268
 
269
- class CoaxElem extends HTMLElement {
269
+ class Coax extends HTMLElement {
270
270
  // A static Map to hold the configuration for different languages
271
271
  static languages = new Map();
272
+ // A static array to hold the tools registered with the component
272
273
  static tools = [];
273
- source;
274
- _renderQueued = false;
275
- baseStylesEl;
276
- themeStylesEl;
277
- dynamicStylesEl;
278
- highlightedCodeEl;
279
- headerEl;
280
- codeNameEl;
281
- codeToolsEl;
282
- codeBodyEl;
283
- alias;
284
- lineString;
285
- speed;
286
- autoScroll;
274
+ source; // Source code content to be highlighted
275
+ _renderQueued = false; // Flag to prevent multiple render requests
276
+ baseStylesEl; // Element for base styles
277
+ themeStylesEl; // Element for theme styles
278
+ dynamicStylesEl; // Element for dynamic styles
279
+ highlightEl; // Element that holds the highlighted code
280
+ headerEl; // Header element (for code name, tools, etc.)
281
+ codeNameEl; // Code name element (shows language or alias)
282
+ codeToolsEl; // Code tools element (for interactive tools like copy)
283
+ codeBodyEl; // Code body element (the container for the code)
284
+ lang = 'plain'; // Language of the code (default is plain text)
285
+ alias = 'Plain Text'; // Alias name for the language (default is 'Plain Text')
286
+ lineString = ''; // The current line's string being typed
287
+ lastLineString = ''; // The last line's string
288
+ speed = 5; // Speed of the typing effect (higher is slower)
289
+ autoScroll = true; // Flag to enable/disable auto-scrolling
290
+ canListen = true; // Flag to enable/disable auto-scrolling
287
291
  constructor() {
288
292
  super();
289
293
  // Attach a Shadow DOM to the custom element
290
294
  this.attachShadow({ mode: 'open' });
291
295
  // Remove leading/trailing whitespace from the raw code content
292
296
  this.source = this.textContent?.replace(/^\s*\n|\n\s*$/g, '') || '';
293
- this.lang = 'plain';
294
- this.alias = 'Plain Text';
295
- this.lineString = '';
296
- this.speed = 5;
297
- this.autoScroll = true;
298
- // 1. 初始化基础骨架
297
+ // Initialize the basic structure of the component
299
298
  this.shadowRoot.innerHTML = `
300
299
  <style id="base-styles">
301
300
  :host {
@@ -425,10 +424,10 @@ class CoaxElem extends HTMLElement {
425
424
  <style id="theme-styles"></style>
426
425
  <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>
427
426
  <div id="code-body">
428
- <pre><code id="highlight-code"></code></pre>
427
+ <pre><code id="highlight"></code></pre>
429
428
  </div>
430
429
  `;
431
- // 缓存引用
430
+ // Cache references to various elements
432
431
  this.baseStylesEl = getEl('#base-styles', this.shadowRoot);
433
432
  this.themeStylesEl = getEl('#theme-styles', this.shadowRoot);
434
433
  this.dynamicStylesEl = getEl('#dynamic-styles', this.shadowRoot);
@@ -436,10 +435,10 @@ class CoaxElem extends HTMLElement {
436
435
  this.codeNameEl = getEl('#code-name', this.shadowRoot);
437
436
  this.codeToolsEl = getEl('#code-tools', this.shadowRoot);
438
437
  this.codeBodyEl = getEl('#code-body', this.shadowRoot);
439
- this.highlightedCodeEl = getEl('#highlight-code', this.shadowRoot);
438
+ this.highlightEl = getEl('#highlight', this.shadowRoot);
440
439
  this.codeBodyEl.addEventListener('scroll', () => {
441
440
  let flag = this.codeBodyEl.scrollTop + this.codeBodyEl.clientHeight < this.codeBodyEl.scrollHeight;
442
- // 检测是否是用户手动滚动
441
+ // Check if the user manually scrolled
443
442
  this.autoScroll = !flag;
444
443
  });
445
444
  }
@@ -448,11 +447,11 @@ class CoaxElem extends HTMLElement {
448
447
  // Store the language configuration in the static map
449
448
  this.languages.set(name, { ...config });
450
449
  }
451
- //注册工具箱
450
+
452
451
  static addTools(items) {
453
- CoaxElem.tools = items;
452
+ Coax.tools = items;
454
453
  }
455
- //加入工具箱
454
+
456
455
  mountTools(toolItems) {
457
456
  requestAnimationFrame(() => {
458
457
  this.codeToolsEl.innerHTML = '';
@@ -463,31 +462,32 @@ class CoaxElem extends HTMLElement {
463
462
  this.codeToolsEl.appendChild(createTools(items));
464
463
  });
465
464
  }
466
- // Called when the element is connected to the DOM
465
+
467
466
  connectedCallback() {
468
467
  this.render();
469
468
  }
470
- // Observed attributes for changes
469
+
471
470
  static get observedAttributes() { return ['lang', 'height', 'max-height', 'tools', 'speed']; }
472
471
 
473
472
  attributeChangedCallback(name, oldVal, newVal) {
474
- if (oldVal === newVal)
473
+ if (oldVal === newVal || !this.canListen)
475
474
  return;
476
475
  if (name === 'height' || name === 'max-height') {
477
476
  this.updateStyleByRegExp(name, newVal);
478
477
  }
479
478
  if (name === 'speed') {
479
+ // Convert to integer (0 or 1)
480
480
  this.speed = ~~(!!newVal);
481
481
  }
482
482
  if (name === 'lang') {
483
- //更新当前语言
483
+ // Update the language and re-render
484
484
  this.lang = newVal;
485
485
  this.render();
486
486
  }
487
487
  if (name === 'tools') {
488
488
  if (!newVal)
489
489
  this.codeToolsEl.innerHTML = '';
490
- const tools = parseClasses$1(newVal), toolItems = CoaxElem.tools.filter(k => tools.includes(k.name));
490
+ const tools = parseClasses$1(newVal), toolItems = Coax.tools.filter(k => tools.includes(k.name));
491
491
  if (!toolItems.length)
492
492
  return;
493
493
  this.mountTools(toolItems);
@@ -501,11 +501,13 @@ class CoaxElem extends HTMLElement {
501
501
  // 替换为新的属性值
502
502
  this.baseStylesEl.textContent = this.baseStylesEl.textContent.replace(regex, `;\n${prop}: ${value};`);
503
503
  }
504
+
504
505
  getCssPrefix(config) {
505
506
  return (config?.cssPrefix || this.lang).replace(/[^a-zA-Z0-9_-]/g, '\\$&');
506
507
  }
508
+
507
509
  getHighLightString(string, config) {
508
- config = config || CoaxElem.languages.get(this.lang);
510
+ config = config || Coax.languages.get(this.lang);
509
511
  if (!config)
510
512
  return string;
511
513
  // 如果找到了配置,则进行高亮处理
@@ -517,19 +519,21 @@ class CoaxElem extends HTMLElement {
517
519
  return i !== -1 && config.rules[i] ? `<span class="${NAMESPACE}-${cssPrefix}-${config.rules[i].token}">${match}</span>` : match;
518
520
  });
519
521
  }
522
+
520
523
  createLineWrap(index, startIndex) {
521
524
  let dataIndex = 0;
522
525
  if (index == null && startIndex == null) {
523
- dataIndex = this.highlightedCodeEl.children.length;
526
+ dataIndex = this.highlightEl.children.length;
524
527
  }
525
528
  else {
526
- const start = startIndex || this.highlightedCodeEl.children.length;
529
+ const start = startIndex || this.highlightEl.children.length;
527
530
  dataIndex = start + index;
528
531
  }
529
532
  return createEl('div', { 'data-index': dataIndex }, '<div></div>');
530
533
  }
534
+
531
535
  getLineToFill(codeWrap, line, config) {
532
- config = config || CoaxElem.languages.get(this.lang);
536
+ config = config || Coax.languages.get(this.lang);
533
537
  let highlightedLine = this.getHighLightString(line, config);
534
538
  // 将高亮后的内容填充到 div 中
535
539
  codeWrap.innerHTML = highlightedLine;
@@ -537,7 +541,7 @@ class CoaxElem extends HTMLElement {
537
541
  ;
538
542
 
539
543
  async highlight(newCode) {
540
- const config = CoaxElem.languages.get(this.lang), startIndex = this.highlightedCodeEl.children.length,
544
+ const config = Coax.languages.get(this.lang), startIndex = this.highlightEl.children.length,
541
545
  // 将新源码按行分割
542
546
  newCodeLines = newCode ? newCode.split('\n') : [];
543
547
  //更新别名
@@ -552,9 +556,9 @@ class CoaxElem extends HTMLElement {
552
556
  // 创建一个 div 包裹每一行
553
557
  const lineWrap = this.createLineWrap(index, startIndex), codeWrap = lineWrap.lastElementChild;
554
558
  //标记完成
555
- this.closeLine(lineWrap);
559
+ lineWrap.completed = true;
556
560
  if (this.hasAttribute('speed')) {
557
- this.highlightedCodeEl.appendChild(lineWrap);
561
+ this.highlightEl.appendChild(lineWrap);
558
562
  //流式打字
559
563
  await typeWriter(lineString, {
560
564
  speed: this.speed,
@@ -568,20 +572,22 @@ class CoaxElem extends HTMLElement {
568
572
  //直接打出
569
573
  this.getLineToFill(codeWrap, lineString, config);
570
574
  //
571
- this.highlightedCodeEl.appendChild(lineWrap);
575
+ this.highlightEl.appendChild(lineWrap);
572
576
  }
573
577
  }
574
578
  //滚动到最底部
575
579
  this.autoScrollCode();
576
580
  return true;
577
581
  }
582
+
578
583
  autoScrollCode() {
579
584
  if (this.autoScroll) {
580
585
  this.codeBodyEl.scrollTop = this.codeBodyEl.scrollHeight;
581
586
  }
582
587
  }
588
+
583
589
  injectThemeStyles() {
584
- const config = CoaxElem.languages.get(this.lang);
590
+ const config = Coax.languages.get(this.lang);
585
591
  if (!config)
586
592
  return;
587
593
  // Get language name, fallback to 'js' if not provided
@@ -603,13 +609,13 @@ class CoaxElem extends HTMLElement {
603
609
  .${NAMESPACE}-${cssPrefix}-${rule.token} { color: var(--${NAMESPACE}-${cssPrefix}-${rule.token},${rule.dark}); }` : ``} `).join('\n');
604
610
  schemeStyles += `}`;
605
611
  // Set the inner HTML of the shadow root, including styles and highlighted code
606
- // 2. 精确更新 DOM 节点而非重写 ShadowRoot
607
612
  this.dynamicStylesEl.textContent = lightStyles + darkStyles + schemeStyles;
608
613
  //附加主题样式
609
614
  if (config?.themeStyles) {
610
615
  this.themeStylesEl.textContent = config.themeStyles;
611
616
  }
612
617
  }
618
+
613
619
  updateName(config) {
614
620
  if (this.hasAttribute('unnamed'))
615
621
  return;
@@ -625,21 +631,18 @@ class CoaxElem extends HTMLElement {
625
631
 
626
632
  render(code = this.source) {
627
633
  //同时多次改变属性,只执行一次
628
- // 如果已经在队列中,则直接返回
629
634
  if (this._renderQueued)
630
635
  return;
631
636
  this._renderQueued = true;
632
- // 使用 requestAnimationFrame 将渲染推迟到下一帧
633
- requestAnimationFrame(async () => {
634
- this.clear();
635
- this.injectThemeStyles();
636
- //一次性渲染
637
- await this.highlight(code);
638
- this._renderQueued = false;
639
- });
637
+ this.clear();
638
+ this.injectThemeStyles();
639
+ //一次性渲染
640
+ this.highlight(code);
641
+ this._renderQueued = false;
640
642
  }
643
+
641
644
  clear() {
642
- this.highlightedCodeEl.innerHTML = this.source = this.lineString = '';
645
+ this.highlightEl.innerHTML = this.source = this.lineString = '';
643
646
  }
644
647
 
645
648
  async replace(newCode) {
@@ -653,36 +656,46 @@ class CoaxElem extends HTMLElement {
653
656
  // 高亮新的部分
654
657
  await this.highlight(newCode);
655
658
  }
656
- getActiveCodeWrap() {
657
- const lastChild = this.highlightedCodeEl.lastElementChild, lastLine = !lastChild || this.highlightedCodeEl.lastElementChild?.completed ?
659
+
660
+ getLastLine() {
661
+ const lastChild = this.highlightEl.lastElementChild, lastLine = !lastChild || this.highlightEl.lastElementChild?.completed ?
658
662
  this.createLineWrap() : lastChild;
659
663
  return {
660
664
  lineWrap: lastLine,
661
665
  codeWrap: lastLine.lastElementChild
662
666
  };
663
667
  }
664
- closeLine(lineWrap) {
665
- lineWrap = lineWrap || this.highlightedCodeEl.lastElementChild;
666
- lineWrap && (lineWrap.completed = true);
668
+
669
+ close() {
670
+ const lineWrap = this.highlightEl.lastElementChild;
671
+ if (!lineWrap)
672
+ return;
673
+ lineWrap.completed = true;
674
+ //行结束前保存
675
+ this.lastLineString = this.lineString;
676
+ this.getLineToFill(lineWrap?.lastElementChild, this.lineString);
677
+ //一行结束,清空临时行文本
678
+ this.lineString = '';
667
679
  }
668
- openLine(lineWrap) {
669
- lineWrap = lineWrap || this.highlightedCodeEl.lastElementChild;
670
- lineWrap && (lineWrap.completed = false);
680
+
681
+ open() {
682
+ const lineWrap = this.highlightEl.lastElementChild;
683
+ if (!lineWrap)
684
+ return;
685
+ lineWrap.completed = false;
686
+ //恢复最后一行字符串
687
+ (lineWrap?.lastElementChild).textContent = this.lineString = this.lastLineString;
671
688
  }
672
- stream(str, forceEnd = false) {
673
- const { lineWrap, codeWrap } = this.getActiveCodeWrap();
674
- this.highlightedCodeEl.appendChild(lineWrap);
689
+
690
+ stream(str, forceClose = false) {
691
+ const { lineWrap, codeWrap } = this.getLastLine();
692
+ this.highlightEl.appendChild(lineWrap);
675
693
  //汇集
676
694
  this.source += str;
677
695
  //如果没有遇到换行符号,也可以强制结束
678
- forceEnd && this.closeLine(lineWrap);
679
- if (str.startsWith('\n') || str.startsWith('\r')) {
696
+ if (forceClose || (str.startsWith('\n') || str.endsWith('\n'))) {
680
697
  //标记完成
681
- this.closeLine(lineWrap);
682
- //渲染
683
- this.getLineToFill(codeWrap, this.lineString);
684
- //一行结束,清空临时行文本
685
- this.lineString = '';
698
+ this.close();
686
699
  }
687
700
  else {
688
701
  //插入文本
@@ -859,4 +872,4 @@ const copy = {
859
872
  }
860
873
  };
861
874
 
862
- export { CoaxElem, copy, css, html, javascript, markdown, typescript };
875
+ export { Coax, copy, css, html, javascript, markdown, typescript };
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * @since Last modified: 2026-1-12 9:47:5
2
+ * @since Last modified: 2026-1-12 15:14:48
3
3
  * @name Coax event management system.
4
- * @version 0.0.3
4
+ * @version 0.0.5
5
5
  * @author AXUI development team <3217728223@qq.com>
6
- * @description Coax is a custom web component that enables syntax highlighting for various programming languages inside your HTML documents.
6
+ * @description Coax is a lightweight web component for elegant code display with syntax highlighting, typewriter effects, and theme switching. Supports JavaScript, HTML, CSS, TypeScript, and Markdown with copy tools and customization.
7
7
  * @see {@link https://coax.axui.cn|Official website}
8
8
  * @see {@link https://github.com/codady/coax/issues|github issues}
9
9
  * @see {@link https://gitee.com/codady/coax/issues|Gitee issues}
@@ -12,4 +12,4 @@
12
12
  * @copyright This software supports the MIT License, allowing free learning and commercial use, but please retain the terms 'coax', 'Coax' and 'COAX' within the software.
13
13
  * @license MIT license
14
14
  */
15
- const typeWriter=(e,t)=>{const n=t.speed||100;return new Promise(r=>{t?.onBeforeType?.(e);let i=0;const a=setInterval(()=>{if(i<e.length){const n=e.charAt(i),r=e.substring(0,i+1);t?.onDuringType?.(n,r),i++}else clearInterval(a),r(e),t?.onAfterType?.(e)},n)})},COMMA$1=",",SPACE$1=" ",trim$1=(e,t="compress")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses$1=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim$1(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim$1(e,"global")).filter(Boolean)},NAMESPACE="ax",getDataType=e=>{let t,n=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===n&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===n&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":n,t},getEl=(e,t=document.body)=>{let n=getDataType(e),r=getDataType(t),i=r.includes("HTML")||"ShadowRoot"===r?t:document.querySelector(t),a=i&&i instanceof HTMLTemplateElement?i.content:i,o=null;if(e)if(n.includes("HTML"))o=e;else if("String"===n)try{o=(a||document).querySelector(e.trim())}catch{o=null}return o},createEl=(e,t,n)=>{let r=(e=e||"div").toUpperCase().trim(),i=document.createElement(r),a=getDataType(t);if(t&&"Object"===a)for(let e in t)t.hasOwnProperty(e)&&i.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let n=getDataType(t);if("TEMPLATE"===r)e.innerHTML=t.toString();else if("Array"===n&&t.length>0)for(let n of t){if(getDataType(n).includes("HTML"))e.appendChild(n);else{let t=createEl(n.name,n.attrs,n.content);t&&e.appendChild(t)}}else if(n.includes("HTML"))e.appendChild(t);else if("String"===n&&t.trim().startsWith("#")&&t.trim().length>1){let n=getEl(t);if(!n)return;"TEMPLATE"===n.nodeName?e.appendChild(n.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",n.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(i,n),i},isEmpty=e=>{let t,n=getDataType(e);return t=!e||("Object"===n?0===Object.keys(e).length:"Array"===n?""===e.join(""):"Function"===n?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===n?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===n||"Map"===n?0===e.size:"Date"===n?isNaN(e.getTime()):"RegExp"===n?""===e.source:"ArrayBuffer"===n?0===e.byteLength:"NodeList"===n||"HTMLCollection"===n||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===n||e instanceof Error?""===e.message:!(!n.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(n))&&0===e.length),t},ALIAS="rep",addClasses=(e,t,n)=>{const r=getEl(e),i=parseClasses$1(t);r&&0!==i.length&&i.forEach(e=>{r.classList.add(e)})},createTools=e=>{const t=createEl("span",{class:"ax-box-tools"}),renderFn=e=>{const t={},n=e.extendable?'<i rep="arrow"></i>':"",r=(e.icon?`<i rep="icon">${e.icon}</i>`:"")+(e.disk?`<i rep="disk"><img src="${e.disk}"/></i>`:"")+(e.cube?`<i rep="cube"><img src="${e.cube}"/></i>`:"")+(e.image?`<i rep="image"><img src="${e.image}"/></i>`:"")+(e.label?`<i rep="label">${e.label}</i>`:"")+n;e.title&&(t.title=e.title),e.focusable&&(t.tabindex=1),e.wrapEl=createEl(e.nodeName||"span",Object.assign(t,e.attrs),r),e.iconEl=e.wrapEl.querySelector('[rep="icon"]'),e.cubeEl=e.wrapEl.querySelector('[rep="cube"]'),e.diskEl=e.wrapEl.querySelector('[rep="disk"]'),e.imageEl=e.wrapEl.querySelector('[rep="image"]'),e.labelEl=e.wrapEl.querySelector('[rep="label"]'),!isEmpty(e.classes)&&addClasses(e.wrapEl,e.classes),!isEmpty(e.styles)&&(e.wrapEl.style.cssText+=e.styles)};for(let n of e)renderFn(n),t.appendChild(n.wrapEl),n?.action?.(n);return t};class CoaxElem extends HTMLElement{static languages=new Map;static tools=[];source;_renderQueued=!1;baseStylesEl;themeStylesEl;dynamicStylesEl;highlightedCodeEl;headerEl;codeNameEl;codeToolsEl;codeBodyEl;alias;lineString;speed;autoScroll;constructor(){super(),this.attachShadow({mode:"open"}),this.source=this.textContent?.replace(/^\s*\n|\n\s*$/g,"")||"",this.lang="plain",this.alias="Plain Text",this.lineString="",this.speed=5,this.autoScroll=!0,this.shadowRoot.innerHTML=`\n <style id="base-styles">\n :host { \n --border-width:1px;\n --border-style:solid;\n --radius:9px;\n --height:auto;\n --max-height:500px;\n --radius:9px;\n --padding:1em;\n --font-size:16px;\n --line-height:1.8;\n --background:rgb(247, 247, 247);\n --border-color:rgb(224, 224, 224);\n --color-code:rgb(51, 51, 51);\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(0,0,0,0.04);\n --color-hover:rgba(0,0,0,0.06);\n } \n :host([scheme="dark"]){\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n @media (prefers-color-scheme: dark) {\n :host{\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n }\n :host {\n font-size: var(--ax-code-font-size,var(--font-size));\n display: block; \n box-sizing:border-box;\n background:var(--ax-code-background-color,var(--background));\n color:var(--ax-code-color,var(--color-code));\n border:var(--ax-code-border-width,var(--border-width)) var(--ax-code-border-style,var(--border-style)) var(--ax-code-border-color,var(--border-color));\n transition: border-color 0.3s ease,color 0.3s ease; \n border-radius: var(--ax-code-radius,var(--radius));\n }\n #code-header{\n line-height:calc(var(--ax-code-line-height,var(--line-height))*1.5);\n padding-inline-start:var(--ax-code-padding,var(--padding));\n display:flex;\n \n >:first-child{\n flex:auto;\n }\n }\n #code-body{\n padding: var(--ax-code-padding,var(--padding)) 0;\n height:var(--ax-code-height,var(--height));\n max-height:var(--ax-code-max-height,var(--max-height));\n overflow:auto;\n }\n pre,code{\n font-family:"Consolas", "Monaco", "Andale Mono", "Ubuntu Mono", "monospace";\n margin:0; padding:0;\n }\n code>div{\n display:flex;\n padding:0 var(--ax-code-padding,var(--padding));\n line-height: var(--ax-code-line-height,var(--line-height));\n box-sizing:border-box;\n \n >div{\n flex:auto;\n }\n }\n code>div>div:empty:before{\n content:' ';\n }\n :host([indexed]) code>div:before{\n display:inline-flex;\n color:var(--color-index);\n content: attr(data-index);\n min-width:var(--ax-code-index-width,2em);\n margin-inline-end:var(--ax-code-padding,8px);\n }\n :host([striped]) code>div:nth-child(odd){\n background-color:var(--color-stripe);\n }\n :host([hoverable]) code>div:hover{\n background-color:var(--color-hover);\n }\n :host([wrapped]) code>div>div{\n white-space: pre-wrap;\n }\n :host([unnamed]) #code-name{\n display:none;\n }\n .ax-box-tools{\n >*{\n font-size:14px;\n display:inline-flex;\n align-items:center;\n justify-content:center;\n height:2em;\n line-height:2em;\n aspect-ratio:1/1;\n margin-inline-end:8px;\n transition:all 200ms ease;\n border-radius:6px;\n &:hover{\n cursor:pointer;\n background-color:rgba(0,0,0,.04);\n }\n }\n [rep=icon]{\n display:inline-flex;\n align-items:center;\n justify-content:center;\n }\n }\n [disabled]{\n pointer-event:none;\n }\n </style>\n <style id="dynamic-styles"></style>\n <style id="theme-styles"></style>\n <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>\n <div id="code-body">\n <pre><code id="highlight-code"></code></pre>\n </div>\n `,this.baseStylesEl=getEl("#base-styles",this.shadowRoot),this.themeStylesEl=getEl("#theme-styles",this.shadowRoot),this.dynamicStylesEl=getEl("#dynamic-styles",this.shadowRoot),this.headerEl=getEl("#code-header",this.shadowRoot),this.codeNameEl=getEl("#code-name",this.shadowRoot),this.codeToolsEl=getEl("#code-tools",this.shadowRoot),this.codeBodyEl=getEl("#code-body",this.shadowRoot),this.highlightedCodeEl=getEl("#highlight-code",this.shadowRoot),this.codeBodyEl.addEventListener("scroll",()=>{let e=this.codeBodyEl.scrollTop+this.codeBodyEl.clientHeight<this.codeBodyEl.scrollHeight;this.autoScroll=!e})}static register(e,t){this.languages.set(e,{...t})}static addTools(e){CoaxElem.tools=e}mountTools(e){requestAnimationFrame(()=>{this.codeToolsEl.innerHTML="";let t=e.map(e=>(e.action=e.action.bind(this),e));this.codeToolsEl.appendChild(createTools(t))})}connectedCallback(){this.render()}static get observedAttributes(){return["lang","height","max-height","tools","speed"]}attributeChangedCallback(e,t,n){if(t!==n&&("height"!==e&&"max-height"!==e||this.updateStyleByRegExp(e,n),"speed"===e&&(this.speed=~~!!n),"lang"===e&&(this.lang=n,this.render()),"tools"===e)){n||(this.codeToolsEl.innerHTML="");const e=parseClasses$1(n),t=CoaxElem.tools.filter(t=>e.includes(t.name));if(!t.length)return;this.mountTools(t)}}updateStyleByRegExp(e,t){const n=new RegExp(`;\\n\\s*${e}:\\s*[^;]+;`,"g");this.baseStylesEl.textContent=this.baseStylesEl.textContent.replace(n,`;\n${e}: ${t};`)}getCssPrefix(e){return(e?.cssPrefix||this.lang).replace(/[^a-zA-Z0-9_-]/g,"\\$&")}getHighLightString(e,t){if(!(t=t||CoaxElem.languages.get(this.lang)))return e;const n=this.getCssPrefix(t),r=new RegExp(t.rules.map(e=>`(${e.pattern.source})`).join("|"),"g");return e.replace(r,(e,...r)=>{const i=r.findIndex(e=>void 0!==e);return-1!==i&&t.rules[i]?`<span class="ax-${n}-${t.rules[i].token}">${e}</span>`:e})}createLineWrap(e,t){let n=0;if(null==e&&null==t)n=this.highlightedCodeEl.children.length;else{n=(t||this.highlightedCodeEl.children.length)+e}return createEl("div",{"data-index":n},"<div></div>")}getLineToFill(e,t,n){n=n||CoaxElem.languages.get(this.lang);let r=this.getHighLightString(t,n);e.innerHTML=r}async highlight(e){const t=CoaxElem.languages.get(this.lang),n=this.highlightedCodeEl.children.length,r=e?e.split("\n"):[];if(this.updateName(t),!r.length)return!0;for(let[e,i]of r.entries()){if(!i.trim()&&this.hasAttribute("sanitized"))continue;const r=this.createLineWrap(e,n),a=r.lastElementChild;this.closeLine(r),this.hasAttribute("speed")?(this.highlightedCodeEl.appendChild(r),await typeWriter(i,{speed:this.speed,onDuringType:(e,t)=>{a.innerHTML=t}}),this.getLineToFill(a,i,t)):(this.getLineToFill(a,i,t),this.highlightedCodeEl.appendChild(r))}return this.autoScrollCode(),!0}autoScrollCode(){this.autoScroll&&(this.codeBodyEl.scrollTop=this.codeBodyEl.scrollHeight)}injectThemeStyles(){const e=CoaxElem.languages.get(this.lang);if(!e)return;let t=this.getCssPrefix(e),n=e.rules.map(e=>`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token}${e.light?","+e.light:""});}`).join("\n"),r="",i="";r+=':host([scheme="dark"]){',r+=e.rules.map(e=>"\n "+(e.light?`\n .ax-${t}-${e.token} {color: var(--ax-${t}-${e.token},${e.dark});}`:"")).join("\n"),r+="}",i="@media (prefers-color-scheme: dark){\n :host{\n ",i+=e.rules.map(e=>`\n ${e.light?`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token},${e.dark}); }`:""} `).join("\n"),i+="}",this.dynamicStylesEl.textContent=n+r+i,e?.themeStyles&&(this.themeStylesEl.textContent=e.themeStyles)}updateName(e){this.hasAttribute("unnamed")||(e?(this.alias=e.alias||this.lang,this.codeNameEl.innerHTML=this.alias):this.codeNameEl.innerHTML="Plain Text")}render(e=this.source){this._renderQueued||(this._renderQueued=!0,requestAnimationFrame(async()=>{this.clear(),this.injectThemeStyles(),await this.highlight(e),this._renderQueued=!1}))}clear(){this.highlightedCodeEl.innerHTML=this.source=this.lineString=""}async replace(e){this.clear(),await this.highlight(e)}async append(e){this.source+=`\n${e}`,await this.highlight(e)}getActiveCodeWrap(){const e=this.highlightedCodeEl.lastElementChild,t=!e||this.highlightedCodeEl.lastElementChild?.completed?this.createLineWrap():e;return{lineWrap:t,codeWrap:t.lastElementChild}}closeLine(e){(e=e||this.highlightedCodeEl.lastElementChild)&&(e.completed=!0)}openLine(e){(e=e||this.highlightedCodeEl.lastElementChild)&&(e.completed=!1)}stream(e,t=!1){const{lineWrap:n,codeWrap:r}=this.getActiveCodeWrap();this.highlightedCodeEl.appendChild(n),this.source+=e,t&&this.closeLine(n),e.startsWith("\n")||e.startsWith("\r")?(this.closeLine(n),this.getLineToFill(r,this.lineString),this.lineString=""):(r.innerHTML+=e,this.lineString+=e),this.autoScrollCode()}}const css=[{token:"comment",pattern:/\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"value",pattern:/(?:'|")(?:\\.|[^\\'"\b])*?(?:'|")/,light:"#032f62",dark:"#a5d6ff"},{token:"func",pattern:/[a-z-]+\(?=/,light:"#e36209",dark:"#ffa657"},{token:"property",pattern:/[a-z-]+(?=\s*:)/,light:"#005cc5",dark:"#79c0ff"},{token:"selector",pattern:/[.#a-z0-9, \n\t>:+()_-]+(?=\s*\{)/i,light:"#22863a",dark:"#7ee787"},{token:"unit",pattern:/(?<=\d)(px|em|rem|%|vh|vw|ms|s|deg)/,light:"#d73a49",dark:"#ff7b72"},{token:"number",pattern:/\b\d+(\.\d+)?\b/,light:"#005cc5",dark:"#79c0ff"},{token:"punct",pattern:/[{}();:]/,light:"#24292e",dark:"#c9d1d9"}],html=[{token:"comment",pattern:/&lt;!--[\s\S]*?--&gt;/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/&lt;!DOCTYPE[\s\S]*?&gt;/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/&lt;\/?[a-zA-Z0-9]+/,light:"#22863a",dark:"#7ee787"},{token:"attr",pattern:/[a-zA-Z-]+(?=\s*=\s*)/,light:"#6f42c1",dark:"#d2a8ff"},{token:"string",pattern:/(['"])(?:\\.|[^\\])*?\1/,light:"#032f62",dark:"#a5d6ff"},{token:"bracket",pattern:/\/?&gt;/,light:"#24292e",dark:"#c9d1d9"}],javascript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"keyword",pattern:/\b(async|await|break|case|catch|class|const|continue|default|delete|do|else|export|extends|finally|for|function|if|import|in|instanceof|new|return|super|switch|this|throw|try|typeof|var|while|with|yield|let|static)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(console|window|document|Math|JSON|true|false|null|undefined|Object|Array|Promise|Number|String|Boolean)\b/,light:"#e36209",dark:"#ffa657"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/[+\-*/%=<>!&|^~]+/,light:"#069598",dark:"#56b6c2"}],markdown=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#6a737d",dark:"#8b949e"},{token:"heading",pattern:/(^|\n)(#{1,6})\s*(.+)/,light:"#e36209",dark:"#ffa657"},{token:"bold",pattern:/\*\*([^*]+)\*\*|__([^_]+)__/g,light:"#d73a49",dark:"#ff7b72"},{token:"italic",pattern:/\*([^*]+)\*|_([^_]+)_/g,light:"#032f62",dark:"#a5d6ff"},{token:"link",pattern:/\[([^\]]+)\]\(([^)]+)\)/g,light:"#0288d1",dark:"#80c0ff"},{token:"inline-code",pattern:/`([^`]+)`/g,light:"#032f62",dark:"#98c379"},{token:"code-block",pattern:/```([^\n]+)\n([\s\S]*?)```/g,light:"#24292e",dark:"#c9d1d9"},{token:"list-item",pattern:/(^|\n)([-*])\s+(.+)/g,light:"#5c6e7c",dark:"#8b949e"},{token:"quote",pattern:/(^|\n)>[ \t]*(.+)/g,light:"#6f42c1",dark:"#d2a8ff"},{token:"image",pattern:/!\[([^\]]+)\]\(([^)]+)\)/g,light:"#d73a49",dark:"#ff7b72"},{token:"hr",pattern:/^(---|___|\*\*\*)\s*$/gm,light:"#24292e",dark:"#c9d1d9"},{token:"strikethrough",pattern:/~~([^~]+)~~/g,light:"#e36209",dark:"#ffa657"},{token:"table",pattern:/\|([^\|]+)\|([^\|]+)\|/g,light:"#5c6e7c",dark:"#8b949e"}],typescript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"decorator",pattern:/@[a-zA-Z_]\w*/,light:"#953800",dark:"#ffa657"},{token:"keyword",pattern:/\b(abstract|as|async|await|break|case|catch|class|const|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|package|private|protected|public|readonly|return|set|static|super|switch|this|throw|try|type|typeof|var|while|with|yield)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(any|boolean|never|number|string|symbol|unknown|void|undefined|null|true|false|console|window|document)\b/,light:"#e36209",dark:"#ffa657"},{token:"type",pattern:/\b[A-Z]\w*\b/,light:"#005cc5",dark:"#79c0ff"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/(\?\.|![:\.]|[+\-*/%=<>!&|^~]+)/,light:"#089ba6",dark:"#79c0ff"}],COMMA=",",SPACE=" ",trim=(e,t="")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim(e,"global")).filter(Boolean)},rtlStyle=(e="")=>`\n <style>\n :where([dir="rtl"]) .icax-${e},\n :where(:dir(rtl)) .icax-${e} {\n transform: scaleX(-1);\n transform-origin: center;\n }\n </style>\n`,wrap=(e,t,n=!1,r)=>{const i=r?.size||"1em",a=r?.color||"currentColor",o=r?.thickness||2,l=r?.classes?parseClasses(r.classes).join(" "):"",s=t.name.replace(/([A-Z])/g,"-$1").toLowerCase();return`<svg xmlns="http://www.w3.org/2000/svg" width="${i}" height="${i}" viewBox="0 0 24 24" fill="none" stroke="${a}"\n stroke-width="${o}" stroke-linecap="round" stroke-linejoin="round" class="${s} ${l}">\n ${n?rtlStyle(s.split("-")[1]):""}\n ${e}\n </svg>`},icaxCheck=e=>wrap('<polyline points="20 6 9 17 4 12"></polyline>',icaxCheck,!1,e),icaxCopy=e=>wrap('<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>',icaxCopy,!1,e),copy={name:"copy",icon:icaxCopy(),action:function(e){e.wrapEl.onclick=()=>{navigator.clipboard.writeText(this.source).then(()=>{e.iconEl.innerHTML=icaxCheck(),e.iconEl.toggleAttribute("disabled",!0),setTimeout(()=>{e.iconEl.removeAttribute("disabled"),e.iconEl.innerHTML=icaxCopy()},2e3)}).catch(e=>{})}}};export{CoaxElem,copy,css,html,javascript,markdown,typescript};
15
+ const typeWriter=(e,t)=>{const n=t.speed||100;return new Promise(r=>{t?.onBeforeType?.(e);let i=0;const a=setInterval(()=>{if(i<e.length){const n=e.charAt(i),r=e.substring(0,i+1);t?.onDuringType?.(n,r),i++}else clearInterval(a),r(e),t?.onAfterType?.(e)},n)})},COMMA$1=",",SPACE$1=" ",trim$1=(e,t="compress")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses$1=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim$1(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim$1(e,"global")).filter(Boolean)},NAMESPACE="ax",getDataType=e=>{let t,n=Object.prototype.toString.call(e).slice(8,-1);return t="Function"===n&&/^\s*class\s+/.test(e.toString())?"Class":"Object"===n&&Object.getPrototypeOf(e)!==Object.prototype?"Instance":n,t},getEl=(e,t=document.body)=>{let n=getDataType(e),r=getDataType(t),i=r.includes("HTML")||"ShadowRoot"===r?t:document.querySelector(t),a=i&&i instanceof HTMLTemplateElement?i.content:i,o=null;if(e)if(n.includes("HTML"))o=e;else if("String"===n)try{o=(a||document).querySelector(e.trim())}catch{o=null}return o},createEl=(e,t,n)=>{let r=(e=e||"div").toUpperCase().trim(),i=document.createElement(r),a=getDataType(t);if(t&&"Object"===a)for(let e in t)t.hasOwnProperty(e)&&i.setAttribute(e,"string"==typeof t[e]?t[e]:JSON.stringify(t[e]));return((e,t)=>{if(""===t||null==t)return!1;let n=getDataType(t);if("TEMPLATE"===r)e.innerHTML=t.toString();else if("Array"===n&&t.length>0)for(let n of t){if(getDataType(n).includes("HTML"))e.appendChild(n);else{let t=createEl(n.name,n.attrs,n.content);t&&e.appendChild(t)}}else if(n.includes("HTML"))e.appendChild(t);else if("String"===n&&t.trim().startsWith("#")&&t.trim().length>1){let n=getEl(t);if(!n)return;"TEMPLATE"===n.nodeName?e.appendChild(n.content.cloneNode(!0)):e.insertAdjacentHTML("beforeEnd",n.innerHTML)}else e.insertAdjacentHTML("beforeEnd",t)})(i,n),i},isEmpty=e=>{let t,n=getDataType(e);return t=!e||("Object"===n?0===Object.keys(e).length:"Array"===n?""===e.join(""):"Function"===n?"{}"===e.toString().replace(/\s+/g,"").match(/{.*}/g)[0]:"Symbol"===n?"()"===e.toString().replace(/\s+/g,"").match(/\(.*\)/g)[0]:"Set"===n||"Map"===n?0===e.size:"Date"===n?isNaN(e.getTime()):"RegExp"===n?""===e.source:"ArrayBuffer"===n?0===e.byteLength:"NodeList"===n||"HTMLCollection"===n||"length"in e&&"number"==typeof e.length?0===e.length:"size"in e&&"number"==typeof e.size?0===e.size:"Error"===n||e instanceof Error?""===e.message:!(!n.includes("Array")||!["Uint8Array","Int8Array","Uint16Array","Int16Array","Uint32Array","Int32Array","Float32Array","Float64Array"].includes(n))&&0===e.length),t},ALIAS="rep",addClasses=(e,t,n)=>{const r=getEl(e),i=parseClasses$1(t);r&&0!==i.length&&i.forEach(e=>{r.classList.add(e)})},createTools=e=>{const t=createEl("span",{class:"ax-box-tools"}),renderFn=e=>{const t={},n=e.extendable?'<i rep="arrow"></i>':"",r=(e.icon?`<i rep="icon">${e.icon}</i>`:"")+(e.disk?`<i rep="disk"><img src="${e.disk}"/></i>`:"")+(e.cube?`<i rep="cube"><img src="${e.cube}"/></i>`:"")+(e.image?`<i rep="image"><img src="${e.image}"/></i>`:"")+(e.label?`<i rep="label">${e.label}</i>`:"")+n;e.title&&(t.title=e.title),e.focusable&&(t.tabindex=1),e.wrapEl=createEl(e.nodeName||"span",Object.assign(t,e.attrs),r),e.iconEl=e.wrapEl.querySelector('[rep="icon"]'),e.cubeEl=e.wrapEl.querySelector('[rep="cube"]'),e.diskEl=e.wrapEl.querySelector('[rep="disk"]'),e.imageEl=e.wrapEl.querySelector('[rep="image"]'),e.labelEl=e.wrapEl.querySelector('[rep="label"]'),!isEmpty(e.classes)&&addClasses(e.wrapEl,e.classes),!isEmpty(e.styles)&&(e.wrapEl.style.cssText+=e.styles)};for(let n of e)renderFn(n),t.appendChild(n.wrapEl),n?.action?.(n);return t};class Coax extends HTMLElement{static languages=new Map;static tools=[];source;_renderQueued=!1;baseStylesEl;themeStylesEl;dynamicStylesEl;highlightEl;headerEl;codeNameEl;codeToolsEl;codeBodyEl;lang="plain";alias="Plain Text";lineString="";lastLineString="";speed=5;autoScroll=!0;canListen=!0;constructor(){super(),this.attachShadow({mode:"open"}),this.source=this.textContent?.replace(/^\s*\n|\n\s*$/g,"")||"",this.shadowRoot.innerHTML=`\n <style id="base-styles">\n :host { \n --border-width:1px;\n --border-style:solid;\n --radius:9px;\n --height:auto;\n --max-height:500px;\n --radius:9px;\n --padding:1em;\n --font-size:16px;\n --line-height:1.8;\n --background:rgb(247, 247, 247);\n --border-color:rgb(224, 224, 224);\n --color-code:rgb(51, 51, 51);\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(0,0,0,0.04);\n --color-hover:rgba(0,0,0,0.06);\n } \n :host([scheme="dark"]){\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n @media (prefers-color-scheme: dark) {\n :host{\n --background: #282c34;\n --border-color: transparent;\n --color-code: #abb2bf;\n --color-index:rgb(153, 153, 153);\n --color-stripe:rgba(255,255,255,0.04);\n --color-hover:rgba(255,255,255,0.06);\n }\n }\n :host {\n font-size: var(--ax-code-font-size,var(--font-size));\n display: block; \n box-sizing:border-box;\n background:var(--ax-code-background-color,var(--background));\n color:var(--ax-code-color,var(--color-code));\n border:var(--ax-code-border-width,var(--border-width)) var(--ax-code-border-style,var(--border-style)) var(--ax-code-border-color,var(--border-color));\n transition: border-color 0.3s ease,color 0.3s ease; \n border-radius: var(--ax-code-radius,var(--radius));\n }\n #code-header{\n line-height:calc(var(--ax-code-line-height,var(--line-height))*1.5);\n padding-inline-start:var(--ax-code-padding,var(--padding));\n display:flex;\n \n >:first-child{\n flex:auto;\n }\n }\n #code-body{\n padding: var(--ax-code-padding,var(--padding)) 0;\n height:var(--ax-code-height,var(--height));\n max-height:var(--ax-code-max-height,var(--max-height));\n overflow:auto;\n }\n pre,code{\n font-family:"Consolas", "Monaco", "Andale Mono", "Ubuntu Mono", "monospace";\n margin:0; padding:0;\n }\n code>div{\n display:flex;\n padding:0 var(--ax-code-padding,var(--padding));\n line-height: var(--ax-code-line-height,var(--line-height));\n box-sizing:border-box;\n \n >div{\n flex:auto;\n }\n }\n code>div>div:empty:before{\n content:' ';\n }\n :host([indexed]) code>div:before{\n display:inline-flex;\n color:var(--color-index);\n content: attr(data-index);\n min-width:var(--ax-code-index-width,2em);\n margin-inline-end:var(--ax-code-padding,8px);\n }\n :host([striped]) code>div:nth-child(odd){\n background-color:var(--color-stripe);\n }\n :host([hoverable]) code>div:hover{\n background-color:var(--color-hover);\n }\n :host([wrapped]) code>div>div{\n white-space: pre-wrap;\n }\n :host([unnamed]) #code-name{\n display:none;\n }\n .ax-box-tools{\n >*{\n font-size:14px;\n display:inline-flex;\n align-items:center;\n justify-content:center;\n height:2em;\n line-height:2em;\n aspect-ratio:1/1;\n margin-inline-end:8px;\n transition:all 200ms ease;\n border-radius:6px;\n &:hover{\n cursor:pointer;\n background-color:rgba(0,0,0,.04);\n }\n }\n [rep=icon]{\n display:inline-flex;\n align-items:center;\n justify-content:center;\n }\n }\n [disabled]{\n pointer-event:none;\n }\n </style>\n <style id="dynamic-styles"></style>\n <style id="theme-styles"></style>\n <div id="code-header"><span id="code-name">${this.alias}</span><div id="code-tools"></div></div>\n <div id="code-body">\n <pre><code id="highlight"></code></pre>\n </div>\n `,this.baseStylesEl=getEl("#base-styles",this.shadowRoot),this.themeStylesEl=getEl("#theme-styles",this.shadowRoot),this.dynamicStylesEl=getEl("#dynamic-styles",this.shadowRoot),this.headerEl=getEl("#code-header",this.shadowRoot),this.codeNameEl=getEl("#code-name",this.shadowRoot),this.codeToolsEl=getEl("#code-tools",this.shadowRoot),this.codeBodyEl=getEl("#code-body",this.shadowRoot),this.highlightEl=getEl("#highlight",this.shadowRoot),this.codeBodyEl.addEventListener("scroll",()=>{let e=this.codeBodyEl.scrollTop+this.codeBodyEl.clientHeight<this.codeBodyEl.scrollHeight;this.autoScroll=!e})}static register(e,t){this.languages.set(e,{...t})}static addTools(e){Coax.tools=e}mountTools(e){requestAnimationFrame(()=>{this.codeToolsEl.innerHTML="";let t=e.map(e=>(e.action=e.action.bind(this),e));this.codeToolsEl.appendChild(createTools(t))})}connectedCallback(){this.render()}static get observedAttributes(){return["lang","height","max-height","tools","speed"]}attributeChangedCallback(e,t,n){if(t!==n&&this.canListen&&("height"!==e&&"max-height"!==e||this.updateStyleByRegExp(e,n),"speed"===e&&(this.speed=~~!!n),"lang"===e&&(this.lang=n,this.render()),"tools"===e)){n||(this.codeToolsEl.innerHTML="");const e=parseClasses$1(n),t=Coax.tools.filter(t=>e.includes(t.name));if(!t.length)return;this.mountTools(t)}}updateStyleByRegExp(e,t){const n=new RegExp(`;\\n\\s*${e}:\\s*[^;]+;`,"g");this.baseStylesEl.textContent=this.baseStylesEl.textContent.replace(n,`;\n${e}: ${t};`)}getCssPrefix(e){return(e?.cssPrefix||this.lang).replace(/[^a-zA-Z0-9_-]/g,"\\$&")}getHighLightString(e,t){if(!(t=t||Coax.languages.get(this.lang)))return e;const n=this.getCssPrefix(t),r=new RegExp(t.rules.map(e=>`(${e.pattern.source})`).join("|"),"g");return e.replace(r,(e,...r)=>{const i=r.findIndex(e=>void 0!==e);return-1!==i&&t.rules[i]?`<span class="ax-${n}-${t.rules[i].token}">${e}</span>`:e})}createLineWrap(e,t){let n=0;if(null==e&&null==t)n=this.highlightEl.children.length;else{n=(t||this.highlightEl.children.length)+e}return createEl("div",{"data-index":n},"<div></div>")}getLineToFill(e,t,n){n=n||Coax.languages.get(this.lang);let r=this.getHighLightString(t,n);e.innerHTML=r}async highlight(e){const t=Coax.languages.get(this.lang),n=this.highlightEl.children.length,r=e?e.split("\n"):[];if(this.updateName(t),!r.length)return!0;for(let[e,i]of r.entries()){if(!i.trim()&&this.hasAttribute("sanitized"))continue;const r=this.createLineWrap(e,n),a=r.lastElementChild;r.completed=!0,this.hasAttribute("speed")?(this.highlightEl.appendChild(r),await typeWriter(i,{speed:this.speed,onDuringType:(e,t)=>{a.innerHTML=t}}),this.getLineToFill(a,i,t)):(this.getLineToFill(a,i,t),this.highlightEl.appendChild(r))}return this.autoScrollCode(),!0}autoScrollCode(){this.autoScroll&&(this.codeBodyEl.scrollTop=this.codeBodyEl.scrollHeight)}injectThemeStyles(){const e=Coax.languages.get(this.lang);if(!e)return;let t=this.getCssPrefix(e),n=e.rules.map(e=>`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token}${e.light?","+e.light:""});}`).join("\n"),r="",i="";r+=':host([scheme="dark"]){',r+=e.rules.map(e=>"\n "+(e.light?`\n .ax-${t}-${e.token} {color: var(--ax-${t}-${e.token},${e.dark});}`:"")).join("\n"),r+="}",i="@media (prefers-color-scheme: dark){\n :host{\n ",i+=e.rules.map(e=>`\n ${e.light?`\n .ax-${t}-${e.token} { color: var(--ax-${t}-${e.token},${e.dark}); }`:""} `).join("\n"),i+="}",this.dynamicStylesEl.textContent=n+r+i,e?.themeStyles&&(this.themeStylesEl.textContent=e.themeStyles)}updateName(e){this.hasAttribute("unnamed")||(e?(this.alias=e.alias||this.lang,this.codeNameEl.innerHTML=this.alias):this.codeNameEl.innerHTML="Plain Text")}render(e=this.source){this._renderQueued||(this._renderQueued=!0,this.clear(),this.injectThemeStyles(),this.highlight(e),this._renderQueued=!1)}clear(){this.highlightEl.innerHTML=this.source=this.lineString=""}async replace(e){this.clear(),await this.highlight(e)}async append(e){this.source+=`\n${e}`,await this.highlight(e)}getLastLine(){const e=this.highlightEl.lastElementChild,t=!e||this.highlightEl.lastElementChild?.completed?this.createLineWrap():e;return{lineWrap:t,codeWrap:t.lastElementChild}}close(){const e=this.highlightEl.lastElementChild;e&&(e.completed=!0,this.lastLineString=this.lineString,this.getLineToFill(e?.lastElementChild,this.lineString),this.lineString="")}open(){const e=this.highlightEl.lastElementChild;e&&(e.completed=!1,(e?.lastElementChild).textContent=this.lineString=this.lastLineString)}stream(e,t=!1){const{lineWrap:n,codeWrap:r}=this.getLastLine();this.highlightEl.appendChild(n),this.source+=e,t||e.startsWith("\n")||e.endsWith("\n")?this.close():(r.innerHTML+=e,this.lineString+=e),this.autoScrollCode()}}const css=[{token:"comment",pattern:/\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"value",pattern:/(?:'|")(?:\\.|[^\\'"\b])*?(?:'|")/,light:"#032f62",dark:"#a5d6ff"},{token:"func",pattern:/[a-z-]+\(?=/,light:"#e36209",dark:"#ffa657"},{token:"property",pattern:/[a-z-]+(?=\s*:)/,light:"#005cc5",dark:"#79c0ff"},{token:"selector",pattern:/[.#a-z0-9, \n\t>:+()_-]+(?=\s*\{)/i,light:"#22863a",dark:"#7ee787"},{token:"unit",pattern:/(?<=\d)(px|em|rem|%|vh|vw|ms|s|deg)/,light:"#d73a49",dark:"#ff7b72"},{token:"number",pattern:/\b\d+(\.\d+)?\b/,light:"#005cc5",dark:"#79c0ff"},{token:"punct",pattern:/[{}();:]/,light:"#24292e",dark:"#c9d1d9"}],html=[{token:"comment",pattern:/&lt;!--[\s\S]*?--&gt;/,light:"#999999",dark:"#6e7681"},{token:"doctype",pattern:/&lt;!DOCTYPE[\s\S]*?&gt;/i,light:"#6a737d",dark:"#8b949e"},{token:"tag",pattern:/&lt;\/?[a-zA-Z0-9]+/,light:"#22863a",dark:"#7ee787"},{token:"attr",pattern:/[a-zA-Z-]+(?=\s*=\s*)/,light:"#6f42c1",dark:"#d2a8ff"},{token:"string",pattern:/(['"])(?:\\.|[^\\])*?\1/,light:"#032f62",dark:"#a5d6ff"},{token:"bracket",pattern:/\/?&gt;/,light:"#24292e",dark:"#c9d1d9"}],javascript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"keyword",pattern:/\b(async|await|break|case|catch|class|const|continue|default|delete|do|else|export|extends|finally|for|function|if|import|in|instanceof|new|return|super|switch|this|throw|try|typeof|var|while|with|yield|let|static)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(console|window|document|Math|JSON|true|false|null|undefined|Object|Array|Promise|Number|String|Boolean)\b/,light:"#e36209",dark:"#ffa657"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/[+\-*/%=<>!&|^~]+/,light:"#069598",dark:"#56b6c2"}],markdown=[{token:"comment",pattern:/<!--[\s\S]*?-->/,light:"#6a737d",dark:"#8b949e"},{token:"heading",pattern:/(^|\n)(#{1,6})\s*(.+)/,light:"#e36209",dark:"#ffa657"},{token:"bold",pattern:/\*\*([^*]+)\*\*|__([^_]+)__/g,light:"#d73a49",dark:"#ff7b72"},{token:"italic",pattern:/\*([^*]+)\*|_([^_]+)_/g,light:"#032f62",dark:"#a5d6ff"},{token:"link",pattern:/\[([^\]]+)\]\(([^)]+)\)/g,light:"#0288d1",dark:"#80c0ff"},{token:"inline-code",pattern:/`([^`]+)`/g,light:"#032f62",dark:"#98c379"},{token:"code-block",pattern:/```([^\n]+)\n([\s\S]*?)```/g,light:"#24292e",dark:"#c9d1d9"},{token:"list-item",pattern:/(^|\n)([-*])\s+(.+)/g,light:"#5c6e7c",dark:"#8b949e"},{token:"quote",pattern:/(^|\n)>[ \t]*(.+)/g,light:"#6f42c1",dark:"#d2a8ff"},{token:"image",pattern:/!\[([^\]]+)\]\(([^)]+)\)/g,light:"#d73a49",dark:"#ff7b72"},{token:"hr",pattern:/^(---|___|\*\*\*)\s*$/gm,light:"#24292e",dark:"#c9d1d9"},{token:"strikethrough",pattern:/~~([^~]+)~~/g,light:"#e36209",dark:"#ffa657"},{token:"table",pattern:/\|([^\|]+)\|([^\|]+)\|/g,light:"#5c6e7c",dark:"#8b949e"}],typescript=[{token:"comment",pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//,light:"#6a737d",dark:"#8b949e"},{token:"string",pattern:/(?:'|"|`)(?:\\.|[^\\'"\b])*?(?:'|"|`)/,light:"#032f62",dark:"#98c379"},{token:"decorator",pattern:/@[a-zA-Z_]\w*/,light:"#953800",dark:"#ffa657"},{token:"keyword",pattern:/\b(abstract|as|async|await|break|case|catch|class|const|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|package|private|protected|public|readonly|return|set|static|super|switch|this|throw|try|type|typeof|var|while|with|yield)\b/,light:"#d73a49",dark:"#ff7b72"},{token:"builtin",pattern:/\b(any|boolean|never|number|string|symbol|unknown|void|undefined|null|true|false|console|window|document)\b/,light:"#e36209",dark:"#ffa657"},{token:"type",pattern:/\b[A-Z]\w*\b/,light:"#005cc5",dark:"#79c0ff"},{token:"number",pattern:/\b(0x[\da-fA-F]+|0b[01]+|\d+(\.\d+)?)\b/,light:"#005cc5",dark:"#79c0ff"},{token:"func",pattern:/\b[a-zA-Z_]\w*(?=\s*\()/,light:"#6f42c1",dark:"#d2a8ff"},{token:"op",pattern:/(\?\.|![:\.]|[+\-*/%=<>!&|^~]+)/,light:"#089ba6",dark:"#79c0ff"}],COMMA=",",SPACE=" ",trim=(e,t="")=>{if("string"!=typeof e)return"";switch(t){case"start":return e.trimStart();case"end":return e.trimEnd();case"both":return e.trim();case"global":return e.replace(/[\s\r\n]+/g,"");default:return e.trim().replace(/[\s\r\n]+/g," ")}},parseClasses=e=>{let t,n=[];return Array.isArray(e)?n=e.filter(e=>e&&"string"==typeof e):(t=(e=trim(e)).includes(",")?",":" ",n=e.split(t)),n.map(e=>trim(e,"global")).filter(Boolean)},rtlStyle=(e="")=>`\n <style>\n :where([dir="rtl"]) .icax-${e},\n :where(:dir(rtl)) .icax-${e} {\n transform: scaleX(-1);\n transform-origin: center;\n }\n </style>\n`,wrap=(e,t,n=!1,r)=>{const i=r?.size||"1em",a=r?.color||"currentColor",o=r?.thickness||2,l=r?.classes?parseClasses(r.classes).join(" "):"",s=t.name.replace(/([A-Z])/g,"-$1").toLowerCase();return`<svg xmlns="http://www.w3.org/2000/svg" width="${i}" height="${i}" viewBox="0 0 24 24" fill="none" stroke="${a}"\n stroke-width="${o}" stroke-linecap="round" stroke-linejoin="round" class="${s} ${l}">\n ${n?rtlStyle(s.split("-")[1]):""}\n ${e}\n </svg>`},icaxCheck=e=>wrap('<polyline points="20 6 9 17 4 12"></polyline>',icaxCheck,!1,e),icaxCopy=e=>wrap('<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>',icaxCopy,!1,e),copy={name:"copy",icon:icaxCopy(),action:function(e){e.wrapEl.onclick=()=>{navigator.clipboard.writeText(this.source).then(()=>{e.iconEl.innerHTML=icaxCheck(),e.iconEl.toggleAttribute("disabled",!0),setTimeout(()=>{e.iconEl.removeAttribute("disabled"),e.iconEl.innerHTML=icaxCopy()},2e3)}).catch(e=>{})}}};export{Coax,copy,css,html,javascript,markdown,typescript};