UNPKG

689 kBJavaScriptView Raw
1/** @license React v16.10.2
2 * react-art.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global.ReactART = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18function _extends() {
19 _extends = Object.assign || function (target) {
20 for (var i = 1; i < arguments.length; i++) {
21 var source = arguments[i];
22
23 for (var key in source) {
24 if (Object.prototype.hasOwnProperty.call(source, key)) {
25 target[key] = source[key];
26 }
27 }
28 }
29
30 return target;
31 };
32
33 return _extends.apply(this, arguments);
34}
35
36function _inheritsLoose(subClass, superClass) {
37 subClass.prototype = Object.create(superClass.prototype);
38 subClass.prototype.constructor = subClass;
39 subClass.__proto__ = superClass;
40}
41
42function _assertThisInitialized(self) {
43 if (self === void 0) {
44 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
45 }
46
47 return self;
48}
49
50// TODO: this is special because it gets imported during build.
51
52var ReactVersion = '16.10.2';
53
54var LegacyRoot = 0;
55var BatchedRoot = 1;
56var ConcurrentRoot = 2;
57
58var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
59var _assign = ReactInternals.assign;
60
61// Do not require this module directly! Use normal `invariant` calls with
62// template literal strings. The messages will be converted to ReactError during
63// build, and in production they will be minified.
64
65// Do not require this module directly! Use normal `invariant` calls with
66// template literal strings. The messages will be converted to ReactError during
67// build, and in production they will be minified.
68function ReactError(error) {
69 error.name = 'Invariant Violation';
70 return error;
71}
72
73var FunctionComponent = 0;
74var ClassComponent = 1;
75var IndeterminateComponent = 2; // Before we know whether it is function or class
76
77var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
78
79var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
80
81var HostComponent = 5;
82var HostText = 6;
83var Fragment = 7;
84var Mode = 8;
85var ContextConsumer = 9;
86var ContextProvider = 10;
87var ForwardRef = 11;
88var Profiler = 12;
89var SuspenseComponent = 13;
90var MemoComponent = 14;
91var SimpleMemoComponent = 15;
92var LazyComponent = 16;
93var IncompleteClassComponent = 17;
94var DehydratedFragment = 18;
95var SuspenseListComponent = 19;
96var FundamentalComponent = 20;
97var ScopeComponent = 21;
98
99/**
100 * Use invariant() to assert state which your program assumes to be true.
101 *
102 * Provide sprintf-style format (only %s is supported) and arguments
103 * to provide information about what broke and what you were
104 * expecting.
105 *
106 * The invariant message will be stripped in production, but the invariant
107 * will remain to ensure logic does not differ in production.
108 */
109
110/**
111 * Similar to invariant but only logs a warning if the condition is not met.
112 * This can be used to log issues in development environments in critical
113 * paths. Removing the logging code for production environments will keep the
114 * same logic and follow the same code paths.
115 */
116var warningWithoutStack = function () {};
117
118{
119 warningWithoutStack = function (condition, format) {
120 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
121 args[_key - 2] = arguments[_key];
122 }
123
124 if (format === undefined) {
125 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
126 }
127
128 if (args.length > 8) {
129 // Check before the condition to catch violations early.
130 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
131 }
132
133 if (condition) {
134 return;
135 }
136
137 if (typeof console !== 'undefined') {
138 var argsWithFormat = args.map(function (item) {
139 return '' + item;
140 });
141 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
142 // breaks IE9: https://github.com/facebook/react/issues/13610
143
144 Function.prototype.apply.call(console.error, console, argsWithFormat);
145 }
146
147 try {
148 // --- Welcome to debugging React ---
149 // This error was thrown as a convenience so that you can use this stack
150 // to find the callsite that caused this warning to fire.
151 var argIndex = 0;
152 var message = 'Warning: ' + format.replace(/%s/g, function () {
153 return args[argIndex++];
154 });
155 throw new Error(message);
156 } catch (x) {}
157 };
158}
159
160var warningWithoutStack$1 = warningWithoutStack;
161
162/**
163 * `ReactInstanceMap` maintains a mapping from a public facing stateful
164 * instance (key) and the internal representation (value). This allows public
165 * methods to accept the user facing instance as an argument and map them back
166 * to internal methods.
167 *
168 * Note that this module is currently shared and assumed to be stateless.
169 * If this becomes an actual Map, that will break.
170 */
171
172/**
173 * This API should be called `delete` but we'd have to make sure to always
174 * transform these to strings for IE support. When this transform is fully
175 * supported we can rename it.
176 */
177
178function get(key) {
179 return key._reactInternalFiber;
180}
181
182function set$1(key, value) {
183 key._reactInternalFiber = value;
184}
185
186var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
187// Current owner and dispatcher used to share the same ref,
188// but PR #14548 split them out to better support the react-debug-tools package.
189
190if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
191 ReactSharedInternals.ReactCurrentDispatcher = {
192 current: null
193 };
194}
195
196if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
197 ReactSharedInternals.ReactCurrentBatchConfig = {
198 suspense: null
199 };
200}
201
202// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
203// nor polyfill, then a plain number is used for performance.
204var hasSymbol = typeof Symbol === 'function' && Symbol.for;
205var REACT_ELEMENT_TYPE$1 = hasSymbol ? Symbol.for('react.element') : 0xeac7;
206var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
207var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
208var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
209var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
210var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
211var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
212// (unstable) APIs that have been removed. Can we remove the symbols?
213
214
215var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
216var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
217var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
218var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
219var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
220var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
221var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
222var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
223var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7;
224var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
225var FAUX_ITERATOR_SYMBOL = '@@iterator';
226function getIteratorFn(maybeIterable) {
227 if (maybeIterable === null || typeof maybeIterable !== 'object') {
228 return null;
229 }
230
231 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
232
233 if (typeof maybeIterator === 'function') {
234 return maybeIterator;
235 }
236
237 return null;
238}
239
240/**
241 * Similar to invariant but only logs a warning if the condition is not met.
242 * This can be used to log issues in development environments in critical
243 * paths. Removing the logging code for production environments will keep the
244 * same logic and follow the same code paths.
245 */
246
247var warning = warningWithoutStack$1;
248
249{
250 warning = function (condition, format) {
251 if (condition) {
252 return;
253 }
254
255 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
256 var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args
257
258 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
259 args[_key - 2] = arguments[_key];
260 }
261
262 warningWithoutStack$1.apply(void 0, [false, format + '%s'].concat(args, [stack]));
263 };
264}
265
266var warning$1 = warning;
267
268var Uninitialized = -1;
269var Pending = 0;
270var Resolved = 1;
271var Rejected = 2;
272function refineResolvedLazyComponent(lazyComponent) {
273 return lazyComponent._status === Resolved ? lazyComponent._result : null;
274}
275function initializeLazyComponentType(lazyComponent) {
276 if (lazyComponent._status === Uninitialized) {
277 lazyComponent._status = Pending;
278 var ctor = lazyComponent._ctor;
279 var thenable = ctor();
280 lazyComponent._result = thenable;
281 thenable.then(function (moduleObject) {
282 if (lazyComponent._status === Pending) {
283 var defaultExport = moduleObject.default;
284
285 {
286 if (defaultExport === undefined) {
287 warning$1(false, 'lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
288 }
289 }
290
291 lazyComponent._status = Resolved;
292 lazyComponent._result = defaultExport;
293 }
294 }, function (error) {
295 if (lazyComponent._status === Pending) {
296 lazyComponent._status = Rejected;
297 lazyComponent._result = error;
298 }
299 });
300 }
301}
302
303function getWrappedName(outerType, innerType, wrapperName) {
304 var functionName = innerType.displayName || innerType.name || '';
305 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
306}
307
308function getComponentName(type) {
309 if (type == null) {
310 // Host root, text node or just invalid type.
311 return null;
312 }
313
314 {
315 if (typeof type.tag === 'number') {
316 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
317 }
318 }
319
320 if (typeof type === 'function') {
321 return type.displayName || type.name || null;
322 }
323
324 if (typeof type === 'string') {
325 return type;
326 }
327
328 switch (type) {
329 case REACT_FRAGMENT_TYPE:
330 return 'Fragment';
331
332 case REACT_PORTAL_TYPE:
333 return 'Portal';
334
335 case REACT_PROFILER_TYPE:
336 return "Profiler";
337
338 case REACT_STRICT_MODE_TYPE:
339 return 'StrictMode';
340
341 case REACT_SUSPENSE_TYPE:
342 return 'Suspense';
343
344 case REACT_SUSPENSE_LIST_TYPE:
345 return 'SuspenseList';
346 }
347
348 if (typeof type === 'object') {
349 switch (type.$$typeof) {
350 case REACT_CONTEXT_TYPE:
351 return 'Context.Consumer';
352
353 case REACT_PROVIDER_TYPE:
354 return 'Context.Provider';
355
356 case REACT_FORWARD_REF_TYPE:
357 return getWrappedName(type, type.render, 'ForwardRef');
358
359 case REACT_MEMO_TYPE:
360 return getComponentName(type.type);
361
362 case REACT_LAZY_TYPE:
363 {
364 var thenable = type;
365 var resolvedThenable = refineResolvedLazyComponent(thenable);
366
367 if (resolvedThenable) {
368 return getComponentName(resolvedThenable);
369 }
370
371 break;
372 }
373 }
374 }
375
376 return null;
377}
378
379// Don't change these two values. They're used by React Dev Tools.
380var NoEffect =
381/* */
3820;
383var PerformedWork =
384/* */
3851; // You can change the rest (and add more).
386
387var Placement =
388/* */
3892;
390var Update =
391/* */
3924;
393var PlacementAndUpdate =
394/* */
3956;
396var Deletion =
397/* */
3988;
399var ContentReset =
400/* */
40116;
402var Callback =
403/* */
40432;
405var DidCapture =
406/* */
40764;
408var Ref =
409/* */
410128;
411var Snapshot =
412/* */
413256;
414var Passive =
415/* */
416512;
417var Hydrating =
418/* */
4191024;
420var HydratingAndUpdate =
421/* */
4221028; // Passive & Update & Callback & Ref & Snapshot
423
424var LifecycleEffectMask =
425/* */
426932; // Union of all host effects
427
428var HostEffectMask =
429/* */
4302047;
431var Incomplete =
432/* */
4332048;
434var ShouldCapture =
435/* */
4364096;
437
438var enableUserTimingAPI = true; // Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
439
440var debugRenderPhaseSideEffects = false; // In some cases, StrictMode should also double-render lifecycles.
441// This can be confusing for tests though,
442// And it can be bad for performance in production.
443// This feature flag can be used to control the behavior:
444
445var debugRenderPhaseSideEffectsForStrictMode = true; // To preserve the "Pause on caught exceptions" behavior of the debugger, we
446// replay the begin phase of a failed component inside invokeGuardedCallback.
447
448var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; // Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
449
450var warnAboutDeprecatedLifecycles = true; // Gather advanced timing metrics for Profiler subtrees.
451
452var enableProfilerTimer = true; // Trace which interactions trigger each commit.
453
454var enableSchedulerTracing = true; // Only used in www builds.
455
456var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
457
458 // Only used in www builds.
459
460 // Only used in www builds.
461
462 // Disable javascript: URL strings in href for XSS protection.
463
464 // React Fire: prevent the value and checked attributes from syncing
465// with their related DOM properties
466
467 // These APIs will no longer be "unstable" in the upcoming 16.7 release,
468// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
469
470
471 // See https://github.com/react-native-community/discussions-and-proposals/issues/72 for more information
472// This is a flag so we can fix warnings in RN core before turning it on
473
474 // Experimental React Flare event system and event components support.
475
476var enableFlareAPI = false; // Experimental Host Component support.
477
478var enableFundamentalAPI = false; // Experimental Scope support.
479
480var enableScopeAPI = false; // New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
481
482 // We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
483// Till then, we warn about the missing mock, but still fallback to a sync mode compatible version
484
485var warnAboutUnmockedScheduler = false; // For tests, we flush suspense fallbacks in an act scope;
486// *except* in some of our own tests, where we test incremental loading states.
487
488var flushSuspenseFallbacksInTests = true; // Changes priority of some events like mousemove to user-blocking priority,
489// but without making them discrete. The flag exists in case it causes
490// starvation problems.
491
492 // Add a callback property to suspense to notify which promises are currently
493// in the update queue. This allows reporting and tracing of what is causing
494// the user to see a loading state.
495// Also allows hydration callbacks to fire when a dehydrated boundary gets
496// hydrated or deleted.
497
498var enableSuspenseCallback = false; // Part of the simplification of React.createElement so we can eventually move
499// from React.createElement to React.jsx
500// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
501
502var warnAboutDefaultPropsOnFunctionComponents = false;
503var warnAboutStringRefs = false;
504var disableLegacyContext = false;
505var disableSchedulerTimeoutBasedOnReactExpirationTime = false;
506
507var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
508function getNearestMountedFiber(fiber) {
509 var node = fiber;
510 var nearestMounted = fiber;
511
512 if (!fiber.alternate) {
513 // If there is no alternate, this might be a new tree that isn't inserted
514 // yet. If it is, then it will have a pending insertion effect on it.
515 var nextNode = node;
516
517 do {
518 node = nextNode;
519
520 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
521 // This is an insertion or in-progress hydration. The nearest possible
522 // mounted fiber is the parent but we need to continue to figure out
523 // if that one is still mounted.
524 nearestMounted = node.return;
525 }
526
527 nextNode = node.return;
528 } while (nextNode);
529 } else {
530 while (node.return) {
531 node = node.return;
532 }
533 }
534
535 if (node.tag === HostRoot) {
536 // TODO: Check if this was a nested HostRoot when used with
537 // renderContainerIntoSubtree.
538 return nearestMounted;
539 } // If we didn't hit the root, that means that we're in an disconnected tree
540 // that has been unmounted.
541
542
543 return null;
544}
545
546
547function isFiberMounted(fiber) {
548 return getNearestMountedFiber(fiber) === fiber;
549}
550function isMounted(component) {
551 {
552 var owner = ReactCurrentOwner.current;
553
554 if (owner !== null && owner.tag === ClassComponent) {
555 var ownerFiber = owner;
556 var instance = ownerFiber.stateNode;
557 !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0;
558 instance._warnedAboutRefsInRender = true;
559 }
560 }
561
562 var fiber = get(component);
563
564 if (!fiber) {
565 return false;
566 }
567
568 return getNearestMountedFiber(fiber) === fiber;
569}
570
571function assertIsMounted(fiber) {
572 (function () {
573 if (!(getNearestMountedFiber(fiber) === fiber)) {
574 {
575 throw ReactError(Error("Unable to find node on an unmounted component."));
576 }
577 }
578 })();
579}
580
581function findCurrentFiberUsingSlowPath(fiber) {
582 var alternate = fiber.alternate;
583
584 if (!alternate) {
585 // If there is no alternate, then we only need to check if it is mounted.
586 var nearestMounted = getNearestMountedFiber(fiber);
587
588 (function () {
589 if (!(nearestMounted !== null)) {
590 {
591 throw ReactError(Error("Unable to find node on an unmounted component."));
592 }
593 }
594 })();
595
596 if (nearestMounted !== fiber) {
597 return null;
598 }
599
600 return fiber;
601 } // If we have two possible branches, we'll walk backwards up to the root
602 // to see what path the root points to. On the way we may hit one of the
603 // special cases and we'll deal with them.
604
605
606 var a = fiber;
607 var b = alternate;
608
609 while (true) {
610 var parentA = a.return;
611
612 if (parentA === null) {
613 // We're at the root.
614 break;
615 }
616
617 var parentB = parentA.alternate;
618
619 if (parentB === null) {
620 // There is no alternate. This is an unusual case. Currently, it only
621 // happens when a Suspense component is hidden. An extra fragment fiber
622 // is inserted in between the Suspense fiber and its children. Skip
623 // over this extra fragment fiber and proceed to the next parent.
624 var nextParent = parentA.return;
625
626 if (nextParent !== null) {
627 a = b = nextParent;
628 continue;
629 } // If there's no parent, we're at the root.
630
631
632 break;
633 } // If both copies of the parent fiber point to the same child, we can
634 // assume that the child is current. This happens when we bailout on low
635 // priority: the bailed out fiber's child reuses the current child.
636
637
638 if (parentA.child === parentB.child) {
639 var child = parentA.child;
640
641 while (child) {
642 if (child === a) {
643 // We've determined that A is the current branch.
644 assertIsMounted(parentA);
645 return fiber;
646 }
647
648 if (child === b) {
649 // We've determined that B is the current branch.
650 assertIsMounted(parentA);
651 return alternate;
652 }
653
654 child = child.sibling;
655 } // We should never have an alternate for any mounting node. So the only
656 // way this could possibly happen is if this was unmounted, if at all.
657
658
659 (function () {
660 {
661 {
662 throw ReactError(Error("Unable to find node on an unmounted component."));
663 }
664 }
665 })();
666 }
667
668 if (a.return !== b.return) {
669 // The return pointer of A and the return pointer of B point to different
670 // fibers. We assume that return pointers never criss-cross, so A must
671 // belong to the child set of A.return, and B must belong to the child
672 // set of B.return.
673 a = parentA;
674 b = parentB;
675 } else {
676 // The return pointers point to the same fiber. We'll have to use the
677 // default, slow path: scan the child sets of each parent alternate to see
678 // which child belongs to which set.
679 //
680 // Search parent A's child set
681 var didFindChild = false;
682 var _child = parentA.child;
683
684 while (_child) {
685 if (_child === a) {
686 didFindChild = true;
687 a = parentA;
688 b = parentB;
689 break;
690 }
691
692 if (_child === b) {
693 didFindChild = true;
694 b = parentA;
695 a = parentB;
696 break;
697 }
698
699 _child = _child.sibling;
700 }
701
702 if (!didFindChild) {
703 // Search parent B's child set
704 _child = parentB.child;
705
706 while (_child) {
707 if (_child === a) {
708 didFindChild = true;
709 a = parentB;
710 b = parentA;
711 break;
712 }
713
714 if (_child === b) {
715 didFindChild = true;
716 b = parentB;
717 a = parentA;
718 break;
719 }
720
721 _child = _child.sibling;
722 }
723
724 (function () {
725 if (!didFindChild) {
726 {
727 throw ReactError(Error("Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue."));
728 }
729 }
730 })();
731 }
732 }
733
734 (function () {
735 if (!(a.alternate === b)) {
736 {
737 throw ReactError(Error("Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue."));
738 }
739 }
740 })();
741 } // If the root is not a host container, we're in a disconnected tree. I.e.
742 // unmounted.
743
744
745 (function () {
746 if (!(a.tag === HostRoot)) {
747 {
748 throw ReactError(Error("Unable to find node on an unmounted component."));
749 }
750 }
751 })();
752
753 if (a.stateNode.current === a) {
754 // We've determined that A is the current branch.
755 return fiber;
756 } // Otherwise B has to be current branch.
757
758
759 return alternate;
760}
761function findCurrentHostFiber(parent) {
762 var currentParent = findCurrentFiberUsingSlowPath(parent);
763
764 if (!currentParent) {
765 return null;
766 } // Next we'll drill down this component to find the first HostComponent/Text.
767
768
769 var node = currentParent;
770
771 while (true) {
772 if (node.tag === HostComponent || node.tag === HostText) {
773 return node;
774 } else if (node.child) {
775 node.child.return = node;
776 node = node.child;
777 continue;
778 }
779
780 if (node === currentParent) {
781 return null;
782 }
783
784 while (!node.sibling) {
785 if (!node.return || node.return === currentParent) {
786 return null;
787 }
788
789 node = node.return;
790 }
791
792 node.sibling.return = node.return;
793 node = node.sibling;
794 } // Flow needs the return null here, but ESLint complains about it.
795 // eslint-disable-next-line no-unreachable
796
797
798 return null;
799}
800
801var _class = function(mixins){
802 var proto = {};
803 for (var i = 0, l = arguments.length; i < l; i++){
804 var mixin = arguments[i];
805 if (typeof mixin == 'function') mixin = mixin.prototype;
806 for (var key in mixin) proto[key] = mixin[key];
807 }
808 if (!proto.initialize) proto.initialize = function(){};
809 proto.constructor = function(a,b,c,d,e,f,g,h){
810 return new proto.initialize(a,b,c,d,e,f,g,h);
811 };
812 proto.constructor.prototype = proto.initialize.prototype = proto;
813 return proto.constructor;
814};
815
816function Transform(xx, yx, xy, yy, x, y){
817 if (xx && typeof xx == 'object'){
818 yx = xx.yx; yy = xx.yy; y = xx.y;
819 xy = xx.xy; x = xx.x; xx = xx.xx;
820 }
821 this.xx = xx == null ? 1 : xx;
822 this.yx = yx || 0;
823 this.xy = xy || 0;
824 this.yy = yy == null ? 1 : yy;
825 this.x = (x == null ? this.x : x) || 0;
826 this.y = (y == null ? this.y : y) || 0;
827 this._transform();
828 return this;
829}
830
831var transform = _class({
832
833 initialize: Transform,
834
835 _transform: function(){},
836
837 xx: 1, yx: 0, x: 0,
838 xy: 0, yy: 1, y: 0,
839
840 transform: function(xx, yx, xy, yy, x, y){
841 var m = this;
842 if (xx && typeof xx == 'object'){
843 yx = xx.yx; yy = xx.yy; y = xx.y;
844 xy = xx.xy; x = xx.x; xx = xx.xx;
845 }
846 if (!x) x = 0;
847 if (!y) y = 0;
848 return this.transformTo(
849 m.xx * xx + m.xy * yx,
850 m.yx * xx + m.yy * yx,
851 m.xx * xy + m.xy * yy,
852 m.yx * xy + m.yy * yy,
853 m.xx * x + m.xy * y + m.x,
854 m.yx * x + m.yy * y + m.y
855 );
856 },
857
858 transformTo: Transform,
859
860 translate: function(x, y){
861 return this.transform(1, 0, 0, 1, x, y);
862 },
863
864 move: function(x, y){
865 this.x += x || 0;
866 this.y += y || 0;
867 this._transform();
868 return this;
869 },
870
871 scale: function(x, y){
872 if (y == null) y = x;
873 return this.transform(x, 0, 0, y, 0, 0);
874 },
875
876 rotate: function(deg, x, y){
877 if (x == null || y == null){
878 x = (this.left || 0) + (this.width || 0) / 2;
879 y = (this.top || 0) + (this.height || 0) / 2;
880 }
881
882 var rad = deg * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
883
884 this.transform(1, 0, 0, 1, x, y);
885 var m = this;
886
887 return this.transformTo(
888 cos * m.xx - sin * m.yx,
889 sin * m.xx + cos * m.yx,
890 cos * m.xy - sin * m.yy,
891 sin * m.xy + cos * m.yy,
892 m.x,
893 m.y
894 ).transform(1, 0, 0, 1, -x, -y);
895 },
896
897 moveTo: function(x, y){
898 var m = this;
899 return this.transformTo(m.xx, m.yx, m.xy, m.yy, x, y);
900 },
901
902 rotateTo: function(deg, x, y){
903 var m = this;
904 var flip = m.yx / m.xx > m.yy / m.xy ? -1 : 1;
905 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = -flip;
906 return this.rotate(deg - Math.atan2(flip * m.yx, flip * m.xx) * 180 / Math.PI, x, y);
907 },
908
909 scaleTo: function(x, y){
910 // Normalize
911 var m = this;
912
913 var h = Math.sqrt(m.xx * m.xx + m.yx * m.yx);
914 m.xx /= h; m.yx /= h;
915
916 h = Math.sqrt(m.yy * m.yy + m.xy * m.xy);
917 m.yy /= h; m.xy /= h;
918
919 return this.scale(x, y);
920 },
921
922 resizeTo: function(width, height){
923 var w = this.width, h = this.height;
924 if (!w || !h) return this;
925 return this.scaleTo(width / w, height / h);
926 },
927
928 /*
929 inverse: function(){
930 var a = this.xx, b = this.yx,
931 c = this.xy, d = this.yy,
932 e = this.x, f = this.y;
933 if (a * d - b * c == 0) return null;
934 return new Transform(
935 d/(a * d-b * c), b/(b * c-a * d),
936 c/(b * c-a * d), a/(a * d-b * c),
937 (d * e-c * f)/(b * c-a * d), (b * e-a * f)/(a * d-b * c)
938 );
939 },
940 */
941
942 inversePoint: function(x, y){
943 var a = this.xx, b = this.yx,
944 c = this.xy, d = this.yy,
945 e = this.x, f = this.y;
946 var det = b * c - a * d;
947 if (det == 0) return null;
948 return {
949 x: (d * (e - x) + c * (y - f)) / det,
950 y: (a * (f - y) + b * (x - e)) / det
951 };
952 },
953
954 point: function(x, y){
955 var m = this;
956 return {
957 x: m.xx * x + m.xy * y + m.x,
958 y: m.yx * x + m.yy * y + m.y
959 };
960 }
961
962});
963
964var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
965
966
967
968
969
970function createCommonjsModule(fn, module) {
971 return module = { exports: {} }, fn(module, module.exports), module.exports;
972}
973
974var current = createCommonjsModule(function (module, exports) {
975function warning(){
976 throw new Error('You must require a mode before requiring anything else.');
977}
978
979exports.Surface = warning;
980exports.Path = warning;
981exports.Shape = warning;
982exports.Group = warning;
983exports.ClippingRectangle = warning;
984exports.Text = warning;
985
986exports.setCurrent = function(mode){
987 for (var key in mode){
988 exports[key] = mode[key];
989 }
990};
991});
992
993var current_1 = current.Surface;
994var current_2 = current.Path;
995var current_3 = current.Shape;
996var current_4 = current.Group;
997var current_5 = current.ClippingRectangle;
998var current_6 = current.Text;
999var current_7 = current.setCurrent;
1000
1001var TYPES = {
1002 CLIPPING_RECTANGLE: 'ClippingRectangle',
1003 GROUP: 'Group',
1004 SHAPE: 'Shape',
1005 TEXT: 'Text'
1006};
1007var EVENT_TYPES = {
1008 onClick: 'click',
1009 onMouseMove: 'mousemove',
1010 onMouseOver: 'mouseover',
1011 onMouseOut: 'mouseout',
1012 onMouseUp: 'mouseup',
1013 onMouseDown: 'mousedown'
1014};
1015function childrenAsString(children) {
1016 if (!children) {
1017 return '';
1018 } else if (typeof children === 'string') {
1019 return children;
1020 } else if (children.length) {
1021 return children.join('');
1022 } else {
1023 return '';
1024 }
1025}
1026
1027// can re-export everything from this module.
1028
1029function shim() {
1030 (function () {
1031 {
1032 {
1033 throw ReactError(Error("The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue."));
1034 }
1035 }
1036 })();
1037} // Persistence (when unsupported)
1038
1039
1040var supportsPersistence = false;
1041var cloneInstance = shim;
1042var cloneFundamentalInstance = shim;
1043var createContainerChildSet = shim;
1044var appendChildToContainerChildSet = shim;
1045var finalizeContainerChildren = shim;
1046var replaceContainerChildren = shim;
1047var cloneHiddenInstance = shim;
1048var cloneHiddenTextInstance = shim;
1049
1050// can re-export everything from this module.
1051
1052function shim$1() {
1053 (function () {
1054 {
1055 {
1056 throw ReactError(Error("The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue."));
1057 }
1058 }
1059 })();
1060} // Hydration (when unsupported)
1061
1062
1063var supportsHydration = false;
1064var canHydrateInstance = shim$1;
1065var canHydrateTextInstance = shim$1;
1066var canHydrateSuspenseInstance = shim$1;
1067var isSuspenseInstancePending = shim$1;
1068var isSuspenseInstanceFallback = shim$1;
1069var registerSuspenseInstanceRetry = shim$1;
1070var getNextHydratableSibling = shim$1;
1071var getFirstHydratableChild = shim$1;
1072var hydrateInstance = shim$1;
1073var hydrateTextInstance = shim$1;
1074var hydrateSuspenseInstance = shim$1;
1075var getNextHydratableInstanceAfterSuspenseInstance = shim$1;
1076var commitHydratedContainer = shim$1;
1077var commitHydratedSuspenseInstance = shim$1;
1078var clearSuspenseBoundary = shim$1;
1079var clearSuspenseBoundaryFromContainer = shim$1;
1080var didNotMatchHydratedContainerTextInstance = shim$1;
1081var didNotMatchHydratedTextInstance = shim$1;
1082var didNotHydrateContainerInstance = shim$1;
1083var didNotHydrateInstance = shim$1;
1084var didNotFindHydratableContainerInstance = shim$1;
1085var didNotFindHydratableContainerTextInstance = shim$1;
1086var didNotFindHydratableContainerSuspenseInstance = shim$1;
1087var didNotFindHydratableInstance = shim$1;
1088var didNotFindHydratableTextInstance = shim$1;
1089var didNotFindHydratableSuspenseInstance = shim$1;
1090
1091var pooledTransform = new transform();
1092var NO_CONTEXT = {};
1093var UPDATE_SIGNAL = {};
1094
1095{
1096 Object.freeze(NO_CONTEXT);
1097 Object.freeze(UPDATE_SIGNAL);
1098}
1099/** Helper Methods */
1100
1101
1102function addEventListeners(instance, type, listener) {
1103 // We need to explicitly unregister before unmount.
1104 // For this reason we need to track subscriptions.
1105 if (!instance._listeners) {
1106 instance._listeners = {};
1107 instance._subscriptions = {};
1108 }
1109
1110 instance._listeners[type] = listener;
1111
1112 if (listener) {
1113 if (!instance._subscriptions[type]) {
1114 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
1115 }
1116 } else {
1117 if (instance._subscriptions[type]) {
1118 instance._subscriptions[type]();
1119
1120 delete instance._subscriptions[type];
1121 }
1122 }
1123}
1124
1125function createEventHandler(instance) {
1126 return function handleEvent(event) {
1127 var listener = instance._listeners[event.type];
1128
1129 if (!listener) {// Noop
1130 } else if (typeof listener === 'function') {
1131 listener.call(instance, event);
1132 } else if (listener.handleEvent) {
1133 listener.handleEvent(event);
1134 }
1135 };
1136}
1137
1138function destroyEventListeners(instance) {
1139 if (instance._subscriptions) {
1140 for (var type in instance._subscriptions) {
1141 instance._subscriptions[type]();
1142 }
1143 }
1144
1145 instance._subscriptions = null;
1146 instance._listeners = null;
1147}
1148
1149function getScaleX(props) {
1150 if (props.scaleX != null) {
1151 return props.scaleX;
1152 } else if (props.scale != null) {
1153 return props.scale;
1154 } else {
1155 return 1;
1156 }
1157}
1158
1159function getScaleY(props) {
1160 if (props.scaleY != null) {
1161 return props.scaleY;
1162 } else if (props.scale != null) {
1163 return props.scale;
1164 } else {
1165 return 1;
1166 }
1167}
1168
1169function isSameFont(oldFont, newFont) {
1170 if (oldFont === newFont) {
1171 return true;
1172 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
1173 return false;
1174 } else {
1175 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
1176 }
1177}
1178/** Render Methods */
1179
1180
1181function applyClippingRectangleProps(instance, props) {
1182 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1183 applyNodeProps(instance, props, prevProps);
1184 instance.width = props.width;
1185 instance.height = props.height;
1186}
1187
1188function applyGroupProps(instance, props) {
1189 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1190 applyNodeProps(instance, props, prevProps);
1191 instance.width = props.width;
1192 instance.height = props.height;
1193}
1194
1195function applyNodeProps(instance, props) {
1196 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1197 var scaleX = getScaleX(props);
1198 var scaleY = getScaleY(props);
1199 pooledTransform.transformTo(1, 0, 0, 1, 0, 0).move(props.x || 0, props.y || 0).rotate(props.rotation || 0, props.originX, props.originY).scale(scaleX, scaleY, props.originX, props.originY);
1200
1201 if (props.transform != null) {
1202 pooledTransform.transform(props.transform);
1203 }
1204
1205 if (instance.xx !== pooledTransform.xx || instance.yx !== pooledTransform.yx || instance.xy !== pooledTransform.xy || instance.yy !== pooledTransform.yy || instance.x !== pooledTransform.x || instance.y !== pooledTransform.y) {
1206 instance.transformTo(pooledTransform);
1207 }
1208
1209 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
1210 instance.indicate(props.cursor, props.title);
1211 }
1212
1213 if (instance.blend && props.opacity !== prevProps.opacity) {
1214 instance.blend(props.opacity == null ? 1 : props.opacity);
1215 }
1216
1217 if (props.visible !== prevProps.visible) {
1218 if (props.visible == null || props.visible) {
1219 instance.show();
1220 } else {
1221 instance.hide();
1222 }
1223 }
1224
1225 for (var type in EVENT_TYPES) {
1226 addEventListeners(instance, EVENT_TYPES[type], props[type]);
1227 }
1228}
1229
1230function applyRenderableNodeProps(instance, props) {
1231 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1232 applyNodeProps(instance, props, prevProps);
1233
1234 if (prevProps.fill !== props.fill) {
1235 if (props.fill && props.fill.applyFill) {
1236 props.fill.applyFill(instance);
1237 } else {
1238 instance.fill(props.fill);
1239 }
1240 }
1241
1242 if (prevProps.stroke !== props.stroke || prevProps.strokeWidth !== props.strokeWidth || prevProps.strokeCap !== props.strokeCap || prevProps.strokeJoin !== props.strokeJoin || // TODO: Consider deep check of stokeDash; may benefit VML in IE.
1243 prevProps.strokeDash !== props.strokeDash) {
1244 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
1245 }
1246}
1247
1248function applyShapeProps(instance, props) {
1249 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1250 applyRenderableNodeProps(instance, props, prevProps);
1251 var path = props.d || childrenAsString(props.children);
1252 var prevDelta = instance._prevDelta;
1253 var prevPath = instance._prevPath;
1254
1255 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
1256 instance.draw(path, props.width, props.height);
1257 instance._prevDelta = path.delta;
1258 instance._prevPath = path;
1259 }
1260}
1261
1262function applyTextProps(instance, props) {
1263 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1264 applyRenderableNodeProps(instance, props, prevProps);
1265 var string = props.children;
1266
1267 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
1268 instance.draw(string, props.font, props.alignment, props.path);
1269 instance._currentString = string;
1270 }
1271}
1272
1273function appendInitialChild(parentInstance, child) {
1274 if (typeof child === 'string') {
1275 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
1276 (function () {
1277 {
1278 {
1279 throw ReactError(Error("Text children should already be flattened."));
1280 }
1281 }
1282 })();
1283
1284 return;
1285 }
1286
1287 child.inject(parentInstance);
1288}
1289function createInstance(type, props, internalInstanceHandle) {
1290 var instance;
1291
1292 switch (type) {
1293 case TYPES.CLIPPING_RECTANGLE:
1294 instance = current.ClippingRectangle();
1295 instance._applyProps = applyClippingRectangleProps;
1296 break;
1297
1298 case TYPES.GROUP:
1299 instance = current.Group();
1300 instance._applyProps = applyGroupProps;
1301 break;
1302
1303 case TYPES.SHAPE:
1304 instance = current.Shape();
1305 instance._applyProps = applyShapeProps;
1306 break;
1307
1308 case TYPES.TEXT:
1309 instance = current.Text(props.children, props.font, props.alignment, props.path);
1310 instance._applyProps = applyTextProps;
1311 break;
1312 }
1313
1314 (function () {
1315 if (!instance) {
1316 {
1317 throw ReactError(Error("ReactART does not support the type \"" + type + "\""));
1318 }
1319 }
1320 })();
1321
1322 instance._applyProps(instance, props);
1323
1324 return instance;
1325}
1326function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
1327 return text;
1328}
1329function finalizeInitialChildren(domElement, type, props) {
1330 return false;
1331}
1332function getPublicInstance(instance) {
1333 return instance;
1334}
1335function prepareForCommit() {// Noop
1336}
1337function prepareUpdate(domElement, type, oldProps, newProps) {
1338 return UPDATE_SIGNAL;
1339}
1340function resetAfterCommit() {// Noop
1341}
1342function resetTextContent(domElement) {// Noop
1343}
1344function shouldDeprioritizeSubtree(type, props) {
1345 return false;
1346}
1347function getRootHostContext() {
1348 return NO_CONTEXT;
1349}
1350function getChildHostContext() {
1351 return NO_CONTEXT;
1352}
1353var scheduleTimeout = setTimeout;
1354var cancelTimeout = clearTimeout;
1355var noTimeout = -1;
1356function shouldSetTextContent(type, props) {
1357 return typeof props.children === 'string' || typeof props.children === 'number';
1358} // The ART renderer is secondary to the React DOM renderer.
1359
1360var isPrimaryRenderer = false; // The ART renderer shouldn't trigger missing act() warnings
1361
1362var warnsIfNotActing = false;
1363var supportsMutation = true;
1364function appendChild(parentInstance, child) {
1365 if (child.parentNode === parentInstance) {
1366 child.eject();
1367 }
1368
1369 child.inject(parentInstance);
1370}
1371function appendChildToContainer(parentInstance, child) {
1372 if (child.parentNode === parentInstance) {
1373 child.eject();
1374 }
1375
1376 child.inject(parentInstance);
1377}
1378function insertBefore(parentInstance, child, beforeChild) {
1379 (function () {
1380 if (!(child !== beforeChild)) {
1381 {
1382 throw ReactError(Error("ReactART: Can not insert node before itself"));
1383 }
1384 }
1385 })();
1386
1387 child.injectBefore(beforeChild);
1388}
1389function insertInContainerBefore(parentInstance, child, beforeChild) {
1390 (function () {
1391 if (!(child !== beforeChild)) {
1392 {
1393 throw ReactError(Error("ReactART: Can not insert node before itself"));
1394 }
1395 }
1396 })();
1397
1398 child.injectBefore(beforeChild);
1399}
1400function removeChild(parentInstance, child) {
1401 destroyEventListeners(child);
1402 child.eject();
1403}
1404function removeChildFromContainer(parentInstance, child) {
1405 destroyEventListeners(child);
1406 child.eject();
1407}
1408
1409
1410function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1411 instance._applyProps(instance, newProps, oldProps);
1412}
1413function hideInstance(instance) {
1414 instance.hide();
1415}
1416
1417function unhideInstance(instance, props) {
1418 if (props.visible == null || props.visible) {
1419 instance.show();
1420 }
1421}
1422function unhideTextInstance(textInstance, text) {// Noop
1423}
1424function mountResponderInstance(responder, responderInstance, props, state, instance) {
1425 throw new Error('Not yet implemented.');
1426}
1427function unmountResponderInstance(responderInstance) {
1428 throw new Error('Not yet implemented.');
1429}
1430function getFundamentalComponentInstance(fundamentalInstance) {
1431 throw new Error('Not yet implemented.');
1432}
1433function mountFundamentalComponent(fundamentalInstance) {
1434 throw new Error('Not yet implemented.');
1435}
1436function shouldUpdateFundamentalComponent(fundamentalInstance) {
1437 throw new Error('Not yet implemented.');
1438}
1439function updateFundamentalComponent(fundamentalInstance) {
1440 throw new Error('Not yet implemented.');
1441}
1442function unmountFundamentalComponent(fundamentalInstance) {
1443 throw new Error('Not yet implemented.');
1444}
1445
1446/**
1447 * Copyright (c) 2013-present, Facebook, Inc.
1448 *
1449 * This source code is licensed under the MIT license found in the
1450 * LICENSE file in the root directory of this source tree.
1451 */
1452
1453
1454
1455var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1456
1457var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
1458
1459/**
1460 * Copyright (c) 2013-present, Facebook, Inc.
1461 *
1462 * This source code is licensed under the MIT license found in the
1463 * LICENSE file in the root directory of this source tree.
1464 */
1465
1466
1467
1468var printWarning = function() {};
1469
1470{
1471 var ReactPropTypesSecret = ReactPropTypesSecret_1;
1472 var loggedTypeFailures = {};
1473 var has$1 = Function.call.bind(Object.prototype.hasOwnProperty);
1474
1475 printWarning = function(text) {
1476 var message = 'Warning: ' + text;
1477 if (typeof console !== 'undefined') {
1478 console.error(message);
1479 }
1480 try {
1481 // --- Welcome to debugging React ---
1482 // This error was thrown as a convenience so that you can use this stack
1483 // to find the callsite that caused this warning to fire.
1484 throw new Error(message);
1485 } catch (x) {}
1486 };
1487}
1488
1489/**
1490 * Assert that the values match with the type specs.
1491 * Error messages are memorized and will only be shown once.
1492 *
1493 * @param {object} typeSpecs Map of name to a ReactPropType
1494 * @param {object} values Runtime values that need to be type-checked
1495 * @param {string} location e.g. "prop", "context", "child context"
1496 * @param {string} componentName Name of the component for error messages.
1497 * @param {?Function} getStack Returns the component stack.
1498 * @private
1499 */
1500function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1501 {
1502 for (var typeSpecName in typeSpecs) {
1503 if (has$1(typeSpecs, typeSpecName)) {
1504 var error;
1505 // Prop type validation may throw. In case they do, we don't want to
1506 // fail the render phase where it didn't fail before. So we log it.
1507 // After these have been cleaned up, we'll let them throw.
1508 try {
1509 // This is intentionally an invariant that gets caught. It's the same
1510 // behavior as without this statement except with a better message.
1511 if (typeof typeSpecs[typeSpecName] !== 'function') {
1512 var err = Error(
1513 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1514 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1515 );
1516 err.name = 'Invariant Violation';
1517 throw err;
1518 }
1519 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
1520 } catch (ex) {
1521 error = ex;
1522 }
1523 if (error && !(error instanceof Error)) {
1524 printWarning(
1525 (componentName || 'React class') + ': type specification of ' +
1526 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1527 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1528 'You may have forgotten to pass an argument to the type checker ' +
1529 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1530 'shape all require an argument).'
1531 );
1532 }
1533 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1534 // Only monitor this failure once because there tends to be a lot of the
1535 // same error.
1536 loggedTypeFailures[error.message] = true;
1537
1538 var stack = getStack ? getStack() : '';
1539
1540 printWarning(
1541 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1542 );
1543 }
1544 }
1545 }
1546 }
1547}
1548
1549/**
1550 * Resets warning cache when testing.
1551 *
1552 * @private
1553 */
1554checkPropTypes.resetWarningCache = function() {
1555 {
1556 loggedTypeFailures = {};
1557 }
1558};
1559
1560var checkPropTypes_1 = checkPropTypes;
1561
1562var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1563var describeComponentFrame = function (name, source, ownerName) {
1564 var sourceInfo = '';
1565
1566 if (source) {
1567 var path = source.fileName;
1568 var fileName = path.replace(BEFORE_SLASH_RE, '');
1569
1570 {
1571 // In DEV, include code for a common special case:
1572 // prefer "folder/index.js" instead of just "index.js".
1573 if (/^index\./.test(fileName)) {
1574 var match = path.match(BEFORE_SLASH_RE);
1575
1576 if (match) {
1577 var pathBeforeSlash = match[1];
1578
1579 if (pathBeforeSlash) {
1580 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1581 fileName = folderName + '/' + fileName;
1582 }
1583 }
1584 }
1585 }
1586
1587 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1588 } else if (ownerName) {
1589 sourceInfo = ' (created by ' + ownerName + ')';
1590 }
1591
1592 return '\n in ' + (name || 'Unknown') + sourceInfo;
1593};
1594
1595var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1596
1597function describeFiber(fiber) {
1598 switch (fiber.tag) {
1599 case HostRoot:
1600 case HostPortal:
1601 case HostText:
1602 case Fragment:
1603 case ContextProvider:
1604 case ContextConsumer:
1605 return '';
1606
1607 default:
1608 var owner = fiber._debugOwner;
1609 var source = fiber._debugSource;
1610 var name = getComponentName(fiber.type);
1611 var ownerName = null;
1612
1613 if (owner) {
1614 ownerName = getComponentName(owner.type);
1615 }
1616
1617 return describeComponentFrame(name, source, ownerName);
1618 }
1619}
1620
1621function getStackByFiberInDevAndProd(workInProgress) {
1622 var info = '';
1623 var node = workInProgress;
1624
1625 do {
1626 info += describeFiber(node);
1627 node = node.return;
1628 } while (node);
1629
1630 return info;
1631}
1632var current$1 = null;
1633var phase = null;
1634function getCurrentFiberOwnerNameInDevOrNull() {
1635 {
1636 if (current$1 === null) {
1637 return null;
1638 }
1639
1640 var owner = current$1._debugOwner;
1641
1642 if (owner !== null && typeof owner !== 'undefined') {
1643 return getComponentName(owner.type);
1644 }
1645 }
1646
1647 return null;
1648}
1649function getCurrentFiberStackInDev() {
1650 {
1651 if (current$1 === null) {
1652 return '';
1653 } // Safe because if current fiber exists, we are reconciling,
1654 // and it is guaranteed to be the work-in-progress version.
1655
1656
1657 return getStackByFiberInDevAndProd(current$1);
1658 }
1659
1660 return '';
1661}
1662function resetCurrentFiber() {
1663 {
1664 ReactDebugCurrentFrame.getCurrentStack = null;
1665 current$1 = null;
1666 phase = null;
1667 }
1668}
1669function setCurrentFiber(fiber) {
1670 {
1671 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1672 current$1 = fiber;
1673 phase = null;
1674 }
1675}
1676function setCurrentPhase(lifeCyclePhase) {
1677 {
1678 phase = lifeCyclePhase;
1679 }
1680}
1681
1682// Prefix measurements so that it's possible to filter them.
1683// Longer prefixes are hard to read in DevTools.
1684var reactEmoji = "\u269B";
1685var warningEmoji = "\u26D4";
1686var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; // Keep track of current fiber so that we know the path to unwind on pause.
1687// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1688
1689var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
1690// Reusing `currentFiber` would be confusing for this because user code fiber
1691// can change during commit phase too, but we don't need to unwind it (since
1692// lifecycles in the commit phase don't resemble a tree).
1693
1694var currentPhase = null;
1695var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
1696// so we will keep track of it, and include it in the report.
1697// Track commits caused by cascading updates.
1698
1699var isCommitting = false;
1700var hasScheduledUpdateInCurrentCommit = false;
1701var hasScheduledUpdateInCurrentPhase = false;
1702var commitCountInCurrentWorkLoop = 0;
1703var effectCountInCurrentCommit = 0;
1704// to avoid stretch the commit phase with measurement overhead.
1705
1706var labelsInCurrentCommit = new Set();
1707
1708var formatMarkName = function (markName) {
1709 return reactEmoji + " " + markName;
1710};
1711
1712var formatLabel = function (label, warning) {
1713 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
1714 var suffix = warning ? " Warning: " + warning : '';
1715 return "" + prefix + label + suffix;
1716};
1717
1718var beginMark = function (markName) {
1719 performance.mark(formatMarkName(markName));
1720};
1721
1722var clearMark = function (markName) {
1723 performance.clearMarks(formatMarkName(markName));
1724};
1725
1726var endMark = function (label, markName, warning) {
1727 var formattedMarkName = formatMarkName(markName);
1728 var formattedLabel = formatLabel(label, warning);
1729
1730 try {
1731 performance.measure(formattedLabel, formattedMarkName);
1732 } catch (err) {} // If previous mark was missing for some reason, this will throw.
1733 // This could only happen if React crashed in an unexpected place earlier.
1734 // Don't pile on with more errors.
1735 // Clear marks immediately to avoid growing buffer.
1736
1737
1738 performance.clearMarks(formattedMarkName);
1739 performance.clearMeasures(formattedLabel);
1740};
1741
1742var getFiberMarkName = function (label, debugID) {
1743 return label + " (#" + debugID + ")";
1744};
1745
1746var getFiberLabel = function (componentName, isMounted, phase) {
1747 if (phase === null) {
1748 // These are composite component total time measurements.
1749 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
1750 } else {
1751 // Composite component methods.
1752 return componentName + "." + phase;
1753 }
1754};
1755
1756var beginFiberMark = function (fiber, phase) {
1757 var componentName = getComponentName(fiber.type) || 'Unknown';
1758 var debugID = fiber._debugID;
1759 var isMounted = fiber.alternate !== null;
1760 var label = getFiberLabel(componentName, isMounted, phase);
1761
1762 if (isCommitting && labelsInCurrentCommit.has(label)) {
1763 // During the commit phase, we don't show duplicate labels because
1764 // there is a fixed overhead for every measurement, and we don't
1765 // want to stretch the commit phase beyond necessary.
1766 return false;
1767 }
1768
1769 labelsInCurrentCommit.add(label);
1770 var markName = getFiberMarkName(label, debugID);
1771 beginMark(markName);
1772 return true;
1773};
1774
1775var clearFiberMark = function (fiber, phase) {
1776 var componentName = getComponentName(fiber.type) || 'Unknown';
1777 var debugID = fiber._debugID;
1778 var isMounted = fiber.alternate !== null;
1779 var label = getFiberLabel(componentName, isMounted, phase);
1780 var markName = getFiberMarkName(label, debugID);
1781 clearMark(markName);
1782};
1783
1784var endFiberMark = function (fiber, phase, warning) {
1785 var componentName = getComponentName(fiber.type) || 'Unknown';
1786 var debugID = fiber._debugID;
1787 var isMounted = fiber.alternate !== null;
1788 var label = getFiberLabel(componentName, isMounted, phase);
1789 var markName = getFiberMarkName(label, debugID);
1790 endMark(label, markName, warning);
1791};
1792
1793var shouldIgnoreFiber = function (fiber) {
1794 // Host components should be skipped in the timeline.
1795 // We could check typeof fiber.type, but does this work with RN?
1796 switch (fiber.tag) {
1797 case HostRoot:
1798 case HostComponent:
1799 case HostText:
1800 case HostPortal:
1801 case Fragment:
1802 case ContextProvider:
1803 case ContextConsumer:
1804 case Mode:
1805 return true;
1806
1807 default:
1808 return false;
1809 }
1810};
1811
1812var clearPendingPhaseMeasurement = function () {
1813 if (currentPhase !== null && currentPhaseFiber !== null) {
1814 clearFiberMark(currentPhaseFiber, currentPhase);
1815 }
1816
1817 currentPhaseFiber = null;
1818 currentPhase = null;
1819 hasScheduledUpdateInCurrentPhase = false;
1820};
1821
1822var pauseTimers = function () {
1823 // Stops all currently active measurements so that they can be resumed
1824 // if we continue in a later deferred loop from the same unit of work.
1825 var fiber = currentFiber;
1826
1827 while (fiber) {
1828 if (fiber._debugIsCurrentlyTiming) {
1829 endFiberMark(fiber, null, null);
1830 }
1831
1832 fiber = fiber.return;
1833 }
1834};
1835
1836var resumeTimersRecursively = function (fiber) {
1837 if (fiber.return !== null) {
1838 resumeTimersRecursively(fiber.return);
1839 }
1840
1841 if (fiber._debugIsCurrentlyTiming) {
1842 beginFiberMark(fiber, null);
1843 }
1844};
1845
1846var resumeTimers = function () {
1847 // Resumes all measurements that were active during the last deferred loop.
1848 if (currentFiber !== null) {
1849 resumeTimersRecursively(currentFiber);
1850 }
1851};
1852
1853function recordEffect() {
1854 if (enableUserTimingAPI) {
1855 effectCountInCurrentCommit++;
1856 }
1857}
1858function recordScheduleUpdate() {
1859 if (enableUserTimingAPI) {
1860 if (isCommitting) {
1861 hasScheduledUpdateInCurrentCommit = true;
1862 }
1863
1864 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1865 hasScheduledUpdateInCurrentPhase = true;
1866 }
1867 }
1868}
1869
1870
1871function startWorkTimer(fiber) {
1872 if (enableUserTimingAPI) {
1873 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1874 return;
1875 } // If we pause, this is the fiber to unwind from.
1876
1877
1878 currentFiber = fiber;
1879
1880 if (!beginFiberMark(fiber, null)) {
1881 return;
1882 }
1883
1884 fiber._debugIsCurrentlyTiming = true;
1885 }
1886}
1887function cancelWorkTimer(fiber) {
1888 if (enableUserTimingAPI) {
1889 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1890 return;
1891 } // Remember we shouldn't complete measurement for this fiber.
1892 // Otherwise flamechart will be deep even for small updates.
1893
1894
1895 fiber._debugIsCurrentlyTiming = false;
1896 clearFiberMark(fiber, null);
1897 }
1898}
1899function stopWorkTimer(fiber) {
1900 if (enableUserTimingAPI) {
1901 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1902 return;
1903 } // If we pause, its parent is the fiber to unwind from.
1904
1905
1906 currentFiber = fiber.return;
1907
1908 if (!fiber._debugIsCurrentlyTiming) {
1909 return;
1910 }
1911
1912 fiber._debugIsCurrentlyTiming = false;
1913 endFiberMark(fiber, null, null);
1914 }
1915}
1916function stopFailedWorkTimer(fiber) {
1917 if (enableUserTimingAPI) {
1918 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1919 return;
1920 } // If we pause, its parent is the fiber to unwind from.
1921
1922
1923 currentFiber = fiber.return;
1924
1925 if (!fiber._debugIsCurrentlyTiming) {
1926 return;
1927 }
1928
1929 fiber._debugIsCurrentlyTiming = false;
1930 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1931 endFiberMark(fiber, null, warning);
1932 }
1933}
1934function startPhaseTimer(fiber, phase) {
1935 if (enableUserTimingAPI) {
1936 if (!supportsUserTiming) {
1937 return;
1938 }
1939
1940 clearPendingPhaseMeasurement();
1941
1942 if (!beginFiberMark(fiber, phase)) {
1943 return;
1944 }
1945
1946 currentPhaseFiber = fiber;
1947 currentPhase = phase;
1948 }
1949}
1950function stopPhaseTimer() {
1951 if (enableUserTimingAPI) {
1952 if (!supportsUserTiming) {
1953 return;
1954 }
1955
1956 if (currentPhase !== null && currentPhaseFiber !== null) {
1957 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1958 endFiberMark(currentPhaseFiber, currentPhase, warning);
1959 }
1960
1961 currentPhase = null;
1962 currentPhaseFiber = null;
1963 }
1964}
1965function startWorkLoopTimer(nextUnitOfWork) {
1966 if (enableUserTimingAPI) {
1967 currentFiber = nextUnitOfWork;
1968
1969 if (!supportsUserTiming) {
1970 return;
1971 }
1972
1973 commitCountInCurrentWorkLoop = 0; // This is top level call.
1974 // Any other measurements are performed within.
1975
1976 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
1977
1978 resumeTimers();
1979 }
1980}
1981function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1982 if (enableUserTimingAPI) {
1983 if (!supportsUserTiming) {
1984 return;
1985 }
1986
1987 var warning = null;
1988
1989 if (interruptedBy !== null) {
1990 if (interruptedBy.tag === HostRoot) {
1991 warning = 'A top-level update interrupted the previous render';
1992 } else {
1993 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1994 warning = "An update to " + componentName + " interrupted the previous render";
1995 }
1996 } else if (commitCountInCurrentWorkLoop > 1) {
1997 warning = 'There were cascading updates';
1998 }
1999
2000 commitCountInCurrentWorkLoop = 0;
2001 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
2002
2003 pauseTimers();
2004 endMark(label, '(React Tree Reconciliation)', warning);
2005 }
2006}
2007function startCommitTimer() {
2008 if (enableUserTimingAPI) {
2009 if (!supportsUserTiming) {
2010 return;
2011 }
2012
2013 isCommitting = true;
2014 hasScheduledUpdateInCurrentCommit = false;
2015 labelsInCurrentCommit.clear();
2016 beginMark('(Committing Changes)');
2017 }
2018}
2019function stopCommitTimer() {
2020 if (enableUserTimingAPI) {
2021 if (!supportsUserTiming) {
2022 return;
2023 }
2024
2025 var warning = null;
2026
2027 if (hasScheduledUpdateInCurrentCommit) {
2028 warning = 'Lifecycle hook scheduled a cascading update';
2029 } else if (commitCountInCurrentWorkLoop > 0) {
2030 warning = 'Caused by a cascading update in earlier commit';
2031 }
2032
2033 hasScheduledUpdateInCurrentCommit = false;
2034 commitCountInCurrentWorkLoop++;
2035 isCommitting = false;
2036 labelsInCurrentCommit.clear();
2037 endMark('(Committing Changes)', '(Committing Changes)', warning);
2038 }
2039}
2040function startCommitSnapshotEffectsTimer() {
2041 if (enableUserTimingAPI) {
2042 if (!supportsUserTiming) {
2043 return;
2044 }
2045
2046 effectCountInCurrentCommit = 0;
2047 beginMark('(Committing Snapshot Effects)');
2048 }
2049}
2050function stopCommitSnapshotEffectsTimer() {
2051 if (enableUserTimingAPI) {
2052 if (!supportsUserTiming) {
2053 return;
2054 }
2055
2056 var count = effectCountInCurrentCommit;
2057 effectCountInCurrentCommit = 0;
2058 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
2059 }
2060}
2061function startCommitHostEffectsTimer() {
2062 if (enableUserTimingAPI) {
2063 if (!supportsUserTiming) {
2064 return;
2065 }
2066
2067 effectCountInCurrentCommit = 0;
2068 beginMark('(Committing Host Effects)');
2069 }
2070}
2071function stopCommitHostEffectsTimer() {
2072 if (enableUserTimingAPI) {
2073 if (!supportsUserTiming) {
2074 return;
2075 }
2076
2077 var count = effectCountInCurrentCommit;
2078 effectCountInCurrentCommit = 0;
2079 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
2080 }
2081}
2082function startCommitLifeCyclesTimer() {
2083 if (enableUserTimingAPI) {
2084 if (!supportsUserTiming) {
2085 return;
2086 }
2087
2088 effectCountInCurrentCommit = 0;
2089 beginMark('(Calling Lifecycle Methods)');
2090 }
2091}
2092function stopCommitLifeCyclesTimer() {
2093 if (enableUserTimingAPI) {
2094 if (!supportsUserTiming) {
2095 return;
2096 }
2097
2098 var count = effectCountInCurrentCommit;
2099 effectCountInCurrentCommit = 0;
2100 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
2101 }
2102}
2103
2104var valueStack = [];
2105var fiberStack;
2106
2107{
2108 fiberStack = [];
2109}
2110
2111var index = -1;
2112
2113function createCursor(defaultValue) {
2114 return {
2115 current: defaultValue
2116 };
2117}
2118
2119function pop(cursor, fiber) {
2120 if (index < 0) {
2121 {
2122 warningWithoutStack$1(false, 'Unexpected pop.');
2123 }
2124
2125 return;
2126 }
2127
2128 {
2129 if (fiber !== fiberStack[index]) {
2130 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
2131 }
2132 }
2133
2134 cursor.current = valueStack[index];
2135 valueStack[index] = null;
2136
2137 {
2138 fiberStack[index] = null;
2139 }
2140
2141 index--;
2142}
2143
2144function push(cursor, value, fiber) {
2145 index++;
2146 valueStack[index] = cursor.current;
2147
2148 {
2149 fiberStack[index] = fiber;
2150 }
2151
2152 cursor.current = value;
2153}
2154
2155var warnedAboutMissingGetChildContext;
2156
2157{
2158 warnedAboutMissingGetChildContext = {};
2159}
2160
2161var emptyContextObject = {};
2162
2163{
2164 Object.freeze(emptyContextObject);
2165} // A cursor to the current merged context object on the stack.
2166
2167
2168var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
2169
2170var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
2171// We use this to get access to the parent context after we have already
2172// pushed the next context provider, and now need to merge their contexts.
2173
2174var previousContext = emptyContextObject;
2175
2176function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
2177 if (disableLegacyContext) {
2178 return emptyContextObject;
2179 } else {
2180 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
2181 // If the fiber is a context provider itself, when we read its context
2182 // we may have already pushed its own child context on the stack. A context
2183 // provider should not "see" its own child context. Therefore we read the
2184 // previous (parent) context instead for a context provider.
2185 return previousContext;
2186 }
2187
2188 return contextStackCursor.current;
2189 }
2190}
2191
2192function cacheContext(workInProgress, unmaskedContext, maskedContext) {
2193 if (disableLegacyContext) {
2194 return;
2195 } else {
2196 var instance = workInProgress.stateNode;
2197 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
2198 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
2199 }
2200}
2201
2202function getMaskedContext(workInProgress, unmaskedContext) {
2203 if (disableLegacyContext) {
2204 return emptyContextObject;
2205 } else {
2206 var type = workInProgress.type;
2207 var contextTypes = type.contextTypes;
2208
2209 if (!contextTypes) {
2210 return emptyContextObject;
2211 } // Avoid recreating masked context unless unmasked context has changed.
2212 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
2213 // This may trigger infinite loops if componentWillReceiveProps calls setState.
2214
2215
2216 var instance = workInProgress.stateNode;
2217
2218 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
2219 return instance.__reactInternalMemoizedMaskedChildContext;
2220 }
2221
2222 var context = {};
2223
2224 for (var key in contextTypes) {
2225 context[key] = unmaskedContext[key];
2226 }
2227
2228 {
2229 var name = getComponentName(type) || 'Unknown';
2230 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
2231 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
2232 // Context is created before the class component is instantiated so check for instance.
2233
2234
2235 if (instance) {
2236 cacheContext(workInProgress, unmaskedContext, context);
2237 }
2238
2239 return context;
2240 }
2241}
2242
2243function hasContextChanged() {
2244 if (disableLegacyContext) {
2245 return false;
2246 } else {
2247 return didPerformWorkStackCursor.current;
2248 }
2249}
2250
2251function isContextProvider(type) {
2252 if (disableLegacyContext) {
2253 return false;
2254 } else {
2255 var childContextTypes = type.childContextTypes;
2256 return childContextTypes !== null && childContextTypes !== undefined;
2257 }
2258}
2259
2260function popContext(fiber) {
2261 if (disableLegacyContext) {
2262 return;
2263 } else {
2264 pop(didPerformWorkStackCursor, fiber);
2265 pop(contextStackCursor, fiber);
2266 }
2267}
2268
2269function popTopLevelContextObject(fiber) {
2270 if (disableLegacyContext) {
2271 return;
2272 } else {
2273 pop(didPerformWorkStackCursor, fiber);
2274 pop(contextStackCursor, fiber);
2275 }
2276}
2277
2278function pushTopLevelContextObject(fiber, context, didChange) {
2279 if (disableLegacyContext) {
2280 return;
2281 } else {
2282 (function () {
2283 if (!(contextStackCursor.current === emptyContextObject)) {
2284 {
2285 throw ReactError(Error("Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue."));
2286 }
2287 }
2288 })();
2289
2290 push(contextStackCursor, context, fiber);
2291 push(didPerformWorkStackCursor, didChange, fiber);
2292 }
2293}
2294
2295function processChildContext(fiber, type, parentContext) {
2296 if (disableLegacyContext) {
2297 return parentContext;
2298 } else {
2299 var instance = fiber.stateNode;
2300 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
2301 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
2302
2303 if (typeof instance.getChildContext !== 'function') {
2304 {
2305 var componentName = getComponentName(type) || 'Unknown';
2306
2307 if (!warnedAboutMissingGetChildContext[componentName]) {
2308 warnedAboutMissingGetChildContext[componentName] = true;
2309 warningWithoutStack$1(false, '%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
2310 }
2311 }
2312
2313 return parentContext;
2314 }
2315
2316 var childContext;
2317
2318 {
2319 setCurrentPhase('getChildContext');
2320 }
2321
2322 startPhaseTimer(fiber, 'getChildContext');
2323 childContext = instance.getChildContext();
2324 stopPhaseTimer();
2325
2326 {
2327 setCurrentPhase(null);
2328 }
2329
2330 for (var contextKey in childContext) {
2331 (function () {
2332 if (!(contextKey in childContextTypes)) {
2333 {
2334 throw ReactError(Error((getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes."));
2335 }
2336 }
2337 })();
2338 }
2339
2340 {
2341 var name = getComponentName(type) || 'Unknown';
2342 checkPropTypes_1(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
2343 // somebody calls unstable_renderSubtreeIntoContainer() and we process
2344 // context from the parent component instance. The stack will be missing
2345 // because it's outside of the reconciliation, and so the pointer has not
2346 // been set. This is rare and doesn't matter. We'll also remove that API.
2347 getCurrentFiberStackInDev);
2348 }
2349
2350 return _assign({}, parentContext, {}, childContext);
2351 }
2352}
2353
2354function pushContextProvider(workInProgress) {
2355 if (disableLegacyContext) {
2356 return false;
2357 } else {
2358 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
2359 // If the instance does not exist yet, we will push null at first,
2360 // and replace it on the stack later when invalidating the context.
2361
2362 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
2363 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2364
2365 previousContext = contextStackCursor.current;
2366 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2367 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2368 return true;
2369 }
2370}
2371
2372function invalidateContextProvider(workInProgress, type, didChange) {
2373 if (disableLegacyContext) {
2374 return;
2375 } else {
2376 var instance = workInProgress.stateNode;
2377
2378 (function () {
2379 if (!instance) {
2380 {
2381 throw ReactError(Error("Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue."));
2382 }
2383 }
2384 })();
2385
2386 if (didChange) {
2387 // Merge parent and own context.
2388 // Skip this if we're not updating due to sCU.
2389 // This avoids unnecessarily recomputing memoized values.
2390 var mergedContext = processChildContext(workInProgress, type, previousContext);
2391 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
2392 // It is important to unwind the context in the reverse order.
2393
2394 pop(didPerformWorkStackCursor, workInProgress);
2395 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
2396
2397 push(contextStackCursor, mergedContext, workInProgress);
2398 push(didPerformWorkStackCursor, didChange, workInProgress);
2399 } else {
2400 pop(didPerformWorkStackCursor, workInProgress);
2401 push(didPerformWorkStackCursor, didChange, workInProgress);
2402 }
2403 }
2404}
2405
2406function findCurrentUnmaskedContext(fiber) {
2407 if (disableLegacyContext) {
2408 return emptyContextObject;
2409 } else {
2410 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2411 // makes sense elsewhere
2412 (function () {
2413 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
2414 {
2415 throw ReactError(Error("Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue."));
2416 }
2417 }
2418 })();
2419
2420 var node = fiber;
2421
2422 do {
2423 switch (node.tag) {
2424 case HostRoot:
2425 return node.stateNode.context;
2426
2427 case ClassComponent:
2428 {
2429 var Component = node.type;
2430
2431 if (isContextProvider(Component)) {
2432 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2433 }
2434
2435 break;
2436 }
2437 }
2438
2439 node = node.return;
2440 } while (node !== null);
2441
2442 (function () {
2443 {
2444 {
2445 throw ReactError(Error("Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue."));
2446 }
2447 }
2448 })();
2449 }
2450}
2451
2452var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2453var _ReactInternals$Sched = ReactInternals$1.Scheduler;
2454var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
2455var unstable_now = _ReactInternals$Sched.unstable_now;
2456var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
2457var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
2458var unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint;
2459var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
2460var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
2461var unstable_next = _ReactInternals$Sched.unstable_next;
2462var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
2463var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
2464var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
2465var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
2466var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
2467var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
2468var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
2469var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
2470var unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate;
2471var unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
2472
2473var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2474var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
2475var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
2476var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
2477var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
2478var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
2479var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
2480var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
2481var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
2482var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
2483var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2484
2485// Intentionally not named imports because Rollup would use dynamic dispatch for
2486// CommonJS interop named imports.
2487var Scheduler_runWithPriority = unstable_runWithPriority;
2488var Scheduler_scheduleCallback = unstable_scheduleCallback;
2489var Scheduler_cancelCallback = unstable_cancelCallback;
2490var Scheduler_shouldYield = unstable_shouldYield;
2491var Scheduler_requestPaint = unstable_requestPaint;
2492var Scheduler_now = unstable_now;
2493var Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
2494var Scheduler_ImmediatePriority = unstable_ImmediatePriority;
2495var Scheduler_UserBlockingPriority = unstable_UserBlockingPriority;
2496var Scheduler_NormalPriority = unstable_NormalPriority;
2497var Scheduler_LowPriority = unstable_LowPriority;
2498var Scheduler_IdlePriority = unstable_IdlePriority;
2499
2500if (enableSchedulerTracing) {
2501 // Provide explicit error message when production+profiling bundle of e.g.
2502 // react-dom is used with production (non-profiling) bundle of
2503 // scheduler/tracing
2504 (function () {
2505 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
2506 {
2507 throw ReactError(Error("It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling"));
2508 }
2509 }
2510 })();
2511}
2512
2513var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
2514// ascending numbers so we can compare them like numbers. They start at 90 to
2515// avoid clashing with Scheduler's priorities.
2516
2517var ImmediatePriority = 99;
2518var UserBlockingPriority = 98;
2519var NormalPriority = 97;
2520var LowPriority = 96;
2521var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
2522
2523var NoPriority = 90;
2524var shouldYield = Scheduler_shouldYield;
2525var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
2526Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
2527var syncQueue = null;
2528var immediateQueueCallbackNode = null;
2529var isFlushingSyncQueue = false;
2530var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
2531// This will be the case for modern browsers that support `performance.now`. In
2532// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
2533// timestamp. In that case, subtract the module initialization time to simulate
2534// the behavior of performance.now and keep our times small enough to fit
2535// within 32 bits.
2536// TODO: Consider lifting this into Scheduler.
2537
2538var now = initialTimeMs < 10000 ? Scheduler_now : function () {
2539 return Scheduler_now() - initialTimeMs;
2540};
2541function getCurrentPriorityLevel() {
2542 switch (Scheduler_getCurrentPriorityLevel()) {
2543 case Scheduler_ImmediatePriority:
2544 return ImmediatePriority;
2545
2546 case Scheduler_UserBlockingPriority:
2547 return UserBlockingPriority;
2548
2549 case Scheduler_NormalPriority:
2550 return NormalPriority;
2551
2552 case Scheduler_LowPriority:
2553 return LowPriority;
2554
2555 case Scheduler_IdlePriority:
2556 return IdlePriority;
2557
2558 default:
2559 (function () {
2560 {
2561 {
2562 throw ReactError(Error("Unknown priority level."));
2563 }
2564 }
2565 })();
2566
2567 }
2568}
2569
2570function reactPriorityToSchedulerPriority(reactPriorityLevel) {
2571 switch (reactPriorityLevel) {
2572 case ImmediatePriority:
2573 return Scheduler_ImmediatePriority;
2574
2575 case UserBlockingPriority:
2576 return Scheduler_UserBlockingPriority;
2577
2578 case NormalPriority:
2579 return Scheduler_NormalPriority;
2580
2581 case LowPriority:
2582 return Scheduler_LowPriority;
2583
2584 case IdlePriority:
2585 return Scheduler_IdlePriority;
2586
2587 default:
2588 (function () {
2589 {
2590 {
2591 throw ReactError(Error("Unknown priority level."));
2592 }
2593 }
2594 })();
2595
2596 }
2597}
2598
2599function runWithPriority(reactPriorityLevel, fn) {
2600 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2601 return Scheduler_runWithPriority(priorityLevel, fn);
2602}
2603function scheduleCallback(reactPriorityLevel, callback, options) {
2604 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2605 return Scheduler_scheduleCallback(priorityLevel, callback, options);
2606}
2607function scheduleSyncCallback(callback) {
2608 // Push this callback into an internal queue. We'll flush these either in
2609 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
2610 if (syncQueue === null) {
2611 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
2612
2613 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
2614 } else {
2615 // Push onto existing queue. Don't need to schedule a callback because
2616 // we already scheduled one when we created the queue.
2617 syncQueue.push(callback);
2618 }
2619
2620 return fakeCallbackNode;
2621}
2622function cancelCallback(callbackNode) {
2623 if (callbackNode !== fakeCallbackNode) {
2624 Scheduler_cancelCallback(callbackNode);
2625 }
2626}
2627function flushSyncCallbackQueue() {
2628 if (immediateQueueCallbackNode !== null) {
2629 var node = immediateQueueCallbackNode;
2630 immediateQueueCallbackNode = null;
2631 Scheduler_cancelCallback(node);
2632 }
2633
2634 flushSyncCallbackQueueImpl();
2635}
2636
2637function flushSyncCallbackQueueImpl() {
2638 if (!isFlushingSyncQueue && syncQueue !== null) {
2639 // Prevent re-entrancy.
2640 isFlushingSyncQueue = true;
2641 var i = 0;
2642
2643 try {
2644 var _isSync = true;
2645 var queue = syncQueue;
2646 runWithPriority(ImmediatePriority, function () {
2647 for (; i < queue.length; i++) {
2648 var callback = queue[i];
2649
2650 do {
2651 callback = callback(_isSync);
2652 } while (callback !== null);
2653 }
2654 });
2655 syncQueue = null;
2656 } catch (error) {
2657 // If something throws, leave the remaining callbacks on the queue.
2658 if (syncQueue !== null) {
2659 syncQueue = syncQueue.slice(i + 1);
2660 } // Resume flushing in the next tick
2661
2662
2663 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
2664 throw error;
2665 } finally {
2666 isFlushingSyncQueue = false;
2667 }
2668 }
2669}
2670
2671var NoMode = 0;
2672var StrictMode = 1; // TODO: Remove BatchedMode and ConcurrentMode by reading from the root
2673// tag instead
2674
2675var BatchedMode = 2;
2676var ConcurrentMode = 4;
2677var ProfileMode = 8;
2678
2679// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2680// Math.pow(2, 30) - 1
2681// 0b111111111111111111111111111111
2682var MAX_SIGNED_31_BIT_INT = 1073741823;
2683
2684var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
2685// Never work can be committed in an inconsistent state without tearing the UI.
2686// The main example is offscreen content, like a hidden subtree. So one possible
2687// name is Offscreen. However, it also includes dehydrated Suspense boundaries,
2688// which are inconsistent in the sense that they haven't finished yet, but
2689// aren't visibly inconsistent because the server rendered HTML matches what the
2690// hydrated tree would look like.
2691
2692var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
2693// order to be consistent.
2694
2695var Idle = 2;
2696var Sync = MAX_SIGNED_31_BIT_INT;
2697var Batched = Sync - 1;
2698var UNIT_SIZE = 10;
2699var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
2700
2701function msToExpirationTime(ms) {
2702 // Always add an offset so that we don't clash with the magic number for NoWork.
2703 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2704}
2705function expirationTimeToMs(expirationTime) {
2706 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2707}
2708
2709function ceiling(num, precision) {
2710 return ((num / precision | 0) + 1) * precision;
2711}
2712
2713function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2714 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2715} // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
2716// the names to reflect.
2717
2718
2719var LOW_PRIORITY_EXPIRATION = 5000;
2720var LOW_PRIORITY_BATCH_SIZE = 250;
2721function computeAsyncExpiration(currentTime) {
2722 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2723}
2724function computeSuspenseExpiration(currentTime, timeoutMs) {
2725 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
2726 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
2727} // We intentionally set a higher expiration time for interactive updates in
2728// dev than in production.
2729//
2730// If the main thread is being blocked so long that you hit the expiration,
2731// it's a problem that could be solved with better scheduling.
2732//
2733// People will be more likely to notice this and fix it with the long
2734// expiration time in development.
2735//
2736// In production we opt for better UX at the risk of masking scheduling
2737// problems, by expiring fast.
2738
2739var HIGH_PRIORITY_EXPIRATION = 500;
2740var HIGH_PRIORITY_BATCH_SIZE = 100;
2741function computeInteractiveExpiration(currentTime) {
2742 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2743}
2744function inferPriorityFromExpirationTime(currentTime, expirationTime) {
2745 if (expirationTime === Sync) {
2746 return ImmediatePriority;
2747 }
2748
2749 if (expirationTime === Never || expirationTime === Idle) {
2750 return IdlePriority;
2751 }
2752
2753 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
2754
2755 if (msUntil <= 0) {
2756 return ImmediatePriority;
2757 }
2758
2759 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
2760 return UserBlockingPriority;
2761 }
2762
2763 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
2764 return NormalPriority;
2765 } // TODO: Handle LowPriority
2766 // Assume anything lower has idle priority
2767
2768
2769 return IdlePriority;
2770}
2771
2772/**
2773 * inlined Object.is polyfill to avoid requiring consumers ship their own
2774 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2775 */
2776function is(x, y) {
2777 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2778 ;
2779}
2780
2781var is$1 = typeof Object.is === 'function' ? Object.is : is;
2782
2783var hasOwnProperty = Object.prototype.hasOwnProperty;
2784/**
2785 * Performs equality by iterating through keys on an object and returning false
2786 * when any key has values which are not strictly equal between the arguments.
2787 * Returns true when the values of all keys are strictly equal.
2788 */
2789
2790function shallowEqual(objA, objB) {
2791 if (is$1(objA, objB)) {
2792 return true;
2793 }
2794
2795 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2796 return false;
2797 }
2798
2799 var keysA = Object.keys(objA);
2800 var keysB = Object.keys(objB);
2801
2802 if (keysA.length !== keysB.length) {
2803 return false;
2804 } // Test for A's keys different from B.
2805
2806
2807 for (var i = 0; i < keysA.length; i++) {
2808 if (!hasOwnProperty.call(objB, keysA[i]) || !is$1(objA[keysA[i]], objB[keysA[i]])) {
2809 return false;
2810 }
2811 }
2812
2813 return true;
2814}
2815
2816/**
2817 * Forked from fbjs/warning:
2818 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2819 *
2820 * Only change is we use console.warn instead of console.error,
2821 * and do nothing when 'console' is not supported.
2822 * This really simplifies the code.
2823 * ---
2824 * Similar to invariant but only logs a warning if the condition is not met.
2825 * This can be used to log issues in development environments in critical
2826 * paths. Removing the logging code for production environments will keep the
2827 * same logic and follow the same code paths.
2828 */
2829var lowPriorityWarningWithoutStack = function () {};
2830
2831{
2832 var printWarning$1 = function (format) {
2833 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2834 args[_key - 1] = arguments[_key];
2835 }
2836
2837 var argIndex = 0;
2838 var message = 'Warning: ' + format.replace(/%s/g, function () {
2839 return args[argIndex++];
2840 });
2841
2842 if (typeof console !== 'undefined') {
2843 console.warn(message);
2844 }
2845
2846 try {
2847 // --- Welcome to debugging React ---
2848 // This error was thrown as a convenience so that you can use this stack
2849 // to find the callsite that caused this warning to fire.
2850 throw new Error(message);
2851 } catch (x) {}
2852 };
2853
2854 lowPriorityWarningWithoutStack = function (condition, format) {
2855 if (format === undefined) {
2856 throw new Error('`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
2857 }
2858
2859 if (!condition) {
2860 for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
2861 args[_key2 - 2] = arguments[_key2];
2862 }
2863
2864 printWarning$1.apply(void 0, [format].concat(args));
2865 }
2866 };
2867}
2868
2869var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack;
2870
2871var ReactStrictModeWarnings = {
2872 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2873 flushPendingUnsafeLifecycleWarnings: function () {},
2874 recordLegacyContextWarning: function (fiber, instance) {},
2875 flushLegacyContextWarning: function () {},
2876 discardPendingWarnings: function () {}
2877};
2878
2879{
2880 var findStrictRoot = function (fiber) {
2881 var maybeStrictRoot = null;
2882 var node = fiber;
2883
2884 while (node !== null) {
2885 if (node.mode & StrictMode) {
2886 maybeStrictRoot = node;
2887 }
2888
2889 node = node.return;
2890 }
2891
2892 return maybeStrictRoot;
2893 };
2894
2895 var setToSortedString = function (set) {
2896 var array = [];
2897 set.forEach(function (value) {
2898 array.push(value);
2899 });
2900 return array.sort().join(', ');
2901 };
2902
2903 var pendingComponentWillMountWarnings = [];
2904 var pendingUNSAFE_ComponentWillMountWarnings = [];
2905 var pendingComponentWillReceivePropsWarnings = [];
2906 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2907 var pendingComponentWillUpdateWarnings = [];
2908 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
2909
2910 var didWarnAboutUnsafeLifecycles = new Set();
2911
2912 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2913 // Dedup strategy: Warn once per component.
2914 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2915 return;
2916 }
2917
2918 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
2919 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2920 pendingComponentWillMountWarnings.push(fiber);
2921 }
2922
2923 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2924 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2925 }
2926
2927 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2928 pendingComponentWillReceivePropsWarnings.push(fiber);
2929 }
2930
2931 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2932 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2933 }
2934
2935 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2936 pendingComponentWillUpdateWarnings.push(fiber);
2937 }
2938
2939 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2940 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2941 }
2942 };
2943
2944 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2945 // We do an initial pass to gather component names
2946 var componentWillMountUniqueNames = new Set();
2947
2948 if (pendingComponentWillMountWarnings.length > 0) {
2949 pendingComponentWillMountWarnings.forEach(function (fiber) {
2950 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2951 didWarnAboutUnsafeLifecycles.add(fiber.type);
2952 });
2953 pendingComponentWillMountWarnings = [];
2954 }
2955
2956 var UNSAFE_componentWillMountUniqueNames = new Set();
2957
2958 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2959 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2960 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2961 didWarnAboutUnsafeLifecycles.add(fiber.type);
2962 });
2963 pendingUNSAFE_ComponentWillMountWarnings = [];
2964 }
2965
2966 var componentWillReceivePropsUniqueNames = new Set();
2967
2968 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2969 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2970 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2971 didWarnAboutUnsafeLifecycles.add(fiber.type);
2972 });
2973 pendingComponentWillReceivePropsWarnings = [];
2974 }
2975
2976 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2977
2978 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2979 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2980 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2981 didWarnAboutUnsafeLifecycles.add(fiber.type);
2982 });
2983 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2984 }
2985
2986 var componentWillUpdateUniqueNames = new Set();
2987
2988 if (pendingComponentWillUpdateWarnings.length > 0) {
2989 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2990 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2991 didWarnAboutUnsafeLifecycles.add(fiber.type);
2992 });
2993 pendingComponentWillUpdateWarnings = [];
2994 }
2995
2996 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2997
2998 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2999 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
3000 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
3001 didWarnAboutUnsafeLifecycles.add(fiber.type);
3002 });
3003 pendingUNSAFE_ComponentWillUpdateWarnings = [];
3004 } // Finally, we flush all the warnings
3005 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
3006
3007
3008 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
3009 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
3010 warningWithoutStack$1(false, 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
3011 }
3012
3013 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
3014 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
3015
3016 warningWithoutStack$1(false, 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
3017 }
3018
3019 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
3020 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
3021
3022 warningWithoutStack$1(false, 'Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
3023 }
3024
3025 if (componentWillMountUniqueNames.size > 0) {
3026 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
3027
3028 lowPriorityWarningWithoutStack$1(false, 'componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
3029 }
3030
3031 if (componentWillReceivePropsUniqueNames.size > 0) {
3032 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
3033
3034 lowPriorityWarningWithoutStack$1(false, 'componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
3035 }
3036
3037 if (componentWillUpdateUniqueNames.size > 0) {
3038 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
3039
3040 lowPriorityWarningWithoutStack$1(false, 'componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
3041 }
3042 };
3043
3044 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
3045
3046 var didWarnAboutLegacyContext = new Set();
3047
3048 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
3049 var strictRoot = findStrictRoot(fiber);
3050
3051 if (strictRoot === null) {
3052 warningWithoutStack$1(false, 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
3053 return;
3054 } // Dedup strategy: Warn once per component.
3055
3056
3057 if (didWarnAboutLegacyContext.has(fiber.type)) {
3058 return;
3059 }
3060
3061 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
3062
3063 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
3064 if (warningsForRoot === undefined) {
3065 warningsForRoot = [];
3066 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
3067 }
3068
3069 warningsForRoot.push(fiber);
3070 }
3071 };
3072
3073 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
3074 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
3075 var uniqueNames = new Set();
3076 fiberArray.forEach(function (fiber) {
3077 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3078 didWarnAboutLegacyContext.add(fiber.type);
3079 });
3080 var sortedNames = setToSortedString(uniqueNames);
3081 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3082 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://fb.me/react-legacy-context' + '%s', sortedNames, strictRootComponentStack);
3083 });
3084 };
3085
3086 ReactStrictModeWarnings.discardPendingWarnings = function () {
3087 pendingComponentWillMountWarnings = [];
3088 pendingUNSAFE_ComponentWillMountWarnings = [];
3089 pendingComponentWillReceivePropsWarnings = [];
3090 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
3091 pendingComponentWillUpdateWarnings = [];
3092 pendingUNSAFE_ComponentWillUpdateWarnings = [];
3093 pendingLegacyContextWarning = new Map();
3094 };
3095}
3096
3097var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
3098
3099var failedBoundaries = null;
3100var setRefreshHandler = function (handler) {
3101 {
3102 resolveFamily = handler;
3103 }
3104};
3105function resolveFunctionForHotReloading(type) {
3106 {
3107 if (resolveFamily === null) {
3108 // Hot reloading is disabled.
3109 return type;
3110 }
3111
3112 var family = resolveFamily(type);
3113
3114 if (family === undefined) {
3115 return type;
3116 } // Use the latest known implementation.
3117
3118
3119 return family.current;
3120 }
3121}
3122function resolveClassForHotReloading(type) {
3123 // No implementation differences.
3124 return resolveFunctionForHotReloading(type);
3125}
3126function resolveForwardRefForHotReloading(type) {
3127 {
3128 if (resolveFamily === null) {
3129 // Hot reloading is disabled.
3130 return type;
3131 }
3132
3133 var family = resolveFamily(type);
3134
3135 if (family === undefined) {
3136 // Check if we're dealing with a real forwardRef. Don't want to crash early.
3137 if (type !== null && type !== undefined && typeof type.render === 'function') {
3138 // ForwardRef is special because its resolved .type is an object,
3139 // but it's possible that we only have its inner render function in the map.
3140 // If that inner render function is different, we'll build a new forwardRef type.
3141 var currentRender = resolveFunctionForHotReloading(type.render);
3142
3143 if (type.render !== currentRender) {
3144 var syntheticType = {
3145 $$typeof: REACT_FORWARD_REF_TYPE,
3146 render: currentRender
3147 };
3148
3149 if (type.displayName !== undefined) {
3150 syntheticType.displayName = type.displayName;
3151 }
3152
3153 return syntheticType;
3154 }
3155 }
3156
3157 return type;
3158 } // Use the latest known implementation.
3159
3160
3161 return family.current;
3162 }
3163}
3164function isCompatibleFamilyForHotReloading(fiber, element) {
3165 {
3166 if (resolveFamily === null) {
3167 // Hot reloading is disabled.
3168 return false;
3169 }
3170
3171 var prevType = fiber.elementType;
3172 var nextType = element.type; // If we got here, we know types aren't === equal.
3173
3174 var needsCompareFamilies = false;
3175 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
3176
3177 switch (fiber.tag) {
3178 case ClassComponent:
3179 {
3180 if (typeof nextType === 'function') {
3181 needsCompareFamilies = true;
3182 }
3183
3184 break;
3185 }
3186
3187 case FunctionComponent:
3188 {
3189 if (typeof nextType === 'function') {
3190 needsCompareFamilies = true;
3191 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
3192 // We don't know the inner type yet.
3193 // We're going to assume that the lazy inner type is stable,
3194 // and so it is sufficient to avoid reconciling it away.
3195 // We're not going to unwrap or actually use the new lazy type.
3196 needsCompareFamilies = true;
3197 }
3198
3199 break;
3200 }
3201
3202 case ForwardRef:
3203 {
3204 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
3205 needsCompareFamilies = true;
3206 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
3207 needsCompareFamilies = true;
3208 }
3209
3210 break;
3211 }
3212
3213 case MemoComponent:
3214 case SimpleMemoComponent:
3215 {
3216 if ($$typeofNextType === REACT_MEMO_TYPE) {
3217 // TODO: if it was but can no longer be simple,
3218 // we shouldn't set this.
3219 needsCompareFamilies = true;
3220 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
3221 needsCompareFamilies = true;
3222 }
3223
3224 break;
3225 }
3226
3227 default:
3228 return false;
3229 } // Check if both types have a family and it's the same one.
3230
3231
3232 if (needsCompareFamilies) {
3233 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
3234 // This means both of them need to be registered to preserve state.
3235 // If we unwrapped and compared the inner types for wrappers instead,
3236 // then we would risk falsely saying two separate memo(Foo)
3237 // calls are equivalent because they wrap the same Foo function.
3238 var prevFamily = resolveFamily(prevType);
3239
3240 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
3241 return true;
3242 }
3243 }
3244
3245 return false;
3246 }
3247}
3248function markFailedErrorBoundaryForHotReloading(fiber) {
3249 {
3250 if (resolveFamily === null) {
3251 // Hot reloading is disabled.
3252 return;
3253 }
3254
3255 if (typeof WeakSet !== 'function') {
3256 return;
3257 }
3258
3259 if (failedBoundaries === null) {
3260 failedBoundaries = new WeakSet();
3261 }
3262
3263 failedBoundaries.add(fiber);
3264 }
3265}
3266var scheduleRefresh = function (root, update) {
3267 {
3268 if (resolveFamily === null) {
3269 // Hot reloading is disabled.
3270 return;
3271 }
3272
3273 var staleFamilies = update.staleFamilies,
3274 updatedFamilies = update.updatedFamilies;
3275 flushPassiveEffects();
3276 flushSync(function () {
3277 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
3278 });
3279 }
3280};
3281var scheduleRoot = function (root, element) {
3282 {
3283 if (root.context !== emptyContextObject) {
3284 // Super edge case: root has a legacy _renderSubtree context
3285 // but we don't know the parentComponent so we can't pass it.
3286 // Just ignore. We'll delete this with _renderSubtree code path later.
3287 return;
3288 }
3289
3290 flushPassiveEffects();
3291 updateContainerAtExpirationTime(element, root, null, Sync, null);
3292 }
3293};
3294
3295function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
3296 {
3297 var alternate = fiber.alternate,
3298 child = fiber.child,
3299 sibling = fiber.sibling,
3300 tag = fiber.tag,
3301 type = fiber.type;
3302 var candidateType = null;
3303
3304 switch (tag) {
3305 case FunctionComponent:
3306 case SimpleMemoComponent:
3307 case ClassComponent:
3308 candidateType = type;
3309 break;
3310
3311 case ForwardRef:
3312 candidateType = type.render;
3313 break;
3314
3315 default:
3316 break;
3317 }
3318
3319 if (resolveFamily === null) {
3320 throw new Error('Expected resolveFamily to be set during hot reload.');
3321 }
3322
3323 var needsRender = false;
3324 var needsRemount = false;
3325
3326 if (candidateType !== null) {
3327 var family = resolveFamily(candidateType);
3328
3329 if (family !== undefined) {
3330 if (staleFamilies.has(family)) {
3331 needsRemount = true;
3332 } else if (updatedFamilies.has(family)) {
3333 if (tag === ClassComponent) {
3334 needsRemount = true;
3335 } else {
3336 needsRender = true;
3337 }
3338 }
3339 }
3340 }
3341
3342 if (failedBoundaries !== null) {
3343 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
3344 needsRemount = true;
3345 }
3346 }
3347
3348 if (needsRemount) {
3349 fiber._debugNeedsRemount = true;
3350 }
3351
3352 if (needsRemount || needsRender) {
3353 scheduleWork(fiber, Sync);
3354 }
3355
3356 if (child !== null && !needsRemount) {
3357 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
3358 }
3359
3360 if (sibling !== null) {
3361 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
3362 }
3363 }
3364}
3365
3366var findHostInstancesForRefresh = function (root, families) {
3367 {
3368 var hostInstances = new Set();
3369 var types = new Set(families.map(function (family) {
3370 return family.current;
3371 }));
3372 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
3373 return hostInstances;
3374 }
3375};
3376
3377function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
3378 {
3379 var child = fiber.child,
3380 sibling = fiber.sibling,
3381 tag = fiber.tag,
3382 type = fiber.type;
3383 var candidateType = null;
3384
3385 switch (tag) {
3386 case FunctionComponent:
3387 case SimpleMemoComponent:
3388 case ClassComponent:
3389 candidateType = type;
3390 break;
3391
3392 case ForwardRef:
3393 candidateType = type.render;
3394 break;
3395
3396 default:
3397 break;
3398 }
3399
3400 var didMatch = false;
3401
3402 if (candidateType !== null) {
3403 if (types.has(candidateType)) {
3404 didMatch = true;
3405 }
3406 }
3407
3408 if (didMatch) {
3409 // We have a match. This only drills down to the closest host components.
3410 // There's no need to search deeper because for the purpose of giving
3411 // visual feedback, "flashing" outermost parent rectangles is sufficient.
3412 findHostInstancesForFiberShallowly(fiber, hostInstances);
3413 } else {
3414 // If there's no match, maybe there will be one further down in the child tree.
3415 if (child !== null) {
3416 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
3417 }
3418 }
3419
3420 if (sibling !== null) {
3421 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
3422 }
3423 }
3424}
3425
3426function findHostInstancesForFiberShallowly(fiber, hostInstances) {
3427 {
3428 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
3429
3430 if (foundHostInstances) {
3431 return;
3432 } // If we didn't find any host children, fallback to closest host parent.
3433
3434
3435 var node = fiber;
3436
3437 while (true) {
3438 switch (node.tag) {
3439 case HostComponent:
3440 hostInstances.add(node.stateNode);
3441 return;
3442
3443 case HostPortal:
3444 hostInstances.add(node.stateNode.containerInfo);
3445 return;
3446
3447 case HostRoot:
3448 hostInstances.add(node.stateNode.containerInfo);
3449 return;
3450 }
3451
3452 if (node.return === null) {
3453 throw new Error('Expected to reach root first.');
3454 }
3455
3456 node = node.return;
3457 }
3458 }
3459}
3460
3461function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
3462 {
3463 var node = fiber;
3464 var foundHostInstances = false;
3465
3466 while (true) {
3467 if (node.tag === HostComponent) {
3468 // We got a match.
3469 foundHostInstances = true;
3470 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
3471 } else if (node.child !== null) {
3472 node.child.return = node;
3473 node = node.child;
3474 continue;
3475 }
3476
3477 if (node === fiber) {
3478 return foundHostInstances;
3479 }
3480
3481 while (node.sibling === null) {
3482 if (node.return === null || node.return === fiber) {
3483 return foundHostInstances;
3484 }
3485
3486 node = node.return;
3487 }
3488
3489 node.sibling.return = node.return;
3490 node = node.sibling;
3491 }
3492 }
3493
3494 return false;
3495}
3496
3497function resolveDefaultProps(Component, baseProps) {
3498 if (Component && Component.defaultProps) {
3499 // Resolve default props. Taken from ReactElement
3500 var props = _assign({}, baseProps);
3501
3502 var defaultProps = Component.defaultProps;
3503
3504 for (var propName in defaultProps) {
3505 if (props[propName] === undefined) {
3506 props[propName] = defaultProps[propName];
3507 }
3508 }
3509
3510 return props;
3511 }
3512
3513 return baseProps;
3514}
3515function readLazyComponentType(lazyComponent) {
3516 initializeLazyComponentType(lazyComponent);
3517
3518 if (lazyComponent._status !== Resolved) {
3519 throw lazyComponent._result;
3520 }
3521
3522 return lazyComponent._result;
3523}
3524
3525var valueCursor = createCursor(null);
3526var rendererSigil;
3527
3528{
3529 // Use this to detect multiple renderers using the same context
3530 rendererSigil = {};
3531}
3532
3533var currentlyRenderingFiber = null;
3534var lastContextDependency = null;
3535var lastContextWithAllBitsObserved = null;
3536var isDisallowedContextReadInDEV = false;
3537function resetContextDependencies() {
3538 // This is called right before React yields execution, to ensure `readContext`
3539 // cannot be called outside the render phase.
3540 currentlyRenderingFiber = null;
3541 lastContextDependency = null;
3542 lastContextWithAllBitsObserved = null;
3543
3544 {
3545 isDisallowedContextReadInDEV = false;
3546 }
3547}
3548function enterDisallowedContextReadInDEV() {
3549 {
3550 isDisallowedContextReadInDEV = true;
3551 }
3552}
3553function exitDisallowedContextReadInDEV() {
3554 {
3555 isDisallowedContextReadInDEV = false;
3556 }
3557}
3558function pushProvider(providerFiber, nextValue) {
3559 var context = providerFiber.type._context;
3560
3561 if (isPrimaryRenderer) {
3562 push(valueCursor, context._currentValue, providerFiber);
3563 context._currentValue = nextValue;
3564
3565 {
3566 !(context._currentRenderer === undefined || context._currentRenderer === null || context._currentRenderer === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
3567 context._currentRenderer = rendererSigil;
3568 }
3569 } else {
3570 push(valueCursor, context._currentValue2, providerFiber);
3571 context._currentValue2 = nextValue;
3572
3573 {
3574 !(context._currentRenderer2 === undefined || context._currentRenderer2 === null || context._currentRenderer2 === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
3575 context._currentRenderer2 = rendererSigil;
3576 }
3577 }
3578}
3579function popProvider(providerFiber) {
3580 var currentValue = valueCursor.current;
3581 pop(valueCursor, providerFiber);
3582 var context = providerFiber.type._context;
3583
3584 if (isPrimaryRenderer) {
3585 context._currentValue = currentValue;
3586 } else {
3587 context._currentValue2 = currentValue;
3588 }
3589}
3590function calculateChangedBits(context, newValue, oldValue) {
3591 if (is$1(oldValue, newValue)) {
3592 // No change
3593 return 0;
3594 } else {
3595 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
3596
3597 {
3598 !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
3599 }
3600
3601 return changedBits | 0;
3602 }
3603}
3604function scheduleWorkOnParentPath(parent, renderExpirationTime) {
3605 // Update the child expiration time of all the ancestors, including
3606 // the alternates.
3607 var node = parent;
3608
3609 while (node !== null) {
3610 var alternate = node.alternate;
3611
3612 if (node.childExpirationTime < renderExpirationTime) {
3613 node.childExpirationTime = renderExpirationTime;
3614
3615 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3616 alternate.childExpirationTime = renderExpirationTime;
3617 }
3618 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3619 alternate.childExpirationTime = renderExpirationTime;
3620 } else {
3621 // Neither alternate was updated, which means the rest of the
3622 // ancestor path already has sufficient priority.
3623 break;
3624 }
3625
3626 node = node.return;
3627 }
3628}
3629function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
3630 var fiber = workInProgress.child;
3631
3632 if (fiber !== null) {
3633 // Set the return pointer of the child to the work-in-progress fiber.
3634 fiber.return = workInProgress;
3635 }
3636
3637 while (fiber !== null) {
3638 var nextFiber = void 0; // Visit this fiber.
3639
3640 var list = fiber.dependencies;
3641
3642 if (list !== null) {
3643 nextFiber = fiber.child;
3644 var dependency = list.firstContext;
3645
3646 while (dependency !== null) {
3647 // Check if the context matches.
3648 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
3649 // Match! Schedule an update on this fiber.
3650 if (fiber.tag === ClassComponent) {
3651 // Schedule a force update on the work-in-progress.
3652 var update = createUpdate(renderExpirationTime, null);
3653 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
3654 // update to the current fiber, too, which means it will persist even if
3655 // this render is thrown away. Since it's a race condition, not sure it's
3656 // worth fixing.
3657
3658 enqueueUpdate(fiber, update);
3659 }
3660
3661 if (fiber.expirationTime < renderExpirationTime) {
3662 fiber.expirationTime = renderExpirationTime;
3663 }
3664
3665 var alternate = fiber.alternate;
3666
3667 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
3668 alternate.expirationTime = renderExpirationTime;
3669 }
3670
3671 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
3672
3673 if (list.expirationTime < renderExpirationTime) {
3674 list.expirationTime = renderExpirationTime;
3675 } // Since we already found a match, we can stop traversing the
3676 // dependency list.
3677
3678
3679 break;
3680 }
3681
3682 dependency = dependency.next;
3683 }
3684 } else if (fiber.tag === ContextProvider) {
3685 // Don't scan deeper if this is a matching provider
3686 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
3687 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedFragment) {
3688 // If a dehydrated suspense bounudary is in this subtree, we don't know
3689 // if it will have any context consumers in it. The best we can do is
3690 // mark it as having updates.
3691 var parentSuspense = fiber.return;
3692
3693 (function () {
3694 if (!(parentSuspense !== null)) {
3695 {
3696 throw ReactError(Error("We just came from a parent so we must have had a parent. This is a bug in React."));
3697 }
3698 }
3699 })();
3700
3701 if (parentSuspense.expirationTime < renderExpirationTime) {
3702 parentSuspense.expirationTime = renderExpirationTime;
3703 }
3704
3705 var _alternate = parentSuspense.alternate;
3706
3707 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
3708 _alternate.expirationTime = renderExpirationTime;
3709 } // This is intentionally passing this fiber as the parent
3710 // because we want to schedule this fiber as having work
3711 // on its children. We'll use the childExpirationTime on
3712 // this fiber to indicate that a context has changed.
3713
3714
3715 scheduleWorkOnParentPath(parentSuspense, renderExpirationTime);
3716 nextFiber = fiber.sibling;
3717 } else {
3718 // Traverse down.
3719 nextFiber = fiber.child;
3720 }
3721
3722 if (nextFiber !== null) {
3723 // Set the return pointer of the child to the work-in-progress fiber.
3724 nextFiber.return = fiber;
3725 } else {
3726 // No child. Traverse to next sibling.
3727 nextFiber = fiber;
3728
3729 while (nextFiber !== null) {
3730 if (nextFiber === workInProgress) {
3731 // We're back to the root of this subtree. Exit.
3732 nextFiber = null;
3733 break;
3734 }
3735
3736 var sibling = nextFiber.sibling;
3737
3738 if (sibling !== null) {
3739 // Set the return pointer of the sibling to the work-in-progress fiber.
3740 sibling.return = nextFiber.return;
3741 nextFiber = sibling;
3742 break;
3743 } // No more siblings. Traverse up.
3744
3745
3746 nextFiber = nextFiber.return;
3747 }
3748 }
3749
3750 fiber = nextFiber;
3751 }
3752}
3753function prepareToReadContext(workInProgress, renderExpirationTime) {
3754 currentlyRenderingFiber = workInProgress;
3755 lastContextDependency = null;
3756 lastContextWithAllBitsObserved = null;
3757 var dependencies = workInProgress.dependencies;
3758
3759 if (dependencies !== null) {
3760 var firstContext = dependencies.firstContext;
3761
3762 if (firstContext !== null) {
3763 if (dependencies.expirationTime >= renderExpirationTime) {
3764 // Context list has a pending update. Mark that this fiber performed work.
3765 markWorkInProgressReceivedUpdate();
3766 } // Reset the work-in-progress list
3767
3768
3769 dependencies.firstContext = null;
3770 }
3771 }
3772}
3773function readContext(context, observedBits) {
3774 {
3775 // This warning would fire if you read context inside a Hook like useMemo.
3776 // Unlike the class check below, it's not enforced in production for perf.
3777 !!isDisallowedContextReadInDEV ? warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().') : void 0;
3778 }
3779
3780 if (lastContextWithAllBitsObserved === context) {// Nothing to do. We already observe everything in this context.
3781 } else if (observedBits === false || observedBits === 0) {// Do not observe any updates.
3782 } else {
3783 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
3784
3785 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
3786 // Observe all updates.
3787 lastContextWithAllBitsObserved = context;
3788 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
3789 } else {
3790 resolvedObservedBits = observedBits;
3791 }
3792
3793 var contextItem = {
3794 context: context,
3795 observedBits: resolvedObservedBits,
3796 next: null
3797 };
3798
3799 if (lastContextDependency === null) {
3800 (function () {
3801 if (!(currentlyRenderingFiber !== null)) {
3802 {
3803 throw ReactError(Error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()."));
3804 }
3805 }
3806 })(); // This is the first dependency for this component. Create a new list.
3807
3808
3809 lastContextDependency = contextItem;
3810 currentlyRenderingFiber.dependencies = {
3811 expirationTime: NoWork,
3812 firstContext: contextItem,
3813 responders: null
3814 };
3815 } else {
3816 // Append a new context item.
3817 lastContextDependency = lastContextDependency.next = contextItem;
3818 }
3819 }
3820
3821 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
3822}
3823
3824// UpdateQueue is a linked list of prioritized updates.
3825//
3826// Like fibers, update queues come in pairs: a current queue, which represents
3827// the visible state of the screen, and a work-in-progress queue, which can be
3828// mutated and processed asynchronously before it is committed — a form of
3829// double buffering. If a work-in-progress render is discarded before finishing,
3830// we create a new work-in-progress by cloning the current queue.
3831//
3832// Both queues share a persistent, singly-linked list structure. To schedule an
3833// update, we append it to the end of both queues. Each queue maintains a
3834// pointer to first update in the persistent list that hasn't been processed.
3835// The work-in-progress pointer always has a position equal to or greater than
3836// the current queue, since we always work on that one. The current queue's
3837// pointer is only updated during the commit phase, when we swap in the
3838// work-in-progress.
3839//
3840// For example:
3841//
3842// Current pointer: A - B - C - D - E - F
3843// Work-in-progress pointer: D - E - F
3844// ^
3845// The work-in-progress queue has
3846// processed more updates than current.
3847//
3848// The reason we append to both queues is because otherwise we might drop
3849// updates without ever processing them. For example, if we only add updates to
3850// the work-in-progress queue, some updates could be lost whenever a work-in
3851// -progress render restarts by cloning from current. Similarly, if we only add
3852// updates to the current queue, the updates will be lost whenever an already
3853// in-progress queue commits and swaps with the current queue. However, by
3854// adding to both queues, we guarantee that the update will be part of the next
3855// work-in-progress. (And because the work-in-progress queue becomes the
3856// current queue once it commits, there's no danger of applying the same
3857// update twice.)
3858//
3859// Prioritization
3860// --------------
3861//
3862// Updates are not sorted by priority, but by insertion; new updates are always
3863// appended to the end of the list.
3864//
3865// The priority is still important, though. When processing the update queue
3866// during the render phase, only the updates with sufficient priority are
3867// included in the result. If we skip an update because it has insufficient
3868// priority, it remains in the queue to be processed later, during a lower
3869// priority render. Crucially, all updates subsequent to a skipped update also
3870// remain in the queue *regardless of their priority*. That means high priority
3871// updates are sometimes processed twice, at two separate priorities. We also
3872// keep track of a base state, that represents the state before the first
3873// update in the queue is applied.
3874//
3875// For example:
3876//
3877// Given a base state of '', and the following queue of updates
3878//
3879// A1 - B2 - C1 - D2
3880//
3881// where the number indicates the priority, and the update is applied to the
3882// previous state by appending a letter, React will process these updates as
3883// two separate renders, one per distinct priority level:
3884//
3885// First render, at priority 1:
3886// Base state: ''
3887// Updates: [A1, C1]
3888// Result state: 'AC'
3889//
3890// Second render, at priority 2:
3891// Base state: 'A' <- The base state does not include C1,
3892// because B2 was skipped.
3893// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
3894// Result state: 'ABCD'
3895//
3896// Because we process updates in insertion order, and rebase high priority
3897// updates when preceding updates are skipped, the final result is deterministic
3898// regardless of priority. Intermediate state may vary according to system
3899// resources, but the final state is always the same.
3900var UpdateState = 0;
3901var ReplaceState = 1;
3902var ForceUpdate = 2;
3903var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
3904// It should only be read right after calling `processUpdateQueue`, via
3905// `checkHasForceUpdateAfterProcessing`.
3906
3907var hasForceUpdate = false;
3908var didWarnUpdateInsideUpdate;
3909var currentlyProcessingQueue;
3910
3911
3912{
3913 didWarnUpdateInsideUpdate = false;
3914 currentlyProcessingQueue = null;
3915
3916
3917}
3918
3919function createUpdateQueue(baseState) {
3920 var queue = {
3921 baseState: baseState,
3922 firstUpdate: null,
3923 lastUpdate: null,
3924 firstCapturedUpdate: null,
3925 lastCapturedUpdate: null,
3926 firstEffect: null,
3927 lastEffect: null,
3928 firstCapturedEffect: null,
3929 lastCapturedEffect: null
3930 };
3931 return queue;
3932}
3933
3934function cloneUpdateQueue(currentQueue) {
3935 var queue = {
3936 baseState: currentQueue.baseState,
3937 firstUpdate: currentQueue.firstUpdate,
3938 lastUpdate: currentQueue.lastUpdate,
3939 // TODO: With resuming, if we bail out and resuse the child tree, we should
3940 // keep these effects.
3941 firstCapturedUpdate: null,
3942 lastCapturedUpdate: null,
3943 firstEffect: null,
3944 lastEffect: null,
3945 firstCapturedEffect: null,
3946 lastCapturedEffect: null
3947 };
3948 return queue;
3949}
3950
3951function createUpdate(expirationTime, suspenseConfig) {
3952 var update = {
3953 expirationTime: expirationTime,
3954 suspenseConfig: suspenseConfig,
3955 tag: UpdateState,
3956 payload: null,
3957 callback: null,
3958 next: null,
3959 nextEffect: null
3960 };
3961
3962 {
3963 update.priority = getCurrentPriorityLevel();
3964 }
3965
3966 return update;
3967}
3968
3969function appendUpdateToQueue(queue, update) {
3970 // Append the update to the end of the list.
3971 if (queue.lastUpdate === null) {
3972 // Queue is empty
3973 queue.firstUpdate = queue.lastUpdate = update;
3974 } else {
3975 queue.lastUpdate.next = update;
3976 queue.lastUpdate = update;
3977 }
3978}
3979
3980function enqueueUpdate(fiber, update) {
3981 // Update queues are created lazily.
3982 var alternate = fiber.alternate;
3983 var queue1;
3984 var queue2;
3985
3986 if (alternate === null) {
3987 // There's only one fiber.
3988 queue1 = fiber.updateQueue;
3989 queue2 = null;
3990
3991 if (queue1 === null) {
3992 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
3993 }
3994 } else {
3995 // There are two owners.
3996 queue1 = fiber.updateQueue;
3997 queue2 = alternate.updateQueue;
3998
3999 if (queue1 === null) {
4000 if (queue2 === null) {
4001 // Neither fiber has an update queue. Create new ones.
4002 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
4003 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
4004 } else {
4005 // Only one fiber has an update queue. Clone to create a new one.
4006 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
4007 }
4008 } else {
4009 if (queue2 === null) {
4010 // Only one fiber has an update queue. Clone to create a new one.
4011 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
4012 } else {// Both owners have an update queue.
4013 }
4014 }
4015 }
4016
4017 if (queue2 === null || queue1 === queue2) {
4018 // There's only a single queue.
4019 appendUpdateToQueue(queue1, update);
4020 } else {
4021 // There are two queues. We need to append the update to both queues,
4022 // while accounting for the persistent structure of the list — we don't
4023 // want the same update to be added multiple times.
4024 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
4025 // One of the queues is not empty. We must add the update to both queues.
4026 appendUpdateToQueue(queue1, update);
4027 appendUpdateToQueue(queue2, update);
4028 } else {
4029 // Both queues are non-empty. The last update is the same in both lists,
4030 // because of structural sharing. So, only append to one of the lists.
4031 appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2.
4032
4033 queue2.lastUpdate = update;
4034 }
4035 }
4036
4037 {
4038 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
4039 warningWithoutStack$1(false, 'An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
4040 didWarnUpdateInsideUpdate = true;
4041 }
4042 }
4043}
4044function enqueueCapturedUpdate(workInProgress, update) {
4045 // Captured updates go into a separate list, and only on the work-in-
4046 // progress queue.
4047 var workInProgressQueue = workInProgress.updateQueue;
4048
4049 if (workInProgressQueue === null) {
4050 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
4051 } else {
4052 // TODO: I put this here rather than createWorkInProgress so that we don't
4053 // clone the queue unnecessarily. There's probably a better way to
4054 // structure this.
4055 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
4056 } // Append the update to the end of the list.
4057
4058
4059 if (workInProgressQueue.lastCapturedUpdate === null) {
4060 // This is the first render phase update
4061 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
4062 } else {
4063 workInProgressQueue.lastCapturedUpdate.next = update;
4064 workInProgressQueue.lastCapturedUpdate = update;
4065 }
4066}
4067
4068function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
4069 var current = workInProgress.alternate;
4070
4071 if (current !== null) {
4072 // If the work-in-progress queue is equal to the current queue,
4073 // we need to clone it first.
4074 if (queue === current.updateQueue) {
4075 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
4076 }
4077 }
4078
4079 return queue;
4080}
4081
4082function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
4083 switch (update.tag) {
4084 case ReplaceState:
4085 {
4086 var payload = update.payload;
4087
4088 if (typeof payload === 'function') {
4089 // Updater function
4090 {
4091 enterDisallowedContextReadInDEV();
4092
4093 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4094 payload.call(instance, prevState, nextProps);
4095 }
4096 }
4097
4098 var nextState = payload.call(instance, prevState, nextProps);
4099
4100 {
4101 exitDisallowedContextReadInDEV();
4102 }
4103
4104 return nextState;
4105 } // State object
4106
4107
4108 return payload;
4109 }
4110
4111 case CaptureUpdate:
4112 {
4113 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
4114 }
4115 // Intentional fallthrough
4116
4117 case UpdateState:
4118 {
4119 var _payload = update.payload;
4120 var partialState;
4121
4122 if (typeof _payload === 'function') {
4123 // Updater function
4124 {
4125 enterDisallowedContextReadInDEV();
4126
4127 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4128 _payload.call(instance, prevState, nextProps);
4129 }
4130 }
4131
4132 partialState = _payload.call(instance, prevState, nextProps);
4133
4134 {
4135 exitDisallowedContextReadInDEV();
4136 }
4137 } else {
4138 // Partial state object
4139 partialState = _payload;
4140 }
4141
4142 if (partialState === null || partialState === undefined) {
4143 // Null and undefined are treated as no-ops.
4144 return prevState;
4145 } // Merge the partial state and the previous state.
4146
4147
4148 return _assign({}, prevState, partialState);
4149 }
4150
4151 case ForceUpdate:
4152 {
4153 hasForceUpdate = true;
4154 return prevState;
4155 }
4156 }
4157
4158 return prevState;
4159}
4160
4161function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
4162 hasForceUpdate = false;
4163 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
4164
4165 {
4166 currentlyProcessingQueue = queue;
4167 } // These values may change as we process the queue.
4168
4169
4170 var newBaseState = queue.baseState;
4171 var newFirstUpdate = null;
4172 var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result.
4173
4174 var update = queue.firstUpdate;
4175 var resultState = newBaseState;
4176
4177 while (update !== null) {
4178 var updateExpirationTime = update.expirationTime;
4179
4180 if (updateExpirationTime < renderExpirationTime) {
4181 // This update does not have sufficient priority. Skip it.
4182 if (newFirstUpdate === null) {
4183 // This is the first skipped update. It will be the first update in
4184 // the new list.
4185 newFirstUpdate = update; // Since this is the first update that was skipped, the current result
4186 // is the new base state.
4187
4188 newBaseState = resultState;
4189 } // Since this update will remain in the list, update the remaining
4190 // expiration time.
4191
4192
4193 if (newExpirationTime < updateExpirationTime) {
4194 newExpirationTime = updateExpirationTime;
4195 }
4196 } else {
4197 // This update does have sufficient priority.
4198 // Mark the event time of this update as relevant to this render pass.
4199 // TODO: This should ideally use the true event time of this update rather than
4200 // its priority which is a derived and not reverseable value.
4201 // TODO: We should skip this update if it was already committed but currently
4202 // we have no way of detecting the difference between a committed and suspended
4203 // update here.
4204 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result.
4205
4206 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
4207 var callback = update.callback;
4208
4209 if (callback !== null) {
4210 workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render.
4211
4212 update.nextEffect = null;
4213
4214 if (queue.lastEffect === null) {
4215 queue.firstEffect = queue.lastEffect = update;
4216 } else {
4217 queue.lastEffect.nextEffect = update;
4218 queue.lastEffect = update;
4219 }
4220 }
4221 } // Continue to the next update.
4222
4223
4224 update = update.next;
4225 } // Separately, iterate though the list of captured updates.
4226
4227
4228 var newFirstCapturedUpdate = null;
4229 update = queue.firstCapturedUpdate;
4230
4231 while (update !== null) {
4232 var _updateExpirationTime = update.expirationTime;
4233
4234 if (_updateExpirationTime < renderExpirationTime) {
4235 // This update does not have sufficient priority. Skip it.
4236 if (newFirstCapturedUpdate === null) {
4237 // This is the first skipped captured update. It will be the first
4238 // update in the new list.
4239 newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is
4240 // the new base state.
4241
4242 if (newFirstUpdate === null) {
4243 newBaseState = resultState;
4244 }
4245 } // Since this update will remain in the list, update the remaining
4246 // expiration time.
4247
4248
4249 if (newExpirationTime < _updateExpirationTime) {
4250 newExpirationTime = _updateExpirationTime;
4251 }
4252 } else {
4253 // This update does have sufficient priority. Process it and compute
4254 // a new result.
4255 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
4256 var _callback = update.callback;
4257
4258 if (_callback !== null) {
4259 workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render.
4260
4261 update.nextEffect = null;
4262
4263 if (queue.lastCapturedEffect === null) {
4264 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
4265 } else {
4266 queue.lastCapturedEffect.nextEffect = update;
4267 queue.lastCapturedEffect = update;
4268 }
4269 }
4270 }
4271
4272 update = update.next;
4273 }
4274
4275 if (newFirstUpdate === null) {
4276 queue.lastUpdate = null;
4277 }
4278
4279 if (newFirstCapturedUpdate === null) {
4280 queue.lastCapturedUpdate = null;
4281 } else {
4282 workInProgress.effectTag |= Callback;
4283 }
4284
4285 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
4286 // We processed every update, without skipping. That means the new base
4287 // state is the same as the result state.
4288 newBaseState = resultState;
4289 }
4290
4291 queue.baseState = newBaseState;
4292 queue.firstUpdate = newFirstUpdate;
4293 queue.firstCapturedUpdate = newFirstCapturedUpdate; // Set the remaining expiration time to be whatever is remaining in the queue.
4294 // This should be fine because the only two other things that contribute to
4295 // expiration time are props and context. We're already in the middle of the
4296 // begin phase by the time we start processing the queue, so we've already
4297 // dealt with the props. Context in components that specify
4298 // shouldComponentUpdate is tricky; but we'll have to account for
4299 // that regardless.
4300
4301 markUnprocessedUpdateTime(newExpirationTime);
4302 workInProgress.expirationTime = newExpirationTime;
4303 workInProgress.memoizedState = resultState;
4304
4305 {
4306 currentlyProcessingQueue = null;
4307 }
4308}
4309
4310function callCallback(callback, context) {
4311 (function () {
4312 if (!(typeof callback === 'function')) {
4313 {
4314 throw ReactError(Error("Invalid argument passed as callback. Expected a function. Instead received: " + callback));
4315 }
4316 }
4317 })();
4318
4319 callback.call(context);
4320}
4321
4322function resetHasForceUpdateBeforeProcessing() {
4323 hasForceUpdate = false;
4324}
4325function checkHasForceUpdateAfterProcessing() {
4326 return hasForceUpdate;
4327}
4328function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
4329 // If the finished render included captured updates, and there are still
4330 // lower priority updates left over, we need to keep the captured updates
4331 // in the queue so that they are rebased and not dropped once we process the
4332 // queue again at the lower priority.
4333 if (finishedQueue.firstCapturedUpdate !== null) {
4334 // Join the captured update list to the end of the normal list.
4335 if (finishedQueue.lastUpdate !== null) {
4336 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
4337 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
4338 } // Clear the list of captured updates.
4339
4340
4341 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
4342 } // Commit the effects
4343
4344
4345 commitUpdateEffects(finishedQueue.firstEffect, instance);
4346 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
4347 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
4348 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
4349}
4350
4351function commitUpdateEffects(effect, instance) {
4352 while (effect !== null) {
4353 var callback = effect.callback;
4354
4355 if (callback !== null) {
4356 effect.callback = null;
4357 callCallback(callback, instance);
4358 }
4359
4360 effect = effect.nextEffect;
4361 }
4362}
4363
4364var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
4365function requestCurrentSuspenseConfig() {
4366 return ReactCurrentBatchConfig.suspense;
4367}
4368
4369var fakeInternalInstance = {};
4370var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default.
4371// We'll use it to determine whether we need to initialize legacy refs.
4372
4373var emptyRefsObject = new React.Component().refs;
4374var didWarnAboutStateAssignmentForComponent;
4375var didWarnAboutUninitializedState;
4376var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
4377var didWarnAboutLegacyLifecyclesAndDerivedState;
4378var didWarnAboutUndefinedDerivedState;
4379var warnOnUndefinedDerivedState;
4380var warnOnInvalidCallback;
4381var didWarnAboutDirectlyAssigningPropsToState;
4382var didWarnAboutContextTypeAndContextTypes;
4383var didWarnAboutInvalidateContextType;
4384
4385{
4386 didWarnAboutStateAssignmentForComponent = new Set();
4387 didWarnAboutUninitializedState = new Set();
4388 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
4389 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
4390 didWarnAboutDirectlyAssigningPropsToState = new Set();
4391 didWarnAboutUndefinedDerivedState = new Set();
4392 didWarnAboutContextTypeAndContextTypes = new Set();
4393 didWarnAboutInvalidateContextType = new Set();
4394 var didWarnOnInvalidCallback = new Set();
4395
4396 warnOnInvalidCallback = function (callback, callerName) {
4397 if (callback === null || typeof callback === 'function') {
4398 return;
4399 }
4400
4401 var key = callerName + "_" + callback;
4402
4403 if (!didWarnOnInvalidCallback.has(key)) {
4404 didWarnOnInvalidCallback.add(key);
4405 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
4406 }
4407 };
4408
4409 warnOnUndefinedDerivedState = function (type, partialState) {
4410 if (partialState === undefined) {
4411 var componentName = getComponentName(type) || 'Component';
4412
4413 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
4414 didWarnAboutUndefinedDerivedState.add(componentName);
4415 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
4416 }
4417 }
4418 }; // This is so gross but it's at least non-critical and can be removed if
4419 // it causes problems. This is meant to give a nicer error message for
4420 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
4421 // ...)) which otherwise throws a "_processChildContext is not a function"
4422 // exception.
4423
4424
4425 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
4426 enumerable: false,
4427 value: function () {
4428 (function () {
4429 {
4430 {
4431 throw ReactError(Error("_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)."));
4432 }
4433 }
4434 })();
4435 }
4436 });
4437 Object.freeze(fakeInternalInstance);
4438}
4439
4440function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
4441 var prevState = workInProgress.memoizedState;
4442
4443 {
4444 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4445 // Invoke the function an extra time to help detect side-effects.
4446 getDerivedStateFromProps(nextProps, prevState);
4447 }
4448 }
4449
4450 var partialState = getDerivedStateFromProps(nextProps, prevState);
4451
4452 {
4453 warnOnUndefinedDerivedState(ctor, partialState);
4454 } // Merge the partial state and the previous state.
4455
4456
4457 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
4458 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
4459 // base state.
4460
4461 var updateQueue = workInProgress.updateQueue;
4462
4463 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
4464 updateQueue.baseState = memoizedState;
4465 }
4466}
4467var classComponentUpdater = {
4468 isMounted: isMounted,
4469 enqueueSetState: function (inst, payload, callback) {
4470 var fiber = get(inst);
4471 var currentTime = requestCurrentTime();
4472 var suspenseConfig = requestCurrentSuspenseConfig();
4473 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
4474 var update = createUpdate(expirationTime, suspenseConfig);
4475 update.payload = payload;
4476
4477 if (callback !== undefined && callback !== null) {
4478 {
4479 warnOnInvalidCallback(callback, 'setState');
4480 }
4481
4482 update.callback = callback;
4483 }
4484
4485 enqueueUpdate(fiber, update);
4486 scheduleWork(fiber, expirationTime);
4487 },
4488 enqueueReplaceState: function (inst, payload, callback) {
4489 var fiber = get(inst);
4490 var currentTime = requestCurrentTime();
4491 var suspenseConfig = requestCurrentSuspenseConfig();
4492 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
4493 var update = createUpdate(expirationTime, suspenseConfig);
4494 update.tag = ReplaceState;
4495 update.payload = payload;
4496
4497 if (callback !== undefined && callback !== null) {
4498 {
4499 warnOnInvalidCallback(callback, 'replaceState');
4500 }
4501
4502 update.callback = callback;
4503 }
4504
4505 enqueueUpdate(fiber, update);
4506 scheduleWork(fiber, expirationTime);
4507 },
4508 enqueueForceUpdate: function (inst, callback) {
4509 var fiber = get(inst);
4510 var currentTime = requestCurrentTime();
4511 var suspenseConfig = requestCurrentSuspenseConfig();
4512 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
4513 var update = createUpdate(expirationTime, suspenseConfig);
4514 update.tag = ForceUpdate;
4515
4516 if (callback !== undefined && callback !== null) {
4517 {
4518 warnOnInvalidCallback(callback, 'forceUpdate');
4519 }
4520
4521 update.callback = callback;
4522 }
4523
4524 enqueueUpdate(fiber, update);
4525 scheduleWork(fiber, expirationTime);
4526 }
4527};
4528
4529function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
4530 var instance = workInProgress.stateNode;
4531
4532 if (typeof instance.shouldComponentUpdate === 'function') {
4533 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
4534 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
4535 stopPhaseTimer();
4536
4537 {
4538 !(shouldUpdate !== undefined) ? warningWithoutStack$1(false, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component') : void 0;
4539 }
4540
4541 return shouldUpdate;
4542 }
4543
4544 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
4545 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
4546 }
4547
4548 return true;
4549}
4550
4551function checkClassInstance(workInProgress, ctor, newProps) {
4552 var instance = workInProgress.stateNode;
4553
4554 {
4555 var name = getComponentName(ctor) || 'Component';
4556 var renderPresent = instance.render;
4557
4558 if (!renderPresent) {
4559 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
4560 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
4561 } else {
4562 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
4563 }
4564 }
4565
4566 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
4567 !noGetInitialStateOnES6 ? warningWithoutStack$1(false, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name) : void 0;
4568 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
4569 !noGetDefaultPropsOnES6 ? warningWithoutStack$1(false, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name) : void 0;
4570 var noInstancePropTypes = !instance.propTypes;
4571 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
4572 var noInstanceContextType = !instance.contextType;
4573 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
4574
4575 if (disableLegacyContext) {
4576 if (ctor.childContextTypes) {
4577 warningWithoutStack$1(false, '%s uses the legacy childContextTypes API which is no longer supported. ' + 'Use React.createContext() instead.', name);
4578 }
4579
4580 if (ctor.contextTypes) {
4581 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with static contextType instead.', name);
4582 }
4583 } else {
4584 var noInstanceContextTypes = !instance.contextTypes;
4585 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
4586
4587 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
4588 didWarnAboutContextTypeAndContextTypes.add(ctor);
4589 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
4590 }
4591 }
4592
4593 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
4594 !noComponentShouldUpdate ? warningWithoutStack$1(false, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name) : void 0;
4595
4596 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
4597 warningWithoutStack$1(false, '%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
4598 }
4599
4600 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
4601 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
4602 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
4603 !noComponentDidReceiveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name) : void 0;
4604 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
4605 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
4606 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
4607 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
4608 var hasMutatedProps = instance.props !== newProps;
4609 !(instance.props === undefined || !hasMutatedProps) ? warningWithoutStack$1(false, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name) : void 0;
4610 var noInstanceDefaultProps = !instance.defaultProps;
4611 !noInstanceDefaultProps ? warningWithoutStack$1(false, 'Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name) : void 0;
4612
4613 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
4614 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
4615 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
4616 }
4617
4618 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
4619 !noInstanceGetDerivedStateFromProps ? warningWithoutStack$1(false, '%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
4620 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
4621 !noInstanceGetDerivedStateFromCatch ? warningWithoutStack$1(false, '%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
4622 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
4623 !noStaticGetSnapshotBeforeUpdate ? warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name) : void 0;
4624 var _state = instance.state;
4625
4626 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
4627 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
4628 }
4629
4630 if (typeof instance.getChildContext === 'function') {
4631 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
4632 }
4633 }
4634}
4635
4636function adoptClassInstance(workInProgress, instance) {
4637 instance.updater = classComponentUpdater;
4638 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
4639
4640 set$1(instance, workInProgress);
4641
4642 {
4643 instance._reactInternalInstance = fakeInternalInstance;
4644 }
4645}
4646
4647function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
4648 var isLegacyContextConsumer = false;
4649 var unmaskedContext = emptyContextObject;
4650 var context = emptyContextObject;
4651 var contextType = ctor.contextType;
4652
4653 {
4654 if ('contextType' in ctor) {
4655 var isValid = // Allow null for conditional declaration
4656 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
4657
4658 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
4659 didWarnAboutInvalidateContextType.add(ctor);
4660 var addendum = '';
4661
4662 if (contextType === undefined) {
4663 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.';
4664 } else if (typeof contextType !== 'object') {
4665 addendum = ' However, it is set to a ' + typeof contextType + '.';
4666 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
4667 addendum = ' Did you accidentally pass the Context.Provider instead?';
4668 } else if (contextType._context !== undefined) {
4669 // <Context.Consumer>
4670 addendum = ' Did you accidentally pass the Context.Consumer instead?';
4671 } else {
4672 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
4673 }
4674
4675 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
4676 }
4677 }
4678 }
4679
4680 if (typeof contextType === 'object' && contextType !== null) {
4681 context = readContext(contextType);
4682 } else if (!disableLegacyContext) {
4683 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4684 var contextTypes = ctor.contextTypes;
4685 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
4686 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
4687 } // Instantiate twice to help detect side-effects.
4688
4689
4690 {
4691 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4692 new ctor(props, context); // eslint-disable-line no-new
4693 }
4694 }
4695
4696 var instance = new ctor(props, context);
4697 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
4698 adoptClassInstance(workInProgress, instance);
4699
4700 {
4701 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
4702 var componentName = getComponentName(ctor) || 'Component';
4703
4704 if (!didWarnAboutUninitializedState.has(componentName)) {
4705 didWarnAboutUninitializedState.add(componentName);
4706 warningWithoutStack$1(false, '`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
4707 }
4708 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
4709 // Warn about these lifecycles if they are present.
4710 // Don't warn about react-lifecycles-compat polyfilled methods though.
4711
4712
4713 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
4714 var foundWillMountName = null;
4715 var foundWillReceivePropsName = null;
4716 var foundWillUpdateName = null;
4717
4718 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
4719 foundWillMountName = 'componentWillMount';
4720 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
4721 foundWillMountName = 'UNSAFE_componentWillMount';
4722 }
4723
4724 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
4725 foundWillReceivePropsName = 'componentWillReceiveProps';
4726 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4727 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
4728 }
4729
4730 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
4731 foundWillUpdateName = 'componentWillUpdate';
4732 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4733 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
4734 }
4735
4736 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
4737 var _componentName = getComponentName(ctor) || 'Component';
4738
4739 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
4740
4741 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
4742 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
4743 warningWithoutStack$1(false, 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
4744 }
4745 }
4746 }
4747 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
4748 // ReactFiberContext usually updates this cache but can't for newly-created instances.
4749
4750
4751 if (isLegacyContextConsumer) {
4752 cacheContext(workInProgress, unmaskedContext, context);
4753 }
4754
4755 return instance;
4756}
4757
4758function callComponentWillMount(workInProgress, instance) {
4759 startPhaseTimer(workInProgress, 'componentWillMount');
4760 var oldState = instance.state;
4761
4762 if (typeof instance.componentWillMount === 'function') {
4763 instance.componentWillMount();
4764 }
4765
4766 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4767 instance.UNSAFE_componentWillMount();
4768 }
4769
4770 stopPhaseTimer();
4771
4772 if (oldState !== instance.state) {
4773 {
4774 warningWithoutStack$1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
4775 }
4776
4777 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4778 }
4779}
4780
4781function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4782 var oldState = instance.state;
4783 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4784
4785 if (typeof instance.componentWillReceiveProps === 'function') {
4786 instance.componentWillReceiveProps(newProps, nextContext);
4787 }
4788
4789 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4790 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4791 }
4792
4793 stopPhaseTimer();
4794
4795 if (instance.state !== oldState) {
4796 {
4797 var componentName = getComponentName(workInProgress.type) || 'Component';
4798
4799 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4800 didWarnAboutStateAssignmentForComponent.add(componentName);
4801 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4802 }
4803 }
4804
4805 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4806 }
4807} // Invokes the mount life-cycles on a previously never rendered instance.
4808
4809
4810function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4811 {
4812 checkClassInstance(workInProgress, ctor, newProps);
4813 }
4814
4815 var instance = workInProgress.stateNode;
4816 instance.props = newProps;
4817 instance.state = workInProgress.memoizedState;
4818 instance.refs = emptyRefsObject;
4819 var contextType = ctor.contextType;
4820
4821 if (typeof contextType === 'object' && contextType !== null) {
4822 instance.context = readContext(contextType);
4823 } else if (disableLegacyContext) {
4824 instance.context = emptyContextObject;
4825 } else {
4826 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4827 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4828 }
4829
4830 {
4831 if (instance.state === newProps) {
4832 var componentName = getComponentName(ctor) || 'Component';
4833
4834 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4835 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4836 warningWithoutStack$1(false, '%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
4837 }
4838 }
4839
4840 if (workInProgress.mode & StrictMode) {
4841 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4842 }
4843
4844 if (warnAboutDeprecatedLifecycles) {
4845 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4846 }
4847 }
4848
4849 var updateQueue = workInProgress.updateQueue;
4850
4851 if (updateQueue !== null) {
4852 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4853 instance.state = workInProgress.memoizedState;
4854 }
4855
4856 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4857
4858 if (typeof getDerivedStateFromProps === 'function') {
4859 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4860 instance.state = workInProgress.memoizedState;
4861 } // In order to support react-lifecycles-compat polyfilled components,
4862 // Unsafe lifecycles should not be invoked for components using the new APIs.
4863
4864
4865 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4866 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
4867 // process them now.
4868
4869 updateQueue = workInProgress.updateQueue;
4870
4871 if (updateQueue !== null) {
4872 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4873 instance.state = workInProgress.memoizedState;
4874 }
4875 }
4876
4877 if (typeof instance.componentDidMount === 'function') {
4878 workInProgress.effectTag |= Update;
4879 }
4880}
4881
4882function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4883 var instance = workInProgress.stateNode;
4884 var oldProps = workInProgress.memoizedProps;
4885 instance.props = oldProps;
4886 var oldContext = instance.context;
4887 var contextType = ctor.contextType;
4888 var nextContext = emptyContextObject;
4889
4890 if (typeof contextType === 'object' && contextType !== null) {
4891 nextContext = readContext(contextType);
4892 } else if (!disableLegacyContext) {
4893 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4894 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4895 }
4896
4897 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4898 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4899 // ever the previously attempted to render - not the "current". However,
4900 // during componentDidUpdate we pass the "current" props.
4901 // In order to support react-lifecycles-compat polyfilled components,
4902 // Unsafe lifecycles should not be invoked for components using the new APIs.
4903
4904 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4905 if (oldProps !== newProps || oldContext !== nextContext) {
4906 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4907 }
4908 }
4909
4910 resetHasForceUpdateBeforeProcessing();
4911 var oldState = workInProgress.memoizedState;
4912 var newState = instance.state = oldState;
4913 var updateQueue = workInProgress.updateQueue;
4914
4915 if (updateQueue !== null) {
4916 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4917 newState = workInProgress.memoizedState;
4918 }
4919
4920 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4921 // If an update was already in progress, we should schedule an Update
4922 // effect even though we're bailing out, so that cWU/cDU are called.
4923 if (typeof instance.componentDidMount === 'function') {
4924 workInProgress.effectTag |= Update;
4925 }
4926
4927 return false;
4928 }
4929
4930 if (typeof getDerivedStateFromProps === 'function') {
4931 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4932 newState = workInProgress.memoizedState;
4933 }
4934
4935 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4936
4937 if (shouldUpdate) {
4938 // In order to support react-lifecycles-compat polyfilled components,
4939 // Unsafe lifecycles should not be invoked for components using the new APIs.
4940 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4941 startPhaseTimer(workInProgress, 'componentWillMount');
4942
4943 if (typeof instance.componentWillMount === 'function') {
4944 instance.componentWillMount();
4945 }
4946
4947 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4948 instance.UNSAFE_componentWillMount();
4949 }
4950
4951 stopPhaseTimer();
4952 }
4953
4954 if (typeof instance.componentDidMount === 'function') {
4955 workInProgress.effectTag |= Update;
4956 }
4957 } else {
4958 // If an update was already in progress, we should schedule an Update
4959 // effect even though we're bailing out, so that cWU/cDU are called.
4960 if (typeof instance.componentDidMount === 'function') {
4961 workInProgress.effectTag |= Update;
4962 } // If shouldComponentUpdate returned false, we should still update the
4963 // memoized state to indicate that this work can be reused.
4964
4965
4966 workInProgress.memoizedProps = newProps;
4967 workInProgress.memoizedState = newState;
4968 } // Update the existing instance's state, props, and context pointers even
4969 // if shouldComponentUpdate returns false.
4970
4971
4972 instance.props = newProps;
4973 instance.state = newState;
4974 instance.context = nextContext;
4975 return shouldUpdate;
4976} // Invokes the update life-cycles and returns false if it shouldn't rerender.
4977
4978
4979function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4980 var instance = workInProgress.stateNode;
4981 var oldProps = workInProgress.memoizedProps;
4982 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4983 var oldContext = instance.context;
4984 var contextType = ctor.contextType;
4985 var nextContext = emptyContextObject;
4986
4987 if (typeof contextType === 'object' && contextType !== null) {
4988 nextContext = readContext(contextType);
4989 } else if (!disableLegacyContext) {
4990 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4991 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4992 }
4993
4994 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4995 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4996 // ever the previously attempted to render - not the "current". However,
4997 // during componentDidUpdate we pass the "current" props.
4998 // In order to support react-lifecycles-compat polyfilled components,
4999 // Unsafe lifecycles should not be invoked for components using the new APIs.
5000
5001 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
5002 if (oldProps !== newProps || oldContext !== nextContext) {
5003 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
5004 }
5005 }
5006
5007 resetHasForceUpdateBeforeProcessing();
5008 var oldState = workInProgress.memoizedState;
5009 var newState = instance.state = oldState;
5010 var updateQueue = workInProgress.updateQueue;
5011
5012 if (updateQueue !== null) {
5013 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
5014 newState = workInProgress.memoizedState;
5015 }
5016
5017 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
5018 // If an update was already in progress, we should schedule an Update
5019 // effect even though we're bailing out, so that cWU/cDU are called.
5020 if (typeof instance.componentDidUpdate === 'function') {
5021 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
5022 workInProgress.effectTag |= Update;
5023 }
5024 }
5025
5026 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
5027 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
5028 workInProgress.effectTag |= Snapshot;
5029 }
5030 }
5031
5032 return false;
5033 }
5034
5035 if (typeof getDerivedStateFromProps === 'function') {
5036 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
5037 newState = workInProgress.memoizedState;
5038 }
5039
5040 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
5041
5042 if (shouldUpdate) {
5043 // In order to support react-lifecycles-compat polyfilled components,
5044 // Unsafe lifecycles should not be invoked for components using the new APIs.
5045 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
5046 startPhaseTimer(workInProgress, 'componentWillUpdate');
5047
5048 if (typeof instance.componentWillUpdate === 'function') {
5049 instance.componentWillUpdate(newProps, newState, nextContext);
5050 }
5051
5052 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
5053 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
5054 }
5055
5056 stopPhaseTimer();
5057 }
5058
5059 if (typeof instance.componentDidUpdate === 'function') {
5060 workInProgress.effectTag |= Update;
5061 }
5062
5063 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
5064 workInProgress.effectTag |= Snapshot;
5065 }
5066 } else {
5067 // If an update was already in progress, we should schedule an Update
5068 // effect even though we're bailing out, so that cWU/cDU are called.
5069 if (typeof instance.componentDidUpdate === 'function') {
5070 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
5071 workInProgress.effectTag |= Update;
5072 }
5073 }
5074
5075 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
5076 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
5077 workInProgress.effectTag |= Snapshot;
5078 }
5079 } // If shouldComponentUpdate returned false, we should still update the
5080 // memoized props/state to indicate that this work can be reused.
5081
5082
5083 workInProgress.memoizedProps = newProps;
5084 workInProgress.memoizedState = newState;
5085 } // Update the existing instance's state, props, and context pointers even
5086 // if shouldComponentUpdate returns false.
5087
5088
5089 instance.props = newProps;
5090 instance.state = newState;
5091 instance.context = nextContext;
5092 return shouldUpdate;
5093}
5094
5095var didWarnAboutMaps;
5096var didWarnAboutGenerators;
5097var didWarnAboutStringRefs;
5098var ownerHasKeyUseWarning;
5099var ownerHasFunctionTypeWarning;
5100
5101var warnForMissingKey = function (child) {};
5102
5103{
5104 didWarnAboutMaps = false;
5105 didWarnAboutGenerators = false;
5106 didWarnAboutStringRefs = {};
5107 /**
5108 * Warn if there's no key explicitly set on dynamic arrays of children or
5109 * object keys are not valid. This allows us to keep track of children between
5110 * updates.
5111 */
5112
5113 ownerHasKeyUseWarning = {};
5114 ownerHasFunctionTypeWarning = {};
5115
5116 warnForMissingKey = function (child) {
5117 if (child === null || typeof child !== 'object') {
5118 return;
5119 }
5120
5121 if (!child._store || child._store.validated || child.key != null) {
5122 return;
5123 }
5124
5125 (function () {
5126 if (!(typeof child._store === 'object')) {
5127 {
5128 throw ReactError(Error("React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue."));
5129 }
5130 }
5131 })();
5132
5133 child._store.validated = true;
5134 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
5135
5136 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
5137 return;
5138 }
5139
5140 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
5141 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
5142 };
5143}
5144
5145var isArray = Array.isArray;
5146
5147function coerceRef(returnFiber, current, element) {
5148 var mixedRef = element.ref;
5149
5150 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
5151 {
5152 // TODO: Clean this up once we turn on the string ref warning for
5153 // everyone, because the strict mode case will no longer be relevant
5154 if (returnFiber.mode & StrictMode || warnAboutStringRefs) {
5155 var componentName = getComponentName(returnFiber.type) || 'Component';
5156
5157 if (!didWarnAboutStringRefs[componentName]) {
5158 if (warnAboutStringRefs) {
5159 warningWithoutStack$1(false, 'Component "%s" contains the string ref "%s". Support for string refs ' + 'will be removed in a future major release. We recommend using ' + 'useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', componentName, mixedRef, getStackByFiberInDevAndProd(returnFiber));
5160 } else {
5161 warningWithoutStack$1(false, 'A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', mixedRef, getStackByFiberInDevAndProd(returnFiber));
5162 }
5163
5164 didWarnAboutStringRefs[componentName] = true;
5165 }
5166 }
5167 }
5168
5169 if (element._owner) {
5170 var owner = element._owner;
5171 var inst;
5172
5173 if (owner) {
5174 var ownerFiber = owner;
5175
5176 (function () {
5177 if (!(ownerFiber.tag === ClassComponent)) {
5178 {
5179 throw ReactError(Error("Function components cannot have refs. Did you mean to use React.forwardRef()?"));
5180 }
5181 }
5182 })();
5183
5184 inst = ownerFiber.stateNode;
5185 }
5186
5187 (function () {
5188 if (!inst) {
5189 {
5190 throw ReactError(Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue."));
5191 }
5192 }
5193 })();
5194
5195 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
5196
5197 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
5198 return current.ref;
5199 }
5200
5201 var ref = function (value) {
5202 var refs = inst.refs;
5203
5204 if (refs === emptyRefsObject) {
5205 // This is a lazy pooled frozen object, so we need to initialize.
5206 refs = inst.refs = {};
5207 }
5208
5209 if (value === null) {
5210 delete refs[stringRef];
5211 } else {
5212 refs[stringRef] = value;
5213 }
5214 };
5215
5216 ref._stringRef = stringRef;
5217 return ref;
5218 } else {
5219 (function () {
5220 if (!(typeof mixedRef === 'string')) {
5221 {
5222 throw ReactError(Error("Expected ref to be a function, a string, an object returned by React.createRef(), or null."));
5223 }
5224 }
5225 })();
5226
5227 (function () {
5228 if (!element._owner) {
5229 {
5230 throw ReactError(Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information."));
5231 }
5232 }
5233 })();
5234 }
5235 }
5236
5237 return mixedRef;
5238}
5239
5240function throwOnInvalidObjectType(returnFiber, newChild) {
5241 if (returnFiber.type !== 'textarea') {
5242 var addendum = '';
5243
5244 {
5245 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
5246 }
5247
5248 (function () {
5249 {
5250 {
5251 throw ReactError(Error("Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + ")." + addendum));
5252 }
5253 }
5254 })();
5255 }
5256}
5257
5258function warnOnFunctionType() {
5259 var currentComponentErrorInfo = 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.' + getCurrentFiberStackInDev();
5260
5261 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
5262 return;
5263 }
5264
5265 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
5266 warning$1(false, 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
5267} // This wrapper function exists because I expect to clone the code in each path
5268// to be able to optimize each path individually by branching early. This needs
5269// a compiler or we can do it manually. Helpers that don't need this branching
5270// live outside of this function.
5271
5272
5273function ChildReconciler(shouldTrackSideEffects) {
5274 function deleteChild(returnFiber, childToDelete) {
5275 if (!shouldTrackSideEffects) {
5276 // Noop.
5277 return;
5278 } // Deletions are added in reversed order so we add it to the front.
5279 // At this point, the return fiber's effect list is empty except for
5280 // deletions, so we can just append the deletion to the list. The remaining
5281 // effects aren't added until the complete phase. Once we implement
5282 // resuming, this may not be true.
5283
5284
5285 var last = returnFiber.lastEffect;
5286
5287 if (last !== null) {
5288 last.nextEffect = childToDelete;
5289 returnFiber.lastEffect = childToDelete;
5290 } else {
5291 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
5292 }
5293
5294 childToDelete.nextEffect = null;
5295 childToDelete.effectTag = Deletion;
5296 }
5297
5298 function deleteRemainingChildren(returnFiber, currentFirstChild) {
5299 if (!shouldTrackSideEffects) {
5300 // Noop.
5301 return null;
5302 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
5303 // assuming that after the first child we've already added everything.
5304
5305
5306 var childToDelete = currentFirstChild;
5307
5308 while (childToDelete !== null) {
5309 deleteChild(returnFiber, childToDelete);
5310 childToDelete = childToDelete.sibling;
5311 }
5312
5313 return null;
5314 }
5315
5316 function mapRemainingChildren(returnFiber, currentFirstChild) {
5317 // Add the remaining children to a temporary map so that we can find them by
5318 // keys quickly. Implicit (null) keys get added to this set with their index
5319 // instead.
5320 var existingChildren = new Map();
5321 var existingChild = currentFirstChild;
5322
5323 while (existingChild !== null) {
5324 if (existingChild.key !== null) {
5325 existingChildren.set(existingChild.key, existingChild);
5326 } else {
5327 existingChildren.set(existingChild.index, existingChild);
5328 }
5329
5330 existingChild = existingChild.sibling;
5331 }
5332
5333 return existingChildren;
5334 }
5335
5336 function useFiber(fiber, pendingProps, expirationTime) {
5337 // We currently set sibling to null and index to 0 here because it is easy
5338 // to forget to do before returning it. E.g. for the single child case.
5339 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
5340 clone.index = 0;
5341 clone.sibling = null;
5342 return clone;
5343 }
5344
5345 function placeChild(newFiber, lastPlacedIndex, newIndex) {
5346 newFiber.index = newIndex;
5347
5348 if (!shouldTrackSideEffects) {
5349 // Noop.
5350 return lastPlacedIndex;
5351 }
5352
5353 var current = newFiber.alternate;
5354
5355 if (current !== null) {
5356 var oldIndex = current.index;
5357
5358 if (oldIndex < lastPlacedIndex) {
5359 // This is a move.
5360 newFiber.effectTag = Placement;
5361 return lastPlacedIndex;
5362 } else {
5363 // This item can stay in place.
5364 return oldIndex;
5365 }
5366 } else {
5367 // This is an insertion.
5368 newFiber.effectTag = Placement;
5369 return lastPlacedIndex;
5370 }
5371 }
5372
5373 function placeSingleChild(newFiber) {
5374 // This is simpler for the single child case. We only need to do a
5375 // placement for inserting new children.
5376 if (shouldTrackSideEffects && newFiber.alternate === null) {
5377 newFiber.effectTag = Placement;
5378 }
5379
5380 return newFiber;
5381 }
5382
5383 function updateTextNode(returnFiber, current, textContent, expirationTime) {
5384 if (current === null || current.tag !== HostText) {
5385 // Insert
5386 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5387 created.return = returnFiber;
5388 return created;
5389 } else {
5390 // Update
5391 var existing = useFiber(current, textContent, expirationTime);
5392 existing.return = returnFiber;
5393 return existing;
5394 }
5395 }
5396
5397 function updateElement(returnFiber, current, element, expirationTime) {
5398 if (current !== null && (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
5399 isCompatibleFamilyForHotReloading(current, element)))) {
5400 // Move based on index
5401 var existing = useFiber(current, element.props, expirationTime);
5402 existing.ref = coerceRef(returnFiber, current, element);
5403 existing.return = returnFiber;
5404
5405 {
5406 existing._debugSource = element._source;
5407 existing._debugOwner = element._owner;
5408 }
5409
5410 return existing;
5411 } else {
5412 // Insert
5413 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
5414 created.ref = coerceRef(returnFiber, current, element);
5415 created.return = returnFiber;
5416 return created;
5417 }
5418 }
5419
5420 function updatePortal(returnFiber, current, portal, expirationTime) {
5421 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
5422 // Insert
5423 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5424 created.return = returnFiber;
5425 return created;
5426 } else {
5427 // Update
5428 var existing = useFiber(current, portal.children || [], expirationTime);
5429 existing.return = returnFiber;
5430 return existing;
5431 }
5432 }
5433
5434 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
5435 if (current === null || current.tag !== Fragment) {
5436 // Insert
5437 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
5438 created.return = returnFiber;
5439 return created;
5440 } else {
5441 // Update
5442 var existing = useFiber(current, fragment, expirationTime);
5443 existing.return = returnFiber;
5444 return existing;
5445 }
5446 }
5447
5448 function createChild(returnFiber, newChild, expirationTime) {
5449 if (typeof newChild === 'string' || typeof newChild === 'number') {
5450 // Text nodes don't have keys. If the previous node is implicitly keyed
5451 // we can continue to replace it without aborting even if it is not a text
5452 // node.
5453 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
5454 created.return = returnFiber;
5455 return created;
5456 }
5457
5458 if (typeof newChild === 'object' && newChild !== null) {
5459 switch (newChild.$$typeof) {
5460 case REACT_ELEMENT_TYPE$1:
5461 {
5462 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
5463
5464 _created.ref = coerceRef(returnFiber, null, newChild);
5465 _created.return = returnFiber;
5466 return _created;
5467 }
5468
5469 case REACT_PORTAL_TYPE:
5470 {
5471 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
5472
5473 _created2.return = returnFiber;
5474 return _created2;
5475 }
5476 }
5477
5478 if (isArray(newChild) || getIteratorFn(newChild)) {
5479 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
5480
5481 _created3.return = returnFiber;
5482 return _created3;
5483 }
5484
5485 throwOnInvalidObjectType(returnFiber, newChild);
5486 }
5487
5488 {
5489 if (typeof newChild === 'function') {
5490 warnOnFunctionType();
5491 }
5492 }
5493
5494 return null;
5495 }
5496
5497 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
5498 // Update the fiber if the keys match, otherwise return null.
5499 var key = oldFiber !== null ? oldFiber.key : null;
5500
5501 if (typeof newChild === 'string' || typeof newChild === 'number') {
5502 // Text nodes don't have keys. If the previous node is implicitly keyed
5503 // we can continue to replace it without aborting even if it is not a text
5504 // node.
5505 if (key !== null) {
5506 return null;
5507 }
5508
5509 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
5510 }
5511
5512 if (typeof newChild === 'object' && newChild !== null) {
5513 switch (newChild.$$typeof) {
5514 case REACT_ELEMENT_TYPE$1:
5515 {
5516 if (newChild.key === key) {
5517 if (newChild.type === REACT_FRAGMENT_TYPE) {
5518 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
5519 }
5520
5521 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
5522 } else {
5523 return null;
5524 }
5525 }
5526
5527 case REACT_PORTAL_TYPE:
5528 {
5529 if (newChild.key === key) {
5530 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
5531 } else {
5532 return null;
5533 }
5534 }
5535 }
5536
5537 if (isArray(newChild) || getIteratorFn(newChild)) {
5538 if (key !== null) {
5539 return null;
5540 }
5541
5542 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
5543 }
5544
5545 throwOnInvalidObjectType(returnFiber, newChild);
5546 }
5547
5548 {
5549 if (typeof newChild === 'function') {
5550 warnOnFunctionType();
5551 }
5552 }
5553
5554 return null;
5555 }
5556
5557 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
5558 if (typeof newChild === 'string' || typeof newChild === 'number') {
5559 // Text nodes don't have keys, so we neither have to check the old nor
5560 // new node for the key. If both are text nodes, they match.
5561 var matchedFiber = existingChildren.get(newIdx) || null;
5562 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
5563 }
5564
5565 if (typeof newChild === 'object' && newChild !== null) {
5566 switch (newChild.$$typeof) {
5567 case REACT_ELEMENT_TYPE$1:
5568 {
5569 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5570
5571 if (newChild.type === REACT_FRAGMENT_TYPE) {
5572 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
5573 }
5574
5575 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
5576 }
5577
5578 case REACT_PORTAL_TYPE:
5579 {
5580 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5581
5582 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
5583 }
5584 }
5585
5586 if (isArray(newChild) || getIteratorFn(newChild)) {
5587 var _matchedFiber3 = existingChildren.get(newIdx) || null;
5588
5589 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
5590 }
5591
5592 throwOnInvalidObjectType(returnFiber, newChild);
5593 }
5594
5595 {
5596 if (typeof newChild === 'function') {
5597 warnOnFunctionType();
5598 }
5599 }
5600
5601 return null;
5602 }
5603 /**
5604 * Warns if there is a duplicate or missing key
5605 */
5606
5607
5608 function warnOnInvalidKey(child, knownKeys) {
5609 {
5610 if (typeof child !== 'object' || child === null) {
5611 return knownKeys;
5612 }
5613
5614 switch (child.$$typeof) {
5615 case REACT_ELEMENT_TYPE$1:
5616 case REACT_PORTAL_TYPE:
5617 warnForMissingKey(child);
5618 var key = child.key;
5619
5620 if (typeof key !== 'string') {
5621 break;
5622 }
5623
5624 if (knownKeys === null) {
5625 knownKeys = new Set();
5626 knownKeys.add(key);
5627 break;
5628 }
5629
5630 if (!knownKeys.has(key)) {
5631 knownKeys.add(key);
5632 break;
5633 }
5634
5635 warning$1(false, 'Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
5636 break;
5637
5638 default:
5639 break;
5640 }
5641 }
5642
5643 return knownKeys;
5644 }
5645
5646 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
5647 // This algorithm can't optimize by searching from both ends since we
5648 // don't have backpointers on fibers. I'm trying to see how far we can get
5649 // with that model. If it ends up not being worth the tradeoffs, we can
5650 // add it later.
5651 // Even with a two ended optimization, we'd want to optimize for the case
5652 // where there are few changes and brute force the comparison instead of
5653 // going for the Map. It'd like to explore hitting that path first in
5654 // forward-only mode and only go for the Map once we notice that we need
5655 // lots of look ahead. This doesn't handle reversal as well as two ended
5656 // search but that's unusual. Besides, for the two ended optimization to
5657 // work on Iterables, we'd need to copy the whole set.
5658 // In this first iteration, we'll just live with hitting the bad case
5659 // (adding everything to a Map) in for every insert/move.
5660 // If you change this code, also update reconcileChildrenIterator() which
5661 // uses the same algorithm.
5662 {
5663 // First, validate keys.
5664 var knownKeys = null;
5665
5666 for (var i = 0; i < newChildren.length; i++) {
5667 var child = newChildren[i];
5668 knownKeys = warnOnInvalidKey(child, knownKeys);
5669 }
5670 }
5671
5672 var resultingFirstChild = null;
5673 var previousNewFiber = null;
5674 var oldFiber = currentFirstChild;
5675 var lastPlacedIndex = 0;
5676 var newIdx = 0;
5677 var nextOldFiber = null;
5678
5679 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
5680 if (oldFiber.index > newIdx) {
5681 nextOldFiber = oldFiber;
5682 oldFiber = null;
5683 } else {
5684 nextOldFiber = oldFiber.sibling;
5685 }
5686
5687 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
5688
5689 if (newFiber === null) {
5690 // TODO: This breaks on empty slots like null children. That's
5691 // unfortunate because it triggers the slow path all the time. We need
5692 // a better way to communicate whether this was a miss or null,
5693 // boolean, undefined, etc.
5694 if (oldFiber === null) {
5695 oldFiber = nextOldFiber;
5696 }
5697
5698 break;
5699 }
5700
5701 if (shouldTrackSideEffects) {
5702 if (oldFiber && newFiber.alternate === null) {
5703 // We matched the slot, but we didn't reuse the existing fiber, so we
5704 // need to delete the existing child.
5705 deleteChild(returnFiber, oldFiber);
5706 }
5707 }
5708
5709 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5710
5711 if (previousNewFiber === null) {
5712 // TODO: Move out of the loop. This only happens for the first run.
5713 resultingFirstChild = newFiber;
5714 } else {
5715 // TODO: Defer siblings if we're not at the right index for this slot.
5716 // I.e. if we had null values before, then we want to defer this
5717 // for each null value. However, we also don't want to call updateSlot
5718 // with the previous one.
5719 previousNewFiber.sibling = newFiber;
5720 }
5721
5722 previousNewFiber = newFiber;
5723 oldFiber = nextOldFiber;
5724 }
5725
5726 if (newIdx === newChildren.length) {
5727 // We've reached the end of the new children. We can delete the rest.
5728 deleteRemainingChildren(returnFiber, oldFiber);
5729 return resultingFirstChild;
5730 }
5731
5732 if (oldFiber === null) {
5733 // If we don't have any more existing children we can choose a fast path
5734 // since the rest will all be insertions.
5735 for (; newIdx < newChildren.length; newIdx++) {
5736 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
5737
5738 if (_newFiber === null) {
5739 continue;
5740 }
5741
5742 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
5743
5744 if (previousNewFiber === null) {
5745 // TODO: Move out of the loop. This only happens for the first run.
5746 resultingFirstChild = _newFiber;
5747 } else {
5748 previousNewFiber.sibling = _newFiber;
5749 }
5750
5751 previousNewFiber = _newFiber;
5752 }
5753
5754 return resultingFirstChild;
5755 } // Add all children to a key map for quick lookups.
5756
5757
5758 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5759
5760 for (; newIdx < newChildren.length; newIdx++) {
5761 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
5762
5763 if (_newFiber2 !== null) {
5764 if (shouldTrackSideEffects) {
5765 if (_newFiber2.alternate !== null) {
5766 // The new fiber is a work in progress, but if there exists a
5767 // current, that means that we reused the fiber. We need to delete
5768 // it from the child list so that we don't add it to the deletion
5769 // list.
5770 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
5771 }
5772 }
5773
5774 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
5775
5776 if (previousNewFiber === null) {
5777 resultingFirstChild = _newFiber2;
5778 } else {
5779 previousNewFiber.sibling = _newFiber2;
5780 }
5781
5782 previousNewFiber = _newFiber2;
5783 }
5784 }
5785
5786 if (shouldTrackSideEffects) {
5787 // Any existing children that weren't consumed above were deleted. We need
5788 // to add them to the deletion list.
5789 existingChildren.forEach(function (child) {
5790 return deleteChild(returnFiber, child);
5791 });
5792 }
5793
5794 return resultingFirstChild;
5795 }
5796
5797 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
5798 // This is the same implementation as reconcileChildrenArray(),
5799 // but using the iterator instead.
5800 var iteratorFn = getIteratorFn(newChildrenIterable);
5801
5802 (function () {
5803 if (!(typeof iteratorFn === 'function')) {
5804 {
5805 throw ReactError(Error("An object is not an iterable. This error is likely caused by a bug in React. Please file an issue."));
5806 }
5807 }
5808 })();
5809
5810 {
5811 // We don't support rendering Generators because it's a mutation.
5812 // See https://github.com/facebook/react/issues/12995
5813 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
5814 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
5815 !didWarnAboutGenerators ? warning$1(false, 'Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.') : void 0;
5816 didWarnAboutGenerators = true;
5817 } // Warn about using Maps as children
5818
5819
5820 if (newChildrenIterable.entries === iteratorFn) {
5821 !didWarnAboutMaps ? warning$1(false, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.') : void 0;
5822 didWarnAboutMaps = true;
5823 } // First, validate keys.
5824 // We'll get a different iterator later for the main pass.
5825
5826
5827 var _newChildren = iteratorFn.call(newChildrenIterable);
5828
5829 if (_newChildren) {
5830 var knownKeys = null;
5831
5832 var _step = _newChildren.next();
5833
5834 for (; !_step.done; _step = _newChildren.next()) {
5835 var child = _step.value;
5836 knownKeys = warnOnInvalidKey(child, knownKeys);
5837 }
5838 }
5839 }
5840
5841 var newChildren = iteratorFn.call(newChildrenIterable);
5842
5843 (function () {
5844 if (!(newChildren != null)) {
5845 {
5846 throw ReactError(Error("An iterable object provided no iterator."));
5847 }
5848 }
5849 })();
5850
5851 var resultingFirstChild = null;
5852 var previousNewFiber = null;
5853 var oldFiber = currentFirstChild;
5854 var lastPlacedIndex = 0;
5855 var newIdx = 0;
5856 var nextOldFiber = null;
5857 var step = newChildren.next();
5858
5859 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
5860 if (oldFiber.index > newIdx) {
5861 nextOldFiber = oldFiber;
5862 oldFiber = null;
5863 } else {
5864 nextOldFiber = oldFiber.sibling;
5865 }
5866
5867 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
5868
5869 if (newFiber === null) {
5870 // TODO: This breaks on empty slots like null children. That's
5871 // unfortunate because it triggers the slow path all the time. We need
5872 // a better way to communicate whether this was a miss or null,
5873 // boolean, undefined, etc.
5874 if (oldFiber === null) {
5875 oldFiber = nextOldFiber;
5876 }
5877
5878 break;
5879 }
5880
5881 if (shouldTrackSideEffects) {
5882 if (oldFiber && newFiber.alternate === null) {
5883 // We matched the slot, but we didn't reuse the existing fiber, so we
5884 // need to delete the existing child.
5885 deleteChild(returnFiber, oldFiber);
5886 }
5887 }
5888
5889 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5890
5891 if (previousNewFiber === null) {
5892 // TODO: Move out of the loop. This only happens for the first run.
5893 resultingFirstChild = newFiber;
5894 } else {
5895 // TODO: Defer siblings if we're not at the right index for this slot.
5896 // I.e. if we had null values before, then we want to defer this
5897 // for each null value. However, we also don't want to call updateSlot
5898 // with the previous one.
5899 previousNewFiber.sibling = newFiber;
5900 }
5901
5902 previousNewFiber = newFiber;
5903 oldFiber = nextOldFiber;
5904 }
5905
5906 if (step.done) {
5907 // We've reached the end of the new children. We can delete the rest.
5908 deleteRemainingChildren(returnFiber, oldFiber);
5909 return resultingFirstChild;
5910 }
5911
5912 if (oldFiber === null) {
5913 // If we don't have any more existing children we can choose a fast path
5914 // since the rest will all be insertions.
5915 for (; !step.done; newIdx++, step = newChildren.next()) {
5916 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5917
5918 if (_newFiber3 === null) {
5919 continue;
5920 }
5921
5922 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5923
5924 if (previousNewFiber === null) {
5925 // TODO: Move out of the loop. This only happens for the first run.
5926 resultingFirstChild = _newFiber3;
5927 } else {
5928 previousNewFiber.sibling = _newFiber3;
5929 }
5930
5931 previousNewFiber = _newFiber3;
5932 }
5933
5934 return resultingFirstChild;
5935 } // Add all children to a key map for quick lookups.
5936
5937
5938 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5939
5940 for (; !step.done; newIdx++, step = newChildren.next()) {
5941 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5942
5943 if (_newFiber4 !== null) {
5944 if (shouldTrackSideEffects) {
5945 if (_newFiber4.alternate !== null) {
5946 // The new fiber is a work in progress, but if there exists a
5947 // current, that means that we reused the fiber. We need to delete
5948 // it from the child list so that we don't add it to the deletion
5949 // list.
5950 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5951 }
5952 }
5953
5954 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5955
5956 if (previousNewFiber === null) {
5957 resultingFirstChild = _newFiber4;
5958 } else {
5959 previousNewFiber.sibling = _newFiber4;
5960 }
5961
5962 previousNewFiber = _newFiber4;
5963 }
5964 }
5965
5966 if (shouldTrackSideEffects) {
5967 // Any existing children that weren't consumed above were deleted. We need
5968 // to add them to the deletion list.
5969 existingChildren.forEach(function (child) {
5970 return deleteChild(returnFiber, child);
5971 });
5972 }
5973
5974 return resultingFirstChild;
5975 }
5976
5977 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5978 // There's no need to check for keys on text nodes since we don't have a
5979 // way to define them.
5980 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5981 // We already have an existing node so let's just update it and delete
5982 // the rest.
5983 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5984 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5985 existing.return = returnFiber;
5986 return existing;
5987 } // The existing first child is not a text node so we need to create one
5988 // and delete the existing ones.
5989
5990
5991 deleteRemainingChildren(returnFiber, currentFirstChild);
5992 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5993 created.return = returnFiber;
5994 return created;
5995 }
5996
5997 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5998 var key = element.key;
5999 var child = currentFirstChild;
6000
6001 while (child !== null) {
6002 // TODO: If key === null and child.key === null, then this only applies to
6003 // the first item in the list.
6004 if (child.key === key) {
6005 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
6006 isCompatibleFamilyForHotReloading(child, element))) {
6007 deleteRemainingChildren(returnFiber, child.sibling);
6008 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
6009 existing.ref = coerceRef(returnFiber, child, element);
6010 existing.return = returnFiber;
6011
6012 {
6013 existing._debugSource = element._source;
6014 existing._debugOwner = element._owner;
6015 }
6016
6017 return existing;
6018 } else {
6019 deleteRemainingChildren(returnFiber, child);
6020 break;
6021 }
6022 } else {
6023 deleteChild(returnFiber, child);
6024 }
6025
6026 child = child.sibling;
6027 }
6028
6029 if (element.type === REACT_FRAGMENT_TYPE) {
6030 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
6031 created.return = returnFiber;
6032 return created;
6033 } else {
6034 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
6035
6036 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
6037 _created4.return = returnFiber;
6038 return _created4;
6039 }
6040 }
6041
6042 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
6043 var key = portal.key;
6044 var child = currentFirstChild;
6045
6046 while (child !== null) {
6047 // TODO: If key === null and child.key === null, then this only applies to
6048 // the first item in the list.
6049 if (child.key === key) {
6050 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
6051 deleteRemainingChildren(returnFiber, child.sibling);
6052 var existing = useFiber(child, portal.children || [], expirationTime);
6053 existing.return = returnFiber;
6054 return existing;
6055 } else {
6056 deleteRemainingChildren(returnFiber, child);
6057 break;
6058 }
6059 } else {
6060 deleteChild(returnFiber, child);
6061 }
6062
6063 child = child.sibling;
6064 }
6065
6066 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
6067 created.return = returnFiber;
6068 return created;
6069 } // This API will tag the children with the side-effect of the reconciliation
6070 // itself. They will be added to the side-effect list as we pass through the
6071 // children and the parent.
6072
6073
6074 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
6075 // This function is not recursive.
6076 // If the top level item is an array, we treat it as a set of children,
6077 // not as a fragment. Nested arrays on the other hand will be treated as
6078 // fragment nodes. Recursion happens at the normal flow.
6079 // Handle top level unkeyed fragments as if they were arrays.
6080 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
6081 // We treat the ambiguous cases above the same.
6082 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
6083
6084 if (isUnkeyedTopLevelFragment) {
6085 newChild = newChild.props.children;
6086 } // Handle object types
6087
6088
6089 var isObject = typeof newChild === 'object' && newChild !== null;
6090
6091 if (isObject) {
6092 switch (newChild.$$typeof) {
6093 case REACT_ELEMENT_TYPE$1:
6094 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
6095
6096 case REACT_PORTAL_TYPE:
6097 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
6098 }
6099 }
6100
6101 if (typeof newChild === 'string' || typeof newChild === 'number') {
6102 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
6103 }
6104
6105 if (isArray(newChild)) {
6106 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
6107 }
6108
6109 if (getIteratorFn(newChild)) {
6110 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
6111 }
6112
6113 if (isObject) {
6114 throwOnInvalidObjectType(returnFiber, newChild);
6115 }
6116
6117 {
6118 if (typeof newChild === 'function') {
6119 warnOnFunctionType();
6120 }
6121 }
6122
6123 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
6124 // If the new child is undefined, and the return fiber is a composite
6125 // component, throw an error. If Fiber return types are disabled,
6126 // we already threw above.
6127 switch (returnFiber.tag) {
6128 case ClassComponent:
6129 {
6130 {
6131 var instance = returnFiber.stateNode;
6132
6133 if (instance.render._isMockFunction) {
6134 // We allow auto-mocks to proceed as if they're returning null.
6135 break;
6136 }
6137 }
6138 }
6139 // Intentionally fall through to the next case, which handles both
6140 // functions and classes
6141 // eslint-disable-next-lined no-fallthrough
6142
6143 case FunctionComponent:
6144 {
6145 var Component = returnFiber.type;
6146
6147 (function () {
6148 {
6149 {
6150 throw ReactError(Error((Component.displayName || Component.name || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null."));
6151 }
6152 }
6153 })();
6154 }
6155 }
6156 } // Remaining cases are all treated as empty.
6157
6158
6159 return deleteRemainingChildren(returnFiber, currentFirstChild);
6160 }
6161
6162 return reconcileChildFibers;
6163}
6164
6165var reconcileChildFibers = ChildReconciler(true);
6166var mountChildFibers = ChildReconciler(false);
6167function cloneChildFibers(current, workInProgress) {
6168 (function () {
6169 if (!(current === null || workInProgress.child === current.child)) {
6170 {
6171 throw ReactError(Error("Resuming work not yet implemented."));
6172 }
6173 }
6174 })();
6175
6176 if (workInProgress.child === null) {
6177 return;
6178 }
6179
6180 var currentChild = workInProgress.child;
6181 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
6182 workInProgress.child = newChild;
6183 newChild.return = workInProgress;
6184
6185 while (currentChild.sibling !== null) {
6186 currentChild = currentChild.sibling;
6187 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
6188 newChild.return = workInProgress;
6189 }
6190
6191 newChild.sibling = null;
6192} // Reset a workInProgress child set to prepare it for a second pass.
6193
6194function resetChildFibers(workInProgress, renderExpirationTime) {
6195 var child = workInProgress.child;
6196
6197 while (child !== null) {
6198 resetWorkInProgress(child, renderExpirationTime);
6199 child = child.sibling;
6200 }
6201}
6202
6203var NO_CONTEXT$1 = {};
6204var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
6205var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
6206var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
6207
6208function requiredContext(c) {
6209 (function () {
6210 if (!(c !== NO_CONTEXT$1)) {
6211 {
6212 throw ReactError(Error("Expected host context to exist. This error is likely caused by a bug in React. Please file an issue."));
6213 }
6214 }
6215 })();
6216
6217 return c;
6218}
6219
6220function getRootHostContainer() {
6221 var rootInstance = requiredContext(rootInstanceStackCursor.current);
6222 return rootInstance;
6223}
6224
6225function pushHostContainer(fiber, nextRootInstance) {
6226 // Push current root instance onto the stack;
6227 // This allows us to reset root when portals are popped.
6228 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
6229 // This enables us to pop only Fibers that provide unique contexts.
6230
6231 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
6232 // However, we can't just call getRootHostContext() and push it because
6233 // we'd have a different number of entries on the stack depending on
6234 // whether getRootHostContext() throws somewhere in renderer code or not.
6235 // So we push an empty value first. This lets us safely unwind on errors.
6236
6237 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
6238 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
6239
6240 pop(contextStackCursor$1, fiber);
6241 push(contextStackCursor$1, nextRootContext, fiber);
6242}
6243
6244function popHostContainer(fiber) {
6245 pop(contextStackCursor$1, fiber);
6246 pop(contextFiberStackCursor, fiber);
6247 pop(rootInstanceStackCursor, fiber);
6248}
6249
6250function getHostContext() {
6251 var context = requiredContext(contextStackCursor$1.current);
6252 return context;
6253}
6254
6255function pushHostContext(fiber) {
6256 var rootInstance = requiredContext(rootInstanceStackCursor.current);
6257 var context = requiredContext(contextStackCursor$1.current);
6258 var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique.
6259
6260 if (context === nextContext) {
6261 return;
6262 } // Track the context and the Fiber that provided it.
6263 // This enables us to pop only Fibers that provide unique contexts.
6264
6265
6266 push(contextFiberStackCursor, fiber, fiber);
6267 push(contextStackCursor$1, nextContext, fiber);
6268}
6269
6270function popHostContext(fiber) {
6271 // Do not pop unless this Fiber provided the current context.
6272 // pushHostContext() only pushes Fibers that provide unique contexts.
6273 if (contextFiberStackCursor.current !== fiber) {
6274 return;
6275 }
6276
6277 pop(contextStackCursor$1, fiber);
6278 pop(contextFiberStackCursor, fiber);
6279}
6280
6281var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
6282// inherited deeply down the subtree. The upper bits only affect
6283// this immediate suspense boundary and gets reset each new
6284// boundary or suspense list.
6285
6286var SubtreeSuspenseContextMask = 1; // Subtree Flags:
6287// InvisibleParentSuspenseContext indicates that one of our parent Suspense
6288// boundaries is not currently showing visible main content.
6289// Either because it is already showing a fallback or is not mounted at all.
6290// We can use this to determine if it is desirable to trigger a fallback at
6291// the parent. If not, then we might need to trigger undesirable boundaries
6292// and/or suspend the commit to avoid hiding the parent content.
6293
6294var InvisibleParentSuspenseContext = 1; // Shallow Flags:
6295// ForceSuspenseFallback can be used by SuspenseList to force newly added
6296// items into their fallback state during one of the render passes.
6297
6298var ForceSuspenseFallback = 2;
6299var suspenseStackCursor = createCursor(DefaultSuspenseContext);
6300function hasSuspenseContext(parentContext, flag) {
6301 return (parentContext & flag) !== 0;
6302}
6303function setDefaultShallowSuspenseContext(parentContext) {
6304 return parentContext & SubtreeSuspenseContextMask;
6305}
6306function setShallowSuspenseContext(parentContext, shallowContext) {
6307 return parentContext & SubtreeSuspenseContextMask | shallowContext;
6308}
6309function addSubtreeSuspenseContext(parentContext, subtreeContext) {
6310 return parentContext | subtreeContext;
6311}
6312function pushSuspenseContext(fiber, newContext) {
6313 push(suspenseStackCursor, newContext, fiber);
6314}
6315function popSuspenseContext(fiber) {
6316 pop(suspenseStackCursor, fiber);
6317}
6318
6319function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
6320 // If it was the primary children that just suspended, capture and render the
6321 // fallback. Otherwise, don't capture and bubble to the next boundary.
6322 var nextState = workInProgress.memoizedState;
6323
6324 if (nextState !== null) {
6325 if (nextState.dehydrated !== null) {
6326 // A dehydrated boundary always captures.
6327 return true;
6328 }
6329
6330 return false;
6331 }
6332
6333 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
6334
6335 if (props.fallback === undefined) {
6336 return false;
6337 } // Regular boundaries always capture.
6338
6339
6340 if (props.unstable_avoidThisFallback !== true) {
6341 return true;
6342 } // If it's a boundary we should avoid, then we prefer to bubble up to the
6343 // parent boundary if it is currently invisible.
6344
6345
6346 if (hasInvisibleParent) {
6347 return false;
6348 } // If the parent is not able to handle it, we must handle it.
6349
6350
6351 return true;
6352}
6353function findFirstSuspended(row) {
6354 var node = row;
6355
6356 while (node !== null) {
6357 if (node.tag === SuspenseComponent) {
6358 var state = node.memoizedState;
6359
6360 if (state !== null) {
6361 var dehydrated = state.dehydrated;
6362
6363 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
6364 return node;
6365 }
6366 }
6367 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
6368 // keep track of whether it suspended or not.
6369 node.memoizedProps.revealOrder !== undefined) {
6370 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
6371
6372 if (didSuspend) {
6373 return node;
6374 }
6375 } else if (node.child !== null) {
6376 node.child.return = node;
6377 node = node.child;
6378 continue;
6379 }
6380
6381 if (node === row) {
6382 return null;
6383 }
6384
6385 while (node.sibling === null) {
6386 if (node.return === null || node.return === row) {
6387 return null;
6388 }
6389
6390 node = node.return;
6391 }
6392
6393 node.sibling.return = node.return;
6394 node = node.sibling;
6395 }
6396
6397 return null;
6398}
6399
6400var emptyObject = {};
6401var isArray$2 = Array.isArray;
6402function createResponderInstance(responder, responderProps, responderState, fiber) {
6403 return {
6404 fiber: fiber,
6405 props: responderProps,
6406 responder: responder,
6407 rootEventTypes: null,
6408 state: responderState
6409 };
6410}
6411
6412function mountEventResponder(responder, responderProps, fiber, respondersMap, rootContainerInstance) {
6413 var responderState = emptyObject;
6414 var getInitialState = responder.getInitialState;
6415
6416 if (getInitialState !== null) {
6417 responderState = getInitialState(responderProps);
6418 }
6419
6420 var responderInstance = createResponderInstance(responder, responderProps, responderState, fiber);
6421
6422 if (!rootContainerInstance) {
6423 var node = fiber;
6424
6425 while (node !== null) {
6426 var tag = node.tag;
6427
6428 if (tag === HostComponent) {
6429 rootContainerInstance = node.stateNode;
6430 break;
6431 } else if (tag === HostRoot) {
6432 rootContainerInstance = node.stateNode.containerInfo;
6433 break;
6434 }
6435
6436 node = node.return;
6437 }
6438 }
6439
6440 mountResponderInstance(responder, responderInstance, responderProps, responderState, rootContainerInstance);
6441 respondersMap.set(responder, responderInstance);
6442}
6443
6444function updateEventListener(listener, fiber, visistedResponders, respondersMap, rootContainerInstance) {
6445 var responder;
6446 var props;
6447
6448 if (listener) {
6449 responder = listener.responder;
6450 props = listener.props;
6451 }
6452
6453 (function () {
6454 if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) {
6455 {
6456 throw ReactError(Error("An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponder()."));
6457 }
6458 }
6459 })();
6460
6461 var listenerProps = props;
6462
6463 if (visistedResponders.has(responder)) {
6464 // show warning
6465 {
6466 warning$1(false, 'Duplicate event responder "%s" found in event listeners. ' + 'Event listeners passed to elements cannot use the same event responder more than once.', responder.displayName);
6467 }
6468
6469 return;
6470 }
6471
6472 visistedResponders.add(responder);
6473 var responderInstance = respondersMap.get(responder);
6474
6475 if (responderInstance === undefined) {
6476 // Mount (happens in either complete or commit phase)
6477 mountEventResponder(responder, listenerProps, fiber, respondersMap, rootContainerInstance);
6478 } else {
6479 // Update (happens during commit phase only)
6480 responderInstance.props = listenerProps;
6481 responderInstance.fiber = fiber;
6482 }
6483}
6484
6485function updateEventListeners(listeners, fiber, rootContainerInstance) {
6486 var visistedResponders = new Set();
6487 var dependencies = fiber.dependencies;
6488
6489 if (listeners != null) {
6490 if (dependencies === null) {
6491 dependencies = fiber.dependencies = {
6492 expirationTime: NoWork,
6493 firstContext: null,
6494 responders: new Map()
6495 };
6496 }
6497
6498 var respondersMap = dependencies.responders;
6499
6500 if (respondersMap === null) {
6501 respondersMap = new Map();
6502 }
6503
6504 if (isArray$2(listeners)) {
6505 for (var i = 0, length = listeners.length; i < length; i++) {
6506 var listener = listeners[i];
6507 updateEventListener(listener, fiber, visistedResponders, respondersMap, rootContainerInstance);
6508 }
6509 } else {
6510 updateEventListener(listeners, fiber, visistedResponders, respondersMap, rootContainerInstance);
6511 }
6512 }
6513
6514 if (dependencies !== null) {
6515 var _respondersMap = dependencies.responders;
6516
6517 if (_respondersMap !== null) {
6518 // Unmount
6519 var mountedResponders = Array.from(_respondersMap.keys());
6520
6521 for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) {
6522 var mountedResponder = mountedResponders[_i];
6523
6524 if (!visistedResponders.has(mountedResponder)) {
6525 var responderInstance = _respondersMap.get(mountedResponder);
6526
6527 unmountResponderInstance(responderInstance);
6528
6529 _respondersMap.delete(mountedResponder);
6530 }
6531 }
6532 }
6533 }
6534}
6535function createResponderListener(responder, props) {
6536 var eventResponderListener = {
6537 responder: responder,
6538 props: props
6539 };
6540
6541 {
6542 Object.freeze(eventResponderListener);
6543 }
6544
6545 return eventResponderListener;
6546}
6547
6548var NoEffect$1 =
6549/* */
65500;
6551var UnmountSnapshot =
6552/* */
65532;
6554var UnmountMutation =
6555/* */
65564;
6557var MountMutation =
6558/* */
65598;
6560var UnmountLayout =
6561/* */
656216;
6563var MountLayout =
6564/* */
656532;
6566var MountPassive =
6567/* */
656864;
6569var UnmountPassive =
6570/* */
6571128;
6572
6573var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
6574var didWarnAboutMismatchedHooksForComponent;
6575
6576{
6577 didWarnAboutMismatchedHooksForComponent = new Set();
6578}
6579
6580// These are set right before calling the component.
6581var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
6582// the work-in-progress hook.
6583
6584var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
6585// current hook list is the list that belongs to the current fiber. The
6586// work-in-progress hook list is a new list that will be added to the
6587// work-in-progress fiber.
6588
6589var currentHook = null;
6590var nextCurrentHook = null;
6591var firstWorkInProgressHook = null;
6592var workInProgressHook = null;
6593var nextWorkInProgressHook = null;
6594var remainingExpirationTime = NoWork;
6595var componentUpdateQueue = null;
6596var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the
6597// end of the current pass. We can't store these updates on the normal queue,
6598// because if the work is aborted, they should be discarded. Because this is
6599// a relatively rare case, we also don't want to add an additional field to
6600// either the hook or queue object types. So we store them in a lazily create
6601// map of queue -> render-phase updates, which are discarded once the component
6602// completes without re-rendering.
6603// Whether an update was scheduled during the currently executing render pass.
6604
6605var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates
6606
6607var renderPhaseUpdates = null; // Counter to prevent infinite loops.
6608
6609var numberOfReRenders = 0;
6610var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
6611
6612var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
6613// The list stores the order of hooks used during the initial render (mount).
6614// Subsequent renders (updates) reference this list.
6615
6616var hookTypesDev = null;
6617var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
6618// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
6619// When true, such Hooks will always be "remounted". Only used during hot reload.
6620
6621var ignorePreviousDependencies = false;
6622
6623function mountHookTypesDev() {
6624 {
6625 var hookName = currentHookNameInDev;
6626
6627 if (hookTypesDev === null) {
6628 hookTypesDev = [hookName];
6629 } else {
6630 hookTypesDev.push(hookName);
6631 }
6632 }
6633}
6634
6635function updateHookTypesDev() {
6636 {
6637 var hookName = currentHookNameInDev;
6638
6639 if (hookTypesDev !== null) {
6640 hookTypesUpdateIndexDev++;
6641
6642 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
6643 warnOnHookMismatchInDev(hookName);
6644 }
6645 }
6646 }
6647}
6648
6649function checkDepsAreArrayDev(deps) {
6650 {
6651 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
6652 // Verify deps, but only on mount to avoid extra checks.
6653 // It's unlikely their type would change as usually you define them inline.
6654 warning$1(false, '%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
6655 }
6656 }
6657}
6658
6659function warnOnHookMismatchInDev(currentHookName) {
6660 {
6661 var componentName = getComponentName(currentlyRenderingFiber$1.type);
6662
6663 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
6664 didWarnAboutMismatchedHooksForComponent.add(componentName);
6665
6666 if (hookTypesDev !== null) {
6667 var table = '';
6668 var secondColumnStart = 30;
6669
6670 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
6671 var oldHookName = hookTypesDev[i];
6672 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
6673 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
6674 // lol @ IE not supporting String#repeat
6675
6676 while (row.length < secondColumnStart) {
6677 row += ' ';
6678 }
6679
6680 row += newHookName + '\n';
6681 table += row;
6682 }
6683
6684 warning$1(false, 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
6685 }
6686 }
6687 }
6688}
6689
6690function throwInvalidHookError() {
6691 (function () {
6692 {
6693 {
6694 throw ReactError(Error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem."));
6695 }
6696 }
6697 })();
6698}
6699
6700function areHookInputsEqual(nextDeps, prevDeps) {
6701 {
6702 if (ignorePreviousDependencies) {
6703 // Only true when this component is being hot reloaded.
6704 return false;
6705 }
6706 }
6707
6708 if (prevDeps === null) {
6709 {
6710 warning$1(false, '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
6711 }
6712
6713 return false;
6714 }
6715
6716 {
6717 // Don't bother comparing lengths in prod because these arrays should be
6718 // passed inline.
6719 if (nextDeps.length !== prevDeps.length) {
6720 warning$1(false, 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
6721 }
6722 }
6723
6724 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
6725 if (is$1(nextDeps[i], prevDeps[i])) {
6726 continue;
6727 }
6728
6729 return false;
6730 }
6731
6732 return true;
6733}
6734
6735function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
6736 renderExpirationTime$1 = nextRenderExpirationTime;
6737 currentlyRenderingFiber$1 = workInProgress;
6738 nextCurrentHook = current !== null ? current.memoizedState : null;
6739
6740 {
6741 hookTypesDev = current !== null ? current._debugHookTypes : null;
6742 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
6743
6744 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
6745 } // The following should have already been reset
6746 // currentHook = null;
6747 // workInProgressHook = null;
6748 // remainingExpirationTime = NoWork;
6749 // componentUpdateQueue = null;
6750 // didScheduleRenderPhaseUpdate = false;
6751 // renderPhaseUpdates = null;
6752 // numberOfReRenders = 0;
6753 // sideEffectTag = 0;
6754 // TODO Warn if no hooks are used at all during mount, then some are used during update.
6755 // Currently we will identify the update render as a mount because nextCurrentHook === null.
6756 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
6757 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
6758 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
6759 // so nextCurrentHook would be null during updates and mounts.
6760
6761
6762 {
6763 if (nextCurrentHook !== null) {
6764 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
6765 } else if (hookTypesDev !== null) {
6766 // This dispatcher handles an edge case where a component is updating,
6767 // but no stateful hooks have been used.
6768 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
6769 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
6770 // This dispatcher does that.
6771 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
6772 } else {
6773 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
6774 }
6775 }
6776
6777 var children = Component(props, refOrContext);
6778
6779 if (didScheduleRenderPhaseUpdate) {
6780 do {
6781 didScheduleRenderPhaseUpdate = false;
6782 numberOfReRenders += 1;
6783
6784 {
6785 // Even when hot reloading, allow dependencies to stabilize
6786 // after first render to prevent infinite render phase updates.
6787 ignorePreviousDependencies = false;
6788 } // Start over from the beginning of the list
6789
6790
6791 nextCurrentHook = current !== null ? current.memoizedState : null;
6792 nextWorkInProgressHook = firstWorkInProgressHook;
6793 currentHook = null;
6794 workInProgressHook = null;
6795 componentUpdateQueue = null;
6796
6797 {
6798 // Also validate hook order for cascading updates.
6799 hookTypesUpdateIndexDev = -1;
6800 }
6801
6802 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
6803 children = Component(props, refOrContext);
6804 } while (didScheduleRenderPhaseUpdate);
6805
6806 renderPhaseUpdates = null;
6807 numberOfReRenders = 0;
6808 } // We can assume the previous dispatcher is always this one, since we set it
6809 // at the beginning of the render phase and there's no re-entrancy.
6810
6811
6812 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
6813 var renderedWork = currentlyRenderingFiber$1;
6814 renderedWork.memoizedState = firstWorkInProgressHook;
6815 renderedWork.expirationTime = remainingExpirationTime;
6816 renderedWork.updateQueue = componentUpdateQueue;
6817 renderedWork.effectTag |= sideEffectTag;
6818
6819 {
6820 renderedWork._debugHookTypes = hookTypesDev;
6821 } // This check uses currentHook so that it works the same in DEV and prod bundles.
6822 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
6823
6824
6825 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
6826 renderExpirationTime$1 = NoWork;
6827 currentlyRenderingFiber$1 = null;
6828 currentHook = null;
6829 nextCurrentHook = null;
6830 firstWorkInProgressHook = null;
6831 workInProgressHook = null;
6832 nextWorkInProgressHook = null;
6833
6834 {
6835 currentHookNameInDev = null;
6836 hookTypesDev = null;
6837 hookTypesUpdateIndexDev = -1;
6838 }
6839
6840 remainingExpirationTime = NoWork;
6841 componentUpdateQueue = null;
6842 sideEffectTag = 0; // These were reset above
6843 // didScheduleRenderPhaseUpdate = false;
6844 // renderPhaseUpdates = null;
6845 // numberOfReRenders = 0;
6846
6847 (function () {
6848 if (!!didRenderTooFewHooks) {
6849 {
6850 throw ReactError(Error("Rendered fewer hooks than expected. This may be caused by an accidental early return statement."));
6851 }
6852 }
6853 })();
6854
6855 return children;
6856}
6857function bailoutHooks(current, workInProgress, expirationTime) {
6858 workInProgress.updateQueue = current.updateQueue;
6859 workInProgress.effectTag &= ~(Passive | Update);
6860
6861 if (current.expirationTime <= expirationTime) {
6862 current.expirationTime = NoWork;
6863 }
6864}
6865function resetHooks() {
6866 // We can assume the previous dispatcher is always this one, since we set it
6867 // at the beginning of the render phase and there's no re-entrancy.
6868 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws.
6869 // It's also called inside mountIndeterminateComponent if we determine the
6870 // component is a module-style component.
6871
6872 renderExpirationTime$1 = NoWork;
6873 currentlyRenderingFiber$1 = null;
6874 currentHook = null;
6875 nextCurrentHook = null;
6876 firstWorkInProgressHook = null;
6877 workInProgressHook = null;
6878 nextWorkInProgressHook = null;
6879
6880 {
6881 hookTypesDev = null;
6882 hookTypesUpdateIndexDev = -1;
6883 currentHookNameInDev = null;
6884 }
6885
6886 remainingExpirationTime = NoWork;
6887 componentUpdateQueue = null;
6888 sideEffectTag = 0;
6889 didScheduleRenderPhaseUpdate = false;
6890 renderPhaseUpdates = null;
6891 numberOfReRenders = 0;
6892}
6893
6894function mountWorkInProgressHook() {
6895 var hook = {
6896 memoizedState: null,
6897 baseState: null,
6898 queue: null,
6899 baseUpdate: null,
6900 next: null
6901 };
6902
6903 if (workInProgressHook === null) {
6904 // This is the first hook in the list
6905 firstWorkInProgressHook = workInProgressHook = hook;
6906 } else {
6907 // Append to the end of the list
6908 workInProgressHook = workInProgressHook.next = hook;
6909 }
6910
6911 return workInProgressHook;
6912}
6913
6914function updateWorkInProgressHook() {
6915 // This function is used both for updates and for re-renders triggered by a
6916 // render phase update. It assumes there is either a current hook we can
6917 // clone, or a work-in-progress hook from a previous render pass that we can
6918 // use as a base. When we reach the end of the base list, we must switch to
6919 // the dispatcher used for mounts.
6920 if (nextWorkInProgressHook !== null) {
6921 // There's already a work-in-progress. Reuse it.
6922 workInProgressHook = nextWorkInProgressHook;
6923 nextWorkInProgressHook = workInProgressHook.next;
6924 currentHook = nextCurrentHook;
6925 nextCurrentHook = currentHook !== null ? currentHook.next : null;
6926 } else {
6927 // Clone from the current hook.
6928 (function () {
6929 if (!(nextCurrentHook !== null)) {
6930 {
6931 throw ReactError(Error("Rendered more hooks than during the previous render."));
6932 }
6933 }
6934 })();
6935
6936 currentHook = nextCurrentHook;
6937 var newHook = {
6938 memoizedState: currentHook.memoizedState,
6939 baseState: currentHook.baseState,
6940 queue: currentHook.queue,
6941 baseUpdate: currentHook.baseUpdate,
6942 next: null
6943 };
6944
6945 if (workInProgressHook === null) {
6946 // This is the first hook in the list.
6947 workInProgressHook = firstWorkInProgressHook = newHook;
6948 } else {
6949 // Append to the end of the list.
6950 workInProgressHook = workInProgressHook.next = newHook;
6951 }
6952
6953 nextCurrentHook = currentHook.next;
6954 }
6955
6956 return workInProgressHook;
6957}
6958
6959function createFunctionComponentUpdateQueue() {
6960 return {
6961 lastEffect: null
6962 };
6963}
6964
6965function basicStateReducer(state, action) {
6966 return typeof action === 'function' ? action(state) : action;
6967}
6968
6969function mountReducer(reducer, initialArg, init) {
6970 var hook = mountWorkInProgressHook();
6971 var initialState;
6972
6973 if (init !== undefined) {
6974 initialState = init(initialArg);
6975 } else {
6976 initialState = initialArg;
6977 }
6978
6979 hook.memoizedState = hook.baseState = initialState;
6980 var queue = hook.queue = {
6981 last: null,
6982 dispatch: null,
6983 lastRenderedReducer: reducer,
6984 lastRenderedState: initialState
6985 };
6986 var dispatch = queue.dispatch = dispatchAction.bind(null, // Flow doesn't know this is non-null, but we do.
6987 currentlyRenderingFiber$1, queue);
6988 return [hook.memoizedState, dispatch];
6989}
6990
6991function updateReducer(reducer, initialArg, init) {
6992 var hook = updateWorkInProgressHook();
6993 var queue = hook.queue;
6994
6995 (function () {
6996 if (!(queue !== null)) {
6997 {
6998 throw ReactError(Error("Should have a queue. This is likely a bug in React. Please file an issue."));
6999 }
7000 }
7001 })();
7002
7003 queue.lastRenderedReducer = reducer;
7004
7005 if (numberOfReRenders > 0) {
7006 // This is a re-render. Apply the new render phase updates to the previous
7007 // work-in-progress hook.
7008 var _dispatch = queue.dispatch;
7009
7010 if (renderPhaseUpdates !== null) {
7011 // Render phase updates are stored in a map of queue -> linked list
7012 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
7013
7014 if (firstRenderPhaseUpdate !== undefined) {
7015 renderPhaseUpdates.delete(queue);
7016 var newState = hook.memoizedState;
7017 var update = firstRenderPhaseUpdate;
7018
7019 do {
7020 // Process this render phase update. We don't have to check the
7021 // priority because it will always be the same as the current
7022 // render's.
7023 var action = update.action;
7024 newState = reducer(newState, action);
7025 update = update.next;
7026 } while (update !== null); // Mark that the fiber performed work, but only if the new state is
7027 // different from the current state.
7028
7029
7030 if (!is$1(newState, hook.memoizedState)) {
7031 markWorkInProgressReceivedUpdate();
7032 }
7033
7034 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
7035 // the base state unless the queue is empty.
7036 // TODO: Not sure if this is the desired semantics, but it's what we
7037 // do for gDSFP. I can't remember why.
7038
7039 if (hook.baseUpdate === queue.last) {
7040 hook.baseState = newState;
7041 }
7042
7043 queue.lastRenderedState = newState;
7044 return [newState, _dispatch];
7045 }
7046 }
7047
7048 return [hook.memoizedState, _dispatch];
7049 } // The last update in the entire queue
7050
7051
7052 var last = queue.last; // The last update that is part of the base state.
7053
7054 var baseUpdate = hook.baseUpdate;
7055 var baseState = hook.baseState; // Find the first unprocessed update.
7056
7057 var first;
7058
7059 if (baseUpdate !== null) {
7060 if (last !== null) {
7061 // For the first update, the queue is a circular linked list where
7062 // `queue.last.next = queue.first`. Once the first update commits, and
7063 // the `baseUpdate` is no longer empty, we can unravel the list.
7064 last.next = null;
7065 }
7066
7067 first = baseUpdate.next;
7068 } else {
7069 first = last !== null ? last.next : null;
7070 }
7071
7072 if (first !== null) {
7073 var _newState = baseState;
7074 var newBaseState = null;
7075 var newBaseUpdate = null;
7076 var prevUpdate = baseUpdate;
7077 var _update = first;
7078 var didSkip = false;
7079
7080 do {
7081 var updateExpirationTime = _update.expirationTime;
7082
7083 if (updateExpirationTime < renderExpirationTime$1) {
7084 // Priority is insufficient. Skip this update. If this is the first
7085 // skipped update, the previous update/state is the new base
7086 // update/state.
7087 if (!didSkip) {
7088 didSkip = true;
7089 newBaseUpdate = prevUpdate;
7090 newBaseState = _newState;
7091 } // Update the remaining priority in the queue.
7092
7093
7094 if (updateExpirationTime > remainingExpirationTime) {
7095 remainingExpirationTime = updateExpirationTime;
7096 markUnprocessedUpdateTime(remainingExpirationTime);
7097 }
7098 } else {
7099 // This update does have sufficient priority.
7100 // Mark the event time of this update as relevant to this render pass.
7101 // TODO: This should ideally use the true event time of this update rather than
7102 // its priority which is a derived and not reverseable value.
7103 // TODO: We should skip this update if it was already committed but currently
7104 // we have no way of detecting the difference between a committed and suspended
7105 // update here.
7106 markRenderEventTimeAndConfig(updateExpirationTime, _update.suspenseConfig); // Process this update.
7107
7108 if (_update.eagerReducer === reducer) {
7109 // If this update was processed eagerly, and its reducer matches the
7110 // current reducer, we can use the eagerly computed state.
7111 _newState = _update.eagerState;
7112 } else {
7113 var _action = _update.action;
7114 _newState = reducer(_newState, _action);
7115 }
7116 }
7117
7118 prevUpdate = _update;
7119 _update = _update.next;
7120 } while (_update !== null && _update !== first);
7121
7122 if (!didSkip) {
7123 newBaseUpdate = prevUpdate;
7124 newBaseState = _newState;
7125 } // Mark that the fiber performed work, but only if the new state is
7126 // different from the current state.
7127
7128
7129 if (!is$1(_newState, hook.memoizedState)) {
7130 markWorkInProgressReceivedUpdate();
7131 }
7132
7133 hook.memoizedState = _newState;
7134 hook.baseUpdate = newBaseUpdate;
7135 hook.baseState = newBaseState;
7136 queue.lastRenderedState = _newState;
7137 }
7138
7139 var dispatch = queue.dispatch;
7140 return [hook.memoizedState, dispatch];
7141}
7142
7143function mountState(initialState) {
7144 var hook = mountWorkInProgressHook();
7145
7146 if (typeof initialState === 'function') {
7147 initialState = initialState();
7148 }
7149
7150 hook.memoizedState = hook.baseState = initialState;
7151 var queue = hook.queue = {
7152 last: null,
7153 dispatch: null,
7154 lastRenderedReducer: basicStateReducer,
7155 lastRenderedState: initialState
7156 };
7157 var dispatch = queue.dispatch = dispatchAction.bind(null, // Flow doesn't know this is non-null, but we do.
7158 currentlyRenderingFiber$1, queue);
7159 return [hook.memoizedState, dispatch];
7160}
7161
7162function updateState(initialState) {
7163 return updateReducer(basicStateReducer, initialState);
7164}
7165
7166function pushEffect(tag, create, destroy, deps) {
7167 var effect = {
7168 tag: tag,
7169 create: create,
7170 destroy: destroy,
7171 deps: deps,
7172 // Circular
7173 next: null
7174 };
7175
7176 if (componentUpdateQueue === null) {
7177 componentUpdateQueue = createFunctionComponentUpdateQueue();
7178 componentUpdateQueue.lastEffect = effect.next = effect;
7179 } else {
7180 var lastEffect = componentUpdateQueue.lastEffect;
7181
7182 if (lastEffect === null) {
7183 componentUpdateQueue.lastEffect = effect.next = effect;
7184 } else {
7185 var firstEffect = lastEffect.next;
7186 lastEffect.next = effect;
7187 effect.next = firstEffect;
7188 componentUpdateQueue.lastEffect = effect;
7189 }
7190 }
7191
7192 return effect;
7193}
7194
7195function mountRef(initialValue) {
7196 var hook = mountWorkInProgressHook();
7197 var ref = {
7198 current: initialValue
7199 };
7200
7201 {
7202 Object.seal(ref);
7203 }
7204
7205 hook.memoizedState = ref;
7206 return ref;
7207}
7208
7209function updateRef(initialValue) {
7210 var hook = updateWorkInProgressHook();
7211 return hook.memoizedState;
7212}
7213
7214function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
7215 var hook = mountWorkInProgressHook();
7216 var nextDeps = deps === undefined ? null : deps;
7217 sideEffectTag |= fiberEffectTag;
7218 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
7219}
7220
7221function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
7222 var hook = updateWorkInProgressHook();
7223 var nextDeps = deps === undefined ? null : deps;
7224 var destroy = undefined;
7225
7226 if (currentHook !== null) {
7227 var prevEffect = currentHook.memoizedState;
7228 destroy = prevEffect.destroy;
7229
7230 if (nextDeps !== null) {
7231 var prevDeps = prevEffect.deps;
7232
7233 if (areHookInputsEqual(nextDeps, prevDeps)) {
7234 pushEffect(NoEffect$1, create, destroy, nextDeps);
7235 return;
7236 }
7237 }
7238 }
7239
7240 sideEffectTag |= fiberEffectTag;
7241 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
7242}
7243
7244function mountEffect(create, deps) {
7245 {
7246 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
7247 if ('undefined' !== typeof jest) {
7248 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
7249 }
7250 }
7251
7252 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
7253}
7254
7255function updateEffect(create, deps) {
7256 {
7257 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
7258 if ('undefined' !== typeof jest) {
7259 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
7260 }
7261 }
7262
7263 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
7264}
7265
7266function mountLayoutEffect(create, deps) {
7267 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
7268}
7269
7270function updateLayoutEffect(create, deps) {
7271 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
7272}
7273
7274function imperativeHandleEffect(create, ref) {
7275 if (typeof ref === 'function') {
7276 var refCallback = ref;
7277
7278 var _inst = create();
7279
7280 refCallback(_inst);
7281 return function () {
7282 refCallback(null);
7283 };
7284 } else if (ref !== null && ref !== undefined) {
7285 var refObject = ref;
7286
7287 {
7288 !refObject.hasOwnProperty('current') ? warning$1(false, 'Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}') : void 0;
7289 }
7290
7291 var _inst2 = create();
7292
7293 refObject.current = _inst2;
7294 return function () {
7295 refObject.current = null;
7296 };
7297 }
7298}
7299
7300function mountImperativeHandle(ref, create, deps) {
7301 {
7302 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
7303 } // TODO: If deps are provided, should we skip comparing the ref itself?
7304
7305
7306 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
7307 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
7308}
7309
7310function updateImperativeHandle(ref, create, deps) {
7311 {
7312 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
7313 } // TODO: If deps are provided, should we skip comparing the ref itself?
7314
7315
7316 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
7317 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
7318}
7319
7320function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
7321 // The react-debug-hooks package injects its own implementation
7322 // so that e.g. DevTools can display custom hook values.
7323}
7324
7325var updateDebugValue = mountDebugValue;
7326
7327function mountCallback(callback, deps) {
7328 var hook = mountWorkInProgressHook();
7329 var nextDeps = deps === undefined ? null : deps;
7330 hook.memoizedState = [callback, nextDeps];
7331 return callback;
7332}
7333
7334function updateCallback(callback, deps) {
7335 var hook = updateWorkInProgressHook();
7336 var nextDeps = deps === undefined ? null : deps;
7337 var prevState = hook.memoizedState;
7338
7339 if (prevState !== null) {
7340 if (nextDeps !== null) {
7341 var prevDeps = prevState[1];
7342
7343 if (areHookInputsEqual(nextDeps, prevDeps)) {
7344 return prevState[0];
7345 }
7346 }
7347 }
7348
7349 hook.memoizedState = [callback, nextDeps];
7350 return callback;
7351}
7352
7353function mountMemo(nextCreate, deps) {
7354 var hook = mountWorkInProgressHook();
7355 var nextDeps = deps === undefined ? null : deps;
7356 var nextValue = nextCreate();
7357 hook.memoizedState = [nextValue, nextDeps];
7358 return nextValue;
7359}
7360
7361function updateMemo(nextCreate, deps) {
7362 var hook = updateWorkInProgressHook();
7363 var nextDeps = deps === undefined ? null : deps;
7364 var prevState = hook.memoizedState;
7365
7366 if (prevState !== null) {
7367 // Assume these are defined. If they're not, areHookInputsEqual will warn.
7368 if (nextDeps !== null) {
7369 var prevDeps = prevState[1];
7370
7371 if (areHookInputsEqual(nextDeps, prevDeps)) {
7372 return prevState[0];
7373 }
7374 }
7375 }
7376
7377 var nextValue = nextCreate();
7378 hook.memoizedState = [nextValue, nextDeps];
7379 return nextValue;
7380}
7381
7382function dispatchAction(fiber, queue, action) {
7383 (function () {
7384 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
7385 {
7386 throw ReactError(Error("Too many re-renders. React limits the number of renders to prevent an infinite loop."));
7387 }
7388 }
7389 })();
7390
7391 {
7392 !(typeof arguments[3] !== 'function') ? warning$1(false, "State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().') : void 0;
7393 }
7394
7395 var alternate = fiber.alternate;
7396
7397 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
7398 // This is a render phase update. Stash it in a lazily-created map of
7399 // queue -> linked list of updates. After this render pass, we'll restart
7400 // and apply the stashed updates on top of the work-in-progress hook.
7401 didScheduleRenderPhaseUpdate = true;
7402 var update = {
7403 expirationTime: renderExpirationTime$1,
7404 suspenseConfig: null,
7405 action: action,
7406 eagerReducer: null,
7407 eagerState: null,
7408 next: null
7409 };
7410
7411 {
7412 update.priority = getCurrentPriorityLevel();
7413 }
7414
7415 if (renderPhaseUpdates === null) {
7416 renderPhaseUpdates = new Map();
7417 }
7418
7419 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
7420
7421 if (firstRenderPhaseUpdate === undefined) {
7422 renderPhaseUpdates.set(queue, update);
7423 } else {
7424 // Append the update to the end of the list.
7425 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
7426
7427 while (lastRenderPhaseUpdate.next !== null) {
7428 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
7429 }
7430
7431 lastRenderPhaseUpdate.next = update;
7432 }
7433 } else {
7434 var currentTime = requestCurrentTime();
7435 var suspenseConfig = requestCurrentSuspenseConfig();
7436 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
7437 var _update2 = {
7438 expirationTime: expirationTime,
7439 suspenseConfig: suspenseConfig,
7440 action: action,
7441 eagerReducer: null,
7442 eagerState: null,
7443 next: null
7444 };
7445
7446 {
7447 _update2.priority = getCurrentPriorityLevel();
7448 } // Append the update to the end of the list.
7449
7450
7451 var last = queue.last;
7452
7453 if (last === null) {
7454 // This is the first update. Create a circular list.
7455 _update2.next = _update2;
7456 } else {
7457 var first = last.next;
7458
7459 if (first !== null) {
7460 // Still circular.
7461 _update2.next = first;
7462 }
7463
7464 last.next = _update2;
7465 }
7466
7467 queue.last = _update2;
7468
7469 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
7470 // The queue is currently empty, which means we can eagerly compute the
7471 // next state before entering the render phase. If the new state is the
7472 // same as the current state, we may be able to bail out entirely.
7473 var lastRenderedReducer = queue.lastRenderedReducer;
7474
7475 if (lastRenderedReducer !== null) {
7476 var prevDispatcher;
7477
7478 {
7479 prevDispatcher = ReactCurrentDispatcher$1.current;
7480 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7481 }
7482
7483 try {
7484 var currentState = queue.lastRenderedState;
7485 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
7486 // it, on the update object. If the reducer hasn't changed by the
7487 // time we enter the render phase, then the eager state can be used
7488 // without calling the reducer again.
7489
7490 _update2.eagerReducer = lastRenderedReducer;
7491 _update2.eagerState = eagerState;
7492
7493 if (is$1(eagerState, currentState)) {
7494 // Fast path. We can bail out without scheduling React to re-render.
7495 // It's still possible that we'll need to rebase this update later,
7496 // if the component re-renders for a different reason and by that
7497 // time the reducer has changed.
7498 return;
7499 }
7500 } catch (error) {// Suppress the error. It will throw again in the render phase.
7501 } finally {
7502 {
7503 ReactCurrentDispatcher$1.current = prevDispatcher;
7504 }
7505 }
7506 }
7507 }
7508
7509 {
7510 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
7511 if ('undefined' !== typeof jest) {
7512 warnIfNotScopedWithMatchingAct(fiber);
7513 warnIfNotCurrentlyActingUpdatesInDev(fiber);
7514 }
7515 }
7516
7517 scheduleWork(fiber, expirationTime);
7518 }
7519}
7520
7521var ContextOnlyDispatcher = {
7522 readContext: readContext,
7523 useCallback: throwInvalidHookError,
7524 useContext: throwInvalidHookError,
7525 useEffect: throwInvalidHookError,
7526 useImperativeHandle: throwInvalidHookError,
7527 useLayoutEffect: throwInvalidHookError,
7528 useMemo: throwInvalidHookError,
7529 useReducer: throwInvalidHookError,
7530 useRef: throwInvalidHookError,
7531 useState: throwInvalidHookError,
7532 useDebugValue: throwInvalidHookError,
7533 useResponder: throwInvalidHookError
7534};
7535var HooksDispatcherOnMountInDEV = null;
7536var HooksDispatcherOnMountWithHookTypesInDEV = null;
7537var HooksDispatcherOnUpdateInDEV = null;
7538var InvalidNestedHooksDispatcherOnMountInDEV = null;
7539var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
7540
7541{
7542 var warnInvalidContextAccess = function () {
7543 warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
7544 };
7545
7546 var warnInvalidHookAccess = function () {
7547 warning$1(false, 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');
7548 };
7549
7550 HooksDispatcherOnMountInDEV = {
7551 readContext: function (context, observedBits) {
7552 return readContext(context, observedBits);
7553 },
7554 useCallback: function (callback, deps) {
7555 currentHookNameInDev = 'useCallback';
7556 mountHookTypesDev();
7557 checkDepsAreArrayDev(deps);
7558 return mountCallback(callback, deps);
7559 },
7560 useContext: function (context, observedBits) {
7561 currentHookNameInDev = 'useContext';
7562 mountHookTypesDev();
7563 return readContext(context, observedBits);
7564 },
7565 useEffect: function (create, deps) {
7566 currentHookNameInDev = 'useEffect';
7567 mountHookTypesDev();
7568 checkDepsAreArrayDev(deps);
7569 return mountEffect(create, deps);
7570 },
7571 useImperativeHandle: function (ref, create, deps) {
7572 currentHookNameInDev = 'useImperativeHandle';
7573 mountHookTypesDev();
7574 checkDepsAreArrayDev(deps);
7575 return mountImperativeHandle(ref, create, deps);
7576 },
7577 useLayoutEffect: function (create, deps) {
7578 currentHookNameInDev = 'useLayoutEffect';
7579 mountHookTypesDev();
7580 checkDepsAreArrayDev(deps);
7581 return mountLayoutEffect(create, deps);
7582 },
7583 useMemo: function (create, deps) {
7584 currentHookNameInDev = 'useMemo';
7585 mountHookTypesDev();
7586 checkDepsAreArrayDev(deps);
7587 var prevDispatcher = ReactCurrentDispatcher$1.current;
7588 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7589
7590 try {
7591 return mountMemo(create, deps);
7592 } finally {
7593 ReactCurrentDispatcher$1.current = prevDispatcher;
7594 }
7595 },
7596 useReducer: function (reducer, initialArg, init) {
7597 currentHookNameInDev = 'useReducer';
7598 mountHookTypesDev();
7599 var prevDispatcher = ReactCurrentDispatcher$1.current;
7600 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7601
7602 try {
7603 return mountReducer(reducer, initialArg, init);
7604 } finally {
7605 ReactCurrentDispatcher$1.current = prevDispatcher;
7606 }
7607 },
7608 useRef: function (initialValue) {
7609 currentHookNameInDev = 'useRef';
7610 mountHookTypesDev();
7611 return mountRef(initialValue);
7612 },
7613 useState: function (initialState) {
7614 currentHookNameInDev = 'useState';
7615 mountHookTypesDev();
7616 var prevDispatcher = ReactCurrentDispatcher$1.current;
7617 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7618
7619 try {
7620 return mountState(initialState);
7621 } finally {
7622 ReactCurrentDispatcher$1.current = prevDispatcher;
7623 }
7624 },
7625 useDebugValue: function (value, formatterFn) {
7626 currentHookNameInDev = 'useDebugValue';
7627 mountHookTypesDev();
7628 return mountDebugValue(value, formatterFn);
7629 },
7630 useResponder: function (responder, props) {
7631 currentHookNameInDev = 'useResponder';
7632 mountHookTypesDev();
7633 return createResponderListener(responder, props);
7634 }
7635 };
7636 HooksDispatcherOnMountWithHookTypesInDEV = {
7637 readContext: function (context, observedBits) {
7638 return readContext(context, observedBits);
7639 },
7640 useCallback: function (callback, deps) {
7641 currentHookNameInDev = 'useCallback';
7642 updateHookTypesDev();
7643 return mountCallback(callback, deps);
7644 },
7645 useContext: function (context, observedBits) {
7646 currentHookNameInDev = 'useContext';
7647 updateHookTypesDev();
7648 return readContext(context, observedBits);
7649 },
7650 useEffect: function (create, deps) {
7651 currentHookNameInDev = 'useEffect';
7652 updateHookTypesDev();
7653 return mountEffect(create, deps);
7654 },
7655 useImperativeHandle: function (ref, create, deps) {
7656 currentHookNameInDev = 'useImperativeHandle';
7657 updateHookTypesDev();
7658 return mountImperativeHandle(ref, create, deps);
7659 },
7660 useLayoutEffect: function (create, deps) {
7661 currentHookNameInDev = 'useLayoutEffect';
7662 updateHookTypesDev();
7663 return mountLayoutEffect(create, deps);
7664 },
7665 useMemo: function (create, deps) {
7666 currentHookNameInDev = 'useMemo';
7667 updateHookTypesDev();
7668 var prevDispatcher = ReactCurrentDispatcher$1.current;
7669 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7670
7671 try {
7672 return mountMemo(create, deps);
7673 } finally {
7674 ReactCurrentDispatcher$1.current = prevDispatcher;
7675 }
7676 },
7677 useReducer: function (reducer, initialArg, init) {
7678 currentHookNameInDev = 'useReducer';
7679 updateHookTypesDev();
7680 var prevDispatcher = ReactCurrentDispatcher$1.current;
7681 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7682
7683 try {
7684 return mountReducer(reducer, initialArg, init);
7685 } finally {
7686 ReactCurrentDispatcher$1.current = prevDispatcher;
7687 }
7688 },
7689 useRef: function (initialValue) {
7690 currentHookNameInDev = 'useRef';
7691 updateHookTypesDev();
7692 return mountRef(initialValue);
7693 },
7694 useState: function (initialState) {
7695 currentHookNameInDev = 'useState';
7696 updateHookTypesDev();
7697 var prevDispatcher = ReactCurrentDispatcher$1.current;
7698 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7699
7700 try {
7701 return mountState(initialState);
7702 } finally {
7703 ReactCurrentDispatcher$1.current = prevDispatcher;
7704 }
7705 },
7706 useDebugValue: function (value, formatterFn) {
7707 currentHookNameInDev = 'useDebugValue';
7708 updateHookTypesDev();
7709 return mountDebugValue(value, formatterFn);
7710 },
7711 useResponder: function (responder, props) {
7712 currentHookNameInDev = 'useResponder';
7713 updateHookTypesDev();
7714 return createResponderListener(responder, props);
7715 }
7716 };
7717 HooksDispatcherOnUpdateInDEV = {
7718 readContext: function (context, observedBits) {
7719 return readContext(context, observedBits);
7720 },
7721 useCallback: function (callback, deps) {
7722 currentHookNameInDev = 'useCallback';
7723 updateHookTypesDev();
7724 return updateCallback(callback, deps);
7725 },
7726 useContext: function (context, observedBits) {
7727 currentHookNameInDev = 'useContext';
7728 updateHookTypesDev();
7729 return readContext(context, observedBits);
7730 },
7731 useEffect: function (create, deps) {
7732 currentHookNameInDev = 'useEffect';
7733 updateHookTypesDev();
7734 return updateEffect(create, deps);
7735 },
7736 useImperativeHandle: function (ref, create, deps) {
7737 currentHookNameInDev = 'useImperativeHandle';
7738 updateHookTypesDev();
7739 return updateImperativeHandle(ref, create, deps);
7740 },
7741 useLayoutEffect: function (create, deps) {
7742 currentHookNameInDev = 'useLayoutEffect';
7743 updateHookTypesDev();
7744 return updateLayoutEffect(create, deps);
7745 },
7746 useMemo: function (create, deps) {
7747 currentHookNameInDev = 'useMemo';
7748 updateHookTypesDev();
7749 var prevDispatcher = ReactCurrentDispatcher$1.current;
7750 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7751
7752 try {
7753 return updateMemo(create, deps);
7754 } finally {
7755 ReactCurrentDispatcher$1.current = prevDispatcher;
7756 }
7757 },
7758 useReducer: function (reducer, initialArg, init) {
7759 currentHookNameInDev = 'useReducer';
7760 updateHookTypesDev();
7761 var prevDispatcher = ReactCurrentDispatcher$1.current;
7762 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7763
7764 try {
7765 return updateReducer(reducer, initialArg, init);
7766 } finally {
7767 ReactCurrentDispatcher$1.current = prevDispatcher;
7768 }
7769 },
7770 useRef: function (initialValue) {
7771 currentHookNameInDev = 'useRef';
7772 updateHookTypesDev();
7773 return updateRef(initialValue);
7774 },
7775 useState: function (initialState) {
7776 currentHookNameInDev = 'useState';
7777 updateHookTypesDev();
7778 var prevDispatcher = ReactCurrentDispatcher$1.current;
7779 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7780
7781 try {
7782 return updateState(initialState);
7783 } finally {
7784 ReactCurrentDispatcher$1.current = prevDispatcher;
7785 }
7786 },
7787 useDebugValue: function (value, formatterFn) {
7788 currentHookNameInDev = 'useDebugValue';
7789 updateHookTypesDev();
7790 return updateDebugValue(value, formatterFn);
7791 },
7792 useResponder: function (responder, props) {
7793 currentHookNameInDev = 'useResponder';
7794 updateHookTypesDev();
7795 return createResponderListener(responder, props);
7796 }
7797 };
7798 InvalidNestedHooksDispatcherOnMountInDEV = {
7799 readContext: function (context, observedBits) {
7800 warnInvalidContextAccess();
7801 return readContext(context, observedBits);
7802 },
7803 useCallback: function (callback, deps) {
7804 currentHookNameInDev = 'useCallback';
7805 warnInvalidHookAccess();
7806 mountHookTypesDev();
7807 return mountCallback(callback, deps);
7808 },
7809 useContext: function (context, observedBits) {
7810 currentHookNameInDev = 'useContext';
7811 warnInvalidHookAccess();
7812 mountHookTypesDev();
7813 return readContext(context, observedBits);
7814 },
7815 useEffect: function (create, deps) {
7816 currentHookNameInDev = 'useEffect';
7817 warnInvalidHookAccess();
7818 mountHookTypesDev();
7819 return mountEffect(create, deps);
7820 },
7821 useImperativeHandle: function (ref, create, deps) {
7822 currentHookNameInDev = 'useImperativeHandle';
7823 warnInvalidHookAccess();
7824 mountHookTypesDev();
7825 return mountImperativeHandle(ref, create, deps);
7826 },
7827 useLayoutEffect: function (create, deps) {
7828 currentHookNameInDev = 'useLayoutEffect';
7829 warnInvalidHookAccess();
7830 mountHookTypesDev();
7831 return mountLayoutEffect(create, deps);
7832 },
7833 useMemo: function (create, deps) {
7834 currentHookNameInDev = 'useMemo';
7835 warnInvalidHookAccess();
7836 mountHookTypesDev();
7837 var prevDispatcher = ReactCurrentDispatcher$1.current;
7838 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7839
7840 try {
7841 return mountMemo(create, deps);
7842 } finally {
7843 ReactCurrentDispatcher$1.current = prevDispatcher;
7844 }
7845 },
7846 useReducer: function (reducer, initialArg, init) {
7847 currentHookNameInDev = 'useReducer';
7848 warnInvalidHookAccess();
7849 mountHookTypesDev();
7850 var prevDispatcher = ReactCurrentDispatcher$1.current;
7851 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7852
7853 try {
7854 return mountReducer(reducer, initialArg, init);
7855 } finally {
7856 ReactCurrentDispatcher$1.current = prevDispatcher;
7857 }
7858 },
7859 useRef: function (initialValue) {
7860 currentHookNameInDev = 'useRef';
7861 warnInvalidHookAccess();
7862 mountHookTypesDev();
7863 return mountRef(initialValue);
7864 },
7865 useState: function (initialState) {
7866 currentHookNameInDev = 'useState';
7867 warnInvalidHookAccess();
7868 mountHookTypesDev();
7869 var prevDispatcher = ReactCurrentDispatcher$1.current;
7870 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7871
7872 try {
7873 return mountState(initialState);
7874 } finally {
7875 ReactCurrentDispatcher$1.current = prevDispatcher;
7876 }
7877 },
7878 useDebugValue: function (value, formatterFn) {
7879 currentHookNameInDev = 'useDebugValue';
7880 warnInvalidHookAccess();
7881 mountHookTypesDev();
7882 return mountDebugValue(value, formatterFn);
7883 },
7884 useResponder: function (responder, props) {
7885 currentHookNameInDev = 'useResponder';
7886 warnInvalidHookAccess();
7887 mountHookTypesDev();
7888 return createResponderListener(responder, props);
7889 }
7890 };
7891 InvalidNestedHooksDispatcherOnUpdateInDEV = {
7892 readContext: function (context, observedBits) {
7893 warnInvalidContextAccess();
7894 return readContext(context, observedBits);
7895 },
7896 useCallback: function (callback, deps) {
7897 currentHookNameInDev = 'useCallback';
7898 warnInvalidHookAccess();
7899 updateHookTypesDev();
7900 return updateCallback(callback, deps);
7901 },
7902 useContext: function (context, observedBits) {
7903 currentHookNameInDev = 'useContext';
7904 warnInvalidHookAccess();
7905 updateHookTypesDev();
7906 return readContext(context, observedBits);
7907 },
7908 useEffect: function (create, deps) {
7909 currentHookNameInDev = 'useEffect';
7910 warnInvalidHookAccess();
7911 updateHookTypesDev();
7912 return updateEffect(create, deps);
7913 },
7914 useImperativeHandle: function (ref, create, deps) {
7915 currentHookNameInDev = 'useImperativeHandle';
7916 warnInvalidHookAccess();
7917 updateHookTypesDev();
7918 return updateImperativeHandle(ref, create, deps);
7919 },
7920 useLayoutEffect: function (create, deps) {
7921 currentHookNameInDev = 'useLayoutEffect';
7922 warnInvalidHookAccess();
7923 updateHookTypesDev();
7924 return updateLayoutEffect(create, deps);
7925 },
7926 useMemo: function (create, deps) {
7927 currentHookNameInDev = 'useMemo';
7928 warnInvalidHookAccess();
7929 updateHookTypesDev();
7930 var prevDispatcher = ReactCurrentDispatcher$1.current;
7931 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7932
7933 try {
7934 return updateMemo(create, deps);
7935 } finally {
7936 ReactCurrentDispatcher$1.current = prevDispatcher;
7937 }
7938 },
7939 useReducer: function (reducer, initialArg, init) {
7940 currentHookNameInDev = 'useReducer';
7941 warnInvalidHookAccess();
7942 updateHookTypesDev();
7943 var prevDispatcher = ReactCurrentDispatcher$1.current;
7944 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7945
7946 try {
7947 return updateReducer(reducer, initialArg, init);
7948 } finally {
7949 ReactCurrentDispatcher$1.current = prevDispatcher;
7950 }
7951 },
7952 useRef: function (initialValue) {
7953 currentHookNameInDev = 'useRef';
7954 warnInvalidHookAccess();
7955 updateHookTypesDev();
7956 return updateRef(initialValue);
7957 },
7958 useState: function (initialState) {
7959 currentHookNameInDev = 'useState';
7960 warnInvalidHookAccess();
7961 updateHookTypesDev();
7962 var prevDispatcher = ReactCurrentDispatcher$1.current;
7963 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7964
7965 try {
7966 return updateState(initialState);
7967 } finally {
7968 ReactCurrentDispatcher$1.current = prevDispatcher;
7969 }
7970 },
7971 useDebugValue: function (value, formatterFn) {
7972 currentHookNameInDev = 'useDebugValue';
7973 warnInvalidHookAccess();
7974 updateHookTypesDev();
7975 return updateDebugValue(value, formatterFn);
7976 },
7977 useResponder: function (responder, props) {
7978 currentHookNameInDev = 'useResponder';
7979 warnInvalidHookAccess();
7980 updateHookTypesDev();
7981 return createResponderListener(responder, props);
7982 }
7983 };
7984}
7985
7986// CommonJS interop named imports.
7987
7988var now$1 = unstable_now;
7989var commitTime = 0;
7990var profilerStartTime = -1;
7991
7992function getCommitTime() {
7993 return commitTime;
7994}
7995
7996function recordCommitTime() {
7997 if (!enableProfilerTimer) {
7998 return;
7999 }
8000
8001 commitTime = now$1();
8002}
8003
8004function startProfilerTimer(fiber) {
8005 if (!enableProfilerTimer) {
8006 return;
8007 }
8008
8009 profilerStartTime = now$1();
8010
8011 if (fiber.actualStartTime < 0) {
8012 fiber.actualStartTime = now$1();
8013 }
8014}
8015
8016function stopProfilerTimerIfRunning(fiber) {
8017 if (!enableProfilerTimer) {
8018 return;
8019 }
8020
8021 profilerStartTime = -1;
8022}
8023
8024function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
8025 if (!enableProfilerTimer) {
8026 return;
8027 }
8028
8029 if (profilerStartTime >= 0) {
8030 var elapsedTime = now$1() - profilerStartTime;
8031 fiber.actualDuration += elapsedTime;
8032
8033 if (overrideBaseTime) {
8034 fiber.selfBaseDuration = elapsedTime;
8035 }
8036
8037 profilerStartTime = -1;
8038 }
8039}
8040
8041// This may have been an insertion or a hydration.
8042
8043var hydrationParentFiber = null;
8044var nextHydratableInstance = null;
8045var isHydrating = false;
8046
8047function warnIfHydrating() {
8048 {
8049 !!isHydrating ? warning$1(false, 'We should not be hydrating here. This is a bug in React. Please file a bug.') : void 0;
8050 }
8051}
8052
8053function enterHydrationState(fiber) {
8054 if (!supportsHydration) {
8055 return false;
8056 }
8057
8058 var parentInstance = fiber.stateNode.containerInfo;
8059 nextHydratableInstance = getFirstHydratableChild(parentInstance);
8060 hydrationParentFiber = fiber;
8061 isHydrating = true;
8062 return true;
8063}
8064
8065function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance) {
8066 if (!supportsHydration) {
8067 return false;
8068 }
8069
8070 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
8071 popToNextHostParent(fiber);
8072 isHydrating = true;
8073 return true;
8074}
8075
8076function deleteHydratableInstance(returnFiber, instance) {
8077 {
8078 switch (returnFiber.tag) {
8079 case HostRoot:
8080 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
8081 break;
8082
8083 case HostComponent:
8084 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
8085 break;
8086 }
8087 }
8088
8089 var childToDelete = createFiberFromHostInstanceForDeletion();
8090 childToDelete.stateNode = instance;
8091 childToDelete.return = returnFiber;
8092 childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,
8093 // these children are not part of the reconciliation list of children.
8094 // Even if we abort and rereconcile the children, that will try to hydrate
8095 // again and the nodes are still in the host tree so these will be
8096 // recreated.
8097
8098 if (returnFiber.lastEffect !== null) {
8099 returnFiber.lastEffect.nextEffect = childToDelete;
8100 returnFiber.lastEffect = childToDelete;
8101 } else {
8102 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
8103 }
8104}
8105
8106function insertNonHydratedInstance(returnFiber, fiber) {
8107 fiber.effectTag = fiber.effectTag & ~Hydrating | Placement;
8108
8109 {
8110 switch (returnFiber.tag) {
8111 case HostRoot:
8112 {
8113 var parentContainer = returnFiber.stateNode.containerInfo;
8114
8115 switch (fiber.tag) {
8116 case HostComponent:
8117 var type = fiber.type;
8118 var props = fiber.pendingProps;
8119 didNotFindHydratableContainerInstance(parentContainer, type, props);
8120 break;
8121
8122 case HostText:
8123 var text = fiber.pendingProps;
8124 didNotFindHydratableContainerTextInstance(parentContainer, text);
8125 break;
8126
8127 case SuspenseComponent:
8128 didNotFindHydratableContainerSuspenseInstance(parentContainer);
8129 break;
8130 }
8131
8132 break;
8133 }
8134
8135 case HostComponent:
8136 {
8137 var parentType = returnFiber.type;
8138 var parentProps = returnFiber.memoizedProps;
8139 var parentInstance = returnFiber.stateNode;
8140
8141 switch (fiber.tag) {
8142 case HostComponent:
8143 var _type = fiber.type;
8144 var _props = fiber.pendingProps;
8145 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
8146 break;
8147
8148 case HostText:
8149 var _text = fiber.pendingProps;
8150 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
8151 break;
8152
8153 case SuspenseComponent:
8154 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
8155 break;
8156 }
8157
8158 break;
8159 }
8160
8161 default:
8162 return;
8163 }
8164 }
8165}
8166
8167function tryHydrate(fiber, nextInstance) {
8168 switch (fiber.tag) {
8169 case HostComponent:
8170 {
8171 var type = fiber.type;
8172 var props = fiber.pendingProps;
8173 var instance = canHydrateInstance(nextInstance, type, props);
8174
8175 if (instance !== null) {
8176 fiber.stateNode = instance;
8177 return true;
8178 }
8179
8180 return false;
8181 }
8182
8183 case HostText:
8184 {
8185 var text = fiber.pendingProps;
8186 var textInstance = canHydrateTextInstance(nextInstance, text);
8187
8188 if (textInstance !== null) {
8189 fiber.stateNode = textInstance;
8190 return true;
8191 }
8192
8193 return false;
8194 }
8195
8196 case SuspenseComponent:
8197 {
8198 if (enableSuspenseServerRenderer) {
8199 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
8200
8201 if (suspenseInstance !== null) {
8202 var suspenseState = {
8203 dehydrated: suspenseInstance,
8204 retryTime: Never
8205 };
8206 fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber.
8207 // This simplifies the code for getHostSibling and deleting nodes,
8208 // since it doesn't have to consider all Suspense boundaries and
8209 // check if they're dehydrated ones or not.
8210
8211 var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance);
8212 dehydratedFragment.return = fiber;
8213 fiber.child = dehydratedFragment;
8214 return true;
8215 }
8216 }
8217
8218 return false;
8219 }
8220
8221 default:
8222 return false;
8223 }
8224}
8225
8226function tryToClaimNextHydratableInstance(fiber) {
8227 if (!isHydrating) {
8228 return;
8229 }
8230
8231 var nextInstance = nextHydratableInstance;
8232
8233 if (!nextInstance) {
8234 // Nothing to hydrate. Make it an insertion.
8235 insertNonHydratedInstance(hydrationParentFiber, fiber);
8236 isHydrating = false;
8237 hydrationParentFiber = fiber;
8238 return;
8239 }
8240
8241 var firstAttemptedInstance = nextInstance;
8242
8243 if (!tryHydrate(fiber, nextInstance)) {
8244 // If we can't hydrate this instance let's try the next one.
8245 // We use this as a heuristic. It's based on intuition and not data so it
8246 // might be flawed or unnecessary.
8247 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
8248
8249 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
8250 // Nothing to hydrate. Make it an insertion.
8251 insertNonHydratedInstance(hydrationParentFiber, fiber);
8252 isHydrating = false;
8253 hydrationParentFiber = fiber;
8254 return;
8255 } // We matched the next one, we'll now assume that the first one was
8256 // superfluous and we'll delete it. Since we can't eagerly delete it
8257 // we'll have to schedule a deletion. To do that, this node needs a dummy
8258 // fiber associated with it.
8259
8260
8261 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
8262 }
8263
8264 hydrationParentFiber = fiber;
8265 nextHydratableInstance = getFirstHydratableChild(nextInstance);
8266}
8267
8268function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
8269 if (!supportsHydration) {
8270 (function () {
8271 {
8272 {
8273 throw ReactError(Error("Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."));
8274 }
8275 }
8276 })();
8277 }
8278
8279 var instance = fiber.stateNode;
8280 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component.
8281
8282 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
8283 // is a new ref we mark this as an update.
8284
8285 if (updatePayload !== null) {
8286 return true;
8287 }
8288
8289 return false;
8290}
8291
8292function prepareToHydrateHostTextInstance(fiber) {
8293 if (!supportsHydration) {
8294 (function () {
8295 {
8296 {
8297 throw ReactError(Error("Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."));
8298 }
8299 }
8300 })();
8301 }
8302
8303 var textInstance = fiber.stateNode;
8304 var textContent = fiber.memoizedProps;
8305 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
8306
8307 {
8308 if (shouldUpdate) {
8309 // We assume that prepareToHydrateHostTextInstance is called in a context where the
8310 // hydration parent is the parent host component of this host text.
8311 var returnFiber = hydrationParentFiber;
8312
8313 if (returnFiber !== null) {
8314 switch (returnFiber.tag) {
8315 case HostRoot:
8316 {
8317 var parentContainer = returnFiber.stateNode.containerInfo;
8318 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
8319 break;
8320 }
8321
8322 case HostComponent:
8323 {
8324 var parentType = returnFiber.type;
8325 var parentProps = returnFiber.memoizedProps;
8326 var parentInstance = returnFiber.stateNode;
8327 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
8328 break;
8329 }
8330 }
8331 }
8332 }
8333 }
8334
8335 return shouldUpdate;
8336}
8337
8338function prepareToHydrateHostSuspenseInstance(fiber) {
8339 if (!supportsHydration) {
8340 (function () {
8341 {
8342 {
8343 throw ReactError(Error("Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."));
8344 }
8345 }
8346 })();
8347 }
8348
8349 var suspenseState = fiber.memoizedState;
8350 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
8351
8352 (function () {
8353 if (!suspenseInstance) {
8354 {
8355 throw ReactError(Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue."));
8356 }
8357 }
8358 })();
8359
8360 hydrateSuspenseInstance(suspenseInstance, fiber);
8361}
8362
8363function skipPastDehydratedSuspenseInstance(fiber) {
8364 if (!supportsHydration) {
8365 (function () {
8366 {
8367 {
8368 throw ReactError(Error("Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue."));
8369 }
8370 }
8371 })();
8372 }
8373
8374 var suspenseState = fiber.memoizedState;
8375 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
8376
8377 if (suspenseInstance === null) {
8378 // This Suspense boundary was hydrated without a match.
8379 return nextHydratableInstance;
8380 }
8381
8382 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
8383}
8384
8385function popToNextHostParent(fiber) {
8386 var parent = fiber.return;
8387
8388 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
8389 parent = parent.return;
8390 }
8391
8392 hydrationParentFiber = parent;
8393}
8394
8395function popHydrationState(fiber) {
8396 if (!supportsHydration) {
8397 return false;
8398 }
8399
8400 if (fiber !== hydrationParentFiber) {
8401 // We're deeper than the current hydration context, inside an inserted
8402 // tree.
8403 return false;
8404 }
8405
8406 if (!isHydrating) {
8407 // If we're not currently hydrating but we're in a hydration context, then
8408 // we were an insertion and now need to pop up reenter hydration of our
8409 // siblings.
8410 popToNextHostParent(fiber);
8411 isHydrating = true;
8412 return false;
8413 }
8414
8415 var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now.
8416 // We only do this deeper than head and body since they tend to have random
8417 // other nodes in them. We also ignore components with pure text content in
8418 // side of them.
8419 // TODO: Better heuristic.
8420
8421 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
8422 var nextInstance = nextHydratableInstance;
8423
8424 while (nextInstance) {
8425 deleteHydratableInstance(fiber, nextInstance);
8426 nextInstance = getNextHydratableSibling(nextInstance);
8427 }
8428 }
8429
8430 popToNextHostParent(fiber);
8431
8432 if (fiber.tag === SuspenseComponent) {
8433 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
8434 } else {
8435 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
8436 }
8437
8438 return true;
8439}
8440
8441function resetHydrationState() {
8442 if (!supportsHydration) {
8443 return;
8444 }
8445
8446 hydrationParentFiber = null;
8447 nextHydratableInstance = null;
8448 isHydrating = false;
8449}
8450
8451var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
8452var didReceiveUpdate = false;
8453var didWarnAboutBadClass;
8454var didWarnAboutModulePatternComponent;
8455var didWarnAboutContextTypeOnFunctionComponent;
8456var didWarnAboutGetDerivedStateOnFunctionComponent;
8457var didWarnAboutFunctionRefs;
8458var didWarnAboutReassigningProps;
8459var didWarnAboutMaxDuration;
8460var didWarnAboutRevealOrder;
8461var didWarnAboutTailOptions;
8462var didWarnAboutDefaultPropsOnFunctionComponent;
8463
8464{
8465 didWarnAboutBadClass = {};
8466 didWarnAboutModulePatternComponent = {};
8467 didWarnAboutContextTypeOnFunctionComponent = {};
8468 didWarnAboutGetDerivedStateOnFunctionComponent = {};
8469 didWarnAboutFunctionRefs = {};
8470 didWarnAboutReassigningProps = false;
8471 didWarnAboutMaxDuration = false;
8472 didWarnAboutRevealOrder = {};
8473 didWarnAboutTailOptions = {};
8474 didWarnAboutDefaultPropsOnFunctionComponent = {};
8475}
8476
8477function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
8478 if (current === null) {
8479 // If this is a fresh new component that hasn't been rendered yet, we
8480 // won't update its child set by applying minimal side-effects. Instead,
8481 // we will add them all to the child before it gets rendered. That means
8482 // we can optimize this reconciliation pass by not tracking side-effects.
8483 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8484 } else {
8485 // If the current child is the same as the work in progress, it means that
8486 // we haven't yet started any work on these children. Therefore, we use
8487 // the clone algorithm to create a copy of all the current children.
8488 // If we had any progressed work already, that is invalid at this point so
8489 // let's throw it out.
8490 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
8491 }
8492}
8493
8494function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
8495 // This function is fork of reconcileChildren. It's used in cases where we
8496 // want to reconcile without matching against the existing set. This has the
8497 // effect of all current children being unmounted; even if the type and key
8498 // are the same, the old child is unmounted and a new child is created.
8499 //
8500 // To do this, we're going to go through the reconcile algorithm twice. In
8501 // the first pass, we schedule a deletion for all the current children by
8502 // passing null.
8503 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
8504 // pass null in place of where we usually pass the current child set. This has
8505 // the effect of remounting all children regardless of whether their their
8506 // identity matches.
8507
8508 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8509}
8510
8511function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
8512 // TODO: current can be non-null here even if the component
8513 // hasn't yet mounted. This happens after the first render suspends.
8514 // We'll need to figure out if this is fine or can cause issues.
8515 {
8516 if (workInProgress.type !== workInProgress.elementType) {
8517 // Lazy component props can't be validated in createElement
8518 // because they're only guaranteed to be resolved here.
8519 var innerPropTypes = Component.propTypes;
8520
8521 if (innerPropTypes) {
8522 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8523 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8524 }
8525 }
8526 }
8527
8528 var render = Component.render;
8529 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
8530
8531 var nextChildren;
8532 prepareToReadContext(workInProgress, renderExpirationTime);
8533
8534 {
8535 ReactCurrentOwner$2.current = workInProgress;
8536 setCurrentPhase('render');
8537 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
8538
8539 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8540 // Only double-render components with Hooks
8541 if (workInProgress.memoizedState !== null) {
8542 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
8543 }
8544 }
8545
8546 setCurrentPhase(null);
8547 }
8548
8549 if (current !== null && !didReceiveUpdate) {
8550 bailoutHooks(current, workInProgress, renderExpirationTime);
8551 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8552 } // React DevTools reads this flag.
8553
8554
8555 workInProgress.effectTag |= PerformedWork;
8556 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8557 return workInProgress.child;
8558}
8559
8560function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
8561 if (current === null) {
8562 var type = Component.type;
8563
8564 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
8565 Component.defaultProps === undefined) {
8566 var resolvedType = type;
8567
8568 {
8569 resolvedType = resolveFunctionForHotReloading(type);
8570 } // If this is a plain function component without default props,
8571 // and with only the default shallow comparison, we upgrade it
8572 // to a SimpleMemoComponent to allow fast path updates.
8573
8574
8575 workInProgress.tag = SimpleMemoComponent;
8576 workInProgress.type = resolvedType;
8577
8578 {
8579 validateFunctionComponentInDev(workInProgress, type);
8580 }
8581
8582 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
8583 }
8584
8585 {
8586 var innerPropTypes = type.propTypes;
8587
8588 if (innerPropTypes) {
8589 // Inner memo component props aren't currently validated in createElement.
8590 // We could move it there, but we'd still need this for lazy code path.
8591 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8592 'prop', getComponentName(type), getCurrentFiberStackInDev);
8593 }
8594 }
8595
8596 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
8597 child.ref = workInProgress.ref;
8598 child.return = workInProgress;
8599 workInProgress.child = child;
8600 return child;
8601 }
8602
8603 {
8604 var _type = Component.type;
8605 var _innerPropTypes = _type.propTypes;
8606
8607 if (_innerPropTypes) {
8608 // Inner memo component props aren't currently validated in createElement.
8609 // We could move it there, but we'd still need this for lazy code path.
8610 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
8611 'prop', getComponentName(_type), getCurrentFiberStackInDev);
8612 }
8613 }
8614
8615 var currentChild = current.child; // This is always exactly one child
8616
8617 if (updateExpirationTime < renderExpirationTime) {
8618 // This will be the props with resolved defaultProps,
8619 // unlike current.memoizedProps which will be the unresolved ones.
8620 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
8621
8622 var compare = Component.compare;
8623 compare = compare !== null ? compare : shallowEqual;
8624
8625 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
8626 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8627 }
8628 } // React DevTools reads this flag.
8629
8630
8631 workInProgress.effectTag |= PerformedWork;
8632 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
8633 newChild.ref = workInProgress.ref;
8634 newChild.return = workInProgress;
8635 workInProgress.child = newChild;
8636 return newChild;
8637}
8638
8639function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
8640 // TODO: current can be non-null here even if the component
8641 // hasn't yet mounted. This happens when the inner render suspends.
8642 // We'll need to figure out if this is fine or can cause issues.
8643 {
8644 if (workInProgress.type !== workInProgress.elementType) {
8645 // Lazy component props can't be validated in createElement
8646 // because they're only guaranteed to be resolved here.
8647 var outerMemoType = workInProgress.elementType;
8648
8649 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
8650 // We warn when you define propTypes on lazy()
8651 // so let's just skip over it to find memo() outer wrapper.
8652 // Inner props for memo are validated later.
8653 outerMemoType = refineResolvedLazyComponent(outerMemoType);
8654 }
8655
8656 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
8657
8658 if (outerPropTypes) {
8659 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
8660 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
8661 } // Inner propTypes will be validated in the function component path.
8662
8663 }
8664 }
8665
8666 if (current !== null) {
8667 var prevProps = current.memoizedProps;
8668
8669 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload:
8670 workInProgress.type === current.type)) {
8671 didReceiveUpdate = false;
8672
8673 if (updateExpirationTime < renderExpirationTime) {
8674 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8675 }
8676 }
8677 }
8678
8679 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
8680}
8681
8682function updateFragment(current, workInProgress, renderExpirationTime) {
8683 var nextChildren = workInProgress.pendingProps;
8684 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8685 return workInProgress.child;
8686}
8687
8688function updateMode(current, workInProgress, renderExpirationTime) {
8689 var nextChildren = workInProgress.pendingProps.children;
8690 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8691 return workInProgress.child;
8692}
8693
8694function updateProfiler(current, workInProgress, renderExpirationTime) {
8695 if (enableProfilerTimer) {
8696 workInProgress.effectTag |= Update;
8697 }
8698
8699 var nextProps = workInProgress.pendingProps;
8700 var nextChildren = nextProps.children;
8701 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8702 return workInProgress.child;
8703}
8704
8705function markRef(current, workInProgress) {
8706 var ref = workInProgress.ref;
8707
8708 if (current === null && ref !== null || current !== null && current.ref !== ref) {
8709 // Schedule a Ref effect
8710 workInProgress.effectTag |= Ref;
8711 }
8712}
8713
8714function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8715 {
8716 if (workInProgress.type !== workInProgress.elementType) {
8717 // Lazy component props can't be validated in createElement
8718 // because they're only guaranteed to be resolved here.
8719 var innerPropTypes = Component.propTypes;
8720
8721 if (innerPropTypes) {
8722 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8723 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8724 }
8725 }
8726 }
8727
8728 var context;
8729
8730 if (!disableLegacyContext) {
8731 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
8732 context = getMaskedContext(workInProgress, unmaskedContext);
8733 }
8734
8735 var nextChildren;
8736 prepareToReadContext(workInProgress, renderExpirationTime);
8737
8738 {
8739 ReactCurrentOwner$2.current = workInProgress;
8740 setCurrentPhase('render');
8741 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8742
8743 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8744 // Only double-render components with Hooks
8745 if (workInProgress.memoizedState !== null) {
8746 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8747 }
8748 }
8749
8750 setCurrentPhase(null);
8751 }
8752
8753 if (current !== null && !didReceiveUpdate) {
8754 bailoutHooks(current, workInProgress, renderExpirationTime);
8755 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8756 } // React DevTools reads this flag.
8757
8758
8759 workInProgress.effectTag |= PerformedWork;
8760 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8761 return workInProgress.child;
8762}
8763
8764function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8765 {
8766 if (workInProgress.type !== workInProgress.elementType) {
8767 // Lazy component props can't be validated in createElement
8768 // because they're only guaranteed to be resolved here.
8769 var innerPropTypes = Component.propTypes;
8770
8771 if (innerPropTypes) {
8772 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8773 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8774 }
8775 }
8776 } // Push context providers early to prevent context stack mismatches.
8777 // During mounting we don't know the child context yet as the instance doesn't exist.
8778 // We will invalidate the child context in finishClassComponent() right after rendering.
8779
8780
8781 var hasContext;
8782
8783 if (isContextProvider(Component)) {
8784 hasContext = true;
8785 pushContextProvider(workInProgress);
8786 } else {
8787 hasContext = false;
8788 }
8789
8790 prepareToReadContext(workInProgress, renderExpirationTime);
8791 var instance = workInProgress.stateNode;
8792 var shouldUpdate;
8793
8794 if (instance === null) {
8795 if (current !== null) {
8796 // An class component without an instance only mounts if it suspended
8797 // inside a non- concurrent tree, in an inconsistent state. We want to
8798 // tree it like a new mount, even though an empty version of it already
8799 // committed. Disconnect the alternate pointers.
8800 current.alternate = null;
8801 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8802
8803 workInProgress.effectTag |= Placement;
8804 } // In the initial pass we might need to construct the instance.
8805
8806
8807 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8808 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8809 shouldUpdate = true;
8810 } else if (current === null) {
8811 // In a resume, we'll already have an instance we can reuse.
8812 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8813 } else {
8814 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
8815 }
8816
8817 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
8818
8819 {
8820 var inst = workInProgress.stateNode;
8821
8822 if (inst.props !== nextProps) {
8823 !didWarnAboutReassigningProps ? warning$1(false, 'It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component') : void 0;
8824 didWarnAboutReassigningProps = true;
8825 }
8826 }
8827
8828 return nextUnitOfWork;
8829}
8830
8831function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
8832 // Refs should update even if shouldComponentUpdate returns false
8833 markRef(current, workInProgress);
8834 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
8835
8836 if (!shouldUpdate && !didCaptureError) {
8837 // Context providers should defer to sCU for rendering
8838 if (hasContext) {
8839 invalidateContextProvider(workInProgress, Component, false);
8840 }
8841
8842 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8843 }
8844
8845 var instance = workInProgress.stateNode; // Rerender
8846
8847 ReactCurrentOwner$2.current = workInProgress;
8848 var nextChildren;
8849
8850 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
8851 // If we captured an error, but getDerivedStateFrom catch is not defined,
8852 // unmount all the children. componentDidCatch will schedule an update to
8853 // re-render a fallback. This is temporary until we migrate everyone to
8854 // the new API.
8855 // TODO: Warn in a future release.
8856 nextChildren = null;
8857
8858 if (enableProfilerTimer) {
8859 stopProfilerTimerIfRunning(workInProgress);
8860 }
8861 } else {
8862 {
8863 setCurrentPhase('render');
8864 nextChildren = instance.render();
8865
8866 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8867 instance.render();
8868 }
8869
8870 setCurrentPhase(null);
8871 }
8872 } // React DevTools reads this flag.
8873
8874
8875 workInProgress.effectTag |= PerformedWork;
8876
8877 if (current !== null && didCaptureError) {
8878 // If we're recovering from an error, reconcile without reusing any of
8879 // the existing children. Conceptually, the normal children and the children
8880 // that are shown on error are two different sets, so we shouldn't reuse
8881 // normal children even if their identities match.
8882 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
8883 } else {
8884 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8885 } // Memoize state using the values we just used to render.
8886 // TODO: Restructure so we never read values from the instance.
8887
8888
8889 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
8890
8891 if (hasContext) {
8892 invalidateContextProvider(workInProgress, Component, true);
8893 }
8894
8895 return workInProgress.child;
8896}
8897
8898function pushHostRootContext(workInProgress) {
8899 var root = workInProgress.stateNode;
8900
8901 if (root.pendingContext) {
8902 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
8903 } else if (root.context) {
8904 // Should always be set
8905 pushTopLevelContextObject(workInProgress, root.context, false);
8906 }
8907
8908 pushHostContainer(workInProgress, root.containerInfo);
8909}
8910
8911function updateHostRoot(current, workInProgress, renderExpirationTime) {
8912 pushHostRootContext(workInProgress);
8913 var updateQueue = workInProgress.updateQueue;
8914
8915 (function () {
8916 if (!(updateQueue !== null)) {
8917 {
8918 throw ReactError(Error("If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue."));
8919 }
8920 }
8921 })();
8922
8923 var nextProps = workInProgress.pendingProps;
8924 var prevState = workInProgress.memoizedState;
8925 var prevChildren = prevState !== null ? prevState.element : null;
8926 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
8927 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
8928 // being called "element".
8929
8930 var nextChildren = nextState.element;
8931
8932 if (nextChildren === prevChildren) {
8933 // If the state is the same as before, that's a bailout because we had
8934 // no work that expires at this time.
8935 resetHydrationState();
8936 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8937 }
8938
8939 var root = workInProgress.stateNode;
8940
8941 if (root.hydrate && enterHydrationState(workInProgress)) {
8942 // If we don't have any current children this might be the first pass.
8943 // We always try to hydrate. If this isn't a hydration pass there won't
8944 // be any children to hydrate which is effectively the same thing as
8945 // not hydrating.
8946 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8947 workInProgress.child = child;
8948 var node = child;
8949
8950 while (node) {
8951 // Mark each child as hydrating. This is a fast path to know whether this
8952 // tree is part of a hydrating tree. This is used to determine if a child
8953 // node has fully mounted yet, and for scheduling event replaying.
8954 // Conceptually this is similar to Placement in that a new subtree is
8955 // inserted into the React tree here. It just happens to not need DOM
8956 // mutations because it already exists.
8957 node.effectTag = node.effectTag & ~Placement | Hydrating;
8958 node = node.sibling;
8959 }
8960 } else {
8961 // Otherwise reset hydration state in case we aborted and resumed another
8962 // root.
8963 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8964 resetHydrationState();
8965 }
8966
8967 return workInProgress.child;
8968}
8969
8970function updateHostComponent(current, workInProgress, renderExpirationTime) {
8971 pushHostContext(workInProgress);
8972
8973 if (current === null) {
8974 tryToClaimNextHydratableInstance(workInProgress);
8975 }
8976
8977 var type = workInProgress.type;
8978 var nextProps = workInProgress.pendingProps;
8979 var prevProps = current !== null ? current.memoizedProps : null;
8980 var nextChildren = nextProps.children;
8981 var isDirectTextChild = shouldSetTextContent(type, nextProps);
8982
8983 if (isDirectTextChild) {
8984 // We special case a direct text child of a host node. This is a common
8985 // case. We won't handle it as a reified child. We will instead handle
8986 // this in the host environment that also have access to this prop. That
8987 // avoids allocating another HostText fiber and traversing it.
8988 nextChildren = null;
8989 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
8990 // If we're switching from a direct text child to a normal child, or to
8991 // empty, we need to schedule the text content to be reset.
8992 workInProgress.effectTag |= ContentReset;
8993 }
8994
8995 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
8996
8997 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
8998 if (enableSchedulerTracing) {
8999 markSpawnedWork(Never);
9000 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
9001
9002
9003 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
9004 return null;
9005 }
9006
9007 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
9008 return workInProgress.child;
9009}
9010
9011function updateHostText(current, workInProgress) {
9012 if (current === null) {
9013 tryToClaimNextHydratableInstance(workInProgress);
9014 } // Nothing to do here. This is terminal. We'll do the completion step
9015 // immediately after.
9016
9017
9018 return null;
9019}
9020
9021function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
9022 if (_current !== null) {
9023 // An lazy component only mounts if it suspended inside a non-
9024 // concurrent tree, in an inconsistent state. We want to treat it like
9025 // a new mount, even though an empty version of it already committed.
9026 // Disconnect the alternate pointers.
9027 _current.alternate = null;
9028 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
9029
9030 workInProgress.effectTag |= Placement;
9031 }
9032
9033 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
9034 // Cancel and resume right after we know the tag.
9035
9036 cancelWorkTimer(workInProgress);
9037 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
9038
9039 workInProgress.type = Component;
9040 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
9041 startWorkTimer(workInProgress);
9042 var resolvedProps = resolveDefaultProps(Component, props);
9043 var child;
9044
9045 switch (resolvedTag) {
9046 case FunctionComponent:
9047 {
9048 {
9049 validateFunctionComponentInDev(workInProgress, Component);
9050 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
9051 }
9052
9053 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
9054 break;
9055 }
9056
9057 case ClassComponent:
9058 {
9059 {
9060 workInProgress.type = Component = resolveClassForHotReloading(Component);
9061 }
9062
9063 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
9064 break;
9065 }
9066
9067 case ForwardRef:
9068 {
9069 {
9070 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
9071 }
9072
9073 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
9074 break;
9075 }
9076
9077 case MemoComponent:
9078 {
9079 {
9080 if (workInProgress.type !== workInProgress.elementType) {
9081 var outerPropTypes = Component.propTypes;
9082
9083 if (outerPropTypes) {
9084 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
9085 'prop', getComponentName(Component), getCurrentFiberStackInDev);
9086 }
9087 }
9088 }
9089
9090 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
9091 updateExpirationTime, renderExpirationTime);
9092 break;
9093 }
9094
9095 default:
9096 {
9097 var hint = '';
9098
9099 {
9100 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
9101 hint = ' Did you wrap a component in React.lazy() more than once?';
9102 }
9103 } // This message intentionally doesn't mention ForwardRef or MemoComponent
9104 // because the fact that it's a separate type of work is an
9105 // implementation detail.
9106
9107
9108 (function () {
9109 {
9110 {
9111 throw ReactError(Error("Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint));
9112 }
9113 }
9114 })();
9115 }
9116 }
9117
9118 return child;
9119}
9120
9121function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
9122 if (_current !== null) {
9123 // An incomplete component only mounts if it suspended inside a non-
9124 // concurrent tree, in an inconsistent state. We want to treat it like
9125 // a new mount, even though an empty version of it already committed.
9126 // Disconnect the alternate pointers.
9127 _current.alternate = null;
9128 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
9129
9130 workInProgress.effectTag |= Placement;
9131 } // Promote the fiber to a class and try rendering again.
9132
9133
9134 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
9135 // Push context providers early to prevent context stack mismatches.
9136 // During mounting we don't know the child context yet as the instance doesn't exist.
9137 // We will invalidate the child context in finishClassComponent() right after rendering.
9138
9139 var hasContext;
9140
9141 if (isContextProvider(Component)) {
9142 hasContext = true;
9143 pushContextProvider(workInProgress);
9144 } else {
9145 hasContext = false;
9146 }
9147
9148 prepareToReadContext(workInProgress, renderExpirationTime);
9149 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
9150 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
9151 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
9152}
9153
9154function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
9155 if (_current !== null) {
9156 // An indeterminate component only mounts if it suspended inside a non-
9157 // concurrent tree, in an inconsistent state. We want to treat it like
9158 // a new mount, even though an empty version of it already committed.
9159 // Disconnect the alternate pointers.
9160 _current.alternate = null;
9161 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
9162
9163 workInProgress.effectTag |= Placement;
9164 }
9165
9166 var props = workInProgress.pendingProps;
9167 var context;
9168
9169 if (!disableLegacyContext) {
9170 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
9171 context = getMaskedContext(workInProgress, unmaskedContext);
9172 }
9173
9174 prepareToReadContext(workInProgress, renderExpirationTime);
9175 var value;
9176
9177 {
9178 if (Component.prototype && typeof Component.prototype.render === 'function') {
9179 var componentName = getComponentName(Component) || 'Unknown';
9180
9181 if (!didWarnAboutBadClass[componentName]) {
9182 warningWithoutStack$1(false, "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
9183 didWarnAboutBadClass[componentName] = true;
9184 }
9185 }
9186
9187 if (workInProgress.mode & StrictMode) {
9188 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
9189 }
9190
9191 ReactCurrentOwner$2.current = workInProgress;
9192 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
9193 } // React DevTools reads this flag.
9194
9195
9196 workInProgress.effectTag |= PerformedWork;
9197
9198 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
9199 {
9200 var _componentName = getComponentName(Component) || 'Unknown';
9201
9202 if (!didWarnAboutModulePatternComponent[_componentName]) {
9203 warningWithoutStack$1(false, 'The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
9204 didWarnAboutModulePatternComponent[_componentName] = true;
9205 }
9206 } // Proceed under the assumption that this is a class instance
9207
9208
9209 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
9210
9211 resetHooks(); // Push context providers early to prevent context stack mismatches.
9212 // During mounting we don't know the child context yet as the instance doesn't exist.
9213 // We will invalidate the child context in finishClassComponent() right after rendering.
9214
9215 var hasContext = false;
9216
9217 if (isContextProvider(Component)) {
9218 hasContext = true;
9219 pushContextProvider(workInProgress);
9220 } else {
9221 hasContext = false;
9222 }
9223
9224 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
9225 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
9226
9227 if (typeof getDerivedStateFromProps === 'function') {
9228 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
9229 }
9230
9231 adoptClassInstance(workInProgress, value);
9232 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
9233 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
9234 } else {
9235 // Proceed under the assumption that this is a function component
9236 workInProgress.tag = FunctionComponent;
9237
9238 {
9239 if (disableLegacyContext && Component.contextTypes) {
9240 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with React.useContext() instead.', getComponentName(Component) || 'Unknown');
9241 }
9242
9243 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
9244 // Only double-render components with Hooks
9245 if (workInProgress.memoizedState !== null) {
9246 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
9247 }
9248 }
9249 }
9250
9251 reconcileChildren(null, workInProgress, value, renderExpirationTime);
9252
9253 {
9254 validateFunctionComponentInDev(workInProgress, Component);
9255 }
9256
9257 return workInProgress.child;
9258 }
9259}
9260
9261function validateFunctionComponentInDev(workInProgress, Component) {
9262 if (Component) {
9263 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
9264 }
9265
9266 if (workInProgress.ref !== null) {
9267 var info = '';
9268 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
9269
9270 if (ownerName) {
9271 info += '\n\nCheck the render method of `' + ownerName + '`.';
9272 }
9273
9274 var warningKey = ownerName || workInProgress._debugID || '';
9275 var debugSource = workInProgress._debugSource;
9276
9277 if (debugSource) {
9278 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
9279 }
9280
9281 if (!didWarnAboutFunctionRefs[warningKey]) {
9282 didWarnAboutFunctionRefs[warningKey] = true;
9283 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
9284 }
9285 }
9286
9287 if (warnAboutDefaultPropsOnFunctionComponents && Component.defaultProps !== undefined) {
9288 var componentName = getComponentName(Component) || 'Unknown';
9289
9290 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
9291 warningWithoutStack$1(false, '%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
9292 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
9293 }
9294 }
9295
9296 if (typeof Component.getDerivedStateFromProps === 'function') {
9297 var _componentName2 = getComponentName(Component) || 'Unknown';
9298
9299 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
9300 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', _componentName2);
9301 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
9302 }
9303 }
9304
9305 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
9306 var _componentName3 = getComponentName(Component) || 'Unknown';
9307
9308 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
9309 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName3);
9310 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
9311 }
9312 }
9313}
9314
9315var SUSPENDED_MARKER = {
9316 dehydrated: null,
9317 retryTime: Never
9318};
9319
9320function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
9321 // If the context is telling us that we should show a fallback, and we're not
9322 // already showing content, then we should show the fallback instead.
9323 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
9324}
9325
9326function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
9327 var mode = workInProgress.mode;
9328 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
9329
9330 {
9331 if (shouldSuspend(workInProgress)) {
9332 workInProgress.effectTag |= DidCapture;
9333 }
9334 }
9335
9336 var suspenseContext = suspenseStackCursor.current;
9337 var nextDidTimeout = false;
9338 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
9339
9340 if (didSuspend || shouldRemainOnFallback(suspenseContext, current, workInProgress)) {
9341 // Something in this boundary's subtree already suspended. Switch to
9342 // rendering the fallback children.
9343 nextDidTimeout = true;
9344 workInProgress.effectTag &= ~DidCapture;
9345 } else {
9346 // Attempting the main content
9347 if (current === null || current.memoizedState !== null) {
9348 // This is a new mount or this boundary is already showing a fallback state.
9349 // Mark this subtree context as having at least one invisible parent that could
9350 // handle the fallback state.
9351 // Boundaries without fallbacks or should be avoided are not considered since
9352 // they cannot handle preferred fallback states.
9353 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
9354 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
9355 }
9356 }
9357 }
9358
9359 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
9360 pushSuspenseContext(workInProgress, suspenseContext);
9361
9362 {
9363 if ('maxDuration' in nextProps) {
9364 if (!didWarnAboutMaxDuration) {
9365 didWarnAboutMaxDuration = true;
9366 warning$1(false, 'maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
9367 }
9368 }
9369 } // This next part is a bit confusing. If the children timeout, we switch to
9370 // showing the fallback children in place of the "primary" children.
9371 // However, we don't want to delete the primary children because then their
9372 // state will be lost (both the React state and the host state, e.g.
9373 // uncontrolled form inputs). Instead we keep them mounted and hide them.
9374 // Both the fallback children AND the primary children are rendered at the
9375 // same time. Once the primary children are un-suspended, we can delete
9376 // the fallback children — don't need to preserve their state.
9377 //
9378 // The two sets of children are siblings in the host environment, but
9379 // semantically, for purposes of reconciliation, they are two separate sets.
9380 // So we store them using two fragment fibers.
9381 //
9382 // However, we want to avoid allocating extra fibers for every placeholder.
9383 // They're only necessary when the children time out, because that's the
9384 // only time when both sets are mounted.
9385 //
9386 // So, the extra fragment fibers are only used if the children time out.
9387 // Otherwise, we render the primary children directly. This requires some
9388 // custom reconciliation logic to preserve the state of the primary
9389 // children. It's essentially a very basic form of re-parenting.
9390
9391
9392 if (current === null) {
9393 if (enableSuspenseServerRenderer) {
9394 // If we're currently hydrating, try to hydrate this boundary.
9395 // But only if this has a fallback.
9396 if (nextProps.fallback !== undefined) {
9397 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
9398
9399 var suspenseState = workInProgress.memoizedState;
9400
9401 if (suspenseState !== null) {
9402 var dehydrated = suspenseState.dehydrated;
9403
9404 if (dehydrated !== null) {
9405 return mountDehydratedSuspenseComponent(workInProgress, dehydrated, renderExpirationTime);
9406 }
9407 }
9408 }
9409 } // This is the initial mount. This branch is pretty simple because there's
9410 // no previous state that needs to be preserved.
9411
9412
9413 if (nextDidTimeout) {
9414 // Mount separate fragments for primary and fallback children.
9415 var nextFallbackChildren = nextProps.fallback;
9416 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
9417 primaryChildFragment.return = workInProgress;
9418
9419 if ((workInProgress.mode & BatchedMode) === NoMode) {
9420 // Outside of batched mode, we commit the effects from the
9421 // partially completed, timed-out tree, too.
9422 var progressedState = workInProgress.memoizedState;
9423 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
9424 primaryChildFragment.child = progressedPrimaryChild;
9425 var progressedChild = progressedPrimaryChild;
9426
9427 while (progressedChild !== null) {
9428 progressedChild.return = primaryChildFragment;
9429 progressedChild = progressedChild.sibling;
9430 }
9431 }
9432
9433 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
9434 fallbackChildFragment.return = workInProgress;
9435 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
9436 // fallback children.
9437
9438 workInProgress.memoizedState = SUSPENDED_MARKER;
9439 workInProgress.child = primaryChildFragment;
9440 return fallbackChildFragment;
9441 } else {
9442 // Mount the primary children without an intermediate fragment fiber.
9443 var nextPrimaryChildren = nextProps.children;
9444 workInProgress.memoizedState = null;
9445 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
9446 }
9447 } else {
9448 // This is an update. This branch is more complicated because we need to
9449 // ensure the state of the primary children is preserved.
9450 var prevState = current.memoizedState;
9451
9452 if (prevState !== null) {
9453 if (enableSuspenseServerRenderer) {
9454 var _dehydrated = prevState.dehydrated;
9455
9456 if (_dehydrated !== null) {
9457 if (!didSuspend) {
9458 return updateDehydratedSuspenseComponent(current, workInProgress, _dehydrated, prevState, renderExpirationTime);
9459 } else if (workInProgress.memoizedState !== null) {
9460 // Something suspended and we should still be in dehydrated mode.
9461 // Leave the existing child in place.
9462 workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there
9463 // but the normal suspense pass doesn't.
9464
9465 workInProgress.effectTag |= DidCapture;
9466 return null;
9467 } else {
9468 // Suspended but we should no longer be in dehydrated mode.
9469 // Therefore we now have to render the fallback. Wrap the children
9470 // in a fragment fiber to keep them separate from the fallback
9471 // children.
9472 var _nextFallbackChildren = nextProps.fallback;
9473
9474 var _primaryChildFragment = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
9475 // going to render this fragment.
9476 null, mode, NoWork, null);
9477
9478 _primaryChildFragment.return = workInProgress; // This is always null since we never want the previous child
9479 // that we're not going to hydrate.
9480
9481 _primaryChildFragment.child = null;
9482
9483 if ((workInProgress.mode & BatchedMode) === NoMode) {
9484 // Outside of batched mode, we commit the effects from the
9485 // partially completed, timed-out tree, too.
9486 var _progressedChild = _primaryChildFragment.child = workInProgress.child;
9487
9488 while (_progressedChild !== null) {
9489 _progressedChild.return = _primaryChildFragment;
9490 _progressedChild = _progressedChild.sibling;
9491 }
9492 } else {
9493 // We will have dropped the effect list which contains the deletion.
9494 // We need to reconcile to delete the current child.
9495 reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime);
9496 } // Because primaryChildFragment is a new fiber that we're inserting as the
9497 // parent of a new tree, we need to set its treeBaseDuration.
9498
9499
9500 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
9501 // treeBaseDuration is the sum of all the child tree base durations.
9502 var treeBaseDuration = 0;
9503 var hiddenChild = _primaryChildFragment.child;
9504
9505 while (hiddenChild !== null) {
9506 treeBaseDuration += hiddenChild.treeBaseDuration;
9507 hiddenChild = hiddenChild.sibling;
9508 }
9509
9510 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
9511 } // Create a fragment from the fallback children, too.
9512
9513
9514 var _fallbackChildFragment = createFiberFromFragment(_nextFallbackChildren, mode, renderExpirationTime, null);
9515
9516 _fallbackChildFragment.return = workInProgress;
9517 _primaryChildFragment.sibling = _fallbackChildFragment;
9518 _fallbackChildFragment.effectTag |= Placement;
9519 _primaryChildFragment.childExpirationTime = NoWork;
9520 workInProgress.memoizedState = SUSPENDED_MARKER;
9521 workInProgress.child = _primaryChildFragment; // Skip the primary children, and continue working on the
9522 // fallback children.
9523
9524 return _fallbackChildFragment;
9525 }
9526 }
9527 } // The current tree already timed out. That means each child set is
9528 // wrapped in a fragment fiber.
9529
9530
9531 var currentPrimaryChildFragment = current.child;
9532 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
9533
9534 if (nextDidTimeout) {
9535 // Still timed out. Reuse the current primary children by cloning
9536 // its fragment. We're going to skip over these entirely.
9537 var _nextFallbackChildren2 = nextProps.fallback;
9538
9539 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
9540
9541 _primaryChildFragment2.return = workInProgress;
9542
9543 if ((workInProgress.mode & BatchedMode) === NoMode) {
9544 // Outside of batched mode, we commit the effects from the
9545 // partially completed, timed-out tree, too.
9546 var _progressedState = workInProgress.memoizedState;
9547
9548 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
9549
9550 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
9551 _primaryChildFragment2.child = _progressedPrimaryChild;
9552 var _progressedChild2 = _progressedPrimaryChild;
9553
9554 while (_progressedChild2 !== null) {
9555 _progressedChild2.return = _primaryChildFragment2;
9556 _progressedChild2 = _progressedChild2.sibling;
9557 }
9558 }
9559 } // Because primaryChildFragment is a new fiber that we're inserting as the
9560 // parent of a new tree, we need to set its treeBaseDuration.
9561
9562
9563 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
9564 // treeBaseDuration is the sum of all the child tree base durations.
9565 var _treeBaseDuration = 0;
9566 var _hiddenChild = _primaryChildFragment2.child;
9567
9568 while (_hiddenChild !== null) {
9569 _treeBaseDuration += _hiddenChild.treeBaseDuration;
9570 _hiddenChild = _hiddenChild.sibling;
9571 }
9572
9573 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
9574 } // Clone the fallback child fragment, too. These we'll continue
9575 // working on.
9576
9577
9578 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2, currentFallbackChildFragment.expirationTime);
9579
9580 _fallbackChildFragment2.return = workInProgress;
9581 _primaryChildFragment2.sibling = _fallbackChildFragment2;
9582 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
9583 // fallback children.
9584
9585 workInProgress.memoizedState = SUSPENDED_MARKER;
9586 workInProgress.child = _primaryChildFragment2;
9587 return _fallbackChildFragment2;
9588 } else {
9589 // No longer suspended. Switch back to showing the primary children,
9590 // and remove the intermediate fragment fiber.
9591 var _nextPrimaryChildren = nextProps.children;
9592 var currentPrimaryChild = currentPrimaryChildFragment.child;
9593 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
9594 // children. Wait until the complete phase, after we've confirmed the
9595 // fallback is no longer needed.
9596 // TODO: Would it be better to store the fallback fragment on
9597 // the stateNode?
9598 // Continue rendering the children, like we normally do.
9599
9600 workInProgress.memoizedState = null;
9601 return workInProgress.child = primaryChild;
9602 }
9603 } else {
9604 // The current tree has not already timed out. That means the primary
9605 // children are not wrapped in a fragment fiber.
9606 var _currentPrimaryChild = current.child;
9607
9608 if (nextDidTimeout) {
9609 // Timed out. Wrap the children in a fragment fiber to keep them
9610 // separate from the fallback children.
9611 var _nextFallbackChildren3 = nextProps.fallback;
9612
9613 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
9614 // going to render this fragment.
9615 null, mode, NoWork, null);
9616
9617 _primaryChildFragment3.return = workInProgress;
9618 _primaryChildFragment3.child = _currentPrimaryChild;
9619
9620 if (_currentPrimaryChild !== null) {
9621 _currentPrimaryChild.return = _primaryChildFragment3;
9622 } // Even though we're creating a new fiber, there are no new children,
9623 // because we're reusing an already mounted tree. So we don't need to
9624 // schedule a placement.
9625 // primaryChildFragment.effectTag |= Placement;
9626
9627
9628 if ((workInProgress.mode & BatchedMode) === NoMode) {
9629 // Outside of batched mode, we commit the effects from the
9630 // partially completed, timed-out tree, too.
9631 var _progressedState2 = workInProgress.memoizedState;
9632
9633 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
9634
9635 _primaryChildFragment3.child = _progressedPrimaryChild2;
9636 var _progressedChild3 = _progressedPrimaryChild2;
9637
9638 while (_progressedChild3 !== null) {
9639 _progressedChild3.return = _primaryChildFragment3;
9640 _progressedChild3 = _progressedChild3.sibling;
9641 }
9642 } // Because primaryChildFragment is a new fiber that we're inserting as the
9643 // parent of a new tree, we need to set its treeBaseDuration.
9644
9645
9646 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
9647 // treeBaseDuration is the sum of all the child tree base durations.
9648 var _treeBaseDuration2 = 0;
9649 var _hiddenChild2 = _primaryChildFragment3.child;
9650
9651 while (_hiddenChild2 !== null) {
9652 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
9653 _hiddenChild2 = _hiddenChild2.sibling;
9654 }
9655
9656 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
9657 } // Create a fragment from the fallback children, too.
9658
9659
9660 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
9661
9662 _fallbackChildFragment3.return = workInProgress;
9663 _primaryChildFragment3.sibling = _fallbackChildFragment3;
9664 _fallbackChildFragment3.effectTag |= Placement;
9665 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
9666 // fallback children.
9667
9668 workInProgress.memoizedState = SUSPENDED_MARKER;
9669 workInProgress.child = _primaryChildFragment3;
9670 return _fallbackChildFragment3;
9671 } else {
9672 // Still haven't timed out. Continue rendering the children, like we
9673 // normally do.
9674 workInProgress.memoizedState = null;
9675 var _nextPrimaryChildren2 = nextProps.children;
9676 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
9677 }
9678 }
9679 }
9680}
9681
9682function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime) {
9683 // We're now not suspended nor dehydrated.
9684 workInProgress.memoizedState = null; // Retry with the full children.
9685
9686 var nextProps = workInProgress.pendingProps;
9687 var nextChildren = nextProps.children; // This will ensure that the children get Placement effects and
9688 // that the old child gets a Deletion effect.
9689 // We could also call forceUnmountCurrentAndReconcile.
9690
9691 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
9692 return workInProgress.child;
9693}
9694
9695function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderExpirationTime) {
9696 // During the first pass, we'll bail out and not drill into the children.
9697 // Instead, we'll leave the content in place and try to hydrate it later.
9698 if ((workInProgress.mode & BatchedMode) === NoMode) {
9699 {
9700 warning$1(false, 'Cannot hydrate Suspense in legacy mode. Switch from ' + 'ReactDOM.hydrate(element, container) to ' + 'ReactDOM.unstable_createSyncRoot(container, { hydrate: true })' + '.render(element) or remove the Suspense components from ' + 'the server rendered components.');
9701 }
9702
9703 workInProgress.expirationTime = Sync;
9704 } else if (isSuspenseInstanceFallback(suspenseInstance)) {
9705 // This is a client-only boundary. Since we won't get any content from the server
9706 // for this, we need to schedule that at a higher priority based on when it would
9707 // have timed out. In theory we could render it in this pass but it would have the
9708 // wrong priority associated with it and will prevent hydration of parent path.
9709 // Instead, we'll leave work left on it to render it in a separate commit.
9710 // TODO This time should be the time at which the server rendered response that is
9711 // a parent to this boundary was displayed. However, since we currently don't have
9712 // a protocol to transfer that time, we'll just estimate it by using the current
9713 // time. This will mean that Suspense timeouts are slightly shifted to later than
9714 // they should be.
9715 var serverDisplayTime = requestCurrentTime(); // Schedule a normal pri update to render this content.
9716
9717 var newExpirationTime = computeAsyncExpiration(serverDisplayTime);
9718
9719 if (enableSchedulerTracing) {
9720 markSpawnedWork(newExpirationTime);
9721 }
9722
9723 workInProgress.expirationTime = newExpirationTime;
9724 } else {
9725 // We'll continue hydrating the rest at offscreen priority since we'll already
9726 // be showing the right content coming from the server, it is no rush.
9727 workInProgress.expirationTime = Never;
9728
9729 if (enableSchedulerTracing) {
9730 markSpawnedWork(Never);
9731 }
9732 }
9733
9734 return null;
9735}
9736
9737function updateDehydratedSuspenseComponent(current, workInProgress, suspenseInstance, suspenseState, renderExpirationTime) {
9738 // We should never be hydrating at this point because it is the first pass,
9739 // but after we've already committed once.
9740 warnIfHydrating();
9741
9742 if ((workInProgress.mode & BatchedMode) === NoMode) {
9743 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime);
9744 }
9745
9746 if (isSuspenseInstanceFallback(suspenseInstance)) {
9747 // This boundary is in a permanent fallback state. In this case, we'll never
9748 // get an update and we'll never be able to hydrate the final content. Let's just try the
9749 // client side render instead.
9750 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime);
9751 } // We use childExpirationTime to indicate that a child might depend on context, so if
9752 // any context has changed, we need to treat is as if the input might have changed.
9753
9754
9755 var hasContextChanged$$1 = current.childExpirationTime >= renderExpirationTime;
9756
9757 if (didReceiveUpdate || hasContextChanged$$1) {
9758 // This boundary has changed since the first render. This means that we are now unable to
9759 // hydrate it. We might still be able to hydrate it using an earlier expiration time, if
9760 // we are rendering at lower expiration than sync.
9761 if (renderExpirationTime < Sync) {
9762 if (suspenseState.retryTime <= renderExpirationTime) {
9763 // This render is even higher pri than we've seen before, let's try again
9764 // at even higher pri.
9765 var attemptHydrationAtExpirationTime = renderExpirationTime + 1;
9766 suspenseState.retryTime = attemptHydrationAtExpirationTime;
9767 scheduleWork(current, attemptHydrationAtExpirationTime); // TODO: Early abort this render.
9768 } else {// We have already tried to ping at a higher priority than we're rendering with
9769 // so if we got here, we must have failed to hydrate at those levels. We must
9770 // now give up. Instead, we're going to delete the whole subtree and instead inject
9771 // a new real Suspense boundary to take its place, which may render content
9772 // or fallback. This might suspend for a while and if it does we might still have
9773 // an opportunity to hydrate before this pass commits.
9774 }
9775 } // If we have scheduled higher pri work above, this will probably just abort the render
9776 // since we now have higher priority work, but in case it doesn't, we need to prepare to
9777 // render something, if we time out. Even if that requires us to delete everything and
9778 // skip hydration.
9779 // Delay having to do this as long as the suspense timeout allows us.
9780
9781
9782 renderDidSuspendDelayIfPossible();
9783 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime);
9784 } else if (isSuspenseInstancePending(suspenseInstance)) {
9785 // This component is still pending more data from the server, so we can't hydrate its
9786 // content. We treat it as if this component suspended itself. It might seem as if
9787 // we could just try to render it client-side instead. However, this will perform a
9788 // lot of unnecessary work and is unlikely to complete since it often will suspend
9789 // on missing data anyway. Additionally, the server might be able to render more
9790 // than we can on the client yet. In that case we'd end up with more fallback states
9791 // on the client than if we just leave it alone. If the server times out or errors
9792 // these should update this boundary to the permanent Fallback state instead.
9793 // Mark it as having captured (i.e. suspended).
9794 workInProgress.effectTag |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment.
9795
9796 workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result.
9797
9798 registerSuspenseInstanceRetry(suspenseInstance, retryDehydratedSuspenseBoundary.bind(null, current));
9799 return null;
9800 } else {
9801 // This is the first attempt.
9802 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance);
9803 var nextProps = workInProgress.pendingProps;
9804 var nextChildren = nextProps.children;
9805 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
9806 var node = child;
9807
9808 while (node) {
9809 // Mark each child as hydrating. This is a fast path to know whether this
9810 // tree is part of a hydrating tree. This is used to determine if a child
9811 // node has fully mounted yet, and for scheduling event replaying.
9812 // Conceptually this is similar to Placement in that a new subtree is
9813 // inserted into the React tree here. It just happens to not need DOM
9814 // mutations because it already exists.
9815 node.effectTag |= Hydrating;
9816 node = node.sibling;
9817 }
9818
9819 workInProgress.child = child;
9820 return workInProgress.child;
9821 }
9822}
9823
9824function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
9825 // Mark any Suspense boundaries with fallbacks as having work to do.
9826 // If they were previously forced into fallbacks, they may now be able
9827 // to unblock.
9828 var node = firstChild;
9829
9830 while (node !== null) {
9831 if (node.tag === SuspenseComponent) {
9832 var state = node.memoizedState;
9833
9834 if (state !== null) {
9835 if (node.expirationTime < renderExpirationTime) {
9836 node.expirationTime = renderExpirationTime;
9837 }
9838
9839 var alternate = node.alternate;
9840
9841 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
9842 alternate.expirationTime = renderExpirationTime;
9843 }
9844
9845 scheduleWorkOnParentPath(node.return, renderExpirationTime);
9846 }
9847 } else if (node.child !== null) {
9848 node.child.return = node;
9849 node = node.child;
9850 continue;
9851 }
9852
9853 if (node === workInProgress) {
9854 return;
9855 }
9856
9857 while (node.sibling === null) {
9858 if (node.return === null || node.return === workInProgress) {
9859 return;
9860 }
9861
9862 node = node.return;
9863 }
9864
9865 node.sibling.return = node.return;
9866 node = node.sibling;
9867 }
9868}
9869
9870function findLastContentRow(firstChild) {
9871 // This is going to find the last row among these children that is already
9872 // showing content on the screen, as opposed to being in fallback state or
9873 // new. If a row has multiple Suspense boundaries, any of them being in the
9874 // fallback state, counts as the whole row being in a fallback state.
9875 // Note that the "rows" will be workInProgress, but any nested children
9876 // will still be current since we haven't rendered them yet. The mounted
9877 // order may not be the same as the new order. We use the new order.
9878 var row = firstChild;
9879 var lastContentRow = null;
9880
9881 while (row !== null) {
9882 var currentRow = row.alternate; // New rows can't be content rows.
9883
9884 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
9885 lastContentRow = row;
9886 }
9887
9888 row = row.sibling;
9889 }
9890
9891 return lastContentRow;
9892}
9893
9894function validateRevealOrder(revealOrder) {
9895 {
9896 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
9897 didWarnAboutRevealOrder[revealOrder] = true;
9898
9899 if (typeof revealOrder === 'string') {
9900 switch (revealOrder.toLowerCase()) {
9901 case 'together':
9902 case 'forwards':
9903 case 'backwards':
9904 {
9905 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
9906 break;
9907 }
9908
9909 case 'forward':
9910 case 'backward':
9911 {
9912 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
9913 break;
9914 }
9915
9916 default:
9917 warning$1(false, '"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
9918 break;
9919 }
9920 } else {
9921 warning$1(false, '%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
9922 }
9923 }
9924 }
9925}
9926
9927function validateTailOptions(tailMode, revealOrder) {
9928 {
9929 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
9930 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
9931 didWarnAboutTailOptions[tailMode] = true;
9932 warning$1(false, '"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
9933 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
9934 didWarnAboutTailOptions[tailMode] = true;
9935 warning$1(false, '<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
9936 }
9937 }
9938 }
9939}
9940
9941function validateSuspenseListNestedChild(childSlot, index) {
9942 {
9943 var isArray = Array.isArray(childSlot);
9944 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
9945
9946 if (isArray || isIterable) {
9947 var type = isArray ? 'array' : 'iterable';
9948 warning$1(false, 'A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
9949 return false;
9950 }
9951 }
9952
9953 return true;
9954}
9955
9956function validateSuspenseListChildren(children, revealOrder) {
9957 {
9958 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
9959 if (Array.isArray(children)) {
9960 for (var i = 0; i < children.length; i++) {
9961 if (!validateSuspenseListNestedChild(children[i], i)) {
9962 return;
9963 }
9964 }
9965 } else {
9966 var iteratorFn = getIteratorFn(children);
9967
9968 if (typeof iteratorFn === 'function') {
9969 var childrenIterator = iteratorFn.call(children);
9970
9971 if (childrenIterator) {
9972 var step = childrenIterator.next();
9973 var _i = 0;
9974
9975 for (; !step.done; step = childrenIterator.next()) {
9976 if (!validateSuspenseListNestedChild(step.value, _i)) {
9977 return;
9978 }
9979
9980 _i++;
9981 }
9982 }
9983 } else {
9984 warning$1(false, 'A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
9985 }
9986 }
9987 }
9988 }
9989}
9990
9991function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
9992 var renderState = workInProgress.memoizedState;
9993
9994 if (renderState === null) {
9995 workInProgress.memoizedState = {
9996 isBackwards: isBackwards,
9997 rendering: null,
9998 last: lastContentRow,
9999 tail: tail,
10000 tailExpiration: 0,
10001 tailMode: tailMode
10002 };
10003 } else {
10004 // We can reuse the existing object from previous renders.
10005 renderState.isBackwards = isBackwards;
10006 renderState.rendering = null;
10007 renderState.last = lastContentRow;
10008 renderState.tail = tail;
10009 renderState.tailExpiration = 0;
10010 renderState.tailMode = tailMode;
10011 }
10012} // This can end up rendering this component multiple passes.
10013// The first pass splits the children fibers into two sets. A head and tail.
10014// We first render the head. If anything is in fallback state, we do another
10015// pass through beginWork to rerender all children (including the tail) with
10016// the force suspend context. If the first render didn't have anything in
10017// in fallback state. Then we render each row in the tail one-by-one.
10018// That happens in the completeWork phase without going back to beginWork.
10019
10020
10021function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
10022 var nextProps = workInProgress.pendingProps;
10023 var revealOrder = nextProps.revealOrder;
10024 var tailMode = nextProps.tail;
10025 var newChildren = nextProps.children;
10026 validateRevealOrder(revealOrder);
10027 validateTailOptions(tailMode, revealOrder);
10028 validateSuspenseListChildren(newChildren, revealOrder);
10029 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
10030 var suspenseContext = suspenseStackCursor.current;
10031 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
10032
10033 if (shouldForceFallback) {
10034 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
10035 workInProgress.effectTag |= DidCapture;
10036 } else {
10037 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
10038
10039 if (didSuspendBefore) {
10040 // If we previously forced a fallback, we need to schedule work
10041 // on any nested boundaries to let them know to try to render
10042 // again. This is the same as context updating.
10043 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
10044 }
10045
10046 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10047 }
10048
10049 pushSuspenseContext(workInProgress, suspenseContext);
10050
10051 if ((workInProgress.mode & BatchedMode) === NoMode) {
10052 // Outside of batched mode, SuspenseList doesn't work so we just
10053 // use make it a noop by treating it as the default revealOrder.
10054 workInProgress.memoizedState = null;
10055 } else {
10056 switch (revealOrder) {
10057 case 'forwards':
10058 {
10059 var lastContentRow = findLastContentRow(workInProgress.child);
10060 var tail;
10061
10062 if (lastContentRow === null) {
10063 // The whole list is part of the tail.
10064 // TODO: We could fast path by just rendering the tail now.
10065 tail = workInProgress.child;
10066 workInProgress.child = null;
10067 } else {
10068 // Disconnect the tail rows after the content row.
10069 // We're going to render them separately later.
10070 tail = lastContentRow.sibling;
10071 lastContentRow.sibling = null;
10072 }
10073
10074 initSuspenseListRenderState(workInProgress, false, // isBackwards
10075 tail, lastContentRow, tailMode);
10076 break;
10077 }
10078
10079 case 'backwards':
10080 {
10081 // We're going to find the first row that has existing content.
10082 // At the same time we're going to reverse the list of everything
10083 // we pass in the meantime. That's going to be our tail in reverse
10084 // order.
10085 var _tail = null;
10086 var row = workInProgress.child;
10087 workInProgress.child = null;
10088
10089 while (row !== null) {
10090 var currentRow = row.alternate; // New rows can't be content rows.
10091
10092 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
10093 // This is the beginning of the main content.
10094 workInProgress.child = row;
10095 break;
10096 }
10097
10098 var nextRow = row.sibling;
10099 row.sibling = _tail;
10100 _tail = row;
10101 row = nextRow;
10102 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
10103
10104
10105 initSuspenseListRenderState(workInProgress, true, // isBackwards
10106 _tail, null, // last
10107 tailMode);
10108 break;
10109 }
10110
10111 case 'together':
10112 {
10113 initSuspenseListRenderState(workInProgress, false, // isBackwards
10114 null, // tail
10115 null, // last
10116 undefined);
10117 break;
10118 }
10119
10120 default:
10121 {
10122 // The default reveal order is the same as not having
10123 // a boundary.
10124 workInProgress.memoizedState = null;
10125 }
10126 }
10127 }
10128
10129 return workInProgress.child;
10130}
10131
10132function updatePortalComponent(current, workInProgress, renderExpirationTime) {
10133 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
10134 var nextChildren = workInProgress.pendingProps;
10135
10136 if (current === null) {
10137 // Portals are special because we don't append the children during mount
10138 // but at commit. Therefore we need to track insertions which the normal
10139 // flow doesn't do during mount. This doesn't happen at the root because
10140 // the root always starts with a "current" with a null child.
10141 // TODO: Consider unifying this with how the root works.
10142 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
10143 } else {
10144 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
10145 }
10146
10147 return workInProgress.child;
10148}
10149
10150function updateContextProvider(current, workInProgress, renderExpirationTime) {
10151 var providerType = workInProgress.type;
10152 var context = providerType._context;
10153 var newProps = workInProgress.pendingProps;
10154 var oldProps = workInProgress.memoizedProps;
10155 var newValue = newProps.value;
10156
10157 {
10158 var providerPropTypes = workInProgress.type.propTypes;
10159
10160 if (providerPropTypes) {
10161 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
10162 }
10163 }
10164
10165 pushProvider(workInProgress, newValue);
10166
10167 if (oldProps !== null) {
10168 var oldValue = oldProps.value;
10169 var changedBits = calculateChangedBits(context, newValue, oldValue);
10170
10171 if (changedBits === 0) {
10172 // No change. Bailout early if children are the same.
10173 if (oldProps.children === newProps.children && !hasContextChanged()) {
10174 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
10175 }
10176 } else {
10177 // The context value changed. Search for matching consumers and schedule
10178 // them to update.
10179 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
10180 }
10181 }
10182
10183 var newChildren = newProps.children;
10184 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
10185 return workInProgress.child;
10186}
10187
10188var hasWarnedAboutUsingContextAsConsumer = false;
10189
10190function updateContextConsumer(current, workInProgress, renderExpirationTime) {
10191 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
10192 // DEV mode, we create a separate object for Context.Consumer that acts
10193 // like a proxy to Context. This proxy object adds unnecessary code in PROD
10194 // so we use the old behaviour (Context.Consumer references Context) to
10195 // reduce size and overhead. The separate object references context via
10196 // a property called "_context", which also gives us the ability to check
10197 // in DEV mode if this property exists or not and warn if it does not.
10198
10199 {
10200 if (context._context === undefined) {
10201 // This may be because it's a Context (rather than a Consumer).
10202 // Or it may be because it's older React where they're the same thing.
10203 // We only want to warn if we're sure it's a new React.
10204 if (context !== context.Consumer) {
10205 if (!hasWarnedAboutUsingContextAsConsumer) {
10206 hasWarnedAboutUsingContextAsConsumer = true;
10207 warning$1(false, 'Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
10208 }
10209 }
10210 } else {
10211 context = context._context;
10212 }
10213 }
10214
10215 var newProps = workInProgress.pendingProps;
10216 var render = newProps.children;
10217
10218 {
10219 !(typeof render === 'function') ? warningWithoutStack$1(false, 'A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.') : void 0;
10220 }
10221
10222 prepareToReadContext(workInProgress, renderExpirationTime);
10223 var newValue = readContext(context, newProps.unstable_observedBits);
10224 var newChildren;
10225
10226 {
10227 ReactCurrentOwner$2.current = workInProgress;
10228 setCurrentPhase('render');
10229 newChildren = render(newValue);
10230 setCurrentPhase(null);
10231 } // React DevTools reads this flag.
10232
10233
10234 workInProgress.effectTag |= PerformedWork;
10235 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
10236 return workInProgress.child;
10237}
10238
10239function updateFundamentalComponent$1(current, workInProgress, renderExpirationTime) {
10240 var fundamentalImpl = workInProgress.type.impl;
10241
10242 if (fundamentalImpl.reconcileChildren === false) {
10243 return null;
10244 }
10245
10246 var nextProps = workInProgress.pendingProps;
10247 var nextChildren = nextProps.children;
10248 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
10249 return workInProgress.child;
10250}
10251
10252function updateScopeComponent(current, workInProgress, renderExpirationTime) {
10253 var nextProps = workInProgress.pendingProps;
10254 var nextChildren = nextProps.children;
10255 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
10256 return workInProgress.child;
10257}
10258
10259function markWorkInProgressReceivedUpdate() {
10260 didReceiveUpdate = true;
10261}
10262
10263function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
10264 cancelWorkTimer(workInProgress);
10265
10266 if (current !== null) {
10267 // Reuse previous dependencies
10268 workInProgress.dependencies = current.dependencies;
10269 }
10270
10271 if (enableProfilerTimer) {
10272 // Don't update "base" render times for bailouts.
10273 stopProfilerTimerIfRunning(workInProgress);
10274 }
10275
10276 var updateExpirationTime = workInProgress.expirationTime;
10277
10278 if (updateExpirationTime !== NoWork) {
10279 markUnprocessedUpdateTime(updateExpirationTime);
10280 } // Check if the children have any pending work.
10281
10282
10283 var childExpirationTime = workInProgress.childExpirationTime;
10284
10285 if (childExpirationTime < renderExpirationTime) {
10286 // The children don't have any work either. We can skip them.
10287 // TODO: Once we add back resuming, we should check if the children are
10288 // a work-in-progress set. If so, we need to transfer their effects.
10289 return null;
10290 } else {
10291 // This fiber doesn't have work, but its subtree does. Clone the child
10292 // fibers and continue.
10293 cloneChildFibers(current, workInProgress);
10294 return workInProgress.child;
10295 }
10296}
10297
10298function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
10299 {
10300 var returnFiber = oldWorkInProgress.return;
10301
10302 if (returnFiber === null) {
10303 throw new Error('Cannot swap the root fiber.');
10304 } // Disconnect from the old current.
10305 // It will get deleted.
10306
10307
10308 current.alternate = null;
10309 oldWorkInProgress.alternate = null; // Connect to the new tree.
10310
10311 newWorkInProgress.index = oldWorkInProgress.index;
10312 newWorkInProgress.sibling = oldWorkInProgress.sibling;
10313 newWorkInProgress.return = oldWorkInProgress.return;
10314 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
10315
10316 if (oldWorkInProgress === returnFiber.child) {
10317 returnFiber.child = newWorkInProgress;
10318 } else {
10319 var prevSibling = returnFiber.child;
10320
10321 if (prevSibling === null) {
10322 throw new Error('Expected parent to have a child.');
10323 }
10324
10325 while (prevSibling.sibling !== oldWorkInProgress) {
10326 prevSibling = prevSibling.sibling;
10327
10328 if (prevSibling === null) {
10329 throw new Error('Expected to find the previous sibling.');
10330 }
10331 }
10332
10333 prevSibling.sibling = newWorkInProgress;
10334 } // Delete the old fiber and place the new one.
10335 // Since the old fiber is disconnected, we have to schedule it manually.
10336
10337
10338 var last = returnFiber.lastEffect;
10339
10340 if (last !== null) {
10341 last.nextEffect = current;
10342 returnFiber.lastEffect = current;
10343 } else {
10344 returnFiber.firstEffect = returnFiber.lastEffect = current;
10345 }
10346
10347 current.nextEffect = null;
10348 current.effectTag = Deletion;
10349 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
10350
10351 return newWorkInProgress;
10352 }
10353}
10354
10355function beginWork$1(current, workInProgress, renderExpirationTime) {
10356 var updateExpirationTime = workInProgress.expirationTime;
10357
10358 {
10359 if (workInProgress._debugNeedsRemount && current !== null) {
10360 // This will restart the begin phase with a new fiber.
10361 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
10362 }
10363 }
10364
10365 if (current !== null) {
10366 var oldProps = current.memoizedProps;
10367 var newProps = workInProgress.pendingProps;
10368
10369 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
10370 workInProgress.type !== current.type)) {
10371 // If props or context changed, mark the fiber as having performed work.
10372 // This may be unset if the props are determined to be equal later (memo).
10373 didReceiveUpdate = true;
10374 } else if (updateExpirationTime < renderExpirationTime) {
10375 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
10376 // the begin phase. There's still some bookkeeping we that needs to be done
10377 // in this optimized path, mostly pushing stuff onto the stack.
10378
10379 switch (workInProgress.tag) {
10380 case HostRoot:
10381 pushHostRootContext(workInProgress);
10382 resetHydrationState();
10383 break;
10384
10385 case HostComponent:
10386 pushHostContext(workInProgress);
10387
10388 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
10389 if (enableSchedulerTracing) {
10390 markSpawnedWork(Never);
10391 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
10392
10393
10394 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
10395 return null;
10396 }
10397
10398 break;
10399
10400 case ClassComponent:
10401 {
10402 var Component = workInProgress.type;
10403
10404 if (isContextProvider(Component)) {
10405 pushContextProvider(workInProgress);
10406 }
10407
10408 break;
10409 }
10410
10411 case HostPortal:
10412 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
10413 break;
10414
10415 case ContextProvider:
10416 {
10417 var newValue = workInProgress.memoizedProps.value;
10418 pushProvider(workInProgress, newValue);
10419 break;
10420 }
10421
10422 case Profiler:
10423 if (enableProfilerTimer) {
10424 workInProgress.effectTag |= Update;
10425 }
10426
10427 break;
10428
10429 case SuspenseComponent:
10430 {
10431 var state = workInProgress.memoizedState;
10432
10433 if (state !== null) {
10434 if (enableSuspenseServerRenderer) {
10435 if (state.dehydrated !== null) {
10436 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has
10437 // been unsuspended it has committed as a resolved Suspense component.
10438 // If it needs to be retried, it should have work scheduled on it.
10439
10440 workInProgress.effectTag |= DidCapture;
10441 break;
10442 }
10443 } // If this boundary is currently timed out, we need to decide
10444 // whether to retry the primary children, or to skip over it and
10445 // go straight to the fallback. Check the priority of the primary
10446 // child fragment.
10447
10448
10449 var primaryChildFragment = workInProgress.child;
10450 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
10451
10452 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
10453 // The primary children have pending work. Use the normal path
10454 // to attempt to render the primary children again.
10455 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
10456 } else {
10457 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
10458 // priority. Bailout.
10459
10460 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
10461
10462 if (child !== null) {
10463 // The fallback children have pending work. Skip over the
10464 // primary children and work on the fallback.
10465 return child.sibling;
10466 } else {
10467 return null;
10468 }
10469 }
10470 } else {
10471 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
10472 }
10473
10474 break;
10475 }
10476
10477 case SuspenseListComponent:
10478 {
10479 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
10480 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
10481
10482 if (didSuspendBefore) {
10483 if (hasChildWork) {
10484 // If something was in fallback state last time, and we have all the
10485 // same children then we're still in progressive loading state.
10486 // Something might get unblocked by state updates or retries in the
10487 // tree which will affect the tail. So we need to use the normal
10488 // path to compute the correct tail.
10489 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
10490 } // If none of the children had any work, that means that none of
10491 // them got retried so they'll still be blocked in the same way
10492 // as before. We can fast bail out.
10493
10494
10495 workInProgress.effectTag |= DidCapture;
10496 } // If nothing suspended before and we're rendering the same children,
10497 // then the tail doesn't matter. Anything new that suspends will work
10498 // in the "together" mode, so we can continue from the state we had.
10499
10500
10501 var renderState = workInProgress.memoizedState;
10502
10503 if (renderState !== null) {
10504 // Reset to the "together" mode in case we've started a different
10505 // update in the past but didn't complete it.
10506 renderState.rendering = null;
10507 renderState.tail = null;
10508 }
10509
10510 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
10511
10512 if (hasChildWork) {
10513 break;
10514 } else {
10515 // If none of the children had any work, that means that none of
10516 // them got retried so they'll still be blocked in the same way
10517 // as before. We can fast bail out.
10518 return null;
10519 }
10520 }
10521 }
10522
10523 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
10524 } else {
10525 // An update was scheduled on this fiber, but there are no new props
10526 // nor legacy context. Set this to false. If an update queue or context
10527 // consumer produces a changed value, it will set this to true. Otherwise,
10528 // the component will assume the children have not changed and bail out.
10529 didReceiveUpdate = false;
10530 }
10531 } else {
10532 didReceiveUpdate = false;
10533 } // Before entering the begin phase, clear the expiration time.
10534
10535
10536 workInProgress.expirationTime = NoWork;
10537
10538 switch (workInProgress.tag) {
10539 case IndeterminateComponent:
10540 {
10541 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
10542 }
10543
10544 case LazyComponent:
10545 {
10546 var elementType = workInProgress.elementType;
10547 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
10548 }
10549
10550 case FunctionComponent:
10551 {
10552 var _Component = workInProgress.type;
10553 var unresolvedProps = workInProgress.pendingProps;
10554 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
10555 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
10556 }
10557
10558 case ClassComponent:
10559 {
10560 var _Component2 = workInProgress.type;
10561 var _unresolvedProps = workInProgress.pendingProps;
10562
10563 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
10564
10565 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
10566 }
10567
10568 case HostRoot:
10569 return updateHostRoot(current, workInProgress, renderExpirationTime);
10570
10571 case HostComponent:
10572 return updateHostComponent(current, workInProgress, renderExpirationTime);
10573
10574 case HostText:
10575 return updateHostText(current, workInProgress);
10576
10577 case SuspenseComponent:
10578 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
10579
10580 case HostPortal:
10581 return updatePortalComponent(current, workInProgress, renderExpirationTime);
10582
10583 case ForwardRef:
10584 {
10585 var type = workInProgress.type;
10586 var _unresolvedProps2 = workInProgress.pendingProps;
10587
10588 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
10589
10590 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
10591 }
10592
10593 case Fragment:
10594 return updateFragment(current, workInProgress, renderExpirationTime);
10595
10596 case Mode:
10597 return updateMode(current, workInProgress, renderExpirationTime);
10598
10599 case Profiler:
10600 return updateProfiler(current, workInProgress, renderExpirationTime);
10601
10602 case ContextProvider:
10603 return updateContextProvider(current, workInProgress, renderExpirationTime);
10604
10605 case ContextConsumer:
10606 return updateContextConsumer(current, workInProgress, renderExpirationTime);
10607
10608 case MemoComponent:
10609 {
10610 var _type2 = workInProgress.type;
10611 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
10612
10613 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
10614
10615 {
10616 if (workInProgress.type !== workInProgress.elementType) {
10617 var outerPropTypes = _type2.propTypes;
10618
10619 if (outerPropTypes) {
10620 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
10621 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
10622 }
10623 }
10624 }
10625
10626 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
10627 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
10628 }
10629
10630 case SimpleMemoComponent:
10631 {
10632 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
10633 }
10634
10635 case IncompleteClassComponent:
10636 {
10637 var _Component3 = workInProgress.type;
10638 var _unresolvedProps4 = workInProgress.pendingProps;
10639
10640 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
10641
10642 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
10643 }
10644
10645 case SuspenseListComponent:
10646 {
10647 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
10648 }
10649
10650 case FundamentalComponent:
10651 {
10652 if (enableFundamentalAPI) {
10653 return updateFundamentalComponent$1(current, workInProgress, renderExpirationTime);
10654 }
10655
10656 break;
10657 }
10658
10659 case ScopeComponent:
10660 {
10661 if (enableScopeAPI) {
10662 return updateScopeComponent(current, workInProgress, renderExpirationTime);
10663 }
10664
10665 break;
10666 }
10667 }
10668
10669 (function () {
10670 {
10671 {
10672 throw ReactError(Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue."));
10673 }
10674 }
10675 })();
10676}
10677
10678function createFundamentalStateInstance(currentFiber, props, impl, state) {
10679 return {
10680 currentFiber: currentFiber,
10681 impl: impl,
10682 instance: null,
10683 prevProps: null,
10684 props: props,
10685 state: state
10686 };
10687}
10688
10689function isFiberSuspenseAndTimedOut(fiber) {
10690 return fiber.tag === SuspenseComponent && fiber.memoizedState !== null;
10691}
10692
10693function getSuspenseFallbackChild(fiber) {
10694 return fiber.child.sibling.child;
10695}
10696
10697function collectScopedNodes(node, fn, scopedNodes) {
10698 if (enableScopeAPI) {
10699 if (node.tag === HostComponent) {
10700 var _type = node.type,
10701 memoizedProps = node.memoizedProps;
10702
10703 if (fn(_type, memoizedProps) === true) {
10704 scopedNodes.push(getPublicInstance(node.stateNode));
10705 }
10706 }
10707
10708 var child = node.child;
10709
10710 if (isFiberSuspenseAndTimedOut(node)) {
10711 child = getSuspenseFallbackChild(node);
10712 }
10713
10714 if (child !== null) {
10715 collectScopedNodesFromChildren(child, fn, scopedNodes);
10716 }
10717 }
10718}
10719
10720function collectScopedNodesFromChildren(startingChild, fn, scopedNodes) {
10721 var child = startingChild;
10722
10723 while (child !== null) {
10724 collectScopedNodes(child, fn, scopedNodes);
10725 child = child.sibling;
10726 }
10727}
10728
10729function collectNearestScopeMethods(node, scope, childrenScopes) {
10730 if (isValidScopeNode(node, scope)) {
10731 childrenScopes.push(node.stateNode.methods);
10732 } else {
10733 var child = node.child;
10734
10735 if (isFiberSuspenseAndTimedOut(node)) {
10736 child = getSuspenseFallbackChild(node);
10737 }
10738
10739 if (child !== null) {
10740 collectNearestChildScopeMethods(child, scope, childrenScopes);
10741 }
10742 }
10743}
10744
10745function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) {
10746 var child = startingChild;
10747
10748 while (child !== null) {
10749 collectNearestScopeMethods(child, scope, childrenScopes);
10750 child = child.sibling;
10751 }
10752}
10753
10754function isValidScopeNode(node, scope) {
10755 return node.tag === ScopeComponent && node.type === scope;
10756}
10757
10758function createScopeMethods(scope, instance) {
10759 var fn = scope.fn;
10760 return {
10761 getChildren: function () {
10762 var currentFiber = instance.fiber;
10763 var child = currentFiber.child;
10764 var childrenScopes = [];
10765
10766 if (child !== null) {
10767 collectNearestChildScopeMethods(child, scope, childrenScopes);
10768 }
10769
10770 return childrenScopes.length === 0 ? null : childrenScopes;
10771 },
10772 getChildrenFromRoot: function () {
10773 var currentFiber = instance.fiber;
10774 var node = currentFiber;
10775
10776 while (node !== null) {
10777 var parent = node.return;
10778
10779 if (parent === null) {
10780 break;
10781 }
10782
10783 node = parent;
10784
10785 if (node.tag === ScopeComponent && node.type === scope) {
10786 break;
10787 }
10788 }
10789
10790 var childrenScopes = [];
10791 collectNearestChildScopeMethods(node.child, scope, childrenScopes);
10792 return childrenScopes.length === 0 ? null : childrenScopes;
10793 },
10794 getParent: function () {
10795 var node = instance.fiber.return;
10796
10797 while (node !== null) {
10798 if (node.tag === ScopeComponent && node.type === scope) {
10799 return node.stateNode.methods;
10800 }
10801
10802 node = node.return;
10803 }
10804
10805 return null;
10806 },
10807 getProps: function () {
10808 var currentFiber = instance.fiber;
10809 return currentFiber.memoizedProps;
10810 },
10811 getScopedNodes: function () {
10812 var currentFiber = instance.fiber;
10813 var child = currentFiber.child;
10814 var scopedNodes = [];
10815
10816 if (child !== null) {
10817 collectScopedNodesFromChildren(child, fn, scopedNodes);
10818 }
10819
10820 return scopedNodes.length === 0 ? null : scopedNodes;
10821 }
10822 };
10823}
10824
10825function markUpdate(workInProgress) {
10826 // Tag the fiber with an update effect. This turns a Placement into
10827 // a PlacementAndUpdate.
10828 workInProgress.effectTag |= Update;
10829}
10830
10831function markRef$1(workInProgress) {
10832 workInProgress.effectTag |= Ref;
10833}
10834
10835var appendAllChildren;
10836var updateHostContainer;
10837var updateHostComponent$1;
10838var updateHostText$1;
10839
10840if (supportsMutation) {
10841 // Mutation mode
10842 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
10843 // We only have the top Fiber that was created but we need recurse down its
10844 // children to find all the terminal nodes.
10845 var node = workInProgress.child;
10846
10847 while (node !== null) {
10848 if (node.tag === HostComponent || node.tag === HostText) {
10849 appendInitialChild(parent, node.stateNode);
10850 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
10851 appendInitialChild(parent, node.stateNode.instance);
10852 } else if (node.tag === HostPortal) {// If we have a portal child, then we don't want to traverse
10853 // down its children. Instead, we'll get insertions from each child in
10854 // the portal directly.
10855 } else if (node.child !== null) {
10856 node.child.return = node;
10857 node = node.child;
10858 continue;
10859 }
10860
10861 if (node === workInProgress) {
10862 return;
10863 }
10864
10865 while (node.sibling === null) {
10866 if (node.return === null || node.return === workInProgress) {
10867 return;
10868 }
10869
10870 node = node.return;
10871 }
10872
10873 node.sibling.return = node.return;
10874 node = node.sibling;
10875 }
10876 };
10877
10878 updateHostContainer = function (workInProgress) {// Noop
10879 };
10880
10881 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
10882 // If we have an alternate, that means this is an update and we need to
10883 // schedule a side-effect to do the updates.
10884 var oldProps = current.memoizedProps;
10885
10886 if (oldProps === newProps) {
10887 // In mutation mode, this is sufficient for a bailout because
10888 // we won't touch this node even if children changed.
10889 return;
10890 } // If we get updated because one of our children updated, we don't
10891 // have newProps so we'll have to reuse them.
10892 // TODO: Split the update API as separate for the props vs. children.
10893 // Even better would be if children weren't special cased at all tho.
10894
10895
10896 var instance = workInProgress.stateNode;
10897 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
10898 // component is hitting the resume path. Figure out why. Possibly
10899 // related to `hidden`.
10900
10901 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
10902
10903 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
10904 // is a new ref we mark this as an update. All the work is done in commitWork.
10905
10906 if (updatePayload) {
10907 markUpdate(workInProgress);
10908 }
10909 };
10910
10911 updateHostText$1 = function (current, workInProgress, oldText, newText) {
10912 // If the text differs, mark it as an update. All the work in done in commitWork.
10913 if (oldText !== newText) {
10914 markUpdate(workInProgress);
10915 }
10916 };
10917} else if (supportsPersistence) {
10918 // Persistent host tree mode
10919 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
10920 // We only have the top Fiber that was created but we need recurse down its
10921 // children to find all the terminal nodes.
10922 var node = workInProgress.child;
10923
10924 while (node !== null) {
10925 // eslint-disable-next-line no-labels
10926 branches: if (node.tag === HostComponent) {
10927 var instance = node.stateNode;
10928
10929 if (needsVisibilityToggle && isHidden) {
10930 // This child is inside a timed out tree. Hide it.
10931 var props = node.memoizedProps;
10932 var type = node.type;
10933 instance = cloneHiddenInstance(instance, type, props, node);
10934 }
10935
10936 appendInitialChild(parent, instance);
10937 } else if (node.tag === HostText) {
10938 var _instance = node.stateNode;
10939
10940 if (needsVisibilityToggle && isHidden) {
10941 // This child is inside a timed out tree. Hide it.
10942 var text = node.memoizedProps;
10943 _instance = cloneHiddenTextInstance(_instance, text, node);
10944 }
10945
10946 appendInitialChild(parent, _instance);
10947 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
10948 var _instance2 = node.stateNode.instance;
10949
10950 if (needsVisibilityToggle && isHidden) {
10951 // This child is inside a timed out tree. Hide it.
10952 var _props = node.memoizedProps;
10953 var _type = node.type;
10954 _instance2 = cloneHiddenInstance(_instance2, _type, _props, node);
10955 }
10956
10957 appendInitialChild(parent, _instance2);
10958 } else if (node.tag === HostPortal) {// If we have a portal child, then we don't want to traverse
10959 // down its children. Instead, we'll get insertions from each child in
10960 // the portal directly.
10961 } else if (node.tag === SuspenseComponent) {
10962 if ((node.effectTag & Update) !== NoEffect) {
10963 // Need to toggle the visibility of the primary children.
10964 var newIsHidden = node.memoizedState !== null;
10965
10966 if (newIsHidden) {
10967 var primaryChildParent = node.child;
10968
10969 if (primaryChildParent !== null) {
10970 if (primaryChildParent.child !== null) {
10971 primaryChildParent.child.return = primaryChildParent;
10972 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
10973 }
10974
10975 var fallbackChildParent = primaryChildParent.sibling;
10976
10977 if (fallbackChildParent !== null) {
10978 fallbackChildParent.return = node;
10979 node = fallbackChildParent;
10980 continue;
10981 }
10982 }
10983 }
10984 }
10985
10986 if (node.child !== null) {
10987 // Continue traversing like normal
10988 node.child.return = node;
10989 node = node.child;
10990 continue;
10991 }
10992 } else if (node.child !== null) {
10993 node.child.return = node;
10994 node = node.child;
10995 continue;
10996 } // $FlowFixMe This is correct but Flow is confused by the labeled break.
10997
10998
10999 node = node;
11000
11001 if (node === workInProgress) {
11002 return;
11003 }
11004
11005 while (node.sibling === null) {
11006 if (node.return === null || node.return === workInProgress) {
11007 return;
11008 }
11009
11010 node = node.return;
11011 }
11012
11013 node.sibling.return = node.return;
11014 node = node.sibling;
11015 }
11016 }; // An unfortunate fork of appendAllChildren because we have two different parent types.
11017
11018
11019 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
11020 // We only have the top Fiber that was created but we need recurse down its
11021 // children to find all the terminal nodes.
11022 var node = workInProgress.child;
11023
11024 while (node !== null) {
11025 // eslint-disable-next-line no-labels
11026 branches: if (node.tag === HostComponent) {
11027 var instance = node.stateNode;
11028
11029 if (needsVisibilityToggle && isHidden) {
11030 // This child is inside a timed out tree. Hide it.
11031 var props = node.memoizedProps;
11032 var type = node.type;
11033 instance = cloneHiddenInstance(instance, type, props, node);
11034 }
11035
11036 appendChildToContainerChildSet(containerChildSet, instance);
11037 } else if (node.tag === HostText) {
11038 var _instance3 = node.stateNode;
11039
11040 if (needsVisibilityToggle && isHidden) {
11041 // This child is inside a timed out tree. Hide it.
11042 var text = node.memoizedProps;
11043 _instance3 = cloneHiddenTextInstance(_instance3, text, node);
11044 }
11045
11046 appendChildToContainerChildSet(containerChildSet, _instance3);
11047 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
11048 var _instance4 = node.stateNode.instance;
11049
11050 if (needsVisibilityToggle && isHidden) {
11051 // This child is inside a timed out tree. Hide it.
11052 var _props2 = node.memoizedProps;
11053 var _type2 = node.type;
11054 _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node);
11055 }
11056
11057 appendChildToContainerChildSet(containerChildSet, _instance4);
11058 } else if (node.tag === HostPortal) {// If we have a portal child, then we don't want to traverse
11059 // down its children. Instead, we'll get insertions from each child in
11060 // the portal directly.
11061 } else if (node.tag === SuspenseComponent) {
11062 if ((node.effectTag & Update) !== NoEffect) {
11063 // Need to toggle the visibility of the primary children.
11064 var newIsHidden = node.memoizedState !== null;
11065
11066 if (newIsHidden) {
11067 var primaryChildParent = node.child;
11068
11069 if (primaryChildParent !== null) {
11070 if (primaryChildParent.child !== null) {
11071 primaryChildParent.child.return = primaryChildParent;
11072 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
11073 }
11074
11075 var fallbackChildParent = primaryChildParent.sibling;
11076
11077 if (fallbackChildParent !== null) {
11078 fallbackChildParent.return = node;
11079 node = fallbackChildParent;
11080 continue;
11081 }
11082 }
11083 }
11084 }
11085
11086 if (node.child !== null) {
11087 // Continue traversing like normal
11088 node.child.return = node;
11089 node = node.child;
11090 continue;
11091 }
11092 } else if (node.child !== null) {
11093 node.child.return = node;
11094 node = node.child;
11095 continue;
11096 } // $FlowFixMe This is correct but Flow is confused by the labeled break.
11097
11098
11099 node = node;
11100
11101 if (node === workInProgress) {
11102 return;
11103 }
11104
11105 while (node.sibling === null) {
11106 if (node.return === null || node.return === workInProgress) {
11107 return;
11108 }
11109
11110 node = node.return;
11111 }
11112
11113 node.sibling.return = node.return;
11114 node = node.sibling;
11115 }
11116 };
11117
11118 updateHostContainer = function (workInProgress) {
11119 var portalOrRoot = workInProgress.stateNode;
11120 var childrenUnchanged = workInProgress.firstEffect === null;
11121
11122 if (childrenUnchanged) {// No changes, just reuse the existing instance.
11123 } else {
11124 var container = portalOrRoot.containerInfo;
11125 var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set.
11126
11127 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
11128 portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container.
11129
11130 markUpdate(workInProgress);
11131 finalizeContainerChildren(container, newChildSet);
11132 }
11133 };
11134
11135 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
11136 var currentInstance = current.stateNode;
11137 var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates.
11138 // This guarantees that we can reuse all of them.
11139
11140 var childrenUnchanged = workInProgress.firstEffect === null;
11141
11142 if (childrenUnchanged && oldProps === newProps) {
11143 // No changes, just reuse the existing instance.
11144 // Note that this might release a previous clone.
11145 workInProgress.stateNode = currentInstance;
11146 return;
11147 }
11148
11149 var recyclableInstance = workInProgress.stateNode;
11150 var currentHostContext = getHostContext();
11151 var updatePayload = null;
11152
11153 if (oldProps !== newProps) {
11154 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
11155 }
11156
11157 if (childrenUnchanged && updatePayload === null) {
11158 // No changes, just reuse the existing instance.
11159 // Note that this might release a previous clone.
11160 workInProgress.stateNode = currentInstance;
11161 return;
11162 }
11163
11164 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
11165
11166 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
11167 markUpdate(workInProgress);
11168 }
11169
11170 workInProgress.stateNode = newInstance;
11171
11172 if (childrenUnchanged) {
11173 // If there are no other effects in this tree, we need to flag this node as having one.
11174 // Even though we're not going to use it for anything.
11175 // Otherwise parents won't know that there are new children to propagate upwards.
11176 markUpdate(workInProgress);
11177 } else {
11178 // If children might have changed, we have to add them all to the set.
11179 appendAllChildren(newInstance, workInProgress, false, false);
11180 }
11181 };
11182
11183 updateHostText$1 = function (current, workInProgress, oldText, newText) {
11184 if (oldText !== newText) {
11185 // If the text content differs, we'll create a new text instance for it.
11186 var rootContainerInstance = getRootHostContainer();
11187 var currentHostContext = getHostContext();
11188 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress); // We'll have to mark it as having an effect, even though we won't use the effect for anything.
11189 // This lets the parents know that at least one of their children has changed.
11190
11191 markUpdate(workInProgress);
11192 }
11193 };
11194} else {
11195 // No host operations
11196 updateHostContainer = function (workInProgress) {// Noop
11197 };
11198
11199 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {// Noop
11200 };
11201
11202 updateHostText$1 = function (current, workInProgress, oldText, newText) {// Noop
11203 };
11204}
11205
11206function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
11207 switch (renderState.tailMode) {
11208 case 'hidden':
11209 {
11210 // Any insertions at the end of the tail list after this point
11211 // should be invisible. If there are already mounted boundaries
11212 // anything before them are not considered for collapsing.
11213 // Therefore we need to go through the whole tail to find if
11214 // there are any.
11215 var tailNode = renderState.tail;
11216 var lastTailNode = null;
11217
11218 while (tailNode !== null) {
11219 if (tailNode.alternate !== null) {
11220 lastTailNode = tailNode;
11221 }
11222
11223 tailNode = tailNode.sibling;
11224 } // Next we're simply going to delete all insertions after the
11225 // last rendered item.
11226
11227
11228 if (lastTailNode === null) {
11229 // All remaining items in the tail are insertions.
11230 renderState.tail = null;
11231 } else {
11232 // Detach the insertion after the last node that was already
11233 // inserted.
11234 lastTailNode.sibling = null;
11235 }
11236
11237 break;
11238 }
11239
11240 case 'collapsed':
11241 {
11242 // Any insertions at the end of the tail list after this point
11243 // should be invisible. If there are already mounted boundaries
11244 // anything before them are not considered for collapsing.
11245 // Therefore we need to go through the whole tail to find if
11246 // there are any.
11247 var _tailNode = renderState.tail;
11248 var _lastTailNode = null;
11249
11250 while (_tailNode !== null) {
11251 if (_tailNode.alternate !== null) {
11252 _lastTailNode = _tailNode;
11253 }
11254
11255 _tailNode = _tailNode.sibling;
11256 } // Next we're simply going to delete all insertions after the
11257 // last rendered item.
11258
11259
11260 if (_lastTailNode === null) {
11261 // All remaining items in the tail are insertions.
11262 if (!hasRenderedATailFallback && renderState.tail !== null) {
11263 // We suspended during the head. We want to show at least one
11264 // row at the tail. So we'll keep on and cut off the rest.
11265 renderState.tail.sibling = null;
11266 } else {
11267 renderState.tail = null;
11268 }
11269 } else {
11270 // Detach the insertion after the last node that was already
11271 // inserted.
11272 _lastTailNode.sibling = null;
11273 }
11274
11275 break;
11276 }
11277 }
11278}
11279
11280function completeWork(current, workInProgress, renderExpirationTime) {
11281 var newProps = workInProgress.pendingProps;
11282
11283 switch (workInProgress.tag) {
11284 case IndeterminateComponent:
11285 break;
11286
11287 case LazyComponent:
11288 break;
11289
11290 case SimpleMemoComponent:
11291 case FunctionComponent:
11292 break;
11293
11294 case ClassComponent:
11295 {
11296 var Component = workInProgress.type;
11297
11298 if (isContextProvider(Component)) {
11299 popContext(workInProgress);
11300 }
11301
11302 break;
11303 }
11304
11305 case HostRoot:
11306 {
11307 popHostContainer(workInProgress);
11308 popTopLevelContextObject(workInProgress);
11309 var fiberRoot = workInProgress.stateNode;
11310
11311 if (fiberRoot.pendingContext) {
11312 fiberRoot.context = fiberRoot.pendingContext;
11313 fiberRoot.pendingContext = null;
11314 }
11315
11316 if (current === null || current.child === null) {
11317 // If we hydrated, pop so that we can delete any remaining children
11318 // that weren't hydrated.
11319 var wasHydrated = popHydrationState(workInProgress);
11320
11321 if (wasHydrated) {
11322 // If we hydrated, then we'll need to schedule an update for
11323 // the commit side-effects on the root.
11324 markUpdate(workInProgress);
11325 }
11326 }
11327
11328 updateHostContainer(workInProgress);
11329 break;
11330 }
11331
11332 case HostComponent:
11333 {
11334 popHostContext(workInProgress);
11335 var rootContainerInstance = getRootHostContainer();
11336 var type = workInProgress.type;
11337
11338 if (current !== null && workInProgress.stateNode != null) {
11339 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
11340
11341 if (enableFlareAPI) {
11342 var prevListeners = current.memoizedProps.listeners;
11343 var nextListeners = newProps.listeners;
11344
11345 if (prevListeners !== nextListeners) {
11346 markUpdate(workInProgress);
11347 }
11348 }
11349
11350 if (current.ref !== workInProgress.ref) {
11351 markRef$1(workInProgress);
11352 }
11353 } else {
11354 if (!newProps) {
11355 (function () {
11356 if (!(workInProgress.stateNode !== null)) {
11357 {
11358 throw ReactError(Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue."));
11359 }
11360 }
11361 })(); // This can happen when we abort work.
11362
11363
11364 break;
11365 }
11366
11367 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
11368 // "stack" as the parent. Then append children as we go in beginWork
11369 // or completeWork depending on we want to add then top->down or
11370 // bottom->up. Top->down is faster in IE11.
11371
11372 var _wasHydrated = popHydrationState(workInProgress);
11373
11374 if (_wasHydrated) {
11375 // TODO: Move this and createInstance step into the beginPhase
11376 // to consolidate.
11377 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
11378 // If changes to the hydrated node needs to be applied at the
11379 // commit-phase we mark this as such.
11380 markUpdate(workInProgress);
11381 }
11382
11383 if (enableFlareAPI) {
11384 var listeners = newProps.listeners;
11385
11386 if (listeners != null) {
11387 updateEventListeners(listeners, workInProgress, rootContainerInstance);
11388 }
11389 }
11390 } else {
11391 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
11392 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
11393
11394 workInProgress.stateNode = instance;
11395
11396 if (enableFlareAPI) {
11397 var _listeners = newProps.listeners;
11398
11399 if (_listeners != null) {
11400 updateEventListeners(_listeners, workInProgress, rootContainerInstance);
11401 }
11402 } // Certain renderers require commit-time effects for initial mount.
11403 // (eg DOM renderer supports auto-focus for certain elements).
11404 // Make sure such renderers get scheduled for later work.
11405
11406
11407 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
11408 markUpdate(workInProgress);
11409 }
11410 }
11411
11412 if (workInProgress.ref !== null) {
11413 // If there is a ref on a host node we need to schedule a callback
11414 markRef$1(workInProgress);
11415 }
11416 }
11417
11418 break;
11419 }
11420
11421 case HostText:
11422 {
11423 var newText = newProps;
11424
11425 if (current && workInProgress.stateNode != null) {
11426 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
11427 // to schedule a side-effect to do the updates.
11428
11429 updateHostText$1(current, workInProgress, oldText, newText);
11430 } else {
11431 if (typeof newText !== 'string') {
11432 (function () {
11433 if (!(workInProgress.stateNode !== null)) {
11434 {
11435 throw ReactError(Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue."));
11436 }
11437 }
11438 })(); // This can happen when we abort work.
11439
11440 }
11441
11442 var _rootContainerInstance = getRootHostContainer();
11443
11444 var _currentHostContext = getHostContext();
11445
11446 var _wasHydrated2 = popHydrationState(workInProgress);
11447
11448 if (_wasHydrated2) {
11449 if (prepareToHydrateHostTextInstance(workInProgress)) {
11450 markUpdate(workInProgress);
11451 }
11452 } else {
11453 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
11454 }
11455 }
11456
11457 break;
11458 }
11459
11460 case ForwardRef:
11461 break;
11462
11463 case SuspenseComponent:
11464 {
11465 popSuspenseContext(workInProgress);
11466 var nextState = workInProgress.memoizedState;
11467
11468 if (enableSuspenseServerRenderer) {
11469 if (nextState !== null && nextState.dehydrated !== null) {
11470 if (current === null) {
11471 var _wasHydrated3 = popHydrationState(workInProgress);
11472
11473 (function () {
11474 if (!_wasHydrated3) {
11475 {
11476 throw ReactError(Error("A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React."));
11477 }
11478 }
11479 })();
11480
11481 prepareToHydrateHostSuspenseInstance(workInProgress);
11482
11483 if (enableSchedulerTracing) {
11484 markSpawnedWork(Never);
11485 }
11486
11487 return null;
11488 } else {
11489 // We should never have been in a hydration state if we didn't have a current.
11490 // However, in some of those paths, we might have reentered a hydration state
11491 // and then we might be inside a hydration state. In that case, we'll need to
11492 // exit out of it.
11493 resetHydrationState();
11494
11495 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
11496 // This boundary did not suspend so it's now hydrated and unsuspended.
11497 workInProgress.memoizedState = null;
11498 } // If nothing suspended, we need to schedule an effect to mark this boundary
11499 // as having hydrated so events know that they're free be invoked.
11500 // It's also a signal to replay events and the suspense callback.
11501 // If something suspended, schedule an effect to attach retry listeners.
11502 // So we might as well always mark this.
11503
11504
11505 workInProgress.effectTag |= Update;
11506 return null;
11507 }
11508 }
11509 }
11510
11511 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
11512 // Something suspended. Re-render with the fallback children.
11513 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
11514
11515 return workInProgress;
11516 }
11517
11518 var nextDidTimeout = nextState !== null;
11519 var prevDidTimeout = false;
11520
11521 if (current === null) {
11522 // In cases where we didn't find a suitable hydration boundary we never
11523 // put this in dehydrated mode, but we still need to pop the hydration
11524 // state since we might be inside the insertion tree.
11525 popHydrationState(workInProgress);
11526 } else {
11527 var prevState = current.memoizedState;
11528 prevDidTimeout = prevState !== null;
11529
11530 if (!nextDidTimeout && prevState !== null) {
11531 // We just switched from the fallback to the normal children.
11532 // Delete the fallback.
11533 // TODO: Would it be better to store the fallback fragment on
11534 // the stateNode during the begin phase?
11535 var currentFallbackChild = current.child.sibling;
11536
11537 if (currentFallbackChild !== null) {
11538 // Deletions go at the beginning of the return fiber's effect list
11539 var first = workInProgress.firstEffect;
11540
11541 if (first !== null) {
11542 workInProgress.firstEffect = currentFallbackChild;
11543 currentFallbackChild.nextEffect = first;
11544 } else {
11545 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
11546 currentFallbackChild.nextEffect = null;
11547 }
11548
11549 currentFallbackChild.effectTag = Deletion;
11550 }
11551 }
11552 }
11553
11554 if (nextDidTimeout && !prevDidTimeout) {
11555 // If this subtreee is running in batched mode we can suspend,
11556 // otherwise we won't suspend.
11557 // TODO: This will still suspend a synchronous tree if anything
11558 // in the concurrent tree already suspended during this render.
11559 // This is a known bug.
11560 if ((workInProgress.mode & BatchedMode) !== NoMode) {
11561 // TODO: Move this back to throwException because this is too late
11562 // if this is a large tree which is common for initial loads. We
11563 // don't know if we should restart a render or not until we get
11564 // this marker, and this is too late.
11565 // If this render already had a ping or lower pri updates,
11566 // and this is the first time we know we're going to suspend we
11567 // should be able to immediately restart from within throwException.
11568 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
11569
11570 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
11571 // If this was in an invisible tree or a new render, then showing
11572 // this boundary is ok.
11573 renderDidSuspend();
11574 } else {
11575 // Otherwise, we're going to have to hide content so we should
11576 // suspend for longer if possible.
11577 renderDidSuspendDelayIfPossible();
11578 }
11579 }
11580 }
11581
11582 if (supportsPersistence) {
11583 // TODO: Only schedule updates if not prevDidTimeout.
11584 if (nextDidTimeout) {
11585 // If this boundary just timed out, schedule an effect to attach a
11586 // retry listener to the proimse. This flag is also used to hide the
11587 // primary children.
11588 workInProgress.effectTag |= Update;
11589 }
11590 }
11591
11592 if (supportsMutation) {
11593 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
11594 if (nextDidTimeout || prevDidTimeout) {
11595 // If this boundary just timed out, schedule an effect to attach a
11596 // retry listener to the proimse. This flag is also used to hide the
11597 // primary children. In mutation mode, we also need the flag to
11598 // *unhide* children that were previously hidden, so check if the
11599 // is currently timed out, too.
11600 workInProgress.effectTag |= Update;
11601 }
11602 }
11603
11604 if (enableSuspenseCallback && workInProgress.updateQueue !== null && workInProgress.memoizedProps.suspenseCallback != null) {
11605 // Always notify the callback
11606 workInProgress.effectTag |= Update;
11607 }
11608
11609 break;
11610 }
11611
11612 case Fragment:
11613 break;
11614
11615 case Mode:
11616 break;
11617
11618 case Profiler:
11619 break;
11620
11621 case HostPortal:
11622 popHostContainer(workInProgress);
11623 updateHostContainer(workInProgress);
11624 break;
11625
11626 case ContextProvider:
11627 // Pop provider fiber
11628 popProvider(workInProgress);
11629 break;
11630
11631 case ContextConsumer:
11632 break;
11633
11634 case MemoComponent:
11635 break;
11636
11637 case IncompleteClassComponent:
11638 {
11639 // Same as class component case. I put it down here so that the tags are
11640 // sequential to ensure this switch is compiled to a jump table.
11641 var _Component = workInProgress.type;
11642
11643 if (isContextProvider(_Component)) {
11644 popContext(workInProgress);
11645 }
11646
11647 break;
11648 }
11649
11650 case SuspenseListComponent:
11651 {
11652 popSuspenseContext(workInProgress);
11653 var renderState = workInProgress.memoizedState;
11654
11655 if (renderState === null) {
11656 // We're running in the default, "independent" mode. We don't do anything
11657 // in this mode.
11658 break;
11659 }
11660
11661 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
11662 var renderedTail = renderState.rendering;
11663
11664 if (renderedTail === null) {
11665 // We just rendered the head.
11666 if (!didSuspendAlready) {
11667 // This is the first pass. We need to figure out if anything is still
11668 // suspended in the rendered set.
11669 // If new content unsuspended, but there's still some content that
11670 // didn't. Then we need to do a second pass that forces everything
11671 // to keep showing their fallbacks.
11672 // We might be suspended if something in this render pass suspended, or
11673 // something in the previous committed pass suspended. Otherwise,
11674 // there's no chance so we can skip the expensive call to
11675 // findFirstSuspended.
11676 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
11677
11678 if (!cannotBeSuspended) {
11679 var row = workInProgress.child;
11680
11681 while (row !== null) {
11682 var suspended = findFirstSuspended(row);
11683
11684 if (suspended !== null) {
11685 didSuspendAlready = true;
11686 workInProgress.effectTag |= DidCapture;
11687 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
11688 // part of the second pass. In that case nothing will subscribe to
11689 // its thennables. Instead, we'll transfer its thennables to the
11690 // SuspenseList so that it can retry if they resolve.
11691 // There might be multiple of these in the list but since we're
11692 // going to wait for all of them anyway, it doesn't really matter
11693 // which ones gets to ping. In theory we could get clever and keep
11694 // track of how many dependencies remain but it gets tricky because
11695 // in the meantime, we can add/remove/change items and dependencies.
11696 // We might bail out of the loop before finding any but that
11697 // doesn't matter since that means that the other boundaries that
11698 // we did find already has their listeners attached.
11699
11700 var newThennables = suspended.updateQueue;
11701
11702 if (newThennables !== null) {
11703 workInProgress.updateQueue = newThennables;
11704 workInProgress.effectTag |= Update;
11705 } // Rerender the whole list, but this time, we'll force fallbacks
11706 // to stay in place.
11707 // Reset the effect list before doing the second pass since that's now invalid.
11708
11709
11710 workInProgress.firstEffect = workInProgress.lastEffect = null; // Reset the child fibers to their original state.
11711
11712 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
11713 // rerender the children.
11714
11715 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
11716 return workInProgress.child;
11717 }
11718
11719 row = row.sibling;
11720 }
11721 }
11722 } else {
11723 cutOffTailIfNeeded(renderState, false);
11724 } // Next we're going to render the tail.
11725
11726 } else {
11727 // Append the rendered row to the child list.
11728 if (!didSuspendAlready) {
11729 var _suspended = findFirstSuspended(renderedTail);
11730
11731 if (_suspended !== null) {
11732 workInProgress.effectTag |= DidCapture;
11733 didSuspendAlready = true;
11734 cutOffTailIfNeeded(renderState, true); // This might have been modified.
11735
11736 if (renderState.tail === null && renderState.tailMode === 'hidden') {
11737 // We need to delete the row we just rendered.
11738 // Ensure we transfer the update queue to the parent.
11739 var _newThennables = _suspended.updateQueue;
11740
11741 if (_newThennables !== null) {
11742 workInProgress.updateQueue = _newThennables;
11743 workInProgress.effectTag |= Update;
11744 } // Reset the effect list to what it w as before we rendered this
11745 // child. The nested children have already appended themselves.
11746
11747
11748 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
11749
11750 if (lastEffect !== null) {
11751 lastEffect.nextEffect = null;
11752 } // We're done.
11753
11754
11755 return null;
11756 }
11757 } else if (now() > renderState.tailExpiration && renderExpirationTime > Never) {
11758 // We have now passed our CPU deadline and we'll just give up further
11759 // attempts to render the main content and only render fallbacks.
11760 // The assumption is that this is usually faster.
11761 workInProgress.effectTag |= DidCapture;
11762 didSuspendAlready = true;
11763 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
11764 // to get it started back up to attempt the next item. If we can show
11765 // them, then they really have the same priority as this render.
11766 // So we'll pick it back up the very next render pass once we've had
11767 // an opportunity to yield for paint.
11768
11769 var nextPriority = renderExpirationTime - 1;
11770 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
11771
11772 if (enableSchedulerTracing) {
11773 markSpawnedWork(nextPriority);
11774 }
11775 }
11776 }
11777
11778 if (renderState.isBackwards) {
11779 // The effect list of the backwards tail will have been added
11780 // to the end. This breaks the guarantee that life-cycles fire in
11781 // sibling order but that isn't a strong guarantee promised by React.
11782 // Especially since these might also just pop in during future commits.
11783 // Append to the beginning of the list.
11784 renderedTail.sibling = workInProgress.child;
11785 workInProgress.child = renderedTail;
11786 } else {
11787 var previousSibling = renderState.last;
11788
11789 if (previousSibling !== null) {
11790 previousSibling.sibling = renderedTail;
11791 } else {
11792 workInProgress.child = renderedTail;
11793 }
11794
11795 renderState.last = renderedTail;
11796 }
11797 }
11798
11799 if (renderState.tail !== null) {
11800 // We still have tail rows to render.
11801 if (renderState.tailExpiration === 0) {
11802 // Heuristic for how long we're willing to spend rendering rows
11803 // until we just give up and show what we have so far.
11804 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
11805 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS;
11806 } // Pop a row.
11807
11808
11809 var next = renderState.tail;
11810 renderState.rendering = next;
11811 renderState.tail = next.sibling;
11812 renderState.lastEffect = workInProgress.lastEffect;
11813 next.sibling = null; // Restore the context.
11814 // TODO: We can probably just avoid popping it instead and only
11815 // setting it the first time we go from not suspended to suspended.
11816
11817 var suspenseContext = suspenseStackCursor.current;
11818
11819 if (didSuspendAlready) {
11820 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
11821 } else {
11822 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
11823 }
11824
11825 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
11826
11827 return next;
11828 }
11829
11830 break;
11831 }
11832
11833 case FundamentalComponent:
11834 {
11835 if (enableFundamentalAPI) {
11836 var fundamentalImpl = workInProgress.type.impl;
11837 var fundamentalInstance = workInProgress.stateNode;
11838
11839 if (fundamentalInstance === null) {
11840 var getInitialState = fundamentalImpl.getInitialState;
11841 var fundamentalState;
11842
11843 if (getInitialState !== undefined) {
11844 fundamentalState = getInitialState(newProps);
11845 }
11846
11847 fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance(workInProgress, newProps, fundamentalImpl, fundamentalState || {});
11848
11849 var _instance5 = getFundamentalComponentInstance(fundamentalInstance);
11850
11851 fundamentalInstance.instance = _instance5;
11852
11853 if (fundamentalImpl.reconcileChildren === false) {
11854 return null;
11855 }
11856
11857 appendAllChildren(_instance5, workInProgress, false, false);
11858 mountFundamentalComponent(fundamentalInstance);
11859 } else {
11860 // We fire update in commit phase
11861 var prevProps = fundamentalInstance.props;
11862 fundamentalInstance.prevProps = prevProps;
11863 fundamentalInstance.props = newProps;
11864 fundamentalInstance.currentFiber = workInProgress;
11865
11866 if (supportsPersistence) {
11867 var _instance6 = cloneFundamentalInstance(fundamentalInstance);
11868
11869 fundamentalInstance.instance = _instance6;
11870 appendAllChildren(_instance6, workInProgress, false, false);
11871 }
11872
11873 var shouldUpdate = shouldUpdateFundamentalComponent(fundamentalInstance);
11874
11875 if (shouldUpdate) {
11876 markUpdate(workInProgress);
11877 }
11878 }
11879 }
11880
11881 break;
11882 }
11883
11884 case ScopeComponent:
11885 {
11886 if (enableScopeAPI) {
11887 if (current === null) {
11888 var _type3 = workInProgress.type;
11889 var scopeInstance = {
11890 fiber: workInProgress,
11891 methods: null
11892 };
11893 workInProgress.stateNode = scopeInstance;
11894 scopeInstance.methods = createScopeMethods(_type3, scopeInstance);
11895
11896 if (enableFlareAPI) {
11897 var _listeners2 = newProps.listeners;
11898
11899 if (_listeners2 != null) {
11900 var _rootContainerInstance2 = getRootHostContainer();
11901
11902 updateEventListeners(_listeners2, workInProgress, _rootContainerInstance2);
11903 }
11904 }
11905
11906 if (workInProgress.ref !== null) {
11907 markRef$1(workInProgress);
11908 markUpdate(workInProgress);
11909 }
11910 } else {
11911 if (enableFlareAPI) {
11912 var _prevListeners = current.memoizedProps.listeners;
11913 var _nextListeners = newProps.listeners;
11914
11915 if (_prevListeners !== _nextListeners || workInProgress.ref !== null) {
11916 markUpdate(workInProgress);
11917 }
11918 } else {
11919 if (workInProgress.ref !== null) {
11920 markUpdate(workInProgress);
11921 }
11922 }
11923
11924 if (current.ref !== workInProgress.ref) {
11925 markRef$1(workInProgress);
11926 }
11927 }
11928 }
11929
11930 break;
11931 }
11932
11933 default:
11934 (function () {
11935 {
11936 {
11937 throw ReactError(Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue."));
11938 }
11939 }
11940 })();
11941
11942 }
11943
11944 return null;
11945}
11946
11947function unwindWork(workInProgress, renderExpirationTime) {
11948 switch (workInProgress.tag) {
11949 case ClassComponent:
11950 {
11951 var Component = workInProgress.type;
11952
11953 if (isContextProvider(Component)) {
11954 popContext(workInProgress);
11955 }
11956
11957 var effectTag = workInProgress.effectTag;
11958
11959 if (effectTag & ShouldCapture) {
11960 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
11961 return workInProgress;
11962 }
11963
11964 return null;
11965 }
11966
11967 case HostRoot:
11968 {
11969 popHostContainer(workInProgress);
11970 popTopLevelContextObject(workInProgress);
11971 var _effectTag = workInProgress.effectTag;
11972
11973 (function () {
11974 if (!((_effectTag & DidCapture) === NoEffect)) {
11975 {
11976 throw ReactError(Error("The root failed to unmount after an error. This is likely a bug in React. Please file an issue."));
11977 }
11978 }
11979 })();
11980
11981 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
11982 return workInProgress;
11983 }
11984
11985 case HostComponent:
11986 {
11987 // TODO: popHydrationState
11988 popHostContext(workInProgress);
11989 return null;
11990 }
11991
11992 case SuspenseComponent:
11993 {
11994 popSuspenseContext(workInProgress);
11995
11996 if (enableSuspenseServerRenderer) {
11997 var suspenseState = workInProgress.memoizedState;
11998
11999 if (suspenseState !== null && suspenseState.dehydrated !== null) {
12000 (function () {
12001 if (!(workInProgress.alternate !== null)) {
12002 {
12003 throw ReactError(Error("Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue."));
12004 }
12005 }
12006 })();
12007
12008 resetHydrationState();
12009 }
12010 }
12011
12012 var _effectTag2 = workInProgress.effectTag;
12013
12014 if (_effectTag2 & ShouldCapture) {
12015 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
12016
12017 return workInProgress;
12018 }
12019
12020 return null;
12021 }
12022
12023 case SuspenseListComponent:
12024 {
12025 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
12026 // caught by a nested boundary. If not, it should bubble through.
12027
12028 return null;
12029 }
12030
12031 case HostPortal:
12032 popHostContainer(workInProgress);
12033 return null;
12034
12035 case ContextProvider:
12036 popProvider(workInProgress);
12037 return null;
12038
12039 default:
12040 return null;
12041 }
12042}
12043
12044function unwindInterruptedWork(interruptedWork) {
12045 switch (interruptedWork.tag) {
12046 case ClassComponent:
12047 {
12048 var childContextTypes = interruptedWork.type.childContextTypes;
12049
12050 if (childContextTypes !== null && childContextTypes !== undefined) {
12051 popContext(interruptedWork);
12052 }
12053
12054 break;
12055 }
12056
12057 case HostRoot:
12058 {
12059 popHostContainer(interruptedWork);
12060 popTopLevelContextObject(interruptedWork);
12061 break;
12062 }
12063
12064 case HostComponent:
12065 {
12066 popHostContext(interruptedWork);
12067 break;
12068 }
12069
12070 case HostPortal:
12071 popHostContainer(interruptedWork);
12072 break;
12073
12074 case SuspenseComponent:
12075 popSuspenseContext(interruptedWork);
12076 break;
12077
12078 case SuspenseListComponent:
12079 popSuspenseContext(interruptedWork);
12080 break;
12081
12082 case ContextProvider:
12083 popProvider(interruptedWork);
12084 break;
12085
12086 default:
12087 break;
12088 }
12089}
12090
12091function createCapturedValue(value, source) {
12092 // If the value is an error, call this function immediately after it is thrown
12093 // so the stack is accurate.
12094 return {
12095 value: value,
12096 source: source,
12097 stack: getStackByFiberInDevAndProd(source)
12098 };
12099}
12100
12101var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
12102 var funcArgs = Array.prototype.slice.call(arguments, 3);
12103
12104 try {
12105 func.apply(context, funcArgs);
12106 } catch (error) {
12107 this.onError(error);
12108 }
12109};
12110
12111{
12112 // In DEV mode, we swap out invokeGuardedCallback for a special version
12113 // that plays more nicely with the browser's DevTools. The idea is to preserve
12114 // "Pause on exceptions" behavior. Because React wraps all user-provided
12115 // functions in invokeGuardedCallback, and the production version of
12116 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
12117 // like caught exceptions, and the DevTools won't pause unless the developer
12118 // takes the extra step of enabling pause on caught exceptions. This is
12119 // unintuitive, though, because even though React has caught the error, from
12120 // the developer's perspective, the error is uncaught.
12121 //
12122 // To preserve the expected "Pause on exceptions" behavior, we don't use a
12123 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
12124 // DOM node, and call the user-provided callback from inside an event handler
12125 // for that fake event. If the callback throws, the error is "captured" using
12126 // a global event handler. But because the error happens in a different
12127 // event loop context, it does not interrupt the normal program flow.
12128 // Effectively, this gives us try-catch behavior without actually using
12129 // try-catch. Neat!
12130 // Check that the browser supports the APIs we need to implement our special
12131 // DEV version of invokeGuardedCallback
12132 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
12133 var fakeNode = document.createElement('react');
12134
12135 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
12136 // If document doesn't exist we know for sure we will crash in this method
12137 // when we call document.createEvent(). However this can cause confusing
12138 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
12139 // So we preemptively throw with a better message instead.
12140 (function () {
12141 if (!(typeof document !== 'undefined')) {
12142 {
12143 throw ReactError(Error("The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous."));
12144 }
12145 }
12146 })();
12147
12148 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
12149 // set this to true at the beginning, then set it to false right after
12150 // calling the function. If the function errors, `didError` will never be
12151 // set to false. This strategy works even if the browser is flaky and
12152 // fails to call our global error handler, because it doesn't rely on
12153 // the error event at all.
12154
12155 var didError = true; // Keeps track of the value of window.event so that we can reset it
12156 // during the callback to let user code access window.event in the
12157 // browsers that support it.
12158
12159 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
12160 // dispatching: https://github.com/facebook/react/issues/13688
12161
12162 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
12163 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
12164 // call the user-provided callback.
12165
12166 var funcArgs = Array.prototype.slice.call(arguments, 3);
12167
12168 function callCallback() {
12169 // We immediately remove the callback from event listeners so that
12170 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
12171 // nested call would trigger the fake event handlers of any call higher
12172 // in the stack.
12173 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
12174 // window.event assignment in both IE <= 10 as they throw an error
12175 // "Member not found" in strict mode, and in Firefox which does not
12176 // support window.event.
12177
12178 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
12179 window.event = windowEvent;
12180 }
12181
12182 func.apply(context, funcArgs);
12183 didError = false;
12184 } // Create a global error event handler. We use this to capture the value
12185 // that was thrown. It's possible that this error handler will fire more
12186 // than once; for example, if non-React code also calls `dispatchEvent`
12187 // and a handler for that event throws. We should be resilient to most of
12188 // those cases. Even if our error event handler fires more than once, the
12189 // last error event is always used. If the callback actually does error,
12190 // we know that the last error event is the correct one, because it's not
12191 // possible for anything else to have happened in between our callback
12192 // erroring and the code that follows the `dispatchEvent` call below. If
12193 // the callback doesn't error, but the error event was fired, we know to
12194 // ignore it because `didError` will be false, as described above.
12195
12196
12197 var error; // Use this to track whether the error event is ever called.
12198
12199 var didSetError = false;
12200 var isCrossOriginError = false;
12201
12202 function handleWindowError(event) {
12203 error = event.error;
12204 didSetError = true;
12205
12206 if (error === null && event.colno === 0 && event.lineno === 0) {
12207 isCrossOriginError = true;
12208 }
12209
12210 if (event.defaultPrevented) {
12211 // Some other error handler has prevented default.
12212 // Browsers silence the error report if this happens.
12213 // We'll remember this to later decide whether to log it or not.
12214 if (error != null && typeof error === 'object') {
12215 try {
12216 error._suppressLogging = true;
12217 } catch (inner) {// Ignore.
12218 }
12219 }
12220 }
12221 } // Create a fake event type.
12222
12223
12224 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
12225
12226 window.addEventListener('error', handleWindowError);
12227 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
12228 // errors, it will trigger our global error handler.
12229
12230 evt.initEvent(evtType, false, false);
12231 fakeNode.dispatchEvent(evt);
12232
12233 if (windowEventDescriptor) {
12234 Object.defineProperty(window, 'event', windowEventDescriptor);
12235 }
12236
12237 if (didError) {
12238 if (!didSetError) {
12239 // The callback errored, but the error event never fired.
12240 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.');
12241 } else if (isCrossOriginError) {
12242 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.');
12243 }
12244
12245 this.onError(error);
12246 } // Remove our event listeners
12247
12248
12249 window.removeEventListener('error', handleWindowError);
12250 };
12251
12252 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
12253 }
12254}
12255
12256var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
12257
12258var hasError = false;
12259var caughtError = null; // Used by event system to capture/rethrow the first error.
12260
12261var reporter = {
12262 onError: function (error) {
12263 hasError = true;
12264 caughtError = error;
12265 }
12266};
12267/**
12268 * Call a function while guarding against errors that happens within it.
12269 * Returns an error if it throws, otherwise null.
12270 *
12271 * In production, this is implemented using a try-catch. The reason we don't
12272 * use a try-catch directly is so that we can swap out a different
12273 * implementation in DEV mode.
12274 *
12275 * @param {String} name of the guard to use for logging or debugging
12276 * @param {Function} func The function to invoke
12277 * @param {*} context The context to use when calling the function
12278 * @param {...*} args Arguments for function
12279 */
12280
12281function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
12282 hasError = false;
12283 caughtError = null;
12284 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
12285}
12286/**
12287 * Same as invokeGuardedCallback, but instead of returning an error, it stores
12288 * it in a global so it can be rethrown by `rethrowCaughtError` later.
12289 * TODO: See if caughtError and rethrowError can be unified.
12290 *
12291 * @param {String} name of the guard to use for logging or debugging
12292 * @param {Function} func The function to invoke
12293 * @param {*} context The context to use when calling the function
12294 * @param {...*} args Arguments for function
12295 */
12296
12297
12298/**
12299 * During execution of guarded functions we will capture the first error which
12300 * we will rethrow to be handled by the top level error handler.
12301 */
12302
12303
12304function hasCaughtError() {
12305 return hasError;
12306}
12307function clearCaughtError() {
12308 if (hasError) {
12309 var error = caughtError;
12310 hasError = false;
12311 caughtError = null;
12312 return error;
12313 } else {
12314 (function () {
12315 {
12316 {
12317 throw ReactError(Error("clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue."));
12318 }
12319 }
12320 })();
12321 }
12322}
12323
12324// This module is forked in different environments.
12325// By default, return `true` to log errors to the console.
12326// Forks can return `false` if this isn't desirable.
12327function showErrorDialog(capturedError) {
12328 return true;
12329}
12330
12331function logCapturedError(capturedError) {
12332 var logError = showErrorDialog(capturedError); // Allow injected showErrorDialog() to prevent default console.error logging.
12333 // This enables renderers like ReactNative to better manage redbox behavior.
12334
12335 if (logError === false) {
12336 return;
12337 }
12338
12339 var error = capturedError.error;
12340
12341 {
12342 var componentName = capturedError.componentName,
12343 componentStack = capturedError.componentStack,
12344 errorBoundaryName = capturedError.errorBoundaryName,
12345 errorBoundaryFound = capturedError.errorBoundaryFound,
12346 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
12347 // `preventDefault()` in window `error` handler.
12348 // We record this information as an expando on the error.
12349
12350 if (error != null && error._suppressLogging) {
12351 if (errorBoundaryFound && willRetry) {
12352 // The error is recoverable and was silenced.
12353 // Ignore it and don't print the stack addendum.
12354 // This is handy for testing error boundaries without noise.
12355 return;
12356 } // The error is fatal. Since the silencing might have
12357 // been accidental, we'll surface it anyway.
12358 // However, the browser would have silenced the original error
12359 // so we'll print it first, and then print the stack addendum.
12360
12361
12362 console.error(error); // For a more detailed description of this block, see:
12363 // https://github.com/facebook/react/pull/13384
12364 }
12365
12366 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
12367 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
12368
12369 if (errorBoundaryFound && errorBoundaryName) {
12370 if (willRetry) {
12371 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
12372 } else {
12373 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
12374 }
12375 } else {
12376 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.';
12377 }
12378
12379 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
12380 // We don't include the original error message and JS stack because the browser
12381 // has already printed it. Even if the application swallows the error, it is still
12382 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
12383
12384 console.error(combinedMessage);
12385 }
12386}
12387
12388var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
12389
12390{
12391 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
12392}
12393
12394var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
12395function logError(boundary, errorInfo) {
12396 var source = errorInfo.source;
12397 var stack = errorInfo.stack;
12398
12399 if (stack === null && source !== null) {
12400 stack = getStackByFiberInDevAndProd(source);
12401 }
12402
12403 var capturedError = {
12404 componentName: source !== null ? getComponentName(source.type) : null,
12405 componentStack: stack !== null ? stack : '',
12406 error: errorInfo.value,
12407 errorBoundary: null,
12408 errorBoundaryName: null,
12409 errorBoundaryFound: false,
12410 willRetry: false
12411 };
12412
12413 if (boundary !== null && boundary.tag === ClassComponent) {
12414 capturedError.errorBoundary = boundary.stateNode;
12415 capturedError.errorBoundaryName = getComponentName(boundary.type);
12416 capturedError.errorBoundaryFound = true;
12417 capturedError.willRetry = true;
12418 }
12419
12420 try {
12421 logCapturedError(capturedError);
12422 } catch (e) {
12423 // This method must not throw, or React internal state will get messed up.
12424 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
12425 // we want to report this error outside of the normal stack as a last resort.
12426 // https://github.com/facebook/react/issues/13188
12427 setTimeout(function () {
12428 throw e;
12429 });
12430 }
12431}
12432
12433var callComponentWillUnmountWithTimer = function (current, instance) {
12434 startPhaseTimer(current, 'componentWillUnmount');
12435 instance.props = current.memoizedProps;
12436 instance.state = current.memoizedState;
12437 instance.componentWillUnmount();
12438 stopPhaseTimer();
12439}; // Capture errors so they don't interrupt unmounting.
12440
12441
12442function safelyCallComponentWillUnmount(current, instance) {
12443 {
12444 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
12445
12446 if (hasCaughtError()) {
12447 var unmountError = clearCaughtError();
12448 captureCommitPhaseError(current, unmountError);
12449 }
12450 }
12451}
12452
12453function safelyDetachRef(current) {
12454 var ref = current.ref;
12455
12456 if (ref !== null) {
12457 if (typeof ref === 'function') {
12458 {
12459 invokeGuardedCallback(null, ref, null, null);
12460
12461 if (hasCaughtError()) {
12462 var refError = clearCaughtError();
12463 captureCommitPhaseError(current, refError);
12464 }
12465 }
12466 } else {
12467 ref.current = null;
12468 }
12469 }
12470}
12471
12472function safelyCallDestroy(current, destroy) {
12473 {
12474 invokeGuardedCallback(null, destroy, null);
12475
12476 if (hasCaughtError()) {
12477 var error = clearCaughtError();
12478 captureCommitPhaseError(current, error);
12479 }
12480 }
12481}
12482
12483function commitBeforeMutationLifeCycles(current, finishedWork) {
12484 switch (finishedWork.tag) {
12485 case FunctionComponent:
12486 case ForwardRef:
12487 case SimpleMemoComponent:
12488 {
12489 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
12490 return;
12491 }
12492
12493 case ClassComponent:
12494 {
12495 if (finishedWork.effectTag & Snapshot) {
12496 if (current !== null) {
12497 var prevProps = current.memoizedProps;
12498 var prevState = current.memoizedState;
12499 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
12500 var instance = finishedWork.stateNode; // We could update instance props and state here,
12501 // but instead we rely on them being set during last render.
12502 // TODO: revisit this when we implement resuming.
12503
12504 {
12505 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12506 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12507 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12508 }
12509 }
12510
12511 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
12512
12513 {
12514 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
12515
12516 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
12517 didWarnSet.add(finishedWork.type);
12518 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
12519 }
12520 }
12521
12522 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
12523 stopPhaseTimer();
12524 }
12525 }
12526
12527 return;
12528 }
12529
12530 case HostRoot:
12531 case HostComponent:
12532 case HostText:
12533 case HostPortal:
12534 case IncompleteClassComponent:
12535 // Nothing to do for these component types
12536 return;
12537
12538 default:
12539 {
12540 (function () {
12541 {
12542 {
12543 throw ReactError(Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."));
12544 }
12545 }
12546 })();
12547 }
12548 }
12549}
12550
12551function commitHookEffectList(unmountTag, mountTag, finishedWork) {
12552 var updateQueue = finishedWork.updateQueue;
12553 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
12554
12555 if (lastEffect !== null) {
12556 var firstEffect = lastEffect.next;
12557 var effect = firstEffect;
12558
12559 do {
12560 if ((effect.tag & unmountTag) !== NoEffect$1) {
12561 // Unmount
12562 var destroy = effect.destroy;
12563 effect.destroy = undefined;
12564
12565 if (destroy !== undefined) {
12566 destroy();
12567 }
12568 }
12569
12570 if ((effect.tag & mountTag) !== NoEffect$1) {
12571 // Mount
12572 var create = effect.create;
12573 effect.destroy = create();
12574
12575 {
12576 var _destroy = effect.destroy;
12577
12578 if (_destroy !== undefined && typeof _destroy !== 'function') {
12579 var addendum = void 0;
12580
12581 if (_destroy === null) {
12582 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
12583 } else if (typeof _destroy.then === 'function') {
12584 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';
12585 } else {
12586 addendum = ' You returned: ' + _destroy;
12587 }
12588
12589 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
12590 }
12591 }
12592 }
12593
12594 effect = effect.next;
12595 } while (effect !== firstEffect);
12596 }
12597}
12598
12599function commitPassiveHookEffects(finishedWork) {
12600 if ((finishedWork.effectTag & Passive) !== NoEffect) {
12601 switch (finishedWork.tag) {
12602 case FunctionComponent:
12603 case ForwardRef:
12604 case SimpleMemoComponent:
12605 {
12606 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
12607 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
12608 break;
12609 }
12610
12611 default:
12612 break;
12613 }
12614 }
12615}
12616
12617function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
12618 switch (finishedWork.tag) {
12619 case FunctionComponent:
12620 case ForwardRef:
12621 case SimpleMemoComponent:
12622 {
12623 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
12624 break;
12625 }
12626
12627 case ClassComponent:
12628 {
12629 var instance = finishedWork.stateNode;
12630
12631 if (finishedWork.effectTag & Update) {
12632 if (current === null) {
12633 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
12634 // but instead we rely on them being set during last render.
12635 // TODO: revisit this when we implement resuming.
12636
12637 {
12638 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12639 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12640 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12641 }
12642 }
12643
12644 instance.componentDidMount();
12645 stopPhaseTimer();
12646 } else {
12647 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
12648 var prevState = current.memoizedState;
12649 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
12650 // but instead we rely on them being set during last render.
12651 // TODO: revisit this when we implement resuming.
12652
12653 {
12654 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12655 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12656 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12657 }
12658 }
12659
12660 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
12661 stopPhaseTimer();
12662 }
12663 }
12664
12665 var updateQueue = finishedWork.updateQueue;
12666
12667 if (updateQueue !== null) {
12668 {
12669 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12670 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12671 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
12672 }
12673 } // We could update instance props and state here,
12674 // but instead we rely on them being set during last render.
12675 // TODO: revisit this when we implement resuming.
12676
12677
12678 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
12679 }
12680
12681 return;
12682 }
12683
12684 case HostRoot:
12685 {
12686 var _updateQueue = finishedWork.updateQueue;
12687
12688 if (_updateQueue !== null) {
12689 var _instance = null;
12690
12691 if (finishedWork.child !== null) {
12692 switch (finishedWork.child.tag) {
12693 case HostComponent:
12694 _instance = getPublicInstance(finishedWork.child.stateNode);
12695 break;
12696
12697 case ClassComponent:
12698 _instance = finishedWork.child.stateNode;
12699 break;
12700 }
12701 }
12702
12703 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
12704 }
12705
12706 return;
12707 }
12708
12709 case HostComponent:
12710 {
12711 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
12712 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
12713 // These effects should only be committed when components are first mounted,
12714 // aka when there is no current/alternate.
12715
12716 if (current === null && finishedWork.effectTag & Update) {
12717 var type = finishedWork.type;
12718 var props = finishedWork.memoizedProps;
12719
12720 }
12721
12722 return;
12723 }
12724
12725 case HostText:
12726 {
12727 // We have no life-cycles associated with text.
12728 return;
12729 }
12730
12731 case HostPortal:
12732 {
12733 // We have no life-cycles associated with portals.
12734 return;
12735 }
12736
12737 case Profiler:
12738 {
12739 if (enableProfilerTimer) {
12740 var onRender = finishedWork.memoizedProps.onRender;
12741
12742 if (typeof onRender === 'function') {
12743 if (enableSchedulerTracing) {
12744 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
12745 } else {
12746 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
12747 }
12748 }
12749 }
12750
12751 return;
12752 }
12753
12754 case SuspenseComponent:
12755 {
12756 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
12757 return;
12758 }
12759
12760 case SuspenseListComponent:
12761 case IncompleteClassComponent:
12762 case FundamentalComponent:
12763 case ScopeComponent:
12764 return;
12765
12766 default:
12767 {
12768 (function () {
12769 {
12770 {
12771 throw ReactError(Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."));
12772 }
12773 }
12774 })();
12775 }
12776 }
12777}
12778
12779function hideOrUnhideAllChildren(finishedWork, isHidden) {
12780 if (supportsMutation) {
12781 // We only have the top Fiber that was inserted but we need to recurse down its
12782 // children to find all the terminal nodes.
12783 var node = finishedWork;
12784
12785 while (true) {
12786 if (node.tag === HostComponent) {
12787 var instance = node.stateNode;
12788
12789 if (isHidden) {
12790 hideInstance(instance);
12791 } else {
12792 unhideInstance(node.stateNode, node.memoizedProps);
12793 }
12794 } else if (node.tag === HostText) {
12795 var _instance3 = node.stateNode;
12796
12797 if (isHidden) {
12798
12799 } else {
12800 unhideTextInstance(_instance3, node.memoizedProps);
12801 }
12802 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
12803 // Found a nested Suspense component that timed out. Skip over the
12804 // primary child fragment, which should remain hidden.
12805 var fallbackChildFragment = node.child.sibling;
12806 fallbackChildFragment.return = node;
12807 node = fallbackChildFragment;
12808 continue;
12809 } else if (node.child !== null) {
12810 node.child.return = node;
12811 node = node.child;
12812 continue;
12813 }
12814
12815 if (node === finishedWork) {
12816 return;
12817 }
12818
12819 while (node.sibling === null) {
12820 if (node.return === null || node.return === finishedWork) {
12821 return;
12822 }
12823
12824 node = node.return;
12825 }
12826
12827 node.sibling.return = node.return;
12828 node = node.sibling;
12829 }
12830 }
12831}
12832
12833function commitAttachRef(finishedWork) {
12834 var ref = finishedWork.ref;
12835
12836 if (ref !== null) {
12837 var instance = finishedWork.stateNode;
12838 var instanceToUse;
12839
12840 switch (finishedWork.tag) {
12841 case HostComponent:
12842 instanceToUse = getPublicInstance(instance);
12843 break;
12844
12845 default:
12846 instanceToUse = instance;
12847 } // Moved outside to ensure DCE works with this flag
12848
12849
12850 if (enableScopeAPI && finishedWork.tag === ScopeComponent) {
12851 instanceToUse = instance.methods;
12852 }
12853
12854 if (typeof ref === 'function') {
12855 ref(instanceToUse);
12856 } else {
12857 {
12858 if (!ref.hasOwnProperty('current')) {
12859 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
12860 }
12861 }
12862
12863 ref.current = instanceToUse;
12864 }
12865 }
12866}
12867
12868function commitDetachRef(current) {
12869 var currentRef = current.ref;
12870
12871 if (currentRef !== null) {
12872 if (typeof currentRef === 'function') {
12873 currentRef(null);
12874 } else {
12875 currentRef.current = null;
12876 }
12877 }
12878} // User-originating errors (lifecycles and refs) should not interrupt
12879// deletion, so don't let them throw. Host-originating errors should
12880// interrupt deletion, so it's okay
12881
12882
12883function commitUnmount(finishedRoot, current, renderPriorityLevel) {
12884 onCommitUnmount(current);
12885
12886 switch (current.tag) {
12887 case FunctionComponent:
12888 case ForwardRef:
12889 case MemoComponent:
12890 case SimpleMemoComponent:
12891 {
12892 var updateQueue = current.updateQueue;
12893
12894 if (updateQueue !== null) {
12895 var lastEffect = updateQueue.lastEffect;
12896
12897 if (lastEffect !== null) {
12898 var firstEffect = lastEffect.next; // When the owner fiber is deleted, the destroy function of a passive
12899 // effect hook is called during the synchronous commit phase. This is
12900 // a concession to implementation complexity. Calling it in the
12901 // passive effect phase (like they usually are, when dependencies
12902 // change during an update) would require either traversing the
12903 // children of the deleted fiber again, or including unmount effects
12904 // as part of the fiber effect list.
12905 //
12906 // Because this is during the sync commit phase, we need to change
12907 // the priority.
12908 //
12909 // TODO: Reconsider this implementation trade off.
12910
12911 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
12912 runWithPriority(priorityLevel, function () {
12913 var effect = firstEffect;
12914
12915 do {
12916 var destroy = effect.destroy;
12917
12918 if (destroy !== undefined) {
12919 safelyCallDestroy(current, destroy);
12920 }
12921
12922 effect = effect.next;
12923 } while (effect !== firstEffect);
12924 });
12925 }
12926 }
12927
12928 break;
12929 }
12930
12931 case ClassComponent:
12932 {
12933 safelyDetachRef(current);
12934 var instance = current.stateNode;
12935
12936 if (typeof instance.componentWillUnmount === 'function') {
12937 safelyCallComponentWillUnmount(current, instance);
12938 }
12939
12940 return;
12941 }
12942
12943 case HostComponent:
12944 {
12945 if (enableFlareAPI) {
12946 var dependencies = current.dependencies;
12947
12948 if (dependencies !== null) {
12949 var respondersMap = dependencies.responders;
12950
12951 if (respondersMap !== null) {
12952 var responderInstances = Array.from(respondersMap.values());
12953
12954 for (var i = 0, length = responderInstances.length; i < length; i++) {
12955 var responderInstance = responderInstances[i];
12956 unmountResponderInstance(responderInstance);
12957 }
12958
12959 dependencies.responders = null;
12960 }
12961 }
12962 }
12963
12964 safelyDetachRef(current);
12965 return;
12966 }
12967
12968 case HostPortal:
12969 {
12970 // TODO: this is recursive.
12971 // We are also not using this parent because
12972 // the portal will get pushed immediately.
12973 if (supportsMutation) {
12974 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
12975 } else if (supportsPersistence) {
12976 emptyPortalContainer(current);
12977 }
12978
12979 return;
12980 }
12981
12982 case FundamentalComponent:
12983 {
12984 if (enableFundamentalAPI) {
12985 var fundamentalInstance = current.stateNode;
12986
12987 if (fundamentalInstance !== null) {
12988 unmountFundamentalComponent(fundamentalInstance);
12989 current.stateNode = null;
12990 }
12991 }
12992
12993 return;
12994 }
12995
12996 case DehydratedFragment:
12997 {
12998 if (enableSuspenseCallback) {
12999 var hydrationCallbacks = finishedRoot.hydrationCallbacks;
13000
13001 if (hydrationCallbacks !== null) {
13002 var onDeleted = hydrationCallbacks.onDeleted;
13003
13004 if (onDeleted) {
13005 onDeleted(current.stateNode);
13006 }
13007 }
13008 }
13009
13010 return;
13011 }
13012
13013 case ScopeComponent:
13014 {
13015 if (enableScopeAPI) {
13016 safelyDetachRef(current);
13017 }
13018 }
13019 }
13020}
13021
13022function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
13023 // While we're inside a removed host node we don't want to call
13024 // removeChild on the inner nodes because they're removed by the top
13025 // call anyway. We also want to call componentWillUnmount on all
13026 // composites before this host node is removed from the tree. Therefore
13027 // we do an inner loop while we're still inside the host node.
13028 var node = root;
13029
13030 while (true) {
13031 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
13032 // Skip portals because commitUnmount() currently visits them recursively.
13033
13034 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
13035 // If we don't use mutation we drill down into portals here instead.
13036 !supportsMutation || node.tag !== HostPortal)) {
13037 node.child.return = node;
13038 node = node.child;
13039 continue;
13040 }
13041
13042 if (node === root) {
13043 return;
13044 }
13045
13046 while (node.sibling === null) {
13047 if (node.return === null || node.return === root) {
13048 return;
13049 }
13050
13051 node = node.return;
13052 }
13053
13054 node.sibling.return = node.return;
13055 node = node.sibling;
13056 }
13057}
13058
13059function detachFiber(current) {
13060 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
13061 // should clear the child pointer of the parent alternate to let this
13062 // get GC:ed but we don't know which for sure which parent is the current
13063 // one so we'll settle for GC:ing the subtree of this child. This child
13064 // itself will be GC:ed when the parent updates the next time.
13065
13066 current.return = null;
13067 current.child = null;
13068 current.memoizedState = null;
13069 current.updateQueue = null;
13070 current.dependencies = null;
13071 current.alternate = null;
13072 current.firstEffect = null;
13073 current.lastEffect = null;
13074 current.pendingProps = null;
13075 current.memoizedProps = null;
13076
13077 if (alternate !== null) {
13078 detachFiber(alternate);
13079 }
13080}
13081
13082function emptyPortalContainer(current) {
13083 if (!supportsPersistence) {
13084 return;
13085 }
13086
13087 var portal = current.stateNode;
13088 var containerInfo = portal.containerInfo;
13089 var emptyChildSet = createContainerChildSet(containerInfo);
13090 replaceContainerChildren(containerInfo, emptyChildSet);
13091}
13092
13093function commitContainer(finishedWork) {
13094 if (!supportsPersistence) {
13095 return;
13096 }
13097
13098 switch (finishedWork.tag) {
13099 case ClassComponent:
13100 case HostComponent:
13101 case HostText:
13102 case FundamentalComponent:
13103 {
13104 return;
13105 }
13106
13107 case HostRoot:
13108 case HostPortal:
13109 {
13110 var portalOrRoot = finishedWork.stateNode;
13111 var containerInfo = portalOrRoot.containerInfo,
13112 pendingChildren = portalOrRoot.pendingChildren;
13113 replaceContainerChildren(containerInfo, pendingChildren);
13114 return;
13115 }
13116
13117 default:
13118 {
13119 (function () {
13120 {
13121 {
13122 throw ReactError(Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."));
13123 }
13124 }
13125 })();
13126 }
13127 }
13128}
13129
13130function getHostParentFiber(fiber) {
13131 var parent = fiber.return;
13132
13133 while (parent !== null) {
13134 if (isHostParent(parent)) {
13135 return parent;
13136 }
13137
13138 parent = parent.return;
13139 }
13140
13141 (function () {
13142 {
13143 {
13144 throw ReactError(Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue."));
13145 }
13146 }
13147 })();
13148}
13149
13150function isHostParent(fiber) {
13151 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
13152}
13153
13154function getHostSibling(fiber) {
13155 // We're going to search forward into the tree until we find a sibling host
13156 // node. Unfortunately, if multiple insertions are done in a row we have to
13157 // search past them. This leads to exponential search for the next sibling.
13158 // TODO: Find a more efficient way to do this.
13159 var node = fiber;
13160
13161 siblings: while (true) {
13162 // If we didn't find anything, let's try the next sibling.
13163 while (node.sibling === null) {
13164 if (node.return === null || isHostParent(node.return)) {
13165 // If we pop out of the root or hit the parent the fiber we are the
13166 // last sibling.
13167 return null;
13168 }
13169
13170 node = node.return;
13171 }
13172
13173 node.sibling.return = node.return;
13174 node = node.sibling;
13175
13176 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
13177 // If it is not host node and, we might have a host node inside it.
13178 // Try to search down until we find one.
13179 if (node.effectTag & Placement) {
13180 // If we don't have a child, try the siblings instead.
13181 continue siblings;
13182 } // If we don't have a child, try the siblings instead.
13183 // We also skip portals because they are not part of this host tree.
13184
13185
13186 if (node.child === null || node.tag === HostPortal) {
13187 continue siblings;
13188 } else {
13189 node.child.return = node;
13190 node = node.child;
13191 }
13192 } // Check if this host node is stable or about to be placed.
13193
13194
13195 if (!(node.effectTag & Placement)) {
13196 // Found it!
13197 return node.stateNode;
13198 }
13199 }
13200}
13201
13202function commitPlacement(finishedWork) {
13203 if (!supportsMutation) {
13204 return;
13205 } // Recursively insert all host nodes into the parent.
13206
13207
13208 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
13209
13210 var parent;
13211 var isContainer;
13212 var parentStateNode = parentFiber.stateNode;
13213
13214 switch (parentFiber.tag) {
13215 case HostComponent:
13216 parent = parentStateNode;
13217 isContainer = false;
13218 break;
13219
13220 case HostRoot:
13221 parent = parentStateNode.containerInfo;
13222 isContainer = true;
13223 break;
13224
13225 case HostPortal:
13226 parent = parentStateNode.containerInfo;
13227 isContainer = true;
13228 break;
13229
13230 case FundamentalComponent:
13231 if (enableFundamentalAPI) {
13232 parent = parentStateNode.instance;
13233 isContainer = false;
13234 }
13235
13236 // eslint-disable-next-line-no-fallthrough
13237
13238 default:
13239 (function () {
13240 {
13241 {
13242 throw ReactError(Error("Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue."));
13243 }
13244 }
13245 })();
13246
13247 }
13248
13249 if (parentFiber.effectTag & ContentReset) {
13250 // Reset the text content of the parent before doing any insertions
13251 parentFiber.effectTag &= ~ContentReset;
13252 }
13253
13254 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
13255 // children to find all the terminal nodes.
13256
13257 var node = finishedWork;
13258
13259 while (true) {
13260 var isHost = node.tag === HostComponent || node.tag === HostText;
13261
13262 if (isHost || enableFundamentalAPI && node.tag === FundamentalComponent) {
13263 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
13264
13265 if (before) {
13266 if (isContainer) {
13267 insertInContainerBefore(parent, stateNode, before);
13268 } else {
13269 insertBefore(parent, stateNode, before);
13270 }
13271 } else {
13272 if (isContainer) {
13273 appendChildToContainer(parent, stateNode);
13274 } else {
13275 appendChild(parent, stateNode);
13276 }
13277 }
13278 } else if (node.tag === HostPortal) {// If the insertion itself is a portal, then we don't want to traverse
13279 // down its children. Instead, we'll get insertions from each child in
13280 // the portal directly.
13281 } else if (node.child !== null) {
13282 node.child.return = node;
13283 node = node.child;
13284 continue;
13285 }
13286
13287 if (node === finishedWork) {
13288 return;
13289 }
13290
13291 while (node.sibling === null) {
13292 if (node.return === null || node.return === finishedWork) {
13293 return;
13294 }
13295
13296 node = node.return;
13297 }
13298
13299 node.sibling.return = node.return;
13300 node = node.sibling;
13301 }
13302}
13303
13304function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
13305 // We only have the top Fiber that was deleted but we need to recurse down its
13306 // children to find all the terminal nodes.
13307 var node = current; // Each iteration, currentParent is populated with node's host parent if not
13308 // currentParentIsValid.
13309
13310 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
13311
13312 var currentParent;
13313 var currentParentIsContainer;
13314
13315 while (true) {
13316 if (!currentParentIsValid) {
13317 var parent = node.return;
13318
13319 findParent: while (true) {
13320 (function () {
13321 if (!(parent !== null)) {
13322 {
13323 throw ReactError(Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue."));
13324 }
13325 }
13326 })();
13327
13328 var parentStateNode = parent.stateNode;
13329
13330 switch (parent.tag) {
13331 case HostComponent:
13332 currentParent = parentStateNode;
13333 currentParentIsContainer = false;
13334 break findParent;
13335
13336 case HostRoot:
13337 currentParent = parentStateNode.containerInfo;
13338 currentParentIsContainer = true;
13339 break findParent;
13340
13341 case HostPortal:
13342 currentParent = parentStateNode.containerInfo;
13343 currentParentIsContainer = true;
13344 break findParent;
13345
13346 case FundamentalComponent:
13347 if (enableFundamentalAPI) {
13348 currentParent = parentStateNode.instance;
13349 currentParentIsContainer = false;
13350 }
13351
13352 }
13353
13354 parent = parent.return;
13355 }
13356
13357 currentParentIsValid = true;
13358 }
13359
13360 if (node.tag === HostComponent || node.tag === HostText) {
13361 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
13362 // node from the tree.
13363
13364 if (currentParentIsContainer) {
13365 removeChildFromContainer(currentParent, node.stateNode);
13366 } else {
13367 removeChild(currentParent, node.stateNode);
13368 } // Don't visit children because we already visited them.
13369
13370 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
13371 var fundamentalNode = node.stateNode.instance;
13372 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
13373 // node from the tree.
13374
13375 if (currentParentIsContainer) {
13376 removeChildFromContainer(currentParent, fundamentalNode);
13377 } else {
13378 removeChild(currentParent, fundamentalNode);
13379 }
13380 } else if (enableSuspenseServerRenderer && node.tag === DehydratedFragment) {
13381 if (enableSuspenseCallback) {
13382 var hydrationCallbacks = finishedRoot.hydrationCallbacks;
13383
13384 if (hydrationCallbacks !== null) {
13385 var onDeleted = hydrationCallbacks.onDeleted;
13386
13387 if (onDeleted) {
13388 onDeleted(node.stateNode);
13389 }
13390 }
13391 } // Delete the dehydrated suspense boundary and all of its content.
13392
13393
13394 if (currentParentIsContainer) {
13395 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
13396 } else {
13397 clearSuspenseBoundary(currentParent, node.stateNode);
13398 }
13399 } else if (node.tag === HostPortal) {
13400 if (node.child !== null) {
13401 // When we go into a portal, it becomes the parent to remove from.
13402 // We will reassign it back when we pop the portal on the way up.
13403 currentParent = node.stateNode.containerInfo;
13404 currentParentIsContainer = true; // Visit children because portals might contain host components.
13405
13406 node.child.return = node;
13407 node = node.child;
13408 continue;
13409 }
13410 } else {
13411 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
13412
13413 if (node.child !== null) {
13414 node.child.return = node;
13415 node = node.child;
13416 continue;
13417 }
13418 }
13419
13420 if (node === current) {
13421 return;
13422 }
13423
13424 while (node.sibling === null) {
13425 if (node.return === null || node.return === current) {
13426 return;
13427 }
13428
13429 node = node.return;
13430
13431 if (node.tag === HostPortal) {
13432 // When we go out of the portal, we need to restore the parent.
13433 // Since we don't keep a stack of them, we will search for it.
13434 currentParentIsValid = false;
13435 }
13436 }
13437
13438 node.sibling.return = node.return;
13439 node = node.sibling;
13440 }
13441}
13442
13443function commitDeletion(finishedRoot, current, renderPriorityLevel) {
13444 if (supportsMutation) {
13445 // Recursively delete all host nodes from the parent.
13446 // Detach refs and call componentWillUnmount() on the whole subtree.
13447 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
13448 } else {
13449 // Detach refs and call componentWillUnmount() on the whole subtree.
13450 commitNestedUnmounts(finishedRoot, current, renderPriorityLevel);
13451 }
13452
13453 detachFiber(current);
13454}
13455
13456function commitWork(current, finishedWork) {
13457 if (!supportsMutation) {
13458 switch (finishedWork.tag) {
13459 case FunctionComponent:
13460 case ForwardRef:
13461 case MemoComponent:
13462 case SimpleMemoComponent:
13463 {
13464 // Note: We currently never use MountMutation, but useLayout uses
13465 // UnmountMutation.
13466 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
13467 return;
13468 }
13469
13470 case Profiler:
13471 {
13472 return;
13473 }
13474
13475 case SuspenseComponent:
13476 {
13477 commitSuspenseComponent(finishedWork);
13478 attachSuspenseRetryListeners(finishedWork);
13479 return;
13480 }
13481
13482 case SuspenseListComponent:
13483 {
13484 attachSuspenseRetryListeners(finishedWork);
13485 return;
13486 }
13487
13488 case HostRoot:
13489 {
13490 if (supportsHydration) {
13491 var root = finishedWork.stateNode;
13492
13493 if (root.hydrate) {
13494 // We've just hydrated. No need to hydrate again.
13495 root.hydrate = false;
13496 commitHydratedContainer(root.containerInfo);
13497 }
13498 }
13499
13500 break;
13501 }
13502 }
13503
13504 commitContainer(finishedWork);
13505 return;
13506 }
13507
13508 switch (finishedWork.tag) {
13509 case FunctionComponent:
13510 case ForwardRef:
13511 case MemoComponent:
13512 case SimpleMemoComponent:
13513 {
13514 // Note: We currently never use MountMutation, but useLayout uses
13515 // UnmountMutation.
13516 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
13517 return;
13518 }
13519
13520 case ClassComponent:
13521 {
13522 return;
13523 }
13524
13525 case HostComponent:
13526 {
13527 var instance = finishedWork.stateNode;
13528
13529 if (instance != null) {
13530 // Commit the work prepared earlier.
13531 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
13532 // as the newProps. The updatePayload will contain the real change in
13533 // this case.
13534
13535 var oldProps = current !== null ? current.memoizedProps : newProps;
13536 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
13537
13538 var updatePayload = finishedWork.updateQueue;
13539 finishedWork.updateQueue = null;
13540
13541 if (updatePayload !== null) {
13542 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
13543 }
13544
13545 if (enableFlareAPI) {
13546 var prevListeners = oldProps.listeners;
13547 var nextListeners = newProps.listeners;
13548
13549 if (prevListeners !== nextListeners) {
13550 updateEventListeners(nextListeners, finishedWork, null);
13551 }
13552 }
13553 }
13554
13555 return;
13556 }
13557
13558 case HostText:
13559 {
13560 (function () {
13561 if (!(finishedWork.stateNode !== null)) {
13562 {
13563 throw ReactError(Error("This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue."));
13564 }
13565 }
13566 })();
13567
13568 var textInstance = finishedWork.stateNode;
13569 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
13570 // as the newProps. The updatePayload will contain the real change in
13571 // this case.
13572
13573 var oldText = current !== null ? current.memoizedProps : newText;
13574 return;
13575 }
13576
13577 case HostRoot:
13578 {
13579 if (supportsHydration) {
13580 var _root = finishedWork.stateNode;
13581
13582 if (_root.hydrate) {
13583 // We've just hydrated. No need to hydrate again.
13584 _root.hydrate = false;
13585 commitHydratedContainer(_root.containerInfo);
13586 }
13587 }
13588
13589 return;
13590 }
13591
13592 case Profiler:
13593 {
13594 return;
13595 }
13596
13597 case SuspenseComponent:
13598 {
13599 commitSuspenseComponent(finishedWork);
13600 attachSuspenseRetryListeners(finishedWork);
13601 return;
13602 }
13603
13604 case SuspenseListComponent:
13605 {
13606 attachSuspenseRetryListeners(finishedWork);
13607 return;
13608 }
13609
13610 case IncompleteClassComponent:
13611 {
13612 return;
13613 }
13614
13615 case FundamentalComponent:
13616 {
13617 if (enableFundamentalAPI) {
13618 var fundamentalInstance = finishedWork.stateNode;
13619 updateFundamentalComponent(fundamentalInstance);
13620 }
13621
13622 return;
13623 }
13624
13625 case ScopeComponent:
13626 {
13627 if (enableScopeAPI) {
13628 var scopeInstance = finishedWork.stateNode;
13629 scopeInstance.fiber = finishedWork;
13630
13631 if (enableFlareAPI) {
13632 var _newProps = finishedWork.memoizedProps;
13633
13634 var _oldProps = current !== null ? current.memoizedProps : _newProps;
13635
13636 var _prevListeners = _oldProps.listeners;
13637 var _nextListeners = _newProps.listeners;
13638
13639 if (_prevListeners !== _nextListeners) {
13640 updateEventListeners(_nextListeners, finishedWork, null);
13641 }
13642 }
13643 }
13644
13645 return;
13646 }
13647
13648 default:
13649 {
13650 (function () {
13651 {
13652 {
13653 throw ReactError(Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."));
13654 }
13655 }
13656 })();
13657 }
13658 }
13659}
13660
13661function commitSuspenseComponent(finishedWork) {
13662 var newState = finishedWork.memoizedState;
13663 var newDidTimeout;
13664 var primaryChildParent = finishedWork;
13665
13666 if (newState === null) {
13667 newDidTimeout = false;
13668 } else {
13669 newDidTimeout = true;
13670 primaryChildParent = finishedWork.child;
13671 markCommitTimeOfFallback();
13672 }
13673
13674 if (supportsMutation && primaryChildParent !== null) {
13675 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
13676 }
13677
13678 if (enableSuspenseCallback && newState !== null) {
13679 var suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
13680
13681 if (typeof suspenseCallback === 'function') {
13682 var thenables = finishedWork.updateQueue;
13683
13684 if (thenables !== null) {
13685 suspenseCallback(new Set(thenables));
13686 }
13687 } else {
13688 if (suspenseCallback !== undefined) {
13689 warning$1(false, 'Unexpected type for suspenseCallback.');
13690 }
13691 }
13692 }
13693}
13694
13695function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
13696 if (!supportsHydration) {
13697 return;
13698 }
13699
13700 var newState = finishedWork.memoizedState;
13701
13702 if (newState === null) {
13703 var current = finishedWork.alternate;
13704
13705 if (current !== null) {
13706 var prevState = current.memoizedState;
13707
13708 if (prevState !== null) {
13709 var suspenseInstance = prevState.dehydrated;
13710
13711 if (suspenseInstance !== null) {
13712 commitHydratedSuspenseInstance(suspenseInstance);
13713
13714 if (enableSuspenseCallback) {
13715 var hydrationCallbacks = finishedRoot.hydrationCallbacks;
13716
13717 if (hydrationCallbacks !== null) {
13718 var onHydrated = hydrationCallbacks.onHydrated;
13719
13720 if (onHydrated) {
13721 onHydrated(suspenseInstance);
13722 }
13723 }
13724 }
13725 }
13726 }
13727 }
13728 }
13729}
13730
13731function attachSuspenseRetryListeners(finishedWork) {
13732 // If this boundary just timed out, then it will have a set of thenables.
13733 // For each thenable, attach a listener so that when it resolves, React
13734 // attempts to re-render the boundary in the primary (pre-timeout) state.
13735 var thenables = finishedWork.updateQueue;
13736
13737 if (thenables !== null) {
13738 finishedWork.updateQueue = null;
13739 var retryCache = finishedWork.stateNode;
13740
13741 if (retryCache === null) {
13742 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
13743 }
13744
13745 thenables.forEach(function (thenable) {
13746 // Memoize using the boundary fiber to prevent redundant listeners.
13747 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
13748
13749 if (!retryCache.has(thenable)) {
13750 if (enableSchedulerTracing) {
13751 if (thenable.__reactDoNotTraceInteractions !== true) {
13752 retry = unstable_wrap(retry);
13753 }
13754 }
13755
13756 retryCache.add(thenable);
13757 thenable.then(retry, retry);
13758 }
13759 });
13760 }
13761}
13762
13763function commitResetTextContent(current) {
13764 if (!supportsMutation) {
13765 return;
13766 }
13767
13768 resetTextContent(current.stateNode);
13769}
13770
13771var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
13772
13773function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
13774 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
13775
13776 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
13777 // being called "element".
13778
13779 update.payload = {
13780 element: null
13781 };
13782 var error = errorInfo.value;
13783
13784 update.callback = function () {
13785 onUncaughtError(error);
13786 logError(fiber, errorInfo);
13787 };
13788
13789 return update;
13790}
13791
13792function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
13793 var update = createUpdate(expirationTime, null);
13794 update.tag = CaptureUpdate;
13795 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
13796
13797 if (typeof getDerivedStateFromError === 'function') {
13798 var error = errorInfo.value;
13799
13800 update.payload = function () {
13801 logError(fiber, errorInfo);
13802 return getDerivedStateFromError(error);
13803 };
13804 }
13805
13806 var inst = fiber.stateNode;
13807
13808 if (inst !== null && typeof inst.componentDidCatch === 'function') {
13809 update.callback = function callback() {
13810 {
13811 markFailedErrorBoundaryForHotReloading(fiber);
13812 }
13813
13814 if (typeof getDerivedStateFromError !== 'function') {
13815 // To preserve the preexisting retry behavior of error boundaries,
13816 // we keep track of which ones already failed during this batch.
13817 // This gets reset before we yield back to the browser.
13818 // TODO: Warn in strict mode if getDerivedStateFromError is
13819 // not defined.
13820 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
13821
13822 logError(fiber, errorInfo);
13823 }
13824
13825 var error = errorInfo.value;
13826 var stack = errorInfo.stack;
13827 this.componentDidCatch(error, {
13828 componentStack: stack !== null ? stack : ''
13829 });
13830
13831 {
13832 if (typeof getDerivedStateFromError !== 'function') {
13833 // If componentDidCatch is the only error boundary method defined,
13834 // then it needs to call setState to recover from errors.
13835 // If no state update is scheduled then the boundary will swallow the error.
13836 !(fiber.expirationTime === Sync) ? warningWithoutStack$1(false, '%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown') : void 0;
13837 }
13838 }
13839 };
13840 } else {
13841 update.callback = function () {
13842 markFailedErrorBoundaryForHotReloading(fiber);
13843 };
13844 }
13845
13846 return update;
13847}
13848
13849function attachPingListener(root, renderExpirationTime, thenable) {
13850 // Attach a listener to the promise to "ping" the root and retry. But
13851 // only if one does not already exist for the current render expiration
13852 // time (which acts like a "thread ID" here).
13853 var pingCache = root.pingCache;
13854 var threadIDs;
13855
13856 if (pingCache === null) {
13857 pingCache = root.pingCache = new PossiblyWeakMap();
13858 threadIDs = new Set();
13859 pingCache.set(thenable, threadIDs);
13860 } else {
13861 threadIDs = pingCache.get(thenable);
13862
13863 if (threadIDs === undefined) {
13864 threadIDs = new Set();
13865 pingCache.set(thenable, threadIDs);
13866 }
13867 }
13868
13869 if (!threadIDs.has(renderExpirationTime)) {
13870 // Memoize using the thread ID to prevent redundant listeners.
13871 threadIDs.add(renderExpirationTime);
13872 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
13873 thenable.then(ping, ping);
13874 }
13875}
13876
13877function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
13878 // The source fiber did not complete.
13879 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
13880
13881 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
13882
13883 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
13884 // This is a thenable.
13885 var thenable = value;
13886 checkForWrongSuspensePriorityInDEV(sourceFiber);
13887 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
13888
13889 var _workInProgress = returnFiber;
13890
13891 do {
13892 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
13893 // Found the nearest boundary.
13894 // Stash the promise on the boundary fiber. If the boundary times out, we'll
13895 // attach another listener to flip the boundary back to its normal state.
13896 var thenables = _workInProgress.updateQueue;
13897
13898 if (thenables === null) {
13899 var updateQueue = new Set();
13900 updateQueue.add(thenable);
13901 _workInProgress.updateQueue = updateQueue;
13902 } else {
13903 thenables.add(thenable);
13904 } // If the boundary is outside of batched mode, we should *not*
13905 // suspend the commit. Pretend as if the suspended component rendered
13906 // null and keep rendering. In the commit phase, we'll schedule a
13907 // subsequent synchronous update to re-render the Suspense.
13908 //
13909 // Note: It doesn't matter whether the component that suspended was
13910 // inside a batched mode tree. If the Suspense is outside of it, we
13911 // should *not* suspend the commit.
13912
13913
13914 if ((_workInProgress.mode & BatchedMode) === NoMode) {
13915 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
13916 // But we shouldn't call any lifecycle methods or callbacks. Remove
13917 // all lifecycle effect tags.
13918
13919 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
13920
13921 if (sourceFiber.tag === ClassComponent) {
13922 var currentSourceFiber = sourceFiber.alternate;
13923
13924 if (currentSourceFiber === null) {
13925 // This is a new mount. Change the tag so it's not mistaken for a
13926 // completed class component. For example, we should not call
13927 // componentWillUnmount if it is deleted.
13928 sourceFiber.tag = IncompleteClassComponent;
13929 } else {
13930 // When we try rendering again, we should not reuse the current fiber,
13931 // since it's known to be in an inconsistent state. Use a force update to
13932 // prevent a bail out.
13933 var update = createUpdate(Sync, null);
13934 update.tag = ForceUpdate;
13935 enqueueUpdate(sourceFiber, update);
13936 }
13937 } // The source fiber did not complete. Mark it with Sync priority to
13938 // indicate that it still has pending work.
13939
13940
13941 sourceFiber.expirationTime = Sync; // Exit without suspending.
13942
13943 return;
13944 } // Confirmed that the boundary is in a concurrent mode tree. Continue
13945 // with the normal suspend path.
13946 //
13947 // After this we'll use a set of heuristics to determine whether this
13948 // render pass will run to completion or restart or "suspend" the commit.
13949 // The actual logic for this is spread out in different places.
13950 //
13951 // This first principle is that if we're going to suspend when we complete
13952 // a root, then we should also restart if we get an update or ping that
13953 // might unsuspend it, and vice versa. The only reason to suspend is
13954 // because you think you might want to restart before committing. However,
13955 // it doesn't make sense to restart only while in the period we're suspended.
13956 //
13957 // Restarting too aggressively is also not good because it starves out any
13958 // intermediate loading state. So we use heuristics to determine when.
13959 // Suspense Heuristics
13960 //
13961 // If nothing threw a Promise or all the same fallbacks are already showing,
13962 // then don't suspend/restart.
13963 //
13964 // If this is an initial render of a new tree of Suspense boundaries and
13965 // those trigger a fallback, then don't suspend/restart. We want to ensure
13966 // that we can show the initial loading state as quickly as possible.
13967 //
13968 // If we hit a "Delayed" case, such as when we'd switch from content back into
13969 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
13970 // this case. If none is defined, JND is used instead.
13971 //
13972 // If we're already showing a fallback and it gets "retried", allowing us to show
13973 // another level, but there's still an inner boundary that would show a fallback,
13974 // then we suspend/restart for 500ms since the last time we showed a fallback
13975 // anywhere in the tree. This effectively throttles progressive loading into a
13976 // consistent train of commits. This also gives us an opportunity to restart to
13977 // get to the completed state slightly earlier.
13978 //
13979 // If there's ambiguity due to batching it's resolved in preference of:
13980 // 1) "delayed", 2) "initial render", 3) "retry".
13981 //
13982 // We want to ensure that a "busy" state doesn't get force committed. We want to
13983 // ensure that new initial loading states can commit as soon as possible.
13984
13985
13986 attachPingListener(root, renderExpirationTime, thenable);
13987 _workInProgress.effectTag |= ShouldCapture;
13988 _workInProgress.expirationTime = renderExpirationTime;
13989 return;
13990 } // This boundary already captured during this render. Continue to the next
13991 // boundary.
13992
13993
13994 _workInProgress = _workInProgress.return;
13995 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
13996 // TODO: Use invariant so the message is stripped in prod?
13997
13998
13999 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));
14000 } // We didn't find a boundary that could handle this type of exception. Start
14001 // over and traverse parent path again, this time treating the exception
14002 // as an error.
14003
14004
14005 renderDidError();
14006 value = createCapturedValue(value, sourceFiber);
14007 var workInProgress = returnFiber;
14008
14009 do {
14010 switch (workInProgress.tag) {
14011 case HostRoot:
14012 {
14013 var _errorInfo = value;
14014 workInProgress.effectTag |= ShouldCapture;
14015 workInProgress.expirationTime = renderExpirationTime;
14016
14017 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
14018
14019 enqueueCapturedUpdate(workInProgress, _update);
14020 return;
14021 }
14022
14023 case ClassComponent:
14024 // Capture and retry
14025 var errorInfo = value;
14026 var ctor = workInProgress.type;
14027 var instance = workInProgress.stateNode;
14028
14029 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
14030 workInProgress.effectTag |= ShouldCapture;
14031 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
14032
14033 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
14034
14035 enqueueCapturedUpdate(workInProgress, _update2);
14036 return;
14037 }
14038
14039 break;
14040
14041 default:
14042 break;
14043 }
14044
14045 workInProgress = workInProgress.return;
14046 } while (workInProgress !== null);
14047}
14048
14049var ceil = Math.ceil;
14050var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
14051var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
14052var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
14053var NoContext =
14054/* */
140550;
14056var BatchedContext =
14057/* */
140581;
14059var DiscreteEventContext =
14060/* */
140614;
14062var LegacyUnbatchedContext =
14063/* */
140648;
14065var RenderContext =
14066/* */
1406716;
14068var CommitContext =
14069/* */
1407032;
14071var RootIncomplete = 0;
14072var RootFatalErrored = 1;
14073var RootErrored = 2;
14074var RootSuspended = 3;
14075var RootSuspendedWithDelay = 4;
14076var RootCompleted = 5;
14077var RootLocked = 6;
14078// Describes where we are in the React execution stack
14079var executionContext = NoContext; // The root we're working on
14080
14081var workInProgressRoot = null; // The fiber we're working on
14082
14083var workInProgress = null; // The expiration time we're rendering
14084
14085var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc.
14086
14087var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
14088
14089var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
14090// This is conceptually a time stamp but expressed in terms of an ExpirationTime
14091// because we deal mostly with expiration times in the hot path, so this avoids
14092// the conversion happening in the hot path.
14093
14094var workInProgressRootLatestProcessedExpirationTime = Sync;
14095var workInProgressRootLatestSuspenseTimeout = Sync;
14096var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
14097// includes unprocessed updates, not work in bailed out children.
14098
14099var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
14100// This flag determines if it might be worthwhile to restart if an opportunity
14101// happens latere.
14102
14103var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
14104// model where we don't commit new loading states in too quick succession.
14105
14106var globalMostRecentFallbackTime = 0;
14107var FALLBACK_THROTTLE_MS = 500;
14108var nextEffect = null;
14109var hasUncaughtError = false;
14110var firstUncaughtError = null;
14111var legacyErrorBoundariesThatAlreadyFailed = null;
14112var rootDoesHavePassiveEffects = false;
14113var rootWithPendingPassiveEffects = null;
14114var pendingPassiveEffectsRenderPriority = NoPriority;
14115var pendingPassiveEffectsExpirationTime = NoWork;
14116var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
14117
14118var NESTED_UPDATE_LIMIT = 50;
14119var nestedUpdateCount = 0;
14120var rootWithNestedUpdates = null;
14121var NESTED_PASSIVE_UPDATE_LIMIT = 50;
14122var nestedPassiveUpdateCount = 0;
14123var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
14124// during the commit phase. This enables them to be traced across components
14125// that spawn new work during render. E.g. hidden boundaries, suspended SSR
14126// hydration or SuspenseList.
14127
14128var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
14129// time). However, if two updates are scheduled within the same event, we
14130// should treat their start times as simultaneous, even if the actual clock
14131// time has advanced between the first and second call.
14132// In other words, because expiration times determine how updates are batched,
14133// we want all updates of like priority that occur within the same event to
14134// receive the same expiration time. Otherwise we get tearing.
14135
14136var currentEventTime = NoWork;
14137function requestCurrentTime() {
14138 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
14139 // We're inside React, so it's fine to read the actual time.
14140 return msToExpirationTime(now());
14141 } // We're not inside React, so we may be in the middle of a browser event.
14142
14143
14144 if (currentEventTime !== NoWork) {
14145 // Use the same start time for all updates until we enter React again.
14146 return currentEventTime;
14147 } // This is the first update since React yielded. Compute a new start time.
14148
14149
14150 currentEventTime = msToExpirationTime(now());
14151 return currentEventTime;
14152}
14153function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
14154 var mode = fiber.mode;
14155
14156 if ((mode & BatchedMode) === NoMode) {
14157 return Sync;
14158 }
14159
14160 var priorityLevel = getCurrentPriorityLevel();
14161
14162 if ((mode & ConcurrentMode) === NoMode) {
14163 return priorityLevel === ImmediatePriority ? Sync : Batched;
14164 }
14165
14166 if ((executionContext & RenderContext) !== NoContext) {
14167 // Use whatever time we're already rendering
14168 // TODO: Should there be a way to opt out, like with `runWithPriority`?
14169 return renderExpirationTime;
14170 }
14171
14172 var expirationTime;
14173
14174 if (suspenseConfig !== null) {
14175 // Compute an expiration time based on the Suspense timeout.
14176 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
14177 } else {
14178 // Compute an expiration time based on the Scheduler priority.
14179 switch (priorityLevel) {
14180 case ImmediatePriority:
14181 expirationTime = Sync;
14182 break;
14183
14184 case UserBlockingPriority:
14185 // TODO: Rename this to computeUserBlockingExpiration
14186 expirationTime = computeInteractiveExpiration(currentTime);
14187 break;
14188
14189 case NormalPriority:
14190 case LowPriority:
14191 // TODO: Handle LowPriority
14192 // TODO: Rename this to... something better.
14193 expirationTime = computeAsyncExpiration(currentTime);
14194 break;
14195
14196 case IdlePriority:
14197 expirationTime = Idle;
14198 break;
14199
14200 default:
14201 (function () {
14202 {
14203 {
14204 throw ReactError(Error("Expected a valid priority level"));
14205 }
14206 }
14207 })();
14208
14209 }
14210 } // If we're in the middle of rendering a tree, do not update at the same
14211 // expiration time that is already rendering.
14212 // TODO: We shouldn't have to do this if the update is on a different root.
14213 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
14214 // the root when we check for this condition.
14215
14216
14217 if (workInProgressRoot !== null && expirationTime === renderExpirationTime) {
14218 // This is a trick to move this update into a separate batch
14219 expirationTime -= 1;
14220 }
14221
14222 return expirationTime;
14223}
14224
14225function scheduleUpdateOnFiber(fiber, expirationTime) {
14226 checkForNestedUpdates();
14227 warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
14228 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
14229
14230 if (root === null) {
14231 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
14232 return;
14233 }
14234
14235 checkForInterruption(fiber, expirationTime);
14236 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
14237 // priority as an argument to that function and this one.
14238
14239 var priorityLevel = getCurrentPriorityLevel();
14240
14241 if (expirationTime === Sync) {
14242 if ( // Check if we're inside unbatchedUpdates
14243 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
14244 (executionContext & (RenderContext | CommitContext)) === NoContext) {
14245 // Register pending interactions on the root to avoid losing traced interaction data.
14246 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
14247 // root inside of batchedUpdates should be synchronous, but layout updates
14248 // should be deferred until the end of the batch.
14249
14250 performSyncWorkOnRoot(root);
14251 } else {
14252 ensureRootIsScheduled(root);
14253 schedulePendingInteractions(root, expirationTime);
14254
14255 if (executionContext === NoContext) {
14256 // Flush the synchronous work now, unless we're already working or inside
14257 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
14258 // scheduleCallbackForFiber to preserve the ability to schedule a callback
14259 // without immediately flushing it. We only do this for user-initiated
14260 // updates, to preserve historical behavior of sync mode.
14261 flushSyncCallbackQueue();
14262 }
14263 }
14264 } else {
14265 ensureRootIsScheduled(root);
14266 schedulePendingInteractions(root, expirationTime);
14267 }
14268
14269 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
14270 // discrete, even inside a discrete event.
14271 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
14272 // This is the result of a discrete event. Track the lowest priority
14273 // discrete update per root so we can flush them early, if needed.
14274 if (rootsWithPendingDiscreteUpdates === null) {
14275 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
14276 } else {
14277 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
14278
14279 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
14280 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
14281 }
14282 }
14283 }
14284}
14285var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
14286// work without treating it as a typical update that originates from an event;
14287// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
14288// on a fiber.
14289
14290function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
14291 // Update the source fiber's expiration time
14292 if (fiber.expirationTime < expirationTime) {
14293 fiber.expirationTime = expirationTime;
14294 }
14295
14296 var alternate = fiber.alternate;
14297
14298 if (alternate !== null && alternate.expirationTime < expirationTime) {
14299 alternate.expirationTime = expirationTime;
14300 } // Walk the parent path to the root and update the child expiration time.
14301
14302
14303 var node = fiber.return;
14304 var root = null;
14305
14306 if (node === null && fiber.tag === HostRoot) {
14307 root = fiber.stateNode;
14308 } else {
14309 while (node !== null) {
14310 alternate = node.alternate;
14311
14312 if (node.childExpirationTime < expirationTime) {
14313 node.childExpirationTime = expirationTime;
14314
14315 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
14316 alternate.childExpirationTime = expirationTime;
14317 }
14318 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
14319 alternate.childExpirationTime = expirationTime;
14320 }
14321
14322 if (node.return === null && node.tag === HostRoot) {
14323 root = node.stateNode;
14324 break;
14325 }
14326
14327 node = node.return;
14328 }
14329 }
14330
14331 if (root !== null) {
14332 if (workInProgressRoot === root) {
14333 // Received an update to a tree that's in the middle of rendering. Mark
14334 // that's unprocessed work on this root.
14335 markUnprocessedUpdateTime(expirationTime);
14336
14337 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
14338 // The root already suspended with a delay, which means this render
14339 // definitely won't finish. Since we have a new update, let's mark it as
14340 // suspended now, right before marking the incoming update. This has the
14341 // effect of interrupting the current render and switching to the update.
14342 // TODO: This happens to work when receiving an update during the render
14343 // phase, because of the trick inside computeExpirationForFiber to
14344 // subtract 1 from `renderExpirationTime` to move it into a
14345 // separate bucket. But we should probably model it with an exception,
14346 // using the same mechanism we use to force hydration of a subtree.
14347 // TODO: This does not account for low pri updates that were already
14348 // scheduled before the root started rendering. Need to track the next
14349 // pending expiration time (perhaps by backtracking the return path) and
14350 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
14351 markRootSuspendedAtTime(root, renderExpirationTime);
14352 }
14353 } // Mark that the root has a pending update.
14354
14355
14356 markRootUpdatedAtTime(root, expirationTime);
14357 }
14358
14359 return root;
14360}
14361
14362function getNextRootExpirationTimeToWorkOn(root) {
14363 // Determines the next expiration time that the root should render, taking
14364 // into account levels that may be suspended, or levels that may have
14365 // received a ping.
14366 var lastExpiredTime = root.lastExpiredTime;
14367
14368 if (lastExpiredTime !== NoWork) {
14369 return lastExpiredTime;
14370 } // "Pending" refers to any update that hasn't committed yet, including if it
14371 // suspended. The "suspended" range is therefore a subset.
14372
14373
14374 var firstPendingTime = root.firstPendingTime;
14375
14376 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
14377 // The highest priority pending time is not suspended. Let's work on that.
14378 return firstPendingTime;
14379 } // If the first pending time is suspended, check if there's a lower priority
14380 // pending level that we know about. Or check if we received a ping. Work
14381 // on whichever is higher priority.
14382
14383
14384 var lastPingedTime = root.lastPingedTime;
14385 var nextKnownPendingLevel = root.nextKnownPendingLevel;
14386 return lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
14387} // Use this function to schedule a task for a root. There's only one task per
14388// root; if a task was already scheduled, we'll check to make sure the
14389// expiration time of the existing task is the same as the expiration time of
14390// the next level that the root has work on. This function is called on every
14391// update, and right before exiting a task.
14392
14393
14394function ensureRootIsScheduled(root) {
14395 var lastExpiredTime = root.lastExpiredTime;
14396
14397 if (lastExpiredTime !== NoWork) {
14398 // Special case: Expired work should flush synchronously.
14399 root.callbackExpirationTime = Sync;
14400 root.callbackPriority = ImmediatePriority;
14401 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
14402 return;
14403 }
14404
14405 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
14406 var existingCallbackNode = root.callbackNode;
14407
14408 if (expirationTime === NoWork) {
14409 // There's nothing to work on.
14410 if (existingCallbackNode !== null) {
14411 root.callbackNode = null;
14412 root.callbackExpirationTime = NoWork;
14413 root.callbackPriority = NoPriority;
14414 }
14415
14416 return;
14417 } // TODO: If this is an update, we already read the current time. Pass the
14418 // time as an argument.
14419
14420
14421 var currentTime = requestCurrentTime();
14422 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
14423 // expiration time. Otherwise, we'll cancel it and schedule a new one.
14424
14425 if (existingCallbackNode !== null) {
14426 var existingCallbackPriority = root.callbackPriority;
14427 var existingCallbackExpirationTime = root.callbackExpirationTime;
14428
14429 if ( // Callback must have the exact same expiration time.
14430 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
14431 existingCallbackPriority >= priorityLevel) {
14432 // Existing callback is sufficient.
14433 return;
14434 } // Need to schedule a new task.
14435 // TODO: Instead of scheduling a new task, we should be able to change the
14436 // priority of the existing one.
14437
14438
14439 cancelCallback(existingCallbackNode);
14440 }
14441
14442 root.callbackExpirationTime = expirationTime;
14443 root.callbackPriority = priorityLevel;
14444 var callbackNode;
14445
14446 if (expirationTime === Sync) {
14447 // Sync React callbacks are scheduled on a special internal queue
14448 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
14449 } else if (disableSchedulerTimeoutBasedOnReactExpirationTime) {
14450 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root));
14451 } else {
14452 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
14453 // ordering because tasks are processed in timeout order.
14454 {
14455 timeout: expirationTimeToMs(expirationTime) - now()
14456 });
14457 }
14458
14459 root.callbackNode = callbackNode;
14460} // This is the entry point for every concurrent task, i.e. anything that
14461// goes through Scheduler.
14462
14463
14464function performConcurrentWorkOnRoot(root, didTimeout) {
14465 // Since we know we're in a React event, we can clear the current
14466 // event time. The next update will compute a new event time.
14467 currentEventTime = NoWork;
14468
14469 if (didTimeout) {
14470 // The render task took too long to complete. Mark the current time as
14471 // expired to synchronously render all expired work in a single batch.
14472 var currentTime = requestCurrentTime();
14473 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
14474
14475 ensureRootIsScheduled(root);
14476 return null;
14477 } // Determine the next expiration time to work on, using the fields stored
14478 // on the root.
14479
14480
14481 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
14482
14483 if (expirationTime !== NoWork) {
14484 var originalCallbackNode = root.callbackNode;
14485
14486 (function () {
14487 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
14488 {
14489 throw ReactError(Error("Should not already be working."));
14490 }
14491 }
14492 })();
14493
14494 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
14495 // and prepare a fresh one. Otherwise we'll continue where we left off.
14496
14497 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
14498 prepareFreshStack(root, expirationTime);
14499 startWorkOnPendingInteractions(root, expirationTime);
14500 } // If we have a work-in-progress fiber, it means there's still work to do
14501 // in this root.
14502
14503
14504 if (workInProgress !== null) {
14505 var prevExecutionContext = executionContext;
14506 executionContext |= RenderContext;
14507 var prevDispatcher = pushDispatcher(root);
14508 var prevInteractions = pushInteractions(root);
14509 startWorkLoopTimer(workInProgress);
14510
14511 do {
14512 try {
14513 workLoopConcurrent();
14514 break;
14515 } catch (thrownValue) {
14516 handleError(root, thrownValue);
14517 }
14518 } while (true);
14519
14520 resetContextDependencies();
14521 executionContext = prevExecutionContext;
14522 popDispatcher(prevDispatcher);
14523
14524 if (enableSchedulerTracing) {
14525 popInteractions(prevInteractions);
14526 }
14527
14528 if (workInProgressRootExitStatus === RootFatalErrored) {
14529 var fatalError = workInProgressRootFatalError;
14530 stopInterruptedWorkLoopTimer();
14531 prepareFreshStack(root, expirationTime);
14532 markRootSuspendedAtTime(root, expirationTime);
14533 ensureRootIsScheduled(root);
14534 throw fatalError;
14535 }
14536
14537 if (workInProgress !== null) {
14538 // There's still work left over. Exit without committing.
14539 stopInterruptedWorkLoopTimer();
14540 } else {
14541 // We now have a consistent tree. The next step is either to commit it,
14542 // or, if something suspended, wait to commit it after a timeout.
14543 stopFinishedWorkLoopTimer();
14544 var finishedWork = root.finishedWork = root.current.alternate;
14545 root.finishedExpirationTime = expirationTime;
14546 resolveLocksOnRoot(root, expirationTime);
14547 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
14548 }
14549
14550 ensureRootIsScheduled(root);
14551
14552 if (root.callbackNode === originalCallbackNode) {
14553 // The task node scheduled for this root is the same one that's
14554 // currently executed. Need to return a continuation.
14555 return performConcurrentWorkOnRoot.bind(null, root);
14556 }
14557 }
14558 }
14559
14560 return null;
14561}
14562
14563function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
14564 // Set this to null to indicate there's no in-progress render.
14565 workInProgressRoot = null;
14566
14567 switch (exitStatus) {
14568 case RootIncomplete:
14569 case RootFatalErrored:
14570 {
14571 (function () {
14572 {
14573 {
14574 throw ReactError(Error("Root did not complete. This is a bug in React."));
14575 }
14576 }
14577 })();
14578 }
14579 // Flow knows about invariant, so it complains if I add a break
14580 // statement, but eslint doesn't know about invariant, so it complains
14581 // if I do. eslint-disable-next-line no-fallthrough
14582
14583 case RootErrored:
14584 {
14585 if (expirationTime !== Idle) {
14586 // If this was an async render, the error may have happened due to
14587 // a mutation in a concurrent event. Try rendering one more time,
14588 // synchronously, to see if the error goes away. If there are
14589 // lower priority updates, let's include those, too, in case they
14590 // fix the inconsistency. Render at Idle to include all updates.
14591 markRootExpiredAtTime(root, Idle);
14592 break;
14593 } // Commit the root in its errored state.
14594
14595
14596 commitRoot(root);
14597 break;
14598 }
14599
14600 case RootSuspended:
14601 {
14602 markRootSuspendedAtTime(root, expirationTime);
14603 var lastSuspendedTime = root.lastSuspendedTime;
14604
14605 if (expirationTime === lastSuspendedTime) {
14606 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
14607 }
14608
14609 flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we
14610 // should immediately commit it or wait a bit.
14611 // If we have processed new updates during this render, we may now
14612 // have a new loading state ready. We want to ensure that we commit
14613 // that as soon as possible.
14614
14615 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
14616
14617 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
14618 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
14619 // If we have not processed any new updates during this pass, then
14620 // this is either a retry of an existing fallback state or a
14621 // hidden tree. Hidden trees shouldn't be batched with other work
14622 // and after that's fixed it can only be a retry. We're going to
14623 // throttle committing retries so that we don't show too many
14624 // loading states too quickly.
14625 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
14626
14627 if (msUntilTimeout > 10) {
14628 if (workInProgressRootHasPendingPing) {
14629 var lastPingedTime = root.lastPingedTime;
14630
14631 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
14632 // This render was pinged but we didn't get to restart
14633 // earlier so try restarting now instead.
14634 root.lastPingedTime = expirationTime;
14635 prepareFreshStack(root, expirationTime);
14636 break;
14637 }
14638 }
14639
14640 var nextTime = getNextRootExpirationTimeToWorkOn(root);
14641
14642 if (nextTime !== NoWork && nextTime !== expirationTime) {
14643 // There's additional work on this root.
14644 break;
14645 }
14646
14647 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
14648 // We should prefer to render the fallback of at the last
14649 // suspended level. Ping the last suspended level to try
14650 // rendering it again.
14651 root.lastPingedTime = lastSuspendedTime;
14652 break;
14653 } // The render is suspended, it hasn't timed out, and there's no
14654 // lower priority work to do. Instead of committing the fallback
14655 // immediately, wait for more data to arrive.
14656
14657
14658 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
14659 break;
14660 }
14661 } // The work expired. Commit immediately.
14662
14663
14664 commitRoot(root);
14665 break;
14666 }
14667
14668 case RootSuspendedWithDelay:
14669 {
14670 markRootSuspendedAtTime(root, expirationTime);
14671 var _lastSuspendedTime = root.lastSuspendedTime;
14672
14673 if (expirationTime === _lastSuspendedTime) {
14674 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
14675 }
14676
14677 flushSuspensePriorityWarningInDEV();
14678
14679 if ( // do not delay if we're inside an act() scope
14680 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
14681 // We're suspended in a state that should be avoided. We'll try to
14682 // avoid committing it for as long as the timeouts let us.
14683 if (workInProgressRootHasPendingPing) {
14684 var _lastPingedTime = root.lastPingedTime;
14685
14686 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
14687 // This render was pinged but we didn't get to restart earlier
14688 // so try restarting now instead.
14689 root.lastPingedTime = expirationTime;
14690 prepareFreshStack(root, expirationTime);
14691 break;
14692 }
14693 }
14694
14695 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
14696
14697 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
14698 // There's additional work on this root.
14699 break;
14700 }
14701
14702 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
14703 // We should prefer to render the fallback of at the last
14704 // suspended level. Ping the last suspended level to try
14705 // rendering it again.
14706 root.lastPingedTime = _lastSuspendedTime;
14707 break;
14708 }
14709
14710 var _msUntilTimeout;
14711
14712 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
14713 // We have processed a suspense config whose expiration time we
14714 // can use as the timeout.
14715 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
14716 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
14717 // This should never normally happen because only new updates
14718 // cause delayed states, so we should have processed something.
14719 // However, this could also happen in an offscreen tree.
14720 _msUntilTimeout = 0;
14721 } else {
14722 // If we don't have a suspense config, we're going to use a
14723 // heuristic to determine how long we can suspend.
14724 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
14725 var currentTimeMs = now();
14726 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
14727 var timeElapsed = currentTimeMs - eventTimeMs;
14728
14729 if (timeElapsed < 0) {
14730 // We get this wrong some time since we estimate the time.
14731 timeElapsed = 0;
14732 }
14733
14734 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
14735 // event time is exact instead of inferred from expiration time
14736 // we don't need this.
14737
14738 if (timeUntilExpirationMs < _msUntilTimeout) {
14739 _msUntilTimeout = timeUntilExpirationMs;
14740 }
14741 } // Don't bother with a very short suspense time.
14742
14743
14744 if (_msUntilTimeout > 10) {
14745 // The render is suspended, it hasn't timed out, and there's no
14746 // lower priority work to do. Instead of committing the fallback
14747 // immediately, wait for more data to arrive.
14748 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
14749 break;
14750 }
14751 } // The work expired. Commit immediately.
14752
14753
14754 commitRoot(root);
14755 break;
14756 }
14757
14758 case RootCompleted:
14759 {
14760 // The work completed. Ready to commit.
14761 if ( // do not delay if we're inside an act() scope
14762 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
14763 // If we have exceeded the minimum loading delay, which probably
14764 // means we have shown a spinner already, we might have to suspend
14765 // a bit longer to ensure that the spinner is shown for
14766 // enough time.
14767 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
14768
14769 if (_msUntilTimeout2 > 10) {
14770 markRootSuspendedAtTime(root, expirationTime);
14771 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
14772 break;
14773 }
14774 }
14775
14776 commitRoot(root);
14777 break;
14778 }
14779
14780 case RootLocked:
14781 {
14782 // This root has a lock that prevents it from committing. Exit. If
14783 // we begin work on the root again, without any intervening updates,
14784 // it will finish without doing additional work.
14785 markRootSuspendedAtTime(root, expirationTime);
14786 break;
14787 }
14788
14789 default:
14790 {
14791 (function () {
14792 {
14793 {
14794 throw ReactError(Error("Unknown root exit status."));
14795 }
14796 }
14797 })();
14798 }
14799 }
14800} // This is the entry point for synchronous tasks that don't go
14801// through Scheduler
14802
14803
14804function performSyncWorkOnRoot(root) {
14805 // Check if there's expired work on this root. Otherwise, render at Sync.
14806 var lastExpiredTime = root.lastExpiredTime;
14807 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
14808
14809 if (root.finishedExpirationTime === expirationTime) {
14810 // There's already a pending commit at this expiration time.
14811 // TODO: This is poorly factored. This case only exists for the
14812 // batch.commit() API.
14813 commitRoot(root);
14814 } else {
14815 (function () {
14816 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
14817 {
14818 throw ReactError(Error("Should not already be working."));
14819 }
14820 }
14821 })();
14822
14823 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
14824 // and prepare a fresh one. Otherwise we'll continue where we left off.
14825
14826 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
14827 prepareFreshStack(root, expirationTime);
14828 startWorkOnPendingInteractions(root, expirationTime);
14829 } // If we have a work-in-progress fiber, it means there's still work to do
14830 // in this root.
14831
14832
14833 if (workInProgress !== null) {
14834 var prevExecutionContext = executionContext;
14835 executionContext |= RenderContext;
14836 var prevDispatcher = pushDispatcher(root);
14837 var prevInteractions = pushInteractions(root);
14838 startWorkLoopTimer(workInProgress);
14839
14840 do {
14841 try {
14842 workLoopSync();
14843 break;
14844 } catch (thrownValue) {
14845 handleError(root, thrownValue);
14846 }
14847 } while (true);
14848
14849 resetContextDependencies();
14850 executionContext = prevExecutionContext;
14851 popDispatcher(prevDispatcher);
14852
14853 if (enableSchedulerTracing) {
14854 popInteractions(prevInteractions);
14855 }
14856
14857 if (workInProgressRootExitStatus === RootFatalErrored) {
14858 var fatalError = workInProgressRootFatalError;
14859 stopInterruptedWorkLoopTimer();
14860 prepareFreshStack(root, expirationTime);
14861 markRootSuspendedAtTime(root, expirationTime);
14862 ensureRootIsScheduled(root);
14863 throw fatalError;
14864 }
14865
14866 if (workInProgress !== null) {
14867 // This is a sync render, so we should have finished the whole tree.
14868 (function () {
14869 {
14870 {
14871 throw ReactError(Error("Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue."));
14872 }
14873 }
14874 })();
14875 } else {
14876 // We now have a consistent tree. Because this is a sync render, we
14877 // will commit it even if something suspended. The only exception is
14878 // if the root is locked (using the unstable_createBatch API).
14879 stopFinishedWorkLoopTimer();
14880 root.finishedWork = root.current.alternate;
14881 root.finishedExpirationTime = expirationTime;
14882 resolveLocksOnRoot(root, expirationTime);
14883 finishSyncRender(root, workInProgressRootExitStatus, expirationTime);
14884 } // Before exiting, make sure there's a callback scheduled for the next
14885 // pending level.
14886
14887
14888 ensureRootIsScheduled(root);
14889 }
14890 }
14891
14892 return null;
14893}
14894
14895function finishSyncRender(root, exitStatus, expirationTime) {
14896 if (exitStatus === RootLocked) {
14897 // This root has a lock that prevents it from committing. Exit. If we
14898 // begin work on the root again, without any intervening updates, it
14899 // will finish without doing additional work.
14900 markRootSuspendedAtTime(root, expirationTime);
14901 } else {
14902 // Set this to null to indicate there's no in-progress render.
14903 workInProgressRoot = null;
14904
14905 {
14906 if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) {
14907 flushSuspensePriorityWarningInDEV();
14908 }
14909 }
14910
14911 commitRoot(root);
14912 }
14913}
14914
14915
14916
14917
14918function resolveLocksOnRoot(root, expirationTime) {
14919 var firstBatch = root.firstBatch;
14920
14921 if (firstBatch !== null && firstBatch._defer && firstBatch._expirationTime >= expirationTime) {
14922 scheduleCallback(NormalPriority, function () {
14923 firstBatch._onComplete();
14924
14925 return null;
14926 });
14927 workInProgressRootExitStatus = RootLocked;
14928 }
14929}
14930
14931
14932
14933
14934
14935
14936
14937
14938function flushSync(fn, a) {
14939 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
14940 (function () {
14941 {
14942 {
14943 throw ReactError(Error("flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering."));
14944 }
14945 }
14946 })();
14947 }
14948
14949 var prevExecutionContext = executionContext;
14950 executionContext |= BatchedContext;
14951
14952 try {
14953 return runWithPriority(ImmediatePriority, fn.bind(null, a));
14954 } finally {
14955 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
14956 // Note that this will happen even if batchedUpdates is higher up
14957 // the stack.
14958
14959 flushSyncCallbackQueue();
14960 }
14961}
14962
14963
14964function prepareFreshStack(root, expirationTime) {
14965 root.finishedWork = null;
14966 root.finishedExpirationTime = NoWork;
14967 var timeoutHandle = root.timeoutHandle;
14968
14969 if (timeoutHandle !== noTimeout) {
14970 // The root previous suspended and scheduled a timeout to commit a fallback
14971 // state. Now that we have additional work, cancel the timeout.
14972 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
14973
14974 cancelTimeout(timeoutHandle);
14975 }
14976
14977 if (workInProgress !== null) {
14978 var interruptedWork = workInProgress.return;
14979
14980 while (interruptedWork !== null) {
14981 unwindInterruptedWork(interruptedWork);
14982 interruptedWork = interruptedWork.return;
14983 }
14984 }
14985
14986 workInProgressRoot = root;
14987 workInProgress = createWorkInProgress(root.current, null, expirationTime);
14988 renderExpirationTime = expirationTime;
14989 workInProgressRootExitStatus = RootIncomplete;
14990 workInProgressRootFatalError = null;
14991 workInProgressRootLatestProcessedExpirationTime = Sync;
14992 workInProgressRootLatestSuspenseTimeout = Sync;
14993 workInProgressRootCanSuspendUsingConfig = null;
14994 workInProgressRootNextUnprocessedUpdateTime = NoWork;
14995 workInProgressRootHasPendingPing = false;
14996
14997 if (enableSchedulerTracing) {
14998 spawnedWorkDuringRender = null;
14999 }
15000
15001 {
15002 ReactStrictModeWarnings.discardPendingWarnings();
15003 componentsThatTriggeredHighPriSuspend = null;
15004 }
15005}
15006
15007function handleError(root, thrownValue) {
15008 do {
15009 try {
15010 // Reset module-level state that was set during the render phase.
15011 resetContextDependencies();
15012 resetHooks();
15013
15014 if (workInProgress === null || workInProgress.return === null) {
15015 // Expected to be working on a non-root fiber. This is a fatal error
15016 // because there's no ancestor that can handle it; the root is
15017 // supposed to capture all errors that weren't caught by an error
15018 // boundary.
15019 workInProgressRootExitStatus = RootFatalErrored;
15020 workInProgressRootFatalError = thrownValue;
15021 return null;
15022 }
15023
15024 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
15025 // Record the time spent rendering before an error was thrown. This
15026 // avoids inaccurate Profiler durations in the case of a
15027 // suspended render.
15028 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
15029 }
15030
15031 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime);
15032 workInProgress = completeUnitOfWork(workInProgress);
15033 } catch (yetAnotherThrownValue) {
15034 // Something in the return path also threw.
15035 thrownValue = yetAnotherThrownValue;
15036 continue;
15037 } // Return to the normal work loop.
15038
15039
15040 return;
15041 } while (true);
15042}
15043
15044function pushDispatcher(root) {
15045 var prevDispatcher = ReactCurrentDispatcher.current;
15046 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
15047
15048 if (prevDispatcher === null) {
15049 // The React isomorphic package does not include a default dispatcher.
15050 // Instead the first renderer will lazily attach one, in order to give
15051 // nicer error messages.
15052 return ContextOnlyDispatcher;
15053 } else {
15054 return prevDispatcher;
15055 }
15056}
15057
15058function popDispatcher(prevDispatcher) {
15059 ReactCurrentDispatcher.current = prevDispatcher;
15060}
15061
15062function pushInteractions(root) {
15063 if (enableSchedulerTracing) {
15064 var prevInteractions = __interactionsRef.current;
15065 __interactionsRef.current = root.memoizedInteractions;
15066 return prevInteractions;
15067 }
15068
15069 return null;
15070}
15071
15072function popInteractions(prevInteractions) {
15073 if (enableSchedulerTracing) {
15074 __interactionsRef.current = prevInteractions;
15075 }
15076}
15077
15078function markCommitTimeOfFallback() {
15079 globalMostRecentFallbackTime = now();
15080}
15081function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
15082 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
15083 workInProgressRootLatestProcessedExpirationTime = expirationTime;
15084 }
15085
15086 if (suspenseConfig !== null) {
15087 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
15088 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
15089
15090 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
15091 }
15092 }
15093}
15094function markUnprocessedUpdateTime(expirationTime) {
15095 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
15096 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
15097 }
15098}
15099function renderDidSuspend() {
15100 if (workInProgressRootExitStatus === RootIncomplete) {
15101 workInProgressRootExitStatus = RootSuspended;
15102 }
15103}
15104function renderDidSuspendDelayIfPossible() {
15105 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
15106 workInProgressRootExitStatus = RootSuspendedWithDelay;
15107 } // Check if there's a lower priority update somewhere else in the tree.
15108
15109
15110 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
15111 // Mark the current render as suspended, and then mark that there's a
15112 // pending update.
15113 // TODO: This should immediately interrupt the current render, instead
15114 // of waiting until the next time we yield.
15115 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime);
15116 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
15117 }
15118}
15119function renderDidError() {
15120 if (workInProgressRootExitStatus !== RootCompleted) {
15121 workInProgressRootExitStatus = RootErrored;
15122 }
15123} // Called during render to determine if anything has suspended.
15124// Returns false if we're not sure.
15125
15126function renderHasNotSuspendedYet() {
15127 // If something errored or completed, we can't really be sure,
15128 // so those are false.
15129 return workInProgressRootExitStatus === RootIncomplete;
15130}
15131
15132function inferTimeFromExpirationTime(expirationTime) {
15133 // We don't know exactly when the update was scheduled, but we can infer an
15134 // approximate start time from the expiration time.
15135 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
15136 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
15137}
15138
15139function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
15140 // We don't know exactly when the update was scheduled, but we can infer an
15141 // approximate start time from the expiration time by subtracting the timeout
15142 // that was added to the event time.
15143 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
15144 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
15145} // The work loop is an extremely hot path. Tell Closure not to inline it.
15146
15147/** @noinline */
15148
15149
15150function workLoopSync() {
15151 // Already timed out, so perform work without checking if we need to yield.
15152 while (workInProgress !== null) {
15153 workInProgress = performUnitOfWork(workInProgress);
15154 }
15155}
15156/** @noinline */
15157
15158
15159function workLoopConcurrent() {
15160 // Perform work until Scheduler asks us to yield
15161 while (workInProgress !== null && !shouldYield()) {
15162 workInProgress = performUnitOfWork(workInProgress);
15163 }
15164}
15165
15166function performUnitOfWork(unitOfWork) {
15167 // The current, flushed, state of this fiber is the alternate. Ideally
15168 // nothing should rely on this, but relying on it here means that we don't
15169 // need an additional field on the work in progress.
15170 var current = unitOfWork.alternate;
15171 startWorkTimer(unitOfWork);
15172 setCurrentFiber(unitOfWork);
15173 var next;
15174
15175 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
15176 startProfilerTimer(unitOfWork);
15177 next = beginWork$$1(current, unitOfWork, renderExpirationTime);
15178 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
15179 } else {
15180 next = beginWork$$1(current, unitOfWork, renderExpirationTime);
15181 }
15182
15183 resetCurrentFiber();
15184 unitOfWork.memoizedProps = unitOfWork.pendingProps;
15185
15186 if (next === null) {
15187 // If this doesn't spawn new work, complete the current work.
15188 next = completeUnitOfWork(unitOfWork);
15189 }
15190
15191 ReactCurrentOwner$1.current = null;
15192 return next;
15193}
15194
15195function completeUnitOfWork(unitOfWork) {
15196 // Attempt to complete the current unit of work, then move to the next
15197 // sibling. If there are no more siblings, return to the parent fiber.
15198 workInProgress = unitOfWork;
15199
15200 do {
15201 // The current, flushed, state of this fiber is the alternate. Ideally
15202 // nothing should rely on this, but relying on it here means that we don't
15203 // need an additional field on the work in progress.
15204 var current = workInProgress.alternate;
15205 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
15206
15207 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
15208 setCurrentFiber(workInProgress);
15209 var next = void 0;
15210
15211 if (!enableProfilerTimer || (workInProgress.mode & ProfileMode) === NoMode) {
15212 next = completeWork(current, workInProgress, renderExpirationTime);
15213 } else {
15214 startProfilerTimer(workInProgress);
15215 next = completeWork(current, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error.
15216
15217 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
15218 }
15219
15220 stopWorkTimer(workInProgress);
15221 resetCurrentFiber();
15222 resetChildExpirationTime(workInProgress);
15223
15224 if (next !== null) {
15225 // Completing this fiber spawned new work. Work on that next.
15226 return next;
15227 }
15228
15229 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
15230 (returnFiber.effectTag & Incomplete) === NoEffect) {
15231 // Append all the effects of the subtree and this fiber onto the effect
15232 // list of the parent. The completion order of the children affects the
15233 // side-effect order.
15234 if (returnFiber.firstEffect === null) {
15235 returnFiber.firstEffect = workInProgress.firstEffect;
15236 }
15237
15238 if (workInProgress.lastEffect !== null) {
15239 if (returnFiber.lastEffect !== null) {
15240 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
15241 }
15242
15243 returnFiber.lastEffect = workInProgress.lastEffect;
15244 } // If this fiber had side-effects, we append it AFTER the children's
15245 // side-effects. We can perform certain side-effects earlier if needed,
15246 // by doing multiple passes over the effect list. We don't want to
15247 // schedule our own side-effect on our own list because if end up
15248 // reusing children we'll schedule this effect onto itself since we're
15249 // at the end.
15250
15251
15252 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
15253 // list. PerformedWork effect is read by React DevTools but shouldn't be
15254 // committed.
15255
15256 if (effectTag > PerformedWork) {
15257 if (returnFiber.lastEffect !== null) {
15258 returnFiber.lastEffect.nextEffect = workInProgress;
15259 } else {
15260 returnFiber.firstEffect = workInProgress;
15261 }
15262
15263 returnFiber.lastEffect = workInProgress;
15264 }
15265 }
15266 } else {
15267 // This fiber did not complete because something threw. Pop values off
15268 // the stack without entering the complete phase. If this is a boundary,
15269 // capture values if possible.
15270 var _next = unwindWork(workInProgress, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time.
15271
15272
15273 if (enableProfilerTimer && (workInProgress.mode & ProfileMode) !== NoMode) {
15274 // Record the render duration for the fiber that errored.
15275 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
15276
15277 var actualDuration = workInProgress.actualDuration;
15278 var child = workInProgress.child;
15279
15280 while (child !== null) {
15281 actualDuration += child.actualDuration;
15282 child = child.sibling;
15283 }
15284
15285 workInProgress.actualDuration = actualDuration;
15286 }
15287
15288 if (_next !== null) {
15289 // If completing this work spawned new work, do that next. We'll come
15290 // back here again.
15291 // Since we're restarting, remove anything that is not a host effect
15292 // from the effect tag.
15293 // TODO: The name stopFailedWorkTimer is misleading because Suspense
15294 // also captures and restarts.
15295 stopFailedWorkTimer(workInProgress);
15296 _next.effectTag &= HostEffectMask;
15297 return _next;
15298 }
15299
15300 stopWorkTimer(workInProgress);
15301
15302 if (returnFiber !== null) {
15303 // Mark the parent fiber as incomplete and clear its effect list.
15304 returnFiber.firstEffect = returnFiber.lastEffect = null;
15305 returnFiber.effectTag |= Incomplete;
15306 }
15307 }
15308
15309 var siblingFiber = workInProgress.sibling;
15310
15311 if (siblingFiber !== null) {
15312 // If there is more work to do in this returnFiber, do that next.
15313 return siblingFiber;
15314 } // Otherwise, return to the parent
15315
15316
15317 workInProgress = returnFiber;
15318 } while (workInProgress !== null); // We've reached the root.
15319
15320
15321 if (workInProgressRootExitStatus === RootIncomplete) {
15322 workInProgressRootExitStatus = RootCompleted;
15323 }
15324
15325 return null;
15326}
15327
15328function getRemainingExpirationTime(fiber) {
15329 var updateExpirationTime = fiber.expirationTime;
15330 var childExpirationTime = fiber.childExpirationTime;
15331 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
15332}
15333
15334function resetChildExpirationTime(completedWork) {
15335 if (renderExpirationTime !== Never && completedWork.childExpirationTime === Never) {
15336 // The children of this component are hidden. Don't bubble their
15337 // expiration times.
15338 return;
15339 }
15340
15341 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
15342
15343 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) {
15344 // In profiling mode, resetChildExpirationTime is also used to reset
15345 // profiler durations.
15346 var actualDuration = completedWork.actualDuration;
15347 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
15348 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
15349 // When work is done, it should bubble to the parent's actualDuration. If
15350 // the fiber has not been cloned though, (meaning no work was done), then
15351 // this value will reflect the amount of time spent working on a previous
15352 // render. In that case it should not bubble. We determine whether it was
15353 // cloned by comparing the child pointer.
15354
15355 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
15356 var child = completedWork.child;
15357
15358 while (child !== null) {
15359 var childUpdateExpirationTime = child.expirationTime;
15360 var childChildExpirationTime = child.childExpirationTime;
15361
15362 if (childUpdateExpirationTime > newChildExpirationTime) {
15363 newChildExpirationTime = childUpdateExpirationTime;
15364 }
15365
15366 if (childChildExpirationTime > newChildExpirationTime) {
15367 newChildExpirationTime = childChildExpirationTime;
15368 }
15369
15370 if (shouldBubbleActualDurations) {
15371 actualDuration += child.actualDuration;
15372 }
15373
15374 treeBaseDuration += child.treeBaseDuration;
15375 child = child.sibling;
15376 }
15377
15378 completedWork.actualDuration = actualDuration;
15379 completedWork.treeBaseDuration = treeBaseDuration;
15380 } else {
15381 var _child = completedWork.child;
15382
15383 while (_child !== null) {
15384 var _childUpdateExpirationTime = _child.expirationTime;
15385 var _childChildExpirationTime = _child.childExpirationTime;
15386
15387 if (_childUpdateExpirationTime > newChildExpirationTime) {
15388 newChildExpirationTime = _childUpdateExpirationTime;
15389 }
15390
15391 if (_childChildExpirationTime > newChildExpirationTime) {
15392 newChildExpirationTime = _childChildExpirationTime;
15393 }
15394
15395 _child = _child.sibling;
15396 }
15397 }
15398
15399 completedWork.childExpirationTime = newChildExpirationTime;
15400}
15401
15402function commitRoot(root) {
15403 var renderPriorityLevel = getCurrentPriorityLevel();
15404 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
15405 return null;
15406}
15407
15408function commitRootImpl(root, renderPriorityLevel) {
15409 flushPassiveEffects();
15410 flushRenderPhaseStrictModeWarningsInDEV();
15411
15412 (function () {
15413 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
15414 {
15415 throw ReactError(Error("Should not already be working."));
15416 }
15417 }
15418 })();
15419
15420 var finishedWork = root.finishedWork;
15421 var expirationTime = root.finishedExpirationTime;
15422
15423 if (finishedWork === null) {
15424 return null;
15425 }
15426
15427 root.finishedWork = null;
15428 root.finishedExpirationTime = NoWork;
15429
15430 (function () {
15431 if (!(finishedWork !== root.current)) {
15432 {
15433 throw ReactError(Error("Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue."));
15434 }
15435 }
15436 })(); // commitRoot never returns a continuation; it always finishes synchronously.
15437 // So we can clear these now to allow a new callback to be scheduled.
15438
15439
15440 root.callbackNode = null;
15441 root.callbackExpirationTime = NoWork;
15442 root.callbackPriority = NoPriority;
15443 root.nextKnownPendingLevel = NoWork;
15444 startCommitTimer(); // Update the first and last pending times on this root. The new first
15445 // pending time is whatever is left on the root fiber.
15446
15447 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
15448 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
15449
15450 if (root === workInProgressRoot) {
15451 // We can reset these now that they are finished.
15452 workInProgressRoot = null;
15453 workInProgress = null;
15454 renderExpirationTime = NoWork;
15455 } else {} // This indicates that the last root we worked on is not the same one that
15456 // we're committing now. This most commonly happens when a suspended root
15457 // times out.
15458 // Get the list of effects.
15459
15460
15461 var firstEffect;
15462
15463 if (finishedWork.effectTag > PerformedWork) {
15464 // A fiber's effect list consists only of its children, not itself. So if
15465 // the root has an effect, we need to add it to the end of the list. The
15466 // resulting list is the set that would belong to the root's parent, if it
15467 // had one; that is, all the effects in the tree including the root.
15468 if (finishedWork.lastEffect !== null) {
15469 finishedWork.lastEffect.nextEffect = finishedWork;
15470 firstEffect = finishedWork.firstEffect;
15471 } else {
15472 firstEffect = finishedWork;
15473 }
15474 } else {
15475 // There is no effect on the root.
15476 firstEffect = finishedWork.firstEffect;
15477 }
15478
15479 if (firstEffect !== null) {
15480 var prevExecutionContext = executionContext;
15481 executionContext |= CommitContext;
15482 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
15483
15484 ReactCurrentOwner$1.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
15485 // of the effect list for each phase: all mutation effects come before all
15486 // layout effects, and so on.
15487 // The first phase a "before mutation" phase. We use this phase to read the
15488 // state of the host tree right before we mutate it. This is where
15489 // getSnapshotBeforeUpdate is called.
15490
15491 startCommitSnapshotEffectsTimer();
15492 prepareForCommit(root.containerInfo);
15493 nextEffect = firstEffect;
15494
15495 do {
15496 {
15497 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
15498
15499 if (hasCaughtError()) {
15500 (function () {
15501 if (!(nextEffect !== null)) {
15502 {
15503 throw ReactError(Error("Should be working on an effect."));
15504 }
15505 }
15506 })();
15507
15508 var error = clearCaughtError();
15509 captureCommitPhaseError(nextEffect, error);
15510 nextEffect = nextEffect.nextEffect;
15511 }
15512 }
15513 } while (nextEffect !== null);
15514
15515 stopCommitSnapshotEffectsTimer();
15516
15517 if (enableProfilerTimer) {
15518 // Mark the current commit time to be shared by all Profilers in this
15519 // batch. This enables them to be grouped later.
15520 recordCommitTime();
15521 } // The next phase is the mutation phase, where we mutate the host tree.
15522
15523
15524 startCommitHostEffectsTimer();
15525 nextEffect = firstEffect;
15526
15527 do {
15528 {
15529 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
15530
15531 if (hasCaughtError()) {
15532 (function () {
15533 if (!(nextEffect !== null)) {
15534 {
15535 throw ReactError(Error("Should be working on an effect."));
15536 }
15537 }
15538 })();
15539
15540 var _error = clearCaughtError();
15541
15542 captureCommitPhaseError(nextEffect, _error);
15543 nextEffect = nextEffect.nextEffect;
15544 }
15545 }
15546 } while (nextEffect !== null);
15547
15548 stopCommitHostEffectsTimer();
15549 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
15550 // the mutation phase, so that the previous tree is still current during
15551 // componentWillUnmount, but before the layout phase, so that the finished
15552 // work is current during componentDidMount/Update.
15553
15554 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
15555 // the host tree after it's been mutated. The idiomatic use case for this is
15556 // layout, but class component lifecycles also fire here for legacy reasons.
15557
15558 startCommitLifeCyclesTimer();
15559 nextEffect = firstEffect;
15560
15561 do {
15562 {
15563 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
15564
15565 if (hasCaughtError()) {
15566 (function () {
15567 if (!(nextEffect !== null)) {
15568 {
15569 throw ReactError(Error("Should be working on an effect."));
15570 }
15571 }
15572 })();
15573
15574 var _error2 = clearCaughtError();
15575
15576 captureCommitPhaseError(nextEffect, _error2);
15577 nextEffect = nextEffect.nextEffect;
15578 }
15579 }
15580 } while (nextEffect !== null);
15581
15582 stopCommitLifeCyclesTimer();
15583 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
15584 // opportunity to paint.
15585
15586 requestPaint();
15587
15588 if (enableSchedulerTracing) {
15589 popInteractions(prevInteractions);
15590 }
15591
15592 executionContext = prevExecutionContext;
15593 } else {
15594 // No effects.
15595 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
15596 // no effects.
15597 // TODO: Maybe there's a better way to report this.
15598
15599 startCommitSnapshotEffectsTimer();
15600 stopCommitSnapshotEffectsTimer();
15601
15602 if (enableProfilerTimer) {
15603 recordCommitTime();
15604 }
15605
15606 startCommitHostEffectsTimer();
15607 stopCommitHostEffectsTimer();
15608 startCommitLifeCyclesTimer();
15609 stopCommitLifeCyclesTimer();
15610 }
15611
15612 stopCommitTimer();
15613 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
15614
15615 if (rootDoesHavePassiveEffects) {
15616 // This commit has passive effects. Stash a reference to them. But don't
15617 // schedule a callback until after flushing layout work.
15618 rootDoesHavePassiveEffects = false;
15619 rootWithPendingPassiveEffects = root;
15620 pendingPassiveEffectsExpirationTime = expirationTime;
15621 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
15622 } else {
15623 // We are done with the effect chain at this point so let's clear the
15624 // nextEffect pointers to assist with GC. If we have passive effects, we'll
15625 // clear this in flushPassiveEffects.
15626 nextEffect = firstEffect;
15627
15628 while (nextEffect !== null) {
15629 var nextNextEffect = nextEffect.nextEffect;
15630 nextEffect.nextEffect = null;
15631 nextEffect = nextNextEffect;
15632 }
15633 } // Check if there's remaining work on this root
15634
15635
15636 var remainingExpirationTime = root.firstPendingTime;
15637
15638 if (remainingExpirationTime !== NoWork) {
15639 if (enableSchedulerTracing) {
15640 if (spawnedWorkDuringRender !== null) {
15641 var expirationTimes = spawnedWorkDuringRender;
15642 spawnedWorkDuringRender = null;
15643
15644 for (var i = 0; i < expirationTimes.length; i++) {
15645 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
15646 }
15647 }
15648
15649 schedulePendingInteractions(root, remainingExpirationTime);
15650 }
15651 } else {
15652 // If there's no remaining work, we can clear the set of already failed
15653 // error boundaries.
15654 legacyErrorBoundariesThatAlreadyFailed = null;
15655 }
15656
15657 if (enableSchedulerTracing) {
15658 if (!rootDidHavePassiveEffects) {
15659 // If there are no passive effects, then we can complete the pending interactions.
15660 // Otherwise, we'll wait until after the passive effects are flushed.
15661 // Wait to do this until after remaining work has been scheduled,
15662 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
15663 finishPendingInteractions(root, expirationTime);
15664 }
15665 }
15666
15667 if (remainingExpirationTime === Sync) {
15668 // Count the number of times the root synchronously re-renders without
15669 // finishing. If there are too many, it indicates an infinite update loop.
15670 if (root === rootWithNestedUpdates) {
15671 nestedUpdateCount++;
15672 } else {
15673 nestedUpdateCount = 0;
15674 rootWithNestedUpdates = root;
15675 }
15676 } else {
15677 nestedUpdateCount = 0;
15678 }
15679
15680 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
15681 // additional work on this root is scheduled.
15682
15683 ensureRootIsScheduled(root);
15684
15685 if (hasUncaughtError) {
15686 hasUncaughtError = false;
15687 var _error3 = firstUncaughtError;
15688 firstUncaughtError = null;
15689 throw _error3;
15690 }
15691
15692 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
15693 // This is a legacy edge case. We just committed the initial mount of
15694 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
15695 // synchronously, but layout updates should be deferred until the end
15696 // of the batch.
15697 return null;
15698 } // If layout work was scheduled, flush it now.
15699
15700
15701 flushSyncCallbackQueue();
15702 return null;
15703}
15704
15705function commitBeforeMutationEffects() {
15706 while (nextEffect !== null) {
15707 var effectTag = nextEffect.effectTag;
15708
15709 if ((effectTag & Snapshot) !== NoEffect) {
15710 setCurrentFiber(nextEffect);
15711 recordEffect();
15712 var current = nextEffect.alternate;
15713 commitBeforeMutationLifeCycles(current, nextEffect);
15714 resetCurrentFiber();
15715 }
15716
15717 if ((effectTag & Passive) !== NoEffect) {
15718 // If there are passive effects, schedule a callback to flush at
15719 // the earliest opportunity.
15720 if (!rootDoesHavePassiveEffects) {
15721 rootDoesHavePassiveEffects = true;
15722 scheduleCallback(NormalPriority, function () {
15723 flushPassiveEffects();
15724 return null;
15725 });
15726 }
15727 }
15728
15729 nextEffect = nextEffect.nextEffect;
15730 }
15731}
15732
15733function commitMutationEffects(root, renderPriorityLevel) {
15734 // TODO: Should probably move the bulk of this function to commitWork.
15735 while (nextEffect !== null) {
15736 setCurrentFiber(nextEffect);
15737 var effectTag = nextEffect.effectTag;
15738
15739 if (effectTag & ContentReset) {
15740 commitResetTextContent(nextEffect);
15741 }
15742
15743 if (effectTag & Ref) {
15744 var current = nextEffect.alternate;
15745
15746 if (current !== null) {
15747 commitDetachRef(current);
15748 }
15749 } // The following switch statement is only concerned about placement,
15750 // updates, and deletions. To avoid needing to add a case for every possible
15751 // bitmap value, we remove the secondary effects from the effect tag and
15752 // switch on that value.
15753
15754
15755 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
15756
15757 switch (primaryEffectTag) {
15758 case Placement:
15759 {
15760 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
15761 // inserted, before any life-cycles like componentDidMount gets called.
15762 // TODO: findDOMNode doesn't rely on this any more but isMounted does
15763 // and isMounted is deprecated anyway so we should be able to kill this.
15764
15765 nextEffect.effectTag &= ~Placement;
15766 break;
15767 }
15768
15769 case PlacementAndUpdate:
15770 {
15771 // Placement
15772 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
15773 // inserted, before any life-cycles like componentDidMount gets called.
15774
15775 nextEffect.effectTag &= ~Placement; // Update
15776
15777 var _current = nextEffect.alternate;
15778 commitWork(_current, nextEffect);
15779 break;
15780 }
15781
15782 case Hydrating:
15783 {
15784 nextEffect.effectTag &= ~Hydrating;
15785 break;
15786 }
15787
15788 case HydratingAndUpdate:
15789 {
15790 nextEffect.effectTag &= ~Hydrating; // Update
15791
15792 var _current2 = nextEffect.alternate;
15793 commitWork(_current2, nextEffect);
15794 break;
15795 }
15796
15797 case Update:
15798 {
15799 var _current3 = nextEffect.alternate;
15800 commitWork(_current3, nextEffect);
15801 break;
15802 }
15803
15804 case Deletion:
15805 {
15806 commitDeletion(root, nextEffect, renderPriorityLevel);
15807 break;
15808 }
15809 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
15810
15811
15812 recordEffect();
15813 resetCurrentFiber();
15814 nextEffect = nextEffect.nextEffect;
15815 }
15816}
15817
15818function commitLayoutEffects(root, committedExpirationTime) {
15819 // TODO: Should probably move the bulk of this function to commitWork.
15820 while (nextEffect !== null) {
15821 setCurrentFiber(nextEffect);
15822 var effectTag = nextEffect.effectTag;
15823
15824 if (effectTag & (Update | Callback)) {
15825 recordEffect();
15826 var current = nextEffect.alternate;
15827 commitLifeCycles(root, current, nextEffect, committedExpirationTime);
15828 }
15829
15830 if (effectTag & Ref) {
15831 recordEffect();
15832 commitAttachRef(nextEffect);
15833 }
15834
15835 resetCurrentFiber();
15836 nextEffect = nextEffect.nextEffect;
15837 }
15838}
15839
15840function flushPassiveEffects() {
15841 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
15842 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
15843 pendingPassiveEffectsRenderPriority = NoPriority;
15844 return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
15845 }
15846}
15847
15848function flushPassiveEffectsImpl() {
15849 if (rootWithPendingPassiveEffects === null) {
15850 return false;
15851 }
15852
15853 var root = rootWithPendingPassiveEffects;
15854 var expirationTime = pendingPassiveEffectsExpirationTime;
15855 rootWithPendingPassiveEffects = null;
15856 pendingPassiveEffectsExpirationTime = NoWork;
15857
15858 (function () {
15859 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
15860 {
15861 throw ReactError(Error("Cannot flush passive effects while already rendering."));
15862 }
15863 }
15864 })();
15865
15866 var prevExecutionContext = executionContext;
15867 executionContext |= CommitContext;
15868 var prevInteractions = pushInteractions(root); // Note: This currently assumes there are no passive effects on the root
15869 // fiber, because the root is not part of its own effect list. This could
15870 // change in the future.
15871
15872 var effect = root.current.firstEffect;
15873
15874 while (effect !== null) {
15875 {
15876 setCurrentFiber(effect);
15877 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
15878
15879 if (hasCaughtError()) {
15880 (function () {
15881 if (!(effect !== null)) {
15882 {
15883 throw ReactError(Error("Should be working on an effect."));
15884 }
15885 }
15886 })();
15887
15888 var error = clearCaughtError();
15889 captureCommitPhaseError(effect, error);
15890 }
15891
15892 resetCurrentFiber();
15893 }
15894
15895 var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC
15896
15897 effect.nextEffect = null;
15898 effect = nextNextEffect;
15899 }
15900
15901 if (enableSchedulerTracing) {
15902 popInteractions(prevInteractions);
15903 finishPendingInteractions(root, expirationTime);
15904 }
15905
15906 executionContext = prevExecutionContext;
15907 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
15908 // exceeds the limit, we'll fire a warning.
15909
15910 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
15911 return true;
15912}
15913
15914function isAlreadyFailedLegacyErrorBoundary(instance) {
15915 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
15916}
15917function markLegacyErrorBoundaryAsFailed(instance) {
15918 if (legacyErrorBoundariesThatAlreadyFailed === null) {
15919 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
15920 } else {
15921 legacyErrorBoundariesThatAlreadyFailed.add(instance);
15922 }
15923}
15924
15925function prepareToThrowUncaughtError(error) {
15926 if (!hasUncaughtError) {
15927 hasUncaughtError = true;
15928 firstUncaughtError = error;
15929 }
15930}
15931
15932var onUncaughtError = prepareToThrowUncaughtError;
15933
15934function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
15935 var errorInfo = createCapturedValue(error, sourceFiber);
15936 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
15937 enqueueUpdate(rootFiber, update);
15938 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
15939
15940 if (root !== null) {
15941 ensureRootIsScheduled(root);
15942 schedulePendingInteractions(root, Sync);
15943 }
15944}
15945
15946function captureCommitPhaseError(sourceFiber, error) {
15947 if (sourceFiber.tag === HostRoot) {
15948 // Error was thrown at the root. There is no parent, so the root
15949 // itself should capture it.
15950 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
15951 return;
15952 }
15953
15954 var fiber = sourceFiber.return;
15955
15956 while (fiber !== null) {
15957 if (fiber.tag === HostRoot) {
15958 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
15959 return;
15960 } else if (fiber.tag === ClassComponent) {
15961 var ctor = fiber.type;
15962 var instance = fiber.stateNode;
15963
15964 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
15965 var errorInfo = createCapturedValue(error, sourceFiber);
15966 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
15967 Sync);
15968 enqueueUpdate(fiber, update);
15969 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
15970
15971 if (root !== null) {
15972 ensureRootIsScheduled(root);
15973 schedulePendingInteractions(root, Sync);
15974 }
15975
15976 return;
15977 }
15978 }
15979
15980 fiber = fiber.return;
15981 }
15982}
15983function pingSuspendedRoot(root, thenable, suspendedTime) {
15984 var pingCache = root.pingCache;
15985
15986 if (pingCache !== null) {
15987 // The thenable resolved, so we no longer need to memoize, because it will
15988 // never be thrown again.
15989 pingCache.delete(thenable);
15990 }
15991
15992 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {
15993 // Received a ping at the same priority level at which we're currently
15994 // rendering. We might want to restart this render. This should mirror
15995 // the logic of whether or not a root suspends once it completes.
15996 // TODO: If we're rendering sync either due to Sync, Batched or expired,
15997 // we should probably never restart.
15998 // If we're suspended with delay, we'll always suspend so we can always
15999 // restart. If we're suspended without any updates, it might be a retry.
16000 // If it's early in the retry we can restart. We can't know for sure
16001 // whether we'll eventually process an update during this render pass,
16002 // but it's somewhat unlikely that we get to a ping before that, since
16003 // getting to the root most update is usually very fast.
16004 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
16005 // Restart from the root. Don't need to schedule a ping because
16006 // we're already working on this tree.
16007 prepareFreshStack(root, renderExpirationTime);
16008 } else {
16009 // Even though we can't restart right now, we might get an
16010 // opportunity later. So we mark this render as having a ping.
16011 workInProgressRootHasPendingPing = true;
16012 }
16013
16014 return;
16015 }
16016
16017 if (!isRootSuspendedAtTime(root, suspendedTime)) {
16018 // The root is no longer suspended at this time.
16019 return;
16020 }
16021
16022 var lastPingedTime = root.lastPingedTime;
16023
16024 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
16025 // There's already a lower priority ping scheduled.
16026 return;
16027 } // Mark the time at which this ping was scheduled.
16028
16029
16030 root.lastPingedTime = suspendedTime;
16031
16032 if (root.finishedExpirationTime === suspendedTime) {
16033 // If there's a pending fallback waiting to commit, throw it away.
16034 root.finishedExpirationTime = NoWork;
16035 root.finishedWork = null;
16036 }
16037
16038 ensureRootIsScheduled(root);
16039 schedulePendingInteractions(root, suspendedTime);
16040}
16041
16042function retryTimedOutBoundary(boundaryFiber, retryTime) {
16043 // The boundary fiber (a Suspense component or SuspenseList component)
16044 // previously was rendered in its fallback state. One of the promises that
16045 // suspended it has resolved, which means at least part of the tree was
16046 // likely unblocked. Try rendering again, at a new expiration time.
16047 if (retryTime === Never) {
16048 var suspenseConfig = null; // Retries don't carry over the already committed update.
16049
16050 var currentTime = requestCurrentTime();
16051 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
16052 } // TODO: Special case idle priority?
16053
16054
16055 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
16056
16057 if (root !== null) {
16058 ensureRootIsScheduled(root);
16059 schedulePendingInteractions(root, retryTime);
16060 }
16061}
16062
16063function retryDehydratedSuspenseBoundary(boundaryFiber) {
16064 var suspenseState = boundaryFiber.memoizedState;
16065 var retryTime = Never;
16066
16067 if (suspenseState !== null) {
16068 retryTime = suspenseState.retryTime;
16069 }
16070
16071 retryTimedOutBoundary(boundaryFiber, retryTime);
16072}
16073function resolveRetryThenable(boundaryFiber, thenable) {
16074 var retryTime = Never; // Default
16075
16076 var retryCache;
16077
16078 if (enableSuspenseServerRenderer) {
16079 switch (boundaryFiber.tag) {
16080 case SuspenseComponent:
16081 retryCache = boundaryFiber.stateNode;
16082 var suspenseState = boundaryFiber.memoizedState;
16083
16084 if (suspenseState !== null) {
16085 retryTime = suspenseState.retryTime;
16086 }
16087
16088 break;
16089
16090 case SuspenseListComponent:
16091 retryCache = boundaryFiber.stateNode;
16092 break;
16093
16094 default:
16095 (function () {
16096 {
16097 {
16098 throw ReactError(Error("Pinged unknown suspense boundary type. This is probably a bug in React."));
16099 }
16100 }
16101 })();
16102
16103 }
16104 } else {
16105 retryCache = boundaryFiber.stateNode;
16106 }
16107
16108 if (retryCache !== null) {
16109 // The thenable resolved, so we no longer need to memoize, because it will
16110 // never be thrown again.
16111 retryCache.delete(thenable);
16112 }
16113
16114 retryTimedOutBoundary(boundaryFiber, retryTime);
16115} // Computes the next Just Noticeable Difference (JND) boundary.
16116// The theory is that a person can't tell the difference between small differences in time.
16117// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
16118// difference in the experience. However, waiting for longer might mean that we can avoid
16119// showing an intermediate loading state. The longer we have already waited, the harder it
16120// is to tell small differences in time. Therefore, the longer we've already waited,
16121// the longer we can wait additionally. At some point we have to give up though.
16122// We pick a train model where the next boundary commits at a consistent schedule.
16123// These particular numbers are vague estimates. We expect to adjust them based on research.
16124
16125function jnd(timeElapsed) {
16126 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
16127}
16128
16129function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
16130 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
16131
16132 if (busyMinDurationMs <= 0) {
16133 return 0;
16134 }
16135
16136 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
16137
16138 var currentTimeMs = now();
16139 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
16140 var timeElapsed = currentTimeMs - eventTimeMs;
16141
16142 if (timeElapsed <= busyDelayMs) {
16143 // If we haven't yet waited longer than the initial delay, we don't
16144 // have to wait any additional time.
16145 return 0;
16146 }
16147
16148 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
16149
16150 return msUntilTimeout;
16151}
16152
16153function checkForNestedUpdates() {
16154 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
16155 nestedUpdateCount = 0;
16156 rootWithNestedUpdates = null;
16157
16158 (function () {
16159 {
16160 {
16161 throw ReactError(Error("Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops."));
16162 }
16163 }
16164 })();
16165 }
16166
16167 {
16168 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
16169 nestedPassiveUpdateCount = 0;
16170 warning$1(false, 'Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
16171 }
16172 }
16173}
16174
16175function flushRenderPhaseStrictModeWarningsInDEV() {
16176 {
16177 ReactStrictModeWarnings.flushLegacyContextWarning();
16178
16179 if (warnAboutDeprecatedLifecycles) {
16180 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
16181 }
16182 }
16183}
16184
16185function stopFinishedWorkLoopTimer() {
16186 var didCompleteRoot = true;
16187 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
16188 interruptedBy = null;
16189}
16190
16191function stopInterruptedWorkLoopTimer() {
16192 // TODO: Track which fiber caused the interruption.
16193 var didCompleteRoot = false;
16194 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
16195 interruptedBy = null;
16196}
16197
16198function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
16199 if (enableUserTimingAPI && workInProgressRoot !== null && updateExpirationTime > renderExpirationTime) {
16200 interruptedBy = fiberThatReceivedUpdate;
16201 }
16202}
16203
16204var didWarnStateUpdateForUnmountedComponent = null;
16205
16206function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
16207 {
16208 var tag = fiber.tag;
16209
16210 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
16211 // Only warn for user-defined components, not internal ones like Suspense.
16212 return;
16213 } // We show the whole stack but dedupe on the top component's name because
16214 // the problematic code almost always lies inside that component.
16215
16216
16217 var componentName = getComponentName(fiber.type) || 'ReactComponent';
16218
16219 if (didWarnStateUpdateForUnmountedComponent !== null) {
16220 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
16221 return;
16222 }
16223
16224 didWarnStateUpdateForUnmountedComponent.add(componentName);
16225 } else {
16226 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
16227 }
16228
16229 warningWithoutStack$1(false, "Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
16230 }
16231}
16232
16233var beginWork$$1;
16234
16235if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
16236 var dummyFiber = null;
16237
16238 beginWork$$1 = function (current, unitOfWork, expirationTime) {
16239 // If a component throws an error, we replay it again in a synchronously
16240 // dispatched event, so that the debugger will treat it as an uncaught
16241 // error See ReactErrorUtils for more information.
16242 // Before entering the begin phase, copy the work-in-progress onto a dummy
16243 // fiber. If beginWork throws, we'll use this to reset the state.
16244 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
16245
16246 try {
16247 return beginWork$1(current, unitOfWork, expirationTime);
16248 } catch (originalError) {
16249 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
16250 // Don't replay promises. Treat everything else like an error.
16251 throw originalError;
16252 } // Keep this code in sync with renderRoot; any changes here must have
16253 // corresponding changes there.
16254
16255
16256 resetContextDependencies();
16257 resetHooks(); // Unwind the failed stack frame
16258
16259 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
16260
16261 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
16262
16263 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {
16264 // Reset the profiler timer.
16265 startProfilerTimer(unitOfWork);
16266 } // Run beginWork again.
16267
16268
16269 invokeGuardedCallback(null, beginWork$1, null, current, unitOfWork, expirationTime);
16270
16271 if (hasCaughtError()) {
16272 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
16273 // Rethrow this error instead of the original one.
16274
16275 throw replayError;
16276 } else {
16277 // This branch is reachable if the render phase is impure.
16278 throw originalError;
16279 }
16280 }
16281 };
16282} else {
16283 beginWork$$1 = beginWork$1;
16284}
16285
16286var didWarnAboutUpdateInRender = false;
16287var didWarnAboutUpdateInGetChildContext = false;
16288
16289function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
16290 {
16291 if (fiber.tag === ClassComponent) {
16292 switch (phase) {
16293 case 'getChildContext':
16294 if (didWarnAboutUpdateInGetChildContext) {
16295 return;
16296 }
16297
16298 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
16299 didWarnAboutUpdateInGetChildContext = true;
16300 break;
16301
16302 case 'render':
16303 if (didWarnAboutUpdateInRender) {
16304 return;
16305 }
16306
16307 warningWithoutStack$1(false, 'Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure function of ' + 'props and state.');
16308 didWarnAboutUpdateInRender = true;
16309 break;
16310 }
16311 }
16312 }
16313} // a 'shared' variable that changes when act() opens/closes in tests.
16314
16315
16316var IsThisRendererActing = {
16317 current: false
16318};
16319function warnIfNotScopedWithMatchingAct(fiber) {
16320 {
16321 if (warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
16322 warningWithoutStack$1(false, "It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + "import {act} from 'react-dom/test-utils';\n" + '// ...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + "import TestRenderer from 'react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '// ...\n' + 'act(() => ...);' + '%s', getStackByFiberInDevAndProd(fiber));
16323 }
16324 }
16325}
16326function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
16327 {
16328 if (warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
16329 warningWithoutStack$1(false, 'An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
16330 }
16331 }
16332}
16333
16334function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
16335 {
16336 if (warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
16337 warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
16338 }
16339 }
16340}
16341
16342var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
16343
16344var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
16345// scheduler is the actual recommendation. The alternative could be a testing build,
16346// a new lib, or whatever; we dunno just yet. This message is for early adopters
16347// to get their tests right.
16348
16349function warnIfUnmockedScheduler(fiber) {
16350 {
16351 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
16352 if (fiber.mode & BatchedMode || fiber.mode & ConcurrentMode) {
16353 didWarnAboutUnmockedScheduler = true;
16354 warningWithoutStack$1(false, 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
16355 } else if (warnAboutUnmockedScheduler === true) {
16356 didWarnAboutUnmockedScheduler = true;
16357 warningWithoutStack$1(false, 'Starting from React v17, the "scheduler" module will need to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
16358 }
16359 }
16360 }
16361}
16362var componentsThatTriggeredHighPriSuspend = null;
16363function checkForWrongSuspensePriorityInDEV(sourceFiber) {
16364 {
16365 var currentPriorityLevel = getCurrentPriorityLevel();
16366
16367 if ((sourceFiber.mode & ConcurrentMode) !== NoEffect && (currentPriorityLevel === UserBlockingPriority || currentPriorityLevel === ImmediatePriority)) {
16368 var workInProgressNode = sourceFiber;
16369
16370 while (workInProgressNode !== null) {
16371 // Add the component that triggered the suspense
16372 var current = workInProgressNode.alternate;
16373
16374 if (current !== null) {
16375 // TODO: warn component that triggers the high priority
16376 // suspend is the HostRoot
16377 switch (workInProgressNode.tag) {
16378 case ClassComponent:
16379 // Loop through the component's update queue and see whether the component
16380 // has triggered any high priority updates
16381 var updateQueue = current.updateQueue;
16382
16383 if (updateQueue !== null) {
16384 var update = updateQueue.firstUpdate;
16385
16386 while (update !== null) {
16387 var priorityLevel = update.priority;
16388
16389 if (priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority) {
16390 if (componentsThatTriggeredHighPriSuspend === null) {
16391 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
16392 } else {
16393 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
16394 }
16395
16396 break;
16397 }
16398
16399 update = update.next;
16400 }
16401 }
16402
16403 break;
16404
16405 case FunctionComponent:
16406 case ForwardRef:
16407 case SimpleMemoComponent:
16408 if (workInProgressNode.memoizedState !== null && workInProgressNode.memoizedState.baseUpdate !== null) {
16409 var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether
16410 // the component has triggered any high pri updates
16411
16412 while (_update !== null) {
16413 var priority = _update.priority;
16414
16415 if (priority === UserBlockingPriority || priority === ImmediatePriority) {
16416 if (componentsThatTriggeredHighPriSuspend === null) {
16417 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
16418 } else {
16419 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
16420 }
16421
16422 break;
16423 }
16424
16425 if (_update.next === workInProgressNode.memoizedState.baseUpdate) {
16426 break;
16427 }
16428
16429 _update = _update.next;
16430 }
16431 }
16432
16433 break;
16434
16435 default:
16436 break;
16437 }
16438 }
16439
16440 workInProgressNode = workInProgressNode.return;
16441 }
16442 }
16443 }
16444}
16445
16446function flushSuspensePriorityWarningInDEV() {
16447 {
16448 if (componentsThatTriggeredHighPriSuspend !== null) {
16449 var componentNames = [];
16450 componentsThatTriggeredHighPriSuspend.forEach(function (name) {
16451 return componentNames.push(name);
16452 });
16453 componentsThatTriggeredHighPriSuspend = null;
16454
16455 if (componentNames.length > 0) {
16456 warningWithoutStack$1(false, '%s triggered a user-blocking update that suspended.' + '\n\n' + 'The fix is to split the update into multiple parts: a user-blocking ' + 'update to provide immediate feedback, and another update that ' + 'triggers the bulk of the changes.' + '\n\n' + 'Refer to the documentation for useSuspenseTransition to learn how ' + 'to implement this pattern.', // TODO: Add link to React docs with more information, once it exists
16457 componentNames.sort().join(', '));
16458 }
16459 }
16460 }
16461}
16462
16463function computeThreadID(root, expirationTime) {
16464 // Interaction threads are unique per root and expiration time.
16465 return expirationTime * 1000 + root.interactionThreadID;
16466}
16467
16468function markSpawnedWork(expirationTime) {
16469 if (!enableSchedulerTracing) {
16470 return;
16471 }
16472
16473 if (spawnedWorkDuringRender === null) {
16474 spawnedWorkDuringRender = [expirationTime];
16475 } else {
16476 spawnedWorkDuringRender.push(expirationTime);
16477 }
16478}
16479
16480function scheduleInteractions(root, expirationTime, interactions) {
16481 if (!enableSchedulerTracing) {
16482 return;
16483 }
16484
16485 if (interactions.size > 0) {
16486 var pendingInteractionMap = root.pendingInteractionMap;
16487 var pendingInteractions = pendingInteractionMap.get(expirationTime);
16488
16489 if (pendingInteractions != null) {
16490 interactions.forEach(function (interaction) {
16491 if (!pendingInteractions.has(interaction)) {
16492 // Update the pending async work count for previously unscheduled interaction.
16493 interaction.__count++;
16494 }
16495
16496 pendingInteractions.add(interaction);
16497 });
16498 } else {
16499 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
16500
16501 interactions.forEach(function (interaction) {
16502 interaction.__count++;
16503 });
16504 }
16505
16506 var subscriber = __subscriberRef.current;
16507
16508 if (subscriber !== null) {
16509 var threadID = computeThreadID(root, expirationTime);
16510 subscriber.onWorkScheduled(interactions, threadID);
16511 }
16512 }
16513}
16514
16515function schedulePendingInteractions(root, expirationTime) {
16516 // This is called when work is scheduled on a root.
16517 // It associates the current interactions with the newly-scheduled expiration.
16518 // They will be restored when that expiration is later committed.
16519 if (!enableSchedulerTracing) {
16520 return;
16521 }
16522
16523 scheduleInteractions(root, expirationTime, __interactionsRef.current);
16524}
16525
16526function startWorkOnPendingInteractions(root, expirationTime) {
16527 // This is called when new work is started on a root.
16528 if (!enableSchedulerTracing) {
16529 return;
16530 } // Determine which interactions this batch of work currently includes, So that
16531 // we can accurately attribute time spent working on it, And so that cascading
16532 // work triggered during the render phase will be associated with it.
16533
16534
16535 var interactions = new Set();
16536 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
16537 if (scheduledExpirationTime >= expirationTime) {
16538 scheduledInteractions.forEach(function (interaction) {
16539 return interactions.add(interaction);
16540 });
16541 }
16542 }); // Store the current set of interactions on the FiberRoot for a few reasons:
16543 // We can re-use it in hot functions like renderRoot() without having to
16544 // recalculate it. We will also use it in commitWork() to pass to any Profiler
16545 // onRender() hooks. This also provides DevTools with a way to access it when
16546 // the onCommitRoot() hook is called.
16547
16548 root.memoizedInteractions = interactions;
16549
16550 if (interactions.size > 0) {
16551 var subscriber = __subscriberRef.current;
16552
16553 if (subscriber !== null) {
16554 var threadID = computeThreadID(root, expirationTime);
16555
16556 try {
16557 subscriber.onWorkStarted(interactions, threadID);
16558 } catch (error) {
16559 // If the subscriber throws, rethrow it in a separate task
16560 scheduleCallback(ImmediatePriority, function () {
16561 throw error;
16562 });
16563 }
16564 }
16565 }
16566}
16567
16568function finishPendingInteractions(root, committedExpirationTime) {
16569 if (!enableSchedulerTracing) {
16570 return;
16571 }
16572
16573 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
16574 var subscriber;
16575
16576 try {
16577 subscriber = __subscriberRef.current;
16578
16579 if (subscriber !== null && root.memoizedInteractions.size > 0) {
16580 var threadID = computeThreadID(root, committedExpirationTime);
16581 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
16582 }
16583 } catch (error) {
16584 // If the subscriber throws, rethrow it in a separate task
16585 scheduleCallback(ImmediatePriority, function () {
16586 throw error;
16587 });
16588 } finally {
16589 // Clear completed interactions from the pending Map.
16590 // Unless the render was suspended or cascading work was scheduled,
16591 // In which case– leave pending interactions until the subsequent render.
16592 var pendingInteractionMap = root.pendingInteractionMap;
16593 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
16594 // Only decrement the pending interaction count if we're done.
16595 // If there's still work at the current priority,
16596 // That indicates that we are waiting for suspense data.
16597 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
16598 pendingInteractionMap.delete(scheduledExpirationTime);
16599 scheduledInteractions.forEach(function (interaction) {
16600 interaction.__count--;
16601
16602 if (subscriber !== null && interaction.__count === 0) {
16603 try {
16604 subscriber.onInteractionScheduledWorkCompleted(interaction);
16605 } catch (error) {
16606 // If the subscriber throws, rethrow it in a separate task
16607 scheduleCallback(ImmediatePriority, function () {
16608 throw error;
16609 });
16610 }
16611 }
16612 });
16613 }
16614 });
16615 }
16616}
16617
16618var onCommitFiberRoot = null;
16619var onCommitFiberUnmount = null;
16620var hasLoggedError = false;
16621var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
16622function injectInternals(internals) {
16623 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
16624 // No DevTools
16625 return false;
16626 }
16627
16628 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
16629
16630 if (hook.isDisabled) {
16631 // This isn't a real property on the hook, but it can be set to opt out
16632 // of DevTools integration and associated warnings and logs.
16633 // https://github.com/facebook/react/issues/3877
16634 return true;
16635 }
16636
16637 if (!hook.supportsFiber) {
16638 {
16639 warningWithoutStack$1(false, 'The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools');
16640 } // DevTools exists, even though it doesn't support Fiber.
16641
16642
16643 return true;
16644 }
16645
16646 try {
16647 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
16648
16649 onCommitFiberRoot = function (root, expirationTime) {
16650 try {
16651 var didError = (root.current.effectTag & DidCapture) === DidCapture;
16652
16653 if (enableProfilerTimer) {
16654 var currentTime = requestCurrentTime();
16655 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
16656 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
16657 } else {
16658 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
16659 }
16660 } catch (err) {
16661 if (true && !hasLoggedError) {
16662 hasLoggedError = true;
16663 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
16664 }
16665 }
16666 };
16667
16668 onCommitFiberUnmount = function (fiber) {
16669 try {
16670 hook.onCommitFiberUnmount(rendererID, fiber);
16671 } catch (err) {
16672 if (true && !hasLoggedError) {
16673 hasLoggedError = true;
16674 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
16675 }
16676 }
16677 };
16678 } catch (err) {
16679 // Catch all errors because it is unsafe to throw during initialization.
16680 {
16681 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
16682 }
16683 } // DevTools exists
16684
16685
16686 return true;
16687}
16688function onCommitRoot(root, expirationTime) {
16689 if (typeof onCommitFiberRoot === 'function') {
16690 onCommitFiberRoot(root, expirationTime);
16691 }
16692}
16693function onCommitUnmount(fiber) {
16694 if (typeof onCommitFiberUnmount === 'function') {
16695 onCommitFiberUnmount(fiber);
16696 }
16697}
16698
16699var hasBadMapPolyfill;
16700
16701{
16702 hasBadMapPolyfill = false;
16703
16704 try {
16705 var nonExtensibleObject = Object.preventExtensions({});
16706 var testMap = new Map([[nonExtensibleObject, null]]);
16707 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
16708 // https://github.com/rollup/rollup/issues/1771
16709 // TODO: we can remove these if Rollup fixes the bug.
16710
16711 testMap.set(0, 0);
16712 testSet.add(0);
16713 } catch (e) {
16714 // TODO: Consider warning about bad polyfills
16715 hasBadMapPolyfill = true;
16716 }
16717}
16718
16719var debugCounter = 1;
16720
16721function FiberNode(tag, pendingProps, key, mode) {
16722 // Instance
16723 this.tag = tag;
16724 this.key = key;
16725 this.elementType = null;
16726 this.type = null;
16727 this.stateNode = null; // Fiber
16728
16729 this.return = null;
16730 this.child = null;
16731 this.sibling = null;
16732 this.index = 0;
16733 this.ref = null;
16734 this.pendingProps = pendingProps;
16735 this.memoizedProps = null;
16736 this.updateQueue = null;
16737 this.memoizedState = null;
16738 this.dependencies = null;
16739 this.mode = mode; // Effects
16740
16741 this.effectTag = NoEffect;
16742 this.nextEffect = null;
16743 this.firstEffect = null;
16744 this.lastEffect = null;
16745 this.expirationTime = NoWork;
16746 this.childExpirationTime = NoWork;
16747 this.alternate = null;
16748
16749 if (enableProfilerTimer) {
16750 // Note: The following is done to avoid a v8 performance cliff.
16751 //
16752 // Initializing the fields below to smis and later updating them with
16753 // double values will cause Fibers to end up having separate shapes.
16754 // This behavior/bug has something to do with Object.preventExtension().
16755 // Fortunately this only impacts DEV builds.
16756 // Unfortunately it makes React unusably slow for some applications.
16757 // To work around this, initialize the fields below with doubles.
16758 //
16759 // Learn more about this here:
16760 // https://github.com/facebook/react/issues/14365
16761 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
16762 this.actualDuration = Number.NaN;
16763 this.actualStartTime = Number.NaN;
16764 this.selfBaseDuration = Number.NaN;
16765 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
16766 // This won't trigger the performance cliff mentioned above,
16767 // and it simplifies other profiler code (including DevTools).
16768
16769 this.actualDuration = 0;
16770 this.actualStartTime = -1;
16771 this.selfBaseDuration = 0;
16772 this.treeBaseDuration = 0;
16773 } // This is normally DEV-only except www when it adds listeners.
16774 // TODO: remove the User Timing integration in favor of Root Events.
16775
16776
16777 if (enableUserTimingAPI) {
16778 this._debugID = debugCounter++;
16779 this._debugIsCurrentlyTiming = false;
16780 }
16781
16782 {
16783 this._debugSource = null;
16784 this._debugOwner = null;
16785 this._debugNeedsRemount = false;
16786 this._debugHookTypes = null;
16787
16788 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
16789 Object.preventExtensions(this);
16790 }
16791 }
16792} // This is a constructor function, rather than a POJO constructor, still
16793// please ensure we do the following:
16794// 1) Nobody should add any instance methods on this. Instance methods can be
16795// more difficult to predict when they get optimized and they are almost
16796// never inlined properly in static compilers.
16797// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
16798// always know when it is a fiber.
16799// 3) We might want to experiment with using numeric keys since they are easier
16800// to optimize in a non-JIT environment.
16801// 4) We can easily go from a constructor to a createFiber object literal if that
16802// is faster.
16803// 5) It should be easy to port this to a C struct and keep a C implementation
16804// compatible.
16805
16806
16807var createFiber = function (tag, pendingProps, key, mode) {
16808 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
16809 return new FiberNode(tag, pendingProps, key, mode);
16810};
16811
16812function shouldConstruct(Component) {
16813 var prototype = Component.prototype;
16814 return !!(prototype && prototype.isReactComponent);
16815}
16816
16817function isSimpleFunctionComponent(type) {
16818 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
16819}
16820function resolveLazyComponentTag(Component) {
16821 if (typeof Component === 'function') {
16822 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
16823 } else if (Component !== undefined && Component !== null) {
16824 var $$typeof = Component.$$typeof;
16825
16826 if ($$typeof === REACT_FORWARD_REF_TYPE) {
16827 return ForwardRef;
16828 }
16829
16830 if ($$typeof === REACT_MEMO_TYPE) {
16831 return MemoComponent;
16832 }
16833 }
16834
16835 return IndeterminateComponent;
16836} // This is used to create an alternate fiber to do work on.
16837
16838function createWorkInProgress(current, pendingProps, expirationTime) {
16839 var workInProgress = current.alternate;
16840
16841 if (workInProgress === null) {
16842 // We use a double buffering pooling technique because we know that we'll
16843 // only ever need at most two versions of a tree. We pool the "other" unused
16844 // node that we're free to reuse. This is lazily created to avoid allocating
16845 // extra objects for things that are never updated. It also allow us to
16846 // reclaim the extra memory if needed.
16847 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
16848 workInProgress.elementType = current.elementType;
16849 workInProgress.type = current.type;
16850 workInProgress.stateNode = current.stateNode;
16851
16852 {
16853 // DEV-only fields
16854 workInProgress._debugID = current._debugID;
16855 workInProgress._debugSource = current._debugSource;
16856 workInProgress._debugOwner = current._debugOwner;
16857 workInProgress._debugHookTypes = current._debugHookTypes;
16858 }
16859
16860 workInProgress.alternate = current;
16861 current.alternate = workInProgress;
16862 } else {
16863 workInProgress.pendingProps = pendingProps; // We already have an alternate.
16864 // Reset the effect tag.
16865
16866 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
16867
16868 workInProgress.nextEffect = null;
16869 workInProgress.firstEffect = null;
16870 workInProgress.lastEffect = null;
16871
16872 if (enableProfilerTimer) {
16873 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
16874 // This prevents time from endlessly accumulating in new commits.
16875 // This has the downside of resetting values for different priority renders,
16876 // But works for yielding (the common case) and should support resuming.
16877 workInProgress.actualDuration = 0;
16878 workInProgress.actualStartTime = -1;
16879 }
16880 }
16881
16882 workInProgress.childExpirationTime = current.childExpirationTime;
16883 workInProgress.expirationTime = current.expirationTime;
16884 workInProgress.child = current.child;
16885 workInProgress.memoizedProps = current.memoizedProps;
16886 workInProgress.memoizedState = current.memoizedState;
16887 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
16888 // it cannot be shared with the current fiber.
16889
16890 var currentDependencies = current.dependencies;
16891 workInProgress.dependencies = currentDependencies === null ? null : {
16892 expirationTime: currentDependencies.expirationTime,
16893 firstContext: currentDependencies.firstContext,
16894 responders: currentDependencies.responders
16895 }; // These will be overridden during the parent's reconciliation
16896
16897 workInProgress.sibling = current.sibling;
16898 workInProgress.index = current.index;
16899 workInProgress.ref = current.ref;
16900
16901 if (enableProfilerTimer) {
16902 workInProgress.selfBaseDuration = current.selfBaseDuration;
16903 workInProgress.treeBaseDuration = current.treeBaseDuration;
16904 }
16905
16906 {
16907 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
16908
16909 switch (workInProgress.tag) {
16910 case IndeterminateComponent:
16911 case FunctionComponent:
16912 case SimpleMemoComponent:
16913 workInProgress.type = resolveFunctionForHotReloading(current.type);
16914 break;
16915
16916 case ClassComponent:
16917 workInProgress.type = resolveClassForHotReloading(current.type);
16918 break;
16919
16920 case ForwardRef:
16921 workInProgress.type = resolveForwardRefForHotReloading(current.type);
16922 break;
16923
16924 default:
16925 break;
16926 }
16927 }
16928
16929 return workInProgress;
16930} // Used to reuse a Fiber for a second pass.
16931
16932function resetWorkInProgress(workInProgress, renderExpirationTime) {
16933 // This resets the Fiber to what createFiber or createWorkInProgress would
16934 // have set the values to before during the first pass. Ideally this wouldn't
16935 // be necessary but unfortunately many code paths reads from the workInProgress
16936 // when they should be reading from current and writing to workInProgress.
16937 // We assume pendingProps, index, key, ref, return are still untouched to
16938 // avoid doing another reconciliation.
16939 // Reset the effect tag but keep any Placement tags, since that's something
16940 // that child fiber is setting, not the reconciliation.
16941 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
16942
16943 workInProgress.nextEffect = null;
16944 workInProgress.firstEffect = null;
16945 workInProgress.lastEffect = null;
16946 var current = workInProgress.alternate;
16947
16948 if (current === null) {
16949 // Reset to createFiber's initial values.
16950 workInProgress.childExpirationTime = NoWork;
16951 workInProgress.expirationTime = renderExpirationTime;
16952 workInProgress.child = null;
16953 workInProgress.memoizedProps = null;
16954 workInProgress.memoizedState = null;
16955 workInProgress.updateQueue = null;
16956 workInProgress.dependencies = null;
16957
16958 if (enableProfilerTimer) {
16959 // Note: We don't reset the actualTime counts. It's useful to accumulate
16960 // actual time across multiple render passes.
16961 workInProgress.selfBaseDuration = 0;
16962 workInProgress.treeBaseDuration = 0;
16963 }
16964 } else {
16965 // Reset to the cloned values that createWorkInProgress would've.
16966 workInProgress.childExpirationTime = current.childExpirationTime;
16967 workInProgress.expirationTime = current.expirationTime;
16968 workInProgress.child = current.child;
16969 workInProgress.memoizedProps = current.memoizedProps;
16970 workInProgress.memoizedState = current.memoizedState;
16971 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
16972 // it cannot be shared with the current fiber.
16973
16974 var currentDependencies = current.dependencies;
16975 workInProgress.dependencies = currentDependencies === null ? null : {
16976 expirationTime: currentDependencies.expirationTime,
16977 firstContext: currentDependencies.firstContext,
16978 responders: currentDependencies.responders
16979 };
16980
16981 if (enableProfilerTimer) {
16982 // Note: We don't reset the actualTime counts. It's useful to accumulate
16983 // actual time across multiple render passes.
16984 workInProgress.selfBaseDuration = current.selfBaseDuration;
16985 workInProgress.treeBaseDuration = current.treeBaseDuration;
16986 }
16987 }
16988
16989 return workInProgress;
16990}
16991function createHostRootFiber(tag) {
16992 var mode;
16993
16994 if (tag === ConcurrentRoot) {
16995 mode = ConcurrentMode | BatchedMode | StrictMode;
16996 } else if (tag === BatchedRoot) {
16997 mode = BatchedMode | StrictMode;
16998 } else {
16999 mode = NoMode;
17000 }
17001
17002 if (enableProfilerTimer && isDevToolsPresent) {
17003 // Always collect profile timings when DevTools are present.
17004 // This enables DevTools to start capturing timing at any point–
17005 // Without some nodes in the tree having empty base times.
17006 mode |= ProfileMode;
17007 }
17008
17009 return createFiber(HostRoot, null, null, mode);
17010}
17011function createFiberFromTypeAndProps(type, // React$ElementType
17012key, pendingProps, owner, mode, expirationTime) {
17013 var fiber;
17014 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
17015
17016 var resolvedType = type;
17017
17018 if (typeof type === 'function') {
17019 if (shouldConstruct(type)) {
17020 fiberTag = ClassComponent;
17021
17022 {
17023 resolvedType = resolveClassForHotReloading(resolvedType);
17024 }
17025 } else {
17026 {
17027 resolvedType = resolveFunctionForHotReloading(resolvedType);
17028 }
17029 }
17030 } else if (typeof type === 'string') {
17031 fiberTag = HostComponent;
17032 } else {
17033 getTag: switch (type) {
17034 case REACT_FRAGMENT_TYPE:
17035 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
17036
17037 case REACT_CONCURRENT_MODE_TYPE:
17038 fiberTag = Mode;
17039 mode |= ConcurrentMode | BatchedMode | StrictMode;
17040 break;
17041
17042 case REACT_STRICT_MODE_TYPE:
17043 fiberTag = Mode;
17044 mode |= StrictMode;
17045 break;
17046
17047 case REACT_PROFILER_TYPE:
17048 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
17049
17050 case REACT_SUSPENSE_TYPE:
17051 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
17052
17053 case REACT_SUSPENSE_LIST_TYPE:
17054 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
17055
17056 default:
17057 {
17058 if (typeof type === 'object' && type !== null) {
17059 switch (type.$$typeof) {
17060 case REACT_PROVIDER_TYPE:
17061 fiberTag = ContextProvider;
17062 break getTag;
17063
17064 case REACT_CONTEXT_TYPE:
17065 // This is a consumer
17066 fiberTag = ContextConsumer;
17067 break getTag;
17068
17069 case REACT_FORWARD_REF_TYPE:
17070 fiberTag = ForwardRef;
17071
17072 {
17073 resolvedType = resolveForwardRefForHotReloading(resolvedType);
17074 }
17075
17076 break getTag;
17077
17078 case REACT_MEMO_TYPE:
17079 fiberTag = MemoComponent;
17080 break getTag;
17081
17082 case REACT_LAZY_TYPE:
17083 fiberTag = LazyComponent;
17084 resolvedType = null;
17085 break getTag;
17086
17087 case REACT_FUNDAMENTAL_TYPE:
17088 if (enableFundamentalAPI) {
17089 return createFiberFromFundamental(type, pendingProps, mode, expirationTime, key);
17090 }
17091
17092 break;
17093
17094 case REACT_SCOPE_TYPE:
17095 if (enableScopeAPI) {
17096 return createFiberFromScope(type, pendingProps, mode, expirationTime, key);
17097 }
17098
17099 }
17100 }
17101
17102 var info = '';
17103
17104 {
17105 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
17106 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.';
17107 }
17108
17109 var ownerName = owner ? getComponentName(owner.type) : null;
17110
17111 if (ownerName) {
17112 info += '\n\nCheck the render method of `' + ownerName + '`.';
17113 }
17114 }
17115
17116 (function () {
17117 {
17118 {
17119 throw ReactError(Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + (type == null ? type : typeof type) + "." + info));
17120 }
17121 }
17122 })();
17123 }
17124 }
17125 }
17126
17127 fiber = createFiber(fiberTag, pendingProps, key, mode);
17128 fiber.elementType = type;
17129 fiber.type = resolvedType;
17130 fiber.expirationTime = expirationTime;
17131 return fiber;
17132}
17133function createFiberFromElement(element, mode, expirationTime) {
17134 var owner = null;
17135
17136 {
17137 owner = element._owner;
17138 }
17139
17140 var type = element.type;
17141 var key = element.key;
17142 var pendingProps = element.props;
17143 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
17144
17145 {
17146 fiber._debugSource = element._source;
17147 fiber._debugOwner = element._owner;
17148 }
17149
17150 return fiber;
17151}
17152function createFiberFromFragment(elements, mode, expirationTime, key) {
17153 var fiber = createFiber(Fragment, elements, key, mode);
17154 fiber.expirationTime = expirationTime;
17155 return fiber;
17156}
17157function createFiberFromFundamental(fundamentalComponent, pendingProps, mode, expirationTime, key) {
17158 var fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
17159 fiber.elementType = fundamentalComponent;
17160 fiber.type = fundamentalComponent;
17161 fiber.expirationTime = expirationTime;
17162 return fiber;
17163}
17164
17165function createFiberFromScope(scope, pendingProps, mode, expirationTime, key) {
17166 var fiber = createFiber(ScopeComponent, pendingProps, key, mode);
17167 fiber.type = scope;
17168 fiber.elementType = scope;
17169 fiber.expirationTime = expirationTime;
17170 return fiber;
17171}
17172
17173function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
17174 {
17175 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
17176 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
17177 }
17178 }
17179
17180 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
17181
17182 fiber.elementType = REACT_PROFILER_TYPE;
17183 fiber.type = REACT_PROFILER_TYPE;
17184 fiber.expirationTime = expirationTime;
17185 return fiber;
17186}
17187
17188function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
17189 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
17190 // This needs to be fixed in getComponentName so that it relies on the tag
17191 // instead.
17192
17193 fiber.type = REACT_SUSPENSE_TYPE;
17194 fiber.elementType = REACT_SUSPENSE_TYPE;
17195 fiber.expirationTime = expirationTime;
17196 return fiber;
17197}
17198function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
17199 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
17200
17201 {
17202 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
17203 // This needs to be fixed in getComponentName so that it relies on the tag
17204 // instead.
17205 fiber.type = REACT_SUSPENSE_LIST_TYPE;
17206 }
17207
17208 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
17209 fiber.expirationTime = expirationTime;
17210 return fiber;
17211}
17212function createFiberFromText(content, mode, expirationTime) {
17213 var fiber = createFiber(HostText, content, null, mode);
17214 fiber.expirationTime = expirationTime;
17215 return fiber;
17216}
17217function createFiberFromHostInstanceForDeletion() {
17218 var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type.
17219
17220 fiber.elementType = 'DELETED';
17221 fiber.type = 'DELETED';
17222 return fiber;
17223}
17224function createFiberFromDehydratedFragment(dehydratedNode) {
17225 var fiber = createFiber(DehydratedFragment, null, null, NoMode);
17226 fiber.stateNode = dehydratedNode;
17227 return fiber;
17228}
17229function createFiberFromPortal(portal, mode, expirationTime) {
17230 var pendingProps = portal.children !== null ? portal.children : [];
17231 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
17232 fiber.expirationTime = expirationTime;
17233 fiber.stateNode = {
17234 containerInfo: portal.containerInfo,
17235 pendingChildren: null,
17236 // Used by persistent updates
17237 implementation: portal.implementation
17238 };
17239 return fiber;
17240} // Used for stashing WIP properties to replay failed work in DEV.
17241
17242function assignFiberPropertiesInDEV(target, source) {
17243 if (target === null) {
17244 // This Fiber's initial properties will always be overwritten.
17245 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
17246 target = createFiber(IndeterminateComponent, null, null, NoMode);
17247 } // This is intentionally written as a list of all properties.
17248 // We tried to use Object.assign() instead but this is called in
17249 // the hottest path, and Object.assign() was too slow:
17250 // https://github.com/facebook/react/issues/12502
17251 // This code is DEV-only so size is not a concern.
17252
17253
17254 target.tag = source.tag;
17255 target.key = source.key;
17256 target.elementType = source.elementType;
17257 target.type = source.type;
17258 target.stateNode = source.stateNode;
17259 target.return = source.return;
17260 target.child = source.child;
17261 target.sibling = source.sibling;
17262 target.index = source.index;
17263 target.ref = source.ref;
17264 target.pendingProps = source.pendingProps;
17265 target.memoizedProps = source.memoizedProps;
17266 target.updateQueue = source.updateQueue;
17267 target.memoizedState = source.memoizedState;
17268 target.dependencies = source.dependencies;
17269 target.mode = source.mode;
17270 target.effectTag = source.effectTag;
17271 target.nextEffect = source.nextEffect;
17272 target.firstEffect = source.firstEffect;
17273 target.lastEffect = source.lastEffect;
17274 target.expirationTime = source.expirationTime;
17275 target.childExpirationTime = source.childExpirationTime;
17276 target.alternate = source.alternate;
17277
17278 if (enableProfilerTimer) {
17279 target.actualDuration = source.actualDuration;
17280 target.actualStartTime = source.actualStartTime;
17281 target.selfBaseDuration = source.selfBaseDuration;
17282 target.treeBaseDuration = source.treeBaseDuration;
17283 }
17284
17285 target._debugID = source._debugID;
17286 target._debugSource = source._debugSource;
17287 target._debugOwner = source._debugOwner;
17288 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
17289 target._debugNeedsRemount = source._debugNeedsRemount;
17290 target._debugHookTypes = source._debugHookTypes;
17291 return target;
17292}
17293
17294function FiberRootNode(containerInfo, tag, hydrate) {
17295 this.tag = tag;
17296 this.current = null;
17297 this.containerInfo = containerInfo;
17298 this.pendingChildren = null;
17299 this.pingCache = null;
17300 this.finishedExpirationTime = NoWork;
17301 this.finishedWork = null;
17302 this.timeoutHandle = noTimeout;
17303 this.context = null;
17304 this.pendingContext = null;
17305 this.hydrate = hydrate;
17306 this.firstBatch = null;
17307 this.callbackNode = null;
17308 this.callbackPriority = NoPriority;
17309 this.firstPendingTime = NoWork;
17310 this.firstSuspendedTime = NoWork;
17311 this.lastSuspendedTime = NoWork;
17312 this.nextKnownPendingLevel = NoWork;
17313 this.lastPingedTime = NoWork;
17314 this.lastExpiredTime = NoWork;
17315
17316 if (enableSchedulerTracing) {
17317 this.interactionThreadID = unstable_getThreadID();
17318 this.memoizedInteractions = new Set();
17319 this.pendingInteractionMap = new Map();
17320 }
17321
17322 if (enableSuspenseCallback) {
17323 this.hydrationCallbacks = null;
17324 }
17325}
17326
17327function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
17328 var root = new FiberRootNode(containerInfo, tag, hydrate);
17329
17330 if (enableSuspenseCallback) {
17331 root.hydrationCallbacks = hydrationCallbacks;
17332 } // Cyclic construction. This cheats the type system right now because
17333 // stateNode is any.
17334
17335
17336 var uninitializedFiber = createHostRootFiber(tag);
17337 root.current = uninitializedFiber;
17338 uninitializedFiber.stateNode = root;
17339 return root;
17340}
17341function isRootSuspendedAtTime(root, expirationTime) {
17342 var firstSuspendedTime = root.firstSuspendedTime;
17343 var lastSuspendedTime = root.lastSuspendedTime;
17344 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
17345}
17346function markRootSuspendedAtTime(root, expirationTime) {
17347 var firstSuspendedTime = root.firstSuspendedTime;
17348 var lastSuspendedTime = root.lastSuspendedTime;
17349
17350 if (firstSuspendedTime < expirationTime) {
17351 root.firstSuspendedTime = expirationTime;
17352 }
17353
17354 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
17355 root.lastSuspendedTime = expirationTime;
17356 }
17357
17358 if (expirationTime <= root.lastPingedTime) {
17359 root.lastPingedTime = NoWork;
17360 }
17361
17362 if (expirationTime <= root.lastExpiredTime) {
17363 root.lastExpiredTime = NoWork;
17364 }
17365}
17366function markRootUpdatedAtTime(root, expirationTime) {
17367 // Update the range of pending times
17368 var firstPendingTime = root.firstPendingTime;
17369
17370 if (expirationTime > firstPendingTime) {
17371 root.firstPendingTime = expirationTime;
17372 } // Update the range of suspended times. Treat everything lower priority or
17373 // equal to this update as unsuspended.
17374
17375
17376 var firstSuspendedTime = root.firstSuspendedTime;
17377
17378 if (firstSuspendedTime !== NoWork) {
17379 if (expirationTime >= firstSuspendedTime) {
17380 // The entire suspended range is now unsuspended.
17381 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
17382 } else if (expirationTime >= root.lastSuspendedTime) {
17383 root.lastSuspendedTime = expirationTime + 1;
17384 } // This is a pending level. Check if it's higher priority than the next
17385 // known pending level.
17386
17387
17388 if (expirationTime > root.nextKnownPendingLevel) {
17389 root.nextKnownPendingLevel = expirationTime;
17390 }
17391 }
17392}
17393function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
17394 // Update the range of pending times
17395 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
17396 // equal to this update as unsuspended.
17397
17398 if (finishedExpirationTime <= root.lastSuspendedTime) {
17399 // The entire suspended range is now unsuspended.
17400 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
17401 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
17402 // Part of the suspended range is now unsuspended. Narrow the range to
17403 // include everything between the unsuspended time (non-inclusive) and the
17404 // last suspended time.
17405 root.firstSuspendedTime = finishedExpirationTime - 1;
17406 }
17407
17408 if (finishedExpirationTime <= root.lastPingedTime) {
17409 // Clear the pinged time
17410 root.lastPingedTime = NoWork;
17411 }
17412
17413 if (finishedExpirationTime <= root.lastExpiredTime) {
17414 // Clear the expired time
17415 root.lastExpiredTime = NoWork;
17416 }
17417}
17418function markRootExpiredAtTime(root, expirationTime) {
17419 var lastExpiredTime = root.lastExpiredTime;
17420
17421 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
17422 root.lastExpiredTime = expirationTime;
17423 }
17424}
17425
17426// This lets us hook into Fiber to debug what it's doing.
17427// See https://github.com/facebook/react/pull/8033.
17428// This is not part of the public API, not even for React DevTools.
17429// You may only inject a debugTool if you work on React Fiber itself.
17430var ReactFiberInstrumentation = {
17431 debugTool: null
17432};
17433var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
17434
17435var didWarnAboutNestedUpdates;
17436{
17437 didWarnAboutNestedUpdates = false;
17438
17439}
17440
17441function getContextForSubtree(parentComponent) {
17442 if (!parentComponent) {
17443 return emptyContextObject;
17444 }
17445
17446 var fiber = get(parentComponent);
17447 var parentContext = findCurrentUnmaskedContext(fiber);
17448
17449 if (fiber.tag === ClassComponent) {
17450 var Component = fiber.type;
17451
17452 if (isContextProvider(Component)) {
17453 return processChildContext(fiber, Component, parentContext);
17454 }
17455 }
17456
17457 return parentContext;
17458}
17459
17460function scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback) {
17461 {
17462 if (phase === 'render' && current$1 !== null && !didWarnAboutNestedUpdates) {
17463 didWarnAboutNestedUpdates = true;
17464 warningWithoutStack$1(false, 'Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName(current$1.type) || 'Unknown');
17465 }
17466 }
17467
17468 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
17469 // being called "element".
17470
17471 update.payload = {
17472 element: element
17473 };
17474 callback = callback === undefined ? null : callback;
17475
17476 if (callback !== null) {
17477 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
17478 update.callback = callback;
17479 }
17480
17481 enqueueUpdate(current$$1, update);
17482 scheduleWork(current$$1, expirationTime);
17483 return expirationTime;
17484}
17485
17486function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback) {
17487 // TODO: If this is a nested container, this won't be the root.
17488 var current$$1 = container.current;
17489
17490 {
17491 if (ReactFiberInstrumentation_1.debugTool) {
17492 if (current$$1.alternate === null) {
17493 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
17494 } else if (element === null) {
17495 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
17496 } else {
17497 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
17498 }
17499 }
17500 }
17501
17502 var context = getContextForSubtree(parentComponent);
17503
17504 if (container.context === null) {
17505 container.context = context;
17506 } else {
17507 container.pendingContext = context;
17508 }
17509
17510 return scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback);
17511}
17512
17513function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
17514 return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks);
17515}
17516function updateContainer(element, container, parentComponent, callback) {
17517 var current$$1 = container.current;
17518 var currentTime = requestCurrentTime();
17519
17520 {
17521 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
17522 if ('undefined' !== typeof jest) {
17523 warnIfUnmockedScheduler(current$$1);
17524 warnIfNotScopedWithMatchingAct(current$$1);
17525 }
17526 }
17527
17528 var suspenseConfig = requestCurrentSuspenseConfig();
17529 var expirationTime = computeExpirationForFiber(currentTime, current$$1, suspenseConfig);
17530 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback);
17531}
17532
17533
17534
17535
17536var shouldSuspendImpl = function (fiber) {
17537 return false;
17538};
17539
17540function shouldSuspend(fiber) {
17541 return shouldSuspendImpl(fiber);
17542}
17543var overrideHookState = null;
17544var overrideProps = null;
17545var scheduleUpdate = null;
17546var setSuspenseHandler = null;
17547
17548{
17549 var copyWithSetImpl = function (obj, path, idx, value) {
17550 if (idx >= path.length) {
17551 return value;
17552 }
17553
17554 var key = path[idx];
17555 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
17556
17557 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
17558 return updated;
17559 };
17560
17561 var copyWithSet = function (obj, path, value) {
17562 return copyWithSetImpl(obj, path, 0, value);
17563 }; // Support DevTools editable values for useState and useReducer.
17564
17565
17566 overrideHookState = function (fiber, id, path, value) {
17567 // For now, the "id" of stateful hooks is just the stateful hook index.
17568 // This may change in the future with e.g. nested hooks.
17569 var currentHook = fiber.memoizedState;
17570
17571 while (currentHook !== null && id > 0) {
17572 currentHook = currentHook.next;
17573 id--;
17574 }
17575
17576 if (currentHook !== null) {
17577 var newState = copyWithSet(currentHook.memoizedState, path, value);
17578 currentHook.memoizedState = newState;
17579 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
17580 // because there is no update we can add for useReducer hooks that won't trigger an error.
17581 // (There's no appropriate action type for DevTools overrides.)
17582 // As a result though, React will see the scheduled update as a noop and bailout.
17583 // Shallow cloning props works as a workaround for now to bypass the bailout check.
17584
17585 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
17586 scheduleWork(fiber, Sync);
17587 }
17588 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
17589
17590
17591 overrideProps = function (fiber, path, value) {
17592 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
17593
17594 if (fiber.alternate) {
17595 fiber.alternate.pendingProps = fiber.pendingProps;
17596 }
17597
17598 scheduleWork(fiber, Sync);
17599 };
17600
17601 scheduleUpdate = function (fiber) {
17602 scheduleWork(fiber, Sync);
17603 };
17604
17605 setSuspenseHandler = function (newShouldSuspendImpl) {
17606 shouldSuspendImpl = newShouldSuspendImpl;
17607 };
17608}
17609
17610function injectIntoDevTools(devToolsConfig) {
17611 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
17612 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
17613 return injectInternals(_assign({}, devToolsConfig, {
17614 overrideHookState: overrideHookState,
17615 overrideProps: overrideProps,
17616 setSuspenseHandler: setSuspenseHandler,
17617 scheduleUpdate: scheduleUpdate,
17618 currentDispatcherRef: ReactCurrentDispatcher,
17619 findHostInstanceByFiber: function (fiber) {
17620 var hostFiber = findCurrentHostFiber(fiber);
17621
17622 if (hostFiber === null) {
17623 return null;
17624 }
17625
17626 return hostFiber.stateNode;
17627 },
17628 findFiberByHostInstance: function (instance) {
17629 if (!findFiberByHostInstance) {
17630 // Might not be implemented by the renderer.
17631 return null;
17632 }
17633
17634 return findFiberByHostInstance(instance);
17635 },
17636 // React Refresh
17637 findHostInstancesForRefresh: findHostInstancesForRefresh,
17638 scheduleRefresh: scheduleRefresh,
17639 scheduleRoot: scheduleRoot,
17640 setRefreshHandler: setRefreshHandler,
17641 // Enables DevTools to append owner stacks to error messages in DEV mode.
17642 getCurrentFiber: function () {
17643 return current$1;
17644 }
17645 }));
17646}
17647
17648// This file intentionally does *not* have the Flow annotation.
17649// Don't add it. See `./inline-typed.js` for an explanation.
17650
17651var container = _class({
17652
17653 grab: function(){
17654 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
17655 return this;
17656 },
17657
17658 empty: function(){
17659 var node;
17660 while (node = this.firstChild) node.eject();
17661 return this;
17662 }
17663
17664});
17665
17666function elementFrom(node){
17667 if (node.toElement) return node.toElement();
17668 if (node.getDOMNode) return node.getDOMNode();
17669 if (node.getNode) return node.getNode();
17670 return node;
17671}
17672
17673var native_1 = _class({
17674
17675 // conventions
17676
17677 toElement: function(){
17678 return this.element;
17679 },
17680
17681 getDOMNode: function(){
17682 return this.toElement();
17683 },
17684
17685 getNode: function(){
17686 return this.toElement();
17687 },
17688
17689 // placement
17690
17691 inject: function(container){
17692 (container.containerElement || elementFrom(container))
17693 .appendChild(this.element);
17694 return this;
17695 },
17696
17697 injectBefore: function(sibling){
17698 var element = elementFrom(sibling);
17699 element.parentNode.insertBefore(this.element, element);
17700 return this;
17701 },
17702
17703 eject: function(){
17704 var element = this.element, parent = element.parentNode;
17705 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
17706 return this;
17707 },
17708
17709 // events
17710
17711 subscribe: function(type, fn, bind){
17712 if (typeof type != 'string'){ // listen type / fn with object
17713 var subscriptions = [];
17714 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
17715 return function(){ // unsubscribe
17716 for (var i = 0, l = subscriptions.length; i < l; i++)
17717 subscriptions[i]();
17718 return this;
17719 };
17720 } else { // listen to one
17721 if (!bind) bind = this;
17722 var bound;
17723 if (typeof fn === 'function'){
17724 bound = fn.bind ? fn.bind(bind)
17725 : function(){ return fn.apply(bind, arguments); };
17726 } else {
17727 bound = fn;
17728 }
17729 var element = this.element;
17730 if (element.addEventListener){
17731 element.addEventListener(type, bound, false);
17732 return function(){ // unsubscribe
17733 element.removeEventListener(type, bound, false);
17734 return this;
17735 };
17736 } else {
17737 element.attachEvent('on' + type, bound);
17738 return function(){ // unsubscribe
17739 element.detachEvent('on' + type, bound);
17740 return this;
17741 };
17742 }
17743 }
17744 }
17745
17746});
17747
17748var fps = 1000 / 60;
17749var invalids = [];
17750var renderTimer;
17751var renderInvalids = function(){
17752 clearTimeout(renderTimer);
17753 renderTimer = null;
17754 var canvases = invalids;
17755 invalids = [];
17756 for (var i = 0, l = canvases.length; i < l; i++){
17757 var c = canvases[i];
17758 c._valid = true;
17759 c.render();
17760 }
17761};
17762
17763var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
17764
17765var previousHit = null;
17766var previousHitSurface = null;
17767
17768var CanvasSurface = _class(native_1, container, {
17769
17770 initialize: function(width, height, existingElement){
17771 var element = this.element = existingElement || document.createElement('canvas');
17772 var context = this.context = element.getContext('2d');
17773 this._valid = true;
17774 if (width != null && height != null) this.resize(width, height);
17775
17776 element.addEventListener('mousemove', this, false);
17777 element.addEventListener('mouseout', this, false);
17778 element.addEventListener('mouseover', this, false);
17779 element.addEventListener('mouseup', this, false);
17780 element.addEventListener('mousedown', this, false);
17781 element.addEventListener('click', this, false);
17782 },
17783
17784 handleEvent: function(event){
17785 if (event.clientX == null) return;
17786 var element = this.element,
17787 rect = element.getBoundingClientRect(),
17788 x = event.clientX - rect.left - element.clientLeft,
17789 y = event.clientY - rect.top - element.clientTop,
17790 hit = this.hitTest(x, y);
17791
17792 if (hit !== previousHit){
17793 if (previousHit){
17794 previousHit.dispatch({
17795 type: 'mouseout',
17796 target: previousHit,
17797 relatedTarget: hit,
17798 sourceEvent: event
17799 });
17800 }
17801 if (hit){
17802 hit.dispatch({
17803 type: 'mouseover',
17804 target: hit,
17805 relatedTarget: previousHit,
17806 sourceEvent: event
17807 });
17808 }
17809 previousHit = hit;
17810 previousHitSurface = this;
17811 this.refreshCursor();
17812 }
17813
17814 if (hit) hit.dispatch(event);
17815 },
17816
17817 refreshCursor: function(){
17818 if (previousHitSurface !== this) return;
17819 var hit = previousHit, hitCursor = '', hitTooltip = '';
17820 while (hit){
17821 if (!hitCursor && hit._cursor){
17822 hitCursor = hit._cursor;
17823 if (hitTooltip) break;
17824 }
17825 if (!hitTooltip && hit._tooltip){
17826 hitTooltip = hit._tooltip;
17827 if (hitCursor) break;
17828 }
17829 hit = hit.parentNode;
17830 }
17831 // TODO: No way to set cursor/title on the surface
17832 this.element.style.cursor = hitCursor;
17833 this.element.title = hitTooltip;
17834 },
17835
17836 resize: function(width, height){
17837 var element = this.element;
17838 element.setAttribute('width', width * resolution);
17839 element.setAttribute('height', height * resolution);
17840 element.style.width = width + 'px';
17841 element.style.height = height + 'px';
17842 this.width = width;
17843 this.height = height;
17844 return this;
17845 },
17846
17847 invalidate: function(left, top, width, height){
17848 if (this._valid){
17849 this._valid = false;
17850 invalids.push(this);
17851 if (!renderTimer){
17852 if (window.mozRequestAnimationFrame){
17853 renderTimer = true;
17854 window.mozRequestAnimationFrame(renderInvalids);
17855 } else {
17856 renderTimer = setTimeout(renderInvalids, fps);
17857 }
17858 }
17859 }
17860 return this;
17861 },
17862
17863 hitTest: function(x, y){
17864 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
17865 var node = this.lastChild;
17866 while (node){
17867 var hit = node.hitTest(x, y);
17868 if (hit) return hit;
17869 node = node.previousSibling;
17870 }
17871 return null;
17872 },
17873
17874 render: function(){
17875 var node = this.firstChild, context = this.context;
17876 context.setTransform(resolution, 0, 0, resolution, 0, 0);
17877 context.clearRect(0, 0, this.width, this.height);
17878 while (node){
17879 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
17880 node = node.nextSibling;
17881 }
17882 this.refreshCursor();
17883 }
17884
17885});
17886
17887CanvasSurface.tagName = 'canvas';
17888
17889var surface = CanvasSurface;
17890
17891var path$2 = _class({
17892
17893 initialize: function(path){
17894 this.reset().push(path);
17895 },
17896
17897 /* parser */
17898
17899 push: function(){
17900 var p = Array.prototype.join.call(arguments, ' ')
17901 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
17902 if (!p) return this;
17903
17904 var last, cmd = p[0], i = 1;
17905 while (cmd){
17906 switch (cmd){
17907 case 'm': this.move(p[i++], p[i++]); break;
17908 case 'l': this.line(p[i++], p[i++]); break;
17909 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
17910 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
17911 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
17912 case 't': this.curve(p[i++], p[i++]); break;
17913 case 'a': this.arc(p[i+5], p[i+6], p[i], p[i+1], p[i+3], !+p[i+4], p[i+2]); i += 7; break;
17914 case 'h': this.line(p[i++], 0); break;
17915 case 'v': this.line(0, p[i++]); break;
17916
17917 case 'M': this.moveTo(p[i++], p[i++]); break;
17918 case 'L': this.lineTo(p[i++], p[i++]); break;
17919 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
17920 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
17921 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
17922 case 'T': this.curveTo(p[i++], p[i++]); break;
17923 case 'A': this.arcTo(p[i+5], p[i+6], p[i], p[i+1], p[i+3], !+p[i+4], p[i+2]); i += 7; break;
17924 case 'H': this.lineTo(p[i++], this.penY); break;
17925 case 'V': this.lineTo(this.penX, p[i++]); break;
17926
17927 case 'Z': case 'z': this.close(); break;
17928 default: cmd = last; i--; continue;
17929 }
17930
17931 last = cmd;
17932 if (last == 'm') last = 'l';
17933 else if (last == 'M') last = 'L';
17934 cmd = p[i++];
17935 }
17936 return this;
17937 },
17938
17939 /* utility methods */
17940
17941 reset: function(){
17942 this.penX = this.penY = 0;
17943 this.penDownX = this.penDownY = null;
17944 this._pivotX = this._pivotY = 0;
17945 this.onReset();
17946 return this;
17947 },
17948
17949 move: function(x,y){
17950 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
17951 return this;
17952 },
17953 moveTo: function(x,y){
17954 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
17955 return this;
17956 },
17957
17958 line: function(x,y){
17959 return this.lineTo(this.penX + (+x), this.penY + (+y));
17960 },
17961 lineTo: function(x,y){
17962 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
17963 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
17964 return this;
17965 },
17966
17967 curve: function(c1x, c1y, c2x, c2y, ex, ey){
17968 var x = this.penX, y = this.penY;
17969 return this.curveTo(
17970 x + (+c1x), y + (+c1y),
17971 c2x == null ? null : x + (+c2x),
17972 c2y == null ? null : y + (+c2y),
17973 ex == null ? null : x + (+ex),
17974 ey == null ? null : y + (+ey)
17975 );
17976 },
17977 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
17978 var x = this.penX, y = this.penY;
17979 if (c2x == null){
17980 c2x = +c1x; c2y = +c1y;
17981 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
17982 }
17983 if (ex == null){
17984 this._pivotX = +c1x; this._pivotY = +c1y;
17985 ex = +c2x; ey = +c2y;
17986 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
17987 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
17988 } else {
17989 this._pivotX = +c2x; this._pivotY = +c2y;
17990 }
17991 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
17992 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
17993 return this;
17994 },
17995
17996 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
17997 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
17998 },
17999 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
18000 ry = Math.abs(+ry || +rx || (+y - this.penY));
18001 rx = Math.abs(+rx || (+x - this.penX));
18002
18003 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
18004
18005 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
18006
18007 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
18008 x -= tX; y -= tY;
18009
18010 // Ellipse Center
18011 var cx = cos * x / 2 + sin * y / 2,
18012 cy = -sin * x / 2 + cos * y / 2,
18013 rxry = rx * rx * ry * ry,
18014 rycx = ry * ry * cx * cx,
18015 rxcy = rx * rx * cy * cy,
18016 a = rxry - rxcy - rycx;
18017
18018 if (a < 0){
18019 a = Math.sqrt(1 - a / rxry);
18020 rx *= a; ry *= a;
18021 cx = x / 2; cy = y / 2;
18022 } else {
18023 a = Math.sqrt(a / (rxcy + rycx));
18024 if (large == clockwise) a = -a;
18025 var cxd = -a * cy * rx / ry,
18026 cyd = a * cx * ry / rx;
18027 cx = cos * cxd - sin * cyd + x / 2;
18028 cy = sin * cxd + cos * cyd + y / 2;
18029 }
18030
18031 // Rotation + Scale Transform
18032 var xx = cos / rx, yx = sin / rx,
18033 xy = -sin / ry, yy = cos / ry;
18034
18035 // Start and End Angle
18036 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
18037 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
18038
18039 cx += tX; cy += tY;
18040 x += tX; y += tY;
18041
18042 // Circular Arc
18043 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
18044 this.onArc(
18045 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
18046 cx, cy, rx, ry, sa, ea, !clockwise, rotation
18047 );
18048 return this;
18049 },
18050
18051 counterArc: function(x, y, rx, ry, outer){
18052 return this.arc(x, y, rx, ry, outer, true);
18053 },
18054 counterArcTo: function(x, y, rx, ry, outer){
18055 return this.arcTo(x, y, rx, ry, outer, true);
18056 },
18057
18058 close: function(){
18059 if (this.penDownX != null){
18060 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
18061 this.penDownX = null;
18062 }
18063 return this;
18064 },
18065
18066 /* overridable handlers */
18067
18068 onReset: function(){
18069 },
18070
18071 onMove: function(sx, sy, ex, ey){
18072 },
18073
18074 onLine: function(sx, sy, ex, ey){
18075 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
18076 },
18077
18078 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
18079 var gx = ex - sx, gy = ey - sy,
18080 g = gx * gx + gy * gy,
18081 v1, v2, cx, cy, u;
18082
18083 cx = c1x - sx; cy = c1y - sy;
18084 u = cx * gx + cy * gy;
18085
18086 if (u > g){
18087 cx -= gx;
18088 cy -= gy;
18089 } else if (u > 0 && g != 0){
18090 cx -= u/g * gx;
18091 cy -= u/g * gy;
18092 }
18093
18094 v1 = cx * cx + cy * cy;
18095
18096 cx = c2x - sx; cy = c2y - sy;
18097 u = cx * gx + cy * gy;
18098
18099 if (u > g){
18100 cx -= gx;
18101 cy -= gy;
18102 } else if (u > 0 && g != 0){
18103 cx -= u/g * gx;
18104 cy -= u/g * gy;
18105 }
18106
18107 v2 = cx * cx + cy * cy;
18108
18109 if (v1 < 0.01 && v2 < 0.01){
18110 this.onLine(sx, sy, ex, ey);
18111 return;
18112 }
18113
18114 // Avoid infinite recursion
18115 if (isNaN(v1) || isNaN(v2)){
18116 throw new Error('Bad input');
18117 }
18118
18119 // Split curve
18120 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
18121 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
18122 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
18123 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
18124 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
18125 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
18126
18127 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
18128 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
18129 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
18130 },
18131
18132 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
18133 // Inverse Rotation + Scale Transform
18134 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
18135 xx = cos * rx, yx = -sin * ry,
18136 xy = sin * rx, yy = cos * ry;
18137
18138 // Bezier Curve Approximation
18139 var arc = ea - sa;
18140 if (arc < 0 && !ccw) arc += Math.PI * 2;
18141 else if (arc > 0 && ccw) arc -= Math.PI * 2;
18142
18143 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
18144 step = arc / n,
18145 k = (4 / 3) * Math.tan(step / 4);
18146
18147 var x = Math.cos(sa), y = Math.sin(sa);
18148
18149 for (var i = 0; i < n; i++){
18150 var cp1x = x - k * y, cp1y = y + k * x;
18151
18152 sa += step;
18153 x = Math.cos(sa); y = Math.sin(sa);
18154
18155 var cp2x = x + k * y, cp2y = y - k * x;
18156
18157 this.onBezierCurve(
18158 sx, sy,
18159 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
18160 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
18161 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
18162 );
18163 }
18164 },
18165
18166 onClose: function(sx, sy, ex, ey){
18167 this.onLine(sx, sy, ex, ey);
18168 }
18169
18170});
18171
18172var CanvasPath = _class(path$2, {
18173
18174 initialize: function(path){
18175 this.reset();
18176 if (path instanceof CanvasPath){
18177 this.path = path.path.slice(0);
18178 } else if (path){
18179 if (path.applyToPath)
18180 path.applyToPath(this);
18181 else
18182 this.push(path);
18183 }
18184 },
18185
18186 onReset: function(){
18187 this.path = [];
18188 },
18189
18190 onMove: function(sx, sy, x, y){
18191 this.path.push(function(context){
18192 context.moveTo(x, y);
18193 });
18194 },
18195
18196 onLine: function(sx, sy, x, y){
18197 this.path.push(function(context){
18198 context.lineTo(x, y);
18199 });
18200 },
18201
18202 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
18203 this.path.push(function(context){
18204 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
18205 });
18206 },
18207
18208 _arcToBezier: path$2.prototype.onArc,
18209
18210 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
18211 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
18212 this.path.push(function(context){
18213 context.arc(cx, cy, rx, sa, ea, ccw);
18214 });
18215 },
18216
18217 onClose: function(){
18218 this.path.push(function(context){
18219 context.closePath();
18220 });
18221 },
18222
18223 toCommands: function(){
18224 return this.path.slice(0);
18225 }
18226
18227});
18228
18229var path = CanvasPath;
18230
18231var colors = {
18232 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
18233 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
18234 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
18235 black: '#000000', silver: '#c0c0c0', gray: '#808080'
18236};
18237
18238var map = function(array, fn){
18239 var results = [];
18240 for (var i = 0, l = array.length; i < l; i++)
18241 results[i] = fn(array[i], i);
18242 return results;
18243};
18244
18245var Color = function(color, type){
18246
18247 if (color.isColor){
18248
18249 this.red = color.red;
18250 this.green = color.green;
18251 this.blue = color.blue;
18252 this.alpha = color.alpha;
18253
18254 } else {
18255
18256 var namedColor = colors[color];
18257 if (namedColor){
18258 color = namedColor;
18259 type = 'hex';
18260 }
18261
18262 switch (typeof color){
18263 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
18264 case 'object': type = type || 'rgb'; color = color.toString(); break;
18265 case 'number': type = 'hex'; color = color.toString(16); break;
18266 }
18267
18268 color = Color['parse' + type.toUpperCase()](color);
18269 this.red = color[0];
18270 this.green = color[1];
18271 this.blue = color[2];
18272 this.alpha = color[3];
18273 }
18274
18275 this.isColor = true;
18276
18277};
18278
18279var limit = function(number, min, max){
18280 return Math.min(max, Math.max(min, number));
18281};
18282
18283var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
18284var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
18285
18286Color.parseRGB = function(color){
18287 return map(color.match(listMatch).slice(1), function(bit, i){
18288 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
18289 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
18290 });
18291};
18292
18293Color.parseHEX = function(color){
18294 if (color.length == 1) color = color + color + color;
18295 return map(color.match(hexMatch).slice(1), function(bit, i){
18296 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
18297 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
18298 });
18299};
18300
18301Color.parseHSB = function(color){
18302 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
18303 if (bit) bit = parseFloat(bit);
18304 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
18305 else if (i < 3) return limit(Math.round(bit), 0, 100);
18306 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
18307 });
18308
18309 var a = hsb[3];
18310 var br = Math.round(hsb[2] / 100 * 255);
18311 if (hsb[1] == 0) return [br, br, br, a];
18312
18313 var hue = hsb[0];
18314 var f = hue % 60;
18315 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
18316 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
18317 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
18318
18319 switch (Math.floor(hue / 60)){
18320 case 0: return [br, t, p, a];
18321 case 1: return [q, br, p, a];
18322 case 2: return [p, br, t, a];
18323 case 3: return [p, q, br, a];
18324 case 4: return [t, p, br, a];
18325 default: return [br, p, q, a];
18326 }
18327};
18328
18329Color.parseHSL = function(color){
18330 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
18331 if (bit) bit = parseFloat(bit);
18332 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
18333 else if (i < 3) return limit(Math.round(bit), 0, 100);
18334 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
18335 });
18336
18337 var h = hsb[0] / 60;
18338 var s = hsb[1] / 100;
18339 var l = hsb[2] / 100;
18340 var a = hsb[3];
18341
18342 var c = (1 - Math.abs(2 * l - 1)) * s;
18343 var x = c * (1 - Math.abs(h % 2 - 1));
18344 var m = l - c / 2;
18345
18346 var p = Math.round((c + m) * 255);
18347 var q = Math.round((x + m) * 255);
18348 var t = Math.round((m) * 255);
18349
18350 switch (Math.floor(h)){
18351 case 0: return [p, q, t, a];
18352 case 1: return [q, p, t, a];
18353 case 2: return [t, p, q, a];
18354 case 3: return [t, q, p, a];
18355 case 4: return [q, t, p, a];
18356 default: return [p, t, q, a];
18357 }
18358};
18359
18360var toString = function(type, array){
18361 if (array[3] != 1) type += 'a';
18362 else array.pop();
18363 return type + '(' + array.join(', ') + ')';
18364};
18365
18366Color.prototype = {
18367
18368 toHSB: function(array){
18369 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
18370
18371 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
18372 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
18373 if (saturation){
18374 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
18375 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
18376 if ((hue /= 6) < 0) hue++;
18377 }
18378
18379 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
18380
18381 return (array) ? hsb : toString('hsb', hsb);
18382 },
18383
18384 toHSL: function(array){
18385 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
18386
18387 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
18388 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
18389 if (saturation){
18390 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
18391 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
18392 if ((hue /= 6) < 0) hue++;
18393 }
18394
18395 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
18396
18397 return (array) ? hsl : toString('hsl', hsl);
18398 },
18399
18400 toHEX: function(array){
18401
18402 var a = this.alpha;
18403 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
18404
18405 var hex = map([this.red, this.green, this.blue], function(bit){
18406 bit = bit.toString(16);
18407 return (bit.length == 1) ? '0' + bit : bit;
18408 });
18409
18410 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
18411 },
18412
18413 toRGB: function(array){
18414 var rgb = [this.red, this.green, this.blue, this.alpha];
18415 return (array) ? rgb : toString('rgb', rgb);
18416 }
18417
18418};
18419
18420Color.prototype.toString = Color.prototype.toRGB;
18421
18422Color.hex = function(hex){
18423 return new Color(hex, 'hex');
18424};
18425
18426if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
18427
18428Color.hsb = function(h, s, b, a){
18429 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
18430};
18431
18432if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
18433
18434Color.hsl = function(h, s, l, a){
18435 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
18436};
18437
18438if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
18439
18440Color.rgb = function(r, g, b, a){
18441 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
18442};
18443
18444if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
18445
18446Color.detach = function(color){
18447 color = new Color(color);
18448 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
18449};
18450
18451var color = Color;
18452
18453var dummy = _class({
18454
18455 // placement
18456
18457 _resetPlacement: function(){
18458 var container = this.parentNode;
18459 if (container){
18460 var previous = this.previousSibling, next = this.nextSibling;
18461 if (previous){
18462 previous.nextSibling = next;
18463 } else {
18464 container.firstChild = next;
18465 }
18466 if (next){
18467 next.previousSibling = previous;
18468 } else {
18469 container.lastChild = this.previousSibling;
18470 }
18471 }
18472 this.previousSibling = null;
18473 this.nextSibling = null;
18474 this.parentNode = null;
18475 return this;
18476 },
18477
18478 inject: function(container){
18479 this._resetPlacement();
18480 var last = container.lastChild;
18481 if (last){
18482 last.nextSibling = this;
18483 this.previousSibling = last;
18484 } else {
18485 container.firstChild = this;
18486 }
18487 container.lastChild = this;
18488 this.parentNode = container;
18489 this._place();
18490 return this;
18491 },
18492
18493 injectBefore: function(sibling){
18494 this._resetPlacement();
18495 var container = sibling.parentNode;
18496 if (!container) return this;
18497 var previous = sibling.previousSibling;
18498 if (previous){
18499 previous.nextSibling = this;
18500 this.previousSibling = previous;
18501 } else {
18502 container.firstChild = this;
18503 }
18504 sibling.previousSibling = this;
18505 this.nextSibling = sibling;
18506 this.parentNode = container;
18507 this._place();
18508 return this;
18509 },
18510
18511 eject: function(){
18512 this._resetPlacement();
18513 this._place();
18514 return this;
18515 },
18516
18517 _place: function(){},
18518
18519 // events
18520
18521 dispatch: function(event){
18522 var events = this._events,
18523 listeners = events && events[event.type];
18524 if (listeners){
18525 listeners = listeners.slice(0);
18526 for (var i = 0, l = listeners.length; i < l; i++){
18527 var fn = listeners[i], result;
18528 if (typeof fn == 'function')
18529 result = fn.call(this, event);
18530 else
18531 result = fn.handleEvent(event);
18532 if (result === false) event.preventDefault();
18533 }
18534 }
18535 if (this.parentNode && this.parentNode.dispatch){
18536 this.parentNode.dispatch(event);
18537 }
18538 },
18539
18540 subscribe: function(type, fn, bind){
18541 if (typeof type != 'string'){ // listen type / fn with object
18542 var subscriptions = [];
18543 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
18544 return function(){ // unsubscribe
18545 for (var i = 0, l = subscriptions.length; i < l; i++)
18546 subscriptions[i]();
18547 return this;
18548 };
18549 } else { // listen to one
18550 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
18551 events = this._events || (this._events = {}),
18552 listeners = events[type] || (events[type] = []);
18553 listeners.push(bound);
18554 return function(){
18555 // unsubscribe
18556 for (var i = 0, l = listeners.length; i < l; i++){
18557 if (listeners[i] === bound){
18558 listeners.splice(i, 1);
18559 break;
18560 }
18561 }
18562 }
18563 }
18564 }
18565
18566});
18567
18568var CanvasNode = _class(transform, dummy, {
18569
18570 invalidate: function(){
18571 if (this.parentNode) this.parentNode.invalidate();
18572 if (this._layer) this._layerCache = null;
18573 return this;
18574 },
18575
18576 _place: function(){
18577 this.invalidate();
18578 },
18579
18580 _transform: function(){
18581 this.invalidate();
18582 },
18583
18584 blend: function(opacity){
18585 if (opacity >= 1 && this._layer) this._layer = null;
18586 this._opacity = opacity;
18587 if (this.parentNode) this.parentNode.invalidate();
18588 return this;
18589 },
18590
18591 // visibility
18592
18593 hide: function(){
18594 this._invisible = true;
18595 if (this.parentNode) this.parentNode.invalidate();
18596 return this;
18597 },
18598
18599 show: function(){
18600 this._invisible = false;
18601 if (this.parentNode) this.parentNode.invalidate();
18602 return this;
18603 },
18604
18605 // interaction
18606
18607 indicate: function(cursor, tooltip){
18608 this._cursor = cursor;
18609 this._tooltip = tooltip;
18610 return this.invalidate();
18611 },
18612
18613 hitTest: function(x, y){
18614 if (this._invisible) return null;
18615 var point = this.inversePoint(x, y);
18616 if (!point) return null;
18617 return this.localHitTest(point.x, point.y);
18618 },
18619
18620 // rendering
18621
18622 renderTo: function(context, xx, yx, xy, yy, x, y){
18623 var opacity = this._opacity;
18624 if (opacity == null || opacity >= 1){
18625 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
18626 }
18627
18628 // Render to a compositing layer and cache it
18629
18630 var layer = this._layer, canvas, isDirty = true,
18631 w = context.canvas.width, h = context.canvas.height;
18632 if (layer){
18633 layer.setTransform(1, 0, 0, 1, 0, 0);
18634 canvas = layer.canvas;
18635 if (canvas.width < w || canvas.height < h){
18636 canvas.width = w;
18637 canvas.height = h;
18638 } else {
18639 var c = this._layerCache;
18640 if (c && c.xx === xx && c.yx === yx && c.xy === xy
18641 && c.yy === yy && c.x === x && c.y === y){
18642 isDirty = false;
18643 } else {
18644 layer.clearRect(0, 0, w, h);
18645 }
18646 }
18647 } else {
18648 canvas = document.createElement('canvas');
18649 canvas.width = w;
18650 canvas.height = h;
18651 this._layer = layer = canvas.getContext('2d');
18652 }
18653
18654 if (isDirty){
18655 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
18656 this._layerCache = {
18657 xx: xx,
18658 yx: yx,
18659 xy: xy,
18660 yy: yy,
18661 x: x,
18662 y: y
18663 };
18664 }
18665
18666 context.globalAlpha = opacity;
18667 context.setTransform(1, 0, 0, 1, 0, 0);
18668 context.drawImage(
18669 canvas,
18670 0, 0, w, h,
18671 0, 0, w, h
18672 );
18673 context.globalAlpha = 1;
18674 }
18675
18676});
18677
18678var node = CanvasNode;
18679
18680var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas');
18681var genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
18682
18683function recolorImage(img, color1, color2){
18684 // TODO: Fix this experimental implementation
18685 color1 = color.detach(color1);
18686 color2 = color.detach(color2);
18687 var canvas = document.createElement('canvas'),
18688 context = canvas.getContext('2d');
18689 canvas.width = img.width;
18690 canvas.height = img.height;
18691 context.fillStyle = color2[0];
18692 context.fillRect(0, 0, img.width, img.height);
18693 context.globalCompositeOperation = 'lighter';
18694 context.drawImage(img, 0, 0);
18695 return canvas;
18696}
18697
18698var Base = _class(node, {
18699
18700 initialize: function(){
18701 this._fill = null;
18702 this._pendingFill = null;
18703 this._fillTransform = null;
18704 this._stroke = null;
18705 this._strokeCap = null;
18706 this._strokeDash = null;
18707 this._strokeJoin = null;
18708 this._strokeWidth = null;
18709 },
18710
18711 /* styles */
18712
18713 _addColors: function(gradient, stops){
18714 // Enumerate stops, assumes offsets are enumerated in order
18715 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
18716 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
18717 gradient.addColorStop(i / l, new color(stops[i]).toString());
18718 else for (var offset in stops)
18719 gradient.addColorStop(offset, new color(stops[offset]).toString());
18720 return gradient;
18721 },
18722
18723
18724 fill: function(color$$1){
18725 if (arguments.length > 1) return this.fillLinear(arguments);
18726 if (this._pendingFill) this._pendingFill();
18727 this._fill = color$$1 ? new color(color$$1).toString() : null;
18728 return this.invalidate();
18729 },
18730
18731 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
18732 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
18733 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
18734 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
18735 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
18736 if (centerX == null) centerX = focusX;
18737 if (centerY == null) centerY = focusY;
18738
18739 centerX += centerX - focusX;
18740 centerY += centerY - focusY;
18741
18742 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
18743 var ys = radiusY / radiusX;
18744
18745 if (this._pendingFill) this._pendingFill();
18746
18747 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
18748
18749 // Double fill radius to simulate repeating gradient
18750 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
18751 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
18752 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
18753 } else for (var offset in stops){
18754 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
18755 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
18756 }
18757
18758 this._fill = gradient;
18759 this._fillTransform = new transform(1, 0, 0, ys);
18760 return this.invalidate();
18761 },
18762
18763 fillLinear: function(stops, x1, y1, x2, y2){
18764 if (arguments.length < 5){
18765 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
18766
18767 var x = Math.cos(angle), y = -Math.sin(angle),
18768 l = (Math.abs(x) + Math.abs(y)) / 2,
18769 w = this.width || 1, h = this.height || 1;
18770
18771 x *= l; y *= l;
18772
18773 x1 = 0.5 - x;
18774 x2 = 0.5 + x;
18775 y1 = 0.5 - y;
18776 y2 = 0.5 + y;
18777 this._fillTransform = new transform(w, 0, 0, h);
18778 } else {
18779 this._fillTransform = null;
18780 }
18781 if (this._pendingFill) this._pendingFill();
18782 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
18783 this._addColors(gradient, stops);
18784 this._fill = gradient;
18785 return this.invalidate();
18786 },
18787
18788 fillImage: function(url, width, height, left, top, color1, color2){
18789 if (this._pendingFill) this._pendingFill();
18790 var img = url;
18791 if (!(img instanceof Image)){
18792 img = new Image();
18793 img.src = url;
18794 }
18795 if (img.width && img.height){
18796 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
18797 }
18798
18799 // Not yet loaded
18800 this._fill = null;
18801 var self = this,
18802 callback = function(){
18803 cancel();
18804 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
18805 },
18806 cancel = function(){
18807 img.removeEventListener('load', callback, false);
18808 self._pendingFill = null;
18809 };
18810 this._pendingFill = cancel;
18811 img.addEventListener('load', callback, false);
18812 return this;
18813 },
18814
18815 _fillImage: function(img, width, height, left, top, color1, color2){
18816 var w = width ? width / img.width : 1,
18817 h = height ? height / img.height : 1;
18818 if (color1 != null) img = recolorImage(img, color1, color2);
18819 this._fill = genericContext.createPattern(img, 'repeat');
18820 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
18821 return this.invalidate();
18822 },
18823
18824 stroke: function(color$$1, width, cap, join, dash){
18825 this._stroke = color$$1 ? new color(color$$1).toString() : null;
18826 this._strokeWidth = (width != null) ? width : 1;
18827 this._strokeCap = (cap != null) ? cap : 'round';
18828 this._strokeJoin = (join != null) ? join : 'round';
18829 this._strokeDash = dash;
18830 return this.invalidate();
18831 },
18832
18833 // Rendering
18834
18835 element_renderTo: node.prototype.renderTo,
18836
18837 renderTo: function(context, xx, yx, xy, yy, x, y){
18838 var opacity = this._opacity;
18839 if (opacity == null || opacity >= 1){
18840 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
18841 }
18842 if (this._fill && this._stroke){
18843 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
18844 }
18845 context.globalAlpha = opacity;
18846 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
18847 context.globalAlpha = 1;
18848 return r;
18849 },
18850
18851 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
18852 context.setTransform(xx, yx, xy, yy, x, y);
18853 this.renderShapeTo(context);
18854 }
18855
18856});
18857
18858Base._genericContext = genericContext;
18859
18860var base = Base;
18861
18862var shape = _class(base, {
18863
18864 base_initialize: base.prototype.initialize,
18865
18866 initialize: function(path$$1, width, height){
18867 this.base_initialize();
18868 this.width = width;
18869 this.height = height;
18870 if (path$$1 != null) this.draw(path$$1);
18871 },
18872
18873 draw: function(path$$1, width, height){
18874 if (!(path$$1 instanceof path)) path$$1 = new path(path$$1);
18875 this.path = path$$1;
18876 this._commands = path$$1.toCommands();
18877 if (width != null) this.width = width;
18878 if (height != null) this.height = height;
18879 return this.invalidate();
18880 },
18881
18882 localHitTest: function(x, y){
18883 if (!this._fill) return null;
18884 if (this.width == null || this.height == null){
18885 var context = base._genericContext, commands = this._commands;
18886 if (!commands) return null;
18887 context.beginPath();
18888 for (var i = 0, l = commands.length; i < l; i++)
18889 commands[i](context);
18890 return context.isPointInPath(x, y) ? this : null;
18891 }
18892 if (x > 0 && y > 0 && x < this.width && y < this.height){
18893 return this;
18894 }
18895 return null;
18896 },
18897
18898 renderShapeTo: function(context){
18899 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
18900 return null;
18901 }
18902 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
18903 var commands = this._commands,
18904 fill = this._fill,
18905 stroke = this._stroke,
18906 dash = this._strokeDash;
18907
18908 context.beginPath();
18909
18910 if (dash) {
18911 if (context.setLineDash) {
18912 context.setLineDash(dash);
18913 } else {
18914 // TODO: Remove when FF supports setLineDash.
18915 context.mozDash = dash;
18916 }
18917 // TODO: Create fallback to other browsers.
18918 } else {
18919 if (context.setLineDash) {
18920 context.setLineDash([]);
18921 } else {
18922 context.mozDash = null;
18923 }
18924 }
18925
18926 for (var i = 0, l = commands.length; i < l; i++)
18927 commands[i](context);
18928
18929 if (fill){
18930 var m = this._fillTransform;
18931 if (m){
18932 context.save(); // TODO: Optimize away this by restoring the transform before stroking
18933 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
18934 context.fillStyle = fill;
18935 context.fill();
18936 context.restore();
18937 } else {
18938 context.fillStyle = fill;
18939 context.fill();
18940 }
18941 }
18942 if (stroke){
18943 context.strokeStyle = stroke;
18944 context.lineWidth = this._strokeWidth;
18945 context.lineCap = this._strokeCap;
18946 context.lineJoin = this._strokeJoin;
18947 context.stroke();
18948 }
18949 }
18950
18951});
18952
18953var group = _class(node, container, {
18954
18955 initialize: function(width, height){
18956 this.width = width;
18957 this.height = height;
18958 },
18959
18960 localHitTest: function(x, y){
18961 var node$$2 = this.lastChild;
18962 while (node$$2){
18963 var hit = node$$2.hitTest(x, y);
18964 if (hit) return hit;
18965 node$$2 = node$$2.previousSibling;
18966 }
18967 return null;
18968 },
18969
18970 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
18971 if (this._invisible) return;
18972
18973 x = xx * this.x + xy * this.y + x;
18974 y = yx * this.x + yy * this.y + y;
18975
18976 var t = xx;
18977 xx = t * this.xx + xy * this.yx;
18978 xy = t * this.xy + xy * this.yy;
18979 t = yx;
18980 yx = t * this.xx + yy * this.yx;
18981 yy = t * this.xy + yy * this.yy;
18982
18983 var node$$2 = this.firstChild;
18984 while (node$$2){
18985 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
18986 node$$2 = node$$2.nextSibling;
18987 }
18988 }
18989
18990});
18991
18992var clippingrectangle = _class(node, container, {
18993
18994 initialize: function(width, height){
18995 this.width = width;
18996 this.height = height;
18997 },
18998
18999 localHitTest: function(x, y) {
19000 var node$$2 = this.lastChild;
19001 while (node$$2){
19002 var hit = node$$2.hitTest(x, y);
19003 if (hit) return hit;
19004 node$$2 = node$$2.previousSibling;
19005 }
19006 return null;
19007 },
19008
19009 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
19010 context.setTransform(xx, yx, xy, yy, x, y);
19011 context.save();
19012 // Need beginPath to fix Firefox bug. See 3354054.
19013 context.beginPath();
19014 context.rect(this.x, this.y, this.width, this.height);
19015 context.clip();
19016
19017 var node$$2 = this.firstChild;
19018 while(node$$2) {
19019 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
19020 node$$2 = node$$2.nextSibling;
19021 }
19022 context.restore();
19023 }
19024});
19025
19026var fontAnchors = { middle: 'center' };
19027
19028var text = _class(base, {
19029
19030 base_initialize: base.prototype.initialize,
19031
19032 initialize: function(text, font, alignment, path){
19033 this.base_initialize();
19034 this.draw.apply(this, arguments);
19035 },
19036
19037 draw: function(text, font, alignment, path){
19038 var em;
19039 if (typeof font == 'string'){
19040 em = Number(/(\d+)/.exec(font)[0]);
19041 } else if (font){
19042 em = parseFloat(font.fontSize || font['font-size'] || '12');
19043 font = (font.fontStyle || font['font-style'] || '') + ' ' +
19044 (font.fontVariant || font['font-variant'] || '') + ' ' +
19045 (font.fontWeight || font['font-weight'] || '') + ' ' +
19046 em + 'px ' +
19047 (font.fontFamily || font['font-family'] || 'Arial');
19048 } else {
19049 font = this._font;
19050 }
19051
19052 var lines = text && text.split(/\r?\n/);
19053 this._font = font;
19054 this._fontSize = em;
19055 this._text = lines;
19056 this._alignment = fontAnchors[alignment] || alignment || 'left';
19057
19058 var context = base._genericContext;
19059
19060 context.font = this._font;
19061 context.textAlign = this._alignment;
19062 context.textBaseline = 'middle';
19063
19064 lines = this._text;
19065 var l = lines.length, width = 0;
19066 for (var i = 0; i < l; i++){
19067 var w = context.measureText(lines[i]).width;
19068 if (w > width) width = w;
19069 }
19070 this.width = width;
19071 this.height = l ? l * 1.1 * em : 0;
19072 return this.invalidate();
19073 },
19074
19075 // Interaction
19076
19077 localHitTest: function(x, y){
19078 if (!this._fill) return null;
19079 if (x > 0 && y > 0 && x < this.width && y < this.height){
19080 return this;
19081 }
19082 return null;
19083 },
19084
19085 // Rendering
19086
19087 renderShapeTo: function(context){
19088 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
19089 return null;
19090 }
19091 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
19092 var fill = this._fill,
19093 stroke = this._stroke,
19094 text = this._text,
19095 dash = this._strokeDash;
19096
19097 context.font = this._font;
19098 context.textAlign = this._alignment;
19099 context.textBaseline = 'middle';
19100
19101 var em = this._fontSize,
19102 y = em / 2,
19103 lineHeight = 1.1 * em,
19104 lines = text,
19105 l = lines.length;
19106
19107 if (fill){
19108 context.fillStyle = fill;
19109 for (var i = 0; i < l; i++)
19110 context.fillText(lines[i], 0, y + i * lineHeight);
19111 }
19112 if (stroke){
19113 if (dash) {
19114 if (context.setLineDash) {
19115 context.setLineDash(dash);
19116 } else {
19117 // TODO: Remove when FF supports setLineDash.
19118 context.mozDash = dash;
19119 }
19120 // TODO: Create fallback to other browsers.
19121 } else {
19122 if (context.setLineDash) {
19123 context.setLineDash([]);
19124 } else {
19125 context.mozDash = null;
19126 }
19127 }
19128
19129 context.strokeStyle = stroke;
19130 context.lineWidth = this._strokeWidth;
19131 context.lineCap = this._strokeCap;
19132 context.lineJoin = this._strokeJoin;
19133 for (i = 0; i < l; i++)
19134 context.strokeText(lines[i], 0, y + i * lineHeight);
19135 }
19136 }
19137
19138});
19139
19140var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
19141
19142var styleSheet;
19143var styledTags = {};
19144var styleTag = function(tag){
19145 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
19146};
19147
19148var init = function(document){
19149
19150 var namespaces;
19151 try { // IE9 workaround: sometimes it throws here
19152 namespaces = document.namespaces;
19153 } catch (e) {
19154 }
19155 if (!namespaces) return false;
19156
19157 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
19158 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
19159
19160 styleSheet = document.createStyleSheet();
19161 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
19162/* styleTag('skew');
19163 styleTag('fill');
19164 styleTag('stroke');
19165 styleTag('path');
19166 styleTag('textpath');
19167 styleTag('group');*/
19168
19169 styleTag('vml');
19170
19171 return true;
19172
19173};
19174
19175var createElement = function(tag){
19176 if (!(tag in styledTags)) styleTag(tag);
19177 return document.createElement('av:' + tag);
19178};
19179
19180var dom = {
19181 init: init,
19182 createElement: createElement
19183};
19184
19185var precision = 100;
19186
19187var VMLSurface = _class(native_1, container, {
19188
19189 initialize: function VMLSurface(width, height, existingElement){
19190 this.element = existingElement || document.createElement('vml');
19191 this.containerElement = dom.createElement('group');
19192 this.element.appendChild(this.containerElement);
19193 if (width != null && height != null) this.resize(width, height);
19194 },
19195
19196 resize: function(width, height){
19197 this.width = width;
19198 this.height = height;
19199
19200 var style = this.element.style;
19201 style.pixelWidth = width;
19202 style.pixelHeight = height;
19203
19204 style = this.containerElement.style;
19205 style.width = width;
19206 style.height = height;
19207
19208 var halfPixel = (0.5 * precision);
19209
19210 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
19211 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
19212
19213 return this;
19214 }
19215
19216});
19217
19218VMLSurface.tagName = 'av:vml';
19219
19220var surface$2 = VMLSurface;
19221
19222var precision$1 = 100;
19223
19224var round = Math.round;
19225
19226var VMLPath = _class(path$2, {
19227
19228 initialize: function(path){
19229 this.reset();
19230 if (path instanceof VMLPath){
19231 this.path = [Array.prototype.join.call(path.path, ' ')];
19232 } else if (path){
19233 if (path.applyToPath)
19234 path.applyToPath(this);
19235 else
19236 this.push(path);
19237 }
19238 },
19239
19240 onReset: function(){
19241 this.path = [];
19242 },
19243
19244 onMove: function(sx, sy, x, y){
19245 this.path.push('m', round(x * precision$1), round(y * precision$1));
19246 },
19247
19248 onLine: function(sx, sy, x, y){
19249 this.path.push('l', round(x * precision$1), round(y * precision$1));
19250 },
19251
19252 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
19253 this.path.push('c',
19254 round(p1x * precision$1), round(p1y * precision$1),
19255 round(p2x * precision$1), round(p2y * precision$1),
19256 round(x * precision$1), round(y * precision$1)
19257 );
19258 },
19259
19260 _arcToBezier: path$2.prototype.onArc,
19261
19262 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
19263 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
19264 cx *= precision$1;
19265 cy *= precision$1;
19266 rx *= precision$1;
19267 this.path.push(ccw ? 'at' : 'wa',
19268 round(cx - rx), round(cy - rx),
19269 round(cx + rx), round(cy + rx),
19270 round(sx * precision$1), round(sy * precision$1),
19271 round(ex * precision$1), round(ey * precision$1)
19272 );
19273 },
19274
19275 onClose: function(){
19276 this.path.push('x');
19277 },
19278
19279 toVML: function(){
19280 return this.path.join(' ');
19281 }
19282
19283});
19284
19285VMLPath.prototype.toString = VMLPath.prototype.toVML;
19286
19287var path$4 = VMLPath;
19288
19289var shadow = _class(dummy, native_1, {
19290
19291 dummy_inject: dummy.prototype.inject,
19292 dummy_injectBefore: dummy.prototype.injectBefore,
19293 dummy_eject: dummy.prototype.eject,
19294 native_inject: native_1.prototype.inject,
19295 native_injectBefore: native_1.prototype.injectBefore,
19296 native_eject: native_1.prototype.eject,
19297
19298 inject: function(container){
19299 this.dummy_inject(container);
19300 this.native_inject(container);
19301 return this;
19302 },
19303
19304 injectBefore: function(sibling){
19305 this.dummy_injectBefore(sibling);
19306 this.native_injectBefore(sibling);
19307 return this;
19308 },
19309
19310 eject: function(){
19311 this.dummy_eject();
19312 this.native_eject();
19313 return this;
19314 }
19315
19316});
19317
19318var node$2 = _class(shadow, transform, {
19319
19320 initialize: function(tag){
19321 //this.uid = uniqueID();
19322 var element = this.element = dom.createElement(tag);
19323 //element.setAttribute('id', 'e' + this.uid);
19324 },
19325
19326 _place: function(){
19327 if (this.parentNode){
19328 this._transform();
19329 }
19330 },
19331
19332 // visibility
19333
19334 hide: function(){
19335 this.element.style.display = 'none';
19336 return this;
19337 },
19338
19339 show: function(){
19340 this.element.style.display = '';
19341 return this;
19342 },
19343
19344 // interaction
19345
19346 indicate: function(cursor, tooltip){
19347 if (cursor) this.element.style.cursor = cursor;
19348 if (tooltip) this.element.title = tooltip;
19349 return this;
19350 }
19351
19352});
19353
19354var precision$3 = 100;
19355
19356var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
19357
19358var base$2 = _class(node$2, {
19359
19360 element_initialize: node$2.prototype.initialize,
19361
19362 initialize: function(tag){
19363 this.element_initialize(tag);
19364 var element = this.element;
19365
19366 var skew = this.skewElement = dom.createElement('skew');
19367 skew.on = true;
19368 element.appendChild(skew);
19369
19370 var fill = this.fillElement = dom.createElement('fill');
19371 fill.on = false;
19372 element.appendChild(fill);
19373
19374 var stroke = this.strokeElement = dom.createElement('stroke');
19375 stroke.on = false;
19376 element.appendChild(stroke);
19377 },
19378
19379 /* transform */
19380
19381 _transform: function(){
19382 var container = this.parentNode;
19383
19384 // Active Transformation Matrix
19385 var m = container ? new transform(container._activeTransform).transform(this) : this;
19386
19387 // Box in shape user space
19388
19389 var box = this._boxCoords || this._size || defaultBox;
19390
19391 var originX = box.left || 0,
19392 originY = box.top || 0,
19393 width = box.width || 1,
19394 height = box.height || 1;
19395
19396 // Flipped
19397 var flip = m.yx / m.xx > m.yy / m.xy;
19398 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
19399 flip = flip ? -1 : 1;
19400
19401 m = new transform().scale(flip, 1).transform(m);
19402
19403 // Rotation is approximated based on the transform
19404 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
19405
19406 // Reverse the rotation, leaving the final transform in box space
19407 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
19408
19409 var transform$$2 = new transform(
19410 (m.xx * cos - m.xy * sin),
19411 (m.yx * cos - m.yy * sin) * flip,
19412 (m.xy * cos + m.xx * sin) * flip,
19413 (m.yy * cos + m.yx * sin)
19414 );
19415
19416 var rotationTransform = new transform().rotate(rotation, 0, 0);
19417
19418 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
19419
19420 // Scale box after reversing rotation
19421 width *= Math.abs(shapeToBox.xx);
19422 height *= Math.abs(shapeToBox.yy);
19423
19424 // Place box
19425 var left = m.x, top = m.y;
19426
19427 // Compensate for offset by center origin rotation
19428 var vx = -width / 2, vy = -height / 2;
19429 var point = rotationTransform.point(vx, vy);
19430 left -= point.x - vx;
19431 top -= point.y - vy;
19432
19433 // Adjust box position based on offset
19434 var rsm = new transform(m).moveTo(0,0);
19435 point = rsm.point(originX, originY);
19436 left += point.x;
19437 top += point.y;
19438
19439 if (flip < 0) left = -left - width;
19440
19441 // Place transformation origin
19442 var point0 = rsm.point(-originX, -originY);
19443 var point1 = rotationTransform.point(width, height);
19444 var point2 = rotationTransform.point(width, 0);
19445 var point3 = rotationTransform.point(0, height);
19446
19447 var minX = Math.min(0, point1.x, point2.x, point3.x),
19448 maxX = Math.max(0, point1.x, point2.x, point3.x),
19449 minY = Math.min(0, point1.y, point2.y, point3.y),
19450 maxY = Math.max(0, point1.y, point2.y, point3.y);
19451
19452 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
19453 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
19454
19455 // Adjust the origin
19456 point = shapeToBox.point(originX, originY);
19457 originX = point.x;
19458 originY = point.y;
19459
19460 // Scale stroke
19461 var strokeWidth = this._strokeWidth;
19462 if (strokeWidth){
19463 // Scale is the hypothenus between the two vectors
19464 // TODO: Use area calculation instead
19465 var vx = m.xx + m.xy, vy = m.yy + m.yx;
19466 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
19467 }
19468
19469 // convert to multiplied precision space
19470 originX *= precision$3;
19471 originY *= precision$3;
19472 left *= precision$3;
19473 top *= precision$3;
19474 width *= precision$3;
19475 height *= precision$3;
19476
19477 // Set box
19478 var element = this.element;
19479 element.coordorigin = originX + ',' + originY;
19480 element.coordsize = width + ',' + height;
19481 element.style.left = left + 'px';
19482 element.style.top = top + 'px';
19483 element.style.width = width;
19484 element.style.height = height;
19485 element.style.rotation = rotation.toFixed(8);
19486 element.style.flip = flip < 0 ? 'x' : '';
19487
19488 // Set transform
19489 var skew = this.skewElement;
19490 skew.matrix = [transform$$2.xx.toFixed(4), transform$$2.xy.toFixed(4), transform$$2.yx.toFixed(4), transform$$2.yy.toFixed(4), 0, 0];
19491 skew.origin = transformOriginX + ',' + transformOriginY;
19492
19493 // Set stroke
19494 this.strokeElement.weight = strokeWidth + 'px';
19495 },
19496
19497 /* styles */
19498
19499 _createGradient: function(style, stops){
19500 var fill = this.fillElement;
19501
19502 // Temporarily eject the fill from the DOM
19503 this.element.removeChild(fill);
19504
19505 fill.type = style;
19506 fill.method = 'none';
19507 fill.rotate = true;
19508
19509 var colors = [], color1, color2;
19510
19511 var addColor = function(offset, color$$2){
19512 color$$2 = color.detach(color$$2);
19513 if (color1 == null) color1 = color2 = color$$2;
19514 else color2 = color$$2;
19515 colors.push(offset + ' ' + color$$2[0]);
19516 };
19517
19518 // Enumerate stops, assumes offsets are enumerated in order
19519 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
19520 else for (var offset in stops) addColor(offset, stops[offset]);
19521
19522 fill.color = color1[0];
19523 fill.color2 = color2[0];
19524
19525 //if (fill.colors) fill.colors.value = colors; else
19526 fill.colors = colors;
19527
19528 // Opacity order gets flipped when color stops are specified
19529 fill.opacity = color2[1];
19530 fill['ao:opacity2'] = color1[1];
19531
19532 fill.on = true;
19533 this.element.appendChild(fill);
19534 return fill;
19535 },
19536
19537 _setColor: function(type, color$$2){
19538 var element = type == 'fill' ? this.fillElement : this.strokeElement;
19539 if (color$$2 == null){
19540 element.on = false;
19541 } else {
19542 color$$2 = color.detach(color$$2);
19543 element.color = color$$2[0];
19544 element.opacity = color$$2[1];
19545 element.on = true;
19546 }
19547 },
19548
19549 fill: function(color$$2){
19550 if (arguments.length > 1){
19551 this.fillLinear(arguments);
19552 } else {
19553 this._boxCoords = defaultBox;
19554 var fill = this.fillElement;
19555 fill.type = 'solid';
19556 fill.color2 = '';
19557 fill['ao:opacity2'] = '';
19558 if (fill.colors) fill.colors.value = '';
19559 this._setColor('fill', color$$2);
19560 }
19561 return this;
19562 },
19563
19564 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
19565 var fill = this._createGradient('gradientradial', stops);
19566 if (focusX == null) focusX = this.left + this.width * 0.5;
19567 if (focusY == null) focusY = this.top + this.height * 0.5;
19568 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
19569 if (radiusX == null) radiusX = this.width * 0.5;
19570 if (centerX == null) centerX = focusX;
19571 if (centerY == null) centerY = focusY;
19572
19573 centerX += centerX - focusX;
19574 centerY += centerY - focusY;
19575
19576 var box = this._boxCoords = {
19577 left: centerX - radiusX * 2,
19578 top: centerY - radiusY * 2,
19579 width: radiusX * 4,
19580 height: radiusY * 4
19581 };
19582 focusX -= box.left;
19583 focusY -= box.top;
19584 focusX /= box.width;
19585 focusY /= box.height;
19586
19587 fill.focussize = '0 0';
19588 fill.focusposition = focusX + ',' + focusY;
19589 fill.focus = '50%';
19590
19591 this._transform();
19592
19593 return this;
19594 },
19595
19596 fillLinear: function(stops, x1, y1, x2, y2){
19597 var fill = this._createGradient('gradient', stops);
19598 fill.focus = '100%';
19599 if (arguments.length == 5){
19600 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
19601 this._boxCoords = {
19602 left: Math.min(x1, x2),
19603 top: Math.min(y1, y2),
19604 width: w < 1 ? h : w,
19605 height: h < 1 ? w : h
19606 };
19607 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
19608 } else {
19609 this._boxCoords = null;
19610 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
19611 }
19612 this._transform();
19613 return this;
19614 },
19615
19616 fillImage: function(url, width, height, left, top, color1, color2){
19617 var fill = this.fillElement;
19618 if (color1 != null){
19619 color1 = color.detach(color1);
19620 if (color2 != null) color2 = color.detach(color2);
19621 fill.type = 'pattern';
19622 fill.color = color1[0];
19623 fill.color2 = color2 == null ? color1[0] : color2[0];
19624 fill.opacity = color2 == null ? 0 : color2[1];
19625 fill['ao:opacity2'] = color1[1];
19626 } else {
19627 fill.type = 'tile';
19628 fill.color = '';
19629 fill.color2 = '';
19630 fill.opacity = 1;
19631 fill['ao:opacity2'] = 1;
19632 }
19633 if (fill.colors) fill.colors.value = '';
19634 fill.rotate = true;
19635 fill.src = url;
19636
19637 fill.size = '1,1';
19638 fill.position = '0,0';
19639 fill.origin = '0,0';
19640 fill.aspect = 'ignore'; // ignore, atleast, atmost
19641 fill.on = true;
19642
19643 if (!left) left = 0;
19644 if (!top) top = 0;
19645 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
19646 this._transform();
19647 return this;
19648 },
19649
19650 /* stroke */
19651
19652 stroke: function(color$$2, width, cap, join){
19653 var stroke = this.strokeElement;
19654 this._strokeWidth = (width != null) ? width : 1;
19655 stroke.weight = (width != null) ? width + 'px' : 1;
19656 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
19657 stroke.joinstyle = (join != null) ? join : 'round';
19658
19659 this._setColor('stroke', color$$2);
19660 return this;
19661 }
19662
19663});
19664
19665var precision$2 = 100;
19666
19667var shape$2 = _class(base$2, {
19668
19669 base_initialize: base$2.prototype.initialize,
19670
19671 initialize: function(path, width, height){
19672 this.base_initialize('shape');
19673
19674 var p = this.pathElement = dom.createElement('path');
19675 p.gradientshapeok = true;
19676 this.element.appendChild(p);
19677
19678 this.width = width;
19679 this.height = height;
19680
19681 if (path != null) this.draw(path);
19682 },
19683
19684 // SVG to VML
19685
19686 draw: function(path, width, height){
19687
19688 if (!(path instanceof path$4)) path = new path$4(path);
19689 this._vml = path.toVML();
19690 //this._size = path.measure();
19691
19692 if (width != null) this.width = width;
19693 if (height != null) this.height = height;
19694
19695 if (!this._boxCoords) this._transform();
19696 this._redraw(this._prefix, this._suffix);
19697
19698 return this;
19699 },
19700
19701 // radial gradient workaround
19702
19703 _redraw: function(prefix, suffix){
19704 var vml = this._vml || '';
19705
19706 this._prefix = prefix;
19707 this._suffix = suffix;
19708 if (prefix){
19709 vml = [
19710 prefix, vml, suffix,
19711 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
19712 'ns e', vml, 'nf'
19713 ].join(' ');
19714 }
19715
19716 this.element.path = vml + 'e';
19717 },
19718
19719 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
19720 var fill = this._createGradient('gradientradial', stops);
19721 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
19722 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
19723 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
19724 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
19725 if (centerX == null) centerX = focusX;
19726 if (centerY == null) centerY = focusY;
19727
19728 centerX += centerX - focusX;
19729 centerY += centerY - focusY;
19730
19731 var cx = Math.round(centerX * precision$2),
19732 cy = Math.round(centerY * precision$2),
19733
19734 rx = Math.round(radiusX * 2 * precision$2),
19735 ry = Math.round(radiusY * 2 * precision$2),
19736
19737 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
19738
19739 this._redraw(
19740 // Resolve rendering bug
19741 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
19742 // Draw an ellipse around the path to force an elliptical gradient on any shape
19743 [
19744 'm', cx, cy - ry,
19745 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
19746 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
19747 ].join(' ')
19748 );
19749
19750 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
19751
19752 fill.focusposition = '0.5,0.5';
19753 fill.focussize = '0 0';
19754 fill.focus = '50%';
19755
19756 this._transform();
19757
19758 return this;
19759 }
19760
19761});
19762
19763var group$2 = _class(node$2, container, {
19764
19765 element_initialize: node$2.prototype.initialize,
19766
19767 initialize: function(width, height){
19768 this.element_initialize('group');
19769 this.width = width;
19770 this.height = height;
19771 },
19772
19773 _transform: function(){
19774 var element = this.element;
19775 element.coordorigin = '0,0';
19776 element.coordsize = '1000,1000';
19777 element.style.left = 0;
19778 element.style.top = 0;
19779 element.style.width = 1000;
19780 element.style.height = 1000;
19781 element.style.rotation = 0;
19782
19783 var container$$2 = this.parentNode;
19784 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
19785 var node = this.firstChild;
19786 while (node){
19787 node._transform();
19788 node = node.nextSibling;
19789 }
19790 }
19791
19792});
19793
19794var clippingrectangle$2 = _class(node$2, container, {
19795
19796 element_initialize: node$2.prototype.initialize,
19797
19798 initialize: function(width, height){
19799 this.element_initialize('clippingrectangle');
19800 this.width = width;
19801 this.height = height;
19802 },
19803
19804 _transform: function(){
19805 var element = this.element;
19806 element.clip = true;
19807 element.coordorigin = -this.x + ',' + (-1 * this.y);
19808 element.coordsize = this.width + ',' + this.height;
19809 // IE8 doesn't like clipBottom. Don't ask me why.
19810 // element.style.clipBottom = this.height + this.y;
19811 element.style.clipLeft = this.x;
19812 element.style.clipRight = this.width + this.x;
19813 element.style.clipTop = this.y;
19814 element.style.left = -this.x;
19815 element.style.top = -this.y;
19816 element.style.width = this.width + this.x;
19817 element.style.height = this.height + this.y;
19818 element.style.rotation = 0;
19819
19820 var container$$2 = this.parentNode;
19821 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
19822 var node = this.firstChild;
19823 while (node){
19824 node._transform();
19825 node = node.nextSibling;
19826 }
19827 }
19828
19829});
19830
19831var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
19832
19833var text$2 = _class(base$2, {
19834
19835 base_initialize: base$2.prototype.initialize,
19836
19837 initialize: function(text, font, alignment, path){
19838 this.base_initialize('shape');
19839
19840 var p = this.pathElement = dom.createElement('path');
19841 p.textpathok = true;
19842 this.element.appendChild(p);
19843
19844 p = this.textPathElement = dom.createElement("textpath");
19845 p.on = true;
19846 p.style['v-text-align'] = 'left';
19847 this.element.appendChild(p);
19848
19849 this.draw.apply(this, arguments);
19850 },
19851
19852 draw: function(text, font, alignment, path){
19853 var element = this.element,
19854 textPath = this.textPathElement,
19855 style = textPath.style;
19856
19857 textPath.string = text;
19858
19859 if (font){
19860 if (typeof font == 'string'){
19861 style.font = font;
19862 } else {
19863 for (var key in font){
19864 var ckey = key.camelCase ? key.camelCase() : key;
19865 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
19866 // NOT UNIVERSALLY SUPPORTED OPTIONS
19867 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
19868 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
19869 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
19870 else style[ckey] = font[key];
19871 }
19872 }
19873 }
19874
19875 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
19876
19877 if (path){
19878 this.currentPath = path = new path$4(path);
19879 this.element.path = path.toVML();
19880 } else if (!this.currentPath){
19881 var i = -1, offsetRows = '\n';
19882 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
19883 textPath.string = offsetRows + textPath.string;
19884 this.element.path = 'm0,0l1,0';
19885 }
19886
19887 // Measuring the bounding box is currently necessary for gradients etc.
19888
19889 // Clone element because the element is dead once it has been in the DOM
19890 element = element.cloneNode(true);
19891 style = element.style;
19892
19893 // Reset coordinates while measuring
19894 element.coordorigin = '0,0';
19895 element.coordsize = '10000,10000';
19896 style.left = '0px';
19897 style.top = '0px';
19898 style.width = '10000px';
19899 style.height = '10000px';
19900 style.rotation = 0;
19901 element.removeChild(element.firstChild); // Remove skew
19902
19903 // Inject the clone into the document
19904
19905 var canvas = new surface$2(1, 1),
19906 group = new group$2(), // Wrapping it in a group seems to alleviate some client rect weirdness
19907 body = element.ownerDocument.body;
19908
19909 canvas.inject(body);
19910 group.element.appendChild(element);
19911 group.inject(canvas);
19912
19913 var ebb = element.getBoundingClientRect(),
19914 cbb = canvas.toElement().getBoundingClientRect();
19915
19916 canvas.eject();
19917
19918 this.left = ebb.left - cbb.left;
19919 this.top = ebb.top - cbb.top;
19920 this.width = ebb.right - ebb.left;
19921 this.height = ebb.bottom - ebb.top;
19922 this.right = ebb.right - cbb.left;
19923 this.bottom = ebb.bottom - cbb.top;
19924
19925 this._transform();
19926
19927 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
19928 return this;
19929 }
19930
19931});
19932
19933var fastNoSideEffects = createCommonjsModule(function (module, exports) {
19934var hasCanvas = function(){
19935
19936 var canvas = document.createElement('canvas');
19937 return canvas && !!canvas.getContext;
19938
19939};
19940
19941if (hasCanvas()) {
19942 exports.Surface = surface;
19943 exports.Path = path;
19944 exports.Shape = shape;
19945 exports.Group = group;
19946 exports.ClippingRectangle = clippingrectangle;
19947 exports.Text = text;
19948} else {
19949 exports.Surface = surface$2;
19950 exports.Path = path$4;
19951 exports.Shape = shape$2;
19952 exports.Group = group$2;
19953 exports.ClippingRectangle = clippingrectangle$2;
19954 exports.Text = text$2;
19955
19956 var DOM$$1 = dom;
19957 if (typeof document !== 'undefined') DOM$$1.init(document);
19958}
19959});
19960
19961var fastNoSideEffects_1 = fastNoSideEffects.Surface;
19962var fastNoSideEffects_2 = fastNoSideEffects.Path;
19963var fastNoSideEffects_3 = fastNoSideEffects.Shape;
19964var fastNoSideEffects_4 = fastNoSideEffects.Group;
19965var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
19966var fastNoSideEffects_6 = fastNoSideEffects.Text;
19967
19968current.setCurrent( // Change to 'art/modes/dom' for easier debugging via SVG
19969fastNoSideEffects);
19970/** Declarative fill-type objects; API design not finalized */
19971
19972var slice = Array.prototype.slice;
19973
19974var LinearGradient =
19975/*#__PURE__*/
19976function () {
19977 function LinearGradient(stops, x1, y1, x2, y2) {
19978 this._args = slice.call(arguments);
19979 }
19980
19981 var _proto = LinearGradient.prototype;
19982
19983 _proto.applyFill = function applyFill(node) {
19984 node.fillLinear.apply(node, this._args);
19985 };
19986
19987 return LinearGradient;
19988}();
19989
19990var RadialGradient =
19991/*#__PURE__*/
19992function () {
19993 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
19994 this._args = slice.call(arguments);
19995 }
19996
19997 var _proto2 = RadialGradient.prototype;
19998
19999 _proto2.applyFill = function applyFill(node) {
20000 node.fillRadial.apply(node, this._args);
20001 };
20002
20003 return RadialGradient;
20004}();
20005
20006var Pattern =
20007/*#__PURE__*/
20008function () {
20009 function Pattern(url, width, height, left, top) {
20010 this._args = slice.call(arguments);
20011 }
20012
20013 var _proto3 = Pattern.prototype;
20014
20015 _proto3.applyFill = function applyFill(node) {
20016 node.fillImage.apply(node, this._args);
20017 };
20018
20019 return Pattern;
20020}();
20021/** React Components */
20022
20023
20024var Surface =
20025/*#__PURE__*/
20026function (_React$Component) {
20027 _inheritsLoose(Surface, _React$Component);
20028
20029 function Surface() {
20030 return _React$Component.apply(this, arguments) || this;
20031 }
20032
20033 var _proto4 = Surface.prototype;
20034
20035 _proto4.componentDidMount = function componentDidMount() {
20036 var _this$props = this.props,
20037 height = _this$props.height,
20038 width = _this$props.width;
20039 this._surface = current.Surface(+width, +height, this._tagRef);
20040 this._mountNode = createContainer(this._surface, LegacyRoot, false, null);
20041 updateContainer(this.props.children, this._mountNode, this);
20042 };
20043
20044 _proto4.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
20045 var props = this.props;
20046
20047 if (props.height !== prevProps.height || props.width !== prevProps.width) {
20048 this._surface.resize(+props.width, +props.height);
20049 }
20050
20051 updateContainer(this.props.children, this._mountNode, this);
20052
20053 if (this._surface.render) {
20054 this._surface.render();
20055 }
20056 };
20057
20058 _proto4.componentWillUnmount = function componentWillUnmount() {
20059 updateContainer(null, this._mountNode, this);
20060 };
20061
20062 _proto4.render = function render() {
20063 var _this = this;
20064
20065 // This is going to be a placeholder because we don't know what it will
20066 // actually resolve to because ART may render canvas, vml or svg tags here.
20067 // We only allow a subset of properties since others might conflict with
20068 // ART's properties.
20069 var props = this.props; // TODO: ART's Canvas Mode overrides surface title and cursor
20070
20071 var Tag = current.Surface.tagName;
20072 return React.createElement(Tag, {
20073 ref: function (ref) {
20074 return _this._tagRef = ref;
20075 },
20076 accessKey: props.accessKey,
20077 className: props.className,
20078 draggable: props.draggable,
20079 role: props.role,
20080 style: props.style,
20081 tabIndex: props.tabIndex,
20082 title: props.title
20083 });
20084 };
20085
20086 return Surface;
20087}(React.Component);
20088
20089var Text =
20090/*#__PURE__*/
20091function (_React$Component2) {
20092 _inheritsLoose(Text, _React$Component2);
20093
20094 function Text(props) {
20095 var _this2;
20096
20097 _this2 = _React$Component2.call(this, props) || this; // We allow reading these props. Ideally we could expose the Text node as
20098 // ref directly.
20099
20100 ['height', 'width', 'x', 'y'].forEach(function (key) {
20101 Object.defineProperty(_assertThisInitialized(_this2), key, {
20102 get: function () {
20103 return this._text ? this._text[key] : undefined;
20104 }
20105 });
20106 });
20107 return _this2;
20108 }
20109
20110 var _proto5 = Text.prototype;
20111
20112 _proto5.render = function render() {
20113 var _this3 = this;
20114
20115 // This means you can't have children that render into strings...
20116 var T = TYPES.TEXT;
20117 return React.createElement(T, _extends({}, this.props, {
20118 ref: function (t) {
20119 return _this3._text = t;
20120 }
20121 }), childrenAsString(this.props.children));
20122 };
20123
20124 return Text;
20125}(React.Component);
20126
20127injectIntoDevTools({
20128 findFiberByHostInstance: function () {
20129 return null;
20130 },
20131 bundleType: 1,
20132 version: ReactVersion,
20133 rendererPackageName: 'react-art'
20134});
20135/** API */
20136
20137var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
20138var Group = TYPES.GROUP;
20139var Shape = TYPES.SHAPE;
20140var Path = current.Path;
20141
20142
20143var ReactART = Object.freeze({
20144 ClippingRectangle: ClippingRectangle,
20145 Group: Group,
20146 Shape: Shape,
20147 Path: Path,
20148 LinearGradient: LinearGradient,
20149 Pattern: Pattern,
20150 RadialGradient: RadialGradient,
20151 Surface: Surface,
20152 Text: Text,
20153 Transform: transform
20154});
20155
20156var reactArt = ReactART;
20157
20158return reactArt;
20159
20160})));