@uplatform/brand 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +26 -0
- package/README.md +68 -0
- package/dist/affiliation.d.ts +8 -0
- package/dist/affiliation.js +117 -0
- package/dist/generated/geometry.json +135 -0
- package/dist/generated/marks.d.ts +4 -0
- package/dist/generated/marks.js +11 -0
- package/dist/generated/products.json +104 -0
- package/dist/generated/u-motion.d.ts +22 -0
- package/dist/generated/u-motion.js +91 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +10 -0
- package/dist/mark.d.ts +8 -0
- package/dist/mark.js +125 -0
- package/dist/products.d.ts +30 -0
- package/dist/products.js +8 -0
- package/marks/iyulab-wordmark-reverse.svg +16 -0
- package/marks/iyulab-wordmark.svg +16 -0
- package/marks/u-board-reverse.svg +1 -0
- package/marks/u-board.svg +1 -0
- package/marks/u-cmms-reverse.svg +1 -0
- package/marks/u-cmms.svg +1 -0
- package/marks/u-draw-reverse.svg +1 -0
- package/marks/u-draw.svg +1 -0
- package/marks/u-ems-reverse.svg +1 -0
- package/marks/u-ems.svg +1 -0
- package/marks/u-mes-reverse.svg +1 -0
- package/marks/u-mes.svg +1 -0
- package/marks/u-platform-reverse.svg +1 -0
- package/marks/u-platform.svg +1 -0
- package/marks/u-sphere-reverse.svg +1 -0
- package/marks/u-sphere.svg +1 -0
- package/marks/u-vision-reverse.svg +1 -0
- package/marks/u-vision.svg +1 -0
- package/media/motion/u-board-chase-dark.webp +0 -0
- package/media/motion/u-board-chase-light.webp +0 -0
- package/media/motion/u-board-reveal-dark-poster.png +0 -0
- package/media/motion/u-board-reveal-dark.webp +0 -0
- package/media/motion/u-board-reveal-light-poster.png +0 -0
- package/media/motion/u-board-reveal-light.webp +0 -0
- package/media/motion/u-cmms-chase-dark.webp +0 -0
- package/media/motion/u-cmms-chase-light.webp +0 -0
- package/media/motion/u-cmms-reveal-dark-poster.png +0 -0
- package/media/motion/u-cmms-reveal-dark.webp +0 -0
- package/media/motion/u-cmms-reveal-light-poster.png +0 -0
- package/media/motion/u-cmms-reveal-light.webp +0 -0
- package/media/motion/u-draw-chase-dark.webp +0 -0
- package/media/motion/u-draw-chase-light.webp +0 -0
- package/media/motion/u-draw-reveal-dark-poster.png +0 -0
- package/media/motion/u-draw-reveal-dark.webp +0 -0
- package/media/motion/u-draw-reveal-light-poster.png +0 -0
- package/media/motion/u-draw-reveal-light.webp +0 -0
- package/media/motion/u-ems-chase-dark.webp +0 -0
- package/media/motion/u-ems-chase-light.webp +0 -0
- package/media/motion/u-ems-reveal-dark-poster.png +0 -0
- package/media/motion/u-ems-reveal-dark.webp +0 -0
- package/media/motion/u-ems-reveal-light-poster.png +0 -0
- package/media/motion/u-ems-reveal-light.webp +0 -0
- package/media/motion/u-mes-chase-dark.webp +0 -0
- package/media/motion/u-mes-chase-light.webp +0 -0
- package/media/motion/u-mes-reveal-dark-poster.png +0 -0
- package/media/motion/u-mes-reveal-dark.webp +0 -0
- package/media/motion/u-mes-reveal-light-poster.png +0 -0
- package/media/motion/u-mes-reveal-light.webp +0 -0
- package/media/motion/u-platform-chase-dark.webp +0 -0
- package/media/motion/u-platform-chase-light.webp +0 -0
- package/media/motion/u-platform-reveal-dark-poster.png +0 -0
- package/media/motion/u-platform-reveal-dark.webp +0 -0
- package/media/motion/u-platform-reveal-light-poster.png +0 -0
- package/media/motion/u-platform-reveal-light.webp +0 -0
- package/media/motion/u-sphere-chase-dark.webp +0 -0
- package/media/motion/u-sphere-chase-light.webp +0 -0
- package/media/motion/u-sphere-reveal-dark-poster.png +0 -0
- package/media/motion/u-sphere-reveal-dark.webp +0 -0
- package/media/motion/u-sphere-reveal-light-poster.png +0 -0
- package/media/motion/u-sphere-reveal-light.webp +0 -0
- package/media/motion/u-vision-chase-dark.webp +0 -0
- package/media/motion/u-vision-chase-light.webp +0 -0
- package/media/motion/u-vision-reveal-dark-poster.png +0 -0
- package/media/motion/u-vision-reveal-dark.webp +0 -0
- package/media/motion/u-vision-reveal-light-poster.png +0 -0
- package/media/motion/u-vision-reveal-light.webp +0 -0
- package/media/og/u-board.png +0 -0
- package/media/og/u-cmms.png +0 -0
- package/media/og/u-draw.png +0 -0
- package/media/og/u-ems.png +0 -0
- package/media/og/u-mes.png +0 -0
- package/media/og/u-platform.png +0 -0
- package/media/og/u-sphere.png +0 -0
- package/media/og/u-vision.png +0 -0
- package/package.json +25 -0
- package/patterns/u-outline.svg +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Code (dist/**/*.js, dist/**/*.d.ts) — MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) iyulab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
7
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
8
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
|
12
|
+
substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
15
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
17
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
|
18
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
19
|
+
|
|
20
|
+
Marks and brand assets (marks/**, media/**, patterns/**, and the mark data embedded in
|
|
21
|
+
dist/generated) — not covered by the MIT License.
|
|
22
|
+
U-Platform and the product names and marks are trademarks of iyulab. The marks, their renders and
|
|
23
|
+
link-preview images (media/**) and the U outline pattern (patterns/**) may be used only to indicate
|
|
24
|
+
that a product belongs to the U-Platform family, unmodified, as rendered by this package.
|
|
25
|
+
The iyulab wordmark (marks/iyulab-wordmark*.svg) may be used only to attribute a U-Platform product
|
|
26
|
+
to iyulab, such as a "made by" credit, unmodified and at least 100 px wide.
|
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# @uplatform/brand
|
|
2
|
+
|
|
3
|
+
The U-Platform affiliation kit: the family product list, product marks, and two elements —
|
|
4
|
+
`<uplatform-affiliation>`, which shows a product belongs to U-Platform and links to its siblings, and
|
|
5
|
+
`<u-mark>`, a product mark that can draw itself in or loop as a loading indicator. For places that cannot
|
|
6
|
+
run code it also ships mark renders (animated WebP, posters, link-preview images), the U outline pattern
|
|
7
|
+
and the iyulab wordmark.
|
|
8
|
+
|
|
9
|
+
It deliberately ships **no colors, fonts or spacing for your UI**. Each product keeps its own design;
|
|
10
|
+
this kit only marks the affiliation.
|
|
11
|
+
|
|
12
|
+
## Use
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import '@uplatform/brand' // registers <uplatform-affiliation> and <u-mark>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```html
|
|
19
|
+
<uplatform-affiliation product="u-board" lang="en" theme="auto"></uplatform-affiliation>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
| Attribute | Values | Default |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `product` | your product id — it is left out of the sibling list | none (all products listed) |
|
|
25
|
+
| `lang` | `ko` · `en` | `ko` |
|
|
26
|
+
| `theme` | `auto` (follows `prefers-color-scheme`) · `light` · `dark` | `auto` |
|
|
27
|
+
|
|
28
|
+
Data only (no element): `import { products, umbrella, productHref } from '@uplatform/brand/products'`.
|
|
29
|
+
`productHref` returns the product's own site, or `undefined` when it has none — render plain text then.
|
|
30
|
+
Mark files: `@uplatform/brand/marks/<id>.svg` and `<id>-reverse.svg` (for dark backgrounds).
|
|
31
|
+
|
|
32
|
+
## Marks that move — `<u-mark>`
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<u-mark product="u-cmms" motion="reveal" play="visible"></u-mark>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
| Attribute | Values | Default |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `product` | a product id, or `u-platform` | `u-platform` |
|
|
41
|
+
| `motion` | `reveal` (drawn in one stroke, then filled) · `chase` (loading) · `none` | `none` |
|
|
42
|
+
| `play` | `load` · `visible` (plays once when half of it is on screen) | `load` |
|
|
43
|
+
| `theme` | `auto` · `light` · `dark` | `auto` |
|
|
44
|
+
|
|
45
|
+
Size it with CSS `width` (the height follows; default 64 px). Sizing by height alone is not supported.
|
|
46
|
+
At 32 px or less the inner glyph is dropped.
|
|
47
|
+
With `prefers-reduced-motion: reduce` it shows the finished mark and never animates.
|
|
48
|
+
The mark is decorative; to name it, put `role="img"` and `aria-label` on the `<u-mark>` element itself.
|
|
49
|
+
|
|
50
|
+
Files for places that cannot run code: `@uplatform/brand/media/motion/<id>-{reveal,chase}-{light,dark}.webp`
|
|
51
|
+
(reveal plays once, chase loops), `<id>-reveal-{light,dark}-poster.png`, link previews `media/og/<id>.png` (1200×630),
|
|
52
|
+
the outline pattern `patterns/u-outline.svg` (one color — tint it with CSS `mask`), and the iyulab wordmark
|
|
53
|
+
`marks/iyulab-wordmark.svg` / `-reverse.svg` (keep it at least 100 px wide).
|
|
54
|
+
|
|
55
|
+
## Placement rules
|
|
56
|
+
|
|
57
|
+
- Put it in the footer, or in your menu's information area. Where exactly is your product's call.
|
|
58
|
+
- Keep the mark at least 16 px and leave clear space around it equal to the mark's stroke weight.
|
|
59
|
+
- To match your background, set `--uplatform-fg` and `--uplatform-bg` on the element.
|
|
60
|
+
- For layout only (placement, spacing, sizing), the shadow parts are exposed: `::part(link)`, `::part(toggle)`
|
|
61
|
+
and `::part(list)`. Colors and type stay with the element — nothing else is themable on purpose.
|
|
62
|
+
- It makes no network requests and sets no cookies; the product list is built into the package, so it
|
|
63
|
+
renders on networks without internet access (the links simply won't resolve there).
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
Code: MIT. Marks, renders, the outline pattern and the iyulab wordmark: trademarks and brand assets
|
|
68
|
+
of iyulab, with limited permitted use — see `LICENSE`.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare class UplatformAffiliation extends HTMLElement {
|
|
2
|
+
#private;
|
|
3
|
+
static observedAttributes: string[];
|
|
4
|
+
connectedCallback(): void;
|
|
5
|
+
disconnectedCallback(): void;
|
|
6
|
+
attributeChangedCallback(): void;
|
|
7
|
+
}
|
|
8
|
+
export declare function defineAffiliation(registry?: CustomElementRegistry): void;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// <uplatform-affiliation> — U-Platform 소속 표시. 의존 0 · 네트워크 0 · 쿠키 0 · shadow DOM.
|
|
2
|
+
// 제품 UI 안에 놓이지만 그 UI 와 스타일이 서로 새지 않는다. 호스트는 --uplatform-fg · --uplatform-bg 로 대비만 맞춘다.
|
|
3
|
+
import { products, umbrella, HUB } from './products.js';
|
|
4
|
+
import { MARKS } from './generated/marks.js';
|
|
5
|
+
const TEXT = {
|
|
6
|
+
ko: { toggle: 'U-Platform 제품', solutions: '업무 시스템', system: '시스템 통합', cross: '독립 제품' },
|
|
7
|
+
en: { toggle: 'U-Platform products', solutions: 'Business systems', system: 'System integration', cross: 'Standalone products' },
|
|
8
|
+
};
|
|
9
|
+
const esc = (s) => s.replace(/[&<>"']/g, c => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c]);
|
|
10
|
+
/** 마크 SVG 는 생성물(신뢰 원본)이다 — 장식이라 보조기술에서 숨긴다. */
|
|
11
|
+
const mark = (id, theme) => (MARKS[id]?.[theme] ?? '').replace(/^<svg/, '<svg aria-hidden="true" focusable="false"');
|
|
12
|
+
const STYLE = `
|
|
13
|
+
:host { display: inline-block; font: inherit; color: var(--uplatform-fg, ${umbrella.ink.light}); position: relative; }
|
|
14
|
+
:host([data-resolved-theme="dark"]) { color: var(--uplatform-fg, ${umbrella.ink.dark}); }
|
|
15
|
+
.row { display: inline-flex; align-items: center; gap: 0.25rem; }
|
|
16
|
+
a { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 0.4rem; }
|
|
17
|
+
a:hover { text-decoration: underline; }
|
|
18
|
+
svg { width: 1.25rem; height: 1.25rem; flex: none; }
|
|
19
|
+
button { font: inherit; color: inherit; background: none; border: 0; padding: 0.15rem 0.3rem; cursor: pointer; border-radius: 0.25rem; }
|
|
20
|
+
a:focus-visible, button:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
|
|
21
|
+
[part="list"] { position: absolute; inset-inline-start: 0; inset-block-end: calc(100% + 0.4rem); min-width: 14rem;
|
|
22
|
+
background: var(--uplatform-bg, #fff); border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
|
|
23
|
+
border-radius: 0.5rem; padding: 0.5rem; z-index: 10; box-shadow: 0 8px 24px rgb(0 0 0 / 0.12); }
|
|
24
|
+
:host([data-resolved-theme="dark"]) [part="list"] { background: var(--uplatform-bg, #1c1f24); }
|
|
25
|
+
[part="list"][hidden] { display: none; }
|
|
26
|
+
[role="group"] + [role="group"] { margin-top: 0.5rem; }
|
|
27
|
+
.label { font-size: 0.75em; opacity: 0.7; margin: 0 0 0.25rem; }
|
|
28
|
+
ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.15rem; }
|
|
29
|
+
li a { padding: 0.25rem 0.35rem; border-radius: 0.25rem; }
|
|
30
|
+
`;
|
|
31
|
+
export class UplatformAffiliation extends HTMLElement {
|
|
32
|
+
static observedAttributes = ['product', 'lang', 'theme'];
|
|
33
|
+
#root = this.attachShadow({ mode: 'open' });
|
|
34
|
+
#mql;
|
|
35
|
+
#onDocClick = (e) => { if (!e.composedPath().includes(this))
|
|
36
|
+
this.#close(false); };
|
|
37
|
+
/** OS 테마가 바뀌면 다시 그린다 — 테마가 명시되지 않았을 때만(명시값은 OS 를 따르지 않는다). */
|
|
38
|
+
#onScheme = () => { const t = this.getAttribute('theme'); if (t !== 'light' && t !== 'dark')
|
|
39
|
+
this.#render(); };
|
|
40
|
+
/** 포커스가 엘리먼트 밖으로 나가면 닫는다(포커스는 되돌리지 않는다). relatedTarget 이 없으면(목록 여백 클릭 등) 닫지 않는다. */
|
|
41
|
+
#onFocusOut = (e) => {
|
|
42
|
+
const next = e.relatedTarget;
|
|
43
|
+
if (next && !this.contains(next) && !this.#root.contains(next))
|
|
44
|
+
this.#close(false);
|
|
45
|
+
};
|
|
46
|
+
connectedCallback() {
|
|
47
|
+
this.#render();
|
|
48
|
+
document.addEventListener('click', this.#onDocClick);
|
|
49
|
+
this.#root.addEventListener('focusout', this.#onFocusOut);
|
|
50
|
+
this.#mql = globalThis.matchMedia?.('(prefers-color-scheme: dark)');
|
|
51
|
+
this.#mql?.addEventListener('change', this.#onScheme);
|
|
52
|
+
}
|
|
53
|
+
disconnectedCallback() {
|
|
54
|
+
document.removeEventListener('click', this.#onDocClick);
|
|
55
|
+
this.#root.removeEventListener('focusout', this.#onFocusOut);
|
|
56
|
+
this.#mql?.removeEventListener('change', this.#onScheme);
|
|
57
|
+
this.#mql = undefined;
|
|
58
|
+
}
|
|
59
|
+
attributeChangedCallback() { if (this.isConnected)
|
|
60
|
+
this.#render(); }
|
|
61
|
+
/** 주 언어 태그로 가린다 — en · en-US · en-GB 는 영어, 그 밖은 한국어. */
|
|
62
|
+
get #lang() { return /^en(-|$)/i.test(this.getAttribute('lang') ?? '') ? 'en' : 'ko'; }
|
|
63
|
+
get #theme() {
|
|
64
|
+
const t = this.getAttribute('theme');
|
|
65
|
+
if (t === 'light' || t === 'dark')
|
|
66
|
+
return t;
|
|
67
|
+
return globalThis.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
68
|
+
}
|
|
69
|
+
#render() {
|
|
70
|
+
const lang = this.#lang;
|
|
71
|
+
const theme = this.#theme;
|
|
72
|
+
this.dataset.resolvedTheme = theme;
|
|
73
|
+
const t = TEXT[lang];
|
|
74
|
+
const own = this.getAttribute('product');
|
|
75
|
+
const others = products.filter(p => p.id !== own && p.site);
|
|
76
|
+
const group = (family, label) => {
|
|
77
|
+
const items = others.filter(p => p.family === family);
|
|
78
|
+
if (items.length === 0)
|
|
79
|
+
return '';
|
|
80
|
+
return `<div role="group" aria-labelledby="label-${family}"><p class="label" id="label-${family}">${esc(label)}</p><ul>${items
|
|
81
|
+
.map(p => `<li><a href="${esc(p.site)}">${p.mark ? mark(p.id, theme) : ''}<span>${esc(p.name)}</span></a></li>`)
|
|
82
|
+
.join('')}</ul></div>`;
|
|
83
|
+
};
|
|
84
|
+
this.#root.innerHTML = `<style>${STYLE}</style>
|
|
85
|
+
<div class="row">
|
|
86
|
+
<a part="link" href="${lang === 'en' ? `${HUB}/en/` : HUB}">${mark('u-platform', theme)}<span>${esc(umbrella.name)}</span></a>
|
|
87
|
+
<button part="toggle" type="button" aria-expanded="false" aria-controls="list" aria-label="${esc(t.toggle)}">▾</button>
|
|
88
|
+
</div>
|
|
89
|
+
<div part="list" id="list" hidden>${group('solutions', t.solutions)}${group('system', t.system)}${group('cross', t.cross)}</div>`;
|
|
90
|
+
const toggle = this.#root.querySelector('[part="toggle"]');
|
|
91
|
+
const list = this.#root.querySelector('[part="list"]');
|
|
92
|
+
toggle.addEventListener('click', e => { e.stopPropagation(); list.hidden ? this.#open() : this.#close(false); });
|
|
93
|
+
list.addEventListener('keydown', e => { if (e.key === 'Escape')
|
|
94
|
+
this.#close(true); });
|
|
95
|
+
toggle.addEventListener('keydown', e => { if (e.key === 'Escape')
|
|
96
|
+
this.#close(true); });
|
|
97
|
+
}
|
|
98
|
+
#open() {
|
|
99
|
+
const list = this.#root.querySelector('[part="list"]');
|
|
100
|
+
list.hidden = false;
|
|
101
|
+
this.#root.querySelector('[part="toggle"]').setAttribute('aria-expanded', 'true');
|
|
102
|
+
}
|
|
103
|
+
#close(returnFocus) {
|
|
104
|
+
const list = this.#root.querySelector('[part="list"]');
|
|
105
|
+
const toggle = this.#root.querySelector('[part="toggle"]');
|
|
106
|
+
if (!list || !toggle || list.hidden)
|
|
107
|
+
return;
|
|
108
|
+
list.hidden = true;
|
|
109
|
+
toggle.setAttribute('aria-expanded', 'false');
|
|
110
|
+
if (returnFocus)
|
|
111
|
+
toggle.focus();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export function defineAffiliation(registry = customElements) {
|
|
115
|
+
if (!registry.get('uplatform-affiliation'))
|
|
116
|
+
registry.define('uplatform-affiliation', UplatformAffiliation);
|
|
117
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
{
|
|
2
|
+
"viewBox": "0 0 64 64",
|
|
3
|
+
"size": 64,
|
|
4
|
+
"arms": "M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z",
|
|
5
|
+
"bowl": "M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z",
|
|
6
|
+
"stroke": {
|
|
7
|
+
"d": "M11.000 -2.000V32.000A21.000 21.000 0 0 0 53.000 32.000V-2.000",
|
|
8
|
+
"width": 30,
|
|
9
|
+
"head": 9
|
|
10
|
+
},
|
|
11
|
+
"band": {
|
|
12
|
+
"y": 30,
|
|
13
|
+
"height": 34
|
|
14
|
+
},
|
|
15
|
+
"glyphStroke": 2.25,
|
|
16
|
+
"ink": {
|
|
17
|
+
"light": "#333232",
|
|
18
|
+
"dark": "#D6D6D6"
|
|
19
|
+
},
|
|
20
|
+
"track": {
|
|
21
|
+
"light": "#C9CDD3",
|
|
22
|
+
"dark": "#3A4150"
|
|
23
|
+
},
|
|
24
|
+
"products": {
|
|
25
|
+
"u-platform": {
|
|
26
|
+
"name": "U-Platform",
|
|
27
|
+
"color": {
|
|
28
|
+
"light": "#3C62A1",
|
|
29
|
+
"dark": "#80A5E3"
|
|
30
|
+
},
|
|
31
|
+
"glyph": {
|
|
32
|
+
"d": "M26.00 27.20H38.00M26.00 32.00H38.00M26.00 36.80H38.00",
|
|
33
|
+
"filled": false
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"u-cmms": {
|
|
37
|
+
"name": "U-CMMS",
|
|
38
|
+
"color": {
|
|
39
|
+
"light": "#556E1C",
|
|
40
|
+
"dark": "#96B069"
|
|
41
|
+
},
|
|
42
|
+
"glyph": {
|
|
43
|
+
"d": "M27.20 32.00A4.80 4.80 0 1 0 36.80 32.00A4.80 4.80 0 1 0 27.20 32.00Z",
|
|
44
|
+
"filled": false
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"u-mes": {
|
|
48
|
+
"name": "U-MES",
|
|
49
|
+
"color": {
|
|
50
|
+
"light": "#00728A",
|
|
51
|
+
"dark": "#4DB4CC"
|
|
52
|
+
},
|
|
53
|
+
"glyph": {
|
|
54
|
+
"d": "M27.80 26.00L37.40 32.00L27.80 38.00Z",
|
|
55
|
+
"filled": false
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"u-board": {
|
|
59
|
+
"name": "U-Board",
|
|
60
|
+
"color": {
|
|
61
|
+
"light": "#007759",
|
|
62
|
+
"dark": "#5CB99B"
|
|
63
|
+
},
|
|
64
|
+
"glyph": {
|
|
65
|
+
"d": "M26.00 26.00H38.00V38.00H26.00ZM32.00 26.00V38.00M26.00 32.00H38.00",
|
|
66
|
+
"filled": false
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"u-draw": {
|
|
70
|
+
"name": "U-Draw",
|
|
71
|
+
"color": {
|
|
72
|
+
"light": "#974936",
|
|
73
|
+
"dark": "#DB8E7A"
|
|
74
|
+
},
|
|
75
|
+
"glyph": {
|
|
76
|
+
"d": "M26.00 32.00H38.00M32.00 26.00V38.00",
|
|
77
|
+
"filled": false
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"u-sphere": {
|
|
81
|
+
"name": "U-Sphere",
|
|
82
|
+
"color": {
|
|
83
|
+
"light": "#725195",
|
|
84
|
+
"dark": "#B395D7"
|
|
85
|
+
},
|
|
86
|
+
"glyph": {
|
|
87
|
+
"d": "M32.00 26.00L38.00 32.00L32.00 38.00L26.00 32.00Z",
|
|
88
|
+
"filled": false
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"u-vision": {
|
|
92
|
+
"name": "U-Vision",
|
|
93
|
+
"color": {
|
|
94
|
+
"light": "#845B00",
|
|
95
|
+
"dark": "#C69E58"
|
|
96
|
+
},
|
|
97
|
+
"glyph": {
|
|
98
|
+
"d": "M28.70 32.00A3.30 3.30 0 1 0 35.30 32.00A3.30 3.30 0 1 0 28.70 32.00Z",
|
|
99
|
+
"filled": true
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"u-ems": {
|
|
103
|
+
"name": "U-EMS",
|
|
104
|
+
"color": {
|
|
105
|
+
"light": "#915115",
|
|
106
|
+
"dark": "#D49464"
|
|
107
|
+
},
|
|
108
|
+
"glyph": {
|
|
109
|
+
"d": "M33.80 26.00L29.00 32.60L35.00 31.40L30.20 38.00",
|
|
110
|
+
"filled": false
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"timing": {
|
|
115
|
+
"reveal": {
|
|
116
|
+
"duration": 1500,
|
|
117
|
+
"stroke": [
|
|
118
|
+
0,
|
|
119
|
+
0.55
|
|
120
|
+
],
|
|
121
|
+
"band": [
|
|
122
|
+
0.55,
|
|
123
|
+
0.82
|
|
124
|
+
],
|
|
125
|
+
"glyph": [
|
|
126
|
+
0.82,
|
|
127
|
+
1
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
"chase": {
|
|
131
|
+
"duration": 1800,
|
|
132
|
+
"length": 0.32
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// 생성물 — 직접 고치지 않는다.
|
|
2
|
+
export const MARKS = {
|
|
3
|
+
"u-cmms": { light: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#333232\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#556E1C\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#556E1C\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M27.20 32.00A4.80 4.80 0 1 0 36.80 32.00A4.80 4.80 0 1 0 27.20 32.00Z\"/></svg>", dark: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#D6D6D6\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#96B069\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#96B069\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M27.20 32.00A4.80 4.80 0 1 0 36.80 32.00A4.80 4.80 0 1 0 27.20 32.00Z\"/></svg>" },
|
|
4
|
+
"u-mes": { light: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#333232\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#00728A\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#00728A\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M27.80 26.00L37.40 32.00L27.80 38.00Z\"/></svg>", dark: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#D6D6D6\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#4DB4CC\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#4DB4CC\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M27.80 26.00L37.40 32.00L27.80 38.00Z\"/></svg>" },
|
|
5
|
+
"u-ems": { light: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#333232\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#915115\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#915115\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M33.80 26.00L29.00 32.60L35.00 31.40L30.20 38.00\"/></svg>", dark: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#D6D6D6\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#D49464\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#D49464\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M33.80 26.00L29.00 32.60L35.00 31.40L30.20 38.00\"/></svg>" },
|
|
6
|
+
"u-sphere": { light: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#333232\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#725195\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#725195\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M32.00 26.00L38.00 32.00L32.00 38.00L26.00 32.00Z\"/></svg>", dark: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#D6D6D6\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#B395D7\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#B395D7\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M32.00 26.00L38.00 32.00L32.00 38.00L26.00 32.00Z\"/></svg>" },
|
|
7
|
+
"u-board": { light: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#333232\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#007759\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#007759\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M26.00 26.00H38.00V38.00H26.00ZM32.00 26.00V38.00M26.00 32.00H38.00\"/></svg>", dark: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#D6D6D6\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#5CB99B\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#5CB99B\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M26.00 26.00H38.00V38.00H26.00ZM32.00 26.00V38.00M26.00 32.00H38.00\"/></svg>" },
|
|
8
|
+
"u-vision": { light: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#333232\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#845B00\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"#845B00\" d=\"M28.70 32.00A3.30 3.30 0 1 0 35.30 32.00A3.30 3.30 0 1 0 28.70 32.00Z\"/></svg>", dark: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#D6D6D6\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#C69E58\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"#C69E58\" d=\"M28.70 32.00A3.30 3.30 0 1 0 35.30 32.00A3.30 3.30 0 1 0 28.70 32.00Z\"/></svg>" },
|
|
9
|
+
"u-draw": { light: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#333232\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#974936\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#974936\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M26.00 32.00H38.00M32.00 26.00V38.00\"/></svg>", dark: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#D6D6D6\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#DB8E7A\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#DB8E7A\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M26.00 32.00H38.00M32.00 26.00V38.00\"/></svg>" },
|
|
10
|
+
"u-platform": { light: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#333232\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#3C62A1\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#3C62A1\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M26.00 27.20H38.00M26.00 32.00H38.00M26.00 36.80H38.00\"/></svg>", dark: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\" width=\"64\" height=\"64\"><path fill=\"#D6D6D6\" d=\"M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z\"/><path fill=\"#80A5E3\" d=\"M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z\"/><path fill=\"none\" stroke=\"#80A5E3\" stroke-width=\"2.250\" stroke-linejoin=\"miter\" d=\"M26.00 27.20H38.00M26.00 32.00H38.00M26.00 36.80H38.00\"/></svg>" },
|
|
11
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"umbrella": {
|
|
3
|
+
"name": "U-Platform",
|
|
4
|
+
"hue": 260,
|
|
5
|
+
"color": {
|
|
6
|
+
"light": "#3C62A1",
|
|
7
|
+
"dark": "#80A5E3"
|
|
8
|
+
},
|
|
9
|
+
"ink": {
|
|
10
|
+
"light": "#333232",
|
|
11
|
+
"dark": "#D6D6D6"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"products": [
|
|
15
|
+
{
|
|
16
|
+
"id": "u-cmms",
|
|
17
|
+
"name": "U-CMMS",
|
|
18
|
+
"family": "solutions",
|
|
19
|
+
"site": "https://cmms.u-platform.kr",
|
|
20
|
+
"hue": 125,
|
|
21
|
+
"color": {
|
|
22
|
+
"light": "#556E1C",
|
|
23
|
+
"dark": "#96B069"
|
|
24
|
+
},
|
|
25
|
+
"glyph": "ring",
|
|
26
|
+
"mark": true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "u-mes",
|
|
30
|
+
"name": "U-MES",
|
|
31
|
+
"family": "solutions",
|
|
32
|
+
"hue": 215,
|
|
33
|
+
"color": {
|
|
34
|
+
"light": "#00728A",
|
|
35
|
+
"dark": "#4DB4CC"
|
|
36
|
+
},
|
|
37
|
+
"glyph": "flow",
|
|
38
|
+
"mark": true
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "u-ems",
|
|
42
|
+
"name": "U-EMS",
|
|
43
|
+
"family": "solutions",
|
|
44
|
+
"hue": 57.5,
|
|
45
|
+
"color": {
|
|
46
|
+
"light": "#915115",
|
|
47
|
+
"dark": "#D49464"
|
|
48
|
+
},
|
|
49
|
+
"glyph": "bolt",
|
|
50
|
+
"mark": true
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "u-sphere",
|
|
54
|
+
"name": "U-Sphere",
|
|
55
|
+
"family": "system",
|
|
56
|
+
"hue": 305,
|
|
57
|
+
"color": {
|
|
58
|
+
"light": "#725195",
|
|
59
|
+
"dark": "#B395D7"
|
|
60
|
+
},
|
|
61
|
+
"glyph": "node",
|
|
62
|
+
"mark": true
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "u-board",
|
|
66
|
+
"name": "U-Board",
|
|
67
|
+
"family": "cross",
|
|
68
|
+
"site": "https://github.com/iyulab/U-Board",
|
|
69
|
+
"hue": 170,
|
|
70
|
+
"color": {
|
|
71
|
+
"light": "#007759",
|
|
72
|
+
"dark": "#5CB99B"
|
|
73
|
+
},
|
|
74
|
+
"glyph": "grid",
|
|
75
|
+
"mark": true
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "u-vision",
|
|
79
|
+
"name": "U-Vision",
|
|
80
|
+
"family": "cross",
|
|
81
|
+
"site": "https://github.com/iyulab/U-Vision",
|
|
82
|
+
"hue": 80,
|
|
83
|
+
"color": {
|
|
84
|
+
"light": "#845B00",
|
|
85
|
+
"dark": "#C69E58"
|
|
86
|
+
},
|
|
87
|
+
"glyph": "dot",
|
|
88
|
+
"mark": true
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": "u-draw",
|
|
92
|
+
"name": "U-Draw",
|
|
93
|
+
"family": "cross",
|
|
94
|
+
"site": "https://udraw.iyulab.com",
|
|
95
|
+
"hue": 35,
|
|
96
|
+
"color": {
|
|
97
|
+
"light": "#974936",
|
|
98
|
+
"dark": "#DB8E7A"
|
|
99
|
+
},
|
|
100
|
+
"glyph": "plus",
|
|
101
|
+
"mark": true
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type State = {
|
|
2
|
+
mode: 'reveal' | 'chase' | 'still';
|
|
3
|
+
stroke: [number, number];
|
|
4
|
+
band: [number, number];
|
|
5
|
+
glyph: number;
|
|
6
|
+
head: boolean;
|
|
7
|
+
};
|
|
8
|
+
/** @typedef {{ mode: 'reveal'|'chase'|'still', stroke: [number, number], band: [number, number], glyph: number, head: boolean }} State */
|
|
9
|
+
/** @type {Readonly<State>} 완성 마크 — 움직임 줄이기 · motion="none" */
|
|
10
|
+
export declare const DONE: Readonly<State>;
|
|
11
|
+
/** @param {any} timing @param {number} p @returns {State} */
|
|
12
|
+
export declare function revealAt(timing: any, p: number): State;
|
|
13
|
+
/** @param {any} timing @param {number} p @returns {State} */
|
|
14
|
+
export declare function chaseAt(timing: any, p: number): State;
|
|
15
|
+
/**
|
|
16
|
+
* svg 안에 마크를 세운다. 같은 페이지에 여럿이어도 clipPath id 가 겹치지 않는다.
|
|
17
|
+
* @param {SVGSVGElement} svg @param {any} geo @param {string} id @param {'light'|'dark'} theme
|
|
18
|
+
* @returns {{ set(state: State): void }}
|
|
19
|
+
*/
|
|
20
|
+
export declare function mount(svg: SVGSVGElement, geo: any, id: string, theme: 'light' | 'dark'): {
|
|
21
|
+
set(state: State): void;
|
|
22
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* U 시리즈 모션 — 유일한 렌더러. 기하는 호출자가 넘겨주는 생성된 기하 데이터에서 온다.
|
|
2
|
+
빈 바탕에 한 획으로 U 를 긋고, 가로획이 그릇에 제품 색을 입힌다. 바탕은 칠하지 않는다.
|
|
3
|
+
상태 함수는 순수하다(시간이 아니라 진행도 p 를 받는다) — 캡처가 재현 가능하다. */
|
|
4
|
+
const NS = 'http://www.w3.org/2000/svg';
|
|
5
|
+
const clamp = x => Math.max(0, Math.min(1, x));
|
|
6
|
+
const seg = (p, [a, b]) => clamp((p - a) / (b - a));
|
|
7
|
+
const easeInOut = t => (t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2);
|
|
8
|
+
const easeOut = t => 1 - Math.pow(1 - t, 3);
|
|
9
|
+
/** @typedef {{ mode: 'reveal'|'chase'|'still', stroke: [number, number], band: [number, number], glyph: number, head: boolean }} State */
|
|
10
|
+
/** @type {Readonly<State>} 완성 마크 — 움직임 줄이기 · motion="none" */
|
|
11
|
+
export const DONE = Object.freeze({ mode: 'still', stroke: [0, 1], band: [0, 1], glyph: 1, head: false });
|
|
12
|
+
/** @param {any} timing @param {number} p @returns {State} */
|
|
13
|
+
export function revealAt(timing, p) {
|
|
14
|
+
const T = timing.reveal;
|
|
15
|
+
return { mode: 'reveal', stroke: [0, easeInOut(seg(p, T.stroke))], band: [0, easeInOut(seg(p, T.band))], glyph: easeOut(seg(p, T.glyph)), head: true };
|
|
16
|
+
}
|
|
17
|
+
/** @param {any} timing @param {number} p @returns {State} */
|
|
18
|
+
export function chaseAt(timing, p) {
|
|
19
|
+
const L = timing.chase.length;
|
|
20
|
+
const x = easeInOut(p < 0.5 ? p * 2 : 2 - p * 2);
|
|
21
|
+
const a = x * (1 - L);
|
|
22
|
+
return { mode: 'chase', stroke: [a, a + L], band: [0, 0], glyph: 1, head: false };
|
|
23
|
+
}
|
|
24
|
+
let serial = 0;
|
|
25
|
+
/**
|
|
26
|
+
* svg 안에 마크를 세운다. 같은 페이지에 여럿이어도 clipPath id 가 겹치지 않는다.
|
|
27
|
+
* @param {SVGSVGElement} svg @param {any} geo @param {string} id @param {'light'|'dark'} theme
|
|
28
|
+
* @returns {{ set(state: State): void }}
|
|
29
|
+
*/
|
|
30
|
+
export function mount(svg, geo, id, theme) {
|
|
31
|
+
const p = geo.products[id];
|
|
32
|
+
if (!p)
|
|
33
|
+
throw new Error(`u-motion: unknown product ${id}`);
|
|
34
|
+
const doc = svg.ownerDocument;
|
|
35
|
+
const el = (tag, attrs, parent) => {
|
|
36
|
+
const n = doc.createElementNS(NS, tag);
|
|
37
|
+
for (const k in attrs)
|
|
38
|
+
n.setAttribute(k, String(attrs[k]));
|
|
39
|
+
parent.appendChild(n);
|
|
40
|
+
return n;
|
|
41
|
+
};
|
|
42
|
+
const uid = `um${++serial}`;
|
|
43
|
+
const ink = geo.ink[theme], color = p.color[theme], track = geo.track[theme];
|
|
44
|
+
svg.setAttribute('viewBox', geo.viewBox);
|
|
45
|
+
while (svg.firstChild)
|
|
46
|
+
svg.removeChild(svg.firstChild);
|
|
47
|
+
const defs = el('defs', {}, svg);
|
|
48
|
+
const markClip = el('clipPath', { id: `${uid}m` }, defs);
|
|
49
|
+
el('path', { d: geo.arms }, markClip);
|
|
50
|
+
el('path', { d: geo.bowl }, markClip);
|
|
51
|
+
const bowlClip = el('clipPath', { id: `${uid}b` }, defs);
|
|
52
|
+
el('path', { d: geo.bowl }, bowlClip);
|
|
53
|
+
const trackG = el('g', { fill: track, display: 'none' }, svg);
|
|
54
|
+
el('path', { d: geo.arms }, trackG);
|
|
55
|
+
el('path', { d: geo.bowl }, trackG);
|
|
56
|
+
const body = el('g', { 'clip-path': `url(#${uid}m)` }, svg);
|
|
57
|
+
const stroke = el('path', { d: geo.stroke.d, fill: 'none', 'stroke-width': geo.stroke.width, pathLength: 1 }, body);
|
|
58
|
+
const head = el('circle', { r: 0 }, body);
|
|
59
|
+
const band = el('rect', { x: 0, y: geo.band.y, width: 0, height: geo.band.height, fill: color, 'clip-path': `url(#${uid}b)` }, svg);
|
|
60
|
+
const glyph = el('path', p.glyph.filled
|
|
61
|
+
? { d: p.glyph.d, class: 'glyph' }
|
|
62
|
+
: { d: p.glyph.d, class: 'glyph', fill: 'none', 'stroke-width': geo.glyphStroke, 'stroke-linejoin': 'miter' }, svg);
|
|
63
|
+
// 붓머리 위치는 브라우저만 잴 수 있다(jsdom 등엔 없다) — 없으면 머리 없이 그린다.
|
|
64
|
+
const measurable = typeof stroke.getPointAtLength === 'function' && typeof stroke.getTotalLength === 'function';
|
|
65
|
+
const W = geo.size;
|
|
66
|
+
return {
|
|
67
|
+
set(s) {
|
|
68
|
+
const chase = s.mode === 'chase';
|
|
69
|
+
trackG.setAttribute('display', chase ? 'inline' : 'none');
|
|
70
|
+
const strokeColor = chase ? color : ink;
|
|
71
|
+
stroke.setAttribute('stroke', strokeColor);
|
|
72
|
+
head.setAttribute('fill', strokeColor);
|
|
73
|
+
const glyphColor = chase ? ink : color;
|
|
74
|
+
glyph.setAttribute(p.glyph.filled ? 'fill' : 'stroke', glyphColor);
|
|
75
|
+
const [a, b] = s.stroke;
|
|
76
|
+
stroke.setAttribute('stroke-dasharray', `0 ${a} ${Math.max(0, b - a)} 2`);
|
|
77
|
+
let r = 0;
|
|
78
|
+
if (s.head && measurable && b > 0 && b < 1) {
|
|
79
|
+
const pt = stroke.getPointAtLength(stroke.getTotalLength() * b);
|
|
80
|
+
head.setAttribute('cx', pt.x);
|
|
81
|
+
head.setAttribute('cy', pt.y);
|
|
82
|
+
r = geo.stroke.head;
|
|
83
|
+
}
|
|
84
|
+
head.setAttribute('r', r);
|
|
85
|
+
const [b0, b1] = s.band;
|
|
86
|
+
band.setAttribute('x', W * b0 - 0.5);
|
|
87
|
+
band.setAttribute('width', b1 > b0 ? W * (b1 - b0) + 1 : 0);
|
|
88
|
+
glyph.setAttribute('opacity', s.glyph);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { products, umbrella, productHref, HUB } from './products.js';
|
|
2
|
+
export { UplatformAffiliation, defineAffiliation } from './affiliation.js';
|
|
3
|
+
export { UMark, defineMark } from './mark.js';
|
|
4
|
+
import { defineAffiliation } from './affiliation.js';
|
|
5
|
+
import { defineMark } from './mark.js';
|
|
6
|
+
// 진입점을 import 하면 두 태그가 등록된다. 등록 없이 쓰려면 './products' 를 import 한다.
|
|
7
|
+
if (typeof customElements !== 'undefined') {
|
|
8
|
+
defineAffiliation();
|
|
9
|
+
defineMark();
|
|
10
|
+
}
|
package/dist/mark.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare class UMark extends HTMLElement {
|
|
2
|
+
#private;
|
|
3
|
+
static observedAttributes: string[];
|
|
4
|
+
connectedCallback(): void;
|
|
5
|
+
disconnectedCallback(): void;
|
|
6
|
+
attributeChangedCallback(name: string): void;
|
|
7
|
+
}
|
|
8
|
+
export declare function defineMark(registry?: CustomElementRegistry): void;
|
package/dist/mark.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// <u-mark> — U 시리즈 마크. 등장(빈 바탕에 한 획 + 가로획 색) · Chase(로딩) · 정지.
|
|
2
|
+
// 렌더러는 키트의 유일한 구현(generated/u-motion.js)이다 — 여기서 다시 그리지 않는다.
|
|
3
|
+
import geometry from './generated/geometry.json' with { type: 'json' };
|
|
4
|
+
import { mount, revealAt, chaseAt, DONE } from './generated/u-motion.js';
|
|
5
|
+
const STYLE = `
|
|
6
|
+
:host { display: inline-block; width: 64px; height: auto; aspect-ratio: 1; container-type: size; }
|
|
7
|
+
svg { display: block; width: 100%; height: 100%; overflow: visible; }
|
|
8
|
+
@container (max-width: 32px) or (max-height: 32px) { .glyph { display: none; } }
|
|
9
|
+
`;
|
|
10
|
+
export class UMark extends HTMLElement {
|
|
11
|
+
static observedAttributes = ['product', 'motion', 'theme', 'play'];
|
|
12
|
+
#root = this.attachShadow({ mode: 'open' });
|
|
13
|
+
#raf = 0;
|
|
14
|
+
/** 렌더 세대 — 옛 렌더의 rAF·관찰자 콜백이 늦게 도착해도 현재 마크를 건드리지 못하게 한다. */
|
|
15
|
+
#gen = 0;
|
|
16
|
+
/** 등장이 한 번 시작됐다 — 이후 재렌더(테마 전환 등)는 완성 마크를 바로 그린다. product·motion 변경만 되돌린다. */
|
|
17
|
+
#revealed = false;
|
|
18
|
+
/** 연결 콜백을 지났다 — 업그레이드 때는 속성 콜백들이 연결 콜백보다 먼저 오면서 isConnected 는 이미 참이라,
|
|
19
|
+
* 그 사이 렌더가 등장을 «시작됨»으로 소진해 버린다. 렌더는 연결 콜백 이후에만 한다. */
|
|
20
|
+
#connected = false;
|
|
21
|
+
#io;
|
|
22
|
+
#scheme;
|
|
23
|
+
#onScheme = () => { const t = this.getAttribute('theme'); if (t !== 'light' && t !== 'dark')
|
|
24
|
+
this.#render(); };
|
|
25
|
+
connectedCallback() {
|
|
26
|
+
this.#connected = true;
|
|
27
|
+
this.#render();
|
|
28
|
+
this.#scheme = globalThis.matchMedia?.('(prefers-color-scheme: dark)');
|
|
29
|
+
this.#scheme?.addEventListener('change', this.#onScheme);
|
|
30
|
+
}
|
|
31
|
+
disconnectedCallback() {
|
|
32
|
+
this.#connected = false;
|
|
33
|
+
this.#stop();
|
|
34
|
+
this.#scheme?.removeEventListener('change', this.#onScheme);
|
|
35
|
+
this.#scheme = undefined;
|
|
36
|
+
}
|
|
37
|
+
attributeChangedCallback(name) {
|
|
38
|
+
if (name === 'product' || name === 'motion')
|
|
39
|
+
this.#revealed = false;
|
|
40
|
+
if (this.#connected)
|
|
41
|
+
this.#render();
|
|
42
|
+
}
|
|
43
|
+
get #theme() {
|
|
44
|
+
const t = this.getAttribute('theme');
|
|
45
|
+
if (t === 'light' || t === 'dark')
|
|
46
|
+
return t;
|
|
47
|
+
return globalThis.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
48
|
+
}
|
|
49
|
+
get #reduced() { return globalThis.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false; }
|
|
50
|
+
#stop() {
|
|
51
|
+
if (this.#raf)
|
|
52
|
+
cancelAnimationFrame(this.#raf);
|
|
53
|
+
this.#raf = 0;
|
|
54
|
+
this.#io?.disconnect();
|
|
55
|
+
this.#io = undefined;
|
|
56
|
+
}
|
|
57
|
+
#render() {
|
|
58
|
+
this.#stop();
|
|
59
|
+
const gen = ++this.#gen;
|
|
60
|
+
const id = this.getAttribute('product') ?? 'u-platform';
|
|
61
|
+
if (!Object.hasOwn(geometry.products, id)) {
|
|
62
|
+
this.#root.innerHTML = '';
|
|
63
|
+
console.error(`<u-mark>: unknown product "${id}"`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.#root.innerHTML = `<style>${STYLE}</style><svg aria-hidden="true" focusable="false"></svg>`;
|
|
67
|
+
const ctl = mount(this.#root.querySelector('svg'), geometry, id, this.#theme);
|
|
68
|
+
const motion = this.getAttribute('motion');
|
|
69
|
+
if (this.#reduced || (motion !== 'reveal' && motion !== 'chase')) {
|
|
70
|
+
ctl.set(DONE);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const timing = geometry.timing;
|
|
74
|
+
if (motion === 'chase') {
|
|
75
|
+
const t0 = performance.now();
|
|
76
|
+
const tick = (now) => {
|
|
77
|
+
if (gen !== this.#gen)
|
|
78
|
+
return;
|
|
79
|
+
ctl.set(chaseAt(timing, ((now - t0) % timing.chase.duration) / timing.chase.duration));
|
|
80
|
+
this.#raf = requestAnimationFrame(tick);
|
|
81
|
+
};
|
|
82
|
+
this.#raf = requestAnimationFrame(tick);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (this.#revealed) {
|
|
86
|
+
ctl.set(DONE);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
ctl.set(revealAt(timing, 0));
|
|
90
|
+
const play = () => {
|
|
91
|
+
if (gen !== this.#gen)
|
|
92
|
+
return;
|
|
93
|
+
this.#revealed = true;
|
|
94
|
+
const t0 = performance.now();
|
|
95
|
+
const tick = (now) => {
|
|
96
|
+
if (gen !== this.#gen)
|
|
97
|
+
return;
|
|
98
|
+
const p = Math.min(1, (now - t0) / timing.reveal.duration);
|
|
99
|
+
ctl.set(p < 1 ? revealAt(timing, p) : DONE);
|
|
100
|
+
this.#raf = p < 1 ? requestAnimationFrame(tick) : 0;
|
|
101
|
+
};
|
|
102
|
+
this.#raf = requestAnimationFrame(tick);
|
|
103
|
+
};
|
|
104
|
+
const IO = globalThis.IntersectionObserver;
|
|
105
|
+
if (this.getAttribute('play') === 'visible' && typeof IO === 'function') {
|
|
106
|
+
const io = new IO(entries => {
|
|
107
|
+
// 문턱 0.5 여도 첫 통지는 가장자리만 걸친 상태로 올 수 있다 — 비율을 직접 확인한다.
|
|
108
|
+
if (this.#io !== io || !entries.some(e => e.isIntersecting && e.intersectionRatio >= 0.5))
|
|
109
|
+
return;
|
|
110
|
+
io.disconnect();
|
|
111
|
+
this.#io = undefined;
|
|
112
|
+
play();
|
|
113
|
+
}, { threshold: 0.5 });
|
|
114
|
+
this.#io = io;
|
|
115
|
+
io.observe(this);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
play();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export function defineMark(registry = customElements) {
|
|
123
|
+
if (!registry.get('u-mark'))
|
|
124
|
+
registry.define('u-mark', UMark);
|
|
125
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface Product {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
family: 'solutions' | 'system' | 'cross';
|
|
5
|
+
/** 제품 자신의 공개 페이지. 없으면 링크하지 않는다(갈 곳이 없다). */
|
|
6
|
+
site?: string;
|
|
7
|
+
hue?: number;
|
|
8
|
+
color?: {
|
|
9
|
+
light: string;
|
|
10
|
+
dark: string;
|
|
11
|
+
};
|
|
12
|
+
glyph?: string;
|
|
13
|
+
mark: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const HUB = "https://u-platform.kr";
|
|
16
|
+
export declare const products: readonly Product[];
|
|
17
|
+
export declare const umbrella: {
|
|
18
|
+
name: string;
|
|
19
|
+
hue: number;
|
|
20
|
+
color: {
|
|
21
|
+
light: string;
|
|
22
|
+
dark: string;
|
|
23
|
+
};
|
|
24
|
+
ink: {
|
|
25
|
+
light: string;
|
|
26
|
+
dark: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/** 갈 곳이 있으면 그 주소, 없으면 undefined — 쓰는 쪽은 링크 대신 글자만 둔다. */
|
|
30
|
+
export declare function productHref(product: Product): string | undefined;
|
package/dist/products.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import data from './generated/products.json' with { type: 'json' };
|
|
2
|
+
export const HUB = 'https://u-platform.kr';
|
|
3
|
+
export const products = data.products;
|
|
4
|
+
export const umbrella = data.umbrella;
|
|
5
|
+
/** 갈 곳이 있으면 그 주소, 없으면 undefined — 쓰는 쪽은 링크 대신 글자만 둔다. */
|
|
6
|
+
export function productHref(product) {
|
|
7
|
+
return product.site;
|
|
8
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1079.3771 647.507" width="1079.3771" height="647.507" role="img">
|
|
2
|
+
<title>iyulab</title>
|
|
3
|
+
<g transform="translate(-373.6,-188.42)">
|
|
4
|
+
<path fill="#333232" d="M373.6,419.55A231.13,231.13 0 1,1 835.86,419.55A231.13,231.13 0 1,1 373.6,419.55Z"/>
|
|
5
|
+
<path fill="#D6D6D6" d="M697.182,207.7159A231.13,231.13 0 1,0 697.182,631.3841Z"/>
|
|
6
|
+
<path fill="#333232" d="M990.7171,419.55A231.13,231.13 0 1,1 1452.9771,419.55A231.13,231.13 0 1,1 990.7171,419.55Z"/>
|
|
7
|
+
<path fill="#D6D6D6" d="M1433.6812,512.002A231.13,231.13 0 1,0 1010.013,512.002Z"/>
|
|
8
|
+
<path fill="#D6D6D6" d="M1187.4665,572.2114L1256.2277,572.2114L1256.2277,648.1086A231.13,231.13 0 0,1 1187.4665,648.1086Z"/>
|
|
9
|
+
<path fill="#D6D6D6" d="M446.566,726.223H465.327V833.363H446.566ZZ"/>
|
|
10
|
+
<path fill="#D6D6D6" d="M599.63,791.335L559.411,726.223L581.148,726.223L609.527,774.235L637.446,726.223L658.443,726.223L618.373,791.335L618.373,833.362L599.63,833.362L599.63,791.335Z"/>
|
|
11
|
+
<path fill="#D6D6D6" d="M751.164,726.223L769.941,726.223L769.941,788.638C769.941,793.358 770.171,797.353 770.599,800.675C771.059,803.963 772.077,807.055 773.688,809.964C775.285,812.859 777.832,815.21 781.334,817.019C784.838,818.827 789.441,819.714 795.147,819.714C800.835,819.714 805.457,818.827 808.942,817.019C812.444,815.21 814.994,812.859 816.604,809.964C818.182,807.055 819.218,803.963 819.662,800.675C820.123,797.353 820.352,793.358 820.352,788.638L820.352,726.223L839.114,726.223L839.114,794.804C839.114,808.204 835.185,818.4 827.325,825.404C819.465,832.424 808.745,835.927 795.147,835.927C781.533,835.927 770.796,832.424 762.952,825.404C755.094,818.4 751.164,808.204 751.164,794.804L751.164,726.223Z"/>
|
|
12
|
+
<path fill="#D6D6D6" d="M944.132,726.223L962.909,726.223L962.909,817.15L1017.366,817.15L1017.366,833.363L944.132,833.363L944.132,726.223Z"/>
|
|
13
|
+
<path fill="#D6D6D6" d="M1135.753,790.742L1168.473,790.742L1152.408,744.671L1151.964,744.671L1135.753,790.742M1142.361,726.222L1162.324,726.222L1203.594,833.362L1183.468,833.362L1173.406,804.998L1130.655,804.998L1120.608,833.362L1101.256,833.362L1142.361,726.222Z"/>
|
|
14
|
+
<path fill="#D6D6D6" d="M1315.962,818.07L1349.126,818.07C1354.832,818.07 1359.271,816.591 1362.412,813.631C1365.553,810.671 1367.13,806.495 1367.13,801.102C1367.13,795.906 1365.553,791.86 1362.412,788.933C1359.271,786.056 1354.832,784.593 1349.126,784.593L1315.962,784.593L1315.962,818.07M1315.962,771.078L1346.577,771.078C1351.182,771.078 1354.964,769.796 1357.906,767.197C1360.85,764.599 1362.33,760.949 1362.33,756.247C1362.33,750.953 1361.03,747.17 1358.432,744.902C1355.834,742.666 1351.872,741.548 1346.577,741.548L1315.962,741.548L1315.962,771.078M1297.218,726.222L1349.275,726.222C1359.19,726.222 1366.967,728.492 1372.622,732.981C1378.278,737.469 1381.107,744.08 1381.107,752.793C1381.107,758.089 1379.758,762.692 1377.111,766.59C1374.464,770.485 1370.683,773.477 1365.783,775.598L1365.783,775.912C1372.294,777.293 1377.259,780.418 1380.713,785.284C1384.166,790.118 1385.892,796.203 1385.892,803.502C1385.892,812.413 1382.62,819.616 1376.059,825.108C1369.514,830.616 1359.633,833.362 1346.429,833.362L1297.218,833.362L1297.218,726.222Z"/>
|
|
15
|
+
</g>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1079.3771 647.507" width="1079.3771" height="647.507" role="img">
|
|
2
|
+
<title>iyulab</title>
|
|
3
|
+
<g transform="translate(-373.6,-188.42)">
|
|
4
|
+
<path fill="#D6D6D6" d="M373.6,419.55A231.13,231.13 0 1,1 835.86,419.55A231.13,231.13 0 1,1 373.6,419.55Z"/>
|
|
5
|
+
<path fill="#333232" d="M697.182,207.7159A231.13,231.13 0 1,0 697.182,631.3841Z"/>
|
|
6
|
+
<path fill="#D6D6D6" d="M990.7171,419.55A231.13,231.13 0 1,1 1452.9771,419.55A231.13,231.13 0 1,1 990.7171,419.55Z"/>
|
|
7
|
+
<path fill="#333232" d="M1433.6812,512.002A231.13,231.13 0 1,0 1010.013,512.002Z"/>
|
|
8
|
+
<path fill="#333232" d="M1187.4665,572.2114L1256.2277,572.2114L1256.2277,648.1086A231.13,231.13 0 0,1 1187.4665,648.1086Z"/>
|
|
9
|
+
<path fill="#333232" d="M446.566,726.223H465.327V833.363H446.566ZZ"/>
|
|
10
|
+
<path fill="#333232" d="M599.63,791.335L559.411,726.223L581.148,726.223L609.527,774.235L637.446,726.223L658.443,726.223L618.373,791.335L618.373,833.362L599.63,833.362L599.63,791.335Z"/>
|
|
11
|
+
<path fill="#333232" d="M751.164,726.223L769.941,726.223L769.941,788.638C769.941,793.358 770.171,797.353 770.599,800.675C771.059,803.963 772.077,807.055 773.688,809.964C775.285,812.859 777.832,815.21 781.334,817.019C784.838,818.827 789.441,819.714 795.147,819.714C800.835,819.714 805.457,818.827 808.942,817.019C812.444,815.21 814.994,812.859 816.604,809.964C818.182,807.055 819.218,803.963 819.662,800.675C820.123,797.353 820.352,793.358 820.352,788.638L820.352,726.223L839.114,726.223L839.114,794.804C839.114,808.204 835.185,818.4 827.325,825.404C819.465,832.424 808.745,835.927 795.147,835.927C781.533,835.927 770.796,832.424 762.952,825.404C755.094,818.4 751.164,808.204 751.164,794.804L751.164,726.223Z"/>
|
|
12
|
+
<path fill="#333232" d="M944.132,726.223L962.909,726.223L962.909,817.15L1017.366,817.15L1017.366,833.363L944.132,833.363L944.132,726.223Z"/>
|
|
13
|
+
<path fill="#333232" d="M1135.753,790.742L1168.473,790.742L1152.408,744.671L1151.964,744.671L1135.753,790.742M1142.361,726.222L1162.324,726.222L1203.594,833.362L1183.468,833.362L1173.406,804.998L1130.655,804.998L1120.608,833.362L1101.256,833.362L1142.361,726.222Z"/>
|
|
14
|
+
<path fill="#333232" d="M1315.962,818.07L1349.126,818.07C1354.832,818.07 1359.271,816.591 1362.412,813.631C1365.553,810.671 1367.13,806.495 1367.13,801.102C1367.13,795.906 1365.553,791.86 1362.412,788.933C1359.271,786.056 1354.832,784.593 1349.126,784.593L1315.962,784.593L1315.962,818.07M1315.962,771.078L1346.577,771.078C1351.182,771.078 1354.964,769.796 1357.906,767.197C1360.85,764.599 1362.33,760.949 1362.33,756.247C1362.33,750.953 1361.03,747.17 1358.432,744.902C1355.834,742.666 1351.872,741.548 1346.577,741.548L1315.962,741.548L1315.962,771.078M1297.218,726.222L1349.275,726.222C1359.19,726.222 1366.967,728.492 1372.622,732.981C1378.278,737.469 1381.107,744.08 1381.107,752.793C1381.107,758.089 1379.758,762.692 1377.111,766.59C1374.464,770.485 1370.683,773.477 1365.783,775.598L1365.783,775.912C1372.294,777.293 1377.259,780.418 1380.713,785.284C1384.166,790.118 1385.892,796.203 1385.892,803.502C1385.892,812.413 1382.62,819.616 1376.059,825.108C1369.514,830.616 1359.633,833.362 1346.429,833.362L1297.218,833.362L1297.218,726.222Z"/>
|
|
15
|
+
</g>
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#D6D6D6" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#5CB99B" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#5CB99B" stroke-width="2.250" stroke-linejoin="miter" d="M26.00 26.00H38.00V38.00H26.00ZM32.00 26.00V38.00M26.00 32.00H38.00"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#333232" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#007759" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#007759" stroke-width="2.250" stroke-linejoin="miter" d="M26.00 26.00H38.00V38.00H26.00ZM32.00 26.00V38.00M26.00 32.00H38.00"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#D6D6D6" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#96B069" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#96B069" stroke-width="2.250" stroke-linejoin="miter" d="M27.20 32.00A4.80 4.80 0 1 0 36.80 32.00A4.80 4.80 0 1 0 27.20 32.00Z"/></svg>
|
package/marks/u-cmms.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#333232" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#556E1C" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#556E1C" stroke-width="2.250" stroke-linejoin="miter" d="M27.20 32.00A4.80 4.80 0 1 0 36.80 32.00A4.80 4.80 0 1 0 27.20 32.00Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#D6D6D6" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#DB8E7A" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#DB8E7A" stroke-width="2.250" stroke-linejoin="miter" d="M26.00 32.00H38.00M32.00 26.00V38.00"/></svg>
|
package/marks/u-draw.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#333232" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#974936" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#974936" stroke-width="2.250" stroke-linejoin="miter" d="M26.00 32.00H38.00M32.00 26.00V38.00"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#D6D6D6" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#D49464" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#D49464" stroke-width="2.250" stroke-linejoin="miter" d="M33.80 26.00L29.00 32.60L35.00 31.40L30.20 38.00"/></svg>
|
package/marks/u-ems.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#333232" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#915115" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#915115" stroke-width="2.250" stroke-linejoin="miter" d="M33.80 26.00L29.00 32.60L35.00 31.40L30.20 38.00"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#D6D6D6" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#4DB4CC" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#4DB4CC" stroke-width="2.250" stroke-linejoin="miter" d="M27.80 26.00L37.40 32.00L27.80 38.00Z"/></svg>
|
package/marks/u-mes.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#333232" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#00728A" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#00728A" stroke-width="2.250" stroke-linejoin="miter" d="M27.80 26.00L37.40 32.00L27.80 38.00Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#D6D6D6" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#80A5E3" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#80A5E3" stroke-width="2.250" stroke-linejoin="miter" d="M26.00 27.20H38.00M26.00 32.00H38.00M26.00 36.80H38.00"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#333232" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#3C62A1" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#3C62A1" stroke-width="2.250" stroke-linejoin="miter" d="M26.00 27.20H38.00M26.00 32.00H38.00M26.00 36.80H38.00"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#D6D6D6" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#B395D7" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#B395D7" stroke-width="2.250" stroke-linejoin="miter" d="M32.00 26.00L38.00 32.00L32.00 38.00L26.00 32.00Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#333232" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#725195" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="none" stroke="#725195" stroke-width="2.250" stroke-linejoin="miter" d="M32.00 26.00L38.00 32.00L32.00 38.00L26.00 32.00Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#D6D6D6" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#C69E58" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="#C69E58" d="M28.70 32.00A3.30 3.30 0 1 0 35.30 32.00A3.30 3.30 0 1 0 28.70 32.00Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><path fill="#333232" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000ZM44.000 32.000L44.000 7.407A1.800 1.800 0 0 1 46.681 5.838A30.000 30.000 0 0 1 62.000 32.000Z"/><path fill="#845B00" d="M2.000 32.000A30.000 30.000 0 0 0 62.000 32.000L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/><path fill="#845B00" d="M28.70 32.00A3.30 3.30 0 1 0 35.30 32.00A3.30 3.30 0 1 0 28.70 32.00Z"/></svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uplatform/brand",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "U-Platform affiliation kit — product list, marks, the <uplatform-affiliation> and <u-mark> elements, mark renders and patterns.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
7
|
+
"homepage": "https://u-platform.kr",
|
|
8
|
+
"publishConfig": { "access": "public" },
|
|
9
|
+
"exports": {
|
|
10
|
+
".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
|
|
11
|
+
"./products": { "types": "./dist/products.d.ts", "default": "./dist/products.js" },
|
|
12
|
+
"./products.json": "./dist/generated/products.json",
|
|
13
|
+
"./marks/*": "./marks/*",
|
|
14
|
+
"./patterns/*": "./patterns/*",
|
|
15
|
+
"./media/*": "./media/*"
|
|
16
|
+
},
|
|
17
|
+
"files": ["dist", "marks", "patterns", "media", "README.md", "LICENSE"],
|
|
18
|
+
"sideEffects": ["./dist/index.js", "./dist/affiliation.js", "./dist/mark.js"],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"sync": "node scripts/sync-kit.mjs",
|
|
21
|
+
"build": "tsc -p tsconfig.build.json && node -e \"const f=require('node:fs');for(const n of ['products.json','geometry.json'])f.cpSync('src/generated/'+n,'dist/generated/'+n)\"",
|
|
22
|
+
"prepack": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": { "jsdom": "^29.1.1", "typescript": "^7.0.2" }
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><g transform="translate(14 14) scale(0.5625)"><path fill="none" stroke="#000" stroke-width="2.4" d="M20.000 32.000L20.000 7.407A1.800 1.800 0 0 0 17.319 5.838A30.000 30.000 0 0 0 2.000 32.000A30.000 30.000 0 0 0 62.000 32.000A30.000 30.000 0 0 0 46.681 5.838A1.800 1.800 0 0 0 44.000 7.407L44.000 32.000A12.000 12.000 0 0 1 20.000 32.000Z"/></g></svg>
|