@iyulab/chat-components 0.12.3 → 0.14.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.
Files changed (73) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +1 -0
  3. package/dist/_virtual/{_@oxc-project_runtime@0.150.0 → _@oxc-project_runtime@0.151.0}/helpers/esm/decorate.js +1 -1
  4. package/dist/_virtual/{_@oxc-project_runtime@0.150.0 → _@oxc-project_runtime@0.151.0}/helpers/esm/decorateMetadata.js +1 -1
  5. package/dist/_virtual/_glob-assets_raw/alert-triangle-fill.svg.4cfc4305.js +4 -0
  6. package/dist/_virtual/_glob-assets_raw/arrows-sort.svg.dda43a85.js +4 -0
  7. package/dist/_virtual/_glob-assets_raw/code.svg.c69bc144.js +4 -0
  8. package/dist/_virtual/_glob-assets_raw/download.svg.bce82177.js +4 -0
  9. package/dist/_virtual/_glob-assets_raw/external-link.svg.a9f7f02d.js +4 -0
  10. package/dist/_virtual/_glob-assets_raw/file-code.svg.0e706f93.js +4 -0
  11. package/dist/_virtual/_glob-assets_raw/file-music.svg.b9970203.js +4 -0
  12. package/dist/_virtual/_glob-assets_raw/file-spreadsheet.svg.8c03bdfa.js +4 -0
  13. package/dist/_virtual/_glob-assets_raw/file-text.svg.85bdd923.js +4 -0
  14. package/dist/_virtual/_glob-assets_raw/file-type-pdf.svg.bc12db6d.js +4 -0
  15. package/dist/_virtual/_glob-assets_raw/file-zip.svg.76dde660.js +4 -0
  16. package/dist/_virtual/_glob-assets_raw/file.svg.28f5d6f1.js +4 -0
  17. package/dist/_virtual/_glob-assets_raw/photo.svg.cc273cc1.js +4 -0
  18. package/dist/_virtual/_glob-assets_raw/player-stop-fill.svg.5378b752.js +4 -0
  19. package/dist/_virtual/_glob-assets_raw/send.svg.02326253.js +4 -0
  20. package/dist/_virtual/_glob-assets_raw/sort-ascending-letters.svg.14a3df67.js +4 -0
  21. package/dist/_virtual/_glob-assets_raw/sort-descending-letters.svg.3e03647c.js +4 -0
  22. package/dist/_virtual/_glob-assets_raw/video.svg.c183f03c.js +4 -0
  23. package/dist/_virtual/_glob-assets_raw/world.svg.cd9903c8.js +4 -0
  24. package/dist/components/UDataElement.d.ts +2 -0
  25. package/dist/components/UDataElement.js +9 -1
  26. package/dist/components/blocks/UCodeBlock.js +3 -2
  27. package/dist/components/blocks/UElementBlock.d.ts +12 -16
  28. package/dist/components/blocks/UElementBlock.js +25 -33
  29. package/dist/components/blocks/UFileBlock.d.ts +3 -2
  30. package/dist/components/blocks/UFileBlock.js +12 -10
  31. package/dist/components/blocks/UFileBlock.styles.js +1 -1
  32. package/dist/components/blocks/UMarkedBlock.d.ts +8 -1
  33. package/dist/components/blocks/UMarkedBlock.js +25 -7
  34. package/dist/components/blocks/UMarkedBlock.styles.js +10 -0
  35. package/dist/components/blocks/URefBlock.js +2 -2
  36. package/dist/components/blocks/UTableBlock.js +3 -2
  37. package/dist/components/blocks/UTextBlock.js +2 -2
  38. package/dist/components/message/UMessage.js +2 -2
  39. package/dist/components/prompt/UPrompt.js +5 -3
  40. package/dist/components/references/URefCard.d.ts +21 -2
  41. package/dist/components/references/URefCard.js +33 -19
  42. package/dist/components/references/URefCardGroup.js +2 -2
  43. package/dist/components/references/URefTag.js +5 -3
  44. package/dist/components-extra/UChartBlock.js +6 -2
  45. package/dist/components-extra/UImagesBlock.d.ts +6 -1
  46. package/dist/components-extra/UImagesBlock.js +30 -7
  47. package/dist/components-extra/UImagesBlock.styles.js +20 -1
  48. package/dist/components-extra/UMapBlock.js +5 -2
  49. package/dist/components-extra/UVideoBlock.js +5 -2
  50. package/dist/extra.d.ts +7 -1
  51. package/dist/extra.js +12 -6
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.js +6 -3
  54. package/dist/node_modules/katex/dist/katex.js +2 -2
  55. package/dist/utilities/ElementRegistry.d.ts +13 -0
  56. package/dist/utilities/ElementRegistry.js +33 -0
  57. package/dist/utilities/PromptBuilder.d.ts +3 -0
  58. package/dist/utilities/PromptBuilder.js +5 -0
  59. package/dist/utilities/icons.js +52 -0
  60. package/dist/utilities/imageSources.d.ts +25 -0
  61. package/dist/utilities/imageSources.js +61 -0
  62. package/dist/utilities/messages.d.ts +1 -1
  63. package/dist/utilities/messages.js +6 -2
  64. package/dist/utilities/sanitizers.d.ts +10 -1
  65. package/dist/utilities/sanitizers.js +16 -5
  66. package/package.json +4 -2
  67. package/skills/iyulab-chat-components/SKILL.md +1 -0
  68. package/skills/iyulab-chat-components/references/components/element-block.md +5 -6
  69. package/skills/iyulab-chat-components/references/components/images-block.md +1 -0
  70. package/skills/iyulab-chat-components/references/components/marked-block.md +12 -0
  71. package/skills/iyulab-chat-components/references/components/ref-card.md +20 -1
  72. package/skills/iyulab-chat-components/references/extra-system.md +4 -4
  73. package/skills/iyulab-chat-components/references/security.md +23 -0
