@iobroker/adapter-react-v5 4.9.1 → 4.9.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/Components/CopyToClipboard.d.ts +6 -0
- package/Components/CopyToClipboard.js +158 -0
- package/Components/Image.d.ts +17 -57
- package/Components/Image.js +125 -162
- package/Components/MDUtils.d.ts +9 -9
- package/Components/MDUtils.js +82 -109
- package/Components/ObjectBrowser.d.ts +1 -1
- package/Components/TextWithIcon.d.ts +1 -1
- package/Components/Utils.d.ts +123 -187
- package/Components/Utils.js +1300 -1502
- package/Dialogs/SelectID.js +8 -8
- package/LegacyConnection.d.ts +3 -3
- package/Prompt.d.ts +1 -1
- package/Prompt.js +14 -12
- package/README.md +6 -0
- package/i18n.d.ts +6 -6
- package/index.d.ts +1 -1
- package/index.js +2 -2
- package/package.json +2 -2
- package/Components/Image.js.map +0 -1
- package/Components/MDUtils.js.map +0 -1
- package/Components/Utils.js.map +0 -1
- package/Components/copy-to-clipboard.d.ts +0 -2
- package/Components/copy-to-clipboard.js +0 -161
- package/Components/copy-to-clipboard.js.map +0 -1
- package/Prompt.js.map +0 -1
package/Components/Utils.js
CHANGED
|
@@ -1,1256 +1,1119 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
});
|
|
7
|
-
exports["default"] = void 0;
|
|
8
|
-
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
-
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
10
|
-
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
11
|
-
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
12
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
13
|
-
var _react = _interopRequireDefault(require("react"));
|
|
14
|
-
var _copyToClipboard = _interopRequireDefault(require("./copy-to-clipboard"));
|
|
15
|
-
var _i18n = _interopRequireDefault(require("../i18n"));
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
6
|
/**
|
|
17
7
|
* Copyright 2018-2023 Denis Haev <dogafox@gmail.com>
|
|
18
8
|
*
|
|
19
9
|
* MIT License
|
|
20
10
|
*
|
|
21
11
|
**/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
12
|
+
const react_1 = __importDefault(require("react"));
|
|
13
|
+
const CopyToClipboard_1 = __importDefault(require("./CopyToClipboard"));
|
|
14
|
+
const i18n_1 = __importDefault(require("../i18n"));
|
|
15
|
+
const NAMESPACE = 'material';
|
|
16
|
+
const days = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
|
|
17
|
+
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
18
|
+
const QUALITY_BITS = {
|
|
19
|
+
0x00: '0x00 - good',
|
|
20
|
+
0x01: '0x01 - general problem',
|
|
21
|
+
0x02: '0x02 - no connection problem',
|
|
22
|
+
0x10: '0x10 - substitute value from controller',
|
|
23
|
+
0x20: '0x20 - substitute initial value',
|
|
24
|
+
0x40: '0x40 - substitute value from device or instance',
|
|
25
|
+
0x80: '0x80 - substitute value from sensor',
|
|
26
|
+
0x11: '0x11 - general problem by instance',
|
|
27
|
+
0x41: '0x41 - general problem by device',
|
|
28
|
+
0x81: '0x81 - general problem by sensor',
|
|
29
|
+
0x12: '0x12 - instance not connected',
|
|
30
|
+
0x42: '0x42 - device not connected',
|
|
31
|
+
0x82: '0x82 - sensor not connected',
|
|
32
|
+
0x44: '0x44 - device reports error',
|
|
33
|
+
0x84: '0x84 - sensor reports error',
|
|
42
34
|
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
35
|
+
const SIGNATURES = {
|
|
36
|
+
JVBERi0: 'pdf',
|
|
37
|
+
R0lGODdh: 'gif',
|
|
38
|
+
R0lGODlh: 'gif',
|
|
39
|
+
iVBORw0KGgo: 'png',
|
|
40
|
+
'/9j/': 'jpg',
|
|
41
|
+
PHN2Zw: 'svg',
|
|
42
|
+
Qk1: 'bmp',
|
|
43
|
+
AAABAA: 'ico', // 00 00 01 00 according to https://en.wikipedia.org/wiki/List_of_file_signatures
|
|
52
44
|
};
|
|
53
|
-
|
|
54
|
-
function Utils() {
|
|
55
|
-
(0, _classCallCheck2["default"])(this, Utils);
|
|
56
|
-
}
|
|
57
|
-
(0, _createClass2["default"])(Utils, null, [{
|
|
58
|
-
key: "CapitalWords",
|
|
59
|
-
value:
|
|
45
|
+
class Utils {
|
|
60
46
|
/**
|
|
61
47
|
* Capitalize words.
|
|
62
|
-
* @param {string | undefined} name
|
|
63
|
-
* @returns {string}
|
|
64
48
|
*/
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}).join(' ');
|
|
49
|
+
static CapitalWords(name) {
|
|
50
|
+
return (name || '').split(/[\s_]/)
|
|
51
|
+
.filter(item => item)
|
|
52
|
+
.map(word => (word ? word[0].toUpperCase() + word.substring(1).toLowerCase() : ''))
|
|
53
|
+
.join(' ');
|
|
71
54
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
minutes
|
|
85
|
-
|
|
86
|
-
seconds %= 60;
|
|
87
|
-
seconds = Math.floor(seconds);
|
|
88
|
-
if (seconds < 10) {
|
|
89
|
-
seconds = "0".concat(seconds);
|
|
90
|
-
}
|
|
91
|
-
var text = '';
|
|
92
|
-
if (days_) {
|
|
93
|
-
text += "".concat(days_, " ").concat(_i18n["default"].t('ra_daysShortText'), " ");
|
|
94
|
-
}
|
|
95
|
-
text += "".concat(hours, ":").concat(minutes, ":").concat(seconds);
|
|
96
|
-
return text;
|
|
55
|
+
static formatSeconds(seconds) {
|
|
56
|
+
const days_ = Math.floor(seconds / (3600 * 24));
|
|
57
|
+
seconds %= 3600 * 24;
|
|
58
|
+
const hours = Math.floor(seconds / 3600);
|
|
59
|
+
seconds %= 3600;
|
|
60
|
+
const minutes = Math.floor(seconds / 60);
|
|
61
|
+
seconds %= 60;
|
|
62
|
+
seconds = Math.floor(seconds);
|
|
63
|
+
let text = '';
|
|
64
|
+
if (days_) {
|
|
65
|
+
text += `${days_} ${i18n_1.default.t('ra_daysShortText')} `;
|
|
66
|
+
}
|
|
67
|
+
text += `${hours < 10 ? `0${hours}` : hours}:${minutes < 10 ? `0${minutes}` : minutes}:${seconds < 10 ? `0${seconds}` : seconds}`;
|
|
68
|
+
return text;
|
|
97
69
|
}
|
|
98
|
-
|
|
99
70
|
/**
|
|
100
71
|
* Get the name of the object by id from the name or description.
|
|
101
|
-
* @param
|
|
102
|
-
* @param
|
|
103
|
-
* @param
|
|
104
|
-
* @param
|
|
105
|
-
* @param
|
|
106
|
-
* @returns {string}
|
|
72
|
+
* @param objects
|
|
73
|
+
* @param id
|
|
74
|
+
* @param settings
|
|
75
|
+
* @param options
|
|
76
|
+
* @param isDesc Set to true to get the description.
|
|
107
77
|
*/
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
text
|
|
145
|
-
}
|
|
146
|
-
return text.trim();
|
|
78
|
+
static getObjectName(objects, id, settings, options, isDesc) {
|
|
79
|
+
const item = objects[id];
|
|
80
|
+
let text;
|
|
81
|
+
const attr = isDesc ? 'desc' : 'name';
|
|
82
|
+
if (typeof settings === 'string' && !options) {
|
|
83
|
+
options = { language: settings };
|
|
84
|
+
settings = null;
|
|
85
|
+
}
|
|
86
|
+
options = options || {};
|
|
87
|
+
if (!options.language) {
|
|
88
|
+
options.language = (objects['system.config'] && objects['system.config'].common && objects['system.config'].common.language) || window.sysLang || 'en';
|
|
89
|
+
}
|
|
90
|
+
if (settings === null || settings === void 0 ? void 0 : settings.name) {
|
|
91
|
+
text = settings.name;
|
|
92
|
+
if (typeof text === 'object') {
|
|
93
|
+
text = (options.language && text[options.language]) || text.en;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (item && item.common && item.common[attr]) {
|
|
97
|
+
text = item.common[attr];
|
|
98
|
+
if (attr !== 'desc' && !text && item.common.desc) {
|
|
99
|
+
text = item.common.desc;
|
|
100
|
+
}
|
|
101
|
+
if (typeof text === 'object') {
|
|
102
|
+
text = (options.language && text[options.language]) || text.en || text.de || text.ru || '';
|
|
103
|
+
}
|
|
104
|
+
text = (text || '').toString().replace(/[_.]/g, ' ');
|
|
105
|
+
if (text === text.toUpperCase()) {
|
|
106
|
+
text = text[0] + text.substring(1).toLowerCase();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const pos = id.lastIndexOf('.');
|
|
111
|
+
text = id.substring(pos + 1).replace(/[_.]/g, ' ');
|
|
112
|
+
text = Utils.CapitalWords(text);
|
|
113
|
+
}
|
|
114
|
+
return text.trim();
|
|
147
115
|
}
|
|
148
|
-
|
|
149
116
|
/**
|
|
150
117
|
* Get the name of the object from the name or description.
|
|
151
|
-
* @param
|
|
152
|
-
* @param
|
|
153
|
-
* @param
|
|
154
|
-
* @param
|
|
155
|
-
* @param
|
|
156
|
-
* @returns {string}
|
|
118
|
+
* @param obj
|
|
119
|
+
* @param settings or language
|
|
120
|
+
* @param options
|
|
121
|
+
* @param isDesc Set to true to get the description.
|
|
122
|
+
* @param noTrim Allow to use spaces in name (by edit)
|
|
157
123
|
*/
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
124
|
+
static getObjectNameFromObj(obj, settings, options, isDesc, noTrim) {
|
|
125
|
+
const item = obj;
|
|
126
|
+
let text = (obj && obj._id) || '';
|
|
127
|
+
const attr = isDesc ? 'desc' : 'name';
|
|
128
|
+
if (typeof settings === 'string' && !options) {
|
|
129
|
+
options = { language: settings };
|
|
130
|
+
settings = null;
|
|
131
|
+
}
|
|
132
|
+
options = options || {};
|
|
133
|
+
if (settings === null || settings === void 0 ? void 0 : settings.name) {
|
|
134
|
+
const textOrTranslation = settings.name;
|
|
135
|
+
if (textOrTranslation && typeof textOrTranslation === 'object') {
|
|
136
|
+
text = (options.language && textOrTranslation[options.language]) || textOrTranslation.en;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
text = textOrTranslation;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else if ((item === null || item === void 0 ? void 0 : item.common) && item.common[attr]) {
|
|
143
|
+
let textOrTranslation = item.common[attr];
|
|
144
|
+
if (attr !== 'desc' && !textOrTranslation && item.common.desc) {
|
|
145
|
+
textOrTranslation = item.common.desc;
|
|
146
|
+
}
|
|
147
|
+
if (typeof textOrTranslation === 'object') {
|
|
148
|
+
text = (options.language && textOrTranslation[options.language]) || textOrTranslation.en;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
text = textOrTranslation;
|
|
152
|
+
}
|
|
153
|
+
text = (text || '').toString().replace(/[_.]/g, ' ');
|
|
154
|
+
if (text === text.toUpperCase()) {
|
|
155
|
+
text = text[0] + text.substring(1).toLowerCase();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return noTrim ? text : text.trim();
|
|
190
159
|
}
|
|
191
|
-
|
|
192
160
|
/**
|
|
193
|
-
*
|
|
194
|
-
* @param {string} forEnumId
|
|
195
|
-
* @param {{ user: string; }} options
|
|
196
|
-
* @returns {string | null}
|
|
161
|
+
* Extracts from the object material settings, depends on username
|
|
197
162
|
*/
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
settings
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (settings
|
|
211
|
-
|
|
163
|
+
static getSettingsOrder(obj, forEnumId, options) {
|
|
164
|
+
let common;
|
|
165
|
+
if (obj && Object.prototype.hasOwnProperty.call(obj, 'common')) {
|
|
166
|
+
common = obj.common;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
common = obj;
|
|
170
|
+
}
|
|
171
|
+
let settings;
|
|
172
|
+
if (common === null || common === void 0 ? void 0 : common.custom) {
|
|
173
|
+
settings = common.custom[NAMESPACE];
|
|
174
|
+
const user = options.user || 'admin';
|
|
175
|
+
if (settings && settings[user]) {
|
|
176
|
+
if (forEnumId) {
|
|
177
|
+
if (settings[user].subOrder && settings[user].subOrder[forEnumId]) {
|
|
178
|
+
return JSON.parse(JSON.stringify(settings[user].subOrder[forEnumId]));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else if (settings[user].order) {
|
|
182
|
+
return JSON.parse(JSON.stringify(settings[user].order));
|
|
183
|
+
}
|
|
212
184
|
}
|
|
213
|
-
} else if (settings[user].order) {
|
|
214
|
-
return JSON.parse(JSON.stringify(settings[user].order));
|
|
215
|
-
}
|
|
216
185
|
}
|
|
217
|
-
|
|
218
|
-
return null;
|
|
186
|
+
return null;
|
|
219
187
|
}
|
|
220
|
-
|
|
221
188
|
/**
|
|
222
|
-
|
|
223
|
-
* @param {string} forEnumId
|
|
224
|
-
* @param {{ user: string; }} options
|
|
189
|
+
Used in material
|
|
225
190
|
*/
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
settings
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (settings
|
|
239
|
-
|
|
191
|
+
static getSettingsCustomURLs(obj, forEnumId, options) {
|
|
192
|
+
let common;
|
|
193
|
+
if (obj && Object.prototype.hasOwnProperty.call(obj, 'common')) {
|
|
194
|
+
common = obj.common;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
common = obj;
|
|
198
|
+
}
|
|
199
|
+
let settings;
|
|
200
|
+
if (common === null || common === void 0 ? void 0 : common.custom) {
|
|
201
|
+
settings = common.custom[NAMESPACE];
|
|
202
|
+
const user = options.user || 'admin';
|
|
203
|
+
if (settings && settings[user]) {
|
|
204
|
+
if (forEnumId) {
|
|
205
|
+
if (settings[user].subURLs && settings[user].subURLs[forEnumId]) {
|
|
206
|
+
return JSON.parse(JSON.stringify(settings[user].subURLs[forEnumId]));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else if (settings[user].URLs) {
|
|
210
|
+
return JSON.parse(JSON.stringify(settings[user].URLs));
|
|
211
|
+
}
|
|
240
212
|
}
|
|
241
|
-
} else if (settings[user].URLs) {
|
|
242
|
-
return JSON.parse(JSON.stringify(settings[user].URLs));
|
|
243
|
-
}
|
|
244
213
|
}
|
|
245
|
-
|
|
246
|
-
return null;
|
|
214
|
+
return null;
|
|
247
215
|
}
|
|
248
|
-
|
|
249
216
|
/**
|
|
250
217
|
* Reorder the array items in list between source and dest.
|
|
251
|
-
* @param {Iterable<any> | ArrayLike<any>} list
|
|
252
|
-
* @param {number} source
|
|
253
|
-
* @param {number} dest
|
|
254
218
|
*/
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
_result$splice2 = (0, _slicedToArray2["default"])(_result$splice, 1),
|
|
261
|
-
removed = _result$splice2[0];
|
|
262
|
-
result.splice(dest, 0, removed);
|
|
263
|
-
return result;
|
|
219
|
+
static reorder(list, source, dest) {
|
|
220
|
+
const result = Array.from(list);
|
|
221
|
+
const [removed] = result.splice(source, 1);
|
|
222
|
+
result.splice(dest, 0, removed);
|
|
223
|
+
return result;
|
|
264
224
|
}
|
|
265
|
-
|
|
266
225
|
/**
|
|
267
|
-
|
|
268
|
-
* @param {{ id: any; user: any; name: any; icon: any; color: any; language: ioBroker.Languages; }} options
|
|
269
|
-
* @param {boolean} [defaultEnabling]
|
|
226
|
+
Get smart name settings for the given object.
|
|
270
227
|
*/
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
settings.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
if (
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
228
|
+
static getSettings(obj, options, defaultEnabling) {
|
|
229
|
+
let settings;
|
|
230
|
+
const id = (obj === null || obj === void 0 ? void 0 : obj._id) || (options === null || options === void 0 ? void 0 : options.id);
|
|
231
|
+
let common;
|
|
232
|
+
if (obj && Object.prototype.hasOwnProperty.call(obj, 'common')) {
|
|
233
|
+
common = obj.common;
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
common = obj;
|
|
237
|
+
}
|
|
238
|
+
if (common === null || common === void 0 ? void 0 : common.custom) {
|
|
239
|
+
settings = common.custom;
|
|
240
|
+
settings = settings[NAMESPACE] && settings[NAMESPACE][options.user || 'admin'] ? JSON.parse(JSON.stringify(settings[NAMESPACE][options.user || 'admin'])) : { enabled: true };
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
settings = { enabled: defaultEnabling === undefined ? true : defaultEnabling, useCustom: false };
|
|
244
|
+
}
|
|
245
|
+
if (!Object.prototype.hasOwnProperty.call(settings, 'enabled')) {
|
|
246
|
+
settings.enabled = defaultEnabling === undefined ? true : defaultEnabling;
|
|
247
|
+
}
|
|
248
|
+
// if (false && settings.useCommon) {
|
|
249
|
+
// if (obj.color) settings.color = obj.color;
|
|
250
|
+
// if (obj.icon) settings.icon = obj.icon;
|
|
251
|
+
// if (obj.name) settings.name = obj.name;
|
|
252
|
+
// } else {
|
|
253
|
+
if (options) {
|
|
254
|
+
if (!settings.name && options.name) {
|
|
255
|
+
settings.name = options.name;
|
|
256
|
+
}
|
|
257
|
+
if (!settings.icon && options.icon) {
|
|
258
|
+
settings.icon = options.icon;
|
|
259
|
+
}
|
|
260
|
+
if (!settings.color && options.color) {
|
|
261
|
+
settings.color = options.color;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (common) {
|
|
265
|
+
// @ts-ignore todo: after new types released
|
|
266
|
+
settings.color = settings.color || common.color;
|
|
267
|
+
settings.icon = settings.icon || common.icon;
|
|
268
|
+
settings.name = settings.name || common.name;
|
|
269
|
+
}
|
|
270
|
+
if (typeof settings.name === 'object') {
|
|
271
|
+
settings.name = (options.language && settings.name[options.language]) || settings.name.en;
|
|
272
|
+
settings.name = (settings.name || '').toString().replace(/_/g, ' ');
|
|
273
|
+
if (settings.name === settings.name.toUpperCase()) {
|
|
274
|
+
settings.name = settings.name[0] + settings.name.substring(1).toLowerCase();
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (!settings.name && id) {
|
|
278
|
+
const pos = id.lastIndexOf('.');
|
|
279
|
+
settings.name = id.substring(pos + 1).replace(/[_.]/g, ' ');
|
|
280
|
+
settings.name = (settings.name || '').toString().replace(/_/g, ' ');
|
|
281
|
+
settings.name = Utils.CapitalWords(settings.name);
|
|
282
|
+
}
|
|
283
|
+
return settings;
|
|
326
284
|
}
|
|
327
|
-
|
|
328
285
|
/**
|
|
329
|
-
|
|
330
|
-
* @param {any} settings
|
|
331
|
-
* @param {{ user: any; language: ioBroker.Languages; }} options
|
|
286
|
+
Sets smartName settings for the given object.
|
|
332
287
|
*/
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
288
|
+
static setSettings(obj, settings, options) {
|
|
289
|
+
if (obj) {
|
|
290
|
+
obj.common = obj.common || {};
|
|
291
|
+
obj.common.custom = obj.common.custom || {};
|
|
292
|
+
obj.common.custom[NAMESPACE] = obj.common.custom[NAMESPACE] || {};
|
|
293
|
+
obj.common.custom[NAMESPACE][options.user || 'admin'] = settings;
|
|
294
|
+
const s = obj.common.custom[NAMESPACE][options.user || 'admin'];
|
|
295
|
+
if (s.useCommon) {
|
|
296
|
+
if (s.color !== undefined) {
|
|
297
|
+
// @ts-ignore todo: after new types released
|
|
298
|
+
obj.common.color = s.color;
|
|
299
|
+
delete s.color;
|
|
300
|
+
}
|
|
301
|
+
if (s.icon !== undefined) {
|
|
302
|
+
obj.common.icon = s.icon;
|
|
303
|
+
delete s.icon;
|
|
304
|
+
}
|
|
305
|
+
if (s.name !== undefined) {
|
|
306
|
+
if (typeof obj.common.name !== 'object' && options.language) {
|
|
307
|
+
obj.common.name = { [options.language]: s.name };
|
|
308
|
+
}
|
|
309
|
+
else if (typeof obj.common.name === 'object' && options.language) {
|
|
310
|
+
obj.common.name[options.language] = s.name;
|
|
311
|
+
}
|
|
312
|
+
delete s.name;
|
|
313
|
+
}
|
|
357
314
|
}
|
|
358
|
-
|
|
359
|
-
}
|
|
315
|
+
return true;
|
|
360
316
|
}
|
|
361
|
-
return
|
|
362
|
-
}
|
|
363
|
-
return false;
|
|
317
|
+
return false;
|
|
364
318
|
}
|
|
365
|
-
|
|
366
319
|
/**
|
|
367
320
|
* Get the icon for the given settings.
|
|
368
|
-
* @param {{ icon: string | undefined; name: string | undefined; prefix: string | undefined}} settings
|
|
369
|
-
* @param {any} style
|
|
370
|
-
* @returns {JSX.Element | null}
|
|
371
321
|
*/
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
src: settings.icon,
|
|
386
|
-
style: style || {}
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
// maybe later some changes for a second type
|
|
390
|
-
return /*#__PURE__*/_react["default"].createElement("img", {
|
|
391
|
-
alt: settings.name,
|
|
392
|
-
src: (settings.prefix || '') + settings.icon,
|
|
393
|
-
style: style || {}
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
return null;
|
|
322
|
+
static getIcon(settings, style) {
|
|
323
|
+
if (settings && settings.icon) {
|
|
324
|
+
// If UTF-8 icon
|
|
325
|
+
if (settings.icon.length <= 2) {
|
|
326
|
+
return react_1.default.createElement("span", { style: style || {} }, settings.icon);
|
|
327
|
+
}
|
|
328
|
+
if (settings.icon.startsWith('data:image')) {
|
|
329
|
+
return react_1.default.createElement("img", { alt: settings.name, src: settings.icon, style: style || {} });
|
|
330
|
+
}
|
|
331
|
+
// maybe later some changes for a second type
|
|
332
|
+
return react_1.default.createElement("img", { alt: settings.name, src: (settings.prefix || '') + settings.icon, style: style });
|
|
333
|
+
}
|
|
334
|
+
return null;
|
|
397
335
|
}
|
|
398
|
-
|
|
399
336
|
/**
|
|
400
337
|
* Get the icon for the given object.
|
|
401
|
-
* @param {string} id
|
|
402
|
-
* @param {{ common: { icon: any; }; }} obj
|
|
403
|
-
* @returns {string | null}
|
|
404
338
|
*/
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
339
|
+
static getObjectIcon(id, obj) {
|
|
340
|
+
// If id is Object
|
|
341
|
+
if (typeof id === 'object') {
|
|
342
|
+
obj = id;
|
|
343
|
+
id = obj === null || obj === void 0 ? void 0 : obj._id;
|
|
344
|
+
}
|
|
345
|
+
if (obj && obj.common && obj.common.icon) {
|
|
346
|
+
let icon = obj.common.icon;
|
|
347
|
+
// If UTF-8 icon
|
|
348
|
+
if (typeof icon === 'string' && icon.length <= 2) {
|
|
349
|
+
return icon;
|
|
350
|
+
}
|
|
351
|
+
if (icon.startsWith('data:image')) {
|
|
352
|
+
return icon;
|
|
353
|
+
}
|
|
354
|
+
const parts = id.split('.');
|
|
355
|
+
if (parts[0] === 'system') {
|
|
356
|
+
icon = `adapter/${parts[2]}${icon.startsWith('/') ? '' : '/'}${icon}`;
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
icon = `adapter/${parts[0]}${icon.startsWith('/') ? '' : '/'}${icon}`;
|
|
360
|
+
}
|
|
361
|
+
if (window.location.pathname.match(/adapter\/[^/]+\/[^/]+\.html/)) {
|
|
362
|
+
icon = `../../${icon}`;
|
|
363
|
+
}
|
|
364
|
+
else if (window.location.pathname.match(/material\/[.\d]+/)) {
|
|
365
|
+
icon = `../../${icon}`;
|
|
366
|
+
}
|
|
367
|
+
else if (window.location.pathname.match(/material\//)) {
|
|
368
|
+
icon = `../${icon}`;
|
|
369
|
+
}
|
|
370
|
+
return icon;
|
|
371
|
+
}
|
|
372
|
+
return null;
|
|
438
373
|
}
|
|
439
|
-
|
|
440
374
|
/**
|
|
441
375
|
* Splits CamelCase into words.
|
|
442
|
-
* @param {string | undefined} text
|
|
443
|
-
* @returns {string}
|
|
444
376
|
*/
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
// }
|
|
481
|
-
return Utils.CapitalWords(text);
|
|
377
|
+
static splitCamelCase(text) {
|
|
378
|
+
// if (false && text !== text.toUpperCase()) {
|
|
379
|
+
// const words = text.split(/\s+/);
|
|
380
|
+
// for (let i = 0; i < words.length; i++) {
|
|
381
|
+
// const word = words[i];
|
|
382
|
+
// if (word.toLowerCase() !== word && word.toUpperCase() !== word) {
|
|
383
|
+
// let z = 0;
|
|
384
|
+
// const ww = [];
|
|
385
|
+
// let start = 0;
|
|
386
|
+
// while (z < word.length) {
|
|
387
|
+
// if (word[z].match(/[A-ZÜÄÖА-Я]/)) {
|
|
388
|
+
// ww.push(word.substring(start, z));
|
|
389
|
+
// start = z;
|
|
390
|
+
// }
|
|
391
|
+
// z++;
|
|
392
|
+
// }
|
|
393
|
+
// if (start !== z) {
|
|
394
|
+
// ww.push(word.substring(start, z));
|
|
395
|
+
// }
|
|
396
|
+
// for (let k = 0; k < ww.length; k++) {
|
|
397
|
+
// words.splice(i + k, 0, ww[k]);
|
|
398
|
+
// }
|
|
399
|
+
// i += ww.length;
|
|
400
|
+
// }
|
|
401
|
+
// }
|
|
402
|
+
//
|
|
403
|
+
// return words.map(w => {
|
|
404
|
+
// w = w.trim();
|
|
405
|
+
// if (w) {
|
|
406
|
+
// return w[0].toUpperCase() + w.substring(1).toLowerCase();
|
|
407
|
+
// }
|
|
408
|
+
// return '';
|
|
409
|
+
// }).join(' ');
|
|
410
|
+
// }
|
|
411
|
+
return text ? Utils.CapitalWords(text) : '';
|
|
482
412
|
}
|
|
483
|
-
|
|
484
413
|
/**
|
|
485
414
|
* Check if the given color is bright.
|
|
486
415
|
* https://stackoverflow.com/questions/35969656/how-can-i-generate-the-opposite-color-according-to-current-color
|
|
487
|
-
* @param {string | null | undefined} color
|
|
488
|
-
* @param {boolean} [defaultValue]
|
|
489
|
-
* @returns {boolean}
|
|
490
416
|
*/
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
return r * 0.299 + g * 0.587 + b * 0.114 <= 186;
|
|
417
|
+
static isUseBright(color, defaultValue) {
|
|
418
|
+
if (!color) {
|
|
419
|
+
return defaultValue === undefined ? true : defaultValue;
|
|
420
|
+
}
|
|
421
|
+
color = color.toString();
|
|
422
|
+
if (color.startsWith('#')) {
|
|
423
|
+
color = color.slice(1);
|
|
424
|
+
}
|
|
425
|
+
let r;
|
|
426
|
+
let g;
|
|
427
|
+
let b;
|
|
428
|
+
const rgb = color.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
|
|
429
|
+
if (rgb && rgb.length === 4) {
|
|
430
|
+
r = parseInt(rgb[1], 10);
|
|
431
|
+
g = parseInt(rgb[2], 10);
|
|
432
|
+
b = parseInt(rgb[3], 10);
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
// convert 3-digit hex to 6-digits.
|
|
436
|
+
if (color.length === 3) {
|
|
437
|
+
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
|
|
438
|
+
}
|
|
439
|
+
// remove alfa channel
|
|
440
|
+
if (color.length === 8) {
|
|
441
|
+
color = color.substring(0, 6);
|
|
442
|
+
}
|
|
443
|
+
else if (color.length !== 6) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
r = parseInt(color.slice(0, 2), 16);
|
|
447
|
+
g = parseInt(color.slice(2, 4), 16);
|
|
448
|
+
b = parseInt(color.slice(4, 6), 16);
|
|
449
|
+
}
|
|
450
|
+
// http://stackoverflow.com/a/3943023/112731
|
|
451
|
+
return (r * 0.299 + g * 0.587 + b * 0.114) <= 186;
|
|
527
452
|
}
|
|
528
|
-
|
|
529
453
|
/**
|
|
530
454
|
* Get the time string in the format 00:00.
|
|
531
|
-
* @param {string | number} seconds
|
|
532
455
|
*/
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
minutes = "0".concat(minutes);
|
|
546
|
-
}
|
|
547
|
-
if (secs < 10) {
|
|
548
|
-
secs = "0".concat(secs);
|
|
549
|
-
}
|
|
550
|
-
return "".concat(hours, ":").concat(minutes, ":").concat(secs);
|
|
551
|
-
}
|
|
552
|
-
if (secs < 10) {
|
|
553
|
-
secs = "0".concat(secs);
|
|
554
|
-
}
|
|
555
|
-
return "".concat(minutes, ":").concat(secs);
|
|
456
|
+
static getTimeString(seconds) {
|
|
457
|
+
seconds = parseFloat(seconds.toString());
|
|
458
|
+
if (Number.isNaN(seconds)) {
|
|
459
|
+
return '--:--';
|
|
460
|
+
}
|
|
461
|
+
const hours = Math.floor(seconds / 3600);
|
|
462
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
463
|
+
const secs = seconds % 60;
|
|
464
|
+
if (hours) {
|
|
465
|
+
return `${hours}:${minutes < 10 ? `0${minutes}` : minutes}:${secs < 10 ? `0${secs}` : secs}`;
|
|
466
|
+
}
|
|
467
|
+
return `${minutes < 10 ? `0${minutes}` : minutes}:${secs < 10 ? `0${secs}` : secs}`;
|
|
556
468
|
}
|
|
557
|
-
|
|
558
469
|
/**
|
|
559
470
|
* Gets the wind direction with the given angle (degrees).
|
|
560
|
-
* @param
|
|
561
|
-
* @returns {string | undefined}
|
|
471
|
+
* @param angle in degrees.
|
|
562
472
|
*/
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
473
|
+
static getWindDirection(angle) {
|
|
474
|
+
if (angle >= 0 && angle < 11.25) {
|
|
475
|
+
return 'N';
|
|
476
|
+
}
|
|
477
|
+
if (angle >= 11.25 && angle < 33.75) {
|
|
478
|
+
return 'NNE';
|
|
479
|
+
}
|
|
480
|
+
if (angle >= 33.75 && angle < 56.25) {
|
|
481
|
+
return 'NE';
|
|
482
|
+
}
|
|
483
|
+
if (angle >= 56.25 && angle < 78.75) {
|
|
484
|
+
return 'ENE';
|
|
485
|
+
}
|
|
486
|
+
if (angle >= 78.75 && angle < 101.25) {
|
|
487
|
+
return 'E';
|
|
488
|
+
}
|
|
489
|
+
if (angle >= 101.25 && angle < 123.75) {
|
|
490
|
+
return 'ESE';
|
|
491
|
+
}
|
|
492
|
+
if (angle >= 123.75 && angle < 146.25) {
|
|
493
|
+
return 'SE';
|
|
494
|
+
}
|
|
495
|
+
if (angle >= 146.25 && angle < 168.75) {
|
|
496
|
+
return 'SSE';
|
|
497
|
+
}
|
|
498
|
+
if (angle >= 168.75 && angle < 191.25) {
|
|
499
|
+
return 'S';
|
|
500
|
+
}
|
|
501
|
+
if (angle >= 191.25 && angle < 213.75) {
|
|
502
|
+
return 'SSW';
|
|
503
|
+
}
|
|
504
|
+
if (angle >= 213.75 && angle < 236.25) {
|
|
505
|
+
return 'SW';
|
|
506
|
+
}
|
|
507
|
+
if (angle >= 236.25 && angle < 258.75) {
|
|
508
|
+
return 'WSW';
|
|
509
|
+
}
|
|
510
|
+
if (angle >= 258.75 && angle < 281.25) {
|
|
511
|
+
return 'W';
|
|
512
|
+
}
|
|
513
|
+
if (angle >= 281.25 && angle < 303.75) {
|
|
514
|
+
return 'WNW';
|
|
515
|
+
}
|
|
516
|
+
if (angle >= 303.75 && angle < 326.25) {
|
|
517
|
+
return 'NW';
|
|
518
|
+
}
|
|
519
|
+
if (angle >= 326.25 && angle < 348.75) {
|
|
520
|
+
return 'NNW';
|
|
521
|
+
}
|
|
522
|
+
// if (angle >= 348.75) {
|
|
567
523
|
return 'N';
|
|
568
|
-
}
|
|
569
|
-
if (angle >= 11.25 && angle < 33.75) {
|
|
570
|
-
return 'NNE';
|
|
571
|
-
}
|
|
572
|
-
if (angle >= 33.75 && angle < 56.25) {
|
|
573
|
-
return 'NE';
|
|
574
|
-
}
|
|
575
|
-
if (angle >= 56.25 && angle < 78.75) {
|
|
576
|
-
return 'ENE';
|
|
577
|
-
}
|
|
578
|
-
if (angle >= 78.75 && angle < 101.25) {
|
|
579
|
-
return 'E';
|
|
580
|
-
}
|
|
581
|
-
if (angle >= 101.25 && angle < 123.75) {
|
|
582
|
-
return 'ESE';
|
|
583
|
-
}
|
|
584
|
-
if (angle >= 123.75 && angle < 146.25) {
|
|
585
|
-
return 'SE';
|
|
586
|
-
}
|
|
587
|
-
if (angle >= 146.25 && angle < 168.75) {
|
|
588
|
-
return 'SSE';
|
|
589
|
-
}
|
|
590
|
-
if (angle >= 168.75 && angle < 191.25) {
|
|
591
|
-
return 'S';
|
|
592
|
-
}
|
|
593
|
-
if (angle >= 191.25 && angle < 213.75) {
|
|
594
|
-
return 'SSW';
|
|
595
|
-
}
|
|
596
|
-
if (angle >= 213.75 && angle < 236.25) {
|
|
597
|
-
return 'SW';
|
|
598
|
-
}
|
|
599
|
-
if (angle >= 236.25 && angle < 258.75) {
|
|
600
|
-
return 'WSW';
|
|
601
|
-
}
|
|
602
|
-
if (angle >= 258.75 && angle < 281.25) {
|
|
603
|
-
return 'W';
|
|
604
|
-
}
|
|
605
|
-
if (angle >= 281.25 && angle < 303.75) {
|
|
606
|
-
return 'WNW';
|
|
607
|
-
}
|
|
608
|
-
if (angle >= 303.75 && angle < 326.25) {
|
|
609
|
-
return 'NW';
|
|
610
|
-
}
|
|
611
|
-
if (angle >= 326.25 && angle < 348.75) {
|
|
612
|
-
return 'NNW';
|
|
613
|
-
}
|
|
614
|
-
// if (angle >= 348.75) {
|
|
615
|
-
return 'N';
|
|
616
524
|
}
|
|
617
|
-
|
|
618
525
|
/**
|
|
619
|
-
* Pad the given number with a zero if it's not
|
|
620
|
-
* @param {string | number} num
|
|
526
|
+
* Pad the given number with a zero if it's not two digits long.
|
|
621
527
|
*/
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
return
|
|
633
|
-
}
|
|
634
|
-
return num;
|
|
528
|
+
static padding(num) {
|
|
529
|
+
if (typeof num === 'string') {
|
|
530
|
+
if (num.length < 2) {
|
|
531
|
+
return `0${num}`;
|
|
532
|
+
}
|
|
533
|
+
return num;
|
|
534
|
+
}
|
|
535
|
+
if (num < 10) {
|
|
536
|
+
return `0${num}`;
|
|
537
|
+
}
|
|
538
|
+
return num.toString();
|
|
635
539
|
}
|
|
636
|
-
|
|
637
540
|
/**
|
|
638
541
|
* Sets the date format.
|
|
639
|
-
* @param {string} format
|
|
640
542
|
*/
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
Utils.dateFormat.splice(Utils.dateFormat.indexOf('YYYY'), 1);
|
|
647
|
-
}
|
|
543
|
+
static setDataFormat(format) {
|
|
544
|
+
if (format) {
|
|
545
|
+
Utils.dateFormat = format.toUpperCase().split(/[.-/]/);
|
|
546
|
+
Utils.dateFormat.splice(Utils.dateFormat.indexOf('YYYY'), 1);
|
|
547
|
+
}
|
|
648
548
|
}
|
|
649
|
-
|
|
650
549
|
/**
|
|
651
550
|
* Converts the date to a string.
|
|
652
|
-
* @param {string | number | Date} now
|
|
653
|
-
* @returns {string}
|
|
654
551
|
*/
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
if (!now) return '';
|
|
661
|
-
// only letters
|
|
662
|
-
if (now.match(/^[\w\s]+$/)) {
|
|
663
|
-
// Day of the week
|
|
664
|
-
return now;
|
|
665
|
-
}
|
|
666
|
-
var m = now.match(/(\d{1,4})[-./](\d{1,2})[-./](\d{1,4})/);
|
|
667
|
-
if (m) {
|
|
668
|
-
var a = [parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10)];
|
|
669
|
-
var year = a.find(function (y) {
|
|
670
|
-
return y > 31;
|
|
671
|
-
});
|
|
672
|
-
a.splice(a.indexOf(year), 1);
|
|
673
|
-
var day = a.find(function (mm) {
|
|
674
|
-
return mm > 12;
|
|
675
|
-
});
|
|
676
|
-
if (day) {
|
|
677
|
-
a.splice(a.indexOf(day), 1);
|
|
678
|
-
now = new Date(year, a[0] - 1, day);
|
|
679
|
-
} else if (Utils.dateFormat[0][0] === 'M' && Utils.dateFormat[1][0] === 'D') {
|
|
680
|
-
// MM DD
|
|
681
|
-
now = new Date(year, a[0] - 1, a[1]);
|
|
682
|
-
if (Math.abs(now.getTime - Date.now()) > 3600000 * 24 * 10) {
|
|
683
|
-
now = new Date(year, a[1] - 1, a[0]);
|
|
552
|
+
static date2string(now) {
|
|
553
|
+
if (typeof now === 'string') {
|
|
554
|
+
now = now.trim();
|
|
555
|
+
if (!now) {
|
|
556
|
+
return '';
|
|
684
557
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
now = new Date(year, a[0] - 1, a[1]);
|
|
558
|
+
// only letters
|
|
559
|
+
if (now.match(/^[\w\s]+$/)) {
|
|
560
|
+
// Day of the week
|
|
561
|
+
return now;
|
|
690
562
|
}
|
|
691
|
-
|
|
563
|
+
const m = now.match(/(\d{1,4})[-./](\d{1,2})[-./](\d{1,4})/);
|
|
564
|
+
if (m) {
|
|
565
|
+
const a = [parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10)];
|
|
566
|
+
// we now have 3 numbers. Let's try to detect where is year, where is day and where is month
|
|
567
|
+
const year = a.find(y => y > 31);
|
|
568
|
+
if (year !== undefined) {
|
|
569
|
+
a.splice(a.indexOf(year), 1);
|
|
570
|
+
const day = a.find(mm => mm > 12);
|
|
571
|
+
if (day) {
|
|
572
|
+
a.splice(a.indexOf(day), 1);
|
|
573
|
+
now = new Date(year, a[0] - 1, day);
|
|
574
|
+
}
|
|
575
|
+
else if (Utils.dateFormat[0][0] === 'M' && Utils.dateFormat[1][0] === 'D') {
|
|
576
|
+
// MM DD
|
|
577
|
+
now = new Date(year, a[0] - 1, a[1]);
|
|
578
|
+
if (Math.abs(now.getTime() - Date.now()) > 3600000 * 24 * 10) {
|
|
579
|
+
now = new Date(year, a[1] - 1, a[0]);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
else if (Utils.dateFormat[0][0] === 'D' && Utils.dateFormat[1][0] === 'M') {
|
|
583
|
+
// DD MM
|
|
584
|
+
now = new Date(year, a[1] - 1, a[0]);
|
|
585
|
+
if (Math.abs(now.getTime() - Date.now()) > 3600000 * 24 * 10) {
|
|
586
|
+
now = new Date(year, a[0] - 1, a[1]);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
now = new Date(now);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
now = new Date(now);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
now = new Date(now);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
692
602
|
now = new Date(now);
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
} else {
|
|
698
|
-
now = new Date(now);
|
|
699
|
-
}
|
|
700
|
-
var date = _i18n["default"].t("ra_dow_".concat(days[now.getDay()])).replace('ra_dow_', '');
|
|
701
|
-
date += ". ".concat(now.getDate(), " ").concat(_i18n["default"].t("ra_month_".concat(months[now.getMonth()])).replace('ra_month_', ''));
|
|
702
|
-
return date;
|
|
603
|
+
}
|
|
604
|
+
let date = i18n_1.default.t(`ra_dow_${days[now.getDay()]}`).replace('ra_dow_', '');
|
|
605
|
+
date += `. ${now.getDate()} ${i18n_1.default.t(`ra_month_${months[now.getMonth()]}`).replace('ra_month_', '')}`;
|
|
606
|
+
return date;
|
|
703
607
|
}
|
|
704
|
-
|
|
705
608
|
/**
|
|
706
609
|
* Render a text as a link.
|
|
707
|
-
* @param {string} text
|
|
708
|
-
* @returns {string | JSX.Element[]}
|
|
709
610
|
*/
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
href: href ? href[1] : '',
|
|
745
|
-
target: target ? target[1] : '_blank',
|
|
746
|
-
rel: rel ? rel[1] : '',
|
|
747
|
-
style: {
|
|
748
|
-
color: 'inherit'
|
|
749
|
-
}
|
|
750
|
-
}, title ? title[1] : ''));
|
|
751
|
-
}
|
|
752
|
-
m = text && text.match(/<a [^<]+<\/a>|<br\s?\/?>|<b>[^<]+<\/b>|<i>[^<]+<\/i>/);
|
|
753
|
-
if (!m) {
|
|
754
|
-
text && result.push( /*#__PURE__*/_react["default"].createElement("span", {
|
|
755
|
-
key: "a".concat(key++)
|
|
756
|
-
}, text));
|
|
757
|
-
}
|
|
758
|
-
} while (m);
|
|
759
|
-
return result;
|
|
760
|
-
}
|
|
761
|
-
return text;
|
|
611
|
+
static renderTextWithA(text) {
|
|
612
|
+
let m = text.match(/<a [^<]+<\/a>|<br\s?\/?>|<b>[^<]+<\/b>|<i>[^<]+<\/i>/);
|
|
613
|
+
if (m) {
|
|
614
|
+
const result = [];
|
|
615
|
+
let key = 1;
|
|
616
|
+
do {
|
|
617
|
+
const start = text.substring(0, m.index);
|
|
618
|
+
text = text.substring((m.index || 0) + m[0].length);
|
|
619
|
+
start && result.push(react_1.default.createElement("span", { key: `a${key++}` }, start));
|
|
620
|
+
if (m[0].startsWith('<b>')) {
|
|
621
|
+
result.push(react_1.default.createElement("b", { key: `a${key++}` }, m[0].substring(3, m[0].length - 4)));
|
|
622
|
+
}
|
|
623
|
+
else if (m[0].startsWith('<i>')) {
|
|
624
|
+
result.push(react_1.default.createElement("i", { key: `a${key++}` }, m[0].substring(3, m[0].length - 4)));
|
|
625
|
+
}
|
|
626
|
+
else if (m[0].startsWith('<br')) {
|
|
627
|
+
result.push(react_1.default.createElement("br", { key: `a${key++}` }));
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
const href = m[0].match(/href="([^"]+)"/) || m[0].match(/href='([^']+)'/);
|
|
631
|
+
const target = m[0].match(/target="([^"]+)"/) || m[0].match(/target='([^']+)'/);
|
|
632
|
+
const rel = m[0].match(/rel="([^"]+)"/) || m[0].match(/rel='([^']+)'/);
|
|
633
|
+
const title = m[0].match(/>([^<]*)</);
|
|
634
|
+
// eslint-disable-next-line
|
|
635
|
+
result.push(react_1.default.createElement("a", { key: `a${key++}`, href: href ? href[1] : '', target: target ? target[1] : '_blank', rel: rel ? rel[1] : '', style: { color: 'inherit' } }, title ? title[1] : ''));
|
|
636
|
+
}
|
|
637
|
+
m = text ? text.match(/<a [^<]+<\/a>|<br\s?\/?>|<b>[^<]+<\/b>|<i>[^<]+<\/i>/) : null;
|
|
638
|
+
if (!m) {
|
|
639
|
+
text && result.push(react_1.default.createElement("span", { key: `a${key++}` }, text));
|
|
640
|
+
}
|
|
641
|
+
} while (m);
|
|
642
|
+
return result;
|
|
643
|
+
}
|
|
644
|
+
return text;
|
|
762
645
|
}
|
|
763
|
-
|
|
764
646
|
/**
|
|
765
647
|
* Get the smart name of the given state.
|
|
766
|
-
* @param {Record<string, ioBroker.StateObject> | ioBroker.StateObject} states
|
|
767
|
-
* @param {string} id
|
|
768
|
-
* @param {string} instanceId
|
|
769
|
-
* @param {boolean} [noCommon]
|
|
770
648
|
*/
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
649
|
+
static getSmartName(states, id, instanceId, noCommon) {
|
|
650
|
+
var _a, _b;
|
|
651
|
+
if (!id) {
|
|
652
|
+
if (!noCommon) {
|
|
653
|
+
if (!states.common) {
|
|
654
|
+
// @ts-ignore
|
|
655
|
+
return states.smartName;
|
|
656
|
+
}
|
|
657
|
+
if (states && !states.common) {
|
|
658
|
+
// @ts-ignore
|
|
659
|
+
return states.smartName;
|
|
660
|
+
}
|
|
661
|
+
// @ts-ignore
|
|
662
|
+
return states.common.smartName;
|
|
663
|
+
}
|
|
664
|
+
if (states && !states.common) {
|
|
665
|
+
// @ts-ignore
|
|
666
|
+
return states.smartName;
|
|
667
|
+
}
|
|
668
|
+
const obj = states;
|
|
669
|
+
return ((_a = obj === null || obj === void 0 ? void 0 : obj.common) === null || _a === void 0 ? void 0 : _a.custom) && obj.common.custom[instanceId] ?
|
|
670
|
+
obj.common.custom[instanceId].smartName : undefined;
|
|
671
|
+
}
|
|
777
672
|
if (!noCommon) {
|
|
778
|
-
|
|
779
|
-
return states.smartName;
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
return states.common.smartName;
|
|
785
|
-
}
|
|
786
|
-
if (states && !states.common) {
|
|
787
|
-
return states.smartName;
|
|
788
|
-
}
|
|
789
|
-
return states !== null && states !== void 0 && (_states$common = states.common) !== null && _states$common !== void 0 && _states$common.custom && states.common.custom[instanceId] ? states.common.custom[instanceId].smartName : undefined;
|
|
790
|
-
}
|
|
791
|
-
if (!noCommon) {
|
|
792
|
-
return states[id].common.smartName;
|
|
793
|
-
}
|
|
794
|
-
return states[id] && (_states$id$common = states[id].common) !== null && _states$id$common !== void 0 && _states$id$common.custom && states[id].common.custom[instanceId] ? states[id].common.custom[instanceId].smartName || null : null;
|
|
673
|
+
// @ts-ignore
|
|
674
|
+
return states[id].common.smartName;
|
|
675
|
+
}
|
|
676
|
+
const obj = states[id];
|
|
677
|
+
return ((_b = obj === null || obj === void 0 ? void 0 : obj.common) === null || _b === void 0 ? void 0 : _b.custom) && obj.common.custom[instanceId] ?
|
|
678
|
+
obj.common.custom[instanceId].smartName || null : null;
|
|
795
679
|
}
|
|
796
|
-
|
|
797
680
|
/**
|
|
798
681
|
* Get the smart name from a state.
|
|
799
|
-
* @param {ioBroker.StateObject} obj
|
|
800
|
-
* @param {string} instanceId
|
|
801
|
-
* @param {boolean} [noCommon]
|
|
802
682
|
*/
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
683
|
+
static getSmartNameFromObj(obj, instanceId, noCommon) {
|
|
684
|
+
var _a;
|
|
685
|
+
if (!noCommon) {
|
|
686
|
+
if (!obj.common) {
|
|
687
|
+
// @ts-ignore
|
|
688
|
+
return obj.smartName;
|
|
689
|
+
}
|
|
690
|
+
if (obj && !obj.common) {
|
|
691
|
+
// @ts-ignore
|
|
692
|
+
return obj.smartName;
|
|
693
|
+
}
|
|
694
|
+
// @ts-ignore
|
|
695
|
+
return obj.common.smartName;
|
|
810
696
|
}
|
|
811
697
|
if (obj && !obj.common) {
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
return obj.smartName;
|
|
818
|
-
}
|
|
819
|
-
return obj !== null && obj !== void 0 && (_obj$common = obj.common) !== null && _obj$common !== void 0 && _obj$common.custom && obj.common.custom[instanceId] ? obj.common.custom[instanceId].smartName : undefined;
|
|
698
|
+
// @ts-ignore
|
|
699
|
+
return obj.smartName;
|
|
700
|
+
}
|
|
701
|
+
return ((_a = obj === null || obj === void 0 ? void 0 : obj.common) === null || _a === void 0 ? void 0 : _a.custom) && obj.common.custom[instanceId] ?
|
|
702
|
+
obj.common.custom[instanceId].smartName : undefined;
|
|
820
703
|
}
|
|
821
|
-
|
|
822
704
|
/**
|
|
823
705
|
* Enable smart name for a state.
|
|
824
|
-
* @param {ioBroker.StateObject} obj
|
|
825
|
-
* @param {string} instanceId
|
|
826
|
-
* @param {boolean} [noCommon]
|
|
827
706
|
*/
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
}
|
|
707
|
+
static enableSmartName(obj, instanceId, noCommon) {
|
|
708
|
+
if (noCommon) {
|
|
709
|
+
obj.common.custom = obj.common.custom || {};
|
|
710
|
+
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
|
|
711
|
+
obj.common.custom[instanceId].smartName = {};
|
|
712
|
+
}
|
|
713
|
+
else {
|
|
714
|
+
obj.common.smartName = {};
|
|
715
|
+
}
|
|
838
716
|
}
|
|
839
|
-
|
|
840
717
|
/**
|
|
841
718
|
* Completely remove smart name from a state.
|
|
842
|
-
* @param {ioBroker.StateObject} obj
|
|
843
|
-
* @param {string | number} instanceId
|
|
844
|
-
* @param {boolean} [noCommon]
|
|
845
719
|
*/
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
720
|
+
static removeSmartName(obj, instanceId, noCommon) {
|
|
721
|
+
if (noCommon) {
|
|
722
|
+
if (obj.common && obj.common.custom && obj.common.custom[instanceId]) {
|
|
723
|
+
obj.common.custom[instanceId] = null;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
// @ts-ignore
|
|
728
|
+
obj.common.smartName = null;
|
|
729
|
+
}
|
|
856
730
|
}
|
|
857
|
-
|
|
858
731
|
/**
|
|
859
732
|
* Update the smartname of a state.
|
|
860
|
-
* @param {ioBroker.StateObject} obj
|
|
861
|
-
* @param {string} newSmartName
|
|
862
|
-
* @param {string | undefined} byON
|
|
863
|
-
* @param {string | undefined} smartType
|
|
864
|
-
* @param {string} instanceId
|
|
865
|
-
* @param {boolean} [noCommon]
|
|
866
733
|
*/
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
obj.
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
obj.common.custom[instanceId].smartName.smartType = smartType;
|
|
900
|
-
}
|
|
901
|
-
} else {
|
|
902
|
-
obj.common.smartName = obj.common.smartName || {};
|
|
903
|
-
if (!smartType) {
|
|
904
|
-
delete obj.common.smartName.smartType;
|
|
905
|
-
} else {
|
|
906
|
-
obj.common.smartName.smartType = smartType;
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
if (byON !== undefined) {
|
|
911
|
-
if (noCommon) {
|
|
912
|
-
obj.common.custom = obj.common.custom || {};
|
|
913
|
-
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
|
|
914
|
-
obj.common.custom[instanceId].smartName = obj.common.custom[instanceId].smartName || {};
|
|
915
|
-
obj.common.custom[instanceId].smartName.byON = byON;
|
|
916
|
-
} else {
|
|
917
|
-
obj.common.smartName = obj.common.smartName || {};
|
|
918
|
-
obj.common.smartName.byON = byON;
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
if (newSmartName !== undefined) {
|
|
922
|
-
var smartName;
|
|
923
|
-
if (noCommon) {
|
|
924
|
-
obj.common.custom = obj.common.custom || {};
|
|
925
|
-
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
|
|
926
|
-
obj.common.custom[instanceId].smartName = obj.common.custom[instanceId].smartName || {};
|
|
927
|
-
smartName = obj.common.custom[instanceId].smartName;
|
|
928
|
-
} else {
|
|
929
|
-
obj.common.smartName = obj.common.smartName || {};
|
|
930
|
-
smartName = obj.common.smartName;
|
|
931
|
-
}
|
|
932
|
-
smartName[language] = newSmartName;
|
|
933
|
-
|
|
934
|
-
// If smart name deleted
|
|
935
|
-
if (smartName && (!smartName[language] || smartName[language] === obj.common.name && (!obj.common.role || obj.common.role.includes('button')))) {
|
|
936
|
-
delete smartName[language];
|
|
937
|
-
var empty = true;
|
|
938
|
-
// Check if the structure has any definitions
|
|
939
|
-
for (var key in smartName) {
|
|
940
|
-
if (Object.prototype.hasOwnProperty.call(smartName, key)) {
|
|
941
|
-
empty = false;
|
|
942
|
-
break;
|
|
734
|
+
static updateSmartName(obj, newSmartName, byON, smartType, instanceId, noCommon) {
|
|
735
|
+
const language = i18n_1.default.getLanguage();
|
|
736
|
+
// convert the old format
|
|
737
|
+
if (typeof obj.common.smartName === 'string') {
|
|
738
|
+
const nnn = obj.common.smartName;
|
|
739
|
+
obj.common.smartName = {};
|
|
740
|
+
obj.common.smartName[language] = nnn;
|
|
741
|
+
}
|
|
742
|
+
// convert the old settings
|
|
743
|
+
if (obj.native && obj.native.byON) {
|
|
744
|
+
delete obj.native.byON;
|
|
745
|
+
let _smartName = obj.common.smartName;
|
|
746
|
+
if (!_smartName) {
|
|
747
|
+
_smartName = {};
|
|
748
|
+
}
|
|
749
|
+
else if (typeof _smartName !== 'object') {
|
|
750
|
+
_smartName = { en: _smartName };
|
|
751
|
+
_smartName[language] = _smartName.en;
|
|
752
|
+
}
|
|
753
|
+
obj.common.smartName = _smartName;
|
|
754
|
+
}
|
|
755
|
+
if (smartType !== undefined) {
|
|
756
|
+
if (noCommon) {
|
|
757
|
+
obj.common.custom = obj.common.custom || {};
|
|
758
|
+
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
|
|
759
|
+
obj.common.custom[instanceId].smartName = obj.common.custom[instanceId].smartName || {};
|
|
760
|
+
if (!smartType) {
|
|
761
|
+
delete obj.common.custom[instanceId].smartName.smartType;
|
|
762
|
+
}
|
|
763
|
+
else {
|
|
764
|
+
obj.common.custom[instanceId].smartName.smartType = smartType;
|
|
765
|
+
}
|
|
943
766
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
767
|
+
else {
|
|
768
|
+
obj.common.smartName = obj.common.smartName || {};
|
|
769
|
+
if (!smartType) {
|
|
770
|
+
delete obj.common.smartName.smartType;
|
|
771
|
+
}
|
|
772
|
+
else {
|
|
773
|
+
obj.common.smartName.smartType = smartType;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
if (byON !== undefined) {
|
|
947
778
|
if (noCommon) {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
779
|
+
obj.common.custom = obj.common.custom || {};
|
|
780
|
+
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
|
|
781
|
+
obj.common.custom[instanceId].smartName = obj.common.custom[instanceId].smartName || {};
|
|
782
|
+
obj.common.custom[instanceId].smartName.byON = byON;
|
|
783
|
+
}
|
|
784
|
+
else {
|
|
785
|
+
obj.common.smartName = obj.common.smartName || {};
|
|
786
|
+
// @ts-ignore
|
|
787
|
+
obj.common.smartName.byON = byON;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
if (newSmartName !== undefined) {
|
|
791
|
+
let smartName;
|
|
792
|
+
if (noCommon) {
|
|
793
|
+
obj.common.custom = obj.common.custom || {};
|
|
794
|
+
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
|
|
795
|
+
obj.common.custom[instanceId].smartName = obj.common.custom[instanceId].smartName || {};
|
|
796
|
+
smartName = obj.common.custom[instanceId].smartName;
|
|
797
|
+
}
|
|
798
|
+
else {
|
|
799
|
+
obj.common.smartName = obj.common.smartName || {};
|
|
800
|
+
smartName = obj.common.smartName;
|
|
801
|
+
}
|
|
802
|
+
smartName[language] = newSmartName;
|
|
803
|
+
// If smart name deleted
|
|
804
|
+
if (smartName && (!smartName[language] ||
|
|
805
|
+
(smartName[language] === obj.common.name &&
|
|
806
|
+
(!obj.common.role || obj.common.role.includes('button'))))) {
|
|
807
|
+
delete smartName[language];
|
|
808
|
+
let empty = true;
|
|
809
|
+
// Check if the structure has any definitions
|
|
810
|
+
for (const key in smartName) {
|
|
811
|
+
if (Object.prototype.hasOwnProperty.call(smartName, key)) {
|
|
812
|
+
empty = false;
|
|
813
|
+
break;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
// If empty => delete smartName completely
|
|
817
|
+
if (empty) {
|
|
818
|
+
if (noCommon && obj.common.custom && obj.common.custom[instanceId]) {
|
|
819
|
+
if (obj.common.custom[instanceId].smartName.byON === undefined) {
|
|
820
|
+
delete obj.common.custom[instanceId];
|
|
821
|
+
}
|
|
822
|
+
else {
|
|
823
|
+
delete obj.common.custom[instanceId].en;
|
|
824
|
+
delete obj.common.custom[instanceId].de;
|
|
825
|
+
delete obj.common.custom[instanceId].ru;
|
|
826
|
+
delete obj.common.custom[instanceId].nl;
|
|
827
|
+
delete obj.common.custom[instanceId].pl;
|
|
828
|
+
delete obj.common.custom[instanceId].it;
|
|
829
|
+
delete obj.common.custom[instanceId].fr;
|
|
830
|
+
delete obj.common.custom[instanceId].pt;
|
|
831
|
+
delete obj.common.custom[instanceId].es;
|
|
832
|
+
delete obj.common.custom[instanceId].uk;
|
|
833
|
+
delete obj.common.custom[instanceId]['zh-cn'];
|
|
834
|
+
}
|
|
835
|
+
// @ts-ignore
|
|
836
|
+
}
|
|
837
|
+
else if (obj.common.smartName && obj.common.smartName.byON !== undefined) {
|
|
838
|
+
delete obj.common.smartName.en;
|
|
839
|
+
delete obj.common.smartName.de;
|
|
840
|
+
delete obj.common.smartName.ru;
|
|
841
|
+
delete obj.common.smartName.nl;
|
|
842
|
+
delete obj.common.smartName.pl;
|
|
843
|
+
delete obj.common.smartName.it;
|
|
844
|
+
delete obj.common.smartName.fr;
|
|
845
|
+
delete obj.common.smartName.pt;
|
|
846
|
+
delete obj.common.smartName.es;
|
|
847
|
+
delete obj.common.smartName.uk;
|
|
848
|
+
delete obj.common.smartName['zh-cn'];
|
|
849
|
+
}
|
|
850
|
+
else {
|
|
851
|
+
// @ts-ignore
|
|
852
|
+
obj.common.smartName = null;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
977
855
|
}
|
|
978
|
-
}
|
|
979
856
|
}
|
|
980
|
-
}
|
|
981
857
|
}
|
|
982
|
-
|
|
983
858
|
/**
|
|
984
859
|
* Disable the smart name of a state.
|
|
985
|
-
* @param {ioBroker.StateObject} obj
|
|
986
|
-
* @param {string} instanceId
|
|
987
|
-
* @param {boolean} [noCommon]
|
|
988
860
|
*/
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
861
|
+
static disableSmartName(obj, instanceId, noCommon) {
|
|
862
|
+
if (noCommon) {
|
|
863
|
+
obj.common.custom = obj.common.custom || {};
|
|
864
|
+
obj.common.custom[instanceId] = obj.common.custom[instanceId] || {};
|
|
865
|
+
obj.common.custom[instanceId].smartName = false;
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
// @ts-ignore
|
|
869
|
+
obj.common.smartName = false;
|
|
870
|
+
}
|
|
999
871
|
}
|
|
1000
|
-
|
|
1001
872
|
/**
|
|
1002
873
|
* Copy text to the clipboard.
|
|
1003
|
-
* @param {string} text
|
|
1004
|
-
* @param {Event} [e]
|
|
1005
874
|
*/
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
e && e.preventDefault();
|
|
1011
|
-
return (0, _copyToClipboard["default"])(text);
|
|
875
|
+
static copyToClipboard(text, e) {
|
|
876
|
+
e && e.stopPropagation();
|
|
877
|
+
e && e.preventDefault();
|
|
878
|
+
return (0, CopyToClipboard_1.default)(text);
|
|
1012
879
|
}
|
|
1013
|
-
|
|
1014
880
|
/**
|
|
1015
881
|
* Gets the extension of a file name.
|
|
1016
|
-
* @param
|
|
1017
|
-
* @returns
|
|
882
|
+
* @param fileName the file name.
|
|
883
|
+
* @returns The extension in lower case.
|
|
1018
884
|
*/
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
return
|
|
1025
|
-
}
|
|
1026
|
-
return null;
|
|
885
|
+
static getFileExtension(fileName) {
|
|
886
|
+
const pos = (fileName || '').lastIndexOf('.');
|
|
887
|
+
if (pos !== -1) {
|
|
888
|
+
return fileName.substring(pos + 1).toLowerCase();
|
|
889
|
+
}
|
|
890
|
+
return null;
|
|
1027
891
|
}
|
|
1028
|
-
|
|
1029
892
|
/**
|
|
1030
893
|
* Format number of bytes as a string with B, KB, MB or GB.
|
|
1031
894
|
* The base for all calculations is 1024.
|
|
1032
|
-
* @param
|
|
1033
|
-
* @returns
|
|
895
|
+
* @param bytes The number of bytes.
|
|
896
|
+
* @returns The formatted string (e.g. '723.5 KB')
|
|
1034
897
|
*/
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
bytes
|
|
1046
|
-
|
|
1047
|
-
} while (Math.abs(bytes) >= 1024 && u < units.length - 1);
|
|
1048
|
-
return "".concat(bytes.toFixed(1), " ").concat(units[u]);
|
|
898
|
+
static formatBytes(bytes) {
|
|
899
|
+
if (Math.abs(bytes) < 1024) {
|
|
900
|
+
return `${bytes} B`;
|
|
901
|
+
}
|
|
902
|
+
const units = ['KB', 'MB', 'GB'];
|
|
903
|
+
// const units = ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
|
|
904
|
+
let u = -1;
|
|
905
|
+
do {
|
|
906
|
+
bytes /= 1024;
|
|
907
|
+
++u;
|
|
908
|
+
} while (Math.abs(bytes) >= 1024 && u < units.length - 1);
|
|
909
|
+
return `${bytes.toFixed(1)} ${units[u]}`;
|
|
1049
910
|
}
|
|
1050
|
-
|
|
1051
911
|
/**
|
|
1052
912
|
* Invert the given color according to a theme type to get the inverted text color for background
|
|
1053
|
-
* @param
|
|
1054
|
-
* @param
|
|
1055
|
-
* @param
|
|
1056
|
-
* @returns {string | undefined}
|
|
913
|
+
* @param color Color in the format '#rrggbb' or '#rgb' (or without a hash)
|
|
914
|
+
* @param themeType theme type
|
|
915
|
+
* @param invert dark theme has light color in control or light theme has light color in control
|
|
1057
916
|
*/
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
917
|
+
static getInvertedColor(color, themeType, invert) {
|
|
918
|
+
if (!color) {
|
|
919
|
+
return undefined;
|
|
920
|
+
}
|
|
921
|
+
const invertedColor = Utils.invertColor(color, true);
|
|
922
|
+
if (invertedColor === '#FFFFFF' && (themeType === 'dark' || (invert && themeType === 'light'))) {
|
|
923
|
+
return '#DDD';
|
|
924
|
+
}
|
|
925
|
+
if (invertedColor === '#000000' && (themeType === 'light' || (invert && themeType === 'dark'))) {
|
|
926
|
+
return '#222';
|
|
927
|
+
}
|
|
1062
928
|
return undefined;
|
|
1063
|
-
}
|
|
1064
|
-
var invertedColor = Utils.invertColor(color, true);
|
|
1065
|
-
if (invertedColor === '#FFFFFF' && (themeType === 'dark' || invert && themeType === 'light')) {
|
|
1066
|
-
return '#DDD';
|
|
1067
|
-
}
|
|
1068
|
-
if (invertedColor === '#000000' && (themeType === 'light' || invert && themeType === 'dark')) {
|
|
1069
|
-
return '#222';
|
|
1070
|
-
}
|
|
1071
|
-
return undefined;
|
|
1072
929
|
}
|
|
1073
|
-
|
|
1074
930
|
// Big thanks to: https://stackoverflow.com/questions/35969656/how-can-i-generate-the-opposite-color-according-to-current-color
|
|
1075
931
|
/**
|
|
1076
932
|
* Invert the given color
|
|
1077
|
-
* @param
|
|
1078
|
-
* @param
|
|
1079
|
-
* @returns {string}
|
|
933
|
+
* @param hex Color in the format '#rrggbb' or '#rgb' (or without hash)
|
|
934
|
+
* @param bw Set to black or white.
|
|
1080
935
|
*/
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
936
|
+
static invertColor(hex, bw) {
|
|
937
|
+
if (hex === undefined || hex === null || hex === '' || typeof hex !== 'string') {
|
|
938
|
+
return '';
|
|
939
|
+
}
|
|
940
|
+
if (hex.startsWith('rgba')) {
|
|
941
|
+
const m = hex.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),\s*([.\d]+)\)/);
|
|
942
|
+
if (m) {
|
|
943
|
+
hex = parseInt(m[1], 10).toString(16).padStart(2, '0') +
|
|
944
|
+
parseInt(m[2], 10).toString(16).padStart(2, '0') +
|
|
945
|
+
parseInt(m[2], 10).toString(16).padStart(2, '0');
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
else if (hex.startsWith('rgb')) {
|
|
949
|
+
const m = hex.match(/rgb?\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
950
|
+
if (m) {
|
|
951
|
+
hex = parseInt(m[1], 10).toString(16).padStart(2, '0') +
|
|
952
|
+
parseInt(m[2], 10).toString(16).padStart(2, '0') +
|
|
953
|
+
parseInt(m[2], 10).toString(16).padStart(2, '0');
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
else if (hex.startsWith('#')) {
|
|
957
|
+
hex = hex.slice(1);
|
|
958
|
+
}
|
|
959
|
+
// convert 3-digit hex to 6-digits.
|
|
960
|
+
if (hex.length === 3) {
|
|
961
|
+
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
|
962
|
+
}
|
|
963
|
+
let alfa = null;
|
|
964
|
+
if (hex.length === 8) {
|
|
965
|
+
alfa = hex.substring(6, 8);
|
|
966
|
+
hex = hex.substring(0, 6);
|
|
967
|
+
}
|
|
968
|
+
else if (hex.length !== 6) {
|
|
969
|
+
console.warn(`Cannot invert color: ${hex}`);
|
|
970
|
+
return hex;
|
|
971
|
+
}
|
|
972
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
973
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
974
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
975
|
+
if (bw) {
|
|
976
|
+
// http://stackoverflow.com/a/3943023/112731
|
|
977
|
+
return (r * 0.299 + g * 0.587 + b * 0.114) > 186
|
|
978
|
+
? `#000000${alfa || ''}`
|
|
979
|
+
: `#FFFFFF${alfa || ''}`;
|
|
980
|
+
}
|
|
981
|
+
// invert color components
|
|
982
|
+
const rs = (255 - r).toString(16);
|
|
983
|
+
const gs = (255 - g).toString(16);
|
|
984
|
+
const bd = (255 - b).toString(16);
|
|
985
|
+
// pad each with zeros and return
|
|
986
|
+
return `#${rs.padStart(2, '0')}${gs.padStart(2, '0')}${bd.padStart(2, '0')}${alfa || ''}`;
|
|
1125
987
|
}
|
|
1126
|
-
|
|
1127
988
|
/**
|
|
1128
989
|
* Convert RGB to array [r, g, b]
|
|
1129
|
-
* @param
|
|
1130
|
-
* @returns
|
|
990
|
+
* @param hex Color in the format '#rrggbb' or '#rgb' (or without hash) or rgb(r,g,b) or rgba(r,g,b,a)
|
|
991
|
+
* @returns Array with 3 elements [r, g, b]
|
|
1131
992
|
*/
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
993
|
+
static color2rgb(hex) {
|
|
994
|
+
if (hex === undefined || hex === null || hex === '' || typeof hex !== 'string') {
|
|
995
|
+
return '';
|
|
996
|
+
}
|
|
997
|
+
if (hex.startsWith('rgba')) {
|
|
998
|
+
const m = hex.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),\s*([.\d]+)\)/);
|
|
999
|
+
if (m) {
|
|
1000
|
+
hex = parseInt(m[1], 10).toString(16).padStart(2, '0') +
|
|
1001
|
+
parseInt(m[2], 10).toString(16).padStart(2, '0') +
|
|
1002
|
+
parseInt(m[2], 10).toString(16).padStart(2, '0');
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
else if (hex.startsWith('rgb')) {
|
|
1006
|
+
const m = hex.match(/rgb?\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
1007
|
+
if (m) {
|
|
1008
|
+
hex = parseInt(m[1], 10).toString(16).padStart(2, '0') +
|
|
1009
|
+
parseInt(m[2], 10).toString(16).padStart(2, '0') +
|
|
1010
|
+
parseInt(m[2], 10).toString(16).padStart(2, '0');
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
else if (hex.startsWith('#')) {
|
|
1014
|
+
hex = hex.slice(1);
|
|
1015
|
+
}
|
|
1016
|
+
// convert 3-digit hex to 6-digits.
|
|
1017
|
+
if (hex.length === 3) {
|
|
1018
|
+
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
|
1019
|
+
}
|
|
1020
|
+
if (hex.length !== 6 && hex.length !== 8) {
|
|
1021
|
+
console.warn(`Cannot invert color: ${hex}`);
|
|
1022
|
+
return false;
|
|
1023
|
+
}
|
|
1024
|
+
return [
|
|
1025
|
+
parseInt(hex.slice(0, 2), 16),
|
|
1026
|
+
parseInt(hex.slice(2, 4), 16),
|
|
1027
|
+
parseInt(hex.slice(4, 6), 16),
|
|
1028
|
+
];
|
|
1160
1029
|
}
|
|
1161
|
-
|
|
1162
1030
|
// Big thanks to: https://github.com/antimatter15/rgb-lab
|
|
1163
1031
|
/**
|
|
1164
1032
|
* Convert RGB to LAB
|
|
1165
1033
|
* @param {Array<number>} rgb color in format [r,g,b]
|
|
1166
1034
|
* @returns {Array<number>} lab color in format [l,a,b]
|
|
1167
1035
|
*/
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
z = z > 0.008856 ? Math.pow(z, 0.33333333) : 7.787 * z + 0.137931; // 16 / 116;
|
|
1183
|
-
|
|
1184
|
-
return [116 * y - 16, 500 * (x - y), 200 * (y - z)];
|
|
1036
|
+
static rgb2lab(rgb) {
|
|
1037
|
+
let r = rgb[0] / 255;
|
|
1038
|
+
let g = rgb[1] / 255;
|
|
1039
|
+
let b = rgb[2] / 255;
|
|
1040
|
+
r = (r > 0.04045) ? ((r + 0.055) / 1.055) ** 2.4 : r / 12.92;
|
|
1041
|
+
g = (g > 0.04045) ? ((g + 0.055) / 1.055) ** 2.4 : g / 12.92;
|
|
1042
|
+
b = (b > 0.04045) ? ((b + 0.055) / 1.055) ** 2.4 : b / 12.92;
|
|
1043
|
+
let x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047;
|
|
1044
|
+
let y = (r * 0.2126 + g * 0.7152 + b * 0.0722); /* / 1.00000; */
|
|
1045
|
+
let z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883;
|
|
1046
|
+
x = (x > 0.008856) ? x ** 0.33333333 : (7.787 * x) + 0.137931; // 16 / 116;
|
|
1047
|
+
y = (y > 0.008856) ? y ** 0.33333333 : (7.787 * y) + 0.137931; // 16 / 116;
|
|
1048
|
+
z = (z > 0.008856) ? z ** 0.33333333 : (7.787 * z) + 0.137931; // 16 / 116;
|
|
1049
|
+
return [(116 * y) - 16, 500 * (x - y), 200 * (y - z)];
|
|
1185
1050
|
}
|
|
1186
|
-
|
|
1187
1051
|
/**
|
|
1188
1052
|
* Calculate the distance between two colors in LAB color space in the range 0-100^2
|
|
1189
1053
|
* If distance is less than 1000, the colors are similar
|
|
1190
|
-
* @param
|
|
1191
|
-
* @param
|
|
1192
|
-
* @returns
|
|
1054
|
+
* @param color1 Color in the format '#rrggbb' or '#rgb' (or without hash) or rgb(r,g,b) or rgba(r,g,b,a)
|
|
1055
|
+
* @param color2 Color in the format '#rrggbb' or '#rgb' (or without hash) or rgb(r,g,b) or rgba(r,g,b,a)
|
|
1056
|
+
* @returns distance in the range 0-100^2
|
|
1193
1057
|
*/
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1058
|
+
static colorDistance(color1, color2) {
|
|
1059
|
+
const rgb1 = Utils.color2rgb(color1);
|
|
1060
|
+
const rgb2 = Utils.color2rgb(color2);
|
|
1061
|
+
if (!rgb1 || !rgb2) {
|
|
1062
|
+
return 0;
|
|
1063
|
+
}
|
|
1064
|
+
const lab1 = Utils.rgb2lab(rgb1);
|
|
1065
|
+
const lab2 = Utils.rgb2lab(rgb2);
|
|
1066
|
+
const dltL = lab1[0] - lab2[0];
|
|
1067
|
+
const dltA = lab1[1] - lab2[1];
|
|
1068
|
+
const dltB = lab1[2] - lab2[2];
|
|
1069
|
+
const c1 = Math.sqrt(lab1[1] * lab1[1] + lab1[2] * lab1[2]);
|
|
1070
|
+
const c2 = Math.sqrt(lab2[1] * lab2[1] + lab2[2] * lab2[2]);
|
|
1071
|
+
const dltC = c1 - c2;
|
|
1072
|
+
let dltH = dltA * dltA + dltB * dltB - dltC * dltC;
|
|
1073
|
+
dltH = dltH < 0 ? 0 : Math.sqrt(dltH);
|
|
1074
|
+
const sc = 1.0 + 0.045 * c1;
|
|
1075
|
+
const sh = 1.0 + 0.015 * c1;
|
|
1076
|
+
const dltLKlsl = dltL;
|
|
1077
|
+
const dltCkcsc = dltC / sc;
|
|
1078
|
+
const dltHkhsh = dltH / sh;
|
|
1079
|
+
const i = dltLKlsl * dltLKlsl + dltCkcsc * dltCkcsc + dltHkhsh * dltHkhsh;
|
|
1080
|
+
return i < 0 ? 0 : i;
|
|
1214
1081
|
}
|
|
1215
|
-
|
|
1216
1082
|
// https://github.com/lukeed/clsx/blob/master/src/index.js
|
|
1217
1083
|
// License
|
|
1218
1084
|
// MIT © Luke Edwards
|
|
1219
1085
|
/**
|
|
1220
1086
|
* @private
|
|
1221
|
-
* @param {any} mix
|
|
1222
|
-
* @returns {string}
|
|
1223
1087
|
*/
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1088
|
+
static _toVal(mix) {
|
|
1089
|
+
let y;
|
|
1090
|
+
let str = '';
|
|
1091
|
+
if (typeof mix === 'string' || typeof mix === 'number') {
|
|
1092
|
+
str += mix;
|
|
1093
|
+
}
|
|
1094
|
+
else if (typeof mix === 'object') {
|
|
1095
|
+
if (Array.isArray(mix)) {
|
|
1096
|
+
for (let k = 0; k < mix.length; k++) {
|
|
1097
|
+
if (mix[k]) {
|
|
1098
|
+
y = Utils._toVal(mix[k]);
|
|
1099
|
+
if (y) {
|
|
1100
|
+
str && (str += ' ');
|
|
1101
|
+
str += y;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1240
1105
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1106
|
+
else {
|
|
1107
|
+
for (const k in mix) {
|
|
1108
|
+
if (mix[k]) {
|
|
1109
|
+
str && (str += ' ');
|
|
1110
|
+
str += k;
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1247
1113
|
}
|
|
1248
|
-
}
|
|
1249
1114
|
}
|
|
1250
|
-
|
|
1251
|
-
return str;
|
|
1115
|
+
return str;
|
|
1252
1116
|
}
|
|
1253
|
-
|
|
1254
1117
|
// https://github.com/lukeed/clsx/blob/master/src/index.js
|
|
1255
1118
|
// License
|
|
1256
1119
|
// MIT © Luke Edwards
|
|
@@ -1258,509 +1121,444 @@ var Utils = /*#__PURE__*/function () {
|
|
|
1258
1121
|
* Convert any object to a string with its values.
|
|
1259
1122
|
* @returns {string}
|
|
1260
1123
|
*/
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
}
|
|
1279
|
-
return str;
|
|
1124
|
+
static clsx(...inputs) {
|
|
1125
|
+
let i = 0;
|
|
1126
|
+
let tmp;
|
|
1127
|
+
let x;
|
|
1128
|
+
let str = '';
|
|
1129
|
+
while (i < inputs.length) {
|
|
1130
|
+
// eslint-disable-next-line prefer-rest-params
|
|
1131
|
+
tmp = inputs[i++];
|
|
1132
|
+
if (tmp) {
|
|
1133
|
+
x = Utils._toVal(tmp);
|
|
1134
|
+
if (x) {
|
|
1135
|
+
str && (str += ' ');
|
|
1136
|
+
str += x;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
return str;
|
|
1280
1141
|
}
|
|
1281
|
-
|
|
1282
1142
|
/**
|
|
1283
1143
|
* Get the current theme name (either from local storage or the browser settings).
|
|
1284
1144
|
* @param {string} [themeName]
|
|
1285
1145
|
* @returns {string}
|
|
1286
1146
|
*/
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
}
|
|
1294
|
-
return themeName || ((window._localStorage || window.localStorage).getItem('App.themeName') ? (window._localStorage || window.localStorage).getItem('App.themeName') : window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'colored');
|
|
1147
|
+
static getThemeName(themeName = '') {
|
|
1148
|
+
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
|
|
1149
|
+
return window.vendorPrefix;
|
|
1150
|
+
}
|
|
1151
|
+
return themeName || ((window._localStorage || window.localStorage).getItem('App.themeName') ?
|
|
1152
|
+
(window._localStorage || window.localStorage).getItem('App.themeName') : window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'colored');
|
|
1295
1153
|
}
|
|
1296
|
-
|
|
1297
1154
|
/**
|
|
1298
1155
|
* Get the type of theme.
|
|
1299
|
-
* @param {string} [themeName]
|
|
1300
|
-
* @returns {'dark' | 'light'}
|
|
1301
1156
|
*/
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
return 'light';
|
|
1308
|
-
}
|
|
1309
|
-
themeName = themeName || (window._localStorage || window.localStorage).getItem('App.themeName');
|
|
1310
|
-
return themeName === 'dark' || themeName === 'blue' ? 'dark' : 'light';
|
|
1157
|
+
static getThemeType(themeName) {
|
|
1158
|
+
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
|
|
1159
|
+
return 'light';
|
|
1160
|
+
}
|
|
1161
|
+
themeName = themeName || (window._localStorage || window.localStorage).getItem('App.themeName');
|
|
1162
|
+
return themeName === 'dark' || themeName === 'blue' ? 'dark' : 'light';
|
|
1311
1163
|
}
|
|
1312
|
-
|
|
1313
1164
|
/**
|
|
1314
1165
|
* Set the theme name and theme type.
|
|
1315
|
-
* @param {string} themeName
|
|
1316
1166
|
*/
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
(window._localStorage || window.localStorage).setItem('App.themeName', themeName);
|
|
1324
|
-
(window._localStorage || window.localStorage).setItem('App.theme', themeName === 'dark' || themeName === 'blue' ? 'dark' : 'light');
|
|
1167
|
+
static setThemeName(themeName) {
|
|
1168
|
+
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
|
|
1169
|
+
return; // ignore
|
|
1170
|
+
}
|
|
1171
|
+
(window._localStorage || window.localStorage).setItem('App.themeName', themeName);
|
|
1172
|
+
(window._localStorage || window.localStorage).setItem('App.theme', themeName === 'dark' || themeName === 'blue' ? 'dark' : 'light');
|
|
1325
1173
|
}
|
|
1326
|
-
|
|
1327
1174
|
/**
|
|
1328
1175
|
* Toggle the theme name between 'dark' and 'colored'.
|
|
1329
1176
|
* @param {string | null} themeName
|
|
1330
1177
|
* @returns {string} the new theme name.
|
|
1331
1178
|
*/
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
newTheme
|
|
1348
|
-
|
|
1349
|
-
Utils.setThemeName(newTheme);
|
|
1350
|
-
return newTheme;
|
|
1179
|
+
static toggleTheme(themeName) {
|
|
1180
|
+
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
|
|
1181
|
+
return window.vendorPrefix;
|
|
1182
|
+
}
|
|
1183
|
+
themeName = themeName || (window._localStorage || window.localStorage).getItem('App.themeName') || 'light';
|
|
1184
|
+
// dark => blue => colored => light => dark
|
|
1185
|
+
const themes = Utils.getThemeNames();
|
|
1186
|
+
const pos = themeName ? themes.indexOf(themeName) : -1;
|
|
1187
|
+
let newTheme;
|
|
1188
|
+
if (pos !== -1) {
|
|
1189
|
+
newTheme = themes[(pos + 1) % themes.length];
|
|
1190
|
+
}
|
|
1191
|
+
else {
|
|
1192
|
+
newTheme = themes[0];
|
|
1193
|
+
}
|
|
1194
|
+
Utils.setThemeName(newTheme);
|
|
1195
|
+
return newTheme;
|
|
1351
1196
|
}
|
|
1352
|
-
|
|
1353
1197
|
/**
|
|
1354
1198
|
* Get the list of themes
|
|
1355
|
-
* @returns
|
|
1199
|
+
* @returns list of possible themes
|
|
1356
1200
|
*/
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
return [
|
|
1362
|
-
}
|
|
1363
|
-
return ['light', 'dark', 'blue', 'colored'];
|
|
1201
|
+
static getThemeNames() {
|
|
1202
|
+
if (window.vendorPrefix && window.vendorPrefix !== '@@vendorPrefix@@') {
|
|
1203
|
+
return [window.vendorPrefix];
|
|
1204
|
+
}
|
|
1205
|
+
return ['light', 'dark', 'blue', 'colored'];
|
|
1364
1206
|
}
|
|
1365
|
-
|
|
1366
1207
|
/**
|
|
1367
1208
|
* Parse a query string into its parts.
|
|
1368
|
-
* @param {string} query
|
|
1369
|
-
* @returns {Record<string, string | boolean | number>}
|
|
1370
1209
|
*/
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1210
|
+
static parseQuery(query) {
|
|
1211
|
+
query = (query || '').toString().replace(/^\?/, '');
|
|
1212
|
+
/** @type {Record<string, string | boolean | number>} */
|
|
1213
|
+
const result = {};
|
|
1214
|
+
query.split('&').forEach(part => {
|
|
1215
|
+
part = part.trim();
|
|
1216
|
+
if (part) {
|
|
1217
|
+
const parts = part.split('=');
|
|
1218
|
+
const attr = decodeURIComponent(parts[0]).trim();
|
|
1219
|
+
if (parts.length > 1) {
|
|
1220
|
+
result[attr] = decodeURIComponent(parts[1]);
|
|
1221
|
+
if (result[attr] === 'true') {
|
|
1222
|
+
result[attr] = true;
|
|
1223
|
+
}
|
|
1224
|
+
else if (result[attr] === 'false') {
|
|
1225
|
+
result[attr] = false;
|
|
1226
|
+
}
|
|
1227
|
+
else if (result[attr]) {
|
|
1228
|
+
const f = parseFloat(result[attr].toString());
|
|
1229
|
+
if (f.toString() === result[attr]) {
|
|
1230
|
+
result[attr] = f;
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
else {
|
|
1235
|
+
result[attr] = true;
|
|
1236
|
+
}
|
|
1393
1237
|
}
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
});
|
|
1399
|
-
return result;
|
|
1238
|
+
});
|
|
1239
|
+
return result;
|
|
1400
1240
|
}
|
|
1401
|
-
|
|
1402
1241
|
/**
|
|
1403
1242
|
* Returns parent ID.
|
|
1404
|
-
* @
|
|
1405
|
-
* @returns {string | null} parent ID or null if no parent
|
|
1243
|
+
* @returns parent ID or null if no parent
|
|
1406
1244
|
*/
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
return
|
|
1414
|
-
}
|
|
1415
|
-
return null;
|
|
1416
|
-
}
|
|
1417
|
-
}, {
|
|
1418
|
-
key: "formatDate",
|
|
1419
|
-
value: function formatDate(dateObj, dateFormat) {
|
|
1420
|
-
// format could be DD.MM.YYYY, YYYY.MM.DD or MM/DD/YYYY
|
|
1421
|
-
|
|
1422
|
-
if (!dateObj) {
|
|
1423
|
-
return '';
|
|
1424
|
-
}
|
|
1425
|
-
var text;
|
|
1426
|
-
var mm = dateObj.getMonth() + 1;
|
|
1427
|
-
if (mm < 10) {
|
|
1428
|
-
mm = "0".concat(mm);
|
|
1429
|
-
}
|
|
1430
|
-
var dd = dateObj.getDate();
|
|
1431
|
-
if (dd < 10) {
|
|
1432
|
-
dd = "0".concat(dd);
|
|
1433
|
-
}
|
|
1434
|
-
if (dateFormat === 'MM/DD/YYYY') {
|
|
1435
|
-
text = "".concat(mm, "/").concat(dd, "/").concat(dateObj.getFullYear());
|
|
1436
|
-
} else {
|
|
1437
|
-
text = "".concat(dateObj.getFullYear(), "-").concat(mm, "-").concat(dd);
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
// time
|
|
1441
|
-
var v = dateObj.getHours();
|
|
1442
|
-
if (v < 10) {
|
|
1443
|
-
text += " 0".concat(v);
|
|
1444
|
-
} else {
|
|
1445
|
-
text += " ".concat(v);
|
|
1446
|
-
}
|
|
1447
|
-
v = dateObj.getMinutes();
|
|
1448
|
-
if (v < 10) {
|
|
1449
|
-
text += ":0".concat(v);
|
|
1450
|
-
} else {
|
|
1451
|
-
text += ":".concat(v);
|
|
1452
|
-
}
|
|
1453
|
-
v = dateObj.getSeconds();
|
|
1454
|
-
if (v < 10) {
|
|
1455
|
-
text += ":0".concat(v);
|
|
1456
|
-
} else {
|
|
1457
|
-
text += ":".concat(v);
|
|
1458
|
-
}
|
|
1459
|
-
v = dateObj.getMilliseconds();
|
|
1460
|
-
if (v < 10) {
|
|
1461
|
-
text += ".00".concat(v);
|
|
1462
|
-
} else if (v < 100) {
|
|
1463
|
-
text += ".0".concat(v);
|
|
1464
|
-
} else {
|
|
1465
|
-
text += ".".concat(v);
|
|
1466
|
-
}
|
|
1467
|
-
return text;
|
|
1245
|
+
static getParentId(id) {
|
|
1246
|
+
const p = (id || '').toString().split('.');
|
|
1247
|
+
if (p.length > 1) {
|
|
1248
|
+
p.pop();
|
|
1249
|
+
return p.join('.');
|
|
1250
|
+
}
|
|
1251
|
+
return null;
|
|
1468
1252
|
}
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1253
|
+
static formatDate(dateObj, dateFormat) {
|
|
1254
|
+
// format could be DD.MM.YYYY, YYYY.MM.DD or MM/DD/YYYY
|
|
1255
|
+
if (!dateObj) {
|
|
1256
|
+
return '';
|
|
1257
|
+
}
|
|
1258
|
+
let text;
|
|
1259
|
+
const mm = dateObj.getMonth() + 1;
|
|
1260
|
+
const dd = dateObj.getDate();
|
|
1261
|
+
if (dateFormat === 'MM/DD/YYYY') {
|
|
1262
|
+
text = `${mm < 10 ? `0${mm}` : mm}/${dd < 10 ? `0${dd}` : dd}/${dateObj.getFullYear()}`;
|
|
1263
|
+
}
|
|
1264
|
+
else {
|
|
1265
|
+
text = `${dateObj.getFullYear()}-${mm}-${dd}`;
|
|
1266
|
+
}
|
|
1267
|
+
// time
|
|
1268
|
+
let v = dateObj.getHours();
|
|
1269
|
+
if (v < 10) {
|
|
1270
|
+
text += ` 0${v}`;
|
|
1271
|
+
}
|
|
1272
|
+
else {
|
|
1273
|
+
text += ` ${v}`;
|
|
1274
|
+
}
|
|
1275
|
+
v = dateObj.getMinutes();
|
|
1276
|
+
if (v < 10) {
|
|
1277
|
+
text += `:0${v}`;
|
|
1278
|
+
}
|
|
1279
|
+
else {
|
|
1280
|
+
text += `:${v}`;
|
|
1281
|
+
}
|
|
1282
|
+
v = dateObj.getSeconds();
|
|
1283
|
+
if (v < 10) {
|
|
1284
|
+
text += `:0${v}`;
|
|
1285
|
+
}
|
|
1286
|
+
else {
|
|
1287
|
+
text += `:${v}`;
|
|
1288
|
+
}
|
|
1289
|
+
v = dateObj.getMilliseconds();
|
|
1290
|
+
if (v < 10) {
|
|
1291
|
+
text += `.00${v}`;
|
|
1292
|
+
}
|
|
1293
|
+
else if (v < 100) {
|
|
1294
|
+
text += `.0${v}`;
|
|
1295
|
+
}
|
|
1296
|
+
else {
|
|
1297
|
+
text += `.${v}`;
|
|
1298
|
+
}
|
|
1299
|
+
return text;
|
|
1487
1300
|
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1301
|
+
/*
|
|
1302
|
+
Format seconds to string like 'h:mm:ss' or 'd.hh:mm:ss'
|
|
1303
|
+
*/
|
|
1304
|
+
static formatTime(seconds) {
|
|
1305
|
+
if (seconds) {
|
|
1306
|
+
seconds = Math.round(seconds);
|
|
1307
|
+
const d = Math.floor(seconds / (3600 * 24));
|
|
1308
|
+
const h = Math.floor((seconds % (3600 * 24)) / 3600);
|
|
1309
|
+
const m = Math.floor((seconds % 3600) / 60);
|
|
1310
|
+
const s = seconds % 60;
|
|
1311
|
+
if (d) {
|
|
1312
|
+
return `${d}.${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
|
|
1313
|
+
}
|
|
1314
|
+
if (h) {
|
|
1315
|
+
return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
|
|
1316
|
+
}
|
|
1317
|
+
return `0:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
|
|
1318
|
+
}
|
|
1319
|
+
return '0:00:00';
|
|
1496
1320
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
window.location = url;
|
|
1504
|
-
} else {
|
|
1505
|
-
window.open(url, target || '_blank');
|
|
1506
|
-
}
|
|
1321
|
+
static MDtext2link(text) {
|
|
1322
|
+
const m = text.match(/\d+\.\)\s/);
|
|
1323
|
+
if (m) {
|
|
1324
|
+
text = text.replace(m[0], m[0].replace(/\s/, ' '));
|
|
1325
|
+
}
|
|
1326
|
+
return text.replace(/[^a-zA-Zа-яА-Я0-9]/g, '').trim().replace(/\s/g, '').toLowerCase();
|
|
1507
1327
|
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
if (lines[i].startsWith('# ')) {
|
|
1521
|
-
return lines[i].substring(2).trim();
|
|
1522
|
-
}
|
|
1523
|
-
}
|
|
1524
|
-
return '';
|
|
1525
|
-
}
|
|
1526
|
-
return header.title;
|
|
1328
|
+
/*
|
|
1329
|
+
Open url link in the new target window
|
|
1330
|
+
*/
|
|
1331
|
+
static openLink(url, target) {
|
|
1332
|
+
// replace IPv6 Address with [ipv6]:port
|
|
1333
|
+
url = url.replace(/\/\/([0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*)(:\d+)?\//i, '//[$1]$2/');
|
|
1334
|
+
if (target === 'this') {
|
|
1335
|
+
window.location.href = url;
|
|
1336
|
+
}
|
|
1337
|
+
else {
|
|
1338
|
+
window.open(url, target || '_blank');
|
|
1339
|
+
}
|
|
1527
1340
|
}
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1341
|
+
static MDgetTitle(text) {
|
|
1342
|
+
const result = Utils.MDextractHeader(text);
|
|
1343
|
+
const header = result.header;
|
|
1344
|
+
let body = result.body;
|
|
1345
|
+
if (!header.title) {
|
|
1346
|
+
// remove {docsify-bla}
|
|
1347
|
+
body = body.replace(/{[^}]*}/g, '');
|
|
1348
|
+
body = body.trim();
|
|
1349
|
+
const lines = body.replace(/\r/g, '').split('\n');
|
|
1350
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1351
|
+
if (lines[i].startsWith('# ')) {
|
|
1352
|
+
return lines[i].substring(2).trim();
|
|
1353
|
+
}
|
|
1540
1354
|
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1355
|
+
return '';
|
|
1356
|
+
}
|
|
1357
|
+
return header.title ? header.title.toString() : '';
|
|
1358
|
+
}
|
|
1359
|
+
static MDextractHeader(text) {
|
|
1360
|
+
const attrs = {};
|
|
1361
|
+
if (text.substring(0, 3) === '---') {
|
|
1362
|
+
const pos = text.substring(3).indexOf('\n---');
|
|
1363
|
+
if (pos !== -1) {
|
|
1364
|
+
const _header = text.substring(3, pos + 3);
|
|
1365
|
+
const lines = _header.replace(/\r/g, '').split('\n');
|
|
1366
|
+
lines.forEach(line => {
|
|
1367
|
+
if (!line.trim()) {
|
|
1368
|
+
return;
|
|
1369
|
+
}
|
|
1370
|
+
const pos_ = line.indexOf(':');
|
|
1371
|
+
if (pos_ !== -1) {
|
|
1372
|
+
const attr = line.substring(0, pos_).trim();
|
|
1373
|
+
let val = line.substring(pos_ + 1).trim();
|
|
1374
|
+
val = val.replace(/^['"]|['"]$/g, '');
|
|
1375
|
+
if (val === 'true') {
|
|
1376
|
+
attrs[attr] = true;
|
|
1377
|
+
}
|
|
1378
|
+
else if (val === 'false') {
|
|
1379
|
+
attrs[attr] = false;
|
|
1380
|
+
}
|
|
1381
|
+
else if (parseFloat(val).toString() === val) {
|
|
1382
|
+
attrs[attr] = parseFloat(val);
|
|
1383
|
+
}
|
|
1384
|
+
else {
|
|
1385
|
+
attrs[attr] = val;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
else {
|
|
1389
|
+
attrs[line.trim()] = true;
|
|
1390
|
+
}
|
|
1391
|
+
});
|
|
1392
|
+
text = text.substring(pos + 7);
|
|
1555
1393
|
}
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
}
|
|
1559
|
-
}
|
|
1560
|
-
return {
|
|
1561
|
-
header: attrs,
|
|
1562
|
-
body: text
|
|
1563
|
-
};
|
|
1394
|
+
}
|
|
1395
|
+
return { header: attrs, body: text };
|
|
1564
1396
|
}
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
return text = text.replace(doc, '');
|
|
1572
|
-
});
|
|
1573
|
-
}
|
|
1574
|
-
return text;
|
|
1397
|
+
static MDremoveDocsify(text) {
|
|
1398
|
+
const m = text.match(/{docsify-[^}]*}/g);
|
|
1399
|
+
if (m) {
|
|
1400
|
+
m.forEach(doc => text = text.replace(doc, ''));
|
|
1401
|
+
}
|
|
1402
|
+
return text;
|
|
1575
1403
|
}
|
|
1576
|
-
|
|
1577
1404
|
/**
|
|
1578
1405
|
* Generate the json file on the file for download.
|
|
1579
|
-
* @param
|
|
1580
|
-
* @param
|
|
1406
|
+
* @param fileName file name
|
|
1407
|
+
* @param json file data
|
|
1581
1408
|
* @returns {object} json structure (not stringified)
|
|
1582
1409
|
*/
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
el.click();
|
|
1592
|
-
document.body.removeChild(el);
|
|
1410
|
+
static generateFile(fileName, json) {
|
|
1411
|
+
const el = document.createElement('a');
|
|
1412
|
+
el.setAttribute('href', `data:application/json;charset=utf-8,${encodeURIComponent(JSON.stringify(json, null, 2))}`);
|
|
1413
|
+
el.setAttribute('download', fileName);
|
|
1414
|
+
el.style.display = 'none';
|
|
1415
|
+
document.body.appendChild(el);
|
|
1416
|
+
el.click();
|
|
1417
|
+
document.body.removeChild(el);
|
|
1593
1418
|
}
|
|
1594
|
-
|
|
1595
1419
|
/**
|
|
1596
1420
|
* Convert quality code into text
|
|
1597
1421
|
* @param {number} quality code
|
|
1598
1422
|
* @returns {array<string>} lines that decode quality
|
|
1599
1423
|
*/
|
|
1600
|
-
|
|
1601
|
-
key: "quality2text",
|
|
1602
|
-
value: function quality2text(quality) {
|
|
1603
|
-
// eslint-disable-next-line no-bitwise
|
|
1604
|
-
var custom = quality & 0xFFFF0000;
|
|
1605
|
-
var text = QUALITY_BITS[quality];
|
|
1606
|
-
var result;
|
|
1607
|
-
if (text) {
|
|
1608
|
-
result = [text];
|
|
1609
|
-
// eslint-disable-next-line no-bitwise
|
|
1610
|
-
} else if (quality & 0x01) {
|
|
1611
|
-
// eslint-disable-next-line no-bitwise
|
|
1612
|
-
result = [QUALITY_BITS[0x01], "0x".concat((quality & (0xFFFF & ~1)).toString(16))];
|
|
1424
|
+
static quality2text(quality) {
|
|
1613
1425
|
// eslint-disable-next-line no-bitwise
|
|
1614
|
-
|
|
1615
|
-
//
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1426
|
+
const custom = quality & 0xFFFF0000;
|
|
1427
|
+
// @ts-ignore
|
|
1428
|
+
const text = QUALITY_BITS[quality];
|
|
1429
|
+
let result;
|
|
1430
|
+
if (text) {
|
|
1431
|
+
result = [text];
|
|
1432
|
+
// eslint-disable-next-line no-bitwise
|
|
1433
|
+
}
|
|
1434
|
+
else if (quality & 0x01) {
|
|
1435
|
+
// eslint-disable-next-line no-bitwise
|
|
1436
|
+
result = [QUALITY_BITS[0x01], `0x${(quality & (0xFFFF & ~1)).toString(16)}`];
|
|
1437
|
+
// eslint-disable-next-line no-bitwise
|
|
1438
|
+
}
|
|
1439
|
+
else if (quality & 0x02) {
|
|
1440
|
+
// eslint-disable-next-line no-bitwise
|
|
1441
|
+
result = [QUALITY_BITS[0x02], `0x${(quality & (0xFFFF & ~2)).toString(16)}`];
|
|
1442
|
+
}
|
|
1443
|
+
else {
|
|
1444
|
+
result = [`0x${quality.toString(16)}`];
|
|
1445
|
+
}
|
|
1446
|
+
if (custom) {
|
|
1447
|
+
// eslint-disable-next-line no-bitwise
|
|
1448
|
+
result.push(`0x${(custom >> 16).toString(16).toUpperCase()}`);
|
|
1449
|
+
}
|
|
1450
|
+
return result;
|
|
1625
1451
|
}
|
|
1626
|
-
|
|
1627
1452
|
/**
|
|
1628
1453
|
* Deep copy object
|
|
1629
|
-
* @param {object} object
|
|
1630
|
-
* @returns {object}
|
|
1631
1454
|
*/
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
value: function clone(object) {
|
|
1635
|
-
return JSON.parse(JSON.stringify(object));
|
|
1455
|
+
static clone(object) {
|
|
1456
|
+
return JSON.parse(JSON.stringify(object));
|
|
1636
1457
|
}
|
|
1637
|
-
|
|
1638
1458
|
/**
|
|
1639
1459
|
* Get states of object
|
|
1640
|
-
* @
|
|
1641
|
-
* @returns {object} states as an object in form {"value1": "label1", "value2": "label2"} or null
|
|
1460
|
+
* @returns states as an object in form {"value1": "label1", "value2": "label2"} or null
|
|
1642
1461
|
*/
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
return states;
|
|
1462
|
+
static getStates(obj) {
|
|
1463
|
+
var _a;
|
|
1464
|
+
let states = (_a = obj === null || obj === void 0 ? void 0 : obj.common) === null || _a === void 0 ? void 0 : _a.states;
|
|
1465
|
+
if (states) {
|
|
1466
|
+
if (typeof states === 'string' && states[0] === '{') {
|
|
1467
|
+
try {
|
|
1468
|
+
states = JSON.parse(states);
|
|
1469
|
+
}
|
|
1470
|
+
catch (ex) {
|
|
1471
|
+
console.error(`Cannot parse states: ${states}`);
|
|
1472
|
+
states = null;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
else if (typeof states === 'string') {
|
|
1476
|
+
// if old format val1:text1;val2:text2
|
|
1477
|
+
const parts = states.split(';');
|
|
1478
|
+
states = {};
|
|
1479
|
+
for (let p = 0; p < parts.length; p++) {
|
|
1480
|
+
const s = parts[p].split(':');
|
|
1481
|
+
states[s[0]] = s[1];
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
else if (Array.isArray(states)) {
|
|
1485
|
+
const result = {};
|
|
1486
|
+
if ((obj === null || obj === void 0 ? void 0 : obj.common.type) === 'number') {
|
|
1487
|
+
states.forEach((value, key) => result[key] = value);
|
|
1488
|
+
}
|
|
1489
|
+
else if ((obj === null || obj === void 0 ? void 0 : obj.common.type) === 'string') {
|
|
1490
|
+
states.forEach(value => result[value] = value);
|
|
1491
|
+
}
|
|
1492
|
+
else if ((obj === null || obj === void 0 ? void 0 : obj.common.type) === 'boolean') {
|
|
1493
|
+
result.false = states[0];
|
|
1494
|
+
result.true = states[1];
|
|
1495
|
+
}
|
|
1496
|
+
return result;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
return states ? states : null;
|
|
1682
1500
|
}
|
|
1683
|
-
|
|
1684
1501
|
/**
|
|
1685
1502
|
* Get svg file as text
|
|
1686
|
-
* @param
|
|
1687
|
-
* @returns
|
|
1503
|
+
* @param url URL of SVG file
|
|
1504
|
+
* @returns Promise with "data:image..."
|
|
1688
1505
|
*/
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
resolve(this.result);
|
|
1701
|
-
};
|
|
1702
|
-
reader.readAsDataURL(blob);
|
|
1506
|
+
static async getSvg(url) {
|
|
1507
|
+
const response = await fetch(url);
|
|
1508
|
+
const blob = await response.blob();
|
|
1509
|
+
return await new Promise(resolve => {
|
|
1510
|
+
const reader = new FileReader();
|
|
1511
|
+
// eslint-disable-next-line func-names
|
|
1512
|
+
reader.onload = function () {
|
|
1513
|
+
var _a;
|
|
1514
|
+
resolve(((_a = this.result) === null || _a === void 0 ? void 0 : _a.toString()) || '');
|
|
1515
|
+
};
|
|
1516
|
+
reader.readAsDataURL(blob);
|
|
1703
1517
|
});
|
|
1704
|
-
});
|
|
1705
1518
|
}
|
|
1706
|
-
|
|
1707
1519
|
/**
|
|
1708
1520
|
* Detect file extension by its content
|
|
1709
1521
|
* @param {string} base64 Base64 encoded binary file
|
|
1710
1522
|
* @returns {string} Detected extension, like 'jpg'
|
|
1711
1523
|
*/
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
return base64.startsWith(s);
|
|
1717
|
-
});
|
|
1718
|
-
return signature ? SIGNATURES[signature] : null;
|
|
1524
|
+
static detectMimeType(base64) {
|
|
1525
|
+
const signature = Object.keys(SIGNATURES).find(s => base64.startsWith(s));
|
|
1526
|
+
// @ts-ignore
|
|
1527
|
+
return signature ? SIGNATURES[signature] : null;
|
|
1719
1528
|
}
|
|
1720
|
-
|
|
1721
1529
|
/**
|
|
1722
1530
|
* Check if configured repository is the stable repository
|
|
1723
1531
|
*
|
|
1724
|
-
* @param
|
|
1725
|
-
* @return {boolean}
|
|
1532
|
+
* @param activeRepo current configured repository or multi repository
|
|
1726
1533
|
*/
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1534
|
+
static isStableRepository(activeRepo) {
|
|
1535
|
+
return !!((typeof activeRepo === 'string' &&
|
|
1536
|
+
activeRepo.toLowerCase().startsWith('stable'))
|
|
1537
|
+
||
|
|
1538
|
+
(activeRepo &&
|
|
1539
|
+
typeof activeRepo !== 'string' &&
|
|
1540
|
+
activeRepo.find(r => r.toLowerCase().startsWith('stable'))));
|
|
1733
1541
|
}
|
|
1734
|
-
|
|
1735
1542
|
/**
|
|
1736
|
-
* Check if given string is an integer
|
|
1543
|
+
* Check if a given string is an integer
|
|
1737
1544
|
*
|
|
1738
|
-
* @param
|
|
1739
|
-
* @return {boolean}
|
|
1545
|
+
* @param str string to check
|
|
1740
1546
|
*/
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
value: function isStringInteger(str) {
|
|
1744
|
-
return parseInt(str).toString() === str;
|
|
1547
|
+
static isStringInteger(str) {
|
|
1548
|
+
return parseInt(str).toString() === str;
|
|
1745
1549
|
}
|
|
1746
|
-
|
|
1747
1550
|
/**
|
|
1748
1551
|
* Check if the date is valid
|
|
1749
1552
|
*
|
|
1750
1553
|
* @param {Date} date
|
|
1751
1554
|
* @return {boolean}
|
|
1752
1555
|
*/
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
value: function isValidDate(date) {
|
|
1756
|
-
return date instanceof Date && !isNaN(date);
|
|
1556
|
+
static isValidDate(date) {
|
|
1557
|
+
return date instanceof Date && !isNaN(date.getTime());
|
|
1757
1558
|
}
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
(0, _defineProperty2["default"])(Utils, "FORBIDDEN_CHARS", /(?:[\0-\x1F"'\*,;<>\?\[-\]`\x7F-\xB4\xB6-\xBF\xD7\xF7\u01BB\u01C0-\u01C3\u01C5\u01C8\u01CB\u01F2\u0294\u02B0-\u036F\u0374\u0375\u0378-\u037A\u037E\u0380-\u0385\u0387\u038B\u038D\u03A2\u03F6\u0482-\u0489\u0530\u0557-\u055F\u0589-\u065F\u066A-\u06EF\u06FA-\u07BF\u07CA-\u0965\u0970-\u09E5\u09F0-\u0A65\u0A70-\u0AE5\u0AF0-\u0B65\u0B70-\u0BE5\u0BF0-\u0C65\u0C70-\u0CE5\u0CF0-\u0D65\u0D70-\u0DE5\u0DF0-\u0E4F\u0E5A-\u0ECF\u0EDA-\u0F1F\u0F2A-\u103F\u104A-\u108F\u109A-\u109F\u10C6\u10C8-\u10CC\u10CE\u10CF\u10FB\u10FC\u1100-\u139F\u13F6\u13F7\u13FE-\u17DF\u17EA-\u180F\u181A-\u1945\u1950-\u19CF\u19DA-\u1A7F\u1A8A-\u1A8F\u1A9A-\u1B4F\u1B5A-\u1BAF\u1BBA-\u1C3F\u1C4A-\u1C4F\u1C5A-\u1C7F\u1C89-\u1C8F\u1CBB\u1CBC\u1CC0-\u1CFF\u1D2C-\u1D6A\u1D78\u1D9B-\u1DFF\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FB5\u1FBC\u1FBD\u1FBF-\u1FC1\u1FC5\u1FCC-\u1FCF\u1FD4\u1FD5\u1FDC-\u1FDF\u1FED-\u1FF1\u1FF5\u1FFC-\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u2135-\u2138\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F-\u2182\u2185-\u2BFF\u2C7C\u2C7D\u2CE5-\u2CEA\u2CEF-\u2CF1\u2CF4-\u2CFF\u2D26\u2D28-\u2D2C\u2D2E-\uA61F\uA62A-\uA63F\uA66E-\uA67F\uA69C-\uA721\uA770\uA788-\uA78A\uA78F\uA7CB-\uA7CF\uA7D2\uA7D4\uA7DA-\uA7F4\uA7F7-\uA7F9\uA7FB-\uA8CF\uA8DA-\uA8FF\uA90A-\uA9CF\uA9DA-\uA9EF\uA9FA-\uAA4F\uAA5A-\uAB2F\uAB5B-\uAB5F\uAB69-\uAB6F\uABC0-\uABEF\uABFA-\uD7FF\uE000-\uFAFF\uFB07-\uFB12\uFB18-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF40\uFF5B-\uFFFF]|[\uD800\uD802\uD808-\uD819\uD81C-\uD834\uD836\uD83B-\uD83D\uD83F-\uDBFF][\uDC00-\uDFFF]|\uD801[\uDC50-\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDD6F\uDD7B\uDD8B\uDD93\uDD96\uDDA2\uDDB2\uDDBA\uDDBD-\uDFFF]|\uD803[\uDC00-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDD2F\uDD3A-\uDFFF]|\uD804[\uDC00-\uDC65\uDC70-\uDCEF\uDCFA-\uDD35\uDD40-\uDDCF\uDDDA-\uDEEF\uDEFA-\uDFFF]|\uD805[\uDC00-\uDC4F\uDC5A-\uDCCF\uDCDA-\uDE4F\uDE5A-\uDEBF\uDECA-\uDF2F\uDF3A-\uDFFF]|\uD806[\uDC00-\uDC9F\uDCEA-\uDD4F\uDD5A-\uDFFF]|\uD807[\uDC00-\uDC4F\uDC5A-\uDD4F\uDD5A-\uDD9F\uDDAA-\uDF4F\uDF5A-\uDFFF]|\uD81A[\uDC00-\uDE5F\uDE6A-\uDEBF\uDECA-\uDF4F\uDF5A-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE80-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3\uDFCC\uDFCD]|\uD837[\uDC00-\uDEFF\uDF0A\uDF1F-\uDF24\uDF2B-\uDFFF]|\uD838[\uDC00-\uDD3F\uDD4A-\uDEEF\uDEFA-\uDFFF]|\uD839[\uDC00-\uDCEF\uDCFA-\uDFFF]|\uD83A[\uDC00-\uDCFF\uDD44-\uDD4F\uDD5A-\uDFFF]|\uD83E[\uDC00-\uDFEF\uDFFA-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+/g);
|
|
1765
|
-
var _default = exports["default"] = Utils;
|
|
1766
|
-
//# sourceMappingURL=Utils.js.map
|
|
1559
|
+
}
|
|
1560
|
+
Utils.namespace = NAMESPACE;
|
|
1561
|
+
Utils.INSTANCES = 'instances';
|
|
1562
|
+
Utils.dateFormat = ['DD', 'MM'];
|
|
1563
|
+
Utils.FORBIDDEN_CHARS = /[^._\-/ :!#$%&()+=@^{}|~\p{Ll}\p{Lu}\p{Nd}]+/gu;
|
|
1564
|
+
exports.default = Utils;
|