@bhsd/common 1.3.1 → 2.0.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/index.d.ts CHANGED
@@ -61,4 +61,9 @@ export declare const lintJSONNative: (str: string, force?: boolean) => JsonError
61
61
  * @param str JSON字符串
62
62
  */
63
63
  export declare const lintJSON: (str: string) => JsonError[];
64
+ /**
65
+ * 诊断JSONC字符串中的语法错误
66
+ * @param str JSONC字符串
67
+ */
68
+ export declare const lintJSONC: (str: string) => JsonError[];
64
69
  export {};
package/dist/index.js CHANGED
@@ -1,21 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.lintJSON = exports.lintJSONNative = exports.splitLines = exports.getObjRegex = exports.sanitizeInlineStyle = exports.splitColors = exports.numToHex = exports.rawurldecode = exports.wmf = void 0;
4
- exports.getRegex = getRegex;
5
- const json_parse_js_1 = require("./json_parse.js");
6
- exports.wmf = 'wiktionary|wiki(?:pedia|books|news|quote|source|versity|voyage)';
1
+ import { json_parse, jsonc_parse } from './json_parse.js';
2
+ export const wmf = 'wiktionary|wiki(?:pedia|books|news|quote|source|versity|voyage)';
7
3
  /**
8
4
  * PHP的`rawurldecode`函数的JavaScript实现
9
5
  * @param str 要解码的字符串
10
6
  */
11
- const rawurldecode = (str) => decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, '%25'));
12
- exports.rawurldecode = rawurldecode;
7
+ export const rawurldecode = (str) => decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, '%25'));
13
8
  /**
14
9
  * 将0~1之间的数字转换为十六进制
15
10
  * @param d 0~1之间的数字
16
11
  */
