@matechat/ng 17.1.0 → 17.2.0-alpha.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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <img alt="MateChat Logo" src="https://matechat.gitcode.com/logo.svg" width="180" style="max-width:100%;">
4
4
  </a>
5
5
  </p>
6
- <h1 align="center">MateChat/Angular</h1>
6
+ <h1 align="center">MateChat / Angular</h1>
7
7
  <p align="center">前端智能化场景解决方案UI库,轻松构建你的AI应用。已服务于华为内部多个应用智能化改造,并助力CodeArts、InsCode AI IDE等智能化助手搭建。</p>
8
8
 
9
9
  ![example](https://matechat.gitcode.com/example1.png)
@@ -25,11 +25,11 @@
25
25
  如果你还没有新建项目,可以使用 Angular CLI 首先初始化一个`angular`项目:
26
26
 
27
27
  ```bash
28
- npm install -g @angular/cli@latest
28
+ $ npm install -g @angular/cli@latest
29
29
 
30
- ng new matechat-demo
30
+ $ ng new matechat-demo
31
31
 
32
- npm i @matechat/ng
32
+ $ npm i @matechat/ng
33
33
  ```
34
34
 
35
35
  ### 2. 引入
@@ -80,6 +80,7 @@ export class AppComponent {}
80
80
  </div>
81
81
  ```
82
82
 
83
+
83
84
  ```ts
84
85
  import { Component } from '@angular/core';
85
86
  import { CommonModule } from '@angular/common';
@@ -133,7 +134,6 @@ export class App {
133
134
  margin-top: 8px;
134
135
  }
135
136
  ```
136
-
137
137
  ### 4. 主题化
138
138
 
139
139
  在`main.ts`中初始化主题
@@ -148,7 +148,6 @@ import { ThemeServiceInit, infinityTheme } from "devui-theme";
148
148
  ThemeServiceInit({ infinityTheme }, "infinityTheme");
149
149
  bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));
150
150
  ```
151
-
152
151
  ## 🧩 对接模型服务
153
152
 
154
153
  在搭建完成页面后,可以开始对接模型服务,如 `盘古大模型`、`ChatGPT` 等优秀大模型,在注册并生成对应模型的调用API_Key后,可以参考如下方法进行调用:
@@ -156,7 +155,7 @@ bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err))
156
155
  1. 通过 npm 安装 openai:
157
156
 
158
157
  ```bash
159
- npm install openai
158
+ $ npm install openai
160
159
  ```
161
160
 
162
161
  2. 使用OpenAI初始化并调用模型接口,如下为一段代码示例:
@@ -5,7 +5,7 @@ import { CommonModule } from '@angular/common';
5
5
  import { Subject, debounceTime } from 'rxjs';
6
6
  import * as i3 from '@angular/forms';
7
7
  import { FormsModule } from '@angular/forms';
8
- import { DiffDOM } from 'diff-dom';
8
+ import morphdom from 'morphdom';
9
9
  import markdownit from 'markdown-it';
10
10
  import { getDefaultWhiteList, getDefaultCSSWhiteList, filterXSS } from 'xss';
11
11
  import hljs from 'highlight.js';
