@kensio/colophon 2.3.0 → 2.4.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/README.md +62 -801
- package/dist/background.d.ts +7 -2
- package/dist/background.d.ts.map +1 -1
- package/dist/background.js +44 -1
- package/dist/background.js.map +1 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/config.d.ts +1 -1
- package/dist/cli/config.js +1 -1
- package/dist/config/defaults.d.ts +8 -7
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +8 -8
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +5 -3
- package/dist/config/index.js.map +1 -1
- package/dist/config/resolve.d.ts +7 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +16 -0
- package/dist/config/resolve.js.map +1 -1
- package/dist/config/size.d.ts +1 -1
- package/dist/config/size.d.ts.map +1 -1
- package/dist/config/size.js +3 -2
- package/dist/config/size.js.map +1 -1
- package/dist/content/props.d.ts +2 -2
- package/dist/content/props.js +2 -2
- package/dist/content/slug.d.ts +5 -5
- package/dist/content/slug.js +6 -6
- package/dist/content/slug.js.map +1 -1
- package/dist/content/walk.d.ts +1 -1
- package/dist/content/walk.js +1 -1
- package/dist/fonts/index.d.ts +3 -2
- package/dist/fonts/index.d.ts.map +1 -1
- package/dist/fonts/index.js +3 -2
- package/dist/fonts/index.js.map +1 -1
- package/dist/fonts/resolve.js +1 -1
- package/dist/generate/extra.js +4 -4
- package/dist/generate/extra.js.map +1 -1
- package/dist/generate/options.d.ts +1 -1
- package/dist/generate/outputs.d.ts +4 -4
- package/dist/generate/outputs.js +4 -4
- package/dist/highlight/language.d.ts +2 -3
- package/dist/highlight/language.d.ts.map +1 -1
- package/dist/highlight/language.js +3 -4
- package/dist/highlight/language.js.map +1 -1
- package/dist/highlight/normalise.d.ts +2 -2
- package/dist/highlight/normalise.js +2 -2
- package/dist/image/index.d.ts +18 -0
- package/dist/image/index.d.ts.map +1 -0
- package/dist/image/index.js +42 -0
- package/dist/image/index.js.map +1 -0
- package/dist/image/jpeg.d.ts +10 -0
- package/dist/image/jpeg.d.ts.map +1 -0
- package/dist/image/jpeg.js +57 -0
- package/dist/image/jpeg.js.map +1 -0
- package/dist/image/load.d.ts +4 -0
- package/dist/image/load.d.ts.map +1 -0
- package/dist/image/load.js +60 -0
- package/dist/image/load.js.map +1 -0
- package/dist/image/media.d.ts +10 -0
- package/dist/image/media.d.ts.map +1 -0
- package/dist/image/media.js +37 -0
- package/dist/image/media.js.map +1 -0
- package/dist/image/resolve.d.ts +13 -0
- package/dist/image/resolve.d.ts.map +1 -0
- package/dist/image/resolve.js +38 -0
- package/dist/image/resolve.js.map +1 -0
- package/dist/image/size.d.ts +22 -0
- package/dist/image/size.d.ts.map +1 -0
- package/dist/image/size.js +60 -0
- package/dist/image/size.js.map +1 -0
- package/dist/image/svg.d.ts +12 -0
- package/dist/image/svg.d.ts.map +1 -0
- package/dist/image/svg.js +61 -0
- package/dist/image/svg.js.map +1 -0
- package/dist/image/uri.d.ts +9 -0
- package/dist/image/uri.d.ts.map +1 -0
- package/dist/image/uri.js +22 -0
- package/dist/image/uri.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/layout/block.d.ts +37 -0
- package/dist/layout/block.d.ts.map +1 -0
- package/dist/layout/block.js +26 -0
- package/dist/layout/block.js.map +1 -0
- package/dist/layout/box.d.ts +20 -0
- package/dist/layout/box.d.ts.map +1 -0
- package/dist/layout/box.js +61 -0
- package/dist/layout/box.js.map +1 -0
- package/dist/layout/distribute.d.ts +15 -0
- package/dist/layout/distribute.d.ts.map +1 -0
- package/dist/layout/distribute.js +30 -0
- package/dist/layout/distribute.js.map +1 -0
- package/dist/layout/image.d.ts +42 -0
- package/dist/layout/image.d.ts.map +1 -0
- package/dist/layout/image.js +34 -0
- package/dist/layout/image.js.map +1 -0
- package/dist/layout/index.d.ts +40 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +30 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/lines.d.ts +45 -0
- package/dist/layout/lines.d.ts.map +1 -0
- package/dist/layout/lines.js +71 -0
- package/dist/layout/lines.js.map +1 -0
- package/dist/layout/measure.d.ts +11 -0
- package/dist/layout/measure.d.ts.map +1 -0
- package/dist/layout/measure.js +11 -0
- package/dist/layout/measure.js.map +1 -0
- package/dist/layout/panel.d.ts +20 -0
- package/dist/layout/panel.d.ts.map +1 -0
- package/dist/layout/panel.js +22 -0
- package/dist/layout/panel.js.map +1 -0
- package/dist/layout/row.d.ts +15 -0
- package/dist/layout/row.d.ts.map +1 -0
- package/dist/layout/row.js +20 -0
- package/dist/layout/row.js.map +1 -0
- package/dist/layout/scrim.d.ts +23 -0
- package/dist/layout/scrim.d.ts.map +1 -0
- package/dist/layout/scrim.js +38 -0
- package/dist/layout/scrim.js.map +1 -0
- package/dist/layout/stack.d.ts +14 -0
- package/dist/layout/stack.d.ts.map +1 -0
- package/dist/layout/stack.js +19 -0
- package/dist/layout/stack.js.map +1 -0
- package/dist/layout/types.d.ts +49 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout/types.js +2 -0
- package/dist/layout/types.js.map +1 -0
- package/dist/manifest/build.d.ts +1 -1
- package/dist/manifest/build.js +1 -1
- package/dist/manifest/index.d.ts +1 -1
- package/dist/manifest/index.js +1 -1
- package/dist/manifest/order.d.ts +1 -1
- package/dist/manifest/order.js +1 -1
- package/dist/manifest/page.d.ts +2 -2
- package/dist/manifest/page.js +3 -3
- package/dist/measure/estimate.d.ts +10 -0
- package/dist/measure/estimate.d.ts.map +1 -0
- package/dist/measure/estimate.js +58 -0
- package/dist/measure/estimate.js.map +1 -0
- package/dist/measure/faces.d.ts +15 -0
- package/dist/measure/faces.d.ts.map +1 -0
- package/dist/measure/faces.js +70 -0
- package/dist/measure/faces.js.map +1 -0
- package/dist/measure/index.d.ts +16 -0
- package/dist/measure/index.d.ts.map +1 -0
- package/dist/measure/index.js +0 -0
- package/dist/measure/index.js.map +1 -0
- package/dist/measure/runs.d.ts +17 -0
- package/dist/measure/runs.d.ts.map +1 -0
- package/dist/measure/runs.js +39 -0
- package/dist/measure/runs.js.map +1 -0
- package/dist/measure/select.d.ts +13 -0
- package/dist/measure/select.d.ts.map +1 -0
- package/dist/measure/select.js +47 -0
- package/dist/measure/select.js.map +1 -0
- package/dist/meta/tags.d.ts +6 -6
- package/dist/meta/tags.js +6 -6
- package/dist/meta/url.d.ts +4 -4
- package/dist/meta/url.js +4 -4
- package/dist/placement/check.d.ts +1 -1
- package/dist/placement/check.js +1 -1
- package/dist/placement/index.js +1 -1
- package/dist/placement/relative.d.ts +3 -3
- package/dist/placement/relative.js +3 -3
- package/dist/pool.d.ts +2 -2
- package/dist/pool.js +3 -3
- package/dist/pool.js.map +1 -1
- package/dist/props.d.ts +7 -0
- package/dist/props.d.ts.map +1 -0
- package/dist/props.js +17 -0
- package/dist/props.js.map +1 -0
- package/dist/render/svg.d.ts +4 -2
- package/dist/render/svg.d.ts.map +1 -1
- package/dist/render/svg.js +19 -4
- package/dist/render/svg.js.map +1 -1
- package/dist/stamp/config-digest.d.ts.map +1 -1
- package/dist/stamp/config-digest.js +20 -1
- package/dist/stamp/config-digest.js.map +1 -1
- package/dist/stamp/index.js +2 -2
- package/dist/stamp/index.js.map +1 -1
- package/dist/stamp/read.d.ts +1 -1
- package/dist/stamp/read.js +4 -4
- package/dist/templates/attribution.d.ts +17 -0
- package/dist/templates/attribution.d.ts.map +1 -0
- package/dist/templates/attribution.js +39 -0
- package/dist/templates/attribution.js.map +1 -0
- package/dist/templates/banner/badge.d.ts.map +1 -1
- package/dist/templates/banner/badge.js +3 -6
- package/dist/templates/banner/badge.js.map +1 -1
- package/dist/templates/banner/index.d.ts +3 -0
- package/dist/templates/banner/index.d.ts.map +1 -1
- package/dist/templates/banner/index.js +37 -35
- package/dist/templates/banner/index.js.map +1 -1
- package/dist/templates/banner/lines.d.ts +7 -12
- package/dist/templates/banner/lines.d.ts.map +1 -1
- package/dist/templates/banner/lines.js +23 -34
- package/dist/templates/banner/lines.js.map +1 -1
- package/dist/templates/banner/version.d.ts +9 -0
- package/dist/templates/banner/version.d.ts.map +1 -0
- package/dist/templates/banner/version.js +21 -0
- package/dist/templates/banner/version.js.map +1 -0
- package/dist/templates/card/index.d.ts +4 -1
- package/dist/templates/card/index.d.ts.map +1 -1
- package/dist/templates/card/index.js +37 -25
- package/dist/templates/card/index.js.map +1 -1
- package/dist/templates/card/lines.d.ts +17 -13
- package/dist/templates/card/lines.d.ts.map +1 -1
- package/dist/templates/card/lines.js +24 -20
- package/dist/templates/card/lines.js.map +1 -1
- package/dist/templates/code/chrome.d.ts +7 -3
- package/dist/templates/code/chrome.d.ts.map +1 -1
- package/dist/templates/code/chrome.js +12 -11
- package/dist/templates/code/chrome.js.map +1 -1
- package/dist/templates/code/clip.d.ts +1 -1
- package/dist/templates/code/clip.js +1 -1
- package/dist/templates/code/fit.d.ts +2 -2
- package/dist/templates/code/fit.d.ts.map +1 -1
- package/dist/templates/code/fit.js +4 -4
- package/dist/templates/code/fit.js.map +1 -1
- package/dist/templates/code/index.d.ts.map +1 -1
- package/dist/templates/code/index.js +7 -6
- package/dist/templates/code/index.js.map +1 -1
- package/dist/templates/code/layout.d.ts +1 -1
- package/dist/templates/code/layout.d.ts.map +1 -1
- package/dist/templates/code/layout.js +6 -6
- package/dist/templates/code/layout.js.map +1 -1
- package/dist/templates/code/panel.d.ts +13 -0
- package/dist/templates/code/panel.d.ts.map +1 -1
- package/dist/templates/code/panel.js +34 -2
- package/dist/templates/code/panel.js.map +1 -1
- package/dist/templates/code/plate.d.ts +3 -1
- package/dist/templates/code/plate.d.ts.map +1 -1
- package/dist/templates/code/plate.js +11 -9
- package/dist/templates/code/plate.js.map +1 -1
- package/dist/templates/code/spans.js +1 -1
- package/dist/templates/code/spans.js.map +1 -1
- package/dist/templates/code/width.d.ts +10 -0
- package/dist/templates/code/width.d.ts.map +1 -0
- package/dist/templates/code/width.js +26 -0
- package/dist/templates/code/width.js.map +1 -0
- package/dist/templates/footer.d.ts +8 -0
- package/dist/templates/footer.d.ts.map +1 -1
- package/dist/templates/footer.js +11 -1
- package/dist/templates/footer.js.map +1 -1
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +1 -1
- package/dist/templates/index.js.map +1 -1
- package/dist/templates/logo.d.ts +15 -0
- package/dist/templates/logo.d.ts.map +1 -0
- package/dist/templates/logo.js +30 -0
- package/dist/templates/logo.js.map +1 -0
- package/dist/templates/measure.d.ts +11 -0
- package/dist/templates/measure.d.ts.map +1 -0
- package/dist/templates/measure.js +11 -0
- package/dist/templates/measure.js.map +1 -0
- package/dist/templates/props.d.ts +2 -2
- package/dist/templates/props.js +2 -2
- package/dist/templates/text.d.ts +37 -0
- package/dist/templates/text.d.ts.map +1 -0
- package/dist/templates/text.js +26 -0
- package/dist/templates/text.js.map +1 -0
- package/dist/text/break.d.ts +11 -0
- package/dist/text/break.d.ts.map +1 -0
- package/dist/text/break.js +30 -0
- package/dist/text/break.js.map +1 -0
- package/dist/text/fit.d.ts +30 -0
- package/dist/text/fit.d.ts.map +1 -0
- package/dist/text/fit.js +29 -0
- package/dist/text/fit.js.map +1 -0
- package/dist/text/index.d.ts +5 -3
- package/dist/text/index.d.ts.map +1 -1
- package/dist/text/index.js +3 -2
- package/dist/text/index.js.map +1 -1
- package/dist/text/wrap.d.ts +17 -7
- package/dist/text/wrap.d.ts.map +1 -1
- package/dist/text/wrap.js +25 -17
- package/dist/text/wrap.js.map +1 -1
- package/dist/types.d.ts +161 -45
- package/dist/types.d.ts.map +1 -1
- package/dist/validate/index.d.ts +1 -1
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +3 -2
- package/dist/validate/index.js.map +1 -1
- package/dist/validate/keys.d.ts +19 -2
- package/dist/validate/keys.d.ts.map +1 -1
- package/dist/validate/keys.js +40 -3
- package/dist/validate/keys.js.map +1 -1
- package/dist/validate/suggest.d.ts.map +1 -1
- package/dist/validate/suggest.js +21 -3
- package/dist/validate/suggest.js.map +1 -1
- package/dist/validate/values.d.ts +2 -2
- package/dist/validate/values.d.ts.map +1 -1
- package/dist/validate/values.js +17 -3
- package/dist/validate/values.js.map +1 -1
- package/package.json +7 -1
|
@@ -2,8 +2,8 @@ import type { RenderJob } from "./job.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Reject a manifest written over one of the images it describes.
|
|
4
4
|
*
|
|
5
|
-
* The manifest is written last, so it wins: the image is replaced by JSON,
|
|
6
|
-
*
|
|
5
|
+
* The manifest is written last, so it wins: the image is replaced by JSON,
|
|
6
|
+
* losing its stamp with it, and rendered again on every build afterwards. It is
|
|
7
7
|
* the same collision as two images sharing a path, so it is answered here,
|
|
8
8
|
* where a path is already compared the way the filesystem would.
|
|
9
9
|
*/
|
|
@@ -16,8 +16,8 @@ export declare function assertManifestIsNotAnImage(manifestPath: string | undefi
|
|
|
16
16
|
* renders both again, for ever.
|
|
17
17
|
*
|
|
18
18
|
* Every job is checked, posts included. That used to be older ground worth
|
|
19
|
-
* leaving alone
|
|
20
|
-
* slug
|
|
19
|
+
* leaving alone, since two posts collided only if they shared a directory and
|
|
20
|
+
* a slug. But `public-dir` gathers a whole tree into one directory, where every
|
|
21
21
|
* post sharing a basename with another lands on it. Naming both sides is what
|
|
22
22
|
* makes that worth reporting: the path alone does not say which two posts.
|
|
23
23
|
*
|
package/dist/generate/outputs.js
CHANGED
|
@@ -22,8 +22,8 @@ function describe(job) {
|
|
|
22
22
|
/**
|
|
23
23
|
* Reject a manifest written over one of the images it describes.
|
|
24
24
|
*
|
|
25
|
-
* The manifest is written last, so it wins: the image is replaced by JSON,
|
|
26
|
-
*
|
|
25
|
+
* The manifest is written last, so it wins: the image is replaced by JSON,
|
|
26
|
+
* losing its stamp with it, and rendered again on every build afterwards. It is
|
|
27
27
|
* the same collision as two images sharing a path, so it is answered here,
|
|
28
28
|
* where a path is already compared the way the filesystem would.
|
|
29
29
|
*/
|
|
@@ -47,8 +47,8 @@ export function assertManifestIsNotAnImage(manifestPath, jobs) {
|
|
|
47
47
|
* renders both again, for ever.
|
|
48
48
|
*
|
|
49
49
|
* Every job is checked, posts included. That used to be older ground worth
|
|
50
|
-
* leaving alone
|
|
51
|
-
* slug
|
|
50
|
+
* leaving alone, since two posts collided only if they shared a directory and
|
|
51
|
+
* a slug. But `public-dir` gathers a whole tree into one directory, where every
|
|
52
52
|
* post sharing a basename with another lands on it. Naming both sides is what
|
|
53
53
|
* makes that worth reporting: the path alone does not say which two posts.
|
|
54
54
|
*
|
|
@@ -6,9 +6,8 @@ import type { BundledLanguage, BundledTheme, SpecialLanguage } from "shiki";
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function resolveLanguage(language: string): BundledLanguage | SpecialLanguage;
|
|
8
8
|
/**
|
|
9
|
-
* Validate a configured theme name.
|
|
10
|
-
*
|
|
11
|
-
* failing on.
|
|
9
|
+
* Validate a configured theme name. Languages come from post frontmatter and
|
|
10
|
+
* fall back quietly, but a bad theme is a config mistake worth failing on.
|
|
12
11
|
*/
|
|
13
12
|
export declare function resolveTheme(theme: string): BundledTheme;
|
|
14
13
|
//# sourceMappingURL=language.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/highlight/language.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAsB5E;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,GACf,eAAe,GAAG,eAAe,CAOnC;AAED
|
|
1
|
+
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/highlight/language.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAsB5E;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,GACf,eAAe,GAAG,eAAe,CAOnC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAQxD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { bundledLanguages, bundledThemes } from "shiki";
|
|
2
2
|
/**
|
|
3
3
|
* Language names that differ between Pygments (which the original Python
|
|
4
|
-
* script used) and Shiki. Everything else is passed through
|
|
4
|
+
* script used) and Shiki. Everything else is passed through, since Shiki
|
|
5
5
|
* understands `bash`, `python`, `typescript`, `yaml`, `toml`, `sql`, `json`,
|
|
6
6
|
* `js` and `text`.
|
|
7
7
|
*/
|
|
@@ -29,9 +29,8 @@ export function resolveLanguage(language) {
|
|
|
29
29
|
: plainText;
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
|
-
* Validate a configured theme name.
|
|
33
|
-
*
|
|
34
|
-
* failing on.
|
|
32
|
+
* Validate a configured theme name. Languages come from post frontmatter and
|
|
33
|
+
* fall back quietly, but a bad theme is a config mistake worth failing on.
|
|
35
34
|
*/
|
|
36
35
|
export function resolveTheme(theme) {
|
|
37
36
|
if (!Object.hasOwn(bundledThemes, theme)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"language.js","sourceRoot":"","sources":["../../src/highlight/language.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAExD;;;;;GAKG;AACH,MAAM,eAAe,GAAgC,IAAI,GAAG,CAAC;IAC3D,CAAC,iBAAiB,EAAE,YAAY,CAAC;IACjC,CAAC,aAAa,EAAE,YAAY,CAAC;IAC7B,CAAC,YAAY,EAAE,YAAY,CAAC;IAC5B,CAAC,UAAU,EAAE,KAAK,CAAC;IACnB,CAAC,SAAS,EAAE,cAAc,CAAC;IAC3B,CAAC,eAAe,EAAE,cAAc,CAAC;IACjC,CAAC,MAAM,EAAE,WAAW,CAAC;IACrB,CAAC,OAAO,EAAE,WAAW,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,SAAS,GAAoB,WAAW,CAAC;AAE/C;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB;IAEhB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjD,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;IAE9D,OAAO,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,OAAO,CAAC;QAC7C,CAAC,CAAE,OAA2B;QAC9B,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"language.js","sourceRoot":"","sources":["../../src/highlight/language.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAExD;;;;;GAKG;AACH,MAAM,eAAe,GAAgC,IAAI,GAAG,CAAC;IAC3D,CAAC,iBAAiB,EAAE,YAAY,CAAC;IACjC,CAAC,aAAa,EAAE,YAAY,CAAC;IAC7B,CAAC,YAAY,EAAE,YAAY,CAAC;IAC5B,CAAC,UAAU,EAAE,KAAK,CAAC;IACnB,CAAC,SAAS,EAAE,cAAc,CAAC;IAC3B,CAAC,eAAe,EAAE,cAAc,CAAC;IACjC,CAAC,MAAM,EAAE,WAAW,CAAC;IACrB,CAAC,OAAO,EAAE,WAAW,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,SAAS,GAAoB,WAAW,CAAC;AAE/C;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB;IAEhB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjD,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;IAE9D,OAAO,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,OAAO,CAAC;QAC7C,CAAC,CAAE,OAA2B;QAC9B,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CACb,uBAAuB,KAAK,4DAA4D,CACzF,CAAC;IACJ,CAAC;IAED,OAAO,KAAqB,CAAC;AAC/B,CAAC"}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
export declare function expandTabs(text: string, tabSize: number): string;
|
|
5
5
|
/**
|
|
6
6
|
* Strip the indentation common to every non-blank line. A snippet lifted out
|
|
7
|
-
* of a nested block would otherwise spend its width
|
|
8
|
-
* the landscape sizes
|
|
7
|
+
* of a nested block would otherwise spend its width, the scarce dimension on
|
|
8
|
+
* the landscape sizes, on indentation that carries no meaning once the
|
|
9
9
|
* surrounding code is gone.
|
|
10
10
|
*/
|
|
11
11
|
export declare function dedent(text: string): string;
|
|
@@ -7,8 +7,8 @@ export function expandTabs(text, tabSize) {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Strip the indentation common to every non-blank line. A snippet lifted out
|
|
10
|
-
* of a nested block would otherwise spend its width
|
|
11
|
-
* the landscape sizes
|
|
10
|
+
* of a nested block would otherwise spend its width, the scarce dimension on
|
|
11
|
+
* the landscape sizes, on indentation that carries no meaning once the
|
|
12
12
|
* surrounding code is gone.
|
|
13
13
|
*/
|
|
14
14
|
export function dedent(text) {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ImageAsset, MetaImageProps, ResolvedConfig } from "../types.js";
|
|
2
|
+
export { loadImage } from "./load.js";
|
|
3
|
+
export { resolveImageSource, resolveOptionalImage } from "./resolve.js";
|
|
4
|
+
/** Every image one rendering needs, loaded and ready to draw. */
|
|
5
|
+
export interface LoadedImages {
|
|
6
|
+
readonly logo: ImageAsset | undefined;
|
|
7
|
+
readonly avatar: ImageAsset | undefined;
|
|
8
|
+
readonly background: ImageAsset | undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Load the logo, the background photo and the post's avatar for one image.
|
|
12
|
+
*
|
|
13
|
+
* Reading files is the renderer's job rather than the template's. A template
|
|
14
|
+
* stays a synchronous function over values it was handed, and the bytes of a
|
|
15
|
+
* logo are read once for a whole build rather than once per image.
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadImages(config: ResolvedConfig, props: MetaImageProps): Promise<LoadedImages>;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/image/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAExE,iEAAiE;AACjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC;CAC7C;AAgCD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,YAAY,CAAC,CAWvB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { loadImage } from "./load.js";
|
|
2
|
+
import { resolveImageSource } from "./resolve.js";
|
|
3
|
+
import { bytesFromDataUri } from "./uri.js";
|
|
4
|
+
export { loadImage } from "./load.js";
|
|
5
|
+
export { resolveImageSource, resolveOptionalImage } from "./resolve.js";
|
|
6
|
+
/**
|
|
7
|
+
* Load an image named by a prop, which is a `data:` URI or a path to a file.
|
|
8
|
+
*
|
|
9
|
+
* A path is resolved from the working directory, as `fonts` and `logo` are.
|
|
10
|
+
* Resolving it against the post instead would be friendlier for a page bundle
|
|
11
|
+
* and wrong for everything else, and a build has one working directory but
|
|
12
|
+
* many content directories.
|
|
13
|
+
*/
|
|
14
|
+
async function loadProp(value, label) {
|
|
15
|
+
if (value === undefined || value === "") {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const source = value.startsWith("data:")
|
|
19
|
+
? { data: bytesFromDataUri(value, label) }
|
|
20
|
+
: resolveImageSource({ path: value }, label);
|
|
21
|
+
return loadImage(source, label);
|
|
22
|
+
}
|
|
23
|
+
async function loadOptional(source, label) {
|
|
24
|
+
return source === undefined ? undefined : loadImage(source, label);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Load the logo, the background photo and the post's avatar for one image.
|
|
28
|
+
*
|
|
29
|
+
* Reading files is the renderer's job rather than the template's. A template
|
|
30
|
+
* stays a synchronous function over values it was handed, and the bytes of a
|
|
31
|
+
* logo are read once for a whole build rather than once per image.
|
|
32
|
+
*/
|
|
33
|
+
export async function loadImages(config, props) {
|
|
34
|
+
const background = config.background.type === "image" ? config.background.source : undefined;
|
|
35
|
+
const [logo, avatar, backgroundImage] = await Promise.all([
|
|
36
|
+
loadOptional(config.logo, "logo"),
|
|
37
|
+
loadProp(props.avatar, "props.avatar"),
|
|
38
|
+
loadOptional(background, "background.source"),
|
|
39
|
+
]);
|
|
40
|
+
return { logo, avatar, background: backgroundImage };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/image/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AASxE;;;;;;;GAOG;AACH,KAAK,UAAU,QAAQ,CACrB,KAAyB,EACzB,KAAa;IAEb,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACxC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAgB,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;QACnD,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE;QAC1C,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;IAE/C,OAAO,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,MAA+B,EAC/B,KAAa;IAEb,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAsB,EACtB,KAAqB;IAErB,MAAM,UAAU,GACd,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAE5E,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACxD,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;QACjC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC;QACtC,YAAY,CAAC,UAAU,EAAE,mBAAmB,CAAC;KAC9C,CAAC,CAAC;IAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Extent } from "./size.js";
|
|
2
|
+
/**
|
|
3
|
+
* The dimensions of a JPEG, by walking its segments to the frame header.
|
|
4
|
+
*
|
|
5
|
+
* Unlike every other format here, a JPEG does not state its size at a fixed
|
|
6
|
+
* offset: the frame header comes after however many comment, quantisation and
|
|
7
|
+
* application segments the encoder felt like writing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function jpegExtent(bytes: Uint8Array): Extent | undefined;
|
|
10
|
+
//# sourceMappingURL=jpeg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jpeg.d.ts","sourceRoot":"","sources":["../../src/image/jpeg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAkBxC;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CA2ChE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Markers that carry no payload, so nothing follows them to skip over. */
|
|
2
|
+
const standalone = new Set([0xd8, 0xd9, 0x01]);
|
|
3
|
+
/** The frame headers, which are the segments that state the image size. */
|
|
4
|
+
function isFrameHeader(marker) {
|
|
5
|
+
// 0xC4, 0xC8 and 0xCC sit in the same range and are tables rather than
|
|
6
|
+
// frames, which is the whole subtlety of reading a JPEG header.
|
|
7
|
+
return (marker >= 0xc0 &&
|
|
8
|
+
marker <= 0xcf &&
|
|
9
|
+
marker !== 0xc4 &&
|
|
10
|
+
marker !== 0xc8 &&
|
|
11
|
+
marker !== 0xcc);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The dimensions of a JPEG, by walking its segments to the frame header.
|
|
15
|
+
*
|
|
16
|
+
* Unlike every other format here, a JPEG does not state its size at a fixed
|
|
17
|
+
* offset: the frame header comes after however many comment, quantisation and
|
|
18
|
+
* application segments the encoder felt like writing.
|
|
19
|
+
*/
|
|
20
|
+
export function jpegExtent(bytes) {
|
|
21
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
22
|
+
let offset = 2;
|
|
23
|
+
while (offset + 4 < bytes.length) {
|
|
24
|
+
if (bytes[offset] !== 0xff) {
|
|
25
|
+
// Anything between segments is skipped a byte at a time rather than
|
|
26
|
+
// read as a length, since a length taken from the middle of one would
|
|
27
|
+
// jump somewhere arbitrary.
|
|
28
|
+
offset += 1;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const marker = bytes[offset + 1] ?? 0;
|
|
32
|
+
if (marker === 0xff) {
|
|
33
|
+
// A marker may be preceded by any number of `0xff` fill bytes, so this
|
|
34
|
+
// is the first of them rather than a marker of its own.
|
|
35
|
+
offset += 1;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (standalone.has(marker)) {
|
|
39
|
+
offset += 2;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (isFrameHeader(marker)) {
|
|
43
|
+
// The dimensions run to offset + 8, further than the loop guarantees, so
|
|
44
|
+
// a file truncated inside its own frame header is unmeasurable rather
|
|
45
|
+
// than a read past the end of the buffer.
|
|
46
|
+
return offset + 8 < bytes.length
|
|
47
|
+
? {
|
|
48
|
+
width: view.getUint16(offset + 7),
|
|
49
|
+
height: view.getUint16(offset + 5),
|
|
50
|
+
}
|
|
51
|
+
: undefined;
|
|
52
|
+
}
|
|
53
|
+
offset += 2 + view.getUint16(offset + 2);
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=jpeg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jpeg.js","sourceRoot":"","sources":["../../src/image/jpeg.ts"],"names":[],"mappings":"AAEA,2EAA2E;AAC3E,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAE/C,2EAA2E;AAC3E,SAAS,aAAa,CAAC,MAAc;IACnC,uEAAuE;IACvE,gEAAgE;IAChE,OAAO,CACL,MAAM,IAAI,IAAI;QACd,MAAM,IAAI,IAAI;QACd,MAAM,KAAK,IAAI;QACf,MAAM,KAAK,IAAI;QACf,MAAM,KAAK,IAAI,CAChB,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5E,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,OAAO,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3B,oEAAoE;YACpE,sEAAsE;YACtE,4BAA4B;YAC5B,MAAM,IAAI,CAAC,CAAC;YACZ,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QAEtC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,uEAAuE;YACvE,wDAAwD;YACxD,MAAM,IAAI,CAAC,CAAC;YACZ,SAAS;QACX,CAAC;QAED,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,CAAC;YACZ,SAAS;QACX,CAAC;QAED,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,yEAAyE;YACzE,sEAAsE;YACtE,0CAA0C;YAC1C,OAAO,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM;gBAC9B,CAAC,CAAC;oBACE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;iBACnC;gBACH,CAAC,CAAC,SAAS,CAAC;QAChB,CAAC;QAED,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/image/load.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA8D3D,6EAA6E;AAC7E,wBAAgB,SAAS,CACvB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,CAUrB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { sniffMediaType } from "./media.js";
|
|
3
|
+
import { aspectOf } from "./size.js";
|
|
4
|
+
/**
|
|
5
|
+
* Loaded images, keyed by the path they were read from. A build draws the same
|
|
6
|
+
* logo onto every image it generates, and the bytes are the largest thing in
|
|
7
|
+
* the SVG, so reading and encoding it once matters more here than it does for
|
|
8
|
+
* a font.
|
|
9
|
+
*/
|
|
10
|
+
const byPath = new Map();
|
|
11
|
+
/** The same for images given as bytes, keyed by the array itself. */
|
|
12
|
+
const byData = new WeakMap();
|
|
13
|
+
/**
|
|
14
|
+
* `Uint8Array.toBase64` reads better and is not on the oldest Node this
|
|
15
|
+
* package supports, so the encoding goes through a Buffer.
|
|
16
|
+
*/
|
|
17
|
+
function base64(bytes) {
|
|
18
|
+
// eslint-disable-next-line unicorn/prefer-uint8array-base64
|
|
19
|
+
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Turn bytes into something drawable: a `data:` URI and the proportions of the
|
|
23
|
+
* picture inside it.
|
|
24
|
+
*
|
|
25
|
+
* Inlining rather than referencing the file is what makes a generated image
|
|
26
|
+
* self-contained. The rasteriser would have to resolve a relative href against
|
|
27
|
+
* something, and there is nothing sensible to resolve it against when the SVG
|
|
28
|
+
* only ever exists in memory.
|
|
29
|
+
*/
|
|
30
|
+
function toAsset(bytes, label) {
|
|
31
|
+
const mediaType = sniffMediaType(bytes);
|
|
32
|
+
if (mediaType === undefined) {
|
|
33
|
+
throw new Error(`${label} is not an image this can read. PNG, JPEG, GIF, WebP and SVG` +
|
|
34
|
+
` are understood, and the bytes given match none of them.`);
|
|
35
|
+
}
|
|
36
|
+
// `Uint8Array.toBase64` would read better and does not exist on the oldest
|
|
37
|
+
// Node this package supports.
|
|
38
|
+
return {
|
|
39
|
+
href: `data:${mediaType};base64,${base64(bytes)}`,
|
|
40
|
+
aspect: aspectOf(bytes, mediaType) ?? 1,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
async function read(source, label) {
|
|
44
|
+
const bytes = "data" in source
|
|
45
|
+
? source.data
|
|
46
|
+
: new Uint8Array(await readFile(source.path));
|
|
47
|
+
return toAsset(bytes, label);
|
|
48
|
+
}
|
|
49
|
+
/** Load one image source, reusing the bytes across the images of a build. */
|
|
50
|
+
export function loadImage(source, label) {
|
|
51
|
+
if ("data" in source) {
|
|
52
|
+
const pending = byData.get(source.data) ?? read(source, label);
|
|
53
|
+
byData.set(source.data, pending);
|
|
54
|
+
return pending;
|
|
55
|
+
}
|
|
56
|
+
const pending = byPath.get(source.path) ?? read(source, label);
|
|
57
|
+
byPath.set(source.path, pending);
|
|
58
|
+
return pending;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/image/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC;;;;;GAKG;AACH,MAAM,MAAM,GAAG,IAAI,GAAG,EAA+B,CAAC;AAEtD,qEAAqE;AACrE,MAAM,MAAM,GAAG,IAAI,OAAO,EAAmC,CAAC;AAE9D;;;GAGG;AACH,SAAS,MAAM,CAAC,KAAiB;IAC/B,4DAA4D;IAC5D,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,QAAQ,CAC3E,QAAQ,CACT,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,OAAO,CAAC,KAAiB,EAAE,KAAa;IAC/C,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAExC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,8DAA8D;YACpE,0DAA0D,CAC7D,CAAC;IACJ,CAAC;IAED,2EAA2E;IAC3E,8BAA8B;IAC9B,OAAO;QACL,IAAI,EAAE,QAAQ,SAAS,WAAW,MAAM,CAAC,KAAK,CAAC,EAAE;QACjD,MAAM,EAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,MAAmB,EAAE,KAAa;IACpD,MAAM,KAAK,GACT,MAAM,IAAI,MAAM;QACd,CAAC,CAAC,MAAM,CAAC,IAAI;QACb,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAElD,OAAO,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,SAAS,CACvB,MAAmB,EACnB,KAAa;IAEb,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;QACrB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC/D,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The image formats a build can draw with. */
|
|
2
|
+
export type MediaType = "image/png" | "image/jpeg" | "image/gif" | "image/webp" | "image/svg+xml";
|
|
3
|
+
/**
|
|
4
|
+
* The format of some bytes, read from the bytes themselves rather than from
|
|
5
|
+
* the file extension. A file named `.png` that is really a JPEG renders either
|
|
6
|
+
* way once the `data:` URI says what it is, and a rename is not the sort of
|
|
7
|
+
* thing a build should fail over.
|
|
8
|
+
*/
|
|
9
|
+
export declare function sniffMediaType(bytes: Uint8Array): MediaType | undefined;
|
|
10
|
+
//# sourceMappingURL=media.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/image/media.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,MAAM,MAAM,SAAS,GACnB,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,GAAG,eAAe,CAAC;AAmB5E;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,CAkBvE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
function hasSignature(bytes, signature) {
|
|
2
|
+
return signature.every((byte, index) => bytes[index] === byte);
|
|
3
|
+
}
|
|
4
|
+
/** Whether the bytes at `offset` spell `text` in ASCII. */
|
|
5
|
+
function hasAscii(bytes, offset, text) {
|
|
6
|
+
return Array.from(text, (character, index) => [character, index]).every(([character, index]) => bytes[offset + index] === character.codePointAt(0));
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The format of some bytes, read from the bytes themselves rather than from
|
|
10
|
+
* the file extension. A file named `.png` that is really a JPEG renders either
|
|
11
|
+
* way once the `data:` URI says what it is, and a rename is not the sort of
|
|
12
|
+
* thing a build should fail over.
|
|
13
|
+
*/
|
|
14
|
+
export function sniffMediaType(bytes) {
|
|
15
|
+
if (hasSignature(bytes, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) {
|
|
16
|
+
return "image/png";
|
|
17
|
+
}
|
|
18
|
+
if (hasSignature(bytes, [0xff, 0xd8, 0xff])) {
|
|
19
|
+
return "image/jpeg";
|
|
20
|
+
}
|
|
21
|
+
if (hasAscii(bytes, 0, "GIF8")) {
|
|
22
|
+
return "image/gif";
|
|
23
|
+
}
|
|
24
|
+
if (hasAscii(bytes, 0, "RIFF") && hasAscii(bytes, 8, "WEBP")) {
|
|
25
|
+
return "image/webp";
|
|
26
|
+
}
|
|
27
|
+
return isSvg(bytes) ? "image/svg+xml" : undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* SVG is text, so it has no signature to match. Look for the opening tag in
|
|
31
|
+
* the first stretch of the file, past any declaration, doctype or comment.
|
|
32
|
+
*/
|
|
33
|
+
function isSvg(bytes) {
|
|
34
|
+
const head = new TextDecoder().decode(bytes.slice(0, 1024));
|
|
35
|
+
return /<svg[\s>]/i.test(head);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/image/media.ts"],"names":[],"mappings":"AAIA,SAAS,YAAY,CACnB,KAAiB,EACjB,SAA4B;IAE5B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,2DAA2D;AAC3D,SAAS,QAAQ,CAAC,KAAiB,EAAE,MAAc,EAAE,IAAY;IAC/D,OAAO,KAAK,CAAC,IAAI,CACf,IAAI,EACJ,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,CAAU,CAClD,CAAC,KAAK,CACL,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAiB;IAC9C,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5C,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;QAC7D,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,SAAS,KAAK,CAAC,KAAiB;IAC9B,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5D,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ImageSource } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validate one image source and make its path absolute.
|
|
4
|
+
*
|
|
5
|
+
* Checked when the config is resolved rather than when the image is drawn, for
|
|
6
|
+
* the reason `fonts/resolve.ts` gives: an image that cannot be read is a blank
|
|
7
|
+
* corner on every generated file, and a blank corner does not say which path
|
|
8
|
+
* was wrong.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveImageSource(source: ImageSource, label: string): ImageSource;
|
|
11
|
+
/** The same for a source that may not be there at all. */
|
|
12
|
+
export declare function resolveOptionalImage(source: ImageSource | undefined, label: string): ImageSource | undefined;
|
|
13
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/image/resolve.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,GACZ,WAAW,CAsCb;AAED,0DAA0D;AAC1D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,GACZ,WAAW,GAAG,SAAS,CAEzB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { existsSync, statSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Validate one image source and make its path absolute.
|
|
5
|
+
*
|
|
6
|
+
* Checked when the config is resolved rather than when the image is drawn, for
|
|
7
|
+
* the reason `fonts/resolve.ts` gives: an image that cannot be read is a blank
|
|
8
|
+
* corner on every generated file, and a blank corner does not say which path
|
|
9
|
+
* was wrong.
|
|
10
|
+
*/
|
|
11
|
+
export function resolveImageSource(source, label) {
|
|
12
|
+
const raw = source;
|
|
13
|
+
const hasPath = raw.path !== undefined;
|
|
14
|
+
const hasData = raw.data !== undefined;
|
|
15
|
+
if (hasPath && hasData) {
|
|
16
|
+
throw new Error(`${label} has both "path" and "data"; give one or the other.`);
|
|
17
|
+
}
|
|
18
|
+
if (raw.data !== undefined) {
|
|
19
|
+
if (raw.data.byteLength === 0) {
|
|
20
|
+
throw new Error(`${label} has empty image data.`);
|
|
21
|
+
}
|
|
22
|
+
return source;
|
|
23
|
+
}
|
|
24
|
+
if (raw.path === undefined || raw.path === "") {
|
|
25
|
+
throw new Error(`${label} needs a "path" to an image file, or its bytes as "data".`);
|
|
26
|
+
}
|
|
27
|
+
const absolute = path.resolve(raw.path);
|
|
28
|
+
if (!existsSync(absolute) || !statSync(absolute).isFile()) {
|
|
29
|
+
throw new Error(`${label}: image file not found at ${absolute} (from "${raw.path}").` +
|
|
30
|
+
` Relative paths resolve from the working directory.`);
|
|
31
|
+
}
|
|
32
|
+
return { path: absolute };
|
|
33
|
+
}
|
|
34
|
+
/** The same for a source that may not be there at all. */
|
|
35
|
+
export function resolveOptionalImage(source, label) {
|
|
36
|
+
return source === undefined ? undefined : resolveImageSource(source, label);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/image/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAmB,EACnB,KAAa;IAEb,MAAM,GAAG,GAAG,MAGX,CAAC;IACF,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC;IACvC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC;IAEvC,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,qDAAqD,CAC9D,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,wBAAwB,CAAC,CAAC;QACpD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,2DAA2D,CACpE,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAExC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,6BAA6B,QAAQ,WAAW,GAAG,CAAC,IAAI,KAAK;YACnE,qDAAqD,CACxD,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,oBAAoB,CAClC,MAA+B,EAC/B,KAAa;IAEb,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { MediaType } from "./media.js";
|
|
2
|
+
/** How big an image is, in whatever units it states for itself. */
|
|
3
|
+
export interface Extent {
|
|
4
|
+
readonly width: number;
|
|
5
|
+
readonly height: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* How wide an image is against how tall, or `undefined` where the format does
|
|
9
|
+
* not say in any way this reads.
|
|
10
|
+
*
|
|
11
|
+
* Only the ratio is wanted. A template sizes a logo from the image it is
|
|
12
|
+
* drawing into rather than from the logo's own pixels, since the same logo has
|
|
13
|
+
* to work on a 1200x630 and a 1200x1200, and the ratio is what stops it being
|
|
14
|
+
* stretched or given a square of space it does not fill.
|
|
15
|
+
*
|
|
16
|
+
* WebP is deliberately absent. Its dimensions live in one of three different
|
|
17
|
+
* chunk layouts depending on how it was encoded, and a logo is a PNG or an SVG
|
|
18
|
+
* often enough that guessing at bit-packed headers is not worth the risk of
|
|
19
|
+
* getting one of them subtly wrong.
|
|
20
|
+
*/
|
|
21
|
+
export declare function aspectOf(bytes: Uint8Array, mediaType: MediaType): number | undefined;
|
|
22
|
+
//# sourceMappingURL=size.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"size.d.ts","sourceRoot":"","sources":["../../src/image/size.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,mEAAmE;AACnE,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAuBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,SAAS,GACnB,MAAM,GAAG,SAAS,CAMpB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jpegExtent } from "./jpeg.js";
|
|
2
|
+
import { svgExtent } from "./svg.js";
|
|
3
|
+
function view(bytes) {
|
|
4
|
+
return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
5
|
+
}
|
|
6
|
+
/** PNG states its size in the IHDR chunk, which is always the first one. */
|
|
7
|
+
function pngExtent(bytes) {
|
|
8
|
+
return bytes.length < 24
|
|
9
|
+
? undefined
|
|
10
|
+
: { width: view(bytes).getUint32(16), height: view(bytes).getUint32(20) };
|
|
11
|
+
}
|
|
12
|
+
/** GIF states its screen size in the header, little-endian. */
|
|
13
|
+
function gifExtent(bytes) {
|
|
14
|
+
return bytes.length < 10
|
|
15
|
+
? undefined
|
|
16
|
+
: {
|
|
17
|
+
width: view(bytes).getUint16(6, true),
|
|
18
|
+
height: view(bytes).getUint16(8, true),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* How wide an image is against how tall, or `undefined` where the format does
|
|
23
|
+
* not say in any way this reads.
|
|
24
|
+
*
|
|
25
|
+
* Only the ratio is wanted. A template sizes a logo from the image it is
|
|
26
|
+
* drawing into rather than from the logo's own pixels, since the same logo has
|
|
27
|
+
* to work on a 1200x630 and a 1200x1200, and the ratio is what stops it being
|
|
28
|
+
* stretched or given a square of space it does not fill.
|
|
29
|
+
*
|
|
30
|
+
* WebP is deliberately absent. Its dimensions live in one of three different
|
|
31
|
+
* chunk layouts depending on how it was encoded, and a logo is a PNG or an SVG
|
|
32
|
+
* often enough that guessing at bit-packed headers is not worth the risk of
|
|
33
|
+
* getting one of them subtly wrong.
|
|
34
|
+
*/
|
|
35
|
+
export function aspectOf(bytes, mediaType) {
|
|
36
|
+
const extent = extentOf(bytes, mediaType);
|
|
37
|
+
return extent === undefined || extent.height <= 0
|
|
38
|
+
? undefined
|
|
39
|
+
: extent.width / extent.height;
|
|
40
|
+
}
|
|
41
|
+
function extentOf(bytes, mediaType) {
|
|
42
|
+
switch (mediaType) {
|
|
43
|
+
case "image/png": {
|
|
44
|
+
return pngExtent(bytes);
|
|
45
|
+
}
|
|
46
|
+
case "image/gif": {
|
|
47
|
+
return gifExtent(bytes);
|
|
48
|
+
}
|
|
49
|
+
case "image/jpeg": {
|
|
50
|
+
return jpegExtent(bytes);
|
|
51
|
+
}
|
|
52
|
+
case "image/svg+xml": {
|
|
53
|
+
return svgExtent(bytes);
|
|
54
|
+
}
|
|
55
|
+
case "image/webp": {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=size.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"size.js","sourceRoot":"","sources":["../../src/image/size.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAQrC,SAAS,IAAI,CAAC,KAAiB;IAC7B,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;AACxE,CAAC;AAED,4EAA4E;AAC5E,SAAS,SAAS,CAAC,KAAiB;IAClC,OAAO,KAAK,CAAC,MAAM,GAAG,EAAE;QACtB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED,+DAA+D;AAC/D,SAAS,SAAS,CAAC,KAAiB;IAClC,OAAO,KAAK,CAAC,MAAM,GAAG,EAAE;QACtB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC;YACE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC;YACrC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC;SACvC,CAAC;AACR,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAiB,EACjB,SAAoB;IAEpB,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAE1C,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;QAC/C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;AACnC,CAAC;AAED,SAAS,QAAQ,CAAC,KAAiB,EAAE,SAAoB;IACvD,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,WAAW,EAAE,CAAC;YACjB,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,KAAK,WAAW,EAAE,CAAC;YACjB,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,KAAK,YAAY,EAAE,CAAC;YAClB,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,KAAK,eAAe,EAAE,CAAC;YACrB,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,KAAK,YAAY,EAAE,CAAC;YAClB,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Extent } from "./size.js";
|
|
2
|
+
/**
|
|
3
|
+
* The proportions of an SVG, which are what a template needs: an SVG has no
|
|
4
|
+
* pixels of its own, so only the ratio between its width and height means
|
|
5
|
+
* anything here.
|
|
6
|
+
*
|
|
7
|
+
* `width` and `height` are read first and `viewBox` second, which is the order
|
|
8
|
+
* a renderer resolves them in. A document with neither is left unmeasured
|
|
9
|
+
* rather than assumed to be square, since a wordmark usually has neither.
|
|
10
|
+
*/
|
|
11
|
+
export declare function svgExtent(bytes: Uint8Array): Extent | undefined;
|
|
12
|
+
//# sourceMappingURL=svg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../src/image/svg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAwCxC;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAyB/D"}
|