automoby-kit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +172 -0
- package/dist/index.cjs.js +3022 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.esm.js +3006 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/types/components/Accordion/Accordion.d.ts +25 -0
- package/dist/types/components/Accordion/Accordion.stories.d.ts +174 -0
- package/dist/types/components/Backdrop/Backdrop.d.ts +20 -0
- package/dist/types/components/Backdrop/Backdrop.stories.d.ts +9 -0
- package/dist/types/components/Breadcrumb/Breadcrumb.d.ts +13 -0
- package/dist/types/components/Breadcrumb/Breadcrumb.stories.d.ts +176 -0
- package/dist/types/components/Button/Button.d.ts +13 -0
- package/dist/types/components/Button/Button.stories.d.ts +100 -0
- package/dist/types/components/Chips/Chips.d.ts +37 -0
- package/dist/types/components/Chips/Chips.stories.d.ts +90 -0
- package/dist/types/components/Divider/Divider.d.ts +25 -0
- package/dist/types/components/Divider/Divider.stories.d.ts +88 -0
- package/dist/types/components/Drawer/Drawer.d.ts +12 -0
- package/dist/types/components/Drawer/Drawer.stories.d.ts +115 -0
- package/dist/types/components/Input/Input.d.ts +16 -0
- package/dist/types/components/Input/Input.stories.d.ts +130 -0
- package/dist/types/components/Menu/Menu.d.ts +39 -0
- package/dist/types/components/Menu/Menu.stories.d.ts +89 -0
- package/dist/types/components/Pagination/Pagination.d.ts +8 -0
- package/dist/types/components/Pagination/Pagination.stories.d.ts +61 -0
- package/dist/types/components/ProtectedComponent.d.ts +5 -0
- package/dist/types/components/RadioGroup/RadioGroup.d.ts +55 -0
- package/dist/types/components/RadioGroup/RadioGroup.stories.d.ts +86 -0
- package/dist/types/components/Tabs/Tabs.d.ts +43 -0
- package/dist/types/components/Tabs/Tabs.stories.d.ts +66 -0
- package/dist/types/components/Typography/Typography.d.ts +9 -0
- package/dist/types/components/Typography/Typography.stories.d.ts +57 -0
- package/dist/types/contexts/MobileContext.d.ts +13 -0
- package/dist/types/contexts/index.d.ts +2 -0
- package/dist/types/index.d.ts +33 -0
- package/dist/types/licensing/LicenseManager.d.ts +41 -0
- package/dist/types/licensing/index.d.ts +30 -0
- package/dist/types/utils/cn.d.ts +2 -0
- package/package.json +90 -0
|
@@ -0,0 +1,3022 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
var jsxRuntime = {exports: {}};
|
|
6
|
+
|
|
7
|
+
var reactJsxRuntime_production = {};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @license React
|
|
11
|
+
* react-jsx-runtime.production.js
|
|
12
|
+
*
|
|
13
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14
|
+
*
|
|
15
|
+
* This source code is licensed under the MIT license found in the
|
|
16
|
+
* LICENSE file in the root directory of this source tree.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
var hasRequiredReactJsxRuntime_production;
|
|
20
|
+
|
|
21
|
+
function requireReactJsxRuntime_production () {
|
|
22
|
+
if (hasRequiredReactJsxRuntime_production) return reactJsxRuntime_production;
|
|
23
|
+
hasRequiredReactJsxRuntime_production = 1;
|
|
24
|
+
var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),
|
|
25
|
+
REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
|
|
26
|
+
function jsxProd(type, config, maybeKey) {
|
|
27
|
+
var key = null;
|
|
28
|
+
void 0 !== maybeKey && (key = "" + maybeKey);
|
|
29
|
+
void 0 !== config.key && (key = "" + config.key);
|
|
30
|
+
if ("key" in config) {
|
|
31
|
+
maybeKey = {};
|
|
32
|
+
for (var propName in config)
|
|
33
|
+
"key" !== propName && (maybeKey[propName] = config[propName]);
|
|
34
|
+
} else maybeKey = config;
|
|
35
|
+
config = maybeKey.ref;
|
|
36
|
+
return {
|
|
37
|
+
$$typeof: REACT_ELEMENT_TYPE,
|
|
38
|
+
type: type,
|
|
39
|
+
key: key,
|
|
40
|
+
ref: void 0 !== config ? config : null,
|
|
41
|
+
props: maybeKey
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
reactJsxRuntime_production.Fragment = REACT_FRAGMENT_TYPE;
|
|
45
|
+
reactJsxRuntime_production.jsx = jsxProd;
|
|
46
|
+
reactJsxRuntime_production.jsxs = jsxProd;
|
|
47
|
+
return reactJsxRuntime_production;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var reactJsxRuntime_development = {};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @license React
|
|
54
|
+
* react-jsx-runtime.development.js
|
|
55
|
+
*
|
|
56
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
57
|
+
*
|
|
58
|
+
* This source code is licensed under the MIT license found in the
|
|
59
|
+
* LICENSE file in the root directory of this source tree.
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
var hasRequiredReactJsxRuntime_development;
|
|
63
|
+
|
|
64
|
+
function requireReactJsxRuntime_development () {
|
|
65
|
+
if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development;
|
|
66
|
+
hasRequiredReactJsxRuntime_development = 1;
|
|
67
|
+
"production" !== process.env.NODE_ENV &&
|
|
68
|
+
(function () {
|
|
69
|
+
function getComponentNameFromType(type) {
|
|
70
|
+
if (null == type) return null;
|
|
71
|
+
if ("function" === typeof type)
|
|
72
|
+
return type.$$typeof === REACT_CLIENT_REFERENCE
|
|
73
|
+
? null
|
|
74
|
+
: type.displayName || type.name || null;
|
|
75
|
+
if ("string" === typeof type) return type;
|
|
76
|
+
switch (type) {
|
|
77
|
+
case REACT_FRAGMENT_TYPE:
|
|
78
|
+
return "Fragment";
|
|
79
|
+
case REACT_PROFILER_TYPE:
|
|
80
|
+
return "Profiler";
|
|
81
|
+
case REACT_STRICT_MODE_TYPE:
|
|
82
|
+
return "StrictMode";
|
|
83
|
+
case REACT_SUSPENSE_TYPE:
|
|
84
|
+
return "Suspense";
|
|
85
|
+
case REACT_SUSPENSE_LIST_TYPE:
|
|
86
|
+
return "SuspenseList";
|
|
87
|
+
case REACT_ACTIVITY_TYPE:
|
|
88
|
+
return "Activity";
|
|
89
|
+
}
|
|
90
|
+
if ("object" === typeof type)
|
|
91
|
+
switch (
|
|
92
|
+
("number" === typeof type.tag &&
|
|
93
|
+
console.error(
|
|
94
|
+
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
95
|
+
),
|
|
96
|
+
type.$$typeof)
|
|
97
|
+
) {
|
|
98
|
+
case REACT_PORTAL_TYPE:
|
|
99
|
+
return "Portal";
|
|
100
|
+
case REACT_CONTEXT_TYPE:
|
|
101
|
+
return (type.displayName || "Context") + ".Provider";
|
|
102
|
+
case REACT_CONSUMER_TYPE:
|
|
103
|
+
return (type._context.displayName || "Context") + ".Consumer";
|
|
104
|
+
case REACT_FORWARD_REF_TYPE:
|
|
105
|
+
var innerType = type.render;
|
|
106
|
+
type = type.displayName;
|
|
107
|
+
type ||
|
|
108
|
+
((type = innerType.displayName || innerType.name || ""),
|
|
109
|
+
(type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef"));
|
|
110
|
+
return type;
|
|
111
|
+
case REACT_MEMO_TYPE:
|
|
112
|
+
return (
|
|
113
|
+
(innerType = type.displayName || null),
|
|
114
|
+
null !== innerType
|
|
115
|
+
? innerType
|
|
116
|
+
: getComponentNameFromType(type.type) || "Memo"
|
|
117
|
+
);
|
|
118
|
+
case REACT_LAZY_TYPE:
|
|
119
|
+
innerType = type._payload;
|
|
120
|
+
type = type._init;
|
|
121
|
+
try {
|
|
122
|
+
return getComponentNameFromType(type(innerType));
|
|
123
|
+
} catch (x) {}
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
function testStringCoercion(value) {
|
|
128
|
+
return "" + value;
|
|
129
|
+
}
|
|
130
|
+
function checkKeyStringCoercion(value) {
|
|
131
|
+
try {
|
|
132
|
+
testStringCoercion(value);
|
|
133
|
+
var JSCompiler_inline_result = !1;
|
|
134
|
+
} catch (e) {
|
|
135
|
+
JSCompiler_inline_result = true;
|
|
136
|
+
}
|
|
137
|
+
if (JSCompiler_inline_result) {
|
|
138
|
+
JSCompiler_inline_result = console;
|
|
139
|
+
var JSCompiler_temp_const = JSCompiler_inline_result.error;
|
|
140
|
+
var JSCompiler_inline_result$jscomp$0 =
|
|
141
|
+
("function" === typeof Symbol &&
|
|
142
|
+
Symbol.toStringTag &&
|
|
143
|
+
value[Symbol.toStringTag]) ||
|
|
144
|
+
value.constructor.name ||
|
|
145
|
+
"Object";
|
|
146
|
+
JSCompiler_temp_const.call(
|
|
147
|
+
JSCompiler_inline_result,
|
|
148
|
+
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
149
|
+
JSCompiler_inline_result$jscomp$0
|
|
150
|
+
);
|
|
151
|
+
return testStringCoercion(value);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function getTaskName(type) {
|
|
155
|
+
if (type === REACT_FRAGMENT_TYPE) return "<>";
|
|
156
|
+
if (
|
|
157
|
+
"object" === typeof type &&
|
|
158
|
+
null !== type &&
|
|
159
|
+
type.$$typeof === REACT_LAZY_TYPE
|
|
160
|
+
)
|
|
161
|
+
return "<...>";
|
|
162
|
+
try {
|
|
163
|
+
var name = getComponentNameFromType(type);
|
|
164
|
+
return name ? "<" + name + ">" : "<...>";
|
|
165
|
+
} catch (x) {
|
|
166
|
+
return "<...>";
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function getOwner() {
|
|
170
|
+
var dispatcher = ReactSharedInternals.A;
|
|
171
|
+
return null === dispatcher ? null : dispatcher.getOwner();
|
|
172
|
+
}
|
|
173
|
+
function UnknownOwner() {
|
|
174
|
+
return Error("react-stack-top-frame");
|
|
175
|
+
}
|
|
176
|
+
function hasValidKey(config) {
|
|
177
|
+
if (hasOwnProperty.call(config, "key")) {
|
|
178
|
+
var getter = Object.getOwnPropertyDescriptor(config, "key").get;
|
|
179
|
+
if (getter && getter.isReactWarning) return false;
|
|
180
|
+
}
|
|
181
|
+
return void 0 !== config.key;
|
|
182
|
+
}
|
|
183
|
+
function defineKeyPropWarningGetter(props, displayName) {
|
|
184
|
+
function warnAboutAccessingKey() {
|
|
185
|
+
specialPropKeyWarningShown ||
|
|
186
|
+
((specialPropKeyWarningShown = true),
|
|
187
|
+
console.error(
|
|
188
|
+
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
|
|
189
|
+
displayName
|
|
190
|
+
));
|
|
191
|
+
}
|
|
192
|
+
warnAboutAccessingKey.isReactWarning = true;
|
|
193
|
+
Object.defineProperty(props, "key", {
|
|
194
|
+
get: warnAboutAccessingKey,
|
|
195
|
+
configurable: true
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
function elementRefGetterWithDeprecationWarning() {
|
|
199
|
+
var componentName = getComponentNameFromType(this.type);
|
|
200
|
+
didWarnAboutElementRef[componentName] ||
|
|
201
|
+
((didWarnAboutElementRef[componentName] = true),
|
|
202
|
+
console.error(
|
|
203
|
+
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
|
|
204
|
+
));
|
|
205
|
+
componentName = this.props.ref;
|
|
206
|
+
return void 0 !== componentName ? componentName : null;
|
|
207
|
+
}
|
|
208
|
+
function ReactElement(
|
|
209
|
+
type,
|
|
210
|
+
key,
|
|
211
|
+
self,
|
|
212
|
+
source,
|
|
213
|
+
owner,
|
|
214
|
+
props,
|
|
215
|
+
debugStack,
|
|
216
|
+
debugTask
|
|
217
|
+
) {
|
|
218
|
+
self = props.ref;
|
|
219
|
+
type = {
|
|
220
|
+
$$typeof: REACT_ELEMENT_TYPE,
|
|
221
|
+
type: type,
|
|
222
|
+
key: key,
|
|
223
|
+
props: props,
|
|
224
|
+
_owner: owner
|
|
225
|
+
};
|
|
226
|
+
null !== (void 0 !== self ? self : null)
|
|
227
|
+
? Object.defineProperty(type, "ref", {
|
|
228
|
+
enumerable: false,
|
|
229
|
+
get: elementRefGetterWithDeprecationWarning
|
|
230
|
+
})
|
|
231
|
+
: Object.defineProperty(type, "ref", { enumerable: false, value: null });
|
|
232
|
+
type._store = {};
|
|
233
|
+
Object.defineProperty(type._store, "validated", {
|
|
234
|
+
configurable: false,
|
|
235
|
+
enumerable: false,
|
|
236
|
+
writable: true,
|
|
237
|
+
value: 0
|
|
238
|
+
});
|
|
239
|
+
Object.defineProperty(type, "_debugInfo", {
|
|
240
|
+
configurable: false,
|
|
241
|
+
enumerable: false,
|
|
242
|
+
writable: true,
|
|
243
|
+
value: null
|
|
244
|
+
});
|
|
245
|
+
Object.defineProperty(type, "_debugStack", {
|
|
246
|
+
configurable: false,
|
|
247
|
+
enumerable: false,
|
|
248
|
+
writable: true,
|
|
249
|
+
value: debugStack
|
|
250
|
+
});
|
|
251
|
+
Object.defineProperty(type, "_debugTask", {
|
|
252
|
+
configurable: false,
|
|
253
|
+
enumerable: false,
|
|
254
|
+
writable: true,
|
|
255
|
+
value: debugTask
|
|
256
|
+
});
|
|
257
|
+
Object.freeze && (Object.freeze(type.props), Object.freeze(type));
|
|
258
|
+
return type;
|
|
259
|
+
}
|
|
260
|
+
function jsxDEVImpl(
|
|
261
|
+
type,
|
|
262
|
+
config,
|
|
263
|
+
maybeKey,
|
|
264
|
+
isStaticChildren,
|
|
265
|
+
source,
|
|
266
|
+
self,
|
|
267
|
+
debugStack,
|
|
268
|
+
debugTask
|
|
269
|
+
) {
|
|
270
|
+
var children = config.children;
|
|
271
|
+
if (void 0 !== children)
|
|
272
|
+
if (isStaticChildren)
|
|
273
|
+
if (isArrayImpl(children)) {
|
|
274
|
+
for (
|
|
275
|
+
isStaticChildren = 0;
|
|
276
|
+
isStaticChildren < children.length;
|
|
277
|
+
isStaticChildren++
|
|
278
|
+
)
|
|
279
|
+
validateChildKeys(children[isStaticChildren]);
|
|
280
|
+
Object.freeze && Object.freeze(children);
|
|
281
|
+
} else
|
|
282
|
+
console.error(
|
|
283
|
+
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
|
|
284
|
+
);
|
|
285
|
+
else validateChildKeys(children);
|
|
286
|
+
if (hasOwnProperty.call(config, "key")) {
|
|
287
|
+
children = getComponentNameFromType(type);
|
|
288
|
+
var keys = Object.keys(config).filter(function (k) {
|
|
289
|
+
return "key" !== k;
|
|
290
|
+
});
|
|
291
|
+
isStaticChildren =
|
|
292
|
+
0 < keys.length
|
|
293
|
+
? "{key: someKey, " + keys.join(": ..., ") + ": ...}"
|
|
294
|
+
: "{key: someKey}";
|
|
295
|
+
didWarnAboutKeySpread[children + isStaticChildren] ||
|
|
296
|
+
((keys =
|
|
297
|
+
0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}"),
|
|
298
|
+
console.error(
|
|
299
|
+
'A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',
|
|
300
|
+
isStaticChildren,
|
|
301
|
+
children,
|
|
302
|
+
keys,
|
|
303
|
+
children
|
|
304
|
+
),
|
|
305
|
+
(didWarnAboutKeySpread[children + isStaticChildren] = true));
|
|
306
|
+
}
|
|
307
|
+
children = null;
|
|
308
|
+
void 0 !== maybeKey &&
|
|
309
|
+
(checkKeyStringCoercion(maybeKey), (children = "" + maybeKey));
|
|
310
|
+
hasValidKey(config) &&
|
|
311
|
+
(checkKeyStringCoercion(config.key), (children = "" + config.key));
|
|
312
|
+
if ("key" in config) {
|
|
313
|
+
maybeKey = {};
|
|
314
|
+
for (var propName in config)
|
|
315
|
+
"key" !== propName && (maybeKey[propName] = config[propName]);
|
|
316
|
+
} else maybeKey = config;
|
|
317
|
+
children &&
|
|
318
|
+
defineKeyPropWarningGetter(
|
|
319
|
+
maybeKey,
|
|
320
|
+
"function" === typeof type
|
|
321
|
+
? type.displayName || type.name || "Unknown"
|
|
322
|
+
: type
|
|
323
|
+
);
|
|
324
|
+
return ReactElement(
|
|
325
|
+
type,
|
|
326
|
+
children,
|
|
327
|
+
self,
|
|
328
|
+
source,
|
|
329
|
+
getOwner(),
|
|
330
|
+
maybeKey,
|
|
331
|
+
debugStack,
|
|
332
|
+
debugTask
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
function validateChildKeys(node) {
|
|
336
|
+
"object" === typeof node &&
|
|
337
|
+
null !== node &&
|
|
338
|
+
node.$$typeof === REACT_ELEMENT_TYPE &&
|
|
339
|
+
node._store &&
|
|
340
|
+
(node._store.validated = 1);
|
|
341
|
+
}
|
|
342
|
+
var React$1 = React,
|
|
343
|
+
REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),
|
|
344
|
+
REACT_PORTAL_TYPE = Symbol.for("react.portal"),
|
|
345
|
+
REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"),
|
|
346
|
+
REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"),
|
|
347
|
+
REACT_PROFILER_TYPE = Symbol.for("react.profiler");
|
|
348
|
+
var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"),
|
|
349
|
+
REACT_CONTEXT_TYPE = Symbol.for("react.context"),
|
|
350
|
+
REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"),
|
|
351
|
+
REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"),
|
|
352
|
+
REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"),
|
|
353
|
+
REACT_MEMO_TYPE = Symbol.for("react.memo"),
|
|
354
|
+
REACT_LAZY_TYPE = Symbol.for("react.lazy"),
|
|
355
|
+
REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),
|
|
356
|
+
REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"),
|
|
357
|
+
ReactSharedInternals =
|
|
358
|
+
React$1.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
|
|
359
|
+
hasOwnProperty = Object.prototype.hasOwnProperty,
|
|
360
|
+
isArrayImpl = Array.isArray,
|
|
361
|
+
createTask = console.createTask
|
|
362
|
+
? console.createTask
|
|
363
|
+
: function () {
|
|
364
|
+
return null;
|
|
365
|
+
};
|
|
366
|
+
React$1 = {
|
|
367
|
+
"react-stack-bottom-frame": function (callStackForError) {
|
|
368
|
+
return callStackForError();
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
var specialPropKeyWarningShown;
|
|
372
|
+
var didWarnAboutElementRef = {};
|
|
373
|
+
var unknownOwnerDebugStack = React$1["react-stack-bottom-frame"].bind(
|
|
374
|
+
React$1,
|
|
375
|
+
UnknownOwner
|
|
376
|
+
)();
|
|
377
|
+
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
|
|
378
|
+
var didWarnAboutKeySpread = {};
|
|
379
|
+
reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE;
|
|
380
|
+
reactJsxRuntime_development.jsx = function (type, config, maybeKey, source, self) {
|
|
381
|
+
var trackActualOwner =
|
|
382
|
+
1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
|
|
383
|
+
return jsxDEVImpl(
|
|
384
|
+
type,
|
|
385
|
+
config,
|
|
386
|
+
maybeKey,
|
|
387
|
+
false,
|
|
388
|
+
source,
|
|
389
|
+
self,
|
|
390
|
+
trackActualOwner
|
|
391
|
+
? Error("react-stack-top-frame")
|
|
392
|
+
: unknownOwnerDebugStack,
|
|
393
|
+
trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
|
|
394
|
+
);
|
|
395
|
+
};
|
|
396
|
+
reactJsxRuntime_development.jsxs = function (type, config, maybeKey, source, self) {
|
|
397
|
+
var trackActualOwner =
|
|
398
|
+
1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
|
|
399
|
+
return jsxDEVImpl(
|
|
400
|
+
type,
|
|
401
|
+
config,
|
|
402
|
+
maybeKey,
|
|
403
|
+
true,
|
|
404
|
+
source,
|
|
405
|
+
self,
|
|
406
|
+
trackActualOwner
|
|
407
|
+
? Error("react-stack-top-frame")
|
|
408
|
+
: unknownOwnerDebugStack,
|
|
409
|
+
trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
|
|
410
|
+
);
|
|
411
|
+
};
|
|
412
|
+
})();
|
|
413
|
+
return reactJsxRuntime_development;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
var hasRequiredJsxRuntime;
|
|
417
|
+
|
|
418
|
+
function requireJsxRuntime () {
|
|
419
|
+
if (hasRequiredJsxRuntime) return jsxRuntime.exports;
|
|
420
|
+
hasRequiredJsxRuntime = 1;
|
|
421
|
+
|
|
422
|
+
if (process.env.NODE_ENV === 'production') {
|
|
423
|
+
jsxRuntime.exports = requireReactJsxRuntime_production();
|
|
424
|
+
} else {
|
|
425
|
+
jsxRuntime.exports = requireReactJsxRuntime_development();
|
|
426
|
+
}
|
|
427
|
+
return jsxRuntime.exports;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
var jsxRuntimeExports = requireJsxRuntime();
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* License Manager for Automoby Kit
|
|
434
|
+
* Handles runtime key validation and component access control
|
|
435
|
+
*/
|
|
436
|
+
class LicenseManager {
|
|
437
|
+
static instance;
|
|
438
|
+
isInitialized = false;
|
|
439
|
+
isValid = false;
|
|
440
|
+
licenseKey = null;
|
|
441
|
+
// Valid license keys - in production, these would be validated against your backend
|
|
442
|
+
validKeys = ['automoby-kit-war-key-2025'];
|
|
443
|
+
constructor() {
|
|
444
|
+
// Private constructor for singleton pattern
|
|
445
|
+
}
|
|
446
|
+
static getInstance() {
|
|
447
|
+
if (!LicenseManager.instance) {
|
|
448
|
+
LicenseManager.instance = new LicenseManager();
|
|
449
|
+
}
|
|
450
|
+
return LicenseManager.instance;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Initialize the license with provided configuration
|
|
454
|
+
*/
|
|
455
|
+
initialize(config) {
|
|
456
|
+
try {
|
|
457
|
+
this.licenseKey = config.key;
|
|
458
|
+
// Validate the license key
|
|
459
|
+
this.isValid = this.validateLicense(config.key);
|
|
460
|
+
this.isInitialized = true;
|
|
461
|
+
if (this.isValid) {
|
|
462
|
+
console.log('✅ Automoby Kit initialized successfully');
|
|
463
|
+
return true;
|
|
464
|
+
}
|
|
465
|
+
console.error('❌ Invalid license key provided for Automoby Kit');
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
console.error('❌ Failed to initialize Automoby Kit:', error);
|
|
470
|
+
this.isValid = false;
|
|
471
|
+
this.isInitialized = true;
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Validate license key (in production, this would call your backend)
|
|
477
|
+
*/
|
|
478
|
+
validateLicense(key) {
|
|
479
|
+
// Basic validation - empty key is invalid
|
|
480
|
+
if (!key || key.trim() === '') {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
// For demo purposes, we're using hardcoded keys
|
|
484
|
+
// In production, you would validate against your backend API
|
|
485
|
+
return this.validKeys.includes(key);
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Check if the license is valid and components can be used
|
|
489
|
+
*/
|
|
490
|
+
canUseComponents() {
|
|
491
|
+
if (!this.isInitialized) {
|
|
492
|
+
console.error('❌ Automoby Kit not initialized. Please call initializeAutomobiKit() with your license key.');
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
if (!this.isValid) {
|
|
496
|
+
console.error('❌ Invalid license key. Please contact support or provide a valid license key.');
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
499
|
+
return true;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Get current license status
|
|
503
|
+
*/
|
|
504
|
+
getLicenseStatus() {
|
|
505
|
+
return {
|
|
506
|
+
initialized: this.isInitialized,
|
|
507
|
+
valid: this.isValid,
|
|
508
|
+
key: this.licenseKey ? `${this.licenseKey.substring(0, 8)}...` : null,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Reset license state (useful for testing)
|
|
513
|
+
*/
|
|
514
|
+
reset() {
|
|
515
|
+
this.isInitialized = false;
|
|
516
|
+
this.isValid = false;
|
|
517
|
+
this.licenseKey = null;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Initialize Automoby Kit with your license key
|
|
523
|
+
* This function must be called before using any components
|
|
524
|
+
*
|
|
525
|
+
* @param config - License configuration
|
|
526
|
+
* @returns boolean indicating success
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```typescript
|
|
530
|
+
* import { initializeAutomobiKit } from 'automoby-kit';
|
|
531
|
+
*
|
|
532
|
+
* // Initialize with your license key
|
|
533
|
+
* const success = initializeAutomobiKit({
|
|
534
|
+
* key: 'your-license-key-here',
|
|
535
|
+
* domain: 'yourdomain.com', // optional
|
|
536
|
+
* environment: 'production' // optional
|
|
537
|
+
* });
|
|
538
|
+
*
|
|
539
|
+
* if (success) {
|
|
540
|
+
* // Now you can use components
|
|
541
|
+
* }
|
|
542
|
+
* ```
|
|
543
|
+
*/
|
|
544
|
+
function initializeAutomobiKit(config) {
|
|
545
|
+
const licenseManager = LicenseManager.getInstance();
|
|
546
|
+
return licenseManager.initialize(config);
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Check if components can be used
|
|
550
|
+
*/
|
|
551
|
+
function canUseComponents() {
|
|
552
|
+
const licenseManager = LicenseManager.getInstance();
|
|
553
|
+
return licenseManager.canUseComponents();
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Higher-order component that protects components with license validation
|
|
558
|
+
*/
|
|
559
|
+
function withLicenseProtection(Component, componentName) {
|
|
560
|
+
const ProtectedComponent = React.forwardRef((props, ref) => {
|
|
561
|
+
if (!canUseComponents()) {
|
|
562
|
+
// Return a placeholder component with error styling
|
|
563
|
+
return (jsxRuntimeExports.jsxs("div", { style: {
|
|
564
|
+
padding: '16px',
|
|
565
|
+
border: '2px dashed #ef4444',
|
|
566
|
+
borderRadius: '8px',
|
|
567
|
+
backgroundColor: '#fef2f2',
|
|
568
|
+
color: '#dc2626',
|
|
569
|
+
textAlign: 'center',
|
|
570
|
+
fontFamily: 'system-ui, sans-serif',
|
|
571
|
+
fontSize: '14px',
|
|
572
|
+
maxWidth: '400px',
|
|
573
|
+
margin: '16px auto',
|
|
574
|
+
}, children: [jsxRuntimeExports.jsx("div", { style: { fontWeight: 'bold', marginBottom: '8px' }, children: "\uD83D\uDD12 License Required" }), jsxRuntimeExports.jsxs("div", { style: { marginBottom: '8px' }, children: ["Component \"", componentName, "\" requires a valid license key."] }), jsxRuntimeExports.jsx("div", { style: { fontSize: '12px', opacity: 0.8 }, children: "Please initialize Automoby Kit with your license key before using components." })] }));
|
|
575
|
+
}
|
|
576
|
+
// If license is valid, render the actual component
|
|
577
|
+
// Use type assertion to handle the generic component props properly
|
|
578
|
+
return jsxRuntimeExports.jsx(Component, { ...props, ref: ref });
|
|
579
|
+
});
|
|
580
|
+
ProtectedComponent.displayName = `Protected(${componentName})`;
|
|
581
|
+
return ProtectedComponent;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
|
|
585
|
+
|
|
586
|
+
function cn(...inputs) {
|
|
587
|
+
return clsx(inputs);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
const variantClasses$1 = {
|
|
591
|
+
// Headings with Fat weight (900)
|
|
592
|
+
h1: 'text-[36px] font-[var(--font-weight-fat)]',
|
|
593
|
+
h2: 'text-[32px] font-[var(--font-weight-fat)]',
|
|
594
|
+
h3: 'text-[28px] font-[var(--font-weight-fat)]',
|
|
595
|
+
h4: 'text-[24px] font-[var(--font-weight-heavy)]',
|
|
596
|
+
h5: 'text-[22px] font-[var(--font-weight-heavy)]',
|
|
597
|
+
h6: 'text-[20px] font-[var(--font-weight-heavy)]',
|
|
598
|
+
// Body Copy with specific weight variants
|
|
599
|
+
'body-xl-heavy': 'text-[20px] font-[var(--font-weight-heavy)]',
|
|
600
|
+
'body-l-heavy': 'text-[18px] font-[var(--font-weight-heavy)]',
|
|
601
|
+
'body-l-bold': 'text-[18px] font-[var(--font-weight-bold)]',
|
|
602
|
+
'body-l-medium': 'text-[18px] font-[var(--font-weight-medium)]',
|
|
603
|
+
'body-m-heavy': 'text-[16px] font-[var(--font-weight-heavy)]',
|
|
604
|
+
'body-m-bold': 'text-[16px] font-[var(--font-weight-bold)]',
|
|
605
|
+
'body-m-medium': 'text-[16px] font-[var(--font-weight-medium)]',
|
|
606
|
+
'body-s-heavy': 'text-[14px] font-[var(--font-weight-heavy)]',
|
|
607
|
+
'body-s-bold': 'text-[14px] font-[var(--font-weight-bold)]',
|
|
608
|
+
'body-s-medium': 'text-[14px] font-[var(--font-weight-medium)]',
|
|
609
|
+
'body-ms-bold': 'text-[13px] font-[var(--font-weight-bold)]',
|
|
610
|
+
'body-ms-medium': 'text-[13px] font-[var(--font-weight-medium)]',
|
|
611
|
+
'body-xs-bold': 'text-[12px] font-[var(--font-weight-bold)]',
|
|
612
|
+
'body-xs-medium': 'text-[12px] font-[var(--font-weight-medium)]',
|
|
613
|
+
'body-t-bold': 'text-[10px] font-[var(--font-weight-bold)]',
|
|
614
|
+
'body-t-medium': 'text-[10px] font-[var(--font-weight-medium)]',
|
|
615
|
+
'body-ss-medium': 'text-[9px] font-[var(--font-weight-medium)]',
|
|
616
|
+
};
|
|
617
|
+
// Export for reuse in other components
|
|
618
|
+
const getTypographyClasses = (variant) => {
|
|
619
|
+
return variantClasses$1[variant];
|
|
620
|
+
};
|
|
621
|
+
const colorClasses = {
|
|
622
|
+
primary: 'text-[var(--color-primary)]',
|
|
623
|
+
secondary: 'text-[var(--color-secondary)]',
|
|
624
|
+
'neutral-darker': 'text-[var(--color-neutral-darker)]',
|
|
625
|
+
'neutral-dark': 'text-[var(--color-neutral-dark)]',
|
|
626
|
+
'neutral-main': 'text-[var(--color-neutral-main)]',
|
|
627
|
+
white: 'text-[var(--color-white)]',
|
|
628
|
+
inherit: 'text-inherit',
|
|
629
|
+
};
|
|
630
|
+
const getDefaultElement = (variant) => {
|
|
631
|
+
if (variant.startsWith('h'))
|
|
632
|
+
return variant.split('-')[0]; // h1, h2, etc.
|
|
633
|
+
return 'p';
|
|
634
|
+
};
|
|
635
|
+
const Typography$1 = React.forwardRef(({ variant = 'body-m-medium', color = 'inherit', as, className, children, ...props }, ref) => {
|
|
636
|
+
const Element = as || getDefaultElement(variant);
|
|
637
|
+
return React.createElement(Element, {
|
|
638
|
+
ref,
|
|
639
|
+
className: cn(variantClasses$1[variant], colorClasses[color], 'leading-[var(--leading-default)]', // 180% line height
|
|
640
|
+
className),
|
|
641
|
+
...props,
|
|
642
|
+
}, children);
|
|
643
|
+
});
|
|
644
|
+
Typography$1.displayName = 'Typography';
|
|
645
|
+
|
|
646
|
+
const sizeClasses = {
|
|
647
|
+
sm: 'px-[16px] py-[7px]',
|
|
648
|
+
md: 'px-[16px] py-[9px]',
|
|
649
|
+
lg: 'px-[16px] py-[13px]',
|
|
650
|
+
xl: 'px-[20px] py-[13px]',
|
|
651
|
+
};
|
|
652
|
+
const defaultTextVariants = {
|
|
653
|
+
sm: 'body-s-bold', // 14px / Bold (600)
|
|
654
|
+
md: 'body-m-bold', // 16px / Bold (600)
|
|
655
|
+
lg: 'body-l-bold', // 18px / Bold (600)
|
|
656
|
+
xl: 'body-xl-heavy', // 20px / Heavy (700)
|
|
657
|
+
};
|
|
658
|
+
const variantClasses = {
|
|
659
|
+
primary: `
|
|
660
|
+
bg-[var(--color-primary)] text-white
|
|
661
|
+
hover:bg-[var(--color-primary-dark)]
|
|
662
|
+
disabled:bg-[var(--color-neutral-light)] disabled:text-[var(--color-neutral-darker)]
|
|
663
|
+
`,
|
|
664
|
+
secondary: `
|
|
665
|
+
bg-[var(--color-primary-lightest)] text-[var(--color-primary)]
|
|
666
|
+
hover:bg-[var(--color-primary-lighter)]
|
|
667
|
+
disabled:bg-[var(--color-neutral-light)] disabled:text-[var(--color-neutral-darker)]
|
|
668
|
+
`,
|
|
669
|
+
tertiary: `
|
|
670
|
+
bg-white border border-[var(--color-primary-light)] text-[var(--color-primary)]
|
|
671
|
+
hover:bg-[var(--color-neutral-lighter)]
|
|
672
|
+
disabled:bg-[var(--color-neutral-light)] disabled:text-[var(--color-neutral-darker)]
|
|
673
|
+
`,
|
|
674
|
+
ghost: `
|
|
675
|
+
bg-transparent text-[var(--color-primary)]
|
|
676
|
+
hover:bg-[var(--color-primary-lightest)]
|
|
677
|
+
disabled:bg-[var(--color-neutral-light)] disabled:text-[var(--color-neutral-darker)]
|
|
678
|
+
`,
|
|
679
|
+
};
|
|
680
|
+
const Button$1 = React.forwardRef(({ className, variant = 'primary', size = 'md', icon, iconPosition = 'right', children, loading = false, disabled, textVariant, ...props }, ref) => {
|
|
681
|
+
const finalTextVariant = textVariant || defaultTextVariants[size];
|
|
682
|
+
return (jsxRuntimeExports.jsxs("button", { ref: ref, type: "button", className: cn('inline-flex items-center justify-center rounded-[8px] transition-colors duration-200', sizeClasses[size], variantClasses[variant], getTypographyClasses(finalTextVariant), disabled && 'opacity-50 pointer-events-none', className), disabled: disabled || loading, ...props, children: [icon && iconPosition === 'left' && (jsxRuntimeExports.jsx("span", { className: "mr-2 flex items-center", children: icon })), loading ? '...' : children, icon && iconPosition === 'right' && (jsxRuntimeExports.jsx("span", { className: "ml-2 flex items-center", children: icon }))] }));
|
|
683
|
+
});
|
|
684
|
+
Button$1.displayName = 'Button';
|
|
685
|
+
|
|
686
|
+
// Generated ESM version of ua-parser-js
|
|
687
|
+
// DO NOT EDIT THIS FILE!
|
|
688
|
+
// Source: /src/main/ua-parser.js
|
|
689
|
+
|
|
690
|
+
/////////////////////////////////////////////////////////////////////////////////
|
|
691
|
+
/* UAParser.js v2.0.4
|
|
692
|
+
Copyright © 2012-2025 Faisal Salman <f@faisalman.com>
|
|
693
|
+
AGPLv3 License *//*
|
|
694
|
+
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
|
695
|
+
Supports browser & node.js environment.
|
|
696
|
+
Demo : https://uaparser.dev
|
|
697
|
+
Source : https://github.com/faisalman/ua-parser-js */
|
|
698
|
+
/////////////////////////////////////////////////////////////////////////////////
|
|
699
|
+
|
|
700
|
+
/* jshint esversion: 6 */
|
|
701
|
+
/* globals window */
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
//////////////
|
|
706
|
+
// Constants
|
|
707
|
+
/////////////
|
|
708
|
+
|
|
709
|
+
var LIBVERSION = '2.0.4',
|
|
710
|
+
UA_MAX_LENGTH = 500,
|
|
711
|
+
USER_AGENT = 'user-agent',
|
|
712
|
+
EMPTY = '',
|
|
713
|
+
UNKNOWN = '?',
|
|
714
|
+
|
|
715
|
+
// typeof
|
|
716
|
+
FUNC_TYPE = 'function',
|
|
717
|
+
UNDEF_TYPE = 'undefined',
|
|
718
|
+
OBJ_TYPE = 'object',
|
|
719
|
+
STR_TYPE = 'string',
|
|
720
|
+
|
|
721
|
+
// properties
|
|
722
|
+
UA_BROWSER = 'browser',
|
|
723
|
+
UA_CPU = 'cpu',
|
|
724
|
+
UA_DEVICE = 'device',
|
|
725
|
+
UA_ENGINE = 'engine',
|
|
726
|
+
UA_OS = 'os',
|
|
727
|
+
UA_RESULT = 'result',
|
|
728
|
+
|
|
729
|
+
NAME = 'name',
|
|
730
|
+
TYPE = 'type',
|
|
731
|
+
VENDOR = 'vendor',
|
|
732
|
+
VERSION = 'version',
|
|
733
|
+
ARCHITECTURE= 'architecture',
|
|
734
|
+
MAJOR = 'major',
|
|
735
|
+
MODEL = 'model',
|
|
736
|
+
|
|
737
|
+
// device types
|
|
738
|
+
CONSOLE = 'console',
|
|
739
|
+
MOBILE = 'mobile',
|
|
740
|
+
TABLET = 'tablet',
|
|
741
|
+
SMARTTV = 'smarttv',
|
|
742
|
+
WEARABLE = 'wearable',
|
|
743
|
+
XR = 'xr',
|
|
744
|
+
EMBEDDED = 'embedded',
|
|
745
|
+
|
|
746
|
+
// browser types
|
|
747
|
+
INAPP = 'inapp',
|
|
748
|
+
|
|
749
|
+
// client hints
|
|
750
|
+
BRANDS = 'brands',
|
|
751
|
+
FORMFACTORS = 'formFactors',
|
|
752
|
+
FULLVERLIST = 'fullVersionList',
|
|
753
|
+
PLATFORM = 'platform',
|
|
754
|
+
PLATFORMVER = 'platformVersion',
|
|
755
|
+
BITNESS = 'bitness',
|
|
756
|
+
CH_HEADER = 'sec-ch-ua',
|
|
757
|
+
CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
|
|
758
|
+
CH_HEADER_ARCH = CH_HEADER + '-arch',
|
|
759
|
+
CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
|
|
760
|
+
CH_HEADER_FORM_FACTORS = CH_HEADER + '-form-factors',
|
|
761
|
+
CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
|
|
762
|
+
CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
|
|
763
|
+
CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
|
|
764
|
+
CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
|
|
765
|
+
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS],
|
|
766
|
+
|
|
767
|
+
// device vendors
|
|
768
|
+
AMAZON = 'Amazon',
|
|
769
|
+
APPLE = 'Apple',
|
|
770
|
+
ASUS = 'ASUS',
|
|
771
|
+
BLACKBERRY = 'BlackBerry',
|
|
772
|
+
GOOGLE = 'Google',
|
|
773
|
+
HUAWEI = 'Huawei',
|
|
774
|
+
LENOVO = 'Lenovo',
|
|
775
|
+
HONOR = 'Honor',
|
|
776
|
+
LG = 'LG',
|
|
777
|
+
MICROSOFT = 'Microsoft',
|
|
778
|
+
MOTOROLA = 'Motorola',
|
|
779
|
+
NVIDIA = 'Nvidia',
|
|
780
|
+
ONEPLUS = 'OnePlus',
|
|
781
|
+
OPPO = 'OPPO',
|
|
782
|
+
SAMSUNG = 'Samsung',
|
|
783
|
+
SHARP = 'Sharp',
|
|
784
|
+
SONY = 'Sony',
|
|
785
|
+
XIAOMI = 'Xiaomi',
|
|
786
|
+
ZEBRA = 'Zebra',
|
|
787
|
+
|
|
788
|
+
// browsers
|
|
789
|
+
CHROME = 'Chrome',
|
|
790
|
+
CHROMIUM = 'Chromium',
|
|
791
|
+
CHROMECAST = 'Chromecast',
|
|
792
|
+
EDGE = 'Edge',
|
|
793
|
+
FIREFOX = 'Firefox',
|
|
794
|
+
OPERA = 'Opera',
|
|
795
|
+
FACEBOOK = 'Facebook',
|
|
796
|
+
SOGOU = 'Sogou',
|
|
797
|
+
|
|
798
|
+
PREFIX_MOBILE = 'Mobile ',
|
|
799
|
+
SUFFIX_BROWSER = ' Browser',
|
|
800
|
+
|
|
801
|
+
// os
|
|
802
|
+
WINDOWS = 'Windows';
|
|
803
|
+
|
|
804
|
+
var isWindow = typeof window !== UNDEF_TYPE,
|
|
805
|
+
NAVIGATOR = (isWindow && window.navigator) ?
|
|
806
|
+
window.navigator :
|
|
807
|
+
undefined,
|
|
808
|
+
NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ?
|
|
809
|
+
NAVIGATOR.userAgentData :
|
|
810
|
+
undefined;
|
|
811
|
+
|
|
812
|
+
///////////
|
|
813
|
+
// Helper
|
|
814
|
+
//////////
|
|
815
|
+
|
|
816
|
+
var extend = function (defaultRgx, extensions) {
|
|
817
|
+
var mergedRgx = {};
|
|
818
|
+
var extraRgx = extensions;
|
|
819
|
+
if (!isExtensions(extensions)) {
|
|
820
|
+
extraRgx = {};
|
|
821
|
+
for (var i in extensions) {
|
|
822
|
+
for (var j in extensions[i]) {
|
|
823
|
+
extraRgx[j] = extensions[i][j].concat(extraRgx[j] ? extraRgx[j] : []);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
for (var k in defaultRgx) {
|
|
828
|
+
mergedRgx[k] = extraRgx[k] && extraRgx[k].length % 2 === 0 ? extraRgx[k].concat(defaultRgx[k]) : defaultRgx[k];
|
|
829
|
+
}
|
|
830
|
+
return mergedRgx;
|
|
831
|
+
},
|
|
832
|
+
enumerize = function (arr) {
|
|
833
|
+
var enums = {};
|
|
834
|
+
for (var i=0; i<arr.length; i++) {
|
|
835
|
+
enums[arr[i].toUpperCase()] = arr[i];
|
|
836
|
+
}
|
|
837
|
+
return enums;
|
|
838
|
+
},
|
|
839
|
+
has = function (str1, str2) {
|
|
840
|
+
if (typeof str1 === OBJ_TYPE && str1.length > 0) {
|
|
841
|
+
for (var i in str1) {
|
|
842
|
+
if (lowerize(str2) == lowerize(str1[i])) return true;
|
|
843
|
+
}
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
846
|
+
return isString(str1) ? lowerize(str2) == lowerize(str1) : false;
|
|
847
|
+
},
|
|
848
|
+
isExtensions = function (obj, deep) {
|
|
849
|
+
for (var prop in obj) {
|
|
850
|
+
return /^(browser|cpu|device|engine|os)$/.test(prop) || (deep ? isExtensions(obj[prop]) : false);
|
|
851
|
+
}
|
|
852
|
+
},
|
|
853
|
+
isString = function (val) {
|
|
854
|
+
return typeof val === STR_TYPE;
|
|
855
|
+
},
|
|
856
|
+
itemListToArray = function (header) {
|
|
857
|
+
if (!header) return undefined;
|
|
858
|
+
var arr = [];
|
|
859
|
+
var tokens = strip(/\\?\"/g, header).split(',');
|
|
860
|
+
for (var i = 0; i < tokens.length; i++) {
|
|
861
|
+
if (tokens[i].indexOf(';') > -1) {
|
|
862
|
+
var token = trim(tokens[i]).split(';v=');
|
|
863
|
+
arr[i] = { brand : token[0], version : token[1] };
|
|
864
|
+
} else {
|
|
865
|
+
arr[i] = trim(tokens[i]);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
return arr;
|
|
869
|
+
},
|
|
870
|
+
lowerize = function (str) {
|
|
871
|
+
return isString(str) ? str.toLowerCase() : str;
|
|
872
|
+
},
|
|
873
|
+
majorize = function (version) {
|
|
874
|
+
return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
|
|
875
|
+
},
|
|
876
|
+
setProps = function (arr) {
|
|
877
|
+
for (var i in arr) {
|
|
878
|
+
var propName = arr[i];
|
|
879
|
+
if (typeof propName == OBJ_TYPE && propName.length == 2) {
|
|
880
|
+
this[propName[0]] = propName[1];
|
|
881
|
+
} else {
|
|
882
|
+
this[propName] = undefined;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return this;
|
|
886
|
+
},
|
|
887
|
+
strip = function (pattern, str) {
|
|
888
|
+
return isString(str) ? str.replace(pattern, EMPTY) : str;
|
|
889
|
+
},
|
|
890
|
+
stripQuotes = function (str) {
|
|
891
|
+
return strip(/\\?\"/g, str);
|
|
892
|
+
},
|
|
893
|
+
trim = function (str, len) {
|
|
894
|
+
if (isString(str)) {
|
|
895
|
+
str = strip(/^\s\s*/, str);
|
|
896
|
+
return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
///////////////
|
|
901
|
+
// Map helper
|
|
902
|
+
//////////////
|
|
903
|
+
|
|
904
|
+
var rgxMapper = function (ua, arrays) {
|
|
905
|
+
|
|
906
|
+
if(!ua || !arrays) return;
|
|
907
|
+
|
|
908
|
+
var i = 0, j, k, p, q, matches, match;
|
|
909
|
+
|
|
910
|
+
// loop through all regexes maps
|
|
911
|
+
while (i < arrays.length && !matches) {
|
|
912
|
+
|
|
913
|
+
var regex = arrays[i], // even sequence (0,2,4,..)
|
|
914
|
+
props = arrays[i + 1]; // odd sequence (1,3,5,..)
|
|
915
|
+
j = k = 0;
|
|
916
|
+
|
|
917
|
+
// try matching uastring with regexes
|
|
918
|
+
while (j < regex.length && !matches) {
|
|
919
|
+
|
|
920
|
+
if (!regex[j]) { break; }
|
|
921
|
+
matches = regex[j++].exec(ua);
|
|
922
|
+
|
|
923
|
+
if (!!matches) {
|
|
924
|
+
for (p = 0; p < props.length; p++) {
|
|
925
|
+
match = matches[++k];
|
|
926
|
+
q = props[p];
|
|
927
|
+
// check if given property is actually array
|
|
928
|
+
if (typeof q === OBJ_TYPE && q.length > 0) {
|
|
929
|
+
if (q.length === 2) {
|
|
930
|
+
if (typeof q[1] == FUNC_TYPE) {
|
|
931
|
+
// assign modified match
|
|
932
|
+
this[q[0]] = q[1].call(this, match);
|
|
933
|
+
} else {
|
|
934
|
+
// assign given value, ignore regex match
|
|
935
|
+
this[q[0]] = q[1];
|
|
936
|
+
}
|
|
937
|
+
} else if (q.length >= 3) {
|
|
938
|
+
// Check whether q[1] FUNCTION or REGEX
|
|
939
|
+
if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
|
|
940
|
+
if (q.length > 3) {
|
|
941
|
+
this[q[0]] = match ? q[1].apply(this, q.slice(2)) : undefined;
|
|
942
|
+
} else {
|
|
943
|
+
// call function (usually string mapper)
|
|
944
|
+
this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
|
|
945
|
+
}
|
|
946
|
+
} else {
|
|
947
|
+
if (q.length == 3) {
|
|
948
|
+
// sanitize match using given regex
|
|
949
|
+
this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
|
|
950
|
+
} else if (q.length == 4) {
|
|
951
|
+
this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
|
|
952
|
+
} else if (q.length > 4) {
|
|
953
|
+
this[q[0]] = match ? q[3].apply(this, [match.replace(q[1], q[2])].concat(q.slice(4))) : undefined;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
} else {
|
|
958
|
+
this[q] = match ? match : undefined;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
i += 2;
|
|
964
|
+
}
|
|
965
|
+
},
|
|
966
|
+
|
|
967
|
+
strMapper = function (str, map) {
|
|
968
|
+
|
|
969
|
+
for (var i in map) {
|
|
970
|
+
// check if current value is array
|
|
971
|
+
if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
|
|
972
|
+
for (var j = 0; j < map[i].length; j++) {
|
|
973
|
+
if (has(map[i][j], str)) {
|
|
974
|
+
return (i === UNKNOWN) ? undefined : i;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
} else if (has(map[i], str)) {
|
|
978
|
+
return (i === UNKNOWN) ? undefined : i;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
return map.hasOwnProperty('*') ? map['*'] : str;
|
|
982
|
+
};
|
|
983
|
+
|
|
984
|
+
///////////////
|
|
985
|
+
// String map
|
|
986
|
+
//////////////
|
|
987
|
+
|
|
988
|
+
var windowsVersionMap = {
|
|
989
|
+
'ME' : '4.90',
|
|
990
|
+
'NT 3.51': '3.51',
|
|
991
|
+
'NT 4.0': '4.0',
|
|
992
|
+
'2000' : ['5.0', '5.01'],
|
|
993
|
+
'XP' : ['5.1', '5.2'],
|
|
994
|
+
'Vista' : '6.0',
|
|
995
|
+
'7' : '6.1',
|
|
996
|
+
'8' : '6.2',
|
|
997
|
+
'8.1' : '6.3',
|
|
998
|
+
'10' : ['6.4', '10.0'],
|
|
999
|
+
'NT' : ''
|
|
1000
|
+
},
|
|
1001
|
+
|
|
1002
|
+
formFactorsMap = {
|
|
1003
|
+
'embedded' : 'Automotive',
|
|
1004
|
+
'mobile' : 'Mobile',
|
|
1005
|
+
'tablet' : ['Tablet', 'EInk'],
|
|
1006
|
+
'smarttv' : 'TV',
|
|
1007
|
+
'wearable' : 'Watch',
|
|
1008
|
+
'xr' : ['VR', 'XR'],
|
|
1009
|
+
'?' : ['Desktop', 'Unknown'],
|
|
1010
|
+
'*' : undefined
|
|
1011
|
+
},
|
|
1012
|
+
|
|
1013
|
+
browserHintsMap = {
|
|
1014
|
+
'Chrome' : 'Google Chrome',
|
|
1015
|
+
'Edge' : 'Microsoft Edge',
|
|
1016
|
+
'Edge WebView2' : 'Microsoft Edge WebView2',
|
|
1017
|
+
'Chrome WebView': 'Android WebView',
|
|
1018
|
+
'Chrome Headless':'HeadlessChrome',
|
|
1019
|
+
'Huawei Browser': 'HuaweiBrowser',
|
|
1020
|
+
'MIUI Browser' : 'Miui Browser',
|
|
1021
|
+
'Opera Mobi' : 'OperaMobile',
|
|
1022
|
+
'Yandex' : 'YaBrowser'
|
|
1023
|
+
};
|
|
1024
|
+
|
|
1025
|
+
//////////////
|
|
1026
|
+
// Regex map
|
|
1027
|
+
/////////////
|
|
1028
|
+
|
|
1029
|
+
var defaultRegexes = {
|
|
1030
|
+
|
|
1031
|
+
browser : [[
|
|
1032
|
+
|
|
1033
|
+
// Most common regardless engine
|
|
1034
|
+
/\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
|
|
1035
|
+
], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
|
|
1036
|
+
/webview.+edge\/([\w\.]+)/i // Microsoft Edge
|
|
1037
|
+
], [VERSION, [NAME, EDGE+' WebView']], [
|
|
1038
|
+
/edg(?:e|ios|a)?\/([\w\.]+)/i
|
|
1039
|
+
], [VERSION, [NAME, 'Edge']], [
|
|
1040
|
+
|
|
1041
|
+
// Presto based
|
|
1042
|
+
/(opera mini)\/([-\w\.]+)/i, // Opera Mini
|
|
1043
|
+
/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet
|
|
1044
|
+
/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera
|
|
1045
|
+
], [NAME, VERSION], [
|
|
1046
|
+
/opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
|
|
1047
|
+
], [VERSION, [NAME, OPERA+' Mini']], [
|
|
1048
|
+
/\bop(?:rg)?x\/([\w\.]+)/i // Opera GX
|
|
1049
|
+
], [VERSION, [NAME, OPERA+' GX']], [
|
|
1050
|
+
/\bopr\/([\w\.]+)/i // Opera Webkit
|
|
1051
|
+
], [VERSION, [NAME, OPERA]], [
|
|
1052
|
+
|
|
1053
|
+
// Mixed
|
|
1054
|
+
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
|
|
1055
|
+
], [VERSION, [NAME, 'Baidu']], [
|
|
1056
|
+
/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i // Maxthon
|
|
1057
|
+
], [VERSION, [NAME, 'Maxthon']], [
|
|
1058
|
+
/(kindle)\/([\w\.]+)/i, // Kindle
|
|
1059
|
+
/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
|
|
1060
|
+
// Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
|
|
1061
|
+
// Trident based
|
|
1062
|
+
/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
|
|
1063
|
+
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
|
1064
|
+
|
|
1065
|
+
// Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble
|
|
1066
|
+
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser)\/([-\w\.]+)/i,
|
|
1067
|
+
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
|
|
1068
|
+
/(heytap|ovi|115|surf)browser\/([\d\.]+)/i, // HeyTap/Ovi/115/Surf
|
|
1069
|
+
/(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i // Ecosia/Weibo
|
|
1070
|
+
], [NAME, VERSION], [
|
|
1071
|
+
/quark(?:pc)?\/([-\w\.]+)/i // Quark
|
|
1072
|
+
], [VERSION, [NAME, 'Quark']], [
|
|
1073
|
+
/\bddg\/([\w\.]+)/i // DuckDuckGo
|
|
1074
|
+
], [VERSION, [NAME, 'DuckDuckGo']], [
|
|
1075
|
+
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
|
|
1076
|
+
], [VERSION, [NAME, 'UCBrowser']], [
|
|
1077
|
+
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
|
1078
|
+
/\bqbcore\/([\w\.]+).+microm/i,
|
|
1079
|
+
/micromessenger\/([\w\.]+)/i // WeChat
|
|
1080
|
+
], [VERSION, [NAME, 'WeChat']], [
|
|
1081
|
+
/konqueror\/([\w\.]+)/i // Konqueror
|
|
1082
|
+
], [VERSION, [NAME, 'Konqueror']], [
|
|
1083
|
+
/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11
|
|
1084
|
+
], [VERSION, [NAME, 'IE']], [
|
|
1085
|
+
/ya(?:search)?browser\/([\w\.]+)/i // Yandex
|
|
1086
|
+
], [VERSION, [NAME, 'Yandex']], [
|
|
1087
|
+
/slbrowser\/([\w\.]+)/i // Smart Lenovo Browser
|
|
1088
|
+
], [VERSION, [NAME, 'Smart ' + LENOVO + SUFFIX_BROWSER]], [
|
|
1089
|
+
/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
|
|
1090
|
+
], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
|
|
1091
|
+
/\bfocus\/([\w\.]+)/i // Firefox Focus
|
|
1092
|
+
], [VERSION, [NAME, FIREFOX+' Focus']], [
|
|
1093
|
+
/\bopt\/([\w\.]+)/i // Opera Touch
|
|
1094
|
+
], [VERSION, [NAME, OPERA+' Touch']], [
|
|
1095
|
+
/coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser
|
|
1096
|
+
], [VERSION, [NAME, 'Coc Coc']], [
|
|
1097
|
+
/dolfin\/([\w\.]+)/i // Dolphin
|
|
1098
|
+
], [VERSION, [NAME, 'Dolphin']], [
|
|
1099
|
+
/coast\/([\w\.]+)/i // Opera Coast
|
|
1100
|
+
], [VERSION, [NAME, OPERA+' Coast']], [
|
|
1101
|
+
/miuibrowser\/([\w\.]+)/i // MIUI Browser
|
|
1102
|
+
], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
|
|
1103
|
+
/fxios\/([\w\.-]+)/i // Firefox for iOS
|
|
1104
|
+
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
|
|
1105
|
+
/\bqihoobrowser\/?([\w\.]*)/i // 360
|
|
1106
|
+
], [VERSION, [NAME, '360']], [
|
|
1107
|
+
/\b(qq)\/([\w\.]+)/i // QQ
|
|
1108
|
+
], [[NAME, /(.+)/, '$1Browser'], VERSION], [
|
|
1109
|
+
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
|
|
1110
|
+
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
|
|
1111
|
+
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
|
|
1112
|
+
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
|
|
1113
|
+
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
|
|
1114
|
+
], [VERSION, [NAME, SOGOU + ' Explorer']], [
|
|
1115
|
+
/(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
|
|
1116
|
+
], [[NAME, SOGOU + ' Mobile'], VERSION], [
|
|
1117
|
+
/(electron)\/([\w\.]+) safari/i, // Electron-based App
|
|
1118
|
+
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
|
|
1119
|
+
/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i // QQ/2345
|
|
1120
|
+
], [NAME, VERSION], [
|
|
1121
|
+
/(lbbrowser|rekonq)/i // LieBao Browser/Rekonq
|
|
1122
|
+
], [NAME], [
|
|
1123
|
+
/ome\/([\w\.]+) \w* ?(iron) saf/i, // Iron
|
|
1124
|
+
/ome\/([\w\.]+).+qihu (360)[es]e/i // 360
|
|
1125
|
+
], [VERSION, NAME], [
|
|
1126
|
+
|
|
1127
|
+
// WebView
|
|
1128
|
+
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
|
|
1129
|
+
], [[NAME, FACEBOOK], VERSION, [TYPE, INAPP]], [
|
|
1130
|
+
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
|
|
1131
|
+
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
|
|
1132
|
+
/(daum)apps[\/ ]([\w\.]+)/i, // Daum App
|
|
1133
|
+
/safari (line)\/([\w\.]+)/i, // Line App for iOS
|
|
1134
|
+
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
|
1135
|
+
/(alipay)client\/([\w\.]+)/i, // Alipay
|
|
1136
|
+
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
|
|
1137
|
+
/(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i // Instagram/Snapchat/Klarna
|
|
1138
|
+
], [NAME, VERSION, [TYPE, INAPP]], [
|
|
1139
|
+
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
|
1140
|
+
], [VERSION, [NAME, 'GSA'], [TYPE, INAPP]], [
|
|
1141
|
+
/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
|
|
1142
|
+
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
|
|
1143
|
+
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
|
1144
|
+
], [NAME, [TYPE, INAPP]], [
|
|
1145
|
+
|
|
1146
|
+
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
|
|
1147
|
+
], [NAME, VERSION], [
|
|
1148
|
+
|
|
1149
|
+
/headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
|
|
1150
|
+
], [VERSION, [NAME, CHROME+' Headless']], [
|
|
1151
|
+
|
|
1152
|
+
/wv\).+chrome\/([\w\.]+).+edgw\//i // Edge WebView2
|
|
1153
|
+
], [VERSION, [NAME, EDGE+' WebView2']], [
|
|
1154
|
+
|
|
1155
|
+
/ wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
|
|
1156
|
+
], [[NAME, CHROME+' WebView'], VERSION], [
|
|
1157
|
+
|
|
1158
|
+
/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser
|
|
1159
|
+
], [VERSION, [NAME, 'Android' + SUFFIX_BROWSER]], [
|
|
1160
|
+
|
|
1161
|
+
/chrome\/([\w\.]+) mobile/i // Chrome Mobile
|
|
1162
|
+
], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
|
|
1163
|
+
|
|
1164
|
+
/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia
|
|
1165
|
+
], [NAME, VERSION], [
|
|
1166
|
+
|
|
1167
|
+
/version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i // Safari Mobile
|
|
1168
|
+
], [VERSION, [NAME, PREFIX_MOBILE + 'Safari']], [
|
|
1169
|
+
/iphone .*mobile(?:\/\w+ | ?)safari/i
|
|
1170
|
+
], [[NAME, PREFIX_MOBILE + 'Safari']], [
|
|
1171
|
+
/version\/([\w\.\,]+) .*(safari)/i // Safari
|
|
1172
|
+
], [VERSION, NAME], [
|
|
1173
|
+
/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
|
|
1174
|
+
], [NAME, [VERSION, '1']], [
|
|
1175
|
+
|
|
1176
|
+
/(webkit|khtml)\/([\w\.]+)/i
|
|
1177
|
+
], [NAME, VERSION], [
|
|
1178
|
+
|
|
1179
|
+
// Gecko based
|
|
1180
|
+
/(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i // Firefox Mobile
|
|
1181
|
+
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
|
|
1182
|
+
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
|
|
1183
|
+
], [[NAME, 'Netscape'], VERSION], [
|
|
1184
|
+
/(wolvic|librewolf)\/([\w\.]+)/i // Wolvic/LibreWolf
|
|
1185
|
+
], [NAME, VERSION], [
|
|
1186
|
+
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
|
|
1187
|
+
], [VERSION, [NAME, FIREFOX+' Reality']], [
|
|
1188
|
+
/ekiohf.+(flow)\/([\w\.]+)/i, // Flow
|
|
1189
|
+
/(swiftfox)/i, // Swiftfox
|
|
1190
|
+
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
|
|
1191
|
+
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
|
|
1192
|
+
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
|
|
1193
|
+
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
|
|
1194
|
+
/(firefox)\/([\w\.]+)/i, // Other Firefox-based
|
|
1195
|
+
/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
|
|
1196
|
+
|
|
1197
|
+
// Other
|
|
1198
|
+
/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
|
1199
|
+
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird
|
|
1200
|
+
/\b(links) \(([\w\.]+)/i // Links
|
|
1201
|
+
], [NAME, [VERSION, /_/g, '.']], [
|
|
1202
|
+
|
|
1203
|
+
/(cobalt)\/([\w\.]+)/i // Cobalt
|
|
1204
|
+
], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
|
|
1205
|
+
],
|
|
1206
|
+
|
|
1207
|
+
cpu : [[
|
|
1208
|
+
|
|
1209
|
+
/\b((amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64)
|
|
1210
|
+
], [[ARCHITECTURE, 'amd64']], [
|
|
1211
|
+
|
|
1212
|
+
/(ia32(?=;))/i, // IA32 (quicktime)
|
|
1213
|
+
/\b((i[346]|x)86)(pc)?\b/i // IA32 (x86)
|
|
1214
|
+
], [[ARCHITECTURE, 'ia32']], [
|
|
1215
|
+
|
|
1216
|
+
/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i // ARM64
|
|
1217
|
+
], [[ARCHITECTURE, 'arm64']], [
|
|
1218
|
+
|
|
1219
|
+
/\b(arm(v[67])?ht?n?[fl]p?)\b/i // ARMHF
|
|
1220
|
+
], [[ARCHITECTURE, 'armhf']], [
|
|
1221
|
+
|
|
1222
|
+
// PocketPC mistakenly identified as PowerPC
|
|
1223
|
+
/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
|
|
1224
|
+
], [[ARCHITECTURE, 'arm']], [
|
|
1225
|
+
|
|
1226
|
+
/((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC
|
|
1227
|
+
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
|
|
1228
|
+
|
|
1229
|
+
/ sun4\w[;\)]/i // SPARC
|
|
1230
|
+
], [[ARCHITECTURE, 'sparc']], [
|
|
1231
|
+
|
|
1232
|
+
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i
|
|
1233
|
+
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
|
|
1234
|
+
], [[ARCHITECTURE, lowerize]]
|
|
1235
|
+
],
|
|
1236
|
+
|
|
1237
|
+
device : [[
|
|
1238
|
+
|
|
1239
|
+
//////////////////////////
|
|
1240
|
+
// MOBILES & TABLETS
|
|
1241
|
+
/////////////////////////
|
|
1242
|
+
|
|
1243
|
+
// Samsung
|
|
1244
|
+
/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i
|
|
1245
|
+
], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
|
|
1246
|
+
/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
|
|
1247
|
+
/samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,
|
|
1248
|
+
/sec-(sgh\w+)/i
|
|
1249
|
+
], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
|
|
1250
|
+
|
|
1251
|
+
// Apple
|
|
1252
|
+
/(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i // iPod/iPhone
|
|
1253
|
+
], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [
|
|
1254
|
+
/\((ipad);[-\w\),; ]+apple/i, // iPad
|
|
1255
|
+
/applecoremedia\/[\w\.]+ \((ipad)/i,
|
|
1256
|
+
/\b(ipad)\d\d?,\d\d?[;\]].+ios/i
|
|
1257
|
+
], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [
|
|
1258
|
+
/(macintosh);/i
|
|
1259
|
+
], [MODEL, [VENDOR, APPLE]], [
|
|
1260
|
+
|
|
1261
|
+
// Sharp
|
|
1262
|
+
/\b(sh-?[altvz]?\d\d[a-ekm]?)/i
|
|
1263
|
+
], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
|
|
1264
|
+
|
|
1265
|
+
// Honor
|
|
1266
|
+
/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i
|
|
1267
|
+
], [MODEL, [VENDOR, HONOR], [TYPE, TABLET]], [
|
|
1268
|
+
/honor([-\w ]+)[;\)]/i
|
|
1269
|
+
], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [
|
|
1270
|
+
|
|
1271
|
+
// Huawei
|
|
1272
|
+
/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i
|
|
1273
|
+
], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
|
|
1274
|
+
/(?:huawei)([-\w ]+)[;\)]/i,
|
|
1275
|
+
/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
|
|
1276
|
+
], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
|
|
1277
|
+
|
|
1278
|
+
// Xiaomi
|
|
1279
|
+
/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,
|
|
1280
|
+
/\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i // Mi Pad tablets
|
|
1281
|
+
],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [
|
|
1282
|
+
|
|
1283
|
+
/\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, // Xiaomi POCO
|
|
1284
|
+
/\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
|
|
1285
|
+
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
|
|
1286
|
+
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
|
|
1287
|
+
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
|
|
1288
|
+
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i, // Xiaomi Mi
|
|
1289
|
+
/ ([\w ]+) miui\/v?\d/i
|
|
1290
|
+
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
|
1291
|
+
|
|
1292
|
+
// OnePlus
|
|
1293
|
+
/droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-k]\w[1m]10)\b/i,
|
|
1294
|
+
/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
|
|
1295
|
+
], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [
|
|
1296
|
+
|
|
1297
|
+
// OPPO
|
|
1298
|
+
/; (\w+) bui.+ oppo/i,
|
|
1299
|
+
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
|
1300
|
+
], [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]], [
|
|
1301
|
+
/\b(opd2(\d{3}a?))(?: bui|\))/i
|
|
1302
|
+
], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['203', '304', '403', '404', '413', '415'], '*' : OPPO }], [TYPE, TABLET]], [
|
|
1303
|
+
|
|
1304
|
+
// BLU
|
|
1305
|
+
/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i // Vivo series
|
|
1306
|
+
], [MODEL, [VENDOR, 'BLU'], [TYPE, MOBILE]], [
|
|
1307
|
+
|
|
1308
|
+
// Vivo
|
|
1309
|
+
/; vivo (\w+)(?: bui|\))/i,
|
|
1310
|
+
/\b(v[12]\d{3}\w?[at])(?: bui|;)/i
|
|
1311
|
+
], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [
|
|
1312
|
+
|
|
1313
|
+
// Realme
|
|
1314
|
+
/\b(rmx[1-3]\d{3})(?: bui|;|\))/i
|
|
1315
|
+
], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [
|
|
1316
|
+
|
|
1317
|
+
// Lenovo
|
|
1318
|
+
/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,
|
|
1319
|
+
/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i
|
|
1320
|
+
], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [
|
|
1321
|
+
/lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i
|
|
1322
|
+
], [MODEL, [VENDOR, LENOVO], [TYPE, MOBILE]], [
|
|
1323
|
+
|
|
1324
|
+
// Motorola
|
|
1325
|
+
/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
|
|
1326
|
+
/\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,
|
|
1327
|
+
/((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i
|
|
1328
|
+
], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [
|
|
1329
|
+
/\b(mz60\d|xoom[2 ]{0,2}) build\//i
|
|
1330
|
+
], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [
|
|
1331
|
+
|
|
1332
|
+
// LG
|
|
1333
|
+
/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
|
|
1334
|
+
], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [
|
|
1335
|
+
/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
|
|
1336
|
+
/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,
|
|
1337
|
+
/\blg-?([\d\w]+) bui/i
|
|
1338
|
+
], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [
|
|
1339
|
+
|
|
1340
|
+
// Nokia
|
|
1341
|
+
/(nokia) (t[12][01])/i
|
|
1342
|
+
], [VENDOR, MODEL, [TYPE, TABLET]], [
|
|
1343
|
+
/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,
|
|
1344
|
+
/nokia[-_ ]?(([-\w\. ]*))/i
|
|
1345
|
+
], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [
|
|
1346
|
+
|
|
1347
|
+
// Google
|
|
1348
|
+
/(pixel (c|tablet))\b/i // Google Pixel C/Tablet
|
|
1349
|
+
], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [
|
|
1350
|
+
// Google Pixel
|
|
1351
|
+
/droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i
|
|
1352
|
+
], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
|
|
1353
|
+
/(google) (pixelbook( go)?)/i
|
|
1354
|
+
], [VENDOR, MODEL], [
|
|
1355
|
+
|
|
1356
|
+
// Sony
|
|
1357
|
+
/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
|
|
1358
|
+
], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
|
|
1359
|
+
/sony tablet [ps]/i,
|
|
1360
|
+
/\b(?:sony)?sgp\w+(?: bui|\))/i
|
|
1361
|
+
], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [
|
|
1362
|
+
|
|
1363
|
+
// Amazon
|
|
1364
|
+
/(alexa)webm/i,
|
|
1365
|
+
/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i, // Kindle Fire without Silk / Echo Show
|
|
1366
|
+
/(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
|
|
1367
|
+
], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
|
|
1368
|
+
/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
|
|
1369
|
+
], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [
|
|
1370
|
+
|
|
1371
|
+
// BlackBerry
|
|
1372
|
+
/(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook
|
|
1373
|
+
], [MODEL, VENDOR, [TYPE, TABLET]], [
|
|
1374
|
+
/\b((?:bb[a-f]|st[hv])100-\d)/i,
|
|
1375
|
+
/\(bb10; (\w+)/i // BlackBerry 10
|
|
1376
|
+
], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [
|
|
1377
|
+
|
|
1378
|
+
// Asus
|
|
1379
|
+
/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
|
|
1380
|
+
], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [
|
|
1381
|
+
/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
|
|
1382
|
+
], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [
|
|
1383
|
+
|
|
1384
|
+
// HTC
|
|
1385
|
+
/(nexus 9)/i // HTC Nexus 9
|
|
1386
|
+
], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
|
|
1387
|
+
/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC
|
|
1388
|
+
|
|
1389
|
+
// ZTE
|
|
1390
|
+
/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
|
|
1391
|
+
/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
|
|
1392
|
+
], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
|
|
1393
|
+
|
|
1394
|
+
// TCL
|
|
1395
|
+
/tcl (xess p17aa)/i,
|
|
1396
|
+
/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i
|
|
1397
|
+
], [MODEL, [VENDOR, 'TCL'], [TYPE, TABLET]], [
|
|
1398
|
+
/droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i
|
|
1399
|
+
], [MODEL, [VENDOR, 'TCL'], [TYPE, MOBILE]], [
|
|
1400
|
+
|
|
1401
|
+
// itel
|
|
1402
|
+
/(itel) ((\w+))/i
|
|
1403
|
+
], [[VENDOR, lowerize], MODEL, [TYPE, strMapper, { 'tablet' : ['p10001l', 'w7001'], '*' : 'mobile' }]], [
|
|
1404
|
+
|
|
1405
|
+
// Acer
|
|
1406
|
+
/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
|
|
1407
|
+
], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
|
|
1408
|
+
|
|
1409
|
+
// Meizu
|
|
1410
|
+
/droid.+; (m[1-5] note) bui/i,
|
|
1411
|
+
/\bmz-([-\w]{2,})/i
|
|
1412
|
+
], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
|
|
1413
|
+
|
|
1414
|
+
// Ulefone
|
|
1415
|
+
/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
|
|
1416
|
+
], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
|
|
1417
|
+
|
|
1418
|
+
// Energizer
|
|
1419
|
+
/; (energy ?\w+)(?: bui|\))/i,
|
|
1420
|
+
/; energizer ([\w ]+)(?: bui|\))/i
|
|
1421
|
+
], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [
|
|
1422
|
+
|
|
1423
|
+
// Cat
|
|
1424
|
+
/; cat (b35);/i,
|
|
1425
|
+
/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
|
|
1426
|
+
], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [
|
|
1427
|
+
|
|
1428
|
+
// Smartfren
|
|
1429
|
+
/((?:new )?andromax[\w- ]+)(?: bui|\))/i
|
|
1430
|
+
], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [
|
|
1431
|
+
|
|
1432
|
+
// Nothing
|
|
1433
|
+
/droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i
|
|
1434
|
+
], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
|
|
1435
|
+
|
|
1436
|
+
// Archos
|
|
1437
|
+
/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,
|
|
1438
|
+
/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i
|
|
1439
|
+
], [MODEL, [VENDOR, 'Archos'], [TYPE, TABLET]], [
|
|
1440
|
+
/archos ([\w ]+)( b|\))/i,
|
|
1441
|
+
/; (ac[3-6]\d\w{2,8})( b|\))/i
|
|
1442
|
+
], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [
|
|
1443
|
+
|
|
1444
|
+
// HMD
|
|
1445
|
+
/; (n159v)/i
|
|
1446
|
+
], [MODEL, [VENDOR, 'HMD'], [TYPE, MOBILE]], [
|
|
1447
|
+
|
|
1448
|
+
// MIXED
|
|
1449
|
+
/(imo) (tab \w+)/i, // IMO
|
|
1450
|
+
/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i // Infinix XPad / Tecno
|
|
1451
|
+
], [VENDOR, MODEL, [TYPE, TABLET]], [
|
|
1452
|
+
|
|
1453
|
+
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
|
|
1454
|
+
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan
|
|
1455
|
+
/; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL
|
|
1456
|
+
/(hp) ([\w ]+\w)/i, // HP iPAQ
|
|
1457
|
+
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
|
|
1458
|
+
/(oppo) ?([\w ]+) bui/i // OPPO
|
|
1459
|
+
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
|
1460
|
+
|
|
1461
|
+
/(kobo)\s(ereader|touch)/i, // Kobo
|
|
1462
|
+
/(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
|
|
1463
|
+
/(kindle)\/([\w\.]+)/i // Kindle
|
|
1464
|
+
], [VENDOR, MODEL, [TYPE, TABLET]], [
|
|
1465
|
+
|
|
1466
|
+
/(surface duo)/i // Surface Duo
|
|
1467
|
+
], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [
|
|
1468
|
+
/droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone
|
|
1469
|
+
], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [
|
|
1470
|
+
/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i // Nvidia Tablets
|
|
1471
|
+
], [MODEL, [VENDOR, NVIDIA], [TYPE, TABLET]], [
|
|
1472
|
+
/(sprint) (\w+)/i // Sprint Phones
|
|
1473
|
+
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
|
1474
|
+
/(kin\.[onetw]{3})/i // Microsoft Kin
|
|
1475
|
+
], [[MODEL, /\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [
|
|
1476
|
+
/droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra
|
|
1477
|
+
], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [
|
|
1478
|
+
/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
|
|
1479
|
+
], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [
|
|
1480
|
+
|
|
1481
|
+
///////////////////
|
|
1482
|
+
// SMARTTVS
|
|
1483
|
+
///////////////////
|
|
1484
|
+
|
|
1485
|
+
/smart-tv.+(samsung)/i // Samsung
|
|
1486
|
+
], [VENDOR, [TYPE, SMARTTV]], [
|
|
1487
|
+
/hbbtv.+maple;(\d+)/i
|
|
1488
|
+
], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [
|
|
1489
|
+
/(vizio)(?: |.+model\/)(\w+-\w+)/i, // Vizio
|
|
1490
|
+
/tcast.+(lg)e?. ([-\w]+)/i // LG SmartTV
|
|
1491
|
+
], [VENDOR, MODEL, [TYPE, SMARTTV]], [
|
|
1492
|
+
/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i
|
|
1493
|
+
], [[VENDOR, LG], [TYPE, SMARTTV]], [
|
|
1494
|
+
/(apple) ?tv/i // Apple TV
|
|
1495
|
+
], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
|
|
1496
|
+
/crkey.*devicetype\/chromecast/i // Google Chromecast Third Generation
|
|
1497
|
+
], [[MODEL, CHROMECAST+' Third Generation'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
|
|
1498
|
+
/crkey.*devicetype\/([^/]*)/i // Google Chromecast with specific device type
|
|
1499
|
+
], [[MODEL, /^/, 'Chromecast '], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
|
|
1500
|
+
/fuchsia.*crkey/i // Google Chromecast Nest Hub
|
|
1501
|
+
], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
|
|
1502
|
+
/crkey/i // Google Chromecast, Linux-based or unknown
|
|
1503
|
+
], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
|
|
1504
|
+
/(portaltv)/i // Facebook Portal TV
|
|
1505
|
+
], [MODEL, [VENDOR, FACEBOOK], [TYPE, SMARTTV]], [
|
|
1506
|
+
/droid.+aft(\w+)( bui|\))/i // Fire TV
|
|
1507
|
+
], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
|
|
1508
|
+
/(shield \w+ tv)/i // Nvidia Shield TV
|
|
1509
|
+
], [MODEL, [VENDOR, NVIDIA], [TYPE, SMARTTV]], [
|
|
1510
|
+
/\(dtv[\);].+(aquos)/i,
|
|
1511
|
+
/(aquos-tv[\w ]+)\)/i // Sharp
|
|
1512
|
+
], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[
|
|
1513
|
+
/(bravia[\w ]+)( bui|\))/i // Sony
|
|
1514
|
+
], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [
|
|
1515
|
+
/(mi(tv|box)-?\w+) bui/i // Xiaomi
|
|
1516
|
+
], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [
|
|
1517
|
+
/Hbbtv.*(technisat) (.*);/i // TechniSAT
|
|
1518
|
+
], [VENDOR, MODEL, [TYPE, SMARTTV]], [
|
|
1519
|
+
/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
|
|
1520
|
+
/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
|
|
1521
|
+
], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [
|
|
1522
|
+
// SmartTV from Unidentified Vendors
|
|
1523
|
+
/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i
|
|
1524
|
+
], [MODEL, [TYPE, SMARTTV]], [
|
|
1525
|
+
/\b(android tv|smart[- ]?tv|opera tv|tv; rv:|large screen[\w ]+safari)\b/i
|
|
1526
|
+
], [[TYPE, SMARTTV]], [
|
|
1527
|
+
|
|
1528
|
+
///////////////////
|
|
1529
|
+
// CONSOLES
|
|
1530
|
+
///////////////////
|
|
1531
|
+
|
|
1532
|
+
/(playstation \w+)/i // Playstation
|
|
1533
|
+
], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [
|
|
1534
|
+
/\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox
|
|
1535
|
+
], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [
|
|
1536
|
+
/(ouya)/i, // Ouya
|
|
1537
|
+
/(nintendo) (\w+)/i, // Nintendo
|
|
1538
|
+
/(retroid) (pocket ([^\)]+))/i // Retroid Pocket
|
|
1539
|
+
], [VENDOR, MODEL, [TYPE, CONSOLE]], [
|
|
1540
|
+
/droid.+; (shield)( bui|\))/i // Nvidia Portable
|
|
1541
|
+
], [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]], [
|
|
1542
|
+
|
|
1543
|
+
///////////////////
|
|
1544
|
+
// WEARABLES
|
|
1545
|
+
///////////////////
|
|
1546
|
+
|
|
1547
|
+
/\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i // Samsung Galaxy Watch
|
|
1548
|
+
], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [
|
|
1549
|
+
/((pebble))app/i, // Pebble
|
|
1550
|
+
/(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i // Asus ZenWatch / LG Watch / Pixel Watch
|
|
1551
|
+
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
|
|
1552
|
+
/(ow(?:19|20)?we?[1-3]{1,3})/i // Oppo Watch
|
|
1553
|
+
], [MODEL, [VENDOR, OPPO], [TYPE, WEARABLE]], [
|
|
1554
|
+
/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
|
|
1555
|
+
], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
|
|
1556
|
+
/(opwwe\d{3})/i // OnePlus Watch
|
|
1557
|
+
], [MODEL, [VENDOR, ONEPLUS], [TYPE, WEARABLE]], [
|
|
1558
|
+
/(moto 360)/i // Motorola 360
|
|
1559
|
+
], [MODEL, [VENDOR, MOTOROLA], [TYPE, WEARABLE]], [
|
|
1560
|
+
/(smartwatch 3)/i // Sony SmartWatch
|
|
1561
|
+
], [MODEL, [VENDOR, SONY], [TYPE, WEARABLE]], [
|
|
1562
|
+
/(g watch r)/i // LG G Watch R
|
|
1563
|
+
], [MODEL, [VENDOR, LG], [TYPE, WEARABLE]], [
|
|
1564
|
+
/droid.+; (wt63?0{2,3})\)/i
|
|
1565
|
+
], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
|
|
1566
|
+
|
|
1567
|
+
///////////////////
|
|
1568
|
+
// XR
|
|
1569
|
+
///////////////////
|
|
1570
|
+
|
|
1571
|
+
/droid.+; (glass) \d/i // Google Glass
|
|
1572
|
+
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
|
|
1573
|
+
/(pico) (4|neo3(?: link|pro)?)/i // Pico
|
|
1574
|
+
], [VENDOR, MODEL, [TYPE, XR]], [
|
|
1575
|
+
/(quest( \d| pro)?s?).+vr/i // Meta Quest
|
|
1576
|
+
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
|
|
1577
|
+
/mobile vr; rv.+firefox/i // Unidentifiable VR device using Firefox Reality / Wolvic
|
|
1578
|
+
], [[TYPE, XR]], [
|
|
1579
|
+
|
|
1580
|
+
///////////////////
|
|
1581
|
+
// EMBEDDED
|
|
1582
|
+
///////////////////
|
|
1583
|
+
|
|
1584
|
+
/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla
|
|
1585
|
+
], [VENDOR, [TYPE, EMBEDDED]], [
|
|
1586
|
+
/(aeobc)\b/i // Echo Dot
|
|
1587
|
+
], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [
|
|
1588
|
+
/(homepod).+mac os/i // Apple HomePod
|
|
1589
|
+
], [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]], [
|
|
1590
|
+
/windows iot/i // Unidentifiable embedded device using Windows IoT
|
|
1591
|
+
], [[TYPE, EMBEDDED]], [
|
|
1592
|
+
|
|
1593
|
+
////////////////////
|
|
1594
|
+
// MIXED (GENERIC)
|
|
1595
|
+
///////////////////
|
|
1596
|
+
|
|
1597
|
+
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i
|
|
1598
|
+
], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [
|
|
1599
|
+
/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
|
|
1600
|
+
], [[TYPE, TABLET]], [
|
|
1601
|
+
/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile
|
|
1602
|
+
], [[TYPE, MOBILE]], [
|
|
1603
|
+
/droid .+?; ([\w\. -]+)( bui|\))/i // Generic Android Device
|
|
1604
|
+
], [MODEL, [VENDOR, 'Generic']]
|
|
1605
|
+
],
|
|
1606
|
+
|
|
1607
|
+
engine : [[
|
|
1608
|
+
|
|
1609
|
+
/windows.+ edge\/([\w\.]+)/i // EdgeHTML
|
|
1610
|
+
], [VERSION, [NAME, EDGE+'HTML']], [
|
|
1611
|
+
|
|
1612
|
+
/(arkweb)\/([\w\.]+)/i // ArkWeb
|
|
1613
|
+
], [NAME, VERSION], [
|
|
1614
|
+
|
|
1615
|
+
/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
|
|
1616
|
+
], [VERSION, [NAME, 'Blink']], [
|
|
1617
|
+
|
|
1618
|
+
/(presto)\/([\w\.]+)/i, // Presto
|
|
1619
|
+
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
|
|
1620
|
+
/ekioh(flow)\/([\w\.]+)/i, // Flow
|
|
1621
|
+
/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
|
|
1622
|
+
/(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
|
|
1623
|
+
|
|
1624
|
+
/\b(libweb)/i // LibWeb
|
|
1625
|
+
], [NAME, VERSION], [
|
|
1626
|
+
/ladybird\//i
|
|
1627
|
+
], [[NAME, 'LibWeb']], [
|
|
1628
|
+
|
|
1629
|
+
/rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko
|
|
1630
|
+
], [VERSION, NAME]
|
|
1631
|
+
],
|
|
1632
|
+
|
|
1633
|
+
os : [[
|
|
1634
|
+
|
|
1635
|
+
// Windows
|
|
1636
|
+
/(windows nt) (6\.[23]); arm/i // Windows RT
|
|
1637
|
+
], [[NAME, /N/, 'R'], [VERSION, strMapper, windowsVersionMap]], [
|
|
1638
|
+
/(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i, // Windows IoT/Mobile/Phone
|
|
1639
|
+
// Windows NT/3.1/95/98/ME/2000/XP/Vista/7/8/8.1/10/11
|
|
1640
|
+
/(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i
|
|
1641
|
+
], [NAME, VERSION], [
|
|
1642
|
+
/windows nt ?([\d\.\)]*)(?!.+xbox)/i,
|
|
1643
|
+
/\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i
|
|
1644
|
+
], [[VERSION, /(;|\))/g, '', strMapper, windowsVersionMap], [NAME, WINDOWS]], [
|
|
1645
|
+
/(windows ce)\/?([\d\.]*)/i // Windows CE
|
|
1646
|
+
], [NAME, VERSION], [
|
|
1647
|
+
|
|
1648
|
+
// iOS/macOS
|
|
1649
|
+
/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
|
|
1650
|
+
/(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i,
|
|
1651
|
+
/cfnetwork\/.+darwin/i
|
|
1652
|
+
], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
|
|
1653
|
+
/(mac os x) ?([\w\. ]*)/i,
|
|
1654
|
+
/(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i // Mac OS
|
|
1655
|
+
], [[NAME, 'macOS'], [VERSION, /_/g, '.']], [
|
|
1656
|
+
|
|
1657
|
+
// Google Chromecast
|
|
1658
|
+
/android ([\d\.]+).*crkey/i // Google Chromecast, Android-based
|
|
1659
|
+
], [VERSION, [NAME, CHROMECAST + ' Android']], [
|
|
1660
|
+
/fuchsia.*crkey\/([\d\.]+)/i // Google Chromecast, Fuchsia-based
|
|
1661
|
+
], [VERSION, [NAME, CHROMECAST + ' Fuchsia']], [
|
|
1662
|
+
/crkey\/([\d\.]+).*devicetype\/smartspeaker/i // Google Chromecast, Linux-based Smart Speaker
|
|
1663
|
+
], [VERSION, [NAME, CHROMECAST + ' SmartSpeaker']], [
|
|
1664
|
+
/linux.*crkey\/([\d\.]+)/i // Google Chromecast, Legacy Linux-based
|
|
1665
|
+
], [VERSION, [NAME, CHROMECAST + ' Linux']], [
|
|
1666
|
+
/crkey\/([\d\.]+)/i // Google Chromecast, unknown
|
|
1667
|
+
], [VERSION, [NAME, CHROMECAST]], [
|
|
1668
|
+
|
|
1669
|
+
// Mobile OSes
|
|
1670
|
+
/droid ([\w\.]+)\b.+(android[- ]x86)/i // Android-x86
|
|
1671
|
+
], [VERSION, NAME], [
|
|
1672
|
+
/(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch
|
|
1673
|
+
], [[NAME, /(.+)/, '$1 Touch'], VERSION], [
|
|
1674
|
+
/(harmonyos)[\/ ]?([\d\.]*)/i, // HarmonyOS
|
|
1675
|
+
// Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen
|
|
1676
|
+
/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i
|
|
1677
|
+
], [NAME, VERSION], [
|
|
1678
|
+
/\(bb(10);/i // BlackBerry 10
|
|
1679
|
+
], [VERSION, [NAME, BLACKBERRY]], [
|
|
1680
|
+
/(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i // Symbian
|
|
1681
|
+
], [VERSION, [NAME, 'Symbian']], [
|
|
1682
|
+
/mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS
|
|
1683
|
+
], [VERSION, [NAME, FIREFOX+' OS']], [
|
|
1684
|
+
/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i, // WebOS
|
|
1685
|
+
/webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i
|
|
1686
|
+
], [VERSION, [NAME, 'webOS']], [
|
|
1687
|
+
/web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i
|
|
1688
|
+
// https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine
|
|
1689
|
+
], [[VERSION, strMapper, {'25':'120','24':'108','23':'94','22':'87','6':'79','5':'68','4':'53','3':'38','2':'538','1':'537','*':'TV'}], [NAME, 'webOS']], [
|
|
1690
|
+
/watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
|
|
1691
|
+
], [VERSION, [NAME, 'watchOS']], [
|
|
1692
|
+
|
|
1693
|
+
// Google ChromeOS
|
|
1694
|
+
/(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
|
|
1695
|
+
], [[NAME, "Chrome OS"], VERSION],[
|
|
1696
|
+
|
|
1697
|
+
// Smart TVs
|
|
1698
|
+
/panasonic;(viera)/i, // Panasonic Viera
|
|
1699
|
+
/(netrange)mmh/i, // Netrange
|
|
1700
|
+
/(nettv)\/(\d+\.[\w\.]+)/i, // NetTV
|
|
1701
|
+
|
|
1702
|
+
// Console
|
|
1703
|
+
/(nintendo|playstation) (\w+)/i, // Nintendo/Playstation
|
|
1704
|
+
/(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
|
|
1705
|
+
/(pico) .+os([\w\.]+)/i, // Pico
|
|
1706
|
+
|
|
1707
|
+
// Other
|
|
1708
|
+
/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
|
|
1709
|
+
/linux.+(mint)[\/\(\) ]?([\w\.]*)/i, // Mint
|
|
1710
|
+
/(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i, // Mageia/VectorLinux/Fuchsia/ArcaOS/Arch
|
|
1711
|
+
/([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
|
|
1712
|
+
// Ubuntu/Debian/SUSE/Gentoo/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire/Knoppix
|
|
1713
|
+
/((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris
|
|
1714
|
+
/\b(aix)[; ]([1-9\.]{0,4})/i, // AIX
|
|
1715
|
+
/(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i, // Hurd/Linux/MorphOS
|
|
1716
|
+
/(gnu) ?([\w\.]*)/i, // GNU
|
|
1717
|
+
/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
|
|
1718
|
+
/(haiku) ?(r\d)?/i // Haiku
|
|
1719
|
+
], [NAME, VERSION], [
|
|
1720
|
+
/(sunos) ?([\d\.]*)/i // Solaris
|
|
1721
|
+
], [[NAME, 'Solaris'], VERSION], [
|
|
1722
|
+
/\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/OpenVMS/HP-UX/SerenityOS
|
|
1723
|
+
/(unix) ?([\w\.]*)/i // UNIX
|
|
1724
|
+
], [NAME, VERSION]
|
|
1725
|
+
]
|
|
1726
|
+
};
|
|
1727
|
+
|
|
1728
|
+
/////////////////
|
|
1729
|
+
// Factories
|
|
1730
|
+
////////////////
|
|
1731
|
+
|
|
1732
|
+
var defaultProps = (function () {
|
|
1733
|
+
var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
|
|
1734
|
+
setProps.call(props.init, [
|
|
1735
|
+
[UA_BROWSER, [NAME, VERSION, MAJOR, TYPE]],
|
|
1736
|
+
[UA_CPU, [ARCHITECTURE]],
|
|
1737
|
+
[UA_DEVICE, [TYPE, MODEL, VENDOR]],
|
|
1738
|
+
[UA_ENGINE, [NAME, VERSION]],
|
|
1739
|
+
[UA_OS, [NAME, VERSION]]
|
|
1740
|
+
]);
|
|
1741
|
+
setProps.call(props.isIgnore, [
|
|
1742
|
+
[UA_BROWSER, [VERSION, MAJOR]],
|
|
1743
|
+
[UA_ENGINE, [VERSION]],
|
|
1744
|
+
[UA_OS, [VERSION]]
|
|
1745
|
+
]);
|
|
1746
|
+
setProps.call(props.isIgnoreRgx, [
|
|
1747
|
+
[UA_BROWSER, / ?browser$/i],
|
|
1748
|
+
[UA_OS, / ?os$/i]
|
|
1749
|
+
]);
|
|
1750
|
+
setProps.call(props.toString, [
|
|
1751
|
+
[UA_BROWSER, [NAME, VERSION]],
|
|
1752
|
+
[UA_CPU, [ARCHITECTURE]],
|
|
1753
|
+
[UA_DEVICE, [VENDOR, MODEL]],
|
|
1754
|
+
[UA_ENGINE, [NAME, VERSION]],
|
|
1755
|
+
[UA_OS, [NAME, VERSION]]
|
|
1756
|
+
]);
|
|
1757
|
+
return props;
|
|
1758
|
+
})();
|
|
1759
|
+
|
|
1760
|
+
var createIData = function (item, itemType) {
|
|
1761
|
+
|
|
1762
|
+
var init_props = defaultProps.init[itemType],
|
|
1763
|
+
is_ignoreProps = defaultProps.isIgnore[itemType] || 0,
|
|
1764
|
+
is_ignoreRgx = defaultProps.isIgnoreRgx[itemType] || 0,
|
|
1765
|
+
toString_props = defaultProps.toString[itemType] || 0;
|
|
1766
|
+
|
|
1767
|
+
function IData () {
|
|
1768
|
+
setProps.call(this, init_props);
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
IData.prototype.getItem = function () {
|
|
1772
|
+
return item;
|
|
1773
|
+
};
|
|
1774
|
+
|
|
1775
|
+
IData.prototype.withClientHints = function () {
|
|
1776
|
+
|
|
1777
|
+
// nodejs / non-client-hints browsers
|
|
1778
|
+
if (!NAVIGATOR_UADATA) {
|
|
1779
|
+
return item
|
|
1780
|
+
.parseCH()
|
|
1781
|
+
.get();
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
// browsers based on chromium 85+
|
|
1785
|
+
return NAVIGATOR_UADATA
|
|
1786
|
+
.getHighEntropyValues(CH_ALL_VALUES)
|
|
1787
|
+
.then(function (res) {
|
|
1788
|
+
return item
|
|
1789
|
+
.setCH(new UACHData(res, false))
|
|
1790
|
+
.parseCH()
|
|
1791
|
+
.get();
|
|
1792
|
+
});
|
|
1793
|
+
};
|
|
1794
|
+
|
|
1795
|
+
IData.prototype.withFeatureCheck = function () {
|
|
1796
|
+
return item.detectFeature().get();
|
|
1797
|
+
};
|
|
1798
|
+
|
|
1799
|
+
if (itemType != UA_RESULT) {
|
|
1800
|
+
IData.prototype.is = function (strToCheck) {
|
|
1801
|
+
var is = false;
|
|
1802
|
+
for (var i in this) {
|
|
1803
|
+
if (this.hasOwnProperty(i) && !has(is_ignoreProps, i) && lowerize(is_ignoreRgx ? strip(is_ignoreRgx, this[i]) : this[i]) == lowerize(is_ignoreRgx ? strip(is_ignoreRgx, strToCheck) : strToCheck)) {
|
|
1804
|
+
is = true;
|
|
1805
|
+
if (strToCheck != UNDEF_TYPE) break;
|
|
1806
|
+
} else if (strToCheck == UNDEF_TYPE && is) {
|
|
1807
|
+
is = !is;
|
|
1808
|
+
break;
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
return is;
|
|
1812
|
+
};
|
|
1813
|
+
IData.prototype.toString = function () {
|
|
1814
|
+
var str = EMPTY;
|
|
1815
|
+
for (var i in toString_props) {
|
|
1816
|
+
if (typeof(this[toString_props[i]]) !== UNDEF_TYPE) {
|
|
1817
|
+
str += (str ? ' ' : EMPTY) + this[toString_props[i]];
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
return str || UNDEF_TYPE;
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
if (!NAVIGATOR_UADATA) {
|
|
1825
|
+
IData.prototype.then = function (cb) {
|
|
1826
|
+
var that = this;
|
|
1827
|
+
var IDataResolve = function () {
|
|
1828
|
+
for (var prop in that) {
|
|
1829
|
+
if (that.hasOwnProperty(prop)) {
|
|
1830
|
+
this[prop] = that[prop];
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
};
|
|
1834
|
+
IDataResolve.prototype = {
|
|
1835
|
+
is : IData.prototype.is,
|
|
1836
|
+
toString : IData.prototype.toString
|
|
1837
|
+
};
|
|
1838
|
+
var resolveData = new IDataResolve();
|
|
1839
|
+
cb(resolveData);
|
|
1840
|
+
return resolveData;
|
|
1841
|
+
};
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
return new IData();
|
|
1845
|
+
};
|
|
1846
|
+
|
|
1847
|
+
/////////////////
|
|
1848
|
+
// Constructor
|
|
1849
|
+
////////////////
|
|
1850
|
+
|
|
1851
|
+
function UACHData (uach, isHttpUACH) {
|
|
1852
|
+
uach = uach || {};
|
|
1853
|
+
setProps.call(this, CH_ALL_VALUES);
|
|
1854
|
+
if (isHttpUACH) {
|
|
1855
|
+
setProps.call(this, [
|
|
1856
|
+
[BRANDS, itemListToArray(uach[CH_HEADER])],
|
|
1857
|
+
[FULLVERLIST, itemListToArray(uach[CH_HEADER_FULL_VER_LIST])],
|
|
1858
|
+
[MOBILE, /\?1/.test(uach[CH_HEADER_MOBILE])],
|
|
1859
|
+
[MODEL, stripQuotes(uach[CH_HEADER_MODEL])],
|
|
1860
|
+
[PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
|
|
1861
|
+
[PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
|
|
1862
|
+
[ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
|
|
1863
|
+
[FORMFACTORS, itemListToArray(uach[CH_HEADER_FORM_FACTORS])],
|
|
1864
|
+
[BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
|
|
1865
|
+
]);
|
|
1866
|
+
} else {
|
|
1867
|
+
for (var prop in uach) {
|
|
1868
|
+
if(this.hasOwnProperty(prop) && typeof uach[prop] !== UNDEF_TYPE) this[prop] = uach[prop];
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
function UAItem (itemType, ua, rgxMap, uaCH) {
|
|
1874
|
+
|
|
1875
|
+
this.get = function (prop) {
|
|
1876
|
+
if (!prop) return this.data;
|
|
1877
|
+
return this.data.hasOwnProperty(prop) ? this.data[prop] : undefined;
|
|
1878
|
+
};
|
|
1879
|
+
|
|
1880
|
+
this.set = function (prop, val) {
|
|
1881
|
+
this.data[prop] = val;
|
|
1882
|
+
return this;
|
|
1883
|
+
};
|
|
1884
|
+
|
|
1885
|
+
this.setCH = function (ch) {
|
|
1886
|
+
this.uaCH = ch;
|
|
1887
|
+
return this;
|
|
1888
|
+
};
|
|
1889
|
+
|
|
1890
|
+
this.detectFeature = function () {
|
|
1891
|
+
if (NAVIGATOR && NAVIGATOR.userAgent == this.ua) {
|
|
1892
|
+
switch (this.itemType) {
|
|
1893
|
+
case UA_BROWSER:
|
|
1894
|
+
// Brave-specific detection
|
|
1895
|
+
if (NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == FUNC_TYPE) {
|
|
1896
|
+
this.set(NAME, 'Brave');
|
|
1897
|
+
}
|
|
1898
|
+
break;
|
|
1899
|
+
case UA_DEVICE:
|
|
1900
|
+
// Chrome-specific detection: check for 'mobile' value of navigator.userAgentData
|
|
1901
|
+
if (!this.get(TYPE) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[MOBILE]) {
|
|
1902
|
+
this.set(TYPE, MOBILE);
|
|
1903
|
+
}
|
|
1904
|
+
// iPadOS-specific detection: identified as Mac, but has some iOS-only properties
|
|
1905
|
+
if (this.get(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== UNDEF_TYPE && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) {
|
|
1906
|
+
this.set(MODEL, 'iPad')
|
|
1907
|
+
.set(TYPE, TABLET);
|
|
1908
|
+
}
|
|
1909
|
+
break;
|
|
1910
|
+
case UA_OS:
|
|
1911
|
+
// Chrome-specific detection: check for 'platform' value of navigator.userAgentData
|
|
1912
|
+
if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) {
|
|
1913
|
+
this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
|
|
1914
|
+
}
|
|
1915
|
+
break;
|
|
1916
|
+
case UA_RESULT:
|
|
1917
|
+
var data = this.data;
|
|
1918
|
+
var detect = function (itemType) {
|
|
1919
|
+
return data[itemType]
|
|
1920
|
+
.getItem()
|
|
1921
|
+
.detectFeature()
|
|
1922
|
+
.get();
|
|
1923
|
+
};
|
|
1924
|
+
this.set(UA_BROWSER, detect(UA_BROWSER))
|
|
1925
|
+
.set(UA_CPU, detect(UA_CPU))
|
|
1926
|
+
.set(UA_DEVICE, detect(UA_DEVICE))
|
|
1927
|
+
.set(UA_ENGINE, detect(UA_ENGINE))
|
|
1928
|
+
.set(UA_OS, detect(UA_OS));
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
return this;
|
|
1932
|
+
};
|
|
1933
|
+
|
|
1934
|
+
this.parseUA = function () {
|
|
1935
|
+
if (this.itemType != UA_RESULT) {
|
|
1936
|
+
rgxMapper.call(this.data, this.ua, this.rgxMap);
|
|
1937
|
+
}
|
|
1938
|
+
if (this.itemType == UA_BROWSER) {
|
|
1939
|
+
this.set(MAJOR, majorize(this.get(VERSION)));
|
|
1940
|
+
}
|
|
1941
|
+
return this;
|
|
1942
|
+
};
|
|
1943
|
+
|
|
1944
|
+
this.parseCH = function () {
|
|
1945
|
+
var uaCH = this.uaCH,
|
|
1946
|
+
rgxMap = this.rgxMap;
|
|
1947
|
+
|
|
1948
|
+
switch (this.itemType) {
|
|
1949
|
+
case UA_BROWSER:
|
|
1950
|
+
case UA_ENGINE:
|
|
1951
|
+
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
|
|
1952
|
+
if (brands) {
|
|
1953
|
+
for (var i in brands) {
|
|
1954
|
+
var brandName = brands[i].brand || brands[i],
|
|
1955
|
+
brandVersion = brands[i].version;
|
|
1956
|
+
if (this.itemType == UA_BROWSER &&
|
|
1957
|
+
!/not.a.brand/i.test(brandName) &&
|
|
1958
|
+
(!prevName ||
|
|
1959
|
+
(/Chrom/.test(prevName) && brandName != CHROMIUM) ||
|
|
1960
|
+
(prevName == EDGE && /WebView2/.test(brandName))
|
|
1961
|
+
)) {
|
|
1962
|
+
brandName = strMapper(brandName, browserHintsMap);
|
|
1963
|
+
prevName = this.get(NAME);
|
|
1964
|
+
if (!(prevName && !/Chrom/.test(prevName) && /Chrom/.test(brandName))) {
|
|
1965
|
+
this.set(NAME, brandName)
|
|
1966
|
+
.set(VERSION, brandVersion)
|
|
1967
|
+
.set(MAJOR, majorize(brandVersion));
|
|
1968
|
+
}
|
|
1969
|
+
prevName = brandName;
|
|
1970
|
+
}
|
|
1971
|
+
if (this.itemType == UA_ENGINE && brandName == CHROMIUM) {
|
|
1972
|
+
this.set(VERSION, brandVersion);
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
break;
|
|
1977
|
+
case UA_CPU:
|
|
1978
|
+
var archName = uaCH[ARCHITECTURE];
|
|
1979
|
+
if (archName) {
|
|
1980
|
+
if (archName && uaCH[BITNESS] == '64') archName += '64';
|
|
1981
|
+
rgxMapper.call(this.data, archName + ';', rgxMap);
|
|
1982
|
+
}
|
|
1983
|
+
break;
|
|
1984
|
+
case UA_DEVICE:
|
|
1985
|
+
if (uaCH[MOBILE]) {
|
|
1986
|
+
this.set(TYPE, MOBILE);
|
|
1987
|
+
}
|
|
1988
|
+
if (uaCH[MODEL]) {
|
|
1989
|
+
this.set(MODEL, uaCH[MODEL]);
|
|
1990
|
+
if (!this.get(TYPE) || !this.get(VENDOR)) {
|
|
1991
|
+
var reParse = {};
|
|
1992
|
+
rgxMapper.call(reParse, 'droid 9; ' + uaCH[MODEL] + ')', rgxMap);
|
|
1993
|
+
if (!this.get(TYPE) && !!reParse.type) {
|
|
1994
|
+
this.set(TYPE, reParse.type);
|
|
1995
|
+
}
|
|
1996
|
+
if (!this.get(VENDOR) && !!reParse.vendor) {
|
|
1997
|
+
this.set(VENDOR, reParse.vendor);
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
if (uaCH[FORMFACTORS]) {
|
|
2002
|
+
var ff;
|
|
2003
|
+
if (typeof uaCH[FORMFACTORS] !== 'string') {
|
|
2004
|
+
var idx = 0;
|
|
2005
|
+
while (!ff && idx < uaCH[FORMFACTORS].length) {
|
|
2006
|
+
ff = strMapper(uaCH[FORMFACTORS][idx++], formFactorsMap);
|
|
2007
|
+
}
|
|
2008
|
+
} else {
|
|
2009
|
+
ff = strMapper(uaCH[FORMFACTORS], formFactorsMap);
|
|
2010
|
+
}
|
|
2011
|
+
this.set(TYPE, ff);
|
|
2012
|
+
}
|
|
2013
|
+
break;
|
|
2014
|
+
case UA_OS:
|
|
2015
|
+
var osName = uaCH[PLATFORM];
|
|
2016
|
+
if(osName) {
|
|
2017
|
+
var osVersion = uaCH[PLATFORMVER];
|
|
2018
|
+
if (osName == WINDOWS) osVersion = (parseInt(majorize(osVersion), 10) >= 13 ? '11' : '10');
|
|
2019
|
+
this.set(NAME, osName)
|
|
2020
|
+
.set(VERSION, osVersion);
|
|
2021
|
+
}
|
|
2022
|
+
// Xbox-Specific Detection
|
|
2023
|
+
if (this.get(NAME) == WINDOWS && uaCH[MODEL] == 'Xbox') {
|
|
2024
|
+
this.set(NAME, 'Xbox')
|
|
2025
|
+
.set(VERSION, undefined);
|
|
2026
|
+
}
|
|
2027
|
+
break;
|
|
2028
|
+
case UA_RESULT:
|
|
2029
|
+
var data = this.data;
|
|
2030
|
+
var parse = function (itemType) {
|
|
2031
|
+
return data[itemType]
|
|
2032
|
+
.getItem()
|
|
2033
|
+
.setCH(uaCH)
|
|
2034
|
+
.parseCH()
|
|
2035
|
+
.get();
|
|
2036
|
+
};
|
|
2037
|
+
this.set(UA_BROWSER, parse(UA_BROWSER))
|
|
2038
|
+
.set(UA_CPU, parse(UA_CPU))
|
|
2039
|
+
.set(UA_DEVICE, parse(UA_DEVICE))
|
|
2040
|
+
.set(UA_ENGINE, parse(UA_ENGINE))
|
|
2041
|
+
.set(UA_OS, parse(UA_OS));
|
|
2042
|
+
}
|
|
2043
|
+
return this;
|
|
2044
|
+
};
|
|
2045
|
+
|
|
2046
|
+
setProps.call(this, [
|
|
2047
|
+
['itemType', itemType],
|
|
2048
|
+
['ua', ua],
|
|
2049
|
+
['uaCH', uaCH],
|
|
2050
|
+
['rgxMap', rgxMap],
|
|
2051
|
+
['data', createIData(this, itemType)]
|
|
2052
|
+
]);
|
|
2053
|
+
|
|
2054
|
+
return this;
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
function UAParser (ua, extensions, headers) {
|
|
2058
|
+
|
|
2059
|
+
if (typeof ua === OBJ_TYPE) {
|
|
2060
|
+
if (isExtensions(ua, true)) {
|
|
2061
|
+
if (typeof extensions === OBJ_TYPE) {
|
|
2062
|
+
headers = extensions; // case UAParser(extensions, headers)
|
|
2063
|
+
}
|
|
2064
|
+
extensions = ua; // case UAParser(extensions)
|
|
2065
|
+
} else {
|
|
2066
|
+
headers = ua; // case UAParser(headers)
|
|
2067
|
+
extensions = undefined;
|
|
2068
|
+
}
|
|
2069
|
+
ua = undefined;
|
|
2070
|
+
} else if (typeof ua === STR_TYPE && !isExtensions(extensions, true)) {
|
|
2071
|
+
headers = extensions; // case UAParser(ua, headers)
|
|
2072
|
+
extensions = undefined;
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
// Convert Headers object into a plain object
|
|
2076
|
+
if (headers && typeof headers.append === FUNC_TYPE) {
|
|
2077
|
+
var kv = {};
|
|
2078
|
+
headers.forEach(function (v, k) { kv[k] = v; });
|
|
2079
|
+
headers = kv;
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
if (!(this instanceof UAParser)) {
|
|
2083
|
+
return new UAParser(ua, extensions, headers).getResult();
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string
|
|
2087
|
+
(headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
|
|
2088
|
+
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
|
|
2089
|
+
EMPTY)), // empty string
|
|
2090
|
+
|
|
2091
|
+
httpUACH = new UACHData(headers, true),
|
|
2092
|
+
regexMap = extensions ?
|
|
2093
|
+
extend(defaultRegexes, extensions) :
|
|
2094
|
+
defaultRegexes,
|
|
2095
|
+
|
|
2096
|
+
createItemFunc = function (itemType) {
|
|
2097
|
+
if (itemType == UA_RESULT) {
|
|
2098
|
+
return function () {
|
|
2099
|
+
return new UAItem(itemType, userAgent, regexMap, httpUACH)
|
|
2100
|
+
.set('ua', userAgent)
|
|
2101
|
+
.set(UA_BROWSER, this.getBrowser())
|
|
2102
|
+
.set(UA_CPU, this.getCPU())
|
|
2103
|
+
.set(UA_DEVICE, this.getDevice())
|
|
2104
|
+
.set(UA_ENGINE, this.getEngine())
|
|
2105
|
+
.set(UA_OS, this.getOS())
|
|
2106
|
+
.get();
|
|
2107
|
+
};
|
|
2108
|
+
} else {
|
|
2109
|
+
return function () {
|
|
2110
|
+
return new UAItem(itemType, userAgent, regexMap[itemType], httpUACH)
|
|
2111
|
+
.parseUA()
|
|
2112
|
+
.get();
|
|
2113
|
+
};
|
|
2114
|
+
}
|
|
2115
|
+
};
|
|
2116
|
+
|
|
2117
|
+
// public methods
|
|
2118
|
+
setProps.call(this, [
|
|
2119
|
+
['getBrowser', createItemFunc(UA_BROWSER)],
|
|
2120
|
+
['getCPU', createItemFunc(UA_CPU)],
|
|
2121
|
+
['getDevice', createItemFunc(UA_DEVICE)],
|
|
2122
|
+
['getEngine', createItemFunc(UA_ENGINE)],
|
|
2123
|
+
['getOS', createItemFunc(UA_OS)],
|
|
2124
|
+
['getResult', createItemFunc(UA_RESULT)],
|
|
2125
|
+
['getUA', function () { return userAgent; }],
|
|
2126
|
+
['setUA', function (ua) {
|
|
2127
|
+
if (isString(ua))
|
|
2128
|
+
userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua;
|
|
2129
|
+
return this;
|
|
2130
|
+
}]
|
|
2131
|
+
])
|
|
2132
|
+
.setUA(userAgent);
|
|
2133
|
+
|
|
2134
|
+
return this;
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
UAParser.VERSION = LIBVERSION;
|
|
2138
|
+
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR, TYPE]);
|
|
2139
|
+
UAParser.CPU = enumerize([ARCHITECTURE]);
|
|
2140
|
+
UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
|
|
2141
|
+
UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
|
|
2142
|
+
|
|
2143
|
+
const MobileContext = React.createContext(undefined);
|
|
2144
|
+
const detectMobile = (userAgent) => {
|
|
2145
|
+
const parser = new UAParser();
|
|
2146
|
+
parser.setUA(userAgent);
|
|
2147
|
+
const device = parser.getDevice();
|
|
2148
|
+
// Consider mobile and tablet devices as mobile
|
|
2149
|
+
return device.type === 'mobile' || device.type === 'tablet';
|
|
2150
|
+
};
|
|
2151
|
+
const MobileProvider = ({ userAgent, children, }) => {
|
|
2152
|
+
const isMobile = detectMobile(userAgent);
|
|
2153
|
+
const value = React.useMemo(() => ({
|
|
2154
|
+
isMobile,
|
|
2155
|
+
userAgent,
|
|
2156
|
+
}), [isMobile, userAgent]);
|
|
2157
|
+
return (jsxRuntimeExports.jsx(MobileContext.Provider, { value: value, children: children }));
|
|
2158
|
+
};
|
|
2159
|
+
const useMobile = (isMobile) => {
|
|
2160
|
+
// const context = useContext(MobileContext);
|
|
2161
|
+
// if (context === undefined) {
|
|
2162
|
+
// throw new Error('useMobile must be used within a MobileProvider');
|
|
2163
|
+
// }
|
|
2164
|
+
const context = {
|
|
2165
|
+
isMobile: isMobile || false,
|
|
2166
|
+
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1',
|
|
2167
|
+
};
|
|
2168
|
+
return context;
|
|
2169
|
+
};
|
|
2170
|
+
|
|
2171
|
+
const Input$1 = React.forwardRef(({ state = 'default', label, value, onChange, helperText, startIcon, endIcon, type = 'text', ...props }, ref) => {
|
|
2172
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
2173
|
+
const id = React.useId();
|
|
2174
|
+
const hasContent = value !== '' && value !== null && value !== undefined;
|
|
2175
|
+
const isLabelFloated = isFocused || hasContent;
|
|
2176
|
+
const isDisabled = state === 'disabled';
|
|
2177
|
+
const { isMobile } = useMobile();
|
|
2178
|
+
const handleFocus = (e) => {
|
|
2179
|
+
if (!isDisabled) {
|
|
2180
|
+
setIsFocused(true);
|
|
2181
|
+
props.onFocus?.(e);
|
|
2182
|
+
}
|
|
2183
|
+
};
|
|
2184
|
+
const handleBlur = (e) => {
|
|
2185
|
+
if (!isDisabled) {
|
|
2186
|
+
setIsFocused(false);
|
|
2187
|
+
props.onBlur?.(e);
|
|
2188
|
+
}
|
|
2189
|
+
};
|
|
2190
|
+
const baseContainerClasses = 'relative flex items-center border rounded-lg transition-all duration-300 w-[360px]';
|
|
2191
|
+
const baseLabelClasses = 'absolute pointer-events-none transition-all duration-300';
|
|
2192
|
+
const baseInputClasses = 'peer w-full h-full bg-transparent outline-none text-m font-medium disabled:text-neutral-light';
|
|
2193
|
+
const baseIconClasses = 'absolute h-5 w-5 transition-colors duration-300';
|
|
2194
|
+
const containerClasses = cn(baseContainerClasses, {
|
|
2195
|
+
'h-[54px]': !isMobile,
|
|
2196
|
+
'h-12': isMobile,
|
|
2197
|
+
'border-neutral-light': state === 'default' && !isFocused,
|
|
2198
|
+
'border-primary': state === 'default' && isFocused,
|
|
2199
|
+
'border-error': state === 'error',
|
|
2200
|
+
'bg-white border-neutral-light cursor-not-allowed': isDisabled,
|
|
2201
|
+
});
|
|
2202
|
+
const labelClasses = cn(baseLabelClasses, {
|
|
2203
|
+
'top-[-10px] bg-white px-1 mx-3 font-medium': isLabelFloated,
|
|
2204
|
+
'text-s': (!isMobile && isLabelFloated) || (isMobile && !isLabelFloated),
|
|
2205
|
+
'text-xs': isMobile && isLabelFloated,
|
|
2206
|
+
'text-m': !isMobile && !isLabelFloated,
|
|
2207
|
+
'right-1': startIcon,
|
|
2208
|
+
'right-3': !startIcon,
|
|
2209
|
+
'top-1/2 -translate-y-1/2 text-m font-medium': !isLabelFloated,
|
|
2210
|
+
'right-11': !isLabelFloated && startIcon,
|
|
2211
|
+
'right-4': !isLabelFloated && !startIcon,
|
|
2212
|
+
'text-neutral-main': !isFocused && state === 'default',
|
|
2213
|
+
'text-neutral-light': isDisabled,
|
|
2214
|
+
'text-primary': isFocused && state === 'default',
|
|
2215
|
+
'text-error': isLabelFloated && state === 'error',
|
|
2216
|
+
});
|
|
2217
|
+
const inputClasses = cn(baseInputClasses, {
|
|
2218
|
+
'pr-12': startIcon,
|
|
2219
|
+
'pl-12': endIcon,
|
|
2220
|
+
'px-4': !startIcon && !endIcon,
|
|
2221
|
+
'pr-4 pl-12': !startIcon && endIcon,
|
|
2222
|
+
'pl-4 pr-12': startIcon && !endIcon,
|
|
2223
|
+
'cursor-not-allowed text-red-500': isDisabled,
|
|
2224
|
+
'text-neutral-dark': !isFocused,
|
|
2225
|
+
'text-neutral-darker': isFocused,
|
|
2226
|
+
});
|
|
2227
|
+
const iconClasses = cn(baseIconClasses, {
|
|
2228
|
+
'text-neutral-main': state !== 'error' && !isFocused,
|
|
2229
|
+
'text-primary': state === 'default' && isFocused,
|
|
2230
|
+
'text-error': state === 'error',
|
|
2231
|
+
'text-neutral-light': isDisabled,
|
|
2232
|
+
});
|
|
2233
|
+
const helperTextClasses = cn('font-light mt-1 px-2 h-4', {
|
|
2234
|
+
'text-s': !isMobile,
|
|
2235
|
+
'text-xs': isMobile,
|
|
2236
|
+
'text-neutral-main': state === 'default',
|
|
2237
|
+
'text-primary': state === 'default' && isFocused,
|
|
2238
|
+
'text-error': state === 'error',
|
|
2239
|
+
'text-neutral-light': isDisabled,
|
|
2240
|
+
});
|
|
2241
|
+
return (jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsxs("div", { className: containerClasses, children: [endIcon && (jsxRuntimeExports.jsx("span", { className: cn(iconClasses, 'left-4'), children: endIcon })), jsxRuntimeExports.jsx("label", { htmlFor: id, className: labelClasses, children: label }), jsxRuntimeExports.jsx("input", { ref: ref, id: id, type: type, value: value, onChange: onChange, onFocus: handleFocus, onBlur: handleBlur, disabled: isDisabled, className: inputClasses, ...props }), startIcon && (jsxRuntimeExports.jsx("span", { className: cn(iconClasses, 'right-4'), children: startIcon }))] }), helperText && jsxRuntimeExports.jsx("p", { className: helperTextClasses, children: helperText })] }));
|
|
2242
|
+
});
|
|
2243
|
+
Input$1.displayName = 'Input';
|
|
2244
|
+
|
|
2245
|
+
// Helper functions moved outside component
|
|
2246
|
+
const handleTabClick = (tabId, disabled, onTabChange) => {
|
|
2247
|
+
if (!disabled) {
|
|
2248
|
+
onTabChange(tabId);
|
|
2249
|
+
}
|
|
2250
|
+
};
|
|
2251
|
+
const handleKeyDown = (e, tabId, disabled, onTabChange) => {
|
|
2252
|
+
if ((e.key === 'Enter' || e.key === ' ') && !disabled) {
|
|
2253
|
+
e.preventDefault();
|
|
2254
|
+
onTabChange(tabId);
|
|
2255
|
+
}
|
|
2256
|
+
};
|
|
2257
|
+
const renderBadge = (count, isActive, disabled, isMobile) => {
|
|
2258
|
+
if (count === undefined)
|
|
2259
|
+
return null;
|
|
2260
|
+
return (jsxRuntimeExports.jsx("div", { className: cn('flex items-center justify-center rounded-[5px] font-sans font-bold text-white', 'transition-colors duration-200', isMobile
|
|
2261
|
+
? 'size-6 text-[14px] pt-0.5'
|
|
2262
|
+
: 'size-[25px] text-[14px] pt-[3px]', disabled ? 'bg-midnight' : isActive ? 'bg-primary' : 'bg-neutral-main'), children: jsxRuntimeExports.jsx("p", { className: "leading-[24px] whitespace-pre", dir: "auto", children: count }) }));
|
|
2263
|
+
};
|
|
2264
|
+
const renderTabContent = (item, isActive, isMobile) => {
|
|
2265
|
+
const hasCount = item.count !== undefined;
|
|
2266
|
+
return (jsxRuntimeExports.jsxs("div", { className: cn('flex flex-row items-center justify-start transition-colors duration-200', isMobile ? 'gap-1.5' : 'gap-1.5'), children: [hasCount && renderBadge(item.count, isActive, item.disabled, isMobile), jsxRuntimeExports.jsx("div", { className: cn('font-sans text-nowrap text-right transition-colors duration-200', isMobile ? 'text-[14px]' : isActive ? 'text-[16px]' : 'text-[18px]', item.disabled
|
|
2267
|
+
? 'font-normal text-midnight'
|
|
2268
|
+
: isActive
|
|
2269
|
+
? 'font-bold text-primary'
|
|
2270
|
+
: 'font-normal text-neutral-main', isMobile
|
|
2271
|
+
? 'leading-[24px]'
|
|
2272
|
+
: isActive
|
|
2273
|
+
? 'leading-normal'
|
|
2274
|
+
: 'leading-[1.9]'), children: jsxRuntimeExports.jsx("p", { className: "whitespace-pre", dir: "auto", children: item.label }) })] }));
|
|
2275
|
+
};
|
|
2276
|
+
const renderTab = (item, activeTab, isMobile, onTabChange) => {
|
|
2277
|
+
const isActive = item.id === activeTab;
|
|
2278
|
+
return (jsxRuntimeExports.jsxs("div", { className: cn('box-border flex flex-col items-center justify-between relative shrink-0', 'cursor-pointer transition-all duration-200', isMobile ? 'h-12 px-3' : 'h-14 px-4', isActive
|
|
2279
|
+
? isMobile
|
|
2280
|
+
? 'pt-[11px] pb-0'
|
|
2281
|
+
: 'pt-3.5 pb-0'
|
|
2282
|
+
: 'py-0 justify-center', item.disabled && 'cursor-not-allowed opacity-50', !item.disabled && 'hover:opacity-80'), onClick: () => handleTabClick(item.id, item.disabled, onTabChange), onKeyDown: (e) => handleKeyDown(e, item.id, item.disabled, onTabChange), tabIndex: item.disabled ? -1 : 0, role: "tab", "aria-selected": isActive, "aria-disabled": item.disabled, children: [renderTabContent(item, isActive, isMobile), isActive && (jsxRuntimeExports.jsx("div", { className: "bg-primary h-1 rounded-tl-[8px] rounded-tr-[8px] shrink-0 w-full" }))] }, item.id));
|
|
2283
|
+
};
|
|
2284
|
+
const Tabs$1 = React.forwardRef(({ items, activeTab, onTabChange, className, isMobile: isMobileProp, ...props }, ref) => {
|
|
2285
|
+
const { isMobile } = useMobile(isMobileProp);
|
|
2286
|
+
return (jsxRuntimeExports.jsxs("div", { ref: ref, className: cn('relative w-full', className), ...props, children: [jsxRuntimeExports.jsx("div", { className: "box-border flex flex-row items-center justify-end p-0 relative w-full", children: items.map((item) => renderTab(item, activeTab, isMobile, onTabChange)) }), jsxRuntimeExports.jsx("div", { className: "absolute border-midnight-light border-[0px_0px_1px] border-solid bottom-[-0.5px] left-0 right-0 top-0 pointer-events-none" })] }));
|
|
2287
|
+
});
|
|
2288
|
+
Tabs$1.displayName = 'Tabs';
|
|
2289
|
+
|
|
2290
|
+
const Drawer$1 = React.forwardRef(({ children, direction = 'bottom', fullScreen = false, isOpen = false, onClose, className, ...props }, ref) => {
|
|
2291
|
+
const overlayRef = React.useRef(null);
|
|
2292
|
+
const drawerRef = React.useRef(null);
|
|
2293
|
+
const { isMobile } = useMobile();
|
|
2294
|
+
// Handle escape key
|
|
2295
|
+
React.useEffect(() => {
|
|
2296
|
+
const handleEscape = (event) => {
|
|
2297
|
+
if (event.key === 'Escape' && isOpen && onClose) {
|
|
2298
|
+
onClose();
|
|
2299
|
+
}
|
|
2300
|
+
};
|
|
2301
|
+
if (isOpen) {
|
|
2302
|
+
document.addEventListener('keydown', handleEscape);
|
|
2303
|
+
// Prevent body scroll when drawer is open
|
|
2304
|
+
document.body.style.overflow = 'hidden';
|
|
2305
|
+
}
|
|
2306
|
+
return () => {
|
|
2307
|
+
document.removeEventListener('keydown', handleEscape);
|
|
2308
|
+
document.body.style.overflow = 'auto';
|
|
2309
|
+
};
|
|
2310
|
+
}, [isOpen, onClose]);
|
|
2311
|
+
// Handle click outside
|
|
2312
|
+
const handleOverlayClick = (event) => {
|
|
2313
|
+
if (!fullScreen &&
|
|
2314
|
+
onClose &&
|
|
2315
|
+
overlayRef.current &&
|
|
2316
|
+
event.target === overlayRef.current) {
|
|
2317
|
+
onClose();
|
|
2318
|
+
}
|
|
2319
|
+
};
|
|
2320
|
+
// Handle keyboard events on overlay
|
|
2321
|
+
const handleOverlayKeyDown = (event) => {
|
|
2322
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
2323
|
+
if (!fullScreen &&
|
|
2324
|
+
onClose &&
|
|
2325
|
+
overlayRef.current &&
|
|
2326
|
+
event.target === overlayRef.current) {
|
|
2327
|
+
onClose();
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
};
|
|
2331
|
+
const getTranslateClasses = () => {
|
|
2332
|
+
if (!isOpen) {
|
|
2333
|
+
switch (direction) {
|
|
2334
|
+
case 'top':
|
|
2335
|
+
return '-translate-y-full';
|
|
2336
|
+
case 'bottom':
|
|
2337
|
+
return 'translate-y-full';
|
|
2338
|
+
case 'left':
|
|
2339
|
+
return '-translate-x-full';
|
|
2340
|
+
case 'right':
|
|
2341
|
+
return 'translate-x-full';
|
|
2342
|
+
default:
|
|
2343
|
+
return 'translate-y-full';
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
return 'translate-x-0 translate-y-0';
|
|
2347
|
+
};
|
|
2348
|
+
const getPositionClasses = () => {
|
|
2349
|
+
switch (direction) {
|
|
2350
|
+
case 'top':
|
|
2351
|
+
return 'top-0 left-0 right-0';
|
|
2352
|
+
case 'bottom':
|
|
2353
|
+
return 'bottom-0 left-0 right-0';
|
|
2354
|
+
case 'left':
|
|
2355
|
+
return 'top-0 left-0 bottom-0';
|
|
2356
|
+
case 'right':
|
|
2357
|
+
return 'top-0 right-0 bottom-0';
|
|
2358
|
+
default:
|
|
2359
|
+
return 'bottom-0 left-0 right-0';
|
|
2360
|
+
}
|
|
2361
|
+
};
|
|
2362
|
+
const getSizeClasses = () => {
|
|
2363
|
+
const isVertical = direction === 'top' || direction === 'bottom';
|
|
2364
|
+
if (fullScreen) {
|
|
2365
|
+
return isVertical ? 'w-full h-full' : 'w-full h-full';
|
|
2366
|
+
}
|
|
2367
|
+
if (isVertical) {
|
|
2368
|
+
return 'w-full max-h-[90vh]';
|
|
2369
|
+
}
|
|
2370
|
+
return 'h-full max-w-[90vw]';
|
|
2371
|
+
};
|
|
2372
|
+
const baseOverlayClasses = 'fixed inset-0 z-50 transition-all duration-300';
|
|
2373
|
+
const baseDrawerClasses = 'fixed bg-white shadow-2xl transition-all duration-300 ease-out overflow-auto';
|
|
2374
|
+
const overlayClasses = cn(baseOverlayClasses, {
|
|
2375
|
+
'bg-neutral-darker/50 backdrop-blur-sm': isOpen,
|
|
2376
|
+
'bg-transparent pointer-events-none': !isOpen,
|
|
2377
|
+
});
|
|
2378
|
+
const drawerClasses = cn(baseDrawerClasses, getPositionClasses(), getSizeClasses(), getTranslateClasses(), {
|
|
2379
|
+
'rounded-t-2xl': direction === 'bottom' && !fullScreen,
|
|
2380
|
+
'rounded-b-2xl': direction === 'top' && !fullScreen,
|
|
2381
|
+
'rounded-r-2xl': direction === 'left' && !fullScreen,
|
|
2382
|
+
'rounded-l-2xl': direction === 'right' && !fullScreen,
|
|
2383
|
+
'p-6': !isMobile,
|
|
2384
|
+
'p-4': isMobile,
|
|
2385
|
+
}, className);
|
|
2386
|
+
if (!isOpen) {
|
|
2387
|
+
return null;
|
|
2388
|
+
}
|
|
2389
|
+
return (jsxRuntimeExports.jsx("div", { ref: overlayRef, className: overlayClasses, onClick: handleOverlayClick, onKeyDown: handleOverlayKeyDown, tabIndex: -1, role: "button", "aria-label": "Close drawer", children: jsxRuntimeExports.jsx("div", { ref: ref || drawerRef, className: drawerClasses, role: "dialog", "aria-modal": "true", "aria-label": "Drawer", ...props, children: children }) }));
|
|
2390
|
+
});
|
|
2391
|
+
Drawer$1.displayName = 'Drawer';
|
|
2392
|
+
|
|
2393
|
+
const Backdrop$1 = React.forwardRef(({ isOpen = false, onClick, blur = false, zIndex = 51, className, children, ...props }, ref) => {
|
|
2394
|
+
const handleClick = (event) => {
|
|
2395
|
+
if (onClick && event.target === event.currentTarget) {
|
|
2396
|
+
onClick();
|
|
2397
|
+
}
|
|
2398
|
+
};
|
|
2399
|
+
const backdropClasses = cn('fixed inset-0 transition-all duration-300', {
|
|
2400
|
+
'opacity-100 pointer-events-auto': isOpen,
|
|
2401
|
+
'opacity-0 pointer-events-none': !isOpen,
|
|
2402
|
+
'backdrop-blur-sm': blur,
|
|
2403
|
+
}, className);
|
|
2404
|
+
const backdropStyle = {
|
|
2405
|
+
backgroundColor: 'rgba(0, 0, 0, 0.60)',
|
|
2406
|
+
zIndex,
|
|
2407
|
+
};
|
|
2408
|
+
return (jsxRuntimeExports.jsx("div", { ref: ref, className: backdropClasses, style: backdropStyle, onClick: handleClick, role: "presentation", "aria-hidden": !isOpen, ...props, children: children }));
|
|
2409
|
+
});
|
|
2410
|
+
Backdrop$1.displayName = 'Backdrop';
|
|
2411
|
+
|
|
2412
|
+
/**
|
|
2413
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2414
|
+
*
|
|
2415
|
+
* This source code is licensed under the ISC license.
|
|
2416
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2417
|
+
*/
|
|
2418
|
+
|
|
2419
|
+
const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
2420
|
+
const toCamelCase = (string) => string.replace(
|
|
2421
|
+
/^([A-Z])|[\s-_]+(\w)/g,
|
|
2422
|
+
(match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
|
|
2423
|
+
);
|
|
2424
|
+
const toPascalCase = (string) => {
|
|
2425
|
+
const camelCase = toCamelCase(string);
|
|
2426
|
+
return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
|
|
2427
|
+
};
|
|
2428
|
+
const mergeClasses = (...classes) => classes.filter((className, index, array) => {
|
|
2429
|
+
return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
|
|
2430
|
+
}).join(" ").trim();
|
|
2431
|
+
const hasA11yProp = (props) => {
|
|
2432
|
+
for (const prop in props) {
|
|
2433
|
+
if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
|
|
2434
|
+
return true;
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
};
|
|
2438
|
+
|
|
2439
|
+
/**
|
|
2440
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2441
|
+
*
|
|
2442
|
+
* This source code is licensed under the ISC license.
|
|
2443
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2444
|
+
*/
|
|
2445
|
+
|
|
2446
|
+
var defaultAttributes = {
|
|
2447
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2448
|
+
width: 24,
|
|
2449
|
+
height: 24,
|
|
2450
|
+
viewBox: "0 0 24 24",
|
|
2451
|
+
fill: "none",
|
|
2452
|
+
stroke: "currentColor",
|
|
2453
|
+
strokeWidth: 2,
|
|
2454
|
+
strokeLinecap: "round",
|
|
2455
|
+
strokeLinejoin: "round"
|
|
2456
|
+
};
|
|
2457
|
+
|
|
2458
|
+
/**
|
|
2459
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2460
|
+
*
|
|
2461
|
+
* This source code is licensed under the ISC license.
|
|
2462
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2463
|
+
*/
|
|
2464
|
+
|
|
2465
|
+
|
|
2466
|
+
const Icon = React.forwardRef(
|
|
2467
|
+
({
|
|
2468
|
+
color = "currentColor",
|
|
2469
|
+
size = 24,
|
|
2470
|
+
strokeWidth = 2,
|
|
2471
|
+
absoluteStrokeWidth,
|
|
2472
|
+
className = "",
|
|
2473
|
+
children,
|
|
2474
|
+
iconNode,
|
|
2475
|
+
...rest
|
|
2476
|
+
}, ref) => React.createElement(
|
|
2477
|
+
"svg",
|
|
2478
|
+
{
|
|
2479
|
+
ref,
|
|
2480
|
+
...defaultAttributes,
|
|
2481
|
+
width: size,
|
|
2482
|
+
height: size,
|
|
2483
|
+
stroke: color,
|
|
2484
|
+
strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
|
|
2485
|
+
className: mergeClasses("lucide", className),
|
|
2486
|
+
...!children && !hasA11yProp(rest) && { "aria-hidden": "true" },
|
|
2487
|
+
...rest
|
|
2488
|
+
},
|
|
2489
|
+
[
|
|
2490
|
+
...iconNode.map(([tag, attrs]) => React.createElement(tag, attrs)),
|
|
2491
|
+
...Array.isArray(children) ? children : [children]
|
|
2492
|
+
]
|
|
2493
|
+
)
|
|
2494
|
+
);
|
|
2495
|
+
|
|
2496
|
+
/**
|
|
2497
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2498
|
+
*
|
|
2499
|
+
* This source code is licensed under the ISC license.
|
|
2500
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2501
|
+
*/
|
|
2502
|
+
|
|
2503
|
+
|
|
2504
|
+
const createLucideIcon = (iconName, iconNode) => {
|
|
2505
|
+
const Component = React.forwardRef(
|
|
2506
|
+
({ className, ...props }, ref) => React.createElement(Icon, {
|
|
2507
|
+
ref,
|
|
2508
|
+
iconNode,
|
|
2509
|
+
className: mergeClasses(
|
|
2510
|
+
`lucide-${toKebabCase(toPascalCase(iconName))}`,
|
|
2511
|
+
`lucide-${iconName}`,
|
|
2512
|
+
className
|
|
2513
|
+
),
|
|
2514
|
+
...props
|
|
2515
|
+
})
|
|
2516
|
+
);
|
|
2517
|
+
Component.displayName = toPascalCase(iconName);
|
|
2518
|
+
return Component;
|
|
2519
|
+
};
|
|
2520
|
+
|
|
2521
|
+
/**
|
|
2522
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2523
|
+
*
|
|
2524
|
+
* This source code is licensed under the ISC license.
|
|
2525
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2526
|
+
*/
|
|
2527
|
+
|
|
2528
|
+
|
|
2529
|
+
const __iconNode$7 = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
|
|
2530
|
+
const ChevronDown = createLucideIcon("chevron-down", __iconNode$7);
|
|
2531
|
+
|
|
2532
|
+
/**
|
|
2533
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2534
|
+
*
|
|
2535
|
+
* This source code is licensed under the ISC license.
|
|
2536
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2537
|
+
*/
|
|
2538
|
+
|
|
2539
|
+
|
|
2540
|
+
const __iconNode$6 = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
|
|
2541
|
+
const ChevronLeft = createLucideIcon("chevron-left", __iconNode$6);
|
|
2542
|
+
|
|
2543
|
+
/**
|
|
2544
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2545
|
+
*
|
|
2546
|
+
* This source code is licensed under the ISC license.
|
|
2547
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2548
|
+
*/
|
|
2549
|
+
|
|
2550
|
+
|
|
2551
|
+
const __iconNode$5 = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
|
|
2552
|
+
const ChevronRight = createLucideIcon("chevron-right", __iconNode$5);
|
|
2553
|
+
|
|
2554
|
+
/**
|
|
2555
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2556
|
+
*
|
|
2557
|
+
* This source code is licensed under the ISC license.
|
|
2558
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2559
|
+
*/
|
|
2560
|
+
|
|
2561
|
+
|
|
2562
|
+
const __iconNode$4 = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
|
|
2563
|
+
const ChevronUp = createLucideIcon("chevron-up", __iconNode$4);
|
|
2564
|
+
|
|
2565
|
+
/**
|
|
2566
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2567
|
+
*
|
|
2568
|
+
* This source code is licensed under the ISC license.
|
|
2569
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2570
|
+
*/
|
|
2571
|
+
|
|
2572
|
+
|
|
2573
|
+
const __iconNode$3 = [
|
|
2574
|
+
["path", { d: "m11 17-5-5 5-5", key: "13zhaf" }],
|
|
2575
|
+
["path", { d: "m18 17-5-5 5-5", key: "h8a8et" }]
|
|
2576
|
+
];
|
|
2577
|
+
const ChevronsLeft = createLucideIcon("chevrons-left", __iconNode$3);
|
|
2578
|
+
|
|
2579
|
+
/**
|
|
2580
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2581
|
+
*
|
|
2582
|
+
* This source code is licensed under the ISC license.
|
|
2583
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2584
|
+
*/
|
|
2585
|
+
|
|
2586
|
+
|
|
2587
|
+
const __iconNode$2 = [
|
|
2588
|
+
["path", { d: "m6 17 5-5-5-5", key: "xnjwq" }],
|
|
2589
|
+
["path", { d: "m13 17 5-5-5-5", key: "17xmmf" }]
|
|
2590
|
+
];
|
|
2591
|
+
const ChevronsRight = createLucideIcon("chevrons-right", __iconNode$2);
|
|
2592
|
+
|
|
2593
|
+
/**
|
|
2594
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2595
|
+
*
|
|
2596
|
+
* This source code is licensed under the ISC license.
|
|
2597
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2598
|
+
*/
|
|
2599
|
+
|
|
2600
|
+
|
|
2601
|
+
const __iconNode$1 = [
|
|
2602
|
+
["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
|
|
2603
|
+
["circle", { cx: "19", cy: "12", r: "1", key: "1wjl8i" }],
|
|
2604
|
+
["circle", { cx: "5", cy: "12", r: "1", key: "1pcz8c" }]
|
|
2605
|
+
];
|
|
2606
|
+
const Ellipsis = createLucideIcon("ellipsis", __iconNode$1);
|
|
2607
|
+
|
|
2608
|
+
/**
|
|
2609
|
+
* @license lucide-react v0.522.0 - ISC
|
|
2610
|
+
*
|
|
2611
|
+
* This source code is licensed under the ISC license.
|
|
2612
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2613
|
+
*/
|
|
2614
|
+
|
|
2615
|
+
|
|
2616
|
+
const __iconNode = [
|
|
2617
|
+
["path", { d: "M18 6 6 18", key: "1bl5f8" }],
|
|
2618
|
+
["path", { d: "m6 6 12 12", key: "d8bk6v" }]
|
|
2619
|
+
];
|
|
2620
|
+
const X = createLucideIcon("x", __iconNode);
|
|
2621
|
+
|
|
2622
|
+
const Breadcrumb$1 = React.forwardRef(({ items, className, testIsMobile }, ref) => {
|
|
2623
|
+
const { isMobile } = useMobile(testIsMobile);
|
|
2624
|
+
const handleItemClick = (item, index, e) => {
|
|
2625
|
+
// Don't make the last item (current page) clickable
|
|
2626
|
+
if (index === items.length - 1)
|
|
2627
|
+
return;
|
|
2628
|
+
if (item.onClick) {
|
|
2629
|
+
e.preventDefault();
|
|
2630
|
+
item.onClick();
|
|
2631
|
+
}
|
|
2632
|
+
// If item has href, let the anchor tag handle navigation naturally
|
|
2633
|
+
};
|
|
2634
|
+
return (jsxRuntimeExports.jsx("nav", { ref: ref, className: cn(
|
|
2635
|
+
// Base layout - RTL with flex-row-reverse to show items right to left
|
|
2636
|
+
'flex flex-row-reverse items-center',
|
|
2637
|
+
// Responsive gap and padding based on mobile state
|
|
2638
|
+
isMobile ? 'gap-1 px-4 py-2.5' : 'gap-3 pr-1 pt-3 pb-4 pl-0', className), "aria-label": "Breadcrumb navigation", children: jsxRuntimeExports.jsx("ol", { className: "flex flex-row-reverse items-center gap-inherit", children: items.map((item, index) => {
|
|
2639
|
+
const isLast = index === items.length - 1;
|
|
2640
|
+
const isClickable = !isLast && (item.href || item.onClick);
|
|
2641
|
+
const itemKey = `${item.label}-${index}`;
|
|
2642
|
+
return (jsxRuntimeExports.jsxs("li", { className: "flex items-center gap-inherit", children: [isClickable ? (jsxRuntimeExports.jsx("a", { href: item.href || '#', className: cn(
|
|
2643
|
+
// Base styles
|
|
2644
|
+
'whitespace-nowrap border-0 bg-transparent p-0 no-underline',
|
|
2645
|
+
// Responsive font size based on mobile state
|
|
2646
|
+
isMobile ? 'text-t' : 'text-s',
|
|
2647
|
+
// Color
|
|
2648
|
+
'text-neutral-main',
|
|
2649
|
+
// Cursor and hover effects for clickable items
|
|
2650
|
+
'cursor-pointer hover:text-neutral-dark transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 rounded-sm'), onClick: (e) => handleItemClick(item, index, e), onKeyDown: (e) => {
|
|
2651
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
2652
|
+
e.preventDefault();
|
|
2653
|
+
if (item.onClick) {
|
|
2654
|
+
item.onClick();
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2657
|
+
}, "aria-label": `Go to ${item.label}`, children: item.label })) : (jsxRuntimeExports.jsx("span", { className: cn(
|
|
2658
|
+
// Base styles
|
|
2659
|
+
'whitespace-nowrap',
|
|
2660
|
+
// Responsive font size based on mobile state
|
|
2661
|
+
isMobile ? 'text-t' : 'text-s',
|
|
2662
|
+
// Color
|
|
2663
|
+
'text-neutral-main',
|
|
2664
|
+
// Different styles for current page (last item)
|
|
2665
|
+
'font-medium'), "aria-current": isLast ? 'page' : undefined, "aria-label": isLast ? `Current page: ${item.label}` : undefined, children: item.label })), !isLast && (jsxRuntimeExports.jsx(ChevronLeft, { className: cn('text-black flex-shrink-0',
|
|
2666
|
+
// Responsive icon size
|
|
2667
|
+
isMobile ? 'w-2.5 h-2.5' : 'w-3 h-3'), "aria-hidden": "true" }))] }, itemKey));
|
|
2668
|
+
}) }) }));
|
|
2669
|
+
});
|
|
2670
|
+
Breadcrumb$1.displayName = 'Breadcrumb';
|
|
2671
|
+
|
|
2672
|
+
function PaginationRoot({ className, ...props }) {
|
|
2673
|
+
return (jsxRuntimeExports.jsx("nav", { role: "navigation", "aria-label": "pagination", "data-slot": "pagination", className: cn('mx-auto flex w-full justify-center', className), ...props }));
|
|
2674
|
+
}
|
|
2675
|
+
function PaginationContent({ className, device, ...props }) {
|
|
2676
|
+
return (jsxRuntimeExports.jsx("ul", { "data-slot": "pagination-content", className: cn('flex flex-row items-center', device === 'mobile' ? 'gap-[6px]' : 'gap-2', className), ...props }));
|
|
2677
|
+
}
|
|
2678
|
+
function PaginationItem({ ...props }) {
|
|
2679
|
+
return jsxRuntimeExports.jsx("li", { "data-slot": "pagination-item", ...props });
|
|
2680
|
+
}
|
|
2681
|
+
function PaginationLink({ className, device, variant, isActive, ...props }) {
|
|
2682
|
+
return (jsxRuntimeExports.jsx("a", { "aria-current": isActive ? 'page' : undefined, "data-slot": "pagination-link", "data-active": isActive, className: cn(buttonVariants({
|
|
2683
|
+
variant: variant === 'nextPrev' ? variant : isActive ? 'active' : 'outline',
|
|
2684
|
+
device,
|
|
2685
|
+
}), className), tabIndex: props['aria-disabled'] ? -1 : 0, ...props }));
|
|
2686
|
+
}
|
|
2687
|
+
function PaginationPrevious({ className, device, variant, ...props }) {
|
|
2688
|
+
const isMobile = device === 'mobile';
|
|
2689
|
+
const content = {
|
|
2690
|
+
mobile: jsxRuntimeExports.jsx(ChevronRight, { size: 18 }),
|
|
2691
|
+
desktop: (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(ChevronsRight, { size: 20 }), " ", jsxRuntimeExports.jsx("span", { children: "\u0642\u0628\u0644\u06CC" })] })),
|
|
2692
|
+
};
|
|
2693
|
+
return (jsxRuntimeExports.jsx(PaginationLink, { "aria-label": "Go to previous page", className: !isMobile
|
|
2694
|
+
? 'flex justify-center items-center gap-2 w-[89px] h-[48px] ml-4'
|
|
2695
|
+
: 'ml-2.5', device: device, variant: "nextPrev", ...props, children: device === 'mobile' ? content.mobile : content.desktop }));
|
|
2696
|
+
}
|
|
2697
|
+
function PaginationNext({ className, device, variant, ...props }) {
|
|
2698
|
+
const isMobile = device === 'mobile';
|
|
2699
|
+
const content = {
|
|
2700
|
+
mobile: jsxRuntimeExports.jsx(ChevronLeft, { size: 18 }),
|
|
2701
|
+
desktop: (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { children: "\u0628\u0639\u062F\u06CC" }), jsxRuntimeExports.jsx(ChevronsLeft, { size: 20 })] })),
|
|
2702
|
+
};
|
|
2703
|
+
return (jsxRuntimeExports.jsx(PaginationLink, { "aria-label": "Go to next page", className: !isMobile
|
|
2704
|
+
? 'flex justify-center items-center gap-2 w-[89px] h-[48px] mr-4'
|
|
2705
|
+
: 'mr-2.5', device: device, variant: "nextPrev", ...props, children: device === 'mobile' ? content.mobile : content.desktop }));
|
|
2706
|
+
}
|
|
2707
|
+
function PaginationEllipsis({ className, ...props }) {
|
|
2708
|
+
return (jsxRuntimeExports.jsx("span", { "aria-hidden": true, "data-slot": "pagination-ellipsis", className: cn('flex size-9 items-center justify-center', className), ...props, children: jsxRuntimeExports.jsx(Ellipsis, { className: "size-4" }) }));
|
|
2709
|
+
}
|
|
2710
|
+
function buttonVariants({ variant, device, }) {
|
|
2711
|
+
const isMobile = device === 'mobile';
|
|
2712
|
+
const base = cn({
|
|
2713
|
+
'flex items-center justify-center rounded-[6px]': true,
|
|
2714
|
+
'w-[40px] h-[40px] text-s font-heavy': isMobile,
|
|
2715
|
+
'w-[48px] h-[48px] text-l font-heavy': !isMobile,
|
|
2716
|
+
});
|
|
2717
|
+
const variants = {
|
|
2718
|
+
outline: 'border border-neutral-light bg-white text-neutral-darker',
|
|
2719
|
+
active: 'bg-primary text-white',
|
|
2720
|
+
nextPrev: 'border border-neutral-light bg-white text-neutral-darker',
|
|
2721
|
+
};
|
|
2722
|
+
return [base, variants[variant]].join(' ');
|
|
2723
|
+
}
|
|
2724
|
+
const Pagination$1 = ({ pageCount, page: controlledPage, defaultPage = 1, onPageChange, className, ...navProps }) => {
|
|
2725
|
+
const isControlled = controlledPage !== undefined;
|
|
2726
|
+
const [internalPage, setInternalPage] = React.useState(defaultPage);
|
|
2727
|
+
const page = isControlled ? controlledPage : internalPage;
|
|
2728
|
+
const { isMobile } = useMobile();
|
|
2729
|
+
const device = isMobile ? 'mobile' : 'desktop';
|
|
2730
|
+
React.useEffect(() => {
|
|
2731
|
+
if (!isControlled)
|
|
2732
|
+
setInternalPage(defaultPage);
|
|
2733
|
+
}, [defaultPage, isControlled]);
|
|
2734
|
+
const changePage = (newPage) => {
|
|
2735
|
+
if (!isControlled)
|
|
2736
|
+
setInternalPage(newPage);
|
|
2737
|
+
onPageChange?.(newPage);
|
|
2738
|
+
};
|
|
2739
|
+
function renderPages() {
|
|
2740
|
+
const items = [];
|
|
2741
|
+
if (pageCount <= 5) {
|
|
2742
|
+
for (let i = 1; i <= pageCount; i++) {
|
|
2743
|
+
items.push(jsxRuntimeExports.jsx(PaginationItem, { children: jsxRuntimeExports.jsx(PaginationLink, { href: "#", isActive: page === i, variant: "main", device: device, onClick: (e) => {
|
|
2744
|
+
e.preventDefault();
|
|
2745
|
+
if (page !== i)
|
|
2746
|
+
changePage(i);
|
|
2747
|
+
}, "aria-disabled": page === i, tabIndex: page === i ? -1 : 0, children: i }) }, i));
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
else {
|
|
2751
|
+
// First page
|
|
2752
|
+
items.push(jsxRuntimeExports.jsx(PaginationItem, { children: jsxRuntimeExports.jsx(PaginationLink, { href: "#", isActive: page === 1, device: device, variant: "main", onClick: (e) => {
|
|
2753
|
+
e.preventDefault();
|
|
2754
|
+
if (page !== 1)
|
|
2755
|
+
changePage(1);
|
|
2756
|
+
}, "aria-disabled": page === 1, tabIndex: page === 1 ? -1 : 0, children: "1" }) }, 1));
|
|
2757
|
+
// Ellipsis start
|
|
2758
|
+
if (page > 3) {
|
|
2759
|
+
items.push(jsxRuntimeExports.jsx(PaginationItem, { children: jsxRuntimeExports.jsx(PaginationEllipsis, {}) }, "start-ellipsis"));
|
|
2760
|
+
}
|
|
2761
|
+
// Middle pages
|
|
2762
|
+
const start = Math.max(2, page - 1);
|
|
2763
|
+
const end = Math.min(pageCount - 1, page + 1);
|
|
2764
|
+
for (let i = start; i <= end; i++) {
|
|
2765
|
+
items.push(jsxRuntimeExports.jsx(PaginationItem, { children: jsxRuntimeExports.jsx(PaginationLink, { href: "#", isActive: page === i, device: device, variant: "main", onClick: (e) => {
|
|
2766
|
+
e.preventDefault();
|
|
2767
|
+
if (page !== i)
|
|
2768
|
+
changePage(i);
|
|
2769
|
+
}, "aria-disabled": page === i, tabIndex: page === i ? -1 : 0, children: i }) }, i));
|
|
2770
|
+
}
|
|
2771
|
+
// Ellipsis end
|
|
2772
|
+
if (page < pageCount - 2) {
|
|
2773
|
+
items.push(jsxRuntimeExports.jsx(PaginationItem, { children: jsxRuntimeExports.jsx(PaginationEllipsis, {}) }, "end-ellipsis"));
|
|
2774
|
+
}
|
|
2775
|
+
// Last page
|
|
2776
|
+
items.push(jsxRuntimeExports.jsx(PaginationItem, { children: jsxRuntimeExports.jsx(PaginationLink, { href: "#", isActive: page === pageCount, device: device, variant: "main", onClick: (e) => {
|
|
2777
|
+
e.preventDefault();
|
|
2778
|
+
if (page !== pageCount)
|
|
2779
|
+
changePage(pageCount);
|
|
2780
|
+
}, "aria-disabled": page === pageCount, tabIndex: page === pageCount ? -1 : 0, children: pageCount }) }, pageCount));
|
|
2781
|
+
}
|
|
2782
|
+
return items;
|
|
2783
|
+
}
|
|
2784
|
+
return (jsxRuntimeExports.jsx(PaginationRoot, { className: className, ...navProps, children: jsxRuntimeExports.jsxs(PaginationContent, { device: "mobile", children: [jsxRuntimeExports.jsx(PaginationItem, { children: jsxRuntimeExports.jsx(PaginationPrevious, { href: "#", onClick: (e) => {
|
|
2785
|
+
e.preventDefault();
|
|
2786
|
+
if (page > 1)
|
|
2787
|
+
changePage(page - 1);
|
|
2788
|
+
}, variant: "nextPrev", device: device, "aria-disabled": page === 1, tabIndex: page === 1 ? -1 : 0 }) }), renderPages(), jsxRuntimeExports.jsx(PaginationItem, { children: jsxRuntimeExports.jsx(PaginationNext, { href: "#", onClick: (e) => {
|
|
2789
|
+
e.preventDefault();
|
|
2790
|
+
if (page < pageCount)
|
|
2791
|
+
changePage(page + 1);
|
|
2792
|
+
}, variant: "nextPrev", device: device, "aria-disabled": page === pageCount, tabIndex: page === pageCount ? -1 : 0 }) })] }) }));
|
|
2793
|
+
};
|
|
2794
|
+
|
|
2795
|
+
const Accordion$1 = React.forwardRef(({ title, body, startIcon, isExpanded: controlledExpanded, onToggle, defaultExpanded = false, className, id, disabled = false, forceMobile, ...props }, ref) => {
|
|
2796
|
+
const [internalExpanded, setInternalExpanded] = React.useState(defaultExpanded);
|
|
2797
|
+
const { isMobile: contextIsMobile } = useMobile();
|
|
2798
|
+
// Use forceMobile prop if provided, otherwise use context
|
|
2799
|
+
const isMobile = forceMobile !== undefined ? forceMobile : contextIsMobile;
|
|
2800
|
+
// Use controlled state if provided, otherwise use internal state
|
|
2801
|
+
const isExpanded = controlledExpanded !== undefined ? controlledExpanded : internalExpanded;
|
|
2802
|
+
const handleToggle = () => {
|
|
2803
|
+
if (disabled)
|
|
2804
|
+
return;
|
|
2805
|
+
const newExpanded = !isExpanded;
|
|
2806
|
+
if (controlledExpanded === undefined) {
|
|
2807
|
+
setInternalExpanded(newExpanded);
|
|
2808
|
+
}
|
|
2809
|
+
onToggle?.(newExpanded);
|
|
2810
|
+
};
|
|
2811
|
+
const accordionId = id || `accordion-${Math.random().toString(36).substr(2, 9)}`;
|
|
2812
|
+
const headerId = `${accordionId}-header`;
|
|
2813
|
+
const contentId = `${accordionId}-content`;
|
|
2814
|
+
// Icon size based on device
|
|
2815
|
+
const iconSize = isMobile ? 20 : 24;
|
|
2816
|
+
// Typography variants based on device
|
|
2817
|
+
const titleVariant = isMobile ? 'body-s-heavy' : 'body-l-heavy';
|
|
2818
|
+
const bodyVariant = isMobile ? 'body-s-medium' : 'body-m-medium';
|
|
2819
|
+
return (jsxRuntimeExports.jsxs("div", { ref: ref, className: cn('rounded-2xl border-0 overflow-hidden', 'transition-all duration-200 ease-in-out', className), ...props, children: [jsxRuntimeExports.jsxs("button", { id: headerId, type: "button", onClick: handleToggle, disabled: disabled, "aria-expanded": isExpanded, "aria-controls": contentId, className: cn('w-full flex items-center justify-between', isMobile ? 'p-3' : 'p-4', 'focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2', 'disabled:opacity-50 disabled:cursor-not-allowed', 'transition-all duration-200 ease-in-out', !disabled && 'hover:bg-neutral-lighter'), children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 mr-4", children: isExpanded ? (jsxRuntimeExports.jsx(ChevronUp, { size: iconSize, className: "text-neutral-darker transition-transform duration-200", "aria-hidden": "true" })) : (jsxRuntimeExports.jsx(ChevronDown, { size: iconSize, className: "text-neutral-darker transition-transform duration-200", "aria-hidden": "true" })) }), jsxRuntimeExports.jsxs("div", { className: cn('flex items-center flex-1', isMobile ? 'gap-3' : 'gap-4'), children: [jsxRuntimeExports.jsx("div", { className: "flex-1 text-right", children: jsxRuntimeExports.jsx(Typography$1, { variant: titleVariant, color: "neutral-darker", children: title }) }), startIcon && (jsxRuntimeExports.jsx("div", { className: cn('flex-shrink-0 flex items-center justify-center', isMobile ? 'w-6 h-6' : 'w-8 h-8'), children: startIcon }))] })] }), jsxRuntimeExports.jsx("div", { id: contentId, role: "region", "aria-labelledby": headerId, className: cn('w-full overflow-hidden transition-all duration-300 ease-in-out', isExpanded ? 'max-h-screen opacity-100' : 'max-h-0 opacity-0'), children: jsxRuntimeExports.jsx("div", { className: cn(isMobile ? 'pb-3 mt-1' : 'pb-4 mt-1.5'), children: jsxRuntimeExports.jsx("div", { className: cn('bg-neutral-lighter rounded-lg', isMobile ? 'p-3' : 'p-4'), children: jsxRuntimeExports.jsx(Typography$1, { variant: bodyVariant, color: "neutral-dark", children: body }) }) }) })] }));
|
|
2820
|
+
});
|
|
2821
|
+
Accordion$1.displayName = 'Accordion';
|
|
2822
|
+
|
|
2823
|
+
const Divider$1 = React.forwardRef(({ width = '100%', height = 1, orientation = 'horizontal', variant = 'neutral-light', className, style, ...props }, ref) => {
|
|
2824
|
+
const isHorizontal = orientation === 'horizontal';
|
|
2825
|
+
const variantClasses = {
|
|
2826
|
+
'neutral-light': 'bg-neutral-light',
|
|
2827
|
+
'neutral-main': 'bg-neutral-main',
|
|
2828
|
+
primary: 'bg-primary',
|
|
2829
|
+
};
|
|
2830
|
+
const dividerStyle = {
|
|
2831
|
+
width: isHorizontal ? width : height,
|
|
2832
|
+
height: isHorizontal ? height : width,
|
|
2833
|
+
...style,
|
|
2834
|
+
};
|
|
2835
|
+
return (jsxRuntimeExports.jsx("div", { ref: ref, className: cn('shrink-0', variantClasses[variant], className), style: dividerStyle, role: "separator", ...props }));
|
|
2836
|
+
});
|
|
2837
|
+
Divider$1.displayName = 'Divider';
|
|
2838
|
+
|
|
2839
|
+
const RadioButton = ({ selected, disabled, isMobile, }) => {
|
|
2840
|
+
const size = isMobile ? 'size-5' : 'size-6';
|
|
2841
|
+
if (selected) {
|
|
2842
|
+
return (jsxRuntimeExports.jsxs("div", { className: cn('relative flex items-center justify-center', size), children: [jsxRuntimeExports.jsx("div", { className: cn('absolute inset-0 rounded-full border-2', disabled
|
|
2843
|
+
? 'bg-neutral-light border-neutral-light'
|
|
2844
|
+
: 'bg-primary border-primary') }), jsxRuntimeExports.jsx("div", { className: cn('absolute rounded-full bg-white', isMobile ? 'inset-[5px]' : 'inset-1.5') })] }));
|
|
2845
|
+
}
|
|
2846
|
+
return (jsxRuntimeExports.jsx("div", { className: cn('relative flex items-center justify-center', size), children: jsxRuntimeExports.jsx("div", { className: cn('absolute inset-0 rounded-full border', isMobile ? 'border' : 'border-[1.5px]', disabled ? 'border-neutral-light' : 'border-midnight') }) }));
|
|
2847
|
+
};
|
|
2848
|
+
const RadioOptionComponent = ({ option, selected, disabled, onClick, name, isMobile, }) => {
|
|
2849
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
2850
|
+
const handleKeyDown = (e) => {
|
|
2851
|
+
if ((e.key === 'Enter' || e.key === ' ') && !disabled) {
|
|
2852
|
+
e.preventDefault();
|
|
2853
|
+
onClick();
|
|
2854
|
+
}
|
|
2855
|
+
};
|
|
2856
|
+
const getBackgroundColor = () => {
|
|
2857
|
+
if (disabled)
|
|
2858
|
+
return 'bg-neutral-lighter';
|
|
2859
|
+
if (selected)
|
|
2860
|
+
return 'bg-primary-lightest';
|
|
2861
|
+
if (isHovered)
|
|
2862
|
+
return 'bg-primary-lightest/20';
|
|
2863
|
+
return 'bg-white';
|
|
2864
|
+
};
|
|
2865
|
+
const getBorderColor = () => {
|
|
2866
|
+
if (selected)
|
|
2867
|
+
return 'border-primary';
|
|
2868
|
+
return 'border-transparent';
|
|
2869
|
+
};
|
|
2870
|
+
const getTextColor = () => {
|
|
2871
|
+
if (disabled)
|
|
2872
|
+
return 'text-midnight';
|
|
2873
|
+
if (selected)
|
|
2874
|
+
return 'text-primary';
|
|
2875
|
+
return 'text-neutral-dark';
|
|
2876
|
+
};
|
|
2877
|
+
const getShadow = () => {
|
|
2878
|
+
if (disabled)
|
|
2879
|
+
return '';
|
|
2880
|
+
return 'shadow-[0px_2px_4px_0px_rgba(0,0,0,0.08)]';
|
|
2881
|
+
};
|
|
2882
|
+
return (jsxRuntimeExports.jsx("div", { className: cn('relative rounded-lg border-[1.5px] cursor-pointer transition-all duration-200', getBackgroundColor(), getBorderColor(), getShadow(), disabled && 'cursor-not-allowed'), onClick: disabled ? undefined : onClick, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onKeyDown: handleKeyDown, tabIndex: disabled ? -1 : 0, role: "radio", "aria-checked": selected, "aria-disabled": disabled, children: jsxRuntimeExports.jsx("div", { className: "flex flex-row items-center justify-end relative w-full", children: jsxRuntimeExports.jsx("div", { className: cn('box-border flex flex-row items-center justify-end relative w-full', isMobile ? 'gap-2 px-4 py-3' : 'gap-4 px-6 py-4'), children: jsxRuntimeExports.jsxs("div", { className: cn('flex flex-row items-center justify-end p-0 relative shrink-0', isMobile ? 'gap-2' : 'gap-3'), children: [jsxRuntimeExports.jsx("input", { type: "radio", name: name, value: option.id, checked: selected, disabled: disabled, onChange: onClick, className: "sr-only", "aria-label": option.label }), jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-0.5 items-end justify-start p-0 relative shrink-0", children: jsxRuntimeExports.jsx("div", { className: cn('font-sans font-bold text-nowrap text-right transition-colors duration-200', isMobile
|
|
2883
|
+
? 'text-[14px] leading-[24px]'
|
|
2884
|
+
: 'text-[16px] leading-normal', getTextColor()), children: jsxRuntimeExports.jsx("p", { className: "whitespace-pre", dir: "auto", children: option.label }) }) }), option.icon && (jsxRuntimeExports.jsx("div", { className: cn('flex items-center justify-center shrink-0 transition-colors duration-200', isMobile ? 'size-6' : 'size-7', getTextColor()), children: option.icon })), jsxRuntimeExports.jsx("div", { className: "flex flex-col items-start justify-start p-0 relative shrink-0", children: jsxRuntimeExports.jsx(RadioButton, { selected: selected, disabled: disabled, isMobile: isMobile }) })] }) }) }) }));
|
|
2885
|
+
};
|
|
2886
|
+
const RadioGroup$1 = React.forwardRef(({ options, value, onChange, name, disabled = false, className, isMobile: isMobileProp, direction = 'vertical', ...props }, ref) => {
|
|
2887
|
+
const { isMobile } = useMobile(isMobileProp);
|
|
2888
|
+
const handleOptionClick = (optionId) => {
|
|
2889
|
+
if (!disabled && onChange) {
|
|
2890
|
+
onChange(optionId);
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2893
|
+
const getContainerClasses = () => {
|
|
2894
|
+
if (direction === 'horizontal') {
|
|
2895
|
+
return cn('flex flex-row gap-2', isMobile ? 'flex-wrap' : 'flex-nowrap', className);
|
|
2896
|
+
}
|
|
2897
|
+
return cn('flex flex-col gap-2', className);
|
|
2898
|
+
};
|
|
2899
|
+
return (jsxRuntimeExports.jsx("div", { ref: ref, className: getContainerClasses(), role: "radiogroup", ...props, children: options.map((option) => (jsxRuntimeExports.jsx(RadioOptionComponent, { option: option, selected: value === option.id, disabled: disabled || option.disabled, onClick: () => handleOptionClick(option.id), name: name, isMobile: isMobile }, option.id))) }));
|
|
2900
|
+
});
|
|
2901
|
+
RadioGroup$1.displayName = 'RadioGroup';
|
|
2902
|
+
|
|
2903
|
+
const chipVariants = {
|
|
2904
|
+
purple: {
|
|
2905
|
+
background: 'bg-[var(--color-primary-lightest)]',
|
|
2906
|
+
text: 'text-[var(--color-primary-darkest)]',
|
|
2907
|
+
border: 'border-[var(--color-primary-light)]',
|
|
2908
|
+
},
|
|
2909
|
+
red: {
|
|
2910
|
+
background: 'bg-[var(--color-error-light)]',
|
|
2911
|
+
text: 'text-[var(--color-error)]',
|
|
2912
|
+
border: 'border-[#f0d6d6]',
|
|
2913
|
+
},
|
|
2914
|
+
green: {
|
|
2915
|
+
background: 'bg-[var(--color-success-light)]',
|
|
2916
|
+
text: 'text-[var(--color-success)]',
|
|
2917
|
+
border: 'border-[#d4e8dc]',
|
|
2918
|
+
},
|
|
2919
|
+
orange: {
|
|
2920
|
+
background: 'bg-[var(--color-warning-light)]',
|
|
2921
|
+
text: 'text-[var(--color-warning)]',
|
|
2922
|
+
border: 'border-[#f5e1d1]',
|
|
2923
|
+
},
|
|
2924
|
+
blue: {
|
|
2925
|
+
background: 'bg-[var(--color-info-light)]',
|
|
2926
|
+
text: 'text-[var(--color-info)]',
|
|
2927
|
+
border: 'border-[#d3e9f2]',
|
|
2928
|
+
},
|
|
2929
|
+
white: {
|
|
2930
|
+
background: 'bg-[var(--color-white)]',
|
|
2931
|
+
text: 'text-[var(--color-neutral-darker)]',
|
|
2932
|
+
border: 'border-[var(--color-neutral-light)]',
|
|
2933
|
+
},
|
|
2934
|
+
disabled: {
|
|
2935
|
+
background: 'bg-[var(--color-neutral-lighter)]',
|
|
2936
|
+
text: 'text-[var(--color-neutral-main)]',
|
|
2937
|
+
border: 'border-[var(--color-neutral-light)]',
|
|
2938
|
+
},
|
|
2939
|
+
};
|
|
2940
|
+
const chipSizes = {
|
|
2941
|
+
mobile: {
|
|
2942
|
+
padding: 'px-2.5 py-1',
|
|
2943
|
+
gap: 'gap-1',
|
|
2944
|
+
iconSize: 'size-4',
|
|
2945
|
+
fontSize: 'text-[12px]',
|
|
2946
|
+
lineHeight: 'leading-[1.8]',
|
|
2947
|
+
},
|
|
2948
|
+
desktop: {
|
|
2949
|
+
padding: 'px-3 py-1',
|
|
2950
|
+
gap: 'gap-1.5',
|
|
2951
|
+
iconSize: 'size-5',
|
|
2952
|
+
fontSize: 'text-[14px]',
|
|
2953
|
+
lineHeight: 'leading-[24px]',
|
|
2954
|
+
},
|
|
2955
|
+
};
|
|
2956
|
+
const Chips$1 = React.forwardRef(({ variant = 'purple', size, children = 'متن پیشفرض', disabled = false, onClick, onIconClick, className, isMobile: isMobileProp, ...props }, ref) => {
|
|
2957
|
+
const { isMobile } = useMobile(isMobileProp);
|
|
2958
|
+
const actualSize = size || (isMobile ? 'mobile' : 'desktop');
|
|
2959
|
+
const actualVariant = disabled ? 'disabled' : variant;
|
|
2960
|
+
const variantStyles = chipVariants[actualVariant];
|
|
2961
|
+
const sizeStyles = chipSizes[actualSize];
|
|
2962
|
+
const handleIconClick = (e) => {
|
|
2963
|
+
e.stopPropagation();
|
|
2964
|
+
if (onIconClick) {
|
|
2965
|
+
onIconClick();
|
|
2966
|
+
}
|
|
2967
|
+
};
|
|
2968
|
+
const handleKeyDown = (e) => {
|
|
2969
|
+
if ((e.key === 'Enter' || e.key === ' ') && onClick && !disabled) {
|
|
2970
|
+
e.preventDefault();
|
|
2971
|
+
onClick();
|
|
2972
|
+
}
|
|
2973
|
+
};
|
|
2974
|
+
const renderIcon = () => {
|
|
2975
|
+
const iconElement = jsxRuntimeExports.jsx(X, { className: cn(sizeStyles.iconSize) });
|
|
2976
|
+
if (onIconClick) {
|
|
2977
|
+
return (jsxRuntimeExports.jsx("button", { type: "button", onClick: handleIconClick, disabled: disabled, className: cn('flex items-center justify-center', 'hover:opacity-70 transition-opacity', disabled && 'cursor-not-allowed opacity-50'), "aria-label": "\u062D\u0630\u0641", children: iconElement }));
|
|
2978
|
+
}
|
|
2979
|
+
return iconElement;
|
|
2980
|
+
};
|
|
2981
|
+
return (jsxRuntimeExports.jsxs("div", { ref: ref, className: cn(
|
|
2982
|
+
// Base styles
|
|
2983
|
+
'relative rounded-[50px] border border-solid inline-flex', 'flex-row items-center justify-center', 'font-sans font-bold not-italic', 'text-nowrap text-right', 'transition-all duration-200',
|
|
2984
|
+
// Variant styles
|
|
2985
|
+
variantStyles.background, variantStyles.text, variantStyles.border,
|
|
2986
|
+
// Size styles
|
|
2987
|
+
sizeStyles.padding, sizeStyles.gap, sizeStyles.fontSize, sizeStyles.lineHeight,
|
|
2988
|
+
// Interactive styles
|
|
2989
|
+
onClick && !disabled && 'cursor-pointer hover:opacity-80', disabled && 'cursor-not-allowed opacity-60', className), onClick: disabled ? undefined : onClick, onKeyDown: onClick && !disabled ? handleKeyDown : undefined, tabIndex: onClick && !disabled ? 0 : undefined, role: onClick ? 'button' : undefined, ...props, children: [jsxRuntimeExports.jsx("span", { className: "text-center", children: children }), renderIcon()] }));
|
|
2990
|
+
});
|
|
2991
|
+
Chips$1.displayName = 'Chips';
|
|
2992
|
+
|
|
2993
|
+
// Protected Components (license-wrapped)
|
|
2994
|
+
const Typography = withLicenseProtection(Typography$1, 'Typography');
|
|
2995
|
+
const Button = withLicenseProtection(Button$1, 'Button');
|
|
2996
|
+
const Input = withLicenseProtection(Input$1, 'Input');
|
|
2997
|
+
const Tabs = withLicenseProtection(Tabs$1, 'Tabs');
|
|
2998
|
+
const Drawer = withLicenseProtection(Drawer$1, 'Drawer');
|
|
2999
|
+
const Backdrop = withLicenseProtection(Backdrop$1, 'Backdrop');
|
|
3000
|
+
const Breadcrumb = withLicenseProtection(Breadcrumb$1, 'Breadcrumb');
|
|
3001
|
+
const Pagination = withLicenseProtection(Pagination$1, 'Pagination');
|
|
3002
|
+
const Accordion = withLicenseProtection(Accordion$1, 'Accordion');
|
|
3003
|
+
const Divider = withLicenseProtection(Divider$1, 'Divider');
|
|
3004
|
+
const RadioGroup = withLicenseProtection(RadioGroup$1, 'RadioGroup');
|
|
3005
|
+
const Chips = withLicenseProtection(Chips$1, 'Chips');
|
|
3006
|
+
|
|
3007
|
+
exports.Accordion = Accordion;
|
|
3008
|
+
exports.Backdrop = Backdrop;
|
|
3009
|
+
exports.Breadcrumb = Breadcrumb;
|
|
3010
|
+
exports.Button = Button;
|
|
3011
|
+
exports.Chips = Chips;
|
|
3012
|
+
exports.Divider = Divider;
|
|
3013
|
+
exports.Drawer = Drawer;
|
|
3014
|
+
exports.Input = Input;
|
|
3015
|
+
exports.MobileProvider = MobileProvider;
|
|
3016
|
+
exports.Pagination = Pagination;
|
|
3017
|
+
exports.RadioGroup = RadioGroup;
|
|
3018
|
+
exports.Tabs = Tabs;
|
|
3019
|
+
exports.Typography = Typography;
|
|
3020
|
+
exports.initializeAutomobiKit = initializeAutomobiKit;
|
|
3021
|
+
exports.useMobile = useMobile;
|
|
3022
|
+
//# sourceMappingURL=index.cjs.js.map
|