app-studio 0.7.15 → 0.7.17
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 +1 -1
- package/dist/app-studio.cjs.development.js +79 -9
- package/dist/app-studio.cjs.development.js.map +1 -1
- package/dist/app-studio.cjs.production.min.js +1 -1
- package/dist/app-studio.esm.js +79 -9
- package/dist/app-studio.esm.js.map +1 -1
- package/dist/app-studio.umd.development.js +79 -9
- package/dist/app-studio.umd.development.js.map +1 -1
- package/dist/app-studio.umd.production.min.js +1 -1
- package/dist/element/Element.types.d.ts +8 -0
- package/dist/element/css.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,7 +83,7 @@ The `Element` component is the cornerstone of App-Studio. Most other components
|
|
|
83
83
|
* **Responsive Styles:** Use the `media` prop to define styles for specific breakpoints (e.g., `media={{ mobile: { padding: 8 }, desktop: { padding: 16 } }}`).
|
|
84
84
|
* **State-Based Styles:** Use the `on` prop to apply styles based on interaction states like hover, focus, or active (e.g., `on={{ hover: { backgroundColor: 'lightgray' } }}`).
|
|
85
85
|
* **Animation:** Integrates with the animation system via the `animate` prop.
|
|
86
|
-
* **Theming:** Automatically resolves theme colors (e.g., `color="theme
|
|
86
|
+
* **Theming:** Automatically resolves theme colors (e.g., `color="theme-primary"`).
|
|
87
87
|
|
|
88
88
|
## Styling System
|
|
89
89
|
|
|
@@ -1703,7 +1703,7 @@ const NumberProps = /*#__PURE__*/new Set(['numberOfLines', 'fontWeight', 'timeSt
|
|
|
1703
1703
|
// Keys to exclude when passing props to the component
|
|
1704
1704
|
const excludedKeys = /*#__PURE__*/new Set([
|
|
1705
1705
|
// Standard styling props
|
|
1706
|
-
'on', 'shadow', 'only', 'media', 'css', 'widthHeight', 'paddingHorizontal', 'paddingVertical', 'marginHorizontal', 'marginVertical', 'animate', 'animateIn', 'animateOut',
|
|
1706
|
+
'on', 'shadow', 'only', 'media', 'css', 'widthHeight', 'paddingHorizontal', 'paddingVertical', 'marginHorizontal', 'marginVertical', 'animate', 'animateIn', 'animateOut', 'theme',
|
|
1707
1707
|
// Underscore-prefixed event props
|
|
1708
1708
|
'_hover', '_active', '_focus', '_visited', '_disabled', '_enabled', '_checked', '_unchecked', '_invalid', '_valid', '_required', '_optional', '_selected', '_target', '_firstChild', '_lastChild', '_onlyChild', '_firstOfType', '_lastOfType', '_empty', '_focusVisible', '_focusWithin', '_placeholder',
|
|
1709
1709
|
// Pseudo-element props
|
|
@@ -2028,6 +2028,24 @@ function hash(str) {
|
|
|
2028
2028
|
}
|
|
2029
2029
|
|
|
2030
2030
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2031
|
+
// Top-level CSS shorthands that reset a wide set of longhands on conflict.
|
|
2032
|
+
// Rules for these properties are injected into a stylesheet that appears
|
|
2033
|
+
// FIRST in the document, so longhand overrides written later in source order
|
|
2034
|
+
// win the cascade regardless of which element first instantiated each class.
|
|
2035
|
+
const TIER2_SHORTHANDS = /*#__PURE__*/new Set(['all', 'background', 'border', 'borderRadius', 'font', 'margin', 'padding', 'animation', 'transition', 'flex', 'grid', 'gridTemplate', 'gridArea', 'outline', 'inset', 'gap', 'gridGap', 'listStyle', 'textDecoration', 'placeItems', 'placeContent', 'placeSelf', 'overflow', 'mask', 'columns', 'columnRule']);
|
|
2036
|
+
// Sub-shorthands: reset some longhands but are themselves reset by tier-2.
|
|
2037
|
+
// Example: `border` resets `borderColor`; `borderColor` resets `borderTopColor`.
|
|
2038
|
+
const TIER3_SUB_SHORTHANDS = /*#__PURE__*/new Set(['borderTop', 'borderRight', 'borderBottom', 'borderLeft', 'borderColor', 'borderStyle', 'borderWidth', 'borderImage', 'flexFlow', 'overflowX', 'overflowY']);
|
|
2039
|
+
function baseContextForProperty(property) {
|
|
2040
|
+
if (TIER2_SHORTHANDS.has(property)) return 'base-shorthand';
|
|
2041
|
+
if (TIER3_SUB_SHORTHANDS.has(property)) return 'base-sub';
|
|
2042
|
+
return 'base';
|
|
2043
|
+
}
|
|
2044
|
+
function overrideContextForProperty(property) {
|
|
2045
|
+
if (TIER2_SHORTHANDS.has(property)) return 'override-shorthand';
|
|
2046
|
+
if (TIER3_SUB_SHORTHANDS.has(property)) return 'override-sub';
|
|
2047
|
+
return 'override';
|
|
2048
|
+
}
|
|
2031
2049
|
// Implement a simple LRU cache for classCache
|
|
2032
2050
|
class LRUCache {
|
|
2033
2051
|
constructor(maxSize) {
|
|
@@ -2269,11 +2287,20 @@ class UtilityClassManager {
|
|
|
2269
2287
|
if (!this.styleSheets.has(targetDocument)) {
|
|
2270
2288
|
const sheetMap = {};
|
|
2271
2289
|
// Initialize all style sheets at once
|
|
2290
|
+
// Order matters: <style> tags are appended to <head> in the order
|
|
2291
|
+
// listed here, and the cascade resolves equal-specificity rules by
|
|
2292
|
+
// source order. Earlier entries cascade FIRST (lower priority), so
|
|
2293
|
+
// top-level shorthands like `border` are listed before their
|
|
2294
|
+
// sub-shorthands and longhands.
|
|
2272
2295
|
const contextIds = {
|
|
2296
|
+
'base-shorthand': 'utility-classes-base-shorthand',
|
|
2297
|
+
'base-sub': 'utility-classes-base-sub',
|
|
2273
2298
|
base: 'utility-classes-base',
|
|
2274
2299
|
pseudo: 'utility-classes-pseudo',
|
|
2275
2300
|
media: 'utility-classes-media',
|
|
2276
2301
|
modifier: 'utility-classes-modifier',
|
|
2302
|
+
'override-shorthand': 'utility-classes-override-shorthand',
|
|
2303
|
+
'override-sub': 'utility-classes-override-sub',
|
|
2277
2304
|
override: 'utility-classes-override'
|
|
2278
2305
|
};
|
|
2279
2306
|
for (const [context, id] of Object.entries(contextIds)) {
|
|
@@ -2350,7 +2377,7 @@ class UtilityClassManager {
|
|
|
2350
2377
|
}
|
|
2351
2378
|
}
|
|
2352
2379
|
getServerStyles() {
|
|
2353
|
-
const contexts = ['base', 'pseudo', 'media', 'modifier', 'override'];
|
|
2380
|
+
const contexts = ['base-shorthand', 'base-sub', 'base', 'pseudo', 'media', 'modifier', 'override-shorthand', 'override-sub', 'override'];
|
|
2354
2381
|
let css = '';
|
|
2355
2382
|
contexts.forEach(context => {
|
|
2356
2383
|
const rules = this.serverRules.get(context);
|
|
@@ -2468,12 +2495,16 @@ class UtilityClassManager {
|
|
|
2468
2495
|
});
|
|
2469
2496
|
} else {
|
|
2470
2497
|
const escapedClassName = this.escapeClassName(baseClassName);
|
|
2471
|
-
// Add rules for all necessary vendor prefixes
|
|
2472
|
-
//
|
|
2498
|
+
// Add rules for all necessary vendor prefixes.
|
|
2499
|
+
// Route to a tiered sheet (shorthand → sub → longhand) within the
|
|
2500
|
+
// passed context (base or override), so shorthand properties cascade
|
|
2501
|
+
// BEFORE their longhands regardless of which element first
|
|
2502
|
+
// instantiated each utility class.
|
|
2503
|
+
const tier = context === 'override' ? overrideContextForProperty(property) : baseContextForProperty(property);
|
|
2473
2504
|
cssProperties.forEach(prefixedProperty => {
|
|
2474
2505
|
rules.push({
|
|
2475
2506
|
rule: `.${escapedClassName} { ${prefixedProperty}: ${valueForCss}; }`,
|
|
2476
|
-
context:
|
|
2507
|
+
context: tier
|
|
2477
2508
|
});
|
|
2478
2509
|
});
|
|
2479
2510
|
}
|
|
@@ -3091,6 +3122,28 @@ function useStableStyleMemo(propsToProcess, getColor, mediaQueries, devices, man
|
|
|
3091
3122
|
}
|
|
3092
3123
|
return cacheRef.current.classes;
|
|
3093
3124
|
}
|
|
3125
|
+
const THEME_PREFIX$1 = 'theme-';
|
|
3126
|
+
// Build a getColor that resolves `theme-*` tokens against a component-scoped
|
|
3127
|
+
// theme override before falling back to the global getColor. Tokens not
|
|
3128
|
+
// covered by the override (color-*, light-*, dark-*, theme-* keys not in the
|
|
3129
|
+
// override) pass straight through.
|
|
3130
|
+
function makeScopedGetColor(componentTheme, baseGetColor) {
|
|
3131
|
+
return name => {
|
|
3132
|
+
if (!name || typeof name !== 'string') return String(name);
|
|
3133
|
+
if (!name.startsWith(THEME_PREFIX$1)) return baseGetColor(name);
|
|
3134
|
+
const parts = name.substring(THEME_PREFIX$1.length).split('-');
|
|
3135
|
+
const lastPart = parts[parts.length - 1];
|
|
3136
|
+
const maybeAlpha = parseInt(lastPart, 10);
|
|
3137
|
+
const hasAlpha = parts.length >= 2 && !isNaN(maybeAlpha) && maybeAlpha >= 0 && maybeAlpha <= 1000;
|
|
3138
|
+
const themeKey = hasAlpha ? parts.slice(0, -1).join('-') : parts.join('-');
|
|
3139
|
+
const overrideValue = componentTheme[themeKey];
|
|
3140
|
+
if (typeof overrideValue !== 'string') return baseGetColor(name);
|
|
3141
|
+
const resolved = baseGetColor(overrideValue);
|
|
3142
|
+
if (!hasAlpha) return resolved;
|
|
3143
|
+
const percentage = Math.round(maybeAlpha / 1000 * 100);
|
|
3144
|
+
return `color-mix(in srgb, ${resolved} ${percentage}%, transparent)`;
|
|
3145
|
+
};
|
|
3146
|
+
}
|
|
3094
3147
|
const Element = /*#__PURE__*/React__default.memo(/*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
3095
3148
|
let {
|
|
3096
3149
|
as = 'div',
|
|
@@ -3105,6 +3158,7 @@ const Element = /*#__PURE__*/React__default.memo(/*#__PURE__*/React.forwardRef((
|
|
|
3105
3158
|
onPress,
|
|
3106
3159
|
blend,
|
|
3107
3160
|
animateOn = 'Both',
|
|
3161
|
+
theme: componentTheme,
|
|
3108
3162
|
...rest
|
|
3109
3163
|
} = props;
|
|
3110
3164
|
const elementRef = React.useRef(null);
|
|
@@ -3120,6 +3174,17 @@ const Element = /*#__PURE__*/React__default.memo(/*#__PURE__*/React.forwardRef((
|
|
|
3120
3174
|
getColor,
|
|
3121
3175
|
theme
|
|
3122
3176
|
} = useTheme();
|
|
3177
|
+
// When a component-level `theme` prop is supplied, wrap getColor so
|
|
3178
|
+
// `theme-*` tokens resolve against the override first. Memoize on a
|
|
3179
|
+
// serialized signature so the function identity stays stable across
|
|
3180
|
+
// renders that don't change the override.
|
|
3181
|
+
const componentThemeKey = componentTheme ? Object.entries(componentTheme).map(_ref2 => {
|
|
3182
|
+
let [k, v] = _ref2;
|
|
3183
|
+
return `${k}=${v}`;
|
|
3184
|
+
}).join('|') : '';
|
|
3185
|
+
const scopedGetColor = React.useMemo(() => componentTheme ? makeScopedGetColor(componentTheme, getColor) : getColor,
|
|
3186
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3187
|
+
[componentThemeKey, getColor]);
|
|
3123
3188
|
const {
|
|
3124
3189
|
trackEvent
|
|
3125
3190
|
} = useAnalytics();
|
|
@@ -3140,8 +3205,8 @@ const Element = /*#__PURE__*/React__default.memo(/*#__PURE__*/React.forwardRef((
|
|
|
3140
3205
|
setIsVisible(true);
|
|
3141
3206
|
return;
|
|
3142
3207
|
}
|
|
3143
|
-
const observer = new IntersectionObserver(
|
|
3144
|
-
let [entry] =
|
|
3208
|
+
const observer = new IntersectionObserver(_ref3 => {
|
|
3209
|
+
let [entry] = _ref3;
|
|
3145
3210
|
if (entry.isIntersecting) {
|
|
3146
3211
|
setIsVisible(true);
|
|
3147
3212
|
observer.disconnect();
|
|
@@ -3210,8 +3275,13 @@ const Element = /*#__PURE__*/React__default.memo(/*#__PURE__*/React.forwardRef((
|
|
|
3210
3275
|
return anim;
|
|
3211
3276
|
});
|
|
3212
3277
|
}
|
|
3213
|
-
// Use hash-based memoization for style extraction
|
|
3214
|
-
|
|
3278
|
+
// Use hash-based memoization for style extraction. Mix the component
|
|
3279
|
+
// theme signature into the `theme` argument so the cache invalidates
|
|
3280
|
+
// when an override changes between renders.
|
|
3281
|
+
const utilityClasses = useStableStyleMemo(propsToProcess, scopedGetColor, mediaQueries, devices, manager, componentTheme ? {
|
|
3282
|
+
...theme,
|
|
3283
|
+
__scope: componentThemeKey
|
|
3284
|
+
} : theme);
|
|
3215
3285
|
const newProps = {
|
|
3216
3286
|
ref: setRef
|
|
3217
3287
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-studio.cjs.development.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app-studio.cjs.development.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|