@edmicro/olkit-icons 1.0.15 → 1.0.16

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
@@ -69,61 +69,93 @@ export class ExampleComponent {}
69
69
 
70
70
  ---
71
71
 
72
- ## ⚡ Hướng dẫn Tree-shaking tối ưu Bundle Size
72
+ ## ⚡ Cách sử dụng & Tối ưu Tree-shaking (Tối ưu Bundle Size)
73
73
 
74
- Mỗi icon chỉ nặng khoảng **2-5 KB**. Để tránh bundle toàn bộ thư viện 13,800+ icons vào ứng dụng, bạn có thể lựa chọn 1 trong 2 cách sau:
74
+ Mỗi icon chỉ nặng khoảng **2-5 KB**. Để ứng dụng chỉ đóng gói đúng các icon bạn sử dụng (Tree-shaking 100%), thư viện hỗ trợ các cách sử dụng sau:
75
75
 
76
- ### Cách 1: Import thủ công (Khuyến nghị cho Angular 19+ / Không cần Plugin)
76
+ ---
77
+
78
+ ### Cách 1: Tự động quét & Nội suy qua CLI (Khuyên dùng nhất – 0 chạm angular.json)
79
+
80
+ * **Không cần nhớ hay viết bất kỳ hằng số nào** (`SOLAR_HOME_2_LINEAR`).
81
+ * **Không cần sửa `angular.json`** (giữ nguyên `@angular/build:application` 100%).
82
+
83
+ #### Bước 1: Thêm script vào `package.json` của dự án:
84
+ ```json
85
+ "scripts": {
86
+ "prebuild": "olkit-icons scan",
87
+ "build": "ng build"
88
+ }
89
+ ```
90
+ *(Nếu bạn chạy build qua script bash như `product.build.sh`, chỉ cần thêm 1 dòng: `npx olkit-icons scan` ngay trước lệnh `ng build`).*
91
+
92
+ #### Bước 2: Nạp vào `app.config.ts` (Thiết lập 1 lần duy nhất):
93
+ ```typescript
94
+ import { appIconsProvider } from './olkit-icons.generated';
95
+
96
+ export const appConfig: ApplicationConfig = {
97
+ providers: [
98
+ appIconsProvider
99
+ ]
100
+ };
101
+ ```
77
102
 
78
- Không cần cài thêm plugin hay cấu hình bundler phức tạp, tận dụng khả năng tree-shaking tự nhiên của ES Module:
103
+ #### Bước 3: Sử dụng trong HTML:
104
+ Dev chỉ việc copy thẻ từ trang Docs và paste vào bất kỳ component nào:
105
+ ```html
106
+ <ol-icon name="solar:home-2-linear" />
107
+ <ol-icon name="user-circle" />
108
+ <ol-icon name="lucide:cog" />
109
+ ```
110
+
111
+ * **Lúc chạy Dev Local (`ng serve`)**: Khi paste icon mới và bấm `Ctrl + S`, thư viện tự động kích hoạt lazy-load ngầm để icon hiển thị ngay lập tức trên trình duyệt.
112
+ * **Lúc chạy Build Production**: Lệnh quét chạy trong 0.04s, tự động phát hiện các icon có trong code và gom vào `src/app/olkit-icons.generated.ts` để Angular đóng gói đúng các icon đó.
113
+
114
+ ---
115
+
116
+ ### Cách 2: Import thủ công hằng số (Không dùng CLI scan)
117
+
118
+ Nếu bạn muốn tự quản lý thủ công từng icon trong code:
79
119
 
80
120
  ```typescript
81
121
  import { bootstrapApplication } from '@angular/platform-browser';
82
122
  import { provideOlIcons } from '@edmicro/olkit-icons';
83
123
 
84
- // Import trực tiếp đúng file icon cần dùng
85
- import { SOLAR_ROCKET_LINEAR } from '@edmicro/olkit-icons/collections/solar/rocket_linear';
124
+ // Import trực tiếp từ file icon lẻ
125
+ import { SOLAR_HOME_2_LINEAR } from '@edmicro/olkit-icons/collections/solar/home_2_linear';
86
126
  import { OLKIT_USER_CIRCLE } from '@edmicro/olkit-icons/collections/olkit/user_circle';
87
- import { LUCIDE_TABLE } from '@edmicro/olkit-icons/collections/lucide/table';
127
+ import { LUCIDE_COG } from '@edmicro/olkit-icons/collections/lucide/cog';
88
128
 
89
129
  bootstrapApplication(AppComponent, {
90
130
  providers: [
131
+ // Hệ thống tự động suy luận ngược tên hằng số sang tên icon:
132
+ // SOLAR_HOME_2_LINEAR -> 'solar:home-2-linear'
133
+ // OLKIT_USER_CIRCLE -> 'user-circle' & 'olkit:user-circle'
134
+ // LUCIDE_COG -> 'lucide:cog'
91
135
  provideOlIcons({
92
- 'solar:rocket-linear': SOLAR_ROCKET_LINEAR,
93
- 'user-circle': OLKIT_USER_CIRCLE,
94
- 'lucide:table': LUCIDE_TABLE,
136
+ SOLAR_HOME_2_LINEAR,
137
+ OLKIT_USER_CIRCLE,
138
+ LUCIDE_COG,
95
139
  })
96
140
  ]
97
141
  });
98
142
  ```
99
143
 
100
- > **Ghi chú về Core Icons:** Các icon tích hợp sẵn trong component của `@edmicro/olkit` (như mũi tên `chevron-down` trong Accordion/Select, dấu tích `check` trong Checkbox, `close` trong Modal/Alert) đã được nạp sẵn trong bộ lõi đồng bộ. Bạn **không cần** phải import hay đăng ký lại các icon này.
101
-
102
144
  ---
103
145
 
104
- ### Cách 2: Khai báo theo tên chuỗi + Cài đặt `esbuild-plugin`
105
-
106
- Nếu bạn muốn khai báo gọn gàng bằng chuỗi tên mà không muốn viết nhiều dòng `import`:
107
-
108
- ```typescript
109
- provideOlIconsByName([
110
- ['solar:rocket-linear'],
111
- ['user-circle'], // Tự động hiểu là bộ olkit
112
- ['lucide:table']
113
- ])
114
- ```
146
+ ### Cách 3: Dành cho dự án dùng Vite hoặc AnalogJS
115
147
 
116
- Khi đó, **bắt buộc cấu hình plugin** `@edmicro/olkit-icons/esbuild-plugin.js` trong build tool (Vite / Next.js / Custom esbuild) để plugin tự động chuyển đổi chuỗi thành direct imports lúc compile:
148
+ Nếu dự án dùng **Vite** và muốn viết mảng chuỗi trực tiếp (`provideOlIconsByName(['solar:home-2-linear'])`), cài đặt plugin trong `vite.config.ts`:
117
149
 
