app-studio 0.7.8 → 0.7.10

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.
@@ -1059,12 +1059,15 @@ const deepMerge = (target, source) => {
1059
1059
  }
1060
1060
  return merged;
1061
1061
  };
1062
+ // Stable default references to prevent unnecessary re-renders and cache invalidation
1063
+ const DEFAULT_THEME_OVERRIDE = {};
1064
+ const DEFAULT_COLORS_OVERRIDE = {};
1062
1065
  const ThemeProvider = _ref => {
1063
1066
  let {
1064
- theme: themeOverride = {},
1067
+ theme: themeOverride = DEFAULT_THEME_OVERRIDE,
1065
1068
  mode: initialMode = 'light',
1066
- dark: darkOverride = {},
1067
- light: lightOverride = {},
1069
+ dark: darkOverride = DEFAULT_COLORS_OVERRIDE,
1070
+ light: lightOverride = DEFAULT_COLORS_OVERRIDE,
1068
1071
  children,
1069
1072
  strict = false,
1070
1073
  targetWindow
@@ -1802,12 +1805,53 @@ const cssProperties = /*#__PURE__*/new Set([
1802
1805
  'textJustify', 'lineClamp', 'textIndent', 'perspective']);
1803
1806
  // Common React event handlers that should not be treated as style props
1804
1807
  const commonEventHandlers = /*#__PURE__*/new Set(['onClick', 'onChange', 'onSubmit', 'onFocus', 'onBlur', 'onKeyDown', 'onKeyUp', 'onKeyPress', 'onMouseDown', 'onMouseUp', 'onMouseMove', 'onMouseEnter', 'onMouseLeave', 'onTouchStart', 'onTouchEnd', 'onTouchMove', 'onScroll', 'onWheel', 'onDrag', 'onDragStart', 'onDragEnd', 'onDrop']);
1808
+ // Non-hyphenated HTML/SVG attributes that must never be treated as style props.
1809
+ // Hyphenated attributes (aria-*, data-*, etc.) are caught by a prefix/hyphen check below.
1810
+ const htmlOnlyAttributes = /*#__PURE__*/new Set([
1811
+ // Accessibility
1812
+ 'role', 'tabIndex',
1813
+ // Global HTML attributes
1814
+ 'id', 'title', 'lang', 'dir', 'hidden', 'draggable', 'contentEditable', 'spellCheck', 'nonce', 'slot', 'is', 'inputMode', 'enterKeyHint', 'autofocus', 'autoFocus', 'translate',
1815
+ // Form attributes
1816
+ 'autoComplete', 'name', 'disabled', 'readOnly', 'required', 'checked', 'selected', 'multiple', 'value', 'defaultValue', 'defaultChecked', 'placeholder', 'htmlFor', 'type', 'accept', 'maxLength', 'minLength', 'pattern', 'noValidate', 'formAction', 'formEncType', 'formMethod', 'formNoValidate', 'formTarget',
1817
+ // Link/navigation attributes
1818
+ 'href', 'target', 'rel', 'download', 'referrerPolicy', 'integrity', 'crossOrigin',
1819
+ // Form container attributes
1820
+ 'action', 'method', 'encType',
1821
+ // Media attributes
1822
+ 'autoPlay', 'controls', 'loop', 'muted', 'playsInline', 'poster', 'preload', 'mediaGroup',
1823
+ // Image/embed attributes
1824
+ 'loading', 'decoding', 'sizes', 'srcDoc', 'srcLang', 'srcSet', 'useMap',
1825
+ // Table attributes
1826
+ 'colSpan', 'rowSpan', 'cols', 'rows', 'headers', 'scope', 'span',
1827
+ // Iframe/embed attributes
1828
+ 'sandbox', 'allowFullScreen', 'frameBorder', 'scrolling', 'seamless', 'allow',
1829
+ // Interactive attributes
1830
+ 'open', 'cite', 'dateTime', 'reversed', 'start', 'high', 'low', 'optimum', 'wrap', 'shape', 'size', 'summary',
1831
+ // Script/resource attributes
1832
+ 'async', 'defer', 'noModule', 'charSet', 'httpEquiv', 'manifest',
1833
+ // Microdata/RDFa attributes
1834
+ 'about', 'datatype', 'inlist', 'prefix', 'property', 'resource', 'typeof', 'vocab', 'itemProp', 'itemScope', 'itemType', 'itemID', 'itemRef',
1835
+ // Deprecated but still used
1836
+ 'classID', 'contextMenu', 'keyParams', 'keyType', 'kind', 'label', 'list', 'profile', 'radioGroup', 'wmode', 'capture', 'challenge', 'scoped', 'step', 'form',
1837
+ // SVG-only attributes (not CSS properties)
1838
+ 'viewBox', 'preserveAspectRatio', 'xmlns', 'xlinkHref', 'xmlBase', 'xmlLang', 'xmlSpace', 'd', 'pathLength', 'points', 'markerEnd', 'markerMid', 'markerStart', 'clipPathUnits', 'gradientUnits', 'gradientTransform', 'patternUnits', 'patternTransform', 'patternContentUnits', 'spreadMethod', 'startOffset', 'stdDeviation', 'stitchTiles', 'surfaceScale', 'textLength', 'lengthAdjust', 'maskUnits', 'maskContentUnits', 'filterUnits', 'primitiveUnits', 'numOctaves', 'baseFrequency', 'seed', 'result', 'in2', 'values', 'keyTimes', 'keySplines', 'repeatCount', 'repeatDur', 'calcMode', 'attributeName', 'attributeType', 'begin', 'dur', 'end', 'by']);
1805
1839
  // Improved style prop detection
1806
1840
  const isStyleProp = prop => {
1807
1841
  // First check if it's a common event handler (these should never be treated as style props)
1808
1842
  if (commonEventHandlers.has(prop)) {
1809
1843
  return false;
1810
1844
  }
1845
+ // HTML attributes should never be treated as style props
1846
+ if (htmlOnlyAttributes.has(prop)) {
1847
+ return false;
1848
+ }
1849
+ // Any prop containing a hyphen is an HTML attribute (aria-*, data-*, accept-charset, etc.)
1850
+ // In React, CSS properties are always camelCase — only CSS custom properties use hyphens (--*),
1851
+ // and data-style-* is a special convention handled separately below.
1852
+ if (prop.includes('-') && !prop.startsWith('--') && !prop.startsWith('data-style-')) {
1853
+ return false;
1854
+ }
1811
1855
  // Check if it's a valid CSS property or custom style prop
1812
1856
  if (cssProperties.has(prop) || extraKeys.has(prop) || prop.startsWith('--') || prop.startsWith('data-style-') && !includeKeys.has(prop)) {
1813
1857
  return true;
@@ -2943,10 +2987,11 @@ const AnalyticsProvider = _ref => {
2943
2987
  trackEvent,
2944
2988
  children
2945
2989
  } = _ref;
2990
+ const value = useMemo(() => ({
2991
+ trackEvent
2992
+ }), [trackEvent]);
2946
2993
  return /*#__PURE__*/React.createElement(AnalyticsContext.Provider, {
2947
- value: {
2948
- trackEvent
2949
- }
2994
+ value: value
2950
2995
  }, children);
2951
2996
  };
2952
2997
 
@@ -2978,12 +3023,10 @@ function hashStyleProps(props) {
2978
3023
  */
2979
3024
  function useStableStyleMemo(propsToProcess, getColor, mediaQueries, devices, manager, theme) {
2980
3025
  const cacheRef = useRef(null);
2981
- // Compute hash of current props
2982
- const currentHash = useMemo(() => {
2983
- // Include theme in hash to bust cache on theme changes
2984
- const themeHash = theme ? JSON.stringify(theme) : '';
2985
- return hashStyleProps(propsToProcess) + '|' + hash(themeHash);
2986
- }, [propsToProcess, theme]);
3026
+ // Compute hash directly no useMemo since propsToProcess is always a new
3027
+ // reference (from destructuring), so the memo deps would always change.
3028
+ const themeHash = theme ? JSON.stringify(theme) : '';
3029
+ const currentHash = hashStyleProps(propsToProcess) + '|' + hash(themeHash);
2987
3030
  // Only recompute classes if hash changed
2988
3031
  if (!cacheRef.current || cacheRef.current.hash !== currentHash) {
2989
3032
  const classes = extractUtilityClasses(propsToProcess, getColor, mediaQueries, devices, manager);
@@ -3075,44 +3118,44 @@ const Element = /*#__PURE__*/React.memo(/*#__PURE__*/forwardRef((_ref, ref) => {
3075
3118
  };
3076
3119
  }, [animateOut, manager]);
3077
3120
  // Prepare props for processing (apply view/scroll timeline if needed)
3078
- const propsToProcess = useMemo(() => {
3079
- const processed = {
3080
- ...rest,
3081
- blend
3082
- };
3083
- // Apply view() timeline ONLY if animateOn='View' (not Both or Mount)
3084
- if (animateOn === 'View' && processed.animate) {
3085
- const animations = Array.isArray(processed.animate) ? processed.animate : [processed.animate];
3086
- processed.animate = animations.map(anim => {
3087
- // Only add timeline if not already specified
3088
- if (!anim.timeline) {
3089
- return {
3090
- ...anim,
3091
- timeline: 'view()',
3092
- range: anim.range || 'entry',
3093
- fillMode: anim.fillMode || 'both'
3094
- };
3095
- }
3096
- return anim;
3097
- });
3098
- }
3099
- // Apply scroll() timeline if animateOn='Scroll'
3100
- if (animateOn === 'Scroll' && processed.animate) {
3101
- const animations = Array.isArray(processed.animate) ? processed.animate : [processed.animate];
3102
- processed.animate = animations.map(anim => {
3103
- // Only add timeline if not already specified
3104
- if (!anim.timeline) {
3105
- return {
3106
- ...anim,
3107
- timeline: 'scroll()',
3108
- fillMode: anim.fillMode || 'both'
3109
- };
3110
- }
3111
- return anim;
3112
- });
3113
- }
3114
- return processed;
3115
- }, [rest, blend, animateOn]);
3121
+ // No useMemo `rest` is always a new reference from destructuring, so
3122
+ // memo deps would always change. useStableStyleMemo handles the real
3123
+ // memoization via hash-based comparison.
3124
+ const propsToProcess = {
3125
+ ...rest,
3126
+ blend
3127
+ };
3128
+ // Apply view() timeline ONLY if animateOn='View' (not Both or Mount)
3129
+ if (animateOn === 'View' && propsToProcess.animate) {
3130
+ const animations = Array.isArray(propsToProcess.animate) ? propsToProcess.animate : [propsToProcess.animate];
3131
+ propsToProcess.animate = animations.map(anim => {
3132
+ // Only add timeline if not already specified
3133
+ if (!anim.timeline) {
3134
+ return {
3135
+ ...anim,
3136
+ timeline: 'view()',
3137
+ range: anim.range || 'entry',
3138
+ fillMode: anim.fillMode || 'both'
3139
+ };
3140
+ }
3141
+ return anim;
3142
+ });
3143
+ }
3144
+ // Apply scroll() timeline if animateOn='Scroll'
3145
+ if (animateOn === 'Scroll' && propsToProcess.animate) {
3146
+ const animations = Array.isArray(propsToProcess.animate) ? propsToProcess.animate : [propsToProcess.animate];
3147
+ propsToProcess.animate = animations.map(anim => {
3148
+ // Only add timeline if not already specified
3149
+ if (!anim.timeline) {
3150
+ return {
3151
+ ...anim,
3152
+ timeline: 'scroll()',
3153
+ fillMode: anim.fillMode || 'both'
3154
+ };
3155
+ }
3156
+ return anim;
3157
+ });
3158
+ }
3116
3159
  // Use hash-based memoization for style extraction
3117
3160
  const utilityClasses = useStableStyleMemo(propsToProcess, getColor, mediaQueries, devices, manager, theme);
3118
3161
  const newProps = {
@@ -5034,14 +5077,28 @@ const WindowSizeProvider = _ref => {
5034
5077
  width: win?.innerWidth || 0,
5035
5078
  height: win?.innerHeight || 0
5036
5079
  });
5080
+ const timeoutRef = useRef();
5037
5081
  useEffect(() => {
5038
5082
  if (!win) return;
5039
- const handleResize = () => setSize({
5040
- width: win.innerWidth,
5041
- height: win.innerHeight
5042
- });
5083
+ const handleResize = () => {
5084
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
5085
+ timeoutRef.current = setTimeout(() => {
5086
+ const newWidth = win.innerWidth;
5087
+ const newHeight = win.innerHeight;
5088
+ setSize(prev => {
5089
+ if (prev.width === newWidth && prev.height === newHeight) return prev;
5090
+ return {
5091
+ width: newWidth,
5092
+ height: newHeight
5093
+ };
5094
+ });
5095
+ }, 100);
5096
+ };
5043
5097
  win.addEventListener('resize', handleResize);
5044
- return () => win.removeEventListener('resize', handleResize);
5098
+ return () => {
5099
+ win.removeEventListener('resize', handleResize);
5100
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
5101
+ };
5045
5102
  }, [win]);
5046
5103
  return /*#__PURE__*/React.createElement(WindowSizeContext.Provider, {
5047
5104
  value: size
@@ -5074,12 +5131,13 @@ function useActive() {
5074
5131
  return [ref, active];
5075
5132
  }
5076
5133
 
5134
+ const DEFAULT_CLICK_OUTSIDE_OPTIONS = {};
5077
5135
  function useClickOutside(options) {
5078
5136
  const [clickedOutside, setClickedOutside] = useState(false);
5079
5137
  const ref = useRef(null);
5080
5138
  const {
5081
5139
  targetWindow
5082
- } = options || {};
5140
+ } = options || DEFAULT_CLICK_OUTSIDE_OPTIONS;
5083
5141
  useEffect(() => {
5084
5142
  const win = targetWindow || (typeof window !== 'undefined' ? window : null);
5085
5143
  if (!win) return;
@@ -5099,13 +5157,14 @@ function useClickOutside(options) {
5099
5157
  return [ref, clickedOutside];
5100
5158
  }
5101
5159
 
5160
+ const DEFAULT_ELEMENT_POSITION_OPTIONS = {};
5102
5161
  /**
5103
5162
  * A React hook to determine an element's relative position within the viewport
5104
5163
  * and where the most available space is around it within the viewport.
5105
5164
  */
5106
5165
  function useElementPosition(options) {
5107
5166
  if (options === void 0) {
5108
- options = {};
5167
+ options = DEFAULT_ELEMENT_POSITION_OPTIONS;
5109
5168
  }
5110
5169
  const {
5111
5170
  trackChanges = true,
@@ -5277,18 +5336,21 @@ function useKeyPress(targetKey) {
5277
5336
  }
5278
5337
 
5279
5338
  const useMount = callback => {
5339
+ const callbackRef = useRef(callback);
5340
+ callbackRef.current = callback;
5280
5341
  useEffect(() => {
5281
- callback();
5342
+ callbackRef.current();
5282
5343
  }, []);
5283
5344
  };
5284
5345
 
5346
+ const DEFAULT_ON_SCREEN_OPTIONS = {};
5285
5347
  function useOnScreen(options) {
5286
5348
  const ref = useRef(null);
5287
5349
  const [isOnScreen, setOnScreen] = useState(false);
5288
5350
  const {
5289
5351
  targetWindow,
5290
5352
  ...observerOptions
5291
- } = options || {};
5353
+ } = options || DEFAULT_ON_SCREEN_OPTIONS;
5292
5354
  useEffect(() => {
5293
5355
  const node = ref.current;
5294
5356
  if (!node) return;
@@ -5307,7 +5369,7 @@ function useOnScreen(options) {
5307
5369
  return () => {
5308
5370
  observer.disconnect();
5309
5371
  };
5310
- }, [targetWindow, options]);
5372
+ }, [targetWindow, observerOptions.root, observerOptions.rootMargin, observerOptions.threshold]);
5311
5373
  return [ref, isOnScreen];
5312
5374
  }
5313
5375
 
@@ -5332,14 +5394,14 @@ const useBreakpoint = () => {
5332
5394
  devices
5333
5395
  } = context;
5334
5396
  // Helper to check if current screen matches a breakpoint or device
5335
- const on = s => devices[s] ? devices[s].includes(screen) : s === screen;
5336
- return {
5397
+ const on = useCallback(s => devices[s] ? devices[s].includes(screen) : s === screen, [devices, screen]);
5398
+ return useMemo(() => ({
5337
5399
  ...context,
5338
5400
  screen,
5339
5401
  orientation,
5340
5402
  on,
5341
5403
  is: on
5342
- };
5404
+ }), [context, screen, orientation, on]);
5343
5405
  };
5344
5406
  /**
5345
5407
  * Hook for components that need exact window dimensions.
@@ -5370,17 +5432,21 @@ const useResponsive = () => {
5370
5432
  orientation,
5371
5433
  devices
5372
5434
  } = context;
5373
- const on = s => devices[s] ? devices[s].includes(screen) : s === screen;
5374
- const result = {
5435
+ const on = useCallback(s => devices[s] ? devices[s].includes(screen) : s === screen, [devices, screen]);
5436
+ return useMemo(() => ({
5375
5437
  ...context,
5376
5438
  screen,
5377
5439
  orientation,
5378
5440
  on,
5379
5441
  is: on
5380
- };
5381
- return result;
5442
+ }), [context, screen, orientation, on]);
5382
5443
  };
5383
5444
 
5445
+ // Stable default references to prevent unnecessary re-renders
5446
+ const DEFAULT_SCROLL_OFFSET = [0, 0];
5447
+ const DEFAULT_SCROLL_OPTIONS = {};
5448
+ const DEFAULT_SCROLL_ANIMATION_OPTIONS = {};
5449
+ const DEFAULT_INFINITE_SCROLL_OPTIONS = {};
5384
5450
  // Helper to check if element is a Window object (works across iframes)
5385
5451
  const isWindow = obj => {
5386
5452
  return obj && obj.window === obj;
@@ -5414,10 +5480,10 @@ const getScrollDimensions = element => {
5414
5480
  const useScroll = function (_temp) {
5415
5481
  let {
5416
5482
  container,
5417
- offset = [0, 0],
5483
+ offset = DEFAULT_SCROLL_OFFSET,
5418
5484
  throttleMs = 100,
5419
5485
  disabled = false
5420
- } = _temp === void 0 ? {} : _temp;
5486
+ } = _temp === void 0 ? DEFAULT_SCROLL_OPTIONS : _temp;
5421
5487
  const [scrollPosition, setScrollPosition] = useState({
5422
5488
  x: 0,
5423
5489
  y: 0,
@@ -5556,7 +5622,7 @@ const useScroll = function (_temp) {
5556
5622
  // Enhanced useScrollAnimation with callback support and iframe support
5557
5623
  const useScrollAnimation = function (ref, options) {
5558
5624
  if (options === void 0) {
5559
- options = {};
5625
+ options = DEFAULT_SCROLL_ANIMATION_OPTIONS;
5560
5626
  }
5561
5627
  const [isInView, setIsInView] = useState(false);
5562
5628
  const [progress, setProgress] = useState(0);
@@ -5624,7 +5690,7 @@ const useSmoothScroll = targetWindow => {
5624
5690
  // Enhanced useInfiniteScroll with debouncing
5625
5691
  const useInfiniteScroll = function (callback, options) {
5626
5692
  if (options === void 0) {
5627
- options = {};
5693
+ options = DEFAULT_INFINITE_SCROLL_OPTIONS;
5628
5694
  }
5629
5695
  const [sentinel, setSentinel] = useState(null);
5630
5696
  const callbackRef = useRef(callback);
@@ -5719,12 +5785,13 @@ const useScrollDirection = function (threshold, targetWindow) {
5719
5785
 
5720
5786
  const useWindowSize = () => useContext(WindowSizeContext);
5721
5787
 
5788
+ const DEFAULT_IN_VIEW_OPTIONS = {};
5722
5789
  function useInView(options) {
5723
5790
  const {
5724
5791
  triggerOnce = false,
5725
5792
  targetWindow,
5726
5793
  ...observerOptions
5727
- } = options || {};
5794
+ } = options || DEFAULT_IN_VIEW_OPTIONS;
5728
5795
  const ref = useRef(null);
5729
5796
  const [inView, setInView] = useState(false);
5730
5797
  useEffect(() => {
@@ -5754,7 +5821,7 @@ function useInView(options) {
5754
5821
  return () => {
5755
5822
  observer.disconnect();
5756
5823
  };
5757
- }, [triggerOnce, targetWindow, ...Object.values(observerOptions || {})]);
5824
+ }, [triggerOnce, targetWindow, observerOptions.root, observerOptions.rootMargin, observerOptions.threshold]);
5758
5825
  return {
5759
5826
  ref,
5760
5827
  inView
@@ -5839,7 +5906,7 @@ function useIframe(iframeRef) {
5839
5906
  if (!iframe) return;
5840
5907
  const updateState = () => {
5841
5908
  const win = iframe.contentWindow;
5842
- const doc = iframe.contentDocument || win?.document;
5909
+ const doc = win?.document || iframe.contentDocument;
5843
5910
  if (win && doc) {
5844
5911
  setIframeWindow(win);
5845
5912
  setIframeDocument(doc);
@@ -1 +1 @@
1
- {"version":3,"file":"app-studio.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"app-studio.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}