vueless 0.0.489 → 0.0.491

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/constants.js +11 -2
  2. package/package.json +1 -1
  3. package/plugin-vite.d.ts +1 -0
  4. package/plugin-vite.js +25 -16
  5. package/ui.form-select/USelect.vue +0 -1
  6. package/ui.image-icon/UIcon.vue +13 -20
  7. package/ui.loader/ULoader.vue +26 -28
  8. package/utils/node/helper.js +20 -8
  9. package/utils/node/loaderIcon.js +198 -121
  10. package/utils/node/loaderSvg.js +3 -3
  11. package/utils/node/vuelessConfig.js +5 -2
  12. package/web-types.json +1 -1
  13. package/assets/icons/add.svg +0 -1
  14. package/assets/icons/apps.svg +0 -1
  15. package/assets/icons/arrow_back.svg +0 -1
  16. package/assets/icons/attach_file.svg +0 -1
  17. package/assets/icons/calendar_month-fill.svg +0 -1
  18. package/assets/icons/check.svg +0 -1
  19. package/assets/icons/check_circle.svg +0 -1
  20. package/assets/icons/chevron_left.svg +0 -1
  21. package/assets/icons/chevron_right.svg +0 -1
  22. package/assets/icons/close.svg +0 -1
  23. package/assets/icons/close_small.svg +0 -1
  24. package/assets/icons/delete.svg +0 -1
  25. package/assets/icons/description.svg +0 -1
  26. package/assets/icons/drag_indicator.svg +0 -1
  27. package/assets/icons/edit.svg +0 -1
  28. package/assets/icons/edit_note.svg +0 -1
  29. package/assets/icons/emoji_food_beverage.svg +0 -1
  30. package/assets/icons/error.svg +0 -1
  31. package/assets/icons/expand_more.svg +0 -1
  32. package/assets/icons/first_page.svg +0 -1
  33. package/assets/icons/image.svg +0 -1
  34. package/assets/icons/keyboard_arrow_down.svg +0 -1
  35. package/assets/icons/keyboard_arrow_left.svg +0 -1
  36. package/assets/icons/keyboard_arrow_right.svg +0 -1
  37. package/assets/icons/label.svg +0 -1
  38. package/assets/icons/last_page.svg +0 -1
  39. package/assets/icons/remove.svg +0 -1
  40. package/assets/icons/search.svg +0 -1
  41. package/assets/icons/star-fill.svg +0 -1
  42. package/assets/icons/star.svg +0 -1
  43. package/assets/icons/title.svg +0 -1
  44. package/assets/icons/visibility-fill.svg +0 -1
  45. package/assets/icons/visibility_off-fill.svg +0 -1
  46. package/assets/icons/warning.svg +0 -1
package/constants.js CHANGED
@@ -185,6 +185,17 @@ export const DEFAULT_SVGO_CONFIG = {
185
185
  ],
186
186
  };
187
187
 
188
+ /* Vueless general */
189
+ export const ICONS_DIR = "assets/icons";
190
+ export const VUELESS_LIBRARY = "vueless";
191
+ export const VUELESS_CONFIG_FILE_NAME = "vueless.config";
192
+ export const VUELESS_CACHE_DIR = "node_modules/.cache/vueless";
193
+ export const VUELESS_DIR = `node_modules/${VUELESS_LIBRARY}`;
194
+ export const VUELESS_LOCAL_DIR = `src`;
195
+ export const VUELESS_ICONS_DIR = `${VUELESS_DIR}/${ICONS_DIR}`;
196
+ export const VUELESS_ICONS_LOCAL_DIR = `src/${ICONS_DIR}`;
197
+ export const VUELESS_ICONS_CACHED_DIR = `${VUELESS_CACHE_DIR}/${ICONS_DIR}`;
198
+
188
199
  /* Other */
189
200
  export const PX_IN_REM = 16;
190
201
  export const NESTED_COMPONENT_REG_EXP = /\{U[^}]*}/g;
@@ -192,5 +203,3 @@ export const DYNAMIC_COLOR_PATTERN = "{color}";
192
203
  export const TAILWIND_COLOR_OPACITY_DELIMITER = "/";
193
204
  export const TAILWIND_VARIANT_DELIMITER = ":";
194
205
  export const TAILWIND_VARIANT_DELIMITER_REG_EXP = /:(?![^[]*])/;
