@slidev/parser 52.15.2 → 52.17.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/dist/core.d.mts +1 -2
- package/dist/core.mjs +8 -9
- package/dist/fs.d.mts +7 -4
- package/dist/fs.mjs +7 -9
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -3
- package/dist/utils.d.mts +1 -1
- package/dist/utils.mjs +144 -3
- package/package.json +6 -3
- package/dist/utils-CmVawvVO.mjs +0 -148
- /package/dist/{utils-Bas9O4Gd.d.mts → utils-DpcPp-I0.d.mts} +0 -0
package/dist/core.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-
|
|
1
|
+
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-DpcPp-I0.mjs";
|
|
2
2
|
import { FontOptions, ResolvedFontOptions, SlidevConfig, SlidevDetectedFeatures, SlidevMarkdown, SlidevPreparserExtension, SlidevThemeMeta, SourceSlideInfo } from "@slidev/types";
|
|
3
|
-
|
|
4
3
|
//#region src/config.d.ts
|
|
5
4
|
declare function getDefaultConfig(): SlidevConfig;
|
|
6
5
|
declare function resolveConfig(headmatter: any, themeMeta?: SlidevThemeMeta, filepath?: string, verify?: boolean): SlidevConfig;
|
package/dist/core.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseAspectRatio, parseRangeString, parseTimeString, parseTimesplits } from "./utils.mjs";
|
|
2
2
|
import { ensurePrefix, toArray, uniq } from "@antfu/utils";
|
|
3
3
|
import YAML from "yaml";
|
|
4
|
-
|
|
5
4
|
//#region src/config.ts
|
|
6
5
|
const RE_QUOTED_STRING = /^(['"]).*\1$/;
|
|
7
6
|
const RE_FILENAME_STEM = /([^\\/]+?)(?:\.\w+)?$/;
|
|
@@ -45,8 +44,10 @@ function getDefaultConfig() {
|
|
|
45
44
|
htmlAttrs: {},
|
|
46
45
|
transition: null,
|
|
47
46
|
editor: true,
|
|
47
|
+
mcp: true,
|
|
48
48
|
contextMenu: null,
|
|
49
49
|
wakeLock: true,
|
|
50
|
+
pwa: false,
|
|
50
51
|
remote: false,
|
|
51
52
|
mdc: false,
|
|
52
53
|
comark: false,
|
|
@@ -192,7 +193,6 @@ function resolveDrawings(options = {}, filepath) {
|
|
|
192
193
|
syncAll
|
|
193
194
|
};
|
|
194
195
|
}
|
|
195
|
-
|
|
196
196
|
//#endregion
|
|
197
197
|
//#region src/core.ts
|
|
198
198
|
const RE_FRONTMATTER = /^---.*\r?\n([\s\S]*?)---/;
|
|
@@ -470,13 +470,12 @@ function scanMonacoReferencedMods(md) {
|
|
|
470
470
|
};
|
|
471
471
|
}
|
|
472
472
|
function hash(str) {
|
|
473
|
-
let hash
|
|
473
|
+
let hash = 0;
|
|
474
474
|
for (let i = 0; i < str.length; i++) {
|
|
475
|
-
hash
|
|
476
|
-
hash
|
|
475
|
+
hash = (hash << 5) - hash + str.charCodeAt(i);
|
|
476
|
+
hash |= 0;
|
|
477
477
|
}
|
|
478
|
-
return hash
|
|
478
|
+
return hash.toString(36).slice(0, 12);
|
|
479
479
|
}
|
|
480
|
-
|
|
481
480
|
//#endregion
|
|
482
|
-
export { detectFeatures, extractImagesUsage, getDefaultConfig, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig };
|
|
481
|
+
export { detectFeatures, extractImagesUsage, getDefaultConfig, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig };
|
package/dist/fs.d.mts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-
|
|
1
|
+
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-DpcPp-I0.mjs";
|
|
2
2
|
import { SlidevParserOptions, detectFeatures, extractImagesUsage, getDefaultConfig, parse, parseSlide, parseSync, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig } from "./core.mjs";
|
|
3
3
|
import { PreparserExtensionLoader, SlidevData, SlidevMarkdown } from "@slidev/types";
|
|
4
|
-
|
|
5
4
|
//#region src/fs.d.ts
|
|
6
5
|
declare function injectPreparserExtensionLoader(fn: PreparserExtensionLoader): void;
|
|
6
|
+
interface LoadRootsInfo {
|
|
7
|
+
roots: string[];
|
|
8
|
+
userRoot: string;
|
|
9
|
+
}
|
|
7
10
|
/**
|
|
8
11
|
* Slidev data without config and themeMeta,
|
|
9
12
|
* because config and themeMeta depends on the theme to be loaded.
|
|
10
13
|
*/
|
|
11
14
|
type LoadedSlidevData = Omit<SlidevData, 'config' | 'themeMeta'>;
|
|
12
|
-
declare function load(
|
|
15
|
+
declare function load(options: LoadRootsInfo, filepath: string, sources?: Record<string, string> | ((path: string) => Promise<string>), mode?: string): Promise<LoadedSlidevData>;
|
|
13
16
|
declare function save(markdown: SlidevMarkdown): Promise<string>;
|
|
14
17
|
//#endregion
|
|
15
|
-
export { LoadedSlidevData, SlidevParserOptions, TimesplitInput, TimesplitOutput, detectFeatures, extractImagesUsage, getDefaultConfig, injectPreparserExtensionLoader, load, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, save, stringify, stringifySlide, verifyConfig };
|
|
18
|
+
export { LoadRootsInfo, LoadedSlidevData, SlidevParserOptions, TimesplitInput, TimesplitOutput, detectFeatures, extractImagesUsage, getDefaultConfig, injectPreparserExtensionLoader, load, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, save, stringify, stringifySlide, verifyConfig };
|
package/dist/fs.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseAspectRatio, parseRangeString, parseTimeString, parseTimesplits } from "./utils.mjs";
|
|
2
2
|
import { detectFeatures, extractImagesUsage, getDefaultConfig, parse, parseSlide, parseSync, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig } from "./core.mjs";
|
|
3
3
|
import { slash } from "@antfu/utils";
|
|
4
4
|
import YAML from "yaml";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { readFile, writeFile } from "node:fs/promises";
|
|
7
7
|
import { dirname, resolve } from "node:path";
|
|
8
|
-
|
|
9
8
|
//#region src/fs.ts
|
|
10
9
|
const RE_FRONTMATTER_START = /^---(?:[^-].*)?$/;
|
|
11
10
|
const RE_BLANK_LINE = /^\s*$/;
|
|
@@ -15,7 +14,7 @@ let preparserExtensionLoader = null;
|
|
|
15
14
|
function injectPreparserExtensionLoader(fn) {
|
|
16
15
|
preparserExtensionLoader = fn;
|
|
17
16
|
}
|
|
18
|
-
async function load(
|
|
17
|
+
async function load(options, filepath, sources = {}, mode) {
|
|
19
18
|
const loadSource = typeof sources === "function" ? sources : async (path) => sources[path] ?? readFile(path, "utf-8");
|
|
20
19
|
const markdown = await loadSource(filepath);
|
|
21
20
|
let extensions;
|
|
@@ -28,12 +27,12 @@ async function load(userRoot, filepath, sources = {}, mode) {
|
|
|
28
27
|
hm = lines.slice(1, hEnd).join("\n");
|
|
29
28
|
}
|
|
30
29
|
const o = YAML.parse(hm) ?? {};
|
|
31
|
-
extensions = await preparserExtensionLoader(o, filepath, mode);
|
|
30
|
+
extensions = await preparserExtensionLoader(options.roots, o, filepath, mode);
|
|
32
31
|
}
|
|
33
32
|
const markdownFiles = {};
|
|
34
33
|
const watchFiles = {};
|
|
35
34
|
const slides = [];
|
|
36
|
-
async function loadMarkdown(path, range
|
|
35
|
+
async function loadMarkdown(path, range, frontmatterOverride, importers) {
|
|
37
36
|
let md = markdownFiles[path];
|
|
38
37
|
if (!md) {
|
|
39
38
|
md = await parse(await loadSource(path), path, extensions);
|
|
@@ -41,7 +40,7 @@ async function load(userRoot, filepath, sources = {}, mode) {
|
|
|
41
40
|
watchFiles[path] = /* @__PURE__ */ new Set();
|
|
42
41
|
}
|
|
43
42
|
const directImporter = importers?.at(-1);
|
|
44
|
-
for (const index of parseRangeString(md.slides.length, range
|
|
43
|
+
for (const index of parseRangeString(md.slides.length, range)) {
|
|
45
44
|
const subSlide = md.slides[index - 1];
|
|
46
45
|
try {
|
|
47
46
|
await loadSlide(md, subSlide, frontmatterOverride, importers);
|
|
@@ -61,7 +60,7 @@ async function load(userRoot, filepath, sources = {}, mode) {
|
|
|
61
60
|
if (slide.frontmatter.disabled || slide.frontmatter.hide) return;
|
|
62
61
|
if (slide.frontmatter.src) {
|
|
63
62
|
const [rawPath, rangeRaw] = slide.frontmatter.src.split("#");
|
|
64
|
-
const path = slash(rawPath.startsWith("/") ? resolve(userRoot, rawPath.substring(1)) : resolve(dirname(slide.filepath), rawPath));
|
|
63
|
+
const path = slash(rawPath.startsWith("/") ? resolve(options.userRoot, rawPath.substring(1)) : resolve(dirname(slide.filepath), rawPath));
|
|
65
64
|
frontmatterOverride = {
|
|
66
65
|
...slide.frontmatter,
|
|
67
66
|
...frontmatterOverride
|
|
@@ -107,6 +106,5 @@ async function save(markdown) {
|
|
|
107
106
|
await writeFile(markdown.filepath, fileContent, "utf-8");
|
|
108
107
|
return fileContent;
|
|
109
108
|
}
|
|
110
|
-
|
|
111
109
|
//#endregion
|
|
112
|
-
export { detectFeatures, extractImagesUsage, getDefaultConfig, injectPreparserExtensionLoader, load, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, save, stringify, stringifySlide, verifyConfig };
|
|
110
|
+
export { detectFeatures, extractImagesUsage, getDefaultConfig, injectPreparserExtensionLoader, load, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, save, stringify, stringifySlide, verifyConfig };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-
|
|
1
|
+
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-DpcPp-I0.mjs";
|
|
2
2
|
import { SlidevParserOptions, detectFeatures, extractImagesUsage, getDefaultConfig, parse, parseSlide, parseSync, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig } from "./core.mjs";
|
|
3
3
|
export { SlidevParserOptions, TimesplitInput, TimesplitOutput, detectFeatures, extractImagesUsage, getDefaultConfig, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseAspectRatio, parseRangeString, parseTimeString, parseTimesplits } from "./utils.mjs";
|
|
2
2
|
import { detectFeatures, extractImagesUsage, getDefaultConfig, parse, parseSlide, parseSync, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig } from "./core.mjs";
|
|
3
|
-
|
|
4
|
-
export { detectFeatures, extractImagesUsage, getDefaultConfig, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig };
|
|
3
|
+
export { detectFeatures, extractImagesUsage, getDefaultConfig, parse, parseAspectRatio, parseRangeString, parseSlide, parseSync, parseTimeString, parseTimesplits, prettify, prettifySlide, resolveConfig, resolveFonts, stringify, stringifySlide, verifyConfig };
|
package/dist/utils.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-
|
|
1
|
+
import { a as TimesplitOutput, i as TimesplitInput, n as parseRangeString, o as parseTimesplits, r as parseTimeString, t as parseAspectRatio } from "./utils-DpcPp-I0.mjs";
|
|
2
2
|
export { TimesplitInput, TimesplitOutput, parseAspectRatio, parseRangeString, parseTimeString, parseTimesplits };
|
package/dist/utils.mjs
CHANGED
|
@@ -1,3 +1,144 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { isNumber, range, uniq } from "@antfu/utils";
|
|
2
|
+
//#region src/timesplit/timestring.ts
|
|
3
|
+
/**
|
|
4
|
+
* Parse timestamp into seconds
|
|
5
|
+
*
|
|
6
|
+
* Accepts:
|
|
7
|
+
* - 10:50.1
|
|
8
|
+
* - 10s
|
|
9
|
+
* - 5m
|
|
10
|
+
* - 3min
|
|
11
|
+
* - 3mins 5secs
|
|
12
|
+
* - 10.5m3s
|
|
13
|
+
* - +10s
|
|
14
|
+
* - 1h10m30s
|
|
15
|
+
* - 1h4s
|
|
16
|
+
* - 1:1:1
|
|
17
|
+
*/
|
|
18
|
+
const RE_ALPHA = /[a-z]/i;
|
|
19
|
+
function parseTimeString(timestamp) {
|
|
20
|
+
if (typeof timestamp === "number") return {
|
|
21
|
+
seconds: timestamp,
|
|
22
|
+
relative: false
|
|
23
|
+
};
|
|
24
|
+
const relative = timestamp.startsWith("+");
|
|
25
|
+
if (relative) timestamp = timestamp.slice(1);
|
|
26
|
+
let seconds = 0;
|
|
27
|
+
if (timestamp.includes(":")) {
|
|
28
|
+
const parts = timestamp.split(":").map(Number);
|
|
29
|
+
let h = 0;
|
|
30
|
+
let m = 0;
|
|
31
|
+
let s = 0;
|
|
32
|
+
if (parts.length === 3) {
|
|
33
|
+
h = parts[0];
|
|
34
|
+
m = parts[1];
|
|
35
|
+
s = parts[2];
|
|
36
|
+
} else if (parts.length === 2) {
|
|
37
|
+
m = parts[0];
|
|
38
|
+
s = parts[1];
|
|
39
|
+
} else if (parts.length === 1) s = parts[0];
|
|
40
|
+
else throw new TypeError("Invalid timestamp format");
|
|
41
|
+
if (Number.isNaN(h) || Number.isNaN(m) || Number.isNaN(s)) throw new TypeError("Invalid timestamp format");
|
|
42
|
+
seconds = (h || 0) * 3600 + (m || 0) * 60 + (s || 0);
|
|
43
|
+
} else if (!RE_ALPHA.test(timestamp)) seconds = Number(timestamp);
|
|
44
|
+
else {
|
|
45
|
+
const unitMap = {
|
|
46
|
+
s: 1,
|
|
47
|
+
sec: 1,
|
|
48
|
+
secs: 1,
|
|
49
|
+
m: 60,
|
|
50
|
+
min: 60,
|
|
51
|
+
mins: 60,
|
|
52
|
+
h: 3600,
|
|
53
|
+
hr: 3600,
|
|
54
|
+
hrs: 3600,
|
|
55
|
+
hour: 3600,
|
|
56
|
+
hours: 3600,
|
|
57
|
+
day: 86400,
|
|
58
|
+
days: 86400,
|
|
59
|
+
week: 604800,
|
|
60
|
+
weeks: 604800,
|
|
61
|
+
month: 2629746,
|
|
62
|
+
months: 2629746,
|
|
63
|
+
year: 31556952,
|
|
64
|
+
years: 31556952
|
|
65
|
+
};
|
|
66
|
+
const regex = /([\d.]+)([a-z]+)/gi;
|
|
67
|
+
const matches = timestamp.matchAll(regex);
|
|
68
|
+
if (matches) for (const match of matches) {
|
|
69
|
+
const value = Number(match[1]);
|
|
70
|
+
if (Number.isNaN(value)) throw new TypeError(`Invalid timestamp value: ${match[1]}`);
|
|
71
|
+
const unit = match[2].toLowerCase();
|
|
72
|
+
if (!(unit in unitMap)) throw new TypeError(`Invalid timestamp unit: ${unit}`);
|
|
73
|
+
seconds += value * unitMap[unit];
|
|
74
|
+
}
|
|
75
|
+
const remaining = timestamp.replace(regex, "").trim();
|
|
76
|
+
if (remaining) throw new TypeError(`Unknown timestamp remaining: ${remaining}`);
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
seconds,
|
|
80
|
+
relative
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/timesplit/timesplit.ts
|
|
85
|
+
function parseTimesplits(inputs) {
|
|
86
|
+
let ts = 0;
|
|
87
|
+
const outputs = [];
|
|
88
|
+
let current = {
|
|
89
|
+
timestampStart: ts,
|
|
90
|
+
timestampEnd: ts,
|
|
91
|
+
noStart: 0,
|
|
92
|
+
noEnd: 0,
|
|
93
|
+
title: "[start]"
|
|
94
|
+
};
|
|
95
|
+
outputs.push(current);
|
|
96
|
+
for (const input of inputs) {
|
|
97
|
+
const time = parseTimeString(input.timesplit);
|
|
98
|
+
const end = time.relative ? ts + time.seconds : time.seconds;
|
|
99
|
+
if (end < ts) throw new Error(`Timesplit end ${end} is before start ${ts}`);
|
|
100
|
+
current.timestampEnd = end;
|
|
101
|
+
current.noEnd = input.no;
|
|
102
|
+
if (input.title) current.title = input.title;
|
|
103
|
+
ts = end;
|
|
104
|
+
current = {
|
|
105
|
+
timestampStart: end,
|
|
106
|
+
timestampEnd: end,
|
|
107
|
+
noStart: input.no,
|
|
108
|
+
noEnd: input.no
|
|
109
|
+
};
|
|
110
|
+
outputs.push(current);
|
|
111
|
+
}
|
|
112
|
+
return outputs;
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/utils.ts
|
|
116
|
+
const RE_ASPECT_RATIO_SEPARATOR = /[:/x|]/;
|
|
117
|
+
/**
|
|
118
|
+
* 1,3-5,8 => [1, 3, 4, 5, 8]
|
|
119
|
+
*/
|
|
120
|
+
function parseRangeString(total, rangeStr) {
|
|
121
|
+
if (!rangeStr || rangeStr === "all" || rangeStr === "*") return range(1, total + 1);
|
|
122
|
+
if (rangeStr === "none") return [];
|
|
123
|
+
const indexes = [];
|
|
124
|
+
for (const part of rangeStr.split(/[,;]/g)) if (!part.includes("-")) indexes.push(+part);
|
|
125
|
+
else {
|
|
126
|
+
const [start, end] = part.split("-", 2);
|
|
127
|
+
indexes.push(...range(+start, !end ? total + 1 : +end + 1));
|
|
128
|
+
}
|
|
129
|
+
return uniq(indexes).filter((i) => i <= total).sort((a, b) => a - b);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Accepts `16/9` `1:1` `3x4`
|
|
133
|
+
*/
|
|
134
|
+
function parseAspectRatio(str) {
|
|
135
|
+
if (isNumber(str)) return str;
|
|
136
|
+
if (!Number.isNaN(+str)) return +str;
|
|
137
|
+
const [wStr = "", hStr = ""] = str.split(RE_ASPECT_RATIO_SEPARATOR);
|
|
138
|
+
const w = Number.parseFloat(wStr.trim());
|
|
139
|
+
const h = Number.parseFloat(hStr.trim());
|
|
140
|
+
if (Number.isNaN(w) || Number.isNaN(h) || h === 0) throw new Error(`Invalid aspect ratio "${str}"`);
|
|
141
|
+
return w / h;
|
|
142
|
+
}
|
|
143
|
+
//#endregion
|
|
144
|
+
export { parseAspectRatio, parseRangeString, parseTimeString, parseTimesplits };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/parser",
|
|
3
|
-
"version": "52.
|
|
3
|
+
"version": "52.17.0",
|
|
4
4
|
"description": "Markdown parser for Slidev",
|
|
5
5
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,8 +30,11 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@antfu/utils": "^9.3.0",
|
|
33
|
-
"yaml": "^2.
|
|
34
|
-
"@slidev/types": "52.
|
|
33
|
+
"yaml": "^2.9.0",
|
|
34
|
+
"@slidev/types": "52.17.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"tsdown-stale-guard": "^0.1.2"
|
|
35
38
|
},
|
|
36
39
|
"scripts": {
|
|
37
40
|
"build": "tsdown",
|
package/dist/utils-CmVawvVO.mjs
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { isNumber, range, uniq } from "@antfu/utils";
|
|
2
|
-
|
|
3
|
-
//#region src/timesplit/timestring.ts
|
|
4
|
-
/**
|
|
5
|
-
* Parse timestamp into seconds
|
|
6
|
-
*
|
|
7
|
-
* Accepts:
|
|
8
|
-
* - 10:50.1
|
|
9
|
-
* - 10s
|
|
10
|
-
* - 5m
|
|
11
|
-
* - 3min
|
|
12
|
-
* - 3mins 5secs
|
|
13
|
-
* - 10.5m3s
|
|
14
|
-
* - +10s
|
|
15
|
-
* - 1h10m30s
|
|
16
|
-
* - 1h4s
|
|
17
|
-
* - 1:1:1
|
|
18
|
-
*/
|
|
19
|
-
const RE_ALPHA = /[a-z]/i;
|
|
20
|
-
function parseTimeString(timestamp) {
|
|
21
|
-
if (typeof timestamp === "number") return {
|
|
22
|
-
seconds: timestamp,
|
|
23
|
-
relative: false
|
|
24
|
-
};
|
|
25
|
-
const relative = timestamp.startsWith("+");
|
|
26
|
-
if (relative) timestamp = timestamp.slice(1);
|
|
27
|
-
let seconds = 0;
|
|
28
|
-
if (timestamp.includes(":")) {
|
|
29
|
-
const parts = timestamp.split(":").map(Number);
|
|
30
|
-
let h = 0;
|
|
31
|
-
let m = 0;
|
|
32
|
-
let s = 0;
|
|
33
|
-
if (parts.length === 3) {
|
|
34
|
-
h = parts[0];
|
|
35
|
-
m = parts[1];
|
|
36
|
-
s = parts[2];
|
|
37
|
-
} else if (parts.length === 2) {
|
|
38
|
-
m = parts[0];
|
|
39
|
-
s = parts[1];
|
|
40
|
-
} else if (parts.length === 1) s = parts[0];
|
|
41
|
-
else throw new TypeError("Invalid timestamp format");
|
|
42
|
-
if (Number.isNaN(h) || Number.isNaN(m) || Number.isNaN(s)) throw new TypeError("Invalid timestamp format");
|
|
43
|
-
seconds = (h || 0) * 3600 + (m || 0) * 60 + (s || 0);
|
|
44
|
-
} else if (!RE_ALPHA.test(timestamp)) seconds = Number(timestamp);
|
|
45
|
-
else {
|
|
46
|
-
const unitMap = {
|
|
47
|
-
s: 1,
|
|
48
|
-
sec: 1,
|
|
49
|
-
secs: 1,
|
|
50
|
-
m: 60,
|
|
51
|
-
min: 60,
|
|
52
|
-
mins: 60,
|
|
53
|
-
h: 3600,
|
|
54
|
-
hr: 3600,
|
|
55
|
-
hrs: 3600,
|
|
56
|
-
hour: 3600,
|
|
57
|
-
hours: 3600,
|
|
58
|
-
day: 86400,
|
|
59
|
-
days: 86400,
|
|
60
|
-
week: 604800,
|
|
61
|
-
weeks: 604800,
|
|
62
|
-
month: 2629746,
|
|
63
|
-
months: 2629746,
|
|
64
|
-
year: 31556952,
|
|
65
|
-
years: 31556952
|
|
66
|
-
};
|
|
67
|
-
const regex = /([\d.]+)([a-z]+)/gi;
|
|
68
|
-
const matches = timestamp.matchAll(regex);
|
|
69
|
-
if (matches) for (const match of matches) {
|
|
70
|
-
const value = Number(match[1]);
|
|
71
|
-
if (Number.isNaN(value)) throw new TypeError(`Invalid timestamp value: ${match[1]}`);
|
|
72
|
-
const unit = match[2].toLowerCase();
|
|
73
|
-
if (!(unit in unitMap)) throw new TypeError(`Invalid timestamp unit: ${unit}`);
|
|
74
|
-
seconds += value * unitMap[unit];
|
|
75
|
-
}
|
|
76
|
-
const remaining = timestamp.replace(regex, "").trim();
|
|
77
|
-
if (remaining) throw new TypeError(`Unknown timestamp remaining: ${remaining}`);
|
|
78
|
-
}
|
|
79
|
-
return {
|
|
80
|
-
seconds,
|
|
81
|
-
relative
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
//#endregion
|
|
86
|
-
//#region src/timesplit/timesplit.ts
|
|
87
|
-
function parseTimesplits(inputs) {
|
|
88
|
-
let ts = 0;
|
|
89
|
-
const outputs = [];
|
|
90
|
-
let current = {
|
|
91
|
-
timestampStart: ts,
|
|
92
|
-
timestampEnd: ts,
|
|
93
|
-
noStart: 0,
|
|
94
|
-
noEnd: 0,
|
|
95
|
-
title: "[start]"
|
|
96
|
-
};
|
|
97
|
-
outputs.push(current);
|
|
98
|
-
for (const input of inputs) {
|
|
99
|
-
const time = parseTimeString(input.timesplit);
|
|
100
|
-
const end = time.relative ? ts + time.seconds : time.seconds;
|
|
101
|
-
if (end < ts) throw new Error(`Timesplit end ${end} is before start ${ts}`);
|
|
102
|
-
current.timestampEnd = end;
|
|
103
|
-
current.noEnd = input.no;
|
|
104
|
-
if (input.title) current.title = input.title;
|
|
105
|
-
ts = end;
|
|
106
|
-
current = {
|
|
107
|
-
timestampStart: end,
|
|
108
|
-
timestampEnd: end,
|
|
109
|
-
noStart: input.no,
|
|
110
|
-
noEnd: input.no
|
|
111
|
-
};
|
|
112
|
-
outputs.push(current);
|
|
113
|
-
}
|
|
114
|
-
return outputs;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
//#endregion
|
|
118
|
-
//#region src/utils.ts
|
|
119
|
-
const RE_ASPECT_RATIO_SEPARATOR = /[:/x|]/;
|
|
120
|
-
/**
|
|
121
|
-
* 1,3-5,8 => [1, 3, 4, 5, 8]
|
|
122
|
-
*/
|
|
123
|
-
function parseRangeString(total, rangeStr) {
|
|
124
|
-
if (!rangeStr || rangeStr === "all" || rangeStr === "*") return range(1, total + 1);
|
|
125
|
-
if (rangeStr === "none") return [];
|
|
126
|
-
const indexes = [];
|
|
127
|
-
for (const part of rangeStr.split(/[,;]/g)) if (!part.includes("-")) indexes.push(+part);
|
|
128
|
-
else {
|
|
129
|
-
const [start, end] = part.split("-", 2);
|
|
130
|
-
indexes.push(...range(+start, !end ? total + 1 : +end + 1));
|
|
131
|
-
}
|
|
132
|
-
return uniq(indexes).filter((i) => i <= total).sort((a, b) => a - b);
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Accepts `16/9` `1:1` `3x4`
|
|
136
|
-
*/
|
|
137
|
-
function parseAspectRatio(str) {
|
|
138
|
-
if (isNumber(str)) return str;
|
|
139
|
-
if (!Number.isNaN(+str)) return +str;
|
|
140
|
-
const [wStr = "", hStr = ""] = str.split(RE_ASPECT_RATIO_SEPARATOR);
|
|
141
|
-
const w = Number.parseFloat(wStr.trim());
|
|
142
|
-
const h = Number.parseFloat(hStr.trim());
|
|
143
|
-
if (Number.isNaN(w) || Number.isNaN(h) || h === 0) throw new Error(`Invalid aspect ratio "${str}"`);
|
|
144
|
-
return w / h;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
//#endregion
|
|
148
|
-
export { parseTimeString as i, parseRangeString as n, parseTimesplits as r, parseAspectRatio as t };
|
|
File without changes
|