shape-text 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 +21 -0
- package/README.md +264 -0
- package/dist/geometry/get-band-intervals-from-polygon.d.ts +2 -0
- package/dist/geometry/get-band-intervals-from-polygon.js +44 -0
- package/dist/geometry/get-band-intervals-from-polygon.js.map +1 -0
- package/dist/geometry/get-polygon-bounds.d.ts +2 -0
- package/dist/geometry/get-polygon-bounds.js +18 -0
- package/dist/geometry/get-polygon-bounds.js.map +1 -0
- package/dist/geometry/get-x-intersections-at-y.d.ts +2 -0
- package/dist/geometry/get-x-intersections-at-y.js +15 -0
- package/dist/geometry/get-x-intersections-at-y.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/layout-dense-fill-pass.d.ts +23 -0
- package/dist/layout/layout-dense-fill-pass.js +64 -0
- package/dist/layout/layout-dense-fill-pass.js.map +1 -0
- package/dist/layout/layout-flow-lines-in-compiled-shape.d.ts +13 -0
- package/dist/layout/layout-flow-lines-in-compiled-shape.js +42 -0
- package/dist/layout/layout-flow-lines-in-compiled-shape.js.map +1 -0
- package/dist/layout/layout-text-in-compiled-shape.d.ts +2 -0
- package/dist/layout/layout-text-in-compiled-shape.js +13 -0
- package/dist/layout/layout-text-in-compiled-shape.js.map +1 -0
- package/dist/layout/layout-text-in-shape.d.ts +2 -0
- package/dist/layout/layout-text-in-shape.js +40 -0
- package/dist/layout/layout-text-in-shape.js.map +1 -0
- package/dist/layout/resolve-flow-layout.d.ts +2 -0
- package/dist/layout/resolve-flow-layout.js +31 -0
- package/dist/layout/resolve-flow-layout.js.map +1 -0
- package/dist/layout/resolve-max-fill-helpers.d.ts +3 -0
- package/dist/layout/resolve-max-fill-helpers.js +18 -0
- package/dist/layout/resolve-max-fill-helpers.js.map +1 -0
- package/dist/layout/resolve-max-fill-layout.d.ts +2 -0
- package/dist/layout/resolve-max-fill-layout.js +34 -0
- package/dist/layout/resolve-max-fill-layout.js.map +1 -0
- package/dist/layout/resolve-sequential-shape-regions.d.ts +3 -0
- package/dist/layout/resolve-sequential-shape-regions.js +95 -0
- package/dist/layout/resolve-sequential-shape-regions.js.map +1 -0
- package/dist/render/escape-xml-text.d.ts +1 -0
- package/dist/render/escape-xml-text.js +9 -0
- package/dist/render/escape-xml-text.js.map +1 -0
- package/dist/render/normalize-shape-decoration.d.ts +2 -0
- package/dist/render/normalize-shape-decoration.js +41 -0
- package/dist/render/normalize-shape-decoration.js.map +1 -0
- package/dist/render/render-layout-to-svg.d.ts +2 -0
- package/dist/render/render-layout-to-svg.js +88 -0
- package/dist/render/render-layout-to-svg.js.map +1 -0
- package/dist/render/render-svg-shadow-filter.d.ts +10 -0
- package/dist/render/render-svg-shadow-filter.js +16 -0
- package/dist/render/render-svg-shadow-filter.js.map +1 -0
- package/dist/shape/build-text-mask-bands-from-alpha.d.ts +8 -0
- package/dist/shape/build-text-mask-bands-from-alpha.js +73 -0
- package/dist/shape/build-text-mask-bands-from-alpha.js.map +1 -0
- package/dist/shape/compile-polygon-shape-for-layout.d.ts +2 -0
- package/dist/shape/compile-polygon-shape-for-layout.js +26 -0
- package/dist/shape/compile-polygon-shape-for-layout.js.map +1 -0
- package/dist/shape/compile-shape-for-layout.d.ts +2 -0
- package/dist/shape/compile-shape-for-layout.js +18 -0
- package/dist/shape/compile-shape-for-layout.js.map +1 -0
- package/dist/shape/compile-text-mask-shape-for-layout.d.ts +2 -0
- package/dist/shape/compile-text-mask-shape-for-layout.js +162 -0
- package/dist/shape/compile-text-mask-shape-for-layout.js.map +1 -0
- package/dist/shape/render-text-mask-raster.d.ts +13 -0
- package/dist/shape/render-text-mask-raster.js +29 -0
- package/dist/shape/render-text-mask-raster.js.map +1 -0
- package/dist/shape/resolve-text-mask-shape-size.d.ts +18 -0
- package/dist/shape/resolve-text-mask-shape-size.js +67 -0
- package/dist/shape/resolve-text-mask-shape-size.js.map +1 -0
- package/dist/shape/segment-text-mask-graphemes.d.ts +6 -0
- package/dist/shape/segment-text-mask-graphemes.js +20 -0
- package/dist/shape/segment-text-mask-graphemes.js.map +1 -0
- package/dist/text/create-browser-canvas-2d-context.d.ts +2 -0
- package/dist/text/create-browser-canvas-2d-context.js +21 -0
- package/dist/text/create-browser-canvas-2d-context.js.map +1 -0
- package/dist/text/create-canvas-text-measurer.d.ts +2 -0
- package/dist/text/create-canvas-text-measurer.js +11 -0
- package/dist/text/create-canvas-text-measurer.js.map +1 -0
- package/dist/text/layout-next-line-from-dense-repeated-text.d.ts +2 -0
- package/dist/text/layout-next-line-from-dense-repeated-text.js +63 -0
- package/dist/text/layout-next-line-from-dense-repeated-text.js.map +1 -0
- package/dist/text/layout-next-line-from-prepared-text.d.ts +2 -0
- package/dist/text/layout-next-line-from-prepared-text.js +57 -0
- package/dist/text/layout-next-line-from-prepared-text.js.map +1 -0
- package/dist/text/layout-next-line-from-repeated-text.d.ts +2 -0
- package/dist/text/layout-next-line-from-repeated-text.js +51 -0
- package/dist/text/layout-next-line-from-repeated-text.js.map +1 -0
- package/dist/text/layout-text-line-helpers.d.ts +4 -0
- package/dist/text/layout-text-line-helpers.js +17 -0
- package/dist/text/layout-text-line-helpers.js.map +1 -0
- package/dist/text/normalize-text-style-to-font.d.ts +6 -0
- package/dist/text/normalize-text-style-to-font.js +31 -0
- package/dist/text/normalize-text-style-to-font.js.map +1 -0
- package/dist/text/prepare-dense-repeat-fill-pattern.d.ts +2 -0
- package/dist/text/prepare-dense-repeat-fill-pattern.js +13 -0
- package/dist/text/prepare-dense-repeat-fill-pattern.js.map +1 -0
- package/dist/text/prepare-stream-repeat-fill-pattern.d.ts +2 -0
- package/dist/text/prepare-stream-repeat-fill-pattern.js +16 -0
- package/dist/text/prepare-stream-repeat-fill-pattern.js.map +1 -0
- package/dist/text/prepare-text-for-layout.d.ts +2 -0
- package/dist/text/prepare-text-for-layout.js +22 -0
- package/dist/text/prepare-text-for-layout.js.map +1 -0
- package/dist/text/segment-text-for-layout.d.ts +3 -0
- package/dist/text/segment-text-for-layout.js +43 -0
- package/dist/text/segment-text-for-layout.js.map +1 -0
- package/dist/types.d.ts +200 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout-text-line-helpers.js","sourceRoot":"","sources":["../../src/text/layout-text-line-helpers.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAC/B,KAA0B,EAC1B,KAAa,EACb,GAAW;IAEX,OAAO,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAE,GAAG,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAE,CAAA;AAC9E,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAA0B,EAC1B,KAAa,EACb,GAAW;IAEX,OAAO,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAA0B,EAC1B,KAAa,EACb,QAAgB;IAEhB,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;IAE5C,KAAK,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QAC/D,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QAClD,IAAI,KAAK,GAAG,cAAc,EAAE,CAAC;YAC3B,OAAO,GAAG,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,SAAS,CAAC,MAAM,CAAA;AAC/B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ResolvedTextStyle, TextStyleInput } from '../types.js';
|
|
2
|
+
export declare function normalizeTextStyleToFont(textStyle: TextStyleInput): ResolvedTextStyle;
|
|
3
|
+
export declare function resolveLayoutTextStyle(options: {
|
|
4
|
+
font?: string;
|
|
5
|
+
textStyle?: TextStyleInput;
|
|
6
|
+
}): ResolvedTextStyle;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function assertFinitePositiveSize(size) {
|
|
2
|
+
if (!Number.isFinite(size) || size <= 0) {
|
|
3
|
+
throw new Error('textStyle.size must be a finite positive number');
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
export function normalizeTextStyleToFont(textStyle) {
|
|
7
|
+
if (textStyle.family.trim().length === 0) {
|
|
8
|
+
throw new Error('textStyle.family must be a non-empty string');
|
|
9
|
+
}
|
|
10
|
+
assertFinitePositiveSize(textStyle.size);
|
|
11
|
+
return {
|
|
12
|
+
family: textStyle.family,
|
|
13
|
+
size: textStyle.size,
|
|
14
|
+
weight: textStyle.weight ?? 400,
|
|
15
|
+
style: textStyle.style ?? 'normal',
|
|
16
|
+
color: textStyle.color,
|
|
17
|
+
font: `${textStyle.style ?? 'normal'} ${String(textStyle.weight ?? 400)} ${textStyle.size}px ${textStyle.family}`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function resolveLayoutTextStyle(options) {
|
|
21
|
+
if (options.textStyle !== undefined) {
|
|
22
|
+
return normalizeTextStyleToFont(options.textStyle);
|
|
23
|
+
}
|
|
24
|
+
if (options.font !== undefined && options.font.trim().length > 0) {
|
|
25
|
+
return {
|
|
26
|
+
font: options.font,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
throw new Error('layout text requires either font or textStyle');
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=normalize-text-style-to-font.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-text-style-to-font.js","sourceRoot":"","sources":["../../src/text/normalize-text-style-to-font.ts"],"names":[],"mappings":"AAEA,SAAS,wBAAwB,CAAC,IAAY;IAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;IACpE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,SAAyB;IAChE,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IAChE,CAAC;IAED,wBAAwB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAExC,OAAO;QACL,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,IAAI,EAAE,SAAS,CAAC,IAAI;QACpB,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,GAAG;QAC/B,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,QAAQ;QAClC,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,IAAI,EAAE,GAAG,SAAS,CAAC,KAAK,IAAI,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,SAAS,CAAC,IAAI,MAAM,SAAS,CAAC,MAAM,EAAE;KAClH,CAAA;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAGtC;IACC,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,wBAAwB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACpD,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjE,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAA;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;AAClE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createMeasuredWordToken } from './segment-text-for-layout.js';
|
|
2
|
+
export function prepareDenseRepeatFillPattern(text, font, measurer) {
|
|
3
|
+
const normalized = text.replace(/\s+/gu, '');
|
|
4
|
+
if (normalized.length === 0) {
|
|
5
|
+
throw new Error('dense autoFill requires at least one non-whitespace grapheme');
|
|
6
|
+
}
|
|
7
|
+
const pattern = createMeasuredWordToken(normalized, value => measurer.measureText(value, font));
|
|
8
|
+
if (pattern.width <= 0) {
|
|
9
|
+
throw new Error('dense autoFill requires measurable graphemes');
|
|
10
|
+
}
|
|
11
|
+
return pattern;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=prepare-dense-repeat-fill-pattern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare-dense-repeat-fill-pattern.js","sourceRoot":"","sources":["../../src/text/prepare-dense-repeat-fill-pattern.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAEtE,MAAM,UAAU,6BAA6B,CAC3C,IAAY,EACZ,IAAY,EACZ,QAAsB;IAEtB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IAE5C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;IACjF,CAAC;IAED,MAAM,OAAO,GAAG,uBAAuB,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;IAC/F,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createMeasuredWordToken } from './segment-text-for-layout.js';
|
|
2
|
+
function normalizeRepeatStreamText(text) {
|
|
3
|
+
return text.replace(/\r\n?/gu, '\n').replace(/[\n\t\f\v]+/gu, ' ');
|
|
4
|
+
}
|
|
5
|
+
export function prepareStreamRepeatFillPattern(text, font, measurer) {
|
|
6
|
+
const normalized = normalizeRepeatStreamText(text);
|
|
7
|
+
if (normalized.length === 0) {
|
|
8
|
+
throw new Error('stream autoFill requires at least one grapheme');
|
|
9
|
+
}
|
|
10
|
+
const pattern = createMeasuredWordToken(normalized, value => measurer.measureText(value, font));
|
|
11
|
+
if (pattern.width <= 0) {
|
|
12
|
+
throw new Error('stream autoFill requires measurable graphemes');
|
|
13
|
+
}
|
|
14
|
+
return pattern;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=prepare-stream-repeat-fill-pattern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare-stream-repeat-fill-pattern.js","sourceRoot":"","sources":["../../src/text/prepare-stream-repeat-fill-pattern.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAEtE,SAAS,yBAAyB,CAAC,IAAY;IAC7C,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAA;AACpE,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,IAAY,EACZ,IAAY,EACZ,QAAsB;IAEtB,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAA;IAElD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;IACnE,CAAC;IAED,MAAM,OAAO,GAAG,uBAAuB,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;IAC/F,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;IAClE,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createMeasuredWordToken, segmentTextForLayout } from './segment-text-for-layout.js';
|
|
2
|
+
export function prepareTextForLayout(text, font, measurer) {
|
|
3
|
+
const segmented = segmentTextForLayout(text);
|
|
4
|
+
const tokens = segmented.map(token => {
|
|
5
|
+
if (token.kind === 'newline') {
|
|
6
|
+
return {
|
|
7
|
+
kind: 'newline',
|
|
8
|
+
text: token.text,
|
|
9
|
+
width: 0,
|
|
10
|
+
graphemes: [],
|
|
11
|
+
graphemePrefixWidths: [0],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
return createMeasuredWordToken(token.text, value => measurer.measureText(value, font));
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
font,
|
|
18
|
+
spaceWidth: measurer.measureText(' ', font),
|
|
19
|
+
tokens,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=prepare-text-for-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare-text-for-layout.js","sourceRoot":"","sources":["../../src/text/prepare-text-for-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAE5F,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,IAAY,EACZ,QAAsB;IAEtB,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAA;IAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QACnC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO;gBACL,IAAI,EAAE,SAAkB;gBACxB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,KAAK,EAAE,CAAC;gBACR,SAAS,EAAE,EAAE;gBACb,oBAAoB,EAAE,CAAC,CAAC,CAAC;aAC1B,CAAA;QACH,CAAC;QAED,OAAO,uBAAuB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;IACxF,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,IAAI;QACJ,UAAU,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC;QAC3C,MAAM;KACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { PreparedLayoutToken } from '../types.js';
|
|
2
|
+
export declare function segmentTextForLayout(text: string): Array<Pick<PreparedLayoutToken, 'kind' | 'text'>>;
|
|
3
|
+
export declare function createMeasuredWordToken(text: string, measureWord: (value: string) => number): PreparedLayoutToken;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
2
|
+
function segmentGraphemes(word) {
|
|
3
|
+
return Array.from(graphemeSegmenter.segment(word), segment => segment.segment);
|
|
4
|
+
}
|
|
5
|
+
export function segmentTextForLayout(text) {
|
|
6
|
+
const normalizedLines = text
|
|
7
|
+
.replace(/\r\n?/g, '\n')
|
|
8
|
+
.split('\n')
|
|
9
|
+
.map(line => line.replace(/[^\S\n]+/g, ' ').trim());
|
|
10
|
+
const tokens = [];
|
|
11
|
+
for (let lineIndex = 0; lineIndex < normalizedLines.length; lineIndex++) {
|
|
12
|
+
const line = normalizedLines[lineIndex];
|
|
13
|
+
if (line.length > 0) {
|
|
14
|
+
const words = line.split(' ');
|
|
15
|
+
for (let wordIndex = 0; wordIndex < words.length; wordIndex++) {
|
|
16
|
+
const word = words[wordIndex];
|
|
17
|
+
if (word.length === 0)
|
|
18
|
+
continue;
|
|
19
|
+
tokens.push({ kind: 'word', text: word });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (lineIndex < normalizedLines.length - 1) {
|
|
23
|
+
tokens.push({ kind: 'newline', text: '\n' });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return tokens;
|
|
27
|
+
}
|
|
28
|
+
export function createMeasuredWordToken(text, measureWord) {
|
|
29
|
+
const graphemes = segmentGraphemes(text);
|
|
30
|
+
const graphemePrefixWidths = [0];
|
|
31
|
+
for (let index = 0; index < graphemes.length; index++) {
|
|
32
|
+
const width = measureWord(graphemes[index]);
|
|
33
|
+
graphemePrefixWidths.push(graphemePrefixWidths[index] + width);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
kind: 'word',
|
|
37
|
+
text,
|
|
38
|
+
width: graphemePrefixWidths[graphemePrefixWidths.length - 1],
|
|
39
|
+
graphemes,
|
|
40
|
+
graphemePrefixWidths,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=segment-text-for-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment-text-for-layout.js","sourceRoot":"","sources":["../../src/text/segment-text-for-layout.ts"],"names":[],"mappings":"AAEA,MAAM,iBAAiB,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAA;AAEpF,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;AAChF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,eAAe,GAAG,IAAI;SACzB,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC;SACvB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAErD,MAAM,MAAM,GAAsD,EAAE,CAAA;IAEpE,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;QACxE,MAAM,IAAI,GAAG,eAAe,CAAC,SAAS,CAAE,CAAA;QAExC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC7B,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;gBAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAE,CAAA;gBAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAQ;gBAC/B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;YAC3C,CAAC;QACH,CAAC;QAED,IAAI,SAAS,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,IAAY,EACZ,WAAsC;IAEtC,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACxC,MAAM,oBAAoB,GAAG,CAAC,CAAC,CAAC,CAAA;IAEhC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,KAAK,CAAE,CAAC,CAAA;QAC5C,oBAAoB,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAE,GAAG,KAAK,CAAC,CAAA;IACjE,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI;QACJ,KAAK,EAAE,oBAAoB,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,CAAE;QAC7D,SAAS;QACT,oBAAoB;KACrB,CAAA;AACH,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
export type ShapeTextPoint = {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
};
|
|
5
|
+
export type Interval = {
|
|
6
|
+
left: number;
|
|
7
|
+
right: number;
|
|
8
|
+
};
|
|
9
|
+
export type TextMaskShapeTextMode = 'whole-text' | 'per-character';
|
|
10
|
+
export type TextMaskShapeSizeMode = 'fit-content' | 'fixed';
|
|
11
|
+
export type TextMaskShapeFitContentSize = {
|
|
12
|
+
mode?: 'fit-content';
|
|
13
|
+
padding?: number;
|
|
14
|
+
};
|
|
15
|
+
export type TextMaskShapeFixedSize = {
|
|
16
|
+
mode: 'fixed';
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
padding?: number;
|
|
20
|
+
};
|
|
21
|
+
export type TextMaskShapeSize = TextMaskShapeFitContentSize | TextMaskShapeFixedSize;
|
|
22
|
+
export type PolygonShape = {
|
|
23
|
+
kind: 'polygon';
|
|
24
|
+
points: ShapeTextPoint[];
|
|
25
|
+
};
|
|
26
|
+
export type TextMaskShape = {
|
|
27
|
+
kind: 'text-mask';
|
|
28
|
+
text: string;
|
|
29
|
+
font: string;
|
|
30
|
+
size?: TextMaskShapeSize;
|
|
31
|
+
shapeTextMode?: TextMaskShapeTextMode;
|
|
32
|
+
maskScale?: number;
|
|
33
|
+
alphaThreshold?: number;
|
|
34
|
+
};
|
|
35
|
+
export type ShapeInput = PolygonShape | TextMaskShape;
|
|
36
|
+
export type TextMeasurer = {
|
|
37
|
+
measureText(text: string, font: string): number;
|
|
38
|
+
};
|
|
39
|
+
export type TextStyleInput = {
|
|
40
|
+
family: string;
|
|
41
|
+
size: number;
|
|
42
|
+
weight?: number | string;
|
|
43
|
+
style?: 'normal' | 'italic' | 'oblique';
|
|
44
|
+
color?: string;
|
|
45
|
+
};
|
|
46
|
+
export type ResolvedTextStyle = {
|
|
47
|
+
font: string;
|
|
48
|
+
family?: string;
|
|
49
|
+
size?: number;
|
|
50
|
+
weight?: number | string;
|
|
51
|
+
style?: 'normal' | 'italic' | 'oblique';
|
|
52
|
+
color?: string;
|
|
53
|
+
};
|
|
54
|
+
export type ShapeShadowInput = {
|
|
55
|
+
color?: string;
|
|
56
|
+
blur: number;
|
|
57
|
+
offsetX?: number;
|
|
58
|
+
offsetY?: number;
|
|
59
|
+
};
|
|
60
|
+
export type ResolvedShapeShadow = {
|
|
61
|
+
color: string;
|
|
62
|
+
blur: number;
|
|
63
|
+
offsetX: number;
|
|
64
|
+
offsetY: number;
|
|
65
|
+
};
|
|
66
|
+
export type ShapeStyleInput = {
|
|
67
|
+
backgroundColor?: string;
|
|
68
|
+
borderColor?: string;
|
|
69
|
+
borderWidth?: number;
|
|
70
|
+
shadow?: ShapeShadowInput;
|
|
71
|
+
};
|
|
72
|
+
export type ResolvedShapeStyle = {
|
|
73
|
+
backgroundColor?: string;
|
|
74
|
+
borderColor: string;
|
|
75
|
+
borderWidth: number;
|
|
76
|
+
shadow?: ResolvedShapeShadow;
|
|
77
|
+
};
|
|
78
|
+
export type PreparedLayoutToken = {
|
|
79
|
+
kind: 'word' | 'newline';
|
|
80
|
+
text: string;
|
|
81
|
+
width: number;
|
|
82
|
+
graphemes: string[];
|
|
83
|
+
graphemePrefixWidths: number[];
|
|
84
|
+
};
|
|
85
|
+
export type PreparedLayoutText = {
|
|
86
|
+
font: string;
|
|
87
|
+
spaceWidth: number;
|
|
88
|
+
tokens: PreparedLayoutToken[];
|
|
89
|
+
};
|
|
90
|
+
export type LayoutCursor = {
|
|
91
|
+
tokenIndex: number;
|
|
92
|
+
graphemeIndex: number;
|
|
93
|
+
};
|
|
94
|
+
export type LayoutLineRange = {
|
|
95
|
+
text: string;
|
|
96
|
+
width: number;
|
|
97
|
+
start: LayoutCursor;
|
|
98
|
+
end: LayoutCursor;
|
|
99
|
+
};
|
|
100
|
+
export type ShapeTextLine = LayoutLineRange & {
|
|
101
|
+
x: number;
|
|
102
|
+
top: number;
|
|
103
|
+
baseline: number;
|
|
104
|
+
slot: Interval;
|
|
105
|
+
font?: string;
|
|
106
|
+
fillPass?: 1 | 2;
|
|
107
|
+
};
|
|
108
|
+
export type ShapeBounds = {
|
|
109
|
+
left: number;
|
|
110
|
+
top: number;
|
|
111
|
+
right: number;
|
|
112
|
+
bottom: number;
|
|
113
|
+
};
|
|
114
|
+
export type CompiledShapeBand = {
|
|
115
|
+
top: number;
|
|
116
|
+
bottom: number;
|
|
117
|
+
intervals: Interval[];
|
|
118
|
+
};
|
|
119
|
+
export type CompiledShapeDebugView = {
|
|
120
|
+
kind: 'polygon';
|
|
121
|
+
points: ShapeTextPoint[];
|
|
122
|
+
} | {
|
|
123
|
+
kind: 'text';
|
|
124
|
+
text: string;
|
|
125
|
+
font: string;
|
|
126
|
+
x: number;
|
|
127
|
+
baseline: number;
|
|
128
|
+
};
|
|
129
|
+
export type CompiledShapeRegion = {
|
|
130
|
+
index: number;
|
|
131
|
+
grapheme: string;
|
|
132
|
+
bounds: ShapeBounds;
|
|
133
|
+
bands: CompiledShapeBand[];
|
|
134
|
+
debugView: CompiledShapeDebugView;
|
|
135
|
+
};
|
|
136
|
+
export type CompiledShapeBands = {
|
|
137
|
+
kind: ShapeInput['kind'];
|
|
138
|
+
source: ShapeInput;
|
|
139
|
+
bounds: ShapeBounds;
|
|
140
|
+
bandHeight: number;
|
|
141
|
+
minSlotWidth: number;
|
|
142
|
+
bands: CompiledShapeBand[];
|
|
143
|
+
regions?: CompiledShapeRegion[];
|
|
144
|
+
debugView: CompiledShapeDebugView;
|
|
145
|
+
};
|
|
146
|
+
export type ShapeTextLayout = {
|
|
147
|
+
font: string;
|
|
148
|
+
textStyle?: ResolvedTextStyle;
|
|
149
|
+
lineHeight: number;
|
|
150
|
+
shape: ShapeInput;
|
|
151
|
+
compiledShape: CompiledShapeBands;
|
|
152
|
+
bounds: ShapeBounds;
|
|
153
|
+
lines: ShapeTextLine[];
|
|
154
|
+
exhausted: boolean;
|
|
155
|
+
autoFill: boolean;
|
|
156
|
+
};
|
|
157
|
+
export type CompileShapeForLayoutOptions = {
|
|
158
|
+
shape: ShapeInput;
|
|
159
|
+
lineHeight: number;
|
|
160
|
+
minSlotWidth?: number;
|
|
161
|
+
};
|
|
162
|
+
export type LayoutTextInCompiledShapeOptions = {
|
|
163
|
+
text: string;
|
|
164
|
+
compiledShape: CompiledShapeBands;
|
|
165
|
+
measurer: TextMeasurer;
|
|
166
|
+
align?: 'left' | 'center';
|
|
167
|
+
baselineRatio?: number;
|
|
168
|
+
autoFill?: boolean;
|
|
169
|
+
} & ({
|
|
170
|
+
font: string;
|
|
171
|
+
textStyle?: TextStyleInput;
|
|
172
|
+
} | {
|
|
173
|
+
font?: string;
|
|
174
|
+
textStyle: TextStyleInput;
|
|
175
|
+
});
|
|
176
|
+
export type LayoutTextInShapeOptions = {
|
|
177
|
+
text: string;
|
|
178
|
+
lineHeight: number;
|
|
179
|
+
shape: ShapeInput;
|
|
180
|
+
measurer: TextMeasurer;
|
|
181
|
+
align?: 'left' | 'center';
|
|
182
|
+
minSlotWidth?: number;
|
|
183
|
+
baselineRatio?: number;
|
|
184
|
+
autoFill?: boolean;
|
|
185
|
+
} & ({
|
|
186
|
+
font: string;
|
|
187
|
+
textStyle?: TextStyleInput;
|
|
188
|
+
} | {
|
|
189
|
+
font?: string;
|
|
190
|
+
textStyle: TextStyleInput;
|
|
191
|
+
});
|
|
192
|
+
export type RenderLayoutToSvgOptions = {
|
|
193
|
+
padding?: number;
|
|
194
|
+
background?: string;
|
|
195
|
+
textFill?: string;
|
|
196
|
+
shapeStroke?: string;
|
|
197
|
+
shapeFill?: string;
|
|
198
|
+
shapeStyle?: ShapeStyleInput;
|
|
199
|
+
showShape?: boolean;
|
|
200
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shape-text",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Browser-first TypeScript library for shape-paragraph layout inside geometry and value-derived shapes, rendered to SVG.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/tqdat410/shape-text.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/tqdat410/shape-text/issues"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/tqdat410/shape-text#readme",
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18",
|
|
30
|
+
"bun": ">=1.0.0"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/run-library-build.mjs')\"",
|
|
39
|
+
"typecheck": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('node_modules/typescript/bin/tsc',['-p','tsconfig.json','--noEmit'])\"",
|
|
40
|
+
"test": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('node_modules/vitest/vitest.mjs',['run'])\"",
|
|
41
|
+
"test:coverage": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('node_modules/vitest/vitest.mjs',['run','--coverage'])\"",
|
|
42
|
+
"check": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/run-project-check.mjs')\"",
|
|
43
|
+
"e2e": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('node_modules/@playwright/test/cli.js',['test'])\"",
|
|
44
|
+
"e2e:ui": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('node_modules/@playwright/test/cli.js',['test','--ui'])\"",
|
|
45
|
+
"e2e:headed": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('node_modules/@playwright/test/cli.js',['test','--headed'])\"",
|
|
46
|
+
"e2e:debug": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('node_modules/@playwright/test/cli.js',['test','--debug'])\"",
|
|
47
|
+
"demo": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/run-demo-app.mjs')\"",
|
|
48
|
+
"demo:dev": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/run-demo-app.mjs')\"",
|
|
49
|
+
"demo:build": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/run-demo-app.mjs',['--build'])\"",
|
|
50
|
+
"demo:preview": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/run-demo-app.mjs',['--preview'])\"",
|
|
51
|
+
"prepack": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/run-library-build.mjs')\"",
|
|
52
|
+
"publish:npm": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/run-manual-npm-publish.mjs', process.argv.slice(1))\" --",
|
|
53
|
+
"ship:check": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/run-library-ship-check.mjs')\"",
|
|
54
|
+
"release:check-tag": "node -e \"const path=require('node:path');let pkg=process.env.npm_package_json||'';if(pkg.charCodeAt(0)===92&&pkg.charCodeAt(1)===92&&pkg.charCodeAt(2)===63&&pkg.charCodeAt(3)===92) pkg=pkg.slice(4);require(path.join(path.dirname(pkg),'scripts','run-node-script-from-package-root.cjs')).run('scripts/validate-release-tag.mjs', process.argv.slice(1))\""
|
|
55
|
+
},
|
|
56
|
+
"keywords": [
|
|
57
|
+
"svg",
|
|
58
|
+
"text-layout",
|
|
59
|
+
"shape-text",
|
|
60
|
+
"shape-paragraph",
|
|
61
|
+
"polygon",
|
|
62
|
+
"typography"
|
|
63
|
+
],
|
|
64
|
+
"author": "Admin",
|
|
65
|
+
"license": "MIT",
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@playwright/test": "^1.58.2",
|
|
68
|
+
"@types/node": "^25.5.0",
|
|
69
|
+
"@types/react": "^19.2.2",
|
|
70
|
+
"@types/react-dom": "^19.2.2",
|
|
71
|
+
"@vitejs/plugin-react": "^5.1.0",
|
|
72
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
73
|
+
"react": "^19.2.0",
|
|
74
|
+
"react-dom": "^19.2.0",
|
|
75
|
+
"typescript": "^5.9.3",
|
|
76
|
+
"vite": "^7.1.12",
|
|
77
|
+
"vitest": "^3.2.4"
|
|
78
|
+
}
|
|
79
|
+
}
|