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