@digitalwalletcorp/utils 0.9.0 → 0.11.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 +1 -0
- package/lib/date-time.cjs +2 -0
- package/lib/date-time.cjs.map +1 -0
- package/lib/date-time.d.cts +203 -0
- package/lib/date-time.d.ts +203 -0
- package/lib/date-time.js +289 -0
- package/lib/date-time.js.map +1 -0
- package/lib/date-util-ByW86YIS.cjs +2 -0
- package/lib/date-util-ByW86YIS.cjs.map +1 -0
- package/lib/date-util-C581gVKx.js +140 -0
- package/lib/date-util-C581gVKx.js.map +1 -0
- package/lib/date-util.cjs +1 -1
- package/lib/date-util.d.cts +8 -15
- package/lib/date-util.d.ts +8 -15
- package/lib/date-util.js +15 -16
- package/lib/{file-util-H-c_eQcd.js → file-util-CO5vjmkO.js} +60 -53
- package/lib/file-util-CO5vjmkO.js.map +1 -0
- package/lib/file-util-Dqiw5tBQ.cjs +2 -0
- package/lib/file-util-Dqiw5tBQ.cjs.map +1 -0
- package/lib/file-util.cjs +1 -1
- package/lib/file-util.js +1 -1
- package/lib/html-util-BctKzfnH.js +60 -0
- package/lib/html-util-BctKzfnH.js.map +1 -0
- package/lib/html-util-ELyFVsxl.cjs +2 -0
- package/lib/html-util-ELyFVsxl.cjs.map +1 -0
- package/lib/html-util.cjs +1 -1
- package/lib/html-util.d.cts +5 -4
- package/lib/html-util.d.ts +5 -4
- package/lib/html-util.js +2 -2
- package/lib/index.cjs +1 -1
- package/lib/index.d.cts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +16 -14
- package/lib/index.js.map +1 -1
- package/lib/{json-util-5mq7fsX_.cjs → json-util-CKnsxu1e.cjs} +3 -3
- package/lib/json-util-CKnsxu1e.cjs.map +1 -0
- package/lib/{json-util-CF-O1b7m.js → json-util-C_Pm1BpJ.js} +6 -5
- package/lib/json-util-C_Pm1BpJ.js.map +1 -0
- package/lib/json-util.cjs +1 -1
- package/lib/json-util.d.cts +10 -1
- package/lib/json-util.d.ts +10 -1
- package/lib/json-util.js +1 -1
- package/lib/{object-util-Cc1SmN-8.cjs → object-util-BHg61ifG.cjs} +2 -2
- package/lib/{object-util-Cc1SmN-8.cjs.map → object-util-BHg61ifG.cjs.map} +1 -1
- package/lib/{object-util-BGqczDbJ.js → object-util-wOMJtGK3.js} +2 -2
- package/lib/{object-util-BGqczDbJ.js.map → object-util-wOMJtGK3.js.map} +1 -1
- package/lib/object-util.cjs +1 -1
- package/lib/object-util.js +2 -2
- package/package.json +1 -1
- package/src/date-time.ts +395 -0
- package/src/date-util.ts +29 -103
- package/src/file-util.ts +23 -0
- package/src/html-util.ts +22 -12
- package/src/index.ts +1 -0
- package/src/json-util.ts +8 -5
- package/lib/date-util-DrfUsv9b.js +0 -181
- package/lib/date-util-DrfUsv9b.js.map +0 -1
- package/lib/date-util-b1Lw7Nyu.cjs +0 -2
- package/lib/date-util-b1Lw7Nyu.cjs.map +0 -1
- package/lib/file-util-D09BvDYY.cjs +0 -2
- package/lib/file-util-D09BvDYY.cjs.map +0 -1
- package/lib/file-util-H-c_eQcd.js.map +0 -1
- package/lib/html-util-CcRJtzod.js +0 -56
- package/lib/html-util-CcRJtzod.js.map +0 -1
- package/lib/html-util-ClGIpzW1.cjs +0 -2
- package/lib/html-util-ClGIpzW1.cjs.map +0 -1
- package/lib/json-util-5mq7fsX_.cjs.map +0 -1
- package/lib/json-util-CF-O1b7m.js.map +0 -1
package/lib/date-util.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { DateTime } from './date-time';
|
|
2
|
+
/**
|
|
3
|
+
* 日時として解釈する値。string はISO形式または inputFormat の書式、number は epoch ミリ秒
|
|
4
|
+
* DateTime は inputTimezone を省略した場合、その DateTime のタイムゾーンで扱う
|
|
5
|
+
*/
|
|
6
|
+
export type DateInput = string | Date | number | DateTime | null | undefined;
|
|
3
7
|
/** 日時の切り捨て(startOf / endOf)に使う単位 */
|
|
4
8
|
export type DateUnit = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond';
|
|
5
9
|
/** 期間の単位 */
|
|
@@ -30,6 +34,8 @@ export interface ParseDateOptions {
|
|
|
30
34
|
startOf?: DateUnit;
|
|
31
35
|
/** 指定した単位の最後の時点に切り上げる(month なら月末の23:59:59.999) */
|
|
32
36
|
endOf?: DateUnit;
|
|
37
|
+
/** 書式の月名・曜日名を解釈・出力するときのロケール。既定は 'en-US' */
|
|
38
|
+
locale?: string;
|
|
33
39
|
}
|
|
34
40
|
/**
|
|
35
41
|
* 日時を文字列にするときのオプション
|
|
@@ -185,19 +191,6 @@ export declare function currentTimestamp(timezone?: string): string;
|
|
|
185
191
|
export declare function convertExcelDateSerialToUnixTimeSerial(excelDateSerial: number, options?: {
|
|
186
192
|
offset: number;
|
|
187
193
|
}): number;
|
|
188
|
-
/**
|
|
189
|
-
* 期間の値を別の単位に換算する
|
|
190
|
-
* 月と年は固定長(1か月 = 30日、1年 = 365日)として換算する
|
|
191
|
-
*
|
|
192
|
-
* @example
|
|
193
|
-
* convertTimeUnit(1, 'hours', 'milliseconds'); // 3600000
|
|
194
|
-
*
|
|
195
|
-
* @param {number} value
|
|
196
|
-
* @param {TimeUnit} inputUnit
|
|
197
|
-
* @param {TimeUnit} outputUnit
|
|
198
|
-
* @returns {number}
|
|
199
|
-
*/
|
|
200
|
-
export declare function convertTimeUnit(value: number, inputUnit: TimeUnit, outputUnit: TimeUnit): number;
|
|
201
194
|
/**
|
|
202
195
|
* timezone が at の時点で夏時間かどうかを返す
|
|
203
196
|
* at を省略した場合は現在時刻で判定する。at が解釈できない場合は false を返す
|
package/lib/date-util.js
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import "
|
|
2
|
-
import { a as i, c as r, b as t, e as m, f as o, g as f,
|
|
1
|
+
import "./date-time.js";
|
|
2
|
+
import { a as i, c as r, b as t, e as m, f as o, g as f, i as n, h as p, j as T, k as l, l as D, m as S, n as b, o as c, p as A, q as x } from "./date-util-C581gVKx.js";
|
|
3
3
|
export {
|
|
4
4
|
i as applyTimezoneAbbr,
|
|
5
5
|
r as convertExcelDateSerialToUnixTimeSerial,
|
|
6
|
-
t as
|
|
7
|
-
m as
|
|
8
|
-
o as
|
|
9
|
-
f as
|
|
10
|
-
n as
|
|
11
|
-
T as isAfter,
|
|
6
|
+
t as currentTimestamp,
|
|
7
|
+
m as diff,
|
|
8
|
+
o as formatDate,
|
|
9
|
+
f as getTimezoneAbbr,
|
|
10
|
+
n as isAfter,
|
|
12
11
|
p as isBefore,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
T as isInDST,
|
|
13
|
+
l as isPastDate,
|
|
14
|
+
D as isPastDateTime,
|
|
15
|
+
S as isSame,
|
|
16
|
+
b as isSameOrAfter,
|
|
17
|
+
c as isSameOrBefore,
|
|
18
|
+
A as isValid,
|
|
19
|
+
x as parseDate
|
|
21
20
|
};
|
|
22
21
|
//# sourceMappingURL=date-util.js.map
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
const a = /^data:([^;,]+)?(?:;[^,]*)?;base64,(.*)$/s, g = "application/octet-stream";
|
|
2
|
-
const
|
|
2
|
+
const T = /^\ufeff?\s*(?:<\?xml[^>]*>\s*)?(?:<!--[\s\S]*?-->\s*)*(?:<!DOCTYPE[^>]*>\s*)?<svg[\s>]/i, B = [
|
|
3
3
|
{ entry: "word/", type: { ext: "docx", mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" } },
|
|
4
4
|
{ entry: "xl/", type: { ext: "xlsx", mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" } },
|
|
5
5
|
{ entry: "ppt/", type: { ext: "pptx", mime: "application/vnd.openxmlformats-officedocument.presentationml.presentation" } }
|
|
6
|
-
], c = (e) => e instanceof ArrayBuffer ? new Uint8Array(e) : new Uint8Array(e.buffer, e.byteOffset, e.byteLength),
|
|
7
|
-
const
|
|
8
|
-
return e.length <
|
|
6
|
+
], d = ["avif", "avis"], c = (e) => e instanceof ArrayBuffer ? new Uint8Array(e) : new Uint8Array(e.buffer, e.byteOffset, e.byteLength), x = (e) => c(e).slice().buffer, i = (e, t, n = 0) => {
|
|
7
|
+
const r = typeof t == "string" ? Array.from(t, (o) => o.charCodeAt(0)) : t;
|
|
8
|
+
return e.length < n + r.length ? !1 : r.every((o, A) => e[n + A] === o);
|
|
9
|
+
}, w = (e) => {
|
|
10
|
+
const t = Math.min(new DataView(e.buffer, e.byteOffset, e.byteLength).getUint32(0), e.length), n = new TextDecoder("latin1").decode(e.subarray(0, t)), r = [n.slice(8, 12)];
|
|
11
|
+
for (let o = 16; o + 4 <= t; o += 4)
|
|
12
|
+
r.push(n.slice(o, o + 4));
|
|
13
|
+
return r;
|
|
9
14
|
}, E = (e) => {
|
|
10
15
|
if (i(e, [137, 80, 78, 71, 13, 10, 26, 10]))
|
|
11
16
|
return { ext: "png", mime: "image/png" };
|
|
@@ -19,80 +24,82 @@ const h = /^\ufeff?\s*(?:<\?xml[^>]*>\s*)?(?:<!--[\s\S]*?-->\s*)*(?:<!DOCTYPE[^>
|
|
|
19
24
|
return { ext: "bmp", mime: "image/bmp" };
|
|
20
25
|
if (i(e, [73, 73, 42, 0]) || i(e, [77, 77, 0, 42]))
|
|
21
26
|
return { ext: "tif", mime: "image/tiff" };
|
|
27
|
+
if (i(e, "ftyp", 4) && w(e).some((t) => d.includes(t)))
|
|
28
|
+
return { ext: "avif", mime: "image/avif" };
|
|
22
29
|
if (i(e, "%PDF-"))
|
|
23
30
|
return { ext: "pdf", mime: "application/pdf" };
|
|
24
31
|
if (i(e, [80, 75, 3, 4]) || i(e, [80, 75, 5, 6]) || i(e, [80, 75, 7, 8])) {
|
|
25
|
-
const t = new TextDecoder("latin1").decode(e),
|
|
26
|
-
return
|
|
32
|
+
const t = new TextDecoder("latin1").decode(e), n = B.find((r) => t.includes(r.entry));
|
|
33
|
+
return n ? n.type : { ext: "zip", mime: "application/zip" };
|
|
27
34
|
}
|
|
28
|
-
return
|
|
35
|
+
return T.test(new TextDecoder().decode(e)) ? { ext: "svg", mime: "image/svg+xml" } : null;
|
|
29
36
|
};
|
|
30
37
|
function u(e, t) {
|
|
31
38
|
return `data:${t || g};base64,${e}`;
|
|
32
39
|
}
|
|
33
40
|
function F(e) {
|
|
34
|
-
const t = a.exec(e),
|
|
35
|
-
return [
|
|
41
|
+
const t = a.exec(e), n = t ? t[2] : e;
|
|
42
|
+
return [n, f(n)?.mime ?? t?.[1] ?? g];
|
|
36
43
|
}
|
|
37
44
|
async function U(e) {
|
|
38
45
|
if (typeof e == "string")
|
|
39
|
-
return a.test(e) ? e :
|
|
46
|
+
return a.test(e) ? e : y(e);
|
|
40
47
|
if (e instanceof Blob) {
|
|
41
48
|
const t = await e.arrayBuffer();
|
|
42
49
|
return s(t, e.type || f(t)?.mime);
|
|
43
50
|
}
|
|
44
51
|
return s(e, f(e)?.mime);
|
|
45
52
|
}
|
|
46
|
-
async function
|
|
47
|
-
return typeof e == "string" ? p(e) : e instanceof Blob ? e.arrayBuffer() :
|
|
53
|
+
async function _(e) {
|
|
54
|
+
return typeof e == "string" ? p(e) : e instanceof Blob ? e.arrayBuffer() : x(e);
|
|
48
55
|
}
|
|
49
|
-
function
|
|
56
|
+
function y(e, t) {
|
|
50
57
|
return e && u(e, t || f(e)?.mime);
|
|
51
58
|
}
|
|
52
|
-
function m(e) {
|
|
53
|
-
const t = atob(e), r = new Uint8Array(t.length);
|
|
54
|
-
for (let n = 0; n < t.length; n++)
|
|
55
|
-
r[n] = t.charCodeAt(n);
|
|
56
|
-
return r.buffer;
|
|
57
|
-
}
|
|
58
59
|
function l(e) {
|
|
60
|
+
const t = atob(e), n = new Uint8Array(t.length);
|
|
61
|
+
for (let r = 0; r < t.length; r++)
|
|
62
|
+
n[r] = t.charCodeAt(r);
|
|
63
|
+
return n.buffer;
|
|
64
|
+
}
|
|
65
|
+
function m(e) {
|
|
59
66
|
return a.exec(e)?.[2] ?? e;
|
|
60
67
|
}
|
|
61
68
|
function p(e) {
|
|
62
|
-
return m(
|
|
69
|
+
return l(m(e));
|
|
63
70
|
}
|
|
64
|
-
function
|
|
71
|
+
function h(e) {
|
|
65
72
|
const t = c(e);
|
|
66
|
-
let
|
|
67
|
-
for (let
|
|
68
|
-
|
|
69
|
-
return btoa(
|
|
73
|
+
let n = "";
|
|
74
|
+
for (let r = 0; r < t.length; r++)
|
|
75
|
+
n += String.fromCharCode(t[r]);
|
|
76
|
+
return btoa(n);
|
|
70
77
|
}
|
|
71
78
|
function s(e, t) {
|
|
72
|
-
return u(
|
|
79
|
+
return u(h(e), t);
|
|
73
80
|
}
|
|
74
|
-
function
|
|
81
|
+
function v(e) {
|
|
75
82
|
return p(e).byteLength;
|
|
76
83
|
}
|
|
77
|
-
function
|
|
84
|
+
function D(e) {
|
|
78
85
|
if (!e)
|
|
79
86
|
return new Blob([]);
|
|
80
87
|
let t;
|
|
81
88
|
if (typeof e == "string") {
|
|
82
|
-
const
|
|
83
|
-
for (let o = 0; o <
|
|
84
|
-
|
|
85
|
-
t = [
|
|
89
|
+
const n = `\uFEFF${e}`, r = new Uint16Array(n.length);
|
|
90
|
+
for (let o = 0; o < n.length; o++)
|
|
91
|
+
r[o] = n.charCodeAt(o);
|
|
92
|
+
t = [r];
|
|
86
93
|
} else
|
|
87
|
-
t = [new Uint8Array([255, 254]),
|
|
94
|
+
t = [new Uint8Array([255, 254]), x(e)];
|
|
88
95
|
return new Blob(t, { type: "text/csv;charset=utf-16;" });
|
|
89
96
|
}
|
|
90
97
|
function f(e) {
|
|
91
98
|
let t;
|
|
92
99
|
if (typeof e == "string") {
|
|
93
|
-
const
|
|
100
|
+
const n = m(e).slice(0, 16384);
|
|
94
101
|
try {
|
|
95
|
-
t = c(
|
|
102
|
+
t = c(l(n.slice(0, n.length - n.length % 4)));
|
|
96
103
|
} catch {
|
|
97
104
|
return null;
|
|
98
105
|
}
|
|
@@ -100,41 +107,41 @@ function f(e) {
|
|
|
100
107
|
t = c(e);
|
|
101
108
|
return E(t);
|
|
102
109
|
}
|
|
103
|
-
function
|
|
110
|
+
function b(e) {
|
|
104
111
|
return e.replace(/[\\/:*?"<>|]/g, "");
|
|
105
112
|
}
|
|
106
113
|
const L = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
107
114
|
__proto__: null,
|
|
108
115
|
analyzeFileType: f,
|
|
109
|
-
arrayBufferToBase64:
|
|
116
|
+
arrayBufferToBase64: h,
|
|
110
117
|
arrayBufferToDataURL: s,
|
|
111
|
-
base64ToArrayBuffer:
|
|
112
|
-
base64ToDataURL:
|
|
113
|
-
calcSize:
|
|
114
|
-
convertUTF16withBOM:
|
|
118
|
+
base64ToArrayBuffer: l,
|
|
119
|
+
base64ToDataURL: y,
|
|
120
|
+
calcSize: v,
|
|
121
|
+
convertUTF16withBOM: D,
|
|
115
122
|
createDataURL: u,
|
|
116
123
|
dataURLToArrayBuffer: p,
|
|
117
|
-
dataURLToBase64:
|
|
124
|
+
dataURLToBase64: m,
|
|
118
125
|
parseDataURL: F,
|
|
119
|
-
readAsArrayBuffer:
|
|
126
|
+
readAsArrayBuffer: _,
|
|
120
127
|
readAsDataURL: U,
|
|
121
|
-
sanitizeFileName:
|
|
128
|
+
sanitizeFileName: b
|
|
122
129
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
123
130
|
export {
|
|
124
131
|
f as a,
|
|
125
|
-
|
|
132
|
+
h as b,
|
|
126
133
|
s as c,
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
l as d,
|
|
135
|
+
y as e,
|
|
129
136
|
L as f,
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
v as g,
|
|
138
|
+
D as h,
|
|
132
139
|
u as i,
|
|
133
140
|
p as j,
|
|
134
|
-
|
|
141
|
+
m as k,
|
|
135
142
|
U as l,
|
|
136
143
|
F as p,
|
|
137
|
-
|
|
138
|
-
|
|
144
|
+
_ as r,
|
|
145
|
+
b as s
|
|
139
146
|
};
|
|
140
|
-
//# sourceMappingURL=file-util-
|
|
147
|
+
//# sourceMappingURL=file-util-CO5vjmkO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-util-CO5vjmkO.js","sources":["../src/file-util.ts"],"sourcesContent":["/** 先頭バイトの署名から判定したファイルの種類 */\nexport interface FileType {\n /** 拡張子(ドットなし) */\n ext: string;\n /** MIMEタイプ */\n mime: string;\n}\n\n/** バイナリとして受け付ける値。Node.js の Buffer も ArrayBufferView として渡せる */\nexport type BinaryInput = ArrayBuffer | ArrayBufferView;\n\nconst DATA_URL_PATTERN = /^data:([^;,]+)?(?:;[^,]*)?;base64,(.*)$/s;\n\nconst DEFAULT_MIME_TYPE = 'application/octet-stream';\n\n/** 種類の判定に使う先頭の base64 の文字数。ZIP の中のエントリ名を探すため数KB分を見る */\nconst SIGNATURE_BASE64_LENGTH = 16384;\n\nconst SVG_PATTERN = /^\\ufeff?\\s*(?:<\\?xml[^>]*>\\s*)?(?:<!--[\\s\\S]*?-->\\s*)*(?:<!DOCTYPE[^>]*>\\s*)?<svg[\\s>]/i;\n\nconst OFFICE_FILE_TYPES: { entry: string; type: FileType; }[] = [\n { entry: 'word/', type: { ext: 'docx', mime: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' } },\n { entry: 'xl/', type: { ext: 'xlsx', mime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' } },\n { entry: 'ppt/', type: { ext: 'pptx', mime: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' } }\n];\n\n/** ftyp ボックスのブランドのうち、AVIF を表すもの */\nconst AVIF_BRANDS = ['avif', 'avis'];\n\nconst toBytes = (data: BinaryInput): Uint8Array => {\n return data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n};\n\nconst toArrayBuffer = (data: BinaryInput): ArrayBuffer => toBytes(data).slice().buffer as ArrayBuffer;\n\nconst startsWith = (bytes: Uint8Array, signature: number[] | string, offset: number = 0): boolean => {\n const expected = typeof signature === 'string' ? Array.from(signature, c => c.charCodeAt(0)) : signature;\n if (bytes.length < offset + expected.length) {\n return false;\n }\n return expected.every((value, i) => bytes[offset + i] === value);\n};\n\n/**\n * ISOBMFF の ftyp ボックスに並ぶブランドを返す\n * 8バイト目からメジャーブランド、16バイト目から互換ブランドが4文字ずつ並ぶ\n *\n * @param {Uint8Array} bytes\n * @returns {string[]}\n */\nconst readBrands = (bytes: Uint8Array): string[] => {\n const end = Math.min(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0), bytes.length);\n const text = new TextDecoder('latin1').decode(bytes.subarray(0, end));\n const brands = [text.slice(8, 12)];\n for (let i = 16; i + 4 <= end; i += 4) {\n brands.push(text.slice(i, i + 4));\n }\n return brands;\n};\n\nconst detectFileType = (bytes: Uint8Array): FileType | null => {\n if (startsWith(bytes, [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) {\n return { ext: 'png', mime: 'image/png' };\n }\n if (startsWith(bytes, [0xFF, 0xD8, 0xFF])) {\n return { ext: 'jpg', mime: 'image/jpeg' };\n }\n if (startsWith(bytes, 'GIF87a') || startsWith(bytes, 'GIF89a')) {\n return { ext: 'gif', mime: 'image/gif' };\n }\n if (startsWith(bytes, 'RIFF') && startsWith(bytes, 'WEBP', 8)) {\n return { ext: 'webp', mime: 'image/webp' };\n }\n if (startsWith(bytes, 'BM')) {\n return { ext: 'bmp', mime: 'image/bmp' };\n }\n if (startsWith(bytes, [0x49, 0x49, 0x2A, 0x00]) || startsWith(bytes, [0x4D, 0x4D, 0x00, 0x2A])) {\n return { ext: 'tif', mime: 'image/tiff' };\n }\n if (startsWith(bytes, 'ftyp', 4) && readBrands(bytes).some(a => AVIF_BRANDS.includes(a))) {\n return { ext: 'avif', mime: 'image/avif' };\n }\n if (startsWith(bytes, '%PDF-')) {\n return { ext: 'pdf', mime: 'application/pdf' };\n }\n if (startsWith(bytes, [0x50, 0x4B, 0x03, 0x04]) || startsWith(bytes, [0x50, 0x4B, 0x05, 0x06]) || startsWith(bytes, [0x50, 0x4B, 0x07, 0x08])) {\n // Office Open XML も ZIP なので、ZIP に含まれるエントリ名で見分ける\n const text = new TextDecoder('latin1').decode(bytes);\n const office = OFFICE_FILE_TYPES.find(a => text.includes(a.entry));\n return office ? office.type : { ext: 'zip', mime: 'application/zip' };\n }\n if (SVG_PATTERN.test(new TextDecoder().decode(bytes))) {\n return { ext: 'svg', mime: 'image/svg+xml' };\n }\n return null;\n};\n\n/**\n * base64 データと MIME タイプから DataURL を生成する\n *\n * @param {string} base64\n * @param {string} [mimeType] 省略時は 'application/octet-stream'\n * @returns {string}\n */\nexport function createDataURL(base64: string, mimeType?: string): string {\n return `data:${mimeType || DEFAULT_MIME_TYPE};base64,${base64}`;\n}\n\n/**\n * DataURL を base64 データと MIME タイプに分解する\n * MIME タイプは DataURL に書かれた値ではなく、データの先頭バイトから判定した値を返す。判定できない場合は DataURL に書かれた値、それもなければ 'application/octet-stream'\n * DataURL 形式でない文字列は base64 データとみなす\n *\n * @param {string} dataURL\n * @returns {[string, string]} [base64, mimeType]\n */\nexport function parseDataURL(dataURL: string): [string, string] {\n const matcher = DATA_URL_PATTERN.exec(dataURL);\n const base64 = matcher ? matcher[2] : dataURL;\n return [base64, analyzeFileType(base64)?.mime ?? matcher?.[1] ?? DEFAULT_MIME_TYPE];\n}\n\n/**\n * データを読み込み DataURL を返す\n * 文字列は、DataURL 形式ならそのまま、そうでなければ base64 データとみなす\n * Blob は Blob の type を、それがなければ先頭バイトから判定した MIME タイプを使う\n *\n * @param {string | Blob | BinaryInput} data\n * @returns {Promise<string>}\n */\nexport async function readAsDataURL(data: string | Blob | BinaryInput): Promise<string> {\n if (typeof data === 'string') {\n return DATA_URL_PATTERN.test(data) ? data : base64ToDataURL(data);\n }\n if (data instanceof Blob) {\n const buffer = await data.arrayBuffer();\n return arrayBufferToDataURL(buffer, data.type || analyzeFileType(buffer)?.mime);\n }\n return arrayBufferToDataURL(data, analyzeFileType(data)?.mime);\n}\n\n/**\n * データを読み込み ArrayBuffer を返す\n * 文字列は、DataURL 形式ならその base64 部分を、そうでなければ base64 データとみなして変換する\n *\n * @param {string | Blob | BinaryInput} data\n * @returns {Promise<ArrayBuffer>}\n */\nexport async function readAsArrayBuffer(data: string | Blob | BinaryInput): Promise<ArrayBuffer> {\n if (typeof data === 'string') {\n return dataURLToArrayBuffer(data);\n }\n if (data instanceof Blob) {\n return data.arrayBuffer();\n }\n return toArrayBuffer(data);\n}\n\n/**\n * base64 データを DataURL に変換する\n * MIME タイプを省略した場合はデータの先頭バイトから判定する\n *\n * @param {string} base64\n * @param {string} [mimeType]\n * @returns {string} base64 が空の場合はそのまま返す\n */\nexport function base64ToDataURL(base64: string, mimeType?: string): string {\n if (!base64) {\n return base64;\n }\n return createDataURL(base64, mimeType || analyzeFileType(base64)?.mime);\n}\n\n/**\n * base64 データを ArrayBuffer に変換する\n *\n * @param {string} base64\n * @returns {ArrayBuffer}\n */\nexport function base64ToArrayBuffer(base64: string): ArrayBuffer {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\n/**\n * DataURL から base64 データを取り出す\n *\n * @param {string} dataURL\n * @returns {string} DataURL 形式でない場合はそのまま返す\n */\nexport function dataURLToBase64(dataURL: string): string {\n return DATA_URL_PATTERN.exec(dataURL)?.[2] ?? dataURL;\n}\n\n/**\n * DataURL を ArrayBuffer に変換する\n *\n * @param {string} dataURL\n * @returns {ArrayBuffer}\n */\nexport function dataURLToArrayBuffer(dataURL: string): ArrayBuffer {\n return base64ToArrayBuffer(dataURLToBase64(dataURL));\n}\n\n/**\n * バイナリを base64 データに変換する\n *\n * @param {BinaryInput} data\n * @returns {string}\n */\nexport function arrayBufferToBase64(data: BinaryInput): string {\n const bytes = toBytes(data);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * バイナリを DataURL に変換する\n *\n * @param {BinaryInput} data\n * @param {string} [mimeType] 省略時は 'application/octet-stream'\n * @returns {string}\n */\nexport function arrayBufferToDataURL(data: BinaryInput, mimeType?: string): string {\n return createDataURL(arrayBufferToBase64(data), mimeType);\n}\n\n/**\n * base64 データまたは DataURL が表すデータのバイト数を返す\n *\n * @param {string} data\n * @returns {number}\n */\nexport function calcSize(data: string): number {\n return dataURLToArrayBuffer(data).byteLength;\n}\n\n/**\n * 文字列またはバイナリを、BOM 付き UTF-16 の CSV の Blob にする\n * バイナリはすでに UTF-16LE で符号化されているものとして BOM だけを付ける\n *\n * @param {string | BinaryInput} data\n * @returns {Blob}\n */\nexport function convertUTF16withBOM(data: string | BinaryInput): Blob {\n if (!data) {\n return new Blob([]);\n }\n let parts: BlobPart[];\n if (typeof data === 'string') {\n const text = `\\ufeff${data}`;\n const codes = new Uint16Array(text.length);\n for (let i = 0; i < text.length; i++) {\n codes[i] = text.charCodeAt(i);\n }\n parts = [codes];\n } else {\n // 文字列で BOM を渡すと Blob が UTF-8 で符号化してしまうため、UTF-16LE の BOM をバイト列で付ける\n parts = [new Uint8Array([0xFF, 0xFE]), toArrayBuffer(data)];\n }\n return new Blob(parts, { type: 'text/csv;charset=utf-16;' });\n}\n\n/**\n * データの先頭バイトの署名からファイルの種類を判定する\n * 判定できる種類: PNG / JPEG / GIF / WebP / BMP / TIFF / SVG / PDF / ZIP / XLSX / DOCX / PPTX\n * 文字列は、DataURL 形式ならその base64 部分を、そうでなければ base64 データとみなす\n *\n * @param {string | BinaryInput} data\n * @returns {FileType | null} 判定できない場合は null\n */\nexport function analyzeFileType(data: string | BinaryInput): FileType | null {\n let bytes: Uint8Array;\n if (typeof data === 'string') {\n const base64 = dataURLToBase64(data).slice(0, SIGNATURE_BASE64_LENGTH);\n try {\n // 判定に必要な先頭だけを復号する。4文字単位で切らないと末尾がパディング不正になる\n bytes = toBytes(base64ToArrayBuffer(base64.slice(0, base64.length - base64.length % 4)));\n } catch (error) {\n // base64 として復号できない文字列は判定できない\n return null;\n }\n } else {\n bytes = toBytes(data);\n }\n return detectFileType(bytes);\n}\n\n/**\n * ファイル名に使えない文字(\\ / : * ? \" < > |)を取り除く\n *\n * @param {string} name\n * @returns {string}\n */\nexport function sanitizeFileName(name: string): string {\n return name.replace(/[\\\\/:*?\"<>|]/g, '');\n}\n"],"names":["DATA_URL_PATTERN","DEFAULT_MIME_TYPE","SVG_PATTERN","OFFICE_FILE_TYPES","AVIF_BRANDS","toBytes","data","toArrayBuffer","startsWith","bytes","signature","offset","expected","c","value","i","readBrands","end","text","brands","detectFileType","a","office","createDataURL","base64","mimeType","parseDataURL","dataURL","matcher","analyzeFileType","readAsDataURL","base64ToDataURL","buffer","arrayBufferToDataURL","readAsArrayBuffer","dataURLToArrayBuffer","base64ToArrayBuffer","binary","dataURLToBase64","arrayBufferToBase64","calcSize","convertUTF16withBOM","parts","codes","sanitizeFileName","name"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const p=/^data:([^;,]+)?(?:;[^,]*)?;base64,(.*)$/s,T="application/octet-stream";const w=/^\ufeff?\s*(?:<\?xml[^>]*>\s*)?(?:<!--[\s\S]*?-->\s*)*(?:<!DOCTYPE[^>]*>\s*)?<svg[\s>]/i,D=[{entry:"word/",type:{ext:"docx",mime:"application/vnd.openxmlformats-officedocument.wordprocessingml.document"}},{entry:"xl/",type:{ext:"xlsx",mime:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}},{entry:"ppt/",type:{ext:"pptx",mime:"application/vnd.openxmlformats-officedocument.presentationml.presentation"}}],R=["avif","avis"],a=e=>e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength),x=e=>a(e).slice().buffer,i=(e,t,r=0)=>{const n=typeof t=="string"?Array.from(t,o=>o.charCodeAt(0)):t;return e.length<r+n.length?!1:n.every((o,L)=>e[r+L]===o)},E=e=>{const t=Math.min(new DataView(e.buffer,e.byteOffset,e.byteLength).getUint32(0),e.length),r=new TextDecoder("latin1").decode(e.subarray(0,t)),n=[r.slice(8,12)];for(let o=16;o+4<=t;o+=4)n.push(r.slice(o,o+4));return n},_=e=>{if(i(e,[137,80,78,71,13,10,26,10]))return{ext:"png",mime:"image/png"};if(i(e,[255,216,255]))return{ext:"jpg",mime:"image/jpeg"};if(i(e,"GIF87a")||i(e,"GIF89a"))return{ext:"gif",mime:"image/gif"};if(i(e,"RIFF")&&i(e,"WEBP",8))return{ext:"webp",mime:"image/webp"};if(i(e,"BM"))return{ext:"bmp",mime:"image/bmp"};if(i(e,[73,73,42,0])||i(e,[77,77,0,42]))return{ext:"tif",mime:"image/tiff"};if(i(e,"ftyp",4)&&E(e).some(t=>R.includes(t)))return{ext:"avif",mime:"image/avif"};if(i(e,"%PDF-"))return{ext:"pdf",mime:"application/pdf"};if(i(e,[80,75,3,4])||i(e,[80,75,5,6])||i(e,[80,75,7,8])){const t=new TextDecoder("latin1").decode(e),r=D.find(n=>t.includes(n.entry));return r?r.type:{ext:"zip",mime:"application/zip"}}return w.test(new TextDecoder().decode(e))?{ext:"svg",mime:"image/svg+xml"}:null};function s(e,t){return`data:${t||T};base64,${e}`}function A(e){const t=p.exec(e),r=t?t[2]:e;return[r,f(r)?.mime??t?.[1]??T]}async function B(e){if(typeof e=="string")return p.test(e)?e:g(e);if(e instanceof Blob){const t=await e.arrayBuffer();return c(t,e.type||f(t)?.mime)}return c(e,f(e)?.mime)}async function h(e){return typeof e=="string"?m(e):e instanceof Blob?e.arrayBuffer():x(e)}function g(e,t){return e&&s(e,t||f(e)?.mime)}function u(e){const t=atob(e),r=new Uint8Array(t.length);for(let n=0;n<t.length;n++)r[n]=t.charCodeAt(n);return r.buffer}function l(e){return p.exec(e)?.[2]??e}function m(e){return u(l(e))}function y(e){const t=a(e);let r="";for(let n=0;n<t.length;n++)r+=String.fromCharCode(t[n]);return btoa(r)}function c(e,t){return s(y(e),t)}function U(e){return m(e).byteLength}function d(e){if(!e)return new Blob([]);let t;if(typeof e=="string"){const r=`\uFEFF${e}`,n=new Uint16Array(r.length);for(let o=0;o<r.length;o++)n[o]=r.charCodeAt(o);t=[n]}else t=[new Uint8Array([255,254]),x(e)];return new Blob(t,{type:"text/csv;charset=utf-16;"})}function f(e){let t;if(typeof e=="string"){const r=l(e).slice(0,16384);try{t=a(u(r.slice(0,r.length-r.length%4)))}catch{return null}}else t=a(e);return _(t)}function F(e){return e.replace(/[\\/:*?"<>|]/g,"")}const v=Object.freeze(Object.defineProperty({__proto__:null,analyzeFileType:f,arrayBufferToBase64:y,arrayBufferToDataURL:c,base64ToArrayBuffer:u,base64ToDataURL:g,calcSize:U,convertUTF16withBOM:d,createDataURL:s,dataURLToArrayBuffer:m,dataURLToBase64:l,parseDataURL:A,readAsArrayBuffer:h,readAsDataURL:B,sanitizeFileName:F},Symbol.toStringTag,{value:"Module"}));exports.analyzeFileType=f;exports.arrayBufferToBase64=y;exports.arrayBufferToDataURL=c;exports.base64ToArrayBuffer=u;exports.base64ToDataURL=g;exports.calcSize=U;exports.convertUTF16withBOM=d;exports.createDataURL=s;exports.dataURLToArrayBuffer=m;exports.dataURLToBase64=l;exports.fileUtil=v;exports.parseDataURL=A;exports.readAsArrayBuffer=h;exports.readAsDataURL=B;exports.sanitizeFileName=F;
|
|
2
|
+
//# sourceMappingURL=file-util-Dqiw5tBQ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-util-Dqiw5tBQ.cjs","sources":["../src/file-util.ts"],"sourcesContent":["/** 先頭バイトの署名から判定したファイルの種類 */\nexport interface FileType {\n /** 拡張子(ドットなし) */\n ext: string;\n /** MIMEタイプ */\n mime: string;\n}\n\n/** バイナリとして受け付ける値。Node.js の Buffer も ArrayBufferView として渡せる */\nexport type BinaryInput = ArrayBuffer | ArrayBufferView;\n\nconst DATA_URL_PATTERN = /^data:([^;,]+)?(?:;[^,]*)?;base64,(.*)$/s;\n\nconst DEFAULT_MIME_TYPE = 'application/octet-stream';\n\n/** 種類の判定に使う先頭の base64 の文字数。ZIP の中のエントリ名を探すため数KB分を見る */\nconst SIGNATURE_BASE64_LENGTH = 16384;\n\nconst SVG_PATTERN = /^\\ufeff?\\s*(?:<\\?xml[^>]*>\\s*)?(?:<!--[\\s\\S]*?-->\\s*)*(?:<!DOCTYPE[^>]*>\\s*)?<svg[\\s>]/i;\n\nconst OFFICE_FILE_TYPES: { entry: string; type: FileType; }[] = [\n { entry: 'word/', type: { ext: 'docx', mime: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' } },\n { entry: 'xl/', type: { ext: 'xlsx', mime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' } },\n { entry: 'ppt/', type: { ext: 'pptx', mime: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' } }\n];\n\n/** ftyp ボックスのブランドのうち、AVIF を表すもの */\nconst AVIF_BRANDS = ['avif', 'avis'];\n\nconst toBytes = (data: BinaryInput): Uint8Array => {\n return data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n};\n\nconst toArrayBuffer = (data: BinaryInput): ArrayBuffer => toBytes(data).slice().buffer as ArrayBuffer;\n\nconst startsWith = (bytes: Uint8Array, signature: number[] | string, offset: number = 0): boolean => {\n const expected = typeof signature === 'string' ? Array.from(signature, c => c.charCodeAt(0)) : signature;\n if (bytes.length < offset + expected.length) {\n return false;\n }\n return expected.every((value, i) => bytes[offset + i] === value);\n};\n\n/**\n * ISOBMFF の ftyp ボックスに並ぶブランドを返す\n * 8バイト目からメジャーブランド、16バイト目から互換ブランドが4文字ずつ並ぶ\n *\n * @param {Uint8Array} bytes\n * @returns {string[]}\n */\nconst readBrands = (bytes: Uint8Array): string[] => {\n const end = Math.min(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0), bytes.length);\n const text = new TextDecoder('latin1').decode(bytes.subarray(0, end));\n const brands = [text.slice(8, 12)];\n for (let i = 16; i + 4 <= end; i += 4) {\n brands.push(text.slice(i, i + 4));\n }\n return brands;\n};\n\nconst detectFileType = (bytes: Uint8Array): FileType | null => {\n if (startsWith(bytes, [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) {\n return { ext: 'png', mime: 'image/png' };\n }\n if (startsWith(bytes, [0xFF, 0xD8, 0xFF])) {\n return { ext: 'jpg', mime: 'image/jpeg' };\n }\n if (startsWith(bytes, 'GIF87a') || startsWith(bytes, 'GIF89a')) {\n return { ext: 'gif', mime: 'image/gif' };\n }\n if (startsWith(bytes, 'RIFF') && startsWith(bytes, 'WEBP', 8)) {\n return { ext: 'webp', mime: 'image/webp' };\n }\n if (startsWith(bytes, 'BM')) {\n return { ext: 'bmp', mime: 'image/bmp' };\n }\n if (startsWith(bytes, [0x49, 0x49, 0x2A, 0x00]) || startsWith(bytes, [0x4D, 0x4D, 0x00, 0x2A])) {\n return { ext: 'tif', mime: 'image/tiff' };\n }\n if (startsWith(bytes, 'ftyp', 4) && readBrands(bytes).some(a => AVIF_BRANDS.includes(a))) {\n return { ext: 'avif', mime: 'image/avif' };\n }\n if (startsWith(bytes, '%PDF-')) {\n return { ext: 'pdf', mime: 'application/pdf' };\n }\n if (startsWith(bytes, [0x50, 0x4B, 0x03, 0x04]) || startsWith(bytes, [0x50, 0x4B, 0x05, 0x06]) || startsWith(bytes, [0x50, 0x4B, 0x07, 0x08])) {\n // Office Open XML も ZIP なので、ZIP に含まれるエントリ名で見分ける\n const text = new TextDecoder('latin1').decode(bytes);\n const office = OFFICE_FILE_TYPES.find(a => text.includes(a.entry));\n return office ? office.type : { ext: 'zip', mime: 'application/zip' };\n }\n if (SVG_PATTERN.test(new TextDecoder().decode(bytes))) {\n return { ext: 'svg', mime: 'image/svg+xml' };\n }\n return null;\n};\n\n/**\n * base64 データと MIME タイプから DataURL を生成する\n *\n * @param {string} base64\n * @param {string} [mimeType] 省略時は 'application/octet-stream'\n * @returns {string}\n */\nexport function createDataURL(base64: string, mimeType?: string): string {\n return `data:${mimeType || DEFAULT_MIME_TYPE};base64,${base64}`;\n}\n\n/**\n * DataURL を base64 データと MIME タイプに分解する\n * MIME タイプは DataURL に書かれた値ではなく、データの先頭バイトから判定した値を返す。判定できない場合は DataURL に書かれた値、それもなければ 'application/octet-stream'\n * DataURL 形式でない文字列は base64 データとみなす\n *\n * @param {string} dataURL\n * @returns {[string, string]} [base64, mimeType]\n */\nexport function parseDataURL(dataURL: string): [string, string] {\n const matcher = DATA_URL_PATTERN.exec(dataURL);\n const base64 = matcher ? matcher[2] : dataURL;\n return [base64, analyzeFileType(base64)?.mime ?? matcher?.[1] ?? DEFAULT_MIME_TYPE];\n}\n\n/**\n * データを読み込み DataURL を返す\n * 文字列は、DataURL 形式ならそのまま、そうでなければ base64 データとみなす\n * Blob は Blob の type を、それがなければ先頭バイトから判定した MIME タイプを使う\n *\n * @param {string | Blob | BinaryInput} data\n * @returns {Promise<string>}\n */\nexport async function readAsDataURL(data: string | Blob | BinaryInput): Promise<string> {\n if (typeof data === 'string') {\n return DATA_URL_PATTERN.test(data) ? data : base64ToDataURL(data);\n }\n if (data instanceof Blob) {\n const buffer = await data.arrayBuffer();\n return arrayBufferToDataURL(buffer, data.type || analyzeFileType(buffer)?.mime);\n }\n return arrayBufferToDataURL(data, analyzeFileType(data)?.mime);\n}\n\n/**\n * データを読み込み ArrayBuffer を返す\n * 文字列は、DataURL 形式ならその base64 部分を、そうでなければ base64 データとみなして変換する\n *\n * @param {string | Blob | BinaryInput} data\n * @returns {Promise<ArrayBuffer>}\n */\nexport async function readAsArrayBuffer(data: string | Blob | BinaryInput): Promise<ArrayBuffer> {\n if (typeof data === 'string') {\n return dataURLToArrayBuffer(data);\n }\n if (data instanceof Blob) {\n return data.arrayBuffer();\n }\n return toArrayBuffer(data);\n}\n\n/**\n * base64 データを DataURL に変換する\n * MIME タイプを省略した場合はデータの先頭バイトから判定する\n *\n * @param {string} base64\n * @param {string} [mimeType]\n * @returns {string} base64 が空の場合はそのまま返す\n */\nexport function base64ToDataURL(base64: string, mimeType?: string): string {\n if (!base64) {\n return base64;\n }\n return createDataURL(base64, mimeType || analyzeFileType(base64)?.mime);\n}\n\n/**\n * base64 データを ArrayBuffer に変換する\n *\n * @param {string} base64\n * @returns {ArrayBuffer}\n */\nexport function base64ToArrayBuffer(base64: string): ArrayBuffer {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\n/**\n * DataURL から base64 データを取り出す\n *\n * @param {string} dataURL\n * @returns {string} DataURL 形式でない場合はそのまま返す\n */\nexport function dataURLToBase64(dataURL: string): string {\n return DATA_URL_PATTERN.exec(dataURL)?.[2] ?? dataURL;\n}\n\n/**\n * DataURL を ArrayBuffer に変換する\n *\n * @param {string} dataURL\n * @returns {ArrayBuffer}\n */\nexport function dataURLToArrayBuffer(dataURL: string): ArrayBuffer {\n return base64ToArrayBuffer(dataURLToBase64(dataURL));\n}\n\n/**\n * バイナリを base64 データに変換する\n *\n * @param {BinaryInput} data\n * @returns {string}\n */\nexport function arrayBufferToBase64(data: BinaryInput): string {\n const bytes = toBytes(data);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * バイナリを DataURL に変換する\n *\n * @param {BinaryInput} data\n * @param {string} [mimeType] 省略時は 'application/octet-stream'\n * @returns {string}\n */\nexport function arrayBufferToDataURL(data: BinaryInput, mimeType?: string): string {\n return createDataURL(arrayBufferToBase64(data), mimeType);\n}\n\n/**\n * base64 データまたは DataURL が表すデータのバイト数を返す\n *\n * @param {string} data\n * @returns {number}\n */\nexport function calcSize(data: string): number {\n return dataURLToArrayBuffer(data).byteLength;\n}\n\n/**\n * 文字列またはバイナリを、BOM 付き UTF-16 の CSV の Blob にする\n * バイナリはすでに UTF-16LE で符号化されているものとして BOM だけを付ける\n *\n * @param {string | BinaryInput} data\n * @returns {Blob}\n */\nexport function convertUTF16withBOM(data: string | BinaryInput): Blob {\n if (!data) {\n return new Blob([]);\n }\n let parts: BlobPart[];\n if (typeof data === 'string') {\n const text = `\\ufeff${data}`;\n const codes = new Uint16Array(text.length);\n for (let i = 0; i < text.length; i++) {\n codes[i] = text.charCodeAt(i);\n }\n parts = [codes];\n } else {\n // 文字列で BOM を渡すと Blob が UTF-8 で符号化してしまうため、UTF-16LE の BOM をバイト列で付ける\n parts = [new Uint8Array([0xFF, 0xFE]), toArrayBuffer(data)];\n }\n return new Blob(parts, { type: 'text/csv;charset=utf-16;' });\n}\n\n/**\n * データの先頭バイトの署名からファイルの種類を判定する\n * 判定できる種類: PNG / JPEG / GIF / WebP / BMP / TIFF / SVG / PDF / ZIP / XLSX / DOCX / PPTX\n * 文字列は、DataURL 形式ならその base64 部分を、そうでなければ base64 データとみなす\n *\n * @param {string | BinaryInput} data\n * @returns {FileType | null} 判定できない場合は null\n */\nexport function analyzeFileType(data: string | BinaryInput): FileType | null {\n let bytes: Uint8Array;\n if (typeof data === 'string') {\n const base64 = dataURLToBase64(data).slice(0, SIGNATURE_BASE64_LENGTH);\n try {\n // 判定に必要な先頭だけを復号する。4文字単位で切らないと末尾がパディング不正になる\n bytes = toBytes(base64ToArrayBuffer(base64.slice(0, base64.length - base64.length % 4)));\n } catch (error) {\n // base64 として復号できない文字列は判定できない\n return null;\n }\n } else {\n bytes = toBytes(data);\n }\n return detectFileType(bytes);\n}\n\n/**\n * ファイル名に使えない文字(\\ / : * ? \" < > |)を取り除く\n *\n * @param {string} name\n * @returns {string}\n */\nexport function sanitizeFileName(name: string): string {\n return name.replace(/[\\\\/:*?\"<>|]/g, '');\n}\n"],"names":["DATA_URL_PATTERN","DEFAULT_MIME_TYPE","SVG_PATTERN","OFFICE_FILE_TYPES","AVIF_BRANDS","toBytes","data","toArrayBuffer","startsWith","bytes","signature","offset","expected","c","value","i","readBrands","end","text","brands","detectFileType","a","office","createDataURL","base64","mimeType","parseDataURL","dataURL","matcher","analyzeFileType","readAsDataURL","base64ToDataURL","buffer","arrayBufferToDataURL","readAsArrayBuffer","dataURLToArrayBuffer","base64ToArrayBuffer","binary","dataURLToBase64","arrayBufferToBase64","calcSize","convertUTF16withBOM","parts","codes","sanitizeFileName","name"],"mappings":"aAWA,MAAMA,EAAmB,2CAEnBC,EAAoB,2BAK1B,MAAMC,EAAc,0FAEdC,EAA0D,CAC9D,CAAE,MAAO,QAAS,KAAM,CAAE,IAAK,OAAQ,KAAM,0EAA0E,EACvH,CAAE,MAAO,MAAO,KAAM,CAAE,IAAK,OAAQ,KAAM,oEAAoE,EAC/G,CAAE,MAAO,OAAQ,KAAM,CAAE,IAAK,OAAQ,KAAM,2EAAA,CAA4E,CAC1H,EAGMC,EAAc,CAAC,OAAQ,MAAM,EAE7BC,EAAWC,GACRA,aAAgB,YAAc,IAAI,WAAWA,CAAI,EAAI,IAAI,WAAWA,EAAK,OAAQA,EAAK,WAAYA,EAAK,UAAU,EAGpHC,EAAiBD,GAAmCD,EAAQC,CAAI,EAAE,QAAQ,OAE1EE,EAAa,CAACC,EAAmBC,EAA8BC,EAAiB,IAAe,CACnG,MAAMC,EAAW,OAAOF,GAAc,SAAW,MAAM,KAAKA,EAAWG,GAAKA,EAAE,WAAW,CAAC,CAAC,EAAIH,EAC/F,OAAID,EAAM,OAASE,EAASC,EAAS,OAC5B,GAEFA,EAAS,MAAM,CAACE,EAAOC,IAAMN,EAAME,EAASI,CAAC,IAAMD,CAAK,CACjE,EASME,EAAcP,GAAgC,CAClD,MAAMQ,EAAM,KAAK,IAAI,IAAI,SAASR,EAAM,OAAQA,EAAM,WAAYA,EAAM,UAAU,EAAE,UAAU,CAAC,EAAGA,EAAM,MAAM,EACxGS,EAAO,IAAI,YAAY,QAAQ,EAAE,OAAOT,EAAM,SAAS,EAAGQ,CAAG,CAAC,EAC9DE,EAAS,CAACD,EAAK,MAAM,EAAG,EAAE,CAAC,EACjC,QAASH,EAAI,GAAIA,EAAI,GAAKE,EAAKF,GAAK,EAClCI,EAAO,KAAKD,EAAK,MAAMH,EAAGA,EAAI,CAAC,CAAC,EAElC,OAAOI,CACT,EAEMC,EAAkBX,GAAuC,CAC7D,GAAID,EAAWC,EAAO,CAAC,IAAM,GAAM,GAAM,GAAM,GAAM,GAAM,GAAM,EAAI,CAAC,EACpE,MAAO,CAAE,IAAK,MAAO,KAAM,WAAA,EAE7B,GAAID,EAAWC,EAAO,CAAC,IAAM,IAAM,GAAI,CAAC,EACtC,MAAO,CAAE,IAAK,MAAO,KAAM,YAAA,EAE7B,GAAID,EAAWC,EAAO,QAAQ,GAAKD,EAAWC,EAAO,QAAQ,EAC3D,MAAO,CAAE,IAAK,MAAO,KAAM,WAAA,EAE7B,GAAID,EAAWC,EAAO,MAAM,GAAKD,EAAWC,EAAO,OAAQ,CAAC,EAC1D,MAAO,CAAE,IAAK,OAAQ,KAAM,YAAA,EAE9B,GAAID,EAAWC,EAAO,IAAI,EACxB,MAAO,CAAE,IAAK,MAAO,KAAM,WAAA,EAE7B,GAAID,EAAWC,EAAO,CAAC,GAAM,GAAM,GAAM,CAAI,CAAC,GAAKD,EAAWC,EAAO,CAAC,GAAM,GAAM,EAAM,EAAI,CAAC,EAC3F,MAAO,CAAE,IAAK,MAAO,KAAM,YAAA,EAE7B,GAAID,EAAWC,EAAO,OAAQ,CAAC,GAAKO,EAAWP,CAAK,EAAE,KAAKY,GAAKjB,EAAY,SAASiB,CAAC,CAAC,EACrF,MAAO,CAAE,IAAK,OAAQ,KAAM,YAAA,EAE9B,GAAIb,EAAWC,EAAO,OAAO,EAC3B,MAAO,CAAE,IAAK,MAAO,KAAM,iBAAA,EAE7B,GAAID,EAAWC,EAAO,CAAC,GAAM,GAAM,EAAM,CAAI,CAAC,GAAKD,EAAWC,EAAO,CAAC,GAAM,GAAM,EAAM,CAAI,CAAC,GAAKD,EAAWC,EAAO,CAAC,GAAM,GAAM,EAAM,CAAI,CAAC,EAAG,CAE7I,MAAMS,EAAO,IAAI,YAAY,QAAQ,EAAE,OAAOT,CAAK,EAC7Ca,EAASnB,EAAkB,KAAKkB,GAAKH,EAAK,SAASG,EAAE,KAAK,CAAC,EACjE,OAAOC,EAASA,EAAO,KAAO,CAAE,IAAK,MAAO,KAAM,iBAAA,CACpD,CACA,OAAIpB,EAAY,KAAK,IAAI,YAAA,EAAc,OAAOO,CAAK,CAAC,EAC3C,CAAE,IAAK,MAAO,KAAM,eAAA,EAEtB,IACT,EASO,SAASc,EAAcC,EAAgBC,EAA2B,CACvE,MAAO,QAAQA,GAAYxB,CAAiB,WAAWuB,CAAM,EAC/D,CAUO,SAASE,EAAaC,EAAmC,CAC9D,MAAMC,EAAU5B,EAAiB,KAAK2B,CAAO,EACvCH,EAASI,EAAUA,EAAQ,CAAC,EAAID,EACtC,MAAO,CAACH,EAAQK,EAAgBL,CAAM,GAAG,MAAQI,IAAU,CAAC,GAAK3B,CAAiB,CACpF,CAUA,eAAsB6B,EAAcxB,EAAoD,CACtF,GAAI,OAAOA,GAAS,SAClB,OAAON,EAAiB,KAAKM,CAAI,EAAIA,EAAOyB,EAAgBzB,CAAI,EAElE,GAAIA,aAAgB,KAAM,CACxB,MAAM0B,EAAS,MAAM1B,EAAK,YAAA,EAC1B,OAAO2B,EAAqBD,EAAQ1B,EAAK,MAAQuB,EAAgBG,CAAM,GAAG,IAAI,CAChF,CACA,OAAOC,EAAqB3B,EAAMuB,EAAgBvB,CAAI,GAAG,IAAI,CAC/D,CASA,eAAsB4B,EAAkB5B,EAAyD,CAC/F,OAAI,OAAOA,GAAS,SACX6B,EAAqB7B,CAAI,EAE9BA,aAAgB,KACXA,EAAK,YAAA,EAEPC,EAAcD,CAAI,CAC3B,CAUO,SAASyB,EAAgBP,EAAgBC,EAA2B,CACzE,OAAKD,GAGED,EAAcC,EAAQC,GAAYI,EAAgBL,CAAM,GAAG,IAAI,CACxE,CAQO,SAASY,EAAoBZ,EAA6B,CAC/D,MAAMa,EAAS,KAAKb,CAAM,EACpBf,EAAQ,IAAI,WAAW4B,EAAO,MAAM,EAC1C,QAAStB,EAAI,EAAGA,EAAIsB,EAAO,OAAQtB,IACjCN,EAAMM,CAAC,EAAIsB,EAAO,WAAWtB,CAAC,EAEhC,OAAON,EAAM,MACf,CAQO,SAAS6B,EAAgBX,EAAyB,CACvD,OAAO3B,EAAiB,KAAK2B,CAAO,IAAI,CAAC,GAAKA,CAChD,CAQO,SAASQ,EAAqBR,EAA8B,CACjE,OAAOS,EAAoBE,EAAgBX,CAAO,CAAC,CACrD,CAQO,SAASY,EAAoBjC,EAA2B,CAC7D,MAAMG,EAAQJ,EAAQC,CAAI,EAC1B,IAAI+B,EAAS,GACb,QAAStB,EAAI,EAAGA,EAAIN,EAAM,OAAQM,IAChCsB,GAAU,OAAO,aAAa5B,EAAMM,CAAC,CAAC,EAExC,OAAO,KAAKsB,CAAM,CACpB,CASO,SAASJ,EAAqB3B,EAAmBmB,EAA2B,CACjF,OAAOF,EAAcgB,EAAoBjC,CAAI,EAAGmB,CAAQ,CAC1D,CAQO,SAASe,EAASlC,EAAsB,CAC7C,OAAO6B,EAAqB7B,CAAI,EAAE,UACpC,CASO,SAASmC,EAAoBnC,EAAkC,CACpE,GAAI,CAACA,EACH,OAAO,IAAI,KAAK,EAAE,EAEpB,IAAIoC,EACJ,GAAI,OAAOpC,GAAS,SAAU,CAC5B,MAAMY,EAAO,SAASZ,CAAI,GACpBqC,EAAQ,IAAI,YAAYzB,EAAK,MAAM,EACzC,QAASH,EAAI,EAAGA,EAAIG,EAAK,OAAQH,IAC/B4B,EAAM5B,CAAC,EAAIG,EAAK,WAAWH,CAAC,EAE9B2B,EAAQ,CAACC,CAAK,CAChB,MAEED,EAAQ,CAAC,IAAI,WAAW,CAAC,IAAM,GAAI,CAAC,EAAGnC,EAAcD,CAAI,CAAC,EAE5D,OAAO,IAAI,KAAKoC,EAAO,CAAE,KAAM,2BAA4B,CAC7D,CAUO,SAASb,EAAgBvB,EAA6C,CAC3E,IAAIG,EACJ,GAAI,OAAOH,GAAS,SAAU,CAC5B,MAAMkB,EAASc,EAAgBhC,CAAI,EAAE,MAAM,EAAG,KAAuB,EACrE,GAAI,CAEFG,EAAQJ,EAAQ+B,EAAoBZ,EAAO,MAAM,EAAGA,EAAO,OAASA,EAAO,OAAS,CAAC,CAAC,CAAC,CACzF,MAAgB,CAEd,OAAO,IACT,CACF,MACEf,EAAQJ,EAAQC,CAAI,EAEtB,OAAOc,EAAeX,CAAK,CAC7B,CAQO,SAASmC,EAAiBC,EAAsB,CACrD,OAAOA,EAAK,QAAQ,gBAAiB,EAAE,CACzC"}
|
package/lib/file-util.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./file-util-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./file-util-Dqiw5tBQ.cjs");exports.analyzeFileType=a.analyzeFileType;exports.arrayBufferToBase64=a.arrayBufferToBase64;exports.arrayBufferToDataURL=a.arrayBufferToDataURL;exports.base64ToArrayBuffer=a.base64ToArrayBuffer;exports.base64ToDataURL=a.base64ToDataURL;exports.calcSize=a.calcSize;exports.convertUTF16withBOM=a.convertUTF16withBOM;exports.createDataURL=a.createDataURL;exports.dataURLToArrayBuffer=a.dataURLToArrayBuffer;exports.dataURLToBase64=a.dataURLToBase64;exports.parseDataURL=a.parseDataURL;exports.readAsArrayBuffer=a.readAsArrayBuffer;exports.readAsDataURL=a.readAsDataURL;exports.sanitizeFileName=a.sanitizeFileName;
|
|
2
2
|
//# sourceMappingURL=file-util.cjs.map
|
package/lib/file-util.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as r, b as s, c as t, d as f, e as o, g as B, h as T, i as U, j as i, k as y, p as L, r as R, l as c, s as d } from "./file-util-
|
|
1
|
+
import { a as r, b as s, c as t, d as f, e as o, g as B, h as T, i as U, j as i, k as y, p as L, r as R, l as c, s as d } from "./file-util-CO5vjmkO.js";
|
|
2
2
|
export {
|
|
3
3
|
r as analyzeFileType,
|
|
4
4
|
s as arrayBufferToBase64,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { diffChars as u } from "diff";
|
|
2
|
+
import { f as h } from "./json-util-C_Pm1BpJ.js";
|
|
3
|
+
const m = /(<!--[\s\S]*?-->|<[^>]*>|&(?:#\d+|#x[\da-f]+|\w+);)/i, b = {
|
|
4
|
+
'"': """,
|
|
5
|
+
"&": "&",
|
|
6
|
+
"'": "'",
|
|
7
|
+
"<": "<",
|
|
8
|
+
">": ">"
|
|
9
|
+
}, l = (r) => r.replace(/["&'<>]/g, (e) => b[e]), S = (r) => typeof r == "string" ? r : Array.isArray(r) ? r.filter(Boolean).join(" ") : Object.keys(r).filter((e) => r[e]).join(" "), j = (r) => typeof r == "string" ? r : Object.entries(r).map(([e, t]) => `${e.startsWith("--") ? e : e.replace(/[A-Z]/g, (n) => `-${n.toLowerCase()}`)}: ${t}`).join("; "), d = {
|
|
10
|
+
added: "color: var(--dwui-color-text-diff-added, light-dark(#006400, rgb(121, 227, 121)))",
|
|
11
|
+
removed: "color: var(--dwui-color-text-diff-removed, light-dark(#ff0000, rgb(222, 109, 109)))",
|
|
12
|
+
same: "color: var(--dwui-color-text-diff-same, light-dark(#838383, #808080))"
|
|
13
|
+
}, f = (r, e, t, o) => {
|
|
14
|
+
let n = "";
|
|
15
|
+
const s = t?.class == null ? "" : S(t.class);
|
|
16
|
+
s && (n += ` class="${l(s)}"`);
|
|
17
|
+
const a = [o, t?.style == null ? "" : j(t.style)].filter(Boolean).join("; ");
|
|
18
|
+
return a && (n += ` style="${l(a)}"`), `<${r}${n}>${l(e)}</${r}>`;
|
|
19
|
+
};
|
|
20
|
+
function g(r, e) {
|
|
21
|
+
if (!r)
|
|
22
|
+
return "";
|
|
23
|
+
const t = (o) => o.replace(/\r\n|\r|\n/g, "<br>").replace(/\t/g, " ").replace(/ /g, " ");
|
|
24
|
+
return e?.html ? r.split(m).map((o, n) => n % 2 === 1 ? o : t(o)).join("") : t(l(r));
|
|
25
|
+
}
|
|
26
|
+
function y(r, e) {
|
|
27
|
+
const { html: t, ...o } = e ?? {}, n = h(r, o);
|
|
28
|
+
return n == null ? "" : g(String(n), { html: t });
|
|
29
|
+
}
|
|
30
|
+
function $(r, e, t) {
|
|
31
|
+
if (!r)
|
|
32
|
+
return "";
|
|
33
|
+
const o = (i) => t?.html ? i : l(i);
|
|
34
|
+
if (!e)
|
|
35
|
+
return o(r);
|
|
36
|
+
const n = e.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"), s = new RegExp(`(${n})`, t?.caseInsensitive ? "i" : ""), a = (i) => i.split(s).map((c, p) => p % 2 === 0 ? o(c) : f("mark", c, t)).join("");
|
|
37
|
+
return t?.html ? r.split(m).map((i, c) => c % 2 === 1 ? i : a(i)).join("") : a(r);
|
|
38
|
+
}
|
|
39
|
+
function x(r, e, t) {
|
|
40
|
+
const o = u(r ?? "", e ?? "", { ignoreCase: t?.ignoreCase });
|
|
41
|
+
let n = "";
|
|
42
|
+
for (const s of o)
|
|
43
|
+
s.added ? n += f("span", s.value, t?.added, d.added) : s.removed ? n += f("span", s.value, t?.removed, d.removed) : n += f("span", s.value, t?.same, d.same);
|
|
44
|
+
return n;
|
|
45
|
+
}
|
|
46
|
+
const E = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
47
|
+
__proto__: null,
|
|
48
|
+
diffForWeb: x,
|
|
49
|
+
formatJsonStringForWeb: y,
|
|
50
|
+
formatStringForWeb: g,
|
|
51
|
+
highlightWord: $
|
|
52
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
53
|
+
export {
|
|
54
|
+
g as a,
|
|
55
|
+
$ as b,
|
|
56
|
+
x as d,
|
|
57
|
+
y as f,
|
|
58
|
+
E as h
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=html-util-BctKzfnH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-util-BctKzfnH.js","sources":["../src/html-util.ts"],"sourcesContent":["import { diffChars } from 'diff';\nimport { formatJsonString } from './json-util';\nimport type { FormatJsonStringOptions } from './json-util';\n\n/**\n * class属性に指定する値\n * 配列は要素を空白区切りで連結し、Recordは値がtrueのキーだけを連結する\n */\nexport type HtmlClassValue = string | string[] | Record<string, boolean>;\n\n/**\n * style属性に指定する値\n * Recordのキーはキャメルケースをケバブケースに変換する。数値には単位を付けない\n */\nexport type HtmlStyleValue = string | Record<string, string | number>;\n\n/**\n * 生成するタグに付与する属性\n */\nexport interface HtmlTagOptions {\n class?: HtmlClassValue;\n style?: HtmlStyleValue;\n}\n\nconst HTML_TOKEN = /(<!--[\\s\\S]*?-->|<[^>]*>|&(?:#\\d+|#x[\\da-f]+|\\w+);)/i;\n\nconst HTML_ESCAPE_CHARS: Record<string, string> = {\n '\"': '"',\n '&': '&',\n '\\'': ''',\n '<': '<',\n '>': '>'\n};\n\nconst escapeHtml = (str: string): string => str.replace(/[\"&'<>]/g, (c) => HTML_ESCAPE_CHARS[c]);\n\nconst toClassString = (value: HtmlClassValue): string => {\n if (typeof value === 'string') {\n return value;\n }\n if (Array.isArray(value)) {\n return value.filter(Boolean).join(' ');\n }\n return Object.keys(value).filter(key => value[key]).join(' ');\n};\n\nconst toStyleString = (value: HtmlStyleValue): string => {\n if (typeof value === 'string') {\n return value;\n }\n return Object.entries(value)\n .map(([key, v]) => {\n // カスタムプロパティ(--xxx)は大文字小文字を区別するため変換しない\n const property = key.startsWith('--') ? key : key.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`);\n return `${property}: ${v}`;\n })\n .join('; ');\n};\n\n/** diffForWebの既定の文字色 */\nconst DIFF_STYLES = {\n added: 'color: var(--dwui-color-text-diff-added, light-dark(#006400, rgb(121, 227, 121)))',\n removed: 'color: var(--dwui-color-text-diff-removed, light-dark(#ff0000, rgb(222, 109, 109)))',\n same: 'color: var(--dwui-color-text-diff-same, light-dark(#838383, #808080))'\n};\n\n/**\n * 値をエスケープしたタグを返す\n *\n * @param {string} tagName\n * @param {string} value\n * @param {HtmlTagOptions} [options]\n * @param {string} [defaultStyle] optionsのstyleより前に出力するstyle\n * @returns {string}\n */\nconst toElement = (tagName: string, value: string, options?: HtmlTagOptions, defaultStyle?: string): string => {\n let attributes = '';\n const className = options?.class == null ? '' : toClassString(options.class);\n if (className) {\n attributes += ` class=\"${escapeHtml(className)}\"`;\n }\n const style = [defaultStyle, options?.style == null ? '' : toStyleString(options.style)].filter(Boolean).join('; ');\n if (style) {\n attributes += ` style=\"${escapeHtml(style)}\"`;\n }\n return `<${tagName}${attributes}>${escapeHtml(value)}</${tagName}>`;\n};\n\n/**\n * 文字列をWEB表示用にフォーマットする\n * オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能\n *\n * @param {string | null | undefined} str\n * @param {*} [options]\n * ├ html boolean trueを指定した場合、入力された文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function formatStringForWeb(str: string | null | undefined, options?: {\n html?: boolean;\n}): string {\n if (!str) {\n return '';\n }\n\n const formatText = (text: string): string => text\n .replace(/\\r\\n|\\r|\\n/g, '<br>')\n .replace(/\\t/g, ' ')\n .replace(/ /g, ' ');\n\n if (options?.html) {\n // 奇数番目がタグ・コメント・文字参照。偶数番目のテキスト部分だけをフォーマットする\n return str\n .split(HTML_TOKEN)\n .map((segment, i) => i % 2 === 1 ? segment : formatText(segment))\n .join('');\n }\n\n return formatText(escapeHtml(str));\n}\n\n/**\n * 値を整形したJSON文字列にしてWEB表示用にフォーマットする\n * formatJsonStringで整形した文字列をformatStringForWebで変換する\n *\n * @param {any} value\n * @param {*} [options] formatJsonStringのオプションに以下を加えたもの\n * ├ html boolean trueを指定した場合、文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function formatJsonStringForWeb(value: any, options?: FormatJsonStringOptions & {\n html?: boolean;\n}): string {\n const { html, ...formatOptions } = options ?? {};\n const json = formatJsonString(value, formatOptions);\n return json == null ? '' : formatStringForWeb(String(json), { html });\n}\n\n/**\n * 文字列の中で一致したワードをmarkタグで囲んだHTML文字列を返す\n * オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能\n *\n * 例)\n * HtmlUtil.highlightWord('This is a test message', 'test', { class: 'highlight' });\n * → 'This is a <mark class=\"highlight\">test</mark> message'\n *\n * @param {string | null | undefined} value\n * @param {string | null | undefined} word\n * @param {*} [options] markタグに付与するclass, styleのほか、以下を指定できる\n * ├ class string | string[] | Record<string, boolean>\n * ├ style string | Record<string, string | number>\n * ├ caseInsensitive boolean trueを指定した場合、大文字小文字を区別しない\n * ├ html boolean trueを指定した場合、入力された文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function highlightWord(\n value: string | null | undefined,\n word: string | null | undefined,\n options?: HtmlTagOptions & {\n caseInsensitive?: boolean;\n html?: boolean;\n }\n): string {\n if (!value) {\n return '';\n }\n\n const toHtml = (text: string): string => options?.html ? text : escapeHtml(text);\n if (!word) {\n return toHtml(value);\n }\n\n const pattern = word.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&').replace(/-/g, '\\\\x2d');\n const regex = new RegExp(`(${pattern})`, options?.caseInsensitive ? 'i' : '');\n // キャプチャグループで分割すると、奇数番目の要素が一致した部分になる\n const highlight = (text: string): string => text\n .split(regex)\n .map((part, i) => i % 2 === 0 ? toHtml(part) : toElement('mark', part, options))\n .join('');\n\n if (!options?.html) {\n return highlight(value);\n }\n\n // 奇数番目がタグ・コメント・文字参照。偶数番目のテキスト部分だけをハイライトする\n return value\n .split(HTML_TOKEN)\n .map((segment, i) => i % 2 === 1 ? segment : highlight(segment))\n .join('');\n}\n\n/**\n * 文字列を1文字ずつ比較し、差分をspanタグで囲んだHTML文字列を返す\n * 追加・削除・一致の部分ごとに既定の文字色を持つ。文字色はCSS変数(--dwui-color-text-diff-added / --dwui-color-text-diff-removed / --dwui-color-text-diff-same)で変更できる\n * 追加・削除・一致の部分ごとに、spanタグに付与するclass, styleを指定できる。styleは既定の文字色より後に出力する\n * 入力文字列はプレーンなテキストであるとみなす\n * 出力される文字列は、diffで埋め込まれるHTMLタグ以外はHTMLエスケープされ、HTMLセーフな文字列となる\n *\n * @param {string | null | undefined} text1 比較元の文字列\n * @param {string | null | undefined} text2 比較される文字列(通常、入力値はこちらに渡す)\n * @param {*} [options]\n * ├ ignoreCase boolean trueを指定した場合、大文字小文字を区別しない\n * ├ added HtmlTagOptions text2で追加された部分のspanタグに付与する属性\n * ├ removed HtmlTagOptions text2で削除された部分のspanタグに付与する属性\n * ├ same HtmlTagOptions 一致した部分のspanタグに付与する属性\n * @returns {string}\n */\nexport function diffForWeb(text1: string | null | undefined, text2: string | null | undefined, options?: {\n ignoreCase?: boolean;\n added?: HtmlTagOptions;\n removed?: HtmlTagOptions;\n same?: HtmlTagOptions;\n}): string {\n const changes = diffChars(text1 ?? '', text2 ?? '', { ignoreCase: options?.ignoreCase });\n let html = '';\n for (const change of changes) {\n if (change.added) {\n html += toElement('span', change.value, options?.added, DIFF_STYLES.added);\n } else if (change.removed) {\n html += toElement('span', change.value, options?.removed, DIFF_STYLES.removed);\n } else {\n html += toElement('span', change.value, options?.same, DIFF_STYLES.same);\n }\n }\n return html;\n}\n"],"names":["HTML_TOKEN","HTML_ESCAPE_CHARS","escapeHtml","str","c","toClassString","value","key","toStyleString","v","DIFF_STYLES","toElement","tagName","options","defaultStyle","attributes","className","style","formatStringForWeb","formatText","text","segment","i","formatJsonStringForWeb","html","formatOptions","json","formatJsonString","highlightWord","word","toHtml","pattern","regex","highlight","part","diffForWeb","text1","text2","changes","diffChars","change"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const S=require("diff"),j=require("./json-util-CKnsxu1e.cjs"),m=/(<!--[\s\S]*?-->|<[^>]*>|&(?:#\d+|#x[\da-f]+|\w+);)/i,y={'"':""","&":"&","'":"'","<":"<",">":">"},a=t=>t.replace(/["&'<>]/g,e=>y[e]),$=t=>typeof t=="string"?t:Array.isArray(t)?t.filter(Boolean).join(" "):Object.keys(t).filter(e=>t[e]).join(" "),W=t=>typeof t=="string"?t:Object.entries(t).map(([e,r])=>`${e.startsWith("--")?e:e.replace(/[A-Z]/g,n=>`-${n.toLowerCase()}`)}: ${r}`).join("; "),d={added:"color: var(--dwui-color-text-diff-added, light-dark(#006400, rgb(121, 227, 121)))",removed:"color: var(--dwui-color-text-diff-removed, light-dark(#ff0000, rgb(222, 109, 109)))",same:"color: var(--dwui-color-text-diff-same, light-dark(#838383, #808080))"},f=(t,e,r,o)=>{let n="";const i=r?.class==null?"":$(r.class);i&&(n+=` class="${a(i)}"`);const l=[o,r?.style==null?"":W(r.style)].filter(Boolean).join("; ");return l&&(n+=` style="${a(l)}"`),`<${t}${n}>${a(e)}</${t}>`};function g(t,e){if(!t)return"";const r=o=>o.replace(/\r\n|\r|\n/g,"<br>").replace(/\t/g," ").replace(/ /g," ");return e?.html?t.split(m).map((o,n)=>n%2===1?o:r(o)).join(""):r(a(t))}function u(t,e){const{html:r,...o}=e??{},n=j.formatJsonString(t,o);return n==null?"":g(String(n),{html:r})}function h(t,e,r){if(!t)return"";const o=s=>r?.html?s:a(s);if(!e)return o(t);const n=e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d"),i=new RegExp(`(${n})`,r?.caseInsensitive?"i":""),l=s=>s.split(i).map((c,b)=>b%2===0?o(c):f("mark",c,r)).join("");return r?.html?t.split(m).map((s,c)=>c%2===1?s:l(s)).join(""):l(t)}function p(t,e,r){const o=S.diffChars(t??"",e??"",{ignoreCase:r?.ignoreCase});let n="";for(const i of o)i.added?n+=f("span",i.value,r?.added,d.added):i.removed?n+=f("span",i.value,r?.removed,d.removed):n+=f("span",i.value,r?.same,d.same);return n}const F=Object.freeze(Object.defineProperty({__proto__:null,diffForWeb:p,formatJsonStringForWeb:u,formatStringForWeb:g,highlightWord:h},Symbol.toStringTag,{value:"Module"}));exports.diffForWeb=p;exports.formatJsonStringForWeb=u;exports.formatStringForWeb=g;exports.highlightWord=h;exports.htmlUtil=F;
|
|
2
|
+
//# sourceMappingURL=html-util-ELyFVsxl.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-util-ELyFVsxl.cjs","sources":["../src/html-util.ts"],"sourcesContent":["import { diffChars } from 'diff';\nimport { formatJsonString } from './json-util';\nimport type { FormatJsonStringOptions } from './json-util';\n\n/**\n * class属性に指定する値\n * 配列は要素を空白区切りで連結し、Recordは値がtrueのキーだけを連結する\n */\nexport type HtmlClassValue = string | string[] | Record<string, boolean>;\n\n/**\n * style属性に指定する値\n * Recordのキーはキャメルケースをケバブケースに変換する。数値には単位を付けない\n */\nexport type HtmlStyleValue = string | Record<string, string | number>;\n\n/**\n * 生成するタグに付与する属性\n */\nexport interface HtmlTagOptions {\n class?: HtmlClassValue;\n style?: HtmlStyleValue;\n}\n\nconst HTML_TOKEN = /(<!--[\\s\\S]*?-->|<[^>]*>|&(?:#\\d+|#x[\\da-f]+|\\w+);)/i;\n\nconst HTML_ESCAPE_CHARS: Record<string, string> = {\n '\"': '"',\n '&': '&',\n '\\'': ''',\n '<': '<',\n '>': '>'\n};\n\nconst escapeHtml = (str: string): string => str.replace(/[\"&'<>]/g, (c) => HTML_ESCAPE_CHARS[c]);\n\nconst toClassString = (value: HtmlClassValue): string => {\n if (typeof value === 'string') {\n return value;\n }\n if (Array.isArray(value)) {\n return value.filter(Boolean).join(' ');\n }\n return Object.keys(value).filter(key => value[key]).join(' ');\n};\n\nconst toStyleString = (value: HtmlStyleValue): string => {\n if (typeof value === 'string') {\n return value;\n }\n return Object.entries(value)\n .map(([key, v]) => {\n // カスタムプロパティ(--xxx)は大文字小文字を区別するため変換しない\n const property = key.startsWith('--') ? key : key.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`);\n return `${property}: ${v}`;\n })\n .join('; ');\n};\n\n/** diffForWebの既定の文字色 */\nconst DIFF_STYLES = {\n added: 'color: var(--dwui-color-text-diff-added, light-dark(#006400, rgb(121, 227, 121)))',\n removed: 'color: var(--dwui-color-text-diff-removed, light-dark(#ff0000, rgb(222, 109, 109)))',\n same: 'color: var(--dwui-color-text-diff-same, light-dark(#838383, #808080))'\n};\n\n/**\n * 値をエスケープしたタグを返す\n *\n * @param {string} tagName\n * @param {string} value\n * @param {HtmlTagOptions} [options]\n * @param {string} [defaultStyle] optionsのstyleより前に出力するstyle\n * @returns {string}\n */\nconst toElement = (tagName: string, value: string, options?: HtmlTagOptions, defaultStyle?: string): string => {\n let attributes = '';\n const className = options?.class == null ? '' : toClassString(options.class);\n if (className) {\n attributes += ` class=\"${escapeHtml(className)}\"`;\n }\n const style = [defaultStyle, options?.style == null ? '' : toStyleString(options.style)].filter(Boolean).join('; ');\n if (style) {\n attributes += ` style=\"${escapeHtml(style)}\"`;\n }\n return `<${tagName}${attributes}>${escapeHtml(value)}</${tagName}>`;\n};\n\n/**\n * 文字列をWEB表示用にフォーマットする\n * オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能\n *\n * @param {string | null | undefined} str\n * @param {*} [options]\n * ├ html boolean trueを指定した場合、入力された文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function formatStringForWeb(str: string | null | undefined, options?: {\n html?: boolean;\n}): string {\n if (!str) {\n return '';\n }\n\n const formatText = (text: string): string => text\n .replace(/\\r\\n|\\r|\\n/g, '<br>')\n .replace(/\\t/g, ' ')\n .replace(/ /g, ' ');\n\n if (options?.html) {\n // 奇数番目がタグ・コメント・文字参照。偶数番目のテキスト部分だけをフォーマットする\n return str\n .split(HTML_TOKEN)\n .map((segment, i) => i % 2 === 1 ? segment : formatText(segment))\n .join('');\n }\n\n return formatText(escapeHtml(str));\n}\n\n/**\n * 値を整形したJSON文字列にしてWEB表示用にフォーマットする\n * formatJsonStringで整形した文字列をformatStringForWebで変換する\n *\n * @param {any} value\n * @param {*} [options] formatJsonStringのオプションに以下を加えたもの\n * ├ html boolean trueを指定した場合、文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function formatJsonStringForWeb(value: any, options?: FormatJsonStringOptions & {\n html?: boolean;\n}): string {\n const { html, ...formatOptions } = options ?? {};\n const json = formatJsonString(value, formatOptions);\n return json == null ? '' : formatStringForWeb(String(json), { html });\n}\n\n/**\n * 文字列の中で一致したワードをmarkタグで囲んだHTML文字列を返す\n * オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能\n *\n * 例)\n * HtmlUtil.highlightWord('This is a test message', 'test', { class: 'highlight' });\n * → 'This is a <mark class=\"highlight\">test</mark> message'\n *\n * @param {string | null | undefined} value\n * @param {string | null | undefined} word\n * @param {*} [options] markタグに付与するclass, styleのほか、以下を指定できる\n * ├ class string | string[] | Record<string, boolean>\n * ├ style string | Record<string, string | number>\n * ├ caseInsensitive boolean trueを指定した場合、大文字小文字を区別しない\n * ├ html boolean trueを指定した場合、入力された文字列をHTMLとして扱う\n * @returns {string}\n */\nexport function highlightWord(\n value: string | null | undefined,\n word: string | null | undefined,\n options?: HtmlTagOptions & {\n caseInsensitive?: boolean;\n html?: boolean;\n }\n): string {\n if (!value) {\n return '';\n }\n\n const toHtml = (text: string): string => options?.html ? text : escapeHtml(text);\n if (!word) {\n return toHtml(value);\n }\n\n const pattern = word.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&').replace(/-/g, '\\\\x2d');\n const regex = new RegExp(`(${pattern})`, options?.caseInsensitive ? 'i' : '');\n // キャプチャグループで分割すると、奇数番目の要素が一致した部分になる\n const highlight = (text: string): string => text\n .split(regex)\n .map((part, i) => i % 2 === 0 ? toHtml(part) : toElement('mark', part, options))\n .join('');\n\n if (!options?.html) {\n return highlight(value);\n }\n\n // 奇数番目がタグ・コメント・文字参照。偶数番目のテキスト部分だけをハイライトする\n return value\n .split(HTML_TOKEN)\n .map((segment, i) => i % 2 === 1 ? segment : highlight(segment))\n .join('');\n}\n\n/**\n * 文字列を1文字ずつ比較し、差分をspanタグで囲んだHTML文字列を返す\n * 追加・削除・一致の部分ごとに既定の文字色を持つ。文字色はCSS変数(--dwui-color-text-diff-added / --dwui-color-text-diff-removed / --dwui-color-text-diff-same)で変更できる\n * 追加・削除・一致の部分ごとに、spanタグに付与するclass, styleを指定できる。styleは既定の文字色より後に出力する\n * 入力文字列はプレーンなテキストであるとみなす\n * 出力される文字列は、diffで埋め込まれるHTMLタグ以外はHTMLエスケープされ、HTMLセーフな文字列となる\n *\n * @param {string | null | undefined} text1 比較元の文字列\n * @param {string | null | undefined} text2 比較される文字列(通常、入力値はこちらに渡す)\n * @param {*} [options]\n * ├ ignoreCase boolean trueを指定した場合、大文字小文字を区別しない\n * ├ added HtmlTagOptions text2で追加された部分のspanタグに付与する属性\n * ├ removed HtmlTagOptions text2で削除された部分のspanタグに付与する属性\n * ├ same HtmlTagOptions 一致した部分のspanタグに付与する属性\n * @returns {string}\n */\nexport function diffForWeb(text1: string | null | undefined, text2: string | null | undefined, options?: {\n ignoreCase?: boolean;\n added?: HtmlTagOptions;\n removed?: HtmlTagOptions;\n same?: HtmlTagOptions;\n}): string {\n const changes = diffChars(text1 ?? '', text2 ?? '', { ignoreCase: options?.ignoreCase });\n let html = '';\n for (const change of changes) {\n if (change.added) {\n html += toElement('span', change.value, options?.added, DIFF_STYLES.added);\n } else if (change.removed) {\n html += toElement('span', change.value, options?.removed, DIFF_STYLES.removed);\n } else {\n html += toElement('span', change.value, options?.same, DIFF_STYLES.same);\n }\n }\n return html;\n}\n"],"names":["HTML_TOKEN","HTML_ESCAPE_CHARS","escapeHtml","str","c","toClassString","value","key","toStyleString","v","DIFF_STYLES","toElement","tagName","options","defaultStyle","attributes","className","style","formatStringForWeb","formatText","text","segment","i","formatJsonStringForWeb","html","formatOptions","json","formatJsonString","highlightWord","word","toHtml","pattern","regex","highlight","part","diffForWeb","text1","text2","changes","diffChars","change"],"mappings":"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"}
|
package/lib/html-util.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("diff");require("./json-util-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("diff");require("./json-util-CKnsxu1e.cjs");const r=require("./html-util-ELyFVsxl.cjs");exports.diffForWeb=r.diffForWeb;exports.formatJsonStringForWeb=r.formatJsonStringForWeb;exports.formatStringForWeb=r.formatStringForWeb;exports.highlightWord=r.highlightWord;
|
|
2
2
|
//# sourceMappingURL=html-util.cjs.map
|
package/lib/html-util.d.cts
CHANGED
|
@@ -41,16 +41,16 @@ export declare function formatJsonStringForWeb(value: any, options?: FormatJsonS
|
|
|
41
41
|
html?: boolean;
|
|
42
42
|
}): string;
|
|
43
43
|
/**
|
|
44
|
-
* 文字列の中で一致したワードを
|
|
44
|
+
* 文字列の中で一致したワードをmarkタグで囲んだHTML文字列を返す
|
|
45
45
|
* オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能
|
|
46
46
|
*
|
|
47
47
|
* 例)
|
|
48
48
|
* HtmlUtil.highlightWord('This is a test message', 'test', { class: 'highlight' });
|
|
49
|
-
* → 'This is a <
|
|
49
|
+
* → 'This is a <mark class="highlight">test</mark> message'
|
|
50
50
|
*
|
|
51
51
|
* @param {string | null | undefined} value
|
|
52
52
|
* @param {string | null | undefined} word
|
|
53
|
-
* @param {*} [options]
|
|
53
|
+
* @param {*} [options] markタグに付与するclass, styleのほか、以下を指定できる
|
|
54
54
|
* ├ class string | string[] | Record<string, boolean>
|
|
55
55
|
* ├ style string | Record<string, string | number>
|
|
56
56
|
* ├ caseInsensitive boolean trueを指定した場合、大文字小文字を区別しない
|
|
@@ -63,7 +63,8 @@ export declare function highlightWord(value: string | null | undefined, word: st
|
|
|
63
63
|
}): string;
|
|
64
64
|
/**
|
|
65
65
|
* 文字列を1文字ずつ比較し、差分をspanタグで囲んだHTML文字列を返す
|
|
66
|
-
*
|
|
66
|
+
* 追加・削除・一致の部分ごとに既定の文字色を持つ。文字色はCSS変数(--dwui-color-text-diff-added / --dwui-color-text-diff-removed / --dwui-color-text-diff-same)で変更できる
|
|
67
|
+
* 追加・削除・一致の部分ごとに、spanタグに付与するclass, styleを指定できる。styleは既定の文字色より後に出力する
|
|
67
68
|
* 入力文字列はプレーンなテキストであるとみなす
|
|
68
69
|
* 出力される文字列は、diffで埋め込まれるHTMLタグ以外はHTMLエスケープされ、HTMLセーフな文字列となる
|
|
69
70
|
*
|
package/lib/html-util.d.ts
CHANGED
|
@@ -41,16 +41,16 @@ export declare function formatJsonStringForWeb(value: any, options?: FormatJsonS
|
|
|
41
41
|
html?: boolean;
|
|
42
42
|
}): string;
|
|
43
43
|
/**
|
|
44
|
-
* 文字列の中で一致したワードを
|
|
44
|
+
* 文字列の中で一致したワードをmarkタグで囲んだHTML文字列を返す
|
|
45
45
|
* オプションのhtmlにより、入力文字列がHTMLなのかプレーンテキストなのかを指定可能
|
|
46
46
|
*
|
|
47
47
|
* 例)
|
|
48
48
|
* HtmlUtil.highlightWord('This is a test message', 'test', { class: 'highlight' });
|
|
49
|
-
* → 'This is a <
|
|
49
|
+
* → 'This is a <mark class="highlight">test</mark> message'
|
|
50
50
|
*
|
|
51
51
|
* @param {string | null | undefined} value
|
|
52
52
|
* @param {string | null | undefined} word
|
|
53
|
-
* @param {*} [options]
|
|
53
|
+
* @param {*} [options] markタグに付与するclass, styleのほか、以下を指定できる
|
|
54
54
|
* ├ class string | string[] | Record<string, boolean>
|
|
55
55
|
* ├ style string | Record<string, string | number>
|
|
56
56
|
* ├ caseInsensitive boolean trueを指定した場合、大文字小文字を区別しない
|
|
@@ -63,7 +63,8 @@ export declare function highlightWord(value: string | null | undefined, word: st
|
|
|
63
63
|
}): string;
|
|
64
64
|
/**
|
|
65
65
|
* 文字列を1文字ずつ比較し、差分をspanタグで囲んだHTML文字列を返す
|
|
66
|
-
*
|
|
66
|
+
* 追加・削除・一致の部分ごとに既定の文字色を持つ。文字色はCSS変数(--dwui-color-text-diff-added / --dwui-color-text-diff-removed / --dwui-color-text-diff-same)で変更できる
|
|
67
|
+
* 追加・削除・一致の部分ごとに、spanタグに付与するclass, styleを指定できる。styleは既定の文字色より後に出力する
|
|
67
68
|
* 入力文字列はプレーンなテキストであるとみなす
|
|
68
69
|
* 出力される文字列は、diffで埋め込まれるHTMLタグ以外はHTMLエスケープされ、HTMLセーフな文字列となる
|
|
69
70
|
*
|
package/lib/html-util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "diff";
|
|
2
|
-
import "./json-util-
|
|
3
|
-
import { d as i, f, a as m, b as s } from "./html-util-
|
|
2
|
+
import "./json-util-C_Pm1BpJ.js";
|
|
3
|
+
import { d as i, f, a as m, b as s } from "./html-util-BctKzfnH.js";
|
|
4
4
|
export {
|
|
5
5
|
i as diffForWeb,
|
|
6
6
|
f as formatJsonStringForWeb,
|
package/lib/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./crypto-util-BcHurtbE.cjs"),i=require("./date-util-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./crypto-util-BcHurtbE.cjs"),i=require("./date-time.cjs"),e=require("./date-util-ByW86YIS.cjs"),l=require("./decimal.cjs"),r=require("./file-util-Dqiw5tBQ.cjs"),U=require("./html-util-ELyFVsxl.cjs"),o=require("./json-util-CKnsxu1e.cjs"),c=require("./number-util-BrDEKYJo.cjs"),n=require("./object-util-BHg61ifG.cjs"),s=require("./string-util-w2I5EYuY.cjs");exports.CryptoUtil=t.cryptoUtil;exports.DateTime=i.DateTime;exports.DateUtil=e.dateUtil;exports.Decimal=l.Decimal;exports.FileUtil=r.fileUtil;exports.HtmlUtil=U.htmlUtil;exports.JsonUtil=o.jsonUtil;exports.NumberUtil=c.numberUtil;exports.ObjectUtil=n.objectUtil;exports.StringUtil=s.stringUtil;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|