UNPKG

689 kBJavaScriptView Raw
1/** @license React v16.10.0
2 * react-art.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global.ReactART = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18function _extends() {
19 _extends = Object.assign || function (target) {
20 for (var i = 1; i < arguments.length; i++) {
21 var source = arguments[i];
22
23 for (var key in source) {
24 if (Object.prototype.hasOwnProperty.call(source, key)) {
25 target[key] = source[key];
26 }
27 }
28 }
29
30 return target;
31 };
32
33 return _extends.apply(this, arguments);
34}
35
36function _inheritsLoose(subClass, superClass) {
37 subClass.prototype = Object.create(superClass.prototype);
38 subClass.prototype.constructor = subClass;
39 subClass.__proto__ = superClass;
40}
41
42function _assertThisInitialized(self) {
43 if (self === void 0) {
44 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
45 }
46
47 return self;
48}
49
50// TODO: this is special because it gets imported during build.
51
52var ReactVersion = '16.10.0';
53
54var LegacyRoot = 0;
55var BatchedRoot = 1;
56var ConcurrentRoot = 2;
57
58var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
59var _assign = ReactInternals.assign;
60
61// Do not require this module directly! Use normal `invariant` calls with
62// template literal strings. The messages will be converted to ReactError during
63// build, and in production they will be minified.
64
65// Do not require this module directly! Use normal `invariant` calls with
66// template literal strings. The messages will be converted to ReactError during
67// build, and in production they will be minified.
68function ReactError(error) {
69 error.name = 'Invariant Violation';
70 return error;
71}
72
73var FunctionComponent = 0;
74var ClassComponent = 1;
75var IndeterminateComponent = 2; // Before we know whether it is function or class
76
77var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
78
79var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
80
81var HostComponent = 5;
82var HostText = 6;
83var Fragment = 7;
84var Mode = 8;
85var ContextConsumer = 9;
86var ContextProvider = 10;
87var ForwardRef = 11;
88var Profiler = 12;
89var SuspenseComponent = 13;
90var MemoComponent = 14;
91var SimpleMemoComponent = 15;
92var LazyComponent = 16;
93var IncompleteClassComponent = 17;
94var DehydratedFragment = 18;
95var SuspenseListComponent = 19;
96var FundamentalComponent = 20;
97var ScopeComponent = 21;
98
99/**
100 * Use invariant() to assert state which your program assumes to be true.
101 *
102 * Provide sprintf-style format (only %s is supported) and arguments
103 * to provide information about what broke and what you were
104 * expecting.
105 *
106 * The invariant message will be stripped in production, but the invariant
107 * will remain to ensure logic does not differ in production.
108 */
109
110/**
111 * Similar to invariant but only logs a warning if the condition is not met.
112 * This can be used to log issues in development environments in critical
113 * paths. Removing the logging code for production environments will keep the
114 * same logic and follow the same code paths.
115 */
116var warningWithoutStack = function () {};
117
118{
119 warningWithoutStack = function (condition, format) {
120 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
121 args[_key - 2] = arguments[_key];
122 }
123
124 if (format === undefined) {
125 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
126 }
127
128 if (args.length > 8) {
129 // Check before the condition to catch violations early.
130 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
131 }
132
133 if (condition) {
134 return;
135 }
136
137 if (typeof console !== 'undefined') {
138 var argsWithFormat = args.map(function (item) {
139 return '' + item;
140 });
141 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
142 // breaks IE9: https://github.com/facebook/react/issues/13610
143
144 Function.prototype.apply.call(console.error, console, argsWithFormat);
145 }
146
147 try {
148 // --- Welcome to debugging React ---
149 // This error was thrown as a convenience so that you can use this stack
150 // to find the callsite that caused this warning to fire.
151 var argIndex = 0;
152 var message = 'Warning: ' + format.replace(/%s/g, function () {
153 return args[argIndex++];
154 });
155 throw new Error(message);
156 } catch (x) {}
157 };
158}
159
160var warningWithoutStack$1 = warningWithoutStack;
161
162/**
163 * `ReactInstanceMap` maintains a mapping from a public facing stateful
164 * instance (key) and the internal representation (value). This allows public
165 * methods to accept the user facing instance as an argument and map them back
166 * to internal methods.
167 *
168 * Note that this module is currently shared and assumed to be stateless.
169 * If this becomes an actual Map, that will break.
170 */
171
172/**
173 * This API should be called `delete` but we'd have to make sure to always
174 * transform these to strings for IE support. When this transform is fully
175 * supported we can rename it.
176 */
177
178function get(key) {
179 return key._reactInternalFiber;
180}
181
182function set$1(key, value) {
183 key._reactInternalFiber = value;
184}
185
186var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
187// Current owner and dispatcher used to share the same ref,
188// but PR #14548 split them out to better support the react-debug-tools package.
189
190if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
191 ReactSharedInternals.ReactCurrentDispatcher = {
192 current: null
193 };
194}
195
196if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
197 ReactSharedInternals.ReactCurrentBatchConfig = {
198 suspense: null
199 };
200}
201
202// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
203// nor polyfill, then a plain number is used for performance.
204var hasSymbol = typeof Symbol === 'function' && Symbol.for;
205var REACT_ELEMENT_TYPE$1 = hasSymbol ? Symbol.for('react.element') : 0xeac7;
206var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
207var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
208var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
209var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
210var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
211var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
212// (unstable) APIs that have been removed. Can we remove the symbols?
213
214
215var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
216var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
217var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
218var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
219var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
220var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
221var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
222var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
223var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7;
224var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
225var FAUX_ITERATOR_SYMBOL = '@@iterator';
226function getIteratorFn(maybeIterable) {
227 if (maybeIterable === null || typeof maybeIterable !== 'object') {
228 return null;
229 }
230
231 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
232
233 if (typeof maybeIterator === 'function') {
234 return maybeIterator;
235 }
236
237 return null;
238}
239
240/**
241 * Similar to invariant but only logs a warning if the condition is not met.
242 * This can be used to log issues in development environments in critical
243 * paths. Removing the logging code for production environments will keep the
244 * same logic and follow the same code paths.
245 */
246
247var warning = warningWithoutStack$1;
248
249{
250 warning = function (condition, format) {
251 if (condition) {
252 return;
253 }
254
255 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
256 var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args
257
258 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
259 args[_key - 2] = arguments[_key];
260 }
261
262 warningWithoutStack$1.apply(void 0, [false, format + '%s'].concat(args, [stack]));
263 };
264}
265
266var warning$1 = warning;
267
268var Uninitialized = -1;
269var Pending = 0;
270var Resolved = 1;
271var Rejected = 2;
272function refineResolvedLazyComponent(lazyComponent) {
273 return lazyComponent._status === Resolved ? lazyComponent._result : null;
274}
275function initializeLazyComponentType(lazyComponent) {
276 if (lazyComponent._status === Uninitialized) {
277 lazyComponent._status = Pending;
278 var ctor = lazyComponent._ctor;
279 var thenable = ctor();
280 lazyComponent._result = thenable;
281 thenable.then(function (moduleObject) {
282 if (lazyComponent._status === Pending) {
283 var defaultExport = moduleObject.default;
284
285 {
286 if (defaultExport === undefined) {
287 warning$1(false, 'lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
288 }
289 }
290
291 lazyComponent._status = Resolved;
292 lazyComponent._result = defaultExport;
293 }
294 }, function (error) {
295 if (lazyComponent._status === Pending) {
296 lazyComponent._status = Rejected;
297 lazyComponent._result = error;
298 }
299 });
300 }
301}
302
303function getWrappedName(outerType, innerType, wrapperName) {
304 var functionName = innerType.displayName || innerType.name || '';
305 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
306}
307
308function getComponentName(type) {
309 if (type == null) {
310 // Host root, text node or just invalid type.
311 return null;
312 }
313
314 {
315 if (typeof type.tag === 'number') {
316 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
317 }
318 }
319
320 if (typeof type === 'function') {
321 return type.displayName || type.name || null;
322 }
323
324 if (typeof type === 'string') {
325 return type;
326 }
327
328 switch (type) {
329 case REACT_FRAGMENT_TYPE:
330 return 'Fragment';
331
332 case REACT_PORTAL_TYPE:
333 return 'Portal';
334
335 case REACT_PROFILER_TYPE:
336 return "Profiler";
337
338 case REACT_STRICT_MODE_TYPE:
339 return 'StrictMode';
340
341 case REACT_SUSPENSE_TYPE:
342 return 'Suspense';
343
344 case REACT_SUSPENSE_LIST_TYPE:
345 return 'SuspenseList';
346 }
347
348 if (typeof type === 'object') {
349 switch (type.$$typeof) {
350 case REACT_CONTEXT_TYPE:
351 return 'Context.Consumer';
352
353 case REACT_PROVIDER_TYPE:
354 return 'Context.Provider';
355
356 case REACT_FORWARD_REF_TYPE:
357 return getWrappedName(type, type.render, 'ForwardRef');
358
359 case REACT_MEMO_TYPE:
360 return getComponentName(type.type);
361
362 case REACT_LAZY_TYPE:
363 {
364 var thenable = type;
365 var resolvedThenable = refineResolvedLazyComponent(thenable);
366
367 if (resolvedThenable) {
368 return getComponentName(resolvedThenable);
369 }
370
371 break;
372 }
373 }
374 }
375
376 return null;
377}
378
379// Don't change these two values. They're used by React Dev Tools.
380var NoEffect =
381/* */
3820;
383var PerformedWork =
384/* */
3851; // You can change the rest (and add more).
386
387var Placement =
388/* */
3892;
390var Update =
391/* */
3924;
393var PlacementAndUpdate =
394/* */
3956;
396var Deletion =
397/* */
3988;
399var ContentReset =
400/* */
40116;
402var Callback =
403/* */
40432;
405var DidCapture =
406/* */
40764;
408var Ref =
409/* */
410128;
411var Snapshot =
412/* */
413256;
414var Passive =
415/* */
416512;
417var Hydrating =
418/* */
4191024;
420var HydratingAndUpdate =
421/* */
4221028; // Passive & Update & Callback & Ref & Snapshot
423
424var LifecycleEffectMask =
425/* */
426932; // Union of all host effects
427
428var HostEffectMask =
429/* */
4302047;
431var Incomplete =
432/* */
4332048;
434var ShouldCapture =
435/* */
4364096;
437
438var enableUserTimingAPI = true; // Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
439
440var debugRenderPhaseSideEffects = false; // In some cases, StrictMode should also double-render lifecycles.
441// This can be confusing for tests though,
442// And it can be bad for performance in production.
443// This feature flag can be used to control the behavior:
444
445var debugRenderPhaseSideEffectsForStrictMode = true; // To preserve the "Pause on caught exceptions" behavior of the debugger, we
446// replay the begin phase of a failed component inside invokeGuardedCallback.
447
448var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; // Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
449
450var warnAboutDeprecatedLifecycles = true; // Gather advanced timing metrics for Profiler subtrees.
451
452var enableProfilerTimer = true; // Trace which interactions trigger each commit.
453
454var enableSchedulerTracing = true; // Only used in www builds.
455
456var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
457
458 // Only used in www builds.
459
460 // Only used in www builds.
461
462 // Disable javascript: URL strings in href for XSS protection.
463
464 // React Fire: prevent the value and checked attributes from syncing
465// with their related DOM properties
466
467 // These APIs will no longer be "unstable" in the upcoming 16.7 release,
468// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
469
470
471 // See https://github.com/react-native-community/discussions-and-proposals/issues/72 for more information
472// This is a flag so we can fix warnings in RN core before turning it on
473
474 // Experimental React Flare event system and event components support.
475
476var enableFlareAPI = false; // Experimental Host Component support.
477
478var enableFundamentalAPI = false; // Experimental Scope support.
479
480var enableScopeAPI = false; // New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
481
482 // We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
483// Till then, we warn about the missing mock, but still fallback to a sync mode compatible version
484
485var warnAboutUnmockedScheduler = false; // For tests, we flush suspense fallbacks in an act scope;
486// *except* in some of our own tests, where we test incremental loading states.
487
488var flushSuspenseFallbacksInTests = true; // Changes priority of some events like mousemove to user-blocking priority,
489// but without making them discrete. The flag exists in case it causes
490// starvation problems.
491
492 // Add a callback property to suspense to notify which promises are currently
493// in the update queue. This allows reporting and tracing of what is causing
494// the user to see a loading state.
495// Also allows hydration callbacks to fire when a dehydrated boundary gets
496// hydrated or deleted.
497
498var enableSuspenseCallback = false; // Part of the simplification of React.createElement so we can eventually move
499// from React.createElement to React.jsx
500// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
501
502var warnAboutDefaultPropsOnFunctionComponents = false;
503var warnAboutStringRefs = false;
504var disableLegacyContext = false;
505var disableSchedulerTimeoutBasedOnReactExpirationTime = false;
506
507var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
508function getNearestMountedFiber(fiber) {
509 var node = fiber;
510 var nearestMounted = fiber;
511
512 if (!fiber.alternate) {
513 // If there is no alternate, this might be a new tree that isn't inserted
514 // yet. If it is, then it will have a pending insertion effect on it.
515 var nextNode = node;
516
517 do {
518 node = nextNode;
519
520 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
521 // This is an insertion or in-progress hydration. The nearest possible
522 // mounted fiber is the parent but we need to continue to figure out
523 // if that one is still mounted.
524 nearestMounted = node.return;
525 }
526
527 nextNode = node.return;
528 } while (nextNode);
529 } else {
530 while (node.return) {
531 node = node.return;
532 }
533 }
534
535 if (node.tag === HostRoot) {
536 // TODO: Check if this was a nested HostRoot when used with
537 // renderContainerIntoSubtree.
538 return nearestMounted;
539 } // If we didn't hit the root, that means that we're in an disconnected tree
540 // that has been unmounted.
541
542
543 return null;
544}
545
546
547function isFiberMounted(fiber) {
548 return getNearestMountedFiber(fiber) === fiber;
549}
550function isMounted(component) {
551 {
552 var owner = ReactCurrentOwner.current;
553
554 if (owner !== null && owner.tag === ClassComponent) {
555 var ownerFiber = owner;
556 var instance = ownerFiber.stateNode;
557 !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0;
558 instance._warnedAboutRefsInRender = true;
559 }
560 }
561
562 var fiber = get(component);
563
564 if (!fiber) {
565 return false;
566 }
567
568 return getNearestMountedFiber(fiber) === fiber;
569}
570
571function assertIsMounted(fiber) {
572 (function () {
573 if (!(getNearestMountedFiber(fiber) === fiber)) {
574 {
575 throw ReactError(Error("Unable to find node on an unmounted component."));
576 }
577 }
578 })();
579}
580
581function findCurrentFiberUsingSlowPath(fiber) {
582 var alternate = fiber.alternate;
583
584 if (!alternate) {
585 // If there is no alternate, then we only need to check if it is mounted.
586 var nearestMounted = getNearestMountedFiber(fiber);
587
588 (function () {
589 if (!(nearestMounted !== null)) {
590 {
591 throw ReactError(Error("Unable to find node on an unmounted component."));
592 }
593 }
594 })();
595
596 if (nearestMounted !== fiber) {
597 return null;
598 }
599
600 return fiber;
601 } // If we have two possible branches, we'll walk backwards up to the root
602 // to see what path the root points to. On the way we may hit one of the
603 // special cases and we'll deal with them.
604
605
606 var a = fiber;
607 var b = alternate;
608
609 while (true) {
610 var parentA = a.return;
611
612 if (parentA === null) {
613 // We're at the root.
614 break;
615 }
616
617 var parentB = parentA.alternate;
618
619 if (parentB === null) {
620 // There is no alternate. This is an unusual case. Currently, it only
621 // happens when a Suspense component is hidden. An extra fragment fiber
622 // is inserted in between the Suspense fiber and its children. Skip
623 // over this extra fragment fiber and proceed to the next parent.
624 var nextParent = parentA.return;
625
626 if (nextParent !== null) {
627 a = b = nextParent;
628 continue;
629 } // If there's no parent, we're at the root.
630
631
632 break;
633 } // If both copies of the parent fiber point to the same child, we can
634 // assume that the child is current. This happens when we bailout on low
635 // priority: the bailed out fiber's child reuses the current child.
636
637
638 if (parentA.child === parentB.child) {
639 var child = parentA.child;
640
641 while (child) {
642 if (child === a) {
643 // We've determined that A is the current branch.
644 assertIsMounted(parentA);
645 return fiber;
646 }
647
648 if (child === b) {
649 // We've determined that B is the current branch.
650 assertIsMounted(parentA);
651 return alternate;
652 }
653
654 child = child.sibling;
655 } // We should never have an alternate for any mounting node. So the only
656 // way this could possibly happen is if this was unmounted, if at all.
657
658
659 (function () {
660 {
661 {
662 throw ReactError(Error("Unable to find node on an unmounted component."));
663 }
664 }
665 })();
666 }
667
668 if (a.return !== b.return) {
669 // The return pointer of A and the return pointer of B point to different
670 // fibers. We assume that return pointers never criss-cross, so A must
671 // belong to the child set of A.return, and B must belong to the child
672 // set of B.return.
673 a = parentA;
674 b = parentB;
675 } else {
676 // The return pointers point to the same fiber. We'll have to use the
677 // default, slow path: scan the child sets of each parent alternate to see
678 // which child belongs to which set.
679 //
680 // Search parent A's child set
681 var didFindChild = false;
682 var _child = parentA.child;
683
684 while (_child) {
685 if (_child === a) {
686 didFindChild = true;
687 a = parentA;
688 b = parentB;
689 break;
690 }
691
692 if (_child === b) {
693 didFindChild = true;
694 b = parentA;
695 a = parentB;
696 break;
697 }
698
699 _child = _child.sibling;
700 }
701
702 if (!didFindChild) {
703 // Search parent B's child set
704 _child = parentB.child;
705
706 while (_child) {
707 if (_child === a) {
708 didFindChild = true;
709 a = parentB;
710 b = parentA;
711 break;
712 }
713
714 if (_child === b) {
715 didFindChild = true;
716 b = parentB;
717 a = parentA;
718 break;
719 }
720
721 _child = _child.sibling;
722 }
723
724 (function () {
725 if (!didFindChild) {
726 {
727 throw ReactError(Error("Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue."));
728 }
729 }
730 })();
731 }
732 }
733
734 (function () {
735 if (!(a.alternate === b)) {
736 {
737 throw ReactError(Error("Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue."));
738 }
739 }
740 })();
741 } // If the root is not a host container, we're in a disconnected tree. I.e.
742 // unmounted.
743
744
745 (function () {
746 if (!(a.tag === HostRoot)) {
747 {
748 throw ReactError(Error("Unable to find node on an unmounted component."));
749 }
750 }
751 })();
752
753 if (a.stateNode.current === a) {
754 // We've determined that A is the current branch.
755 return fiber;
756 } // Otherwise B has to be current branch.
757
758
759 return alternate;
760}
761function findCurrentHostFiber(parent) {
762 var currentParent = findCurrentFiberUsingSlowPath(parent);
763
764 if (!currentParent) {
765 return null;
766 } // Next we'll drill down this component to find the first HostComponent/Text.
767
768
769 var node = currentParent;
770
771 while (true) {
772 if (node.tag === HostComponent || node.tag === HostText) {
773 return node;
774 } else if (node.child) {
775 node.child.return = node;
776 node = node.child;
777 continue;
778 }
779
780 if (node === currentParent) {
781 return null;
782 }
783
784 while (!node.sibling) {
785 if (!node.return || node.return === currentParent) {
786 return null;
787 }
788
789 node = node.return;
790 }
791
792 node.sibling.return = node.return;
793 node = node.sibling;
794 } // Flow needs the return null here, but ESLint complains about it.
795 // eslint-disable-next-line no-unreachable
796
797
798 return null;
799}
800
801var _class = function(mixins){
802 var proto = {};
803 for (var i = 0, l = arguments.length; i < l; i++){
804 var mixin = arguments[i];
805 if (typeof mixin == 'function') mixin = mixin.prototype;
806 for (var key in mixin) proto[key] = mixin[key];
807 }
808 if (!proto.initialize) proto.initialize = function(){};
809 proto.constructor = function(a,b,c,d,e,f,g,h){
810 return new proto.initialize(a,b,c,d,e,f,g,h);
811 };
812 proto.constructor.prototype = proto.initialize.prototype = proto;
813 return proto.constructor;
814};
815
816function Transform(xx, yx, xy, yy, x, y){
817 if (xx && typeof xx == 'object'){
818 yx = xx.yx; yy = xx.yy; y = xx.y;
819 xy = xx.xy; x = xx.x; xx = xx.xx;
820 }
821 this.xx = xx == null ? 1 : xx;
822 this.yx = yx || 0;
823 this.xy = xy || 0;
824 this.yy = yy == null ? 1 : yy;
825 this.x = (x == null ? this.x : x) || 0;
826 this.y = (y == null ? this.y : y) || 0;
827 this._transform();
828 return this;
829}
830
831var transform = _class({
832
833 initialize: Transform,
834
835 _transform: function(){},
836
837 xx: 1, yx: 0, x: 0,
838 xy: 0, yy: 1, y: 0,
839
840 transform: function(xx, yx, xy, yy, x, y){
841 var m = this;
842 if (xx && typeof xx == 'object'){
843 yx = xx.yx; yy = xx.yy; y = xx.y;
844 xy = xx.xy; x = xx.x; xx = xx.xx;
845 }
846 if (!x) x = 0;
847 if (!y) y = 0;
848 return this.transformTo(
849 m.xx * xx + m.xy * yx,
850 m.yx * xx + m.yy * yx,
851 m.xx * xy + m.xy * yy,
852 m.yx * xy + m.yy * yy,
853 m.xx * x + m.xy * y + m.x,
854 m.yx * x + m.yy * y + m.y
855 );
856 },
857
858 transformTo: Transform,
859
860 translate: function(x, y){
861 return this.transform(1, 0, 0, 1, x, y);
862 },
863
864 move: function(x, y){
865 this.x += x || 0;
866 this.y += y || 0;
867 this._transform();
868 return this;
869 },
870
871 scale: function(x, y){
872 if (y == null) y = x;
873 return this.transform(x, 0, 0, y, 0, 0);
874 },
875
876 rotate: function(deg, x, y){
877 if (x == null || y == null){
878 x = (this.left || 0) + (this.width || 0) / 2;
879 y = (this.top || 0) + (this.height || 0) / 2;
880 }
881
882 var rad = deg * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
883
884 this.transform(1, 0, 0, 1, x, y);
885 var m = this;
886
887 return this.transformTo(
888 cos * m.xx - sin * m.yx,
889 sin * m.xx + cos * m.yx,
890 cos * m.xy - sin * m.yy,
891 sin * m.xy + cos * m.yy,
892 m.x,
893 m.y
894 ).transform(1, 0, 0, 1, -x, -y);
895 },
896
897 moveTo: function(x, y){
898 var m = this;
899 return this.transformTo(m.xx, m.yx, m.xy, m.yy, x, y);
900 },
901
902 rotateTo: function(deg, x, y){
903 var m = this;
904 var flip = m.yx / m.xx > m.yy / m.xy ? -1 : 1;
905 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = -flip;
906 return this.rotate(deg - Math.atan2(flip * m.yx, flip * m.xx) * 180 / Math.PI, x, y);
907 },
908
909 scaleTo: function(x, y){
910 // Normalize
911 var m = this;
912
913 var h = Math.sqrt(m.xx * m.xx + m.yx * m.yx);
914 m.xx /= h; m.yx /= h;
915
916 h = Math.sqrt(m.yy * m.yy + m.xy * m.xy);
917 m.yy /= h; m.xy /= h;
918
919 return this.scale(x, y);
920 },
921
922 resizeTo: function(width, height){
923 var w = this.width, h = this.height;
924 if (!w || !h) return this;
925 return this.scaleTo(width / w, height / h);
926 },
927
928 /*
929 inverse: function(){
930 var a = this.xx, b = this.yx,
931 c = this.xy, d = this.yy,
932 e = this.x, f = this.y;
933 if (a * d - b * c == 0) return null;
934 return new Transform(
935 d/(a * d-b * c), b/(b * c-a * d),
936 c/(b * c-a * d), a/(a * d-b * c),
937 (d * e-c * f)/(b * c-a * d), (b * e-a * f)/(a * d-b * c)
938 );
939 },
940 */
941
942 inversePoint: function(x, y){
943 var a = this.xx, b = this.yx,
944 c = this.xy, d = this.yy,
945 e = this.x, f = this.y;
946 var det = b * c - a * d;
947 if (det == 0) return null;
948 return {
949 x: (d * (e - x) + c * (y - f)) / det,
950 y: (a * (f - y) + b * (x - e)) / det
951 };
952 },
953
954 point: function(x, y){
955 var m = this;
956 return {
957 x: m.xx * x + m.xy * y + m.x,
958 y: m.yx * x + m.yy * y + m.y
959 };
960 }
961
962});
963
964var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
965
966
967
968
969
970function createCommonjsModule(fn, module) {
971 return module = { exports: {} }, fn(module, module.exports), module.exports;
972}
973
974var current = createCommonjsModule(function (module, exports) {
975function warning(){
976 throw new Error('You must require a mode before requiring anything else.');
977}
978
979exports.Surface = warning;
980exports.Path = warning;
981exports.Shape = warning;
982exports.Group = warning;
983exports.ClippingRectangle = warning;
984exports.Text = warning;
985
986exports.setCurrent = function(mode){
987 for (var key in mode){
988 exports[key] = mode[key];
989 }
990};
991});
992
993var current_1 = current.Surface;
994var current_2 = current.Path;
995var current_3 = current.Shape;
996var current_4 = current.Group;
997var current_5 = current.ClippingRectangle;
998var current_6 = current.Text;
999var current_7 = current.setCurrent;
1000
1001var TYPES = {
1002 CLIPPING_RECTANGLE: 'ClippingRectangle',
1003 GROUP: 'Group',
1004 SHAPE: 'Shape',
1005 TEXT: 'Text'
1006};
1007var EVENT_TYPES = {
1008 onClick: 'click',
1009 onMouseMove: 'mousemove',
1010 onMouseOver: 'mouseover',
1011 onMouseOut: 'mouseout',
1012 onMouseUp: 'mouseup',
1013 onMouseDown: 'mousedown'
1014};
1015function childrenAsString(children) {
1016 if (!children) {
1017 return '';
1018 } else if (typeof children === 'string') {
1019 return children;
1020 } else if (children.length) {
1021 return children.join('');
1022 } else {
1023 return '';
1024 }
1025}
1026
1027// can re-export everything from this module.
1028
1029function shim() {
1030 (function () {
1031 {
1032 {
1033 throw ReactError(Error("The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue."));
1034 }
1035 }
1036 })();
1037} // Persistence (when unsupported)
1038
1039
1040var supportsPersistence = false;
1041var cloneInstance = shim;
1042var cloneFundamentalInstance = shim;
1043var createContainerChildSet = shim;
1044var appendChildToContainerChildSet = shim;
1045var finalizeContainerChildren = shim;
1046var replaceContainerChildren = shim;
1047var cloneHiddenInstance = shim;
1048var cloneHiddenTextInstance = shim;
1049
1050// can re-export everything from this module.
1051
1052function shim$1() {
1053 (function () {
1054 {
1055 {
1056 throw ReactError(Error("The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue."));
1057 }
1058 }
1059 })();
1060} // Hydration (when unsupported)
1061
1062
1063var supportsHydration = false;
1064var canHydrateInstance = shim$1;
1065var canHydrateTextInstance = shim$1;
1066var canHydrateSuspenseInstance = shim$1;
1067var isSuspenseInstancePending = shim$1;
1068var isSuspenseInstanceFallback = shim$1;
1069var registerSuspenseInstanceRetry = shim$1;
1070var getNextHydratableSibling = shim$1;
1071var getFirstHydratableChild = shim$1;
1072var hydrateInstance = shim$1;
1073var hydrateTextInstance = shim$1;
1074var hydrateSuspenseInstance = shim$1;
1075var getNextHydratableInstanceAfterSuspenseInstance = shim$1;
1076var commitHydratedContainer = shim$1;
1077var commitHydratedSuspenseInstance = shim$1;
1078var clearSuspenseBoundary = shim$1;
1079var clearSuspenseBoundaryFromContainer = shim$1;
1080var didNotMatchHydratedContainerTextInstance = shim$1;
1081var didNotMatchHydratedTextInstance = shim$1;
1082var didNotHydrateContainerInstance = shim$1;
1083var didNotHydrateInstance = shim$1;
1084var didNotFindHydratableContainerInstance = shim$1;
1085var didNotFindHydratableContainerTextInstance = shim$1;
1086var didNotFindHydratableContainerSuspenseInstance = shim$1;
1087var didNotFindHydratableInstance = shim$1;
1088var didNotFindHydratableTextInstance = shim$1;
1089var didNotFindHydratableSuspenseInstance = shim$1;
1090
1091var pooledTransform = new transform();
1092var NO_CONTEXT = {};
1093var UPDATE_SIGNAL = {};
1094
1095{
1096 Object.freeze(NO_CONTEXT);
1097 Object.freeze(UPDATE_SIGNAL);
1098}
1099/** Helper Methods */
1100
1101
1102function addEventListeners(instance, type, listener) {
1103 // We need to explicitly unregister before unmount.
1104 // For this reason we need to track subscriptions.
1105 if (!instance._listeners) {
1106 instance._listeners = {};
1107 instance._subscriptions = {};
1108 }
1109
1110 instance._listeners[type] = listener;
1111
1112 if (listener) {
1113 if (!instance._subscriptions[type]) {
1114 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
1115 }
1116 } else {
1117 if (instance._subscriptions[type]) {
1118 instance._subscriptions[type]();
1119
1120 delete instance._subscriptions[type];
1121 }
1122 }
1123}
1124
1125function createEventHandler(instance) {
1126 return function handleEvent(event) {
1127 var listener = instance._listeners[event.type];
1128
1129 if (!listener) {// Noop
1130 } else if (typeof listener === 'function') {
1131 listener.call(instance, event);
1132 } else if (listener.handleEvent) {
1133 listener.handleEvent(event);
1134 }
1135 };
1136}
1137
1138function destroyEventListeners(instance) {
1139 if (instance._subscriptions) {
1140 for (var type in instance._subscriptions) {
1141 instance._subscriptions[type]();
1142 }
1143 }
1144
1145 instance._subscriptions = null;
1146 instance._listeners = null;
1147}
1148
1149function getScaleX(props) {
1150 if (props.scaleX != null) {
1151 return props.scaleX;
1152 } else if (props.scale != null) {
1153 return props.scale;
1154 } else {
1155 return 1;
1156 }
1157}
1158
1159function getScaleY(props) {
1160 if (props.scaleY != null) {
1161 return props.scaleY;
1162 } else if (props.scale != null) {
1163 return props.scale;
1164 } else {
1165 return 1;
1166 }
1167}
1168
1169function isSameFont(oldFont, newFont) {
1170 if (oldFont === newFont) {
1171 return true;
1172 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
1173 return false;
1174 } else {
1175 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
1176 }
1177}
1178/** Render Methods */
1179
1180
1181function applyClippingRectangleProps(instance, props) {
1182 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1183 applyNodeProps(instance, props, prevProps);
1184 instance.width = props.width;
1185 instance.height = props.height;
1186}
1187
1188function applyGroupProps(instance, props) {
1189 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1190 applyNodeProps(instance, props, prevProps);
1191 instance.width = props.width;
1192 instance.height = props.height;
1193}
1194
1195function applyNodeProps(instance, props) {
1196 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1197 var scaleX = getScaleX(props);
1198 var scaleY = getScaleY(props);
1199 pooledTransform.transformTo(1, 0, 0, 1, 0, 0).move(props.x || 0, props.y || 0).rotate(props.rotation || 0, props.originX, props.originY).scale(scaleX, scaleY, props.originX, props.originY);
1200
1201 if (props.transform != null) {
1202 pooledTransform.transform(props.transform);
1203 }
1204
1205 if (instance.xx !== pooledTransform.xx || instance.yx !== pooledTransform.yx || instance.xy !== pooledTransform.xy || instance.yy !== pooledTransform.yy || instance.x !== pooledTransform.x || instance.y !== pooledTransform.y) {
1206 instance.transformTo(pooledTransform);
1207 }
1208
1209 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
1210 instance.indicate(props.cursor, props.title);
1211 }
1212
1213 if (instance.blend && props.opacity !== prevProps.opacity) {
1214 instance.blend(props.opacity == null ? 1 : props.opacity);
1215 }
1216
1217 if (props.visible !== prevProps.visible) {
1218 if (props.visible == null || props.visible) {
1219 instance.show();
1220 } else {
1221 instance.hide();
1222 }
1223 }
1224
1225 for (var type in EVENT_TYPES) {
1226 addEventListeners(instance, EVENT_TYPES[type], props[type]);
1227 }
1228}
1229
1230function applyRenderableNodeProps(instance, props) {
1231 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1232 applyNodeProps(instance, props, prevProps);
1233
1234 if (prevProps.fill !== props.fill) {
1235 if (props.fill && props.fill.applyFill) {
1236 props.fill.applyFill(instance);
1237 } else {
1238 instance.fill(props.fill);
1239 }
1240 }
1241
1242 if (prevProps.stroke !== props.stroke || prevProps.strokeWidth !== props.strokeWidth || prevProps.strokeCap !== props.strokeCap || prevProps.strokeJoin !== props.strokeJoin || // TODO: Consider deep check of stokeDash; may benefit VML in IE.
1243 prevProps.strokeDash !== props.strokeDash) {
1244 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
1245 }
1246}
1247
1248function applyShapeProps(instance, props) {
1249 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1250 applyRenderableNodeProps(instance, props, prevProps);
1251 var path = props.d || childrenAsString(props.children);
1252 var prevDelta = instance._prevDelta;
1253 var prevPath = instance._prevPath;
1254
1255 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
1256 instance.draw(path, props.width, props.height);
1257 instance._prevDelta = path.delta;
1258 instance._prevPath = path;
1259 }
1260}
1261
1262function applyTextProps(instance, props) {
1263 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1264 applyRenderableNodeProps(instance, props, prevProps);
1265 var string = props.children;
1266
1267 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
1268 instance.draw(string, props.font, props.alignment, props.path);
1269 instance._currentString = string;
1270 }
1271}
1272
1273function appendInitialChild(parentInstance, child) {
1274 if (typeof child === 'string') {
1275 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
1276 (function () {
1277 {
1278 {
1279 throw ReactError(Error("Text children should already be flattened."));
1280 }
1281 }
1282 })();
1283
1284 return;
1285 }
1286
1287 child.inject(parentInstance);
1288}
1289function createInstance(type, props, internalInstanceHandle) {
1290 var instance;
1291
1292 switch (type) {
1293 case TYPES.CLIPPING_RECTANGLE:
1294 instance = current.ClippingRectangle();
1295 instance._applyProps = applyClippingRectangleProps;
1296 break;
1297
1298 case TYPES.GROUP:
1299 instance = current.Group();
1300 instance._applyProps = applyGroupProps;
1301 break;
1302
1303 case TYPES.SHAPE:
1304 instance = current.Shape();
1305 instance._applyProps = applyShapeProps;
1306 break;
1307
1308 case TYPES.TEXT:
1309 instance = current.Text(props.children, props.font, props.alignment, props.path);
1310 instance._applyProps = applyTextProps;
1311 break;
1312 }
1313
1314 (function () {
1315 if (!instance) {
1316 {
1317 throw ReactError(Error("ReactART does not support the type \"" + type + "\""));
1318 }
1319 }
1320 })();
1321
1322 instance._applyProps(instance, props);
1323
1324 return instance;
1325}
1326function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
1327 return text;
1328}
1329function finalizeInitialChildren(domElement, type, props) {
1330 return false;
1331}
1332function getPublicInstance(instance) {
1333 return instance;
1334}
1335function prepareForCommit() {// Noop
1336}
1337function prepareUpdate(domElement, type, oldProps, newProps) {
1338 return UPDATE_SIGNAL;
1339}
1340function resetAfterCommit() {// Noop
1341}
1342function resetTextContent(domElement) {// Noop
1343}
1344function shouldDeprioritizeSubtree(type, props) {
1345 return false;
1346}
1347function getRootHostContext() {
1348 return NO_CONTEXT;
1349}
1350function getChildHostContext() {
1351 return NO_CONTEXT;
1352}
1353var scheduleTimeout = setTimeout;
1354var cancelTimeout = clearTimeout;
1355var noTimeout = -1;
1356function shouldSetTextContent(type, props) {
1357 return typeof props.children === 'string' || typeof props.children === 'number';
1358} // The ART renderer is secondary to the React DOM renderer.
1359
1360var isPrimaryRenderer = false; // The ART renderer shouldn't trigger missing act() warnings
1361
1362var warnsIfNotActing = false;
1363var supportsMutation = true;
1364function appendChild(parentInstance, child) {
1365 if (child.parentNode === parentInstance) {
1366 child.eject();
1367 }
1368
1369 child.inject(parentInstance);
1370}
1371function appendChildToContainer(parentInstance, child) {
1372 if (child.parentNode === parentInstance) {
1373 child.eject();
1374 }
1375
1376 child.inject(parentInstance);
1377}
1378function insertBefore(parentInstance, child, beforeChild) {
1379 (function () {
1380 if (!(child !== beforeChild)) {
1381 {
1382 throw ReactError(Error("ReactART: Can not insert node before itself"));
1383 }
1384 }
1385 })();
1386
1387 child.injectBefore(beforeChild);
1388}
1389function insertInContainerBefore(parentInstance, child, beforeChild) {
1390 (function () {
1391 if (!(child !== beforeChild)) {
1392 {
1393 throw ReactError(Error("ReactART: Can not insert node before itself"));
1394 }
1395 }
1396 })();
1397
1398 child.injectBefore(beforeChild);
1399}
1400function removeChild(parentInstance, child) {
1401 destroyEventListeners(child);
1402 child.eject();
1403}
1404function removeChildFromContainer(parentInstance, child) {
1405 destroyEventListeners(child);
1406 child.eject();
1407}
1408
1409
1410function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1411 instance._applyProps(instance, newProps, oldProps);
1412}
1413function hideInstance(instance) {
1414 instance.hide();
1415}
1416
1417function unhideInstance(instance, props) {
1418 if (props.visible == null || props.visible) {
1419 instance.show();
1420 }
1421}
1422function unhideTextInstance(textInstance, text) {// Noop
1423}
1424function mountResponderInstance(responder, responderInstance, props, state, instance) {
1425 throw new Error('Not yet implemented.');
1426}
1427function unmountResponderInstance(responderInstance) {
1428 throw new Error('Not yet implemented.');
1429}
1430function getFundamentalComponentInstance(fundamentalInstance) {
1431 throw new Error('Not yet implemented.');
1432}
1433function mountFundamentalComponent(fundamentalInstance) {
1434 throw new Error('Not yet implemented.');
1435}
1436function shouldUpdateFundamentalComponent(fundamentalInstance) {
1437 throw new Error('Not yet implemented.');
1438}
1439function updateFundamentalComponent(fundamentalInstance) {
1440 throw new Error('Not yet implemented.');
1441}
1442function unmountFundamentalComponent(fundamentalInstance) {
1443 throw new Error('Not yet implemented.');
1444}
1445
1446/**
1447 * Copyright (c) 2013-present, Facebook, Inc.
1448 *
1449 * This source code is licensed under the MIT license found in the
1450 * LICENSE file in the root directory of this source tree.
1451 */
1452
1453
1454
1455var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1456
1457var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
1458
1459/**
1460 * Copyright (c) 2013-present, Facebook, Inc.
1461 *
1462 * This source code is licensed under the MIT license found in the
1463 * LICENSE file in the root directory of this source tree.
1464 */
1465
1466
1467
1468var printWarning = function() {};
1469
1470{
1471 var ReactPropTypesSecret = ReactPropTypesSecret_1;
1472 var loggedTypeFailures = {};
1473 var has$1 = Function.call.bind(Object.prototype.hasOwnProperty);
1474
1475 printWarning = function(text) {
1476 var message = 'Warning: ' + text;
1477 if (typeof console !== 'undefined') {
1478 console.error(message);
1479 }
1480 try {
1481 // --- Welcome to debugging React ---
1482 // This error was thrown as a convenience so that you can use this stack
1483 // to find the callsite that caused this warning to fire.
1484 throw new Error(message);
1485 } catch (x) {}
1486 };
1487}
1488
1489/**
1490 * Assert that the values match with the type specs.
1491 * Error messages are memorized and will only be shown once.
1492 *
1493 * @param {object} typeSpecs Map of name to a ReactPropType
1494 * @param {object} values Runtime values that need to be type-checked
1495 * @param {string} location e.g. "prop", "context", "child context"
1496 * @param {string} componentName Name of the component for error messages.
1497 * @param {?Function} getStack Returns the component stack.
1498 * @private
1499 */
1500function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1501 {
1502 for (var typeSpecName in typeSpecs) {
1503 if (has$1(typeSpecs, typeSpecName)) {
1504 var error;
1505 // Prop type validation may throw. In case they do, we don't want to
1506 // fail the render phase where it didn't fail before. So we log it.
1507 // After these have been cleaned up, we'll let them throw.
1508 try {
1509 // This is intentionally an invariant that gets caught. It's the same
1510 // behavior as without this statement except with a better message.
1511 if (typeof typeSpecs[typeSpecName] !== 'function') {
1512 var err = Error(
1513 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1514 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1515 );
1516 err.name = 'Invariant Violation';
1517 throw err;
1518 }
1519 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
1520 } catch (ex) {
1521 error = ex;
1522 }
1523 if (error && !(error instanceof Error)) {
1524 printWarning(
1525 (componentName || 'React class') + ': type specification of ' +
1526 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1527 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1528 'You may have forgotten to pass an argument to the type checker ' +
1529 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1530 'shape all require an argument).'
1531 );
1532 }
1533 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1534 // Only monitor this failure once because there tends to be a lot of the
1535 // same error.
1536 loggedTypeFailures[error.message] = true;
1537
1538 var stack = getStack ? getStack() : '';
1539
1540 printWarning(
1541 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1542 );
1543 }
1544 }
1545 }
1546 }
1547}
1548
1549/**
1550 * Resets warning cache when testing.
1551 *
1552 * @private
1553 */
1554checkPropTypes.resetWarningCache = function() {
1555 {
1556 loggedTypeFailures = {};
1557 }
1558};
1559
1560var checkPropTypes_1 = checkPropTypes;
1561
1562var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1563var describeComponentFrame = function (name, source, ownerName) {
1564 var sourceInfo = '';
1565
1566 if (source) {
1567 var path = source.fileName;
1568 var fileName = path.replace(BEFORE_SLASH_RE, '');
1569
1570 {
1571 // In DEV, include code for a common special case:
1572 // prefer "folder/index.js" instead of just "index.js".
1573 if (/^index\./.test(fileName)) {
1574 var match = path.match(BEFORE_SLASH_RE);
1575
1576 if (match) {
1577 var pathBeforeSlash = match[1];
1578
1579 if (pathBeforeSlash) {
1580 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1581 fileName = folderName + '/' + fileName;
1582 }
1583 }
1584 }
1585 }
1586
1587 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1588 } else if (ownerName) {
1589 sourceInfo = ' (created by ' + ownerName + ')';
1590 }
1591
1592 return '\n in ' + (name || 'Unknown') + sourceInfo;
1593};
1594
1595var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1596
1597function describeFiber(fiber) {
1598 switch (fiber.tag) {
1599 case HostRoot:
1600 case HostPortal:
1601 case HostText:
1602 case Fragment:
1603 case ContextProvider:
1604 case ContextConsumer:
1605 return '';
1606
1607 default:
1608 var owner = fiber._debugOwner;
1609 var source = fiber._debugSource;
1610 var name = getComponentName(fiber.type);
1611 var ownerName = null;
1612
1613 if (owner) {
1614 ownerName = getComponentName(owner.type);
1615 }
1616
1617 return describeComponentFrame(name, source, ownerName);
1618 }
1619}
1620
1621function getStackByFiberInDevAndProd(workInProgress) {
1622 var info = '';
1623 var node = workInProgress;
1624
1625 do {
1626 info += describeFiber(node);
1627 node = node.return;
1628 } while (node);
1629
1630 return info;
1631}
1632var current$1 = null;
1633var phase = null;
1634function getCurrentFiberOwnerNameInDevOrNull() {
1635 {
1636 if (current$1 === null) {
1637 return null;
1638 }
1639
1640 var owner = current$1._debugOwner;
1641
1642 if (owner !== null && typeof owner !== 'undefined') {
1643 return getComponentName(owner.type);
1644 }
1645 }
1646
1647 return null;
1648}
1649function getCurrentFiberStackInDev() {
1650 {
1651 if (current$1 === null) {
1652 return '';
1653 } // Safe because if current fiber exists, we are reconciling,
1654 // and it is guaranteed to be the work-in-progress version.
1655
1656
1657 return getStackByFiberInDevAndProd(current$1);
1658 }
1659
1660 return '';
1661}
1662function resetCurrentFiber() {
1663 {
1664 ReactDebugCurrentFrame.getCurrentStack = null;
1665 current$1 = null;
1666 phase = null;
1667 }
1668}
1669function setCurrentFiber(fiber) {
1670 {
1671 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1672 current$1 = fiber;
1673 phase = null;
1674 }
1675}
1676function setCurrentPhase(lifeCyclePhase) {
1677 {
1678 phase = lifeCyclePhase;
1679 }
1680}
1681
1682// Prefix measurements so that it's possible to filter them.
1683// Longer prefixes are hard to read in DevTools.
1684var reactEmoji = "\u269B";
1685var warningEmoji = "\u26D4";
1686var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; // Keep track of current fiber so that we know the path to unwind on pause.
1687// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1688
1689var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
1690// Reusing `currentFiber` would be confusing for this because user code fiber
1691// can change during commit phase too, but we don't need to unwind it (since
1692// lifecycles in the commit phase don't resemble a tree).
1693
1694var currentPhase = null;
1695var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
1696// so we will keep track of it, and include it in the report.
1697// Track commits caused by cascading updates.
1698
1699var isCommitting = false;
1700var hasScheduledUpdateInCurrentCommit = false;
1701var hasScheduledUpdateInCurrentPhase = false;
1702var commitCountInCurrentWorkLoop = 0;
1703var effectCountInCurrentCommit = 0;
1704// to avoid stretch the commit phase with measurement overhead.
1705
1706var labelsInCurrentCommit = new Set();
1707
1708var formatMarkName = function (markName) {
1709 return reactEmoji + " " + markName;
1710};
1711
1712var formatLabel = function (label, warning) {
1713 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
1714 var suffix = warning ? " Warning: " + warning : '';
1715 return "" + prefix + label + suffix;
1716};
1717
1718var beginMark = function (markName) {
1719 performance.mark(formatMarkName(markName));
1720};
1721
1722var clearMark = function (markName) {
1723 performance.clearMarks(formatMarkName(markName));
1724};
1725
1726var endMark = function (label, markName, warning) {
1727 var formattedMarkName = formatMarkName(markName);
1728 var formattedLabel = formatLabel(label, warning);
1729
1730 try {
1731 performance.measure(formattedLabel, formattedMarkName);
1732 } catch (err) {} // If previous mark was missing for some reason, this will throw.
1733 // This could only happen if React crashed in an unexpected place earlier.
1734 // Don't pile on with more errors.
1735 // Clear marks immediately to avoid growing buffer.
1736
1737
1738 performance.clearMarks(formattedMarkName);
1739 performance.clearMeasures(formattedLabel);
1740};
1741
1742var getFiberMarkName = function (label, debugID) {
1743 return label + " (#" + debugID + ")";
1744};
1745
1746var getFiberLabel = function (componentName, isMounted, phase) {
1747 if (phase === null) {
1748 // These are composite component total time measurements.
1749 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
1750 } else {
1751 // Composite component methods.
1752 return componentName + "." + phase;
1753 }
1754};
1755
1756var beginFiberMark = function (fiber, phase) {
1757 var componentName = getComponentName(fiber.type) || 'Unknown';
1758 var debugID = fiber._debugID;
1759 var isMounted = fiber.alternate !== null;
1760 var label = getFiberLabel(componentName, isMounted, phase);
1761
1762 if (isCommitting && labelsInCurrentCommit.has(label)) {
1763 // During the commit phase, we don't show duplicate labels because
1764 // there is a fixed overhead for every measurement, and we don't
1765 // want to stretch the commit phase beyond necessary.
1766 return false;
1767 }
1768
1769 labelsInCurrentCommit.add(label);
1770 var markName = getFiberMarkName(label, debugID);
1771 beginMark(markName);
1772 return true;
1773};
1774
1775var clearFiberMark = function (fiber, phase) {
1776 var componentName = getComponentName(fiber.type) || 'Unknown';
1777 var debugID = fiber._debugID;
1778 var isMounted = fiber.alternate !== null;
1779 var label = getFiberLabel(componentName, isMounted, phase);
1780 var markName = getFiberMarkName(label, debugID);
1781 clearMark(markName);
1782};
1783
1784var endFiberMark = function (fiber, phase, warning) {
1785 var componentName = getComponentName(fiber.type) || 'Unknown';
1786 var debugID = fiber._debugID;
1787 var isMounted = fiber.alternate !== null;
1788 var label = getFiberLabel(componentName, isMounted, phase);
1789 var markName = getFiberMarkName(label, debugID);
1790 endMark(label, markName, warning);
1791};
1792
1793var shouldIgnoreFiber = function (fiber) {
1794 // Host components should be skipped in the timeline.
1795 // We could check typeof fiber.type, but does this work with RN?
1796 switch (fiber.tag) {
1797 case HostRoot:
1798 case HostComponent:
1799 case HostText:
1800 case HostPortal:
1801 case Fragment:
1802 case ContextProvider:
1803 case ContextConsumer:
1804 case Mode:
1805 return true;
1806
1807 default:
1808 return false;
1809 }
1810};
1811
1812var clearPendingPhaseMeasurement = function () {
1813 if (currentPhase !== null && currentPhaseFiber !== null) {
1814 clearFiberMark(currentPhaseFiber, currentPhase);
1815 }
1816
1817 currentPhaseFiber = null;
1818 currentPhase = null;
1819 hasScheduledUpdateInCurrentPhase = false;
1820};
1821
1822var pauseTimers = function () {
1823 // Stops all currently active measurements so that they can be resumed
1824 // if we continue in a later deferred loop from the same unit of work.
1825 var fiber = currentFiber;
1826
1827 while (fiber) {
1828 if (fiber._debugIsCurrentlyTiming) {
1829 endFiberMark(fiber, null, null);
1830 }
1831
1832 fiber = fiber.return;
1833 }
1834};
1835
1836var resumeTimersRecursively = function (fiber) {
1837 if (fiber.return !== null) {
1838 resumeTimersRecursively(fiber.return);
1839 }
1840
1841 if (fiber._debugIsCurrentlyTiming) {
1842 beginFiberMark(fiber, null);
1843 }
1844};
1845
1846var resumeTimers = function () {
1847 // Resumes all measurements that were active during the last deferred loop.
1848 if (currentFiber !== null) {
1849 resumeTimersRecursively(currentFiber);
1850 }
1851};
1852
1853function recordEffect() {
1854 if (enableUserTimingAPI) {
1855 effectCountInCurrentCommit++;
1856 }
1857}
1858function recordScheduleUpdate() {
1859 if (enableUserTimingAPI) {
1860 if (isCommitting) {
1861 hasScheduledUpdateInCurrentCommit = true;
1862 }
1863
1864 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1865 hasScheduledUpdateInCurrentPhase = true;
1866 }
1867 }
1868}
1869
1870
1871function startWorkTimer(fiber) {
1872 if (enableUserTimingAPI) {
1873 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1874 return;
1875 } // If we pause, this is the fiber to unwind from.
1876
1877
1878 currentFiber = fiber;
1879
1880 if (!beginFiberMark(fiber, null)) {
1881 return;
1882 }
1883
1884 fiber._debugIsCurrentlyTiming = true;
1885 }
1886}
1887function cancelWorkTimer(fiber) {
1888 if (enableUserTimingAPI) {
1889 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1890 return;
1891 } // Remember we shouldn't complete measurement for this fiber.
1892 // Otherwise flamechart will be deep even for small updates.
1893
1894
1895 fiber._debugIsCurrentlyTiming = false;
1896 clearFiberMark(fiber, null);
1897 }
1898}
1899function stopWorkTimer(fiber) {
1900 if (enableUserTimingAPI) {
1901 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1902 return;
1903 } // If we pause, its parent is the fiber to unwind from.
1904
1905
1906 currentFiber = fiber.return;
1907
1908 if (!fiber._debugIsCurrentlyTiming) {
1909 return;
1910 }
1911
1912 fiber._debugIsCurrentlyTiming = false;
1913 endFiberMark(fiber, null, null);
1914 }
1915}
1916function stopFailedWorkTimer(fiber) {
1917 if (enableUserTimingAPI) {
1918 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1919 return;
1920 } // If we pause, its parent is the fiber to unwind from.
1921
1922
1923 currentFiber = fiber.return;
1924
1925 if (!fiber._debugIsCurrentlyTiming) {
1926 return;
1927 }
1928
1929 fiber._debugIsCurrentlyTiming = false;
1930 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1931 endFiberMark(fiber, null, warning);
1932 }
1933}
1934function startPhaseTimer(fiber, phase) {
1935 if (enableUserTimingAPI) {
1936 if (!supportsUserTiming) {
1937 return;
1938 }
1939
1940 clearPendingPhaseMeasurement();
1941
1942 if (!beginFiberMark(fiber, phase)) {
1943 return;
1944 }
1945
1946 currentPhaseFiber = fiber;
1947 currentPhase = phase;
1948 }
1949}
1950function stopPhaseTimer() {
1951 if (enableUserTimingAPI) {
1952 if (!supportsUserTiming) {
1953 return;
1954 }
1955
1956 if (currentPhase !== null && currentPhaseFiber !== null) {
1957 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1958 endFiberMark(currentPhaseFiber, currentPhase, warning);
1959 }
1960
1961 currentPhase = null;
1962 currentPhaseFiber = null;
1963 }
1964}
1965function startWorkLoopTimer(nextUnitOfWork) {
1966 if (enableUserTimingAPI) {
1967 currentFiber = nextUnitOfWork;
1968
1969 if (!supportsUserTiming) {
1970 return;
1971 }
1972
1973 commitCountInCurrentWorkLoop = 0; // This is top level call.
1974 // Any other measurements are performed within.
1975
1976 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
1977
1978 resumeTimers();
1979 }
1980}
1981function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1982 if (enableUserTimingAPI) {
1983 if (!supportsUserTiming) {
1984 return;
1985 }
1986
1987 var warning = null;
1988
1989 if (interruptedBy !== null) {
1990 if (interruptedBy.tag === HostRoot) {
1991 warning = 'A top-level update interrupted the previous render';
1992 } else {
1993 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1994 warning = "An update to " + componentName + " interrupted the previous render";
1995 }
1996 } else if (commitCountInCurrentWorkLoop > 1) {
1997 warning = 'There were cascading updates';
1998 }
1999
2000 commitCountInCurrentWorkLoop = 0;
2001 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
2002
2003 pauseTimers();
2004 endMark(label, '(React Tree Reconciliation)', warning);
2005 }
2006}
2007function startCommitTimer() {
2008 if (enableUserTimingAPI) {
2009 if (!supportsUserTiming) {
2010 return;
2011 }
2012
2013 isCommitting = true;
2014 hasScheduledUpdateInCurrentCommit = false;
2015 labelsInCurrentCommit.clear();
2016 beginMark('(Committing Changes)');
2017 }
2018}
2019function stopCommitTimer() {
2020 if (enableUserTimingAPI) {
2021 if (!supportsUserTiming) {
2022 return;
2023 }
2024
2025 var warning = null;
2026
2027 if (hasScheduledUpdateInCurrentCommit) {
2028 warning = 'Lifecycle hook scheduled a cascading update';
2029 } else if (commitCountInCurrentWorkLoop > 0) {
2030 warning = 'Caused by a cascading update in earlier commit';
2031 }
2032
2033 hasScheduledUpdateInCurrentCommit = false;
2034 commitCountInCurrentWorkLoop++;
2035 isCommitting = false;
2036 labelsInCurrentCommit.clear();
2037 endMark('(Committing Changes)', '(Committing Changes)', warning);
2038 }
2039}
2040function startCommitSnapshotEffectsTimer() {
2041 if (enableUserTimingAPI) {
2042 if (!supportsUserTiming) {
2043 return;
2044 }
2045
2046 effectCountInCurrentCommit = 0;
2047 beginMark('(Committing Snapshot Effects)');
2048 }
2049}
2050function stopCommitSnapshotEffectsTimer() {
2051 if (enableUserTimingAPI) {
2052 if (!supportsUserTiming) {
2053 return;
2054 }
2055
2056 var count = effectCountInCurrentCommit;
2057 effectCountInCurrentCommit = 0;
2058 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
2059 }
2060}
2061function startCommitHostEffectsTimer() {
2062 if (enableUserTimingAPI) {
2063 if (!supportsUserTiming) {
2064 return;
2065 }
2066
2067 effectCountInCurrentCommit = 0;
2068 beginMark('(Committing Host Effects)');
2069 }
2070}
2071function stopCommitHostEffectsTimer() {
2072 if (enableUserTimingAPI) {
2073 if (!supportsUserTiming) {
2074 return;
2075 }
2076
2077 var count = effectCountInCurrentCommit;
2078 effectCountInCurrentCommit = 0;
2079 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
2080 }
2081}
2082function startCommitLifeCyclesTimer() {
2083 if (enableUserTimingAPI) {
2084 if (!supportsUserTiming) {
2085 return;
2086 }
2087
2088 effectCountInCurrentCommit = 0;
2089 beginMark('(Calling Lifecycle Methods)');
2090 }
2091}
2092function stopCommitLifeCyclesTimer() {
2093 if (enableUserTimingAPI) {
2094 if (!supportsUserTiming) {
2095 return;
2096 }
2097
2098 var count = effectCountInCurrentCommit;
2099 effectCountInCurrentCommit = 0;
2100 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
2101 }
2102}
2103
2104var valueStack = [];
2105var fiberStack;
2106
2107{
2108 fiberStack = [];
2109}
2110
2111var index = -1;
2112
2113function createCursor(defaultValue) {
2114 return {
2115 current: defaultValue
2116 };
2117}
2118
2119function pop(cursor, fiber) {
2120 if (index < 0) {
2121 {
2122 warningWithoutStack$1(false, 'Unexpected pop.');
2123 }
2124
2125 return;
2126 }
2127
2128 {
2129 if (fiber !== fiberStack[index]) {
2130 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
2131 }
2132 }
2133
2134 cursor.current = valueStack[index];
2135 valueStack[index] = null;
2136
2137 {
2138 fiberStack[index] = null;
2139 }
2140
2141 index--;
2142}
2143
2144function push(cursor, value, fiber) {
2145 index++;
2146 valueStack[index] = cursor.current;
2147
2148 {
2149 fiberStack[index] = fiber;
2150 }
2151
2152 cursor.current = value;
2153}
2154
2155var warnedAboutMissingGetChildContext;
2156
2157{
2158 warnedAboutMissingGetChildContext = {};
2159}
2160
2161var emptyContextObject = {};
2162
2163{
2164 Object.freeze(emptyContextObject);
2165} // A cursor to the current merged context object on the stack.
2166
2167
2168var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
2169
2170var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
2171// We use this to get access to the parent context after we have already
2172// pushed the next context provider, and now need to merge their contexts.
2173
2174var previousContext = emptyContextObject;
2175
2176function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
2177 if (disableLegacyContext) {
2178 return emptyContextObject;
2179 } else {
2180 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
2181 // If the fiber is a context provider itself, when we read its context
2182 // we may have already pushed its own child context on the stack. A context
2183 // provider should not "see" its own child context. Therefore we read the
2184 // previous (parent) context instead for a context provider.
2185 return previousContext;
2186 }
2187
2188 return contextStackCursor.current;
2189 }
2190}
2191
2192function cacheContext(workInProgress, unmaskedContext, maskedContext) {
2193 if (disableLegacyContext) {
2194 return;
2195 } else {
2196 var instance = workInProgress.stateNode;
2197 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
2198 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
2199 }
2200}
2201
2202function getMaskedContext(workInProgress, unmaskedContext) {
2203 if (disableLegacyContext) {
2204 return emptyContextObject;
2205 } else {
2206 var type = workInProgress.type;
2207 var contextTypes = type.contextTypes;
2208
2209 if (!contextTypes) {
2210 return emptyContextObject;
2211 } // Avoid recreating masked context unless unmasked context has changed.
2212 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
2213 // This may trigger infinite loops if componentWillReceiveProps calls setState.
2214
2215
2216 var instance = workInProgress.stateNode;
2217
2218 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
2219 return instance.__reactInternalMemoizedMaskedChildContext;
2220 }
2221
2222 var context = {};
2223
2224 for (var key in contextTypes) {
2225 context[key] = unmaskedContext[key];
2226 }
2227
2228 {
2229 var name = getComponentName(type) || 'Unknown';
2230 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
2231 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
2232 // Context is created before the class component is instantiated so check for instance.
2233
2234
2235 if (instance) {
2236 cacheContext(workInProgress, unmaskedContext, context);
2237 }
2238
2239 return context;
2240 }
2241}
2242
2243function hasContextChanged() {
2244 if (disableLegacyContext) {
2245 return false;
2246 } else {
2247 return didPerformWorkStackCursor.current;
2248 }
2249}
2250
2251function isContextProvider(type) {
2252 if (disableLegacyContext) {
2253 return false;
2254 } else {
2255 var childContextTypes = type.childContextTypes;
2256 return childContextTypes !== null && childContextTypes !== undefined;
2257 }
2258}
2259
2260function popContext(fiber) {
2261 if (disableLegacyContext) {
2262 return;
2263 } else {
2264 pop(didPerformWorkStackCursor, fiber);
2265 pop(contextStackCursor, fiber);
2266 }
2267}
2268
2269function popTopLevelContextObject(fiber) {
2270 if (disableLegacyContext) {
2271 return;
2272 } else {
2273 pop(didPerformWorkStackCursor, fiber);
2274 pop(contextStackCursor, fiber);
2275 }
2276}
2277
2278function pushTopLevelContextObject(fiber, context, didChange) {
2279 if (disableLegacyContext) {
2280 return;
2281 } else {
2282 (function () {
2283 if (!(contextStackCursor.current === emptyContextObject)) {
2284 {
2285 throw ReactError(Error("Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue."));
2286 }
2287 }
2288 })();
2289
2290 push(contextStackCursor, context, fiber);
2291 push(didPerformWorkStackCursor, didChange, fiber);
2292 }
2293}
2294
2295function processChildContext(fiber, type, parentContext) {
2296 if (disableLegacyContext) {
2297 return parentContext;
2298 } else {
2299 var instance = fiber.stateNode;
2300 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
2301 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
2302
2303 if (typeof instance.getChildContext !== 'function') {
2304 {
2305 var componentName = getComponentName(type) || 'Unknown';
2306
2307 if (!warnedAboutMissingGetChildContext[componentName]) {
2308 warnedAboutMissingGetChildContext[componentName] = true;
2309 warningWithoutStack$1(false, '%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
2310 }
2311 }
2312
2313 return parentContext;
2314 }
2315
2316 var childContext;
2317
2318 {
2319 setCurrentPhase('getChildContext');
2320 }
2321
2322 startPhaseTimer(fiber, 'getChildContext');
2323 childContext = instance.getChildContext();
2324 stopPhaseTimer();
2325
2326 {
2327 setCurrentPhase(null);
2328 }
2329
2330 for (var contextKey in childContext) {
2331 (function () {
2332 if (!(contextKey in childContextTypes)) {
2333 {
2334 throw ReactError(Error((getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes."));
2335 }
2336 }
2337 })();
2338 }
2339
2340 {
2341 var name = getComponentName(type) || 'Unknown';
2342 checkPropTypes_1(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
2343 // somebody calls unstable_renderSubtreeIntoContainer() and we process
2344 // context from the parent component instance. The stack will be missing
2345 // because it's outside of the reconciliation, and so the pointer has not
2346 // been set. This is rare and doesn't matter. We'll also remove that API.
2347 getCurrentFiberStackInDev);
2348 }
2349
2350 return _assign({}, parentContext, {}, childContext);
2351 }
2352}
2353
2354function pushContextProvider(workInProgress) {
2355 if (disableLegacyContext) {
2356 return false;
2357 } else {
2358 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
2359 // If the instance does not exist yet, we will push null at first,
2360 // and replace it on the stack later when invalidating the context.
2361
2362 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
2363 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2364
2365 previousContext = contextStackCursor.current;
2366 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2367 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2368 return true;
2369 }
2370}
2371
2372function invalidateContextProvider(workInProgress, type, didChange) {
2373 if (disableLegacyContext) {
2374 return;
2375 } else {
2376 var instance = workInProgress.stateNode;
2377
2378 (function () {
2379 if (!instance) {
2380 {
2381 throw ReactError(Error("Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue."));
2382 }
2383 }
2384 })();
2385
2386 if (didChange) {
2387 // Merge parent and own context.
2388 // Skip this if we're not updating due to sCU.
2389 // This avoids unnecessarily recomputing memoized values.
2390 var mergedContext = processChildContext(workInProgress, type, previousContext);
2391 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
2392 // It is important to unwind the context in the reverse order.
2393
2394 pop(didPerformWorkStackCursor, workInProgress);
2395 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
2396
2397 push(contextStackCursor, mergedContext, workInProgress);
2398 push(didPerformWorkStackCursor, didChange, workInProgress);
2399 } else {
2400 pop(didPerformWorkStackCursor, workInProgress);
2401 push(didPerformWorkStackCursor, didChange, workInProgress);
2402 }
2403 }
2404}
2405
2406function findCurrentUnmaskedContext(fiber) {
2407 if (disableLegacyContext) {
2408 return emptyContextObject;
2409 } else {
2410 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2411 // makes sense elsewhere
2412 (function () {
2413 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
2414 {
2415 throw ReactError(Error("Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue."));
2416 }
2417 }
2418 })();
2419
2420 var node = fiber;
2421
2422 do {
2423 switch (node.tag) {
2424 case HostRoot:
2425 return node.stateNode.context;
2426
2427 case ClassComponent:
2428 {
2429 var Component = node.type;
2430
2431 if (isContextProvider(Component)) {
2432 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2433 }
2434
2435 break;
2436 }
2437 }
2438
2439 node = node.return;
2440 } while (node !== null);
2441
2442 (function () {
2443 {
2444 {
2445 throw ReactError(Error("Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue."));
2446 }
2447 }
2448 })();
2449 }
2450}
2451
2452var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2453var _ReactInternals$Sched = ReactInternals$1.Scheduler;
2454var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
2455var unstable_now = _ReactInternals$Sched.unstable_now;
2456var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
2457var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
2458var unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint;
2459var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
2460var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
2461var unstable_next = _ReactInternals$Sched.unstable_next;
2462var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
2463var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
2464var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
2465var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
2466var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
2467var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
2468var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
2469var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
2470var unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate;
2471var unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
2472
2473var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2474var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
2475var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
2476var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
2477var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
2478var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
2479var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
2480var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
2481var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
2482var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
2483var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2484
2485// Intentionally not named imports because Rollup would use dynamic dispatch for
2486// CommonJS interop named imports.
2487var Scheduler_runWithPriority = unstable_runWithPriority;
2488var Scheduler_scheduleCallback = unstable_scheduleCallback;
2489var Scheduler_cancelCallback = unstable_cancelCallback;
2490var Scheduler_shouldYield = unstable_shouldYield;
2491var Scheduler_requestPaint = unstable_requestPaint;
2492var Scheduler_now = unstable_now;
2493var Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
2494var Scheduler_ImmediatePriority = unstable_ImmediatePriority;
2495var Scheduler_UserBlockingPriority = unstable_UserBlockingPriority;
2496var Scheduler_NormalPriority = unstable_NormalPriority;
2497var Scheduler_LowPriority = unstable_LowPriority;
2498var Scheduler_IdlePriority = unstable_IdlePriority;
2499
2500if (enableSchedulerTracing) {
2501 // Provide explicit error message when production+profiling bundle of e.g.
2502 // react-dom is used with production (non-profiling) bundle of
2503 // scheduler/tracing
2504 (function () {
2505 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
2506 {
2507 throw ReactError(Error("It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling"));
2508 }
2509 }
2510 })();
2511}
2512
2513var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
2514// ascending numbers so we can compare them like numbers. They start at 90 to
2515// avoid clashing with Scheduler's priorities.
2516
2517var ImmediatePriority = 99;
2518var UserBlockingPriority = 98;
2519var NormalPriority = 97;
2520var LowPriority = 96;
2521var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
2522
2523var NoPriority = 90;
2524var shouldYield = Scheduler_shouldYield;
2525var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
2526Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
2527var syncQueue = null;
2528var immediateQueueCallbackNode = null;
2529var isFlushingSyncQueue = false;
2530var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
2531// This will be the case for modern browsers that support `performance.now`. In
2532// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
2533// timestamp. In that case, subtract the module initialization time to simulate
2534// the behavior of performance.now and keep our times small enough to fit
2535// within 32 bits.
2536// TODO: Consider lifting this into Scheduler.
2537
2538var now = initialTimeMs < 10000 ? Scheduler_now : function () {
2539 return Scheduler_now() - initialTimeMs;
2540};
2541function getCurrentPriorityLevel() {
2542 switch (Scheduler_getCurrentPriorityLevel()) {
2543 case Scheduler_ImmediatePriority:
2544 return ImmediatePriority;
2545
2546 case Scheduler_UserBlockingPriority:
2547 return UserBlockingPriority;
2548
2549 case Scheduler_NormalPriority:
2550 return NormalPriority;
2551
2552 case Scheduler_LowPriority:
2553 return LowPriority;
2554
2555 case Scheduler_IdlePriority:
2556 return IdlePriority;
2557
2558 default:
2559 (function () {
2560 {
2561 {
2562 throw ReactError(Error("Unknown priority level."));
2563 }
2564 }
2565 })();
2566
2567 }
2568}
2569
2570function reactPriorityToSchedulerPriority(reactPriorityLevel) {
2571 switch (reactPriorityLevel) {
2572 case ImmediatePriority:
2573 return Scheduler_ImmediatePriority;
2574
2575 case UserBlockingPriority:
2576 return Scheduler_UserBlockingPriority;
2577
2578 case NormalPriority:
2579 return Scheduler_NormalPriority;
2580
2581 case LowPriority:
2582 return Scheduler_LowPriority;
2583
2584 case IdlePriority:
2585 return Scheduler_IdlePriority;
2586
2587 default:
2588 (function () {
2589 {
2590 {
2591 throw ReactError(Error("Unknown priority level."));
2592 }
2593 }
2594 })();
2595
2596 }
2597}
2598
2599function runWithPriority(reactPriorityLevel, fn) {
2600 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2601 return Scheduler_runWithPriority(priorityLevel, fn);
2602}
2603function scheduleCallback(reactPriorityLevel, callback, options) {
2604 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2605 return Scheduler_scheduleCallback(priorityLevel, callback, options);
2606}
2607function scheduleSyncCallback(callback) {
2608 // Push this callback into an internal queue. We'll flush these either in
2609 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
2610 if (syncQueue === null) {
2611 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
2612
2613 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
2614 } else {
2615 // Push onto existing queue. Don't need to schedule a callback because
2616 // we already scheduled one when we created the queue.
2617 syncQueue.push(callback);
2618 }
2619
2620 return fakeCallbackNode;
2621}
2622function cancelCallback(callbackNode) {
2623 if (callbackNode !== fakeCallbackNode) {
2624 Scheduler_cancelCallback(callbackNode);
2625 }
2626}
2627function flushSyncCallbackQueue() {
2628 if (immediateQueueCallbackNode !== null) {
2629 var node = immediateQueueCallbackNode;
2630 immediateQueueCallbackNode = null;
2631 Scheduler_cancelCallback(node);
2632 }
2633
2634 flushSyncCallbackQueueImpl();
2635}
2636
2637function flushSyncCallbackQueueImpl() {
2638 if (!isFlushingSyncQueue && syncQueue !== null) {
2639 // Prevent re-entrancy.
2640 isFlushingSyncQueue = true;
2641 var i = 0;
2642
2643 try {
2644 var _isSync = true;
2645 var queue = syncQueue;
2646 runWithPriority(ImmediatePriority, function () {
2647 for (; i < queue.length; i++) {
2648 var callback = queue[i];
2649
2650 do {
2651 callback = callback(_isSync);
2652 } while (callback !== null);
2653 }
2654 });
2655 syncQueue = null;
2656 } catch (error) {
2657 // If something throws, leave the remaining callbacks on the queue.
2658 if (syncQueue !== null) {
2659 syncQueue = syncQueue.slice(i + 1);
2660 } // Resume flushing in the next tick
2661
2662
2663 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
2664 throw error;
2665 } finally {
2666 isFlushingSyncQueue = false;
2667 }
2668 }
2669}
2670
2671var NoMode = 0;
2672var StrictMode = 1; // TODO: Remove BatchedMode and ConcurrentMode by reading from the root
2673// tag instead
2674
2675var BatchedMode = 2;
2676var ConcurrentMode = 4;
2677var ProfileMode = 8;
2678
2679// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2680// Math.pow(2, 30) - 1
2681// 0b111111111111111111111111111111
2682var MAX_SIGNED_31_BIT_INT = 1073741823;
2683
2684var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
2685// Never work can be committed in an inconsistent state without tearing the UI.
2686// The main example is offscreen content, like a hidden subtree. So one possible
2687// name is Offscreen. However, it also includes dehydrated Suspense boundaries,
2688// which are inconsistent in the sense that they haven't finished yet, but
2689// aren't visibly inconsistent because the server rendered HTML matches what the
2690// hydrated tree would look like.
2691
2692var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
2693// order to be consistent.
2694
2695var Idle = 2;
2696var Sync = MAX_SIGNED_31_BIT_INT;
2697var Batched = Sync - 1;
2698var UNIT_SIZE = 10;
2699var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
2700
2701function msToExpirationTime(ms) {
2702 // Always add an offset so that we don't clash with the magic number for NoWork.
2703 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2704}
2705function expirationTimeToMs(expirationTime) {
2706 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2707}
2708
2709function ceiling(num, precision) {
2710 return ((num / precision | 0) + 1) * precision;
2711}
2712
2713function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2714 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2715} // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
2716// the names to reflect.
2717
2718
2719var LOW_PRIORITY_EXPIRATION = 5000;
2720var LOW_PRIORITY_BATCH_SIZE = 250;
2721function computeAsyncExpiration(currentTime) {
2722 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2723}
2724function computeSuspenseExpiration(currentTime, timeoutMs) {
2725 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
2726 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
2727} // We intentionally set a higher expiration time for interactive updates in
2728// dev than in production.
2729//
2730// If the main thread is being blocked so long that you hit the expiration,
2731// it's a problem that could be solved with better scheduling.
2732//
2733// People will be more likely to notice this and fix it with the long
2734// expiration time in development.
2735//
2736// In production we opt for better UX at the risk of masking scheduling
2737// problems, by expiring fast.
2738
2739var HIGH_PRIORITY_EXPIRATION = 500;
2740var HIGH_PRIORITY_BATCH_SIZE = 100;
2741function computeInteractiveExpiration(currentTime) {
2742 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2743}
2744function inferPriorityFromExpirationTime(currentTime, expirationTime) {
2745 if (expirationTime === Sync) {
2746 return ImmediatePriority;
2747 }
2748
2749 if (expirationTime === Never || expirationTime === Idle) {
2750 return IdlePriority;
2751 }
2752
2753 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
2754
2755 if (msUntil <= 0) {
2756 return ImmediatePriority;
2757 }
2758
2759 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
2760 return UserBlockingPriority;
2761 }
2762
2763 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
2764 return NormalPriority;
2765 } // TODO: Handle LowPriority
2766 // Assume anything lower has idle priority
2767
2768
2769 return IdlePriority;
2770}
2771
2772/**
2773 * inlined Object.is polyfill to avoid requiring consumers ship their own
2774 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2775 */
2776function is(x, y) {
2777 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2778 ;
2779}
2780
2781var is$1 = typeof Object.is === 'function' ? Object.is : is;
2782
2783var hasOwnProperty = Object.prototype.hasOwnProperty;
2784/**
2785 * Performs equality by iterating through keys on an object and returning false
2786 * when any key has values which are not strictly equal between the arguments.
2787 * Returns true when the values of all keys are strictly equal.
2788 */
2789
2790function shallowEqual(objA, objB) {
2791 if (is$1(objA, objB)) {
2792 return true;
2793 }
2794
2795 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2796 return false;
2797 }
2798
2799 var keysA = Object.keys(objA);
2800 var keysB = Object.keys(objB);
2801
2802 if (keysA.length !== keysB.length) {
2803 return false;
2804 } // Test for A's keys different from B.
2805
2806
2807 for (var i = 0; i < keysA.length; i++) {
2808 if (!hasOwnProperty.call(objB, keysA[i]) || !is$1(objA[keysA[i]], objB[keysA[i]])) {
2809 return false;
2810 }
2811 }
2812
2813 return true;
2814}
2815
2816/**
2817 * Forked from fbjs/warning:
2818 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2819 *
2820 * Only change is we use console.warn instead of console.error,
2821 * and do nothing when 'console' is not supported.
2822 * This really simplifies the code.
2823 * ---
2824 * Similar to invariant but only logs a warning if the condition is not met.
2825 * This can be used to log issues in development environments in critical
2826 * paths. Removing the logging code for production environments will keep the
2827 * same logic and follow the same code paths.
2828 */
2829var lowPriorityWarningWithoutStack = function () {};
2830
2831{
2832 var printWarning$1 = function (format) {
2833 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2834 args[_key - 1] = arguments[_key];
2835 }
2836
2837 var argIndex = 0;
2838 var message = 'Warning: ' + format.replace(/%s/g, function () {
2839 return args[argIndex++];
2840 });
2841
2842 if (typeof console !== 'undefined') {
2843 console.warn(message);
2844 }
2845
2846 try {
2847 // --- Welcome to debugging React ---
2848 // This error was thrown as a convenience so that you can use this stack
2849 // to find the callsite that caused this warning to fire.
2850 throw new Error(message);
2851 } catch (x) {}
2852 };
2853
2854 lowPriorityWarningWithoutStack = function (condition, format) {
2855 if (format === undefined) {
2856 throw new Error('`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
2857 }
2858
2859 if (!condition) {
2860 for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
2861 args[_key2 - 2] = arguments[_key2];
2862 }
2863
2864 printWarning$1.apply(void 0, [format].concat(args));
2865 }
2866 };
2867}
2868
2869var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack;
2870
2871var ReactStrictModeWarnings = {
2872 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2873 flushPendingUnsafeLifecycleWarnings: function () {},
2874 recordLegacyContextWarning: function (fiber, instance) {},
2875 flushLegacyContextWarning: function () {},
2876 discardPendingWarnings: function () {}
2877};
2878
2879{
2880 var findStrictRoot = function (fiber) {
2881 var maybeStrictRoot = null;
2882 var node = fiber;
2883
2884 while (node !== null) {
2885 if (node.mode & StrictMode) {
2886 maybeStrictRoot = node;
2887 }
2888
2889 node = node.return;
2890 }
2891
2892 return maybeStrictRoot;
2893 };
2894
2895 var setToSortedString = function (set) {
2896 var array = [];
2897 set.forEach(function (value) {
2898 array.push(value);
2899 });
2900 return array.sort().join(', ');
2901 };
2902
2903 var pendingComponentWillMountWarnings = [];
2904 var pendingUNSAFE_ComponentWillMountWarnings = [];
2905 var pendingComponentWillReceivePropsWarnings = [];
2906 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2907 var pendingComponentWillUpdateWarnings = [];
2908 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
2909
2910 var didWarnAboutUnsafeLifecycles = new Set();
2911
2912 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2913 // Dedup strategy: Warn once per component.
2914 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2915 return;
2916 }
2917
2918 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
2919 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2920 pendingComponentWillMountWarnings.push(fiber);
2921 }
2922
2923 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2924 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2925 }
2926
2927 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2928 pendingComponentWillReceivePropsWarnings.push(fiber);
2929 }
2930
2931 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2932 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2933 }
2934
2935 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2936 pendingComponentWillUpdateWarnings.push(fiber);
2937 }
2938
2939 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2940 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2941 }
2942 };
2943
2944 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2945 // We do an initial pass to gather component names
2946 var componentWillMountUniqueNames = new Set();
2947
2948 if (pendingComponentWillMountWarnings.length > 0) {
2949 pendingComponentWillMountWarnings.forEach(function (fiber) {
2950 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2951 didWarnAboutUnsafeLifecycles.add(fiber.type);
2952 });
2953 pendingComponentWillMountWarnings = [];
2954 }
2955
2956 var UNSAFE_componentWillMountUniqueNames = new Set();
2957
2958 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2959 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2960 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2961 didWarnAboutUnsafeLifecycles.add(fiber.type);
2962 });
2963 pendingUNSAFE_ComponentWillMountWarnings = [];
2964 }
2965
2966 var componentWillReceivePropsUniqueNames = new Set();
2967
2968 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2969 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2970 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2971 didWarnAboutUnsafeLifecycles.add(fiber.type);
2972 });
2973 pendingComponentWillReceivePropsWarnings = [];
2974 }
2975
2976 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2977
2978 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2979 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2980 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2981 didWarnAboutUnsafeLifecycles.add(fiber.type);
2982 });
2983 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2984 }
2985
2986 var componentWillUpdateUniqueNames = new Set();
2987
2988 if (pendingComponentWillUpdateWarnings.length > 0) {
2989 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2990 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2991 didWarnAboutUnsafeLifecycles.add(fiber.type);
2992 });
2993 pendingComponentWillUpdateWarnings = [];
2994 }
2995
2996 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2997
2998 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2999 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
3000 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
3001 didWarnAboutUnsafeLifecycles.add(fiber.type);
3002 });
3003 pendingUNSAFE_ComponentWillUpdateWarnings = [];
3004 } // Finally, we flush all the warnings
3005 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
3006
3007
3008 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
3009 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
3010 warningWithoutStack$1(false, 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
3011 }
3012
3013 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
3014 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
3015
3016 warningWithoutStack$1(false, 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
3017 }
3018
3019 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
3020 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
3021
3022 warningWithoutStack$1(false, 'Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
3023 }
3024
3025 if (componentWillMountUniqueNames.size > 0) {
3026 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
3027
3028 lowPriorityWarningWithoutStack$1(false, 'componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
3029 }
3030
3031 if (componentWillReceivePropsUniqueNames.size > 0) {
3032 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
3033
3034 lowPriorityWarningWithoutStack$1(false, 'componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
3035 }
3036
3037 if (componentWillUpdateUniqueNames.size > 0) {
3038 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
3039
3040 lowPriorityWarningWithoutStack$1(false, 'componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
3041 }
3042 };
3043
3044 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
3045
3046 var didWarnAboutLegacyContext = new Set();
3047
3048 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
3049 var strictRoot = findStrictRoot(fiber);
3050
3051 if (strictRoot === null) {
3052 warningWithoutStack$1(false, 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
3053 return;
3054 } // Dedup strategy: Warn once per component.
3055
3056
3057 if (didWarnAboutLegacyContext.has(fiber.type)) {
3058 return;
3059 }
3060
3061 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
3062
3063 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
3064 if (warningsForRoot === undefined) {
3065 warningsForRoot = [];
3066 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
3067 }
3068
3069 warningsForRoot.push(fiber);
3070 }
3071 };
3072
3073 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
3074 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
3075 var uniqueNames = new Set();
3076 fiberArray.forEach(function (fiber) {
3077 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3078 didWarnAboutLegacyContext.add(fiber.type);
3079 });
3080 var sortedNames = setToSortedString(uniqueNames);
3081 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3082 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://fb.me/react-legacy-context' + '%s', sortedNames, strictRootComponentStack);
3083 });
3084 };
3085
3086 ReactStrictModeWarnings.discardPendingWarnings = function () {
3087 pendingComponentWillMountWarnings = [];
3088 pendingUNSAFE_ComponentWillMountWarnings = [];
3089 pendingComponentWillReceivePropsWarnings = [];
3090 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
3091 pendingComponentWillUpdateWarnings = [];
3092 pendingUNSAFE_ComponentWillUpdateWarnings = [];
3093 pendingLegacyContextWarning = new Map();
3094 };
3095}
3096
3097var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
3098
3099var failedBoundaries = null;
3100var setRefreshHandler = function (handler) {
3101 {
3102 resolveFamily = handler;
3103 }
3104};
3105function resolveFunctionForHotReloading(type) {
3106 {
3107 if (resolveFamily === null) {
3108 // Hot reloading is disabled.
3109 return type;
3110 }
3111
3112 var family = resolveFamily(type);
3113
3114 if (family === undefined) {
3115 return type;
3116 } // Use the latest known implementation.
3117
3118
3119 return family.current;
3120 }
3121}
3122function resolveClassForHotReloading(type) {
3123 // No implementation differences.
3124 return resolveFunctionForHotReloading(type);
3125}
3126function resolveForwardRefForHotReloading(type) {
3127 {
3128 if (resolveFamily === null) {
3129 // Hot reloading is disabled.
3130 return type;
3131 }
3132
3133 var family = resolveFamily(type);
3134
3135 if (family === undefined) {
3136 // Check if we're dealing with a real forwardRef. Don't want to crash early.
3137 if (type !== null && type !== undefined && typeof type.render === 'function') {
3138 // ForwardRef is special because its resolved .type is an object,
3139 // but it's possible that we only have its inner render function in the map.
3140 // If that inner render function is different, we'll build a new forwardRef type.
3141 var currentRender = resolveFunctionForHotReloading(type.render);
3142
3143 if (type.render !== currentRender) {
3144 var syntheticType = {
3145 $$typeof: REACT_FORWARD_REF_TYPE,
3146 render: currentRender
3147 };
3148
3149 if (type.displayName !== undefined) {
3150 syntheticType.displayName = type.displayName;
3151 }
3152
3153 return syntheticType;
3154 }
3155 }
3156
3157 return type;
3158 } // Use the latest known implementation.
3159
3160
3161 return family.current;
3162 }
3163}
3164function isCompatibleFamilyForHotReloading(fiber, element) {
3165 {
3166 if (resolveFamily === null) {
3167 // Hot reloading is disabled.
3168 return false;
3169 }
3170
3171 var prevType = fiber.elementType;
3172 var nextType = element.type; // If we got here, we know types aren't === equal.
3173
3174 var needsCompareFamilies = false;
3175 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
3176
3177 switch (fiber.tag) {
3178 case ClassComponent:
3179 {
3180 if (typeof nextType === 'function') {
3181 needsCompareFamilies = true;
3182 }
3183
3184 break;
3185 }
3186
3187 case FunctionComponent:
3188 {
3189 if (typeof nextType === 'function') {
3190 needsCompareFamilies = true;
3191 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
3192 // We don't know the inner type yet.
3193 // We're going to assume that the lazy inner type is stable,
3194 // and so it is sufficient to avoid reconciling it away.
3195 // We're not going to unwrap or actually use the new lazy type.
3196 needsCompareFamilies = true;
3197 }
3198
3199 break;
3200 }
3201
3202 case ForwardRef:
3203 {
3204 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
3205 needsCompareFamilies = true;
3206 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
3207 needsCompareFamilies = true;
3208 }
3209
3210 break;
3211 }
3212
3213 case MemoComponent:
3214 case SimpleMemoComponent:
3215 {
3216 if ($$typeofNextType === REACT_MEMO_TYPE) {
3217 // TODO: if it was but can no longer be simple,
3218 // we shouldn't set this.
3219 needsCompareFamilies = true;
3220 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
3221 needsCompareFamilies = true;
3222 }
3223
3224 break;
3225 }
3226
3227 default:
3228 return false;
3229 } // Check if both types have a family and it's the same one.
3230
3231
3232 if (needsCompareFamilies) {
3233 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
3234 // This means both of them need to be registered to preserve state.
3235 // If we unwrapped and compared the inner types for wrappers instead,
3236 // then we would risk falsely saying two separate memo(Foo)
3237 // calls are equivalent because they wrap the same Foo function.
3238 var prevFamily = resolveFamily(prevType);
3239
3240 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
3241 return true;
3242 }
3243 }
3244
3245 return false;
3246 }
3247}
3248function markFailedErrorBoundaryForHotReloading(fiber) {
3249 {
3250 if (resolveFamily === null) {
3251 // Hot reloading is disabled.
3252 return;
3253 }
3254
3255 if (typeof WeakSet !== 'function') {
3256 return;
3257 }
3258
3259 if (failedBoundaries === null) {
3260 failedBoundaries = new WeakSet();
3261 }
3262
3263 failedBoundaries.add(fiber);
3264 }
3265}
3266var scheduleRefresh = function (root, update) {
3267 {
3268 if (resolveFamily === null) {
3269 // Hot reloading is disabled.
3270 return;
3271 }
3272
3273 var staleFamilies = update.staleFamilies,
3274 updatedFamilies = update.updatedFamilies;
3275 flushPassiveEffects();
3276 flushSync(function () {
3277 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
3278 });
3279 }
3280};
3281var scheduleRoot = function (root, element) {
3282 {
3283 if (root.context !== emptyContextObject) {
3284 // Super edge case: root has a legacy _renderSubtree context
3285 // but we don't know the parentComponent so we can't pass it.
3286 // Just ignore. We'll delete this with _renderSubtree code path later.
3287 return;
3288 }
3289
3290 flushPassiveEffects();
3291 updateContainerAtExpirationTime(element, root, null, Sync, null);
3292 }
3293};
3294
3295function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
3296 {
3297 var alternate = fiber.alternate,
3298 child = fiber.child,
3299 sibling = fiber.sibling,
3300 tag = fiber.tag,
3301 type = fiber.type;
3302 var candidateType = null;
3303
3304 switch (tag) {
3305 case FunctionComponent:
3306 case SimpleMemoComponent:
3307 case ClassComponent:
3308 candidateType = type;
3309 break;
3310
3311 case ForwardRef:
3312 candidateType = type.render;
3313 break;
3314
3315 default:
3316 break;
3317 }
3318
3319 if (resolveFamily === null) {
3320 throw new Error('Expected resolveFamily to be set during hot reload.');
3321 }
3322
3323 var needsRender = false;
3324 var needsRemount = false;
3325
3326 if (candidateType !== null) {
3327 var family = resolveFamily(candidateType);
3328
3329 if (family !== undefined) {
3330 if (staleFamilies.has(family)) {
3331 needsRemount = true;
3332 } else if (updatedFamilies.has(family)) {
3333 if (tag === ClassComponent) {
3334 needsRemount = true;
3335 } else {
3336 needsRender = true;
3337 }
3338 }
3339 }
3340 }
3341
3342 if (failedBoundaries !== null) {
3343 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
3344 needsRemount = true;
3345 }
3346 }
3347
3348 if (needsRemount) {
3349 fiber._debugNeedsRemount = true;
3350 }
3351
3352 if (needsRemount || needsRender) {
3353 scheduleWork(fiber, Sync);
3354 }
3355
3356 if (child !== null && !needsRemount) {
3357 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
3358 }
3359
3360 if (sibling !== null) {
3361 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
3362 }
3363 }
3364}
3365
3366var findHostInstancesForRefresh = function (root, families) {
3367 {
3368 var hostInstances = new Set();
3369 var types = new Set(families.map(function (family) {
3370 return family.current;
3371 }));
3372 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
3373 return hostInstances;
3374 }
3375};
3376
3377function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
3378 {
3379 var child = fiber.child,
3380 sibling = fiber.sibling,
3381 tag = fiber.tag,
3382 type = fiber.type;
3383 var candidateType = null;
3384
3385 switch (tag) {
3386 case FunctionComponent:
3387 case SimpleMemoComponent:
3388 case ClassComponent:
3389 candidateType = type;
3390 break;
3391
3392 case ForwardRef:
3393 candidateType = type.render;
3394 break;
3395
3396 default:
3397 break;
3398 }
3399
3400 var didMatch = false;
3401
3402 if (candidateType !== null) {
3403 if (types.has(candidateType)) {
3404 didMatch = true;
3405 }
3406 }
3407
3408 if (didMatch) {
3409 // We have a match. This only drills down to the closest host components.
3410 // There's no need to search deeper because for the purpose of giving
3411 // visual feedback, "flashing" outermost parent rectangles is sufficient.
3412 findHostInstancesForFiberShallowly(fiber, hostInstances);
3413 } else {
3414 // If there's no match, maybe there will be one further down in the child tree.
3415 if (child !== null) {
3416 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
3417 }
3418 }
3419
3420 if (sibling !== null) {
3421 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
3422 }
3423 }
3424}
3425
3426function findHostInstancesForFiberShallowly(fiber, hostInstances) {
3427 {
3428 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
3429
3430 if (foundHostInstances) {
3431 return;
3432 } // If we didn't find any host children, fallback to closest host parent.
3433
3434
3435 var node = fiber;
3436
3437 while (true) {
3438 switch (node.tag) {
3439 case HostComponent:
3440 hostInstances.add(node.stateNode);
3441 return;
3442
3443 case HostPortal:
3444 hostInstances.add(node.stateNode.containerInfo);
3445 return;
3446
3447 case HostRoot:
3448 hostInstances.add(node.stateNode.containerInfo);
3449 return;
3450 }
3451
3452 if (node.return === null) {
3453 throw new Error('Expected to reach root first.');
3454 }
3455
3456 node = node.return;
3457 }
3458 }
3459}
3460
3461function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
3462 {
3463 var node = fiber;
3464 var foundHostInstances = false;
3465
3466 while (true) {
3467 if (node.tag === HostComponent) {
3468 // We got a match.
3469 foundHostInstances = true;
3470 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
3471 } else if (node.child !== null) {
3472 node.child.return = node;
3473 node = node.child;
3474 continue;
3475 }
3476
3477 if (node === fiber) {
3478 return foundHostInstances;
3479 }
3480
3481 while (node.sibling === null) {
3482 if (node.return === null || node.return === fiber) {
3483 return foundHostInstances;
3484 }
3485
3486 node = node.return;
3487 }
3488
3489 node.sibling.return = node.return;
3490 node = node.sibling;
3491 }
3492 }
3493
3494 return false;
3495}
3496
3497function resolveDefaultProps(Component, baseProps) {
3498 if (Component && Component.defaultProps) {
3499 // Resolve default props. Taken from ReactElement
3500 var props = _assign({}, baseProps);
3501
3502 var defaultProps = Component.defaultProps;
3503
3504 for (var propName in defaultProps) {
3505 if (props[propName] === undefined) {
3506 props[propName] = defaultProps[propName];
3507 }
3508 }
3509
3510 return props;
3511 }
3512
3513 return baseProps;
3514}
3515function readLazyComponentType(lazyComponent) {
3516 initializeLazyComponentType(lazyComponent);
3517
3518 if (lazyComponent._status !== Resolved) {
3519 throw lazyComponent._result;
3520 }
3521
3522 return lazyComponent._result;
3523}
3524
3525var valueCursor = createCursor(null);
3526var rendererSigil;
3527
3528{
3529 // Use this to detect multiple renderers using the same context
3530 rendererSigil = {};
3531}
3532
3533var currentlyRenderingFiber = null;
3534var lastContextDependency = null;
3535var lastContextWithAllBitsObserved = null;
3536var isDisallowedContextReadInDEV = false;
3537function resetContextDependencies() {
3538 // This is called right before React yields execution, to ensure `readContext`
3539 // cannot be called outside the render phase.
3540 currentlyRenderingFiber = null;
3541 lastContextDependency = null;
3542 lastContextWithAllBitsObserved = null;
3543
3544 {
3545 isDisallowedContextReadInDEV = false;
3546 }
3547}
3548function enterDisallowedContextReadInDEV() {
3549 {
3550 isDisallowedContextReadInDEV = true;
3551 }
3552}
3553function exitDisallowedContextReadInDEV() {
3554 {
3555 isDisallowedContextReadInDEV = false;
3556 }
3557}
3558function pushProvider(providerFiber, nextValue) {
3559 var context = providerFiber.type._context;
3560
3561 if (isPrimaryRenderer) {
3562 push(valueCursor, context._currentValue, providerFiber);
3563 context._currentValue = nextValue;
3564
3565 {
3566 !(context._currentRenderer === undefined || context._currentRenderer === null || context._currentRenderer === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
3567 context._currentRenderer = rendererSigil;
3568 }
3569 } else {
3570 push(valueCursor, context._currentValue2, providerFiber);
3571 context._currentValue2 = nextValue;
3572
3573 {
3574 !(context._currentRenderer2 === undefined || context._currentRenderer2 === null || context._currentRenderer2 === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
3575 context._currentRenderer2 = rendererSigil;
3576 }
3577 }
3578}
3579function popProvider(providerFiber) {
3580 var currentValue = valueCursor.current;
3581 pop(valueCursor, providerFiber);
3582 var context = providerFiber.type._context;
3583
3584 if (isPrimaryRenderer) {
3585 context._currentValue = currentValue;
3586 } else {
3587 context._currentValue2 = currentValue;
3588 }
3589}
3590function calculateChangedBits(context, newValue, oldValue) {
3591 if (is$1(oldValue, newValue)) {
3592 // No change
3593 return 0;
3594 } else {
3595 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
3596
3597 {
3598 !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
3599 }
3600
3601 return changedBits | 0;
3602 }
3603}
3604function scheduleWorkOnParentPath(parent, renderExpirationTime) {
3605 // Update the child expiration time of all the ancestors, including
3606 // the alternates.
3607 var node = parent;
3608
3609 while (node !== null) {
3610 var alternate = node.alternate;
3611
3612 if (node.childExpirationTime < renderExpirationTime) {
3613 node.childExpirationTime = renderExpirationTime;
3614
3615 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3616 alternate.childExpirationTime = renderExpirationTime;
3617 }
3618 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3619 alternate.childExpirationTime = renderExpirationTime;
3620 } else {
3621 // Neither alternate was updated, which means the rest of the
3622 // ancestor path already has sufficient priority.
3623 break;
3624 }
3625
3626 node = node.return;
3627 }
3628}
3629function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
3630 var fiber = workInProgress.child;
3631
3632 if (fiber !== null) {
3633 // Set the return pointer of the child to the work-in-progress fiber.
3634 fiber.return = workInProgress;
3635 }
3636
3637 while (fiber !== null) {
3638 var nextFiber = void 0; // Visit this fiber.
3639
3640 var list = fiber.dependencies;
3641
3642 if (list !== null) {
3643 nextFiber = fiber.child;
3644 var dependency = list.firstContext;
3645
3646 while (dependency !== null) {
3647 // Check if the context matches.
3648 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
3649 // Match! Schedule an update on this fiber.
3650 if (fiber.tag === ClassComponent) {
3651 // Schedule a force update on the work-in-progress.
3652 var update = createUpdate(renderExpirationTime, null);
3653 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
3654 // update to the current fiber, too, which means it will persist even if
3655 // this render is thrown away. Since it's a race condition, not sure it's
3656 // worth fixing.
3657
3658 enqueueUpdate(fiber, update);
3659 }
3660
3661 if (fiber.expirationTime < renderExpirationTime) {
3662 fiber.expirationTime = renderExpirationTime;
3663 }
3664
3665 var alternate = fiber.alternate;
3666
3667 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
3668 alternate.expirationTime = renderExpirationTime;
3669 }
3670
3671 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
3672
3673 if (list.expirationTime < renderExpirationTime) {
3674 list.expirationTime = renderExpirationTime;
3675 } // Since we already found a match, we can stop traversing the
3676 // dependency list.
3677
3678
3679 break;
3680 }
3681
3682 dependency = dependency.next;
3683 }
3684 } else if (fiber.tag === ContextProvider) {
3685 // Don't scan deeper if this is a matching provider
3686 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
3687 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedFragment) {
3688 // If a dehydrated suspense bounudary is in this subtree, we don't know
3689 // if it will have any context consumers in it. The best we can do is
3690 // mark it as having updates.
3691 var parentSuspense = fiber.return;
3692
3693 (function () {
3694 if (!(parentSuspense !== null)) {
3695 {
3696 throw ReactError(Error("We just came from a parent so we must have had a parent. This is a bug in React."));
3697 }
3698 }
3699 })();
3700
3701 if (parentSuspense.expirationTime < renderExpirationTime) {
3702 parentSuspense.expirationTime = renderExpirationTime;
3703 }
3704
3705 var _alternate = parentSuspense.alternate;
3706
3707 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
3708 _alternate.expirationTime = renderExpirationTime;
3709 } // This is intentionally passing this fiber as the parent
3710 // because we want to schedule this fiber as having work
3711 // on its children. We'll use the childExpirationTime on
3712 // this fiber to indicate that a context has changed.
3713
3714
3715 scheduleWorkOnParentPath(parentSuspense, renderExpirationTime);
3716 nextFiber = fiber.sibling;
3717 } else {
3718 // Traverse down.
3719 nextFiber = fiber.child;
3720 }
3721
3722 if (nextFiber !== null) {
3723 // Set the return pointer of the child to the work-in-progress fiber.
3724 nextFiber.return = fiber;
3725 } else {
3726 // No child. Traverse to next sibling.
3727 nextFiber = fiber;
3728
3729 while (nextFiber !== null) {
3730 if (nextFiber === workInProgress) {
3731 // We're back to the root of this subtree. Exit.
3732 nextFiber = null;
3733 break;
3734 }
3735
3736 var sibling = nextFiber.sibling;
3737
3738 if (sibling !== null) {
3739 // Set the return pointer of the sibling to the work-in-progress fiber.
3740 sibling.return = nextFiber.return;
3741 nextFiber = sibling;
3742 break;
3743 } // No more siblings. Traverse up.
3744
3745
3746 nextFiber = nextFiber.return;
3747 }
3748 }
3749
3750 fiber = nextFiber;
3751 }
3752}
3753function prepareToReadContext(workInProgress, renderExpirationTime) {
3754 currentlyRenderingFiber = workInProgress;
3755 lastContextDependency = null;
3756 lastContextWithAllBitsObserved = null;
3757 var dependencies = workInProgress.dependencies;
3758
3759 if (dependencies !== null) {
3760 var firstContext = dependencies.firstContext;
3761
3762 if (firstContext !== null) {
3763 if (dependencies.expirationTime >= renderExpirationTime) {
3764 // Context list has a pending update. Mark that this fiber performed work.
3765 markWorkInProgressReceivedUpdate();
3766 } // Reset the work-in-progress list
3767
3768
3769 dependencies.firstContext = null;
3770 }
3771 }
3772}
3773function readContext(context, observedBits) {
3774 {
3775 // This warning would fire if you read context inside a Hook like useMemo.
3776 // Unlike the class check below, it's not enforced in production for perf.
3777 !!isDisallowedContextReadInDEV ? warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().') : void 0;
3778 }
3779
3780 if (lastContextWithAllBitsObserved === context) {// Nothing to do. We already observe everything in this context.
3781 } else if (observedBits === false || observedBits === 0) {// Do not observe any updates.
3782 } else {
3783 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
3784
3785 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
3786 // Observe all updates.
3787 lastContextWithAllBitsObserved = context;
3788 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
3789 } else {
3790 resolvedObservedBits = observedBits;
3791 }
3792
3793 var contextItem = {
3794 context: context,
3795 observedBits: resolvedObservedBits,
3796 next: null
3797 };
3798
3799 if (lastContextDependency === null) {
3800 (function () {
3801 if (!(currentlyRenderingFiber !== null)) {
3802 {
3803 throw ReactError(Error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()."));
3804 }
3805 }
3806 })(); // This is the first dependency for this component. Create a new list.
3807
3808
3809 lastContextDependency = contextItem;
3810 currentlyRenderingFiber.dependencies = {
3811 expirationTime: NoWork,
3812 firstContext: contextItem,
3813 responders: null
3814 };
3815 } else {
3816 // Append a new context item.
3817 lastContextDependency = lastContextDependency.next = contextItem;
3818 }
3819 }
3820
3821 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
3822}
3823
3824// UpdateQueue is a linked list of prioritized updates.
3825//
3826// Like fibers, update queues come in pairs: a current queue, which represents
3827// the visible state of the screen, and a work-in-progress queue, which can be
3828// mutated and processed asynchronously before it is committed — a form of
3829// double buffering. If a work-in-progress render is discarded before finishing,
3830// we create a new work-in-progress by cloning the current queue.
3831//
3832// Both queues share a persistent, singly-linked list structure. To schedule an
3833// update, we append it to the end of both queues. Each queue maintains a
3834// pointer to first update in the persistent list that hasn't been processed.
3835// The work-in-progress pointer always has a position equal to or greater than
3836// the current queue, since we always work on that one. The current queue's
3837// pointer is only updated during the commit phase, when we swap in the
3838// work-in-progress.
3839//
3840// For example:
3841//
3842// Current pointer: A - B - C - D - E - F
3843// Work-in-progress pointer: D - E - F
3844// ^
3845// The work-in-progress queue has
3846// processed more updates than current.
3847//
3848// The reason we append to both queues is because otherwise we might drop
3849// updates without ever processing them. For example, if we only add updates to
3850// the work-in-progress queue, some updates could be lost whenever a work-in
3851// -progress render restarts by cloning from current. Similarly, if we only add
3852// updates to the current queue, the updates will be lost whenever an already
3853// in-progress queue commits and swaps with the current queue. However, by
3854// adding to both queues, we guarantee that the update will be part of the next
3855// work-in-progress. (And because the work-in-progress queue becomes the
3856// current queue once it commits, there's no danger of applying the same
3857// update twice.)
3858//
3859// Prioritization
3860// --------------
3861//
3862// Updates are not sorted by priority, but by insertion; new updates are always
3863// appended to the end of the list.
3864//
3865// The priority is still important, though. When processing the update queue
3866// during the render phase, only the updates with sufficient priority are
3867// included in the result. If we skip an update because it has insufficient
3868// priority, it remains in the queue to be processed later, during a lower
3869// priority render. Crucially, all updates subsequent to a skipped update also
3870// remain in the queue *regardless of their priority*. That means high priority
3871// updates are sometimes processed twice, at two separate priorities. We also
3872// keep track of a base state, that represents the state before the first
3873// update in the queue is applied.
3874//
3875// For example:
3876//
3877// Given a base state of '', and the following queue of updates
3878//
3879// A1 - B2 - C1 - D2
3880//
3881// where the number indicates the priority, and the update is applied to the
3882// previous state by appending a letter, React will process these updates as
3883// two separate renders, one per distinct priority level:
3884//
3885// First render, at priority 1:
3886// Base state: ''
3887// Updates: [A1, C1]
3888// Result state: 'AC'
3889//
3890// Second render, at priority 2:
3891// Base state: 'A' <- The base state does not include C1,
3892// because B2 was skipped.
3893// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
3894// Result state: 'ABCD'
3895//
3896// Because we process updates in insertion order, and rebase high priority
3897// updates when preceding updates are skipped, the final result is deterministic
3898// regardless of priority. Intermediate state may vary according to system
3899// resources, but the final state is always the same.
3900var UpdateState = 0;
3901var ReplaceState = 1;
3902var ForceUpdate = 2;
3903var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
3904// It should only be read right after calling `processUpdateQueue`, via
3905// `checkHasForceUpdateAfterProcessing`.
3906
3907var hasForceUpdate = false;
3908var didWarnUpdateInsideUpdate;
3909var currentlyProcessingQueue;
3910
3911
3912{
3913 didWarnUpdateInsideUpdate = false;
3914 currentlyProcessingQueue = null;
3915
3916
3917}
3918
3919function createUpdateQueue(baseState) {
3920 var queue = {
3921 baseState: baseState,
3922 firstUpdate: null,
3923 lastUpdate: null,
3924 firstCapturedUpdate: null,
3925 lastCapturedUpdate: null,
3926 firstEffect: null,
3927 lastEffect: null,
3928 firstCapturedEffect: null,
3929 lastCapturedEffect: null
3930 };
3931 return queue;
3932}
3933
3934function cloneUpdateQueue(currentQueue) {
3935 var queue = {
3936 baseState: currentQueue.baseState,
3937 firstUpdate: currentQueue.firstUpdate,
3938 lastUpdate: currentQueue.lastUpdate,
3939 // TODO: With resuming, if we bail out and resuse the child tree, we should
3940 // keep these effects.
3941 firstCapturedUpdate: null,
3942 lastCapturedUpdate: null,
3943 firstEffect: null,
3944 lastEffect: null,
3945 firstCapturedEffect: null,
3946 lastCapturedEffect: null
3947 };
3948 return queue;
3949}
3950
3951function createUpdate(expirationTime, suspenseConfig) {
3952 var update = {
3953 expirationTime: expirationTime,
3954 suspenseConfig: suspenseConfig,
3955 tag: UpdateState,
3956 payload: null,
3957 callback: null,
3958 next: null,
3959 nextEffect: null
3960 };
3961
3962 {
3963 update.priority = getCurrentPriorityLevel();
3964 }
3965
3966 return update;
3967}
3968
3969function appendUpdateToQueue(queue, update) {
3970 // Append the update to the end of the list.
3971 if (queue.lastUpdate === null) {
3972 // Queue is empty
3973 queue.firstUpdate = queue.lastUpdate = update;
3974 } else {
3975 queue.lastUpdate.next = update;
3976 queue.lastUpdate = update;
3977 }
3978}
3979
3980function enqueueUpdate(fiber, update) {
3981 // Update queues are created lazily.
3982 var alternate = fiber.alternate;
3983 var queue1;
3984 var queue2;
3985
3986 if (alternate === null) {
3987 // There's only one fiber.
3988 queue1 = fiber.updateQueue;
3989 queue2 = null;
3990
3991 if (queue1 === null) {
3992 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
3993 }
3994 } else {
3995 // There are two owners.
3996 queue1 = fiber.updateQueue;
3997 queue2 = alternate.updateQueue;
3998
3999 if (queue1 === null) {
4000 if (queue2 === null) {
4001 // Neither fiber has an update queue. Create new ones.
4002 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
4003 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
4004 } else {
4005 // Only one fiber has an update queue. Clone to create a new one.
4006 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
4007 }
4008 } else {
4009 if (queue2 === null) {
4010 // Only one fiber has an update queue. Clone to create a new one.
4011 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
4012 } else {// Both owners have an update queue.
4013 }
4014 }
4015 }
4016
4017 if (queue2 === null || queue1 === queue2) {
4018 // There's only a single queue.
4019 appendUpdateToQueue(queue1, update);
4020 } else {
4021 // There are two queues. We need to append the update to both queues,
4022 // while accounting for the persistent structure of the list — we don't
4023 // want the same update to be added multiple times.
4024 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
4025 // One of the queues is not empty. We must add the update to both queues.
4026 appendUpdateToQueue(queue1, update);
4027 appendUpdateToQueue(queue2, update);
4028 } else {
4029 // Both queues are non-empty. The last update is the same in both lists,
4030 // because of structural sharing. So, only append to one of the lists.
4031 appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2.
4032
4033 queue2.lastUpdate = update;
4034 }
4035 }
4036
4037 {
4038 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
4039 warningWithoutStack$1(false, 'An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
4040 didWarnUpdateInsideUpdate = true;
4041 }
4042 }
4043}
4044function enqueueCapturedUpdate(workInProgress, update) {
4045 // Captured updates go into a separate list, and only on the work-in-
4046 // progress queue.
4047 var workInProgressQueue = workInProgress.updateQueue;
4048
4049 if (workInProgressQueue === null) {
4050 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
4051 } else {
4052 // TODO: I put this here rather than createWorkInProgress so that we don't
4053 // clone the queue unnecessarily. There's probably a better way to
4054 // structure this.
4055 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
4056 } // Append the update to the end of the list.
4057
4058
4059 if (workInProgressQueue.lastCapturedUpdate === null) {
4060 // This is the first render phase update
4061 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
4062 } else {
4063 workInProgressQueue.lastCapturedUpdate.next = update;
4064 workInProgressQueue.lastCapturedUpdate = update;
4065 }
4066}
4067
4068function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
4069 var current = workInProgress.alternate;
4070
4071 if (current !== null) {
4072 // If the work-in-progress queue is equal to the current queue,
4073 // we need to clone it first.
4074 if (queue === current.updateQueue) {
4075 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
4076 }
4077 }
4078
4079 return queue;
4080}
4081
4082function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
4083 switch (update.tag) {
4084 case ReplaceState:
4085 {
4086 var payload = update.payload;
4087
4088 if (typeof payload === 'function') {
4089 // Updater function
4090 {
4091 enterDisallowedContextReadInDEV();
4092
4093 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4094 payload.call(instance, prevState, nextProps);
4095 }
4096 }
4097
4098 var nextState = payload.call(instance, prevState, nextProps);
4099
4100 {
4101 exitDisallowedContextReadInDEV();
4102 }
4103
4104 return nextState;
4105 } // State object
4106
4107
4108 return payload;
4109 }
4110
4111 case CaptureUpdate:
4112 {
4113 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
4114 }
4115 // Intentional fallthrough
4116
4117 case UpdateState:
4118 {
4119 var _payload = update.payload;
4120 var partialState;
4121
4122 if (typeof _payload === 'function') {
4123 // Updater function
4124 {
4125 enterDisallowedContextReadInDEV();
4126
4127 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4128 _payload.call(instance, prevState, nextProps);
4129 }
4130 }
4131
4132 partialState = _payload.call(instance, prevState, nextProps);
4133
4134 {
4135 exitDisallowedContextReadInDEV();
4136 }
4137 } else {
4138 // Partial state object
4139 partialState = _payload;
4140 }
4141
4142 if (partialState === null || partialState === undefined) {
4143 // Null and undefined are treated as no-ops.
4144 return prevState;
4145 } // Merge the partial state and the previous state.
4146
4147
4148 return _assign({}, prevState, partialState);
4149 }
4150
4151 case ForceUpdate:
4152 {
4153 hasForceUpdate = true;
4154 return prevState;
4155 }
4156 }
4157
4158 return prevState;
4159}
4160
4161function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
4162 hasForceUpdate = false;
4163 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
4164
4165 {
4166 currentlyProcessingQueue = queue;
4167 } // These values may change as we process the queue.
4168
4169
4170 var newBaseState = queue.baseState;
4171 var newFirstUpdate = null;
4172 var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result.
4173
4174 var update = queue.firstUpdate;
4175 var resultState = newBaseState;
4176
4177 while (update !== null) {
4178 var updateExpirationTime = update.expirationTime;
4179
4180 if (updateExpirationTime < renderExpirationTime) {
4181 // This update does not have sufficient priority. Skip it.
4182 if (newFirstUpdate === null) {
4183 // This is the first skipped update. It will be the first update in
4184 // the new list.
4185 newFirstUpdate = update; // Since this is the first update that was skipped, the current result
4186 // is the new base state.
4187
4188 newBaseState = resultState;
4189 } // Since this update will remain in the list, update the remaining
4190 // expiration time.
4191
4192
4193 if (newExpirationTime < updateExpirationTime) {
4194 newExpirationTime = updateExpirationTime;
4195 }
4196 } else {
4197 // This update does have sufficient priority.
4198 // Mark the event time of this update as relevant to this render pass.
4199 // TODO: This should ideally use the true event time of this update rather than
4200 // its priority which is a derived and not reverseable value.
4201 // TODO: We should skip this update if it was already committed but currently
4202 // we have no way of detecting the difference between a committed and suspended
4203 // update here.
4204 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result.
4205
4206 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
4207 var callback = update.callback;
4208
4209 if (callback !== null) {
4210 workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render.
4211
4212 update.nextEffect = null;
4213
4214 if (queue.lastEffect === null) {
4215 queue.firstEffect = queue.lastEffect = update;
4216 } else {
4217 queue.lastEffect.nextEffect = update;
4218 queue.lastEffect = update;
4219 }
4220 }
4221 } // Continue to the next update.
4222
4223
4224 update = update.next;
4225 } // Separately, iterate though the list of captured updates.
4226
4227
4228 var newFirstCapturedUpdate = null;
4229 update = queue.firstCapturedUpdate;
4230
4231 while (update !== null) {
4232 var _updateExpirationTime = update.expirationTime;
4233
4234 if (_updateExpirationTime < renderExpirationTime) {
4235 // This update does not have sufficient priority. Skip it.
4236 if (newFirstCapturedUpdate === null) {
4237 // This is the first skipped captured update. It will be the first
4238 // update in the new list.
4239 newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is
4240 // the new base state.
4241
4242 if (newFirstUpdate === null) {
4243 newBaseState = resultState;
4244 }
4245 } // Since this update will remain in the list, update the remaining
4246 // expiration time.
4247
4248
4249 if (newExpirationTime < _updateExpirationTime) {
4250 newExpirationTime = _updateExpirationTime;
4251 }
4252 } else {
4253 // This update does have sufficient priority. Process it and compute
4254 // a new result.
4255 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
4256 var _callback = update.callback;
4257
4258 if (_callback !== null) {
4259 workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render.
4260
4261 update.nextEffect = null;
4262
4263 if (queue.lastCapturedEffect === null) {
4264 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
4265 } else {
4266 queue.lastCapturedEffect.nextEffect = update;
4267 queue.lastCapturedEffect = update;
4268 }
4269 }
4270 }
4271
4272 update = update.next;
4273 }
4274
4275 if (newFirstUpdate === null) {
4276 queue.lastUpdate = null;
4277 }
4278
4279 if (newFirstCapturedUpdate === null) {
4280 queue.lastCapturedUpdate = null;
4281 } else {
4282 workInProgress.effectTag |= Callback;
4283 }
4284
4285 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
4286 // We processed every update, without skipping. That means the new base
4287 // state is the same as the result state.
4288 newBaseState = resultState;
4289 }
4290
4291 queue.baseState = newBaseState;
4292 queue.firstUpdate = newFirstUpdate;
4293 queue.firstCapturedUpdate = newFirstCapturedUpdate; // Set the remaining expiration time to be whatever is remaining in the queue.
4294 // This should be fine because the only two other things that contribute to
4295 // expiration time are props and context. We're already in the middle of the
4296 // begin phase by the time we start processing the queue, so we've already
4297 // dealt with the props. Context in components that specify
4298 // shouldComponentUpdate is tricky; but we'll have to account for
4299 // that regardless.
4300
4301 markUnprocessedUpdateTime(newExpirationTime);
4302 workInProgress.expirationTime = newExpirationTime;
4303 workInProgress.memoizedState = resultState;
4304
4305 {
4306 currentlyProcessingQueue = null;
4307 }
4308}
4309
4310function callCallback(callback, context) {
4311 (function () {
4312 if (!(typeof callback === 'function')) {
4313 {
4314 throw ReactError(Error("Invalid argument passed as callback. Expected a function. Instead received: " + callback));
4315 }
4316 }
4317 })();
4318
4319 callback.call(context);
4320}
4321
4322function resetHasForceUpdateBeforeProcessing() {
4323 hasForceUpdate = false;
4324}
4325function checkHasForceUpdateAfterProcessing() {
4326 return hasForceUpdate;
4327}
4328function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
4329 // If the finished render included captured updates, and there are still
4330 // lower priority updates left over, we need to keep the captured updates
4331 // in the queue so that they are rebased and not dropped once we process the
4332 // queue again at the lower priority.
4333 if (finishedQueue.firstCapturedUpdate !== null) {
4334 // Join the captured update list to the end of the normal list.
4335 if (finishedQueue.lastUpdate !== null) {
4336 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
4337 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
4338 } // Clear the list of captured updates.
4339
4340
4341 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
4342 } // Commit the effects
4343
4344
4345 commitUpdateEffects(finishedQueue.firstEffect, instance);
4346 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
4347 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
4348 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
4349}
4350
4351function commitUpdateEffects(effect, instance) {
4352 while (effect !== null) {
4353 var callback = effect.callback;
4354
4355 if (callback !== null) {
4356 effect.callback = null;
4357 callCallback(callback, instance);
4358 }
4359
4360 effect = effect.nextEffect;
4361 }
4362}
4363
4364var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
4365function requestCurrentSuspenseConfig() {
4366 return ReactCurrentBatchConfig.suspense;
4367}
4368
4369var fakeInternalInstance = {};
4370var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default.
4371// We'll use it to determine whether we need to initialize legacy refs.
4372
4373var emptyRefsObject = new React.Component().refs;
4374var didWarnAboutStateAssignmentForComponent;
4375var didWarnAboutUninitializedState;
4376var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
4377var didWarnAboutLegacyLifecyclesAndDerivedState;
4378var didWarnAboutUndefinedDerivedState;
4379var warnOnUndefinedDerivedState;
4380var warnOnInvalidCallback;
4381var didWarnAboutDirectlyAssigningPropsToState;
4382var didWarnAboutContextTypeAndContextTypes;
4383var didWarnAboutInvalidateContextType;
4384
4385{
4386 didWarnAboutStateAssignmentForComponent = new Set();
4387 didWarnAboutUninitializedState = new Set();
4388 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
4389 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
4390 didWarnAboutDirectlyAssigningPropsToState = new Set();
4391 didWarnAboutUndefinedDerivedState = new Set();
4392 didWarnAboutContextTypeAndContextTypes = new Set();
4393 didWarnAboutInvalidateContextType = new Set();
4394 var didWarnOnInvalidCallback = new Set();
4395
4396 warnOnInvalidCallback = function (callback, callerName) {
4397 if (callback === null || typeof callback === 'function') {
4398 return;
4399 }
4400
4401 var key = callerName + "_" + callback;
4402
4403 if (!didWarnOnInvalidCallback.has(key)) {
4404 didWarnOnInvalidCallback.add(key);
4405 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
4406 }
4407 };
4408
4409 warnOnUndefinedDerivedState = function (type, partialState) {
4410 if (partialState === undefined) {
4411 var componentName = getComponentName(type) || 'Component';
4412
4413 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
4414 didWarnAboutUndefinedDerivedState.add(componentName);
4415 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
4416 }
4417 }
4418 }; // This is so gross but it's at least non-critical and can be removed if
4419 // it causes problems. This is meant to give a nicer error message for
4420 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
4421 // ...)) which otherwise throws a "_processChildContext is not a function"
4422 // exception.
4423
4424
4425 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
4426 enumerable: false,
4427 value: function () {
4428 (function () {
4429 {
4430 {
4431 throw ReactError(Error("_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)."));
4432 }
4433 }
4434 })();
4435 }
4436 });
4437 Object.freeze(fakeInternalInstance);
4438}
4439
4440function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
4441 var prevState = workInProgress.memoizedState;
4442
4443 {
4444 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4445 // Invoke the function an extra time to help detect side-effects.
4446 getDerivedStateFromProps(nextProps, prevState);
4447 }
4448 }
4449
4450 var partialState = getDerivedStateFromProps(nextProps, prevState);
4451
4452 {
4453 warnOnUndefinedDerivedState(ctor, partialState);
4454 } // Merge the partial state and the previous state.
4455
4456
4457 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
4458 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
4459 // base state.
4460
4461 var updateQueue = workInProgress.updateQueue;
4462
4463 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
4464 updateQueue.baseState = memoizedState;
4465 }
4466}
4467var classComponentUpdater = {
4468 isMounted: isMounted,
4469 enqueueSetState: function (inst, payload, callback) {
4470 var fiber = get(inst);
4471 var currentTime = requestCurrentTime();
4472 var suspenseConfig = requestCurrentSuspenseConfig();
4473 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
4474 var update = createUpdate(expirationTime, suspenseConfig);
4475 update.payload = payload;
4476
4477 if (callback !== undefined && callback !== null) {
4478 {
4479 warnOnInvalidCallback(callback, 'setState');
4480 }
4481
4482 update.callback = callback;
4483 }
4484
4485 enqueueUpdate(fiber, update);
4486 scheduleWork(fiber, expirationTime);
4487 },
4488 enqueueReplaceState: function (inst, payload, callback) {
4489 var fiber = get(inst);
4490 var currentTime = requestCurrentTime();
4491 var suspenseConfig = requestCurrentSuspenseConfig();
4492 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
4493 var update = createUpdate(expirationTime, suspenseConfig);
4494 update.tag = ReplaceState;
4495 update.payload = payload;
4496
4497 if (callback !== undefined && callback !== null) {
4498 {
4499 warnOnInvalidCallback(callback, 'replaceState');
4500 }
4501
4502 update.callback = callback;
4503 }
4504
4505 enqueueUpdate(fiber, update);
4506 scheduleWork(fiber, expirationTime);
4507 },
4508 enqueueForceUpdate: function (inst, callback) {
4509 var fiber = get(inst);
4510 var currentTime = requestCurrentTime();
4511 var suspenseConfig = requestCurrentSuspenseConfig();
4512 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
4513 var update = createUpdate(expirationTime, suspenseConfig);
4514 update.tag = ForceUpdate;
4515
4516 if (callback !== undefined && callback !== null) {
4517 {
4518 warnOnInvalidCallback(callback, 'forceUpdate');
4519 }
4520
4521 update.callback = callback;
4522 }
4523
4524 enqueueUpdate(fiber, update);
4525 scheduleWork(fiber, expirationTime);
4526 }
4527};
4528
4529function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
4530 var instance = workInProgress.stateNode;
4531
4532 if (typeof instance.shouldComponentUpdate === 'function') {
4533 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
4534 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
4535 stopPhaseTimer();
4536
4537 {
4538 !(shouldUpdate !== undefined) ? warningWithoutStack$1(false, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component') : void 0;
4539 }
4540
4541 return shouldUpdate;
4542 }
4543
4544 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
4545 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
4546 }
4547
4548 return true;
4549}
4550
4551function checkClassInstance(workInProgress, ctor, newProps) {
4552 var instance = workInProgress.stateNode;
4553
4554 {
4555 var name = getComponentName(ctor) || 'Component';
4556 var renderPresent = instance.render;
4557
4558 if (!renderPresent) {
4559 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
4560 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
4561 } else {
4562 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
4563 }
4564 }
4565
4566 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
4567 !noGetInitialStateOnES6 ? warningWithoutStack$1(false, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name) : void 0;
4568 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
4569 !noGetDefaultPropsOnES6 ? warningWithoutStack$1(false, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name) : void 0;
4570 var noInstancePropTypes = !instance.propTypes;
4571 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
4572 var noInstanceContextType = !instance.contextType;
4573 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
4574
4575 if (disableLegacyContext) {
4576 if (ctor.childContextTypes) {
4577 warningWithoutStack$1(false, '%s uses the legacy childContextTypes API which is no longer supported. ' + 'Use React.createContext() instead.', name);
4578 }
4579
4580 if (ctor.contextTypes) {
4581 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with static contextType instead.', name);
4582 }
4583 } else {
4584 var noInstanceContextTypes = !instance.contextTypes;
4585 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
4586
4587 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
4588 didWarnAboutContextTypeAndContextTypes.add(ctor);
4589 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
4590 }
4591 }
4592
4593 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
4594 !noComponentShouldUpdate ? warningWithoutStack$1(false, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name) : void 0;
4595
4596 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
4597 warningWithoutStack$1(false, '%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
4598 }
4599
4600 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
4601 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
4602 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
4603 !noComponentDidReceiveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name) : void 0;
4604 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
4605 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
4606 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
4607 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
4608 var hasMutatedProps = instance.props !== newProps;
4609 !(instance.props === undefined || !hasMutatedProps) ? warningWithoutStack$1(false, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name) : void 0;
4610 var noInstanceDefaultProps = !instance.defaultProps;
4611 !noInstanceDefaultProps ? warningWithoutStack$1(false, 'Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name) : void 0;
4612
4613 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
4614 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
4615 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
4616 }
4617
4618 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
4619 !noInstanceGetDerivedStateFromProps ? warningWithoutStack$1(false, '%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
4620 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
4621 !noInstanceGetDerivedStateFromCatch ? warningWithoutStack$1(false, '%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
4622 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
4623 !noStaticGetSnapshotBeforeUpdate ? warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name) : void 0;
4624 var _state = instance.state;
4625
4626 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
4627 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
4628 }
4629
4630 if (typeof instance.getChildContext === 'function') {
4631 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
4632 }
4633 }
4634}
4635
4636function adoptClassInstance(workInProgress, instance) {
4637 instance.updater = classComponentUpdater;
4638 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
4639
4640 set$1(instance, workInProgress);
4641
4642 {
4643 instance._reactInternalInstance = fakeInternalInstance;
4644 }
4645}
4646
4647function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
4648 var isLegacyContextConsumer = false;
4649 var unmaskedContext = emptyContextObject;
4650 var context = emptyContextObject;
4651 var contextType = ctor.contextType;
4652
4653 {
4654 if ('contextType' in ctor) {
4655 var isValid = // Allow null for conditional declaration
4656 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
4657
4658 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
4659 didWarnAboutInvalidateContextType.add(ctor);
4660 var addendum = '';
4661
4662 if (contextType === undefined) {
4663 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.';
4664 } else if (typeof contextType !== 'object') {
4665 addendum = ' However, it is set to a ' + typeof contextType + '.';
4666 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
4667 addendum = ' Did you accidentally pass the Context.Provider instead?';
4668 } else if (contextType._context !== undefined) {
4669 // <Context.Consumer>
4670 addendum = ' Did you accidentally pass the Context.Consumer instead?';
4671 } else {
4672 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
4673 }
4674
4675 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
4676 }
4677 }
4678 }
4679
4680 if (typeof contextType === 'object' && contextType !== null) {
4681 context = readContext(contextType);
4682 } else if (!disableLegacyContext) {
4683 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4684 var contextTypes = ctor.contextTypes;
4685 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
4686 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
4687 } // Instantiate twice to help detect side-effects.
4688
4689
4690 {
4691 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4692 new ctor(props, context); // eslint-disable-line no-new
4693 }
4694 }
4695
4696 var instance = new ctor(props, context);
4697 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
4698 adoptClassInstance(workInProgress, instance);
4699
4700 {
4701 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
4702 var componentName = getComponentName(ctor) || 'Component';
4703
4704 if (!didWarnAboutUninitializedState.has(componentName)) {
4705 didWarnAboutUninitializedState.add(componentName);
4706 warningWithoutStack$1(false, '`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
4707 }
4708 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
4709 // Warn about these lifecycles if they are present.
4710 // Don't warn about react-lifecycles-compat polyfilled methods though.
4711
4712
4713 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
4714 var foundWillMountName = null;
4715 var foundWillReceivePropsName = null;
4716 var foundWillUpdateName = null;
4717
4718 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
4719 foundWillMountName = 'componentWillMount';
4720 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
4721 foundWillMountName = 'UNSAFE_componentWillMount';
4722 }
4723
4724 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
4725 foundWillReceivePropsName = 'componentWillReceiveProps';
4726 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4727 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
4728 }
4729
4730 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
4731 foundWillUpdateName = 'componentWillUpdate';
4732 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4733 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
4734 }
4735
4736 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
4737 var _componentName = getComponentName(ctor) || 'Component';
4738
4739 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
4740
4741 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
4742 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
4743 warningWithoutStack$1(false, 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
4744 }
4745 }
4746 }
4747 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
4748 // ReactFiberContext usually updates this cache but can't for newly-created instances.
4749
4750
4751 if (isLegacyContextConsumer) {
4752 cacheContext(workInProgress, unmaskedContext, context);
4753 }
4754
4755 return instance;
4756}
4757
4758function callComponentWillMount(workInProgress, instance) {
4759 startPhaseTimer(workInProgress, 'componentWillMount');
4760 var oldState = instance.state;
4761
4762 if (typeof instance.componentWillMount === 'function') {
4763 instance.componentWillMount();
4764 }
4765
4766 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4767 instance.UNSAFE_componentWillMount();
4768 }
4769
4770 stopPhaseTimer();
4771
4772 if (oldState !== instance.state) {
4773 {
4774 warningWithoutStack$1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
4775 }
4776
4777 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4778 }
4779}
4780
4781function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4782 var oldState = instance.state;
4783 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4784
4785 if (typeof instance.componentWillReceiveProps === 'function') {
4786 instance.componentWillReceiveProps(newProps, nextContext);
4787 }
4788
4789 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4790 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4791 }
4792
4793 stopPhaseTimer();
4794
4795 if (instance.state !== oldState) {
4796 {
4797 var componentName = getComponentName(workInProgress.type) || 'Component';
4798
4799 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4800 didWarnAboutStateAssignmentForComponent.add(componentName);
4801 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4802 }
4803 }
4804
4805 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4806 }
4807} // Invokes the mount life-cycles on a previously never rendered instance.
4808
4809
4810function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4811 {
4812 checkClassInstance(workInProgress, ctor, newProps);
4813 }
4814
4815 var instance = workInProgress.stateNode;
4816 instance.props = newProps;
4817 instance.state = workInProgress.memoizedState;
4818 instance.refs = emptyRefsObject;
4819 var contextType = ctor.contextType;
4820
4821 if (typeof contextType === 'object' && contextType !== null) {
4822 instance.context = readContext(contextType);
4823 } else if (disableLegacyContext) {
4824 instance.context = emptyContextObject;
4825 } else {
4826 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4827 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4828 }
4829
4830 {
4831 if (instance.state === newProps) {
4832 var componentName = getComponentName(ctor) || 'Component';
4833
4834 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4835 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4836 warningWithoutStack$1(false, '%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
4837 }
4838 }
4839
4840 if (workInProgress.mode & StrictMode) {
4841 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4842 }
4843
4844 if (warnAboutDeprecatedLifecycles) {
4845 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4846 }
4847 }
4848
4849 var updateQueue = workInProgress.updateQueue;
4850
4851 if (updateQueue !== null) {
4852 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4853 instance.state = workInProgress.memoizedState;
4854 }
4855
4856 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4857
4858 if (typeof getDerivedStateFromProps === 'function') {
4859 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4860 instance.state = workInProgress.memoizedState;
4861 } // In order to support react-lifecycles-compat polyfilled components,
4862 // Unsafe lifecycles should not be invoked for components using the new APIs.
4863
4864
4865 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4866 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
4867 // process them now.
4868
4869 updateQueue = workInProgress.updateQueue;
4870
4871 if (updateQueue !== null) {
4872 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4873 instance.state = workInProgress.memoizedState;
4874 }
4875 }
4876
4877 if (typeof instance.componentDidMount === 'function') {
4878 workInProgress.effectTag |= Update;
4879 }
4880}
4881
4882function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4883 var instance = workInProgress.stateNode;
4884 var oldProps = workInProgress.memoizedProps;
4885 instance.props = oldProps;
4886 var oldContext = instance.context;
4887 var contextType = ctor.contextType;
4888 var nextContext = emptyContextObject;
4889
4890 if (typeof contextType === 'object' && contextType !== null) {
4891 nextContext = readContext(contextType);
4892 } else if (!disableLegacyContext) {
4893 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4894 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4895 }
4896
4897 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4898 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4899 // ever the previously attempted to render - not the "current". However,
4900 // during componentDidUpdate we pass the "current" props.
4901 // In order to support react-lifecycles-compat polyfilled components,
4902 // Unsafe lifecycles should not be invoked for components using the new APIs.
4903
4904 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4905 if (oldProps !== newProps || oldContext !== nextContext) {
4906 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4907 }
4908 }
4909
4910 resetHasForceUpdateBeforeProcessing();
4911 var oldState = workInProgress.memoizedState;
4912 var newState = instance.state = oldState;
4913 var updateQueue = workInProgress.updateQueue;
4914
4915 if (updateQueue !== null) {
4916 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4917 newState = workInProgress.memoizedState;
4918 }
4919
4920 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4921 // If an update was already in progress, we should schedule an Update
4922 // effect even though we're bailing out, so that cWU/cDU are called.
4923 if (typeof instance.componentDidMount === 'function') {
4924 workInProgress.effectTag |= Update;
4925 }
4926
4927 return false;
4928 }
4929
4930 if (typeof getDerivedStateFromProps === 'function') {
4931 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4932 newState = workInProgress.memoizedState;
4933 }
4934
4935 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4936
4937 if (shouldUpdate) {
4938 // In order to support react-lifecycles-compat polyfilled components,
4939 // Unsafe lifecycles should not be invoked for components using the new APIs.
4940 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4941 startPhaseTimer(workInProgress, 'componentWillMount');
4942
4943 if (typeof instance.componentWillMount === 'function') {
4944 instance.componentWillMount();
4945 }
4946
4947 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4948 instance.UNSAFE_componentWillMount();
4949 }
4950
4951 stopPhaseTimer();
4952 }
4953
4954 if (typeof instance.componentDidMount === 'function') {
4955 workInProgress.effectTag |= Update;
4956 }
4957 } else {
4958 // If an update was already in progress, we should schedule an Update
4959 // effect even though we're bailing out, so that cWU/cDU are called.
4960 if (typeof instance.componentDidMount === 'function') {
4961 workInProgress.effectTag |= Update;
4962 } // If shouldComponentUpdate returned false, we should still update the
4963 // memoized state to indicate that this work can be reused.
4964
4965
4966 workInProgress.memoizedProps = newProps;
4967 workInProgress.memoizedState = newState;
4968 } // Update the existing instance's state, props, and context pointers even
4969 // if shouldComponentUpdate returns false.
4970
4971
4972 instance.props = newProps;
4973 instance.state = newState;
4974 instance.context = nextContext;
4975 return shouldUpdate;
4976} // Invokes the update life-cycles and returns false if it shouldn't rerender.
4977
4978
4979function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4980 var instance = workInProgress.stateNode;
4981 var oldProps = workInProgress.memoizedProps;
4982 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4983 var oldContext = instance.context;
4984 var contextType = ctor.contextType;
4985 var nextContext = emptyContextObject;
4986
4987 if (typeof contextType === 'object' && contextType !== null) {
4988 nextContext = readContext(contextType);
4989 } else if (!disableLegacyContext) {
4990 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4991 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4992 }
4993
4994 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4995 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4996 // ever the previously attempted to render - not the "current". However,
4997 // during componentDidUpdate we pass the "current" props.
4998 // In order to support react-lifecycles-compat polyfilled components,
4999 // Unsafe lifecycles should not be invoked for components using the new APIs.
5000
5001 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
5002 if (oldProps !== newProps || oldContext !== nextContext) {
5003 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
5004 }
5005 }
5006
5007 resetHasForceUpdateBeforeProcessing();
5008 var oldState = workInProgress.memoizedState;
5009 var newState = instance.state = oldState;
5010 var updateQueue = workInProgress.updateQueue;
5011
5012 if (updateQueue !== null) {
5013 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
5014 newState = workInProgress.memoizedState;
5015 }
5016
5017 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
5018 // If an update was already in progress, we should schedule an Update
5019 // effect even though we're bailing out, so that cWU/cDU are called.
5020 if (typeof instance.componentDidUpdate === 'function') {
5021 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
5022 workInProgress.effectTag |= Update;
5023 }
5024 }
5025
5026 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
5027 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
5028 workInProgress.effectTag |= Snapshot;
5029 }
5030 }
5031
5032 return false;
5033 }
5034
5035 if (typeof getDerivedStateFromProps === 'function') {
5036 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
5037 newState = workInProgress.memoizedState;
5038 }
5039
5040 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
5041
5042 if (shouldUpdate) {
5043 // In order to support react-lifecycles-compat polyfilled components,
5044 // Unsafe lifecycles should not be invoked for components using the new APIs.
5045 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
5046 startPhaseTimer(workInProgress, 'componentWillUpdate');
5047
5048 if (typeof instance.componentWillUpdate === 'function') {
5049 instance.componentWillUpdate(newProps, newState, nextContext);
5050 }
5051
5052 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
5053 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
5054 }
5055
5056 stopPhaseTimer();
5057 }
5058
5059 if (typeof instance.componentDidUpdate === 'function') {
5060 workInProgress.effectTag |= Update;
5061 }
5062
5063 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
5064 workInProgress.effectTag |= Snapshot;
5065 }
5066 } else {
5067 // If an update was already in progress, we should schedule an Update
5068 // effect even though we're bailing out, so that cWU/cDU are called.
5069 if (typeof instance.componentDidUpdate === 'function') {
5070 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
5071 workInProgress.effectTag |= Update;
5072 }
5073 }
5074
5075 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
5076 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
5077 workInProgress.effectTag |= Snapshot;
5078 }
5079 } // If shouldComponentUpdate returned false, we should still update the
5080 // memoized props/state to indicate that this work can be reused.
5081
5082
5083 workInProgress.memoizedProps = newProps;
5084 workInProgress.memoizedState = newState;
5085 } // Update the existing instance's state, props, and context pointers even
5086 // if shouldComponentUpdate returns false.
5087
5088
5089 instance.props = newProps;
5090 instance.state = newState;
5091 instance.context = nextContext;
5092 return shouldUpdate;
5093}
5094
5095var didWarnAboutMaps;
5096var didWarnAboutGenerators;
5097var didWarnAboutStringRefs;
5098var ownerHasKeyUseWarning;
5099var ownerHasFunctionTypeWarning;
5100
5101var warnForMissingKey = function (child) {};
5102
5103{
5104 didWarnAboutMaps = false;
5105 didWarnAboutGenerators = false;
5106 didWarnAboutStringRefs = {};
5107 /**
5108 * Warn if there's no key explicitly set on dynamic arrays of children or
5109 * object keys are not valid. This allows us to keep track of children between
5110 * updates.
5111 */
5112
5113 ownerHasKeyUseWarning = {};
5114 ownerHasFunctionTypeWarning = {};
5115
5116 warnForMissingKey = function (child) {
5117 if (child === null || typeof child !== 'object') {
5118 return;
5119 }
5120
5121 if (!child._store || child._store.validated || child.key != null) {
5122 return;
5123 }
5124
5125 (function () {
5126 if (!(typeof child._store === 'object')) {
5127 {
5128 throw ReactError(Error("React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue."));
5129 }
5130 }
5131 })();
5132
5133 child._store.validated = true;
5134 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
5135
5136 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
5137 return;
5138 }
5139
5140 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
5141 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
5142 };
5143}
5144
5145var isArray = Array.isArray;
5146
5147function coerceRef(returnFiber, current, element) {
5148 var mixedRef = element.ref;
5149
5150 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
5151 {
5152 // TODO: Clean this up once we turn on the string ref warning for
5153 // everyone, because the strict mode case will no longer be relevant
5154 if (returnFiber.mode & StrictMode || warnAboutStringRefs) {
5155 var componentName = getComponentName(returnFiber.type) || 'Component';
5156
5157 if (!didWarnAboutStringRefs[componentName]) {
5158 if (warnAboutStringRefs) {
5159 warningWithoutStack$1(false, 'Component "%s" contains the string ref "%s". Support for string refs ' + 'will be removed in a future major release. We recommend using ' + 'useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', componentName, mixedRef, getStackByFiberInDevAndProd(returnFiber));
5160 } else {
5161 warningWithoutStack$1(false, 'A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', mixedRef, getStackByFiberInDevAndProd(returnFiber));
5162 }
5163
5164 didWarnAboutStringRefs[componentName] = true;
5165 }
5166 }
5167 }
5168
5169 if (element._owner) {
5170 var owner = element._owner;
5171 var inst;
5172
5173 if (owner) {
5174 var ownerFiber = owner;
5175
5176 (function () {
5177 if (!(ownerFiber.tag === ClassComponent)) {
5178 {
5179 throw ReactError(Error("Function components cannot have refs. Did you mean to use React.forwardRef()?"));
5180 }
5181 }
5182 })();
5183
5184 inst = ownerFiber.stateNode;
5185 }
5186
5187 (function () {
5188 if (!inst) {
5189 {
5190 throw ReactError(Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue."));
5191 }
5192 }
5193 })();
5194
5195 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
5196
5197 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
5198 return current.ref;
5199 }
5200
5201 var ref = function (value) {
5202 var refs = inst.refs;
5203
5204 if (refs === emptyRefsObject) {
5205 // This is a lazy pooled frozen object, so we need to initialize.
5206 refs = inst.refs = {};
5207 }
5208
5209 if (value === null) {
5210 delete refs[stringRef];
5211 } else {
5212 refs[stringRef] = value;
5213 }
5214 };
5215
5216 ref._stringRef = stringRef;
5217 return ref;
5218 } else {
5219 (function () {
5220 if (!(typeof mixedRef === 'string')) {
5221 {
5222 throw ReactError(Error("Expected ref to be a function, a string, an object returned by React.createRef(), or null."));
5223 }
5224 }
5225 })();
5226
5227 (function () {
5228 if (!element._owner) {
5229 {
5230 throw ReactError(Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information."));
5231 }
5232 }
5233 })();
5234 }
5235 }
5236
5237 return mixedRef;
5238}
5239
5240function throwOnInvalidObjectType(returnFiber, newChild) {
5241 if (returnFiber.type !== 'textarea') {
5242 var addendum = '';
5243
5244 {
5245 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
5246 }
5247
5248 (function () {
5249 {
5250 {
5251 throw ReactError(Error("Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + ")." + addendum));
5252 }
5253 }
5254 })();
5255 }
5256}
5257
5258function warnOnFunctionType() {
5259 var currentComponentErrorInfo = 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.' + getCurrentFiberStackInDev();
5260
5261 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
5262 return;
5263 }
5264
5265 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
5266 warning$1(false, 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
5267} // This wrapper function exists because I expect to clone the code in each path
5268// to be able to optimize each path individually by branching early. This needs
5269// a compiler or we can do it manually. Helpers that don't need this branching
5270// live outside of this function.
5271
5272
5273function ChildReconciler(shouldTrackSideEffects) {
5274 function deleteChild(returnFiber, childToDelete) {
5275 if (!shouldTrackSideEffects) {
5276 // Noop.
5277 return;
5278 } // Deletions are added in reversed order so we add it to the front.
5279 // At this point, the return fiber's effect list is empty except for
5280 // deletions, so we can just append the deletion to the list. The remaining
5281 // effects aren't added until the complete phase. Once we implement
5282 // resuming, this may not be true.
5283
5284
5285 var last = returnFiber.lastEffect;
5286
5287 if (last !== null) {
5288 last.nextEffect = childToDelete;
5289 returnFiber.lastEffect = childToDelete;
5290 } else {
5291 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
5292 }
5293
5294 childToDelete.nextEffect = null;
5295 childToDelete.effectTag = Deletion;
5296 }
5297
5298 function deleteRemainingChildren(returnFiber, currentFirstChild) {
5299 if (!shouldTrackSideEffects) {
5300 // Noop.
5301 return null;
5302 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
5303 // assuming that after the first child we've already added everything.
5304
5305
5306 var childToDelete = currentFirstChild;
5307
5308 while (childToDelete !== null) {
5309 deleteChild(returnFiber, childToDelete);
5310 childToDelete = childToDelete.sibling;
5311 }
5312
5313 return null;
5314 }
5315
5316 function mapRemainingChildren(returnFiber, currentFirstChild) {
5317 // Add the remaining children to a temporary map so that we can find them by
5318 // keys quickly. Implicit (null) keys get added to this set with their index
5319 // instead.
5320 var existingChildren = new Map();
5321 var existingChild = currentFirstChild;
5322
5323 while (existingChild !== null) {
5324 if (existingChild.key !== null) {
5325 existingChildren.set(existingChild.key, existingChild);
5326 } else {
5327 existingChildren.set(existingChild.index, existingChild);
5328 }
5329
5330 existingChild = existingChild.sibling;
5331 }
5332
5333 return existingChildren;
5334 }
5335
5336 function useFiber(fiber, pendingProps, expirationTime) {
5337 // We currently set sibling to null and index to 0 here because it is easy
5338 // to forget to do before returning it. E.g. for the single child case.
5339 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
5340 clone.index = 0;
5341 clone.sibling = null;
5342 return clone;
5343 }
5344
5345 function placeChild(newFiber, lastPlacedIndex, newIndex) {
5346 newFiber.index = newIndex;
5347
5348 if (!shouldTrackSideEffects) {
5349 // Noop.
5350 return lastPlacedIndex;
5351 }
5352
5353 var current = newFiber.alternate;
5354
5355 if (current !== null) {
5356 var oldIndex = current.index;
5357
5358 if (oldIndex < lastPlacedIndex) {
5359 // This is a move.
5360 newFiber.effectTag = Placement;
5361 return lastPlacedIndex;
5362 } else {
5363 // This item can stay in place.
5364 return oldIndex;
5365 }
5366 } else {
5367 // This is an insertion.
5368 newFiber.effectTag = Placement;
5369 return lastPlacedIndex;
5370 }
5371 }
5372
5373 function placeSingleChild(newFiber) {
5374 // This is simpler for the single child case. We only need to do a
5375 // placement for inserting new children.
5376 if (shouldTrackSideEffects && newFiber.alternate === null) {
5377 newFiber.effectTag = Placement;
5378 }
5379
5380 return newFiber;
5381 }
5382
5383 function updateTextNode(returnFiber, current, textContent, expirationTime) {
5384 if (current === null || current.tag !== HostText) {
5385 // Insert
5386 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5387 created.return = returnFiber;
5388 return created;
5389 } else {
5390 // Update
5391 var existing = useFiber(current, textContent, expirationTime);
5392 existing.return = returnFiber;
5393 return existing;
5394 }
5395 }
5396
5397 function updateElement(returnFiber, current, element, expirationTime) {
5398 if (current !== null && (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
5399 isCompatibleFamilyForHotReloading(current, element)))) {
5400 // Move based on index
5401 var existing = useFiber(current, element.props, expirationTime);
5402 existing.ref = coerceRef(returnFiber, current, element);
5403 existing.return = returnFiber;
5404
5405 {
5406 existing._debugSource = element._source;
5407 existing._debugOwner = element._owner;
5408 }
5409
5410 return existing;
5411 } else {
5412 // Insert
5413 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
5414 created.ref = coerceRef(returnFiber, current, element);
5415 created.return = returnFiber;
5416 return created;
5417 }
5418 }
5419
5420 function updatePortal(returnFiber, current, portal, expirationTime) {
5421 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
5422 // Insert
5423 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5424 created.return = returnFiber;
5425 return created;
5426 } else {
5427 // Update
5428 var existing = useFiber(current, portal.children || [], expirationTime);
5429 existing.return = returnFiber;
5430 return existing;
5431 }
5432 }
5433
5434 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
5435 if (current === null || current.tag !== Fragment) {
5436 // Insert
5437 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
5438 created.return = returnFiber;
5439 return created;
5440 } else {
5441 // Update
5442 var existing = useFiber(current, fragment, expirationTime);
5443 existing.return = returnFiber;
5444 return existing;
5445 }
5446 }
5447
5448 function createChild(returnFiber, newChild, expirationTime) {
5449 if (typeof newChild === 'string' || typeof newChild === 'number') {
5450 // Text nodes don't have keys. If the previous node is implicitly keyed
5451 // we can continue to replace it without aborting even if it is not a text
5452 // node.
5453 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
5454 created.return = returnFiber;
5455 return created;
5456 }
5457
5458 if (typeof newChild === 'object' && newChild !== null) {
5459 switch (newChild.$$typeof) {
5460 case REACT_ELEMENT_TYPE$1:
5461 {
5462 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
5463
5464 _created.ref = coerceRef(returnFiber, null, newChild);
5465 _created.return = returnFiber;
5466 return _created;
5467 }
5468
5469 case REACT_PORTAL_TYPE:
5470 {
5471 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
5472
5473 _created2.return = returnFiber;
5474 return _created2;
5475 }
5476 }
5477
5478 if (isArray(newChild) || getIteratorFn(newChild)) {
5479 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
5480
5481 _created3.return = returnFiber;
5482 return _created3;
5483 }
5484
5485 throwOnInvalidObjectType(returnFiber, newChild);
5486 }
5487
5488 {
5489 if (typeof newChild === 'function') {
5490 warnOnFunctionType();
5491 }
5492 }
5493
5494 return null;
5495 }
5496
5497 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
5498 // Update the fiber if the keys match, otherwise return null.
5499 var key = oldFiber !== null ? oldFiber.key : null;
5500
5501 if (typeof newChild === 'string' || typeof newChild === 'number') {
5502 // Text nodes don't have keys. If the previous node is implicitly keyed
5503 // we can continue to replace it without aborting even if it is not a text
5504 // node.
5505 if (key !== null) {
5506 return null;
5507 }
5508
5509 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
5510 }
5511
5512 if (typeof newChild === 'object' && newChild !== null) {
5513 switch (newChild.$$typeof) {
5514 case REACT_ELEMENT_TYPE$1:
5515 {
5516 if (newChild.key === key) {
5517 if (newChild.type === REACT_FRAGMENT_TYPE) {
5518 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
5519 }
5520
5521 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
5522 } else {
5523 return null;
5524 }
5525 }
5526
5527 case REACT_PORTAL_TYPE:
5528 {
5529 if (newChild.key === key) {
5530 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
5531 } else {
5532 return null;
5533 }
5534 }
5535 }
5536
5537 if (isArray(newChild) || getIteratorFn(newChild)) {
5538 if (key !== null) {
5539 return null;
5540 }
5541
5542 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
5543 }
5544
5545 throwOnInvalidObjectType(returnFiber, newChild);
5546 }
5547
5548 {
5549 if (typeof newChild === 'function') {
5550 warnOnFunctionType();
5551 }
5552 }
5553
5554 return null;
5555 }
5556
5557 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
5558 if (typeof newChild === 'string' || typeof newChild === 'number') {
5559 // Text nodes don't have keys, so we neither have to check the old nor
5560 // new node for the key. If both are text nodes, they match.
5561 var matchedFiber = existingChildren.get(newIdx) || null;
5562 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
5563 }
5564
5565 if (typeof newChild === 'object' && newChild !== null) {
5566 switch (newChild.$$typeof) {
5567 case REACT_ELEMENT_TYPE$1:
5568 {
5569 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5570
5571 if (newChild.type === REACT_FRAGMENT_TYPE) {
5572 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
5573 }
5574
5575 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
5576 }
5577
5578 case REACT_PORTAL_TYPE:
5579 {
5580 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5581
5582 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
5583 }
5584 }
5585
5586 if (isArray(newChild) || getIteratorFn(newChild)) {
5587 var _matchedFiber3 = existingChildren.get(newIdx) || null;
5588
5589 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
5590 }
5591
5592 throwOnInvalidObjectType(returnFiber, newChild);
5593 }
5594
5595 {
5596 if (typeof newChild === 'function') {
5597 warnOnFunctionType();
5598 }
5599 }
5600
5601 return null;
5602 }
5603 /**
5604 * Warns if there is a duplicate or missing key
5605 */
5606
5607
5608 function warnOnInvalidKey(child, knownKeys) {
5609 {
5610 if (typeof child !== 'object' || child === null) {
5611 return knownKeys;
5612 }
5613
5614 switch (child.$$typeof) {
5615 case REACT_ELEMENT_TYPE$1:
5616 case REACT_PORTAL_TYPE:
5617 warnForMissingKey(child);
5618 var key = child.key;
5619
5620 if (typeof key !== 'string') {
5621 break;
5622 }
5623
5624 if (knownKeys === null) {
5625 knownKeys = new Set();
5626 knownKeys.add(key);
5627 break;
5628 }
5629
5630 if (!knownKeys.has(key)) {
5631 knownKeys.add(key);
5632 break;
5633 }
5634
5635 warning$1(false, 'Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
5636 break;
5637
5638 default:
5639 break;
5640 }
5641 }
5642
5643 return knownKeys;
5644 }
5645
5646 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
5647 // This algorithm can't optimize by searching from both ends since we
5648 // don't have backpointers on fibers. I'm trying to see how far we can get
5649 // with that model. If it ends up not being worth the tradeoffs, we can
5650 // add it later.
5651 // Even with a two ended optimization, we'd want to optimize for the case
5652 // where there are few changes and brute force the comparison instead of
5653 // going for the Map. It'd like to explore hitting that path first in
5654 // forward-only mode and only go for the Map once we notice that we need
5655 // lots of look ahead. This doesn't handle reversal as well as two ended
5656 // search but that's unusual. Besides, for the two ended optimization to
5657 // work on Iterables, we'd need to copy the whole set.
5658 // In this first iteration, we'll just live with hitting the bad case
5659 // (adding everything to a Map) in for every insert/move.
5660 // If you change this code, also update reconcileChildrenIterator() which
5661 // uses the same algorithm.
5662 {
5663 // First, validate keys.
5664 var knownKeys = null;
5665
5666 for (var i = 0; i < newChildren.length; i++) {
5667 var child = newChildren[i];
5668 knownKeys = warnOnInvalidKey(child, knownKeys);
5669 }
5670 }
5671
5672 var resultingFirstChild = null;
5673 var previousNewFiber = null;
5674 var oldFiber = currentFirstChild;
5675 var lastPlacedIndex = 0;
5676 var newIdx = 0;
5677 var nextOldFiber = null;
5678
5679 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
5680 if (oldFiber.index > newIdx) {
5681 nextOldFiber = oldFiber;
5682 oldFiber = null;
5683 } else {
5684 nextOldFiber = oldFiber.sibling;
5685 }
5686
5687 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
5688
5689 if (newFiber === null) {
5690 // TODO: This breaks on empty slots like null children. That's
5691 // unfortunate because it triggers the slow path all the time. We need
5692 // a better way to communicate whether this was a miss or null,
5693 // boolean, undefined, etc.
5694 if (oldFiber === null) {
5695 oldFiber = nextOldFiber;
5696 }
5697
5698 break;
5699 }
5700
5701 if (shouldTrackSideEffects) {
5702 if (oldFiber && newFiber.alternate === null) {
5703 // We matched the slot, but we didn't reuse the existing fiber, so we
5704 // need to delete the existing child.
5705 deleteChild(returnFiber, oldFiber);
5706 }
5707 }
5708
5709 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5710
5711 if (previousNewFiber === null) {
5712 // TODO: Move out of the loop. This only happens for the first run.
5713 resultingFirstChild = newFiber;
5714 } else {
5715 // TODO: Defer siblings if we're not at the right index for this slot.
5716 // I.e. if we had null values before, then we want to defer this
5717 // for each null value. However, we also don't want to call updateSlot
5718 // with the previous one.
5719 previousNewFiber.sibling = newFiber;
5720 }
5721
5722 previousNewFiber = newFiber;
5723 oldFiber = nextOldFiber;
5724 }
5725
5726 if (newIdx === newChildren.length) {
5727 // We've reached the end of the new children. We can delete the rest.
5728 deleteRemainingChildren(returnFiber, oldFiber);
5729 return resultingFirstChild;
5730 }
5731
5732 if (oldFiber === null) {
5733 // If we don't have any more existing children we can choose a fast path
5734 // since the rest will all be insertions.
5735 for (; newIdx < newChildren.length; newIdx++) {
5736 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
5737
5738 if (_newFiber === null) {
5739 continue;
5740 }
5741
5742 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
5743
5744 if (previousNewFiber === null) {
5745 // TODO: Move out of the loop. This only happens for the first run.
5746 resultingFirstChild = _newFiber;
5747 } else {
5748 previousNewFiber.sibling = _newFiber;
5749 }
5750
5751 previousNewFiber = _newFiber;
5752 }
5753
5754 return resultingFirstChild;
5755 } // Add all children to a key map for quick lookups.
5756
5757
5758 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5759
5760 for (; newIdx < newChildren.length; newIdx++) {
5761 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
5762
5763 if (_newFiber2 !== null) {
5764 if (shouldTrackSideEffects) {
5765 if (_newFiber2.alternate !== null) {
5766 // The new fiber is a work in progress, but if there exists a
5767 // current, that means that we reused the fiber. We need to delete
5768 // it from the child list so that we don't add it to the deletion
5769 // list.
5770 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
5771 }
5772 }
5773
5774 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
5775
5776 if (previousNewFiber === null) {
5777 resultingFirstChild = _newFiber2;
5778 } else {
5779 previousNewFiber.sibling = _newFiber2;
5780 }
5781
5782 previousNewFiber = _newFiber2;
5783 }
5784 }
5785
5786 if (shouldTrackSideEffects) {
5787 // Any existing children that weren't consumed above were deleted. We need
5788 // to add them to the deletion list.
5789 existingChildren.forEach(function (child) {
5790 return deleteChild(returnFiber, child);
5791 });
5792 }
5793
5794 return resultingFirstChild;
5795 }
5796
5797 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
5798 // This is the same implementation as reconcileChildrenArray(),
5799 // but using the iterator instead.
5800 var iteratorFn = getIteratorFn(newChildrenIterable);
5801
5802 (function () {
5803 if (!(typeof iteratorFn === 'function')) {
5804 {
5805 throw ReactError(Error("An object is not an iterable. This error is likely caused by a bug in React. Please file an issue."));
5806 }
5807 }
5808 })();
5809
5810 {
5811 // We don't support rendering Generators because it's a mutation.
5812 // See https://github.com/facebook/react/issues/12995
5813 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
5814 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
5815 !didWarnAboutGenerators ? warning$1(false, 'Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.') : void 0;
5816 didWarnAboutGenerators = true;
5817 } // Warn about using Maps as children
5818
5819
5820 if (newChildrenIterable.entries === iteratorFn) {
5821 !didWarnAboutMaps ? warning$1(false, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.') : void 0;
5822 didWarnAboutMaps = true;
5823 } // First, validate keys.
5824 // We'll get a different iterator later for the main pass.
5825
5826
5827 var _newChildren = iteratorFn.call(newChildrenIterable);
5828
5829 if (_newChildren) {
5830 var knownKeys = null;
5831
5832 var _step = _newChildren.next();
5833
5834 for (; !_step.done; _step = _newChildren.next()) {
5835 var child = _step.value;
5836 knownKeys = warnOnInvalidKey(child, knownKeys);
5837 }
5838 }
5839 }
5840
5841 var newChildren = iteratorFn.call(newChildrenIterable);
5842
5843 (function () {
5844 if (!(newChildren != null)) {
5845 {
5846 throw ReactError(Error("An iterable object provided no iterator."));
5847 }
5848 }
5849 })();
5850
5851 var resultingFirstChild = null;
5852 var previousNewFiber = null;
5853 var oldFiber = currentFirstChild;
5854 var lastPlacedIndex = 0;
5855 var newIdx = 0;
5856 var nextOldFiber = null;
5857 var step = newChildren.next();
5858
5859 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
5860 if (oldFiber.index > newIdx) {
5861 nextOldFiber = oldFiber;
5862 oldFiber = null;
5863 } else {
5864 nextOldFiber = oldFiber.sibling;
5865 }
5866
5867 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
5868
5869 if (newFiber === null) {
5870 // TODO: This breaks on empty slots like null children. That's
5871 // unfortunate because it triggers the slow path all the time. We need
5872 // a better way to communicate whether this was a miss or null,
5873 // boolean, undefined, etc.
5874 if (oldFiber === null) {
5875 oldFiber = nextOldFiber;
5876 }
5877
5878 break;
5879 }
5880
5881 if (shouldTrackSideEffects) {
5882 if (oldFiber && newFiber.alternate === null) {
5883 // We matched the slot, but we didn't reuse the existing fiber, so we
5884 // need to delete the existing child.
5885 deleteChild(returnFiber, oldFiber);
5886 }
5887 }
5888
5889 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5890
5891 if (previousNewFiber === null) {
5892 // TODO: Move out of the loop. This only happens for the first run.
5893 resultingFirstChild = newFiber;
5894 } else {
5895 // TODO: Defer siblings if we're not at the right index for this slot.
5896 // I.e. if we had null values before, then we want to defer this
5897 // for each null value. However, we also don't want to call updateSlot
5898 // with the previous one.
5899 previousNewFiber.sibling = newFiber;
5900 }
5901
5902 previousNewFiber = newFiber;
5903 oldFiber = nextOldFiber;
5904 }
5905
5906 if (step.done) {
5907 // We've reached the end of the new children. We can delete the rest.
5908 deleteRemainingChildren(returnFiber, oldFiber);
5909 return resultingFirstChild;
5910 }
5911
5912 if (oldFiber === null) {
5913 // If we don't have any more existing children we can choose a fast path
5914 // since the rest will all be insertions.
5915 for (; !step.done; newIdx++, step = newChildren.next()) {
5916 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5917
5918 if (_newFiber3 === null) {
5919 continue;
5920 }
5921
5922 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5923
5924 if (previousNewFiber === null) {
5925 // TODO: Move out of the loop. This only happens for the first run.
5926 resultingFirstChild = _newFiber3;
5927 } else {
5928 previousNewFiber.sibling = _newFiber3;
5929 }
5930
5931 previousNewFiber = _newFiber3;
5932 }
5933
5934 return resultingFirstChild;
5935 } // Add all children to a key map for quick lookups.
5936
5937
5938 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5939
5940 for (; !step.done; newIdx++, step = newChildren.next()) {
5941 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5942
5943 if (_newFiber4 !== null) {
5944 if (shouldTrackSideEffects) {
5945 if (_newFiber4.alternate !== null) {
5946 // The new fiber is a work in progress, but if there exists a
5947 // current, that means that we reused the fiber. We need to delete
5948 // it from the child list so that we don't add it to the deletion
5949 // list.
5950 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5951 }
5952 }
5953
5954 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5955
5956 if (previousNewFiber === null) {
5957 resultingFirstChild = _newFiber4;
5958 } else {
5959 previousNewFiber.sibling = _newFiber4;
5960 }
5961
5962 previousNewFiber = _newFiber4;
5963 }
5964 }
5965
5966 if (shouldTrackSideEffects) {
5967 // Any existing children that weren't consumed above were deleted. We need
5968 // to add them to the deletion list.
5969 existingChildren.forEach(function (child) {
5970 return deleteChild(returnFiber, child);
5971 });
5972 }
5973
5974 return resultingFirstChild;
5975 }
5976
5977 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5978 // There's no need to check for keys on text nodes since we don't have a
5979 // way to define them.
5980 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5981 // We already have an existing node so let's just update it and delete
5982 // the rest.
5983 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5984 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5985 existing.return = returnFiber;
5986 return existing;
5987 } // The existing first child is not a text node so we need to create one
5988 // and delete the existing ones.
5989
5990
5991 deleteRemainingChildren(returnFiber, currentFirstChild);
5992 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5993 created.return = returnFiber;
5994 return created;
5995 }
5996
5997 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5998 var key = element.key;
5999 var child = currentFirstChild;
6000
6001 while (child !== null) {
6002 // TODO: If key === null and child.key === null, then this only applies to
6003 // the first item in the list.
6004 if (child.key === key) {
6005 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
6006 isCompatibleFamilyForHotReloading(child, element))) {
6007 deleteRemainingChildren(returnFiber, child.sibling);
6008 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
6009 existing.ref = coerceRef(returnFiber, child, element);
6010 existing.return = returnFiber;
6011
6012 {
6013 existing._debugSource = element._source;
6014 existing._debugOwner = element._owner;
6015 }
6016
6017 return existing;
6018 } else {
6019 deleteRemainingChildren(returnFiber, child);
6020 break;
6021 }
6022 } else {
6023 deleteChild(returnFiber, child);
6024 }
6025
6026 child = child.sibling;
6027 }
6028
6029 if (element.type === REACT_FRAGMENT_TYPE) {
6030 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
6031 created.return = returnFiber;
6032 return created;
6033 } else {
6034 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
6035
6036 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
6037 _created4.return = returnFiber;
6038 return _created4;
6039 }
6040 }
6041
6042 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
6043 var key = portal.key;
6044 var child = currentFirstChild;
6045
6046 while (child !== null) {
6047 // TODO: If key === null and child.key === null, then this only applies to
6048 // the first item in the list.
6049 if (child.key === key) {
6050 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
6051 deleteRemainingChildren(returnFiber, child.sibling);
6052 var existing = useFiber(child, portal.children || [], expirationTime);
6053 existing.return = returnFiber;
6054 return existing;
6055 } else {
6056 deleteRemainingChildren(returnFiber, child);
6057 break;
6058 }
6059 } else {
6060 deleteChild(returnFiber, child);
6061 }
6062
6063 child = child.sibling;
6064 }
6065
6066 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
6067 created.return = returnFiber;
6068 return created;
6069 } // This API will tag the children with the side-effect of the reconciliation
6070 // itself. They will be added to the side-effect list as we pass through the
6071 // children and the parent.
6072
6073
6074 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
6075 // This function is not recursive.
6076 // If the top level item is an array, we treat it as a set of children,
6077 // not as a fragment. Nested arrays on the other hand will be treated as
6078 // fragment nodes. Recursion happens at the normal flow.
6079 // Handle top level unkeyed fragments as if they were arrays.
6080 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
6081 // We treat the ambiguous cases above the same.
6082 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
6083
6084 if (isUnkeyedTopLevelFragment) {
6085 newChild = newChild.props.children;
6086 } // Handle object types
6087
6088
6089 var isObject = typeof newChild === 'object' && newChild !== null;
6090
6091 if (isObject) {
6092 switch (newChild.$$typeof) {
6093 case REACT_ELEMENT_TYPE$1:
6094 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
6095
6096 case REACT_PORTAL_TYPE:
6097 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
6098 }
6099 }
6100
6101 if (typeof newChild === 'string' || typeof newChild === 'number') {
6102 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
6103 }
6104
6105 if (isArray(newChild)) {
6106 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
6107 }
6108
6109 if (getIteratorFn(newChild)) {
6110 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
6111 }
6112
6113 if (isObject) {
6114 throwOnInvalidObjectType(returnFiber, newChild);
6115 }
6116
6117 {
6118 if (typeof newChild === 'function') {
6119 warnOnFunctionType();
6120 }
6121 }
6122
6123 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
6124 // If the new child is undefined, and the return fiber is a composite
6125 // component, throw an error. If Fiber return types are disabled,
6126 // we already threw above.
6127 switch (returnFiber.tag) {
6128 case ClassComponent:
6129 {
6130 {
6131 var instance = returnFiber.stateNode;
6132
6133 if (instance.render._isMockFunction) {
6134 // We allow auto-mocks to proceed as if they're returning null.
6135 break;
6136 }
6137 }
6138 }
6139 // Intentionally fall through to the next case, which handles both
6140 // functions and classes
6141 // eslint-disable-next-lined no-fallthrough
6142
6143 case FunctionComponent:
6144 {
6145 var Component = returnFiber.type;
6146
6147 (function () {
6148 {
6149 {
6150 throw ReactError(Error((Component.displayName || Component.name || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null."));
6151 }
6152 }
6153 })();
6154 }
6155 }
6156 } // Remaining cases are all treated as empty.
6157
6158
6159 return deleteRemainingChildren(returnFiber, currentFirstChild);
6160 }
6161
6162 return reconcileChildFibers;
6163}
6164
6165var reconcileChildFibers = ChildReconciler(true);
6166var mountChildFibers = ChildReconciler(false);
6167function cloneChildFibers(current, workInProgress) {
6168 (function () {
6169 if (!(current === null || workInProgress.child === current.child)) {
6170 {
6171 throw ReactError(Error("Resuming work not yet implemented."));
6172 }
6173 }
6174 })();
6175
6176 if (workInProgress.child === null) {
6177 return;
6178 }
6179
6180 var currentChild = workInProgress.child;
6181 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
6182 workInProgress.child = newChild;
6183 newChild.return = workInProgress;
6184
6185 while (currentChild.sibling !== null) {
6186 currentChild = currentChild.sibling;
6187 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
6188 newChild.return = workInProgress;
6189 }
6190
6191 newChild.sibling = null;
6192} // Reset a workInProgress child set to prepare it for a second pass.
6193
6194function resetChildFibers(workInProgress, renderExpirationTime) {
6195 var child = workInProgress.child;
6196
6197 while (child !== null) {
6198 resetWorkInProgress(child, renderExpirationTime);
6199 child = child.sibling;
6200 }
6201}
6202
6203var NO_CONTEXT$1 = {};
6204var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
6205var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
6206var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
6207
6208function requiredContext(c) {
6209 (function () {
6210 if (!(c !== NO_CONTEXT$1)) {
6211 {
6212 throw ReactError(Error("Expected host context to exist. This error is likely caused by a bug in React. Please file an issue."));
6213 }
6214 }
6215 })();
6216
6217 return c;
6218}
6219
6220function getRootHostContainer() {
6221 var rootInstance = requiredContext(rootInstanceStackCursor.current);
6222 return rootInstance;
6223}
6224
6225function pushHostContainer(fiber, nextRootInstance) {
6226 // Push current root instance onto the stack;
6227 // This allows us to reset root when portals are popped.
6228 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
6229 // This enables us to pop only Fibers that provide unique contexts.
6230
6231 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
6232 // However, we can't just call getRootHostContext() and push it because
6233 // we'd have a different number of entries on the stack depending on
6234 // whether getRootHostContext() throws somewhere in renderer code or not.
6235 // So we push an empty value first. This lets us safely unwind on errors.
6236
6237 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
6238 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
6239
6240 pop(contextStackCursor$1, fiber);
6241 push(contextStackCursor$1, nextRootContext, fiber);
6242}
6243
6244function popHostContainer(fiber) {
6245 pop(contextStackCursor$1, fiber);
6246 pop(contextFiberStackCursor, fiber);
6247 pop(rootInstanceStackCursor, fiber);
6248}
6249
6250function getHostContext() {
6251 var context = requiredContext(contextStackCursor$1.current);
6252 return context;
6253}
6254
6255function pushHostContext(fiber) {
6256 var rootInstance = requiredContext(rootInstanceStackCursor.current);
6257 var context = requiredContext(contextStackCursor$1.current);
6258 var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique.
6259
6260 if (context === nextContext) {
6261 return;
6262 } // Track the context and the Fiber that provided it.
6263 // This enables us to pop only Fibers that provide unique contexts.
6264
6265
6266 push(contextFiberStackCursor, fiber, fiber);
6267 push(contextStackCursor$1, nextContext, fiber);
6268}
6269
6270function popHostContext(fiber) {
6271 // Do not pop unless this Fiber provided the current context.
6272 // pushHostContext() only pushes Fibers that provide unique contexts.
6273 if (contextFiberStackCursor.current !== fiber) {
6274 return;
6275 }
6276
6277 pop(contextStackCursor$1, fiber);
6278 pop(contextFiberStackCursor, fiber);
6279}
6280
6281var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
6282// inherited deeply down the subtree. The upper bits only affect
6283// this immediate suspense boundary and gets reset each new
6284// boundary or suspense list.
6285
6286var SubtreeSuspenseContextMask = 1; // Subtree Flags:
6287// InvisibleParentSuspenseContext indicates that one of our parent Suspense
6288// boundaries is not currently showing visible main content.
6289// Either because it is already showing a fallback or is not mounted at all.
6290// We can use this to determine if it is desirable to trigger a fallback at
6291// the parent. If not, then we might need to trigger undesirable boundaries
6292// and/or suspend the commit to avoid hiding the parent content.
6293
6294var InvisibleParentSuspenseContext = 1; // Shallow Flags:
6295// ForceSuspenseFallback can be used by SuspenseList to force newly added
6296// items into their fallback state during one of the render passes.
6297
6298var ForceSuspenseFallback = 2;
6299var suspenseStackCursor = createCursor(DefaultSuspenseContext);
6300function hasSuspenseContext(parentContext, flag) {
6301 return (parentContext & flag) !== 0;
6302}
6303function setDefaultShallowSuspenseContext(parentContext) {
6304 return parentContext & SubtreeSuspenseContextMask;
6305}
6306function setShallowSuspenseContext(parentContext, shallowContext) {
6307 return parentContext & SubtreeSuspenseContextMask | shallowContext;
6308}
6309function addSubtreeSuspenseContext(parentContext, subtreeContext) {
6310 return parentContext | subtreeContext;
6311}
6312function pushSuspenseContext(fiber, newContext) {
6313 push(suspenseStackCursor, newContext, fiber);
6314}
6315function popSuspenseContext(fiber) {
6316 pop(suspenseStackCursor, fiber);
6317}
6318
6319function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
6320 // If it was the primary children that just suspended, capture and render the
6321 // fallback. Otherwise, don't capture and bubble to the next boundary.
6322 var nextState = workInProgress.memoizedState;
6323
6324 if (nextState !== null) {
6325 if (nextState.dehydrated !== null) {
6326 // A dehydrated boundary always captures.
6327 return true;
6328 }
6329
6330 return false;
6331 }
6332
6333 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
6334
6335 if (props.fallback === undefined) {
6336 return false;
6337 } // Regular boundaries always capture.
6338
6339
6340 if (props.unstable_avoidThisFallback !== true) {
6341 return true;
6342 } // If it's a boundary we should avoid, then we prefer to bubble up to the
6343 // parent boundary if it is currently invisible.
6344
6345
6346 if (hasInvisibleParent) {
6347 return false;
6348 } // If the parent is not able to handle it, we must handle it.
6349
6350
6351 return true;
6352}
6353function findFirstSuspended(row) {
6354 var node = row;
6355
6356 while (node !== null) {
6357 if (node.tag === SuspenseComponent) {
6358 var state = node.memoizedState;
6359
6360 if (state !== null) {
6361 var dehydrated = state.dehydrated;
6362
6363 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
6364 return node;
6365 }
6366 }
6367 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
6368 // keep track of whether it suspended or not.
6369 node.memoizedProps.revealOrder !== undefined) {
6370 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
6371
6372 if (didSuspend) {
6373 return node;
6374 }
6375 } else if (node.child !== null) {
6376 node.child.return = node;
6377 node = node.child;
6378 continue;
6379 }
6380
6381 if (node === row) {
6382 return null;
6383 }
6384
6385 while (node.sibling === null) {
6386 if (node.return === null || node.return === row) {
6387 return null;
6388 }
6389
6390 node = node.return;
6391 }
6392
6393 node.sibling.return = node.return;
6394 node = node.sibling;
6395 }
6396
6397 return null;
6398}
6399
6400var emptyObject = {};
6401var isArray$2 = Array.isArray;
6402function createResponderInstance(responder, responderProps, responderState, fiber) {
6403 return {
6404 fiber: fiber,
6405 props: responderProps,
6406 responder: responder,
6407 rootEventTypes: null,
6408 state: responderState
6409 };
6410}
6411
6412function mountEventResponder(responder, responderProps, fiber, respondersMap, rootContainerInstance) {
6413 var responderState = emptyObject;
6414 var getInitialState = responder.getInitialState;
6415
6416 if (getInitialState !== null) {
6417 responderState = getInitialState(responderProps);
6418 }
6419
6420 var responderInstance = createResponderInstance(responder, responderProps, responderState, fiber);
6421
6422 if (!rootContainerInstance) {
6423 var node = fiber;
6424
6425 while (node !== null) {
6426 var tag = node.tag;
6427
6428 if (tag === HostComponent) {
6429 rootContainerInstance = node.stateNode;
6430 break;
6431 } else if (tag === HostRoot) {
6432 rootContainerInstance = node.stateNode.containerInfo;
6433 break;
6434 }
6435
6436 node = node.return;
6437 }
6438 }
6439
6440 mountResponderInstance(responder, responderInstance, responderProps, responderState, rootContainerInstance);
6441 respondersMap.set(responder, responderInstance);
6442}
6443
6444function updateEventListener(listener, fiber, visistedResponders, respondersMap, rootContainerInstance) {
6445 var responder;
6446 var props;
6447
6448 if (listener) {
6449 responder = listener.responder;
6450 props = listener.props;
6451 }
6452
6453 (function () {
6454 if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) {
6455 {
6456 throw ReactError(Error("An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponder()."));
6457 }
6458 }
6459 })();
6460
6461 var listenerProps = props;
6462
6463 if (visistedResponders.has(responder)) {
6464 // show warning
6465 {
6466 warning$1(false, 'Duplicate event responder "%s" found in event listeners. ' + 'Event listeners passed to elements cannot use the same event responder more than once.', responder.displayName);
6467 }
6468
6469 return;
6470 }
6471
6472 visistedResponders.add(responder);
6473 var responderInstance = respondersMap.get(responder);
6474
6475 if (responderInstance === undefined) {
6476 // Mount (happens in either complete or commit phase)
6477 mountEventResponder(responder, listenerProps, fiber, respondersMap, rootContainerInstance);
6478 } else {
6479 // Update (happens during commit phase only)
6480 responderInstance.props = listenerProps;
6481 responderInstance.fiber = fiber;
6482 }
6483}
6484
6485function updateEventListeners(listeners, fiber, rootContainerInstance) {
6486 var visistedResponders = new Set();
6487 var dependencies = fiber.dependencies;
6488
6489 if (listeners != null) {
6490 if (dependencies === null) {
6491 dependencies = fiber.dependencies = {
6492 expirationTime: NoWork,
6493 firstContext: null,
6494 responders: new Map()
6495 };
6496 }
6497
6498 var respondersMap = dependencies.responders;
6499
6500 if (respondersMap === null) {
6501 respondersMap = new Map();
6502 }
6503
6504 if (isArray$2(listeners)) {
6505 for (var i = 0, length = listeners.length; i < length; i++) {
6506 var listener = listeners[i];
6507 updateEventListener(listener, fiber, visistedResponders, respondersMap, rootContainerInstance);
6508 }
6509 } else {
6510 updateEventListener(listeners, fiber, visistedResponders, respondersMap, rootContainerInstance);
6511 }
6512 }
6513
6514 if (dependencies !== null) {
6515 var _respondersMap = dependencies.responders;
6516
6517 if (_respondersMap !== null) {
6518 // Unmount
6519 var mountedResponders = Array.from(_respondersMap.keys());
6520
6521 for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) {
6522 var mountedResponder = mountedResponders[_i];
6523
6524 if (!visistedResponders.has(mountedResponder)) {
6525 var responderInstance = _respondersMap.get(mountedResponder);
6526
6527 unmountResponderInstance(responderInstance);
6528
6529 _respondersMap.delete(mountedResponder);
6530 }
6531 }
6532 }
6533 }
6534}
6535function createResponderListener(responder, props) {
6536 var eventResponderListener = {
6537 responder: responder,
6538 props: props
6539 };
6540
6541 {
6542 Object.freeze(eventResponderListener);
6543 }
6544
6545 return eventResponderListener;
6546}
6547
6548var NoEffect$1 =
6549/* */
65500;
6551var UnmountSnapshot =
6552/* */
65532;
6554var UnmountMutation =
6555/* */
65564;
6557var MountMutation =
6558/* */
65598;
6560var UnmountLayout =
6561/* */
656216;
6563var MountLayout =
6564/* */
656532;
6566var MountPassive =
6567/* */
656864;
6569var UnmountPassive =
6570/* */
6571128;
6572
6573var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
6574var didWarnAboutMismatchedHooksForComponent;
6575
6576{
6577 didWarnAboutMismatchedHooksForComponent = new Set();
6578}
6579
6580// These are set right before calling the component.
6581var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
6582// the work-in-progress hook.
6583
6584var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
6585// current hook list is the list that belongs to the current fiber. The
6586// work-in-progress hook list is a new list that will be added to the
6587// work-in-progress fiber.
6588
6589var currentHook = null;
6590var nextCurrentHook = null;
6591var firstWorkInProgressHook = null;
6592var workInProgressHook = null;
6593var nextWorkInProgressHook = null;
6594var remainingExpirationTime = NoWork;
6595var componentUpdateQueue = null;
6596var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the
6597// end of the current pass. We can't store these updates on the normal queue,
6598// because if the work is aborted, they should be discarded. Because this is
6599// a relatively rare case, we also don't want to add an additional field to
6600// either the hook or queue object types. So we store them in a lazily create
6601// map of queue -> render-phase updates, which are discarded once the component
6602// completes without re-rendering.
6603// Whether an update was scheduled during the currently executing render pass.
6604
6605var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates
6606
6607var renderPhaseUpdates = null; // Counter to prevent infinite loops.
6608
6609var numberOfReRenders = 0;
6610var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
6611
6612var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
6613// The list stores the order of hooks used during the initial render (mount).
6614// Subsequent renders (updates) reference this list.
6615
6616var hookTypesDev = null;
6617var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
6618// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
6619// When true, such Hooks will always be "remounted". Only used during hot reload.
6620
6621var ignorePreviousDependencies = false;
6622
6623function mountHookTypesDev() {
6624 {
6625 var hookName = currentHookNameInDev;
6626
6627 if (hookTypesDev === null) {
6628 hookTypesDev = [hookName];
6629 } else {
6630 hookTypesDev.push(hookName);
6631 }
6632 }
6633}
6634
6635function updateHookTypesDev() {
6636 {
6637 var hookName = currentHookNameInDev;
6638
6639 if (hookTypesDev !== null) {
6640 hookTypesUpdateIndexDev++;
6641
6642 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
6643 warnOnHookMismatchInDev(hookName);
6644 }
6645 }
6646 }
6647}
6648
6649function checkDepsAreArrayDev(deps) {
6650 {
6651 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
6652 // Verify deps, but only on mount to avoid extra checks.
6653 // It's unlikely their type would change as usually you define them inline.
6654 warning$1(false, '%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
6655 }
6656 }
6657}
6658
6659function warnOnHookMismatchInDev(currentHookName) {
6660 {
6661 var componentName = getComponentName(currentlyRenderingFiber$1.type);
6662
6663 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
6664 didWarnAboutMismatchedHooksForComponent.add(componentName);
6665
6666 if (hookTypesDev !== null) {
6667 var table = '';
6668 var secondColumnStart = 30;
6669
6670 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
6671 var oldHookName = hookTypesDev[i];
6672 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
6673 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
6674 // lol @ IE not supporting String#repeat
6675
6676 while (row.length < secondColumnStart) {
6677 row += ' ';
6678 }
6679
6680 row += newHookName + '\n';
6681 table += row;
6682 }
6683
6684 warning$1(false, 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
6685 }
6686 }
6687 }
6688}
6689
6690function throwInvalidHookError() {
6691 (function () {
6692 {
6693 {
6694 throw ReactError(Error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem."));
6695 }
6696 }
6697 })();
6698}
6699
6700function areHookInputsEqual(nextDeps, prevDeps) {
6701 {
6702 if (ignorePreviousDependencies) {
6703 // Only true when this component is being hot reloaded.
6704 return false;
6705 }
6706 }
6707
6708 if (prevDeps === null) {
6709 {
6710 warning$1(false, '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
6711 }
6712
6713 return false;
6714 }
6715
6716 {
6717 // Don't bother comparing lengths in prod because these arrays should be
6718 // passed inline.
6719 if (nextDeps.length !== prevDeps.length) {
6720 warning$1(false, 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
6721 }
6722 }
6723
6724 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
6725 if (is$1(nextDeps[i], prevDeps[i])) {
6726 continue;
6727 }
6728
6729 return false;
6730 }
6731
6732 return true;
6733}
6734
6735function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
6736 renderExpirationTime$1 = nextRenderExpirationTime;
6737 currentlyRenderingFiber$1 = workInProgress;
6738 nextCurrentHook = current !== null ? current.memoizedState : null;
6739
6740 {
6741 hookTypesDev = current !== null ? current._debugHookTypes : null;
6742 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
6743
6744 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
6745 } // The following should have already been reset
6746 // currentHook = null;
6747 // workInProgressHook = null;
6748 // remainingExpirationTime = NoWork;
6749 // componentUpdateQueue = null;
6750 // didScheduleRenderPhaseUpdate = false;
6751 // renderPhaseUpdates = null;
6752 // numberOfReRenders = 0;
6753 // sideEffectTag = 0;
6754 // TODO Warn if no hooks are used at all during mount, then some are used during update.
6755 // Currently we will identify the update render as a mount because nextCurrentHook === null.
6756 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
6757 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
6758 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
6759 // so nextCurrentHook would be null during updates and mounts.
6760
6761
6762 {
6763 if (nextCurrentHook !== null) {
6764 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
6765 } else if (hookTypesDev !== null) {
6766 // This dispatcher handles an edge case where a component is updating,
6767 // but no stateful hooks have been used.
6768 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
6769 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
6770 // This dispatcher does that.
6771 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
6772 } else {
6773 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
6774 }
6775 }
6776
6777 var children = Component(props, refOrContext);
6778
6779 if (didScheduleRenderPhaseUpdate) {
6780 do {
6781 didScheduleRenderPhaseUpdate = false;
6782 numberOfReRenders += 1;
6783
6784 {
6785 // Even when hot reloading, allow dependencies to stabilize
6786 // after first render to prevent infinite render phase updates.
6787 ignorePreviousDependencies = false;
6788 } // Start over from the beginning of the list
6789
6790
6791 nextCurrentHook = current !== null ? current.memoizedState : null;
6792 nextWorkInProgressHook = firstWorkInProgressHook;
6793 currentHook = null;
6794 workInProgressHook = null;
6795 componentUpdateQueue = null;
6796
6797 {
6798 // Also validate hook order for cascading updates.
6799 hookTypesUpdateIndexDev = -1;
6800 }
6801
6802 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
6803 children = Component(props, refOrContext);
6804 } while (didScheduleRenderPhaseUpdate);
6805
6806 renderPhaseUpdates = null;
6807 numberOfReRenders = 0;
6808 } // We can assume the previous dispatcher is always this one, since we set it
6809 // at the beginning of the render phase and there's no re-entrancy.
6810
6811
6812 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
6813 var renderedWork = currentlyRenderingFiber$1;
6814 renderedWork.memoizedState = firstWorkInProgressHook;
6815 renderedWork.expirationTime = remainingExpirationTime;
6816 renderedWork.updateQueue = componentUpdateQueue;
6817 renderedWork.effectTag |= sideEffectTag;
6818
6819 {
6820 renderedWork._debugHookTypes = hookTypesDev;
6821 } // This check uses currentHook so that it works the same in DEV and prod bundles.
6822 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
6823
6824
6825 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
6826 renderExpirationTime$1 = NoWork;
6827 currentlyRenderingFiber$1 = null;
6828 currentHook = null;
6829 nextCurrentHook = null;
6830 firstWorkInProgressHook = null;
6831 workInProgressHook = null;
6832 nextWorkInProgressHook = null;
6833
6834 {
6835 currentHookNameInDev = null;
6836 hookTypesDev = null;
6837 hookTypesUpdateIndexDev = -1;
6838 }
6839
6840 remainingExpirationTime = NoWork;
6841 componentUpdateQueue = null;
6842 sideEffectTag = 0; // These were reset above
6843 // didScheduleRenderPhaseUpdate = false;
6844 // renderPhaseUpdates = null;
6845 // numberOfReRenders = 0;
6846
6847 (function () {
6848 if (!!didRenderTooFewHooks) {
6849 {
6850 throw ReactError(Error("Rendered fewer hooks than expected. This may be caused by an accidental early return statement."));
6851 }
6852 }
6853 })();
6854
6855 return children;
6856}
6857function bailoutHooks(current, workInProgress, expirationTime) {
6858 workInProgress.updateQueue = current.updateQueue;
6859 workInProgress.effectTag &= ~(Passive | Update);
6860
6861 if (current.expirationTime <= expirationTime) {
6862 current.expirationTime = NoWork;
6863 }
6864}
6865function resetHooks() {
6866 // We can assume the previous dispatcher is always this one, since we set it
6867 // at the beginning of the render phase and there's no re-entrancy.
6868 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws.
6869 // It's also called inside mountIndeterminateComponent if we determine the
6870 // component is a module-style component.
6871
6872 renderExpirationTime$1 = NoWork;
6873 currentlyRenderingFiber$1 = null;
6874 currentHook = null;
6875 nextCurrentHook = null;
6876 firstWorkInProgressHook = null;
6877 workInProgressHook = null;
6878 nextWorkInProgressHook = null;
6879
6880 {
6881 hookTypesDev = null;
6882 hookTypesUpdateIndexDev = -1;
6883 currentHookNameInDev = null;
6884 }
6885
6886 remainingExpirationTime = NoWork;
6887 componentUpdateQueue = null;
6888 sideEffectTag = 0;
6889 didScheduleRenderPhaseUpdate = false;
6890 renderPhaseUpdates = null;
6891 numberOfReRenders = 0;
6892}
6893
6894function mountWorkInProgressHook() {
6895 var hook = {
6896 memoizedState: null,
6897 baseState: null,
6898 queue: null,
6899 baseUpdate: null,
6900 next: null
6901 };
6902
6903 if (workInProgressHook === null) {
6904 // This is the first hook in the list
6905 firstWorkInProgressHook = workInProgressHook = hook;
6906 } else {
6907 // Append to the end of the list
6908 workInProgressHook = workInProgressHook.next = hook;
6909 }
6910
6911 return workInProgressHook;
6912}
6913
6914function updateWorkInProgressHook() {
6915 // This function is used both for updates and for re-renders triggered by a
6916 // render phase update. It assumes there is either a current hook we can
6917 // clone, or a work-in-progress hook from a previous render pass that we can
6918 // use as a base. When we reach the end of the base list, we must switch to
6919 // the dispatcher used for mounts.
6920 if (nextWorkInProgressHook !== null) {
6921 // There's already a work-in-progress. Reuse it.
6922 workInProgressHook = nextWorkInProgressHook;
6923 nextWorkInProgressHook = workInProgressHook.next;
6924 currentHook = nextCurrentHook;
6925 nextCurrentHook = currentHook !== null ? currentHook.next : null;
6926 } else {
6927 // Clone from the current hook.
6928 (function () {
6929 if (!(nextCurrentHook !== null)) {
6930 {
6931 throw ReactError(Error("Rendered more hooks than during the previous render."));
6932 }
6933 }
6934 })();
6935
6936 currentHook = nextCurrentHook;
6937 var newHook = {
6938 memoizedState: currentHook.memoizedState,
6939 baseState: currentHook.baseState,
6940 queue: currentHook.queue,
6941 baseUpdate: currentHook.baseUpdate,
6942 next: null
6943 };
6944
6945 if (workInProgressHook === null) {
6946 // This is the first hook in the list.
6947 workInProgressHook = firstWorkInProgressHook = newHook;
6948 } else {
6949 // Append to the end of the list.
6950 workInProgressHook = workInProgressHook.next = newHook;
6951 }
6952
6953 nextCurrentHook = currentHook.next;
6954 }
6955
6956 return workInProgressHook;
6957}
6958
6959function createFunctionComponentUpdateQueue() {
6960 return {
6961 lastEffect: null
6962 };
6963}
6964
6965function basicStateReducer(state, action) {
6966 return typeof action === 'function' ? action(state) : action;
6967}
6968
6969function mountReducer(reducer, initialArg, init) {
6970 var hook = mountWorkInProgressHook();
6971 var initialState;
6972
6973 if (init !== undefined) {
6974 initialState = init(initialArg);
6975 } else {
6976 initialState = initialArg;
6977 }
6978
6979 hook.memoizedState = hook.baseState = initialState;
6980 var queue = hook.queue = {
6981 last: null,
6982 dispatch: null,
6983 lastRenderedReducer: reducer,
6984 lastRenderedState: initialState
6985 };
6986 var dispatch = queue.dispatch = dispatchAction.bind(null, // Flow doesn't know this is non-null, but we do.
6987 currentlyRenderingFiber$1, queue);
6988 return [hook.memoizedState, dispatch];
6989}
6990
6991function updateReducer(reducer, initialArg, init) {
6992 var hook = updateWorkInProgressHook();
6993 var queue = hook.queue;
6994
6995 (function () {
6996 if (!(queue !== null)) {
6997 {
6998 throw ReactError(Error("Should have a queue. This is likely a bug in React. Please file an issue."));
6999 }
7000 }
7001 })();
7002
7003 queue.lastRenderedReducer = reducer;
7004
7005 if (numberOfReRenders > 0) {
7006 // This is a re-render. Apply the new render phase updates to the previous
7007 // work-in-progress hook.
7008 var _dispatch = queue.dispatch;
7009
7010 if (renderPhaseUpdates !== null) {
7011 // Render phase updates are stored in a map of queue -> linked list
7012 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
7013
7014 if (firstRenderPhaseUpdate !== undefined) {
7015 renderPhaseUpdates.delete(queue);
7016 var newState = hook.memoizedState;
7017 var update = firstRenderPhaseUpdate;
7018
7019 do {
7020 // Process this render phase update. We don't have to check the
7021 // priority because it will always be the same as the current
7022 // render's.
7023 var action = update.action;
7024 newState = reducer(newState, action);
7025 update = update.next;
7026 } while (update !== null); // Mark that the fiber performed work, but only if the new state is
7027 // different from the current state.
7028
7029
7030 if (!is$1(newState, hook.memoizedState)) {
7031 markWorkInProgressReceivedUpdate();
7032 }
7033
7034 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
7035 // the base state unless the queue is empty.
7036 // TODO: Not sure if this is the desired semantics, but it's what we
7037 // do for gDSFP. I can't remember why.
7038
7039 if (hook.baseUpdate === queue.last) {
7040 hook.baseState = newState;
7041 }
7042
7043 queue.lastRenderedState = newState;
7044 return [newState, _dispatch];
7045 }
7046 }
7047
7048 return [hook.memoizedState, _dispatch];
7049 } // The last update in the entire queue
7050
7051
7052 var last = queue.last; // The last update that is part of the base state.
7053
7054 var baseUpdate = hook.baseUpdate;
7055 var baseState = hook.baseState; // Find the first unprocessed update.
7056
7057 var first;
7058
7059 if (baseUpdate !== null) {
7060 if (last !== null) {
7061 // For the first update, the queue is a circular linked list where
7062 // `queue.last.next = queue.first`. Once the first update commits, and
7063 // the `baseUpdate` is no longer empty, we can unravel the list.
7064 last.next = null;
7065 }
7066
7067 first = baseUpdate.next;
7068 } else {
7069 first = last !== null ? last.next : null;
7070 }
7071
7072 if (first !== null) {
7073 var _newState = baseState;
7074 var newBaseState = null;
7075 var newBaseUpdate = null;
7076 var prevUpdate = baseUpdate;
7077 var _update = first;
7078 var didSkip = false;
7079
7080 do {
7081 var updateExpirationTime = _update.expirationTime;
7082
7083 if (updateExpirationTime < renderExpirationTime$1) {
7084 // Priority is insufficient. Skip this update. If this is the first
7085 // skipped update, the previous update/state is the new base
7086 // update/state.
7087 if (!didSkip) {
7088 didSkip = true;
7089 newBaseUpdate = prevUpdate;
7090 newBaseState = _newState;
7091 } // Update the remaining priority in the queue.
7092
7093
7094 if (updateExpirationTime > remainingExpirationTime) {
7095 remainingExpirationTime = updateExpirationTime;
7096 markUnprocessedUpdateTime(remainingExpirationTime);
7097 }
7098 } else {
7099 // This update does have sufficient priority.
7100 // Mark the event time of this update as relevant to this render pass.
7101 // TODO: This should ideally use the true event time of this update rather than
7102 // its priority which is a derived and not reverseable value.
7103 // TODO: We should skip this update if it was already committed but currently
7104 // we have no way of detecting the difference between a committed and suspended
7105 // update here.
7106 markRenderEventTimeAndConfig(updateExpirationTime, _update.suspenseConfig); // Process this update.
7107
7108 if (_update.eagerReducer === reducer) {
7109 // If this update was processed eagerly, and its reducer matches the
7110 // current reducer, we can use the eagerly computed state.
7111 _newState = _update.eagerState;
7112 } else {
7113 var _action = _update.action;
7114 _newState = reducer(_newState, _action);
7115 }
7116 }
7117
7118 prevUpdate = _update;
7119 _update = _update.next;
7120 } while (_update !== null && _update !== first);
7121
7122 if (!didSkip) {
7123 newBaseUpdate = prevUpdate;
7124 newBaseState = _newState;
7125 } // Mark that the fiber performed work, but only if the new state is
7126 // different from the current state.
7127
7128
7129 if (!is$1(_newState, hook.memoizedState)) {
7130 markWorkInProgressReceivedUpdate();
7131 }
7132
7133 hook.memoizedState = _newState;
7134 hook.baseUpdate = newBaseUpdate;
7135 hook.baseState = newBaseState;
7136 queue.lastRenderedState = _newState;
7137 }
7138
7139 var dispatch = queue.dispatch;
7140 return [hook.memoizedState, dispatch];
7141}
7142
7143function mountState(initialState) {
7144 var hook = mountWorkInProgressHook();
7145
7146 if (typeof initialState === 'function') {
7147 initialState = initialState();
7148 }
7149
7150 hook.memoizedState = hook.baseState = initialState;
7151 var queue = hook.queue = {
7152 last: null,
7153 dispatch: null,
7154 lastRenderedReducer: basicStateReducer,
7155 lastRenderedState: initialState
7156 };
7157 var dispatch = queue.dispatch = dispatchAction.bind(null, // Flow doesn't know this is non-null, but we do.
7158 currentlyRenderingFiber$1, queue);
7159 return [hook.memoizedState, dispatch];
7160}
7161
7162function updateState(initialState) {
7163 return updateReducer(basicStateReducer, initialState);
7164}
7165
7166function pushEffect(tag, create, destroy, deps) {
7167 var effect = {
7168 tag: tag,
7169 create: create,
7170 destroy: destroy,
7171 deps: deps,
7172 // Circular
7173 next: null
7174 };
7175
7176 if (componentUpdateQueue === null) {
7177 componentUpdateQueue = createFunctionComponentUpdateQueue();
7178 componentUpdateQueue.lastEffect = effect.next = effect;
7179 } else {
7180 var lastEffect = componentUpdateQueue.lastEffect;
7181
7182 if (lastEffect === null) {
7183 componentUpdateQueue.lastEffect = effect.next = effect;
7184 } else {
7185 var firstEffect = lastEffect.next;
7186 lastEffect.next = effect;
7187 effect.next = firstEffect;
7188 componentUpdateQueue.lastEffect = effect;
7189 }
7190 }
7191
7192 return effect;
7193}
7194
7195function mountRef(initialValue) {
7196 var hook = mountWorkInProgressHook();
7197 var ref = {
7198 current: initialValue
7199 };
7200
7201 {
7202 Object.seal(ref);
7203 }
7204
7205 hook.memoizedState = ref;
7206 return ref;
7207}
7208
7209function updateRef(initialValue) {
7210 var hook = updateWorkInProgressHook();
7211 return hook.memoizedState;
7212}
7213
7214function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
7215 var hook = mountWorkInProgressHook();
7216 var nextDeps = deps === undefined ? null : deps;
7217 sideEffectTag |= fiberEffectTag;
7218 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
7219}
7220
7221function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
7222 var hook = updateWorkInProgressHook();
7223 var nextDeps = deps === undefined ? null : deps;
7224 var destroy = undefined;
7225
7226 if (currentHook !== null) {
7227 var prevEffect = currentHook.memoizedState;
7228 destroy = prevEffect.destroy;
7229
7230 if (nextDeps !== null) {
7231 var prevDeps = prevEffect.deps;
7232
7233 if (areHookInputsEqual(nextDeps, prevDeps)) {
7234 pushEffect(NoEffect$1, create, destroy, nextDeps);
7235 return;
7236 }
7237 }
7238 }
7239
7240 sideEffectTag |= fiberEffectTag;
7241 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
7242}
7243
7244function mountEffect(create, deps) {
7245 {
7246 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
7247 if ('undefined' !== typeof jest) {
7248 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
7249 }
7250 }
7251
7252 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
7253}
7254
7255function updateEffect(create, deps) {
7256 {
7257 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
7258 if ('undefined' !== typeof jest) {
7259 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
7260 }
7261 }
7262
7263 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
7264}
7265
7266function mountLayoutEffect(create, deps) {
7267 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
7268}
7269
7270function updateLayoutEffect(create, deps) {
7271 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
7272}
7273
7274function imperativeHandleEffect(create, ref) {
7275 if (typeof ref === 'function') {
7276 var refCallback = ref;
7277
7278 var _inst = create();
7279
7280 refCallback(_inst);
7281 return function () {
7282 refCallback(null);
7283 };
7284 } else if (ref !== null && ref !== undefined) {
7285 var refObject = ref;
7286
7287 {
7288 !refObject.hasOwnProperty('current') ? warning$1(false, 'Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}') : void 0;
7289 }
7290
7291 var _inst2 = create();
7292
7293 refObject.current = _inst2;
7294 return function () {
7295 refObject.current = null;
7296 };
7297 }
7298}
7299
7300function mountImperativeHandle(ref, create, deps) {
7301 {
7302 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
7303 } // TODO: If deps are provided, should we skip comparing the ref itself?
7304
7305
7306 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
7307 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
7308}
7309
7310function updateImperativeHandle(ref, create, deps) {
7311 {
7312 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
7313 } // TODO: If deps are provided, should we skip comparing the ref itself?
7314
7315
7316 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
7317 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
7318}
7319
7320function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
7321 // The react-debug-hooks package injects its own implementation
7322 // so that e.g. DevTools can display custom hook values.
7323}
7324
7325var updateDebugValue = mountDebugValue;
7326
7327function mountCallback(callback, deps) {
7328 var hook = mountWorkInProgressHook();
7329 var nextDeps = deps === undefined ? null : deps;
7330 hook.memoizedState = [callback, nextDeps];
7331 return callback;
7332}
7333
7334function updateCallback(callback, deps) {
7335 var hook = updateWorkInProgressHook();
7336 var nextDeps = deps === undefined ? null : deps;
7337 var prevState = hook.memoizedState;
7338
7339 if (prevState !== null) {
7340 if (nextDeps !== null) {
7341 var prevDeps = prevState[1];
7342
7343 if (areHookInputsEqual(nextDeps, prevDeps)) {
7344 return prevState[0];
7345 }
7346 }
7347 }
7348
7349 hook.memoizedState = [callback, nextDeps];
7350 return callback;
7351}
7352
7353function mountMemo(nextCreate, deps) {
7354 var hook = mountWorkInProgressHook();
7355 var nextDeps = deps === undefined ? null : deps;
7356 var nextValue = nextCreate();
7357 hook.memoizedState = [nextValue, nextDeps];
7358 return nextValue;
7359}
7360
7361function updateMemo(nextCreate, deps) {
7362 var hook = updateWorkInProgressHook();
7363 var nextDeps = deps === undefined ? null : deps;
7364 var prevState = hook.memoizedState;
7365
7366 if (prevState !== null) {
7367 // Assume these are defined. If they're not, areHookInputsEqual will warn.
7368 if (nextDeps !== null) {
7369 var prevDeps = prevState[1];
7370
7371 if (areHookInputsEqual(nextDeps, prevDeps)) {
7372 return prevState[0];
7373 }
7374 }
7375 }
7376
7377 var nextValue = nextCreate();
7378 hook.memoizedState = [nextValue, nextDeps];
7379 return nextValue;
7380}
7381
7382function dispatchAction(fiber, queue, action) {
7383 (function () {
7384 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
7385 {
7386 throw ReactError(Error("Too many re-renders. React limits the number of renders to prevent an infinite loop."));
7387 }
7388 }
7389 })();
7390
7391 {
7392 !(typeof arguments[3] !== 'function') ? warning$1(false, "State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().') : void 0;
7393 }
7394
7395 var alternate = fiber.alternate;
7396
7397 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
7398 // This is a render phase update. Stash it in a lazily-created map of
7399 // queue -> linked list of updates. After this render pass, we'll restart
7400 // and apply the stashed updates on top of the work-in-progress hook.
7401 didScheduleRenderPhaseUpdate = true;
7402 var update = {
7403 expirationTime: renderExpirationTime$1,
7404 suspenseConfig: null,
7405 action: action,
7406 eagerReducer: null,
7407 eagerState: null,
7408 next: null
7409 };
7410
7411 {
7412 update.priority = getCurrentPriorityLevel();
7413 }
7414
7415 if (renderPhaseUpdates === null) {
7416 renderPhaseUpdates = new Map();
7417 }
7418
7419 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
7420
7421 if (firstRenderPhaseUpdate === undefined) {
7422 renderPhaseUpdates.set(queue, update);
7423 } else {
7424 // Append the update to the end of the list.
7425 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
7426
7427 while (lastRenderPhaseUpdate.next !== null) {
7428 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
7429 }
7430
7431 lastRenderPhaseUpdate.next = update;
7432 }
7433 } else {
7434 var currentTime = requestCurrentTime();
7435 var suspenseConfig = requestCurrentSuspenseConfig();
7436 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
7437 var _update2 = {
7438 expirationTime: expirationTime,
7439 suspenseConfig: suspenseConfig,
7440 action: action,
7441 eagerReducer: null,
7442 eagerState: null,
7443 next: null
7444 };
7445
7446 {
7447 _update2.priority = getCurrentPriorityLevel();
7448 } // Append the update to the end of the list.
7449
7450
7451 var last = queue.last;
7452
7453 if (last === null) {
7454 // This is the first update. Create a circular list.
7455 _update2.next = _update2;
7456 } else {
7457 var first = last.next;
7458
7459 if (first !== null) {
7460 // Still circular.
7461 _update2.next = first;
7462 }
7463
7464 last.next = _update2;
7465 }
7466
7467 queue.last = _update2;
7468
7469 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
7470 // The queue is currently empty, which means we can eagerly compute the
7471 // next state before entering the render phase. If the new state is the
7472 // same as the current state, we may be able to bail out entirely.
7473 var lastRenderedReducer = queue.lastRenderedReducer;
7474
7475 if (lastRenderedReducer !== null) {
7476 var prevDispatcher;
7477
7478 {
7479 prevDispatcher = ReactCurrentDispatcher$1.current;
7480 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7481 }
7482
7483 try {
7484 var currentState = queue.lastRenderedState;
7485 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
7486 // it, on the update object. If the reducer hasn't changed by the
7487 // time we enter the render phase, then the eager state can be used
7488 // without calling the reducer again.
7489
7490 _update2.eagerReducer = lastRenderedReducer;
7491 _update2.eagerState = eagerState;
7492
7493 if (is$1(eagerState, currentState)) {
7494 // Fast path. We can bail out without scheduling React to re-render.
7495 // It's still possible that we'll need to rebase this update later,
7496 // if the component re-renders for a different reason and by that
7497 // time the reducer has changed.
7498 return;
7499 }
7500 } catch (error) {// Suppress the error. It will throw again in the render phase.
7501 } finally {
7502 {
7503 ReactCurrentDispatcher$1.current = prevDispatcher;
7504 }
7505 }
7506 }
7507 }
7508
7509 {
7510 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
7511 if ('undefined' !== typeof jest) {
7512 warnIfNotScopedWithMatchingAct(fiber);
7513 warnIfNotCurrentlyActingUpdatesInDev(fiber);
7514 }
7515 }
7516
7517 scheduleWork(fiber, expirationTime);
7518 }
7519}
7520
7521var ContextOnlyDispatcher = {
7522 readContext: readContext,
7523 useCallback: throwInvalidHookError,
7524 useContext: throwInvalidHookError,
7525 useEffect: throwInvalidHookError,
7526 useImperativeHandle: throwInvalidHookError,
7527 useLayoutEffect: throwInvalidHookError,
7528 useMemo: throwInvalidHookError,
7529 useReducer: throwInvalidHookError,
7530 useRef: throwInvalidHookError,
7531 useState: throwInvalidHookError,
7532 useDebugValue: throwInvalidHookError,
7533 useResponder: throwInvalidHookError
7534};
7535var HooksDispatcherOnMountInDEV = null;
7536var HooksDispatcherOnMountWithHookTypesInDEV = null;
7537var HooksDispatcherOnUpdateInDEV = null;
7538var InvalidNestedHooksDispatcherOnMountInDEV = null;
7539var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
7540
7541{
7542 var warnInvalidContextAccess = function () {
7543 warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
7544 };
7545
7546 var warnInvalidHookAccess = function () {
7547 warning$1(false, 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');
7548 };
7549
7550 HooksDispatcherOnMountInDEV = {
7551 readContext: function (context, observedBits) {
7552 return readContext(context, observedBits);
7553 },
7554 useCallback: function (callback, deps) {
7555 currentHookNameInDev = 'useCallback';
7556 mountHookTypesDev();
7557 checkDepsAreArrayDev(deps);
7558 return mountCallback(callback, deps);
7559 },
7560 useContext: function (context, observedBits) {
7561 currentHookNameInDev = 'useContext';
7562 mountHookTypesDev();
7563 return readContext(context, observedBits);
7564 },
7565 useEffect: function (create, deps) {
7566 currentHookNameInDev = 'useEffect';
7567 mountHookTypesDev();
7568 checkDepsAreArrayDev(deps);
7569 return mountEffect(create, deps);
7570 },
7571 useImperativeHandle: function (ref, create, deps) {
7572 currentHookNameInDev = 'useImperativeHandle';
7573 mountHookTypesDev();
7574 checkDepsAreArrayDev(deps);
7575 return mountImperativeHandle(ref, create, deps);
7576 },
7577 useLayoutEffect: function (create, deps) {
7578 currentHookNameInDev = 'useLayoutEffect';
7579 mountHookTypesDev();
7580 checkDepsAreArrayDev(deps);
7581 return mountLayoutEffect(create, deps);
7582 },
7583 useMemo: function (create, deps) {
7584 currentHookNameInDev = 'useMemo';
7585 mountHookTypesDev();
7586 checkDepsAreArrayDev(deps);
7587 var prevDispatcher = ReactCurrentDispatcher$1.current;
7588 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7589
7590 try {
7591 return mountMemo(create, deps);
7592 } finally {
7593 ReactCurrentDispatcher$1.current = prevDispatcher;
7594 }
7595 },
7596 useReducer: function (reducer, initialArg, init) {
7597 currentHookNameInDev = 'useReducer';
7598 mountHookTypesDev();
7599 var prevDispatcher = ReactCurrentDispatcher$1.current;
7600 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7601
7602 try {
7603 return mountReducer(reducer, initialArg, init);
7604 } finally {
7605 ReactCurrentDispatcher$1.current = prevDispatcher;
7606 }
7607 },
7608 useRef: function (initialValue) {
7609 currentHookNameInDev = 'useRef';
7610 mountHookTypesDev();
7611 return mountRef(initialValue);
7612 },
7613 useState: function (initialState) {
7614 currentHookNameInDev = 'useState';
7615 mountHookTypesDev();
7616 var prevDispatcher = ReactCurrentDispatcher$1.current;
7617 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7618
7619 try {
7620 return mountState(initialState);
7621 } finally {
7622 ReactCurrentDispatcher$1.current = prevDispatcher;
7623 }
7624 },
7625 useDebugValue: function (value, formatterFn) {
7626 currentHookNameInDev = 'useDebugValue';
7627 mountHookTypesDev();
7628 return mountDebugValue(value, formatterFn);
7629 },
7630 useResponder: function (responder, props) {
7631 currentHookNameInDev = 'useResponder';
7632 mountHookTypesDev();
7633 return createResponderListener(responder, props);
7634 }
7635 };
7636 HooksDispatcherOnMountWithHookTypesInDEV = {
7637 readContext: function (context, observedBits) {
7638 return readContext(context, observedBits);
7639 },
7640 useCallback: function (callback, deps) {
7641 currentHookNameInDev = 'useCallback';
7642 updateHookTypesDev();
7643 return mountCallback(callback, deps);
7644 },
7645 useContext: function (context, observedBits) {
7646 currentHookNameInDev = 'useContext';
7647 updateHookTypesDev();
7648 return readContext(context, observedBits);
7649 },
7650 useEffect: function (create, deps) {
7651 currentHookNameInDev = 'useEffect';
7652 updateHookTypesDev();
7653 return mountEffect(create, deps);
7654 },
7655 useImperativeHandle: function (ref, create, deps) {
7656 currentHookNameInDev = 'useImperativeHandle';
7657 updateHookTypesDev();
7658 return mountImperativeHandle(ref, create, deps);
7659 },
7660 useLayoutEffect: function (create, deps) {
7661 currentHookNameInDev = 'useLayoutEffect';
7662 updateHookTypesDev();
7663 return mountLayoutEffect(create, deps);
7664 },
7665 useMemo: function (create, deps) {
7666 currentHookNameInDev = 'useMemo';
7667 updateHookTypesDev();
7668 var prevDispatcher = ReactCurrentDispatcher$1.current;
7669 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7670
7671 try {
7672 return mountMemo(create, deps);
7673 } finally {
7674 ReactCurrentDispatcher$1.current = prevDispatcher;
7675 }
7676 },
7677 useReducer: function (reducer, initialArg, init) {
7678 currentHookNameInDev = 'useReducer';
7679 updateHookTypesDev();
7680 var prevDispatcher = ReactCurrentDispatcher$1.current;
7681 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7682
7683 try {
7684 return mountReducer(reducer, initialArg, init);
7685 } finally {
7686 ReactCurrentDispatcher$1.current = prevDispatcher;
7687 }
7688 },
7689 useRef: function (initialValue) {
7690 currentHookNameInDev = 'useRef';
7691 updateHookTypesDev();
7692 return mountRef(initialValue);
7693 },
7694 useState: function (initialState) {
7695 currentHookNameInDev = 'useState';
7696 updateHookTypesDev();
7697 var prevDispatcher = ReactCurrentDispatcher$1.current;
7698 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7699
7700 try {
7701 return mountState(initialState);
7702 } finally {
7703 ReactCurrentDispatcher$1.current = prevDispatcher;
7704 }
7705 },
7706 useDebugValue: function (value, formatterFn) {
7707 currentHookNameInDev = 'useDebugValue';
7708 updateHookTypesDev();
7709 return mountDebugValue(value, formatterFn);
7710 },
7711 useResponder: function (responder, props) {
7712 currentHookNameInDev = 'useResponder';
7713 updateHookTypesDev();
7714 return createResponderListener(responder, props);
7715 }
7716 };
7717 HooksDispatcherOnUpdateInDEV = {
7718 readContext: function (context, observedBits) {
7719 return readContext(context, observedBits);
7720 },
7721 useCallback: function (callback, deps) {
7722 currentHookNameInDev = 'useCallback';
7723 updateHookTypesDev();
7724 return updateCallback(callback, deps);
7725 },
7726 useContext: function (context, observedBits) {
7727 currentHookNameInDev = 'useContext';
7728 updateHookTypesDev();
7729 return readContext(context, observedBits);
7730 },
7731 useEffect: function (create, deps) {
7732 currentHookNameInDev = 'useEffect';
7733 updateHookTypesDev();
7734 return updateEffect(create, deps);
7735 },
7736 useImperativeHandle: function (ref, create, deps) {
7737 currentHookNameInDev = 'useImperativeHandle';
7738 updateHookTypesDev();
7739 return updateImperativeHandle(ref, create, deps);
7740 },
7741 useLayoutEffect: function (create, deps) {
7742 currentHookNameInDev = 'useLayoutEffect';
7743 updateHookTypesDev();
7744 return updateLayoutEffect(create, deps);
7745 },
7746 useMemo: function (create, deps) {
7747 currentHookNameInDev = 'useMemo';
7748 updateHookTypesDev();
7749 var prevDispatcher = ReactCurrentDispatcher$1.current;
7750 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7751
7752 try {
7753 return updateMemo(create, deps);
7754 } finally {
7755 ReactCurrentDispatcher$1.current = prevDispatcher;
7756 }
7757 },
7758 useReducer: function (reducer, initialArg, init) {
7759 currentHookNameInDev = 'useReducer';
7760 updateHookTypesDev();
7761 var prevDispatcher = ReactCurrentDispatcher$1.current;
7762 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7763
7764 try {
7765 return updateReducer(reducer, initialArg, init);
7766 } finally {
7767 ReactCurrentDispatcher$1.current = prevDispatcher;
7768 }
7769 },
7770 useRef: function (initialValue) {
7771 currentHookNameInDev = 'useRef';
7772 updateHookTypesDev();
7773 return updateRef(initialValue);
7774 },
7775 useState: function (initialState) {
7776 currentHookNameInDev = 'useState';
7777 updateHookTypesDev();
7778 var prevDispatcher = ReactCurrentDispatcher$1.current;
7779 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7780
7781 try {
7782 return updateState(initialState);
7783 } finally {
7784 ReactCurrentDispatcher$1.current = prevDispatcher;
7785 }
7786 },
7787 useDebugValue: function (value, formatterFn) {
7788 currentHookNameInDev = 'useDebugValue';
7789 updateHookTypesDev();
7790 return updateDebugValue(value, formatterFn);
7791 },
7792 useResponder: function (responder, props) {
7793 currentHookNameInDev = 'useResponder';
7794 updateHookTypesDev();
7795 return createResponderListener(responder, props);
7796 }
7797 };
7798 InvalidNestedHooksDispatcherOnMountInDEV = {
7799 readContext: function (context, observedBits) {
7800 warnInvalidContextAccess();
7801 return readContext(context, observedBits);
7802 },
7803 useCallback: function (callback, deps) {
7804 currentHookNameInDev = 'useCallback';
7805 warnInvalidHookAccess();
7806 mountHookTypesDev();
7807 return mountCallback(callback, deps);
7808 },
7809 useContext: function (context, observedBits) {
7810 currentHookNameInDev = 'useContext';
7811 warnInvalidHookAccess();
7812 mountHookTypesDev();
7813 return readContext(context, observedBits);
7814 },
7815 useEffect: function (create, deps) {
7816 currentHookNameInDev = 'useEffect';
7817 warnInvalidHookAccess();
7818 mountHookTypesDev();
7819 return mountEffect(create, deps);
7820 },
7821 useImperativeHandle: function (ref, create, deps) {
7822 currentHookNameInDev = 'useImperativeHandle';
7823 warnInvalidHookAccess();
7824 mountHookTypesDev();
7825 return mountImperativeHandle(ref, create, deps);
7826 },
7827 useLayoutEffect: function (create, deps) {
7828 currentHookNameInDev = 'useLayoutEffect';
7829 warnInvalidHookAccess();
7830 mountHookTypesDev();
7831 return mountLayoutEffect(create, deps);
7832 },
7833 useMemo: function (create, deps) {
7834 currentHookNameInDev = 'useMemo';
7835 warnInvalidHookAccess();
7836 mountHookTypesDev();
7837 var prevDispatcher = ReactCurrentDispatcher$1.current;
7838 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7839
7840 try {
7841 return mountMemo(create, deps);
7842 } finally {
7843 ReactCurrentDispatcher$1.current = prevDispatcher;
7844 }
7845 },
7846 useReducer: function (reducer, initialArg, init) {
7847 currentHookNameInDev = 'useReducer';
7848 warnInvalidHookAccess();
7849 mountHookTypesDev();
7850 var prevDispatcher = ReactCurrentDispatcher$1.current;
7851 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7852
7853 try {
7854 return mountReducer(reducer, initialArg, init);
7855 } finally {
7856 ReactCurrentDispatcher$1.current = prevDispatcher;
7857 }
7858 },
7859 useRef: function (initialValue) {
7860 currentHookNameInDev = 'useRef';
7861 warnInvalidHookAccess();
7862 mountHookTypesDev();
7863 return mountRef(initialValue);
7864 },
7865 useState: function (initialState) {
7866 currentHookNameInDev = 'useState';
7867 warnInvalidHookAccess();
7868 mountHookTypesDev();
7869 var prevDispatcher = ReactCurrentDispatcher$1.current;
7870 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7871
7872 try {
7873 return mountState(initialState);
7874 } finally {
7875 ReactCurrentDispatcher$1.current = prevDispatcher;
7876 }
7877 },
7878 useDebugValue: function (value, formatterFn) {
7879 currentHookNameInDev = 'useDebugValue';
7880 warnInvalidHookAccess();
7881 mountHookTypesDev();
7882 return mountDebugValue(value, formatterFn);
7883 },
7884 useResponder: function (responder, props) {
7885 currentHookNameInDev = 'useResponder';
7886 warnInvalidHookAccess();
7887 mountHookTypesDev();
7888 return createResponderListener(responder, props);
7889 }
7890 };
7891 InvalidNestedHooksDispatcherOnUpdateInDEV = {
7892 readContext: function (context, observedBits) {
7893 warnInvalidContextAccess();
7894 return readContext(context, observedBits);
7895 },
7896 useCallback: function (callback, deps) {
7897 currentHookNameInDev = 'useCallback';
7898 warnInvalidHookAccess();
7899 updateHookTypesDev();
7900 return updateCallback(callback, deps);
7901 },
7902 useContext: function (context, observedBits) {
7903 currentHookNameInDev = 'useContext';
7904 warnInvalidHookAccess();
7905 updateHookTypesDev();
7906 return readContext(context, observedBits);
7907 },
7908 useEffect: function (create, deps) {
7909 currentHookNameInDev = 'useEffect';
7910 warnInvalidHookAccess();
7911 updateHookTypesDev();
7912 return updateEffect(create, deps);
7913 },
7914 useImperativeHandle: function (ref, create, deps) {
7915 currentHookNameInDev = 'useImperativeHandle';
7916 warnInvalidHookAccess();
7917 updateHookTypesDev();
7918 return updateImperativeHandle(ref, create, deps);
7919 },
7920 useLayoutEffect: function (create, deps) {
7921 currentHookNameInDev = 'useLayoutEffect';
7922 warnInvalidHookAccess();
7923 updateHookTypesDev();
7924 return updateLayoutEffect(create, deps);
7925 },
7926 useMemo: function (create, deps) {
7927 currentHookNameInDev = 'useMemo';
7928 warnInvalidHookAccess();
7929 updateHookTypesDev();
7930 var prevDispatcher = ReactCurrentDispatcher$1.current;
7931 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7932
7933 try {
7934 return updateMemo(create, deps);
7935 } finally {
7936 ReactCurrentDispatcher$1.current = prevDispatcher;
7937 }
7938 },
7939 useReducer: function (reducer, initialArg, init) {
7940 currentHookNameInDev = 'useReducer';
7941 warnInvalidHookAccess();
7942 updateHookTypesDev();
7943 var prevDispatcher = ReactCurrentDispatcher$1.current;
7944 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7945
7946 try {
7947 return updateReducer(reducer, initialArg, init);
7948 } finally {
7949 ReactCurrentDispatcher$1.current = prevDispatcher;
7950 }
7951 },
7952 useRef: function (initialValue) {
7953 currentHookNameInDev = 'useRef';
7954 warnInvalidHookAccess();
7955 updateHookTypesDev();
7956 return updateRef(initialValue);
7957 },
7958 useState: function (initialState) {
7959 currentHookNameInDev = 'useState';
7960 warnInvalidHookAccess();
7961 updateHookTypesDev();
7962 var prevDispatcher = ReactCurrentDispatcher$1.current;
7963 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7964
7965 try {
7966 return updateState(initialState);
7967 } finally {
7968 ReactCurrentDispatcher$1.current = prevDispatcher;
7969 }
7970 },
7971 useDebugValue: function (value, formatterFn) {
7972 currentHookNameInDev = 'useDebugValue';
7973 warnInvalidHookAccess();
7974 updateHookTypesDev();
7975 return updateDebugValue(value, formatterFn);
7976 },
7977 useResponder: function (responder, props) {
7978 currentHookNameInDev = 'useResponder';
7979 warnInvalidHookAccess();
7980 updateHookTypesDev();
7981 return createResponderListener(responder, props);
7982 }
7983 };
7984}
7985
7986// CommonJS interop named imports.
7987
7988var now$1 = unstable_now;
7989var commitTime = 0;
7990var profilerStartTime = -1;
7991
7992function getCommitTime() {
7993 return commitTime;
7994}
7995
7996function recordCommitTime() {
7997 if (!enableProfilerTimer) {
7998 return;
7999 }
8000
8001 commitTime = now$1();
8002}
8003
8004function startProfilerTimer(fiber) {
8005 if (!enableProfilerTimer) {
8006 return;
8007 }
8008
8009 profilerStartTime = now$1();
8010
8011 if (fiber.actualStartTime < 0) {
8012 fiber.actualStartTime = now$1();
8013 }
8014}
8015
8016function stopProfilerTimerIfRunning(fiber) {
8017 if (!enableProfilerTimer) {
8018 return;
8019 }
8020
8021 profilerStartTime = -1;
8022}
8023
8024function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
8025 if (!enableProfilerTimer) {
8026 return;
8027 }
8028
8029 if (profilerStartTime >= 0) {
8030 var elapsedTime = now$1() - profilerStartTime;
8031 fiber.actualDuration += elapsedTime;
8032
8033 if (overrideBaseTime) {
8034 fiber.selfBaseDuration = elapsedTime;
8035 }
8036
8037 profilerStartTime = -1;
8038 }
8039}
8040
8041// This may have been an insertion or a hydration.
8042
8043var hydrationParentFiber = null;
8044var nextHydratableInstance = null;
8045var isHydrating = false;
8046
8047function warnIfHydrating() {
8048 {
8049 !!isHydrating ? warning$1(false, 'We should not be hydrating here. This is a bug in React. Please file a bug.') : void 0;
8050 }
8051}
8052
8053function enterHydrationState(fiber) {
8054 if (!supportsHydration) {
8055 return false;
8056 }
8057
8058 var parentInstance = fiber.stateNode.containerInfo;
8059 nextHydratableInstance = getFirstHydratableChild(parentInstance);
8060 hydrationParentFiber = fiber;
8061 isHydrating = true;
8062 return true;
8063}
8064
8065function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance) {
8066 if (!supportsHydration) {
8067 return false;
8068 }
8069
8070 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
8071 popToNextHostParent(fiber);
8072 isHydrating = true;
8073 return true;
8074}
8075
8076function deleteHydratableInstance(returnFiber, instance) {
8077 {
8078 switch (returnFiber.tag) {
8079 case HostRoot:
8080 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
8081 break;
8082
8083 case HostComponent:
8084 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
8085 break;
8086 }
8087 }
8088
8089 var childToDelete = createFiberFromHostInstanceForDeletion();
8090 childToDelete.stateNode = instance;
8091 childToDelete.return = returnFiber;
8092 childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,
8093 // these children are not part of the reconciliation list of children.
8094 // Even if we abort and rereconcile the children, that will try to hydrate
8095 // again and the nodes are still in the host tree so these will be
8096 // recreated.
8097
8098 if (returnFiber.lastEffect !== null) {
8099 returnFiber.lastEffect.nextEffect = childToDelete;
8100 returnFiber.lastEffect = childToDelete;
8101 } else {
8102 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
8103 }
8104}
8105
8106function insertNonHydratedInstance(returnFiber, fiber) {
8107 fiber.effectTag = fiber.effectTag & ~Hydrating | Placement;
8108
8109 {
8110 switch (returnFiber.tag) {
8111 case HostRoot:
8112 {
8113 var parentContainer = returnFiber.stateNode.containerInfo;
8114
8115 switch (fiber.tag) {
8116 case HostComponent:
8117 var type = fiber.type;
8118 var props = fiber.pendingProps;
8119 didNotFindHydratableContainerInstance(parentContainer, type, props);
8120 break;
8121
8122 case HostText:
8123 var text = fiber.pendingProps;
8124 didNotFindHydratableContainerTextInstance(parentContainer, text);
8125 break;
8126
8127 case SuspenseComponent:
8128 didNotFindHydratableContainerSuspenseInstance(parentContainer);
8129 break;
8130 }
8131
8132 break;
8133 }
8134
8135 case HostComponent:
8136 {
8137 var parentType = returnFiber.type;
8138 var parentProps = returnFiber.memoizedProps;
8139 var parentInstance = returnFiber.stateNode;
8140
8141 switch (fiber.tag) {
8142 case HostComponent:
8143 var _type = fiber.type;
8144 var _props = fiber.pendingProps;
8145 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
8146 break;
8147
8148 case HostText:
8149 var _text = fiber.pendingProps;
8150 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
8151 break;
8152
8153 case SuspenseComponent:
8154 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
8155 break;
8156 }
8157
8158 break;
8159 }
8160
8161 default:
8162 return;
8163 }
8164 }
8165}
8166
8167function tryHydrate(fiber, nextInstance) {
8168 switch (fiber.tag) {
8169 case HostComponent:
8170 {
8171 var type = fiber.type;
8172 var props = fiber.pendingProps;
8173 var instance = canHydrateInstance(nextInstance, type, props);
8174
8175 if (instance !== null) {
8176 fiber.stateNode = instance;
8177 return true;
8178 }
8179
8180 return false;
8181 }
8182
8183 case HostText:
8184 {
8185 var text = fiber.pendingProps;
8186 var textInstance = canHydrateTextInstance(nextInstance, text);
8187
8188 if (textInstance !== null) {
8189 fiber.stateNode = textInstance;
8190 return true;
8191 }
8192
8193 return false;
8194 }
8195
8196 case SuspenseComponent:
8197 {
8198 if (enableSuspenseServerRenderer) {
8199 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
8200
8201 if (suspenseInstance !== null) {
8202 var suspenseState = {
8203 dehydrated: suspenseInstance,
8204 retryTime: Never
8205 };
8206 fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber.
8207 // This simplifies the code for getHostSibling and deleting nodes,
8208 // since it doesn't have to consider all Suspense boundaries and
8209 // check if they're dehydrated ones or not.
8210
8211 var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance);
8212 dehydratedFragment.return = fiber;
8213 fiber.child = dehydratedFragment;
8214 return true;
8215 }
8216 }
8217
8218 return false;
8219 }
8220
8221 default:
8222 return false;
8223 }
8224}
8225
8226function tryToClaimNextHydratableInstance(fiber) {
8227 if (!isHydrating) {
8228 return;
8229 }
8230
8231 var nextInstance = nextHydratableInstance;
8232
8233 if (!nextInstance) {
8234 // Nothing to hydrate. Make it an insertion.
8235 insertNonHydratedInstance(hydrationParentFiber, fiber);
8236 isHydrating = false;
8237 hydrationParentFiber = fiber;
8238 return;
8239 }
8240
8241 var firstAttemptedInstance = nextInstance;
8242
8243 if (!tryHydrate(fiber, nextInstance)) {
8244 // If we can't hydrate this instance let's try the next one.
8245 // We use this as a heuristic. It's based on intuition and not data so it
8246 // might be flawed or unnecessary.
8247 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
8248
8249 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
8250 // Nothing to hydrate. Make it an insertion.
8251 insertNonHydratedInstance(hydrationParentFiber, fiber);
8252 isHydrating = false;
8253 hydrationParentFiber = fiber;
8254 return;
8255 } // We matched the next one, we'll now assume that the first one was
8256 // superfluous and we'll delete it. Since we can't eagerly delete it
8257 // we'll have to schedule a deletion. To do that, this node needs a dummy
8258 // fiber associated with it.
8259
8260
8261 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
8262 }
8263
8264 hydrationParentFiber = fiber;
8265 nextHydratableInstance = getFirstHydratableChild(nextInstance);
8266}
8267
8268function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
8269 if (!supportsHydration) {
8270 (function () {
8271 {
8272 {
8273 throw ReactError(Error("Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."));
8274 }
8275 }
8276 })();
8277 }
8278
8279 var instance = fiber.stateNode;
8280 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component.
8281
8282 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
8283 // is a new ref we mark this as an update.
8284
8285 if (updatePayload !== null) {
8286 return true;
8287 }
8288
8289 return false;
8290}
8291
8292function prepareToHydrateHostTextInstance(fiber) {
8293 if (!supportsHydration) {
8294 (function () {
8295 {
8296 {
8297 throw ReactError(Error("Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."));
8298 }
8299 }
8300 })();
8301 }
8302
8303 var textInstance = fiber.stateNode;
8304 var textContent = fiber.memoizedProps;
8305 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
8306
8307 {
8308 if (shouldUpdate) {
8309 // We assume that prepareToHydrateHostTextInstance is called in a context where the
8310 // hydration parent is the parent host component of this host text.
8311 var returnFiber = hydrationParentFiber;
8312
8313 if (returnFiber !== null) {
8314 switch (returnFiber.tag) {
8315 case HostRoot:
8316 {
8317 var parentContainer = returnFiber.stateNode.containerInfo;
8318 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
8319 break;
8320 }
8321
8322 case HostComponent:
8323 {
8324 var parentType = returnFiber.type;
8325 var parentProps = returnFiber.memoizedProps;
8326 var parentInstance = returnFiber.stateNode;
8327 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
8328 break;
8329 }
8330 }
8331 }
8332 }
8333 }
8334
8335 return shouldUpdate;
8336}
8337
8338function prepareToHydrateHostSuspenseInstance(fiber) {
8339 if (!supportsHydration) {
8340 (function () {
8341 {
8342 {
8343 throw ReactError(Error("Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."));
8344 }
8345 }
8346 })();
8347 }
8348
8349 var suspenseState = fiber.memoizedState;
8350 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
8351
8352 (function () {
8353 if (!suspenseInstance) {
8354 {
8355 throw ReactError(Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue."));
8356 }
8357 }
8358 })();
8359
8360 hydrateSuspenseInstance(suspenseInstance, fiber);
8361}
8362
8363function skipPastDehydratedSuspenseInstance(fiber) {
8364 if (!supportsHydration) {
8365 (function () {
8366 {
8367 {
8368 throw ReactError(Error("Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."));
8369 }
8370 }
8371 })();
8372 }
8373
8374 var suspenseState = fiber.memoizedState;
8375 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
8376
8377 (function () {
8378 if (!suspenseInstance) {
8379 {
8380 throw ReactError(Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue."));
8381 }
8382 }
8383 })();
8384
8385 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
8386}
8387
8388function popToNextHostParent(fiber) {
8389 var parent = fiber.return;
8390
8391 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
8392 parent = parent.return;
8393 }
8394
8395 hydrationParentFiber = parent;
8396}
8397
8398function popHydrationState(fiber) {
8399 if (!supportsHydration) {
8400 return false;
8401 }
8402
8403 if (fiber !== hydrationParentFiber) {
8404 // We're deeper than the current hydration context, inside an inserted
8405 // tree.
8406 return false;
8407 }
8408
8409 if (!isHydrating) {
8410 // If we're not currently hydrating but we're in a hydration context, then
8411 // we were an insertion and now need to pop up reenter hydration of our
8412 // siblings.
8413 popToNextHostParent(fiber);
8414 isHydrating = true;
8415 return false;
8416 }
8417
8418 var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now.
8419 // We only do this deeper than head and body since they tend to have random
8420 // other nodes in them. We also ignore components with pure text content in
8421 // side of them.
8422 // TODO: Better heuristic.
8423
8424 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
8425 var nextInstance = nextHydratableInstance;
8426
8427 while (nextInstance) {
8428 deleteHydratableInstance(fiber, nextInstance);
8429 nextInstance = getNextHydratableSibling(nextInstance);
8430 }
8431 }
8432
8433 popToNextHostParent(fiber);
8434
8435 if (fiber.tag === SuspenseComponent) {
8436 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
8437 } else {
8438 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
8439 }
8440
8441 return true;
8442}
8443
8444function resetHydrationState() {
8445 if (!supportsHydration) {
8446 return;
8447 }
8448
8449 hydrationParentFiber = null;
8450 nextHydratableInstance = null;
8451 isHydrating = false;
8452}
8453
8454var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
8455var didReceiveUpdate = false;
8456var didWarnAboutBadClass;
8457var didWarnAboutModulePatternComponent;
8458var didWarnAboutContextTypeOnFunctionComponent;
8459var didWarnAboutGetDerivedStateOnFunctionComponent;
8460var didWarnAboutFunctionRefs;
8461var didWarnAboutReassigningProps;
8462var didWarnAboutMaxDuration;
8463var didWarnAboutRevealOrder;
8464var didWarnAboutTailOptions;
8465var didWarnAboutDefaultPropsOnFunctionComponent;
8466
8467{
8468 didWarnAboutBadClass = {};
8469 didWarnAboutModulePatternComponent = {};
8470 didWarnAboutContextTypeOnFunctionComponent = {};
8471 didWarnAboutGetDerivedStateOnFunctionComponent = {};
8472 didWarnAboutFunctionRefs = {};
8473 didWarnAboutReassigningProps = false;
8474 didWarnAboutMaxDuration = false;
8475 didWarnAboutRevealOrder = {};
8476 didWarnAboutTailOptions = {};
8477 didWarnAboutDefaultPropsOnFunctionComponent = {};
8478}
8479
8480function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
8481 if (current === null) {
8482 // If this is a fresh new component that hasn't been rendered yet, we
8483 // won't update its child set by applying minimal side-effects. Instead,
8484 // we will add them all to the child before it gets rendered. That means
8485 // we can optimize this reconciliation pass by not tracking side-effects.
8486 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8487 } else {
8488 // If the current child is the same as the work in progress, it means that
8489 // we haven't yet started any work on these children. Therefore, we use
8490 // the clone algorithm to create a copy of all the current children.
8491 // If we had any progressed work already, that is invalid at this point so
8492 // let's throw it out.
8493 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
8494 }
8495}
8496
8497function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
8498 // This function is fork of reconcileChildren. It's used in cases where we
8499 // want to reconcile without matching against the existing set. This has the
8500 // effect of all current children being unmounted; even if the type and key
8501 // are the same, the old child is unmounted and a new child is created.
8502 //
8503 // To do this, we're going to go through the reconcile algorithm twice. In
8504 // the first pass, we schedule a deletion for all the current children by
8505 // passing null.
8506 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
8507 // pass null in place of where we usually pass the current child set. This has
8508 // the effect of remounting all children regardless of whether their their
8509 // identity matches.
8510
8511 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8512}
8513
8514function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
8515 // TODO: current can be non-null here even if the component
8516 // hasn't yet mounted. This happens after the first render suspends.
8517 // We'll need to figure out if this is fine or can cause issues.
8518 {
8519 if (workInProgress.type !== workInProgress.elementType) {
8520 // Lazy component props can't be validated in createElement
8521 // because they're only guaranteed to be resolved here.
8522 var innerPropTypes = Component.propTypes;
8523
8524 if (innerPropTypes) {
8525 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8526 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8527 }
8528 }
8529 }
8530
8531 var render = Component.render;
8532 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
8533
8534 var nextChildren;
8535 prepareToReadContext(workInProgress, renderExpirationTime);
8536
8537 {
8538 ReactCurrentOwner$2.current = workInProgress;
8539 setCurrentPhase('render');
8540 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
8541
8542 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8543 // Only double-render components with Hooks
8544 if (workInProgress.memoizedState !== null) {
8545 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
8546 }
8547 }
8548
8549 setCurrentPhase(null);
8550 }
8551
8552 if (current !== null && !didReceiveUpdate) {
8553 bailoutHooks(current, workInProgress, renderExpirationTime);
8554 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8555 } // React DevTools reads this flag.
8556
8557
8558 workInProgress.effectTag |= PerformedWork;
8559 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8560 return workInProgress.child;
8561}
8562
8563function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
8564 if (current === null) {
8565 var type = Component.type;
8566
8567 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
8568 Component.defaultProps === undefined) {
8569 var resolvedType = type;
8570
8571 {
8572 resolvedType = resolveFunctionForHotReloading(type);
8573 } // If this is a plain function component without default props,
8574 // and with only the default shallow comparison, we upgrade it
8575 // to a SimpleMemoComponent to allow fast path updates.
8576
8577
8578 workInProgress.tag = SimpleMemoComponent;
8579 workInProgress.type = resolvedType;
8580
8581 {
8582 validateFunctionComponentInDev(workInProgress, type);
8583 }
8584
8585 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
8586 }
8587
8588 {
8589 var innerPropTypes = type.propTypes;
8590
8591 if (innerPropTypes) {
8592 // Inner memo component props aren't currently validated in createElement.
8593 // We could move it there, but we'd still need this for lazy code path.
8594 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8595 'prop', getComponentName(type), getCurrentFiberStackInDev);
8596 }
8597 }
8598
8599 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
8600 child.ref = workInProgress.ref;
8601 child.return = workInProgress;
8602 workInProgress.child = child;
8603 return child;
8604 }
8605
8606 {
8607 var _type = Component.type;
8608 var _innerPropTypes = _type.propTypes;
8609
8610 if (_innerPropTypes) {
8611 // Inner memo component props aren't currently validated in createElement.
8612 // We could move it there, but we'd still need this for lazy code path.
8613 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
8614 'prop', getComponentName(_type), getCurrentFiberStackInDev);
8615 }
8616 }
8617
8618 var currentChild = current.child; // This is always exactly one child
8619
8620 if (updateExpirationTime < renderExpirationTime) {
8621 // This will be the props with resolved defaultProps,
8622 // unlike current.memoizedProps which will be the unresolved ones.
8623 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
8624
8625 var compare = Component.compare;
8626 compare = compare !== null ? compare : shallowEqual;
8627
8628 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
8629 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8630 }
8631 } // React DevTools reads this flag.
8632
8633
8634 workInProgress.effectTag |= PerformedWork;
8635 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
8636 newChild.ref = workInProgress.ref;
8637 newChild.return = workInProgress;
8638 workInProgress.child = newChild;
8639 return newChild;
8640}
8641
8642function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
8643 // TODO: current can be non-null here even if the component
8644 // hasn't yet mounted. This happens when the inner render suspends.
8645 // We'll need to figure out if this is fine or can cause issues.
8646 {
8647 if (workInProgress.type !== workInProgress.elementType) {
8648 // Lazy component props can't be validated in createElement
8649 // because they're only guaranteed to be resolved here.
8650 var outerMemoType = workInProgress.elementType;
8651
8652 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
8653 // We warn when you define propTypes on lazy()
8654 // so let's just skip over it to find memo() outer wrapper.
8655 // Inner props for memo are validated later.
8656 outerMemoType = refineResolvedLazyComponent(outerMemoType);
8657 }
8658
8659 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
8660
8661 if (outerPropTypes) {
8662 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
8663 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
8664 } // Inner propTypes will be validated in the function component path.
8665
8666 }
8667 }
8668
8669 if (current !== null) {
8670 var prevProps = current.memoizedProps;
8671
8672 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload:
8673 workInProgress.type === current.type)) {
8674 didReceiveUpdate = false;
8675
8676 if (updateExpirationTime < renderExpirationTime) {
8677 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8678 }
8679 }
8680 }
8681
8682 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
8683}
8684
8685function updateFragment(current, workInProgress, renderExpirationTime) {
8686 var nextChildren = workInProgress.pendingProps;
8687 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8688 return workInProgress.child;
8689}
8690
8691function updateMode(current, workInProgress, renderExpirationTime) {
8692 var nextChildren = workInProgress.pendingProps.children;
8693 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8694 return workInProgress.child;
8695}
8696
8697function updateProfiler(current, workInProgress, renderExpirationTime) {
8698 if (enableProfilerTimer) {
8699 workInProgress.effectTag |= Update;
8700 }
8701
8702 var nextProps = workInProgress.pendingProps;
8703 var nextChildren = nextProps.children;
8704 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8705 return workInProgress.child;
8706}
8707
8708function markRef(current, workInProgress) {
8709 var ref = workInProgress.ref;
8710
8711 if (current === null && ref !== null || current !== null && current.ref !== ref) {
8712 // Schedule a Ref effect
8713 workInProgress.effectTag |= Ref;
8714 }
8715}
8716
8717function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8718 {
8719 if (workInProgress.type !== workInProgress.elementType) {
8720 // Lazy component props can't be validated in createElement
8721 // because they're only guaranteed to be resolved here.
8722 var innerPropTypes = Component.propTypes;
8723
8724 if (innerPropTypes) {
8725 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8726 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8727 }
8728 }
8729 }
8730
8731 var context;
8732
8733 if (!disableLegacyContext) {
8734 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
8735 context = getMaskedContext(workInProgress, unmaskedContext);
8736 }
8737
8738 var nextChildren;
8739 prepareToReadContext(workInProgress, renderExpirationTime);
8740
8741 {
8742 ReactCurrentOwner$2.current = workInProgress;
8743 setCurrentPhase('render');
8744 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8745
8746 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8747 // Only double-render components with Hooks
8748 if (workInProgress.memoizedState !== null) {
8749 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8750 }
8751 }
8752
8753 setCurrentPhase(null);
8754 }
8755
8756 if (current !== null && !didReceiveUpdate) {
8757 bailoutHooks(current, workInProgress, renderExpirationTime);
8758 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8759 } // React DevTools reads this flag.
8760
8761
8762 workInProgress.effectTag |= PerformedWork;
8763 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8764 return workInProgress.child;
8765}
8766
8767function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8768 {
8769 if (workInProgress.type !== workInProgress.elementType) {
8770 // Lazy component props can't be validated in createElement
8771 // because they're only guaranteed to be resolved here.
8772 var innerPropTypes = Component.propTypes;
8773
8774 if (innerPropTypes) {
8775 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8776 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8777 }
8778 }
8779 } // Push context providers early to prevent context stack mismatches.
8780 // During mounting we don't know the child context yet as the instance doesn't exist.
8781 // We will invalidate the child context in finishClassComponent() right after rendering.
8782
8783
8784 var hasContext;
8785
8786 if (isContextProvider(Component)) {
8787 hasContext = true;
8788 pushContextProvider(workInProgress);
8789 } else {
8790 hasContext = false;
8791 }
8792
8793 prepareToReadContext(workInProgress, renderExpirationTime);
8794 var instance = workInProgress.stateNode;
8795 var shouldUpdate;
8796
8797 if (instance === null) {
8798 if (current !== null) {
8799 // An class component without an instance only mounts if it suspended
8800 // inside a non- concurrent tree, in an inconsistent state. We want to
8801 // tree it like a new mount, even though an empty version of it already
8802 // committed. Disconnect the alternate pointers.
8803 current.alternate = null;
8804 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8805
8806 workInProgress.effectTag |= Placement;
8807 } // In the initial pass we might need to construct the instance.
8808
8809
8810 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8811 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8812 shouldUpdate = true;
8813 } else if (current === null) {
8814 // In a resume, we'll already have an instance we can reuse.
8815 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8816 } else {
8817 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
8818 }
8819
8820 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
8821
8822 {
8823 var inst = workInProgress.stateNode;
8824
8825 if (inst.props !== nextProps) {
8826 !didWarnAboutReassigningProps ? warning$1(false, 'It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component') : void 0;
8827 didWarnAboutReassigningProps = true;
8828 }
8829 }
8830
8831 return nextUnitOfWork;
8832}
8833
8834function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
8835 // Refs should update even if shouldComponentUpdate returns false
8836 markRef(current, workInProgress);
8837 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
8838
8839 if (!shouldUpdate && !didCaptureError) {
8840 // Context providers should defer to sCU for rendering
8841 if (hasContext) {
8842 invalidateContextProvider(workInProgress, Component, false);
8843 }
8844
8845 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8846 }
8847
8848 var instance = workInProgress.stateNode; // Rerender
8849
8850 ReactCurrentOwner$2.current = workInProgress;
8851 var nextChildren;
8852
8853 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
8854 // If we captured an error, but getDerivedStateFrom catch is not defined,
8855 // unmount all the children. componentDidCatch will schedule an update to
8856 // re-render a fallback. This is temporary until we migrate everyone to
8857 // the new API.
8858 // TODO: Warn in a future release.
8859 nextChildren = null;
8860
8861 if (enableProfilerTimer) {
8862 stopProfilerTimerIfRunning(workInProgress);
8863 }
8864 } else {
8865 {
8866 setCurrentPhase('render');
8867 nextChildren = instance.render();
8868
8869 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8870 instance.render();
8871 }
8872
8873 setCurrentPhase(null);
8874 }
8875 } // React DevTools reads this flag.
8876
8877
8878 workInProgress.effectTag |= PerformedWork;
8879
8880 if (current !== null && didCaptureError) {
8881 // If we're recovering from an error, reconcile without reusing any of
8882 // the existing children. Conceptually, the normal children and the children
8883 // that are shown on error are two different sets, so we shouldn't reuse
8884 // normal children even if their identities match.
8885 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
8886 } else {
8887 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8888 } // Memoize state using the values we just used to render.
8889 // TODO: Restructure so we never read values from the instance.
8890
8891
8892 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
8893
8894 if (hasContext) {
8895 invalidateContextProvider(workInProgress, Component, true);
8896 }
8897
8898 return workInProgress.child;
8899}
8900
8901function pushHostRootContext(workInProgress) {
8902 var root = workInProgress.stateNode;
8903
8904 if (root.pendingContext) {
8905 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
8906 } else if (root.context) {
8907 // Should always be set
8908 pushTopLevelContextObject(workInProgress, root.context, false);
8909 }
8910
8911 pushHostContainer(workInProgress, root.containerInfo);
8912}
8913
8914function updateHostRoot(current, workInProgress, renderExpirationTime) {
8915 pushHostRootContext(workInProgress);
8916 var updateQueue = workInProgress.updateQueue;
8917
8918 (function () {
8919 if (!(updateQueue !== null)) {
8920 {
8921 throw ReactError(Error("If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue."));
8922 }
8923 }
8924 })();
8925
8926 var nextProps = workInProgress.pendingProps;
8927 var prevState = workInProgress.memoizedState;
8928 var prevChildren = prevState !== null ? prevState.element : null;
8929 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
8930 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
8931 // being called "element".
8932
8933 var nextChildren = nextState.element;
8934
8935 if (nextChildren === prevChildren) {
8936 // If the state is the same as before, that's a bailout because we had
8937 // no work that expires at this time.
8938 resetHydrationState();
8939 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8940 }
8941
8942 var root = workInProgress.stateNode;
8943
8944 if (root.hydrate && enterHydrationState(workInProgress)) {
8945 // If we don't have any current children this might be the first pass.
8946 // We always try to hydrate. If this isn't a hydration pass there won't
8947 // be any children to hydrate which is effectively the same thing as
8948 // not hydrating.
8949 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8950 workInProgress.child = child;
8951 var node = child;
8952
8953 while (node) {
8954 // Mark each child as hydrating. This is a fast path to know whether this
8955 // tree is part of a hydrating tree. This is used to determine if a child
8956 // node has fully mounted yet, and for scheduling event replaying.
8957 // Conceptually this is similar to Placement in that a new subtree is
8958 // inserted into the React tree here. It just happens to not need DOM
8959 // mutations because it already exists.
8960 node.effectTag = node.effectTag & ~Placement | Hydrating;
8961 node = node.sibling;
8962 }
8963 } else {
8964 // Otherwise reset hydration state in case we aborted and resumed another
8965 // root.
8966 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8967 resetHydrationState();
8968 }
8969
8970 return workInProgress.child;
8971}
8972
8973function updateHostComponent(current, workInProgress, renderExpirationTime) {
8974 pushHostContext(workInProgress);
8975
8976 if (current === null) {
8977 tryToClaimNextHydratableInstance(workInProgress);
8978 }
8979
8980 var type = workInProgress.type;
8981 var nextProps = workInProgress.pendingProps;
8982 var prevProps = current !== null ? current.memoizedProps : null;
8983 var nextChildren = nextProps.children;
8984 var isDirectTextChild = shouldSetTextContent(type, nextProps);
8985
8986 if (isDirectTextChild) {
8987 // We special case a direct text child of a host node. This is a common
8988 // case. We won't handle it as a reified child. We will instead handle
8989 // this in the host environment that also have access to this prop. That
8990 // avoids allocating another HostText fiber and traversing it.
8991 nextChildren = null;
8992 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
8993 // If we're switching from a direct text child to a normal child, or to
8994 // empty, we need to schedule the text content to be reset.
8995 workInProgress.effectTag |= ContentReset;
8996 }
8997
8998 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
8999
9000 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
9001 if (enableSchedulerTracing) {
9002 markSpawnedWork(Never);
9003 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
9004
9005
9006 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
9007 return null;
9008 }
9009
9010 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
9011 return workInProgress.child;
9012}
9013
9014function updateHostText(current, workInProgress) {
9015 if (current === null) {
9016 tryToClaimNextHydratableInstance(workInProgress);
9017 } // Nothing to do here. This is terminal. We'll do the completion step
9018 // immediately after.
9019
9020
9021 return null;
9022}
9023
9024function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
9025 if (_current !== null) {
9026 // An lazy component only mounts if it suspended inside a non-
9027 // concurrent tree, in an inconsistent state. We want to treat it like
9028 // a new mount, even though an empty version of it already committed.
9029 // Disconnect the alternate pointers.
9030 _current.alternate = null;
9031 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
9032
9033 workInProgress.effectTag |= Placement;
9034 }
9035
9036 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
9037 // Cancel and resume right after we know the tag.
9038
9039 cancelWorkTimer(workInProgress);
9040 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
9041
9042 workInProgress.type = Component;
9043 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
9044 startWorkTimer(workInProgress);
9045 var resolvedProps = resolveDefaultProps(Component, props);
9046 var child;
9047
9048 switch (resolvedTag) {
9049 case FunctionComponent:
9050 {
9051 {
9052 validateFunctionComponentInDev(workInProgress, Component);
9053 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
9054 }
9055
9056 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
9057 break;
9058 }
9059
9060 case ClassComponent:
9061 {
9062 {
9063 workInProgress.type = Component = resolveClassForHotReloading(Component);
9064 }
9065
9066 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
9067 break;
9068 }
9069
9070 case ForwardRef:
9071 {
9072 {
9073 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
9074 }
9075
9076 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
9077 break;
9078 }
9079
9080 case MemoComponent:
9081 {
9082 {
9083 if (workInProgress.type !== workInProgress.elementType) {
9084 var outerPropTypes = Component.propTypes;
9085
9086 if (outerPropTypes) {
9087 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
9088 'prop', getComponentName(Component), getCurrentFiberStackInDev);
9089 }
9090 }
9091 }
9092
9093 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
9094 updateExpirationTime, renderExpirationTime);
9095 break;
9096 }
9097
9098 default:
9099 {
9100 var hint = '';
9101
9102 {
9103 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
9104 hint = ' Did you wrap a component in React.lazy() more than once?';
9105 }
9106 } // This message intentionally doesn't mention ForwardRef or MemoComponent
9107 // because the fact that it's a separate type of work is an
9108 // implementation detail.
9109
9110
9111 (function () {
9112 {
9113 {
9114 throw ReactError(Error("Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint));
9115 }
9116 }
9117 })();
9118 }
9119 }
9120
9121 return child;
9122}
9123
9124function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
9125 if (_current !== null) {
9126 // An incomplete component only mounts if it suspended inside a non-
9127 // concurrent tree, in an inconsistent state. We want to treat it like
9128 // a new mount, even though an empty version of it already committed.
9129 // Disconnect the alternate pointers.
9130 _current.alternate = null;
9131 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
9132
9133 workInProgress.effectTag |= Placement;
9134 } // Promote the fiber to a class and try rendering again.
9135
9136
9137 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
9138 // Push context providers early to prevent context stack mismatches.
9139 // During mounting we don't know the child context yet as the instance doesn't exist.
9140 // We will invalidate the child context in finishClassComponent() right after rendering.
9141
9142 var hasContext;
9143
9144 if (isContextProvider(Component)) {
9145 hasContext = true;
9146 pushContextProvider(workInProgress);
9147 } else {
9148 hasContext = false;
9149 }
9150
9151 prepareToReadContext(workInProgress, renderExpirationTime);
9152 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
9153 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
9154 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
9155}
9156
9157function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
9158 if (_current !== null) {
9159 // An indeterminate component only mounts if it suspended inside a non-
9160 // concurrent tree, in an inconsistent state. We want to treat it like
9161 // a new mount, even though an empty version of it already committed.
9162 // Disconnect the alternate pointers.
9163 _current.alternate = null;
9164 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
9165
9166 workInProgress.effectTag |= Placement;
9167 }
9168
9169 var props = workInProgress.pendingProps;
9170 var context;
9171
9172 if (!disableLegacyContext) {
9173 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
9174 context = getMaskedContext(workInProgress, unmaskedContext);
9175 }
9176
9177 prepareToReadContext(workInProgress, renderExpirationTime);
9178 var value;
9179
9180 {
9181 if (Component.prototype && typeof Component.prototype.render === 'function') {
9182 var componentName = getComponentName(Component) || 'Unknown';
9183
9184 if (!didWarnAboutBadClass[componentName]) {
9185 warningWithoutStack$1(false, "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
9186 didWarnAboutBadClass[componentName] = true;
9187 }
9188 }
9189
9190 if (workInProgress.mode & StrictMode) {
9191 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
9192 }
9193
9194 ReactCurrentOwner$2.current = workInProgress;
9195 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
9196 } // React DevTools reads this flag.
9197
9198
9199 workInProgress.effectTag |= PerformedWork;
9200
9201 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
9202 {
9203 var _componentName = getComponentName(Component) || 'Unknown';
9204
9205 if (!didWarnAboutModulePatternComponent[_componentName]) {
9206 warningWithoutStack$1(false, 'The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
9207 didWarnAboutModulePatternComponent[_componentName] = true;
9208 }
9209 } // Proceed under the assumption that this is a class instance
9210
9211
9212 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
9213
9214 resetHooks(); // Push context providers early to prevent context stack mismatches.
9215 // During mounting we don't know the child context yet as the instance doesn't exist.
9216 // We will invalidate the child context in finishClassComponent() right after rendering.
9217
9218 var hasContext = false;
9219
9220 if (isContextProvider(Component)) {
9221 hasContext = true;
9222 pushContextProvider(workInProgress);
9223 } else {
9224 hasContext = false;
9225 }
9226
9227 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
9228 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
9229
9230 if (typeof getDerivedStateFromProps === 'function') {
9231 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
9232 }
9233
9234 adoptClassInstance(workInProgress, value);
9235 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
9236 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
9237 } else {
9238 // Proceed under the assumption that this is a function component
9239 workInProgress.tag = FunctionComponent;
9240
9241 {
9242 if (disableLegacyContext && Component.contextTypes) {
9243 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with React.useContext() instead.', getComponentName(Component) || 'Unknown');
9244 }
9245
9246 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
9247 // Only double-render components with Hooks
9248 if (workInProgress.memoizedState !== null) {
9249 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
9250 }
9251 }
9252 }
9253
9254 reconcileChildren(null, workInProgress, value, renderExpirationTime);
9255
9256 {
9257 validateFunctionComponentInDev(workInProgress, Component);
9258 }
9259
9260 return workInProgress.child;
9261 }
9262}
9263
9264function validateFunctionComponentInDev(workInProgress, Component) {
9265 if (Component) {
9266 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
9267 }
9268
9269 if (workInProgress.ref !== null) {
9270 var info = '';
9271 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
9272
9273 if (ownerName) {
9274 info += '\n\nCheck the render method of `' + ownerName + '`.';
9275 }
9276
9277 var warningKey = ownerName || workInProgress._debugID || '';
9278 var debugSource = workInProgress._debugSource;
9279
9280 if (debugSource) {
9281 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
9282 }
9283
9284 if (!didWarnAboutFunctionRefs[warningKey]) {
9285 didWarnAboutFunctionRefs[warningKey] = true;
9286 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
9287 }
9288 }
9289
9290 if (warnAboutDefaultPropsOnFunctionComponents && Component.defaultProps !== undefined) {
9291 var componentName = getComponentName(Component) || 'Unknown';
9292
9293 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
9294 warningWithoutStack$1(false, '%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
9295 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
9296 }
9297 }
9298
9299 if (typeof Component.getDerivedStateFromProps === 'function') {
9300 var _componentName2 = getComponentName(Component) || 'Unknown';
9301
9302 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
9303 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', _componentName2);
9304 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
9305 }
9306 }
9307
9308 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
9309 var _componentName3 = getComponentName(Component) || 'Unknown';
9310
9311 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
9312 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName3);
9313 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
9314 }
9315 }
9316}
9317
9318var SUSPENDED_MARKER = {
9319 dehydrated: null,
9320 retryTime: Never
9321};
9322
9323function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
9324 // If the context is telling us that we should show a fallback, and we're not
9325 // already showing content, then we should show the fallback instead.
9326 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
9327}
9328
9329function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
9330 var mode = workInProgress.mode;
9331 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
9332
9333 {
9334 if (shouldSuspend(workInProgress)) {
9335 workInProgress.effectTag |= DidCapture;
9336 }
9337 }
9338
9339 var suspenseContext = suspenseStackCursor.current;
9340 var nextDidTimeout = false;
9341 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
9342
9343 if (didSuspend || shouldRemainOnFallback(suspenseContext, current, workInProgress)) {
9344 // Something in this boundary's subtree already suspended. Switch to
9345 // rendering the fallback children.
9346 nextDidTimeout = true;
9347 workInProgress.effectTag &= ~DidCapture;
9348 } else {
9349 // Attempting the main content
9350 if (current === null || current.memoizedState !== null) {
9351 // This is a new mount or this boundary is already showing a fallback state.
9352 // Mark this subtree context as having at least one invisible parent that could
9353 // handle the fallback state.
9354 // Boundaries without fallbacks or should be avoided are not considered since
9355 // they cannot handle preferred fallback states.
9356 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
9357 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
9358 }
9359 }
9360 }
9361
9362 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
9363 pushSuspenseContext(workInProgress, suspenseContext);
9364
9365 {
9366 if ('maxDuration' in nextProps) {
9367 if (!didWarnAboutMaxDuration) {
9368 didWarnAboutMaxDuration = true;
9369 warning$1(false, 'maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
9370 }
9371 }
9372 } // This next part is a bit confusing. If the children timeout, we switch to
9373 // showing the fallback children in place of the "primary" children.
9374 // However, we don't want to delete the primary children because then their
9375 // state will be lost (both the React state and the host state, e.g.
9376 // uncontrolled form inputs). Instead we keep them mounted and hide them.
9377 // Both the fallback children AND the primary children are rendered at the
9378 // same time. Once the primary children are un-suspended, we can delete
9379 // the fallback children — don't need to preserve their state.
9380 //
9381 // The two sets of children are siblings in the host environment, but
9382 // semantically, for purposes of reconciliation, they are two separate sets.
9383 // So we store them using two fragment fibers.
9384 //
9385 // However, we want to avoid allocating extra fibers for every placeholder.
9386 // They're only necessary when the children time out, because that's the
9387 // only time when both sets are mounted.
9388 //
9389 // So, the extra fragment fibers are only used if the children time out.
9390 // Otherwise, we render the primary children directly. This requires some
9391 // custom reconciliation logic to preserve the state of the primary
9392 // children. It's essentially a very basic form of re-parenting.
9393
9394
9395 if (current === null) {
9396 if (enableSuspenseServerRenderer) {
9397 // If we're currently hydrating, try to hydrate this boundary.
9398 // But only if this has a fallback.
9399 if (nextProps.fallback !== undefined) {
9400 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
9401
9402 var suspenseState = workInProgress.memoizedState;
9403
9404 if (suspenseState !== null) {
9405 var dehydrated = suspenseState.dehydrated;
9406
9407 if (dehydrated !== null) {
9408 return mountDehydratedSuspenseComponent(workInProgress, dehydrated, renderExpirationTime);
9409 }
9410 }
9411 }
9412 } // This is the initial mount. This branch is pretty simple because there's
9413 // no previous state that needs to be preserved.
9414
9415
9416 if (nextDidTimeout) {
9417 // Mount separate fragments for primary and fallback children.
9418 var nextFallbackChildren = nextProps.fallback;
9419 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
9420 primaryChildFragment.return = workInProgress;
9421
9422 if ((workInProgress.mode & BatchedMode) === NoMode) {
9423 // Outside of batched mode, we commit the effects from the
9424 // partially completed, timed-out tree, too.
9425 var progressedState = workInProgress.memoizedState;
9426 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
9427 primaryChildFragment.child = progressedPrimaryChild;
9428 var progressedChild = progressedPrimaryChild;
9429
9430 while (progressedChild !== null) {
9431 progressedChild.return = primaryChildFragment;
9432 progressedChild = progressedChild.sibling;
9433 }
9434 }
9435
9436 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
9437 fallbackChildFragment.return = workInProgress;
9438 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
9439 // fallback children.
9440
9441 workInProgress.memoizedState = SUSPENDED_MARKER;
9442 workInProgress.child = primaryChildFragment;
9443 return fallbackChildFragment;
9444 } else {
9445 // Mount the primary children without an intermediate fragment fiber.
9446 var nextPrimaryChildren = nextProps.children;
9447 workInProgress.memoizedState = null;
9448 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
9449 }
9450 } else {
9451 // This is an update. This branch is more complicated because we need to
9452 // ensure the state of the primary children is preserved.
9453 var prevState = current.memoizedState;
9454
9455 if (prevState !== null) {
9456 if (enableSuspenseServerRenderer) {
9457 var _dehydrated = prevState.dehydrated;
9458
9459 if (_dehydrated !== null) {
9460 if (!didSuspend) {
9461 return updateDehydratedSuspenseComponent(current, workInProgress, _dehydrated, prevState, renderExpirationTime);
9462 } else if (workInProgress.memoizedState !== null) {
9463 // Something suspended and we should still be in dehydrated mode.
9464 // Leave the existing child in place.
9465 workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there
9466 // but the normal suspense pass doesn't.
9467
9468 workInProgress.effectTag |= DidCapture;
9469 return null;
9470 } else {
9471 // Suspended but we should no longer be in dehydrated mode.
9472 // Therefore we now have to render the fallback. Wrap the children
9473 // in a fragment fiber to keep them separate from the fallback
9474 // children.
9475 var _nextFallbackChildren = nextProps.fallback;
9476
9477 var _primaryChildFragment = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
9478 // going to render this fragment.
9479 null, mode, NoWork, null);
9480
9481 _primaryChildFragment.return = workInProgress; // This is always null since we never want the previous child
9482 // that we're not going to hydrate.
9483
9484 _primaryChildFragment.child = null;
9485
9486 if ((workInProgress.mode & BatchedMode) === NoMode) {
9487 // Outside of batched mode, we commit the effects from the
9488 // partially completed, timed-out tree, too.
9489 var _progressedChild = _primaryChildFragment.child = workInProgress.child;
9490
9491 while (_progressedChild !== null) {
9492 _progressedChild.return = _primaryChildFragment;
9493 _progressedChild = _progressedChild.sibling;
9494 }
9495 } else {
9496 // We will have dropped the effect list which contains the deletion.
9497 // We need to reconcile to delete the current child.
9498 reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime);
9499 } // Because primaryChildFragment is a new fiber that we're inserting as the
9500 // parent of a new tree, we need to set its treeBaseDuration.
9501
9502
9503 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
9504 // treeBaseDuration is the sum of all the child tree base durations.
9505 var treeBaseDuration = 0;
9506 var hiddenChild = _primaryChildFragment.child;
9507
9508 while (hiddenChild !== null) {
9509 treeBaseDuration += hiddenChild.treeBaseDuration;
9510 hiddenChild = hiddenChild.sibling;
9511 }
9512
9513 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
9514 } // Create a fragment from the fallback children, too.
9515
9516
9517 var _fallbackChildFragment = createFiberFromFragment(_nextFallbackChildren, mode, renderExpirationTime, null);
9518
9519 _fallbackChildFragment.return = workInProgress;
9520 _primaryChildFragment.sibling = _fallbackChildFragment;
9521 _fallbackChildFragment.effectTag |= Placement;
9522 _primaryChildFragment.childExpirationTime = NoWork;
9523 workInProgress.memoizedState = SUSPENDED_MARKER;
9524 workInProgress.child = _primaryChildFragment; // Skip the primary children, and continue working on the
9525 // fallback children.
9526
9527 return _fallbackChildFragment;
9528 }
9529 }
9530 } // The current tree already timed out. That means each child set is
9531 // wrapped in a fragment fiber.
9532
9533
9534 var currentPrimaryChildFragment = current.child;
9535 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
9536
9537 if (nextDidTimeout) {
9538 // Still timed out. Reuse the current primary children by cloning
9539 // its fragment. We're going to skip over these entirely.
9540 var _nextFallbackChildren2 = nextProps.fallback;
9541
9542 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
9543
9544 _primaryChildFragment2.return = workInProgress;
9545
9546 if ((workInProgress.mode & BatchedMode) === NoMode) {
9547 // Outside of batched mode, we commit the effects from the
9548 // partially completed, timed-out tree, too.
9549 var _progressedState = workInProgress.memoizedState;
9550
9551 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
9552
9553 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
9554 _primaryChildFragment2.child = _progressedPrimaryChild;
9555 var _progressedChild2 = _progressedPrimaryChild;
9556
9557 while (_progressedChild2 !== null) {
9558 _progressedChild2.return = _primaryChildFragment2;
9559 _progressedChild2 = _progressedChild2.sibling;
9560 }
9561 }
9562 } // Because primaryChildFragment is a new fiber that we're inserting as the
9563 // parent of a new tree, we need to set its treeBaseDuration.
9564
9565
9566 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
9567 // treeBaseDuration is the sum of all the child tree base durations.
9568 var _treeBaseDuration = 0;
9569 var _hiddenChild = _primaryChildFragment2.child;
9570
9571 while (_hiddenChild !== null) {
9572 _treeBaseDuration += _hiddenChild.treeBaseDuration;
9573 _hiddenChild = _hiddenChild.sibling;
9574 }
9575
9576 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
9577 } // Clone the fallback child fragment, too. These we'll continue
9578 // working on.
9579
9580
9581 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2, currentFallbackChildFragment.expirationTime);
9582
9583 _fallbackChildFragment2.return = workInProgress;
9584 _primaryChildFragment2.sibling = _fallbackChildFragment2;
9585 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
9586 // fallback children.
9587
9588 workInProgress.memoizedState = SUSPENDED_MARKER;
9589 workInProgress.child = _primaryChildFragment2;
9590 return _fallbackChildFragment2;
9591 } else {
9592 // No longer suspended. Switch back to showing the primary children,
9593 // and remove the intermediate fragment fiber.
9594 var _nextPrimaryChildren = nextProps.children;
9595 var currentPrimaryChild = currentPrimaryChildFragment.child;
9596 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
9597 // children. Wait until the complete phase, after we've confirmed the
9598 // fallback is no longer needed.
9599 // TODO: Would it be better to store the fallback fragment on
9600 // the stateNode?
9601 // Continue rendering the children, like we normally do.
9602
9603 workInProgress.memoizedState = null;
9604 return workInProgress.child = primaryChild;
9605 }
9606 } else {
9607 // The current tree has not already timed out. That means the primary
9608 // children are not wrapped in a fragment fiber.
9609 var _currentPrimaryChild = current.child;
9610
9611 if (nextDidTimeout) {
9612 // Timed out. Wrap the children in a fragment fiber to keep them
9613 // separate from the fallback children.
9614 var _nextFallbackChildren3 = nextProps.fallback;
9615
9616 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
9617 // going to render this fragment.
9618 null, mode, NoWork, null);
9619
9620 _primaryChildFragment3.return = workInProgress;
9621 _primaryChildFragment3.child = _currentPrimaryChild;
9622
9623 if (_currentPrimaryChild !== null) {
9624 _currentPrimaryChild.return = _primaryChildFragment3;
9625 } // Even though we're creating a new fiber, there are no new children,
9626 // because we're reusing an already mounted tree. So we don't need to
9627 // schedule a placement.
9628 // primaryChildFragment.effectTag |= Placement;
9629
9630
9631 if ((workInProgress.mode & BatchedMode) === NoMode) {
9632 // Outside of batched mode, we commit the effects from the
9633 // partially completed, timed-out tree, too.
9634 var _progressedState2 = workInProgress.memoizedState;
9635
9636 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
9637
9638 _primaryChildFragment3.child = _progressedPrimaryChild2;
9639 var _progressedChild3 = _progressedPrimaryChild2;
9640
9641 while (_progressedChild3 !== null) {
9642 _progressedChild3.return = _primaryChildFragment3;
9643 _progressedChild3 = _progressedChild3.sibling;
9644 }
9645 } // Because primaryChildFragment is a new fiber that we're inserting as the
9646 // parent of a new tree, we need to set its treeBaseDuration.
9647
9648
9649 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
9650 // treeBaseDuration is the sum of all the child tree base durations.
9651 var _treeBaseDuration2 = 0;
9652 var _hiddenChild2 = _primaryChildFragment3.child;
9653
9654 while (_hiddenChild2 !== null) {
9655 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
9656 _hiddenChild2 = _hiddenChild2.sibling;
9657 }
9658
9659 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
9660 } // Create a fragment from the fallback children, too.
9661
9662
9663 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
9664
9665 _fallbackChildFragment3.return = workInProgress;
9666 _primaryChildFragment3.sibling = _fallbackChildFragment3;
9667 _fallbackChildFragment3.effectTag |= Placement;
9668 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
9669 // fallback children.
9670
9671 workInProgress.memoizedState = SUSPENDED_MARKER;
9672 workInProgress.child = _primaryChildFragment3;
9673 return _fallbackChildFragment3;
9674 } else {
9675 // Still haven't timed out. Continue rendering the children, like we
9676 // normally do.
9677 workInProgress.memoizedState = null;
9678 var _nextPrimaryChildren2 = nextProps.children;
9679 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
9680 }
9681 }
9682 }
9683}
9684
9685function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime) {
9686 // We're now not suspended nor dehydrated.
9687 workInProgress.memoizedState = null; // Retry with the full children.
9688
9689 var nextProps = workInProgress.pendingProps;
9690 var nextChildren = nextProps.children; // This will ensure that the children get Placement effects and
9691 // that the old child gets a Deletion effect.
9692 // We could also call forceUnmountCurrentAndReconcile.
9693
9694 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
9695 return workInProgress.child;
9696}
9697
9698function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderExpirationTime) {
9699 // During the first pass, we'll bail out and not drill into the children.
9700 // Instead, we'll leave the content in place and try to hydrate it later.
9701 if ((workInProgress.mode & BatchedMode) === NoMode) {
9702 {
9703 warning$1(false, 'Cannot hydrate Suspense in legacy mode. Switch from ' + 'ReactDOM.hydrate(element, container) to ' + 'ReactDOM.unstable_createSyncRoot(container, { hydrate: true })' + '.render(element) or remove the Suspense components from ' + 'the server rendered components.');
9704 }
9705
9706 workInProgress.expirationTime = Sync;
9707 } else if (isSuspenseInstanceFallback(suspenseInstance)) {
9708 // This is a client-only boundary. Since we won't get any content from the server
9709 // for this, we need to schedule that at a higher priority based on when it would
9710 // have timed out. In theory we could render it in this pass but it would have the
9711 // wrong priority associated with it and will prevent hydration of parent path.
9712 // Instead, we'll leave work left on it to render it in a separate commit.
9713 // TODO This time should be the time at which the server rendered response that is
9714 // a parent to this boundary was displayed. However, since we currently don't have
9715 // a protocol to transfer that time, we'll just estimate it by using the current
9716 // time. This will mean that Suspense timeouts are slightly shifted to later than
9717 // they should be.
9718 var serverDisplayTime = requestCurrentTime(); // Schedule a normal pri update to render this content.
9719
9720 var newExpirationTime = computeAsyncExpiration(serverDisplayTime);
9721
9722 if (enableSchedulerTracing) {
9723 markSpawnedWork(newExpirationTime);
9724 }
9725
9726 workInProgress.expirationTime = newExpirationTime;
9727 } else {
9728 // We'll continue hydrating the rest at offscreen priority since we'll already
9729 // be showing the right content coming from the server, it is no rush.
9730 workInProgress.expirationTime = Never;
9731
9732 if (enableSchedulerTracing) {
9733 markSpawnedWork(Never);
9734 }
9735 }
9736
9737 return null;
9738}
9739
9740function updateDehydratedSuspenseComponent(current, workInProgress, suspenseInstance, suspenseState, renderExpirationTime) {
9741 // We should never be hydrating at this point because it is the first pass,
9742 // but after we've already committed once.
9743 warnIfHydrating();
9744
9745 if ((workInProgress.mode & BatchedMode) === NoMode) {
9746 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime);
9747 }
9748
9749 if (isSuspenseInstanceFallback(suspenseInstance)) {
9750 // This boundary is in a permanent fallback state. In this case, we'll never
9751 // get an update and we'll never be able to hydrate the final content. Let's just try the
9752 // client side render instead.
9753 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime);
9754 } // We use childExpirationTime to indicate that a child might depend on context, so if
9755 // any context has changed, we need to treat is as if the input might have changed.
9756
9757
9758 var hasContextChanged$$1 = current.childExpirationTime >= renderExpirationTime;
9759
9760 if (didReceiveUpdate || hasContextChanged$$1) {
9761 // This boundary has changed since the first render. This means that we are now unable to
9762 // hydrate it. We might still be able to hydrate it using an earlier expiration time, if
9763 // we are rendering at lower expiration than sync.
9764 if (renderExpirationTime < Sync) {
9765 if (suspenseState.retryTime <= renderExpirationTime) {
9766 // This render is even higher pri than we've seen before, let's try again
9767 // at even higher pri.
9768 var attemptHydrationAtExpirationTime = renderExpirationTime + 1;
9769 suspenseState.retryTime = attemptHydrationAtExpirationTime;
9770 scheduleWork(current, attemptHydrationAtExpirationTime); // TODO: Early abort this render.
9771 } else {// We have already tried to ping at a higher priority than we're rendering with
9772 // so if we got here, we must have failed to hydrate at those levels. We must
9773 // now give up. Instead, we're going to delete the whole subtree and instead inject
9774 // a new real Suspense boundary to take its place, which may render content
9775 // or fallback. This might suspend for a while and if it does we might still have
9776 // an opportunity to hydrate before this pass commits.
9777 }
9778 } // If we have scheduled higher pri work above, this will probably just abort the render
9779 // since we now have higher priority work, but in case it doesn't, we need to prepare to
9780 // render something, if we time out. Even if that requires us to delete everything and
9781 // skip hydration.
9782 // Delay having to do this as long as the suspense timeout allows us.
9783
9784
9785 renderDidSuspendDelayIfPossible();
9786 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime);
9787 } else if (isSuspenseInstancePending(suspenseInstance)) {
9788 // This component is still pending more data from the server, so we can't hydrate its
9789 // content. We treat it as if this component suspended itself. It might seem as if
9790 // we could just try to render it client-side instead. However, this will perform a
9791 // lot of unnecessary work and is unlikely to complete since it often will suspend
9792 // on missing data anyway. Additionally, the server might be able to render more
9793 // than we can on the client yet. In that case we'd end up with more fallback states
9794 // on the client than if we just leave it alone. If the server times out or errors
9795 // these should update this boundary to the permanent Fallback state instead.
9796 // Mark it as having captured (i.e. suspended).
9797 workInProgress.effectTag |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment.
9798
9799 workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result.
9800
9801 registerSuspenseInstanceRetry(suspenseInstance, retryDehydratedSuspenseBoundary.bind(null, current));
9802 return null;
9803 } else {
9804 // This is the first attempt.
9805 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance);
9806 var nextProps = workInProgress.pendingProps;
9807 var nextChildren = nextProps.children;
9808 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
9809 var node = child;
9810
9811 while (node) {
9812 // Mark each child as hydrating. This is a fast path to know whether this
9813 // tree is part of a hydrating tree. This is used to determine if a child
9814 // node has fully mounted yet, and for scheduling event replaying.
9815 // Conceptually this is similar to Placement in that a new subtree is
9816 // inserted into the React tree here. It just happens to not need DOM
9817 // mutations because it already exists.
9818 node.effectTag |= Hydrating;
9819 node = node.sibling;
9820 }
9821
9822 workInProgress.child = child;
9823 return workInProgress.child;
9824 }
9825}
9826
9827function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
9828 // Mark any Suspense boundaries with fallbacks as having work to do.
9829 // If they were previously forced into fallbacks, they may now be able
9830 // to unblock.
9831 var node = firstChild;
9832
9833 while (node !== null) {
9834 if (node.tag === SuspenseComponent) {
9835 var state = node.memoizedState;
9836
9837 if (state !== null) {
9838 if (node.expirationTime < renderExpirationTime) {
9839 node.expirationTime = renderExpirationTime;
9840 }
9841
9842 var alternate = node.alternate;
9843
9844 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
9845 alternate.expirationTime = renderExpirationTime;
9846 }
9847
9848 scheduleWorkOnParentPath(node.return, renderExpirationTime);
9849 }
9850 } else if (node.child !== null) {
9851 node.child.return = node;
9852 node = node.child;
9853 continue;
9854 }
9855
9856 if (node === workInProgress) {
9857 return;
9858 }
9859
9860 while (node.sibling === null) {
9861 if (node.return === null || node.return === workInProgress) {
9862 return;
9863 }
9864
9865 node = node.return;
9866 }
9867
9868 node.sibling.return = node.return;
9869 node = node.sibling;
9870 }
9871}
9872
9873function findLastContentRow(firstChild) {
9874 // This is going to find the last row among these children that is already
9875 // showing content on the screen, as opposed to being in fallback state or
9876 // new. If a row has multiple Suspense boundaries, any of them being in the
9877 // fallback state, counts as the whole row being in a fallback state.
9878 // Note that the "rows" will be workInProgress, but any nested children
9879 // will still be current since we haven't rendered them yet. The mounted
9880 // order may not be the same as the new order. We use the new order.
9881 var row = firstChild;
9882 var lastContentRow = null;
9883
9884 while (row !== null) {
9885 var currentRow = row.alternate; // New rows can't be content rows.
9886
9887 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
9888 lastContentRow = row;
9889 }
9890
9891 row = row.sibling;
9892 }
9893
9894 return lastContentRow;
9895}
9896
9897function validateRevealOrder(revealOrder) {
9898 {
9899 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
9900 didWarnAboutRevealOrder[revealOrder] = true;
9901
9902 if (typeof revealOrder === 'string') {
9903 switch (revealOrder.toLowerCase()) {
9904 case 'together':
9905 case 'forwards':
9906 case 'backwards':
9907 {
9908 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
9909 break;
9910 }
9911
9912 case 'forward':
9913 case 'backward':
9914 {
9915 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
9916 break;
9917 }
9918
9919 default:
9920 warning$1(false, '"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
9921 break;
9922 }
9923 } else {
9924 warning$1(false, '%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
9925 }
9926 }
9927 }
9928}
9929
9930function validateTailOptions(tailMode, revealOrder) {
9931 {
9932 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
9933 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
9934 didWarnAboutTailOptions[tailMode] = true;
9935 warning$1(false, '"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
9936 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
9937 didWarnAboutTailOptions[tailMode] = true;
9938 warning$1(false, '<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
9939 }
9940 }
9941 }
9942}
9943
9944function validateSuspenseListNestedChild(childSlot, index) {
9945 {
9946 var isArray = Array.isArray(childSlot);
9947 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
9948
9949 if (isArray || isIterable) {
9950 var type = isArray ? 'array' : 'iterable';
9951 warning$1(false, 'A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
9952 return false;
9953 }
9954 }
9955
9956 return true;
9957}
9958
9959function validateSuspenseListChildren(children, revealOrder) {
9960 {
9961 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
9962 if (Array.isArray(children)) {
9963 for (var i = 0; i < children.length; i++) {
9964 if (!validateSuspenseListNestedChild(children[i], i)) {
9965 return;
9966 }
9967 }
9968 } else {
9969 var iteratorFn = getIteratorFn(children);
9970
9971 if (typeof iteratorFn === 'function') {
9972 var childrenIterator = iteratorFn.call(children);
9973
9974 if (childrenIterator) {
9975 var step = childrenIterator.next();
9976 var _i = 0;
9977
9978 for (; !step.done; step = childrenIterator.next()) {
9979 if (!validateSuspenseListNestedChild(step.value, _i)) {
9980 return;
9981 }
9982
9983 _i++;
9984 }
9985 }
9986 } else {
9987 warning$1(false, 'A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
9988 }
9989 }
9990 }
9991 }
9992}
9993
9994function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
9995 var renderState = workInProgress.memoizedState;
9996
9997 if (renderState === null) {
9998 workInProgress.memoizedState = {
9999 isBackwards: isBackwards,
10000 rendering: null,
10001 last: lastContentRow,
10002 tail: tail,
10003 tailExpiration: 0,
10004 tailMode: tailMode
10005 };
10006 } else {
10007 // We can reuse the existing object from previous renders.
10008 renderState.isBackwards = isBackwards;
10009 renderState.rendering = null;
10010 renderState.last = lastContentRow;
10011 renderState.tail = tail;
10012 renderState.tailExpiration = 0;
10013 renderState.tailMode = tailMode;
10014 }
10015} // This can end up rendering this component multiple passes.
10016// The first pass splits the children fibers into two sets. A head and tail.
10017// We first render the head. If anything is in fallback state, we do another
10018// pass through beginWork to rerender all children (including the tail) with
10019// the force suspend context. If the first render didn't have anything in
10020// in fallback state. Then we render each row in the tail one-by-one.
10021// That happens in the completeWork phase without going back to beginWork.
10022
10023
10024function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
10025 var nextProps = workInProgress.pendingProps;
10026 var revealOrder = nextProps.revealOrder;
10027 var tailMode = nextProps.tail;
10028 var newChildren = nextProps.children;
10029 validateRevealOrder(revealOrder);
10030 validateTailOptions(tailMode, revealOrder);
10031 validateSuspenseListChildren(newChildren, revealOrder);
10032 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
10033 var suspenseContext = suspenseStackCursor.current;
10034 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
10035
10036 if (shouldForceFallback) {
10037 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
10038 workInProgress.effectTag |= DidCapture;
10039 } else {
10040 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
10041
10042 if (didSuspendBefore) {
10043 // If we previously forced a fallback, we need to schedule work
10044 // on any nested boundaries to let them know to try to render
10045 // again. This is the same as context updating.
10046 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
10047 }
10048
10049 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10050 }
10051
10052 pushSuspenseContext(workInProgress, suspenseContext);
10053
10054 if ((workInProgress.mode & BatchedMode) === NoMode) {
10055 // Outside of batched mode, SuspenseList doesn't work so we just
10056 // use make it a noop by treating it as the default revealOrder.
10057 workInProgress.memoizedState = null;
10058 } else {
10059 switch (revealOrder) {
10060 case 'forwards':
10061 {
10062 var lastContentRow = findLastContentRow(workInProgress.child);
10063 var tail;
10064
10065 if (lastContentRow === null) {
10066 // The whole list is part of the tail.
10067 // TODO: We could fast path by just rendering the tail now.
10068 tail = workInProgress.child;
10069 workInProgress.child = null;
10070 } else {
10071 // Disconnect the tail rows after the content row.
10072 // We're going to render them separately later.
10073 tail = lastContentRow.sibling;
10074 lastContentRow.sibling = null;
10075 }
10076
10077 initSuspenseListRenderState(workInProgress, false, // isBackwards
10078 tail, lastContentRow, tailMode);
10079 break;
10080 }
10081
10082 case 'backwards':
10083 {
10084 // We're going to find the first row that has existing content.
10085 // At the same time we're going to reverse the list of everything
10086 // we pass in the meantime. That's going to be our tail in reverse
10087 // order.
10088 var _tail = null;
10089 var row = workInProgress.child;
10090 workInProgress.child = null;
10091
10092 while (row !== null) {
10093 var currentRow = row.alternate; // New rows can't be content rows.
10094
10095 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
10096 // This is the beginning of the main content.
10097 workInProgress.child = row;
10098 break;
10099 }
10100
10101 var nextRow = row.sibling;
10102 row.sibling = _tail;
10103 _tail = row;
10104 row = nextRow;
10105 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
10106
10107
10108 initSuspenseListRenderState(workInProgress, true, // isBackwards
10109 _tail, null, // last
10110 tailMode);
10111 break;
10112 }
10113
10114 case 'together':
10115 {
10116 initSuspenseListRenderState(workInProgress, false, // isBackwards
10117 null, // tail
10118 null, // last
10119 undefined);
10120 break;
10121 }
10122
10123 default:
10124 {
10125 // The default reveal order is the same as not having
10126 // a boundary.
10127 workInProgress.memoizedState = null;
10128 }
10129 }
10130 }
10131
10132 return workInProgress.child;
10133}
10134
10135function updatePortalComponent(current, workInProgress, renderExpirationTime) {
10136 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
10137 var nextChildren = workInProgress.pendingProps;
10138
10139 if (current === null) {
10140 // Portals are special because we don't append the children during mount
10141 // but at commit. Therefore we need to track insertions which the normal
10142 // flow doesn't do during mount. This doesn't happen at the root because
10143 // the root always starts with a "current" with a null child.
10144 // TODO: Consider unifying this with how the root works.
10145 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
10146 } else {
10147 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
10148 }
10149
10150 return workInProgress.child;
10151}
10152
10153function updateContextProvider(current, workInProgress, renderExpirationTime) {
10154 var providerType = workInProgress.type;
10155 var context = providerType._context;
10156 var newProps = workInProgress.pendingProps;
10157 var oldProps = workInProgress.memoizedProps;
10158 var newValue = newProps.value;
10159
10160 {
10161 var providerPropTypes = workInProgress.type.propTypes;
10162
10163 if (providerPropTypes) {
10164 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
10165 }
10166 }
10167
10168 pushProvider(workInProgress, newValue);
10169
10170 if (oldProps !== null) {
10171 var oldValue = oldProps.value;
10172 var changedBits = calculateChangedBits(context, newValue, oldValue);
10173
10174 if (changedBits === 0) {
10175 // No change. Bailout early if children are the same.
10176 if (oldProps.children === newProps.children && !hasContextChanged()) {
10177 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
10178 }
10179 } else {
10180 // The context value changed. Search for matching consumers and schedule
10181 // them to update.
10182 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
10183 }
10184 }
10185
10186 var newChildren = newProps.children;
10187 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
10188 return workInProgress.child;
10189}
10190
10191var hasWarnedAboutUsingContextAsConsumer = false;
10192
10193function updateContextConsumer(current, workInProgress, renderExpirationTime) {
10194 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
10195 // DEV mode, we create a separate object for Context.Consumer that acts
10196 // like a proxy to Context. This proxy object adds unnecessary code in PROD
10197 // so we use the old behaviour (Context.Consumer references Context) to
10198 // reduce size and overhead. The separate object references context via
10199 // a property called "_context", which also gives us the ability to check
10200 // in DEV mode if this property exists or not and warn if it does not.
10201
10202 {
10203 if (context._context === undefined) {
10204 // This may be because it's a Context (rather than a Consumer).
10205 // Or it may be because it's older React where they're the same thing.
10206 // We only want to warn if we're sure it's a new React.
10207 if (context !== context.Consumer) {
10208 if (!hasWarnedAboutUsingContextAsConsumer) {
10209 hasWarnedAboutUsingContextAsConsumer = true;
10210 warning$1(false, 'Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
10211 }
10212 }
10213 } else {
10214 context = context._context;
10215 }
10216 }
10217
10218 var newProps = workInProgress.pendingProps;
10219 var render = newProps.children;
10220
10221 {
10222 !(typeof render === 'function') ? warningWithoutStack$1(false, 'A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.') : void 0;
10223 }
10224
10225 prepareToReadContext(workInProgress, renderExpirationTime);
10226 var newValue = readContext(context, newProps.unstable_observedBits);
10227 var newChildren;
10228
10229 {
10230 ReactCurrentOwner$2.current = workInProgress;
10231 setCurrentPhase('render');
10232 newChildren = render(newValue);
10233 setCurrentPhase(null);
10234 } // React DevTools reads this flag.
10235
10236
10237 workInProgress.effectTag |= PerformedWork;
10238 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
10239 return workInProgress.child;
10240}
10241
10242function updateFundamentalComponent$1(current, workInProgress, renderExpirationTime) {
10243 var fundamentalImpl = workInProgress.type.impl;
10244
10245 if (fundamentalImpl.reconcileChildren === false) {
10246 return null;
10247 }
10248
10249 var nextProps = workInProgress.pendingProps;
10250 var nextChildren = nextProps.children;
10251 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
10252 return workInProgress.child;
10253}
10254
10255function updateScopeComponent(current, workInProgress, renderExpirationTime) {
10256 var nextProps = workInProgress.pendingProps;
10257 var nextChildren = nextProps.children;
10258 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
10259 return workInProgress.child;
10260}
10261
10262function markWorkInProgressReceivedUpdate() {
10263 didReceiveUpdate = true;
10264}
10265
10266function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
10267 cancelWorkTimer(workInProgress);
10268
10269 if (current !== null) {
10270 // Reuse previous dependencies
10271 workInProgress.dependencies = current.dependencies;
10272 }
10273
10274 if (enableProfilerTimer) {
10275 // Don't update "base" render times for bailouts.
10276 stopProfilerTimerIfRunning(workInProgress);
10277 }
10278
10279 var updateExpirationTime = workInProgress.expirationTime;
10280
10281 if (updateExpirationTime !== NoWork) {
10282 markUnprocessedUpdateTime(updateExpirationTime);
10283 } // Check if the children have any pending work.
10284
10285
10286 var childExpirationTime = workInProgress.childExpirationTime;
10287
10288 if (childExpirationTime < renderExpirationTime) {
10289 // The children don't have any work either. We can skip them.
10290 // TODO: Once we add back resuming, we should check if the children are
10291 // a work-in-progress set. If so, we need to transfer their effects.
10292 return null;
10293 } else {
10294 // This fiber doesn't have work, but its subtree does. Clone the child
10295 // fibers and continue.
10296 cloneChildFibers(current, workInProgress);
10297 return workInProgress.child;
10298 }
10299}
10300
10301function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
10302 {
10303 var returnFiber = oldWorkInProgress.return;
10304
10305 if (returnFiber === null) {
10306 throw new Error('Cannot swap the root fiber.');
10307 } // Disconnect from the old current.
10308 // It will get deleted.
10309
10310
10311 current.alternate = null;
10312 oldWorkInProgress.alternate = null; // Connect to the new tree.
10313
10314 newWorkInProgress.index = oldWorkInProgress.index;
10315 newWorkInProgress.sibling = oldWorkInProgress.sibling;
10316 newWorkInProgress.return = oldWorkInProgress.return;
10317 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
10318
10319 if (oldWorkInProgress === returnFiber.child) {
10320 returnFiber.child = newWorkInProgress;
10321 } else {
10322 var prevSibling = returnFiber.child;
10323
10324 if (prevSibling === null) {
10325 throw new Error('Expected parent to have a child.');
10326 }
10327
10328 while (prevSibling.sibling !== oldWorkInProgress) {
10329 prevSibling = prevSibling.sibling;
10330
10331 if (prevSibling === null) {
10332 throw new Error('Expected to find the previous sibling.');
10333 }
10334 }
10335
10336 prevSibling.sibling = newWorkInProgress;
10337 } // Delete the old fiber and place the new one.
10338 // Since the old fiber is disconnected, we have to schedule it manually.
10339
10340
10341 var last = returnFiber.lastEffect;
10342
10343 if (last !== null) {
10344 last.nextEffect = current;
10345 returnFiber.lastEffect = current;
10346 } else {
10347 returnFiber.firstEffect = returnFiber.lastEffect = current;
10348 }
10349
10350 current.nextEffect = null;
10351 current.effectTag = Deletion;
10352 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
10353
10354 return newWorkInProgress;
10355 }
10356}
10357
10358function beginWork$1(current, workInProgress, renderExpirationTime) {
10359 var updateExpirationTime = workInProgress.expirationTime;
10360
10361 {
10362 if (workInProgress._debugNeedsRemount && current !== null) {
10363 // This will restart the begin phase with a new fiber.
10364 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
10365 }
10366 }
10367
10368 if (current !== null) {
10369 var oldProps = current.memoizedProps;
10370 var newProps = workInProgress.pendingProps;
10371
10372 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
10373 workInProgress.type !== current.type)) {
10374 // If props or context changed, mark the fiber as having performed work.
10375 // This may be unset if the props are determined to be equal later (memo).
10376 didReceiveUpdate = true;
10377 } else if (updateExpirationTime < renderExpirationTime) {
10378 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
10379 // the begin phase. There's still some bookkeeping we that needs to be done
10380 // in this optimized path, mostly pushing stuff onto the stack.
10381
10382 switch (workInProgress.tag) {
10383 case HostRoot:
10384 pushHostRootContext(workInProgress);
10385 resetHydrationState();
10386 break;
10387
10388 case HostComponent:
10389 pushHostContext(workInProgress);
10390
10391 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
10392 if (enableSchedulerTracing) {
10393 markSpawnedWork(Never);
10394 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
10395
10396
10397 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
10398 return null;
10399 }
10400
10401 break;
10402
10403 case ClassComponent:
10404 {
10405 var Component = workInProgress.type;
10406
10407 if (isContextProvider(Component)) {
10408 pushContextProvider(workInProgress);
10409 }
10410
10411 break;
10412 }
10413
10414 case HostPortal:
10415 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
10416 break;
10417
10418 case ContextProvider:
10419 {
10420 var newValue = workInProgress.memoizedProps.value;
10421 pushProvider(workInProgress, newValue);
10422 break;
10423 }
10424
10425 case Profiler:
10426 if (enableProfilerTimer) {
10427 workInProgress.effectTag |= Update;
10428 }
10429
10430 break;
10431
10432 case SuspenseComponent:
10433 {
10434 var state = workInProgress.memoizedState;
10435
10436 if (state !== null) {
10437 if (enableSuspenseServerRenderer) {
10438 if (state.dehydrated !== null) {
10439 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has
10440 // been unsuspended it has committed as a resolved Suspense component.
10441 // If it needs to be retried, it should have work scheduled on it.
10442
10443 workInProgress.effectTag |= DidCapture;
10444 break;
10445 }
10446 } // If this boundary is currently timed out, we need to decide
10447 // whether to retry the primary children, or to skip over it and
10448 // go straight to the fallback. Check the priority of the primary
10449 // child fragment.
10450
10451
10452 var primaryChildFragment = workInProgress.child;
10453 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
10454
10455 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
10456 // The primary children have pending work. Use the normal path
10457 // to attempt to render the primary children again.
10458 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
10459 } else {
10460 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
10461 // priority. Bailout.
10462
10463 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
10464
10465 if (child !== null) {
10466 // The fallback children have pending work. Skip over the
10467 // primary children and work on the fallback.
10468 return child.sibling;
10469 } else {
10470 return null;
10471 }
10472 }
10473 } else {
10474 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
10475 }
10476
10477 break;
10478 }
10479
10480 case SuspenseListComponent:
10481 {
10482 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
10483 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
10484
10485 if (didSuspendBefore) {
10486 if (hasChildWork) {
10487 // If something was in fallback state last time, and we have all the
10488 // same children then we're still in progressive loading state.
10489 // Something might get unblocked by state updates or retries in the
10490 // tree which will affect the tail. So we need to use the normal
10491 // path to compute the correct tail.
10492 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
10493 } // If none of the children had any work, that means that none of
10494 // them got retried so they'll still be blocked in the same way
10495 // as before. We can fast bail out.
10496
10497
10498 workInProgress.effectTag |= DidCapture;
10499 } // If nothing suspended before and we're rendering the same children,
10500 // then the tail doesn't matter. Anything new that suspends will work
10501 // in the "together" mode, so we can continue from the state we had.
10502
10503
10504 var renderState = workInProgress.memoizedState;
10505
10506 if (renderState !== null) {
10507 // Reset to the "together" mode in case we've started a different
10508 // update in the past but didn't complete it.
10509 renderState.rendering = null;
10510 renderState.tail = null;
10511 }
10512
10513 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
10514
10515 if (hasChildWork) {
10516 break;
10517 } else {
10518 // If none of the children had any work, that means that none of
10519 // them got retried so they'll still be blocked in the same way
10520 // as before. We can fast bail out.
10521 return null;
10522 }
10523 }
10524 }
10525
10526 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
10527 } else {
10528 // An update was scheduled on this fiber, but there are no new props
10529 // nor legacy context. Set this to false. If an update queue or context
10530 // consumer produces a changed value, it will set this to true. Otherwise,
10531 // the component will assume the children have not changed and bail out.
10532 didReceiveUpdate = false;
10533 }
10534 } else {
10535 didReceiveUpdate = false;
10536 } // Before entering the begin phase, clear the expiration time.
10537
10538
10539 workInProgress.expirationTime = NoWork;
10540
10541 switch (workInProgress.tag) {
10542 case IndeterminateComponent:
10543 {
10544 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
10545 }
10546
10547 case LazyComponent:
10548 {
10549 var elementType = workInProgress.elementType;
10550 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
10551 }
10552
10553 case FunctionComponent:
10554 {
10555 var _Component = workInProgress.type;
10556 var unresolvedProps = workInProgress.pendingProps;
10557 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
10558 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
10559 }
10560
10561 case ClassComponent:
10562 {
10563 var _Component2 = workInProgress.type;
10564 var _unresolvedProps = workInProgress.pendingProps;
10565
10566 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
10567
10568 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
10569 }
10570
10571 case HostRoot:
10572 return updateHostRoot(current, workInProgress, renderExpirationTime);
10573
10574 case HostComponent:
10575 return updateHostComponent(current, workInProgress, renderExpirationTime);
10576
10577 case HostText:
10578 return updateHostText(current, workInProgress);
10579
10580 case SuspenseComponent:
10581 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
10582
10583 case HostPortal:
10584 return updatePortalComponent(current, workInProgress, renderExpirationTime);
10585
10586 case ForwardRef:
10587 {
10588 var type = workInProgress.type;
10589 var _unresolvedProps2 = workInProgress.pendingProps;
10590
10591 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
10592
10593 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
10594 }
10595
10596 case Fragment:
10597 return updateFragment(current, workInProgress, renderExpirationTime);
10598
10599 case Mode:
10600 return updateMode(current, workInProgress, renderExpirationTime);
10601
10602 case Profiler:
10603 return updateProfiler(current, workInProgress, renderExpirationTime);
10604
10605 case ContextProvider:
10606 return updateContextProvider(current, workInProgress, renderExpirationTime);
10607
10608 case ContextConsumer:
10609 return updateContextConsumer(current, workInProgress, renderExpirationTime);
10610
10611 case MemoComponent:
10612 {
10613 var _type2 = workInProgress.type;
10614 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
10615
10616 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
10617
10618 {
10619 if (workInProgress.type !== workInProgress.elementType) {
10620 var outerPropTypes = _type2.propTypes;
10621
10622 if (outerPropTypes) {
10623 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
10624 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
10625 }
10626 }
10627 }
10628
10629 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
10630 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
10631 }
10632
10633 case SimpleMemoComponent:
10634 {
10635 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
10636 }
10637
10638 case IncompleteClassComponent:
10639 {
10640 var _Component3 = workInProgress.type;
10641 var _unresolvedProps4 = workInProgress.pendingProps;
10642
10643 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
10644
10645 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
10646 }
10647
10648 case SuspenseListComponent:
10649 {
10650 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
10651 }
10652
10653 case FundamentalComponent:
10654 {
10655 if (enableFundamentalAPI) {
10656 return updateFundamentalComponent$1(current, workInProgress, renderExpirationTime);
10657 }
10658
10659 break;
10660 }
10661
10662 case ScopeComponent:
10663 {
10664 if (enableScopeAPI) {
10665 return updateScopeComponent(current, workInProgress, renderExpirationTime);
10666 }
10667
10668 break;
10669 }
10670 }
10671
10672 (function () {
10673 {
10674 {
10675 throw ReactError(Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue."));
10676 }
10677 }
10678 })();
10679}
10680
10681function createFundamentalStateInstance(currentFiber, props, impl, state) {
10682 return {
10683 currentFiber: currentFiber,
10684 impl: impl,
10685 instance: null,
10686 prevProps: null,
10687 props: props,
10688 state: state
10689 };
10690}
10691
10692function isFiberSuspenseAndTimedOut(fiber) {
10693 return fiber.tag === SuspenseComponent && fiber.memoizedState !== null;
10694}
10695
10696function getSuspenseFallbackChild(fiber) {
10697 return fiber.child.sibling.child;
10698}
10699
10700function collectScopedNodes(node, fn, scopedNodes) {
10701 if (enableScopeAPI) {
10702 if (node.tag === HostComponent) {
10703 var _type = node.type,
10704 memoizedProps = node.memoizedProps;
10705
10706 if (fn(_type, memoizedProps) === true) {
10707 scopedNodes.push(getPublicInstance(node.stateNode));
10708 }
10709 }
10710
10711 var child = node.child;
10712
10713 if (isFiberSuspenseAndTimedOut(node)) {
10714 child = getSuspenseFallbackChild(node);
10715 }
10716
10717 if (child !== null) {
10718 collectScopedNodesFromChildren(child, fn, scopedNodes);
10719 }
10720 }
10721}
10722
10723function collectScopedNodesFromChildren(startingChild, fn, scopedNodes) {
10724 var child = startingChild;
10725
10726 while (child !== null) {
10727 collectScopedNodes(child, fn, scopedNodes);
10728 child = child.sibling;
10729 }
10730}
10731
10732function collectNearestScopeMethods(node, scope, childrenScopes) {
10733 if (isValidScopeNode(node, scope)) {
10734 childrenScopes.push(node.stateNode.methods);
10735 } else {
10736 var child = node.child;
10737
10738 if (isFiberSuspenseAndTimedOut(node)) {
10739 child = getSuspenseFallbackChild(node);
10740 }
10741
10742 if (child !== null) {
10743 collectNearestChildScopeMethods(child, scope, childrenScopes);
10744 }
10745 }
10746}
10747
10748function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) {
10749 var child = startingChild;
10750
10751 while (child !== null) {
10752 collectNearestScopeMethods(child, scope, childrenScopes);
10753 child = child.sibling;
10754 }
10755}
10756
10757function isValidScopeNode(node, scope) {
10758 return node.tag === ScopeComponent && node.type === scope;
10759}
10760
10761function createScopeMethods(scope, instance) {
10762 var fn = scope.fn;
10763 return {
10764 getChildren: function () {
10765 var currentFiber = instance.fiber;
10766 var child = currentFiber.child;
10767 var childrenScopes = [];
10768
10769 if (child !== null) {
10770 collectNearestChildScopeMethods(child, scope, childrenScopes);
10771 }
10772
10773 return childrenScopes.length === 0 ? null : childrenScopes;
10774 },
10775 getChildrenFromRoot: function () {
10776 var currentFiber = instance.fiber;
10777 var node = currentFiber;
10778
10779 while (node !== null) {
10780 var parent = node.return;
10781
10782 if (parent === null) {
10783 break;
10784 }
10785
10786 node = parent;
10787
10788 if (node.tag === ScopeComponent && node.type === scope) {
10789 break;
10790 }
10791 }
10792
10793 var childrenScopes = [];
10794 collectNearestChildScopeMethods(node.child, scope, childrenScopes);
10795 return childrenScopes.length === 0 ? null : childrenScopes;
10796 },
10797 getParent: function () {
10798 var node = instance.fiber.return;
10799
10800 while (node !== null) {
10801 if (node.tag === ScopeComponent && node.type === scope) {
10802 return node.stateNode.methods;
10803 }
10804
10805 node = node.return;
10806 }
10807
10808 return null;
10809 },
10810 getProps: function () {
10811 var currentFiber = instance.fiber;
10812 return currentFiber.memoizedProps;
10813 },
10814 getScopedNodes: function () {
10815 var currentFiber = instance.fiber;
10816 var child = currentFiber.child;
10817 var scopedNodes = [];
10818
10819 if (child !== null) {
10820 collectScopedNodesFromChildren(child, fn, scopedNodes);
10821 }
10822
10823 return scopedNodes.length === 0 ? null : scopedNodes;
10824 }
10825 };
10826}
10827
10828function markUpdate(workInProgress) {
10829 // Tag the fiber with an update effect. This turns a Placement into
10830 // a PlacementAndUpdate.
10831 workInProgress.effectTag |= Update;
10832}
10833
10834function markRef$1(workInProgress) {
10835 workInProgress.effectTag |= Ref;
10836}
10837
10838var appendAllChildren;
10839var updateHostContainer;
10840var updateHostComponent$1;
10841var updateHostText$1;
10842
10843if (supportsMutation) {
10844 // Mutation mode
10845 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
10846 // We only have the top Fiber that was created but we need recurse down its
10847 // children to find all the terminal nodes.
10848 var node = workInProgress.child;
10849
10850 while (node !== null) {
10851 if (node.tag === HostComponent || node.tag === HostText) {
10852 appendInitialChild(parent, node.stateNode);
10853 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
10854 appendInitialChild(parent, node.stateNode.instance);
10855 } else if (node.tag === HostPortal) {// If we have a portal child, then we don't want to traverse
10856 // down its children. Instead, we'll get insertions from each child in
10857 // the portal directly.
10858 } else if (node.child !== null) {
10859 node.child.return = node;
10860 node = node.child;
10861 continue;
10862 }
10863
10864 if (node === workInProgress) {
10865 return;
10866 }
10867
10868 while (node.sibling === null) {
10869 if (node.return === null || node.return === workInProgress) {
10870 return;
10871 }
10872
10873 node = node.return;
10874 }
10875
10876 node.sibling.return = node.return;
10877 node = node.sibling;
10878 }
10879 };
10880
10881 updateHostContainer = function (workInProgress) {// Noop
10882 };
10883
10884 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
10885 // If we have an alternate, that means this is an update and we need to
10886 // schedule a side-effect to do the updates.
10887 var oldProps = current.memoizedProps;
10888
10889 if (oldProps === newProps) {
10890 // In mutation mode, this is sufficient for a bailout because
10891 // we won't touch this node even if children changed.
10892 return;
10893 } // If we get updated because one of our children updated, we don't
10894 // have newProps so we'll have to reuse them.
10895 // TODO: Split the update API as separate for the props vs. children.
10896 // Even better would be if children weren't special cased at all tho.
10897
10898
10899 var instance = workInProgress.stateNode;
10900 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
10901 // component is hitting the resume path. Figure out why. Possibly
10902 // related to `hidden`.
10903
10904 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
10905
10906 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
10907 // is a new ref we mark this as an update. All the work is done in commitWork.
10908
10909 if (updatePayload) {
10910 markUpdate(workInProgress);
10911 }
10912 };
10913
10914 updateHostText$1 = function (current, workInProgress, oldText, newText) {
10915 // If the text differs, mark it as an update. All the work in done in commitWork.
10916 if (oldText !== newText) {
10917 markUpdate(workInProgress);
10918 }
10919 };
10920} else if (supportsPersistence) {
10921 // Persistent host tree mode
10922 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
10923 // We only have the top Fiber that was created but we need recurse down its
10924 // children to find all the terminal nodes.
10925 var node = workInProgress.child;
10926
10927 while (node !== null) {
10928 // eslint-disable-next-line no-labels
10929 branches: if (node.tag === HostComponent) {
10930 var instance = node.stateNode;
10931
10932 if (needsVisibilityToggle && isHidden) {
10933 // This child is inside a timed out tree. Hide it.
10934 var props = node.memoizedProps;
10935 var type = node.type;
10936 instance = cloneHiddenInstance(instance, type, props, node);
10937 }
10938
10939 appendInitialChild(parent, instance);
10940 } else if (node.tag === HostText) {
10941 var _instance = node.stateNode;
10942
10943 if (needsVisibilityToggle && isHidden) {
10944 // This child is inside a timed out tree. Hide it.
10945 var text = node.memoizedProps;
10946 _instance = cloneHiddenTextInstance(_instance, text, node);
10947 }
10948
10949 appendInitialChild(parent, _instance);
10950 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
10951 var _instance2 = node.stateNode.instance;
10952
10953 if (needsVisibilityToggle && isHidden) {
10954 // This child is inside a timed out tree. Hide it.
10955 var _props = node.memoizedProps;
10956 var _type = node.type;
10957 _instance2 = cloneHiddenInstance(_instance2, _type, _props, node);
10958 }
10959
10960 appendInitialChild(parent, _instance2);
10961 } else if (node.tag === HostPortal) {// If we have a portal child, then we don't want to traverse
10962 // down its children. Instead, we'll get insertions from each child in
10963 // the portal directly.
10964 } else if (node.tag === SuspenseComponent) {
10965 if ((node.effectTag & Update) !== NoEffect) {
10966 // Need to toggle the visibility of the primary children.
10967 var newIsHidden = node.memoizedState !== null;
10968
10969 if (newIsHidden) {
10970 var primaryChildParent = node.child;
10971
10972 if (primaryChildParent !== null) {
10973 if (primaryChildParent.child !== null) {
10974 primaryChildParent.child.return = primaryChildParent;
10975 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
10976 }
10977
10978 var fallbackChildParent = primaryChildParent.sibling;
10979
10980 if (fallbackChildParent !== null) {
10981 fallbackChildParent.return = node;
10982 node = fallbackChildParent;
10983 continue;
10984 }
10985 }
10986 }
10987 }
10988
10989 if (node.child !== null) {
10990 // Continue traversing like normal
10991 node.child.return = node;
10992 node = node.child;
10993 continue;
10994 }
10995 } else if (node.child !== null) {
10996 node.child.return = node;
10997 node = node.child;
10998 continue;
10999 } // $FlowFixMe This is correct but Flow is confused by the labeled break.
11000
11001
11002 node = node;
11003
11004 if (node === workInProgress) {
11005 return;
11006 }
11007
11008 while (node.sibling === null) {
11009 if (node.return === null || node.return === workInProgress) {
11010 return;
11011 }
11012
11013 node = node.return;
11014 }
11015
11016 node.sibling.return = node.return;
11017 node = node.sibling;
11018 }
11019 }; // An unfortunate fork of appendAllChildren because we have two different parent types.
11020
11021
11022 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
11023 // We only have the top Fiber that was created but we need recurse down its
11024 // children to find all the terminal nodes.
11025 var node = workInProgress.child;
11026
11027 while (node !== null) {
11028 // eslint-disable-next-line no-labels
11029 branches: if (node.tag === HostComponent) {
11030 var instance = node.stateNode;
11031
11032 if (needsVisibilityToggle && isHidden) {
11033 // This child is inside a timed out tree. Hide it.
11034 var props = node.memoizedProps;
11035 var type = node.type;
11036 instance = cloneHiddenInstance(instance, type, props, node);
11037 }
11038
11039 appendChildToContainerChildSet(containerChildSet, instance);
11040 } else if (node.tag === HostText) {
11041 var _instance3 = node.stateNode;
11042
11043 if (needsVisibilityToggle && isHidden) {
11044 // This child is inside a timed out tree. Hide it.
11045 var text = node.memoizedProps;
11046 _instance3 = cloneHiddenTextInstance(_instance3, text, node);
11047 }
11048
11049 appendChildToContainerChildSet(containerChildSet, _instance3);
11050 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
11051 var _instance4 = node.stateNode.instance;
11052
11053 if (needsVisibilityToggle && isHidden) {
11054 // This child is inside a timed out tree. Hide it.
11055 var _props2 = node.memoizedProps;
11056 var _type2 = node.type;
11057 _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node);
11058 }
11059
11060 appendChildToContainerChildSet(containerChildSet, _instance4);
11061 } else if (node.tag === HostPortal) {// If we have a portal child, then we don't want to traverse
11062 // down its children. Instead, we'll get insertions from each child in
11063 // the portal directly.
11064 } else if (node.tag === SuspenseComponent) {
11065 if ((node.effectTag & Update) !== NoEffect) {
11066 // Need to toggle the visibility of the primary children.
11067 var newIsHidden = node.memoizedState !== null;
11068
11069 if (newIsHidden) {
11070 var primaryChildParent = node.child;
11071
11072 if (primaryChildParent !== null) {
11073 if (primaryChildParent.child !== null) {
11074 primaryChildParent.child.return = primaryChildParent;
11075 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
11076 }
11077
11078 var fallbackChildParent = primaryChildParent.sibling;
11079
11080 if (fallbackChildParent !== null) {
11081 fallbackChildParent.return = node;
11082 node = fallbackChildParent;
11083 continue;
11084 }
11085 }
11086 }
11087 }
11088
11089 if (node.child !== null) {
11090 // Continue traversing like normal
11091 node.child.return = node;
11092 node = node.child;
11093 continue;
11094 }
11095 } else if (node.child !== null) {
11096 node.child.return = node;
11097 node = node.child;
11098 continue;
11099 } // $FlowFixMe This is correct but Flow is confused by the labeled break.
11100
11101
11102 node = node;
11103
11104 if (node === workInProgress) {
11105 return;
11106 }
11107
11108 while (node.sibling === null) {
11109 if (node.return === null || node.return === workInProgress) {
11110 return;
11111 }
11112
11113 node = node.return;
11114 }
11115
11116 node.sibling.return = node.return;
11117 node = node.sibling;
11118 }
11119 };
11120
11121 updateHostContainer = function (workInProgress) {
11122 var portalOrRoot = workInProgress.stateNode;
11123 var childrenUnchanged = workInProgress.firstEffect === null;
11124
11125 if (childrenUnchanged) {// No changes, just reuse the existing instance.
11126 } else {
11127 var container = portalOrRoot.containerInfo;
11128 var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set.
11129
11130 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
11131 portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container.
11132
11133 markUpdate(workInProgress);
11134 finalizeContainerChildren(container, newChildSet);
11135 }
11136 };
11137
11138 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
11139 var currentInstance = current.stateNode;
11140 var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates.
11141 // This guarantees that we can reuse all of them.
11142
11143 var childrenUnchanged = workInProgress.firstEffect === null;
11144
11145 if (childrenUnchanged && oldProps === newProps) {
11146 // No changes, just reuse the existing instance.
11147 // Note that this might release a previous clone.
11148 workInProgress.stateNode = currentInstance;
11149 return;
11150 }
11151
11152 var recyclableInstance = workInProgress.stateNode;
11153 var currentHostContext = getHostContext();
11154 var updatePayload = null;
11155
11156 if (oldProps !== newProps) {
11157 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
11158 }
11159
11160 if (childrenUnchanged && updatePayload === null) {
11161 // No changes, just reuse the existing instance.
11162 // Note that this might release a previous clone.
11163 workInProgress.stateNode = currentInstance;
11164 return;
11165 }
11166
11167 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
11168
11169 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
11170 markUpdate(workInProgress);
11171 }
11172
11173 workInProgress.stateNode = newInstance;
11174
11175 if (childrenUnchanged) {
11176 // If there are no other effects in this tree, we need to flag this node as having one.
11177 // Even though we're not going to use it for anything.
11178 // Otherwise parents won't know that there are new children to propagate upwards.
11179 markUpdate(workInProgress);
11180 } else {
11181 // If children might have changed, we have to add them all to the set.
11182 appendAllChildren(newInstance, workInProgress, false, false);
11183 }
11184 };
11185
11186 updateHostText$1 = function (current, workInProgress, oldText, newText) {
11187 if (oldText !== newText) {
11188 // If the text content differs, we'll create a new text instance for it.
11189 var rootContainerInstance = getRootHostContainer();
11190 var currentHostContext = getHostContext();
11191 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress); // We'll have to mark it as having an effect, even though we won't use the effect for anything.
11192 // This lets the parents know that at least one of their children has changed.
11193
11194 markUpdate(workInProgress);
11195 }
11196 };
11197} else {
11198 // No host operations
11199 updateHostContainer = function (workInProgress) {// Noop
11200 };
11201
11202 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {// Noop
11203 };
11204
11205 updateHostText$1 = function (current, workInProgress, oldText, newText) {// Noop
11206 };
11207}
11208
11209function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
11210 switch (renderState.tailMode) {
11211 case 'hidden':
11212 {
11213 // Any insertions at the end of the tail list after this point
11214 // should be invisible. If there are already mounted boundaries
11215 // anything before them are not considered for collapsing.
11216 // Therefore we need to go through the whole tail to find if
11217 // there are any.
11218 var tailNode = renderState.tail;
11219 var lastTailNode = null;
11220
11221 while (tailNode !== null) {
11222 if (tailNode.alternate !== null) {
11223 lastTailNode = tailNode;
11224 }
11225
11226 tailNode = tailNode.sibling;
11227 } // Next we're simply going to delete all insertions after the
11228 // last rendered item.
11229
11230
11231 if (lastTailNode === null) {
11232 // All remaining items in the tail are insertions.
11233 renderState.tail = null;
11234 } else {
11235 // Detach the insertion after the last node that was already
11236 // inserted.
11237 lastTailNode.sibling = null;
11238 }
11239
11240 break;
11241 }
11242
11243 case 'collapsed':
11244 {
11245 // Any insertions at the end of the tail list after this point
11246 // should be invisible. If there are already mounted boundaries
11247 // anything before them are not considered for collapsing.
11248 // Therefore we need to go through the whole tail to find if
11249 // there are any.
11250 var _tailNode = renderState.tail;
11251 var _lastTailNode = null;
11252
11253 while (_tailNode !== null) {
11254 if (_tailNode.alternate !== null) {
11255 _lastTailNode = _tailNode;
11256 }
11257
11258 _tailNode = _tailNode.sibling;
11259 } // Next we're simply going to delete all insertions after the
11260 // last rendered item.
11261
11262
11263 if (_lastTailNode === null) {
11264 // All remaining items in the tail are insertions.
11265 if (!hasRenderedATailFallback && renderState.tail !== null) {
11266 // We suspended during the head. We want to show at least one
11267 // row at the tail. So we'll keep on and cut off the rest.
11268 renderState.tail.sibling = null;
11269 } else {
11270 renderState.tail = null;
11271 }
11272 } else {
11273 // Detach the insertion after the last node that was already
11274 // inserted.
11275 _lastTailNode.sibling = null;
11276 }
11277
11278 break;
11279 }
11280 }
11281}
11282
11283function completeWork(current, workInProgress, renderExpirationTime) {
11284 var newProps = workInProgress.pendingProps;
11285
11286 switch (workInProgress.tag) {
11287 case IndeterminateComponent:
11288 break;
11289
11290 case LazyComponent:
11291 break;
11292
11293 case SimpleMemoComponent:
11294 case FunctionComponent:
11295 break;
11296
11297 case ClassComponent:
11298 {
11299 var Component = workInProgress.type;
11300
11301 if (isContextProvider(Component)) {
11302 popContext(workInProgress);
11303 }
11304
11305 break;
11306 }
11307
11308 case HostRoot:
11309 {
11310 popHostContainer(workInProgress);
11311 popTopLevelContextObject(workInProgress);
11312 var fiberRoot = workInProgress.stateNode;
11313
11314 if (fiberRoot.pendingContext) {
11315 fiberRoot.context = fiberRoot.pendingContext;
11316 fiberRoot.pendingContext = null;
11317 }
11318
11319 if (current === null || current.child === null) {
11320 // If we hydrated, pop so that we can delete any remaining children
11321 // that weren't hydrated.
11322 var wasHydrated = popHydrationState(workInProgress);
11323
11324 if (wasHydrated) {
11325 // If we hydrated, then we'll need to schedule an update for
11326 // the commit side-effects on the root.
11327 markUpdate(workInProgress);
11328 }
11329 }
11330
11331 updateHostContainer(workInProgress);
11332 break;
11333 }
11334
11335 case HostComponent:
11336 {
11337 popHostContext(workInProgress);
11338 var rootContainerInstance = getRootHostContainer();
11339 var type = workInProgress.type;
11340
11341 if (current !== null && workInProgress.stateNode != null) {
11342 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
11343
11344 if (enableFlareAPI) {
11345 var prevListeners = current.memoizedProps.listeners;
11346 var nextListeners = newProps.listeners;
11347
11348 if (prevListeners !== nextListeners) {
11349 markUpdate(workInProgress);
11350 }
11351 }
11352
11353 if (current.ref !== workInProgress.ref) {
11354 markRef$1(workInProgress);
11355 }
11356 } else {
11357 if (!newProps) {
11358 (function () {
11359 if (!(workInProgress.stateNode !== null)) {
11360 {
11361 throw ReactError(Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue."));
11362 }
11363 }
11364 })(); // This can happen when we abort work.
11365
11366
11367 break;
11368 }
11369
11370 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
11371 // "stack" as the parent. Then append children as we go in beginWork
11372 // or completeWork depending on we want to add then top->down or
11373 // bottom->up. Top->down is faster in IE11.
11374
11375 var _wasHydrated = popHydrationState(workInProgress);
11376
11377 if (_wasHydrated) {
11378 // TODO: Move this and createInstance step into the beginPhase
11379 // to consolidate.
11380 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
11381 // If changes to the hydrated node needs to be applied at the
11382 // commit-phase we mark this as such.
11383 markUpdate(workInProgress);
11384 }
11385
11386 if (enableFlareAPI) {
11387 var listeners = newProps.listeners;
11388
11389 if (listeners != null) {
11390 updateEventListeners(listeners, workInProgress, rootContainerInstance);
11391 }
11392 }
11393 } else {
11394 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
11395 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
11396
11397 workInProgress.stateNode = instance;
11398
11399 if (enableFlareAPI) {
11400 var _listeners = newProps.listeners;
11401
11402 if (_listeners != null) {
11403 updateEventListeners(_listeners, workInProgress, rootContainerInstance);
11404 }
11405 } // Certain renderers require commit-time effects for initial mount.
11406 // (eg DOM renderer supports auto-focus for certain elements).
11407 // Make sure such renderers get scheduled for later work.
11408
11409
11410 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
11411 markUpdate(workInProgress);
11412 }
11413 }
11414
11415 if (workInProgress.ref !== null) {
11416 // If there is a ref on a host node we need to schedule a callback
11417 markRef$1(workInProgress);
11418 }
11419 }
11420
11421 break;
11422 }
11423
11424 case HostText:
11425 {
11426 var newText = newProps;
11427
11428 if (current && workInProgress.stateNode != null) {
11429 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
11430 // to schedule a side-effect to do the updates.
11431
11432 updateHostText$1(current, workInProgress, oldText, newText);
11433 } else {
11434 if (typeof newText !== 'string') {
11435 (function () {
11436 if (!(workInProgress.stateNode !== null)) {
11437 {
11438 throw ReactError(Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue."));
11439 }
11440 }
11441 })(); // This can happen when we abort work.
11442
11443 }
11444
11445 var _rootContainerInstance = getRootHostContainer();
11446
11447 var _currentHostContext = getHostContext();
11448
11449 var _wasHydrated2 = popHydrationState(workInProgress);
11450
11451 if (_wasHydrated2) {
11452 if (prepareToHydrateHostTextInstance(workInProgress)) {
11453 markUpdate(workInProgress);
11454 }
11455 } else {
11456 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
11457 }
11458 }
11459
11460 break;
11461 }
11462
11463 case ForwardRef:
11464 break;
11465
11466 case SuspenseComponent:
11467 {
11468 popSuspenseContext(workInProgress);
11469 var nextState = workInProgress.memoizedState;
11470
11471 if (enableSuspenseServerRenderer) {
11472 if (nextState !== null && nextState.dehydrated !== null) {
11473 if (current === null) {
11474 var _wasHydrated3 = popHydrationState(workInProgress);
11475
11476 (function () {
11477 if (!_wasHydrated3) {
11478 {
11479 throw ReactError(Error("A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React."));
11480 }
11481 }
11482 })();
11483
11484 prepareToHydrateHostSuspenseInstance(workInProgress);
11485
11486 if (enableSchedulerTracing) {
11487 markSpawnedWork(Never);
11488 }
11489
11490 return null;
11491 } else {
11492 // We should never have been in a hydration state if we didn't have a current.
11493 // However, in some of those paths, we might have reentered a hydration state
11494 // and then we might be inside a hydration state. In that case, we'll need to
11495 // exit out of it.
11496 resetHydrationState();
11497
11498 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
11499 // This boundary did not suspend so it's now hydrated and unsuspended.
11500 workInProgress.memoizedState = null;
11501 } // If nothing suspended, we need to schedule an effect to mark this boundary
11502 // as having hydrated so events know that they're free be invoked.
11503 // It's also a signal to replay events and the suspense callback.
11504 // If something suspended, schedule an effect to attach retry listeners.
11505 // So we might as well always mark this.
11506
11507
11508 workInProgress.effectTag |= Update;
11509 return null;
11510 }
11511 }
11512 }
11513
11514 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
11515 // Something suspended. Re-render with the fallback children.
11516 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
11517
11518 return workInProgress;
11519 }
11520
11521 var nextDidTimeout = nextState !== null;
11522 var prevDidTimeout = false;
11523
11524 if (current === null) {
11525 // In cases where we didn't find a suitable hydration boundary we never
11526 // put this in dehydrated mode, but we still need to pop the hydration
11527 // state since we might be inside the insertion tree.
11528 popHydrationState(workInProgress);
11529 } else {
11530 var prevState = current.memoizedState;
11531 prevDidTimeout = prevState !== null;
11532
11533 if (!nextDidTimeout && prevState !== null) {
11534 // We just switched from the fallback to the normal children.
11535 // Delete the fallback.
11536 // TODO: Would it be better to store the fallback fragment on
11537 // the stateNode during the begin phase?
11538 var currentFallbackChild = current.child.sibling;
11539
11540 if (currentFallbackChild !== null) {
11541 // Deletions go at the beginning of the return fiber's effect list
11542 var first = workInProgress.firstEffect;
11543
11544 if (first !== null) {
11545 workInProgress.firstEffect = currentFallbackChild;
11546 currentFallbackChild.nextEffect = first;
11547 } else {
11548 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
11549 currentFallbackChild.nextEffect = null;
11550 }
11551
11552 currentFallbackChild.effectTag = Deletion;
11553 }
11554 }
11555 }
11556
11557 if (nextDidTimeout && !prevDidTimeout) {
11558 // If this subtreee is running in batched mode we can suspend,
11559 // otherwise we won't suspend.
11560 // TODO: This will still suspend a synchronous tree if anything
11561 // in the concurrent tree already suspended during this render.
11562 // This is a known bug.
11563 if ((workInProgress.mode & BatchedMode) !== NoMode) {
11564 // TODO: Move this back to throwException because this is too late
11565 // if this is a large tree which is common for initial loads. We
11566 // don't know if we should restart a render or not until we get
11567 // this marker, and this is too late.
11568 // If this render already had a ping or lower pri updates,
11569 // and this is the first time we know we're going to suspend we
11570 // should be able to immediately restart from within throwException.
11571 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
11572
11573 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
11574 // If this was in an invisible tree or a new render, then showing
11575 // this boundary is ok.
11576 renderDidSuspend();
11577 } else {
11578 // Otherwise, we're going to have to hide content so we should
11579 // suspend for longer if possible.
11580 renderDidSuspendDelayIfPossible();
11581 }
11582 }
11583 }
11584
11585 if (supportsPersistence) {
11586 // TODO: Only schedule updates if not prevDidTimeout.
11587 if (nextDidTimeout) {
11588 // If this boundary just timed out, schedule an effect to attach a
11589 // retry listener to the proimse. This flag is also used to hide the
11590 // primary children.
11591 workInProgress.effectTag |= Update;
11592 }
11593 }
11594
11595 if (supportsMutation) {
11596 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
11597 if (nextDidTimeout || prevDidTimeout) {
11598 // If this boundary just timed out, schedule an effect to attach a
11599 // retry listener to the proimse. This flag is also used to hide the
11600 // primary children. In mutation mode, we also need the flag to
11601 // *unhide* children that were previously hidden, so check if the
11602 // is currently timed out, too.
11603 workInProgress.effectTag |= Update;
11604 }
11605 }
11606
11607 if (enableSuspenseCallback && workInProgress.updateQueue !== null && workInProgress.memoizedProps.suspenseCallback != null) {
11608 // Always notify the callback
11609 workInProgress.effectTag |= Update;
11610 }
11611
11612 break;
11613 }
11614
11615 case Fragment:
11616 break;
11617
11618 case Mode:
11619 break;
11620
11621 case Profiler:
11622 break;
11623
11624 case HostPortal:
11625 popHostContainer(workInProgress);
11626 updateHostContainer(workInProgress);
11627 break;
11628
11629 case ContextProvider:
11630 // Pop provider fiber
11631 popProvider(workInProgress);
11632 break;
11633
11634 case ContextConsumer:
11635 break;
11636
11637 case MemoComponent:
11638 break;
11639
11640 case IncompleteClassComponent:
11641 {
11642 // Same as class component case. I put it down here so that the tags are
11643 // sequential to ensure this switch is compiled to a jump table.
11644 var _Component = workInProgress.type;
11645
11646 if (isContextProvider(_Component)) {
11647 popContext(workInProgress);
11648 }
11649
11650 break;
11651 }
11652
11653 case SuspenseListComponent:
11654 {
11655 popSuspenseContext(workInProgress);
11656 var renderState = workInProgress.memoizedState;
11657
11658 if (renderState === null) {
11659 // We're running in the default, "independent" mode. We don't do anything
11660 // in this mode.
11661 break;
11662 }
11663
11664 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
11665 var renderedTail = renderState.rendering;
11666
11667 if (renderedTail === null) {
11668 // We just rendered the head.
11669 if (!didSuspendAlready) {
11670 // This is the first pass. We need to figure out if anything is still
11671 // suspended in the rendered set.
11672 // If new content unsuspended, but there's still some content that
11673 // didn't. Then we need to do a second pass that forces everything
11674 // to keep showing their fallbacks.
11675 // We might be suspended if something in this render pass suspended, or
11676 // something in the previous committed pass suspended. Otherwise,
11677 // there's no chance so we can skip the expensive call to
11678 // findFirstSuspended.
11679 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
11680
11681 if (!cannotBeSuspended) {
11682 var row = workInProgress.child;
11683
11684 while (row !== null) {
11685 var suspended = findFirstSuspended(row);
11686
11687 if (suspended !== null) {
11688 didSuspendAlready = true;
11689 workInProgress.effectTag |= DidCapture;
11690 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
11691 // part of the second pass. In that case nothing will subscribe to
11692 // its thennables. Instead, we'll transfer its thennables to the
11693 // SuspenseList so that it can retry if they resolve.
11694 // There might be multiple of these in the list but since we're
11695 // going to wait for all of them anyway, it doesn't really matter
11696 // which ones gets to ping. In theory we could get clever and keep
11697 // track of how many dependencies remain but it gets tricky because
11698 // in the meantime, we can add/remove/change items and dependencies.
11699 // We might bail out of the loop before finding any but that
11700 // doesn't matter since that means that the other boundaries that
11701 // we did find already has their listeners attached.
11702
11703 var newThennables = suspended.updateQueue;
11704
11705 if (newThennables !== null) {
11706 workInProgress.updateQueue = newThennables;
11707 workInProgress.effectTag |= Update;
11708 } // Rerender the whole list, but this time, we'll force fallbacks
11709 // to stay in place.
11710 // Reset the effect list before doing the second pass since that's now invalid.
11711
11712
11713 workInProgress.firstEffect = workInProgress.lastEffect = null; // Reset the child fibers to their original state.
11714
11715 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
11716 // rerender the children.
11717
11718 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
11719 return workInProgress.child;
11720 }
11721
11722 row = row.sibling;
11723 }
11724 }
11725 } else {
11726 cutOffTailIfNeeded(renderState, false);
11727 } // Next we're going to render the tail.
11728
11729 } else {
11730 // Append the rendered row to the child list.
11731 if (!didSuspendAlready) {
11732 var _suspended = findFirstSuspended(renderedTail);
11733
11734 if (_suspended !== null) {
11735 workInProgress.effectTag |= DidCapture;
11736 didSuspendAlready = true;
11737 cutOffTailIfNeeded(renderState, true); // This might have been modified.
11738
11739 if (renderState.tail === null && renderState.tailMode === 'hidden') {
11740 // We need to delete the row we just rendered.
11741 // Ensure we transfer the update queue to the parent.
11742 var _newThennables = _suspended.updateQueue;
11743
11744 if (_newThennables !== null) {
11745 workInProgress.updateQueue = _newThennables;
11746 workInProgress.effectTag |= Update;
11747 } // Reset the effect list to what it w as before we rendered this
11748 // child. The nested children have already appended themselves.
11749
11750
11751 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
11752
11753 if (lastEffect !== null) {
11754 lastEffect.nextEffect = null;
11755 } // We're done.
11756
11757
11758 return null;
11759 }
11760 } else if (now() > renderState.tailExpiration && renderExpirationTime > Never) {
11761 // We have now passed our CPU deadline and we'll just give up further
11762 // attempts to render the main content and only render fallbacks.
11763 // The assumption is that this is usually faster.
11764 workInProgress.effectTag |= DidCapture;
11765 didSuspendAlready = true;
11766 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
11767 // to get it started back up to attempt the next item. If we can show
11768 // them, then they really have the same priority as this render.
11769 // So we'll pick it back up the very next render pass once we've had
11770 // an opportunity to yield for paint.
11771
11772 var nextPriority = renderExpirationTime - 1;
11773 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
11774
11775 if (enableSchedulerTracing) {
11776 markSpawnedWork(nextPriority);
11777 }
11778 }
11779 }
11780
11781 if (renderState.isBackwards) {
11782 // The effect list of the backwards tail will have been added
11783 // to the end. This breaks the guarantee that life-cycles fire in
11784 // sibling order but that isn't a strong guarantee promised by React.
11785 // Especially since these might also just pop in during future commits.
11786 // Append to the beginning of the list.
11787 renderedTail.sibling = workInProgress.child;
11788 workInProgress.child = renderedTail;
11789 } else {
11790 var previousSibling = renderState.last;
11791
11792 if (previousSibling !== null) {
11793 previousSibling.sibling = renderedTail;
11794 } else {
11795 workInProgress.child = renderedTail;
11796 }
11797
11798 renderState.last = renderedTail;
11799 }
11800 }
11801
11802 if (renderState.tail !== null) {
11803 // We still have tail rows to render.
11804 if (renderState.tailExpiration === 0) {
11805 // Heuristic for how long we're willing to spend rendering rows
11806 // until we just give up and show what we have so far.
11807 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
11808 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS;
11809 } // Pop a row.
11810
11811
11812 var next = renderState.tail;
11813 renderState.rendering = next;
11814 renderState.tail = next.sibling;
11815 renderState.lastEffect = workInProgress.lastEffect;
11816 next.sibling = null; // Restore the context.
11817 // TODO: We can probably just avoid popping it instead and only
11818 // setting it the first time we go from not suspended to suspended.
11819
11820 var suspenseContext = suspenseStackCursor.current;
11821
11822 if (didSuspendAlready) {
11823 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
11824 } else {
11825 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
11826 }
11827
11828 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
11829
11830 return next;
11831 }
11832
11833 break;
11834 }
11835
11836 case FundamentalComponent:
11837 {
11838 if (enableFundamentalAPI) {
11839 var fundamentalImpl = workInProgress.type.impl;
11840 var fundamentalInstance = workInProgress.stateNode;
11841
11842 if (fundamentalInstance === null) {
11843 var getInitialState = fundamentalImpl.getInitialState;
11844 var fundamentalState;
11845
11846 if (getInitialState !== undefined) {
11847 fundamentalState = getInitialState(newProps);
11848 }
11849
11850 fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance(workInProgress, newProps, fundamentalImpl, fundamentalState || {});
11851
11852 var _instance5 = getFundamentalComponentInstance(fundamentalInstance);
11853
11854 fundamentalInstance.instance = _instance5;
11855
11856 if (fundamentalImpl.reconcileChildren === false) {
11857 return null;
11858 }
11859
11860 appendAllChildren(_instance5, workInProgress, false, false);
11861 mountFundamentalComponent(fundamentalInstance);
11862 } else {
11863 // We fire update in commit phase
11864 var prevProps = fundamentalInstance.props;
11865 fundamentalInstance.prevProps = prevProps;
11866 fundamentalInstance.props = newProps;
11867 fundamentalInstance.currentFiber = workInProgress;
11868
11869 if (supportsPersistence) {
11870 var _instance6 = cloneFundamentalInstance(fundamentalInstance);
11871
11872 fundamentalInstance.instance = _instance6;
11873 appendAllChildren(_instance6, workInProgress, false, false);
11874 }
11875
11876 var shouldUpdate = shouldUpdateFundamentalComponent(fundamentalInstance);
11877
11878 if (shouldUpdate) {
11879 markUpdate(workInProgress);
11880 }
11881 }
11882 }
11883
11884 break;
11885 }
11886
11887 case ScopeComponent:
11888 {
11889 if (enableScopeAPI) {
11890 if (current === null) {
11891 var _type3 = workInProgress.type;
11892 var scopeInstance = {
11893 fiber: workInProgress,
11894 methods: null
11895 };
11896 workInProgress.stateNode = scopeInstance;
11897 scopeInstance.methods = createScopeMethods(_type3, scopeInstance);
11898
11899 if (enableFlareAPI) {
11900 var _listeners2 = newProps.listeners;
11901
11902 if (_listeners2 != null) {
11903 var _rootContainerInstance2 = getRootHostContainer();
11904
11905 updateEventListeners(_listeners2, workInProgress, _rootContainerInstance2);
11906 }
11907 }
11908
11909 if (workInProgress.ref !== null) {
11910 markRef$1(workInProgress);
11911 markUpdate(workInProgress);
11912 }
11913 } else {
11914 if (enableFlareAPI) {
11915 var _prevListeners = current.memoizedProps.listeners;
11916 var _nextListeners = newProps.listeners;
11917
11918 if (_prevListeners !== _nextListeners || workInProgress.ref !== null) {
11919 markUpdate(workInProgress);
11920 }
11921 } else {
11922 if (workInProgress.ref !== null) {
11923 markUpdate(workInProgress);
11924 }
11925 }
11926
11927 if (current.ref !== workInProgress.ref) {
11928 markRef$1(workInProgress);
11929 }
11930 }
11931 }
11932
11933 break;
11934 }
11935
11936 default:
11937 (function () {
11938 {
11939 {
11940 throw ReactError(Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue."));
11941 }
11942 }
11943 })();
11944
11945 }
11946
11947 return null;
11948}
11949
11950function unwindWork(workInProgress, renderExpirationTime) {
11951 switch (workInProgress.tag) {
11952 case ClassComponent:
11953 {
11954 var Component = workInProgress.type;
11955
11956 if (isContextProvider(Component)) {
11957 popContext(workInProgress);
11958 }
11959
11960 var effectTag = workInProgress.effectTag;
11961
11962 if (effectTag & ShouldCapture) {
11963 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
11964 return workInProgress;
11965 }
11966
11967 return null;
11968 }
11969
11970 case HostRoot:
11971 {
11972 popHostContainer(workInProgress);
11973 popTopLevelContextObject(workInProgress);
11974 var _effectTag = workInProgress.effectTag;
11975
11976 (function () {
11977 if (!((_effectTag & DidCapture) === NoEffect)) {
11978 {
11979 throw ReactError(Error("The root failed to unmount after an error. This is likely a bug in React. Please file an issue."));
11980 }
11981 }
11982 })();
11983
11984 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
11985 return workInProgress;
11986 }
11987
11988 case HostComponent:
11989 {
11990 // TODO: popHydrationState
11991 popHostContext(workInProgress);
11992 return null;
11993 }
11994
11995 case SuspenseComponent:
11996 {
11997 popSuspenseContext(workInProgress);
11998
11999 if (enableSuspenseServerRenderer) {
12000 var suspenseState = workInProgress.memoizedState;
12001
12002 if (suspenseState !== null && suspenseState.dehydrated !== null) {
12003 (function () {
12004 if (!(workInProgress.alternate !== null)) {
12005 {
12006 throw ReactError(Error("Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue."));
12007 }
12008 }
12009 })();
12010
12011 resetHydrationState();
12012 }
12013 }
12014
12015 var _effectTag2 = workInProgress.effectTag;
12016
12017 if (_effectTag2 & ShouldCapture) {
12018 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
12019
12020 return workInProgress;
12021 }
12022
12023 return null;
12024 }
12025
12026 case SuspenseListComponent:
12027 {
12028 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
12029 // caught by a nested boundary. If not, it should bubble through.
12030
12031 return null;
12032 }
12033
12034 case HostPortal:
12035 popHostContainer(workInProgress);
12036 return null;
12037
12038 case ContextProvider:
12039 popProvider(workInProgress);
12040 return null;
12041
12042 default:
12043 return null;
12044 }
12045}
12046
12047function unwindInterruptedWork(interruptedWork) {
12048 switch (interruptedWork.tag) {
12049 case ClassComponent:
12050 {
12051 var childContextTypes = interruptedWork.type.childContextTypes;
12052
12053 if (childContextTypes !== null && childContextTypes !== undefined) {
12054 popContext(interruptedWork);
12055 }
12056
12057 break;
12058 }
12059
12060 case HostRoot:
12061 {
12062 popHostContainer(interruptedWork);
12063 popTopLevelContextObject(interruptedWork);
12064 break;
12065 }
12066
12067 case HostComponent:
12068 {
12069 popHostContext(interruptedWork);
12070 break;
12071 }
12072
12073 case HostPortal:
12074 popHostContainer(interruptedWork);
12075 break;
12076
12077 case SuspenseComponent:
12078 popSuspenseContext(interruptedWork);
12079 break;
12080
12081 case SuspenseListComponent:
12082 popSuspenseContext(interruptedWork);
12083 break;
12084
12085 case ContextProvider:
12086 popProvider(interruptedWork);
12087 break;
12088
12089 default:
12090 break;
12091 }
12092}
12093
12094function createCapturedValue(value, source) {
12095 // If the value is an error, call this function immediately after it is thrown
12096 // so the stack is accurate.
12097 return {
12098 value: value,
12099 source: source,
12100 stack: getStackByFiberInDevAndProd(source)
12101 };
12102}
12103
12104var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
12105 var funcArgs = Array.prototype.slice.call(arguments, 3);
12106
12107 try {
12108 func.apply(context, funcArgs);
12109 } catch (error) {
12110 this.onError(error);
12111 }
12112};
12113
12114{
12115 // In DEV mode, we swap out invokeGuardedCallback for a special version
12116 // that plays more nicely with the browser's DevTools. The idea is to preserve
12117 // "Pause on exceptions" behavior. Because React wraps all user-provided
12118 // functions in invokeGuardedCallback, and the production version of
12119 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
12120 // like caught exceptions, and the DevTools won't pause unless the developer
12121 // takes the extra step of enabling pause on caught exceptions. This is
12122 // unintuitive, though, because even though React has caught the error, from
12123 // the developer's perspective, the error is uncaught.
12124 //
12125 // To preserve the expected "Pause on exceptions" behavior, we don't use a
12126 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
12127 // DOM node, and call the user-provided callback from inside an event handler
12128 // for that fake event. If the callback throws, the error is "captured" using
12129 // a global event handler. But because the error happens in a different
12130 // event loop context, it does not interrupt the normal program flow.
12131 // Effectively, this gives us try-catch behavior without actually using
12132 // try-catch. Neat!
12133 // Check that the browser supports the APIs we need to implement our special
12134 // DEV version of invokeGuardedCallback
12135 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
12136 var fakeNode = document.createElement('react');
12137
12138 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
12139 // If document doesn't exist we know for sure we will crash in this method
12140 // when we call document.createEvent(). However this can cause confusing
12141 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
12142 // So we preemptively throw with a better message instead.
12143 (function () {
12144 if (!(typeof document !== 'undefined')) {
12145 {
12146 throw ReactError(Error("The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous."));
12147 }
12148 }
12149 })();
12150
12151 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
12152 // set this to true at the beginning, then set it to false right after
12153 // calling the function. If the function errors, `didError` will never be
12154 // set to false. This strategy works even if the browser is flaky and
12155 // fails to call our global error handler, because it doesn't rely on
12156 // the error event at all.
12157
12158 var didError = true; // Keeps track of the value of window.event so that we can reset it
12159 // during the callback to let user code access window.event in the
12160 // browsers that support it.
12161
12162 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
12163 // dispatching: https://github.com/facebook/react/issues/13688
12164
12165 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
12166 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
12167 // call the user-provided callback.
12168
12169 var funcArgs = Array.prototype.slice.call(arguments, 3);
12170
12171 function callCallback() {
12172 // We immediately remove the callback from event listeners so that
12173 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
12174 // nested call would trigger the fake event handlers of any call higher
12175 // in the stack.
12176 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
12177 // window.event assignment in both IE <= 10 as they throw an error
12178 // "Member not found" in strict mode, and in Firefox which does not
12179 // support window.event.
12180
12181 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
12182 window.event = windowEvent;
12183 }
12184
12185 func.apply(context, funcArgs);
12186 didError = false;
12187 } // Create a global error event handler. We use this to capture the value
12188 // that was thrown. It's possible that this error handler will fire more
12189 // than once; for example, if non-React code also calls `dispatchEvent`
12190 // and a handler for that event throws. We should be resilient to most of
12191 // those cases. Even if our error event handler fires more than once, the
12192 // last error event is always used. If the callback actually does error,
12193 // we know that the last error event is the correct one, because it's not
12194 // possible for anything else to have happened in between our callback
12195 // erroring and the code that follows the `dispatchEvent` call below. If
12196 // the callback doesn't error, but the error event was fired, we know to
12197 // ignore it because `didError` will be false, as described above.
12198
12199
12200 var error; // Use this to track whether the error event is ever called.
12201
12202 var didSetError = false;
12203 var isCrossOriginError = false;
12204
12205 function handleWindowError(event) {
12206 error = event.error;
12207 didSetError = true;
12208
12209 if (error === null && event.colno === 0 && event.lineno === 0) {
12210 isCrossOriginError = true;
12211 }
12212
12213 if (event.defaultPrevented) {
12214 // Some other error handler has prevented default.
12215 // Browsers silence the error report if this happens.
12216 // We'll remember this to later decide whether to log it or not.
12217 if (error != null && typeof error === 'object') {
12218 try {
12219 error._suppressLogging = true;
12220 } catch (inner) {// Ignore.
12221 }
12222 }
12223 }
12224 } // Create a fake event type.
12225
12226
12227 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
12228
12229 window.addEventListener('error', handleWindowError);
12230 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
12231 // errors, it will trigger our global error handler.
12232
12233 evt.initEvent(evtType, false, false);
12234 fakeNode.dispatchEvent(evt);
12235
12236 if (windowEventDescriptor) {
12237 Object.defineProperty(window, 'event', windowEventDescriptor);
12238 }
12239
12240 if (didError) {
12241 if (!didSetError) {
12242 // The callback errored, but the error event never fired.
12243 error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.');
12244 } else if (isCrossOriginError) {
12245 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.');
12246 }
12247
12248 this.onError(error);
12249 } // Remove our event listeners
12250
12251
12252 window.removeEventListener('error', handleWindowError);
12253 };
12254
12255 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
12256 }
12257}
12258
12259var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
12260
12261var hasError = false;
12262var caughtError = null; // Used by event system to capture/rethrow the first error.
12263
12264var reporter = {
12265 onError: function (error) {
12266 hasError = true;
12267 caughtError = error;
12268 }
12269};
12270/**
12271 * Call a function while guarding against errors that happens within it.
12272 * Returns an error if it throws, otherwise null.
12273 *
12274 * In production, this is implemented using a try-catch. The reason we don't
12275 * use a try-catch directly is so that we can swap out a different
12276 * implementation in DEV mode.
12277 *
12278 * @param {String} name of the guard to use for logging or debugging
12279 * @param {Function} func The function to invoke
12280 * @param {*} context The context to use when calling the function
12281 * @param {...*} args Arguments for function
12282 */
12283
12284function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
12285 hasError = false;
12286 caughtError = null;
12287 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
12288}
12289/**
12290 * Same as invokeGuardedCallback, but instead of returning an error, it stores
12291 * it in a global so it can be rethrown by `rethrowCaughtError` later.
12292 * TODO: See if caughtError and rethrowError can be unified.
12293 *
12294 * @param {String} name of the guard to use for logging or debugging
12295 * @param {Function} func The function to invoke
12296 * @param {*} context The context to use when calling the function
12297 * @param {...*} args Arguments for function
12298 */
12299
12300
12301/**
12302 * During execution of guarded functions we will capture the first error which
12303 * we will rethrow to be handled by the top level error handler.
12304 */
12305
12306
12307function hasCaughtError() {
12308 return hasError;
12309}
12310function clearCaughtError() {
12311 if (hasError) {
12312 var error = caughtError;
12313 hasError = false;
12314 caughtError = null;
12315 return error;
12316 } else {
12317 (function () {
12318 {
12319 {
12320 throw ReactError(Error("clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue."));
12321 }
12322 }
12323 })();
12324 }
12325}
12326
12327// This module is forked in different environments.
12328// By default, return `true` to log errors to the console.
12329// Forks can return `false` if this isn't desirable.
12330function showErrorDialog(capturedError) {
12331 return true;
12332}
12333
12334function logCapturedError(capturedError) {
12335 var logError = showErrorDialog(capturedError); // Allow injected showErrorDialog() to prevent default console.error logging.
12336 // This enables renderers like ReactNative to better manage redbox behavior.
12337
12338 if (logError === false) {
12339 return;
12340 }
12341
12342 var error = capturedError.error;
12343
12344 {
12345 var componentName = capturedError.componentName,
12346 componentStack = capturedError.componentStack,
12347 errorBoundaryName = capturedError.errorBoundaryName,
12348 errorBoundaryFound = capturedError.errorBoundaryFound,
12349 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
12350 // `preventDefault()` in window `error` handler.
12351 // We record this information as an expando on the error.
12352
12353 if (error != null && error._suppressLogging) {
12354 if (errorBoundaryFound && willRetry) {
12355 // The error is recoverable and was silenced.
12356 // Ignore it and don't print the stack addendum.
12357 // This is handy for testing error boundaries without noise.
12358 return;
12359 } // The error is fatal. Since the silencing might have
12360 // been accidental, we'll surface it anyway.
12361 // However, the browser would have silenced the original error
12362 // so we'll print it first, and then print the stack addendum.
12363
12364
12365 console.error(error); // For a more detailed description of this block, see:
12366 // https://github.com/facebook/react/pull/13384
12367 }
12368
12369 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
12370 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
12371
12372 if (errorBoundaryFound && errorBoundaryName) {
12373 if (willRetry) {
12374 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
12375 } else {
12376 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
12377 }
12378 } else {
12379 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://fb.me/react-error-boundaries to learn more about error boundaries.';
12380 }
12381
12382 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
12383 // We don't include the original error message and JS stack because the browser
12384 // has already printed it. Even if the application swallows the error, it is still
12385 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
12386
12387 console.error(combinedMessage);
12388 }
12389}
12390
12391var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
12392
12393{
12394 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
12395}
12396
12397var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
12398function logError(boundary, errorInfo) {
12399 var source = errorInfo.source;
12400 var stack = errorInfo.stack;
12401
12402 if (stack === null && source !== null) {
12403 stack = getStackByFiberInDevAndProd(source);
12404 }
12405
12406 var capturedError = {
12407 componentName: source !== null ? getComponentName(source.type) : null,
12408 componentStack: stack !== null ? stack : '',
12409 error: errorInfo.value,
12410 errorBoundary: null,
12411 errorBoundaryName: null,
12412 errorBoundaryFound: false,
12413 willRetry: false
12414 };
12415
12416 if (boundary !== null && boundary.tag === ClassComponent) {
12417 capturedError.errorBoundary = boundary.stateNode;
12418 capturedError.errorBoundaryName = getComponentName(boundary.type);
12419 capturedError.errorBoundaryFound = true;
12420 capturedError.willRetry = true;
12421 }
12422
12423 try {
12424 logCapturedError(capturedError);
12425 } catch (e) {
12426 // This method must not throw, or React internal state will get messed up.
12427 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
12428 // we want to report this error outside of the normal stack as a last resort.
12429 // https://github.com/facebook/react/issues/13188
12430 setTimeout(function () {
12431 throw e;
12432 });
12433 }
12434}
12435
12436var callComponentWillUnmountWithTimer = function (current, instance) {
12437 startPhaseTimer(current, 'componentWillUnmount');
12438 instance.props = current.memoizedProps;
12439 instance.state = current.memoizedState;
12440 instance.componentWillUnmount();
12441 stopPhaseTimer();
12442}; // Capture errors so they don't interrupt unmounting.
12443
12444
12445function safelyCallComponentWillUnmount(current, instance) {
12446 {
12447 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
12448
12449 if (hasCaughtError()) {
12450 var unmountError = clearCaughtError();
12451 captureCommitPhaseError(current, unmountError);
12452 }
12453 }
12454}
12455
12456function safelyDetachRef(current) {
12457 var ref = current.ref;
12458
12459 if (ref !== null) {
12460 if (typeof ref === 'function') {
12461 {
12462 invokeGuardedCallback(null, ref, null, null);
12463
12464 if (hasCaughtError()) {
12465 var refError = clearCaughtError();
12466 captureCommitPhaseError(current, refError);
12467 }
12468 }
12469 } else {
12470 ref.current = null;
12471 }
12472 }
12473}
12474
12475function safelyCallDestroy(current, destroy) {
12476 {
12477 invokeGuardedCallback(null, destroy, null);
12478
12479 if (hasCaughtError()) {
12480 var error = clearCaughtError();
12481 captureCommitPhaseError(current, error);
12482 }
12483 }
12484}
12485
12486function commitBeforeMutationLifeCycles(current, finishedWork) {
12487 switch (finishedWork.tag) {
12488 case FunctionComponent:
12489 case ForwardRef:
12490 case SimpleMemoComponent:
12491 {
12492 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
12493 return;
12494 }
12495
12496 case ClassComponent:
12497 {
12498 if (finishedWork.effectTag & Snapshot) {
12499 if (current !== null) {
12500 var prevProps = current.memoizedProps;
12501 var prevState = current.memoizedState;
12502 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
12503 var instance = finishedWork.stateNode; // We could update instance props and state here,
12504 // but instead we rely on them being set during last render.
12505 // TODO: revisit this when we implement resuming.
12506
12507 {
12508 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12509 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12510 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12511 }
12512 }
12513
12514 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
12515
12516 {
12517 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
12518
12519 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
12520 didWarnSet.add(finishedWork.type);
12521 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
12522 }
12523 }
12524
12525 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
12526 stopPhaseTimer();
12527 }
12528 }
12529
12530 return;
12531 }
12532
12533 case HostRoot:
12534 case HostComponent:
12535 case HostText:
12536 case HostPortal:
12537 case IncompleteClassComponent:
12538 // Nothing to do for these component types
12539 return;
12540
12541 default:
12542 {
12543 (function () {
12544 {
12545 {
12546 throw ReactError(Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."));
12547 }
12548 }
12549 })();
12550 }
12551 }
12552}
12553
12554function commitHookEffectList(unmountTag, mountTag, finishedWork) {
12555 var updateQueue = finishedWork.updateQueue;
12556 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
12557
12558 if (lastEffect !== null) {
12559 var firstEffect = lastEffect.next;
12560 var effect = firstEffect;
12561
12562 do {
12563 if ((effect.tag & unmountTag) !== NoEffect$1) {
12564 // Unmount
12565 var destroy = effect.destroy;
12566 effect.destroy = undefined;
12567
12568 if (destroy !== undefined) {
12569 destroy();
12570 }
12571 }
12572
12573 if ((effect.tag & mountTag) !== NoEffect$1) {
12574 // Mount
12575 var create = effect.create;
12576 effect.destroy = create();
12577
12578 {
12579 var _destroy = effect.destroy;
12580
12581 if (_destroy !== undefined && typeof _destroy !== 'function') {
12582 var addendum = void 0;
12583
12584 if (_destroy === null) {
12585 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
12586 } else if (typeof _destroy.then === 'function') {
12587 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching';
12588 } else {
12589 addendum = ' You returned: ' + _destroy;
12590 }
12591
12592 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
12593 }
12594 }
12595 }
12596
12597 effect = effect.next;
12598 } while (effect !== firstEffect);
12599 }
12600}
12601
12602function commitPassiveHookEffects(finishedWork) {
12603 if ((finishedWork.effectTag & Passive) !== NoEffect) {
12604 switch (finishedWork.tag) {
12605 case FunctionComponent:
12606 case ForwardRef:
12607 case SimpleMemoComponent:
12608 {
12609 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
12610 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
12611 break;
12612 }
12613
12614 default:
12615 break;
12616 }
12617 }
12618}
12619
12620function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
12621 switch (finishedWork.tag) {
12622 case FunctionComponent:
12623 case ForwardRef:
12624 case SimpleMemoComponent:
12625 {
12626 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
12627 break;
12628 }
12629
12630 case ClassComponent:
12631 {
12632 var instance = finishedWork.stateNode;
12633
12634 if (finishedWork.effectTag & Update) {
12635 if (current === null) {
12636 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
12637 // but instead we rely on them being set during last render.
12638 // TODO: revisit this when we implement resuming.
12639
12640 {
12641 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12642 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12643 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12644 }
12645 }
12646
12647 instance.componentDidMount();
12648 stopPhaseTimer();
12649 } else {
12650 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
12651 var prevState = current.memoizedState;
12652 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
12653 // but instead we rely on them being set during last render.
12654 // TODO: revisit this when we implement resuming.
12655
12656 {
12657 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12658 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12659 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12660 }
12661 }
12662
12663 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
12664 stopPhaseTimer();
12665 }
12666 }
12667
12668 var updateQueue = finishedWork.updateQueue;
12669
12670 if (updateQueue !== null) {
12671 {
12672 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12673 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12674 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12675 }
12676 } // We could update instance props and state here,
12677 // but instead we rely on them being set during last render.
12678 // TODO: revisit this when we implement resuming.
12679
12680
12681 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
12682 }
12683
12684 return;
12685 }
12686
12687 case HostRoot:
12688 {
12689 var _updateQueue = finishedWork.updateQueue;
12690
12691 if (_updateQueue !== null) {
12692 var _instance = null;
12693
12694 if (finishedWork.child !== null) {
12695 switch (finishedWork.child.tag) {
12696 case HostComponent:
12697 _instance = getPublicInstance(finishedWork.child.stateNode);
12698 break;
12699
12700 case ClassComponent:
12701 _instance = finishedWork.child.stateNode;
12702 break;
12703 }
12704 }
12705
12706 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
12707 }
12708
12709 return;
12710 }
12711
12712 case HostComponent:
12713 {
12714 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
12715 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
12716 // These effects should only be committed when components are first mounted,
12717 // aka when there is no current/alternate.
12718
12719 if (current === null && finishedWork.effectTag & Update) {
12720 var type = finishedWork.type;
12721 var props = finishedWork.memoizedProps;
12722
12723 }
12724
12725 return;
12726 }
12727
12728 case HostText:
12729 {
12730 // We have no life-cycles associated with text.
12731 return;
12732 }
12733
12734 case HostPortal:
12735 {
12736 // We have no life-cycles associated with portals.
12737 return;
12738 }
12739
12740 case Profiler:
12741 {
12742 if (enableProfilerTimer) {
12743 var onRender = finishedWork.memoizedProps.onRender;
12744
12745 if (typeof onRender === 'function') {
12746 if (enableSchedulerTracing) {
12747 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
12748 } else {
12749 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
12750 }
12751 }
12752 }
12753
12754 return;
12755 }
12756
12757 case SuspenseComponent:
12758 {
12759 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
12760 return;
12761 }
12762
12763 case SuspenseListComponent:
12764 case IncompleteClassComponent:
12765 case FundamentalComponent:
12766 case ScopeComponent:
12767 return;
12768
12769 default:
12770 {
12771 (function () {
12772 {
12773 {
12774 throw ReactError(Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."));
12775 }
12776 }
12777 })();
12778 }
12779 }
12780}
12781
12782function hideOrUnhideAllChildren(finishedWork, isHidden) {
12783 if (supportsMutation) {
12784 // We only have the top Fiber that was inserted but we need to recurse down its
12785 // children to find all the terminal nodes.
12786 var node = finishedWork;
12787
12788 while (true) {
12789 if (node.tag === HostComponent) {
12790 var instance = node.stateNode;
12791
12792 if (isHidden) {
12793 hideInstance(instance);
12794 } else {
12795 unhideInstance(node.stateNode, node.memoizedProps);
12796 }
12797 } else if (node.tag === HostText) {
12798 var _instance3 = node.stateNode;
12799
12800 if (isHidden) {
12801
12802 } else {
12803 unhideTextInstance(_instance3, node.memoizedProps);
12804 }
12805 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
12806 // Found a nested Suspense component that timed out. Skip over the
12807 // primary child fragment, which should remain hidden.
12808 var fallbackChildFragment = node.child.sibling;
12809 fallbackChildFragment.return = node;
12810 node = fallbackChildFragment;
12811 continue;
12812 } else if (node.child !== null) {
12813 node.child.return = node;
12814 node = node.child;
12815 continue;
12816 }
12817
12818 if (node === finishedWork) {
12819 return;
12820 }
12821
12822 while (node.sibling === null) {
12823 if (node.return === null || node.return === finishedWork) {
12824 return;
12825 }
12826
12827 node = node.return;
12828 }
12829
12830 node.sibling.return = node.return;
12831 node = node.sibling;
12832 }
12833 }
12834}
12835
12836function commitAttachRef(finishedWork) {
12837 var ref = finishedWork.ref;
12838
12839 if (ref !== null) {
12840 var instance = finishedWork.stateNode;
12841 var instanceToUse;
12842
12843 switch (finishedWork.tag) {
12844 case HostComponent:
12845 instanceToUse = getPublicInstance(instance);
12846 break;
12847
12848 default:
12849 instanceToUse = instance;
12850 } // Moved outside to ensure DCE works with this flag
12851
12852
12853 if (enableScopeAPI && finishedWork.tag === ScopeComponent) {
12854 instanceToUse = instance.methods;
12855 }
12856
12857 if (typeof ref === 'function') {
12858 ref(instanceToUse);
12859 } else {
12860 {
12861 if (!ref.hasOwnProperty('current')) {
12862 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
12863 }
12864 }
12865
12866 ref.current = instanceToUse;
12867 }
12868 }
12869}
12870
12871function commitDetachRef(current) {
12872 var currentRef = current.ref;
12873
12874 if (currentRef !== null) {
12875 if (typeof currentRef === 'function') {
12876 currentRef(null);
12877 } else {
12878 currentRef.current = null;
12879 }
12880 }
12881} // User-originating errors (lifecycles and refs) should not interrupt
12882// deletion, so don't let them throw. Host-originating errors should
12883// interrupt deletion, so it's okay
12884
12885
12886function commitUnmount(finishedRoot, current, renderPriorityLevel) {
12887 onCommitUnmount(current);
12888
12889 switch (current.tag) {
12890 case FunctionComponent:
12891 case ForwardRef:
12892 case MemoComponent:
12893 case SimpleMemoComponent:
12894 {
12895 var updateQueue = current.updateQueue;
12896
12897 if (updateQueue !== null) {
12898 var lastEffect = updateQueue.lastEffect;
12899
12900 if (lastEffect !== null) {
12901 var firstEffect = lastEffect.next; // When the owner fiber is deleted, the destroy function of a passive
12902 // effect hook is called during the synchronous commit phase. This is
12903 // a concession to implementation complexity. Calling it in the
12904 // passive effect phase (like they usually are, when dependencies
12905 // change during an update) would require either traversing the
12906 // children of the deleted fiber again, or including unmount effects
12907 // as part of the fiber effect list.
12908 //
12909 // Because this is during the sync commit phase, we need to change
12910 // the priority.
12911 //
12912 // TODO: Reconsider this implementation trade off.
12913
12914 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
12915 runWithPriority(priorityLevel, function () {
12916 var effect = firstEffect;
12917
12918 do {
12919 var destroy = effect.destroy;
12920
12921 if (destroy !== undefined) {
12922 safelyCallDestroy(current, destroy);
12923 }
12924
12925 effect = effect.next;
12926 } while (effect !== firstEffect);
12927 });
12928 }
12929 }
12930
12931 break;
12932 }
12933
12934 case ClassComponent:
12935 {
12936 safelyDetachRef(current);
12937 var instance = current.stateNode;
12938
12939 if (typeof instance.componentWillUnmount === 'function') {
12940 safelyCallComponentWillUnmount(current, instance);
12941 }
12942
12943 return;
12944 }
12945
12946 case HostComponent:
12947 {
12948 if (enableFlareAPI) {
12949 var dependencies = current.dependencies;
12950
12951 if (dependencies !== null) {
12952 var respondersMap = dependencies.responders;
12953
12954 if (respondersMap !== null) {
12955 var responderInstances = Array.from(respondersMap.values());
12956
12957 for (var i = 0, length = responderInstances.length; i < length; i++) {
12958 var responderInstance = responderInstances[i];
12959 unmountResponderInstance(responderInstance);
12960 }
12961
12962 dependencies.responders = null;
12963 }
12964 }
12965 }
12966
12967 safelyDetachRef(current);
12968 return;
12969 }
12970
12971 case HostPortal:
12972 {
12973 // TODO: this is recursive.
12974 // We are also not using this parent because
12975 // the portal will get pushed immediately.
12976 if (supportsMutation) {
12977 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
12978 } else if (supportsPersistence) {
12979 emptyPortalContainer(current);
12980 }
12981
12982 return;
12983 }
12984
12985 case FundamentalComponent:
12986 {
12987 if (enableFundamentalAPI) {
12988 var fundamentalInstance = current.stateNode;
12989
12990 if (fundamentalInstance !== null) {
12991 unmountFundamentalComponent(fundamentalInstance);
12992 current.stateNode = null;
12993 }
12994 }
12995
12996 return;
12997 }
12998
12999 case DehydratedFragment:
13000 {
13001 if (enableSuspenseCallback) {
13002 var hydrationCallbacks = finishedRoot.hydrationCallbacks;
13003
13004 if (hydrationCallbacks !== null) {
13005 var onDeleted = hydrationCallbacks.onDeleted;
13006
13007 if (onDeleted) {
13008 onDeleted(current.stateNode);
13009 }
13010 }
13011 }
13012
13013 return;
13014 }
13015
13016 case ScopeComponent:
13017 {
13018 if (enableScopeAPI) {
13019 safelyDetachRef(current);
13020 }
13021 }
13022 }
13023}
13024
13025function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
13026 // While we're inside a removed host node we don't want to call
13027 // removeChild on the inner nodes because they're removed by the top
13028 // call anyway. We also want to call componentWillUnmount on all
13029 // composites before this host node is removed from the tree. Therefore
13030 // we do an inner loop while we're still inside the host node.
13031 var node = root;
13032
13033 while (true) {
13034 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
13035 // Skip portals because commitUnmount() currently visits them recursively.
13036
13037 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
13038 // If we don't use mutation we drill down into portals here instead.
13039 !supportsMutation || node.tag !== HostPortal)) {
13040 node.child.return = node;
13041 node = node.child;
13042 continue;
13043 }
13044
13045 if (node === root) {
13046 return;
13047 }
13048
13049 while (node.sibling === null) {
13050 if (node.return === null || node.return === root) {
13051 return;
13052 }
13053
13054 node = node.return;
13055 }
13056
13057 node.sibling.return = node.return;
13058 node = node.sibling;
13059 }
13060}
13061
13062function detachFiber(current) {
13063 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
13064 // should clear the child pointer of the parent alternate to let this
13065 // get GC:ed but we don't know which for sure which parent is the current
13066 // one so we'll settle for GC:ing the subtree of this child. This child
13067 // itself will be GC:ed when the parent updates the next time.
13068
13069 current.return = null;
13070 current.child = null;
13071 current.memoizedState = null;
13072 current.updateQueue = null;
13073 current.dependencies = null;
13074 current.alternate = null;
13075 current.firstEffect = null;
13076 current.lastEffect = null;
13077 current.pendingProps = null;
13078 current.memoizedProps = null;
13079
13080 if (alternate !== null) {
13081 detachFiber(alternate);
13082 }
13083}
13084
13085function emptyPortalContainer(current) {
13086 if (!supportsPersistence) {
13087 return;
13088 }
13089
13090 var portal = current.stateNode;
13091 var containerInfo = portal.containerInfo;
13092 var emptyChildSet = createContainerChildSet(containerInfo);
13093 replaceContainerChildren(containerInfo, emptyChildSet);
13094}
13095
13096function commitContainer(finishedWork) {
13097 if (!supportsPersistence) {
13098 return;
13099 }
13100
13101 switch (finishedWork.tag) {
13102 case ClassComponent:
13103 case HostComponent:
13104 case HostText:
13105 case FundamentalComponent:
13106 {
13107 return;
13108 }
13109
13110 case HostRoot:
13111 case HostPortal:
13112 {
13113 var portalOrRoot = finishedWork.stateNode;
13114 var containerInfo = portalOrRoot.containerInfo,
13115 pendingChildren = portalOrRoot.pendingChildren;
13116 replaceContainerChildren(containerInfo, pendingChildren);
13117 return;
13118 }
13119
13120 default:
13121 {
13122 (function () {
13123 {
13124 {
13125 throw ReactError(Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."));
13126 }
13127 }
13128 })();
13129 }
13130 }
13131}
13132
13133function getHostParentFiber(fiber) {
13134 var parent = fiber.return;
13135
13136 while (parent !== null) {
13137 if (isHostParent(parent)) {
13138 return parent;
13139 }
13140
13141 parent = parent.return;
13142 }
13143
13144 (function () {
13145 {
13146 {
13147 throw ReactError(Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue."));
13148 }
13149 }
13150 })();
13151}
13152
13153function isHostParent(fiber) {
13154 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
13155}
13156
13157function getHostSibling(fiber) {
13158 // We're going to search forward into the tree until we find a sibling host
13159 // node. Unfortunately, if multiple insertions are done in a row we have to
13160 // search past them. This leads to exponential search for the next sibling.
13161 // TODO: Find a more efficient way to do this.
13162 var node = fiber;
13163
13164 siblings: while (true) {
13165 // If we didn't find anything, let's try the next sibling.
13166 while (node.sibling === null) {
13167 if (node.return === null || isHostParent(node.return)) {
13168 // If we pop out of the root or hit the parent the fiber we are the
13169 // last sibling.
13170 return null;
13171 }
13172
13173 node = node.return;
13174 }
13175
13176 node.sibling.return = node.return;
13177 node = node.sibling;
13178
13179 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
13180 // If it is not host node and, we might have a host node inside it.
13181 // Try to search down until we find one.
13182 if (node.effectTag & Placement) {
13183 // If we don't have a child, try the siblings instead.
13184 continue siblings;
13185 } // If we don't have a child, try the siblings instead.
13186 // We also skip portals because they are not part of this host tree.
13187
13188
13189 if (node.child === null || node.tag === HostPortal) {
13190 continue siblings;
13191 } else {
13192 node.child.return = node;
13193 node = node.child;
13194 }
13195 } // Check if this host node is stable or about to be placed.
13196
13197
13198 if (!(node.effectTag & Placement)) {
13199 // Found it!
13200 return node.stateNode;
13201 }
13202 }
13203}
13204
13205function commitPlacement(finishedWork) {
13206 if (!supportsMutation) {
13207 return;
13208 } // Recursively insert all host nodes into the parent.
13209
13210
13211 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
13212
13213 var parent;
13214 var isContainer;
13215 var parentStateNode = parentFiber.stateNode;
13216
13217 switch (parentFiber.tag) {
13218 case HostComponent:
13219 parent = parentStateNode;
13220 isContainer = false;
13221 break;
13222
13223 case HostRoot:
13224 parent = parentStateNode.containerInfo;
13225 isContainer = true;
13226 break;
13227
13228 case HostPortal:
13229 parent = parentStateNode.containerInfo;
13230 isContainer = true;
13231 break;
13232
13233 case FundamentalComponent:
13234 if (enableFundamentalAPI) {
13235 parent = parentStateNode.instance;
13236 isContainer = false;
13237 }
13238
13239 // eslint-disable-next-line-no-fallthrough
13240
13241 default:
13242 (function () {
13243 {
13244 {
13245 throw ReactError(Error("Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue."));
13246 }
13247 }
13248 })();
13249
13250 }
13251
13252 if (parentFiber.effectTag & ContentReset) {
13253 // Reset the text content of the parent before doing any insertions
13254 parentFiber.effectTag &= ~ContentReset;
13255 }
13256
13257 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
13258 // children to find all the terminal nodes.
13259
13260 var node = finishedWork;
13261
13262 while (true) {
13263 var isHost = node.tag === HostComponent || node.tag === HostText;
13264
13265 if (isHost || enableFundamentalAPI && node.tag === FundamentalComponent) {
13266 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
13267
13268 if (before) {
13269 if (isContainer) {
13270 insertInContainerBefore(parent, stateNode, before);
13271 } else {
13272 insertBefore(parent, stateNode, before);
13273 }
13274 } else {
13275 if (isContainer) {
13276 appendChildToContainer(parent, stateNode);
13277 } else {
13278 appendChild(parent, stateNode);
13279 }
13280 }
13281 } else if (node.tag === HostPortal) {// If the insertion itself is a portal, then we don't want to traverse
13282 // down its children. Instead, we'll get insertions from each child in
13283 // the portal directly.
13284 } else if (node.child !== null) {
13285 node.child.return = node;
13286 node = node.child;
13287 continue;
13288 }
13289
13290 if (node === finishedWork) {
13291 return;
13292 }
13293
13294 while (node.sibling === null) {
13295 if (node.return === null || node.return === finishedWork) {
13296 return;
13297 }
13298
13299 node = node.return;
13300 }
13301
13302 node.sibling.return = node.return;
13303 node = node.sibling;
13304 }
13305}
13306
13307function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
13308 // We only have the top Fiber that was deleted but we need to recurse down its
13309 // children to find all the terminal nodes.
13310 var node = current; // Each iteration, currentParent is populated with node's host parent if not
13311 // currentParentIsValid.
13312
13313 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
13314
13315 var currentParent;
13316 var currentParentIsContainer;
13317
13318 while (true) {
13319 if (!currentParentIsValid) {
13320 var parent = node.return;
13321
13322 findParent: while (true) {
13323 (function () {
13324 if (!(parent !== null)) {
13325 {
13326 throw ReactError(Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue."));
13327 }
13328 }
13329 })();
13330
13331 var parentStateNode = parent.stateNode;
13332
13333 switch (parent.tag) {
13334 case HostComponent:
13335 currentParent = parentStateNode;
13336 currentParentIsContainer = false;
13337 break findParent;
13338
13339 case HostRoot:
13340 currentParent = parentStateNode.containerInfo;
13341 currentParentIsContainer = true;
13342 break findParent;
13343
13344 case HostPortal:
13345 currentParent = parentStateNode.containerInfo;
13346 currentParentIsContainer = true;
13347 break findParent;
13348
13349 case FundamentalComponent:
13350 if (enableFundamentalAPI) {
13351 currentParent = parentStateNode.instance;
13352 currentParentIsContainer = false;
13353 }
13354
13355 }
13356
13357 parent = parent.return;
13358 }
13359
13360 currentParentIsValid = true;
13361 }
13362
13363 if (node.tag === HostComponent || node.tag === HostText) {
13364 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
13365 // node from the tree.
13366
13367 if (currentParentIsContainer) {
13368 removeChildFromContainer(currentParent, node.stateNode);
13369 } else {
13370 removeChild(currentParent, node.stateNode);
13371 } // Don't visit children because we already visited them.
13372
13373 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
13374 var fundamentalNode = node.stateNode.instance;
13375 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
13376 // node from the tree.
13377
13378 if (currentParentIsContainer) {
13379 removeChildFromContainer(currentParent, fundamentalNode);
13380 } else {
13381 removeChild(currentParent, fundamentalNode);
13382 }
13383 } else if (enableSuspenseServerRenderer && node.tag === DehydratedFragment) {
13384 if (enableSuspenseCallback) {
13385 var hydrationCallbacks = finishedRoot.hydrationCallbacks;
13386
13387 if (hydrationCallbacks !== null) {
13388 var onDeleted = hydrationCallbacks.onDeleted;
13389
13390 if (onDeleted) {
13391 onDeleted(node.stateNode);
13392 }
13393 }
13394 } // Delete the dehydrated suspense boundary and all of its content.
13395
13396
13397 if (currentParentIsContainer) {
13398 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
13399 } else {
13400 clearSuspenseBoundary(currentParent, node.stateNode);
13401 }
13402 } else if (node.tag === HostPortal) {
13403 if (node.child !== null) {
13404 // When we go into a portal, it becomes the parent to remove from.
13405 // We will reassign it back when we pop the portal on the way up.
13406 currentParent = node.stateNode.containerInfo;
13407 currentParentIsContainer = true; // Visit children because portals might contain host components.
13408
13409 node.child.return = node;
13410 node = node.child;
13411 continue;
13412 }
13413 } else {
13414 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
13415
13416 if (node.child !== null) {
13417 node.child.return = node;
13418 node = node.child;
13419 continue;
13420 }
13421 }
13422
13423 if (node === current) {
13424 return;
13425 }
13426
13427 while (node.sibling === null) {
13428 if (node.return === null || node.return === current) {
13429 return;
13430 }
13431
13432 node = node.return;
13433
13434 if (node.tag === HostPortal) {
13435 // When we go out of the portal, we need to restore the parent.
13436 // Since we don't keep a stack of them, we will search for it.
13437 currentParentIsValid = false;
13438 }
13439 }
13440
13441 node.sibling.return = node.return;
13442 node = node.sibling;
13443 }
13444}
13445
13446function commitDeletion(finishedRoot, current, renderPriorityLevel) {
13447 if (supportsMutation) {
13448 // Recursively delete all host nodes from the parent.
13449 // Detach refs and call componentWillUnmount() on the whole subtree.
13450 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
13451 } else {
13452 // Detach refs and call componentWillUnmount() on the whole subtree.
13453 commitNestedUnmounts(finishedRoot, current, renderPriorityLevel);
13454 }
13455
13456 detachFiber(current);
13457}
13458
13459function commitWork(current, finishedWork) {
13460 if (!supportsMutation) {
13461 switch (finishedWork.tag) {
13462 case FunctionComponent:
13463 case ForwardRef:
13464 case MemoComponent:
13465 case SimpleMemoComponent:
13466 {
13467 // Note: We currently never use MountMutation, but useLayout uses
13468 // UnmountMutation.
13469 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
13470 return;
13471 }
13472
13473 case Profiler:
13474 {
13475 return;
13476 }
13477
13478 case SuspenseComponent:
13479 {
13480 commitSuspenseComponent(finishedWork);
13481 attachSuspenseRetryListeners(finishedWork);
13482 return;
13483 }
13484
13485 case SuspenseListComponent:
13486 {
13487 attachSuspenseRetryListeners(finishedWork);
13488 return;
13489 }
13490
13491 case HostRoot:
13492 {
13493 if (supportsHydration) {
13494 var root = finishedWork.stateNode;
13495
13496 if (root.hydrate) {
13497 // We've just hydrated. No need to hydrate again.
13498 root.hydrate = false;
13499 commitHydratedContainer(root.containerInfo);
13500 }
13501 }
13502
13503 break;
13504 }
13505 }
13506
13507 commitContainer(finishedWork);
13508 return;
13509 }
13510
13511 switch (finishedWork.tag) {
13512 case FunctionComponent:
13513 case ForwardRef:
13514 case MemoComponent:
13515 case SimpleMemoComponent:
13516 {
13517 // Note: We currently never use MountMutation, but useLayout uses
13518 // UnmountMutation.
13519 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
13520 return;
13521 }
13522
13523 case ClassComponent:
13524 {
13525 return;
13526 }
13527
13528 case HostComponent:
13529 {
13530 var instance = finishedWork.stateNode;
13531
13532 if (instance != null) {
13533 // Commit the work prepared earlier.
13534 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
13535 // as the newProps. The updatePayload will contain the real change in
13536 // this case.
13537
13538 var oldProps = current !== null ? current.memoizedProps : newProps;
13539 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
13540
13541 var updatePayload = finishedWork.updateQueue;
13542 finishedWork.updateQueue = null;
13543
13544 if (updatePayload !== null) {
13545 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
13546 }
13547
13548 if (enableFlareAPI) {
13549 var prevListeners = oldProps.listeners;
13550 var nextListeners = newProps.listeners;
13551
13552 if (prevListeners !== nextListeners) {
13553 updateEventListeners(nextListeners, finishedWork, null);
13554 }
13555 }
13556 }
13557
13558 return;
13559 }
13560
13561 case HostText:
13562 {
13563 (function () {
13564 if (!(finishedWork.stateNode !== null)) {
13565 {
13566 throw ReactError(Error("This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue."));
13567 }
13568 }
13569 })();
13570
13571 var textInstance = finishedWork.stateNode;
13572 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
13573 // as the newProps. The updatePayload will contain the real change in
13574 // this case.
13575
13576 var oldText = current !== null ? current.memoizedProps : newText;
13577 return;
13578 }
13579
13580 case HostRoot:
13581 {
13582 if (supportsHydration) {
13583 var _root = finishedWork.stateNode;
13584
13585 if (_root.hydrate) {
13586 // We've just hydrated. No need to hydrate again.
13587 _root.hydrate = false;
13588 commitHydratedContainer(_root.containerInfo);
13589 }
13590 }
13591
13592 return;
13593 }
13594
13595 case Profiler:
13596 {
13597 return;
13598 }
13599
13600 case SuspenseComponent:
13601 {
13602 commitSuspenseComponent(finishedWork);
13603 attachSuspenseRetryListeners(finishedWork);
13604 return;
13605 }
13606
13607 case SuspenseListComponent:
13608 {
13609 attachSuspenseRetryListeners(finishedWork);
13610 return;
13611 }
13612
13613 case IncompleteClassComponent:
13614 {
13615 return;
13616 }
13617
13618 case FundamentalComponent:
13619 {
13620 if (enableFundamentalAPI) {
13621 var fundamentalInstance = finishedWork.stateNode;
13622 updateFundamentalComponent(fundamentalInstance);
13623 }
13624
13625 return;
13626 }
13627
13628 case ScopeComponent:
13629 {
13630 if (enableScopeAPI) {
13631 var scopeInstance = finishedWork.stateNode;
13632 scopeInstance.fiber = finishedWork;
13633
13634 if (enableFlareAPI) {
13635 var _newProps = finishedWork.memoizedProps;
13636
13637 var _oldProps = current !== null ? current.memoizedProps : _newProps;
13638
13639 var _prevListeners = _oldProps.listeners;
13640 var _nextListeners = _newProps.listeners;
13641
13642 if (_prevListeners !== _nextListeners) {
13643 updateEventListeners(_nextListeners, finishedWork, null);
13644 }
13645 }
13646 }
13647
13648 return;
13649 }
13650
13651 default:
13652 {
13653 (function () {
13654 {
13655 {
13656 throw ReactError(Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."));
13657 }
13658 }
13659 })();
13660 }
13661 }
13662}
13663
13664function commitSuspenseComponent(finishedWork) {
13665 var newState = finishedWork.memoizedState;
13666 var newDidTimeout;
13667 var primaryChildParent = finishedWork;
13668
13669 if (newState === null) {
13670 newDidTimeout = false;
13671 } else {
13672 newDidTimeout = true;
13673 primaryChildParent = finishedWork.child;
13674 markCommitTimeOfFallback();
13675 }
13676
13677 if (supportsMutation && primaryChildParent !== null) {
13678 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
13679 }
13680
13681 if (enableSuspenseCallback && newState !== null) {
13682 var suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
13683
13684 if (typeof suspenseCallback === 'function') {
13685 var thenables = finishedWork.updateQueue;
13686
13687 if (thenables !== null) {
13688 suspenseCallback(new Set(thenables));
13689 }
13690 } else {
13691 if (suspenseCallback !== undefined) {
13692 warning$1(false, 'Unexpected type for suspenseCallback.');
13693 }
13694 }
13695 }
13696}
13697
13698function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
13699 if (!supportsHydration) {
13700 return;
13701 }
13702
13703 var newState = finishedWork.memoizedState;
13704
13705 if (newState === null) {
13706 var current = finishedWork.alternate;
13707
13708 if (current !== null) {
13709 var prevState = current.memoizedState;
13710
13711 if (prevState !== null) {
13712 var suspenseInstance = prevState.dehydrated;
13713
13714 if (suspenseInstance !== null) {
13715 commitHydratedSuspenseInstance(suspenseInstance);
13716
13717 if (enableSuspenseCallback) {
13718 var hydrationCallbacks = finishedRoot.hydrationCallbacks;
13719
13720 if (hydrationCallbacks !== null) {
13721 var onHydrated = hydrationCallbacks.onHydrated;
13722
13723 if (onHydrated) {
13724 onHydrated(suspenseInstance);
13725 }
13726 }
13727 }
13728 }
13729 }
13730 }
13731 }
13732}
13733
13734function attachSuspenseRetryListeners(finishedWork) {
13735 // If this boundary just timed out, then it will have a set of thenables.
13736 // For each thenable, attach a listener so that when it resolves, React
13737 // attempts to re-render the boundary in the primary (pre-timeout) state.
13738 var thenables = finishedWork.updateQueue;
13739
13740 if (thenables !== null) {
13741 finishedWork.updateQueue = null;
13742 var retryCache = finishedWork.stateNode;
13743
13744 if (retryCache === null) {
13745 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
13746 }
13747
13748 thenables.forEach(function (thenable) {
13749 // Memoize using the boundary fiber to prevent redundant listeners.
13750 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
13751
13752 if (!retryCache.has(thenable)) {
13753 if (enableSchedulerTracing) {
13754 if (thenable.__reactDoNotTraceInteractions !== true) {
13755 retry = unstable_wrap(retry);
13756 }
13757 }
13758
13759 retryCache.add(thenable);
13760 thenable.then(retry, retry);
13761 }
13762 });
13763 }
13764}
13765
13766function commitResetTextContent(current) {
13767 if (!supportsMutation) {
13768 return;
13769 }
13770
13771 resetTextContent(current.stateNode);
13772}
13773
13774var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
13775
13776function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
13777 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
13778
13779 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
13780 // being called "element".
13781
13782 update.payload = {
13783 element: null
13784 };
13785 var error = errorInfo.value;
13786
13787 update.callback = function () {
13788 onUncaughtError(error);
13789 logError(fiber, errorInfo);
13790 };
13791
13792 return update;
13793}
13794
13795function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
13796 var update = createUpdate(expirationTime, null);
13797 update.tag = CaptureUpdate;
13798 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
13799
13800 if (typeof getDerivedStateFromError === 'function') {
13801 var error = errorInfo.value;
13802
13803 update.payload = function () {
13804 logError(fiber, errorInfo);
13805 return getDerivedStateFromError(error);
13806 };
13807 }
13808
13809 var inst = fiber.stateNode;
13810
13811 if (inst !== null && typeof inst.componentDidCatch === 'function') {
13812 update.callback = function callback() {
13813 {
13814 markFailedErrorBoundaryForHotReloading(fiber);
13815 }
13816
13817 if (typeof getDerivedStateFromError !== 'function') {
13818 // To preserve the preexisting retry behavior of error boundaries,
13819 // we keep track of which ones already failed during this batch.
13820 // This gets reset before we yield back to the browser.
13821 // TODO: Warn in strict mode if getDerivedStateFromError is
13822 // not defined.
13823 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
13824
13825 logError(fiber, errorInfo);
13826 }
13827
13828 var error = errorInfo.value;
13829 var stack = errorInfo.stack;
13830 this.componentDidCatch(error, {
13831 componentStack: stack !== null ? stack : ''
13832 });
13833
13834 {
13835 if (typeof getDerivedStateFromError !== 'function') {
13836 // If componentDidCatch is the only error boundary method defined,
13837 // then it needs to call setState to recover from errors.
13838 // If no state update is scheduled then the boundary will swallow the error.
13839 !(fiber.expirationTime === Sync) ? warningWithoutStack$1(false, '%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown') : void 0;
13840 }
13841 }
13842 };
13843 } else {
13844 update.callback = function () {
13845 markFailedErrorBoundaryForHotReloading(fiber);
13846 };
13847 }
13848
13849 return update;
13850}
13851
13852function attachPingListener(root, renderExpirationTime, thenable) {
13853 // Attach a listener to the promise to "ping" the root and retry. But
13854 // only if one does not already exist for the current render expiration
13855 // time (which acts like a "thread ID" here).
13856 var pingCache = root.pingCache;
13857 var threadIDs;
13858
13859 if (pingCache === null) {
13860 pingCache = root.pingCache = new PossiblyWeakMap();
13861 threadIDs = new Set();
13862 pingCache.set(thenable, threadIDs);
13863 } else {
13864 threadIDs = pingCache.get(thenable);
13865
13866 if (threadIDs === undefined) {
13867 threadIDs = new Set();
13868 pingCache.set(thenable, threadIDs);
13869 }
13870 }
13871
13872 if (!threadIDs.has(renderExpirationTime)) {
13873 // Memoize using the thread ID to prevent redundant listeners.
13874 threadIDs.add(renderExpirationTime);
13875 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
13876 thenable.then(ping, ping);
13877 }
13878}
13879
13880function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
13881 // The source fiber did not complete.
13882 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
13883
13884 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
13885
13886 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
13887 // This is a thenable.
13888 var thenable = value;
13889 checkForWrongSuspensePriorityInDEV(sourceFiber);
13890 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
13891
13892 var _workInProgress = returnFiber;
13893
13894 do {
13895 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
13896 // Found the nearest boundary.
13897 // Stash the promise on the boundary fiber. If the boundary times out, we'll
13898 // attach another listener to flip the boundary back to its normal state.
13899 var thenables = _workInProgress.updateQueue;
13900
13901 if (thenables === null) {
13902 var updateQueue = new Set();
13903 updateQueue.add(thenable);
13904 _workInProgress.updateQueue = updateQueue;
13905 } else {
13906 thenables.add(thenable);
13907 } // If the boundary is outside of batched mode, we should *not*
13908 // suspend the commit. Pretend as if the suspended component rendered
13909 // null and keep rendering. In the commit phase, we'll schedule a
13910 // subsequent synchronous update to re-render the Suspense.
13911 //
13912 // Note: It doesn't matter whether the component that suspended was
13913 // inside a batched mode tree. If the Suspense is outside of it, we
13914 // should *not* suspend the commit.
13915
13916
13917 if ((_workInProgress.mode & BatchedMode) === NoMode) {
13918 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
13919 // But we shouldn't call any lifecycle methods or callbacks. Remove
13920 // all lifecycle effect tags.
13921
13922 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
13923
13924 if (sourceFiber.tag === ClassComponent) {
13925 var currentSourceFiber = sourceFiber.alternate;
13926
13927 if (currentSourceFiber === null) {
13928 // This is a new mount. Change the tag so it's not mistaken for a
13929 // completed class component. For example, we should not call
13930 // componentWillUnmount if it is deleted.
13931 sourceFiber.tag = IncompleteClassComponent;
13932 } else {
13933 // When we try rendering again, we should not reuse the current fiber,
13934 // since it's known to be in an inconsistent state. Use a force update to
13935 // prevent a bail out.
13936 var update = createUpdate(Sync, null);
13937 update.tag = ForceUpdate;
13938 enqueueUpdate(sourceFiber, update);
13939 }
13940 } // The source fiber did not complete. Mark it with Sync priority to
13941 // indicate that it still has pending work.
13942
13943
13944 sourceFiber.expirationTime = Sync; // Exit without suspending.
13945
13946 return;
13947 } // Confirmed that the boundary is in a concurrent mode tree. Continue
13948 // with the normal suspend path.
13949 //
13950 // After this we'll use a set of heuristics to determine whether this
13951 // render pass will run to completion or restart or "suspend" the commit.
13952 // The actual logic for this is spread out in different places.
13953 //
13954 // This first principle is that if we're going to suspend when we complete
13955 // a root, then we should also restart if we get an update or ping that
13956 // might unsuspend it, and vice versa. The only reason to suspend is
13957 // because you think you might want to restart before committing. However,
13958 // it doesn't make sense to restart only while in the period we're suspended.
13959 //
13960 // Restarting too aggressively is also not good because it starves out any
13961 // intermediate loading state. So we use heuristics to determine when.
13962 // Suspense Heuristics
13963 //
13964 // If nothing threw a Promise or all the same fallbacks are already showing,
13965 // then don't suspend/restart.
13966 //
13967 // If this is an initial render of a new tree of Suspense boundaries and
13968 // those trigger a fallback, then don't suspend/restart. We want to ensure
13969 // that we can show the initial loading state as quickly as possible.
13970 //
13971 // If we hit a "Delayed" case, such as when we'd switch from content back into
13972 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
13973 // this case. If none is defined, JND is used instead.
13974 //
13975 // If we're already showing a fallback and it gets "retried", allowing us to show
13976 // another level, but there's still an inner boundary that would show a fallback,
13977 // then we suspend/restart for 500ms since the last time we showed a fallback
13978 // anywhere in the tree. This effectively throttles progressive loading into a
13979 // consistent train of commits. This also gives us an opportunity to restart to
13980 // get to the completed state slightly earlier.
13981 //
13982 // If there's ambiguity due to batching it's resolved in preference of:
13983 // 1) "delayed", 2) "initial render", 3) "retry".
13984 //
13985 // We want to ensure that a "busy" state doesn't get force committed. We want to
13986 // ensure that new initial loading states can commit as soon as possible.
13987
13988
13989 attachPingListener(root, renderExpirationTime, thenable);
13990 _workInProgress.effectTag |= ShouldCapture;
13991 _workInProgress.expirationTime = renderExpirationTime;
13992 return;
13993 } // This boundary already captured during this render. Continue to the next
13994 // boundary.
13995
13996
13997 _workInProgress = _workInProgress.return;
13998 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
13999 // TODO: Use invariant so the message is stripped in prod?
14000
14001
14002 value = new Error((getComponentName(sourceFiber.type) || 'A React component') + ' suspended while rendering, but no fallback UI was specified.\n' + '\n' + 'Add a <Suspense fallback=...> component higher in the tree to ' + 'provide a loading indicator or placeholder to display.' + getStackByFiberInDevAndProd(sourceFiber));
14003 } // We didn't find a boundary that could handle this type of exception. Start
14004 // over and traverse parent path again, this time treating the exception
14005 // as an error.
14006
14007
14008 renderDidError();
14009 value = createCapturedValue(value, sourceFiber);
14010 var workInProgress = returnFiber;
14011
14012 do {
14013 switch (workInProgress.tag) {
14014 case HostRoot:
14015 {
14016 var _errorInfo = value;
14017 workInProgress.effectTag |= ShouldCapture;
14018 workInProgress.expirationTime = renderExpirationTime;
14019
14020 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
14021
14022 enqueueCapturedUpdate(workInProgress, _update);
14023 return;
14024 }
14025
14026 case ClassComponent:
14027 // Capture and retry
14028 var errorInfo = value;
14029 var ctor = workInProgress.type;
14030 var instance = workInProgress.stateNode;
14031
14032 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
14033 workInProgress.effectTag |= ShouldCapture;
14034 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
14035
14036 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
14037
14038 enqueueCapturedUpdate(workInProgress, _update2);
14039 return;
14040 }
14041
14042 break;
14043
14044 default:
14045 break;
14046 }
14047
14048 workInProgress = workInProgress.return;
14049 } while (workInProgress !== null);
14050}
14051
14052var ceil = Math.ceil;
14053var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
14054var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
14055var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
14056var NoContext =
14057/* */
140580;
14059var BatchedContext =
14060/* */
140611;
14062var DiscreteEventContext =
14063/* */
140644;
14065var LegacyUnbatchedContext =
14066/* */
140678;
14068var RenderContext =
14069/* */
1407016;
14071var CommitContext =
14072/* */
1407332;
14074var RootIncomplete = 0;
14075var RootFatalErrored = 1;
14076var RootErrored = 2;
14077var RootSuspended = 3;
14078var RootSuspendedWithDelay = 4;
14079var RootCompleted = 5;
14080var RootLocked = 6;
14081// Describes where we are in the React execution stack
14082var executionContext = NoContext; // The root we're working on
14083
14084var workInProgressRoot = null; // The fiber we're working on
14085
14086var workInProgress = null; // The expiration time we're rendering
14087
14088var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc.
14089
14090var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
14091
14092var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
14093// This is conceptually a time stamp but expressed in terms of an ExpirationTime
14094// because we deal mostly with expiration times in the hot path, so this avoids
14095// the conversion happening in the hot path.
14096
14097var workInProgressRootLatestProcessedExpirationTime = Sync;
14098var workInProgressRootLatestSuspenseTimeout = Sync;
14099var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
14100// includes unprocessed updates, not work in bailed out children.
14101
14102var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
14103// This flag determines if it might be worthwhile to restart if an opportunity
14104// happens latere.
14105
14106var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
14107// model where we don't commit new loading states in too quick succession.
14108
14109var globalMostRecentFallbackTime = 0;
14110var FALLBACK_THROTTLE_MS = 500;
14111var nextEffect = null;
14112var hasUncaughtError = false;
14113var firstUncaughtError = null;
14114var legacyErrorBoundariesThatAlreadyFailed = null;
14115var rootDoesHavePassiveEffects = false;
14116var rootWithPendingPassiveEffects = null;
14117var pendingPassiveEffectsRenderPriority = NoPriority;
14118var pendingPassiveEffectsExpirationTime = NoWork;
14119var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
14120
14121var NESTED_UPDATE_LIMIT = 50;
14122var nestedUpdateCount = 0;
14123var rootWithNestedUpdates = null;
14124var NESTED_PASSIVE_UPDATE_LIMIT = 50;
14125var nestedPassiveUpdateCount = 0;
14126var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
14127// during the commit phase. This enables them to be traced across components
14128// that spawn new work during render. E.g. hidden boundaries, suspended SSR
14129// hydration or SuspenseList.
14130
14131var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
14132// time). However, if two updates are scheduled within the same event, we
14133// should treat their start times as simultaneous, even if the actual clock
14134// time has advanced between the first and second call.
14135// In other words, because expiration times determine how updates are batched,
14136// we want all updates of like priority that occur within the same event to
14137// receive the same expiration time. Otherwise we get tearing.
14138
14139var currentEventTime = NoWork;
14140function requestCurrentTime() {
14141 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
14142 // We're inside React, so it's fine to read the actual time.
14143 return msToExpirationTime(now());
14144 } // We're not inside React, so we may be in the middle of a browser event.
14145
14146
14147 if (currentEventTime !== NoWork) {
14148 // Use the same start time for all updates until we enter React again.
14149 return currentEventTime;
14150 } // This is the first update since React yielded. Compute a new start time.
14151
14152
14153 currentEventTime = msToExpirationTime(now());
14154 return currentEventTime;
14155}
14156function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
14157 var mode = fiber.mode;
14158
14159 if ((mode & BatchedMode) === NoMode) {
14160 return Sync;
14161 }
14162
14163 var priorityLevel = getCurrentPriorityLevel();
14164
14165 if ((mode & ConcurrentMode) === NoMode) {
14166 return priorityLevel === ImmediatePriority ? Sync : Batched;
14167 }
14168
14169 if ((executionContext & RenderContext) !== NoContext) {
14170 // Use whatever time we're already rendering
14171 // TODO: Should there be a way to opt out, like with `runWithPriority`?
14172 return renderExpirationTime;
14173 }
14174
14175 var expirationTime;
14176
14177 if (suspenseConfig !== null) {
14178 // Compute an expiration time based on the Suspense timeout.
14179 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
14180 } else {
14181 // Compute an expiration time based on the Scheduler priority.
14182 switch (priorityLevel) {
14183 case ImmediatePriority:
14184 expirationTime = Sync;
14185 break;
14186
14187 case UserBlockingPriority:
14188 // TODO: Rename this to computeUserBlockingExpiration
14189 expirationTime = computeInteractiveExpiration(currentTime);
14190 break;
14191
14192 case NormalPriority:
14193 case LowPriority:
14194 // TODO: Handle LowPriority
14195 // TODO: Rename this to... something better.
14196 expirationTime = computeAsyncExpiration(currentTime);
14197 break;
14198
14199 case IdlePriority:
14200 expirationTime = Idle;
14201 break;
14202
14203 default:
14204 (function () {
14205 {
14206 {
14207 throw ReactError(Error("Expected a valid priority level"));
14208 }
14209 }
14210 })();
14211
14212 }
14213 } // If we're in the middle of rendering a tree, do not update at the same
14214 // expiration time that is already rendering.
14215 // TODO: We shouldn't have to do this if the update is on a different root.
14216 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
14217 // the root when we check for this condition.
14218
14219
14220 if (workInProgressRoot !== null && expirationTime === renderExpirationTime) {
14221 // This is a trick to move this update into a separate batch
14222 expirationTime -= 1;
14223 }
14224
14225 return expirationTime;
14226}
14227
14228function scheduleUpdateOnFiber(fiber, expirationTime) {
14229 checkForNestedUpdates();
14230 warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
14231 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
14232
14233 if (root === null) {
14234 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
14235 return;
14236 }
14237
14238 checkForInterruption(fiber, expirationTime);
14239 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
14240 // priority as an argument to that function and this one.
14241
14242 var priorityLevel = getCurrentPriorityLevel();
14243
14244 if (expirationTime === Sync) {
14245 if ( // Check if we're inside unbatchedUpdates
14246 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
14247 (executionContext & (RenderContext | CommitContext)) === NoContext) {
14248 // Register pending interactions on the root to avoid losing traced interaction data.
14249 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
14250 // root inside of batchedUpdates should be synchronous, but layout updates
14251 // should be deferred until the end of the batch.
14252
14253 performSyncWorkOnRoot(root);
14254 } else {
14255 ensureRootIsScheduled(root);
14256 schedulePendingInteractions(root, expirationTime);
14257
14258 if (executionContext === NoContext) {
14259 // Flush the synchronous work now, unless we're already working or inside
14260 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
14261 // scheduleCallbackForFiber to preserve the ability to schedule a callback
14262 // without immediately flushing it. We only do this for user-initiated
14263 // updates, to preserve historical behavior of sync mode.
14264 flushSyncCallbackQueue();
14265 }
14266 }
14267 } else {
14268 ensureRootIsScheduled(root);
14269 schedulePendingInteractions(root, expirationTime);
14270 }
14271
14272 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
14273 // discrete, even inside a discrete event.
14274 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
14275 // This is the result of a discrete event. Track the lowest priority
14276 // discrete update per root so we can flush them early, if needed.
14277 if (rootsWithPendingDiscreteUpdates === null) {
14278 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
14279 } else {
14280 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
14281
14282 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
14283 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
14284 }
14285 }
14286 }
14287}
14288var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
14289// work without treating it as a typical update that originates from an event;
14290// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
14291// on a fiber.
14292
14293function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
14294 // Update the source fiber's expiration time
14295 if (fiber.expirationTime < expirationTime) {
14296 fiber.expirationTime = expirationTime;
14297 }
14298
14299 var alternate = fiber.alternate;
14300
14301 if (alternate !== null && alternate.expirationTime < expirationTime) {
14302 alternate.expirationTime = expirationTime;
14303 } // Walk the parent path to the root and update the child expiration time.
14304
14305
14306 var node = fiber.return;
14307 var root = null;
14308
14309 if (node === null && fiber.tag === HostRoot) {
14310 root = fiber.stateNode;
14311 } else {
14312 while (node !== null) {
14313 alternate = node.alternate;
14314
14315 if (node.childExpirationTime < expirationTime) {
14316 node.childExpirationTime = expirationTime;
14317
14318 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
14319 alternate.childExpirationTime = expirationTime;
14320 }
14321 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
14322 alternate.childExpirationTime = expirationTime;
14323 }
14324
14325 if (node.return === null && node.tag === HostRoot) {
14326 root = node.stateNode;
14327 break;
14328 }
14329
14330 node = node.return;
14331 }
14332 }
14333
14334 if (root !== null) {
14335 if (workInProgressRoot === root) {
14336 // Received an update to a tree that's in the middle of rendering. Mark
14337 // that's unprocessed work on this root.
14338 markUnprocessedUpdateTime(expirationTime);
14339
14340 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
14341 // The root already suspended with a delay, which means this render
14342 // definitely won't finish. Since we have a new update, let's mark it as
14343 // suspended now, right before marking the incoming update. This has the
14344 // effect of interrupting the current render and switching to the update.
14345 // TODO: This happens to work when receiving an update during the render
14346 // phase, because of the trick inside computeExpirationForFiber to
14347 // subtract 1 from `renderExpirationTime` to move it into a
14348 // separate bucket. But we should probably model it with an exception,
14349 // using the same mechanism we use to force hydration of a subtree.
14350 // TODO: This does not account for low pri updates that were already
14351 // scheduled before the root started rendering. Need to track the next
14352 // pending expiration time (perhaps by backtracking the return path) and
14353 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
14354 markRootSuspendedAtTime(root, renderExpirationTime);
14355 }
14356 } // Mark that the root has a pending update.
14357
14358
14359 markRootUpdatedAtTime(root, expirationTime);
14360 }
14361
14362 return root;
14363}
14364
14365function getNextRootExpirationTimeToWorkOn(root) {
14366 // Determines the next expiration time that the root should render, taking
14367 // into account levels that may be suspended, or levels that may have
14368 // received a ping.
14369 var lastExpiredTime = root.lastExpiredTime;
14370
14371 if (lastExpiredTime !== NoWork) {
14372 return lastExpiredTime;
14373 } // "Pending" refers to any update that hasn't committed yet, including if it
14374 // suspended. The "suspended" range is therefore a subset.
14375
14376
14377 var firstPendingTime = root.firstPendingTime;
14378
14379 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
14380 // The highest priority pending time is not suspended. Let's work on that.
14381 return firstPendingTime;
14382 } // If the first pending time is suspended, check if there's a lower priority
14383 // pending level that we know about. Or check if we received a ping. Work
14384 // on whichever is higher priority.
14385
14386
14387 var lastPingedTime = root.lastPingedTime;
14388 var nextKnownPendingLevel = root.nextKnownPendingLevel;
14389 return lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
14390} // Use this function to schedule a task for a root. There's only one task per
14391// root; if a task was already scheduled, we'll check to make sure the
14392// expiration time of the existing task is the same as the expiration time of
14393// the next level that the root has work on. This function is called on every
14394// update, and right before exiting a task.
14395
14396
14397function ensureRootIsScheduled(root) {
14398 var lastExpiredTime = root.lastExpiredTime;
14399
14400 if (lastExpiredTime !== NoWork) {
14401 // Special case: Expired work should flush synchronously.
14402 root.callbackExpirationTime = Sync;
14403 root.callbackPriority = ImmediatePriority;
14404 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
14405 return;
14406 }
14407
14408 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
14409 var existingCallbackNode = root.callbackNode;
14410
14411 if (expirationTime === NoWork) {
14412 // There's nothing to work on.
14413 if (existingCallbackNode !== null) {
14414 root.callbackNode = null;
14415 root.callbackExpirationTime = NoWork;
14416 root.callbackPriority = NoPriority;
14417 }
14418
14419 return;
14420 } // TODO: If this is an update, we already read the current time. Pass the
14421 // time as an argument.
14422
14423
14424 var currentTime = requestCurrentTime();
14425 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
14426 // expiration time. Otherwise, we'll cancel it and schedule a new one.
14427
14428 if (existingCallbackNode !== null) {
14429 var existingCallbackPriority = root.callbackPriority;
14430 var existingCallbackExpirationTime = root.callbackExpirationTime;
14431
14432 if ( // Callback must have the exact same expiration time.
14433 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
14434 existingCallbackPriority >= priorityLevel) {
14435 // Existing callback is sufficient.
14436 return;
14437 } // Need to schedule a new task.
14438 // TODO: Instead of scheduling a new task, we should be able to change the
14439 // priority of the existing one.
14440
14441
14442 cancelCallback(existingCallbackNode);
14443 }
14444
14445 root.callbackExpirationTime = expirationTime;
14446 root.callbackPriority = priorityLevel;
14447 var callbackNode;
14448
14449 if (expirationTime === Sync) {
14450 // Sync React callbacks are scheduled on a special internal queue
14451 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
14452 } else if (disableSchedulerTimeoutBasedOnReactExpirationTime) {
14453 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root));
14454 } else {
14455 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
14456 // ordering because tasks are processed in timeout order.
14457 {
14458 timeout: expirationTimeToMs(expirationTime) - now()
14459 });
14460 }
14461
14462 root.callbackNode = callbackNode;
14463} // This is the entry point for every concurrent task, i.e. anything that
14464// goes through Scheduler.
14465
14466
14467function performConcurrentWorkOnRoot(root, didTimeout) {
14468 // Since we know we're in a React event, we can clear the current
14469 // event time. The next update will compute a new event time.
14470 currentEventTime = NoWork;
14471
14472 if (didTimeout) {
14473 // The render task took too long to complete. Mark the current time as
14474 // expired to synchronously render all expired work in a single batch.
14475 var currentTime = requestCurrentTime();
14476 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
14477
14478 ensureRootIsScheduled(root);
14479 return null;
14480 } // Determine the next expiration time to work on, using the fields stored
14481 // on the root.
14482
14483
14484 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
14485
14486 if (expirationTime !== NoWork) {
14487 var originalCallbackNode = root.callbackNode;
14488
14489 (function () {
14490 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
14491 {
14492 throw ReactError(Error("Should not already be working."));
14493 }
14494 }
14495 })();
14496
14497 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
14498 // and prepare a fresh one. Otherwise we'll continue where we left off.
14499
14500 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
14501 prepareFreshStack(root, expirationTime);
14502 startWorkOnPendingInteractions(root, expirationTime);
14503 } // If we have a work-in-progress fiber, it means there's still work to do
14504 // in this root.
14505
14506
14507 if (workInProgress !== null) {
14508 var prevExecutionContext = executionContext;
14509 executionContext |= RenderContext;
14510 var prevDispatcher = pushDispatcher(root);
14511 var prevInteractions = pushInteractions(root);
14512 startWorkLoopTimer(workInProgress);
14513
14514 do {
14515 try {
14516 workLoopConcurrent();
14517 break;
14518 } catch (thrownValue) {
14519 handleError(root, thrownValue);
14520 }
14521 } while (true);
14522
14523 resetContextDependencies();
14524 executionContext = prevExecutionContext;
14525 popDispatcher(prevDispatcher);
14526
14527 if (enableSchedulerTracing) {
14528 popInteractions(prevInteractions);
14529 }
14530
14531 if (workInProgressRootExitStatus === RootFatalErrored) {
14532 var fatalError = workInProgressRootFatalError;
14533 stopInterruptedWorkLoopTimer();
14534 prepareFreshStack(root, expirationTime);
14535 markRootSuspendedAtTime(root, expirationTime);
14536 ensureRootIsScheduled(root);
14537 throw fatalError;
14538 }
14539
14540 if (workInProgress !== null) {
14541 // There's still work left over. Exit without committing.
14542 stopInterruptedWorkLoopTimer();
14543 } else {
14544 // We now have a consistent tree. The next step is either to commit it,
14545 // or, if something suspended, wait to commit it after a timeout.
14546 stopFinishedWorkLoopTimer();
14547 var finishedWork = root.finishedWork = root.current.alternate;
14548 root.finishedExpirationTime = expirationTime;
14549 resolveLocksOnRoot(root, expirationTime);
14550 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
14551 }
14552
14553 ensureRootIsScheduled(root);
14554
14555 if (root.callbackNode === originalCallbackNode) {
14556 // The task node scheduled for this root is the same one that's
14557 // currently executed. Need to return a continuation.
14558 return performConcurrentWorkOnRoot.bind(null, root);
14559 }
14560 }
14561 }
14562
14563 return null;
14564}
14565
14566function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
14567 // Set this to null to indicate there's no in-progress render.
14568 workInProgressRoot = null;
14569
14570 switch (exitStatus) {
14571 case RootIncomplete:
14572 case RootFatalErrored:
14573 {
14574 (function () {
14575 {
14576 {
14577 throw ReactError(Error("Root did not complete. This is a bug in React."));
14578 }
14579 }
14580 })();
14581 }
14582 // Flow knows about invariant, so it complains if I add a break
14583 // statement, but eslint doesn't know about invariant, so it complains
14584 // if I do. eslint-disable-next-line no-fallthrough
14585
14586 case RootErrored:
14587 {
14588 if (expirationTime !== Idle) {
14589 // If this was an async render, the error may have happened due to
14590 // a mutation in a concurrent event. Try rendering one more time,
14591 // synchronously, to see if the error goes away. If there are
14592 // lower priority updates, let's include those, too, in case they
14593 // fix the inconsistency. Render at Idle to include all updates.
14594 markRootExpiredAtTime(root, Idle);
14595 break;
14596 } // Commit the root in its errored state.
14597
14598
14599 commitRoot(root);
14600 break;
14601 }
14602
14603 case RootSuspended:
14604 {
14605 markRootSuspendedAtTime(root, expirationTime);
14606 var lastSuspendedTime = root.lastSuspendedTime;
14607
14608 if (expirationTime === lastSuspendedTime) {
14609 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
14610 }
14611
14612 flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we
14613 // should immediately commit it or wait a bit.
14614 // If we have processed new updates during this render, we may now
14615 // have a new loading state ready. We want to ensure that we commit
14616 // that as soon as possible.
14617
14618 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
14619
14620 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
14621 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
14622 // If we have not processed any new updates during this pass, then
14623 // this is either a retry of an existing fallback state or a
14624 // hidden tree. Hidden trees shouldn't be batched with other work
14625 // and after that's fixed it can only be a retry. We're going to
14626 // throttle committing retries so that we don't show too many
14627 // loading states too quickly.
14628 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
14629
14630 if (msUntilTimeout > 10) {
14631 if (workInProgressRootHasPendingPing) {
14632 var lastPingedTime = root.lastPingedTime;
14633
14634 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
14635 // This render was pinged but we didn't get to restart
14636 // earlier so try restarting now instead.
14637 root.lastPingedTime = expirationTime;
14638 prepareFreshStack(root, expirationTime);
14639 break;
14640 }
14641 }
14642
14643 var nextTime = getNextRootExpirationTimeToWorkOn(root);
14644
14645 if (nextTime !== NoWork && nextTime !== expirationTime) {
14646 // There's additional work on this root.
14647 break;
14648 }
14649
14650 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
14651 // We should prefer to render the fallback of at the last
14652 // suspended level. Ping the last suspended level to try
14653 // rendering it again.
14654 root.lastPingedTime = lastSuspendedTime;
14655 break;
14656 } // The render is suspended, it hasn't timed out, and there's no
14657 // lower priority work to do. Instead of committing the fallback
14658 // immediately, wait for more data to arrive.
14659
14660
14661 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
14662 break;
14663 }
14664 } // The work expired. Commit immediately.
14665
14666
14667 commitRoot(root);
14668 break;
14669 }
14670
14671 case RootSuspendedWithDelay:
14672 {
14673 markRootSuspendedAtTime(root, expirationTime);
14674 var _lastSuspendedTime = root.lastSuspendedTime;
14675
14676 if (expirationTime === _lastSuspendedTime) {
14677 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
14678 }
14679
14680 flushSuspensePriorityWarningInDEV();
14681
14682 if ( // do not delay if we're inside an act() scope
14683 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
14684 // We're suspended in a state that should be avoided. We'll try to
14685 // avoid committing it for as long as the timeouts let us.
14686 if (workInProgressRootHasPendingPing) {
14687 var _lastPingedTime = root.lastPingedTime;
14688
14689 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
14690 // This render was pinged but we didn't get to restart earlier
14691 // so try restarting now instead.
14692 root.lastPingedTime = expirationTime;
14693 prepareFreshStack(root, expirationTime);
14694 break;
14695 }
14696 }
14697
14698 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
14699
14700 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
14701 // There's additional work on this root.
14702 break;
14703 }
14704
14705 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
14706 // We should prefer to render the fallback of at the last
14707 // suspended level. Ping the last suspended level to try
14708 // rendering it again.
14709 root.lastPingedTime = _lastSuspendedTime;
14710 break;
14711 }
14712
14713 var _msUntilTimeout;
14714
14715 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
14716 // We have processed a suspense config whose expiration time we
14717 // can use as the timeout.
14718 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
14719 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
14720 // This should never normally happen because only new updates
14721 // cause delayed states, so we should have processed something.
14722 // However, this could also happen in an offscreen tree.
14723 _msUntilTimeout = 0;
14724 } else {
14725 // If we don't have a suspense config, we're going to use a
14726 // heuristic to determine how long we can suspend.
14727 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
14728 var currentTimeMs = now();
14729 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
14730 var timeElapsed = currentTimeMs - eventTimeMs;
14731
14732 if (timeElapsed < 0) {
14733 // We get this wrong some time since we estimate the time.
14734 timeElapsed = 0;
14735 }
14736
14737 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
14738 // event time is exact instead of inferred from expiration time
14739 // we don't need this.
14740
14741 if (timeUntilExpirationMs < _msUntilTimeout) {
14742 _msUntilTimeout = timeUntilExpirationMs;
14743 }
14744 } // Don't bother with a very short suspense time.
14745
14746
14747 if (_msUntilTimeout > 10) {
14748 // The render is suspended, it hasn't timed out, and there's no
14749 // lower priority work to do. Instead of committing the fallback
14750 // immediately, wait for more data to arrive.
14751 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
14752 break;
14753 }
14754 } // The work expired. Commit immediately.
14755
14756
14757 commitRoot(root);
14758 break;
14759 }
14760
14761 case RootCompleted:
14762 {
14763 // The work completed. Ready to commit.
14764 if ( // do not delay if we're inside an act() scope
14765 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
14766 // If we have exceeded the minimum loading delay, which probably
14767 // means we have shown a spinner already, we might have to suspend
14768 // a bit longer to ensure that the spinner is shown for
14769 // enough time.
14770 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
14771
14772 if (_msUntilTimeout2 > 10) {
14773 markRootSuspendedAtTime(root, expirationTime);
14774 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
14775 break;
14776 }
14777 }
14778
14779 commitRoot(root);
14780 break;
14781 }
14782
14783 case RootLocked:
14784 {
14785 // This root has a lock that prevents it from committing. Exit. If
14786 // we begin work on the root again, without any intervening updates,
14787 // it will finish without doing additional work.
14788 markRootSuspendedAtTime(root, expirationTime);
14789 break;
14790 }
14791
14792 default:
14793 {
14794 (function () {
14795 {
14796 {
14797 throw ReactError(Error("Unknown root exit status."));
14798 }
14799 }
14800 })();
14801 }
14802 }
14803} // This is the entry point for synchronous tasks that don't go
14804// through Scheduler
14805
14806
14807function performSyncWorkOnRoot(root) {
14808 // Check if there's expired work on this root. Otherwise, render at Sync.
14809 var lastExpiredTime = root.lastExpiredTime;
14810 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
14811
14812 if (root.finishedExpirationTime === expirationTime) {
14813 // There's already a pending commit at this expiration time.
14814 // TODO: This is poorly factored. This case only exists for the
14815 // batch.commit() API.
14816 commitRoot(root);
14817 } else {
14818 (function () {
14819 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
14820 {
14821 throw ReactError(Error("Should not already be working."));
14822 }
14823 }
14824 })();
14825
14826 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
14827 // and prepare a fresh one. Otherwise we'll continue where we left off.
14828
14829 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
14830 prepareFreshStack(root, expirationTime);
14831 startWorkOnPendingInteractions(root, expirationTime);
14832 } // If we have a work-in-progress fiber, it means there's still work to do
14833 // in this root.
14834
14835
14836 if (workInProgress !== null) {
14837 var prevExecutionContext = executionContext;
14838 executionContext |= RenderContext;
14839 var prevDispatcher = pushDispatcher(root);
14840 var prevInteractions = pushInteractions(root);
14841 startWorkLoopTimer(workInProgress);
14842
14843 do {
14844 try {
14845 workLoopSync();
14846 break;
14847 } catch (thrownValue) {
14848 handleError(root, thrownValue);
14849 }
14850 } while (true);
14851
14852 resetContextDependencies();
14853 executionContext = prevExecutionContext;
14854 popDispatcher(prevDispatcher);
14855
14856 if (enableSchedulerTracing) {
14857 popInteractions(prevInteractions);
14858 }
14859
14860 if (workInProgressRootExitStatus === RootFatalErrored) {
14861 var fatalError = workInProgressRootFatalError;
14862 stopInterruptedWorkLoopTimer();
14863 prepareFreshStack(root, expirationTime);
14864 markRootSuspendedAtTime(root, expirationTime);
14865 ensureRootIsScheduled(root);
14866 throw fatalError;
14867 }
14868
14869 if (workInProgress !== null) {
14870 // This is a sync render, so we should have finished the whole tree.
14871 (function () {
14872 {
14873 {
14874 throw ReactError(Error("Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue."));
14875 }
14876 }
14877 })();
14878 } else {
14879 // We now have a consistent tree. Because this is a sync render, we
14880 // will commit it even if something suspended. The only exception is
14881 // if the root is locked (using the unstable_createBatch API).
14882 stopFinishedWorkLoopTimer();
14883 root.finishedWork = root.current.alternate;
14884 root.finishedExpirationTime = expirationTime;
14885 resolveLocksOnRoot(root, expirationTime);
14886 finishSyncRender(root, workInProgressRootExitStatus, expirationTime);
14887 } // Before exiting, make sure there's a callback scheduled for the next
14888 // pending level.
14889
14890
14891 ensureRootIsScheduled(root);
14892 }
14893 }
14894
14895 return null;
14896}
14897
14898function finishSyncRender(root, exitStatus, expirationTime) {
14899 if (exitStatus === RootLocked) {
14900 // This root has a lock that prevents it from committing. Exit. If we
14901 // begin work on the root again, without any intervening updates, it
14902 // will finish without doing additional work.
14903 markRootSuspendedAtTime(root, expirationTime);
14904 } else {
14905 // Set this to null to indicate there's no in-progress render.
14906 workInProgressRoot = null;
14907
14908 {
14909 if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) {
14910 flushSuspensePriorityWarningInDEV();
14911 }
14912 }
14913
14914 commitRoot(root);
14915 }
14916}
14917
14918
14919
14920
14921function resolveLocksOnRoot(root, expirationTime) {
14922 var firstBatch = root.firstBatch;
14923
14924 if (firstBatch !== null && firstBatch._defer && firstBatch._expirationTime >= expirationTime) {
14925 scheduleCallback(NormalPriority, function () {
14926 firstBatch._onComplete();
14927
14928 return null;
14929 });
14930 workInProgressRootExitStatus = RootLocked;
14931 }
14932}
14933
14934
14935
14936
14937
14938
14939
14940
14941function flushSync(fn, a) {
14942 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
14943 (function () {
14944 {
14945 {
14946 throw ReactError(Error("flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering."));
14947 }
14948 }
14949 })();
14950 }
14951
14952 var prevExecutionContext = executionContext;
14953 executionContext |= BatchedContext;
14954
14955 try {
14956 return runWithPriority(ImmediatePriority, fn.bind(null, a));
14957 } finally {
14958 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
14959 // Note that this will happen even if batchedUpdates is higher up
14960 // the stack.
14961
14962 flushSyncCallbackQueue();
14963 }
14964}
14965
14966
14967function prepareFreshStack(root, expirationTime) {
14968 root.finishedWork = null;
14969 root.finishedExpirationTime = NoWork;
14970 var timeoutHandle = root.timeoutHandle;
14971
14972 if (timeoutHandle !== noTimeout) {
14973 // The root previous suspended and scheduled a timeout to commit a fallback
14974 // state. Now that we have additional work, cancel the timeout.
14975 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
14976
14977 cancelTimeout(timeoutHandle);
14978 }
14979
14980 if (workInProgress !== null) {
14981 var interruptedWork = workInProgress.return;
14982
14983 while (interruptedWork !== null) {
14984 unwindInterruptedWork(interruptedWork);
14985 interruptedWork = interruptedWork.return;
14986 }
14987 }
14988
14989 workInProgressRoot = root;
14990 workInProgress = createWorkInProgress(root.current, null, expirationTime);
14991 renderExpirationTime = expirationTime;
14992 workInProgressRootExitStatus = RootIncomplete;
14993 workInProgressRootFatalError = null;
14994 workInProgressRootLatestProcessedExpirationTime = Sync;
14995 workInProgressRootLatestSuspenseTimeout = Sync;
14996 workInProgressRootCanSuspendUsingConfig = null;
14997 workInProgressRootNextUnprocessedUpdateTime = NoWork;
14998 workInProgressRootHasPendingPing = false;
14999
15000 if (enableSchedulerTracing) {
15001 spawnedWorkDuringRender = null;
15002 }
15003
15004 {
15005 ReactStrictModeWarnings.discardPendingWarnings();
15006 componentsThatTriggeredHighPriSuspend = null;
15007 }
15008}
15009
15010function handleError(root, thrownValue) {
15011 do {
15012 try {
15013 // Reset module-level state that was set during the render phase.
15014 resetContextDependencies();
15015 resetHooks();
15016
15017 if (workInProgress === null || workInProgress.return === null) {
15018 // Expected to be working on a non-root fiber. This is a fatal error
15019 // because there's no ancestor that can handle it; the root is
15020 // supposed to capture all errors that weren't caught by an error
15021 // boundary.
15022 workInProgressRootExitStatus = RootFatalErrored;
15023 workInProgressRootFatalError = thrownValue;
15024 return null;
15025 }
15026
15027 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15028 // Record the time spent rendering before an error was thrown. This
15029 // avoids inaccurate Profiler durations in the case of a
15030 // suspended render.
15031 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
15032 }
15033
15034 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime);
15035 workInProgress = completeUnitOfWork(workInProgress);
15036 } catch (yetAnotherThrownValue) {
15037 // Something in the return path also threw.
15038 thrownValue = yetAnotherThrownValue;
15039 continue;
15040 } // Return to the normal work loop.
15041
15042
15043 return;
15044 } while (true);
15045}
15046
15047function pushDispatcher(root) {
15048 var prevDispatcher = ReactCurrentDispatcher.current;
15049 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
15050
15051 if (prevDispatcher === null) {
15052 // The React isomorphic package does not include a default dispatcher.
15053 // Instead the first renderer will lazily attach one, in order to give
15054 // nicer error messages.
15055 return ContextOnlyDispatcher;
15056 } else {
15057 return prevDispatcher;
15058 }
15059}
15060
15061function popDispatcher(prevDispatcher) {
15062 ReactCurrentDispatcher.current = prevDispatcher;
15063}
15064
15065function pushInteractions(root) {
15066 if (enableSchedulerTracing) {
15067 var prevInteractions = __interactionsRef.current;
15068 __interactionsRef.current = root.memoizedInteractions;
15069 return prevInteractions;
15070 }
15071
15072 return null;
15073}
15074
15075function popInteractions(prevInteractions) {
15076 if (enableSchedulerTracing) {
15077 __interactionsRef.current = prevInteractions;
15078 }
15079}
15080
15081function markCommitTimeOfFallback() {
15082 globalMostRecentFallbackTime = now();
15083}
15084function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
15085 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
15086 workInProgressRootLatestProcessedExpirationTime = expirationTime;
15087 }
15088
15089 if (suspenseConfig !== null) {
15090 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
15091 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
15092
15093 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
15094 }
15095 }
15096}
15097function markUnprocessedUpdateTime(expirationTime) {
15098 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
15099 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
15100 }
15101}
15102function renderDidSuspend() {
15103 if (workInProgressRootExitStatus === RootIncomplete) {
15104 workInProgressRootExitStatus = RootSuspended;
15105 }
15106}
15107function renderDidSuspendDelayIfPossible() {
15108 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
15109 workInProgressRootExitStatus = RootSuspendedWithDelay;
15110 } // Check if there's a lower priority update somewhere else in the tree.
15111
15112
15113 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
15114 // Mark the current render as suspended, and then mark that there's a
15115 // pending update.
15116 // TODO: This should immediately interrupt the current render, instead
15117 // of waiting until the next time we yield.
15118 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime);
15119 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
15120 }
15121}
15122function renderDidError() {
15123 if (workInProgressRootExitStatus !== RootCompleted) {
15124 workInProgressRootExitStatus = RootErrored;
15125 }
15126} // Called during render to determine if anything has suspended.
15127// Returns false if we're not sure.
15128
15129function renderHasNotSuspendedYet() {
15130 // If something errored or completed, we can't really be sure,
15131 // so those are false.
15132 return workInProgressRootExitStatus === RootIncomplete;
15133}
15134
15135function inferTimeFromExpirationTime(expirationTime) {
15136 // We don't know exactly when the update was scheduled, but we can infer an
15137 // approximate start time from the expiration time.
15138 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
15139 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
15140}
15141
15142function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
15143 // We don't know exactly when the update was scheduled, but we can infer an
15144 // approximate start time from the expiration time by subtracting the timeout
15145 // that was added to the event time.
15146 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
15147 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
15148} // The work loop is an extremely hot path. Tell Closure not to inline it.
15149
15150/** @noinline */
15151
15152
15153function workLoopSync() {
15154 // Already timed out, so perform work without checking if we need to yield.
15155 while (workInProgress !== null) {
15156 workInProgress = performUnitOfWork(workInProgress);
15157 }
15158}
15159/** @noinline */
15160
15161
15162function workLoopConcurrent() {
15163 // Perform work until Scheduler asks us to yield
15164 while (workInProgress !== null && !shouldYield()) {
15165 workInProgress = performUnitOfWork(workInProgress);
15166 }
15167}
15168
15169function performUnitOfWork(unitOfWork) {
15170 // The current, flushed, state of this fiber is the alternate. Ideally
15171 // nothing should rely on this, but relying on it here means that we don't
15172 // need an additional field on the work in progress.
15173 var current = unitOfWork.alternate;
15174 startWorkTimer(unitOfWork);
15175 setCurrentFiber(unitOfWork);
15176 var next;
15177
15178 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
15179 startProfilerTimer(unitOfWork);
15180 next = beginWork$$1(current, unitOfWork, renderExpirationTime);
15181 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
15182 } else {
15183 next = beginWork$$1(current, unitOfWork, renderExpirationTime);
15184 }
15185
15186 resetCurrentFiber();
15187 unitOfWork.memoizedProps = unitOfWork.pendingProps;
15188
15189 if (next === null) {
15190 // If this doesn't spawn new work, complete the current work.
15191 next = completeUnitOfWork(unitOfWork);
15192 }
15193
15194 ReactCurrentOwner$1.current = null;
15195 return next;
15196}
15197
15198function completeUnitOfWork(unitOfWork) {
15199 // Attempt to complete the current unit of work, then move to the next
15200 // sibling. If there are no more siblings, return to the parent fiber.
15201 workInProgress = unitOfWork;
15202
15203 do {
15204 // The current, flushed, state of this fiber is the alternate. Ideally
15205 // nothing should rely on this, but relying on it here means that we don't
15206 // need an additional field on the work in progress.
15207 var current = workInProgress.alternate;
15208 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
15209
15210 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
15211 setCurrentFiber(workInProgress);
15212 var next = void 0;
15213
15214 if (!enableProfilerTimer || (workInProgress.mode & ProfileMode) === NoMode) {
15215 next = completeWork(current, workInProgress, renderExpirationTime);
15216 } else {
15217 startProfilerTimer(workInProgress);
15218 next = completeWork(current, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error.
15219
15220 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
15221 }
15222
15223 stopWorkTimer(workInProgress);
15224 resetCurrentFiber();
15225 resetChildExpirationTime(workInProgress);
15226
15227 if (next !== null) {
15228 // Completing this fiber spawned new work. Work on that next.
15229 return next;
15230 }
15231
15232 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
15233 (returnFiber.effectTag & Incomplete) === NoEffect) {
15234 // Append all the effects of the subtree and this fiber onto the effect
15235 // list of the parent. The completion order of the children affects the
15236 // side-effect order.
15237 if (returnFiber.firstEffect === null) {
15238 returnFiber.firstEffect = workInProgress.firstEffect;
15239 }
15240
15241 if (workInProgress.lastEffect !== null) {
15242 if (returnFiber.lastEffect !== null) {
15243 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
15244 }
15245
15246 returnFiber.lastEffect = workInProgress.lastEffect;
15247 } // If this fiber had side-effects, we append it AFTER the children's
15248 // side-effects. We can perform certain side-effects earlier if needed,
15249 // by doing multiple passes over the effect list. We don't want to
15250 // schedule our own side-effect on our own list because if end up
15251 // reusing children we'll schedule this effect onto itself since we're
15252 // at the end.
15253
15254
15255 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
15256 // list. PerformedWork effect is read by React DevTools but shouldn't be
15257 // committed.
15258
15259 if (effectTag > PerformedWork) {
15260 if (returnFiber.lastEffect !== null) {
15261 returnFiber.lastEffect.nextEffect = workInProgress;
15262 } else {
15263 returnFiber.firstEffect = workInProgress;
15264 }
15265
15266 returnFiber.lastEffect = workInProgress;
15267 }
15268 }
15269 } else {
15270 // This fiber did not complete because something threw. Pop values off
15271 // the stack without entering the complete phase. If this is a boundary,
15272 // capture values if possible.
15273 var _next = unwindWork(workInProgress, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time.
15274
15275
15276 if (enableProfilerTimer && (workInProgress.mode & ProfileMode) !== NoMode) {
15277 // Record the render duration for the fiber that errored.
15278 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
15279
15280 var actualDuration = workInProgress.actualDuration;
15281 var child = workInProgress.child;
15282
15283 while (child !== null) {
15284 actualDuration += child.actualDuration;
15285 child = child.sibling;
15286 }
15287
15288 workInProgress.actualDuration = actualDuration;
15289 }
15290
15291 if (_next !== null) {
15292 // If completing this work spawned new work, do that next. We'll come
15293 // back here again.
15294 // Since we're restarting, remove anything that is not a host effect
15295 // from the effect tag.
15296 // TODO: The name stopFailedWorkTimer is misleading because Suspense
15297 // also captures and restarts.
15298 stopFailedWorkTimer(workInProgress);
15299 _next.effectTag &= HostEffectMask;
15300 return _next;
15301 }
15302
15303 stopWorkTimer(workInProgress);
15304
15305 if (returnFiber !== null) {
15306 // Mark the parent fiber as incomplete and clear its effect list.
15307 returnFiber.firstEffect = returnFiber.lastEffect = null;
15308 returnFiber.effectTag |= Incomplete;
15309 }
15310 }
15311
15312 var siblingFiber = workInProgress.sibling;
15313
15314 if (siblingFiber !== null) {
15315 // If there is more work to do in this returnFiber, do that next.
15316 return siblingFiber;
15317 } // Otherwise, return to the parent
15318
15319
15320 workInProgress = returnFiber;
15321 } while (workInProgress !== null); // We've reached the root.
15322
15323
15324 if (workInProgressRootExitStatus === RootIncomplete) {
15325 workInProgressRootExitStatus = RootCompleted;
15326 }
15327
15328 return null;
15329}
15330
15331function getRemainingExpirationTime(fiber) {
15332 var updateExpirationTime = fiber.expirationTime;
15333 var childExpirationTime = fiber.childExpirationTime;
15334 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
15335}
15336
15337function resetChildExpirationTime(completedWork) {
15338 if (renderExpirationTime !== Never && completedWork.childExpirationTime === Never) {
15339 // The children of this component are hidden. Don't bubble their
15340 // expiration times.
15341 return;
15342 }
15343
15344 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
15345
15346 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) {
15347 // In profiling mode, resetChildExpirationTime is also used to reset
15348 // profiler durations.
15349 var actualDuration = completedWork.actualDuration;
15350 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
15351 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
15352 // When work is done, it should bubble to the parent's actualDuration. If
15353 // the fiber has not been cloned though, (meaning no work was done), then
15354 // this value will reflect the amount of time spent working on a previous
15355 // render. In that case it should not bubble. We determine whether it was
15356 // cloned by comparing the child pointer.
15357
15358 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
15359 var child = completedWork.child;
15360
15361 while (child !== null) {
15362 var childUpdateExpirationTime = child.expirationTime;
15363 var childChildExpirationTime = child.childExpirationTime;
15364
15365 if (childUpdateExpirationTime > newChildExpirationTime) {
15366 newChildExpirationTime = childUpdateExpirationTime;
15367 }
15368
15369 if (childChildExpirationTime > newChildExpirationTime) {
15370 newChildExpirationTime = childChildExpirationTime;
15371 }
15372
15373 if (shouldBubbleActualDurations) {
15374 actualDuration += child.actualDuration;
15375 }
15376
15377 treeBaseDuration += child.treeBaseDuration;
15378 child = child.sibling;
15379 }
15380
15381 completedWork.actualDuration = actualDuration;
15382 completedWork.treeBaseDuration = treeBaseDuration;
15383 } else {
15384 var _child = completedWork.child;
15385
15386 while (_child !== null) {
15387 var _childUpdateExpirationTime = _child.expirationTime;
15388 var _childChildExpirationTime = _child.childExpirationTime;
15389
15390 if (_childUpdateExpirationTime > newChildExpirationTime) {
15391 newChildExpirationTime = _childUpdateExpirationTime;
15392 }
15393
15394 if (_childChildExpirationTime > newChildExpirationTime) {
15395 newChildExpirationTime = _childChildExpirationTime;
15396 }
15397
15398 _child = _child.sibling;
15399 }
15400 }
15401
15402 completedWork.childExpirationTime = newChildExpirationTime;
15403}
15404
15405function commitRoot(root) {
15406 var renderPriorityLevel = getCurrentPriorityLevel();
15407 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
15408 return null;
15409}
15410
15411function commitRootImpl(root, renderPriorityLevel) {
15412 flushPassiveEffects();
15413 flushRenderPhaseStrictModeWarningsInDEV();
15414
15415 (function () {
15416 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
15417 {
15418 throw ReactError(Error("Should not already be working."));
15419 }
15420 }
15421 })();
15422
15423 var finishedWork = root.finishedWork;
15424 var expirationTime = root.finishedExpirationTime;
15425
15426 if (finishedWork === null) {
15427 return null;
15428 }
15429
15430 root.finishedWork = null;
15431 root.finishedExpirationTime = NoWork;
15432
15433 (function () {
15434 if (!(finishedWork !== root.current)) {
15435 {
15436 throw ReactError(Error("Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue."));
15437 }
15438 }
15439 })(); // commitRoot never returns a continuation; it always finishes synchronously.
15440 // So we can clear these now to allow a new callback to be scheduled.
15441
15442
15443 root.callbackNode = null;
15444 root.callbackExpirationTime = NoWork;
15445 root.callbackPriority = NoPriority;
15446 root.nextKnownPendingLevel = NoWork;
15447 startCommitTimer(); // Update the first and last pending times on this root. The new first
15448 // pending time is whatever is left on the root fiber.
15449
15450 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
15451 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
15452
15453 if (root === workInProgressRoot) {
15454 // We can reset these now that they are finished.
15455 workInProgressRoot = null;
15456 workInProgress = null;
15457 renderExpirationTime = NoWork;
15458 } else {} // This indicates that the last root we worked on is not the same one that
15459 // we're committing now. This most commonly happens when a suspended root
15460 // times out.
15461 // Get the list of effects.
15462
15463
15464 var firstEffect;
15465
15466 if (finishedWork.effectTag > PerformedWork) {
15467 // A fiber's effect list consists only of its children, not itself. So if
15468 // the root has an effect, we need to add it to the end of the list. The
15469 // resulting list is the set that would belong to the root's parent, if it
15470 // had one; that is, all the effects in the tree including the root.
15471 if (finishedWork.lastEffect !== null) {
15472 finishedWork.lastEffect.nextEffect = finishedWork;
15473 firstEffect = finishedWork.firstEffect;
15474 } else {
15475 firstEffect = finishedWork;
15476 }
15477 } else {
15478 // There is no effect on the root.
15479 firstEffect = finishedWork.firstEffect;
15480 }
15481
15482 if (firstEffect !== null) {
15483 var prevExecutionContext = executionContext;
15484 executionContext |= CommitContext;
15485 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
15486
15487 ReactCurrentOwner$1.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
15488 // of the effect list for each phase: all mutation effects come before all
15489 // layout effects, and so on.
15490 // The first phase a "before mutation" phase. We use this phase to read the
15491 // state of the host tree right before we mutate it. This is where
15492 // getSnapshotBeforeUpdate is called.
15493
15494 startCommitSnapshotEffectsTimer();
15495 prepareForCommit(root.containerInfo);
15496 nextEffect = firstEffect;
15497
15498 do {
15499 {
15500 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
15501
15502 if (hasCaughtError()) {
15503 (function () {
15504 if (!(nextEffect !== null)) {
15505 {
15506 throw ReactError(Error("Should be working on an effect."));
15507 }
15508 }
15509 })();
15510
15511 var error = clearCaughtError();
15512 captureCommitPhaseError(nextEffect, error);
15513 nextEffect = nextEffect.nextEffect;
15514 }
15515 }
15516 } while (nextEffect !== null);
15517
15518 stopCommitSnapshotEffectsTimer();
15519
15520 if (enableProfilerTimer) {
15521 // Mark the current commit time to be shared by all Profilers in this
15522 // batch. This enables them to be grouped later.
15523 recordCommitTime();
15524 } // The next phase is the mutation phase, where we mutate the host tree.
15525
15526
15527 startCommitHostEffectsTimer();
15528 nextEffect = firstEffect;
15529
15530 do {
15531 {
15532 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
15533
15534 if (hasCaughtError()) {
15535 (function () {
15536 if (!(nextEffect !== null)) {
15537 {
15538 throw ReactError(Error("Should be working on an effect."));
15539 }
15540 }
15541 })();
15542
15543 var _error = clearCaughtError();
15544
15545 captureCommitPhaseError(nextEffect, _error);
15546 nextEffect = nextEffect.nextEffect;
15547 }
15548 }
15549 } while (nextEffect !== null);
15550
15551 stopCommitHostEffectsTimer();
15552 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
15553 // the mutation phase, so that the previous tree is still current during
15554 // componentWillUnmount, but before the layout phase, so that the finished
15555 // work is current during componentDidMount/Update.
15556
15557 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
15558 // the host tree after it's been mutated. The idiomatic use case for this is
15559 // layout, but class component lifecycles also fire here for legacy reasons.
15560
15561 startCommitLifeCyclesTimer();
15562 nextEffect = firstEffect;
15563
15564 do {
15565 {
15566 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
15567
15568 if (hasCaughtError()) {
15569 (function () {
15570 if (!(nextEffect !== null)) {
15571 {
15572 throw ReactError(Error("Should be working on an effect."));
15573 }
15574 }
15575 })();
15576
15577 var _error2 = clearCaughtError();
15578
15579 captureCommitPhaseError(nextEffect, _error2);
15580 nextEffect = nextEffect.nextEffect;
15581 }
15582 }
15583 } while (nextEffect !== null);
15584
15585 stopCommitLifeCyclesTimer();
15586 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
15587 // opportunity to paint.
15588
15589 requestPaint();
15590
15591 if (enableSchedulerTracing) {
15592 popInteractions(prevInteractions);
15593 }
15594
15595 executionContext = prevExecutionContext;
15596 } else {
15597 // No effects.
15598 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
15599 // no effects.
15600 // TODO: Maybe there's a better way to report this.
15601
15602 startCommitSnapshotEffectsTimer();
15603 stopCommitSnapshotEffectsTimer();
15604
15605 if (enableProfilerTimer) {
15606 recordCommitTime();
15607 }
15608
15609 startCommitHostEffectsTimer();
15610 stopCommitHostEffectsTimer();
15611 startCommitLifeCyclesTimer();
15612 stopCommitLifeCyclesTimer();
15613 }
15614
15615 stopCommitTimer();
15616 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
15617
15618 if (rootDoesHavePassiveEffects) {
15619 // This commit has passive effects. Stash a reference to them. But don't
15620 // schedule a callback until after flushing layout work.
15621 rootDoesHavePassiveEffects = false;
15622 rootWithPendingPassiveEffects = root;
15623 pendingPassiveEffectsExpirationTime = expirationTime;
15624 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
15625 } else {
15626 // We are done with the effect chain at this point so let's clear the
15627 // nextEffect pointers to assist with GC. If we have passive effects, we'll
15628 // clear this in flushPassiveEffects.
15629 nextEffect = firstEffect;
15630
15631 while (nextEffect !== null) {
15632 var nextNextEffect = nextEffect.nextEffect;
15633 nextEffect.nextEffect = null;
15634 nextEffect = nextNextEffect;
15635 }
15636 } // Check if there's remaining work on this root
15637
15638
15639 var remainingExpirationTime = root.firstPendingTime;
15640
15641 if (remainingExpirationTime !== NoWork) {
15642 if (enableSchedulerTracing) {
15643 if (spawnedWorkDuringRender !== null) {
15644 var expirationTimes = spawnedWorkDuringRender;
15645 spawnedWorkDuringRender = null;
15646
15647 for (var i = 0; i < expirationTimes.length; i++) {
15648 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
15649 }
15650 }
15651
15652 schedulePendingInteractions(root, remainingExpirationTime);
15653 }
15654 } else {
15655 // If there's no remaining work, we can clear the set of already failed
15656 // error boundaries.
15657 legacyErrorBoundariesThatAlreadyFailed = null;
15658 }
15659
15660 if (enableSchedulerTracing) {
15661 if (!rootDidHavePassiveEffects) {
15662 // If there are no passive effects, then we can complete the pending interactions.
15663 // Otherwise, we'll wait until after the passive effects are flushed.
15664 // Wait to do this until after remaining work has been scheduled,
15665 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
15666 finishPendingInteractions(root, expirationTime);
15667 }
15668 }
15669
15670 if (remainingExpirationTime === Sync) {
15671 // Count the number of times the root synchronously re-renders without
15672 // finishing. If there are too many, it indicates an infinite update loop.
15673 if (root === rootWithNestedUpdates) {
15674 nestedUpdateCount++;
15675 } else {
15676 nestedUpdateCount = 0;
15677 rootWithNestedUpdates = root;
15678 }
15679 } else {
15680 nestedUpdateCount = 0;
15681 }
15682
15683 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
15684 // additional work on this root is scheduled.
15685
15686 ensureRootIsScheduled(root);
15687
15688 if (hasUncaughtError) {
15689 hasUncaughtError = false;
15690 var _error3 = firstUncaughtError;
15691 firstUncaughtError = null;
15692 throw _error3;
15693 }
15694
15695 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
15696 // This is a legacy edge case. We just committed the initial mount of
15697 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
15698 // synchronously, but layout updates should be deferred until the end
15699 // of the batch.
15700 return null;
15701 } // If layout work was scheduled, flush it now.
15702
15703
15704 flushSyncCallbackQueue();
15705 return null;
15706}
15707
15708function commitBeforeMutationEffects() {
15709 while (nextEffect !== null) {
15710 var effectTag = nextEffect.effectTag;
15711
15712 if ((effectTag & Snapshot) !== NoEffect) {
15713 setCurrentFiber(nextEffect);
15714 recordEffect();
15715 var current = nextEffect.alternate;
15716 commitBeforeMutationLifeCycles(current, nextEffect);
15717 resetCurrentFiber();
15718 }
15719
15720 if ((effectTag & Passive) !== NoEffect) {
15721 // If there are passive effects, schedule a callback to flush at
15722 // the earliest opportunity.
15723 if (!rootDoesHavePassiveEffects) {
15724 rootDoesHavePassiveEffects = true;
15725 scheduleCallback(NormalPriority, function () {
15726 flushPassiveEffects();
15727 return null;
15728 });
15729 }
15730 }
15731
15732 nextEffect = nextEffect.nextEffect;
15733 }
15734}
15735
15736function commitMutationEffects(root, renderPriorityLevel) {
15737 // TODO: Should probably move the bulk of this function to commitWork.
15738 while (nextEffect !== null) {
15739 setCurrentFiber(nextEffect);
15740 var effectTag = nextEffect.effectTag;
15741
15742 if (effectTag & ContentReset) {
15743 commitResetTextContent(nextEffect);
15744 }
15745
15746 if (effectTag & Ref) {
15747 var current = nextEffect.alternate;
15748
15749 if (current !== null) {
15750 commitDetachRef(current);
15751 }
15752 } // The following switch statement is only concerned about placement,
15753 // updates, and deletions. To avoid needing to add a case for every possible
15754 // bitmap value, we remove the secondary effects from the effect tag and
15755 // switch on that value.
15756
15757
15758 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
15759
15760 switch (primaryEffectTag) {
15761 case Placement:
15762 {
15763 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
15764 // inserted, before any life-cycles like componentDidMount gets called.
15765 // TODO: findDOMNode doesn't rely on this any more but isMounted does
15766 // and isMounted is deprecated anyway so we should be able to kill this.
15767
15768 nextEffect.effectTag &= ~Placement;
15769 break;
15770 }
15771
15772 case PlacementAndUpdate:
15773 {
15774 // Placement
15775 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
15776 // inserted, before any life-cycles like componentDidMount gets called.
15777
15778 nextEffect.effectTag &= ~Placement; // Update
15779
15780 var _current = nextEffect.alternate;
15781 commitWork(_current, nextEffect);
15782 break;
15783 }
15784
15785 case Hydrating:
15786 {
15787 nextEffect.effectTag &= ~Hydrating;
15788 break;
15789 }
15790
15791 case HydratingAndUpdate:
15792 {
15793 nextEffect.effectTag &= ~Hydrating; // Update
15794
15795 var _current2 = nextEffect.alternate;
15796 commitWork(_current2, nextEffect);
15797 break;
15798 }
15799
15800 case Update:
15801 {
15802 var _current3 = nextEffect.alternate;
15803 commitWork(_current3, nextEffect);
15804 break;
15805 }
15806
15807 case Deletion:
15808 {
15809 commitDeletion(root, nextEffect, renderPriorityLevel);
15810 break;
15811 }
15812 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
15813
15814
15815 recordEffect();
15816 resetCurrentFiber();
15817 nextEffect = nextEffect.nextEffect;
15818 }
15819}
15820
15821function commitLayoutEffects(root, committedExpirationTime) {
15822 // TODO: Should probably move the bulk of this function to commitWork.
15823 while (nextEffect !== null) {
15824 setCurrentFiber(nextEffect);
15825 var effectTag = nextEffect.effectTag;
15826
15827 if (effectTag & (Update | Callback)) {
15828 recordEffect();
15829 var current = nextEffect.alternate;
15830 commitLifeCycles(root, current, nextEffect, committedExpirationTime);
15831 }
15832
15833 if (effectTag & Ref) {
15834 recordEffect();
15835 commitAttachRef(nextEffect);
15836 }
15837
15838 resetCurrentFiber();
15839 nextEffect = nextEffect.nextEffect;
15840 }
15841}
15842
15843function flushPassiveEffects() {
15844 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
15845 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
15846 pendingPassiveEffectsRenderPriority = NoPriority;
15847 return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
15848 }
15849}
15850
15851function flushPassiveEffectsImpl() {
15852 if (rootWithPendingPassiveEffects === null) {
15853 return false;
15854 }
15855
15856 var root = rootWithPendingPassiveEffects;
15857 var expirationTime = pendingPassiveEffectsExpirationTime;
15858 rootWithPendingPassiveEffects = null;
15859 pendingPassiveEffectsExpirationTime = NoWork;
15860
15861 (function () {
15862 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
15863 {
15864 throw ReactError(Error("Cannot flush passive effects while already rendering."));
15865 }
15866 }
15867 })();
15868
15869 var prevExecutionContext = executionContext;
15870 executionContext |= CommitContext;
15871 var prevInteractions = pushInteractions(root); // Note: This currently assumes there are no passive effects on the root
15872 // fiber, because the root is not part of its own effect list. This could
15873 // change in the future.
15874
15875 var effect = root.current.firstEffect;
15876
15877 while (effect !== null) {
15878 {
15879 setCurrentFiber(effect);
15880 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
15881
15882 if (hasCaughtError()) {
15883 (function () {
15884 if (!(effect !== null)) {
15885 {
15886 throw ReactError(Error("Should be working on an effect."));
15887 }
15888 }
15889 })();
15890
15891 var error = clearCaughtError();
15892 captureCommitPhaseError(effect, error);
15893 }
15894
15895 resetCurrentFiber();
15896 }
15897
15898 var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC
15899
15900 effect.nextEffect = null;
15901 effect = nextNextEffect;
15902 }
15903
15904 if (enableSchedulerTracing) {
15905 popInteractions(prevInteractions);
15906 finishPendingInteractions(root, expirationTime);
15907 }
15908
15909 executionContext = prevExecutionContext;
15910 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
15911 // exceeds the limit, we'll fire a warning.
15912
15913 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
15914 return true;
15915}
15916
15917function isAlreadyFailedLegacyErrorBoundary(instance) {
15918 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
15919}
15920function markLegacyErrorBoundaryAsFailed(instance) {
15921 if (legacyErrorBoundariesThatAlreadyFailed === null) {
15922 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
15923 } else {
15924 legacyErrorBoundariesThatAlreadyFailed.add(instance);
15925 }
15926}
15927
15928function prepareToThrowUncaughtError(error) {
15929 if (!hasUncaughtError) {
15930 hasUncaughtError = true;
15931 firstUncaughtError = error;
15932 }
15933}
15934
15935var onUncaughtError = prepareToThrowUncaughtError;
15936
15937function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
15938 var errorInfo = createCapturedValue(error, sourceFiber);
15939 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
15940 enqueueUpdate(rootFiber, update);
15941 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
15942
15943 if (root !== null) {
15944 ensureRootIsScheduled(root);
15945 schedulePendingInteractions(root, Sync);
15946 }
15947}
15948
15949function captureCommitPhaseError(sourceFiber, error) {
15950 if (sourceFiber.tag === HostRoot) {
15951 // Error was thrown at the root. There is no parent, so the root
15952 // itself should capture it.
15953 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
15954 return;
15955 }
15956
15957 var fiber = sourceFiber.return;
15958
15959 while (fiber !== null) {
15960 if (fiber.tag === HostRoot) {
15961 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
15962 return;
15963 } else if (fiber.tag === ClassComponent) {
15964 var ctor = fiber.type;
15965 var instance = fiber.stateNode;
15966
15967 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
15968 var errorInfo = createCapturedValue(error, sourceFiber);
15969 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
15970 Sync);
15971 enqueueUpdate(fiber, update);
15972 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
15973
15974 if (root !== null) {
15975 ensureRootIsScheduled(root);
15976 schedulePendingInteractions(root, Sync);
15977 }
15978
15979 return;
15980 }
15981 }
15982
15983 fiber = fiber.return;
15984 }
15985}
15986function pingSuspendedRoot(root, thenable, suspendedTime) {
15987 var pingCache = root.pingCache;
15988
15989 if (pingCache !== null) {
15990 // The thenable resolved, so we no longer need to memoize, because it will
15991 // never be thrown again.
15992 pingCache.delete(thenable);
15993 }
15994
15995 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {
15996 // Received a ping at the same priority level at which we're currently
15997 // rendering. We might want to restart this render. This should mirror
15998 // the logic of whether or not a root suspends once it completes.
15999 // TODO: If we're rendering sync either due to Sync, Batched or expired,
16000 // we should probably never restart.
16001 // If we're suspended with delay, we'll always suspend so we can always
16002 // restart. If we're suspended without any updates, it might be a retry.
16003 // If it's early in the retry we can restart. We can't know for sure
16004 // whether we'll eventually process an update during this render pass,
16005 // but it's somewhat unlikely that we get to a ping before that, since
16006 // getting to the root most update is usually very fast.
16007 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
16008 // Restart from the root. Don't need to schedule a ping because
16009 // we're already working on this tree.
16010 prepareFreshStack(root, renderExpirationTime);
16011 } else {
16012 // Even though we can't restart right now, we might get an
16013 // opportunity later. So we mark this render as having a ping.
16014 workInProgressRootHasPendingPing = true;
16015 }
16016
16017 return;
16018 }
16019
16020 if (!isRootSuspendedAtTime(root, suspendedTime)) {
16021 // The root is no longer suspended at this time.
16022 return;
16023 }
16024
16025 var lastPingedTime = root.lastPingedTime;
16026
16027 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
16028 // There's already a lower priority ping scheduled.
16029 return;
16030 } // Mark the time at which this ping was scheduled.
16031
16032
16033 root.lastPingedTime = suspendedTime;
16034
16035 if (root.finishedExpirationTime === suspendedTime) {
16036 // If there's a pending fallback waiting to commit, throw it away.
16037 root.finishedExpirationTime = NoWork;
16038 root.finishedWork = null;
16039 }
16040
16041 ensureRootIsScheduled(root);
16042 schedulePendingInteractions(root, suspendedTime);
16043}
16044
16045function retryTimedOutBoundary(boundaryFiber, retryTime) {
16046 // The boundary fiber (a Suspense component or SuspenseList component)
16047 // previously was rendered in its fallback state. One of the promises that
16048 // suspended it has resolved, which means at least part of the tree was
16049 // likely unblocked. Try rendering again, at a new expiration time.
16050 if (retryTime === Never) {
16051 var suspenseConfig = null; // Retries don't carry over the already committed update.
16052
16053 var currentTime = requestCurrentTime();
16054 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
16055 } // TODO: Special case idle priority?
16056
16057
16058 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
16059
16060 if (root !== null) {
16061 ensureRootIsScheduled(root);
16062 schedulePendingInteractions(root, retryTime);
16063 }
16064}
16065
16066function retryDehydratedSuspenseBoundary(boundaryFiber) {
16067 var suspenseState = boundaryFiber.memoizedState;
16068 var retryTime = Never;
16069
16070 if (suspenseState !== null) {
16071 retryTime = suspenseState.retryTime;
16072 }
16073
16074 retryTimedOutBoundary(boundaryFiber, retryTime);
16075}
16076function resolveRetryThenable(boundaryFiber, thenable) {
16077 var retryTime = Never; // Default
16078
16079 var retryCache;
16080
16081 if (enableSuspenseServerRenderer) {
16082 switch (boundaryFiber.tag) {
16083 case SuspenseComponent:
16084 retryCache = boundaryFiber.stateNode;
16085 var suspenseState = boundaryFiber.memoizedState;
16086
16087 if (suspenseState !== null) {
16088 retryTime = suspenseState.retryTime;
16089 }
16090
16091 break;
16092
16093 case SuspenseListComponent:
16094 retryCache = boundaryFiber.stateNode;
16095 break;
16096
16097 default:
16098 (function () {
16099 {
16100 {
16101 throw ReactError(Error("Pinged unknown suspense boundary type. This is probably a bug in React."));
16102 }
16103 }
16104 })();
16105
16106 }
16107 } else {
16108 retryCache = boundaryFiber.stateNode;
16109 }
16110
16111 if (retryCache !== null) {
16112 // The thenable resolved, so we no longer need to memoize, because it will
16113 // never be thrown again.
16114 retryCache.delete(thenable);
16115 }
16116
16117 retryTimedOutBoundary(boundaryFiber, retryTime);
16118} // Computes the next Just Noticeable Difference (JND) boundary.
16119// The theory is that a person can't tell the difference between small differences in time.
16120// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
16121// difference in the experience. However, waiting for longer might mean that we can avoid
16122// showing an intermediate loading state. The longer we have already waited, the harder it
16123// is to tell small differences in time. Therefore, the longer we've already waited,
16124// the longer we can wait additionally. At some point we have to give up though.
16125// We pick a train model where the next boundary commits at a consistent schedule.
16126// These particular numbers are vague estimates. We expect to adjust them based on research.
16127
16128function jnd(timeElapsed) {
16129 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
16130}
16131
16132function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
16133 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
16134
16135 if (busyMinDurationMs <= 0) {
16136 return 0;
16137 }
16138
16139 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
16140
16141 var currentTimeMs = now();
16142 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
16143 var timeElapsed = currentTimeMs - eventTimeMs;
16144
16145 if (timeElapsed <= busyDelayMs) {
16146 // If we haven't yet waited longer than the initial delay, we don't
16147 // have to wait any additional time.
16148 return 0;
16149 }
16150
16151 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
16152
16153 return msUntilTimeout;
16154}
16155
16156function checkForNestedUpdates() {
16157 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
16158 nestedUpdateCount = 0;
16159 rootWithNestedUpdates = null;
16160
16161 (function () {
16162 {
16163 {
16164 throw ReactError(Error("Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops."));
16165 }
16166 }
16167 })();
16168 }
16169
16170 {
16171 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
16172 nestedPassiveUpdateCount = 0;
16173 warning$1(false, 'Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
16174 }
16175 }
16176}
16177
16178function flushRenderPhaseStrictModeWarningsInDEV() {
16179 {
16180 ReactStrictModeWarnings.flushLegacyContextWarning();
16181
16182 if (warnAboutDeprecatedLifecycles) {
16183 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
16184 }
16185 }
16186}
16187
16188function stopFinishedWorkLoopTimer() {
16189 var didCompleteRoot = true;
16190 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
16191 interruptedBy = null;
16192}
16193
16194function stopInterruptedWorkLoopTimer() {
16195 // TODO: Track which fiber caused the interruption.
16196 var didCompleteRoot = false;
16197 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
16198 interruptedBy = null;
16199}
16200
16201function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
16202 if (enableUserTimingAPI && workInProgressRoot !== null && updateExpirationTime > renderExpirationTime) {
16203 interruptedBy = fiberThatReceivedUpdate;
16204 }
16205}
16206
16207var didWarnStateUpdateForUnmountedComponent = null;
16208
16209function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
16210 {
16211 var tag = fiber.tag;
16212
16213 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
16214 // Only warn for user-defined components, not internal ones like Suspense.
16215 return;
16216 } // We show the whole stack but dedupe on the top component's name because
16217 // the problematic code almost always lies inside that component.
16218
16219
16220 var componentName = getComponentName(fiber.type) || 'ReactComponent';
16221
16222 if (didWarnStateUpdateForUnmountedComponent !== null) {
16223 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
16224 return;
16225 }
16226
16227 didWarnStateUpdateForUnmountedComponent.add(componentName);
16228 } else {
16229 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
16230 }
16231
16232 warningWithoutStack$1(false, "Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
16233 }
16234}
16235
16236var beginWork$$1;
16237
16238if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
16239 var dummyFiber = null;
16240
16241 beginWork$$1 = function (current, unitOfWork, expirationTime) {
16242 // If a component throws an error, we replay it again in a synchronously
16243 // dispatched event, so that the debugger will treat it as an uncaught
16244 // error See ReactErrorUtils for more information.
16245 // Before entering the begin phase, copy the work-in-progress onto a dummy
16246 // fiber. If beginWork throws, we'll use this to reset the state.
16247 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
16248
16249 try {
16250 return beginWork$1(current, unitOfWork, expirationTime);
16251 } catch (originalError) {
16252 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
16253 // Don't replay promises. Treat everything else like an error.
16254 throw originalError;
16255 } // Keep this code in sync with renderRoot; any changes here must have
16256 // corresponding changes there.
16257
16258
16259 resetContextDependencies();
16260 resetHooks(); // Unwind the failed stack frame
16261
16262 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
16263
16264 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
16265
16266 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {
16267 // Reset the profiler timer.
16268 startProfilerTimer(unitOfWork);
16269 } // Run beginWork again.
16270
16271
16272 invokeGuardedCallback(null, beginWork$1, null, current, unitOfWork, expirationTime);
16273
16274 if (hasCaughtError()) {
16275 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
16276 // Rethrow this error instead of the original one.
16277
16278 throw replayError;
16279 } else {
16280 // This branch is reachable if the render phase is impure.
16281 throw originalError;
16282 }
16283 }
16284 };
16285} else {
16286 beginWork$$1 = beginWork$1;
16287}
16288
16289var didWarnAboutUpdateInRender = false;
16290var didWarnAboutUpdateInGetChildContext = false;
16291
16292function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
16293 {
16294 if (fiber.tag === ClassComponent) {
16295 switch (phase) {
16296 case 'getChildContext':
16297 if (didWarnAboutUpdateInGetChildContext) {
16298 return;
16299 }
16300
16301 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
16302 didWarnAboutUpdateInGetChildContext = true;
16303 break;
16304
16305 case 'render':
16306 if (didWarnAboutUpdateInRender) {
16307 return;
16308 }
16309
16310 warningWithoutStack$1(false, 'Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure function of ' + 'props and state.');
16311 didWarnAboutUpdateInRender = true;
16312 break;
16313 }
16314 }
16315 }
16316} // a 'shared' variable that changes when act() opens/closes in tests.
16317
16318
16319var IsThisRendererActing = {
16320 current: false
16321};
16322function warnIfNotScopedWithMatchingAct(fiber) {
16323 {
16324 if (warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
16325 warningWithoutStack$1(false, "It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + "import {act} from 'react-dom/test-utils';\n" + '// ...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + "import TestRenderer from 'react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '// ...\n' + 'act(() => ...);' + '%s', getStackByFiberInDevAndProd(fiber));
16326 }
16327 }
16328}
16329function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
16330 {
16331 if (warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
16332 warningWithoutStack$1(false, 'An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
16333 }
16334 }
16335}
16336
16337function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
16338 {
16339 if (warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
16340 warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
16341 }
16342 }
16343}
16344
16345var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
16346
16347var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
16348// scheduler is the actual recommendation. The alternative could be a testing build,
16349// a new lib, or whatever; we dunno just yet. This message is for early adopters
16350// to get their tests right.
16351
16352function warnIfUnmockedScheduler(fiber) {
16353 {
16354 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
16355 if (fiber.mode & BatchedMode || fiber.mode & ConcurrentMode) {
16356 didWarnAboutUnmockedScheduler = true;
16357 warningWithoutStack$1(false, 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
16358 } else if (warnAboutUnmockedScheduler === true) {
16359 didWarnAboutUnmockedScheduler = true;
16360 warningWithoutStack$1(false, 'Starting from React v17, the "scheduler" module will need to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
16361 }
16362 }
16363 }
16364}
16365var componentsThatTriggeredHighPriSuspend = null;
16366function checkForWrongSuspensePriorityInDEV(sourceFiber) {
16367 {
16368 var currentPriorityLevel = getCurrentPriorityLevel();
16369
16370 if ((sourceFiber.mode & ConcurrentMode) !== NoEffect && (currentPriorityLevel === UserBlockingPriority || currentPriorityLevel === ImmediatePriority)) {
16371 var workInProgressNode = sourceFiber;
16372
16373 while (workInProgressNode !== null) {
16374 // Add the component that triggered the suspense
16375 var current = workInProgressNode.alternate;
16376
16377 if (current !== null) {
16378 // TODO: warn component that triggers the high priority
16379 // suspend is the HostRoot
16380 switch (workInProgressNode.tag) {
16381 case ClassComponent:
16382 // Loop through the component's update queue and see whether the component
16383 // has triggered any high priority updates
16384 var updateQueue = current.updateQueue;
16385
16386 if (updateQueue !== null) {
16387 var update = updateQueue.firstUpdate;
16388
16389 while (update !== null) {
16390 var priorityLevel = update.priority;
16391
16392 if (priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority) {
16393 if (componentsThatTriggeredHighPriSuspend === null) {
16394 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
16395 } else {
16396 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
16397 }
16398
16399 break;
16400 }
16401
16402 update = update.next;
16403 }
16404 }
16405
16406 break;
16407
16408 case FunctionComponent:
16409 case ForwardRef:
16410 case SimpleMemoComponent:
16411 if (workInProgressNode.memoizedState !== null && workInProgressNode.memoizedState.baseUpdate !== null) {
16412 var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether
16413 // the component has triggered any high pri updates
16414
16415 while (_update !== null) {
16416 var priority = _update.priority;
16417
16418 if (priority === UserBlockingPriority || priority === ImmediatePriority) {
16419 if (componentsThatTriggeredHighPriSuspend === null) {
16420 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
16421 } else {
16422 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
16423 }
16424
16425 break;
16426 }
16427
16428 if (_update.next === workInProgressNode.memoizedState.baseUpdate) {
16429 break;
16430 }
16431
16432 _update = _update.next;
16433 }
16434 }
16435
16436 break;
16437
16438 default:
16439 break;
16440 }
16441 }
16442
16443 workInProgressNode = workInProgressNode.return;
16444 }
16445 }
16446 }
16447}
16448
16449function flushSuspensePriorityWarningInDEV() {
16450 {
16451 if (componentsThatTriggeredHighPriSuspend !== null) {
16452 var componentNames = [];
16453 componentsThatTriggeredHighPriSuspend.forEach(function (name) {
16454 return componentNames.push(name);
16455 });
16456 componentsThatTriggeredHighPriSuspend = null;
16457
16458 if (componentNames.length > 0) {
16459 warningWithoutStack$1(false, '%s triggered a user-blocking update that suspended.' + '\n\n' + 'The fix is to split the update into multiple parts: a user-blocking ' + 'update to provide immediate feedback, and another update that ' + 'triggers the bulk of the changes.' + '\n\n' + 'Refer to the documentation for useSuspenseTransition to learn how ' + 'to implement this pattern.', // TODO: Add link to React docs with more information, once it exists
16460 componentNames.sort().join(', '));
16461 }
16462 }
16463 }
16464}
16465
16466function computeThreadID(root, expirationTime) {
16467 // Interaction threads are unique per root and expiration time.
16468 return expirationTime * 1000 + root.interactionThreadID;
16469}
16470
16471function markSpawnedWork(expirationTime) {
16472 if (!enableSchedulerTracing) {
16473 return;
16474 }
16475
16476 if (spawnedWorkDuringRender === null) {
16477 spawnedWorkDuringRender = [expirationTime];
16478 } else {
16479 spawnedWorkDuringRender.push(expirationTime);
16480 }
16481}
16482
16483function scheduleInteractions(root, expirationTime, interactions) {
16484 if (!enableSchedulerTracing) {
16485 return;
16486 }
16487
16488 if (interactions.size > 0) {
16489 var pendingInteractionMap = root.pendingInteractionMap;
16490 var pendingInteractions = pendingInteractionMap.get(expirationTime);
16491
16492 if (pendingInteractions != null) {
16493 interactions.forEach(function (interaction) {
16494 if (!pendingInteractions.has(interaction)) {
16495 // Update the pending async work count for previously unscheduled interaction.
16496 interaction.__count++;
16497 }
16498
16499 pendingInteractions.add(interaction);
16500 });
16501 } else {
16502 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
16503
16504 interactions.forEach(function (interaction) {
16505 interaction.__count++;
16506 });
16507 }
16508
16509 var subscriber = __subscriberRef.current;
16510
16511 if (subscriber !== null) {
16512 var threadID = computeThreadID(root, expirationTime);
16513 subscriber.onWorkScheduled(interactions, threadID);
16514 }
16515 }
16516}
16517
16518function schedulePendingInteractions(root, expirationTime) {
16519 // This is called when work is scheduled on a root.
16520 // It associates the current interactions with the newly-scheduled expiration.
16521 // They will be restored when that expiration is later committed.
16522 if (!enableSchedulerTracing) {
16523 return;
16524 }
16525
16526 scheduleInteractions(root, expirationTime, __interactionsRef.current);
16527}
16528
16529function startWorkOnPendingInteractions(root, expirationTime) {
16530 // This is called when new work is started on a root.
16531 if (!enableSchedulerTracing) {
16532 return;
16533 } // Determine which interactions this batch of work currently includes, So that
16534 // we can accurately attribute time spent working on it, And so that cascading
16535 // work triggered during the render phase will be associated with it.
16536
16537
16538 var interactions = new Set();
16539 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
16540 if (scheduledExpirationTime >= expirationTime) {
16541 scheduledInteractions.forEach(function (interaction) {
16542 return interactions.add(interaction);
16543 });
16544 }
16545 }); // Store the current set of interactions on the FiberRoot for a few reasons:
16546 // We can re-use it in hot functions like renderRoot() without having to
16547 // recalculate it. We will also use it in commitWork() to pass to any Profiler
16548 // onRender() hooks. This also provides DevTools with a way to access it when
16549 // the onCommitRoot() hook is called.
16550
16551 root.memoizedInteractions = interactions;
16552
16553 if (interactions.size > 0) {
16554 var subscriber = __subscriberRef.current;
16555
16556 if (subscriber !== null) {
16557 var threadID = computeThreadID(root, expirationTime);
16558
16559 try {
16560 subscriber.onWorkStarted(interactions, threadID);
16561 } catch (error) {
16562 // If the subscriber throws, rethrow it in a separate task
16563 scheduleCallback(ImmediatePriority, function () {
16564 throw error;
16565 });
16566 }
16567 }
16568 }
16569}
16570
16571function finishPendingInteractions(root, committedExpirationTime) {
16572 if (!enableSchedulerTracing) {
16573 return;
16574 }
16575
16576 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
16577 var subscriber;
16578
16579 try {
16580 subscriber = __subscriberRef.current;
16581
16582 if (subscriber !== null && root.memoizedInteractions.size > 0) {
16583 var threadID = computeThreadID(root, committedExpirationTime);
16584 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
16585 }
16586 } catch (error) {
16587 // If the subscriber throws, rethrow it in a separate task
16588 scheduleCallback(ImmediatePriority, function () {
16589 throw error;
16590 });
16591 } finally {
16592 // Clear completed interactions from the pending Map.
16593 // Unless the render was suspended or cascading work was scheduled,
16594 // In which case– leave pending interactions until the subsequent render.
16595 var pendingInteractionMap = root.pendingInteractionMap;
16596 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
16597 // Only decrement the pending interaction count if we're done.
16598 // If there's still work at the current priority,
16599 // That indicates that we are waiting for suspense data.
16600 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
16601 pendingInteractionMap.delete(scheduledExpirationTime);
16602 scheduledInteractions.forEach(function (interaction) {
16603 interaction.__count--;
16604
16605 if (subscriber !== null && interaction.__count === 0) {
16606 try {
16607 subscriber.onInteractionScheduledWorkCompleted(interaction);
16608 } catch (error) {
16609 // If the subscriber throws, rethrow it in a separate task
16610 scheduleCallback(ImmediatePriority, function () {
16611 throw error;
16612 });
16613 }
16614 }
16615 });
16616 }
16617 });
16618 }
16619}
16620
16621var onCommitFiberRoot = null;
16622var onCommitFiberUnmount = null;
16623var hasLoggedError = false;
16624var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
16625function injectInternals(internals) {
16626 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
16627 // No DevTools
16628 return false;
16629 }
16630
16631 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
16632
16633 if (hook.isDisabled) {
16634 // This isn't a real property on the hook, but it can be set to opt out
16635 // of DevTools integration and associated warnings and logs.
16636 // https://github.com/facebook/react/issues/3877
16637 return true;
16638 }
16639
16640 if (!hook.supportsFiber) {
16641 {
16642 warningWithoutStack$1(false, 'The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools');
16643 } // DevTools exists, even though it doesn't support Fiber.
16644
16645
16646 return true;
16647 }
16648
16649 try {
16650 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
16651
16652 onCommitFiberRoot = function (root, expirationTime) {
16653 try {
16654 var didError = (root.current.effectTag & DidCapture) === DidCapture;
16655
16656 if (enableProfilerTimer) {
16657 var currentTime = requestCurrentTime();
16658 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
16659 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
16660 } else {
16661 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
16662 }
16663 } catch (err) {
16664 if (true && !hasLoggedError) {
16665 hasLoggedError = true;
16666 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
16667 }
16668 }
16669 };
16670
16671 onCommitFiberUnmount = function (fiber) {
16672 try {
16673 hook.onCommitFiberUnmount(rendererID, fiber);
16674 } catch (err) {
16675 if (true && !hasLoggedError) {
16676 hasLoggedError = true;
16677 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
16678 }
16679 }
16680 };
16681 } catch (err) {
16682 // Catch all errors because it is unsafe to throw during initialization.
16683 {
16684 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
16685 }
16686 } // DevTools exists
16687
16688
16689 return true;
16690}
16691function onCommitRoot(root, expirationTime) {
16692 if (typeof onCommitFiberRoot === 'function') {
16693 onCommitFiberRoot(root, expirationTime);
16694 }
16695}
16696function onCommitUnmount(fiber) {
16697 if (typeof onCommitFiberUnmount === 'function') {
16698 onCommitFiberUnmount(fiber);
16699 }
16700}
16701
16702var hasBadMapPolyfill;
16703
16704{
16705 hasBadMapPolyfill = false;
16706
16707 try {
16708 var nonExtensibleObject = Object.preventExtensions({});
16709 var testMap = new Map([[nonExtensibleObject, null]]);
16710 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
16711 // https://github.com/rollup/rollup/issues/1771
16712 // TODO: we can remove these if Rollup fixes the bug.
16713
16714 testMap.set(0, 0);
16715 testSet.add(0);
16716 } catch (e) {
16717 // TODO: Consider warning about bad polyfills
16718 hasBadMapPolyfill = true;
16719 }
16720}
16721
16722var debugCounter = 1;
16723
16724function FiberNode(tag, pendingProps, key, mode) {
16725 // Instance
16726 this.tag = tag;
16727 this.key = key;
16728 this.elementType = null;
16729 this.type = null;
16730 this.stateNode = null; // Fiber
16731
16732 this.return = null;
16733 this.child = null;
16734 this.sibling = null;
16735 this.index = 0;
16736 this.ref = null;
16737 this.pendingProps = pendingProps;
16738 this.memoizedProps = null;
16739 this.updateQueue = null;
16740 this.memoizedState = null;
16741 this.dependencies = null;
16742 this.mode = mode; // Effects
16743
16744 this.effectTag = NoEffect;
16745 this.nextEffect = null;
16746 this.firstEffect = null;
16747 this.lastEffect = null;
16748 this.expirationTime = NoWork;
16749 this.childExpirationTime = NoWork;
16750 this.alternate = null;
16751
16752 if (enableProfilerTimer) {
16753 // Note: The following is done to avoid a v8 performance cliff.
16754 //
16755 // Initializing the fields below to smis and later updating them with
16756 // double values will cause Fibers to end up having separate shapes.
16757 // This behavior/bug has something to do with Object.preventExtension().
16758 // Fortunately this only impacts DEV builds.
16759 // Unfortunately it makes React unusably slow for some applications.
16760 // To work around this, initialize the fields below with doubles.
16761 //
16762 // Learn more about this here:
16763 // https://github.com/facebook/react/issues/14365
16764 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
16765 this.actualDuration = Number.NaN;
16766 this.actualStartTime = Number.NaN;
16767 this.selfBaseDuration = Number.NaN;
16768 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
16769 // This won't trigger the performance cliff mentioned above,
16770 // and it simplifies other profiler code (including DevTools).
16771
16772 this.actualDuration = 0;
16773 this.actualStartTime = -1;
16774 this.selfBaseDuration = 0;
16775 this.treeBaseDuration = 0;
16776 } // This is normally DEV-only except www when it adds listeners.
16777 // TODO: remove the User Timing integration in favor of Root Events.
16778
16779
16780 if (enableUserTimingAPI) {
16781 this._debugID = debugCounter++;
16782 this._debugIsCurrentlyTiming = false;
16783 }
16784
16785 {
16786 this._debugSource = null;
16787 this._debugOwner = null;
16788 this._debugNeedsRemount = false;
16789 this._debugHookTypes = null;
16790
16791 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
16792 Object.preventExtensions(this);
16793 }
16794 }
16795} // This is a constructor function, rather than a POJO constructor, still
16796// please ensure we do the following:
16797// 1) Nobody should add any instance methods on this. Instance methods can be
16798// more difficult to predict when they get optimized and they are almost
16799// never inlined properly in static compilers.
16800// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
16801// always know when it is a fiber.
16802// 3) We might want to experiment with using numeric keys since they are easier
16803// to optimize in a non-JIT environment.
16804// 4) We can easily go from a constructor to a createFiber object literal if that
16805// is faster.
16806// 5) It should be easy to port this to a C struct and keep a C implementation
16807// compatible.
16808
16809
16810var createFiber = function (tag, pendingProps, key, mode) {
16811 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
16812 return new FiberNode(tag, pendingProps, key, mode);
16813};
16814
16815function shouldConstruct(Component) {
16816 var prototype = Component.prototype;
16817 return !!(prototype && prototype.isReactComponent);
16818}
16819
16820function isSimpleFunctionComponent(type) {
16821 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
16822}
16823function resolveLazyComponentTag(Component) {
16824 if (typeof Component === 'function') {
16825 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
16826 } else if (Component !== undefined && Component !== null) {
16827 var $$typeof = Component.$$typeof;
16828
16829 if ($$typeof === REACT_FORWARD_REF_TYPE) {
16830 return ForwardRef;
16831 }
16832
16833 if ($$typeof === REACT_MEMO_TYPE) {
16834 return MemoComponent;
16835 }
16836 }
16837
16838 return IndeterminateComponent;
16839} // This is used to create an alternate fiber to do work on.
16840
16841function createWorkInProgress(current, pendingProps, expirationTime) {
16842 var workInProgress = current.alternate;
16843
16844 if (workInProgress === null) {
16845 // We use a double buffering pooling technique because we know that we'll
16846 // only ever need at most two versions of a tree. We pool the "other" unused
16847 // node that we're free to reuse. This is lazily created to avoid allocating
16848 // extra objects for things that are never updated. It also allow us to
16849 // reclaim the extra memory if needed.
16850 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
16851 workInProgress.elementType = current.elementType;
16852 workInProgress.type = current.type;
16853 workInProgress.stateNode = current.stateNode;
16854
16855 {
16856 // DEV-only fields
16857 workInProgress._debugID = current._debugID;
16858 workInProgress._debugSource = current._debugSource;
16859 workInProgress._debugOwner = current._debugOwner;
16860 workInProgress._debugHookTypes = current._debugHookTypes;
16861 }
16862
16863 workInProgress.alternate = current;
16864 current.alternate = workInProgress;
16865 } else {
16866 workInProgress.pendingProps = pendingProps; // We already have an alternate.
16867 // Reset the effect tag.
16868
16869 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
16870
16871 workInProgress.nextEffect = null;
16872 workInProgress.firstEffect = null;
16873 workInProgress.lastEffect = null;
16874
16875 if (enableProfilerTimer) {
16876 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
16877 // This prevents time from endlessly accumulating in new commits.
16878 // This has the downside of resetting values for different priority renders,
16879 // But works for yielding (the common case) and should support resuming.
16880 workInProgress.actualDuration = 0;
16881 workInProgress.actualStartTime = -1;
16882 }
16883 }
16884
16885 workInProgress.childExpirationTime = current.childExpirationTime;
16886 workInProgress.expirationTime = current.expirationTime;
16887 workInProgress.child = current.child;
16888 workInProgress.memoizedProps = current.memoizedProps;
16889 workInProgress.memoizedState = current.memoizedState;
16890 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
16891 // it cannot be shared with the current fiber.
16892
16893 var currentDependencies = current.dependencies;
16894 workInProgress.dependencies = currentDependencies === null ? null : {
16895 expirationTime: currentDependencies.expirationTime,
16896 firstContext: currentDependencies.firstContext,
16897 responders: currentDependencies.responders
16898 }; // These will be overridden during the parent's reconciliation
16899
16900 workInProgress.sibling = current.sibling;
16901 workInProgress.index = current.index;
16902 workInProgress.ref = current.ref;
16903
16904 if (enableProfilerTimer) {
16905 workInProgress.selfBaseDuration = current.selfBaseDuration;
16906 workInProgress.treeBaseDuration = current.treeBaseDuration;
16907 }
16908
16909 {
16910 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
16911
16912 switch (workInProgress.tag) {
16913 case IndeterminateComponent:
16914 case FunctionComponent:
16915 case SimpleMemoComponent:
16916 workInProgress.type = resolveFunctionForHotReloading(current.type);
16917 break;
16918
16919 case ClassComponent:
16920 workInProgress.type = resolveClassForHotReloading(current.type);
16921 break;
16922
16923 case ForwardRef:
16924 workInProgress.type = resolveForwardRefForHotReloading(current.type);
16925 break;
16926
16927 default:
16928 break;
16929 }
16930 }
16931
16932 return workInProgress;
16933} // Used to reuse a Fiber for a second pass.
16934
16935function resetWorkInProgress(workInProgress, renderExpirationTime) {
16936 // This resets the Fiber to what createFiber or createWorkInProgress would
16937 // have set the values to before during the first pass. Ideally this wouldn't
16938 // be necessary but unfortunately many code paths reads from the workInProgress
16939 // when they should be reading from current and writing to workInProgress.
16940 // We assume pendingProps, index, key, ref, return are still untouched to
16941 // avoid doing another reconciliation.
16942 // Reset the effect tag but keep any Placement tags, since that's something
16943 // that child fiber is setting, not the reconciliation.
16944 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
16945
16946 workInProgress.nextEffect = null;
16947 workInProgress.firstEffect = null;
16948 workInProgress.lastEffect = null;
16949 var current = workInProgress.alternate;
16950
16951 if (current === null) {
16952 // Reset to createFiber's initial values.
16953 workInProgress.childExpirationTime = NoWork;
16954 workInProgress.expirationTime = renderExpirationTime;
16955 workInProgress.child = null;
16956 workInProgress.memoizedProps = null;
16957 workInProgress.memoizedState = null;
16958 workInProgress.updateQueue = null;
16959 workInProgress.dependencies = null;
16960
16961 if (enableProfilerTimer) {
16962 // Note: We don't reset the actualTime counts. It's useful to accumulate
16963 // actual time across multiple render passes.
16964 workInProgress.selfBaseDuration = 0;
16965 workInProgress.treeBaseDuration = 0;
16966 }
16967 } else {
16968 // Reset to the cloned values that createWorkInProgress would've.
16969 workInProgress.childExpirationTime = current.childExpirationTime;
16970 workInProgress.expirationTime = current.expirationTime;
16971 workInProgress.child = current.child;
16972 workInProgress.memoizedProps = current.memoizedProps;
16973 workInProgress.memoizedState = current.memoizedState;
16974 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
16975 // it cannot be shared with the current fiber.
16976
16977 var currentDependencies = current.dependencies;
16978 workInProgress.dependencies = currentDependencies === null ? null : {
16979 expirationTime: currentDependencies.expirationTime,
16980 firstContext: currentDependencies.firstContext,
16981 responders: currentDependencies.responders
16982 };
16983
16984 if (enableProfilerTimer) {
16985 // Note: We don't reset the actualTime counts. It's useful to accumulate
16986 // actual time across multiple render passes.
16987 workInProgress.selfBaseDuration = current.selfBaseDuration;
16988 workInProgress.treeBaseDuration = current.treeBaseDuration;
16989 }
16990 }
16991
16992 return workInProgress;
16993}
16994function createHostRootFiber(tag) {
16995 var mode;
16996
16997 if (tag === ConcurrentRoot) {
16998 mode = ConcurrentMode | BatchedMode | StrictMode;
16999 } else if (tag === BatchedRoot) {
17000 mode = BatchedMode | StrictMode;
17001 } else {
17002 mode = NoMode;
17003 }
17004
17005 if (enableProfilerTimer && isDevToolsPresent) {
17006 // Always collect profile timings when DevTools are present.
17007 // This enables DevTools to start capturing timing at any point–
17008 // Without some nodes in the tree having empty base times.
17009 mode |= ProfileMode;
17010 }
17011
17012 return createFiber(HostRoot, null, null, mode);
17013}
17014function createFiberFromTypeAndProps(type, // React$ElementType
17015key, pendingProps, owner, mode, expirationTime) {
17016 var fiber;
17017 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
17018
17019 var resolvedType = type;
17020
17021 if (typeof type === 'function') {
17022 if (shouldConstruct(type)) {
17023 fiberTag = ClassComponent;
17024
17025 {
17026 resolvedType = resolveClassForHotReloading(resolvedType);
17027 }
17028 } else {
17029 {
17030 resolvedType = resolveFunctionForHotReloading(resolvedType);
17031 }
17032 }
17033 } else if (typeof type === 'string') {
17034 fiberTag = HostComponent;
17035 } else {
17036 getTag: switch (type) {
17037 case REACT_FRAGMENT_TYPE:
17038 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
17039
17040 case REACT_CONCURRENT_MODE_TYPE:
17041 fiberTag = Mode;
17042 mode |= ConcurrentMode | BatchedMode | StrictMode;
17043 break;
17044
17045 case REACT_STRICT_MODE_TYPE:
17046 fiberTag = Mode;
17047 mode |= StrictMode;
17048 break;
17049
17050 case REACT_PROFILER_TYPE:
17051 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
17052
17053 case REACT_SUSPENSE_TYPE:
17054 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
17055
17056 case REACT_SUSPENSE_LIST_TYPE:
17057 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
17058
17059 default:
17060 {
17061 if (typeof type === 'object' && type !== null) {
17062 switch (type.$$typeof) {
17063 case REACT_PROVIDER_TYPE:
17064 fiberTag = ContextProvider;
17065 break getTag;
17066
17067 case REACT_CONTEXT_TYPE:
17068 // This is a consumer
17069 fiberTag = ContextConsumer;
17070 break getTag;
17071
17072 case REACT_FORWARD_REF_TYPE:
17073 fiberTag = ForwardRef;
17074
17075 {
17076 resolvedType = resolveForwardRefForHotReloading(resolvedType);
17077 }
17078
17079 break getTag;
17080
17081 case REACT_MEMO_TYPE:
17082 fiberTag = MemoComponent;
17083 break getTag;
17084
17085 case REACT_LAZY_TYPE:
17086 fiberTag = LazyComponent;
17087 resolvedType = null;
17088 break getTag;
17089
17090 case REACT_FUNDAMENTAL_TYPE:
17091 if (enableFundamentalAPI) {
17092 return createFiberFromFundamental(type, pendingProps, mode, expirationTime, key);
17093 }
17094
17095 break;
17096
17097 case REACT_SCOPE_TYPE:
17098 if (enableScopeAPI) {
17099 return createFiberFromScope(type, pendingProps, mode, expirationTime, key);
17100 }
17101
17102 }
17103 }
17104
17105 var info = '';
17106
17107 {
17108 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
17109 info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and " + 'named imports.';
17110 }
17111
17112 var ownerName = owner ? getComponentName(owner.type) : null;
17113
17114 if (ownerName) {
17115 info += '\n\nCheck the render method of `' + ownerName + '`.';
17116 }
17117 }
17118
17119 (function () {
17120 {
17121 {
17122 throw ReactError(Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + (type == null ? type : typeof type) + "." + info));
17123 }
17124 }
17125 })();
17126 }
17127 }
17128 }
17129
17130 fiber = createFiber(fiberTag, pendingProps, key, mode);
17131 fiber.elementType = type;
17132 fiber.type = resolvedType;
17133 fiber.expirationTime = expirationTime;
17134 return fiber;
17135}
17136function createFiberFromElement(element, mode, expirationTime) {
17137 var owner = null;
17138
17139 {
17140 owner = element._owner;
17141 }
17142
17143 var type = element.type;
17144 var key = element.key;
17145 var pendingProps = element.props;
17146 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
17147
17148 {
17149 fiber._debugSource = element._source;
17150 fiber._debugOwner = element._owner;
17151 }
17152
17153 return fiber;
17154}
17155function createFiberFromFragment(elements, mode, expirationTime, key) {
17156 var fiber = createFiber(Fragment, elements, key, mode);
17157 fiber.expirationTime = expirationTime;
17158 return fiber;
17159}
17160function createFiberFromFundamental(fundamentalComponent, pendingProps, mode, expirationTime, key) {
17161 var fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
17162 fiber.elementType = fundamentalComponent;
17163 fiber.type = fundamentalComponent;
17164 fiber.expirationTime = expirationTime;
17165 return fiber;
17166}
17167
17168function createFiberFromScope(scope, pendingProps, mode, expirationTime, key) {
17169 var fiber = createFiber(ScopeComponent, pendingProps, key, mode);
17170 fiber.type = scope;
17171 fiber.elementType = scope;
17172 fiber.expirationTime = expirationTime;
17173 return fiber;
17174}
17175
17176function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
17177 {
17178 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
17179 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
17180 }
17181 }
17182
17183 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
17184
17185 fiber.elementType = REACT_PROFILER_TYPE;
17186 fiber.type = REACT_PROFILER_TYPE;
17187 fiber.expirationTime = expirationTime;
17188 return fiber;
17189}
17190
17191function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
17192 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
17193 // This needs to be fixed in getComponentName so that it relies on the tag
17194 // instead.
17195
17196 fiber.type = REACT_SUSPENSE_TYPE;
17197 fiber.elementType = REACT_SUSPENSE_TYPE;
17198 fiber.expirationTime = expirationTime;
17199 return fiber;
17200}
17201function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
17202 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
17203
17204 {
17205 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
17206 // This needs to be fixed in getComponentName so that it relies on the tag
17207 // instead.
17208 fiber.type = REACT_SUSPENSE_LIST_TYPE;
17209 }
17210
17211 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
17212 fiber.expirationTime = expirationTime;
17213 return fiber;
17214}
17215function createFiberFromText(content, mode, expirationTime) {
17216 var fiber = createFiber(HostText, content, null, mode);
17217 fiber.expirationTime = expirationTime;
17218 return fiber;
17219}
17220function createFiberFromHostInstanceForDeletion() {
17221 var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type.
17222
17223 fiber.elementType = 'DELETED';
17224 fiber.type = 'DELETED';
17225 return fiber;
17226}
17227function createFiberFromDehydratedFragment(dehydratedNode) {
17228 var fiber = createFiber(DehydratedFragment, null, null, NoMode);
17229 fiber.stateNode = dehydratedNode;
17230 return fiber;
17231}
17232function createFiberFromPortal(portal, mode, expirationTime) {
17233 var pendingProps = portal.children !== null ? portal.children : [];
17234 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
17235 fiber.expirationTime = expirationTime;
17236 fiber.stateNode = {
17237 containerInfo: portal.containerInfo,
17238 pendingChildren: null,
17239 // Used by persistent updates
17240 implementation: portal.implementation
17241 };
17242 return fiber;
17243} // Used for stashing WIP properties to replay failed work in DEV.
17244
17245function assignFiberPropertiesInDEV(target, source) {
17246 if (target === null) {
17247 // This Fiber's initial properties will always be overwritten.
17248 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
17249 target = createFiber(IndeterminateComponent, null, null, NoMode);
17250 } // This is intentionally written as a list of all properties.
17251 // We tried to use Object.assign() instead but this is called in
17252 // the hottest path, and Object.assign() was too slow:
17253 // https://github.com/facebook/react/issues/12502
17254 // This code is DEV-only so size is not a concern.
17255
17256
17257 target.tag = source.tag;
17258 target.key = source.key;
17259 target.elementType = source.elementType;
17260 target.type = source.type;
17261 target.stateNode = source.stateNode;
17262 target.return = source.return;
17263 target.child = source.child;
17264 target.sibling = source.sibling;
17265 target.index = source.index;
17266 target.ref = source.ref;
17267 target.pendingProps = source.pendingProps;
17268 target.memoizedProps = source.memoizedProps;
17269 target.updateQueue = source.updateQueue;
17270 target.memoizedState = source.memoizedState;
17271 target.dependencies = source.dependencies;
17272 target.mode = source.mode;
17273 target.effectTag = source.effectTag;
17274 target.nextEffect = source.nextEffect;
17275 target.firstEffect = source.firstEffect;
17276 target.lastEffect = source.lastEffect;
17277 target.expirationTime = source.expirationTime;
17278 target.childExpirationTime = source.childExpirationTime;
17279 target.alternate = source.alternate;
17280
17281 if (enableProfilerTimer) {
17282 target.actualDuration = source.actualDuration;
17283 target.actualStartTime = source.actualStartTime;
17284 target.selfBaseDuration = source.selfBaseDuration;
17285 target.treeBaseDuration = source.treeBaseDuration;
17286 }
17287
17288 target._debugID = source._debugID;
17289 target._debugSource = source._debugSource;
17290 target._debugOwner = source._debugOwner;
17291 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
17292 target._debugNeedsRemount = source._debugNeedsRemount;
17293 target._debugHookTypes = source._debugHookTypes;
17294 return target;
17295}
17296
17297function FiberRootNode(containerInfo, tag, hydrate) {
17298 this.tag = tag;
17299 this.current = null;
17300 this.containerInfo = containerInfo;
17301 this.pendingChildren = null;
17302 this.pingCache = null;
17303 this.finishedExpirationTime = NoWork;
17304 this.finishedWork = null;
17305 this.timeoutHandle = noTimeout;
17306 this.context = null;
17307 this.pendingContext = null;
17308 this.hydrate = hydrate;
17309 this.firstBatch = null;
17310 this.callbackNode = null;
17311 this.callbackPriority = NoPriority;
17312 this.firstPendingTime = NoWork;
17313 this.firstSuspendedTime = NoWork;
17314 this.lastSuspendedTime = NoWork;
17315 this.nextKnownPendingLevel = NoWork;
17316 this.lastPingedTime = NoWork;
17317 this.lastExpiredTime = NoWork;
17318
17319 if (enableSchedulerTracing) {
17320 this.interactionThreadID = unstable_getThreadID();
17321 this.memoizedInteractions = new Set();
17322 this.pendingInteractionMap = new Map();
17323 }
17324
17325 if (enableSuspenseCallback) {
17326 this.hydrationCallbacks = null;
17327 }
17328}
17329
17330function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
17331 var root = new FiberRootNode(containerInfo, tag, hydrate);
17332
17333 if (enableSuspenseCallback) {
17334 root.hydrationCallbacks = hydrationCallbacks;
17335 } // Cyclic construction. This cheats the type system right now because
17336 // stateNode is any.
17337
17338
17339 var uninitializedFiber = createHostRootFiber(tag);
17340 root.current = uninitializedFiber;
17341 uninitializedFiber.stateNode = root;
17342 return root;
17343}
17344function isRootSuspendedAtTime(root, expirationTime) {
17345 var firstSuspendedTime = root.firstSuspendedTime;
17346 var lastSuspendedTime = root.lastSuspendedTime;
17347 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
17348}
17349function markRootSuspendedAtTime(root, expirationTime) {
17350 var firstSuspendedTime = root.firstSuspendedTime;
17351 var lastSuspendedTime = root.lastSuspendedTime;
17352
17353 if (firstSuspendedTime < expirationTime) {
17354 root.firstSuspendedTime = expirationTime;
17355 }
17356
17357 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
17358 root.lastSuspendedTime = expirationTime;
17359 }
17360
17361 if (expirationTime <= root.lastPingedTime) {
17362 root.lastPingedTime = NoWork;
17363 }
17364
17365 if (expirationTime <= root.lastExpiredTime) {
17366 root.lastExpiredTime = NoWork;
17367 }
17368}
17369function markRootUpdatedAtTime(root, expirationTime) {
17370 // Update the range of pending times
17371 var firstPendingTime = root.firstPendingTime;
17372
17373 if (expirationTime > firstPendingTime) {
17374 root.firstPendingTime = expirationTime;
17375 } // Update the range of suspended times. Treat everything lower priority or
17376 // equal to this update as unsuspended.
17377
17378
17379 var firstSuspendedTime = root.firstSuspendedTime;
17380
17381 if (firstSuspendedTime !== NoWork) {
17382 if (expirationTime >= firstSuspendedTime) {
17383 // The entire suspended range is now unsuspended.
17384 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
17385 } else if (expirationTime >= root.lastSuspendedTime) {
17386 root.lastSuspendedTime = expirationTime + 1;
17387 } // This is a pending level. Check if it's higher priority than the next
17388 // known pending level.
17389
17390
17391 if (expirationTime > root.nextKnownPendingLevel) {
17392 root.nextKnownPendingLevel = expirationTime;
17393 }
17394 }
17395}
17396function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
17397 // Update the range of pending times
17398 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
17399 // equal to this update as unsuspended.
17400
17401 if (finishedExpirationTime <= root.lastSuspendedTime) {
17402 // The entire suspended range is now unsuspended.
17403 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
17404 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
17405 // Part of the suspended range is now unsuspended. Narrow the range to
17406 // include everything between the unsuspended time (non-inclusive) and the
17407 // last suspended time.
17408 root.firstSuspendedTime = finishedExpirationTime - 1;
17409 }
17410
17411 if (finishedExpirationTime <= root.lastPingedTime) {
17412 // Clear the pinged time
17413 root.lastPingedTime = NoWork;
17414 }
17415
17416 if (finishedExpirationTime <= root.lastExpiredTime) {
17417 // Clear the expired time
17418 root.lastExpiredTime = NoWork;
17419 }
17420}
17421function markRootExpiredAtTime(root, expirationTime) {
17422 var lastExpiredTime = root.lastExpiredTime;
17423
17424 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
17425 root.lastExpiredTime = expirationTime;
17426 }
17427}
17428
17429// This lets us hook into Fiber to debug what it's doing.
17430// See https://github.com/facebook/react/pull/8033.
17431// This is not part of the public API, not even for React DevTools.
17432// You may only inject a debugTool if you work on React Fiber itself.
17433var ReactFiberInstrumentation = {
17434 debugTool: null
17435};
17436var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
17437
17438var didWarnAboutNestedUpdates;
17439{
17440 didWarnAboutNestedUpdates = false;
17441
17442}
17443
17444function getContextForSubtree(parentComponent) {
17445 if (!parentComponent) {
17446 return emptyContextObject;
17447 }
17448
17449 var fiber = get(parentComponent);
17450 var parentContext = findCurrentUnmaskedContext(fiber);
17451
17452 if (fiber.tag === ClassComponent) {
17453 var Component = fiber.type;
17454
17455 if (isContextProvider(Component)) {
17456 return processChildContext(fiber, Component, parentContext);
17457 }
17458 }
17459
17460 return parentContext;
17461}
17462
17463function scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback) {
17464 {
17465 if (phase === 'render' && current$1 !== null && !didWarnAboutNestedUpdates) {
17466 didWarnAboutNestedUpdates = true;
17467 warningWithoutStack$1(false, 'Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName(current$1.type) || 'Unknown');
17468 }
17469 }
17470
17471 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
17472 // being called "element".
17473
17474 update.payload = {
17475 element: element
17476 };
17477 callback = callback === undefined ? null : callback;
17478
17479 if (callback !== null) {
17480 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
17481 update.callback = callback;
17482 }
17483
17484 enqueueUpdate(current$$1, update);
17485 scheduleWork(current$$1, expirationTime);
17486 return expirationTime;
17487}
17488
17489function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback) {
17490 // TODO: If this is a nested container, this won't be the root.
17491 var current$$1 = container.current;
17492
17493 {
17494 if (ReactFiberInstrumentation_1.debugTool) {
17495 if (current$$1.alternate === null) {
17496 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
17497 } else if (element === null) {
17498 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
17499 } else {
17500 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
17501 }
17502 }
17503 }
17504
17505 var context = getContextForSubtree(parentComponent);
17506
17507 if (container.context === null) {
17508 container.context = context;
17509 } else {
17510 container.pendingContext = context;
17511 }
17512
17513 return scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback);
17514}
17515
17516function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
17517 return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks);
17518}
17519function updateContainer(element, container, parentComponent, callback) {
17520 var current$$1 = container.current;
17521 var currentTime = requestCurrentTime();
17522
17523 {
17524 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
17525 if ('undefined' !== typeof jest) {
17526 warnIfUnmockedScheduler(current$$1);
17527 warnIfNotScopedWithMatchingAct(current$$1);
17528 }
17529 }
17530
17531 var suspenseConfig = requestCurrentSuspenseConfig();
17532 var expirationTime = computeExpirationForFiber(currentTime, current$$1, suspenseConfig);
17533 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback);
17534}
17535
17536
17537
17538
17539var shouldSuspendImpl = function (fiber) {
17540 return false;
17541};
17542
17543function shouldSuspend(fiber) {
17544 return shouldSuspendImpl(fiber);
17545}
17546var overrideHookState = null;
17547var overrideProps = null;
17548var scheduleUpdate = null;
17549var setSuspenseHandler = null;
17550
17551{
17552 var copyWithSetImpl = function (obj, path, idx, value) {
17553 if (idx >= path.length) {
17554 return value;
17555 }
17556
17557 var key = path[idx];
17558 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
17559
17560 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
17561 return updated;
17562 };
17563
17564 var copyWithSet = function (obj, path, value) {
17565 return copyWithSetImpl(obj, path, 0, value);
17566 }; // Support DevTools editable values for useState and useReducer.
17567
17568
17569 overrideHookState = function (fiber, id, path, value) {
17570 // For now, the "id" of stateful hooks is just the stateful hook index.
17571 // This may change in the future with e.g. nested hooks.
17572 var currentHook = fiber.memoizedState;
17573
17574 while (currentHook !== null && id > 0) {
17575 currentHook = currentHook.next;
17576 id--;
17577 }
17578
17579 if (currentHook !== null) {
17580 var newState = copyWithSet(currentHook.memoizedState, path, value);
17581 currentHook.memoizedState = newState;
17582 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
17583 // because there is no update we can add for useReducer hooks that won't trigger an error.
17584 // (There's no appropriate action type for DevTools overrides.)
17585 // As a result though, React will see the scheduled update as a noop and bailout.
17586 // Shallow cloning props works as a workaround for now to bypass the bailout check.
17587
17588 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
17589 scheduleWork(fiber, Sync);
17590 }
17591 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
17592
17593
17594 overrideProps = function (fiber, path, value) {
17595 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
17596
17597 if (fiber.alternate) {
17598 fiber.alternate.pendingProps = fiber.pendingProps;
17599 }
17600
17601 scheduleWork(fiber, Sync);
17602 };
17603
17604 scheduleUpdate = function (fiber) {
17605 scheduleWork(fiber, Sync);
17606 };
17607
17608 setSuspenseHandler = function (newShouldSuspendImpl) {
17609 shouldSuspendImpl = newShouldSuspendImpl;
17610 };
17611}
17612
17613function injectIntoDevTools(devToolsConfig) {
17614 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
17615 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
17616 return injectInternals(_assign({}, devToolsConfig, {
17617 overrideHookState: overrideHookState,
17618 overrideProps: overrideProps,
17619 setSuspenseHandler: setSuspenseHandler,
17620 scheduleUpdate: scheduleUpdate,
17621 currentDispatcherRef: ReactCurrentDispatcher,
17622 findHostInstanceByFiber: function (fiber) {
17623 var hostFiber = findCurrentHostFiber(fiber);
17624
17625 if (hostFiber === null) {
17626 return null;
17627 }
17628
17629 return hostFiber.stateNode;
17630 },
17631 findFiberByHostInstance: function (instance) {
17632 if (!findFiberByHostInstance) {
17633 // Might not be implemented by the renderer.
17634 return null;
17635 }
17636
17637 return findFiberByHostInstance(instance);
17638 },
17639 // React Refresh
17640 findHostInstancesForRefresh: findHostInstancesForRefresh,
17641 scheduleRefresh: scheduleRefresh,
17642 scheduleRoot: scheduleRoot,
17643 setRefreshHandler: setRefreshHandler,
17644 // Enables DevTools to append owner stacks to error messages in DEV mode.
17645 getCurrentFiber: function () {
17646 return current$1;
17647 }
17648 }));
17649}
17650
17651// This file intentionally does *not* have the Flow annotation.
17652// Don't add it. See `./inline-typed.js` for an explanation.
17653
17654var container = _class({
17655
17656 grab: function(){
17657 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
17658 return this;
17659 },
17660
17661 empty: function(){
17662 var node;
17663 while (node = this.firstChild) node.eject();
17664 return this;
17665 }
17666
17667});
17668
17669function elementFrom(node){
17670 if (node.toElement) return node.toElement();
17671 if (node.getDOMNode) return node.getDOMNode();
17672 if (node.getNode) return node.getNode();
17673 return node;
17674}
17675
17676var native_1 = _class({
17677
17678 // conventions
17679
17680 toElement: function(){
17681 return this.element;
17682 },
17683
17684 getDOMNode: function(){
17685 return this.toElement();
17686 },
17687
17688 getNode: function(){
17689 return this.toElement();
17690 },
17691
17692 // placement
17693
17694 inject: function(container){
17695 (container.containerElement || elementFrom(container))
17696 .appendChild(this.element);
17697 return this;
17698 },
17699
17700 injectBefore: function(sibling){
17701 var element = elementFrom(sibling);
17702 element.parentNode.insertBefore(this.element, element);
17703 return this;
17704 },
17705
17706 eject: function(){
17707 var element = this.element, parent = element.parentNode;
17708 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
17709 return this;
17710 },
17711
17712 // events
17713
17714 subscribe: function(type, fn, bind){
17715 if (typeof type != 'string'){ // listen type / fn with object
17716 var subscriptions = [];
17717 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
17718 return function(){ // unsubscribe
17719 for (var i = 0, l = subscriptions.length; i < l; i++)
17720 subscriptions[i]();
17721 return this;
17722 };
17723 } else { // listen to one
17724 if (!bind) bind = this;
17725 var bound;
17726 if (typeof fn === 'function'){
17727 bound = fn.bind ? fn.bind(bind)
17728 : function(){ return fn.apply(bind, arguments); };
17729 } else {
17730 bound = fn;
17731 }
17732 var element = this.element;
17733 if (element.addEventListener){
17734 element.addEventListener(type, bound, false);
17735 return function(){ // unsubscribe
17736 element.removeEventListener(type, bound, false);
17737 return this;
17738 };
17739 } else {
17740 element.attachEvent('on' + type, bound);
17741 return function(){ // unsubscribe
17742 element.detachEvent('on' + type, bound);
17743 return this;
17744 };
17745 }
17746 }
17747 }
17748
17749});
17750
17751var fps = 1000 / 60;
17752var invalids = [];
17753var renderTimer;
17754var renderInvalids = function(){
17755 clearTimeout(renderTimer);
17756 renderTimer = null;
17757 var canvases = invalids;
17758 invalids = [];
17759 for (var i = 0, l = canvases.length; i < l; i++){
17760 var c = canvases[i];
17761 c._valid = true;
17762 c.render();
17763 }
17764};
17765
17766var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
17767
17768var previousHit = null;
17769var previousHitSurface = null;
17770
17771var CanvasSurface = _class(native_1, container, {
17772
17773 initialize: function(width, height, existingElement){
17774 var element = this.element = existingElement || document.createElement('canvas');
17775 var context = this.context = element.getContext('2d');
17776 this._valid = true;
17777 if (width != null && height != null) this.resize(width, height);
17778
17779 element.addEventListener('mousemove', this, false);
17780 element.addEventListener('mouseout', this, false);
17781 element.addEventListener('mouseover', this, false);
17782 element.addEventListener('mouseup', this, false);
17783 element.addEventListener('mousedown', this, false);
17784 element.addEventListener('click', this, false);
17785 },
17786
17787 handleEvent: function(event){
17788 if (event.clientX == null) return;
17789 var element = this.element,
17790 rect = element.getBoundingClientRect(),
17791 x = event.clientX - rect.left - element.clientLeft,
17792 y = event.clientY - rect.top - element.clientTop,
17793 hit = this.hitTest(x, y);
17794
17795 if (hit !== previousHit){
17796 if (previousHit){
17797 previousHit.dispatch({
17798 type: 'mouseout',
17799 target: previousHit,
17800 relatedTarget: hit,
17801 sourceEvent: event
17802 });
17803 }
17804 if (hit){
17805 hit.dispatch({
17806 type: 'mouseover',
17807 target: hit,
17808 relatedTarget: previousHit,
17809 sourceEvent: event
17810 });
17811 }
17812 previousHit = hit;
17813 previousHitSurface = this;
17814 this.refreshCursor();
17815 }
17816
17817 if (hit) hit.dispatch(event);
17818 },
17819
17820 refreshCursor: function(){
17821 if (previousHitSurface !== this) return;
17822 var hit = previousHit, hitCursor = '', hitTooltip = '';
17823 while (hit){
17824 if (!hitCursor && hit._cursor){
17825 hitCursor = hit._cursor;
17826 if (hitTooltip) break;
17827 }
17828 if (!hitTooltip && hit._tooltip){
17829 hitTooltip = hit._tooltip;
17830 if (hitCursor) break;
17831 }
17832 hit = hit.parentNode;
17833 }
17834 // TODO: No way to set cursor/title on the surface
17835 this.element.style.cursor = hitCursor;
17836 this.element.title = hitTooltip;
17837 },
17838
17839 resize: function(width, height){
17840 var element = this.element;
17841 element.setAttribute('width', width * resolution);
17842 element.setAttribute('height', height * resolution);
17843 element.style.width = width + 'px';
17844 element.style.height = height + 'px';
17845 this.width = width;
17846 this.height = height;
17847 return this;
17848 },
17849
17850 invalidate: function(left, top, width, height){
17851 if (this._valid){
17852 this._valid = false;
17853 invalids.push(this);
17854 if (!renderTimer){
17855 if (window.mozRequestAnimationFrame){
17856 renderTimer = true;
17857 window.mozRequestAnimationFrame(renderInvalids);
17858 } else {
17859 renderTimer = setTimeout(renderInvalids, fps);
17860 }
17861 }
17862 }
17863 return this;
17864 },
17865
17866 hitTest: function(x, y){
17867 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
17868 var node = this.lastChild;
17869 while (node){
17870 var hit = node.hitTest(x, y);
17871 if (hit) return hit;
17872 node = node.previousSibling;
17873 }
17874 return null;
17875 },
17876
17877 render: function(){
17878 var node = this.firstChild, context = this.context;
17879 context.setTransform(resolution, 0, 0, resolution, 0, 0);
17880 context.clearRect(0, 0, this.width, this.height);
17881 while (node){
17882 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
17883 node = node.nextSibling;
17884 }
17885 this.refreshCursor();
17886 }
17887
17888});
17889
17890CanvasSurface.tagName = 'canvas';
17891
17892var surface = CanvasSurface;
17893
17894var path$2 = _class({
17895
17896 initialize: function(path){
17897 this.reset().push(path);
17898 },
17899
17900 /* parser */
17901
17902 push: function(){
17903 var p = Array.prototype.join.call(arguments, ' ')
17904 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
17905 if (!p) return this;
17906
17907 var last, cmd = p[0], i = 1;
17908 while (cmd){
17909 switch (cmd){
17910 case 'm': this.move(p[i++], p[i++]); break;
17911 case 'l': this.line(p[i++], p[i++]); break;
17912 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
17913 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
17914 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
17915 case 't': this.curve(p[i++], p[i++]); break;
17916 case 'a': this.arc(p[i+5], p[i+6], p[i], p[i+1], p[i+3], !+p[i+4], p[i+2]); i += 7; break;
17917 case 'h': this.line(p[i++], 0); break;
17918 case 'v': this.line(0, p[i++]); break;
17919
17920 case 'M': this.moveTo(p[i++], p[i++]); break;
17921 case 'L': this.lineTo(p[i++], p[i++]); break;
17922 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
17923 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
17924 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
17925 case 'T': this.curveTo(p[i++], p[i++]); break;
17926 case 'A': this.arcTo(p[i+5], p[i+6], p[i], p[i+1], p[i+3], !+p[i+4], p[i+2]); i += 7; break;
17927 case 'H': this.lineTo(p[i++], this.penY); break;
17928 case 'V': this.lineTo(this.penX, p[i++]); break;
17929
17930 case 'Z': case 'z': this.close(); break;
17931 default: cmd = last; i--; continue;
17932 }
17933
17934 last = cmd;
17935 if (last == 'm') last = 'l';
17936 else if (last == 'M') last = 'L';
17937 cmd = p[i++];
17938 }
17939 return this;
17940 },
17941
17942 /* utility methods */
17943
17944 reset: function(){
17945 this.penX = this.penY = 0;
17946 this.penDownX = this.penDownY = null;
17947 this._pivotX = this._pivotY = 0;
17948 this.onReset();
17949 return this;
17950 },
17951
17952 move: function(x,y){
17953 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
17954 return this;
17955 },
17956 moveTo: function(x,y){
17957 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
17958 return this;
17959 },
17960
17961 line: function(x,y){
17962 return this.lineTo(this.penX + (+x), this.penY + (+y));
17963 },
17964 lineTo: function(x,y){
17965 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
17966 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
17967 return this;
17968 },
17969
17970 curve: function(c1x, c1y, c2x, c2y, ex, ey){
17971 var x = this.penX, y = this.penY;
17972 return this.curveTo(
17973 x + (+c1x), y + (+c1y),
17974 c2x == null ? null : x + (+c2x),
17975 c2y == null ? null : y + (+c2y),
17976 ex == null ? null : x + (+ex),
17977 ey == null ? null : y + (+ey)
17978 );
17979 },
17980 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
17981 var x = this.penX, y = this.penY;
17982 if (c2x == null){
17983 c2x = +c1x; c2y = +c1y;
17984 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
17985 }
17986 if (ex == null){
17987 this._pivotX = +c1x; this._pivotY = +c1y;
17988 ex = +c2x; ey = +c2y;
17989 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
17990 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
17991 } else {
17992 this._pivotX = +c2x; this._pivotY = +c2y;
17993 }
17994 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
17995 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
17996 return this;
17997 },
17998
17999 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
18000 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
18001 },
18002 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
18003 ry = Math.abs(+ry || +rx || (+y - this.penY));
18004 rx = Math.abs(+rx || (+x - this.penX));
18005
18006 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
18007
18008 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
18009
18010 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
18011 x -= tX; y -= tY;
18012
18013 // Ellipse Center
18014 var cx = cos * x / 2 + sin * y / 2,
18015 cy = -sin * x / 2 + cos * y / 2,
18016 rxry = rx * rx * ry * ry,
18017 rycx = ry * ry * cx * cx,
18018 rxcy = rx * rx * cy * cy,
18019 a = rxry - rxcy - rycx;
18020
18021 if (a < 0){
18022 a = Math.sqrt(1 - a / rxry);
18023 rx *= a; ry *= a;
18024 cx = x / 2; cy = y / 2;
18025 } else {
18026 a = Math.sqrt(a / (rxcy + rycx));
18027 if (large == clockwise) a = -a;
18028 var cxd = -a * cy * rx / ry,
18029 cyd = a * cx * ry / rx;
18030 cx = cos * cxd - sin * cyd + x / 2;
18031 cy = sin * cxd + cos * cyd + y / 2;
18032 }
18033
18034 // Rotation + Scale Transform
18035 var xx = cos / rx, yx = sin / rx,
18036 xy = -sin / ry, yy = cos / ry;
18037
18038 // Start and End Angle
18039 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
18040 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
18041
18042 cx += tX; cy += tY;
18043 x += tX; y += tY;
18044
18045 // Circular Arc
18046 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
18047 this.onArc(
18048 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
18049 cx, cy, rx, ry, sa, ea, !clockwise, rotation
18050 );
18051 return this;
18052 },
18053
18054 counterArc: function(x, y, rx, ry, outer){
18055 return this.arc(x, y, rx, ry, outer, true);
18056 },
18057 counterArcTo: function(x, y, rx, ry, outer){
18058 return this.arcTo(x, y, rx, ry, outer, true);
18059 },
18060
18061 close: function(){
18062 if (this.penDownX != null){
18063 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
18064 this.penDownX = null;
18065 }
18066 return this;
18067 },
18068
18069 /* overridable handlers */
18070
18071 onReset: function(){
18072 },
18073
18074 onMove: function(sx, sy, ex, ey){
18075 },
18076
18077 onLine: function(sx, sy, ex, ey){
18078 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
18079 },
18080
18081 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
18082 var gx = ex - sx, gy = ey - sy,
18083 g = gx * gx + gy * gy,
18084 v1, v2, cx, cy, u;
18085
18086 cx = c1x - sx; cy = c1y - sy;
18087 u = cx * gx + cy * gy;
18088
18089 if (u > g){
18090 cx -= gx;
18091 cy -= gy;
18092 } else if (u > 0 && g != 0){
18093 cx -= u/g * gx;
18094 cy -= u/g * gy;
18095 }
18096
18097 v1 = cx * cx + cy * cy;
18098
18099 cx = c2x - sx; cy = c2y - sy;
18100 u = cx * gx + cy * gy;
18101
18102 if (u > g){
18103 cx -= gx;
18104 cy -= gy;
18105 } else if (u > 0 && g != 0){
18106 cx -= u/g * gx;
18107 cy -= u/g * gy;
18108 }
18109
18110 v2 = cx * cx + cy * cy;
18111
18112 if (v1 < 0.01 && v2 < 0.01){
18113 this.onLine(sx, sy, ex, ey);
18114 return;
18115 }
18116
18117 // Avoid infinite recursion
18118 if (isNaN(v1) || isNaN(v2)){
18119 throw new Error('Bad input');
18120 }
18121
18122 // Split curve
18123 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
18124 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
18125 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
18126 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
18127 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
18128 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
18129
18130 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
18131 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
18132 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
18133 },
18134
18135 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
18136 // Inverse Rotation + Scale Transform
18137 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
18138 xx = cos * rx, yx = -sin * ry,
18139 xy = sin * rx, yy = cos * ry;
18140
18141 // Bezier Curve Approximation
18142 var arc = ea - sa;
18143 if (arc < 0 && !ccw) arc += Math.PI * 2;
18144 else if (arc > 0 && ccw) arc -= Math.PI * 2;
18145
18146 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
18147 step = arc / n,
18148 k = (4 / 3) * Math.tan(step / 4);
18149
18150 var x = Math.cos(sa), y = Math.sin(sa);
18151
18152 for (var i = 0; i < n; i++){
18153 var cp1x = x - k * y, cp1y = y + k * x;
18154
18155 sa += step;
18156 x = Math.cos(sa); y = Math.sin(sa);
18157
18158 var cp2x = x + k * y, cp2y = y - k * x;
18159
18160 this.onBezierCurve(
18161 sx, sy,
18162 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
18163 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
18164 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
18165 );
18166 }
18167 },
18168
18169 onClose: function(sx, sy, ex, ey){
18170 this.onLine(sx, sy, ex, ey);
18171 }
18172
18173});
18174
18175var CanvasPath = _class(path$2, {
18176
18177 initialize: function(path){
18178 this.reset();
18179 if (path instanceof CanvasPath){
18180 this.path = path.path.slice(0);
18181 } else if (path){
18182 if (path.applyToPath)
18183 path.applyToPath(this);
18184 else
18185 this.push(path);
18186 }
18187 },
18188
18189 onReset: function(){
18190 this.path = [];
18191 },
18192
18193 onMove: function(sx, sy, x, y){
18194 this.path.push(function(context){
18195 context.moveTo(x, y);
18196 });
18197 },
18198
18199 onLine: function(sx, sy, x, y){
18200 this.path.push(function(context){
18201 context.lineTo(x, y);
18202 });
18203 },
18204
18205 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
18206 this.path.push(function(context){
18207 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
18208 });
18209 },
18210
18211 _arcToBezier: path$2.prototype.onArc,
18212
18213 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
18214 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
18215 this.path.push(function(context){
18216 context.arc(cx, cy, rx, sa, ea, ccw);
18217 });
18218 },
18219
18220 onClose: function(){
18221 this.path.push(function(context){
18222 context.closePath();
18223 });
18224 },
18225
18226 toCommands: function(){
18227 return this.path.slice(0);
18228 }
18229
18230});
18231
18232var path = CanvasPath;
18233
18234var colors = {
18235 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
18236 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
18237 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
18238 black: '#000000', silver: '#c0c0c0', gray: '#808080'
18239};
18240
18241var map = function(array, fn){
18242 var results = [];
18243 for (var i = 0, l = array.length; i < l; i++)
18244 results[i] = fn(array[i], i);
18245 return results;
18246};
18247
18248var Color = function(color, type){
18249
18250 if (color.isColor){
18251
18252 this.red = color.red;
18253 this.green = color.green;
18254 this.blue = color.blue;
18255 this.alpha = color.alpha;
18256
18257 } else {
18258
18259 var namedColor = colors[color];
18260 if (namedColor){
18261 color = namedColor;
18262 type = 'hex';
18263 }
18264
18265 switch (typeof color){
18266 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
18267 case 'object': type = type || 'rgb'; color = color.toString(); break;
18268 case 'number': type = 'hex'; color = color.toString(16); break;
18269 }
18270
18271 color = Color['parse' + type.toUpperCase()](color);
18272 this.red = color[0];
18273 this.green = color[1];
18274 this.blue = color[2];
18275 this.alpha = color[3];
18276 }
18277
18278 this.isColor = true;
18279
18280};
18281
18282var limit = function(number, min, max){
18283 return Math.min(max, Math.max(min, number));
18284};
18285
18286var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
18287var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
18288
18289Color.parseRGB = function(color){
18290 return map(color.match(listMatch).slice(1), function(bit, i){
18291 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
18292 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
18293 });
18294};
18295
18296Color.parseHEX = function(color){
18297 if (color.length == 1) color = color + color + color;
18298 return map(color.match(hexMatch).slice(1), function(bit, i){
18299 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
18300 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
18301 });
18302};
18303
18304Color.parseHSB = function(color){
18305 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
18306 if (bit) bit = parseFloat(bit);
18307 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
18308 else if (i < 3) return limit(Math.round(bit), 0, 100);
18309 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
18310 });
18311
18312 var a = hsb[3];
18313 var br = Math.round(hsb[2] / 100 * 255);
18314 if (hsb[1] == 0) return [br, br, br, a];
18315
18316 var hue = hsb[0];
18317 var f = hue % 60;
18318 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
18319 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
18320 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
18321
18322 switch (Math.floor(hue / 60)){
18323 case 0: return [br, t, p, a];
18324 case 1: return [q, br, p, a];
18325 case 2: return [p, br, t, a];
18326 case 3: return [p, q, br, a];
18327 case 4: return [t, p, br, a];
18328 default: return [br, p, q, a];
18329 }
18330};
18331
18332Color.parseHSL = function(color){
18333 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
18334 if (bit) bit = parseFloat(bit);
18335 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
18336 else if (i < 3) return limit(Math.round(bit), 0, 100);
18337 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
18338 });
18339
18340 var h = hsb[0] / 60;
18341 var s = hsb[1] / 100;
18342 var l = hsb[2] / 100;
18343 var a = hsb[3];
18344
18345 var c = (1 - Math.abs(2 * l - 1)) * s;
18346 var x = c * (1 - Math.abs(h % 2 - 1));
18347 var m = l - c / 2;
18348
18349 var p = Math.round((c + m) * 255);
18350 var q = Math.round((x + m) * 255);
18351 var t = Math.round((m) * 255);
18352
18353 switch (Math.floor(h)){
18354 case 0: return [p, q, t, a];
18355 case 1: return [q, p, t, a];
18356 case 2: return [t, p, q, a];
18357 case 3: return [t, q, p, a];
18358 case 4: return [q, t, p, a];
18359 default: return [p, t, q, a];
18360 }
18361};
18362
18363var toString = function(type, array){
18364 if (array[3] != 1) type += 'a';
18365 else array.pop();
18366 return type + '(' + array.join(', ') + ')';
18367};
18368
18369Color.prototype = {
18370
18371 toHSB: function(array){
18372 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
18373
18374 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
18375 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
18376 if (saturation){
18377 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
18378 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
18379 if ((hue /= 6) < 0) hue++;
18380 }
18381
18382 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
18383
18384 return (array) ? hsb : toString('hsb', hsb);
18385 },
18386
18387 toHSL: function(array){
18388 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
18389
18390 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
18391 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
18392 if (saturation){
18393 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
18394 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
18395 if ((hue /= 6) < 0) hue++;
18396 }
18397
18398 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
18399
18400 return (array) ? hsl : toString('hsl', hsl);
18401 },
18402
18403 toHEX: function(array){
18404
18405 var a = this.alpha;
18406 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
18407
18408 var hex = map([this.red, this.green, this.blue], function(bit){
18409 bit = bit.toString(16);
18410 return (bit.length == 1) ? '0' + bit : bit;
18411 });
18412
18413 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
18414 },
18415
18416 toRGB: function(array){
18417 var rgb = [this.red, this.green, this.blue, this.alpha];
18418 return (array) ? rgb : toString('rgb', rgb);
18419 }
18420
18421};
18422
18423Color.prototype.toString = Color.prototype.toRGB;
18424
18425Color.hex = function(hex){
18426 return new Color(hex, 'hex');
18427};
18428
18429if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
18430
18431Color.hsb = function(h, s, b, a){
18432 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
18433};
18434
18435if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
18436
18437Color.hsl = function(h, s, l, a){
18438 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
18439};
18440
18441if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
18442
18443Color.rgb = function(r, g, b, a){
18444 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
18445};
18446
18447if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
18448
18449Color.detach = function(color){
18450 color = new Color(color);
18451 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
18452};
18453
18454var color = Color;
18455
18456var dummy = _class({
18457
18458 // placement
18459
18460 _resetPlacement: function(){
18461 var container = this.parentNode;
18462 if (container){
18463 var previous = this.previousSibling, next = this.nextSibling;
18464 if (previous){
18465 previous.nextSibling = next;
18466 } else {
18467 container.firstChild = next;
18468 }
18469 if (next){
18470 next.previousSibling = previous;
18471 } else {
18472 container.lastChild = this.previousSibling;
18473 }
18474 }
18475 this.previousSibling = null;
18476 this.nextSibling = null;
18477 this.parentNode = null;
18478 return this;
18479 },
18480
18481 inject: function(container){
18482 this._resetPlacement();
18483 var last = container.lastChild;
18484 if (last){
18485 last.nextSibling = this;
18486 this.previousSibling = last;
18487 } else {
18488 container.firstChild = this;
18489 }
18490 container.lastChild = this;
18491 this.parentNode = container;
18492 this._place();
18493 return this;
18494 },
18495
18496 injectBefore: function(sibling){
18497 this._resetPlacement();
18498 var container = sibling.parentNode;
18499 if (!container) return this;
18500 var previous = sibling.previousSibling;
18501 if (previous){
18502 previous.nextSibling = this;
18503 this.previousSibling = previous;
18504 } else {
18505 container.firstChild = this;
18506 }
18507 sibling.previousSibling = this;
18508 this.nextSibling = sibling;
18509 this.parentNode = container;
18510 this._place();
18511 return this;
18512 },
18513
18514 eject: function(){
18515 this._resetPlacement();
18516 this._place();
18517 return this;
18518 },
18519
18520 _place: function(){},
18521
18522 // events
18523
18524 dispatch: function(event){
18525 var events = this._events,
18526 listeners = events && events[event.type];
18527 if (listeners){
18528 listeners = listeners.slice(0);
18529 for (var i = 0, l = listeners.length; i < l; i++){
18530 var fn = listeners[i], result;
18531 if (typeof fn == 'function')
18532 result = fn.call(this, event);
18533 else
18534 result = fn.handleEvent(event);
18535 if (result === false) event.preventDefault();
18536 }
18537 }
18538 if (this.parentNode && this.parentNode.dispatch){
18539 this.parentNode.dispatch(event);
18540 }
18541 },
18542
18543 subscribe: function(type, fn, bind){
18544 if (typeof type != 'string'){ // listen type / fn with object
18545 var subscriptions = [];
18546 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
18547 return function(){ // unsubscribe
18548 for (var i = 0, l = subscriptions.length; i < l; i++)
18549 subscriptions[i]();
18550 return this;
18551 };
18552 } else { // listen to one
18553 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
18554 events = this._events || (this._events = {}),
18555 listeners = events[type] || (events[type] = []);
18556 listeners.push(bound);
18557 return function(){
18558 // unsubscribe
18559 for (var i = 0, l = listeners.length; i < l; i++){
18560 if (listeners[i] === bound){
18561 listeners.splice(i, 1);
18562 break;
18563 }
18564 }
18565 }
18566 }
18567 }
18568
18569});
18570
18571var CanvasNode = _class(transform, dummy, {
18572
18573 invalidate: function(){
18574 if (this.parentNode) this.parentNode.invalidate();
18575 if (this._layer) this._layerCache = null;
18576 return this;
18577 },
18578
18579 _place: function(){
18580 this.invalidate();
18581 },
18582
18583 _transform: function(){
18584 this.invalidate();
18585 },
18586
18587 blend: function(opacity){
18588 if (opacity >= 1 && this._layer) this._layer = null;
18589 this._opacity = opacity;
18590 if (this.parentNode) this.parentNode.invalidate();
18591 return this;
18592 },
18593
18594 // visibility
18595
18596 hide: function(){
18597 this._invisible = true;
18598 if (this.parentNode) this.parentNode.invalidate();
18599 return this;
18600 },
18601
18602 show: function(){
18603 this._invisible = false;
18604 if (this.parentNode) this.parentNode.invalidate();
18605 return this;
18606 },
18607
18608 // interaction
18609
18610 indicate: function(cursor, tooltip){
18611 this._cursor = cursor;
18612 this._tooltip = tooltip;
18613 return this.invalidate();
18614 },
18615
18616 hitTest: function(x, y){
18617 if (this._invisible) return null;
18618 var point = this.inversePoint(x, y);
18619 if (!point) return null;
18620 return this.localHitTest(point.x, point.y);
18621 },
18622
18623 // rendering
18624
18625 renderTo: function(context, xx, yx, xy, yy, x, y){
18626 var opacity = this._opacity;
18627 if (opacity == null || opacity >= 1){
18628 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
18629 }
18630
18631 // Render to a compositing layer and cache it
18632
18633 var layer = this._layer, canvas, isDirty = true,
18634 w = context.canvas.width, h = context.canvas.height;
18635 if (layer){
18636 layer.setTransform(1, 0, 0, 1, 0, 0);
18637 canvas = layer.canvas;
18638 if (canvas.width < w || canvas.height < h){
18639 canvas.width = w;
18640 canvas.height = h;
18641 } else {
18642 var c = this._layerCache;
18643 if (c && c.xx === xx && c.yx === yx && c.xy === xy
18644 && c.yy === yy && c.x === x && c.y === y){
18645 isDirty = false;
18646 } else {
18647 layer.clearRect(0, 0, w, h);
18648 }
18649 }
18650 } else {
18651 canvas = document.createElement('canvas');
18652 canvas.width = w;
18653 canvas.height = h;
18654 this._layer = layer = canvas.getContext('2d');
18655 }
18656
18657 if (isDirty){
18658 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
18659 this._layerCache = {
18660 xx: xx,
18661 yx: yx,
18662 xy: xy,
18663 yy: yy,
18664 x: x,
18665 y: y
18666 };
18667 }
18668
18669 context.globalAlpha = opacity;
18670 context.setTransform(1, 0, 0, 1, 0, 0);
18671 context.drawImage(
18672 canvas,
18673 0, 0, w, h,
18674 0, 0, w, h
18675 );
18676 context.globalAlpha = 1;
18677 }
18678
18679});
18680
18681var node = CanvasNode;
18682
18683var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas');
18684var genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
18685
18686function recolorImage(img, color1, color2){
18687 // TODO: Fix this experimental implementation
18688 color1 = color.detach(color1);
18689 color2 = color.detach(color2);
18690 var canvas = document.createElement('canvas'),
18691 context = canvas.getContext('2d');
18692 canvas.width = img.width;
18693 canvas.height = img.height;
18694 context.fillStyle = color2[0];
18695 context.fillRect(0, 0, img.width, img.height);
18696 context.globalCompositeOperation = 'lighter';
18697 context.drawImage(img, 0, 0);
18698 return canvas;
18699}
18700
18701var Base = _class(node, {
18702
18703 initialize: function(){
18704 this._fill = null;
18705 this._pendingFill = null;
18706 this._fillTransform = null;
18707 this._stroke = null;
18708 this._strokeCap = null;
18709 this._strokeDash = null;
18710 this._strokeJoin = null;
18711 this._strokeWidth = null;
18712 },
18713
18714 /* styles */
18715
18716 _addColors: function(gradient, stops){
18717 // Enumerate stops, assumes offsets are enumerated in order
18718 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
18719 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
18720 gradient.addColorStop(i / l, new color(stops[i]).toString());
18721 else for (var offset in stops)
18722 gradient.addColorStop(offset, new color(stops[offset]).toString());
18723 return gradient;
18724 },
18725
18726
18727 fill: function(color$$1){
18728 if (arguments.length > 1) return this.fillLinear(arguments);
18729 if (this._pendingFill) this._pendingFill();
18730 this._fill = color$$1 ? new color(color$$1).toString() : null;
18731 return this.invalidate();
18732 },
18733
18734 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
18735 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
18736 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
18737 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
18738 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
18739 if (centerX == null) centerX = focusX;
18740 if (centerY == null) centerY = focusY;
18741
18742 centerX += centerX - focusX;
18743 centerY += centerY - focusY;
18744
18745 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
18746 var ys = radiusY / radiusX;
18747
18748 if (this._pendingFill) this._pendingFill();
18749
18750 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
18751
18752 // Double fill radius to simulate repeating gradient
18753 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
18754 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
18755 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
18756 } else for (var offset in stops){
18757 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
18758 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
18759 }
18760
18761 this._fill = gradient;
18762 this._fillTransform = new transform(1, 0, 0, ys);
18763 return this.invalidate();
18764 },
18765
18766 fillLinear: function(stops, x1, y1, x2, y2){
18767 if (arguments.length < 5){
18768 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
18769
18770 var x = Math.cos(angle), y = -Math.sin(angle),
18771 l = (Math.abs(x) + Math.abs(y)) / 2,
18772 w = this.width || 1, h = this.height || 1;
18773
18774 x *= l; y *= l;
18775
18776 x1 = 0.5 - x;
18777 x2 = 0.5 + x;
18778 y1 = 0.5 - y;
18779 y2 = 0.5 + y;
18780 this._fillTransform = new transform(w, 0, 0, h);
18781 } else {
18782 this._fillTransform = null;
18783 }
18784 if (this._pendingFill) this._pendingFill();
18785 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
18786 this._addColors(gradient, stops);
18787 this._fill = gradient;
18788 return this.invalidate();
18789 },
18790
18791 fillImage: function(url, width, height, left, top, color1, color2){
18792 if (this._pendingFill) this._pendingFill();
18793 var img = url;
18794 if (!(img instanceof Image)){
18795 img = new Image();
18796 img.src = url;
18797 }
18798 if (img.width && img.height){
18799 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
18800 }
18801
18802 // Not yet loaded
18803 this._fill = null;
18804 var self = this,
18805 callback = function(){
18806 cancel();
18807 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
18808 },
18809 cancel = function(){
18810 img.removeEventListener('load', callback, false);
18811 self._pendingFill = null;
18812 };
18813 this._pendingFill = cancel;
18814 img.addEventListener('load', callback, false);
18815 return this;
18816 },
18817
18818 _fillImage: function(img, width, height, left, top, color1, color2){
18819 var w = width ? width / img.width : 1,
18820 h = height ? height / img.height : 1;
18821 if (color1 != null) img = recolorImage(img, color1, color2);
18822 this._fill = genericContext.createPattern(img, 'repeat');
18823 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
18824 return this.invalidate();
18825 },
18826
18827 stroke: function(color$$1, width, cap, join, dash){
18828 this._stroke = color$$1 ? new color(color$$1).toString() : null;
18829 this._strokeWidth = (width != null) ? width : 1;
18830 this._strokeCap = (cap != null) ? cap : 'round';
18831 this._strokeJoin = (join != null) ? join : 'round';
18832 this._strokeDash = dash;
18833 return this.invalidate();
18834 },
18835
18836 // Rendering
18837
18838 element_renderTo: node.prototype.renderTo,
18839
18840 renderTo: function(context, xx, yx, xy, yy, x, y){
18841 var opacity = this._opacity;
18842 if (opacity == null || opacity >= 1){
18843 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
18844 }
18845 if (this._fill && this._stroke){
18846 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
18847 }
18848 context.globalAlpha = opacity;
18849 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
18850 context.globalAlpha = 1;
18851 return r;
18852 },
18853
18854 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
18855 context.setTransform(xx, yx, xy, yy, x, y);
18856 this.renderShapeTo(context);
18857 }
18858
18859});
18860
18861Base._genericContext = genericContext;
18862
18863var base = Base;
18864
18865var shape = _class(base, {
18866
18867 base_initialize: base.prototype.initialize,
18868
18869 initialize: function(path$$1, width, height){
18870 this.base_initialize();
18871 this.width = width;
18872 this.height = height;
18873 if (path$$1 != null) this.draw(path$$1);
18874 },
18875
18876 draw: function(path$$1, width, height){
18877 if (!(path$$1 instanceof path)) path$$1 = new path(path$$1);
18878 this.path = path$$1;
18879 this._commands = path$$1.toCommands();
18880 if (width != null) this.width = width;
18881 if (height != null) this.height = height;
18882 return this.invalidate();
18883 },
18884
18885 localHitTest: function(x, y){
18886 if (!this._fill) return null;
18887 if (this.width == null || this.height == null){
18888 var context = base._genericContext, commands = this._commands;
18889 if (!commands) return null;
18890 context.beginPath();
18891 for (var i = 0, l = commands.length; i < l; i++)
18892 commands[i](context);
18893 return context.isPointInPath(x, y) ? this : null;
18894 }
18895 if (x > 0 && y > 0 && x < this.width && y < this.height){
18896 return this;
18897 }
18898 return null;
18899 },
18900
18901 renderShapeTo: function(context){
18902 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
18903 return null;
18904 }
18905 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
18906 var commands = this._commands,
18907 fill = this._fill,
18908 stroke = this._stroke,
18909 dash = this._strokeDash;
18910
18911 context.beginPath();
18912
18913 if (dash) {
18914 if (context.setLineDash) {
18915 context.setLineDash(dash);
18916 } else {
18917 // TODO: Remove when FF supports setLineDash.
18918 context.mozDash = dash;
18919 }
18920 // TODO: Create fallback to other browsers.
18921 } else {
18922 if (context.setLineDash) {
18923 context.setLineDash([]);
18924 } else {
18925 context.mozDash = null;
18926 }
18927 }
18928
18929 for (var i = 0, l = commands.length; i < l; i++)
18930 commands[i](context);
18931
18932 if (fill){
18933 var m = this._fillTransform;
18934 if (m){
18935 context.save(); // TODO: Optimize away this by restoring the transform before stroking
18936 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
18937 context.fillStyle = fill;
18938 context.fill();
18939 context.restore();
18940 } else {
18941 context.fillStyle = fill;
18942 context.fill();
18943 }
18944 }
18945 if (stroke){
18946 context.strokeStyle = stroke;
18947 context.lineWidth = this._strokeWidth;
18948 context.lineCap = this._strokeCap;
18949 context.lineJoin = this._strokeJoin;
18950 context.stroke();
18951 }
18952 }
18953
18954});
18955
18956var group = _class(node, container, {
18957
18958 initialize: function(width, height){
18959 this.width = width;
18960 this.height = height;
18961 },
18962
18963 localHitTest: function(x, y){
18964 var node$$2 = this.lastChild;
18965 while (node$$2){
18966 var hit = node$$2.hitTest(x, y);
18967 if (hit) return hit;
18968 node$$2 = node$$2.previousSibling;
18969 }
18970 return null;
18971 },
18972
18973 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
18974 if (this._invisible) return;
18975
18976 x = xx * this.x + xy * this.y + x;
18977 y = yx * this.x + yy * this.y + y;
18978
18979 var t = xx;
18980 xx = t * this.xx + xy * this.yx;
18981 xy = t * this.xy + xy * this.yy;
18982 t = yx;
18983 yx = t * this.xx + yy * this.yx;
18984 yy = t * this.xy + yy * this.yy;
18985
18986 var node$$2 = this.firstChild;
18987 while (node$$2){
18988 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
18989 node$$2 = node$$2.nextSibling;
18990 }
18991 }
18992
18993});
18994
18995var clippingrectangle = _class(node, container, {
18996
18997 initialize: function(width, height){
18998 this.width = width;
18999 this.height = height;
19000 },
19001
19002 localHitTest: function(x, y) {
19003 var node$$2 = this.lastChild;
19004 while (node$$2){
19005 var hit = node$$2.hitTest(x, y);
19006 if (hit) return hit;
19007 node$$2 = node$$2.previousSibling;
19008 }
19009 return null;
19010 },
19011
19012 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
19013 context.setTransform(xx, yx, xy, yy, x, y);
19014 context.save();
19015 // Need beginPath to fix Firefox bug. See 3354054.
19016 context.beginPath();
19017 context.rect(this.x, this.y, this.width, this.height);
19018 context.clip();
19019
19020 var node$$2 = this.firstChild;
19021 while(node$$2) {
19022 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
19023 node$$2 = node$$2.nextSibling;
19024 }
19025 context.restore();
19026 }
19027});
19028
19029var fontAnchors = { middle: 'center' };
19030
19031var text = _class(base, {
19032
19033 base_initialize: base.prototype.initialize,
19034
19035 initialize: function(text, font, alignment, path){
19036 this.base_initialize();
19037 this.draw.apply(this, arguments);
19038 },
19039
19040 draw: function(text, font, alignment, path){
19041 var em;
19042 if (typeof font == 'string'){
19043 em = Number(/(\d+)/.exec(font)[0]);
19044 } else if (font){
19045 em = parseFloat(font.fontSize || font['font-size'] || '12');
19046 font = (font.fontStyle || font['font-style'] || '') + ' ' +
19047 (font.fontVariant || font['font-variant'] || '') + ' ' +
19048 (font.fontWeight || font['font-weight'] || '') + ' ' +
19049 em + 'px ' +
19050 (font.fontFamily || font['font-family'] || 'Arial');
19051 } else {
19052 font = this._font;
19053 }
19054
19055 var lines = text && text.split(/\r?\n/);
19056 this._font = font;
19057 this._fontSize = em;
19058 this._text = lines;
19059 this._alignment = fontAnchors[alignment] || alignment || 'left';
19060
19061 var context = base._genericContext;
19062
19063 context.font = this._font;
19064 context.textAlign = this._alignment;
19065 context.textBaseline = 'middle';
19066
19067 lines = this._text;
19068 var l = lines.length, width = 0;
19069 for (var i = 0; i < l; i++){
19070 var w = context.measureText(lines[i]).width;
19071 if (w > width) width = w;
19072 }
19073 this.width = width;
19074 this.height = l ? l * 1.1 * em : 0;
19075 return this.invalidate();
19076 },
19077
19078 // Interaction
19079
19080 localHitTest: function(x, y){
19081 if (!this._fill) return null;
19082 if (x > 0 && y > 0 && x < this.width && y < this.height){
19083 return this;
19084 }
19085 return null;
19086 },
19087
19088 // Rendering
19089
19090 renderShapeTo: function(context){
19091 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
19092 return null;
19093 }
19094 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
19095 var fill = this._fill,
19096 stroke = this._stroke,
19097 text = this._text,
19098 dash = this._strokeDash;
19099
19100 context.font = this._font;
19101 context.textAlign = this._alignment;
19102 context.textBaseline = 'middle';
19103
19104 var em = this._fontSize,
19105 y = em / 2,
19106 lineHeight = 1.1 * em,
19107 lines = text,
19108 l = lines.length;
19109
19110 if (fill){
19111 context.fillStyle = fill;
19112 for (var i = 0; i < l; i++)
19113 context.fillText(lines[i], 0, y + i * lineHeight);
19114 }
19115 if (stroke){
19116 if (dash) {
19117 if (context.setLineDash) {
19118 context.setLineDash(dash);
19119 } else {
19120 // TODO: Remove when FF supports setLineDash.
19121 context.mozDash = dash;
19122 }
19123 // TODO: Create fallback to other browsers.
19124 } else {
19125 if (context.setLineDash) {
19126 context.setLineDash([]);
19127 } else {
19128 context.mozDash = null;
19129 }
19130 }
19131
19132 context.strokeStyle = stroke;
19133 context.lineWidth = this._strokeWidth;
19134 context.lineCap = this._strokeCap;
19135 context.lineJoin = this._strokeJoin;
19136 for (i = 0; i < l; i++)
19137 context.strokeText(lines[i], 0, y + i * lineHeight);
19138 }
19139 }
19140
19141});
19142
19143var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
19144
19145var styleSheet;
19146var styledTags = {};
19147var styleTag = function(tag){
19148 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
19149};
19150
19151var init = function(document){
19152
19153 var namespaces;
19154 try { // IE9 workaround: sometimes it throws here
19155 namespaces = document.namespaces;
19156 } catch (e) {
19157 }
19158 if (!namespaces) return false;
19159
19160 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
19161 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
19162
19163 styleSheet = document.createStyleSheet();
19164 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
19165/* styleTag('skew');
19166 styleTag('fill');
19167 styleTag('stroke');
19168 styleTag('path');
19169 styleTag('textpath');
19170 styleTag('group');*/
19171
19172 styleTag('vml');
19173
19174 return true;
19175
19176};
19177
19178var createElement = function(tag){
19179 if (!(tag in styledTags)) styleTag(tag);
19180 return document.createElement('av:' + tag);
19181};
19182
19183var dom = {
19184 init: init,
19185 createElement: createElement
19186};
19187
19188var precision = 100;
19189
19190var VMLSurface = _class(native_1, container, {
19191
19192 initialize: function VMLSurface(width, height, existingElement){
19193 this.element = existingElement || document.createElement('vml');
19194 this.containerElement = dom.createElement('group');
19195 this.element.appendChild(this.containerElement);
19196 if (width != null && height != null) this.resize(width, height);
19197 },
19198
19199 resize: function(width, height){
19200 this.width = width;
19201 this.height = height;
19202
19203 var style = this.element.style;
19204 style.pixelWidth = width;
19205 style.pixelHeight = height;
19206
19207 style = this.containerElement.style;
19208 style.width = width;
19209 style.height = height;
19210
19211 var halfPixel = (0.5 * precision);
19212
19213 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
19214 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
19215
19216 return this;
19217 }
19218
19219});
19220
19221VMLSurface.tagName = 'av:vml';
19222
19223var surface$2 = VMLSurface;
19224
19225var precision$1 = 100;
19226
19227var round = Math.round;
19228
19229var VMLPath = _class(path$2, {
19230
19231 initialize: function(path){
19232 this.reset();
19233 if (path instanceof VMLPath){
19234 this.path = [Array.prototype.join.call(path.path, ' ')];
19235 } else if (path){
19236 if (path.applyToPath)
19237 path.applyToPath(this);
19238 else
19239 this.push(path);
19240 }
19241 },
19242
19243 onReset: function(){
19244 this.path = [];
19245 },
19246
19247 onMove: function(sx, sy, x, y){
19248 this.path.push('m', round(x * precision$1), round(y * precision$1));
19249 },
19250
19251 onLine: function(sx, sy, x, y){
19252 this.path.push('l', round(x * precision$1), round(y * precision$1));
19253 },
19254
19255 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
19256 this.path.push('c',
19257 round(p1x * precision$1), round(p1y * precision$1),
19258 round(p2x * precision$1), round(p2y * precision$1),
19259 round(x * precision$1), round(y * precision$1)
19260 );
19261 },
19262
19263 _arcToBezier: path$2.prototype.onArc,
19264
19265 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
19266 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
19267 cx *= precision$1;
19268 cy *= precision$1;
19269 rx *= precision$1;
19270 this.path.push(ccw ? 'at' : 'wa',
19271 round(cx - rx), round(cy - rx),
19272 round(cx + rx), round(cy + rx),
19273 round(sx * precision$1), round(sy * precision$1),
19274 round(ex * precision$1), round(ey * precision$1)
19275 );
19276 },
19277
19278 onClose: function(){
19279 this.path.push('x');
19280 },
19281
19282 toVML: function(){
19283 return this.path.join(' ');
19284 }
19285
19286});
19287
19288VMLPath.prototype.toString = VMLPath.prototype.toVML;
19289
19290var path$4 = VMLPath;
19291
19292var shadow = _class(dummy, native_1, {
19293
19294 dummy_inject: dummy.prototype.inject,
19295 dummy_injectBefore: dummy.prototype.injectBefore,
19296 dummy_eject: dummy.prototype.eject,
19297 native_inject: native_1.prototype.inject,
19298 native_injectBefore: native_1.prototype.injectBefore,
19299 native_eject: native_1.prototype.eject,
19300
19301 inject: function(container){
19302 this.dummy_inject(container);
19303 this.native_inject(container);
19304 return this;
19305 },
19306
19307 injectBefore: function(sibling){
19308 this.dummy_injectBefore(sibling);
19309 this.native_injectBefore(sibling);
19310 return this;
19311 },
19312
19313 eject: function(){
19314 this.dummy_eject();
19315 this.native_eject();
19316 return this;
19317 }
19318
19319});
19320
19321var node$2 = _class(shadow, transform, {
19322
19323 initialize: function(tag){
19324 //this.uid = uniqueID();
19325 var element = this.element = dom.createElement(tag);
19326 //element.setAttribute('id', 'e' + this.uid);
19327 },
19328
19329 _place: function(){
19330 if (this.parentNode){
19331 this._transform();
19332 }
19333 },
19334
19335 // visibility
19336
19337 hide: function(){
19338 this.element.style.display = 'none';
19339 return this;
19340 },
19341
19342 show: function(){
19343 this.element.style.display = '';
19344 return this;
19345 },
19346
19347 // interaction
19348
19349 indicate: function(cursor, tooltip){
19350 if (cursor) this.element.style.cursor = cursor;
19351 if (tooltip) this.element.title = tooltip;
19352 return this;
19353 }
19354
19355});
19356
19357var precision$3 = 100;
19358
19359var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
19360
19361var base$2 = _class(node$2, {
19362
19363 element_initialize: node$2.prototype.initialize,
19364
19365 initialize: function(tag){
19366 this.element_initialize(tag);
19367 var element = this.element;
19368
19369 var skew = this.skewElement = dom.createElement('skew');
19370 skew.on = true;
19371 element.appendChild(skew);
19372
19373 var fill = this.fillElement = dom.createElement('fill');
19374 fill.on = false;
19375 element.appendChild(fill);
19376
19377 var stroke = this.strokeElement = dom.createElement('stroke');
19378 stroke.on = false;
19379 element.appendChild(stroke);
19380 },
19381
19382 /* transform */
19383
19384 _transform: function(){
19385 var container = this.parentNode;
19386
19387 // Active Transformation Matrix
19388 var m = container ? new transform(container._activeTransform).transform(this) : this;
19389
19390 // Box in shape user space
19391
19392 var box = this._boxCoords || this._size || defaultBox;
19393
19394 var originX = box.left || 0,
19395 originY = box.top || 0,
19396 width = box.width || 1,
19397 height = box.height || 1;
19398
19399 // Flipped
19400 var flip = m.yx / m.xx > m.yy / m.xy;
19401 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
19402 flip = flip ? -1 : 1;
19403
19404 m = new transform().scale(flip, 1).transform(m);
19405
19406 // Rotation is approximated based on the transform
19407 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
19408
19409 // Reverse the rotation, leaving the final transform in box space
19410 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
19411
19412 var transform$$2 = new transform(
19413 (m.xx * cos - m.xy * sin),
19414 (m.yx * cos - m.yy * sin) * flip,
19415 (m.xy * cos + m.xx * sin) * flip,
19416 (m.yy * cos + m.yx * sin)
19417 );
19418
19419 var rotationTransform = new transform().rotate(rotation, 0, 0);
19420
19421 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
19422
19423 // Scale box after reversing rotation
19424 width *= Math.abs(shapeToBox.xx);
19425 height *= Math.abs(shapeToBox.yy);
19426
19427 // Place box
19428 var left = m.x, top = m.y;
19429
19430 // Compensate for offset by center origin rotation
19431 var vx = -width / 2, vy = -height / 2;
19432 var point = rotationTransform.point(vx, vy);
19433 left -= point.x - vx;
19434 top -= point.y - vy;
19435
19436 // Adjust box position based on offset
19437 var rsm = new transform(m).moveTo(0,0);
19438 point = rsm.point(originX, originY);
19439 left += point.x;
19440 top += point.y;
19441
19442 if (flip < 0) left = -left - width;
19443
19444 // Place transformation origin
19445 var point0 = rsm.point(-originX, -originY);
19446 var point1 = rotationTransform.point(width, height);
19447 var point2 = rotationTransform.point(width, 0);
19448 var point3 = rotationTransform.point(0, height);
19449
19450 var minX = Math.min(0, point1.x, point2.x, point3.x),
19451 maxX = Math.max(0, point1.x, point2.x, point3.x),
19452 minY = Math.min(0, point1.y, point2.y, point3.y),
19453 maxY = Math.max(0, point1.y, point2.y, point3.y);
19454
19455 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
19456 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
19457
19458 // Adjust the origin
19459 point = shapeToBox.point(originX, originY);
19460 originX = point.x;
19461 originY = point.y;
19462
19463 // Scale stroke
19464 var strokeWidth = this._strokeWidth;
19465 if (strokeWidth){
19466 // Scale is the hypothenus between the two vectors
19467 // TODO: Use area calculation instead
19468 var vx = m.xx + m.xy, vy = m.yy + m.yx;
19469 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
19470 }
19471
19472 // convert to multiplied precision space
19473 originX *= precision$3;
19474 originY *= precision$3;
19475 left *= precision$3;
19476 top *= precision$3;
19477 width *= precision$3;
19478 height *= precision$3;
19479
19480 // Set box
19481 var element = this.element;
19482 element.coordorigin = originX + ',' + originY;
19483 element.coordsize = width + ',' + height;
19484 element.style.left = left + 'px';
19485 element.style.top = top + 'px';
19486 element.style.width = width;
19487 element.style.height = height;
19488 element.style.rotation = rotation.toFixed(8);
19489 element.style.flip = flip < 0 ? 'x' : '';
19490
19491 // Set transform
19492 var skew = this.skewElement;
19493 skew.matrix = [transform$$2.xx.toFixed(4), transform$$2.xy.toFixed(4), transform$$2.yx.toFixed(4), transform$$2.yy.toFixed(4), 0, 0];
19494 skew.origin = transformOriginX + ',' + transformOriginY;
19495
19496 // Set stroke
19497 this.strokeElement.weight = strokeWidth + 'px';
19498 },
19499
19500 /* styles */
19501
19502 _createGradient: function(style, stops){
19503 var fill = this.fillElement;
19504
19505 // Temporarily eject the fill from the DOM
19506 this.element.removeChild(fill);
19507
19508 fill.type = style;
19509 fill.method = 'none';
19510 fill.rotate = true;
19511
19512 var colors = [], color1, color2;
19513
19514 var addColor = function(offset, color$$2){
19515 color$$2 = color.detach(color$$2);
19516 if (color1 == null) color1 = color2 = color$$2;
19517 else color2 = color$$2;
19518 colors.push(offset + ' ' + color$$2[0]);
19519 };
19520
19521 // Enumerate stops, assumes offsets are enumerated in order
19522 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
19523 else for (var offset in stops) addColor(offset, stops[offset]);
19524
19525 fill.color = color1[0];
19526 fill.color2 = color2[0];
19527
19528 //if (fill.colors) fill.colors.value = colors; else
19529 fill.colors = colors;
19530
19531 // Opacity order gets flipped when color stops are specified
19532 fill.opacity = color2[1];
19533 fill['ao:opacity2'] = color1[1];
19534
19535 fill.on = true;
19536 this.element.appendChild(fill);
19537 return fill;
19538 },
19539
19540 _setColor: function(type, color$$2){
19541 var element = type == 'fill' ? this.fillElement : this.strokeElement;
19542 if (color$$2 == null){
19543 element.on = false;
19544 } else {
19545 color$$2 = color.detach(color$$2);
19546 element.color = color$$2[0];
19547 element.opacity = color$$2[1];
19548 element.on = true;
19549 }
19550 },
19551
19552 fill: function(color$$2){
19553 if (arguments.length > 1){
19554 this.fillLinear(arguments);
19555 } else {
19556 this._boxCoords = defaultBox;
19557 var fill = this.fillElement;
19558 fill.type = 'solid';
19559 fill.color2 = '';
19560 fill['ao:opacity2'] = '';
19561 if (fill.colors) fill.colors.value = '';
19562 this._setColor('fill', color$$2);
19563 }
19564 return this;
19565 },
19566
19567 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
19568 var fill = this._createGradient('gradientradial', stops);
19569 if (focusX == null) focusX = this.left + this.width * 0.5;
19570 if (focusY == null) focusY = this.top + this.height * 0.5;
19571 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
19572 if (radiusX == null) radiusX = this.width * 0.5;
19573 if (centerX == null) centerX = focusX;
19574 if (centerY == null) centerY = focusY;
19575
19576 centerX += centerX - focusX;
19577 centerY += centerY - focusY;
19578
19579 var box = this._boxCoords = {
19580 left: centerX - radiusX * 2,
19581 top: centerY - radiusY * 2,
19582 width: radiusX * 4,
19583 height: radiusY * 4
19584 };
19585 focusX -= box.left;
19586 focusY -= box.top;
19587 focusX /= box.width;
19588 focusY /= box.height;
19589
19590 fill.focussize = '0 0';
19591 fill.focusposition = focusX + ',' + focusY;
19592 fill.focus = '50%';
19593
19594 this._transform();
19595
19596 return this;
19597 },
19598
19599 fillLinear: function(stops, x1, y1, x2, y2){
19600 var fill = this._createGradient('gradient', stops);
19601 fill.focus = '100%';
19602 if (arguments.length == 5){
19603 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
19604 this._boxCoords = {
19605 left: Math.min(x1, x2),
19606 top: Math.min(y1, y2),
19607 width: w < 1 ? h : w,
19608 height: h < 1 ? w : h
19609 };
19610 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
19611 } else {
19612 this._boxCoords = null;
19613 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
19614 }
19615 this._transform();
19616 return this;
19617 },
19618
19619 fillImage: function(url, width, height, left, top, color1, color2){
19620 var fill = this.fillElement;
19621 if (color1 != null){
19622 color1 = color.detach(color1);
19623 if (color2 != null) color2 = color.detach(color2);
19624 fill.type = 'pattern';
19625 fill.color = color1[0];
19626 fill.color2 = color2 == null ? color1[0] : color2[0];
19627 fill.opacity = color2 == null ? 0 : color2[1];
19628 fill['ao:opacity2'] = color1[1];
19629 } else {
19630 fill.type = 'tile';
19631 fill.color = '';
19632 fill.color2 = '';
19633 fill.opacity = 1;
19634 fill['ao:opacity2'] = 1;
19635 }
19636 if (fill.colors) fill.colors.value = '';
19637 fill.rotate = true;
19638 fill.src = url;
19639
19640 fill.size = '1,1';
19641 fill.position = '0,0';
19642 fill.origin = '0,0';
19643 fill.aspect = 'ignore'; // ignore, atleast, atmost
19644 fill.on = true;
19645
19646 if (!left) left = 0;
19647 if (!top) top = 0;
19648 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
19649 this._transform();
19650 return this;
19651 },
19652
19653 /* stroke */
19654
19655 stroke: function(color$$2, width, cap, join){
19656 var stroke = this.strokeElement;
19657 this._strokeWidth = (width != null) ? width : 1;
19658 stroke.weight = (width != null) ? width + 'px' : 1;
19659 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
19660 stroke.joinstyle = (join != null) ? join : 'round';
19661
19662 this._setColor('stroke', color$$2);
19663 return this;
19664 }
19665
19666});
19667
19668var precision$2 = 100;
19669
19670var shape$2 = _class(base$2, {
19671
19672 base_initialize: base$2.prototype.initialize,
19673
19674 initialize: function(path, width, height){
19675 this.base_initialize('shape');
19676
19677 var p = this.pathElement = dom.createElement('path');
19678 p.gradientshapeok = true;
19679 this.element.appendChild(p);
19680
19681 this.width = width;
19682 this.height = height;
19683
19684 if (path != null) this.draw(path);
19685 },
19686
19687 // SVG to VML
19688
19689 draw: function(path, width, height){
19690
19691 if (!(path instanceof path$4)) path = new path$4(path);
19692 this._vml = path.toVML();
19693 //this._size = path.measure();
19694
19695 if (width != null) this.width = width;
19696 if (height != null) this.height = height;
19697
19698 if (!this._boxCoords) this._transform();
19699 this._redraw(this._prefix, this._suffix);
19700
19701 return this;
19702 },
19703
19704 // radial gradient workaround
19705
19706 _redraw: function(prefix, suffix){
19707 var vml = this._vml || '';
19708
19709 this._prefix = prefix;
19710 this._suffix = suffix;
19711 if (prefix){
19712 vml = [
19713 prefix, vml, suffix,
19714 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
19715 'ns e', vml, 'nf'
19716 ].join(' ');
19717 }
19718
19719 this.element.path = vml + 'e';
19720 },
19721
19722 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
19723 var fill = this._createGradient('gradientradial', stops);
19724 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
19725 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
19726 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
19727 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
19728 if (centerX == null) centerX = focusX;
19729 if (centerY == null) centerY = focusY;
19730
19731 centerX += centerX - focusX;
19732 centerY += centerY - focusY;
19733
19734 var cx = Math.round(centerX * precision$2),
19735 cy = Math.round(centerY * precision$2),
19736
19737 rx = Math.round(radiusX * 2 * precision$2),
19738 ry = Math.round(radiusY * 2 * precision$2),
19739
19740 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
19741
19742 this._redraw(
19743 // Resolve rendering bug
19744 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
19745 // Draw an ellipse around the path to force an elliptical gradient on any shape
19746 [
19747 'm', cx, cy - ry,
19748 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
19749 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
19750 ].join(' ')
19751 );
19752
19753 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
19754
19755 fill.focusposition = '0.5,0.5';
19756 fill.focussize = '0 0';
19757 fill.focus = '50%';
19758
19759 this._transform();
19760
19761 return this;
19762 }
19763
19764});
19765
19766var group$2 = _class(node$2, container, {
19767
19768 element_initialize: node$2.prototype.initialize,
19769
19770 initialize: function(width, height){
19771 this.element_initialize('group');
19772 this.width = width;
19773 this.height = height;
19774 },
19775
19776 _transform: function(){
19777 var element = this.element;
19778 element.coordorigin = '0,0';
19779 element.coordsize = '1000,1000';
19780 element.style.left = 0;
19781 element.style.top = 0;
19782 element.style.width = 1000;
19783 element.style.height = 1000;
19784 element.style.rotation = 0;
19785
19786 var container$$2 = this.parentNode;
19787 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
19788 var node = this.firstChild;
19789 while (node){
19790 node._transform();
19791 node = node.nextSibling;
19792 }
19793 }
19794
19795});
19796
19797var clippingrectangle$2 = _class(node$2, container, {
19798
19799 element_initialize: node$2.prototype.initialize,
19800
19801 initialize: function(width, height){
19802 this.element_initialize('clippingrectangle');
19803 this.width = width;
19804 this.height = height;
19805 },
19806
19807 _transform: function(){
19808 var element = this.element;
19809 element.clip = true;
19810 element.coordorigin = -this.x + ',' + (-1 * this.y);
19811 element.coordsize = this.width + ',' + this.height;
19812 // IE8 doesn't like clipBottom. Don't ask me why.
19813 // element.style.clipBottom = this.height + this.y;
19814 element.style.clipLeft = this.x;
19815 element.style.clipRight = this.width + this.x;
19816 element.style.clipTop = this.y;
19817 element.style.left = -this.x;
19818 element.style.top = -this.y;
19819 element.style.width = this.width + this.x;
19820 element.style.height = this.height + this.y;
19821 element.style.rotation = 0;
19822
19823 var container$$2 = this.parentNode;
19824 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
19825 var node = this.firstChild;
19826 while (node){
19827 node._transform();
19828 node = node.nextSibling;
19829 }
19830 }
19831
19832});
19833
19834var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
19835
19836var text$2 = _class(base$2, {
19837
19838 base_initialize: base$2.prototype.initialize,
19839
19840 initialize: function(text, font, alignment, path){
19841 this.base_initialize('shape');
19842
19843 var p = this.pathElement = dom.createElement('path');
19844 p.textpathok = true;
19845 this.element.appendChild(p);
19846
19847 p = this.textPathElement = dom.createElement("textpath");
19848 p.on = true;
19849 p.style['v-text-align'] = 'left';
19850 this.element.appendChild(p);
19851
19852 this.draw.apply(this, arguments);
19853 },
19854
19855 draw: function(text, font, alignment, path){
19856 var element = this.element,
19857 textPath = this.textPathElement,
19858 style = textPath.style;
19859
19860 textPath.string = text;
19861
19862 if (font){
19863 if (typeof font == 'string'){
19864 style.font = font;
19865 } else {
19866 for (var key in font){
19867 var ckey = key.camelCase ? key.camelCase() : key;
19868 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
19869 // NOT UNIVERSALLY SUPPORTED OPTIONS
19870 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
19871 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
19872 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
19873 else style[ckey] = font[key];
19874 }
19875 }
19876 }
19877
19878 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
19879
19880 if (path){
19881 this.currentPath = path = new path$4(path);
19882 this.element.path = path.toVML();
19883 } else if (!this.currentPath){
19884 var i = -1, offsetRows = '\n';
19885 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
19886 textPath.string = offsetRows + textPath.string;
19887 this.element.path = 'm0,0l1,0';
19888 }
19889
19890 // Measuring the bounding box is currently necessary for gradients etc.
19891
19892 // Clone element because the element is dead once it has been in the DOM
19893 element = element.cloneNode(true);
19894 style = element.style;
19895
19896 // Reset coordinates while measuring
19897 element.coordorigin = '0,0';
19898 element.coordsize = '10000,10000';
19899 style.left = '0px';
19900 style.top = '0px';
19901 style.width = '10000px';
19902 style.height = '10000px';
19903 style.rotation = 0;
19904 element.removeChild(element.firstChild); // Remove skew
19905
19906 // Inject the clone into the document
19907
19908 var canvas = new surface$2(1, 1),
19909 group = new group$2(), // Wrapping it in a group seems to alleviate some client rect weirdness
19910 body = element.ownerDocument.body;
19911
19912 canvas.inject(body);
19913 group.element.appendChild(element);
19914 group.inject(canvas);
19915
19916 var ebb = element.getBoundingClientRect(),
19917 cbb = canvas.toElement().getBoundingClientRect();
19918
19919 canvas.eject();
19920
19921 this.left = ebb.left - cbb.left;
19922 this.top = ebb.top - cbb.top;
19923 this.width = ebb.right - ebb.left;
19924 this.height = ebb.bottom - ebb.top;
19925 this.right = ebb.right - cbb.left;
19926 this.bottom = ebb.bottom - cbb.top;
19927
19928 this._transform();
19929
19930 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
19931 return this;
19932 }
19933
19934});
19935
19936var fastNoSideEffects = createCommonjsModule(function (module, exports) {
19937var hasCanvas = function(){
19938
19939 var canvas = document.createElement('canvas');
19940 return canvas && !!canvas.getContext;
19941
19942};
19943
19944if (hasCanvas()) {
19945 exports.Surface = surface;
19946 exports.Path = path;
19947 exports.Shape = shape;
19948 exports.Group = group;
19949 exports.ClippingRectangle = clippingrectangle;
19950 exports.Text = text;
19951} else {
19952 exports.Surface = surface$2;
19953 exports.Path = path$4;
19954 exports.Shape = shape$2;
19955 exports.Group = group$2;
19956 exports.ClippingRectangle = clippingrectangle$2;
19957 exports.Text = text$2;
19958
19959 var DOM$$1 = dom;
19960 if (typeof document !== 'undefined') DOM$$1.init(document);
19961}
19962});
19963
19964var fastNoSideEffects_1 = fastNoSideEffects.Surface;
19965var fastNoSideEffects_2 = fastNoSideEffects.Path;
19966var fastNoSideEffects_3 = fastNoSideEffects.Shape;
19967var fastNoSideEffects_4 = fastNoSideEffects.Group;
19968var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
19969var fastNoSideEffects_6 = fastNoSideEffects.Text;
19970
19971current.setCurrent( // Change to 'art/modes/dom' for easier debugging via SVG
19972fastNoSideEffects);
19973/** Declarative fill-type objects; API design not finalized */
19974
19975var slice = Array.prototype.slice;
19976
19977var LinearGradient =
19978/*#__PURE__*/
19979function () {
19980 function LinearGradient(stops, x1, y1, x2, y2) {
19981 this._args = slice.call(arguments);
19982 }
19983
19984 var _proto = LinearGradient.prototype;
19985
19986 _proto.applyFill = function applyFill(node) {
19987 node.fillLinear.apply(node, this._args);
19988 };
19989
19990 return LinearGradient;
19991}();
19992
19993var RadialGradient =
19994/*#__PURE__*/
19995function () {
19996 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
19997 this._args = slice.call(arguments);
19998 }
19999
20000 var _proto2 = RadialGradient.prototype;
20001
20002 _proto2.applyFill = function applyFill(node) {
20003 node.fillRadial.apply(node, this._args);
20004 };
20005
20006 return RadialGradient;
20007}();
20008
20009var Pattern =
20010/*#__PURE__*/
20011function () {
20012 function Pattern(url, width, height, left, top) {
20013 this._args = slice.call(arguments);
20014 }
20015
20016 var _proto3 = Pattern.prototype;
20017
20018 _proto3.applyFill = function applyFill(node) {
20019 node.fillImage.apply(node, this._args);
20020 };
20021
20022 return Pattern;
20023}();
20024/** React Components */
20025
20026
20027var Surface =
20028/*#__PURE__*/
20029function (_React$Component) {
20030 _inheritsLoose(Surface, _React$Component);
20031
20032 function Surface() {
20033 return _React$Component.apply(this, arguments) || this;
20034 }
20035
20036 var _proto4 = Surface.prototype;
20037
20038 _proto4.componentDidMount = function componentDidMount() {
20039 var _this$props = this.props,
20040 height = _this$props.height,
20041 width = _this$props.width;
20042 this._surface = current.Surface(+width, +height, this._tagRef);
20043 this._mountNode = createContainer(this._surface, LegacyRoot, false, null);
20044 updateContainer(this.props.children, this._mountNode, this);
20045 };
20046
20047 _proto4.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
20048 var props = this.props;
20049
20050 if (props.height !== prevProps.height || props.width !== prevProps.width) {
20051 this._surface.resize(+props.width, +props.height);
20052 }
20053
20054 updateContainer(this.props.children, this._mountNode, this);
20055
20056 if (this._surface.render) {
20057 this._surface.render();
20058 }
20059 };
20060
20061 _proto4.componentWillUnmount = function componentWillUnmount() {
20062 updateContainer(null, this._mountNode, this);
20063 };
20064
20065 _proto4.render = function render() {
20066 var _this = this;
20067
20068 // This is going to be a placeholder because we don't know what it will
20069 // actually resolve to because ART may render canvas, vml or svg tags here.
20070 // We only allow a subset of properties since others might conflict with
20071 // ART's properties.
20072 var props = this.props; // TODO: ART's Canvas Mode overrides surface title and cursor
20073
20074 var Tag = current.Surface.tagName;
20075 return React.createElement(Tag, {
20076 ref: function (ref) {
20077 return _this._tagRef = ref;
20078 },
20079 accessKey: props.accessKey,
20080 className: props.className,
20081 draggable: props.draggable,
20082 role: props.role,
20083 style: props.style,
20084 tabIndex: props.tabIndex,
20085 title: props.title
20086 });
20087 };
20088
20089 return Surface;
20090}(React.Component);
20091
20092var Text =
20093/*#__PURE__*/
20094function (_React$Component2) {
20095 _inheritsLoose(Text, _React$Component2);
20096
20097 function Text(props) {
20098 var _this2;
20099
20100 _this2 = _React$Component2.call(this, props) || this; // We allow reading these props. Ideally we could expose the Text node as
20101 // ref directly.
20102
20103 ['height', 'width', 'x', 'y'].forEach(function (key) {
20104 Object.defineProperty(_assertThisInitialized(_this2), key, {
20105 get: function () {
20106 return this._text ? this._text[key] : undefined;
20107 }
20108 });
20109 });
20110 return _this2;
20111 }
20112
20113 var _proto5 = Text.prototype;
20114
20115 _proto5.render = function render() {
20116 var _this3 = this;
20117
20118 // This means you can't have children that render into strings...
20119 var T = TYPES.TEXT;
20120 return React.createElement(T, _extends({}, this.props, {
20121 ref: function (t) {
20122 return _this3._text = t;
20123 }
20124 }), childrenAsString(this.props.children));
20125 };
20126
20127 return Text;
20128}(React.Component);
20129
20130injectIntoDevTools({
20131 findFiberByHostInstance: function () {
20132 return null;
20133 },
20134 bundleType: 1,
20135 version: ReactVersion,
20136 rendererPackageName: 'react-art'
20137});
20138/** API */
20139
20140var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
20141var Group = TYPES.GROUP;
20142var Shape = TYPES.SHAPE;
20143var Path = current.Path;
20144
20145
20146var ReactART = Object.freeze({
20147 ClippingRectangle: ClippingRectangle,
20148 Group: Group,
20149 Shape: Shape,
20150 Path: Path,
20151 LinearGradient: LinearGradient,
20152 Pattern: Pattern,
20153 RadialGradient: RadialGradient,
20154 Surface: Surface,
20155 Text: Text,
20156 Transform: transform
20157});
20158
20159var reactArt = ReactART;
20160
20161return reactArt;
20162
20163})));