@@ -923,7 +923,7 @@ class InputComponent extends BaseComponent {
923
923
  ngOnInit() {
924
924
  this.foundation = new InputFoundation(this.adapter);
925
925
  this.foundation.init();
926
- this.inputValue = this.value;
926
+ this.inputValue = this.value || '';
927
927
  }
928
928
  get adapter() {
929
929
  return {
@@ -1639,7 +1639,6 @@ class CodeBlockComponent extends BaseComponent {
1639
1639
  .pipe(debounceTime(300))
1640
1640
  .subscribe(() => this.copyCodeInternal());
1641
1641
  this.foundation = new CodeBlockFoundation(this.adapter);
1642
- this.diffDom = new DiffDOM();
1643
1642
  }
1644
1643
  get adapter() {
1645
1644
  return {
@@ -1653,8 +1652,7 @@ class CodeBlockComponent extends BaseComponent {
1653
1652
  const newElement = document.createElement('code');
1654
1653
  newElement.className = `hljs language-${language}`;
1655
1654
  newElement.innerHTML = highlightedCode;
1656
- const diff = this.diffDom.diff(this.codeElementRef.nativeElement, newElement);
1657
- this.diffDom.apply(this.codeElementRef.nativeElement, diff);
1655
+ morphdom(this.codeElementRef.nativeElement, newElement);
1658
1656
  }
1659
1657
  },
1660
1658
  };
@@ -1678,6 +1676,7 @@ class CodeBlockComponent extends BaseComponent {
1678
1676
  }
1679
1677
  }
1680
1678
  ngAfterViewInit() {
1679
+ this.updateHighlightedCode();
1681
1680
  if (this.isMermaid) {
1682
1681
  this.renderMermaid();
1683
1682
  }
@@ -1703,7 +1702,9 @@ class CodeBlockComponent extends BaseComponent {
1703
1702
  this.isMermaid = this.foundation.checkIsMermaid();
1704
1703
  }
1705
1704
  updateHighlightedCode() {
1706
- this.foundation.updateHighlightedCode();
1705
+ setTimeout(() => {
1706
+ this.foundation.updateHighlightedCode();
1707
+ });
1707
1708
  }
1708
1709
  zoomIn() {
1709
1710
  this.foundation.zoomIn();
@@ -2040,6 +2041,26 @@ const tokensToAst = (tokens) => {
2040
2041
  }
2041
2042
  return rootNode.children;
2042
2043
  };
2044
+ /**
2045
+ * 递归查找所有层级中 className 包含 code-block-wrapper 的 DIV 节点
2046
+ * @param {Array} vnodes - 待查找的 vnode 列表
2047
+ * @returns {Array} 符合条件的节点列表
2048
+ */
2049
+ function findCodeBlockWrappers(vnodes) {
2050
+ const result = [];
2051
+ // 遍历当前层级的 vnode
2052
+ vnodes.forEach((node) => {
2053
+ // 检查当前节点是否符合条件
2054
+ if (node.nodeName === 'DIV' && node.className?.includes('code-block-wrapper')) {
2055
+ result.push(node);
2056
+ }
2057
+ // 递归处理子节点(如果存在子节点且为数组)
2058
+ if (node.childNodes?.length) {
2059
+ result.push(...findCodeBlockWrappers(node.childNodes));
2060
+ }
2061
+ });
2062
+ return result;
2063
+ }
2043
2064
  // 声明一个utils静态默认导出
2044
2065
  var MdParserUtils = {
2045
2066
  isSelfClosingTag,
@@ -2047,7 +2068,8 @@ var MdParserUtils = {
2047
2068
  tokensToAst,
2048
2069
  genTreeNode,
2049
2070
  matchHtmlToken,
2050
- isValidTagName
2071
+ isValidTagName,
2072
+ findCodeBlockWrappers,
2051
2073
  };
2052
2074
 
2053
2075
  class MarkdownCardComponent extends BaseComponent {
@@ -2072,6 +2094,7 @@ class MarkdownCardComponent extends BaseComponent {
2072
2094
  // 组件缓存映射表,用于存储已创建的CodeBlockComponent实例
2073
2095
  this.codeBlockComponentsCache = new Map();
2074
2096
  this.afterMdtInit = new EventEmitter();
2097
+ this.mdRenderChange = new EventEmitter();
2075
2098
  this.typingStart = new EventEmitter();
2076
2099
  this.typingEvent = new EventEmitter();
2077
2100
  this.typingEnd = new EventEmitter();
@@ -2092,21 +2115,6 @@ class MarkdownCardComponent extends BaseComponent {
2092
2115
  });
2093
2116
  this.mdCardService = new MDCardService();
2094
2117
  this.foundation = new MarkdownCardFoundation(this.adapter);
2095
- // 初始化 diffDom 实例
2096
- this.diffDom = new DiffDOM({
2097
- // 配置filterOuterDiff钩子,识别code-block-wrapper元素并直接替换
2098
- filterOuterDiff: (t1, t2, diffs) => {
2099
- // 检查是否是class为code-block-wrapper的div元素
2100
- const isTargetElement = t2.nodeName === 'DIV' &&
2101
- t2.attributes &&
2102
- t2.attributes.class &&
2103
- t2.attributes.class.includes('code-block-wrapper');
2104
- if (isTargetElement) {
2105
- t1.innerDone = true;
2106
- t2.innerDone = true;
2107
- }
2108
- },
2109
- });
2110
2118
  }
2111
2119
  ngOnInit() {
2112
2120
  this.mdCardService.setMdPlugins(this.mdPlugins || [], this.mdt);
@@ -2132,28 +2140,35 @@ class MarkdownCardComponent extends BaseComponent {
2132
2140
  }
2133
2141
  ngOnChanges(changes) {
2134
2142
  if (changes['content']) {
2135
- if (!this.typing) {
2136
- this.typingIndex = this.content?.length || 0;
2137
- this.parseContent();
2138
- }
2139
- if (this.content.indexOf(changes['content']?.previousValue) === -1) {
2140
- this.typingIndex = 0;
2141
- }
2142
- // 使用setTimeout模拟Vue的nextTick行为
2143
- setTimeout(() => this.typewriterStart());
2143
+ this.contentChange(changes['content']);
2144
2144
  }
2145
- if (changes['customXssRules']) {
2145
+ if (changes['customXssRules'] && !changes['customXssRules'].firstChange) {
2146
2146
  this.mdCardService.setCustomXssRules(this.customXssRules || []);
2147
2147
  this.parseContent();
2148
2148
  }
2149
- if (changes['enableThink'] || changes['thinkOptions'] || changes['theme']) {
2149
+ if ((changes['enableThink'] && !changes['enableThink'].firstChange) ||
2150
+ (changes['thinkOptions'] && !changes['thinkOptions'].firstChange) ||
2151
+ (changes['theme'] && !changes['theme'].firstChange)) {
2150
2152
  this.parseContent();
2151
2153
  }
2152
- if (changes['mdPlugins']) {
2154
+ if (changes['mdPlugins'] && !changes['mdPlugins'].firstChange) {
2153
2155
  this.mdCardService.setMdPlugins(this.mdPlugins || [], this.mdt);
2154
2156
  this.parseContent();
2155
2157
  }
2156
2158
  }
2159
+ contentChange(change) {
2160
+ if (!this.typing) {
2161
+ this.typingIndex = this.content?.length || 0;
2162
+ this.parseContent();
2163
+ }
2164
+ else {
2165
+ if (this.content.indexOf(change.previousValue) === -1) {
2166
+ this.typingIndex = 0;
2167
+ }
2168
+ // 使用setTimeout模拟Vue的nextTick行为
2169
+ setTimeout(() => this.typewriterStart());
2170
+ }
2171
+ }
2157
2172
  parseContent() {
2158
2173
  this.foundation.parseContent();
2159
2174
  }
@@ -2168,10 +2183,7 @@ class MarkdownCardComponent extends BaseComponent {
2168
2183
  const container = this.markdownContainer.element.nativeElement;
2169
2184
  const parser = new DOMParser();
2170
2185
  const newContainerDiv = parser.parseFromString(`<div></div>`, 'text/html');
2171
- const codeBlockWrappers = vnodes.filter((node) => {
2172
- return (node.nodeName === 'DIV' &&
2173
- node.className?.includes('code-block-wrapper'));
2174
- });
2186
+ const codeBlockWrappers = this.parser.findCodeBlockWrappers(vnodes);
2175
2187
  vnodes.forEach((node) => {
2176
2188
  if (node &&
2177
2189
  (node.nodeType ||
@@ -2186,8 +2198,19 @@ class MarkdownCardComponent extends BaseComponent {
2186
2198
  }
2187
2199
  });
2188
2200
  let newContainerDivHTML = newContainerDiv.body?.firstChild?.outerHTML || '';
2189
- const patches = this.diffDom.diff(container, this.mdCardService.filterHtml(newContainerDivHTML));
2190
- this.diffDom.apply(container, patches);
2201
+ const filteredHTML = this.mdCardService.filterHtml(newContainerDivHTML);
2202
+ // 使用morphdom进行DOM更新
2203
+ const newElement = document.createElement('div');
2204
+ newElement.innerHTML = filteredHTML;
2205
+ morphdom(container, filteredHTML, {
2206
+ onBeforeElUpdated: (fromEl, toEl) => {
2207
+ // 检查是否是代码块元素
2208
+ if (fromEl.nodeName === 'DIV' && fromEl.classList.contains('code-block-wrapper')) {
2209
+ return false;
2210
+ }
2211
+ return true;
2212
+ }
2213
+ });
2191
2214
  // 将codeBlockWrappers中的每个div元素替换container中的对应key属性的元素
2192
2215
  codeBlockWrappers.forEach((newCodeBlock) => {
2193
2216
  if (newCodeBlock &&
@@ -2202,6 +2225,7 @@ class MarkdownCardComponent extends BaseComponent {
2202
2225
  }
2203
2226
  }
2204
2227
  });
2228
+ this.mdRenderChange.emit(newContainerDivHTML);
2205
2229
  }
2206
2230
  getEmptyCodeBlock(node) {
2207
2231
  const codeNode = document.createElement('div');
@@ -2430,7 +2454,7 @@ class MarkdownCardComponent extends BaseComponent {
2430
2454
  this.codeBlockComponentsCache.clear();
2431
2455
  }
2432
2456
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: MarkdownCardComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2433
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.10", type: MarkdownCardComponent, isStandalone: false, selector: "mc-markdown-card", inputs: { content: "content", typing: "typing", enableThink: "enableThink", typingOptions: "typingOptions", thinkOptions: "thinkOptions", mdOptions: "mdOptions", mdPlugins: "mdPlugins", customXssRules: "customXssRules", theme: "theme", enableMermaid: "enableMermaid", mermaidConfig: "mermaidConfig", actionsTemplate: "actionsTemplate", headerTemplate: "headerTemplate", contentTemplate: "contentTemplate" }, outputs: { afterMdtInit: "afterMdtInit", typingStart: "typingStart", typingEvent: "typingEvent", typingEnd: "typingEnd" }, viewQueries: [{ propertyName: "markdownContainer", first: true, predicate: ["markdownContainer"], descendants: true, read: ViewContainerRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"mc-markdown-render\" [ngClass]=\"theme === 'dark' ? 'mc-markdown-render-dark' : 'mc-markdown-render-light'\">\n <div #markdownContainer></div>\n</div>\n<ng-content></ng-content>", styles: [".mc-markdown-render ::ng-deep .h1,.mc-markdown-render ::ng-deep .h2,.mc-markdown-render ::ng-deep .h3,.mc-markdown-render ::ng-deep .h4,.mc-markdown-render ::ng-deep .h5,.mc-markdown-render ::ng-deep .h6,.mc-markdown-render ::ng-deep h1,.mc-markdown-render ::ng-deep h2,.mc-markdown-render ::ng-deep h3,.mc-markdown-render ::ng-deep h4,.mc-markdown-render ::ng-deep h5,.mc-markdown-render ::ng-deep h6{line-height:1.1;margin:16px 0 12px}.mc-markdown-render ::ng-deep .h1:first-child,.mc-markdown-render ::ng-deep .h2:first-child,.mc-markdown-render ::ng-deep .h3:first-child,.mc-markdown-render ::ng-deep .h4:first-child,.mc-markdown-render ::ng-deep .h5:first-child,.mc-markdown-render ::ng-deep .h6:first-child,.mc-markdown-render ::ng-deep h1:first-child,.mc-markdown-render ::ng-deep h2:first-child,.mc-markdown-render ::ng-deep h3:first-child,.mc-markdown-render ::ng-deep h4:first-child,.mc-markdown-render ::ng-deep h5:first-child,.mc-markdown-render ::ng-deep h6:first-child{margin-top:0}.mc-markdown-render ::ng-deep h1{font-size:32px;line-height:40px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h3{line-height:28px;font-size:20px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep caption{border:1px dashed var(--devui-line, #d7d8da);border-bottom:0;padding:3px;text-align:center}.mc-markdown-render ::ng-deep p{overflow-wrap:break-word;margin:0;padding:0;line-height:24px}.mc-markdown-render ::ng-deep p:last-child{margin:0}.mc-markdown-render ::ng-deep ul,.mc-markdown-render ::ng-deep ol{margin:0;padding:0;padding-inline-start:1.75em}.mc-markdown-render ::ng-deep ul>li,.mc-markdown-render ::ng-deep ol>li{line-height:21px}.mc-markdown-render ::ng-deep ul{list-style-type:disc}.mc-markdown-render ::ng-deep ul li::marker{font-size:20px}.mc-markdown-render ::ng-deep ol{list-style-type:decimal}.mc-markdown-render ::ng-deep table{margin-bottom:10px;border-collapse:collapse;display:table}.mc-markdown-render ::ng-deep td,.mc-markdown-render ::ng-deep th{padding:5px 10px;border:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-base-bg, #ffffff)}.mc-markdown-render ::ng-deep th{border-top:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-global-bg, #f6f6f8)}.mc-markdown-render ::ng-deep td p{margin:0;padding:0}.mc-markdown-render ::ng-deep blockquote{padding:0 8px;margin:0;color:var(--devui-text-weak, #575d6c);border-left:5px solid var(--devui-dividing-line, #f2f2f3)}.mc-markdown-render ::ng-deep a{color:var(--devui-link, #526ecc);text-decoration:none;cursor:pointer}.mc-markdown-render ::ng-deep a:hover{color:var(--devui-link-active, #526ecc)}.mc-markdown-render ::ng-deep img{max-width:100%}.mc-markdown-render{font-size:var(--devui-font-size, 14px);overflow-x:auto}.mc-markdown-render.mc-markdown-render-dark{color:#ced1db}.mc-markdown-render.mc-markdown-render-light{color:#252b3a}::ng-deep .mc-think-block{color:var(--devui-aide-text, #71757f);border-left:1px solid var(--devui-line, #d7d8da);padding-left:8px;margin-bottom:1rem}::ng-deep .mc-typewriter-color{background-image:-webkit-linear-gradient(left,#191919,#5588f0,#e171ee,#f2c55c);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-gradient{background:linear-gradient(to right,var(--devui-text, #252b3a),var(--devui-base-bg, #ffffff));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-cursor{font-weight:900;animation:typewriter .8s linear 0s infinite}@keyframes typewriter{0%{opacity:1}50%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
2457
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.10", type: MarkdownCardComponent, isStandalone: false, selector: "mc-markdown-card", inputs: { content: "content", typing: "typing", enableThink: "enableThink", typingOptions: "typingOptions", thinkOptions: "thinkOptions", mdOptions: "mdOptions", mdPlugins: "mdPlugins", customXssRules: "customXssRules", theme: "theme", enableMermaid: "enableMermaid", mermaidConfig: "mermaidConfig", actionsTemplate: "actionsTemplate", headerTemplate: "headerTemplate", contentTemplate: "contentTemplate" }, outputs: { afterMdtInit: "afterMdtInit", mdRenderChange: "mdRenderChange", typingStart: "typingStart", typingEvent: "typingEvent", typingEnd: "typingEnd" }, viewQueries: [{ propertyName: "markdownContainer", first: true, predicate: ["markdownContainer"], descendants: true, read: ViewContainerRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"mc-markdown-render\" [ngClass]=\"theme === 'dark' ? 'mc-markdown-render-dark' : 'mc-markdown-render-light'\">\n <div #markdownContainer></div>\n</div>\n<ng-content></ng-content>", styles: [".mc-markdown-render ::ng-deep .h1,.mc-markdown-render ::ng-deep .h2,.mc-markdown-render ::ng-deep .h3,.mc-markdown-render ::ng-deep .h4,.mc-markdown-render ::ng-deep .h5,.mc-markdown-render ::ng-deep .h6,.mc-markdown-render ::ng-deep h1,.mc-markdown-render ::ng-deep h2,.mc-markdown-render ::ng-deep h3,.mc-markdown-render ::ng-deep h4,.mc-markdown-render ::ng-deep h5,.mc-markdown-render ::ng-deep h6{line-height:1.1;margin:16px 0 12px}.mc-markdown-render ::ng-deep .h1:first-child,.mc-markdown-render ::ng-deep .h2:first-child,.mc-markdown-render ::ng-deep .h3:first-child,.mc-markdown-render ::ng-deep .h4:first-child,.mc-markdown-render ::ng-deep .h5:first-child,.mc-markdown-render ::ng-deep .h6:first-child,.mc-markdown-render ::ng-deep h1:first-child,.mc-markdown-render ::ng-deep h2:first-child,.mc-markdown-render ::ng-deep h3:first-child,.mc-markdown-render ::ng-deep h4:first-child,.mc-markdown-render ::ng-deep h5:first-child,.mc-markdown-render ::ng-deep h6:first-child{margin-top:0}.mc-markdown-render ::ng-deep h1{font-size:32px;line-height:40px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep h3{line-height:28px;font-size:20px;overflow-wrap:break-word}.mc-markdown-render ::ng-deep caption{border:1px dashed var(--devui-line, #d7d8da);border-bottom:0;padding:3px;text-align:center}.mc-markdown-render ::ng-deep p{overflow-wrap:break-word;margin:0;padding:0;line-height:24px}.mc-markdown-render ::ng-deep p:last-child{margin:0}.mc-markdown-render ::ng-deep ul,.mc-markdown-render ::ng-deep ol{margin:0;padding:0;padding-inline-start:1.75em}.mc-markdown-render ::ng-deep ul>li,.mc-markdown-render ::ng-deep ol>li{line-height:21px}.mc-markdown-render ::ng-deep ul{list-style-type:disc}.mc-markdown-render ::ng-deep ul li::marker{font-size:20px}.mc-markdown-render ::ng-deep ol{list-style-type:decimal}.mc-markdown-render ::ng-deep table{margin-bottom:10px;border-collapse:collapse;display:table}.mc-markdown-render ::ng-deep td,.mc-markdown-render ::ng-deep th{padding:5px 10px;border:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-base-bg, #ffffff)}.mc-markdown-render ::ng-deep th{border-top:1px solid var(--devui-dividing-line, #f2f2f3);background-color:var(--devui-global-bg, #f6f6f8)}.mc-markdown-render ::ng-deep td p{margin:0;padding:0}.mc-markdown-render ::ng-deep blockquote{padding:0 8px;margin:0;color:var(--devui-text-weak, #575d6c);border-left:5px solid var(--devui-dividing-line, #f2f2f3)}.mc-markdown-render ::ng-deep a{color:var(--devui-link, #526ecc);text-decoration:none;cursor:pointer}.mc-markdown-render ::ng-deep a:hover{color:var(--devui-link-active, #526ecc)}.mc-markdown-render ::ng-deep img{max-width:100%}.mc-markdown-render{font-size:var(--devui-font-size, 14px);overflow-x:auto}.mc-markdown-render.mc-markdown-render-dark{color:#ced1db}.mc-markdown-render.mc-markdown-render-light{color:#252b3a}::ng-deep .mc-think-block{color:var(--devui-aide-text, #71757f);border-left:1px solid var(--devui-line, #d7d8da);padding-left:8px;margin-bottom:1rem}::ng-deep .mc-typewriter-color{background-image:-webkit-linear-gradient(left,#191919,#5588f0,#e171ee,#f2c55c);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-gradient{background:linear-gradient(to right,var(--devui-text, #252b3a),var(--devui-base-bg, #ffffff));background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}::ng-deep .mc-typewriter-cursor{font-weight:900;animation:typewriter .8s linear 0s infinite}@keyframes typewriter{0%{opacity:1}50%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
2434
2458
  }
2435
2459
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: MarkdownCardComponent, decorators: [{
2436
2460
  type: Component,
@@ -2465,6 +2489,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImpo
2465
2489
  type: Input
2466
2490
  }], afterMdtInit: [{
2467
2491
  type: Output
2492
+ }], mdRenderChange: [{
2493
+ type: Output
2468
2494
  }], typingStart: [{
2469
2495
  type: Output
2470
2496
  }], typingEvent: [{