@cowave-cli/utils 2.5.3

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/node.js ADDED
@@ -0,0 +1,1849 @@
1
+ import { mkdirSync, readdirSync, statSync, readFileSync, existsSync, writeFileSync, lstatSync, copyFileSync, rmdirSync, unlinkSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import axios from 'axios';
4
+
5
+ /*
6
+ * @Description: 文件操作函数
7
+ * @Author: Zye
8
+ * @Date: 2024-03-11
9
+ */
10
+ /**
11
+ * 创建文件夹
12
+ *
13
+ * @param path 文件夹路径
14
+ */
15
+ const createDir = async (path) => {
16
+ await mkdirSync(path);
17
+ };
18
+ /**
19
+ * 读取文件夹
20
+ *
21
+ * @param path 文件夹路径
22
+ * @returns {{dirs,files}}
23
+ */
24
+ const readDir = async (path) => {
25
+ const list = await readdirSync(path);
26
+ const dirs = [];
27
+ const files = [];
28
+ for (let i = 0; i < list.length; i++) {
29
+ const dirOrFile = join(path.toString(), list[i]);
30
+ const msg = await statSync(dirOrFile);
31
+ if (msg.isFile()) {
32
+ files.push(dirOrFile);
33
+ }
34
+ else if (msg.isDirectory()) {
35
+ dirs.push(dirOrFile);
36
+ }
37
+ }
38
+ return {
39
+ dirs,
40
+ files,
41
+ };
42
+ };
43
+ /** 读取文件
44
+ *
45
+ * @param pathName 文件名
46
+ * @returns
47
+ */
48
+ const readFile = async (pathName, encoding = 'utf-8') => {
49
+ const data = await readFileSync(pathName, encoding);
50
+ return data;
51
+ };
52
+ /** 写入内容
53
+ *
54
+ * @param pathName 文件路径
55
+ * @param content 内容
56
+ */
57
+ const writeFile = async (pathName, content) => {
58
+ // 如果不存在文件夹,先创建文件夹
59
+ const dirName = dirname(pathName.toString());
60
+ if (!existsSync(dirName)) {
61
+ await mkdirSync(dirName, { recursive: true });
62
+ }
63
+ await writeFileSync(pathName, content);
64
+ };
65
+ /** 复制文件夹或者文件
66
+ *
67
+ * @param src 文件夹或者文件
68
+ * @param dest 目标文件夹
69
+ */
70
+ const copyFileOrDir = async (src, dest) => {
71
+ const stats = await lstatSync(src);
72
+ if (stats.isDirectory()) {
73
+ // 如果是目录,则创建目标目录并递归复制子项
74
+ if (!existsSync(dest)) {
75
+ await mkdirSync(dest, { recursive: true });
76
+ }
77
+ const entries = await readdirSync(src, { withFileTypes: true });
78
+ for (const entry of entries) {
79
+ const srcPath = join(src.toString(), entry.name);
80
+ const destPath = join(dest.toString(), entry.name);
81
+ await copyFileOrDir(srcPath, destPath);
82
+ }
83
+ }
84
+ else {
85
+ // 如果是文件,则直接复制
86
+ await copyFileSync(src, dest);
87
+ }
88
+ };
89
+ /** 删除文件夹或者文件
90
+ *
91
+ * @param path 路径
92
+ */
93
+ const removeFileOrDir = async (path) => {
94
+ try {
95
+ const stats = await lstatSync(path);
96
+ if (stats.isDirectory()) {
97
+ // 如果是目录,则递归删除其中所有文件和子目录
98
+ const files = await readdirSync(path);
99
+ for (const file of files) {
100
+ const currentPath = join(path.toString(), file);
101
+ await removeFileOrDir(currentPath);
102
+ }
103
+ // 删除空目录(或内部文件已全部删除后的目录)
104
+ await rmdirSync(path);
105
+ }
106
+ else {
107
+ // 如果是文件,则直接删除
108
+ await unlinkSync(path);
109
+ }
110
+ }
111
+ catch (error) {
112
+ console.log('删除文件夹出错:' + error);
113
+ }
114
+ };
115
+
116
+ const noDisk = (fromPath1, toPath1) => fromPath1 != toPath1 && error('noDisk');
117
+ const errorType = {
118
+ noDisk: '路径错误:导出文件不在同一根目录',
119
+ };
120
+ const error = (type) => {
121
+ throw new Error(errorType[type]);
122
+ };
123
+
124
+ /*
125
+ * @Description: 路径处理
126
+ * @Author: Zye
127
+ * @Date: 2024-03-11
128
+ */
129
+ /**
130
+ * 判断从toPath引入fromPath的路径相对关系
131
+ *
132
+ * @param fromPath 源路径
133
+ * @param toPath 目标路径
134
+ * @example
135
+ * relation('src/components', 'src/views/home.vue') // '../components/'
136
+ * @returns
137
+ */
138
+ const relation = (fromPath, toPath) => {
139
+ const fromPathArr = fromPath.split(/[\\/]+/g).filter((path) => path && !path.includes('.'));
140
+ const toPathArr = (toPath.split(/[\\/]+/g)).filter((path) => path && !path.includes('.'));
141
+ noDisk(fromPathArr.shift(), toPathArr.shift());
142
+ while (fromPathArr.length && toPathArr.length && toPathArr[0] == fromPathArr[0]) {
143
+ toPathArr.shift();
144
+ fromPathArr.shift();
145
+ }
146
+ let path = '';
147
+ if (toPathArr.length) {
148
+ path += '../'.repeat(toPathArr.length);
149
+ }
150
+ else {
151
+ path += './';
152
+ }
153
+ if (fromPathArr.length) {
154
+ path += fromPathArr.join('/') + '/';
155
+ }
156
+ return path;
157
+ };
158
+ /**
159
+ * 过滤文件(仅过滤文件路径,不过滤文件夹路径)
160
+ *
161
+ * @param {string[]} files 文件名列表
162
+ * @returns {} { includeFiles, excludeFiles }
163
+ */
164
+ const filter = async (files, basePath, includePath, excludePath) => {
165
+ if (!includePath?.length && !excludePath?.length)
166
+ return { include: files, exclude: [] };
167
+ const includeRegexList = (includePath || []).map((item) => new RegExp(typeof item == 'string' ? item.replace(/[\\/]+/g, '[\\\\/]+') : item));
168
+ const excludeRegexList = (excludePath || []).map((item) => new RegExp(typeof item == 'string' ? item.replace(/[\\/]+/g, '[\\\\/]+') : item));
169
+ let includeFiles = [];
170
+ let excludeFiles = [];
171
+ for (const file of files) {
172
+ let isMatchedInclude = false;
173
+ let isMatchedExclude = false;
174
+ let subPath = basePath ? file.replace(basePath, '') : file;
175
+ // 检查文件路径是否符合包含规则
176
+ if (!includePath?.length) {
177
+ isMatchedInclude = true;
178
+ }
179
+ for (const includeRegex of includeRegexList) {
180
+ if (includeRegex.test(subPath)) {
181
+ isMatchedInclude = true;
182
+ break;
183
+ }
184
+ }
185
+ // 检查文件路径是否符合排除规则
186
+ for (const excludeRegex of excludeRegexList) {
187
+ if (excludeRegex.test(subPath)) {
188
+ isMatchedExclude = true;
189
+ break;
190
+ }
191
+ }
192
+ // 根据匹配结果将文件分类
193
+ if (isMatchedInclude && !isMatchedExclude) {
194
+ includeFiles.push(file);
195
+ }
196
+ else {
197
+ excludeFiles.push(file);
198
+ }
199
+ }
200
+ return { include: includeFiles, exclude: excludeFiles };
201
+ };
202
+ /**
203
+ * 遍历寻找src目录下的所有文件
204
+ * @param dirs
205
+ * @returns
206
+ */
207
+ const findFiles = async (srcs, includePath, excludePath) => {
208
+ const allFiles = [];
209
+ const fn = async (dir, src) => {
210
+ // 读取文件夹
211
+ const { dirs, files } = await readDir(dir);
212
+ allFiles.push(...(await filter(files, src, includePath, excludePath)).include);
213
+ // 递归 过滤文件夹路径
214
+ for (let dir of (await filter(dirs, src, [], excludePath)).include) {
215
+ await fn(dir, src);
216
+ }
217
+ };
218
+ // 源文件夹
219
+ for (const src of srcs) {
220
+ await fn(src, src);
221
+ }
222
+ return allFiles;
223
+ };
224
+
225
+ /*
226
+ * @Description: 字符串处理
227
+ * @Author: Zye
228
+ * @Date: 2024-03-11
229
+ */
230
+ /**
231
+ * @deprecated 这个函数已弃用,请使用 toHump() 代替
232
+ */
233
+ const pathToHump = (path, isGreatHump = true) => {
234
+ if (isGreatHump) {
235
+ path = path.replace(/^([a-z])/g, (_, p1) => p1.toUpperCase());
236
+ }
237
+ path = path.replace(/-([a-z])/g, (_, p1) => p1.toUpperCase());
238
+ return path;
239
+ };
240
+ /**
241
+ * 将连接符字符串转换为驼峰字符串
242
+ *
243
+ * @param strings 字符串(列表)
244
+ * @param hyphenType 连接符
245
+ * @param isGreatHump 是否为大驼峰
246
+ * @returns humpString
247
+ */
248
+ const toHump = (strings, hyphenType = '-', isGreatHump = false) => {
249
+ hyphenType = hyphenType || '-';
250
+ const results = (typeof strings === 'string' ? [strings] : strings).map(string => {
251
+ if (isGreatHump) {
252
+ string = string.replace(/^([a-z])/g, (_, p1) => p1.toUpperCase());
253
+ }
254
+ string = string.replace(new RegExp(hyphenType + '([a-z])', 'g'), (_, p1) => p1.toUpperCase());
255
+ return string;
256
+ });
257
+ return typeof strings === 'string' ? results[0] : results;
258
+ };
259
+ /**
260
+ * 将驼峰字符串转换为连接符字符串
261
+ *
262
+ * @param strings 字符串(列表)
263
+ * @param hyphenType 连接符
264
+ * @returns hyphenString
265
+ */
266
+ const toHyphen = (strings, hyphenType = '-') => {
267
+ const results = (typeof strings === 'string' ? [strings] : strings).map(string => {
268
+ string = string.replace(/^([A-Z])/g, (_, p1) => p1.toLowerCase());
269
+ string = string.replace(/([A-Z])/g, (_, p1) => hyphenType + p1.toLowerCase());
270
+ });
271
+ return typeof strings === 'string' ? results[0] : results;
272
+ };
273
+ // 字符串拼接
274
+ /**
275
+ * 将object转换成query参数
276
+ *
277
+ * @param keyValue 对象
278
+ * @returns query参数
279
+ */
280
+ const query = (keyValue) => {
281
+ return keyValue
282
+ ? '?' +
283
+ Object.keys(keyValue)
284
+ .filter((key) => keyValue[key] !== undefined && keyValue[key] !== null)
285
+ .map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(keyValue[key]))
286
+ .join('&')
287
+ : '';
288
+ };
289
+ /**
290
+ *
291
+ * 将url 传参转成data格式
292
+ *
293
+ * @param url (?********)
294
+ * @returns
295
+ */
296
+ const urlToData = (url) => {
297
+ const res = [];
298
+ const index = url.indexOf('?');
299
+ if (index === -1)
300
+ return [{ key: '', value: '' }];
301
+ url
302
+ .slice(index + 1)
303
+ .split('&')
304
+ .forEach((v) => {
305
+ res.push({
306
+ key: decodeURI(v.split('=')[0]),
307
+ value: decodeURI(v.split('=')[1]),
308
+ });
309
+ });
310
+ return [
311
+ ...res,
312
+ {
313
+ key: '',
314
+ value: '',
315
+ },
316
+ ];
317
+ };
318
+ /**
319
+ *
320
+ * 判断url格式
321
+ *
322
+ * @param url
323
+ * @returns
324
+ */
325
+ const isUrl = (path) => {
326
+ const reg = /^(https?:\/\/)([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)\/?(\?[^\s#]*)?$/;
327
+ return reg.test(path);
328
+ };
329
+
330
+ /*
331
+ * @Description: 时间处理
332
+ * @Author: Zye
333
+ * @Date: 2024-03-11
334
+ *
335
+ * setTime(time) time -> 服务器时间
336
+ * getTime() 返回服务器时间戳
337
+ *
338
+ */
339
+ // 服务器时间戳 减去 客户端时间戳
340
+ let _time_diff = 0;
341
+ // 同步时间
342
+ /**
343
+ * @param callback 获取服务器时间的回调函数,需要返回服务器时间
344
+ *
345
+ * @example
346
+ *
347
+ * setTime(async () => {
348
+ * return await getServerTime()
349
+ * })
350
+ *
351
+ */
352
+ const setTime = async (callback) => {
353
+ let _time_before, _time_after, _time_server;
354
+ _time_before = new Date().getTime();
355
+ _time_server = new Date(await callback()).getTime();
356
+ _time_after = new Date().getTime();
357
+ _time_diff = _time_diff
358
+ ? (_time_diff + _time_server - _time_before / 2 - _time_after / 2) / 2
359
+ : _time_server - _time_before / 2 - _time_after / 2;
360
+ };
361
+ // 获取本地时间戳
362
+ const _local_time = () => new Date().getTime();
363
+ /**
364
+ * 获取服务器时间戳
365
+ *
366
+ * @returns 服务器时间戳
367
+ */
368
+ const getTime = () => _local_time() + _time_diff;
369
+ /** 时间格式化 (参考dayjs)
370
+ *
371
+ * @param date 时间
372
+ * @param formatStr 格式如下
373
+ * @returns 格式化后的时间
374
+ *
375
+ * @formatStr
376
+ *
377
+ * |格式 |输出| 描述|
378
+ * |----|----|----|
379
+ * |YY| 18 |两位数年份|
380
+ * |YYYY| 2018 |四位数年份|
381
+ * |M| 1-12 |月份,从 1 开始|
382
+ * |MM |01-12 |月份,2 位数字|
383
+ * |D |1-31 |该月的哪一天|
384
+ * |DD| 01-31| 月份中的日期,2 位数字|
385
+ * |h| 0-23| 小时|
386
+ * |hh |00-23 |小时,2 位数字|
387
+ * |m| 0-59| 分钟|
388
+ * |mm |00-59 |分钟,2 位数字|
389
+ * |s |0-59| 秒钟|
390
+ * |ss |00-59 |秒钟,2 位数字|
391
+ */
392
+ const getDate = (date, formatStr) => {
393
+ if (!date)
394
+ date = getTime();
395
+ if (typeof date == 'string' || typeof date == 'number') {
396
+ date = new Date(date);
397
+ }
398
+ if (!formatStr)
399
+ return new Date(date);
400
+ let ret;
401
+ let d = {
402
+ year: date.getFullYear().toString(),
403
+ month: (date.getMonth() + 1).toString(),
404
+ day: date.getDate().toString(),
405
+ hour: date.getHours().toString(),
406
+ minutes: date.getMinutes().toString(),
407
+ seconds: date.getSeconds().toString(),
408
+ week: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][date.getDay()],
409
+ };
410
+ let keys = {
411
+ 'YYYY': d.year,
412
+ 'YY': d.year.slice(2),
413
+ 'M+': d.month,
414
+ 'D+': d.day,
415
+ '[Hh]+': d.hour,
416
+ 'm+': d.minutes,
417
+ 's+': d.seconds,
418
+ '[Ww]+': d.week,
419
+ };
420
+ for (let key in keys) {
421
+ ret = new RegExp('(' + key + ')').exec(formatStr);
422
+ if (ret) {
423
+ formatStr = formatStr.replace(ret[1], keys[key].padStart(ret[1].length, '0'));
424
+ }
425
+ }
426
+ return formatStr;
427
+ };
428
+ /** 获取特殊时间节点
429
+ *
430
+ * @param {'weekstart' | 'weekend' | 'monthstart' | 'monthend' | 'yearstart' | 'yearend' | 'weekbefore' |'weekafter'| 'monthbefore' | 'yearbefore' | 'yearafter'} dateType 获取特殊时间
431
+ * @param {string } formatter 格式字符串或预设方案数字
432
+ *
433
+ * dateType:
434
+ *
435
+ * - weekstart —— 本周起始日期
436
+ *
437
+ * - weekend —— 本周结束日期
438
+ *
439
+ * - weekbefore —— 一周前日期
440
+ *
441
+ * - weekafter —— 一周后日期
442
+ *
443
+ * - monthstart —— 本月起始日期
444
+ *
445
+ * - monthend —— 本月结束日期
446
+ *
447
+ * - monthbefore—— 一个月前日期
448
+ *
449
+ * - yearstart —— 今年1月1日
450
+ *
451
+ * - yearend —— 今年12月31日
452
+ *
453
+ * - yearbefore —— 一年前日期
454
+ *
455
+ * - yearafter —— 一年后日期
456
+ *
457
+ * formatter: 参考 getDate
458
+ *
459
+ * @returns {Date | string}
460
+ */
461
+ const getSpecialDate = (dateType, date, formatter) => {
462
+ // 是否为开始时间
463
+ let isStart = true;
464
+ let time = new Date(date || getTime());
465
+ const setTime = () => {
466
+ if (isStart) {
467
+ time.setHours(0);
468
+ time.setMinutes(0);
469
+ time.setSeconds(0);
470
+ }
471
+ else {
472
+ time.setHours(23);
473
+ time.setMinutes(59);
474
+ time.setSeconds(59);
475
+ }
476
+ };
477
+ switch (dateType) {
478
+ case 'daybefore':
479
+ time = new Date(time.getTime() - 24 * 60 * 60 * 1000);
480
+ break;
481
+ case 'dayafter':
482
+ isStart = false;
483
+ time = new Date(time.getTime() + 24 * 60 * 60 * 1000);
484
+ break;
485
+ case 'weekstart':
486
+ time = new Date(time.getTime() - (time.getDay() - 1) * 24 * 60 * 60 * 1000);
487
+ break;
488
+ case 'weekstart7': //从周日开始
489
+ time = new Date(time.getTime() - time.getDay() * 24 * 60 * 60 * 1000);
490
+ break;
491
+ case 'weekend':
492
+ isStart = false;
493
+ time = new Date(time.getTime() + (7 - time.getDay()) * 24 * 60 * 60 * 1000);
494
+ break;
495
+ case 'weekbefore':
496
+ time = new Date(time.getTime() - 7 * 24 * 60 * 60 * 1000);
497
+ break;
498
+ case 'weekafter':
499
+ isStart = false;
500
+ time = (new Date(time.getTime() + 7 * 24 * 60 * 60 * 1000));
501
+ break;
502
+ case 'monthstart':
503
+ time = (new Date(time.getFullYear(), time.getMonth(), 1));
504
+ break;
505
+ case 'monthend':
506
+ isStart = false;
507
+ time = new Date(time.getFullYear(), time.getMonth() + 1, 0);
508
+ break;
509
+ case 'monthbefore':
510
+ time.setMonth(time.getMonth() - 1);
511
+ break;
512
+ case 'monthafter':
513
+ isStart = false;
514
+ time.setMonth(time.getMonth() + 1);
515
+ break;
516
+ case 'yearstart':
517
+ time.setMonth(0);
518
+ time.setDate(1);
519
+ break;
520
+ case 'yearend':
521
+ isStart = false;
522
+ time.setMonth(11);
523
+ time.setDate(31);
524
+ break;
525
+ case 'yearbefore':
526
+ time.setFullYear(time.getFullYear() - 1);
527
+ break;
528
+ case 'yearafter':
529
+ isStart = false;
530
+ time.setFullYear(time.getFullYear() + 1);
531
+ break;
532
+ }
533
+ setTime();
534
+ return getDate(time, formatter);
535
+ };
536
+
537
+ /*
538
+ * @Description: 对象处理
539
+ * @Author: Zye
540
+ * @Date: 2022-09-08
541
+ */
542
+ /**
543
+ * 从对象数组中获取匹配特定键值对的对象。
544
+ * @param objectArr 对象数组,每个对象至少包含一个键值对。
545
+ * @param keyName 需要匹配的键的名称。
546
+ * @param keyValue 需要匹配的键对应的值。可以是具体值或函数,如果为函数,则会将函数应用于数组中每个对象的键值进行匹配。
547
+ * @param foundKeyName 如果找到匹配的对象,从该对象中返回的键的名称。如果未指定,则返回整个对象。
548
+ * @returns 如果找到匹配的对象且指定了`foundKeyName`,则返回该键的值;如果未指定`foundKeyName`,则返回整个匹配的对象。如果没有找到匹配的对象,则返回一个空对象。
549
+ */
550
+ const getObject = (objectArr, keyName, keyValue, foundKeyName) => {
551
+ // 使用find方法查找数组中匹配的元素,如果未找到则返回一个空对象
552
+ let obj = objectArr.find((v) => (typeof keyValue == 'function' ? keyValue(v[keyName]) : v[keyName] == keyValue)) || new Object();
553
+ // 根据是否指定了foundKeyName返回不同的结果
554
+ return foundKeyName ? obj[foundKeyName] : obj;
555
+ };
556
+ /**
557
+ * 将源对象[src]的属性分配到目标对象[dist],并递归地合并它们的属性。
558
+ * 如果源对象的属性是一个对象(且不是数组),则会递归地将其属性分配到目标对象的相应属性中。
559
+ * 如果源对象的属性是数组或其他类型,则直接覆盖目标对象的相应属性。
560
+ *
561
+ * @param dist 目标对象,其属性将被源对象的属性覆盖或合并。
562
+ * @param src 源对象,其属性将覆盖或合并到目标对象中。
563
+ * @returns 返回合并后的目标对象。
564
+ * @template T 目标对象和源对象的类型,该类型必须是可深度写入的对象类型。
565
+ */
566
+ const assignObject = (dist, src) => {
567
+ const obj = {};
568
+ for (const [key, value] of Object.entries(dist)) {
569
+ if (typeof value !== 'object' || value === null) {
570
+ obj[key] = value;
571
+ }
572
+ }
573
+ for (const [key, value] of Object.entries(src)) {
574
+ if (!dist[key] || typeof value !== 'object' || value === null) {
575
+ obj[key] = value;
576
+ }
577
+ else {
578
+ // 如果源对象中的键值是可深度写入的对象,则递归调用assignObject函数进行合并
579
+ obj[key] = assignObject(dist[key], value);
580
+ }
581
+ }
582
+ return obj;
583
+ };
584
+ /**
585
+ * 此函数用来处理中间件向上透传方法 (仅用于Vue组件封装)
586
+ *
587
+ * @example
588
+ *
589
+ * com.vue
590
+ * !暴露form表单的所有方法,table表格的所有方法,以及onClick
591
+ * defineExpose( { onClick: () => { console.log('click') } }, formRef,tableRef)
592
+ * !父组件调用
593
+ * com.value.change() //调用表单change方法
594
+ * com.value.onClick() //调用onClick方法
595
+ *
596
+ * @param callback 回调函数,传onMounted
597
+ * @param option 默认暴露对象
598
+ * @param refs 要暴露的组件
599
+ * @returns 暴露对象
600
+ */
601
+ const expose = (option, ...refs) => {
602
+ return new Proxy(option, {
603
+ get(_, prop) {
604
+ for (const ref of refs) {
605
+ if (ref.value && prop in ref.value) {
606
+ return ref.value?.[prop];
607
+ }
608
+ }
609
+ },
610
+ has(_, prop) {
611
+ for (const ref of refs) {
612
+ if (ref.value && prop in ref.value) {
613
+ return true;
614
+ }
615
+ }
616
+ return false;
617
+ }
618
+ });
619
+ };
620
+ /**
621
+ * 此函数用来处理中间件向上透传事件 (仅用于Vue组件封装)
622
+ *
623
+ * @param emit emit
624
+ * @param emitStrs
625
+ * @returns
626
+ */
627
+ const on = (emit, emitStrs) => {
628
+ const emits = {};
629
+ if (!Array.isArray(emitStrs)) {
630
+ emitStrs = Object.keys(emitStrs);
631
+ }
632
+ emitStrs.forEach(key => {
633
+ emits[key] = (...args) => {
634
+ emit(key, ...args);
635
+ };
636
+ });
637
+ return emits;
638
+ };
639
+
640
+ /*
641
+ * @Description: 逻辑处理
642
+ * @Author: Zye
643
+ * @Date: 2022-11-21
644
+ */
645
+ const setValue = (condition, value, def = undefined) => {
646
+ return condition ? value : def;
647
+ };
648
+
649
+ /*
650
+ * @Description: 全屏
651
+ * @Author: Zye
652
+ * @Date: 2022-09-29
653
+ */
654
+ /**
655
+ * 是否全屏
656
+ *
657
+ * @returns boolean
658
+ */
659
+ function isFullscreen() {
660
+ return !!(document.fullscreenElement ||
661
+ document.mozFullScreenElement ||
662
+ document.webkitFullscreenElement ||
663
+ document.msFullscreenElement);
664
+ }
665
+ /**
666
+ * 进入全屏
667
+ *
668
+ * @param { HTMLElement } el 需要进入全屏的元素
669
+ *
670
+ */
671
+ function inFullscreen(el = document.querySelector('body')) {
672
+ if (el.requestFullscreen) {
673
+ el.requestFullscreen();
674
+ }
675
+ else if (el.mozRequestFullScreen) {
676
+ // Firefox
677
+ el.mozRequestFullScreen();
678
+ }
679
+ else if (el.webkitRequestFullscreen) {
680
+ // Chrome, Safari, Opera
681
+ el.webkitRequestFullscreen();
682
+ }
683
+ else if (el.msRequestFullscreen) {
684
+ // IE/Edge
685
+ el.msRequestFullscreen();
686
+ }
687
+ }
688
+ /**
689
+ * 退出全屏
690
+ *
691
+ */
692
+ function exitFullscreen() {
693
+ if (document.exitFullscreen) {
694
+ document.exitFullscreen();
695
+ }
696
+ else if (document.mozCancelFullScreen) {
697
+ // Firefox
698
+ document.mozCancelFullScreen();
699
+ }
700
+ else if (document.webkitExitFullscreen) {
701
+ // Chrome, Safari, Opera
702
+ document.webkitExitFullscreen();
703
+ }
704
+ else if (document.msExitFullscreen) {
705
+ // IE/Edge
706
+ document.msExitFullscreen();
707
+ }
708
+ }
709
+ /**
710
+ * 切换全屏显示
711
+ *
712
+ * @param { HTMLElement } el 需要进入全屏的元素
713
+ */
714
+ function fullscreen(el = document.querySelector('body')) {
715
+ isFullscreen() ? exitFullscreen() : inFullscreen(el);
716
+ }
717
+
718
+ /*
719
+ * @Description: 数字处理
720
+ * @Author: Zye
721
+ * @Date: 2021-11-04
722
+ */
723
+ /**
724
+ * 取近似值,取整
725
+ *
726
+ * @param num 数字
727
+ * @param factor 近似因子
728
+ * @returns 数字
729
+ *
730
+ * @ep
731
+ *
732
+ * Num(13,5) // 15
733
+ *
734
+ * Num(1.264,0.01) //1.26
735
+ *
736
+ */
737
+ const Num = (num, factor) => {
738
+ if (!num)
739
+ return 0;
740
+ if (typeof num == 'string') {
741
+ num = parseFloat(num);
742
+ }
743
+ return factor ? Math.round(num / factor) * factor : num;
744
+ };
745
+
746
+ /**
747
+ * 浏览器引擎判断
748
+ *
749
+ * Gecke 火狐(Firefox)
750
+ * Blink (谷歌, 欧朋)
751
+ * WebKit (苹果,老版谷歌)
752
+ * Unknown (其他)
753
+ */
754
+ function browserEngine() {
755
+ var userAgent = navigator.userAgent;
756
+ var isGecko = /Gecko\/\d+\.\d+/i.test(userAgent) && !/like Gecko/.test(userAgent);
757
+ var isBlink = /Chrome\/[\d.]+/.test(userAgent) && /Safari\/[\d.]+/.test(userAgent);
758
+ var isWebKit = /AppleWebKit\/[\d.]+/.test(userAgent) && !isBlink;
759
+ if (isGecko) {
760
+ return 'Gecko';
761
+ }
762
+ else if (isBlink) {
763
+ return 'Blink';
764
+ }
765
+ else if (isWebKit) {
766
+ return 'WebKit';
767
+ }
768
+ else {
769
+ return 'Unknown';
770
+ }
771
+ }
772
+
773
+ /**
774
+ *
775
+ * @param px 像素或者数字
776
+ * @returns
777
+ */
778
+ function addPx(px) {
779
+ return typeof px === 'number' ? px + 'px' : px;
780
+ }
781
+
782
+ /**
783
+ *
784
+ * @param config 配置 (如配置 baseUrl、timeout 等 )
785
+ * @param request 请求拦截
786
+ * @param response 响应成功拦截
787
+ * @param reject 响应错误拦截 (正常情况用不到)
788
+ * @returns
789
+ */
790
+ const createHttp = ({ config = {}, request = config => config, response = data => data, reject = error => Promise.reject(error), }) => {
791
+ // 创建Axios
792
+ const axiosClone = axios.create({ timeout: 1000 * 60 * 5, ...(config || {}) });
793
+ // 请求
794
+ axiosClone.interceptors.request.use((config) => {
795
+ return request(config);
796
+ });
797
+ // 响应
798
+ axiosClone.interceptors.response.use((res) => {
799
+ // 处理文件
800
+ const contentType = res.headers['content-type'];
801
+ if ((contentType && contentType.includes('application/octet-stream')) || contentType.includes('file'))
802
+ return res.data;
803
+ // 处理数据
804
+ return response(res.data, res);
805
+ }, (error) => {
806
+ return Promise.reject(reject(error));
807
+ });
808
+ // 重写http
809
+ const http = (config) => {
810
+ return axiosClone(config);
811
+ };
812
+ const get = (method) => {
813
+ return http[method] = (url, params = {}, config = {}) => {
814
+ return axiosClone[method](url, {
815
+ ...config,
816
+ params,
817
+ });
818
+ };
819
+ };
820
+ const post = (method) => {
821
+ return http[method] = (url, data = {}, config = {}) => {
822
+ return axiosClone[method](url, data, config);
823
+ };
824
+ };
825
+ http.get = get('get');
826
+ http.delete = get('delete');
827
+ http.head = get('head');
828
+ http.post = post('post');
829
+ http.put = post('put');
830
+ http.patch = post('patch');
831
+ return http;
832
+ };
833
+
834
+ let trimLeft = /^\s+/;
835
+ let trimRight = /\s+$/;
836
+ let mathRound = Math.round;
837
+ let mathMin = Math.min;
838
+ let mathMax = Math.max;
839
+ let mathRandom = Math.random;
840
+ class TinyColor {
841
+ matchers;
842
+ names;
843
+ _originalInput;
844
+ _r;
845
+ _g;
846
+ _b;
847
+ _a;
848
+ _roundA;
849
+ _format;
850
+ _gradientType;
851
+ _ok;
852
+ isDark;
853
+ isLight;
854
+ isValid;
855
+ constructor(color, opts) {
856
+ // If input is already a tinycolor, return itself
857
+ if (color instanceof TinyColor) {
858
+ return color;
859
+ }
860
+ this.init(color, opts);
861
+ }
862
+ init(color, opts) {
863
+ this.matchers = this.initMatchers();
864
+ this.names = TinyColor.initNames();
865
+ const rgb = this.inputToRGB(color);
866
+ this._originalInput = typeof color !== 'undefined' ? color : '';
867
+ this._r = rgb.r;
868
+ this._g = rgb.g;
869
+ this._b = rgb.b;
870
+ this._a = rgb.a;
871
+ this._roundA = mathRound(100 * this._a) / 100;
872
+ // this._format = typeof opts !== 'undefined' && typeof opts.format !== 'undefined' ? opts.format : rgb.format || ''
873
+ this._format = opts?.format || rgb?.format || '';
874
+ // this._gradientType = typeof opts !== 'undefined' && typeof opts.gradientType !== 'undefined' ? opts.gradientType : ''
875
+ this._gradientType = opts?.gradientType || '';
876
+ // Don't let the range of [0,255] come back in [0,1].
877
+ // Potentially lose a little bit of precision here, but will fix issues where
878
+ // .5 gets interpreted as half of the total, instead of half of 1
879
+ // If it was supposed to be 128, this was already taken care of by `inputToRgb`
880
+ if (this._r < 1) {
881
+ this._r = mathRound(this._r);
882
+ }
883
+ if (this._g < 1) {
884
+ this._g = mathRound(this._g);
885
+ }
886
+ if (this._b < 1) {
887
+ this._b = mathRound(this._b);
888
+ }
889
+ this._ok = rgb.ok;
890
+ this.initAttr();
891
+ }
892
+ initAttr() {
893
+ this.isDark = this.getBrightness() < 128;
894
+ this.isLight = !this.isDark;
895
+ this.isValid = this._ok;
896
+ }
897
+ static initNames() {
898
+ // Big List of Colors
899
+ // ------------------
900
+ // <http://www.w3.org/TR/css3-color/#svg-color>
901
+ return {
902
+ aliceblue: 'f0f8ff',
903
+ antiquewhite: 'faebd7',
904
+ aqua: '0ff',
905
+ aquamarine: '7fffd4',
906
+ azure: 'f0ffff',
907
+ beige: 'f5f5dc',
908
+ bisque: 'ffe4c4',
909
+ black: '000',
910
+ blanchedalmond: 'ffebcd',
911
+ blue: '00f',
912
+ blueviolet: '8a2be2',
913
+ brown: 'a52a2a',
914
+ burlywood: 'deb887',
915
+ burntsienna: 'ea7e5d',
916
+ cadetblue: '5f9ea0',
917
+ chartreuse: '7fff00',
918
+ chocolate: 'd2691e',
919
+ coral: 'ff7f50',
920
+ cornflowerblue: '6495ed',
921
+ cornsilk: 'fff8dc',
922
+ crimson: 'dc143c',
923
+ cyan: '0ff',
924
+ darkblue: '00008b',
925
+ darkcyan: '008b8b',
926
+ darkgoldenrod: 'b8860b',
927
+ darkgray: 'a9a9a9',
928
+ darkgreen: '006400',
929
+ darkgrey: 'a9a9a9',
930
+ darkkhaki: 'bdb76b',
931
+ darkmagenta: '8b008b',
932
+ darkolivegreen: '556b2f',
933
+ darkorange: 'ff8c00',
934
+ darkorchid: '9932cc',
935
+ darkred: '8b0000',
936
+ darksalmon: 'e9967a',
937
+ darkseagreen: '8fbc8f',
938
+ darkslateblue: '483d8b',
939
+ darkslategray: '2f4f4f',
940
+ darkslategrey: '2f4f4f',
941
+ darkturquoise: '00ced1',
942
+ darkviolet: '9400d3',
943
+ deeppink: 'ff1493',
944
+ deepskyblue: '00bfff',
945
+ dimgray: '696969',
946
+ dimgrey: '696969',
947
+ dodgerblue: '1e90ff',
948
+ firebrick: 'b22222',
949
+ floralwhite: 'fffaf0',
950
+ forestgreen: '228b22',
951
+ fuchsia: 'f0f',
952
+ gainsboro: 'dcdcdc',
953
+ ghostwhite: 'f8f8ff',
954
+ gold: 'ffd700',
955
+ goldenrod: 'daa520',
956
+ gray: '808080',
957
+ green: '008000',
958
+ greenyellow: 'adff2f',
959
+ grey: '808080',
960
+ honeydew: 'f0fff0',
961
+ hotpink: 'ff69b4',
962
+ indianred: 'cd5c5c',
963
+ indigo: '4b0082',
964
+ ivory: 'fffff0',
965
+ khaki: 'f0e68c',
966
+ lavender: 'e6e6fa',
967
+ lavenderblush: 'fff0f5',
968
+ lawngreen: '7cfc00',
969
+ lemonchiffon: 'fffacd',
970
+ lightblue: 'add8e6',
971
+ lightcoral: 'f08080',
972
+ lightcyan: 'e0ffff',
973
+ lightgoldenrodyellow: 'fafad2',
974
+ lightgray: 'd3d3d3',
975
+ lightgreen: '90ee90',
976
+ lightgrey: 'd3d3d3',
977
+ lightpink: 'ffb6c1',
978
+ lightsalmon: 'ffa07a',
979
+ lightseagreen: '20b2aa',
980
+ lightskyblue: '87cefa',
981
+ lightslategray: '789',
982
+ lightslategrey: '789',
983
+ lightsteelblue: 'b0c4de',
984
+ lightyellow: 'ffffe0',
985
+ lime: '0f0',
986
+ limegreen: '32cd32',
987
+ linen: 'faf0e6',
988
+ magenta: 'f0f',
989
+ maroon: '800000',
990
+ mediumaquamarine: '66cdaa',
991
+ mediumblue: '0000cd',
992
+ mediumorchid: 'ba55d3',
993
+ mediumpurple: '9370db',
994
+ mediumseagreen: '3cb371',
995
+ mediumslateblue: '7b68ee',
996
+ mediumspringgreen: '00fa9a',
997
+ mediumturquoise: '48d1cc',
998
+ mediumvioletred: 'c71585',
999
+ midnightblue: '191970',
1000
+ mintcream: 'f5fffa',
1001
+ mistyrose: 'ffe4e1',
1002
+ moccasin: 'ffe4b5',
1003
+ navajowhite: 'ffdead',
1004
+ navy: '000080',
1005
+ oldlace: 'fdf5e6',
1006
+ olive: '808000',
1007
+ olivedrab: '6b8e23',
1008
+ orange: 'ffa500',
1009
+ orangered: 'ff4500',
1010
+ orchid: 'da70d6',
1011
+ palegoldenrod: 'eee8aa',
1012
+ palegreen: '98fb98',
1013
+ paleturquoise: 'afeeee',
1014
+ palevioletred: 'db7093',
1015
+ papayawhip: 'ffefd5',
1016
+ peachpuff: 'ffdab9',
1017
+ peru: 'cd853f',
1018
+ pink: 'ffc0cb',
1019
+ plum: 'dda0dd',
1020
+ powderblue: 'b0e0e6',
1021
+ purple: '800080',
1022
+ rebeccapurple: '663399',
1023
+ red: 'f00',
1024
+ rosybrown: 'bc8f8f',
1025
+ royalblue: '4169e1',
1026
+ saddlebrown: '8b4513',
1027
+ salmon: 'fa8072',
1028
+ sandybrown: 'f4a460',
1029
+ seagreen: '2e8b57',
1030
+ seashell: 'fff5ee',
1031
+ sienna: 'a0522d',
1032
+ silver: 'c0c0c0',
1033
+ skyblue: '87ceeb',
1034
+ slateblue: '6a5acd',
1035
+ slategray: '708090',
1036
+ slategrey: '708090',
1037
+ snow: 'fffafa',
1038
+ springgreen: '00ff7f',
1039
+ steelblue: '4682b4',
1040
+ tan: 'd2b48c',
1041
+ teal: '008080',
1042
+ thistle: 'd8bfd8',
1043
+ tomato: 'ff6347',
1044
+ turquoise: '40e0d0',
1045
+ violet: 'ee82ee',
1046
+ wheat: 'f5deb3',
1047
+ white: 'fff',
1048
+ whitesmoke: 'f5f5f5',
1049
+ yellow: 'ff0',
1050
+ yellowgreen: '9acd32',
1051
+ };
1052
+ }
1053
+ initMatchers() {
1054
+ // <http://www.w3.org/TR/css3-values/#integers>
1055
+ const CSS_INTEGER = '[-\\+]?\\d+%?';
1056
+ // <http://www.w3.org/TR/css3-values/#number-value>
1057
+ const CSS_NUMBER = '[-\\+]?\\d*\\.\\d+%?';
1058
+ // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
1059
+ const CSS_UNIT = '(?:' + CSS_NUMBER + ')|(?:' + CSS_INTEGER + ')';
1060
+ // Actual matching.
1061
+ // Parentheses and commas are optional, but not required.
1062
+ // Whitespace can take the place of commas or opening paren
1063
+ const PERMISSIVE_MATCH3 = '[\\s|\\(]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')\\s*\\)?';
1064
+ const PERMISSIVE_MATCH4 = '[\\s|\\(]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')[,|\\s]+(' + CSS_UNIT + ')\\s*\\)?';
1065
+ return {
1066
+ CSS_UNIT: new RegExp(CSS_UNIT),
1067
+ rgb: new RegExp('rgb' + PERMISSIVE_MATCH3),
1068
+ rgba: new RegExp('rgba' + PERMISSIVE_MATCH4),
1069
+ hsl: new RegExp('hsl' + PERMISSIVE_MATCH3),
1070
+ hsla: new RegExp('hsla' + PERMISSIVE_MATCH4),
1071
+ hsv: new RegExp('hsv' + PERMISSIVE_MATCH3),
1072
+ hsva: new RegExp('hsva' + PERMISSIVE_MATCH4),
1073
+ hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
1074
+ hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
1075
+ hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
1076
+ hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
1077
+ };
1078
+ }
1079
+ getBrightness() {
1080
+ //http://www.w3.org/TR/AERT#color-contrast
1081
+ const rgb = this.toRgb();
1082
+ return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
1083
+ }
1084
+ toRgb() {
1085
+ return {
1086
+ r: mathRound(this._r),
1087
+ g: mathRound(this._g),
1088
+ b: mathRound(this._b),
1089
+ a: this._a,
1090
+ };
1091
+ }
1092
+ static getNames() {
1093
+ return this.initNames();
1094
+ }
1095
+ getOriginalInput() {
1096
+ return this._originalInput;
1097
+ }
1098
+ getFormat() {
1099
+ return this._format;
1100
+ }
1101
+ getAlpha() {
1102
+ return this._a;
1103
+ }
1104
+ getLuminance() {
1105
+ //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
1106
+ const rgb = this.toRgb();
1107
+ let RsRGB, GsRGB, BsRGB, R, G, B;
1108
+ RsRGB = rgb.r / 255;
1109
+ GsRGB = rgb.g / 255;
1110
+ BsRGB = rgb.b / 255;
1111
+ if (RsRGB <= 0.03928) {
1112
+ R = RsRGB / 12.92;
1113
+ }
1114
+ else {
1115
+ R = Math.pow((RsRGB + 0.055) / 1.055, 2.4);
1116
+ }
1117
+ if (GsRGB <= 0.03928) {
1118
+ G = GsRGB / 12.92;
1119
+ }
1120
+ else {
1121
+ G = Math.pow((GsRGB + 0.055) / 1.055, 2.4);
1122
+ }
1123
+ if (BsRGB <= 0.03928) {
1124
+ B = BsRGB / 12.92;
1125
+ }
1126
+ else {
1127
+ B = Math.pow((BsRGB + 0.055) / 1.055, 2.4);
1128
+ }
1129
+ return 0.2126 * R + 0.7152 * G + 0.0722 * B;
1130
+ }
1131
+ setAlpha(value) {
1132
+ this._a = this.boundAlpha(value);
1133
+ this._roundA = mathRound(100 * this._a) / 100;
1134
+ return this;
1135
+ }
1136
+ toHsv() {
1137
+ let hsv = this.rgbToHsv(this._r, this._g, this._b);
1138
+ return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
1139
+ }
1140
+ toHsvString() {
1141
+ let hsv = this.rgbToHsv(this._r, this._g, this._b);
1142
+ let h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
1143
+ return this._a == 1 ? 'hsv(' + h + ', ' + s + '%, ' + v + '%)' : 'hsva(' + h + ', ' + s + '%, ' + v + '%, ' + this._roundA + ')';
1144
+ }
1145
+ toHsl() {
1146
+ let hsl = this.rgbToHsl(this._r, this._g, this._b);
1147
+ return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
1148
+ }
1149
+ toHslString() {
1150
+ let hsl = this.rgbToHsl(this._r, this._g, this._b);
1151
+ let h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
1152
+ return this._a == 1 ? 'hsl(' + h + ', ' + s + '%, ' + l + '%)' : 'hsla(' + h + ', ' + s + '%, ' + l + '%, ' + this._roundA + ')';
1153
+ }
1154
+ toHex(allow3Char) {
1155
+ return this.rgbToHex(this._r, this._g, this._b, allow3Char);
1156
+ }
1157
+ toHexString(allow3Char) {
1158
+ return '#' + this.toHex(allow3Char);
1159
+ }
1160
+ toHex8(allow4Char) {
1161
+ return this.rgbaToHex(this._r, this._g, this._b, this._a, allow4Char);
1162
+ }
1163
+ toHex8String(allow4Char) {
1164
+ return '#' + this.toHex8(allow4Char);
1165
+ }
1166
+ toRgbString() {
1167
+ return this._a == 1
1168
+ ? 'rgb(' + mathRound(this._r) + ', ' + mathRound(this._g) + ', ' + mathRound(this._b) + ')'
1169
+ : 'rgba(' + mathRound(this._r) + ', ' + mathRound(this._g) + ', ' + mathRound(this._b) + ', ' + this._roundA + ')';
1170
+ }
1171
+ toPercentageRgb() {
1172
+ return {
1173
+ r: mathRound(this.bound01(this._r, 255) * 100) + '%',
1174
+ g: mathRound(this.bound01(this._g, 255) * 100) + '%',
1175
+ b: mathRound(this.bound01(this._b, 255) * 100) + '%',
1176
+ a: this._a,
1177
+ };
1178
+ }
1179
+ toPercentageRgbString() {
1180
+ return this._a == 1
1181
+ ? 'rgb(' +
1182
+ mathRound(this.bound01(this._r, 255) * 100) +
1183
+ '%, ' +
1184
+ mathRound(this.bound01(this._g, 255) * 100) +
1185
+ '%, ' +
1186
+ mathRound(this.bound01(this._b, 255) * 100) +
1187
+ '%)'
1188
+ : 'rgba(' +
1189
+ mathRound(this.bound01(this._r, 255) * 100) +
1190
+ '%, ' +
1191
+ mathRound(this.bound01(this._g, 255) * 100) +
1192
+ '%, ' +
1193
+ mathRound(this.bound01(this._b, 255) * 100) +
1194
+ '%, ' +
1195
+ this._roundA +
1196
+ ')';
1197
+ }
1198
+ toName() {
1199
+ if (this._a === 0) {
1200
+ return 'transparent';
1201
+ }
1202
+ if (this._a < 1) {
1203
+ return false;
1204
+ }
1205
+ return this._flip()[this.rgbToHex(this._r, this._g, this._b, true)] || false;
1206
+ }
1207
+ toFilter(secondColor) {
1208
+ let hex8String = '#' + this.rgbaToArgbHex(this._r, this._g, this._b, this._a);
1209
+ let secondHex8String = hex8String;
1210
+ let gradientType = this._gradientType ? 'GradientType = 1, ' : '';
1211
+ if (secondColor) {
1212
+ const tinyColorObj = new TinyColor(secondColor);
1213
+ secondHex8String = '#' + this.rgbaToArgbHex(tinyColorObj._r, tinyColorObj._g, tinyColorObj._b, tinyColorObj._a);
1214
+ }
1215
+ return ('progid:DXImageTransform.Microsoft.gradient(' +
1216
+ gradientType +
1217
+ 'startColorstr=' +
1218
+ hex8String +
1219
+ ',endColorstr=' +
1220
+ secondHex8String +
1221
+ ')');
1222
+ }
1223
+ toString(format) {
1224
+ let formatSet = !!format;
1225
+ format = format || this._format;
1226
+ let formattedString = '';
1227
+ let hasAlpha = this._a < 1 && this._a >= 0;
1228
+ let needsAlphaFormat = !formatSet &&
1229
+ hasAlpha &&
1230
+ (format === 'hex' || format === 'hex6' || format === 'hex3' || format === 'hex4' || format === 'hex8' || format === 'name');
1231
+ if (needsAlphaFormat) {
1232
+ if (format === 'name' && this._a === 0) {
1233
+ return this.toName();
1234
+ }
1235
+ return this.toRgbString();
1236
+ }
1237
+ if (format === 'rgb') {
1238
+ formattedString = this.toRgbString();
1239
+ }
1240
+ if (format === 'prgb') {
1241
+ formattedString = this.toPercentageRgbString();
1242
+ }
1243
+ if (format === 'hex' || format === 'hex6') {
1244
+ formattedString = this.toHexString();
1245
+ }
1246
+ if (format === 'hex3') {
1247
+ formattedString = this.toHexString(true);
1248
+ }
1249
+ if (format === 'hex4') {
1250
+ formattedString = this.toHex8String(true);
1251
+ }
1252
+ if (format === 'hex8') {
1253
+ formattedString = this.toHex8String();
1254
+ }
1255
+ if (format === 'name') {
1256
+ formattedString = this.toName();
1257
+ }
1258
+ if (format === 'hsl') {
1259
+ formattedString = this.toHslString();
1260
+ }
1261
+ if (format === 'hsv') {
1262
+ formattedString = this.toHsvString();
1263
+ }
1264
+ return formattedString || this.toHexString();
1265
+ }
1266
+ clone() {
1267
+ return new TinyColor(this.toString());
1268
+ }
1269
+ _applyModification(fn, args) {
1270
+ let color = fn.apply(null, [this].concat([].slice.call(args)));
1271
+ this._r = color._r;
1272
+ this._g = color._g;
1273
+ this._b = color._b;
1274
+ this.setAlpha(color._a);
1275
+ return this;
1276
+ }
1277
+ _lighten(color, amount) {
1278
+ amount = amount === 0 ? 0 : amount || 10;
1279
+ let hsl = new TinyColor(color).toHsl();
1280
+ hsl.l += amount / 100;
1281
+ hsl.l = color.clamp01(hsl.l);
1282
+ return new TinyColor(hsl);
1283
+ }
1284
+ lighten(...args) {
1285
+ return this._applyModification(this._lighten, args);
1286
+ }
1287
+ _brighten(color, amount) {
1288
+ amount = amount === 0 ? 0 : amount || 10;
1289
+ let rgb = new TinyColor(color).toRgb();
1290
+ rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * -(amount / 100))));
1291
+ rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * -(amount / 100))));
1292
+ rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * -(amount / 100))));
1293
+ return new TinyColor(rgb);
1294
+ }
1295
+ brighten(...args) {
1296
+ return this._applyModification(this._brighten, args);
1297
+ }
1298
+ _darken(color, amount) {
1299
+ amount = amount === 0 ? 0 : amount || 10;
1300
+ let hsl = new TinyColor(color).toHsl();
1301
+ hsl.l -= amount / 100;
1302
+ hsl.l = color.clamp01(hsl.l);
1303
+ return new TinyColor(hsl);
1304
+ }
1305
+ darken(...args) {
1306
+ return this._applyModification(this._darken, args);
1307
+ }
1308
+ _desaturate(color, amount) {
1309
+ amount = amount === 0 ? 0 : amount || 10;
1310
+ let hsl = new TinyColor(color).toHsl();
1311
+ hsl.s -= amount / 100;
1312
+ hsl.s = color.clamp01(hsl.s);
1313
+ return new TinyColor(hsl);
1314
+ }
1315
+ desaturate(...args) {
1316
+ return this._applyModification(this._desaturate, args);
1317
+ }
1318
+ _saturate(color, amount) {
1319
+ amount = amount === 0 ? 0 : amount || 10;
1320
+ let hsl = new TinyColor(color).toHsl();
1321
+ hsl.s += amount / 100;
1322
+ hsl.s = color.clamp01(hsl.s);
1323
+ return new TinyColor(hsl);
1324
+ }
1325
+ saturate(...args) {
1326
+ return this._applyModification(this._saturate, args);
1327
+ }
1328
+ _greyscale(color) {
1329
+ return new TinyColor(color).desaturate(100);
1330
+ }
1331
+ greyscale(...args) {
1332
+ return this._applyModification(this._greyscale, args);
1333
+ }
1334
+ _spin(color, amount) {
1335
+ let hsl = new TinyColor(color).toHsl();
1336
+ let hue = (hsl.h + amount) % 360;
1337
+ hsl.h = hue < 0 ? 360 + hue : hue;
1338
+ return new TinyColor(hsl);
1339
+ }
1340
+ spin(...args) {
1341
+ return this._applyModification(this._spin, args);
1342
+ }
1343
+ _applyCombination(fn, args) {
1344
+ return fn.apply(null, [this].concat([].slice.call(args)));
1345
+ }
1346
+ _analogous(color, results, slices) {
1347
+ results = results || 6;
1348
+ slices = slices || 30;
1349
+ let hsl = new TinyColor(color).toHsl();
1350
+ let part = 360 / slices;
1351
+ let ret = [new TinyColor(color)];
1352
+ for (hsl.h = (hsl.h - ((part * results) >> 1) + 720) % 360; --results;) {
1353
+ hsl.h = (hsl.h + part) % 360;
1354
+ ret.push(new TinyColor(hsl));
1355
+ }
1356
+ return ret;
1357
+ }
1358
+ analogous(...args) {
1359
+ return this._applyCombination(this._analogous, args);
1360
+ }
1361
+ _complement(color) {
1362
+ let hsl = new TinyColor(color).toHsl();
1363
+ hsl.h = (hsl.h + 180) % 360;
1364
+ return new TinyColor(hsl);
1365
+ }
1366
+ complement(...args) {
1367
+ return this._applyCombination(this._complement, args);
1368
+ }
1369
+ _monochromatic(color, results) {
1370
+ results = results || 6;
1371
+ let hsv = new TinyColor(color).toHsv();
1372
+ let h = hsv.h, s = hsv.s, v = hsv.v;
1373
+ let ret = [];
1374
+ let modification = 1 / results;
1375
+ while (results--) {
1376
+ ret.push(new TinyColor({ h: h, s: s, v: v }));
1377
+ v = (v + modification) % 1;
1378
+ }
1379
+ return ret;
1380
+ }
1381
+ monochromatic(...args) {
1382
+ return this._applyCombination(this._monochromatic, args);
1383
+ }
1384
+ _splitcomplement(color) {
1385
+ let hsl = new TinyColor(color).toHsl();
1386
+ let h = hsl.h;
1387
+ return [
1388
+ new TinyColor(color),
1389
+ new TinyColor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l }),
1390
+ new TinyColor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l }),
1391
+ ];
1392
+ }
1393
+ splitcomplement(...args) {
1394
+ return this._applyCombination(this._splitcomplement, args);
1395
+ }
1396
+ _triad(color) {
1397
+ let hsl = new TinyColor(color).toHsl();
1398
+ let h = hsl.h;
1399
+ return [
1400
+ new TinyColor(color),
1401
+ new TinyColor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
1402
+ new TinyColor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }),
1403
+ ];
1404
+ }
1405
+ triad(...args) {
1406
+ return this._applyCombination(this._triad, args);
1407
+ }
1408
+ _tetrad(obj) {
1409
+ let hsl = new TinyColor(obj).toHsl();
1410
+ let h = hsl.h;
1411
+ return [
1412
+ new TinyColor(obj),
1413
+ new TinyColor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
1414
+ new TinyColor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
1415
+ new TinyColor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }),
1416
+ ];
1417
+ }
1418
+ tetrad(...args) {
1419
+ return this._applyCombination(this._tetrad, args);
1420
+ }
1421
+ static fromRatio(color, opts) {
1422
+ if (typeof color == 'object') {
1423
+ let newColor = {};
1424
+ for (let i in color) {
1425
+ if (color.hasOwnProperty(i)) {
1426
+ if (i === 'a') {
1427
+ newColor[i] = color[i];
1428
+ }
1429
+ else {
1430
+ newColor[i] = TinyColor.convertToPercentage(color[i]);
1431
+ }
1432
+ }
1433
+ }
1434
+ color = newColor;
1435
+ }
1436
+ return new TinyColor(color, opts);
1437
+ }
1438
+ static equals(color1, color2) {
1439
+ if (!color1 || !color2) {
1440
+ return false;
1441
+ }
1442
+ return new TinyColor(color1).toRgbString() == new TinyColor(color2).toRgbString();
1443
+ }
1444
+ static random() {
1445
+ return TinyColor.fromRatio({
1446
+ r: mathRandom(),
1447
+ g: mathRandom(),
1448
+ b: mathRandom(),
1449
+ });
1450
+ }
1451
+ static mix(color1, color2, amount) {
1452
+ amount = amount === 0 ? 0 : amount || 50;
1453
+ let rgb1 = new TinyColor(color1).toRgb();
1454
+ let rgb2 = new TinyColor(color2).toRgb();
1455
+ let p = amount / 100;
1456
+ let rgba = {
1457
+ r: (rgb2.r - rgb1.r) * p + rgb1.r,
1458
+ g: (rgb2.g - rgb1.g) * p + rgb1.g,
1459
+ b: (rgb2.b - rgb1.b) * p + rgb1.b,
1460
+ a: (rgb2.a - rgb1.a) * p + rgb1.a,
1461
+ };
1462
+ return new TinyColor(rgba);
1463
+ }
1464
+ static readability(color1, color2) {
1465
+ let c1 = new TinyColor(color1);
1466
+ let c2 = new TinyColor(color2);
1467
+ return (Math.max(c1.getLuminance(), c2.getLuminance()) + 0.05) / (Math.min(c1.getLuminance(), c2.getLuminance()) + 0.05);
1468
+ }
1469
+ static isReadable(color1, color2, wcag2) {
1470
+ let readability = TinyColor.readability(color1, color2);
1471
+ let wcag2Parms, out;
1472
+ out = false;
1473
+ wcag2Parms = TinyColor.validateWCAG2Parms(wcag2);
1474
+ switch (wcag2Parms.level + wcag2Parms.size) {
1475
+ case 'AAsmall':
1476
+ case 'AAAlarge':
1477
+ out = readability >= 4.5;
1478
+ break;
1479
+ case 'AAlarge':
1480
+ out = readability >= 3;
1481
+ break;
1482
+ case 'AAAsmall':
1483
+ out = readability >= 7;
1484
+ break;
1485
+ }
1486
+ return out;
1487
+ }
1488
+ static mostReadable(baseColor, colorList, args) {
1489
+ let bestColor = '';
1490
+ let bestScore = 0;
1491
+ let readability;
1492
+ let includeFallbackColors, level, size;
1493
+ args = args || {};
1494
+ includeFallbackColors = args.includeFallbackColors;
1495
+ level = args.level;
1496
+ size = args.size;
1497
+ for (let item of colorList) {
1498
+ readability = TinyColor.readability(baseColor, item);
1499
+ if (readability > bestScore) {
1500
+ bestScore = readability;
1501
+ bestColor = new TinyColor(item);
1502
+ }
1503
+ }
1504
+ if (TinyColor.isReadable(baseColor, bestColor, {
1505
+ level: level,
1506
+ size: size,
1507
+ }) ||
1508
+ !includeFallbackColors) {
1509
+ return bestColor;
1510
+ }
1511
+ else {
1512
+ args.includeFallbackColors = false;
1513
+ return TinyColor.mostReadable(baseColor, ['#fff', '#000'], args);
1514
+ }
1515
+ }
1516
+ clamp01(val) {
1517
+ return mathMin(1, mathMax(0, val));
1518
+ }
1519
+ _flip() {
1520
+ let flipped = {};
1521
+ let allName = TinyColor.initNames();
1522
+ for (let i in allName) {
1523
+ if (allName.hasOwnProperty(i)) {
1524
+ flipped[allName[i]] = i;
1525
+ }
1526
+ }
1527
+ return flipped;
1528
+ }
1529
+ isValidCSSUnit(color) {
1530
+ return !!this.matchers.CSS_UNIT.exec(color);
1531
+ }
1532
+ isOnePointZero(n) {
1533
+ return typeof n == 'string' && n.indexOf('.') != -1 && parseFloat(n) === 1;
1534
+ }
1535
+ isPercentage(n) {
1536
+ return typeof n === 'string' && n.indexOf('%') != -1;
1537
+ }
1538
+ pad2(c) {
1539
+ return c.length == 1 ? '0' + c : '' + c;
1540
+ }
1541
+ bound01(n, max) {
1542
+ if (this.isOnePointZero(n)) {
1543
+ n = '100%';
1544
+ }
1545
+ let processPercent = this.isPercentage(n);
1546
+ n = mathMin(max, mathMax(0, parseFloat(n)));
1547
+ // Automatically convert percentage into number
1548
+ if (processPercent) {
1549
+ n = parseInt('' + n * max, 10) / 100;
1550
+ }
1551
+ // Handle floating point rounding errors
1552
+ if (Math.abs(n - max) < 0.000001) {
1553
+ return 1;
1554
+ }
1555
+ // Convert into [0, 1] range if it isn't already
1556
+ return (n % max) / parseFloat(max);
1557
+ }
1558
+ convertDecimalToHex(d) {
1559
+ return Math.round(parseFloat(d) * 255).toString(16);
1560
+ }
1561
+ rgbToRgb(r, g, b) {
1562
+ return {
1563
+ r: this.bound01(r, 255) * 255,
1564
+ g: this.bound01(g, 255) * 255,
1565
+ b: this.bound01(b, 255) * 255,
1566
+ };
1567
+ }
1568
+ hsvToRgb(h, s, v) {
1569
+ h = this.bound01(h, 360) * 6;
1570
+ s = this.bound01(s, 100);
1571
+ v = this.bound01(v, 100);
1572
+ let i = Math.floor(h), f = h - i, p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s), mod = i % 6, r = [v, q, p, p, t, v][mod], g = [t, v, v, q, p, p][mod], b = [p, p, t, v, v, q][mod];
1573
+ return { r: r * 255, g: g * 255, b: b * 255 };
1574
+ }
1575
+ hslToRgb(h, s, l) {
1576
+ let r, g, b;
1577
+ h = this.bound01(h, 360);
1578
+ s = this.bound01(s, 100);
1579
+ l = this.bound01(l, 100);
1580
+ function hue2rgb(p, q, t) {
1581
+ if (t < 0)
1582
+ t += 1;
1583
+ if (t > 1)
1584
+ t -= 1;
1585
+ if (t < 1 / 6)
1586
+ return p + (q - p) * 6 * t;
1587
+ if (t < 1 / 2)
1588
+ return q;
1589
+ if (t < 2 / 3)
1590
+ return p + (q - p) * (2 / 3 - t) * 6;
1591
+ return p;
1592
+ }
1593
+ if (s === 0) {
1594
+ r = g = b = l; // achromatic
1595
+ }
1596
+ else {
1597
+ let q = l < 0.5 ? l * (1 + s) : l + s - l * s;
1598
+ let p = 2 * l - q;
1599
+ r = hue2rgb(p, q, h + 1 / 3);
1600
+ g = hue2rgb(p, q, h);
1601
+ b = hue2rgb(p, q, h - 1 / 3);
1602
+ }
1603
+ return { r: r * 255, g: g * 255, b: b * 255 };
1604
+ }
1605
+ rgbToHsl(r, g, b) {
1606
+ r = this.bound01(r, 255);
1607
+ g = this.bound01(g, 255);
1608
+ b = this.bound01(b, 255);
1609
+ let max = mathMax(r, g, b), min = mathMin(r, g, b);
1610
+ let h, s, l = (max + min) / 2;
1611
+ if (max == min) {
1612
+ h = s = 0; // achromatic
1613
+ }
1614
+ else {
1615
+ let d = max - min;
1616
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1617
+ switch (max) {
1618
+ case r:
1619
+ h = (g - b) / d + (g < b ? 6 : 0);
1620
+ break;
1621
+ case g:
1622
+ h = (b - r) / d + 2;
1623
+ break;
1624
+ case b:
1625
+ h = (r - g) / d + 4;
1626
+ break;
1627
+ }
1628
+ h /= 6;
1629
+ }
1630
+ return { h: h, s: s, l: l };
1631
+ }
1632
+ rgbToHsv(r, g, b) {
1633
+ r = this.bound01(r, 255);
1634
+ g = this.bound01(g, 255);
1635
+ b = this.bound01(b, 255);
1636
+ let max = mathMax(r, g, b), min = mathMin(r, g, b);
1637
+ let h, s, v = max;
1638
+ let d = max - min;
1639
+ s = max === 0 ? 0 : d / max;
1640
+ if (max == min) {
1641
+ h = 0; // achromatic
1642
+ }
1643
+ else {
1644
+ switch (max) {
1645
+ case r:
1646
+ h = (g - b) / d + (g < b ? 6 : 0);
1647
+ break;
1648
+ case g:
1649
+ h = (b - r) / d + 2;
1650
+ break;
1651
+ case b:
1652
+ h = (r - g) / d + 4;
1653
+ break;
1654
+ }
1655
+ h /= 6;
1656
+ }
1657
+ return { h: h, s: s, v: v };
1658
+ }
1659
+ rgbToHex(r, g, b, allow3Char) {
1660
+ let hex = [this.pad2(mathRound(r).toString(16)), this.pad2(mathRound(g).toString(16)), this.pad2(mathRound(b).toString(16))];
1661
+ // Return a 3 character hex if possible
1662
+ if (allow3Char &&
1663
+ hex[0].charAt(0) == hex[0].charAt(1) &&
1664
+ hex[1].charAt(0) == hex[1].charAt(1) &&
1665
+ hex[2].charAt(0) == hex[2].charAt(1)) {
1666
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
1667
+ }
1668
+ return hex.join('');
1669
+ }
1670
+ rgbaToHex(r, g, b, a, allow4Char) {
1671
+ let hex = [
1672
+ this.pad2(mathRound(r).toString(16)),
1673
+ this.pad2(mathRound(g).toString(16)),
1674
+ this.pad2(mathRound(b).toString(16)),
1675
+ this.pad2(this.convertDecimalToHex('' + a)),
1676
+ ];
1677
+ // Return a 4 character hex if possible
1678
+ if (allow4Char &&
1679
+ hex[0].charAt(0) == hex[0].charAt(1) &&
1680
+ hex[1].charAt(0) == hex[1].charAt(1) &&
1681
+ hex[2].charAt(0) == hex[2].charAt(1) &&
1682
+ hex[3].charAt(0) == hex[3].charAt(1)) {
1683
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
1684
+ }
1685
+ return hex.join('');
1686
+ }
1687
+ rgbaToArgbHex(r, g, b, a) {
1688
+ let hex = [
1689
+ this.pad2(this.convertDecimalToHex('' + a)),
1690
+ this.pad2(mathRound(r).toString(16)),
1691
+ this.pad2(mathRound(g).toString(16)),
1692
+ this.pad2(mathRound(b).toString(16)),
1693
+ ];
1694
+ return hex.join('');
1695
+ }
1696
+ static convertToPercentage(n) {
1697
+ if (n <= 1) {
1698
+ n = n * 100 + '%';
1699
+ }
1700
+ return n;
1701
+ }
1702
+ boundAlpha(a) {
1703
+ a = parseFloat(a);
1704
+ if (isNaN(a) || a < 0 || a > 1) {
1705
+ a = 1;
1706
+ }
1707
+ return a;
1708
+ }
1709
+ inputToRGB(color) {
1710
+ let rgb = { r: 0, g: 0, b: 0 };
1711
+ let a = 1;
1712
+ let s = null;
1713
+ let v = null;
1714
+ let l = null;
1715
+ let ok = false;
1716
+ let format = '';
1717
+ if (color === null) {
1718
+ color = '';
1719
+ }
1720
+ if (typeof color == 'string') {
1721
+ color = this.stringInputToObject(color);
1722
+ }
1723
+ if (typeof color == 'object') {
1724
+ if (this.isValidCSSUnit(color.r) && this.isValidCSSUnit(color.g) && this.isValidCSSUnit(color.b)) {
1725
+ rgb = this.rgbToRgb(color.r, color.g, color.b);
1726
+ ok = true;
1727
+ format = String(color.r).substr(-1) === '%' ? 'prgb' : 'rgb';
1728
+ }
1729
+ else if (this.isValidCSSUnit(color.h) && this.isValidCSSUnit(color.s) && this.isValidCSSUnit(color.v)) {
1730
+ s = TinyColor.convertToPercentage(color.s);
1731
+ v = TinyColor.convertToPercentage(color.v);
1732
+ rgb = this.hsvToRgb(color.h, s, v);
1733
+ ok = true;
1734
+ format = 'hsv';
1735
+ }
1736
+ else if (this.isValidCSSUnit(color.h) && this.isValidCSSUnit(color.s) && this.isValidCSSUnit(color.l)) {
1737
+ s = TinyColor.convertToPercentage(color.s);
1738
+ l = TinyColor.convertToPercentage(color.l);
1739
+ rgb = this.hslToRgb(color.h, s, l);
1740
+ ok = true;
1741
+ format = 'hsl';
1742
+ }
1743
+ if (color.hasOwnProperty('a')) {
1744
+ a = color.a;
1745
+ }
1746
+ }
1747
+ a = this.boundAlpha(a);
1748
+ return {
1749
+ ok: ok,
1750
+ format: color.format || format,
1751
+ r: mathMin(255, mathMax(rgb.r, 0)),
1752
+ g: mathMin(255, mathMax(rgb.g, 0)),
1753
+ b: mathMin(255, mathMax(rgb.b, 0)),
1754
+ a: a,
1755
+ };
1756
+ }
1757
+ parseIntFromHex(val) {
1758
+ return parseInt(val, 16);
1759
+ }
1760
+ convertHexToDecimal(h) {
1761
+ return this.parseIntFromHex(h) / 255;
1762
+ }
1763
+ stringInputToObject(color) {
1764
+ color = color.replace(trimLeft, '').replace(trimRight, '').toLowerCase();
1765
+ let named = false;
1766
+ if (this.names[color]) {
1767
+ color = this.names[color];
1768
+ named = true;
1769
+ }
1770
+ else if (color == 'transparent') {
1771
+ return { r: 0, g: 0, b: 0, a: 0, format: 'name' };
1772
+ }
1773
+ // Try to match string input using regular expressions.
1774
+ // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
1775
+ // Just return an object and let the conversion functions handle that.
1776
+ // This way the result will be the same whether the tinycolor is initialized with string or object.
1777
+ let match;
1778
+ if ((match = this.matchers.rgb.exec(color))) {
1779
+ return { r: match[1], g: match[2], b: match[3] };
1780
+ }
1781
+ if ((match = this.matchers.rgba.exec(color))) {
1782
+ return { r: match[1], g: match[2], b: match[3], a: match[4] };
1783
+ }
1784
+ if ((match = this.matchers.hsl.exec(color))) {
1785
+ return { h: match[1], s: match[2], l: match[3] };
1786
+ }
1787
+ if ((match = this.matchers.hsla.exec(color))) {
1788
+ return { h: match[1], s: match[2], l: match[3], a: match[4] };
1789
+ }
1790
+ if ((match = this.matchers.hsv.exec(color))) {
1791
+ return { h: match[1], s: match[2], v: match[3] };
1792
+ }
1793
+ if ((match = this.matchers.hsva.exec(color))) {
1794
+ return { h: match[1], s: match[2], v: match[3], a: match[4] };
1795
+ }
1796
+ if ((match = this.matchers.hex8.exec(color))) {
1797
+ return {
1798
+ r: this.parseIntFromHex(match[1]),
1799
+ g: this.parseIntFromHex(match[2]),
1800
+ b: this.parseIntFromHex(match[3]),
1801
+ a: this.convertHexToDecimal(match[4]),
1802
+ format: named ? 'name' : 'hex8',
1803
+ };
1804
+ }
1805
+ if ((match = this.matchers.hex6.exec(color))) {
1806
+ return {
1807
+ r: this.parseIntFromHex(match[1]),
1808
+ g: this.parseIntFromHex(match[2]),
1809
+ b: this.parseIntFromHex(match[3]),
1810
+ format: named ? 'name' : 'hex',
1811
+ };
1812
+ }
1813
+ if ((match = this.matchers.hex4.exec(color))) {
1814
+ return {
1815
+ r: this.parseIntFromHex(match[1] + '' + match[1]),
1816
+ g: this.parseIntFromHex(match[2] + '' + match[2]),
1817
+ b: this.parseIntFromHex(match[3] + '' + match[3]),
1818
+ a: this.convertHexToDecimal(match[4] + '' + match[4]),
1819
+ format: named ? 'name' : 'hex8',
1820
+ };
1821
+ }
1822
+ if ((match = this.matchers.hex3.exec(color))) {
1823
+ return {
1824
+ r: this.parseIntFromHex(match[1] + '' + match[1]),
1825
+ g: this.parseIntFromHex(match[2] + '' + match[2]),
1826
+ b: this.parseIntFromHex(match[3] + '' + match[3]),
1827
+ format: named ? 'name' : 'hex',
1828
+ };
1829
+ }
1830
+ return false;
1831
+ }
1832
+ static validateWCAG2Parms(parms) {
1833
+ // return valid WCAG2 parms for isReadable.
1834
+ // If input parms are invalid, return {"level":"AA", "size":"small"}
1835
+ let level, size;
1836
+ parms = parms || { level: 'AA', size: 'small' };
1837
+ level = (parms.level || 'AA').toUpperCase();
1838
+ size = (parms.size || 'small').toLowerCase();
1839
+ if (level !== 'AA' && level !== 'AAA') {
1840
+ level = 'AA';
1841
+ }
1842
+ if (size !== 'small' && size !== 'large') {
1843
+ size = 'small';
1844
+ }
1845
+ return { level: level, size: size };
1846
+ }
1847
+ }
1848
+
1849
+ export { Num, TinyColor, addPx, assignObject, browserEngine, copyFileOrDir, createDir, createHttp, exitFullscreen, expose, filter, findFiles, fullscreen, getDate, getObject, getSpecialDate, getTime, inFullscreen, isFullscreen, isUrl, on, pathToHump, query, readDir, readFile, relation, removeFileOrDir, setTime, setValue, toHump, toHyphen, urlToData, writeFile };