UNPKG

537 kBJavaScriptView Raw
1/** @license React v16.13.0
2 * react-test-renderer.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
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18var _assign = require('object-assign');
19var Scheduler = require('scheduler/unstable_mock');
20var React = require('react');
21var checkPropTypes = require('prop-types/checkPropTypes');
22var Scheduler$1 = require('scheduler');
23var tracing = require('scheduler/tracing');
24
25function _defineProperties(target, props) {
26 for (var i = 0; i < props.length; i++) {
27 var descriptor = props[i];
28 descriptor.enumerable = descriptor.enumerable || false;
29 descriptor.configurable = true;
30 if ("value" in descriptor) descriptor.writable = true;
31 Object.defineProperty(target, descriptor.key, descriptor);
32 }
33}
34
35function _createClass(Constructor, protoProps, staticProps) {
36 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
37 if (staticProps) _defineProperties(Constructor, staticProps);
38 return Constructor;
39}
40
41function _objectWithoutPropertiesLoose(source, excluded) {
42 if (source == null) return {};
43 var target = {};
44 var sourceKeys = Object.keys(source);
45 var key, i;
46
47 for (i = 0; i < sourceKeys.length; i++) {
48 key = sourceKeys[i];
49 if (excluded.indexOf(key) >= 0) continue;
50 target[key] = source[key];
51 }
52
53 return target;
54}
55
56var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
57// Current owner and dispatcher used to share the same ref,
58// but PR #14548 split them out to better support the react-debug-tools package.
59
60if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
61 ReactSharedInternals.ReactCurrentDispatcher = {
62 current: null
63 };
64}
65
66if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
67 ReactSharedInternals.ReactCurrentBatchConfig = {
68 suspense: null
69 };
70}
71
72// by calls to these methods by a Babel plugin.
73//
74// In PROD (or in packages without access to React internals),
75// they are left as they are instead.
76
77function warn(format) {
78 {
79 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
80 args[_key - 1] = arguments[_key];
81 }
82
83 printWarning('warn', format, args);
84 }
85}
86function error(format) {
87 {
88 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
89 args[_key2 - 1] = arguments[_key2];
90 }
91
92 printWarning('error', format, args);
93 }
94}
95
96function printWarning(level, format, args) {
97 // When changing this logic, you might want to also
98 // update consoleWithStackDev.www.js as well.
99 {
100 var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
101
102 if (!hasExistingStack) {
103 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
104 var stack = ReactDebugCurrentFrame.getStackAddendum();
105
106 if (stack !== '') {
107 format += '%s';
108 args = args.concat([stack]);
109 }
110 }
111
112 var argsWithFormat = args.map(function (item) {
113 return '' + item;
114 }); // Careful: RN currently depends on this prefix
115
116 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
117 // breaks IE9: https://github.com/facebook/react/issues/13610
118 // eslint-disable-next-line react-internal/no-production-logging
119
120 Function.prototype.apply.call(console[level], console, argsWithFormat);
121
122 try {
123 // --- Welcome to debugging React ---
124 // This error was thrown as a convenience so that you can use this stack
125 // to find the callsite that caused this warning to fire.
126 var argIndex = 0;
127 var message = 'Warning: ' + format.replace(/%s/g, function () {
128 return args[argIndex++];
129 });
130 throw new Error(message);
131 } catch (x) {}
132 }
133}
134
135var FunctionComponent = 0;
136var ClassComponent = 1;
137var IndeterminateComponent = 2; // Before we know whether it is function or class
138
139var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
140
141var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
142
143var HostComponent = 5;
144var HostText = 6;
145var Fragment = 7;
146var Mode = 8;
147var ContextConsumer = 9;
148var ContextProvider = 10;
149var ForwardRef = 11;
150var Profiler = 12;
151var SuspenseComponent = 13;
152var MemoComponent = 14;
153var SimpleMemoComponent = 15;
154var LazyComponent = 16;
155var IncompleteClassComponent = 17;
156var DehydratedFragment = 18;
157var SuspenseListComponent = 19;
158var FundamentalComponent = 20;
159var ScopeComponent = 21;
160var Block = 22;
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 */
171function get(key) {
172 return key._reactInternalFiber;
173}
174function set(key, value) {
175 key._reactInternalFiber = value;
176}
177
178// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
179// nor polyfill, then a plain number is used for performance.
180var hasSymbol = typeof Symbol === 'function' && Symbol.for;
181var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
182var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
183var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
184var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
185var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
186var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
187var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
188var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
189var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
190var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
191var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
192var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
193var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
194var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
195var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
196var FAUX_ITERATOR_SYMBOL = '@@iterator';
197function getIteratorFn(maybeIterable) {
198 if (maybeIterable === null || typeof maybeIterable !== 'object') {
199 return null;
200 }
201
202 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
203
204 if (typeof maybeIterator === 'function') {
205 return maybeIterator;
206 }
207
208 return null;
209}
210
211var Uninitialized = -1;
212var Pending = 0;
213var Resolved = 1;
214var Rejected = 2;
215function refineResolvedLazyComponent(lazyComponent) {
216 return lazyComponent._status === Resolved ? lazyComponent._result : null;
217}
218function initializeLazyComponentType(lazyComponent) {
219 if (lazyComponent._status === Uninitialized) {
220 lazyComponent._status = Pending;
221 var ctor = lazyComponent._ctor;
222 var thenable = ctor();
223 lazyComponent._result = thenable;
224 thenable.then(function (moduleObject) {
225 if (lazyComponent._status === Pending) {
226 var defaultExport = moduleObject.default;
227
228 {
229 if (defaultExport === undefined) {
230 error('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);
231 }
232 }
233
234 lazyComponent._status = Resolved;
235 lazyComponent._result = defaultExport;
236 }
237 }, function (error) {
238 if (lazyComponent._status === Pending) {
239 lazyComponent._status = Rejected;
240 lazyComponent._result = error;
241 }
242 });
243 }
244}
245
246function getWrappedName(outerType, innerType, wrapperName) {
247 var functionName = innerType.displayName || innerType.name || '';
248 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
249}
250
251function getComponentName(type) {
252 if (type == null) {
253 // Host root, text node or just invalid type.
254 return null;
255 }
256
257 {
258 if (typeof type.tag === 'number') {
259 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
260 }
261 }
262
263 if (typeof type === 'function') {
264 return type.displayName || type.name || null;
265 }
266
267 if (typeof type === 'string') {
268 return type;
269 }
270
271 switch (type) {
272 case REACT_FRAGMENT_TYPE:
273 return 'Fragment';
274
275 case REACT_PORTAL_TYPE:
276 return 'Portal';
277
278 case REACT_PROFILER_TYPE:
279 return "Profiler";
280
281 case REACT_STRICT_MODE_TYPE:
282 return 'StrictMode';
283
284 case REACT_SUSPENSE_TYPE:
285 return 'Suspense';
286
287 case REACT_SUSPENSE_LIST_TYPE:
288 return 'SuspenseList';
289 }
290
291 if (typeof type === 'object') {
292 switch (type.$$typeof) {
293 case REACT_CONTEXT_TYPE:
294 return 'Context.Consumer';
295
296 case REACT_PROVIDER_TYPE:
297 return 'Context.Provider';
298
299 case REACT_FORWARD_REF_TYPE:
300 return getWrappedName(type, type.render, 'ForwardRef');
301
302 case REACT_MEMO_TYPE:
303 return getComponentName(type.type);
304
305 case REACT_BLOCK_TYPE:
306 return getComponentName(type.render);
307
308 case REACT_LAZY_TYPE:
309 {
310 var thenable = type;
311 var resolvedThenable = refineResolvedLazyComponent(thenable);
312
313 if (resolvedThenable) {
314 return getComponentName(resolvedThenable);
315 }
316
317 break;
318 }
319 }
320 }
321
322 return null;
323}
324
325// Don't change these two values. They're used by React Dev Tools.
326var NoEffect =
327/* */
3280;
329var PerformedWork =
330/* */
3311; // You can change the rest (and add more).
332
333var Placement =
334/* */
3352;
336var Update =
337/* */
3384;
339var PlacementAndUpdate =
340/* */
3416;
342var Deletion =
343/* */
3448;
345var ContentReset =
346/* */
34716;
348var Callback =
349/* */
35032;
351var DidCapture =
352/* */
35364;
354var Ref =
355/* */
356128;
357var Snapshot =
358/* */
359256;
360var Passive =
361/* */
362512;
363var Hydrating =
364/* */
3651024;
366var HydratingAndUpdate =
367/* */
3681028; // Passive & Update & Callback & Ref & Snapshot
369
370var LifecycleEffectMask =
371/* */
372932; // Union of all host effects
373
374var HostEffectMask =
375/* */
3762047;
377var Incomplete =
378/* */
3792048;
380var ShouldCapture =
381/* */
3824096;
383
384var enableProfilerTimer = true;
385var enableFundamentalAPI = false;
386var warnAboutStringRefs = false;
387
388var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
389function getNearestMountedFiber(fiber) {
390 var node = fiber;
391 var nearestMounted = fiber;
392
393 if (!fiber.alternate) {
394 // If there is no alternate, this might be a new tree that isn't inserted
395 // yet. If it is, then it will have a pending insertion effect on it.
396 var nextNode = node;
397
398 do {
399 node = nextNode;
400
401 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
402 // This is an insertion or in-progress hydration. The nearest possible
403 // mounted fiber is the parent but we need to continue to figure out
404 // if that one is still mounted.
405 nearestMounted = node.return;
406 }
407
408 nextNode = node.return;
409 } while (nextNode);
410 } else {
411 while (node.return) {
412 node = node.return;
413 }
414 }
415
416 if (node.tag === HostRoot) {
417 // TODO: Check if this was a nested HostRoot when used with
418 // renderContainerIntoSubtree.
419 return nearestMounted;
420 } // If we didn't hit the root, that means that we're in an disconnected tree
421 // that has been unmounted.
422
423
424 return null;
425}
426function isFiberMounted(fiber) {
427 return getNearestMountedFiber(fiber) === fiber;
428}
429function isMounted(component) {
430 {
431 var owner = ReactCurrentOwner.current;
432
433 if (owner !== null && owner.tag === ClassComponent) {
434 var ownerFiber = owner;
435 var instance = ownerFiber.stateNode;
436
437 if (!instance._warnedAboutRefsInRender) {
438 error('%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');
439 }
440
441 instance._warnedAboutRefsInRender = true;
442 }
443 }
444
445 var fiber = get(component);
446
447 if (!fiber) {
448 return false;
449 }
450
451 return getNearestMountedFiber(fiber) === fiber;
452}
453
454function assertIsMounted(fiber) {
455 if (!(getNearestMountedFiber(fiber) === fiber)) {
456 {
457 throw Error( "Unable to find node on an unmounted component." );
458 }
459 }
460}
461
462function findCurrentFiberUsingSlowPath(fiber) {
463 var alternate = fiber.alternate;
464
465 if (!alternate) {
466 // If there is no alternate, then we only need to check if it is mounted.
467 var nearestMounted = getNearestMountedFiber(fiber);
468
469 if (!(nearestMounted !== null)) {
470 {
471 throw Error( "Unable to find node on an unmounted component." );
472 }
473 }
474
475 if (nearestMounted !== fiber) {
476 return null;
477 }
478
479 return fiber;
480 } // If we have two possible branches, we'll walk backwards up to the root
481 // to see what path the root points to. On the way we may hit one of the
482 // special cases and we'll deal with them.
483
484
485 var a = fiber;
486 var b = alternate;
487
488 while (true) {
489 var parentA = a.return;
490
491 if (parentA === null) {
492 // We're at the root.
493 break;
494 }
495
496 var parentB = parentA.alternate;
497
498 if (parentB === null) {
499 // There is no alternate. This is an unusual case. Currently, it only
500 // happens when a Suspense component is hidden. An extra fragment fiber
501 // is inserted in between the Suspense fiber and its children. Skip
502 // over this extra fragment fiber and proceed to the next parent.
503 var nextParent = parentA.return;
504
505 if (nextParent !== null) {
506 a = b = nextParent;
507 continue;
508 } // If there's no parent, we're at the root.
509
510
511 break;
512 } // If both copies of the parent fiber point to the same child, we can
513 // assume that the child is current. This happens when we bailout on low
514 // priority: the bailed out fiber's child reuses the current child.
515
516
517 if (parentA.child === parentB.child) {
518 var child = parentA.child;
519
520 while (child) {
521 if (child === a) {
522 // We've determined that A is the current branch.
523 assertIsMounted(parentA);
524 return fiber;
525 }
526
527 if (child === b) {
528 // We've determined that B is the current branch.
529 assertIsMounted(parentA);
530 return alternate;
531 }
532
533 child = child.sibling;
534 } // We should never have an alternate for any mounting node. So the only
535 // way this could possibly happen is if this was unmounted, if at all.
536
537
538 {
539 {
540 throw Error( "Unable to find node on an unmounted component." );
541 }
542 }
543 }
544
545 if (a.return !== b.return) {
546 // The return pointer of A and the return pointer of B point to different
547 // fibers. We assume that return pointers never criss-cross, so A must
548 // belong to the child set of A.return, and B must belong to the child
549 // set of B.return.
550 a = parentA;
551 b = parentB;
552 } else {
553 // The return pointers point to the same fiber. We'll have to use the
554 // default, slow path: scan the child sets of each parent alternate to see
555 // which child belongs to which set.
556 //
557 // Search parent A's child set
558 var didFindChild = false;
559 var _child = parentA.child;
560
561 while (_child) {
562 if (_child === a) {
563 didFindChild = true;
564 a = parentA;
565 b = parentB;
566 break;
567 }
568
569 if (_child === b) {
570 didFindChild = true;
571 b = parentA;
572 a = parentB;
573 break;
574 }
575
576 _child = _child.sibling;
577 }
578
579 if (!didFindChild) {
580 // Search parent B's child set
581 _child = parentB.child;
582
583 while (_child) {
584 if (_child === a) {
585 didFindChild = true;
586 a = parentB;
587 b = parentA;
588 break;
589 }
590
591 if (_child === b) {
592 didFindChild = true;
593 b = parentB;
594 a = parentA;
595 break;
596 }
597
598 _child = _child.sibling;
599 }
600
601 if (!didFindChild) {
602 {
603 throw Error( "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." );
604 }
605 }
606 }
607 }
608
609 if (!(a.alternate === b)) {
610 {
611 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
612 }
613 }
614 } // If the root is not a host container, we're in a disconnected tree. I.e.
615 // unmounted.
616
617
618 if (!(a.tag === HostRoot)) {
619 {
620 throw Error( "Unable to find node on an unmounted component." );
621 }
622 }
623
624 if (a.stateNode.current === a) {
625 // We've determined that A is the current branch.
626 return fiber;
627 } // Otherwise B has to be current branch.
628
629
630 return alternate;
631}
632function findCurrentHostFiber(parent) {
633 var currentParent = findCurrentFiberUsingSlowPath(parent);
634
635 if (!currentParent) {
636 return null;
637 } // Next we'll drill down this component to find the first HostComponent/Text.
638
639
640 var node = currentParent;
641
642 while (true) {
643 if (node.tag === HostComponent || node.tag === HostText) {
644 return node;
645 } else if (node.child) {
646 node.child.return = node;
647 node = node.child;
648 continue;
649 }
650
651 if (node === currentParent) {
652 return null;
653 }
654
655 while (!node.sibling) {
656 if (!node.return || node.return === currentParent) {
657 return null;
658 }
659
660 node = node.return;
661 }
662
663 node.sibling.return = node.return;
664 node = node.sibling;
665 } // Flow needs the return null here, but ESLint complains about it.
666 // eslint-disable-next-line no-unreachable
667
668
669 return null;
670}
671
672// can re-export everything from this module.
673
674function shim() {
675 {
676 {
677 throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." );
678 }
679 }
680} // Hydration (when unsupported)
681var isSuspenseInstancePending = shim;
682var isSuspenseInstanceFallback = shim;
683var hydrateTextInstance = shim;
684
685var NO_CONTEXT = {};
686var UPDATE_SIGNAL = {};
687var nodeToInstanceMap = new WeakMap();
688
689{
690 Object.freeze(NO_CONTEXT);
691 Object.freeze(UPDATE_SIGNAL);
692}
693
694function getPublicInstance(inst) {
695 switch (inst.tag) {
696 case 'INSTANCE':
697 var createNodeMock = inst.rootContainerInstance.createNodeMock;
698 var mockNode = createNodeMock({
699 type: inst.type,
700 props: inst.props
701 });
702
703 if (typeof mockNode === 'object' && mockNode !== null) {
704 nodeToInstanceMap.set(mockNode, inst);
705 }
706
707 return mockNode;
708
709 default:
710 return inst;
711 }
712}
713function appendChild(parentInstance, child) {
714 {
715 if (!Array.isArray(parentInstance.children)) {
716 error('An invalid container has been provided. ' + 'This may indicate that another renderer is being used in addition to the test renderer. ' + '(For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) ' + 'This is not supported.');
717 }
718 }
719
720 var index = parentInstance.children.indexOf(child);
721
722 if (index !== -1) {
723 parentInstance.children.splice(index, 1);
724 }
725
726 parentInstance.children.push(child);
727}
728function insertBefore(parentInstance, child, beforeChild) {
729 var index = parentInstance.children.indexOf(child);
730
731 if (index !== -1) {
732 parentInstance.children.splice(index, 1);
733 }
734
735 var beforeIndex = parentInstance.children.indexOf(beforeChild);
736 parentInstance.children.splice(beforeIndex, 0, child);
737}
738function removeChild(parentInstance, child) {
739 var index = parentInstance.children.indexOf(child);
740 parentInstance.children.splice(index, 1);
741}
742function getRootHostContext(rootContainerInstance) {
743 return NO_CONTEXT;
744}
745function getChildHostContext(parentHostContext, type, rootContainerInstance) {
746 return NO_CONTEXT;
747}
748function prepareForCommit(containerInfo) {// noop
749}
750function resetAfterCommit(containerInfo) {// noop
751}
752function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
753 var propsToUse = props;
754
755 return {
756 type: type,
757 props: propsToUse,
758 isHidden: false,
759 children: [],
760 internalInstanceHandle: internalInstanceHandle,
761 rootContainerInstance: rootContainerInstance,
762 tag: 'INSTANCE'
763 };
764}
765function appendInitialChild(parentInstance, child) {
766 var index = parentInstance.children.indexOf(child);
767
768 if (index !== -1) {
769 parentInstance.children.splice(index, 1);
770 }
771
772 parentInstance.children.push(child);
773}
774function prepareUpdate(testElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
775 return UPDATE_SIGNAL;
776}
777function shouldSetTextContent(type, props) {
778 return false;
779}
780function shouldDeprioritizeSubtree(type, props) {
781 return false;
782}
783function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
784
785 return {
786 text: text,
787 isHidden: false,
788 tag: 'TEXT'
789 };
790}
791var scheduleTimeout = setTimeout;
792var cancelTimeout = clearTimeout;
793var noTimeout = -1; // -------------------
794function commitUpdate(instance, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
795 instance.type = type;
796 instance.props = newProps;
797}
798function commitTextUpdate(textInstance, oldText, newText) {
799 textInstance.text = newText;
800}
801function resetTextContent(testElement) {// noop
802}
803var appendChildToContainer = appendChild;
804var insertInContainerBefore = insertBefore;
805var removeChildFromContainer = removeChild;
806function hideInstance(instance) {
807 instance.isHidden = true;
808}
809function hideTextInstance(textInstance) {
810 textInstance.isHidden = true;
811}
812function unhideInstance(instance, props) {
813 instance.isHidden = false;
814}
815function unhideTextInstance(textInstance, text) {
816 textInstance.isHidden = false;
817}
818
819var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
820function describeComponentFrame (name, source, ownerName) {
821 var sourceInfo = '';
822
823 if (source) {
824 var path = source.fileName;
825 var fileName = path.replace(BEFORE_SLASH_RE, '');
826
827 {
828 // In DEV, include code for a common special case:
829 // prefer "folder/index.js" instead of just "index.js".
830 if (/^index\./.test(fileName)) {
831 var match = path.match(BEFORE_SLASH_RE);
832
833 if (match) {
834 var pathBeforeSlash = match[1];
835
836 if (pathBeforeSlash) {
837 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
838 fileName = folderName + '/' + fileName;
839 }
840 }
841 }
842 }
843
844 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
845 } else if (ownerName) {
846 sourceInfo = ' (created by ' + ownerName + ')';
847 }
848
849 return '\n in ' + (name || 'Unknown') + sourceInfo;
850}
851
852var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
853
854function describeFiber(fiber) {
855 switch (fiber.tag) {
856 case HostRoot:
857 case HostPortal:
858 case HostText:
859 case Fragment:
860 case ContextProvider:
861 case ContextConsumer:
862 return '';
863
864 default:
865 var owner = fiber._debugOwner;
866 var source = fiber._debugSource;
867 var name = getComponentName(fiber.type);
868 var ownerName = null;
869
870 if (owner) {
871 ownerName = getComponentName(owner.type);
872 }
873
874 return describeComponentFrame(name, source, ownerName);
875 }
876}
877
878function getStackByFiberInDevAndProd(workInProgress) {
879 var info = '';
880 var node = workInProgress;
881
882 do {
883 info += describeFiber(node);
884 node = node.return;
885 } while (node);
886
887 return info;
888}
889var current = null;
890var phase = null;
891function getCurrentFiberOwnerNameInDevOrNull() {
892 {
893 if (current === null) {
894 return null;
895 }
896
897 var owner = current._debugOwner;
898
899 if (owner !== null && typeof owner !== 'undefined') {
900 return getComponentName(owner.type);
901 }
902 }
903
904 return null;
905}
906function getCurrentFiberStackInDev() {
907 {
908 if (current === null) {
909 return '';
910 } // Safe because if current fiber exists, we are reconciling,
911 // and it is guaranteed to be the work-in-progress version.
912
913
914 return getStackByFiberInDevAndProd(current);
915 }
916}
917function resetCurrentFiber() {
918 {
919 ReactDebugCurrentFrame.getCurrentStack = null;
920 current = null;
921 phase = null;
922 }
923}
924function setCurrentFiber(fiber) {
925 {
926 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
927 current = fiber;
928 phase = null;
929 }
930}
931function setCurrentPhase(lifeCyclePhase) {
932 {
933 phase = lifeCyclePhase;
934 }
935}
936
937// Prefix measurements so that it's possible to filter them.
938// Longer prefixes are hard to read in DevTools.
939var reactEmoji = "\u269B";
940var warningEmoji = "\u26D4";
941var 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.
942// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
943
944var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
945// Reusing `currentFiber` would be confusing for this because user code fiber
946// can change during commit phase too, but we don't need to unwind it (since
947// lifecycles in the commit phase don't resemble a tree).
948
949var currentPhase = null;
950var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
951// so we will keep track of it, and include it in the report.
952// Track commits caused by cascading updates.
953
954var isCommitting = false;
955var hasScheduledUpdateInCurrentCommit = false;
956var hasScheduledUpdateInCurrentPhase = false;
957var commitCountInCurrentWorkLoop = 0;
958var effectCountInCurrentCommit = 0;
959// to avoid stretch the commit phase with measurement overhead.
960
961var labelsInCurrentCommit = new Set();
962
963var formatMarkName = function (markName) {
964 return reactEmoji + " " + markName;
965};
966
967var formatLabel = function (label, warning) {
968 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
969 var suffix = warning ? " Warning: " + warning : '';
970 return "" + prefix + label + suffix;
971};
972
973var beginMark = function (markName) {
974 performance.mark(formatMarkName(markName));
975};
976
977var clearMark = function (markName) {
978 performance.clearMarks(formatMarkName(markName));
979};
980
981var endMark = function (label, markName, warning) {
982 var formattedMarkName = formatMarkName(markName);
983 var formattedLabel = formatLabel(label, warning);
984
985 try {
986 performance.measure(formattedLabel, formattedMarkName);
987 } catch (err) {} // If previous mark was missing for some reason, this will throw.
988 // This could only happen if React crashed in an unexpected place earlier.
989 // Don't pile on with more errors.
990 // Clear marks immediately to avoid growing buffer.
991
992
993 performance.clearMarks(formattedMarkName);
994 performance.clearMeasures(formattedLabel);
995};
996
997var getFiberMarkName = function (label, debugID) {
998 return label + " (#" + debugID + ")";
999};
1000
1001var getFiberLabel = function (componentName, isMounted, phase) {
1002 if (phase === null) {
1003 // These are composite component total time measurements.
1004 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
1005 } else {
1006 // Composite component methods.
1007 return componentName + "." + phase;
1008 }
1009};
1010
1011var beginFiberMark = function (fiber, phase) {
1012 var componentName = getComponentName(fiber.type) || 'Unknown';
1013 var debugID = fiber._debugID;
1014 var isMounted = fiber.alternate !== null;
1015 var label = getFiberLabel(componentName, isMounted, phase);
1016
1017 if (isCommitting && labelsInCurrentCommit.has(label)) {
1018 // During the commit phase, we don't show duplicate labels because
1019 // there is a fixed overhead for every measurement, and we don't
1020 // want to stretch the commit phase beyond necessary.
1021 return false;
1022 }
1023
1024 labelsInCurrentCommit.add(label);
1025 var markName = getFiberMarkName(label, debugID);
1026 beginMark(markName);
1027 return true;
1028};
1029
1030var clearFiberMark = function (fiber, phase) {
1031 var componentName = getComponentName(fiber.type) || 'Unknown';
1032 var debugID = fiber._debugID;
1033 var isMounted = fiber.alternate !== null;
1034 var label = getFiberLabel(componentName, isMounted, phase);
1035 var markName = getFiberMarkName(label, debugID);
1036 clearMark(markName);
1037};
1038
1039var endFiberMark = function (fiber, phase, warning) {
1040 var componentName = getComponentName(fiber.type) || 'Unknown';
1041 var debugID = fiber._debugID;
1042 var isMounted = fiber.alternate !== null;
1043 var label = getFiberLabel(componentName, isMounted, phase);
1044 var markName = getFiberMarkName(label, debugID);
1045 endMark(label, markName, warning);
1046};
1047
1048var shouldIgnoreFiber = function (fiber) {
1049 // Host components should be skipped in the timeline.
1050 // We could check typeof fiber.type, but does this work with RN?
1051 switch (fiber.tag) {
1052 case HostRoot:
1053 case HostComponent:
1054 case HostText:
1055 case HostPortal:
1056 case Fragment:
1057 case ContextProvider:
1058 case ContextConsumer:
1059 case Mode:
1060 return true;
1061
1062 default:
1063 return false;
1064 }
1065};
1066
1067var clearPendingPhaseMeasurement = function () {
1068 if (currentPhase !== null && currentPhaseFiber !== null) {
1069 clearFiberMark(currentPhaseFiber, currentPhase);
1070 }
1071
1072 currentPhaseFiber = null;
1073 currentPhase = null;
1074 hasScheduledUpdateInCurrentPhase = false;
1075};
1076
1077var pauseTimers = function () {
1078 // Stops all currently active measurements so that they can be resumed
1079 // if we continue in a later deferred loop from the same unit of work.
1080 var fiber = currentFiber;
1081
1082 while (fiber) {
1083 if (fiber._debugIsCurrentlyTiming) {
1084 endFiberMark(fiber, null, null);
1085 }
1086
1087 fiber = fiber.return;
1088 }
1089};
1090
1091var resumeTimersRecursively = function (fiber) {
1092 if (fiber.return !== null) {
1093 resumeTimersRecursively(fiber.return);
1094 }
1095
1096 if (fiber._debugIsCurrentlyTiming) {
1097 beginFiberMark(fiber, null);
1098 }
1099};
1100
1101var resumeTimers = function () {
1102 // Resumes all measurements that were active during the last deferred loop.
1103 if (currentFiber !== null) {
1104 resumeTimersRecursively(currentFiber);
1105 }
1106};
1107
1108function recordEffect() {
1109 {
1110 effectCountInCurrentCommit++;
1111 }
1112}
1113function recordScheduleUpdate() {
1114 {
1115 if (isCommitting) {
1116 hasScheduledUpdateInCurrentCommit = true;
1117 }
1118
1119 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1120 hasScheduledUpdateInCurrentPhase = true;
1121 }
1122 }
1123}
1124function startWorkTimer(fiber) {
1125 {
1126 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1127 return;
1128 } // If we pause, this is the fiber to unwind from.
1129
1130
1131 currentFiber = fiber;
1132
1133 if (!beginFiberMark(fiber, null)) {
1134 return;
1135 }
1136
1137 fiber._debugIsCurrentlyTiming = true;
1138 }
1139}
1140function cancelWorkTimer(fiber) {
1141 {
1142 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1143 return;
1144 } // Remember we shouldn't complete measurement for this fiber.
1145 // Otherwise flamechart will be deep even for small updates.
1146
1147
1148 fiber._debugIsCurrentlyTiming = false;
1149 clearFiberMark(fiber, null);
1150 }
1151}
1152function stopWorkTimer(fiber) {
1153 {
1154 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1155 return;
1156 } // If we pause, its parent is the fiber to unwind from.
1157
1158
1159 currentFiber = fiber.return;
1160
1161 if (!fiber._debugIsCurrentlyTiming) {
1162 return;
1163 }
1164
1165 fiber._debugIsCurrentlyTiming = false;
1166 endFiberMark(fiber, null, null);
1167 }
1168}
1169function stopFailedWorkTimer(fiber) {
1170 {
1171 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1172 return;
1173 } // If we pause, its parent is the fiber to unwind from.
1174
1175
1176 currentFiber = fiber.return;
1177
1178 if (!fiber._debugIsCurrentlyTiming) {
1179 return;
1180 }
1181
1182 fiber._debugIsCurrentlyTiming = false;
1183 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1184 endFiberMark(fiber, null, warning);
1185 }
1186}
1187function startPhaseTimer(fiber, phase) {
1188 {
1189 if (!supportsUserTiming) {
1190 return;
1191 }
1192
1193 clearPendingPhaseMeasurement();
1194
1195 if (!beginFiberMark(fiber, phase)) {
1196 return;
1197 }
1198
1199 currentPhaseFiber = fiber;
1200 currentPhase = phase;
1201 }
1202}
1203function stopPhaseTimer() {
1204 {
1205 if (!supportsUserTiming) {
1206 return;
1207 }
1208
1209 if (currentPhase !== null && currentPhaseFiber !== null) {
1210 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1211 endFiberMark(currentPhaseFiber, currentPhase, warning);
1212 }
1213
1214 currentPhase = null;
1215 currentPhaseFiber = null;
1216 }
1217}
1218function startWorkLoopTimer(nextUnitOfWork) {
1219 {
1220 currentFiber = nextUnitOfWork;
1221
1222 if (!supportsUserTiming) {
1223 return;
1224 }
1225
1226 commitCountInCurrentWorkLoop = 0; // This is top level call.
1227 // Any other measurements are performed within.
1228
1229 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
1230
1231 resumeTimers();
1232 }
1233}
1234function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1235 {
1236 if (!supportsUserTiming) {
1237 return;
1238 }
1239
1240 var warning = null;
1241
1242 if (interruptedBy !== null) {
1243 if (interruptedBy.tag === HostRoot) {
1244 warning = 'A top-level update interrupted the previous render';
1245 } else {
1246 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1247 warning = "An update to " + componentName + " interrupted the previous render";
1248 }
1249 } else if (commitCountInCurrentWorkLoop > 1) {
1250 warning = 'There were cascading updates';
1251 }
1252
1253 commitCountInCurrentWorkLoop = 0;
1254 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
1255
1256 pauseTimers();
1257 endMark(label, '(React Tree Reconciliation)', warning);
1258 }
1259}
1260function startCommitTimer() {
1261 {
1262 if (!supportsUserTiming) {
1263 return;
1264 }
1265
1266 isCommitting = true;
1267 hasScheduledUpdateInCurrentCommit = false;
1268 labelsInCurrentCommit.clear();
1269 beginMark('(Committing Changes)');
1270 }
1271}
1272function stopCommitTimer() {
1273 {
1274 if (!supportsUserTiming) {
1275 return;
1276 }
1277
1278 var warning = null;
1279
1280 if (hasScheduledUpdateInCurrentCommit) {
1281 warning = 'Lifecycle hook scheduled a cascading update';
1282 } else if (commitCountInCurrentWorkLoop > 0) {
1283 warning = 'Caused by a cascading update in earlier commit';
1284 }
1285
1286 hasScheduledUpdateInCurrentCommit = false;
1287 commitCountInCurrentWorkLoop++;
1288 isCommitting = false;
1289 labelsInCurrentCommit.clear();
1290 endMark('(Committing Changes)', '(Committing Changes)', warning);
1291 }
1292}
1293function startCommitSnapshotEffectsTimer() {
1294 {
1295 if (!supportsUserTiming) {
1296 return;
1297 }
1298
1299 effectCountInCurrentCommit = 0;
1300 beginMark('(Committing Snapshot Effects)');
1301 }
1302}
1303function stopCommitSnapshotEffectsTimer() {
1304 {
1305 if (!supportsUserTiming) {
1306 return;
1307 }
1308
1309 var count = effectCountInCurrentCommit;
1310 effectCountInCurrentCommit = 0;
1311 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
1312 }
1313}
1314function startCommitHostEffectsTimer() {
1315 {
1316 if (!supportsUserTiming) {
1317 return;
1318 }
1319
1320 effectCountInCurrentCommit = 0;
1321 beginMark('(Committing Host Effects)');
1322 }
1323}
1324function stopCommitHostEffectsTimer() {
1325 {
1326 if (!supportsUserTiming) {
1327 return;
1328 }
1329
1330 var count = effectCountInCurrentCommit;
1331 effectCountInCurrentCommit = 0;
1332 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
1333 }
1334}
1335function startCommitLifeCyclesTimer() {
1336 {
1337 if (!supportsUserTiming) {
1338 return;
1339 }
1340
1341 effectCountInCurrentCommit = 0;
1342 beginMark('(Calling Lifecycle Methods)');
1343 }
1344}
1345function stopCommitLifeCyclesTimer() {
1346 {
1347 if (!supportsUserTiming) {
1348 return;
1349 }
1350
1351 var count = effectCountInCurrentCommit;
1352 effectCountInCurrentCommit = 0;
1353 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
1354 }
1355}
1356
1357var valueStack = [];
1358var fiberStack;
1359
1360{
1361 fiberStack = [];
1362}
1363
1364var index = -1;
1365
1366function createCursor(defaultValue) {
1367 return {
1368 current: defaultValue
1369 };
1370}
1371
1372function pop(cursor, fiber) {
1373 if (index < 0) {
1374 {
1375 error('Unexpected pop.');
1376 }
1377
1378 return;
1379 }
1380
1381 {
1382 if (fiber !== fiberStack[index]) {
1383 error('Unexpected Fiber popped.');
1384 }
1385 }
1386
1387 cursor.current = valueStack[index];
1388 valueStack[index] = null;
1389
1390 {
1391 fiberStack[index] = null;
1392 }
1393
1394 index--;
1395}
1396
1397function push(cursor, value, fiber) {
1398 index++;
1399 valueStack[index] = cursor.current;
1400
1401 {
1402 fiberStack[index] = fiber;
1403 }
1404
1405 cursor.current = value;
1406}
1407
1408var warnedAboutMissingGetChildContext;
1409
1410{
1411 warnedAboutMissingGetChildContext = {};
1412}
1413
1414var emptyContextObject = {};
1415
1416{
1417 Object.freeze(emptyContextObject);
1418} // A cursor to the current merged context object on the stack.
1419
1420
1421var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
1422
1423var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
1424// We use this to get access to the parent context after we have already
1425// pushed the next context provider, and now need to merge their contexts.
1426
1427var previousContext = emptyContextObject;
1428
1429function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1430 {
1431 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1432 // If the fiber is a context provider itself, when we read its context
1433 // we may have already pushed its own child context on the stack. A context
1434 // provider should not "see" its own child context. Therefore we read the
1435 // previous (parent) context instead for a context provider.
1436 return previousContext;
1437 }
1438
1439 return contextStackCursor.current;
1440 }
1441}
1442
1443function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1444 {
1445 var instance = workInProgress.stateNode;
1446 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1447 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1448 }
1449}
1450
1451function getMaskedContext(workInProgress, unmaskedContext) {
1452 {
1453 var type = workInProgress.type;
1454 var contextTypes = type.contextTypes;
1455
1456 if (!contextTypes) {
1457 return emptyContextObject;
1458 } // Avoid recreating masked context unless unmasked context has changed.
1459 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1460 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1461
1462
1463 var instance = workInProgress.stateNode;
1464
1465 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1466 return instance.__reactInternalMemoizedMaskedChildContext;
1467 }
1468
1469 var context = {};
1470
1471 for (var key in contextTypes) {
1472 context[key] = unmaskedContext[key];
1473 }
1474
1475 {
1476 var name = getComponentName(type) || 'Unknown';
1477 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1478 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
1479 // Context is created before the class component is instantiated so check for instance.
1480
1481
1482 if (instance) {
1483 cacheContext(workInProgress, unmaskedContext, context);
1484 }
1485
1486 return context;
1487 }
1488}
1489
1490function hasContextChanged() {
1491 {
1492 return didPerformWorkStackCursor.current;
1493 }
1494}
1495
1496function isContextProvider(type) {
1497 {
1498 var childContextTypes = type.childContextTypes;
1499 return childContextTypes !== null && childContextTypes !== undefined;
1500 }
1501}
1502
1503function popContext(fiber) {
1504 {
1505 pop(didPerformWorkStackCursor, fiber);
1506 pop(contextStackCursor, fiber);
1507 }
1508}
1509
1510function popTopLevelContextObject(fiber) {
1511 {
1512 pop(didPerformWorkStackCursor, fiber);
1513 pop(contextStackCursor, fiber);
1514 }
1515}
1516
1517function pushTopLevelContextObject(fiber, context, didChange) {
1518 {
1519 if (!(contextStackCursor.current === emptyContextObject)) {
1520 {
1521 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
1522 }
1523 }
1524
1525 push(contextStackCursor, context, fiber);
1526 push(didPerformWorkStackCursor, didChange, fiber);
1527 }
1528}
1529
1530function processChildContext(fiber, type, parentContext) {
1531 {
1532 var instance = fiber.stateNode;
1533 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
1534 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
1535
1536 if (typeof instance.getChildContext !== 'function') {
1537 {
1538 var componentName = getComponentName(type) || 'Unknown';
1539
1540 if (!warnedAboutMissingGetChildContext[componentName]) {
1541 warnedAboutMissingGetChildContext[componentName] = true;
1542
1543 error('%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);
1544 }
1545 }
1546
1547 return parentContext;
1548 }
1549
1550 var childContext;
1551
1552 {
1553 setCurrentPhase('getChildContext');
1554 }
1555
1556 startPhaseTimer(fiber, 'getChildContext');
1557 childContext = instance.getChildContext();
1558 stopPhaseTimer();
1559
1560 {
1561 setCurrentPhase(null);
1562 }
1563
1564 for (var contextKey in childContext) {
1565 if (!(contextKey in childContextTypes)) {
1566 {
1567 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
1568 }
1569 }
1570 }
1571
1572 {
1573 var name = getComponentName(type) || 'Unknown';
1574 checkPropTypes(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
1575 // somebody calls unstable_renderSubtreeIntoContainer() and we process
1576 // context from the parent component instance. The stack will be missing
1577 // because it's outside of the reconciliation, and so the pointer has not
1578 // been set. This is rare and doesn't matter. We'll also remove that API.
1579 getCurrentFiberStackInDev);
1580 }
1581
1582 return _assign({}, parentContext, {}, childContext);
1583 }
1584}
1585
1586function pushContextProvider(workInProgress) {
1587 {
1588 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
1589 // If the instance does not exist yet, we will push null at first,
1590 // and replace it on the stack later when invalidating the context.
1591
1592 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
1593 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
1594
1595 previousContext = contextStackCursor.current;
1596 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
1597 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
1598 return true;
1599 }
1600}
1601
1602function invalidateContextProvider(workInProgress, type, didChange) {
1603 {
1604 var instance = workInProgress.stateNode;
1605
1606 if (!instance) {
1607 {
1608 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
1609 }
1610 }
1611
1612 if (didChange) {
1613 // Merge parent and own context.
1614 // Skip this if we're not updating due to sCU.
1615 // This avoids unnecessarily recomputing memoized values.
1616 var mergedContext = processChildContext(workInProgress, type, previousContext);
1617 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
1618 // It is important to unwind the context in the reverse order.
1619
1620 pop(didPerformWorkStackCursor, workInProgress);
1621 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
1622
1623 push(contextStackCursor, mergedContext, workInProgress);
1624 push(didPerformWorkStackCursor, didChange, workInProgress);
1625 } else {
1626 pop(didPerformWorkStackCursor, workInProgress);
1627 push(didPerformWorkStackCursor, didChange, workInProgress);
1628 }
1629 }
1630}
1631
1632function findCurrentUnmaskedContext(fiber) {
1633 {
1634 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
1635 // makes sense elsewhere
1636 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
1637 {
1638 throw Error( "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." );
1639 }
1640 }
1641
1642 var node = fiber;
1643
1644 do {
1645 switch (node.tag) {
1646 case HostRoot:
1647 return node.stateNode.context;
1648
1649 case ClassComponent:
1650 {
1651 var Component = node.type;
1652
1653 if (isContextProvider(Component)) {
1654 return node.stateNode.__reactInternalMemoizedMergedChildContext;
1655 }
1656
1657 break;
1658 }
1659 }
1660
1661 node = node.return;
1662 } while (node !== null);
1663
1664 {
1665 {
1666 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
1667 }
1668 }
1669 }
1670}
1671
1672var LegacyRoot = 0;
1673var BlockingRoot = 1;
1674var ConcurrentRoot = 2;
1675
1676var Scheduler_runWithPriority = Scheduler$1.unstable_runWithPriority,
1677 Scheduler_scheduleCallback = Scheduler$1.unstable_scheduleCallback,
1678 Scheduler_cancelCallback = Scheduler$1.unstable_cancelCallback,
1679 Scheduler_shouldYield = Scheduler$1.unstable_shouldYield,
1680 Scheduler_requestPaint = Scheduler$1.unstable_requestPaint,
1681 Scheduler_now = Scheduler$1.unstable_now,
1682 Scheduler_getCurrentPriorityLevel = Scheduler$1.unstable_getCurrentPriorityLevel,
1683 Scheduler_ImmediatePriority = Scheduler$1.unstable_ImmediatePriority,
1684 Scheduler_UserBlockingPriority = Scheduler$1.unstable_UserBlockingPriority,
1685 Scheduler_NormalPriority = Scheduler$1.unstable_NormalPriority,
1686 Scheduler_LowPriority = Scheduler$1.unstable_LowPriority,
1687 Scheduler_IdlePriority = Scheduler$1.unstable_IdlePriority;
1688
1689{
1690 // Provide explicit error message when production+profiling bundle of e.g.
1691 // react-dom is used with production (non-profiling) bundle of
1692 // scheduler/tracing
1693 if (!(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null)) {
1694 {
1695 throw 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" );
1696 }
1697 }
1698}
1699
1700var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
1701// ascending numbers so we can compare them like numbers. They start at 90 to
1702// avoid clashing with Scheduler's priorities.
1703
1704var ImmediatePriority = 99;
1705var UserBlockingPriority = 98;
1706var NormalPriority = 97;
1707var LowPriority = 96;
1708var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
1709
1710var NoPriority = 90;
1711var shouldYield = Scheduler_shouldYield;
1712var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
1713Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
1714var syncQueue = null;
1715var immediateQueueCallbackNode = null;
1716var isFlushingSyncQueue = false;
1717var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
1718// This will be the case for modern browsers that support `performance.now`. In
1719// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
1720// timestamp. In that case, subtract the module initialization time to simulate
1721// the behavior of performance.now and keep our times small enough to fit
1722// within 32 bits.
1723// TODO: Consider lifting this into Scheduler.
1724
1725var now = initialTimeMs < 10000 ? Scheduler_now : function () {
1726 return Scheduler_now() - initialTimeMs;
1727};
1728function getCurrentPriorityLevel() {
1729 switch (Scheduler_getCurrentPriorityLevel()) {
1730 case Scheduler_ImmediatePriority:
1731 return ImmediatePriority;
1732
1733 case Scheduler_UserBlockingPriority:
1734 return UserBlockingPriority;
1735
1736 case Scheduler_NormalPriority:
1737 return NormalPriority;
1738
1739 case Scheduler_LowPriority:
1740 return LowPriority;
1741
1742 case Scheduler_IdlePriority:
1743 return IdlePriority;
1744
1745 default:
1746 {
1747 {
1748 throw Error( "Unknown priority level." );
1749 }
1750 }
1751
1752 }
1753}
1754
1755function reactPriorityToSchedulerPriority(reactPriorityLevel) {
1756 switch (reactPriorityLevel) {
1757 case ImmediatePriority:
1758 return Scheduler_ImmediatePriority;
1759
1760 case UserBlockingPriority:
1761 return Scheduler_UserBlockingPriority;
1762
1763 case NormalPriority:
1764 return Scheduler_NormalPriority;
1765
1766 case LowPriority:
1767 return Scheduler_LowPriority;
1768
1769 case IdlePriority:
1770 return Scheduler_IdlePriority;
1771
1772 default:
1773 {
1774 {
1775 throw Error( "Unknown priority level." );
1776 }
1777 }
1778
1779 }
1780}
1781
1782function runWithPriority(reactPriorityLevel, fn) {
1783 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
1784 return Scheduler_runWithPriority(priorityLevel, fn);
1785}
1786function scheduleCallback(reactPriorityLevel, callback, options) {
1787 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
1788 return Scheduler_scheduleCallback(priorityLevel, callback, options);
1789}
1790function scheduleSyncCallback(callback) {
1791 // Push this callback into an internal queue. We'll flush these either in
1792 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
1793 if (syncQueue === null) {
1794 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
1795
1796 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
1797 } else {
1798 // Push onto existing queue. Don't need to schedule a callback because
1799 // we already scheduled one when we created the queue.
1800 syncQueue.push(callback);
1801 }
1802
1803 return fakeCallbackNode;
1804}
1805function cancelCallback(callbackNode) {
1806 if (callbackNode !== fakeCallbackNode) {
1807 Scheduler_cancelCallback(callbackNode);
1808 }
1809}
1810function flushSyncCallbackQueue() {
1811 if (immediateQueueCallbackNode !== null) {
1812 var node = immediateQueueCallbackNode;
1813 immediateQueueCallbackNode = null;
1814 Scheduler_cancelCallback(node);
1815 }
1816
1817 flushSyncCallbackQueueImpl();
1818}
1819
1820function flushSyncCallbackQueueImpl() {
1821 if (!isFlushingSyncQueue && syncQueue !== null) {
1822 // Prevent re-entrancy.
1823 isFlushingSyncQueue = true;
1824 var i = 0;
1825
1826 try {
1827 var _isSync = true;
1828 var queue = syncQueue;
1829 runWithPriority(ImmediatePriority, function () {
1830 for (; i < queue.length; i++) {
1831 var callback = queue[i];
1832
1833 do {
1834 callback = callback(_isSync);
1835 } while (callback !== null);
1836 }
1837 });
1838 syncQueue = null;
1839 } catch (error) {
1840 // If something throws, leave the remaining callbacks on the queue.
1841 if (syncQueue !== null) {
1842 syncQueue = syncQueue.slice(i + 1);
1843 } // Resume flushing in the next tick
1844
1845
1846 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
1847 throw error;
1848 } finally {
1849 isFlushingSyncQueue = false;
1850 }
1851 }
1852}
1853
1854var NoMode = 0;
1855var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
1856// tag instead
1857
1858var BlockingMode = 2;
1859var ConcurrentMode = 4;
1860var ProfileMode = 8;
1861
1862// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
1863// Math.pow(2, 30) - 1
1864// 0b111111111111111111111111111111
1865var MAX_SIGNED_31_BIT_INT = 1073741823;
1866
1867var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
1868// Never work can be committed in an inconsistent state without tearing the UI.
1869// The main example is offscreen content, like a hidden subtree. So one possible
1870// name is Offscreen. However, it also includes dehydrated Suspense boundaries,
1871// which are inconsistent in the sense that they haven't finished yet, but
1872// aren't visibly inconsistent because the server rendered HTML matches what the
1873// hydrated tree would look like.
1874
1875var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
1876// order to be consistent.
1877
1878var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase
1879var Sync = MAX_SIGNED_31_BIT_INT;
1880var Batched = Sync - 1;
1881var UNIT_SIZE = 10;
1882var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
1883
1884function msToExpirationTime(ms) {
1885 // Always subtract from the offset so that we don't clash with the magic number for NoWork.
1886 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
1887}
1888function expirationTimeToMs(expirationTime) {
1889 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
1890}
1891
1892function ceiling(num, precision) {
1893 return ((num / precision | 0) + 1) * precision;
1894}
1895
1896function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
1897 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
1898} // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
1899// the names to reflect.
1900
1901
1902var LOW_PRIORITY_EXPIRATION = 5000;
1903var LOW_PRIORITY_BATCH_SIZE = 250;
1904function computeAsyncExpiration(currentTime) {
1905 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
1906}
1907function computeSuspenseExpiration(currentTime, timeoutMs) {
1908 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
1909 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
1910} // We intentionally set a higher expiration time for interactive updates in
1911// dev than in production.
1912//
1913// If the main thread is being blocked so long that you hit the expiration,
1914// it's a problem that could be solved with better scheduling.
1915//
1916// People will be more likely to notice this and fix it with the long
1917// expiration time in development.
1918//
1919// In production we opt for better UX at the risk of masking scheduling
1920// problems, by expiring fast.
1921
1922var HIGH_PRIORITY_EXPIRATION = 500 ;
1923var HIGH_PRIORITY_BATCH_SIZE = 100;
1924function computeInteractiveExpiration(currentTime) {
1925 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
1926}
1927function inferPriorityFromExpirationTime(currentTime, expirationTime) {
1928 if (expirationTime === Sync) {
1929 return ImmediatePriority;
1930 }
1931
1932 if (expirationTime === Never || expirationTime === Idle) {
1933 return IdlePriority;
1934 }
1935
1936 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
1937
1938 if (msUntil <= 0) {
1939 return ImmediatePriority;
1940 }
1941
1942 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
1943 return UserBlockingPriority;
1944 }
1945
1946 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
1947 return NormalPriority;
1948 } // TODO: Handle LowPriority
1949 // Assume anything lower has idle priority
1950
1951
1952 return IdlePriority;
1953}
1954
1955/**
1956 * inlined Object.is polyfill to avoid requiring consumers ship their own
1957 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
1958 */
1959function is(x, y) {
1960 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
1961 ;
1962}
1963
1964var objectIs = typeof Object.is === 'function' ? Object.is : is;
1965
1966var hasOwnProperty = Object.prototype.hasOwnProperty;
1967/**
1968 * Performs equality by iterating through keys on an object and returning false
1969 * when any key has values which are not strictly equal between the arguments.
1970 * Returns true when the values of all keys are strictly equal.
1971 */
1972
1973function shallowEqual(objA, objB) {
1974 if (objectIs(objA, objB)) {
1975 return true;
1976 }
1977
1978 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
1979 return false;
1980 }
1981
1982 var keysA = Object.keys(objA);
1983 var keysB = Object.keys(objB);
1984
1985 if (keysA.length !== keysB.length) {
1986 return false;
1987 } // Test for A's keys different from B.
1988
1989
1990 for (var i = 0; i < keysA.length; i++) {
1991 if (!hasOwnProperty.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
1992 return false;
1993 }
1994 }
1995
1996 return true;
1997}
1998
1999var ReactStrictModeWarnings = {
2000 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2001 flushPendingUnsafeLifecycleWarnings: function () {},
2002 recordLegacyContextWarning: function (fiber, instance) {},
2003 flushLegacyContextWarning: function () {},
2004 discardPendingWarnings: function () {}
2005};
2006
2007{
2008 var findStrictRoot = function (fiber) {
2009 var maybeStrictRoot = null;
2010 var node = fiber;
2011
2012 while (node !== null) {
2013 if (node.mode & StrictMode) {
2014 maybeStrictRoot = node;
2015 }
2016
2017 node = node.return;
2018 }
2019
2020 return maybeStrictRoot;
2021 };
2022
2023 var setToSortedString = function (set) {
2024 var array = [];
2025 set.forEach(function (value) {
2026 array.push(value);
2027 });
2028 return array.sort().join(', ');
2029 };
2030
2031 var pendingComponentWillMountWarnings = [];
2032 var pendingUNSAFE_ComponentWillMountWarnings = [];
2033 var pendingComponentWillReceivePropsWarnings = [];
2034 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2035 var pendingComponentWillUpdateWarnings = [];
2036 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
2037
2038 var didWarnAboutUnsafeLifecycles = new Set();
2039
2040 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2041 // Dedup strategy: Warn once per component.
2042 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2043 return;
2044 }
2045
2046 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
2047 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2048 pendingComponentWillMountWarnings.push(fiber);
2049 }
2050
2051 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2052 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2053 }
2054
2055 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2056 pendingComponentWillReceivePropsWarnings.push(fiber);
2057 }
2058
2059 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2060 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2061 }
2062
2063 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2064 pendingComponentWillUpdateWarnings.push(fiber);
2065 }
2066
2067 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2068 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2069 }
2070 };
2071
2072 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2073 // We do an initial pass to gather component names
2074 var componentWillMountUniqueNames = new Set();
2075
2076 if (pendingComponentWillMountWarnings.length > 0) {
2077 pendingComponentWillMountWarnings.forEach(function (fiber) {
2078 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2079 didWarnAboutUnsafeLifecycles.add(fiber.type);
2080 });
2081 pendingComponentWillMountWarnings = [];
2082 }
2083
2084 var UNSAFE_componentWillMountUniqueNames = new Set();
2085
2086 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2087 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2088 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2089 didWarnAboutUnsafeLifecycles.add(fiber.type);
2090 });
2091 pendingUNSAFE_ComponentWillMountWarnings = [];
2092 }
2093
2094 var componentWillReceivePropsUniqueNames = new Set();
2095
2096 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2097 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2098 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2099 didWarnAboutUnsafeLifecycles.add(fiber.type);
2100 });
2101 pendingComponentWillReceivePropsWarnings = [];
2102 }
2103
2104 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2105
2106 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2107 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2108 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2109 didWarnAboutUnsafeLifecycles.add(fiber.type);
2110 });
2111 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2112 }
2113
2114 var componentWillUpdateUniqueNames = new Set();
2115
2116 if (pendingComponentWillUpdateWarnings.length > 0) {
2117 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2118 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2119 didWarnAboutUnsafeLifecycles.add(fiber.type);
2120 });
2121 pendingComponentWillUpdateWarnings = [];
2122 }
2123
2124 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2125
2126 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2127 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2128 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2129 didWarnAboutUnsafeLifecycles.add(fiber.type);
2130 });
2131 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2132 } // Finally, we flush all the warnings
2133 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
2134
2135
2136 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
2137 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
2138
2139 error('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);
2140 }
2141
2142 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
2143 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
2144
2145 error('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);
2146 }
2147
2148 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
2149 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
2150
2151 error('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);
2152 }
2153
2154 if (componentWillMountUniqueNames.size > 0) {
2155 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
2156
2157 warn('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);
2158 }
2159
2160 if (componentWillReceivePropsUniqueNames.size > 0) {
2161 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
2162
2163 warn('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);
2164 }
2165
2166 if (componentWillUpdateUniqueNames.size > 0) {
2167 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
2168
2169 warn('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);
2170 }
2171 };
2172
2173 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
2174
2175 var didWarnAboutLegacyContext = new Set();
2176
2177 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
2178 var strictRoot = findStrictRoot(fiber);
2179
2180 if (strictRoot === null) {
2181 error('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.');
2182
2183 return;
2184 } // Dedup strategy: Warn once per component.
2185
2186
2187 if (didWarnAboutLegacyContext.has(fiber.type)) {
2188 return;
2189 }
2190
2191 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
2192
2193 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
2194 if (warningsForRoot === undefined) {
2195 warningsForRoot = [];
2196 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
2197 }
2198
2199 warningsForRoot.push(fiber);
2200 }
2201 };
2202
2203 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
2204 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
2205 if (fiberArray.length === 0) {
2206 return;
2207 }
2208
2209 var firstFiber = fiberArray[0];
2210 var uniqueNames = new Set();
2211 fiberArray.forEach(function (fiber) {
2212 uniqueNames.add(getComponentName(fiber.type) || 'Component');
2213 didWarnAboutLegacyContext.add(fiber.type);
2214 });
2215 var sortedNames = setToSortedString(uniqueNames);
2216 var firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
2217
2218 error('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, firstComponentStack);
2219 });
2220 };
2221
2222 ReactStrictModeWarnings.discardPendingWarnings = function () {
2223 pendingComponentWillMountWarnings = [];
2224 pendingUNSAFE_ComponentWillMountWarnings = [];
2225 pendingComponentWillReceivePropsWarnings = [];
2226 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2227 pendingComponentWillUpdateWarnings = [];
2228 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2229 pendingLegacyContextWarning = new Map();
2230 };
2231}
2232
2233var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
2234
2235var failedBoundaries = null;
2236var setRefreshHandler = function (handler) {
2237 {
2238 resolveFamily = handler;
2239 }
2240};
2241function resolveFunctionForHotReloading(type) {
2242 {
2243 if (resolveFamily === null) {
2244 // Hot reloading is disabled.
2245 return type;
2246 }
2247
2248 var family = resolveFamily(type);
2249
2250 if (family === undefined) {
2251 return type;
2252 } // Use the latest known implementation.
2253
2254
2255 return family.current;
2256 }
2257}
2258function resolveClassForHotReloading(type) {
2259 // No implementation differences.
2260 return resolveFunctionForHotReloading(type);
2261}
2262function resolveForwardRefForHotReloading(type) {
2263 {
2264 if (resolveFamily === null) {
2265 // Hot reloading is disabled.
2266 return type;
2267 }
2268
2269 var family = resolveFamily(type);
2270
2271 if (family === undefined) {
2272 // Check if we're dealing with a real forwardRef. Don't want to crash early.
2273 if (type !== null && type !== undefined && typeof type.render === 'function') {
2274 // ForwardRef is special because its resolved .type is an object,
2275 // but it's possible that we only have its inner render function in the map.
2276 // If that inner render function is different, we'll build a new forwardRef type.
2277 var currentRender = resolveFunctionForHotReloading(type.render);
2278
2279 if (type.render !== currentRender) {
2280 var syntheticType = {
2281 $$typeof: REACT_FORWARD_REF_TYPE,
2282 render: currentRender
2283 };
2284
2285 if (type.displayName !== undefined) {
2286 syntheticType.displayName = type.displayName;
2287 }
2288
2289 return syntheticType;
2290 }
2291 }
2292
2293 return type;
2294 } // Use the latest known implementation.
2295
2296
2297 return family.current;
2298 }
2299}
2300function isCompatibleFamilyForHotReloading(fiber, element) {
2301 {
2302 if (resolveFamily === null) {
2303 // Hot reloading is disabled.
2304 return false;
2305 }
2306
2307 var prevType = fiber.elementType;
2308 var nextType = element.type; // If we got here, we know types aren't === equal.
2309
2310 var needsCompareFamilies = false;
2311 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
2312
2313 switch (fiber.tag) {
2314 case ClassComponent:
2315 {
2316 if (typeof nextType === 'function') {
2317 needsCompareFamilies = true;
2318 }
2319
2320 break;
2321 }
2322
2323 case FunctionComponent:
2324 {
2325 if (typeof nextType === 'function') {
2326 needsCompareFamilies = true;
2327 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2328 // We don't know the inner type yet.
2329 // We're going to assume that the lazy inner type is stable,
2330 // and so it is sufficient to avoid reconciling it away.
2331 // We're not going to unwrap or actually use the new lazy type.
2332 needsCompareFamilies = true;
2333 }
2334
2335 break;
2336 }
2337
2338 case ForwardRef:
2339 {
2340 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
2341 needsCompareFamilies = true;
2342 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2343 needsCompareFamilies = true;
2344 }
2345
2346 break;
2347 }
2348
2349 case MemoComponent:
2350 case SimpleMemoComponent:
2351 {
2352 if ($$typeofNextType === REACT_MEMO_TYPE) {
2353 // TODO: if it was but can no longer be simple,
2354 // we shouldn't set this.
2355 needsCompareFamilies = true;
2356 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2357 needsCompareFamilies = true;
2358 }
2359
2360 break;
2361 }
2362
2363 default:
2364 return false;
2365 } // Check if both types have a family and it's the same one.
2366
2367
2368 if (needsCompareFamilies) {
2369 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
2370 // This means both of them need to be registered to preserve state.
2371 // If we unwrapped and compared the inner types for wrappers instead,
2372 // then we would risk falsely saying two separate memo(Foo)
2373 // calls are equivalent because they wrap the same Foo function.
2374 var prevFamily = resolveFamily(prevType);
2375
2376 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
2377 return true;
2378 }
2379 }
2380
2381 return false;
2382 }
2383}
2384function markFailedErrorBoundaryForHotReloading(fiber) {
2385 {
2386 if (resolveFamily === null) {
2387 // Hot reloading is disabled.
2388 return;
2389 }
2390
2391 if (typeof WeakSet !== 'function') {
2392 return;
2393 }
2394
2395 if (failedBoundaries === null) {
2396 failedBoundaries = new WeakSet();
2397 }
2398
2399 failedBoundaries.add(fiber);
2400 }
2401}
2402var scheduleRefresh = function (root, update) {
2403 {
2404 if (resolveFamily === null) {
2405 // Hot reloading is disabled.
2406 return;
2407 }
2408
2409 var staleFamilies = update.staleFamilies,
2410 updatedFamilies = update.updatedFamilies;
2411 flushPassiveEffects();
2412 flushSync(function () {
2413 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
2414 });
2415 }
2416};
2417var scheduleRoot = function (root, element) {
2418 {
2419 if (root.context !== emptyContextObject) {
2420 // Super edge case: root has a legacy _renderSubtree context
2421 // but we don't know the parentComponent so we can't pass it.
2422 // Just ignore. We'll delete this with _renderSubtree code path later.
2423 return;
2424 }
2425
2426 flushPassiveEffects();
2427 syncUpdates(function () {
2428 updateContainer(element, root, null, null);
2429 });
2430 }
2431};
2432
2433function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
2434 {
2435 var alternate = fiber.alternate,
2436 child = fiber.child,
2437 sibling = fiber.sibling,
2438 tag = fiber.tag,
2439 type = fiber.type;
2440 var candidateType = null;
2441
2442 switch (tag) {
2443 case FunctionComponent:
2444 case SimpleMemoComponent:
2445 case ClassComponent:
2446 candidateType = type;
2447 break;
2448
2449 case ForwardRef:
2450 candidateType = type.render;
2451 break;
2452 }
2453
2454 if (resolveFamily === null) {
2455 throw new Error('Expected resolveFamily to be set during hot reload.');
2456 }
2457
2458 var needsRender = false;
2459 var needsRemount = false;
2460
2461 if (candidateType !== null) {
2462 var family = resolveFamily(candidateType);
2463
2464 if (family !== undefined) {
2465 if (staleFamilies.has(family)) {
2466 needsRemount = true;
2467 } else if (updatedFamilies.has(family)) {
2468 if (tag === ClassComponent) {
2469 needsRemount = true;
2470 } else {
2471 needsRender = true;
2472 }
2473 }
2474 }
2475 }
2476
2477 if (failedBoundaries !== null) {
2478 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
2479 needsRemount = true;
2480 }
2481 }
2482
2483 if (needsRemount) {
2484 fiber._debugNeedsRemount = true;
2485 }
2486
2487 if (needsRemount || needsRender) {
2488 scheduleWork(fiber, Sync);
2489 }
2490
2491 if (child !== null && !needsRemount) {
2492 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
2493 }
2494
2495 if (sibling !== null) {
2496 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
2497 }
2498 }
2499}
2500
2501var findHostInstancesForRefresh = function (root, families) {
2502 {
2503 var hostInstances = new Set();
2504 var types = new Set(families.map(function (family) {
2505 return family.current;
2506 }));
2507 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
2508 return hostInstances;
2509 }
2510};
2511
2512function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
2513 {
2514 var child = fiber.child,
2515 sibling = fiber.sibling,
2516 tag = fiber.tag,
2517 type = fiber.type;
2518 var candidateType = null;
2519
2520 switch (tag) {
2521 case FunctionComponent:
2522 case SimpleMemoComponent:
2523 case ClassComponent:
2524 candidateType = type;
2525 break;
2526
2527 case ForwardRef:
2528 candidateType = type.render;
2529 break;
2530 }
2531
2532 var didMatch = false;
2533
2534 if (candidateType !== null) {
2535 if (types.has(candidateType)) {
2536 didMatch = true;
2537 }
2538 }
2539
2540 if (didMatch) {
2541 // We have a match. This only drills down to the closest host components.
2542 // There's no need to search deeper because for the purpose of giving
2543 // visual feedback, "flashing" outermost parent rectangles is sufficient.
2544 findHostInstancesForFiberShallowly(fiber, hostInstances);
2545 } else {
2546 // If there's no match, maybe there will be one further down in the child tree.
2547 if (child !== null) {
2548 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
2549 }
2550 }
2551
2552 if (sibling !== null) {
2553 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
2554 }
2555 }
2556}
2557
2558function findHostInstancesForFiberShallowly(fiber, hostInstances) {
2559 {
2560 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
2561
2562 if (foundHostInstances) {
2563 return;
2564 } // If we didn't find any host children, fallback to closest host parent.
2565
2566
2567 var node = fiber;
2568
2569 while (true) {
2570 switch (node.tag) {
2571 case HostComponent:
2572 hostInstances.add(node.stateNode);
2573 return;
2574
2575 case HostPortal:
2576 hostInstances.add(node.stateNode.containerInfo);
2577 return;
2578
2579 case HostRoot:
2580 hostInstances.add(node.stateNode.containerInfo);
2581 return;
2582 }
2583
2584 if (node.return === null) {
2585 throw new Error('Expected to reach root first.');
2586 }
2587
2588 node = node.return;
2589 }
2590 }
2591}
2592
2593function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
2594 {
2595 var node = fiber;
2596 var foundHostInstances = false;
2597
2598 while (true) {
2599 if (node.tag === HostComponent) {
2600 // We got a match.
2601 foundHostInstances = true;
2602 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
2603 } else if (node.child !== null) {
2604 node.child.return = node;
2605 node = node.child;
2606 continue;
2607 }
2608
2609 if (node === fiber) {
2610 return foundHostInstances;
2611 }
2612
2613 while (node.sibling === null) {
2614 if (node.return === null || node.return === fiber) {
2615 return foundHostInstances;
2616 }
2617
2618 node = node.return;
2619 }
2620
2621 node.sibling.return = node.return;
2622 node = node.sibling;
2623 }
2624 }
2625
2626 return false;
2627}
2628
2629function resolveDefaultProps(Component, baseProps) {
2630 if (Component && Component.defaultProps) {
2631 // Resolve default props. Taken from ReactElement
2632 var props = _assign({}, baseProps);
2633
2634 var defaultProps = Component.defaultProps;
2635
2636 for (var propName in defaultProps) {
2637 if (props[propName] === undefined) {
2638 props[propName] = defaultProps[propName];
2639 }
2640 }
2641
2642 return props;
2643 }
2644
2645 return baseProps;
2646}
2647function readLazyComponentType(lazyComponent) {
2648 initializeLazyComponentType(lazyComponent);
2649
2650 if (lazyComponent._status !== Resolved) {
2651 throw lazyComponent._result;
2652 }
2653
2654 return lazyComponent._result;
2655}
2656
2657var valueCursor = createCursor(null);
2658var rendererSigil;
2659
2660{
2661 // Use this to detect multiple renderers using the same context
2662 rendererSigil = {};
2663}
2664
2665var currentlyRenderingFiber = null;
2666var lastContextDependency = null;
2667var lastContextWithAllBitsObserved = null;
2668var isDisallowedContextReadInDEV = false;
2669function resetContextDependencies() {
2670 // This is called right before React yields execution, to ensure `readContext`
2671 // cannot be called outside the render phase.
2672 currentlyRenderingFiber = null;
2673 lastContextDependency = null;
2674 lastContextWithAllBitsObserved = null;
2675
2676 {
2677 isDisallowedContextReadInDEV = false;
2678 }
2679}
2680function enterDisallowedContextReadInDEV() {
2681 {
2682 isDisallowedContextReadInDEV = true;
2683 }
2684}
2685function exitDisallowedContextReadInDEV() {
2686 {
2687 isDisallowedContextReadInDEV = false;
2688 }
2689}
2690function pushProvider(providerFiber, nextValue) {
2691 var context = providerFiber.type._context;
2692
2693 {
2694 push(valueCursor, context._currentValue2, providerFiber);
2695 context._currentValue2 = nextValue;
2696
2697 {
2698 if (context._currentRenderer2 !== undefined && context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil) {
2699 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
2700 }
2701
2702 context._currentRenderer2 = rendererSigil;
2703 }
2704 }
2705}
2706function popProvider(providerFiber) {
2707 var currentValue = valueCursor.current;
2708 pop(valueCursor, providerFiber);
2709 var context = providerFiber.type._context;
2710
2711 {
2712 context._currentValue2 = currentValue;
2713 }
2714}
2715function calculateChangedBits(context, newValue, oldValue) {
2716 if (objectIs(oldValue, newValue)) {
2717 // No change
2718 return 0;
2719 } else {
2720 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
2721
2722 {
2723 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
2724 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
2725 }
2726 }
2727
2728 return changedBits | 0;
2729 }
2730}
2731function scheduleWorkOnParentPath(parent, renderExpirationTime) {
2732 // Update the child expiration time of all the ancestors, including
2733 // the alternates.
2734 var node = parent;
2735
2736 while (node !== null) {
2737 var alternate = node.alternate;
2738
2739 if (node.childExpirationTime < renderExpirationTime) {
2740 node.childExpirationTime = renderExpirationTime;
2741
2742 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
2743 alternate.childExpirationTime = renderExpirationTime;
2744 }
2745 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
2746 alternate.childExpirationTime = renderExpirationTime;
2747 } else {
2748 // Neither alternate was updated, which means the rest of the
2749 // ancestor path already has sufficient priority.
2750 break;
2751 }
2752
2753 node = node.return;
2754 }
2755}
2756function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
2757 var fiber = workInProgress.child;
2758
2759 if (fiber !== null) {
2760 // Set the return pointer of the child to the work-in-progress fiber.
2761 fiber.return = workInProgress;
2762 }
2763
2764 while (fiber !== null) {
2765 var nextFiber = void 0; // Visit this fiber.
2766
2767 var list = fiber.dependencies;
2768
2769 if (list !== null) {
2770 nextFiber = fiber.child;
2771 var dependency = list.firstContext;
2772
2773 while (dependency !== null) {
2774 // Check if the context matches.
2775 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
2776 // Match! Schedule an update on this fiber.
2777 if (fiber.tag === ClassComponent) {
2778 // Schedule a force update on the work-in-progress.
2779 var update = createUpdate(renderExpirationTime, null);
2780 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
2781 // update to the current fiber, too, which means it will persist even if
2782 // this render is thrown away. Since it's a race condition, not sure it's
2783 // worth fixing.
2784
2785 enqueueUpdate(fiber, update);
2786 }
2787
2788 if (fiber.expirationTime < renderExpirationTime) {
2789 fiber.expirationTime = renderExpirationTime;
2790 }
2791
2792 var alternate = fiber.alternate;
2793
2794 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
2795 alternate.expirationTime = renderExpirationTime;
2796 }
2797
2798 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
2799
2800 if (list.expirationTime < renderExpirationTime) {
2801 list.expirationTime = renderExpirationTime;
2802 } // Since we already found a match, we can stop traversing the
2803 // dependency list.
2804
2805
2806 break;
2807 }
2808
2809 dependency = dependency.next;
2810 }
2811 } else if (fiber.tag === ContextProvider) {
2812 // Don't scan deeper if this is a matching provider
2813 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
2814 } else {
2815 // Traverse down.
2816 nextFiber = fiber.child;
2817 }
2818
2819 if (nextFiber !== null) {
2820 // Set the return pointer of the child to the work-in-progress fiber.
2821 nextFiber.return = fiber;
2822 } else {
2823 // No child. Traverse to next sibling.
2824 nextFiber = fiber;
2825
2826 while (nextFiber !== null) {
2827 if (nextFiber === workInProgress) {
2828 // We're back to the root of this subtree. Exit.
2829 nextFiber = null;
2830 break;
2831 }
2832
2833 var sibling = nextFiber.sibling;
2834
2835 if (sibling !== null) {
2836 // Set the return pointer of the sibling to the work-in-progress fiber.
2837 sibling.return = nextFiber.return;
2838 nextFiber = sibling;
2839 break;
2840 } // No more siblings. Traverse up.
2841
2842
2843 nextFiber = nextFiber.return;
2844 }
2845 }
2846
2847 fiber = nextFiber;
2848 }
2849}
2850function prepareToReadContext(workInProgress, renderExpirationTime) {
2851 currentlyRenderingFiber = workInProgress;
2852 lastContextDependency = null;
2853 lastContextWithAllBitsObserved = null;
2854 var dependencies = workInProgress.dependencies;
2855
2856 if (dependencies !== null) {
2857 var firstContext = dependencies.firstContext;
2858
2859 if (firstContext !== null) {
2860 if (dependencies.expirationTime >= renderExpirationTime) {
2861 // Context list has a pending update. Mark that this fiber performed work.
2862 markWorkInProgressReceivedUpdate();
2863 } // Reset the work-in-progress list
2864
2865
2866 dependencies.firstContext = null;
2867 }
2868 }
2869}
2870function readContext(context, observedBits) {
2871 {
2872 // This warning would fire if you read context inside a Hook like useMemo.
2873 // Unlike the class check below, it's not enforced in production for perf.
2874 if (isDisallowedContextReadInDEV) {
2875 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().');
2876 }
2877 }
2878
2879 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
2880 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
2881
2882 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
2883 // Observe all updates.
2884 lastContextWithAllBitsObserved = context;
2885 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
2886 } else {
2887 resolvedObservedBits = observedBits;
2888 }
2889
2890 var contextItem = {
2891 context: context,
2892 observedBits: resolvedObservedBits,
2893 next: null
2894 };
2895
2896 if (lastContextDependency === null) {
2897 if (!(currentlyRenderingFiber !== null)) {
2898 {
2899 throw 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()." );
2900 }
2901 } // This is the first dependency for this component. Create a new list.
2902
2903
2904 lastContextDependency = contextItem;
2905 currentlyRenderingFiber.dependencies = {
2906 expirationTime: NoWork,
2907 firstContext: contextItem,
2908 responders: null
2909 };
2910 } else {
2911 // Append a new context item.
2912 lastContextDependency = lastContextDependency.next = contextItem;
2913 }
2914 }
2915
2916 return context._currentValue2;
2917}
2918
2919var UpdateState = 0;
2920var ReplaceState = 1;
2921var ForceUpdate = 2;
2922var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
2923// It should only be read right after calling `processUpdateQueue`, via
2924// `checkHasForceUpdateAfterProcessing`.
2925
2926var hasForceUpdate = false;
2927var didWarnUpdateInsideUpdate;
2928var currentlyProcessingQueue;
2929
2930{
2931 didWarnUpdateInsideUpdate = false;
2932 currentlyProcessingQueue = null;
2933}
2934
2935function initializeUpdateQueue(fiber) {
2936 var queue = {
2937 baseState: fiber.memoizedState,
2938 baseQueue: null,
2939 shared: {
2940 pending: null
2941 },
2942 effects: null
2943 };
2944 fiber.updateQueue = queue;
2945}
2946function cloneUpdateQueue(current, workInProgress) {
2947 // Clone the update queue from current. Unless it's already a clone.
2948 var queue = workInProgress.updateQueue;
2949 var currentQueue = current.updateQueue;
2950
2951 if (queue === currentQueue) {
2952 var clone = {
2953 baseState: currentQueue.baseState,
2954 baseQueue: currentQueue.baseQueue,
2955 shared: currentQueue.shared,
2956 effects: currentQueue.effects
2957 };
2958 workInProgress.updateQueue = clone;
2959 }
2960}
2961function createUpdate(expirationTime, suspenseConfig) {
2962 var update = {
2963 expirationTime: expirationTime,
2964 suspenseConfig: suspenseConfig,
2965 tag: UpdateState,
2966 payload: null,
2967 callback: null,
2968 next: null
2969 };
2970 update.next = update;
2971
2972 {
2973 update.priority = getCurrentPriorityLevel();
2974 }
2975
2976 return update;
2977}
2978function enqueueUpdate(fiber, update) {
2979 var updateQueue = fiber.updateQueue;
2980
2981 if (updateQueue === null) {
2982 // Only occurs if the fiber has been unmounted.
2983 return;
2984 }
2985
2986 var sharedQueue = updateQueue.shared;
2987 var pending = sharedQueue.pending;
2988
2989 if (pending === null) {
2990 // This is the first update. Create a circular list.
2991 update.next = update;
2992 } else {
2993 update.next = pending.next;
2994 pending.next = update;
2995 }
2996
2997 sharedQueue.pending = update;
2998
2999 {
3000 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
3001 error('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.');
3002
3003 didWarnUpdateInsideUpdate = true;
3004 }
3005 }
3006}
3007function enqueueCapturedUpdate(workInProgress, update) {
3008 var current = workInProgress.alternate;
3009
3010 if (current !== null) {
3011 // Ensure the work-in-progress queue is a clone
3012 cloneUpdateQueue(current, workInProgress);
3013 } // Captured updates go only on the work-in-progress queue.
3014
3015
3016 var queue = workInProgress.updateQueue; // Append the update to the end of the list.
3017
3018 var last = queue.baseQueue;
3019
3020 if (last === null) {
3021 queue.baseQueue = update.next = update;
3022 update.next = update;
3023 } else {
3024 update.next = last.next;
3025 last.next = update;
3026 }
3027}
3028
3029function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3030 switch (update.tag) {
3031 case ReplaceState:
3032 {
3033 var payload = update.payload;
3034
3035 if (typeof payload === 'function') {
3036 // Updater function
3037 {
3038 enterDisallowedContextReadInDEV();
3039 }
3040
3041 var nextState = payload.call(instance, prevState, nextProps);
3042
3043 {
3044 exitDisallowedContextReadInDEV();
3045 }
3046
3047 return nextState;
3048 } // State object
3049
3050
3051 return payload;
3052 }
3053
3054 case CaptureUpdate:
3055 {
3056 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
3057 }
3058 // Intentional fallthrough
3059
3060 case UpdateState:
3061 {
3062 var _payload = update.payload;
3063 var partialState;
3064
3065 if (typeof _payload === 'function') {
3066 // Updater function
3067 {
3068 enterDisallowedContextReadInDEV();
3069 }
3070
3071 partialState = _payload.call(instance, prevState, nextProps);
3072
3073 {
3074 exitDisallowedContextReadInDEV();
3075 }
3076 } else {
3077 // Partial state object
3078 partialState = _payload;
3079 }
3080
3081 if (partialState === null || partialState === undefined) {
3082 // Null and undefined are treated as no-ops.
3083 return prevState;
3084 } // Merge the partial state and the previous state.
3085
3086
3087 return _assign({}, prevState, partialState);
3088 }
3089
3090 case ForceUpdate:
3091 {
3092 hasForceUpdate = true;
3093 return prevState;
3094 }
3095 }
3096
3097 return prevState;
3098}
3099
3100function processUpdateQueue(workInProgress, props, instance, renderExpirationTime) {
3101 // This is always non-null on a ClassComponent or HostRoot
3102 var queue = workInProgress.updateQueue;
3103 hasForceUpdate = false;
3104
3105 {
3106 currentlyProcessingQueue = queue.shared;
3107 } // The last rebase update that is NOT part of the base state.
3108
3109
3110 var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet.
3111
3112 var pendingQueue = queue.shared.pending;
3113
3114 if (pendingQueue !== null) {
3115 // We have new updates that haven't been processed yet.
3116 // We'll add them to the base queue.
3117 if (baseQueue !== null) {
3118 // Merge the pending queue and the base queue.
3119 var baseFirst = baseQueue.next;
3120 var pendingFirst = pendingQueue.next;
3121 baseQueue.next = pendingFirst;
3122 pendingQueue.next = baseFirst;
3123 }
3124
3125 baseQueue = pendingQueue;
3126 queue.shared.pending = null; // TODO: Pass `current` as argument
3127
3128 var current = workInProgress.alternate;
3129
3130 if (current !== null) {
3131 var currentQueue = current.updateQueue;
3132
3133 if (currentQueue !== null) {
3134 currentQueue.baseQueue = pendingQueue;
3135 }
3136 }
3137 } // These values may change as we process the queue.
3138
3139
3140 if (baseQueue !== null) {
3141 var first = baseQueue.next; // Iterate through the list of updates to compute the result.
3142
3143 var newState = queue.baseState;
3144 var newExpirationTime = NoWork;
3145 var newBaseState = null;
3146 var newBaseQueueFirst = null;
3147 var newBaseQueueLast = null;
3148
3149 if (first !== null) {
3150 var update = first;
3151
3152 do {
3153 var updateExpirationTime = update.expirationTime;
3154
3155 if (updateExpirationTime < renderExpirationTime) {
3156 // Priority is insufficient. Skip this update. If this is the first
3157 // skipped update, the previous update/state is the new base
3158 // update/state.
3159 var clone = {
3160 expirationTime: update.expirationTime,
3161 suspenseConfig: update.suspenseConfig,
3162 tag: update.tag,
3163 payload: update.payload,
3164 callback: update.callback,
3165 next: null
3166 };
3167
3168 if (newBaseQueueLast === null) {
3169 newBaseQueueFirst = newBaseQueueLast = clone;
3170 newBaseState = newState;
3171 } else {
3172 newBaseQueueLast = newBaseQueueLast.next = clone;
3173 } // Update the remaining priority in the queue.
3174
3175
3176 if (updateExpirationTime > newExpirationTime) {
3177 newExpirationTime = updateExpirationTime;
3178 }
3179 } else {
3180 // This update does have sufficient priority.
3181 if (newBaseQueueLast !== null) {
3182 var _clone = {
3183 expirationTime: Sync,
3184 // This update is going to be committed so we never want uncommit it.
3185 suspenseConfig: update.suspenseConfig,
3186 tag: update.tag,
3187 payload: update.payload,
3188 callback: update.callback,
3189 next: null
3190 };
3191 newBaseQueueLast = newBaseQueueLast.next = _clone;
3192 } // Mark the event time of this update as relevant to this render pass.
3193 // TODO: This should ideally use the true event time of this update rather than
3194 // its priority which is a derived and not reverseable value.
3195 // TODO: We should skip this update if it was already committed but currently
3196 // we have no way of detecting the difference between a committed and suspended
3197 // update here.
3198
3199
3200 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
3201
3202 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
3203 var callback = update.callback;
3204
3205 if (callback !== null) {
3206 workInProgress.effectTag |= Callback;
3207 var effects = queue.effects;
3208
3209 if (effects === null) {
3210 queue.effects = [update];
3211 } else {
3212 effects.push(update);
3213 }
3214 }
3215 }
3216
3217 update = update.next;
3218
3219 if (update === null || update === first) {
3220 pendingQueue = queue.shared.pending;
3221
3222 if (pendingQueue === null) {
3223 break;
3224 } else {
3225 // An update was scheduled from inside a reducer. Add the new
3226 // pending updates to the end of the list and keep processing.
3227 update = baseQueue.next = pendingQueue.next;
3228 pendingQueue.next = first;
3229 queue.baseQueue = baseQueue = pendingQueue;
3230 queue.shared.pending = null;
3231 }
3232 }
3233 } while (true);
3234 }
3235
3236 if (newBaseQueueLast === null) {
3237 newBaseState = newState;
3238 } else {
3239 newBaseQueueLast.next = newBaseQueueFirst;
3240 }
3241
3242 queue.baseState = newBaseState;
3243 queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue.
3244 // This should be fine because the only two other things that contribute to
3245 // expiration time are props and context. We're already in the middle of the
3246 // begin phase by the time we start processing the queue, so we've already
3247 // dealt with the props. Context in components that specify
3248 // shouldComponentUpdate is tricky; but we'll have to account for
3249 // that regardless.
3250
3251 markUnprocessedUpdateTime(newExpirationTime);
3252 workInProgress.expirationTime = newExpirationTime;
3253 workInProgress.memoizedState = newState;
3254 }
3255
3256 {
3257 currentlyProcessingQueue = null;
3258 }
3259}
3260
3261function callCallback(callback, context) {
3262 if (!(typeof callback === 'function')) {
3263 {
3264 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
3265 }
3266 }
3267
3268 callback.call(context);
3269}
3270
3271function resetHasForceUpdateBeforeProcessing() {
3272 hasForceUpdate = false;
3273}
3274function checkHasForceUpdateAfterProcessing() {
3275 return hasForceUpdate;
3276}
3277function commitUpdateQueue(finishedWork, finishedQueue, instance) {
3278 // Commit the effects
3279 var effects = finishedQueue.effects;
3280 finishedQueue.effects = null;
3281
3282 if (effects !== null) {
3283 for (var i = 0; i < effects.length; i++) {
3284 var effect = effects[i];
3285 var callback = effect.callback;
3286
3287 if (callback !== null) {
3288 effect.callback = null;
3289 callCallback(callback, instance);
3290 }
3291 }
3292 }
3293}
3294
3295var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
3296function requestCurrentSuspenseConfig() {
3297 return ReactCurrentBatchConfig.suspense;
3298}
3299
3300var fakeInternalInstance = {};
3301var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
3302// We'll use it to determine whether we need to initialize legacy refs.
3303
3304var emptyRefsObject = new React.Component().refs;
3305var didWarnAboutStateAssignmentForComponent;
3306var didWarnAboutUninitializedState;
3307var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
3308var didWarnAboutLegacyLifecyclesAndDerivedState;
3309var didWarnAboutUndefinedDerivedState;
3310var warnOnUndefinedDerivedState;
3311var warnOnInvalidCallback;
3312var didWarnAboutDirectlyAssigningPropsToState;
3313var didWarnAboutContextTypeAndContextTypes;
3314var didWarnAboutInvalidateContextType;
3315
3316{
3317 didWarnAboutStateAssignmentForComponent = new Set();
3318 didWarnAboutUninitializedState = new Set();
3319 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3320 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3321 didWarnAboutDirectlyAssigningPropsToState = new Set();
3322 didWarnAboutUndefinedDerivedState = new Set();
3323 didWarnAboutContextTypeAndContextTypes = new Set();
3324 didWarnAboutInvalidateContextType = new Set();
3325 var didWarnOnInvalidCallback = new Set();
3326
3327 warnOnInvalidCallback = function (callback, callerName) {
3328 if (callback === null || typeof callback === 'function') {
3329 return;
3330 }
3331
3332 var key = callerName + "_" + callback;
3333
3334 if (!didWarnOnInvalidCallback.has(key)) {
3335 didWarnOnInvalidCallback.add(key);
3336
3337 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3338 }
3339 };
3340
3341 warnOnUndefinedDerivedState = function (type, partialState) {
3342 if (partialState === undefined) {
3343 var componentName = getComponentName(type) || 'Component';
3344
3345 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3346 didWarnAboutUndefinedDerivedState.add(componentName);
3347
3348 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3349 }
3350 }
3351 }; // This is so gross but it's at least non-critical and can be removed if
3352 // it causes problems. This is meant to give a nicer error message for
3353 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3354 // ...)) which otherwise throws a "_processChildContext is not a function"
3355 // exception.
3356
3357
3358 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3359 enumerable: false,
3360 value: function () {
3361 {
3362 {
3363 throw 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)." );
3364 }
3365 }
3366 }
3367 });
3368 Object.freeze(fakeInternalInstance);
3369}
3370
3371function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3372 var prevState = workInProgress.memoizedState;
3373
3374 var partialState = getDerivedStateFromProps(nextProps, prevState);
3375
3376 {
3377 warnOnUndefinedDerivedState(ctor, partialState);
3378 } // Merge the partial state and the previous state.
3379
3380
3381 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3382 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
3383 // base state.
3384
3385 if (workInProgress.expirationTime === NoWork) {
3386 // Queue is always non-null for classes
3387 var updateQueue = workInProgress.updateQueue;
3388 updateQueue.baseState = memoizedState;
3389 }
3390}
3391var classComponentUpdater = {
3392 isMounted: isMounted,
3393 enqueueSetState: function (inst, payload, callback) {
3394 var fiber = get(inst);
3395 var currentTime = requestCurrentTimeForUpdate();
3396 var suspenseConfig = requestCurrentSuspenseConfig();
3397 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3398 var update = createUpdate(expirationTime, suspenseConfig);
3399 update.payload = payload;
3400
3401 if (callback !== undefined && callback !== null) {
3402 {
3403 warnOnInvalidCallback(callback, 'setState');
3404 }
3405
3406 update.callback = callback;
3407 }
3408
3409 enqueueUpdate(fiber, update);
3410 scheduleWork(fiber, expirationTime);
3411 },
3412 enqueueReplaceState: function (inst, payload, callback) {
3413 var fiber = get(inst);
3414 var currentTime = requestCurrentTimeForUpdate();
3415 var suspenseConfig = requestCurrentSuspenseConfig();
3416 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3417 var update = createUpdate(expirationTime, suspenseConfig);
3418 update.tag = ReplaceState;
3419 update.payload = payload;
3420
3421 if (callback !== undefined && callback !== null) {
3422 {
3423 warnOnInvalidCallback(callback, 'replaceState');
3424 }
3425
3426 update.callback = callback;
3427 }
3428
3429 enqueueUpdate(fiber, update);
3430 scheduleWork(fiber, expirationTime);
3431 },
3432 enqueueForceUpdate: function (inst, callback) {
3433 var fiber = get(inst);
3434 var currentTime = requestCurrentTimeForUpdate();
3435 var suspenseConfig = requestCurrentSuspenseConfig();
3436 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3437 var update = createUpdate(expirationTime, suspenseConfig);
3438 update.tag = ForceUpdate;
3439
3440 if (callback !== undefined && callback !== null) {
3441 {
3442 warnOnInvalidCallback(callback, 'forceUpdate');
3443 }
3444
3445 update.callback = callback;
3446 }
3447
3448 enqueueUpdate(fiber, update);
3449 scheduleWork(fiber, expirationTime);
3450 }
3451};
3452
3453function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3454 var instance = workInProgress.stateNode;
3455
3456 if (typeof instance.shouldComponentUpdate === 'function') {
3457
3458 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3459 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3460 stopPhaseTimer();
3461
3462 {
3463 if (shouldUpdate === undefined) {
3464 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
3465 }
3466 }
3467
3468 return shouldUpdate;
3469 }
3470
3471 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3472 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3473 }
3474
3475 return true;
3476}
3477
3478function checkClassInstance(workInProgress, ctor, newProps) {
3479 var instance = workInProgress.stateNode;
3480
3481 {
3482 var name = getComponentName(ctor) || 'Component';
3483 var renderPresent = instance.render;
3484
3485 if (!renderPresent) {
3486 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3487 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3488 } else {
3489 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3490 }
3491 }
3492
3493 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
3494 error('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);
3495 }
3496
3497 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
3498 error('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);
3499 }
3500
3501 if (instance.propTypes) {
3502 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
3503 }
3504
3505 if (instance.contextType) {
3506 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
3507 }
3508
3509 {
3510 if (instance.contextTypes) {
3511 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
3512 }
3513
3514 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3515 didWarnAboutContextTypeAndContextTypes.add(ctor);
3516
3517 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3518 }
3519 }
3520
3521 if (typeof instance.componentShouldUpdate === 'function') {
3522 error('%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);
3523 }
3524
3525 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3526 error('%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');
3527 }
3528
3529 if (typeof instance.componentDidUnmount === 'function') {
3530 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
3531 }
3532
3533 if (typeof instance.componentDidReceiveProps === 'function') {
3534 error('%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);
3535 }
3536
3537 if (typeof instance.componentWillRecieveProps === 'function') {
3538 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
3539 }
3540
3541 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
3542 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
3543 }
3544
3545 var hasMutatedProps = instance.props !== newProps;
3546
3547 if (instance.props !== undefined && hasMutatedProps) {
3548 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
3549 }
3550
3551 if (instance.defaultProps) {
3552 error('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);
3553 }
3554
3555 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3556 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3557
3558 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3559 }
3560
3561 if (typeof instance.getDerivedStateFromProps === 'function') {
3562 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
3563 }
3564
3565 if (typeof instance.getDerivedStateFromError === 'function') {
3566 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
3567 }
3568
3569 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
3570 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
3571 }
3572
3573 var _state = instance.state;
3574
3575 if (_state && (typeof _state !== 'object' || isArray(_state))) {
3576 error('%s.state: must be set to an object or null', name);
3577 }
3578
3579 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
3580 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
3581 }
3582 }
3583}
3584
3585function adoptClassInstance(workInProgress, instance) {
3586 instance.updater = classComponentUpdater;
3587 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
3588
3589 set(instance, workInProgress);
3590
3591 {
3592 instance._reactInternalInstance = fakeInternalInstance;
3593 }
3594}
3595
3596function constructClassInstance(workInProgress, ctor, props) {
3597 var isLegacyContextConsumer = false;
3598 var unmaskedContext = emptyContextObject;
3599 var context = emptyContextObject;
3600 var contextType = ctor.contextType;
3601
3602 {
3603 if ('contextType' in ctor) {
3604 var isValid = // Allow null for conditional declaration
3605 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
3606
3607 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
3608 didWarnAboutInvalidateContextType.add(ctor);
3609 var addendum = '';
3610
3611 if (contextType === undefined) {
3612 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.';
3613 } else if (typeof contextType !== 'object') {
3614 addendum = ' However, it is set to a ' + typeof contextType + '.';
3615 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
3616 addendum = ' Did you accidentally pass the Context.Provider instead?';
3617 } else if (contextType._context !== undefined) {
3618 // <Context.Consumer>
3619 addendum = ' Did you accidentally pass the Context.Consumer instead?';
3620 } else {
3621 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
3622 }
3623
3624 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
3625 }
3626 }
3627 }
3628
3629 if (typeof contextType === 'object' && contextType !== null) {
3630 context = readContext(contextType);
3631 } else {
3632 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3633 var contextTypes = ctor.contextTypes;
3634 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
3635 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
3636 } // Instantiate twice to help detect side-effects.
3637
3638 var instance = new ctor(props, context);
3639 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
3640 adoptClassInstance(workInProgress, instance);
3641
3642 {
3643 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
3644 var componentName = getComponentName(ctor) || 'Component';
3645
3646 if (!didWarnAboutUninitializedState.has(componentName)) {
3647 didWarnAboutUninitializedState.add(componentName);
3648
3649 error('`%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);
3650 }
3651 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
3652 // Warn about these lifecycles if they are present.
3653 // Don't warn about react-lifecycles-compat polyfilled methods though.
3654
3655
3656 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
3657 var foundWillMountName = null;
3658 var foundWillReceivePropsName = null;
3659 var foundWillUpdateName = null;
3660
3661 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3662 foundWillMountName = 'componentWillMount';
3663 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
3664 foundWillMountName = 'UNSAFE_componentWillMount';
3665 }
3666
3667 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3668 foundWillReceivePropsName = 'componentWillReceiveProps';
3669 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3670 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
3671 }
3672
3673 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3674 foundWillUpdateName = 'componentWillUpdate';
3675 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3676 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
3677 }
3678
3679 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
3680 var _componentName = getComponentName(ctor) || 'Component';
3681
3682 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
3683
3684 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
3685 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
3686
3687 error('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 : '');
3688 }
3689 }
3690 }
3691 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
3692 // ReactFiberContext usually updates this cache but can't for newly-created instances.
3693
3694
3695 if (isLegacyContextConsumer) {
3696 cacheContext(workInProgress, unmaskedContext, context);
3697 }
3698
3699 return instance;
3700}
3701
3702function callComponentWillMount(workInProgress, instance) {
3703 startPhaseTimer(workInProgress, 'componentWillMount');
3704 var oldState = instance.state;
3705
3706 if (typeof instance.componentWillMount === 'function') {
3707 instance.componentWillMount();
3708 }
3709
3710 if (typeof instance.UNSAFE_componentWillMount === 'function') {
3711 instance.UNSAFE_componentWillMount();
3712 }
3713
3714 stopPhaseTimer();
3715
3716 if (oldState !== instance.state) {
3717 {
3718 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
3719 }
3720
3721 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
3722 }
3723}
3724
3725function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
3726 var oldState = instance.state;
3727 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
3728
3729 if (typeof instance.componentWillReceiveProps === 'function') {
3730 instance.componentWillReceiveProps(newProps, nextContext);
3731 }
3732
3733 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3734 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
3735 }
3736
3737 stopPhaseTimer();
3738
3739 if (instance.state !== oldState) {
3740 {
3741 var componentName = getComponentName(workInProgress.type) || 'Component';
3742
3743 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
3744 didWarnAboutStateAssignmentForComponent.add(componentName);
3745
3746 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
3747 }
3748 }
3749
3750 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
3751 }
3752} // Invokes the mount life-cycles on a previously never rendered instance.
3753
3754
3755function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
3756 {
3757 checkClassInstance(workInProgress, ctor, newProps);
3758 }
3759
3760 var instance = workInProgress.stateNode;
3761 instance.props = newProps;
3762 instance.state = workInProgress.memoizedState;
3763 instance.refs = emptyRefsObject;
3764 initializeUpdateQueue(workInProgress);
3765 var contextType = ctor.contextType;
3766
3767 if (typeof contextType === 'object' && contextType !== null) {
3768 instance.context = readContext(contextType);
3769 } else {
3770 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3771 instance.context = getMaskedContext(workInProgress, unmaskedContext);
3772 }
3773
3774 {
3775 if (instance.state === newProps) {
3776 var componentName = getComponentName(ctor) || 'Component';
3777
3778 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
3779 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
3780
3781 error('%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);
3782 }
3783 }
3784
3785 if (workInProgress.mode & StrictMode) {
3786 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
3787 }
3788
3789 {
3790 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
3791 }
3792 }
3793
3794 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
3795 instance.state = workInProgress.memoizedState;
3796 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
3797
3798 if (typeof getDerivedStateFromProps === 'function') {
3799 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
3800 instance.state = workInProgress.memoizedState;
3801 } // In order to support react-lifecycles-compat polyfilled components,
3802 // Unsafe lifecycles should not be invoked for components using the new APIs.
3803
3804
3805 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
3806 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
3807 // process them now.
3808
3809 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
3810 instance.state = workInProgress.memoizedState;
3811 }
3812
3813 if (typeof instance.componentDidMount === 'function') {
3814 workInProgress.effectTag |= Update;
3815 }
3816}
3817
3818function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
3819 var instance = workInProgress.stateNode;
3820 var oldProps = workInProgress.memoizedProps;
3821 instance.props = oldProps;
3822 var oldContext = instance.context;
3823 var contextType = ctor.contextType;
3824 var nextContext = emptyContextObject;
3825
3826 if (typeof contextType === 'object' && contextType !== null) {
3827 nextContext = readContext(contextType);
3828 } else {
3829 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3830 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
3831 }
3832
3833 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
3834 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
3835 // ever the previously attempted to render - not the "current". However,
3836 // during componentDidUpdate we pass the "current" props.
3837 // In order to support react-lifecycles-compat polyfilled components,
3838 // Unsafe lifecycles should not be invoked for components using the new APIs.
3839
3840 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
3841 if (oldProps !== newProps || oldContext !== nextContext) {
3842 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
3843 }
3844 }
3845
3846 resetHasForceUpdateBeforeProcessing();
3847 var oldState = workInProgress.memoizedState;
3848 var newState = instance.state = oldState;
3849 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
3850 newState = workInProgress.memoizedState;
3851
3852 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
3853 // If an update was already in progress, we should schedule an Update
3854 // effect even though we're bailing out, so that cWU/cDU are called.
3855 if (typeof instance.componentDidMount === 'function') {
3856 workInProgress.effectTag |= Update;
3857 }
3858
3859 return false;
3860 }
3861
3862 if (typeof getDerivedStateFromProps === 'function') {
3863 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
3864 newState = workInProgress.memoizedState;
3865 }
3866
3867 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
3868
3869 if (shouldUpdate) {
3870 // In order to support react-lifecycles-compat polyfilled components,
3871 // Unsafe lifecycles should not be invoked for components using the new APIs.
3872 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
3873 startPhaseTimer(workInProgress, 'componentWillMount');
3874
3875 if (typeof instance.componentWillMount === 'function') {
3876 instance.componentWillMount();
3877 }
3878
3879 if (typeof instance.UNSAFE_componentWillMount === 'function') {
3880 instance.UNSAFE_componentWillMount();
3881 }
3882
3883 stopPhaseTimer();
3884 }
3885
3886 if (typeof instance.componentDidMount === 'function') {
3887 workInProgress.effectTag |= Update;
3888 }
3889 } else {
3890 // If an update was already in progress, we should schedule an Update
3891 // effect even though we're bailing out, so that cWU/cDU are called.
3892 if (typeof instance.componentDidMount === 'function') {
3893 workInProgress.effectTag |= Update;
3894 } // If shouldComponentUpdate returned false, we should still update the
3895 // memoized state to indicate that this work can be reused.
3896
3897
3898 workInProgress.memoizedProps = newProps;
3899 workInProgress.memoizedState = newState;
3900 } // Update the existing instance's state, props, and context pointers even
3901 // if shouldComponentUpdate returns false.
3902
3903
3904 instance.props = newProps;
3905 instance.state = newState;
3906 instance.context = nextContext;
3907 return shouldUpdate;
3908} // Invokes the update life-cycles and returns false if it shouldn't rerender.
3909
3910
3911function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
3912 var instance = workInProgress.stateNode;
3913 cloneUpdateQueue(current, workInProgress);
3914 var oldProps = workInProgress.memoizedProps;
3915 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
3916 var oldContext = instance.context;
3917 var contextType = ctor.contextType;
3918 var nextContext = emptyContextObject;
3919
3920 if (typeof contextType === 'object' && contextType !== null) {
3921 nextContext = readContext(contextType);
3922 } else {
3923 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3924 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
3925 }
3926
3927 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
3928 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
3929 // ever the previously attempted to render - not the "current". However,
3930 // during componentDidUpdate we pass the "current" props.
3931 // In order to support react-lifecycles-compat polyfilled components,
3932 // Unsafe lifecycles should not be invoked for components using the new APIs.
3933
3934 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
3935 if (oldProps !== newProps || oldContext !== nextContext) {
3936 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
3937 }
3938 }
3939
3940 resetHasForceUpdateBeforeProcessing();
3941 var oldState = workInProgress.memoizedState;
3942 var newState = instance.state = oldState;
3943 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
3944 newState = workInProgress.memoizedState;
3945
3946 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
3947 // If an update was already in progress, we should schedule an Update
3948 // effect even though we're bailing out, so that cWU/cDU are called.
3949 if (typeof instance.componentDidUpdate === 'function') {
3950 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
3951 workInProgress.effectTag |= Update;
3952 }
3953 }
3954
3955 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
3956 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
3957 workInProgress.effectTag |= Snapshot;
3958 }
3959 }
3960
3961 return false;
3962 }
3963
3964 if (typeof getDerivedStateFromProps === 'function') {
3965 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
3966 newState = workInProgress.memoizedState;
3967 }
3968
3969 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
3970
3971 if (shouldUpdate) {
3972 // In order to support react-lifecycles-compat polyfilled components,
3973 // Unsafe lifecycles should not be invoked for components using the new APIs.
3974 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
3975 startPhaseTimer(workInProgress, 'componentWillUpdate');
3976
3977 if (typeof instance.componentWillUpdate === 'function') {
3978 instance.componentWillUpdate(newProps, newState, nextContext);
3979 }
3980
3981 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3982 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
3983 }
3984
3985 stopPhaseTimer();
3986 }
3987
3988 if (typeof instance.componentDidUpdate === 'function') {
3989 workInProgress.effectTag |= Update;
3990 }
3991
3992 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
3993 workInProgress.effectTag |= Snapshot;
3994 }
3995 } else {
3996 // If an update was already in progress, we should schedule an Update
3997 // effect even though we're bailing out, so that cWU/cDU are called.
3998 if (typeof instance.componentDidUpdate === 'function') {
3999 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4000 workInProgress.effectTag |= Update;
4001 }
4002 }
4003
4004 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4005 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4006 workInProgress.effectTag |= Snapshot;
4007 }
4008 } // If shouldComponentUpdate returned false, we should still update the
4009 // memoized props/state to indicate that this work can be reused.
4010
4011
4012 workInProgress.memoizedProps = newProps;
4013 workInProgress.memoizedState = newState;
4014 } // Update the existing instance's state, props, and context pointers even
4015 // if shouldComponentUpdate returns false.
4016
4017
4018 instance.props = newProps;
4019 instance.state = newState;
4020 instance.context = nextContext;
4021 return shouldUpdate;
4022}
4023
4024var didWarnAboutMaps;
4025var didWarnAboutGenerators;
4026var didWarnAboutStringRefs;
4027var ownerHasKeyUseWarning;
4028var ownerHasFunctionTypeWarning;
4029
4030var warnForMissingKey = function (child) {};
4031
4032{
4033 didWarnAboutMaps = false;
4034 didWarnAboutGenerators = false;
4035 didWarnAboutStringRefs = {};
4036 /**
4037 * Warn if there's no key explicitly set on dynamic arrays of children or
4038 * object keys are not valid. This allows us to keep track of children between
4039 * updates.
4040 */
4041
4042 ownerHasKeyUseWarning = {};
4043 ownerHasFunctionTypeWarning = {};
4044
4045 warnForMissingKey = function (child) {
4046 if (child === null || typeof child !== 'object') {
4047 return;
4048 }
4049
4050 if (!child._store || child._store.validated || child.key != null) {
4051 return;
4052 }
4053
4054 if (!(typeof child._store === 'object')) {
4055 {
4056 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
4057 }
4058 }
4059
4060 child._store.validated = true;
4061 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4062
4063 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4064 return;
4065 }
4066
4067 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4068
4069 error('Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4070 };
4071}
4072
4073var isArray$1 = Array.isArray;
4074
4075function coerceRef(returnFiber, current, element) {
4076 var mixedRef = element.ref;
4077
4078 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4079 {
4080 // TODO: Clean this up once we turn on the string ref warning for
4081 // everyone, because the strict mode case will no longer be relevant
4082 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
4083 // because these cannot be automatically converted to an arrow function
4084 // using a codemod. Therefore, we don't have to warn about string refs again.
4085 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
4086 var componentName = getComponentName(returnFiber.type) || 'Component';
4087
4088 if (!didWarnAboutStringRefs[componentName]) {
4089 {
4090 error('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));
4091 }
4092
4093 didWarnAboutStringRefs[componentName] = true;
4094 }
4095 }
4096 }
4097
4098 if (element._owner) {
4099 var owner = element._owner;
4100 var inst;
4101
4102 if (owner) {
4103 var ownerFiber = owner;
4104
4105 if (!(ownerFiber.tag === ClassComponent)) {
4106 {
4107 throw Error( "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" );
4108 }
4109 }
4110
4111 inst = ownerFiber.stateNode;
4112 }
4113
4114 if (!inst) {
4115 {
4116 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
4117 }
4118 }
4119
4120 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
4121
4122 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4123 return current.ref;
4124 }
4125
4126 var ref = function (value) {
4127 var refs = inst.refs;
4128
4129 if (refs === emptyRefsObject) {
4130 // This is a lazy pooled frozen object, so we need to initialize.
4131 refs = inst.refs = {};
4132 }
4133
4134 if (value === null) {
4135 delete refs[stringRef];
4136 } else {
4137 refs[stringRef] = value;
4138 }
4139 };
4140
4141 ref._stringRef = stringRef;
4142 return ref;
4143 } else {
4144 if (!(typeof mixedRef === 'string')) {
4145 {
4146 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
4147 }
4148 }
4149
4150 if (!element._owner) {
4151 {
4152 throw 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." );
4153 }
4154 }
4155 }
4156 }
4157
4158 return mixedRef;
4159}
4160
4161function throwOnInvalidObjectType(returnFiber, newChild) {
4162 if (returnFiber.type !== 'textarea') {
4163 var addendum = '';
4164
4165 {
4166 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4167 }
4168
4169 {
4170 {
4171 throw 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 );
4172 }
4173 }
4174 }
4175}
4176
4177function warnOnFunctionType() {
4178 {
4179 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();
4180
4181 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4182 return;
4183 }
4184
4185 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4186
4187 error('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.');
4188 }
4189} // This wrapper function exists because I expect to clone the code in each path
4190// to be able to optimize each path individually by branching early. This needs
4191// a compiler or we can do it manually. Helpers that don't need this branching
4192// live outside of this function.
4193
4194
4195function ChildReconciler(shouldTrackSideEffects) {
4196 function deleteChild(returnFiber, childToDelete) {
4197 if (!shouldTrackSideEffects) {
4198 // Noop.
4199 return;
4200 } // Deletions are added in reversed order so we add it to the front.
4201 // At this point, the return fiber's effect list is empty except for
4202 // deletions, so we can just append the deletion to the list. The remaining
4203 // effects aren't added until the complete phase. Once we implement
4204 // resuming, this may not be true.
4205
4206
4207 var last = returnFiber.lastEffect;
4208
4209 if (last !== null) {
4210 last.nextEffect = childToDelete;
4211 returnFiber.lastEffect = childToDelete;
4212 } else {
4213 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4214 }
4215
4216 childToDelete.nextEffect = null;
4217 childToDelete.effectTag = Deletion;
4218 }
4219
4220 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4221 if (!shouldTrackSideEffects) {
4222 // Noop.
4223 return null;
4224 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
4225 // assuming that after the first child we've already added everything.
4226
4227
4228 var childToDelete = currentFirstChild;
4229
4230 while (childToDelete !== null) {
4231 deleteChild(returnFiber, childToDelete);
4232 childToDelete = childToDelete.sibling;
4233 }
4234
4235 return null;
4236 }
4237
4238 function mapRemainingChildren(returnFiber, currentFirstChild) {
4239 // Add the remaining children to a temporary map so that we can find them by
4240 // keys quickly. Implicit (null) keys get added to this set with their index
4241 // instead.
4242 var existingChildren = new Map();
4243 var existingChild = currentFirstChild;
4244
4245 while (existingChild !== null) {
4246 if (existingChild.key !== null) {
4247 existingChildren.set(existingChild.key, existingChild);
4248 } else {
4249 existingChildren.set(existingChild.index, existingChild);
4250 }
4251
4252 existingChild = existingChild.sibling;
4253 }
4254
4255 return existingChildren;
4256 }
4257
4258 function useFiber(fiber, pendingProps) {
4259 // We currently set sibling to null and index to 0 here because it is easy
4260 // to forget to do before returning it. E.g. for the single child case.
4261 var clone = createWorkInProgress(fiber, pendingProps);
4262 clone.index = 0;
4263 clone.sibling = null;
4264 return clone;
4265 }
4266
4267 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4268 newFiber.index = newIndex;
4269
4270 if (!shouldTrackSideEffects) {
4271 // Noop.
4272 return lastPlacedIndex;
4273 }
4274
4275 var current = newFiber.alternate;
4276
4277 if (current !== null) {
4278 var oldIndex = current.index;
4279
4280 if (oldIndex < lastPlacedIndex) {
4281 // This is a move.
4282 newFiber.effectTag = Placement;
4283 return lastPlacedIndex;
4284 } else {
4285 // This item can stay in place.
4286 return oldIndex;
4287 }
4288 } else {
4289 // This is an insertion.
4290 newFiber.effectTag = Placement;
4291 return lastPlacedIndex;
4292 }
4293 }
4294
4295 function placeSingleChild(newFiber) {
4296 // This is simpler for the single child case. We only need to do a
4297 // placement for inserting new children.
4298 if (shouldTrackSideEffects && newFiber.alternate === null) {
4299 newFiber.effectTag = Placement;
4300 }
4301
4302 return newFiber;
4303 }
4304
4305 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4306 if (current === null || current.tag !== HostText) {
4307 // Insert
4308 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4309 created.return = returnFiber;
4310 return created;
4311 } else {
4312 // Update
4313 var existing = useFiber(current, textContent);
4314 existing.return = returnFiber;
4315 return existing;
4316 }
4317 }
4318
4319 function updateElement(returnFiber, current, element, expirationTime) {
4320 if (current !== null) {
4321 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
4322 isCompatibleFamilyForHotReloading(current, element) )) {
4323 // Move based on index
4324 var existing = useFiber(current, element.props);
4325 existing.ref = coerceRef(returnFiber, current, element);
4326 existing.return = returnFiber;
4327
4328 {
4329 existing._debugSource = element._source;
4330 existing._debugOwner = element._owner;
4331 }
4332
4333 return existing;
4334 }
4335 } // Insert
4336
4337
4338 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4339 created.ref = coerceRef(returnFiber, current, element);
4340 created.return = returnFiber;
4341 return created;
4342 }
4343
4344 function updatePortal(returnFiber, current, portal, expirationTime) {
4345 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4346 // Insert
4347 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4348 created.return = returnFiber;
4349 return created;
4350 } else {
4351 // Update
4352 var existing = useFiber(current, portal.children || []);
4353 existing.return = returnFiber;
4354 return existing;
4355 }
4356 }
4357
4358 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4359 if (current === null || current.tag !== Fragment) {
4360 // Insert
4361 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4362 created.return = returnFiber;
4363 return created;
4364 } else {
4365 // Update
4366 var existing = useFiber(current, fragment);
4367 existing.return = returnFiber;
4368 return existing;
4369 }
4370 }
4371
4372 function createChild(returnFiber, newChild, expirationTime) {
4373 if (typeof newChild === 'string' || typeof newChild === 'number') {
4374 // Text nodes don't have keys. If the previous node is implicitly keyed
4375 // we can continue to replace it without aborting even if it is not a text
4376 // node.
4377 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4378 created.return = returnFiber;
4379 return created;
4380 }
4381
4382 if (typeof newChild === 'object' && newChild !== null) {
4383 switch (newChild.$$typeof) {
4384 case REACT_ELEMENT_TYPE:
4385 {
4386 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4387
4388 _created.ref = coerceRef(returnFiber, null, newChild);
4389 _created.return = returnFiber;
4390 return _created;
4391 }
4392
4393 case REACT_PORTAL_TYPE:
4394 {
4395 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4396
4397 _created2.return = returnFiber;
4398 return _created2;
4399 }
4400 }
4401
4402 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4403 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4404
4405 _created3.return = returnFiber;
4406 return _created3;
4407 }
4408
4409 throwOnInvalidObjectType(returnFiber, newChild);
4410 }
4411
4412 {
4413 if (typeof newChild === 'function') {
4414 warnOnFunctionType();
4415 }
4416 }
4417
4418 return null;
4419 }
4420
4421 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4422 // Update the fiber if the keys match, otherwise return null.
4423 var key = oldFiber !== null ? oldFiber.key : null;
4424
4425 if (typeof newChild === 'string' || typeof newChild === 'number') {
4426 // Text nodes don't have keys. If the previous node is implicitly keyed
4427 // we can continue to replace it without aborting even if it is not a text
4428 // node.
4429 if (key !== null) {
4430 return null;
4431 }
4432
4433 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4434 }
4435
4436 if (typeof newChild === 'object' && newChild !== null) {
4437 switch (newChild.$$typeof) {
4438 case REACT_ELEMENT_TYPE:
4439 {
4440 if (newChild.key === key) {
4441 if (newChild.type === REACT_FRAGMENT_TYPE) {
4442 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4443 }
4444
4445 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4446 } else {
4447 return null;
4448 }
4449 }
4450
4451 case REACT_PORTAL_TYPE:
4452 {
4453 if (newChild.key === key) {
4454 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4455 } else {
4456 return null;
4457 }
4458 }
4459 }
4460
4461 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4462 if (key !== null) {
4463 return null;
4464 }
4465
4466 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4467 }
4468
4469 throwOnInvalidObjectType(returnFiber, newChild);
4470 }
4471
4472 {
4473 if (typeof newChild === 'function') {
4474 warnOnFunctionType();
4475 }
4476 }
4477
4478 return null;
4479 }
4480
4481 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4482 if (typeof newChild === 'string' || typeof newChild === 'number') {
4483 // Text nodes don't have keys, so we neither have to check the old nor
4484 // new node for the key. If both are text nodes, they match.
4485 var matchedFiber = existingChildren.get(newIdx) || null;
4486 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4487 }
4488
4489 if (typeof newChild === 'object' && newChild !== null) {
4490 switch (newChild.$$typeof) {
4491 case REACT_ELEMENT_TYPE:
4492 {
4493 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4494
4495 if (newChild.type === REACT_FRAGMENT_TYPE) {
4496 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4497 }
4498
4499 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4500 }
4501
4502 case REACT_PORTAL_TYPE:
4503 {
4504 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4505
4506 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4507 }
4508 }
4509
4510 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4511 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4512
4513 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4514 }
4515
4516 throwOnInvalidObjectType(returnFiber, newChild);
4517 }
4518
4519 {
4520 if (typeof newChild === 'function') {
4521 warnOnFunctionType();
4522 }
4523 }
4524
4525 return null;
4526 }
4527 /**
4528 * Warns if there is a duplicate or missing key
4529 */
4530
4531
4532 function warnOnInvalidKey(child, knownKeys) {
4533 {
4534 if (typeof child !== 'object' || child === null) {
4535 return knownKeys;
4536 }
4537
4538 switch (child.$$typeof) {
4539 case REACT_ELEMENT_TYPE:
4540 case REACT_PORTAL_TYPE:
4541 warnForMissingKey(child);
4542 var key = child.key;
4543
4544 if (typeof key !== 'string') {
4545 break;
4546 }
4547
4548 if (knownKeys === null) {
4549 knownKeys = new Set();
4550 knownKeys.add(key);
4551 break;
4552 }
4553
4554 if (!knownKeys.has(key)) {
4555 knownKeys.add(key);
4556 break;
4557 }
4558
4559 error('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);
4560
4561 break;
4562 }
4563 }
4564
4565 return knownKeys;
4566 }
4567
4568 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4569 // This algorithm can't optimize by searching from both ends since we
4570 // don't have backpointers on fibers. I'm trying to see how far we can get
4571 // with that model. If it ends up not being worth the tradeoffs, we can
4572 // add it later.
4573 // Even with a two ended optimization, we'd want to optimize for the case
4574 // where there are few changes and brute force the comparison instead of
4575 // going for the Map. It'd like to explore hitting that path first in
4576 // forward-only mode and only go for the Map once we notice that we need
4577 // lots of look ahead. This doesn't handle reversal as well as two ended
4578 // search but that's unusual. Besides, for the two ended optimization to
4579 // work on Iterables, we'd need to copy the whole set.
4580 // In this first iteration, we'll just live with hitting the bad case
4581 // (adding everything to a Map) in for every insert/move.
4582 // If you change this code, also update reconcileChildrenIterator() which
4583 // uses the same algorithm.
4584 {
4585 // First, validate keys.
4586 var knownKeys = null;
4587
4588 for (var i = 0; i < newChildren.length; i++) {
4589 var child = newChildren[i];
4590 knownKeys = warnOnInvalidKey(child, knownKeys);
4591 }
4592 }
4593
4594 var resultingFirstChild = null;
4595 var previousNewFiber = null;
4596 var oldFiber = currentFirstChild;
4597 var lastPlacedIndex = 0;
4598 var newIdx = 0;
4599 var nextOldFiber = null;
4600
4601 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4602 if (oldFiber.index > newIdx) {
4603 nextOldFiber = oldFiber;
4604 oldFiber = null;
4605 } else {
4606 nextOldFiber = oldFiber.sibling;
4607 }
4608
4609 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4610
4611 if (newFiber === null) {
4612 // TODO: This breaks on empty slots like null children. That's
4613 // unfortunate because it triggers the slow path all the time. We need
4614 // a better way to communicate whether this was a miss or null,
4615 // boolean, undefined, etc.
4616 if (oldFiber === null) {
4617 oldFiber = nextOldFiber;
4618 }
4619
4620 break;
4621 }
4622
4623 if (shouldTrackSideEffects) {
4624 if (oldFiber && newFiber.alternate === null) {
4625 // We matched the slot, but we didn't reuse the existing fiber, so we
4626 // need to delete the existing child.
4627 deleteChild(returnFiber, oldFiber);
4628 }
4629 }
4630
4631 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4632
4633 if (previousNewFiber === null) {
4634 // TODO: Move out of the loop. This only happens for the first run.
4635 resultingFirstChild = newFiber;
4636 } else {
4637 // TODO: Defer siblings if we're not at the right index for this slot.
4638 // I.e. if we had null values before, then we want to defer this
4639 // for each null value. However, we also don't want to call updateSlot
4640 // with the previous one.
4641 previousNewFiber.sibling = newFiber;
4642 }
4643
4644 previousNewFiber = newFiber;
4645 oldFiber = nextOldFiber;
4646 }
4647
4648 if (newIdx === newChildren.length) {
4649 // We've reached the end of the new children. We can delete the rest.
4650 deleteRemainingChildren(returnFiber, oldFiber);
4651 return resultingFirstChild;
4652 }
4653
4654 if (oldFiber === null) {
4655 // If we don't have any more existing children we can choose a fast path
4656 // since the rest will all be insertions.
4657 for (; newIdx < newChildren.length; newIdx++) {
4658 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
4659
4660 if (_newFiber === null) {
4661 continue;
4662 }
4663
4664 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
4665
4666 if (previousNewFiber === null) {
4667 // TODO: Move out of the loop. This only happens for the first run.
4668 resultingFirstChild = _newFiber;
4669 } else {
4670 previousNewFiber.sibling = _newFiber;
4671 }
4672
4673 previousNewFiber = _newFiber;
4674 }
4675
4676 return resultingFirstChild;
4677 } // Add all children to a key map for quick lookups.
4678
4679
4680 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
4681
4682 for (; newIdx < newChildren.length; newIdx++) {
4683 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
4684
4685 if (_newFiber2 !== null) {
4686 if (shouldTrackSideEffects) {
4687 if (_newFiber2.alternate !== null) {
4688 // The new fiber is a work in progress, but if there exists a
4689 // current, that means that we reused the fiber. We need to delete
4690 // it from the child list so that we don't add it to the deletion
4691 // list.
4692 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
4693 }
4694 }
4695
4696 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
4697
4698 if (previousNewFiber === null) {
4699 resultingFirstChild = _newFiber2;
4700 } else {
4701 previousNewFiber.sibling = _newFiber2;
4702 }
4703
4704 previousNewFiber = _newFiber2;
4705 }
4706 }
4707
4708 if (shouldTrackSideEffects) {
4709 // Any existing children that weren't consumed above were deleted. We need
4710 // to add them to the deletion list.
4711 existingChildren.forEach(function (child) {
4712 return deleteChild(returnFiber, child);
4713 });
4714 }
4715
4716 return resultingFirstChild;
4717 }
4718
4719 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
4720 // This is the same implementation as reconcileChildrenArray(),
4721 // but using the iterator instead.
4722 var iteratorFn = getIteratorFn(newChildrenIterable);
4723
4724 if (!(typeof iteratorFn === 'function')) {
4725 {
4726 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
4727 }
4728 }
4729
4730 {
4731 // We don't support rendering Generators because it's a mutation.
4732 // See https://github.com/facebook/react/issues/12995
4733 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
4734 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
4735 if (!didWarnAboutGenerators) {
4736 error('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.');
4737 }
4738
4739 didWarnAboutGenerators = true;
4740 } // Warn about using Maps as children
4741
4742
4743 if (newChildrenIterable.entries === iteratorFn) {
4744 if (!didWarnAboutMaps) {
4745 error('Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.');
4746 }
4747
4748 didWarnAboutMaps = true;
4749 } // First, validate keys.
4750 // We'll get a different iterator later for the main pass.
4751
4752
4753 var _newChildren = iteratorFn.call(newChildrenIterable);
4754
4755 if (_newChildren) {
4756 var knownKeys = null;
4757
4758 var _step = _newChildren.next();
4759
4760 for (; !_step.done; _step = _newChildren.next()) {
4761 var child = _step.value;
4762 knownKeys = warnOnInvalidKey(child, knownKeys);
4763 }
4764 }
4765 }
4766
4767 var newChildren = iteratorFn.call(newChildrenIterable);
4768
4769 if (!(newChildren != null)) {
4770 {
4771 throw Error( "An iterable object provided no iterator." );
4772 }
4773 }
4774
4775 var resultingFirstChild = null;
4776 var previousNewFiber = null;
4777 var oldFiber = currentFirstChild;
4778 var lastPlacedIndex = 0;
4779 var newIdx = 0;
4780 var nextOldFiber = null;
4781 var step = newChildren.next();
4782
4783 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
4784 if (oldFiber.index > newIdx) {
4785 nextOldFiber = oldFiber;
4786 oldFiber = null;
4787 } else {
4788 nextOldFiber = oldFiber.sibling;
4789 }
4790
4791 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
4792
4793 if (newFiber === null) {
4794 // TODO: This breaks on empty slots like null children. That's
4795 // unfortunate because it triggers the slow path all the time. We need
4796 // a better way to communicate whether this was a miss or null,
4797 // boolean, undefined, etc.
4798 if (oldFiber === null) {
4799 oldFiber = nextOldFiber;
4800 }
4801
4802 break;
4803 }
4804
4805 if (shouldTrackSideEffects) {
4806 if (oldFiber && newFiber.alternate === null) {
4807 // We matched the slot, but we didn't reuse the existing fiber, so we
4808 // need to delete the existing child.
4809 deleteChild(returnFiber, oldFiber);
4810 }
4811 }
4812
4813 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4814
4815 if (previousNewFiber === null) {
4816 // TODO: Move out of the loop. This only happens for the first run.
4817 resultingFirstChild = newFiber;
4818 } else {
4819 // TODO: Defer siblings if we're not at the right index for this slot.
4820 // I.e. if we had null values before, then we want to defer this
4821 // for each null value. However, we also don't want to call updateSlot
4822 // with the previous one.
4823 previousNewFiber.sibling = newFiber;
4824 }
4825
4826 previousNewFiber = newFiber;
4827 oldFiber = nextOldFiber;
4828 }
4829
4830 if (step.done) {
4831 // We've reached the end of the new children. We can delete the rest.
4832 deleteRemainingChildren(returnFiber, oldFiber);
4833 return resultingFirstChild;
4834 }
4835
4836 if (oldFiber === null) {
4837 // If we don't have any more existing children we can choose a fast path
4838 // since the rest will all be insertions.
4839 for (; !step.done; newIdx++, step = newChildren.next()) {
4840 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
4841
4842 if (_newFiber3 === null) {
4843 continue;
4844 }
4845
4846 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
4847
4848 if (previousNewFiber === null) {
4849 // TODO: Move out of the loop. This only happens for the first run.
4850 resultingFirstChild = _newFiber3;
4851 } else {
4852 previousNewFiber.sibling = _newFiber3;
4853 }
4854
4855 previousNewFiber = _newFiber3;
4856 }
4857
4858 return resultingFirstChild;
4859 } // Add all children to a key map for quick lookups.
4860
4861
4862 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
4863
4864 for (; !step.done; newIdx++, step = newChildren.next()) {
4865 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
4866
4867 if (_newFiber4 !== null) {
4868 if (shouldTrackSideEffects) {
4869 if (_newFiber4.alternate !== null) {
4870 // The new fiber is a work in progress, but if there exists a
4871 // current, that means that we reused the fiber. We need to delete
4872 // it from the child list so that we don't add it to the deletion
4873 // list.
4874 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
4875 }
4876 }
4877
4878 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
4879
4880 if (previousNewFiber === null) {
4881 resultingFirstChild = _newFiber4;
4882 } else {
4883 previousNewFiber.sibling = _newFiber4;
4884 }
4885
4886 previousNewFiber = _newFiber4;
4887 }
4888 }
4889
4890 if (shouldTrackSideEffects) {
4891 // Any existing children that weren't consumed above were deleted. We need
4892 // to add them to the deletion list.
4893 existingChildren.forEach(function (child) {
4894 return deleteChild(returnFiber, child);
4895 });
4896 }
4897
4898 return resultingFirstChild;
4899 }
4900
4901 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
4902 // There's no need to check for keys on text nodes since we don't have a
4903 // way to define them.
4904 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
4905 // We already have an existing node so let's just update it and delete
4906 // the rest.
4907 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
4908 var existing = useFiber(currentFirstChild, textContent);
4909 existing.return = returnFiber;
4910 return existing;
4911 } // The existing first child is not a text node so we need to create one
4912 // and delete the existing ones.
4913
4914
4915 deleteRemainingChildren(returnFiber, currentFirstChild);
4916 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4917 created.return = returnFiber;
4918 return created;
4919 }
4920
4921 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
4922 var key = element.key;
4923 var child = currentFirstChild;
4924
4925 while (child !== null) {
4926 // TODO: If key === null and child.key === null, then this only applies to
4927 // the first item in the list.
4928 if (child.key === key) {
4929 switch (child.tag) {
4930 case Fragment:
4931 {
4932 if (element.type === REACT_FRAGMENT_TYPE) {
4933 deleteRemainingChildren(returnFiber, child.sibling);
4934 var existing = useFiber(child, element.props.children);
4935 existing.return = returnFiber;
4936
4937 {
4938 existing._debugSource = element._source;
4939 existing._debugOwner = element._owner;
4940 }
4941
4942 return existing;
4943 }
4944
4945 break;
4946 }
4947
4948 case Block:
4949
4950 // We intentionally fallthrough here if enableBlocksAPI is not on.
4951 // eslint-disable-next-lined no-fallthrough
4952
4953 default:
4954 {
4955 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
4956 isCompatibleFamilyForHotReloading(child, element) )) {
4957 deleteRemainingChildren(returnFiber, child.sibling);
4958
4959 var _existing3 = useFiber(child, element.props);
4960
4961 _existing3.ref = coerceRef(returnFiber, child, element);
4962 _existing3.return = returnFiber;
4963
4964 {
4965 _existing3._debugSource = element._source;
4966 _existing3._debugOwner = element._owner;
4967 }
4968
4969 return _existing3;
4970 }
4971
4972 break;
4973 }
4974 } // Didn't match.
4975
4976
4977 deleteRemainingChildren(returnFiber, child);
4978 break;
4979 } else {
4980 deleteChild(returnFiber, child);
4981 }
4982
4983 child = child.sibling;
4984 }
4985
4986 if (element.type === REACT_FRAGMENT_TYPE) {
4987 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
4988 created.return = returnFiber;
4989 return created;
4990 } else {
4991 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
4992
4993 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
4994 _created4.return = returnFiber;
4995 return _created4;
4996 }
4997 }
4998
4999 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5000 var key = portal.key;
5001 var child = currentFirstChild;
5002
5003 while (child !== null) {
5004 // TODO: If key === null and child.key === null, then this only applies to
5005 // the first item in the list.
5006 if (child.key === key) {
5007 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5008 deleteRemainingChildren(returnFiber, child.sibling);
5009 var existing = useFiber(child, portal.children || []);
5010 existing.return = returnFiber;
5011 return existing;
5012 } else {
5013 deleteRemainingChildren(returnFiber, child);
5014 break;
5015 }
5016 } else {
5017 deleteChild(returnFiber, child);
5018 }
5019
5020 child = child.sibling;
5021 }
5022
5023 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5024 created.return = returnFiber;
5025 return created;
5026 } // This API will tag the children with the side-effect of the reconciliation
5027 // itself. They will be added to the side-effect list as we pass through the
5028 // children and the parent.
5029
5030
5031 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5032 // This function is not recursive.
5033 // If the top level item is an array, we treat it as a set of children,
5034 // not as a fragment. Nested arrays on the other hand will be treated as
5035 // fragment nodes. Recursion happens at the normal flow.
5036 // Handle top level unkeyed fragments as if they were arrays.
5037 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5038 // We treat the ambiguous cases above the same.
5039 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5040
5041 if (isUnkeyedTopLevelFragment) {
5042 newChild = newChild.props.children;
5043 } // Handle object types
5044
5045
5046 var isObject = typeof newChild === 'object' && newChild !== null;
5047
5048 if (isObject) {
5049 switch (newChild.$$typeof) {
5050 case REACT_ELEMENT_TYPE:
5051 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5052
5053 case REACT_PORTAL_TYPE:
5054 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5055 }
5056 }
5057
5058 if (typeof newChild === 'string' || typeof newChild === 'number') {
5059 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5060 }
5061
5062 if (isArray$1(newChild)) {
5063 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5064 }
5065
5066 if (getIteratorFn(newChild)) {
5067 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5068 }
5069
5070 if (isObject) {
5071 throwOnInvalidObjectType(returnFiber, newChild);
5072 }
5073
5074 {
5075 if (typeof newChild === 'function') {
5076 warnOnFunctionType();
5077 }
5078 }
5079
5080 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5081 // If the new child is undefined, and the return fiber is a composite
5082 // component, throw an error. If Fiber return types are disabled,
5083 // we already threw above.
5084 switch (returnFiber.tag) {
5085 case ClassComponent:
5086 {
5087 {
5088 var instance = returnFiber.stateNode;
5089
5090 if (instance.render._isMockFunction) {
5091 // We allow auto-mocks to proceed as if they're returning null.
5092 break;
5093 }
5094 }
5095 }
5096 // Intentionally fall through to the next case, which handles both
5097 // functions and classes
5098 // eslint-disable-next-lined no-fallthrough
5099
5100 case FunctionComponent:
5101 {
5102 var Component = returnFiber.type;
5103
5104 {
5105 {
5106 throw 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." );
5107 }
5108 }
5109 }
5110 }
5111 } // Remaining cases are all treated as empty.
5112
5113
5114 return deleteRemainingChildren(returnFiber, currentFirstChild);
5115 }
5116
5117 return reconcileChildFibers;
5118}
5119
5120var reconcileChildFibers = ChildReconciler(true);
5121var mountChildFibers = ChildReconciler(false);
5122function cloneChildFibers(current, workInProgress) {
5123 if (!(current === null || workInProgress.child === current.child)) {
5124 {
5125 throw Error( "Resuming work not yet implemented." );
5126 }
5127 }
5128
5129 if (workInProgress.child === null) {
5130 return;
5131 }
5132
5133 var currentChild = workInProgress.child;
5134 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
5135 workInProgress.child = newChild;
5136 newChild.return = workInProgress;
5137
5138 while (currentChild.sibling !== null) {
5139 currentChild = currentChild.sibling;
5140 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
5141 newChild.return = workInProgress;
5142 }
5143
5144 newChild.sibling = null;
5145} // Reset a workInProgress child set to prepare it for a second pass.
5146
5147function resetChildFibers(workInProgress, renderExpirationTime) {
5148 var child = workInProgress.child;
5149
5150 while (child !== null) {
5151 resetWorkInProgress(child, renderExpirationTime);
5152 child = child.sibling;
5153 }
5154}
5155
5156var NO_CONTEXT$1 = {};
5157var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5158var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5159var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5160
5161function requiredContext(c) {
5162 if (!(c !== NO_CONTEXT$1)) {
5163 {
5164 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
5165 }
5166 }
5167
5168 return c;
5169}
5170
5171function getRootHostContainer() {
5172 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5173 return rootInstance;
5174}
5175
5176function pushHostContainer(fiber, nextRootInstance) {
5177 // Push current root instance onto the stack;
5178 // This allows us to reset root when portals are popped.
5179 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
5180 // This enables us to pop only Fibers that provide unique contexts.
5181
5182 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
5183 // However, we can't just call getRootHostContext() and push it because
5184 // we'd have a different number of entries on the stack depending on
5185 // whether getRootHostContext() throws somewhere in renderer code or not.
5186 // So we push an empty value first. This lets us safely unwind on errors.
5187
5188 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5189 var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it.
5190
5191 pop(contextStackCursor$1, fiber);
5192 push(contextStackCursor$1, nextRootContext, fiber);
5193}
5194
5195function popHostContainer(fiber) {
5196 pop(contextStackCursor$1, fiber);
5197 pop(contextFiberStackCursor, fiber);
5198 pop(rootInstanceStackCursor, fiber);
5199}
5200
5201function getHostContext() {
5202 var context = requiredContext(contextStackCursor$1.current);
5203 return context;
5204}
5205
5206function pushHostContext(fiber) {
5207 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5208 var context = requiredContext(contextStackCursor$1.current);
5209 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
5210
5211 if (context === nextContext) {
5212 return;
5213 } // Track the context and the Fiber that provided it.
5214 // This enables us to pop only Fibers that provide unique contexts.
5215
5216
5217 push(contextFiberStackCursor, fiber, fiber);
5218 push(contextStackCursor$1, nextContext, fiber);
5219}
5220
5221function popHostContext(fiber) {
5222 // Do not pop unless this Fiber provided the current context.
5223 // pushHostContext() only pushes Fibers that provide unique contexts.
5224 if (contextFiberStackCursor.current !== fiber) {
5225 return;
5226 }
5227
5228 pop(contextStackCursor$1, fiber);
5229 pop(contextFiberStackCursor, fiber);
5230}
5231
5232var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
5233// inherited deeply down the subtree. The upper bits only affect
5234// this immediate suspense boundary and gets reset each new
5235// boundary or suspense list.
5236
5237var SubtreeSuspenseContextMask = 1; // Subtree Flags:
5238// InvisibleParentSuspenseContext indicates that one of our parent Suspense
5239// boundaries is not currently showing visible main content.
5240// Either because it is already showing a fallback or is not mounted at all.
5241// We can use this to determine if it is desirable to trigger a fallback at
5242// the parent. If not, then we might need to trigger undesirable boundaries
5243// and/or suspend the commit to avoid hiding the parent content.
5244
5245var InvisibleParentSuspenseContext = 1; // Shallow Flags:
5246// ForceSuspenseFallback can be used by SuspenseList to force newly added
5247// items into their fallback state during one of the render passes.
5248
5249var ForceSuspenseFallback = 2;
5250var suspenseStackCursor = createCursor(DefaultSuspenseContext);
5251function hasSuspenseContext(parentContext, flag) {
5252 return (parentContext & flag) !== 0;
5253}
5254function setDefaultShallowSuspenseContext(parentContext) {
5255 return parentContext & SubtreeSuspenseContextMask;
5256}
5257function setShallowSuspenseContext(parentContext, shallowContext) {
5258 return parentContext & SubtreeSuspenseContextMask | shallowContext;
5259}
5260function addSubtreeSuspenseContext(parentContext, subtreeContext) {
5261 return parentContext | subtreeContext;
5262}
5263function pushSuspenseContext(fiber, newContext) {
5264 push(suspenseStackCursor, newContext, fiber);
5265}
5266function popSuspenseContext(fiber) {
5267 pop(suspenseStackCursor, fiber);
5268}
5269
5270function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
5271 // If it was the primary children that just suspended, capture and render the
5272 // fallback. Otherwise, don't capture and bubble to the next boundary.
5273 var nextState = workInProgress.memoizedState;
5274
5275 if (nextState !== null) {
5276 if (nextState.dehydrated !== null) {
5277 // A dehydrated boundary always captures.
5278 return true;
5279 }
5280
5281 return false;
5282 }
5283
5284 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
5285
5286 if (props.fallback === undefined) {
5287 return false;
5288 } // Regular boundaries always capture.
5289
5290
5291 if (props.unstable_avoidThisFallback !== true) {
5292 return true;
5293 } // If it's a boundary we should avoid, then we prefer to bubble up to the
5294 // parent boundary if it is currently invisible.
5295
5296
5297 if (hasInvisibleParent) {
5298 return false;
5299 } // If the parent is not able to handle it, we must handle it.
5300
5301
5302 return true;
5303}
5304function findFirstSuspended(row) {
5305 var node = row;
5306
5307 while (node !== null) {
5308 if (node.tag === SuspenseComponent) {
5309 var state = node.memoizedState;
5310
5311 if (state !== null) {
5312 var dehydrated = state.dehydrated;
5313
5314 if (dehydrated === null || isSuspenseInstancePending() || isSuspenseInstanceFallback()) {
5315 return node;
5316 }
5317 }
5318 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
5319 // keep track of whether it suspended or not.
5320 node.memoizedProps.revealOrder !== undefined) {
5321 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
5322
5323 if (didSuspend) {
5324 return node;
5325 }
5326 } else if (node.child !== null) {
5327 node.child.return = node;
5328 node = node.child;
5329 continue;
5330 }
5331
5332 if (node === row) {
5333 return null;
5334 }
5335
5336 while (node.sibling === null) {
5337 if (node.return === null || node.return === row) {
5338 return null;
5339 }
5340
5341 node = node.return;
5342 }
5343
5344 node.sibling.return = node.return;
5345 node = node.sibling;
5346 }
5347
5348 return null;
5349}
5350
5351function createDeprecatedResponderListener(responder, props) {
5352 var eventResponderListener = {
5353 responder: responder,
5354 props: props
5355 };
5356
5357 {
5358 Object.freeze(eventResponderListener);
5359 }
5360
5361 return eventResponderListener;
5362}
5363
5364var HasEffect =
5365/* */
53661; // Represents the phase in which the effect (not the clean-up) fires.
5367
5368var Layout =
5369/* */
53702;
5371var Passive$1 =
5372/* */
53734;
5374
5375var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
5376 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
5377var didWarnAboutMismatchedHooksForComponent;
5378
5379{
5380 didWarnAboutMismatchedHooksForComponent = new Set();
5381}
5382
5383// These are set right before calling the component.
5384var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
5385// the work-in-progress hook.
5386
5387var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
5388// current hook list is the list that belongs to the current fiber. The
5389// work-in-progress hook list is a new list that will be added to the
5390// work-in-progress fiber.
5391
5392var currentHook = null;
5393var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
5394// does not get reset if we do another render pass; only when we're completely
5395// finished evaluating this component. This is an optimization so we know
5396// whether we need to clear render phase updates after a throw.
5397
5398var didScheduleRenderPhaseUpdate = false;
5399var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
5400
5401var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
5402// The list stores the order of hooks used during the initial render (mount).
5403// Subsequent renders (updates) reference this list.
5404
5405var hookTypesDev = null;
5406var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
5407// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
5408// When true, such Hooks will always be "remounted". Only used during hot reload.
5409
5410var ignorePreviousDependencies = false;
5411
5412function mountHookTypesDev() {
5413 {
5414 var hookName = currentHookNameInDev;
5415
5416 if (hookTypesDev === null) {
5417 hookTypesDev = [hookName];
5418 } else {
5419 hookTypesDev.push(hookName);
5420 }
5421 }
5422}
5423
5424function updateHookTypesDev() {
5425 {
5426 var hookName = currentHookNameInDev;
5427
5428 if (hookTypesDev !== null) {
5429 hookTypesUpdateIndexDev++;
5430
5431 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
5432 warnOnHookMismatchInDev(hookName);
5433 }
5434 }
5435 }
5436}
5437
5438function checkDepsAreArrayDev(deps) {
5439 {
5440 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
5441 // Verify deps, but only on mount to avoid extra checks.
5442 // It's unlikely their type would change as usually you define them inline.
5443 error('%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);
5444 }
5445 }
5446}
5447
5448function warnOnHookMismatchInDev(currentHookName) {
5449 {
5450 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5451
5452 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5453 didWarnAboutMismatchedHooksForComponent.add(componentName);
5454
5455 if (hookTypesDev !== null) {
5456 var table = '';
5457 var secondColumnStart = 30;
5458
5459 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
5460 var oldHookName = hookTypesDev[i];
5461 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
5462 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
5463 // lol @ IE not supporting String#repeat
5464
5465 while (row.length < secondColumnStart) {
5466 row += ' ';
5467 }
5468
5469 row += newHookName + '\n';
5470 table += row;
5471 }
5472
5473 error('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);
5474 }
5475 }
5476 }
5477}
5478
5479function throwInvalidHookError() {
5480 {
5481 {
5482 throw 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." );
5483 }
5484 }
5485}
5486
5487function areHookInputsEqual(nextDeps, prevDeps) {
5488 {
5489 if (ignorePreviousDependencies) {
5490 // Only true when this component is being hot reloaded.
5491 return false;
5492 }
5493 }
5494
5495 if (prevDeps === null) {
5496 {
5497 error('%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);
5498 }
5499
5500 return false;
5501 }
5502
5503 {
5504 // Don't bother comparing lengths in prod because these arrays should be
5505 // passed inline.
5506 if (nextDeps.length !== prevDeps.length) {
5507 error('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(', ') + "]");
5508 }
5509 }
5510
5511 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5512 if (objectIs(nextDeps[i], prevDeps[i])) {
5513 continue;
5514 }
5515
5516 return false;
5517 }
5518
5519 return true;
5520}
5521
5522function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderExpirationTime) {
5523 renderExpirationTime = nextRenderExpirationTime;
5524 currentlyRenderingFiber$1 = workInProgress;
5525
5526 {
5527 hookTypesDev = current !== null ? current._debugHookTypes : null;
5528 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
5529
5530 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
5531 }
5532
5533 workInProgress.memoizedState = null;
5534 workInProgress.updateQueue = null;
5535 workInProgress.expirationTime = NoWork; // The following should have already been reset
5536 // currentHook = null;
5537 // workInProgressHook = null;
5538 // didScheduleRenderPhaseUpdate = false;
5539 // TODO Warn if no hooks are used at all during mount, then some are used during update.
5540 // Currently we will identify the update render as a mount because memoizedState === null.
5541 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
5542 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
5543 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
5544 // so memoizedState would be null during updates and mounts.
5545
5546 {
5547 if (current !== null && current.memoizedState !== null) {
5548 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
5549 } else if (hookTypesDev !== null) {
5550 // This dispatcher handles an edge case where a component is updating,
5551 // but no stateful hooks have been used.
5552 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
5553 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
5554 // This dispatcher does that.
5555 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;
5556 } else {
5557 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;
5558 }
5559 }
5560
5561 var children = Component(props, secondArg); // Check if there was a render phase update
5562
5563 if (workInProgress.expirationTime === renderExpirationTime) {
5564 // Keep rendering in a loop for as long as render phase updates continue to
5565 // be scheduled. Use a counter to prevent infinite loops.
5566 var numberOfReRenders = 0;
5567
5568 do {
5569 workInProgress.expirationTime = NoWork;
5570
5571 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
5572 {
5573 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
5574 }
5575 }
5576
5577 numberOfReRenders += 1;
5578
5579 {
5580 // Even when hot reloading, allow dependencies to stabilize
5581 // after first render to prevent infinite render phase updates.
5582 ignorePreviousDependencies = false;
5583 } // Start over from the beginning of the list
5584
5585
5586 currentHook = null;
5587 workInProgressHook = null;
5588 workInProgress.updateQueue = null;
5589
5590 {
5591 // Also validate hook order for cascading updates.
5592 hookTypesUpdateIndexDev = -1;
5593 }
5594
5595 ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV ;
5596 children = Component(props, secondArg);
5597 } while (workInProgress.expirationTime === renderExpirationTime);
5598 } // We can assume the previous dispatcher is always this one, since we set it
5599 // at the beginning of the render phase and there's no re-entrancy.
5600
5601
5602 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
5603
5604 {
5605 workInProgress._debugHookTypes = hookTypesDev;
5606 } // This check uses currentHook so that it works the same in DEV and prod bundles.
5607 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
5608
5609
5610 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5611 renderExpirationTime = NoWork;
5612 currentlyRenderingFiber$1 = null;
5613 currentHook = null;
5614 workInProgressHook = null;
5615
5616 {
5617 currentHookNameInDev = null;
5618 hookTypesDev = null;
5619 hookTypesUpdateIndexDev = -1;
5620 }
5621
5622 didScheduleRenderPhaseUpdate = false;
5623
5624 if (!!didRenderTooFewHooks) {
5625 {
5626 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
5627 }
5628 }
5629
5630 return children;
5631}
5632function bailoutHooks(current, workInProgress, expirationTime) {
5633 workInProgress.updateQueue = current.updateQueue;
5634 workInProgress.effectTag &= ~(Passive | Update);
5635
5636 if (current.expirationTime <= expirationTime) {
5637 current.expirationTime = NoWork;
5638 }
5639}
5640function resetHooksAfterThrow() {
5641 // We can assume the previous dispatcher is always this one, since we set it
5642 // at the beginning of the render phase and there's no re-entrancy.
5643 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
5644
5645 if (didScheduleRenderPhaseUpdate) {
5646 // There were render phase updates. These are only valid for this render
5647 // phase, which we are now aborting. Remove the updates from the queues so
5648 // they do not persist to the next render. Do not remove updates from hooks
5649 // that weren't processed.
5650 //
5651 // Only reset the updates from the queue if it has a clone. If it does
5652 // not have a clone, that means it wasn't processed, and the updates were
5653 // scheduled before we entered the render phase.
5654 var hook = currentlyRenderingFiber$1.memoizedState;
5655
5656 while (hook !== null) {
5657 var queue = hook.queue;
5658
5659 if (queue !== null) {
5660 queue.pending = null;
5661 }
5662
5663 hook = hook.next;
5664 }
5665 }
5666
5667 renderExpirationTime = NoWork;
5668 currentlyRenderingFiber$1 = null;
5669 currentHook = null;
5670 workInProgressHook = null;
5671
5672 {
5673 hookTypesDev = null;
5674 hookTypesUpdateIndexDev = -1;
5675 currentHookNameInDev = null;
5676 }
5677
5678 didScheduleRenderPhaseUpdate = false;
5679}
5680
5681function mountWorkInProgressHook() {
5682 var hook = {
5683 memoizedState: null,
5684 baseState: null,
5685 baseQueue: null,
5686 queue: null,
5687 next: null
5688 };
5689
5690 if (workInProgressHook === null) {
5691 // This is the first hook in the list
5692 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
5693 } else {
5694 // Append to the end of the list
5695 workInProgressHook = workInProgressHook.next = hook;
5696 }
5697
5698 return workInProgressHook;
5699}
5700
5701function updateWorkInProgressHook() {
5702 // This function is used both for updates and for re-renders triggered by a
5703 // render phase update. It assumes there is either a current hook we can
5704 // clone, or a work-in-progress hook from a previous render pass that we can
5705 // use as a base. When we reach the end of the base list, we must switch to
5706 // the dispatcher used for mounts.
5707 var nextCurrentHook;
5708
5709 if (currentHook === null) {
5710 var current = currentlyRenderingFiber$1.alternate;
5711
5712 if (current !== null) {
5713 nextCurrentHook = current.memoizedState;
5714 } else {
5715 nextCurrentHook = null;
5716 }
5717 } else {
5718 nextCurrentHook = currentHook.next;
5719 }
5720
5721 var nextWorkInProgressHook;
5722
5723 if (workInProgressHook === null) {
5724 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
5725 } else {
5726 nextWorkInProgressHook = workInProgressHook.next;
5727 }
5728
5729 if (nextWorkInProgressHook !== null) {
5730 // There's already a work-in-progress. Reuse it.
5731 workInProgressHook = nextWorkInProgressHook;
5732 nextWorkInProgressHook = workInProgressHook.next;
5733 currentHook = nextCurrentHook;
5734 } else {
5735 // Clone from the current hook.
5736 if (!(nextCurrentHook !== null)) {
5737 {
5738 throw Error( "Rendered more hooks than during the previous render." );
5739 }
5740 }
5741
5742 currentHook = nextCurrentHook;
5743 var newHook = {
5744 memoizedState: currentHook.memoizedState,
5745 baseState: currentHook.baseState,
5746 baseQueue: currentHook.baseQueue,
5747 queue: currentHook.queue,
5748 next: null
5749 };
5750
5751 if (workInProgressHook === null) {
5752 // This is the first hook in the list.
5753 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
5754 } else {
5755 // Append to the end of the list.
5756 workInProgressHook = workInProgressHook.next = newHook;
5757 }
5758 }
5759
5760 return workInProgressHook;
5761}
5762
5763function createFunctionComponentUpdateQueue() {
5764 return {
5765 lastEffect: null
5766 };
5767}
5768
5769function basicStateReducer(state, action) {
5770 // $FlowFixMe: Flow doesn't like mixed types
5771 return typeof action === 'function' ? action(state) : action;
5772}
5773
5774function mountReducer(reducer, initialArg, init) {
5775 var hook = mountWorkInProgressHook();
5776 var initialState;
5777
5778 if (init !== undefined) {
5779 initialState = init(initialArg);
5780 } else {
5781 initialState = initialArg;
5782 }
5783
5784 hook.memoizedState = hook.baseState = initialState;
5785 var queue = hook.queue = {
5786 pending: null,
5787 dispatch: null,
5788 lastRenderedReducer: reducer,
5789 lastRenderedState: initialState
5790 };
5791 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
5792 return [hook.memoizedState, dispatch];
5793}
5794
5795function updateReducer(reducer, initialArg, init) {
5796 var hook = updateWorkInProgressHook();
5797 var queue = hook.queue;
5798
5799 if (!(queue !== null)) {
5800 {
5801 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
5802 }
5803 }
5804
5805 queue.lastRenderedReducer = reducer;
5806 var current = currentHook; // The last rebase update that is NOT part of the base state.
5807
5808 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
5809
5810 var pendingQueue = queue.pending;
5811
5812 if (pendingQueue !== null) {
5813 // We have new updates that haven't been processed yet.
5814 // We'll add them to the base queue.
5815 if (baseQueue !== null) {
5816 // Merge the pending queue and the base queue.
5817 var baseFirst = baseQueue.next;
5818 var pendingFirst = pendingQueue.next;
5819 baseQueue.next = pendingFirst;
5820 pendingQueue.next = baseFirst;
5821 }
5822
5823 current.baseQueue = baseQueue = pendingQueue;
5824 queue.pending = null;
5825 }
5826
5827 if (baseQueue !== null) {
5828 // We have a queue to process.
5829 var first = baseQueue.next;
5830 var newState = current.baseState;
5831 var newBaseState = null;
5832 var newBaseQueueFirst = null;
5833 var newBaseQueueLast = null;
5834 var update = first;
5835
5836 do {
5837 var updateExpirationTime = update.expirationTime;
5838
5839 if (updateExpirationTime < renderExpirationTime) {
5840 // Priority is insufficient. Skip this update. If this is the first
5841 // skipped update, the previous update/state is the new base
5842 // update/state.
5843 var clone = {
5844 expirationTime: update.expirationTime,
5845 suspenseConfig: update.suspenseConfig,
5846 action: update.action,
5847 eagerReducer: update.eagerReducer,
5848 eagerState: update.eagerState,
5849 next: null
5850 };
5851
5852 if (newBaseQueueLast === null) {
5853 newBaseQueueFirst = newBaseQueueLast = clone;
5854 newBaseState = newState;
5855 } else {
5856 newBaseQueueLast = newBaseQueueLast.next = clone;
5857 } // Update the remaining priority in the queue.
5858
5859
5860 if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) {
5861 currentlyRenderingFiber$1.expirationTime = updateExpirationTime;
5862 markUnprocessedUpdateTime(updateExpirationTime);
5863 }
5864 } else {
5865 // This update does have sufficient priority.
5866 if (newBaseQueueLast !== null) {
5867 var _clone = {
5868 expirationTime: Sync,
5869 // This update is going to be committed so we never want uncommit it.
5870 suspenseConfig: update.suspenseConfig,
5871 action: update.action,
5872 eagerReducer: update.eagerReducer,
5873 eagerState: update.eagerState,
5874 next: null
5875 };
5876 newBaseQueueLast = newBaseQueueLast.next = _clone;
5877 } // Mark the event time of this update as relevant to this render pass.
5878 // TODO: This should ideally use the true event time of this update rather than
5879 // its priority which is a derived and not reverseable value.
5880 // TODO: We should skip this update if it was already committed but currently
5881 // we have no way of detecting the difference between a committed and suspended
5882 // update here.
5883
5884
5885 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
5886
5887 if (update.eagerReducer === reducer) {
5888 // If this update was processed eagerly, and its reducer matches the
5889 // current reducer, we can use the eagerly computed state.
5890 newState = update.eagerState;
5891 } else {
5892 var action = update.action;
5893 newState = reducer(newState, action);
5894 }
5895 }
5896
5897 update = update.next;
5898 } while (update !== null && update !== first);
5899
5900 if (newBaseQueueLast === null) {
5901 newBaseState = newState;
5902 } else {
5903 newBaseQueueLast.next = newBaseQueueFirst;
5904 } // Mark that the fiber performed work, but only if the new state is
5905 // different from the current state.
5906
5907
5908 if (!objectIs(newState, hook.memoizedState)) {
5909 markWorkInProgressReceivedUpdate();
5910 }
5911
5912 hook.memoizedState = newState;
5913 hook.baseState = newBaseState;
5914 hook.baseQueue = newBaseQueueLast;
5915 queue.lastRenderedState = newState;
5916 }
5917
5918 var dispatch = queue.dispatch;
5919 return [hook.memoizedState, dispatch];
5920}
5921
5922function rerenderReducer(reducer, initialArg, init) {
5923 var hook = updateWorkInProgressHook();
5924 var queue = hook.queue;
5925
5926 if (!(queue !== null)) {
5927 {
5928 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
5929 }
5930 }
5931
5932 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
5933 // work-in-progress hook.
5934
5935 var dispatch = queue.dispatch;
5936 var lastRenderPhaseUpdate = queue.pending;
5937 var newState = hook.memoizedState;
5938
5939 if (lastRenderPhaseUpdate !== null) {
5940 // The queue doesn't persist past this render pass.
5941 queue.pending = null;
5942 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
5943 var update = firstRenderPhaseUpdate;
5944
5945 do {
5946 // Process this render phase update. We don't have to check the
5947 // priority because it will always be the same as the current
5948 // render's.
5949 var action = update.action;
5950 newState = reducer(newState, action);
5951 update = update.next;
5952 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
5953 // different from the current state.
5954
5955
5956 if (!objectIs(newState, hook.memoizedState)) {
5957 markWorkInProgressReceivedUpdate();
5958 }
5959
5960 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
5961 // the base state unless the queue is empty.
5962 // TODO: Not sure if this is the desired semantics, but it's what we
5963 // do for gDSFP. I can't remember why.
5964
5965 if (hook.baseQueue === null) {
5966 hook.baseState = newState;
5967 }
5968
5969 queue.lastRenderedState = newState;
5970 }
5971
5972 return [newState, dispatch];
5973}
5974
5975function mountState(initialState) {
5976 var hook = mountWorkInProgressHook();
5977
5978 if (typeof initialState === 'function') {
5979 // $FlowFixMe: Flow doesn't like mixed types
5980 initialState = initialState();
5981 }
5982
5983 hook.memoizedState = hook.baseState = initialState;
5984 var queue = hook.queue = {
5985 pending: null,
5986 dispatch: null,
5987 lastRenderedReducer: basicStateReducer,
5988 lastRenderedState: initialState
5989 };
5990 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
5991 return [hook.memoizedState, dispatch];
5992}
5993
5994function updateState(initialState) {
5995 return updateReducer(basicStateReducer);
5996}
5997
5998function rerenderState(initialState) {
5999 return rerenderReducer(basicStateReducer);
6000}
6001
6002function pushEffect(tag, create, destroy, deps) {
6003 var effect = {
6004 tag: tag,
6005 create: create,
6006 destroy: destroy,
6007 deps: deps,
6008 // Circular
6009 next: null
6010 };
6011 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
6012
6013 if (componentUpdateQueue === null) {
6014 componentUpdateQueue = createFunctionComponentUpdateQueue();
6015 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
6016 componentUpdateQueue.lastEffect = effect.next = effect;
6017 } else {
6018 var lastEffect = componentUpdateQueue.lastEffect;
6019
6020 if (lastEffect === null) {
6021 componentUpdateQueue.lastEffect = effect.next = effect;
6022 } else {
6023 var firstEffect = lastEffect.next;
6024 lastEffect.next = effect;
6025 effect.next = firstEffect;
6026 componentUpdateQueue.lastEffect = effect;
6027 }
6028 }
6029
6030 return effect;
6031}
6032
6033function mountRef(initialValue) {
6034 var hook = mountWorkInProgressHook();
6035 var ref = {
6036 current: initialValue
6037 };
6038
6039 {
6040 Object.seal(ref);
6041 }
6042
6043 hook.memoizedState = ref;
6044 return ref;
6045}
6046
6047function updateRef(initialValue) {
6048 var hook = updateWorkInProgressHook();
6049 return hook.memoizedState;
6050}
6051
6052function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6053 var hook = mountWorkInProgressHook();
6054 var nextDeps = deps === undefined ? null : deps;
6055 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6056 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, undefined, nextDeps);
6057}
6058
6059function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6060 var hook = updateWorkInProgressHook();
6061 var nextDeps = deps === undefined ? null : deps;
6062 var destroy = undefined;
6063
6064 if (currentHook !== null) {
6065 var prevEffect = currentHook.memoizedState;
6066 destroy = prevEffect.destroy;
6067
6068 if (nextDeps !== null) {
6069 var prevDeps = prevEffect.deps;
6070
6071 if (areHookInputsEqual(nextDeps, prevDeps)) {
6072 pushEffect(hookEffectTag, create, destroy, nextDeps);
6073 return;
6074 }
6075 }
6076 }
6077
6078 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6079 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, destroy, nextDeps);
6080}
6081
6082function mountEffect(create, deps) {
6083 {
6084 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6085 if ('undefined' !== typeof jest) {
6086 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6087 }
6088 }
6089
6090 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
6091}
6092
6093function updateEffect(create, deps) {
6094 {
6095 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6096 if ('undefined' !== typeof jest) {
6097 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6098 }
6099 }
6100
6101 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
6102}
6103
6104function mountLayoutEffect(create, deps) {
6105 return mountEffectImpl(Update, Layout, create, deps);
6106}
6107
6108function updateLayoutEffect(create, deps) {
6109 return updateEffectImpl(Update, Layout, create, deps);
6110}
6111
6112function imperativeHandleEffect(create, ref) {
6113 if (typeof ref === 'function') {
6114 var refCallback = ref;
6115
6116 var _inst = create();
6117
6118 refCallback(_inst);
6119 return function () {
6120 refCallback(null);
6121 };
6122 } else if (ref !== null && ref !== undefined) {
6123 var refObject = ref;
6124
6125 {
6126 if (!refObject.hasOwnProperty('current')) {
6127 error('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(', ') + '}');
6128 }
6129 }
6130
6131 var _inst2 = create();
6132
6133 refObject.current = _inst2;
6134 return function () {
6135 refObject.current = null;
6136 };
6137 }
6138}
6139
6140function mountImperativeHandle(ref, create, deps) {
6141 {
6142 if (typeof create !== 'function') {
6143 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6144 }
6145 } // TODO: If deps are provided, should we skip comparing the ref itself?
6146
6147
6148 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6149 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6150}
6151
6152function updateImperativeHandle(ref, create, deps) {
6153 {
6154 if (typeof create !== 'function') {
6155 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6156 }
6157 } // TODO: If deps are provided, should we skip comparing the ref itself?
6158
6159
6160 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6161 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6162}
6163
6164function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
6165 // The react-debug-hooks package injects its own implementation
6166 // so that e.g. DevTools can display custom hook values.
6167}
6168
6169var updateDebugValue = mountDebugValue;
6170
6171function mountCallback(callback, deps) {
6172 var hook = mountWorkInProgressHook();
6173 var nextDeps = deps === undefined ? null : deps;
6174 hook.memoizedState = [callback, nextDeps];
6175 return callback;
6176}
6177
6178function updateCallback(callback, deps) {
6179 var hook = updateWorkInProgressHook();
6180 var nextDeps = deps === undefined ? null : deps;
6181 var prevState = hook.memoizedState;
6182
6183 if (prevState !== null) {
6184 if (nextDeps !== null) {
6185 var prevDeps = prevState[1];
6186
6187 if (areHookInputsEqual(nextDeps, prevDeps)) {
6188 return prevState[0];
6189 }
6190 }
6191 }
6192
6193 hook.memoizedState = [callback, nextDeps];
6194 return callback;
6195}
6196
6197function mountMemo(nextCreate, deps) {
6198 var hook = mountWorkInProgressHook();
6199 var nextDeps = deps === undefined ? null : deps;
6200 var nextValue = nextCreate();
6201 hook.memoizedState = [nextValue, nextDeps];
6202 return nextValue;
6203}
6204
6205function updateMemo(nextCreate, deps) {
6206 var hook = updateWorkInProgressHook();
6207 var nextDeps = deps === undefined ? null : deps;
6208 var prevState = hook.memoizedState;
6209
6210 if (prevState !== null) {
6211 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6212 if (nextDeps !== null) {
6213 var prevDeps = prevState[1];
6214
6215 if (areHookInputsEqual(nextDeps, prevDeps)) {
6216 return prevState[0];
6217 }
6218 }
6219 }
6220
6221 var nextValue = nextCreate();
6222 hook.memoizedState = [nextValue, nextDeps];
6223 return nextValue;
6224}
6225
6226function mountDeferredValue(value, config) {
6227 var _mountState = mountState(value),
6228 prevValue = _mountState[0],
6229 setValue = _mountState[1];
6230
6231 mountEffect(function () {
6232 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6233 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6234
6235 try {
6236 setValue(value);
6237 } finally {
6238 ReactCurrentBatchConfig$1.suspense = previousConfig;
6239 }
6240 }, [value, config]);
6241 return prevValue;
6242}
6243
6244function updateDeferredValue(value, config) {
6245 var _updateState = updateState(),
6246 prevValue = _updateState[0],
6247 setValue = _updateState[1];
6248
6249 updateEffect(function () {
6250 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6251 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6252
6253 try {
6254 setValue(value);
6255 } finally {
6256 ReactCurrentBatchConfig$1.suspense = previousConfig;
6257 }
6258 }, [value, config]);
6259 return prevValue;
6260}
6261
6262function rerenderDeferredValue(value, config) {
6263 var _rerenderState = rerenderState(),
6264 prevValue = _rerenderState[0],
6265 setValue = _rerenderState[1];
6266
6267 updateEffect(function () {
6268 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6269 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6270
6271 try {
6272 setValue(value);
6273 } finally {
6274 ReactCurrentBatchConfig$1.suspense = previousConfig;
6275 }
6276 }, [value, config]);
6277 return prevValue;
6278}
6279
6280function startTransition(setPending, config, callback) {
6281 var priorityLevel = getCurrentPriorityLevel();
6282 runWithPriority(priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, function () {
6283 setPending(true);
6284 });
6285 runWithPriority(priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function () {
6286 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6287 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6288
6289 try {
6290 setPending(false);
6291 callback();
6292 } finally {
6293 ReactCurrentBatchConfig$1.suspense = previousConfig;
6294 }
6295 });
6296}
6297
6298function mountTransition(config) {
6299 var _mountState2 = mountState(false),
6300 isPending = _mountState2[0],
6301 setPending = _mountState2[1];
6302
6303 var start = mountCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6304 return [start, isPending];
6305}
6306
6307function updateTransition(config) {
6308 var _updateState2 = updateState(),
6309 isPending = _updateState2[0],
6310 setPending = _updateState2[1];
6311
6312 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6313 return [start, isPending];
6314}
6315
6316function rerenderTransition(config) {
6317 var _rerenderState2 = rerenderState(),
6318 isPending = _rerenderState2[0],
6319 setPending = _rerenderState2[1];
6320
6321 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6322 return [start, isPending];
6323}
6324
6325function dispatchAction(fiber, queue, action) {
6326 {
6327 if (typeof arguments[3] === 'function') {
6328 error("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().');
6329 }
6330 }
6331
6332 var currentTime = requestCurrentTimeForUpdate();
6333 var suspenseConfig = requestCurrentSuspenseConfig();
6334 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
6335 var update = {
6336 expirationTime: expirationTime,
6337 suspenseConfig: suspenseConfig,
6338 action: action,
6339 eagerReducer: null,
6340 eagerState: null,
6341 next: null
6342 };
6343
6344 {
6345 update.priority = getCurrentPriorityLevel();
6346 } // Append the update to the end of the list.
6347
6348
6349 var pending = queue.pending;
6350
6351 if (pending === null) {
6352 // This is the first update. Create a circular list.
6353 update.next = update;
6354 } else {
6355 update.next = pending.next;
6356 pending.next = update;
6357 }
6358
6359 queue.pending = update;
6360 var alternate = fiber.alternate;
6361
6362 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6363 // This is a render phase update. Stash it in a lazily-created map of
6364 // queue -> linked list of updates. After this render pass, we'll restart
6365 // and apply the stashed updates on top of the work-in-progress hook.
6366 didScheduleRenderPhaseUpdate = true;
6367 update.expirationTime = renderExpirationTime;
6368 currentlyRenderingFiber$1.expirationTime = renderExpirationTime;
6369 } else {
6370 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6371 // The queue is currently empty, which means we can eagerly compute the
6372 // next state before entering the render phase. If the new state is the
6373 // same as the current state, we may be able to bail out entirely.
6374 var lastRenderedReducer = queue.lastRenderedReducer;
6375
6376 if (lastRenderedReducer !== null) {
6377 var prevDispatcher;
6378
6379 {
6380 prevDispatcher = ReactCurrentDispatcher.current;
6381 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6382 }
6383
6384 try {
6385 var currentState = queue.lastRenderedState;
6386 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
6387 // it, on the update object. If the reducer hasn't changed by the
6388 // time we enter the render phase, then the eager state can be used
6389 // without calling the reducer again.
6390
6391 update.eagerReducer = lastRenderedReducer;
6392 update.eagerState = eagerState;
6393
6394 if (objectIs(eagerState, currentState)) {
6395 // Fast path. We can bail out without scheduling React to re-render.
6396 // It's still possible that we'll need to rebase this update later,
6397 // if the component re-renders for a different reason and by that
6398 // time the reducer has changed.
6399 return;
6400 }
6401 } catch (error) {// Suppress the error. It will throw again in the render phase.
6402 } finally {
6403 {
6404 ReactCurrentDispatcher.current = prevDispatcher;
6405 }
6406 }
6407 }
6408 }
6409
6410 {
6411 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6412 if ('undefined' !== typeof jest) {
6413 warnIfNotScopedWithMatchingAct(fiber);
6414 warnIfNotCurrentlyActingUpdatesInDev(fiber);
6415 }
6416 }
6417
6418 scheduleWork(fiber, expirationTime);
6419 }
6420}
6421
6422var ContextOnlyDispatcher = {
6423 readContext: readContext,
6424 useCallback: throwInvalidHookError,
6425 useContext: throwInvalidHookError,
6426 useEffect: throwInvalidHookError,
6427 useImperativeHandle: throwInvalidHookError,
6428 useLayoutEffect: throwInvalidHookError,
6429 useMemo: throwInvalidHookError,
6430 useReducer: throwInvalidHookError,
6431 useRef: throwInvalidHookError,
6432 useState: throwInvalidHookError,
6433 useDebugValue: throwInvalidHookError,
6434 useResponder: throwInvalidHookError,
6435 useDeferredValue: throwInvalidHookError,
6436 useTransition: throwInvalidHookError
6437};
6438var HooksDispatcherOnMountInDEV = null;
6439var HooksDispatcherOnMountWithHookTypesInDEV = null;
6440var HooksDispatcherOnUpdateInDEV = null;
6441var HooksDispatcherOnRerenderInDEV = null;
6442var InvalidNestedHooksDispatcherOnMountInDEV = null;
6443var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6444var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
6445
6446{
6447 var warnInvalidContextAccess = function () {
6448 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().');
6449 };
6450
6451 var warnInvalidHookAccess = function () {
6452 error('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');
6453 };
6454
6455 HooksDispatcherOnMountInDEV = {
6456 readContext: function (context, observedBits) {
6457 return readContext(context, observedBits);
6458 },
6459 useCallback: function (callback, deps) {
6460 currentHookNameInDev = 'useCallback';
6461 mountHookTypesDev();
6462 checkDepsAreArrayDev(deps);
6463 return mountCallback(callback, deps);
6464 },
6465 useContext: function (context, observedBits) {
6466 currentHookNameInDev = 'useContext';
6467 mountHookTypesDev();
6468 return readContext(context, observedBits);
6469 },
6470 useEffect: function (create, deps) {
6471 currentHookNameInDev = 'useEffect';
6472 mountHookTypesDev();
6473 checkDepsAreArrayDev(deps);
6474 return mountEffect(create, deps);
6475 },
6476 useImperativeHandle: function (ref, create, deps) {
6477 currentHookNameInDev = 'useImperativeHandle';
6478 mountHookTypesDev();
6479 checkDepsAreArrayDev(deps);
6480 return mountImperativeHandle(ref, create, deps);
6481 },
6482 useLayoutEffect: function (create, deps) {
6483 currentHookNameInDev = 'useLayoutEffect';
6484 mountHookTypesDev();
6485 checkDepsAreArrayDev(deps);
6486 return mountLayoutEffect(create, deps);
6487 },
6488 useMemo: function (create, deps) {
6489 currentHookNameInDev = 'useMemo';
6490 mountHookTypesDev();
6491 checkDepsAreArrayDev(deps);
6492 var prevDispatcher = ReactCurrentDispatcher.current;
6493 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6494
6495 try {
6496 return mountMemo(create, deps);
6497 } finally {
6498 ReactCurrentDispatcher.current = prevDispatcher;
6499 }
6500 },
6501 useReducer: function (reducer, initialArg, init) {
6502 currentHookNameInDev = 'useReducer';
6503 mountHookTypesDev();
6504 var prevDispatcher = ReactCurrentDispatcher.current;
6505 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6506
6507 try {
6508 return mountReducer(reducer, initialArg, init);
6509 } finally {
6510 ReactCurrentDispatcher.current = prevDispatcher;
6511 }
6512 },
6513 useRef: function (initialValue) {
6514 currentHookNameInDev = 'useRef';
6515 mountHookTypesDev();
6516 return mountRef(initialValue);
6517 },
6518 useState: function (initialState) {
6519 currentHookNameInDev = 'useState';
6520 mountHookTypesDev();
6521 var prevDispatcher = ReactCurrentDispatcher.current;
6522 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6523
6524 try {
6525 return mountState(initialState);
6526 } finally {
6527 ReactCurrentDispatcher.current = prevDispatcher;
6528 }
6529 },
6530 useDebugValue: function (value, formatterFn) {
6531 currentHookNameInDev = 'useDebugValue';
6532 mountHookTypesDev();
6533 return mountDebugValue();
6534 },
6535 useResponder: function (responder, props) {
6536 currentHookNameInDev = 'useResponder';
6537 mountHookTypesDev();
6538 return createDeprecatedResponderListener(responder, props);
6539 },
6540 useDeferredValue: function (value, config) {
6541 currentHookNameInDev = 'useDeferredValue';
6542 mountHookTypesDev();
6543 return mountDeferredValue(value, config);
6544 },
6545 useTransition: function (config) {
6546 currentHookNameInDev = 'useTransition';
6547 mountHookTypesDev();
6548 return mountTransition(config);
6549 }
6550 };
6551 HooksDispatcherOnMountWithHookTypesInDEV = {
6552 readContext: function (context, observedBits) {
6553 return readContext(context, observedBits);
6554 },
6555 useCallback: function (callback, deps) {
6556 currentHookNameInDev = 'useCallback';
6557 updateHookTypesDev();
6558 return mountCallback(callback, deps);
6559 },
6560 useContext: function (context, observedBits) {
6561 currentHookNameInDev = 'useContext';
6562 updateHookTypesDev();
6563 return readContext(context, observedBits);
6564 },
6565 useEffect: function (create, deps) {
6566 currentHookNameInDev = 'useEffect';
6567 updateHookTypesDev();
6568 return mountEffect(create, deps);
6569 },
6570 useImperativeHandle: function (ref, create, deps) {
6571 currentHookNameInDev = 'useImperativeHandle';
6572 updateHookTypesDev();
6573 return mountImperativeHandle(ref, create, deps);
6574 },
6575 useLayoutEffect: function (create, deps) {
6576 currentHookNameInDev = 'useLayoutEffect';
6577 updateHookTypesDev();
6578 return mountLayoutEffect(create, deps);
6579 },
6580 useMemo: function (create, deps) {
6581 currentHookNameInDev = 'useMemo';
6582 updateHookTypesDev();
6583 var prevDispatcher = ReactCurrentDispatcher.current;
6584 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6585
6586 try {
6587 return mountMemo(create, deps);
6588 } finally {
6589 ReactCurrentDispatcher.current = prevDispatcher;
6590 }
6591 },
6592 useReducer: function (reducer, initialArg, init) {
6593 currentHookNameInDev = 'useReducer';
6594 updateHookTypesDev();
6595 var prevDispatcher = ReactCurrentDispatcher.current;
6596 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6597
6598 try {
6599 return mountReducer(reducer, initialArg, init);
6600 } finally {
6601 ReactCurrentDispatcher.current = prevDispatcher;
6602 }
6603 },
6604 useRef: function (initialValue) {
6605 currentHookNameInDev = 'useRef';
6606 updateHookTypesDev();
6607 return mountRef(initialValue);
6608 },
6609 useState: function (initialState) {
6610 currentHookNameInDev = 'useState';
6611 updateHookTypesDev();
6612 var prevDispatcher = ReactCurrentDispatcher.current;
6613 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6614
6615 try {
6616 return mountState(initialState);
6617 } finally {
6618 ReactCurrentDispatcher.current = prevDispatcher;
6619 }
6620 },
6621 useDebugValue: function (value, formatterFn) {
6622 currentHookNameInDev = 'useDebugValue';
6623 updateHookTypesDev();
6624 return mountDebugValue();
6625 },
6626 useResponder: function (responder, props) {
6627 currentHookNameInDev = 'useResponder';
6628 updateHookTypesDev();
6629 return createDeprecatedResponderListener(responder, props);
6630 },
6631 useDeferredValue: function (value, config) {
6632 currentHookNameInDev = 'useDeferredValue';
6633 updateHookTypesDev();
6634 return mountDeferredValue(value, config);
6635 },
6636 useTransition: function (config) {
6637 currentHookNameInDev = 'useTransition';
6638 updateHookTypesDev();
6639 return mountTransition(config);
6640 }
6641 };
6642 HooksDispatcherOnUpdateInDEV = {
6643 readContext: function (context, observedBits) {
6644 return readContext(context, observedBits);
6645 },
6646 useCallback: function (callback, deps) {
6647 currentHookNameInDev = 'useCallback';
6648 updateHookTypesDev();
6649 return updateCallback(callback, deps);
6650 },
6651 useContext: function (context, observedBits) {
6652 currentHookNameInDev = 'useContext';
6653 updateHookTypesDev();
6654 return readContext(context, observedBits);
6655 },
6656 useEffect: function (create, deps) {
6657 currentHookNameInDev = 'useEffect';
6658 updateHookTypesDev();
6659 return updateEffect(create, deps);
6660 },
6661 useImperativeHandle: function (ref, create, deps) {
6662 currentHookNameInDev = 'useImperativeHandle';
6663 updateHookTypesDev();
6664 return updateImperativeHandle(ref, create, deps);
6665 },
6666 useLayoutEffect: function (create, deps) {
6667 currentHookNameInDev = 'useLayoutEffect';
6668 updateHookTypesDev();
6669 return updateLayoutEffect(create, deps);
6670 },
6671 useMemo: function (create, deps) {
6672 currentHookNameInDev = 'useMemo';
6673 updateHookTypesDev();
6674 var prevDispatcher = ReactCurrentDispatcher.current;
6675 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6676
6677 try {
6678 return updateMemo(create, deps);
6679 } finally {
6680 ReactCurrentDispatcher.current = prevDispatcher;
6681 }
6682 },
6683 useReducer: function (reducer, initialArg, init) {
6684 currentHookNameInDev = 'useReducer';
6685 updateHookTypesDev();
6686 var prevDispatcher = ReactCurrentDispatcher.current;
6687 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6688
6689 try {
6690 return updateReducer(reducer, initialArg, init);
6691 } finally {
6692 ReactCurrentDispatcher.current = prevDispatcher;
6693 }
6694 },
6695 useRef: function (initialValue) {
6696 currentHookNameInDev = 'useRef';
6697 updateHookTypesDev();
6698 return updateRef();
6699 },
6700 useState: function (initialState) {
6701 currentHookNameInDev = 'useState';
6702 updateHookTypesDev();
6703 var prevDispatcher = ReactCurrentDispatcher.current;
6704 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6705
6706 try {
6707 return updateState(initialState);
6708 } finally {
6709 ReactCurrentDispatcher.current = prevDispatcher;
6710 }
6711 },
6712 useDebugValue: function (value, formatterFn) {
6713 currentHookNameInDev = 'useDebugValue';
6714 updateHookTypesDev();
6715 return updateDebugValue();
6716 },
6717 useResponder: function (responder, props) {
6718 currentHookNameInDev = 'useResponder';
6719 updateHookTypesDev();
6720 return createDeprecatedResponderListener(responder, props);
6721 },
6722 useDeferredValue: function (value, config) {
6723 currentHookNameInDev = 'useDeferredValue';
6724 updateHookTypesDev();
6725 return updateDeferredValue(value, config);
6726 },
6727 useTransition: function (config) {
6728 currentHookNameInDev = 'useTransition';
6729 updateHookTypesDev();
6730 return updateTransition(config);
6731 }
6732 };
6733 HooksDispatcherOnRerenderInDEV = {
6734 readContext: function (context, observedBits) {
6735 return readContext(context, observedBits);
6736 },
6737 useCallback: function (callback, deps) {
6738 currentHookNameInDev = 'useCallback';
6739 updateHookTypesDev();
6740 return updateCallback(callback, deps);
6741 },
6742 useContext: function (context, observedBits) {
6743 currentHookNameInDev = 'useContext';
6744 updateHookTypesDev();
6745 return readContext(context, observedBits);
6746 },
6747 useEffect: function (create, deps) {
6748 currentHookNameInDev = 'useEffect';
6749 updateHookTypesDev();
6750 return updateEffect(create, deps);
6751 },
6752 useImperativeHandle: function (ref, create, deps) {
6753 currentHookNameInDev = 'useImperativeHandle';
6754 updateHookTypesDev();
6755 return updateImperativeHandle(ref, create, deps);
6756 },
6757 useLayoutEffect: function (create, deps) {
6758 currentHookNameInDev = 'useLayoutEffect';
6759 updateHookTypesDev();
6760 return updateLayoutEffect(create, deps);
6761 },
6762 useMemo: function (create, deps) {
6763 currentHookNameInDev = 'useMemo';
6764 updateHookTypesDev();
6765 var prevDispatcher = ReactCurrentDispatcher.current;
6766 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
6767
6768 try {
6769 return updateMemo(create, deps);
6770 } finally {
6771 ReactCurrentDispatcher.current = prevDispatcher;
6772 }
6773 },
6774 useReducer: function (reducer, initialArg, init) {
6775 currentHookNameInDev = 'useReducer';
6776 updateHookTypesDev();
6777 var prevDispatcher = ReactCurrentDispatcher.current;
6778 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
6779
6780 try {
6781 return rerenderReducer(reducer, initialArg, init);
6782 } finally {
6783 ReactCurrentDispatcher.current = prevDispatcher;
6784 }
6785 },
6786 useRef: function (initialValue) {
6787 currentHookNameInDev = 'useRef';
6788 updateHookTypesDev();
6789 return updateRef();
6790 },
6791 useState: function (initialState) {
6792 currentHookNameInDev = 'useState';
6793 updateHookTypesDev();
6794 var prevDispatcher = ReactCurrentDispatcher.current;
6795 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
6796
6797 try {
6798 return rerenderState(initialState);
6799 } finally {
6800 ReactCurrentDispatcher.current = prevDispatcher;
6801 }
6802 },
6803 useDebugValue: function (value, formatterFn) {
6804 currentHookNameInDev = 'useDebugValue';
6805 updateHookTypesDev();
6806 return updateDebugValue();
6807 },
6808 useResponder: function (responder, props) {
6809 currentHookNameInDev = 'useResponder';
6810 updateHookTypesDev();
6811 return createDeprecatedResponderListener(responder, props);
6812 },
6813 useDeferredValue: function (value, config) {
6814 currentHookNameInDev = 'useDeferredValue';
6815 updateHookTypesDev();
6816 return rerenderDeferredValue(value, config);
6817 },
6818 useTransition: function (config) {
6819 currentHookNameInDev = 'useTransition';
6820 updateHookTypesDev();
6821 return rerenderTransition(config);
6822 }
6823 };
6824 InvalidNestedHooksDispatcherOnMountInDEV = {
6825 readContext: function (context, observedBits) {
6826 warnInvalidContextAccess();
6827 return readContext(context, observedBits);
6828 },
6829 useCallback: function (callback, deps) {
6830 currentHookNameInDev = 'useCallback';
6831 warnInvalidHookAccess();
6832 mountHookTypesDev();
6833 return mountCallback(callback, deps);
6834 },
6835 useContext: function (context, observedBits) {
6836 currentHookNameInDev = 'useContext';
6837 warnInvalidHookAccess();
6838 mountHookTypesDev();
6839 return readContext(context, observedBits);
6840 },
6841 useEffect: function (create, deps) {
6842 currentHookNameInDev = 'useEffect';
6843 warnInvalidHookAccess();
6844 mountHookTypesDev();
6845 return mountEffect(create, deps);
6846 },
6847 useImperativeHandle: function (ref, create, deps) {
6848 currentHookNameInDev = 'useImperativeHandle';
6849 warnInvalidHookAccess();
6850 mountHookTypesDev();
6851 return mountImperativeHandle(ref, create, deps);
6852 },
6853 useLayoutEffect: function (create, deps) {
6854 currentHookNameInDev = 'useLayoutEffect';
6855 warnInvalidHookAccess();
6856 mountHookTypesDev();
6857 return mountLayoutEffect(create, deps);
6858 },
6859 useMemo: function (create, deps) {
6860 currentHookNameInDev = 'useMemo';
6861 warnInvalidHookAccess();
6862 mountHookTypesDev();
6863 var prevDispatcher = ReactCurrentDispatcher.current;
6864 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6865
6866 try {
6867 return mountMemo(create, deps);
6868 } finally {
6869 ReactCurrentDispatcher.current = prevDispatcher;
6870 }
6871 },
6872 useReducer: function (reducer, initialArg, init) {
6873 currentHookNameInDev = 'useReducer';
6874 warnInvalidHookAccess();
6875 mountHookTypesDev();
6876 var prevDispatcher = ReactCurrentDispatcher.current;
6877 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6878
6879 try {
6880 return mountReducer(reducer, initialArg, init);
6881 } finally {
6882 ReactCurrentDispatcher.current = prevDispatcher;
6883 }
6884 },
6885 useRef: function (initialValue) {
6886 currentHookNameInDev = 'useRef';
6887 warnInvalidHookAccess();
6888 mountHookTypesDev();
6889 return mountRef(initialValue);
6890 },
6891 useState: function (initialState) {
6892 currentHookNameInDev = 'useState';
6893 warnInvalidHookAccess();
6894 mountHookTypesDev();
6895 var prevDispatcher = ReactCurrentDispatcher.current;
6896 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6897
6898 try {
6899 return mountState(initialState);
6900 } finally {
6901 ReactCurrentDispatcher.current = prevDispatcher;
6902 }
6903 },
6904 useDebugValue: function (value, formatterFn) {
6905 currentHookNameInDev = 'useDebugValue';
6906 warnInvalidHookAccess();
6907 mountHookTypesDev();
6908 return mountDebugValue();
6909 },
6910 useResponder: function (responder, props) {
6911 currentHookNameInDev = 'useResponder';
6912 warnInvalidHookAccess();
6913 mountHookTypesDev();
6914 return createDeprecatedResponderListener(responder, props);
6915 },
6916 useDeferredValue: function (value, config) {
6917 currentHookNameInDev = 'useDeferredValue';
6918 warnInvalidHookAccess();
6919 mountHookTypesDev();
6920 return mountDeferredValue(value, config);
6921 },
6922 useTransition: function (config) {
6923 currentHookNameInDev = 'useTransition';
6924 warnInvalidHookAccess();
6925 mountHookTypesDev();
6926 return mountTransition(config);
6927 }
6928 };
6929 InvalidNestedHooksDispatcherOnUpdateInDEV = {
6930 readContext: function (context, observedBits) {
6931 warnInvalidContextAccess();
6932 return readContext(context, observedBits);
6933 },
6934 useCallback: function (callback, deps) {
6935 currentHookNameInDev = 'useCallback';
6936 warnInvalidHookAccess();
6937 updateHookTypesDev();
6938 return updateCallback(callback, deps);
6939 },
6940 useContext: function (context, observedBits) {
6941 currentHookNameInDev = 'useContext';
6942 warnInvalidHookAccess();
6943 updateHookTypesDev();
6944 return readContext(context, observedBits);
6945 },
6946 useEffect: function (create, deps) {
6947 currentHookNameInDev = 'useEffect';
6948 warnInvalidHookAccess();
6949 updateHookTypesDev();
6950 return updateEffect(create, deps);
6951 },
6952 useImperativeHandle: function (ref, create, deps) {
6953 currentHookNameInDev = 'useImperativeHandle';
6954 warnInvalidHookAccess();
6955 updateHookTypesDev();
6956 return updateImperativeHandle(ref, create, deps);
6957 },
6958 useLayoutEffect: function (create, deps) {
6959 currentHookNameInDev = 'useLayoutEffect';
6960 warnInvalidHookAccess();
6961 updateHookTypesDev();
6962 return updateLayoutEffect(create, deps);
6963 },
6964 useMemo: function (create, deps) {
6965 currentHookNameInDev = 'useMemo';
6966 warnInvalidHookAccess();
6967 updateHookTypesDev();
6968 var prevDispatcher = ReactCurrentDispatcher.current;
6969 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6970
6971 try {
6972 return updateMemo(create, deps);
6973 } finally {
6974 ReactCurrentDispatcher.current = prevDispatcher;
6975 }
6976 },
6977 useReducer: function (reducer, initialArg, init) {
6978 currentHookNameInDev = 'useReducer';
6979 warnInvalidHookAccess();
6980 updateHookTypesDev();
6981 var prevDispatcher = ReactCurrentDispatcher.current;
6982 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6983
6984 try {
6985 return updateReducer(reducer, initialArg, init);
6986 } finally {
6987 ReactCurrentDispatcher.current = prevDispatcher;
6988 }
6989 },
6990 useRef: function (initialValue) {
6991 currentHookNameInDev = 'useRef';
6992 warnInvalidHookAccess();
6993 updateHookTypesDev();
6994 return updateRef();
6995 },
6996 useState: function (initialState) {
6997 currentHookNameInDev = 'useState';
6998 warnInvalidHookAccess();
6999 updateHookTypesDev();
7000 var prevDispatcher = ReactCurrentDispatcher.current;
7001 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7002
7003 try {
7004 return updateState(initialState);
7005 } finally {
7006 ReactCurrentDispatcher.current = prevDispatcher;
7007 }
7008 },
7009 useDebugValue: function (value, formatterFn) {
7010 currentHookNameInDev = 'useDebugValue';
7011 warnInvalidHookAccess();
7012 updateHookTypesDev();
7013 return updateDebugValue();
7014 },
7015 useResponder: function (responder, props) {
7016 currentHookNameInDev = 'useResponder';
7017 warnInvalidHookAccess();
7018 updateHookTypesDev();
7019 return createDeprecatedResponderListener(responder, props);
7020 },
7021 useDeferredValue: function (value, config) {
7022 currentHookNameInDev = 'useDeferredValue';
7023 warnInvalidHookAccess();
7024 updateHookTypesDev();
7025 return updateDeferredValue(value, config);
7026 },
7027 useTransition: function (config) {
7028 currentHookNameInDev = 'useTransition';
7029 warnInvalidHookAccess();
7030 updateHookTypesDev();
7031 return updateTransition(config);
7032 }
7033 };
7034 InvalidNestedHooksDispatcherOnRerenderInDEV = {
7035 readContext: function (context, observedBits) {
7036 warnInvalidContextAccess();
7037 return readContext(context, observedBits);
7038 },
7039 useCallback: function (callback, deps) {
7040 currentHookNameInDev = 'useCallback';
7041 warnInvalidHookAccess();
7042 updateHookTypesDev();
7043 return updateCallback(callback, deps);
7044 },
7045 useContext: function (context, observedBits) {
7046 currentHookNameInDev = 'useContext';
7047 warnInvalidHookAccess();
7048 updateHookTypesDev();
7049 return readContext(context, observedBits);
7050 },
7051 useEffect: function (create, deps) {
7052 currentHookNameInDev = 'useEffect';
7053 warnInvalidHookAccess();
7054 updateHookTypesDev();
7055 return updateEffect(create, deps);
7056 },
7057 useImperativeHandle: function (ref, create, deps) {
7058 currentHookNameInDev = 'useImperativeHandle';
7059 warnInvalidHookAccess();
7060 updateHookTypesDev();
7061 return updateImperativeHandle(ref, create, deps);
7062 },
7063 useLayoutEffect: function (create, deps) {
7064 currentHookNameInDev = 'useLayoutEffect';
7065 warnInvalidHookAccess();
7066 updateHookTypesDev();
7067 return updateLayoutEffect(create, deps);
7068 },
7069 useMemo: function (create, deps) {
7070 currentHookNameInDev = 'useMemo';
7071 warnInvalidHookAccess();
7072 updateHookTypesDev();
7073 var prevDispatcher = ReactCurrentDispatcher.current;
7074 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7075
7076 try {
7077 return updateMemo(create, deps);
7078 } finally {
7079 ReactCurrentDispatcher.current = prevDispatcher;
7080 }
7081 },
7082 useReducer: function (reducer, initialArg, init) {
7083 currentHookNameInDev = 'useReducer';
7084 warnInvalidHookAccess();
7085 updateHookTypesDev();
7086 var prevDispatcher = ReactCurrentDispatcher.current;
7087 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7088
7089 try {
7090 return rerenderReducer(reducer, initialArg, init);
7091 } finally {
7092 ReactCurrentDispatcher.current = prevDispatcher;
7093 }
7094 },
7095 useRef: function (initialValue) {
7096 currentHookNameInDev = 'useRef';
7097 warnInvalidHookAccess();
7098 updateHookTypesDev();
7099 return updateRef();
7100 },
7101 useState: function (initialState) {
7102 currentHookNameInDev = 'useState';
7103 warnInvalidHookAccess();
7104 updateHookTypesDev();
7105 var prevDispatcher = ReactCurrentDispatcher.current;
7106 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7107
7108 try {
7109 return rerenderState(initialState);
7110 } finally {
7111 ReactCurrentDispatcher.current = prevDispatcher;
7112 }
7113 },
7114 useDebugValue: function (value, formatterFn) {
7115 currentHookNameInDev = 'useDebugValue';
7116 warnInvalidHookAccess();
7117 updateHookTypesDev();
7118 return updateDebugValue();
7119 },
7120 useResponder: function (responder, props) {
7121 currentHookNameInDev = 'useResponder';
7122 warnInvalidHookAccess();
7123 updateHookTypesDev();
7124 return createDeprecatedResponderListener(responder, props);
7125 },
7126 useDeferredValue: function (value, config) {
7127 currentHookNameInDev = 'useDeferredValue';
7128 warnInvalidHookAccess();
7129 updateHookTypesDev();
7130 return rerenderDeferredValue(value, config);
7131 },
7132 useTransition: function (config) {
7133 currentHookNameInDev = 'useTransition';
7134 warnInvalidHookAccess();
7135 updateHookTypesDev();
7136 return rerenderTransition(config);
7137 }
7138 };
7139}
7140
7141var now$1 = Scheduler$1.unstable_now;
7142var commitTime = 0;
7143var profilerStartTime = -1;
7144
7145function getCommitTime() {
7146 return commitTime;
7147}
7148
7149function recordCommitTime() {
7150
7151 commitTime = now$1();
7152}
7153
7154function startProfilerTimer(fiber) {
7155
7156 profilerStartTime = now$1();
7157
7158 if (fiber.actualStartTime < 0) {
7159 fiber.actualStartTime = now$1();
7160 }
7161}
7162
7163function stopProfilerTimerIfRunning(fiber) {
7164
7165 profilerStartTime = -1;
7166}
7167
7168function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
7169
7170 if (profilerStartTime >= 0) {
7171 var elapsedTime = now$1() - profilerStartTime;
7172 fiber.actualDuration += elapsedTime;
7173
7174 if (overrideBaseTime) {
7175 fiber.selfBaseDuration = elapsedTime;
7176 }
7177
7178 profilerStartTime = -1;
7179 }
7180}
7181
7182function enterHydrationState(fiber) {
7183 {
7184 return false;
7185 }
7186}
7187
7188function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
7189 {
7190 {
7191 {
7192 throw Error( "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7193 }
7194 }
7195 }
7196}
7197
7198function prepareToHydrateHostTextInstance(fiber) {
7199 {
7200 {
7201 {
7202 throw Error( "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7203 }
7204 }
7205 }
7206 var shouldUpdate = hydrateTextInstance();
7207}
7208
7209function popHydrationState(fiber) {
7210 {
7211 return false;
7212 }
7213}
7214
7215var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
7216var didReceiveUpdate = false;
7217var didWarnAboutBadClass;
7218var didWarnAboutModulePatternComponent;
7219var didWarnAboutContextTypeOnFunctionComponent;
7220var didWarnAboutGetDerivedStateOnFunctionComponent;
7221var didWarnAboutFunctionRefs;
7222var didWarnAboutReassigningProps;
7223var didWarnAboutMaxDuration;
7224var didWarnAboutRevealOrder;
7225var didWarnAboutTailOptions;
7226
7227{
7228 didWarnAboutBadClass = {};
7229 didWarnAboutModulePatternComponent = {};
7230 didWarnAboutContextTypeOnFunctionComponent = {};
7231 didWarnAboutGetDerivedStateOnFunctionComponent = {};
7232 didWarnAboutFunctionRefs = {};
7233 didWarnAboutReassigningProps = false;
7234 didWarnAboutMaxDuration = false;
7235 didWarnAboutRevealOrder = {};
7236 didWarnAboutTailOptions = {};
7237}
7238
7239function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
7240 if (current === null) {
7241 // If this is a fresh new component that hasn't been rendered yet, we
7242 // won't update its child set by applying minimal side-effects. Instead,
7243 // we will add them all to the child before it gets rendered. That means
7244 // we can optimize this reconciliation pass by not tracking side-effects.
7245 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7246 } else {
7247 // If the current child is the same as the work in progress, it means that
7248 // we haven't yet started any work on these children. Therefore, we use
7249 // the clone algorithm to create a copy of all the current children.
7250 // If we had any progressed work already, that is invalid at this point so
7251 // let's throw it out.
7252 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
7253 }
7254}
7255
7256function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
7257 // This function is fork of reconcileChildren. It's used in cases where we
7258 // want to reconcile without matching against the existing set. This has the
7259 // effect of all current children being unmounted; even if the type and key
7260 // are the same, the old child is unmounted and a new child is created.
7261 //
7262 // To do this, we're going to go through the reconcile algorithm twice. In
7263 // the first pass, we schedule a deletion for all the current children by
7264 // passing null.
7265 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
7266 // pass null in place of where we usually pass the current child set. This has
7267 // the effect of remounting all children regardless of whether their
7268 // identities match.
7269
7270 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7271}
7272
7273function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
7274 // TODO: current can be non-null here even if the component
7275 // hasn't yet mounted. This happens after the first render suspends.
7276 // We'll need to figure out if this is fine or can cause issues.
7277 {
7278 if (workInProgress.type !== workInProgress.elementType) {
7279 // Lazy component props can't be validated in createElement
7280 // because they're only guaranteed to be resolved here.
7281 var innerPropTypes = Component.propTypes;
7282
7283 if (innerPropTypes) {
7284 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7285 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7286 }
7287 }
7288 }
7289
7290 var render = Component.render;
7291 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
7292
7293 var nextChildren;
7294 prepareToReadContext(workInProgress, renderExpirationTime);
7295
7296 {
7297 ReactCurrentOwner$1.current = workInProgress;
7298 setCurrentPhase('render');
7299 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7300
7301 setCurrentPhase(null);
7302 }
7303
7304 if (current !== null && !didReceiveUpdate) {
7305 bailoutHooks(current, workInProgress, renderExpirationTime);
7306 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7307 } // React DevTools reads this flag.
7308
7309
7310 workInProgress.effectTag |= PerformedWork;
7311 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7312 return workInProgress.child;
7313}
7314
7315function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7316 if (current === null) {
7317 var type = Component.type;
7318
7319 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
7320 Component.defaultProps === undefined) {
7321 var resolvedType = type;
7322
7323 {
7324 resolvedType = resolveFunctionForHotReloading(type);
7325 } // If this is a plain function component without default props,
7326 // and with only the default shallow comparison, we upgrade it
7327 // to a SimpleMemoComponent to allow fast path updates.
7328
7329
7330 workInProgress.tag = SimpleMemoComponent;
7331 workInProgress.type = resolvedType;
7332
7333 {
7334 validateFunctionComponentInDev(workInProgress, type);
7335 }
7336
7337 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
7338 }
7339
7340 {
7341 var innerPropTypes = type.propTypes;
7342
7343 if (innerPropTypes) {
7344 // Inner memo component props aren't currently validated in createElement.
7345 // We could move it there, but we'd still need this for lazy code path.
7346 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7347 'prop', getComponentName(type), getCurrentFiberStackInDev);
7348 }
7349 }
7350
7351 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
7352 child.ref = workInProgress.ref;
7353 child.return = workInProgress;
7354 workInProgress.child = child;
7355 return child;
7356 }
7357
7358 {
7359 var _type = Component.type;
7360 var _innerPropTypes = _type.propTypes;
7361
7362 if (_innerPropTypes) {
7363 // Inner memo component props aren't currently validated in createElement.
7364 // We could move it there, but we'd still need this for lazy code path.
7365 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
7366 'prop', getComponentName(_type), getCurrentFiberStackInDev);
7367 }
7368 }
7369
7370 var currentChild = current.child; // This is always exactly one child
7371
7372 if (updateExpirationTime < renderExpirationTime) {
7373 // This will be the props with resolved defaultProps,
7374 // unlike current.memoizedProps which will be the unresolved ones.
7375 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
7376
7377 var compare = Component.compare;
7378 compare = compare !== null ? compare : shallowEqual;
7379
7380 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
7381 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7382 }
7383 } // React DevTools reads this flag.
7384
7385
7386 workInProgress.effectTag |= PerformedWork;
7387 var newChild = createWorkInProgress(currentChild, nextProps);
7388 newChild.ref = workInProgress.ref;
7389 newChild.return = workInProgress;
7390 workInProgress.child = newChild;
7391 return newChild;
7392}
7393
7394function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7395 // TODO: current can be non-null here even if the component
7396 // hasn't yet mounted. This happens when the inner render suspends.
7397 // We'll need to figure out if this is fine or can cause issues.
7398 {
7399 if (workInProgress.type !== workInProgress.elementType) {
7400 // Lazy component props can't be validated in createElement
7401 // because they're only guaranteed to be resolved here.
7402 var outerMemoType = workInProgress.elementType;
7403
7404 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
7405 // We warn when you define propTypes on lazy()
7406 // so let's just skip over it to find memo() outer wrapper.
7407 // Inner props for memo are validated later.
7408 outerMemoType = refineResolvedLazyComponent(outerMemoType);
7409 }
7410
7411 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
7412
7413 if (outerPropTypes) {
7414 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
7415 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
7416 } // Inner propTypes will be validated in the function component path.
7417
7418 }
7419 }
7420
7421 if (current !== null) {
7422 var prevProps = current.memoizedProps;
7423
7424 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
7425 workInProgress.type === current.type )) {
7426 didReceiveUpdate = false;
7427
7428 if (updateExpirationTime < renderExpirationTime) {
7429 // The pending update priority was cleared at the beginning of
7430 // beginWork. We're about to bail out, but there might be additional
7431 // updates at a lower priority. Usually, the priority level of the
7432 // remaining updates is accumlated during the evaluation of the
7433 // component (i.e. when processing the update queue). But since since
7434 // we're bailing out early *without* evaluating the component, we need
7435 // to account for it here, too. Reset to the value of the current fiber.
7436 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
7437 // because a MemoComponent fiber does not have hooks or an update queue;
7438 // rather, it wraps around an inner component, which may or may not
7439 // contains hooks.
7440 // TODO: Move the reset at in beginWork out of the common path so that
7441 // this is no longer necessary.
7442 workInProgress.expirationTime = current.expirationTime;
7443 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7444 }
7445 }
7446 }
7447
7448 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
7449}
7450
7451function updateFragment(current, workInProgress, renderExpirationTime) {
7452 var nextChildren = workInProgress.pendingProps;
7453 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7454 return workInProgress.child;
7455}
7456
7457function updateMode(current, workInProgress, renderExpirationTime) {
7458 var nextChildren = workInProgress.pendingProps.children;
7459 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7460 return workInProgress.child;
7461}
7462
7463function updateProfiler(current, workInProgress, renderExpirationTime) {
7464 {
7465 workInProgress.effectTag |= Update;
7466 }
7467
7468 var nextProps = workInProgress.pendingProps;
7469 var nextChildren = nextProps.children;
7470 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7471 return workInProgress.child;
7472}
7473
7474function markRef(current, workInProgress) {
7475 var ref = workInProgress.ref;
7476
7477 if (current === null && ref !== null || current !== null && current.ref !== ref) {
7478 // Schedule a Ref effect
7479 workInProgress.effectTag |= Ref;
7480 }
7481}
7482
7483function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7484 {
7485 if (workInProgress.type !== workInProgress.elementType) {
7486 // Lazy component props can't be validated in createElement
7487 // because they're only guaranteed to be resolved here.
7488 var innerPropTypes = Component.propTypes;
7489
7490 if (innerPropTypes) {
7491 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7492 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7493 }
7494 }
7495 }
7496
7497 var context;
7498
7499 {
7500 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
7501 context = getMaskedContext(workInProgress, unmaskedContext);
7502 }
7503
7504 var nextChildren;
7505 prepareToReadContext(workInProgress, renderExpirationTime);
7506
7507 {
7508 ReactCurrentOwner$1.current = workInProgress;
7509 setCurrentPhase('render');
7510 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7511
7512 setCurrentPhase(null);
7513 }
7514
7515 if (current !== null && !didReceiveUpdate) {
7516 bailoutHooks(current, workInProgress, renderExpirationTime);
7517 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7518 } // React DevTools reads this flag.
7519
7520
7521 workInProgress.effectTag |= PerformedWork;
7522 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7523 return workInProgress.child;
7524}
7525
7526function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7527 {
7528 if (workInProgress.type !== workInProgress.elementType) {
7529 // Lazy component props can't be validated in createElement
7530 // because they're only guaranteed to be resolved here.
7531 var innerPropTypes = Component.propTypes;
7532
7533 if (innerPropTypes) {
7534 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7535 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7536 }
7537 }
7538 } // Push context providers early to prevent context stack mismatches.
7539 // During mounting we don't know the child context yet as the instance doesn't exist.
7540 // We will invalidate the child context in finishClassComponent() right after rendering.
7541
7542
7543 var hasContext;
7544
7545 if (isContextProvider(Component)) {
7546 hasContext = true;
7547 pushContextProvider(workInProgress);
7548 } else {
7549 hasContext = false;
7550 }
7551
7552 prepareToReadContext(workInProgress, renderExpirationTime);
7553 var instance = workInProgress.stateNode;
7554 var shouldUpdate;
7555
7556 if (instance === null) {
7557 if (current !== null) {
7558 // A class component without an instance only mounts if it suspended
7559 // inside a non-concurrent tree, in an inconsistent state. We want to
7560 // treat it like a new mount, even though an empty version of it already
7561 // committed. Disconnect the alternate pointers.
7562 current.alternate = null;
7563 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
7564
7565 workInProgress.effectTag |= Placement;
7566 } // In the initial pass we might need to construct the instance.
7567
7568
7569 constructClassInstance(workInProgress, Component, nextProps);
7570 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7571 shouldUpdate = true;
7572 } else if (current === null) {
7573 // In a resume, we'll already have an instance we can reuse.
7574 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7575 } else {
7576 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
7577 }
7578
7579 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7580
7581 {
7582 var inst = workInProgress.stateNode;
7583
7584 if (inst.props !== nextProps) {
7585 if (!didWarnAboutReassigningProps) {
7586 error('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');
7587 }
7588
7589 didWarnAboutReassigningProps = true;
7590 }
7591 }
7592
7593 return nextUnitOfWork;
7594}
7595
7596function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7597 // Refs should update even if shouldComponentUpdate returns false
7598 markRef(current, workInProgress);
7599 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7600
7601 if (!shouldUpdate && !didCaptureError) {
7602 // Context providers should defer to sCU for rendering
7603 if (hasContext) {
7604 invalidateContextProvider(workInProgress, Component, false);
7605 }
7606
7607 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7608 }
7609
7610 var instance = workInProgress.stateNode; // Rerender
7611
7612 ReactCurrentOwner$1.current = workInProgress;
7613 var nextChildren;
7614
7615 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7616 // If we captured an error, but getDerivedStateFromError is not defined,
7617 // unmount all the children. componentDidCatch will schedule an update to
7618 // re-render a fallback. This is temporary until we migrate everyone to
7619 // the new API.
7620 // TODO: Warn in a future release.
7621 nextChildren = null;
7622
7623 {
7624 stopProfilerTimerIfRunning();
7625 }
7626 } else {
7627 {
7628 setCurrentPhase('render');
7629 nextChildren = instance.render();
7630
7631 setCurrentPhase(null);
7632 }
7633 } // React DevTools reads this flag.
7634
7635
7636 workInProgress.effectTag |= PerformedWork;
7637
7638 if (current !== null && didCaptureError) {
7639 // If we're recovering from an error, reconcile without reusing any of
7640 // the existing children. Conceptually, the normal children and the children
7641 // that are shown on error are two different sets, so we shouldn't reuse
7642 // normal children even if their identities match.
7643 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
7644 } else {
7645 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7646 } // Memoize state using the values we just used to render.
7647 // TODO: Restructure so we never read values from the instance.
7648
7649
7650 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
7651
7652 if (hasContext) {
7653 invalidateContextProvider(workInProgress, Component, true);
7654 }
7655
7656 return workInProgress.child;
7657}
7658
7659function pushHostRootContext(workInProgress) {
7660 var root = workInProgress.stateNode;
7661
7662 if (root.pendingContext) {
7663 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7664 } else if (root.context) {
7665 // Should always be set
7666 pushTopLevelContextObject(workInProgress, root.context, false);
7667 }
7668
7669 pushHostContainer(workInProgress, root.containerInfo);
7670}
7671
7672function updateHostRoot(current, workInProgress, renderExpirationTime) {
7673 pushHostRootContext(workInProgress);
7674 var updateQueue = workInProgress.updateQueue;
7675
7676 if (!(current !== null && updateQueue !== null)) {
7677 {
7678 throw 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." );
7679 }
7680 }
7681
7682 var nextProps = workInProgress.pendingProps;
7683 var prevState = workInProgress.memoizedState;
7684 var prevChildren = prevState !== null ? prevState.element : null;
7685 cloneUpdateQueue(current, workInProgress);
7686 processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime);
7687 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
7688 // being called "element".
7689
7690 var nextChildren = nextState.element;
7691
7692 if (nextChildren === prevChildren) {
7693 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7694 }
7695
7696 var root = workInProgress.stateNode;
7697
7698 if (root.hydrate && enterHydrationState()) {
7699 // If we don't have any current children this might be the first pass.
7700 // We always try to hydrate. If this isn't a hydration pass there won't
7701 // be any children to hydrate which is effectively the same thing as
7702 // not hydrating.
7703 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7704 workInProgress.child = child;
7705 var node = child;
7706
7707 while (node) {
7708 // Mark each child as hydrating. This is a fast path to know whether this
7709 // tree is part of a hydrating tree. This is used to determine if a child
7710 // node has fully mounted yet, and for scheduling event replaying.
7711 // Conceptually this is similar to Placement in that a new subtree is
7712 // inserted into the React tree here. It just happens to not need DOM
7713 // mutations because it already exists.
7714 node.effectTag = node.effectTag & ~Placement | Hydrating;
7715 node = node.sibling;
7716 }
7717 } else {
7718 // Otherwise reset hydration state in case we aborted and resumed another
7719 // root.
7720 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7721 }
7722
7723 return workInProgress.child;
7724}
7725
7726function updateHostComponent(current, workInProgress, renderExpirationTime) {
7727 pushHostContext(workInProgress);
7728
7729 var type = workInProgress.type;
7730 var nextProps = workInProgress.pendingProps;
7731 var prevProps = current !== null ? current.memoizedProps : null;
7732 var nextChildren = nextProps.children;
7733
7734 if (prevProps !== null && shouldSetTextContent()) {
7735 // If we're switching from a direct text child to a normal child, or to
7736 // empty, we need to schedule the text content to be reset.
7737 workInProgress.effectTag |= ContentReset;
7738 }
7739
7740 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
7741
7742 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree()) {
7743 {
7744 markSpawnedWork(Never);
7745 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
7746
7747
7748 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7749 return null;
7750 }
7751
7752 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7753 return workInProgress.child;
7754}
7755
7756function updateHostText(current, workInProgress) {
7757 // immediately after.
7758
7759
7760 return null;
7761}
7762
7763function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7764 if (_current !== null) {
7765 // A lazy component only mounts if it suspended inside a non-
7766 // concurrent tree, in an inconsistent state. We want to treat it like
7767 // a new mount, even though an empty version of it already committed.
7768 // Disconnect the alternate pointers.
7769 _current.alternate = null;
7770 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
7771
7772 workInProgress.effectTag |= Placement;
7773 }
7774
7775 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
7776 // Cancel and resume right after we know the tag.
7777
7778 cancelWorkTimer(workInProgress);
7779 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
7780
7781 workInProgress.type = Component;
7782 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
7783 startWorkTimer(workInProgress);
7784 var resolvedProps = resolveDefaultProps(Component, props);
7785 var child;
7786
7787 switch (resolvedTag) {
7788 case FunctionComponent:
7789 {
7790 {
7791 validateFunctionComponentInDev(workInProgress, Component);
7792 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
7793 }
7794
7795 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7796 return child;
7797 }
7798
7799 case ClassComponent:
7800 {
7801 {
7802 workInProgress.type = Component = resolveClassForHotReloading(Component);
7803 }
7804
7805 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7806 return child;
7807 }
7808
7809 case ForwardRef:
7810 {
7811 {
7812 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
7813 }
7814
7815 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7816 return child;
7817 }
7818
7819 case MemoComponent:
7820 {
7821 {
7822 if (workInProgress.type !== workInProgress.elementType) {
7823 var outerPropTypes = Component.propTypes;
7824
7825 if (outerPropTypes) {
7826 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
7827 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7828 }
7829 }
7830 }
7831
7832 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
7833 updateExpirationTime, renderExpirationTime);
7834 return child;
7835 }
7836 }
7837
7838 var hint = '';
7839
7840 {
7841 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
7842 hint = ' Did you wrap a component in React.lazy() more than once?';
7843 }
7844 } // This message intentionally doesn't mention ForwardRef or MemoComponent
7845 // because the fact that it's a separate type of work is an
7846 // implementation detail.
7847
7848
7849 {
7850 {
7851 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
7852 }
7853 }
7854}
7855
7856function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
7857 if (_current !== null) {
7858 // An incomplete component only mounts if it suspended inside a non-
7859 // concurrent tree, in an inconsistent state. We want to treat it like
7860 // a new mount, even though an empty version of it already committed.
7861 // Disconnect the alternate pointers.
7862 _current.alternate = null;
7863 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
7864
7865 workInProgress.effectTag |= Placement;
7866 } // Promote the fiber to a class and try rendering again.
7867
7868
7869 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
7870 // Push context providers early to prevent context stack mismatches.
7871 // During mounting we don't know the child context yet as the instance doesn't exist.
7872 // We will invalidate the child context in finishClassComponent() right after rendering.
7873
7874 var hasContext;
7875
7876 if (isContextProvider(Component)) {
7877 hasContext = true;
7878 pushContextProvider(workInProgress);
7879 } else {
7880 hasContext = false;
7881 }
7882
7883 prepareToReadContext(workInProgress, renderExpirationTime);
7884 constructClassInstance(workInProgress, Component, nextProps);
7885 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7886 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7887}
7888
7889function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
7890 if (_current !== null) {
7891 // An indeterminate component only mounts if it suspended inside a non-
7892 // concurrent tree, in an inconsistent state. We want to treat it like
7893 // a new mount, even though an empty version of it already committed.
7894 // Disconnect the alternate pointers.
7895 _current.alternate = null;
7896 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
7897
7898 workInProgress.effectTag |= Placement;
7899 }
7900
7901 var props = workInProgress.pendingProps;
7902 var context;
7903
7904 {
7905 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
7906 context = getMaskedContext(workInProgress, unmaskedContext);
7907 }
7908
7909 prepareToReadContext(workInProgress, renderExpirationTime);
7910 var value;
7911
7912 {
7913 if (Component.prototype && typeof Component.prototype.render === 'function') {
7914 var componentName = getComponentName(Component) || 'Unknown';
7915
7916 if (!didWarnAboutBadClass[componentName]) {
7917 error("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);
7918
7919 didWarnAboutBadClass[componentName] = true;
7920 }
7921 }
7922
7923 if (workInProgress.mode & StrictMode) {
7924 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
7925 }
7926
7927 ReactCurrentOwner$1.current = workInProgress;
7928 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7929 } // React DevTools reads this flag.
7930
7931
7932 workInProgress.effectTag |= PerformedWork;
7933
7934 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
7935 {
7936 var _componentName = getComponentName(Component) || 'Unknown';
7937
7938 if (!didWarnAboutModulePatternComponent[_componentName]) {
7939 error('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);
7940
7941 didWarnAboutModulePatternComponent[_componentName] = true;
7942 }
7943 } // Proceed under the assumption that this is a class instance
7944
7945
7946 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
7947
7948 workInProgress.memoizedState = null;
7949 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
7950 // During mounting we don't know the child context yet as the instance doesn't exist.
7951 // We will invalidate the child context in finishClassComponent() right after rendering.
7952
7953 var hasContext = false;
7954
7955 if (isContextProvider(Component)) {
7956 hasContext = true;
7957 pushContextProvider(workInProgress);
7958 } else {
7959 hasContext = false;
7960 }
7961
7962 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
7963 initializeUpdateQueue(workInProgress);
7964 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
7965
7966 if (typeof getDerivedStateFromProps === 'function') {
7967 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
7968 }
7969
7970 adoptClassInstance(workInProgress, value);
7971 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
7972 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7973 } else {
7974 // Proceed under the assumption that this is a function component
7975 workInProgress.tag = FunctionComponent;
7976
7977 reconcileChildren(null, workInProgress, value, renderExpirationTime);
7978
7979 {
7980 validateFunctionComponentInDev(workInProgress, Component);
7981 }
7982
7983 return workInProgress.child;
7984 }
7985}
7986
7987function validateFunctionComponentInDev(workInProgress, Component) {
7988 {
7989 if (Component) {
7990 if (Component.childContextTypes) {
7991 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
7992 }
7993 }
7994
7995 if (workInProgress.ref !== null) {
7996 var info = '';
7997 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
7998
7999 if (ownerName) {
8000 info += '\n\nCheck the render method of `' + ownerName + '`.';
8001 }
8002
8003 var warningKey = ownerName || workInProgress._debugID || '';
8004 var debugSource = workInProgress._debugSource;
8005
8006 if (debugSource) {
8007 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8008 }
8009
8010 if (!didWarnAboutFunctionRefs[warningKey]) {
8011 didWarnAboutFunctionRefs[warningKey] = true;
8012
8013 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
8014 }
8015 }
8016
8017 if (typeof Component.getDerivedStateFromProps === 'function') {
8018 var _componentName2 = getComponentName(Component) || 'Unknown';
8019
8020 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
8021 error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);
8022
8023 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
8024 }
8025 }
8026
8027 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
8028 var _componentName3 = getComponentName(Component) || 'Unknown';
8029
8030 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
8031 error('%s: Function components do not support contextType.', _componentName3);
8032
8033 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
8034 }
8035 }
8036 }
8037}
8038
8039var SUSPENDED_MARKER = {
8040 dehydrated: null,
8041 retryTime: NoWork
8042};
8043
8044function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
8045 // If the context is telling us that we should show a fallback, and we're not
8046 // already showing content, then we should show the fallback instead.
8047 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
8048}
8049
8050function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
8051 var mode = workInProgress.mode;
8052 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
8053
8054 {
8055 if (shouldSuspend(workInProgress)) {
8056 workInProgress.effectTag |= DidCapture;
8057 }
8058 }
8059
8060 var suspenseContext = suspenseStackCursor.current;
8061 var nextDidTimeout = false;
8062 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
8063
8064 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
8065 // Something in this boundary's subtree already suspended. Switch to
8066 // rendering the fallback children.
8067 nextDidTimeout = true;
8068 workInProgress.effectTag &= ~DidCapture;
8069 } else {
8070 // Attempting the main content
8071 if (current === null || current.memoizedState !== null) {
8072 // This is a new mount or this boundary is already showing a fallback state.
8073 // Mark this subtree context as having at least one invisible parent that could
8074 // handle the fallback state.
8075 // Boundaries without fallbacks or should be avoided are not considered since
8076 // they cannot handle preferred fallback states.
8077 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
8078 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
8079 }
8080 }
8081 }
8082
8083 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8084 pushSuspenseContext(workInProgress, suspenseContext);
8085
8086 {
8087 if ('maxDuration' in nextProps) {
8088 if (!didWarnAboutMaxDuration) {
8089 didWarnAboutMaxDuration = true;
8090
8091 error('maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
8092 }
8093 }
8094 } // This next part is a bit confusing. If the children timeout, we switch to
8095 // showing the fallback children in place of the "primary" children.
8096 // However, we don't want to delete the primary children because then their
8097 // state will be lost (both the React state and the host state, e.g.
8098 // uncontrolled form inputs). Instead we keep them mounted and hide them.
8099 // Both the fallback children AND the primary children are rendered at the
8100 // same time. Once the primary children are un-suspended, we can delete
8101 // the fallback children — don't need to preserve their state.
8102 //
8103 // The two sets of children are siblings in the host environment, but
8104 // semantically, for purposes of reconciliation, they are two separate sets.
8105 // So we store them using two fragment fibers.
8106 //
8107 // However, we want to avoid allocating extra fibers for every placeholder.
8108 // They're only necessary when the children time out, because that's the
8109 // only time when both sets are mounted.
8110 //
8111 // So, the extra fragment fibers are only used if the children time out.
8112 // Otherwise, we render the primary children directly. This requires some
8113 // custom reconciliation logic to preserve the state of the primary
8114 // children. It's essentially a very basic form of re-parenting.
8115
8116
8117 if (current === null) {
8118 // If we're currently hydrating, try to hydrate this boundary.
8119 // But only if this has a fallback.
8120 if (nextProps.fallback !== undefined) ; // This is the initial mount. This branch is pretty simple because there's
8121 // no previous state that needs to be preserved.
8122
8123
8124 if (nextDidTimeout) {
8125 // Mount separate fragments for primary and fallback children.
8126 var nextFallbackChildren = nextProps.fallback;
8127 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
8128 primaryChildFragment.return = workInProgress;
8129
8130 if ((workInProgress.mode & BlockingMode) === NoMode) {
8131 // Outside of blocking mode, we commit the effects from the
8132 // partially completed, timed-out tree, too.
8133 var progressedState = workInProgress.memoizedState;
8134 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
8135 primaryChildFragment.child = progressedPrimaryChild;
8136 var progressedChild = progressedPrimaryChild;
8137
8138 while (progressedChild !== null) {
8139 progressedChild.return = primaryChildFragment;
8140 progressedChild = progressedChild.sibling;
8141 }
8142 }
8143
8144 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
8145 fallbackChildFragment.return = workInProgress;
8146 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
8147 // fallback children.
8148
8149 workInProgress.memoizedState = SUSPENDED_MARKER;
8150 workInProgress.child = primaryChildFragment;
8151 return fallbackChildFragment;
8152 } else {
8153 // Mount the primary children without an intermediate fragment fiber.
8154 var nextPrimaryChildren = nextProps.children;
8155 workInProgress.memoizedState = null;
8156 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
8157 }
8158 } else {
8159 // This is an update. This branch is more complicated because we need to
8160 // ensure the state of the primary children is preserved.
8161 var prevState = current.memoizedState;
8162
8163 if (prevState !== null) {
8164 // wrapped in a fragment fiber.
8165
8166
8167 var currentPrimaryChildFragment = current.child;
8168 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
8169
8170 if (nextDidTimeout) {
8171 // Still timed out. Reuse the current primary children by cloning
8172 // its fragment. We're going to skip over these entirely.
8173 var _nextFallbackChildren2 = nextProps.fallback;
8174
8175 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps);
8176
8177 _primaryChildFragment2.return = workInProgress;
8178
8179 if ((workInProgress.mode & BlockingMode) === NoMode) {
8180 // Outside of blocking mode, we commit the effects from the
8181 // partially completed, timed-out tree, too.
8182 var _progressedState = workInProgress.memoizedState;
8183
8184 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
8185
8186 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
8187 _primaryChildFragment2.child = _progressedPrimaryChild;
8188 var _progressedChild2 = _progressedPrimaryChild;
8189
8190 while (_progressedChild2 !== null) {
8191 _progressedChild2.return = _primaryChildFragment2;
8192 _progressedChild2 = _progressedChild2.sibling;
8193 }
8194 }
8195 } // Because primaryChildFragment is a new fiber that we're inserting as the
8196 // parent of a new tree, we need to set its treeBaseDuration.
8197
8198
8199 if ( workInProgress.mode & ProfileMode) {
8200 // treeBaseDuration is the sum of all the child tree base durations.
8201 var _treeBaseDuration = 0;
8202 var _hiddenChild = _primaryChildFragment2.child;
8203
8204 while (_hiddenChild !== null) {
8205 _treeBaseDuration += _hiddenChild.treeBaseDuration;
8206 _hiddenChild = _hiddenChild.sibling;
8207 }
8208
8209 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
8210 } // Clone the fallback child fragment, too. These we'll continue
8211 // working on.
8212
8213
8214 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2);
8215
8216 _fallbackChildFragment2.return = workInProgress;
8217 _primaryChildFragment2.sibling = _fallbackChildFragment2;
8218 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8219 // fallback children.
8220
8221 workInProgress.memoizedState = SUSPENDED_MARKER;
8222 workInProgress.child = _primaryChildFragment2;
8223 return _fallbackChildFragment2;
8224 } else {
8225 // No longer suspended. Switch back to showing the primary children,
8226 // and remove the intermediate fragment fiber.
8227 var _nextPrimaryChildren = nextProps.children;
8228 var currentPrimaryChild = currentPrimaryChildFragment.child;
8229 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
8230 // children. Wait until the complete phase, after we've confirmed the
8231 // fallback is no longer needed.
8232 // TODO: Would it be better to store the fallback fragment on
8233 // the stateNode?
8234 // Continue rendering the children, like we normally do.
8235
8236 workInProgress.memoizedState = null;
8237 return workInProgress.child = primaryChild;
8238 }
8239 } else {
8240 // The current tree has not already timed out. That means the primary
8241 // children are not wrapped in a fragment fiber.
8242 var _currentPrimaryChild = current.child;
8243
8244 if (nextDidTimeout) {
8245 // Timed out. Wrap the children in a fragment fiber to keep them
8246 // separate from the fallback children.
8247 var _nextFallbackChildren3 = nextProps.fallback;
8248
8249 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
8250 // going to render this fragment.
8251 null, mode, NoWork, null);
8252
8253 _primaryChildFragment3.return = workInProgress;
8254 _primaryChildFragment3.child = _currentPrimaryChild;
8255
8256 if (_currentPrimaryChild !== null) {
8257 _currentPrimaryChild.return = _primaryChildFragment3;
8258 } // Even though we're creating a new fiber, there are no new children,
8259 // because we're reusing an already mounted tree. So we don't need to
8260 // schedule a placement.
8261 // primaryChildFragment.effectTag |= Placement;
8262
8263
8264 if ((workInProgress.mode & BlockingMode) === NoMode) {
8265 // Outside of blocking mode, we commit the effects from the
8266 // partially completed, timed-out tree, too.
8267 var _progressedState2 = workInProgress.memoizedState;
8268
8269 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
8270
8271 _primaryChildFragment3.child = _progressedPrimaryChild2;
8272 var _progressedChild3 = _progressedPrimaryChild2;
8273
8274 while (_progressedChild3 !== null) {
8275 _progressedChild3.return = _primaryChildFragment3;
8276 _progressedChild3 = _progressedChild3.sibling;
8277 }
8278 } // Because primaryChildFragment is a new fiber that we're inserting as the
8279 // parent of a new tree, we need to set its treeBaseDuration.
8280
8281
8282 if ( workInProgress.mode & ProfileMode) {
8283 // treeBaseDuration is the sum of all the child tree base durations.
8284 var _treeBaseDuration2 = 0;
8285 var _hiddenChild2 = _primaryChildFragment3.child;
8286
8287 while (_hiddenChild2 !== null) {
8288 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
8289 _hiddenChild2 = _hiddenChild2.sibling;
8290 }
8291
8292 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
8293 } // Create a fragment from the fallback children, too.
8294
8295
8296 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
8297
8298 _fallbackChildFragment3.return = workInProgress;
8299 _primaryChildFragment3.sibling = _fallbackChildFragment3;
8300 _fallbackChildFragment3.effectTag |= Placement;
8301 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8302 // fallback children.
8303
8304 workInProgress.memoizedState = SUSPENDED_MARKER;
8305 workInProgress.child = _primaryChildFragment3;
8306 return _fallbackChildFragment3;
8307 } else {
8308 // Still haven't timed out. Continue rendering the children, like we
8309 // normally do.
8310 workInProgress.memoizedState = null;
8311 var _nextPrimaryChildren2 = nextProps.children;
8312 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
8313 }
8314 }
8315 }
8316}
8317
8318function scheduleWorkOnFiber(fiber, renderExpirationTime) {
8319 if (fiber.expirationTime < renderExpirationTime) {
8320 fiber.expirationTime = renderExpirationTime;
8321 }
8322
8323 var alternate = fiber.alternate;
8324
8325 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8326 alternate.expirationTime = renderExpirationTime;
8327 }
8328
8329 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
8330}
8331
8332function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
8333 // Mark any Suspense boundaries with fallbacks as having work to do.
8334 // If they were previously forced into fallbacks, they may now be able
8335 // to unblock.
8336 var node = firstChild;
8337
8338 while (node !== null) {
8339 if (node.tag === SuspenseComponent) {
8340 var state = node.memoizedState;
8341
8342 if (state !== null) {
8343 scheduleWorkOnFiber(node, renderExpirationTime);
8344 }
8345 } else if (node.tag === SuspenseListComponent) {
8346 // If the tail is hidden there might not be an Suspense boundaries
8347 // to schedule work on. In this case we have to schedule it on the
8348 // list itself.
8349 // We don't have to traverse to the children of the list since
8350 // the list will propagate the change when it rerenders.
8351 scheduleWorkOnFiber(node, renderExpirationTime);
8352 } else if (node.child !== null) {
8353 node.child.return = node;
8354 node = node.child;
8355 continue;
8356 }
8357
8358 if (node === workInProgress) {
8359 return;
8360 }
8361
8362 while (node.sibling === null) {
8363 if (node.return === null || node.return === workInProgress) {
8364 return;
8365 }
8366
8367 node = node.return;
8368 }
8369
8370 node.sibling.return = node.return;
8371 node = node.sibling;
8372 }
8373}
8374
8375function findLastContentRow(firstChild) {
8376 // This is going to find the last row among these children that is already
8377 // showing content on the screen, as opposed to being in fallback state or
8378 // new. If a row has multiple Suspense boundaries, any of them being in the
8379 // fallback state, counts as the whole row being in a fallback state.
8380 // Note that the "rows" will be workInProgress, but any nested children
8381 // will still be current since we haven't rendered them yet. The mounted
8382 // order may not be the same as the new order. We use the new order.
8383 var row = firstChild;
8384 var lastContentRow = null;
8385
8386 while (row !== null) {
8387 var currentRow = row.alternate; // New rows can't be content rows.
8388
8389 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8390 lastContentRow = row;
8391 }
8392
8393 row = row.sibling;
8394 }
8395
8396 return lastContentRow;
8397}
8398
8399function validateRevealOrder(revealOrder) {
8400 {
8401 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
8402 didWarnAboutRevealOrder[revealOrder] = true;
8403
8404 if (typeof revealOrder === 'string') {
8405 switch (revealOrder.toLowerCase()) {
8406 case 'together':
8407 case 'forwards':
8408 case 'backwards':
8409 {
8410 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
8411
8412 break;
8413 }
8414
8415 case 'forward':
8416 case 'backward':
8417 {
8418 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
8419
8420 break;
8421 }
8422
8423 default:
8424 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8425
8426 break;
8427 }
8428 } else {
8429 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8430 }
8431 }
8432 }
8433}
8434
8435function validateTailOptions(tailMode, revealOrder) {
8436 {
8437 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
8438 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
8439 didWarnAboutTailOptions[tailMode] = true;
8440
8441 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
8442 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
8443 didWarnAboutTailOptions[tailMode] = true;
8444
8445 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
8446 }
8447 }
8448 }
8449}
8450
8451function validateSuspenseListNestedChild(childSlot, index) {
8452 {
8453 var isArray = Array.isArray(childSlot);
8454 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
8455
8456 if (isArray || isIterable) {
8457 var type = isArray ? 'array' : 'iterable';
8458
8459 error('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);
8460
8461 return false;
8462 }
8463 }
8464
8465 return true;
8466}
8467
8468function validateSuspenseListChildren(children, revealOrder) {
8469 {
8470 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
8471 if (Array.isArray(children)) {
8472 for (var i = 0; i < children.length; i++) {
8473 if (!validateSuspenseListNestedChild(children[i], i)) {
8474 return;
8475 }
8476 }
8477 } else {
8478 var iteratorFn = getIteratorFn(children);
8479
8480 if (typeof iteratorFn === 'function') {
8481 var childrenIterator = iteratorFn.call(children);
8482
8483 if (childrenIterator) {
8484 var step = childrenIterator.next();
8485 var _i = 0;
8486
8487 for (; !step.done; step = childrenIterator.next()) {
8488 if (!validateSuspenseListNestedChild(step.value, _i)) {
8489 return;
8490 }
8491
8492 _i++;
8493 }
8494 }
8495 } else {
8496 error('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);
8497 }
8498 }
8499 }
8500 }
8501}
8502
8503function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
8504 var renderState = workInProgress.memoizedState;
8505
8506 if (renderState === null) {
8507 workInProgress.memoizedState = {
8508 isBackwards: isBackwards,
8509 rendering: null,
8510 renderingStartTime: 0,
8511 last: lastContentRow,
8512 tail: tail,
8513 tailExpiration: 0,
8514 tailMode: tailMode,
8515 lastEffect: lastEffectBeforeRendering
8516 };
8517 } else {
8518 // We can reuse the existing object from previous renders.
8519 renderState.isBackwards = isBackwards;
8520 renderState.rendering = null;
8521 renderState.renderingStartTime = 0;
8522 renderState.last = lastContentRow;
8523 renderState.tail = tail;
8524 renderState.tailExpiration = 0;
8525 renderState.tailMode = tailMode;
8526 renderState.lastEffect = lastEffectBeforeRendering;
8527 }
8528} // This can end up rendering this component multiple passes.
8529// The first pass splits the children fibers into two sets. A head and tail.
8530// We first render the head. If anything is in fallback state, we do another
8531// pass through beginWork to rerender all children (including the tail) with
8532// the force suspend context. If the first render didn't have anything in
8533// in fallback state. Then we render each row in the tail one-by-one.
8534// That happens in the completeWork phase without going back to beginWork.
8535
8536
8537function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
8538 var nextProps = workInProgress.pendingProps;
8539 var revealOrder = nextProps.revealOrder;
8540 var tailMode = nextProps.tail;
8541 var newChildren = nextProps.children;
8542 validateRevealOrder(revealOrder);
8543 validateTailOptions(tailMode, revealOrder);
8544 validateSuspenseListChildren(newChildren, revealOrder);
8545 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8546 var suspenseContext = suspenseStackCursor.current;
8547 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
8548
8549 if (shouldForceFallback) {
8550 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
8551 workInProgress.effectTag |= DidCapture;
8552 } else {
8553 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
8554
8555 if (didSuspendBefore) {
8556 // If we previously forced a fallback, we need to schedule work
8557 // on any nested boundaries to let them know to try to render
8558 // again. This is the same as context updating.
8559 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
8560 }
8561
8562 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8563 }
8564
8565 pushSuspenseContext(workInProgress, suspenseContext);
8566
8567 if ((workInProgress.mode & BlockingMode) === NoMode) {
8568 // Outside of blocking mode, SuspenseList doesn't work so we just
8569 // use make it a noop by treating it as the default revealOrder.
8570 workInProgress.memoizedState = null;
8571 } else {
8572 switch (revealOrder) {
8573 case 'forwards':
8574 {
8575 var lastContentRow = findLastContentRow(workInProgress.child);
8576 var tail;
8577
8578 if (lastContentRow === null) {
8579 // The whole list is part of the tail.
8580 // TODO: We could fast path by just rendering the tail now.
8581 tail = workInProgress.child;
8582 workInProgress.child = null;
8583 } else {
8584 // Disconnect the tail rows after the content row.
8585 // We're going to render them separately later.
8586 tail = lastContentRow.sibling;
8587 lastContentRow.sibling = null;
8588 }
8589
8590 initSuspenseListRenderState(workInProgress, false, // isBackwards
8591 tail, lastContentRow, tailMode, workInProgress.lastEffect);
8592 break;
8593 }
8594
8595 case 'backwards':
8596 {
8597 // We're going to find the first row that has existing content.
8598 // At the same time we're going to reverse the list of everything
8599 // we pass in the meantime. That's going to be our tail in reverse
8600 // order.
8601 var _tail = null;
8602 var row = workInProgress.child;
8603 workInProgress.child = null;
8604
8605 while (row !== null) {
8606 var currentRow = row.alternate; // New rows can't be content rows.
8607
8608 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8609 // This is the beginning of the main content.
8610 workInProgress.child = row;
8611 break;
8612 }
8613
8614 var nextRow = row.sibling;
8615 row.sibling = _tail;
8616 _tail = row;
8617 row = nextRow;
8618 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
8619
8620
8621 initSuspenseListRenderState(workInProgress, true, // isBackwards
8622 _tail, null, // last
8623 tailMode, workInProgress.lastEffect);
8624 break;
8625 }
8626
8627 case 'together':
8628 {
8629 initSuspenseListRenderState(workInProgress, false, // isBackwards
8630 null, // tail
8631 null, // last
8632 undefined, workInProgress.lastEffect);
8633 break;
8634 }
8635
8636 default:
8637 {
8638 // The default reveal order is the same as not having
8639 // a boundary.
8640 workInProgress.memoizedState = null;
8641 }
8642 }
8643 }
8644
8645 return workInProgress.child;
8646}
8647
8648function updatePortalComponent(current, workInProgress, renderExpirationTime) {
8649 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8650 var nextChildren = workInProgress.pendingProps;
8651
8652 if (current === null) {
8653 // Portals are special because we don't append the children during mount
8654 // but at commit. Therefore we need to track insertions which the normal
8655 // flow doesn't do during mount. This doesn't happen at the root because
8656 // the root always starts with a "current" with a null child.
8657 // TODO: Consider unifying this with how the root works.
8658 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8659 } else {
8660 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8661 }
8662
8663 return workInProgress.child;
8664}
8665
8666function updateContextProvider(current, workInProgress, renderExpirationTime) {
8667 var providerType = workInProgress.type;
8668 var context = providerType._context;
8669 var newProps = workInProgress.pendingProps;
8670 var oldProps = workInProgress.memoizedProps;
8671 var newValue = newProps.value;
8672
8673 {
8674 var providerPropTypes = workInProgress.type.propTypes;
8675
8676 if (providerPropTypes) {
8677 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
8678 }
8679 }
8680
8681 pushProvider(workInProgress, newValue);
8682
8683 if (oldProps !== null) {
8684 var oldValue = oldProps.value;
8685 var changedBits = calculateChangedBits(context, newValue, oldValue);
8686
8687 if (changedBits === 0) {
8688 // No change. Bailout early if children are the same.
8689 if (oldProps.children === newProps.children && !hasContextChanged()) {
8690 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8691 }
8692 } else {
8693 // The context value changed. Search for matching consumers and schedule
8694 // them to update.
8695 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
8696 }
8697 }
8698
8699 var newChildren = newProps.children;
8700 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8701 return workInProgress.child;
8702}
8703
8704var hasWarnedAboutUsingContextAsConsumer = false;
8705
8706function updateContextConsumer(current, workInProgress, renderExpirationTime) {
8707 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
8708 // DEV mode, we create a separate object for Context.Consumer that acts
8709 // like a proxy to Context. This proxy object adds unnecessary code in PROD
8710 // so we use the old behaviour (Context.Consumer references Context) to
8711 // reduce size and overhead. The separate object references context via
8712 // a property called "_context", which also gives us the ability to check
8713 // in DEV mode if this property exists or not and warn if it does not.
8714
8715 {
8716 if (context._context === undefined) {
8717 // This may be because it's a Context (rather than a Consumer).
8718 // Or it may be because it's older React where they're the same thing.
8719 // We only want to warn if we're sure it's a new React.
8720 if (context !== context.Consumer) {
8721 if (!hasWarnedAboutUsingContextAsConsumer) {
8722 hasWarnedAboutUsingContextAsConsumer = true;
8723
8724 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
8725 }
8726 }
8727 } else {
8728 context = context._context;
8729 }
8730 }
8731
8732 var newProps = workInProgress.pendingProps;
8733 var render = newProps.children;
8734
8735 {
8736 if (typeof render !== 'function') {
8737 error('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.');
8738 }
8739 }
8740
8741 prepareToReadContext(workInProgress, renderExpirationTime);
8742 var newValue = readContext(context, newProps.unstable_observedBits);
8743 var newChildren;
8744
8745 {
8746 ReactCurrentOwner$1.current = workInProgress;
8747 setCurrentPhase('render');
8748 newChildren = render(newValue);
8749 setCurrentPhase(null);
8750 } // React DevTools reads this flag.
8751
8752
8753 workInProgress.effectTag |= PerformedWork;
8754 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8755 return workInProgress.child;
8756}
8757
8758function markWorkInProgressReceivedUpdate() {
8759 didReceiveUpdate = true;
8760}
8761
8762function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
8763 cancelWorkTimer(workInProgress);
8764
8765 if (current !== null) {
8766 // Reuse previous dependencies
8767 workInProgress.dependencies = current.dependencies;
8768 }
8769
8770 {
8771 // Don't update "base" render times for bailouts.
8772 stopProfilerTimerIfRunning();
8773 }
8774
8775 var updateExpirationTime = workInProgress.expirationTime;
8776
8777 if (updateExpirationTime !== NoWork) {
8778 markUnprocessedUpdateTime(updateExpirationTime);
8779 } // Check if the children have any pending work.
8780
8781
8782 var childExpirationTime = workInProgress.childExpirationTime;
8783
8784 if (childExpirationTime < renderExpirationTime) {
8785 // The children don't have any work either. We can skip them.
8786 // TODO: Once we add back resuming, we should check if the children are
8787 // a work-in-progress set. If so, we need to transfer their effects.
8788 return null;
8789 } else {
8790 // This fiber doesn't have work, but its subtree does. Clone the child
8791 // fibers and continue.
8792 cloneChildFibers(current, workInProgress);
8793 return workInProgress.child;
8794 }
8795}
8796
8797function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
8798 {
8799 var returnFiber = oldWorkInProgress.return;
8800
8801 if (returnFiber === null) {
8802 throw new Error('Cannot swap the root fiber.');
8803 } // Disconnect from the old current.
8804 // It will get deleted.
8805
8806
8807 current.alternate = null;
8808 oldWorkInProgress.alternate = null; // Connect to the new tree.
8809
8810 newWorkInProgress.index = oldWorkInProgress.index;
8811 newWorkInProgress.sibling = oldWorkInProgress.sibling;
8812 newWorkInProgress.return = oldWorkInProgress.return;
8813 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
8814
8815 if (oldWorkInProgress === returnFiber.child) {
8816 returnFiber.child = newWorkInProgress;
8817 } else {
8818 var prevSibling = returnFiber.child;
8819
8820 if (prevSibling === null) {
8821 throw new Error('Expected parent to have a child.');
8822 }
8823
8824 while (prevSibling.sibling !== oldWorkInProgress) {
8825 prevSibling = prevSibling.sibling;
8826
8827 if (prevSibling === null) {
8828 throw new Error('Expected to find the previous sibling.');
8829 }
8830 }
8831
8832 prevSibling.sibling = newWorkInProgress;
8833 } // Delete the old fiber and place the new one.
8834 // Since the old fiber is disconnected, we have to schedule it manually.
8835
8836
8837 var last = returnFiber.lastEffect;
8838
8839 if (last !== null) {
8840 last.nextEffect = current;
8841 returnFiber.lastEffect = current;
8842 } else {
8843 returnFiber.firstEffect = returnFiber.lastEffect = current;
8844 }
8845
8846 current.nextEffect = null;
8847 current.effectTag = Deletion;
8848 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
8849
8850 return newWorkInProgress;
8851 }
8852}
8853
8854function beginWork(current, workInProgress, renderExpirationTime) {
8855 var updateExpirationTime = workInProgress.expirationTime;
8856
8857 {
8858 if (workInProgress._debugNeedsRemount && current !== null) {
8859 // This will restart the begin phase with a new fiber.
8860 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
8861 }
8862 }
8863
8864 if (current !== null) {
8865 var oldProps = current.memoizedProps;
8866 var newProps = workInProgress.pendingProps;
8867
8868 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
8869 workInProgress.type !== current.type )) {
8870 // If props or context changed, mark the fiber as having performed work.
8871 // This may be unset if the props are determined to be equal later (memo).
8872 didReceiveUpdate = true;
8873 } else if (updateExpirationTime < renderExpirationTime) {
8874 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
8875 // the begin phase. There's still some bookkeeping we that needs to be done
8876 // in this optimized path, mostly pushing stuff onto the stack.
8877
8878 switch (workInProgress.tag) {
8879 case HostRoot:
8880 pushHostRootContext(workInProgress);
8881 break;
8882
8883 case HostComponent:
8884 pushHostContext(workInProgress);
8885
8886 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type)) {
8887 {
8888 markSpawnedWork(Never);
8889 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
8890
8891
8892 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
8893 return null;
8894 }
8895
8896 break;
8897
8898 case ClassComponent:
8899 {
8900 var Component = workInProgress.type;
8901
8902 if (isContextProvider(Component)) {
8903 pushContextProvider(workInProgress);
8904 }
8905
8906 break;
8907 }
8908
8909 case HostPortal:
8910 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8911 break;
8912
8913 case ContextProvider:
8914 {
8915 var newValue = workInProgress.memoizedProps.value;
8916 pushProvider(workInProgress, newValue);
8917 break;
8918 }
8919
8920 case Profiler:
8921 {
8922 // Profiler should only call onRender when one of its descendants actually rendered.
8923 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
8924
8925 if (hasChildWork) {
8926 workInProgress.effectTag |= Update;
8927 }
8928 }
8929
8930 break;
8931
8932 case SuspenseComponent:
8933 {
8934 var state = workInProgress.memoizedState;
8935
8936 if (state !== null) {
8937 // whether to retry the primary children, or to skip over it and
8938 // go straight to the fallback. Check the priority of the primary
8939 // child fragment.
8940
8941
8942 var primaryChildFragment = workInProgress.child;
8943 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
8944
8945 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
8946 // The primary children have pending work. Use the normal path
8947 // to attempt to render the primary children again.
8948 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
8949 } else {
8950 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
8951 // priority. Bailout.
8952
8953 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8954
8955 if (child !== null) {
8956 // The fallback children have pending work. Skip over the
8957 // primary children and work on the fallback.
8958 return child.sibling;
8959 } else {
8960 return null;
8961 }
8962 }
8963 } else {
8964 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
8965 }
8966
8967 break;
8968 }
8969
8970 case SuspenseListComponent:
8971 {
8972 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
8973
8974 var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
8975
8976 if (didSuspendBefore) {
8977 if (_hasChildWork) {
8978 // If something was in fallback state last time, and we have all the
8979 // same children then we're still in progressive loading state.
8980 // Something might get unblocked by state updates or retries in the
8981 // tree which will affect the tail. So we need to use the normal
8982 // path to compute the correct tail.
8983 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
8984 } // If none of the children had any work, that means that none of
8985 // them got retried so they'll still be blocked in the same way
8986 // as before. We can fast bail out.
8987
8988
8989 workInProgress.effectTag |= DidCapture;
8990 } // If nothing suspended before and we're rendering the same children,
8991 // then the tail doesn't matter. Anything new that suspends will work
8992 // in the "together" mode, so we can continue from the state we had.
8993
8994
8995 var renderState = workInProgress.memoizedState;
8996
8997 if (renderState !== null) {
8998 // Reset to the "together" mode in case we've started a different
8999 // update in the past but didn't complete it.
9000 renderState.rendering = null;
9001 renderState.tail = null;
9002 }
9003
9004 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
9005
9006 if (_hasChildWork) {
9007 break;
9008 } else {
9009 // If none of the children had any work, that means that none of
9010 // them got retried so they'll still be blocked in the same way
9011 // as before. We can fast bail out.
9012 return null;
9013 }
9014 }
9015 }
9016
9017 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9018 } else {
9019 // An update was scheduled on this fiber, but there are no new props
9020 // nor legacy context. Set this to false. If an update queue or context
9021 // consumer produces a changed value, it will set this to true. Otherwise,
9022 // the component will assume the children have not changed and bail out.
9023 didReceiveUpdate = false;
9024 }
9025 } else {
9026 didReceiveUpdate = false;
9027 } // Before entering the begin phase, clear pending update priority.
9028 // TODO: This assumes that we're about to evaluate the component and process
9029 // the update queue. However, there's an exception: SimpleMemoComponent
9030 // sometimes bails out later in the begin phase. This indicates that we should
9031 // move this assignment out of the common path and into each branch.
9032
9033
9034 workInProgress.expirationTime = NoWork;
9035
9036 switch (workInProgress.tag) {
9037 case IndeterminateComponent:
9038 {
9039 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
9040 }
9041
9042 case LazyComponent:
9043 {
9044 var elementType = workInProgress.elementType;
9045 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
9046 }
9047
9048 case FunctionComponent:
9049 {
9050 var _Component = workInProgress.type;
9051 var unresolvedProps = workInProgress.pendingProps;
9052 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
9053 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
9054 }
9055
9056 case ClassComponent:
9057 {
9058 var _Component2 = workInProgress.type;
9059 var _unresolvedProps = workInProgress.pendingProps;
9060
9061 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
9062
9063 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
9064 }
9065
9066 case HostRoot:
9067 return updateHostRoot(current, workInProgress, renderExpirationTime);
9068
9069 case HostComponent:
9070 return updateHostComponent(current, workInProgress, renderExpirationTime);
9071
9072 case HostText:
9073 return updateHostText();
9074
9075 case SuspenseComponent:
9076 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9077
9078 case HostPortal:
9079 return updatePortalComponent(current, workInProgress, renderExpirationTime);
9080
9081 case ForwardRef:
9082 {
9083 var type = workInProgress.type;
9084 var _unresolvedProps2 = workInProgress.pendingProps;
9085
9086 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
9087
9088 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
9089 }
9090
9091 case Fragment:
9092 return updateFragment(current, workInProgress, renderExpirationTime);
9093
9094 case Mode:
9095 return updateMode(current, workInProgress, renderExpirationTime);
9096
9097 case Profiler:
9098 return updateProfiler(current, workInProgress, renderExpirationTime);
9099
9100 case ContextProvider:
9101 return updateContextProvider(current, workInProgress, renderExpirationTime);
9102
9103 case ContextConsumer:
9104 return updateContextConsumer(current, workInProgress, renderExpirationTime);
9105
9106 case MemoComponent:
9107 {
9108 var _type2 = workInProgress.type;
9109 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
9110
9111 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
9112
9113 {
9114 if (workInProgress.type !== workInProgress.elementType) {
9115 var outerPropTypes = _type2.propTypes;
9116
9117 if (outerPropTypes) {
9118 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
9119 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
9120 }
9121 }
9122 }
9123
9124 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
9125 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
9126 }
9127
9128 case SimpleMemoComponent:
9129 {
9130 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
9131 }
9132
9133 case IncompleteClassComponent:
9134 {
9135 var _Component3 = workInProgress.type;
9136 var _unresolvedProps4 = workInProgress.pendingProps;
9137
9138 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
9139
9140 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
9141 }
9142
9143 case SuspenseListComponent:
9144 {
9145 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9146 }
9147 }
9148
9149 {
9150 {
9151 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
9152 }
9153 }
9154}
9155
9156function markUpdate(workInProgress) {
9157 // Tag the fiber with an update effect. This turns a Placement into
9158 // a PlacementAndUpdate.
9159 workInProgress.effectTag |= Update;
9160}
9161
9162function markRef$1(workInProgress) {
9163 workInProgress.effectTag |= Ref;
9164}
9165
9166var appendAllChildren;
9167var updateHostContainer;
9168var updateHostComponent$1;
9169var updateHostText$1;
9170
9171{
9172 // Mutation mode
9173 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9174 // We only have the top Fiber that was created but we need recurse down its
9175 // children to find all the terminal nodes.
9176 var node = workInProgress.child;
9177
9178 while (node !== null) {
9179 if (node.tag === HostComponent || node.tag === HostText) {
9180 appendInitialChild(parent, node.stateNode);
9181 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
9182 node.child.return = node;
9183 node = node.child;
9184 continue;
9185 }
9186
9187 if (node === workInProgress) {
9188 return;
9189 }
9190
9191 while (node.sibling === null) {
9192 if (node.return === null || node.return === workInProgress) {
9193 return;
9194 }
9195
9196 node = node.return;
9197 }
9198
9199 node.sibling.return = node.return;
9200 node = node.sibling;
9201 }
9202 };
9203
9204 updateHostContainer = function (workInProgress) {// Noop
9205 };
9206
9207 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9208 // If we have an alternate, that means this is an update and we need to
9209 // schedule a side-effect to do the updates.
9210 var oldProps = current.memoizedProps;
9211
9212 if (oldProps === newProps) {
9213 // In mutation mode, this is sufficient for a bailout because
9214 // we won't touch this node even if children changed.
9215 return;
9216 } // If we get updated because one of our children updated, we don't
9217 // have newProps so we'll have to reuse them.
9218 // TODO: Split the update API as separate for the props vs. children.
9219 // Even better would be if children weren't special cased at all tho.
9220
9221
9222 var instance = workInProgress.stateNode;
9223 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
9224 // component is hitting the resume path. Figure out why. Possibly
9225 // related to `hidden`.
9226
9227 var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component.
9228
9229 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
9230 // is a new ref we mark this as an update. All the work is done in commitWork.
9231
9232 if (updatePayload) {
9233 markUpdate(workInProgress);
9234 }
9235 };
9236
9237 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9238 // If the text differs, mark it as an update. All the work in done in commitWork.
9239 if (oldText !== newText) {
9240 markUpdate(workInProgress);
9241 }
9242 };
9243}
9244
9245function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
9246 switch (renderState.tailMode) {
9247 case 'hidden':
9248 {
9249 // Any insertions at the end of the tail list after this point
9250 // should be invisible. If there are already mounted boundaries
9251 // anything before them are not considered for collapsing.
9252 // Therefore we need to go through the whole tail to find if
9253 // there are any.
9254 var tailNode = renderState.tail;
9255 var lastTailNode = null;
9256
9257 while (tailNode !== null) {
9258 if (tailNode.alternate !== null) {
9259 lastTailNode = tailNode;
9260 }
9261
9262 tailNode = tailNode.sibling;
9263 } // Next we're simply going to delete all insertions after the
9264 // last rendered item.
9265
9266
9267 if (lastTailNode === null) {
9268 // All remaining items in the tail are insertions.
9269 renderState.tail = null;
9270 } else {
9271 // Detach the insertion after the last node that was already
9272 // inserted.
9273 lastTailNode.sibling = null;
9274 }
9275
9276 break;
9277 }
9278
9279 case 'collapsed':
9280 {
9281 // Any insertions at the end of the tail list after this point
9282 // should be invisible. If there are already mounted boundaries
9283 // anything before them are not considered for collapsing.
9284 // Therefore we need to go through the whole tail to find if
9285 // there are any.
9286 var _tailNode = renderState.tail;
9287 var _lastTailNode = null;
9288
9289 while (_tailNode !== null) {
9290 if (_tailNode.alternate !== null) {
9291 _lastTailNode = _tailNode;
9292 }
9293
9294 _tailNode = _tailNode.sibling;
9295 } // Next we're simply going to delete all insertions after the
9296 // last rendered item.
9297
9298
9299 if (_lastTailNode === null) {
9300 // All remaining items in the tail are insertions.
9301 if (!hasRenderedATailFallback && renderState.tail !== null) {
9302 // We suspended during the head. We want to show at least one
9303 // row at the tail. So we'll keep on and cut off the rest.
9304 renderState.tail.sibling = null;
9305 } else {
9306 renderState.tail = null;
9307 }
9308 } else {
9309 // Detach the insertion after the last node that was already
9310 // inserted.
9311 _lastTailNode.sibling = null;
9312 }
9313
9314 break;
9315 }
9316 }
9317}
9318
9319function completeWork(current, workInProgress, renderExpirationTime) {
9320 var newProps = workInProgress.pendingProps;
9321
9322 switch (workInProgress.tag) {
9323 case IndeterminateComponent:
9324 case LazyComponent:
9325 case SimpleMemoComponent:
9326 case FunctionComponent:
9327 case ForwardRef:
9328 case Fragment:
9329 case Mode:
9330 case Profiler:
9331 case ContextConsumer:
9332 case MemoComponent:
9333 return null;
9334
9335 case ClassComponent:
9336 {
9337 var Component = workInProgress.type;
9338
9339 if (isContextProvider(Component)) {
9340 popContext(workInProgress);
9341 }
9342
9343 return null;
9344 }
9345
9346 case HostRoot:
9347 {
9348 popHostContainer(workInProgress);
9349 popTopLevelContextObject(workInProgress);
9350 var fiberRoot = workInProgress.stateNode;
9351
9352 if (fiberRoot.pendingContext) {
9353 fiberRoot.context = fiberRoot.pendingContext;
9354 fiberRoot.pendingContext = null;
9355 }
9356
9357 if (current === null || current.child === null) {
9358 // If we hydrated, pop so that we can delete any remaining children
9359 // that weren't hydrated.
9360 var wasHydrated = popHydrationState();
9361
9362 if (wasHydrated) {
9363 // If we hydrated, then we'll need to schedule an update for
9364 // the commit side-effects on the root.
9365 markUpdate(workInProgress);
9366 }
9367 }
9368
9369 updateHostContainer(workInProgress);
9370 return null;
9371 }
9372
9373 case HostComponent:
9374 {
9375 popHostContext(workInProgress);
9376 var rootContainerInstance = getRootHostContainer();
9377 var type = workInProgress.type;
9378
9379 if (current !== null && workInProgress.stateNode != null) {
9380 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9381
9382 if (current.ref !== workInProgress.ref) {
9383 markRef$1(workInProgress);
9384 }
9385 } else {
9386 if (!newProps) {
9387 if (!(workInProgress.stateNode !== null)) {
9388 {
9389 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
9390 }
9391 } // This can happen when we abort work.
9392
9393
9394 return null;
9395 }
9396
9397 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
9398 // "stack" as the parent. Then append children as we go in beginWork
9399 // or completeWork depending on whether we want to add them top->down or
9400 // bottom->up. Top->down is faster in IE11.
9401
9402 var _wasHydrated = popHydrationState();
9403
9404 if (_wasHydrated) {
9405 // TODO: Move this and createInstance step into the beginPhase
9406 // to consolidate.
9407 if (prepareToHydrateHostInstance()) {
9408 // If changes to the hydrated node need to be applied at the
9409 // commit-phase we mark this as such.
9410 markUpdate(workInProgress);
9411 }
9412 } else {
9413 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9414 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
9415
9416 workInProgress.stateNode = instance;
9417 }
9418
9419 if (workInProgress.ref !== null) {
9420 // If there is a ref on a host node we need to schedule a callback
9421 markRef$1(workInProgress);
9422 }
9423 }
9424
9425 return null;
9426 }
9427
9428 case HostText:
9429 {
9430 var newText = newProps;
9431
9432 if (current && workInProgress.stateNode != null) {
9433 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
9434 // to schedule a side-effect to do the updates.
9435
9436 updateHostText$1(current, workInProgress, oldText, newText);
9437 } else {
9438 if (typeof newText !== 'string') {
9439 if (!(workInProgress.stateNode !== null)) {
9440 {
9441 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
9442 }
9443 } // This can happen when we abort work.
9444
9445 }
9446
9447 var _rootContainerInstance = getRootHostContainer();
9448
9449 var _currentHostContext = getHostContext();
9450
9451 var _wasHydrated2 = popHydrationState();
9452
9453 if (_wasHydrated2) {
9454 if (prepareToHydrateHostTextInstance()) {
9455 markUpdate(workInProgress);
9456 }
9457 } else {
9458 workInProgress.stateNode = createTextInstance(newText);
9459 }
9460 }
9461
9462 return null;
9463 }
9464
9465 case SuspenseComponent:
9466 {
9467 popSuspenseContext(workInProgress);
9468 var nextState = workInProgress.memoizedState;
9469
9470 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9471 // Something suspended. Re-render with the fallback children.
9472 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
9473
9474 return workInProgress;
9475 }
9476
9477 var nextDidTimeout = nextState !== null;
9478 var prevDidTimeout = false;
9479
9480 if (current === null) {
9481 if (workInProgress.memoizedProps.fallback !== undefined) ;
9482 } else {
9483 var prevState = current.memoizedState;
9484 prevDidTimeout = prevState !== null;
9485
9486 if (!nextDidTimeout && prevState !== null) {
9487 // We just switched from the fallback to the normal children.
9488 // Delete the fallback.
9489 // TODO: Would it be better to store the fallback fragment on
9490 // the stateNode during the begin phase?
9491 var currentFallbackChild = current.child.sibling;
9492
9493 if (currentFallbackChild !== null) {
9494 // Deletions go at the beginning of the return fiber's effect list
9495 var first = workInProgress.firstEffect;
9496
9497 if (first !== null) {
9498 workInProgress.firstEffect = currentFallbackChild;
9499 currentFallbackChild.nextEffect = first;
9500 } else {
9501 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9502 currentFallbackChild.nextEffect = null;
9503 }
9504
9505 currentFallbackChild.effectTag = Deletion;
9506 }
9507 }
9508 }
9509
9510 if (nextDidTimeout && !prevDidTimeout) {
9511 // If this subtreee is running in blocking mode we can suspend,
9512 // otherwise we won't suspend.
9513 // TODO: This will still suspend a synchronous tree if anything
9514 // in the concurrent tree already suspended during this render.
9515 // This is a known bug.
9516 if ((workInProgress.mode & BlockingMode) !== NoMode) {
9517 // TODO: Move this back to throwException because this is too late
9518 // if this is a large tree which is common for initial loads. We
9519 // don't know if we should restart a render or not until we get
9520 // this marker, and this is too late.
9521 // If this render already had a ping or lower pri updates,
9522 // and this is the first time we know we're going to suspend we
9523 // should be able to immediately restart from within throwException.
9524 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
9525
9526 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
9527 // If this was in an invisible tree or a new render, then showing
9528 // this boundary is ok.
9529 renderDidSuspend();
9530 } else {
9531 // Otherwise, we're going to have to hide content so we should
9532 // suspend for longer if possible.
9533 renderDidSuspendDelayIfPossible();
9534 }
9535 }
9536 }
9537
9538 {
9539 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
9540 if (nextDidTimeout || prevDidTimeout) {
9541 // If this boundary just timed out, schedule an effect to attach a
9542 // retry listener to the promise. This flag is also used to hide the
9543 // primary children. In mutation mode, we also need the flag to
9544 // *unhide* children that were previously hidden, so check if this
9545 // is currently timed out, too.
9546 workInProgress.effectTag |= Update;
9547 }
9548 }
9549
9550 return null;
9551 }
9552
9553 case HostPortal:
9554 popHostContainer(workInProgress);
9555 updateHostContainer(workInProgress);
9556 return null;
9557
9558 case ContextProvider:
9559 // Pop provider fiber
9560 popProvider(workInProgress);
9561 return null;
9562
9563 case IncompleteClassComponent:
9564 {
9565 // Same as class component case. I put it down here so that the tags are
9566 // sequential to ensure this switch is compiled to a jump table.
9567 var _Component = workInProgress.type;
9568
9569 if (isContextProvider(_Component)) {
9570 popContext(workInProgress);
9571 }
9572
9573 return null;
9574 }
9575
9576 case SuspenseListComponent:
9577 {
9578 popSuspenseContext(workInProgress);
9579 var renderState = workInProgress.memoizedState;
9580
9581 if (renderState === null) {
9582 // We're running in the default, "independent" mode.
9583 // We don't do anything in this mode.
9584 return null;
9585 }
9586
9587 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
9588 var renderedTail = renderState.rendering;
9589
9590 if (renderedTail === null) {
9591 // We just rendered the head.
9592 if (!didSuspendAlready) {
9593 // This is the first pass. We need to figure out if anything is still
9594 // suspended in the rendered set.
9595 // If new content unsuspended, but there's still some content that
9596 // didn't. Then we need to do a second pass that forces everything
9597 // to keep showing their fallbacks.
9598 // We might be suspended if something in this render pass suspended, or
9599 // something in the previous committed pass suspended. Otherwise,
9600 // there's no chance so we can skip the expensive call to
9601 // findFirstSuspended.
9602 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
9603
9604 if (!cannotBeSuspended) {
9605 var row = workInProgress.child;
9606
9607 while (row !== null) {
9608 var suspended = findFirstSuspended(row);
9609
9610 if (suspended !== null) {
9611 didSuspendAlready = true;
9612 workInProgress.effectTag |= DidCapture;
9613 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
9614 // part of the second pass. In that case nothing will subscribe to
9615 // its thennables. Instead, we'll transfer its thennables to the
9616 // SuspenseList so that it can retry if they resolve.
9617 // There might be multiple of these in the list but since we're
9618 // going to wait for all of them anyway, it doesn't really matter
9619 // which ones gets to ping. In theory we could get clever and keep
9620 // track of how many dependencies remain but it gets tricky because
9621 // in the meantime, we can add/remove/change items and dependencies.
9622 // We might bail out of the loop before finding any but that
9623 // doesn't matter since that means that the other boundaries that
9624 // we did find already has their listeners attached.
9625
9626 var newThennables = suspended.updateQueue;
9627
9628 if (newThennables !== null) {
9629 workInProgress.updateQueue = newThennables;
9630 workInProgress.effectTag |= Update;
9631 } // Rerender the whole list, but this time, we'll force fallbacks
9632 // to stay in place.
9633 // Reset the effect list before doing the second pass since that's now invalid.
9634
9635
9636 if (renderState.lastEffect === null) {
9637 workInProgress.firstEffect = null;
9638 }
9639
9640 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
9641
9642 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
9643 // rerender the children.
9644
9645 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
9646 return workInProgress.child;
9647 }
9648
9649 row = row.sibling;
9650 }
9651 }
9652 } else {
9653 cutOffTailIfNeeded(renderState, false);
9654 } // Next we're going to render the tail.
9655
9656 } else {
9657 // Append the rendered row to the child list.
9658 if (!didSuspendAlready) {
9659 var _suspended = findFirstSuspended(renderedTail);
9660
9661 if (_suspended !== null) {
9662 workInProgress.effectTag |= DidCapture;
9663 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
9664 // get lost if this row ends up dropped during a second pass.
9665
9666 var _newThennables = _suspended.updateQueue;
9667
9668 if (_newThennables !== null) {
9669 workInProgress.updateQueue = _newThennables;
9670 workInProgress.effectTag |= Update;
9671 }
9672
9673 cutOffTailIfNeeded(renderState, true); // This might have been modified.
9674
9675 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {
9676 // We need to delete the row we just rendered.
9677 // Reset the effect list to what it was before we rendered this
9678 // child. The nested children have already appended themselves.
9679 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
9680
9681 if (lastEffect !== null) {
9682 lastEffect.nextEffect = null;
9683 } // We're done.
9684
9685
9686 return null;
9687 }
9688 } else if ( // The time it took to render last row is greater than time until
9689 // the expiration.
9690 now() * 2 - renderState.renderingStartTime > renderState.tailExpiration && renderExpirationTime > Never) {
9691 // We have now passed our CPU deadline and we'll just give up further
9692 // attempts to render the main content and only render fallbacks.
9693 // The assumption is that this is usually faster.
9694 workInProgress.effectTag |= DidCapture;
9695 didSuspendAlready = true;
9696 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
9697 // to get it started back up to attempt the next item. If we can show
9698 // them, then they really have the same priority as this render.
9699 // So we'll pick it back up the very next render pass once we've had
9700 // an opportunity to yield for paint.
9701
9702 var nextPriority = renderExpirationTime - 1;
9703 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
9704
9705 {
9706 markSpawnedWork(nextPriority);
9707 }
9708 }
9709 }
9710
9711 if (renderState.isBackwards) {
9712 // The effect list of the backwards tail will have been added
9713 // to the end. This breaks the guarantee that life-cycles fire in
9714 // sibling order but that isn't a strong guarantee promised by React.
9715 // Especially since these might also just pop in during future commits.
9716 // Append to the beginning of the list.
9717 renderedTail.sibling = workInProgress.child;
9718 workInProgress.child = renderedTail;
9719 } else {
9720 var previousSibling = renderState.last;
9721
9722 if (previousSibling !== null) {
9723 previousSibling.sibling = renderedTail;
9724 } else {
9725 workInProgress.child = renderedTail;
9726 }
9727
9728 renderState.last = renderedTail;
9729 }
9730 }
9731
9732 if (renderState.tail !== null) {
9733 // We still have tail rows to render.
9734 if (renderState.tailExpiration === 0) {
9735 // Heuristic for how long we're willing to spend rendering rows
9736 // until we just give up and show what we have so far.
9737 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
9738 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this
9739 // is a per component value. It should really be since the start
9740 // of the total render or last commit. Consider using something like
9741 // globalMostRecentFallbackTime. That doesn't account for being
9742 // suspended for part of the time or when it's a new render.
9743 // It should probably use a global start time value instead.
9744 } // Pop a row.
9745
9746
9747 var next = renderState.tail;
9748 renderState.rendering = next;
9749 renderState.tail = next.sibling;
9750 renderState.lastEffect = workInProgress.lastEffect;
9751 renderState.renderingStartTime = now();
9752 next.sibling = null; // Restore the context.
9753 // TODO: We can probably just avoid popping it instead and only
9754 // setting it the first time we go from not suspended to suspended.
9755
9756 var suspenseContext = suspenseStackCursor.current;
9757
9758 if (didSuspendAlready) {
9759 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
9760 } else {
9761 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
9762 }
9763
9764 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
9765
9766 return next;
9767 }
9768
9769 return null;
9770 }
9771 }
9772
9773 {
9774 {
9775 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
9776 }
9777 }
9778}
9779
9780function unwindWork(workInProgress, renderExpirationTime) {
9781 switch (workInProgress.tag) {
9782 case ClassComponent:
9783 {
9784 var Component = workInProgress.type;
9785
9786 if (isContextProvider(Component)) {
9787 popContext(workInProgress);
9788 }
9789
9790 var effectTag = workInProgress.effectTag;
9791
9792 if (effectTag & ShouldCapture) {
9793 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
9794 return workInProgress;
9795 }
9796
9797 return null;
9798 }
9799
9800 case HostRoot:
9801 {
9802 popHostContainer(workInProgress);
9803 popTopLevelContextObject(workInProgress);
9804 var _effectTag = workInProgress.effectTag;
9805
9806 if (!((_effectTag & DidCapture) === NoEffect)) {
9807 {
9808 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
9809 }
9810 }
9811
9812 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
9813 return workInProgress;
9814 }
9815
9816 case HostComponent:
9817 {
9818 // TODO: popHydrationState
9819 popHostContext(workInProgress);
9820 return null;
9821 }
9822
9823 case SuspenseComponent:
9824 {
9825 popSuspenseContext(workInProgress);
9826
9827 var _effectTag2 = workInProgress.effectTag;
9828
9829 if (_effectTag2 & ShouldCapture) {
9830 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
9831
9832 return workInProgress;
9833 }
9834
9835 return null;
9836 }
9837
9838 case SuspenseListComponent:
9839 {
9840 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
9841 // caught by a nested boundary. If not, it should bubble through.
9842
9843 return null;
9844 }
9845
9846 case HostPortal:
9847 popHostContainer(workInProgress);
9848 return null;
9849
9850 case ContextProvider:
9851 popProvider(workInProgress);
9852 return null;
9853
9854 default:
9855 return null;
9856 }
9857}
9858
9859function unwindInterruptedWork(interruptedWork) {
9860 switch (interruptedWork.tag) {
9861 case ClassComponent:
9862 {
9863 var childContextTypes = interruptedWork.type.childContextTypes;
9864
9865 if (childContextTypes !== null && childContextTypes !== undefined) {
9866 popContext(interruptedWork);
9867 }
9868
9869 break;
9870 }
9871
9872 case HostRoot:
9873 {
9874 popHostContainer(interruptedWork);
9875 popTopLevelContextObject(interruptedWork);
9876 break;
9877 }
9878
9879 case HostComponent:
9880 {
9881 popHostContext(interruptedWork);
9882 break;
9883 }
9884
9885 case HostPortal:
9886 popHostContainer(interruptedWork);
9887 break;
9888
9889 case SuspenseComponent:
9890 popSuspenseContext(interruptedWork);
9891 break;
9892
9893 case SuspenseListComponent:
9894 popSuspenseContext(interruptedWork);
9895 break;
9896
9897 case ContextProvider:
9898 popProvider(interruptedWork);
9899 break;
9900 }
9901}
9902
9903function createCapturedValue(value, source) {
9904 // If the value is an error, call this function immediately after it is thrown
9905 // so the stack is accurate.
9906 return {
9907 value: value,
9908 source: source,
9909 stack: getStackByFiberInDevAndProd(source)
9910 };
9911}
9912
9913var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
9914 var funcArgs = Array.prototype.slice.call(arguments, 3);
9915
9916 try {
9917 func.apply(context, funcArgs);
9918 } catch (error) {
9919 this.onError(error);
9920 }
9921};
9922
9923{
9924 // In DEV mode, we swap out invokeGuardedCallback for a special version
9925 // that plays more nicely with the browser's DevTools. The idea is to preserve
9926 // "Pause on exceptions" behavior. Because React wraps all user-provided
9927 // functions in invokeGuardedCallback, and the production version of
9928 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
9929 // like caught exceptions, and the DevTools won't pause unless the developer
9930 // takes the extra step of enabling pause on caught exceptions. This is
9931 // unintuitive, though, because even though React has caught the error, from
9932 // the developer's perspective, the error is uncaught.
9933 //
9934 // To preserve the expected "Pause on exceptions" behavior, we don't use a
9935 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
9936 // DOM node, and call the user-provided callback from inside an event handler
9937 // for that fake event. If the callback throws, the error is "captured" using
9938 // a global event handler. But because the error happens in a different
9939 // event loop context, it does not interrupt the normal program flow.
9940 // Effectively, this gives us try-catch behavior without actually using
9941 // try-catch. Neat!
9942 // Check that the browser supports the APIs we need to implement our special
9943 // DEV version of invokeGuardedCallback
9944 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
9945 var fakeNode = document.createElement('react');
9946
9947 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
9948 // If document doesn't exist we know for sure we will crash in this method
9949 // when we call document.createEvent(). However this can cause confusing
9950 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
9951 // So we preemptively throw with a better message instead.
9952 if (!(typeof document !== 'undefined')) {
9953 {
9954 throw 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." );
9955 }
9956 }
9957
9958 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
9959 // set this to true at the beginning, then set it to false right after
9960 // calling the function. If the function errors, `didError` will never be
9961 // set to false. This strategy works even if the browser is flaky and
9962 // fails to call our global error handler, because it doesn't rely on
9963 // the error event at all.
9964
9965 var didError = true; // Keeps track of the value of window.event so that we can reset it
9966 // during the callback to let user code access window.event in the
9967 // browsers that support it.
9968
9969 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
9970 // dispatching: https://github.com/facebook/react/issues/13688
9971
9972 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
9973 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
9974 // call the user-provided callback.
9975
9976 var funcArgs = Array.prototype.slice.call(arguments, 3);
9977
9978 function callCallback() {
9979 // We immediately remove the callback from event listeners so that
9980 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
9981 // nested call would trigger the fake event handlers of any call higher
9982 // in the stack.
9983 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
9984 // window.event assignment in both IE <= 10 as they throw an error
9985 // "Member not found" in strict mode, and in Firefox which does not
9986 // support window.event.
9987
9988 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
9989 window.event = windowEvent;
9990 }
9991
9992 func.apply(context, funcArgs);
9993 didError = false;
9994 } // Create a global error event handler. We use this to capture the value
9995 // that was thrown. It's possible that this error handler will fire more
9996 // than once; for example, if non-React code also calls `dispatchEvent`
9997 // and a handler for that event throws. We should be resilient to most of
9998 // those cases. Even if our error event handler fires more than once, the
9999 // last error event is always used. If the callback actually does error,
10000 // we know that the last error event is the correct one, because it's not
10001 // possible for anything else to have happened in between our callback
10002 // erroring and the code that follows the `dispatchEvent` call below. If
10003 // the callback doesn't error, but the error event was fired, we know to
10004 // ignore it because `didError` will be false, as described above.
10005
10006
10007 var error; // Use this to track whether the error event is ever called.
10008
10009 var didSetError = false;
10010 var isCrossOriginError = false;
10011
10012 function handleWindowError(event) {
10013 error = event.error;
10014 didSetError = true;
10015
10016 if (error === null && event.colno === 0 && event.lineno === 0) {
10017 isCrossOriginError = true;
10018 }
10019
10020 if (event.defaultPrevented) {
10021 // Some other error handler has prevented default.
10022 // Browsers silence the error report if this happens.
10023 // We'll remember this to later decide whether to log it or not.
10024 if (error != null && typeof error === 'object') {
10025 try {
10026 error._suppressLogging = true;
10027 } catch (inner) {// Ignore.
10028 }
10029 }
10030 }
10031 } // Create a fake event type.
10032
10033
10034 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
10035
10036 window.addEventListener('error', handleWindowError);
10037 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
10038 // errors, it will trigger our global error handler.
10039
10040 evt.initEvent(evtType, false, false);
10041 fakeNode.dispatchEvent(evt);
10042
10043 if (windowEventDescriptor) {
10044 Object.defineProperty(window, 'event', windowEventDescriptor);
10045 }
10046
10047 if (didError) {
10048 if (!didSetError) {
10049 // The callback errored, but the error event never fired.
10050 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.');
10051 } else if (isCrossOriginError) {
10052 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.');
10053 }
10054
10055 this.onError(error);
10056 } // Remove our event listeners
10057
10058
10059 window.removeEventListener('error', handleWindowError);
10060 };
10061
10062 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
10063 }
10064}
10065
10066var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
10067
10068var hasError = false;
10069var caughtError = null; // Used by event system to capture/rethrow the first error.
10070var reporter = {
10071 onError: function (error) {
10072 hasError = true;
10073 caughtError = error;
10074 }
10075};
10076/**
10077 * Call a function while guarding against errors that happens within it.
10078 * Returns an error if it throws, otherwise null.
10079 *
10080 * In production, this is implemented using a try-catch. The reason we don't
10081 * use a try-catch directly is so that we can swap out a different
10082 * implementation in DEV mode.
10083 *
10084 * @param {String} name of the guard to use for logging or debugging
10085 * @param {Function} func The function to invoke
10086 * @param {*} context The context to use when calling the function
10087 * @param {...*} args Arguments for function
10088 */
10089
10090function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
10091 hasError = false;
10092 caughtError = null;
10093 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
10094}
10095function hasCaughtError() {
10096 return hasError;
10097}
10098function clearCaughtError() {
10099 if (hasError) {
10100 var error = caughtError;
10101 hasError = false;
10102 caughtError = null;
10103 return error;
10104 } else {
10105 {
10106 {
10107 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
10108 }
10109 }
10110 }
10111}
10112
10113function logCapturedError(capturedError) {
10114
10115 var error = capturedError.error;
10116
10117 {
10118 var componentName = capturedError.componentName,
10119 componentStack = capturedError.componentStack,
10120 errorBoundaryName = capturedError.errorBoundaryName,
10121 errorBoundaryFound = capturedError.errorBoundaryFound,
10122 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
10123 // `preventDefault()` in window `error` handler.
10124 // We record this information as an expando on the error.
10125
10126 if (error != null && error._suppressLogging) {
10127 if (errorBoundaryFound && willRetry) {
10128 // The error is recoverable and was silenced.
10129 // Ignore it and don't print the stack addendum.
10130 // This is handy for testing error boundaries without noise.
10131 return;
10132 } // The error is fatal. Since the silencing might have
10133 // been accidental, we'll surface it anyway.
10134 // However, the browser would have silenced the original error
10135 // so we'll print it first, and then print the stack addendum.
10136
10137
10138 console['error'](error); // Don't transform to our wrapper
10139 // For a more detailed description of this block, see:
10140 // https://github.com/facebook/react/pull/13384
10141 }
10142
10143 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
10144 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10145
10146 if (errorBoundaryFound && errorBoundaryName) {
10147 if (willRetry) {
10148 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
10149 } else {
10150 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
10151 }
10152 } else {
10153 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.';
10154 }
10155
10156 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
10157 // We don't include the original error message and JS stack because the browser
10158 // has already printed it. Even if the application swallows the error, it is still
10159 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10160
10161 console['error'](combinedMessage); // Don't transform to our wrapper
10162 }
10163}
10164
10165var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
10166
10167{
10168 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
10169}
10170
10171var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
10172function logError(boundary, errorInfo) {
10173 var source = errorInfo.source;
10174 var stack = errorInfo.stack;
10175
10176 if (stack === null && source !== null) {
10177 stack = getStackByFiberInDevAndProd(source);
10178 }
10179
10180 var capturedError = {
10181 componentName: source !== null ? getComponentName(source.type) : null,
10182 componentStack: stack !== null ? stack : '',
10183 error: errorInfo.value,
10184 errorBoundary: null,
10185 errorBoundaryName: null,
10186 errorBoundaryFound: false,
10187 willRetry: false
10188 };
10189
10190 if (boundary !== null && boundary.tag === ClassComponent) {
10191 capturedError.errorBoundary = boundary.stateNode;
10192 capturedError.errorBoundaryName = getComponentName(boundary.type);
10193 capturedError.errorBoundaryFound = true;
10194 capturedError.willRetry = true;
10195 }
10196
10197 try {
10198 logCapturedError(capturedError);
10199 } catch (e) {
10200 // This method must not throw, or React internal state will get messed up.
10201 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
10202 // we want to report this error outside of the normal stack as a last resort.
10203 // https://github.com/facebook/react/issues/13188
10204 setTimeout(function () {
10205 throw e;
10206 });
10207 }
10208}
10209
10210var callComponentWillUnmountWithTimer = function (current, instance) {
10211 startPhaseTimer(current, 'componentWillUnmount');
10212 instance.props = current.memoizedProps;
10213 instance.state = current.memoizedState;
10214 instance.componentWillUnmount();
10215 stopPhaseTimer();
10216}; // Capture errors so they don't interrupt unmounting.
10217
10218
10219function safelyCallComponentWillUnmount(current, instance) {
10220 {
10221 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
10222
10223 if (hasCaughtError()) {
10224 var unmountError = clearCaughtError();
10225 captureCommitPhaseError(current, unmountError);
10226 }
10227 }
10228}
10229
10230function safelyDetachRef(current) {
10231 var ref = current.ref;
10232
10233 if (ref !== null) {
10234 if (typeof ref === 'function') {
10235 {
10236 invokeGuardedCallback(null, ref, null, null);
10237
10238 if (hasCaughtError()) {
10239 var refError = clearCaughtError();
10240 captureCommitPhaseError(current, refError);
10241 }
10242 }
10243 } else {
10244 ref.current = null;
10245 }
10246 }
10247}
10248
10249function safelyCallDestroy(current, destroy) {
10250 {
10251 invokeGuardedCallback(null, destroy, null);
10252
10253 if (hasCaughtError()) {
10254 var error = clearCaughtError();
10255 captureCommitPhaseError(current, error);
10256 }
10257 }
10258}
10259
10260function commitBeforeMutationLifeCycles(current, finishedWork) {
10261 switch (finishedWork.tag) {
10262 case FunctionComponent:
10263 case ForwardRef:
10264 case SimpleMemoComponent:
10265 case Block:
10266 {
10267 return;
10268 }
10269
10270 case ClassComponent:
10271 {
10272 if (finishedWork.effectTag & Snapshot) {
10273 if (current !== null) {
10274 var prevProps = current.memoizedProps;
10275 var prevState = current.memoizedState;
10276 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
10277 var instance = finishedWork.stateNode; // We could update instance props and state here,
10278 // but instead we rely on them being set during last render.
10279 // TODO: revisit this when we implement resuming.
10280
10281 {
10282 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10283 if (instance.props !== finishedWork.memoizedProps) {
10284 error('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');
10285 }
10286
10287 if (instance.state !== finishedWork.memoizedState) {
10288 error('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');
10289 }
10290 }
10291 }
10292
10293 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
10294
10295 {
10296 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
10297
10298 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
10299 didWarnSet.add(finishedWork.type);
10300
10301 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
10302 }
10303 }
10304
10305 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
10306 stopPhaseTimer();
10307 }
10308 }
10309
10310 return;
10311 }
10312
10313 case HostRoot:
10314 case HostComponent:
10315 case HostText:
10316 case HostPortal:
10317 case IncompleteClassComponent:
10318 // Nothing to do for these component types
10319 return;
10320 }
10321
10322 {
10323 {
10324 throw 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." );
10325 }
10326 }
10327}
10328
10329function commitHookEffectListUnmount(tag, finishedWork) {
10330 var updateQueue = finishedWork.updateQueue;
10331 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10332
10333 if (lastEffect !== null) {
10334 var firstEffect = lastEffect.next;
10335 var effect = firstEffect;
10336
10337 do {
10338 if ((effect.tag & tag) === tag) {
10339 // Unmount
10340 var destroy = effect.destroy;
10341 effect.destroy = undefined;
10342
10343 if (destroy !== undefined) {
10344 destroy();
10345 }
10346 }
10347
10348 effect = effect.next;
10349 } while (effect !== firstEffect);
10350 }
10351}
10352
10353function commitHookEffectListMount(tag, finishedWork) {
10354 var updateQueue = finishedWork.updateQueue;
10355 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10356
10357 if (lastEffect !== null) {
10358 var firstEffect = lastEffect.next;
10359 var effect = firstEffect;
10360
10361 do {
10362 if ((effect.tag & tag) === tag) {
10363 // Mount
10364 var create = effect.create;
10365 effect.destroy = create();
10366
10367 {
10368 var destroy = effect.destroy;
10369
10370 if (destroy !== undefined && typeof destroy !== 'function') {
10371 var addendum = void 0;
10372
10373 if (destroy === null) {
10374 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
10375 } else if (typeof destroy.then === 'function') {
10376 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';
10377 } else {
10378 addendum = ' You returned: ' + destroy;
10379 }
10380
10381 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
10382 }
10383 }
10384 }
10385
10386 effect = effect.next;
10387 } while (effect !== firstEffect);
10388 }
10389}
10390
10391function commitPassiveHookEffects(finishedWork) {
10392 if ((finishedWork.effectTag & Passive) !== NoEffect) {
10393 switch (finishedWork.tag) {
10394 case FunctionComponent:
10395 case ForwardRef:
10396 case SimpleMemoComponent:
10397 case Block:
10398 {
10399 // TODO (#17945) We should call all passive destroy functions (for all fibers)
10400 // before calling any create functions. The current approach only serializes
10401 // these for a single fiber.
10402 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
10403 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
10404 break;
10405 }
10406 }
10407 }
10408}
10409
10410function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
10411 switch (finishedWork.tag) {
10412 case FunctionComponent:
10413 case ForwardRef:
10414 case SimpleMemoComponent:
10415 case Block:
10416 {
10417 // At this point layout effects have already been destroyed (during mutation phase).
10418 // This is done to prevent sibling component effects from interfering with each other,
10419 // e.g. a destroy function in one component should never override a ref set
10420 // by a create function in another component during the same commit.
10421 commitHookEffectListMount(Layout | HasEffect, finishedWork);
10422
10423 return;
10424 }
10425
10426 case ClassComponent:
10427 {
10428 var instance = finishedWork.stateNode;
10429
10430 if (finishedWork.effectTag & Update) {
10431 if (current === null) {
10432 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
10433 // but instead we rely on them being set during last render.
10434 // TODO: revisit this when we implement resuming.
10435
10436 {
10437 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10438 if (instance.props !== finishedWork.memoizedProps) {
10439 error('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');
10440 }
10441
10442 if (instance.state !== finishedWork.memoizedState) {
10443 error('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');
10444 }
10445 }
10446 }
10447
10448 instance.componentDidMount();
10449 stopPhaseTimer();
10450 } else {
10451 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
10452 var prevState = current.memoizedState;
10453 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
10454 // but instead we rely on them being set during last render.
10455 // TODO: revisit this when we implement resuming.
10456
10457 {
10458 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10459 if (instance.props !== finishedWork.memoizedProps) {
10460 error('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');
10461 }
10462
10463 if (instance.state !== finishedWork.memoizedState) {
10464 error('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');
10465 }
10466 }
10467 }
10468
10469 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
10470 stopPhaseTimer();
10471 }
10472 }
10473
10474 var updateQueue = finishedWork.updateQueue;
10475
10476 if (updateQueue !== null) {
10477 {
10478 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10479 if (instance.props !== finishedWork.memoizedProps) {
10480 error('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');
10481 }
10482
10483 if (instance.state !== finishedWork.memoizedState) {
10484 error('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');
10485 }
10486 }
10487 } // We could update instance props and state here,
10488 // but instead we rely on them being set during last render.
10489 // TODO: revisit this when we implement resuming.
10490
10491
10492 commitUpdateQueue(finishedWork, updateQueue, instance);
10493 }
10494
10495 return;
10496 }
10497
10498 case HostRoot:
10499 {
10500 var _updateQueue = finishedWork.updateQueue;
10501
10502 if (_updateQueue !== null) {
10503 var _instance = null;
10504
10505 if (finishedWork.child !== null) {
10506 switch (finishedWork.child.tag) {
10507 case HostComponent:
10508 _instance = getPublicInstance(finishedWork.child.stateNode);
10509 break;
10510
10511 case ClassComponent:
10512 _instance = finishedWork.child.stateNode;
10513 break;
10514 }
10515 }
10516
10517 commitUpdateQueue(finishedWork, _updateQueue, _instance);
10518 }
10519
10520 return;
10521 }
10522
10523 case HostComponent:
10524 {
10525 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
10526 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
10527 // These effects should only be committed when components are first mounted,
10528 // aka when there is no current/alternate.
10529
10530 if (current === null && finishedWork.effectTag & Update) {
10531 var type = finishedWork.type;
10532 var props = finishedWork.memoizedProps;
10533 }
10534
10535 return;
10536 }
10537
10538 case HostText:
10539 {
10540 // We have no life-cycles associated with text.
10541 return;
10542 }
10543
10544 case HostPortal:
10545 {
10546 // We have no life-cycles associated with portals.
10547 return;
10548 }
10549
10550 case Profiler:
10551 {
10552 {
10553 var onRender = finishedWork.memoizedProps.onRender;
10554
10555 if (typeof onRender === 'function') {
10556 {
10557 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
10558 }
10559 }
10560 }
10561
10562 return;
10563 }
10564
10565 case SuspenseComponent:
10566 {
10567 return;
10568 }
10569
10570 case SuspenseListComponent:
10571 case IncompleteClassComponent:
10572 case FundamentalComponent:
10573 case ScopeComponent:
10574 return;
10575 }
10576
10577 {
10578 {
10579 throw 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." );
10580 }
10581 }
10582}
10583
10584function hideOrUnhideAllChildren(finishedWork, isHidden) {
10585 {
10586 // We only have the top Fiber that was inserted but we need to recurse down its
10587 // children to find all the terminal nodes.
10588 var node = finishedWork;
10589
10590 while (true) {
10591 if (node.tag === HostComponent) {
10592 var instance = node.stateNode;
10593
10594 if (isHidden) {
10595 hideInstance(instance);
10596 } else {
10597 unhideInstance(node.stateNode, node.memoizedProps);
10598 }
10599 } else if (node.tag === HostText) {
10600 var _instance3 = node.stateNode;
10601
10602 if (isHidden) {
10603 hideTextInstance(_instance3);
10604 } else {
10605 unhideTextInstance(_instance3, node.memoizedProps);
10606 }
10607 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
10608 // Found a nested Suspense component that timed out. Skip over the
10609 // primary child fragment, which should remain hidden.
10610 var fallbackChildFragment = node.child.sibling;
10611 fallbackChildFragment.return = node;
10612 node = fallbackChildFragment;
10613 continue;
10614 } else if (node.child !== null) {
10615 node.child.return = node;
10616 node = node.child;
10617 continue;
10618 }
10619
10620 if (node === finishedWork) {
10621 return;
10622 }
10623
10624 while (node.sibling === null) {
10625 if (node.return === null || node.return === finishedWork) {
10626 return;
10627 }
10628
10629 node = node.return;
10630 }
10631
10632 node.sibling.return = node.return;
10633 node = node.sibling;
10634 }
10635 }
10636}
10637
10638function commitAttachRef(finishedWork) {
10639 var ref = finishedWork.ref;
10640
10641 if (ref !== null) {
10642 var instance = finishedWork.stateNode;
10643 var instanceToUse;
10644
10645 switch (finishedWork.tag) {
10646 case HostComponent:
10647 instanceToUse = getPublicInstance(instance);
10648 break;
10649
10650 default:
10651 instanceToUse = instance;
10652 } // Moved outside to ensure DCE works with this flag
10653
10654 if (typeof ref === 'function') {
10655 ref(instanceToUse);
10656 } else {
10657 {
10658 if (!ref.hasOwnProperty('current')) {
10659 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
10660 }
10661 }
10662
10663 ref.current = instanceToUse;
10664 }
10665 }
10666}
10667
10668function commitDetachRef(current) {
10669 var currentRef = current.ref;
10670
10671 if (currentRef !== null) {
10672 if (typeof currentRef === 'function') {
10673 currentRef(null);
10674 } else {
10675 currentRef.current = null;
10676 }
10677 }
10678} // User-originating errors (lifecycles and refs) should not interrupt
10679// deletion, so don't let them throw. Host-originating errors should
10680// interrupt deletion, so it's okay
10681
10682
10683function commitUnmount(finishedRoot, current, renderPriorityLevel) {
10684 onCommitUnmount(current);
10685
10686 switch (current.tag) {
10687 case FunctionComponent:
10688 case ForwardRef:
10689 case MemoComponent:
10690 case SimpleMemoComponent:
10691 case Block:
10692 {
10693 var updateQueue = current.updateQueue;
10694
10695 if (updateQueue !== null) {
10696 var lastEffect = updateQueue.lastEffect;
10697
10698 if (lastEffect !== null) {
10699 var firstEffect = lastEffect.next;
10700
10701 {
10702 // When the owner fiber is deleted, the destroy function of a passive
10703 // effect hook is called during the synchronous commit phase. This is
10704 // a concession to implementation complexity. Calling it in the
10705 // passive effect phase (like they usually are, when dependencies
10706 // change during an update) would require either traversing the
10707 // children of the deleted fiber again, or including unmount effects
10708 // as part of the fiber effect list.
10709 //
10710 // Because this is during the sync commit phase, we need to change
10711 // the priority.
10712 //
10713 // TODO: Reconsider this implementation trade off.
10714 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
10715 runWithPriority(priorityLevel, function () {
10716 var effect = firstEffect;
10717
10718 do {
10719 var _destroy = effect.destroy;
10720
10721 if (_destroy !== undefined) {
10722 safelyCallDestroy(current, _destroy);
10723 }
10724
10725 effect = effect.next;
10726 } while (effect !== firstEffect);
10727 });
10728 }
10729 }
10730 }
10731
10732 return;
10733 }
10734
10735 case ClassComponent:
10736 {
10737 safelyDetachRef(current);
10738 var instance = current.stateNode;
10739
10740 if (typeof instance.componentWillUnmount === 'function') {
10741 safelyCallComponentWillUnmount(current, instance);
10742 }
10743
10744 return;
10745 }
10746
10747 case HostComponent:
10748 {
10749
10750 safelyDetachRef(current);
10751 return;
10752 }
10753
10754 case HostPortal:
10755 {
10756 // TODO: this is recursive.
10757 // We are also not using this parent because
10758 // the portal will get pushed immediately.
10759 {
10760 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
10761 }
10762
10763 return;
10764 }
10765
10766 case FundamentalComponent:
10767 {
10768
10769 return;
10770 }
10771
10772 case DehydratedFragment:
10773 {
10774
10775 return;
10776 }
10777
10778 case ScopeComponent:
10779 {
10780
10781 return;
10782 }
10783 }
10784}
10785
10786function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
10787 // While we're inside a removed host node we don't want to call
10788 // removeChild on the inner nodes because they're removed by the top
10789 // call anyway. We also want to call componentWillUnmount on all
10790 // composites before this host node is removed from the tree. Therefore
10791 // we do an inner loop while we're still inside the host node.
10792 var node = root;
10793
10794 while (true) {
10795 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
10796 // Skip portals because commitUnmount() currently visits them recursively.
10797
10798 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
10799 // If we don't use mutation we drill down into portals here instead.
10800 node.tag !== HostPortal)) {
10801 node.child.return = node;
10802 node = node.child;
10803 continue;
10804 }
10805
10806 if (node === root) {
10807 return;
10808 }
10809
10810 while (node.sibling === null) {
10811 if (node.return === null || node.return === root) {
10812 return;
10813 }
10814
10815 node = node.return;
10816 }
10817
10818 node.sibling.return = node.return;
10819 node = node.sibling;
10820 }
10821}
10822
10823function detachFiber(current) {
10824 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
10825 // should clear the child pointer of the parent alternate to let this
10826 // get GC:ed but we don't know which for sure which parent is the current
10827 // one so we'll settle for GC:ing the subtree of this child. This child
10828 // itself will be GC:ed when the parent updates the next time.
10829
10830 current.return = null;
10831 current.child = null;
10832 current.memoizedState = null;
10833 current.updateQueue = null;
10834 current.dependencies = null;
10835 current.alternate = null;
10836 current.firstEffect = null;
10837 current.lastEffect = null;
10838 current.pendingProps = null;
10839 current.memoizedProps = null;
10840 current.stateNode = null;
10841
10842 if (alternate !== null) {
10843 detachFiber(alternate);
10844 }
10845}
10846
10847function getHostParentFiber(fiber) {
10848 var parent = fiber.return;
10849
10850 while (parent !== null) {
10851 if (isHostParent(parent)) {
10852 return parent;
10853 }
10854
10855 parent = parent.return;
10856 }
10857
10858 {
10859 {
10860 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
10861 }
10862 }
10863}
10864
10865function isHostParent(fiber) {
10866 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
10867}
10868
10869function getHostSibling(fiber) {
10870 // We're going to search forward into the tree until we find a sibling host
10871 // node. Unfortunately, if multiple insertions are done in a row we have to
10872 // search past them. This leads to exponential search for the next sibling.
10873 // TODO: Find a more efficient way to do this.
10874 var node = fiber;
10875
10876 siblings: while (true) {
10877 // If we didn't find anything, let's try the next sibling.
10878 while (node.sibling === null) {
10879 if (node.return === null || isHostParent(node.return)) {
10880 // If we pop out of the root or hit the parent the fiber we are the
10881 // last sibling.
10882 return null;
10883 }
10884
10885 node = node.return;
10886 }
10887
10888 node.sibling.return = node.return;
10889 node = node.sibling;
10890
10891 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
10892 // If it is not host node and, we might have a host node inside it.
10893 // Try to search down until we find one.
10894 if (node.effectTag & Placement) {
10895 // If we don't have a child, try the siblings instead.
10896 continue siblings;
10897 } // If we don't have a child, try the siblings instead.
10898 // We also skip portals because they are not part of this host tree.
10899
10900
10901 if (node.child === null || node.tag === HostPortal) {
10902 continue siblings;
10903 } else {
10904 node.child.return = node;
10905 node = node.child;
10906 }
10907 } // Check if this host node is stable or about to be placed.
10908
10909
10910 if (!(node.effectTag & Placement)) {
10911 // Found it!
10912 return node.stateNode;
10913 }
10914 }
10915}
10916
10917function commitPlacement(finishedWork) {
10918
10919
10920 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
10921
10922 var parent;
10923 var isContainer;
10924 var parentStateNode = parentFiber.stateNode;
10925
10926 switch (parentFiber.tag) {
10927 case HostComponent:
10928 parent = parentStateNode;
10929 isContainer = false;
10930 break;
10931
10932 case HostRoot:
10933 parent = parentStateNode.containerInfo;
10934 isContainer = true;
10935 break;
10936
10937 case HostPortal:
10938 parent = parentStateNode.containerInfo;
10939 isContainer = true;
10940 break;
10941
10942 case FundamentalComponent:
10943
10944 // eslint-disable-next-line-no-fallthrough
10945
10946 default:
10947 {
10948 {
10949 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
10950 }
10951 }
10952
10953 }
10954
10955 if (parentFiber.effectTag & ContentReset) {
10956
10957 parentFiber.effectTag &= ~ContentReset;
10958 }
10959
10960 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
10961 // children to find all the terminal nodes.
10962
10963 if (isContainer) {
10964 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
10965 } else {
10966 insertOrAppendPlacementNode(finishedWork, before, parent);
10967 }
10968}
10969
10970function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
10971 var tag = node.tag;
10972 var isHost = tag === HostComponent || tag === HostText;
10973
10974 if (isHost || enableFundamentalAPI ) {
10975 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
10976
10977 if (before) {
10978 insertInContainerBefore(parent, stateNode, before);
10979 } else {
10980 appendChildToContainer(parent, stateNode);
10981 }
10982 } else if (tag === HostPortal) ; else {
10983 var child = node.child;
10984
10985 if (child !== null) {
10986 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
10987 var sibling = child.sibling;
10988
10989 while (sibling !== null) {
10990 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
10991 sibling = sibling.sibling;
10992 }
10993 }
10994 }
10995}
10996
10997function insertOrAppendPlacementNode(node, before, parent) {
10998 var tag = node.tag;
10999 var isHost = tag === HostComponent || tag === HostText;
11000
11001 if (isHost || enableFundamentalAPI ) {
11002 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
11003
11004 if (before) {
11005 insertBefore(parent, stateNode, before);
11006 } else {
11007 appendChild(parent, stateNode);
11008 }
11009 } else if (tag === HostPortal) ; else {
11010 var child = node.child;
11011
11012 if (child !== null) {
11013 insertOrAppendPlacementNode(child, before, parent);
11014 var sibling = child.sibling;
11015
11016 while (sibling !== null) {
11017 insertOrAppendPlacementNode(sibling, before, parent);
11018 sibling = sibling.sibling;
11019 }
11020 }
11021 }
11022}
11023
11024function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
11025 // We only have the top Fiber that was deleted but we need to recurse down its
11026 // children to find all the terminal nodes.
11027 var node = current; // Each iteration, currentParent is populated with node's host parent if not
11028 // currentParentIsValid.
11029
11030 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
11031
11032 var currentParent;
11033 var currentParentIsContainer;
11034
11035 while (true) {
11036 if (!currentParentIsValid) {
11037 var parent = node.return;
11038
11039 findParent: while (true) {
11040 if (!(parent !== null)) {
11041 {
11042 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
11043 }
11044 }
11045
11046 var parentStateNode = parent.stateNode;
11047
11048 switch (parent.tag) {
11049 case HostComponent:
11050 currentParent = parentStateNode;
11051 currentParentIsContainer = false;
11052 break findParent;
11053
11054 case HostRoot:
11055 currentParent = parentStateNode.containerInfo;
11056 currentParentIsContainer = true;
11057 break findParent;
11058
11059 case HostPortal:
11060 currentParent = parentStateNode.containerInfo;
11061 currentParentIsContainer = true;
11062 break findParent;
11063
11064 }
11065
11066 parent = parent.return;
11067 }
11068
11069 currentParentIsValid = true;
11070 }
11071
11072 if (node.tag === HostComponent || node.tag === HostText) {
11073 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
11074 // node from the tree.
11075
11076 if (currentParentIsContainer) {
11077 removeChildFromContainer(currentParent, node.stateNode);
11078 } else {
11079 removeChild(currentParent, node.stateNode);
11080 } // Don't visit children because we already visited them.
11081
11082 } else if (node.tag === HostPortal) {
11083 if (node.child !== null) {
11084 // When we go into a portal, it becomes the parent to remove from.
11085 // We will reassign it back when we pop the portal on the way up.
11086 currentParent = node.stateNode.containerInfo;
11087 currentParentIsContainer = true; // Visit children because portals might contain host components.
11088
11089 node.child.return = node;
11090 node = node.child;
11091 continue;
11092 }
11093 } else {
11094 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
11095
11096 if (node.child !== null) {
11097 node.child.return = node;
11098 node = node.child;
11099 continue;
11100 }
11101 }
11102
11103 if (node === current) {
11104 return;
11105 }
11106
11107 while (node.sibling === null) {
11108 if (node.return === null || node.return === current) {
11109 return;
11110 }
11111
11112 node = node.return;
11113
11114 if (node.tag === HostPortal) {
11115 // When we go out of the portal, we need to restore the parent.
11116 // Since we don't keep a stack of them, we will search for it.
11117 currentParentIsValid = false;
11118 }
11119 }
11120
11121 node.sibling.return = node.return;
11122 node = node.sibling;
11123 }
11124}
11125
11126function commitDeletion(finishedRoot, current, renderPriorityLevel) {
11127 {
11128 // Recursively delete all host nodes from the parent.
11129 // Detach refs and call componentWillUnmount() on the whole subtree.
11130 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
11131 }
11132
11133 detachFiber(current);
11134}
11135
11136function commitWork(current, finishedWork) {
11137
11138 switch (finishedWork.tag) {
11139 case FunctionComponent:
11140 case ForwardRef:
11141 case MemoComponent:
11142 case SimpleMemoComponent:
11143 case Block:
11144 {
11145 // Layout effects are destroyed during the mutation phase so that all
11146 // destroy functions for all fibers are called before any create functions.
11147 // This prevents sibling component effects from interfering with each other,
11148 // e.g. a destroy function in one component should never override a ref set
11149 // by a create function in another component during the same commit.
11150 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
11151 return;
11152 }
11153
11154 case ClassComponent:
11155 {
11156 return;
11157 }
11158
11159 case HostComponent:
11160 {
11161 var instance = finishedWork.stateNode;
11162
11163 if (instance != null) {
11164 // Commit the work prepared earlier.
11165 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11166 // as the newProps. The updatePayload will contain the real change in
11167 // this case.
11168
11169 var oldProps = current !== null ? current.memoizedProps : newProps;
11170 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
11171
11172 var updatePayload = finishedWork.updateQueue;
11173 finishedWork.updateQueue = null;
11174
11175 if (updatePayload !== null) {
11176 commitUpdate(instance, updatePayload, type, oldProps, newProps);
11177 }
11178 }
11179
11180 return;
11181 }
11182
11183 case HostText:
11184 {
11185 if (!(finishedWork.stateNode !== null)) {
11186 {
11187 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
11188 }
11189 }
11190
11191 var textInstance = finishedWork.stateNode;
11192 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11193 // as the newProps. The updatePayload will contain the real change in
11194 // this case.
11195
11196 var oldText = current !== null ? current.memoizedProps : newText;
11197 commitTextUpdate(textInstance, oldText, newText);
11198 return;
11199 }
11200
11201 case HostRoot:
11202 {
11203
11204 return;
11205 }
11206
11207 case Profiler:
11208 {
11209 return;
11210 }
11211
11212 case SuspenseComponent:
11213 {
11214 commitSuspenseComponent(finishedWork);
11215 attachSuspenseRetryListeners(finishedWork);
11216 return;
11217 }
11218
11219 case SuspenseListComponent:
11220 {
11221 attachSuspenseRetryListeners(finishedWork);
11222 return;
11223 }
11224
11225 case IncompleteClassComponent:
11226 {
11227 return;
11228 }
11229 }
11230
11231 {
11232 {
11233 throw 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." );
11234 }
11235 }
11236}
11237
11238function commitSuspenseComponent(finishedWork) {
11239 var newState = finishedWork.memoizedState;
11240 var newDidTimeout;
11241 var primaryChildParent = finishedWork;
11242
11243 if (newState === null) {
11244 newDidTimeout = false;
11245 } else {
11246 newDidTimeout = true;
11247 primaryChildParent = finishedWork.child;
11248 markCommitTimeOfFallback();
11249 }
11250
11251 if ( primaryChildParent !== null) {
11252 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
11253 }
11254}
11255
11256function attachSuspenseRetryListeners(finishedWork) {
11257 // If this boundary just timed out, then it will have a set of thenables.
11258 // For each thenable, attach a listener so that when it resolves, React
11259 // attempts to re-render the boundary in the primary (pre-timeout) state.
11260 var thenables = finishedWork.updateQueue;
11261
11262 if (thenables !== null) {
11263 finishedWork.updateQueue = null;
11264 var retryCache = finishedWork.stateNode;
11265
11266 if (retryCache === null) {
11267 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
11268 }
11269
11270 thenables.forEach(function (thenable) {
11271 // Memoize using the boundary fiber to prevent redundant listeners.
11272 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
11273
11274 if (!retryCache.has(thenable)) {
11275 {
11276 if (thenable.__reactDoNotTraceInteractions !== true) {
11277 retry = tracing.unstable_wrap(retry);
11278 }
11279 }
11280
11281 retryCache.add(thenable);
11282 thenable.then(retry, retry);
11283 }
11284 });
11285 }
11286}
11287
11288function commitResetTextContent(current) {
11289
11290 resetTextContent(current.stateNode);
11291}
11292
11293var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
11294
11295function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
11296 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
11297
11298 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
11299 // being called "element".
11300
11301 update.payload = {
11302 element: null
11303 };
11304 var error = errorInfo.value;
11305
11306 update.callback = function () {
11307 onUncaughtError(error);
11308 logError(fiber, errorInfo);
11309 };
11310
11311 return update;
11312}
11313
11314function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
11315 var update = createUpdate(expirationTime, null);
11316 update.tag = CaptureUpdate;
11317 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
11318
11319 if (typeof getDerivedStateFromError === 'function') {
11320 var error$1 = errorInfo.value;
11321
11322 update.payload = function () {
11323 logError(fiber, errorInfo);
11324 return getDerivedStateFromError(error$1);
11325 };
11326 }
11327
11328 var inst = fiber.stateNode;
11329
11330 if (inst !== null && typeof inst.componentDidCatch === 'function') {
11331 update.callback = function callback() {
11332 {
11333 markFailedErrorBoundaryForHotReloading(fiber);
11334 }
11335
11336 if (typeof getDerivedStateFromError !== 'function') {
11337 // To preserve the preexisting retry behavior of error boundaries,
11338 // we keep track of which ones already failed during this batch.
11339 // This gets reset before we yield back to the browser.
11340 // TODO: Warn in strict mode if getDerivedStateFromError is
11341 // not defined.
11342 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
11343
11344 logError(fiber, errorInfo);
11345 }
11346
11347 var error$1 = errorInfo.value;
11348 var stack = errorInfo.stack;
11349 this.componentDidCatch(error$1, {
11350 componentStack: stack !== null ? stack : ''
11351 });
11352
11353 {
11354 if (typeof getDerivedStateFromError !== 'function') {
11355 // If componentDidCatch is the only error boundary method defined,
11356 // then it needs to call setState to recover from errors.
11357 // If no state update is scheduled then the boundary will swallow the error.
11358 if (fiber.expirationTime !== Sync) {
11359 error('%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');
11360 }
11361 }
11362 }
11363 };
11364 } else {
11365 update.callback = function () {
11366 markFailedErrorBoundaryForHotReloading(fiber);
11367 };
11368 }
11369
11370 return update;
11371}
11372
11373function attachPingListener(root, renderExpirationTime, thenable) {
11374 // Attach a listener to the promise to "ping" the root and retry. But
11375 // only if one does not already exist for the current render expiration
11376 // time (which acts like a "thread ID" here).
11377 var pingCache = root.pingCache;
11378 var threadIDs;
11379
11380 if (pingCache === null) {
11381 pingCache = root.pingCache = new PossiblyWeakMap();
11382 threadIDs = new Set();
11383 pingCache.set(thenable, threadIDs);
11384 } else {
11385 threadIDs = pingCache.get(thenable);
11386
11387 if (threadIDs === undefined) {
11388 threadIDs = new Set();
11389 pingCache.set(thenable, threadIDs);
11390 }
11391 }
11392
11393 if (!threadIDs.has(renderExpirationTime)) {
11394 // Memoize using the thread ID to prevent redundant listeners.
11395 threadIDs.add(renderExpirationTime);
11396 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
11397 thenable.then(ping, ping);
11398 }
11399}
11400
11401function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
11402 // The source fiber did not complete.
11403 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
11404
11405 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
11406
11407 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
11408 // This is a thenable.
11409 var thenable = value;
11410
11411 if ((sourceFiber.mode & BlockingMode) === NoMode) {
11412 // Reset the memoizedState to what it was before we attempted
11413 // to render it.
11414 var currentSource = sourceFiber.alternate;
11415
11416 if (currentSource) {
11417 sourceFiber.memoizedState = currentSource.memoizedState;
11418 sourceFiber.expirationTime = currentSource.expirationTime;
11419 } else {
11420 sourceFiber.memoizedState = null;
11421 }
11422 }
11423
11424 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
11425
11426 var _workInProgress = returnFiber;
11427
11428 do {
11429 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
11430 // Found the nearest boundary.
11431 // Stash the promise on the boundary fiber. If the boundary times out, we'll
11432 // attach another listener to flip the boundary back to its normal state.
11433 var thenables = _workInProgress.updateQueue;
11434
11435 if (thenables === null) {
11436 var updateQueue = new Set();
11437 updateQueue.add(thenable);
11438 _workInProgress.updateQueue = updateQueue;
11439 } else {
11440 thenables.add(thenable);
11441 } // If the boundary is outside of blocking mode, we should *not*
11442 // suspend the commit. Pretend as if the suspended component rendered
11443 // null and keep rendering. In the commit phase, we'll schedule a
11444 // subsequent synchronous update to re-render the Suspense.
11445 //
11446 // Note: It doesn't matter whether the component that suspended was
11447 // inside a blocking mode tree. If the Suspense is outside of it, we
11448 // should *not* suspend the commit.
11449
11450
11451 if ((_workInProgress.mode & BlockingMode) === NoMode) {
11452 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
11453 // But we shouldn't call any lifecycle methods or callbacks. Remove
11454 // all lifecycle effect tags.
11455
11456 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
11457
11458 if (sourceFiber.tag === ClassComponent) {
11459 var currentSourceFiber = sourceFiber.alternate;
11460
11461 if (currentSourceFiber === null) {
11462 // This is a new mount. Change the tag so it's not mistaken for a
11463 // completed class component. For example, we should not call
11464 // componentWillUnmount if it is deleted.
11465 sourceFiber.tag = IncompleteClassComponent;
11466 } else {
11467 // When we try rendering again, we should not reuse the current fiber,
11468 // since it's known to be in an inconsistent state. Use a force update to
11469 // prevent a bail out.
11470 var update = createUpdate(Sync, null);
11471 update.tag = ForceUpdate;
11472 enqueueUpdate(sourceFiber, update);
11473 }
11474 } // The source fiber did not complete. Mark it with Sync priority to
11475 // indicate that it still has pending work.
11476
11477
11478 sourceFiber.expirationTime = Sync; // Exit without suspending.
11479
11480 return;
11481 } // Confirmed that the boundary is in a concurrent mode tree. Continue
11482 // with the normal suspend path.
11483 //
11484 // After this we'll use a set of heuristics to determine whether this
11485 // render pass will run to completion or restart or "suspend" the commit.
11486 // The actual logic for this is spread out in different places.
11487 //
11488 // This first principle is that if we're going to suspend when we complete
11489 // a root, then we should also restart if we get an update or ping that
11490 // might unsuspend it, and vice versa. The only reason to suspend is
11491 // because you think you might want to restart before committing. However,
11492 // it doesn't make sense to restart only while in the period we're suspended.
11493 //
11494 // Restarting too aggressively is also not good because it starves out any
11495 // intermediate loading state. So we use heuristics to determine when.
11496 // Suspense Heuristics
11497 //
11498 // If nothing threw a Promise or all the same fallbacks are already showing,
11499 // then don't suspend/restart.
11500 //
11501 // If this is an initial render of a new tree of Suspense boundaries and
11502 // those trigger a fallback, then don't suspend/restart. We want to ensure
11503 // that we can show the initial loading state as quickly as possible.
11504 //
11505 // If we hit a "Delayed" case, such as when we'd switch from content back into
11506 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
11507 // this case. If none is defined, JND is used instead.
11508 //
11509 // If we're already showing a fallback and it gets "retried", allowing us to show
11510 // another level, but there's still an inner boundary that would show a fallback,
11511 // then we suspend/restart for 500ms since the last time we showed a fallback
11512 // anywhere in the tree. This effectively throttles progressive loading into a
11513 // consistent train of commits. This also gives us an opportunity to restart to
11514 // get to the completed state slightly earlier.
11515 //
11516 // If there's ambiguity due to batching it's resolved in preference of:
11517 // 1) "delayed", 2) "initial render", 3) "retry".
11518 //
11519 // We want to ensure that a "busy" state doesn't get force committed. We want to
11520 // ensure that new initial loading states can commit as soon as possible.
11521
11522
11523 attachPingListener(root, renderExpirationTime, thenable);
11524 _workInProgress.effectTag |= ShouldCapture;
11525 _workInProgress.expirationTime = renderExpirationTime;
11526 return;
11527 } // This boundary already captured during this render. Continue to the next
11528 // boundary.
11529
11530
11531 _workInProgress = _workInProgress.return;
11532 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
11533 // TODO: Use invariant so the message is stripped in prod?
11534
11535
11536 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));
11537 } // We didn't find a boundary that could handle this type of exception. Start
11538 // over and traverse parent path again, this time treating the exception
11539 // as an error.
11540
11541
11542 renderDidError();
11543 value = createCapturedValue(value, sourceFiber);
11544 var workInProgress = returnFiber;
11545
11546 do {
11547 switch (workInProgress.tag) {
11548 case HostRoot:
11549 {
11550 var _errorInfo = value;
11551 workInProgress.effectTag |= ShouldCapture;
11552 workInProgress.expirationTime = renderExpirationTime;
11553
11554 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
11555
11556 enqueueCapturedUpdate(workInProgress, _update);
11557 return;
11558 }
11559
11560 case ClassComponent:
11561 // Capture and retry
11562 var errorInfo = value;
11563 var ctor = workInProgress.type;
11564 var instance = workInProgress.stateNode;
11565
11566 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
11567 workInProgress.effectTag |= ShouldCapture;
11568 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
11569
11570 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
11571
11572 enqueueCapturedUpdate(workInProgress, _update2);
11573 return;
11574 }
11575
11576 break;
11577 }
11578
11579 workInProgress = workInProgress.return;
11580 } while (workInProgress !== null);
11581}
11582
11583var ceil = Math.ceil;
11584var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
11585 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
11586 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
11587var NoContext =
11588/* */
115890;
11590var BatchedContext =
11591/* */
115921;
11593var DiscreteEventContext =
11594/* */
115954;
11596var LegacyUnbatchedContext =
11597/* */
115988;
11599var RenderContext =
11600/* */
1160116;
11602var CommitContext =
11603/* */
1160432;
11605var RootIncomplete = 0;
11606var RootFatalErrored = 1;
11607var RootErrored = 2;
11608var RootSuspended = 3;
11609var RootSuspendedWithDelay = 4;
11610var RootCompleted = 5;
11611// Describes where we are in the React execution stack
11612var executionContext = NoContext; // The root we're working on
11613
11614var workInProgressRoot = null; // The fiber we're working on
11615
11616var workInProgress = null; // The expiration time we're rendering
11617
11618var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc.
11619
11620var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
11621
11622var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
11623// This is conceptually a time stamp but expressed in terms of an ExpirationTime
11624// because we deal mostly with expiration times in the hot path, so this avoids
11625// the conversion happening in the hot path.
11626
11627var workInProgressRootLatestProcessedExpirationTime = Sync;
11628var workInProgressRootLatestSuspenseTimeout = Sync;
11629var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
11630// includes unprocessed updates, not work in bailed out children.
11631
11632var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
11633// This flag determines if it might be worthwhile to restart if an opportunity
11634// happens latere.
11635
11636var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
11637// model where we don't commit new loading states in too quick succession.
11638
11639var globalMostRecentFallbackTime = 0;
11640var FALLBACK_THROTTLE_MS = 500;
11641var nextEffect = null;
11642var hasUncaughtError = false;
11643var firstUncaughtError = null;
11644var legacyErrorBoundariesThatAlreadyFailed = null;
11645var rootDoesHavePassiveEffects = false;
11646var rootWithPendingPassiveEffects = null;
11647var pendingPassiveEffectsRenderPriority = NoPriority;
11648var pendingPassiveEffectsExpirationTime = NoWork;
11649var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
11650
11651var NESTED_UPDATE_LIMIT = 50;
11652var nestedUpdateCount = 0;
11653var rootWithNestedUpdates = null;
11654var NESTED_PASSIVE_UPDATE_LIMIT = 50;
11655var nestedPassiveUpdateCount = 0;
11656var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
11657// during the commit phase. This enables them to be traced across components
11658// that spawn new work during render. E.g. hidden boundaries, suspended SSR
11659// hydration or SuspenseList.
11660
11661var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
11662// time). However, if two updates are scheduled within the same event, we
11663// should treat their start times as simultaneous, even if the actual clock
11664// time has advanced between the first and second call.
11665// In other words, because expiration times determine how updates are batched,
11666// we want all updates of like priority that occur within the same event to
11667// receive the same expiration time. Otherwise we get tearing.
11668
11669var currentEventTime = NoWork;
11670function requestCurrentTimeForUpdate() {
11671 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
11672 // We're inside React, so it's fine to read the actual time.
11673 return msToExpirationTime(now());
11674 } // We're not inside React, so we may be in the middle of a browser event.
11675
11676
11677 if (currentEventTime !== NoWork) {
11678 // Use the same start time for all updates until we enter React again.
11679 return currentEventTime;
11680 } // This is the first update since React yielded. Compute a new start time.
11681
11682
11683 currentEventTime = msToExpirationTime(now());
11684 return currentEventTime;
11685}
11686function getCurrentTime() {
11687 return msToExpirationTime(now());
11688}
11689function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
11690 var mode = fiber.mode;
11691
11692 if ((mode & BlockingMode) === NoMode) {
11693 return Sync;
11694 }
11695
11696 var priorityLevel = getCurrentPriorityLevel();
11697
11698 if ((mode & ConcurrentMode) === NoMode) {
11699 return priorityLevel === ImmediatePriority ? Sync : Batched;
11700 }
11701
11702 if ((executionContext & RenderContext) !== NoContext) {
11703 // Use whatever time we're already rendering
11704 // TODO: Should there be a way to opt out, like with `runWithPriority`?
11705 return renderExpirationTime$1;
11706 }
11707
11708 var expirationTime;
11709
11710 if (suspenseConfig !== null) {
11711 // Compute an expiration time based on the Suspense timeout.
11712 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
11713 } else {
11714 // Compute an expiration time based on the Scheduler priority.
11715 switch (priorityLevel) {
11716 case ImmediatePriority:
11717 expirationTime = Sync;
11718 break;
11719
11720 case UserBlockingPriority:
11721 // TODO: Rename this to computeUserBlockingExpiration
11722 expirationTime = computeInteractiveExpiration(currentTime);
11723 break;
11724
11725 case NormalPriority:
11726 case LowPriority:
11727 // TODO: Handle LowPriority
11728 // TODO: Rename this to... something better.
11729 expirationTime = computeAsyncExpiration(currentTime);
11730 break;
11731
11732 case IdlePriority:
11733 expirationTime = Idle;
11734 break;
11735
11736 default:
11737 {
11738 {
11739 throw Error( "Expected a valid priority level" );
11740 }
11741 }
11742
11743 }
11744 } // If we're in the middle of rendering a tree, do not update at the same
11745 // expiration time that is already rendering.
11746 // TODO: We shouldn't have to do this if the update is on a different root.
11747 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
11748 // the root when we check for this condition.
11749
11750
11751 if (workInProgressRoot !== null && expirationTime === renderExpirationTime$1) {
11752 // This is a trick to move this update into a separate batch
11753 expirationTime -= 1;
11754 }
11755
11756 return expirationTime;
11757}
11758function scheduleUpdateOnFiber(fiber, expirationTime) {
11759 checkForNestedUpdates();
11760 warnAboutRenderPhaseUpdatesInDEV(fiber);
11761 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
11762
11763 if (root === null) {
11764 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
11765 return;
11766 }
11767
11768 checkForInterruption(fiber, expirationTime);
11769 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
11770 // priority as an argument to that function and this one.
11771
11772 var priorityLevel = getCurrentPriorityLevel();
11773
11774 if (expirationTime === Sync) {
11775 if ( // Check if we're inside unbatchedUpdates
11776 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
11777 (executionContext & (RenderContext | CommitContext)) === NoContext) {
11778 // Register pending interactions on the root to avoid losing traced interaction data.
11779 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
11780 // root inside of batchedUpdates should be synchronous, but layout updates
11781 // should be deferred until the end of the batch.
11782
11783 performSyncWorkOnRoot(root);
11784 } else {
11785 ensureRootIsScheduled(root);
11786 schedulePendingInteractions(root, expirationTime);
11787
11788 if (executionContext === NoContext) {
11789 // Flush the synchronous work now, unless we're already working or inside
11790 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
11791 // scheduleCallbackForFiber to preserve the ability to schedule a callback
11792 // without immediately flushing it. We only do this for user-initiated
11793 // updates, to preserve historical behavior of legacy mode.
11794 flushSyncCallbackQueue();
11795 }
11796 }
11797 } else {
11798 ensureRootIsScheduled(root);
11799 schedulePendingInteractions(root, expirationTime);
11800 }
11801
11802 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
11803 // discrete, even inside a discrete event.
11804 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
11805 // This is the result of a discrete event. Track the lowest priority
11806 // discrete update per root so we can flush them early, if needed.
11807 if (rootsWithPendingDiscreteUpdates === null) {
11808 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
11809 } else {
11810 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
11811
11812 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
11813 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
11814 }
11815 }
11816 }
11817}
11818var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
11819// work without treating it as a typical update that originates from an event;
11820// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
11821// on a fiber.
11822
11823function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
11824 // Update the source fiber's expiration time
11825 if (fiber.expirationTime < expirationTime) {
11826 fiber.expirationTime = expirationTime;
11827 }
11828
11829 var alternate = fiber.alternate;
11830
11831 if (alternate !== null && alternate.expirationTime < expirationTime) {
11832 alternate.expirationTime = expirationTime;
11833 } // Walk the parent path to the root and update the child expiration time.
11834
11835
11836 var node = fiber.return;
11837 var root = null;
11838
11839 if (node === null && fiber.tag === HostRoot) {
11840 root = fiber.stateNode;
11841 } else {
11842 while (node !== null) {
11843 alternate = node.alternate;
11844
11845 if (node.childExpirationTime < expirationTime) {
11846 node.childExpirationTime = expirationTime;
11847
11848 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
11849 alternate.childExpirationTime = expirationTime;
11850 }
11851 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
11852 alternate.childExpirationTime = expirationTime;
11853 }
11854
11855 if (node.return === null && node.tag === HostRoot) {
11856 root = node.stateNode;
11857 break;
11858 }
11859
11860 node = node.return;
11861 }
11862 }
11863
11864 if (root !== null) {
11865 if (workInProgressRoot === root) {
11866 // Received an update to a tree that's in the middle of rendering. Mark
11867 // that's unprocessed work on this root.
11868 markUnprocessedUpdateTime(expirationTime);
11869
11870 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
11871 // The root already suspended with a delay, which means this render
11872 // definitely won't finish. Since we have a new update, let's mark it as
11873 // suspended now, right before marking the incoming update. This has the
11874 // effect of interrupting the current render and switching to the update.
11875 // TODO: This happens to work when receiving an update during the render
11876 // phase, because of the trick inside computeExpirationForFiber to
11877 // subtract 1 from `renderExpirationTime` to move it into a
11878 // separate bucket. But we should probably model it with an exception,
11879 // using the same mechanism we use to force hydration of a subtree.
11880 // TODO: This does not account for low pri updates that were already
11881 // scheduled before the root started rendering. Need to track the next
11882 // pending expiration time (perhaps by backtracking the return path) and
11883 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
11884 markRootSuspendedAtTime(root, renderExpirationTime$1);
11885 }
11886 } // Mark that the root has a pending update.
11887
11888
11889 markRootUpdatedAtTime(root, expirationTime);
11890 }
11891
11892 return root;
11893}
11894
11895function getNextRootExpirationTimeToWorkOn(root) {
11896 // Determines the next expiration time that the root should render, taking
11897 // into account levels that may be suspended, or levels that may have
11898 // received a ping.
11899 var lastExpiredTime = root.lastExpiredTime;
11900
11901 if (lastExpiredTime !== NoWork) {
11902 return lastExpiredTime;
11903 } // "Pending" refers to any update that hasn't committed yet, including if it
11904 // suspended. The "suspended" range is therefore a subset.
11905
11906
11907 var firstPendingTime = root.firstPendingTime;
11908
11909 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
11910 // The highest priority pending time is not suspended. Let's work on that.
11911 return firstPendingTime;
11912 } // If the first pending time is suspended, check if there's a lower priority
11913 // pending level that we know about. Or check if we received a ping. Work
11914 // on whichever is higher priority.
11915
11916
11917 var lastPingedTime = root.lastPingedTime;
11918 var nextKnownPendingLevel = root.nextKnownPendingLevel;
11919 var nextLevel = lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
11920
11921 if ( nextLevel <= Idle && firstPendingTime !== nextLevel) {
11922 // Don't work on Idle/Never priority unless everything else is committed.
11923 return NoWork;
11924 }
11925
11926 return nextLevel;
11927} // Use this function to schedule a task for a root. There's only one task per
11928// root; if a task was already scheduled, we'll check to make sure the
11929// expiration time of the existing task is the same as the expiration time of
11930// the next level that the root has work on. This function is called on every
11931// update, and right before exiting a task.
11932
11933
11934function ensureRootIsScheduled(root) {
11935 var lastExpiredTime = root.lastExpiredTime;
11936
11937 if (lastExpiredTime !== NoWork) {
11938 // Special case: Expired work should flush synchronously.
11939 root.callbackExpirationTime = Sync;
11940 root.callbackPriority = ImmediatePriority;
11941 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
11942 return;
11943 }
11944
11945 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
11946 var existingCallbackNode = root.callbackNode;
11947
11948 if (expirationTime === NoWork) {
11949 // There's nothing to work on.
11950 if (existingCallbackNode !== null) {
11951 root.callbackNode = null;
11952 root.callbackExpirationTime = NoWork;
11953 root.callbackPriority = NoPriority;
11954 }
11955
11956 return;
11957 } // TODO: If this is an update, we already read the current time. Pass the
11958 // time as an argument.
11959
11960
11961 var currentTime = requestCurrentTimeForUpdate();
11962 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
11963 // expiration time. Otherwise, we'll cancel it and schedule a new one.
11964
11965 if (existingCallbackNode !== null) {
11966 var existingCallbackPriority = root.callbackPriority;
11967 var existingCallbackExpirationTime = root.callbackExpirationTime;
11968
11969 if ( // Callback must have the exact same expiration time.
11970 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
11971 existingCallbackPriority >= priorityLevel) {
11972 // Existing callback is sufficient.
11973 return;
11974 } // Need to schedule a new task.
11975 // TODO: Instead of scheduling a new task, we should be able to change the
11976 // priority of the existing one.
11977
11978
11979 cancelCallback(existingCallbackNode);
11980 }
11981
11982 root.callbackExpirationTime = expirationTime;
11983 root.callbackPriority = priorityLevel;
11984 var callbackNode;
11985
11986 if (expirationTime === Sync) {
11987 // Sync React callbacks are scheduled on a special internal queue
11988 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
11989 } else {
11990 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
11991 // ordering because tasks are processed in timeout order.
11992 {
11993 timeout: expirationTimeToMs(expirationTime) - now()
11994 });
11995 }
11996
11997 root.callbackNode = callbackNode;
11998} // This is the entry point for every concurrent task, i.e. anything that
11999// goes through Scheduler.
12000
12001
12002function performConcurrentWorkOnRoot(root, didTimeout) {
12003 // Since we know we're in a React event, we can clear the current
12004 // event time. The next update will compute a new event time.
12005 currentEventTime = NoWork;
12006
12007 if (didTimeout) {
12008 // The render task took too long to complete. Mark the current time as
12009 // expired to synchronously render all expired work in a single batch.
12010 var currentTime = requestCurrentTimeForUpdate();
12011 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
12012
12013 ensureRootIsScheduled(root);
12014 return null;
12015 } // Determine the next expiration time to work on, using the fields stored
12016 // on the root.
12017
12018
12019 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
12020
12021 if (expirationTime !== NoWork) {
12022 var originalCallbackNode = root.callbackNode;
12023
12024 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12025 {
12026 throw Error( "Should not already be working." );
12027 }
12028 }
12029
12030 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12031 // and prepare a fresh one. Otherwise we'll continue where we left off.
12032
12033 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12034 prepareFreshStack(root, expirationTime);
12035 startWorkOnPendingInteractions(root, expirationTime);
12036 } // If we have a work-in-progress fiber, it means there's still work to do
12037 // in this root.
12038
12039
12040 if (workInProgress !== null) {
12041 var prevExecutionContext = executionContext;
12042 executionContext |= RenderContext;
12043 var prevDispatcher = pushDispatcher();
12044 var prevInteractions = pushInteractions(root);
12045 startWorkLoopTimer(workInProgress);
12046
12047 do {
12048 try {
12049 workLoopConcurrent();
12050 break;
12051 } catch (thrownValue) {
12052 handleError(root, thrownValue);
12053 }
12054 } while (true);
12055
12056 resetContextDependencies();
12057 executionContext = prevExecutionContext;
12058 popDispatcher(prevDispatcher);
12059
12060 {
12061 popInteractions(prevInteractions);
12062 }
12063
12064 if (workInProgressRootExitStatus === RootFatalErrored) {
12065 var fatalError = workInProgressRootFatalError;
12066 stopInterruptedWorkLoopTimer();
12067 prepareFreshStack(root, expirationTime);
12068 markRootSuspendedAtTime(root, expirationTime);
12069 ensureRootIsScheduled(root);
12070 throw fatalError;
12071 }
12072
12073 if (workInProgress !== null) {
12074 // There's still work left over. Exit without committing.
12075 stopInterruptedWorkLoopTimer();
12076 } else {
12077 // We now have a consistent tree. The next step is either to commit it,
12078 // or, if something suspended, wait to commit it after a timeout.
12079 stopFinishedWorkLoopTimer();
12080 var finishedWork = root.finishedWork = root.current.alternate;
12081 root.finishedExpirationTime = expirationTime;
12082 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
12083 }
12084
12085 ensureRootIsScheduled(root);
12086
12087 if (root.callbackNode === originalCallbackNode) {
12088 // The task node scheduled for this root is the same one that's
12089 // currently executed. Need to return a continuation.
12090 return performConcurrentWorkOnRoot.bind(null, root);
12091 }
12092 }
12093 }
12094
12095 return null;
12096}
12097
12098function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
12099 // Set this to null to indicate there's no in-progress render.
12100 workInProgressRoot = null;
12101
12102 switch (exitStatus) {
12103 case RootIncomplete:
12104 case RootFatalErrored:
12105 {
12106 {
12107 {
12108 throw Error( "Root did not complete. This is a bug in React." );
12109 }
12110 }
12111 }
12112 // Flow knows about invariant, so it complains if I add a break
12113 // statement, but eslint doesn't know about invariant, so it complains
12114 // if I do. eslint-disable-next-line no-fallthrough
12115
12116 case RootErrored:
12117 {
12118 // If this was an async render, the error may have happened due to
12119 // a mutation in a concurrent event. Try rendering one more time,
12120 // synchronously, to see if the error goes away. If there are
12121 // lower priority updates, let's include those, too, in case they
12122 // fix the inconsistency. Render at Idle to include all updates.
12123 // If it was Idle or Never or some not-yet-invented time, render
12124 // at that time.
12125 markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous
12126 // and therefore not hit this path again.
12127
12128 break;
12129 }
12130
12131 case RootSuspended:
12132 {
12133 markRootSuspendedAtTime(root, expirationTime);
12134 var lastSuspendedTime = root.lastSuspendedTime;
12135
12136 if (expirationTime === lastSuspendedTime) {
12137 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12138 } // We have an acceptable loading state. We need to figure out if we
12139 // should immediately commit it or wait a bit.
12140 // If we have processed new updates during this render, we may now
12141 // have a new loading state ready. We want to ensure that we commit
12142 // that as soon as possible.
12143
12144
12145 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
12146
12147 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
12148 !( IsThisRendererActing.current)) {
12149 // If we have not processed any new updates during this pass, then
12150 // this is either a retry of an existing fallback state or a
12151 // hidden tree. Hidden trees shouldn't be batched with other work
12152 // and after that's fixed it can only be a retry. We're going to
12153 // throttle committing retries so that we don't show too many
12154 // loading states too quickly.
12155 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
12156
12157 if (msUntilTimeout > 10) {
12158 if (workInProgressRootHasPendingPing) {
12159 var lastPingedTime = root.lastPingedTime;
12160
12161 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
12162 // This render was pinged but we didn't get to restart
12163 // earlier so try restarting now instead.
12164 root.lastPingedTime = expirationTime;
12165 prepareFreshStack(root, expirationTime);
12166 break;
12167 }
12168 }
12169
12170 var nextTime = getNextRootExpirationTimeToWorkOn(root);
12171
12172 if (nextTime !== NoWork && nextTime !== expirationTime) {
12173 // There's additional work on this root.
12174 break;
12175 }
12176
12177 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
12178 // We should prefer to render the fallback of at the last
12179 // suspended level. Ping the last suspended level to try
12180 // rendering it again.
12181 root.lastPingedTime = lastSuspendedTime;
12182 break;
12183 } // The render is suspended, it hasn't timed out, and there's no
12184 // lower priority work to do. Instead of committing the fallback
12185 // immediately, wait for more data to arrive.
12186
12187
12188 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
12189 break;
12190 }
12191 } // The work expired. Commit immediately.
12192
12193
12194 commitRoot(root);
12195 break;
12196 }
12197
12198 case RootSuspendedWithDelay:
12199 {
12200 markRootSuspendedAtTime(root, expirationTime);
12201 var _lastSuspendedTime = root.lastSuspendedTime;
12202
12203 if (expirationTime === _lastSuspendedTime) {
12204 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12205 }
12206
12207 if ( // do not delay if we're inside an act() scope
12208 !( IsThisRendererActing.current)) {
12209 // We're suspended in a state that should be avoided. We'll try to
12210 // avoid committing it for as long as the timeouts let us.
12211 if (workInProgressRootHasPendingPing) {
12212 var _lastPingedTime = root.lastPingedTime;
12213
12214 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
12215 // This render was pinged but we didn't get to restart earlier
12216 // so try restarting now instead.
12217 root.lastPingedTime = expirationTime;
12218 prepareFreshStack(root, expirationTime);
12219 break;
12220 }
12221 }
12222
12223 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
12224
12225 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
12226 // There's additional work on this root.
12227 break;
12228 }
12229
12230 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
12231 // We should prefer to render the fallback of at the last
12232 // suspended level. Ping the last suspended level to try
12233 // rendering it again.
12234 root.lastPingedTime = _lastSuspendedTime;
12235 break;
12236 }
12237
12238 var _msUntilTimeout;
12239
12240 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
12241 // We have processed a suspense config whose expiration time we
12242 // can use as the timeout.
12243 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
12244 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
12245 // This should never normally happen because only new updates
12246 // cause delayed states, so we should have processed something.
12247 // However, this could also happen in an offscreen tree.
12248 _msUntilTimeout = 0;
12249 } else {
12250 // If we don't have a suspense config, we're going to use a
12251 // heuristic to determine how long we can suspend.
12252 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
12253 var currentTimeMs = now();
12254 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
12255 var timeElapsed = currentTimeMs - eventTimeMs;
12256
12257 if (timeElapsed < 0) {
12258 // We get this wrong some time since we estimate the time.
12259 timeElapsed = 0;
12260 }
12261
12262 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
12263 // event time is exact instead of inferred from expiration time
12264 // we don't need this.
12265
12266 if (timeUntilExpirationMs < _msUntilTimeout) {
12267 _msUntilTimeout = timeUntilExpirationMs;
12268 }
12269 } // Don't bother with a very short suspense time.
12270
12271
12272 if (_msUntilTimeout > 10) {
12273 // The render is suspended, it hasn't timed out, and there's no
12274 // lower priority work to do. Instead of committing the fallback
12275 // immediately, wait for more data to arrive.
12276 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
12277 break;
12278 }
12279 } // The work expired. Commit immediately.
12280
12281
12282 commitRoot(root);
12283 break;
12284 }
12285
12286 case RootCompleted:
12287 {
12288 // The work completed. Ready to commit.
12289 if ( // do not delay if we're inside an act() scope
12290 !( IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
12291 // If we have exceeded the minimum loading delay, which probably
12292 // means we have shown a spinner already, we might have to suspend
12293 // a bit longer to ensure that the spinner is shown for
12294 // enough time.
12295 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
12296
12297 if (_msUntilTimeout2 > 10) {
12298 markRootSuspendedAtTime(root, expirationTime);
12299 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
12300 break;
12301 }
12302 }
12303
12304 commitRoot(root);
12305 break;
12306 }
12307
12308 default:
12309 {
12310 {
12311 {
12312 throw Error( "Unknown root exit status." );
12313 }
12314 }
12315 }
12316 }
12317} // This is the entry point for synchronous tasks that don't go
12318// through Scheduler
12319
12320
12321function performSyncWorkOnRoot(root) {
12322 // Check if there's expired work on this root. Otherwise, render at Sync.
12323 var lastExpiredTime = root.lastExpiredTime;
12324 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
12325
12326 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12327 {
12328 throw Error( "Should not already be working." );
12329 }
12330 }
12331
12332 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12333 // and prepare a fresh one. Otherwise we'll continue where we left off.
12334
12335 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12336 prepareFreshStack(root, expirationTime);
12337 startWorkOnPendingInteractions(root, expirationTime);
12338 } // If we have a work-in-progress fiber, it means there's still work to do
12339 // in this root.
12340
12341
12342 if (workInProgress !== null) {
12343 var prevExecutionContext = executionContext;
12344 executionContext |= RenderContext;
12345 var prevDispatcher = pushDispatcher();
12346 var prevInteractions = pushInteractions(root);
12347 startWorkLoopTimer(workInProgress);
12348
12349 do {
12350 try {
12351 workLoopSync();
12352 break;
12353 } catch (thrownValue) {
12354 handleError(root, thrownValue);
12355 }
12356 } while (true);
12357
12358 resetContextDependencies();
12359 executionContext = prevExecutionContext;
12360 popDispatcher(prevDispatcher);
12361
12362 {
12363 popInteractions(prevInteractions);
12364 }
12365
12366 if (workInProgressRootExitStatus === RootFatalErrored) {
12367 var fatalError = workInProgressRootFatalError;
12368 stopInterruptedWorkLoopTimer();
12369 prepareFreshStack(root, expirationTime);
12370 markRootSuspendedAtTime(root, expirationTime);
12371 ensureRootIsScheduled(root);
12372 throw fatalError;
12373 }
12374
12375 if (workInProgress !== null) {
12376 // This is a sync render, so we should have finished the whole tree.
12377 {
12378 {
12379 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
12380 }
12381 }
12382 } else {
12383 // We now have a consistent tree. Because this is a sync render, we
12384 // will commit it even if something suspended.
12385 stopFinishedWorkLoopTimer();
12386 root.finishedWork = root.current.alternate;
12387 root.finishedExpirationTime = expirationTime;
12388 finishSyncRender(root);
12389 } // Before exiting, make sure there's a callback scheduled for the next
12390 // pending level.
12391
12392
12393 ensureRootIsScheduled(root);
12394 }
12395
12396 return null;
12397}
12398
12399function finishSyncRender(root) {
12400 // Set this to null to indicate there's no in-progress render.
12401 workInProgressRoot = null;
12402 commitRoot(root);
12403}
12404function syncUpdates(fn, a, b, c) {
12405 return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c));
12406}
12407
12408function batchedUpdates(fn, a) {
12409 var prevExecutionContext = executionContext;
12410 executionContext |= BatchedContext;
12411
12412 try {
12413 return fn(a);
12414 } finally {
12415 executionContext = prevExecutionContext;
12416
12417 if (executionContext === NoContext) {
12418 // Flush the immediate callbacks that were scheduled during this batch
12419 flushSyncCallbackQueue();
12420 }
12421 }
12422}
12423function flushSync(fn, a) {
12424 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12425 {
12426 {
12427 throw Error( "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." );
12428 }
12429 }
12430 }
12431
12432 var prevExecutionContext = executionContext;
12433 executionContext |= BatchedContext;
12434
12435 try {
12436 return runWithPriority(ImmediatePriority, fn.bind(null, a));
12437 } finally {
12438 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
12439 // Note that this will happen even if batchedUpdates is higher up
12440 // the stack.
12441
12442 flushSyncCallbackQueue();
12443 }
12444}
12445
12446function prepareFreshStack(root, expirationTime) {
12447 root.finishedWork = null;
12448 root.finishedExpirationTime = NoWork;
12449 var timeoutHandle = root.timeoutHandle;
12450
12451 if (timeoutHandle !== noTimeout) {
12452 // The root previous suspended and scheduled a timeout to commit a fallback
12453 // state. Now that we have additional work, cancel the timeout.
12454 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12455
12456 cancelTimeout(timeoutHandle);
12457 }
12458
12459 if (workInProgress !== null) {
12460 var interruptedWork = workInProgress.return;
12461
12462 while (interruptedWork !== null) {
12463 unwindInterruptedWork(interruptedWork);
12464 interruptedWork = interruptedWork.return;
12465 }
12466 }
12467
12468 workInProgressRoot = root;
12469 workInProgress = createWorkInProgress(root.current, null);
12470 renderExpirationTime$1 = expirationTime;
12471 workInProgressRootExitStatus = RootIncomplete;
12472 workInProgressRootFatalError = null;
12473 workInProgressRootLatestProcessedExpirationTime = Sync;
12474 workInProgressRootLatestSuspenseTimeout = Sync;
12475 workInProgressRootCanSuspendUsingConfig = null;
12476 workInProgressRootNextUnprocessedUpdateTime = NoWork;
12477 workInProgressRootHasPendingPing = false;
12478
12479 {
12480 spawnedWorkDuringRender = null;
12481 }
12482
12483 {
12484 ReactStrictModeWarnings.discardPendingWarnings();
12485 }
12486}
12487
12488function handleError(root, thrownValue) {
12489 do {
12490 try {
12491 // Reset module-level state that was set during the render phase.
12492 resetContextDependencies();
12493 resetHooksAfterThrow();
12494 resetCurrentFiber();
12495
12496 if (workInProgress === null || workInProgress.return === null) {
12497 // Expected to be working on a non-root fiber. This is a fatal error
12498 // because there's no ancestor that can handle it; the root is
12499 // supposed to capture all errors that weren't caught by an error
12500 // boundary.
12501 workInProgressRootExitStatus = RootFatalErrored;
12502 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
12503 // sibling, or the parent if there are no siblings. But since the root
12504 // has no siblings nor a parent, we set it to null. Usually this is
12505 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
12506 // interntionally not calling those, we need set it here.
12507 // TODO: Consider calling `unwindWork` to pop the contexts.
12508
12509 workInProgress = null;
12510 return null;
12511 }
12512
12513 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
12514 // Record the time spent rendering before an error was thrown. This
12515 // avoids inaccurate Profiler durations in the case of a
12516 // suspended render.
12517 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
12518 }
12519
12520 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime$1);
12521 workInProgress = completeUnitOfWork(workInProgress);
12522 } catch (yetAnotherThrownValue) {
12523 // Something in the return path also threw.
12524 thrownValue = yetAnotherThrownValue;
12525 continue;
12526 } // Return to the normal work loop.
12527
12528
12529 return;
12530 } while (true);
12531}
12532
12533function pushDispatcher(root) {
12534 var prevDispatcher = ReactCurrentDispatcher$1.current;
12535 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12536
12537 if (prevDispatcher === null) {
12538 // The React isomorphic package does not include a default dispatcher.
12539 // Instead the first renderer will lazily attach one, in order to give
12540 // nicer error messages.
12541 return ContextOnlyDispatcher;
12542 } else {
12543 return prevDispatcher;
12544 }
12545}
12546
12547function popDispatcher(prevDispatcher) {
12548 ReactCurrentDispatcher$1.current = prevDispatcher;
12549}
12550
12551function pushInteractions(root) {
12552 {
12553 var prevInteractions = tracing.__interactionsRef.current;
12554 tracing.__interactionsRef.current = root.memoizedInteractions;
12555 return prevInteractions;
12556 }
12557}
12558
12559function popInteractions(prevInteractions) {
12560 {
12561 tracing.__interactionsRef.current = prevInteractions;
12562 }
12563}
12564
12565function markCommitTimeOfFallback() {
12566 globalMostRecentFallbackTime = now();
12567}
12568function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
12569 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
12570 workInProgressRootLatestProcessedExpirationTime = expirationTime;
12571 }
12572
12573 if (suspenseConfig !== null) {
12574 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
12575 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
12576
12577 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
12578 }
12579 }
12580}
12581function markUnprocessedUpdateTime(expirationTime) {
12582 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
12583 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
12584 }
12585}
12586function renderDidSuspend() {
12587 if (workInProgressRootExitStatus === RootIncomplete) {
12588 workInProgressRootExitStatus = RootSuspended;
12589 }
12590}
12591function renderDidSuspendDelayIfPossible() {
12592 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
12593 workInProgressRootExitStatus = RootSuspendedWithDelay;
12594 } // Check if there's a lower priority update somewhere else in the tree.
12595
12596
12597 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
12598 // Mark the current render as suspended, and then mark that there's a
12599 // pending update.
12600 // TODO: This should immediately interrupt the current render, instead
12601 // of waiting until the next time we yield.
12602 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1);
12603 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
12604 }
12605}
12606function renderDidError() {
12607 if (workInProgressRootExitStatus !== RootCompleted) {
12608 workInProgressRootExitStatus = RootErrored;
12609 }
12610} // Called during render to determine if anything has suspended.
12611// Returns false if we're not sure.
12612
12613function renderHasNotSuspendedYet() {
12614 // If something errored or completed, we can't really be sure,
12615 // so those are false.
12616 return workInProgressRootExitStatus === RootIncomplete;
12617}
12618
12619function inferTimeFromExpirationTime(expirationTime) {
12620 // We don't know exactly when the update was scheduled, but we can infer an
12621 // approximate start time from the expiration time.
12622 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
12623 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
12624}
12625
12626function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
12627 // We don't know exactly when the update was scheduled, but we can infer an
12628 // approximate start time from the expiration time by subtracting the timeout
12629 // that was added to the event time.
12630 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
12631 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
12632} // The work loop is an extremely hot path. Tell Closure not to inline it.
12633
12634/** @noinline */
12635
12636
12637function workLoopSync() {
12638 // Already timed out, so perform work without checking if we need to yield.
12639 while (workInProgress !== null) {
12640 workInProgress = performUnitOfWork(workInProgress);
12641 }
12642}
12643/** @noinline */
12644
12645
12646function workLoopConcurrent() {
12647 // Perform work until Scheduler asks us to yield
12648 while (workInProgress !== null && !shouldYield()) {
12649 workInProgress = performUnitOfWork(workInProgress);
12650 }
12651}
12652
12653function performUnitOfWork(unitOfWork) {
12654 // The current, flushed, state of this fiber is the alternate. Ideally
12655 // nothing should rely on this, but relying on it here means that we don't
12656 // need an additional field on the work in progress.
12657 var current = unitOfWork.alternate;
12658 startWorkTimer(unitOfWork);
12659 setCurrentFiber(unitOfWork);
12660 var next;
12661
12662 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
12663 startProfilerTimer(unitOfWork);
12664 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
12665 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
12666 } else {
12667 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
12668 }
12669
12670 resetCurrentFiber();
12671 unitOfWork.memoizedProps = unitOfWork.pendingProps;
12672
12673 if (next === null) {
12674 // If this doesn't spawn new work, complete the current work.
12675 next = completeUnitOfWork(unitOfWork);
12676 }
12677
12678 ReactCurrentOwner$2.current = null;
12679 return next;
12680}
12681
12682function completeUnitOfWork(unitOfWork) {
12683 // Attempt to complete the current unit of work, then move to the next
12684 // sibling. If there are no more siblings, return to the parent fiber.
12685 workInProgress = unitOfWork;
12686
12687 do {
12688 // The current, flushed, state of this fiber is the alternate. Ideally
12689 // nothing should rely on this, but relying on it here means that we don't
12690 // need an additional field on the work in progress.
12691 var current = workInProgress.alternate;
12692 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
12693
12694 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
12695 setCurrentFiber(workInProgress);
12696 var next = void 0;
12697
12698 if ( (workInProgress.mode & ProfileMode) === NoMode) {
12699 next = completeWork(current, workInProgress, renderExpirationTime$1);
12700 } else {
12701 startProfilerTimer(workInProgress);
12702 next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.
12703
12704 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
12705 }
12706
12707 stopWorkTimer(workInProgress);
12708 resetCurrentFiber();
12709 resetChildExpirationTime(workInProgress);
12710
12711 if (next !== null) {
12712 // Completing this fiber spawned new work. Work on that next.
12713 return next;
12714 }
12715
12716 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
12717 (returnFiber.effectTag & Incomplete) === NoEffect) {
12718 // Append all the effects of the subtree and this fiber onto the effect
12719 // list of the parent. The completion order of the children affects the
12720 // side-effect order.
12721 if (returnFiber.firstEffect === null) {
12722 returnFiber.firstEffect = workInProgress.firstEffect;
12723 }
12724
12725 if (workInProgress.lastEffect !== null) {
12726 if (returnFiber.lastEffect !== null) {
12727 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
12728 }
12729
12730 returnFiber.lastEffect = workInProgress.lastEffect;
12731 } // If this fiber had side-effects, we append it AFTER the children's
12732 // side-effects. We can perform certain side-effects earlier if needed,
12733 // by doing multiple passes over the effect list. We don't want to
12734 // schedule our own side-effect on our own list because if end up
12735 // reusing children we'll schedule this effect onto itself since we're
12736 // at the end.
12737
12738
12739 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
12740 // list. PerformedWork effect is read by React DevTools but shouldn't be
12741 // committed.
12742
12743 if (effectTag > PerformedWork) {
12744 if (returnFiber.lastEffect !== null) {
12745 returnFiber.lastEffect.nextEffect = workInProgress;
12746 } else {
12747 returnFiber.firstEffect = workInProgress;
12748 }
12749
12750 returnFiber.lastEffect = workInProgress;
12751 }
12752 }
12753 } else {
12754 // This fiber did not complete because something threw. Pop values off
12755 // the stack without entering the complete phase. If this is a boundary,
12756 // capture values if possible.
12757 var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time.
12758
12759
12760 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
12761 // Record the render duration for the fiber that errored.
12762 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
12763
12764 var actualDuration = workInProgress.actualDuration;
12765 var child = workInProgress.child;
12766
12767 while (child !== null) {
12768 actualDuration += child.actualDuration;
12769 child = child.sibling;
12770 }
12771
12772 workInProgress.actualDuration = actualDuration;
12773 }
12774
12775 if (_next !== null) {
12776 // If completing this work spawned new work, do that next. We'll come
12777 // back here again.
12778 // Since we're restarting, remove anything that is not a host effect
12779 // from the effect tag.
12780 // TODO: The name stopFailedWorkTimer is misleading because Suspense
12781 // also captures and restarts.
12782 stopFailedWorkTimer(workInProgress);
12783 _next.effectTag &= HostEffectMask;
12784 return _next;
12785 }
12786
12787 stopWorkTimer(workInProgress);
12788
12789 if (returnFiber !== null) {
12790 // Mark the parent fiber as incomplete and clear its effect list.
12791 returnFiber.firstEffect = returnFiber.lastEffect = null;
12792 returnFiber.effectTag |= Incomplete;
12793 }
12794 }
12795
12796 var siblingFiber = workInProgress.sibling;
12797
12798 if (siblingFiber !== null) {
12799 // If there is more work to do in this returnFiber, do that next.
12800 return siblingFiber;
12801 } // Otherwise, return to the parent
12802
12803
12804 workInProgress = returnFiber;
12805 } while (workInProgress !== null); // We've reached the root.
12806
12807
12808 if (workInProgressRootExitStatus === RootIncomplete) {
12809 workInProgressRootExitStatus = RootCompleted;
12810 }
12811
12812 return null;
12813}
12814
12815function getRemainingExpirationTime(fiber) {
12816 var updateExpirationTime = fiber.expirationTime;
12817 var childExpirationTime = fiber.childExpirationTime;
12818 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
12819}
12820
12821function resetChildExpirationTime(completedWork) {
12822 if (renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never) {
12823 // The children of this component are hidden. Don't bubble their
12824 // expiration times.
12825 return;
12826 }
12827
12828 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
12829
12830 if ( (completedWork.mode & ProfileMode) !== NoMode) {
12831 // In profiling mode, resetChildExpirationTime is also used to reset
12832 // profiler durations.
12833 var actualDuration = completedWork.actualDuration;
12834 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
12835 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
12836 // When work is done, it should bubble to the parent's actualDuration. If
12837 // the fiber has not been cloned though, (meaning no work was done), then
12838 // this value will reflect the amount of time spent working on a previous
12839 // render. In that case it should not bubble. We determine whether it was
12840 // cloned by comparing the child pointer.
12841
12842 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
12843 var child = completedWork.child;
12844
12845 while (child !== null) {
12846 var childUpdateExpirationTime = child.expirationTime;
12847 var childChildExpirationTime = child.childExpirationTime;
12848
12849 if (childUpdateExpirationTime > newChildExpirationTime) {
12850 newChildExpirationTime = childUpdateExpirationTime;
12851 }
12852
12853 if (childChildExpirationTime > newChildExpirationTime) {
12854 newChildExpirationTime = childChildExpirationTime;
12855 }
12856
12857 if (shouldBubbleActualDurations) {
12858 actualDuration += child.actualDuration;
12859 }
12860
12861 treeBaseDuration += child.treeBaseDuration;
12862 child = child.sibling;
12863 }
12864
12865 completedWork.actualDuration = actualDuration;
12866 completedWork.treeBaseDuration = treeBaseDuration;
12867 } else {
12868 var _child = completedWork.child;
12869
12870 while (_child !== null) {
12871 var _childUpdateExpirationTime = _child.expirationTime;
12872 var _childChildExpirationTime = _child.childExpirationTime;
12873
12874 if (_childUpdateExpirationTime > newChildExpirationTime) {
12875 newChildExpirationTime = _childUpdateExpirationTime;
12876 }
12877
12878 if (_childChildExpirationTime > newChildExpirationTime) {
12879 newChildExpirationTime = _childChildExpirationTime;
12880 }
12881
12882 _child = _child.sibling;
12883 }
12884 }
12885
12886 completedWork.childExpirationTime = newChildExpirationTime;
12887}
12888
12889function commitRoot(root) {
12890 var renderPriorityLevel = getCurrentPriorityLevel();
12891 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
12892 return null;
12893}
12894
12895function commitRootImpl(root, renderPriorityLevel) {
12896 do {
12897 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
12898 // means `flushPassiveEffects` will sometimes result in additional
12899 // passive effects. So we need to keep flushing in a loop until there are
12900 // no more pending effects.
12901 // TODO: Might be better if `flushPassiveEffects` did not automatically
12902 // flush synchronous work at the end, to avoid factoring hazards like this.
12903 flushPassiveEffects();
12904 } while (rootWithPendingPassiveEffects !== null);
12905
12906 flushRenderPhaseStrictModeWarningsInDEV();
12907
12908 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12909 {
12910 throw Error( "Should not already be working." );
12911 }
12912 }
12913
12914 var finishedWork = root.finishedWork;
12915 var expirationTime = root.finishedExpirationTime;
12916
12917 if (finishedWork === null) {
12918 return null;
12919 }
12920
12921 root.finishedWork = null;
12922 root.finishedExpirationTime = NoWork;
12923
12924 if (!(finishedWork !== root.current)) {
12925 {
12926 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
12927 }
12928 } // commitRoot never returns a continuation; it always finishes synchronously.
12929 // So we can clear these now to allow a new callback to be scheduled.
12930
12931
12932 root.callbackNode = null;
12933 root.callbackExpirationTime = NoWork;
12934 root.callbackPriority = NoPriority;
12935 root.nextKnownPendingLevel = NoWork;
12936 startCommitTimer(); // Update the first and last pending times on this root. The new first
12937 // pending time is whatever is left on the root fiber.
12938
12939 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
12940 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
12941
12942 if (root === workInProgressRoot) {
12943 // We can reset these now that they are finished.
12944 workInProgressRoot = null;
12945 workInProgress = null;
12946 renderExpirationTime$1 = NoWork;
12947 } // This indicates that the last root we worked on is not the same one that
12948 // we're committing now. This most commonly happens when a suspended root
12949 // times out.
12950 // Get the list of effects.
12951
12952
12953 var firstEffect;
12954
12955 if (finishedWork.effectTag > PerformedWork) {
12956 // A fiber's effect list consists only of its children, not itself. So if
12957 // the root has an effect, we need to add it to the end of the list. The
12958 // resulting list is the set that would belong to the root's parent, if it
12959 // had one; that is, all the effects in the tree including the root.
12960 if (finishedWork.lastEffect !== null) {
12961 finishedWork.lastEffect.nextEffect = finishedWork;
12962 firstEffect = finishedWork.firstEffect;
12963 } else {
12964 firstEffect = finishedWork;
12965 }
12966 } else {
12967 // There is no effect on the root.
12968 firstEffect = finishedWork.firstEffect;
12969 }
12970
12971 if (firstEffect !== null) {
12972 var prevExecutionContext = executionContext;
12973 executionContext |= CommitContext;
12974 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
12975
12976 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
12977 // of the effect list for each phase: all mutation effects come before all
12978 // layout effects, and so on.
12979 // The first phase a "before mutation" phase. We use this phase to read the
12980 // state of the host tree right before we mutate it. This is where
12981 // getSnapshotBeforeUpdate is called.
12982
12983 startCommitSnapshotEffectsTimer();
12984 prepareForCommit(root.containerInfo);
12985 nextEffect = firstEffect;
12986
12987 do {
12988 {
12989 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
12990
12991 if (hasCaughtError()) {
12992 if (!(nextEffect !== null)) {
12993 {
12994 throw Error( "Should be working on an effect." );
12995 }
12996 }
12997
12998 var error = clearCaughtError();
12999 captureCommitPhaseError(nextEffect, error);
13000 nextEffect = nextEffect.nextEffect;
13001 }
13002 }
13003 } while (nextEffect !== null);
13004
13005 stopCommitSnapshotEffectsTimer();
13006
13007 {
13008 // Mark the current commit time to be shared by all Profilers in this
13009 // batch. This enables them to be grouped later.
13010 recordCommitTime();
13011 } // The next phase is the mutation phase, where we mutate the host tree.
13012
13013
13014 startCommitHostEffectsTimer();
13015 nextEffect = firstEffect;
13016
13017 do {
13018 {
13019 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
13020
13021 if (hasCaughtError()) {
13022 if (!(nextEffect !== null)) {
13023 {
13024 throw Error( "Should be working on an effect." );
13025 }
13026 }
13027
13028 var _error = clearCaughtError();
13029
13030 captureCommitPhaseError(nextEffect, _error);
13031 nextEffect = nextEffect.nextEffect;
13032 }
13033 }
13034 } while (nextEffect !== null);
13035
13036 stopCommitHostEffectsTimer();
13037 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
13038 // the mutation phase, so that the previous tree is still current during
13039 // componentWillUnmount, but before the layout phase, so that the finished
13040 // work is current during componentDidMount/Update.
13041
13042 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
13043 // the host tree after it's been mutated. The idiomatic use case for this is
13044 // layout, but class component lifecycles also fire here for legacy reasons.
13045
13046 startCommitLifeCyclesTimer();
13047 nextEffect = firstEffect;
13048
13049 do {
13050 {
13051 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
13052
13053 if (hasCaughtError()) {
13054 if (!(nextEffect !== null)) {
13055 {
13056 throw Error( "Should be working on an effect." );
13057 }
13058 }
13059
13060 var _error2 = clearCaughtError();
13061
13062 captureCommitPhaseError(nextEffect, _error2);
13063 nextEffect = nextEffect.nextEffect;
13064 }
13065 }
13066 } while (nextEffect !== null);
13067
13068 stopCommitLifeCyclesTimer();
13069 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
13070 // opportunity to paint.
13071
13072 requestPaint();
13073
13074 {
13075 popInteractions(prevInteractions);
13076 }
13077
13078 executionContext = prevExecutionContext;
13079 } else {
13080 // No effects.
13081 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
13082 // no effects.
13083 // TODO: Maybe there's a better way to report this.
13084
13085 startCommitSnapshotEffectsTimer();
13086 stopCommitSnapshotEffectsTimer();
13087
13088 {
13089 recordCommitTime();
13090 }
13091
13092 startCommitHostEffectsTimer();
13093 stopCommitHostEffectsTimer();
13094 startCommitLifeCyclesTimer();
13095 stopCommitLifeCyclesTimer();
13096 }
13097
13098 stopCommitTimer();
13099 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
13100
13101 if (rootDoesHavePassiveEffects) {
13102 // This commit has passive effects. Stash a reference to them. But don't
13103 // schedule a callback until after flushing layout work.
13104 rootDoesHavePassiveEffects = false;
13105 rootWithPendingPassiveEffects = root;
13106 pendingPassiveEffectsExpirationTime = expirationTime;
13107 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
13108 } else {
13109 // We are done with the effect chain at this point so let's clear the
13110 // nextEffect pointers to assist with GC. If we have passive effects, we'll
13111 // clear this in flushPassiveEffects.
13112 nextEffect = firstEffect;
13113
13114 while (nextEffect !== null) {
13115 var nextNextEffect = nextEffect.nextEffect;
13116 nextEffect.nextEffect = null;
13117 nextEffect = nextNextEffect;
13118 }
13119 } // Check if there's remaining work on this root
13120
13121
13122 var remainingExpirationTime = root.firstPendingTime;
13123
13124 if (remainingExpirationTime !== NoWork) {
13125 {
13126 if (spawnedWorkDuringRender !== null) {
13127 var expirationTimes = spawnedWorkDuringRender;
13128 spawnedWorkDuringRender = null;
13129
13130 for (var i = 0; i < expirationTimes.length; i++) {
13131 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
13132 }
13133 }
13134
13135 schedulePendingInteractions(root, remainingExpirationTime);
13136 }
13137 } else {
13138 // If there's no remaining work, we can clear the set of already failed
13139 // error boundaries.
13140 legacyErrorBoundariesThatAlreadyFailed = null;
13141 }
13142
13143 {
13144 if (!rootDidHavePassiveEffects) {
13145 // If there are no passive effects, then we can complete the pending interactions.
13146 // Otherwise, we'll wait until after the passive effects are flushed.
13147 // Wait to do this until after remaining work has been scheduled,
13148 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
13149 finishPendingInteractions(root, expirationTime);
13150 }
13151 }
13152
13153 if (remainingExpirationTime === Sync) {
13154 // Count the number of times the root synchronously re-renders without
13155 // finishing. If there are too many, it indicates an infinite update loop.
13156 if (root === rootWithNestedUpdates) {
13157 nestedUpdateCount++;
13158 } else {
13159 nestedUpdateCount = 0;
13160 rootWithNestedUpdates = root;
13161 }
13162 } else {
13163 nestedUpdateCount = 0;
13164 }
13165
13166 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
13167 // additional work on this root is scheduled.
13168
13169 ensureRootIsScheduled(root);
13170
13171 if (hasUncaughtError) {
13172 hasUncaughtError = false;
13173 var _error3 = firstUncaughtError;
13174 firstUncaughtError = null;
13175 throw _error3;
13176 }
13177
13178 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
13179 // This is a legacy edge case. We just committed the initial mount of
13180 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
13181 // synchronously, but layout updates should be deferred until the end
13182 // of the batch.
13183 return null;
13184 } // If layout work was scheduled, flush it now.
13185
13186
13187 flushSyncCallbackQueue();
13188 return null;
13189}
13190
13191function commitBeforeMutationEffects() {
13192 while (nextEffect !== null) {
13193 var effectTag = nextEffect.effectTag;
13194
13195 if ((effectTag & Snapshot) !== NoEffect) {
13196 setCurrentFiber(nextEffect);
13197 recordEffect();
13198 var current = nextEffect.alternate;
13199 commitBeforeMutationLifeCycles(current, nextEffect);
13200 resetCurrentFiber();
13201 }
13202
13203 if ((effectTag & Passive) !== NoEffect) {
13204 // If there are passive effects, schedule a callback to flush at
13205 // the earliest opportunity.
13206 if (!rootDoesHavePassiveEffects) {
13207 rootDoesHavePassiveEffects = true;
13208 scheduleCallback(NormalPriority, function () {
13209 flushPassiveEffects();
13210 return null;
13211 });
13212 }
13213 }
13214
13215 nextEffect = nextEffect.nextEffect;
13216 }
13217}
13218
13219function commitMutationEffects(root, renderPriorityLevel) {
13220 // TODO: Should probably move the bulk of this function to commitWork.
13221 while (nextEffect !== null) {
13222 setCurrentFiber(nextEffect);
13223 var effectTag = nextEffect.effectTag;
13224
13225 if (effectTag & ContentReset) {
13226 commitResetTextContent(nextEffect);
13227 }
13228
13229 if (effectTag & Ref) {
13230 var current = nextEffect.alternate;
13231
13232 if (current !== null) {
13233 commitDetachRef(current);
13234 }
13235 } // The following switch statement is only concerned about placement,
13236 // updates, and deletions. To avoid needing to add a case for every possible
13237 // bitmap value, we remove the secondary effects from the effect tag and
13238 // switch on that value.
13239
13240
13241 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
13242
13243 switch (primaryEffectTag) {
13244 case Placement:
13245 {
13246 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13247 // inserted, before any life-cycles like componentDidMount gets called.
13248 // TODO: findDOMNode doesn't rely on this any more but isMounted does
13249 // and isMounted is deprecated anyway so we should be able to kill this.
13250
13251 nextEffect.effectTag &= ~Placement;
13252 break;
13253 }
13254
13255 case PlacementAndUpdate:
13256 {
13257 // Placement
13258 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13259 // inserted, before any life-cycles like componentDidMount gets called.
13260
13261 nextEffect.effectTag &= ~Placement; // Update
13262
13263 var _current = nextEffect.alternate;
13264 commitWork(_current, nextEffect);
13265 break;
13266 }
13267
13268 case Hydrating:
13269 {
13270 nextEffect.effectTag &= ~Hydrating;
13271 break;
13272 }
13273
13274 case HydratingAndUpdate:
13275 {
13276 nextEffect.effectTag &= ~Hydrating; // Update
13277
13278 var _current2 = nextEffect.alternate;
13279 commitWork(_current2, nextEffect);
13280 break;
13281 }
13282
13283 case Update:
13284 {
13285 var _current3 = nextEffect.alternate;
13286 commitWork(_current3, nextEffect);
13287 break;
13288 }
13289
13290 case Deletion:
13291 {
13292 commitDeletion(root, nextEffect, renderPriorityLevel);
13293 break;
13294 }
13295 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
13296
13297
13298 recordEffect();
13299 resetCurrentFiber();
13300 nextEffect = nextEffect.nextEffect;
13301 }
13302}
13303
13304function commitLayoutEffects(root, committedExpirationTime) {
13305 // TODO: Should probably move the bulk of this function to commitWork.
13306 while (nextEffect !== null) {
13307 setCurrentFiber(nextEffect);
13308 var effectTag = nextEffect.effectTag;
13309
13310 if (effectTag & (Update | Callback)) {
13311 recordEffect();
13312 var current = nextEffect.alternate;
13313 commitLifeCycles(root, current, nextEffect);
13314 }
13315
13316 if (effectTag & Ref) {
13317 recordEffect();
13318 commitAttachRef(nextEffect);
13319 }
13320
13321 resetCurrentFiber();
13322 nextEffect = nextEffect.nextEffect;
13323 }
13324}
13325
13326function flushPassiveEffects() {
13327 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
13328 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
13329 pendingPassiveEffectsRenderPriority = NoPriority;
13330 return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
13331 }
13332}
13333
13334function flushPassiveEffectsImpl() {
13335 if (rootWithPendingPassiveEffects === null) {
13336 return false;
13337 }
13338
13339 var root = rootWithPendingPassiveEffects;
13340 var expirationTime = pendingPassiveEffectsExpirationTime;
13341 rootWithPendingPassiveEffects = null;
13342 pendingPassiveEffectsExpirationTime = NoWork;
13343
13344 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13345 {
13346 throw Error( "Cannot flush passive effects while already rendering." );
13347 }
13348 }
13349
13350 var prevExecutionContext = executionContext;
13351 executionContext |= CommitContext;
13352 var prevInteractions = pushInteractions(root);
13353
13354 {
13355 // Note: This currently assumes there are no passive effects on the root fiber
13356 // because the root is not part of its own effect list.
13357 // This could change in the future.
13358 var _effect2 = root.current.firstEffect;
13359
13360 while (_effect2 !== null) {
13361 {
13362 setCurrentFiber(_effect2);
13363 invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);
13364
13365 if (hasCaughtError()) {
13366 if (!(_effect2 !== null)) {
13367 {
13368 throw Error( "Should be working on an effect." );
13369 }
13370 }
13371
13372 var _error5 = clearCaughtError();
13373
13374 captureCommitPhaseError(_effect2, _error5);
13375 }
13376
13377 resetCurrentFiber();
13378 }
13379
13380 var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC
13381
13382 _effect2.nextEffect = null;
13383 _effect2 = nextNextEffect;
13384 }
13385 }
13386
13387 {
13388 popInteractions(prevInteractions);
13389 finishPendingInteractions(root, expirationTime);
13390 }
13391
13392 executionContext = prevExecutionContext;
13393 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
13394 // exceeds the limit, we'll fire a warning.
13395
13396 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
13397 return true;
13398}
13399
13400function isAlreadyFailedLegacyErrorBoundary(instance) {
13401 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
13402}
13403function markLegacyErrorBoundaryAsFailed(instance) {
13404 if (legacyErrorBoundariesThatAlreadyFailed === null) {
13405 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
13406 } else {
13407 legacyErrorBoundariesThatAlreadyFailed.add(instance);
13408 }
13409}
13410
13411function prepareToThrowUncaughtError(error) {
13412 if (!hasUncaughtError) {
13413 hasUncaughtError = true;
13414 firstUncaughtError = error;
13415 }
13416}
13417
13418var onUncaughtError = prepareToThrowUncaughtError;
13419
13420function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
13421 var errorInfo = createCapturedValue(error, sourceFiber);
13422 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
13423 enqueueUpdate(rootFiber, update);
13424 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
13425
13426 if (root !== null) {
13427 ensureRootIsScheduled(root);
13428 schedulePendingInteractions(root, Sync);
13429 }
13430}
13431
13432function captureCommitPhaseError(sourceFiber, error) {
13433 if (sourceFiber.tag === HostRoot) {
13434 // Error was thrown at the root. There is no parent, so the root
13435 // itself should capture it.
13436 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
13437 return;
13438 }
13439
13440 var fiber = sourceFiber.return;
13441
13442 while (fiber !== null) {
13443 if (fiber.tag === HostRoot) {
13444 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
13445 return;
13446 } else if (fiber.tag === ClassComponent) {
13447 var ctor = fiber.type;
13448 var instance = fiber.stateNode;
13449
13450 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
13451 var errorInfo = createCapturedValue(error, sourceFiber);
13452 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
13453 Sync);
13454 enqueueUpdate(fiber, update);
13455 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
13456
13457 if (root !== null) {
13458 ensureRootIsScheduled(root);
13459 schedulePendingInteractions(root, Sync);
13460 }
13461
13462 return;
13463 }
13464 }
13465
13466 fiber = fiber.return;
13467 }
13468}
13469function pingSuspendedRoot(root, thenable, suspendedTime) {
13470 var pingCache = root.pingCache;
13471
13472 if (pingCache !== null) {
13473 // The thenable resolved, so we no longer need to memoize, because it will
13474 // never be thrown again.
13475 pingCache.delete(thenable);
13476 }
13477
13478 if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) {
13479 // Received a ping at the same priority level at which we're currently
13480 // rendering. We might want to restart this render. This should mirror
13481 // the logic of whether or not a root suspends once it completes.
13482 // TODO: If we're rendering sync either due to Sync, Batched or expired,
13483 // we should probably never restart.
13484 // If we're suspended with delay, we'll always suspend so we can always
13485 // restart. If we're suspended without any updates, it might be a retry.
13486 // If it's early in the retry we can restart. We can't know for sure
13487 // whether we'll eventually process an update during this render pass,
13488 // but it's somewhat unlikely that we get to a ping before that, since
13489 // getting to the root most update is usually very fast.
13490 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
13491 // Restart from the root. Don't need to schedule a ping because
13492 // we're already working on this tree.
13493 prepareFreshStack(root, renderExpirationTime$1);
13494 } else {
13495 // Even though we can't restart right now, we might get an
13496 // opportunity later. So we mark this render as having a ping.
13497 workInProgressRootHasPendingPing = true;
13498 }
13499
13500 return;
13501 }
13502
13503 if (!isRootSuspendedAtTime(root, suspendedTime)) {
13504 // The root is no longer suspended at this time.
13505 return;
13506 }
13507
13508 var lastPingedTime = root.lastPingedTime;
13509
13510 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
13511 // There's already a lower priority ping scheduled.
13512 return;
13513 } // Mark the time at which this ping was scheduled.
13514
13515
13516 root.lastPingedTime = suspendedTime;
13517
13518 ensureRootIsScheduled(root);
13519 schedulePendingInteractions(root, suspendedTime);
13520}
13521
13522function retryTimedOutBoundary(boundaryFiber, retryTime) {
13523 // The boundary fiber (a Suspense component or SuspenseList component)
13524 // previously was rendered in its fallback state. One of the promises that
13525 // suspended it has resolved, which means at least part of the tree was
13526 // likely unblocked. Try rendering again, at a new expiration time.
13527 if (retryTime === NoWork) {
13528 var suspenseConfig = null; // Retries don't carry over the already committed update.
13529
13530 var currentTime = requestCurrentTimeForUpdate();
13531 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
13532 } // TODO: Special case idle priority?
13533
13534
13535 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
13536
13537 if (root !== null) {
13538 ensureRootIsScheduled(root);
13539 schedulePendingInteractions(root, retryTime);
13540 }
13541}
13542function resolveRetryThenable(boundaryFiber, thenable) {
13543 var retryTime = NoWork; // Default
13544
13545 var retryCache;
13546
13547 {
13548 retryCache = boundaryFiber.stateNode;
13549 }
13550
13551 if (retryCache !== null) {
13552 // The thenable resolved, so we no longer need to memoize, because it will
13553 // never be thrown again.
13554 retryCache.delete(thenable);
13555 }
13556
13557 retryTimedOutBoundary(boundaryFiber, retryTime);
13558} // Computes the next Just Noticeable Difference (JND) boundary.
13559// The theory is that a person can't tell the difference between small differences in time.
13560// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
13561// difference in the experience. However, waiting for longer might mean that we can avoid
13562// showing an intermediate loading state. The longer we have already waited, the harder it
13563// is to tell small differences in time. Therefore, the longer we've already waited,
13564// the longer we can wait additionally. At some point we have to give up though.
13565// We pick a train model where the next boundary commits at a consistent schedule.
13566// These particular numbers are vague estimates. We expect to adjust them based on research.
13567
13568function jnd(timeElapsed) {
13569 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
13570}
13571
13572function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
13573 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
13574
13575 if (busyMinDurationMs <= 0) {
13576 return 0;
13577 }
13578
13579 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
13580
13581 var currentTimeMs = now();
13582 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
13583 var timeElapsed = currentTimeMs - eventTimeMs;
13584
13585 if (timeElapsed <= busyDelayMs) {
13586 // If we haven't yet waited longer than the initial delay, we don't
13587 // have to wait any additional time.
13588 return 0;
13589 }
13590
13591 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
13592
13593 return msUntilTimeout;
13594}
13595
13596function checkForNestedUpdates() {
13597 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
13598 nestedUpdateCount = 0;
13599 rootWithNestedUpdates = null;
13600
13601 {
13602 {
13603 throw 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." );
13604 }
13605 }
13606 }
13607
13608 {
13609 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
13610 nestedPassiveUpdateCount = 0;
13611
13612 error('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.');
13613 }
13614 }
13615}
13616
13617function flushRenderPhaseStrictModeWarningsInDEV() {
13618 {
13619 ReactStrictModeWarnings.flushLegacyContextWarning();
13620
13621 {
13622 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
13623 }
13624 }
13625}
13626
13627function stopFinishedWorkLoopTimer() {
13628 var didCompleteRoot = true;
13629 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
13630 interruptedBy = null;
13631}
13632
13633function stopInterruptedWorkLoopTimer() {
13634 // TODO: Track which fiber caused the interruption.
13635 var didCompleteRoot = false;
13636 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
13637 interruptedBy = null;
13638}
13639
13640function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
13641 if ( workInProgressRoot !== null && updateExpirationTime > renderExpirationTime$1) {
13642 interruptedBy = fiberThatReceivedUpdate;
13643 }
13644}
13645
13646var didWarnStateUpdateForUnmountedComponent = null;
13647
13648function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
13649 {
13650 var tag = fiber.tag;
13651
13652 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
13653 // Only warn for user-defined components, not internal ones like Suspense.
13654 return;
13655 }
13656 // the problematic code almost always lies inside that component.
13657
13658
13659 var componentName = getComponentName(fiber.type) || 'ReactComponent';
13660
13661 if (didWarnStateUpdateForUnmountedComponent !== null) {
13662 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
13663 return;
13664 }
13665
13666 didWarnStateUpdateForUnmountedComponent.add(componentName);
13667 } else {
13668 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
13669 }
13670
13671 error("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));
13672 }
13673}
13674
13675var beginWork$1;
13676
13677{
13678 beginWork$1 = beginWork;
13679}
13680
13681var didWarnAboutUpdateInRender = false;
13682var didWarnAboutUpdateInGetChildContext = false;
13683
13684function warnAboutRenderPhaseUpdatesInDEV(fiber) {
13685 {
13686 if ((executionContext & RenderContext) !== NoContext) {
13687 switch (fiber.tag) {
13688 case FunctionComponent:
13689 case ForwardRef:
13690 case SimpleMemoComponent:
13691 {
13692 error('Cannot update a component from inside the function body of a ' + 'different component.');
13693
13694 break;
13695 }
13696
13697 case ClassComponent:
13698 {
13699 switch (phase) {
13700 case 'getChildContext':
13701 if (didWarnAboutUpdateInGetChildContext) {
13702 return;
13703 }
13704
13705 error('setState(...): Cannot call setState() inside getChildContext()');
13706
13707 didWarnAboutUpdateInGetChildContext = true;
13708 break;
13709
13710 case 'render':
13711 if (didWarnAboutUpdateInRender) {
13712 return;
13713 }
13714
13715 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
13716
13717 didWarnAboutUpdateInRender = true;
13718 break;
13719 }
13720
13721 break;
13722 }
13723 }
13724 }
13725 }
13726} // a 'shared' variable that changes when act() opens/closes in tests.
13727
13728
13729var IsThisRendererActing = {
13730 current: false
13731};
13732function warnIfNotScopedWithMatchingAct(fiber) {
13733 {
13734 if ( IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
13735 error("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));
13736 }
13737 }
13738}
13739function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
13740 {
13741 if ( (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
13742 error('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));
13743 }
13744 }
13745}
13746
13747function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
13748 {
13749 if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
13750 error('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));
13751 }
13752 }
13753}
13754
13755var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
13756
13757var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
13758// scheduler is the actual recommendation. The alternative could be a testing build,
13759// a new lib, or whatever; we dunno just yet. This message is for early adopters
13760// to get their tests right.
13761
13762function warnIfUnmockedScheduler(fiber) {
13763 {
13764 if (didWarnAboutUnmockedScheduler === false && Scheduler$1.unstable_flushAllWithoutAsserting === undefined) {
13765 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
13766 didWarnAboutUnmockedScheduler = true;
13767
13768 error('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');
13769 }
13770 }
13771 }
13772}
13773
13774function computeThreadID(root, expirationTime) {
13775 // Interaction threads are unique per root and expiration time.
13776 return expirationTime * 1000 + root.interactionThreadID;
13777}
13778
13779function markSpawnedWork(expirationTime) {
13780
13781 if (spawnedWorkDuringRender === null) {
13782 spawnedWorkDuringRender = [expirationTime];
13783 } else {
13784 spawnedWorkDuringRender.push(expirationTime);
13785 }
13786}
13787
13788function scheduleInteractions(root, expirationTime, interactions) {
13789
13790 if (interactions.size > 0) {
13791 var pendingInteractionMap = root.pendingInteractionMap;
13792 var pendingInteractions = pendingInteractionMap.get(expirationTime);
13793
13794 if (pendingInteractions != null) {
13795 interactions.forEach(function (interaction) {
13796 if (!pendingInteractions.has(interaction)) {
13797 // Update the pending async work count for previously unscheduled interaction.
13798 interaction.__count++;
13799 }
13800
13801 pendingInteractions.add(interaction);
13802 });
13803 } else {
13804 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
13805
13806 interactions.forEach(function (interaction) {
13807 interaction.__count++;
13808 });
13809 }
13810
13811 var subscriber = tracing.__subscriberRef.current;
13812
13813 if (subscriber !== null) {
13814 var threadID = computeThreadID(root, expirationTime);
13815 subscriber.onWorkScheduled(interactions, threadID);
13816 }
13817 }
13818}
13819
13820function schedulePendingInteractions(root, expirationTime) {
13821
13822 scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current);
13823}
13824
13825function startWorkOnPendingInteractions(root, expirationTime) {
13826 // we can accurately attribute time spent working on it, And so that cascading
13827 // work triggered during the render phase will be associated with it.
13828
13829
13830 var interactions = new Set();
13831 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
13832 if (scheduledExpirationTime >= expirationTime) {
13833 scheduledInteractions.forEach(function (interaction) {
13834 return interactions.add(interaction);
13835 });
13836 }
13837 }); // Store the current set of interactions on the FiberRoot for a few reasons:
13838 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
13839 // without having to recalculate it. We will also use it in commitWork() to
13840 // pass to any Profiler onRender() hooks. This also provides DevTools with a
13841 // way to access it when the onCommitRoot() hook is called.
13842
13843 root.memoizedInteractions = interactions;
13844
13845 if (interactions.size > 0) {
13846 var subscriber = tracing.__subscriberRef.current;
13847
13848 if (subscriber !== null) {
13849 var threadID = computeThreadID(root, expirationTime);
13850
13851 try {
13852 subscriber.onWorkStarted(interactions, threadID);
13853 } catch (error) {
13854 // If the subscriber throws, rethrow it in a separate task
13855 scheduleCallback(ImmediatePriority, function () {
13856 throw error;
13857 });
13858 }
13859 }
13860 }
13861}
13862
13863function finishPendingInteractions(root, committedExpirationTime) {
13864
13865 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
13866 var subscriber;
13867
13868 try {
13869 subscriber = tracing.__subscriberRef.current;
13870
13871 if (subscriber !== null && root.memoizedInteractions.size > 0) {
13872 var threadID = computeThreadID(root, committedExpirationTime);
13873 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
13874 }
13875 } catch (error) {
13876 // If the subscriber throws, rethrow it in a separate task
13877 scheduleCallback(ImmediatePriority, function () {
13878 throw error;
13879 });
13880 } finally {
13881 // Clear completed interactions from the pending Map.
13882 // Unless the render was suspended or cascading work was scheduled,
13883 // In which case– leave pending interactions until the subsequent render.
13884 var pendingInteractionMap = root.pendingInteractionMap;
13885 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
13886 // Only decrement the pending interaction count if we're done.
13887 // If there's still work at the current priority,
13888 // That indicates that we are waiting for suspense data.
13889 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
13890 pendingInteractionMap.delete(scheduledExpirationTime);
13891 scheduledInteractions.forEach(function (interaction) {
13892 interaction.__count--;
13893
13894 if (subscriber !== null && interaction.__count === 0) {
13895 try {
13896 subscriber.onInteractionScheduledWorkCompleted(interaction);
13897 } catch (error) {
13898 // If the subscriber throws, rethrow it in a separate task
13899 scheduleCallback(ImmediatePriority, function () {
13900 throw error;
13901 });
13902 }
13903 }
13904 });
13905 }
13906 });
13907 }
13908}
13909
13910var onScheduleFiberRoot = null;
13911var onCommitFiberRoot = null;
13912var onCommitFiberUnmount = null;
13913var hasLoggedError = false;
13914var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
13915function injectInternals(internals) {
13916 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
13917 // No DevTools
13918 return false;
13919 }
13920
13921 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
13922
13923 if (hook.isDisabled) {
13924 // This isn't a real property on the hook, but it can be set to opt out
13925 // of DevTools integration and associated warnings and logs.
13926 // https://github.com/facebook/react/issues/3877
13927 return true;
13928 }
13929
13930 if (!hook.supportsFiber) {
13931 {
13932 error('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');
13933 } // DevTools exists, even though it doesn't support Fiber.
13934
13935
13936 return true;
13937 }
13938
13939 try {
13940 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
13941
13942 if (true) {
13943 // Only used by Fast Refresh
13944 if (typeof hook.onScheduleFiberRoot === 'function') {
13945 onScheduleFiberRoot = function (root, children) {
13946 try {
13947 hook.onScheduleFiberRoot(rendererID, root, children);
13948 } catch (err) {
13949 if (true && !hasLoggedError) {
13950 hasLoggedError = true;
13951
13952 error('React instrumentation encountered an error: %s', err);
13953 }
13954 }
13955 };
13956 }
13957 }
13958
13959 onCommitFiberRoot = function (root, expirationTime) {
13960 try {
13961 var didError = (root.current.effectTag & DidCapture) === DidCapture;
13962
13963 if (enableProfilerTimer) {
13964 var currentTime = getCurrentTime();
13965 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
13966 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
13967 } else {
13968 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
13969 }
13970 } catch (err) {
13971 if (true) {
13972 if (!hasLoggedError) {
13973 hasLoggedError = true;
13974
13975 error('React instrumentation encountered an error: %s', err);
13976 }
13977 }
13978 }
13979 };
13980
13981 onCommitFiberUnmount = function (fiber) {
13982 try {
13983 hook.onCommitFiberUnmount(rendererID, fiber);
13984 } catch (err) {
13985 if (true) {
13986 if (!hasLoggedError) {
13987 hasLoggedError = true;
13988
13989 error('React instrumentation encountered an error: %s', err);
13990 }
13991 }
13992 }
13993 };
13994 } catch (err) {
13995 // Catch all errors because it is unsafe to throw during initialization.
13996 {
13997 error('React instrumentation encountered an error: %s.', err);
13998 }
13999 } // DevTools exists
14000
14001
14002 return true;
14003}
14004function onScheduleRoot(root, children) {
14005 if (typeof onScheduleFiberRoot === 'function') {
14006 onScheduleFiberRoot(root, children);
14007 }
14008}
14009function onCommitRoot(root, expirationTime) {
14010 if (typeof onCommitFiberRoot === 'function') {
14011 onCommitFiberRoot(root, expirationTime);
14012 }
14013}
14014function onCommitUnmount(fiber) {
14015 if (typeof onCommitFiberUnmount === 'function') {
14016 onCommitFiberUnmount(fiber);
14017 }
14018}
14019
14020var hasBadMapPolyfill;
14021
14022{
14023 hasBadMapPolyfill = false;
14024
14025 try {
14026 var nonExtensibleObject = Object.preventExtensions({});
14027 var testMap = new Map([[nonExtensibleObject, null]]);
14028 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
14029 // https://github.com/rollup/rollup/issues/1771
14030 // TODO: we can remove these if Rollup fixes the bug.
14031
14032 testMap.set(0, 0);
14033 testSet.add(0);
14034 } catch (e) {
14035 // TODO: Consider warning about bad polyfills
14036 hasBadMapPolyfill = true;
14037 }
14038}
14039
14040var debugCounter = 1;
14041
14042function FiberNode(tag, pendingProps, key, mode) {
14043 // Instance
14044 this.tag = tag;
14045 this.key = key;
14046 this.elementType = null;
14047 this.type = null;
14048 this.stateNode = null; // Fiber
14049
14050 this.return = null;
14051 this.child = null;
14052 this.sibling = null;
14053 this.index = 0;
14054 this.ref = null;
14055 this.pendingProps = pendingProps;
14056 this.memoizedProps = null;
14057 this.updateQueue = null;
14058 this.memoizedState = null;
14059 this.dependencies = null;
14060 this.mode = mode; // Effects
14061
14062 this.effectTag = NoEffect;
14063 this.nextEffect = null;
14064 this.firstEffect = null;
14065 this.lastEffect = null;
14066 this.expirationTime = NoWork;
14067 this.childExpirationTime = NoWork;
14068 this.alternate = null;
14069
14070 {
14071 // Note: The following is done to avoid a v8 performance cliff.
14072 //
14073 // Initializing the fields below to smis and later updating them with
14074 // double values will cause Fibers to end up having separate shapes.
14075 // This behavior/bug has something to do with Object.preventExtension().
14076 // Fortunately this only impacts DEV builds.
14077 // Unfortunately it makes React unusably slow for some applications.
14078 // To work around this, initialize the fields below with doubles.
14079 //
14080 // Learn more about this here:
14081 // https://github.com/facebook/react/issues/14365
14082 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
14083 this.actualDuration = Number.NaN;
14084 this.actualStartTime = Number.NaN;
14085 this.selfBaseDuration = Number.NaN;
14086 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
14087 // This won't trigger the performance cliff mentioned above,
14088 // and it simplifies other profiler code (including DevTools).
14089
14090 this.actualDuration = 0;
14091 this.actualStartTime = -1;
14092 this.selfBaseDuration = 0;
14093 this.treeBaseDuration = 0;
14094 } // This is normally DEV-only except www when it adds listeners.
14095 // TODO: remove the User Timing integration in favor of Root Events.
14096
14097
14098 {
14099 this._debugID = debugCounter++;
14100 this._debugIsCurrentlyTiming = false;
14101 }
14102
14103 {
14104 this._debugSource = null;
14105 this._debugOwner = null;
14106 this._debugNeedsRemount = false;
14107 this._debugHookTypes = null;
14108
14109 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
14110 Object.preventExtensions(this);
14111 }
14112 }
14113} // This is a constructor function, rather than a POJO constructor, still
14114// please ensure we do the following:
14115// 1) Nobody should add any instance methods on this. Instance methods can be
14116// more difficult to predict when they get optimized and they are almost
14117// never inlined properly in static compilers.
14118// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
14119// always know when it is a fiber.
14120// 3) We might want to experiment with using numeric keys since they are easier
14121// to optimize in a non-JIT environment.
14122// 4) We can easily go from a constructor to a createFiber object literal if that
14123// is faster.
14124// 5) It should be easy to port this to a C struct and keep a C implementation
14125// compatible.
14126
14127
14128var createFiber = function (tag, pendingProps, key, mode) {
14129 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
14130 return new FiberNode(tag, pendingProps, key, mode);
14131};
14132
14133function shouldConstruct(Component) {
14134 var prototype = Component.prototype;
14135 return !!(prototype && prototype.isReactComponent);
14136}
14137
14138function isSimpleFunctionComponent(type) {
14139 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
14140}
14141function resolveLazyComponentTag(Component) {
14142 if (typeof Component === 'function') {
14143 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
14144 } else if (Component !== undefined && Component !== null) {
14145 var $$typeof = Component.$$typeof;
14146
14147 if ($$typeof === REACT_FORWARD_REF_TYPE) {
14148 return ForwardRef;
14149 }
14150
14151 if ($$typeof === REACT_MEMO_TYPE) {
14152 return MemoComponent;
14153 }
14154 }
14155
14156 return IndeterminateComponent;
14157} // This is used to create an alternate fiber to do work on.
14158
14159function createWorkInProgress(current, pendingProps) {
14160 var workInProgress = current.alternate;
14161
14162 if (workInProgress === null) {
14163 // We use a double buffering pooling technique because we know that we'll
14164 // only ever need at most two versions of a tree. We pool the "other" unused
14165 // node that we're free to reuse. This is lazily created to avoid allocating
14166 // extra objects for things that are never updated. It also allow us to
14167 // reclaim the extra memory if needed.
14168 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
14169 workInProgress.elementType = current.elementType;
14170 workInProgress.type = current.type;
14171 workInProgress.stateNode = current.stateNode;
14172
14173 {
14174 // DEV-only fields
14175 {
14176 workInProgress._debugID = current._debugID;
14177 }
14178
14179 workInProgress._debugSource = current._debugSource;
14180 workInProgress._debugOwner = current._debugOwner;
14181 workInProgress._debugHookTypes = current._debugHookTypes;
14182 }
14183
14184 workInProgress.alternate = current;
14185 current.alternate = workInProgress;
14186 } else {
14187 workInProgress.pendingProps = pendingProps; // We already have an alternate.
14188 // Reset the effect tag.
14189
14190 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
14191
14192 workInProgress.nextEffect = null;
14193 workInProgress.firstEffect = null;
14194 workInProgress.lastEffect = null;
14195
14196 {
14197 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
14198 // This prevents time from endlessly accumulating in new commits.
14199 // This has the downside of resetting values for different priority renders,
14200 // But works for yielding (the common case) and should support resuming.
14201 workInProgress.actualDuration = 0;
14202 workInProgress.actualStartTime = -1;
14203 }
14204 }
14205
14206 workInProgress.childExpirationTime = current.childExpirationTime;
14207 workInProgress.expirationTime = current.expirationTime;
14208 workInProgress.child = current.child;
14209 workInProgress.memoizedProps = current.memoizedProps;
14210 workInProgress.memoizedState = current.memoizedState;
14211 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14212 // it cannot be shared with the current fiber.
14213
14214 var currentDependencies = current.dependencies;
14215 workInProgress.dependencies = currentDependencies === null ? null : {
14216 expirationTime: currentDependencies.expirationTime,
14217 firstContext: currentDependencies.firstContext,
14218 responders: currentDependencies.responders
14219 }; // These will be overridden during the parent's reconciliation
14220
14221 workInProgress.sibling = current.sibling;
14222 workInProgress.index = current.index;
14223 workInProgress.ref = current.ref;
14224
14225 {
14226 workInProgress.selfBaseDuration = current.selfBaseDuration;
14227 workInProgress.treeBaseDuration = current.treeBaseDuration;
14228 }
14229
14230 {
14231 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
14232
14233 switch (workInProgress.tag) {
14234 case IndeterminateComponent:
14235 case FunctionComponent:
14236 case SimpleMemoComponent:
14237 workInProgress.type = resolveFunctionForHotReloading(current.type);
14238 break;
14239
14240 case ClassComponent:
14241 workInProgress.type = resolveClassForHotReloading(current.type);
14242 break;
14243
14244 case ForwardRef:
14245 workInProgress.type = resolveForwardRefForHotReloading(current.type);
14246 break;
14247 }
14248 }
14249
14250 return workInProgress;
14251} // Used to reuse a Fiber for a second pass.
14252
14253function resetWorkInProgress(workInProgress, renderExpirationTime) {
14254 // This resets the Fiber to what createFiber or createWorkInProgress would
14255 // have set the values to before during the first pass. Ideally this wouldn't
14256 // be necessary but unfortunately many code paths reads from the workInProgress
14257 // when they should be reading from current and writing to workInProgress.
14258 // We assume pendingProps, index, key, ref, return are still untouched to
14259 // avoid doing another reconciliation.
14260 // Reset the effect tag but keep any Placement tags, since that's something
14261 // that child fiber is setting, not the reconciliation.
14262 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
14263
14264 workInProgress.nextEffect = null;
14265 workInProgress.firstEffect = null;
14266 workInProgress.lastEffect = null;
14267 var current = workInProgress.alternate;
14268
14269 if (current === null) {
14270 // Reset to createFiber's initial values.
14271 workInProgress.childExpirationTime = NoWork;
14272 workInProgress.expirationTime = renderExpirationTime;
14273 workInProgress.child = null;
14274 workInProgress.memoizedProps = null;
14275 workInProgress.memoizedState = null;
14276 workInProgress.updateQueue = null;
14277 workInProgress.dependencies = null;
14278
14279 {
14280 // Note: We don't reset the actualTime counts. It's useful to accumulate
14281 // actual time across multiple render passes.
14282 workInProgress.selfBaseDuration = 0;
14283 workInProgress.treeBaseDuration = 0;
14284 }
14285 } else {
14286 // Reset to the cloned values that createWorkInProgress would've.
14287 workInProgress.childExpirationTime = current.childExpirationTime;
14288 workInProgress.expirationTime = current.expirationTime;
14289 workInProgress.child = current.child;
14290 workInProgress.memoizedProps = current.memoizedProps;
14291 workInProgress.memoizedState = current.memoizedState;
14292 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14293 // it cannot be shared with the current fiber.
14294
14295 var currentDependencies = current.dependencies;
14296 workInProgress.dependencies = currentDependencies === null ? null : {
14297 expirationTime: currentDependencies.expirationTime,
14298 firstContext: currentDependencies.firstContext,
14299 responders: currentDependencies.responders
14300 };
14301
14302 {
14303 // Note: We don't reset the actualTime counts. It's useful to accumulate
14304 // actual time across multiple render passes.
14305 workInProgress.selfBaseDuration = current.selfBaseDuration;
14306 workInProgress.treeBaseDuration = current.treeBaseDuration;
14307 }
14308 }
14309
14310 return workInProgress;
14311}
14312function createHostRootFiber(tag) {
14313 var mode;
14314
14315 if (tag === ConcurrentRoot) {
14316 mode = ConcurrentMode | BlockingMode | StrictMode;
14317 } else if (tag === BlockingRoot) {
14318 mode = BlockingMode | StrictMode;
14319 } else {
14320 mode = NoMode;
14321 }
14322
14323 if ( isDevToolsPresent) {
14324 // Always collect profile timings when DevTools are present.
14325 // This enables DevTools to start capturing timing at any point–
14326 // Without some nodes in the tree having empty base times.
14327 mode |= ProfileMode;
14328 }
14329
14330 return createFiber(HostRoot, null, null, mode);
14331}
14332function createFiberFromTypeAndProps(type, // React$ElementType
14333key, pendingProps, owner, mode, expirationTime) {
14334 var fiber;
14335 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
14336
14337 var resolvedType = type;
14338
14339 if (typeof type === 'function') {
14340 if (shouldConstruct(type)) {
14341 fiberTag = ClassComponent;
14342
14343 {
14344 resolvedType = resolveClassForHotReloading(resolvedType);
14345 }
14346 } else {
14347 {
14348 resolvedType = resolveFunctionForHotReloading(resolvedType);
14349 }
14350 }
14351 } else if (typeof type === 'string') {
14352 fiberTag = HostComponent;
14353 } else {
14354 getTag: switch (type) {
14355 case REACT_FRAGMENT_TYPE:
14356 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
14357
14358 case REACT_CONCURRENT_MODE_TYPE:
14359 fiberTag = Mode;
14360 mode |= ConcurrentMode | BlockingMode | StrictMode;
14361 break;
14362
14363 case REACT_STRICT_MODE_TYPE:
14364 fiberTag = Mode;
14365 mode |= StrictMode;
14366 break;
14367
14368 case REACT_PROFILER_TYPE:
14369 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
14370
14371 case REACT_SUSPENSE_TYPE:
14372 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
14373
14374 case REACT_SUSPENSE_LIST_TYPE:
14375 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
14376
14377 default:
14378 {
14379 if (typeof type === 'object' && type !== null) {
14380 switch (type.$$typeof) {
14381 case REACT_PROVIDER_TYPE:
14382 fiberTag = ContextProvider;
14383 break getTag;
14384
14385 case REACT_CONTEXT_TYPE:
14386 // This is a consumer
14387 fiberTag = ContextConsumer;
14388 break getTag;
14389
14390 case REACT_FORWARD_REF_TYPE:
14391 fiberTag = ForwardRef;
14392
14393 {
14394 resolvedType = resolveForwardRefForHotReloading(resolvedType);
14395 }
14396
14397 break getTag;
14398
14399 case REACT_MEMO_TYPE:
14400 fiberTag = MemoComponent;
14401 break getTag;
14402
14403 case REACT_LAZY_TYPE:
14404 fiberTag = LazyComponent;
14405 resolvedType = null;
14406 break getTag;
14407
14408 case REACT_BLOCK_TYPE:
14409 fiberTag = Block;
14410 break getTag;
14411
14412 }
14413 }
14414
14415 var info = '';
14416
14417 {
14418 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
14419 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.';
14420 }
14421
14422 var ownerName = owner ? getComponentName(owner.type) : null;
14423
14424 if (ownerName) {
14425 info += '\n\nCheck the render method of `' + ownerName + '`.';
14426 }
14427 }
14428
14429 {
14430 {
14431 throw 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 );
14432 }
14433 }
14434 }
14435 }
14436 }
14437
14438 fiber = createFiber(fiberTag, pendingProps, key, mode);
14439 fiber.elementType = type;
14440 fiber.type = resolvedType;
14441 fiber.expirationTime = expirationTime;
14442 return fiber;
14443}
14444function createFiberFromElement(element, mode, expirationTime) {
14445 var owner = null;
14446
14447 {
14448 owner = element._owner;
14449 }
14450
14451 var type = element.type;
14452 var key = element.key;
14453 var pendingProps = element.props;
14454 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
14455
14456 {
14457 fiber._debugSource = element._source;
14458 fiber._debugOwner = element._owner;
14459 }
14460
14461 return fiber;
14462}
14463function createFiberFromFragment(elements, mode, expirationTime, key) {
14464 var fiber = createFiber(Fragment, elements, key, mode);
14465 fiber.expirationTime = expirationTime;
14466 return fiber;
14467}
14468
14469function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
14470 {
14471 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
14472 error('Profiler must specify an "id" string and "onRender" function as props');
14473 }
14474 }
14475
14476 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
14477
14478 fiber.elementType = REACT_PROFILER_TYPE;
14479 fiber.type = REACT_PROFILER_TYPE;
14480 fiber.expirationTime = expirationTime;
14481 return fiber;
14482}
14483
14484function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
14485 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
14486 // This needs to be fixed in getComponentName so that it relies on the tag
14487 // instead.
14488
14489 fiber.type = REACT_SUSPENSE_TYPE;
14490 fiber.elementType = REACT_SUSPENSE_TYPE;
14491 fiber.expirationTime = expirationTime;
14492 return fiber;
14493}
14494function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
14495 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
14496
14497 {
14498 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
14499 // This needs to be fixed in getComponentName so that it relies on the tag
14500 // instead.
14501 fiber.type = REACT_SUSPENSE_LIST_TYPE;
14502 }
14503
14504 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
14505 fiber.expirationTime = expirationTime;
14506 return fiber;
14507}
14508function createFiberFromText(content, mode, expirationTime) {
14509 var fiber = createFiber(HostText, content, null, mode);
14510 fiber.expirationTime = expirationTime;
14511 return fiber;
14512}
14513function createFiberFromPortal(portal, mode, expirationTime) {
14514 var pendingProps = portal.children !== null ? portal.children : [];
14515 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
14516 fiber.expirationTime = expirationTime;
14517 fiber.stateNode = {
14518 containerInfo: portal.containerInfo,
14519 pendingChildren: null,
14520 // Used by persistent updates
14521 implementation: portal.implementation
14522 };
14523 return fiber;
14524} // Used for stashing WIP properties to replay failed work in DEV.
14525
14526function FiberRootNode(containerInfo, tag, hydrate) {
14527 this.tag = tag;
14528 this.current = null;
14529 this.containerInfo = containerInfo;
14530 this.pendingChildren = null;
14531 this.pingCache = null;
14532 this.finishedExpirationTime = NoWork;
14533 this.finishedWork = null;
14534 this.timeoutHandle = noTimeout;
14535 this.context = null;
14536 this.pendingContext = null;
14537 this.hydrate = hydrate;
14538 this.callbackNode = null;
14539 this.callbackPriority = NoPriority;
14540 this.firstPendingTime = NoWork;
14541 this.firstSuspendedTime = NoWork;
14542 this.lastSuspendedTime = NoWork;
14543 this.nextKnownPendingLevel = NoWork;
14544 this.lastPingedTime = NoWork;
14545 this.lastExpiredTime = NoWork;
14546
14547 {
14548 this.interactionThreadID = tracing.unstable_getThreadID();
14549 this.memoizedInteractions = new Set();
14550 this.pendingInteractionMap = new Map();
14551 }
14552}
14553
14554function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
14555 var root = new FiberRootNode(containerInfo, tag, hydrate);
14556 // stateNode is any.
14557
14558
14559 var uninitializedFiber = createHostRootFiber(tag);
14560 root.current = uninitializedFiber;
14561 uninitializedFiber.stateNode = root;
14562 initializeUpdateQueue(uninitializedFiber);
14563 return root;
14564}
14565function isRootSuspendedAtTime(root, expirationTime) {
14566 var firstSuspendedTime = root.firstSuspendedTime;
14567 var lastSuspendedTime = root.lastSuspendedTime;
14568 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
14569}
14570function markRootSuspendedAtTime(root, expirationTime) {
14571 var firstSuspendedTime = root.firstSuspendedTime;
14572 var lastSuspendedTime = root.lastSuspendedTime;
14573
14574 if (firstSuspendedTime < expirationTime) {
14575 root.firstSuspendedTime = expirationTime;
14576 }
14577
14578 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
14579 root.lastSuspendedTime = expirationTime;
14580 }
14581
14582 if (expirationTime <= root.lastPingedTime) {
14583 root.lastPingedTime = NoWork;
14584 }
14585
14586 if (expirationTime <= root.lastExpiredTime) {
14587 root.lastExpiredTime = NoWork;
14588 }
14589}
14590function markRootUpdatedAtTime(root, expirationTime) {
14591 // Update the range of pending times
14592 var firstPendingTime = root.firstPendingTime;
14593
14594 if (expirationTime > firstPendingTime) {
14595 root.firstPendingTime = expirationTime;
14596 } // Update the range of suspended times. Treat everything lower priority or
14597 // equal to this update as unsuspended.
14598
14599
14600 var firstSuspendedTime = root.firstSuspendedTime;
14601
14602 if (firstSuspendedTime !== NoWork) {
14603 if (expirationTime >= firstSuspendedTime) {
14604 // The entire suspended range is now unsuspended.
14605 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
14606 } else if (expirationTime >= root.lastSuspendedTime) {
14607 root.lastSuspendedTime = expirationTime + 1;
14608 } // This is a pending level. Check if it's higher priority than the next
14609 // known pending level.
14610
14611
14612 if (expirationTime > root.nextKnownPendingLevel) {
14613 root.nextKnownPendingLevel = expirationTime;
14614 }
14615 }
14616}
14617function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
14618 // Update the range of pending times
14619 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
14620 // equal to this update as unsuspended.
14621
14622 if (finishedExpirationTime <= root.lastSuspendedTime) {
14623 // The entire suspended range is now unsuspended.
14624 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
14625 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
14626 // Part of the suspended range is now unsuspended. Narrow the range to
14627 // include everything between the unsuspended time (non-inclusive) and the
14628 // last suspended time.
14629 root.firstSuspendedTime = finishedExpirationTime - 1;
14630 }
14631
14632 if (finishedExpirationTime <= root.lastPingedTime) {
14633 // Clear the pinged time
14634 root.lastPingedTime = NoWork;
14635 }
14636
14637 if (finishedExpirationTime <= root.lastExpiredTime) {
14638 // Clear the expired time
14639 root.lastExpiredTime = NoWork;
14640 }
14641}
14642function markRootExpiredAtTime(root, expirationTime) {
14643 var lastExpiredTime = root.lastExpiredTime;
14644
14645 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
14646 root.lastExpiredTime = expirationTime;
14647 }
14648}
14649
14650var didWarnAboutMessageChannel = false;
14651var enqueueTaskImpl = null;
14652function enqueueTask(task) {
14653 if (enqueueTaskImpl === null) {
14654 try {
14655 // read require off the module object to get around the bundlers.
14656 // we don't want them to detect a require and bundle a Node polyfill.
14657 var requireString = ('require' + Math.random()).slice(0, 7);
14658 var nodeRequire = module && module[requireString]; // assuming we're in node, let's try to get node's
14659 // version of setImmediate, bypassing fake timers if any.
14660
14661 enqueueTaskImpl = nodeRequire('timers').setImmediate;
14662 } catch (_err) {
14663 // we're in a browser
14664 // we can't use regular timers because they may still be faked
14665 // so we try MessageChannel+postMessage instead
14666 enqueueTaskImpl = function (callback) {
14667 {
14668 if (didWarnAboutMessageChannel === false) {
14669 didWarnAboutMessageChannel = true;
14670
14671 if (typeof MessageChannel === 'undefined') {
14672 error('This browser does not have a MessageChannel implementation, ' + 'so enqueuing tasks via await act(async () => ...) will fail. ' + 'Please file an issue at https://github.com/facebook/react/issues ' + 'if you encounter this warning.');
14673 }
14674 }
14675 }
14676
14677 var channel = new MessageChannel();
14678 channel.port1.onmessage = callback;
14679 channel.port2.postMessage(undefined);
14680 };
14681 }
14682 }
14683
14684 return enqueueTaskImpl(task);
14685}
14686
14687var didWarnAboutNestedUpdates;
14688
14689{
14690 didWarnAboutNestedUpdates = false;
14691}
14692
14693function getContextForSubtree(parentComponent) {
14694 if (!parentComponent) {
14695 return emptyContextObject;
14696 }
14697
14698 var fiber = get(parentComponent);
14699 var parentContext = findCurrentUnmaskedContext(fiber);
14700
14701 if (fiber.tag === ClassComponent) {
14702 var Component = fiber.type;
14703
14704 if (isContextProvider(Component)) {
14705 return processChildContext(fiber, Component, parentContext);
14706 }
14707 }
14708
14709 return parentContext;
14710}
14711
14712function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
14713 return createFiberRoot(containerInfo, tag, hydrate);
14714}
14715function updateContainer(element, container, parentComponent, callback) {
14716 {
14717 onScheduleRoot(container, element);
14718 }
14719
14720 var current$1 = container.current;
14721 var currentTime = requestCurrentTimeForUpdate();
14722
14723 {
14724 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
14725 if ('undefined' !== typeof jest) {
14726 warnIfUnmockedScheduler(current$1);
14727 warnIfNotScopedWithMatchingAct(current$1);
14728 }
14729 }
14730
14731 var suspenseConfig = requestCurrentSuspenseConfig();
14732 var expirationTime = computeExpirationForFiber(currentTime, current$1, suspenseConfig);
14733 var context = getContextForSubtree(parentComponent);
14734
14735 if (container.context === null) {
14736 container.context = context;
14737 } else {
14738 container.pendingContext = context;
14739 }
14740
14741 {
14742 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
14743 didWarnAboutNestedUpdates = true;
14744
14745 error('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.type) || 'Unknown');
14746 }
14747 }
14748
14749 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
14750 // being called "element".
14751
14752 update.payload = {
14753 element: element
14754 };
14755 callback = callback === undefined ? null : callback;
14756
14757 if (callback !== null) {
14758 {
14759 if (typeof callback !== 'function') {
14760 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
14761 }
14762 }
14763
14764 update.callback = callback;
14765 }
14766
14767 enqueueUpdate(current$1, update);
14768 scheduleWork(current$1, expirationTime);
14769 return expirationTime;
14770}
14771function getPublicRootInstance(container) {
14772 var containerFiber = container.current;
14773
14774 if (!containerFiber.child) {
14775 return null;
14776 }
14777
14778 switch (containerFiber.child.tag) {
14779 case HostComponent:
14780 return getPublicInstance(containerFiber.child.stateNode);
14781
14782 default:
14783 return containerFiber.child.stateNode;
14784 }
14785}
14786
14787var shouldSuspendImpl = function (fiber) {
14788 return false;
14789};
14790
14791function shouldSuspend(fiber) {
14792 return shouldSuspendImpl(fiber);
14793}
14794var overrideHookState = null;
14795var overrideProps = null;
14796var scheduleUpdate = null;
14797var setSuspenseHandler = null;
14798
14799{
14800 var copyWithSetImpl = function (obj, path, idx, value) {
14801 if (idx >= path.length) {
14802 return value;
14803 }
14804
14805 var key = path[idx];
14806 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
14807
14808 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
14809 return updated;
14810 };
14811
14812 var copyWithSet = function (obj, path, value) {
14813 return copyWithSetImpl(obj, path, 0, value);
14814 }; // Support DevTools editable values for useState and useReducer.
14815
14816
14817 overrideHookState = function (fiber, id, path, value) {
14818 // For now, the "id" of stateful hooks is just the stateful hook index.
14819 // This may change in the future with e.g. nested hooks.
14820 var currentHook = fiber.memoizedState;
14821
14822 while (currentHook !== null && id > 0) {
14823 currentHook = currentHook.next;
14824 id--;
14825 }
14826
14827 if (currentHook !== null) {
14828 var newState = copyWithSet(currentHook.memoizedState, path, value);
14829 currentHook.memoizedState = newState;
14830 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
14831 // because there is no update we can add for useReducer hooks that won't trigger an error.
14832 // (There's no appropriate action type for DevTools overrides.)
14833 // As a result though, React will see the scheduled update as a noop and bailout.
14834 // Shallow cloning props works as a workaround for now to bypass the bailout check.
14835
14836 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
14837 scheduleWork(fiber, Sync);
14838 }
14839 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
14840
14841
14842 overrideProps = function (fiber, path, value) {
14843 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
14844
14845 if (fiber.alternate) {
14846 fiber.alternate.pendingProps = fiber.pendingProps;
14847 }
14848
14849 scheduleWork(fiber, Sync);
14850 };
14851
14852 scheduleUpdate = function (fiber) {
14853 scheduleWork(fiber, Sync);
14854 };
14855
14856 setSuspenseHandler = function (newShouldSuspendImpl) {
14857 shouldSuspendImpl = newShouldSuspendImpl;
14858 };
14859}
14860
14861function injectIntoDevTools(devToolsConfig) {
14862 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
14863 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
14864 return injectInternals(_assign({}, devToolsConfig, {
14865 overrideHookState: overrideHookState,
14866 overrideProps: overrideProps,
14867 setSuspenseHandler: setSuspenseHandler,
14868 scheduleUpdate: scheduleUpdate,
14869 currentDispatcherRef: ReactCurrentDispatcher,
14870 findHostInstanceByFiber: function (fiber) {
14871 var hostFiber = findCurrentHostFiber(fiber);
14872
14873 if (hostFiber === null) {
14874 return null;
14875 }
14876
14877 return hostFiber.stateNode;
14878 },
14879 findFiberByHostInstance: function (instance) {
14880 if (!findFiberByHostInstance) {
14881 // Might not be implemented by the renderer.
14882 return null;
14883 }
14884
14885 return findFiberByHostInstance(instance);
14886 },
14887 // React Refresh
14888 findHostInstancesForRefresh: findHostInstancesForRefresh ,
14889 scheduleRefresh: scheduleRefresh ,
14890 scheduleRoot: scheduleRoot ,
14891 setRefreshHandler: setRefreshHandler ,
14892 // Enables DevTools to append owner stacks to error messages in DEV mode.
14893 getCurrentFiber: function () {
14894 return current;
14895 }
14896 }));
14897}
14898var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
14899var isSchedulerMocked = typeof Scheduler$1.unstable_flushAllWithoutAsserting === 'function';
14900
14901var flushWork = Scheduler$1.unstable_flushAllWithoutAsserting || function () {
14902 var didFlushWork = false;
14903
14904 while (flushPassiveEffects()) {
14905 didFlushWork = true;
14906 }
14907
14908 return didFlushWork;
14909};
14910
14911function flushWorkAndMicroTasks(onDone) {
14912 try {
14913 flushWork();
14914 enqueueTask(function () {
14915 if (flushWork()) {
14916 flushWorkAndMicroTasks(onDone);
14917 } else {
14918 onDone();
14919 }
14920 });
14921 } catch (err) {
14922 onDone(err);
14923 }
14924} // we track the 'depth' of the act() calls with this counter,
14925// so we can tell if any async act() calls try to run in parallel.
14926
14927
14928var actingUpdatesScopeDepth = 0;
14929
14930function act(callback) {
14931
14932 var previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
14933 var previousIsSomeRendererActing;
14934 var previousIsThisRendererActing;
14935 actingUpdatesScopeDepth++;
14936 previousIsSomeRendererActing = IsSomeRendererActing$1.current;
14937 previousIsThisRendererActing = IsThisRendererActing.current;
14938 IsSomeRendererActing$1.current = true;
14939 IsThisRendererActing.current = true;
14940
14941 function onDone() {
14942 actingUpdatesScopeDepth--;
14943 IsSomeRendererActing$1.current = previousIsSomeRendererActing;
14944 IsThisRendererActing.current = previousIsThisRendererActing;
14945
14946 {
14947 if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
14948 // if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
14949 error('You seem to have overlapping act() calls, this is not supported. ' + 'Be sure to await previous act() calls before making a new one. ');
14950 }
14951 }
14952 }
14953
14954 var result;
14955
14956 try {
14957 result = batchedUpdates(callback);
14958 } catch (error) {
14959 // on sync errors, we still want to 'cleanup' and decrement actingUpdatesScopeDepth
14960 onDone();
14961 throw error;
14962 }
14963
14964 if (result !== null && typeof result === 'object' && typeof result.then === 'function') {
14965 // setup a boolean that gets set to true only
14966 // once this act() call is await-ed
14967 var called = false;
14968
14969 {
14970 if (typeof Promise !== 'undefined') {
14971 //eslint-disable-next-line no-undef
14972 Promise.resolve().then(function () {}).then(function () {
14973 if (called === false) {
14974 error('You called act(async () => ...) without await. ' + 'This could lead to unexpected testing behaviour, interleaving multiple act ' + 'calls and mixing their scopes. You should - await act(async () => ...);');
14975 }
14976 });
14977 }
14978 } // in the async case, the returned thenable runs the callback, flushes
14979 // effects and microtasks in a loop until flushPassiveEffects() === false,
14980 // and cleans up
14981
14982
14983 return {
14984 then: function (resolve, reject) {
14985 called = true;
14986 result.then(function () {
14987 if (actingUpdatesScopeDepth > 1 || isSchedulerMocked === true && previousIsSomeRendererActing === true) {
14988 onDone();
14989 resolve();
14990 return;
14991 } // we're about to exit the act() scope,
14992 // now's the time to flush tasks/effects
14993
14994
14995 flushWorkAndMicroTasks(function (err) {
14996 onDone();
14997
14998 if (err) {
14999 reject(err);
15000 } else {
15001 resolve();
15002 }
15003 });
15004 }, function (err) {
15005 onDone();
15006 reject(err);
15007 });
15008 }
15009 };
15010 } else {
15011 {
15012 if (result !== undefined) {
15013 error('The callback passed to act(...) function ' + 'must return undefined, or a Promise. You returned %s', result);
15014 }
15015 } // flush effects until none remain, and cleanup
15016
15017
15018 try {
15019 if (actingUpdatesScopeDepth === 1 && (isSchedulerMocked === false || previousIsSomeRendererActing === false)) {
15020 // we're about to exit the act() scope,
15021 // now's the time to flush effects
15022 flushWork();
15023 }
15024
15025 onDone();
15026 } catch (err) {
15027 onDone();
15028 throw err;
15029 } // in the sync case, the returned thenable only warns *if* await-ed
15030
15031
15032 return {
15033 then: function (resolve) {
15034 {
15035 error('Do not await the result of calling act(...) with sync logic, it is not a Promise.');
15036 }
15037
15038 resolve();
15039 }
15040 };
15041 }
15042}
15043
15044var ReactVersion = '16.13.0';
15045
15046var defaultTestOptions = {
15047 createNodeMock: function () {
15048 return null;
15049 }
15050};
15051
15052function toJSON(inst) {
15053 if (inst.isHidden) {
15054 // Omit timed out children from output entirely. This seems like the least
15055 // surprising behavior. We could perhaps add a separate API that includes
15056 // them, if it turns out people need it.
15057 return null;
15058 }
15059
15060 switch (inst.tag) {
15061 case 'TEXT':
15062 return inst.text;
15063
15064 case 'INSTANCE':
15065 {
15066 /* eslint-disable no-unused-vars */
15067 // We don't include the `children` prop in JSON.
15068 // Instead, we will include the actual rendered children.
15069 var _inst$props = inst.props,
15070 children = _inst$props.children,
15071 props = _objectWithoutPropertiesLoose(_inst$props, ["children"]);
15072 /* eslint-enable */
15073
15074
15075 var renderedChildren = null;
15076
15077 if (inst.children && inst.children.length) {
15078 for (var i = 0; i < inst.children.length; i++) {
15079 var renderedChild = toJSON(inst.children[i]);
15080
15081 if (renderedChild !== null) {
15082 if (renderedChildren === null) {
15083 renderedChildren = [renderedChild];
15084 } else {
15085 renderedChildren.push(renderedChild);
15086 }
15087 }
15088 }
15089 }
15090
15091 var json = {
15092 type: inst.type,
15093 props: props,
15094 children: renderedChildren
15095 };
15096 Object.defineProperty(json, '$$typeof', {
15097 value: Symbol.for('react.test.json')
15098 });
15099 return json;
15100 }
15101
15102 default:
15103 throw new Error("Unexpected node type in toJSON: " + inst.tag);
15104 }
15105}
15106
15107function childrenToTree(node) {
15108 if (!node) {
15109 return null;
15110 }
15111
15112 var children = nodeAndSiblingsArray(node);
15113
15114 if (children.length === 0) {
15115 return null;
15116 } else if (children.length === 1) {
15117 return toTree(children[0]);
15118 }
15119
15120 return flatten(children.map(toTree));
15121}
15122
15123function nodeAndSiblingsArray(nodeWithSibling) {
15124 var array = [];
15125 var node = nodeWithSibling;
15126
15127 while (node != null) {
15128 array.push(node);
15129 node = node.sibling;
15130 }
15131
15132 return array;
15133}
15134
15135function flatten(arr) {
15136 var result = [];
15137 var stack = [{
15138 i: 0,
15139 array: arr
15140 }];
15141
15142 while (stack.length) {
15143 var n = stack.pop();
15144
15145 while (n.i < n.array.length) {
15146 var el = n.array[n.i];
15147 n.i += 1;
15148
15149 if (Array.isArray(el)) {
15150 stack.push(n);
15151 stack.push({
15152 i: 0,
15153 array: el
15154 });
15155 break;
15156 }
15157
15158 result.push(el);
15159 }
15160 }
15161
15162 return result;
15163}
15164
15165function toTree(node) {
15166 if (node == null) {
15167 return null;
15168 }
15169
15170 switch (node.tag) {
15171 case HostRoot:
15172 return childrenToTree(node.child);
15173
15174 case HostPortal:
15175 return childrenToTree(node.child);
15176
15177 case ClassComponent:
15178 return {
15179 nodeType: 'component',
15180 type: node.type,
15181 props: _assign({}, node.memoizedProps),
15182 instance: node.stateNode,
15183 rendered: childrenToTree(node.child)
15184 };
15185
15186 case FunctionComponent:
15187 case SimpleMemoComponent:
15188 return {
15189 nodeType: 'component',
15190 type: node.type,
15191 props: _assign({}, node.memoizedProps),
15192 instance: null,
15193 rendered: childrenToTree(node.child)
15194 };
15195
15196 case Block:
15197 return {
15198 nodeType: 'block',
15199 type: node.type,
15200 props: _assign({}, node.memoizedProps),
15201 instance: null,
15202 rendered: childrenToTree(node.child)
15203 };
15204
15205 case HostComponent:
15206 {
15207 return {
15208 nodeType: 'host',
15209 type: node.type,
15210 props: _assign({}, node.memoizedProps),
15211 instance: null,
15212 // TODO: use createNodeMock here somehow?
15213 rendered: flatten(nodeAndSiblingsArray(node.child).map(toTree))
15214 };
15215 }
15216
15217 case HostText:
15218 return node.stateNode.text;
15219
15220 case Fragment:
15221 case ContextProvider:
15222 case ContextConsumer:
15223 case Mode:
15224 case Profiler:
15225 case ForwardRef:
15226 case MemoComponent:
15227 case IncompleteClassComponent:
15228 case ScopeComponent:
15229 return childrenToTree(node.child);
15230
15231 default:
15232 {
15233 {
15234 throw Error( "toTree() does not yet know how to handle nodes with tag=" + node.tag );
15235 }
15236 }
15237
15238 }
15239}
15240
15241var validWrapperTypes = new Set([FunctionComponent, ClassComponent, HostComponent, ForwardRef, MemoComponent, SimpleMemoComponent, Block, // Normally skipped, but used when there's more than one root child.
15242HostRoot]);
15243
15244function getChildren(parent) {
15245 var children = [];
15246 var startingNode = parent;
15247 var node = startingNode;
15248
15249 if (node.child === null) {
15250 return children;
15251 }
15252
15253 node.child.return = node;
15254 node = node.child;
15255
15256 outer: while (true) {
15257 var descend = false;
15258
15259 if (validWrapperTypes.has(node.tag)) {
15260 children.push(wrapFiber(node));
15261 } else if (node.tag === HostText) {
15262 children.push('' + node.memoizedProps);
15263 } else {
15264 descend = true;
15265 }
15266
15267 if (descend && node.child !== null) {
15268 node.child.return = node;
15269 node = node.child;
15270 continue;
15271 }
15272
15273 while (node.sibling === null) {
15274 if (node.return === startingNode) {
15275 break outer;
15276 }
15277
15278 node = node.return;
15279 }
15280
15281 node.sibling.return = node.return;
15282 node = node.sibling;
15283 }
15284
15285 return children;
15286}
15287
15288var ReactTestInstance =
15289/*#__PURE__*/
15290function () {
15291 var _proto = ReactTestInstance.prototype;
15292
15293 _proto._currentFiber = function _currentFiber() {
15294 // Throws if this component has been unmounted.
15295 var fiber = findCurrentFiberUsingSlowPath(this._fiber);
15296
15297 if (!(fiber !== null)) {
15298 {
15299 throw Error( "Can't read from currently-mounting component. This error is likely caused by a bug in React. Please file an issue." );
15300 }
15301 }
15302
15303 return fiber;
15304 };
15305
15306 function ReactTestInstance(fiber) {
15307 if (!validWrapperTypes.has(fiber.tag)) {
15308 {
15309 throw Error( "Unexpected object passed to ReactTestInstance constructor (tag: " + fiber.tag + "). This is probably a bug in React." );
15310 }
15311 }
15312
15313 this._fiber = fiber;
15314 }
15315
15316 // Custom search functions
15317 _proto.find = function find(predicate) {
15318 return expectOne(this.findAll(predicate, {
15319 deep: false
15320 }), "matching custom predicate: " + predicate.toString());
15321 };
15322
15323 _proto.findByType = function findByType(type) {
15324 return expectOne(this.findAllByType(type, {
15325 deep: false
15326 }), "with node type: \"" + (type.displayName || type.name) + "\"");
15327 };
15328
15329 _proto.findByProps = function findByProps(props) {
15330 return expectOne(this.findAllByProps(props, {
15331 deep: false
15332 }), "with props: " + JSON.stringify(props));
15333 };
15334
15335 _proto.findAll = function findAll(predicate) {
15336 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15337 return _findAll(this, predicate, options);
15338 };
15339
15340 _proto.findAllByType = function findAllByType(type) {
15341 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15342 return _findAll(this, function (node) {
15343 return node.type === type;
15344 }, options);
15345 };
15346
15347 _proto.findAllByProps = function findAllByProps(props) {
15348 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15349 return _findAll(this, function (node) {
15350 return node.props && propsMatch(node.props, props);
15351 }, options);
15352 };
15353
15354 _createClass(ReactTestInstance, [{
15355 key: "instance",
15356 get: function () {
15357 if (this._fiber.tag === HostComponent) {
15358 return getPublicInstance(this._fiber.stateNode);
15359 } else {
15360 return this._fiber.stateNode;
15361 }
15362 }
15363 }, {
15364 key: "type",
15365 get: function () {
15366 return this._fiber.type;
15367 }
15368 }, {
15369 key: "props",
15370 get: function () {
15371 return this._currentFiber().memoizedProps;
15372 }
15373 }, {
15374 key: "parent",
15375 get: function () {
15376 var parent = this._fiber.return;
15377
15378 while (parent !== null) {
15379 if (validWrapperTypes.has(parent.tag)) {
15380 if (parent.tag === HostRoot) {
15381 // Special case: we only "materialize" instances for roots
15382 // if they have more than a single child. So we'll check that now.
15383 if (getChildren(parent).length < 2) {
15384 return null;
15385 }
15386 }
15387
15388 return wrapFiber(parent);
15389 }
15390
15391 parent = parent.return;
15392 }
15393
15394 return null;
15395 }
15396 }, {
15397 key: "children",
15398 get: function () {
15399 return getChildren(this._currentFiber());
15400 }
15401 }]);
15402
15403 return ReactTestInstance;
15404}();
15405
15406function _findAll(root, predicate, options) {
15407 var deep = options ? options.deep : true;
15408 var results = [];
15409
15410 if (predicate(root)) {
15411 results.push(root);
15412
15413 if (!deep) {
15414 return results;
15415 }
15416 }
15417
15418 root.children.forEach(function (child) {
15419 if (typeof child === 'string') {
15420 return;
15421 }
15422
15423 results.push.apply(results, _findAll(child, predicate, options));
15424 });
15425 return results;
15426}
15427
15428function expectOne(all, message) {
15429 if (all.length === 1) {
15430 return all[0];
15431 }
15432
15433 var prefix = all.length === 0 ? 'No instances found ' : "Expected 1 but found " + all.length + " instances ";
15434 throw new Error(prefix + message);
15435}
15436
15437function propsMatch(props, filter) {
15438 for (var key in filter) {
15439 if (props[key] !== filter[key]) {
15440 return false;
15441 }
15442 }
15443
15444 return true;
15445}
15446
15447var ReactTestRendererFiber = {
15448 _Scheduler: Scheduler,
15449 create: function (element, options) {
15450 var createNodeMock = defaultTestOptions.createNodeMock;
15451 var isConcurrent = false;
15452
15453 if (typeof options === 'object' && options !== null) {
15454 if (typeof options.createNodeMock === 'function') {
15455 createNodeMock = options.createNodeMock;
15456 }
15457
15458 if (options.unstable_isConcurrent === true) {
15459 isConcurrent = true;
15460 }
15461 }
15462
15463 var container = {
15464 children: [],
15465 createNodeMock: createNodeMock,
15466 tag: 'CONTAINER'
15467 };
15468 var root = createContainer(container, isConcurrent ? ConcurrentRoot : LegacyRoot, false);
15469
15470 if (!(root != null)) {
15471 {
15472 throw Error( "something went wrong" );
15473 }
15474 }
15475
15476 updateContainer(element, root, null, null);
15477 var entry = {
15478 _Scheduler: Scheduler,
15479 root: undefined,
15480 // makes flow happy
15481 // we define a 'getter' for 'root' below using 'Object.defineProperty'
15482 toJSON: function () {
15483 if (root == null || root.current == null || container == null) {
15484 return null;
15485 }
15486
15487 if (container.children.length === 0) {
15488 return null;
15489 }
15490
15491 if (container.children.length === 1) {
15492 return toJSON(container.children[0]);
15493 }
15494
15495 if (container.children.length === 2 && container.children[0].isHidden === true && container.children[1].isHidden === false) {
15496 // Omit timed out children from output entirely, including the fact that we
15497 // temporarily wrap fallback and timed out children in an array.
15498 return toJSON(container.children[1]);
15499 }
15500
15501 var renderedChildren = null;
15502
15503 if (container.children && container.children.length) {
15504 for (var i = 0; i < container.children.length; i++) {
15505 var renderedChild = toJSON(container.children[i]);
15506
15507 if (renderedChild !== null) {
15508 if (renderedChildren === null) {
15509 renderedChildren = [renderedChild];
15510 } else {
15511 renderedChildren.push(renderedChild);
15512 }
15513 }
15514 }
15515 }
15516
15517 return renderedChildren;
15518 },
15519 toTree: function () {
15520 if (root == null || root.current == null) {
15521 return null;
15522 }
15523
15524 return toTree(root.current);
15525 },
15526 update: function (newElement) {
15527 if (root == null || root.current == null) {
15528 return;
15529 }
15530
15531 updateContainer(newElement, root, null, null);
15532 },
15533 unmount: function () {
15534 if (root == null || root.current == null) {
15535 return;
15536 }
15537
15538 updateContainer(null, root, null, null);
15539 container = null;
15540 root = null;
15541 },
15542 getInstance: function () {
15543 if (root == null || root.current == null) {
15544 return null;
15545 }
15546
15547 return getPublicRootInstance(root);
15548 },
15549 unstable_flushSync: function (fn) {
15550 return flushSync(fn);
15551 }
15552 };
15553 Object.defineProperty(entry, 'root', {
15554 configurable: true,
15555 enumerable: true,
15556 get: function () {
15557 if (root === null) {
15558 throw new Error("Can't access .root on unmounted test renderer");
15559 }
15560
15561 var children = getChildren(root.current);
15562
15563 if (children.length === 0) {
15564 throw new Error("Can't access .root on unmounted test renderer");
15565 } else if (children.length === 1) {
15566 // Normally, we skip the root and just give you the child.
15567 return children[0];
15568 } else {
15569 // However, we give you the root if there's more than one root child.
15570 // We could make this the behavior for all cases but it would be a breaking change.
15571 return wrapFiber(root.current);
15572 }
15573 }
15574 });
15575 return entry;
15576 },
15577
15578 /* eslint-disable-next-line camelcase */
15579 unstable_batchedUpdates: batchedUpdates,
15580 act: act
15581};
15582var fiberToWrapper = new WeakMap();
15583
15584function wrapFiber(fiber) {
15585 var wrapper = fiberToWrapper.get(fiber);
15586
15587 if (wrapper === undefined && fiber.alternate !== null) {
15588 wrapper = fiberToWrapper.get(fiber.alternate);
15589 }
15590
15591 if (wrapper === undefined) {
15592 wrapper = new ReactTestInstance(fiber);
15593 fiberToWrapper.set(fiber, wrapper);
15594 }
15595
15596 return wrapper;
15597} // Enable ReactTestRenderer to be used to test DevTools integration.
15598
15599
15600injectIntoDevTools({
15601 findFiberByHostInstance: function () {
15602 throw new Error('TestRenderer does not support findFiberByHostInstance()');
15603 },
15604 bundleType: 1 ,
15605 version: ReactVersion,
15606 rendererPackageName: 'react-test-renderer'
15607});
15608
15609// TODO: decide on the top-level export form.
15610// This is hacky but makes it work with both Rollup and Jest.
15611
15612
15613var reactTestRenderer = ReactTestRendererFiber.default || ReactTestRendererFiber;
15614
15615module.exports = reactTestRenderer;
15616 })();
15617}