118
150
  ```typescript
119
151
  // vite.config.ts
120
152
  import { defineConfig } from 'vite';
121
- import olkitIconsPlugin from '@edmicro/olkit-icons/esbuild-plugin.js';
153
+ const olkitIconsPlugin = require('@edmicro/olkit-icons/esbuild-plugin.js');
122
154
 
123
155
  export default defineConfig({
124
156
  optimizeDeps: {
125
157
  esbuildOptions: {
126
- plugins: [olkitIconsPlugin]
158
+ plugins: [olkitIconsPlugin()]
127
159
  }
128
160
  }
129
161
  });
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * CLI Tool for @edmicro/olkit-icons
5
+ * Automatically scans project templates & code for icon usages,
6
+ * infers imports, and generates a tree-shakable provider file.
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ // Icon name to file path and constant name inference
13
+ function getIconInfo(iconName) {
14
+ let collection, name;
15
+ const constMatch = iconName.match(/^(SOLAR|LUCIDE|MYNAUI|OLKIT)_(.+)$/i);
16
+ if (constMatch) {
17
+ collection = constMatch[1].toLowerCase();
18
+ name = constMatch[2].toLowerCase().replace(/_/g, '-');
19
+ } else if (iconName.includes(':')) {
20
+ const match = iconName.match(/^([^:]+):(.+)$/);
21
+ if (!match) return null;
22
+ collection = match[1].toLowerCase();
23
+ name = match[2];
24
+ } else {
25
+ collection = 'olkit';
26
+ name = iconName;
27
+ }
28
+
29
+ // Only support valid collections
30
+ if (!['solar', 'lucide', 'mynaui', 'olkit'].includes(collection)) {
31
+ return null;
32
+ }
33
+
34
+ // Convert icon name to filename (e.g. "home-2-linear" -> "home_2_linear")
35
+ const filename = name.replace(/-/g, '_');
36
+
37
+ // Convert to constant name (e.g. "SOLAR_HOME_2_LINEAR")
38
+ const constantName = `${collection.toUpperCase()}_${filename.toUpperCase()}`;
39
+
40
+ // Build import path
41
+ const importPath = `@edmicro/olkit-icons/collections/${collection}/${filename}`;
42
+
43
+ return { collection, filename, constantName, importPath, originalName: iconName };
44
+ }
45
+
46
+ // Find all files matching extensions in directory
47
+ function findFiles(dir, extensions, fileList = []) {
48
+ if (!fs.existsSync(dir)) return fileList;
49
+ const files = fs.readdirSync(dir);
50
+
51
+ for (const file of files) {
52
+ const fullPath = path.join(dir, file);
53
+ if (file === 'node_modules' || file === '.git' || file === 'dist') continue;
54
+
55
+ const stat = fs.statSync(fullPath);
56
+ if (stat.isDirectory()) {
57
+ findFiles(fullPath, extensions, fileList);
58
+ } else if (extensions.some(ext => file.endsWith(ext))) {
59
+ fileList.push(fullPath);
60
+ }
61
+ }
62
+
63
+ return fileList;
64
+ }
65
+
66
+ // Extract icon names from source code
67
+ function extractIconsFromContent(content) {
68
+ const icons = new Set();
69
+
70
+ // Pattern 1: name="icon-name" or icon="icon-name" (HTML templates)
71
+ const tagAttrRegex = /\b(?:name|icon)=["']([^"'\s]+)["']/g;
72
+ let match;
73
+ while ((match = tagAttrRegex.exec(content)) !== null) {
74
+ const name = match[1];
75
+ if (isValidIconName(name)) icons.add(name);
76
+ }
77
+
78
+ // Pattern 2: [name]="'icon-name'" or [icon]="'icon-name'" (Angular property binding)
79
+ const bindingRegex = /\[(?:name|icon)\]=["']'([^"']+)'["']/g;
80
+ while ((match = bindingRegex.exec(content)) !== null) {
81
+ const name = match[1];
82
+ if (isValidIconName(name)) icons.add(name);
83
+ }
84
+
85
+ // Pattern 3: provideOlIconsByName(['...']) or provideOlIcons(['...'])
86
+ const provideRegex = /(?:provideOlIconsByName|provideOlIcons)\s*\(\s*\[([\s\S]*?)\]\s*\)/g;
87
+ while ((match = provideRegex.exec(content)) !== null) {
88
+ const argsStr = match[1];
89
+ const strMatches = argsStr.matchAll(/['"]([^'"]+)['"]/g);
90
+ for (const strMatch of strMatches) {
91
+ const name = strMatch[1];
92
+ if (isValidIconName(name)) icons.add(name);
93
+ }
94
+ }
95
+
96
+ return icons;
97
+ }
98
+
99
+ function isValidIconName(name) {
100
+ if (!name || name.includes(' ') || name.includes('{{') || name.startsWith('http')) {
101
+ return false;
102
+ }
103
+ // If it has collection prefix
104
+ if (name.includes(':')) {
105
+ const [col] = name.split(':');
106
+ return ['solar', 'lucide', 'mynaui', 'olkit'].includes(col.toLowerCase());
107
+ }
108
+ // Single names (could be olkit icon)
109
+ return /^[a-z0-9_-]+$/i.test(name);
110
+ }
111
+
112
+ // Core icons that don't need manual bundle import
113
+ const CORE_ICONS = new Set([
114
+ 'chevron-down', 'chevron-up', 'chevron-left', 'chevron-right',
115
+ 'check', 'close', 'x', 'plus', 'minus', 'search', 'list',
116
+ 'eye', 'eye-closed', 'copy', 'info', 'alert', 'warning',
117
+ ]);
118
+
119
+ function runScan(srcDir = './src', outFile = './src/app/olkit-icons.generated.ts') {
120
+ console.log(`\n🔍 [olkit-icons scan] Đang quét icon trong "${srcDir}"...`);
121
+
122
+ const files = findFiles(srcDir, ['.html', '.ts']);
123
+ const allIcons = new Set();
124
+
125
+ for (const file of files) {
126
+ // Skip the generated file itself
127
+ if (path.resolve(file) === path.resolve(outFile)) continue;
128
+
129
+ const content = fs.readFileSync(file, 'utf8');
130
+ const icons = extractIconsFromContent(content);
131
+ for (const icon of icons) {
132
+ allIcons.add(icon);
133
+ }
134
+ }
135
+
136
+ // Process and filter icons
137
+ const iconInfos = [];
138
+ const skippedCore = [];
139
+
140
+ for (const icon of allIcons) {
141
+ // If it's a built-in core icon, it's already in the core bundle
142
+ if (CORE_ICONS.has(icon.toLowerCase())) {
143
+ skippedCore.push(icon);
144
+ continue;
145
+ }
146
+
147
+ const info = getIconInfo(icon);
148
+ if (info) {
149
+ iconInfos.push(info);
150
+ }
151
+ }
152
+
153
+ // Deduplicate by constantName
154
+ const uniqueIcons = new Map();
155
+ for (const info of iconInfos) {
156
+ uniqueIcons.set(info.constantName, info);
157
+ }
158
+
159
+ const sortedIcons = Array.from(uniqueIcons.values()).sort((a, b) =>
160
+ a.constantName.localeCompare(b.constantName)
161
+ );
162
+
163
+ // Generate file content
164
+ const lines = [
165
+ `/**`,
166
+ ` * File được tự động sinh bởi: npx olkit-icons scan`,
167
+ ` * KHÔNG SỬA TAY. Chạy lại lệnh quét để cập nhật khi thêm icon mới.`,
168
+ ` */`,
169
+ `import { provideOlIcons } from '@edmicro/olkit-icons';`,
170
+ ];
171
+
172
+ if (sortedIcons.length > 0) {
173
+ lines.push('');
174
+ for (const icon of sortedIcons) {
175
+ lines.push(`import { ${icon.constantName} } from '${icon.importPath}';`);
176
+ }
177
+ lines.push('');
178
+ lines.push(`export const appIconsProvider = provideOlIcons({`);
179
+ for (const icon of sortedIcons) {
180
+ lines.push(` ${icon.constantName},`);
181
+ }
182
+ lines.push(`});`);
183
+ } else {
184
+ lines.push('');
185
+ lines.push(`export const appIconsProvider = provideOlIcons({});`);
186
+ }
187
+ lines.push('');
188
+
189
+ // Ensure output directory exists
190
+ const outDir = path.dirname(outFile);
191
+ if (!fs.existsSync(outDir)) {
192
+ fs.mkdirSync(outDir, { recursive: true });
193
+ }
194
+
195
+ fs.writeFileSync(outFile, lines.join('\n'), 'utf8');
196
+
197
+ console.log(`✨ [olkit-icons scan] Hoàn tất!`);
198
+ console.log(` - Tổng số file quét: ${files.length} files`);
199
+ console.log(` - Icon tìm thấy: ${sortedIcons.length} icons (đã bỏ qua ${skippedCore.length} core icons có sẵn)`);
200
+ if (sortedIcons.length > 0) {
201
+ sortedIcons.forEach(i => console.log(` ✓ ${i.originalName} ➜ ${i.constantName}`));
202
+ }
203
+ console.log(` - Đã sinh file: ${outFile}\n`);
204
+ }
205
+
206
+ // CLI argument parsing
207
+ const args = process.argv.slice(2);
208
+ let srcDir = './src';
209
+ let outFile = './src/app/olkit-icons.generated.ts';
210
+ let isWatch = false;
211
+
212
+ for (let i = 0; i < args.length; i++) {
213
+ if (args[i] === '--src' || args[i] === '-s') {
214
+ srcDir = args[++i];
215
+ } else if (args[i] === '--out' || args[i] === '-o') {
216
+ outFile = args[++i];
217
+ } else if (args[i] === '--watch' || args[i] === '-w') {
218
+ isWatch = true;
219
+ }
220
+ }
221
+
222
+ // Initial scan
223
+ runScan(srcDir, outFile);
224
+
225
+ // Watch mode for local development
226
+ if (isWatch) {
227
+ console.log(`👀 [olkit-icons] Đang lắng nghe thay đổi trong "${srcDir}"...`);
228
+ let debounceTimer = null;
229
+
230
+ try {
231
+ fs.watch(srcDir, { recursive: true }, (eventType, filename) => {
232
+ if (!filename) return;
233
+ if (filename.endsWith('.html') || filename.endsWith('.ts')) {
234
+ // Skip changes to the generated file itself
235
+ if (path.resolve(path.join(srcDir, filename)) === path.resolve(outFile)) return;
236
+
237
+ clearTimeout(debounceTimer);
238
+ debounceTimer = setTimeout(() => {
239
+ console.log(`🔄 Phát hiện thay đổi ở "${filename}", đang cập nhật icon...`);
240
+ runScan(srcDir, outFile);
241
+ }, 150);
242
+ }
243
+ });
244
+ } catch (err) {
245
+ console.warn(`[olkit-icons] Watch mode không được hỗ trợ trên môi trường này: ${err.message}`);
246
+ }
247
+ }
package/esbuild-plugin.js CHANGED
@@ -23,7 +23,11 @@ const path = require('path');
23
23
  // Map icon name to file path and constant name
24
24
  function getIconInfo(iconName) {
25
25
  let collection, name;
26
- if (iconName.includes(':')) {
26
+ const constMatch = iconName.match(/^(SOLAR|LUCIDE|MYNAUI|OLKIT)_(.+)$/i);
27
+ if (constMatch) {
28
+ collection = constMatch[1].toLowerCase();
29
+ name = constMatch[2].toLowerCase().replace(/_/g, '-');
30
+ } else if (iconName.includes(':')) {
27
31
  const match = iconName.match(/^([^:]+):(.+)$/);
28
32
  if (!match) {
29
33
  throw new Error(`Invalid icon name: ${iconName}. Expected format: "collection:icon-name"`);
@@ -47,10 +51,10 @@ function getIconInfo(iconName) {
47
51
  return { collection, filename, constantName, importPath };
48
52
  }
49
53
 
50
- // Extract icon names from provideOlIconsByName call
54
+ // Extract icon names from provideOlIconsByName or provideOlIcons call
51
55
  function extractIconNames(code) {
52
- // Match: provideOlIconsByName([[...]])
53
- const regex = /provideOlIconsByName\s*\(\s*\[\s*\[([\s\S]*?)\]\s*\]\s*\)/g;
56
+ // Match: provideOlIconsByName([...]) or provideOlIcons([...])
57
+ const regex = /(?:provideOlIconsByName|provideOlIcons)\s*\(\s*\[([\s\S]*?)\]\s*\)/g;
54
58
  const icons = [];
55
59
 
56
60
  let match;
@@ -65,7 +69,7 @@ function extractIconNames(code) {
65
69
  }
66
70
  }
67
71
 
68
- return icons;
72
+ return [...new Set(icons)];
69
73
  }
70
74
 
71
75
  // Transform code
@@ -82,22 +86,29 @@ function transformCode(code, iconNames) {
82
86
  const { importPath, constantName } = getIconInfo(iconName);
83
87
  const varName = `__olkit_icon_${index}`;
84
88
 
85
- imports.push(`import ${varName} from '${importPath}';`);
86
- iconMap[iconName] = `${varName}.${constantName}`;
89
+ imports.push(`import { ${constantName} as ${varName} } from '${importPath}';`);
90
+ iconMap[iconName] = varName;
87
91
  } catch (error) {
88
92
  console.warn(`[olkit-icons] Warning: ${error.message}`);
89
93
  }
90
94
  });
91
95
 
92
- // Replace provideOlIconsByName with provideOlIcons
96
+ // Replace provideOlIconsByName / provideOlIcons with provideOlIcons
93
97
  const iconEntries = Object.entries(iconMap)
94
98
  .map(([name, ref]) => ` '${name}': ${ref}`)
95
99
  .join(',\n');
96
100
 
97
101
  const replacement = `provideOlIcons({\n${iconEntries}\n })`;
98
102
 
103
+ // Replace provideOlIconsByName([...])
99
104
  transformed = transformed.replace(
100
- /provideOlIconsByName\s*\(\s*\[\s*\[[\s\S]*?\]\s*\]\s*\)/g,
105
+ /provideOlIconsByName\s*\(\s*\[[\s\S]*?\]\s*\)/g,
106
+ replacement
107
+ );
108
+
109
+ // Replace provideOlIcons([...])
110
+ transformed = transformed.replace(
111
+ /provideOlIcons\s*\(\s*\[[\s\S]*?\]\s*\)/g,
101
112
  replacement
102
113
  );
103
114
 
@@ -109,8 +120,8 @@ function transformCode(code, iconNames) {
109
120
  return transformed;
110
121
  }
111
122
 
112
- // ESBuild plugin
113
- module.exports = function olkitIconsPlugin() {
123
+ // ESBuild plugin implementation
124
+ function createOlkitIconsPlugin() {
114
125
  return {
115
126
  name: 'olkit-icons-transform',
116
127
  setup(build) {
@@ -118,8 +129,8 @@ module.exports = function olkitIconsPlugin() {
118
129
  build.onLoad({ filter: /\.tsx?$/ }, async (args) => {
119
130
  const source = await fs.promises.readFile(args.path, 'utf8');
120
131
 
121
- // Skip if file doesn't use provideOlIconsByName
122
- if (!source.includes('provideOlIconsByName')) {
132
+ // Skip if file doesn't use provideOlIconsByName or provideOlIcons
133
+ if (!source.includes('provideOlIconsByName') && !source.includes('provideOlIcons')) {
123
134
  return null;
124
135
  }
125
136
 
@@ -140,4 +151,13 @@ module.exports = function olkitIconsPlugin() {
140
151
  });
141
152
  },
142
153
  };
143
- };
154
+ }
155
+
156
+ const olkitIconsPlugin = createOlkitIconsPlugin;
157
+ const instance = createOlkitIconsPlugin();
158
+ olkitIconsPlugin.name = instance.name;
159
+ olkitIconsPlugin.setup = instance.setup;
160
+
161
+ module.exports = olkitIconsPlugin;
162
+ module.exports.default = olkitIconsPlugin;
163
+ module.exports.olkitIconsPlugin = olkitIconsPlugin;
@@ -144,6 +144,7 @@ const CORE_ICONS = {
144
144
  };
145
145
  const OL_ICONS = new InjectionToken("OL_ICONS");
146
146
  function provideOlIcons(icons) {
147
+ if (Array.isArray(icons)) return [];
147
148
  return [{
148
149
  provide: OL_ICONS,
149
150
  useValue: icons,
@@ -151,7 +152,6 @@ function provideOlIcons(icons) {
151
152
  }];
152
153
  }
153
154
  function provideOlIconsByName(iconNames) {
154
- if (typeof window !== "undefined") console.warn("[olkit-icons] provideOlIconsByName requires esbuild plugin to work. Add plugin to angular.json. See README for setup instructions.");
155
155
  return [];
156
156
  }
157
157
  var OlIconService = class OlIconService {
@@ -163,11 +163,22 @@ var OlIconService = class OlIconService {
163
163
  }
164
164
  register(icons) {
165
165
  for (const [name, svg] of Object.entries(icons)) {
166
- const norm = name.trim().toLowerCase();
166
+ const trimmed = name.trim();
167
+ const norm = trimmed.toLowerCase();
167
168
  this.registered.set(norm, svg);
168
- for (const key of [...this.cache.keys()]) if (key.endsWith(`:${this.aliasMap[norm] || norm}`)) this.cache.delete(key);
169
+ const inferred = this.constantToIconName(trimmed);
170
+ if (inferred) {
171
+ this.registered.set(inferred, svg);
172
+ if (inferred.startsWith("olkit:")) this.registered.set(inferred.slice(6), svg);
173
+ }
174
+ for (const key of [...this.cache.keys()]) if (key.endsWith(`:${this.aliasMap[norm] || norm}`) || inferred && key.endsWith(`:${inferred}`)) this.cache.delete(key);
169
175
  }
170
176
  }
177
+ constantToIconName(constantName) {
178
+ const match = constantName.match(/^(SOLAR|LUCIDE|MYNAUI|OLKIT)_(.+)$/i);
179
+ if (!match) return null;
180
+ return `${match[1].toLowerCase()}:${match[2].toLowerCase().replace(/_/g, "-")}`;
181
+ }
171
182
  getIconSync(name, variant = "linear") {
172
183
  if (typeof name !== "string" || !name.trim()) return null;
173
184
  const key = this.normalizeKey(name, variant);
@@ -322,6 +333,7 @@ const MULTICOLOR_ICONS = /* @__PURE__ */ new Set([
322
333
  ]);
323
334
  var OlIcon = class OlIcon {
324
335
  iconService = inject(OlIconService);
336
+ localIcons = inject(OL_ICONS, { optional: true });
325
337
  name = input.required(...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
326
338
  size = input("base", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
327
339
  color = input("current", ...ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []);
@@ -336,6 +348,7 @@ var OlIcon = class OlIcon {
336
348
  return this.asyncSvg();
337
349
  }, ...ngDevMode ? [{ debugName: "svgContent" }] : /* istanbul ignore next */ []);
338
350
  constructor() {
351
+ if (this.localIcons) for (const group of this.localIcons) this.iconService.register(group);
339
352
  effect(() => {
340
353
  const n = this.name();
341
354
  const v = this.variant();
@@ -1 +1 @@
1
- {"version":3,"file":"edmicro-olkit-icons.mjs","names":[],"sources":["../../../projects/olkit-icons/src/lib/icon/icon-aliases.ts","../../../projects/olkit-icons/src/lib/icon/core.icons.ts","../../../projects/olkit-icons/src/lib/icon/icon.service.ts","../../../projects/olkit-icons/src/lib/icon/icon.component.ts","../../../projects/olkit-icons/src/lib/icon-shape/icon-shape.component.ts","../../../projects/olkit-icons/src/lib/icon-shape/icon-shape.component.html","../../../projects/olkit-icons/src/lib/icon-stack/icon-stack.component.ts"],"sourcesContent":["/**\r\n * Bí danh tên icon → tên chuẩn trong registry.\r\n *\r\n * Tách khỏi `OlIconService` để `scripts/gen-core-icons.mjs` tra tên ĐÚNG như\r\n * service tra lúc chạy khi sinh bộ lõi (`core.icons.ts`). Hai nơi giữ hai bản\r\n * là hai bản sẽ lệch nhau.\r\n */\r\nexport const ICON_ALIASES: Readonly<Record<string, string>> = {\r\n /**\r\n * `check` phải là DẤU TÍCH THUẦN, không vòng tròn bao quanh.\r\n *\r\n * `solar.registry.ts` (file SINH TỰ ĐỘNG) ánh xạ `check` sang\r\n * `SOLAR_CHECK_CIRCLE_LINEAR` — icon có `<circle r=\"10\">`. Đo\r\n * /checkbox-radio ngày 2026-09-16: 10/10 ô đã chọn render vòng tròn quanh\r\n * dấu tích, trong khi Figma `Checkbox input, Checked=True` (#1149:54710)\r\n * vẽ MỘT path đặc, không circle.\r\n *\r\n * Sửa ở đây chứ không sửa registry: registry do\r\n * `scripts/gen-registry-metadata.js` sinh lại, vá tay sẽ mất.\r\n * 19 chỗ trong repo dùng `name=\"check\"` đều là ngữ cảnh dấu tích.\r\n */\r\n check: 'lucide:check',\r\n\r\n /**\r\n * `close` phải là DẤU X THUẦN, không vòng tròn bao quanh — cùng lớp lỗi\r\n * với `check` ngay trên.\r\n *\r\n * Registry KHÔNG có khoá `close` trần (tra cả 13.064 khoá: chỉ có\r\n * `close-circle`, `close-square`, và `lucide:x` / `mynaui:x`). Nên 17 chỗ\r\n * trong repo phải viết `name=\"close-circle\"` — icon có `<circle r=\"10\">`.\r\n *\r\n * Đọc Figma 2026-09-17: mọi node `close` trong `ol-select`, `ol-tag-input`,\r\n * `ol-autocomplete-menu`, `ol-autocomplete-item`, `ol-alert`,\r\n * `ol-modal-header`, `ol-modal-footer`, `ol-drawer-header` đều có\r\n * **ellipse = 0** và đúng **1 VECTOR** — dấu X trần, KHÔNG vòng tròn.\r\n * Code lệch Figma ở cả 7 component đo được.\r\n *\r\n * Sửa ở đây chứ không sửa registry: registry do\r\n * `scripts/gen-registry-metadata.js` sinh lại, vá tay sẽ mất.\r\n */\r\n close: 'lucide:x',\r\n x: 'lucide:x',\r\n\r\n minus: 'lucide:minus',\r\n\r\n /**\r\n * `plus` phải là DẤU CỘNG THUẦN, cặp với `minus` ngay trên — cùng lớp lỗi\r\n * với `check` và `close`.\r\n *\r\n * Registry KHÔNG có khoá `plus` trần (tra 13.241 khoá: chỉ `plus-minus`,\r\n * `user-plus`, `user-plus-rounded`, và `lucide:plus` / `mynaui:plus`). Tên\r\n * `plus` rơi vào một icon CÓ VÒNG TRÒN qua đường tra khác.\r\n *\r\n * Đo /forms 2026-09-17 trên `ol-input-counter`: nút `minus` render 1 path\r\n * trần, nút `plus` ngay cạnh render kèm `<circle>` — hai nút cùng cặp mà\r\n * một có vòng một không, lệch thấy rõ.\r\n */\r\n plus: 'lucide:plus',\r\n info: 'lucide:info',\r\n share: 'screen-share',\r\n 'share-nodes': 'screen-share',\r\n print: 'printer',\r\n 'file-copy': 'file',\r\n 'file-copy-alt': 'file',\r\n 'floppy-disk-alt': 'bookmark',\r\n 'search-minimalistic': 'minimalistic-magnifer',\r\n 'box-shadow': 'layers',\r\n 'grid-ruler': 'widget',\r\n sparkles: 'star-shine',\r\n 'avatar-user': 'user-circle',\r\n pattern: 'three-squares',\r\n illustration: 'photo',\r\n 'logo-wave': 'onluyen-logo',\r\n list: 'reorder',\r\n palette: 'palette',\r\n sun: 'sun',\r\n moon: 'moon',\r\n code: 'code-file',\r\n bars: 'menu',\r\n hamburger: 'menu',\r\n 'hamburger-menu': 'menu',\r\n 'inbox-full': 'inbox',\r\n 'academic-cap': 'square-academic-cap',\r\n 'adjustments-horizontal': 'sort-horizontal',\r\n 'adjustments-vertical': 'sort-vertical',\r\n 'alert-circle': 'danger-circle',\r\n 'alert-triangle': 'danger-triangle',\r\n 'align-center': 'mynaui:text-align-center',\r\n 'align-justify': 'lucide:text-align-justify',\r\n 'angle-down': 'chevron-down',\r\n 'angle-left': 'chevron-left',\r\n 'angle-right': 'chevron-right',\r\n 'arrow-right-to-bracket': 'lucide:arrow-right-to-line',\r\n 'arrows-repeat': 'mynaui:repeat',\r\n 'backward-step': 'lucide:step-back',\r\n caption: 'lucide:closed-caption',\r\n 'cash-register': 'solar:cash-out-outline',\r\n 'chevron-sort': 'sort',\r\n 'code-branch': 'lucide:git-branch',\r\n 'desktop-computer': 'lucide:computer',\r\n 'dots-horizontal': 'menu-dots',\r\n envelope: 'letter',\r\n expand: 'lucide:expand',\r\n 'file-circle-plus': 'mynaui:file-plus',\r\n 'file-lines': 'file-text',\r\n 'forward-step': 'lucide:step-forward',\r\n 'insert-table-alt': 'mynaui:table',\r\n 'letter-italic': 'lucide:italic',\r\n 'letter-underline': 'lucide:underline',\r\n 'life-saver': 'lucide:life-buoy',\r\n 'list-music': 'lucide:list-music',\r\n 'mail-box': 'lucide:mailbox',\r\n 'message-square': 'lucide:message-square',\r\n messages: 'mynaui:chat-messages',\r\n 'ordered-list': 'lucide:list-ordered',\r\n 'phone-hangup': 'lucide:phone-off',\r\n photograph: 'photo',\r\n 'share-2': 'lucide:share-2',\r\n 'text-size': 'lucide:type',\r\n 'text-slash': 'lucide:remove-formatting',\r\n 'user-headset': 'lucide:headset',\r\n 'video-camera': 'lucide:video',\r\n 'volume-up': 'lucide:volume-2',\r\n};\r\n","/**\r\n * Bộ icon lõi — SVG của đúng các icon mà component trong thư viện tự vẽ.\r\n * Sinh tự động bởi scripts/gen-core-icons.mjs — đừng sửa tay.\r\n *\r\n * `OlIconService` tra bảng này TRƯỚC registry theo bộ: component chỉ dùng\r\n * icon lõi thì không tải bộ nào (bộ Solar 10 MB). Khoá là tên ĐÃ CHUẨN HOÁ\r\n * (chữ thường) mà component truyền vào, giá trị là SVG đã tra theo bí danh.\r\n *\r\n * 64 icon · olkit 24 · lucide 20 · mynaui 5 · solar 15\r\n */\r\nexport const CORE_ICONS: Readonly<Record<string, string>> = {\r\n 'alt-arrow-down':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M19 9L12 15L5 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'alt-arrow-left':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M15 5L9 12L15 19\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'alt-arrow-right':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M9 5L15 12L9 19\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'arrow-left':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M20 12H4M10 18L4 12L10 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'arrow-right':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M4 12H20M14 18L20 12L14 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n calendar:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M2 12C2 8.22876 2 6.34315 3.17157 5.17157C4.34315 4 6.22876 4 10 4H14C17.7712 4 19.6569 4 20.8284 5.17157C22 6.34315 22 8.22876 22 12V14C22 17.7712 22 19.6569 20.8284 20.8284C19.6569 22 17.7712 22 14 22H10C6.22876 22 4.34315 22 3.17157 20.8284C2 19.6569 2 17.7712 2 14V12Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M7 4V2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M17 4V2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M2.5 9H21.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M18 17C18 17.5523 17.5523 18 17 18C16.4477 18 16 17.5523 16 17C16 16.4477 16.4477 16 17 16C17.5523 16 18 16.4477 18 17Z\" fill=\"currentColor\"/> <path d=\"M18 13C18 13.5523 17.5523 14 17 14C16.4477 14 16 13.5523 16 13C16 12.4477 16.4477 12 17 12C17.5523 12 18 12.4477 18 13Z\" fill=\"currentColor\"/> <path d=\"M13 17C13 17.5523 12.5523 18 12 18C11.4477 18 11 17.5523 11 17C11 16.4477 11.4477 16 12 16C12.5523 16 13 16.4477 13 17Z\" fill=\"currentColor\"/> <path d=\"M13 13C13 13.5523 12.5523 14 12 14C11.4477 14 11 13.5523 11 13C11 12.4477 11.4477 12 12 12C12.5523 12 13 12.4477 13 13Z\" fill=\"currentColor\"/> <path d=\"M8 17C8 17.5523 7.55228 18 7 18C6.44772 18 6 17.5523 6 17C6 16.4477 6.44772 16 7 16C7.55228 16 8 16.4477 8 17Z\" fill=\"currentColor\"/> <path d=\"M8 13C8 13.5523 7.55228 14 7 14C6.44772 14 6 13.5523 6 13C6 12.4477 6.44772 12 7 12C7.55228 12 8 12.4477 8 13Z\" fill=\"currentColor\"/> </svg>',\r\n 'calendar-add':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M2 12C2 8.22876 2 6.34315 3.17157 5.17157C4.34315 4 6.22876 4 10 4H14C17.7712 4 19.6569 4 20.8284 5.17157C22 6.34315 22 8.22876 22 12V14C22 17.7712 22 19.6569 20.8284 20.8284C19.6569 22 17.7712 22 14 22H10C6.22876 22 4.34315 22 3.17157 20.8284C2 19.6569 2 17.7712 2 14V12Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M18 16L16 16M16 16L14 16M16 16L16 14M16 16L16 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M7 4V2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M17 4V2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M2.5 9H21.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> </svg>',\r\n check:\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20 6L9 17l-5-5\"/></svg>',\r\n 'check-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M8.5 12.5L10.5 14.5L15.5 9.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'chevron-down':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"m6 9l6 6l6-6\"/></svg>',\r\n 'chevron-left':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"m15 6l-6 6l6 6\"/></svg>',\r\n 'chevron-right':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"m9 18l6-6l-6-6\"/></svg>',\r\n 'clock-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 8V12L14.5 14.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n close:\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 6L6 18M6 6l12 12\"/></svg>',\r\n 'close-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M14.5 9.50002L9.5 14.5M9.49998 9.5L14.5 14.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> </svg>',\r\n 'danger-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 7V13\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"12\" cy=\"16\" r=\"1\" fill=\"currentColor\"/> </svg>',\r\n 'danger-triangle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M5.31171 10.7615C8.23007 5.58716 9.68925 3 12 3C14.3107 3 15.7699 5.58716 18.6883 10.7615L19.0519 11.4063C21.4771 15.7061 22.6897 17.856 21.5937 19.428C20.4978 21 17.7864 21 12.3637 21H11.6363C6.21356 21 3.50217 21 2.40626 19.428C1.31034 17.856 2.52291 15.7061 4.94805 11.4063L5.31171 10.7615Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 8V13\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"12\" cy=\"16\" r=\"1\" fill=\"currentColor\"/> </svg>',\r\n download:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M22 14.0002H21.25V14.0002H22ZM22 15.0002H22.75V15.0002H22ZM16 21.0002V20.2502V20.2502V21.0002ZM8 21.0002V21.7502V21.7502V21.0002ZM2 15.0002H2.75H2ZM2 14.0002H1.25H2ZM2.87868 8.87889L3.40901 9.40922L3.40901 9.40922L2.87868 8.87889ZM21.1213 8.87889L21.6517 8.34856V8.34856L21.1213 8.87889ZM17.0042 7.25196C16.59 7.24966 16.2523 7.58357 16.25 7.99778C16.2477 8.41198 16.5816 8.74963 16.9958 8.75194L17 8.00195L17.0042 7.25196ZM7.00418 8.75194C7.41838 8.74963 7.75229 8.41198 7.74999 7.99778C7.74768 7.58357 7.41003 7.24966 6.99583 7.25196L7 8.00195L7.00418 8.75194ZM12.75 3C12.75 2.58579 12.4142 2.25 12 2.25C11.5858 2.25 11.25 2.58579 11.25 3L12 3L12.75 3ZM12 17L11.4697 17.5303C11.6103 17.671 11.8011 17.75 12 17.75C12.1989 17.75 12.3897 17.671 12.5303 17.5303L12 17ZM8.53033 12.4697C8.23744 12.1768 7.76256 12.1768 7.46967 12.4697C7.17678 12.7626 7.17678 13.2374 7.46967 13.5303L8 13L8.53033 12.4697ZM16.5303 13.5303C16.8232 13.2374 16.8232 12.7626 16.5303 12.4697C16.2374 12.1768 15.7626 12.1768 15.4697 12.4697L16 13L16.5303 13.5303ZM22 14.0002H21.25V15.0002H22H22.75V14.0002H22ZM16 21.0002V20.2502H8V21.0002V21.7502H16V21.0002ZM2 15.0002H2.75L2.75 14.0002H2H1.25L1.25 15.0002H2ZM2 14.0002H2.75C2.75 12.5648 2.75159 11.5637 2.85315 10.8083C2.9518 10.0746 3.13225 9.68599 3.40901 9.40922L2.87868 8.87889L2.34835 8.34856C1.74643 8.95048 1.48754 9.70835 1.36652 10.6085C1.24841 11.487 1.25 12.6072 1.25 14.0002H2ZM8 21.0002V20.2502C6.56458 20.2502 5.56347 20.2486 4.80812 20.1471C4.07434 20.0484 3.68577 19.868 3.40901 19.5912L2.87868 20.1215L2.34835 20.6519C2.95027 21.2538 3.70814 21.5127 4.60825 21.6337C5.48678 21.7518 6.60699 21.7502 8 21.7502V21.0002ZM2 15.0002H1.25C1.25 16.3932 1.24841 17.5134 1.36652 18.392C1.48754 19.2921 1.74643 20.0499 2.34835 20.6519L2.87868 20.1215L3.40901 19.5912C3.13225 19.3144 2.9518 18.9259 2.85315 18.1921C2.75159 17.4367 2.75 16.4356 2.75 15.0002H2ZM22 15.0002H21.25C21.25 16.4356 21.2484 17.4367 21.1469 18.1921C21.0482 18.9259 20.8678 19.3144 20.591 19.5912L21.1213 20.1215L21.6517 20.6519C22.2536 20.0499 22.5125 19.2921 22.6335 18.392C22.7516 17.5134 22.75 16.3932 22.75 15.0002H22ZM16 21.0002V21.7502C17.393 21.7502 18.5132 21.7518 19.3918 21.6337C20.2919 21.5127 21.0497 21.2538 21.6517 20.6519L21.1213 20.1215L20.591 19.5912C20.3142 19.868 19.9257 20.0484 19.1919 20.1471C18.4365 20.2486 17.4354 20.2502 16 20.2502V21.0002ZM22 14.0002H22.75C22.75 12.6072 22.7516 11.487 22.6335 10.6085C22.5125 9.70835 22.2536 8.95048 21.6517 8.34856L21.1213 8.87889L20.591 9.40922C20.8678 9.68599 21.0482 10.0746 21.1469 10.8083C21.2484 11.5637 21.25 12.5648 21.25 14.0002H22ZM17 8.00195L16.9958 8.75194C18.0893 8.75803 18.8644 8.78643 19.4527 8.89448C20.0195 8.99859 20.3475 9.16577 20.591 9.40922L21.1213 8.87889L21.6517 8.34856C21.1267 7.82363 20.4816 7.55839 19.7236 7.41916C18.9871 7.28386 18.0857 7.25798 17.0042 7.25196L17 8.00195ZM7 8.00195L6.99583 7.25196C5.9143 7.25798 5.01291 7.28386 4.27635 7.41916C3.51835 7.55839 2.87328 7.82363 2.34835 8.34856L2.87868 8.87889L3.40901 9.40922C3.65246 9.16577 3.98054 8.99859 4.54735 8.89448C5.13559 8.78642 5.91068 8.75803 7.00418 8.75194L7 8.00195ZM12 3L11.25 3L11.25 17H12H12.75L12.75 3L12 3ZM12 17L12.5303 16.4697L8.53033 12.4697L8 13L7.46967 13.5303L11.4697 17.5303L12 17ZM12 17L12.5303 17.5303L16.5303 13.5303L16 13L15.4697 12.4697L11.4697 16.4697L12 17Z\" fill=\"currentColor\"/> </svg>',\r\n 'info-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 17V11\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"1\" cy=\"1\" r=\"1\" transform=\"matrix(1 0 0 -1 11 9)\" fill=\"currentColor\"/> </svg>',\r\n link: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M10.0464 14C8.54044 12.4882 8.67609 9.90087 10.3494 8.22108L15.197 3.35462C16.8703 1.67483 19.4476 1.53865 20.9536 3.05046C22.4596 4.56228 22.3239 7.14956 20.6506 8.82935L18.2268 11.2626\"/><path d=\"M13.9536 10C15.4596 11.5118 15.3239 14.0991 13.6506 15.7789L11.2268 18.2121L8.80299 20.6454C7.12969 22.3252 4.55237 22.4613 3.0464 20.9495C1.54043 19.4377 1.67609 16.8504 3.34939 15.1706L5.77323 12.7373\"/></g></svg>',\r\n list: '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M2 17.5C2 16.5654 2 16.0981 2.20096 15.75C2.33261 15.522 2.52197 15.3326 2.75 15.201C3.09808 15 3.56538 15 4.5 15C5.43462 15 5.90192 15 6.25 15.201C6.47803 15.3326 6.66739 15.522 6.79904 15.75C7 16.0981 7 16.5654 7 17.5C7 18.4346 7 18.9019 6.79904 19.25C6.66739 19.478 6.47803 19.6674 6.25 19.799C5.90192 20 5.43462 20 4.5 20C3.56538 20 3.09808 20 2.75 19.799C2.52197 19.6674 2.33261 19.478 2.20096 19.25C2 18.9019 2 18.4346 2 17.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M9.5 17.5C9.5 16.5654 9.5 16.0981 9.70096 15.75C9.83261 15.522 10.022 15.3326 10.25 15.201C10.5981 15 11.0654 15 12 15C12.9346 15 13.4019 15 13.75 15.201C13.978 15.3326 14.1674 15.522 14.299 15.75C14.5 16.0981 14.5 16.5654 14.5 17.5C14.5 18.4346 14.5 18.9019 14.299 19.25C14.1674 19.478 13.978 19.6674 13.75 19.799C13.4019 20 12.9346 20 12 20C11.0654 20 10.5981 20 10.25 19.799C10.022 19.6674 9.83261 19.478 9.70096 19.25C9.5 18.9019 9.5 18.4346 9.5 17.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M17 17.5C17 16.5654 17 16.0981 17.201 15.75C17.3326 15.522 17.522 15.3326 17.75 15.201C18.0981 15 18.5654 15 19.5 15C20.4346 15 20.9019 15 21.25 15.201C21.478 15.3326 21.6674 15.522 21.799 15.75C22 16.0981 22 16.5654 22 17.5C22 18.4346 22 18.9019 21.799 19.25C21.6674 19.478 21.478 19.6674 21.25 19.799C20.9019 20 20.4346 20 19.5 20C18.5654 20 18.0981 20 17.75 19.799C17.522 19.6674 17.3326 19.478 17.201 19.25C17 18.9019 17 18.4346 17 17.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M4.5 15V9C4.5 6.64298 4.5 5.46447 5.23223 4.73223C5.96447 4 7.14298 4 9.5 4H14.5C16.857 4 18.0355 4 18.7678 4.73223C19.5 5.46447 19.5 6.64298 19.5 9V12M17 9.5L19.5 12L22 9.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'lucide:bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\"/></svg>',\r\n 'lucide:code':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m16 18l6-6l-6-6M8 6l-6 6l6 6\"/></svg>',\r\n 'lucide:file':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5\"/></g></svg>',\r\n 'lucide:file-archive':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M13.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v11.5\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5M8 12v-1m0 7v-2m0-9V6\"/><circle cx=\"8\" cy=\"20\" r=\"2\"/></g></svg>',\r\n 'lucide:file-code':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5m-10 4.5L8 15l2 2.5m4-5l2 2.5l-2 2.5\"/></g></svg>',\r\n 'lucide:file-image':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5\"/><circle cx=\"10\" cy=\"12\" r=\"2\"/><path d=\"m20 17l-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22\"/></g></svg>',\r\n 'lucide:file-music':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M11.65 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v10.35\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5M8 20v-7l3 1.474\"/><circle cx=\"6\" cy=\"20\" r=\"2\"/></g></svg>',\r\n 'lucide:file-spreadsheet':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5M8 13h2m4 0h2m-8 4h2m4 0h2\"/></g></svg>',\r\n 'lucide:file-text':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5M10 9H8m8 4H8m8 4H8\"/></g></svg>',\r\n 'lucide:file-type':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5m-9 10h2m-1-6v6m-3-5v-.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5v.5\"/></g></svg>',\r\n 'lucide:file-video-camera':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M4 12V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5m-10 9.843l3.033-1.755a.64.64 0 0 1 .967.56v4.704a.65.65 0 0 1-.967.56L10 20.157\"/><rect width=\"7\" height=\"6\" x=\"3\" y=\"16\" rx=\"1\"/></g></svg>',\r\n 'lucide:italic':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 4h-9m4 16H5M15 4L9 20\"/></svg>',\r\n 'lucide:lock':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\"/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"/></g></svg>',\r\n 'lucide:presentation':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M2 3h20m-1 0v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3m4 18l5-5l5 5\"/></svg>',\r\n 'lucide:zoom-in':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21l-4.35-4.35M11 8v6m-3-3h6\"/></g></svg>',\r\n 'lucide:zoom-out':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21l-4.35-4.35M8 11h6\"/></g></svg>',\r\n magnifer:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"11.5\" cy=\"11.5\" r=\"9.5\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M18.5 18.5L22 22\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> </svg>',\r\n menu: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M20 7L4 7\"/><path d=\"M20 12L4 12\"/><path d=\"M20 17L4 17\"/></g></svg>',\r\n 'menu-dots':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"5\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <circle cx=\"12\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <circle cx=\"19\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/> </svg>',\r\n minus:\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14\"/></svg>',\r\n 'mynaui:smile':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\"><path d=\"M9 15c.85.63 1.885 1 3 1s2.15-.37 3-1m-5.5-4.5V10m5 .5V10\"/><path d=\"M21 12a9 9 0 1 1-18 0a9 9 0 0 1 18 0\"/></g></svg>',\r\n 'notification-unread':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M22 10.5V12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2H13.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"19\" cy=\"5\" r=\"3\" stroke=\"currentColor\" stroke-width=\"1.5\"/> </svg>',\r\n photo:\r\n '<svg viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M6 3C6 1.89543 6.89543 1 8 1H20L28 9V29C28 30.1046 27.1046 31 26 31H8C6.89543 31 6 30.1046 6 29V3Z\" fill=\"#0D9488\"/> <path d=\"M20 1V9H28L20 1Z\" fill=\"#0F766E\"/> <circle cx=\"12\" cy=\"15\" r=\"2\" fill=\"#F59E0B\"/> <path d=\"M9 24L14 18L18 22L21 19L23 24H9Z\" fill=\"#FFFFFF\"/> </svg>',\r\n plus: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7v14\"/></svg>',\r\n 'question-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M10.125 8.875C10.125 7.83947 10.9645 7 12 7C13.0355 7 13.875 7.83947 13.875 8.875C13.875 9.56245 13.505 10.1635 12.9534 10.4899C12.478 10.7711 12 11.1977 12 11.75V13\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"12\" cy=\"16\" r=\"1\" fill=\"currentColor\"/> </svg>',\r\n refresh:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M3.67981 11.3333H2.92981V11.3333H3.67981ZM3.67981 13L3.15157 13.5324C3.44398 13.8225 3.91565 13.8225 4.20805 13.5324L3.67981 13ZM5.88787 11.8657C6.18191 11.574 6.18377 11.0991 5.89203 10.8051C5.60029 10.511 5.12542 10.5092 4.83138 10.8009L5.35962 11.3333L5.88787 11.8657ZM2.52824 10.8009C2.2342 10.5092 1.75933 10.511 1.46759 10.8051C1.17585 11.0991 1.17772 11.574 1.47176 11.8657L2 11.3333L2.52824 10.8009ZM18.6156 7.39279C18.8325 7.74565 19.2944 7.85585 19.6473 7.63892C20.0001 7.42199 20.1103 6.96007 19.8934 6.60721L19.2545 7L18.6156 7.39279ZM12.0789 3V2.25C7.03155 2.25 2.92981 6.3112 2.92981 11.3333H3.67981H4.42981C4.42981 7.15072 7.84884 3.75 12.0789 3.75V3ZM3.67981 11.3333H2.92981L2.92981 13H3.67981H4.42981L4.42981 11.3333H3.67981ZM3.67981 13L4.20805 13.5324L5.88787 11.8657L5.35962 11.3333L4.83138 10.8009L3.15157 12.4676L3.67981 13ZM3.67981 13L4.20805 12.4676L2.52824 10.8009L2 11.3333L1.47176 11.8657L3.15157 13.5324L3.67981 13ZM19.2545 7L19.8934 6.60721C18.287 3.99427 15.3873 2.25 12.0789 2.25V3V3.75C14.8484 3.75 17.2727 5.20845 18.6156 7.39279L19.2545 7Z\" fill=\"currentColor\"/> <path d=\"M20.3139 11L20.8411 10.4666C20.549 10.1778 20.0788 10.1778 19.7867 10.4666L20.3139 11ZM18.1004 12.1333C17.8058 12.4244 17.8031 12.8993 18.0942 13.1939C18.3854 13.4885 18.8603 13.4913 19.1549 13.2001L18.6277 12.6667L18.1004 12.1333ZM21.4729 13.2001C21.7675 13.4913 22.2424 13.4885 22.5335 13.1939C22.8247 12.8993 22.822 12.4244 22.5274 12.1332L22.0001 12.6667L21.4729 13.2001ZM5.31794 16.6061C5.1004 16.2536 4.6383 16.1442 4.28581 16.3618C3.93331 16.5793 3.82391 17.0414 4.04144 17.3939L4.67969 17L5.31794 16.6061ZM11.8827 21V21.75C16.9451 21.75 21.0639 17.6915 21.0639 12.6667H20.3139H19.5639C19.5639 16.8466 16.1332 20.25 11.8827 20.25V21ZM20.3139 12.6667H21.0639V11H20.3139H19.5639V12.6667H20.3139ZM20.3139 11L19.7867 10.4666L18.1004 12.1333L18.6277 12.6667L19.1549 13.2001L20.8411 11.5334L20.3139 11ZM20.3139 11L19.7867 11.5334L21.4729 13.2001L22.0001 12.6667L22.5274 12.1332L20.8411 10.4666L20.3139 11ZM4.67969 17L4.04144 17.3939C5.65405 20.007 8.56403 21.75 11.8827 21.75V21V20.25C9.10023 20.25 6.66584 18.7903 5.31794 16.6061L4.67969 17Z\" fill=\"currentColor\"/> </svg>',\r\n search:\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M19 11.5a7.5 7.5 0 1 1-15 0a7.5 7.5 0 0 1 15 0m-2.107 5.42l3.08 3.08\"/></svg>',\r\n 'solar:arrow-left-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M20 12H4M10 18L4 12L10 6\"/></svg>',\r\n 'solar:check-circle-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM16.0303 8.96967C16.3232 9.26256 16.3232 9.73744 16.0303 10.0303L11.0303 15.0303C10.7374 15.3232 10.2626 15.3232 9.96967 15.0303L7.96967 13.0303C7.67678 12.7374 7.67678 12.2626 7.96967 11.9697C8.26256 11.6768 8.73744 11.6768 9.03033 11.9697L10.5 13.4393L12.7348 11.2045L14.9697 8.96967C15.2626 8.67678 15.7374 8.67678 16.0303 8.96967Z\" clip-rule=\"evenodd\"/></svg>',\r\n 'solar:danger-circle-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12ZM12 6.25C12.4142 6.25 12.75 6.58579 12.75 7V13C12.75 13.4142 12.4142 13.75 12 13.75C11.5858 13.75 11.25 13.4142 11.25 13V7C11.25 6.58579 11.5858 6.25 12 6.25ZM12 17C12.5523 17 13 16.5523 13 16C13 15.4477 12.5523 15 12 15C11.4477 15 11 15.4477 11 16C11 16.5523 11.4477 17 12 17Z\" clip-rule=\"evenodd\"/></svg>',\r\n 'solar:eye-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"currentColor\"><path d=\"M9.75 12C9.75 10.7574 10.7574 9.75 12 9.75C13.2426 9.75 14.25 10.7574 14.25 12C14.25 13.2426 13.2426 14.25 12 14.25C10.7574 14.25 9.75 13.2426 9.75 12Z\"/><path fill-rule=\"evenodd\" d=\"M2 12C2 13.6394 2.42496 14.1915 3.27489 15.2957C4.97196 17.5004 7.81811 20 12 20C16.1819 20 19.028 17.5004 20.7251 15.2957C21.575 14.1915 22 13.6394 22 12C22 10.3606 21.575 9.80853 20.7251 8.70433C19.028 6.49956 16.1819 4 12 4C7.81811 4 4.97196 6.49956 3.27489 8.70433C2.42496 9.80853 2 10.3606 2 12ZM12 8.25C9.92893 8.25 8.25 9.92893 8.25 12C8.25 14.0711 9.92893 15.75 12 15.75C14.0711 15.75 15.75 14.0711 15.75 12C15.75 9.92893 14.0711 8.25 12 8.25Z\" clip-rule=\"evenodd\"/></g></svg>',\r\n 'solar:gallery-add-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2\"/><path d=\"M2 12.5001L3.75159 10.9675C4.66286 10.1702 6.03628 10.2159 6.89249 11.0721L11.1822 15.3618C11.8694 16.0491 12.9512 16.1428 13.7464 15.5839L14.0446 15.3744C15.1888 14.5702 16.7369 14.6634 17.7765 15.599L21 18.5001\"/><path d=\"M15 5.5H18.5M18.5 5.5H22M18.5 5.5V9M18.5 5.5V2\"/></g></svg>',\r\n 'solar:hamburger-menu-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M20 7L4 7\"/><path d=\"M20 12L4 12\"/><path d=\"M20 17L4 17\"/></g></svg>',\r\n 'solar:lock-password-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M2 16C2 13.1716 2 11.7574 2.87868 10.8787C3.75736 10 5.17157 10 8 10H16C18.8284 10 20.2426 10 21.1213 10.8787C22 11.7574 22 13.1716 22 16C22 18.8284 22 20.2426 21.1213 21.1213C20.2426 22 18.8284 22 16 22H8C5.17157 22 3.75736 22 2.87868 21.1213C2 20.2426 2 18.8284 2 16Z\"/><path stroke-linecap=\"round\" d=\"M6 10V8C6 4.68629 8.68629 2 12 2C15.3137 2 18 4.68629 18 8V10\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 16H8.009M11.991 16H12M15.991 16H16\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 16H8.009M11.991 16H12M15.991 16H16\"/></g></svg>',\r\n 'solar:logout-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M12 20C7.58172 20 4 16.4183 4 12C4 7.58172 7.58172 4 12 4\"/><path stroke-linejoin=\"round\" d=\"M10 12H20M17 15L20 12L17 9\"/></g></svg>',\r\n 'solar:magnifer-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"11.5\" cy=\"11.5\" r=\"9.5\"/><path stroke-linecap=\"round\" d=\"M18.5 18.5L22 22\"/></g></svg>',\r\n 'solar:refresh-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"currentColor\"><path d=\"M12.0789 2.25C7.2854 2.25 3.34478 5.913 2.96055 10.5833H2.00002C1.69614 10.5833 1.42229 10.7667 1.30655 11.0477C1.19081 11.3287 1.25606 11.6517 1.47178 11.8657L3.15159 13.5324C3.444 13.8225 3.91567 13.8225 4.20808 13.5324L5.88789 11.8657C6.10361 11.6517 6.16886 11.3287 6.05312 11.0477C5.93738 10.7667 5.66353 10.5833 5.35965 10.5833H4.4668C4.84652 6.75167 8.10479 3.75 12.0789 3.75C14.8484 3.75 17.2727 5.20845 18.6156 7.39279C18.8325 7.74565 19.2944 7.85585 19.6473 7.63892C20.0002 7.42199 20.1104 6.96007 19.8934 6.60721C18.2871 3.99427 15.3873 2.25 12.0789 2.25Z\"/><path d=\"M20.8411 10.4666C20.549 10.1778 20.0789 10.1778 19.7867 10.4666L18.1005 12.1333C17.8841 12.3471 17.8184 12.6703 17.9339 12.9517C18.0495 13.233 18.3235 13.4167 18.6277 13.4167H19.5268C19.1455 17.2462 15.8759 20.25 11.8828 20.25C9.10026 20.25 6.66586 18.7903 5.31796 16.6061C5.10042 16.2536 4.63833 16.1442 4.28583 16.3618C3.93334 16.5793 3.82393 17.0414 4.04146 17.3939C5.65407 20.007 8.56406 21.75 11.8828 21.75C16.6906 21.75 20.6475 18.0892 21.0331 13.4167H22.0002C22.3043 13.4167 22.5783 13.233 22.6939 12.9517C22.8095 12.6703 22.7437 12.3471 22.5274 12.1333L20.8411 10.4666Z\"/></g></svg>',\r\n 'solar:trash-bin-trash-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"currentColor\"><path d=\"M3 6.38597C3 5.90152 3.34538 5.50879 3.77143 5.50879L6.43567 5.50832C6.96502 5.49306 7.43202 5.11033 7.61214 4.54412C7.61688 4.52923 7.62232 4.51087 7.64185 4.44424L7.75665 4.05256C7.8269 3.81241 7.8881 3.60318 7.97375 3.41617C8.31209 2.67736 8.93808 2.16432 9.66147 2.03297C9.84457 1.99972 10.0385 1.99986 10.2611 2.00002H13.7391C13.9617 1.99986 14.1556 1.99972 14.3387 2.03297C15.0621 2.16432 15.6881 2.67736 16.0264 3.41617C16.1121 3.60318 16.1733 3.81241 16.2435 4.05256L16.3583 4.44424C16.3778 4.51087 16.3833 4.52923 16.388 4.54412C16.5682 5.11033 17.1278 5.49353 17.6571 5.50879H20.2286C20.6546 5.50879 21 5.90152 21 6.38597C21 6.87043 20.6546 7.26316 20.2286 7.26316H3.77143C3.34538 7.26316 3 6.87043 3 6.38597Z\"/><path fill-rule=\"evenodd\" d=\"M11.5956 22.0001H12.4044C15.1871 22.0001 16.5785 22.0001 17.4831 21.1142C18.3878 20.2283 18.4803 18.7751 18.6654 15.8686L18.9321 11.6807C19.0326 10.1037 19.0828 9.31524 18.6289 8.81558C18.1751 8.31592 17.4087 8.31592 15.876 8.31592H8.12404C6.59127 8.31592 5.82488 8.31592 5.37105 8.81558C4.91722 9.31524 4.96744 10.1037 5.06788 11.6807L5.33459 15.8686C5.5197 18.7751 5.61225 20.2283 6.51689 21.1142C7.42153 22.0001 8.81289 22.0001 11.5956 22.0001ZM10.2463 12.1886C10.2051 11.7548 9.83753 11.4382 9.42537 11.4816C9.01321 11.525 8.71251 11.9119 8.75372 12.3457L9.25372 17.6089C9.29494 18.0427 9.66247 18.3593 10.0746 18.3159C10.4868 18.2725 10.7875 17.8856 10.7463 17.4518L10.2463 12.1886ZM14.5746 11.4816C14.9868 11.525 15.2875 11.9119 15.2463 12.3457L14.7463 17.6089C14.7051 18.0427 14.3375 18.3593 13.9254 18.3159C13.5132 18.2725 13.2125 17.8856 13.2537 17.4518L13.7537 12.1886C13.7949 11.7548 14.1625 11.4382 14.5746 11.4816Z\" clip-rule=\"evenodd\"/></g></svg>',\r\n 'solar:upload-minimalistic-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\"><path d=\"M3 15C3 17.8284 3 19.2426 3.87868 20.1213C4.75736 21 6.17157 21 9 21H15C17.8284 21 19.2426 21 20.1213 20.1213C21 19.2426 21 17.8284 21 15\"/><path d=\"M12 16V3M8 7.375L12 3L16 7.375\"/></g></svg>',\r\n 'solar:user-circle-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"12\" cy=\"9\" r=\"3\"/><circle cx=\"12\" cy=\"12\" r=\"10\"/><path stroke-linecap=\"round\" d=\"M17.9691 20C17.81 17.1085 16.9247 15 11.9999 15C7.07521 15 6.18991 17.1085 6.03076 20\"/></g></svg>',\r\n sparkles:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M10.5766 8.70419C11.2099 7.56806 11.5266 7 12 7C12.4734 7 12.7901 7.56806 13.4234 8.70419L13.5873 8.99812C13.7672 9.32097 13.8572 9.48239 13.9975 9.5889C14.1378 9.69541 14.3126 9.73495 14.6621 9.81402L14.9802 9.88601C16.2101 10.1643 16.825 10.3034 16.9713 10.7739C17.1176 11.2443 16.6984 11.7345 15.86 12.715L15.643 12.9686C15.4048 13.2472 15.2857 13.3865 15.2321 13.5589C15.1785 13.7312 15.1965 13.9171 15.2325 14.2888L15.2653 14.6272C15.3921 15.9353 15.4554 16.5894 15.0724 16.8801C14.6894 17.1709 14.1137 16.9058 12.9622 16.3756L12.6643 16.2384C12.337 16.0878 12.1734 16.0124 12 16.0124C11.8266 16.0124 11.663 16.0878 11.3357 16.2384L11.0378 16.3756C9.88634 16.9058 9.31059 17.1709 8.92757 16.8801C8.54456 16.5894 8.60794 15.9353 8.7347 14.6272L8.76749 14.2888C8.80351 13.9171 8.82152 13.7312 8.76793 13.5589C8.71434 13.3865 8.59521 13.2472 8.35696 12.9686L8.14005 12.715C7.30162 11.7345 6.88241 11.2443 7.02871 10.7739C7.17501 10.3034 7.78993 10.1643 9.01977 9.88601L9.33794 9.81402C9.68743 9.73495 9.86217 9.69541 10.0025 9.5889C10.1428 9.48239 10.2328 9.32097 10.4127 8.99812L10.5766 8.70419Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 2V4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M12 20V22\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M2 12L4 12\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M20 12L22 12\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M6 18L6.34305 17.657\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M17.6567 6.34326L18 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M18 18L17.657 17.657\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M6.34326 6.34326L6 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> </svg>',\r\n star: '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M9.15316 5.40838C10.4198 3.13613 11.0531 2 12 2C12.9469 2 13.5802 3.13612 14.8468 5.40837L15.1745 5.99623C15.5345 6.64193 15.7144 6.96479 15.9951 7.17781C16.2757 7.39083 16.6251 7.4699 17.3241 7.62805L17.9605 7.77203C20.4201 8.32856 21.65 8.60682 21.9426 9.54773C22.2352 10.4886 21.3968 11.4691 19.7199 13.4299L19.2861 13.9372C18.8096 14.4944 18.5713 14.773 18.4641 15.1177C18.357 15.4624 18.393 15.8341 18.465 16.5776L18.5306 17.2544C18.7841 19.8706 18.9109 21.1787 18.1449 21.7602C17.3788 22.3417 16.2273 21.8115 13.9243 20.7512L13.3285 20.4768C12.6741 20.1755 12.3469 20.0248 12 20.0248C11.6531 20.0248 11.3259 20.1755 10.6715 20.4768L10.0757 20.7512C7.77268 21.8115 6.62118 22.3417 5.85515 21.7602C5.08912 21.1787 5.21588 19.8706 5.4694 17.2544L5.53498 16.5776C5.60703 15.8341 5.64305 15.4624 5.53586 15.1177C5.42868 14.773 5.19043 14.4944 4.71392 13.9372L4.2801 13.4299C2.60325 11.4691 1.76482 10.4886 2.05742 9.54773C2.35002 8.60682 3.57986 8.32856 6.03954 7.77203L6.67589 7.62805C7.37485 7.4699 7.72433 7.39083 8.00494 7.17781C8.28555 6.96479 8.46553 6.64194 8.82547 5.99623L9.15316 5.40838Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> </svg>',\r\n user: '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"6\" r=\"4\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M20 17.5C20 19.9853 20 22 12 22C4 22 4 19.9853 4 17.5C4 15.0147 7.58172 13 12 13C16.4183 13 20 15.0147 20 17.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> </svg>',\r\n};\r\n","import { InjectionToken, Injectable, Provider, inject } from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { Observable, from, of } from 'rxjs';\r\nimport { catchError, map, shareReplay, tap } from 'rxjs/operators';\r\nimport { ICON_ALIASES } from './icon-aliases';\r\nimport { CORE_ICONS } from './core.icons';\r\n\r\n/**\r\n * Icon nơi dùng tự đăng ký — tên → SVG. Xem `provideOlIcons`.\r\n */\r\nexport const OL_ICONS = new InjectionToken<ReadonlyArray<Record<string, string>>>('OL_ICONS');\r\n\r\n/**\r\n * Đăng ký icon import RIÊNG TỪNG CÁI — cách dùng tree-shake được.\r\n *\r\n * \\`\\`\\`ts\r\n * import { provideOlIcons } from '@edmicro/olkit-icons';\r\n * import { SOLAR_HOME_2_LINEAR } from '@edmicro/olkit-icons/collections/solar/home_2_linear';\r\n *\r\n * bootstrapApplication(App, {\r\n * providers: [provideOlIcons({ 'solar:home-2-linear': SOLAR_HOME_2_LINEAR })],\r\n * });\r\n * \\`\\`\\`\r\n *\r\n * Bundler chỉ giữ đúng các hằng được import (~2-5 KB/icon).\r\n */\r\nexport function provideOlIcons(icons: Record<string, string>): Provider[] {\r\n return [{ provide: OL_ICONS, useValue: icons, multi: true }];\r\n}\r\n\r\n/**\r\n * Đăng ký icon theo TÊN - chỉ cần string, không cần import constants.\r\n *\r\n * ```ts\r\n * import { provideOlIconsByName } from '@edmicro/olkit-icons';\r\n *\r\n * @Component({\r\n * providers: [\r\n * provideOlIconsByName([['solar:home-2-linear'], ['olkit:logo']])\r\n * ],\r\n * })\r\n * ```\r\n *\r\n * **QUAN TRỌNG:** Để bundle size tối ưu (~2-5 KB/icon), phải dùng esbuild plugin.\r\n * Plugin sẽ tự động transform call này thành `provideOlIcons()` với direct imports.\r\n * Xem README để setup plugin trong angular.json.\r\n * \r\n * Nếu không dùng plugin, function này sẽ không làm gì (icons không load).\r\n */\r\nexport function provideOlIconsByName(iconNames: string[][]): Provider[] {\r\n if (typeof window !== 'undefined') {\r\n console.warn(\r\n '[olkit-icons] provideOlIconsByName requires esbuild plugin to work. ' +\r\n 'Add plugin to angular.json. See README for setup instructions.'\r\n );\r\n }\r\n return [];\r\n}\r\n\r\n/**\r\n * Service quản lý icons cho Ôn Luyện Design System.\r\n * \r\n * Icons được đăng ký qua `provideOlIcons()` hoặc `provideOlIconsByName()` (với esbuild plugin).\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class OlIconService {\r\n private readonly sanitizer = inject(DomSanitizer);\r\n private readonly cache = new Map<string, SafeHtml>();\r\n\r\n /** Icon đăng ký qua `provideOlIcons` / `register` — tên đã chuẩn hoá → SVG. */\r\n private readonly registered = new Map<string, string>();\r\n\r\n constructor() {\r\n for (const group of inject(OL_ICONS, { optional: true }) ?? []) this.register(group);\r\n }\r\n\r\n /**\r\n * Đăng ký icon lúc chạy — cùng tác dụng với `provideOlIcons`, cho nơi cần\r\n * thêm icon sau khi ứng dụng đã khởi động. Tên trùng thì bản sau thắng.\r\n */\r\n register(icons: Record<string, string>): void {\r\n for (const [name, svg] of Object.entries(icons)) {\r\n const norm = name.trim().toLowerCase();\r\n this.registered.set(norm, svg);\r\n // Xoá cache của tên này: đăng ký lại phải vẽ theo SVG mới.\r\n for (const key of [...this.cache.keys()]) {\r\n if (key.endsWith(`:${this.aliasMap[norm] || norm}`)) this.cache.delete(key);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Lấy SVG SafeHtml sync (chỉ trả icon đã load trong cache hoặc core icons)\r\n * Không load registry - dùng getIcon() cho async loading\r\n */\r\n getIconSync(name: string, variant: string = 'linear'): SafeHtml | null {\r\n if (typeof name !== 'string' || !name.trim()) return null;\r\n\r\n const key = this.normalizeKey(name, variant);\r\n\r\n // Check cache first\r\n if (this.cache.has(key)) {\r\n return this.cache.get(key)!;\r\n }\r\n\r\n const trimmed = name.trim().toLowerCase();\r\n\r\n // 1. Tra cứu trực tiếp trong CORE_ICONS theo tên truyền vào (đường dẫn đồng bộ nhanh nhất cho icon lõi: chevron-down, list, close, check, v.v.)\r\n if (trimmed in CORE_ICONS) {\r\n const svg = CORE_ICONS[trimmed as keyof typeof CORE_ICONS];\r\n const cleaned = this.cleanSvg(svg);\r\n const safe = this.sanitizer.bypassSecurityTrustHtml(cleaned);\r\n this.cache.set(key, safe);\r\n return safe;\r\n }\r\n\r\n // Auto-add olkit: prefix nếu không có collection prefix\r\n const normName = trimmed.includes(':') ? trimmed : `olkit:${trimmed}`;\r\n let resolvedName = this.aliasMap[trimmed] || this.aliasMap[normName] || normName;\r\n if (!resolvedName.includes(':')) {\r\n resolvedName = `olkit:${resolvedName}`;\r\n }\r\n\r\n // Check directly registered icons (from provideOlIcons)\r\n const registered =\r\n this.registered.get(resolvedName) ??\r\n this.registered.get(normName) ??\r\n this.registered.get(trimmed);\r\n if (registered) {\r\n const cleaned = this.cleanSvg(registered);\r\n const safe = this.sanitizer.bypassSecurityTrustHtml(cleaned);\r\n this.cache.set(key, safe);\r\n return safe;\r\n }\r\n\r\n // Check core icons theo resolvedName hoặc normName\r\n if (resolvedName in CORE_ICONS) {\r\n const svg = CORE_ICONS[resolvedName as keyof typeof CORE_ICONS];\r\n const cleaned = this.cleanSvg(svg);\r\n const safe = this.sanitizer.bypassSecurityTrustHtml(cleaned);\r\n this.cache.set(key, safe);\r\n return safe;\r\n }\r\n if (normName in CORE_ICONS) {\r\n const svg = CORE_ICONS[normName as keyof typeof CORE_ICONS];\r\n const cleaned = this.cleanSvg(svg);\r\n const safe = this.sanitizer.bypassSecurityTrustHtml(cleaned);\r\n this.cache.set(key, safe);\r\n return safe;\r\n }\r\n\r\n // Try loaded registries synchronously (for icons already in memory)\r\n return null;\r\n }\r\n\r\n /** Cache registry loaders để tránh load lại */\r\n private registryLoaders = new Map<string, Observable<void>>();\r\n\r\n /**\r\n * Load registry từ grouped registry file và register tất cả icons của collection\r\n * Chỉ dùng trong docs app để load icons động cho icon picker\r\n * User projects KHÔNG nên dùng (dùng provideOlIcons với manual imports)\r\n */\r\n loadRegistry(collection: 'solar' | 'lucide' | 'mynaui' | 'olkit'): Observable<void> {\r\n // Check cache first\r\n if (this.registryLoaders.has(collection)) {\r\n return this.registryLoaders.get(collection)!;\r\n }\r\n\r\n // Load registry file với static import path\r\n const loader$ = from(\r\n (async () => {\r\n let registry: any;\r\n switch (collection) {\r\n case 'solar':\r\n registry = await import('./registries/solar.registry');\r\n break;\r\n case 'lucide':\r\n registry = await import('./registries/lucide.registry');\r\n break;\r\n case 'mynaui':\r\n registry = await import('./registries/mynaui.registry');\r\n break;\r\n case 'olkit':\r\n registry = await import('./registries/olkit.registry');\r\n break;\r\n }\r\n const icons = registry['_REGISTRY'];\r\n if (!icons) {\r\n throw new Error(`Registry ${collection} does not export _REGISTRY`);\r\n }\r\n console.log(`[OlIconService] Registering ${Object.keys(icons).length} icons from ${collection}`);\r\n this.register(icons);\r\n console.log(`[OlIconService] Successfully registered ${collection} registry`);\r\n })()\r\n ).pipe(\r\n catchError((err) => {\r\n console.error(`[OlIconService] Failed to load registry ${collection}:`, err);\r\n return of(void 0);\r\n }),\r\n shareReplay(1)\r\n );\r\n\r\n this.registryLoaders.set(collection, loader$);\r\n return loader$;\r\n }\r\n\r\n /**\r\n * Lấy SVG SafeHtml cho icon theo tên và biến thể\r\n * Tự động load registry nếu icon chưa có (dùng trong docs app)\r\n */\r\n getIcon(name: string, variant: string = 'linear'): Observable<SafeHtml | null> {\r\n if (typeof name !== 'string' || !name.trim()) return of(null);\r\n\r\n // Try sync first\r\n const sync = this.getIconSync(name, variant);\r\n if (sync) return of(sync);\r\n\r\n // Auto-add olkit: prefix nếu không có collection prefix\r\n const trimmed = name.trim().toLowerCase();\r\n const normName = trimmed.includes(':') ? trimmed : `olkit:${trimmed}`;\r\n let resolvedName = this.aliasMap[trimmed] || this.aliasMap[normName] || normName;\r\n if (!resolvedName.includes(':')) {\r\n resolvedName = `olkit:${resolvedName}`;\r\n }\r\n\r\n // Extract collection từ resolved name (e.g., \"solar:home-2-linear\" → \"solar\", \"olkit:book\" → \"olkit\")\r\n const [collection] = resolvedName.split(':');\r\n if (!collection || !['solar', 'lucide', 'mynaui', 'olkit'].includes(collection)) {\r\n return of(null);\r\n }\r\n\r\n // Load registry và retry\r\n return this.loadRegistry(collection as any).pipe(\r\n map(() => this.getIconSync(name, variant))\r\n );\r\n }\r\n\r\n /** Bảng bí danh — xem `icon-aliases.ts` (dùng chung với script sinh bộ lõi). */\r\n private readonly aliasMap = ICON_ALIASES;\r\n\r\n private normalizeKey(name: string, variant?: string): string {\r\n const v = variant || 'linear';\r\n const trimmed = name.trim().toLowerCase();\r\n if (trimmed in CORE_ICONS) {\r\n return `${v}:${trimmed}`;\r\n }\r\n const withPrefix = trimmed.includes(':') ? trimmed : `olkit:${trimmed}`;\r\n let resolvedName = this.aliasMap[trimmed] || this.aliasMap[withPrefix] || withPrefix;\r\n if (!resolvedName.includes(':')) {\r\n resolvedName = `olkit:${resolvedName}`;\r\n }\r\n return `${v}:${resolvedName}`;\r\n }\r\n\r\n private cleanSvg(svgText: string): string {\r\n let cleaned = svgText.trim();\r\n\r\n // 1. Chuẩn hóa thẻ <svg>: bỏ width/height cố định để scale vector mượt mà theo CSS\r\n cleaned = cleaned.replace(/<svg\\s+([^>]*?)>/i, (match, attrs) => {\r\n // Giữ viewBox, bỏ width và height tĩnh nếu có\r\n let newAttrs = attrs\r\n .replace(/\\bwidth=\"[^\"]*\"/gi, '')\r\n .replace(/\\bheight=\"[^\"]*\"/gi, '')\r\n .trim();\r\n\r\n if (!newAttrs.includes('class=')) {\r\n newAttrs += ' class=\"w-full h-full block\"';\r\n }\r\n if (!newAttrs.includes('shape-rendering=')) {\r\n newAttrs += ' shape-rendering=\"geometricPrecision\"';\r\n }\r\n return `<svg ${newAttrs}>`;\r\n });\r\n\r\n // 2. Chuyển đổi stroke và fill cứng sang currentColor\r\n // Detect multicolor: gradient, url patterns, hoặc nhiều màu fill/stroke khác nhau\r\n const fillColors = cleaned.match(/fill=\"#[0-9a-fA-F]{3,8}\"/gi) || [];\r\n const strokeColors = cleaned.match(/stroke=\"#[0-9a-fA-F]{3,8}\"/gi) || [];\r\n const uniqueFills = new Set(fillColors.map((f) => f.toLowerCase()));\r\n const uniqueStrokes = new Set(strokeColors.map((s) => s.toLowerCase()));\r\n\r\n const isSpecialMulticolor =\r\n cleaned.includes('url(#') ||\r\n cleaned.includes('linearGradient') ||\r\n cleaned.includes('radialGradient') ||\r\n uniqueFills.size > 1 || // Nhiều màu fill khác nhau\r\n uniqueStrokes.size > 1; // Nhiều màu stroke khác nhau\r\n\r\n if (!isSpecialMulticolor) {\r\n // Convert all stroke=\"#...\" to stroke=\"currentColor\"\r\n cleaned = cleaned.replace(/stroke=\"#[0-9a-fA-F]{3,8}\"/gi, 'stroke=\"currentColor\"');\r\n // Convert all fill=\"#...\" to fill=\"currentColor\" (for monochrome icons)\r\n cleaned = cleaned.replace(/fill=\"#[0-9a-fA-F]{3,8}\"/gi, 'fill=\"currentColor\"');\r\n }\r\n\r\n return cleaned;\r\n }\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n signal,\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { SafeHtml } from '@angular/platform-browser';\r\nimport { OlIconService } from './icon.service';\r\n\r\n/**\r\n * Icon nhiều màu — không được áp class màu đè lên.\r\n * Nguồn: src/assets/iconify/olkit/catalog.json (metadata.isMulticolor).\r\n * Chỉ 11 icon nên nhúng thẳng, thay cho icon-metadata.ts 2,4 MB vốn sinh\r\n * hỏng: 443 mục olkit có isMulticolor nhưng bản TS mất sạch (0/10.860).\r\n */\r\nconst MULTICOLOR_ICONS = new Set<string>([\r\n '3d',\r\n 'audio',\r\n 'docx',\r\n 'onluyen-ai',\r\n 'onluyen-logo',\r\n 'pdf',\r\n 'photo',\r\n 'pptx',\r\n 'video',\r\n 'xlsx',\r\n 'zip',\r\n]);\r\n\r\nexport type IconSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | number;\r\nexport type IconColor =\r\n | 'current'\r\n | 'brand'\r\n | 'primary'\r\n | 'secondary'\r\n | 'success'\r\n | 'danger'\r\n | 'warning'\r\n | 'white'\r\n | 'muted'\r\n | string;\r\n\r\nexport type IconVariant =\r\n 'linear' | 'bold' | 'line-duotone' | 'file-type' | 'brand' | 'custom' | string;\r\n\r\n@Component({\r\n selector: 'ol-icon',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n @if (svgContent(); as svg) {\r\n <span\r\n [class]=\"containerClasses()\"\r\n [style.width]=\"customPixelSize()\"\r\n [style.height]=\"customPixelSize()\"\r\n [style.stroke-width]=\"strokeWidth()\"\r\n [style.color]=\"isCustomColor() ? color() : null\"\r\n [innerHTML]=\"svg\"\r\n ></span>\r\n } @else {\r\n <!-- Fallback / Loading placeholder -->\r\n <span\r\n [class]=\"containerClasses()\"\r\n [style.width]=\"customPixelSize()\"\r\n [style.height]=\"customPixelSize()\"\r\n [style.color]=\"isCustomColor() ? color() : null\"\r\n ></span>\r\n }\r\n `,\r\n styles: [\r\n `\r\n :host {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n vertical-align: middle;\r\n line-height: 1;\r\n flex-shrink: 0;\r\n }\r\n :host ::ng-deep svg {\r\n width: 100%;\r\n height: 100%;\r\n display: block;\r\n shape-rendering: geometricPrecision;\r\n text-rendering: geometricPrecision;\r\n }\r\n `,\r\n ],\r\n host: {\r\n class: 'inline-flex items-center justify-center shrink-0 leading-none align-middle',\r\n },\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class OlIcon {\r\n private readonly iconService = inject(OlIconService);\r\n\r\n readonly name = input.required<string>();\r\n readonly size = input<IconSize>('base');\r\n readonly color = input<IconColor>('current');\r\n readonly variant = input<IconVariant>('linear');\r\n readonly strokeWidth = input<string | number | null>(null);\r\n\r\n private readonly asyncSvg = signal<SafeHtml | null>(null);\r\n\r\n readonly svgContent = computed<SafeHtml | null>(() => {\r\n const n = this.name();\r\n const v = this.variant();\r\n const sync = this.iconService.getIconSync(n, v);\r\n if (sync) return sync;\r\n return this.asyncSvg();\r\n });\r\n\r\n constructor() {\r\n effect(() => {\r\n const n = this.name();\r\n const v = this.variant();\r\n const sync = this.iconService.getIconSync(n, v);\r\n if (!sync) {\r\n this.asyncSvg.set(null);\r\n this.iconService.getIcon(n, v).subscribe((svg) => {\r\n this.asyncSvg.set(svg);\r\n });\r\n }\r\n });\r\n }\r\n\r\n readonly isNumericSize = computed(() => {\r\n const sz = this.size();\r\n return typeof sz === 'number';\r\n });\r\n\r\n readonly customPixelSize = computed(() => {\r\n const sz = this.size();\r\n if (typeof sz === 'number') {\r\n return `${sz}px`;\r\n }\r\n return null;\r\n });\r\n\r\n readonly sizeClasses = computed(() => {\r\n if (this.isNumericSize()) return '';\r\n\r\n switch (this.size()) {\r\n case 'xs':\r\n return 'w-3.5 h-3.5';\r\n case 'sm':\r\n return 'w-4 h-4';\r\n case 'base':\r\n return 'w-5 h-5';\r\n case 'lg':\r\n return 'w-6 h-6';\r\n case 'xl':\r\n return 'w-8 h-8';\r\n case '2xl':\r\n return 'w-10 h-10';\r\n case '3xl':\r\n return 'w-12 h-12';\r\n default:\r\n return 'w-5 h-5';\r\n }\r\n });\r\n\r\n readonly isCustomColor = computed(() => {\r\n const c = this.color();\r\n return (\r\n typeof c === 'string' && (c.startsWith('#') || c.startsWith('rgb') || c.startsWith('hsl'))\r\n );\r\n });\r\n\r\n readonly isMulticolor = computed(() => {\r\n const n = this.name();\r\n if (!n) return false;\r\n return MULTICOLOR_ICONS.has(\r\n n\r\n .trim()\r\n .toLowerCase()\r\n .replace(/^olkit:/, ''),\r\n );\r\n });\r\n\r\n readonly colorClasses = computed(() => {\r\n if (this.isMulticolor() || this.isCustomColor()) return '';\r\n\r\n switch (this.color()) {\r\n case 'current':\r\n return 'text-current';\r\n case 'white':\r\n return 'text-white';\r\n case 'primary':\r\n return 'text-heading';\r\n case 'secondary':\r\n return 'text-body';\r\n // Token fg-* tự đổi theo chế độ sáng/tối nên không cần cặp `dark:` viết tay.\r\n case 'brand':\r\n return 'text-fg-brand';\r\n case 'muted':\r\n return 'text-fg-disabled';\r\n case 'success':\r\n return 'text-fg-success';\r\n case 'danger':\r\n return 'text-fg-danger';\r\n case 'warning':\r\n return 'text-fg-warning';\r\n case 'purple':\r\n return 'text-fg-purple';\r\n case 'pink':\r\n return 'text-fg-pink';\r\n case 'cyan':\r\n return 'text-fg-cyan';\r\n case 'indigo':\r\n return 'text-fg-indigo';\r\n default: {\r\n // `isCustomColor()` đã loại `typeof c !== 'string'`, nên `undefined`\r\n // rơi thẳng xuống đây và `.startsWith` ném TypeError. `input()` có mặc\r\n // định KHÔNG chặn được undefined lúc chạy khi nơi gọi bind biểu thức.\r\n const c = this.color();\r\n return typeof c === 'string' && c.startsWith('text-') ? c : 'text-current';\r\n }\r\n }\r\n });\r\n\r\n readonly containerClasses = computed(() => {\r\n return `inline-flex items-center justify-center shrink-0 ${this.sizeClasses()} ${this.colorClasses()}`;\r\n });\r\n}\r\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { OlIcon } from '../icon/icon.component';\r\n\r\nexport type IconShapeSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl';\r\nexport type IconShapeColor = 'brand' | 'white' | 'dark' | 'red' | 'gray' | 'green' | 'yellow';\r\nexport type IconShapeType = 'circle' | 'square';\r\n\r\n@Component({\r\n selector: 'ol-icon-shape',\r\n standalone: true,\r\n imports: [CommonModule, OlIcon],\r\n templateUrl: './icon-shape.component.html',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class OlIconShape {\r\n readonly icon = input<string>('');\r\n readonly size = input<IconShapeSize>('base');\r\n readonly color = input<IconShapeColor>('brand');\r\n readonly type = input<IconShapeType>('circle');\r\n\r\n readonly iconSize = computed<number>(() => {\r\n switch (this.size()) {\r\n case 'xs':\r\n return 10;\r\n case 'sm':\r\n return 16;\r\n case 'base':\r\n return 20;\r\n case 'lg':\r\n return 28;\r\n case 'xl':\r\n return 36;\r\n case '2xl':\r\n return 56;\r\n default:\r\n return 20;\r\n }\r\n });\r\n}\r\n","<!-- Figma ol-icon-shape (#1149:56578): cả White và Gray dùng text-body.\r\n Hai [class.text-body] riêng sẽ bị Angular gộp làm một binding và cái sau\r\n thắng, nên phải gộp điều kiện bằng ||.\r\n\r\n Bo góc: đọc đủ 84 variant Figma — Square bo 12px ở MỌI size, Circle luôn\r\n tròn. Không có thang bo góc nào. Sáu dòng cũ khai ba [class.rounded-md]\r\n trùng tên nên Angular chỉ giữ dòng cuối; `sm` và `lg` mất bo góc hoàn toàn\r\n (đo ra 0px). Chú thích phải nằm NGOÀI thẻ mở — đặt giữa danh sách thuộc\r\n tính là hỏng build. -->\r\n<div\r\n class=\"inline-flex items-center justify-center shrink-0 leading-none select-none\"\r\n [class.rounded-full]=\"type() === 'circle'\"\r\n [class.rounded-md]=\"type() === 'square'\"\r\n [class.w-4]=\"size() === 'xs'\"\r\n [class.h-4]=\"size() === 'xs'\"\r\n [class.w-6]=\"size() === 'sm'\"\r\n [class.h-6]=\"size() === 'sm'\"\r\n [class.w-9]=\"size() === 'base'\"\r\n [class.h-9]=\"size() === 'base'\"\r\n [class.w-12]=\"size() === 'lg'\"\r\n [class.h-12]=\"size() === 'lg'\"\r\n [class.w-16]=\"size() === 'xl'\"\r\n [class.h-16]=\"size() === 'xl'\"\r\n [class.w-24]=\"size() === '2xl'\"\r\n [class.h-24]=\"size() === '2xl'\"\r\n [class.bg-brand-softer]=\"color() === 'brand'\"\r\n [class.text-fg-brand]=\"color() === 'brand'\"\r\n [class.bg-neutral-primary-medium]=\"color() === 'white'\"\r\n [class.border]=\"color() === 'white'\"\r\n [class.border-default-medium]=\"color() === 'white'\"\r\n [class.bg-dark]=\"color() === 'dark'\"\r\n [class.text-white]=\"color() === 'dark'\"\r\n [class.bg-danger-soft]=\"color() === 'red'\"\r\n [class.text-fg-danger-strong]=\"color() === 'red'\"\r\n [class.bg-neutral-tertiary]=\"color() === 'gray'\"\r\n [class.text-body]=\"color() === 'white' || color() === 'gray'\"\r\n [class.bg-success-soft]=\"color() === 'green'\"\r\n [class.text-fg-success-strong]=\"color() === 'green'\"\r\n [class.bg-warning-soft]=\"color() === 'yellow'\"\r\n [class.text-fg-warning]=\"color() === 'yellow'\"\r\n>\r\n @if (icon()) {\r\n <ol-icon [name]=\"icon()\" [size]=\"iconSize()\" />\r\n } @else {\r\n <ng-content />\r\n }\r\n</div>\r\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\r\n\r\nexport type OlIconStackSize = 'sm' | 'base' | 'lg';\r\n\r\n/**\r\n * Chồng nhiều icon hoặc logo lên nhau, kèm số đếm \"+N\".\r\n *\r\n * Chưa có node Figma — dựng theo `ol-avatar-group`, component cùng cơ chế đã\r\n * có trong thư viện. Khác ở chỗ: avatar là ảnh người nên luôn tròn, còn icon\r\n * thường là biểu tượng dịch vụ hay môn học nên mặc định bo vừa (`rounded-lg`)\r\n * và có nền để icon một màu vẫn tách khỏi icon bên dưới.\r\n *\r\n * ## Vòng viền là thứ làm nên hiệu ứng chồng\r\n *\r\n * Mỗi ô có `ring-2 ring-buffer` — vòng viền màu nền trang, không phải viền\r\n * màu. Nhờ nó hai ô chồng nhau vẫn thấy rõ ranh giới. Bỏ vòng này thì các ô\r\n * dính thành một khối nhoè.\r\n *\r\n * `ring-buffer` chứ không `ring-white`: ở chế độ tối nền không phải trắng, và\r\n * viền trắng trên nền đen là đường kẻ sáng chói quanh mỗi icon.\r\n *\r\n * ## Thứ tự chồng\r\n *\r\n * Mặc định ô ĐẦU nằm trên — giống xếp bài. `reverse` lật lại cho ô cuối nằm\r\n * trên, dùng khi ô cuối là thứ cần nhấn (icon \"thêm\", trạng thái mới nhất).\r\n *\r\n * Làm bằng `flex-row-reverse` cộng đảo thứ tự dữ liệu chứ không bằng\r\n * `z-index`: `z-index` cần stacking context và sẽ hỏng khi nơi gọi đặt\r\n * component vào một phần tử có `transform` hay `opacity`.\r\n */\r\n@Component({\r\n selector: 'ol-icon-stack',\r\n standalone: true,\r\n template: `\r\n <div [class]=\"rootClasses()\">\r\n <ng-content />\r\n\r\n @if (counter()) {\r\n <!-- Xem chú thích counterClasses() về lựa chọn màu chữ. -->\r\n <span [class]=\"counterClasses()\" [attr.aria-label]=\"counterAriaLabel()\">\r\n {{ counter() }}\r\n </span>\r\n }\r\n </div>\r\n `,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: { class: 'inline-block' },\r\n})\r\nexport class OlIconStack {\r\n readonly size = input<OlIconStackSize>('base');\r\n\r\n /** Số đếm \"+N\" ở cuối. `null` thì không vẽ. */\r\n readonly counter = input<string | number | null>(null);\r\n\r\n readonly counterAriaLabel = input<string>('mục khác');\r\n\r\n /** Lật thứ tự chồng: ô CUỐI nằm trên thay vì ô đầu. */\r\n readonly reverse = input<boolean>(false);\r\n\r\n /**\r\n * Bo góc của từng ô. `full` cho logo tròn, `lg` cho biểu tượng vuông.\r\n *\r\n * Áp lên CON qua biến thể `*:` của Tailwind, nên nơi gọi chỉ việc đặt\r\n * `<ol-icon>` hay `<img>` vào là xong.\r\n */\r\n readonly rounded = input<'lg' | 'full'>('lg');\r\n\r\n protected readonly rootClasses = computed(() => {\r\n const gap = { sm: '-space-x-1.5', base: '-space-x-2', lg: '-space-x-2.5' }[this.size() as OlIconStackSize];\r\n const box = { sm: '*:size-6', base: '*:size-8', lg: '*:size-10' }[this.size() as OlIconStackSize];\r\n const radius = this.rounded() === 'full' ? '*:rounded-full' : '*:rounded-lg';\r\n const dir = this.reverse() ? 'flex-row-reverse space-x-reverse' : '';\r\n\r\n return [\r\n 'flex items-center',\r\n gap,\r\n dir,\r\n // Vòng viền màu nền trang tạo ranh giới giữa hai ô chồng nhau.\r\n `${box} ${radius} *:shrink-0 *:ring-2 *:ring-buffer *:bg-neutral-secondary`,\r\n '*:flex *:items-center *:justify-center *:text-body-subtle',\r\n ].join(' ');\r\n });\r\n\r\n /**\r\n * Ô đếm \"+N\".\r\n *\r\n * `text-heading` chứ KHÔNG `text-body`: tổ hợp `bg-neutral-quaternary` +\r\n * `text-body` đo được 6.10 ở chế độ sáng nhưng chỉ 3.96 ở chế độ tối — dưới\r\n * ngưỡng WCAG 4.5. Đây là kết luận đã đo ở `ol-avatar-group` (BUG-016 mục 5),\r\n * theo tiền lệ sẵn có chứ không đoán lại.\r\n *\r\n * Chú thích để Ở ĐÂY chứ không trong template: template là một chuỗi\r\n * template literal, nên dấu backtick trong chú thích HTML đóng chuỗi sớm và\r\n * TS báo lỗi ở dòng chẳng liên quan (đã mắc khi viết file này).\r\n */\r\n protected readonly counterClasses = computed(() => {\r\n const font = { sm: 'text-2xs', base: 'text-xs', lg: 'text-sm' }[this.size() as OlIconStackSize];\r\n return `font-medium bg-neutral-quaternary text-heading select-none ${font}`;\r\n });\r\n}\r\n"],"mappings":";;;;;;AAOA,MAAa,eAAiD;CAc5D,OAAO;CAmBP,OAAO;CACP,GAAG;CAEH,OAAO;CAcP,MAAM;CACN,MAAM;CACN,OAAO;CACP,eAAe;CACf,OAAO;CACP,aAAa;CACb,iBAAiB;CACjB,mBAAmB;CACnB,uBAAuB;CACvB,cAAc;CACd,cAAc;CACd,UAAU;CACV,eAAe;CACf,SAAS;CACT,cAAc;CACd,aAAa;CACb,MAAM;CACN,SAAS;CACT,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,WAAW;CACX,kBAAkB;CAClB,cAAc;CACd,gBAAgB;CAChB,0BAA0B;CAC1B,wBAAwB;CACxB,gBAAgB;CAChB,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB;CACjB,cAAc;CACd,cAAc;CACd,eAAe;CACf,0BAA0B;CAC1B,iBAAiB;CACjB,iBAAiB;CACjB,SAAS;CACT,iBAAiB;CACjB,gBAAgB;CAChB,eAAe;CACf,oBAAoB;CACpB,mBAAmB;CACnB,UAAU;CACV,QAAQ;CACR,oBAAoB;CACpB,cAAc;CACd,gBAAgB;CAChB,oBAAoB;CACpB,iBAAiB;CACjB,oBAAoB;CACpB,cAAc;CACd,cAAc;CACd,YAAY;CACZ,kBAAkB;CAClB,UAAU;CACV,gBAAgB;CAChB,gBAAgB;CAChB,YAAY;CACZ,WAAW;CACX,aAAa;CACb,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,aAAa;AACd;ACjHD,MAAa,aAA+C;CAC1D,kBACE;CACF,kBACE;CACF,mBACE;CACF,cACE;CACF,eACE;CACF,UACE;CACF,gBACE;CACF,OACE;CACF,gBACE;CACF,gBACE;CACF,gBACE;CACF,iBACE;CACF,gBACE;CACF,OACE;CACF,gBACE;CACF,iBACE;CACF,mBACE;CACF,UACE;CACF,eACE;CACF,MAAM;CACN,MAAM;CACN,eACE;CACF,eACE;CACF,eACE;CACF,uBACE;CACF,oBACE;CACF,qBACE;CACF,qBACE;CACF,2BACE;CACF,oBACE;CACF,oBACE;CACF,4BACE;CACF,iBACE;CACF,eACE;CACF,uBA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"}
1
+ {"version":3,"file":"edmicro-olkit-icons.mjs","names":[],"sources":["../../../projects/olkit-icons/src/lib/icon/icon-aliases.ts","../../../projects/olkit-icons/src/lib/icon/core.icons.ts","../../../projects/olkit-icons/src/lib/icon/icon.service.ts","../../../projects/olkit-icons/src/lib/icon/icon.component.ts","../../../projects/olkit-icons/src/lib/icon-shape/icon-shape.component.ts","../../../projects/olkit-icons/src/lib/icon-shape/icon-shape.component.html","../../../projects/olkit-icons/src/lib/icon-stack/icon-stack.component.ts"],"sourcesContent":["/**\r\n * Bí danh tên icon → tên chuẩn trong registry.\r\n *\r\n * Tách khỏi `OlIconService` để `scripts/gen-core-icons.mjs` tra tên ĐÚNG như\r\n * service tra lúc chạy khi sinh bộ lõi (`core.icons.ts`). Hai nơi giữ hai bản\r\n * là hai bản sẽ lệch nhau.\r\n */\r\nexport const ICON_ALIASES: Readonly<Record<string, string>> = {\r\n /**\r\n * `check` phải là DẤU TÍCH THUẦN, không vòng tròn bao quanh.\r\n *\r\n * `solar.registry.ts` (file SINH TỰ ĐỘNG) ánh xạ `check` sang\r\n * `SOLAR_CHECK_CIRCLE_LINEAR` — icon có `<circle r=\"10\">`. Đo\r\n * /checkbox-radio ngày 2026-09-16: 10/10 ô đã chọn render vòng tròn quanh\r\n * dấu tích, trong khi Figma `Checkbox input, Checked=True` (#1149:54710)\r\n * vẽ MỘT path đặc, không circle.\r\n *\r\n * Sửa ở đây chứ không sửa registry: registry do\r\n * `scripts/gen-registry-metadata.js` sinh lại, vá tay sẽ mất.\r\n * 19 chỗ trong repo dùng `name=\"check\"` đều là ngữ cảnh dấu tích.\r\n */\r\n check: 'lucide:check',\r\n\r\n /**\r\n * `close` phải là DẤU X THUẦN, không vòng tròn bao quanh — cùng lớp lỗi\r\n * với `check` ngay trên.\r\n *\r\n * Registry KHÔNG có khoá `close` trần (tra cả 13.064 khoá: chỉ có\r\n * `close-circle`, `close-square`, và `lucide:x` / `mynaui:x`). Nên 17 chỗ\r\n * trong repo phải viết `name=\"close-circle\"` — icon có `<circle r=\"10\">`.\r\n *\r\n * Đọc Figma 2026-09-17: mọi node `close` trong `ol-select`, `ol-tag-input`,\r\n * `ol-autocomplete-menu`, `ol-autocomplete-item`, `ol-alert`,\r\n * `ol-modal-header`, `ol-modal-footer`, `ol-drawer-header` đều có\r\n * **ellipse = 0** và đúng **1 VECTOR** — dấu X trần, KHÔNG vòng tròn.\r\n * Code lệch Figma ở cả 7 component đo được.\r\n *\r\n * Sửa ở đây chứ không sửa registry: registry do\r\n * `scripts/gen-registry-metadata.js` sinh lại, vá tay sẽ mất.\r\n */\r\n close: 'lucide:x',\r\n x: 'lucide:x',\r\n\r\n minus: 'lucide:minus',\r\n\r\n /**\r\n * `plus` phải là DẤU CỘNG THUẦN, cặp với `minus` ngay trên — cùng lớp lỗi\r\n * với `check` và `close`.\r\n *\r\n * Registry KHÔNG có khoá `plus` trần (tra 13.241 khoá: chỉ `plus-minus`,\r\n * `user-plus`, `user-plus-rounded`, và `lucide:plus` / `mynaui:plus`). Tên\r\n * `plus` rơi vào một icon CÓ VÒNG TRÒN qua đường tra khác.\r\n *\r\n * Đo /forms 2026-09-17 trên `ol-input-counter`: nút `minus` render 1 path\r\n * trần, nút `plus` ngay cạnh render kèm `<circle>` — hai nút cùng cặp mà\r\n * một có vòng một không, lệch thấy rõ.\r\n */\r\n plus: 'lucide:plus',\r\n info: 'lucide:info',\r\n share: 'screen-share',\r\n 'share-nodes': 'screen-share',\r\n print: 'printer',\r\n 'file-copy': 'file',\r\n 'file-copy-alt': 'file',\r\n 'floppy-disk-alt': 'bookmark',\r\n 'search-minimalistic': 'minimalistic-magnifer',\r\n 'box-shadow': 'layers',\r\n 'grid-ruler': 'widget',\r\n sparkles: 'star-shine',\r\n 'avatar-user': 'user-circle',\r\n pattern: 'three-squares',\r\n illustration: 'photo',\r\n 'logo-wave': 'onluyen-logo',\r\n list: 'reorder',\r\n palette: 'palette',\r\n sun: 'sun',\r\n moon: 'moon',\r\n code: 'code-file',\r\n bars: 'menu',\r\n hamburger: 'menu',\r\n 'hamburger-menu': 'menu',\r\n 'inbox-full': 'inbox',\r\n 'academic-cap': 'square-academic-cap',\r\n 'adjustments-horizontal': 'sort-horizontal',\r\n 'adjustments-vertical': 'sort-vertical',\r\n 'alert-circle': 'danger-circle',\r\n 'alert-triangle': 'danger-triangle',\r\n 'align-center': 'mynaui:text-align-center',\r\n 'align-justify': 'lucide:text-align-justify',\r\n 'angle-down': 'chevron-down',\r\n 'angle-left': 'chevron-left',\r\n 'angle-right': 'chevron-right',\r\n 'arrow-right-to-bracket': 'lucide:arrow-right-to-line',\r\n 'arrows-repeat': 'mynaui:repeat',\r\n 'backward-step': 'lucide:step-back',\r\n caption: 'lucide:closed-caption',\r\n 'cash-register': 'solar:cash-out-outline',\r\n 'chevron-sort': 'sort',\r\n 'code-branch': 'lucide:git-branch',\r\n 'desktop-computer': 'lucide:computer',\r\n 'dots-horizontal': 'menu-dots',\r\n envelope: 'letter',\r\n expand: 'lucide:expand',\r\n 'file-circle-plus': 'mynaui:file-plus',\r\n 'file-lines': 'file-text',\r\n 'forward-step': 'lucide:step-forward',\r\n 'insert-table-alt': 'mynaui:table',\r\n 'letter-italic': 'lucide:italic',\r\n 'letter-underline': 'lucide:underline',\r\n 'life-saver': 'lucide:life-buoy',\r\n 'list-music': 'lucide:list-music',\r\n 'mail-box': 'lucide:mailbox',\r\n 'message-square': 'lucide:message-square',\r\n messages: 'mynaui:chat-messages',\r\n 'ordered-list': 'lucide:list-ordered',\r\n 'phone-hangup': 'lucide:phone-off',\r\n photograph: 'photo',\r\n 'share-2': 'lucide:share-2',\r\n 'text-size': 'lucide:type',\r\n 'text-slash': 'lucide:remove-formatting',\r\n 'user-headset': 'lucide:headset',\r\n 'video-camera': 'lucide:video',\r\n 'volume-up': 'lucide:volume-2',\r\n};\r\n","/**\r\n * Bộ icon lõi — SVG của đúng các icon mà component trong thư viện tự vẽ.\r\n * Sinh tự động bởi scripts/gen-core-icons.mjs — đừng sửa tay.\r\n *\r\n * `OlIconService` tra bảng này TRƯỚC registry theo bộ: component chỉ dùng\r\n * icon lõi thì không tải bộ nào (bộ Solar 10 MB). Khoá là tên ĐÃ CHUẨN HOÁ\r\n * (chữ thường) mà component truyền vào, giá trị là SVG đã tra theo bí danh.\r\n *\r\n * 64 icon · olkit 24 · lucide 20 · mynaui 5 · solar 15\r\n */\r\nexport const CORE_ICONS: Readonly<Record<string, string>> = {\r\n 'alt-arrow-down':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M19 9L12 15L5 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'alt-arrow-left':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M15 5L9 12L15 19\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'alt-arrow-right':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M9 5L15 12L9 19\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'arrow-left':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M20 12H4M10 18L4 12L10 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'arrow-right':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M4 12H20M14 18L20 12L14 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n calendar:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M2 12C2 8.22876 2 6.34315 3.17157 5.17157C4.34315 4 6.22876 4 10 4H14C17.7712 4 19.6569 4 20.8284 5.17157C22 6.34315 22 8.22876 22 12V14C22 17.7712 22 19.6569 20.8284 20.8284C19.6569 22 17.7712 22 14 22H10C6.22876 22 4.34315 22 3.17157 20.8284C2 19.6569 2 17.7712 2 14V12Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M7 4V2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M17 4V2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M2.5 9H21.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M18 17C18 17.5523 17.5523 18 17 18C16.4477 18 16 17.5523 16 17C16 16.4477 16.4477 16 17 16C17.5523 16 18 16.4477 18 17Z\" fill=\"currentColor\"/> <path d=\"M18 13C18 13.5523 17.5523 14 17 14C16.4477 14 16 13.5523 16 13C16 12.4477 16.4477 12 17 12C17.5523 12 18 12.4477 18 13Z\" fill=\"currentColor\"/> <path d=\"M13 17C13 17.5523 12.5523 18 12 18C11.4477 18 11 17.5523 11 17C11 16.4477 11.4477 16 12 16C12.5523 16 13 16.4477 13 17Z\" fill=\"currentColor\"/> <path d=\"M13 13C13 13.5523 12.5523 14 12 14C11.4477 14 11 13.5523 11 13C11 12.4477 11.4477 12 12 12C12.5523 12 13 12.4477 13 13Z\" fill=\"currentColor\"/> <path d=\"M8 17C8 17.5523 7.55228 18 7 18C6.44772 18 6 17.5523 6 17C6 16.4477 6.44772 16 7 16C7.55228 16 8 16.4477 8 17Z\" fill=\"currentColor\"/> <path d=\"M8 13C8 13.5523 7.55228 14 7 14C6.44772 14 6 13.5523 6 13C6 12.4477 6.44772 12 7 12C7.55228 12 8 12.4477 8 13Z\" fill=\"currentColor\"/> </svg>',\r\n 'calendar-add':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M2 12C2 8.22876 2 6.34315 3.17157 5.17157C4.34315 4 6.22876 4 10 4H14C17.7712 4 19.6569 4 20.8284 5.17157C22 6.34315 22 8.22876 22 12V14C22 17.7712 22 19.6569 20.8284 20.8284C19.6569 22 17.7712 22 14 22H10C6.22876 22 4.34315 22 3.17157 20.8284C2 19.6569 2 17.7712 2 14V12Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M18 16L16 16M16 16L14 16M16 16L16 14M16 16L16 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M7 4V2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M17 4V2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M2.5 9H21.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> </svg>',\r\n check:\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20 6L9 17l-5-5\"/></svg>',\r\n 'check-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M8.5 12.5L10.5 14.5L15.5 9.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'chevron-down':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"m6 9l6 6l6-6\"/></svg>',\r\n 'chevron-left':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"m15 6l-6 6l6 6\"/></svg>',\r\n 'chevron-right':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"m9 18l6-6l-6-6\"/></svg>',\r\n 'clock-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 8V12L14.5 14.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n close:\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 6L6 18M6 6l12 12\"/></svg>',\r\n 'close-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M14.5 9.50002L9.5 14.5M9.49998 9.5L14.5 14.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> </svg>',\r\n 'danger-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 7V13\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"12\" cy=\"16\" r=\"1\" fill=\"currentColor\"/> </svg>',\r\n 'danger-triangle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M5.31171 10.7615C8.23007 5.58716 9.68925 3 12 3C14.3107 3 15.7699 5.58716 18.6883 10.7615L19.0519 11.4063C21.4771 15.7061 22.6897 17.856 21.5937 19.428C20.4978 21 17.7864 21 12.3637 21H11.6363C6.21356 21 3.50217 21 2.40626 19.428C1.31034 17.856 2.52291 15.7061 4.94805 11.4063L5.31171 10.7615Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 8V13\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"12\" cy=\"16\" r=\"1\" fill=\"currentColor\"/> </svg>',\r\n download:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M22 14.0002H21.25V14.0002H22ZM22 15.0002H22.75V15.0002H22ZM16 21.0002V20.2502V20.2502V21.0002ZM8 21.0002V21.7502V21.7502V21.0002ZM2 15.0002H2.75H2ZM2 14.0002H1.25H2ZM2.87868 8.87889L3.40901 9.40922L3.40901 9.40922L2.87868 8.87889ZM21.1213 8.87889L21.6517 8.34856V8.34856L21.1213 8.87889ZM17.0042 7.25196C16.59 7.24966 16.2523 7.58357 16.25 7.99778C16.2477 8.41198 16.5816 8.74963 16.9958 8.75194L17 8.00195L17.0042 7.25196ZM7.00418 8.75194C7.41838 8.74963 7.75229 8.41198 7.74999 7.99778C7.74768 7.58357 7.41003 7.24966 6.99583 7.25196L7 8.00195L7.00418 8.75194ZM12.75 3C12.75 2.58579 12.4142 2.25 12 2.25C11.5858 2.25 11.25 2.58579 11.25 3L12 3L12.75 3ZM12 17L11.4697 17.5303C11.6103 17.671 11.8011 17.75 12 17.75C12.1989 17.75 12.3897 17.671 12.5303 17.5303L12 17ZM8.53033 12.4697C8.23744 12.1768 7.76256 12.1768 7.46967 12.4697C7.17678 12.7626 7.17678 13.2374 7.46967 13.5303L8 13L8.53033 12.4697ZM16.5303 13.5303C16.8232 13.2374 16.8232 12.7626 16.5303 12.4697C16.2374 12.1768 15.7626 12.1768 15.4697 12.4697L16 13L16.5303 13.5303ZM22 14.0002H21.25V15.0002H22H22.75V14.0002H22ZM16 21.0002V20.2502H8V21.0002V21.7502H16V21.0002ZM2 15.0002H2.75L2.75 14.0002H2H1.25L1.25 15.0002H2ZM2 14.0002H2.75C2.75 12.5648 2.75159 11.5637 2.85315 10.8083C2.9518 10.0746 3.13225 9.68599 3.40901 9.40922L2.87868 8.87889L2.34835 8.34856C1.74643 8.95048 1.48754 9.70835 1.36652 10.6085C1.24841 11.487 1.25 12.6072 1.25 14.0002H2ZM8 21.0002V20.2502C6.56458 20.2502 5.56347 20.2486 4.80812 20.1471C4.07434 20.0484 3.68577 19.868 3.40901 19.5912L2.87868 20.1215L2.34835 20.6519C2.95027 21.2538 3.70814 21.5127 4.60825 21.6337C5.48678 21.7518 6.60699 21.7502 8 21.7502V21.0002ZM2 15.0002H1.25C1.25 16.3932 1.24841 17.5134 1.36652 18.392C1.48754 19.2921 1.74643 20.0499 2.34835 20.6519L2.87868 20.1215L3.40901 19.5912C3.13225 19.3144 2.9518 18.9259 2.85315 18.1921C2.75159 17.4367 2.75 16.4356 2.75 15.0002H2ZM22 15.0002H21.25C21.25 16.4356 21.2484 17.4367 21.1469 18.1921C21.0482 18.9259 20.8678 19.3144 20.591 19.5912L21.1213 20.1215L21.6517 20.6519C22.2536 20.0499 22.5125 19.2921 22.6335 18.392C22.7516 17.5134 22.75 16.3932 22.75 15.0002H22ZM16 21.0002V21.7502C17.393 21.7502 18.5132 21.7518 19.3918 21.6337C20.2919 21.5127 21.0497 21.2538 21.6517 20.6519L21.1213 20.1215L20.591 19.5912C20.3142 19.868 19.9257 20.0484 19.1919 20.1471C18.4365 20.2486 17.4354 20.2502 16 20.2502V21.0002ZM22 14.0002H22.75C22.75 12.6072 22.7516 11.487 22.6335 10.6085C22.5125 9.70835 22.2536 8.95048 21.6517 8.34856L21.1213 8.87889L20.591 9.40922C20.8678 9.68599 21.0482 10.0746 21.1469 10.8083C21.2484 11.5637 21.25 12.5648 21.25 14.0002H22ZM17 8.00195L16.9958 8.75194C18.0893 8.75803 18.8644 8.78643 19.4527 8.89448C20.0195 8.99859 20.3475 9.16577 20.591 9.40922L21.1213 8.87889L21.6517 8.34856C21.1267 7.82363 20.4816 7.55839 19.7236 7.41916C18.9871 7.28386 18.0857 7.25798 17.0042 7.25196L17 8.00195ZM7 8.00195L6.99583 7.25196C5.9143 7.25798 5.01291 7.28386 4.27635 7.41916C3.51835 7.55839 2.87328 7.82363 2.34835 8.34856L2.87868 8.87889L3.40901 9.40922C3.65246 9.16577 3.98054 8.99859 4.54735 8.89448C5.13559 8.78642 5.91068 8.75803 7.00418 8.75194L7 8.00195ZM12 3L11.25 3L11.25 17H12H12.75L12.75 3L12 3ZM12 17L12.5303 16.4697L8.53033 12.4697L8 13L7.46967 13.5303L11.4697 17.5303L12 17ZM12 17L12.5303 17.5303L16.5303 13.5303L16 13L15.4697 12.4697L11.4697 16.4697L12 17Z\" fill=\"currentColor\"/> </svg>',\r\n 'info-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 17V11\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"1\" cy=\"1\" r=\"1\" transform=\"matrix(1 0 0 -1 11 9)\" fill=\"currentColor\"/> </svg>',\r\n link: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M10.0464 14C8.54044 12.4882 8.67609 9.90087 10.3494 8.22108L15.197 3.35462C16.8703 1.67483 19.4476 1.53865 20.9536 3.05046C22.4596 4.56228 22.3239 7.14956 20.6506 8.82935L18.2268 11.2626\"/><path d=\"M13.9536 10C15.4596 11.5118 15.3239 14.0991 13.6506 15.7789L11.2268 18.2121L8.80299 20.6454C7.12969 22.3252 4.55237 22.4613 3.0464 20.9495C1.54043 19.4377 1.67609 16.8504 3.34939 15.1706L5.77323 12.7373\"/></g></svg>',\r\n list: '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M2 17.5C2 16.5654 2 16.0981 2.20096 15.75C2.33261 15.522 2.52197 15.3326 2.75 15.201C3.09808 15 3.56538 15 4.5 15C5.43462 15 5.90192 15 6.25 15.201C6.47803 15.3326 6.66739 15.522 6.79904 15.75C7 16.0981 7 16.5654 7 17.5C7 18.4346 7 18.9019 6.79904 19.25C6.66739 19.478 6.47803 19.6674 6.25 19.799C5.90192 20 5.43462 20 4.5 20C3.56538 20 3.09808 20 2.75 19.799C2.52197 19.6674 2.33261 19.478 2.20096 19.25C2 18.9019 2 18.4346 2 17.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M9.5 17.5C9.5 16.5654 9.5 16.0981 9.70096 15.75C9.83261 15.522 10.022 15.3326 10.25 15.201C10.5981 15 11.0654 15 12 15C12.9346 15 13.4019 15 13.75 15.201C13.978 15.3326 14.1674 15.522 14.299 15.75C14.5 16.0981 14.5 16.5654 14.5 17.5C14.5 18.4346 14.5 18.9019 14.299 19.25C14.1674 19.478 13.978 19.6674 13.75 19.799C13.4019 20 12.9346 20 12 20C11.0654 20 10.5981 20 10.25 19.799C10.022 19.6674 9.83261 19.478 9.70096 19.25C9.5 18.9019 9.5 18.4346 9.5 17.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M17 17.5C17 16.5654 17 16.0981 17.201 15.75C17.3326 15.522 17.522 15.3326 17.75 15.201C18.0981 15 18.5654 15 19.5 15C20.4346 15 20.9019 15 21.25 15.201C21.478 15.3326 21.6674 15.522 21.799 15.75C22 16.0981 22 16.5654 22 17.5C22 18.4346 22 18.9019 21.799 19.25C21.6674 19.478 21.478 19.6674 21.25 19.799C20.9019 20 20.4346 20 19.5 20C18.5654 20 18.0981 20 17.75 19.799C17.522 19.6674 17.3326 19.478 17.201 19.25C17 18.9019 17 18.4346 17 17.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M4.5 15V9C4.5 6.64298 4.5 5.46447 5.23223 4.73223C5.96447 4 7.14298 4 9.5 4H14.5C16.857 4 18.0355 4 18.7678 4.73223C19.5 5.46447 19.5 6.64298 19.5 9V12M17 9.5L19.5 12L22 9.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/> </svg>',\r\n 'lucide:bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\"/></svg>',\r\n 'lucide:code':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m16 18l6-6l-6-6M8 6l-6 6l6 6\"/></svg>',\r\n 'lucide:file':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5\"/></g></svg>',\r\n 'lucide:file-archive':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M13.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v11.5\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5M8 12v-1m0 7v-2m0-9V6\"/><circle cx=\"8\" cy=\"20\" r=\"2\"/></g></svg>',\r\n 'lucide:file-code':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5m-10 4.5L8 15l2 2.5m4-5l2 2.5l-2 2.5\"/></g></svg>',\r\n 'lucide:file-image':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5\"/><circle cx=\"10\" cy=\"12\" r=\"2\"/><path d=\"m20 17l-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22\"/></g></svg>',\r\n 'lucide:file-music':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M11.65 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v10.35\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5M8 20v-7l3 1.474\"/><circle cx=\"6\" cy=\"20\" r=\"2\"/></g></svg>',\r\n 'lucide:file-spreadsheet':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5M8 13h2m4 0h2m-8 4h2m4 0h2\"/></g></svg>',\r\n 'lucide:file-text':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5M10 9H8m8 4H8m8 4H8\"/></g></svg>',\r\n 'lucide:file-type':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5m-9 10h2m-1-6v6m-3-5v-.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5v.5\"/></g></svg>',\r\n 'lucide:file-video-camera':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M4 12V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2\"/><path d=\"M14 2v5a1 1 0 0 0 1 1h5m-10 9.843l3.033-1.755a.64.64 0 0 1 .967.56v4.704a.65.65 0 0 1-.967.56L10 20.157\"/><rect width=\"7\" height=\"6\" x=\"3\" y=\"16\" rx=\"1\"/></g></svg>',\r\n 'lucide:italic':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 4h-9m4 16H5M15 4L9 20\"/></svg>',\r\n 'lucide:lock':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\"/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"/></g></svg>',\r\n 'lucide:presentation':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M2 3h20m-1 0v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3m4 18l5-5l5 5\"/></svg>',\r\n 'lucide:zoom-in':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21l-4.35-4.35M11 8v6m-3-3h6\"/></g></svg>',\r\n 'lucide:zoom-out':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21l-4.35-4.35M8 11h6\"/></g></svg>',\r\n magnifer:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"11.5\" cy=\"11.5\" r=\"9.5\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M18.5 18.5L22 22\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> </svg>',\r\n menu: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M20 7L4 7\"/><path d=\"M20 12L4 12\"/><path d=\"M20 17L4 17\"/></g></svg>',\r\n 'menu-dots':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"5\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <circle cx=\"12\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <circle cx=\"19\" cy=\"12\" r=\"2\" stroke=\"currentColor\" stroke-width=\"1.5\"/> </svg>',\r\n minus:\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14\"/></svg>',\r\n 'mynaui:smile':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\"><path d=\"M9 15c.85.63 1.885 1 3 1s2.15-.37 3-1m-5.5-4.5V10m5 .5V10\"/><path d=\"M21 12a9 9 0 1 1-18 0a9 9 0 0 1 18 0\"/></g></svg>',\r\n 'notification-unread':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M22 10.5V12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2H13.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"19\" cy=\"5\" r=\"3\" stroke=\"currentColor\" stroke-width=\"1.5\"/> </svg>',\r\n photo:\r\n '<svg viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M6 3C6 1.89543 6.89543 1 8 1H20L28 9V29C28 30.1046 27.1046 31 26 31H8C6.89543 31 6 30.1046 6 29V3Z\" fill=\"#0D9488\"/> <path d=\"M20 1V9H28L20 1Z\" fill=\"#0F766E\"/> <circle cx=\"12\" cy=\"15\" r=\"2\" fill=\"#F59E0B\"/> <path d=\"M9 24L14 18L18 22L21 19L23 24H9Z\" fill=\"#FFFFFF\"/> </svg>',\r\n plus: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7v14\"/></svg>',\r\n 'question-circle':\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M10.125 8.875C10.125 7.83947 10.9645 7 12 7C13.0355 7 13.875 7.83947 13.875 8.875C13.875 9.56245 13.505 10.1635 12.9534 10.4899C12.478 10.7711 12 11.1977 12 11.75V13\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <circle cx=\"12\" cy=\"16\" r=\"1\" fill=\"currentColor\"/> </svg>',\r\n refresh:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M3.67981 11.3333H2.92981V11.3333H3.67981ZM3.67981 13L3.15157 13.5324C3.44398 13.8225 3.91565 13.8225 4.20805 13.5324L3.67981 13ZM5.88787 11.8657C6.18191 11.574 6.18377 11.0991 5.89203 10.8051C5.60029 10.511 5.12542 10.5092 4.83138 10.8009L5.35962 11.3333L5.88787 11.8657ZM2.52824 10.8009C2.2342 10.5092 1.75933 10.511 1.46759 10.8051C1.17585 11.0991 1.17772 11.574 1.47176 11.8657L2 11.3333L2.52824 10.8009ZM18.6156 7.39279C18.8325 7.74565 19.2944 7.85585 19.6473 7.63892C20.0001 7.42199 20.1103 6.96007 19.8934 6.60721L19.2545 7L18.6156 7.39279ZM12.0789 3V2.25C7.03155 2.25 2.92981 6.3112 2.92981 11.3333H3.67981H4.42981C4.42981 7.15072 7.84884 3.75 12.0789 3.75V3ZM3.67981 11.3333H2.92981L2.92981 13H3.67981H4.42981L4.42981 11.3333H3.67981ZM3.67981 13L4.20805 13.5324L5.88787 11.8657L5.35962 11.3333L4.83138 10.8009L3.15157 12.4676L3.67981 13ZM3.67981 13L4.20805 12.4676L2.52824 10.8009L2 11.3333L1.47176 11.8657L3.15157 13.5324L3.67981 13ZM19.2545 7L19.8934 6.60721C18.287 3.99427 15.3873 2.25 12.0789 2.25V3V3.75C14.8484 3.75 17.2727 5.20845 18.6156 7.39279L19.2545 7Z\" fill=\"currentColor\"/> <path d=\"M20.3139 11L20.8411 10.4666C20.549 10.1778 20.0788 10.1778 19.7867 10.4666L20.3139 11ZM18.1004 12.1333C17.8058 12.4244 17.8031 12.8993 18.0942 13.1939C18.3854 13.4885 18.8603 13.4913 19.1549 13.2001L18.6277 12.6667L18.1004 12.1333ZM21.4729 13.2001C21.7675 13.4913 22.2424 13.4885 22.5335 13.1939C22.8247 12.8993 22.822 12.4244 22.5274 12.1332L22.0001 12.6667L21.4729 13.2001ZM5.31794 16.6061C5.1004 16.2536 4.6383 16.1442 4.28581 16.3618C3.93331 16.5793 3.82391 17.0414 4.04144 17.3939L4.67969 17L5.31794 16.6061ZM11.8827 21V21.75C16.9451 21.75 21.0639 17.6915 21.0639 12.6667H20.3139H19.5639C19.5639 16.8466 16.1332 20.25 11.8827 20.25V21ZM20.3139 12.6667H21.0639V11H20.3139H19.5639V12.6667H20.3139ZM20.3139 11L19.7867 10.4666L18.1004 12.1333L18.6277 12.6667L19.1549 13.2001L20.8411 11.5334L20.3139 11ZM20.3139 11L19.7867 11.5334L21.4729 13.2001L22.0001 12.6667L22.5274 12.1332L20.8411 10.4666L20.3139 11ZM4.67969 17L4.04144 17.3939C5.65405 20.007 8.56403 21.75 11.8827 21.75V21V20.25C9.10023 20.25 6.66584 18.7903 5.31794 16.6061L4.67969 17Z\" fill=\"currentColor\"/> </svg>',\r\n search:\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M19 11.5a7.5 7.5 0 1 1-15 0a7.5 7.5 0 0 1 15 0m-2.107 5.42l3.08 3.08\"/></svg>',\r\n 'solar:arrow-left-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M20 12H4M10 18L4 12L10 6\"/></svg>',\r\n 'solar:check-circle-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM16.0303 8.96967C16.3232 9.26256 16.3232 9.73744 16.0303 10.0303L11.0303 15.0303C10.7374 15.3232 10.2626 15.3232 9.96967 15.0303L7.96967 13.0303C7.67678 12.7374 7.67678 12.2626 7.96967 11.9697C8.26256 11.6768 8.73744 11.6768 9.03033 11.9697L10.5 13.4393L12.7348 11.2045L14.9697 8.96967C15.2626 8.67678 15.7374 8.67678 16.0303 8.96967Z\" clip-rule=\"evenodd\"/></svg>',\r\n 'solar:danger-circle-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12ZM12 6.25C12.4142 6.25 12.75 6.58579 12.75 7V13C12.75 13.4142 12.4142 13.75 12 13.75C11.5858 13.75 11.25 13.4142 11.25 13V7C11.25 6.58579 11.5858 6.25 12 6.25ZM12 17C12.5523 17 13 16.5523 13 16C13 15.4477 12.5523 15 12 15C11.4477 15 11 15.4477 11 16C11 16.5523 11.4477 17 12 17Z\" clip-rule=\"evenodd\"/></svg>',\r\n 'solar:eye-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"currentColor\"><path d=\"M9.75 12C9.75 10.7574 10.7574 9.75 12 9.75C13.2426 9.75 14.25 10.7574 14.25 12C14.25 13.2426 13.2426 14.25 12 14.25C10.7574 14.25 9.75 13.2426 9.75 12Z\"/><path fill-rule=\"evenodd\" d=\"M2 12C2 13.6394 2.42496 14.1915 3.27489 15.2957C4.97196 17.5004 7.81811 20 12 20C16.1819 20 19.028 17.5004 20.7251 15.2957C21.575 14.1915 22 13.6394 22 12C22 10.3606 21.575 9.80853 20.7251 8.70433C19.028 6.49956 16.1819 4 12 4C7.81811 4 4.97196 6.49956 3.27489 8.70433C2.42496 9.80853 2 10.3606 2 12ZM12 8.25C9.92893 8.25 8.25 9.92893 8.25 12C8.25 14.0711 9.92893 15.75 12 15.75C14.0711 15.75 15.75 14.0711 15.75 12C15.75 9.92893 14.0711 8.25 12 8.25Z\" clip-rule=\"evenodd\"/></g></svg>',\r\n 'solar:gallery-add-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2\"/><path d=\"M2 12.5001L3.75159 10.9675C4.66286 10.1702 6.03628 10.2159 6.89249 11.0721L11.1822 15.3618C11.8694 16.0491 12.9512 16.1428 13.7464 15.5839L14.0446 15.3744C15.1888 14.5702 16.7369 14.6634 17.7765 15.599L21 18.5001\"/><path d=\"M15 5.5H18.5M18.5 5.5H22M18.5 5.5V9M18.5 5.5V2\"/></g></svg>',\r\n 'solar:hamburger-menu-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M20 7L4 7\"/><path d=\"M20 12L4 12\"/><path d=\"M20 17L4 17\"/></g></svg>',\r\n 'solar:lock-password-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M2 16C2 13.1716 2 11.7574 2.87868 10.8787C3.75736 10 5.17157 10 8 10H16C18.8284 10 20.2426 10 21.1213 10.8787C22 11.7574 22 13.1716 22 16C22 18.8284 22 20.2426 21.1213 21.1213C20.2426 22 18.8284 22 16 22H8C5.17157 22 3.75736 22 2.87868 21.1213C2 20.2426 2 18.8284 2 16Z\"/><path stroke-linecap=\"round\" d=\"M6 10V8C6 4.68629 8.68629 2 12 2C15.3137 2 18 4.68629 18 8V10\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 16H8.009M11.991 16H12M15.991 16H16\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 16H8.009M11.991 16H12M15.991 16H16\"/></g></svg>',\r\n 'solar:logout-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><path d=\"M12 20C7.58172 20 4 16.4183 4 12C4 7.58172 7.58172 4 12 4\"/><path stroke-linejoin=\"round\" d=\"M10 12H20M17 15L20 12L17 9\"/></g></svg>',\r\n 'solar:magnifer-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"11.5\" cy=\"11.5\" r=\"9.5\"/><path stroke-linecap=\"round\" d=\"M18.5 18.5L22 22\"/></g></svg>',\r\n 'solar:refresh-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"currentColor\"><path d=\"M12.0789 2.25C7.2854 2.25 3.34478 5.913 2.96055 10.5833H2.00002C1.69614 10.5833 1.42229 10.7667 1.30655 11.0477C1.19081 11.3287 1.25606 11.6517 1.47178 11.8657L3.15159 13.5324C3.444 13.8225 3.91567 13.8225 4.20808 13.5324L5.88789 11.8657C6.10361 11.6517 6.16886 11.3287 6.05312 11.0477C5.93738 10.7667 5.66353 10.5833 5.35965 10.5833H4.4668C4.84652 6.75167 8.10479 3.75 12.0789 3.75C14.8484 3.75 17.2727 5.20845 18.6156 7.39279C18.8325 7.74565 19.2944 7.85585 19.6473 7.63892C20.0002 7.42199 20.1104 6.96007 19.8934 6.60721C18.2871 3.99427 15.3873 2.25 12.0789 2.25Z\"/><path d=\"M20.8411 10.4666C20.549 10.1778 20.0789 10.1778 19.7867 10.4666L18.1005 12.1333C17.8841 12.3471 17.8184 12.6703 17.9339 12.9517C18.0495 13.233 18.3235 13.4167 18.6277 13.4167H19.5268C19.1455 17.2462 15.8759 20.25 11.8828 20.25C9.10026 20.25 6.66586 18.7903 5.31796 16.6061C5.10042 16.2536 4.63833 16.1442 4.28583 16.3618C3.93334 16.5793 3.82393 17.0414 4.04146 17.3939C5.65407 20.007 8.56406 21.75 11.8828 21.75C16.6906 21.75 20.6475 18.0892 21.0331 13.4167H22.0002C22.3043 13.4167 22.5783 13.233 22.6939 12.9517C22.8095 12.6703 22.7437 12.3471 22.5274 12.1333L20.8411 10.4666Z\"/></g></svg>',\r\n 'solar:trash-bin-trash-bold':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"currentColor\"><path d=\"M3 6.38597C3 5.90152 3.34538 5.50879 3.77143 5.50879L6.43567 5.50832C6.96502 5.49306 7.43202 5.11033 7.61214 4.54412C7.61688 4.52923 7.62232 4.51087 7.64185 4.44424L7.75665 4.05256C7.8269 3.81241 7.8881 3.60318 7.97375 3.41617C8.31209 2.67736 8.93808 2.16432 9.66147 2.03297C9.84457 1.99972 10.0385 1.99986 10.2611 2.00002H13.7391C13.9617 1.99986 14.1556 1.99972 14.3387 2.03297C15.0621 2.16432 15.6881 2.67736 16.0264 3.41617C16.1121 3.60318 16.1733 3.81241 16.2435 4.05256L16.3583 4.44424C16.3778 4.51087 16.3833 4.52923 16.388 4.54412C16.5682 5.11033 17.1278 5.49353 17.6571 5.50879H20.2286C20.6546 5.50879 21 5.90152 21 6.38597C21 6.87043 20.6546 7.26316 20.2286 7.26316H3.77143C3.34538 7.26316 3 6.87043 3 6.38597Z\"/><path fill-rule=\"evenodd\" d=\"M11.5956 22.0001H12.4044C15.1871 22.0001 16.5785 22.0001 17.4831 21.1142C18.3878 20.2283 18.4803 18.7751 18.6654 15.8686L18.9321 11.6807C19.0326 10.1037 19.0828 9.31524 18.6289 8.81558C18.1751 8.31592 17.4087 8.31592 15.876 8.31592H8.12404C6.59127 8.31592 5.82488 8.31592 5.37105 8.81558C4.91722 9.31524 4.96744 10.1037 5.06788 11.6807L5.33459 15.8686C5.5197 18.7751 5.61225 20.2283 6.51689 21.1142C7.42153 22.0001 8.81289 22.0001 11.5956 22.0001ZM10.2463 12.1886C10.2051 11.7548 9.83753 11.4382 9.42537 11.4816C9.01321 11.525 8.71251 11.9119 8.75372 12.3457L9.25372 17.6089C9.29494 18.0427 9.66247 18.3593 10.0746 18.3159C10.4868 18.2725 10.7875 17.8856 10.7463 17.4518L10.2463 12.1886ZM14.5746 11.4816C14.9868 11.525 15.2875 11.9119 15.2463 12.3457L14.7463 17.6089C14.7051 18.0427 14.3375 18.3593 13.9254 18.3159C13.5132 18.2725 13.2125 17.8856 13.2537 17.4518L13.7537 12.1886C13.7949 11.7548 14.1625 11.4382 14.5746 11.4816Z\" clip-rule=\"evenodd\"/></g></svg>',\r\n 'solar:upload-minimalistic-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\"><path d=\"M3 15C3 17.8284 3 19.2426 3.87868 20.1213C4.75736 21 6.17157 21 9 21H15C17.8284 21 19.2426 21 20.1213 20.1213C21 19.2426 21 17.8284 21 15\"/><path d=\"M12 16V3M8 7.375L12 3L16 7.375\"/></g></svg>',\r\n 'solar:user-circle-linear':\r\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><g fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"12\" cy=\"9\" r=\"3\"/><circle cx=\"12\" cy=\"12\" r=\"10\"/><path stroke-linecap=\"round\" d=\"M17.9691 20C17.81 17.1085 16.9247 15 11.9999 15C7.07521 15 6.18991 17.1085 6.03076 20\"/></g></svg>',\r\n sparkles:\r\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M10.5766 8.70419C11.2099 7.56806 11.5266 7 12 7C12.4734 7 12.7901 7.56806 13.4234 8.70419L13.5873 8.99812C13.7672 9.32097 13.8572 9.48239 13.9975 9.5889C14.1378 9.69541 14.3126 9.73495 14.6621 9.81402L14.9802 9.88601C16.2101 10.1643 16.825 10.3034 16.9713 10.7739C17.1176 11.2443 16.6984 11.7345 15.86 12.715L15.643 12.9686C15.4048 13.2472 15.2857 13.3865 15.2321 13.5589C15.1785 13.7312 15.1965 13.9171 15.2325 14.2888L15.2653 14.6272C15.3921 15.9353 15.4554 16.5894 15.0724 16.8801C14.6894 17.1709 14.1137 16.9058 12.9622 16.3756L12.6643 16.2384C12.337 16.0878 12.1734 16.0124 12 16.0124C11.8266 16.0124 11.663 16.0878 11.3357 16.2384L11.0378 16.3756C9.88634 16.9058 9.31059 17.1709 8.92757 16.8801C8.54456 16.5894 8.60794 15.9353 8.7347 14.6272L8.76749 14.2888C8.80351 13.9171 8.82152 13.7312 8.76793 13.5589C8.71434 13.3865 8.59521 13.2472 8.35696 12.9686L8.14005 12.715C7.30162 11.7345 6.88241 11.2443 7.02871 10.7739C7.17501 10.3034 7.78993 10.1643 9.01977 9.88601L9.33794 9.81402C9.68743 9.73495 9.86217 9.69541 10.0025 9.5889C10.1428 9.48239 10.2328 9.32097 10.4127 8.99812L10.5766 8.70419Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M12 2V4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M12 20V22\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M2 12L4 12\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M20 12L22 12\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M6 18L6.34305 17.657\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M17.6567 6.34326L18 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M18 18L17.657 17.657\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> <path d=\"M6.34326 6.34326L6 6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/> </svg>',\r\n star: '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"M9.15316 5.40838C10.4198 3.13613 11.0531 2 12 2C12.9469 2 13.5802 3.13612 14.8468 5.40837L15.1745 5.99623C15.5345 6.64193 15.7144 6.96479 15.9951 7.17781C16.2757 7.39083 16.6251 7.4699 17.3241 7.62805L17.9605 7.77203C20.4201 8.32856 21.65 8.60682 21.9426 9.54773C22.2352 10.4886 21.3968 11.4691 19.7199 13.4299L19.2861 13.9372C18.8096 14.4944 18.5713 14.773 18.4641 15.1177C18.357 15.4624 18.393 15.8341 18.465 16.5776L18.5306 17.2544C18.7841 19.8706 18.9109 21.1787 18.1449 21.7602C17.3788 22.3417 16.2273 21.8115 13.9243 20.7512L13.3285 20.4768C12.6741 20.1755 12.3469 20.0248 12 20.0248C11.6531 20.0248 11.3259 20.1755 10.6715 20.4768L10.0757 20.7512C7.77268 21.8115 6.62118 22.3417 5.85515 21.7602C5.08912 21.1787 5.21588 19.8706 5.4694 17.2544L5.53498 16.5776C5.60703 15.8341 5.64305 15.4624 5.53586 15.1177C5.42868 14.773 5.19043 14.4944 4.71392 13.9372L4.2801 13.4299C2.60325 11.4691 1.76482 10.4886 2.05742 9.54773C2.35002 8.60682 3.57986 8.32856 6.03954 7.77203L6.67589 7.62805C7.37485 7.4699 7.72433 7.39083 8.00494 7.17781C8.28555 6.96479 8.46553 6.64194 8.82547 5.99623L9.15316 5.40838Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> </svg>',\r\n user: '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"> <circle cx=\"12\" cy=\"6\" r=\"4\" stroke=\"currentColor\" stroke-width=\"1.5\"/> <path d=\"M20 17.5C20 19.9853 20 22 12 22C4 22 4 19.9853 4 17.5C4 15.0147 7.58172 13 12 13C16.4183 13 20 15.0147 20 17.5Z\" stroke=\"currentColor\" stroke-width=\"1.5\"/> </svg>',\r\n};\r\n","import { InjectionToken, Injectable, Provider, inject } from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { Observable, from, of } from 'rxjs';\r\nimport { catchError, map, shareReplay, tap } from 'rxjs/operators';\r\nimport { ICON_ALIASES } from './icon-aliases';\r\nimport { CORE_ICONS } from './core.icons';\r\n\r\n/**\r\n * Icon nơi dùng tự đăng ký — tên → SVG. Xem `provideOlIcons`.\r\n */\r\nexport const OL_ICONS = new InjectionToken<ReadonlyArray<Record<string, string>>>('OL_ICONS');\r\n\r\n/**\r\n * Đăng ký icon import RIÊNG TỪNG CÁI — cách dùng tree-shake được.\r\n *\r\n * \\`\\`\\`ts\r\n * import { provideOlIcons } from '@edmicro/olkit-icons';\r\n * import { SOLAR_HOME_2_LINEAR } from '@edmicro/olkit-icons/collections/solar/home_2_linear';\r\n *\r\n * bootstrapApplication(App, {\r\n * providers: [provideOlIcons({ 'solar:home-2-linear': SOLAR_HOME_2_LINEAR })],\r\n * });\r\n * \\`\\`\\`\r\n *\r\n * Bundler chỉ giữ đúng các hằng được import (~2-5 KB/icon).\r\n */\r\nexport function provideOlIcons(\r\n icons: Record<string, string> | (string | string[])[]\r\n): Provider[] {\r\n if (Array.isArray(icons)) {\r\n // Khi dùng build-time plugin (esbuild), mảng này sẽ được tự động suy luận ngược\r\n // và compile thành direct imports { 'solar:home-2-linear': SOLAR_HOME_2_LINEAR }.\r\n // Nếu chạy môi trường không có plugin, IconService sẽ fallback load on-demand lúc render.\r\n return [];\r\n }\r\n return [{ provide: OL_ICONS, useValue: icons, multi: true }];\r\n}\r\n\r\n/**\r\n * Đăng ký icon theo TÊN - chỉ cần string, không cần import constants hay nhớ 13k tên.\r\n *\r\n * ```ts\r\n * import { provideOlIconsByName } from '@edmicro/olkit-icons';\r\n *\r\n * bootstrapApplication(App, {\r\n * providers: [\r\n * provideOlIconsByName(['solar:home-2-linear', 'lucide:cog', 'user-circle'])\r\n * ],\r\n * });\r\n * ```\r\n *\r\n * Plugin build sẽ tự động suy luận ngược từ chuỗi tên thành file và constant tương ứng để tree-shaking.\r\n */\r\nexport function provideOlIconsByName(iconNames: (string | string[])[]): Provider[] {\r\n return [];\r\n}\r\n\r\n/**\r\n * Service quản lý icons cho Ôn Luyện Design System.\r\n * \r\n * Icons được đăng ký qua `provideOlIcons()` hoặc `provideOlIconsByName()` (với esbuild plugin).\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class OlIconService {\r\n private readonly sanitizer = inject(DomSanitizer);\r\n private readonly cache = new Map<string, SafeHtml>();\r\n\r\n /** Icon đăng ký qua `provideOlIcons` / `register` — tên đã chuẩn hoá → SVG. */\r\n private readonly registered = new Map<string, string>();\r\n\r\n constructor() {\r\n for (const group of inject(OL_ICONS, { optional: true }) ?? []) this.register(group);\r\n }\r\n\r\n /**\r\n * Đăng ký icon lúc chạy — cùng tác dụng với `provideOlIcons`, cho nơi cần\r\n * thêm icon sau khi ứng dụng đã khởi động. Tên trùng thì bản sau thắng.\r\n *\r\n * Tự động suy luận ngược từ tên hằng số (SOLAR_HOME_2_LINEAR) sang tên icon ('solar:home-2-linear'),\r\n * cho phép người dùng truyền trực tiếp: provideOlIcons({ SOLAR_HOME_2_LINEAR, OLKIT_USER_CIRCLE }).\r\n */\r\n register(icons: Record<string, string>): void {\r\n for (const [name, svg] of Object.entries(icons)) {\r\n const trimmed = name.trim();\r\n const norm = trimmed.toLowerCase();\r\n this.registered.set(norm, svg);\r\n\r\n // Tự động suy luận alias ngược: SOLAR_HOME_2_LINEAR -> solar:home-2-linear\r\n const inferred = this.constantToIconName(trimmed);\r\n if (inferred) {\r\n this.registered.set(inferred, svg);\r\n if (inferred.startsWith('olkit:')) {\r\n this.registered.set(inferred.slice(6), svg);\r\n }\r\n }\r\n\r\n // Xoá cache của tên này: đăng ký lại phải vẽ theo SVG mới.\r\n for (const key of [...this.cache.keys()]) {\r\n if (\r\n key.endsWith(`:${this.aliasMap[norm] || norm}`) ||\r\n (inferred && key.endsWith(`:${inferred}`))\r\n ) {\r\n this.cache.delete(key);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Suy luận ngược từ tên hằng số sang tên icon chuẩn:\r\n * SOLAR_HOME_2_LINEAR -> solar:home-2-linear\r\n * OLKIT_USER_CIRCLE -> olkit:user-circle\r\n * LUCIDE_COG -> lucide:cog\r\n * MYNAUI_SEARCH -> mynaui:search\r\n */\r\n constantToIconName(constantName: string): string | null {\r\n const match = constantName.match(/^(SOLAR|LUCIDE|MYNAUI|OLKIT)_(.+)$/i);\r\n if (!match) return null;\r\n const collection = match[1].toLowerCase();\r\n const iconKebab = match[2].toLowerCase().replace(/_/g, '-');\r\n return `${collection}:${iconKebab}`;\r\n }\r\n\r\n /**\r\n * Lấy SVG SafeHtml sync (chỉ trả icon đã load trong cache hoặc core icons)\r\n * Không load registry - dùng getIcon() cho async loading\r\n */\r\n getIconSync(name: string, variant: string = 'linear'): SafeHtml | null {\r\n if (typeof name !== 'string' || !name.trim()) return null;\r\n\r\n const key = this.normalizeKey(name, variant);\r\n\r\n // Check cache first\r\n if (this.cache.has(key)) {\r\n return this.cache.get(key)!;\r\n }\r\n\r\n const trimmed = name.trim().toLowerCase();\r\n\r\n // 1. Tra cứu trực tiếp trong CORE_ICONS theo tên truyền vào (đường dẫn đồng bộ nhanh nhất cho icon lõi: chevron-down, list, close, check, v.v.)\r\n if (trimmed in CORE_ICONS) {\r\n const svg = CORE_ICONS[trimmed as keyof typeof CORE_ICONS];\r\n const cleaned = this.cleanSvg(svg);\r\n const safe = this.sanitizer.bypassSecurityTrustHtml(cleaned);\r\n this.cache.set(key, safe);\r\n return safe;\r\n }\r\n\r\n // Auto-add olkit: prefix nếu không có collection prefix\r\n const normName = trimmed.includes(':') ? trimmed : `olkit:${trimmed}`;\r\n let resolvedName = this.aliasMap[trimmed] || this.aliasMap[normName] || normName;\r\n if (!resolvedName.includes(':')) {\r\n resolvedName = `olkit:${resolvedName}`;\r\n }\r\n\r\n // Check directly registered icons (from provideOlIcons)\r\n const registered =\r\n this.registered.get(resolvedName) ??\r\n this.registered.get(normName) ??\r\n this.registered.get(trimmed);\r\n if (registered) {\r\n const cleaned = this.cleanSvg(registered);\r\n const safe = this.sanitizer.bypassSecurityTrustHtml(cleaned);\r\n this.cache.set(key, safe);\r\n return safe;\r\n }\r\n\r\n // Check core icons theo resolvedName hoặc normName\r\n if (resolvedName in CORE_ICONS) {\r\n const svg = CORE_ICONS[resolvedName as keyof typeof CORE_ICONS];\r\n const cleaned = this.cleanSvg(svg);\r\n const safe = this.sanitizer.bypassSecurityTrustHtml(cleaned);\r\n this.cache.set(key, safe);\r\n return safe;\r\n }\r\n if (normName in CORE_ICONS) {\r\n const svg = CORE_ICONS[normName as keyof typeof CORE_ICONS];\r\n const cleaned = this.cleanSvg(svg);\r\n const safe = this.sanitizer.bypassSecurityTrustHtml(cleaned);\r\n this.cache.set(key, safe);\r\n return safe;\r\n }\r\n\r\n // Try loaded registries synchronously (for icons already in memory)\r\n return null;\r\n }\r\n\r\n /** Cache registry loaders để tránh load lại */\r\n private registryLoaders = new Map<string, Observable<void>>();\r\n\r\n /**\r\n * Load registry từ grouped registry file và register tất cả icons của collection\r\n * Chỉ dùng trong docs app để load icons động cho icon picker\r\n * User projects KHÔNG nên dùng (dùng provideOlIcons với manual imports)\r\n */\r\n loadRegistry(collection: 'solar' | 'lucide' | 'mynaui' | 'olkit'): Observable<void> {\r\n // Check cache first\r\n if (this.registryLoaders.has(collection)) {\r\n return this.registryLoaders.get(collection)!;\r\n }\r\n\r\n // Load registry file với static import path\r\n const loader$ = from(\r\n (async () => {\r\n let registry: any;\r\n switch (collection) {\r\n case 'solar':\r\n registry = await import('./registries/solar.registry');\r\n break;\r\n case 'lucide':\r\n registry = await import('./registries/lucide.registry');\r\n break;\r\n case 'mynaui':\r\n registry = await import('./registries/mynaui.registry');\r\n break;\r\n case 'olkit':\r\n registry = await import('./registries/olkit.registry');\r\n break;\r\n }\r\n const icons = registry['_REGISTRY'];\r\n if (!icons) {\r\n throw new Error(`Registry ${collection} does not export _REGISTRY`);\r\n }\r\n console.log(`[OlIconService] Registering ${Object.keys(icons).length} icons from ${collection}`);\r\n this.register(icons);\r\n console.log(`[OlIconService] Successfully registered ${collection} registry`);\r\n })()\r\n ).pipe(\r\n catchError((err) => {\r\n console.error(`[OlIconService] Failed to load registry ${collection}:`, err);\r\n return of(void 0);\r\n }),\r\n shareReplay(1)\r\n );\r\n\r\n this.registryLoaders.set(collection, loader$);\r\n return loader$;\r\n }\r\n\r\n /**\r\n * Lấy SVG SafeHtml cho icon theo tên và biến thể\r\n * Tự động load registry nếu icon chưa có (dùng trong docs app)\r\n */\r\n getIcon(name: string, variant: string = 'linear'): Observable<SafeHtml | null> {\r\n if (typeof name !== 'string' || !name.trim()) return of(null);\r\n\r\n // Try sync first\r\n const sync = this.getIconSync(name, variant);\r\n if (sync) return of(sync);\r\n\r\n // Auto-add olkit: prefix nếu không có collection prefix\r\n const trimmed = name.trim().toLowerCase();\r\n const normName = trimmed.includes(':') ? trimmed : `olkit:${trimmed}`;\r\n let resolvedName = this.aliasMap[trimmed] || this.aliasMap[normName] || normName;\r\n if (!resolvedName.includes(':')) {\r\n resolvedName = `olkit:${resolvedName}`;\r\n }\r\n\r\n // Extract collection từ resolved name (e.g., \"solar:home-2-linear\" → \"solar\", \"olkit:book\" → \"olkit\")\r\n const [collection] = resolvedName.split(':');\r\n if (!collection || !['solar', 'lucide', 'mynaui', 'olkit'].includes(collection)) {\r\n return of(null);\r\n }\r\n\r\n // Load registry và retry\r\n return this.loadRegistry(collection as any).pipe(\r\n map(() => this.getIconSync(name, variant))\r\n );\r\n }\r\n\r\n /** Bảng bí danh — xem `icon-aliases.ts` (dùng chung với script sinh bộ lõi). */\r\n private readonly aliasMap = ICON_ALIASES;\r\n\r\n private normalizeKey(name: string, variant?: string): string {\r\n const v = variant || 'linear';\r\n const trimmed = name.trim().toLowerCase();\r\n if (trimmed in CORE_ICONS) {\r\n return `${v}:${trimmed}`;\r\n }\r\n const withPrefix = trimmed.includes(':') ? trimmed : `olkit:${trimmed}`;\r\n let resolvedName = this.aliasMap[trimmed] || this.aliasMap[withPrefix] || withPrefix;\r\n if (!resolvedName.includes(':')) {\r\n resolvedName = `olkit:${resolvedName}`;\r\n }\r\n return `${v}:${resolvedName}`;\r\n }\r\n\r\n private cleanSvg(svgText: string): string {\r\n let cleaned = svgText.trim();\r\n\r\n // 1. Chuẩn hóa thẻ <svg>: bỏ width/height cố định để scale vector mượt mà theo CSS\r\n cleaned = cleaned.replace(/<svg\\s+([^>]*?)>/i, (match, attrs) => {\r\n // Giữ viewBox, bỏ width và height tĩnh nếu có\r\n let newAttrs = attrs\r\n .replace(/\\bwidth=\"[^\"]*\"/gi, '')\r\n .replace(/\\bheight=\"[^\"]*\"/gi, '')\r\n .trim();\r\n\r\n if (!newAttrs.includes('class=')) {\r\n newAttrs += ' class=\"w-full h-full block\"';\r\n }\r\n if (!newAttrs.includes('shape-rendering=')) {\r\n newAttrs += ' shape-rendering=\"geometricPrecision\"';\r\n }\r\n return `<svg ${newAttrs}>`;\r\n });\r\n\r\n // 2. Chuyển đổi stroke và fill cứng sang currentColor\r\n // Detect multicolor: gradient, url patterns, hoặc nhiều màu fill/stroke khác nhau\r\n const fillColors = cleaned.match(/fill=\"#[0-9a-fA-F]{3,8}\"/gi) || [];\r\n const strokeColors = cleaned.match(/stroke=\"#[0-9a-fA-F]{3,8}\"/gi) || [];\r\n const uniqueFills = new Set(fillColors.map((f) => f.toLowerCase()));\r\n const uniqueStrokes = new Set(strokeColors.map((s) => s.toLowerCase()));\r\n\r\n const isSpecialMulticolor =\r\n cleaned.includes('url(#') ||\r\n cleaned.includes('linearGradient') ||\r\n cleaned.includes('radialGradient') ||\r\n uniqueFills.size > 1 || // Nhiều màu fill khác nhau\r\n uniqueStrokes.size > 1; // Nhiều màu stroke khác nhau\r\n\r\n if (!isSpecialMulticolor) {\r\n // Convert all stroke=\"#...\" to stroke=\"currentColor\"\r\n cleaned = cleaned.replace(/stroke=\"#[0-9a-fA-F]{3,8}\"/gi, 'stroke=\"currentColor\"');\r\n // Convert all fill=\"#...\" to fill=\"currentColor\" (for monochrome icons)\r\n cleaned = cleaned.replace(/fill=\"#[0-9a-fA-F]{3,8}\"/gi, 'fill=\"currentColor\"');\r\n }\r\n\r\n return cleaned;\r\n }\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n signal,\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { SafeHtml } from '@angular/platform-browser';\r\nimport { OL_ICONS, OlIconService } from './icon.service';\r\n\r\n/**\r\n * Icon nhiều màu — không được áp class màu đè lên.\r\n * Nguồn: src/assets/iconify/olkit/catalog.json (metadata.isMulticolor).\r\n * Chỉ 11 icon nên nhúng thẳng, thay cho icon-metadata.ts 2,4 MB vốn sinh\r\n * hỏng: 443 mục olkit có isMulticolor nhưng bản TS mất sạch (0/10.860).\r\n */\r\nconst MULTICOLOR_ICONS = new Set<string>([\r\n '3d',\r\n 'audio',\r\n 'docx',\r\n 'onluyen-ai',\r\n 'onluyen-logo',\r\n 'pdf',\r\n 'photo',\r\n 'pptx',\r\n 'video',\r\n 'xlsx',\r\n 'zip',\r\n]);\r\n\r\nexport type IconSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | number;\r\nexport type IconColor =\r\n | 'current'\r\n | 'brand'\r\n | 'primary'\r\n | 'secondary'\r\n | 'success'\r\n | 'danger'\r\n | 'warning'\r\n | 'white'\r\n | 'muted'\r\n | string;\r\n\r\nexport type IconVariant =\r\n 'linear' | 'bold' | 'line-duotone' | 'file-type' | 'brand' | 'custom' | string;\r\n\r\n@Component({\r\n selector: 'ol-icon',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n @if (svgContent(); as svg) {\r\n <span\r\n [class]=\"containerClasses()\"\r\n [style.width]=\"customPixelSize()\"\r\n [style.height]=\"customPixelSize()\"\r\n [style.stroke-width]=\"strokeWidth()\"\r\n [style.color]=\"isCustomColor() ? color() : null\"\r\n [innerHTML]=\"svg\"\r\n ></span>\r\n } @else {\r\n <!-- Fallback / Loading placeholder -->\r\n <span\r\n [class]=\"containerClasses()\"\r\n [style.width]=\"customPixelSize()\"\r\n [style.height]=\"customPixelSize()\"\r\n [style.color]=\"isCustomColor() ? color() : null\"\r\n ></span>\r\n }\r\n `,\r\n styles: [\r\n `\r\n :host {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n vertical-align: middle;\r\n line-height: 1;\r\n flex-shrink: 0;\r\n }\r\n :host ::ng-deep svg {\r\n width: 100%;\r\n height: 100%;\r\n display: block;\r\n shape-rendering: geometricPrecision;\r\n text-rendering: geometricPrecision;\r\n }\r\n `,\r\n ],\r\n host: {\r\n class: 'inline-flex items-center justify-center shrink-0 leading-none align-middle',\r\n },\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class OlIcon {\r\n private readonly iconService = inject(OlIconService);\r\n private readonly localIcons = inject(OL_ICONS, { optional: true });\r\n\r\n readonly name = input.required<string>();\r\n readonly size = input<IconSize>('base');\r\n readonly color = input<IconColor>('current');\r\n readonly variant = input<IconVariant>('linear');\r\n readonly strokeWidth = input<string | number | null>(null);\r\n\r\n private readonly asyncSvg = signal<SafeHtml | null>(null);\r\n\r\n readonly svgContent = computed<SafeHtml | null>(() => {\r\n const n = this.name();\r\n const v = this.variant();\r\n const sync = this.iconService.getIconSync(n, v);\r\n if (sync) return sync;\r\n return this.asyncSvg();\r\n });\r\n\r\n constructor() {\r\n if (this.localIcons) {\r\n for (const group of this.localIcons) {\r\n this.iconService.register(group);\r\n }\r\n }\r\n\r\n effect(() => {\r\n const n = this.name();\r\n const v = this.variant();\r\n const sync = this.iconService.getIconSync(n, v);\r\n if (!sync) {\r\n this.asyncSvg.set(null);\r\n this.iconService.getIcon(n, v).subscribe((svg) => {\r\n this.asyncSvg.set(svg);\r\n });\r\n }\r\n });\r\n }\r\n\r\n readonly isNumericSize = computed(() => {\r\n const sz = this.size();\r\n return typeof sz === 'number';\r\n });\r\n\r\n readonly customPixelSize = computed(() => {\r\n const sz = this.size();\r\n if (typeof sz === 'number') {\r\n return `${sz}px`;\r\n }\r\n return null;\r\n });\r\n\r\n readonly sizeClasses = computed(() => {\r\n if (this.isNumericSize()) return '';\r\n\r\n switch (this.size()) {\r\n case 'xs':\r\n return 'w-3.5 h-3.5';\r\n case 'sm':\r\n return 'w-4 h-4';\r\n case 'base':\r\n return 'w-5 h-5';\r\n case 'lg':\r\n return 'w-6 h-6';\r\n case 'xl':\r\n return 'w-8 h-8';\r\n case '2xl':\r\n return 'w-10 h-10';\r\n case '3xl':\r\n return 'w-12 h-12';\r\n default:\r\n return 'w-5 h-5';\r\n }\r\n });\r\n\r\n readonly isCustomColor = computed(() => {\r\n const c = this.color();\r\n return (\r\n typeof c === 'string' && (c.startsWith('#') || c.startsWith('rgb') || c.startsWith('hsl'))\r\n );\r\n });\r\n\r\n readonly isMulticolor = computed(() => {\r\n const n = this.name();\r\n if (!n) return false;\r\n return MULTICOLOR_ICONS.has(\r\n n\r\n .trim()\r\n .toLowerCase()\r\n .replace(/^olkit:/, ''),\r\n );\r\n });\r\n\r\n readonly colorClasses = computed(() => {\r\n if (this.isMulticolor() || this.isCustomColor()) return '';\r\n\r\n switch (this.color()) {\r\n case 'current':\r\n return 'text-current';\r\n case 'white':\r\n return 'text-white';\r\n case 'primary':\r\n return 'text-heading';\r\n case 'secondary':\r\n return 'text-body';\r\n // Token fg-* tự đổi theo chế độ sáng/tối nên không cần cặp `dark:` viết tay.\r\n case 'brand':\r\n return 'text-fg-brand';\r\n case 'muted':\r\n return 'text-fg-disabled';\r\n case 'success':\r\n return 'text-fg-success';\r\n case 'danger':\r\n return 'text-fg-danger';\r\n case 'warning':\r\n return 'text-fg-warning';\r\n case 'purple':\r\n return 'text-fg-purple';\r\n case 'pink':\r\n return 'text-fg-pink';\r\n case 'cyan':\r\n return 'text-fg-cyan';\r\n case 'indigo':\r\n return 'text-fg-indigo';\r\n default: {\r\n // `isCustomColor()` đã loại `typeof c !== 'string'`, nên `undefined`\r\n // rơi thẳng xuống đây và `.startsWith` ném TypeError. `input()` có mặc\r\n // định KHÔNG chặn được undefined lúc chạy khi nơi gọi bind biểu thức.\r\n const c = this.color();\r\n return typeof c === 'string' && c.startsWith('text-') ? c : 'text-current';\r\n }\r\n }\r\n });\r\n\r\n readonly containerClasses = computed(() => {\r\n return `inline-flex items-center justify-center shrink-0 ${this.sizeClasses()} ${this.colorClasses()}`;\r\n });\r\n}\r\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { OlIcon } from '../icon/icon.component';\r\n\r\nexport type IconShapeSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl';\r\nexport type IconShapeColor = 'brand' | 'white' | 'dark' | 'red' | 'gray' | 'green' | 'yellow';\r\nexport type IconShapeType = 'circle' | 'square';\r\n\r\n@Component({\r\n selector: 'ol-icon-shape',\r\n standalone: true,\r\n imports: [CommonModule, OlIcon],\r\n templateUrl: './icon-shape.component.html',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class OlIconShape {\r\n readonly icon = input<string>('');\r\n readonly size = input<IconShapeSize>('base');\r\n readonly color = input<IconShapeColor>('brand');\r\n readonly type = input<IconShapeType>('circle');\r\n\r\n readonly iconSize = computed<number>(() => {\r\n switch (this.size()) {\r\n case 'xs':\r\n return 10;\r\n case 'sm':\r\n return 16;\r\n case 'base':\r\n return 20;\r\n case 'lg':\r\n return 28;\r\n case 'xl':\r\n return 36;\r\n case '2xl':\r\n return 56;\r\n default:\r\n return 20;\r\n }\r\n });\r\n}\r\n","<!-- Figma ol-icon-shape (#1149:56578): cả White và Gray dùng text-body.\r\n Hai [class.text-body] riêng sẽ bị Angular gộp làm một binding và cái sau\r\n thắng, nên phải gộp điều kiện bằng ||.\r\n\r\n Bo góc: đọc đủ 84 variant Figma — Square bo 12px ở MỌI size, Circle luôn\r\n tròn. Không có thang bo góc nào. Sáu dòng cũ khai ba [class.rounded-md]\r\n trùng tên nên Angular chỉ giữ dòng cuối; `sm` và `lg` mất bo góc hoàn toàn\r\n (đo ra 0px). Chú thích phải nằm NGOÀI thẻ mở — đặt giữa danh sách thuộc\r\n tính là hỏng build. -->\r\n<div\r\n class=\"inline-flex items-center justify-center shrink-0 leading-none select-none\"\r\n [class.rounded-full]=\"type() === 'circle'\"\r\n [class.rounded-md]=\"type() === 'square'\"\r\n [class.w-4]=\"size() === 'xs'\"\r\n [class.h-4]=\"size() === 'xs'\"\r\n [class.w-6]=\"size() === 'sm'\"\r\n [class.h-6]=\"size() === 'sm'\"\r\n [class.w-9]=\"size() === 'base'\"\r\n [class.h-9]=\"size() === 'base'\"\r\n [class.w-12]=\"size() === 'lg'\"\r\n [class.h-12]=\"size() === 'lg'\"\r\n [class.w-16]=\"size() === 'xl'\"\r\n [class.h-16]=\"size() === 'xl'\"\r\n [class.w-24]=\"size() === '2xl'\"\r\n [class.h-24]=\"size() === '2xl'\"\r\n [class.bg-brand-softer]=\"color() === 'brand'\"\r\n [class.text-fg-brand]=\"color() === 'brand'\"\r\n [class.bg-neutral-primary-medium]=\"color() === 'white'\"\r\n [class.border]=\"color() === 'white'\"\r\n [class.border-default-medium]=\"color() === 'white'\"\r\n [class.bg-dark]=\"color() === 'dark'\"\r\n [class.text-white]=\"color() === 'dark'\"\r\n [class.bg-danger-soft]=\"color() === 'red'\"\r\n [class.text-fg-danger-strong]=\"color() === 'red'\"\r\n [class.bg-neutral-tertiary]=\"color() === 'gray'\"\r\n [class.text-body]=\"color() === 'white' || color() === 'gray'\"\r\n [class.bg-success-soft]=\"color() === 'green'\"\r\n [class.text-fg-success-strong]=\"color() === 'green'\"\r\n [class.bg-warning-soft]=\"color() === 'yellow'\"\r\n [class.text-fg-warning]=\"color() === 'yellow'\"\r\n>\r\n @if (icon()) {\r\n <ol-icon [name]=\"icon()\" [size]=\"iconSize()\" />\r\n } @else {\r\n <ng-content />\r\n }\r\n</div>\r\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\r\n\r\nexport type OlIconStackSize = 'sm' | 'base' | 'lg';\r\n\r\n/**\r\n * Chồng nhiều icon hoặc logo lên nhau, kèm số đếm \"+N\".\r\n *\r\n * Chưa có node Figma — dựng theo `ol-avatar-group`, component cùng cơ chế đã\r\n * có trong thư viện. Khác ở chỗ: avatar là ảnh người nên luôn tròn, còn icon\r\n * thường là biểu tượng dịch vụ hay môn học nên mặc định bo vừa (`rounded-lg`)\r\n * và có nền để icon một màu vẫn tách khỏi icon bên dưới.\r\n *\r\n * ## Vòng viền là thứ làm nên hiệu ứng chồng\r\n *\r\n * Mỗi ô có `ring-2 ring-buffer` — vòng viền màu nền trang, không phải viền\r\n * màu. Nhờ nó hai ô chồng nhau vẫn thấy rõ ranh giới. Bỏ vòng này thì các ô\r\n * dính thành một khối nhoè.\r\n *\r\n * `ring-buffer` chứ không `ring-white`: ở chế độ tối nền không phải trắng, và\r\n * viền trắng trên nền đen là đường kẻ sáng chói quanh mỗi icon.\r\n *\r\n * ## Thứ tự chồng\r\n *\r\n * Mặc định ô ĐẦU nằm trên — giống xếp bài. `reverse` lật lại cho ô cuối nằm\r\n * trên, dùng khi ô cuối là thứ cần nhấn (icon \"thêm\", trạng thái mới nhất).\r\n *\r\n * Làm bằng `flex-row-reverse` cộng đảo thứ tự dữ liệu chứ không bằng\r\n * `z-index`: `z-index` cần stacking context và sẽ hỏng khi nơi gọi đặt\r\n * component vào một phần tử có `transform` hay `opacity`.\r\n */\r\n@Component({\r\n selector: 'ol-icon-stack',\r\n standalone: true,\r\n template: `\r\n <div [class]=\"rootClasses()\">\r\n <ng-content />\r\n\r\n @if (counter()) {\r\n <!-- Xem chú thích counterClasses() về lựa chọn màu chữ. -->\r\n <span [class]=\"counterClasses()\" [attr.aria-label]=\"counterAriaLabel()\">\r\n {{ counter() }}\r\n </span>\r\n }\r\n </div>\r\n `,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: { class: 'inline-block' },\r\n})\r\nexport class OlIconStack {\r\n readonly size = input<OlIconStackSize>('base');\r\n\r\n /** Số đếm \"+N\" ở cuối. `null` thì không vẽ. */\r\n readonly counter = input<string | number | null>(null);\r\n\r\n readonly counterAriaLabel = input<string>('mục khác');\r\n\r\n /** Lật thứ tự chồng: ô CUỐI nằm trên thay vì ô đầu. */\r\n readonly reverse = input<boolean>(false);\r\n\r\n /**\r\n * Bo góc của từng ô. `full` cho logo tròn, `lg` cho biểu tượng vuông.\r\n *\r\n * Áp lên CON qua biến thể `*:` của Tailwind, nên nơi gọi chỉ việc đặt\r\n * `<ol-icon>` hay `<img>` vào là xong.\r\n */\r\n readonly rounded = input<'lg' | 'full'>('lg');\r\n\r\n protected readonly rootClasses = computed(() => {\r\n const gap = { sm: '-space-x-1.5', base: '-space-x-2', lg: '-space-x-2.5' }[this.size() as OlIconStackSize];\r\n const box = { sm: '*:size-6', base: '*:size-8', lg: '*:size-10' }[this.size() as OlIconStackSize];\r\n const radius = this.rounded() === 'full' ? '*:rounded-full' : '*:rounded-lg';\r\n const dir = this.reverse() ? 'flex-row-reverse space-x-reverse' : '';\r\n\r\n return [\r\n 'flex items-center',\r\n gap,\r\n dir,\r\n // Vòng viền màu nền trang tạo ranh giới giữa hai ô chồng nhau.\r\n `${box} ${radius} *:shrink-0 *:ring-2 *:ring-buffer *:bg-neutral-secondary`,\r\n '*:flex *:items-center *:justify-center *:text-body-subtle',\r\n ].join(' ');\r\n });\r\n\r\n /**\r\n * Ô đếm \"+N\".\r\n *\r\n * `text-heading` chứ KHÔNG `text-body`: tổ hợp `bg-neutral-quaternary` +\r\n * `text-body` đo được 6.10 ở chế độ sáng nhưng chỉ 3.96 ở chế độ tối — dưới\r\n * ngưỡng WCAG 4.5. Đây là kết luận đã đo ở `ol-avatar-group` (BUG-016 mục 5),\r\n * theo tiền lệ sẵn có chứ không đoán lại.\r\n *\r\n * Chú thích để Ở ĐÂY chứ không trong template: template là một chuỗi\r\n * template literal, nên dấu backtick trong chú thích HTML đóng chuỗi sớm và\r\n * TS báo lỗi ở dòng chẳng liên quan (đã mắc khi viết file này).\r\n */\r\n protected readonly counterClasses = computed(() => {\r\n const font = { sm: 'text-2xs', base: 'text-xs', lg: 'text-sm' }[this.size() as OlIconStackSize];\r\n return `font-medium bg-neutral-quaternary text-heading select-none ${font}`;\r\n });\r\n}\r\n"],"mappings":";;;;;;AAOA,MAAa,eAAiD;CAc5D,OAAO;CAmBP,OAAO;CACP,GAAG;CAEH,OAAO;CAcP,MAAM;CACN,MAAM;CACN,OAAO;CACP,eAAe;CACf,OAAO;CACP,aAAa;CACb,iBAAiB;CACjB,mBAAmB;CACnB,uBAAuB;CACvB,cAAc;CACd,cAAc;CACd,UAAU;CACV,eAAe;CACf,SAAS;CACT,cAAc;CACd,aAAa;CACb,MAAM;CACN,SAAS;CACT,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,WAAW;CACX,kBAAkB;CAClB,cAAc;CACd,gBAAgB;CAChB,0BAA0B;CAC1B,wBAAwB;CACxB,gBAAgB;CAChB,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB;CACjB,cAAc;CACd,cAAc;CACd,eAAe;CACf,0BAA0B;CAC1B,iBAAiB;CACjB,iBAAiB;CACjB,SAAS;CACT,iBAAiB;CACjB,gBAAgB;CAChB,eAAe;CACf,oBAAoB;CACpB,mBAAmB;CACnB,UAAU;CACV,QAAQ;CACR,oBAAoB;CACpB,cAAc;CACd,gBAAgB;CAChB,oBAAoB;CACpB,iBAAiB;CACjB,oBAAoB;CACpB,cAAc;CACd,cAAc;CACd,YAAY;CACZ,kBAAkB;CAClB,UAAU;CACV,gBAAgB;CAChB,gBAAgB;CAChB,YAAY;CACZ,WAAW;CACX,aAAa;CACb,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,aAAa;AACd;ACjHD,MAAa,aAA+C;CAC1D,kBACE;CACF,kBACE;CACF,mBACE;CACF,cACE;CACF,eACE;CACF,UACE;CACF,gBACE;CACF,OACE;CACF,gBACE;CACF,gBACE;CACF,gBACE;CACF,iBACE;CACF,gBACE;CACF,OACE;CACF,gBACE;CACF,iBACE;CACF,mBACE;CACF,UACE;CACF,eACE;CACF,MAAM;CACN,MAAM;CACN,eACE;CACF,eACE;CACF,eACE;CACF,uBACE;CACF,oBACE;CACF,qBACE;CACF,qBACE;CACF,2BACE;CACF,oBACE;CACF,oBACE;CACF,4BACE;CACF,iBACE;CACF,eACE;CACF,uBA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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edmicro/olkit-icons",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "Icon collections and components for Ôn Luyện Design System",
5
5
  "author": "EDMICRO",
6
6
  "license": "MIT",
@@ -8,14 +8,7 @@
8
8
  "type": "git",
9
9
  "url": "https://gitlab.edmicro.io/onluyenpub/olkit-deploy.git"
10
10
  },
