unhead 0.1.2 → 0.1.4
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/dist/index.cjs +64 -71
- package/dist/index.d.ts +2 -4
- package/dist/index.mjs +65 -70
- package/package.json +5 -3
package/dist/index.cjs
CHANGED
|
@@ -2,18 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
const hookable = require('hookable');
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const HasElementTags = [
|
|
6
|
+
"base",
|
|
7
|
+
"meta",
|
|
8
|
+
"link",
|
|
9
|
+
"style",
|
|
10
|
+
"script",
|
|
11
|
+
"noscript"
|
|
12
|
+
];
|
|
13
|
+
const ValidHeadTags = [
|
|
14
|
+
"title",
|
|
15
|
+
"titleTemplate",
|
|
16
|
+
"base",
|
|
17
|
+
"htmlAttrs",
|
|
18
|
+
"bodyAttrs",
|
|
19
|
+
"meta",
|
|
20
|
+
"link",
|
|
21
|
+
"style",
|
|
22
|
+
"script",
|
|
23
|
+
"noscript"
|
|
24
|
+
];
|
|
25
|
+
const TagConfigKeys = ["tagPosition", "tagPriority", "tagDuplicateStrategy"];
|
|
26
|
+
|
|
27
|
+
function normaliseTag(tagName, input) {
|
|
6
28
|
const tag = { tag: tagName, props: {} };
|
|
7
29
|
if (tagName === "title")
|
|
8
30
|
tag.children = String(input);
|
|
9
31
|
else
|
|
10
32
|
tag.props = normaliseProps({ ...input });
|
|
11
|
-
["children",
|
|
33
|
+
["children", "innerHtml", "innerHTML"].forEach((key) => {
|
|
12
34
|
if (typeof tag.props[key] !== "undefined") {
|
|
13
35
|
tag.children = tag.props[key];
|
|
14
36
|
delete tag.props[key];
|
|
15
37
|
}
|
|
16
38
|
});
|
|
39
|
+
Object.keys(tag.props).filter((k) => TagConfigKeys.includes(k)).forEach((k) => {
|
|
40
|
+
tag[k] = tag.props[k];
|
|
41
|
+
delete tag.props[k];
|
|
42
|
+
});
|
|
43
|
+
if (typeof tag.props.class === "object" && !Array.isArray(tag.props.class)) {
|
|
44
|
+
tag.props.class = Object.keys(tag.props.class).filter((k) => tag.props.class[k]);
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(tag.props.class))
|
|
47
|
+
tag.props.class = tag.props.class.join(" ");
|
|
48
|
+
if (tag.props.content && Array.isArray(tag.props.content)) {
|
|
49
|
+
return tag.props.content.map((v, i) => {
|
|
50
|
+
const newTag = { ...tag, props: { ...tag.props } };
|
|
51
|
+
newTag.props.content = v;
|
|
52
|
+
newTag.key = `${tag.props.name || tag.props.property}:${i}`;
|
|
53
|
+
return newTag;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
17
56
|
return tag;
|
|
18
57
|
}
|
|
19
58
|
function normaliseProps(props) {
|
|
@@ -26,44 +65,26 @@ function normaliseProps(props) {
|
|
|
26
65
|
}
|
|
27
66
|
return props;
|
|
28
67
|
}
|
|
29
|
-
const HasElementTags = [
|
|
30
|
-
"base",
|
|
31
|
-
"meta",
|
|
32
|
-
"link",
|
|
33
|
-
"style",
|
|
34
|
-
"script",
|
|
35
|
-
"noscript"
|
|
36
|
-
];
|
|
37
|
-
const ValidHeadTags = [
|
|
38
|
-
"title",
|
|
39
|
-
"titleTemplate",
|
|
40
|
-
"base",
|
|
41
|
-
"htmlAttrs",
|
|
42
|
-
"bodyAttrs",
|
|
43
|
-
"meta",
|
|
44
|
-
"link",
|
|
45
|
-
"style",
|
|
46
|
-
"script",
|
|
47
|
-
"noscript"
|
|
48
|
-
];
|
|
49
68
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
69
|
+
const tagWeight = (tag) => {
|
|
70
|
+
if (typeof tag.tagPriority === "number")
|
|
71
|
+
return tag.tagPriority;
|
|
72
|
+
switch (tag.tag) {
|
|
73
|
+
case "base":
|
|
74
|
+
return -1;
|
|
75
|
+
case "title":
|
|
76
|
+
return 1;
|
|
77
|
+
case "meta":
|
|
78
|
+
if (tag.props.charset)
|
|
79
|
+
return -2;
|
|
80
|
+
if (tag.props["http-equiv"] === "content-security-policy")
|
|
81
|
+
return 0;
|
|
82
|
+
return 10;
|
|
83
|
+
default:
|
|
84
|
+
return 10;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const sortTags = (aTag, bTag) => {
|
|
67
88
|
return tagWeight(aTag) - tagWeight(bTag);
|
|
68
89
|
};
|
|
69
90
|
|
|
@@ -181,12 +202,8 @@ const SortTagsPlugin = () => {
|
|
|
181
202
|
"tags:resolve": (ctx) => {
|
|
182
203
|
const tagIndexForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
|
|
183
204
|
for (const tag of ctx.tags) {
|
|
184
|
-
if (!tag
|
|
185
|
-
continue;
|
|
186
|
-
if (typeof tag.tagPriority === "number") {
|
|
187
|
-
tag._p = tag.tagPriority;
|
|
205
|
+
if (!tag.tagPriority || typeof tag.tagPriority === "number")
|
|
188
206
|
continue;
|
|
189
|
-
}
|
|
190
207
|
const modifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
|
|
191
208
|
for (const { prefix, offset } of modifiers) {
|
|
192
209
|
if (tag.tagPriority.startsWith(prefix)) {
|
|
@@ -197,7 +214,7 @@ const SortTagsPlugin = () => {
|
|
|
197
214
|
}
|
|
198
215
|
}
|
|
199
216
|
}
|
|
200
|
-
ctx.tags.sort((a, b) => a._p - b._p).sort(
|
|
217
|
+
ctx.tags.sort((a, b) => a._p - b._p).sort(sortTags);
|
|
201
218
|
}
|
|
202
219
|
}
|
|
203
220
|
});
|
|
@@ -286,34 +303,12 @@ const useNoscript = (noscript) => {
|
|
|
286
303
|
function asArray(value) {
|
|
287
304
|
return Array.isArray(value) ? value : [value];
|
|
288
305
|
}
|
|
289
|
-
const TagConfigKeys = ["tagPosition", "tagPriority", "tagDuplicateStrategy"];
|
|
290
306
|
|
|
291
|
-
function normaliseTag(tagName, input, entry) {
|
|
292
|
-
const tag = normaliseTag$1(tagName, input, { childrenKeys: ["innerHTML", "textContent"] });
|
|
293
|
-
tag._e = entry._i;
|
|
294
|
-
Object.keys(tag.props).filter((k) => TagConfigKeys.includes(k)).forEach((k) => {
|
|
295
|
-
tag[k] = tag.props[k];
|
|
296
|
-
delete tag.props[k];
|
|
297
|
-
});
|
|
298
|
-
if (typeof tag.props.class === "object" && !Array.isArray(tag.props.class)) {
|
|
299
|
-
tag.props.class = Object.keys(tag.props.class).filter((k) => tag.props.class[k]);
|
|
300
|
-
}
|
|
301
|
-
if (Array.isArray(tag.props.class))
|
|
302
|
-
tag.props.class = tag.props.class.join(" ");
|
|
303
|
-
if (tag.props.content && Array.isArray(tag.props.content)) {
|
|
304
|
-
return tag.props.content.map((v, i) => {
|
|
305
|
-
const newTag = { ...tag, props: { ...tag.props } };
|
|
306
|
-
newTag.props.content = v;
|
|
307
|
-
newTag.key = `${tag.props.name || tag.props.property}:${i}`;
|
|
308
|
-
return newTag;
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
return tag;
|
|
312
|
-
}
|
|
313
307
|
function normaliseEntryTags(e) {
|
|
314
308
|
return Object.entries(e.input).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).map(
|
|
315
|
-
([k, value]) => asArray(value).map((props) => asArray(normaliseTag(k, props
|
|
309
|
+
([k, value]) => asArray(value).map((props) => asArray(normaliseTag(k, props)))
|
|
316
310
|
).flat(3).map((t, i) => {
|
|
311
|
+
t._e = e._i;
|
|
317
312
|
t._p = (e._i << 8) + i++;
|
|
318
313
|
return t;
|
|
319
314
|
});
|
|
@@ -406,14 +401,12 @@ function defineHeadPlugin(plugin) {
|
|
|
406
401
|
exports.DedupesTagsPlugin = DedupesTagsPlugin;
|
|
407
402
|
exports.HydratesStatePlugin = HydratesStatePlugin;
|
|
408
403
|
exports.SortTagsPlugin = SortTagsPlugin;
|
|
409
|
-
exports.TagConfigKeys = TagConfigKeys;
|
|
410
404
|
exports.TitleTemplatePlugin = TitleTemplatePlugin;
|
|
411
405
|
exports.asArray = asArray;
|
|
412
406
|
exports.createHead = createHead;
|
|
413
407
|
exports.defineHeadPlugin = defineHeadPlugin;
|
|
414
408
|
exports.getActiveHead = getActiveHead;
|
|
415
409
|
exports.normaliseEntryTags = normaliseEntryTags;
|
|
416
|
-
exports.normaliseTag = normaliseTag;
|
|
417
410
|
exports.setActiveHead = setActiveHead;
|
|
418
411
|
exports.useBase = useBase;
|
|
419
412
|
exports.useBodyAttrs = useBodyAttrs;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _unhead_schema from '@unhead/schema';
|
|
2
|
-
import { Head, HeadEntryOptions, Meta, Link, Script, Style, Base, HtmlAttributes, BodyAttributes, Noscript, HeadClient, CreateHeadOptions, HeadPlugin,
|
|
2
|
+
import { Head, HeadEntryOptions, Meta, Link, Script, Style, Base, HtmlAttributes, BodyAttributes, Noscript, HeadClient, CreateHeadOptions, HeadPlugin, HeadEntry, HeadTag } from '@unhead/schema';
|
|
3
3
|
|
|
4
4
|
interface DedupesTagsPluginOptions {
|
|
5
5
|
dedupeKeys?: string[];
|
|
@@ -33,11 +33,9 @@ declare function createHead<T extends {} = Head>(options?: CreateHeadOptions): P
|
|
|
33
33
|
|
|
34
34
|
declare function defineHeadPlugin(plugin: HeadPlugin): HeadPlugin;
|
|
35
35
|
|
|
36
|
-
declare function normaliseTag<T>(tagName: HeadTag['tag'], input: HeadTag['props'], entry: HeadEntry<T>): HeadTag | HeadTag[];
|
|
37
36
|
declare function normaliseEntryTags<T extends {} = Head>(e: HeadEntry<T>): HeadTag[];
|
|
38
37
|
|
|
39
38
|
declare type Arrayable<T> = T | Array<T>;
|
|
40
39
|
declare function asArray<T>(value: Arrayable<T>): T[];
|
|
41
|
-
declare const TagConfigKeys: string[];
|
|
42
40
|
|
|
43
|
-
export { Arrayable, DedupesTagsPlugin, DedupesTagsPluginOptions, HydratesStatePlugin, SortTagsPlugin,
|
|
41
|
+
export { Arrayable, DedupesTagsPlugin, DedupesTagsPluginOptions, HydratesStatePlugin, SortTagsPlugin, TitleTemplatePlugin, activeHead, asArray, createHead, defineHeadPlugin, getActiveHead, normaliseEntryTags, setActiveHead, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useServerHead, useStyle, useTitle, useTitleTemplate };
|
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,56 @@
|
|
|
1
1
|
import { createHooks } from 'hookable';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const HasElementTags = [
|
|
4
|
+
"base",
|
|
5
|
+
"meta",
|
|
6
|
+
"link",
|
|
7
|
+
"style",
|
|
8
|
+
"script",
|
|
9
|
+
"noscript"
|
|
10
|
+
];
|
|
11
|
+
const ValidHeadTags = [
|
|
12
|
+
"title",
|
|
13
|
+
"titleTemplate",
|
|
14
|
+
"base",
|
|
15
|
+
"htmlAttrs",
|
|
16
|
+
"bodyAttrs",
|
|
17
|
+
"meta",
|
|
18
|
+
"link",
|
|
19
|
+
"style",
|
|
20
|
+
"script",
|
|
21
|
+
"noscript"
|
|
22
|
+
];
|
|
23
|
+
const TagConfigKeys = ["tagPosition", "tagPriority", "tagDuplicateStrategy"];
|
|
24
|
+
|
|
25
|
+
function normaliseTag(tagName, input) {
|
|
4
26
|
const tag = { tag: tagName, props: {} };
|
|
5
27
|
if (tagName === "title")
|
|
6
28
|
tag.children = String(input);
|
|
7
29
|
else
|
|
8
30
|
tag.props = normaliseProps({ ...input });
|
|
9
|
-
["children",
|
|
31
|
+
["children", "innerHtml", "innerHTML"].forEach((key) => {
|
|
10
32
|
if (typeof tag.props[key] !== "undefined") {
|
|
11
33
|
tag.children = tag.props[key];
|
|
12
34
|
delete tag.props[key];
|
|
13
35
|
}
|
|
14
36
|
});
|
|
37
|
+
Object.keys(tag.props).filter((k) => TagConfigKeys.includes(k)).forEach((k) => {
|
|
38
|
+
tag[k] = tag.props[k];
|
|
39
|
+
delete tag.props[k];
|
|
40
|
+
});
|
|
41
|
+
if (typeof tag.props.class === "object" && !Array.isArray(tag.props.class)) {
|
|
42
|
+
tag.props.class = Object.keys(tag.props.class).filter((k) => tag.props.class[k]);
|
|
43
|
+
}
|
|
44
|
+
if (Array.isArray(tag.props.class))
|
|
45
|
+
tag.props.class = tag.props.class.join(" ");
|
|
46
|
+
if (tag.props.content && Array.isArray(tag.props.content)) {
|
|
47
|
+
return tag.props.content.map((v, i) => {
|
|
48
|
+
const newTag = { ...tag, props: { ...tag.props } };
|
|
49
|
+
newTag.props.content = v;
|
|
50
|
+
newTag.key = `${tag.props.name || tag.props.property}:${i}`;
|
|
51
|
+
return newTag;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
15
54
|
return tag;
|
|
16
55
|
}
|
|
17
56
|
function normaliseProps(props) {
|
|
@@ -24,44 +63,26 @@ function normaliseProps(props) {
|
|
|
24
63
|
}
|
|
25
64
|
return props;
|
|
26
65
|
}
|
|
27
|
-
const HasElementTags = [
|
|
28
|
-
"base",
|
|
29
|
-
"meta",
|
|
30
|
-
"link",
|
|
31
|
-
"style",
|
|
32
|
-
"script",
|
|
33
|
-
"noscript"
|
|
34
|
-
];
|
|
35
|
-
const ValidHeadTags = [
|
|
36
|
-
"title",
|
|
37
|
-
"titleTemplate",
|
|
38
|
-
"base",
|
|
39
|
-
"htmlAttrs",
|
|
40
|
-
"bodyAttrs",
|
|
41
|
-
"meta",
|
|
42
|
-
"link",
|
|
43
|
-
"style",
|
|
44
|
-
"script",
|
|
45
|
-
"noscript"
|
|
46
|
-
];
|
|
47
66
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
67
|
+
const tagWeight = (tag) => {
|
|
68
|
+
if (typeof tag.tagPriority === "number")
|
|
69
|
+
return tag.tagPriority;
|
|
70
|
+
switch (tag.tag) {
|
|
71
|
+
case "base":
|
|
72
|
+
return -1;
|
|
73
|
+
case "title":
|
|
74
|
+
return 1;
|
|
75
|
+
case "meta":
|
|
76
|
+
if (tag.props.charset)
|
|
77
|
+
return -2;
|
|
78
|
+
if (tag.props["http-equiv"] === "content-security-policy")
|
|
79
|
+
return 0;
|
|
80
|
+
return 10;
|
|
81
|
+
default:
|
|
82
|
+
return 10;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const sortTags = (aTag, bTag) => {
|
|
65
86
|
return tagWeight(aTag) - tagWeight(bTag);
|
|
66
87
|
};
|
|
67
88
|
|
|
@@ -179,12 +200,8 @@ const SortTagsPlugin = () => {
|
|
|
179
200
|
"tags:resolve": (ctx) => {
|
|
180
201
|
const tagIndexForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
|
|
181
202
|
for (const tag of ctx.tags) {
|
|
182
|
-
if (!tag
|
|
183
|
-
continue;
|
|
184
|
-
if (typeof tag.tagPriority === "number") {
|
|
185
|
-
tag._p = tag.tagPriority;
|
|
203
|
+
if (!tag.tagPriority || typeof tag.tagPriority === "number")
|
|
186
204
|
continue;
|
|
187
|
-
}
|
|
188
205
|
const modifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
|
|
189
206
|
for (const { prefix, offset } of modifiers) {
|
|
190
207
|
if (tag.tagPriority.startsWith(prefix)) {
|
|
@@ -195,7 +212,7 @@ const SortTagsPlugin = () => {
|
|
|
195
212
|
}
|
|
196
213
|
}
|
|
197
214
|
}
|
|
198
|
-
ctx.tags.sort((a, b) => a._p - b._p).sort(
|
|
215
|
+
ctx.tags.sort((a, b) => a._p - b._p).sort(sortTags);
|
|
199
216
|
}
|
|
200
217
|
}
|
|
201
218
|
});
|
|
@@ -284,34 +301,12 @@ const useNoscript = (noscript) => {
|
|
|
284
301
|
function asArray(value) {
|
|
285
302
|
return Array.isArray(value) ? value : [value];
|
|
286
303
|
}
|
|
287
|
-
const TagConfigKeys = ["tagPosition", "tagPriority", "tagDuplicateStrategy"];
|
|
288
304
|
|
|
289
|
-
function normaliseTag(tagName, input, entry) {
|
|
290
|
-
const tag = normaliseTag$1(tagName, input, { childrenKeys: ["innerHTML", "textContent"] });
|
|
291
|
-
tag._e = entry._i;
|
|
292
|
-
Object.keys(tag.props).filter((k) => TagConfigKeys.includes(k)).forEach((k) => {
|
|
293
|
-
tag[k] = tag.props[k];
|
|
294
|
-
delete tag.props[k];
|
|
295
|
-
});
|
|
296
|
-
if (typeof tag.props.class === "object" && !Array.isArray(tag.props.class)) {
|
|
297
|
-
tag.props.class = Object.keys(tag.props.class).filter((k) => tag.props.class[k]);
|
|
298
|
-
}
|
|
299
|
-
if (Array.isArray(tag.props.class))
|
|
300
|
-
tag.props.class = tag.props.class.join(" ");
|
|
301
|
-
if (tag.props.content && Array.isArray(tag.props.content)) {
|
|
302
|
-
return tag.props.content.map((v, i) => {
|
|
303
|
-
const newTag = { ...tag, props: { ...tag.props } };
|
|
304
|
-
newTag.props.content = v;
|
|
305
|
-
newTag.key = `${tag.props.name || tag.props.property}:${i}`;
|
|
306
|
-
return newTag;
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
return tag;
|
|
310
|
-
}
|
|
311
305
|
function normaliseEntryTags(e) {
|
|
312
306
|
return Object.entries(e.input).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).map(
|
|
313
|
-
([k, value]) => asArray(value).map((props) => asArray(normaliseTag(k, props
|
|
307
|
+
([k, value]) => asArray(value).map((props) => asArray(normaliseTag(k, props)))
|
|
314
308
|
).flat(3).map((t, i) => {
|
|
309
|
+
t._e = e._i;
|
|
315
310
|
t._p = (e._i << 8) + i++;
|
|
316
311
|
return t;
|
|
317
312
|
});
|
|
@@ -401,4 +396,4 @@ function defineHeadPlugin(plugin) {
|
|
|
401
396
|
return plugin;
|
|
402
397
|
}
|
|
403
398
|
|
|
404
|
-
export { DedupesTagsPlugin, HydratesStatePlugin, SortTagsPlugin,
|
|
399
|
+
export { DedupesTagsPlugin, HydratesStatePlugin, SortTagsPlugin, TitleTemplatePlugin, activeHead, asArray, createHead, defineHeadPlugin, getActiveHead, normaliseEntryTags, setActiveHead, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useServerHead, useStyle, useTitle, useTitleTemplate };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unhead",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.4",
|
|
5
5
|
"packageManager": "pnpm@7.14.0",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -19,20 +19,22 @@
|
|
|
19
19
|
"exports": {
|
|
20
20
|
".": {
|
|
21
21
|
"types": "./dist/index.d.ts",
|
|
22
|
+
"require": "./dist/index.cjs",
|
|
22
23
|
"import": "./dist/index.mjs"
|
|
23
24
|
}
|
|
24
25
|
},
|
|
26
|
+
"main": "dist/index.cjs",
|
|
25
27
|
"module": "dist/index.mjs",
|
|
26
28
|
"types": "dist/index.d.ts",
|
|
27
29
|
"files": [
|
|
28
30
|
"dist"
|
|
29
31
|
],
|
|
30
32
|
"dependencies": {
|
|
31
|
-
"@unhead/schema": "0.1.
|
|
33
|
+
"@unhead/schema": "0.1.4",
|
|
32
34
|
"hookable": "^5.4.1"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
|
-
"zhead": "1.0.0-beta.
|
|
37
|
+
"zhead": "1.0.0-beta.5"
|
|
36
38
|
},
|
|
37
39
|
"scripts": {
|
|
38
40
|
"build": "unbuild .",
|