195
- export const CACHE_PATH = "node_modules/.cache/vueless";
196
- export const VUELESS_CONFIG_FILE_NAME = "vueless.config";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.489",
3
+ "version": "0.0.491",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
6
6
  "keywords": [
package/plugin-vite.d.ts CHANGED
@@ -7,4 +7,5 @@ export function Vueless(options?: {
7
7
  mode?: string;
8
8
  debug?: boolean;
9
9
  include?: string[];
10
+ mirrorCacheDir?: string;
10
11
  }): never;
package/plugin-vite.js CHANGED
@@ -6,9 +6,9 @@
6
6
  import UnpluginVueComponents from "unplugin-vue-components/vite";
7
7
 
8
8
  import { loadSvg } from "./utils/node/loaderSvg.js";
9
- import { copyIcons, removeIcons } from "./utils/node/loaderIcon.js";
9
+ import { cacheIcons, removeIconsCache, copyIconsCache } from "./utils/node/loaderIcon.js";
10
10
  import { createTailwindSafelist, clearTailwindSafelist } from "./utils/node/tailwindSafelist.js";
11
- import { getNuxtFiles, getVueSourceFile } from "./utils/node/helper.js";
11
+ import { getNuxtFiles, getVueFiles } from "./utils/node/helper.js";
12
12
  import { componentResolver, directiveResolver } from "./utils/node/vuelessResolver.js";
13
13
 
14
14
  /* Automatically importing Vueless components on demand */
@@ -25,21 +25,22 @@ export const VuelessUnpluginComponents = (options) =>
25
25
  – Loads SVG images as a Vue components.
26
26
  */
27
27
  export const Vueless = function (options = {}) {
28
- const { mode, debug, env, include } = options;
28
+ const { mode, debug, env, include, mirrorCacheDir } = options;
29
29
 
30
30
  const isVuelessEnv = env === "vueless";
31
31
  const isNuxt = mode === "nuxt-module";
32
- const srcDir = isNuxt ? process.cwd() : getVueSourceFile();
33
32
 
34
- const targetFiles = [srcDir, ...(include || []), ...(isNuxt ? getNuxtFiles() : [])];
33
+ const targetFiles = [...(include || []), ...(isNuxt ? getNuxtFiles() : getVueFiles())];
35
34
 
36
35
  /* if server stopped by developer (Ctrl+C) */
37
36
  process.on("SIGINT", async () => {
38
- /* remove dynamically copied icons */
39
- await removeIcons({ debug, isNuxt });
37
+ /* remove cached icons */
38
+ await removeIconsCache(mirrorCacheDir, debug);
40
39
 
41
40
  /* clear tailwind safelist */
42
41
  clearTailwindSafelist(debug);
42
+
43
+ /* stop command line process */
43
44
  process.exit(0);
44
45
  });
45
46
 
@@ -57,28 +58,36 @@ export const Vueless = function (options = {}) {
57
58
  }),
58
59
 
59
60
  configResolved: async (config) => {
60
- /* collect used in project colors for tailwind safelist */
61
61
  if (!isNuxt) {
62
+ /* collect used in project colors for tailwind safelist */
62
63
  await createTailwindSafelist({ mode, env, debug, targetFiles });
63
64
  }
64
65
 
65
66
  if (config.command === "build") {
66
- await removeIcons({ debug, isNuxt });
67
+ /* remove cached icons */
68
+ await removeIconsCache(mirrorCacheDir, debug);
69
+
70
+ /* cache vueless built-in and project icons */
71
+ await cacheIcons({ mode: "vuelessIcons", env, debug, targetFiles });
72
+ await cacheIcons({ mode, env, debug, targetFiles });
67
73
 
68
- /* dynamically copy used icons before build */
69
- await copyIcons({ mode: "vuelessIcons", env, debug, targetFiles });
70
- await copyIcons({ mode, env, debug, targetFiles, isNuxt });
74
+ /* copy vueless cache folder */
75
+ await copyIconsCache(mirrorCacheDir, debug);
71
76
  }
72
77
 
73
78
  if (config.command === "dev" || config.command === "serve") {
74
- /* remove dynamically copied icons on dev server start */
75
- await removeIcons({ debug, isNuxt });
79
+ /* remove cached icons */
80
+ await removeIconsCache(mirrorCacheDir, debug);
81
+ /* cache vueless built-in icons */
82
+ await cacheIcons({ mode: "vuelessIcons", env, debug, targetFiles });
83
+ /* copy vueless cache folder */
84
+ await copyIconsCache(mirrorCacheDir, debug);
76
85
  }
77
86
  },
78
87
 
79
- /* remove dynamically copied icons after build */
80
88
  buildEnd: async () => {
81
- await removeIcons({ debug, isNuxt });
89
+ /* remove cached icons */
90
+ await removeIconsCache(mirrorCacheDir, debug);
82
91
  },
83
92
 
84
93
  /* load SVG images as a Vue components */
@@ -209,7 +209,6 @@
209
209
  autocomplete="off"
210
210
  :spellcheck="false"
211
211
  :placeholder="inputPlaceholder"
212
- :value="search"
213
212
  :disabled="disabled"
214
213
  :aria-controls="'listbox-' + elementId"
215
214
  v-bind="searchInputAttrs"
@@ -11,15 +11,15 @@
11
11
 
12
12
  <script setup>
13
13
  import { computed, defineAsyncComponent } from "vue";
14
+ import { vTooltip } from "../directives";
14
15
  import { getDefault } from "../utils/ui.ts";
15
16
  import { isSSR } from "../utils/helper.ts";
17
+ import { VUELESS_ICONS_CACHED_DIR, VUELESS_LIBRARY } from "../constants.js";
16
18
 
17
19
  import { UIcon } from "./constants.js";
18
20
  import defaultConfig from "./config.ts";
19
21
  import useAttrs from "./useAttrs.js";
20
22
 
21
- import { vTooltip } from "../directives";
22
-
23
23
  defineOptions({ inheritAttrs: false });
24
24
 
25
25
  const props = defineProps({
@@ -127,21 +127,12 @@ const emit = defineEmits([
127
127
  const { config, iconAttrs } = useAttrs(props);
128
128
 
129
129
  const generatedIcons = computed(() => {
130
- /**
131
- * Use nuxt assets folders to include icons in final build.
132
- * TODO: Find another way to include icons in build
133
- */
134
- if (isSSR) {
135
- return (
136
- Object.entries(
137
- import.meta.glob(`/assets/.vueless/icons/**/*.svg`, { eager: true, query: "?component" }),
138
- ) || []
139
- );
140
- }
141
-
142
130
  return (
143
131
  Object.entries(
144
- import.meta.glob(`../assets/icons/**/*.svg`, { eager: true, query: "?component" }),
132
+ import.meta.glob(`/node_modules/.cache/vueless/assets/icons/**/*.svg`, {
133
+ eager: true,
134
+ query: "?component",
135
+ }),
145
136
  ) || []
146
137
  );
147
138
  });
@@ -149,10 +140,12 @@ const generatedIcons = computed(() => {
149
140
  const dynamicComponent = computed(() => {
150
141
  const FILL_SUFFIX = "-fill";
151
142
 
152
- const isDefaultIcon = Boolean(generatedIcons.value.find(([path]) => path.includes(props.name)));
153
- const userLibrary = config.value.defaults.library;
143
+ const isInternalIcon = Boolean(
144
+ generatedIcons.value.find(([path]) => path.includes(VUELESS_LIBRARY + "/" + props.name)),
145
+ );
154
146
 
155
- const library = props.internal && isDefaultIcon ? "vueless" : userLibrary;
147
+ const userLibrary = config.value.defaults.library;
148
+ const library = props.internal && isInternalIcon ? VUELESS_LIBRARY : userLibrary;
156
149
  const weight = config.value.defaults.weight;
157
150
  const style = config.value.defaults.style;
158
151
  const isFill = props.name.endsWith(FILL_SUFFIX);
@@ -185,8 +178,8 @@ const dynamicComponent = computed(() => {
185
178
  return import.meta.env.PROD
186
179
  ? await getIcon([name])
187
180
  : isSSR
188
- ? import(/* @vite-ignore */ `node_modules/vueless/assets/icons/${name}.svg?component`)
189
- : import(/* @vite-ignore */ `../assets/icons/${name}.svg?component`);
181
+ ? import(/* @vite-ignore */ `${VUELESS_ICONS_CACHED_DIR}/${VUELESS_LIBRARY}/${name}.svg?component`)
182
+ : import(/* @vite-ignore */ `/${VUELESS_ICONS_CACHED_DIR}/${VUELESS_LIBRARY}/${name}.svg?component`);
190
183
  },
191
184
  "@material-symbols": async () => {
192
185
  return import.meta.env.PROD
@@ -50,43 +50,41 @@ const { loaderAttrs, ellipseAttrs, config } = useAttrs(props);
50
50
  </script>
51
51
 
52
52
  <style scoped lang="postcss">
53
- .vueless-loader-ellipse {
54
- &:nth-child(1) {
55
- animation: ellipse-1 0.6s infinite;
56
- }
53
+ .vueless-loader-ellipse:nth-child(1) {
54
+ animation: ellipse-1 0.6s infinite;
55
+ }
57
56
 
58
- &:nth-child(4) {
59
- animation: ellipse-3 0.6s infinite;
60
- }
57
+ .vueless-loader-ellipse:nth-child(4) {
58
+ animation: ellipse-3 0.6s infinite;
59
+ }
61
60
 
62
- &-sm {
63
- &:nth-child(2) {
64
- animation: ellipse-2-sm 0.6s infinite;
65
- }
61
+ .vueless-loader-ellipse-sm {
62
+ &:nth-child(2) {
63
+ animation: ellipse-2-sm 0.6s infinite;
64
+ }
66
65
 
67
- &:nth-child(3) {
68
- animation: ellipse-2-sm 0.6s infinite;
69
- }
66
+ &:nth-child(3) {
67
+ animation: ellipse-2-sm 0.6s infinite;
70
68
  }
69
+ }
71
70
 
72
- &-md {
73
- &:nth-child(2) {
74
- animation: ellipse-2-md 0.6s infinite;
75
- }
71
+ .vueless-loader-ellipse-md {
72
+ &:nth-child(2) {
73
+ animation: ellipse-2-md 0.6s infinite;
74
+ }
76
75
 
77
- &:nth-child(3) {
78
- animation: ellipse-2-md 0.6s infinite;
79
- }
76
+ &:nth-child(3) {
77
+ animation: ellipse-2-md 0.6s infinite;
80
78
  }
79
+ }
81
80
 
82
- &-lg {
83
- &:nth-child(2) {
84
- animation: ellipse-2-lg 0.6s infinite;
85
- }
81
+ .vueless-loader-ellipse-lg {
82
+ &:nth-child(2) {
83
+ animation: ellipse-2-lg 0.6s infinite;
84
+ }
86
85
 
87
- &:nth-child(3) {
88
- animation: ellipse-2-lg 0.6s infinite;
89
- }
86
+ &:nth-child(3) {
87
+ animation: ellipse-2-lg 0.6s infinite;
90
88
  }
91
89
  }
92
90
 
@@ -5,15 +5,27 @@ import { readdir } from "node:fs/promises";
5
5
  export async function getDirFiles(dirPath, ext, { recursive = true, exclude = [] } = {}) {
6
6
  let fileNames = [];
7
7
 
8
+ const ERROR_CODE = {
9
+ dirIsFile: "ENOTDIR",
10
+ noEntry: "ENOENT",
11
+ };
12
+
8
13
  try {
9
14
  fileNames = await readdir(dirPath, { recursive });
10
15
  } catch (error) {
11
- if (error.code === "ENOTDIR") {
12
- fileNames = [dirPath.split(path.sep).at(-1)];
13
- dirPath = dirPath.split(path.sep).slice(0, -1).join(path.sep);
14
- } else if (error.code === "ENOENT") {
16
+ if (error.code === ERROR_CODE.dirIsFile) {
17
+ const pathArray = dirPath.split(path.sep);
18
+ const fileName = pathArray.pop();
19
+
20
+ fileNames = [fileName];
21
+ dirPath = pathArray.join(path.sep);
22
+ }
23
+
24
+ if (error.code === ERROR_CODE.noEntry) {
15
25
  fileNames = [];
16
- } else {
26
+ }
27
+
28
+ if (!error.code.includes(Object.values(ERROR_CODE))) {
17
29
  // eslint-disable-next-line no-console
18
30
  console.error(error);
19
31
  }
@@ -52,8 +64,8 @@ export function getNuxtFiles() {
52
64
  ];
53
65
  }
54
66
 
55
- export function getVueSourceFile() {
56
- return path.join(process.cwd(), "src");
67
+ export function getVueFiles() {
68
+ return [path.join(process.cwd(), "src")];
57
69
  }
58
70
 
59
71
  export function getDefaultConfigJson(fileContents) {
@@ -64,7 +76,7 @@ export function getDefaultConfigJson(fileContents) {
64
76
  return (0, eval)("(" + objectString + ")"); // Converting into JS object
65
77
  }
66
78
 
67
- export function merge(source, target) {
79
+ export function merge(source = {}, target = {}) {
68
80
  for (const [key, val] of Object.entries(source)) {
69
81
  if (val !== null && typeof val === `object`) {
70
82
  target[key] ??= new val.__proto__.constructor();
@@ -1,10 +1,7 @@
1
1
  /**
2
2
  This scrypt find icon names from the UIcon props and objects across the project
3
3
  and copy SVG icons from the default icons library (@material-symbols or other from config)
4
- to the ".../cache" folder.
5
-
6
- Those icons will be used only in the build stage.
7
- The script is needed to avoid all @material-symbols icons set in the project bundle.
4
+ to the `VUELESS_ICONS_CACHED_DIR` folder.
8
5
  */
9
6
 
10
7
  /* eslint-disable no-console */
@@ -15,89 +12,140 @@ import { rm, cp } from "node:fs/promises";
15
12
 
16
13
  import { vuelessConfig } from "./vuelessConfig.js";
17
14
  import { getDirFiles, getDefaultConfigJson, merge } from "./helper.js";
18
- import { CACHE_PATH, VUELESS_CONFIG_FILE_NAME } from "../../constants.js";
19
-
20
- const ICONS_DIR = "assets/icons";
21
- const NUXT_ASSETS_DIR = path.join(process.cwd(), "assets/.vueless/icons");
22
- const DEFAULT_ICONS_DIR = path.join(process.cwd(), `src/${ICONS_DIR}`);
23
- const CACHED_ICONS_DIR = path.join(process.cwd(), `${CACHE_PATH}/${ICONS_DIR}`);
24
- const ICON_CONFIG_PATH = "ui.image-icon/config.ts";
25
- const ICON_COMPONENT_NAME = "UIcon";
26
- const STORYBOOK_STORY_EXTENSIONS = ["/stories.js", "/stories.ts"];
15
+ import {
16
+ COMPONENTS,
17
+ VUELESS_DIR,
18
+ VUELESS_LOCAL_DIR,
19
+ VUELESS_LIBRARY,
20
+ VUELESS_ICONS_DIR,
21
+ VUELESS_ICONS_LOCAL_DIR,
22
+ VUELESS_ICONS_CACHED_DIR,
23
+ VUELESS_CONFIG_FILE_NAME,
24
+ ICONS_DIR,
25
+ } from "../../constants.js";
26
+
27
+ const cwd = process.cwd();
28
+
29
+ const DEFAULT_ICONS_DIR = path.join(cwd, VUELESS_ICONS_DIR);
30
+ const DEFAULT_ICONS_LOCAL_DIR = path.join(cwd, VUELESS_ICONS_LOCAL_DIR);
31
+ const CACHED_ICONS_DIR = path.join(cwd, VUELESS_ICONS_CACHED_DIR);
32
+ const U_ICON = "UIcon";
27
33
 
28
34
  let isDebug = false;
29
35
  let isVuelessEnv = false;
30
- let isDefaultMode = false;
31
36
  let isStorybookMode = false;
32
37
  let isVuelessIconsMode = false;
33
- let cachedIconsDir = CACHED_ICONS_DIR;
38
+ let cacheIconsPath = CACHED_ICONS_DIR;
34
39
 
35
- // perform icons copy magick... ✨
36
- export async function copyIcons({ mode = "", env, debug, targetFiles = [], isNuxt } = {}) {
40
+ /**
41
+ * Dynamically find icons across the project and cache it.
42
+ * Icons cache magick happens here... ✨
43
+ * @param {string} mode
44
+ * @param {string} env
45
+ * @param {boolean} debug
46
+ * @param {Array} targetFiles
47
+ */
48
+ export async function cacheIcons({ mode, env, debug, targetFiles = [] } = {}) {
37
49
  isDebug = debug || false;
38
50
  isVuelessEnv = env === "vueless";
39
- isDefaultMode = mode === "";
40
51
  isStorybookMode = mode === "storybook";
41
52
  isVuelessIconsMode = mode === "vuelessIcons";
53
+ cacheIconsPath = CACHED_ICONS_DIR;
42
54
 
43
- if (isVuelessIconsMode && isVuelessEnv) cachedIconsDir = DEFAULT_ICONS_DIR;
44
- if (isStorybookMode && isVuelessEnv) cachedIconsDir = CACHED_ICONS_DIR;
55
+ if (isVuelessIconsMode && isVuelessEnv) {
56
+ cacheIconsPath = DEFAULT_ICONS_LOCAL_DIR;
57
+ }
45
58
 
46
- if (isStorybookMode) {
47
- const storybookStoriesJs = await getDirFiles("src", STORYBOOK_STORY_EXTENSIONS[0]);
48
- const storybookStoriesTs = await getDirFiles("src", STORYBOOK_STORY_EXTENSIONS[1]);
59
+ const exclude = isStorybookMode ? [] : ["/stories.js", "/stories.ts", ".d.ts"];
49
60
 
50
- findAndCopyIcons([...storybookStoriesJs.flat(), ...storybookStoriesTs.flat()]);
51
- }
61
+ const vueFiles = targetFiles.map((componentPath) => getDirFiles(componentPath, ".vue"));
62
+ const jsFiles = targetFiles.map((jsFilePath) => getDirFiles(jsFilePath, ".js", { exclude }));
63
+ const tsFiles = targetFiles.map((tsFilePath) => getDirFiles(tsFilePath, ".ts", { exclude }));
52
64
 
53
- if (isVuelessIconsMode || isDefaultMode || isStorybookMode) {
54
- const vueFiles = targetFiles.map((componentPath) => getDirFiles(componentPath, ".vue"));
65
+ const iconFiles = await Promise.all([...vueFiles, ...jsFiles, ...tsFiles]);
55
66
 
56
- const jsFiles = targetFiles.map((jsFilePath) =>
57
- getDirFiles(jsFilePath, ".js", { exclude: [STORYBOOK_STORY_EXTENSIONS[0]] }),
58
- );
67
+ findAndCopyIcons([
68
+ ...iconFiles.flat(),
69
+ `${VUELESS_CONFIG_FILE_NAME}.js`,
70
+ `${VUELESS_CONFIG_FILE_NAME}.ts`,
71
+ ]);
59
72
 
60
- const tsFiles = targetFiles.map((tsFilePath) =>
61
- getDirFiles(tsFilePath, ".ts", { exclude: [STORYBOOK_STORY_EXTENSIONS[1], ".d.ts"] }),
62
- );
73
+ if (isVuelessIconsMode) {
74
+ await copyVuelessIconsIntoCache(isVuelessEnv);
75
+ }
76
+ }
63
77
 
64
- const iconFiles = await Promise.all([...vueFiles, ...jsFiles, ...tsFiles]);
78
+ /**
79
+ * Remove cached icons.
80
+ * @param {string} mirrorCacheDir
81
+ * @param {boolean} debug
82
+ * @returns {Promise<void>}
83
+ */
84
+ export async function removeIconsCache(mirrorCacheDir, debug) {
85
+ if (fs.existsSync(cacheIconsPath)) {
86
+ await rm(cacheIconsPath, { recursive: true, force: true });
87
+ }
88
+
89
+ if (mirrorCacheDir) {
90
+ const mirrorCacheIconsPath = path.join(cwd, mirrorCacheDir, ICONS_DIR);
65
91
 
66
- findAndCopyIcons([
67
- ...iconFiles.flat(),
68
- `${VUELESS_CONFIG_FILE_NAME}.js`,
69
- `${VUELESS_CONFIG_FILE_NAME}.ts`,
70
- ]);
92
+ if (fs.existsSync(mirrorCacheIconsPath)) {
93
+ await rm(mirrorCacheIconsPath, { recursive: true, force: true });
94
+ }
71
95
  }
72
96
 
73
- if (isNuxt) {
74
- await cp(CACHED_ICONS_DIR, NUXT_ASSETS_DIR, {
75
- recursive: true,
76
- });
97
+ if (debug) {
98
+ console.log("Icons cache was successfully removed.");
77
99
  }
78
100
  }
79
101
 
80
- export async function removeIcons({ debug, isNuxt }) {
81
- if (!fs.existsSync(cachedIconsDir)) return;
82
-
83
- await rm(cachedIconsDir, { recursive: true, force: true });
102
+ /**
103
+ * Copy cached icons in the provided folder by path.
104
+ * @param {string} mirrorCacheDir
105
+ * @param {boolean} debug
106
+ * @returns {Promise<void>}
107
+ */
108
+ export async function copyIconsCache(mirrorCacheDir, debug) {
109
+ const cachePath = path.join(cwd, VUELESS_ICONS_CACHED_DIR);
84
110
 
85
- if (isNuxt) {
86
- await rm(NUXT_ASSETS_DIR, { recursive: true, force: true });
111
+ if (mirrorCacheDir && fs.existsSync(cachePath)) {
112
+ await cp(cachePath, path.join(cwd, mirrorCacheDir, ICONS_DIR), { recursive: true });
87
113
  }
88
114
 
89
115
  if (debug) {
90
- console.log("Dynamically copied icons was successfully removed.");
116
+ console.log(`Vueless cached icons was successfully copied into: ${mirrorCacheDir}.`);
91
117
  }
92
118
  }
93
119
 
120
+ /**
121
+ * Copy icons which using in vueless components to the cache.
122
+ * @param {boolean} isVuelessEnv
123
+ * @returns {Promise<void>}
124
+ */
125
+ async function copyVuelessIconsIntoCache(isVuelessEnv) {
126
+ if (isVuelessEnv && fs.existsSync(DEFAULT_ICONS_LOCAL_DIR)) {
127
+ await cp(DEFAULT_ICONS_LOCAL_DIR, path.join(CACHED_ICONS_DIR, VUELESS_LIBRARY), {
128
+ recursive: true,
129
+ });
130
+ }
131
+
132
+ if (!isVuelessEnv && fs.existsSync(DEFAULT_ICONS_DIR)) {
133
+ await cp(DEFAULT_ICONS_DIR, path.join(CACHED_ICONS_DIR, VUELESS_LIBRARY), {
134
+ recursive: true,
135
+ });
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Scan the project for icon names and copy found icons to the cache.
141
+ * @param {Array} files
142
+ */
94
143
  function findAndCopyIcons(files) {
95
- const defaults = getMergedConfig();
96
- const safelistIcons = getSafelistIcons();
144
+ const defaults = getDefaults();
145
+ const safelistIcons = vuelessConfig.component?.[U_ICON]?.safelistIcons;
97
146
 
98
- safelistIcons.forEach((iconName) => {
99
- copyFile(iconName, false);
100
- copyFile(iconName, true);
147
+ safelistIcons?.forEach((iconName) => {
148
+ copyIcon(iconName, defaults);
101
149
  });
102
150
 
103
151
  files.forEach((file) => {
@@ -114,7 +162,7 @@ function findAndCopyIcons(files) {
114
162
 
115
163
  try {
116
164
  if (iconName) {
117
- copyFile(iconName);
165
+ copyIcon(iconName, defaults);
118
166
  }
119
167
  } catch (error) {
120
168
  isDebug && console.log(error);
@@ -137,96 +185,125 @@ function findAndCopyIcons(files) {
137
185
  try {
138
186
  if (!iconName) return;
139
187
 
140
- if (iconName?.includes("?")) {
188
+ if (iconName?.includes("?") && iconName?.includes(":")) {
141
189
  const [trueName, falseName] = getTernaryValues(iconName);
142
190
 
143
- copyFile(trueName);
144
- copyFile(falseName);
191
+ copyIcon(trueName, defaults);
192
+ copyIcon(falseName, defaults);
145
193
  } else {
146
- copyFile(iconName);
194
+ copyIcon(iconName, defaults);
147
195
  }
148
196
  } catch (error) {
149
197
  isDebug && console.log(error);
150
198
  }
151
199
  }
152
200
  });
201
+ }
153
202
 
154
- function getTernaryValues(expression) {
155
- const [, values] = expression
156
- .replace(/\s/g, "") // newlines and spaces
157
- .replace(/\?\./g, "") // conditional chaining `?.`
158
- .replace(/['"]/g, "") // single and double quotes
159
- .split("?");
203
+ /**
204
+ * Retrieve values from ternary of strings.
205
+ * @param {string} expression
206
+ * @returns {Array} of ternary values
207
+ */
208
+ function getTernaryValues(expression) {
209
+ const [, values] = expression
210
+ .replace(/\s/g, "") // newlines and spaces
211
+ .replace(/\?\./g, "") // conditional chaining `?.`
212
+ .replace(/['"]/g, "") // single and double quotes
213
+ .split("?");
160
214
 
161
- const [trueValue, falseValue] = values.split(":");
215
+ const [trueValue, falseValue] = values.split(":");
162
216
 
163
- return [trueValue, falseValue];
164
- }
217
+ return [trueValue, falseValue];
218
+ }
165
219
 
166
- function copyFile(name) {
167
- name = name.toLowerCase();
168
-
169
- const library = defaults.library;
170
- const weight = defaults.weight;
171
- const style = defaults.style;
172
-
173
- const require = createRequire(import.meta.url);
174
-
175
- /* eslint-disable vue/max-len, prettier/prettier */
176
- const libraries = {
177
- vueless: {
178
- // @material-symbols icons which used across the components.
179
- source: `${process.cwd()}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
180
- destination: `${cachedIconsDir}/${name}.svg`
181
- },
182
- "@material-symbols": {
183
- source: `${process.cwd()}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
184
- destination: `${cachedIconsDir}/${library}/svg-${weight}/${style}/${name}.svg`
185
- },
186
- "bootstrap-icons": {
187
- source: `${process.cwd()}/node_modules/${library}/icons/${name}.svg`,
188
- destination: `${cachedIconsDir}/${library}/icons/${name}.svg`
189
- },
190
- heroicons: {
191
- source: `${process.cwd()}/node_modules/${library}/24/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`,
192
- destination: `${cachedIconsDir}/24/${style}/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`
193
- }
194
- };
195
- /* eslint-enable vue/max-len, prettier/prettier */
220
+ /**
221
+ * Copy icon from icon package into cache folder.
222
+ * @param {string} name
223
+ * @param {object} defaults
224
+ */
225
+ function copyIcon(name, defaults) {
226
+ name = name.toLowerCase();
196
227
 
197
- const { source, destination } =
198
- libraries[isVuelessIconsMode && isVuelessEnv ? "vueless" : library];
228
+ const iconNameRegex = /^[a-z0-9_-]+$/;
199
229
 
200
- if (fs.existsSync(destination) || !fs.existsSync(source)) return;
230
+ /* Stop the scrypt if the icon name is irrelevant. */
231
+ if (!iconNameRegex.test(name)) {
232
+ return;
233
+ }
201
234
 
202
- const destDir = path.dirname(destination);
235
+ const { source, destination } = getIconLibraryPaths(name, defaults);
203
236
 
204
- fs.mkdirSync(destDir, { recursive: true });
205
- fs.copyFile(require.resolve(source), destination, (error) => {
206
- if (isDebug) {
207
- error
208
- ? console.error(`Error copying icon "${name}":`, error)
209
- : console.log(`Icon "${name}" copied successfully!`);
210
- }
211
- });
237
+ if (fs.existsSync(destination) || !fs.existsSync(source)) {
238
+ return;
212
239
  }
240
+
241
+ const require = createRequire(import.meta.url);
242
+ const destDir = path.dirname(destination);
243
+
244
+ fs.mkdirSync(destDir, {
245
+ recursive: true,
246
+ });
247
+
248
+ fs.copyFile(require.resolve(source), destination, (error) => {
249
+ if (isDebug) {
250
+ error
251
+ ? console.error(`Error copying icon "${name}":`, error)
252
+ : console.log(`Icon "${name}" copied successfully!`);
253
+ }
254
+ });
213
255
  }
214
256
 
215
- function getSafelistIcons() {
216
- return vuelessConfig.component
217
- ? vuelessConfig.component[ICON_COMPONENT_NAME]?.safelistIcons || []
218
- : [];
257
+ /**
258
+ * Build a path to the icon source in the selected icon library and cache destination path.
259
+ * @param {string} name
260
+ * @param {object} defaults
261
+ * @returns {source: string, destination: string}
262
+ */
263
+ function getIconLibraryPaths(name, defaults) {
264
+ const library = isVuelessIconsMode && isVuelessEnv ? VUELESS_LIBRARY : defaults.library;
265
+ const weight = defaults.weight;
266
+ const style = defaults.style;
267
+
268
+ /* eslint-disable prettier/prettier */
269
+ const libraries = {
270
+ [VUELESS_LIBRARY]: {
271
+ // @material-symbols icons which used across the components.
272
+ source: `${cwd}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
273
+ destination: `${cacheIconsPath}/${VUELESS_LIBRARY}/${name}.svg`
274
+ },
275
+ "@material-symbols": {
276
+ source: `${cwd}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
277
+ destination: `${cacheIconsPath}/${library}/svg-${weight}/${style}/${name}.svg`
278
+ },
279
+ "bootstrap-icons": {
280
+ source: `${cwd}/node_modules/${library}/icons/${name}.svg`,
281
+ destination: `${cacheIconsPath}/${library}/icons/${name}.svg`
282
+ },
283
+ "heroicons": {
284
+ source: `${cwd}/node_modules/${library}/24/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`,
285
+ destination: `${cacheIconsPath}/24/${style}/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`
286
+ }
287
+ };
288
+ /* eslint-enable prettier/prettier */
289
+
290
+ return libraries[library];
219
291
  }
220
292
 
221
- function getMergedConfig() {
222
- const defaultConfigPath = (isVuelessEnv ? "src/" : "node_modules/vueless/") + ICON_CONFIG_PATH;
293
+ /**
294
+ * Merge global and local defaults config for UIcon.
295
+ * @returns {Object}
296
+ */
297
+ function getDefaults() {
298
+ const defaultIconsDir = isVuelessEnv ? VUELESS_LOCAL_DIR : VUELESS_DIR;
299
+ const defaultConfigPath = path.join(cwd, defaultIconsDir, COMPONENTS[U_ICON], "config.ts");
223
300
 
224
301
  if (fs.existsSync(defaultConfigPath)) {
225
302
  const defaultConfigFile = fs.readFileSync(defaultConfigPath).toString();
226
303
 
227
- const defaultConfig = getDefaultConfigJson(defaultConfigFile);
228
- const globalConfig = vuelessConfig.component && vuelessConfig.component[ICON_COMPONENT_NAME];
229
-
230
- return merge(globalConfig?.defaults || {}, defaultConfig.defaults);
304
+ return merge(
305
+ getDefaultConfigJson(defaultConfigFile)?.defaults,
306
+ vuelessConfig?.component?.[U_ICON]?.defaults,
307
+ );
231
308
  }
232
309
  }
@@ -25,7 +25,7 @@ export async function loadSvg(id, options) {
25
25
  svgPath = svgPath.replace("/__skip_vite/", "");
26
26
 
27
27
  // use default svg loader
28
- if (importType === "url" && !svgPath.includes(".generated")) {
28
+ if (importType === "url") {
29
29
  return;
30
30
  }
31
31
 
@@ -36,11 +36,11 @@ export async function loadSvg(id, options) {
36
36
 
37
37
  try {
38
38
  svg = await fs.promises.readFile(svgPath, "utf-8");
39
- } catch {
39
+ } catch (error) {
40
40
  // define an empty svg to prevent a UI crash.
41
41
  svg = `<svg xmlns="http://www.w3.org/2000/svg"></svg>`;
42
42
  // eslint-disable-next-line no-console
43
- console.warn("\n", `${id} couldn't be loaded by vueless vite plugin.`);
43
+ console.warn(`${svgPath} couldn't be loaded by vueless vite plugin.`, "\n", error);
44
44
  }
45
45
 
46
46
  if (importType === "raw") {
@@ -2,7 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import esbuild from "esbuild";
4
4
 
5
- import { CACHE_PATH, VUELESS_CONFIG_FILE_NAME } from "../../constants.js";
5
+ import { VUELESS_CACHE_DIR, VUELESS_CONFIG_FILE_NAME } from "../../constants.js";
6
6
 
7
7
  /**
8
8
  * Load Vueless config from the project root.
@@ -13,7 +13,10 @@ export let vuelessConfig = {};
13
13
  (async () => {
14
14
  const configPathJs = path.join(process.cwd(), `${VUELESS_CONFIG_FILE_NAME}.js`);
15
15
  const configPathTs = path.join(process.cwd(), `${VUELESS_CONFIG_FILE_NAME}.ts`);
16
- const configOutPath = path.join(process.cwd(), `${CACHE_PATH}/${VUELESS_CONFIG_FILE_NAME}.mjs`);
16
+ const configOutPath = path.join(
17
+ process.cwd(),
18
+ `${VUELESS_CACHE_DIR}/${VUELESS_CONFIG_FILE_NAME}.mjs`,
19
+ );
17
20
 
18
21
  if (!fs.existsSync(configPathJs) && !fs.existsSync(configPathTs)) {
19
22
  vuelessConfig = {};
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "framework": "vue",
3
3
  "name": "vueless",
4
- "version": "0.0.489",
4
+ "version": "0.0.491",
5
5
  "contributions": {
6
6
  "html": {
7
7
  "description-markup": "markdown",
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M445.93-445.93H194.02v-68.14h251.91v-252.15h68.14v252.15h252.15v68.14H514.07v251.91h-68.14v-251.91Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M223.29-154.5q-29.12 0-48.95-19.84-19.84-19.83-19.84-48.95 0-29.12 19.84-48.91 19.83-19.8 48.95-19.8 29.12 0 48.91 19.8 19.8 19.79 19.8 48.91 0 29.12-19.8 48.95-19.79 19.84-48.91 19.84Zm256.8 0q-29.05 0-48.88-19.84-19.84-19.83-19.84-48.95 0-29.12 19.75-48.91 19.74-19.8 48.79-19.8t48.88 19.8q19.84 19.79 19.84 48.91 0 29.12-19.75 48.95-19.74 19.84-48.79 19.84Zm256.62 0q-29.12 0-48.91-19.84-19.8-19.83-19.8-48.95 0-29.12 19.8-48.91 19.79-19.8 48.91-19.8 29.12 0 48.95 19.8 19.84 19.79 19.84 48.91 0 29.12-19.84 48.95-19.83 19.84-48.95 19.84ZM223.29-411.37q-29.12 0-48.95-19.75-19.84-19.74-19.84-48.79t19.84-48.88q19.83-19.84 48.95-19.84 29.12 0 48.91 19.75 19.8 19.74 19.8 48.79t-19.8 48.88q-19.79 19.84-48.91 19.84Zm256.8 0q-29.05 0-48.88-19.75-19.84-19.74-19.84-48.79t19.75-48.88q19.74-19.84 48.79-19.84t48.88 19.75q19.84 19.74 19.84 48.79t-19.75 48.88q-19.74 19.84-48.79 19.84Zm256.62 0q-29.12 0-48.91-19.75-19.8-19.74-19.8-48.79t19.8-48.88q19.79-19.84 48.91-19.84 29.12 0 48.95 19.75 19.84 19.74 19.84 48.79t-19.84 48.88q-19.83 19.84-48.95 19.84ZM223.29-668q-29.12 0-48.95-19.8-19.84-19.79-19.84-48.91 0-29.12 19.84-48.95 19.83-19.84 48.95-19.84 29.12 0 48.91 19.84 19.8 19.83 19.8 48.95 0 29.12-19.8 48.91-19.79 19.8-48.91 19.8Zm256.8 0q-29.05 0-48.88-19.8-19.84-19.79-19.84-48.91 0-29.12 19.75-48.95 19.74-19.84 48.79-19.84t48.88 19.84q19.84 19.83 19.84 48.95 0 29.12-19.75 48.91-19.74 19.8-48.79 19.8Zm256.62 0q-29.12 0-48.91-19.8-19.8-19.79-19.8-48.91 0-29.12 19.8-48.95 19.79-19.84 48.91-19.84 29.12 0 48.95 19.84 19.84 19.83 19.84 48.95 0 29.12-19.84 48.91-19.83 19.8-48.95 19.8Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m283.8-445.93 244.18 244.17L480-154.02 154.02-480 480-806.22l47.98 47.98L283.8-514.07h522.42v68.14H283.8Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M737.33-324.39q0 105.46-74.69 177.91-74.69 72.46-180.26 72.46-105.58 0-180.35-72.46-74.77-72.45-74.77-177.85v-383.82q0-74.63 53.41-126.35 53.42-51.72 127.75-51.72 74.34 0 127.69 51.72 53.35 51.72 53.35 126.35v363.82q0 43.66-31.56 74.62-31.55 30.97-75.81 30.97-44.26 0-75.61-30.64t-31.35-74.95v-370h66.46v370q0 16.05 11.97 27.59t29.2 11.54q17.24 0 28.74-11.5 11.5-11.51 11.5-27.63v-363.58q.24-47.35-33.38-79.6-33.62-32.25-81.35-32.25-47.74 0-81.14 32.19-33.41 32.19-33.41 79.42v383.82q.24 77.83 55.57 130.96 55.33 53.13 133.62 53.13 77.86 0 133.03-53.16 55.17-53.17 54.93-130.93v-396.93h66.46v396.87Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M480.03-398.57q-17.6 0-29.53-11.9-11.93-11.91-11.93-29.5 0-17.6 11.9-29.53 11.91-11.93 29.5-11.93 17.6 0 29.53 11.9 11.93 11.91 11.93 29.5 0 17.6-11.9 29.53-11.91 11.93-29.5 11.93Zm-160 0q-17.6 0-29.53-11.9-11.93-11.91-11.93-29.5 0-17.6 11.9-29.53 11.91-11.93 29.5-11.93 17.6 0 29.53 11.9 11.93 11.91 11.93 29.5 0 17.6-11.9 29.53-11.91 11.93-29.5 11.93Zm320 0q-17.27 0-29.37-11.9-12.09-11.91-12.09-29.5 0-17.6 12.07-29.53t29.45-11.93q17.39 0 29.37 11.9 11.97 11.91 11.97 29.5 0 17.6-11.9 29.53-11.91 11.93-29.5 11.93Zm-160 160q-17.6 0-29.53-12.07t-11.93-29.45q0-17.39 11.9-29.37 11.91-11.97 29.5-11.97 17.6 0 29.53 11.9 11.93 11.91 11.93 29.5 0 17.27-11.9 29.37-11.91 12.09-29.5 12.09Zm-160 0q-17.6 0-29.53-12.07t-11.93-29.45q0-17.39 11.9-29.37 11.91-11.97 29.5-11.97 17.6 0 29.53 11.9 11.93 11.91 11.93 29.5 0 17.27-11.9 29.37-11.91 12.09-29.5 12.09Zm320 0q-17.27 0-29.37-12.07-12.09-12.07-12.09-29.45 0-17.39 12.07-29.37 12.07-11.97 29.45-11.97 17.39 0 29.37 11.9 11.97 11.91 11.97 29.5 0 17.27-11.9 29.37-11.91 12.09-29.5 12.09ZM182.15-74.02q-27.6 0-47.86-20.27-20.27-20.26-20.27-47.86v-615.7q0-27.7 20.27-48.03 20.26-20.34 47.86-20.34H245v-60h69.07v60h331.86v-60H715v60h62.85q27.7 0 48.03 20.34 20.34 20.33 20.34 48.03v615.7q0 27.6-20.34 47.86-20.33 20.27-48.03 20.27h-595.7Zm0-68.13h595.7V-570h-595.7v427.85Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M378-240.26 148.26-470l48.98-48.98L378-338.22l383.76-383.76L810.74-673 378-240.26Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m420.52-294.41 285.63-285.63-50.78-50.03-234.85 234.85-117.85-117.85-49.78 50.03 167.63 168.63Zm59.51 220.39q-83.46 0-157.54-31.88-74.07-31.88-129.39-87.2-55.32-55.32-87.2-129.36-31.88-74.04-31.88-157.51 0-84.46 31.88-158.54 31.88-74.07 87.16-128.9 55.28-54.84 129.34-86.82 74.06-31.99 157.55-31.99 84.48 0 158.59 31.97 74.1 31.97 128.91 86.77 54.82 54.8 86.79 128.88 31.98 74.08 31.98 158.6 0 83.5-31.99 157.57-31.98 74.07-86.82 129.36-54.83 55.29-128.87 87.17-74.04 31.88-158.51 31.88Zm-.03-68.13q141.04 0 239.45-98.75 98.4-98.76 98.4-239.1 0-141.04-98.4-239.45-98.41-98.4-239.57-98.4-140.16 0-238.95 98.4-98.78 98.41-98.78 239.57 0 140.16 98.75 238.95 98.76 98.78 239.1 98.78ZM480-480Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M561-234.26 314.26-481 561-727.74 609.74-679l-198 198 198 198L561-234.26Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m524.26-481-198-198L375-727.74 621.74-481 375-234.26 326.26-283l198-198Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M249-201.26 201.26-249l231-231-231-231L249-758.74l231 231 231-231L758.74-711l-231 231 231 231L711-201.26l-231-231-231 231Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m305.02-257.28-47.74-47.74L432.02-480 257.28-653.98l47.74-47.74L480-526.98l173.98-174.74 47.74 47.74L526.98-480l174.74 174.98-47.74 47.74L480-432.02 305.02-257.28Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M259.09-114.02q-28.45 0-48.41-19.89-19.96-19.89-19.96-48.24v-565.94h-45.07v-68.13h198.28v-34.3h271.9v34.3h198.52v68.13h-45.07v565.94q0 27.6-20.33 47.86-20.34 20.27-48.04 20.27H259.09Zm441.82-634.07H259.09v565.94h441.82v-565.94ZM363.89-266.24h64.07v-399h-64.07v399Zm168.15 0h64.31v-399h-64.31v399ZM259.09-748.09v565.94-565.94Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M319-249.52h322v-62.63H319v62.63Zm0-170h322v-62.63H319v62.63Zm-96.85 345.5q-27.6 0-47.86-20.27-20.27-20.26-20.27-47.86v-675.7q0-27.7 20.27-48.03 20.26-20.34 47.86-20.34h361.48l222.59 222.59v521.48q0 27.6-20.34 47.86-20.33 20.27-48.03 20.27h-515.7Zm326.7-557.83v-186h-326.7v675.7h515.7v-489.7h-189Zm-326.7-186v186-186 675.7-675.7Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M347.41-154.5q-30.1 0-51.51-21.43-21.4-21.44-21.4-51.54 0-30.1 21.43-51.31Q317.37-300 347.47-300q30.1 0 51.31 21.25Q420-257.51 420-227.41q0 30.1-21.25 51.51-21.24 21.4-51.34 21.4Zm265.34 0q-30.1 0-51.42-21.43Q540-197.37 540-227.47q0-30.1 21.39-51.31Q582.79-300 612.83-300q30.14 0 51.4 21.25 21.27 21.24 21.27 51.34 0 30.1-21.32 51.51-21.33 21.4-51.43 21.4ZM347.41-407.37q-30.1 0-51.51-21.39-21.4-21.4-21.4-51.44 0-30.23 21.43-51.33 21.44-21.1 51.54-21.1 30.1 0 51.31 21.19Q420-510.26 420-480.14q0 30.12-21.25 51.44-21.24 21.33-51.34 21.33Zm265.34 0q-30.1 0-51.42-21.39Q540-450.16 540-480.2q0-30.23 21.39-51.33 21.4-21.1 51.44-21.1 30.14 0 51.4 21.19 21.27 21.18 21.27 51.3 0 30.12-21.32 51.44-21.33 21.33-51.43 21.33ZM347.41-660q-30.1 0-51.51-21.39-21.4-21.4-21.4-51.44 0-30.14 21.43-51.4 21.44-21.27 51.54-21.27 30.1 0 51.31 21.32Q420-762.85 420-732.75t-21.25 51.42Q377.51-660 347.41-660Zm265.34 0q-30.1 0-51.42-21.39Q540-702.79 540-732.83q0-30.14 21.39-51.4 21.4-21.27 51.44-21.27 30.14 0 51.4 21.32 21.27 21.33 21.27 51.43t-21.32 51.42Q642.85-660 612.75-660Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M181.91-182.15h44.24l459.81-458.81-43.76-44-460.29 459.05v43.76Zm-67.89 68.13V-253.5l574.52-573.76q8.24-8.48 19.81-13.22 11.56-4.74 24.11-4.74 11.47 0 22.95 4.74 11.48 4.74 21.2 12.98l51.89 51.17q9.24 9.72 13.48 21.32t4.24 23.31q0 11.72-4.74 23.7-4.74 11.98-12.98 20.46L253.74-114.02H114.02ZM775.17-732.7l-41.24-41.47 41.24 41.47ZM664.2-663.2l-22-21.76 43.76 44-21.76-22.24Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M154.02-396.85v-68.13h310.76v68.13H154.02Zm0-170.5v-68.13h478.13v68.13H154.02Zm0-170.5v-68.37h478.13v68.37H154.02Zm365.02 583.83v-128.02L741-503q9.51-9.63 21.13-13.91 11.62-4.29 23.5-4.29 12.48 0 24.21 4.86T831.02-502l37 37q9.44 9.48 13.82 21.12 4.38 11.63 4.38 23.27 0 11.96-4.86 24.06-4.86 12.09-14.25 21.57L647.07-154.02H519.04Zm303.59-266.59-37-37 37 37Zm-240 203h38l120.28-121.23-18-19.02-19-18.03-121.28 120.22v38.06Zm140.28-140.28-19-18 37 37-18-19Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M154.02-114.02v-68.13h652.2v68.13h-652.2ZM309.8-258.57q-65.17 0-110.48-44.93-45.3-44.93-45.3-109.85v-432.87h664.07q28.1 0 48.11 20.08 20.02 20.08 20.02 48.05v160q0 28.1-20.02 48.12-20.01 20.01-48.11 20.01h-92.66v136.61q0 64.92-45.47 109.85-45.48 44.93-110.55 44.93H309.8Zm.24-519.28H657.3 222.15h87.89Zm415.39 159.76h92.42v-160h-92.42v160ZM569.15-326.93q34.84 0 61.5-26.52 26.65-26.52 26.65-60.14v-364.26H399.15v37.31l71 58q1 1 9 18v150q0 9.6-7 16.8-7 7.2-18 7.2h-151q-11 0-18-7.2t-7-16.8v-150q0-4 9-18l72-58v-37.31h-137v364.26q0 33.62 26.98 60.14 26.97 26.52 60.91 26.52h259.11ZM355.57-777.85h40-40Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M479.93-274.02q16.46 0 27.4-10.74 10.93-10.75 10.93-27.21t-10.86-27.52q-10.86-11.05-27.33-11.05-16.46 0-27.4 11.03-10.93 11.04-10.93 27.5 0 16.47 10.86 27.23 10.86 10.76 27.33 10.76Zm-31-158.74h68.14v-257.07h-68.14v257.07ZM480.3-74.02q-84.2 0-158.04-31.88-73.84-31.88-129.16-87.2-55.32-55.32-87.2-129.2-31.88-73.88-31.88-158.17 0-84.28 31.88-158.2 31.88-73.91 87.16-128.74 55.28-54.84 129.18-86.82 73.9-31.99 158.21-31.99 84.3 0 158.25 31.97 73.94 31.97 128.75 86.77 54.82 54.8 86.79 128.88 31.98 74.08 31.98 158.33 0 84.24-31.99 158.07-31.98 73.84-86.82 128.95-54.83 55.1-128.87 87.17Q564.5-74.02 480.3-74.02Zm.2-68.13q140.54 0 238.95-98.75 98.4-98.76 98.4-239.6 0-140.54-98.22-238.95-98.21-98.4-239.75-98.4-140.16 0-238.95 98.22-98.78 98.21-98.78 239.75 0 140.16 98.75 238.95 98.76 98.78 239.6 98.78ZM480-480Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M480-339.5 234.26-585.24 283-633.98l197 198 197-197 48.74 48.74L480-339.5Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M235.93-234.26v-491.48h68.14v491.48h-68.14Zm451.07-3L447.26-477 687-716.74 735.74-668l-191 191 191 191L687-237.26Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M182.15-114.02q-27.6 0-47.86-20.27-20.27-20.26-20.27-47.86v-595.7q0-27.7 20.27-48.03 20.26-20.34 47.86-20.34h595.7q27.7 0 48.03 20.34 20.34 20.33 20.34 48.03v595.7q0 27.6-20.34 47.86-20.33 20.27-48.03 20.27h-595.7Zm0-68.13h595.7v-595.7h-595.7v595.7Zm50.74-92.7h495.22L578-476.59l-132 171-93-127-120.11 157.74Zm-50.74 92.7v-595.7 595.7Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M480-338.26 234.26-584 283-632.74l197 197 197-197L725.74-584 480-338.26Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M561-234.26 314.26-481 561-727.74 609.74-679l-198 198 198 198L561-234.26Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m524.26-481-198-198L375-727.74 621.74-481 375-234.26 326.26-283l198-198Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M846.22-480 674.83-237.89q-14.2 19.67-33.86 31.77-19.67 12.1-43.36 12.1H182.15q-28.1 0-48.12-20.01-20.01-20.02-20.01-48.12v-435.7q0-28.2 20.01-48.28 20.02-20.09 48.12-20.09h415.46q23.69 0 43.36 12.34 19.67 12.34 33.86 31.77L846.22-480Zm-85.29 0L608.56-697.85H182.15v435.7h426.46L760.93-480Zm-578.78 0v217.85-435.7V-480Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M272-239.26 223.26-288l192-192-192-192L272-720.74 512.74-480 272-239.26Zm383.93 5v-491.48h68.14v491.48h-68.14Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M194.02-445.93v-68.14h572.2v68.14h-572.2Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M795.76-114.3 531.33-378.5q-29.76 25.26-69.6 39.41-39.84 14.16-85.16 14.16-109.84 0-185.96-76.2Q114.5-477.33 114.5-585t76.2-183.87q76.19-76.2 184.37-76.2 108.17 0 183.86 76.2 75.7 76.2 75.7 184.02 0 43.33-13.64 82.97t-40.92 74.4L845.5-164.04l-49.74 49.74ZM375.65-393.07q79.73 0 135.29-56.24Q566.5-505.55 566.5-585q0-79.45-55.6-135.69-55.59-56.24-135.25-56.24-80.49 0-136.76 56.24-56.26 56.24-56.26 135.69 0 79.45 56.23 135.69 56.23 56.24 136.79 56.24Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m224.15-107.56 67.39-291.29L65.41-594.78l298.52-25.72L480-895.3l116.07 274.8 298.52 25.72-226.13 195.93 67.63 291.29L480-262.3 224.15-107.56Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="m326.37-249.79 153.64-91.89 153.64 92.9-41.28-173.94L727.5-540.33l-178.17-15.52L480-720.02l-69.33 163.41-178.17 15.28 135.22 117.38-41.35 174.16ZM224.15-107.56l67.39-291.29L65.41-594.78l298.43-25.67L480-895.3l116.16 274.85 298.43 25.67-226.13 195.93 67.63 291.29L480-262.3 224.15-107.56ZM480-474.52Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M425.93-154.02v-544.07H194.02v-108.13h572.2v108.13H534.3v544.07H425.93Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M480.12-330q70.88 0 120.38-49.62t49.5-120.5q0-70.88-49.62-120.38T479.88-670Q409-670 359.5-620.38T310-499.88q0 70.88 49.62 120.38t120.5 49.5Zm-.3-61.83q-45.15 0-76.57-31.6-31.42-31.6-31.42-76.75t31.6-76.57q31.6-31.42 76.75-31.42t76.57 31.6q31.42 31.6 31.42 76.75t-31.6 76.57q-31.6 31.42-76.75 31.42ZM480-194.5q-147.91 0-267.35-84.67Q93.22-363.85 34.5-500q58.72-136.15 178.15-220.83Q332.09-805.5 480-805.5q147.91 0 267.35 84.67Q866.78-636.15 925.5-500q-58.72 136.15-178.15 220.83Q627.91-194.5 480-194.5Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M813.85-61.85 649.2-223.74q-35 14-79.24 21.62-44.24 7.62-89.96 7.62-147.2 0-267.75-82.46Q91.7-359.41 34.5-500q19.52-51.76 55.38-101.86t86.38-95.81L50.98-822.48l43.91-45.15 759.87 759.87-40.91 45.91ZM480-330q13.28 0 28.45-2.5 15.16-2.5 25.44-7.26L319.28-553.89q-4.52 11.28-6.9 25.56Q310-514.04 310-500q0 72 50 121t120 49Zm283.74 41.91L629.96-422.11q9.52-15.04 14.78-36.18T650-500q0-71-49.5-120.5T480-670q-20.8 0-41.09 4.76-20.28 4.76-36.8 15.04L287.57-765.5q35-16 90.21-28 55.22-12 107.22-12 143.96 0 264.01 82.34Q869.07-640.83 925.5-500q-25.76 64.48-67.12 118.08-41.36 53.59-94.64 93.83ZM578.07-474l-125.5-125.5q25.17-10.28 52.82-5.1 27.65 5.19 48.5 24.56 20.61 20.61 28.53 46 7.93 25.39-4.35 60.04Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M34.74-116.89 480-886.22l445.26 769.33H34.74Zm113.8-65.74h662.92L480-754.98 148.54-182.63Zm335.64-54.85q12.96 0 21.87-9.08 8.91-9.09 8.91-22.05t-9.09-21.75q-9.08-8.79-22.05-8.79-12.96 0-21.87 8.96-8.91 8.97-8.91 21.93 0 12.96 9.09 21.87 9.08 8.91 22.05 8.91ZM454-348h60v-222.09h-60V-348Zm26-120.8Z"/></svg>