UNPKG

632 kBJavaScriptView Raw
1/** @license React v16.13.0
2 * react-art.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global = global || self, global.ReactART = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18 function _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
36 function _inheritsLoose(subClass, superClass) {
37 subClass.prototype = Object.create(superClass.prototype);
38 subClass.prototype.constructor = subClass;
39 subClass.__proto__ = superClass;
40 }
41
42 function _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 var ReactVersion = '16.13.0';
51
52 var LegacyRoot = 0;
53 var BlockingRoot = 1;
54 var ConcurrentRoot = 2;
55
56 var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
57 var _assign = ReactInternals.assign;
58
59 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
60 // Current owner and dispatcher used to share the same ref,
61 // but PR #14548 split them out to better support the react-debug-tools package.
62
63 if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
64 ReactSharedInternals.ReactCurrentDispatcher = {
65 current: null
66 };
67 }
68
69 if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
70 ReactSharedInternals.ReactCurrentBatchConfig = {
71 suspense: null
72 };
73 }
74
75 // by calls to these methods by a Babel plugin.
76 //
77 // In PROD (or in packages without access to React internals),
78 // they are left as they are instead.
79
80 function warn(format) {
81 {
82 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
83 args[_key - 1] = arguments[_key];
84 }
85
86 printWarning('warn', format, args);
87 }
88 }
89 function error(format) {
90 {
91 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
92 args[_key2 - 1] = arguments[_key2];
93 }
94
95 printWarning('error', format, args);
96 }
97 }
98
99 function printWarning(level, format, args) {
100 // When changing this logic, you might want to also
101 // update consoleWithStackDev.www.js as well.
102 {
103 var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
104
105 if (!hasExistingStack) {
106 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
107 var stack = ReactDebugCurrentFrame.getStackAddendum();
108
109 if (stack !== '') {
110 format += '%s';
111 args = args.concat([stack]);
112 }
113 }
114
115 var argsWithFormat = args.map(function (item) {
116 return '' + item;
117 }); // Careful: RN currently depends on this prefix
118
119 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
120 // breaks IE9: https://github.com/facebook/react/issues/13610
121 // eslint-disable-next-line react-internal/no-production-logging
122
123 Function.prototype.apply.call(console[level], console, argsWithFormat);
124
125 try {
126 // --- Welcome to debugging React ---
127 // This error was thrown as a convenience so that you can use this stack
128 // to find the callsite that caused this warning to fire.
129 var argIndex = 0;
130 var message = 'Warning: ' + format.replace(/%s/g, function () {
131 return args[argIndex++];
132 });
133 throw new Error(message);
134 } catch (x) {}
135 }
136 }
137
138 var FunctionComponent = 0;
139 var ClassComponent = 1;
140 var IndeterminateComponent = 2; // Before we know whether it is function or class
141
142 var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
143
144 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
145
146 var HostComponent = 5;
147 var HostText = 6;
148 var Fragment = 7;
149 var Mode = 8;
150 var ContextConsumer = 9;
151 var ContextProvider = 10;
152 var ForwardRef = 11;
153 var Profiler = 12;
154 var SuspenseComponent = 13;
155 var MemoComponent = 14;
156 var SimpleMemoComponent = 15;
157 var LazyComponent = 16;
158 var IncompleteClassComponent = 17;
159 var DehydratedFragment = 18;
160 var SuspenseListComponent = 19;
161 var FundamentalComponent = 20;
162 var ScopeComponent = 21;
163 var Block = 22;
164
165 /**
166 * `ReactInstanceMap` maintains a mapping from a public facing stateful
167 * instance (key) and the internal representation (value). This allows public
168 * methods to accept the user facing instance as an argument and map them back
169 * to internal methods.
170 *
171 * Note that this module is currently shared and assumed to be stateless.
172 * If this becomes an actual Map, that will break.
173 */
174 function get(key) {
175 return key._reactInternalFiber;
176 }
177 function set(key, value) {
178 key._reactInternalFiber = value;
179 }
180
181 // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
182 // nor polyfill, then a plain number is used for performance.
183 var hasSymbol = typeof Symbol === 'function' && Symbol.for;
184 var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
185 var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
186 var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
187 var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
188 var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
189 var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
190 var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
191 var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
192 var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
193 var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
194 var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
195 var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
196 var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
197 var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
198 var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
199 var FAUX_ITERATOR_SYMBOL = '@@iterator';
200 function getIteratorFn(maybeIterable) {
201 if (maybeIterable === null || typeof maybeIterable !== 'object') {
202 return null;
203 }
204
205 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
206
207 if (typeof maybeIterator === 'function') {
208 return maybeIterator;
209 }
210
211 return null;
212 }
213
214 var Uninitialized = -1;
215 var Pending = 0;
216 var Resolved = 1;
217 var Rejected = 2;
218 function refineResolvedLazyComponent(lazyComponent) {
219 return lazyComponent._status === Resolved ? lazyComponent._result : null;
220 }
221 function initializeLazyComponentType(lazyComponent) {
222 if (lazyComponent._status === Uninitialized) {
223 lazyComponent._status = Pending;
224 var ctor = lazyComponent._ctor;
225 var thenable = ctor();
226 lazyComponent._result = thenable;
227 thenable.then(function (moduleObject) {
228 if (lazyComponent._status === Pending) {
229 var defaultExport = moduleObject.default;
230
231 {
232 if (defaultExport === undefined) {
233 error('lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
234 }
235 }
236
237 lazyComponent._status = Resolved;
238 lazyComponent._result = defaultExport;
239 }
240 }, function (error) {
241 if (lazyComponent._status === Pending) {
242 lazyComponent._status = Rejected;
243 lazyComponent._result = error;
244 }
245 });
246 }
247 }
248
249 function getWrappedName(outerType, innerType, wrapperName) {
250 var functionName = innerType.displayName || innerType.name || '';
251 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
252 }
253
254 function getComponentName(type) {
255 if (type == null) {
256 // Host root, text node or just invalid type.
257 return null;
258 }
259
260 {
261 if (typeof type.tag === 'number') {
262 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
263 }
264 }
265
266 if (typeof type === 'function') {
267 return type.displayName || type.name || null;
268 }
269
270 if (typeof type === 'string') {
271 return type;
272 }
273
274 switch (type) {
275 case REACT_FRAGMENT_TYPE:
276 return 'Fragment';
277
278 case REACT_PORTAL_TYPE:
279 return 'Portal';
280
281 case REACT_PROFILER_TYPE:
282 return "Profiler";
283
284 case REACT_STRICT_MODE_TYPE:
285 return 'StrictMode';
286
287 case REACT_SUSPENSE_TYPE:
288 return 'Suspense';
289
290 case REACT_SUSPENSE_LIST_TYPE:
291 return 'SuspenseList';
292 }
293
294 if (typeof type === 'object') {
295 switch (type.$$typeof) {
296 case REACT_CONTEXT_TYPE:
297 return 'Context.Consumer';
298
299 case REACT_PROVIDER_TYPE:
300 return 'Context.Provider';
301
302 case REACT_FORWARD_REF_TYPE:
303 return getWrappedName(type, type.render, 'ForwardRef');
304
305 case REACT_MEMO_TYPE:
306 return getComponentName(type.type);
307
308 case REACT_BLOCK_TYPE:
309 return getComponentName(type.render);
310
311 case REACT_LAZY_TYPE:
312 {
313 var thenable = type;
314 var resolvedThenable = refineResolvedLazyComponent(thenable);
315
316 if (resolvedThenable) {
317 return getComponentName(resolvedThenable);
318 }
319
320 break;
321 }
322 }
323 }
324
325 return null;
326 }
327
328 // Don't change these two values. They're used by React Dev Tools.
329 var NoEffect =
330 /* */
331 0;
332 var PerformedWork =
333 /* */
334 1; // You can change the rest (and add more).
335
336 var Placement =
337 /* */
338 2;
339 var Update =
340 /* */
341 4;
342 var PlacementAndUpdate =
343 /* */
344 6;
345 var Deletion =
346 /* */
347 8;
348 var ContentReset =
349 /* */
350 16;
351 var Callback =
352 /* */
353 32;
354 var DidCapture =
355 /* */
356 64;
357 var Ref =
358 /* */
359 128;
360 var Snapshot =
361 /* */
362 256;
363 var Passive =
364 /* */
365 512;
366 var Hydrating =
367 /* */
368 1024;
369 var HydratingAndUpdate =
370 /* */
371 1028; // Passive & Update & Callback & Ref & Snapshot
372
373 var LifecycleEffectMask =
374 /* */
375 932; // Union of all host effects
376
377 var HostEffectMask =
378 /* */
379 2047;
380 var Incomplete =
381 /* */
382 2048;
383 var ShouldCapture =
384 /* */
385 4096;
386
387 var enableProfilerTimer = true; // Trace which interactions trigger each commit.
388
389 var enableFundamentalAPI = false; // Experimental Scope support.
390 var warnAboutStringRefs = false;
391
392 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
393 function getNearestMountedFiber(fiber) {
394 var node = fiber;
395 var nearestMounted = fiber;
396
397 if (!fiber.alternate) {
398 // If there is no alternate, this might be a new tree that isn't inserted
399 // yet. If it is, then it will have a pending insertion effect on it.
400 var nextNode = node;
401
402 do {
403 node = nextNode;
404
405 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
406 // This is an insertion or in-progress hydration. The nearest possible
407 // mounted fiber is the parent but we need to continue to figure out
408 // if that one is still mounted.
409 nearestMounted = node.return;
410 }
411
412 nextNode = node.return;
413 } while (nextNode);
414 } else {
415 while (node.return) {
416 node = node.return;
417 }
418 }
419
420 if (node.tag === HostRoot) {
421 // TODO: Check if this was a nested HostRoot when used with
422 // renderContainerIntoSubtree.
423 return nearestMounted;
424 } // If we didn't hit the root, that means that we're in an disconnected tree
425 // that has been unmounted.
426
427
428 return null;
429 }
430 function isFiberMounted(fiber) {
431 return getNearestMountedFiber(fiber) === fiber;
432 }
433 function isMounted(component) {
434 {
435 var owner = ReactCurrentOwner.current;
436
437 if (owner !== null && owner.tag === ClassComponent) {
438 var ownerFiber = owner;
439 var instance = ownerFiber.stateNode;
440
441 if (!instance._warnedAboutRefsInRender) {
442 error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component');
443 }
444
445 instance._warnedAboutRefsInRender = true;
446 }
447 }
448
449 var fiber = get(component);
450
451 if (!fiber) {
452 return false;
453 }
454
455 return getNearestMountedFiber(fiber) === fiber;
456 }
457
458 function assertIsMounted(fiber) {
459 if (!(getNearestMountedFiber(fiber) === fiber)) {
460 {
461 throw Error( "Unable to find node on an unmounted component." );
462 }
463 }
464 }
465
466 function findCurrentFiberUsingSlowPath(fiber) {
467 var alternate = fiber.alternate;
468
469 if (!alternate) {
470 // If there is no alternate, then we only need to check if it is mounted.
471 var nearestMounted = getNearestMountedFiber(fiber);
472
473 if (!(nearestMounted !== null)) {
474 {
475 throw Error( "Unable to find node on an unmounted component." );
476 }
477 }
478
479 if (nearestMounted !== fiber) {
480 return null;
481 }
482
483 return fiber;
484 } // If we have two possible branches, we'll walk backwards up to the root
485 // to see what path the root points to. On the way we may hit one of the
486 // special cases and we'll deal with them.
487
488
489 var a = fiber;
490 var b = alternate;
491
492 while (true) {
493 var parentA = a.return;
494
495 if (parentA === null) {
496 // We're at the root.
497 break;
498 }
499
500 var parentB = parentA.alternate;
501
502 if (parentB === null) {
503 // There is no alternate. This is an unusual case. Currently, it only
504 // happens when a Suspense component is hidden. An extra fragment fiber
505 // is inserted in between the Suspense fiber and its children. Skip
506 // over this extra fragment fiber and proceed to the next parent.
507 var nextParent = parentA.return;
508
509 if (nextParent !== null) {
510 a = b = nextParent;
511 continue;
512 } // If there's no parent, we're at the root.
513
514
515 break;
516 } // If both copies of the parent fiber point to the same child, we can
517 // assume that the child is current. This happens when we bailout on low
518 // priority: the bailed out fiber's child reuses the current child.
519
520
521 if (parentA.child === parentB.child) {
522 var child = parentA.child;
523
524 while (child) {
525 if (child === a) {
526 // We've determined that A is the current branch.
527 assertIsMounted(parentA);
528 return fiber;
529 }
530
531 if (child === b) {
532 // We've determined that B is the current branch.
533 assertIsMounted(parentA);
534 return alternate;
535 }
536
537 child = child.sibling;
538 } // We should never have an alternate for any mounting node. So the only
539 // way this could possibly happen is if this was unmounted, if at all.
540
541
542 {
543 {
544 throw Error( "Unable to find node on an unmounted component." );
545 }
546 }
547 }
548
549 if (a.return !== b.return) {
550 // The return pointer of A and the return pointer of B point to different
551 // fibers. We assume that return pointers never criss-cross, so A must
552 // belong to the child set of A.return, and B must belong to the child
553 // set of B.return.
554 a = parentA;
555 b = parentB;
556 } else {
557 // The return pointers point to the same fiber. We'll have to use the
558 // default, slow path: scan the child sets of each parent alternate to see
559 // which child belongs to which set.
560 //
561 // Search parent A's child set
562 var didFindChild = false;
563 var _child = parentA.child;
564
565 while (_child) {
566 if (_child === a) {
567 didFindChild = true;
568 a = parentA;
569 b = parentB;
570 break;
571 }
572
573 if (_child === b) {
574 didFindChild = true;
575 b = parentA;
576 a = parentB;
577 break;
578 }
579
580 _child = _child.sibling;
581 }
582
583 if (!didFindChild) {
584 // Search parent B's child set
585 _child = parentB.child;
586
587 while (_child) {
588 if (_child === a) {
589 didFindChild = true;
590 a = parentB;
591 b = parentA;
592 break;
593 }
594
595 if (_child === b) {
596 didFindChild = true;
597 b = parentB;
598 a = parentA;
599 break;
600 }
601
602 _child = _child.sibling;
603 }
604
605 if (!didFindChild) {
606 {
607 throw Error( "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." );
608 }
609 }
610 }
611 }
612
613 if (!(a.alternate === b)) {
614 {
615 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
616 }
617 }
618 } // If the root is not a host container, we're in a disconnected tree. I.e.
619 // unmounted.
620
621
622 if (!(a.tag === HostRoot)) {
623 {
624 throw Error( "Unable to find node on an unmounted component." );
625 }
626 }
627
628 if (a.stateNode.current === a) {
629 // We've determined that A is the current branch.
630 return fiber;
631 } // Otherwise B has to be current branch.
632
633
634 return alternate;
635 }
636 function findCurrentHostFiber(parent) {
637 var currentParent = findCurrentFiberUsingSlowPath(parent);
638
639 if (!currentParent) {
640 return null;
641 } // Next we'll drill down this component to find the first HostComponent/Text.
642
643
644 var node = currentParent;
645
646 while (true) {
647 if (node.tag === HostComponent || node.tag === HostText) {
648 return node;
649 } else if (node.child) {
650 node.child.return = node;
651 node = node.child;
652 continue;
653 }
654
655 if (node === currentParent) {
656 return null;
657 }
658
659 while (!node.sibling) {
660 if (!node.return || node.return === currentParent) {
661 return null;
662 }
663
664 node = node.return;
665 }
666
667 node.sibling.return = node.return;
668 node = node.sibling;
669 } // Flow needs the return null here, but ESLint complains about it.
670 // eslint-disable-next-line no-unreachable
671
672
673 return null;
674 }
675
676 var _class = function(mixins){
677 var proto = {};
678 for (var i = 0, l = arguments.length; i < l; i++){
679 var mixin = arguments[i];
680 if (typeof mixin == 'function') mixin = mixin.prototype;
681 for (var key in mixin) proto[key] = mixin[key];
682 }
683 if (!proto.initialize) proto.initialize = function(){};
684 proto.constructor = function(a,b,c,d,e,f,g,h){
685 return new proto.initialize(a,b,c,d,e,f,g,h);
686 };
687 proto.constructor.prototype = proto.initialize.prototype = proto;
688 return proto.constructor;
689 };
690
691 function Transform(xx, yx, xy, yy, x, y){
692 if (xx && typeof xx == 'object'){
693 yx = xx.yx; yy = xx.yy; y = xx.y;
694 xy = xx.xy; x = xx.x; xx = xx.xx;
695 }
696 this.xx = xx == null ? 1 : xx;
697 this.yx = yx || 0;
698 this.xy = xy || 0;
699 this.yy = yy == null ? 1 : yy;
700 this.x = (x == null ? this.x : x) || 0;
701 this.y = (y == null ? this.y : y) || 0;
702 this._transform();
703 return this;
704 }
705 var transform = _class({
706
707 initialize: Transform,
708
709 _transform: function(){},
710
711 xx: 1, yx: 0, x: 0,
712 xy: 0, yy: 1, y: 0,
713
714 transform: function(xx, yx, xy, yy, x, y){
715 var m = this;
716 if (xx && typeof xx == 'object'){
717 yx = xx.yx; yy = xx.yy; y = xx.y;
718 xy = xx.xy; x = xx.x; xx = xx.xx;
719 }
720 if (!x) x = 0;
721 if (!y) y = 0;
722 return this.transformTo(
723 m.xx * xx + m.xy * yx,
724 m.yx * xx + m.yy * yx,
725 m.xx * xy + m.xy * yy,
726 m.yx * xy + m.yy * yy,
727 m.xx * x + m.xy * y + m.x,
728 m.yx * x + m.yy * y + m.y
729 );
730 },
731
732 transformTo: Transform,
733
734 translate: function(x, y){
735 return this.transform(1, 0, 0, 1, x, y);
736 },
737
738 move: function(x, y){
739 this.x += x || 0;
740 this.y += y || 0;
741 this._transform();
742 return this;
743 },
744
745 scale: function(x, y){
746 if (y == null) y = x;
747 return this.transform(x, 0, 0, y, 0, 0);
748 },
749
750 rotate: function(deg, x, y){
751 if (x == null || y == null){
752 x = (this.left || 0) + (this.width || 0) / 2;
753 y = (this.top || 0) + (this.height || 0) / 2;
754 }
755
756 var rad = deg * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
757
758 this.transform(1, 0, 0, 1, x, y);
759 var m = this;
760
761 return this.transformTo(
762 cos * m.xx - sin * m.yx,
763 sin * m.xx + cos * m.yx,
764 cos * m.xy - sin * m.yy,
765 sin * m.xy + cos * m.yy,
766 m.x,
767 m.y
768 ).transform(1, 0, 0, 1, -x, -y);
769 },
770
771 moveTo: function(x, y){
772 var m = this;
773 return this.transformTo(m.xx, m.yx, m.xy, m.yy, x, y);
774 },
775
776 rotateTo: function(deg, x, y){
777 var m = this;
778 var flip = m.yx / m.xx > m.yy / m.xy ? -1 : 1;
779 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = -flip;
780 return this.rotate(deg - Math.atan2(flip * m.yx, flip * m.xx) * 180 / Math.PI, x, y);
781 },
782
783 scaleTo: function(x, y){
784 // Normalize
785 var m = this;
786
787 var h = Math.sqrt(m.xx * m.xx + m.yx * m.yx);
788 m.xx /= h; m.yx /= h;
789
790 h = Math.sqrt(m.yy * m.yy + m.xy * m.xy);
791 m.yy /= h; m.xy /= h;
792
793 return this.scale(x, y);
794 },
795
796 resizeTo: function(width, height){
797 var w = this.width, h = this.height;
798 if (!w || !h) return this;
799 return this.scaleTo(width / w, height / h);
800 },
801
802 /*
803 inverse: function(){
804 var a = this.xx, b = this.yx,
805 c = this.xy, d = this.yy,
806 e = this.x, f = this.y;
807 if (a * d - b * c == 0) return null;
808 return new Transform(
809 d/(a * d-b * c), b/(b * c-a * d),
810 c/(b * c-a * d), a/(a * d-b * c),
811 (d * e-c * f)/(b * c-a * d), (b * e-a * f)/(a * d-b * c)
812 );
813 },
814 */
815
816 inversePoint: function(x, y){
817 var a = this.xx, b = this.yx,
818 c = this.xy, d = this.yy,
819 e = this.x, f = this.y;
820 var det = b * c - a * d;
821 if (det == 0) return null;
822 return {
823 x: (d * (e - x) + c * (y - f)) / det,
824 y: (a * (f - y) + b * (x - e)) / det
825 };
826 },
827
828 point: function(x, y){
829 var m = this;
830 return {
831 x: m.xx * x + m.xy * y + m.x,
832 y: m.yx * x + m.yy * y + m.y
833 };
834 }
835
836 });
837
838 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
839
840 function createCommonjsModule(fn, module) {
841 return module = { exports: {} }, fn(module, module.exports), module.exports;
842 }
843
844 var current = createCommonjsModule(function (module, exports) {
845 function warning(){
846 throw new Error('You must require a mode before requiring anything else.');
847 }
848
849 exports.Surface = warning;
850 exports.Path = warning;
851 exports.Shape = warning;
852 exports.Group = warning;
853 exports.ClippingRectangle = warning;
854 exports.Text = warning;
855
856 exports.setCurrent = function(mode){
857 for (var key in mode){
858 exports[key] = mode[key];
859 }
860 };
861 });
862 var current_1 = current.Surface;
863 var current_2 = current.Path;
864 var current_3 = current.Shape;
865 var current_4 = current.Group;
866 var current_5 = current.ClippingRectangle;
867 var current_6 = current.Text;
868 var current_7 = current.setCurrent;
869
870 var TYPES = {
871 CLIPPING_RECTANGLE: 'ClippingRectangle',
872 GROUP: 'Group',
873 SHAPE: 'Shape',
874 TEXT: 'Text'
875 };
876 var EVENT_TYPES = {
877 onClick: 'click',
878 onMouseMove: 'mousemove',
879 onMouseOver: 'mouseover',
880 onMouseOut: 'mouseout',
881 onMouseUp: 'mouseup',
882 onMouseDown: 'mousedown'
883 };
884 function childrenAsString(children) {
885 if (!children) {
886 return '';
887 } else if (typeof children === 'string') {
888 return children;
889 } else if (children.length) {
890 return children.join('');
891 } else {
892 return '';
893 }
894 }
895
896 // can re-export everything from this module.
897
898 function shim() {
899 {
900 {
901 throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." );
902 }
903 }
904 } // Hydration (when unsupported)
905 var isSuspenseInstancePending = shim;
906 var isSuspenseInstanceFallback = shim;
907 var hydrateTextInstance = shim;
908
909 var pooledTransform = new transform();
910 var NO_CONTEXT = {};
911 var UPDATE_SIGNAL = {};
912
913 {
914 Object.freeze(NO_CONTEXT);
915 Object.freeze(UPDATE_SIGNAL);
916 }
917 /** Helper Methods */
918
919
920 function addEventListeners(instance, type, listener) {
921 // We need to explicitly unregister before unmount.
922 // For this reason we need to track subscriptions.
923 if (!instance._listeners) {
924 instance._listeners = {};
925 instance._subscriptions = {};
926 }
927
928 instance._listeners[type] = listener;
929
930 if (listener) {
931 if (!instance._subscriptions[type]) {
932 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
933 }
934 } else {
935 if (instance._subscriptions[type]) {
936 instance._subscriptions[type]();
937
938 delete instance._subscriptions[type];
939 }
940 }
941 }
942
943 function createEventHandler(instance) {
944 return function handleEvent(event) {
945 var listener = instance._listeners[event.type];
946
947 if (!listener) ; else if (typeof listener === 'function') {
948 listener.call(instance, event);
949 } else if (listener.handleEvent) {
950 listener.handleEvent(event);
951 }
952 };
953 }
954
955 function destroyEventListeners(instance) {
956 if (instance._subscriptions) {
957 for (var type in instance._subscriptions) {
958 instance._subscriptions[type]();
959 }
960 }
961
962 instance._subscriptions = null;
963 instance._listeners = null;
964 }
965
966 function getScaleX(props) {
967 if (props.scaleX != null) {
968 return props.scaleX;
969 } else if (props.scale != null) {
970 return props.scale;
971 } else {
972 return 1;
973 }
974 }
975
976 function getScaleY(props) {
977 if (props.scaleY != null) {
978 return props.scaleY;
979 } else if (props.scale != null) {
980 return props.scale;
981 } else {
982 return 1;
983 }
984 }
985
986 function isSameFont(oldFont, newFont) {
987 if (oldFont === newFont) {
988 return true;
989 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
990 return false;
991 } else {
992 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
993 }
994 }
995 /** Render Methods */
996
997
998 function applyClippingRectangleProps(instance, props) {
999 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1000 applyNodeProps(instance, props, prevProps);
1001 instance.width = props.width;
1002 instance.height = props.height;
1003 }
1004
1005 function applyGroupProps(instance, props) {
1006 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1007 applyNodeProps(instance, props, prevProps);
1008 instance.width = props.width;
1009 instance.height = props.height;
1010 }
1011
1012 function applyNodeProps(instance, props) {
1013 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1014 var scaleX = getScaleX(props);
1015 var scaleY = getScaleY(props);
1016 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);
1017
1018 if (props.transform != null) {
1019 pooledTransform.transform(props.transform);
1020 }
1021
1022 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) {
1023 instance.transformTo(pooledTransform);
1024 }
1025
1026 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
1027 instance.indicate(props.cursor, props.title);
1028 }
1029
1030 if (instance.blend && props.opacity !== prevProps.opacity) {
1031 instance.blend(props.opacity == null ? 1 : props.opacity);
1032 }
1033
1034 if (props.visible !== prevProps.visible) {
1035 if (props.visible == null || props.visible) {
1036 instance.show();
1037 } else {
1038 instance.hide();
1039 }
1040 }
1041
1042 for (var type in EVENT_TYPES) {
1043 addEventListeners(instance, EVENT_TYPES[type], props[type]);
1044 }
1045 }
1046
1047 function applyRenderableNodeProps(instance, props) {
1048 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1049 applyNodeProps(instance, props, prevProps);
1050
1051 if (prevProps.fill !== props.fill) {
1052 if (props.fill && props.fill.applyFill) {
1053 props.fill.applyFill(instance);
1054 } else {
1055 instance.fill(props.fill);
1056 }
1057 }
1058
1059 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.
1060 prevProps.strokeDash !== props.strokeDash) {
1061 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
1062 }
1063 }
1064
1065 function applyShapeProps(instance, props) {
1066 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1067 applyRenderableNodeProps(instance, props, prevProps);
1068 var path = props.d || childrenAsString(props.children);
1069 var prevDelta = instance._prevDelta;
1070 var prevPath = instance._prevPath;
1071
1072 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
1073 instance.draw(path, props.width, props.height);
1074 instance._prevDelta = path.delta;
1075 instance._prevPath = path;
1076 }
1077 }
1078
1079 function applyTextProps(instance, props) {
1080 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1081 applyRenderableNodeProps(instance, props, prevProps);
1082 var string = props.children;
1083
1084 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
1085 instance.draw(string, props.font, props.alignment, props.path);
1086 instance._currentString = string;
1087 }
1088 }
1089 function appendInitialChild(parentInstance, child) {
1090 if (typeof child === 'string') {
1091 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
1092 {
1093 {
1094 throw Error( "Text children should already be flattened." );
1095 }
1096 }
1097 }
1098
1099 child.inject(parentInstance);
1100 }
1101 function createInstance(type, props, internalInstanceHandle) {
1102 var instance;
1103
1104 switch (type) {
1105 case TYPES.CLIPPING_RECTANGLE:
1106 instance = current.ClippingRectangle();
1107 instance._applyProps = applyClippingRectangleProps;
1108 break;
1109
1110 case TYPES.GROUP:
1111 instance = current.Group();
1112 instance._applyProps = applyGroupProps;
1113 break;
1114
1115 case TYPES.SHAPE:
1116 instance = current.Shape();
1117 instance._applyProps = applyShapeProps;
1118 break;
1119
1120 case TYPES.TEXT:
1121 instance = current.Text(props.children, props.font, props.alignment, props.path);
1122 instance._applyProps = applyTextProps;
1123 break;
1124 }
1125
1126 if (!instance) {
1127 {
1128 throw Error( "ReactART does not support the type \"" + type + "\"" );
1129 }
1130 }
1131
1132 instance._applyProps(instance, props);
1133
1134 return instance;
1135 }
1136 function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
1137 return text;
1138 }
1139 function getPublicInstance(instance) {
1140 return instance;
1141 }
1142 function prepareForCommit() {// Noop
1143 }
1144 function prepareUpdate(domElement, type, oldProps, newProps) {
1145 return UPDATE_SIGNAL;
1146 }
1147 function resetAfterCommit() {// Noop
1148 }
1149 function resetTextContent(domElement) {// Noop
1150 }
1151 function shouldDeprioritizeSubtree(type, props) {
1152 return false;
1153 }
1154 function getRootHostContext() {
1155 return NO_CONTEXT;
1156 }
1157 function getChildHostContext() {
1158 return NO_CONTEXT;
1159 }
1160 var scheduleTimeout = setTimeout;
1161 var cancelTimeout = clearTimeout;
1162 var noTimeout = -1;
1163 function shouldSetTextContent(type, props) {
1164 return typeof props.children === 'string' || typeof props.children === 'number';
1165 } // The ART renderer is secondary to the React DOM renderer.
1166 function appendChild(parentInstance, child) {
1167 if (child.parentNode === parentInstance) {
1168 child.eject();
1169 }
1170
1171 child.inject(parentInstance);
1172 }
1173 function appendChildToContainer(parentInstance, child) {
1174 if (child.parentNode === parentInstance) {
1175 child.eject();
1176 }
1177
1178 child.inject(parentInstance);
1179 }
1180 function insertBefore(parentInstance, child, beforeChild) {
1181 if (!(child !== beforeChild)) {
1182 {
1183 throw Error( "ReactART: Can not insert node before itself" );
1184 }
1185 }
1186
1187 child.injectBefore(beforeChild);
1188 }
1189 function insertInContainerBefore(parentInstance, child, beforeChild) {
1190 if (!(child !== beforeChild)) {
1191 {
1192 throw Error( "ReactART: Can not insert node before itself" );
1193 }
1194 }
1195
1196 child.injectBefore(beforeChild);
1197 }
1198 function removeChild(parentInstance, child) {
1199 destroyEventListeners(child);
1200 child.eject();
1201 }
1202 function removeChildFromContainer(parentInstance, child) {
1203 destroyEventListeners(child);
1204 child.eject();
1205 }
1206 function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1207 instance._applyProps(instance, newProps, oldProps);
1208 }
1209 function hideInstance(instance) {
1210 instance.hide();
1211 }
1212 function unhideInstance(instance, props) {
1213 if (props.visible == null || props.visible) {
1214 instance.show();
1215 }
1216 }
1217 function unhideTextInstance(textInstance, text) {// Noop
1218 }
1219
1220 /**
1221 * Copyright (c) 2013-present, Facebook, Inc.
1222 *
1223 * This source code is licensed under the MIT license found in the
1224 * LICENSE file in the root directory of this source tree.
1225 */
1226
1227 var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1228
1229 var ReactPropTypesSecret_1 = ReactPropTypesSecret;
1230
1231 var printWarning$1 = function() {};
1232
1233 {
1234 var ReactPropTypesSecret$1 = ReactPropTypesSecret_1;
1235 var loggedTypeFailures = {};
1236 var has = Function.call.bind(Object.prototype.hasOwnProperty);
1237
1238 printWarning$1 = function(text) {
1239 var message = 'Warning: ' + text;
1240 if (typeof console !== 'undefined') {
1241 console.error(message);
1242 }
1243 try {
1244 // --- Welcome to debugging React ---
1245 // This error was thrown as a convenience so that you can use this stack
1246 // to find the callsite that caused this warning to fire.
1247 throw new Error(message);
1248 } catch (x) {}
1249 };
1250 }
1251
1252 /**
1253 * Assert that the values match with the type specs.
1254 * Error messages are memorized and will only be shown once.
1255 *
1256 * @param {object} typeSpecs Map of name to a ReactPropType
1257 * @param {object} values Runtime values that need to be type-checked
1258 * @param {string} location e.g. "prop", "context", "child context"
1259 * @param {string} componentName Name of the component for error messages.
1260 * @param {?Function} getStack Returns the component stack.
1261 * @private
1262 */
1263 function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1264 {
1265 for (var typeSpecName in typeSpecs) {
1266 if (has(typeSpecs, typeSpecName)) {
1267 var error;
1268 // Prop type validation may throw. In case they do, we don't want to
1269 // fail the render phase where it didn't fail before. So we log it.
1270 // After these have been cleaned up, we'll let them throw.
1271 try {
1272 // This is intentionally an invariant that gets caught. It's the same
1273 // behavior as without this statement except with a better message.
1274 if (typeof typeSpecs[typeSpecName] !== 'function') {
1275 var err = Error(
1276 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1277 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1278 );
1279 err.name = 'Invariant Violation';
1280 throw err;
1281 }
1282 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret$1);
1283 } catch (ex) {
1284 error = ex;
1285 }
1286 if (error && !(error instanceof Error)) {
1287 printWarning$1(
1288 (componentName || 'React class') + ': type specification of ' +
1289 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1290 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1291 'You may have forgotten to pass an argument to the type checker ' +
1292 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1293 'shape all require an argument).'
1294 );
1295 }
1296 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1297 // Only monitor this failure once because there tends to be a lot of the
1298 // same error.
1299 loggedTypeFailures[error.message] = true;
1300
1301 var stack = getStack ? getStack() : '';
1302
1303 printWarning$1(
1304 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1305 );
1306 }
1307 }
1308 }
1309 }
1310 }
1311
1312 /**
1313 * Resets warning cache when testing.
1314 *
1315 * @private
1316 */
1317 checkPropTypes.resetWarningCache = function() {
1318 {
1319 loggedTypeFailures = {};
1320 }
1321 };
1322
1323 var checkPropTypes_1 = checkPropTypes;
1324
1325 var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1326 function describeComponentFrame (name, source, ownerName) {
1327 var sourceInfo = '';
1328
1329 if (source) {
1330 var path = source.fileName;
1331 var fileName = path.replace(BEFORE_SLASH_RE, '');
1332
1333 {
1334 // In DEV, include code for a common special case:
1335 // prefer "folder/index.js" instead of just "index.js".
1336 if (/^index\./.test(fileName)) {
1337 var match = path.match(BEFORE_SLASH_RE);
1338
1339 if (match) {
1340 var pathBeforeSlash = match[1];
1341
1342 if (pathBeforeSlash) {
1343 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1344 fileName = folderName + '/' + fileName;
1345 }
1346 }
1347 }
1348 }
1349
1350 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1351 } else if (ownerName) {
1352 sourceInfo = ' (created by ' + ownerName + ')';
1353 }
1354
1355 return '\n in ' + (name || 'Unknown') + sourceInfo;
1356 }
1357
1358 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1359
1360 function describeFiber(fiber) {
1361 switch (fiber.tag) {
1362 case HostRoot:
1363 case HostPortal:
1364 case HostText:
1365 case Fragment:
1366 case ContextProvider:
1367 case ContextConsumer:
1368 return '';
1369
1370 default:
1371 var owner = fiber._debugOwner;
1372 var source = fiber._debugSource;
1373 var name = getComponentName(fiber.type);
1374 var ownerName = null;
1375
1376 if (owner) {
1377 ownerName = getComponentName(owner.type);
1378 }
1379
1380 return describeComponentFrame(name, source, ownerName);
1381 }
1382 }
1383
1384 function getStackByFiberInDevAndProd(workInProgress) {
1385 var info = '';
1386 var node = workInProgress;
1387
1388 do {
1389 info += describeFiber(node);
1390 node = node.return;
1391 } while (node);
1392
1393 return info;
1394 }
1395 var current$1 = null;
1396 var phase = null;
1397 function getCurrentFiberOwnerNameInDevOrNull() {
1398 {
1399 if (current$1 === null) {
1400 return null;
1401 }
1402
1403 var owner = current$1._debugOwner;
1404
1405 if (owner !== null && typeof owner !== 'undefined') {
1406 return getComponentName(owner.type);
1407 }
1408 }
1409
1410 return null;
1411 }
1412 function getCurrentFiberStackInDev() {
1413 {
1414 if (current$1 === null) {
1415 return '';
1416 } // Safe because if current fiber exists, we are reconciling,
1417 // and it is guaranteed to be the work-in-progress version.
1418
1419
1420 return getStackByFiberInDevAndProd(current$1);
1421 }
1422 }
1423 function resetCurrentFiber() {
1424 {
1425 ReactDebugCurrentFrame.getCurrentStack = null;
1426 current$1 = null;
1427 phase = null;
1428 }
1429 }
1430 function setCurrentFiber(fiber) {
1431 {
1432 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1433 current$1 = fiber;
1434 phase = null;
1435 }
1436 }
1437 function setCurrentPhase(lifeCyclePhase) {
1438 {
1439 phase = lifeCyclePhase;
1440 }
1441 }
1442
1443 // Prefix measurements so that it's possible to filter them.
1444 // Longer prefixes are hard to read in DevTools.
1445 var reactEmoji = "\u269B";
1446 var warningEmoji = "\u26D4";
1447 var 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.
1448 // TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1449
1450 var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
1451 // Reusing `currentFiber` would be confusing for this because user code fiber
1452 // can change during commit phase too, but we don't need to unwind it (since
1453 // lifecycles in the commit phase don't resemble a tree).
1454
1455 var currentPhase = null;
1456 var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
1457 // so we will keep track of it, and include it in the report.
1458 // Track commits caused by cascading updates.
1459
1460 var isCommitting = false;
1461 var hasScheduledUpdateInCurrentCommit = false;
1462 var hasScheduledUpdateInCurrentPhase = false;
1463 var commitCountInCurrentWorkLoop = 0;
1464 var effectCountInCurrentCommit = 0;
1465 // to avoid stretch the commit phase with measurement overhead.
1466
1467 var labelsInCurrentCommit = new Set();
1468
1469 var formatMarkName = function (markName) {
1470 return reactEmoji + " " + markName;
1471 };
1472
1473 var formatLabel = function (label, warning) {
1474 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
1475 var suffix = warning ? " Warning: " + warning : '';
1476 return "" + prefix + label + suffix;
1477 };
1478
1479 var beginMark = function (markName) {
1480 performance.mark(formatMarkName(markName));
1481 };
1482
1483 var clearMark = function (markName) {
1484 performance.clearMarks(formatMarkName(markName));
1485 };
1486
1487 var endMark = function (label, markName, warning) {
1488 var formattedMarkName = formatMarkName(markName);
1489 var formattedLabel = formatLabel(label, warning);
1490
1491 try {
1492 performance.measure(formattedLabel, formattedMarkName);
1493 } catch (err) {} // If previous mark was missing for some reason, this will throw.
1494 // This could only happen if React crashed in an unexpected place earlier.
1495 // Don't pile on with more errors.
1496 // Clear marks immediately to avoid growing buffer.
1497
1498
1499 performance.clearMarks(formattedMarkName);
1500 performance.clearMeasures(formattedLabel);
1501 };
1502
1503 var getFiberMarkName = function (label, debugID) {
1504 return label + " (#" + debugID + ")";
1505 };
1506
1507 var getFiberLabel = function (componentName, isMounted, phase) {
1508 if (phase === null) {
1509 // These are composite component total time measurements.
1510 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
1511 } else {
1512 // Composite component methods.
1513 return componentName + "." + phase;
1514 }
1515 };
1516
1517 var beginFiberMark = function (fiber, phase) {
1518 var componentName = getComponentName(fiber.type) || 'Unknown';
1519 var debugID = fiber._debugID;
1520 var isMounted = fiber.alternate !== null;
1521 var label = getFiberLabel(componentName, isMounted, phase);
1522
1523 if (isCommitting && labelsInCurrentCommit.has(label)) {
1524 // During the commit phase, we don't show duplicate labels because
1525 // there is a fixed overhead for every measurement, and we don't
1526 // want to stretch the commit phase beyond necessary.
1527 return false;
1528 }
1529
1530 labelsInCurrentCommit.add(label);
1531 var markName = getFiberMarkName(label, debugID);
1532 beginMark(markName);
1533 return true;
1534 };
1535
1536 var clearFiberMark = function (fiber, phase) {
1537 var componentName = getComponentName(fiber.type) || 'Unknown';
1538 var debugID = fiber._debugID;
1539 var isMounted = fiber.alternate !== null;
1540 var label = getFiberLabel(componentName, isMounted, phase);
1541 var markName = getFiberMarkName(label, debugID);
1542 clearMark(markName);
1543 };
1544
1545 var endFiberMark = function (fiber, phase, warning) {
1546 var componentName = getComponentName(fiber.type) || 'Unknown';
1547 var debugID = fiber._debugID;
1548 var isMounted = fiber.alternate !== null;
1549 var label = getFiberLabel(componentName, isMounted, phase);
1550 var markName = getFiberMarkName(label, debugID);
1551 endMark(label, markName, warning);
1552 };
1553
1554 var shouldIgnoreFiber = function (fiber) {
1555 // Host components should be skipped in the timeline.
1556 // We could check typeof fiber.type, but does this work with RN?
1557 switch (fiber.tag) {
1558 case HostRoot:
1559 case HostComponent:
1560 case HostText:
1561 case HostPortal:
1562 case Fragment:
1563 case ContextProvider:
1564 case ContextConsumer:
1565 case Mode:
1566 return true;
1567
1568 default:
1569 return false;
1570 }
1571 };
1572
1573 var clearPendingPhaseMeasurement = function () {
1574 if (currentPhase !== null && currentPhaseFiber !== null) {
1575 clearFiberMark(currentPhaseFiber, currentPhase);
1576 }
1577
1578 currentPhaseFiber = null;
1579 currentPhase = null;
1580 hasScheduledUpdateInCurrentPhase = false;
1581 };
1582
1583 var pauseTimers = function () {
1584 // Stops all currently active measurements so that they can be resumed
1585 // if we continue in a later deferred loop from the same unit of work.
1586 var fiber = currentFiber;
1587
1588 while (fiber) {
1589 if (fiber._debugIsCurrentlyTiming) {
1590 endFiberMark(fiber, null, null);
1591 }
1592
1593 fiber = fiber.return;
1594 }
1595 };
1596
1597 var resumeTimersRecursively = function (fiber) {
1598 if (fiber.return !== null) {
1599 resumeTimersRecursively(fiber.return);
1600 }
1601
1602 if (fiber._debugIsCurrentlyTiming) {
1603 beginFiberMark(fiber, null);
1604 }
1605 };
1606
1607 var resumeTimers = function () {
1608 // Resumes all measurements that were active during the last deferred loop.
1609 if (currentFiber !== null) {
1610 resumeTimersRecursively(currentFiber);
1611 }
1612 };
1613
1614 function recordEffect() {
1615 {
1616 effectCountInCurrentCommit++;
1617 }
1618 }
1619 function recordScheduleUpdate() {
1620 {
1621 if (isCommitting) {
1622 hasScheduledUpdateInCurrentCommit = true;
1623 }
1624
1625 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1626 hasScheduledUpdateInCurrentPhase = true;
1627 }
1628 }
1629 }
1630 function startWorkTimer(fiber) {
1631 {
1632 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1633 return;
1634 } // If we pause, this is the fiber to unwind from.
1635
1636
1637 currentFiber = fiber;
1638
1639 if (!beginFiberMark(fiber, null)) {
1640 return;
1641 }
1642
1643 fiber._debugIsCurrentlyTiming = true;
1644 }
1645 }
1646 function cancelWorkTimer(fiber) {
1647 {
1648 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1649 return;
1650 } // Remember we shouldn't complete measurement for this fiber.
1651 // Otherwise flamechart will be deep even for small updates.
1652
1653
1654 fiber._debugIsCurrentlyTiming = false;
1655 clearFiberMark(fiber, null);
1656 }
1657 }
1658 function stopWorkTimer(fiber) {
1659 {
1660 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1661 return;
1662 } // If we pause, its parent is the fiber to unwind from.
1663
1664
1665 currentFiber = fiber.return;
1666
1667 if (!fiber._debugIsCurrentlyTiming) {
1668 return;
1669 }
1670
1671 fiber._debugIsCurrentlyTiming = false;
1672 endFiberMark(fiber, null, null);
1673 }
1674 }
1675 function stopFailedWorkTimer(fiber) {
1676 {
1677 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1678 return;
1679 } // If we pause, its parent is the fiber to unwind from.
1680
1681
1682 currentFiber = fiber.return;
1683
1684 if (!fiber._debugIsCurrentlyTiming) {
1685 return;
1686 }
1687
1688 fiber._debugIsCurrentlyTiming = false;
1689 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1690 endFiberMark(fiber, null, warning);
1691 }
1692 }
1693 function startPhaseTimer(fiber, phase) {
1694 {
1695 if (!supportsUserTiming) {
1696 return;
1697 }
1698
1699 clearPendingPhaseMeasurement();
1700
1701 if (!beginFiberMark(fiber, phase)) {
1702 return;
1703 }
1704
1705 currentPhaseFiber = fiber;
1706 currentPhase = phase;
1707 }
1708 }
1709 function stopPhaseTimer() {
1710 {
1711 if (!supportsUserTiming) {
1712 return;
1713 }
1714
1715 if (currentPhase !== null && currentPhaseFiber !== null) {
1716 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1717 endFiberMark(currentPhaseFiber, currentPhase, warning);
1718 }
1719
1720 currentPhase = null;
1721 currentPhaseFiber = null;
1722 }
1723 }
1724 function startWorkLoopTimer(nextUnitOfWork) {
1725 {
1726 currentFiber = nextUnitOfWork;
1727
1728 if (!supportsUserTiming) {
1729 return;
1730 }
1731
1732 commitCountInCurrentWorkLoop = 0; // This is top level call.
1733 // Any other measurements are performed within.
1734
1735 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
1736
1737 resumeTimers();
1738 }
1739 }
1740 function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1741 {
1742 if (!supportsUserTiming) {
1743 return;
1744 }
1745
1746 var warning = null;
1747
1748 if (interruptedBy !== null) {
1749 if (interruptedBy.tag === HostRoot) {
1750 warning = 'A top-level update interrupted the previous render';
1751 } else {
1752 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1753 warning = "An update to " + componentName + " interrupted the previous render";
1754 }
1755 } else if (commitCountInCurrentWorkLoop > 1) {
1756 warning = 'There were cascading updates';
1757 }
1758
1759 commitCountInCurrentWorkLoop = 0;
1760 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
1761
1762 pauseTimers();
1763 endMark(label, '(React Tree Reconciliation)', warning);
1764 }
1765 }
1766 function startCommitTimer() {
1767 {
1768 if (!supportsUserTiming) {
1769 return;
1770 }
1771
1772 isCommitting = true;
1773 hasScheduledUpdateInCurrentCommit = false;
1774 labelsInCurrentCommit.clear();
1775 beginMark('(Committing Changes)');
1776 }
1777 }
1778 function stopCommitTimer() {
1779 {
1780 if (!supportsUserTiming) {
1781 return;
1782 }
1783
1784 var warning = null;
1785
1786 if (hasScheduledUpdateInCurrentCommit) {
1787 warning = 'Lifecycle hook scheduled a cascading update';
1788 } else if (commitCountInCurrentWorkLoop > 0) {
1789 warning = 'Caused by a cascading update in earlier commit';
1790 }
1791
1792 hasScheduledUpdateInCurrentCommit = false;
1793 commitCountInCurrentWorkLoop++;
1794 isCommitting = false;
1795 labelsInCurrentCommit.clear();
1796 endMark('(Committing Changes)', '(Committing Changes)', warning);
1797 }
1798 }
1799 function startCommitSnapshotEffectsTimer() {
1800 {
1801 if (!supportsUserTiming) {
1802 return;
1803 }
1804
1805 effectCountInCurrentCommit = 0;
1806 beginMark('(Committing Snapshot Effects)');
1807 }
1808 }
1809 function stopCommitSnapshotEffectsTimer() {
1810 {
1811 if (!supportsUserTiming) {
1812 return;
1813 }
1814
1815 var count = effectCountInCurrentCommit;
1816 effectCountInCurrentCommit = 0;
1817 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
1818 }
1819 }
1820 function startCommitHostEffectsTimer() {
1821 {
1822 if (!supportsUserTiming) {
1823 return;
1824 }
1825
1826 effectCountInCurrentCommit = 0;
1827 beginMark('(Committing Host Effects)');
1828 }
1829 }
1830 function stopCommitHostEffectsTimer() {
1831 {
1832 if (!supportsUserTiming) {
1833 return;
1834 }
1835
1836 var count = effectCountInCurrentCommit;
1837 effectCountInCurrentCommit = 0;
1838 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
1839 }
1840 }
1841 function startCommitLifeCyclesTimer() {
1842 {
1843 if (!supportsUserTiming) {
1844 return;
1845 }
1846
1847 effectCountInCurrentCommit = 0;
1848 beginMark('(Calling Lifecycle Methods)');
1849 }
1850 }
1851 function stopCommitLifeCyclesTimer() {
1852 {
1853 if (!supportsUserTiming) {
1854 return;
1855 }
1856
1857 var count = effectCountInCurrentCommit;
1858 effectCountInCurrentCommit = 0;
1859 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
1860 }
1861 }
1862
1863 var valueStack = [];
1864 var fiberStack;
1865
1866 {
1867 fiberStack = [];
1868 }
1869
1870 var index = -1;
1871
1872 function createCursor(defaultValue) {
1873 return {
1874 current: defaultValue
1875 };
1876 }
1877
1878 function pop(cursor, fiber) {
1879 if (index < 0) {
1880 {
1881 error('Unexpected pop.');
1882 }
1883
1884 return;
1885 }
1886
1887 {
1888 if (fiber !== fiberStack[index]) {
1889 error('Unexpected Fiber popped.');
1890 }
1891 }
1892
1893 cursor.current = valueStack[index];
1894 valueStack[index] = null;
1895
1896 {
1897 fiberStack[index] = null;
1898 }
1899
1900 index--;
1901 }
1902
1903 function push(cursor, value, fiber) {
1904 index++;
1905 valueStack[index] = cursor.current;
1906
1907 {
1908 fiberStack[index] = fiber;
1909 }
1910
1911 cursor.current = value;
1912 }
1913
1914 var warnedAboutMissingGetChildContext;
1915
1916 {
1917 warnedAboutMissingGetChildContext = {};
1918 }
1919
1920 var emptyContextObject = {};
1921
1922 {
1923 Object.freeze(emptyContextObject);
1924 } // A cursor to the current merged context object on the stack.
1925
1926
1927 var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
1928
1929 var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
1930 // We use this to get access to the parent context after we have already
1931 // pushed the next context provider, and now need to merge their contexts.
1932
1933 var previousContext = emptyContextObject;
1934
1935 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1936 {
1937 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1938 // If the fiber is a context provider itself, when we read its context
1939 // we may have already pushed its own child context on the stack. A context
1940 // provider should not "see" its own child context. Therefore we read the
1941 // previous (parent) context instead for a context provider.
1942 return previousContext;
1943 }
1944
1945 return contextStackCursor.current;
1946 }
1947 }
1948
1949 function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1950 {
1951 var instance = workInProgress.stateNode;
1952 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1953 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1954 }
1955 }
1956
1957 function getMaskedContext(workInProgress, unmaskedContext) {
1958 {
1959 var type = workInProgress.type;
1960 var contextTypes = type.contextTypes;
1961
1962 if (!contextTypes) {
1963 return emptyContextObject;
1964 } // Avoid recreating masked context unless unmasked context has changed.
1965 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1966 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1967
1968
1969 var instance = workInProgress.stateNode;
1970
1971 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1972 return instance.__reactInternalMemoizedMaskedChildContext;
1973 }
1974
1975 var context = {};
1976
1977 for (var key in contextTypes) {
1978 context[key] = unmaskedContext[key];
1979 }
1980
1981 {
1982 var name = getComponentName(type) || 'Unknown';
1983 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1984 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
1985 // Context is created before the class component is instantiated so check for instance.
1986
1987
1988 if (instance) {
1989 cacheContext(workInProgress, unmaskedContext, context);
1990 }
1991
1992 return context;
1993 }
1994 }
1995
1996 function hasContextChanged() {
1997 {
1998 return didPerformWorkStackCursor.current;
1999 }
2000 }
2001
2002 function isContextProvider(type) {
2003 {
2004 var childContextTypes = type.childContextTypes;
2005 return childContextTypes !== null && childContextTypes !== undefined;
2006 }
2007 }
2008
2009 function popContext(fiber) {
2010 {
2011 pop(didPerformWorkStackCursor, fiber);
2012 pop(contextStackCursor, fiber);
2013 }
2014 }
2015
2016 function popTopLevelContextObject(fiber) {
2017 {
2018 pop(didPerformWorkStackCursor, fiber);
2019 pop(contextStackCursor, fiber);
2020 }
2021 }
2022
2023 function pushTopLevelContextObject(fiber, context, didChange) {
2024 {
2025 if (!(contextStackCursor.current === emptyContextObject)) {
2026 {
2027 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
2028 }
2029 }
2030
2031 push(contextStackCursor, context, fiber);
2032 push(didPerformWorkStackCursor, didChange, fiber);
2033 }
2034 }
2035
2036 function processChildContext(fiber, type, parentContext) {
2037 {
2038 var instance = fiber.stateNode;
2039 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
2040 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
2041
2042 if (typeof instance.getChildContext !== 'function') {
2043 {
2044 var componentName = getComponentName(type) || 'Unknown';
2045
2046 if (!warnedAboutMissingGetChildContext[componentName]) {
2047 warnedAboutMissingGetChildContext[componentName] = true;
2048
2049 error('%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
2050 }
2051 }
2052
2053 return parentContext;
2054 }
2055
2056 var childContext;
2057
2058 {
2059 setCurrentPhase('getChildContext');
2060 }
2061
2062 startPhaseTimer(fiber, 'getChildContext');
2063 childContext = instance.getChildContext();
2064 stopPhaseTimer();
2065
2066 {
2067 setCurrentPhase(null);
2068 }
2069
2070 for (var contextKey in childContext) {
2071 if (!(contextKey in childContextTypes)) {
2072 {
2073 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
2074 }
2075 }
2076 }
2077
2078 {
2079 var name = getComponentName(type) || 'Unknown';
2080 checkPropTypes_1(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
2081 // somebody calls unstable_renderSubtreeIntoContainer() and we process
2082 // context from the parent component instance. The stack will be missing
2083 // because it's outside of the reconciliation, and so the pointer has not
2084 // been set. This is rare and doesn't matter. We'll also remove that API.
2085 getCurrentFiberStackInDev);
2086 }
2087
2088 return _assign({}, parentContext, {}, childContext);
2089 }
2090 }
2091
2092 function pushContextProvider(workInProgress) {
2093 {
2094 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
2095 // If the instance does not exist yet, we will push null at first,
2096 // and replace it on the stack later when invalidating the context.
2097
2098 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
2099 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2100
2101 previousContext = contextStackCursor.current;
2102 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2103 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2104 return true;
2105 }
2106 }
2107
2108 function invalidateContextProvider(workInProgress, type, didChange) {
2109 {
2110 var instance = workInProgress.stateNode;
2111
2112 if (!instance) {
2113 {
2114 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
2115 }
2116 }
2117
2118 if (didChange) {
2119 // Merge parent and own context.
2120 // Skip this if we're not updating due to sCU.
2121 // This avoids unnecessarily recomputing memoized values.
2122 var mergedContext = processChildContext(workInProgress, type, previousContext);
2123 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
2124 // It is important to unwind the context in the reverse order.
2125
2126 pop(didPerformWorkStackCursor, workInProgress);
2127 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
2128
2129 push(contextStackCursor, mergedContext, workInProgress);
2130 push(didPerformWorkStackCursor, didChange, workInProgress);
2131 } else {
2132 pop(didPerformWorkStackCursor, workInProgress);
2133 push(didPerformWorkStackCursor, didChange, workInProgress);
2134 }
2135 }
2136 }
2137
2138 function findCurrentUnmaskedContext(fiber) {
2139 {
2140 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2141 // makes sense elsewhere
2142 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
2143 {
2144 throw Error( "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." );
2145 }
2146 }
2147
2148 var node = fiber;
2149
2150 do {
2151 switch (node.tag) {
2152 case HostRoot:
2153 return node.stateNode.context;
2154
2155 case ClassComponent:
2156 {
2157 var Component = node.type;
2158
2159 if (isContextProvider(Component)) {
2160 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2161 }
2162
2163 break;
2164 }
2165 }
2166
2167 node = node.return;
2168 } while (node !== null);
2169
2170 {
2171 {
2172 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
2173 }
2174 }
2175 }
2176 }
2177
2178 var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2179 var _ReactInternals$Sched = ReactInternals$1.Scheduler,
2180 unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback,
2181 unstable_now = _ReactInternals$Sched.unstable_now,
2182 unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback,
2183 unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield,
2184 unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint,
2185 unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode,
2186 unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority,
2187 unstable_next = _ReactInternals$Sched.unstable_next,
2188 unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution,
2189 unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution,
2190 unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel,
2191 unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority,
2192 unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority,
2193 unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority,
2194 unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority,
2195 unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority,
2196 unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate,
2197 unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
2198
2199 var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2200 var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing,
2201 __interactionsRef = _ReactInternals$Sched$1.__interactionsRef,
2202 __subscriberRef = _ReactInternals$Sched$1.__subscriberRef,
2203 unstable_clear = _ReactInternals$Sched$1.unstable_clear,
2204 unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent,
2205 unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID,
2206 unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe,
2207 unstable_trace = _ReactInternals$Sched$1.unstable_trace,
2208 unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe,
2209 unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2210
2211 var Scheduler_runWithPriority = unstable_runWithPriority,
2212 Scheduler_scheduleCallback = unstable_scheduleCallback,
2213 Scheduler_cancelCallback = unstable_cancelCallback,
2214 Scheduler_shouldYield = unstable_shouldYield,
2215 Scheduler_requestPaint = unstable_requestPaint,
2216 Scheduler_now = unstable_now,
2217 Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel,
2218 Scheduler_ImmediatePriority = unstable_ImmediatePriority,
2219 Scheduler_UserBlockingPriority = unstable_UserBlockingPriority,
2220 Scheduler_NormalPriority = unstable_NormalPriority,
2221 Scheduler_LowPriority = unstable_LowPriority,
2222 Scheduler_IdlePriority = unstable_IdlePriority;
2223
2224 {
2225 // Provide explicit error message when production+profiling bundle of e.g.
2226 // react-dom is used with production (non-profiling) bundle of
2227 // scheduler/tracing
2228 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
2229 {
2230 throw Error( "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling" );
2231 }
2232 }
2233 }
2234
2235 var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
2236 // ascending numbers so we can compare them like numbers. They start at 90 to
2237 // avoid clashing with Scheduler's priorities.
2238
2239 var ImmediatePriority = 99;
2240 var UserBlockingPriority = 98;
2241 var NormalPriority = 97;
2242 var LowPriority = 96;
2243 var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
2244
2245 var NoPriority = 90;
2246 var shouldYield = Scheduler_shouldYield;
2247 var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
2248 Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
2249 var syncQueue = null;
2250 var immediateQueueCallbackNode = null;
2251 var isFlushingSyncQueue = false;
2252 var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
2253 // This will be the case for modern browsers that support `performance.now`. In
2254 // older browsers, Scheduler falls back to `Date.now`, which returns a Unix
2255 // timestamp. In that case, subtract the module initialization time to simulate
2256 // the behavior of performance.now and keep our times small enough to fit
2257 // within 32 bits.
2258 // TODO: Consider lifting this into Scheduler.
2259
2260 var now = initialTimeMs < 10000 ? Scheduler_now : function () {
2261 return Scheduler_now() - initialTimeMs;
2262 };
2263 function getCurrentPriorityLevel() {
2264 switch (Scheduler_getCurrentPriorityLevel()) {
2265 case Scheduler_ImmediatePriority:
2266 return ImmediatePriority;
2267
2268 case Scheduler_UserBlockingPriority:
2269 return UserBlockingPriority;
2270
2271 case Scheduler_NormalPriority:
2272 return NormalPriority;
2273
2274 case Scheduler_LowPriority:
2275 return LowPriority;
2276
2277 case Scheduler_IdlePriority:
2278 return IdlePriority;
2279
2280 default:
2281 {
2282 {
2283 throw Error( "Unknown priority level." );
2284 }
2285 }
2286
2287 }
2288 }
2289
2290 function reactPriorityToSchedulerPriority(reactPriorityLevel) {
2291 switch (reactPriorityLevel) {
2292 case ImmediatePriority:
2293 return Scheduler_ImmediatePriority;
2294
2295 case UserBlockingPriority:
2296 return Scheduler_UserBlockingPriority;
2297
2298 case NormalPriority:
2299 return Scheduler_NormalPriority;
2300
2301 case LowPriority:
2302 return Scheduler_LowPriority;
2303
2304 case IdlePriority:
2305 return Scheduler_IdlePriority;
2306
2307 default:
2308 {
2309 {
2310 throw Error( "Unknown priority level." );
2311 }
2312 }
2313
2314 }
2315 }
2316
2317 function runWithPriority(reactPriorityLevel, fn) {
2318 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2319 return Scheduler_runWithPriority(priorityLevel, fn);
2320 }
2321 function scheduleCallback(reactPriorityLevel, callback, options) {
2322 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2323 return Scheduler_scheduleCallback(priorityLevel, callback, options);
2324 }
2325 function scheduleSyncCallback(callback) {
2326 // Push this callback into an internal queue. We'll flush these either in
2327 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
2328 if (syncQueue === null) {
2329 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
2330
2331 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
2332 } else {
2333 // Push onto existing queue. Don't need to schedule a callback because
2334 // we already scheduled one when we created the queue.
2335 syncQueue.push(callback);
2336 }
2337
2338 return fakeCallbackNode;
2339 }
2340 function cancelCallback(callbackNode) {
2341 if (callbackNode !== fakeCallbackNode) {
2342 Scheduler_cancelCallback(callbackNode);
2343 }
2344 }
2345 function flushSyncCallbackQueue() {
2346 if (immediateQueueCallbackNode !== null) {
2347 var node = immediateQueueCallbackNode;
2348 immediateQueueCallbackNode = null;
2349 Scheduler_cancelCallback(node);
2350 }
2351
2352 flushSyncCallbackQueueImpl();
2353 }
2354
2355 function flushSyncCallbackQueueImpl() {
2356 if (!isFlushingSyncQueue && syncQueue !== null) {
2357 // Prevent re-entrancy.
2358 isFlushingSyncQueue = true;
2359 var i = 0;
2360
2361 try {
2362 var _isSync = true;
2363 var queue = syncQueue;
2364 runWithPriority(ImmediatePriority, function () {
2365 for (; i < queue.length; i++) {
2366 var callback = queue[i];
2367
2368 do {
2369 callback = callback(_isSync);
2370 } while (callback !== null);
2371 }
2372 });
2373 syncQueue = null;
2374 } catch (error) {
2375 // If something throws, leave the remaining callbacks on the queue.
2376 if (syncQueue !== null) {
2377 syncQueue = syncQueue.slice(i + 1);
2378 } // Resume flushing in the next tick
2379
2380
2381 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
2382 throw error;
2383 } finally {
2384 isFlushingSyncQueue = false;
2385 }
2386 }
2387 }
2388
2389 var NoMode = 0;
2390 var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
2391 // tag instead
2392
2393 var BlockingMode = 2;
2394 var ConcurrentMode = 4;
2395 var ProfileMode = 8;
2396
2397 // Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2398 // Math.pow(2, 30) - 1
2399 // 0b111111111111111111111111111111
2400 var MAX_SIGNED_31_BIT_INT = 1073741823;
2401
2402 var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
2403 // Never work can be committed in an inconsistent state without tearing the UI.
2404 // The main example is offscreen content, like a hidden subtree. So one possible
2405 // name is Offscreen. However, it also includes dehydrated Suspense boundaries,
2406 // which are inconsistent in the sense that they haven't finished yet, but
2407 // aren't visibly inconsistent because the server rendered HTML matches what the
2408 // hydrated tree would look like.
2409
2410 var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
2411 // order to be consistent.
2412
2413 var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase
2414 var Sync = MAX_SIGNED_31_BIT_INT;
2415 var Batched = Sync - 1;
2416 var UNIT_SIZE = 10;
2417 var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
2418
2419 function msToExpirationTime(ms) {
2420 // Always subtract from the offset so that we don't clash with the magic number for NoWork.
2421 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2422 }
2423 function expirationTimeToMs(expirationTime) {
2424 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2425 }
2426
2427 function ceiling(num, precision) {
2428 return ((num / precision | 0) + 1) * precision;
2429 }
2430
2431 function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2432 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2433 } // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
2434 // the names to reflect.
2435
2436
2437 var LOW_PRIORITY_EXPIRATION = 5000;
2438 var LOW_PRIORITY_BATCH_SIZE = 250;
2439 function computeAsyncExpiration(currentTime) {
2440 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2441 }
2442 function computeSuspenseExpiration(currentTime, timeoutMs) {
2443 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
2444 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
2445 } // We intentionally set a higher expiration time for interactive updates in
2446 // dev than in production.
2447 //
2448 // If the main thread is being blocked so long that you hit the expiration,
2449 // it's a problem that could be solved with better scheduling.
2450 //
2451 // People will be more likely to notice this and fix it with the long
2452 // expiration time in development.
2453 //
2454 // In production we opt for better UX at the risk of masking scheduling
2455 // problems, by expiring fast.
2456
2457 var HIGH_PRIORITY_EXPIRATION = 500 ;
2458 var HIGH_PRIORITY_BATCH_SIZE = 100;
2459 function computeInteractiveExpiration(currentTime) {
2460 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2461 }
2462 function inferPriorityFromExpirationTime(currentTime, expirationTime) {
2463 if (expirationTime === Sync) {
2464 return ImmediatePriority;
2465 }
2466
2467 if (expirationTime === Never || expirationTime === Idle) {
2468 return IdlePriority;
2469 }
2470
2471 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
2472
2473 if (msUntil <= 0) {
2474 return ImmediatePriority;
2475 }
2476
2477 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
2478 return UserBlockingPriority;
2479 }
2480
2481 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
2482 return NormalPriority;
2483 } // TODO: Handle LowPriority
2484 // Assume anything lower has idle priority
2485
2486
2487 return IdlePriority;
2488 }
2489
2490 /**
2491 * inlined Object.is polyfill to avoid requiring consumers ship their own
2492 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2493 */
2494 function is(x, y) {
2495 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2496 ;
2497 }
2498
2499 var objectIs = typeof Object.is === 'function' ? Object.is : is;
2500
2501 var hasOwnProperty = Object.prototype.hasOwnProperty;
2502 /**
2503 * Performs equality by iterating through keys on an object and returning false
2504 * when any key has values which are not strictly equal between the arguments.
2505 * Returns true when the values of all keys are strictly equal.
2506 */
2507
2508 function shallowEqual(objA, objB) {
2509 if (objectIs(objA, objB)) {
2510 return true;
2511 }
2512
2513 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2514 return false;
2515 }
2516
2517 var keysA = Object.keys(objA);
2518 var keysB = Object.keys(objB);
2519
2520 if (keysA.length !== keysB.length) {
2521 return false;
2522 } // Test for A's keys different from B.
2523
2524
2525 for (var i = 0; i < keysA.length; i++) {
2526 if (!hasOwnProperty.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
2527 return false;
2528 }
2529 }
2530
2531 return true;
2532 }
2533
2534 var ReactStrictModeWarnings = {
2535 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2536 flushPendingUnsafeLifecycleWarnings: function () {},
2537 recordLegacyContextWarning: function (fiber, instance) {},
2538 flushLegacyContextWarning: function () {},
2539 discardPendingWarnings: function () {}
2540 };
2541
2542 {
2543 var findStrictRoot = function (fiber) {
2544 var maybeStrictRoot = null;
2545 var node = fiber;
2546
2547 while (node !== null) {
2548 if (node.mode & StrictMode) {
2549 maybeStrictRoot = node;
2550 }
2551
2552 node = node.return;
2553 }
2554
2555 return maybeStrictRoot;
2556 };
2557
2558 var setToSortedString = function (set) {
2559 var array = [];
2560 set.forEach(function (value) {
2561 array.push(value);
2562 });
2563 return array.sort().join(', ');
2564 };
2565
2566 var pendingComponentWillMountWarnings = [];
2567 var pendingUNSAFE_ComponentWillMountWarnings = [];
2568 var pendingComponentWillReceivePropsWarnings = [];
2569 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2570 var pendingComponentWillUpdateWarnings = [];
2571 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
2572
2573 var didWarnAboutUnsafeLifecycles = new Set();
2574
2575 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2576 // Dedup strategy: Warn once per component.
2577 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2578 return;
2579 }
2580
2581 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
2582 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2583 pendingComponentWillMountWarnings.push(fiber);
2584 }
2585
2586 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2587 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2588 }
2589
2590 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2591 pendingComponentWillReceivePropsWarnings.push(fiber);
2592 }
2593
2594 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2595 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2596 }
2597
2598 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2599 pendingComponentWillUpdateWarnings.push(fiber);
2600 }
2601
2602 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2603 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2604 }
2605 };
2606
2607 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2608 // We do an initial pass to gather component names
2609 var componentWillMountUniqueNames = new Set();
2610
2611 if (pendingComponentWillMountWarnings.length > 0) {
2612 pendingComponentWillMountWarnings.forEach(function (fiber) {
2613 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2614 didWarnAboutUnsafeLifecycles.add(fiber.type);
2615 });
2616 pendingComponentWillMountWarnings = [];
2617 }
2618
2619 var UNSAFE_componentWillMountUniqueNames = new Set();
2620
2621 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2622 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2623 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2624 didWarnAboutUnsafeLifecycles.add(fiber.type);
2625 });
2626 pendingUNSAFE_ComponentWillMountWarnings = [];
2627 }
2628
2629 var componentWillReceivePropsUniqueNames = new Set();
2630
2631 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2632 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2633 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2634 didWarnAboutUnsafeLifecycles.add(fiber.type);
2635 });
2636 pendingComponentWillReceivePropsWarnings = [];
2637 }
2638
2639 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2640
2641 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2642 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2643 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2644 didWarnAboutUnsafeLifecycles.add(fiber.type);
2645 });
2646 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2647 }
2648
2649 var componentWillUpdateUniqueNames = new Set();
2650
2651 if (pendingComponentWillUpdateWarnings.length > 0) {
2652 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2653 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2654 didWarnAboutUnsafeLifecycles.add(fiber.type);
2655 });
2656 pendingComponentWillUpdateWarnings = [];
2657 }
2658
2659 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2660
2661 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2662 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2663 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2664 didWarnAboutUnsafeLifecycles.add(fiber.type);
2665 });
2666 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2667 } // Finally, we flush all the warnings
2668 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
2669
2670
2671 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
2672 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
2673
2674 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
2675 }
2676
2677 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
2678 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
2679
2680 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
2681 }
2682
2683 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
2684 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
2685
2686 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
2687 }
2688
2689 if (componentWillMountUniqueNames.size > 0) {
2690 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
2691
2692 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
2693 }
2694
2695 if (componentWillReceivePropsUniqueNames.size > 0) {
2696 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
2697
2698 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
2699 }
2700
2701 if (componentWillUpdateUniqueNames.size > 0) {
2702 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
2703
2704 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
2705 }
2706 };
2707
2708 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
2709
2710 var didWarnAboutLegacyContext = new Set();
2711
2712 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
2713 var strictRoot = findStrictRoot(fiber);
2714
2715 if (strictRoot === null) {
2716 error('Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2717
2718 return;
2719 } // Dedup strategy: Warn once per component.
2720
2721
2722 if (didWarnAboutLegacyContext.has(fiber.type)) {
2723 return;
2724 }
2725
2726 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
2727
2728 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
2729 if (warningsForRoot === undefined) {
2730 warningsForRoot = [];
2731 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
2732 }
2733
2734 warningsForRoot.push(fiber);
2735 }
2736 };
2737
2738 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
2739 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
2740 if (fiberArray.length === 0) {
2741 return;
2742 }
2743
2744 var firstFiber = fiberArray[0];
2745 var uniqueNames = new Set();
2746 fiberArray.forEach(function (fiber) {
2747 uniqueNames.add(getComponentName(fiber.type) || 'Component');
2748 didWarnAboutLegacyContext.add(fiber.type);
2749 });
2750 var sortedNames = setToSortedString(uniqueNames);
2751 var firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
2752
2753 error('Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://fb.me/react-legacy-context' + '%s', sortedNames, firstComponentStack);
2754 });
2755 };
2756
2757 ReactStrictModeWarnings.discardPendingWarnings = function () {
2758 pendingComponentWillMountWarnings = [];
2759 pendingUNSAFE_ComponentWillMountWarnings = [];
2760 pendingComponentWillReceivePropsWarnings = [];
2761 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2762 pendingComponentWillUpdateWarnings = [];
2763 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2764 pendingLegacyContextWarning = new Map();
2765 };
2766 }
2767
2768 var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
2769
2770 var failedBoundaries = null;
2771 var setRefreshHandler = function (handler) {
2772 {
2773 resolveFamily = handler;
2774 }
2775 };
2776 function resolveFunctionForHotReloading(type) {
2777 {
2778 if (resolveFamily === null) {
2779 // Hot reloading is disabled.
2780 return type;
2781 }
2782
2783 var family = resolveFamily(type);
2784
2785 if (family === undefined) {
2786 return type;
2787 } // Use the latest known implementation.
2788
2789
2790 return family.current;
2791 }
2792 }
2793 function resolveClassForHotReloading(type) {
2794 // No implementation differences.
2795 return resolveFunctionForHotReloading(type);
2796 }
2797 function resolveForwardRefForHotReloading(type) {
2798 {
2799 if (resolveFamily === null) {
2800 // Hot reloading is disabled.
2801 return type;
2802 }
2803
2804 var family = resolveFamily(type);
2805
2806 if (family === undefined) {
2807 // Check if we're dealing with a real forwardRef. Don't want to crash early.
2808 if (type !== null && type !== undefined && typeof type.render === 'function') {
2809 // ForwardRef is special because its resolved .type is an object,
2810 // but it's possible that we only have its inner render function in the map.
2811 // If that inner render function is different, we'll build a new forwardRef type.
2812 var currentRender = resolveFunctionForHotReloading(type.render);
2813
2814 if (type.render !== currentRender) {
2815 var syntheticType = {
2816 $$typeof: REACT_FORWARD_REF_TYPE,
2817 render: currentRender
2818 };
2819
2820 if (type.displayName !== undefined) {
2821 syntheticType.displayName = type.displayName;
2822 }
2823
2824 return syntheticType;
2825 }
2826 }
2827
2828 return type;
2829 } // Use the latest known implementation.
2830
2831
2832 return family.current;
2833 }
2834 }
2835 function isCompatibleFamilyForHotReloading(fiber, element) {
2836 {
2837 if (resolveFamily === null) {
2838 // Hot reloading is disabled.
2839 return false;
2840 }
2841
2842 var prevType = fiber.elementType;
2843 var nextType = element.type; // If we got here, we know types aren't === equal.
2844
2845 var needsCompareFamilies = false;
2846 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
2847
2848 switch (fiber.tag) {
2849 case ClassComponent:
2850 {
2851 if (typeof nextType === 'function') {
2852 needsCompareFamilies = true;
2853 }
2854
2855 break;
2856 }
2857
2858 case FunctionComponent:
2859 {
2860 if (typeof nextType === 'function') {
2861 needsCompareFamilies = true;
2862 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2863 // We don't know the inner type yet.
2864 // We're going to assume that the lazy inner type is stable,
2865 // and so it is sufficient to avoid reconciling it away.
2866 // We're not going to unwrap or actually use the new lazy type.
2867 needsCompareFamilies = true;
2868 }
2869
2870 break;
2871 }
2872
2873 case ForwardRef:
2874 {
2875 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
2876 needsCompareFamilies = true;
2877 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2878 needsCompareFamilies = true;
2879 }
2880
2881 break;
2882 }
2883
2884 case MemoComponent:
2885 case SimpleMemoComponent:
2886 {
2887 if ($$typeofNextType === REACT_MEMO_TYPE) {
2888 // TODO: if it was but can no longer be simple,
2889 // we shouldn't set this.
2890 needsCompareFamilies = true;
2891 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2892 needsCompareFamilies = true;
2893 }
2894
2895 break;
2896 }
2897
2898 default:
2899 return false;
2900 } // Check if both types have a family and it's the same one.
2901
2902
2903 if (needsCompareFamilies) {
2904 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
2905 // This means both of them need to be registered to preserve state.
2906 // If we unwrapped and compared the inner types for wrappers instead,
2907 // then we would risk falsely saying two separate memo(Foo)
2908 // calls are equivalent because they wrap the same Foo function.
2909 var prevFamily = resolveFamily(prevType);
2910
2911 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
2912 return true;
2913 }
2914 }
2915
2916 return false;
2917 }
2918 }
2919 function markFailedErrorBoundaryForHotReloading(fiber) {
2920 {
2921 if (resolveFamily === null) {
2922 // Hot reloading is disabled.
2923 return;
2924 }
2925
2926 if (typeof WeakSet !== 'function') {
2927 return;
2928 }
2929
2930 if (failedBoundaries === null) {
2931 failedBoundaries = new WeakSet();
2932 }
2933
2934 failedBoundaries.add(fiber);
2935 }
2936 }
2937 var scheduleRefresh = function (root, update) {
2938 {
2939 if (resolveFamily === null) {
2940 // Hot reloading is disabled.
2941 return;
2942 }
2943
2944 var staleFamilies = update.staleFamilies,
2945 updatedFamilies = update.updatedFamilies;
2946 flushPassiveEffects();
2947 flushSync(function () {
2948 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
2949 });
2950 }
2951 };
2952 var scheduleRoot = function (root, element) {
2953 {
2954 if (root.context !== emptyContextObject) {
2955 // Super edge case: root has a legacy _renderSubtree context
2956 // but we don't know the parentComponent so we can't pass it.
2957 // Just ignore. We'll delete this with _renderSubtree code path later.
2958 return;
2959 }
2960
2961 flushPassiveEffects();
2962 syncUpdates(function () {
2963 updateContainer(element, root, null, null);
2964 });
2965 }
2966 };
2967
2968 function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
2969 {
2970 var alternate = fiber.alternate,
2971 child = fiber.child,
2972 sibling = fiber.sibling,
2973 tag = fiber.tag,
2974 type = fiber.type;
2975 var candidateType = null;
2976
2977 switch (tag) {
2978 case FunctionComponent:
2979 case SimpleMemoComponent:
2980 case ClassComponent:
2981 candidateType = type;
2982 break;
2983
2984 case ForwardRef:
2985 candidateType = type.render;
2986 break;
2987 }
2988
2989 if (resolveFamily === null) {
2990 throw new Error('Expected resolveFamily to be set during hot reload.');
2991 }
2992
2993 var needsRender = false;
2994 var needsRemount = false;
2995
2996 if (candidateType !== null) {
2997 var family = resolveFamily(candidateType);
2998
2999 if (family !== undefined) {
3000 if (staleFamilies.has(family)) {
3001 needsRemount = true;
3002 } else if (updatedFamilies.has(family)) {
3003 if (tag === ClassComponent) {
3004 needsRemount = true;
3005 } else {
3006 needsRender = true;
3007 }
3008 }
3009 }
3010 }
3011
3012 if (failedBoundaries !== null) {
3013 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
3014 needsRemount = true;
3015 }
3016 }
3017
3018 if (needsRemount) {
3019 fiber._debugNeedsRemount = true;
3020 }
3021
3022 if (needsRemount || needsRender) {
3023 scheduleWork(fiber, Sync);
3024 }
3025
3026 if (child !== null && !needsRemount) {
3027 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
3028 }
3029
3030 if (sibling !== null) {
3031 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
3032 }
3033 }
3034 }
3035
3036 var findHostInstancesForRefresh = function (root, families) {
3037 {
3038 var hostInstances = new Set();
3039 var types = new Set(families.map(function (family) {
3040 return family.current;
3041 }));
3042 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
3043 return hostInstances;
3044 }
3045 };
3046
3047 function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
3048 {
3049 var child = fiber.child,
3050 sibling = fiber.sibling,
3051 tag = fiber.tag,
3052 type = fiber.type;
3053 var candidateType = null;
3054
3055 switch (tag) {
3056 case FunctionComponent:
3057 case SimpleMemoComponent:
3058 case ClassComponent:
3059 candidateType = type;
3060 break;
3061
3062 case ForwardRef:
3063 candidateType = type.render;
3064 break;
3065 }
3066
3067 var didMatch = false;
3068
3069 if (candidateType !== null) {
3070 if (types.has(candidateType)) {
3071 didMatch = true;
3072 }
3073 }
3074
3075 if (didMatch) {
3076 // We have a match. This only drills down to the closest host components.
3077 // There's no need to search deeper because for the purpose of giving
3078 // visual feedback, "flashing" outermost parent rectangles is sufficient.
3079 findHostInstancesForFiberShallowly(fiber, hostInstances);
3080 } else {
3081 // If there's no match, maybe there will be one further down in the child tree.
3082 if (child !== null) {
3083 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
3084 }
3085 }
3086
3087 if (sibling !== null) {
3088 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
3089 }
3090 }
3091 }
3092
3093 function findHostInstancesForFiberShallowly(fiber, hostInstances) {
3094 {
3095 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
3096
3097 if (foundHostInstances) {
3098 return;
3099 } // If we didn't find any host children, fallback to closest host parent.
3100
3101
3102 var node = fiber;
3103
3104 while (true) {
3105 switch (node.tag) {
3106 case HostComponent:
3107 hostInstances.add(node.stateNode);
3108 return;
3109
3110 case HostPortal:
3111 hostInstances.add(node.stateNode.containerInfo);
3112 return;
3113
3114 case HostRoot:
3115 hostInstances.add(node.stateNode.containerInfo);
3116 return;
3117 }
3118
3119 if (node.return === null) {
3120 throw new Error('Expected to reach root first.');
3121 }
3122
3123 node = node.return;
3124 }
3125 }
3126 }
3127
3128 function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
3129 {
3130 var node = fiber;
3131 var foundHostInstances = false;
3132
3133 while (true) {
3134 if (node.tag === HostComponent) {
3135 // We got a match.
3136 foundHostInstances = true;
3137 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
3138 } else if (node.child !== null) {
3139 node.child.return = node;
3140 node = node.child;
3141 continue;
3142 }
3143
3144 if (node === fiber) {
3145 return foundHostInstances;
3146 }
3147
3148 while (node.sibling === null) {
3149 if (node.return === null || node.return === fiber) {
3150 return foundHostInstances;
3151 }
3152
3153 node = node.return;
3154 }
3155
3156 node.sibling.return = node.return;
3157 node = node.sibling;
3158 }
3159 }
3160
3161 return false;
3162 }
3163
3164 function resolveDefaultProps(Component, baseProps) {
3165 if (Component && Component.defaultProps) {
3166 // Resolve default props. Taken from ReactElement
3167 var props = _assign({}, baseProps);
3168
3169 var defaultProps = Component.defaultProps;
3170
3171 for (var propName in defaultProps) {
3172 if (props[propName] === undefined) {
3173 props[propName] = defaultProps[propName];
3174 }
3175 }
3176
3177 return props;
3178 }
3179
3180 return baseProps;
3181 }
3182 function readLazyComponentType(lazyComponent) {
3183 initializeLazyComponentType(lazyComponent);
3184
3185 if (lazyComponent._status !== Resolved) {
3186 throw lazyComponent._result;
3187 }
3188
3189 return lazyComponent._result;
3190 }
3191
3192 var valueCursor = createCursor(null);
3193 var rendererSigil;
3194
3195 {
3196 // Use this to detect multiple renderers using the same context
3197 rendererSigil = {};
3198 }
3199
3200 var currentlyRenderingFiber = null;
3201 var lastContextDependency = null;
3202 var lastContextWithAllBitsObserved = null;
3203 var isDisallowedContextReadInDEV = false;
3204 function resetContextDependencies() {
3205 // This is called right before React yields execution, to ensure `readContext`
3206 // cannot be called outside the render phase.
3207 currentlyRenderingFiber = null;
3208 lastContextDependency = null;
3209 lastContextWithAllBitsObserved = null;
3210
3211 {
3212 isDisallowedContextReadInDEV = false;
3213 }
3214 }
3215 function enterDisallowedContextReadInDEV() {
3216 {
3217 isDisallowedContextReadInDEV = true;
3218 }
3219 }
3220 function exitDisallowedContextReadInDEV() {
3221 {
3222 isDisallowedContextReadInDEV = false;
3223 }
3224 }
3225 function pushProvider(providerFiber, nextValue) {
3226 var context = providerFiber.type._context;
3227
3228 {
3229 push(valueCursor, context._currentValue2, providerFiber);
3230 context._currentValue2 = nextValue;
3231
3232 {
3233 if (context._currentRenderer2 !== undefined && context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil) {
3234 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
3235 }
3236
3237 context._currentRenderer2 = rendererSigil;
3238 }
3239 }
3240 }
3241 function popProvider(providerFiber) {
3242 var currentValue = valueCursor.current;
3243 pop(valueCursor, providerFiber);
3244 var context = providerFiber.type._context;
3245
3246 {
3247 context._currentValue2 = currentValue;
3248 }
3249 }
3250 function calculateChangedBits(context, newValue, oldValue) {
3251 if (objectIs(oldValue, newValue)) {
3252 // No change
3253 return 0;
3254 } else {
3255 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
3256
3257 {
3258 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
3259 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
3260 }
3261 }
3262
3263 return changedBits | 0;
3264 }
3265 }
3266 function scheduleWorkOnParentPath(parent, renderExpirationTime) {
3267 // Update the child expiration time of all the ancestors, including
3268 // the alternates.
3269 var node = parent;
3270
3271 while (node !== null) {
3272 var alternate = node.alternate;
3273
3274 if (node.childExpirationTime < renderExpirationTime) {
3275 node.childExpirationTime = renderExpirationTime;
3276
3277 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3278 alternate.childExpirationTime = renderExpirationTime;
3279 }
3280 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3281 alternate.childExpirationTime = renderExpirationTime;
3282 } else {
3283 // Neither alternate was updated, which means the rest of the
3284 // ancestor path already has sufficient priority.
3285 break;
3286 }
3287
3288 node = node.return;
3289 }
3290 }
3291 function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
3292 var fiber = workInProgress.child;
3293
3294 if (fiber !== null) {
3295 // Set the return pointer of the child to the work-in-progress fiber.
3296 fiber.return = workInProgress;
3297 }
3298
3299 while (fiber !== null) {
3300 var nextFiber = void 0; // Visit this fiber.
3301
3302 var list = fiber.dependencies;
3303
3304 if (list !== null) {
3305 nextFiber = fiber.child;
3306 var dependency = list.firstContext;
3307
3308 while (dependency !== null) {
3309 // Check if the context matches.
3310 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
3311 // Match! Schedule an update on this fiber.
3312 if (fiber.tag === ClassComponent) {
3313 // Schedule a force update on the work-in-progress.
3314 var update = createUpdate(renderExpirationTime, null);
3315 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
3316 // update to the current fiber, too, which means it will persist even if
3317 // this render is thrown away. Since it's a race condition, not sure it's
3318 // worth fixing.
3319
3320 enqueueUpdate(fiber, update);
3321 }
3322
3323 if (fiber.expirationTime < renderExpirationTime) {
3324 fiber.expirationTime = renderExpirationTime;
3325 }
3326
3327 var alternate = fiber.alternate;
3328
3329 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
3330 alternate.expirationTime = renderExpirationTime;
3331 }
3332
3333 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
3334
3335 if (list.expirationTime < renderExpirationTime) {
3336 list.expirationTime = renderExpirationTime;
3337 } // Since we already found a match, we can stop traversing the
3338 // dependency list.
3339
3340
3341 break;
3342 }
3343
3344 dependency = dependency.next;
3345 }
3346 } else if (fiber.tag === ContextProvider) {
3347 // Don't scan deeper if this is a matching provider
3348 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
3349 } else {
3350 // Traverse down.
3351 nextFiber = fiber.child;
3352 }
3353
3354 if (nextFiber !== null) {
3355 // Set the return pointer of the child to the work-in-progress fiber.
3356 nextFiber.return = fiber;
3357 } else {
3358 // No child. Traverse to next sibling.
3359 nextFiber = fiber;
3360
3361 while (nextFiber !== null) {
3362 if (nextFiber === workInProgress) {
3363 // We're back to the root of this subtree. Exit.
3364 nextFiber = null;
3365 break;
3366 }
3367
3368 var sibling = nextFiber.sibling;
3369
3370 if (sibling !== null) {
3371 // Set the return pointer of the sibling to the work-in-progress fiber.
3372 sibling.return = nextFiber.return;
3373 nextFiber = sibling;
3374 break;
3375 } // No more siblings. Traverse up.
3376
3377
3378 nextFiber = nextFiber.return;
3379 }
3380 }
3381
3382 fiber = nextFiber;
3383 }
3384 }
3385 function prepareToReadContext(workInProgress, renderExpirationTime) {
3386 currentlyRenderingFiber = workInProgress;
3387 lastContextDependency = null;
3388 lastContextWithAllBitsObserved = null;
3389 var dependencies = workInProgress.dependencies;
3390
3391 if (dependencies !== null) {
3392 var firstContext = dependencies.firstContext;
3393
3394 if (firstContext !== null) {
3395 if (dependencies.expirationTime >= renderExpirationTime) {
3396 // Context list has a pending update. Mark that this fiber performed work.
3397 markWorkInProgressReceivedUpdate();
3398 } // Reset the work-in-progress list
3399
3400
3401 dependencies.firstContext = null;
3402 }
3403 }
3404 }
3405 function readContext(context, observedBits) {
3406 {
3407 // This warning would fire if you read context inside a Hook like useMemo.
3408 // Unlike the class check below, it's not enforced in production for perf.
3409 if (isDisallowedContextReadInDEV) {
3410 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().');
3411 }
3412 }
3413
3414 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
3415 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
3416
3417 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
3418 // Observe all updates.
3419 lastContextWithAllBitsObserved = context;
3420 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
3421 } else {
3422 resolvedObservedBits = observedBits;
3423 }
3424
3425 var contextItem = {
3426 context: context,
3427 observedBits: resolvedObservedBits,
3428 next: null
3429 };
3430
3431 if (lastContextDependency === null) {
3432 if (!(currentlyRenderingFiber !== null)) {
3433 {
3434 throw Error( "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." );
3435 }
3436 } // This is the first dependency for this component. Create a new list.
3437
3438
3439 lastContextDependency = contextItem;
3440 currentlyRenderingFiber.dependencies = {
3441 expirationTime: NoWork,
3442 firstContext: contextItem,
3443 responders: null
3444 };
3445 } else {
3446 // Append a new context item.
3447 lastContextDependency = lastContextDependency.next = contextItem;
3448 }
3449 }
3450
3451 return context._currentValue2;
3452 }
3453
3454 var UpdateState = 0;
3455 var ReplaceState = 1;
3456 var ForceUpdate = 2;
3457 var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
3458 // It should only be read right after calling `processUpdateQueue`, via
3459 // `checkHasForceUpdateAfterProcessing`.
3460
3461 var hasForceUpdate = false;
3462 var didWarnUpdateInsideUpdate;
3463 var currentlyProcessingQueue;
3464
3465 {
3466 didWarnUpdateInsideUpdate = false;
3467 currentlyProcessingQueue = null;
3468 }
3469
3470 function initializeUpdateQueue(fiber) {
3471 var queue = {
3472 baseState: fiber.memoizedState,
3473 baseQueue: null,
3474 shared: {
3475 pending: null
3476 },
3477 effects: null
3478 };
3479 fiber.updateQueue = queue;
3480 }
3481 function cloneUpdateQueue(current, workInProgress) {
3482 // Clone the update queue from current. Unless it's already a clone.
3483 var queue = workInProgress.updateQueue;
3484 var currentQueue = current.updateQueue;
3485
3486 if (queue === currentQueue) {
3487 var clone = {
3488 baseState: currentQueue.baseState,
3489 baseQueue: currentQueue.baseQueue,
3490 shared: currentQueue.shared,
3491 effects: currentQueue.effects
3492 };
3493 workInProgress.updateQueue = clone;
3494 }
3495 }
3496 function createUpdate(expirationTime, suspenseConfig) {
3497 var update = {
3498 expirationTime: expirationTime,
3499 suspenseConfig: suspenseConfig,
3500 tag: UpdateState,
3501 payload: null,
3502 callback: null,
3503 next: null
3504 };
3505 update.next = update;
3506
3507 {
3508 update.priority = getCurrentPriorityLevel();
3509 }
3510
3511 return update;
3512 }
3513 function enqueueUpdate(fiber, update) {
3514 var updateQueue = fiber.updateQueue;
3515
3516 if (updateQueue === null) {
3517 // Only occurs if the fiber has been unmounted.
3518 return;
3519 }
3520
3521 var sharedQueue = updateQueue.shared;
3522 var pending = sharedQueue.pending;
3523
3524 if (pending === null) {
3525 // This is the first update. Create a circular list.
3526 update.next = update;
3527 } else {
3528 update.next = pending.next;
3529 pending.next = update;
3530 }
3531
3532 sharedQueue.pending = update;
3533
3534 {
3535 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
3536 error('An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
3537
3538 didWarnUpdateInsideUpdate = true;
3539 }
3540 }
3541 }
3542 function enqueueCapturedUpdate(workInProgress, update) {
3543 var current = workInProgress.alternate;
3544
3545 if (current !== null) {
3546 // Ensure the work-in-progress queue is a clone
3547 cloneUpdateQueue(current, workInProgress);
3548 } // Captured updates go only on the work-in-progress queue.
3549
3550
3551 var queue = workInProgress.updateQueue; // Append the update to the end of the list.
3552
3553 var last = queue.baseQueue;
3554
3555 if (last === null) {
3556 queue.baseQueue = update.next = update;
3557 update.next = update;
3558 } else {
3559 update.next = last.next;
3560 last.next = update;
3561 }
3562 }
3563
3564 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3565 switch (update.tag) {
3566 case ReplaceState:
3567 {
3568 var payload = update.payload;
3569
3570 if (typeof payload === 'function') {
3571 // Updater function
3572 {
3573 enterDisallowedContextReadInDEV();
3574
3575 if ( workInProgress.mode & StrictMode) {
3576 payload.call(instance, prevState, nextProps);
3577 }
3578 }
3579
3580 var nextState = payload.call(instance, prevState, nextProps);
3581
3582 {
3583 exitDisallowedContextReadInDEV();
3584 }
3585
3586 return nextState;
3587 } // State object
3588
3589
3590 return payload;
3591 }
3592
3593 case CaptureUpdate:
3594 {
3595 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
3596 }
3597 // Intentional fallthrough
3598
3599 case UpdateState:
3600 {
3601 var _payload = update.payload;
3602 var partialState;
3603
3604 if (typeof _payload === 'function') {
3605 // Updater function
3606 {
3607 enterDisallowedContextReadInDEV();
3608
3609 if ( workInProgress.mode & StrictMode) {
3610 _payload.call(instance, prevState, nextProps);
3611 }
3612 }
3613
3614 partialState = _payload.call(instance, prevState, nextProps);
3615
3616 {
3617 exitDisallowedContextReadInDEV();
3618 }
3619 } else {
3620 // Partial state object
3621 partialState = _payload;
3622 }
3623
3624 if (partialState === null || partialState === undefined) {
3625 // Null and undefined are treated as no-ops.
3626 return prevState;
3627 } // Merge the partial state and the previous state.
3628
3629
3630 return _assign({}, prevState, partialState);
3631 }
3632
3633 case ForceUpdate:
3634 {
3635 hasForceUpdate = true;
3636 return prevState;
3637 }
3638 }
3639
3640 return prevState;
3641 }
3642
3643 function processUpdateQueue(workInProgress, props, instance, renderExpirationTime) {
3644 // This is always non-null on a ClassComponent or HostRoot
3645 var queue = workInProgress.updateQueue;
3646 hasForceUpdate = false;
3647
3648 {
3649 currentlyProcessingQueue = queue.shared;
3650 } // The last rebase update that is NOT part of the base state.
3651
3652
3653 var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet.
3654
3655 var pendingQueue = queue.shared.pending;
3656
3657 if (pendingQueue !== null) {
3658 // We have new updates that haven't been processed yet.
3659 // We'll add them to the base queue.
3660 if (baseQueue !== null) {
3661 // Merge the pending queue and the base queue.
3662 var baseFirst = baseQueue.next;
3663 var pendingFirst = pendingQueue.next;
3664 baseQueue.next = pendingFirst;
3665 pendingQueue.next = baseFirst;
3666 }
3667
3668 baseQueue = pendingQueue;
3669 queue.shared.pending = null; // TODO: Pass `current` as argument
3670
3671 var current = workInProgress.alternate;
3672
3673 if (current !== null) {
3674 var currentQueue = current.updateQueue;
3675
3676 if (currentQueue !== null) {
3677 currentQueue.baseQueue = pendingQueue;
3678 }
3679 }
3680 } // These values may change as we process the queue.
3681
3682
3683 if (baseQueue !== null) {
3684 var first = baseQueue.next; // Iterate through the list of updates to compute the result.
3685
3686 var newState = queue.baseState;
3687 var newExpirationTime = NoWork;
3688 var newBaseState = null;
3689 var newBaseQueueFirst = null;
3690 var newBaseQueueLast = null;
3691
3692 if (first !== null) {
3693 var update = first;
3694
3695 do {
3696 var updateExpirationTime = update.expirationTime;
3697
3698 if (updateExpirationTime < renderExpirationTime) {
3699 // Priority is insufficient. Skip this update. If this is the first
3700 // skipped update, the previous update/state is the new base
3701 // update/state.
3702 var clone = {
3703 expirationTime: update.expirationTime,
3704 suspenseConfig: update.suspenseConfig,
3705 tag: update.tag,
3706 payload: update.payload,
3707 callback: update.callback,
3708 next: null
3709 };
3710
3711 if (newBaseQueueLast === null) {
3712 newBaseQueueFirst = newBaseQueueLast = clone;
3713 newBaseState = newState;
3714 } else {
3715 newBaseQueueLast = newBaseQueueLast.next = clone;
3716 } // Update the remaining priority in the queue.
3717
3718
3719 if (updateExpirationTime > newExpirationTime) {
3720 newExpirationTime = updateExpirationTime;
3721 }
3722 } else {
3723 // This update does have sufficient priority.
3724 if (newBaseQueueLast !== null) {
3725 var _clone = {
3726 expirationTime: Sync,
3727 // This update is going to be committed so we never want uncommit it.
3728 suspenseConfig: update.suspenseConfig,
3729 tag: update.tag,
3730 payload: update.payload,
3731 callback: update.callback,
3732 next: null
3733 };
3734 newBaseQueueLast = newBaseQueueLast.next = _clone;
3735 } // Mark the event time of this update as relevant to this render pass.
3736 // TODO: This should ideally use the true event time of this update rather than
3737 // its priority which is a derived and not reverseable value.
3738 // TODO: We should skip this update if it was already committed but currently
3739 // we have no way of detecting the difference between a committed and suspended
3740 // update here.
3741
3742
3743 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
3744
3745 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
3746 var callback = update.callback;
3747
3748 if (callback !== null) {
3749 workInProgress.effectTag |= Callback;
3750 var effects = queue.effects;
3751
3752 if (effects === null) {
3753 queue.effects = [update];
3754 } else {
3755 effects.push(update);
3756 }
3757 }
3758 }
3759
3760 update = update.next;
3761
3762 if (update === null || update === first) {
3763 pendingQueue = queue.shared.pending;
3764
3765 if (pendingQueue === null) {
3766 break;
3767 } else {
3768 // An update was scheduled from inside a reducer. Add the new
3769 // pending updates to the end of the list and keep processing.
3770 update = baseQueue.next = pendingQueue.next;
3771 pendingQueue.next = first;
3772 queue.baseQueue = baseQueue = pendingQueue;
3773 queue.shared.pending = null;
3774 }
3775 }
3776 } while (true);
3777 }
3778
3779 if (newBaseQueueLast === null) {
3780 newBaseState = newState;
3781 } else {
3782 newBaseQueueLast.next = newBaseQueueFirst;
3783 }
3784
3785 queue.baseState = newBaseState;
3786 queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue.
3787 // This should be fine because the only two other things that contribute to
3788 // expiration time are props and context. We're already in the middle of the
3789 // begin phase by the time we start processing the queue, so we've already
3790 // dealt with the props. Context in components that specify
3791 // shouldComponentUpdate is tricky; but we'll have to account for
3792 // that regardless.
3793
3794 markUnprocessedUpdateTime(newExpirationTime);
3795 workInProgress.expirationTime = newExpirationTime;
3796 workInProgress.memoizedState = newState;
3797 }
3798
3799 {
3800 currentlyProcessingQueue = null;
3801 }
3802 }
3803
3804 function callCallback(callback, context) {
3805 if (!(typeof callback === 'function')) {
3806 {
3807 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
3808 }
3809 }
3810
3811 callback.call(context);
3812 }
3813
3814 function resetHasForceUpdateBeforeProcessing() {
3815 hasForceUpdate = false;
3816 }
3817 function checkHasForceUpdateAfterProcessing() {
3818 return hasForceUpdate;
3819 }
3820 function commitUpdateQueue(finishedWork, finishedQueue, instance) {
3821 // Commit the effects
3822 var effects = finishedQueue.effects;
3823 finishedQueue.effects = null;
3824
3825 if (effects !== null) {
3826 for (var i = 0; i < effects.length; i++) {
3827 var effect = effects[i];
3828 var callback = effect.callback;
3829
3830 if (callback !== null) {
3831 effect.callback = null;
3832 callCallback(callback, instance);
3833 }
3834 }
3835 }
3836 }
3837
3838 var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
3839 function requestCurrentSuspenseConfig() {
3840 return ReactCurrentBatchConfig.suspense;
3841 }
3842
3843 var fakeInternalInstance = {};
3844 var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
3845 // We'll use it to determine whether we need to initialize legacy refs.
3846
3847 var emptyRefsObject = new React.Component().refs;
3848 var didWarnAboutStateAssignmentForComponent;
3849 var didWarnAboutUninitializedState;
3850 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
3851 var didWarnAboutLegacyLifecyclesAndDerivedState;
3852 var didWarnAboutUndefinedDerivedState;
3853 var warnOnUndefinedDerivedState;
3854 var warnOnInvalidCallback;
3855 var didWarnAboutDirectlyAssigningPropsToState;
3856 var didWarnAboutContextTypeAndContextTypes;
3857 var didWarnAboutInvalidateContextType;
3858
3859 {
3860 didWarnAboutStateAssignmentForComponent = new Set();
3861 didWarnAboutUninitializedState = new Set();
3862 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3863 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3864 didWarnAboutDirectlyAssigningPropsToState = new Set();
3865 didWarnAboutUndefinedDerivedState = new Set();
3866 didWarnAboutContextTypeAndContextTypes = new Set();
3867 didWarnAboutInvalidateContextType = new Set();
3868 var didWarnOnInvalidCallback = new Set();
3869
3870 warnOnInvalidCallback = function (callback, callerName) {
3871 if (callback === null || typeof callback === 'function') {
3872 return;
3873 }
3874
3875 var key = callerName + "_" + callback;
3876
3877 if (!didWarnOnInvalidCallback.has(key)) {
3878 didWarnOnInvalidCallback.add(key);
3879
3880 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3881 }
3882 };
3883
3884 warnOnUndefinedDerivedState = function (type, partialState) {
3885 if (partialState === undefined) {
3886 var componentName = getComponentName(type) || 'Component';
3887
3888 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3889 didWarnAboutUndefinedDerivedState.add(componentName);
3890
3891 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3892 }
3893 }
3894 }; // This is so gross but it's at least non-critical and can be removed if
3895 // it causes problems. This is meant to give a nicer error message for
3896 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3897 // ...)) which otherwise throws a "_processChildContext is not a function"
3898 // exception.
3899
3900
3901 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3902 enumerable: false,
3903 value: function () {
3904 {
3905 {
3906 throw Error( "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." );
3907 }
3908 }
3909 }
3910 });
3911 Object.freeze(fakeInternalInstance);
3912 }
3913
3914 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3915 var prevState = workInProgress.memoizedState;
3916
3917 {
3918 if ( workInProgress.mode & StrictMode) {
3919 // Invoke the function an extra time to help detect side-effects.
3920 getDerivedStateFromProps(nextProps, prevState);
3921 }
3922 }
3923
3924 var partialState = getDerivedStateFromProps(nextProps, prevState);
3925
3926 {
3927 warnOnUndefinedDerivedState(ctor, partialState);
3928 } // Merge the partial state and the previous state.
3929
3930
3931 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3932 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
3933 // base state.
3934
3935 if (workInProgress.expirationTime === NoWork) {
3936 // Queue is always non-null for classes
3937 var updateQueue = workInProgress.updateQueue;
3938 updateQueue.baseState = memoizedState;
3939 }
3940 }
3941 var classComponentUpdater = {
3942 isMounted: isMounted,
3943 enqueueSetState: function (inst, payload, callback) {
3944 var fiber = get(inst);
3945 var currentTime = requestCurrentTimeForUpdate();
3946 var suspenseConfig = requestCurrentSuspenseConfig();
3947 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3948 var update = createUpdate(expirationTime, suspenseConfig);
3949 update.payload = payload;
3950
3951 if (callback !== undefined && callback !== null) {
3952 {
3953 warnOnInvalidCallback(callback, 'setState');
3954 }
3955
3956 update.callback = callback;
3957 }
3958
3959 enqueueUpdate(fiber, update);
3960 scheduleWork(fiber, expirationTime);
3961 },
3962 enqueueReplaceState: function (inst, payload, callback) {
3963 var fiber = get(inst);
3964 var currentTime = requestCurrentTimeForUpdate();
3965 var suspenseConfig = requestCurrentSuspenseConfig();
3966 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3967 var update = createUpdate(expirationTime, suspenseConfig);
3968 update.tag = ReplaceState;
3969 update.payload = payload;
3970
3971 if (callback !== undefined && callback !== null) {
3972 {
3973 warnOnInvalidCallback(callback, 'replaceState');
3974 }
3975
3976 update.callback = callback;
3977 }
3978
3979 enqueueUpdate(fiber, update);
3980 scheduleWork(fiber, expirationTime);
3981 },
3982 enqueueForceUpdate: function (inst, callback) {
3983 var fiber = get(inst);
3984 var currentTime = requestCurrentTimeForUpdate();
3985 var suspenseConfig = requestCurrentSuspenseConfig();
3986 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3987 var update = createUpdate(expirationTime, suspenseConfig);
3988 update.tag = ForceUpdate;
3989
3990 if (callback !== undefined && callback !== null) {
3991 {
3992 warnOnInvalidCallback(callback, 'forceUpdate');
3993 }
3994
3995 update.callback = callback;
3996 }
3997
3998 enqueueUpdate(fiber, update);
3999 scheduleWork(fiber, expirationTime);
4000 }
4001 };
4002
4003 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
4004 var instance = workInProgress.stateNode;
4005
4006 if (typeof instance.shouldComponentUpdate === 'function') {
4007 {
4008 if ( workInProgress.mode & StrictMode) {
4009 // Invoke the function an extra time to help detect side-effects.
4010 instance.shouldComponentUpdate(newProps, newState, nextContext);
4011 }
4012 }
4013
4014 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
4015 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
4016 stopPhaseTimer();
4017
4018 {
4019 if (shouldUpdate === undefined) {
4020 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
4021 }
4022 }
4023
4024 return shouldUpdate;
4025 }
4026
4027 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
4028 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
4029 }
4030
4031 return true;
4032 }
4033
4034 function checkClassInstance(workInProgress, ctor, newProps) {
4035 var instance = workInProgress.stateNode;
4036
4037 {
4038 var name = getComponentName(ctor) || 'Component';
4039 var renderPresent = instance.render;
4040
4041 if (!renderPresent) {
4042 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
4043 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
4044 } else {
4045 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
4046 }
4047 }
4048
4049 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
4050 error('getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name);
4051 }
4052
4053 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
4054 error('getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name);
4055 }
4056
4057 if (instance.propTypes) {
4058 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
4059 }
4060
4061 if (instance.contextType) {
4062 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
4063 }
4064
4065 {
4066 if (instance.contextTypes) {
4067 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
4068 }
4069
4070 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
4071 didWarnAboutContextTypeAndContextTypes.add(ctor);
4072
4073 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
4074 }
4075 }
4076
4077 if (typeof instance.componentShouldUpdate === 'function') {
4078 error('%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name);
4079 }
4080
4081 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
4082 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
4083 }
4084
4085 if (typeof instance.componentDidUnmount === 'function') {
4086 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
4087 }
4088
4089 if (typeof instance.componentDidReceiveProps === 'function') {
4090 error('%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name);
4091 }
4092
4093 if (typeof instance.componentWillRecieveProps === 'function') {
4094 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
4095 }
4096
4097 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
4098 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
4099 }
4100
4101 var hasMutatedProps = instance.props !== newProps;
4102
4103 if (instance.props !== undefined && hasMutatedProps) {
4104 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
4105 }
4106
4107 if (instance.defaultProps) {
4108 error('Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name);
4109 }
4110
4111 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
4112 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
4113
4114 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
4115 }
4116
4117 if (typeof instance.getDerivedStateFromProps === 'function') {
4118 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
4119 }
4120
4121 if (typeof instance.getDerivedStateFromError === 'function') {
4122 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
4123 }
4124
4125 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
4126 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
4127 }
4128
4129 var _state = instance.state;
4130
4131 if (_state && (typeof _state !== 'object' || isArray(_state))) {
4132 error('%s.state: must be set to an object or null', name);
4133 }
4134
4135 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
4136 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
4137 }
4138 }
4139 }
4140
4141 function adoptClassInstance(workInProgress, instance) {
4142 instance.updater = classComponentUpdater;
4143 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
4144
4145 set(instance, workInProgress);
4146
4147 {
4148 instance._reactInternalInstance = fakeInternalInstance;
4149 }
4150 }
4151
4152 function constructClassInstance(workInProgress, ctor, props) {
4153 var isLegacyContextConsumer = false;
4154 var unmaskedContext = emptyContextObject;
4155 var context = emptyContextObject;
4156 var contextType = ctor.contextType;
4157
4158 {
4159 if ('contextType' in ctor) {
4160 var isValid = // Allow null for conditional declaration
4161 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
4162
4163 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
4164 didWarnAboutInvalidateContextType.add(ctor);
4165 var addendum = '';
4166
4167 if (contextType === undefined) {
4168 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.';
4169 } else if (typeof contextType !== 'object') {
4170 addendum = ' However, it is set to a ' + typeof contextType + '.';
4171 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
4172 addendum = ' Did you accidentally pass the Context.Provider instead?';
4173 } else if (contextType._context !== undefined) {
4174 // <Context.Consumer>
4175 addendum = ' Did you accidentally pass the Context.Consumer instead?';
4176 } else {
4177 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
4178 }
4179
4180 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
4181 }
4182 }
4183 }
4184
4185 if (typeof contextType === 'object' && contextType !== null) {
4186 context = readContext(contextType);
4187 } else {
4188 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4189 var contextTypes = ctor.contextTypes;
4190 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
4191 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
4192 } // Instantiate twice to help detect side-effects.
4193
4194
4195 {
4196 if ( workInProgress.mode & StrictMode) {
4197 new ctor(props, context); // eslint-disable-line no-new
4198 }
4199 }
4200
4201 var instance = new ctor(props, context);
4202 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
4203 adoptClassInstance(workInProgress, instance);
4204
4205 {
4206 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
4207 var componentName = getComponentName(ctor) || 'Component';
4208
4209 if (!didWarnAboutUninitializedState.has(componentName)) {
4210 didWarnAboutUninitializedState.add(componentName);
4211
4212 error('`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
4213 }
4214 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
4215 // Warn about these lifecycles if they are present.
4216 // Don't warn about react-lifecycles-compat polyfilled methods though.
4217
4218
4219 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
4220 var foundWillMountName = null;
4221 var foundWillReceivePropsName = null;
4222 var foundWillUpdateName = null;
4223
4224 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
4225 foundWillMountName = 'componentWillMount';
4226 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
4227 foundWillMountName = 'UNSAFE_componentWillMount';
4228 }
4229
4230 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
4231 foundWillReceivePropsName = 'componentWillReceiveProps';
4232 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4233 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
4234 }
4235
4236 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
4237 foundWillUpdateName = 'componentWillUpdate';
4238 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4239 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
4240 }
4241
4242 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
4243 var _componentName = getComponentName(ctor) || 'Component';
4244
4245 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
4246
4247 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
4248 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
4249
4250 error('Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
4251 }
4252 }
4253 }
4254 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
4255 // ReactFiberContext usually updates this cache but can't for newly-created instances.
4256
4257
4258 if (isLegacyContextConsumer) {
4259 cacheContext(workInProgress, unmaskedContext, context);
4260 }
4261
4262 return instance;
4263 }
4264
4265 function callComponentWillMount(workInProgress, instance) {
4266 startPhaseTimer(workInProgress, 'componentWillMount');
4267 var oldState = instance.state;
4268
4269 if (typeof instance.componentWillMount === 'function') {
4270 instance.componentWillMount();
4271 }
4272
4273 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4274 instance.UNSAFE_componentWillMount();
4275 }
4276
4277 stopPhaseTimer();
4278
4279 if (oldState !== instance.state) {
4280 {
4281 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
4282 }
4283
4284 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4285 }
4286 }
4287
4288 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4289 var oldState = instance.state;
4290 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4291
4292 if (typeof instance.componentWillReceiveProps === 'function') {
4293 instance.componentWillReceiveProps(newProps, nextContext);
4294 }
4295
4296 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4297 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4298 }
4299
4300 stopPhaseTimer();
4301
4302 if (instance.state !== oldState) {
4303 {
4304 var componentName = getComponentName(workInProgress.type) || 'Component';
4305
4306 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4307 didWarnAboutStateAssignmentForComponent.add(componentName);
4308
4309 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4310 }
4311 }
4312
4313 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4314 }
4315 } // Invokes the mount life-cycles on a previously never rendered instance.
4316
4317
4318 function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4319 {
4320 checkClassInstance(workInProgress, ctor, newProps);
4321 }
4322
4323 var instance = workInProgress.stateNode;
4324 instance.props = newProps;
4325 instance.state = workInProgress.memoizedState;
4326 instance.refs = emptyRefsObject;
4327 initializeUpdateQueue(workInProgress);
4328 var contextType = ctor.contextType;
4329
4330 if (typeof contextType === 'object' && contextType !== null) {
4331 instance.context = readContext(contextType);
4332 } else {
4333 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4334 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4335 }
4336
4337 {
4338 if (instance.state === newProps) {
4339 var componentName = getComponentName(ctor) || 'Component';
4340
4341 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4342 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4343
4344 error('%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
4345 }
4346 }
4347
4348 if (workInProgress.mode & StrictMode) {
4349 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4350 }
4351
4352 {
4353 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4354 }
4355 }
4356
4357 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4358 instance.state = workInProgress.memoizedState;
4359 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4360
4361 if (typeof getDerivedStateFromProps === 'function') {
4362 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4363 instance.state = workInProgress.memoizedState;
4364 } // In order to support react-lifecycles-compat polyfilled components,
4365 // Unsafe lifecycles should not be invoked for components using the new APIs.
4366
4367
4368 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4369 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
4370 // process them now.
4371
4372 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4373 instance.state = workInProgress.memoizedState;
4374 }
4375
4376 if (typeof instance.componentDidMount === 'function') {
4377 workInProgress.effectTag |= Update;
4378 }
4379 }
4380
4381 function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4382 var instance = workInProgress.stateNode;
4383 var oldProps = workInProgress.memoizedProps;
4384 instance.props = oldProps;
4385 var oldContext = instance.context;
4386 var contextType = ctor.contextType;
4387 var nextContext = emptyContextObject;
4388
4389 if (typeof contextType === 'object' && contextType !== null) {
4390 nextContext = readContext(contextType);
4391 } else {
4392 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4393 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4394 }
4395
4396 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4397 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4398 // ever the previously attempted to render - not the "current". However,
4399 // during componentDidUpdate we pass the "current" props.
4400 // In order to support react-lifecycles-compat polyfilled components,
4401 // Unsafe lifecycles should not be invoked for components using the new APIs.
4402
4403 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4404 if (oldProps !== newProps || oldContext !== nextContext) {
4405 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4406 }
4407 }
4408
4409 resetHasForceUpdateBeforeProcessing();
4410 var oldState = workInProgress.memoizedState;
4411 var newState = instance.state = oldState;
4412 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4413 newState = workInProgress.memoizedState;
4414
4415 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4416 // If an update was already in progress, we should schedule an Update
4417 // effect even though we're bailing out, so that cWU/cDU are called.
4418 if (typeof instance.componentDidMount === 'function') {
4419 workInProgress.effectTag |= Update;
4420 }
4421
4422 return false;
4423 }
4424
4425 if (typeof getDerivedStateFromProps === 'function') {
4426 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4427 newState = workInProgress.memoizedState;
4428 }
4429
4430 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4431
4432 if (shouldUpdate) {
4433 // In order to support react-lifecycles-compat polyfilled components,
4434 // Unsafe lifecycles should not be invoked for components using the new APIs.
4435 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4436 startPhaseTimer(workInProgress, 'componentWillMount');
4437
4438 if (typeof instance.componentWillMount === 'function') {
4439 instance.componentWillMount();
4440 }
4441
4442 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4443 instance.UNSAFE_componentWillMount();
4444 }
4445
4446 stopPhaseTimer();
4447 }
4448
4449 if (typeof instance.componentDidMount === 'function') {
4450 workInProgress.effectTag |= Update;
4451 }
4452 } else {
4453 // If an update was already in progress, we should schedule an Update
4454 // effect even though we're bailing out, so that cWU/cDU are called.
4455 if (typeof instance.componentDidMount === 'function') {
4456 workInProgress.effectTag |= Update;
4457 } // If shouldComponentUpdate returned false, we should still update the
4458 // memoized state to indicate that this work can be reused.
4459
4460
4461 workInProgress.memoizedProps = newProps;
4462 workInProgress.memoizedState = newState;
4463 } // Update the existing instance's state, props, and context pointers even
4464 // if shouldComponentUpdate returns false.
4465
4466
4467 instance.props = newProps;
4468 instance.state = newState;
4469 instance.context = nextContext;
4470 return shouldUpdate;
4471 } // Invokes the update life-cycles and returns false if it shouldn't rerender.
4472
4473
4474 function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4475 var instance = workInProgress.stateNode;
4476 cloneUpdateQueue(current, workInProgress);
4477 var oldProps = workInProgress.memoizedProps;
4478 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4479 var oldContext = instance.context;
4480 var contextType = ctor.contextType;
4481 var nextContext = emptyContextObject;
4482
4483 if (typeof contextType === 'object' && contextType !== null) {
4484 nextContext = readContext(contextType);
4485 } else {
4486 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4487 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4488 }
4489
4490 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4491 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4492 // ever the previously attempted to render - not the "current". However,
4493 // during componentDidUpdate we pass the "current" props.
4494 // In order to support react-lifecycles-compat polyfilled components,
4495 // Unsafe lifecycles should not be invoked for components using the new APIs.
4496
4497 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4498 if (oldProps !== newProps || oldContext !== nextContext) {
4499 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4500 }
4501 }
4502
4503 resetHasForceUpdateBeforeProcessing();
4504 var oldState = workInProgress.memoizedState;
4505 var newState = instance.state = oldState;
4506 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4507 newState = workInProgress.memoizedState;
4508
4509 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4510 // If an update was already in progress, we should schedule an Update
4511 // effect even though we're bailing out, so that cWU/cDU are called.
4512 if (typeof instance.componentDidUpdate === 'function') {
4513 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4514 workInProgress.effectTag |= Update;
4515 }
4516 }
4517
4518 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4519 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4520 workInProgress.effectTag |= Snapshot;
4521 }
4522 }
4523
4524 return false;
4525 }
4526
4527 if (typeof getDerivedStateFromProps === 'function') {
4528 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4529 newState = workInProgress.memoizedState;
4530 }
4531
4532 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4533
4534 if (shouldUpdate) {
4535 // In order to support react-lifecycles-compat polyfilled components,
4536 // Unsafe lifecycles should not be invoked for components using the new APIs.
4537 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4538 startPhaseTimer(workInProgress, 'componentWillUpdate');
4539
4540 if (typeof instance.componentWillUpdate === 'function') {
4541 instance.componentWillUpdate(newProps, newState, nextContext);
4542 }
4543
4544 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4545 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4546 }
4547
4548 stopPhaseTimer();
4549 }
4550
4551 if (typeof instance.componentDidUpdate === 'function') {
4552 workInProgress.effectTag |= Update;
4553 }
4554
4555 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4556 workInProgress.effectTag |= Snapshot;
4557 }
4558 } else {
4559 // If an update was already in progress, we should schedule an Update
4560 // effect even though we're bailing out, so that cWU/cDU are called.
4561 if (typeof instance.componentDidUpdate === 'function') {
4562 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4563 workInProgress.effectTag |= Update;
4564 }
4565 }
4566
4567 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4568 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4569 workInProgress.effectTag |= Snapshot;
4570 }
4571 } // If shouldComponentUpdate returned false, we should still update the
4572 // memoized props/state to indicate that this work can be reused.
4573
4574
4575 workInProgress.memoizedProps = newProps;
4576 workInProgress.memoizedState = newState;
4577 } // Update the existing instance's state, props, and context pointers even
4578 // if shouldComponentUpdate returns false.
4579
4580
4581 instance.props = newProps;
4582 instance.state = newState;
4583 instance.context = nextContext;
4584 return shouldUpdate;
4585 }
4586
4587 var didWarnAboutMaps;
4588 var didWarnAboutGenerators;
4589 var didWarnAboutStringRefs;
4590 var ownerHasKeyUseWarning;
4591 var ownerHasFunctionTypeWarning;
4592
4593 var warnForMissingKey = function (child) {};
4594
4595 {
4596 didWarnAboutMaps = false;
4597 didWarnAboutGenerators = false;
4598 didWarnAboutStringRefs = {};
4599 /**
4600 * Warn if there's no key explicitly set on dynamic arrays of children or
4601 * object keys are not valid. This allows us to keep track of children between
4602 * updates.
4603 */
4604
4605 ownerHasKeyUseWarning = {};
4606 ownerHasFunctionTypeWarning = {};
4607
4608 warnForMissingKey = function (child) {
4609 if (child === null || typeof child !== 'object') {
4610 return;
4611 }
4612
4613 if (!child._store || child._store.validated || child.key != null) {
4614 return;
4615 }
4616
4617 if (!(typeof child._store === 'object')) {
4618 {
4619 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
4620 }
4621 }
4622
4623 child._store.validated = true;
4624 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4625
4626 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4627 return;
4628 }
4629
4630 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4631
4632 error('Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4633 };
4634 }
4635
4636 var isArray$1 = Array.isArray;
4637
4638 function coerceRef(returnFiber, current, element) {
4639 var mixedRef = element.ref;
4640
4641 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4642 {
4643 // TODO: Clean this up once we turn on the string ref warning for
4644 // everyone, because the strict mode case will no longer be relevant
4645 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
4646 // because these cannot be automatically converted to an arrow function
4647 // using a codemod. Therefore, we don't have to warn about string refs again.
4648 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
4649 var componentName = getComponentName(returnFiber.type) || 'Component';
4650
4651 if (!didWarnAboutStringRefs[componentName]) {
4652 {
4653 error('A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', mixedRef, getStackByFiberInDevAndProd(returnFiber));
4654 }
4655
4656 didWarnAboutStringRefs[componentName] = true;
4657 }
4658 }
4659 }
4660
4661 if (element._owner) {
4662 var owner = element._owner;
4663 var inst;
4664
4665 if (owner) {
4666 var ownerFiber = owner;
4667
4668 if (!(ownerFiber.tag === ClassComponent)) {
4669 {
4670 throw Error( "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" );
4671 }
4672 }
4673
4674 inst = ownerFiber.stateNode;
4675 }
4676
4677 if (!inst) {
4678 {
4679 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
4680 }
4681 }
4682
4683 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
4684
4685 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4686 return current.ref;
4687 }
4688
4689 var ref = function (value) {
4690 var refs = inst.refs;
4691
4692 if (refs === emptyRefsObject) {
4693 // This is a lazy pooled frozen object, so we need to initialize.
4694 refs = inst.refs = {};
4695 }
4696
4697 if (value === null) {
4698 delete refs[stringRef];
4699 } else {
4700 refs[stringRef] = value;
4701 }
4702 };
4703
4704 ref._stringRef = stringRef;
4705 return ref;
4706 } else {
4707 if (!(typeof mixedRef === 'string')) {
4708 {
4709 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
4710 }
4711 }
4712
4713 if (!element._owner) {
4714 {
4715 throw Error( "Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." );
4716 }
4717 }
4718 }
4719 }
4720
4721 return mixedRef;
4722 }
4723
4724 function throwOnInvalidObjectType(returnFiber, newChild) {
4725 if (returnFiber.type !== 'textarea') {
4726 var addendum = '';
4727
4728 {
4729 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4730 }
4731
4732 {
4733 {
4734 throw Error( "Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + ")." + addendum );
4735 }
4736 }
4737 }
4738 }
4739
4740 function warnOnFunctionType() {
4741 {
4742 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();
4743
4744 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4745 return;
4746 }
4747
4748 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4749
4750 error('Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
4751 }
4752 } // This wrapper function exists because I expect to clone the code in each path
4753 // to be able to optimize each path individually by branching early. This needs
4754 // a compiler or we can do it manually. Helpers that don't need this branching
4755 // live outside of this function.
4756
4757
4758 function ChildReconciler(shouldTrackSideEffects) {
4759 function deleteChild(returnFiber, childToDelete) {
4760 if (!shouldTrackSideEffects) {
4761 // Noop.
4762 return;
4763 } // Deletions are added in reversed order so we add it to the front.
4764 // At this point, the return fiber's effect list is empty except for
4765 // deletions, so we can just append the deletion to the list. The remaining
4766 // effects aren't added until the complete phase. Once we implement
4767 // resuming, this may not be true.
4768
4769
4770 var last = returnFiber.lastEffect;
4771
4772 if (last !== null) {
4773 last.nextEffect = childToDelete;
4774 returnFiber.lastEffect = childToDelete;
4775 } else {
4776 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4777 }
4778
4779 childToDelete.nextEffect = null;
4780 childToDelete.effectTag = Deletion;
4781 }
4782
4783 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4784 if (!shouldTrackSideEffects) {
4785 // Noop.
4786 return null;
4787 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
4788 // assuming that after the first child we've already added everything.
4789
4790
4791 var childToDelete = currentFirstChild;
4792
4793 while (childToDelete !== null) {
4794 deleteChild(returnFiber, childToDelete);
4795 childToDelete = childToDelete.sibling;
4796 }
4797
4798 return null;
4799 }
4800
4801 function mapRemainingChildren(returnFiber, currentFirstChild) {
4802 // Add the remaining children to a temporary map so that we can find them by
4803 // keys quickly. Implicit (null) keys get added to this set with their index
4804 // instead.
4805 var existingChildren = new Map();
4806 var existingChild = currentFirstChild;
4807
4808 while (existingChild !== null) {
4809 if (existingChild.key !== null) {
4810 existingChildren.set(existingChild.key, existingChild);
4811 } else {
4812 existingChildren.set(existingChild.index, existingChild);
4813 }
4814
4815 existingChild = existingChild.sibling;
4816 }
4817
4818 return existingChildren;
4819 }
4820
4821 function useFiber(fiber, pendingProps) {
4822 // We currently set sibling to null and index to 0 here because it is easy
4823 // to forget to do before returning it. E.g. for the single child case.
4824 var clone = createWorkInProgress(fiber, pendingProps);
4825 clone.index = 0;
4826 clone.sibling = null;
4827 return clone;
4828 }
4829
4830 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4831 newFiber.index = newIndex;
4832
4833 if (!shouldTrackSideEffects) {
4834 // Noop.
4835 return lastPlacedIndex;
4836 }
4837
4838 var current = newFiber.alternate;
4839
4840 if (current !== null) {
4841 var oldIndex = current.index;
4842
4843 if (oldIndex < lastPlacedIndex) {
4844 // This is a move.
4845 newFiber.effectTag = Placement;
4846 return lastPlacedIndex;
4847 } else {
4848 // This item can stay in place.
4849 return oldIndex;
4850 }
4851 } else {
4852 // This is an insertion.
4853 newFiber.effectTag = Placement;
4854 return lastPlacedIndex;
4855 }
4856 }
4857
4858 function placeSingleChild(newFiber) {
4859 // This is simpler for the single child case. We only need to do a
4860 // placement for inserting new children.
4861 if (shouldTrackSideEffects && newFiber.alternate === null) {
4862 newFiber.effectTag = Placement;
4863 }
4864
4865 return newFiber;
4866 }
4867
4868 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4869 if (current === null || current.tag !== HostText) {
4870 // Insert
4871 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4872 created.return = returnFiber;
4873 return created;
4874 } else {
4875 // Update
4876 var existing = useFiber(current, textContent);
4877 existing.return = returnFiber;
4878 return existing;
4879 }
4880 }
4881
4882 function updateElement(returnFiber, current, element, expirationTime) {
4883 if (current !== null) {
4884 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
4885 isCompatibleFamilyForHotReloading(current, element) )) {
4886 // Move based on index
4887 var existing = useFiber(current, element.props);
4888 existing.ref = coerceRef(returnFiber, current, element);
4889 existing.return = returnFiber;
4890
4891 {
4892 existing._debugSource = element._source;
4893 existing._debugOwner = element._owner;
4894 }
4895
4896 return existing;
4897 }
4898 } // Insert
4899
4900
4901 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4902 created.ref = coerceRef(returnFiber, current, element);
4903 created.return = returnFiber;
4904 return created;
4905 }
4906
4907 function updatePortal(returnFiber, current, portal, expirationTime) {
4908 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4909 // Insert
4910 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4911 created.return = returnFiber;
4912 return created;
4913 } else {
4914 // Update
4915 var existing = useFiber(current, portal.children || []);
4916 existing.return = returnFiber;
4917 return existing;
4918 }
4919 }
4920
4921 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4922 if (current === null || current.tag !== Fragment) {
4923 // Insert
4924 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4925 created.return = returnFiber;
4926 return created;
4927 } else {
4928 // Update
4929 var existing = useFiber(current, fragment);
4930 existing.return = returnFiber;
4931 return existing;
4932 }
4933 }
4934
4935 function createChild(returnFiber, newChild, expirationTime) {
4936 if (typeof newChild === 'string' || typeof newChild === 'number') {
4937 // Text nodes don't have keys. If the previous node is implicitly keyed
4938 // we can continue to replace it without aborting even if it is not a text
4939 // node.
4940 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4941 created.return = returnFiber;
4942 return created;
4943 }
4944
4945 if (typeof newChild === 'object' && newChild !== null) {
4946 switch (newChild.$$typeof) {
4947 case REACT_ELEMENT_TYPE:
4948 {
4949 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4950
4951 _created.ref = coerceRef(returnFiber, null, newChild);
4952 _created.return = returnFiber;
4953 return _created;
4954 }
4955
4956 case REACT_PORTAL_TYPE:
4957 {
4958 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4959
4960 _created2.return = returnFiber;
4961 return _created2;
4962 }
4963 }
4964
4965 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4966 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4967
4968 _created3.return = returnFiber;
4969 return _created3;
4970 }
4971
4972 throwOnInvalidObjectType(returnFiber, newChild);
4973 }
4974
4975 {
4976 if (typeof newChild === 'function') {
4977 warnOnFunctionType();
4978 }
4979 }
4980
4981 return null;
4982 }
4983
4984 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4985 // Update the fiber if the keys match, otherwise return null.
4986 var key = oldFiber !== null ? oldFiber.key : null;
4987
4988 if (typeof newChild === 'string' || typeof newChild === 'number') {
4989 // Text nodes don't have keys. If the previous node is implicitly keyed
4990 // we can continue to replace it without aborting even if it is not a text
4991 // node.
4992 if (key !== null) {
4993 return null;
4994 }
4995
4996 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4997 }
4998
4999 if (typeof newChild === 'object' && newChild !== null) {
5000 switch (newChild.$$typeof) {
5001 case REACT_ELEMENT_TYPE:
5002 {
5003 if (newChild.key === key) {
5004 if (newChild.type === REACT_FRAGMENT_TYPE) {
5005 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
5006 }
5007
5008 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
5009 } else {
5010 return null;
5011 }
5012 }
5013
5014 case REACT_PORTAL_TYPE:
5015 {
5016 if (newChild.key === key) {
5017 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
5018 } else {
5019 return null;
5020 }
5021 }
5022 }
5023
5024 if (isArray$1(newChild) || getIteratorFn(newChild)) {
5025 if (key !== null) {
5026 return null;
5027 }
5028
5029 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
5030 }
5031
5032 throwOnInvalidObjectType(returnFiber, newChild);
5033 }
5034
5035 {
5036 if (typeof newChild === 'function') {
5037 warnOnFunctionType();
5038 }
5039 }
5040
5041 return null;
5042 }
5043
5044 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
5045 if (typeof newChild === 'string' || typeof newChild === 'number') {
5046 // Text nodes don't have keys, so we neither have to check the old nor
5047 // new node for the key. If both are text nodes, they match.
5048 var matchedFiber = existingChildren.get(newIdx) || null;
5049 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
5050 }
5051
5052 if (typeof newChild === 'object' && newChild !== null) {
5053 switch (newChild.$$typeof) {
5054 case REACT_ELEMENT_TYPE:
5055 {
5056 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5057
5058 if (newChild.type === REACT_FRAGMENT_TYPE) {
5059 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
5060 }
5061
5062 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
5063 }
5064
5065 case REACT_PORTAL_TYPE:
5066 {
5067 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5068
5069 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
5070 }
5071 }
5072
5073 if (isArray$1(newChild) || getIteratorFn(newChild)) {
5074 var _matchedFiber3 = existingChildren.get(newIdx) || null;
5075
5076 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
5077 }
5078
5079 throwOnInvalidObjectType(returnFiber, newChild);
5080 }
5081
5082 {
5083 if (typeof newChild === 'function') {
5084 warnOnFunctionType();
5085 }
5086 }
5087
5088 return null;
5089 }
5090 /**
5091 * Warns if there is a duplicate or missing key
5092 */
5093
5094
5095 function warnOnInvalidKey(child, knownKeys) {
5096 {
5097 if (typeof child !== 'object' || child === null) {
5098 return knownKeys;
5099 }
5100
5101 switch (child.$$typeof) {
5102 case REACT_ELEMENT_TYPE:
5103 case REACT_PORTAL_TYPE:
5104 warnForMissingKey(child);
5105 var key = child.key;
5106
5107 if (typeof key !== 'string') {
5108 break;
5109 }
5110
5111 if (knownKeys === null) {
5112 knownKeys = new Set();
5113 knownKeys.add(key);
5114 break;
5115 }
5116
5117 if (!knownKeys.has(key)) {
5118 knownKeys.add(key);
5119 break;
5120 }
5121
5122 error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
5123
5124 break;
5125 }
5126 }
5127
5128 return knownKeys;
5129 }
5130
5131 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
5132 // This algorithm can't optimize by searching from both ends since we
5133 // don't have backpointers on fibers. I'm trying to see how far we can get
5134 // with that model. If it ends up not being worth the tradeoffs, we can
5135 // add it later.
5136 // Even with a two ended optimization, we'd want to optimize for the case
5137 // where there are few changes and brute force the comparison instead of
5138 // going for the Map. It'd like to explore hitting that path first in
5139 // forward-only mode and only go for the Map once we notice that we need
5140 // lots of look ahead. This doesn't handle reversal as well as two ended
5141 // search but that's unusual. Besides, for the two ended optimization to
5142 // work on Iterables, we'd need to copy the whole set.
5143 // In this first iteration, we'll just live with hitting the bad case
5144 // (adding everything to a Map) in for every insert/move.
5145 // If you change this code, also update reconcileChildrenIterator() which
5146 // uses the same algorithm.
5147 {
5148 // First, validate keys.
5149 var knownKeys = null;
5150
5151 for (var i = 0; i < newChildren.length; i++) {
5152 var child = newChildren[i];
5153 knownKeys = warnOnInvalidKey(child, knownKeys);
5154 }
5155 }
5156
5157 var resultingFirstChild = null;
5158 var previousNewFiber = null;
5159 var oldFiber = currentFirstChild;
5160 var lastPlacedIndex = 0;
5161 var newIdx = 0;
5162 var nextOldFiber = null;
5163
5164 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
5165 if (oldFiber.index > newIdx) {
5166 nextOldFiber = oldFiber;
5167 oldFiber = null;
5168 } else {
5169 nextOldFiber = oldFiber.sibling;
5170 }
5171
5172 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
5173
5174 if (newFiber === null) {
5175 // TODO: This breaks on empty slots like null children. That's
5176 // unfortunate because it triggers the slow path all the time. We need
5177 // a better way to communicate whether this was a miss or null,
5178 // boolean, undefined, etc.
5179 if (oldFiber === null) {
5180 oldFiber = nextOldFiber;
5181 }
5182
5183 break;
5184 }
5185
5186 if (shouldTrackSideEffects) {
5187 if (oldFiber && newFiber.alternate === null) {
5188 // We matched the slot, but we didn't reuse the existing fiber, so we
5189 // need to delete the existing child.
5190 deleteChild(returnFiber, oldFiber);
5191 }
5192 }
5193
5194 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5195
5196 if (previousNewFiber === null) {
5197 // TODO: Move out of the loop. This only happens for the first run.
5198 resultingFirstChild = newFiber;
5199 } else {
5200 // TODO: Defer siblings if we're not at the right index for this slot.
5201 // I.e. if we had null values before, then we want to defer this
5202 // for each null value. However, we also don't want to call updateSlot
5203 // with the previous one.
5204 previousNewFiber.sibling = newFiber;
5205 }
5206
5207 previousNewFiber = newFiber;
5208 oldFiber = nextOldFiber;
5209 }
5210
5211 if (newIdx === newChildren.length) {
5212 // We've reached the end of the new children. We can delete the rest.
5213 deleteRemainingChildren(returnFiber, oldFiber);
5214 return resultingFirstChild;
5215 }
5216
5217 if (oldFiber === null) {
5218 // If we don't have any more existing children we can choose a fast path
5219 // since the rest will all be insertions.
5220 for (; newIdx < newChildren.length; newIdx++) {
5221 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
5222
5223 if (_newFiber === null) {
5224 continue;
5225 }
5226
5227 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
5228
5229 if (previousNewFiber === null) {
5230 // TODO: Move out of the loop. This only happens for the first run.
5231 resultingFirstChild = _newFiber;
5232 } else {
5233 previousNewFiber.sibling = _newFiber;
5234 }
5235
5236 previousNewFiber = _newFiber;
5237 }
5238
5239 return resultingFirstChild;
5240 } // Add all children to a key map for quick lookups.
5241
5242
5243 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5244
5245 for (; newIdx < newChildren.length; newIdx++) {
5246 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
5247
5248 if (_newFiber2 !== null) {
5249 if (shouldTrackSideEffects) {
5250 if (_newFiber2.alternate !== null) {
5251 // The new fiber is a work in progress, but if there exists a
5252 // current, that means that we reused the fiber. We need to delete
5253 // it from the child list so that we don't add it to the deletion
5254 // list.
5255 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
5256 }
5257 }
5258
5259 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
5260
5261 if (previousNewFiber === null) {
5262 resultingFirstChild = _newFiber2;
5263 } else {
5264 previousNewFiber.sibling = _newFiber2;
5265 }
5266
5267 previousNewFiber = _newFiber2;
5268 }
5269 }
5270
5271 if (shouldTrackSideEffects) {
5272 // Any existing children that weren't consumed above were deleted. We need
5273 // to add them to the deletion list.
5274 existingChildren.forEach(function (child) {
5275 return deleteChild(returnFiber, child);
5276 });
5277 }
5278
5279 return resultingFirstChild;
5280 }
5281
5282 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
5283 // This is the same implementation as reconcileChildrenArray(),
5284 // but using the iterator instead.
5285 var iteratorFn = getIteratorFn(newChildrenIterable);
5286
5287 if (!(typeof iteratorFn === 'function')) {
5288 {
5289 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
5290 }
5291 }
5292
5293 {
5294 // We don't support rendering Generators because it's a mutation.
5295 // See https://github.com/facebook/react/issues/12995
5296 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
5297 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
5298 if (!didWarnAboutGenerators) {
5299 error('Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.');
5300 }
5301
5302 didWarnAboutGenerators = true;
5303 } // Warn about using Maps as children
5304
5305
5306 if (newChildrenIterable.entries === iteratorFn) {
5307 if (!didWarnAboutMaps) {
5308 error('Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.');
5309 }
5310
5311 didWarnAboutMaps = true;
5312 } // First, validate keys.
5313 // We'll get a different iterator later for the main pass.
5314
5315
5316 var _newChildren = iteratorFn.call(newChildrenIterable);
5317
5318 if (_newChildren) {
5319 var knownKeys = null;
5320
5321 var _step = _newChildren.next();
5322
5323 for (; !_step.done; _step = _newChildren.next()) {
5324 var child = _step.value;
5325 knownKeys = warnOnInvalidKey(child, knownKeys);
5326 }
5327 }
5328 }
5329
5330 var newChildren = iteratorFn.call(newChildrenIterable);
5331
5332 if (!(newChildren != null)) {
5333 {
5334 throw Error( "An iterable object provided no iterator." );
5335 }
5336 }
5337
5338 var resultingFirstChild = null;
5339 var previousNewFiber = null;
5340 var oldFiber = currentFirstChild;
5341 var lastPlacedIndex = 0;
5342 var newIdx = 0;
5343 var nextOldFiber = null;
5344 var step = newChildren.next();
5345
5346 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
5347 if (oldFiber.index > newIdx) {
5348 nextOldFiber = oldFiber;
5349 oldFiber = null;
5350 } else {
5351 nextOldFiber = oldFiber.sibling;
5352 }
5353
5354 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
5355
5356 if (newFiber === null) {
5357 // TODO: This breaks on empty slots like null children. That's
5358 // unfortunate because it triggers the slow path all the time. We need
5359 // a better way to communicate whether this was a miss or null,
5360 // boolean, undefined, etc.
5361 if (oldFiber === null) {
5362 oldFiber = nextOldFiber;
5363 }
5364
5365 break;
5366 }
5367
5368 if (shouldTrackSideEffects) {
5369 if (oldFiber && newFiber.alternate === null) {
5370 // We matched the slot, but we didn't reuse the existing fiber, so we
5371 // need to delete the existing child.
5372 deleteChild(returnFiber, oldFiber);
5373 }
5374 }
5375
5376 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5377
5378 if (previousNewFiber === null) {
5379 // TODO: Move out of the loop. This only happens for the first run.
5380 resultingFirstChild = newFiber;
5381 } else {
5382 // TODO: Defer siblings if we're not at the right index for this slot.
5383 // I.e. if we had null values before, then we want to defer this
5384 // for each null value. However, we also don't want to call updateSlot
5385 // with the previous one.
5386 previousNewFiber.sibling = newFiber;
5387 }
5388
5389 previousNewFiber = newFiber;
5390 oldFiber = nextOldFiber;
5391 }
5392
5393 if (step.done) {
5394 // We've reached the end of the new children. We can delete the rest.
5395 deleteRemainingChildren(returnFiber, oldFiber);
5396 return resultingFirstChild;
5397 }
5398
5399 if (oldFiber === null) {
5400 // If we don't have any more existing children we can choose a fast path
5401 // since the rest will all be insertions.
5402 for (; !step.done; newIdx++, step = newChildren.next()) {
5403 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5404
5405 if (_newFiber3 === null) {
5406 continue;
5407 }
5408
5409 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5410
5411 if (previousNewFiber === null) {
5412 // TODO: Move out of the loop. This only happens for the first run.
5413 resultingFirstChild = _newFiber3;
5414 } else {
5415 previousNewFiber.sibling = _newFiber3;
5416 }
5417
5418 previousNewFiber = _newFiber3;
5419 }
5420
5421 return resultingFirstChild;
5422 } // Add all children to a key map for quick lookups.
5423
5424
5425 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5426
5427 for (; !step.done; newIdx++, step = newChildren.next()) {
5428 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5429
5430 if (_newFiber4 !== null) {
5431 if (shouldTrackSideEffects) {
5432 if (_newFiber4.alternate !== null) {
5433 // The new fiber is a work in progress, but if there exists a
5434 // current, that means that we reused the fiber. We need to delete
5435 // it from the child list so that we don't add it to the deletion
5436 // list.
5437 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5438 }
5439 }
5440
5441 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5442
5443 if (previousNewFiber === null) {
5444 resultingFirstChild = _newFiber4;
5445 } else {
5446 previousNewFiber.sibling = _newFiber4;
5447 }
5448
5449 previousNewFiber = _newFiber4;
5450 }
5451 }
5452
5453 if (shouldTrackSideEffects) {
5454 // Any existing children that weren't consumed above were deleted. We need
5455 // to add them to the deletion list.
5456 existingChildren.forEach(function (child) {
5457 return deleteChild(returnFiber, child);
5458 });
5459 }
5460
5461 return resultingFirstChild;
5462 }
5463
5464 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5465 // There's no need to check for keys on text nodes since we don't have a
5466 // way to define them.
5467 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5468 // We already have an existing node so let's just update it and delete
5469 // the rest.
5470 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5471 var existing = useFiber(currentFirstChild, textContent);
5472 existing.return = returnFiber;
5473 return existing;
5474 } // The existing first child is not a text node so we need to create one
5475 // and delete the existing ones.
5476
5477
5478 deleteRemainingChildren(returnFiber, currentFirstChild);
5479 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5480 created.return = returnFiber;
5481 return created;
5482 }
5483
5484 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5485 var key = element.key;
5486 var child = currentFirstChild;
5487
5488 while (child !== null) {
5489 // TODO: If key === null and child.key === null, then this only applies to
5490 // the first item in the list.
5491 if (child.key === key) {
5492 switch (child.tag) {
5493 case Fragment:
5494 {
5495 if (element.type === REACT_FRAGMENT_TYPE) {
5496 deleteRemainingChildren(returnFiber, child.sibling);
5497 var existing = useFiber(child, element.props.children);
5498 existing.return = returnFiber;
5499
5500 {
5501 existing._debugSource = element._source;
5502 existing._debugOwner = element._owner;
5503 }
5504
5505 return existing;
5506 }
5507
5508 break;
5509 }
5510
5511 case Block:
5512
5513 // We intentionally fallthrough here if enableBlocksAPI is not on.
5514 // eslint-disable-next-lined no-fallthrough
5515
5516 default:
5517 {
5518 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
5519 isCompatibleFamilyForHotReloading(child, element) )) {
5520 deleteRemainingChildren(returnFiber, child.sibling);
5521
5522 var _existing3 = useFiber(child, element.props);
5523
5524 _existing3.ref = coerceRef(returnFiber, child, element);
5525 _existing3.return = returnFiber;
5526
5527 {
5528 _existing3._debugSource = element._source;
5529 _existing3._debugOwner = element._owner;
5530 }
5531
5532 return _existing3;
5533 }
5534
5535 break;
5536 }
5537 } // Didn't match.
5538
5539
5540 deleteRemainingChildren(returnFiber, child);
5541 break;
5542 } else {
5543 deleteChild(returnFiber, child);
5544 }
5545
5546 child = child.sibling;
5547 }
5548
5549 if (element.type === REACT_FRAGMENT_TYPE) {
5550 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5551 created.return = returnFiber;
5552 return created;
5553 } else {
5554 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5555
5556 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5557 _created4.return = returnFiber;
5558 return _created4;
5559 }
5560 }
5561
5562 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5563 var key = portal.key;
5564 var child = currentFirstChild;
5565
5566 while (child !== null) {
5567 // TODO: If key === null and child.key === null, then this only applies to
5568 // the first item in the list.
5569 if (child.key === key) {
5570 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5571 deleteRemainingChildren(returnFiber, child.sibling);
5572 var existing = useFiber(child, portal.children || []);
5573 existing.return = returnFiber;
5574 return existing;
5575 } else {
5576 deleteRemainingChildren(returnFiber, child);
5577 break;
5578 }
5579 } else {
5580 deleteChild(returnFiber, child);
5581 }
5582
5583 child = child.sibling;
5584 }
5585
5586 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5587 created.return = returnFiber;
5588 return created;
5589 } // This API will tag the children with the side-effect of the reconciliation
5590 // itself. They will be added to the side-effect list as we pass through the
5591 // children and the parent.
5592
5593
5594 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5595 // This function is not recursive.
5596 // If the top level item is an array, we treat it as a set of children,
5597 // not as a fragment. Nested arrays on the other hand will be treated as
5598 // fragment nodes. Recursion happens at the normal flow.
5599 // Handle top level unkeyed fragments as if they were arrays.
5600 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5601 // We treat the ambiguous cases above the same.
5602 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5603
5604 if (isUnkeyedTopLevelFragment) {
5605 newChild = newChild.props.children;
5606 } // Handle object types
5607
5608
5609 var isObject = typeof newChild === 'object' && newChild !== null;
5610
5611 if (isObject) {
5612 switch (newChild.$$typeof) {
5613 case REACT_ELEMENT_TYPE:
5614 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5615
5616 case REACT_PORTAL_TYPE:
5617 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5618 }
5619 }
5620
5621 if (typeof newChild === 'string' || typeof newChild === 'number') {
5622 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5623 }
5624
5625 if (isArray$1(newChild)) {
5626 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5627 }
5628
5629 if (getIteratorFn(newChild)) {
5630 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5631 }
5632
5633 if (isObject) {
5634 throwOnInvalidObjectType(returnFiber, newChild);
5635 }
5636
5637 {
5638 if (typeof newChild === 'function') {
5639 warnOnFunctionType();
5640 }
5641 }
5642
5643 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5644 // If the new child is undefined, and the return fiber is a composite
5645 // component, throw an error. If Fiber return types are disabled,
5646 // we already threw above.
5647 switch (returnFiber.tag) {
5648 case ClassComponent:
5649 {
5650 {
5651 var instance = returnFiber.stateNode;
5652
5653 if (instance.render._isMockFunction) {
5654 // We allow auto-mocks to proceed as if they're returning null.
5655 break;
5656 }
5657 }
5658 }
5659 // Intentionally fall through to the next case, which handles both
5660 // functions and classes
5661 // eslint-disable-next-lined no-fallthrough
5662
5663 case FunctionComponent:
5664 {
5665 var Component = returnFiber.type;
5666
5667 {
5668 {
5669 throw Error( (Component.displayName || Component.name || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." );
5670 }
5671 }
5672 }
5673 }
5674 } // Remaining cases are all treated as empty.
5675
5676
5677 return deleteRemainingChildren(returnFiber, currentFirstChild);
5678 }
5679
5680 return reconcileChildFibers;
5681 }
5682
5683 var reconcileChildFibers = ChildReconciler(true);
5684 var mountChildFibers = ChildReconciler(false);
5685 function cloneChildFibers(current, workInProgress) {
5686 if (!(current === null || workInProgress.child === current.child)) {
5687 {
5688 throw Error( "Resuming work not yet implemented." );
5689 }
5690 }
5691
5692 if (workInProgress.child === null) {
5693 return;
5694 }
5695
5696 var currentChild = workInProgress.child;
5697 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
5698 workInProgress.child = newChild;
5699 newChild.return = workInProgress;
5700
5701 while (currentChild.sibling !== null) {
5702 currentChild = currentChild.sibling;
5703 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
5704 newChild.return = workInProgress;
5705 }
5706
5707 newChild.sibling = null;
5708 } // Reset a workInProgress child set to prepare it for a second pass.
5709
5710 function resetChildFibers(workInProgress, renderExpirationTime) {
5711 var child = workInProgress.child;
5712
5713 while (child !== null) {
5714 resetWorkInProgress(child, renderExpirationTime);
5715 child = child.sibling;
5716 }
5717 }
5718
5719 var NO_CONTEXT$1 = {};
5720 var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5721 var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5722 var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5723
5724 function requiredContext(c) {
5725 if (!(c !== NO_CONTEXT$1)) {
5726 {
5727 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
5728 }
5729 }
5730
5731 return c;
5732 }
5733
5734 function getRootHostContainer() {
5735 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5736 return rootInstance;
5737 }
5738
5739 function pushHostContainer(fiber, nextRootInstance) {
5740 // Push current root instance onto the stack;
5741 // This allows us to reset root when portals are popped.
5742 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
5743 // This enables us to pop only Fibers that provide unique contexts.
5744
5745 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
5746 // However, we can't just call getRootHostContext() and push it because
5747 // we'd have a different number of entries on the stack depending on
5748 // whether getRootHostContext() throws somewhere in renderer code or not.
5749 // So we push an empty value first. This lets us safely unwind on errors.
5750
5751 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5752 var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it.
5753
5754 pop(contextStackCursor$1, fiber);
5755 push(contextStackCursor$1, nextRootContext, fiber);
5756 }
5757
5758 function popHostContainer(fiber) {
5759 pop(contextStackCursor$1, fiber);
5760 pop(contextFiberStackCursor, fiber);
5761 pop(rootInstanceStackCursor, fiber);
5762 }
5763
5764 function getHostContext() {
5765 var context = requiredContext(contextStackCursor$1.current);
5766 return context;
5767 }
5768
5769 function pushHostContext(fiber) {
5770 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5771 var context = requiredContext(contextStackCursor$1.current);
5772 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
5773
5774 if (context === nextContext) {
5775 return;
5776 } // Track the context and the Fiber that provided it.
5777 // This enables us to pop only Fibers that provide unique contexts.
5778
5779
5780 push(contextFiberStackCursor, fiber, fiber);
5781 push(contextStackCursor$1, nextContext, fiber);
5782 }
5783
5784 function popHostContext(fiber) {
5785 // Do not pop unless this Fiber provided the current context.
5786 // pushHostContext() only pushes Fibers that provide unique contexts.
5787 if (contextFiberStackCursor.current !== fiber) {
5788 return;
5789 }
5790
5791 pop(contextStackCursor$1, fiber);
5792 pop(contextFiberStackCursor, fiber);
5793 }
5794
5795 var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
5796 // inherited deeply down the subtree. The upper bits only affect
5797 // this immediate suspense boundary and gets reset each new
5798 // boundary or suspense list.
5799
5800 var SubtreeSuspenseContextMask = 1; // Subtree Flags:
5801 // InvisibleParentSuspenseContext indicates that one of our parent Suspense
5802 // boundaries is not currently showing visible main content.
5803 // Either because it is already showing a fallback or is not mounted at all.
5804 // We can use this to determine if it is desirable to trigger a fallback at
5805 // the parent. If not, then we might need to trigger undesirable boundaries
5806 // and/or suspend the commit to avoid hiding the parent content.
5807
5808 var InvisibleParentSuspenseContext = 1; // Shallow Flags:
5809 // ForceSuspenseFallback can be used by SuspenseList to force newly added
5810 // items into their fallback state during one of the render passes.
5811
5812 var ForceSuspenseFallback = 2;
5813 var suspenseStackCursor = createCursor(DefaultSuspenseContext);
5814 function hasSuspenseContext(parentContext, flag) {
5815 return (parentContext & flag) !== 0;
5816 }
5817 function setDefaultShallowSuspenseContext(parentContext) {
5818 return parentContext & SubtreeSuspenseContextMask;
5819 }
5820 function setShallowSuspenseContext(parentContext, shallowContext) {
5821 return parentContext & SubtreeSuspenseContextMask | shallowContext;
5822 }
5823 function addSubtreeSuspenseContext(parentContext, subtreeContext) {
5824 return parentContext | subtreeContext;
5825 }
5826 function pushSuspenseContext(fiber, newContext) {
5827 push(suspenseStackCursor, newContext, fiber);
5828 }
5829 function popSuspenseContext(fiber) {
5830 pop(suspenseStackCursor, fiber);
5831 }
5832
5833 function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
5834 // If it was the primary children that just suspended, capture and render the
5835 // fallback. Otherwise, don't capture and bubble to the next boundary.
5836 var nextState = workInProgress.memoizedState;
5837
5838 if (nextState !== null) {
5839 if (nextState.dehydrated !== null) {
5840 // A dehydrated boundary always captures.
5841 return true;
5842 }
5843
5844 return false;
5845 }
5846
5847 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
5848
5849 if (props.fallback === undefined) {
5850 return false;
5851 } // Regular boundaries always capture.
5852
5853
5854 if (props.unstable_avoidThisFallback !== true) {
5855 return true;
5856 } // If it's a boundary we should avoid, then we prefer to bubble up to the
5857 // parent boundary if it is currently invisible.
5858
5859
5860 if (hasInvisibleParent) {
5861 return false;
5862 } // If the parent is not able to handle it, we must handle it.
5863
5864
5865 return true;
5866 }
5867 function findFirstSuspended(row) {
5868 var node = row;
5869
5870 while (node !== null) {
5871 if (node.tag === SuspenseComponent) {
5872 var state = node.memoizedState;
5873
5874 if (state !== null) {
5875 var dehydrated = state.dehydrated;
5876
5877 if (dehydrated === null || isSuspenseInstancePending() || isSuspenseInstanceFallback()) {
5878 return node;
5879 }
5880 }
5881 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
5882 // keep track of whether it suspended or not.
5883 node.memoizedProps.revealOrder !== undefined) {
5884 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
5885
5886 if (didSuspend) {
5887 return node;
5888 }
5889 } else if (node.child !== null) {
5890 node.child.return = node;
5891 node = node.child;
5892 continue;
5893 }
5894
5895 if (node === row) {
5896 return null;
5897 }
5898
5899 while (node.sibling === null) {
5900 if (node.return === null || node.return === row) {
5901 return null;
5902 }
5903
5904 node = node.return;
5905 }
5906
5907 node.sibling.return = node.return;
5908 node = node.sibling;
5909 }
5910
5911 return null;
5912 }
5913
5914 function createDeprecatedResponderListener(responder, props) {
5915 var eventResponderListener = {
5916 responder: responder,
5917 props: props
5918 };
5919
5920 {
5921 Object.freeze(eventResponderListener);
5922 }
5923
5924 return eventResponderListener;
5925 }
5926
5927 var HasEffect =
5928 /* */
5929 1; // Represents the phase in which the effect (not the clean-up) fires.
5930
5931 var Layout =
5932 /* */
5933 2;
5934 var Passive$1 =
5935 /* */
5936 4;
5937
5938 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
5939 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
5940 var didWarnAboutMismatchedHooksForComponent;
5941
5942 {
5943 didWarnAboutMismatchedHooksForComponent = new Set();
5944 }
5945
5946 // These are set right before calling the component.
5947 var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
5948 // the work-in-progress hook.
5949
5950 var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
5951 // current hook list is the list that belongs to the current fiber. The
5952 // work-in-progress hook list is a new list that will be added to the
5953 // work-in-progress fiber.
5954
5955 var currentHook = null;
5956 var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
5957 // does not get reset if we do another render pass; only when we're completely
5958 // finished evaluating this component. This is an optimization so we know
5959 // whether we need to clear render phase updates after a throw.
5960
5961 var didScheduleRenderPhaseUpdate = false;
5962 var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
5963
5964 var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
5965 // The list stores the order of hooks used during the initial render (mount).
5966 // Subsequent renders (updates) reference this list.
5967
5968 var hookTypesDev = null;
5969 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
5970 // the dependencies for Hooks that need them (e.g. useEffect or useMemo).
5971 // When true, such Hooks will always be "remounted". Only used during hot reload.
5972
5973 var ignorePreviousDependencies = false;
5974
5975 function mountHookTypesDev() {
5976 {
5977 var hookName = currentHookNameInDev;
5978
5979 if (hookTypesDev === null) {
5980 hookTypesDev = [hookName];
5981 } else {
5982 hookTypesDev.push(hookName);
5983 }
5984 }
5985 }
5986
5987 function updateHookTypesDev() {
5988 {
5989 var hookName = currentHookNameInDev;
5990
5991 if (hookTypesDev !== null) {
5992 hookTypesUpdateIndexDev++;
5993
5994 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
5995 warnOnHookMismatchInDev(hookName);
5996 }
5997 }
5998 }
5999 }
6000
6001 function checkDepsAreArrayDev(deps) {
6002 {
6003 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
6004 // Verify deps, but only on mount to avoid extra checks.
6005 // It's unlikely their type would change as usually you define them inline.
6006 error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
6007 }
6008 }
6009 }
6010
6011 function warnOnHookMismatchInDev(currentHookName) {
6012 {
6013 var componentName = getComponentName(currentlyRenderingFiber$1.type);
6014
6015 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
6016 didWarnAboutMismatchedHooksForComponent.add(componentName);
6017
6018 if (hookTypesDev !== null) {
6019 var table = '';
6020 var secondColumnStart = 30;
6021
6022 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
6023 var oldHookName = hookTypesDev[i];
6024 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
6025 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
6026 // lol @ IE not supporting String#repeat
6027
6028 while (row.length < secondColumnStart) {
6029 row += ' ';
6030 }
6031
6032 row += newHookName + '\n';
6033 table += row;
6034 }
6035
6036 error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
6037 }
6038 }
6039 }
6040 }
6041
6042 function throwInvalidHookError() {
6043 {
6044 {
6045 throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." );
6046 }
6047 }
6048 }
6049
6050 function areHookInputsEqual(nextDeps, prevDeps) {
6051 {
6052 if (ignorePreviousDependencies) {
6053 // Only true when this component is being hot reloaded.
6054 return false;
6055 }
6056 }
6057
6058 if (prevDeps === null) {
6059 {
6060 error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
6061 }
6062
6063 return false;
6064 }
6065
6066 {
6067 // Don't bother comparing lengths in prod because these arrays should be
6068 // passed inline.
6069 if (nextDeps.length !== prevDeps.length) {
6070 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
6071 }
6072 }
6073
6074 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
6075 if (objectIs(nextDeps[i], prevDeps[i])) {
6076 continue;
6077 }
6078
6079 return false;
6080 }
6081
6082 return true;
6083 }
6084
6085 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderExpirationTime) {
6086 renderExpirationTime = nextRenderExpirationTime;
6087 currentlyRenderingFiber$1 = workInProgress;
6088
6089 {
6090 hookTypesDev = current !== null ? current._debugHookTypes : null;
6091 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
6092
6093 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
6094 }
6095
6096 workInProgress.memoizedState = null;
6097 workInProgress.updateQueue = null;
6098 workInProgress.expirationTime = NoWork; // The following should have already been reset
6099 // currentHook = null;
6100 // workInProgressHook = null;
6101 // didScheduleRenderPhaseUpdate = false;
6102 // TODO Warn if no hooks are used at all during mount, then some are used during update.
6103 // Currently we will identify the update render as a mount because memoizedState === null.
6104 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
6105 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
6106 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
6107 // so memoizedState would be null during updates and mounts.
6108
6109 {
6110 if (current !== null && current.memoizedState !== null) {
6111 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
6112 } else if (hookTypesDev !== null) {
6113 // This dispatcher handles an edge case where a component is updating,
6114 // but no stateful hooks have been used.
6115 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
6116 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
6117 // This dispatcher does that.
6118 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;
6119 } else {
6120 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;
6121 }
6122 }
6123
6124 var children = Component(props, secondArg); // Check if there was a render phase update
6125
6126 if (workInProgress.expirationTime === renderExpirationTime) {
6127 // Keep rendering in a loop for as long as render phase updates continue to
6128 // be scheduled. Use a counter to prevent infinite loops.
6129 var numberOfReRenders = 0;
6130
6131 do {
6132 workInProgress.expirationTime = NoWork;
6133
6134 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
6135 {
6136 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
6137 }
6138 }
6139
6140 numberOfReRenders += 1;
6141
6142 {
6143 // Even when hot reloading, allow dependencies to stabilize
6144 // after first render to prevent infinite render phase updates.
6145 ignorePreviousDependencies = false;
6146 } // Start over from the beginning of the list
6147
6148
6149 currentHook = null;
6150 workInProgressHook = null;
6151 workInProgress.updateQueue = null;
6152
6153 {
6154 // Also validate hook order for cascading updates.
6155 hookTypesUpdateIndexDev = -1;
6156 }
6157
6158 ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV ;
6159 children = Component(props, secondArg);
6160 } while (workInProgress.expirationTime === renderExpirationTime);
6161 } // We can assume the previous dispatcher is always this one, since we set it
6162 // at the beginning of the render phase and there's no re-entrancy.
6163
6164
6165 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
6166
6167 {
6168 workInProgress._debugHookTypes = hookTypesDev;
6169 } // This check uses currentHook so that it works the same in DEV and prod bundles.
6170 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
6171
6172
6173 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
6174 renderExpirationTime = NoWork;
6175 currentlyRenderingFiber$1 = null;
6176 currentHook = null;
6177 workInProgressHook = null;
6178
6179 {
6180 currentHookNameInDev = null;
6181 hookTypesDev = null;
6182 hookTypesUpdateIndexDev = -1;
6183 }
6184
6185 didScheduleRenderPhaseUpdate = false;
6186
6187 if (!!didRenderTooFewHooks) {
6188 {
6189 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
6190 }
6191 }
6192
6193 return children;
6194 }
6195 function bailoutHooks(current, workInProgress, expirationTime) {
6196 workInProgress.updateQueue = current.updateQueue;
6197 workInProgress.effectTag &= ~(Passive | Update);
6198
6199 if (current.expirationTime <= expirationTime) {
6200 current.expirationTime = NoWork;
6201 }
6202 }
6203 function resetHooksAfterThrow() {
6204 // We can assume the previous dispatcher is always this one, since we set it
6205 // at the beginning of the render phase and there's no re-entrancy.
6206 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
6207
6208 if (didScheduleRenderPhaseUpdate) {
6209 // There were render phase updates. These are only valid for this render
6210 // phase, which we are now aborting. Remove the updates from the queues so
6211 // they do not persist to the next render. Do not remove updates from hooks
6212 // that weren't processed.
6213 //
6214 // Only reset the updates from the queue if it has a clone. If it does
6215 // not have a clone, that means it wasn't processed, and the updates were
6216 // scheduled before we entered the render phase.
6217 var hook = currentlyRenderingFiber$1.memoizedState;
6218
6219 while (hook !== null) {
6220 var queue = hook.queue;
6221
6222 if (queue !== null) {
6223 queue.pending = null;
6224 }
6225
6226 hook = hook.next;
6227 }
6228 }
6229
6230 renderExpirationTime = NoWork;
6231 currentlyRenderingFiber$1 = null;
6232 currentHook = null;
6233 workInProgressHook = null;
6234
6235 {
6236 hookTypesDev = null;
6237 hookTypesUpdateIndexDev = -1;
6238 currentHookNameInDev = null;
6239 }
6240
6241 didScheduleRenderPhaseUpdate = false;
6242 }
6243
6244 function mountWorkInProgressHook() {
6245 var hook = {
6246 memoizedState: null,
6247 baseState: null,
6248 baseQueue: null,
6249 queue: null,
6250 next: null
6251 };
6252
6253 if (workInProgressHook === null) {
6254 // This is the first hook in the list
6255 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
6256 } else {
6257 // Append to the end of the list
6258 workInProgressHook = workInProgressHook.next = hook;
6259 }
6260
6261 return workInProgressHook;
6262 }
6263
6264 function updateWorkInProgressHook() {
6265 // This function is used both for updates and for re-renders triggered by a
6266 // render phase update. It assumes there is either a current hook we can
6267 // clone, or a work-in-progress hook from a previous render pass that we can
6268 // use as a base. When we reach the end of the base list, we must switch to
6269 // the dispatcher used for mounts.
6270 var nextCurrentHook;
6271
6272 if (currentHook === null) {
6273 var current = currentlyRenderingFiber$1.alternate;
6274
6275 if (current !== null) {
6276 nextCurrentHook = current.memoizedState;
6277 } else {
6278 nextCurrentHook = null;
6279 }
6280 } else {
6281 nextCurrentHook = currentHook.next;
6282 }
6283
6284 var nextWorkInProgressHook;
6285
6286 if (workInProgressHook === null) {
6287 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
6288 } else {
6289 nextWorkInProgressHook = workInProgressHook.next;
6290 }
6291
6292 if (nextWorkInProgressHook !== null) {
6293 // There's already a work-in-progress. Reuse it.
6294 workInProgressHook = nextWorkInProgressHook;
6295 nextWorkInProgressHook = workInProgressHook.next;
6296 currentHook = nextCurrentHook;
6297 } else {
6298 // Clone from the current hook.
6299 if (!(nextCurrentHook !== null)) {
6300 {
6301 throw Error( "Rendered more hooks than during the previous render." );
6302 }
6303 }
6304
6305 currentHook = nextCurrentHook;
6306 var newHook = {
6307 memoizedState: currentHook.memoizedState,
6308 baseState: currentHook.baseState,
6309 baseQueue: currentHook.baseQueue,
6310 queue: currentHook.queue,
6311 next: null
6312 };
6313
6314 if (workInProgressHook === null) {
6315 // This is the first hook in the list.
6316 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
6317 } else {
6318 // Append to the end of the list.
6319 workInProgressHook = workInProgressHook.next = newHook;
6320 }
6321 }
6322
6323 return workInProgressHook;
6324 }
6325
6326 function createFunctionComponentUpdateQueue() {
6327 return {
6328 lastEffect: null
6329 };
6330 }
6331
6332 function basicStateReducer(state, action) {
6333 // $FlowFixMe: Flow doesn't like mixed types
6334 return typeof action === 'function' ? action(state) : action;
6335 }
6336
6337 function mountReducer(reducer, initialArg, init) {
6338 var hook = mountWorkInProgressHook();
6339 var initialState;
6340
6341 if (init !== undefined) {
6342 initialState = init(initialArg);
6343 } else {
6344 initialState = initialArg;
6345 }
6346
6347 hook.memoizedState = hook.baseState = initialState;
6348 var queue = hook.queue = {
6349 pending: null,
6350 dispatch: null,
6351 lastRenderedReducer: reducer,
6352 lastRenderedState: initialState
6353 };
6354 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
6355 return [hook.memoizedState, dispatch];
6356 }
6357
6358 function updateReducer(reducer, initialArg, init) {
6359 var hook = updateWorkInProgressHook();
6360 var queue = hook.queue;
6361
6362 if (!(queue !== null)) {
6363 {
6364 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
6365 }
6366 }
6367
6368 queue.lastRenderedReducer = reducer;
6369 var current = currentHook; // The last rebase update that is NOT part of the base state.
6370
6371 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
6372
6373 var pendingQueue = queue.pending;
6374
6375 if (pendingQueue !== null) {
6376 // We have new updates that haven't been processed yet.
6377 // We'll add them to the base queue.
6378 if (baseQueue !== null) {
6379 // Merge the pending queue and the base queue.
6380 var baseFirst = baseQueue.next;
6381 var pendingFirst = pendingQueue.next;
6382 baseQueue.next = pendingFirst;
6383 pendingQueue.next = baseFirst;
6384 }
6385
6386 current.baseQueue = baseQueue = pendingQueue;
6387 queue.pending = null;
6388 }
6389
6390 if (baseQueue !== null) {
6391 // We have a queue to process.
6392 var first = baseQueue.next;
6393 var newState = current.baseState;
6394 var newBaseState = null;
6395 var newBaseQueueFirst = null;
6396 var newBaseQueueLast = null;
6397 var update = first;
6398
6399 do {
6400 var updateExpirationTime = update.expirationTime;
6401
6402 if (updateExpirationTime < renderExpirationTime) {
6403 // Priority is insufficient. Skip this update. If this is the first
6404 // skipped update, the previous update/state is the new base
6405 // update/state.
6406 var clone = {
6407 expirationTime: update.expirationTime,
6408 suspenseConfig: update.suspenseConfig,
6409 action: update.action,
6410 eagerReducer: update.eagerReducer,
6411 eagerState: update.eagerState,
6412 next: null
6413 };
6414
6415 if (newBaseQueueLast === null) {
6416 newBaseQueueFirst = newBaseQueueLast = clone;
6417 newBaseState = newState;
6418 } else {
6419 newBaseQueueLast = newBaseQueueLast.next = clone;
6420 } // Update the remaining priority in the queue.
6421
6422
6423 if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) {
6424 currentlyRenderingFiber$1.expirationTime = updateExpirationTime;
6425 markUnprocessedUpdateTime(updateExpirationTime);
6426 }
6427 } else {
6428 // This update does have sufficient priority.
6429 if (newBaseQueueLast !== null) {
6430 var _clone = {
6431 expirationTime: Sync,
6432 // This update is going to be committed so we never want uncommit it.
6433 suspenseConfig: update.suspenseConfig,
6434 action: update.action,
6435 eagerReducer: update.eagerReducer,
6436 eagerState: update.eagerState,
6437 next: null
6438 };
6439 newBaseQueueLast = newBaseQueueLast.next = _clone;
6440 } // Mark the event time of this update as relevant to this render pass.
6441 // TODO: This should ideally use the true event time of this update rather than
6442 // its priority which is a derived and not reverseable value.
6443 // TODO: We should skip this update if it was already committed but currently
6444 // we have no way of detecting the difference between a committed and suspended
6445 // update here.
6446
6447
6448 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
6449
6450 if (update.eagerReducer === reducer) {
6451 // If this update was processed eagerly, and its reducer matches the
6452 // current reducer, we can use the eagerly computed state.
6453 newState = update.eagerState;
6454 } else {
6455 var action = update.action;
6456 newState = reducer(newState, action);
6457 }
6458 }
6459
6460 update = update.next;
6461 } while (update !== null && update !== first);
6462
6463 if (newBaseQueueLast === null) {
6464 newBaseState = newState;
6465 } else {
6466 newBaseQueueLast.next = newBaseQueueFirst;
6467 } // Mark that the fiber performed work, but only if the new state is
6468 // different from the current state.
6469
6470
6471 if (!objectIs(newState, hook.memoizedState)) {
6472 markWorkInProgressReceivedUpdate();
6473 }
6474
6475 hook.memoizedState = newState;
6476 hook.baseState = newBaseState;
6477 hook.baseQueue = newBaseQueueLast;
6478 queue.lastRenderedState = newState;
6479 }
6480
6481 var dispatch = queue.dispatch;
6482 return [hook.memoizedState, dispatch];
6483 }
6484
6485 function rerenderReducer(reducer, initialArg, init) {
6486 var hook = updateWorkInProgressHook();
6487 var queue = hook.queue;
6488
6489 if (!(queue !== null)) {
6490 {
6491 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
6492 }
6493 }
6494
6495 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
6496 // work-in-progress hook.
6497
6498 var dispatch = queue.dispatch;
6499 var lastRenderPhaseUpdate = queue.pending;
6500 var newState = hook.memoizedState;
6501
6502 if (lastRenderPhaseUpdate !== null) {
6503 // The queue doesn't persist past this render pass.
6504 queue.pending = null;
6505 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6506 var update = firstRenderPhaseUpdate;
6507
6508 do {
6509 // Process this render phase update. We don't have to check the
6510 // priority because it will always be the same as the current
6511 // render's.
6512 var action = update.action;
6513 newState = reducer(newState, action);
6514 update = update.next;
6515 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
6516 // different from the current state.
6517
6518
6519 if (!objectIs(newState, hook.memoizedState)) {
6520 markWorkInProgressReceivedUpdate();
6521 }
6522
6523 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
6524 // the base state unless the queue is empty.
6525 // TODO: Not sure if this is the desired semantics, but it's what we
6526 // do for gDSFP. I can't remember why.
6527
6528 if (hook.baseQueue === null) {
6529 hook.baseState = newState;
6530 }
6531
6532 queue.lastRenderedState = newState;
6533 }
6534
6535 return [newState, dispatch];
6536 }
6537
6538 function mountState(initialState) {
6539 var hook = mountWorkInProgressHook();
6540
6541 if (typeof initialState === 'function') {
6542 // $FlowFixMe: Flow doesn't like mixed types
6543 initialState = initialState();
6544 }
6545
6546 hook.memoizedState = hook.baseState = initialState;
6547 var queue = hook.queue = {
6548 pending: null,
6549 dispatch: null,
6550 lastRenderedReducer: basicStateReducer,
6551 lastRenderedState: initialState
6552 };
6553 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
6554 return [hook.memoizedState, dispatch];
6555 }
6556
6557 function updateState(initialState) {
6558 return updateReducer(basicStateReducer);
6559 }
6560
6561 function rerenderState(initialState) {
6562 return rerenderReducer(basicStateReducer);
6563 }
6564
6565 function pushEffect(tag, create, destroy, deps) {
6566 var effect = {
6567 tag: tag,
6568 create: create,
6569 destroy: destroy,
6570 deps: deps,
6571 // Circular
6572 next: null
6573 };
6574 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
6575
6576 if (componentUpdateQueue === null) {
6577 componentUpdateQueue = createFunctionComponentUpdateQueue();
6578 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
6579 componentUpdateQueue.lastEffect = effect.next = effect;
6580 } else {
6581 var lastEffect = componentUpdateQueue.lastEffect;
6582
6583 if (lastEffect === null) {
6584 componentUpdateQueue.lastEffect = effect.next = effect;
6585 } else {
6586 var firstEffect = lastEffect.next;
6587 lastEffect.next = effect;
6588 effect.next = firstEffect;
6589 componentUpdateQueue.lastEffect = effect;
6590 }
6591 }
6592
6593 return effect;
6594 }
6595
6596 function mountRef(initialValue) {
6597 var hook = mountWorkInProgressHook();
6598 var ref = {
6599 current: initialValue
6600 };
6601
6602 {
6603 Object.seal(ref);
6604 }
6605
6606 hook.memoizedState = ref;
6607 return ref;
6608 }
6609
6610 function updateRef(initialValue) {
6611 var hook = updateWorkInProgressHook();
6612 return hook.memoizedState;
6613 }
6614
6615 function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6616 var hook = mountWorkInProgressHook();
6617 var nextDeps = deps === undefined ? null : deps;
6618 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6619 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, undefined, nextDeps);
6620 }
6621
6622 function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6623 var hook = updateWorkInProgressHook();
6624 var nextDeps = deps === undefined ? null : deps;
6625 var destroy = undefined;
6626
6627 if (currentHook !== null) {
6628 var prevEffect = currentHook.memoizedState;
6629 destroy = prevEffect.destroy;
6630
6631 if (nextDeps !== null) {
6632 var prevDeps = prevEffect.deps;
6633
6634 if (areHookInputsEqual(nextDeps, prevDeps)) {
6635 pushEffect(hookEffectTag, create, destroy, nextDeps);
6636 return;
6637 }
6638 }
6639 }
6640
6641 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6642 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, destroy, nextDeps);
6643 }
6644
6645 function mountEffect(create, deps) {
6646
6647 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
6648 }
6649
6650 function updateEffect(create, deps) {
6651
6652 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
6653 }
6654
6655 function mountLayoutEffect(create, deps) {
6656 return mountEffectImpl(Update, Layout, create, deps);
6657 }
6658
6659 function updateLayoutEffect(create, deps) {
6660 return updateEffectImpl(Update, Layout, create, deps);
6661 }
6662
6663 function imperativeHandleEffect(create, ref) {
6664 if (typeof ref === 'function') {
6665 var refCallback = ref;
6666
6667 var _inst = create();
6668
6669 refCallback(_inst);
6670 return function () {
6671 refCallback(null);
6672 };
6673 } else if (ref !== null && ref !== undefined) {
6674 var refObject = ref;
6675
6676 {
6677 if (!refObject.hasOwnProperty('current')) {
6678 error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');
6679 }
6680 }
6681
6682 var _inst2 = create();
6683
6684 refObject.current = _inst2;
6685 return function () {
6686 refObject.current = null;
6687 };
6688 }
6689 }
6690
6691 function mountImperativeHandle(ref, create, deps) {
6692 {
6693 if (typeof create !== 'function') {
6694 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6695 }
6696 } // TODO: If deps are provided, should we skip comparing the ref itself?
6697
6698
6699 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6700 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6701 }
6702
6703 function updateImperativeHandle(ref, create, deps) {
6704 {
6705 if (typeof create !== 'function') {
6706 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6707 }
6708 } // TODO: If deps are provided, should we skip comparing the ref itself?
6709
6710
6711 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6712 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6713 }
6714
6715 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
6716 // The react-debug-hooks package injects its own implementation
6717 // so that e.g. DevTools can display custom hook values.
6718 }
6719
6720 var updateDebugValue = mountDebugValue;
6721
6722 function mountCallback(callback, deps) {
6723 var hook = mountWorkInProgressHook();
6724 var nextDeps = deps === undefined ? null : deps;
6725 hook.memoizedState = [callback, nextDeps];
6726 return callback;
6727 }
6728
6729 function updateCallback(callback, deps) {
6730 var hook = updateWorkInProgressHook();
6731 var nextDeps = deps === undefined ? null : deps;
6732 var prevState = hook.memoizedState;
6733
6734 if (prevState !== null) {
6735 if (nextDeps !== null) {
6736 var prevDeps = prevState[1];
6737
6738 if (areHookInputsEqual(nextDeps, prevDeps)) {
6739 return prevState[0];
6740 }
6741 }
6742 }
6743
6744 hook.memoizedState = [callback, nextDeps];
6745 return callback;
6746 }
6747
6748 function mountMemo(nextCreate, deps) {
6749 var hook = mountWorkInProgressHook();
6750 var nextDeps = deps === undefined ? null : deps;
6751 var nextValue = nextCreate();
6752 hook.memoizedState = [nextValue, nextDeps];
6753 return nextValue;
6754 }
6755
6756 function updateMemo(nextCreate, deps) {
6757 var hook = updateWorkInProgressHook();
6758 var nextDeps = deps === undefined ? null : deps;
6759 var prevState = hook.memoizedState;
6760
6761 if (prevState !== null) {
6762 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6763 if (nextDeps !== null) {
6764 var prevDeps = prevState[1];
6765
6766 if (areHookInputsEqual(nextDeps, prevDeps)) {
6767 return prevState[0];
6768 }
6769 }
6770 }
6771
6772 var nextValue = nextCreate();
6773 hook.memoizedState = [nextValue, nextDeps];
6774 return nextValue;
6775 }
6776
6777 function mountDeferredValue(value, config) {
6778 var _mountState = mountState(value),
6779 prevValue = _mountState[0],
6780 setValue = _mountState[1];
6781
6782 mountEffect(function () {
6783 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6784 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6785
6786 try {
6787 setValue(value);
6788 } finally {
6789 ReactCurrentBatchConfig$1.suspense = previousConfig;
6790 }
6791 }, [value, config]);
6792 return prevValue;
6793 }
6794
6795 function updateDeferredValue(value, config) {
6796 var _updateState = updateState(),
6797 prevValue = _updateState[0],
6798 setValue = _updateState[1];
6799
6800 updateEffect(function () {
6801 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6802 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6803
6804 try {
6805 setValue(value);
6806 } finally {
6807 ReactCurrentBatchConfig$1.suspense = previousConfig;
6808 }
6809 }, [value, config]);
6810 return prevValue;
6811 }
6812
6813 function rerenderDeferredValue(value, config) {
6814 var _rerenderState = rerenderState(),
6815 prevValue = _rerenderState[0],
6816 setValue = _rerenderState[1];
6817
6818 updateEffect(function () {
6819 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6820 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6821
6822 try {
6823 setValue(value);
6824 } finally {
6825 ReactCurrentBatchConfig$1.suspense = previousConfig;
6826 }
6827 }, [value, config]);
6828 return prevValue;
6829 }
6830
6831 function startTransition(setPending, config, callback) {
6832 var priorityLevel = getCurrentPriorityLevel();
6833 runWithPriority(priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, function () {
6834 setPending(true);
6835 });
6836 runWithPriority(priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function () {
6837 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6838 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6839
6840 try {
6841 setPending(false);
6842 callback();
6843 } finally {
6844 ReactCurrentBatchConfig$1.suspense = previousConfig;
6845 }
6846 });
6847 }
6848
6849 function mountTransition(config) {
6850 var _mountState2 = mountState(false),
6851 isPending = _mountState2[0],
6852 setPending = _mountState2[1];
6853
6854 var start = mountCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6855 return [start, isPending];
6856 }
6857
6858 function updateTransition(config) {
6859 var _updateState2 = updateState(),
6860 isPending = _updateState2[0],
6861 setPending = _updateState2[1];
6862
6863 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6864 return [start, isPending];
6865 }
6866
6867 function rerenderTransition(config) {
6868 var _rerenderState2 = rerenderState(),
6869 isPending = _rerenderState2[0],
6870 setPending = _rerenderState2[1];
6871
6872 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6873 return [start, isPending];
6874 }
6875
6876 function dispatchAction(fiber, queue, action) {
6877 {
6878 if (typeof arguments[3] === 'function') {
6879 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
6880 }
6881 }
6882
6883 var currentTime = requestCurrentTimeForUpdate();
6884 var suspenseConfig = requestCurrentSuspenseConfig();
6885 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
6886 var update = {
6887 expirationTime: expirationTime,
6888 suspenseConfig: suspenseConfig,
6889 action: action,
6890 eagerReducer: null,
6891 eagerState: null,
6892 next: null
6893 };
6894
6895 {
6896 update.priority = getCurrentPriorityLevel();
6897 } // Append the update to the end of the list.
6898
6899
6900 var pending = queue.pending;
6901
6902 if (pending === null) {
6903 // This is the first update. Create a circular list.
6904 update.next = update;
6905 } else {
6906 update.next = pending.next;
6907 pending.next = update;
6908 }
6909
6910 queue.pending = update;
6911 var alternate = fiber.alternate;
6912
6913 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6914 // This is a render phase update. Stash it in a lazily-created map of
6915 // queue -> linked list of updates. After this render pass, we'll restart
6916 // and apply the stashed updates on top of the work-in-progress hook.
6917 didScheduleRenderPhaseUpdate = true;
6918 update.expirationTime = renderExpirationTime;
6919 currentlyRenderingFiber$1.expirationTime = renderExpirationTime;
6920 } else {
6921 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6922 // The queue is currently empty, which means we can eagerly compute the
6923 // next state before entering the render phase. If the new state is the
6924 // same as the current state, we may be able to bail out entirely.
6925 var lastRenderedReducer = queue.lastRenderedReducer;
6926
6927 if (lastRenderedReducer !== null) {
6928 var prevDispatcher;
6929
6930 {
6931 prevDispatcher = ReactCurrentDispatcher.current;
6932 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6933 }
6934
6935 try {
6936 var currentState = queue.lastRenderedState;
6937 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
6938 // it, on the update object. If the reducer hasn't changed by the
6939 // time we enter the render phase, then the eager state can be used
6940 // without calling the reducer again.
6941
6942 update.eagerReducer = lastRenderedReducer;
6943 update.eagerState = eagerState;
6944
6945 if (objectIs(eagerState, currentState)) {
6946 // Fast path. We can bail out without scheduling React to re-render.
6947 // It's still possible that we'll need to rebase this update later,
6948 // if the component re-renders for a different reason and by that
6949 // time the reducer has changed.
6950 return;
6951 }
6952 } catch (error) {// Suppress the error. It will throw again in the render phase.
6953 } finally {
6954 {
6955 ReactCurrentDispatcher.current = prevDispatcher;
6956 }
6957 }
6958 }
6959 }
6960
6961 scheduleWork(fiber, expirationTime);
6962 }
6963 }
6964
6965 var ContextOnlyDispatcher = {
6966 readContext: readContext,
6967 useCallback: throwInvalidHookError,
6968 useContext: throwInvalidHookError,
6969 useEffect: throwInvalidHookError,
6970 useImperativeHandle: throwInvalidHookError,
6971 useLayoutEffect: throwInvalidHookError,
6972 useMemo: throwInvalidHookError,
6973 useReducer: throwInvalidHookError,
6974 useRef: throwInvalidHookError,
6975 useState: throwInvalidHookError,
6976 useDebugValue: throwInvalidHookError,
6977 useResponder: throwInvalidHookError,
6978 useDeferredValue: throwInvalidHookError,
6979 useTransition: throwInvalidHookError
6980 };
6981 var HooksDispatcherOnMountInDEV = null;
6982 var HooksDispatcherOnMountWithHookTypesInDEV = null;
6983 var HooksDispatcherOnUpdateInDEV = null;
6984 var HooksDispatcherOnRerenderInDEV = null;
6985 var InvalidNestedHooksDispatcherOnMountInDEV = null;
6986 var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6987 var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
6988
6989 {
6990 var warnInvalidContextAccess = function () {
6991 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().');
6992 };
6993
6994 var warnInvalidHookAccess = function () {
6995 error('Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');
6996 };
6997
6998 HooksDispatcherOnMountInDEV = {
6999 readContext: function (context, observedBits) {
7000 return readContext(context, observedBits);
7001 },
7002 useCallback: function (callback, deps) {
7003 currentHookNameInDev = 'useCallback';
7004 mountHookTypesDev();
7005 checkDepsAreArrayDev(deps);
7006 return mountCallback(callback, deps);
7007 },
7008 useContext: function (context, observedBits) {
7009 currentHookNameInDev = 'useContext';
7010 mountHookTypesDev();
7011 return readContext(context, observedBits);
7012 },
7013 useEffect: function (create, deps) {
7014 currentHookNameInDev = 'useEffect';
7015 mountHookTypesDev();
7016 checkDepsAreArrayDev(deps);
7017 return mountEffect(create, deps);
7018 },
7019 useImperativeHandle: function (ref, create, deps) {
7020 currentHookNameInDev = 'useImperativeHandle';
7021 mountHookTypesDev();
7022 checkDepsAreArrayDev(deps);
7023 return mountImperativeHandle(ref, create, deps);
7024 },
7025 useLayoutEffect: function (create, deps) {
7026 currentHookNameInDev = 'useLayoutEffect';
7027 mountHookTypesDev();
7028 checkDepsAreArrayDev(deps);
7029 return mountLayoutEffect(create, deps);
7030 },
7031 useMemo: function (create, deps) {
7032 currentHookNameInDev = 'useMemo';
7033 mountHookTypesDev();
7034 checkDepsAreArrayDev(deps);
7035 var prevDispatcher = ReactCurrentDispatcher.current;
7036 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7037
7038 try {
7039 return mountMemo(create, deps);
7040 } finally {
7041 ReactCurrentDispatcher.current = prevDispatcher;
7042 }
7043 },
7044 useReducer: function (reducer, initialArg, init) {
7045 currentHookNameInDev = 'useReducer';
7046 mountHookTypesDev();
7047 var prevDispatcher = ReactCurrentDispatcher.current;
7048 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7049
7050 try {
7051 return mountReducer(reducer, initialArg, init);
7052 } finally {
7053 ReactCurrentDispatcher.current = prevDispatcher;
7054 }
7055 },
7056 useRef: function (initialValue) {
7057 currentHookNameInDev = 'useRef';
7058 mountHookTypesDev();
7059 return mountRef(initialValue);
7060 },
7061 useState: function (initialState) {
7062 currentHookNameInDev = 'useState';
7063 mountHookTypesDev();
7064 var prevDispatcher = ReactCurrentDispatcher.current;
7065 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7066
7067 try {
7068 return mountState(initialState);
7069 } finally {
7070 ReactCurrentDispatcher.current = prevDispatcher;
7071 }
7072 },
7073 useDebugValue: function (value, formatterFn) {
7074 currentHookNameInDev = 'useDebugValue';
7075 mountHookTypesDev();
7076 return mountDebugValue();
7077 },
7078 useResponder: function (responder, props) {
7079 currentHookNameInDev = 'useResponder';
7080 mountHookTypesDev();
7081 return createDeprecatedResponderListener(responder, props);
7082 },
7083 useDeferredValue: function (value, config) {
7084 currentHookNameInDev = 'useDeferredValue';
7085 mountHookTypesDev();
7086 return mountDeferredValue(value, config);
7087 },
7088 useTransition: function (config) {
7089 currentHookNameInDev = 'useTransition';
7090 mountHookTypesDev();
7091 return mountTransition(config);
7092 }
7093 };
7094 HooksDispatcherOnMountWithHookTypesInDEV = {
7095 readContext: function (context, observedBits) {
7096 return readContext(context, observedBits);
7097 },
7098 useCallback: function (callback, deps) {
7099 currentHookNameInDev = 'useCallback';
7100 updateHookTypesDev();
7101 return mountCallback(callback, deps);
7102 },
7103 useContext: function (context, observedBits) {
7104 currentHookNameInDev = 'useContext';
7105 updateHookTypesDev();
7106 return readContext(context, observedBits);
7107 },
7108 useEffect: function (create, deps) {
7109 currentHookNameInDev = 'useEffect';
7110 updateHookTypesDev();
7111 return mountEffect(create, deps);
7112 },
7113 useImperativeHandle: function (ref, create, deps) {
7114 currentHookNameInDev = 'useImperativeHandle';
7115 updateHookTypesDev();
7116 return mountImperativeHandle(ref, create, deps);
7117 },
7118 useLayoutEffect: function (create, deps) {
7119 currentHookNameInDev = 'useLayoutEffect';
7120 updateHookTypesDev();
7121 return mountLayoutEffect(create, deps);
7122 },
7123 useMemo: function (create, deps) {
7124 currentHookNameInDev = 'useMemo';
7125 updateHookTypesDev();
7126 var prevDispatcher = ReactCurrentDispatcher.current;
7127 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7128
7129 try {
7130 return mountMemo(create, deps);
7131 } finally {
7132 ReactCurrentDispatcher.current = prevDispatcher;
7133 }
7134 },
7135 useReducer: function (reducer, initialArg, init) {
7136 currentHookNameInDev = 'useReducer';
7137 updateHookTypesDev();
7138 var prevDispatcher = ReactCurrentDispatcher.current;
7139 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7140
7141 try {
7142 return mountReducer(reducer, initialArg, init);
7143 } finally {
7144 ReactCurrentDispatcher.current = prevDispatcher;
7145 }
7146 },
7147 useRef: function (initialValue) {
7148 currentHookNameInDev = 'useRef';
7149 updateHookTypesDev();
7150 return mountRef(initialValue);
7151 },
7152 useState: function (initialState) {
7153 currentHookNameInDev = 'useState';
7154 updateHookTypesDev();
7155 var prevDispatcher = ReactCurrentDispatcher.current;
7156 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7157
7158 try {
7159 return mountState(initialState);
7160 } finally {
7161 ReactCurrentDispatcher.current = prevDispatcher;
7162 }
7163 },
7164 useDebugValue: function (value, formatterFn) {
7165 currentHookNameInDev = 'useDebugValue';
7166 updateHookTypesDev();
7167 return mountDebugValue();
7168 },
7169 useResponder: function (responder, props) {
7170 currentHookNameInDev = 'useResponder';
7171 updateHookTypesDev();
7172 return createDeprecatedResponderListener(responder, props);
7173 },
7174 useDeferredValue: function (value, config) {
7175 currentHookNameInDev = 'useDeferredValue';
7176 updateHookTypesDev();
7177 return mountDeferredValue(value, config);
7178 },
7179 useTransition: function (config) {
7180 currentHookNameInDev = 'useTransition';
7181 updateHookTypesDev();
7182 return mountTransition(config);
7183 }
7184 };
7185 HooksDispatcherOnUpdateInDEV = {
7186 readContext: function (context, observedBits) {
7187 return readContext(context, observedBits);
7188 },
7189 useCallback: function (callback, deps) {
7190 currentHookNameInDev = 'useCallback';
7191 updateHookTypesDev();
7192 return updateCallback(callback, deps);
7193 },
7194 useContext: function (context, observedBits) {
7195 currentHookNameInDev = 'useContext';
7196 updateHookTypesDev();
7197 return readContext(context, observedBits);
7198 },
7199 useEffect: function (create, deps) {
7200 currentHookNameInDev = 'useEffect';
7201 updateHookTypesDev();
7202 return updateEffect(create, deps);
7203 },
7204 useImperativeHandle: function (ref, create, deps) {
7205 currentHookNameInDev = 'useImperativeHandle';
7206 updateHookTypesDev();
7207 return updateImperativeHandle(ref, create, deps);
7208 },
7209 useLayoutEffect: function (create, deps) {
7210 currentHookNameInDev = 'useLayoutEffect';
7211 updateHookTypesDev();
7212 return updateLayoutEffect(create, deps);
7213 },
7214 useMemo: function (create, deps) {
7215 currentHookNameInDev = 'useMemo';
7216 updateHookTypesDev();
7217 var prevDispatcher = ReactCurrentDispatcher.current;
7218 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7219
7220 try {
7221 return updateMemo(create, deps);
7222 } finally {
7223 ReactCurrentDispatcher.current = prevDispatcher;
7224 }
7225 },
7226 useReducer: function (reducer, initialArg, init) {
7227 currentHookNameInDev = 'useReducer';
7228 updateHookTypesDev();
7229 var prevDispatcher = ReactCurrentDispatcher.current;
7230 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7231
7232 try {
7233 return updateReducer(reducer, initialArg, init);
7234 } finally {
7235 ReactCurrentDispatcher.current = prevDispatcher;
7236 }
7237 },
7238 useRef: function (initialValue) {
7239 currentHookNameInDev = 'useRef';
7240 updateHookTypesDev();
7241 return updateRef();
7242 },
7243 useState: function (initialState) {
7244 currentHookNameInDev = 'useState';
7245 updateHookTypesDev();
7246 var prevDispatcher = ReactCurrentDispatcher.current;
7247 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7248
7249 try {
7250 return updateState(initialState);
7251 } finally {
7252 ReactCurrentDispatcher.current = prevDispatcher;
7253 }
7254 },
7255 useDebugValue: function (value, formatterFn) {
7256 currentHookNameInDev = 'useDebugValue';
7257 updateHookTypesDev();
7258 return updateDebugValue();
7259 },
7260 useResponder: function (responder, props) {
7261 currentHookNameInDev = 'useResponder';
7262 updateHookTypesDev();
7263 return createDeprecatedResponderListener(responder, props);
7264 },
7265 useDeferredValue: function (value, config) {
7266 currentHookNameInDev = 'useDeferredValue';
7267 updateHookTypesDev();
7268 return updateDeferredValue(value, config);
7269 },
7270 useTransition: function (config) {
7271 currentHookNameInDev = 'useTransition';
7272 updateHookTypesDev();
7273 return updateTransition(config);
7274 }
7275 };
7276 HooksDispatcherOnRerenderInDEV = {
7277 readContext: function (context, observedBits) {
7278 return readContext(context, observedBits);
7279 },
7280 useCallback: function (callback, deps) {
7281 currentHookNameInDev = 'useCallback';
7282 updateHookTypesDev();
7283 return updateCallback(callback, deps);
7284 },
7285 useContext: function (context, observedBits) {
7286 currentHookNameInDev = 'useContext';
7287 updateHookTypesDev();
7288 return readContext(context, observedBits);
7289 },
7290 useEffect: function (create, deps) {
7291 currentHookNameInDev = 'useEffect';
7292 updateHookTypesDev();
7293 return updateEffect(create, deps);
7294 },
7295 useImperativeHandle: function (ref, create, deps) {
7296 currentHookNameInDev = 'useImperativeHandle';
7297 updateHookTypesDev();
7298 return updateImperativeHandle(ref, create, deps);
7299 },
7300 useLayoutEffect: function (create, deps) {
7301 currentHookNameInDev = 'useLayoutEffect';
7302 updateHookTypesDev();
7303 return updateLayoutEffect(create, deps);
7304 },
7305 useMemo: function (create, deps) {
7306 currentHookNameInDev = 'useMemo';
7307 updateHookTypesDev();
7308 var prevDispatcher = ReactCurrentDispatcher.current;
7309 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7310
7311 try {
7312 return updateMemo(create, deps);
7313 } finally {
7314 ReactCurrentDispatcher.current = prevDispatcher;
7315 }
7316 },
7317 useReducer: function (reducer, initialArg, init) {
7318 currentHookNameInDev = 'useReducer';
7319 updateHookTypesDev();
7320 var prevDispatcher = ReactCurrentDispatcher.current;
7321 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7322
7323 try {
7324 return rerenderReducer(reducer, initialArg, init);
7325 } finally {
7326 ReactCurrentDispatcher.current = prevDispatcher;
7327 }
7328 },
7329 useRef: function (initialValue) {
7330 currentHookNameInDev = 'useRef';
7331 updateHookTypesDev();
7332 return updateRef();
7333 },
7334 useState: function (initialState) {
7335 currentHookNameInDev = 'useState';
7336 updateHookTypesDev();
7337 var prevDispatcher = ReactCurrentDispatcher.current;
7338 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7339
7340 try {
7341 return rerenderState(initialState);
7342 } finally {
7343 ReactCurrentDispatcher.current = prevDispatcher;
7344 }
7345 },
7346 useDebugValue: function (value, formatterFn) {
7347 currentHookNameInDev = 'useDebugValue';
7348 updateHookTypesDev();
7349 return updateDebugValue();
7350 },
7351 useResponder: function (responder, props) {
7352 currentHookNameInDev = 'useResponder';
7353 updateHookTypesDev();
7354 return createDeprecatedResponderListener(responder, props);
7355 },
7356 useDeferredValue: function (value, config) {
7357 currentHookNameInDev = 'useDeferredValue';
7358 updateHookTypesDev();
7359 return rerenderDeferredValue(value, config);
7360 },
7361 useTransition: function (config) {
7362 currentHookNameInDev = 'useTransition';
7363 updateHookTypesDev();
7364 return rerenderTransition(config);
7365 }
7366 };
7367 InvalidNestedHooksDispatcherOnMountInDEV = {
7368 readContext: function (context, observedBits) {
7369 warnInvalidContextAccess();
7370 return readContext(context, observedBits);
7371 },
7372 useCallback: function (callback, deps) {
7373 currentHookNameInDev = 'useCallback';
7374 warnInvalidHookAccess();
7375 mountHookTypesDev();
7376 return mountCallback(callback, deps);
7377 },
7378 useContext: function (context, observedBits) {
7379 currentHookNameInDev = 'useContext';
7380 warnInvalidHookAccess();
7381 mountHookTypesDev();
7382 return readContext(context, observedBits);
7383 },
7384 useEffect: function (create, deps) {
7385 currentHookNameInDev = 'useEffect';
7386 warnInvalidHookAccess();
7387 mountHookTypesDev();
7388 return mountEffect(create, deps);
7389 },
7390 useImperativeHandle: function (ref, create, deps) {
7391 currentHookNameInDev = 'useImperativeHandle';
7392 warnInvalidHookAccess();
7393 mountHookTypesDev();
7394 return mountImperativeHandle(ref, create, deps);
7395 },
7396 useLayoutEffect: function (create, deps) {
7397 currentHookNameInDev = 'useLayoutEffect';
7398 warnInvalidHookAccess();
7399 mountHookTypesDev();
7400 return mountLayoutEffect(create, deps);
7401 },
7402 useMemo: function (create, deps) {
7403 currentHookNameInDev = 'useMemo';
7404 warnInvalidHookAccess();
7405 mountHookTypesDev();
7406 var prevDispatcher = ReactCurrentDispatcher.current;
7407 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7408
7409 try {
7410 return mountMemo(create, deps);
7411 } finally {
7412 ReactCurrentDispatcher.current = prevDispatcher;
7413 }
7414 },
7415 useReducer: function (reducer, initialArg, init) {
7416 currentHookNameInDev = 'useReducer';
7417 warnInvalidHookAccess();
7418 mountHookTypesDev();
7419 var prevDispatcher = ReactCurrentDispatcher.current;
7420 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7421
7422 try {
7423 return mountReducer(reducer, initialArg, init);
7424 } finally {
7425 ReactCurrentDispatcher.current = prevDispatcher;
7426 }
7427 },
7428 useRef: function (initialValue) {
7429 currentHookNameInDev = 'useRef';
7430 warnInvalidHookAccess();
7431 mountHookTypesDev();
7432 return mountRef(initialValue);
7433 },
7434 useState: function (initialState) {
7435 currentHookNameInDev = 'useState';
7436 warnInvalidHookAccess();
7437 mountHookTypesDev();
7438 var prevDispatcher = ReactCurrentDispatcher.current;
7439 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7440
7441 try {
7442 return mountState(initialState);
7443 } finally {
7444 ReactCurrentDispatcher.current = prevDispatcher;
7445 }
7446 },
7447 useDebugValue: function (value, formatterFn) {
7448 currentHookNameInDev = 'useDebugValue';
7449 warnInvalidHookAccess();
7450 mountHookTypesDev();
7451 return mountDebugValue();
7452 },
7453 useResponder: function (responder, props) {
7454 currentHookNameInDev = 'useResponder';
7455 warnInvalidHookAccess();
7456 mountHookTypesDev();
7457 return createDeprecatedResponderListener(responder, props);
7458 },
7459 useDeferredValue: function (value, config) {
7460 currentHookNameInDev = 'useDeferredValue';
7461 warnInvalidHookAccess();
7462 mountHookTypesDev();
7463 return mountDeferredValue(value, config);
7464 },
7465 useTransition: function (config) {
7466 currentHookNameInDev = 'useTransition';
7467 warnInvalidHookAccess();
7468 mountHookTypesDev();
7469 return mountTransition(config);
7470 }
7471 };
7472 InvalidNestedHooksDispatcherOnUpdateInDEV = {
7473 readContext: function (context, observedBits) {
7474 warnInvalidContextAccess();
7475 return readContext(context, observedBits);
7476 },
7477 useCallback: function (callback, deps) {
7478 currentHookNameInDev = 'useCallback';
7479 warnInvalidHookAccess();
7480 updateHookTypesDev();
7481 return updateCallback(callback, deps);
7482 },
7483 useContext: function (context, observedBits) {
7484 currentHookNameInDev = 'useContext';
7485 warnInvalidHookAccess();
7486 updateHookTypesDev();
7487 return readContext(context, observedBits);
7488 },
7489 useEffect: function (create, deps) {
7490 currentHookNameInDev = 'useEffect';
7491 warnInvalidHookAccess();
7492 updateHookTypesDev();
7493 return updateEffect(create, deps);
7494 },
7495 useImperativeHandle: function (ref, create, deps) {
7496 currentHookNameInDev = 'useImperativeHandle';
7497 warnInvalidHookAccess();
7498 updateHookTypesDev();
7499 return updateImperativeHandle(ref, create, deps);
7500 },
7501 useLayoutEffect: function (create, deps) {
7502 currentHookNameInDev = 'useLayoutEffect';
7503 warnInvalidHookAccess();
7504 updateHookTypesDev();
7505 return updateLayoutEffect(create, deps);
7506 },
7507 useMemo: function (create, deps) {
7508 currentHookNameInDev = 'useMemo';
7509 warnInvalidHookAccess();
7510 updateHookTypesDev();
7511 var prevDispatcher = ReactCurrentDispatcher.current;
7512 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7513
7514 try {
7515 return updateMemo(create, deps);
7516 } finally {
7517 ReactCurrentDispatcher.current = prevDispatcher;
7518 }
7519 },
7520 useReducer: function (reducer, initialArg, init) {
7521 currentHookNameInDev = 'useReducer';
7522 warnInvalidHookAccess();
7523 updateHookTypesDev();
7524 var prevDispatcher = ReactCurrentDispatcher.current;
7525 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7526
7527 try {
7528 return updateReducer(reducer, initialArg, init);
7529 } finally {
7530 ReactCurrentDispatcher.current = prevDispatcher;
7531 }
7532 },
7533 useRef: function (initialValue) {
7534 currentHookNameInDev = 'useRef';
7535 warnInvalidHookAccess();
7536 updateHookTypesDev();
7537 return updateRef();
7538 },
7539 useState: function (initialState) {
7540 currentHookNameInDev = 'useState';
7541 warnInvalidHookAccess();
7542 updateHookTypesDev();
7543 var prevDispatcher = ReactCurrentDispatcher.current;
7544 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7545
7546 try {
7547 return updateState(initialState);
7548 } finally {
7549 ReactCurrentDispatcher.current = prevDispatcher;
7550 }
7551 },
7552 useDebugValue: function (value, formatterFn) {
7553 currentHookNameInDev = 'useDebugValue';
7554 warnInvalidHookAccess();
7555 updateHookTypesDev();
7556 return updateDebugValue();
7557 },
7558 useResponder: function (responder, props) {
7559 currentHookNameInDev = 'useResponder';
7560 warnInvalidHookAccess();
7561 updateHookTypesDev();
7562 return createDeprecatedResponderListener(responder, props);
7563 },
7564 useDeferredValue: function (value, config) {
7565 currentHookNameInDev = 'useDeferredValue';
7566 warnInvalidHookAccess();
7567 updateHookTypesDev();
7568 return updateDeferredValue(value, config);
7569 },
7570 useTransition: function (config) {
7571 currentHookNameInDev = 'useTransition';
7572 warnInvalidHookAccess();
7573 updateHookTypesDev();
7574 return updateTransition(config);
7575 }
7576 };
7577 InvalidNestedHooksDispatcherOnRerenderInDEV = {
7578 readContext: function (context, observedBits) {
7579 warnInvalidContextAccess();
7580 return readContext(context, observedBits);
7581 },
7582 useCallback: function (callback, deps) {
7583 currentHookNameInDev = 'useCallback';
7584 warnInvalidHookAccess();
7585 updateHookTypesDev();
7586 return updateCallback(callback, deps);
7587 },
7588 useContext: function (context, observedBits) {
7589 currentHookNameInDev = 'useContext';
7590 warnInvalidHookAccess();
7591 updateHookTypesDev();
7592 return readContext(context, observedBits);
7593 },
7594 useEffect: function (create, deps) {
7595 currentHookNameInDev = 'useEffect';
7596 warnInvalidHookAccess();
7597 updateHookTypesDev();
7598 return updateEffect(create, deps);
7599 },
7600 useImperativeHandle: function (ref, create, deps) {
7601 currentHookNameInDev = 'useImperativeHandle';
7602 warnInvalidHookAccess();
7603 updateHookTypesDev();
7604 return updateImperativeHandle(ref, create, deps);
7605 },
7606 useLayoutEffect: function (create, deps) {
7607 currentHookNameInDev = 'useLayoutEffect';
7608 warnInvalidHookAccess();
7609 updateHookTypesDev();
7610 return updateLayoutEffect(create, deps);
7611 },
7612 useMemo: function (create, deps) {
7613 currentHookNameInDev = 'useMemo';
7614 warnInvalidHookAccess();
7615 updateHookTypesDev();
7616 var prevDispatcher = ReactCurrentDispatcher.current;
7617 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7618
7619 try {
7620 return updateMemo(create, deps);
7621 } finally {
7622 ReactCurrentDispatcher.current = prevDispatcher;
7623 }
7624 },
7625 useReducer: function (reducer, initialArg, init) {
7626 currentHookNameInDev = 'useReducer';
7627 warnInvalidHookAccess();
7628 updateHookTypesDev();
7629 var prevDispatcher = ReactCurrentDispatcher.current;
7630 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7631
7632 try {
7633 return rerenderReducer(reducer, initialArg, init);
7634 } finally {
7635 ReactCurrentDispatcher.current = prevDispatcher;
7636 }
7637 },
7638 useRef: function (initialValue) {
7639 currentHookNameInDev = 'useRef';
7640 warnInvalidHookAccess();
7641 updateHookTypesDev();
7642 return updateRef();
7643 },
7644 useState: function (initialState) {
7645 currentHookNameInDev = 'useState';
7646 warnInvalidHookAccess();
7647 updateHookTypesDev();
7648 var prevDispatcher = ReactCurrentDispatcher.current;
7649 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7650
7651 try {
7652 return rerenderState(initialState);
7653 } finally {
7654 ReactCurrentDispatcher.current = prevDispatcher;
7655 }
7656 },
7657 useDebugValue: function (value, formatterFn) {
7658 currentHookNameInDev = 'useDebugValue';
7659 warnInvalidHookAccess();
7660 updateHookTypesDev();
7661 return updateDebugValue();
7662 },
7663 useResponder: function (responder, props) {
7664 currentHookNameInDev = 'useResponder';
7665 warnInvalidHookAccess();
7666 updateHookTypesDev();
7667 return createDeprecatedResponderListener(responder, props);
7668 },
7669 useDeferredValue: function (value, config) {
7670 currentHookNameInDev = 'useDeferredValue';
7671 warnInvalidHookAccess();
7672 updateHookTypesDev();
7673 return rerenderDeferredValue(value, config);
7674 },
7675 useTransition: function (config) {
7676 currentHookNameInDev = 'useTransition';
7677 warnInvalidHookAccess();
7678 updateHookTypesDev();
7679 return rerenderTransition(config);
7680 }
7681 };
7682 }
7683
7684 var now$1 = unstable_now;
7685 var commitTime = 0;
7686 var profilerStartTime = -1;
7687
7688 function getCommitTime() {
7689 return commitTime;
7690 }
7691
7692 function recordCommitTime() {
7693
7694 commitTime = now$1();
7695 }
7696
7697 function startProfilerTimer(fiber) {
7698
7699 profilerStartTime = now$1();
7700
7701 if (fiber.actualStartTime < 0) {
7702 fiber.actualStartTime = now$1();
7703 }
7704 }
7705
7706 function stopProfilerTimerIfRunning(fiber) {
7707
7708 profilerStartTime = -1;
7709 }
7710
7711 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
7712
7713 if (profilerStartTime >= 0) {
7714 var elapsedTime = now$1() - profilerStartTime;
7715 fiber.actualDuration += elapsedTime;
7716
7717 if (overrideBaseTime) {
7718 fiber.selfBaseDuration = elapsedTime;
7719 }
7720
7721 profilerStartTime = -1;
7722 }
7723 }
7724
7725 function enterHydrationState(fiber) {
7726 {
7727 return false;
7728 }
7729 }
7730
7731 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
7732 {
7733 {
7734 {
7735 throw Error( "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7736 }
7737 }
7738 }
7739 }
7740
7741 function prepareToHydrateHostTextInstance(fiber) {
7742 {
7743 {
7744 {
7745 throw Error( "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7746 }
7747 }
7748 }
7749 var shouldUpdate = hydrateTextInstance();
7750 }
7751
7752 function popHydrationState(fiber) {
7753 {
7754 return false;
7755 }
7756 }
7757
7758 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
7759 var didReceiveUpdate = false;
7760 var didWarnAboutBadClass;
7761 var didWarnAboutModulePatternComponent;
7762 var didWarnAboutContextTypeOnFunctionComponent;
7763 var didWarnAboutGetDerivedStateOnFunctionComponent;
7764 var didWarnAboutFunctionRefs;
7765 var didWarnAboutReassigningProps;
7766 var didWarnAboutMaxDuration;
7767 var didWarnAboutRevealOrder;
7768 var didWarnAboutTailOptions;
7769
7770 {
7771 didWarnAboutBadClass = {};
7772 didWarnAboutModulePatternComponent = {};
7773 didWarnAboutContextTypeOnFunctionComponent = {};
7774 didWarnAboutGetDerivedStateOnFunctionComponent = {};
7775 didWarnAboutFunctionRefs = {};
7776 didWarnAboutReassigningProps = false;
7777 didWarnAboutMaxDuration = false;
7778 didWarnAboutRevealOrder = {};
7779 didWarnAboutTailOptions = {};
7780 }
7781
7782 function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
7783 if (current === null) {
7784 // If this is a fresh new component that hasn't been rendered yet, we
7785 // won't update its child set by applying minimal side-effects. Instead,
7786 // we will add them all to the child before it gets rendered. That means
7787 // we can optimize this reconciliation pass by not tracking side-effects.
7788 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7789 } else {
7790 // If the current child is the same as the work in progress, it means that
7791 // we haven't yet started any work on these children. Therefore, we use
7792 // the clone algorithm to create a copy of all the current children.
7793 // If we had any progressed work already, that is invalid at this point so
7794 // let's throw it out.
7795 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
7796 }
7797 }
7798
7799 function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
7800 // This function is fork of reconcileChildren. It's used in cases where we
7801 // want to reconcile without matching against the existing set. This has the
7802 // effect of all current children being unmounted; even if the type and key
7803 // are the same, the old child is unmounted and a new child is created.
7804 //
7805 // To do this, we're going to go through the reconcile algorithm twice. In
7806 // the first pass, we schedule a deletion for all the current children by
7807 // passing null.
7808 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
7809 // pass null in place of where we usually pass the current child set. This has
7810 // the effect of remounting all children regardless of whether their
7811 // identities match.
7812
7813 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7814 }
7815
7816 function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
7817 // TODO: current can be non-null here even if the component
7818 // hasn't yet mounted. This happens after the first render suspends.
7819 // We'll need to figure out if this is fine or can cause issues.
7820 {
7821 if (workInProgress.type !== workInProgress.elementType) {
7822 // Lazy component props can't be validated in createElement
7823 // because they're only guaranteed to be resolved here.
7824 var innerPropTypes = Component.propTypes;
7825
7826 if (innerPropTypes) {
7827 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7828 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7829 }
7830 }
7831 }
7832
7833 var render = Component.render;
7834 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
7835
7836 var nextChildren;
7837 prepareToReadContext(workInProgress, renderExpirationTime);
7838
7839 {
7840 ReactCurrentOwner$1.current = workInProgress;
7841 setCurrentPhase('render');
7842 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7843
7844 if ( workInProgress.mode & StrictMode) {
7845 // Only double-render components with Hooks
7846 if (workInProgress.memoizedState !== null) {
7847 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7848 }
7849 }
7850
7851 setCurrentPhase(null);
7852 }
7853
7854 if (current !== null && !didReceiveUpdate) {
7855 bailoutHooks(current, workInProgress, renderExpirationTime);
7856 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7857 } // React DevTools reads this flag.
7858
7859
7860 workInProgress.effectTag |= PerformedWork;
7861 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7862 return workInProgress.child;
7863 }
7864
7865 function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7866 if (current === null) {
7867 var type = Component.type;
7868
7869 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
7870 Component.defaultProps === undefined) {
7871 var resolvedType = type;
7872
7873 {
7874 resolvedType = resolveFunctionForHotReloading(type);
7875 } // If this is a plain function component without default props,
7876 // and with only the default shallow comparison, we upgrade it
7877 // to a SimpleMemoComponent to allow fast path updates.
7878
7879
7880 workInProgress.tag = SimpleMemoComponent;
7881 workInProgress.type = resolvedType;
7882
7883 {
7884 validateFunctionComponentInDev(workInProgress, type);
7885 }
7886
7887 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
7888 }
7889
7890 {
7891 var innerPropTypes = type.propTypes;
7892
7893 if (innerPropTypes) {
7894 // Inner memo component props aren't currently validated in createElement.
7895 // We could move it there, but we'd still need this for lazy code path.
7896 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7897 'prop', getComponentName(type), getCurrentFiberStackInDev);
7898 }
7899 }
7900
7901 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
7902 child.ref = workInProgress.ref;
7903 child.return = workInProgress;
7904 workInProgress.child = child;
7905 return child;
7906 }
7907
7908 {
7909 var _type = Component.type;
7910 var _innerPropTypes = _type.propTypes;
7911
7912 if (_innerPropTypes) {
7913 // Inner memo component props aren't currently validated in createElement.
7914 // We could move it there, but we'd still need this for lazy code path.
7915 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
7916 'prop', getComponentName(_type), getCurrentFiberStackInDev);
7917 }
7918 }
7919
7920 var currentChild = current.child; // This is always exactly one child
7921
7922 if (updateExpirationTime < renderExpirationTime) {
7923 // This will be the props with resolved defaultProps,
7924 // unlike current.memoizedProps which will be the unresolved ones.
7925 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
7926
7927 var compare = Component.compare;
7928 compare = compare !== null ? compare : shallowEqual;
7929
7930 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
7931 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7932 }
7933 } // React DevTools reads this flag.
7934
7935
7936 workInProgress.effectTag |= PerformedWork;
7937 var newChild = createWorkInProgress(currentChild, nextProps);
7938 newChild.ref = workInProgress.ref;
7939 newChild.return = workInProgress;
7940 workInProgress.child = newChild;
7941 return newChild;
7942 }
7943
7944 function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7945 // TODO: current can be non-null here even if the component
7946 // hasn't yet mounted. This happens when the inner render suspends.
7947 // We'll need to figure out if this is fine or can cause issues.
7948 {
7949 if (workInProgress.type !== workInProgress.elementType) {
7950 // Lazy component props can't be validated in createElement
7951 // because they're only guaranteed to be resolved here.
7952 var outerMemoType = workInProgress.elementType;
7953
7954 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
7955 // We warn when you define propTypes on lazy()
7956 // so let's just skip over it to find memo() outer wrapper.
7957 // Inner props for memo are validated later.
7958 outerMemoType = refineResolvedLazyComponent(outerMemoType);
7959 }
7960
7961 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
7962
7963 if (outerPropTypes) {
7964 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
7965 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
7966 } // Inner propTypes will be validated in the function component path.
7967
7968 }
7969 }
7970
7971 if (current !== null) {
7972 var prevProps = current.memoizedProps;
7973
7974 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
7975 workInProgress.type === current.type )) {
7976 didReceiveUpdate = false;
7977
7978 if (updateExpirationTime < renderExpirationTime) {
7979 // The pending update priority was cleared at the beginning of
7980 // beginWork. We're about to bail out, but there might be additional
7981 // updates at a lower priority. Usually, the priority level of the
7982 // remaining updates is accumlated during the evaluation of the
7983 // component (i.e. when processing the update queue). But since since
7984 // we're bailing out early *without* evaluating the component, we need
7985 // to account for it here, too. Reset to the value of the current fiber.
7986 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
7987 // because a MemoComponent fiber does not have hooks or an update queue;
7988 // rather, it wraps around an inner component, which may or may not
7989 // contains hooks.
7990 // TODO: Move the reset at in beginWork out of the common path so that
7991 // this is no longer necessary.
7992 workInProgress.expirationTime = current.expirationTime;
7993 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7994 }
7995 }
7996 }
7997
7998 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
7999 }
8000
8001 function updateFragment(current, workInProgress, renderExpirationTime) {
8002 var nextChildren = workInProgress.pendingProps;
8003 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8004 return workInProgress.child;
8005 }
8006
8007 function updateMode(current, workInProgress, renderExpirationTime) {
8008 var nextChildren = workInProgress.pendingProps.children;
8009 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8010 return workInProgress.child;
8011 }
8012
8013 function updateProfiler(current, workInProgress, renderExpirationTime) {
8014 {
8015 workInProgress.effectTag |= Update;
8016 }
8017
8018 var nextProps = workInProgress.pendingProps;
8019 var nextChildren = nextProps.children;
8020 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8021 return workInProgress.child;
8022 }
8023
8024 function markRef(current, workInProgress) {
8025 var ref = workInProgress.ref;
8026
8027 if (current === null && ref !== null || current !== null && current.ref !== ref) {
8028 // Schedule a Ref effect
8029 workInProgress.effectTag |= Ref;
8030 }
8031 }
8032
8033 function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8034 {
8035 if (workInProgress.type !== workInProgress.elementType) {
8036 // Lazy component props can't be validated in createElement
8037 // because they're only guaranteed to be resolved here.
8038 var innerPropTypes = Component.propTypes;
8039
8040 if (innerPropTypes) {
8041 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8042 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8043 }
8044 }
8045 }
8046
8047 var context;
8048
8049 {
8050 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
8051 context = getMaskedContext(workInProgress, unmaskedContext);
8052 }
8053
8054 var nextChildren;
8055 prepareToReadContext(workInProgress, renderExpirationTime);
8056
8057 {
8058 ReactCurrentOwner$1.current = workInProgress;
8059 setCurrentPhase('render');
8060 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8061
8062 if ( workInProgress.mode & StrictMode) {
8063 // Only double-render components with Hooks
8064 if (workInProgress.memoizedState !== null) {
8065 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8066 }
8067 }
8068
8069 setCurrentPhase(null);
8070 }
8071
8072 if (current !== null && !didReceiveUpdate) {
8073 bailoutHooks(current, workInProgress, renderExpirationTime);
8074 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8075 } // React DevTools reads this flag.
8076
8077
8078 workInProgress.effectTag |= PerformedWork;
8079 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8080 return workInProgress.child;
8081 }
8082
8083 function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8084 {
8085 if (workInProgress.type !== workInProgress.elementType) {
8086 // Lazy component props can't be validated in createElement
8087 // because they're only guaranteed to be resolved here.
8088 var innerPropTypes = Component.propTypes;
8089
8090 if (innerPropTypes) {
8091 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8092 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8093 }
8094 }
8095 } // Push context providers early to prevent context stack mismatches.
8096 // During mounting we don't know the child context yet as the instance doesn't exist.
8097 // We will invalidate the child context in finishClassComponent() right after rendering.
8098
8099
8100 var hasContext;
8101
8102 if (isContextProvider(Component)) {
8103 hasContext = true;
8104 pushContextProvider(workInProgress);
8105 } else {
8106 hasContext = false;
8107 }
8108
8109 prepareToReadContext(workInProgress, renderExpirationTime);
8110 var instance = workInProgress.stateNode;
8111 var shouldUpdate;
8112
8113 if (instance === null) {
8114 if (current !== null) {
8115 // A class component without an instance only mounts if it suspended
8116 // inside a non-concurrent tree, in an inconsistent state. We want to
8117 // treat it like a new mount, even though an empty version of it already
8118 // committed. Disconnect the alternate pointers.
8119 current.alternate = null;
8120 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8121
8122 workInProgress.effectTag |= Placement;
8123 } // In the initial pass we might need to construct the instance.
8124
8125
8126 constructClassInstance(workInProgress, Component, nextProps);
8127 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8128 shouldUpdate = true;
8129 } else if (current === null) {
8130 // In a resume, we'll already have an instance we can reuse.
8131 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8132 } else {
8133 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
8134 }
8135
8136 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
8137
8138 {
8139 var inst = workInProgress.stateNode;
8140
8141 if (inst.props !== nextProps) {
8142 if (!didWarnAboutReassigningProps) {
8143 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component');
8144 }
8145
8146 didWarnAboutReassigningProps = true;
8147 }
8148 }
8149
8150 return nextUnitOfWork;
8151 }
8152
8153 function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
8154 // Refs should update even if shouldComponentUpdate returns false
8155 markRef(current, workInProgress);
8156 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
8157
8158 if (!shouldUpdate && !didCaptureError) {
8159 // Context providers should defer to sCU for rendering
8160 if (hasContext) {
8161 invalidateContextProvider(workInProgress, Component, false);
8162 }
8163
8164 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8165 }
8166
8167 var instance = workInProgress.stateNode; // Rerender
8168
8169 ReactCurrentOwner$1.current = workInProgress;
8170 var nextChildren;
8171
8172 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
8173 // If we captured an error, but getDerivedStateFromError is not defined,
8174 // unmount all the children. componentDidCatch will schedule an update to
8175 // re-render a fallback. This is temporary until we migrate everyone to
8176 // the new API.
8177 // TODO: Warn in a future release.
8178 nextChildren = null;
8179
8180 {
8181 stopProfilerTimerIfRunning();
8182 }
8183 } else {
8184 {
8185 setCurrentPhase('render');
8186 nextChildren = instance.render();
8187
8188 if ( workInProgress.mode & StrictMode) {
8189 instance.render();
8190 }
8191
8192 setCurrentPhase(null);
8193 }
8194 } // React DevTools reads this flag.
8195
8196
8197 workInProgress.effectTag |= PerformedWork;
8198
8199 if (current !== null && didCaptureError) {
8200 // If we're recovering from an error, reconcile without reusing any of
8201 // the existing children. Conceptually, the normal children and the children
8202 // that are shown on error are two different sets, so we shouldn't reuse
8203 // normal children even if their identities match.
8204 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
8205 } else {
8206 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8207 } // Memoize state using the values we just used to render.
8208 // TODO: Restructure so we never read values from the instance.
8209
8210
8211 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
8212
8213 if (hasContext) {
8214 invalidateContextProvider(workInProgress, Component, true);
8215 }
8216
8217 return workInProgress.child;
8218 }
8219
8220 function pushHostRootContext(workInProgress) {
8221 var root = workInProgress.stateNode;
8222
8223 if (root.pendingContext) {
8224 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
8225 } else if (root.context) {
8226 // Should always be set
8227 pushTopLevelContextObject(workInProgress, root.context, false);
8228 }
8229
8230 pushHostContainer(workInProgress, root.containerInfo);
8231 }
8232
8233 function updateHostRoot(current, workInProgress, renderExpirationTime) {
8234 pushHostRootContext(workInProgress);
8235 var updateQueue = workInProgress.updateQueue;
8236
8237 if (!(current !== null && updateQueue !== null)) {
8238 {
8239 throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." );
8240 }
8241 }
8242
8243 var nextProps = workInProgress.pendingProps;
8244 var prevState = workInProgress.memoizedState;
8245 var prevChildren = prevState !== null ? prevState.element : null;
8246 cloneUpdateQueue(current, workInProgress);
8247 processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime);
8248 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
8249 // being called "element".
8250
8251 var nextChildren = nextState.element;
8252
8253 if (nextChildren === prevChildren) {
8254 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8255 }
8256
8257 var root = workInProgress.stateNode;
8258
8259 if (root.hydrate && enterHydrationState()) {
8260 // If we don't have any current children this might be the first pass.
8261 // We always try to hydrate. If this isn't a hydration pass there won't
8262 // be any children to hydrate which is effectively the same thing as
8263 // not hydrating.
8264 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8265 workInProgress.child = child;
8266 var node = child;
8267
8268 while (node) {
8269 // Mark each child as hydrating. This is a fast path to know whether this
8270 // tree is part of a hydrating tree. This is used to determine if a child
8271 // node has fully mounted yet, and for scheduling event replaying.
8272 // Conceptually this is similar to Placement in that a new subtree is
8273 // inserted into the React tree here. It just happens to not need DOM
8274 // mutations because it already exists.
8275 node.effectTag = node.effectTag & ~Placement | Hydrating;
8276 node = node.sibling;
8277 }
8278 } else {
8279 // Otherwise reset hydration state in case we aborted and resumed another
8280 // root.
8281 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8282 }
8283
8284 return workInProgress.child;
8285 }
8286
8287 function updateHostComponent(current, workInProgress, renderExpirationTime) {
8288 pushHostContext(workInProgress);
8289
8290 var type = workInProgress.type;
8291 var nextProps = workInProgress.pendingProps;
8292 var prevProps = current !== null ? current.memoizedProps : null;
8293 var nextChildren = nextProps.children;
8294 var isDirectTextChild = shouldSetTextContent(type, nextProps);
8295
8296 if (isDirectTextChild) {
8297 // We special case a direct text child of a host node. This is a common
8298 // case. We won't handle it as a reified child. We will instead handle
8299 // this in the host environment that also has access to this prop. That
8300 // avoids allocating another HostText fiber and traversing it.
8301 nextChildren = null;
8302 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
8303 // If we're switching from a direct text child to a normal child, or to
8304 // empty, we need to schedule the text content to be reset.
8305 workInProgress.effectTag |= ContentReset;
8306 }
8307
8308 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
8309
8310 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree()) {
8311 {
8312 markSpawnedWork(Never);
8313 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
8314
8315
8316 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
8317 return null;
8318 }
8319
8320 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8321 return workInProgress.child;
8322 }
8323
8324 function updateHostText(current, workInProgress) {
8325 // immediately after.
8326
8327
8328 return null;
8329 }
8330
8331 function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
8332 if (_current !== null) {
8333 // A lazy component only mounts if it suspended inside a non-
8334 // concurrent tree, in an inconsistent state. We want to treat it like
8335 // a new mount, even though an empty version of it already committed.
8336 // Disconnect the alternate pointers.
8337 _current.alternate = null;
8338 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8339
8340 workInProgress.effectTag |= Placement;
8341 }
8342
8343 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
8344 // Cancel and resume right after we know the tag.
8345
8346 cancelWorkTimer(workInProgress);
8347 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
8348
8349 workInProgress.type = Component;
8350 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
8351 startWorkTimer(workInProgress);
8352 var resolvedProps = resolveDefaultProps(Component, props);
8353 var child;
8354
8355 switch (resolvedTag) {
8356 case FunctionComponent:
8357 {
8358 {
8359 validateFunctionComponentInDev(workInProgress, Component);
8360 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
8361 }
8362
8363 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8364 return child;
8365 }
8366
8367 case ClassComponent:
8368 {
8369 {
8370 workInProgress.type = Component = resolveClassForHotReloading(Component);
8371 }
8372
8373 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8374 return child;
8375 }
8376
8377 case ForwardRef:
8378 {
8379 {
8380 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
8381 }
8382
8383 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8384 return child;
8385 }
8386
8387 case MemoComponent:
8388 {
8389 {
8390 if (workInProgress.type !== workInProgress.elementType) {
8391 var outerPropTypes = Component.propTypes;
8392
8393 if (outerPropTypes) {
8394 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
8395 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8396 }
8397 }
8398 }
8399
8400 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
8401 updateExpirationTime, renderExpirationTime);
8402 return child;
8403 }
8404 }
8405
8406 var hint = '';
8407
8408 {
8409 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
8410 hint = ' Did you wrap a component in React.lazy() more than once?';
8411 }
8412 } // This message intentionally doesn't mention ForwardRef or MemoComponent
8413 // because the fact that it's a separate type of work is an
8414 // implementation detail.
8415
8416
8417 {
8418 {
8419 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
8420 }
8421 }
8422 }
8423
8424 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
8425 if (_current !== null) {
8426 // An incomplete component only mounts if it suspended inside a non-
8427 // concurrent tree, in an inconsistent state. We want to treat it like
8428 // a new mount, even though an empty version of it already committed.
8429 // Disconnect the alternate pointers.
8430 _current.alternate = null;
8431 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8432
8433 workInProgress.effectTag |= Placement;
8434 } // Promote the fiber to a class and try rendering again.
8435
8436
8437 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
8438 // Push context providers early to prevent context stack mismatches.
8439 // During mounting we don't know the child context yet as the instance doesn't exist.
8440 // We will invalidate the child context in finishClassComponent() right after rendering.
8441
8442 var hasContext;
8443
8444 if (isContextProvider(Component)) {
8445 hasContext = true;
8446 pushContextProvider(workInProgress);
8447 } else {
8448 hasContext = false;
8449 }
8450
8451 prepareToReadContext(workInProgress, renderExpirationTime);
8452 constructClassInstance(workInProgress, Component, nextProps);
8453 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8454 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8455 }
8456
8457 function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
8458 if (_current !== null) {
8459 // An indeterminate component only mounts if it suspended inside a non-
8460 // concurrent tree, in an inconsistent state. We want to treat it like
8461 // a new mount, even though an empty version of it already committed.
8462 // Disconnect the alternate pointers.
8463 _current.alternate = null;
8464 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8465
8466 workInProgress.effectTag |= Placement;
8467 }
8468
8469 var props = workInProgress.pendingProps;
8470 var context;
8471
8472 {
8473 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
8474 context = getMaskedContext(workInProgress, unmaskedContext);
8475 }
8476
8477 prepareToReadContext(workInProgress, renderExpirationTime);
8478 var value;
8479
8480 {
8481 if (Component.prototype && typeof Component.prototype.render === 'function') {
8482 var componentName = getComponentName(Component) || 'Unknown';
8483
8484 if (!didWarnAboutBadClass[componentName]) {
8485 error("The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
8486
8487 didWarnAboutBadClass[componentName] = true;
8488 }
8489 }
8490
8491 if (workInProgress.mode & StrictMode) {
8492 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
8493 }
8494
8495 ReactCurrentOwner$1.current = workInProgress;
8496 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8497 } // React DevTools reads this flag.
8498
8499
8500 workInProgress.effectTag |= PerformedWork;
8501
8502 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
8503 {
8504 var _componentName = getComponentName(Component) || 'Unknown';
8505
8506 if (!didWarnAboutModulePatternComponent[_componentName]) {
8507 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
8508
8509 didWarnAboutModulePatternComponent[_componentName] = true;
8510 }
8511 } // Proceed under the assumption that this is a class instance
8512
8513
8514 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
8515
8516 workInProgress.memoizedState = null;
8517 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
8518 // During mounting we don't know the child context yet as the instance doesn't exist.
8519 // We will invalidate the child context in finishClassComponent() right after rendering.
8520
8521 var hasContext = false;
8522
8523 if (isContextProvider(Component)) {
8524 hasContext = true;
8525 pushContextProvider(workInProgress);
8526 } else {
8527 hasContext = false;
8528 }
8529
8530 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
8531 initializeUpdateQueue(workInProgress);
8532 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
8533
8534 if (typeof getDerivedStateFromProps === 'function') {
8535 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
8536 }
8537
8538 adoptClassInstance(workInProgress, value);
8539 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
8540 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8541 } else {
8542 // Proceed under the assumption that this is a function component
8543 workInProgress.tag = FunctionComponent;
8544
8545 {
8546
8547 if ( workInProgress.mode & StrictMode) {
8548 // Only double-render components with Hooks
8549 if (workInProgress.memoizedState !== null) {
8550 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8551 }
8552 }
8553 }
8554
8555 reconcileChildren(null, workInProgress, value, renderExpirationTime);
8556
8557 {
8558 validateFunctionComponentInDev(workInProgress, Component);
8559 }
8560
8561 return workInProgress.child;
8562 }
8563 }
8564
8565 function validateFunctionComponentInDev(workInProgress, Component) {
8566 {
8567 if (Component) {
8568 if (Component.childContextTypes) {
8569 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
8570 }
8571 }
8572
8573 if (workInProgress.ref !== null) {
8574 var info = '';
8575 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
8576
8577 if (ownerName) {
8578 info += '\n\nCheck the render method of `' + ownerName + '`.';
8579 }
8580
8581 var warningKey = ownerName || workInProgress._debugID || '';
8582 var debugSource = workInProgress._debugSource;
8583
8584 if (debugSource) {
8585 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8586 }
8587
8588 if (!didWarnAboutFunctionRefs[warningKey]) {
8589 didWarnAboutFunctionRefs[warningKey] = true;
8590
8591 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
8592 }
8593 }
8594
8595 if (typeof Component.getDerivedStateFromProps === 'function') {
8596 var _componentName2 = getComponentName(Component) || 'Unknown';
8597
8598 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
8599 error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);
8600
8601 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
8602 }
8603 }
8604
8605 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
8606 var _componentName3 = getComponentName(Component) || 'Unknown';
8607
8608 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
8609 error('%s: Function components do not support contextType.', _componentName3);
8610
8611 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
8612 }
8613 }
8614 }
8615 }
8616
8617 var SUSPENDED_MARKER = {
8618 dehydrated: null,
8619 retryTime: NoWork
8620 };
8621
8622 function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
8623 // If the context is telling us that we should show a fallback, and we're not
8624 // already showing content, then we should show the fallback instead.
8625 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
8626 }
8627
8628 function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
8629 var mode = workInProgress.mode;
8630 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
8631
8632 {
8633 if (shouldSuspend(workInProgress)) {
8634 workInProgress.effectTag |= DidCapture;
8635 }
8636 }
8637
8638 var suspenseContext = suspenseStackCursor.current;
8639 var nextDidTimeout = false;
8640 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
8641
8642 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
8643 // Something in this boundary's subtree already suspended. Switch to
8644 // rendering the fallback children.
8645 nextDidTimeout = true;
8646 workInProgress.effectTag &= ~DidCapture;
8647 } else {
8648 // Attempting the main content
8649 if (current === null || current.memoizedState !== null) {
8650 // This is a new mount or this boundary is already showing a fallback state.
8651 // Mark this subtree context as having at least one invisible parent that could
8652 // handle the fallback state.
8653 // Boundaries without fallbacks or should be avoided are not considered since
8654 // they cannot handle preferred fallback states.
8655 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
8656 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
8657 }
8658 }
8659 }
8660
8661 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8662 pushSuspenseContext(workInProgress, suspenseContext);
8663
8664 {
8665 if ('maxDuration' in nextProps) {
8666 if (!didWarnAboutMaxDuration) {
8667 didWarnAboutMaxDuration = true;
8668
8669 error('maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
8670 }
8671 }
8672 } // This next part is a bit confusing. If the children timeout, we switch to
8673 // showing the fallback children in place of the "primary" children.
8674 // However, we don't want to delete the primary children because then their
8675 // state will be lost (both the React state and the host state, e.g.
8676 // uncontrolled form inputs). Instead we keep them mounted and hide them.
8677 // Both the fallback children AND the primary children are rendered at the
8678 // same time. Once the primary children are un-suspended, we can delete
8679 // the fallback children — don't need to preserve their state.
8680 //
8681 // The two sets of children are siblings in the host environment, but
8682 // semantically, for purposes of reconciliation, they are two separate sets.
8683 // So we store them using two fragment fibers.
8684 //
8685 // However, we want to avoid allocating extra fibers for every placeholder.
8686 // They're only necessary when the children time out, because that's the
8687 // only time when both sets are mounted.
8688 //
8689 // So, the extra fragment fibers are only used if the children time out.
8690 // Otherwise, we render the primary children directly. This requires some
8691 // custom reconciliation logic to preserve the state of the primary
8692 // children. It's essentially a very basic form of re-parenting.
8693
8694
8695 if (current === null) {
8696 // If we're currently hydrating, try to hydrate this boundary.
8697 // But only if this has a fallback.
8698 if (nextProps.fallback !== undefined) ; // This is the initial mount. This branch is pretty simple because there's
8699 // no previous state that needs to be preserved.
8700
8701
8702 if (nextDidTimeout) {
8703 // Mount separate fragments for primary and fallback children.
8704 var nextFallbackChildren = nextProps.fallback;
8705 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
8706 primaryChildFragment.return = workInProgress;
8707
8708 if ((workInProgress.mode & BlockingMode) === NoMode) {
8709 // Outside of blocking mode, we commit the effects from the
8710 // partially completed, timed-out tree, too.
8711 var progressedState = workInProgress.memoizedState;
8712 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
8713 primaryChildFragment.child = progressedPrimaryChild;
8714 var progressedChild = progressedPrimaryChild;
8715
8716 while (progressedChild !== null) {
8717 progressedChild.return = primaryChildFragment;
8718 progressedChild = progressedChild.sibling;
8719 }
8720 }
8721
8722 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
8723 fallbackChildFragment.return = workInProgress;
8724 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
8725 // fallback children.
8726
8727 workInProgress.memoizedState = SUSPENDED_MARKER;
8728 workInProgress.child = primaryChildFragment;
8729 return fallbackChildFragment;
8730 } else {
8731 // Mount the primary children without an intermediate fragment fiber.
8732 var nextPrimaryChildren = nextProps.children;
8733 workInProgress.memoizedState = null;
8734 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
8735 }
8736 } else {
8737 // This is an update. This branch is more complicated because we need to
8738 // ensure the state of the primary children is preserved.
8739 var prevState = current.memoizedState;
8740
8741 if (prevState !== null) {
8742 // wrapped in a fragment fiber.
8743
8744
8745 var currentPrimaryChildFragment = current.child;
8746 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
8747
8748 if (nextDidTimeout) {
8749 // Still timed out. Reuse the current primary children by cloning
8750 // its fragment. We're going to skip over these entirely.
8751 var _nextFallbackChildren2 = nextProps.fallback;
8752
8753 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps);
8754
8755 _primaryChildFragment2.return = workInProgress;
8756
8757 if ((workInProgress.mode & BlockingMode) === NoMode) {
8758 // Outside of blocking mode, we commit the effects from the
8759 // partially completed, timed-out tree, too.
8760 var _progressedState = workInProgress.memoizedState;
8761
8762 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
8763
8764 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
8765 _primaryChildFragment2.child = _progressedPrimaryChild;
8766 var _progressedChild2 = _progressedPrimaryChild;
8767
8768 while (_progressedChild2 !== null) {
8769 _progressedChild2.return = _primaryChildFragment2;
8770 _progressedChild2 = _progressedChild2.sibling;
8771 }
8772 }
8773 } // Because primaryChildFragment is a new fiber that we're inserting as the
8774 // parent of a new tree, we need to set its treeBaseDuration.
8775
8776
8777 if ( workInProgress.mode & ProfileMode) {
8778 // treeBaseDuration is the sum of all the child tree base durations.
8779 var _treeBaseDuration = 0;
8780 var _hiddenChild = _primaryChildFragment2.child;
8781
8782 while (_hiddenChild !== null) {
8783 _treeBaseDuration += _hiddenChild.treeBaseDuration;
8784 _hiddenChild = _hiddenChild.sibling;
8785 }
8786
8787 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
8788 } // Clone the fallback child fragment, too. These we'll continue
8789 // working on.
8790
8791
8792 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2);
8793
8794 _fallbackChildFragment2.return = workInProgress;
8795 _primaryChildFragment2.sibling = _fallbackChildFragment2;
8796 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8797 // fallback children.
8798
8799 workInProgress.memoizedState = SUSPENDED_MARKER;
8800 workInProgress.child = _primaryChildFragment2;
8801 return _fallbackChildFragment2;
8802 } else {
8803 // No longer suspended. Switch back to showing the primary children,
8804 // and remove the intermediate fragment fiber.
8805 var _nextPrimaryChildren = nextProps.children;
8806 var currentPrimaryChild = currentPrimaryChildFragment.child;
8807 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
8808 // children. Wait until the complete phase, after we've confirmed the
8809 // fallback is no longer needed.
8810 // TODO: Would it be better to store the fallback fragment on
8811 // the stateNode?
8812 // Continue rendering the children, like we normally do.
8813
8814 workInProgress.memoizedState = null;
8815 return workInProgress.child = primaryChild;
8816 }
8817 } else {
8818 // The current tree has not already timed out. That means the primary
8819 // children are not wrapped in a fragment fiber.
8820 var _currentPrimaryChild = current.child;
8821
8822 if (nextDidTimeout) {
8823 // Timed out. Wrap the children in a fragment fiber to keep them
8824 // separate from the fallback children.
8825 var _nextFallbackChildren3 = nextProps.fallback;
8826
8827 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
8828 // going to render this fragment.
8829 null, mode, NoWork, null);
8830
8831 _primaryChildFragment3.return = workInProgress;
8832 _primaryChildFragment3.child = _currentPrimaryChild;
8833
8834 if (_currentPrimaryChild !== null) {
8835 _currentPrimaryChild.return = _primaryChildFragment3;
8836 } // Even though we're creating a new fiber, there are no new children,
8837 // because we're reusing an already mounted tree. So we don't need to
8838 // schedule a placement.
8839 // primaryChildFragment.effectTag |= Placement;
8840
8841
8842 if ((workInProgress.mode & BlockingMode) === NoMode) {
8843 // Outside of blocking mode, we commit the effects from the
8844 // partially completed, timed-out tree, too.
8845 var _progressedState2 = workInProgress.memoizedState;
8846
8847 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
8848
8849 _primaryChildFragment3.child = _progressedPrimaryChild2;
8850 var _progressedChild3 = _progressedPrimaryChild2;
8851
8852 while (_progressedChild3 !== null) {
8853 _progressedChild3.return = _primaryChildFragment3;
8854 _progressedChild3 = _progressedChild3.sibling;
8855 }
8856 } // Because primaryChildFragment is a new fiber that we're inserting as the
8857 // parent of a new tree, we need to set its treeBaseDuration.
8858
8859
8860 if ( workInProgress.mode & ProfileMode) {
8861 // treeBaseDuration is the sum of all the child tree base durations.
8862 var _treeBaseDuration2 = 0;
8863 var _hiddenChild2 = _primaryChildFragment3.child;
8864
8865 while (_hiddenChild2 !== null) {
8866 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
8867 _hiddenChild2 = _hiddenChild2.sibling;
8868 }
8869
8870 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
8871 } // Create a fragment from the fallback children, too.
8872
8873
8874 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
8875
8876 _fallbackChildFragment3.return = workInProgress;
8877 _primaryChildFragment3.sibling = _fallbackChildFragment3;
8878 _fallbackChildFragment3.effectTag |= Placement;
8879 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8880 // fallback children.
8881
8882 workInProgress.memoizedState = SUSPENDED_MARKER;
8883 workInProgress.child = _primaryChildFragment3;
8884 return _fallbackChildFragment3;
8885 } else {
8886 // Still haven't timed out. Continue rendering the children, like we
8887 // normally do.
8888 workInProgress.memoizedState = null;
8889 var _nextPrimaryChildren2 = nextProps.children;
8890 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
8891 }
8892 }
8893 }
8894 }
8895
8896 function scheduleWorkOnFiber(fiber, renderExpirationTime) {
8897 if (fiber.expirationTime < renderExpirationTime) {
8898 fiber.expirationTime = renderExpirationTime;
8899 }
8900
8901 var alternate = fiber.alternate;
8902
8903 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8904 alternate.expirationTime = renderExpirationTime;
8905 }
8906
8907 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
8908 }
8909
8910 function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
8911 // Mark any Suspense boundaries with fallbacks as having work to do.
8912 // If they were previously forced into fallbacks, they may now be able
8913 // to unblock.
8914 var node = firstChild;
8915
8916 while (node !== null) {
8917 if (node.tag === SuspenseComponent) {
8918 var state = node.memoizedState;
8919
8920 if (state !== null) {
8921 scheduleWorkOnFiber(node, renderExpirationTime);
8922 }
8923 } else if (node.tag === SuspenseListComponent) {
8924 // If the tail is hidden there might not be an Suspense boundaries
8925 // to schedule work on. In this case we have to schedule it on the
8926 // list itself.
8927 // We don't have to traverse to the children of the list since
8928 // the list will propagate the change when it rerenders.
8929 scheduleWorkOnFiber(node, renderExpirationTime);
8930 } else if (node.child !== null) {
8931 node.child.return = node;
8932 node = node.child;
8933 continue;
8934 }
8935
8936 if (node === workInProgress) {
8937 return;
8938 }
8939
8940 while (node.sibling === null) {
8941 if (node.return === null || node.return === workInProgress) {
8942 return;
8943 }
8944
8945 node = node.return;
8946 }
8947
8948 node.sibling.return = node.return;
8949 node = node.sibling;
8950 }
8951 }
8952
8953 function findLastContentRow(firstChild) {
8954 // This is going to find the last row among these children that is already
8955 // showing content on the screen, as opposed to being in fallback state or
8956 // new. If a row has multiple Suspense boundaries, any of them being in the
8957 // fallback state, counts as the whole row being in a fallback state.
8958 // Note that the "rows" will be workInProgress, but any nested children
8959 // will still be current since we haven't rendered them yet. The mounted
8960 // order may not be the same as the new order. We use the new order.
8961 var row = firstChild;
8962 var lastContentRow = null;
8963
8964 while (row !== null) {
8965 var currentRow = row.alternate; // New rows can't be content rows.
8966
8967 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8968 lastContentRow = row;
8969 }
8970
8971 row = row.sibling;
8972 }
8973
8974 return lastContentRow;
8975 }
8976
8977 function validateRevealOrder(revealOrder) {
8978 {
8979 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
8980 didWarnAboutRevealOrder[revealOrder] = true;
8981
8982 if (typeof revealOrder === 'string') {
8983 switch (revealOrder.toLowerCase()) {
8984 case 'together':
8985 case 'forwards':
8986 case 'backwards':
8987 {
8988 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
8989
8990 break;
8991 }
8992
8993 case 'forward':
8994 case 'backward':
8995 {
8996 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
8997
8998 break;
8999 }
9000
9001 default:
9002 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
9003
9004 break;
9005 }
9006 } else {
9007 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
9008 }
9009 }
9010 }
9011 }
9012
9013 function validateTailOptions(tailMode, revealOrder) {
9014 {
9015 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
9016 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
9017 didWarnAboutTailOptions[tailMode] = true;
9018
9019 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
9020 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
9021 didWarnAboutTailOptions[tailMode] = true;
9022
9023 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
9024 }
9025 }
9026 }
9027 }
9028
9029 function validateSuspenseListNestedChild(childSlot, index) {
9030 {
9031 var isArray = Array.isArray(childSlot);
9032 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
9033
9034 if (isArray || isIterable) {
9035 var type = isArray ? 'array' : 'iterable';
9036
9037 error('A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
9038
9039 return false;
9040 }
9041 }
9042
9043 return true;
9044 }
9045
9046 function validateSuspenseListChildren(children, revealOrder) {
9047 {
9048 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
9049 if (Array.isArray(children)) {
9050 for (var i = 0; i < children.length; i++) {
9051 if (!validateSuspenseListNestedChild(children[i], i)) {
9052 return;
9053 }
9054 }
9055 } else {
9056 var iteratorFn = getIteratorFn(children);
9057
9058 if (typeof iteratorFn === 'function') {
9059 var childrenIterator = iteratorFn.call(children);
9060
9061 if (childrenIterator) {
9062 var step = childrenIterator.next();
9063 var _i = 0;
9064
9065 for (; !step.done; step = childrenIterator.next()) {
9066 if (!validateSuspenseListNestedChild(step.value, _i)) {
9067 return;
9068 }
9069
9070 _i++;
9071 }
9072 }
9073 } else {
9074 error('A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
9075 }
9076 }
9077 }
9078 }
9079 }
9080
9081 function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
9082 var renderState = workInProgress.memoizedState;
9083
9084 if (renderState === null) {
9085 workInProgress.memoizedState = {
9086 isBackwards: isBackwards,
9087 rendering: null,
9088 renderingStartTime: 0,
9089 last: lastContentRow,
9090 tail: tail,
9091 tailExpiration: 0,
9092 tailMode: tailMode,
9093 lastEffect: lastEffectBeforeRendering
9094 };
9095 } else {
9096 // We can reuse the existing object from previous renders.
9097 renderState.isBackwards = isBackwards;
9098 renderState.rendering = null;
9099 renderState.renderingStartTime = 0;
9100 renderState.last = lastContentRow;
9101 renderState.tail = tail;
9102 renderState.tailExpiration = 0;
9103 renderState.tailMode = tailMode;
9104 renderState.lastEffect = lastEffectBeforeRendering;
9105 }
9106 } // This can end up rendering this component multiple passes.
9107 // The first pass splits the children fibers into two sets. A head and tail.
9108 // We first render the head. If anything is in fallback state, we do another
9109 // pass through beginWork to rerender all children (including the tail) with
9110 // the force suspend context. If the first render didn't have anything in
9111 // in fallback state. Then we render each row in the tail one-by-one.
9112 // That happens in the completeWork phase without going back to beginWork.
9113
9114
9115 function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
9116 var nextProps = workInProgress.pendingProps;
9117 var revealOrder = nextProps.revealOrder;
9118 var tailMode = nextProps.tail;
9119 var newChildren = nextProps.children;
9120 validateRevealOrder(revealOrder);
9121 validateTailOptions(tailMode, revealOrder);
9122 validateSuspenseListChildren(newChildren, revealOrder);
9123 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
9124 var suspenseContext = suspenseStackCursor.current;
9125 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
9126
9127 if (shouldForceFallback) {
9128 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
9129 workInProgress.effectTag |= DidCapture;
9130 } else {
9131 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
9132
9133 if (didSuspendBefore) {
9134 // If we previously forced a fallback, we need to schedule work
9135 // on any nested boundaries to let them know to try to render
9136 // again. This is the same as context updating.
9137 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
9138 }
9139
9140 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
9141 }
9142
9143 pushSuspenseContext(workInProgress, suspenseContext);
9144
9145 if ((workInProgress.mode & BlockingMode) === NoMode) {
9146 // Outside of blocking mode, SuspenseList doesn't work so we just
9147 // use make it a noop by treating it as the default revealOrder.
9148 workInProgress.memoizedState = null;
9149 } else {
9150 switch (revealOrder) {
9151 case 'forwards':
9152 {
9153 var lastContentRow = findLastContentRow(workInProgress.child);
9154 var tail;
9155
9156 if (lastContentRow === null) {
9157 // The whole list is part of the tail.
9158 // TODO: We could fast path by just rendering the tail now.
9159 tail = workInProgress.child;
9160 workInProgress.child = null;
9161 } else {
9162 // Disconnect the tail rows after the content row.
9163 // We're going to render them separately later.
9164 tail = lastContentRow.sibling;
9165 lastContentRow.sibling = null;
9166 }
9167
9168 initSuspenseListRenderState(workInProgress, false, // isBackwards
9169 tail, lastContentRow, tailMode, workInProgress.lastEffect);
9170 break;
9171 }
9172
9173 case 'backwards':
9174 {
9175 // We're going to find the first row that has existing content.
9176 // At the same time we're going to reverse the list of everything
9177 // we pass in the meantime. That's going to be our tail in reverse
9178 // order.
9179 var _tail = null;
9180 var row = workInProgress.child;
9181 workInProgress.child = null;
9182
9183 while (row !== null) {
9184 var currentRow = row.alternate; // New rows can't be content rows.
9185
9186 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
9187 // This is the beginning of the main content.
9188 workInProgress.child = row;
9189 break;
9190 }
9191
9192 var nextRow = row.sibling;
9193 row.sibling = _tail;
9194 _tail = row;
9195 row = nextRow;
9196 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
9197
9198
9199 initSuspenseListRenderState(workInProgress, true, // isBackwards
9200 _tail, null, // last
9201 tailMode, workInProgress.lastEffect);
9202 break;
9203 }
9204
9205 case 'together':
9206 {
9207 initSuspenseListRenderState(workInProgress, false, // isBackwards
9208 null, // tail
9209 null, // last
9210 undefined, workInProgress.lastEffect);
9211 break;
9212 }
9213
9214 default:
9215 {
9216 // The default reveal order is the same as not having
9217 // a boundary.
9218 workInProgress.memoizedState = null;
9219 }
9220 }
9221 }
9222
9223 return workInProgress.child;
9224 }
9225
9226 function updatePortalComponent(current, workInProgress, renderExpirationTime) {
9227 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9228 var nextChildren = workInProgress.pendingProps;
9229
9230 if (current === null) {
9231 // Portals are special because we don't append the children during mount
9232 // but at commit. Therefore we need to track insertions which the normal
9233 // flow doesn't do during mount. This doesn't happen at the root because
9234 // the root always starts with a "current" with a null child.
9235 // TODO: Consider unifying this with how the root works.
9236 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
9237 } else {
9238 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
9239 }
9240
9241 return workInProgress.child;
9242 }
9243
9244 function updateContextProvider(current, workInProgress, renderExpirationTime) {
9245 var providerType = workInProgress.type;
9246 var context = providerType._context;
9247 var newProps = workInProgress.pendingProps;
9248 var oldProps = workInProgress.memoizedProps;
9249 var newValue = newProps.value;
9250
9251 {
9252 var providerPropTypes = workInProgress.type.propTypes;
9253
9254 if (providerPropTypes) {
9255 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
9256 }
9257 }
9258
9259 pushProvider(workInProgress, newValue);
9260
9261 if (oldProps !== null) {
9262 var oldValue = oldProps.value;
9263 var changedBits = calculateChangedBits(context, newValue, oldValue);
9264
9265 if (changedBits === 0) {
9266 // No change. Bailout early if children are the same.
9267 if (oldProps.children === newProps.children && !hasContextChanged()) {
9268 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9269 }
9270 } else {
9271 // The context value changed. Search for matching consumers and schedule
9272 // them to update.
9273 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
9274 }
9275 }
9276
9277 var newChildren = newProps.children;
9278 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
9279 return workInProgress.child;
9280 }
9281
9282 var hasWarnedAboutUsingContextAsConsumer = false;
9283
9284 function updateContextConsumer(current, workInProgress, renderExpirationTime) {
9285 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
9286 // DEV mode, we create a separate object for Context.Consumer that acts
9287 // like a proxy to Context. This proxy object adds unnecessary code in PROD
9288 // so we use the old behaviour (Context.Consumer references Context) to
9289 // reduce size and overhead. The separate object references context via
9290 // a property called "_context", which also gives us the ability to check
9291 // in DEV mode if this property exists or not and warn if it does not.
9292
9293 {
9294 if (context._context === undefined) {
9295 // This may be because it's a Context (rather than a Consumer).
9296 // Or it may be because it's older React where they're the same thing.
9297 // We only want to warn if we're sure it's a new React.
9298 if (context !== context.Consumer) {
9299 if (!hasWarnedAboutUsingContextAsConsumer) {
9300 hasWarnedAboutUsingContextAsConsumer = true;
9301
9302 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
9303 }
9304 }
9305 } else {
9306 context = context._context;
9307 }
9308 }
9309
9310 var newProps = workInProgress.pendingProps;
9311 var render = newProps.children;
9312
9313 {
9314 if (typeof render !== 'function') {
9315 error('A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.');
9316 }
9317 }
9318
9319 prepareToReadContext(workInProgress, renderExpirationTime);
9320 var newValue = readContext(context, newProps.unstable_observedBits);
9321 var newChildren;
9322
9323 {
9324 ReactCurrentOwner$1.current = workInProgress;
9325 setCurrentPhase('render');
9326 newChildren = render(newValue);
9327 setCurrentPhase(null);
9328 } // React DevTools reads this flag.
9329
9330
9331 workInProgress.effectTag |= PerformedWork;
9332 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
9333 return workInProgress.child;
9334 }
9335
9336 function markWorkInProgressReceivedUpdate() {
9337 didReceiveUpdate = true;
9338 }
9339
9340 function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
9341 cancelWorkTimer(workInProgress);
9342
9343 if (current !== null) {
9344 // Reuse previous dependencies
9345 workInProgress.dependencies = current.dependencies;
9346 }
9347
9348 {
9349 // Don't update "base" render times for bailouts.
9350 stopProfilerTimerIfRunning();
9351 }
9352
9353 var updateExpirationTime = workInProgress.expirationTime;
9354
9355 if (updateExpirationTime !== NoWork) {
9356 markUnprocessedUpdateTime(updateExpirationTime);
9357 } // Check if the children have any pending work.
9358
9359
9360 var childExpirationTime = workInProgress.childExpirationTime;
9361
9362 if (childExpirationTime < renderExpirationTime) {
9363 // The children don't have any work either. We can skip them.
9364 // TODO: Once we add back resuming, we should check if the children are
9365 // a work-in-progress set. If so, we need to transfer their effects.
9366 return null;
9367 } else {
9368 // This fiber doesn't have work, but its subtree does. Clone the child
9369 // fibers and continue.
9370 cloneChildFibers(current, workInProgress);
9371 return workInProgress.child;
9372 }
9373 }
9374
9375 function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
9376 {
9377 var returnFiber = oldWorkInProgress.return;
9378
9379 if (returnFiber === null) {
9380 throw new Error('Cannot swap the root fiber.');
9381 } // Disconnect from the old current.
9382 // It will get deleted.
9383
9384
9385 current.alternate = null;
9386 oldWorkInProgress.alternate = null; // Connect to the new tree.
9387
9388 newWorkInProgress.index = oldWorkInProgress.index;
9389 newWorkInProgress.sibling = oldWorkInProgress.sibling;
9390 newWorkInProgress.return = oldWorkInProgress.return;
9391 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
9392
9393 if (oldWorkInProgress === returnFiber.child) {
9394 returnFiber.child = newWorkInProgress;
9395 } else {
9396 var prevSibling = returnFiber.child;
9397
9398 if (prevSibling === null) {
9399 throw new Error('Expected parent to have a child.');
9400 }
9401
9402 while (prevSibling.sibling !== oldWorkInProgress) {
9403 prevSibling = prevSibling.sibling;
9404
9405 if (prevSibling === null) {
9406 throw new Error('Expected to find the previous sibling.');
9407 }
9408 }
9409
9410 prevSibling.sibling = newWorkInProgress;
9411 } // Delete the old fiber and place the new one.
9412 // Since the old fiber is disconnected, we have to schedule it manually.
9413
9414
9415 var last = returnFiber.lastEffect;
9416
9417 if (last !== null) {
9418 last.nextEffect = current;
9419 returnFiber.lastEffect = current;
9420 } else {
9421 returnFiber.firstEffect = returnFiber.lastEffect = current;
9422 }
9423
9424 current.nextEffect = null;
9425 current.effectTag = Deletion;
9426 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
9427
9428 return newWorkInProgress;
9429 }
9430 }
9431
9432 function beginWork(current, workInProgress, renderExpirationTime) {
9433 var updateExpirationTime = workInProgress.expirationTime;
9434
9435 {
9436 if (workInProgress._debugNeedsRemount && current !== null) {
9437 // This will restart the begin phase with a new fiber.
9438 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
9439 }
9440 }
9441
9442 if (current !== null) {
9443 var oldProps = current.memoizedProps;
9444 var newProps = workInProgress.pendingProps;
9445
9446 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
9447 workInProgress.type !== current.type )) {
9448 // If props or context changed, mark the fiber as having performed work.
9449 // This may be unset if the props are determined to be equal later (memo).
9450 didReceiveUpdate = true;
9451 } else if (updateExpirationTime < renderExpirationTime) {
9452 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
9453 // the begin phase. There's still some bookkeeping we that needs to be done
9454 // in this optimized path, mostly pushing stuff onto the stack.
9455
9456 switch (workInProgress.tag) {
9457 case HostRoot:
9458 pushHostRootContext(workInProgress);
9459 break;
9460
9461 case HostComponent:
9462 pushHostContext(workInProgress);
9463
9464 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type)) {
9465 {
9466 markSpawnedWork(Never);
9467 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
9468
9469
9470 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
9471 return null;
9472 }
9473
9474 break;
9475
9476 case ClassComponent:
9477 {
9478 var Component = workInProgress.type;
9479
9480 if (isContextProvider(Component)) {
9481 pushContextProvider(workInProgress);
9482 }
9483
9484 break;
9485 }
9486
9487 case HostPortal:
9488 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9489 break;
9490
9491 case ContextProvider:
9492 {
9493 var newValue = workInProgress.memoizedProps.value;
9494 pushProvider(workInProgress, newValue);
9495 break;
9496 }
9497
9498 case Profiler:
9499 {
9500 // Profiler should only call onRender when one of its descendants actually rendered.
9501 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
9502
9503 if (hasChildWork) {
9504 workInProgress.effectTag |= Update;
9505 }
9506 }
9507
9508 break;
9509
9510 case SuspenseComponent:
9511 {
9512 var state = workInProgress.memoizedState;
9513
9514 if (state !== null) {
9515 // whether to retry the primary children, or to skip over it and
9516 // go straight to the fallback. Check the priority of the primary
9517 // child fragment.
9518
9519
9520 var primaryChildFragment = workInProgress.child;
9521 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
9522
9523 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
9524 // The primary children have pending work. Use the normal path
9525 // to attempt to render the primary children again.
9526 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9527 } else {
9528 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
9529 // priority. Bailout.
9530
9531 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9532
9533 if (child !== null) {
9534 // The fallback children have pending work. Skip over the
9535 // primary children and work on the fallback.
9536 return child.sibling;
9537 } else {
9538 return null;
9539 }
9540 }
9541 } else {
9542 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9543 }
9544
9545 break;
9546 }
9547
9548 case SuspenseListComponent:
9549 {
9550 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
9551
9552 var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
9553
9554 if (didSuspendBefore) {
9555 if (_hasChildWork) {
9556 // If something was in fallback state last time, and we have all the
9557 // same children then we're still in progressive loading state.
9558 // Something might get unblocked by state updates or retries in the
9559 // tree which will affect the tail. So we need to use the normal
9560 // path to compute the correct tail.
9561 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9562 } // If none of the children had any work, that means that none of
9563 // them got retried so they'll still be blocked in the same way
9564 // as before. We can fast bail out.
9565
9566
9567 workInProgress.effectTag |= DidCapture;
9568 } // If nothing suspended before and we're rendering the same children,
9569 // then the tail doesn't matter. Anything new that suspends will work
9570 // in the "together" mode, so we can continue from the state we had.
9571
9572
9573 var renderState = workInProgress.memoizedState;
9574
9575 if (renderState !== null) {
9576 // Reset to the "together" mode in case we've started a different
9577 // update in the past but didn't complete it.
9578 renderState.rendering = null;
9579 renderState.tail = null;
9580 }
9581
9582 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
9583
9584 if (_hasChildWork) {
9585 break;
9586 } else {
9587 // If none of the children had any work, that means that none of
9588 // them got retried so they'll still be blocked in the same way
9589 // as before. We can fast bail out.
9590 return null;
9591 }
9592 }
9593 }
9594
9595 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9596 } else {
9597 // An update was scheduled on this fiber, but there are no new props
9598 // nor legacy context. Set this to false. If an update queue or context
9599 // consumer produces a changed value, it will set this to true. Otherwise,
9600 // the component will assume the children have not changed and bail out.
9601 didReceiveUpdate = false;
9602 }
9603 } else {
9604 didReceiveUpdate = false;
9605 } // Before entering the begin phase, clear pending update priority.
9606 // TODO: This assumes that we're about to evaluate the component and process
9607 // the update queue. However, there's an exception: SimpleMemoComponent
9608 // sometimes bails out later in the begin phase. This indicates that we should
9609 // move this assignment out of the common path and into each branch.
9610
9611
9612 workInProgress.expirationTime = NoWork;
9613
9614 switch (workInProgress.tag) {
9615 case IndeterminateComponent:
9616 {
9617 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
9618 }
9619
9620 case LazyComponent:
9621 {
9622 var elementType = workInProgress.elementType;
9623 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
9624 }
9625
9626 case FunctionComponent:
9627 {
9628 var _Component = workInProgress.type;
9629 var unresolvedProps = workInProgress.pendingProps;
9630 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
9631 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
9632 }
9633
9634 case ClassComponent:
9635 {
9636 var _Component2 = workInProgress.type;
9637 var _unresolvedProps = workInProgress.pendingProps;
9638
9639 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
9640
9641 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
9642 }
9643
9644 case HostRoot:
9645 return updateHostRoot(current, workInProgress, renderExpirationTime);
9646
9647 case HostComponent:
9648 return updateHostComponent(current, workInProgress, renderExpirationTime);
9649
9650 case HostText:
9651 return updateHostText();
9652
9653 case SuspenseComponent:
9654 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9655
9656 case HostPortal:
9657 return updatePortalComponent(current, workInProgress, renderExpirationTime);
9658
9659 case ForwardRef:
9660 {
9661 var type = workInProgress.type;
9662 var _unresolvedProps2 = workInProgress.pendingProps;
9663
9664 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
9665
9666 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
9667 }
9668
9669 case Fragment:
9670 return updateFragment(current, workInProgress, renderExpirationTime);
9671
9672 case Mode:
9673 return updateMode(current, workInProgress, renderExpirationTime);
9674
9675 case Profiler:
9676 return updateProfiler(current, workInProgress, renderExpirationTime);
9677
9678 case ContextProvider:
9679 return updateContextProvider(current, workInProgress, renderExpirationTime);
9680
9681 case ContextConsumer:
9682 return updateContextConsumer(current, workInProgress, renderExpirationTime);
9683
9684 case MemoComponent:
9685 {
9686 var _type2 = workInProgress.type;
9687 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
9688
9689 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
9690
9691 {
9692 if (workInProgress.type !== workInProgress.elementType) {
9693 var outerPropTypes = _type2.propTypes;
9694
9695 if (outerPropTypes) {
9696 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
9697 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
9698 }
9699 }
9700 }
9701
9702 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
9703 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
9704 }
9705
9706 case SimpleMemoComponent:
9707 {
9708 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
9709 }
9710
9711 case IncompleteClassComponent:
9712 {
9713 var _Component3 = workInProgress.type;
9714 var _unresolvedProps4 = workInProgress.pendingProps;
9715
9716 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
9717
9718 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
9719 }
9720
9721 case SuspenseListComponent:
9722 {
9723 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9724 }
9725 }
9726
9727 {
9728 {
9729 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
9730 }
9731 }
9732 }
9733
9734 function markUpdate(workInProgress) {
9735 // Tag the fiber with an update effect. This turns a Placement into
9736 // a PlacementAndUpdate.
9737 workInProgress.effectTag |= Update;
9738 }
9739
9740 function markRef$1(workInProgress) {
9741 workInProgress.effectTag |= Ref;
9742 }
9743
9744 var appendAllChildren;
9745 var updateHostContainer;
9746 var updateHostComponent$1;
9747 var updateHostText$1;
9748
9749 {
9750 // Mutation mode
9751 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9752 // We only have the top Fiber that was created but we need recurse down its
9753 // children to find all the terminal nodes.
9754 var node = workInProgress.child;
9755
9756 while (node !== null) {
9757 if (node.tag === HostComponent || node.tag === HostText) {
9758 appendInitialChild(parent, node.stateNode);
9759 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
9760 node.child.return = node;
9761 node = node.child;
9762 continue;
9763 }
9764
9765 if (node === workInProgress) {
9766 return;
9767 }
9768
9769 while (node.sibling === null) {
9770 if (node.return === null || node.return === workInProgress) {
9771 return;
9772 }
9773
9774 node = node.return;
9775 }
9776
9777 node.sibling.return = node.return;
9778 node = node.sibling;
9779 }
9780 };
9781
9782 updateHostContainer = function (workInProgress) {// Noop
9783 };
9784
9785 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9786 // If we have an alternate, that means this is an update and we need to
9787 // schedule a side-effect to do the updates.
9788 var oldProps = current.memoizedProps;
9789
9790 if (oldProps === newProps) {
9791 // In mutation mode, this is sufficient for a bailout because
9792 // we won't touch this node even if children changed.
9793 return;
9794 } // If we get updated because one of our children updated, we don't
9795 // have newProps so we'll have to reuse them.
9796 // TODO: Split the update API as separate for the props vs. children.
9797 // Even better would be if children weren't special cased at all tho.
9798
9799
9800 var instance = workInProgress.stateNode;
9801 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
9802 // component is hitting the resume path. Figure out why. Possibly
9803 // related to `hidden`.
9804
9805 var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component.
9806
9807 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
9808 // is a new ref we mark this as an update. All the work is done in commitWork.
9809
9810 if (updatePayload) {
9811 markUpdate(workInProgress);
9812 }
9813 };
9814
9815 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9816 // If the text differs, mark it as an update. All the work in done in commitWork.
9817 if (oldText !== newText) {
9818 markUpdate(workInProgress);
9819 }
9820 };
9821 }
9822
9823 function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
9824 switch (renderState.tailMode) {
9825 case 'hidden':
9826 {
9827 // Any insertions at the end of the tail list after this point
9828 // should be invisible. If there are already mounted boundaries
9829 // anything before them are not considered for collapsing.
9830 // Therefore we need to go through the whole tail to find if
9831 // there are any.
9832 var tailNode = renderState.tail;
9833 var lastTailNode = null;
9834
9835 while (tailNode !== null) {
9836 if (tailNode.alternate !== null) {
9837 lastTailNode = tailNode;
9838 }
9839
9840 tailNode = tailNode.sibling;
9841 } // Next we're simply going to delete all insertions after the
9842 // last rendered item.
9843
9844
9845 if (lastTailNode === null) {
9846 // All remaining items in the tail are insertions.
9847 renderState.tail = null;
9848 } else {
9849 // Detach the insertion after the last node that was already
9850 // inserted.
9851 lastTailNode.sibling = null;
9852 }
9853
9854 break;
9855 }
9856
9857 case 'collapsed':
9858 {
9859 // Any insertions at the end of the tail list after this point
9860 // should be invisible. If there are already mounted boundaries
9861 // anything before them are not considered for collapsing.
9862 // Therefore we need to go through the whole tail to find if
9863 // there are any.
9864 var _tailNode = renderState.tail;
9865 var _lastTailNode = null;
9866
9867 while (_tailNode !== null) {
9868 if (_tailNode.alternate !== null) {
9869 _lastTailNode = _tailNode;
9870 }
9871
9872 _tailNode = _tailNode.sibling;
9873 } // Next we're simply going to delete all insertions after the
9874 // last rendered item.
9875
9876
9877 if (_lastTailNode === null) {
9878 // All remaining items in the tail are insertions.
9879 if (!hasRenderedATailFallback && renderState.tail !== null) {
9880 // We suspended during the head. We want to show at least one
9881 // row at the tail. So we'll keep on and cut off the rest.
9882 renderState.tail.sibling = null;
9883 } else {
9884 renderState.tail = null;
9885 }
9886 } else {
9887 // Detach the insertion after the last node that was already
9888 // inserted.
9889 _lastTailNode.sibling = null;
9890 }
9891
9892 break;
9893 }
9894 }
9895 }
9896
9897 function completeWork(current, workInProgress, renderExpirationTime) {
9898 var newProps = workInProgress.pendingProps;
9899
9900 switch (workInProgress.tag) {
9901 case IndeterminateComponent:
9902 case LazyComponent:
9903 case SimpleMemoComponent:
9904 case FunctionComponent:
9905 case ForwardRef:
9906 case Fragment:
9907 case Mode:
9908 case Profiler:
9909 case ContextConsumer:
9910 case MemoComponent:
9911 return null;
9912
9913 case ClassComponent:
9914 {
9915 var Component = workInProgress.type;
9916
9917 if (isContextProvider(Component)) {
9918 popContext(workInProgress);
9919 }
9920
9921 return null;
9922 }
9923
9924 case HostRoot:
9925 {
9926 popHostContainer(workInProgress);
9927 popTopLevelContextObject(workInProgress);
9928 var fiberRoot = workInProgress.stateNode;
9929
9930 if (fiberRoot.pendingContext) {
9931 fiberRoot.context = fiberRoot.pendingContext;
9932 fiberRoot.pendingContext = null;
9933 }
9934
9935 if (current === null || current.child === null) {
9936 // If we hydrated, pop so that we can delete any remaining children
9937 // that weren't hydrated.
9938 var wasHydrated = popHydrationState();
9939
9940 if (wasHydrated) {
9941 // If we hydrated, then we'll need to schedule an update for
9942 // the commit side-effects on the root.
9943 markUpdate(workInProgress);
9944 }
9945 }
9946
9947 updateHostContainer(workInProgress);
9948 return null;
9949 }
9950
9951 case HostComponent:
9952 {
9953 popHostContext(workInProgress);
9954 var rootContainerInstance = getRootHostContainer();
9955 var type = workInProgress.type;
9956
9957 if (current !== null && workInProgress.stateNode != null) {
9958 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9959
9960 if (current.ref !== workInProgress.ref) {
9961 markRef$1(workInProgress);
9962 }
9963 } else {
9964 if (!newProps) {
9965 if (!(workInProgress.stateNode !== null)) {
9966 {
9967 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
9968 }
9969 } // This can happen when we abort work.
9970
9971
9972 return null;
9973 }
9974
9975 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
9976 // "stack" as the parent. Then append children as we go in beginWork
9977 // or completeWork depending on whether we want to add them top->down or
9978 // bottom->up. Top->down is faster in IE11.
9979
9980 var _wasHydrated = popHydrationState();
9981
9982 if (_wasHydrated) {
9983 // TODO: Move this and createInstance step into the beginPhase
9984 // to consolidate.
9985 if (prepareToHydrateHostInstance()) {
9986 // If changes to the hydrated node need to be applied at the
9987 // commit-phase we mark this as such.
9988 markUpdate(workInProgress);
9989 }
9990 } else {
9991 var instance = createInstance(type, newProps);
9992 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
9993
9994 workInProgress.stateNode = instance;
9995 }
9996
9997 if (workInProgress.ref !== null) {
9998 // If there is a ref on a host node we need to schedule a callback
9999 markRef$1(workInProgress);
10000 }
10001 }
10002
10003 return null;
10004 }
10005
10006 case HostText:
10007 {
10008 var newText = newProps;
10009
10010 if (current && workInProgress.stateNode != null) {
10011 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
10012 // to schedule a side-effect to do the updates.
10013
10014 updateHostText$1(current, workInProgress, oldText, newText);
10015 } else {
10016 if (typeof newText !== 'string') {
10017 if (!(workInProgress.stateNode !== null)) {
10018 {
10019 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
10020 }
10021 } // This can happen when we abort work.
10022
10023 }
10024
10025 var _rootContainerInstance = getRootHostContainer();
10026
10027 var _currentHostContext = getHostContext();
10028
10029 var _wasHydrated2 = popHydrationState();
10030
10031 if (_wasHydrated2) {
10032 if (prepareToHydrateHostTextInstance()) {
10033 markUpdate(workInProgress);
10034 }
10035 } else {
10036 workInProgress.stateNode = createTextInstance(newText);
10037 }
10038 }
10039
10040 return null;
10041 }
10042
10043 case SuspenseComponent:
10044 {
10045 popSuspenseContext(workInProgress);
10046 var nextState = workInProgress.memoizedState;
10047
10048 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
10049 // Something suspended. Re-render with the fallback children.
10050 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
10051
10052 return workInProgress;
10053 }
10054
10055 var nextDidTimeout = nextState !== null;
10056 var prevDidTimeout = false;
10057
10058 if (current === null) {
10059 if (workInProgress.memoizedProps.fallback !== undefined) ;
10060 } else {
10061 var prevState = current.memoizedState;
10062 prevDidTimeout = prevState !== null;
10063
10064 if (!nextDidTimeout && prevState !== null) {
10065 // We just switched from the fallback to the normal children.
10066 // Delete the fallback.
10067 // TODO: Would it be better to store the fallback fragment on
10068 // the stateNode during the begin phase?
10069 var currentFallbackChild = current.child.sibling;
10070
10071 if (currentFallbackChild !== null) {
10072 // Deletions go at the beginning of the return fiber's effect list
10073 var first = workInProgress.firstEffect;
10074
10075 if (first !== null) {
10076 workInProgress.firstEffect = currentFallbackChild;
10077 currentFallbackChild.nextEffect = first;
10078 } else {
10079 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
10080 currentFallbackChild.nextEffect = null;
10081 }
10082
10083 currentFallbackChild.effectTag = Deletion;
10084 }
10085 }
10086 }
10087
10088 if (nextDidTimeout && !prevDidTimeout) {
10089 // If this subtreee is running in blocking mode we can suspend,
10090 // otherwise we won't suspend.
10091 // TODO: This will still suspend a synchronous tree if anything
10092 // in the concurrent tree already suspended during this render.
10093 // This is a known bug.
10094 if ((workInProgress.mode & BlockingMode) !== NoMode) {
10095 // TODO: Move this back to throwException because this is too late
10096 // if this is a large tree which is common for initial loads. We
10097 // don't know if we should restart a render or not until we get
10098 // this marker, and this is too late.
10099 // If this render already had a ping or lower pri updates,
10100 // and this is the first time we know we're going to suspend we
10101 // should be able to immediately restart from within throwException.
10102 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
10103
10104 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
10105 // If this was in an invisible tree or a new render, then showing
10106 // this boundary is ok.
10107 renderDidSuspend();
10108 } else {
10109 // Otherwise, we're going to have to hide content so we should
10110 // suspend for longer if possible.
10111 renderDidSuspendDelayIfPossible();
10112 }
10113 }
10114 }
10115
10116 {
10117 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
10118 if (nextDidTimeout || prevDidTimeout) {
10119 // If this boundary just timed out, schedule an effect to attach a
10120 // retry listener to the promise. This flag is also used to hide the
10121 // primary children. In mutation mode, we also need the flag to
10122 // *unhide* children that were previously hidden, so check if this
10123 // is currently timed out, too.
10124 workInProgress.effectTag |= Update;
10125 }
10126 }
10127
10128 return null;
10129 }
10130
10131 case HostPortal:
10132 popHostContainer(workInProgress);
10133 updateHostContainer(workInProgress);
10134 return null;
10135
10136 case ContextProvider:
10137 // Pop provider fiber
10138 popProvider(workInProgress);
10139 return null;
10140
10141 case IncompleteClassComponent:
10142 {
10143 // Same as class component case. I put it down here so that the tags are
10144 // sequential to ensure this switch is compiled to a jump table.
10145 var _Component = workInProgress.type;
10146
10147 if (isContextProvider(_Component)) {
10148 popContext(workInProgress);
10149 }
10150
10151 return null;
10152 }
10153
10154 case SuspenseListComponent:
10155 {
10156 popSuspenseContext(workInProgress);
10157 var renderState = workInProgress.memoizedState;
10158
10159 if (renderState === null) {
10160 // We're running in the default, "independent" mode.
10161 // We don't do anything in this mode.
10162 return null;
10163 }
10164
10165 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
10166 var renderedTail = renderState.rendering;
10167
10168 if (renderedTail === null) {
10169 // We just rendered the head.
10170 if (!didSuspendAlready) {
10171 // This is the first pass. We need to figure out if anything is still
10172 // suspended in the rendered set.
10173 // If new content unsuspended, but there's still some content that
10174 // didn't. Then we need to do a second pass that forces everything
10175 // to keep showing their fallbacks.
10176 // We might be suspended if something in this render pass suspended, or
10177 // something in the previous committed pass suspended. Otherwise,
10178 // there's no chance so we can skip the expensive call to
10179 // findFirstSuspended.
10180 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
10181
10182 if (!cannotBeSuspended) {
10183 var row = workInProgress.child;
10184
10185 while (row !== null) {
10186 var suspended = findFirstSuspended(row);
10187
10188 if (suspended !== null) {
10189 didSuspendAlready = true;
10190 workInProgress.effectTag |= DidCapture;
10191 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
10192 // part of the second pass. In that case nothing will subscribe to
10193 // its thennables. Instead, we'll transfer its thennables to the
10194 // SuspenseList so that it can retry if they resolve.
10195 // There might be multiple of these in the list but since we're
10196 // going to wait for all of them anyway, it doesn't really matter
10197 // which ones gets to ping. In theory we could get clever and keep
10198 // track of how many dependencies remain but it gets tricky because
10199 // in the meantime, we can add/remove/change items and dependencies.
10200 // We might bail out of the loop before finding any but that
10201 // doesn't matter since that means that the other boundaries that
10202 // we did find already has their listeners attached.
10203
10204 var newThennables = suspended.updateQueue;
10205
10206 if (newThennables !== null) {
10207 workInProgress.updateQueue = newThennables;
10208 workInProgress.effectTag |= Update;
10209 } // Rerender the whole list, but this time, we'll force fallbacks
10210 // to stay in place.
10211 // Reset the effect list before doing the second pass since that's now invalid.
10212
10213
10214 if (renderState.lastEffect === null) {
10215 workInProgress.firstEffect = null;
10216 }
10217
10218 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
10219
10220 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
10221 // rerender the children.
10222
10223 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
10224 return workInProgress.child;
10225 }
10226
10227 row = row.sibling;
10228 }
10229 }
10230 } else {
10231 cutOffTailIfNeeded(renderState, false);
10232 } // Next we're going to render the tail.
10233
10234 } else {
10235 // Append the rendered row to the child list.
10236 if (!didSuspendAlready) {
10237 var _suspended = findFirstSuspended(renderedTail);
10238
10239 if (_suspended !== null) {
10240 workInProgress.effectTag |= DidCapture;
10241 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
10242 // get lost if this row ends up dropped during a second pass.
10243
10244 var _newThennables = _suspended.updateQueue;
10245
10246 if (_newThennables !== null) {
10247 workInProgress.updateQueue = _newThennables;
10248 workInProgress.effectTag |= Update;
10249 }
10250
10251 cutOffTailIfNeeded(renderState, true); // This might have been modified.
10252
10253 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {
10254 // We need to delete the row we just rendered.
10255 // Reset the effect list to what it was before we rendered this
10256 // child. The nested children have already appended themselves.
10257 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
10258
10259 if (lastEffect !== null) {
10260 lastEffect.nextEffect = null;
10261 } // We're done.
10262
10263
10264 return null;
10265 }
10266 } else if ( // The time it took to render last row is greater than time until
10267 // the expiration.
10268 now() * 2 - renderState.renderingStartTime > renderState.tailExpiration && renderExpirationTime > Never) {
10269 // We have now passed our CPU deadline and we'll just give up further
10270 // attempts to render the main content and only render fallbacks.
10271 // The assumption is that this is usually faster.
10272 workInProgress.effectTag |= DidCapture;
10273 didSuspendAlready = true;
10274 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
10275 // to get it started back up to attempt the next item. If we can show
10276 // them, then they really have the same priority as this render.
10277 // So we'll pick it back up the very next render pass once we've had
10278 // an opportunity to yield for paint.
10279
10280 var nextPriority = renderExpirationTime - 1;
10281 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
10282
10283 {
10284 markSpawnedWork(nextPriority);
10285 }
10286 }
10287 }
10288
10289 if (renderState.isBackwards) {
10290 // The effect list of the backwards tail will have been added
10291 // to the end. This breaks the guarantee that life-cycles fire in
10292 // sibling order but that isn't a strong guarantee promised by React.
10293 // Especially since these might also just pop in during future commits.
10294 // Append to the beginning of the list.
10295 renderedTail.sibling = workInProgress.child;
10296 workInProgress.child = renderedTail;
10297 } else {
10298 var previousSibling = renderState.last;
10299
10300 if (previousSibling !== null) {
10301 previousSibling.sibling = renderedTail;
10302 } else {
10303 workInProgress.child = renderedTail;
10304 }
10305
10306 renderState.last = renderedTail;
10307 }
10308 }
10309
10310 if (renderState.tail !== null) {
10311 // We still have tail rows to render.
10312 if (renderState.tailExpiration === 0) {
10313 // Heuristic for how long we're willing to spend rendering rows
10314 // until we just give up and show what we have so far.
10315 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
10316 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this
10317 // is a per component value. It should really be since the start
10318 // of the total render or last commit. Consider using something like
10319 // globalMostRecentFallbackTime. That doesn't account for being
10320 // suspended for part of the time or when it's a new render.
10321 // It should probably use a global start time value instead.
10322 } // Pop a row.
10323
10324
10325 var next = renderState.tail;
10326 renderState.rendering = next;
10327 renderState.tail = next.sibling;
10328 renderState.lastEffect = workInProgress.lastEffect;
10329 renderState.renderingStartTime = now();
10330 next.sibling = null; // Restore the context.
10331 // TODO: We can probably just avoid popping it instead and only
10332 // setting it the first time we go from not suspended to suspended.
10333
10334 var suspenseContext = suspenseStackCursor.current;
10335
10336 if (didSuspendAlready) {
10337 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
10338 } else {
10339 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10340 }
10341
10342 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
10343
10344 return next;
10345 }
10346
10347 return null;
10348 }
10349 }
10350
10351 {
10352 {
10353 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
10354 }
10355 }
10356 }
10357
10358 function unwindWork(workInProgress, renderExpirationTime) {
10359 switch (workInProgress.tag) {
10360 case ClassComponent:
10361 {
10362 var Component = workInProgress.type;
10363
10364 if (isContextProvider(Component)) {
10365 popContext(workInProgress);
10366 }
10367
10368 var effectTag = workInProgress.effectTag;
10369
10370 if (effectTag & ShouldCapture) {
10371 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10372 return workInProgress;
10373 }
10374
10375 return null;
10376 }
10377
10378 case HostRoot:
10379 {
10380 popHostContainer(workInProgress);
10381 popTopLevelContextObject(workInProgress);
10382 var _effectTag = workInProgress.effectTag;
10383
10384 if (!((_effectTag & DidCapture) === NoEffect)) {
10385 {
10386 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
10387 }
10388 }
10389
10390 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10391 return workInProgress;
10392 }
10393
10394 case HostComponent:
10395 {
10396 // TODO: popHydrationState
10397 popHostContext(workInProgress);
10398 return null;
10399 }
10400
10401 case SuspenseComponent:
10402 {
10403 popSuspenseContext(workInProgress);
10404
10405 var _effectTag2 = workInProgress.effectTag;
10406
10407 if (_effectTag2 & ShouldCapture) {
10408 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
10409
10410 return workInProgress;
10411 }
10412
10413 return null;
10414 }
10415
10416 case SuspenseListComponent:
10417 {
10418 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
10419 // caught by a nested boundary. If not, it should bubble through.
10420
10421 return null;
10422 }
10423
10424 case HostPortal:
10425 popHostContainer(workInProgress);
10426 return null;
10427
10428 case ContextProvider:
10429 popProvider(workInProgress);
10430 return null;
10431
10432 default:
10433 return null;
10434 }
10435 }
10436
10437 function unwindInterruptedWork(interruptedWork) {
10438 switch (interruptedWork.tag) {
10439 case ClassComponent:
10440 {
10441 var childContextTypes = interruptedWork.type.childContextTypes;
10442
10443 if (childContextTypes !== null && childContextTypes !== undefined) {
10444 popContext(interruptedWork);
10445 }
10446
10447 break;
10448 }
10449
10450 case HostRoot:
10451 {
10452 popHostContainer(interruptedWork);
10453 popTopLevelContextObject(interruptedWork);
10454 break;
10455 }
10456
10457 case HostComponent:
10458 {
10459 popHostContext(interruptedWork);
10460 break;
10461 }
10462
10463 case HostPortal:
10464 popHostContainer(interruptedWork);
10465 break;
10466
10467 case SuspenseComponent:
10468 popSuspenseContext(interruptedWork);
10469 break;
10470
10471 case SuspenseListComponent:
10472 popSuspenseContext(interruptedWork);
10473 break;
10474
10475 case ContextProvider:
10476 popProvider(interruptedWork);
10477 break;
10478 }
10479 }
10480
10481 function createCapturedValue(value, source) {
10482 // If the value is an error, call this function immediately after it is thrown
10483 // so the stack is accurate.
10484 return {
10485 value: value,
10486 source: source,
10487 stack: getStackByFiberInDevAndProd(source)
10488 };
10489 }
10490
10491 var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
10492 var funcArgs = Array.prototype.slice.call(arguments, 3);
10493
10494 try {
10495 func.apply(context, funcArgs);
10496 } catch (error) {
10497 this.onError(error);
10498 }
10499 };
10500
10501 {
10502 // In DEV mode, we swap out invokeGuardedCallback for a special version
10503 // that plays more nicely with the browser's DevTools. The idea is to preserve
10504 // "Pause on exceptions" behavior. Because React wraps all user-provided
10505 // functions in invokeGuardedCallback, and the production version of
10506 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
10507 // like caught exceptions, and the DevTools won't pause unless the developer
10508 // takes the extra step of enabling pause on caught exceptions. This is
10509 // unintuitive, though, because even though React has caught the error, from
10510 // the developer's perspective, the error is uncaught.
10511 //
10512 // To preserve the expected "Pause on exceptions" behavior, we don't use a
10513 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
10514 // DOM node, and call the user-provided callback from inside an event handler
10515 // for that fake event. If the callback throws, the error is "captured" using
10516 // a global event handler. But because the error happens in a different
10517 // event loop context, it does not interrupt the normal program flow.
10518 // Effectively, this gives us try-catch behavior without actually using
10519 // try-catch. Neat!
10520 // Check that the browser supports the APIs we need to implement our special
10521 // DEV version of invokeGuardedCallback
10522 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
10523 var fakeNode = document.createElement('react');
10524
10525 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
10526 // If document doesn't exist we know for sure we will crash in this method
10527 // when we call document.createEvent(). However this can cause confusing
10528 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
10529 // So we preemptively throw with a better message instead.
10530 if (!(typeof document !== 'undefined')) {
10531 {
10532 throw Error( "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." );
10533 }
10534 }
10535
10536 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
10537 // set this to true at the beginning, then set it to false right after
10538 // calling the function. If the function errors, `didError` will never be
10539 // set to false. This strategy works even if the browser is flaky and
10540 // fails to call our global error handler, because it doesn't rely on
10541 // the error event at all.
10542
10543 var didError = true; // Keeps track of the value of window.event so that we can reset it
10544 // during the callback to let user code access window.event in the
10545 // browsers that support it.
10546
10547 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
10548 // dispatching: https://github.com/facebook/react/issues/13688
10549
10550 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
10551 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
10552 // call the user-provided callback.
10553
10554 var funcArgs = Array.prototype.slice.call(arguments, 3);
10555
10556 function callCallback() {
10557 // We immediately remove the callback from event listeners so that
10558 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
10559 // nested call would trigger the fake event handlers of any call higher
10560 // in the stack.
10561 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
10562 // window.event assignment in both IE <= 10 as they throw an error
10563 // "Member not found" in strict mode, and in Firefox which does not
10564 // support window.event.
10565
10566 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
10567 window.event = windowEvent;
10568 }
10569
10570 func.apply(context, funcArgs);
10571 didError = false;
10572 } // Create a global error event handler. We use this to capture the value
10573 // that was thrown. It's possible that this error handler will fire more
10574 // than once; for example, if non-React code also calls `dispatchEvent`
10575 // and a handler for that event throws. We should be resilient to most of
10576 // those cases. Even if our error event handler fires more than once, the
10577 // last error event is always used. If the callback actually does error,
10578 // we know that the last error event is the correct one, because it's not
10579 // possible for anything else to have happened in between our callback
10580 // erroring and the code that follows the `dispatchEvent` call below. If
10581 // the callback doesn't error, but the error event was fired, we know to
10582 // ignore it because `didError` will be false, as described above.
10583
10584
10585 var error; // Use this to track whether the error event is ever called.
10586
10587 var didSetError = false;
10588 var isCrossOriginError = false;
10589
10590 function handleWindowError(event) {
10591 error = event.error;
10592 didSetError = true;
10593
10594 if (error === null && event.colno === 0 && event.lineno === 0) {
10595 isCrossOriginError = true;
10596 }
10597
10598 if (event.defaultPrevented) {
10599 // Some other error handler has prevented default.
10600 // Browsers silence the error report if this happens.
10601 // We'll remember this to later decide whether to log it or not.
10602 if (error != null && typeof error === 'object') {
10603 try {
10604 error._suppressLogging = true;
10605 } catch (inner) {// Ignore.
10606 }
10607 }
10608 }
10609 } // Create a fake event type.
10610
10611
10612 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
10613
10614 window.addEventListener('error', handleWindowError);
10615 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
10616 // errors, it will trigger our global error handler.
10617
10618 evt.initEvent(evtType, false, false);
10619 fakeNode.dispatchEvent(evt);
10620
10621 if (windowEventDescriptor) {
10622 Object.defineProperty(window, 'event', windowEventDescriptor);
10623 }
10624
10625 if (didError) {
10626 if (!didSetError) {
10627 // The callback errored, but the error event never fired.
10628 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.');
10629 } else if (isCrossOriginError) {
10630 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.');
10631 }
10632
10633 this.onError(error);
10634 } // Remove our event listeners
10635
10636
10637 window.removeEventListener('error', handleWindowError);
10638 };
10639
10640 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
10641 }
10642 }
10643
10644 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
10645
10646 var hasError = false;
10647 var caughtError = null; // Used by event system to capture/rethrow the first error.
10648 var reporter = {
10649 onError: function (error) {
10650 hasError = true;
10651 caughtError = error;
10652 }
10653 };
10654 /**
10655 * Call a function while guarding against errors that happens within it.
10656 * Returns an error if it throws, otherwise null.
10657 *
10658 * In production, this is implemented using a try-catch. The reason we don't
10659 * use a try-catch directly is so that we can swap out a different
10660 * implementation in DEV mode.
10661 *
10662 * @param {String} name of the guard to use for logging or debugging
10663 * @param {Function} func The function to invoke
10664 * @param {*} context The context to use when calling the function
10665 * @param {...*} args Arguments for function
10666 */
10667
10668 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
10669 hasError = false;
10670 caughtError = null;
10671 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
10672 }
10673 function hasCaughtError() {
10674 return hasError;
10675 }
10676 function clearCaughtError() {
10677 if (hasError) {
10678 var error = caughtError;
10679 hasError = false;
10680 caughtError = null;
10681 return error;
10682 } else {
10683 {
10684 {
10685 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
10686 }
10687 }
10688 }
10689 }
10690
10691 function logCapturedError(capturedError) {
10692
10693 var error = capturedError.error;
10694
10695 {
10696 var componentName = capturedError.componentName,
10697 componentStack = capturedError.componentStack,
10698 errorBoundaryName = capturedError.errorBoundaryName,
10699 errorBoundaryFound = capturedError.errorBoundaryFound,
10700 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
10701 // `preventDefault()` in window `error` handler.
10702 // We record this information as an expando on the error.
10703
10704 if (error != null && error._suppressLogging) {
10705 if (errorBoundaryFound && willRetry) {
10706 // The error is recoverable and was silenced.
10707 // Ignore it and don't print the stack addendum.
10708 // This is handy for testing error boundaries without noise.
10709 return;
10710 } // The error is fatal. Since the silencing might have
10711 // been accidental, we'll surface it anyway.
10712 // However, the browser would have silenced the original error
10713 // so we'll print it first, and then print the stack addendum.
10714
10715
10716 console['error'](error); // Don't transform to our wrapper
10717 // For a more detailed description of this block, see:
10718 // https://github.com/facebook/react/pull/13384
10719 }
10720
10721 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
10722 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10723
10724 if (errorBoundaryFound && errorBoundaryName) {
10725 if (willRetry) {
10726 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
10727 } else {
10728 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
10729 }
10730 } else {
10731 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.';
10732 }
10733
10734 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
10735 // We don't include the original error message and JS stack because the browser
10736 // has already printed it. Even if the application swallows the error, it is still
10737 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10738
10739 console['error'](combinedMessage); // Don't transform to our wrapper
10740 }
10741 }
10742
10743 var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
10744
10745 {
10746 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
10747 }
10748
10749 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
10750 function logError(boundary, errorInfo) {
10751 var source = errorInfo.source;
10752 var stack = errorInfo.stack;
10753
10754 if (stack === null && source !== null) {
10755 stack = getStackByFiberInDevAndProd(source);
10756 }
10757
10758 var capturedError = {
10759 componentName: source !== null ? getComponentName(source.type) : null,
10760 componentStack: stack !== null ? stack : '',
10761 error: errorInfo.value,
10762 errorBoundary: null,
10763 errorBoundaryName: null,
10764 errorBoundaryFound: false,
10765 willRetry: false
10766 };
10767
10768 if (boundary !== null && boundary.tag === ClassComponent) {
10769 capturedError.errorBoundary = boundary.stateNode;
10770 capturedError.errorBoundaryName = getComponentName(boundary.type);
10771 capturedError.errorBoundaryFound = true;
10772 capturedError.willRetry = true;
10773 }
10774
10775 try {
10776 logCapturedError(capturedError);
10777 } catch (e) {
10778 // This method must not throw, or React internal state will get messed up.
10779 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
10780 // we want to report this error outside of the normal stack as a last resort.
10781 // https://github.com/facebook/react/issues/13188
10782 setTimeout(function () {
10783 throw e;
10784 });
10785 }
10786 }
10787
10788 var callComponentWillUnmountWithTimer = function (current, instance) {
10789 startPhaseTimer(current, 'componentWillUnmount');
10790 instance.props = current.memoizedProps;
10791 instance.state = current.memoizedState;
10792 instance.componentWillUnmount();
10793 stopPhaseTimer();
10794 }; // Capture errors so they don't interrupt unmounting.
10795
10796
10797 function safelyCallComponentWillUnmount(current, instance) {
10798 {
10799 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
10800
10801 if (hasCaughtError()) {
10802 var unmountError = clearCaughtError();
10803 captureCommitPhaseError(current, unmountError);
10804 }
10805 }
10806 }
10807
10808 function safelyDetachRef(current) {
10809 var ref = current.ref;
10810
10811 if (ref !== null) {
10812 if (typeof ref === 'function') {
10813 {
10814 invokeGuardedCallback(null, ref, null, null);
10815
10816 if (hasCaughtError()) {
10817 var refError = clearCaughtError();
10818 captureCommitPhaseError(current, refError);
10819 }
10820 }
10821 } else {
10822 ref.current = null;
10823 }
10824 }
10825 }
10826
10827 function safelyCallDestroy(current, destroy) {
10828 {
10829 invokeGuardedCallback(null, destroy, null);
10830
10831 if (hasCaughtError()) {
10832 var error = clearCaughtError();
10833 captureCommitPhaseError(current, error);
10834 }
10835 }
10836 }
10837
10838 function commitBeforeMutationLifeCycles(current, finishedWork) {
10839 switch (finishedWork.tag) {
10840 case FunctionComponent:
10841 case ForwardRef:
10842 case SimpleMemoComponent:
10843 case Block:
10844 {
10845 return;
10846 }
10847
10848 case ClassComponent:
10849 {
10850 if (finishedWork.effectTag & Snapshot) {
10851 if (current !== null) {
10852 var prevProps = current.memoizedProps;
10853 var prevState = current.memoizedState;
10854 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
10855 var instance = finishedWork.stateNode; // We could update instance props and state here,
10856 // but instead we rely on them being set during last render.
10857 // TODO: revisit this when we implement resuming.
10858
10859 {
10860 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10861 if (instance.props !== finishedWork.memoizedProps) {
10862 error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
10863 }
10864
10865 if (instance.state !== finishedWork.memoizedState) {
10866 error('Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
10867 }
10868 }
10869 }
10870
10871 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
10872
10873 {
10874 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
10875
10876 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
10877 didWarnSet.add(finishedWork.type);
10878
10879 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
10880 }
10881 }
10882
10883 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
10884 stopPhaseTimer();
10885 }
10886 }
10887
10888 return;
10889 }
10890
10891 case HostRoot:
10892 case HostComponent:
10893 case HostText:
10894 case HostPortal:
10895 case IncompleteClassComponent:
10896 // Nothing to do for these component types
10897 return;
10898 }
10899
10900 {
10901 {
10902 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
10903 }
10904 }
10905 }
10906
10907 function commitHookEffectListUnmount(tag, finishedWork) {
10908 var updateQueue = finishedWork.updateQueue;
10909 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10910
10911 if (lastEffect !== null) {
10912 var firstEffect = lastEffect.next;
10913 var effect = firstEffect;
10914
10915 do {
10916 if ((effect.tag & tag) === tag) {
10917 // Unmount
10918 var destroy = effect.destroy;
10919 effect.destroy = undefined;
10920
10921 if (destroy !== undefined) {
10922 destroy();
10923 }
10924 }
10925
10926 effect = effect.next;
10927 } while (effect !== firstEffect);
10928 }
10929 }
10930
10931 function commitHookEffectListMount(tag, finishedWork) {
10932 var updateQueue = finishedWork.updateQueue;
10933 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10934
10935 if (lastEffect !== null) {
10936 var firstEffect = lastEffect.next;
10937 var effect = firstEffect;
10938
10939 do {
10940 if ((effect.tag & tag) === tag) {
10941 // Mount
10942 var create = effect.create;
10943 effect.destroy = create();
10944
10945 {
10946 var destroy = effect.destroy;
10947
10948 if (destroy !== undefined && typeof destroy !== 'function') {
10949 var addendum = void 0;
10950
10951 if (destroy === null) {
10952 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
10953 } else if (typeof destroy.then === 'function') {
10954 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';
10955 } else {
10956 addendum = ' You returned: ' + destroy;
10957 }
10958
10959 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
10960 }
10961 }
10962 }
10963
10964 effect = effect.next;
10965 } while (effect !== firstEffect);
10966 }
10967 }
10968
10969 function commitPassiveHookEffects(finishedWork) {
10970 if ((finishedWork.effectTag & Passive) !== NoEffect) {
10971 switch (finishedWork.tag) {
10972 case FunctionComponent:
10973 case ForwardRef:
10974 case SimpleMemoComponent:
10975 case Block:
10976 {
10977 // TODO (#17945) We should call all passive destroy functions (for all fibers)
10978 // before calling any create functions. The current approach only serializes
10979 // these for a single fiber.
10980 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
10981 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
10982 break;
10983 }
10984 }
10985 }
10986 }
10987
10988 function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
10989 switch (finishedWork.tag) {
10990 case FunctionComponent:
10991 case ForwardRef:
10992 case SimpleMemoComponent:
10993 case Block:
10994 {
10995 // At this point layout effects have already been destroyed (during mutation phase).
10996 // This is done to prevent sibling component effects from interfering with each other,
10997 // e.g. a destroy function in one component should never override a ref set
10998 // by a create function in another component during the same commit.
10999 commitHookEffectListMount(Layout | HasEffect, finishedWork);
11000
11001 return;
11002 }
11003
11004 case ClassComponent:
11005 {
11006 var instance = finishedWork.stateNode;
11007
11008 if (finishedWork.effectTag & Update) {
11009 if (current === null) {
11010 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
11011 // but instead we rely on them being set during last render.
11012 // TODO: revisit this when we implement resuming.
11013
11014 {
11015 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11016 if (instance.props !== finishedWork.memoizedProps) {
11017 error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11018 }
11019
11020 if (instance.state !== finishedWork.memoizedState) {
11021 error('Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11022 }
11023 }
11024 }
11025
11026 instance.componentDidMount();
11027 stopPhaseTimer();
11028 } else {
11029 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
11030 var prevState = current.memoizedState;
11031 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
11032 // but instead we rely on them being set during last render.
11033 // TODO: revisit this when we implement resuming.
11034
11035 {
11036 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11037 if (instance.props !== finishedWork.memoizedProps) {
11038 error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11039 }
11040
11041 if (instance.state !== finishedWork.memoizedState) {
11042 error('Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11043 }
11044 }
11045 }
11046
11047 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
11048 stopPhaseTimer();
11049 }
11050 }
11051
11052 var updateQueue = finishedWork.updateQueue;
11053
11054 if (updateQueue !== null) {
11055 {
11056 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11057 if (instance.props !== finishedWork.memoizedProps) {
11058 error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11059 }
11060
11061 if (instance.state !== finishedWork.memoizedState) {
11062 error('Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11063 }
11064 }
11065 } // We could update instance props and state here,
11066 // but instead we rely on them being set during last render.
11067 // TODO: revisit this when we implement resuming.
11068
11069
11070 commitUpdateQueue(finishedWork, updateQueue, instance);
11071 }
11072
11073 return;
11074 }
11075
11076 case HostRoot:
11077 {
11078 var _updateQueue = finishedWork.updateQueue;
11079
11080 if (_updateQueue !== null) {
11081 var _instance = null;
11082
11083 if (finishedWork.child !== null) {
11084 switch (finishedWork.child.tag) {
11085 case HostComponent:
11086 _instance = getPublicInstance(finishedWork.child.stateNode);
11087 break;
11088
11089 case ClassComponent:
11090 _instance = finishedWork.child.stateNode;
11091 break;
11092 }
11093 }
11094
11095 commitUpdateQueue(finishedWork, _updateQueue, _instance);
11096 }
11097
11098 return;
11099 }
11100
11101 case HostComponent:
11102 {
11103 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
11104 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
11105 // These effects should only be committed when components are first mounted,
11106 // aka when there is no current/alternate.
11107
11108 if (current === null && finishedWork.effectTag & Update) {
11109 var type = finishedWork.type;
11110 var props = finishedWork.memoizedProps;
11111 }
11112
11113 return;
11114 }
11115
11116 case HostText:
11117 {
11118 // We have no life-cycles associated with text.
11119 return;
11120 }
11121
11122 case HostPortal:
11123 {
11124 // We have no life-cycles associated with portals.
11125 return;
11126 }
11127
11128 case Profiler:
11129 {
11130 {
11131 var onRender = finishedWork.memoizedProps.onRender;
11132
11133 if (typeof onRender === 'function') {
11134 {
11135 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
11136 }
11137 }
11138 }
11139
11140 return;
11141 }
11142
11143 case SuspenseComponent:
11144 {
11145 return;
11146 }
11147
11148 case SuspenseListComponent:
11149 case IncompleteClassComponent:
11150 case FundamentalComponent:
11151 case ScopeComponent:
11152 return;
11153 }
11154
11155 {
11156 {
11157 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
11158 }
11159 }
11160 }
11161
11162 function hideOrUnhideAllChildren(finishedWork, isHidden) {
11163 {
11164 // We only have the top Fiber that was inserted but we need to recurse down its
11165 // children to find all the terminal nodes.
11166 var node = finishedWork;
11167
11168 while (true) {
11169 if (node.tag === HostComponent) {
11170 var instance = node.stateNode;
11171
11172 if (isHidden) {
11173 hideInstance(instance);
11174 } else {
11175 unhideInstance(node.stateNode, node.memoizedProps);
11176 }
11177 } else if (node.tag === HostText) {
11178 var _instance3 = node.stateNode;
11179
11180 if (isHidden) ; else {
11181 unhideTextInstance(_instance3, node.memoizedProps);
11182 }
11183 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
11184 // Found a nested Suspense component that timed out. Skip over the
11185 // primary child fragment, which should remain hidden.
11186 var fallbackChildFragment = node.child.sibling;
11187 fallbackChildFragment.return = node;
11188 node = fallbackChildFragment;
11189 continue;
11190 } else if (node.child !== null) {
11191 node.child.return = node;
11192 node = node.child;
11193 continue;
11194 }
11195
11196 if (node === finishedWork) {
11197 return;
11198 }
11199
11200 while (node.sibling === null) {
11201 if (node.return === null || node.return === finishedWork) {
11202 return;
11203 }
11204
11205 node = node.return;
11206 }
11207
11208 node.sibling.return = node.return;
11209 node = node.sibling;
11210 }
11211 }
11212 }
11213
11214 function commitAttachRef(finishedWork) {
11215 var ref = finishedWork.ref;
11216
11217 if (ref !== null) {
11218 var instance = finishedWork.stateNode;
11219 var instanceToUse;
11220
11221 switch (finishedWork.tag) {
11222 case HostComponent:
11223 instanceToUse = getPublicInstance(instance);
11224 break;
11225
11226 default:
11227 instanceToUse = instance;
11228 } // Moved outside to ensure DCE works with this flag
11229
11230 if (typeof ref === 'function') {
11231 ref(instanceToUse);
11232 } else {
11233 {
11234 if (!ref.hasOwnProperty('current')) {
11235 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
11236 }
11237 }
11238
11239 ref.current = instanceToUse;
11240 }
11241 }
11242 }
11243
11244 function commitDetachRef(current) {
11245 var currentRef = current.ref;
11246
11247 if (currentRef !== null) {
11248 if (typeof currentRef === 'function') {
11249 currentRef(null);
11250 } else {
11251 currentRef.current = null;
11252 }
11253 }
11254 } // User-originating errors (lifecycles and refs) should not interrupt
11255 // deletion, so don't let them throw. Host-originating errors should
11256 // interrupt deletion, so it's okay
11257
11258
11259 function commitUnmount(finishedRoot, current, renderPriorityLevel) {
11260 onCommitUnmount(current);
11261
11262 switch (current.tag) {
11263 case FunctionComponent:
11264 case ForwardRef:
11265 case MemoComponent:
11266 case SimpleMemoComponent:
11267 case Block:
11268 {
11269 var updateQueue = current.updateQueue;
11270
11271 if (updateQueue !== null) {
11272 var lastEffect = updateQueue.lastEffect;
11273
11274 if (lastEffect !== null) {
11275 var firstEffect = lastEffect.next;
11276
11277 {
11278 // When the owner fiber is deleted, the destroy function of a passive
11279 // effect hook is called during the synchronous commit phase. This is
11280 // a concession to implementation complexity. Calling it in the
11281 // passive effect phase (like they usually are, when dependencies
11282 // change during an update) would require either traversing the
11283 // children of the deleted fiber again, or including unmount effects
11284 // as part of the fiber effect list.
11285 //
11286 // Because this is during the sync commit phase, we need to change
11287 // the priority.
11288 //
11289 // TODO: Reconsider this implementation trade off.
11290 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
11291 runWithPriority(priorityLevel, function () {
11292 var effect = firstEffect;
11293
11294 do {
11295 var _destroy = effect.destroy;
11296
11297 if (_destroy !== undefined) {
11298 safelyCallDestroy(current, _destroy);
11299 }
11300
11301 effect = effect.next;
11302 } while (effect !== firstEffect);
11303 });
11304 }
11305 }
11306 }
11307
11308 return;
11309 }
11310
11311 case ClassComponent:
11312 {
11313 safelyDetachRef(current);
11314 var instance = current.stateNode;
11315
11316 if (typeof instance.componentWillUnmount === 'function') {
11317 safelyCallComponentWillUnmount(current, instance);
11318 }
11319
11320 return;
11321 }
11322
11323 case HostComponent:
11324 {
11325
11326 safelyDetachRef(current);
11327 return;
11328 }
11329
11330 case HostPortal:
11331 {
11332 // TODO: this is recursive.
11333 // We are also not using this parent because
11334 // the portal will get pushed immediately.
11335 {
11336 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
11337 }
11338
11339 return;
11340 }
11341
11342 case FundamentalComponent:
11343 {
11344
11345 return;
11346 }
11347
11348 case DehydratedFragment:
11349 {
11350
11351 return;
11352 }
11353
11354 case ScopeComponent:
11355 {
11356
11357 return;
11358 }
11359 }
11360 }
11361
11362 function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
11363 // While we're inside a removed host node we don't want to call
11364 // removeChild on the inner nodes because they're removed by the top
11365 // call anyway. We also want to call componentWillUnmount on all
11366 // composites before this host node is removed from the tree. Therefore
11367 // we do an inner loop while we're still inside the host node.
11368 var node = root;
11369
11370 while (true) {
11371 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
11372 // Skip portals because commitUnmount() currently visits them recursively.
11373
11374 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
11375 // If we don't use mutation we drill down into portals here instead.
11376 node.tag !== HostPortal)) {
11377 node.child.return = node;
11378 node = node.child;
11379 continue;
11380 }
11381
11382 if (node === root) {
11383 return;
11384 }
11385
11386 while (node.sibling === null) {
11387 if (node.return === null || node.return === root) {
11388 return;
11389 }
11390
11391 node = node.return;
11392 }
11393
11394 node.sibling.return = node.return;
11395 node = node.sibling;
11396 }
11397 }
11398
11399 function detachFiber(current) {
11400 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
11401 // should clear the child pointer of the parent alternate to let this
11402 // get GC:ed but we don't know which for sure which parent is the current
11403 // one so we'll settle for GC:ing the subtree of this child. This child
11404 // itself will be GC:ed when the parent updates the next time.
11405
11406 current.return = null;
11407 current.child = null;
11408 current.memoizedState = null;
11409 current.updateQueue = null;
11410 current.dependencies = null;
11411 current.alternate = null;
11412 current.firstEffect = null;
11413 current.lastEffect = null;
11414 current.pendingProps = null;
11415 current.memoizedProps = null;
11416 current.stateNode = null;
11417
11418 if (alternate !== null) {
11419 detachFiber(alternate);
11420 }
11421 }
11422
11423 function getHostParentFiber(fiber) {
11424 var parent = fiber.return;
11425
11426 while (parent !== null) {
11427 if (isHostParent(parent)) {
11428 return parent;
11429 }
11430
11431 parent = parent.return;
11432 }
11433
11434 {
11435 {
11436 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
11437 }
11438 }
11439 }
11440
11441 function isHostParent(fiber) {
11442 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
11443 }
11444
11445 function getHostSibling(fiber) {
11446 // We're going to search forward into the tree until we find a sibling host
11447 // node. Unfortunately, if multiple insertions are done in a row we have to
11448 // search past them. This leads to exponential search for the next sibling.
11449 // TODO: Find a more efficient way to do this.
11450 var node = fiber;
11451
11452 siblings: while (true) {
11453 // If we didn't find anything, let's try the next sibling.
11454 while (node.sibling === null) {
11455 if (node.return === null || isHostParent(node.return)) {
11456 // If we pop out of the root or hit the parent the fiber we are the
11457 // last sibling.
11458 return null;
11459 }
11460
11461 node = node.return;
11462 }
11463
11464 node.sibling.return = node.return;
11465 node = node.sibling;
11466
11467 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
11468 // If it is not host node and, we might have a host node inside it.
11469 // Try to search down until we find one.
11470 if (node.effectTag & Placement) {
11471 // If we don't have a child, try the siblings instead.
11472 continue siblings;
11473 } // If we don't have a child, try the siblings instead.
11474 // We also skip portals because they are not part of this host tree.
11475
11476
11477 if (node.child === null || node.tag === HostPortal) {
11478 continue siblings;
11479 } else {
11480 node.child.return = node;
11481 node = node.child;
11482 }
11483 } // Check if this host node is stable or about to be placed.
11484
11485
11486 if (!(node.effectTag & Placement)) {
11487 // Found it!
11488 return node.stateNode;
11489 }
11490 }
11491 }
11492
11493 function commitPlacement(finishedWork) {
11494
11495
11496 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
11497
11498 var parent;
11499 var isContainer;
11500 var parentStateNode = parentFiber.stateNode;
11501
11502 switch (parentFiber.tag) {
11503 case HostComponent:
11504 parent = parentStateNode;
11505 isContainer = false;
11506 break;
11507
11508 case HostRoot:
11509 parent = parentStateNode.containerInfo;
11510 isContainer = true;
11511 break;
11512
11513 case HostPortal:
11514 parent = parentStateNode.containerInfo;
11515 isContainer = true;
11516 break;
11517
11518 case FundamentalComponent:
11519
11520 // eslint-disable-next-line-no-fallthrough
11521
11522 default:
11523 {
11524 {
11525 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
11526 }
11527 }
11528
11529 }
11530
11531 if (parentFiber.effectTag & ContentReset) {
11532
11533 parentFiber.effectTag &= ~ContentReset;
11534 }
11535
11536 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
11537 // children to find all the terminal nodes.
11538
11539 if (isContainer) {
11540 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
11541 } else {
11542 insertOrAppendPlacementNode(finishedWork, before, parent);
11543 }
11544 }
11545
11546 function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
11547 var tag = node.tag;
11548 var isHost = tag === HostComponent || tag === HostText;
11549
11550 if (isHost || enableFundamentalAPI ) {
11551 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
11552
11553 if (before) {
11554 insertInContainerBefore(parent, stateNode, before);
11555 } else {
11556 appendChildToContainer(parent, stateNode);
11557 }
11558 } else if (tag === HostPortal) ; else {
11559 var child = node.child;
11560
11561 if (child !== null) {
11562 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
11563 var sibling = child.sibling;
11564
11565 while (sibling !== null) {
11566 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
11567 sibling = sibling.sibling;
11568 }
11569 }
11570 }
11571 }
11572
11573 function insertOrAppendPlacementNode(node, before, parent) {
11574 var tag = node.tag;
11575 var isHost = tag === HostComponent || tag === HostText;
11576
11577 if (isHost || enableFundamentalAPI ) {
11578 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
11579
11580 if (before) {
11581 insertBefore(parent, stateNode, before);
11582 } else {
11583 appendChild(parent, stateNode);
11584 }
11585 } else if (tag === HostPortal) ; else {
11586 var child = node.child;
11587
11588 if (child !== null) {
11589 insertOrAppendPlacementNode(child, before, parent);
11590 var sibling = child.sibling;
11591
11592 while (sibling !== null) {
11593 insertOrAppendPlacementNode(sibling, before, parent);
11594 sibling = sibling.sibling;
11595 }
11596 }
11597 }
11598 }
11599
11600 function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
11601 // We only have the top Fiber that was deleted but we need to recurse down its
11602 // children to find all the terminal nodes.
11603 var node = current; // Each iteration, currentParent is populated with node's host parent if not
11604 // currentParentIsValid.
11605
11606 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
11607
11608 var currentParent;
11609 var currentParentIsContainer;
11610
11611 while (true) {
11612 if (!currentParentIsValid) {
11613 var parent = node.return;
11614
11615 findParent: while (true) {
11616 if (!(parent !== null)) {
11617 {
11618 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
11619 }
11620 }
11621
11622 var parentStateNode = parent.stateNode;
11623
11624 switch (parent.tag) {
11625 case HostComponent:
11626 currentParent = parentStateNode;
11627 currentParentIsContainer = false;
11628 break findParent;
11629
11630 case HostRoot:
11631 currentParent = parentStateNode.containerInfo;
11632 currentParentIsContainer = true;
11633 break findParent;
11634
11635 case HostPortal:
11636 currentParent = parentStateNode.containerInfo;
11637 currentParentIsContainer = true;
11638 break findParent;
11639
11640 }
11641
11642 parent = parent.return;
11643 }
11644
11645 currentParentIsValid = true;
11646 }
11647
11648 if (node.tag === HostComponent || node.tag === HostText) {
11649 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
11650 // node from the tree.
11651
11652 if (currentParentIsContainer) {
11653 removeChildFromContainer(currentParent, node.stateNode);
11654 } else {
11655 removeChild(currentParent, node.stateNode);
11656 } // Don't visit children because we already visited them.
11657
11658 } else if (node.tag === HostPortal) {
11659 if (node.child !== null) {
11660 // When we go into a portal, it becomes the parent to remove from.
11661 // We will reassign it back when we pop the portal on the way up.
11662 currentParent = node.stateNode.containerInfo;
11663 currentParentIsContainer = true; // Visit children because portals might contain host components.
11664
11665 node.child.return = node;
11666 node = node.child;
11667 continue;
11668 }
11669 } else {
11670 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
11671
11672 if (node.child !== null) {
11673 node.child.return = node;
11674 node = node.child;
11675 continue;
11676 }
11677 }
11678
11679 if (node === current) {
11680 return;
11681 }
11682
11683 while (node.sibling === null) {
11684 if (node.return === null || node.return === current) {
11685 return;
11686 }
11687
11688 node = node.return;
11689
11690 if (node.tag === HostPortal) {
11691 // When we go out of the portal, we need to restore the parent.
11692 // Since we don't keep a stack of them, we will search for it.
11693 currentParentIsValid = false;
11694 }
11695 }
11696
11697 node.sibling.return = node.return;
11698 node = node.sibling;
11699 }
11700 }
11701
11702 function commitDeletion(finishedRoot, current, renderPriorityLevel) {
11703 {
11704 // Recursively delete all host nodes from the parent.
11705 // Detach refs and call componentWillUnmount() on the whole subtree.
11706 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
11707 }
11708
11709 detachFiber(current);
11710 }
11711
11712 function commitWork(current, finishedWork) {
11713
11714 switch (finishedWork.tag) {
11715 case FunctionComponent:
11716 case ForwardRef:
11717 case MemoComponent:
11718 case SimpleMemoComponent:
11719 case Block:
11720 {
11721 // Layout effects are destroyed during the mutation phase so that all
11722 // destroy functions for all fibers are called before any create functions.
11723 // This prevents sibling component effects from interfering with each other,
11724 // e.g. a destroy function in one component should never override a ref set
11725 // by a create function in another component during the same commit.
11726 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
11727 return;
11728 }
11729
11730 case ClassComponent:
11731 {
11732 return;
11733 }
11734
11735 case HostComponent:
11736 {
11737 var instance = finishedWork.stateNode;
11738
11739 if (instance != null) {
11740 // Commit the work prepared earlier.
11741 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11742 // as the newProps. The updatePayload will contain the real change in
11743 // this case.
11744
11745 var oldProps = current !== null ? current.memoizedProps : newProps;
11746 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
11747
11748 var updatePayload = finishedWork.updateQueue;
11749 finishedWork.updateQueue = null;
11750
11751 if (updatePayload !== null) {
11752 commitUpdate(instance, updatePayload, type, oldProps, newProps);
11753 }
11754 }
11755
11756 return;
11757 }
11758
11759 case HostText:
11760 {
11761 if (!(finishedWork.stateNode !== null)) {
11762 {
11763 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
11764 }
11765 }
11766
11767 var textInstance = finishedWork.stateNode;
11768 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11769 // as the newProps. The updatePayload will contain the real change in
11770 // this case.
11771
11772 var oldText = current !== null ? current.memoizedProps : newText;
11773 return;
11774 }
11775
11776 case HostRoot:
11777 {
11778
11779 return;
11780 }
11781
11782 case Profiler:
11783 {
11784 return;
11785 }
11786
11787 case SuspenseComponent:
11788 {
11789 commitSuspenseComponent(finishedWork);
11790 attachSuspenseRetryListeners(finishedWork);
11791 return;
11792 }
11793
11794 case SuspenseListComponent:
11795 {
11796 attachSuspenseRetryListeners(finishedWork);
11797 return;
11798 }
11799
11800 case IncompleteClassComponent:
11801 {
11802 return;
11803 }
11804 }
11805
11806 {
11807 {
11808 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
11809 }
11810 }
11811 }
11812
11813 function commitSuspenseComponent(finishedWork) {
11814 var newState = finishedWork.memoizedState;
11815 var newDidTimeout;
11816 var primaryChildParent = finishedWork;
11817
11818 if (newState === null) {
11819 newDidTimeout = false;
11820 } else {
11821 newDidTimeout = true;
11822 primaryChildParent = finishedWork.child;
11823 markCommitTimeOfFallback();
11824 }
11825
11826 if ( primaryChildParent !== null) {
11827 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
11828 }
11829 }
11830
11831 function attachSuspenseRetryListeners(finishedWork) {
11832 // If this boundary just timed out, then it will have a set of thenables.
11833 // For each thenable, attach a listener so that when it resolves, React
11834 // attempts to re-render the boundary in the primary (pre-timeout) state.
11835 var thenables = finishedWork.updateQueue;
11836
11837 if (thenables !== null) {
11838 finishedWork.updateQueue = null;
11839 var retryCache = finishedWork.stateNode;
11840
11841 if (retryCache === null) {
11842 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
11843 }
11844
11845 thenables.forEach(function (thenable) {
11846 // Memoize using the boundary fiber to prevent redundant listeners.
11847 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
11848
11849 if (!retryCache.has(thenable)) {
11850 {
11851 if (thenable.__reactDoNotTraceInteractions !== true) {
11852 retry = unstable_wrap(retry);
11853 }
11854 }
11855
11856 retryCache.add(thenable);
11857 thenable.then(retry, retry);
11858 }
11859 });
11860 }
11861 }
11862
11863 function commitResetTextContent(current) {
11864
11865 resetTextContent(current.stateNode);
11866 }
11867
11868 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
11869
11870 function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
11871 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
11872
11873 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
11874 // being called "element".
11875
11876 update.payload = {
11877 element: null
11878 };
11879 var error = errorInfo.value;
11880
11881 update.callback = function () {
11882 onUncaughtError(error);
11883 logError(fiber, errorInfo);
11884 };
11885
11886 return update;
11887 }
11888
11889 function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
11890 var update = createUpdate(expirationTime, null);
11891 update.tag = CaptureUpdate;
11892 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
11893
11894 if (typeof getDerivedStateFromError === 'function') {
11895 var error$1 = errorInfo.value;
11896
11897 update.payload = function () {
11898 logError(fiber, errorInfo);
11899 return getDerivedStateFromError(error$1);
11900 };
11901 }
11902
11903 var inst = fiber.stateNode;
11904
11905 if (inst !== null && typeof inst.componentDidCatch === 'function') {
11906 update.callback = function callback() {
11907 {
11908 markFailedErrorBoundaryForHotReloading(fiber);
11909 }
11910
11911 if (typeof getDerivedStateFromError !== 'function') {
11912 // To preserve the preexisting retry behavior of error boundaries,
11913 // we keep track of which ones already failed during this batch.
11914 // This gets reset before we yield back to the browser.
11915 // TODO: Warn in strict mode if getDerivedStateFromError is
11916 // not defined.
11917 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
11918
11919 logError(fiber, errorInfo);
11920 }
11921
11922 var error$1 = errorInfo.value;
11923 var stack = errorInfo.stack;
11924 this.componentDidCatch(error$1, {
11925 componentStack: stack !== null ? stack : ''
11926 });
11927
11928 {
11929 if (typeof getDerivedStateFromError !== 'function') {
11930 // If componentDidCatch is the only error boundary method defined,
11931 // then it needs to call setState to recover from errors.
11932 // If no state update is scheduled then the boundary will swallow the error.
11933 if (fiber.expirationTime !== Sync) {
11934 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown');
11935 }
11936 }
11937 }
11938 };
11939 } else {
11940 update.callback = function () {
11941 markFailedErrorBoundaryForHotReloading(fiber);
11942 };
11943 }
11944
11945 return update;
11946 }
11947
11948 function attachPingListener(root, renderExpirationTime, thenable) {
11949 // Attach a listener to the promise to "ping" the root and retry. But
11950 // only if one does not already exist for the current render expiration
11951 // time (which acts like a "thread ID" here).
11952 var pingCache = root.pingCache;
11953 var threadIDs;
11954
11955 if (pingCache === null) {
11956 pingCache = root.pingCache = new PossiblyWeakMap();
11957 threadIDs = new Set();
11958 pingCache.set(thenable, threadIDs);
11959 } else {
11960 threadIDs = pingCache.get(thenable);
11961
11962 if (threadIDs === undefined) {
11963 threadIDs = new Set();
11964 pingCache.set(thenable, threadIDs);
11965 }
11966 }
11967
11968 if (!threadIDs.has(renderExpirationTime)) {
11969 // Memoize using the thread ID to prevent redundant listeners.
11970 threadIDs.add(renderExpirationTime);
11971 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
11972 thenable.then(ping, ping);
11973 }
11974 }
11975
11976 function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
11977 // The source fiber did not complete.
11978 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
11979
11980 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
11981
11982 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
11983 // This is a thenable.
11984 var thenable = value;
11985
11986 if ((sourceFiber.mode & BlockingMode) === NoMode) {
11987 // Reset the memoizedState to what it was before we attempted
11988 // to render it.
11989 var currentSource = sourceFiber.alternate;
11990
11991 if (currentSource) {
11992 sourceFiber.memoizedState = currentSource.memoizedState;
11993 sourceFiber.expirationTime = currentSource.expirationTime;
11994 } else {
11995 sourceFiber.memoizedState = null;
11996 }
11997 }
11998
11999 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
12000
12001 var _workInProgress = returnFiber;
12002
12003 do {
12004 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
12005 // Found the nearest boundary.
12006 // Stash the promise on the boundary fiber. If the boundary times out, we'll
12007 // attach another listener to flip the boundary back to its normal state.
12008 var thenables = _workInProgress.updateQueue;
12009
12010 if (thenables === null) {
12011 var updateQueue = new Set();
12012 updateQueue.add(thenable);
12013 _workInProgress.updateQueue = updateQueue;
12014 } else {
12015 thenables.add(thenable);
12016 } // If the boundary is outside of blocking mode, we should *not*
12017 // suspend the commit. Pretend as if the suspended component rendered
12018 // null and keep rendering. In the commit phase, we'll schedule a
12019 // subsequent synchronous update to re-render the Suspense.
12020 //
12021 // Note: It doesn't matter whether the component that suspended was
12022 // inside a blocking mode tree. If the Suspense is outside of it, we
12023 // should *not* suspend the commit.
12024
12025
12026 if ((_workInProgress.mode & BlockingMode) === NoMode) {
12027 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
12028 // But we shouldn't call any lifecycle methods or callbacks. Remove
12029 // all lifecycle effect tags.
12030
12031 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
12032
12033 if (sourceFiber.tag === ClassComponent) {
12034 var currentSourceFiber = sourceFiber.alternate;
12035
12036 if (currentSourceFiber === null) {
12037 // This is a new mount. Change the tag so it's not mistaken for a
12038 // completed class component. For example, we should not call
12039 // componentWillUnmount if it is deleted.
12040 sourceFiber.tag = IncompleteClassComponent;
12041 } else {
12042 // When we try rendering again, we should not reuse the current fiber,
12043 // since it's known to be in an inconsistent state. Use a force update to
12044 // prevent a bail out.
12045 var update = createUpdate(Sync, null);
12046 update.tag = ForceUpdate;
12047 enqueueUpdate(sourceFiber, update);
12048 }
12049 } // The source fiber did not complete. Mark it with Sync priority to
12050 // indicate that it still has pending work.
12051
12052
12053 sourceFiber.expirationTime = Sync; // Exit without suspending.
12054
12055 return;
12056 } // Confirmed that the boundary is in a concurrent mode tree. Continue
12057 // with the normal suspend path.
12058 //
12059 // After this we'll use a set of heuristics to determine whether this
12060 // render pass will run to completion or restart or "suspend" the commit.
12061 // The actual logic for this is spread out in different places.
12062 //
12063 // This first principle is that if we're going to suspend when we complete
12064 // a root, then we should also restart if we get an update or ping that
12065 // might unsuspend it, and vice versa. The only reason to suspend is
12066 // because you think you might want to restart before committing. However,
12067 // it doesn't make sense to restart only while in the period we're suspended.
12068 //
12069 // Restarting too aggressively is also not good because it starves out any
12070 // intermediate loading state. So we use heuristics to determine when.
12071 // Suspense Heuristics
12072 //
12073 // If nothing threw a Promise or all the same fallbacks are already showing,
12074 // then don't suspend/restart.
12075 //
12076 // If this is an initial render of a new tree of Suspense boundaries and
12077 // those trigger a fallback, then don't suspend/restart. We want to ensure
12078 // that we can show the initial loading state as quickly as possible.
12079 //
12080 // If we hit a "Delayed" case, such as when we'd switch from content back into
12081 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
12082 // this case. If none is defined, JND is used instead.
12083 //
12084 // If we're already showing a fallback and it gets "retried", allowing us to show
12085 // another level, but there's still an inner boundary that would show a fallback,
12086 // then we suspend/restart for 500ms since the last time we showed a fallback
12087 // anywhere in the tree. This effectively throttles progressive loading into a
12088 // consistent train of commits. This also gives us an opportunity to restart to
12089 // get to the completed state slightly earlier.
12090 //
12091 // If there's ambiguity due to batching it's resolved in preference of:
12092 // 1) "delayed", 2) "initial render", 3) "retry".
12093 //
12094 // We want to ensure that a "busy" state doesn't get force committed. We want to
12095 // ensure that new initial loading states can commit as soon as possible.
12096
12097
12098 attachPingListener(root, renderExpirationTime, thenable);
12099 _workInProgress.effectTag |= ShouldCapture;
12100 _workInProgress.expirationTime = renderExpirationTime;
12101 return;
12102 } // This boundary already captured during this render. Continue to the next
12103 // boundary.
12104
12105
12106 _workInProgress = _workInProgress.return;
12107 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
12108 // TODO: Use invariant so the message is stripped in prod?
12109
12110
12111 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));
12112 } // We didn't find a boundary that could handle this type of exception. Start
12113 // over and traverse parent path again, this time treating the exception
12114 // as an error.
12115
12116
12117 renderDidError();
12118 value = createCapturedValue(value, sourceFiber);
12119 var workInProgress = returnFiber;
12120
12121 do {
12122 switch (workInProgress.tag) {
12123 case HostRoot:
12124 {
12125 var _errorInfo = value;
12126 workInProgress.effectTag |= ShouldCapture;
12127 workInProgress.expirationTime = renderExpirationTime;
12128
12129 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
12130
12131 enqueueCapturedUpdate(workInProgress, _update);
12132 return;
12133 }
12134
12135 case ClassComponent:
12136 // Capture and retry
12137 var errorInfo = value;
12138 var ctor = workInProgress.type;
12139 var instance = workInProgress.stateNode;
12140
12141 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
12142 workInProgress.effectTag |= ShouldCapture;
12143 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
12144
12145 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
12146
12147 enqueueCapturedUpdate(workInProgress, _update2);
12148 return;
12149 }
12150
12151 break;
12152 }
12153
12154 workInProgress = workInProgress.return;
12155 } while (workInProgress !== null);
12156 }
12157
12158 var ceil = Math.ceil;
12159 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
12160 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
12161 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
12162 var NoContext =
12163 /* */
12164 0;
12165 var BatchedContext =
12166 /* */
12167 1;
12168 var DiscreteEventContext =
12169 /* */
12170 4;
12171 var LegacyUnbatchedContext =
12172 /* */
12173 8;
12174 var RenderContext =
12175 /* */
12176 16;
12177 var CommitContext =
12178 /* */
12179 32;
12180 var RootIncomplete = 0;
12181 var RootFatalErrored = 1;
12182 var RootErrored = 2;
12183 var RootSuspended = 3;
12184 var RootSuspendedWithDelay = 4;
12185 var RootCompleted = 5;
12186 // Describes where we are in the React execution stack
12187 var executionContext = NoContext; // The root we're working on
12188
12189 var workInProgressRoot = null; // The fiber we're working on
12190
12191 var workInProgress = null; // The expiration time we're rendering
12192
12193 var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc.
12194
12195 var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
12196
12197 var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
12198 // This is conceptually a time stamp but expressed in terms of an ExpirationTime
12199 // because we deal mostly with expiration times in the hot path, so this avoids
12200 // the conversion happening in the hot path.
12201
12202 var workInProgressRootLatestProcessedExpirationTime = Sync;
12203 var workInProgressRootLatestSuspenseTimeout = Sync;
12204 var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
12205 // includes unprocessed updates, not work in bailed out children.
12206
12207 var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
12208 // This flag determines if it might be worthwhile to restart if an opportunity
12209 // happens latere.
12210
12211 var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
12212 // model where we don't commit new loading states in too quick succession.
12213
12214 var globalMostRecentFallbackTime = 0;
12215 var FALLBACK_THROTTLE_MS = 500;
12216 var nextEffect = null;
12217 var hasUncaughtError = false;
12218 var firstUncaughtError = null;
12219 var legacyErrorBoundariesThatAlreadyFailed = null;
12220 var rootDoesHavePassiveEffects = false;
12221 var rootWithPendingPassiveEffects = null;
12222 var pendingPassiveEffectsRenderPriority = NoPriority;
12223 var pendingPassiveEffectsExpirationTime = NoWork;
12224 var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
12225
12226 var NESTED_UPDATE_LIMIT = 50;
12227 var nestedUpdateCount = 0;
12228 var rootWithNestedUpdates = null;
12229 var NESTED_PASSIVE_UPDATE_LIMIT = 50;
12230 var nestedPassiveUpdateCount = 0;
12231 var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
12232 // during the commit phase. This enables them to be traced across components
12233 // that spawn new work during render. E.g. hidden boundaries, suspended SSR
12234 // hydration or SuspenseList.
12235
12236 var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
12237 // time). However, if two updates are scheduled within the same event, we
12238 // should treat their start times as simultaneous, even if the actual clock
12239 // time has advanced between the first and second call.
12240 // In other words, because expiration times determine how updates are batched,
12241 // we want all updates of like priority that occur within the same event to
12242 // receive the same expiration time. Otherwise we get tearing.
12243
12244 var currentEventTime = NoWork;
12245 function requestCurrentTimeForUpdate() {
12246 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12247 // We're inside React, so it's fine to read the actual time.
12248 return msToExpirationTime(now());
12249 } // We're not inside React, so we may be in the middle of a browser event.
12250
12251
12252 if (currentEventTime !== NoWork) {
12253 // Use the same start time for all updates until we enter React again.
12254 return currentEventTime;
12255 } // This is the first update since React yielded. Compute a new start time.
12256
12257
12258 currentEventTime = msToExpirationTime(now());
12259 return currentEventTime;
12260 }
12261 function getCurrentTime() {
12262 return msToExpirationTime(now());
12263 }
12264 function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
12265 var mode = fiber.mode;
12266
12267 if ((mode & BlockingMode) === NoMode) {
12268 return Sync;
12269 }
12270
12271 var priorityLevel = getCurrentPriorityLevel();
12272
12273 if ((mode & ConcurrentMode) === NoMode) {
12274 return priorityLevel === ImmediatePriority ? Sync : Batched;
12275 }
12276
12277 if ((executionContext & RenderContext) !== NoContext) {
12278 // Use whatever time we're already rendering
12279 // TODO: Should there be a way to opt out, like with `runWithPriority`?
12280 return renderExpirationTime$1;
12281 }
12282
12283 var expirationTime;
12284
12285 if (suspenseConfig !== null) {
12286 // Compute an expiration time based on the Suspense timeout.
12287 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
12288 } else {
12289 // Compute an expiration time based on the Scheduler priority.
12290 switch (priorityLevel) {
12291 case ImmediatePriority:
12292 expirationTime = Sync;
12293 break;
12294
12295 case UserBlockingPriority:
12296 // TODO: Rename this to computeUserBlockingExpiration
12297 expirationTime = computeInteractiveExpiration(currentTime);
12298 break;
12299
12300 case NormalPriority:
12301 case LowPriority:
12302 // TODO: Handle LowPriority
12303 // TODO: Rename this to... something better.
12304 expirationTime = computeAsyncExpiration(currentTime);
12305 break;
12306
12307 case IdlePriority:
12308 expirationTime = Idle;
12309 break;
12310
12311 default:
12312 {
12313 {
12314 throw Error( "Expected a valid priority level" );
12315 }
12316 }
12317
12318 }
12319 } // If we're in the middle of rendering a tree, do not update at the same
12320 // expiration time that is already rendering.
12321 // TODO: We shouldn't have to do this if the update is on a different root.
12322 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
12323 // the root when we check for this condition.
12324
12325
12326 if (workInProgressRoot !== null && expirationTime === renderExpirationTime$1) {
12327 // This is a trick to move this update into a separate batch
12328 expirationTime -= 1;
12329 }
12330
12331 return expirationTime;
12332 }
12333 function scheduleUpdateOnFiber(fiber, expirationTime) {
12334 checkForNestedUpdates();
12335 warnAboutRenderPhaseUpdatesInDEV(fiber);
12336 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
12337
12338 if (root === null) {
12339 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
12340 return;
12341 }
12342
12343 checkForInterruption(fiber, expirationTime);
12344 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
12345 // priority as an argument to that function and this one.
12346
12347 var priorityLevel = getCurrentPriorityLevel();
12348
12349 if (expirationTime === Sync) {
12350 if ( // Check if we're inside unbatchedUpdates
12351 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
12352 (executionContext & (RenderContext | CommitContext)) === NoContext) {
12353 // Register pending interactions on the root to avoid losing traced interaction data.
12354 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
12355 // root inside of batchedUpdates should be synchronous, but layout updates
12356 // should be deferred until the end of the batch.
12357
12358 performSyncWorkOnRoot(root);
12359 } else {
12360 ensureRootIsScheduled(root);
12361 schedulePendingInteractions(root, expirationTime);
12362
12363 if (executionContext === NoContext) {
12364 // Flush the synchronous work now, unless we're already working or inside
12365 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
12366 // scheduleCallbackForFiber to preserve the ability to schedule a callback
12367 // without immediately flushing it. We only do this for user-initiated
12368 // updates, to preserve historical behavior of legacy mode.
12369 flushSyncCallbackQueue();
12370 }
12371 }
12372 } else {
12373 ensureRootIsScheduled(root);
12374 schedulePendingInteractions(root, expirationTime);
12375 }
12376
12377 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
12378 // discrete, even inside a discrete event.
12379 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
12380 // This is the result of a discrete event. Track the lowest priority
12381 // discrete update per root so we can flush them early, if needed.
12382 if (rootsWithPendingDiscreteUpdates === null) {
12383 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
12384 } else {
12385 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
12386
12387 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
12388 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
12389 }
12390 }
12391 }
12392 }
12393 var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
12394 // work without treating it as a typical update that originates from an event;
12395 // e.g. retrying a Suspense boundary isn't an update, but it does schedule work
12396 // on a fiber.
12397
12398 function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
12399 // Update the source fiber's expiration time
12400 if (fiber.expirationTime < expirationTime) {
12401 fiber.expirationTime = expirationTime;
12402 }
12403
12404 var alternate = fiber.alternate;
12405
12406 if (alternate !== null && alternate.expirationTime < expirationTime) {
12407 alternate.expirationTime = expirationTime;
12408 } // Walk the parent path to the root and update the child expiration time.
12409
12410
12411 var node = fiber.return;
12412 var root = null;
12413
12414 if (node === null && fiber.tag === HostRoot) {
12415 root = fiber.stateNode;
12416 } else {
12417 while (node !== null) {
12418 alternate = node.alternate;
12419
12420 if (node.childExpirationTime < expirationTime) {
12421 node.childExpirationTime = expirationTime;
12422
12423 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12424 alternate.childExpirationTime = expirationTime;
12425 }
12426 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12427 alternate.childExpirationTime = expirationTime;
12428 }
12429
12430 if (node.return === null && node.tag === HostRoot) {
12431 root = node.stateNode;
12432 break;
12433 }
12434
12435 node = node.return;
12436 }
12437 }
12438
12439 if (root !== null) {
12440 if (workInProgressRoot === root) {
12441 // Received an update to a tree that's in the middle of rendering. Mark
12442 // that's unprocessed work on this root.
12443 markUnprocessedUpdateTime(expirationTime);
12444
12445 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
12446 // The root already suspended with a delay, which means this render
12447 // definitely won't finish. Since we have a new update, let's mark it as
12448 // suspended now, right before marking the incoming update. This has the
12449 // effect of interrupting the current render and switching to the update.
12450 // TODO: This happens to work when receiving an update during the render
12451 // phase, because of the trick inside computeExpirationForFiber to
12452 // subtract 1 from `renderExpirationTime` to move it into a
12453 // separate bucket. But we should probably model it with an exception,
12454 // using the same mechanism we use to force hydration of a subtree.
12455 // TODO: This does not account for low pri updates that were already
12456 // scheduled before the root started rendering. Need to track the next
12457 // pending expiration time (perhaps by backtracking the return path) and
12458 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
12459 markRootSuspendedAtTime(root, renderExpirationTime$1);
12460 }
12461 } // Mark that the root has a pending update.
12462
12463
12464 markRootUpdatedAtTime(root, expirationTime);
12465 }
12466
12467 return root;
12468 }
12469
12470 function getNextRootExpirationTimeToWorkOn(root) {
12471 // Determines the next expiration time that the root should render, taking
12472 // into account levels that may be suspended, or levels that may have
12473 // received a ping.
12474 var lastExpiredTime = root.lastExpiredTime;
12475
12476 if (lastExpiredTime !== NoWork) {
12477 return lastExpiredTime;
12478 } // "Pending" refers to any update that hasn't committed yet, including if it
12479 // suspended. The "suspended" range is therefore a subset.
12480
12481
12482 var firstPendingTime = root.firstPendingTime;
12483
12484 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
12485 // The highest priority pending time is not suspended. Let's work on that.
12486 return firstPendingTime;
12487 } // If the first pending time is suspended, check if there's a lower priority
12488 // pending level that we know about. Or check if we received a ping. Work
12489 // on whichever is higher priority.
12490
12491
12492 var lastPingedTime = root.lastPingedTime;
12493 var nextKnownPendingLevel = root.nextKnownPendingLevel;
12494 var nextLevel = lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
12495
12496 if ( nextLevel <= Idle && firstPendingTime !== nextLevel) {
12497 // Don't work on Idle/Never priority unless everything else is committed.
12498 return NoWork;
12499 }
12500
12501 return nextLevel;
12502 } // Use this function to schedule a task for a root. There's only one task per
12503 // root; if a task was already scheduled, we'll check to make sure the
12504 // expiration time of the existing task is the same as the expiration time of
12505 // the next level that the root has work on. This function is called on every
12506 // update, and right before exiting a task.
12507
12508
12509 function ensureRootIsScheduled(root) {
12510 var lastExpiredTime = root.lastExpiredTime;
12511
12512 if (lastExpiredTime !== NoWork) {
12513 // Special case: Expired work should flush synchronously.
12514 root.callbackExpirationTime = Sync;
12515 root.callbackPriority = ImmediatePriority;
12516 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
12517 return;
12518 }
12519
12520 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
12521 var existingCallbackNode = root.callbackNode;
12522
12523 if (expirationTime === NoWork) {
12524 // There's nothing to work on.
12525 if (existingCallbackNode !== null) {
12526 root.callbackNode = null;
12527 root.callbackExpirationTime = NoWork;
12528 root.callbackPriority = NoPriority;
12529 }
12530
12531 return;
12532 } // TODO: If this is an update, we already read the current time. Pass the
12533 // time as an argument.
12534
12535
12536 var currentTime = requestCurrentTimeForUpdate();
12537 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
12538 // expiration time. Otherwise, we'll cancel it and schedule a new one.
12539
12540 if (existingCallbackNode !== null) {
12541 var existingCallbackPriority = root.callbackPriority;
12542 var existingCallbackExpirationTime = root.callbackExpirationTime;
12543
12544 if ( // Callback must have the exact same expiration time.
12545 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
12546 existingCallbackPriority >= priorityLevel) {
12547 // Existing callback is sufficient.
12548 return;
12549 } // Need to schedule a new task.
12550 // TODO: Instead of scheduling a new task, we should be able to change the
12551 // priority of the existing one.
12552
12553
12554 cancelCallback(existingCallbackNode);
12555 }
12556
12557 root.callbackExpirationTime = expirationTime;
12558 root.callbackPriority = priorityLevel;
12559 var callbackNode;
12560
12561 if (expirationTime === Sync) {
12562 // Sync React callbacks are scheduled on a special internal queue
12563 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
12564 } else {
12565 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
12566 // ordering because tasks are processed in timeout order.
12567 {
12568 timeout: expirationTimeToMs(expirationTime) - now()
12569 });
12570 }
12571
12572 root.callbackNode = callbackNode;
12573 } // This is the entry point for every concurrent task, i.e. anything that
12574 // goes through Scheduler.
12575
12576
12577 function performConcurrentWorkOnRoot(root, didTimeout) {
12578 // Since we know we're in a React event, we can clear the current
12579 // event time. The next update will compute a new event time.
12580 currentEventTime = NoWork;
12581
12582 if (didTimeout) {
12583 // The render task took too long to complete. Mark the current time as
12584 // expired to synchronously render all expired work in a single batch.
12585 var currentTime = requestCurrentTimeForUpdate();
12586 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
12587
12588 ensureRootIsScheduled(root);
12589 return null;
12590 } // Determine the next expiration time to work on, using the fields stored
12591 // on the root.
12592
12593
12594 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
12595
12596 if (expirationTime !== NoWork) {
12597 var originalCallbackNode = root.callbackNode;
12598
12599 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12600 {
12601 throw Error( "Should not already be working." );
12602 }
12603 }
12604
12605 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12606 // and prepare a fresh one. Otherwise we'll continue where we left off.
12607
12608 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12609 prepareFreshStack(root, expirationTime);
12610 startWorkOnPendingInteractions(root, expirationTime);
12611 } // If we have a work-in-progress fiber, it means there's still work to do
12612 // in this root.
12613
12614
12615 if (workInProgress !== null) {
12616 var prevExecutionContext = executionContext;
12617 executionContext |= RenderContext;
12618 var prevDispatcher = pushDispatcher();
12619 var prevInteractions = pushInteractions(root);
12620 startWorkLoopTimer(workInProgress);
12621
12622 do {
12623 try {
12624 workLoopConcurrent();
12625 break;
12626 } catch (thrownValue) {
12627 handleError(root, thrownValue);
12628 }
12629 } while (true);
12630
12631 resetContextDependencies();
12632 executionContext = prevExecutionContext;
12633 popDispatcher(prevDispatcher);
12634
12635 {
12636 popInteractions(prevInteractions);
12637 }
12638
12639 if (workInProgressRootExitStatus === RootFatalErrored) {
12640 var fatalError = workInProgressRootFatalError;
12641 stopInterruptedWorkLoopTimer();
12642 prepareFreshStack(root, expirationTime);
12643 markRootSuspendedAtTime(root, expirationTime);
12644 ensureRootIsScheduled(root);
12645 throw fatalError;
12646 }
12647
12648 if (workInProgress !== null) {
12649 // There's still work left over. Exit without committing.
12650 stopInterruptedWorkLoopTimer();
12651 } else {
12652 // We now have a consistent tree. The next step is either to commit it,
12653 // or, if something suspended, wait to commit it after a timeout.
12654 stopFinishedWorkLoopTimer();
12655 var finishedWork = root.finishedWork = root.current.alternate;
12656 root.finishedExpirationTime = expirationTime;
12657 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
12658 }
12659
12660 ensureRootIsScheduled(root);
12661
12662 if (root.callbackNode === originalCallbackNode) {
12663 // The task node scheduled for this root is the same one that's
12664 // currently executed. Need to return a continuation.
12665 return performConcurrentWorkOnRoot.bind(null, root);
12666 }
12667 }
12668 }
12669
12670 return null;
12671 }
12672
12673 function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
12674 // Set this to null to indicate there's no in-progress render.
12675 workInProgressRoot = null;
12676
12677 switch (exitStatus) {
12678 case RootIncomplete:
12679 case RootFatalErrored:
12680 {
12681 {
12682 {
12683 throw Error( "Root did not complete. This is a bug in React." );
12684 }
12685 }
12686 }
12687 // Flow knows about invariant, so it complains if I add a break
12688 // statement, but eslint doesn't know about invariant, so it complains
12689 // if I do. eslint-disable-next-line no-fallthrough
12690
12691 case RootErrored:
12692 {
12693 // If this was an async render, the error may have happened due to
12694 // a mutation in a concurrent event. Try rendering one more time,
12695 // synchronously, to see if the error goes away. If there are
12696 // lower priority updates, let's include those, too, in case they
12697 // fix the inconsistency. Render at Idle to include all updates.
12698 // If it was Idle or Never or some not-yet-invented time, render
12699 // at that time.
12700 markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous
12701 // and therefore not hit this path again.
12702
12703 break;
12704 }
12705
12706 case RootSuspended:
12707 {
12708 markRootSuspendedAtTime(root, expirationTime);
12709 var lastSuspendedTime = root.lastSuspendedTime;
12710
12711 if (expirationTime === lastSuspendedTime) {
12712 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12713 } // We have an acceptable loading state. We need to figure out if we
12714 // should immediately commit it or wait a bit.
12715 // If we have processed new updates during this render, we may now
12716 // have a new loading state ready. We want to ensure that we commit
12717 // that as soon as possible.
12718
12719
12720 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
12721
12722 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
12723 !( IsThisRendererActing.current)) {
12724 // If we have not processed any new updates during this pass, then
12725 // this is either a retry of an existing fallback state or a
12726 // hidden tree. Hidden trees shouldn't be batched with other work
12727 // and after that's fixed it can only be a retry. We're going to
12728 // throttle committing retries so that we don't show too many
12729 // loading states too quickly.
12730 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
12731
12732 if (msUntilTimeout > 10) {
12733 if (workInProgressRootHasPendingPing) {
12734 var lastPingedTime = root.lastPingedTime;
12735
12736 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
12737 // This render was pinged but we didn't get to restart
12738 // earlier so try restarting now instead.
12739 root.lastPingedTime = expirationTime;
12740 prepareFreshStack(root, expirationTime);
12741 break;
12742 }
12743 }
12744
12745 var nextTime = getNextRootExpirationTimeToWorkOn(root);
12746
12747 if (nextTime !== NoWork && nextTime !== expirationTime) {
12748 // There's additional work on this root.
12749 break;
12750 }
12751
12752 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
12753 // We should prefer to render the fallback of at the last
12754 // suspended level. Ping the last suspended level to try
12755 // rendering it again.
12756 root.lastPingedTime = lastSuspendedTime;
12757 break;
12758 } // The render is suspended, it hasn't timed out, and there's no
12759 // lower priority work to do. Instead of committing the fallback
12760 // immediately, wait for more data to arrive.
12761
12762
12763 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
12764 break;
12765 }
12766 } // The work expired. Commit immediately.
12767
12768
12769 commitRoot(root);
12770 break;
12771 }
12772
12773 case RootSuspendedWithDelay:
12774 {
12775 markRootSuspendedAtTime(root, expirationTime);
12776 var _lastSuspendedTime = root.lastSuspendedTime;
12777
12778 if (expirationTime === _lastSuspendedTime) {
12779 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12780 }
12781
12782 {
12783 // We're suspended in a state that should be avoided. We'll try to
12784 // avoid committing it for as long as the timeouts let us.
12785 if (workInProgressRootHasPendingPing) {
12786 var _lastPingedTime = root.lastPingedTime;
12787
12788 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
12789 // This render was pinged but we didn't get to restart earlier
12790 // so try restarting now instead.
12791 root.lastPingedTime = expirationTime;
12792 prepareFreshStack(root, expirationTime);
12793 break;
12794 }
12795 }
12796
12797 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
12798
12799 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
12800 // There's additional work on this root.
12801 break;
12802 }
12803
12804 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
12805 // We should prefer to render the fallback of at the last
12806 // suspended level. Ping the last suspended level to try
12807 // rendering it again.
12808 root.lastPingedTime = _lastSuspendedTime;
12809 break;
12810 }
12811
12812 var _msUntilTimeout;
12813
12814 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
12815 // We have processed a suspense config whose expiration time we
12816 // can use as the timeout.
12817 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
12818 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
12819 // This should never normally happen because only new updates
12820 // cause delayed states, so we should have processed something.
12821 // However, this could also happen in an offscreen tree.
12822 _msUntilTimeout = 0;
12823 } else {
12824 // If we don't have a suspense config, we're going to use a
12825 // heuristic to determine how long we can suspend.
12826 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
12827 var currentTimeMs = now();
12828 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
12829 var timeElapsed = currentTimeMs - eventTimeMs;
12830
12831 if (timeElapsed < 0) {
12832 // We get this wrong some time since we estimate the time.
12833 timeElapsed = 0;
12834 }
12835
12836 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
12837 // event time is exact instead of inferred from expiration time
12838 // we don't need this.
12839
12840 if (timeUntilExpirationMs < _msUntilTimeout) {
12841 _msUntilTimeout = timeUntilExpirationMs;
12842 }
12843 } // Don't bother with a very short suspense time.
12844
12845
12846 if (_msUntilTimeout > 10) {
12847 // The render is suspended, it hasn't timed out, and there's no
12848 // lower priority work to do. Instead of committing the fallback
12849 // immediately, wait for more data to arrive.
12850 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
12851 break;
12852 }
12853 } // The work expired. Commit immediately.
12854
12855
12856 commitRoot(root);
12857 break;
12858 }
12859
12860 case RootCompleted:
12861 {
12862 // The work completed. Ready to commit.
12863 if ( // do not delay if we're inside an act() scope
12864 workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
12865 // If we have exceeded the minimum loading delay, which probably
12866 // means we have shown a spinner already, we might have to suspend
12867 // a bit longer to ensure that the spinner is shown for
12868 // enough time.
12869 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
12870
12871 if (_msUntilTimeout2 > 10) {
12872 markRootSuspendedAtTime(root, expirationTime);
12873 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
12874 break;
12875 }
12876 }
12877
12878 commitRoot(root);
12879 break;
12880 }
12881
12882 default:
12883 {
12884 {
12885 {
12886 throw Error( "Unknown root exit status." );
12887 }
12888 }
12889 }
12890 }
12891 } // This is the entry point for synchronous tasks that don't go
12892 // through Scheduler
12893
12894
12895 function performSyncWorkOnRoot(root) {
12896 // Check if there's expired work on this root. Otherwise, render at Sync.
12897 var lastExpiredTime = root.lastExpiredTime;
12898 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
12899
12900 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12901 {
12902 throw Error( "Should not already be working." );
12903 }
12904 }
12905
12906 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12907 // and prepare a fresh one. Otherwise we'll continue where we left off.
12908
12909 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12910 prepareFreshStack(root, expirationTime);
12911 startWorkOnPendingInteractions(root, expirationTime);
12912 } // If we have a work-in-progress fiber, it means there's still work to do
12913 // in this root.
12914
12915
12916 if (workInProgress !== null) {
12917 var prevExecutionContext = executionContext;
12918 executionContext |= RenderContext;
12919 var prevDispatcher = pushDispatcher();
12920 var prevInteractions = pushInteractions(root);
12921 startWorkLoopTimer(workInProgress);
12922
12923 do {
12924 try {
12925 workLoopSync();
12926 break;
12927 } catch (thrownValue) {
12928 handleError(root, thrownValue);
12929 }
12930 } while (true);
12931
12932 resetContextDependencies();
12933 executionContext = prevExecutionContext;
12934 popDispatcher(prevDispatcher);
12935
12936 {
12937 popInteractions(prevInteractions);
12938 }
12939
12940 if (workInProgressRootExitStatus === RootFatalErrored) {
12941 var fatalError = workInProgressRootFatalError;
12942 stopInterruptedWorkLoopTimer();
12943 prepareFreshStack(root, expirationTime);
12944 markRootSuspendedAtTime(root, expirationTime);
12945 ensureRootIsScheduled(root);
12946 throw fatalError;
12947 }
12948
12949 if (workInProgress !== null) {
12950 // This is a sync render, so we should have finished the whole tree.
12951 {
12952 {
12953 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
12954 }
12955 }
12956 } else {
12957 // We now have a consistent tree. Because this is a sync render, we
12958 // will commit it even if something suspended.
12959 stopFinishedWorkLoopTimer();
12960 root.finishedWork = root.current.alternate;
12961 root.finishedExpirationTime = expirationTime;
12962 finishSyncRender(root);
12963 } // Before exiting, make sure there's a callback scheduled for the next
12964 // pending level.
12965
12966
12967 ensureRootIsScheduled(root);
12968 }
12969
12970 return null;
12971 }
12972
12973 function finishSyncRender(root) {
12974 // Set this to null to indicate there's no in-progress render.
12975 workInProgressRoot = null;
12976 commitRoot(root);
12977 }
12978 function syncUpdates(fn, a, b, c) {
12979 return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c));
12980 }
12981 function flushSync(fn, a) {
12982 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12983 {
12984 {
12985 throw Error( "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." );
12986 }
12987 }
12988 }
12989
12990 var prevExecutionContext = executionContext;
12991 executionContext |= BatchedContext;
12992
12993 try {
12994 return runWithPriority(ImmediatePriority, fn.bind(null, a));
12995 } finally {
12996 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
12997 // Note that this will happen even if batchedUpdates is higher up
12998 // the stack.
12999
13000 flushSyncCallbackQueue();
13001 }
13002 }
13003
13004 function prepareFreshStack(root, expirationTime) {
13005 root.finishedWork = null;
13006 root.finishedExpirationTime = NoWork;
13007 var timeoutHandle = root.timeoutHandle;
13008
13009 if (timeoutHandle !== noTimeout) {
13010 // The root previous suspended and scheduled a timeout to commit a fallback
13011 // state. Now that we have additional work, cancel the timeout.
13012 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
13013
13014 cancelTimeout(timeoutHandle);
13015 }
13016
13017 if (workInProgress !== null) {
13018 var interruptedWork = workInProgress.return;
13019
13020 while (interruptedWork !== null) {
13021 unwindInterruptedWork(interruptedWork);
13022 interruptedWork = interruptedWork.return;
13023 }
13024 }
13025
13026 workInProgressRoot = root;
13027 workInProgress = createWorkInProgress(root.current, null);
13028 renderExpirationTime$1 = expirationTime;
13029 workInProgressRootExitStatus = RootIncomplete;
13030 workInProgressRootFatalError = null;
13031 workInProgressRootLatestProcessedExpirationTime = Sync;
13032 workInProgressRootLatestSuspenseTimeout = Sync;
13033 workInProgressRootCanSuspendUsingConfig = null;
13034 workInProgressRootNextUnprocessedUpdateTime = NoWork;
13035 workInProgressRootHasPendingPing = false;
13036
13037 {
13038 spawnedWorkDuringRender = null;
13039 }
13040
13041 {
13042 ReactStrictModeWarnings.discardPendingWarnings();
13043 }
13044 }
13045
13046 function handleError(root, thrownValue) {
13047 do {
13048 try {
13049 // Reset module-level state that was set during the render phase.
13050 resetContextDependencies();
13051 resetHooksAfterThrow();
13052 resetCurrentFiber();
13053
13054 if (workInProgress === null || workInProgress.return === null) {
13055 // Expected to be working on a non-root fiber. This is a fatal error
13056 // because there's no ancestor that can handle it; the root is
13057 // supposed to capture all errors that weren't caught by an error
13058 // boundary.
13059 workInProgressRootExitStatus = RootFatalErrored;
13060 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
13061 // sibling, or the parent if there are no siblings. But since the root
13062 // has no siblings nor a parent, we set it to null. Usually this is
13063 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
13064 // interntionally not calling those, we need set it here.
13065 // TODO: Consider calling `unwindWork` to pop the contexts.
13066
13067 workInProgress = null;
13068 return null;
13069 }
13070
13071 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
13072 // Record the time spent rendering before an error was thrown. This
13073 // avoids inaccurate Profiler durations in the case of a
13074 // suspended render.
13075 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
13076 }
13077
13078 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime$1);
13079 workInProgress = completeUnitOfWork(workInProgress);
13080 } catch (yetAnotherThrownValue) {
13081 // Something in the return path also threw.
13082 thrownValue = yetAnotherThrownValue;
13083 continue;
13084 } // Return to the normal work loop.
13085
13086
13087 return;
13088 } while (true);
13089 }
13090
13091 function pushDispatcher(root) {
13092 var prevDispatcher = ReactCurrentDispatcher$1.current;
13093 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
13094
13095 if (prevDispatcher === null) {
13096 // The React isomorphic package does not include a default dispatcher.
13097 // Instead the first renderer will lazily attach one, in order to give
13098 // nicer error messages.
13099 return ContextOnlyDispatcher;
13100 } else {
13101 return prevDispatcher;
13102 }
13103 }
13104
13105 function popDispatcher(prevDispatcher) {
13106 ReactCurrentDispatcher$1.current = prevDispatcher;
13107 }
13108
13109 function pushInteractions(root) {
13110 {
13111 var prevInteractions = __interactionsRef.current;
13112 __interactionsRef.current = root.memoizedInteractions;
13113 return prevInteractions;
13114 }
13115 }
13116
13117 function popInteractions(prevInteractions) {
13118 {
13119 __interactionsRef.current = prevInteractions;
13120 }
13121 }
13122
13123 function markCommitTimeOfFallback() {
13124 globalMostRecentFallbackTime = now();
13125 }
13126 function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
13127 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
13128 workInProgressRootLatestProcessedExpirationTime = expirationTime;
13129 }
13130
13131 if (suspenseConfig !== null) {
13132 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
13133 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
13134
13135 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
13136 }
13137 }
13138 }
13139 function markUnprocessedUpdateTime(expirationTime) {
13140 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
13141 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
13142 }
13143 }
13144 function renderDidSuspend() {
13145 if (workInProgressRootExitStatus === RootIncomplete) {
13146 workInProgressRootExitStatus = RootSuspended;
13147 }
13148 }
13149 function renderDidSuspendDelayIfPossible() {
13150 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
13151 workInProgressRootExitStatus = RootSuspendedWithDelay;
13152 } // Check if there's a lower priority update somewhere else in the tree.
13153
13154
13155 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
13156 // Mark the current render as suspended, and then mark that there's a
13157 // pending update.
13158 // TODO: This should immediately interrupt the current render, instead
13159 // of waiting until the next time we yield.
13160 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1);
13161 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
13162 }
13163 }
13164 function renderDidError() {
13165 if (workInProgressRootExitStatus !== RootCompleted) {
13166 workInProgressRootExitStatus = RootErrored;
13167 }
13168 } // Called during render to determine if anything has suspended.
13169 // Returns false if we're not sure.
13170
13171 function renderHasNotSuspendedYet() {
13172 // If something errored or completed, we can't really be sure,
13173 // so those are false.
13174 return workInProgressRootExitStatus === RootIncomplete;
13175 }
13176
13177 function inferTimeFromExpirationTime(expirationTime) {
13178 // We don't know exactly when the update was scheduled, but we can infer an
13179 // approximate start time from the expiration time.
13180 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
13181 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
13182 }
13183
13184 function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
13185 // We don't know exactly when the update was scheduled, but we can infer an
13186 // approximate start time from the expiration time by subtracting the timeout
13187 // that was added to the event time.
13188 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
13189 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
13190 } // The work loop is an extremely hot path. Tell Closure not to inline it.
13191
13192 /** @noinline */
13193
13194
13195 function workLoopSync() {
13196 // Already timed out, so perform work without checking if we need to yield.
13197 while (workInProgress !== null) {
13198 workInProgress = performUnitOfWork(workInProgress);
13199 }
13200 }
13201 /** @noinline */
13202
13203
13204 function workLoopConcurrent() {
13205 // Perform work until Scheduler asks us to yield
13206 while (workInProgress !== null && !shouldYield()) {
13207 workInProgress = performUnitOfWork(workInProgress);
13208 }
13209 }
13210
13211 function performUnitOfWork(unitOfWork) {
13212 // The current, flushed, state of this fiber is the alternate. Ideally
13213 // nothing should rely on this, but relying on it here means that we don't
13214 // need an additional field on the work in progress.
13215 var current = unitOfWork.alternate;
13216 startWorkTimer(unitOfWork);
13217 setCurrentFiber(unitOfWork);
13218 var next;
13219
13220 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
13221 startProfilerTimer(unitOfWork);
13222 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
13223 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
13224 } else {
13225 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
13226 }
13227
13228 resetCurrentFiber();
13229 unitOfWork.memoizedProps = unitOfWork.pendingProps;
13230
13231 if (next === null) {
13232 // If this doesn't spawn new work, complete the current work.
13233 next = completeUnitOfWork(unitOfWork);
13234 }
13235
13236 ReactCurrentOwner$2.current = null;
13237 return next;
13238 }
13239
13240 function completeUnitOfWork(unitOfWork) {
13241 // Attempt to complete the current unit of work, then move to the next
13242 // sibling. If there are no more siblings, return to the parent fiber.
13243 workInProgress = unitOfWork;
13244
13245 do {
13246 // The current, flushed, state of this fiber is the alternate. Ideally
13247 // nothing should rely on this, but relying on it here means that we don't
13248 // need an additional field on the work in progress.
13249 var current = workInProgress.alternate;
13250 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
13251
13252 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
13253 setCurrentFiber(workInProgress);
13254 var next = void 0;
13255
13256 if ( (workInProgress.mode & ProfileMode) === NoMode) {
13257 next = completeWork(current, workInProgress, renderExpirationTime$1);
13258 } else {
13259 startProfilerTimer(workInProgress);
13260 next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.
13261
13262 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
13263 }
13264
13265 stopWorkTimer(workInProgress);
13266 resetCurrentFiber();
13267 resetChildExpirationTime(workInProgress);
13268
13269 if (next !== null) {
13270 // Completing this fiber spawned new work. Work on that next.
13271 return next;
13272 }
13273
13274 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
13275 (returnFiber.effectTag & Incomplete) === NoEffect) {
13276 // Append all the effects of the subtree and this fiber onto the effect
13277 // list of the parent. The completion order of the children affects the
13278 // side-effect order.
13279 if (returnFiber.firstEffect === null) {
13280 returnFiber.firstEffect = workInProgress.firstEffect;
13281 }
13282
13283 if (workInProgress.lastEffect !== null) {
13284 if (returnFiber.lastEffect !== null) {
13285 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
13286 }
13287
13288 returnFiber.lastEffect = workInProgress.lastEffect;
13289 } // If this fiber had side-effects, we append it AFTER the children's
13290 // side-effects. We can perform certain side-effects earlier if needed,
13291 // by doing multiple passes over the effect list. We don't want to
13292 // schedule our own side-effect on our own list because if end up
13293 // reusing children we'll schedule this effect onto itself since we're
13294 // at the end.
13295
13296
13297 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
13298 // list. PerformedWork effect is read by React DevTools but shouldn't be
13299 // committed.
13300
13301 if (effectTag > PerformedWork) {
13302 if (returnFiber.lastEffect !== null) {
13303 returnFiber.lastEffect.nextEffect = workInProgress;
13304 } else {
13305 returnFiber.firstEffect = workInProgress;
13306 }
13307
13308 returnFiber.lastEffect = workInProgress;
13309 }
13310 }
13311 } else {
13312 // This fiber did not complete because something threw. Pop values off
13313 // the stack without entering the complete phase. If this is a boundary,
13314 // capture values if possible.
13315 var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time.
13316
13317
13318 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
13319 // Record the render duration for the fiber that errored.
13320 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
13321
13322 var actualDuration = workInProgress.actualDuration;
13323 var child = workInProgress.child;
13324
13325 while (child !== null) {
13326 actualDuration += child.actualDuration;
13327 child = child.sibling;
13328 }
13329
13330 workInProgress.actualDuration = actualDuration;
13331 }
13332
13333 if (_next !== null) {
13334 // If completing this work spawned new work, do that next. We'll come
13335 // back here again.
13336 // Since we're restarting, remove anything that is not a host effect
13337 // from the effect tag.
13338 // TODO: The name stopFailedWorkTimer is misleading because Suspense
13339 // also captures and restarts.
13340 stopFailedWorkTimer(workInProgress);
13341 _next.effectTag &= HostEffectMask;
13342 return _next;
13343 }
13344
13345 stopWorkTimer(workInProgress);
13346
13347 if (returnFiber !== null) {
13348 // Mark the parent fiber as incomplete and clear its effect list.
13349 returnFiber.firstEffect = returnFiber.lastEffect = null;
13350 returnFiber.effectTag |= Incomplete;
13351 }
13352 }
13353
13354 var siblingFiber = workInProgress.sibling;
13355
13356 if (siblingFiber !== null) {
13357 // If there is more work to do in this returnFiber, do that next.
13358 return siblingFiber;
13359 } // Otherwise, return to the parent
13360
13361
13362 workInProgress = returnFiber;
13363 } while (workInProgress !== null); // We've reached the root.
13364
13365
13366 if (workInProgressRootExitStatus === RootIncomplete) {
13367 workInProgressRootExitStatus = RootCompleted;
13368 }
13369
13370 return null;
13371 }
13372
13373 function getRemainingExpirationTime(fiber) {
13374 var updateExpirationTime = fiber.expirationTime;
13375 var childExpirationTime = fiber.childExpirationTime;
13376 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
13377 }
13378
13379 function resetChildExpirationTime(completedWork) {
13380 if (renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never) {
13381 // The children of this component are hidden. Don't bubble their
13382 // expiration times.
13383 return;
13384 }
13385
13386 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
13387
13388 if ( (completedWork.mode & ProfileMode) !== NoMode) {
13389 // In profiling mode, resetChildExpirationTime is also used to reset
13390 // profiler durations.
13391 var actualDuration = completedWork.actualDuration;
13392 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
13393 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
13394 // When work is done, it should bubble to the parent's actualDuration. If
13395 // the fiber has not been cloned though, (meaning no work was done), then
13396 // this value will reflect the amount of time spent working on a previous
13397 // render. In that case it should not bubble. We determine whether it was
13398 // cloned by comparing the child pointer.
13399
13400 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
13401 var child = completedWork.child;
13402
13403 while (child !== null) {
13404 var childUpdateExpirationTime = child.expirationTime;
13405 var childChildExpirationTime = child.childExpirationTime;
13406
13407 if (childUpdateExpirationTime > newChildExpirationTime) {
13408 newChildExpirationTime = childUpdateExpirationTime;
13409 }
13410
13411 if (childChildExpirationTime > newChildExpirationTime) {
13412 newChildExpirationTime = childChildExpirationTime;
13413 }
13414
13415 if (shouldBubbleActualDurations) {
13416 actualDuration += child.actualDuration;
13417 }
13418
13419 treeBaseDuration += child.treeBaseDuration;
13420 child = child.sibling;
13421 }
13422
13423 completedWork.actualDuration = actualDuration;
13424 completedWork.treeBaseDuration = treeBaseDuration;
13425 } else {
13426 var _child = completedWork.child;
13427
13428 while (_child !== null) {
13429 var _childUpdateExpirationTime = _child.expirationTime;
13430 var _childChildExpirationTime = _child.childExpirationTime;
13431
13432 if (_childUpdateExpirationTime > newChildExpirationTime) {
13433 newChildExpirationTime = _childUpdateExpirationTime;
13434 }
13435
13436 if (_childChildExpirationTime > newChildExpirationTime) {
13437 newChildExpirationTime = _childChildExpirationTime;
13438 }
13439
13440 _child = _child.sibling;
13441 }
13442 }
13443
13444 completedWork.childExpirationTime = newChildExpirationTime;
13445 }
13446
13447 function commitRoot(root) {
13448 var renderPriorityLevel = getCurrentPriorityLevel();
13449 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
13450 return null;
13451 }
13452
13453 function commitRootImpl(root, renderPriorityLevel) {
13454 do {
13455 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
13456 // means `flushPassiveEffects` will sometimes result in additional
13457 // passive effects. So we need to keep flushing in a loop until there are
13458 // no more pending effects.
13459 // TODO: Might be better if `flushPassiveEffects` did not automatically
13460 // flush synchronous work at the end, to avoid factoring hazards like this.
13461 flushPassiveEffects();
13462 } while (rootWithPendingPassiveEffects !== null);
13463
13464 flushRenderPhaseStrictModeWarningsInDEV();
13465
13466 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13467 {
13468 throw Error( "Should not already be working." );
13469 }
13470 }
13471
13472 var finishedWork = root.finishedWork;
13473 var expirationTime = root.finishedExpirationTime;
13474
13475 if (finishedWork === null) {
13476 return null;
13477 }
13478
13479 root.finishedWork = null;
13480 root.finishedExpirationTime = NoWork;
13481
13482 if (!(finishedWork !== root.current)) {
13483 {
13484 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
13485 }
13486 } // commitRoot never returns a continuation; it always finishes synchronously.
13487 // So we can clear these now to allow a new callback to be scheduled.
13488
13489
13490 root.callbackNode = null;
13491 root.callbackExpirationTime = NoWork;
13492 root.callbackPriority = NoPriority;
13493 root.nextKnownPendingLevel = NoWork;
13494 startCommitTimer(); // Update the first and last pending times on this root. The new first
13495 // pending time is whatever is left on the root fiber.
13496
13497 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
13498 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
13499
13500 if (root === workInProgressRoot) {
13501 // We can reset these now that they are finished.
13502 workInProgressRoot = null;
13503 workInProgress = null;
13504 renderExpirationTime$1 = NoWork;
13505 } // This indicates that the last root we worked on is not the same one that
13506 // we're committing now. This most commonly happens when a suspended root
13507 // times out.
13508 // Get the list of effects.
13509
13510
13511 var firstEffect;
13512
13513 if (finishedWork.effectTag > PerformedWork) {
13514 // A fiber's effect list consists only of its children, not itself. So if
13515 // the root has an effect, we need to add it to the end of the list. The
13516 // resulting list is the set that would belong to the root's parent, if it
13517 // had one; that is, all the effects in the tree including the root.
13518 if (finishedWork.lastEffect !== null) {
13519 finishedWork.lastEffect.nextEffect = finishedWork;
13520 firstEffect = finishedWork.firstEffect;
13521 } else {
13522 firstEffect = finishedWork;
13523 }
13524 } else {
13525 // There is no effect on the root.
13526 firstEffect = finishedWork.firstEffect;
13527 }
13528
13529 if (firstEffect !== null) {
13530 var prevExecutionContext = executionContext;
13531 executionContext |= CommitContext;
13532 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
13533
13534 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
13535 // of the effect list for each phase: all mutation effects come before all
13536 // layout effects, and so on.
13537 // The first phase a "before mutation" phase. We use this phase to read the
13538 // state of the host tree right before we mutate it. This is where
13539 // getSnapshotBeforeUpdate is called.
13540
13541 startCommitSnapshotEffectsTimer();
13542 prepareForCommit(root.containerInfo);
13543 nextEffect = firstEffect;
13544
13545 do {
13546 {
13547 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
13548
13549 if (hasCaughtError()) {
13550 if (!(nextEffect !== null)) {
13551 {
13552 throw Error( "Should be working on an effect." );
13553 }
13554 }
13555
13556 var error = clearCaughtError();
13557 captureCommitPhaseError(nextEffect, error);
13558 nextEffect = nextEffect.nextEffect;
13559 }
13560 }
13561 } while (nextEffect !== null);
13562
13563 stopCommitSnapshotEffectsTimer();
13564
13565 {
13566 // Mark the current commit time to be shared by all Profilers in this
13567 // batch. This enables them to be grouped later.
13568 recordCommitTime();
13569 } // The next phase is the mutation phase, where we mutate the host tree.
13570
13571
13572 startCommitHostEffectsTimer();
13573 nextEffect = firstEffect;
13574
13575 do {
13576 {
13577 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
13578
13579 if (hasCaughtError()) {
13580 if (!(nextEffect !== null)) {
13581 {
13582 throw Error( "Should be working on an effect." );
13583 }
13584 }
13585
13586 var _error = clearCaughtError();
13587
13588 captureCommitPhaseError(nextEffect, _error);
13589 nextEffect = nextEffect.nextEffect;
13590 }
13591 }
13592 } while (nextEffect !== null);
13593
13594 stopCommitHostEffectsTimer();
13595 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
13596 // the mutation phase, so that the previous tree is still current during
13597 // componentWillUnmount, but before the layout phase, so that the finished
13598 // work is current during componentDidMount/Update.
13599
13600 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
13601 // the host tree after it's been mutated. The idiomatic use case for this is
13602 // layout, but class component lifecycles also fire here for legacy reasons.
13603
13604 startCommitLifeCyclesTimer();
13605 nextEffect = firstEffect;
13606
13607 do {
13608 {
13609 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
13610
13611 if (hasCaughtError()) {
13612 if (!(nextEffect !== null)) {
13613 {
13614 throw Error( "Should be working on an effect." );
13615 }
13616 }
13617
13618 var _error2 = clearCaughtError();
13619
13620 captureCommitPhaseError(nextEffect, _error2);
13621 nextEffect = nextEffect.nextEffect;
13622 }
13623 }
13624 } while (nextEffect !== null);
13625
13626 stopCommitLifeCyclesTimer();
13627 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
13628 // opportunity to paint.
13629
13630 requestPaint();
13631
13632 {
13633 popInteractions(prevInteractions);
13634 }
13635
13636 executionContext = prevExecutionContext;
13637 } else {
13638 // No effects.
13639 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
13640 // no effects.
13641 // TODO: Maybe there's a better way to report this.
13642
13643 startCommitSnapshotEffectsTimer();
13644 stopCommitSnapshotEffectsTimer();
13645
13646 {
13647 recordCommitTime();
13648 }
13649
13650 startCommitHostEffectsTimer();
13651 stopCommitHostEffectsTimer();
13652 startCommitLifeCyclesTimer();
13653 stopCommitLifeCyclesTimer();
13654 }
13655
13656 stopCommitTimer();
13657 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
13658
13659 if (rootDoesHavePassiveEffects) {
13660 // This commit has passive effects. Stash a reference to them. But don't
13661 // schedule a callback until after flushing layout work.
13662 rootDoesHavePassiveEffects = false;
13663 rootWithPendingPassiveEffects = root;
13664 pendingPassiveEffectsExpirationTime = expirationTime;
13665 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
13666 } else {
13667 // We are done with the effect chain at this point so let's clear the
13668 // nextEffect pointers to assist with GC. If we have passive effects, we'll
13669 // clear this in flushPassiveEffects.
13670 nextEffect = firstEffect;
13671
13672 while (nextEffect !== null) {
13673 var nextNextEffect = nextEffect.nextEffect;
13674 nextEffect.nextEffect = null;
13675 nextEffect = nextNextEffect;
13676 }
13677 } // Check if there's remaining work on this root
13678
13679
13680 var remainingExpirationTime = root.firstPendingTime;
13681
13682 if (remainingExpirationTime !== NoWork) {
13683 {
13684 if (spawnedWorkDuringRender !== null) {
13685 var expirationTimes = spawnedWorkDuringRender;
13686 spawnedWorkDuringRender = null;
13687
13688 for (var i = 0; i < expirationTimes.length; i++) {
13689 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
13690 }
13691 }
13692
13693 schedulePendingInteractions(root, remainingExpirationTime);
13694 }
13695 } else {
13696 // If there's no remaining work, we can clear the set of already failed
13697 // error boundaries.
13698 legacyErrorBoundariesThatAlreadyFailed = null;
13699 }
13700
13701 {
13702 if (!rootDidHavePassiveEffects) {
13703 // If there are no passive effects, then we can complete the pending interactions.
13704 // Otherwise, we'll wait until after the passive effects are flushed.
13705 // Wait to do this until after remaining work has been scheduled,
13706 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
13707 finishPendingInteractions(root, expirationTime);
13708 }
13709 }
13710
13711 if (remainingExpirationTime === Sync) {
13712 // Count the number of times the root synchronously re-renders without
13713 // finishing. If there are too many, it indicates an infinite update loop.
13714 if (root === rootWithNestedUpdates) {
13715 nestedUpdateCount++;
13716 } else {
13717 nestedUpdateCount = 0;
13718 rootWithNestedUpdates = root;
13719 }
13720 } else {
13721 nestedUpdateCount = 0;
13722 }
13723
13724 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
13725 // additional work on this root is scheduled.
13726
13727 ensureRootIsScheduled(root);
13728
13729 if (hasUncaughtError) {
13730 hasUncaughtError = false;
13731 var _error3 = firstUncaughtError;
13732 firstUncaughtError = null;
13733 throw _error3;
13734 }
13735
13736 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
13737 // This is a legacy edge case. We just committed the initial mount of
13738 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
13739 // synchronously, but layout updates should be deferred until the end
13740 // of the batch.
13741 return null;
13742 } // If layout work was scheduled, flush it now.
13743
13744
13745 flushSyncCallbackQueue();
13746 return null;
13747 }
13748
13749 function commitBeforeMutationEffects() {
13750 while (nextEffect !== null) {
13751 var effectTag = nextEffect.effectTag;
13752
13753 if ((effectTag & Snapshot) !== NoEffect) {
13754 setCurrentFiber(nextEffect);
13755 recordEffect();
13756 var current = nextEffect.alternate;
13757 commitBeforeMutationLifeCycles(current, nextEffect);
13758 resetCurrentFiber();
13759 }
13760
13761 if ((effectTag & Passive) !== NoEffect) {
13762 // If there are passive effects, schedule a callback to flush at
13763 // the earliest opportunity.
13764 if (!rootDoesHavePassiveEffects) {
13765 rootDoesHavePassiveEffects = true;
13766 scheduleCallback(NormalPriority, function () {
13767 flushPassiveEffects();
13768 return null;
13769 });
13770 }
13771 }
13772
13773 nextEffect = nextEffect.nextEffect;
13774 }
13775 }
13776
13777 function commitMutationEffects(root, renderPriorityLevel) {
13778 // TODO: Should probably move the bulk of this function to commitWork.
13779 while (nextEffect !== null) {
13780 setCurrentFiber(nextEffect);
13781 var effectTag = nextEffect.effectTag;
13782
13783 if (effectTag & ContentReset) {
13784 commitResetTextContent(nextEffect);
13785 }
13786
13787 if (effectTag & Ref) {
13788 var current = nextEffect.alternate;
13789
13790 if (current !== null) {
13791 commitDetachRef(current);
13792 }
13793 } // The following switch statement is only concerned about placement,
13794 // updates, and deletions. To avoid needing to add a case for every possible
13795 // bitmap value, we remove the secondary effects from the effect tag and
13796 // switch on that value.
13797
13798
13799 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
13800
13801 switch (primaryEffectTag) {
13802 case Placement:
13803 {
13804 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13805 // inserted, before any life-cycles like componentDidMount gets called.
13806 // TODO: findDOMNode doesn't rely on this any more but isMounted does
13807 // and isMounted is deprecated anyway so we should be able to kill this.
13808
13809 nextEffect.effectTag &= ~Placement;
13810 break;
13811 }
13812
13813 case PlacementAndUpdate:
13814 {
13815 // Placement
13816 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13817 // inserted, before any life-cycles like componentDidMount gets called.
13818
13819 nextEffect.effectTag &= ~Placement; // Update
13820
13821 var _current = nextEffect.alternate;
13822 commitWork(_current, nextEffect);
13823 break;
13824 }
13825
13826 case Hydrating:
13827 {
13828 nextEffect.effectTag &= ~Hydrating;
13829 break;
13830 }
13831
13832 case HydratingAndUpdate:
13833 {
13834 nextEffect.effectTag &= ~Hydrating; // Update
13835
13836 var _current2 = nextEffect.alternate;
13837 commitWork(_current2, nextEffect);
13838 break;
13839 }
13840
13841 case Update:
13842 {
13843 var _current3 = nextEffect.alternate;
13844 commitWork(_current3, nextEffect);
13845 break;
13846 }
13847
13848 case Deletion:
13849 {
13850 commitDeletion(root, nextEffect, renderPriorityLevel);
13851 break;
13852 }
13853 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
13854
13855
13856 recordEffect();
13857 resetCurrentFiber();
13858 nextEffect = nextEffect.nextEffect;
13859 }
13860 }
13861
13862 function commitLayoutEffects(root, committedExpirationTime) {
13863 // TODO: Should probably move the bulk of this function to commitWork.
13864 while (nextEffect !== null) {
13865 setCurrentFiber(nextEffect);
13866 var effectTag = nextEffect.effectTag;
13867
13868 if (effectTag & (Update | Callback)) {
13869 recordEffect();
13870 var current = nextEffect.alternate;
13871 commitLifeCycles(root, current, nextEffect);
13872 }
13873
13874 if (effectTag & Ref) {
13875 recordEffect();
13876 commitAttachRef(nextEffect);
13877 }
13878
13879 resetCurrentFiber();
13880 nextEffect = nextEffect.nextEffect;
13881 }
13882 }
13883
13884 function flushPassiveEffects() {
13885 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
13886 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
13887 pendingPassiveEffectsRenderPriority = NoPriority;
13888 return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
13889 }
13890 }
13891
13892 function flushPassiveEffectsImpl() {
13893 if (rootWithPendingPassiveEffects === null) {
13894 return false;
13895 }
13896
13897 var root = rootWithPendingPassiveEffects;
13898 var expirationTime = pendingPassiveEffectsExpirationTime;
13899 rootWithPendingPassiveEffects = null;
13900 pendingPassiveEffectsExpirationTime = NoWork;
13901
13902 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13903 {
13904 throw Error( "Cannot flush passive effects while already rendering." );
13905 }
13906 }
13907
13908 var prevExecutionContext = executionContext;
13909 executionContext |= CommitContext;
13910 var prevInteractions = pushInteractions(root);
13911
13912 {
13913 // Note: This currently assumes there are no passive effects on the root fiber
13914 // because the root is not part of its own effect list.
13915 // This could change in the future.
13916 var _effect2 = root.current.firstEffect;
13917
13918 while (_effect2 !== null) {
13919 {
13920 setCurrentFiber(_effect2);
13921 invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);
13922
13923 if (hasCaughtError()) {
13924 if (!(_effect2 !== null)) {
13925 {
13926 throw Error( "Should be working on an effect." );
13927 }
13928 }
13929
13930 var _error5 = clearCaughtError();
13931
13932 captureCommitPhaseError(_effect2, _error5);
13933 }
13934
13935 resetCurrentFiber();
13936 }
13937
13938 var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC
13939
13940 _effect2.nextEffect = null;
13941 _effect2 = nextNextEffect;
13942 }
13943 }
13944
13945 {
13946 popInteractions(prevInteractions);
13947 finishPendingInteractions(root, expirationTime);
13948 }
13949
13950 executionContext = prevExecutionContext;
13951 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
13952 // exceeds the limit, we'll fire a warning.
13953
13954 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
13955 return true;
13956 }
13957
13958 function isAlreadyFailedLegacyErrorBoundary(instance) {
13959 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
13960 }
13961 function markLegacyErrorBoundaryAsFailed(instance) {
13962 if (legacyErrorBoundariesThatAlreadyFailed === null) {
13963 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
13964 } else {
13965 legacyErrorBoundariesThatAlreadyFailed.add(instance);
13966 }
13967 }
13968
13969 function prepareToThrowUncaughtError(error) {
13970 if (!hasUncaughtError) {
13971 hasUncaughtError = true;
13972 firstUncaughtError = error;
13973 }
13974 }
13975
13976 var onUncaughtError = prepareToThrowUncaughtError;
13977
13978 function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
13979 var errorInfo = createCapturedValue(error, sourceFiber);
13980 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
13981 enqueueUpdate(rootFiber, update);
13982 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
13983
13984 if (root !== null) {
13985 ensureRootIsScheduled(root);
13986 schedulePendingInteractions(root, Sync);
13987 }
13988 }
13989
13990 function captureCommitPhaseError(sourceFiber, error) {
13991 if (sourceFiber.tag === HostRoot) {
13992 // Error was thrown at the root. There is no parent, so the root
13993 // itself should capture it.
13994 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
13995 return;
13996 }
13997
13998 var fiber = sourceFiber.return;
13999
14000 while (fiber !== null) {
14001 if (fiber.tag === HostRoot) {
14002 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
14003 return;
14004 } else if (fiber.tag === ClassComponent) {
14005 var ctor = fiber.type;
14006 var instance = fiber.stateNode;
14007
14008 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
14009 var errorInfo = createCapturedValue(error, sourceFiber);
14010 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
14011 Sync);
14012 enqueueUpdate(fiber, update);
14013 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
14014
14015 if (root !== null) {
14016 ensureRootIsScheduled(root);
14017 schedulePendingInteractions(root, Sync);
14018 }
14019
14020 return;
14021 }
14022 }
14023
14024 fiber = fiber.return;
14025 }
14026 }
14027 function pingSuspendedRoot(root, thenable, suspendedTime) {
14028 var pingCache = root.pingCache;
14029
14030 if (pingCache !== null) {
14031 // The thenable resolved, so we no longer need to memoize, because it will
14032 // never be thrown again.
14033 pingCache.delete(thenable);
14034 }
14035
14036 if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) {
14037 // Received a ping at the same priority level at which we're currently
14038 // rendering. We might want to restart this render. This should mirror
14039 // the logic of whether or not a root suspends once it completes.
14040 // TODO: If we're rendering sync either due to Sync, Batched or expired,
14041 // we should probably never restart.
14042 // If we're suspended with delay, we'll always suspend so we can always
14043 // restart. If we're suspended without any updates, it might be a retry.
14044 // If it's early in the retry we can restart. We can't know for sure
14045 // whether we'll eventually process an update during this render pass,
14046 // but it's somewhat unlikely that we get to a ping before that, since
14047 // getting to the root most update is usually very fast.
14048 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
14049 // Restart from the root. Don't need to schedule a ping because
14050 // we're already working on this tree.
14051 prepareFreshStack(root, renderExpirationTime$1);
14052 } else {
14053 // Even though we can't restart right now, we might get an
14054 // opportunity later. So we mark this render as having a ping.
14055 workInProgressRootHasPendingPing = true;
14056 }
14057
14058 return;
14059 }
14060
14061 if (!isRootSuspendedAtTime(root, suspendedTime)) {
14062 // The root is no longer suspended at this time.
14063 return;
14064 }
14065
14066 var lastPingedTime = root.lastPingedTime;
14067
14068 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
14069 // There's already a lower priority ping scheduled.
14070 return;
14071 } // Mark the time at which this ping was scheduled.
14072
14073
14074 root.lastPingedTime = suspendedTime;
14075
14076 ensureRootIsScheduled(root);
14077 schedulePendingInteractions(root, suspendedTime);
14078 }
14079
14080 function retryTimedOutBoundary(boundaryFiber, retryTime) {
14081 // The boundary fiber (a Suspense component or SuspenseList component)
14082 // previously was rendered in its fallback state. One of the promises that
14083 // suspended it has resolved, which means at least part of the tree was
14084 // likely unblocked. Try rendering again, at a new expiration time.
14085 if (retryTime === NoWork) {
14086 var suspenseConfig = null; // Retries don't carry over the already committed update.
14087
14088 var currentTime = requestCurrentTimeForUpdate();
14089 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
14090 } // TODO: Special case idle priority?
14091
14092
14093 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
14094
14095 if (root !== null) {
14096 ensureRootIsScheduled(root);
14097 schedulePendingInteractions(root, retryTime);
14098 }
14099 }
14100 function resolveRetryThenable(boundaryFiber, thenable) {
14101 var retryTime = NoWork; // Default
14102
14103 var retryCache;
14104
14105 {
14106 retryCache = boundaryFiber.stateNode;
14107 }
14108
14109 if (retryCache !== null) {
14110 // The thenable resolved, so we no longer need to memoize, because it will
14111 // never be thrown again.
14112 retryCache.delete(thenable);
14113 }
14114
14115 retryTimedOutBoundary(boundaryFiber, retryTime);
14116 } // Computes the next Just Noticeable Difference (JND) boundary.
14117 // The theory is that a person can't tell the difference between small differences in time.
14118 // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
14119 // difference in the experience. However, waiting for longer might mean that we can avoid
14120 // showing an intermediate loading state. The longer we have already waited, the harder it
14121 // is to tell small differences in time. Therefore, the longer we've already waited,
14122 // the longer we can wait additionally. At some point we have to give up though.
14123 // We pick a train model where the next boundary commits at a consistent schedule.
14124 // These particular numbers are vague estimates. We expect to adjust them based on research.
14125
14126 function jnd(timeElapsed) {
14127 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
14128 }
14129
14130 function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
14131 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
14132
14133 if (busyMinDurationMs <= 0) {
14134 return 0;
14135 }
14136
14137 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
14138
14139 var currentTimeMs = now();
14140 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
14141 var timeElapsed = currentTimeMs - eventTimeMs;
14142
14143 if (timeElapsed <= busyDelayMs) {
14144 // If we haven't yet waited longer than the initial delay, we don't
14145 // have to wait any additional time.
14146 return 0;
14147 }
14148
14149 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
14150
14151 return msUntilTimeout;
14152 }
14153
14154 function checkForNestedUpdates() {
14155 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
14156 nestedUpdateCount = 0;
14157 rootWithNestedUpdates = null;
14158
14159 {
14160 {
14161 throw Error( "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." );
14162 }
14163 }
14164 }
14165
14166 {
14167 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
14168 nestedPassiveUpdateCount = 0;
14169
14170 error('Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
14171 }
14172 }
14173 }
14174
14175 function flushRenderPhaseStrictModeWarningsInDEV() {
14176 {
14177 ReactStrictModeWarnings.flushLegacyContextWarning();
14178
14179 {
14180 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
14181 }
14182 }
14183 }
14184
14185 function stopFinishedWorkLoopTimer() {
14186 var didCompleteRoot = true;
14187 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
14188 interruptedBy = null;
14189 }
14190
14191 function stopInterruptedWorkLoopTimer() {
14192 // TODO: Track which fiber caused the interruption.
14193 var didCompleteRoot = false;
14194 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
14195 interruptedBy = null;
14196 }
14197
14198 function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
14199 if ( workInProgressRoot !== null && updateExpirationTime > renderExpirationTime$1) {
14200 interruptedBy = fiberThatReceivedUpdate;
14201 }
14202 }
14203
14204 var didWarnStateUpdateForUnmountedComponent = null;
14205
14206 function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
14207 {
14208 var tag = fiber.tag;
14209
14210 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
14211 // Only warn for user-defined components, not internal ones like Suspense.
14212 return;
14213 }
14214 // the problematic code almost always lies inside that component.
14215
14216
14217 var componentName = getComponentName(fiber.type) || 'ReactComponent';
14218
14219 if (didWarnStateUpdateForUnmountedComponent !== null) {
14220 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
14221 return;
14222 }
14223
14224 didWarnStateUpdateForUnmountedComponent.add(componentName);
14225 } else {
14226 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
14227 }
14228
14229 error("Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
14230 }
14231 }
14232
14233 var beginWork$1;
14234
14235 {
14236 var dummyFiber = null;
14237
14238 beginWork$1 = function (current, unitOfWork, expirationTime) {
14239 // If a component throws an error, we replay it again in a synchronously
14240 // dispatched event, so that the debugger will treat it as an uncaught
14241 // error See ReactErrorUtils for more information.
14242 // Before entering the begin phase, copy the work-in-progress onto a dummy
14243 // fiber. If beginWork throws, we'll use this to reset the state.
14244 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
14245
14246 try {
14247 return beginWork(current, unitOfWork, expirationTime);
14248 } catch (originalError) {
14249 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
14250 // Don't replay promises. Treat everything else like an error.
14251 throw originalError;
14252 } // Keep this code in sync with handleError; any changes here must have
14253 // corresponding changes there.
14254
14255
14256 resetContextDependencies();
14257 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
14258 // same fiber again.
14259 // Unwind the failed stack frame
14260
14261 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
14262
14263 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
14264
14265 if ( unitOfWork.mode & ProfileMode) {
14266 // Reset the profiler timer.
14267 startProfilerTimer(unitOfWork);
14268 } // Run beginWork again.
14269
14270
14271 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, expirationTime);
14272
14273 if (hasCaughtError()) {
14274 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
14275 // Rethrow this error instead of the original one.
14276
14277 throw replayError;
14278 } else {
14279 // This branch is reachable if the render phase is impure.
14280 throw originalError;
14281 }
14282 }
14283 };
14284 }
14285
14286 var didWarnAboutUpdateInRender = false;
14287 var didWarnAboutUpdateInGetChildContext = false;
14288
14289 function warnAboutRenderPhaseUpdatesInDEV(fiber) {
14290 {
14291 if ((executionContext & RenderContext) !== NoContext) {
14292 switch (fiber.tag) {
14293 case FunctionComponent:
14294 case ForwardRef:
14295 case SimpleMemoComponent:
14296 {
14297 error('Cannot update a component from inside the function body of a ' + 'different component.');
14298
14299 break;
14300 }
14301
14302 case ClassComponent:
14303 {
14304 switch (phase) {
14305 case 'getChildContext':
14306 if (didWarnAboutUpdateInGetChildContext) {
14307 return;
14308 }
14309
14310 error('setState(...): Cannot call setState() inside getChildContext()');
14311
14312 didWarnAboutUpdateInGetChildContext = true;
14313 break;
14314
14315 case 'render':
14316 if (didWarnAboutUpdateInRender) {
14317 return;
14318 }
14319
14320 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
14321
14322 didWarnAboutUpdateInRender = true;
14323 break;
14324 }
14325
14326 break;
14327 }
14328 }
14329 }
14330 }
14331 } // a 'shared' variable that changes when act() opens/closes in tests.
14332
14333
14334 var IsThisRendererActing = {
14335 current: false
14336 };
14337
14338 var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
14339 // scheduler is the actual recommendation. The alternative could be a testing build,
14340 // a new lib, or whatever; we dunno just yet. This message is for early adopters
14341 // to get their tests right.
14342
14343 function warnIfUnmockedScheduler(fiber) {
14344 {
14345 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
14346 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
14347 didWarnAboutUnmockedScheduler = true;
14348
14349 error('In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
14350 }
14351 }
14352 }
14353 }
14354
14355 function computeThreadID(root, expirationTime) {
14356 // Interaction threads are unique per root and expiration time.
14357 return expirationTime * 1000 + root.interactionThreadID;
14358 }
14359
14360 function markSpawnedWork(expirationTime) {
14361
14362 if (spawnedWorkDuringRender === null) {
14363 spawnedWorkDuringRender = [expirationTime];
14364 } else {
14365 spawnedWorkDuringRender.push(expirationTime);
14366 }
14367 }
14368
14369 function scheduleInteractions(root, expirationTime, interactions) {
14370
14371 if (interactions.size > 0) {
14372 var pendingInteractionMap = root.pendingInteractionMap;
14373 var pendingInteractions = pendingInteractionMap.get(expirationTime);
14374
14375 if (pendingInteractions != null) {
14376 interactions.forEach(function (interaction) {
14377 if (!pendingInteractions.has(interaction)) {
14378 // Update the pending async work count for previously unscheduled interaction.
14379 interaction.__count++;
14380 }
14381
14382 pendingInteractions.add(interaction);
14383 });
14384 } else {
14385 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
14386
14387 interactions.forEach(function (interaction) {
14388 interaction.__count++;
14389 });
14390 }
14391
14392 var subscriber = __subscriberRef.current;
14393
14394 if (subscriber !== null) {
14395 var threadID = computeThreadID(root, expirationTime);
14396 subscriber.onWorkScheduled(interactions, threadID);
14397 }
14398 }
14399 }
14400
14401 function schedulePendingInteractions(root, expirationTime) {
14402
14403 scheduleInteractions(root, expirationTime, __interactionsRef.current);
14404 }
14405
14406 function startWorkOnPendingInteractions(root, expirationTime) {
14407 // we can accurately attribute time spent working on it, And so that cascading
14408 // work triggered during the render phase will be associated with it.
14409
14410
14411 var interactions = new Set();
14412 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14413 if (scheduledExpirationTime >= expirationTime) {
14414 scheduledInteractions.forEach(function (interaction) {
14415 return interactions.add(interaction);
14416 });
14417 }
14418 }); // Store the current set of interactions on the FiberRoot for a few reasons:
14419 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
14420 // without having to recalculate it. We will also use it in commitWork() to
14421 // pass to any Profiler onRender() hooks. This also provides DevTools with a
14422 // way to access it when the onCommitRoot() hook is called.
14423
14424 root.memoizedInteractions = interactions;
14425
14426 if (interactions.size > 0) {
14427 var subscriber = __subscriberRef.current;
14428
14429 if (subscriber !== null) {
14430 var threadID = computeThreadID(root, expirationTime);
14431
14432 try {
14433 subscriber.onWorkStarted(interactions, threadID);
14434 } catch (error) {
14435 // If the subscriber throws, rethrow it in a separate task
14436 scheduleCallback(ImmediatePriority, function () {
14437 throw error;
14438 });
14439 }
14440 }
14441 }
14442 }
14443
14444 function finishPendingInteractions(root, committedExpirationTime) {
14445
14446 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
14447 var subscriber;
14448
14449 try {
14450 subscriber = __subscriberRef.current;
14451
14452 if (subscriber !== null && root.memoizedInteractions.size > 0) {
14453 var threadID = computeThreadID(root, committedExpirationTime);
14454 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
14455 }
14456 } catch (error) {
14457 // If the subscriber throws, rethrow it in a separate task
14458 scheduleCallback(ImmediatePriority, function () {
14459 throw error;
14460 });
14461 } finally {
14462 // Clear completed interactions from the pending Map.
14463 // Unless the render was suspended or cascading work was scheduled,
14464 // In which case– leave pending interactions until the subsequent render.
14465 var pendingInteractionMap = root.pendingInteractionMap;
14466 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14467 // Only decrement the pending interaction count if we're done.
14468 // If there's still work at the current priority,
14469 // That indicates that we are waiting for suspense data.
14470 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
14471 pendingInteractionMap.delete(scheduledExpirationTime);
14472 scheduledInteractions.forEach(function (interaction) {
14473 interaction.__count--;
14474
14475 if (subscriber !== null && interaction.__count === 0) {
14476 try {
14477 subscriber.onInteractionScheduledWorkCompleted(interaction);
14478 } catch (error) {
14479 // If the subscriber throws, rethrow it in a separate task
14480 scheduleCallback(ImmediatePriority, function () {
14481 throw error;
14482 });
14483 }
14484 }
14485 });
14486 }
14487 });
14488 }
14489 }
14490
14491 var onScheduleFiberRoot = null;
14492 var onCommitFiberRoot = null;
14493 var onCommitFiberUnmount = null;
14494 var hasLoggedError = false;
14495 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
14496 function injectInternals(internals) {
14497 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
14498 // No DevTools
14499 return false;
14500 }
14501
14502 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
14503
14504 if (hook.isDisabled) {
14505 // This isn't a real property on the hook, but it can be set to opt out
14506 // of DevTools integration and associated warnings and logs.
14507 // https://github.com/facebook/react/issues/3877
14508 return true;
14509 }
14510
14511 if (!hook.supportsFiber) {
14512 {
14513 error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools');
14514 } // DevTools exists, even though it doesn't support Fiber.
14515
14516
14517 return true;
14518 }
14519
14520 try {
14521 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
14522
14523 if (true) {
14524 // Only used by Fast Refresh
14525 if (typeof hook.onScheduleFiberRoot === 'function') {
14526 onScheduleFiberRoot = function (root, children) {
14527 try {
14528 hook.onScheduleFiberRoot(rendererID, root, children);
14529 } catch (err) {
14530 if (true && !hasLoggedError) {
14531 hasLoggedError = true;
14532
14533 error('React instrumentation encountered an error: %s', err);
14534 }
14535 }
14536 };
14537 }
14538 }
14539
14540 onCommitFiberRoot = function (root, expirationTime) {
14541 try {
14542 var didError = (root.current.effectTag & DidCapture) === DidCapture;
14543
14544 if (enableProfilerTimer) {
14545 var currentTime = getCurrentTime();
14546 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
14547 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
14548 } else {
14549 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
14550 }
14551 } catch (err) {
14552 if (true) {
14553 if (!hasLoggedError) {
14554 hasLoggedError = true;
14555
14556 error('React instrumentation encountered an error: %s', err);
14557 }
14558 }
14559 }
14560 };
14561
14562 onCommitFiberUnmount = function (fiber) {
14563 try {
14564 hook.onCommitFiberUnmount(rendererID, fiber);
14565 } catch (err) {
14566 if (true) {
14567 if (!hasLoggedError) {
14568 hasLoggedError = true;
14569
14570 error('React instrumentation encountered an error: %s', err);
14571 }
14572 }
14573 }
14574 };
14575 } catch (err) {
14576 // Catch all errors because it is unsafe to throw during initialization.
14577 {
14578 error('React instrumentation encountered an error: %s.', err);
14579 }
14580 } // DevTools exists
14581
14582
14583 return true;
14584 }
14585 function onScheduleRoot(root, children) {
14586 if (typeof onScheduleFiberRoot === 'function') {
14587 onScheduleFiberRoot(root, children);
14588 }
14589 }
14590 function onCommitRoot(root, expirationTime) {
14591 if (typeof onCommitFiberRoot === 'function') {
14592 onCommitFiberRoot(root, expirationTime);
14593 }
14594 }
14595 function onCommitUnmount(fiber) {
14596 if (typeof onCommitFiberUnmount === 'function') {
14597 onCommitFiberUnmount(fiber);
14598 }
14599 }
14600
14601 var hasBadMapPolyfill;
14602
14603 {
14604 hasBadMapPolyfill = false;
14605
14606 try {
14607 var nonExtensibleObject = Object.preventExtensions({});
14608 var testMap = new Map([[nonExtensibleObject, null]]);
14609 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
14610 // https://github.com/rollup/rollup/issues/1771
14611 // TODO: we can remove these if Rollup fixes the bug.
14612
14613 testMap.set(0, 0);
14614 testSet.add(0);
14615 } catch (e) {
14616 // TODO: Consider warning about bad polyfills
14617 hasBadMapPolyfill = true;
14618 }
14619 }
14620
14621 var debugCounter = 1;
14622
14623 function FiberNode(tag, pendingProps, key, mode) {
14624 // Instance
14625 this.tag = tag;
14626 this.key = key;
14627 this.elementType = null;
14628 this.type = null;
14629 this.stateNode = null; // Fiber
14630
14631 this.return = null;
14632 this.child = null;
14633 this.sibling = null;
14634 this.index = 0;
14635 this.ref = null;
14636 this.pendingProps = pendingProps;
14637 this.memoizedProps = null;
14638 this.updateQueue = null;
14639 this.memoizedState = null;
14640 this.dependencies = null;
14641 this.mode = mode; // Effects
14642
14643 this.effectTag = NoEffect;
14644 this.nextEffect = null;
14645 this.firstEffect = null;
14646 this.lastEffect = null;
14647 this.expirationTime = NoWork;
14648 this.childExpirationTime = NoWork;
14649 this.alternate = null;
14650
14651 {
14652 // Note: The following is done to avoid a v8 performance cliff.
14653 //
14654 // Initializing the fields below to smis and later updating them with
14655 // double values will cause Fibers to end up having separate shapes.
14656 // This behavior/bug has something to do with Object.preventExtension().
14657 // Fortunately this only impacts DEV builds.
14658 // Unfortunately it makes React unusably slow for some applications.
14659 // To work around this, initialize the fields below with doubles.
14660 //
14661 // Learn more about this here:
14662 // https://github.com/facebook/react/issues/14365
14663 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
14664 this.actualDuration = Number.NaN;
14665 this.actualStartTime = Number.NaN;
14666 this.selfBaseDuration = Number.NaN;
14667 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
14668 // This won't trigger the performance cliff mentioned above,
14669 // and it simplifies other profiler code (including DevTools).
14670
14671 this.actualDuration = 0;
14672 this.actualStartTime = -1;
14673 this.selfBaseDuration = 0;
14674 this.treeBaseDuration = 0;
14675 } // This is normally DEV-only except www when it adds listeners.
14676 // TODO: remove the User Timing integration in favor of Root Events.
14677
14678
14679 {
14680 this._debugID = debugCounter++;
14681 this._debugIsCurrentlyTiming = false;
14682 }
14683
14684 {
14685 this._debugSource = null;
14686 this._debugOwner = null;
14687 this._debugNeedsRemount = false;
14688 this._debugHookTypes = null;
14689
14690 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
14691 Object.preventExtensions(this);
14692 }
14693 }
14694 } // This is a constructor function, rather than a POJO constructor, still
14695 // please ensure we do the following:
14696 // 1) Nobody should add any instance methods on this. Instance methods can be
14697 // more difficult to predict when they get optimized and they are almost
14698 // never inlined properly in static compilers.
14699 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
14700 // always know when it is a fiber.
14701 // 3) We might want to experiment with using numeric keys since they are easier
14702 // to optimize in a non-JIT environment.
14703 // 4) We can easily go from a constructor to a createFiber object literal if that
14704 // is faster.
14705 // 5) It should be easy to port this to a C struct and keep a C implementation
14706 // compatible.
14707
14708
14709 var createFiber = function (tag, pendingProps, key, mode) {
14710 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
14711 return new FiberNode(tag, pendingProps, key, mode);
14712 };
14713
14714 function shouldConstruct(Component) {
14715 var prototype = Component.prototype;
14716 return !!(prototype && prototype.isReactComponent);
14717 }
14718
14719 function isSimpleFunctionComponent(type) {
14720 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
14721 }
14722 function resolveLazyComponentTag(Component) {
14723 if (typeof Component === 'function') {
14724 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
14725 } else if (Component !== undefined && Component !== null) {
14726 var $$typeof = Component.$$typeof;
14727
14728 if ($$typeof === REACT_FORWARD_REF_TYPE) {
14729 return ForwardRef;
14730 }
14731
14732 if ($$typeof === REACT_MEMO_TYPE) {
14733 return MemoComponent;
14734 }
14735 }
14736
14737 return IndeterminateComponent;
14738 } // This is used to create an alternate fiber to do work on.
14739
14740 function createWorkInProgress(current, pendingProps) {
14741 var workInProgress = current.alternate;
14742
14743 if (workInProgress === null) {
14744 // We use a double buffering pooling technique because we know that we'll
14745 // only ever need at most two versions of a tree. We pool the "other" unused
14746 // node that we're free to reuse. This is lazily created to avoid allocating
14747 // extra objects for things that are never updated. It also allow us to
14748 // reclaim the extra memory if needed.
14749 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
14750 workInProgress.elementType = current.elementType;
14751 workInProgress.type = current.type;
14752 workInProgress.stateNode = current.stateNode;
14753
14754 {
14755 // DEV-only fields
14756 {
14757 workInProgress._debugID = current._debugID;
14758 }
14759
14760 workInProgress._debugSource = current._debugSource;
14761 workInProgress._debugOwner = current._debugOwner;
14762 workInProgress._debugHookTypes = current._debugHookTypes;
14763 }
14764
14765 workInProgress.alternate = current;
14766 current.alternate = workInProgress;
14767 } else {
14768 workInProgress.pendingProps = pendingProps; // We already have an alternate.
14769 // Reset the effect tag.
14770
14771 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
14772
14773 workInProgress.nextEffect = null;
14774 workInProgress.firstEffect = null;
14775 workInProgress.lastEffect = null;
14776
14777 {
14778 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
14779 // This prevents time from endlessly accumulating in new commits.
14780 // This has the downside of resetting values for different priority renders,
14781 // But works for yielding (the common case) and should support resuming.
14782 workInProgress.actualDuration = 0;
14783 workInProgress.actualStartTime = -1;
14784 }
14785 }
14786
14787 workInProgress.childExpirationTime = current.childExpirationTime;
14788 workInProgress.expirationTime = current.expirationTime;
14789 workInProgress.child = current.child;
14790 workInProgress.memoizedProps = current.memoizedProps;
14791 workInProgress.memoizedState = current.memoizedState;
14792 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14793 // it cannot be shared with the current fiber.
14794
14795 var currentDependencies = current.dependencies;
14796 workInProgress.dependencies = currentDependencies === null ? null : {
14797 expirationTime: currentDependencies.expirationTime,
14798 firstContext: currentDependencies.firstContext,
14799 responders: currentDependencies.responders
14800 }; // These will be overridden during the parent's reconciliation
14801
14802 workInProgress.sibling = current.sibling;
14803 workInProgress.index = current.index;
14804 workInProgress.ref = current.ref;
14805
14806 {
14807 workInProgress.selfBaseDuration = current.selfBaseDuration;
14808 workInProgress.treeBaseDuration = current.treeBaseDuration;
14809 }
14810
14811 {
14812 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
14813
14814 switch (workInProgress.tag) {
14815 case IndeterminateComponent:
14816 case FunctionComponent:
14817 case SimpleMemoComponent:
14818 workInProgress.type = resolveFunctionForHotReloading(current.type);
14819 break;
14820
14821 case ClassComponent:
14822 workInProgress.type = resolveClassForHotReloading(current.type);
14823 break;
14824
14825 case ForwardRef:
14826 workInProgress.type = resolveForwardRefForHotReloading(current.type);
14827 break;
14828 }
14829 }
14830
14831 return workInProgress;
14832 } // Used to reuse a Fiber for a second pass.
14833
14834 function resetWorkInProgress(workInProgress, renderExpirationTime) {
14835 // This resets the Fiber to what createFiber or createWorkInProgress would
14836 // have set the values to before during the first pass. Ideally this wouldn't
14837 // be necessary but unfortunately many code paths reads from the workInProgress
14838 // when they should be reading from current and writing to workInProgress.
14839 // We assume pendingProps, index, key, ref, return are still untouched to
14840 // avoid doing another reconciliation.
14841 // Reset the effect tag but keep any Placement tags, since that's something
14842 // that child fiber is setting, not the reconciliation.
14843 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
14844
14845 workInProgress.nextEffect = null;
14846 workInProgress.firstEffect = null;
14847 workInProgress.lastEffect = null;
14848 var current = workInProgress.alternate;
14849
14850 if (current === null) {
14851 // Reset to createFiber's initial values.
14852 workInProgress.childExpirationTime = NoWork;
14853 workInProgress.expirationTime = renderExpirationTime;
14854 workInProgress.child = null;
14855 workInProgress.memoizedProps = null;
14856 workInProgress.memoizedState = null;
14857 workInProgress.updateQueue = null;
14858 workInProgress.dependencies = null;
14859
14860 {
14861 // Note: We don't reset the actualTime counts. It's useful to accumulate
14862 // actual time across multiple render passes.
14863 workInProgress.selfBaseDuration = 0;
14864 workInProgress.treeBaseDuration = 0;
14865 }
14866 } else {
14867 // Reset to the cloned values that createWorkInProgress would've.
14868 workInProgress.childExpirationTime = current.childExpirationTime;
14869 workInProgress.expirationTime = current.expirationTime;
14870 workInProgress.child = current.child;
14871 workInProgress.memoizedProps = current.memoizedProps;
14872 workInProgress.memoizedState = current.memoizedState;
14873 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14874 // it cannot be shared with the current fiber.
14875
14876 var currentDependencies = current.dependencies;
14877 workInProgress.dependencies = currentDependencies === null ? null : {
14878 expirationTime: currentDependencies.expirationTime,
14879 firstContext: currentDependencies.firstContext,
14880 responders: currentDependencies.responders
14881 };
14882
14883 {
14884 // Note: We don't reset the actualTime counts. It's useful to accumulate
14885 // actual time across multiple render passes.
14886 workInProgress.selfBaseDuration = current.selfBaseDuration;
14887 workInProgress.treeBaseDuration = current.treeBaseDuration;
14888 }
14889 }
14890
14891 return workInProgress;
14892 }
14893 function createHostRootFiber(tag) {
14894 var mode;
14895
14896 if (tag === ConcurrentRoot) {
14897 mode = ConcurrentMode | BlockingMode | StrictMode;
14898 } else if (tag === BlockingRoot) {
14899 mode = BlockingMode | StrictMode;
14900 } else {
14901 mode = NoMode;
14902 }
14903
14904 if ( isDevToolsPresent) {
14905 // Always collect profile timings when DevTools are present.
14906 // This enables DevTools to start capturing timing at any point–
14907 // Without some nodes in the tree having empty base times.
14908 mode |= ProfileMode;
14909 }
14910
14911 return createFiber(HostRoot, null, null, mode);
14912 }
14913 function createFiberFromTypeAndProps(type, // React$ElementType
14914 key, pendingProps, owner, mode, expirationTime) {
14915 var fiber;
14916 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
14917
14918 var resolvedType = type;
14919
14920 if (typeof type === 'function') {
14921 if (shouldConstruct(type)) {
14922 fiberTag = ClassComponent;
14923
14924 {
14925 resolvedType = resolveClassForHotReloading(resolvedType);
14926 }
14927 } else {
14928 {
14929 resolvedType = resolveFunctionForHotReloading(resolvedType);
14930 }
14931 }
14932 } else if (typeof type === 'string') {
14933 fiberTag = HostComponent;
14934 } else {
14935 getTag: switch (type) {
14936 case REACT_FRAGMENT_TYPE:
14937 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
14938
14939 case REACT_CONCURRENT_MODE_TYPE:
14940 fiberTag = Mode;
14941 mode |= ConcurrentMode | BlockingMode | StrictMode;
14942 break;
14943
14944 case REACT_STRICT_MODE_TYPE:
14945 fiberTag = Mode;
14946 mode |= StrictMode;
14947 break;
14948
14949 case REACT_PROFILER_TYPE:
14950 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
14951
14952 case REACT_SUSPENSE_TYPE:
14953 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
14954
14955 case REACT_SUSPENSE_LIST_TYPE:
14956 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
14957
14958 default:
14959 {
14960 if (typeof type === 'object' && type !== null) {
14961 switch (type.$$typeof) {
14962 case REACT_PROVIDER_TYPE:
14963 fiberTag = ContextProvider;
14964 break getTag;
14965
14966 case REACT_CONTEXT_TYPE:
14967 // This is a consumer
14968 fiberTag = ContextConsumer;
14969 break getTag;
14970
14971 case REACT_FORWARD_REF_TYPE:
14972 fiberTag = ForwardRef;
14973
14974 {
14975 resolvedType = resolveForwardRefForHotReloading(resolvedType);
14976 }
14977
14978 break getTag;
14979
14980 case REACT_MEMO_TYPE:
14981 fiberTag = MemoComponent;
14982 break getTag;
14983
14984 case REACT_LAZY_TYPE:
14985 fiberTag = LazyComponent;
14986 resolvedType = null;
14987 break getTag;
14988
14989 case REACT_BLOCK_TYPE:
14990 fiberTag = Block;
14991 break getTag;
14992
14993 }
14994 }
14995
14996 var info = '';
14997
14998 {
14999 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
15000 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.';
15001 }
15002
15003 var ownerName = owner ? getComponentName(owner.type) : null;
15004
15005 if (ownerName) {
15006 info += '\n\nCheck the render method of `' + ownerName + '`.';
15007 }
15008 }
15009
15010 {
15011 {
15012 throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + (type == null ? type : typeof type) + "." + info );
15013 }
15014 }
15015 }
15016 }
15017 }
15018
15019 fiber = createFiber(fiberTag, pendingProps, key, mode);
15020 fiber.elementType = type;
15021 fiber.type = resolvedType;
15022 fiber.expirationTime = expirationTime;
15023 return fiber;
15024 }
15025 function createFiberFromElement(element, mode, expirationTime) {
15026 var owner = null;
15027
15028 {
15029 owner = element._owner;
15030 }
15031
15032 var type = element.type;
15033 var key = element.key;
15034 var pendingProps = element.props;
15035 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
15036
15037 {
15038 fiber._debugSource = element._source;
15039 fiber._debugOwner = element._owner;
15040 }
15041
15042 return fiber;
15043 }
15044 function createFiberFromFragment(elements, mode, expirationTime, key) {
15045 var fiber = createFiber(Fragment, elements, key, mode);
15046 fiber.expirationTime = expirationTime;
15047 return fiber;
15048 }
15049
15050 function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
15051 {
15052 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
15053 error('Profiler must specify an "id" string and "onRender" function as props');
15054 }
15055 }
15056
15057 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
15058
15059 fiber.elementType = REACT_PROFILER_TYPE;
15060 fiber.type = REACT_PROFILER_TYPE;
15061 fiber.expirationTime = expirationTime;
15062 return fiber;
15063 }
15064
15065 function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
15066 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
15067 // This needs to be fixed in getComponentName so that it relies on the tag
15068 // instead.
15069
15070 fiber.type = REACT_SUSPENSE_TYPE;
15071 fiber.elementType = REACT_SUSPENSE_TYPE;
15072 fiber.expirationTime = expirationTime;
15073 return fiber;
15074 }
15075 function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
15076 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
15077
15078 {
15079 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
15080 // This needs to be fixed in getComponentName so that it relies on the tag
15081 // instead.
15082 fiber.type = REACT_SUSPENSE_LIST_TYPE;
15083 }
15084
15085 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
15086 fiber.expirationTime = expirationTime;
15087 return fiber;
15088 }
15089 function createFiberFromText(content, mode, expirationTime) {
15090 var fiber = createFiber(HostText, content, null, mode);
15091 fiber.expirationTime = expirationTime;
15092 return fiber;
15093 }
15094 function createFiberFromPortal(portal, mode, expirationTime) {
15095 var pendingProps = portal.children !== null ? portal.children : [];
15096 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
15097 fiber.expirationTime = expirationTime;
15098 fiber.stateNode = {
15099 containerInfo: portal.containerInfo,
15100 pendingChildren: null,
15101 // Used by persistent updates
15102 implementation: portal.implementation
15103 };
15104 return fiber;
15105 } // Used for stashing WIP properties to replay failed work in DEV.
15106
15107 function assignFiberPropertiesInDEV(target, source) {
15108 if (target === null) {
15109 // This Fiber's initial properties will always be overwritten.
15110 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
15111 target = createFiber(IndeterminateComponent, null, null, NoMode);
15112 } // This is intentionally written as a list of all properties.
15113 // We tried to use Object.assign() instead but this is called in
15114 // the hottest path, and Object.assign() was too slow:
15115 // https://github.com/facebook/react/issues/12502
15116 // This code is DEV-only so size is not a concern.
15117
15118
15119 target.tag = source.tag;
15120 target.key = source.key;
15121 target.elementType = source.elementType;
15122 target.type = source.type;
15123 target.stateNode = source.stateNode;
15124 target.return = source.return;
15125 target.child = source.child;
15126 target.sibling = source.sibling;
15127 target.index = source.index;
15128 target.ref = source.ref;
15129 target.pendingProps = source.pendingProps;
15130 target.memoizedProps = source.memoizedProps;
15131 target.updateQueue = source.updateQueue;
15132 target.memoizedState = source.memoizedState;
15133 target.dependencies = source.dependencies;
15134 target.mode = source.mode;
15135 target.effectTag = source.effectTag;
15136 target.nextEffect = source.nextEffect;
15137 target.firstEffect = source.firstEffect;
15138 target.lastEffect = source.lastEffect;
15139 target.expirationTime = source.expirationTime;
15140 target.childExpirationTime = source.childExpirationTime;
15141 target.alternate = source.alternate;
15142
15143 {
15144 target.actualDuration = source.actualDuration;
15145 target.actualStartTime = source.actualStartTime;
15146 target.selfBaseDuration = source.selfBaseDuration;
15147 target.treeBaseDuration = source.treeBaseDuration;
15148 }
15149
15150 {
15151 target._debugID = source._debugID;
15152 }
15153
15154 target._debugSource = source._debugSource;
15155 target._debugOwner = source._debugOwner;
15156 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
15157 target._debugNeedsRemount = source._debugNeedsRemount;
15158 target._debugHookTypes = source._debugHookTypes;
15159 return target;
15160 }
15161
15162 function FiberRootNode(containerInfo, tag, hydrate) {
15163 this.tag = tag;
15164 this.current = null;
15165 this.containerInfo = containerInfo;
15166 this.pendingChildren = null;
15167 this.pingCache = null;
15168 this.finishedExpirationTime = NoWork;
15169 this.finishedWork = null;
15170 this.timeoutHandle = noTimeout;
15171 this.context = null;
15172 this.pendingContext = null;
15173 this.hydrate = hydrate;
15174 this.callbackNode = null;
15175 this.callbackPriority = NoPriority;
15176 this.firstPendingTime = NoWork;
15177 this.firstSuspendedTime = NoWork;
15178 this.lastSuspendedTime = NoWork;
15179 this.nextKnownPendingLevel = NoWork;
15180 this.lastPingedTime = NoWork;
15181 this.lastExpiredTime = NoWork;
15182
15183 {
15184 this.interactionThreadID = unstable_getThreadID();
15185 this.memoizedInteractions = new Set();
15186 this.pendingInteractionMap = new Map();
15187 }
15188 }
15189
15190 function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
15191 var root = new FiberRootNode(containerInfo, tag, hydrate);
15192 // stateNode is any.
15193
15194
15195 var uninitializedFiber = createHostRootFiber(tag);
15196 root.current = uninitializedFiber;
15197 uninitializedFiber.stateNode = root;
15198 initializeUpdateQueue(uninitializedFiber);
15199 return root;
15200 }
15201 function isRootSuspendedAtTime(root, expirationTime) {
15202 var firstSuspendedTime = root.firstSuspendedTime;
15203 var lastSuspendedTime = root.lastSuspendedTime;
15204 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
15205 }
15206 function markRootSuspendedAtTime(root, expirationTime) {
15207 var firstSuspendedTime = root.firstSuspendedTime;
15208 var lastSuspendedTime = root.lastSuspendedTime;
15209
15210 if (firstSuspendedTime < expirationTime) {
15211 root.firstSuspendedTime = expirationTime;
15212 }
15213
15214 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
15215 root.lastSuspendedTime = expirationTime;
15216 }
15217
15218 if (expirationTime <= root.lastPingedTime) {
15219 root.lastPingedTime = NoWork;
15220 }
15221
15222 if (expirationTime <= root.lastExpiredTime) {
15223 root.lastExpiredTime = NoWork;
15224 }
15225 }
15226 function markRootUpdatedAtTime(root, expirationTime) {
15227 // Update the range of pending times
15228 var firstPendingTime = root.firstPendingTime;
15229
15230 if (expirationTime > firstPendingTime) {
15231 root.firstPendingTime = expirationTime;
15232 } // Update the range of suspended times. Treat everything lower priority or
15233 // equal to this update as unsuspended.
15234
15235
15236 var firstSuspendedTime = root.firstSuspendedTime;
15237
15238 if (firstSuspendedTime !== NoWork) {
15239 if (expirationTime >= firstSuspendedTime) {
15240 // The entire suspended range is now unsuspended.
15241 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
15242 } else if (expirationTime >= root.lastSuspendedTime) {
15243 root.lastSuspendedTime = expirationTime + 1;
15244 } // This is a pending level. Check if it's higher priority than the next
15245 // known pending level.
15246
15247
15248 if (expirationTime > root.nextKnownPendingLevel) {
15249 root.nextKnownPendingLevel = expirationTime;
15250 }
15251 }
15252 }
15253 function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
15254 // Update the range of pending times
15255 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
15256 // equal to this update as unsuspended.
15257
15258 if (finishedExpirationTime <= root.lastSuspendedTime) {
15259 // The entire suspended range is now unsuspended.
15260 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
15261 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
15262 // Part of the suspended range is now unsuspended. Narrow the range to
15263 // include everything between the unsuspended time (non-inclusive) and the
15264 // last suspended time.
15265 root.firstSuspendedTime = finishedExpirationTime - 1;
15266 }
15267
15268 if (finishedExpirationTime <= root.lastPingedTime) {
15269 // Clear the pinged time
15270 root.lastPingedTime = NoWork;
15271 }
15272
15273 if (finishedExpirationTime <= root.lastExpiredTime) {
15274 // Clear the expired time
15275 root.lastExpiredTime = NoWork;
15276 }
15277 }
15278 function markRootExpiredAtTime(root, expirationTime) {
15279 var lastExpiredTime = root.lastExpiredTime;
15280
15281 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
15282 root.lastExpiredTime = expirationTime;
15283 }
15284 }
15285
15286 var didWarnAboutNestedUpdates;
15287
15288 {
15289 didWarnAboutNestedUpdates = false;
15290 }
15291
15292 function getContextForSubtree(parentComponent) {
15293 if (!parentComponent) {
15294 return emptyContextObject;
15295 }
15296
15297 var fiber = get(parentComponent);
15298 var parentContext = findCurrentUnmaskedContext(fiber);
15299
15300 if (fiber.tag === ClassComponent) {
15301 var Component = fiber.type;
15302
15303 if (isContextProvider(Component)) {
15304 return processChildContext(fiber, Component, parentContext);
15305 }
15306 }
15307
15308 return parentContext;
15309 }
15310
15311 function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
15312 return createFiberRoot(containerInfo, tag, hydrate);
15313 }
15314 function updateContainer(element, container, parentComponent, callback) {
15315 {
15316 onScheduleRoot(container, element);
15317 }
15318
15319 var current = container.current;
15320 var currentTime = requestCurrentTimeForUpdate();
15321
15322 {
15323 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15324 if ('undefined' !== typeof jest) {
15325 warnIfUnmockedScheduler(current);
15326 }
15327 }
15328
15329 var suspenseConfig = requestCurrentSuspenseConfig();
15330 var expirationTime = computeExpirationForFiber(currentTime, current, suspenseConfig);
15331 var context = getContextForSubtree(parentComponent);
15332
15333 if (container.context === null) {
15334 container.context = context;
15335 } else {
15336 container.pendingContext = context;
15337 }
15338
15339 {
15340 if (phase === 'render' && current$1 !== null && !didWarnAboutNestedUpdates) {
15341 didWarnAboutNestedUpdates = true;
15342
15343 error('Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName(current$1.type) || 'Unknown');
15344 }
15345 }
15346
15347 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
15348 // being called "element".
15349
15350 update.payload = {
15351 element: element
15352 };
15353 callback = callback === undefined ? null : callback;
15354
15355 if (callback !== null) {
15356 {
15357 if (typeof callback !== 'function') {
15358 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
15359 }
15360 }
15361
15362 update.callback = callback;
15363 }
15364
15365 enqueueUpdate(current, update);
15366 scheduleWork(current, expirationTime);
15367 return expirationTime;
15368 }
15369
15370 var shouldSuspendImpl = function (fiber) {
15371 return false;
15372 };
15373
15374 function shouldSuspend(fiber) {
15375 return shouldSuspendImpl(fiber);
15376 }
15377 var overrideHookState = null;
15378 var overrideProps = null;
15379 var scheduleUpdate = null;
15380 var setSuspenseHandler = null;
15381
15382 {
15383 var copyWithSetImpl = function (obj, path, idx, value) {
15384 if (idx >= path.length) {
15385 return value;
15386 }
15387
15388 var key = path[idx];
15389 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
15390
15391 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
15392 return updated;
15393 };
15394
15395 var copyWithSet = function (obj, path, value) {
15396 return copyWithSetImpl(obj, path, 0, value);
15397 }; // Support DevTools editable values for useState and useReducer.
15398
15399
15400 overrideHookState = function (fiber, id, path, value) {
15401 // For now, the "id" of stateful hooks is just the stateful hook index.
15402 // This may change in the future with e.g. nested hooks.
15403 var currentHook = fiber.memoizedState;
15404
15405 while (currentHook !== null && id > 0) {
15406 currentHook = currentHook.next;
15407 id--;
15408 }
15409
15410 if (currentHook !== null) {
15411 var newState = copyWithSet(currentHook.memoizedState, path, value);
15412 currentHook.memoizedState = newState;
15413 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
15414 // because there is no update we can add for useReducer hooks that won't trigger an error.
15415 // (There's no appropriate action type for DevTools overrides.)
15416 // As a result though, React will see the scheduled update as a noop and bailout.
15417 // Shallow cloning props works as a workaround for now to bypass the bailout check.
15418
15419 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
15420 scheduleWork(fiber, Sync);
15421 }
15422 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
15423
15424
15425 overrideProps = function (fiber, path, value) {
15426 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
15427
15428 if (fiber.alternate) {
15429 fiber.alternate.pendingProps = fiber.pendingProps;
15430 }
15431
15432 scheduleWork(fiber, Sync);
15433 };
15434
15435 scheduleUpdate = function (fiber) {
15436 scheduleWork(fiber, Sync);
15437 };
15438
15439 setSuspenseHandler = function (newShouldSuspendImpl) {
15440 shouldSuspendImpl = newShouldSuspendImpl;
15441 };
15442 }
15443
15444 function injectIntoDevTools(devToolsConfig) {
15445 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
15446 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
15447 return injectInternals(_assign({}, devToolsConfig, {
15448 overrideHookState: overrideHookState,
15449 overrideProps: overrideProps,
15450 setSuspenseHandler: setSuspenseHandler,
15451 scheduleUpdate: scheduleUpdate,
15452 currentDispatcherRef: ReactCurrentDispatcher,
15453 findHostInstanceByFiber: function (fiber) {
15454 var hostFiber = findCurrentHostFiber(fiber);
15455
15456 if (hostFiber === null) {
15457 return null;
15458 }
15459
15460 return hostFiber.stateNode;
15461 },
15462 findFiberByHostInstance: function (instance) {
15463 if (!findFiberByHostInstance) {
15464 // Might not be implemented by the renderer.
15465 return null;
15466 }
15467
15468 return findFiberByHostInstance(instance);
15469 },
15470 // React Refresh
15471 findHostInstancesForRefresh: findHostInstancesForRefresh ,
15472 scheduleRefresh: scheduleRefresh ,
15473 scheduleRoot: scheduleRoot ,
15474 setRefreshHandler: setRefreshHandler ,
15475 // Enables DevTools to append owner stacks to error messages in DEV mode.
15476 getCurrentFiber: function () {
15477 return current$1;
15478 }
15479 }));
15480 }
15481 var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
15482
15483 var container = _class({
15484
15485 grab: function(){
15486 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
15487 return this;
15488 },
15489
15490 empty: function(){
15491 var node;
15492 while (node = this.firstChild) node.eject();
15493 return this;
15494 }
15495
15496 });
15497
15498 function elementFrom(node){
15499 if (node.toElement) return node.toElement();
15500 if (node.getDOMNode) return node.getDOMNode();
15501 if (node.getNode) return node.getNode();
15502 return node;
15503 }
15504
15505 var native_1 = _class({
15506
15507 // conventions
15508
15509 toElement: function(){
15510 return this.element;
15511 },
15512
15513 getDOMNode: function(){
15514 return this.toElement();
15515 },
15516
15517 getNode: function(){
15518 return this.toElement();
15519 },
15520
15521 // placement
15522
15523 inject: function(container){
15524 (container.containerElement || elementFrom(container))
15525 .appendChild(this.element);
15526 return this;
15527 },
15528
15529 injectBefore: function(sibling){
15530 var element = elementFrom(sibling);
15531 element.parentNode.insertBefore(this.element, element);
15532 return this;
15533 },
15534
15535 eject: function(){
15536 var element = this.element, parent = element.parentNode;
15537 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
15538 return this;
15539 },
15540
15541 // events
15542
15543 subscribe: function(type, fn, bind){
15544 if (typeof type != 'string'){ // listen type / fn with object
15545 var subscriptions = [];
15546 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
15547 return function(){ // unsubscribe
15548 for (var i = 0, l = subscriptions.length; i < l; i++)
15549 subscriptions[i]();
15550 return this;
15551 };
15552 } else { // listen to one
15553 if (!bind) bind = this;
15554 var bound;
15555 if (typeof fn === 'function'){
15556 bound = fn.bind ? fn.bind(bind)
15557 : function(){ return fn.apply(bind, arguments); };
15558 } else {
15559 bound = fn;
15560 }
15561 var element = this.element;
15562 if (element.addEventListener){
15563 element.addEventListener(type, bound, false);
15564 return function(){ // unsubscribe
15565 element.removeEventListener(type, bound, false);
15566 return this;
15567 };
15568 } else {
15569 element.attachEvent('on' + type, bound);
15570 return function(){ // unsubscribe
15571 element.detachEvent('on' + type, bound);
15572 return this;
15573 };
15574 }
15575 }
15576 }
15577
15578 });
15579
15580 var fps = 1000 / 60, invalids = [], renderTimer, renderInvalids = function(){
15581 clearTimeout(renderTimer);
15582 renderTimer = null;
15583 var canvases = invalids;
15584 invalids = [];
15585 for (var i = 0, l = canvases.length; i < l; i++){
15586 var c = canvases[i];
15587 c._valid = true;
15588 c.render();
15589 }
15590 };
15591
15592 var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
15593
15594 var previousHit = null, previousHitSurface = null;
15595
15596 var CanvasSurface = _class(native_1, container, {
15597
15598 initialize: function(width, height, existingElement){
15599 var element = this.element = existingElement || document.createElement('canvas');
15600 var context = this.context = element.getContext('2d');
15601 this._valid = true;
15602 if (width != null && height != null) this.resize(width, height);
15603
15604 element.addEventListener('mousemove', this, false);
15605 element.addEventListener('mouseout', this, false);
15606 element.addEventListener('mouseover', this, false);
15607 element.addEventListener('mouseup', this, false);
15608 element.addEventListener('mousedown', this, false);
15609 element.addEventListener('click', this, false);
15610 },
15611
15612 handleEvent: function(event){
15613 if (event.clientX == null) return;
15614 var element = this.element,
15615 rect = element.getBoundingClientRect(),
15616 x = event.clientX - rect.left - element.clientLeft,
15617 y = event.clientY - rect.top - element.clientTop,
15618 hit = this.hitTest(x, y);
15619
15620 if (hit !== previousHit){
15621 if (previousHit){
15622 previousHit.dispatch({
15623 type: 'mouseout',
15624 target: previousHit,
15625 relatedTarget: hit,
15626 sourceEvent: event
15627 });
15628 }
15629 if (hit){
15630 hit.dispatch({
15631 type: 'mouseover',
15632 target: hit,
15633 relatedTarget: previousHit,
15634 sourceEvent: event
15635 });
15636 }
15637 previousHit = hit;
15638 previousHitSurface = this;
15639 this.refreshCursor();
15640 }
15641
15642 if (hit) hit.dispatch(event);
15643 },
15644
15645 refreshCursor: function(){
15646 if (previousHitSurface !== this) return;
15647 var hit = previousHit, hitCursor = '', hitTooltip = '';
15648 while (hit){
15649 if (!hitCursor && hit._cursor){
15650 hitCursor = hit._cursor;
15651 if (hitTooltip) break;
15652 }
15653 if (!hitTooltip && hit._tooltip){
15654 hitTooltip = hit._tooltip;
15655 if (hitCursor) break;
15656 }
15657 hit = hit.parentNode;
15658 }
15659 // TODO: No way to set cursor/title on the surface
15660 this.element.style.cursor = hitCursor;
15661 this.element.title = hitTooltip;
15662 },
15663
15664 resize: function(width, height){
15665 var element = this.element;
15666 element.setAttribute('width', width * resolution);
15667 element.setAttribute('height', height * resolution);
15668 element.style.width = width + 'px';
15669 element.style.height = height + 'px';
15670 this.width = width;
15671 this.height = height;
15672 return this;
15673 },
15674
15675 invalidate: function(left, top, width, height){
15676 if (this._valid){
15677 this._valid = false;
15678 invalids.push(this);
15679 if (!renderTimer){
15680 if (window.mozRequestAnimationFrame){
15681 renderTimer = true;
15682 window.mozRequestAnimationFrame(renderInvalids);
15683 } else {
15684 renderTimer = setTimeout(renderInvalids, fps);
15685 }
15686 }
15687 }
15688 return this;
15689 },
15690
15691 hitTest: function(x, y){
15692 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
15693 var node = this.lastChild;
15694 while (node){
15695 var hit = node.hitTest(x, y);
15696 if (hit) return hit;
15697 node = node.previousSibling;
15698 }
15699 return null;
15700 },
15701
15702 render: function(){
15703 var node = this.firstChild, context = this.context;
15704 context.setTransform(resolution, 0, 0, resolution, 0, 0);
15705 context.clearRect(0, 0, this.width, this.height);
15706 while (node){
15707 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
15708 node = node.nextSibling;
15709 }
15710 this.refreshCursor();
15711 }
15712
15713 });
15714
15715 CanvasSurface.tagName = 'canvas';
15716
15717 var surface = CanvasSurface;
15718
15719 var path = _class({
15720
15721 initialize: function(path){
15722 this.reset().push(path);
15723 },
15724
15725 /* parser */
15726
15727 push: function(){
15728 var p = Array.prototype.join.call(arguments, ' ')
15729 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
15730 if (!p) return this;
15731
15732 var last, cmd = p[0], i = 1;
15733 while (cmd){
15734 switch (cmd){
15735 case 'm': this.move(p[i++], p[i++]); break;
15736 case 'l': this.line(p[i++], p[i++]); break;
15737 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
15738 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
15739 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
15740 case 't': this.curve(p[i++], p[i++]); break;
15741 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;
15742 case 'h': this.line(p[i++], 0); break;
15743 case 'v': this.line(0, p[i++]); break;
15744
15745 case 'M': this.moveTo(p[i++], p[i++]); break;
15746 case 'L': this.lineTo(p[i++], p[i++]); break;
15747 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
15748 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
15749 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
15750 case 'T': this.curveTo(p[i++], p[i++]); break;
15751 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;
15752 case 'H': this.lineTo(p[i++], this.penY); break;
15753 case 'V': this.lineTo(this.penX, p[i++]); break;
15754
15755 case 'Z': case 'z': this.close(); break;
15756 default: cmd = last; i--; continue;
15757 }
15758
15759 last = cmd;
15760 if (last == 'm') last = 'l';
15761 else if (last == 'M') last = 'L';
15762 cmd = p[i++];
15763 }
15764 return this;
15765 },
15766
15767 /* utility methods */
15768
15769 reset: function(){
15770 this.penX = this.penY = 0;
15771 this.penDownX = this.penDownY = null;
15772 this._pivotX = this._pivotY = 0;
15773 this.onReset();
15774 return this;
15775 },
15776
15777 move: function(x,y){
15778 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
15779 return this;
15780 },
15781 moveTo: function(x,y){
15782 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
15783 return this;
15784 },
15785
15786 line: function(x,y){
15787 return this.lineTo(this.penX + (+x), this.penY + (+y));
15788 },
15789 lineTo: function(x,y){
15790 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
15791 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
15792 return this;
15793 },
15794
15795 curve: function(c1x, c1y, c2x, c2y, ex, ey){
15796 var x = this.penX, y = this.penY;
15797 return this.curveTo(
15798 x + (+c1x), y + (+c1y),
15799 c2x == null ? null : x + (+c2x),
15800 c2y == null ? null : y + (+c2y),
15801 ex == null ? null : x + (+ex),
15802 ey == null ? null : y + (+ey)
15803 );
15804 },
15805 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
15806 var x = this.penX, y = this.penY;
15807 if (c2x == null){
15808 c2x = +c1x; c2y = +c1y;
15809 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
15810 }
15811 if (ex == null){
15812 this._pivotX = +c1x; this._pivotY = +c1y;
15813 ex = +c2x; ey = +c2y;
15814 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
15815 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
15816 } else {
15817 this._pivotX = +c2x; this._pivotY = +c2y;
15818 }
15819 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
15820 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
15821 return this;
15822 },
15823
15824 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
15825 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
15826 },
15827 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
15828 ry = Math.abs(+ry || +rx || (+y - this.penY));
15829 rx = Math.abs(+rx || (+x - this.penX));
15830
15831 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
15832
15833 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
15834
15835 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
15836 x -= tX; y -= tY;
15837
15838 // Ellipse Center
15839 var cx = cos * x / 2 + sin * y / 2,
15840 cy = -sin * x / 2 + cos * y / 2,
15841 rxry = rx * rx * ry * ry,
15842 rycx = ry * ry * cx * cx,
15843 rxcy = rx * rx * cy * cy,
15844 a = rxry - rxcy - rycx;
15845
15846 if (a < 0){
15847 a = Math.sqrt(1 - a / rxry);
15848 rx *= a; ry *= a;
15849 cx = x / 2; cy = y / 2;
15850 } else {
15851 a = Math.sqrt(a / (rxcy + rycx));
15852 if (large == clockwise) a = -a;
15853 var cxd = -a * cy * rx / ry,
15854 cyd = a * cx * ry / rx;
15855 cx = cos * cxd - sin * cyd + x / 2;
15856 cy = sin * cxd + cos * cyd + y / 2;
15857 }
15858
15859 // Rotation + Scale Transform
15860 var xx = cos / rx, yx = sin / rx,
15861 xy = -sin / ry, yy = cos / ry;
15862
15863 // Start and End Angle
15864 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
15865 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
15866
15867 cx += tX; cy += tY;
15868 x += tX; y += tY;
15869
15870 // Circular Arc
15871 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
15872 this.onArc(
15873 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
15874 cx, cy, rx, ry, sa, ea, !clockwise, rotation
15875 );
15876 return this;
15877 },
15878
15879 counterArc: function(x, y, rx, ry, outer){
15880 return this.arc(x, y, rx, ry, outer, true);
15881 },
15882 counterArcTo: function(x, y, rx, ry, outer){
15883 return this.arcTo(x, y, rx, ry, outer, true);
15884 },
15885
15886 close: function(){
15887 if (this.penDownX != null){
15888 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
15889 this.penDownX = null;
15890 }
15891 return this;
15892 },
15893
15894 /* overridable handlers */
15895
15896 onReset: function(){
15897 },
15898
15899 onMove: function(sx, sy, ex, ey){
15900 },
15901
15902 onLine: function(sx, sy, ex, ey){
15903 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
15904 },
15905
15906 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
15907 var gx = ex - sx, gy = ey - sy,
15908 g = gx * gx + gy * gy,
15909 v1, v2, cx, cy, u;
15910
15911 cx = c1x - sx; cy = c1y - sy;
15912 u = cx * gx + cy * gy;
15913
15914 if (u > g){
15915 cx -= gx;
15916 cy -= gy;
15917 } else if (u > 0 && g != 0){
15918 cx -= u/g * gx;
15919 cy -= u/g * gy;
15920 }
15921
15922 v1 = cx * cx + cy * cy;
15923
15924 cx = c2x - sx; cy = c2y - sy;
15925 u = cx * gx + cy * gy;
15926
15927 if (u > g){
15928 cx -= gx;
15929 cy -= gy;
15930 } else if (u > 0 && g != 0){
15931 cx -= u/g * gx;
15932 cy -= u/g * gy;
15933 }
15934
15935 v2 = cx * cx + cy * cy;
15936
15937 if (v1 < 0.01 && v2 < 0.01){
15938 this.onLine(sx, sy, ex, ey);
15939 return;
15940 }
15941
15942 // Avoid infinite recursion
15943 if (isNaN(v1) || isNaN(v2)){
15944 throw new Error('Bad input');
15945 }
15946
15947 // Split curve
15948 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
15949 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
15950 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
15951 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
15952 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
15953 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
15954
15955 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
15956 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
15957 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
15958 },
15959
15960 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
15961 // Inverse Rotation + Scale Transform
15962 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
15963 xx = cos * rx, yx = -sin * ry,
15964 xy = sin * rx, yy = cos * ry;
15965
15966 // Bezier Curve Approximation
15967 var arc = ea - sa;
15968 if (arc < 0 && !ccw) arc += Math.PI * 2;
15969 else if (arc > 0 && ccw) arc -= Math.PI * 2;
15970
15971 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
15972 step = arc / n,
15973 k = (4 / 3) * Math.tan(step / 4);
15974
15975 var x = Math.cos(sa), y = Math.sin(sa);
15976
15977 for (var i = 0; i < n; i++){
15978 var cp1x = x - k * y, cp1y = y + k * x;
15979
15980 sa += step;
15981 x = Math.cos(sa); y = Math.sin(sa);
15982
15983 var cp2x = x + k * y, cp2y = y - k * x;
15984
15985 this.onBezierCurve(
15986 sx, sy,
15987 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
15988 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
15989 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
15990 );
15991 }
15992 },
15993
15994 onClose: function(sx, sy, ex, ey){
15995 this.onLine(sx, sy, ex, ey);
15996 }
15997
15998 });
15999
16000 var CanvasPath = _class(path, {
16001
16002 initialize: function(path){
16003 this.reset();
16004 if (path instanceof CanvasPath){
16005 this.path = path.path.slice(0);
16006 } else if (path){
16007 if (path.applyToPath)
16008 path.applyToPath(this);
16009 else
16010 this.push(path);
16011 }
16012 },
16013
16014 onReset: function(){
16015 this.path = [];
16016 },
16017
16018 onMove: function(sx, sy, x, y){
16019 this.path.push(function(context){
16020 context.moveTo(x, y);
16021 });
16022 },
16023
16024 onLine: function(sx, sy, x, y){
16025 this.path.push(function(context){
16026 context.lineTo(x, y);
16027 });
16028 },
16029
16030 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
16031 this.path.push(function(context){
16032 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
16033 });
16034 },
16035
16036 _arcToBezier: path.prototype.onArc,
16037
16038 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
16039 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
16040 this.path.push(function(context){
16041 context.arc(cx, cy, rx, sa, ea, ccw);
16042 });
16043 },
16044
16045 onClose: function(){
16046 this.path.push(function(context){
16047 context.closePath();
16048 });
16049 },
16050
16051 toCommands: function(){
16052 return this.path.slice(0);
16053 }
16054
16055 });
16056
16057 var path$1 = CanvasPath;
16058
16059 var colors = {
16060 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
16061 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
16062 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
16063 black: '#000000', silver: '#c0c0c0', gray: '#808080'
16064 };
16065
16066 var map = function(array, fn){
16067 var results = [];
16068 for (var i = 0, l = array.length; i < l; i++)
16069 results[i] = fn(array[i], i);
16070 return results;
16071 };
16072
16073 var Color = function(color, type){
16074
16075 if (color.isColor){
16076
16077 this.red = color.red;
16078 this.green = color.green;
16079 this.blue = color.blue;
16080 this.alpha = color.alpha;
16081
16082 } else {
16083
16084 var namedColor = colors[color];
16085 if (namedColor){
16086 color = namedColor;
16087 type = 'hex';
16088 }
16089
16090 switch (typeof color){
16091 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
16092 case 'object': type = type || 'rgb'; color = color.toString(); break;
16093 case 'number': type = 'hex'; color = color.toString(16); break;
16094 }
16095
16096 color = Color['parse' + type.toUpperCase()](color);
16097 this.red = color[0];
16098 this.green = color[1];
16099 this.blue = color[2];
16100 this.alpha = color[3];
16101 }
16102
16103 this.isColor = true;
16104
16105 };
16106
16107 var limit = function(number, min, max){
16108 return Math.min(max, Math.max(min, number));
16109 };
16110
16111 var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
16112 var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
16113
16114 Color.parseRGB = function(color){
16115 return map(color.match(listMatch).slice(1), function(bit, i){
16116 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
16117 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
16118 });
16119 };
16120
16121 Color.parseHEX = function(color){
16122 if (color.length == 1) color = color + color + color;
16123 return map(color.match(hexMatch).slice(1), function(bit, i){
16124 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
16125 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
16126 });
16127 };
16128
16129 Color.parseHSB = function(color){
16130 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
16131 if (bit) bit = parseFloat(bit);
16132 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
16133 else if (i < 3) return limit(Math.round(bit), 0, 100);
16134 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
16135 });
16136
16137 var a = hsb[3];
16138 var br = Math.round(hsb[2] / 100 * 255);
16139 if (hsb[1] == 0) return [br, br, br, a];
16140
16141 var hue = hsb[0];
16142 var f = hue % 60;
16143 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
16144 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
16145 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
16146
16147 switch (Math.floor(hue / 60)){
16148 case 0: return [br, t, p, a];
16149 case 1: return [q, br, p, a];
16150 case 2: return [p, br, t, a];
16151 case 3: return [p, q, br, a];
16152 case 4: return [t, p, br, a];
16153 default: return [br, p, q, a];
16154 }
16155 };
16156
16157 Color.parseHSL = function(color){
16158 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
16159 if (bit) bit = parseFloat(bit);
16160 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
16161 else if (i < 3) return limit(Math.round(bit), 0, 100);
16162 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
16163 });
16164
16165 var h = hsb[0] / 60;
16166 var s = hsb[1] / 100;
16167 var l = hsb[2] / 100;
16168 var a = hsb[3];
16169
16170 var c = (1 - Math.abs(2 * l - 1)) * s;
16171 var x = c * (1 - Math.abs(h % 2 - 1));
16172 var m = l - c / 2;
16173
16174 var p = Math.round((c + m) * 255);
16175 var q = Math.round((x + m) * 255);
16176 var t = Math.round((m) * 255);
16177
16178 switch (Math.floor(h)){
16179 case 0: return [p, q, t, a];
16180 case 1: return [q, p, t, a];
16181 case 2: return [t, p, q, a];
16182 case 3: return [t, q, p, a];
16183 case 4: return [q, t, p, a];
16184 default: return [p, t, q, a];
16185 }
16186 };
16187
16188 var toString = function(type, array){
16189 if (array[3] != 1) type += 'a';
16190 else array.pop();
16191 return type + '(' + array.join(', ') + ')';
16192 };
16193
16194 Color.prototype = {
16195
16196 toHSB: function(array){
16197 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
16198
16199 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
16200 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
16201 if (saturation){
16202 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
16203 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
16204 if ((hue /= 6) < 0) hue++;
16205 }
16206
16207 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
16208
16209 return (array) ? hsb : toString('hsb', hsb);
16210 },
16211
16212 toHSL: function(array){
16213 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
16214
16215 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
16216 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
16217 if (saturation){
16218 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
16219 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
16220 if ((hue /= 6) < 0) hue++;
16221 }
16222
16223 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
16224
16225 return (array) ? hsl : toString('hsl', hsl);
16226 },
16227
16228 toHEX: function(array){
16229
16230 var a = this.alpha;
16231 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
16232
16233 var hex = map([this.red, this.green, this.blue], function(bit){
16234 bit = bit.toString(16);
16235 return (bit.length == 1) ? '0' + bit : bit;
16236 });
16237
16238 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
16239 },
16240
16241 toRGB: function(array){
16242 var rgb = [this.red, this.green, this.blue, this.alpha];
16243 return (array) ? rgb : toString('rgb', rgb);
16244 }
16245
16246 };
16247
16248 Color.prototype.toString = Color.prototype.toRGB;
16249
16250 Color.hex = function(hex){
16251 return new Color(hex, 'hex');
16252 };
16253
16254 if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
16255
16256 Color.hsb = function(h, s, b, a){
16257 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
16258 };
16259
16260 if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
16261
16262 Color.hsl = function(h, s, l, a){
16263 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
16264 };
16265
16266 if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
16267
16268 Color.rgb = function(r, g, b, a){
16269 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
16270 };
16271
16272 if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
16273
16274 Color.detach = function(color){
16275 color = new Color(color);
16276 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
16277 };
16278
16279 var color = Color;
16280
16281 var dummy = _class({
16282
16283 // placement
16284
16285 _resetPlacement: function(){
16286 var container = this.parentNode;
16287 if (container){
16288 var previous = this.previousSibling, next = this.nextSibling;
16289 if (previous){
16290 previous.nextSibling = next;
16291 } else {
16292 container.firstChild = next;
16293 }
16294 if (next){
16295 next.previousSibling = previous;
16296 } else {
16297 container.lastChild = this.previousSibling;
16298 }
16299 }
16300 this.previousSibling = null;
16301 this.nextSibling = null;
16302 this.parentNode = null;
16303 return this;
16304 },
16305
16306 inject: function(container){
16307 this._resetPlacement();
16308 var last = container.lastChild;
16309 if (last){
16310 last.nextSibling = this;
16311 this.previousSibling = last;
16312 } else {
16313 container.firstChild = this;
16314 }
16315 container.lastChild = this;
16316 this.parentNode = container;
16317 this._place();
16318 return this;
16319 },
16320
16321 injectBefore: function(sibling){
16322 this._resetPlacement();
16323 var container = sibling.parentNode;
16324 if (!container) return this;
16325 var previous = sibling.previousSibling;
16326 if (previous){
16327 previous.nextSibling = this;
16328 this.previousSibling = previous;
16329 } else {
16330 container.firstChild = this;
16331 }
16332 sibling.previousSibling = this;
16333 this.nextSibling = sibling;
16334 this.parentNode = container;
16335 this._place();
16336 return this;
16337 },
16338
16339 eject: function(){
16340 this._resetPlacement();
16341 this._place();
16342 return this;
16343 },
16344
16345 _place: function(){},
16346
16347 // events
16348
16349 dispatch: function(event){
16350 var events = this._events,
16351 listeners = events && events[event.type];
16352 if (listeners){
16353 listeners = listeners.slice(0);
16354 for (var i = 0, l = listeners.length; i < l; i++){
16355 var fn = listeners[i], result;
16356 if (typeof fn == 'function')
16357 result = fn.call(this, event);
16358 else
16359 result = fn.handleEvent(event);
16360 if (result === false) event.preventDefault();
16361 }
16362 }
16363 if (this.parentNode && this.parentNode.dispatch){
16364 this.parentNode.dispatch(event);
16365 }
16366 },
16367
16368 subscribe: function(type, fn, bind){
16369 if (typeof type != 'string'){ // listen type / fn with object
16370 var subscriptions = [];
16371 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
16372 return function(){ // unsubscribe
16373 for (var i = 0, l = subscriptions.length; i < l; i++)
16374 subscriptions[i]();
16375 return this;
16376 };
16377 } else { // listen to one
16378 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
16379 events = this._events || (this._events = {}),
16380 listeners = events[type] || (events[type] = []);
16381 listeners.push(bound);
16382 return function(){
16383 // unsubscribe
16384 for (var i = 0, l = listeners.length; i < l; i++){
16385 if (listeners[i] === bound){
16386 listeners.splice(i, 1);
16387 break;
16388 }
16389 }
16390 }
16391 }
16392 }
16393
16394 });
16395
16396 var CanvasNode = _class(transform, dummy, {
16397
16398 invalidate: function(){
16399 if (this.parentNode) this.parentNode.invalidate();
16400 if (this._layer) this._layerCache = null;
16401 return this;
16402 },
16403
16404 _place: function(){
16405 this.invalidate();
16406 },
16407
16408 _transform: function(){
16409 this.invalidate();
16410 },
16411
16412 blend: function(opacity){
16413 if (opacity >= 1 && this._layer) this._layer = null;
16414 this._opacity = opacity;
16415 if (this.parentNode) this.parentNode.invalidate();
16416 return this;
16417 },
16418
16419 // visibility
16420
16421 hide: function(){
16422 this._invisible = true;
16423 if (this.parentNode) this.parentNode.invalidate();
16424 return this;
16425 },
16426
16427 show: function(){
16428 this._invisible = false;
16429 if (this.parentNode) this.parentNode.invalidate();
16430 return this;
16431 },
16432
16433 // interaction
16434
16435 indicate: function(cursor, tooltip){
16436 this._cursor = cursor;
16437 this._tooltip = tooltip;
16438 return this.invalidate();
16439 },
16440
16441 hitTest: function(x, y){
16442 if (this._invisible) return null;
16443 var point = this.inversePoint(x, y);
16444 if (!point) return null;
16445 return this.localHitTest(point.x, point.y);
16446 },
16447
16448 // rendering
16449
16450 renderTo: function(context, xx, yx, xy, yy, x, y){
16451 var opacity = this._opacity;
16452 if (opacity == null || opacity >= 1){
16453 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
16454 }
16455
16456 // Render to a compositing layer and cache it
16457
16458 var layer = this._layer, canvas, isDirty = true,
16459 w = context.canvas.width, h = context.canvas.height;
16460 if (layer){
16461 layer.setTransform(1, 0, 0, 1, 0, 0);
16462 canvas = layer.canvas;
16463 if (canvas.width < w || canvas.height < h){
16464 canvas.width = w;
16465 canvas.height = h;
16466 } else {
16467 var c = this._layerCache;
16468 if (c && c.xx === xx && c.yx === yx && c.xy === xy
16469 && c.yy === yy && c.x === x && c.y === y){
16470 isDirty = false;
16471 } else {
16472 layer.clearRect(0, 0, w, h);
16473 }
16474 }
16475 } else {
16476 canvas = document.createElement('canvas');
16477 canvas.width = w;
16478 canvas.height = h;
16479 this._layer = layer = canvas.getContext('2d');
16480 }
16481
16482 if (isDirty){
16483 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
16484 this._layerCache = {
16485 xx: xx,
16486 yx: yx,
16487 xy: xy,
16488 yy: yy,
16489 x: x,
16490 y: y
16491 };
16492 }
16493
16494 context.globalAlpha = opacity;
16495 context.setTransform(1, 0, 0, 1, 0, 0);
16496 context.drawImage(
16497 canvas,
16498 0, 0, w, h,
16499 0, 0, w, h
16500 );
16501 context.globalAlpha = 1;
16502 }
16503
16504 });
16505
16506 var node = CanvasNode;
16507
16508 var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas'),
16509 genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
16510
16511 function recolorImage(img, color1, color2){
16512 // TODO: Fix this experimental implementation
16513 color1 = color.detach(color1);
16514 color2 = color.detach(color2);
16515 var canvas = document.createElement('canvas'),
16516 context = canvas.getContext('2d');
16517 canvas.width = img.width;
16518 canvas.height = img.height;
16519 context.fillStyle = color2[0];
16520 context.fillRect(0, 0, img.width, img.height);
16521 context.globalCompositeOperation = 'lighter';
16522 context.drawImage(img, 0, 0);
16523 return canvas;
16524 }
16525
16526 var Base = _class(node, {
16527
16528 initialize: function(){
16529 this._fill = null;
16530 this._pendingFill = null;
16531 this._fillTransform = null;
16532 this._stroke = null;
16533 this._strokeCap = null;
16534 this._strokeDash = null;
16535 this._strokeJoin = null;
16536 this._strokeWidth = null;
16537 },
16538
16539 /* styles */
16540
16541 _addColors: function(gradient, stops){
16542 // Enumerate stops, assumes offsets are enumerated in order
16543 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
16544 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
16545 gradient.addColorStop(i / l, new color(stops[i]).toString());
16546 else for (var offset in stops)
16547 gradient.addColorStop(offset, new color(stops[offset]).toString());
16548 return gradient;
16549 },
16550
16551
16552 fill: function(color$1){
16553 if (arguments.length > 1) return this.fillLinear(arguments);
16554 if (this._pendingFill) this._pendingFill();
16555 this._fill = color$1 ? new color(color$1).toString() : null;
16556 return this.invalidate();
16557 },
16558
16559 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
16560 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
16561 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
16562 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
16563 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
16564 if (centerX == null) centerX = focusX;
16565 if (centerY == null) centerY = focusY;
16566
16567 centerX += centerX - focusX;
16568 centerY += centerY - focusY;
16569
16570 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
16571 var ys = radiusY / radiusX;
16572
16573 if (this._pendingFill) this._pendingFill();
16574
16575 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
16576
16577 // Double fill radius to simulate repeating gradient
16578 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
16579 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
16580 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
16581 } else for (var offset in stops){
16582 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
16583 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
16584 }
16585
16586 this._fill = gradient;
16587 this._fillTransform = new transform(1, 0, 0, ys);
16588 return this.invalidate();
16589 },
16590
16591 fillLinear: function(stops, x1, y1, x2, y2){
16592 if (arguments.length < 5){
16593 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
16594
16595 var x = Math.cos(angle), y = -Math.sin(angle),
16596 l = (Math.abs(x) + Math.abs(y)) / 2,
16597 w = this.width || 1, h = this.height || 1;
16598
16599 x *= l; y *= l;
16600
16601 x1 = 0.5 - x;
16602 x2 = 0.5 + x;
16603 y1 = 0.5 - y;
16604 y2 = 0.5 + y;
16605 this._fillTransform = new transform(w, 0, 0, h);
16606 } else {
16607 this._fillTransform = null;
16608 }
16609 if (this._pendingFill) this._pendingFill();
16610 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
16611 this._addColors(gradient, stops);
16612 this._fill = gradient;
16613 return this.invalidate();
16614 },
16615
16616 fillImage: function(url, width, height, left, top, color1, color2){
16617 if (this._pendingFill) this._pendingFill();
16618 var img = url;
16619 if (!(img instanceof Image)){
16620 img = new Image();
16621 img.src = url;
16622 }
16623 if (img.width && img.height){
16624 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
16625 }
16626
16627 // Not yet loaded
16628 this._fill = null;
16629 var self = this,
16630 callback = function(){
16631 cancel();
16632 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
16633 },
16634 cancel = function(){
16635 img.removeEventListener('load', callback, false);
16636 self._pendingFill = null;
16637 };
16638 this._pendingFill = cancel;
16639 img.addEventListener('load', callback, false);
16640 return this;
16641 },
16642
16643 _fillImage: function(img, width, height, left, top, color1, color2){
16644 var w = width ? width / img.width : 1,
16645 h = height ? height / img.height : 1;
16646 if (color1 != null) img = recolorImage(img, color1, color2);
16647 this._fill = genericContext.createPattern(img, 'repeat');
16648 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
16649 return this.invalidate();
16650 },
16651
16652 stroke: function(color$1, width, cap, join, dash){
16653 this._stroke = color$1 ? new color(color$1).toString() : null;
16654 this._strokeWidth = (width != null) ? width : 1;
16655 this._strokeCap = (cap != null) ? cap : 'round';
16656 this._strokeJoin = (join != null) ? join : 'round';
16657 this._strokeDash = dash;
16658 return this.invalidate();
16659 },
16660
16661 // Rendering
16662
16663 element_renderTo: node.prototype.renderTo,
16664
16665 renderTo: function(context, xx, yx, xy, yy, x, y){
16666 var opacity = this._opacity;
16667 if (opacity == null || opacity >= 1){
16668 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
16669 }
16670 if (this._fill && this._stroke){
16671 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
16672 }
16673 context.globalAlpha = opacity;
16674 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
16675 context.globalAlpha = 1;
16676 return r;
16677 },
16678
16679 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
16680 context.setTransform(xx, yx, xy, yy, x, y);
16681 this.renderShapeTo(context);
16682 }
16683
16684 });
16685
16686 Base._genericContext = genericContext;
16687
16688 var base = Base;
16689
16690 var shape = _class(base, {
16691
16692 base_initialize: base.prototype.initialize,
16693
16694 initialize: function(path, width, height){
16695 this.base_initialize();
16696 this.width = width;
16697 this.height = height;
16698 if (path != null) this.draw(path);
16699 },
16700
16701 draw: function(path, width, height){
16702 if (!(path instanceof path$1)) path = new path$1(path);
16703 this.path = path;
16704 this._commands = path.toCommands();
16705 if (width != null) this.width = width;
16706 if (height != null) this.height = height;
16707 return this.invalidate();
16708 },
16709
16710 localHitTest: function(x, y){
16711 if (!this._fill) return null;
16712 if (this.width == null || this.height == null){
16713 var context = base._genericContext, commands = this._commands;
16714 if (!commands) return null;
16715 context.beginPath();
16716 for (var i = 0, l = commands.length; i < l; i++)
16717 commands[i](context);
16718 return context.isPointInPath(x, y) ? this : null;
16719 }
16720 if (x > 0 && y > 0 && x < this.width && y < this.height){
16721 return this;
16722 }
16723 return null;
16724 },
16725
16726 renderShapeTo: function(context){
16727 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
16728 return null;
16729 }
16730 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
16731 var commands = this._commands,
16732 fill = this._fill,
16733 stroke = this._stroke,
16734 dash = this._strokeDash;
16735
16736 context.beginPath();
16737
16738 if (dash) {
16739 if (context.setLineDash) {
16740 context.setLineDash(dash);
16741 } else {
16742 // TODO: Remove when FF supports setLineDash.
16743 context.mozDash = dash;
16744 }
16745 // TODO: Create fallback to other browsers.
16746 } else {
16747 if (context.setLineDash) {
16748 context.setLineDash([]);
16749 } else {
16750 context.mozDash = null;
16751 }
16752 }
16753
16754 for (var i = 0, l = commands.length; i < l; i++)
16755 commands[i](context);
16756
16757 if (fill){
16758 var m = this._fillTransform;
16759 if (m){
16760 context.save(); // TODO: Optimize away this by restoring the transform before stroking
16761 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
16762 context.fillStyle = fill;
16763 context.fill();
16764 context.restore();
16765 } else {
16766 context.fillStyle = fill;
16767 context.fill();
16768 }
16769 }
16770 if (stroke){
16771 context.strokeStyle = stroke;
16772 context.lineWidth = this._strokeWidth;
16773 context.lineCap = this._strokeCap;
16774 context.lineJoin = this._strokeJoin;
16775 context.stroke();
16776 }
16777 }
16778
16779 });
16780
16781 var group = _class(node, container, {
16782
16783 initialize: function(width, height){
16784 this.width = width;
16785 this.height = height;
16786 },
16787
16788 localHitTest: function(x, y){
16789 var node = this.lastChild;
16790 while (node){
16791 var hit = node.hitTest(x, y);
16792 if (hit) return hit;
16793 node = node.previousSibling;
16794 }
16795 return null;
16796 },
16797
16798 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
16799 if (this._invisible) return;
16800
16801 x = xx * this.x + xy * this.y + x;
16802 y = yx * this.x + yy * this.y + y;
16803
16804 var t = xx;
16805 xx = t * this.xx + xy * this.yx;
16806 xy = t * this.xy + xy * this.yy;
16807 t = yx;
16808 yx = t * this.xx + yy * this.yx;
16809 yy = t * this.xy + yy * this.yy;
16810
16811 var node = this.firstChild;
16812 while (node){
16813 node.renderTo(context, xx, yx, xy, yy, x, y);
16814 node = node.nextSibling;
16815 }
16816 }
16817
16818 });
16819
16820 var clippingrectangle = _class(node, container, {
16821
16822 initialize: function(width, height){
16823 this.width = width;
16824 this.height = height;
16825 },
16826
16827 localHitTest: function(x, y) {
16828 var node = this.lastChild;
16829 while (node){
16830 var hit = node.hitTest(x, y);
16831 if (hit) return hit;
16832 node = node.previousSibling;
16833 }
16834 return null;
16835 },
16836
16837 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
16838 context.setTransform(xx, yx, xy, yy, x, y);
16839 context.save();
16840 // Need beginPath to fix Firefox bug. See 3354054.
16841 context.beginPath();
16842 context.rect(this.x, this.y, this.width, this.height);
16843 context.clip();
16844
16845 var node = this.firstChild;
16846 while(node) {
16847 node.renderTo(context, xx, yx, xy, yy, x, y);
16848 node = node.nextSibling;
16849 }
16850 context.restore();
16851 }
16852 });
16853
16854 var fontAnchors = { middle: 'center' };
16855
16856 var text = _class(base, {
16857
16858 base_initialize: base.prototype.initialize,
16859
16860 initialize: function(text, font, alignment, path){
16861 this.base_initialize();
16862 this.draw.apply(this, arguments);
16863 },
16864
16865 draw: function(text, font, alignment, path){
16866 var em;
16867 if (typeof font == 'string'){
16868 em = Number(/(\d+)/.exec(font)[0]);
16869 } else if (font){
16870 em = parseFloat(font.fontSize || font['font-size'] || '12');
16871 font = (font.fontStyle || font['font-style'] || '') + ' ' +
16872 (font.fontVariant || font['font-variant'] || '') + ' ' +
16873 (font.fontWeight || font['font-weight'] || '') + ' ' +
16874 em + 'px ' +
16875 (font.fontFamily || font['font-family'] || 'Arial');
16876 } else {
16877 font = this._font;
16878 }
16879
16880 var lines = text && text.split(/\r?\n/);
16881 this._font = font;
16882 this._fontSize = em;
16883 this._text = lines;
16884 this._alignment = fontAnchors[alignment] || alignment || 'left';
16885
16886 var context = base._genericContext;
16887
16888 context.font = this._font;
16889 context.textAlign = this._alignment;
16890 context.textBaseline = 'middle';
16891
16892 lines = this._text;
16893 var l = lines.length, width = 0;
16894 for (var i = 0; i < l; i++){
16895 var w = context.measureText(lines[i]).width;
16896 if (w > width) width = w;
16897 }
16898 this.width = width;
16899 this.height = l ? l * 1.1 * em : 0;
16900 return this.invalidate();
16901 },
16902
16903 // Interaction
16904
16905 localHitTest: function(x, y){
16906 if (!this._fill) return null;
16907 if (x > 0 && y > 0 && x < this.width && y < this.height){
16908 return this;
16909 }
16910 return null;
16911 },
16912
16913 // Rendering
16914
16915 renderShapeTo: function(context){
16916 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
16917 return null;
16918 }
16919 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
16920 var fill = this._fill,
16921 stroke = this._stroke,
16922 text = this._text,
16923 dash = this._strokeDash;
16924
16925 context.font = this._font;
16926 context.textAlign = this._alignment;
16927 context.textBaseline = 'middle';
16928
16929 var em = this._fontSize,
16930 y = em / 2,
16931 lineHeight = 1.1 * em,
16932 lines = text,
16933 l = lines.length;
16934
16935 if (fill){
16936 context.fillStyle = fill;
16937 for (var i = 0; i < l; i++)
16938 context.fillText(lines[i], 0, y + i * lineHeight);
16939 }
16940 if (stroke){
16941 if (dash) {
16942 if (context.setLineDash) {
16943 context.setLineDash(dash);
16944 } else {
16945 // TODO: Remove when FF supports setLineDash.
16946 context.mozDash = dash;
16947 }
16948 // TODO: Create fallback to other browsers.
16949 } else {
16950 if (context.setLineDash) {
16951 context.setLineDash([]);
16952 } else {
16953 context.mozDash = null;
16954 }
16955 }
16956
16957 context.strokeStyle = stroke;
16958 context.lineWidth = this._strokeWidth;
16959 context.lineCap = this._strokeCap;
16960 context.lineJoin = this._strokeJoin;
16961 for (i = 0; i < l; i++)
16962 context.strokeText(lines[i], 0, y + i * lineHeight);
16963 }
16964 }
16965
16966 });
16967
16968 var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
16969
16970 var styleSheet, styledTags = {}, styleTag = function(tag){
16971 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
16972 };
16973
16974 var init = function(document){
16975
16976 var namespaces;
16977 try { // IE9 workaround: sometimes it throws here
16978 namespaces = document.namespaces;
16979 } catch (e) {
16980 }
16981 if (!namespaces) return false;
16982
16983 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
16984 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
16985
16986 styleSheet = document.createStyleSheet();
16987 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
16988 /* styleTag('skew');
16989 styleTag('fill');
16990 styleTag('stroke');
16991 styleTag('path');
16992 styleTag('textpath');
16993 styleTag('group');*/
16994
16995 styleTag('vml');
16996
16997 return true;
16998
16999 };
17000
17001 var createElement = function(tag){
17002 if (!(tag in styledTags)) styleTag(tag);
17003 return document.createElement('av:' + tag);
17004 };
17005
17006 var dom = {
17007 init: init,
17008 createElement: createElement
17009 };
17010
17011 var precision = 100;
17012
17013 var VMLSurface = _class(native_1, container, {
17014
17015 initialize: function VMLSurface(width, height, existingElement){
17016 this.element = existingElement || document.createElement('vml');
17017 this.containerElement = dom.createElement('group');
17018 this.element.appendChild(this.containerElement);
17019 if (width != null && height != null) this.resize(width, height);
17020 },
17021
17022 resize: function(width, height){
17023 this.width = width;
17024 this.height = height;
17025
17026 var style = this.element.style;
17027 style.pixelWidth = width;
17028 style.pixelHeight = height;
17029
17030 style = this.containerElement.style;
17031 style.width = width;
17032 style.height = height;
17033
17034 var halfPixel = (0.5 * precision);
17035
17036 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
17037 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
17038
17039 return this;
17040 }
17041
17042 });
17043
17044 VMLSurface.tagName = 'av:vml';
17045
17046 var surface$1 = VMLSurface;
17047
17048 var precision$1 = 100;
17049
17050 var round = Math.round;
17051
17052 var VMLPath = _class(path, {
17053
17054 initialize: function(path){
17055 this.reset();
17056 if (path instanceof VMLPath){
17057 this.path = [Array.prototype.join.call(path.path, ' ')];
17058 } else if (path){
17059 if (path.applyToPath)
17060 path.applyToPath(this);
17061 else
17062 this.push(path);
17063 }
17064 },
17065
17066 onReset: function(){
17067 this.path = [];
17068 },
17069
17070 onMove: function(sx, sy, x, y){
17071 this.path.push('m', round(x * precision$1), round(y * precision$1));
17072 },
17073
17074 onLine: function(sx, sy, x, y){
17075 this.path.push('l', round(x * precision$1), round(y * precision$1));
17076 },
17077
17078 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
17079 this.path.push('c',
17080 round(p1x * precision$1), round(p1y * precision$1),
17081 round(p2x * precision$1), round(p2y * precision$1),
17082 round(x * precision$1), round(y * precision$1)
17083 );
17084 },
17085
17086 _arcToBezier: path.prototype.onArc,
17087
17088 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
17089 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
17090 cx *= precision$1;
17091 cy *= precision$1;
17092 rx *= precision$1;
17093 this.path.push(ccw ? 'at' : 'wa',
17094 round(cx - rx), round(cy - rx),
17095 round(cx + rx), round(cy + rx),
17096 round(sx * precision$1), round(sy * precision$1),
17097 round(ex * precision$1), round(ey * precision$1)
17098 );
17099 },
17100
17101 onClose: function(){
17102 this.path.push('x');
17103 },
17104
17105 toVML: function(){
17106 return this.path.join(' ');
17107 }
17108
17109 });
17110
17111 VMLPath.prototype.toString = VMLPath.prototype.toVML;
17112
17113 var path$2 = VMLPath;
17114
17115 var shadow = _class(dummy, native_1, {
17116
17117 dummy_inject: dummy.prototype.inject,
17118 dummy_injectBefore: dummy.prototype.injectBefore,
17119 dummy_eject: dummy.prototype.eject,
17120 native_inject: native_1.prototype.inject,
17121 native_injectBefore: native_1.prototype.injectBefore,
17122 native_eject: native_1.prototype.eject,
17123
17124 inject: function(container){
17125 this.dummy_inject(container);
17126 this.native_inject(container);
17127 return this;
17128 },
17129
17130 injectBefore: function(sibling){
17131 this.dummy_injectBefore(sibling);
17132 this.native_injectBefore(sibling);
17133 return this;
17134 },
17135
17136 eject: function(){
17137 this.dummy_eject();
17138 this.native_eject();
17139 return this;
17140 }
17141
17142 });
17143
17144 var node$1 = _class(shadow, transform, {
17145
17146 initialize: function(tag){
17147 //this.uid = uniqueID();
17148 var element = this.element = dom.createElement(tag);
17149 //element.setAttribute('id', 'e' + this.uid);
17150 },
17151
17152 _place: function(){
17153 if (this.parentNode){
17154 this._transform();
17155 }
17156 },
17157
17158 // visibility
17159
17160 hide: function(){
17161 this.element.style.display = 'none';
17162 return this;
17163 },
17164
17165 show: function(){
17166 this.element.style.display = '';
17167 return this;
17168 },
17169
17170 // interaction
17171
17172 indicate: function(cursor, tooltip){
17173 if (cursor) this.element.style.cursor = cursor;
17174 if (tooltip) this.element.title = tooltip;
17175 return this;
17176 }
17177
17178 });
17179
17180 var precision$2 = 100;
17181
17182 var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
17183
17184 var base$1 = _class(node$1, {
17185
17186 element_initialize: node$1.prototype.initialize,
17187
17188 initialize: function(tag){
17189 this.element_initialize(tag);
17190 var element = this.element;
17191
17192 var skew = this.skewElement = dom.createElement('skew');
17193 skew.on = true;
17194 element.appendChild(skew);
17195
17196 var fill = this.fillElement = dom.createElement('fill');
17197 fill.on = false;
17198 element.appendChild(fill);
17199
17200 var stroke = this.strokeElement = dom.createElement('stroke');
17201 stroke.on = false;
17202 element.appendChild(stroke);
17203 },
17204
17205 /* transform */
17206
17207 _transform: function(){
17208 var container = this.parentNode;
17209
17210 // Active Transformation Matrix
17211 var m = container ? new transform(container._activeTransform).transform(this) : this;
17212
17213 // Box in shape user space
17214
17215 var box = this._boxCoords || this._size || defaultBox;
17216
17217 var originX = box.left || 0,
17218 originY = box.top || 0,
17219 width = box.width || 1,
17220 height = box.height || 1;
17221
17222 // Flipped
17223 var flip = m.yx / m.xx > m.yy / m.xy;
17224 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
17225 flip = flip ? -1 : 1;
17226
17227 m = new transform().scale(flip, 1).transform(m);
17228
17229 // Rotation is approximated based on the transform
17230 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
17231
17232 // Reverse the rotation, leaving the final transform in box space
17233 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
17234
17235 var transform$1 = new transform(
17236 (m.xx * cos - m.xy * sin),
17237 (m.yx * cos - m.yy * sin) * flip,
17238 (m.xy * cos + m.xx * sin) * flip,
17239 (m.yy * cos + m.yx * sin)
17240 );
17241
17242 var rotationTransform = new transform().rotate(rotation, 0, 0);
17243
17244 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
17245
17246 // Scale box after reversing rotation
17247 width *= Math.abs(shapeToBox.xx);
17248 height *= Math.abs(shapeToBox.yy);
17249
17250 // Place box
17251 var left = m.x, top = m.y;
17252
17253 // Compensate for offset by center origin rotation
17254 var vx = -width / 2, vy = -height / 2;
17255 var point = rotationTransform.point(vx, vy);
17256 left -= point.x - vx;
17257 top -= point.y - vy;
17258
17259 // Adjust box position based on offset
17260 var rsm = new transform(m).moveTo(0,0);
17261 point = rsm.point(originX, originY);
17262 left += point.x;
17263 top += point.y;
17264
17265 if (flip < 0) left = -left - width;
17266
17267 // Place transformation origin
17268 var point0 = rsm.point(-originX, -originY);
17269 var point1 = rotationTransform.point(width, height);
17270 var point2 = rotationTransform.point(width, 0);
17271 var point3 = rotationTransform.point(0, height);
17272
17273 var minX = Math.min(0, point1.x, point2.x, point3.x),
17274 maxX = Math.max(0, point1.x, point2.x, point3.x),
17275 minY = Math.min(0, point1.y, point2.y, point3.y),
17276 maxY = Math.max(0, point1.y, point2.y, point3.y);
17277
17278 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
17279 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
17280
17281 // Adjust the origin
17282 point = shapeToBox.point(originX, originY);
17283 originX = point.x;
17284 originY = point.y;
17285
17286 // Scale stroke
17287 var strokeWidth = this._strokeWidth;
17288 if (strokeWidth){
17289 // Scale is the hypothenus between the two vectors
17290 // TODO: Use area calculation instead
17291 var vx = m.xx + m.xy, vy = m.yy + m.yx;
17292 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
17293 }
17294
17295 // convert to multiplied precision space
17296 originX *= precision$2;
17297 originY *= precision$2;
17298 left *= precision$2;
17299 top *= precision$2;
17300 width *= precision$2;
17301 height *= precision$2;
17302
17303 // Set box
17304 var element = this.element;
17305 element.coordorigin = originX + ',' + originY;
17306 element.coordsize = width + ',' + height;
17307 element.style.left = left + 'px';
17308 element.style.top = top + 'px';
17309 element.style.width = width;
17310 element.style.height = height;
17311 element.style.rotation = rotation.toFixed(8);
17312 element.style.flip = flip < 0 ? 'x' : '';
17313
17314 // Set transform
17315 var skew = this.skewElement;
17316 skew.matrix = [transform$1.xx.toFixed(4), transform$1.xy.toFixed(4), transform$1.yx.toFixed(4), transform$1.yy.toFixed(4), 0, 0];
17317 skew.origin = transformOriginX + ',' + transformOriginY;
17318
17319 // Set stroke
17320 this.strokeElement.weight = strokeWidth + 'px';
17321 },
17322
17323 /* styles */
17324
17325 _createGradient: function(style, stops){
17326 var fill = this.fillElement;
17327
17328 // Temporarily eject the fill from the DOM
17329 this.element.removeChild(fill);
17330
17331 fill.type = style;
17332 fill.method = 'none';
17333 fill.rotate = true;
17334
17335 var colors = [], color1, color2;
17336
17337 var addColor = function(offset, color$1){
17338 color$1 = color.detach(color$1);
17339 if (color1 == null) color1 = color2 = color$1;
17340 else color2 = color$1;
17341 colors.push(offset + ' ' + color$1[0]);
17342 };
17343
17344 // Enumerate stops, assumes offsets are enumerated in order
17345 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
17346 else for (var offset in stops) addColor(offset, stops[offset]);
17347
17348 fill.color = color1[0];
17349 fill.color2 = color2[0];
17350
17351 //if (fill.colors) fill.colors.value = colors; else
17352 fill.colors = colors;
17353
17354 // Opacity order gets flipped when color stops are specified
17355 fill.opacity = color2[1];
17356 fill['ao:opacity2'] = color1[1];
17357
17358 fill.on = true;
17359 this.element.appendChild(fill);
17360 return fill;
17361 },
17362
17363 _setColor: function(type, color$1){
17364 var element = type == 'fill' ? this.fillElement : this.strokeElement;
17365 if (color$1 == null){
17366 element.on = false;
17367 } else {
17368 color$1 = color.detach(color$1);
17369 element.color = color$1[0];
17370 element.opacity = color$1[1];
17371 element.on = true;
17372 }
17373 },
17374
17375 fill: function(color){
17376 if (arguments.length > 1){
17377 this.fillLinear(arguments);
17378 } else {
17379 this._boxCoords = defaultBox;
17380 var fill = this.fillElement;
17381 fill.type = 'solid';
17382 fill.color2 = '';
17383 fill['ao:opacity2'] = '';
17384 if (fill.colors) fill.colors.value = '';
17385 this._setColor('fill', color);
17386 }
17387 return this;
17388 },
17389
17390 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
17391 var fill = this._createGradient('gradientradial', stops);
17392 if (focusX == null) focusX = this.left + this.width * 0.5;
17393 if (focusY == null) focusY = this.top + this.height * 0.5;
17394 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
17395 if (radiusX == null) radiusX = this.width * 0.5;
17396 if (centerX == null) centerX = focusX;
17397 if (centerY == null) centerY = focusY;
17398
17399 centerX += centerX - focusX;
17400 centerY += centerY - focusY;
17401
17402 var box = this._boxCoords = {
17403 left: centerX - radiusX * 2,
17404 top: centerY - radiusY * 2,
17405 width: radiusX * 4,
17406 height: radiusY * 4
17407 };
17408 focusX -= box.left;
17409 focusY -= box.top;
17410 focusX /= box.width;
17411 focusY /= box.height;
17412
17413 fill.focussize = '0 0';
17414 fill.focusposition = focusX + ',' + focusY;
17415 fill.focus = '50%';
17416
17417 this._transform();
17418
17419 return this;
17420 },
17421
17422 fillLinear: function(stops, x1, y1, x2, y2){
17423 var fill = this._createGradient('gradient', stops);
17424 fill.focus = '100%';
17425 if (arguments.length == 5){
17426 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
17427 this._boxCoords = {
17428 left: Math.min(x1, x2),
17429 top: Math.min(y1, y2),
17430 width: w < 1 ? h : w,
17431 height: h < 1 ? w : h
17432 };
17433 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
17434 } else {
17435 this._boxCoords = null;
17436 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
17437 }
17438 this._transform();
17439 return this;
17440 },
17441
17442 fillImage: function(url, width, height, left, top, color1, color2){
17443 var fill = this.fillElement;
17444 if (color1 != null){
17445 color1 = color.detach(color1);
17446 if (color2 != null) color2 = color.detach(color2);
17447 fill.type = 'pattern';
17448 fill.color = color1[0];
17449 fill.color2 = color2 == null ? color1[0] : color2[0];
17450 fill.opacity = color2 == null ? 0 : color2[1];
17451 fill['ao:opacity2'] = color1[1];
17452 } else {
17453 fill.type = 'tile';
17454 fill.color = '';
17455 fill.color2 = '';
17456 fill.opacity = 1;
17457 fill['ao:opacity2'] = 1;
17458 }
17459 if (fill.colors) fill.colors.value = '';
17460 fill.rotate = true;
17461 fill.src = url;
17462
17463 fill.size = '1,1';
17464 fill.position = '0,0';
17465 fill.origin = '0,0';
17466 fill.aspect = 'ignore'; // ignore, atleast, atmost
17467 fill.on = true;
17468
17469 if (!left) left = 0;
17470 if (!top) top = 0;
17471 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
17472 this._transform();
17473 return this;
17474 },
17475
17476 /* stroke */
17477
17478 stroke: function(color, width, cap, join){
17479 var stroke = this.strokeElement;
17480 this._strokeWidth = (width != null) ? width : 1;
17481 stroke.weight = (width != null) ? width + 'px' : 1;
17482 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
17483 stroke.joinstyle = (join != null) ? join : 'round';
17484
17485 this._setColor('stroke', color);
17486 return this;
17487 }
17488
17489 });
17490
17491 var precision$3 = 100;
17492
17493 var shape$1 = _class(base$1, {
17494
17495 base_initialize: base$1.prototype.initialize,
17496
17497 initialize: function(path, width, height){
17498 this.base_initialize('shape');
17499
17500 var p = this.pathElement = dom.createElement('path');
17501 p.gradientshapeok = true;
17502 this.element.appendChild(p);
17503
17504 this.width = width;
17505 this.height = height;
17506
17507 if (path != null) this.draw(path);
17508 },
17509
17510 // SVG to VML
17511
17512 draw: function(path, width, height){
17513
17514 if (!(path instanceof path$2)) path = new path$2(path);
17515 this._vml = path.toVML();
17516 //this._size = path.measure();
17517
17518 if (width != null) this.width = width;
17519 if (height != null) this.height = height;
17520
17521 if (!this._boxCoords) this._transform();
17522 this._redraw(this._prefix, this._suffix);
17523
17524 return this;
17525 },
17526
17527 // radial gradient workaround
17528
17529 _redraw: function(prefix, suffix){
17530 var vml = this._vml || '';
17531
17532 this._prefix = prefix;
17533 this._suffix = suffix;
17534 if (prefix){
17535 vml = [
17536 prefix, vml, suffix,
17537 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
17538 'ns e', vml, 'nf'
17539 ].join(' ');
17540 }
17541
17542 this.element.path = vml + 'e';
17543 },
17544
17545 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
17546 var fill = this._createGradient('gradientradial', stops);
17547 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
17548 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
17549 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
17550 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
17551 if (centerX == null) centerX = focusX;
17552 if (centerY == null) centerY = focusY;
17553
17554 centerX += centerX - focusX;
17555 centerY += centerY - focusY;
17556
17557 var cx = Math.round(centerX * precision$3),
17558 cy = Math.round(centerY * precision$3),
17559
17560 rx = Math.round(radiusX * 2 * precision$3),
17561 ry = Math.round(radiusY * 2 * precision$3),
17562
17563 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
17564
17565 this._redraw(
17566 // Resolve rendering bug
17567 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
17568 // Draw an ellipse around the path to force an elliptical gradient on any shape
17569 [
17570 'm', cx, cy - ry,
17571 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
17572 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
17573 ].join(' ')
17574 );
17575
17576 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
17577
17578 fill.focusposition = '0.5,0.5';
17579 fill.focussize = '0 0';
17580 fill.focus = '50%';
17581
17582 this._transform();
17583
17584 return this;
17585 }
17586
17587 });
17588
17589 var group$1 = _class(node$1, container, {
17590
17591 element_initialize: node$1.prototype.initialize,
17592
17593 initialize: function(width, height){
17594 this.element_initialize('group');
17595 this.width = width;
17596 this.height = height;
17597 },
17598
17599 _transform: function(){
17600 var element = this.element;
17601 element.coordorigin = '0,0';
17602 element.coordsize = '1000,1000';
17603 element.style.left = 0;
17604 element.style.top = 0;
17605 element.style.width = 1000;
17606 element.style.height = 1000;
17607 element.style.rotation = 0;
17608
17609 var container = this.parentNode;
17610 this._activeTransform = container ? new transform(container._activeTransform).transform(this) : this;
17611 var node = this.firstChild;
17612 while (node){
17613 node._transform();
17614 node = node.nextSibling;
17615 }
17616 }
17617
17618 });
17619
17620 var clippingrectangle$1 = _class(node$1, container, {
17621
17622 element_initialize: node$1.prototype.initialize,
17623
17624 initialize: function(width, height){
17625 this.element_initialize('clippingrectangle');
17626 this.width = width;
17627 this.height = height;
17628 },
17629
17630 _transform: function(){
17631 var element = this.element;
17632 element.clip = true;
17633 element.coordorigin = -this.x + ',' + (-1 * this.y);
17634 element.coordsize = this.width + ',' + this.height;
17635 // IE8 doesn't like clipBottom. Don't ask me why.
17636 // element.style.clipBottom = this.height + this.y;
17637 element.style.clipLeft = this.x;
17638 element.style.clipRight = this.width + this.x;
17639 element.style.clipTop = this.y;
17640 element.style.left = -this.x;
17641 element.style.top = -this.y;
17642 element.style.width = this.width + this.x;
17643 element.style.height = this.height + this.y;
17644 element.style.rotation = 0;
17645
17646 var container = this.parentNode;
17647 this._activeTransform = container ? new transform(container._activeTransform).transform(this) : this;
17648 var node = this.firstChild;
17649 while (node){
17650 node._transform();
17651 node = node.nextSibling;
17652 }
17653 }
17654
17655 });
17656
17657 var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
17658
17659 var text$1 = _class(base$1, {
17660
17661 base_initialize: base$1.prototype.initialize,
17662
17663 initialize: function(text, font, alignment, path){
17664 this.base_initialize('shape');
17665
17666 var p = this.pathElement = dom.createElement('path');
17667 p.textpathok = true;
17668 this.element.appendChild(p);
17669
17670 p = this.textPathElement = dom.createElement("textpath");
17671 p.on = true;
17672 p.style['v-text-align'] = 'left';
17673 this.element.appendChild(p);
17674
17675 this.draw.apply(this, arguments);
17676 },
17677
17678 draw: function(text, font, alignment, path){
17679 var element = this.element,
17680 textPath = this.textPathElement,
17681 style = textPath.style;
17682
17683 textPath.string = text;
17684
17685 if (font){
17686 if (typeof font == 'string'){
17687 style.font = font;
17688 } else {
17689 for (var key in font){
17690 var ckey = key.camelCase ? key.camelCase() : key;
17691 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
17692 // NOT UNIVERSALLY SUPPORTED OPTIONS
17693 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
17694 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
17695 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
17696 else style[ckey] = font[key];
17697 }
17698 }
17699 }
17700
17701 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
17702
17703 if (path){
17704 this.currentPath = path = new path$2(path);
17705 this.element.path = path.toVML();
17706 } else if (!this.currentPath){
17707 var i = -1, offsetRows = '\n';
17708 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
17709 textPath.string = offsetRows + textPath.string;
17710 this.element.path = 'm0,0l1,0';
17711 }
17712
17713 // Measuring the bounding box is currently necessary for gradients etc.
17714
17715 // Clone element because the element is dead once it has been in the DOM
17716 element = element.cloneNode(true);
17717 style = element.style;
17718
17719 // Reset coordinates while measuring
17720 element.coordorigin = '0,0';
17721 element.coordsize = '10000,10000';
17722 style.left = '0px';
17723 style.top = '0px';
17724 style.width = '10000px';
17725 style.height = '10000px';
17726 style.rotation = 0;
17727 element.removeChild(element.firstChild); // Remove skew
17728
17729 // Inject the clone into the document
17730
17731 var canvas = new surface$1(1, 1),
17732 group = new group$1(), // Wrapping it in a group seems to alleviate some client rect weirdness
17733 body = element.ownerDocument.body;
17734
17735 canvas.inject(body);
17736 group.element.appendChild(element);
17737 group.inject(canvas);
17738
17739 var ebb = element.getBoundingClientRect(),
17740 cbb = canvas.toElement().getBoundingClientRect();
17741
17742 canvas.eject();
17743
17744 this.left = ebb.left - cbb.left;
17745 this.top = ebb.top - cbb.top;
17746 this.width = ebb.right - ebb.left;
17747 this.height = ebb.bottom - ebb.top;
17748 this.right = ebb.right - cbb.left;
17749 this.bottom = ebb.bottom - cbb.top;
17750
17751 this._transform();
17752
17753 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
17754 return this;
17755 }
17756
17757 });
17758
17759 var fastNoSideEffects = createCommonjsModule(function (module, exports) {
17760 var hasCanvas = function(){
17761
17762 var canvas = document.createElement('canvas');
17763 return canvas && !!canvas.getContext;
17764
17765 };
17766
17767 if (hasCanvas()) {
17768 exports.Surface = surface;
17769 exports.Path = path$1;
17770 exports.Shape = shape;
17771 exports.Group = group;
17772 exports.ClippingRectangle = clippingrectangle;
17773 exports.Text = text;
17774 } else {
17775 exports.Surface = surface$1;
17776 exports.Path = path$2;
17777 exports.Shape = shape$1;
17778 exports.Group = group$1;
17779 exports.ClippingRectangle = clippingrectangle$1;
17780 exports.Text = text$1;
17781
17782 var DOM = dom;
17783 if (typeof document !== 'undefined') DOM.init(document);
17784 }
17785 });
17786 var fastNoSideEffects_1 = fastNoSideEffects.Surface;
17787 var fastNoSideEffects_2 = fastNoSideEffects.Path;
17788 var fastNoSideEffects_3 = fastNoSideEffects.Shape;
17789 var fastNoSideEffects_4 = fastNoSideEffects.Group;
17790 var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
17791 var fastNoSideEffects_6 = fastNoSideEffects.Text;
17792
17793 current.setCurrent( // Change to 'art/modes/dom' for easier debugging via SVG
17794 fastNoSideEffects);
17795 /** Declarative fill-type objects; API design not finalized */
17796
17797 var slice = Array.prototype.slice;
17798
17799 var LinearGradient =
17800 /*#__PURE__*/
17801 function () {
17802 function LinearGradient(stops, x1, y1, x2, y2) {
17803 this._args = slice.call(arguments);
17804 }
17805
17806 var _proto = LinearGradient.prototype;
17807
17808 _proto.applyFill = function applyFill(node) {
17809 node.fillLinear.apply(node, this._args);
17810 };
17811
17812 return LinearGradient;
17813 }();
17814
17815 var RadialGradient =
17816 /*#__PURE__*/
17817 function () {
17818 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
17819 this._args = slice.call(arguments);
17820 }
17821
17822 var _proto2 = RadialGradient.prototype;
17823
17824 _proto2.applyFill = function applyFill(node) {
17825 node.fillRadial.apply(node, this._args);
17826 };
17827
17828 return RadialGradient;
17829 }();
17830
17831 var Pattern =
17832 /*#__PURE__*/
17833 function () {
17834 function Pattern(url, width, height, left, top) {
17835 this._args = slice.call(arguments);
17836 }
17837
17838 var _proto3 = Pattern.prototype;
17839
17840 _proto3.applyFill = function applyFill(node) {
17841 node.fillImage.apply(node, this._args);
17842 };
17843
17844 return Pattern;
17845 }();
17846 /** React Components */
17847
17848
17849 var Surface =
17850 /*#__PURE__*/
17851 function (_React$Component) {
17852 _inheritsLoose(Surface, _React$Component);
17853
17854 function Surface() {
17855 return _React$Component.apply(this, arguments) || this;
17856 }
17857
17858 var _proto4 = Surface.prototype;
17859
17860 _proto4.componentDidMount = function componentDidMount() {
17861 var _this$props = this.props,
17862 height = _this$props.height,
17863 width = _this$props.width;
17864 this._surface = current.Surface(+width, +height, this._tagRef);
17865 this._mountNode = createContainer(this._surface, LegacyRoot, false);
17866 updateContainer(this.props.children, this._mountNode, this);
17867 };
17868
17869 _proto4.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
17870 var props = this.props;
17871
17872 if (props.height !== prevProps.height || props.width !== prevProps.width) {
17873 this._surface.resize(+props.width, +props.height);
17874 }
17875
17876 updateContainer(this.props.children, this._mountNode, this);
17877
17878 if (this._surface.render) {
17879 this._surface.render();
17880 }
17881 };
17882
17883 _proto4.componentWillUnmount = function componentWillUnmount() {
17884 updateContainer(null, this._mountNode, this);
17885 };
17886
17887 _proto4.render = function render() {
17888 var _this = this;
17889
17890 // This is going to be a placeholder because we don't know what it will
17891 // actually resolve to because ART may render canvas, vml or svg tags here.
17892 // We only allow a subset of properties since others might conflict with
17893 // ART's properties.
17894 var props = this.props; // TODO: ART's Canvas Mode overrides surface title and cursor
17895
17896 var Tag = current.Surface.tagName;
17897 return React.createElement(Tag, {
17898 ref: function (ref) {
17899 return _this._tagRef = ref;
17900 },
17901 accessKey: props.accessKey,
17902 className: props.className,
17903 draggable: props.draggable,
17904 role: props.role,
17905 style: props.style,
17906 tabIndex: props.tabIndex,
17907 title: props.title
17908 });
17909 };
17910
17911 return Surface;
17912 }(React.Component);
17913
17914 var Text =
17915 /*#__PURE__*/
17916 function (_React$Component2) {
17917 _inheritsLoose(Text, _React$Component2);
17918
17919 function Text(props) {
17920 var _this2;
17921
17922 _this2 = _React$Component2.call(this, props) || this; // We allow reading these props. Ideally we could expose the Text node as
17923 // ref directly.
17924
17925 ['height', 'width', 'x', 'y'].forEach(function (key) {
17926 Object.defineProperty(_assertThisInitialized(_this2), key, {
17927 get: function () {
17928 return this._text ? this._text[key] : undefined;
17929 }
17930 });
17931 });
17932 return _this2;
17933 }
17934
17935 var _proto5 = Text.prototype;
17936
17937 _proto5.render = function render() {
17938 var _this3 = this;
17939
17940 // This means you can't have children that render into strings...
17941 var T = TYPES.TEXT;
17942 return React.createElement(T, _extends({}, this.props, {
17943 ref: function (t) {
17944 return _this3._text = t;
17945 }
17946 }), childrenAsString(this.props.children));
17947 };
17948
17949 return Text;
17950 }(React.Component);
17951
17952 injectIntoDevTools({
17953 findFiberByHostInstance: function () {
17954 return null;
17955 },
17956 bundleType: 1 ,
17957 version: ReactVersion,
17958 rendererPackageName: 'react-art'
17959 });
17960 /** API */
17961
17962 var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
17963 var Group = TYPES.GROUP;
17964 var Shape = TYPES.SHAPE;
17965 var Path = current.Path;
17966
17967 var ReactART = /*#__PURE__*/Object.freeze({
17968 __proto__: null,
17969 ClippingRectangle: ClippingRectangle,
17970 Group: Group,
17971 Shape: Shape,
17972 Path: Path,
17973 LinearGradient: LinearGradient,
17974 Pattern: Pattern,
17975 RadialGradient: RadialGradient,
17976 Surface: Surface,
17977 Text: Text,
17978 Transform: transform
17979 });
17980
17981 var reactArt = ReactART;
17982
17983 return reactArt;
17984
17985})));