11
- "keywords": [
12
- "icons",
13
- "angular",
14
- "design-system",
15
- "solar-icons",
16
- "lucide",
17
- "mynaui"
18
- ],
11
+ "keywords": [],
19
12
  "peerDependencies": {
20
13
  "@angular/common": "^22.0.0",
21
14
  "@angular/core": "^22.0.0"
@@ -24,6 +17,9 @@
24
17
  "tslib": "^2.3.0"
25
18
  },
26
19
  "sideEffects": false,
20
+ "bin": {
21
+ "olkit-icons": "./bin/olkit-icons.js"
22
+ },
27
23
  "exports": {
28
24
  ".": {
29
25
  "types": "./types/edmicro-olkit-icons.d.ts",
@@ -7,6 +7,7 @@ export type IconColor = 'current' | 'brand' | 'primary' | 'secondary' | 'success
7
7
  export type IconVariant = 'linear' | 'bold' | 'line-duotone' | 'file-type' | 'brand' | 'custom' | string;
8
8
  export declare class OlIcon {
9
9
  private readonly iconService;
10
+ private readonly localIcons;
10
11
  readonly name: import("@angular/core").InputSignal<string>;
11
12
  readonly size: import("@angular/core").InputSignal<IconSize>;
12
13
  readonly color: import("@angular/core").InputSignal<string>;
@@ -69,27 +70,23 @@ export declare const OL_ICONS: InjectionToken<readonly Record<string, string>[]>
69
70
  *
70
71
  * Bundler chỉ giữ đúng các hằng được import (~2-5 KB/icon).
71
72
  */
72
- export declare function provideOlIcons(icons: Record<string, string>): Provider[];
73
+ export declare function provideOlIcons(icons: Record<string, string> | (string | string[])[]): Provider[];
73
74
  /**
74
- * Đăng ký icon theo TÊN - chỉ cần string, không cần import constants.
75
+ * Đăng ký icon theo TÊN - chỉ cần string, không cần import constants hay nhớ 13k tên.
75
76
  *
76
77
  * ```ts
77
78
  * import { provideOlIconsByName } from '@edmicro/olkit-icons';
78
79
  *
79
- * @Component({
80
+ * bootstrapApplication(App, {
80
81
  * providers: [
81
- * provideOlIconsByName([['solar:home-2-linear'], ['olkit:logo']])
82
+ * provideOlIconsByName(['solar:home-2-linear', 'lucide:cog', 'user-circle'])
82
83
  * ],
83
- * })
84
+ * });
84
85
  * ```
85
86
  *
86
- * **QUAN TRỌNG:** Để bundle size tối ưu (~2-5 KB/icon), phải dùng esbuild plugin.
87
- * Plugin sẽ tự động transform call này thành `provideOlIcons()` với direct imports.
88
- * Xem README để setup plugin trong angular.json.
89
- *
90
- * Nếu không dùng plugin, function này sẽ không làm gì (icons không load).
87
+ * Plugin build sẽ tự động suy luận ngược từ chuỗi tên thành file và constant tương ứng để tree-shaking.
91
88
  */
92
- export declare function provideOlIconsByName(iconNames: string[][]): Provider[];
89
+ export declare function provideOlIconsByName(iconNames: (string | string[])[]): Provider[];
93
90
  /**
94
91
  * Service quản lý icons cho Ôn Luyện Design System.
95
92
  *
@@ -104,8 +101,19 @@ export declare class OlIconService {
104
101
  /**
105
102
  * Đăng ký icon lúc chạy — cùng tác dụng với `provideOlIcons`, cho nơi cần
106
103
  * thêm icon sau khi ứng dụng đã khởi động. Tên trùng thì bản sau thắng.
104
+ *
105
+ * Tự động suy luận ngược từ tên hằng số (SOLAR_HOME_2_LINEAR) sang tên icon ('solar:home-2-linear'),
106
+ * cho phép người dùng truyền trực tiếp: provideOlIcons({ SOLAR_HOME_2_LINEAR, OLKIT_USER_CIRCLE }).
107
107
  */
108
108
  register(icons: Record<string, string>): void;
109
+ /**
110
+ * Suy luận ngược từ tên hằng số sang tên icon chuẩn:
111
+ * SOLAR_HOME_2_LINEAR -> solar:home-2-linear
112
+ * OLKIT_USER_CIRCLE -> olkit:user-circle
113
+ * LUCIDE_COG -> lucide:cog
114
+ * MYNAUI_SEARCH -> mynaui:search
115
+ */
116
+ constantToIconName(constantName: string): string | null;
109
117
  /**
110
118
  * Lấy SVG SafeHtml sync (chỉ trả icon đã load trong cache hoặc core icons)
111
119
  * Không load registry - dùng getIcon() cho async loading
package/version.txt CHANGED
@@ -1,3 +1,3 @@
1
- Version: 1.0.15
2
- Build Time: 2026-10-12 15:33:15
1
+ Version: 1.0.16
2
+ Build Time: 2026-10-12 17:05:31
3
3
  Total Icons: 13,915