@@ -1,14 +1,16 @@
1
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
3
  import "./UCodeBlock.js";
4
4
  import { escapeHtmlAttr, escapeHtmlHref, escapeHtmlText, stripZeroWidth } from "../../utilities/sanitizers.js";
5
5
  import { HtmlBuilder } from "../../utilities/HtmlBuilder.js";
6
6
  import { UElementBlock } from "./UElementBlock.js";
7
+ import { messages } from "../../utilities/messages.js";
7
8
  import { markedKatex } from "../../utilities/markedKatex.js";
8
9
  import "../references/URefTag.js";
9
10
  import { URefCard } from "../references/URefCard.js";
10
11
  import "../references/URefCardGroup.js";
11
12
  import { UTableBlock } from "./UTableBlock.js";
13
+ import { resolveImageSource } from "../../utilities/imageSources.js";
12
14
  import { HtmlPlaceholder, stripRefPlaceholders } from "../../utilities/HtmlPlaceholder.js";
13
15
  import { styles } from "./UMarkedBlock.styles.js";
14
16
  import { nothing } from "lit";
@@ -40,9 +42,15 @@ var UMarkedBlock = class UMarkedBlock extends UElement {
40
42
  static {
41
43
  this.styles = [super.styles, styles];
42
44
  }
45
+ connectedCallback() {
46
+ super.connectedCallback();
47
+ this.requestUpdate();
48
+ }
43
49
  disconnectedCallback() {
44
50
  clearTimeout(this.queuedTimer);
45
51
  clearTimeout(this.streamingTimer);
52
+ this.queued = false;
53
+ this.streaming = false;
46
54
  super.disconnectedCallback();
47
55
  }
48
56
  shouldUpdate(_changedProperties) {
@@ -79,7 +87,7 @@ var UMarkedBlock = class UMarkedBlock extends UElement {
79
87
  */
80
88
  renderCode(token) {
81
89
  const lang = token.lang ?? "plaintext";
82
- if (lang === "block-json") return UElementBlock.buildHTML(token.text, { loading: this.streaming });
90
+ if (lang === "block-json") return UElementBlock.buildHTML(stripRefPlaceholders(token.text), { loading: this.streaming });
83
91
  const safeText = escapeHtmlText(this.removeRefs(token.text));
84
92
  return HtmlBuilder.build("u-code-block", { lang }, safeText);
85
93
  }
@@ -93,12 +101,13 @@ var UMarkedBlock = class UMarkedBlock extends UElement {
93
101
  * 반드시 `this.parser.defaults`(우리 렌더러가 병합된 설정)를 함께 넘긴다.
94
102
  */
95
103
  renderTable(token) {
104
+ const cellHtml = (cell) => this.placeholder.restore(cell.tokens ? Parser.parseInline(cell.tokens, this.parser.defaults) : cell.text);
96
105
  const headers = token.header.map((h) => ({
97
- text: h.tokens ? Parser.parseInline(h.tokens, this.parser.defaults) : h.text,
106
+ text: cellHtml(h),
98
107
  align: h.align
99
108
  }));
100
109
  const rows = token.rows.map((row) => row.map((cell) => ({
101
- text: cell.tokens ? Parser.parseInline(cell.tokens, this.parser.defaults) : cell.text,
110
+ text: cellHtml(cell),
102
111
  align: cell.align
103
112
  })));
104
113
  return UTableBlock.buildHTML({
@@ -126,9 +135,18 @@ var UMarkedBlock = class UMarkedBlock extends UElement {
126
135
  out += `>${text}</a>`;
127
136
  return out;
128
137
  }
129
- /** 마크다운 이미지의 src도 `renderLink`와 동일하게 protocol을 검사합니다. */
138
+ /**
139
+ * 마크다운 이미지의 src도 `renderLink`와 동일하게 protocol을 검사하고, 이미지 출처 정책
140
+ * (`setAllowedImagePrefixes`)에 대어 봅니다. 막힌 이미지는 `<img>` 를 만들지 않는다 —
141
+ * 요청 자체가 반출 경로이므로 대체 텍스트만 그린다.
142
+ */
130
143
  renderImage(token) {
131
- let out = `<img src="${escapeHtmlHref(token.href)}" alt="${escapeHtmlAttr(token.text)}"`;
144
+ const src = resolveImageSource(token.href);
145
+ if (src === null) {
146
+ const label = token.text ? messages.text("imageBlockedNamed", { name: token.text }) : messages.text("imageBlocked");
147
+ return `<span class="image-blocked" part="image-blocked">${escapeHtmlText(label)}</span>`;
148
+ }
149
+ let out = `<img src="${escapeHtmlAttr(src)}" alt="${escapeHtmlAttr(token.text)}"`;
132
150
  if (token.title) out += ` title="${escapeHtmlAttr(token.title)}"`;
133
151
  out += `>`;
134
152
  return out;
@@ -327,6 +327,16 @@ var styles = css`
327
327
  background-color: transparent;
328
328
  }
329
329
 
330
+ /* 이미지 출처 정책이 막은 자리 — 요청 없이 대체 텍스트만 보인다. */
331
+ .image-blocked {
332
+ display: inline-block;
333
+ padding: 0 var(--base-size-4);
334
+ border: 1px dashed var(--borderColor-default);
335
+ border-radius: 6px;
336
+ color: var(--fgColor-muted);
337
+ font-size: 0.875em;
338
+ }
339
+
330
340
  .emoji {
331
341
  max-width: none;
332
342
  vertical-align: text-top;
@@ -1,5 +1,5 @@
1
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
3
  import "../references/URefCard.js";
4
4
  import { styles } from "./URefBlock.styles.js";
5
5
  import { html } from "lit";
@@ -1,5 +1,6 @@
1
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import "../../utilities/icons.js";
2
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
4
  import { UDataElement } from "../UDataElement.js";
4
5
  import { messages } from "../../utilities/messages.js";
5
6
  import { styles } from "./UTableBlock.styles.js";
@@ -1,5 +1,5 @@
1
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
3
  import { styles } from "./UTextBlock.styles.js";
4
4
  import { html } from "lit";
5
5
  import { customElement, property, query } from "lit/decorators.js";
@@ -1,5 +1,5 @@
1
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
3
  import { styles } from "./UMessage.styles.js";
4
4
  import { html } from "lit";
5
5
  import { customElement, property } from "lit/decorators.js";
@@ -1,5 +1,6 @@
1
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import "../../utilities/icons.js";
2
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
4
  import { messages } from "../../utilities/messages.js";
4
5
  import "../blocks/UFileBlock.js";
5
6
  import { styles } from "./UPrompt.styles.js";
@@ -9,6 +10,7 @@ import "@iyulab/components/dist/components/icon/UIcon.js";
9
10
  import { UElement } from "@iyulab/components/dist/components/UElement.js";
10
11
  import "@iyulab/components/dist/components/button/UButton.js";
11
12
  import { repeat } from "lit/directives/repeat.js";
13
+ import { isImeComposing } from "@iyulab/components/dist/utilities/keyboard.js";
12
14
  //#region src/components/prompt/UPrompt.ts
13
15
  var UPrompt = class UPrompt extends UElement {
14
16
  constructor(..._args) {
@@ -115,7 +117,7 @@ var UPrompt = class UPrompt extends UElement {
115
117
  this.value = target.value;
116
118
  }
117
119
  handleTextBlockKeydown(e) {
118
- if (e.key === "Enter" && !e.shiftKey) {
120
+ if (e.key === "Enter" && !e.shiftKey && !isImeComposing(e)) {
119
121
  e.preventDefault();
120
122
  this.submit();
121
123
  }
@@ -1,10 +1,27 @@
1
1
  import { UDataElement } from '../UDataElement.js';
2
+ /**
3
+ * 웹 참조 카드의 파비콘 이미지 URL 을 정한다. `undefined` 를 돌려주면 파비콘 없이 그린다.
4
+ * @param url 카드의 `url`
5
+ */
6
+ export type FaviconResolver = (url: string) => string | undefined;
7
+ /**
8
+ * 구글 공개 파비콘 서비스를 쓰는 리졸버(opt-in). 카드마다 사이트의 호스트 이름을 구글에 보낸다 —
9
+ * 공용 인터넷에 닿지 않는 망에서는 쓰지 말 것.
10
+ *
11
+ * @example URefCard.defaultFaviconUrl = googleFaviconUrl;
12
+ */
13
+ export declare const googleFaviconUrl: FaviconResolver;
2
14
  /**
3
15
  * 참조 소스를 카드 형태로 표시하는 공통 컴포넌트입니다.
4
16
  * Web과 Document 타입 모두 지원합니다.
5
17
  */
6
18
  export declare class URefCard extends UDataElement {
7
19
  static styles: import('lit').CSSResultGroup[];
20
+ /**
21
+ * 자기 `faviconUrl` 이 없는 모든 카드가 쓰는 리졸버. 기본값 `undefined` 는 파비콘을 요청하지 않는다 —
22
+ * 카드가 밖으로 나가는 요청을 스스로 만들지 않는다. 카드가 그려지기 전에 정할 것.
23
+ */
24
+ static defaultFaviconUrl?: FaviconResolver;
8
25
  /** 카드 타입 (web 또는 document) */
9
26
  type: 'web' | 'document';
10
27
  /** 외부 링크 URL */
@@ -15,6 +32,8 @@ export declare class URefCard extends UDataElement {
15
32
  snippet?: string;
16
33
  /** 태그 목록 */
17
34
  tags?: string[];
35
+ /** 이 카드의 파비콘 리졸버 — `URefCard.defaultFaviconUrl` 보다 우선한다. */
36
+ faviconUrl?: FaviconResolver;
18
37
  render(): import('lit-html').TemplateResult<1>;
19
38
  /**
20
39
  * script-payload(UMarkedBlock 툴팁)와 property 바인딩(URefBlock) 두 사용
@@ -24,8 +43,8 @@ export declare class URefCard extends UDataElement {
24
43
  protected load(data?: object): Promise<void>;
25
44
  /** 링크 클릭 핸들러 */
26
45
  private handleAnchorClick;
27
- /** URL에서 Google의 파비콘 URL을 반환합니다. */
28
- private getFaviconUrl;
46
+ /** 리졸버가 URL 을 돌려줄 때만 파비콘을 그린다(장식 — 제목이 이름을 나른다). */
47
+ private renderFavicon;
29
48
  /** URL에서 도메인 사이트 주소를 반환합니다. */
30
49
  private getDomainName;
31
50
  }
@@ -1,14 +1,33 @@
1
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import "../../utilities/icons.js";
2
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
4
+ import { sanitizeHref } from "../../utilities/sanitizers.js";
3
5
  import { UDataElement } from "../UDataElement.js";
4
6
  import { styles } from "./URefCard.styles.js";
5
- import { html } from "lit";
7
+ import { html, nothing } from "lit";
6
8
  import { customElement, property } from "lit/decorators.js";
7
9
  import "@iyulab/components/dist/components/icon/UIcon.js";
8
10
  import { ifDefined } from "lit/directives/if-defined.js";
9
11
  import { arrayAttrConverter } from "@iyulab/components/dist/utilities/converters.js";
10
12
  //#region src/components/references/URefCard.ts
13
+ var _URefCard;
14
+ /**
15
+ * 구글 공개 파비콘 서비스를 쓰는 리졸버(opt-in). 카드마다 사이트의 호스트 이름을 구글에 보낸다 —
16
+ * 공용 인터넷에 닿지 않는 망에서는 쓰지 말 것.
17
+ *
18
+ * @example URefCard.defaultFaviconUrl = googleFaviconUrl;
19
+ */
20
+ var googleFaviconUrl = (url) => {
21
+ try {
22
+ return `https://www.google.com/s2/favicons?sz=64&domain=${encodeURIComponent(new URL(url).hostname)}`;
23
+ } catch {
24
+ return;
25
+ }
26
+ };
11
27
  var URefCard = class URefCard extends UDataElement {
28
+ static {
29
+ _URefCard = this;
30
+ }
12
31
  constructor(..._args) {
13
32
  super(..._args);
14
33
  this.type = "web";
@@ -19,14 +38,10 @@ var URefCard = class URefCard extends UDataElement {
19
38
  }
20
39
  render() {
21
40
  return html`
22
- <a href="${ifDefined(this.url)}" target="_blank" rel="noopener noreferrer"
41
+ <a href="${ifDefined(this.url ? sanitizeHref(this.url) : void 0)}" target="_blank" rel="noopener noreferrer"
23
42
  @click=${this.handleAnchorClick}>
24
43
  <div class="header">
25
- <img class="favicon"
26
- src="${this.getFaviconUrl(this.url)}"
27
- alt=""
28
- aria-hidden="true"
29
- />
44
+ ${this.renderFavicon()}
30
45
  <div class="title">
31
46
  ${this.title || this.getDomainName(this.url)}
32
47
  </div>
@@ -68,14 +83,12 @@ var URefCard = class URefCard extends UDataElement {
68
83
  e.stopPropagation();
69
84
  }
70
85
  }
71
- /** URL에서 Google의 파비콘 URL을 반환합니다. */
72
- getFaviconUrl(url) {
73
- if (!url) return `/favicon.ico`;
74
- try {
75
- return `https://www.google.com/s2/favicons?sz=64&domain=${new URL(url).hostname}`;
76
- } catch {
77
- return `/favicon.ico`;
78
- }
86
+ /** 리졸버가 URL 을 돌려줄 때만 파비콘을 그린다(장식 — 제목이 이름을 나른다). */
87
+ renderFavicon() {
88
+ const resolve = this.faviconUrl ?? _URefCard.defaultFaviconUrl;
89
+ const src = this.url && resolve ? resolve(this.url) : void 0;
90
+ if (!src) return nothing;
91
+ return html`<img class="favicon" src=${src} alt="" aria-hidden="true" />`;
79
92
  }
80
93
  /** URL에서 도메인 사이트 주소를 반환합니다. */
81
94
  getDomainName(url) {
@@ -98,6 +111,7 @@ __decorate([property({
98
111
  type: Array,
99
112
  converter: arrayAttrConverter((v) => v)
100
113
  }), __decorateMetadata("design:type", Array)], URefCard.prototype, "tags", void 0);
101
- URefCard = __decorate([customElement("u-ref-card")], URefCard);
114
+ __decorate([property({ attribute: false }), __decorateMetadata("design:type", Object)], URefCard.prototype, "faviconUrl", void 0);
115
+ URefCard = _URefCard = __decorate([customElement("u-ref-card")], URefCard);
102
116
  //#endregion
103
- export { URefCard };
117
+ export { URefCard, googleFaviconUrl };
@@ -1,5 +1,5 @@
1
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
3
  import { messages } from "../../utilities/messages.js";
4
4
  import { URefCard } from "./URefCard.js";
5
5
  import { styles } from "./URefCardGroup.styles.js";
@@ -1,5 +1,7 @@
1
- import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import "../../utilities/icons.js";
2
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
4
+ import { sanitizeHref } from "../../utilities/sanitizers.js";
3
5
  import { styles } from "./URefTag.styles.js";
4
6
  import { html } from "lit";
5
7
  import { customElement, property } from "lit/decorators.js";
@@ -14,7 +16,7 @@ var URefTag = class URefTag extends UElement {
14
16
  }
15
17
  render() {
16
18
  return html`
17
- <a href="${ifDefined(this.href)}" target="_blank" rel="noopener noreferrer"
19
+ <a href="${ifDefined(this.href ? sanitizeHref(this.href) : void 0)}" target="_blank" rel="noopener noreferrer"
18
20
  @click=${this.handleAnchorClick}>
19
21
  <slot></slot>
20
22
  </a>
@@ -1,7 +1,10 @@
1
- import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import "../utilities/icons.js";
2
+ import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
4
+ import { registerElementBlock } from "../utilities/ElementRegistry.js";
3
5
  import { messages } from "../utilities/messages.js";
4
6
  import { styles } from "./UChartBlock.styles.js";
7
+ import schema from "./UChartBlock.schema.js";
5
8
  import { html, nothing } from "lit";
6
9
  import { customElement, property, query, state } from "lit/decorators.js";
7
10
  import "@iyulab/components/dist/components/icon/UIcon.js";
@@ -9,6 +12,7 @@ import { UElement } from "@iyulab/components/dist/components/UElement.js";
9
12
  import "@iyulab/components/dist/components/button/UButton.js";
10
13
  import { Chart } from "chart.js/auto";
11
14
  //#region src/components-extra/UChartBlock.ts
15
+ registerElementBlock(schema);
12
16
  var UChartBlock = class UChartBlock extends UElement {
13
17
  constructor(..._args) {
14
18
  super(..._args);
@@ -1,4 +1,4 @@
1
- import { nothing } from 'lit';
1
+ import { nothing, PropertyValues } from 'lit';
2
2
  import { UElement } from '@iyulab/components/dist/components/UElement.js';
3
3
  export interface ImageSlide {
4
4
  src: string;
@@ -16,7 +16,12 @@ export declare class UImagesBlock extends UElement {
16
16
  private index;
17
17
  connectedCallback(): void;
18
18
  disconnectedCallback(): void;
19
+ /** 열린 라이트박스는 층이다 — Escape 는 components 의 층 스택이 «가장 나중에 연 층 하나» 에만 준다. */
20
+ protected updated(changed: PropertyValues): void;
19
21
  render(): typeof nothing | import('lit-html').TemplateResult<1>;
22
+ /** 출처 정책(`setAllowedImagePrefixes`)이 막은 이미지 자리의 문구. */
23
+ private blockedLabel;
24
+ private renderLightboxImage;
20
25
  private renderLightbox;
21
26
  open: (i: number) => void;
22
27
  close: () => void;
@@ -1,14 +1,19 @@
1
- import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
+ import __decorate from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
+ import { registerElementBlock } from "../utilities/ElementRegistry.js";
3
4
  import { messages } from "../utilities/messages.js";
5
+ import { resolveImageSource } from "../utilities/imageSources.js";
4
6
  import { styles } from "./UImagesBlock.styles.js";
7
+ import schema from "./UImagesBlock.schema.js";
5
8
  import { html, nothing } from "lit";
6
9
  import { customElement, property, state } from "lit/decorators.js";
7
10
  import "@iyulab/components/dist/components/icon/UIcon.js";
8
11
  import { UElement } from "@iyulab/components/dist/components/UElement.js";
12
+ import { OverlayManager } from "@iyulab/components/dist/utilities/OverlayManager.js";
9
13
  import { repeat } from "lit/directives/repeat.js";
10
14
  import "@iyulab/components/dist/components/carousel/UCarousel.js";
11
15
  //#region src/components-extra/UImagesBlock.ts
16
+ registerElementBlock(schema);
12
17
  var UImagesBlock = class UImagesBlock extends UElement {
13
18
  constructor(..._args) {
14
19
  super(..._args);
@@ -36,8 +41,7 @@ var UImagesBlock = class UImagesBlock extends UElement {
36
41
  };
37
42
  this.handleKeyDown = (e) => {
38
43
  if (this.index === null) return;
39
- if (e.key === "Escape") this.close();
40
- else if (e.key === "ArrowLeft") this.prev();
44
+ if (e.key === "ArrowLeft") this.prev();
41
45
  else if (e.key === "ArrowRight") this.next();
42
46
  };
43
47
  }
@@ -50,8 +54,16 @@ var UImagesBlock = class UImagesBlock extends UElement {
50
54
  }
51
55
  disconnectedCallback() {
52
56
  document.removeEventListener("keydown", this.handleKeyDown);
57
+ OverlayManager.closeLayer(this);
53
58
  super.disconnectedCallback();
54
59
  }
60
+ /** 열린 라이트박스는 층이다 — Escape 는 components 의 층 스택이 «가장 나중에 연 층 하나» 에만 준다. */
61
+ updated(changed) {
62
+ super.updated(changed);
63
+ if (!changed.has("index")) return;
64
+ if (this.index !== null) OverlayManager.openLayer(this, () => this.close());
65
+ else OverlayManager.closeLayer(this);
66
+ }
55
67
  render() {
56
68
  if (!this.items?.length) return nothing;
57
69
  const count = this.items.length;
@@ -64,14 +76,17 @@ var UImagesBlock = class UImagesBlock extends UElement {
64
76
  .slidesPerView=${Math.min(count, 3)}
65
77
  .gap=${8}
66
78
  >
67
- ${repeat(this.items, (item, i) => html`
79
+ ${repeat(this.items, (item, i) => resolveImageSource(item.src) === null ? html`
80
+ <!-- 출처 정책이 막은 이미지는 요청하지 않는다 — 열 것이 없으므로 버튼도 아니다. -->
81
+ <div class="slide blocked">${this.blockedLabel(item)}</div>
82
+ ` : html`
68
83
  <!-- 썸네일은 라이트박스를 여는 버튼이다 — 클릭만 받는 div 는 키보드로 열 수 없었다.
69
84
  대체 텍스트가 있으면 그것이 이름이고, 없으면 «이미지 N 열기» 로 이름을 준다. -->
70
85
  <button type="button" class="slide"
71
86
  aria-label=${item.alt ? nothing : messages.text("openImage", { index: i + 1 })}
72
87
  @click=${() => this.open(i)}>
73
88
  <img
74
- src=${item.src}
89
+ src=${resolveImageSource(item.src)}
75
90
  alt=${item.alt || ""}
76
91
  loading="lazy"
77
92
  />
@@ -86,6 +101,14 @@ var UImagesBlock = class UImagesBlock extends UElement {
86
101
  ${this.renderLightbox()}
87
102
  `;
88
103
  }
104
+ /** 출처 정책(`setAllowedImagePrefixes`)이 막은 이미지 자리의 문구. */
105
+ blockedLabel(item) {
106
+ return item.alt ? messages.text("imageBlockedNamed", { name: item.alt }) : messages.text("imageBlocked");
107
+ }
108
+ renderLightboxImage(img) {
109
+ const src = resolveImageSource(img.src);
110
+ return src === null ? html`<div class="lb-blocked">${this.blockedLabel(img)}</div>` : html`<img src=${src} alt=${img.alt || ""} />`;
111
+ }
89
112
  renderLightbox() {
90
113
  const idx = this.index;
91
114
  if (idx === null) return nothing;
@@ -113,7 +136,7 @@ var UImagesBlock = class UImagesBlock extends UElement {
113
136
  <div class="lb-track" style="transform:translateX(${translateX})">
114
137
  ${repeat(this.items, (img, i) => html`
115
138
  <div class="lb-slide" ?active=${i === idx}>
116
- <img src=${img.src} alt=${img.alt || ""} />
139
+ ${this.renderLightboxImage(img)}
117
140
  </div>
118
141
  `)}
119
142
  </div>
@@ -40,6 +40,19 @@ var styles = css`
40
40
  filter: brightness(0.92);
41
41
  }
42
42
 
43
+ /* 출처 정책이 막은 이미지 — 요청 없이 대체 텍스트만. */
44
+ .slide.blocked {
45
+ display: grid;
46
+ place-items: center;
47
+ padding: 8px;
48
+ box-sizing: border-box;
49
+ border: 1px dashed var(--u-border-color, #E0E0E0);
50
+ color: var(--u-txt-color-weak, #616161);
51
+ font-size: 0.8em;
52
+ text-align: center;
53
+ cursor: default;
54
+ }
55
+
43
56
  .caption {
44
57
  position: absolute;
45
58
  bottom: 0;
@@ -58,7 +71,7 @@ var styles = css`
58
71
  .lb-overlay {
59
72
  position: fixed;
60
73
  inset: 0;
61
- z-index: 9999;
74
+ z-index: var(--u-layer-overlay, 9999);
62
75
  display: flex;
63
76
  flex-direction: column;
64
77
  background: rgba(0, 0, 0, 0.92);
@@ -160,6 +173,12 @@ var styles = css`
160
173
  user-select: none;
161
174
  pointer-events: none;
162
175
  }
176
+ .lb-blocked {
177
+ padding: 16px 24px;
178
+ border: 1px dashed rgba(255, 255, 255, 0.5);
179
+ border-radius: 6px;
180
+ color: white;
181
+ }
163
182
 
164
183
  .lb-nav {
165
184
  position: absolute;
@@ -1,10 +1,13 @@
1
- import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
+ import __decorate from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
+ import { registerElementBlock } from "../utilities/ElementRegistry.js";
3
4
  import { styles } from "./UMapBlock.styles.js";
5
+ import schema from "./UMapBlock.schema.js";
4
6
  import { html, nothing } from "lit";
5
7
  import { customElement, property } from "lit/decorators.js";
6
8
  import { UElement } from "@iyulab/components/dist/components/UElement.js";
7
9
  //#region src/components-extra/UMapBlock.ts
10
+ registerElementBlock(schema);
8
11
  var UMapBlock = class UMapBlock extends UElement {
9
12
  constructor(..._args) {
10
13
  super(..._args);
@@ -1,11 +1,14 @@
1
- import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
2
+ import __decorate from "../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
+ import { registerElementBlock } from "../utilities/ElementRegistry.js";
3
4
  import { styles } from "./UVideoBlock.styles.js";
5
+ import schema from "./UVideoBlock.schema.js";
4
6
  import { html, nothing } from "lit";
5
7
  import { customElement, property } from "lit/decorators.js";
6
8
  import { UElement } from "@iyulab/components/dist/components/UElement.js";
7
9
  import { ifDefined } from "lit/directives/if-defined.js";
8
10
  //#region src/components-extra/UVideoBlock.ts
11
+ registerElementBlock(schema);
9
12
  var UVideoBlock = class UVideoBlock extends UElement {
10
13
  constructor(..._args) {
11
14
  super(..._args);
package/dist/extra.d.ts CHANGED
@@ -2,5 +2,11 @@ export * from './components-extra/UChartBlock.js';
2
2
  export * from './components-extra/UImagesBlock.js';
3
3
  export * from './components-extra/UMapBlock.js';
4
4
  export * from './components-extra/UVideoBlock.js';
5
- /** 내장 extra 블록(chart/images/map/video)이 모두 등록된 LLM 시스템 프롬프트 조각 */
5
+ /**
6
+ * 내장 extra 블록(chart/images/map/video)이 모두 등록된 LLM 시스템 프롬프트 조각.
7
+ *
8
+ * 공유 인스턴스(`ElementPromptBuilder.instance`)에 등록한다 — 문서가 약속하듯 소비자가 거기에
9
+ * 자기 extra 를 더한 뒤 `build()` 를 다시 부르면 내장 넷과 함께 나온다. 종전에는 별도 인스턴스에
10
+ * 등록해 그 `build()` 가 소비자 것만 돌려줬다.
11
+ */
6
12
  export declare const prompt: string;
package/dist/extra.js CHANGED
@@ -1,14 +1,20 @@
1
1
  import { ElementPromptBuilder } from "./utilities/PromptBuilder.js";
2
- import { UChartBlock } from "./components-extra/UChartBlock.js";
3
- import { UImagesBlock } from "./components-extra/UImagesBlock.js";
4
- import { UMapBlock } from "./components-extra/UMapBlock.js";
5
- import { UVideoBlock } from "./components-extra/UVideoBlock.js";
6
2
  import schema from "./components-extra/UChartBlock.schema.js";
3
+ import { UChartBlock } from "./components-extra/UChartBlock.js";
7
4
  import schema$1 from "./components-extra/UImagesBlock.schema.js";
5
+ import { UImagesBlock } from "./components-extra/UImagesBlock.js";
8
6
  import schema$2 from "./components-extra/UMapBlock.schema.js";
7
+ import { UMapBlock } from "./components-extra/UMapBlock.js";
9
8
  import schema$3 from "./components-extra/UVideoBlock.schema.js";
9
+ import { UVideoBlock } from "./components-extra/UVideoBlock.js";
10
10
  //#region src/extra.ts
11
- /** 내장 extra 블록(chart/images/map/video)이 모두 등록된 LLM 시스템 프롬프트 조각 */
12
- var prompt = new ElementPromptBuilder().add(schema$1).add(schema$3).add(schema$2).add(schema).build();
11
+ /**
12
+ * 내장 extra 블록(chart/images/map/video)이 모두 등록된 LLM 시스템 프롬프트 조각.
13
+ *
14
+ * 공유 인스턴스(`ElementPromptBuilder.instance`)에 등록한다 — 문서가 약속하듯 소비자가 거기에
15
+ * 자기 extra 를 더한 뒤 `build()` 를 다시 부르면 내장 넷과 함께 나온다. 종전에는 별도 인스턴스에
16
+ * 등록해 그 `build()` 가 소비자 것만 돌려줬다.
17
+ */
18
+ var prompt = ElementPromptBuilder.instance.add(schema$1).add(schema$3).add(schema$2).add(schema).build();
13
19
  //#endregion
14
20
  export { UChartBlock, UImagesBlock, UMapBlock, UVideoBlock, prompt };
package/dist/index.d.ts CHANGED
@@ -17,4 +17,6 @@ export type * from './events/SendEvent';
17
17
  export type * from './events/StopEvent';
18
18
  export * from './utilities/HtmlBuilder.js';
19
19
  export * from './utilities/PromptBuilder.js';
20
+ export * from './utilities/ElementRegistry.js';
20
21
  export * from './utilities/sanitizers.js';
22
+ export * from './utilities/imageSources.js';
package/dist/index.js CHANGED
@@ -1,16 +1,19 @@
1
+ import "./utilities/icons.js";
1
2
  import { UCodeBlock } from "./components/blocks/UCodeBlock.js";
2
- import { escapeHtmlAttr, escapeHtmlHref, escapeHtmlText, stripZeroWidth } from "./utilities/sanitizers.js";
3
+ import { escapeHtmlAttr, escapeHtmlHref, escapeHtmlText, sanitizeHref, stripZeroWidth } from "./utilities/sanitizers.js";
3
4
  import { HtmlBuilder } from "./utilities/HtmlBuilder.js";
5
+ import { getElementBlockProperties, registerElementBlock } from "./utilities/ElementRegistry.js";
4
6
  import { UElementBlock } from "./components/blocks/UElementBlock.js";
5
7
  import { UFileBlock } from "./components/blocks/UFileBlock.js";
6
8
  import { URefTag } from "./components/references/URefTag.js";
7
- import { URefCard } from "./components/references/URefCard.js";
9
+ import { URefCard, googleFaviconUrl } from "./components/references/URefCard.js";
8
10
  import { URefCardGroup } from "./components/references/URefCardGroup.js";
9
11
  import { UTableBlock } from "./components/blocks/UTableBlock.js";
12
+ import { getAllowedImagePrefixes, resolveImageSource, setAllowedImagePrefixes } from "./utilities/imageSources.js";
10
13
  import { UMarkedBlock } from "./components/blocks/UMarkedBlock.js";
11
14
  import { UTextBlock } from "./components/blocks/UTextBlock.js";
12
15
  import { URefBlock } from "./components/blocks/URefBlock.js";
13
16
  import { UMessage } from "./components/message/UMessage.js";
14
17
  import { UPrompt } from "./components/prompt/UPrompt.js";
15
18
  import { ElementPromptBuilder } from "./utilities/PromptBuilder.js";
16
- export { ElementPromptBuilder, HtmlBuilder, UCodeBlock, UElementBlock, UFileBlock, UMarkedBlock, UMessage, UPrompt, URefBlock, URefCard, URefCardGroup, URefTag, UTableBlock, UTextBlock, escapeHtmlAttr, escapeHtmlHref, escapeHtmlText, stripZeroWidth };
19
+ export { ElementPromptBuilder, HtmlBuilder, UCodeBlock, UElementBlock, UFileBlock, UMarkedBlock, UMessage, UPrompt, URefBlock, URefCard, URefCardGroup, URefTag, UTableBlock, UTextBlock, escapeHtmlAttr, escapeHtmlHref, escapeHtmlText, getAllowedImagePrefixes, getElementBlockProperties, googleFaviconUrl, registerElementBlock, resolveImageSource, sanitizeHref, setAllowedImagePrefixes, stripZeroWidth };
@@ -20846,7 +20846,7 @@ function parseArray(parser, _ref, style) {
20846
20846
  parser.consume();
20847
20847
  } else if (next === "\\end") {
20848
20848
  endRow();
20849
- if (row.length === 1 && cell.type === "styling" && cell.body.length === 1 && cell.body[0].type === "ordgroup" && cell.body[0].body.length === 0 && (body.length > 1 || !emptySingleRow) && !Array.isArray(tags == null ? void 0 : tags[tags.length - 1])) body.pop();
20849
+ if (row.length === 1 && cell.type === "styling" && cell.body.length === 1 && cell.body[0].type === "ordgroup" && cell.body[0].body.length === 0 && (body.length > 1 || !emptySingleRow) && !Array.isArray(tags == null ? void 0 : tags[tags.length - 1]) && !(autoTag && (tags == null ? void 0 : tags[tags.length - 1]) === true)) body.pop();
20850
20850
  if (hLinesBeforeRow.length < body.length + 1) hLinesBeforeRow.push([]);
20851
20851
  break;
20852
20852
  } else if (next === "\\\\") {
@@ -26276,7 +26276,7 @@ var renderToHTMLTree = function renderToHTMLTree(expression, options) {
26276
26276
  return renderError(error, expression, settings);
26277
26277
  }
26278
26278
  };
26279
- var version = "0.18.7";
26279
+ var version = "0.18.9";
26280
26280
  var __domTree = {
26281
26281
  Span,
26282
26282
  Anchor,