17
- const numToHex = (d) => Math.round(d * 255).toString(16).padStart(2, '0');
18
- exports.numToHex = numToHex;
12
+ export const numToHex = (d) => Math.round(d * 255).toString(16).padStart(2, '0');
19
13
  const regex = /* #__PURE__ */ (() => {
20
14
  const hexColor = String.raw `#(?:[\da-f]{3,4}|(?:[\da-f]{2}){3,4})(?![\p{L}\p{N}_])`, rgbValue = String.raw `(?:\d*\.)?\d+%?`, hue = String.raw `(?:\d*\.)?\d+(?:deg|grad|rad|turn)?`, rgbColor = String.raw `rgba?\(\s*(?:${String.raw `${new Array(3).fill(rgbValue).join(String.raw `\s+`)}(?:\s*\/\s*${rgbValue})?`}|${String.raw `${new Array(3).fill(rgbValue).join(String.raw `\s*,\s*`)}(?:\s*,\s*${rgbValue})?`})\s*\)`, hslColor = String.raw `hsla?\(\s*(?:${String.raw `${hue}\s+${rgbValue}\s+${rgbValue}(?:\s*\/\s*${rgbValue})?`}|${String.raw `${hue}${String.raw `\s*,\s*(?:\d*\.)?\d+%`.repeat(2)}(?:\s*,\s*${rgbValue})?`})\s*\)`;
21
15
  return {
@@ -28,7 +22,7 @@ const regex = /* #__PURE__ */ (() => {
28
22
  * @param str 字符串
29
23
  * @param hsl 是否包含 HSL
30
24
  */
31
- const splitColors = (str, hsl = true) => {
25
+ export const splitColors = (str, hsl = true) => {
32
26
  const pieces = [], re = regex[hsl ? 'full' : 'rgb'];
33
27
  re.lastIndex = 0;
34
28
  let mt = re.exec(str), lastIndex = 0;
@@ -46,15 +40,13 @@ const splitColors = (str, hsl = true) => {
46
40
  }
47
41
  return pieces;
48
42
  };
49
- exports.splitColors = splitColors;
50
43
  /**
51
44
  * 清理内联样式中的`{`和`}`
52
45
  * @param style 内联样式
53
46
  */
54
- const sanitizeInlineStyle = (style) => style.replace(/[{}]/gu, p => p === '{' ? '{' : '}')
47
+ export const sanitizeInlineStyle = (style) => style.replace(/[{}]/gu, p => p === '{' ? '{' : '}')
55
48
  .replace(/^[\s;]+/u, p => p.replace(/;/gu, ' '));
56
- exports.sanitizeInlineStyle = sanitizeInlineStyle;
57
- function getRegex(f) {
49
+ export function getRegex(f) {
58
50
  const map = new Map(), weakMap = new WeakMap();
59
51
  return s => {
60
52
  const regexp = typeof s === 'string' ? map : weakMap;
@@ -73,12 +65,12 @@ function getRegex(f) {
73
65
  * @param f 生成正则表达式的函数
74
66
  * @deprecated 需要改为使用`getRegex`
75
67
  */
76
- exports.getObjRegex = getRegex;
68
+ export const getObjRegex = getRegex;
77
69
  /**
78
70
  * 按行分割字符串并记录每行的起止位置
79
71
  * @param str 字符串
80
72
  */
81
- const splitLines = (str) => {
73
+ export const splitLines = (str) => {
82
74
  const lines = [];
83
75
  let start = 0;
84
76
  for (const line of str.split('\n')) {
@@ -88,12 +80,11 @@ const splitLines = (str) => {
88
80
  }
89
81
  return lines;
90
82
  };
91
- exports.splitLines = splitLines;
92
83
  const mt2num = (mt) => mt && Number(mt[1]);
93
84
  const formatJsonError = (str, errors) => {
94
85
  let lines;
95
86
  const offsetToPosition = (offset) => {
96
- lines ??= (0, exports.splitLines)(str);
87
+ lines ??= splitLines(str);
97
88
  const line = lines.findIndex(([, , end]) => offset <= end) + 1;
98
89
  return {
99
90
  line,
@@ -104,7 +95,7 @@ const formatJsonError = (str, errors) => {
104
95
  const { line, column, from, to } = error;
105
96
  if (from === null || from === undefined) {
106
97
  if (line) {
107
- lines ??= (0, exports.splitLines)(str);
98
+ lines ??= splitLines(str);
108
99
  error.column ??= 1;
109
100
  error.from = lines[line - 1][1] + (error.column - 1);
110
101
  }
@@ -129,7 +120,7 @@ const formatJsonError = (str, errors) => {
129
120
  * @param str JSON字符串
130
121
  * @param force 是否强制诊断
131
122
  */
132
- const lintJSONNative = (str, force) => {
123
+ export const lintJSONNative = (str, force) => {
133
124
  if (force || str.trim()) {
134
125
  try {
135
126
  JSON.parse(str);
@@ -141,18 +132,9 @@ const lintJSONNative = (str, force) => {
141
132
  }
142
133
  return [];
143
134
  };
144
- exports.lintJSONNative = lintJSONNative;
145
- /**
146
- * 诊断JSON字符串中的语法错误
147
- * @param str JSON字符串
148
- */
149
- const lintJSON = (str) => {
150
- if (!str.trim()) {
151
- return [];
152
- }
153
- let errors;
135
+ const lintJSONBase = (str, parse) => {
154
136
  try {
155
- (0, json_parse_js_1.json_parse)(str);
137
+ parse(str);
156
138
  }
157
139
  catch (e) {
158
140
  if (!(e instanceof Error)) {
@@ -160,13 +142,24 @@ const lintJSON = (str) => {
160
142
  if (error.message) {
161
143
  warnings.push(error);
162
144
  }
163
- errors = formatJsonError(str, warnings);
164
- if (error.message) {
165
- return errors;
166
- }
145
+ return formatJsonError(str, warnings);
167
146
  }
168
147
  }
169
- const nativeErrors = (0, exports.lintJSONNative)(str);
170
- return errors ? [...nativeErrors, ...errors] : nativeErrors;
148
+ return [];
149
+ };
150
+ /**
151
+ * 诊断JSON字符串中的语法错误
152
+ * @param str JSON字符串
153
+ */
154
+ export const lintJSON = (str) => {
155
+ if (!str.trim()) {
156
+ return [];
157
+ }
158
+ const errors = lintJSONBase(str, json_parse);
159
+ return errors[errors.length - 1]?.severity === 'error' ? errors : [...errors, ...lintJSONNative(str)];
171
160
  };
172
- exports.lintJSON = lintJSON;
161
+ /**
162
+ * 诊断JSONC字符串中的语法错误
163
+ * @param str JSONC字符串
164
+ */
165
+ export const lintJSONC = (str) => str.trim() ? lintJSONBase(str, jsonc_parse) : [];
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /*
3
2
  json_parse.js
4
3
  2016-05-02
@@ -27,8 +26,6 @@
27
26
 
28
27
  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO NOT CONTROL.
29
28
  */
30
- Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.json_parse = void 0;
32
29
  const escapee = {
33
30
  '"': '"',
34
31
  "\\": "\\",
@@ -46,7 +43,7 @@ const stringify = (c) => {
46
43
  }
47
44
  return c === '"' ? `'"'` : JSON.stringify(c);
48
45
  };
49
- exports.json_parse = (() => {
46
+ const factory = (jsonc) => {
50
47
  // This is a function that can parse a JSON text.
51
48
  // It is a simple, recursive descent parser.
52
49
  // It does not use eval or regular expressions,
@@ -203,9 +200,40 @@ exports.json_parse = (() => {
203
200
  return error("Unterminated string");
204
201
  };
205
202
  const white = () => {
206
- // Skip whitespace.
207
- while (ch && spaces.has(ch)) {
208
- next();
203
+ // Skip whitespace and comments (JSONC).
204
+ while (ch) {
205
+ // Skip whitespace.
206
+ while (ch && spaces.has(ch)) {
207
+ next();
208
+ }
209
+ if (jsonc && ch === "/") {
210
+ const peek = text.charAt(at);
211
+ if (peek === "/") {
212
+ // Skip single-line comments.
213
+ next(); // skip /
214
+ next(); // skip /
215
+ // @ts-expect-error `ch` modified
216
+ while (ch && ch !== "\n" && ch !== "\r") {
217
+ next();
218
+ }
219
+ continue;
220
+ }
221
+ else if (peek === "*") {
222
+ // Skip multi-line comments.
223
+ next(); // skip /
224
+ next(); // skip *
225
+ // @ts-expect-error `ch` modified
226
+ while (ch && !(ch === "*" && text.charAt(at) === "/")) {
227
+ next();
228
+ }
229
+ if (ch === "*") {
230
+ next(); // skip *
231
+ next(); // skip /
232
+ }
233
+ continue;
234
+ }
235
+ }
236
+ break;
209
237
  }
210
238
  };
211
239
  const word = () => {
@@ -242,9 +270,19 @@ exports.json_parse = (() => {
242
270
  next();
243
271
  return; // empty array
244
272
  }
273
+ else if (jsonc && ch === ",") {
274
+ next();
275
+ white();
276
+ next("]");
277
+ return;
278
+ }
245
279
  let from;
246
280
  while (ch) {
247
281
  if (ch === "]") {
282
+ if (jsonc) {
283
+ next();
284
+ return;
285
+ }
248
286
  error("Trailing comma in array", from, from + 1);
249
287
  }
250
288
  value();
@@ -273,9 +311,19 @@ exports.json_parse = (() => {
273
311
  next();
274
312
  return; // empty object
275
313
  }
314
+ else if (jsonc && ch === ",") {
315
+ next();
316
+ white();
317
+ next("}");
318
+ return;
319
+ }
276
320
  let from;
277
321
  while (ch) {
278
322
  if (ch === "}") {
323
+ if (jsonc) {
324
+ next();
325
+ return;
326
+ }
279
327
  error("Trailing comma in object", from, from + 1);
280
328
  }
281
329
  from = at;
@@ -311,6 +359,8 @@ exports.json_parse = (() => {
311
359
  // or a word.
312
360
  white();
313
361
  switch (ch) {
362
+ case "":
363
+ return undefined;
314
364
  case "{":
315
365
  return object();
316
366
  case "[":
@@ -341,4 +391,5 @@ exports.json_parse = (() => {
341
391
  throw { warnings };
342
392
  }
343
393
  };
344
- })();
394
+ };
395
+ export const json_parse = /* @__PURE__ */ factory(), jsonc_parse = /* @__PURE__ */ factory(true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bhsd/common",
3
- "version": "1.3.1",
3
+ "version": "2.0.0",
4
4
  "homepage": "https://github.com/bhsd-harry/common#readme",
5
5
  "bugs": {
6
6
  "url": "https://github.com/bhsd-harry/common/issues"
@@ -9,44 +9,38 @@
9
9
  "author": "Bhsd",
10
10
  "files": [
11
11
  "/dist/*.js",
12
- "/dist/index.mjs",
13
12
  "/dist/index.d.ts"
14
13
  ],
15
- "exports": {
16
- ".": {
17
- "types": "./dist/index.d.ts",
18
- "import": "./dist/index.mjs",
19
- "require": "./dist/index.js"
20
- }
21
- },
14
+ "main": "./dist/index.js",
22
15
  "types": "./dist/index.d.ts",
16
+ "type": "module",
23
17
  "sideEffects": false,
24
18
  "scripts": {
25
19
  "prepublishOnly": "npm run build",
26
- "build": "tsc && esbuild src/index.ts --charset=utf8 --target=es2024 --bundle --format=esm --outfile=dist/index.mjs && cp dist/index.d.ts dist/index.d.mts",
20
+ "build": "tsc",
27
21
  "lint:ts": "tsc --noEmit && eslint --cache .",
28
22
  "lint": "npm run lint:ts",
29
23
  "test": "mocha"
30
24
  },
31
25
  "devDependencies": {
32
- "@bhsd/code-standard": "^1.3.2",
33
- "@stylistic/eslint-plugin": "^5.5.0",
26
+ "@bhsd/code-standard": "^2.1.1",
27
+ "@stylistic/eslint-plugin": "^5.10.0",
34
28
  "@types/mocha": "^10.0.10",
35
- "@typescript-eslint/eslint-plugin": "^8.46.4",
36
- "@typescript-eslint/parser": "^8.46.4",
37
- "esbuild": "^0.25.12",
38
- "eslint": "^9.39.1",
39
- "eslint-plugin-es-x": "^9.1.2",
29
+ "@typescript-eslint/eslint-plugin": "^8.57.0",
30
+ "@typescript-eslint/parser": "^8.57.0",
31
+ "esbuild": "^0.27.4",
32
+ "eslint": "^9.39.4",
33
+ "eslint-plugin-es-x": "^9.5.0",
40
34
  "eslint-plugin-eslint-comments": "^3.2.0",
41
- "eslint-plugin-jsdoc": "^61.2.1",
42
- "eslint-plugin-jsonc": "^2.21.0",
35
+ "eslint-plugin-jsdoc": "^62.7.1",
36
+ "eslint-plugin-jsonc": "^3.1.1",
43
37
  "eslint-plugin-promise": "^7.2.1",
44
- "eslint-plugin-regexp": "^2.10.0",
45
- "eslint-plugin-unicorn": "^62.0.0",
38
+ "eslint-plugin-regexp": "^3.1.0",
39
+ "eslint-plugin-unicorn": "^63.0.0",
46
40
  "mocha": "^11.7.5",
47
41
  "typescript": "^5.9.3"
48
42
  },
49
43
  "engines": {
50
- "node": ">=18.17.0"
44
+ "node": "^20.19.0 || ^22.13.0 || >=24.11.0"
51
45
  }
52
46
  }
package/dist/index.mjs DELETED
@@ -1,411 +0,0 @@
1
- // src/json_parse.ts
2
- var escapee = {
3
- '"': '"',
4
- "\\": "\\",
5
- "/": "/",
6
- b: "\b",
7
- f: "\f",
8
- n: "\n",
9
- r: "\r",
10
- t: " "
11
- };
12
- var spaces = /* @__PURE__ */ new Set([" ", " ", "\n", "\r"]);
13
- var stringify = (c) => {
14
- if (c === "") {
15
- return "end of input";
16
- }
17
- return c === '"' ? `'"'` : JSON.stringify(c);
18
- };
19
- var json_parse = /* @__PURE__ */ (() => {
20
- let at;
21
- let ch;
22
- let text;
23
- let warnings;
24
- const prepareError = (e, from, to) => {
25
- if (from === void 0) {
26
- e.from = at - 1;
27
- } else {
28
- e.from = from;
29
- e.to = to ?? at - 1;
30
- }
31
- };
32
- const warn = (message, from, to) => {
33
- const warning = {
34
- message,
35
- severity: "warning"
36
- };
37
- prepareError(warning, from, to);
38
- warnings.push(warning);
39
- };
40
- const error = (message, from, to) => {
41
- const e = {
42
- warnings,
43
- message,
44
- severity: "error"
45
- };
46
- prepareError(e, from, to);
47
- throw e;
48
- };
49
- const next = (c) => {
50
- if (c && c !== ch) {
51
- error(`Expected ${stringify(c)} instead of ${stringify(ch)}`);
52
- }
53
- ch = text.charAt(at);
54
- at++;
55
- return ch;
56
- };
57
- const number = () => {
58
- let string2 = "";
59
- const from = at - 1;
60
- if (ch === "-") {
61
- string2 = "-";
62
- next();
63
- }
64
- if (ch === "0") {
65
- string2 += ch;
66
- next();
67
- if (ch >= "0" && ch <= "9") {
68
- error("Bad number");
69
- }
70
- } else if (ch >= "1" && ch <= "9") {
71
- while (ch >= "0" && ch <= "9") {
72
- string2 += ch;
73
- next();
74
- }
75
- } else {
76
- error("No number after minus sign");
77
- }
78
- if (ch !== "." && ch !== "e" && ch !== "E") {
79
- const value3 = Number(string2);
80
- if (!Number.isSafeInteger(value3)) {
81
- warn("Not a safe integer", from);
82
- }
83
- return;
84
- }
85
- if (ch === ".") {
86
- string2 += ".";
87
- next();
88
- if (ch < "0" || ch > "9") {
89
- error("Unterminated fractional number");
90
- }
91
- while (ch >= "0" && ch <= "9") {
92
- string2 += ch;
93
- next();
94
- }
95
- }
96
- if (ch === "e" || ch === "E") {
97
- string2 += ch;
98
- next();
99
- if (ch === "-" || ch === "+") {
100
- string2 += ch;
101
- next();
102
- }
103
- while (ch >= "0" && ch <= "9") {
104
- string2 += ch;
105
- next();
106
- }
107
- }
108
- const value2 = Number(string2);
109
- if (!Number.isFinite(value2)) {
110
- error("Bad number");
111
- }
112
- };
113
- const string = () => {
114
- let value2 = "";
115
- if (ch === '"') {
116
- while (next()) {
117
- if (ch === '"') {
118
- next();
119
- return value2;
120
- }
121
- const from = at - 1;
122
- if (ch === "\\") {
123
- next();
124
- if (ch === "u") {
125
- let i = 0;
126
- let uffff = 0;
127
- for (; i < 4; i++) {
128
- const hex = parseInt(next(), 16);
129
- if (!isFinite(hex)) {
130
- break;
131
- }
132
- uffff = uffff * 16 + hex;
133
- }
134
- if (i < 4) {
135
- error("Bad unicode escape", from);
136
- }
137
- value2 += String.fromCharCode(uffff);
138
- } else if (typeof escapee[ch] === "string") {
139
- value2 += escapee[ch];
140
- } else {
141
- error("Bad escaped character", from, at);
142
- }
143
- } else if (ch < " ") {
144
- error("Bad control character", from, at);
145
- } else {
146
- value2 += ch;
147
- }
148
- }
149
- } else {
150
- error(`Expected '"' instead of ${JSON.stringify(ch)}`);
151
- }
152
- return error("Unterminated string");
153
- };
154
- const white = () => {
155
- while (ch && spaces.has(ch)) {
156
- next();
157
- }
158
- };
159
- const word = () => {
160
- switch (ch) {
161
- case "t":
162
- next();
163
- next("r");
164
- next("u");
165
- next("e");
166
- return;
167
- case "f":
168
- next();
169
- next("a");
170
- next("l");
171
- next("s");
172
- next("e");
173
- return;
174
- case "n":
175
- next();
176
- next("u");
177
- next("l");
178
- next("l");
179
- return;
180
- default:
181
- error(`Unexpected ${JSON.stringify(ch)}`);
182
- }
183
- };
184
- const array = () => {
185
- next();
186
- white();
187
- if (ch === "]") {
188
- next();
189
- return;
190
- }
191
- let from;
192
- while (ch) {
193
- if (ch === "]") {
194
- error("Trailing comma in array", from, from + 1);
195
- }
196
- value();
197
- white();
198
- if (ch === "]") {
199
- next();
200
- return;
201
- } else if (ch === ",") {
202
- from = at - 1;
203
- next();
204
- white();
205
- } else {
206
- error(`Expected "," or "]" instead of ${stringify(ch)}`);
207
- }
208
- }
209
- error("Unterminated array");
210
- };
211
- const object = () => {
212
- const keys = /* @__PURE__ */ new Set();
213
- next();
214
- white();
215
- if (ch === "}") {
216
- next();
217
- return;
218
- }
219
- let from;
220
- while (ch) {
221
- if (ch === "}") {
222
- error("Trailing comma in object", from, from + 1);
223
- }
224
- from = at;
225
- const key = string();
226
- const to = at - 2;
227
- white();
228
- next(":");
229
- if (keys.has(key)) {
230
- warn(`Duplicate key ${stringify(key)}`, from, to);
231
- } else {
232
- keys.add(key);
233
- }
234
- value();
235
- white();
236
- if (ch === "}") {
237
- next();
238
- return;
239
- } else if (ch === ",") {
240
- from = at - 1;
241
- next();
242
- white();
243
- } else {
244
- error(`Expected "," or "}" instead of ${stringify(ch)}`);
245
- }
246
- }
247
- error(`Expected '"'`);
248
- };
249
- const value = () => {
250
- white();
251
- switch (ch) {
252
- case "{":
253
- return object();
254
- case "[":
255
- return array();
256
- case '"':
257
- return string();
258
- case "-":
259
- return number();
260
- default:
261
- return ch >= "0" && ch <= "9" ? number() : word();
262
- }
263
- };
264
- return (source) => {
265
- text = source;
266
- warnings = [];
267
- at = 0;
268
- ch = " ";
269
- value();
270
- white();
271
- if (ch) {
272
- error("Syntax error");
273
- } else if (warnings.length > 0) {
274
- throw { warnings };
275
- }
276
- };
277
- })();
278
-
279
- // src/index.ts
280
- var wmf = "wiktionary|wiki(?:pedia|books|news|quote|source|versity|voyage)";
281
- var rawurldecode = (str) => decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, "%25"));
282
- var numToHex = (d) => Math.round(d * 255).toString(16).padStart(2, "0");
283
- var regex = /* @__PURE__ */ (() => {
284
- const hexColor = String.raw`#(?:[\da-f]{3,4}|(?:[\da-f]{2}){3,4})(?![\p{L}\p{N}_])`, rgbValue = String.raw`(?:\d*\.)?\d+%?`, hue = String.raw`(?:\d*\.)?\d+(?:deg|grad|rad|turn)?`, rgbColor = String.raw`rgba?\(\s*(?:${String.raw`${new Array(3).fill(rgbValue).join(String.raw`\s+`)}(?:\s*\/\s*${rgbValue})?`}|${String.raw`${new Array(3).fill(rgbValue).join(String.raw`\s*,\s*`)}(?:\s*,\s*${rgbValue})?`})\s*\)`, hslColor = String.raw`hsla?\(\s*(?:${String.raw`${hue}\s+${rgbValue}\s+${rgbValue}(?:\s*\/\s*${rgbValue})?`}|${String.raw`${hue}${String.raw`\s*,\s*(?:\d*\.)?\d+%`.repeat(2)}(?:\s*,\s*${rgbValue})?`})\s*\)`;
285
- return {
286
- full: new RegExp(String.raw`(^|[^\p{L}\p{N}_])(${hexColor}|${rgbColor}|${hslColor})`, "giu"),
287
- rgb: new RegExp(String.raw`(^|[^\p{L}\p{N}_])(${hexColor}|${rgbColor})`, "giu")
288
- };
289
- })();
290
- var splitColors = (str, hsl = true) => {
291
- const pieces = [], re = regex[hsl ? "full" : "rgb"];
292
- re.lastIndex = 0;
293
- let mt = re.exec(str), lastIndex = 0;
294
- while (mt) {
295
- const index = mt.index + mt[1].length;
296
- if (index > lastIndex) {
297
- pieces.push([str.slice(lastIndex, index), lastIndex, index, false]);
298
- }
299
- ({ lastIndex } = re);
300
- pieces.push([mt[2], index, lastIndex, str[index - 1] !== "&" || !/^#\d+$/u.test(mt[2])]);
301
- mt = re.exec(str);
302
- }
303
- if (str.length > lastIndex) {
304
- pieces.push([str.slice(lastIndex), lastIndex, str.length, false]);
305
- }
306
- return pieces;
307
- };
308
- var sanitizeInlineStyle = (style) => style.replace(/[{}]/gu, (p) => p === "{" ? "{" : "}").replace(/^[\s;]+/u, (p) => p.replace(/;/gu, " "));
309
- function getRegex(f) {
310
- const map = /* @__PURE__ */ new Map(), weakMap = /* @__PURE__ */ new WeakMap();
311
- return (s) => {
312
- const regexp = typeof s === "string" ? map : weakMap;
313
- if (regexp.has(s)) {
314
- const re2 = regexp.get(s);
315
- re2.lastIndex = 0;
316
- return re2;
317
- }
318
- const re = f(s);
319
- regexp.set(s, re);
320
- return re;
321
- };
322
- }
323
- var getObjRegex = getRegex;
324
- var splitLines = (str) => {
325
- const lines = [];
326
- let start = 0;
327
- for (const line of str.split("\n")) {
328
- const end = start + line.length;
329
- lines.push([line, start, end]);
330
- start = end + 1;
331
- }
332
- return lines;
333
- };
334
- var mt2num = (mt) => mt && Number(mt[1]);
335
- var formatJsonError = (str, errors) => {
336
- let lines;
337
- const offsetToPosition = (offset) => {
338
- lines ??= splitLines(str);
339
- const line = lines.findIndex(([, , end]) => offset <= end) + 1;
340
- return {
341
- line,
342
- column: offset - lines[line - 1][1] + 1
343
- };
344
- };
345
- for (const error of errors) {
346
- const { line, column, from, to } = error;
347
- if (from === null || from === void 0) {
348
- if (line) {
349
- lines ??= splitLines(str);
350
- error.column ??= 1;
351
- error.from = lines[line - 1][1] + (error.column - 1);
352
- } else {
353
- error.from = 0;
354
- error.line = 1;
355
- error.column = 1;
356
- }
357
- } else if (!line || !column) {
358
- Object.assign(error, offsetToPosition(from));
359
- }
360
- if (to !== void 0) {
361
- ({ line: error.endLine, column: error.endColumn } = offsetToPosition(to));
362
- }
363
- error.position = error.from;
364
- }
365
- return errors;
366
- };
367
- var lintJSONNative = (str, force) => {
368
- if (force || str.trim()) {
369
- try {
370
- JSON.parse(str);
371
- } catch (e) {
372
- const { message } = e, line = mt2num(/\bline (\d+)/u.exec(message)), column = mt2num(/\bcolumn (\d+)/u.exec(message)), from = mt2num(/\bposition (\d+)/u.exec(message));
373
- return formatJsonError(str, [{ message, line, column, from, severity: "error" }]);
374
- }
375
- }
376
- return [];
377
- };
378
- var lintJSON = (str) => {
379
- if (!str.trim()) {
380
- return [];
381
- }
382
- let errors;
383
- try {
384
- json_parse(str);
385
- } catch (e) {
386
- if (!(e instanceof Error)) {
387
- const { warnings, ...error } = e;
388
- if (error.message) {
389
- warnings.push(error);
390
- }
391
- errors = formatJsonError(str, warnings);
392
- if (error.message) {
393
- return errors;
394
- }
395
- }
396
- }
397
- const nativeErrors = lintJSONNative(str);
398
- return errors ? [...nativeErrors, ...errors] : nativeErrors;
399
- };
400
- export {
401
- getObjRegex,
402
- getRegex,
403
- lintJSON,
404
- lintJSONNative,
405
- numToHex,
406
- rawurldecode,
407
- sanitizeInlineStyle,
408
- splitColors,
409
- splitLines,
410
- wmf
411
- };