vite-plugin-taro-runtime 0.6.7
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 +174 -0
- package/README.md +45 -0
- package/dist/bom/URL.d.ts +53 -0
- package/dist/bom/URL.js +222 -0
- package/dist/bom/URL.js.map +1 -0
- package/dist/bom/URLSearchParams.d.ts +3 -0
- package/dist/bom/URLSearchParams.js +131 -0
- package/dist/bom/URLSearchParams.js.map +1 -0
- package/dist/bom/document.d.ts +5 -0
- package/dist/bom/document.js +185 -0
- package/dist/bom/document.js.map +1 -0
- package/dist/bom/getComputedStyle.d.ts +8 -0
- package/dist/bom/getComputedStyle.js +9 -0
- package/dist/bom/getComputedStyle.js.map +1 -0
- package/dist/bom/history.d.ts +34 -0
- package/dist/bom/history.js +121 -0
- package/dist/bom/history.js.map +1 -0
- package/dist/bom/location.d.ts +40 -0
- package/dist/bom/location.js +240 -0
- package/dist/bom/location.js.map +1 -0
- package/dist/bom/navigator.d.ts +3 -0
- package/dist/bom/navigator.js +24 -0
- package/dist/bom/navigator.js.map +1 -0
- package/dist/bom/raf.d.ts +5 -0
- package/dist/bom/raf.js +33 -0
- package/dist/bom/raf.js.map +1 -0
- package/dist/bom/window.d.ts +28 -0
- package/dist/bom/window.js +93 -0
- package/dist/bom/window.js.map +1 -0
- package/dist/constants/index.d.ts +59 -0
- package/dist/constants/index.js +62 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/current.d.ts +22 -0
- package/dist/current.js +9 -0
- package/dist/current.js.map +1 -0
- package/dist/dom/anchor-element.js +54 -0
- package/dist/dom/anchor-element.js.map +1 -0
- package/dist/dom/class-list.d.ts +19 -0
- package/dist/dom/class-list.js +92 -0
- package/dist/dom/class-list.js.map +1 -0
- package/dist/dom/document.d.ts +24 -0
- package/dist/dom/document.js +80 -0
- package/dist/dom/document.js.map +1 -0
- package/dist/dom/element.d.ts +43 -0
- package/dist/dom/element.js +317 -0
- package/dist/dom/element.js.map +1 -0
- package/dist/dom/event-source.d.ts +9 -0
- package/dist/dom/event-source.js +17 -0
- package/dist/dom/event-source.js.map +1 -0
- package/dist/dom/event-target.d.ts +11 -0
- package/dist/dom/event-target.js +83 -0
- package/dist/dom/event-target.js.map +1 -0
- package/dist/dom/event.d.ts +27 -0
- package/dist/dom/event.js +160 -0
- package/dist/dom/event.js.map +1 -0
- package/dist/dom/form.d.ts +12 -0
- package/dist/dom/form.js +38 -0
- package/dist/dom/form.js.map +1 -0
- package/dist/dom/node.d.ts +79 -0
- package/dist/dom/node.js +301 -0
- package/dist/dom/node.js.map +1 -0
- package/dist/dom/node_types.d.ts +12 -0
- package/dist/dom/root.d.ts +21 -0
- package/dist/dom/root.js +186 -0
- package/dist/dom/root.js.map +1 -0
- package/dist/dom/style.d.ts +17 -0
- package/dist/dom/style.js +168 -0
- package/dist/dom/style.js.map +1 -0
- package/dist/dom/style_properties.js +187 -0
- package/dist/dom/style_properties.js.map +1 -0
- package/dist/dom/svg.d.ts +6 -0
- package/dist/dom/svg.js +8 -0
- package/dist/dom/svg.js.map +1 -0
- package/dist/dom/text.d.ts +17 -0
- package/dist/dom/text.js +41 -0
- package/dist/dom/text.js.map +1 -0
- package/dist/dom/transfer.js +15 -0
- package/dist/dom/transfer.js.map +1 -0
- package/dist/dom/tree.js +38 -0
- package/dist/dom/tree.js.map +1 -0
- package/dist/dom-external/element.js +36 -0
- package/dist/dom-external/element.js.map +1 -0
- package/dist/dom-external/index.js +39 -0
- package/dist/dom-external/index.js.map +1 -0
- package/dist/dom-external/inner-html/html.d.ts +5 -0
- package/dist/dom-external/inner-html/html.js +35 -0
- package/dist/dom-external/inner-html/html.js.map +1 -0
- package/dist/dom-external/inner-html/parser.d.ts +20 -0
- package/dist/dom-external/inner-html/parser.js +216 -0
- package/dist/dom-external/inner-html/parser.js.map +1 -0
- package/dist/dom-external/inner-html/scanner.js +304 -0
- package/dist/dom-external/inner-html/scanner.js.map +1 -0
- package/dist/dom-external/inner-html/style.js +235 -0
- package/dist/dom-external/inner-html/style.js.map +1 -0
- package/dist/dom-external/inner-html/tags.js +26 -0
- package/dist/dom-external/inner-html/tags.js.map +1 -0
- package/dist/dom-external/inner-html/utils.js +12 -0
- package/dist/dom-external/inner-html/utils.js.map +1 -0
- package/dist/dom-external/mutation-observer/implements.d.ts +55 -0
- package/dist/dom-external/mutation-observer/implements.js +108 -0
- package/dist/dom-external/mutation-observer/implements.js.map +1 -0
- package/dist/dom-external/mutation-observer/index.d.ts +15 -0
- package/dist/dom-external/mutation-observer/index.js +35 -0
- package/dist/dom-external/mutation-observer/index.js.map +1 -0
- package/dist/dom-external/mutation-observer/record.d.ts +28 -0
- package/dist/dom-external/node.js +75 -0
- package/dist/dom-external/node.js.map +1 -0
- package/dist/dsl/common.d.ts +17 -0
- package/dist/dsl/common.js +376 -0
- package/dist/dsl/common.js.map +1 -0
- package/dist/dsl/instance.d.ts +97 -0
- package/dist/emitter/emitter.d.ts +8 -0
- package/dist/emitter/emitter.js +7 -0
- package/dist/emitter/emitter.js.map +1 -0
- package/dist/env.d.ts +9 -0
- package/dist/env.js +9 -0
- package/dist/env.js.map +1 -0
- package/dist/hydrate.d.ts +13 -0
- package/dist/hydrate.js +104 -0
- package/dist/hydrate.js.map +1 -0
- package/dist/index.cjs.d.ts +921 -0
- package/dist/index.cjs.js +5401 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/interface/animate.d.ts +83 -0
- package/dist/interface/element.d.ts +6 -0
- package/dist/interface/event-target.d.ts +13 -0
- package/dist/interface/event.d.ts +16 -0
- package/dist/interface/hydrate.d.ts +33 -0
- package/dist/interface/node.d.ts +10 -0
- package/dist/interface/options.d.ts +19 -0
- package/dist/interface/utils.d.ts +4 -0
- package/dist/next-tick.d.ts +5 -0
- package/dist/next-tick.js +47 -0
- package/dist/next-tick.js.map +1 -0
- package/dist/options.d.ts +5 -0
- package/dist/options.js +7 -0
- package/dist/options.js.map +1 -0
- package/dist/perf.d.ts +10 -0
- package/dist/perf.js +49 -0
- package/dist/perf.js.map +1 -0
- package/dist/polyfill/array.js +56 -0
- package/dist/polyfill/array.js.map +1 -0
- package/dist/polyfill/index.d.ts +3 -0
- package/dist/polyfill/index.js +34 -0
- package/dist/polyfill/index.js.map +1 -0
- package/dist/polyfill/intersection-observer.js +597 -0
- package/dist/polyfill/intersection-observer.js.map +1 -0
- package/dist/polyfill/object.js +102 -0
- package/dist/polyfill/object.js.map +1 -0
- package/dist/runtime.esm.d.ts +921 -0
- package/dist/runtime.esm.js +5274 -0
- package/dist/runtime.esm.js.map +1 -0
- package/dist/utils/cache.d.ts +14 -0
- package/dist/utils/cache.js +27 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/index.d.ts +26 -0
- package/dist/utils/index.js +99 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/lodash.d.ts +4 -0
- package/dist/utils/lodash.js +32 -0
- package/dist/utils/lodash.js.map +1 -0
- package/dist/utils/router.d.ts +9 -0
- package/dist/utils/router.js +24 -0
- package/dist/utils/router.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { isFunction } from '@tarojs/shared';
|
|
2
|
+
import { options } from '../../options.js';
|
|
3
|
+
import { Scanner } from './scanner.js';
|
|
4
|
+
import StyleTagParser from './style.js';
|
|
5
|
+
import { specialMiniElements, isMiniElements, isBlockElements, isInlineElements } from './tags.js';
|
|
6
|
+
import { unquote } from './utils.js';
|
|
7
|
+
|
|
8
|
+
const closingTagAncestorBreakers = {
|
|
9
|
+
li: ['ul', 'ol', 'menu'],
|
|
10
|
+
dt: ['dl'],
|
|
11
|
+
dd: ['dl'],
|
|
12
|
+
tbody: ['table'],
|
|
13
|
+
thead: ['table'],
|
|
14
|
+
tfoot: ['table'],
|
|
15
|
+
tr: ['table'],
|
|
16
|
+
td: ['table']
|
|
17
|
+
};
|
|
18
|
+
function hasTerminalParent(tagName, stack) {
|
|
19
|
+
const tagParents = closingTagAncestorBreakers[tagName];
|
|
20
|
+
if (tagParents) {
|
|
21
|
+
let currentIndex = stack.length - 1;
|
|
22
|
+
while (currentIndex >= 0) {
|
|
23
|
+
const parentTagName = stack[currentIndex].tagName;
|
|
24
|
+
if (parentTagName === tagName) {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
if (tagParents && tagParents.includes(parentTagName)) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
currentIndex--;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
function getTagName(tag) {
|
|
36
|
+
if (options.html.renderHTMLTag) {
|
|
37
|
+
return tag;
|
|
38
|
+
}
|
|
39
|
+
if (specialMiniElements[tag]) {
|
|
40
|
+
return specialMiniElements[tag];
|
|
41
|
+
}
|
|
42
|
+
else if (isMiniElements(tag)) {
|
|
43
|
+
return tag;
|
|
44
|
+
}
|
|
45
|
+
else if (isBlockElements(tag)) {
|
|
46
|
+
return 'view';
|
|
47
|
+
}
|
|
48
|
+
else if (isInlineElements(tag)) {
|
|
49
|
+
return 'text';
|
|
50
|
+
}
|
|
51
|
+
return 'view';
|
|
52
|
+
}
|
|
53
|
+
function splitEqual(str) {
|
|
54
|
+
const sep = '=';
|
|
55
|
+
const idx = str.indexOf(sep);
|
|
56
|
+
if (idx === -1)
|
|
57
|
+
return [str];
|
|
58
|
+
const key = str.slice(0, idx).trim();
|
|
59
|
+
const value = str.slice(idx + sep.length).trim();
|
|
60
|
+
return [key, value];
|
|
61
|
+
}
|
|
62
|
+
function format(children, document, styleOptions, parent) {
|
|
63
|
+
return children
|
|
64
|
+
.filter(child => {
|
|
65
|
+
// 过滤注释和空文本节点
|
|
66
|
+
if (child.type === 'comment') {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
else if (child.type === 'text') {
|
|
70
|
+
return child.content !== '';
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
})
|
|
74
|
+
.map((child) => {
|
|
75
|
+
// 文本节点
|
|
76
|
+
if (child.type === 'text') {
|
|
77
|
+
let text = document.createTextNode(child.content);
|
|
78
|
+
if (isFunction(options.html.transformText)) {
|
|
79
|
+
text = options.html.transformText(text, child);
|
|
80
|
+
}
|
|
81
|
+
parent === null || parent === void 0 ? void 0 : parent.appendChild(text);
|
|
82
|
+
return text;
|
|
83
|
+
}
|
|
84
|
+
const el = document.createElement(getTagName(child.tagName));
|
|
85
|
+
el.h5tagName = child.tagName;
|
|
86
|
+
parent === null || parent === void 0 ? void 0 : parent.appendChild(el);
|
|
87
|
+
if (!options.html.renderHTMLTag) {
|
|
88
|
+
el.className = `h5-${child.tagName}`;
|
|
89
|
+
}
|
|
90
|
+
for (let i = 0; i < child.attributes.length; i++) {
|
|
91
|
+
const attr = child.attributes[i];
|
|
92
|
+
const [key, value] = splitEqual(attr);
|
|
93
|
+
if (key === 'class') {
|
|
94
|
+
el.className += ' ' + unquote(value);
|
|
95
|
+
}
|
|
96
|
+
else if (key[0] === 'o' && key[1] === 'n') {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
el.setAttribute(key, value == null ? true : unquote(value));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const { styleTagParser, descendantList } = styleOptions;
|
|
104
|
+
const list = descendantList.slice();
|
|
105
|
+
const style = styleTagParser.matchStyle(child.tagName, el, list);
|
|
106
|
+
el.setAttribute('style', style + el.style.cssText);
|
|
107
|
+
// console.log('style, ', style)
|
|
108
|
+
format(child.children, document, {
|
|
109
|
+
styleTagParser,
|
|
110
|
+
descendantList: list
|
|
111
|
+
}, el);
|
|
112
|
+
if (isFunction(options.html.transformElement)) {
|
|
113
|
+
return options.html.transformElement(el, child);
|
|
114
|
+
}
|
|
115
|
+
return el;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
function parser(html, document) {
|
|
119
|
+
const styleTagParser = new StyleTagParser();
|
|
120
|
+
html = styleTagParser.extractStyle(html);
|
|
121
|
+
const tokens = new Scanner(html).scan();
|
|
122
|
+
const root = { tagName: '', children: [], type: 'element', attributes: [] };
|
|
123
|
+
const state = { tokens, cursor: 0, stack: [root] };
|
|
124
|
+
parse(state);
|
|
125
|
+
return format(root.children, document, {
|
|
126
|
+
styleTagParser,
|
|
127
|
+
descendantList: Array(styleTagParser.styles.length).fill(0)
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function parse(state) {
|
|
131
|
+
const { tokens, stack } = state;
|
|
132
|
+
let { cursor } = state;
|
|
133
|
+
const len = tokens.length;
|
|
134
|
+
let nodes = stack[stack.length - 1].children;
|
|
135
|
+
while (cursor < len) {
|
|
136
|
+
const token = tokens[cursor];
|
|
137
|
+
if (token.type !== 'tag-start') {
|
|
138
|
+
// comment or text
|
|
139
|
+
nodes.push(token);
|
|
140
|
+
cursor++;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const tagToken = tokens[++cursor];
|
|
144
|
+
cursor++;
|
|
145
|
+
const tagName = tagToken.content.toLowerCase();
|
|
146
|
+
if (token.close) {
|
|
147
|
+
let index = stack.length;
|
|
148
|
+
let shouldRewind = false;
|
|
149
|
+
while (--index > -1) {
|
|
150
|
+
if (stack[index].tagName === tagName) {
|
|
151
|
+
shouldRewind = true;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
while (cursor < len) {
|
|
156
|
+
const endToken = tokens[cursor];
|
|
157
|
+
if (endToken.type !== 'tag-end')
|
|
158
|
+
break;
|
|
159
|
+
cursor++;
|
|
160
|
+
}
|
|
161
|
+
if (shouldRewind) {
|
|
162
|
+
stack.splice(index);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const isClosingTag = options.html.closingElements.has(tagName);
|
|
170
|
+
let shouldRewindToAutoClose = isClosingTag;
|
|
171
|
+
if (shouldRewindToAutoClose) {
|
|
172
|
+
shouldRewindToAutoClose = !hasTerminalParent(tagName, stack);
|
|
173
|
+
}
|
|
174
|
+
if (shouldRewindToAutoClose) {
|
|
175
|
+
let currentIndex = stack.length - 1;
|
|
176
|
+
while (currentIndex > 0) {
|
|
177
|
+
if (tagName === stack[currentIndex].tagName) {
|
|
178
|
+
stack.splice(currentIndex);
|
|
179
|
+
const previousIndex = currentIndex - 1;
|
|
180
|
+
nodes = stack[previousIndex].children;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
currentIndex = currentIndex - 1;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const attributes = [];
|
|
187
|
+
let attrToken;
|
|
188
|
+
while (cursor < len) {
|
|
189
|
+
attrToken = tokens[cursor];
|
|
190
|
+
if (attrToken.type === 'tag-end')
|
|
191
|
+
break;
|
|
192
|
+
attributes.push(attrToken.content);
|
|
193
|
+
cursor++;
|
|
194
|
+
}
|
|
195
|
+
cursor++;
|
|
196
|
+
const children = [];
|
|
197
|
+
const element = {
|
|
198
|
+
type: 'element',
|
|
199
|
+
tagName: tagToken.content,
|
|
200
|
+
attributes,
|
|
201
|
+
children
|
|
202
|
+
};
|
|
203
|
+
nodes.push(element);
|
|
204
|
+
const hasChildren = !(attrToken.close || options.html.voidElements.has(tagName));
|
|
205
|
+
if (hasChildren) {
|
|
206
|
+
stack.push({ tagName, children });
|
|
207
|
+
const innerState = { tokens, cursor, stack };
|
|
208
|
+
parse(innerState);
|
|
209
|
+
cursor = innerState.cursor;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
state.cursor = cursor;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export { parser };
|
|
216
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sources":["../../../../src/dom-external/inner-html/parser.ts"],"sourcesContent":["import { isFunction } from '@tarojs/shared'\n\nimport { options } from '../../options'\nimport { Scanner, Token } from './scanner'\nimport StyleTagParser from './style'\nimport { isBlockElements, isInlineElements, isMiniElements, specialMiniElements } from './tags'\nimport { unquote } from './utils'\n\nimport type { TaroDocument } from '../../dom/document'\nimport type { TaroElement } from '../../dom/element'\n\ninterface State {\n tokens: Token[]\n cursor: number\n stack: Element[]\n}\n\nconst closingTagAncestorBreakers = {\n li: ['ul', 'ol', 'menu'],\n dt: ['dl'],\n dd: ['dl'],\n tbody: ['table'],\n thead: ['table'],\n tfoot: ['table'],\n tr: ['table'],\n td: ['table']\n}\n\ninterface Node {\n type: string\n}\n\ninterface Comment extends Node {\n type: 'comment'\n content: string\n}\n\nexport interface Text extends Node {\n type: 'text'\n content: string\n}\n\nexport interface Element extends Node {\n type: 'element'\n tagName: string\n children: ChildNode[]\n attributes: string[]\n}\n\nexport interface ParsedTaroElement extends TaroElement{\n h5tagName?: string\n}\n\ntype ChildNode = Comment | Text | Element\n\nfunction hasTerminalParent (tagName: string, stack: Element[]) {\n const tagParents: undefined | string[] = closingTagAncestorBreakers[tagName]\n if (tagParents) {\n let currentIndex = stack.length - 1\n while (currentIndex >= 0) {\n const parentTagName = stack[currentIndex].tagName\n if (parentTagName === tagName) {\n break\n }\n if (tagParents && tagParents.includes(parentTagName!)) {\n return true\n }\n currentIndex--\n }\n }\n return false\n}\n\nfunction getTagName (tag: string) {\n if (options.html!.renderHTMLTag) {\n return tag\n }\n\n if (specialMiniElements[tag]) {\n return specialMiniElements[tag]\n } else if (isMiniElements(tag)) {\n return tag\n } else if (isBlockElements(tag)) {\n return 'view'\n } else if (isInlineElements(tag)) {\n return 'text'\n }\n\n return 'view'\n}\n\nfunction splitEqual (str: string) {\n const sep = '='\n const idx = str.indexOf(sep)\n if (idx === -1) return [str]\n const key = str.slice(0, idx).trim()\n const value = str.slice(idx + sep.length).trim()\n return [key, value]\n}\n\nfunction format (\n children: ChildNode[],\n document: TaroDocument,\n styleOptions: {\n styleTagParser: StyleTagParser\n descendantList: number[]\n },\n parent?: TaroElement\n) {\n return children\n .filter(child => {\n // 过滤注释和空文本节点\n if (child.type === 'comment') {\n return false\n } else if (child.type === 'text') {\n return child.content !== ''\n }\n return true\n })\n .map((child: Text | Element) => {\n // 文本节点\n if (child.type === 'text') {\n let text = document.createTextNode(child.content)\n if (isFunction(options.html!.transformText)) {\n text = options.html!.transformText(text, child)\n }\n parent?.appendChild(text)\n return text\n }\n\n const el: ParsedTaroElement = document.createElement(getTagName(child.tagName))\n el.h5tagName = child.tagName\n\n parent?.appendChild(el)\n\n if (!options.html!.renderHTMLTag) {\n el.className = `h5-${child.tagName}`\n }\n\n for (let i = 0; i < child.attributes.length; i++) {\n const attr = child.attributes[i]\n const [key, value] = splitEqual(attr)\n if (key === 'class') {\n el.className += ' ' + unquote(value)\n } else if (key[0] === 'o' && key[1] === 'n') {\n continue\n } else {\n el.setAttribute(key, value == null ? true : unquote(value))\n }\n }\n\n const { styleTagParser, descendantList } = styleOptions\n const list = descendantList.slice()\n const style = styleTagParser.matchStyle(child.tagName, el, list)\n\n el.setAttribute('style', style + el.style.cssText)\n // console.log('style, ', style)\n\n format(child.children, document, {\n styleTagParser,\n descendantList: list\n }, el)\n\n if (isFunction(options.html!.transformElement)) {\n return options.html!.transformElement(el, child)\n }\n\n return el\n })\n}\n\nexport function parser (html: string, document: TaroDocument) {\n const styleTagParser = new StyleTagParser()\n html = styleTagParser.extractStyle(html)\n\n const tokens = new Scanner(html).scan()\n\n const root: Element = { tagName: '', children: [], type: 'element', attributes: [] }\n\n const state = { tokens, options, cursor: 0, stack: [root] }\n parse(state)\n\n return format(root.children, document, {\n styleTagParser,\n descendantList: Array(styleTagParser.styles.length).fill(0)\n })\n}\n\nfunction parse (state: State) {\n const { tokens, stack } = state\n let { cursor } = state\n\n const len = tokens.length\n\n let nodes = stack[stack.length - 1].children\n\n while (cursor < len) {\n const token = tokens[cursor]\n if (token.type !== 'tag-start') {\n // comment or text\n nodes.push(token as ChildNode)\n cursor++\n continue\n }\n\n const tagToken = tokens[++cursor]\n cursor++\n const tagName = tagToken.content!.toLowerCase()\n if (token.close) {\n let index = stack.length\n let shouldRewind = false\n while (--index > -1) {\n if (stack[index].tagName === tagName) {\n shouldRewind = true\n break\n }\n }\n while (cursor < len) {\n const endToken = tokens[cursor]\n if (endToken.type !== 'tag-end') break\n cursor++\n }\n if (shouldRewind) {\n stack.splice(index)\n break\n } else {\n continue\n }\n }\n\n const isClosingTag = options.html!.closingElements.has(tagName)\n let shouldRewindToAutoClose = isClosingTag\n if (shouldRewindToAutoClose) {\n shouldRewindToAutoClose = !hasTerminalParent(tagName, stack)\n }\n\n if (shouldRewindToAutoClose) {\n let currentIndex = stack.length - 1\n while (currentIndex > 0) {\n if (tagName === stack[currentIndex].tagName) {\n stack.splice(currentIndex)\n const previousIndex = currentIndex - 1\n nodes = stack[previousIndex].children\n break\n }\n currentIndex = currentIndex - 1\n }\n }\n\n const attributes: string[] = []\n let attrToken: Token\n while (cursor < len) {\n attrToken = tokens[cursor]\n if (attrToken.type === 'tag-end') break\n attributes.push(attrToken.content!)\n cursor++\n }\n\n cursor++\n const children: Element[] = []\n const element: Element = {\n type: 'element',\n tagName: tagToken.content!,\n attributes,\n children\n }\n nodes.push(element)\n\n const hasChildren = !(attrToken!.close || options.html!.voidElements.has(tagName))\n if (hasChildren) {\n stack.push({ tagName, children } as any)\n const innerState: State = { tokens, cursor, stack }\n parse(innerState)\n cursor = innerState.cursor\n }\n }\n\n state.cursor = cursor\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { options } from '../../options.js';
|
|
2
|
+
|
|
3
|
+
function initPosition() {
|
|
4
|
+
return {
|
|
5
|
+
index: 0,
|
|
6
|
+
column: 0,
|
|
7
|
+
line: 0
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function feedPosition(position, str, len) {
|
|
11
|
+
const start = position.index;
|
|
12
|
+
const end = position.index = start + len;
|
|
13
|
+
for (let i = start; i < end; i++) {
|
|
14
|
+
const char = str.charAt(i);
|
|
15
|
+
if (char === '\n') {
|
|
16
|
+
position.line++;
|
|
17
|
+
position.column = 0;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
position.column++;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function jumpPosition(position, str, end) {
|
|
25
|
+
const len = end - position.index;
|
|
26
|
+
return feedPosition(position, str, len);
|
|
27
|
+
}
|
|
28
|
+
function copyPosition(position) {
|
|
29
|
+
return {
|
|
30
|
+
index: position.index,
|
|
31
|
+
line: position.line,
|
|
32
|
+
column: position.column
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const whitespace = /\s/;
|
|
36
|
+
function isWhitespaceChar(char) {
|
|
37
|
+
return whitespace.test(char);
|
|
38
|
+
}
|
|
39
|
+
const equalSign = /=/;
|
|
40
|
+
function isEqualSignChar(char) {
|
|
41
|
+
return equalSign.test(char);
|
|
42
|
+
}
|
|
43
|
+
function shouldBeIgnore(tagName) {
|
|
44
|
+
const name = tagName.toLowerCase();
|
|
45
|
+
if (options.html.skipElements.has(name)) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const alphanumeric = /[A-Za-z0-9]/;
|
|
51
|
+
function findTextEnd(str, index) {
|
|
52
|
+
while (true) {
|
|
53
|
+
const textEnd = str.indexOf('<', index);
|
|
54
|
+
if (textEnd === -1) {
|
|
55
|
+
return textEnd;
|
|
56
|
+
}
|
|
57
|
+
const char = str.charAt(textEnd + 1);
|
|
58
|
+
if (char === '/' || char === '!' || alphanumeric.test(char)) {
|
|
59
|
+
return textEnd;
|
|
60
|
+
}
|
|
61
|
+
index = textEnd + 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function isWordEnd(cursor, wordBegin, html) {
|
|
65
|
+
if (!isWhitespaceChar(html.charAt(cursor)))
|
|
66
|
+
return false;
|
|
67
|
+
const len = html.length;
|
|
68
|
+
// backward
|
|
69
|
+
for (let i = cursor - 1; i > wordBegin; i--) {
|
|
70
|
+
const char = html.charAt(i);
|
|
71
|
+
if (!isWhitespaceChar(char)) {
|
|
72
|
+
if (isEqualSignChar(char))
|
|
73
|
+
return false;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// forward
|
|
78
|
+
for (let i = cursor + 1; i < len; i++) {
|
|
79
|
+
const char = html.charAt(i);
|
|
80
|
+
if (!isWhitespaceChar(char)) {
|
|
81
|
+
if (isEqualSignChar(char))
|
|
82
|
+
return false;
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
class Scanner {
|
|
88
|
+
constructor(html) {
|
|
89
|
+
this.tokens = [];
|
|
90
|
+
this.position = initPosition();
|
|
91
|
+
this.html = html;
|
|
92
|
+
}
|
|
93
|
+
scan() {
|
|
94
|
+
const { html, position } = this;
|
|
95
|
+
const len = html.length;
|
|
96
|
+
while (position.index < len) {
|
|
97
|
+
const start = position.index;
|
|
98
|
+
this.scanText();
|
|
99
|
+
if (position.index === start) {
|
|
100
|
+
const isComment = html.startsWith('!--', start + 1);
|
|
101
|
+
if (isComment) {
|
|
102
|
+
this.scanComment();
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const tagName = this.scanTag();
|
|
106
|
+
if (shouldBeIgnore(tagName)) {
|
|
107
|
+
this.scanSkipTag(tagName);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return this.tokens;
|
|
113
|
+
}
|
|
114
|
+
scanText() {
|
|
115
|
+
const type = 'text';
|
|
116
|
+
const { html, position } = this;
|
|
117
|
+
let textEnd = findTextEnd(html, position.index);
|
|
118
|
+
if (textEnd === position.index) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (textEnd === -1) {
|
|
122
|
+
textEnd = html.length;
|
|
123
|
+
}
|
|
124
|
+
const start = copyPosition(position);
|
|
125
|
+
const content = html.slice(position.index, textEnd);
|
|
126
|
+
jumpPosition(position, html, textEnd);
|
|
127
|
+
const end = copyPosition(position);
|
|
128
|
+
this.tokens.push({ type, content, position: { start, end } });
|
|
129
|
+
}
|
|
130
|
+
scanComment() {
|
|
131
|
+
const type = 'comment';
|
|
132
|
+
const { html, position } = this;
|
|
133
|
+
const start = copyPosition(position);
|
|
134
|
+
feedPosition(position, html, 4); // "<!--".length
|
|
135
|
+
let contentEnd = html.indexOf('-->', position.index);
|
|
136
|
+
let commentEnd = contentEnd + 3; // "-->".length
|
|
137
|
+
if (contentEnd === -1) {
|
|
138
|
+
contentEnd = commentEnd = html.length;
|
|
139
|
+
}
|
|
140
|
+
const content = html.slice(position.index, contentEnd);
|
|
141
|
+
jumpPosition(position, html, commentEnd);
|
|
142
|
+
this.tokens.push({
|
|
143
|
+
type,
|
|
144
|
+
content,
|
|
145
|
+
position: {
|
|
146
|
+
start,
|
|
147
|
+
end: copyPosition(position)
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
scanTag() {
|
|
152
|
+
this.scanTagStart();
|
|
153
|
+
const tagName = this.scanTagName();
|
|
154
|
+
this.scanAttrs();
|
|
155
|
+
this.scanTagEnd();
|
|
156
|
+
return tagName;
|
|
157
|
+
}
|
|
158
|
+
scanTagStart() {
|
|
159
|
+
const type = 'tag-start';
|
|
160
|
+
const { html, position } = this;
|
|
161
|
+
const secondChar = html.charAt(position.index + 1);
|
|
162
|
+
const close = secondChar === '/';
|
|
163
|
+
const start = copyPosition(position);
|
|
164
|
+
feedPosition(position, html, close ? 2 : 1);
|
|
165
|
+
this.tokens.push({ type, close, position: { start } });
|
|
166
|
+
}
|
|
167
|
+
scanTagEnd() {
|
|
168
|
+
const type = 'tag-end';
|
|
169
|
+
const { html, position } = this;
|
|
170
|
+
const firstChar = html.charAt(position.index);
|
|
171
|
+
const close = firstChar === '/';
|
|
172
|
+
feedPosition(position, html, close ? 2 : 1);
|
|
173
|
+
const end = copyPosition(position);
|
|
174
|
+
this.tokens.push({ type, close, position: { end } });
|
|
175
|
+
}
|
|
176
|
+
scanTagName() {
|
|
177
|
+
const type = 'tag';
|
|
178
|
+
const { html, position } = this;
|
|
179
|
+
const len = html.length;
|
|
180
|
+
let start = position.index;
|
|
181
|
+
while (start < len) {
|
|
182
|
+
const char = html.charAt(start);
|
|
183
|
+
const isTagChar = !(isWhitespaceChar(char) || char === '/' || char === '>');
|
|
184
|
+
if (isTagChar)
|
|
185
|
+
break;
|
|
186
|
+
start++;
|
|
187
|
+
}
|
|
188
|
+
let end = start + 1;
|
|
189
|
+
while (end < len) {
|
|
190
|
+
const char = html.charAt(end);
|
|
191
|
+
const isTagChar = !(isWhitespaceChar(char) || char === '/' || char === '>');
|
|
192
|
+
if (!isTagChar)
|
|
193
|
+
break;
|
|
194
|
+
end++;
|
|
195
|
+
}
|
|
196
|
+
jumpPosition(position, html, end);
|
|
197
|
+
const tagName = html.slice(start, end);
|
|
198
|
+
this.tokens.push({
|
|
199
|
+
type,
|
|
200
|
+
content: tagName
|
|
201
|
+
});
|
|
202
|
+
return tagName;
|
|
203
|
+
}
|
|
204
|
+
scanAttrs() {
|
|
205
|
+
const { html, position, tokens } = this;
|
|
206
|
+
let cursor = position.index;
|
|
207
|
+
let quote = null; // null, single-, or double-quote
|
|
208
|
+
let wordBegin = cursor; // index of word start
|
|
209
|
+
const words = []; // "key", "key=value", "key='value'", etc
|
|
210
|
+
const len = html.length;
|
|
211
|
+
while (cursor < len) {
|
|
212
|
+
const char = html.charAt(cursor);
|
|
213
|
+
if (quote) {
|
|
214
|
+
const isQuoteEnd = char === quote;
|
|
215
|
+
if (isQuoteEnd) {
|
|
216
|
+
quote = null;
|
|
217
|
+
}
|
|
218
|
+
cursor++;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const isTagEnd = char === '/' || char === '>';
|
|
222
|
+
if (isTagEnd) {
|
|
223
|
+
if (cursor !== wordBegin) {
|
|
224
|
+
words.push(html.slice(wordBegin, cursor));
|
|
225
|
+
}
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
if (isWordEnd(cursor, wordBegin, html)) {
|
|
229
|
+
if (cursor !== wordBegin) {
|
|
230
|
+
words.push(html.slice(wordBegin, cursor));
|
|
231
|
+
}
|
|
232
|
+
wordBegin = cursor + 1;
|
|
233
|
+
cursor++;
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
const isQuoteStart = char === '\'' || char === '"';
|
|
237
|
+
if (isQuoteStart) {
|
|
238
|
+
quote = char;
|
|
239
|
+
cursor++;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
cursor++;
|
|
243
|
+
}
|
|
244
|
+
jumpPosition(position, html, cursor);
|
|
245
|
+
const wLen = words.length;
|
|
246
|
+
const type = 'attribute';
|
|
247
|
+
for (let i = 0; i < wLen; i++) {
|
|
248
|
+
const word = words[i];
|
|
249
|
+
const isNotPair = word.includes('=');
|
|
250
|
+
if (isNotPair) {
|
|
251
|
+
const secondWord = words[i + 1];
|
|
252
|
+
if (secondWord && secondWord.startsWith('=')) {
|
|
253
|
+
if (secondWord.length > 1) {
|
|
254
|
+
const newWord = word + secondWord;
|
|
255
|
+
tokens.push({ type, content: newWord });
|
|
256
|
+
i += 1;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const thirdWord = words[i + 2];
|
|
260
|
+
i += 1;
|
|
261
|
+
if (thirdWord) {
|
|
262
|
+
const newWord = word + '=' + thirdWord;
|
|
263
|
+
tokens.push({ type, content: newWord });
|
|
264
|
+
i += 1;
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (word.endsWith('=')) {
|
|
270
|
+
const secondWord = words[i + 1];
|
|
271
|
+
if (secondWord && !secondWord.includes('=')) {
|
|
272
|
+
const newWord = word + secondWord;
|
|
273
|
+
tokens.push({ type, content: newWord });
|
|
274
|
+
i += 1;
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
const newWord = word.slice(0, -1);
|
|
278
|
+
tokens.push({ type, content: newWord });
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
tokens.push({ type, content: word });
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
scanSkipTag(tagName) {
|
|
285
|
+
const { html, position } = this;
|
|
286
|
+
const safeTagName = tagName.toLowerCase();
|
|
287
|
+
const len = html.length;
|
|
288
|
+
while (position.index < len) {
|
|
289
|
+
const nextTag = html.indexOf('</', position.index);
|
|
290
|
+
if (nextTag === -1) {
|
|
291
|
+
this.scanText();
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
jumpPosition(position, html, nextTag);
|
|
295
|
+
const name = this.scanTag();
|
|
296
|
+
if (safeTagName === name.toLowerCase()) {
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export { Scanner };
|
|
304
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sources":["../../../../src/dom-external/inner-html/scanner.ts"],"sourcesContent":["import { options } from '../../options'\n\ninterface Position {\n index: number\n column: number\n line: number\n}\n\nexport interface Token {\n type: string\n content?: string\n position?: {\n start?: Position\n end?: Position\n }\n close?: boolean\n}\n\nfunction initPosition (): Position {\n return {\n index: 0,\n column: 0,\n line: 0\n }\n}\n\nfunction feedPosition (position: Position, str: string, len: number) {\n const start = position.index\n const end = position.index = start + len\n for (let i = start; i < end; i++) {\n const char = str.charAt(i)\n if (char === '\\n') {\n position.line++\n position.column = 0\n } else {\n position.column++\n }\n }\n}\n\nfunction jumpPosition (position: Position, str: string, end: number) {\n const len = end - position.index\n return feedPosition(position, str, len)\n}\n\nfunction copyPosition (position: Position) {\n return {\n index: position.index,\n line: position.line,\n column: position.column\n }\n}\n\nconst whitespace = /\\s/\nfunction isWhitespaceChar (char: string) {\n return whitespace.test(char)\n}\n\nconst equalSign = /=/\nfunction isEqualSignChar (char: string) {\n return equalSign.test(char)\n}\n\nfunction shouldBeIgnore (tagName: string) {\n const name = tagName.toLowerCase()\n if (options.html!.skipElements.has(name)) {\n return true\n }\n return false\n}\n\nconst alphanumeric = /[A-Za-z0-9]/\n\nfunction findTextEnd (str: string, index: number) {\n while (true) {\n const textEnd = str.indexOf('<', index)\n if (textEnd === -1) {\n return textEnd\n }\n const char = str.charAt(textEnd + 1)\n if (char === '/' || char === '!' || alphanumeric.test(char)) {\n return textEnd\n }\n index = textEnd + 1\n }\n}\n\nfunction isWordEnd (cursor: number, wordBegin: number, html: string) {\n if (!isWhitespaceChar(html.charAt(cursor))) return false\n\n const len = html.length\n\n // backward\n for (let i = cursor - 1; i > wordBegin; i--) {\n const char = html.charAt(i)\n if (!isWhitespaceChar(char)) {\n if (isEqualSignChar(char)) return false\n break\n }\n }\n\n // forward\n for (let i = cursor + 1; i < len; i++) {\n const char = html.charAt(i)\n if (!isWhitespaceChar(char)) {\n if (isEqualSignChar(char)) return false\n return true\n }\n }\n}\n\nexport class Scanner {\n private tokens: Token[] = []\n\n private position: Position = initPosition()\n\n private html: string\n\n constructor (html: string) {\n this.html = html\n }\n\n public scan (): Token[] {\n const { html, position } = this\n const len = html.length\n\n while (position.index < len) {\n const start = position.index\n this.scanText()\n if (position.index === start) {\n const isComment = html.startsWith('!--', start + 1)\n if (isComment) {\n this.scanComment()\n } else {\n const tagName = this.scanTag()\n if (shouldBeIgnore(tagName)) {\n this.scanSkipTag(tagName)\n }\n }\n }\n }\n\n return this.tokens\n }\n\n private scanText () {\n const type = 'text'\n const { html, position } = this\n let textEnd = findTextEnd(html, position.index)\n if (textEnd === position.index) {\n return\n }\n if (textEnd === -1) {\n textEnd = html.length\n }\n\n const start = copyPosition(position)\n const content = html.slice(position.index, textEnd)\n jumpPosition(position, html, textEnd)\n const end = copyPosition(position)\n this.tokens.push({ type, content, position: { start, end } })\n }\n\n private scanComment () {\n const type = 'comment'\n const { html, position } = this\n const start = copyPosition(position)\n feedPosition(position, html, 4) // \"<!--\".length\n let contentEnd = html.indexOf('-->', position.index)\n let commentEnd = contentEnd + 3 // \"-->\".length\n if (contentEnd === -1) {\n contentEnd = commentEnd = html.length\n }\n\n const content = html.slice(position.index, contentEnd)\n jumpPosition(position, html, commentEnd)\n this.tokens.push({\n type,\n content,\n position: {\n start,\n end: copyPosition(position)\n }\n })\n }\n\n private scanTag () {\n this.scanTagStart()\n const tagName = this.scanTagName()\n this.scanAttrs()\n this.scanTagEnd()\n\n return tagName\n }\n\n private scanTagStart () {\n const type = 'tag-start'\n const { html, position } = this\n\n const secondChar = html.charAt(position.index + 1)\n const close = secondChar === '/'\n const start = copyPosition(position)\n feedPosition(position, html, close ? 2 : 1)\n this.tokens.push({ type, close, position: { start } })\n }\n\n private scanTagEnd () {\n const type = 'tag-end'\n const { html, position } = this\n\n const firstChar = html.charAt(position.index)\n const close = firstChar === '/'\n feedPosition(position, html, close ? 2 : 1)\n const end = copyPosition(position)\n this.tokens.push({ type, close, position: { end } })\n }\n\n private scanTagName (): string {\n const type = 'tag'\n const { html, position } = this\n const len = html.length\n let start = position.index\n while (start < len) {\n const char = html.charAt(start)\n const isTagChar = !(isWhitespaceChar(char) || char === '/' || char === '>')\n if (isTagChar) break\n start++\n }\n\n let end = start + 1\n while (end < len) {\n const char = html.charAt(end)\n const isTagChar = !(isWhitespaceChar(char) || char === '/' || char === '>')\n if (!isTagChar) break\n end++\n }\n\n jumpPosition(position, html, end)\n const tagName = html.slice(start, end)\n this.tokens.push({\n type,\n content: tagName\n })\n\n return tagName\n }\n\n private scanAttrs () {\n const { html, position, tokens } = this\n let cursor = position.index\n let quote: string | null = null // null, single-, or double-quote\n let wordBegin = cursor // index of word start\n const words: string[] = [] // \"key\", \"key=value\", \"key='value'\", etc\n const len = html.length\n while (cursor < len) {\n const char = html.charAt(cursor)\n if (quote) {\n const isQuoteEnd = char === quote\n if (isQuoteEnd) {\n quote = null\n }\n cursor++\n continue\n }\n\n const isTagEnd = char === '/' || char === '>'\n if (isTagEnd) {\n if (cursor !== wordBegin) {\n words.push(html.slice(wordBegin, cursor))\n }\n break\n }\n\n if (isWordEnd(cursor, wordBegin, html)) {\n if (cursor !== wordBegin) {\n words.push(html.slice(wordBegin, cursor))\n }\n wordBegin = cursor + 1\n cursor++\n continue\n }\n\n const isQuoteStart = char === '\\'' || char === '\"'\n if (isQuoteStart) {\n quote = char\n cursor++\n continue\n }\n\n cursor++\n }\n\n jumpPosition(position, html, cursor)\n\n const wLen = words.length\n const type = 'attribute'\n for (let i = 0; i < wLen; i++) {\n const word = words[i]\n const isNotPair = word.includes('=')\n if (isNotPair) {\n const secondWord = words[i + 1]\n if (secondWord && secondWord.startsWith('=')) {\n if (secondWord.length > 1) {\n const newWord = word + secondWord\n tokens.push({ type, content: newWord })\n i += 1\n continue\n }\n const thirdWord = words[i + 2]\n i += 1\n if (thirdWord) {\n const newWord = word + '=' + thirdWord\n tokens.push({ type, content: newWord })\n i += 1\n continue\n }\n }\n }\n if (word.endsWith('=')) {\n const secondWord = words[i + 1]\n if (secondWord && !secondWord.includes('=')) {\n const newWord = word + secondWord\n tokens.push({ type, content: newWord })\n i += 1\n continue\n }\n\n const newWord = word.slice(0, -1)\n tokens.push({ type, content: newWord })\n continue\n }\n\n tokens.push({ type, content: word })\n }\n }\n\n private scanSkipTag (tagName: string) {\n const { html, position } = this\n const safeTagName = tagName.toLowerCase()\n const len = html.length\n while (position.index < len) {\n const nextTag = html.indexOf('</', position.index)\n if (nextTag === -1) {\n this.scanText()\n break\n }\n\n jumpPosition(position, html, nextTag)\n const name = this.scanTag()\n if (safeTagName === name.toLowerCase()) {\n break\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
|