watermark-js-nine 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Your Name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # Watermark Component
2
+
3
+ 一个功能强大的网页水印组件,支持文字和图片水印,支持全图平铺或单个水印,支持旋转、透明度等多种配置。
4
+
5
+ A powerful web watermark component that supports text and image watermarks, full-screen tiling or single watermark, rotation, opacity, and various other configurations.
6
+
7
+ ## 特性 Features
8
+
9
+ - 📝 **文字水印 / Text Watermark**: 支持自定义文本、字体、颜色、大小 / Custom text, font, color, size
10
+ - 🖼️ **图片水印 / Image Watermark**: 支持自定义图片、大小、透明度 / Custom image, size, opacity
11
+ - 🔄 **灵活布局 / Flexible Layout**: 支持全图平铺或单个定位(九宫格) / Full-screen tiling or single positioning (9-grid)
12
+ - 📐 **精确控制 / Precise Control**: 支持旋转角度、偏移量、间距(毫米单位) / Rotation angle, offset, spacing (in mm)
13
+ - 🖨️ **打印支持 / Print Support**: 针对打印场景的优化 / Optimization for printing scenarios
14
+ - 📦 **TypeScript**: 完整的类型定义 / Complete type definitions
15
+
16
+ ## 安装 Installation
17
+
18
+ ```bash
19
+ npm install watermark-js-nine
20
+ ```
21
+
22
+ 或者使用 yarn / Or use yarn:
23
+
24
+ ```bash
25
+ yarn add watermark-js-nine
26
+ ```
27
+
28
+ ## 使用方法 Usage
29
+
30
+ ### 引入 Import
31
+
32
+ ```typescript
33
+ import NewWatermark, { WatermarkConfig } from 'watermark-js-nine';
34
+ ```
35
+
36
+ ### 基本使用 Basic Usage
37
+
38
+ ```typescript
39
+ // 配置水印 / Configure watermark
40
+ const config: WatermarkConfig = {
41
+ type: "text",
42
+ tilling: true, // 平铺 / Tiling
43
+ value: "机密文件\nCONFIDENTIAL",
44
+ font: "20pt Arial",
45
+ fillStyle: "rgba(200, 200, 200, 0.5)",
46
+ rotate: -45,
47
+ horizontal: 20, // mm
48
+ vertical: 20 // mm
49
+ };
50
+
51
+ // 初始化 / Initialize
52
+ // 参数1: 目标元素ID / Target Element ID
53
+ // 参数2: 配置对象或数组 / Configuration object or array
54
+ const watermark = new NewWatermark("target-element-id", config);
55
+ watermark.init();
56
+ ```
57
+
58
+ ### 混合水印 Mixed Watermarks
59
+
60
+ 支持传入配置数组来叠加多个水印。
61
+
62
+ Supports passing a configuration array to overlay multiple watermarks.
63
+
64
+ ```typescript
65
+ const configs: WatermarkConfig[] = [
66
+ {
67
+ type: "text",
68
+ tilling: true,
69
+ value: "内部资料",
70
+ rotate: -45,
71
+ fillStyle: "rgba(0,0,0,0.1)"
72
+ },
73
+ {
74
+ type: "image",
75
+ tilling: false,
76
+ place: "topRight",
77
+ image: {
78
+ data: "base64-string...",
79
+ size: [20, 20] // mm
80
+ }
81
+ }
82
+ ];
83
+
84
+ const wm = new NewWatermark("app", configs);
85
+ wm.init();
86
+ ```
87
+
88
+ ## 配置选项 Configuration (WatermarkConfig)
89
+
90
+ | 属性 Property | 类型 Type | 说明 Description | 默认值 Default |
91
+ |--------------|-----------|------------------|---------------|
92
+ | `type` | `"text" \| "image"` | 水印类型 / Watermark type | `"text"` |
93
+ | `tilling` | `boolean` | 是否平铺 / Whether to tile | `true` |
94
+ | `rotate` | `number` | 旋转角度 / Rotation angle | `0` |
95
+ | `offset` | `[number, number]` | 偏移量 [x, y] (mm) / Offset | `[0, 0]` |
96
+ | `horizontal` | `number` | 横向间距 (mm) / Horizontal spacing | `0` |
97
+ | `vertical` | `number` | 纵向间距 (mm) / Vertical spacing | `0` |
98
+ | `place` | `PlaceType` | 单个水印位置 / Single watermark position | `"middleCenter"` |
99
+
100
+ ### 文字水印配置 Text Configuration
101
+
102
+ | 属性 Property | 类型 Type | 说明 Description |
103
+ |--------------|-----------|------------------|
104
+ | `value` | `string` | 水印文本(支持 `\n` 换行) / Watermark text |
105
+ | `font` | `string` | 字体样式 (e.g. "20pt SimSun") / Font style |
106
+ | `fillStyle` | `string` | 填充颜色 / Fill color |
107
+
108
+ ### 图片水印配置 Image Configuration (`image` object)
109
+
110
+ | 属性 Property | 类型 Type | 说明 Description |
111
+ |--------------|-----------|------------------|
112
+ | `type` | `string` | 图片类型 (png/jpg) / Image type |
113
+ | `data` | `string` | 图片 Base64 数据 / Image Base64 data |
114
+ | `size` | `[number, number]` | 图片大小 [width, height] (mm) / Image size |
115
+ | `opacity` | `number` | 不透明度 (0-100) / Opacity |
116
+
117
+ ### 位置类型 PlaceType
118
+
119
+ 单个水印支持以下位置:
120
+ Supported positions for single watermark:
121
+
122
+ - `topLeft`, `topCenter`, `topRight`
123
+ - `middleLeft`, `middleCenter`, `middleRight`
124
+ - `bottomLeft`, `bottomCenter`, `bottomRight`
125
+
126
+ ## API
127
+
128
+ ### `constructor(elementId: string, config: WatermarkConfig | WatermarkConfig[], isPrint?: boolean, zoom?: number)`
129
+
130
+ - `elementId`: 目标 DOM 元素的 ID。
131
+ - `config`: 水印配置对象或数组。
132
+ - `isPrint`: 是否为打印模式(影响 DPI 计算)。
133
+ - `zoom`: 缩放比例。
134
+
135
+ ### `init(): Promise<void>`
136
+
137
+ 初始化并渲染水印。
138
+
139
+ Initialize and render the watermark.
140
+
141
+ ### `destroy(): void`
142
+
143
+ 移除水印。
144
+
145
+ Remove the watermark.
146
+
147
+ ## 许可证 License
148
+
149
+ MIT
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Options for configuring the SvgDraggableComponent
3
+ */
4
+ export interface SvgDraggableComponentOptions {
5
+ /** Width of the SVG canvas (default: 800) */
6
+ width?: number;
7
+ /** Height of the SVG canvas (default: 600) */
8
+ height?: number;
9
+ /** X position of the rectangle (default: 10) */
10
+ rectX?: number;
11
+ /** Y position of the rectangle (default: 10) */
12
+ rectY?: number;
13
+ /** Width of the rectangle (default: 200) */
14
+ rectWidth?: number;
15
+ /** Height of the rectangle (default: 100) */
16
+ rectHeight?: number;
17
+ /** Fill color of the rectangle (default: 'yellow') */
18
+ rectFill?: string;
19
+ /** Stroke color of the rectangle (default: 'black') */
20
+ rectStroke?: string;
21
+ /** X position of the component group (default: 100) */
22
+ compX?: number;
23
+ /** Y position of the component group (default: 100) */
24
+ compY?: number;
25
+ /** Whether to show the border (default: true) */
26
+ showBorder?: boolean;
27
+ }
28
+
29
+ /**
30
+ * A lightweight SVG component with drag and resize functionality
31
+ */
32
+ export default class SvgDraggableComponent {
33
+ /**
34
+ * Create a new SvgDraggableComponent instance
35
+ * @param options - Configuration options
36
+ */
37
+ constructor(options?: SvgDraggableComponentOptions);
38
+
39
+ /**
40
+ * Mount the component to a container element
41
+ * @param container - DOM element or CSS selector string
42
+ * @throws Error if container is not found
43
+ */
44
+ mount(container: HTMLElement | string): void;
45
+
46
+ /**
47
+ * Destroy the component and cleanup event listeners
48
+ */
49
+ destroy(): void;
50
+ }
package/dist/index.js ADDED
@@ -0,0 +1,279 @@
1
+ /**
2
+ * SvgDraggableComponent - A lightweight SVG component with drag and resize functionality
3
+ */
4
+ class SvgDraggableComponent {
5
+ constructor(options = {}) {
6
+ this.options = {
7
+ width: options.width || 800,
8
+ height: options.height || 600,
9
+ rectX: options.rectX || 10,
10
+ rectY: options.rectY || 10,
11
+ rectWidth: options.rectWidth || 200,
12
+ rectHeight: options.rectHeight || 100,
13
+ rectFill: options.rectFill || 'yellow',
14
+ rectStroke: options.rectStroke || 'black',
15
+ compX: options.compX || 100,
16
+ compY: options.compY || 100,
17
+ showBorder: options.showBorder !== undefined ? options.showBorder : true
18
+ };
19
+
20
+ this.elements = {};
21
+ this.state = {
22
+ startX: 0,
23
+ startY: 0,
24
+ oldX: 0,
25
+ oldY: 0,
26
+ oldW: 0,
27
+ oldH: 0,
28
+ pressed: false,
29
+ task: 0
30
+ };
31
+
32
+ this.container = null;
33
+ }
34
+
35
+ /**
36
+ * Create SVG elements
37
+ */
38
+ createSvg() {
39
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
40
+ svg.setAttribute('width', this.options.width);
41
+ svg.setAttribute('height', this.options.height);
42
+
43
+ if (this.options.showBorder) {
44
+ svg.style.border = '1px solid red';
45
+ }
46
+
47
+ // Create component group
48
+ const comp = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
49
+ comp.setAttribute('x', this.options.compX);
50
+ comp.setAttribute('y', this.options.compY);
51
+ comp.id = 'comp';
52
+
53
+ // Create rectangle
54
+ const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
55
+ rect.setAttribute('x', this.options.rectX);
56
+ rect.setAttribute('y', this.options.rectY);
57
+ rect.setAttribute('width', this.options.rectWidth);
58
+ rect.setAttribute('height', this.options.rectHeight);
59
+ rect.setAttribute('stroke', this.options.rectStroke);
60
+ rect.setAttribute('fill', this.options.rectFill);
61
+ rect.id = 'rect';
62
+
63
+ // Create corner circles
64
+ const clt = this.createCorner('clt', this.options.rectX, this.options.rectY);
65
+ const crt = this.createCorner('crt', this.options.rectX + this.options.rectWidth, this.options.rectY);
66
+ const clb = this.createCorner('clb', this.options.rectX, this.options.rectY + this.options.rectHeight);
67
+ const crb = this.createCorner('crb', this.options.rectX + this.options.rectWidth, this.options.rectY + this.options.rectHeight);
68
+
69
+ // Append elements
70
+ comp.appendChild(rect);
71
+ comp.appendChild(clt);
72
+ comp.appendChild(crt);
73
+ comp.appendChild(clb);
74
+ comp.appendChild(crb);
75
+ svg.appendChild(comp);
76
+
77
+ // Store references
78
+ this.elements = {
79
+ svg,
80
+ comp,
81
+ rect,
82
+ clt,
83
+ crt,
84
+ clb,
85
+ crb
86
+ };
87
+
88
+ return svg;
89
+ }
90
+
91
+ /**
92
+ * Create a corner circle
93
+ */
94
+ createCorner(id, cx, cy) {
95
+ const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
96
+ circle.setAttribute('id', id);
97
+ circle.setAttribute('cx', cx);
98
+ circle.setAttribute('cy', cy);
99
+ circle.setAttribute('r', 10);
100
+ circle.setAttribute('stroke', 'none');
101
+ circle.setAttribute('fill', 'red');
102
+ circle.setAttribute('fill-opacity', 0.5);
103
+ return circle;
104
+ }
105
+
106
+ /**
107
+ * Setup drag functionality for the rectangle
108
+ */
109
+ setupRectDrag() {
110
+ const { rect, comp } = this.elements;
111
+
112
+ const handleMouseDown = (e) => {
113
+ this.state.pressed = true;
114
+ this.state.startX = e.offsetX;
115
+ this.state.startY = e.offsetY;
116
+ this.state.oldX = Number.parseFloat(comp.getAttribute('x'));
117
+ this.state.oldY = Number.parseFloat(comp.getAttribute('y'));
118
+ };
119
+
120
+ const handleMouseMove = (e) => {
121
+ if (!this.state.pressed) return;
122
+
123
+ const dx = e.offsetX - this.state.startX;
124
+ const dy = e.offsetY - this.state.startY;
125
+
126
+ if (this.state.task !== 0) {
127
+ cancelAnimationFrame(this.state.task);
128
+ }
129
+
130
+ this.state.task = requestAnimationFrame(() => {
131
+ comp.setAttribute('x', this.state.oldX + dx);
132
+ comp.setAttribute('y', this.state.oldY + dy);
133
+ });
134
+ };
135
+
136
+ const handleMouseUp = () => {
137
+ this.state.pressed = false;
138
+ };
139
+
140
+ const handleMouseOver = () => {
141
+ rect.style.cursor = 'move';
142
+ };
143
+
144
+ rect.addEventListener('mousedown', handleMouseDown);
145
+ rect.addEventListener('mousemove', handleMouseMove);
146
+ rect.addEventListener('mouseup', handleMouseUp);
147
+ rect.addEventListener('mouseover', handleMouseOver);
148
+
149
+ // Store handlers for cleanup
150
+ this.handlers = this.handlers || {};
151
+ this.handlers.rect = {
152
+ mousedown: handleMouseDown,
153
+ mousemove: handleMouseMove,
154
+ mouseup: handleMouseUp,
155
+ mouseover: handleMouseOver
156
+ };
157
+ }
158
+
159
+ /**
160
+ * Setup resize functionality for the corner
161
+ */
162
+ setupCornerResize() {
163
+ const { crb } = this.elements;
164
+
165
+ const handleMouseDown = (e) => {
166
+ this.state.pressed = true;
167
+ this.state.startX = e.offsetX;
168
+ this.state.startY = e.offsetY;
169
+ this.state.oldX = Number.parseFloat(crb.getAttribute('cx'));
170
+ this.state.oldY = Number.parseFloat(crb.getAttribute('cy'));
171
+ };
172
+
173
+ const handleMouseMove = (e) => {
174
+ if (!this.state.pressed) return;
175
+
176
+ const dx = e.offsetX - this.state.startX;
177
+ const dy = e.offsetY - this.state.startY;
178
+
179
+ if (this.state.task !== 0) {
180
+ cancelAnimationFrame(this.state.task);
181
+ }
182
+
183
+ crb.setAttribute('cx', this.state.oldX + dx);
184
+ crb.setAttribute('cy', this.state.oldY + dy);
185
+ };
186
+
187
+ const handleMouseUp = () => {
188
+ this.state.pressed = false;
189
+ };
190
+
191
+ const handleMouseOver = () => {
192
+ crb.style.cursor = 'nwse-resize';
193
+ };
194
+
195
+ const handleMouseLeave = () => {
196
+ // Handle mouse leave if needed
197
+ };
198
+
199
+ crb.addEventListener('mousedown', handleMouseDown);
200
+ crb.addEventListener('mousemove', handleMouseMove);
201
+ crb.addEventListener('mouseup', handleMouseUp);
202
+ crb.addEventListener('mouseover', handleMouseOver);
203
+ crb.addEventListener('mouseleave', handleMouseLeave);
204
+
205
+ // Store handlers for cleanup
206
+ this.handlers = this.handlers || {};
207
+ this.handlers.crb = {
208
+ mousedown: handleMouseDown,
209
+ mousemove: handleMouseMove,
210
+ mouseup: handleMouseUp,
211
+ mouseover: handleMouseOver,
212
+ mouseleave: handleMouseLeave
213
+ };
214
+ }
215
+
216
+ /**
217
+ * Mount the component to a container
218
+ * @param {HTMLElement|string} container - DOM element or selector string
219
+ */
220
+ mount(container) {
221
+ if (typeof container === 'string') {
222
+ this.container = document.querySelector(container);
223
+ } else {
224
+ this.container = container;
225
+ }
226
+
227
+ if (!this.container) {
228
+ throw new Error('Container not found');
229
+ }
230
+
231
+ const svg = this.createSvg();
232
+ this.container.appendChild(svg);
233
+
234
+ this.setupRectDrag();
235
+ this.setupCornerResize();
236
+ }
237
+
238
+ /**
239
+ * Destroy the component and cleanup
240
+ */
241
+ destroy() {
242
+ if (this.elements.svg && this.container) {
243
+ this.container.removeChild(this.elements.svg);
244
+ }
245
+
246
+ // Cleanup event listeners
247
+ if (this.handlers) {
248
+ Object.keys(this.handlers).forEach(elementKey => {
249
+ const element = this.elements[elementKey];
250
+ const handlers = this.handlers[elementKey];
251
+ Object.keys(handlers).forEach(eventName => {
252
+ element.removeEventListener(eventName, handlers[eventName]);
253
+ });
254
+ });
255
+ }
256
+
257
+ this.elements = {};
258
+ this.handlers = {};
259
+ this.container = null;
260
+ }
261
+ }
262
+
263
+ // Export for different module systems
264
+ if (typeof module !== 'undefined' && module.exports) {
265
+ module.exports = SvgDraggableComponent;
266
+ }
267
+
268
+ if (typeof define === 'function' && define.amd) {
269
+ define([], function() {
270
+ return SvgDraggableComponent;
271
+ });
272
+ }
273
+
274
+ if (typeof window !== 'undefined') {
275
+ window.SvgDraggableComponent = SvgDraggableComponent;
276
+ }
277
+
278
+ export default SvgDraggableComponent;
279
+
@@ -0,0 +1,95 @@
1
+ export interface WatermarkConfig {
2
+ type: "text" | "image";
3
+ tilling: boolean;
4
+ value?: string;
5
+ font?: string;
6
+ fillStyle?: string;
7
+ image?: {
8
+ type?: string;
9
+ data?: string;
10
+ size?: [number, number];
11
+ opacity?: number;
12
+ };
13
+ rotate?: number;
14
+ offset?: [number, number];
15
+ horizontal?: number;
16
+ vertical?: number;
17
+ place?: PlaceType;
18
+ svgContainer?: SVGSVGElement;
19
+ }
20
+ type PlaceType = "topLeft" | "topCenter" | "topRight" | "middleLeft" | "middleCenter" | "middleRight" | "bottomLeft" | "bottomCenter" | "bottomRight";
21
+ export default class NewWatermark {
22
+ private elementId;
23
+ private config;
24
+ private element;
25
+ private isImageElement;
26
+ private isPrint;
27
+ private observer;
28
+ /**
29
+ * 创建水印实例
30
+ * @param elementId 目标元素的id
31
+ * @param config 水印配置
32
+ * @param isPrint 是否为打印模式
33
+ * @param zoom 缩放比例
34
+ */
35
+ constructor(elementId: string, config: WatermarkConfig | Array<WatermarkConfig>, isPrint?: boolean, zoom?: number);
36
+ private getRandomPlace;
37
+ /**
38
+ * 合并默认配置
39
+ */
40
+ private mergeDefaultConfig;
41
+ /**
42
+ * 初始化并渲染水印
43
+ */
44
+ init(): Promise<void>;
45
+ private waterListener;
46
+ /**
47
+ * 创建SVG容器
48
+ */
49
+ private createSvgContainer;
50
+ /**
51
+ * 包装图片元素(为图片创建一个容器)
52
+ */
53
+ private wrapImageElement;
54
+ /**
55
+ * 渲染平铺水印(全图水印)
56
+ */
57
+ private renderTillingWatermark;
58
+ /**
59
+ * 创建平铺图片水印
60
+ */
61
+ private createTillingImageWatermark;
62
+ /**
63
+ * 创建平铺文字水印
64
+ */
65
+ private createTillingTextWatermark;
66
+ /**
67
+ * 渲染单个水印
68
+ */
69
+ private renderSingleWatermark;
70
+ /**
71
+ * 创建单个图片水印
72
+ */
73
+ private createSingleImageWatermark;
74
+ /**
75
+ * 单个图片计算位置 始终沿着九宫格不超出范围定位和旋转
76
+ */
77
+ private calculateImagePosition;
78
+ /**
79
+ * 创建单个文字水印
80
+ */
81
+ private createSingleTextWatermark;
82
+ /**
83
+ * 单个文字计算位置
84
+ */
85
+ private calculateTextPosition;
86
+ private renderImageWatermark;
87
+ private imageWatermark;
88
+ private translateXY;
89
+ /**
90
+ * 移除水印
91
+ */
92
+ destroy(): void;
93
+ }
94
+ export {};
95
+ //# sourceMappingURL=waterMark.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waterMark.d.ts","sourceRoot":"","sources":["../src/waterMark.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IAEjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IAEF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,YAAY,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED,KAAK,SAAS,GACV,SAAS,GACT,WAAW,GACX,UAAU,GACV,YAAY,GACZ,cAAc,GACd,aAAa,GACb,YAAY,GACZ,cAAc,GACd,aAAa,CAAC;AAmMlB,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAA2C;IACzD,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAwB;IAExC;;;;;;OAMG;gBAED,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC,EAChD,OAAO,UAAQ,EACf,IAAI,SAAI;IAQV,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4B1B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC3B,OAAO,CAAC,aAAa;IAerB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgC1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA6BxB;;OAEG;YACW,sBAAsB;IAuCpC;;OAEG;YACW,2BAA2B;IA6CzC;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAkClC;;OAEG;YACW,qBAAqB;IAiBnC;;OAEG;YACW,0BAA0B;IAiCxC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA4G9B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA+BjC;;OAEG;IACH,OAAO,CAAC,qBAAqB;YAsIf,oBAAoB;YAUpB,cAAc;IAiL5B,OAAO,CAAC,WAAW;IA0DnB;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}