UNPKG

562 kBJavaScriptView Raw
1/** @license React v16.8.6
2 * react-art.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global.ReactART = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
19
20var _assign = ReactInternals.assign;
21
22// TODO: this is special because it gets imported during build.
23
24var ReactVersion = '16.8.6';
25
26/**
27 * Use invariant() to assert state which your program assumes to be true.
28 *
29 * Provide sprintf-style format (only %s is supported) and arguments
30 * to provide information about what broke and what you were
31 * expecting.
32 *
33 * The invariant message will be stripped in production, but the invariant
34 * will remain to ensure logic does not differ in production.
35 */
36
37var validateFormat = function () {};
38
39{
40 validateFormat = function (format) {
41 if (format === undefined) {
42 throw new Error('invariant requires an error message argument');
43 }
44 };
45}
46
47function invariant(condition, format, a, b, c, d, e, f) {
48 validateFormat(format);
49
50 if (!condition) {
51 var error = void 0;
52 if (format === undefined) {
53 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
54 } else {
55 var args = [a, b, c, d, e, f];
56 var argIndex = 0;
57 error = new Error(format.replace(/%s/g, function () {
58 return args[argIndex++];
59 }));
60 error.name = 'Invariant Violation';
61 }
62
63 error.framesToPop = 1; // we don't care about invariant's own frame
64 throw error;
65 }
66}
67
68// Relying on the `invariant()` implementation lets us
69// preserve the format and params in the www builds.
70
71/**
72 * Similar to invariant but only logs a warning if the condition is not met.
73 * This can be used to log issues in development environments in critical
74 * paths. Removing the logging code for production environments will keep the
75 * same logic and follow the same code paths.
76 */
77
78var warningWithoutStack = function () {};
79
80{
81 warningWithoutStack = function (condition, format) {
82 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
83 args[_key - 2] = arguments[_key];
84 }
85
86 if (format === undefined) {
87 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
88 }
89 if (args.length > 8) {
90 // Check before the condition to catch violations early.
91 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
92 }
93 if (condition) {
94 return;
95 }
96 if (typeof console !== 'undefined') {
97 var argsWithFormat = args.map(function (item) {
98 return '' + item;
99 });
100 argsWithFormat.unshift('Warning: ' + format);
101
102 // We intentionally don't use spread (or .apply) directly because it
103 // breaks IE9: https://github.com/facebook/react/issues/13610
104 Function.prototype.apply.call(console.error, console, argsWithFormat);
105 }
106 try {
107 // --- Welcome to debugging React ---
108 // This error was thrown as a convenience so that you can use this stack
109 // to find the callsite that caused this warning to fire.
110 var argIndex = 0;
111 var message = 'Warning: ' + format.replace(/%s/g, function () {
112 return args[argIndex++];
113 });
114 throw new Error(message);
115 } catch (x) {}
116 };
117}
118
119var warningWithoutStack$1 = warningWithoutStack;
120
121/**
122 * `ReactInstanceMap` maintains a mapping from a public facing stateful
123 * instance (key) and the internal representation (value). This allows public
124 * methods to accept the user facing instance as an argument and map them back
125 * to internal methods.
126 *
127 * Note that this module is currently shared and assumed to be stateless.
128 * If this becomes an actual Map, that will break.
129 */
130
131/**
132 * This API should be called `delete` but we'd have to make sure to always
133 * transform these to strings for IE support. When this transform is fully
134 * supported we can rename it.
135 */
136
137
138function get(key) {
139 return key._reactInternalFiber;
140}
141
142
143
144function set(key, value) {
145 key._reactInternalFiber = value;
146}
147
148var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
149
150// Prevent newer renderers from RTE when used with older react package versions.
151// Current owner and dispatcher used to share the same ref,
152// but PR #14548 split them out to better support the react-debug-tools package.
153if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
154 ReactSharedInternals.ReactCurrentDispatcher = {
155 current: null
156 };
157}
158
159// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
160// nor polyfill, then a plain number is used for performance.
161var hasSymbol = typeof Symbol === 'function' && Symbol.for;
162
163var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
164var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
165var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
166var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
167var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
168var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
169var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
170
171var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
172var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
173var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
174var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
175var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
176
177var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
178var FAUX_ITERATOR_SYMBOL = '@@iterator';
179
180function getIteratorFn(maybeIterable) {
181 if (maybeIterable === null || typeof maybeIterable !== 'object') {
182 return null;
183 }
184 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
185 if (typeof maybeIterator === 'function') {
186 return maybeIterator;
187 }
188 return null;
189}
190
191var Pending = 0;
192var Resolved = 1;
193var Rejected = 2;
194
195function refineResolvedLazyComponent(lazyComponent) {
196 return lazyComponent._status === Resolved ? lazyComponent._result : null;
197}
198
199function getWrappedName(outerType, innerType, wrapperName) {
200 var functionName = innerType.displayName || innerType.name || '';
201 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
202}
203
204function getComponentName(type) {
205 if (type == null) {
206 // Host root, text node or just invalid type.
207 return null;
208 }
209 {
210 if (typeof type.tag === 'number') {
211 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
212 }
213 }
214 if (typeof type === 'function') {
215 return type.displayName || type.name || null;
216 }
217 if (typeof type === 'string') {
218 return type;
219 }
220 switch (type) {
221 case REACT_CONCURRENT_MODE_TYPE:
222 return 'ConcurrentMode';
223 case REACT_FRAGMENT_TYPE:
224 return 'Fragment';
225 case REACT_PORTAL_TYPE:
226 return 'Portal';
227 case REACT_PROFILER_TYPE:
228 return 'Profiler';
229 case REACT_STRICT_MODE_TYPE:
230 return 'StrictMode';
231 case REACT_SUSPENSE_TYPE:
232 return 'Suspense';
233 }
234 if (typeof type === 'object') {
235 switch (type.$$typeof) {
236 case REACT_CONTEXT_TYPE:
237 return 'Context.Consumer';
238 case REACT_PROVIDER_TYPE:
239 return 'Context.Provider';
240 case REACT_FORWARD_REF_TYPE:
241 return getWrappedName(type, type.render, 'ForwardRef');
242 case REACT_MEMO_TYPE:
243 return getComponentName(type.type);
244 case REACT_LAZY_TYPE:
245 {
246 var thenable = type;
247 var resolvedThenable = refineResolvedLazyComponent(thenable);
248 if (resolvedThenable) {
249 return getComponentName(resolvedThenable);
250 }
251 }
252 }
253 }
254 return null;
255}
256
257var FunctionComponent = 0;
258var ClassComponent = 1;
259var IndeterminateComponent = 2; // Before we know whether it is function or class
260var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
261var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
262var HostComponent = 5;
263var HostText = 6;
264var Fragment = 7;
265var Mode = 8;
266var ContextConsumer = 9;
267var ContextProvider = 10;
268var ForwardRef = 11;
269var Profiler = 12;
270var SuspenseComponent = 13;
271var MemoComponent = 14;
272var SimpleMemoComponent = 15;
273var LazyComponent = 16;
274var IncompleteClassComponent = 17;
275var DehydratedSuspenseComponent = 18;
276
277// Don't change these two values. They're used by React Dev Tools.
278var NoEffect = /* */0;
279var PerformedWork = /* */1;
280
281// You can change the rest (and add more).
282var Placement = /* */2;
283var Update = /* */4;
284var PlacementAndUpdate = /* */6;
285var Deletion = /* */8;
286var ContentReset = /* */16;
287var Callback = /* */32;
288var DidCapture = /* */64;
289var Ref = /* */128;
290var Snapshot = /* */256;
291var Passive = /* */512;
292
293// Passive & Update & Callback & Ref & Snapshot
294var LifecycleEffectMask = /* */932;
295
296// Union of all host effects
297var HostEffectMask = /* */1023;
298
299var Incomplete = /* */1024;
300var ShouldCapture = /* */2048;
301
302var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
303
304var MOUNTING = 1;
305var MOUNTED = 2;
306var UNMOUNTED = 3;
307
308function isFiberMountedImpl(fiber) {
309 var node = fiber;
310 if (!fiber.alternate) {
311 // If there is no alternate, this might be a new tree that isn't inserted
312 // yet. If it is, then it will have a pending insertion effect on it.
313 if ((node.effectTag & Placement) !== NoEffect) {
314 return MOUNTING;
315 }
316 while (node.return) {
317 node = node.return;
318 if ((node.effectTag & Placement) !== NoEffect) {
319 return MOUNTING;
320 }
321 }
322 } else {
323 while (node.return) {
324 node = node.return;
325 }
326 }
327 if (node.tag === HostRoot) {
328 // TODO: Check if this was a nested HostRoot when used with
329 // renderContainerIntoSubtree.
330 return MOUNTED;
331 }
332 // If we didn't hit the root, that means that we're in an disconnected tree
333 // that has been unmounted.
334 return UNMOUNTED;
335}
336
337function isFiberMounted(fiber) {
338 return isFiberMountedImpl(fiber) === MOUNTED;
339}
340
341function isMounted(component) {
342 {
343 var owner = ReactCurrentOwner.current;
344 if (owner !== null && owner.tag === ClassComponent) {
345 var ownerFiber = owner;
346 var instance = ownerFiber.stateNode;
347 !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0;
348 instance._warnedAboutRefsInRender = true;
349 }
350 }
351
352 var fiber = get(component);
353 if (!fiber) {
354 return false;
355 }
356 return isFiberMountedImpl(fiber) === MOUNTED;
357}
358
359function assertIsMounted(fiber) {
360 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
361}
362
363function findCurrentFiberUsingSlowPath(fiber) {
364 var alternate = fiber.alternate;
365 if (!alternate) {
366 // If there is no alternate, then we only need to check if it is mounted.
367 var state = isFiberMountedImpl(fiber);
368 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
369 if (state === MOUNTING) {
370 return null;
371 }
372 return fiber;
373 }
374 // If we have two possible branches, we'll walk backwards up to the root
375 // to see what path the root points to. On the way we may hit one of the
376 // special cases and we'll deal with them.
377 var a = fiber;
378 var b = alternate;
379 while (true) {
380 var parentA = a.return;
381 var parentB = parentA ? parentA.alternate : null;
382 if (!parentA || !parentB) {
383 // We're at the root.
384 break;
385 }
386
387 // If both copies of the parent fiber point to the same child, we can
388 // assume that the child is current. This happens when we bailout on low
389 // priority: the bailed out fiber's child reuses the current child.
390 if (parentA.child === parentB.child) {
391 var child = parentA.child;
392 while (child) {
393 if (child === a) {
394 // We've determined that A is the current branch.
395 assertIsMounted(parentA);
396 return fiber;
397 }
398 if (child === b) {
399 // We've determined that B is the current branch.
400 assertIsMounted(parentA);
401 return alternate;
402 }
403 child = child.sibling;
404 }
405 // We should never have an alternate for any mounting node. So the only
406 // way this could possibly happen is if this was unmounted, if at all.
407 invariant(false, 'Unable to find node on an unmounted component.');
408 }
409
410 if (a.return !== b.return) {
411 // The return pointer of A and the return pointer of B point to different
412 // fibers. We assume that return pointers never criss-cross, so A must
413 // belong to the child set of A.return, and B must belong to the child
414 // set of B.return.
415 a = parentA;
416 b = parentB;
417 } else {
418 // The return pointers point to the same fiber. We'll have to use the
419 // default, slow path: scan the child sets of each parent alternate to see
420 // which child belongs to which set.
421 //
422 // Search parent A's child set
423 var didFindChild = false;
424 var _child = parentA.child;
425 while (_child) {
426 if (_child === a) {
427 didFindChild = true;
428 a = parentA;
429 b = parentB;
430 break;
431 }
432 if (_child === b) {
433 didFindChild = true;
434 b = parentA;
435 a = parentB;
436 break;
437 }
438 _child = _child.sibling;
439 }
440 if (!didFindChild) {
441 // Search parent B's child set
442 _child = parentB.child;
443 while (_child) {
444 if (_child === a) {
445 didFindChild = true;
446 a = parentB;
447 b = parentA;
448 break;
449 }
450 if (_child === b) {
451 didFindChild = true;
452 b = parentB;
453 a = parentA;
454 break;
455 }
456 _child = _child.sibling;
457 }
458 !didFindChild ? invariant(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0;
459 }
460 }
461
462 !(a.alternate === b) ? invariant(false, 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0;
463 }
464 // If the root is not a host container, we're in a disconnected tree. I.e.
465 // unmounted.
466 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
467 if (a.stateNode.current === a) {
468 // We've determined that A is the current branch.
469 return fiber;
470 }
471 // Otherwise B has to be current branch.
472 return alternate;
473}
474
475function findCurrentHostFiber(parent) {
476 var currentParent = findCurrentFiberUsingSlowPath(parent);
477 if (!currentParent) {
478 return null;
479 }
480
481 // Next we'll drill down this component to find the first HostComponent/Text.
482 var node = currentParent;
483 while (true) {
484 if (node.tag === HostComponent || node.tag === HostText) {
485 return node;
486 } else if (node.child) {
487 node.child.return = node;
488 node = node.child;
489 continue;
490 }
491 if (node === currentParent) {
492 return null;
493 }
494 while (!node.sibling) {
495 if (!node.return || node.return === currentParent) {
496 return null;
497 }
498 node = node.return;
499 }
500 node.sibling.return = node.return;
501 node = node.sibling;
502 }
503 // Flow needs the return null here, but ESLint complains about it.
504 // eslint-disable-next-line no-unreachable
505 return null;
506}
507
508var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
509
510var _ReactInternals$Sched = ReactInternals$1.Scheduler;
511var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
512var unstable_now = _ReactInternals$Sched.unstable_now;
513var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
514var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
515var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
516var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
517var unstable_next = _ReactInternals$Sched.unstable_next;
518var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
519var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
520var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
521var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
522var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
523var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
524var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
525var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
526
527var _class = function(mixins){
528 var proto = {};
529 for (var i = 0, l = arguments.length; i < l; i++){
530 var mixin = arguments[i];
531 if (typeof mixin == 'function') mixin = mixin.prototype;
532 for (var key in mixin) proto[key] = mixin[key];
533 }
534 if (!proto.initialize) proto.initialize = function(){};
535 proto.constructor = function(a,b,c,d,e,f,g,h){
536 return new proto.initialize(a,b,c,d,e,f,g,h);
537 };
538 proto.constructor.prototype = proto.initialize.prototype = proto;
539 return proto.constructor;
540};
541
542function Transform(xx, yx, xy, yy, x, y){
543 if (xx && typeof xx == 'object'){
544 yx = xx.yx; yy = xx.yy; y = xx.y;
545 xy = xx.xy; x = xx.x; xx = xx.xx;
546 }
547 this.xx = xx == null ? 1 : xx;
548 this.yx = yx || 0;
549 this.xy = xy || 0;
550 this.yy = yy == null ? 1 : yy;
551 this.x = (x == null ? this.x : x) || 0;
552 this.y = (y == null ? this.y : y) || 0;
553 this._transform();
554 return this;
555}
556
557var transform = _class({
558
559 initialize: Transform,
560
561 _transform: function(){},
562
563 xx: 1, yx: 0, x: 0,
564 xy: 0, yy: 1, y: 0,
565
566 transform: function(xx, yx, xy, yy, x, y){
567 var m = this;
568 if (xx && typeof xx == 'object'){
569 yx = xx.yx; yy = xx.yy; y = xx.y;
570 xy = xx.xy; x = xx.x; xx = xx.xx;
571 }
572 if (!x) x = 0;
573 if (!y) y = 0;
574 return this.transformTo(
575 m.xx * xx + m.xy * yx,
576 m.yx * xx + m.yy * yx,
577 m.xx * xy + m.xy * yy,
578 m.yx * xy + m.yy * yy,
579 m.xx * x + m.xy * y + m.x,
580 m.yx * x + m.yy * y + m.y
581 );
582 },
583
584 transformTo: Transform,
585
586 translate: function(x, y){
587 return this.transform(1, 0, 0, 1, x, y);
588 },
589
590 move: function(x, y){
591 this.x += x || 0;
592 this.y += y || 0;
593 this._transform();
594 return this;
595 },
596
597 scale: function(x, y){
598 if (y == null) y = x;
599 return this.transform(x, 0, 0, y, 0, 0);
600 },
601
602 rotate: function(deg, x, y){
603 if (x == null || y == null){
604 x = (this.left || 0) + (this.width || 0) / 2;
605 y = (this.top || 0) + (this.height || 0) / 2;
606 }
607
608 var rad = deg * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
609
610 this.transform(1, 0, 0, 1, x, y);
611 var m = this;
612
613 return this.transformTo(
614 cos * m.xx - sin * m.yx,
615 sin * m.xx + cos * m.yx,
616 cos * m.xy - sin * m.yy,
617 sin * m.xy + cos * m.yy,
618 m.x,
619 m.y
620 ).transform(1, 0, 0, 1, -x, -y);
621 },
622
623 moveTo: function(x, y){
624 var m = this;
625 return this.transformTo(m.xx, m.yx, m.xy, m.yy, x, y);
626 },
627
628 rotateTo: function(deg, x, y){
629 var m = this;
630 var flip = m.yx / m.xx > m.yy / m.xy ? -1 : 1;
631 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = -flip;
632 return this.rotate(deg - Math.atan2(flip * m.yx, flip * m.xx) * 180 / Math.PI, x, y);
633 },
634
635 scaleTo: function(x, y){
636 // Normalize
637 var m = this;
638
639 var h = Math.sqrt(m.xx * m.xx + m.yx * m.yx);
640 m.xx /= h; m.yx /= h;
641
642 h = Math.sqrt(m.yy * m.yy + m.xy * m.xy);
643 m.yy /= h; m.xy /= h;
644
645 return this.scale(x, y);
646 },
647
648 resizeTo: function(width, height){
649 var w = this.width, h = this.height;
650 if (!w || !h) return this;
651 return this.scaleTo(width / w, height / h);
652 },
653
654 /*
655 inverse: function(){
656 var a = this.xx, b = this.yx,
657 c = this.xy, d = this.yy,
658 e = this.x, f = this.y;
659 if (a * d - b * c == 0) return null;
660 return new Transform(
661 d/(a * d-b * c), b/(b * c-a * d),
662 c/(b * c-a * d), a/(a * d-b * c),
663 (d * e-c * f)/(b * c-a * d), (b * e-a * f)/(a * d-b * c)
664 );
665 },
666 */
667
668 inversePoint: function(x, y){
669 var a = this.xx, b = this.yx,
670 c = this.xy, d = this.yy,
671 e = this.x, f = this.y;
672 var det = b * c - a * d;
673 if (det == 0) return null;
674 return {
675 x: (d * (e - x) + c * (y - f)) / det,
676 y: (a * (f - y) + b * (x - e)) / det
677 };
678 },
679
680 point: function(x, y){
681 var m = this;
682 return {
683 x: m.xx * x + m.xy * y + m.x,
684 y: m.yx * x + m.yy * y + m.y
685 };
686 }
687
688});
689
690var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
691
692
693
694
695
696function createCommonjsModule(fn, module) {
697 return module = { exports: {} }, fn(module, module.exports), module.exports;
698}
699
700var current = createCommonjsModule(function (module, exports) {
701function warning(){
702 throw new Error('You must require a mode before requiring anything else.');
703}
704
705exports.Surface = warning;
706exports.Path = warning;
707exports.Shape = warning;
708exports.Group = warning;
709exports.ClippingRectangle = warning;
710exports.Text = warning;
711
712exports.setCurrent = function(mode){
713 for (var key in mode){
714 exports[key] = mode[key];
715 }
716};
717});
718
719var current_1 = current.Surface;
720var current_2 = current.Path;
721var current_3 = current.Shape;
722var current_4 = current.Group;
723var current_5 = current.ClippingRectangle;
724var current_6 = current.Text;
725var current_7 = current.setCurrent;
726
727var TYPES = {
728 CLIPPING_RECTANGLE: 'ClippingRectangle',
729 GROUP: 'Group',
730 SHAPE: 'Shape',
731 TEXT: 'Text'
732};
733
734var EVENT_TYPES = {
735 onClick: 'click',
736 onMouseMove: 'mousemove',
737 onMouseOver: 'mouseover',
738 onMouseOut: 'mouseout',
739 onMouseUp: 'mouseup',
740 onMouseDown: 'mousedown'
741};
742
743function childrenAsString(children) {
744 if (!children) {
745 return '';
746 } else if (typeof children === 'string') {
747 return children;
748 } else if (children.length) {
749 return children.join('');
750 } else {
751 return '';
752 }
753}
754
755// Renderers that don't support persistence
756// can re-export everything from this module.
757
758function shim() {
759 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.');
760}
761
762// Persistence (when unsupported)
763var supportsPersistence = false;
764var cloneInstance = shim;
765var createContainerChildSet = shim;
766var appendChildToContainerChildSet = shim;
767var finalizeContainerChildren = shim;
768var replaceContainerChildren = shim;
769var cloneHiddenInstance = shim;
770var cloneUnhiddenInstance = shim;
771var createHiddenTextInstance = shim;
772
773// Renderers that don't support hydration
774// can re-export everything from this module.
775
776function shim$1() {
777 invariant(false, 'The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue.');
778}
779
780// Hydration (when unsupported)
781
782var supportsHydration = false;
783var canHydrateInstance = shim$1;
784var canHydrateTextInstance = shim$1;
785var canHydrateSuspenseInstance = shim$1;
786var getNextHydratableSibling = shim$1;
787var getFirstHydratableChild = shim$1;
788var hydrateInstance = shim$1;
789var hydrateTextInstance = shim$1;
790var getNextHydratableInstanceAfterSuspenseInstance = shim$1;
791var clearSuspenseBoundary = shim$1;
792var clearSuspenseBoundaryFromContainer = shim$1;
793var didNotMatchHydratedContainerTextInstance = shim$1;
794var didNotMatchHydratedTextInstance = shim$1;
795var didNotHydrateContainerInstance = shim$1;
796var didNotHydrateInstance = shim$1;
797var didNotFindHydratableContainerInstance = shim$1;
798var didNotFindHydratableContainerTextInstance = shim$1;
799var didNotFindHydratableContainerSuspenseInstance = shim$1;
800var didNotFindHydratableInstance = shim$1;
801var didNotFindHydratableTextInstance = shim$1;
802var didNotFindHydratableSuspenseInstance = shim$1;
803
804var pooledTransform = new transform();
805
806var NO_CONTEXT = {};
807var UPDATE_SIGNAL = {};
808{
809 Object.freeze(NO_CONTEXT);
810 Object.freeze(UPDATE_SIGNAL);
811}
812
813/** Helper Methods */
814
815function addEventListeners(instance, type, listener) {
816 // We need to explicitly unregister before unmount.
817 // For this reason we need to track subscriptions.
818 if (!instance._listeners) {
819 instance._listeners = {};
820 instance._subscriptions = {};
821 }
822
823 instance._listeners[type] = listener;
824
825 if (listener) {
826 if (!instance._subscriptions[type]) {
827 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
828 }
829 } else {
830 if (instance._subscriptions[type]) {
831 instance._subscriptions[type]();
832 delete instance._subscriptions[type];
833 }
834 }
835}
836
837function createEventHandler(instance) {
838 return function handleEvent(event) {
839 var listener = instance._listeners[event.type];
840
841 if (!listener) {
842 // Noop
843 } else if (typeof listener === 'function') {
844 listener.call(instance, event);
845 } else if (listener.handleEvent) {
846 listener.handleEvent(event);
847 }
848 };
849}
850
851function destroyEventListeners(instance) {
852 if (instance._subscriptions) {
853 for (var type in instance._subscriptions) {
854 instance._subscriptions[type]();
855 }
856 }
857
858 instance._subscriptions = null;
859 instance._listeners = null;
860}
861
862function getScaleX(props) {
863 if (props.scaleX != null) {
864 return props.scaleX;
865 } else if (props.scale != null) {
866 return props.scale;
867 } else {
868 return 1;
869 }
870}
871
872function getScaleY(props) {
873 if (props.scaleY != null) {
874 return props.scaleY;
875 } else if (props.scale != null) {
876 return props.scale;
877 } else {
878 return 1;
879 }
880}
881
882function isSameFont(oldFont, newFont) {
883 if (oldFont === newFont) {
884 return true;
885 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
886 return false;
887 } else {
888 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
889 }
890}
891
892/** Render Methods */
893
894function applyClippingRectangleProps(instance, props) {
895 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
896
897 applyNodeProps(instance, props, prevProps);
898
899 instance.width = props.width;
900 instance.height = props.height;
901}
902
903function applyGroupProps(instance, props) {
904 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
905
906 applyNodeProps(instance, props, prevProps);
907
908 instance.width = props.width;
909 instance.height = props.height;
910}
911
912function applyNodeProps(instance, props) {
913 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
914
915 var scaleX = getScaleX(props);
916 var scaleY = getScaleY(props);
917
918 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);
919
920 if (props.transform != null) {
921 pooledTransform.transform(props.transform);
922 }
923
924 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) {
925 instance.transformTo(pooledTransform);
926 }
927
928 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
929 instance.indicate(props.cursor, props.title);
930 }
931
932 if (instance.blend && props.opacity !== prevProps.opacity) {
933 instance.blend(props.opacity == null ? 1 : props.opacity);
934 }
935
936 if (props.visible !== prevProps.visible) {
937 if (props.visible == null || props.visible) {
938 instance.show();
939 } else {
940 instance.hide();
941 }
942 }
943
944 for (var type in EVENT_TYPES) {
945 addEventListeners(instance, EVENT_TYPES[type], props[type]);
946 }
947}
948
949function applyRenderableNodeProps(instance, props) {
950 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
951
952 applyNodeProps(instance, props, prevProps);
953
954 if (prevProps.fill !== props.fill) {
955 if (props.fill && props.fill.applyFill) {
956 props.fill.applyFill(instance);
957 } else {
958 instance.fill(props.fill);
959 }
960 }
961 if (prevProps.stroke !== props.stroke || prevProps.strokeWidth !== props.strokeWidth || prevProps.strokeCap !== props.strokeCap || prevProps.strokeJoin !== props.strokeJoin ||
962 // TODO: Consider deep check of stokeDash; may benefit VML in IE.
963 prevProps.strokeDash !== props.strokeDash) {
964 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
965 }
966}
967
968function applyShapeProps(instance, props) {
969 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
970
971 applyRenderableNodeProps(instance, props, prevProps);
972
973 var path = props.d || childrenAsString(props.children);
974
975 var prevDelta = instance._prevDelta;
976 var prevPath = instance._prevPath;
977
978 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
979 instance.draw(path, props.width, props.height);
980
981 instance._prevDelta = path.delta;
982 instance._prevPath = path;
983 }
984}
985
986function applyTextProps(instance, props) {
987 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
988
989 applyRenderableNodeProps(instance, props, prevProps);
990
991 var string = props.children;
992
993 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
994 instance.draw(string, props.font, props.alignment, props.path);
995
996 instance._currentString = string;
997 }
998}
999
1000function appendInitialChild(parentInstance, child) {
1001 if (typeof child === 'string') {
1002 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
1003 invariant(false, 'Text children should already be flattened.');
1004 return;
1005 }
1006
1007 child.inject(parentInstance);
1008}
1009
1010function createInstance(type, props, internalInstanceHandle) {
1011 var instance = void 0;
1012
1013 switch (type) {
1014 case TYPES.CLIPPING_RECTANGLE:
1015 instance = current.ClippingRectangle();
1016 instance._applyProps = applyClippingRectangleProps;
1017 break;
1018 case TYPES.GROUP:
1019 instance = current.Group();
1020 instance._applyProps = applyGroupProps;
1021 break;
1022 case TYPES.SHAPE:
1023 instance = current.Shape();
1024 instance._applyProps = applyShapeProps;
1025 break;
1026 case TYPES.TEXT:
1027 instance = current.Text(props.children, props.font, props.alignment, props.path);
1028 instance._applyProps = applyTextProps;
1029 break;
1030 }
1031
1032 !instance ? invariant(false, 'ReactART does not support the type "%s"', type) : void 0;
1033
1034 instance._applyProps(instance, props);
1035
1036 return instance;
1037}
1038
1039function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
1040 return text;
1041}
1042
1043function finalizeInitialChildren(domElement, type, props) {
1044 return false;
1045}
1046
1047function getPublicInstance(instance) {
1048 return instance;
1049}
1050
1051function prepareForCommit() {
1052 // Noop
1053}
1054
1055function prepareUpdate(domElement, type, oldProps, newProps) {
1056 return UPDATE_SIGNAL;
1057}
1058
1059function resetAfterCommit() {
1060 // Noop
1061}
1062
1063function resetTextContent(domElement) {
1064 // Noop
1065}
1066
1067function shouldDeprioritizeSubtree(type, props) {
1068 return false;
1069}
1070
1071function getRootHostContext() {
1072 return NO_CONTEXT;
1073}
1074
1075function getChildHostContext() {
1076 return NO_CONTEXT;
1077}
1078
1079var scheduleTimeout = setTimeout;
1080var cancelTimeout = clearTimeout;
1081var noTimeout = -1;
1082var schedulePassiveEffects = unstable_scheduleCallback;
1083var cancelPassiveEffects = unstable_cancelCallback;
1084
1085function shouldSetTextContent(type, props) {
1086 return typeof props.children === 'string' || typeof props.children === 'number';
1087}
1088
1089// The ART renderer is secondary to the React DOM renderer.
1090var isPrimaryRenderer = false;
1091
1092var supportsMutation = true;
1093
1094function appendChild(parentInstance, child) {
1095 if (child.parentNode === parentInstance) {
1096 child.eject();
1097 }
1098 child.inject(parentInstance);
1099}
1100
1101function appendChildToContainer(parentInstance, child) {
1102 if (child.parentNode === parentInstance) {
1103 child.eject();
1104 }
1105 child.inject(parentInstance);
1106}
1107
1108function insertBefore(parentInstance, child, beforeChild) {
1109 !(child !== beforeChild) ? invariant(false, 'ReactART: Can not insert node before itself') : void 0;
1110 child.injectBefore(beforeChild);
1111}
1112
1113function insertInContainerBefore(parentInstance, child, beforeChild) {
1114 !(child !== beforeChild) ? invariant(false, 'ReactART: Can not insert node before itself') : void 0;
1115 child.injectBefore(beforeChild);
1116}
1117
1118function removeChild(parentInstance, child) {
1119 destroyEventListeners(child);
1120 child.eject();
1121}
1122
1123function removeChildFromContainer(parentInstance, child) {
1124 destroyEventListeners(child);
1125 child.eject();
1126}
1127
1128
1129
1130
1131
1132function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1133 instance._applyProps(instance, newProps, oldProps);
1134}
1135
1136function hideInstance(instance) {
1137 instance.hide();
1138}
1139
1140
1141
1142function unhideInstance(instance, props) {
1143 if (props.visible == null || props.visible) {
1144 instance.show();
1145 }
1146}
1147
1148function unhideTextInstance(textInstance, text) {
1149 // Noop
1150}
1151
1152/**
1153 * Copyright (c) 2013-present, Facebook, Inc.
1154 *
1155 * This source code is licensed under the MIT license found in the
1156 * LICENSE file in the root directory of this source tree.
1157 */
1158
1159
1160
1161var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1162
1163var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
1164
1165/**
1166 * Copyright (c) 2013-present, Facebook, Inc.
1167 *
1168 * This source code is licensed under the MIT license found in the
1169 * LICENSE file in the root directory of this source tree.
1170 */
1171
1172
1173
1174var printWarning = function() {};
1175
1176{
1177 var ReactPropTypesSecret = ReactPropTypesSecret_1;
1178 var loggedTypeFailures = {};
1179
1180 printWarning = function(text) {
1181 var message = 'Warning: ' + text;
1182 if (typeof console !== 'undefined') {
1183 console.error(message);
1184 }
1185 try {
1186 // --- Welcome to debugging React ---
1187 // This error was thrown as a convenience so that you can use this stack
1188 // to find the callsite that caused this warning to fire.
1189 throw new Error(message);
1190 } catch (x) {}
1191 };
1192}
1193
1194/**
1195 * Assert that the values match with the type specs.
1196 * Error messages are memorized and will only be shown once.
1197 *
1198 * @param {object} typeSpecs Map of name to a ReactPropType
1199 * @param {object} values Runtime values that need to be type-checked
1200 * @param {string} location e.g. "prop", "context", "child context"
1201 * @param {string} componentName Name of the component for error messages.
1202 * @param {?Function} getStack Returns the component stack.
1203 * @private
1204 */
1205function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1206 {
1207 for (var typeSpecName in typeSpecs) {
1208 if (typeSpecs.hasOwnProperty(typeSpecName)) {
1209 var error;
1210 // Prop type validation may throw. In case they do, we don't want to
1211 // fail the render phase where it didn't fail before. So we log it.
1212 // After these have been cleaned up, we'll let them throw.
1213 try {
1214 // This is intentionally an invariant that gets caught. It's the same
1215 // behavior as without this statement except with a better message.
1216 if (typeof typeSpecs[typeSpecName] !== 'function') {
1217 var err = Error(
1218 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1219 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1220 );
1221 err.name = 'Invariant Violation';
1222 throw err;
1223 }
1224 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
1225 } catch (ex) {
1226 error = ex;
1227 }
1228 if (error && !(error instanceof Error)) {
1229 printWarning(
1230 (componentName || 'React class') + ': type specification of ' +
1231 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1232 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1233 'You may have forgotten to pass an argument to the type checker ' +
1234 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1235 'shape all require an argument).'
1236 );
1237
1238 }
1239 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1240 // Only monitor this failure once because there tends to be a lot of the
1241 // same error.
1242 loggedTypeFailures[error.message] = true;
1243
1244 var stack = getStack ? getStack() : '';
1245
1246 printWarning(
1247 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1248 );
1249 }
1250 }
1251 }
1252 }
1253}
1254
1255var checkPropTypes_1 = checkPropTypes;
1256
1257var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1258
1259var describeComponentFrame = function (name, source, ownerName) {
1260 var sourceInfo = '';
1261 if (source) {
1262 var path = source.fileName;
1263 var fileName = path.replace(BEFORE_SLASH_RE, '');
1264 {
1265 // In DEV, include code for a common special case:
1266 // prefer "folder/index.js" instead of just "index.js".
1267 if (/^index\./.test(fileName)) {
1268 var match = path.match(BEFORE_SLASH_RE);
1269 if (match) {
1270 var pathBeforeSlash = match[1];
1271 if (pathBeforeSlash) {
1272 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1273 fileName = folderName + '/' + fileName;
1274 }
1275 }
1276 }
1277 }
1278 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1279 } else if (ownerName) {
1280 sourceInfo = ' (created by ' + ownerName + ')';
1281 }
1282 return '\n in ' + (name || 'Unknown') + sourceInfo;
1283};
1284
1285var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1286
1287function describeFiber(fiber) {
1288 switch (fiber.tag) {
1289 case HostRoot:
1290 case HostPortal:
1291 case HostText:
1292 case Fragment:
1293 case ContextProvider:
1294 case ContextConsumer:
1295 return '';
1296 default:
1297 var owner = fiber._debugOwner;
1298 var source = fiber._debugSource;
1299 var name = getComponentName(fiber.type);
1300 var ownerName = null;
1301 if (owner) {
1302 ownerName = getComponentName(owner.type);
1303 }
1304 return describeComponentFrame(name, source, ownerName);
1305 }
1306}
1307
1308function getStackByFiberInDevAndProd(workInProgress) {
1309 var info = '';
1310 var node = workInProgress;
1311 do {
1312 info += describeFiber(node);
1313 node = node.return;
1314 } while (node);
1315 return info;
1316}
1317
1318var current$1 = null;
1319var phase = null;
1320
1321function getCurrentFiberOwnerNameInDevOrNull() {
1322 {
1323 if (current$1 === null) {
1324 return null;
1325 }
1326 var owner = current$1._debugOwner;
1327 if (owner !== null && typeof owner !== 'undefined') {
1328 return getComponentName(owner.type);
1329 }
1330 }
1331 return null;
1332}
1333
1334function getCurrentFiberStackInDev() {
1335 {
1336 if (current$1 === null) {
1337 return '';
1338 }
1339 // Safe because if current fiber exists, we are reconciling,
1340 // and it is guaranteed to be the work-in-progress version.
1341 return getStackByFiberInDevAndProd(current$1);
1342 }
1343 return '';
1344}
1345
1346function resetCurrentFiber() {
1347 {
1348 ReactDebugCurrentFrame.getCurrentStack = null;
1349 current$1 = null;
1350 phase = null;
1351 }
1352}
1353
1354function setCurrentFiber(fiber) {
1355 {
1356 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1357 current$1 = fiber;
1358 phase = null;
1359 }
1360}
1361
1362function setCurrentPhase(lifeCyclePhase) {
1363 {
1364 phase = lifeCyclePhase;
1365 }
1366}
1367
1368var enableUserTimingAPI = true;
1369
1370// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
1371var debugRenderPhaseSideEffects = false;
1372
1373// In some cases, StrictMode should also double-render lifecycles.
1374// This can be confusing for tests though,
1375// And it can be bad for performance in production.
1376// This feature flag can be used to control the behavior:
1377var debugRenderPhaseSideEffectsForStrictMode = true;
1378
1379// To preserve the "Pause on caught exceptions" behavior of the debugger, we
1380// replay the begin phase of a failed component inside invokeGuardedCallback.
1381var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
1382
1383// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
1384var warnAboutDeprecatedLifecycles = false;
1385
1386// Gather advanced timing metrics for Profiler subtrees.
1387var enableProfilerTimer = true;
1388
1389// Trace which interactions trigger each commit.
1390var enableSchedulerTracing = true;
1391
1392// Only used in www builds.
1393var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
1394
1395// Only used in www builds.
1396
1397
1398// Only used in www builds.
1399
1400
1401// React Fire: prevent the value and checked attributes from syncing
1402// with their related DOM properties
1403
1404
1405// These APIs will no longer be "unstable" in the upcoming 16.7 release,
1406// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
1407
1408// Prefix measurements so that it's possible to filter them.
1409// Longer prefixes are hard to read in DevTools.
1410var reactEmoji = '\u269B';
1411var warningEmoji = '\u26D4';
1412var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
1413
1414// Keep track of current fiber so that we know the path to unwind on pause.
1415// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1416var currentFiber = null;
1417// If we're in the middle of user code, which fiber and method is it?
1418// Reusing `currentFiber` would be confusing for this because user code fiber
1419// can change during commit phase too, but we don't need to unwind it (since
1420// lifecycles in the commit phase don't resemble a tree).
1421var currentPhase = null;
1422var currentPhaseFiber = null;
1423// Did lifecycle hook schedule an update? This is often a performance problem,
1424// so we will keep track of it, and include it in the report.
1425// Track commits caused by cascading updates.
1426var isCommitting = false;
1427var hasScheduledUpdateInCurrentCommit = false;
1428var hasScheduledUpdateInCurrentPhase = false;
1429var commitCountInCurrentWorkLoop = 0;
1430var effectCountInCurrentCommit = 0;
1431var isWaitingForCallback = false;
1432// During commits, we only show a measurement once per method name
1433// to avoid stretch the commit phase with measurement overhead.
1434var labelsInCurrentCommit = new Set();
1435
1436var formatMarkName = function (markName) {
1437 return reactEmoji + ' ' + markName;
1438};
1439
1440var formatLabel = function (label, warning) {
1441 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
1442 var suffix = warning ? ' Warning: ' + warning : '';
1443 return '' + prefix + label + suffix;
1444};
1445
1446var beginMark = function (markName) {
1447 performance.mark(formatMarkName(markName));
1448};
1449
1450var clearMark = function (markName) {
1451 performance.clearMarks(formatMarkName(markName));
1452};
1453
1454var endMark = function (label, markName, warning) {
1455 var formattedMarkName = formatMarkName(markName);
1456 var formattedLabel = formatLabel(label, warning);
1457 try {
1458 performance.measure(formattedLabel, formattedMarkName);
1459 } catch (err) {}
1460 // If previous mark was missing for some reason, this will throw.
1461 // This could only happen if React crashed in an unexpected place earlier.
1462 // Don't pile on with more errors.
1463
1464 // Clear marks immediately to avoid growing buffer.
1465 performance.clearMarks(formattedMarkName);
1466 performance.clearMeasures(formattedLabel);
1467};
1468
1469var getFiberMarkName = function (label, debugID) {
1470 return label + ' (#' + debugID + ')';
1471};
1472
1473var getFiberLabel = function (componentName, isMounted, phase) {
1474 if (phase === null) {
1475 // These are composite component total time measurements.
1476 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
1477 } else {
1478 // Composite component methods.
1479 return componentName + '.' + phase;
1480 }
1481};
1482
1483var beginFiberMark = function (fiber, phase) {
1484 var componentName = getComponentName(fiber.type) || 'Unknown';
1485 var debugID = fiber._debugID;
1486 var isMounted = fiber.alternate !== null;
1487 var label = getFiberLabel(componentName, isMounted, phase);
1488
1489 if (isCommitting && labelsInCurrentCommit.has(label)) {
1490 // During the commit phase, we don't show duplicate labels because
1491 // there is a fixed overhead for every measurement, and we don't
1492 // want to stretch the commit phase beyond necessary.
1493 return false;
1494 }
1495 labelsInCurrentCommit.add(label);
1496
1497 var markName = getFiberMarkName(label, debugID);
1498 beginMark(markName);
1499 return true;
1500};
1501
1502var clearFiberMark = function (fiber, phase) {
1503 var componentName = getComponentName(fiber.type) || 'Unknown';
1504 var debugID = fiber._debugID;
1505 var isMounted = fiber.alternate !== null;
1506 var label = getFiberLabel(componentName, isMounted, phase);
1507 var markName = getFiberMarkName(label, debugID);
1508 clearMark(markName);
1509};
1510
1511var endFiberMark = function (fiber, phase, warning) {
1512 var componentName = getComponentName(fiber.type) || 'Unknown';
1513 var debugID = fiber._debugID;
1514 var isMounted = fiber.alternate !== null;
1515 var label = getFiberLabel(componentName, isMounted, phase);
1516 var markName = getFiberMarkName(label, debugID);
1517 endMark(label, markName, warning);
1518};
1519
1520var shouldIgnoreFiber = function (fiber) {
1521 // Host components should be skipped in the timeline.
1522 // We could check typeof fiber.type, but does this work with RN?
1523 switch (fiber.tag) {
1524 case HostRoot:
1525 case HostComponent:
1526 case HostText:
1527 case HostPortal:
1528 case Fragment:
1529 case ContextProvider:
1530 case ContextConsumer:
1531 case Mode:
1532 return true;
1533 default:
1534 return false;
1535 }
1536};
1537
1538var clearPendingPhaseMeasurement = function () {
1539 if (currentPhase !== null && currentPhaseFiber !== null) {
1540 clearFiberMark(currentPhaseFiber, currentPhase);
1541 }
1542 currentPhaseFiber = null;
1543 currentPhase = null;
1544 hasScheduledUpdateInCurrentPhase = false;
1545};
1546
1547var pauseTimers = function () {
1548 // Stops all currently active measurements so that they can be resumed
1549 // if we continue in a later deferred loop from the same unit of work.
1550 var fiber = currentFiber;
1551 while (fiber) {
1552 if (fiber._debugIsCurrentlyTiming) {
1553 endFiberMark(fiber, null, null);
1554 }
1555 fiber = fiber.return;
1556 }
1557};
1558
1559var resumeTimersRecursively = function (fiber) {
1560 if (fiber.return !== null) {
1561 resumeTimersRecursively(fiber.return);
1562 }
1563 if (fiber._debugIsCurrentlyTiming) {
1564 beginFiberMark(fiber, null);
1565 }
1566};
1567
1568var resumeTimers = function () {
1569 // Resumes all measurements that were active during the last deferred loop.
1570 if (currentFiber !== null) {
1571 resumeTimersRecursively(currentFiber);
1572 }
1573};
1574
1575function recordEffect() {
1576 if (enableUserTimingAPI) {
1577 effectCountInCurrentCommit++;
1578 }
1579}
1580
1581function recordScheduleUpdate() {
1582 if (enableUserTimingAPI) {
1583 if (isCommitting) {
1584 hasScheduledUpdateInCurrentCommit = true;
1585 }
1586 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1587 hasScheduledUpdateInCurrentPhase = true;
1588 }
1589 }
1590}
1591
1592function startRequestCallbackTimer() {
1593 if (enableUserTimingAPI) {
1594 if (supportsUserTiming && !isWaitingForCallback) {
1595 isWaitingForCallback = true;
1596 beginMark('(Waiting for async callback...)');
1597 }
1598 }
1599}
1600
1601function stopRequestCallbackTimer(didExpire, expirationTime) {
1602 if (enableUserTimingAPI) {
1603 if (supportsUserTiming) {
1604 isWaitingForCallback = false;
1605 var warning = didExpire ? 'React was blocked by main thread' : null;
1606 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
1607 }
1608 }
1609}
1610
1611function startWorkTimer(fiber) {
1612 if (enableUserTimingAPI) {
1613 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1614 return;
1615 }
1616 // If we pause, this is the fiber to unwind from.
1617 currentFiber = fiber;
1618 if (!beginFiberMark(fiber, null)) {
1619 return;
1620 }
1621 fiber._debugIsCurrentlyTiming = true;
1622 }
1623}
1624
1625function cancelWorkTimer(fiber) {
1626 if (enableUserTimingAPI) {
1627 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1628 return;
1629 }
1630 // Remember we shouldn't complete measurement for this fiber.
1631 // Otherwise flamechart will be deep even for small updates.
1632 fiber._debugIsCurrentlyTiming = false;
1633 clearFiberMark(fiber, null);
1634 }
1635}
1636
1637function stopWorkTimer(fiber) {
1638 if (enableUserTimingAPI) {
1639 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1640 return;
1641 }
1642 // If we pause, its parent is the fiber to unwind from.
1643 currentFiber = fiber.return;
1644 if (!fiber._debugIsCurrentlyTiming) {
1645 return;
1646 }
1647 fiber._debugIsCurrentlyTiming = false;
1648 endFiberMark(fiber, null, null);
1649 }
1650}
1651
1652function stopFailedWorkTimer(fiber) {
1653 if (enableUserTimingAPI) {
1654 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1655 return;
1656 }
1657 // If we pause, its parent is the fiber to unwind from.
1658 currentFiber = fiber.return;
1659 if (!fiber._debugIsCurrentlyTiming) {
1660 return;
1661 }
1662 fiber._debugIsCurrentlyTiming = false;
1663 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1664 endFiberMark(fiber, null, warning);
1665 }
1666}
1667
1668function startPhaseTimer(fiber, phase) {
1669 if (enableUserTimingAPI) {
1670 if (!supportsUserTiming) {
1671 return;
1672 }
1673 clearPendingPhaseMeasurement();
1674 if (!beginFiberMark(fiber, phase)) {
1675 return;
1676 }
1677 currentPhaseFiber = fiber;
1678 currentPhase = phase;
1679 }
1680}
1681
1682function stopPhaseTimer() {
1683 if (enableUserTimingAPI) {
1684 if (!supportsUserTiming) {
1685 return;
1686 }
1687 if (currentPhase !== null && currentPhaseFiber !== null) {
1688 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1689 endFiberMark(currentPhaseFiber, currentPhase, warning);
1690 }
1691 currentPhase = null;
1692 currentPhaseFiber = null;
1693 }
1694}
1695
1696function startWorkLoopTimer(nextUnitOfWork) {
1697 if (enableUserTimingAPI) {
1698 currentFiber = nextUnitOfWork;
1699 if (!supportsUserTiming) {
1700 return;
1701 }
1702 commitCountInCurrentWorkLoop = 0;
1703 // This is top level call.
1704 // Any other measurements are performed within.
1705 beginMark('(React Tree Reconciliation)');
1706 // Resume any measurements that were in progress during the last loop.
1707 resumeTimers();
1708 }
1709}
1710
1711function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1712 if (enableUserTimingAPI) {
1713 if (!supportsUserTiming) {
1714 return;
1715 }
1716 var warning = null;
1717 if (interruptedBy !== null) {
1718 if (interruptedBy.tag === HostRoot) {
1719 warning = 'A top-level update interrupted the previous render';
1720 } else {
1721 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1722 warning = 'An update to ' + componentName + ' interrupted the previous render';
1723 }
1724 } else if (commitCountInCurrentWorkLoop > 1) {
1725 warning = 'There were cascading updates';
1726 }
1727 commitCountInCurrentWorkLoop = 0;
1728 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
1729 // Pause any measurements until the next loop.
1730 pauseTimers();
1731 endMark(label, '(React Tree Reconciliation)', warning);
1732 }
1733}
1734
1735function startCommitTimer() {
1736 if (enableUserTimingAPI) {
1737 if (!supportsUserTiming) {
1738 return;
1739 }
1740 isCommitting = true;
1741 hasScheduledUpdateInCurrentCommit = false;
1742 labelsInCurrentCommit.clear();
1743 beginMark('(Committing Changes)');
1744 }
1745}
1746
1747function stopCommitTimer() {
1748 if (enableUserTimingAPI) {
1749 if (!supportsUserTiming) {
1750 return;
1751 }
1752
1753 var warning = null;
1754 if (hasScheduledUpdateInCurrentCommit) {
1755 warning = 'Lifecycle hook scheduled a cascading update';
1756 } else if (commitCountInCurrentWorkLoop > 0) {
1757 warning = 'Caused by a cascading update in earlier commit';
1758 }
1759 hasScheduledUpdateInCurrentCommit = false;
1760 commitCountInCurrentWorkLoop++;
1761 isCommitting = false;
1762 labelsInCurrentCommit.clear();
1763
1764 endMark('(Committing Changes)', '(Committing Changes)', warning);
1765 }
1766}
1767
1768function startCommitSnapshotEffectsTimer() {
1769 if (enableUserTimingAPI) {
1770 if (!supportsUserTiming) {
1771 return;
1772 }
1773 effectCountInCurrentCommit = 0;
1774 beginMark('(Committing Snapshot Effects)');
1775 }
1776}
1777
1778function stopCommitSnapshotEffectsTimer() {
1779 if (enableUserTimingAPI) {
1780 if (!supportsUserTiming) {
1781 return;
1782 }
1783 var count = effectCountInCurrentCommit;
1784 effectCountInCurrentCommit = 0;
1785 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
1786 }
1787}
1788
1789function startCommitHostEffectsTimer() {
1790 if (enableUserTimingAPI) {
1791 if (!supportsUserTiming) {
1792 return;
1793 }
1794 effectCountInCurrentCommit = 0;
1795 beginMark('(Committing Host Effects)');
1796 }
1797}
1798
1799function stopCommitHostEffectsTimer() {
1800 if (enableUserTimingAPI) {
1801 if (!supportsUserTiming) {
1802 return;
1803 }
1804 var count = effectCountInCurrentCommit;
1805 effectCountInCurrentCommit = 0;
1806 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
1807 }
1808}
1809
1810function startCommitLifeCyclesTimer() {
1811 if (enableUserTimingAPI) {
1812 if (!supportsUserTiming) {
1813 return;
1814 }
1815 effectCountInCurrentCommit = 0;
1816 beginMark('(Calling Lifecycle Methods)');
1817 }
1818}
1819
1820function stopCommitLifeCyclesTimer() {
1821 if (enableUserTimingAPI) {
1822 if (!supportsUserTiming) {
1823 return;
1824 }
1825 var count = effectCountInCurrentCommit;
1826 effectCountInCurrentCommit = 0;
1827 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
1828 }
1829}
1830
1831var valueStack = [];
1832
1833var fiberStack = void 0;
1834
1835{
1836 fiberStack = [];
1837}
1838
1839var index = -1;
1840
1841function createCursor(defaultValue) {
1842 return {
1843 current: defaultValue
1844 };
1845}
1846
1847function pop(cursor, fiber) {
1848 if (index < 0) {
1849 {
1850 warningWithoutStack$1(false, 'Unexpected pop.');
1851 }
1852 return;
1853 }
1854
1855 {
1856 if (fiber !== fiberStack[index]) {
1857 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
1858 }
1859 }
1860
1861 cursor.current = valueStack[index];
1862
1863 valueStack[index] = null;
1864
1865 {
1866 fiberStack[index] = null;
1867 }
1868
1869 index--;
1870}
1871
1872function push(cursor, value, fiber) {
1873 index++;
1874
1875 valueStack[index] = cursor.current;
1876
1877 {
1878 fiberStack[index] = fiber;
1879 }
1880
1881 cursor.current = value;
1882}
1883
1884function checkThatStackIsEmpty() {
1885 {
1886 if (index !== -1) {
1887 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
1888 }
1889 }
1890}
1891
1892function resetStackAfterFatalErrorInDev() {
1893 {
1894 index = -1;
1895 valueStack.length = 0;
1896 fiberStack.length = 0;
1897 }
1898}
1899
1900var warnedAboutMissingGetChildContext = void 0;
1901
1902{
1903 warnedAboutMissingGetChildContext = {};
1904}
1905
1906var emptyContextObject = {};
1907{
1908 Object.freeze(emptyContextObject);
1909}
1910
1911// A cursor to the current merged context object on the stack.
1912var contextStackCursor = createCursor(emptyContextObject);
1913// A cursor to a boolean indicating whether the context has changed.
1914var didPerformWorkStackCursor = createCursor(false);
1915// Keep track of the previous context object that was on the stack.
1916// We use this to get access to the parent context after we have already
1917// pushed the next context provider, and now need to merge their contexts.
1918var previousContext = emptyContextObject;
1919
1920function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1921 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1922 // If the fiber is a context provider itself, when we read its context
1923 // we may have already pushed its own child context on the stack. A context
1924 // provider should not "see" its own child context. Therefore we read the
1925 // previous (parent) context instead for a context provider.
1926 return previousContext;
1927 }
1928 return contextStackCursor.current;
1929}
1930
1931function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1932 var instance = workInProgress.stateNode;
1933 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1934 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1935}
1936
1937function getMaskedContext(workInProgress, unmaskedContext) {
1938 var type = workInProgress.type;
1939 var contextTypes = type.contextTypes;
1940 if (!contextTypes) {
1941 return emptyContextObject;
1942 }
1943
1944 // Avoid recreating masked context unless unmasked context has changed.
1945 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1946 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1947 var instance = workInProgress.stateNode;
1948 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1949 return instance.__reactInternalMemoizedMaskedChildContext;
1950 }
1951
1952 var context = {};
1953 for (var key in contextTypes) {
1954 context[key] = unmaskedContext[key];
1955 }
1956
1957 {
1958 var name = getComponentName(type) || 'Unknown';
1959 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1960 }
1961
1962 // Cache unmasked context so we can avoid recreating masked context unless necessary.
1963 // Context is created before the class component is instantiated so check for instance.
1964 if (instance) {
1965 cacheContext(workInProgress, unmaskedContext, context);
1966 }
1967
1968 return context;
1969}
1970
1971function hasContextChanged() {
1972 return didPerformWorkStackCursor.current;
1973}
1974
1975function isContextProvider(type) {
1976 var childContextTypes = type.childContextTypes;
1977 return childContextTypes !== null && childContextTypes !== undefined;
1978}
1979
1980function popContext(fiber) {
1981 pop(didPerformWorkStackCursor, fiber);
1982 pop(contextStackCursor, fiber);
1983}
1984
1985function popTopLevelContextObject(fiber) {
1986 pop(didPerformWorkStackCursor, fiber);
1987 pop(contextStackCursor, fiber);
1988}
1989
1990function pushTopLevelContextObject(fiber, context, didChange) {
1991 !(contextStackCursor.current === emptyContextObject) ? invariant(false, 'Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.') : void 0;
1992
1993 push(contextStackCursor, context, fiber);
1994 push(didPerformWorkStackCursor, didChange, fiber);
1995}
1996
1997function processChildContext(fiber, type, parentContext) {
1998 var instance = fiber.stateNode;
1999 var childContextTypes = type.childContextTypes;
2000
2001 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
2002 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
2003 if (typeof instance.getChildContext !== 'function') {
2004 {
2005 var componentName = getComponentName(type) || 'Unknown';
2006
2007 if (!warnedAboutMissingGetChildContext[componentName]) {
2008 warnedAboutMissingGetChildContext[componentName] = true;
2009 warningWithoutStack$1(false, '%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
2010 }
2011 }
2012 return parentContext;
2013 }
2014
2015 var childContext = void 0;
2016 {
2017 setCurrentPhase('getChildContext');
2018 }
2019 startPhaseTimer(fiber, 'getChildContext');
2020 childContext = instance.getChildContext();
2021 stopPhaseTimer();
2022 {
2023 setCurrentPhase(null);
2024 }
2025 for (var contextKey in childContext) {
2026 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
2027 }
2028 {
2029 var name = getComponentName(type) || 'Unknown';
2030 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
2031 // In practice, there is one case in which we won't get a stack. It's when
2032 // somebody calls unstable_renderSubtreeIntoContainer() and we process
2033 // context from the parent component instance. The stack will be missing
2034 // because it's outside of the reconciliation, and so the pointer has not
2035 // been set. This is rare and doesn't matter. We'll also remove that API.
2036 getCurrentFiberStackInDev);
2037 }
2038
2039 return _assign({}, parentContext, childContext);
2040}
2041
2042function pushContextProvider(workInProgress) {
2043 var instance = workInProgress.stateNode;
2044 // We push the context as early as possible to ensure stack integrity.
2045 // If the instance does not exist yet, we will push null at first,
2046 // and replace it on the stack later when invalidating the context.
2047 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
2048
2049 // Remember the parent context so we can merge with it later.
2050 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2051 previousContext = contextStackCursor.current;
2052 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2053 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2054
2055 return true;
2056}
2057
2058function invalidateContextProvider(workInProgress, type, didChange) {
2059 var instance = workInProgress.stateNode;
2060 !instance ? invariant(false, 'Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.') : void 0;
2061
2062 if (didChange) {
2063 // Merge parent and own context.
2064 // Skip this if we're not updating due to sCU.
2065 // This avoids unnecessarily recomputing memoized values.
2066 var mergedContext = processChildContext(workInProgress, type, previousContext);
2067 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
2068
2069 // Replace the old (or empty) context with the new one.
2070 // It is important to unwind the context in the reverse order.
2071 pop(didPerformWorkStackCursor, workInProgress);
2072 pop(contextStackCursor, workInProgress);
2073 // Now push the new context and mark that it has changed.
2074 push(contextStackCursor, mergedContext, workInProgress);
2075 push(didPerformWorkStackCursor, didChange, workInProgress);
2076 } else {
2077 pop(didPerformWorkStackCursor, workInProgress);
2078 push(didPerformWorkStackCursor, didChange, workInProgress);
2079 }
2080}
2081
2082function findCurrentUnmaskedContext(fiber) {
2083 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2084 // makes sense elsewhere
2085 !(isFiberMounted(fiber) && fiber.tag === ClassComponent) ? invariant(false, 'Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.') : void 0;
2086
2087 var node = fiber;
2088 do {
2089 switch (node.tag) {
2090 case HostRoot:
2091 return node.stateNode.context;
2092 case ClassComponent:
2093 {
2094 var Component = node.type;
2095 if (isContextProvider(Component)) {
2096 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2097 }
2098 break;
2099 }
2100 }
2101 node = node.return;
2102 } while (node !== null);
2103 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
2104}
2105
2106var onCommitFiberRoot = null;
2107var onCommitFiberUnmount = null;
2108var hasLoggedError = false;
2109
2110function catchErrors(fn) {
2111 return function (arg) {
2112 try {
2113 return fn(arg);
2114 } catch (err) {
2115 if (true && !hasLoggedError) {
2116 hasLoggedError = true;
2117 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
2118 }
2119 }
2120 };
2121}
2122
2123var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
2124
2125function injectInternals(internals) {
2126 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
2127 // No DevTools
2128 return false;
2129 }
2130 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
2131 if (hook.isDisabled) {
2132 // This isn't a real property on the hook, but it can be set to opt out
2133 // of DevTools integration and associated warnings and logs.
2134 // https://github.com/facebook/react/issues/3877
2135 return true;
2136 }
2137 if (!hook.supportsFiber) {
2138 {
2139 warningWithoutStack$1(false, 'The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools');
2140 }
2141 // DevTools exists, even though it doesn't support Fiber.
2142 return true;
2143 }
2144 try {
2145 var rendererID = hook.inject(internals);
2146 // We have successfully injected, so now it is safe to set up hooks.
2147 onCommitFiberRoot = catchErrors(function (root) {
2148 return hook.onCommitFiberRoot(rendererID, root);
2149 });
2150 onCommitFiberUnmount = catchErrors(function (fiber) {
2151 return hook.onCommitFiberUnmount(rendererID, fiber);
2152 });
2153 } catch (err) {
2154 // Catch all errors because it is unsafe to throw during initialization.
2155 {
2156 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
2157 }
2158 }
2159 // DevTools exists
2160 return true;
2161}
2162
2163function onCommitRoot(root) {
2164 if (typeof onCommitFiberRoot === 'function') {
2165 onCommitFiberRoot(root);
2166 }
2167}
2168
2169function onCommitUnmount(fiber) {
2170 if (typeof onCommitFiberUnmount === 'function') {
2171 onCommitFiberUnmount(fiber);
2172 }
2173}
2174
2175// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2176// Math.pow(2, 30) - 1
2177// 0b111111111111111111111111111111
2178var maxSigned31BitInt = 1073741823;
2179
2180var NoWork = 0;
2181var Never = 1;
2182var Sync = maxSigned31BitInt;
2183
2184var UNIT_SIZE = 10;
2185var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
2186
2187// 1 unit of expiration time represents 10ms.
2188function msToExpirationTime(ms) {
2189 // Always add an offset so that we don't clash with the magic number for NoWork.
2190 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2191}
2192
2193function expirationTimeToMs(expirationTime) {
2194 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2195}
2196
2197function ceiling(num, precision) {
2198 return ((num / precision | 0) + 1) * precision;
2199}
2200
2201function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2202 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2203}
2204
2205var LOW_PRIORITY_EXPIRATION = 5000;
2206var LOW_PRIORITY_BATCH_SIZE = 250;
2207
2208function computeAsyncExpiration(currentTime) {
2209 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2210}
2211
2212// We intentionally set a higher expiration time for interactive updates in
2213// dev than in production.
2214//
2215// If the main thread is being blocked so long that you hit the expiration,
2216// it's a problem that could be solved with better scheduling.
2217//
2218// People will be more likely to notice this and fix it with the long
2219// expiration time in development.
2220//
2221// In production we opt for better UX at the risk of masking scheduling
2222// problems, by expiring fast.
2223var HIGH_PRIORITY_EXPIRATION = 500;
2224var HIGH_PRIORITY_BATCH_SIZE = 100;
2225
2226function computeInteractiveExpiration(currentTime) {
2227 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2228}
2229
2230var NoContext = 0;
2231var ConcurrentMode = 1;
2232var StrictMode = 2;
2233var ProfileMode = 4;
2234
2235var hasBadMapPolyfill = void 0;
2236
2237{
2238 hasBadMapPolyfill = false;
2239 try {
2240 var nonExtensibleObject = Object.preventExtensions({});
2241 var testMap = new Map([[nonExtensibleObject, null]]);
2242 var testSet = new Set([nonExtensibleObject]);
2243 // This is necessary for Rollup to not consider these unused.
2244 // https://github.com/rollup/rollup/issues/1771
2245 // TODO: we can remove these if Rollup fixes the bug.
2246 testMap.set(0, 0);
2247 testSet.add(0);
2248 } catch (e) {
2249 // TODO: Consider warning about bad polyfills
2250 hasBadMapPolyfill = true;
2251 }
2252}
2253
2254// A Fiber is work on a Component that needs to be done or was done. There can
2255// be more than one per component.
2256
2257
2258var debugCounter = void 0;
2259
2260{
2261 debugCounter = 1;
2262}
2263
2264function FiberNode(tag, pendingProps, key, mode) {
2265 // Instance
2266 this.tag = tag;
2267 this.key = key;
2268 this.elementType = null;
2269 this.type = null;
2270 this.stateNode = null;
2271
2272 // Fiber
2273 this.return = null;
2274 this.child = null;
2275 this.sibling = null;
2276 this.index = 0;
2277
2278 this.ref = null;
2279
2280 this.pendingProps = pendingProps;
2281 this.memoizedProps = null;
2282 this.updateQueue = null;
2283 this.memoizedState = null;
2284 this.contextDependencies = null;
2285
2286 this.mode = mode;
2287
2288 // Effects
2289 this.effectTag = NoEffect;
2290 this.nextEffect = null;
2291
2292 this.firstEffect = null;
2293 this.lastEffect = null;
2294
2295 this.expirationTime = NoWork;
2296 this.childExpirationTime = NoWork;
2297
2298 this.alternate = null;
2299
2300 if (enableProfilerTimer) {
2301 // Note: The following is done to avoid a v8 performance cliff.
2302 //
2303 // Initializing the fields below to smis and later updating them with
2304 // double values will cause Fibers to end up having separate shapes.
2305 // This behavior/bug has something to do with Object.preventExtension().
2306 // Fortunately this only impacts DEV builds.
2307 // Unfortunately it makes React unusably slow for some applications.
2308 // To work around this, initialize the fields below with doubles.
2309 //
2310 // Learn more about this here:
2311 // https://github.com/facebook/react/issues/14365
2312 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
2313 this.actualDuration = Number.NaN;
2314 this.actualStartTime = Number.NaN;
2315 this.selfBaseDuration = Number.NaN;
2316 this.treeBaseDuration = Number.NaN;
2317
2318 // It's okay to replace the initial doubles with smis after initialization.
2319 // This won't trigger the performance cliff mentioned above,
2320 // and it simplifies other profiler code (including DevTools).
2321 this.actualDuration = 0;
2322 this.actualStartTime = -1;
2323 this.selfBaseDuration = 0;
2324 this.treeBaseDuration = 0;
2325 }
2326
2327 {
2328 this._debugID = debugCounter++;
2329 this._debugSource = null;
2330 this._debugOwner = null;
2331 this._debugIsCurrentlyTiming = false;
2332 this._debugHookTypes = null;
2333 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
2334 Object.preventExtensions(this);
2335 }
2336 }
2337}
2338
2339// This is a constructor function, rather than a POJO constructor, still
2340// please ensure we do the following:
2341// 1) Nobody should add any instance methods on this. Instance methods can be
2342// more difficult to predict when they get optimized and they are almost
2343// never inlined properly in static compilers.
2344// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
2345// always know when it is a fiber.
2346// 3) We might want to experiment with using numeric keys since they are easier
2347// to optimize in a non-JIT environment.
2348// 4) We can easily go from a constructor to a createFiber object literal if that
2349// is faster.
2350// 5) It should be easy to port this to a C struct and keep a C implementation
2351// compatible.
2352var createFiber = function (tag, pendingProps, key, mode) {
2353 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
2354 return new FiberNode(tag, pendingProps, key, mode);
2355};
2356
2357function shouldConstruct(Component) {
2358 var prototype = Component.prototype;
2359 return !!(prototype && prototype.isReactComponent);
2360}
2361
2362function isSimpleFunctionComponent(type) {
2363 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
2364}
2365
2366function resolveLazyComponentTag(Component) {
2367 if (typeof Component === 'function') {
2368 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
2369 } else if (Component !== undefined && Component !== null) {
2370 var $$typeof = Component.$$typeof;
2371 if ($$typeof === REACT_FORWARD_REF_TYPE) {
2372 return ForwardRef;
2373 }
2374 if ($$typeof === REACT_MEMO_TYPE) {
2375 return MemoComponent;
2376 }
2377 }
2378 return IndeterminateComponent;
2379}
2380
2381// This is used to create an alternate fiber to do work on.
2382function createWorkInProgress(current, pendingProps, expirationTime) {
2383 var workInProgress = current.alternate;
2384 if (workInProgress === null) {
2385 // We use a double buffering pooling technique because we know that we'll
2386 // only ever need at most two versions of a tree. We pool the "other" unused
2387 // node that we're free to reuse. This is lazily created to avoid allocating
2388 // extra objects for things that are never updated. It also allow us to
2389 // reclaim the extra memory if needed.
2390 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
2391 workInProgress.elementType = current.elementType;
2392 workInProgress.type = current.type;
2393 workInProgress.stateNode = current.stateNode;
2394
2395 {
2396 // DEV-only fields
2397 workInProgress._debugID = current._debugID;
2398 workInProgress._debugSource = current._debugSource;
2399 workInProgress._debugOwner = current._debugOwner;
2400 workInProgress._debugHookTypes = current._debugHookTypes;
2401 }
2402
2403 workInProgress.alternate = current;
2404 current.alternate = workInProgress;
2405 } else {
2406 workInProgress.pendingProps = pendingProps;
2407
2408 // We already have an alternate.
2409 // Reset the effect tag.
2410 workInProgress.effectTag = NoEffect;
2411
2412 // The effect list is no longer valid.
2413 workInProgress.nextEffect = null;
2414 workInProgress.firstEffect = null;
2415 workInProgress.lastEffect = null;
2416
2417 if (enableProfilerTimer) {
2418 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
2419 // This prevents time from endlessly accumulating in new commits.
2420 // This has the downside of resetting values for different priority renders,
2421 // But works for yielding (the common case) and should support resuming.
2422 workInProgress.actualDuration = 0;
2423 workInProgress.actualStartTime = -1;
2424 }
2425 }
2426
2427 workInProgress.childExpirationTime = current.childExpirationTime;
2428 workInProgress.expirationTime = current.expirationTime;
2429
2430 workInProgress.child = current.child;
2431 workInProgress.memoizedProps = current.memoizedProps;
2432 workInProgress.memoizedState = current.memoizedState;
2433 workInProgress.updateQueue = current.updateQueue;
2434 workInProgress.contextDependencies = current.contextDependencies;
2435
2436 // These will be overridden during the parent's reconciliation
2437 workInProgress.sibling = current.sibling;
2438 workInProgress.index = current.index;
2439 workInProgress.ref = current.ref;
2440
2441 if (enableProfilerTimer) {
2442 workInProgress.selfBaseDuration = current.selfBaseDuration;
2443 workInProgress.treeBaseDuration = current.treeBaseDuration;
2444 }
2445
2446 return workInProgress;
2447}
2448
2449function createHostRootFiber(isConcurrent) {
2450 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
2451
2452 if (enableProfilerTimer && isDevToolsPresent) {
2453 // Always collect profile timings when DevTools are present.
2454 // This enables DevTools to start capturing timing at any point–
2455 // Without some nodes in the tree having empty base times.
2456 mode |= ProfileMode;
2457 }
2458
2459 return createFiber(HostRoot, null, null, mode);
2460}
2461
2462function createFiberFromTypeAndProps(type, // React$ElementType
2463key, pendingProps, owner, mode, expirationTime) {
2464 var fiber = void 0;
2465
2466 var fiberTag = IndeterminateComponent;
2467 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
2468 var resolvedType = type;
2469 if (typeof type === 'function') {
2470 if (shouldConstruct(type)) {
2471 fiberTag = ClassComponent;
2472 }
2473 } else if (typeof type === 'string') {
2474 fiberTag = HostComponent;
2475 } else {
2476 getTag: switch (type) {
2477 case REACT_FRAGMENT_TYPE:
2478 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
2479 case REACT_CONCURRENT_MODE_TYPE:
2480 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
2481 case REACT_STRICT_MODE_TYPE:
2482 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
2483 case REACT_PROFILER_TYPE:
2484 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
2485 case REACT_SUSPENSE_TYPE:
2486 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
2487 default:
2488 {
2489 if (typeof type === 'object' && type !== null) {
2490 switch (type.$$typeof) {
2491 case REACT_PROVIDER_TYPE:
2492 fiberTag = ContextProvider;
2493 break getTag;
2494 case REACT_CONTEXT_TYPE:
2495 // This is a consumer
2496 fiberTag = ContextConsumer;
2497 break getTag;
2498 case REACT_FORWARD_REF_TYPE:
2499 fiberTag = ForwardRef;
2500 break getTag;
2501 case REACT_MEMO_TYPE:
2502 fiberTag = MemoComponent;
2503 break getTag;
2504 case REACT_LAZY_TYPE:
2505 fiberTag = LazyComponent;
2506 resolvedType = null;
2507 break getTag;
2508 }
2509 }
2510 var info = '';
2511 {
2512 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
2513 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.';
2514 }
2515 var ownerName = owner ? getComponentName(owner.type) : null;
2516 if (ownerName) {
2517 info += '\n\nCheck the render method of `' + ownerName + '`.';
2518 }
2519 }
2520 invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info);
2521 }
2522 }
2523 }
2524
2525 fiber = createFiber(fiberTag, pendingProps, key, mode);
2526 fiber.elementType = type;
2527 fiber.type = resolvedType;
2528 fiber.expirationTime = expirationTime;
2529
2530 return fiber;
2531}
2532
2533function createFiberFromElement(element, mode, expirationTime) {
2534 var owner = null;
2535 {
2536 owner = element._owner;
2537 }
2538 var type = element.type;
2539 var key = element.key;
2540 var pendingProps = element.props;
2541 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
2542 {
2543 fiber._debugSource = element._source;
2544 fiber._debugOwner = element._owner;
2545 }
2546 return fiber;
2547}
2548
2549function createFiberFromFragment(elements, mode, expirationTime, key) {
2550 var fiber = createFiber(Fragment, elements, key, mode);
2551 fiber.expirationTime = expirationTime;
2552 return fiber;
2553}
2554
2555function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
2556 {
2557 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
2558 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
2559 }
2560 }
2561
2562 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
2563 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
2564 fiber.elementType = REACT_PROFILER_TYPE;
2565 fiber.type = REACT_PROFILER_TYPE;
2566 fiber.expirationTime = expirationTime;
2567
2568 return fiber;
2569}
2570
2571function createFiberFromMode(pendingProps, mode, expirationTime, key) {
2572 var fiber = createFiber(Mode, pendingProps, key, mode);
2573
2574 // TODO: The Mode fiber shouldn't have a type. It has a tag.
2575 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
2576 fiber.elementType = type;
2577 fiber.type = type;
2578
2579 fiber.expirationTime = expirationTime;
2580 return fiber;
2581}
2582
2583function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
2584 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
2585
2586 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
2587 var type = REACT_SUSPENSE_TYPE;
2588 fiber.elementType = type;
2589 fiber.type = type;
2590
2591 fiber.expirationTime = expirationTime;
2592 return fiber;
2593}
2594
2595function createFiberFromText(content, mode, expirationTime) {
2596 var fiber = createFiber(HostText, content, null, mode);
2597 fiber.expirationTime = expirationTime;
2598 return fiber;
2599}
2600
2601function createFiberFromHostInstanceForDeletion() {
2602 var fiber = createFiber(HostComponent, null, null, NoContext);
2603 // TODO: These should not need a type.
2604 fiber.elementType = 'DELETED';
2605 fiber.type = 'DELETED';
2606 return fiber;
2607}
2608
2609function createFiberFromPortal(portal, mode, expirationTime) {
2610 var pendingProps = portal.children !== null ? portal.children : [];
2611 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
2612 fiber.expirationTime = expirationTime;
2613 fiber.stateNode = {
2614 containerInfo: portal.containerInfo,
2615 pendingChildren: null, // Used by persistent updates
2616 implementation: portal.implementation
2617 };
2618 return fiber;
2619}
2620
2621// Used for stashing WIP properties to replay failed work in DEV.
2622function assignFiberPropertiesInDEV(target, source) {
2623 if (target === null) {
2624 // This Fiber's initial properties will always be overwritten.
2625 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
2626 target = createFiber(IndeterminateComponent, null, null, NoContext);
2627 }
2628
2629 // This is intentionally written as a list of all properties.
2630 // We tried to use Object.assign() instead but this is called in
2631 // the hottest path, and Object.assign() was too slow:
2632 // https://github.com/facebook/react/issues/12502
2633 // This code is DEV-only so size is not a concern.
2634
2635 target.tag = source.tag;
2636 target.key = source.key;
2637 target.elementType = source.elementType;
2638 target.type = source.type;
2639 target.stateNode = source.stateNode;
2640 target.return = source.return;
2641 target.child = source.child;
2642 target.sibling = source.sibling;
2643 target.index = source.index;
2644 target.ref = source.ref;
2645 target.pendingProps = source.pendingProps;
2646 target.memoizedProps = source.memoizedProps;
2647 target.updateQueue = source.updateQueue;
2648 target.memoizedState = source.memoizedState;
2649 target.contextDependencies = source.contextDependencies;
2650 target.mode = source.mode;
2651 target.effectTag = source.effectTag;
2652 target.nextEffect = source.nextEffect;
2653 target.firstEffect = source.firstEffect;
2654 target.lastEffect = source.lastEffect;
2655 target.expirationTime = source.expirationTime;
2656 target.childExpirationTime = source.childExpirationTime;
2657 target.alternate = source.alternate;
2658 if (enableProfilerTimer) {
2659 target.actualDuration = source.actualDuration;
2660 target.actualStartTime = source.actualStartTime;
2661 target.selfBaseDuration = source.selfBaseDuration;
2662 target.treeBaseDuration = source.treeBaseDuration;
2663 }
2664 target._debugID = source._debugID;
2665 target._debugSource = source._debugSource;
2666 target._debugOwner = source._debugOwner;
2667 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
2668 target._debugHookTypes = source._debugHookTypes;
2669 return target;
2670}
2671
2672var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2673
2674var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
2675var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
2676var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
2677var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
2678var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
2679var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
2680var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
2681var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
2682var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
2683var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2684
2685// TODO: This should be lifted into the renderer.
2686
2687
2688// The following attributes are only used by interaction tracing builds.
2689// They enable interactions to be associated with their async work,
2690// And expose interaction metadata to the React DevTools Profiler plugin.
2691// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
2692
2693
2694// Exported FiberRoot type includes all properties,
2695// To avoid requiring potentially error-prone :any casts throughout the project.
2696// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
2697// The types are defined separately within this file to ensure they stay in sync.
2698// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
2699
2700
2701function createFiberRoot(containerInfo, isConcurrent, hydrate) {
2702 // Cyclic construction. This cheats the type system right now because
2703 // stateNode is any.
2704 var uninitializedFiber = createHostRootFiber(isConcurrent);
2705
2706 var root = void 0;
2707 if (enableSchedulerTracing) {
2708 root = {
2709 current: uninitializedFiber,
2710 containerInfo: containerInfo,
2711 pendingChildren: null,
2712
2713 earliestPendingTime: NoWork,
2714 latestPendingTime: NoWork,
2715 earliestSuspendedTime: NoWork,
2716 latestSuspendedTime: NoWork,
2717 latestPingedTime: NoWork,
2718
2719 pingCache: null,
2720
2721 didError: false,
2722
2723 pendingCommitExpirationTime: NoWork,
2724 finishedWork: null,
2725 timeoutHandle: noTimeout,
2726 context: null,
2727 pendingContext: null,
2728 hydrate: hydrate,
2729 nextExpirationTimeToWorkOn: NoWork,
2730 expirationTime: NoWork,
2731 firstBatch: null,
2732 nextScheduledRoot: null,
2733
2734 interactionThreadID: unstable_getThreadID(),
2735 memoizedInteractions: new Set(),
2736 pendingInteractionMap: new Map()
2737 };
2738 } else {
2739 root = {
2740 current: uninitializedFiber,
2741 containerInfo: containerInfo,
2742 pendingChildren: null,
2743
2744 pingCache: null,
2745
2746 earliestPendingTime: NoWork,
2747 latestPendingTime: NoWork,
2748 earliestSuspendedTime: NoWork,
2749 latestSuspendedTime: NoWork,
2750 latestPingedTime: NoWork,
2751
2752 didError: false,
2753
2754 pendingCommitExpirationTime: NoWork,
2755 finishedWork: null,
2756 timeoutHandle: noTimeout,
2757 context: null,
2758 pendingContext: null,
2759 hydrate: hydrate,
2760 nextExpirationTimeToWorkOn: NoWork,
2761 expirationTime: NoWork,
2762 firstBatch: null,
2763 nextScheduledRoot: null
2764 };
2765 }
2766
2767 uninitializedFiber.stateNode = root;
2768
2769 // The reason for the way the Flow types are structured in this file,
2770 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
2771 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
2772 // $FlowFixMe Remove this :any cast and replace it with something better.
2773 return root;
2774}
2775
2776var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
2777 var funcArgs = Array.prototype.slice.call(arguments, 3);
2778 try {
2779 func.apply(context, funcArgs);
2780 } catch (error) {
2781 this.onError(error);
2782 }
2783};
2784
2785{
2786 // In DEV mode, we swap out invokeGuardedCallback for a special version
2787 // that plays more nicely with the browser's DevTools. The idea is to preserve
2788 // "Pause on exceptions" behavior. Because React wraps all user-provided
2789 // functions in invokeGuardedCallback, and the production version of
2790 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
2791 // like caught exceptions, and the DevTools won't pause unless the developer
2792 // takes the extra step of enabling pause on caught exceptions. This is
2793 // unintuitive, though, because even though React has caught the error, from
2794 // the developer's perspective, the error is uncaught.
2795 //
2796 // To preserve the expected "Pause on exceptions" behavior, we don't use a
2797 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
2798 // DOM node, and call the user-provided callback from inside an event handler
2799 // for that fake event. If the callback throws, the error is "captured" using
2800 // a global event handler. But because the error happens in a different
2801 // event loop context, it does not interrupt the normal program flow.
2802 // Effectively, this gives us try-catch behavior without actually using
2803 // try-catch. Neat!
2804
2805 // Check that the browser supports the APIs we need to implement our special
2806 // DEV version of invokeGuardedCallback
2807 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
2808 var fakeNode = document.createElement('react');
2809
2810 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
2811 // If document doesn't exist we know for sure we will crash in this method
2812 // when we call document.createEvent(). However this can cause confusing
2813 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
2814 // So we preemptively throw with a better message instead.
2815 !(typeof document !== 'undefined') ? invariant(false, '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.') : void 0;
2816 var evt = document.createEvent('Event');
2817
2818 // Keeps track of whether the user-provided callback threw an error. We
2819 // set this to true at the beginning, then set it to false right after
2820 // calling the function. If the function errors, `didError` will never be
2821 // set to false. This strategy works even if the browser is flaky and
2822 // fails to call our global error handler, because it doesn't rely on
2823 // the error event at all.
2824 var didError = true;
2825
2826 // Keeps track of the value of window.event so that we can reset it
2827 // during the callback to let user code access window.event in the
2828 // browsers that support it.
2829 var windowEvent = window.event;
2830
2831 // Keeps track of the descriptor of window.event to restore it after event
2832 // dispatching: https://github.com/facebook/react/issues/13688
2833 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
2834
2835 // Create an event handler for our fake event. We will synchronously
2836 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
2837 // call the user-provided callback.
2838 var funcArgs = Array.prototype.slice.call(arguments, 3);
2839 function callCallback() {
2840 // We immediately remove the callback from event listeners so that
2841 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
2842 // nested call would trigger the fake event handlers of any call higher
2843 // in the stack.
2844 fakeNode.removeEventListener(evtType, callCallback, false);
2845
2846 // We check for window.hasOwnProperty('event') to prevent the
2847 // window.event assignment in both IE <= 10 as they throw an error
2848 // "Member not found" in strict mode, and in Firefox which does not
2849 // support window.event.
2850 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
2851 window.event = windowEvent;
2852 }
2853
2854 func.apply(context, funcArgs);
2855 didError = false;
2856 }
2857
2858 // Create a global error event handler. We use this to capture the value
2859 // that was thrown. It's possible that this error handler will fire more
2860 // than once; for example, if non-React code also calls `dispatchEvent`
2861 // and a handler for that event throws. We should be resilient to most of
2862 // those cases. Even if our error event handler fires more than once, the
2863 // last error event is always used. If the callback actually does error,
2864 // we know that the last error event is the correct one, because it's not
2865 // possible for anything else to have happened in between our callback
2866 // erroring and the code that follows the `dispatchEvent` call below. If
2867 // the callback doesn't error, but the error event was fired, we know to
2868 // ignore it because `didError` will be false, as described above.
2869 var error = void 0;
2870 // Use this to track whether the error event is ever called.
2871 var didSetError = false;
2872 var isCrossOriginError = false;
2873
2874 function handleWindowError(event) {
2875 error = event.error;
2876 didSetError = true;
2877 if (error === null && event.colno === 0 && event.lineno === 0) {
2878 isCrossOriginError = true;
2879 }
2880 if (event.defaultPrevented) {
2881 // Some other error handler has prevented default.
2882 // Browsers silence the error report if this happens.
2883 // We'll remember this to later decide whether to log it or not.
2884 if (error != null && typeof error === 'object') {
2885 try {
2886 error._suppressLogging = true;
2887 } catch (inner) {
2888 // Ignore.
2889 }
2890 }
2891 }
2892 }
2893
2894 // Create a fake event type.
2895 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
2896
2897 // Attach our event handlers
2898 window.addEventListener('error', handleWindowError);
2899 fakeNode.addEventListener(evtType, callCallback, false);
2900
2901 // Synchronously dispatch our fake event. If the user-provided function
2902 // errors, it will trigger our global error handler.
2903 evt.initEvent(evtType, false, false);
2904 fakeNode.dispatchEvent(evt);
2905
2906 if (windowEventDescriptor) {
2907 Object.defineProperty(window, 'event', windowEventDescriptor);
2908 }
2909
2910 if (didError) {
2911 if (!didSetError) {
2912 // The callback errored, but the error event never fired.
2913 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.');
2914 } else if (isCrossOriginError) {
2915 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.');
2916 }
2917 this.onError(error);
2918 }
2919
2920 // Remove our event listeners
2921 window.removeEventListener('error', handleWindowError);
2922 };
2923
2924 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
2925 }
2926}
2927
2928var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
2929
2930// Used by Fiber to simulate a try-catch.
2931var hasError = false;
2932var caughtError = null;
2933
2934var reporter = {
2935 onError: function (error) {
2936 hasError = true;
2937 caughtError = error;
2938 }
2939};
2940
2941/**
2942 * Call a function while guarding against errors that happens within it.
2943 * Returns an error if it throws, otherwise null.
2944 *
2945 * In production, this is implemented using a try-catch. The reason we don't
2946 * use a try-catch directly is so that we can swap out a different
2947 * implementation in DEV mode.
2948 *
2949 * @param {String} name of the guard to use for logging or debugging
2950 * @param {Function} func The function to invoke
2951 * @param {*} context The context to use when calling the function
2952 * @param {...*} args Arguments for function
2953 */
2954function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
2955 hasError = false;
2956 caughtError = null;
2957 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
2958}
2959
2960/**
2961 * Same as invokeGuardedCallback, but instead of returning an error, it stores
2962 * it in a global so it can be rethrown by `rethrowCaughtError` later.
2963 * TODO: See if caughtError and rethrowError can be unified.
2964 *
2965 * @param {String} name of the guard to use for logging or debugging
2966 * @param {Function} func The function to invoke
2967 * @param {*} context The context to use when calling the function
2968 * @param {...*} args Arguments for function
2969 */
2970
2971
2972/**
2973 * During execution of guarded functions we will capture the first error which
2974 * we will rethrow to be handled by the top level error handler.
2975 */
2976
2977
2978function hasCaughtError() {
2979 return hasError;
2980}
2981
2982function clearCaughtError() {
2983 if (hasError) {
2984 var error = caughtError;
2985 hasError = false;
2986 caughtError = null;
2987 return error;
2988 } else {
2989 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
2990 }
2991}
2992
2993/**
2994 * Forked from fbjs/warning:
2995 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2996 *
2997 * Only change is we use console.warn instead of console.error,
2998 * and do nothing when 'console' is not supported.
2999 * This really simplifies the code.
3000 * ---
3001 * Similar to invariant but only logs a warning if the condition is not met.
3002 * This can be used to log issues in development environments in critical
3003 * paths. Removing the logging code for production environments will keep the
3004 * same logic and follow the same code paths.
3005 */
3006
3007var lowPriorityWarning = function () {};
3008
3009{
3010 var printWarning$1 = function (format) {
3011 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
3012 args[_key - 1] = arguments[_key];
3013 }
3014
3015 var argIndex = 0;
3016 var message = 'Warning: ' + format.replace(/%s/g, function () {
3017 return args[argIndex++];
3018 });
3019 if (typeof console !== 'undefined') {
3020 console.warn(message);
3021 }
3022 try {
3023 // --- Welcome to debugging React ---
3024 // This error was thrown as a convenience so that you can use this stack
3025 // to find the callsite that caused this warning to fire.
3026 throw new Error(message);
3027 } catch (x) {}
3028 };
3029
3030 lowPriorityWarning = function (condition, format) {
3031 if (format === undefined) {
3032 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
3033 }
3034 if (!condition) {
3035 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
3036 args[_key2 - 2] = arguments[_key2];
3037 }
3038
3039 printWarning$1.apply(undefined, [format].concat(args));
3040 }
3041 };
3042}
3043
3044var lowPriorityWarning$1 = lowPriorityWarning;
3045
3046var ReactStrictModeWarnings = {
3047 discardPendingWarnings: function () {},
3048 flushPendingDeprecationWarnings: function () {},
3049 flushPendingUnsafeLifecycleWarnings: function () {},
3050 recordDeprecationWarnings: function (fiber, instance) {},
3051 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
3052 recordLegacyContextWarning: function (fiber, instance) {},
3053 flushLegacyContextWarning: function () {}
3054};
3055
3056{
3057 var LIFECYCLE_SUGGESTIONS = {
3058 UNSAFE_componentWillMount: 'componentDidMount',
3059 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
3060 UNSAFE_componentWillUpdate: 'componentDidUpdate'
3061 };
3062
3063 var pendingComponentWillMountWarnings = [];
3064 var pendingComponentWillReceivePropsWarnings = [];
3065 var pendingComponentWillUpdateWarnings = [];
3066 var pendingUnsafeLifecycleWarnings = new Map();
3067 var pendingLegacyContextWarning = new Map();
3068
3069 // Tracks components we have already warned about.
3070 var didWarnAboutDeprecatedLifecycles = new Set();
3071 var didWarnAboutUnsafeLifecycles = new Set();
3072 var didWarnAboutLegacyContext = new Set();
3073
3074 var setToSortedString = function (set) {
3075 var array = [];
3076 set.forEach(function (value) {
3077 array.push(value);
3078 });
3079 return array.sort().join(', ');
3080 };
3081
3082 ReactStrictModeWarnings.discardPendingWarnings = function () {
3083 pendingComponentWillMountWarnings = [];
3084 pendingComponentWillReceivePropsWarnings = [];
3085 pendingComponentWillUpdateWarnings = [];
3086 pendingUnsafeLifecycleWarnings = new Map();
3087 pendingLegacyContextWarning = new Map();
3088 };
3089
3090 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
3091 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
3092 var lifecyclesWarningMessages = [];
3093
3094 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
3095 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
3096 if (lifecycleWarnings.length > 0) {
3097 var componentNames = new Set();
3098 lifecycleWarnings.forEach(function (fiber) {
3099 componentNames.add(getComponentName(fiber.type) || 'Component');
3100 didWarnAboutUnsafeLifecycles.add(fiber.type);
3101 });
3102
3103 var formatted = lifecycle.replace('UNSAFE_', '');
3104 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
3105 var sortedComponentNames = setToSortedString(componentNames);
3106
3107 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
3108 }
3109 });
3110
3111 if (lifecyclesWarningMessages.length > 0) {
3112 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3113
3114 warningWithoutStack$1(false, 'Unsafe lifecycle methods were found within a strict-mode tree:%s' + '\n\n%s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, lifecyclesWarningMessages.join('\n\n'));
3115 }
3116 });
3117
3118 pendingUnsafeLifecycleWarnings = new Map();
3119 };
3120
3121 var findStrictRoot = function (fiber) {
3122 var maybeStrictRoot = null;
3123
3124 var node = fiber;
3125 while (node !== null) {
3126 if (node.mode & StrictMode) {
3127 maybeStrictRoot = node;
3128 }
3129 node = node.return;
3130 }
3131
3132 return maybeStrictRoot;
3133 };
3134
3135 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
3136 if (pendingComponentWillMountWarnings.length > 0) {
3137 var uniqueNames = new Set();
3138 pendingComponentWillMountWarnings.forEach(function (fiber) {
3139 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3140 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3141 });
3142
3143 var sortedNames = setToSortedString(uniqueNames);
3144
3145 lowPriorityWarning$1(false, 'componentWillMount is deprecated and will be removed in the next major version. ' + 'Use componentDidMount instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillMount.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', sortedNames);
3146
3147 pendingComponentWillMountWarnings = [];
3148 }
3149
3150 if (pendingComponentWillReceivePropsWarnings.length > 0) {
3151 var _uniqueNames = new Set();
3152 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
3153 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
3154 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3155 });
3156
3157 var _sortedNames = setToSortedString(_uniqueNames);
3158
3159 lowPriorityWarning$1(false, 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' + 'Use static getDerivedStateFromProps instead.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames);
3160
3161 pendingComponentWillReceivePropsWarnings = [];
3162 }
3163
3164 if (pendingComponentWillUpdateWarnings.length > 0) {
3165 var _uniqueNames2 = new Set();
3166 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
3167 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
3168 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3169 });
3170
3171 var _sortedNames2 = setToSortedString(_uniqueNames2);
3172
3173 lowPriorityWarning$1(false, 'componentWillUpdate is deprecated and will be removed in the next major version. ' + 'Use componentDidUpdate instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillUpdate.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames2);
3174
3175 pendingComponentWillUpdateWarnings = [];
3176 }
3177 };
3178
3179 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
3180 // Dedup strategy: Warn once per component.
3181 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
3182 return;
3183 }
3184
3185 // Don't warn about react-lifecycles-compat polyfilled components.
3186 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3187 pendingComponentWillMountWarnings.push(fiber);
3188 }
3189 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3190 pendingComponentWillReceivePropsWarnings.push(fiber);
3191 }
3192 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3193 pendingComponentWillUpdateWarnings.push(fiber);
3194 }
3195 };
3196
3197 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
3198 var strictRoot = findStrictRoot(fiber);
3199 if (strictRoot === null) {
3200 warningWithoutStack$1(false, 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
3201 return;
3202 }
3203
3204 // Dedup strategy: Warn once per component.
3205 // This is difficult to track any other way since component names
3206 // are often vague and are likely to collide between 3rd party libraries.
3207 // An expand property is probably okay to use here since it's DEV-only,
3208 // and will only be set in the event of serious warnings.
3209 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
3210 return;
3211 }
3212
3213 var warningsForRoot = void 0;
3214 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
3215 warningsForRoot = {
3216 UNSAFE_componentWillMount: [],
3217 UNSAFE_componentWillReceiveProps: [],
3218 UNSAFE_componentWillUpdate: []
3219 };
3220
3221 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
3222 } else {
3223 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
3224 }
3225
3226 var unsafeLifecycles = [];
3227 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
3228 unsafeLifecycles.push('UNSAFE_componentWillMount');
3229 }
3230 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3231 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
3232 }
3233 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
3234 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
3235 }
3236
3237 if (unsafeLifecycles.length > 0) {
3238 unsafeLifecycles.forEach(function (lifecycle) {
3239 warningsForRoot[lifecycle].push(fiber);
3240 });
3241 }
3242 };
3243
3244 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
3245 var strictRoot = findStrictRoot(fiber);
3246 if (strictRoot === null) {
3247 warningWithoutStack$1(false, 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
3248 return;
3249 }
3250
3251 // Dedup strategy: Warn once per component.
3252 if (didWarnAboutLegacyContext.has(fiber.type)) {
3253 return;
3254 }
3255
3256 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
3257
3258 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
3259 if (warningsForRoot === undefined) {
3260 warningsForRoot = [];
3261 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
3262 }
3263 warningsForRoot.push(fiber);
3264 }
3265 };
3266
3267 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
3268 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
3269 var uniqueNames = new Set();
3270 fiberArray.forEach(function (fiber) {
3271 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3272 didWarnAboutLegacyContext.add(fiber.type);
3273 });
3274
3275 var sortedNames = setToSortedString(uniqueNames);
3276 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3277
3278 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree: %s' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, sortedNames);
3279 });
3280 };
3281}
3282
3283// This lets us hook into Fiber to debug what it's doing.
3284// See https://github.com/facebook/react/pull/8033.
3285// This is not part of the public API, not even for React DevTools.
3286// You may only inject a debugTool if you work on React Fiber itself.
3287var ReactFiberInstrumentation = {
3288 debugTool: null
3289};
3290
3291var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
3292
3293// TODO: Offscreen updates should never suspend. However, a promise that
3294// suspended inside an offscreen subtree should be able to ping at the priority
3295// of the outer render.
3296
3297function markPendingPriorityLevel(root, expirationTime) {
3298 // If there's a gap between completing a failed root and retrying it,
3299 // additional updates may be scheduled. Clear `didError`, in case the update
3300 // is sufficient to fix the error.
3301 root.didError = false;
3302
3303 // Update the latest and earliest pending times
3304 var earliestPendingTime = root.earliestPendingTime;
3305 if (earliestPendingTime === NoWork) {
3306 // No other pending updates.
3307 root.earliestPendingTime = root.latestPendingTime = expirationTime;
3308 } else {
3309 if (earliestPendingTime < expirationTime) {
3310 // This is the earliest pending update.
3311 root.earliestPendingTime = expirationTime;
3312 } else {
3313 var latestPendingTime = root.latestPendingTime;
3314 if (latestPendingTime > expirationTime) {
3315 // This is the latest pending update
3316 root.latestPendingTime = expirationTime;
3317 }
3318 }
3319 }
3320 findNextExpirationTimeToWorkOn(expirationTime, root);
3321}
3322
3323function markCommittedPriorityLevels(root, earliestRemainingTime) {
3324 root.didError = false;
3325
3326 if (earliestRemainingTime === NoWork) {
3327 // Fast path. There's no remaining work. Clear everything.
3328 root.earliestPendingTime = NoWork;
3329 root.latestPendingTime = NoWork;
3330 root.earliestSuspendedTime = NoWork;
3331 root.latestSuspendedTime = NoWork;
3332 root.latestPingedTime = NoWork;
3333 findNextExpirationTimeToWorkOn(NoWork, root);
3334 return;
3335 }
3336
3337 if (earliestRemainingTime < root.latestPingedTime) {
3338 root.latestPingedTime = NoWork;
3339 }
3340
3341 // Let's see if the previous latest known pending level was just flushed.
3342 var latestPendingTime = root.latestPendingTime;
3343 if (latestPendingTime !== NoWork) {
3344 if (latestPendingTime > earliestRemainingTime) {
3345 // We've flushed all the known pending levels.
3346 root.earliestPendingTime = root.latestPendingTime = NoWork;
3347 } else {
3348 var earliestPendingTime = root.earliestPendingTime;
3349 if (earliestPendingTime > earliestRemainingTime) {
3350 // We've flushed the earliest known pending level. Set this to the
3351 // latest pending time.
3352 root.earliestPendingTime = root.latestPendingTime;
3353 }
3354 }
3355 }
3356
3357 // Now let's handle the earliest remaining level in the whole tree. We need to
3358 // decide whether to treat it as a pending level or as suspended. Check
3359 // it falls within the range of known suspended levels.
3360
3361 var earliestSuspendedTime = root.earliestSuspendedTime;
3362 if (earliestSuspendedTime === NoWork) {
3363 // There's no suspended work. Treat the earliest remaining level as a
3364 // pending level.
3365 markPendingPriorityLevel(root, earliestRemainingTime);
3366 findNextExpirationTimeToWorkOn(NoWork, root);
3367 return;
3368 }
3369
3370 var latestSuspendedTime = root.latestSuspendedTime;
3371 if (earliestRemainingTime < latestSuspendedTime) {
3372 // The earliest remaining level is later than all the suspended work. That
3373 // means we've flushed all the suspended work.
3374 root.earliestSuspendedTime = NoWork;
3375 root.latestSuspendedTime = NoWork;
3376 root.latestPingedTime = NoWork;
3377
3378 // There's no suspended work. Treat the earliest remaining level as a
3379 // pending level.
3380 markPendingPriorityLevel(root, earliestRemainingTime);
3381 findNextExpirationTimeToWorkOn(NoWork, root);
3382 return;
3383 }
3384
3385 if (earliestRemainingTime > earliestSuspendedTime) {
3386 // The earliest remaining time is earlier than all the suspended work.
3387 // Treat it as a pending update.
3388 markPendingPriorityLevel(root, earliestRemainingTime);
3389 findNextExpirationTimeToWorkOn(NoWork, root);
3390 return;
3391 }
3392
3393 // The earliest remaining time falls within the range of known suspended
3394 // levels. We should treat this as suspended work.
3395 findNextExpirationTimeToWorkOn(NoWork, root);
3396}
3397
3398function hasLowerPriorityWork(root, erroredExpirationTime) {
3399 var latestPendingTime = root.latestPendingTime;
3400 var latestSuspendedTime = root.latestSuspendedTime;
3401 var latestPingedTime = root.latestPingedTime;
3402 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
3403}
3404
3405function isPriorityLevelSuspended(root, expirationTime) {
3406 var earliestSuspendedTime = root.earliestSuspendedTime;
3407 var latestSuspendedTime = root.latestSuspendedTime;
3408 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
3409}
3410
3411function markSuspendedPriorityLevel(root, suspendedTime) {
3412 root.didError = false;
3413 clearPing(root, suspendedTime);
3414
3415 // First, check the known pending levels and update them if needed.
3416 var earliestPendingTime = root.earliestPendingTime;
3417 var latestPendingTime = root.latestPendingTime;
3418 if (earliestPendingTime === suspendedTime) {
3419 if (latestPendingTime === suspendedTime) {
3420 // Both known pending levels were suspended. Clear them.
3421 root.earliestPendingTime = root.latestPendingTime = NoWork;
3422 } else {
3423 // The earliest pending level was suspended. Clear by setting it to the
3424 // latest pending level.
3425 root.earliestPendingTime = latestPendingTime;
3426 }
3427 } else if (latestPendingTime === suspendedTime) {
3428 // The latest pending level was suspended. Clear by setting it to the
3429 // latest pending level.
3430 root.latestPendingTime = earliestPendingTime;
3431 }
3432
3433 // Finally, update the known suspended levels.
3434 var earliestSuspendedTime = root.earliestSuspendedTime;
3435 var latestSuspendedTime = root.latestSuspendedTime;
3436 if (earliestSuspendedTime === NoWork) {
3437 // No other suspended levels.
3438 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
3439 } else {
3440 if (earliestSuspendedTime < suspendedTime) {
3441 // This is the earliest suspended level.
3442 root.earliestSuspendedTime = suspendedTime;
3443 } else if (latestSuspendedTime > suspendedTime) {
3444 // This is the latest suspended level
3445 root.latestSuspendedTime = suspendedTime;
3446 }
3447 }
3448
3449 findNextExpirationTimeToWorkOn(suspendedTime, root);
3450}
3451
3452function markPingedPriorityLevel(root, pingedTime) {
3453 root.didError = false;
3454
3455 // TODO: When we add back resuming, we need to ensure the progressed work
3456 // is thrown out and not reused during the restarted render. One way to
3457 // invalidate the progressed work is to restart at expirationTime + 1.
3458 var latestPingedTime = root.latestPingedTime;
3459 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
3460 root.latestPingedTime = pingedTime;
3461 }
3462 findNextExpirationTimeToWorkOn(pingedTime, root);
3463}
3464
3465function clearPing(root, completedTime) {
3466 var latestPingedTime = root.latestPingedTime;
3467 if (latestPingedTime >= completedTime) {
3468 root.latestPingedTime = NoWork;
3469 }
3470}
3471
3472function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
3473 var earliestExpirationTime = renderExpirationTime;
3474
3475 var earliestPendingTime = root.earliestPendingTime;
3476 var earliestSuspendedTime = root.earliestSuspendedTime;
3477 if (earliestPendingTime > earliestExpirationTime) {
3478 earliestExpirationTime = earliestPendingTime;
3479 }
3480 if (earliestSuspendedTime > earliestExpirationTime) {
3481 earliestExpirationTime = earliestSuspendedTime;
3482 }
3483 return earliestExpirationTime;
3484}
3485
3486function didExpireAtExpirationTime(root, currentTime) {
3487 var expirationTime = root.expirationTime;
3488 if (expirationTime !== NoWork && currentTime <= expirationTime) {
3489 // The root has expired. Flush all work up to the current time.
3490 root.nextExpirationTimeToWorkOn = currentTime;
3491 }
3492}
3493
3494function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
3495 var earliestSuspendedTime = root.earliestSuspendedTime;
3496 var latestSuspendedTime = root.latestSuspendedTime;
3497 var earliestPendingTime = root.earliestPendingTime;
3498 var latestPingedTime = root.latestPingedTime;
3499
3500 // Work on the earliest pending time. Failing that, work on the latest
3501 // pinged time.
3502 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
3503
3504 // If there is no pending or pinged work, check if there's suspended work
3505 // that's lower priority than what we just completed.
3506 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
3507 // The lowest priority suspended work is the work most likely to be
3508 // committed next. Let's start rendering it again, so that if it times out,
3509 // it's ready to commit.
3510 nextExpirationTimeToWorkOn = latestSuspendedTime;
3511 }
3512
3513 var expirationTime = nextExpirationTimeToWorkOn;
3514 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
3515 // Expire using the earliest known expiration time.
3516 expirationTime = earliestSuspendedTime;
3517 }
3518
3519 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
3520 root.expirationTime = expirationTime;
3521}
3522
3523/**
3524 * Similar to invariant but only logs a warning if the condition is not met.
3525 * This can be used to log issues in development environments in critical
3526 * paths. Removing the logging code for production environments will keep the
3527 * same logic and follow the same code paths.
3528 */
3529
3530var warning = warningWithoutStack$1;
3531
3532{
3533 warning = function (condition, format) {
3534 if (condition) {
3535 return;
3536 }
3537 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
3538 var stack = ReactDebugCurrentFrame.getStackAddendum();
3539 // eslint-disable-next-line react-internal/warning-and-invariant-args
3540
3541 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
3542 args[_key - 2] = arguments[_key];
3543 }
3544
3545 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
3546 };
3547}
3548
3549var warning$1 = warning;
3550
3551/**
3552 * inlined Object.is polyfill to avoid requiring consumers ship their own
3553 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3554 */
3555function is(x, y) {
3556 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
3557 ;
3558}
3559
3560var hasOwnProperty = Object.prototype.hasOwnProperty;
3561
3562/**
3563 * Performs equality by iterating through keys on an object and returning false
3564 * when any key has values which are not strictly equal between the arguments.
3565 * Returns true when the values of all keys are strictly equal.
3566 */
3567function shallowEqual(objA, objB) {
3568 if (is(objA, objB)) {
3569 return true;
3570 }
3571
3572 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3573 return false;
3574 }
3575
3576 var keysA = Object.keys(objA);
3577 var keysB = Object.keys(objB);
3578
3579 if (keysA.length !== keysB.length) {
3580 return false;
3581 }
3582
3583 // Test for A's keys different from B.
3584 for (var i = 0; i < keysA.length; i++) {
3585 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
3586 return false;
3587 }
3588 }
3589
3590 return true;
3591}
3592
3593function resolveDefaultProps(Component, baseProps) {
3594 if (Component && Component.defaultProps) {
3595 // Resolve default props. Taken from ReactElement
3596 var props = _assign({}, baseProps);
3597 var defaultProps = Component.defaultProps;
3598 for (var propName in defaultProps) {
3599 if (props[propName] === undefined) {
3600 props[propName] = defaultProps[propName];
3601 }
3602 }
3603 return props;
3604 }
3605 return baseProps;
3606}
3607
3608function readLazyComponentType(lazyComponent) {
3609 var status = lazyComponent._status;
3610 var result = lazyComponent._result;
3611 switch (status) {
3612 case Resolved:
3613 {
3614 var Component = result;
3615 return Component;
3616 }
3617 case Rejected:
3618 {
3619 var error = result;
3620 throw error;
3621 }
3622 case Pending:
3623 {
3624 var thenable = result;
3625 throw thenable;
3626 }
3627 default:
3628 {
3629 lazyComponent._status = Pending;
3630 var ctor = lazyComponent._ctor;
3631 var _thenable = ctor();
3632 _thenable.then(function (moduleObject) {
3633 if (lazyComponent._status === Pending) {
3634 var defaultExport = moduleObject.default;
3635 {
3636 if (defaultExport === undefined) {
3637 warning$1(false, 'lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
3638 }
3639 }
3640 lazyComponent._status = Resolved;
3641 lazyComponent._result = defaultExport;
3642 }
3643 }, function (error) {
3644 if (lazyComponent._status === Pending) {
3645 lazyComponent._status = Rejected;
3646 lazyComponent._result = error;
3647 }
3648 });
3649 // Handle synchronous thenables.
3650 switch (lazyComponent._status) {
3651 case Resolved:
3652 return lazyComponent._result;
3653 case Rejected:
3654 throw lazyComponent._result;
3655 }
3656 lazyComponent._result = _thenable;
3657 throw _thenable;
3658 }
3659 }
3660}
3661
3662var fakeInternalInstance = {};
3663var isArray$1 = Array.isArray;
3664
3665// React.Component uses a shared frozen object by default.
3666// We'll use it to determine whether we need to initialize legacy refs.
3667var emptyRefsObject = new React.Component().refs;
3668
3669var didWarnAboutStateAssignmentForComponent = void 0;
3670var didWarnAboutUninitializedState = void 0;
3671var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
3672var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
3673var didWarnAboutUndefinedDerivedState = void 0;
3674var warnOnUndefinedDerivedState = void 0;
3675var warnOnInvalidCallback = void 0;
3676var didWarnAboutDirectlyAssigningPropsToState = void 0;
3677var didWarnAboutContextTypeAndContextTypes = void 0;
3678var didWarnAboutInvalidateContextType = void 0;
3679
3680{
3681 didWarnAboutStateAssignmentForComponent = new Set();
3682 didWarnAboutUninitializedState = new Set();
3683 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3684 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3685 didWarnAboutDirectlyAssigningPropsToState = new Set();
3686 didWarnAboutUndefinedDerivedState = new Set();
3687 didWarnAboutContextTypeAndContextTypes = new Set();
3688 didWarnAboutInvalidateContextType = new Set();
3689
3690 var didWarnOnInvalidCallback = new Set();
3691
3692 warnOnInvalidCallback = function (callback, callerName) {
3693 if (callback === null || typeof callback === 'function') {
3694 return;
3695 }
3696 var key = callerName + '_' + callback;
3697 if (!didWarnOnInvalidCallback.has(key)) {
3698 didWarnOnInvalidCallback.add(key);
3699 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3700 }
3701 };
3702
3703 warnOnUndefinedDerivedState = function (type, partialState) {
3704 if (partialState === undefined) {
3705 var componentName = getComponentName(type) || 'Component';
3706 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3707 didWarnAboutUndefinedDerivedState.add(componentName);
3708 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3709 }
3710 }
3711 };
3712
3713 // This is so gross but it's at least non-critical and can be removed if
3714 // it causes problems. This is meant to give a nicer error message for
3715 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3716 // ...)) which otherwise throws a "_processChildContext is not a function"
3717 // exception.
3718 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3719 enumerable: false,
3720 value: function () {
3721 invariant(false, '_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).');
3722 }
3723 });
3724 Object.freeze(fakeInternalInstance);
3725}
3726
3727function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3728 var prevState = workInProgress.memoizedState;
3729
3730 {
3731 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3732 // Invoke the function an extra time to help detect side-effects.
3733 getDerivedStateFromProps(nextProps, prevState);
3734 }
3735 }
3736
3737 var partialState = getDerivedStateFromProps(nextProps, prevState);
3738
3739 {
3740 warnOnUndefinedDerivedState(ctor, partialState);
3741 }
3742 // Merge the partial state and the previous state.
3743 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3744 workInProgress.memoizedState = memoizedState;
3745
3746 // Once the update queue is empty, persist the derived state onto the
3747 // base state.
3748 var updateQueue = workInProgress.updateQueue;
3749 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
3750 updateQueue.baseState = memoizedState;
3751 }
3752}
3753
3754var classComponentUpdater = {
3755 isMounted: isMounted,
3756 enqueueSetState: function (inst, payload, callback) {
3757 var fiber = get(inst);
3758 var currentTime = requestCurrentTime();
3759 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3760
3761 var update = createUpdate(expirationTime);
3762 update.payload = payload;
3763 if (callback !== undefined && callback !== null) {
3764 {
3765 warnOnInvalidCallback(callback, 'setState');
3766 }
3767 update.callback = callback;
3768 }
3769
3770 flushPassiveEffects();
3771 enqueueUpdate(fiber, update);
3772 scheduleWork(fiber, expirationTime);
3773 },
3774 enqueueReplaceState: function (inst, payload, callback) {
3775 var fiber = get(inst);
3776 var currentTime = requestCurrentTime();
3777 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3778
3779 var update = createUpdate(expirationTime);
3780 update.tag = ReplaceState;
3781 update.payload = payload;
3782
3783 if (callback !== undefined && callback !== null) {
3784 {
3785 warnOnInvalidCallback(callback, 'replaceState');
3786 }
3787 update.callback = callback;
3788 }
3789
3790 flushPassiveEffects();
3791 enqueueUpdate(fiber, update);
3792 scheduleWork(fiber, expirationTime);
3793 },
3794 enqueueForceUpdate: function (inst, callback) {
3795 var fiber = get(inst);
3796 var currentTime = requestCurrentTime();
3797 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3798
3799 var update = createUpdate(expirationTime);
3800 update.tag = ForceUpdate;
3801
3802 if (callback !== undefined && callback !== null) {
3803 {
3804 warnOnInvalidCallback(callback, 'forceUpdate');
3805 }
3806 update.callback = callback;
3807 }
3808
3809 flushPassiveEffects();
3810 enqueueUpdate(fiber, update);
3811 scheduleWork(fiber, expirationTime);
3812 }
3813};
3814
3815function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3816 var instance = workInProgress.stateNode;
3817 if (typeof instance.shouldComponentUpdate === 'function') {
3818 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3819 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3820 stopPhaseTimer();
3821
3822 {
3823 !(shouldUpdate !== undefined) ? warningWithoutStack$1(false, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component') : void 0;
3824 }
3825
3826 return shouldUpdate;
3827 }
3828
3829 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3830 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3831 }
3832
3833 return true;
3834}
3835
3836function checkClassInstance(workInProgress, ctor, newProps) {
3837 var instance = workInProgress.stateNode;
3838 {
3839 var name = getComponentName(ctor) || 'Component';
3840 var renderPresent = instance.render;
3841
3842 if (!renderPresent) {
3843 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3844 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3845 } else {
3846 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3847 }
3848 }
3849
3850 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
3851 !noGetInitialStateOnES6 ? warningWithoutStack$1(false, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name) : void 0;
3852 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
3853 !noGetDefaultPropsOnES6 ? warningWithoutStack$1(false, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name) : void 0;
3854 var noInstancePropTypes = !instance.propTypes;
3855 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
3856 var noInstanceContextType = !instance.contextType;
3857 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
3858 var noInstanceContextTypes = !instance.contextTypes;
3859 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
3860
3861 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3862 didWarnAboutContextTypeAndContextTypes.add(ctor);
3863 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3864 }
3865
3866 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
3867 !noComponentShouldUpdate ? warningWithoutStack$1(false, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name) : void 0;
3868 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3869 warningWithoutStack$1(false, '%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
3870 }
3871 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
3872 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
3873 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
3874 !noComponentDidReceiveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name) : void 0;
3875 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
3876 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
3877 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
3878 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
3879 var hasMutatedProps = instance.props !== newProps;
3880 !(instance.props === undefined || !hasMutatedProps) ? warningWithoutStack$1(false, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name) : void 0;
3881 var noInstanceDefaultProps = !instance.defaultProps;
3882 !noInstanceDefaultProps ? warningWithoutStack$1(false, 'Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name) : void 0;
3883
3884 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3885 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3886 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3887 }
3888
3889 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
3890 !noInstanceGetDerivedStateFromProps ? warningWithoutStack$1(false, '%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
3891 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
3892 !noInstanceGetDerivedStateFromCatch ? warningWithoutStack$1(false, '%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
3893 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
3894 !noStaticGetSnapshotBeforeUpdate ? warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name) : void 0;
3895 var _state = instance.state;
3896 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
3897 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
3898 }
3899 if (typeof instance.getChildContext === 'function') {
3900 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
3901 }
3902 }
3903}
3904
3905function adoptClassInstance(workInProgress, instance) {
3906 instance.updater = classComponentUpdater;
3907 workInProgress.stateNode = instance;
3908 // The instance needs access to the fiber so that it can schedule updates
3909 set(instance, workInProgress);
3910 {
3911 instance._reactInternalInstance = fakeInternalInstance;
3912 }
3913}
3914
3915function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
3916 var isLegacyContextConsumer = false;
3917 var unmaskedContext = emptyContextObject;
3918 var context = null;
3919 var contextType = ctor.contextType;
3920
3921 {
3922 if ('contextType' in ctor) {
3923 var isValid =
3924 // Allow null for conditional declaration
3925 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
3926
3927 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
3928 didWarnAboutInvalidateContextType.add(ctor);
3929
3930 var addendum = '';
3931 if (contextType === undefined) {
3932 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.';
3933 } else if (typeof contextType !== 'object') {
3934 addendum = ' However, it is set to a ' + typeof contextType + '.';
3935 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
3936 addendum = ' Did you accidentally pass the Context.Provider instead?';
3937 } else if (contextType._context !== undefined) {
3938 // <Context.Consumer>
3939 addendum = ' Did you accidentally pass the Context.Consumer instead?';
3940 } else {
3941 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
3942 }
3943 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
3944 }
3945 }
3946 }
3947
3948 if (typeof contextType === 'object' && contextType !== null) {
3949 context = readContext(contextType);
3950 } else {
3951 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3952 var contextTypes = ctor.contextTypes;
3953 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
3954 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
3955 }
3956
3957 // Instantiate twice to help detect side-effects.
3958 {
3959 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3960 new ctor(props, context); // eslint-disable-line no-new
3961 }
3962 }
3963
3964 var instance = new ctor(props, context);
3965 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
3966 adoptClassInstance(workInProgress, instance);
3967
3968 {
3969 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
3970 var componentName = getComponentName(ctor) || 'Component';
3971 if (!didWarnAboutUninitializedState.has(componentName)) {
3972 didWarnAboutUninitializedState.add(componentName);
3973 warningWithoutStack$1(false, '`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
3974 }
3975 }
3976
3977 // If new component APIs are defined, "unsafe" lifecycles won't be called.
3978 // Warn about these lifecycles if they are present.
3979 // Don't warn about react-lifecycles-compat polyfilled methods though.
3980 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
3981 var foundWillMountName = null;
3982 var foundWillReceivePropsName = null;
3983 var foundWillUpdateName = null;
3984 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3985 foundWillMountName = 'componentWillMount';
3986 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
3987 foundWillMountName = 'UNSAFE_componentWillMount';
3988 }
3989 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3990 foundWillReceivePropsName = 'componentWillReceiveProps';
3991 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3992 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
3993 }
3994 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3995 foundWillUpdateName = 'componentWillUpdate';
3996 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3997 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
3998 }
3999 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
4000 var _componentName = getComponentName(ctor) || 'Component';
4001 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
4002 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
4003 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
4004 warningWithoutStack$1(false, 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-async-component-lifecycle-hooks', _componentName, newApiName, foundWillMountName !== null ? '\n ' + foundWillMountName : '', foundWillReceivePropsName !== null ? '\n ' + foundWillReceivePropsName : '', foundWillUpdateName !== null ? '\n ' + foundWillUpdateName : '');
4005 }
4006 }
4007 }
4008 }
4009
4010 // Cache unmasked context so we can avoid recreating masked context unless necessary.
4011 // ReactFiberContext usually updates this cache but can't for newly-created instances.
4012 if (isLegacyContextConsumer) {
4013 cacheContext(workInProgress, unmaskedContext, context);
4014 }
4015
4016 return instance;
4017}
4018
4019function callComponentWillMount(workInProgress, instance) {
4020 startPhaseTimer(workInProgress, 'componentWillMount');
4021 var oldState = instance.state;
4022
4023 if (typeof instance.componentWillMount === 'function') {
4024 instance.componentWillMount();
4025 }
4026 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4027 instance.UNSAFE_componentWillMount();
4028 }
4029
4030 stopPhaseTimer();
4031
4032 if (oldState !== instance.state) {
4033 {
4034 warningWithoutStack$1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
4035 }
4036 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4037 }
4038}
4039
4040function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4041 var oldState = instance.state;
4042 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4043 if (typeof instance.componentWillReceiveProps === 'function') {
4044 instance.componentWillReceiveProps(newProps, nextContext);
4045 }
4046 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4047 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4048 }
4049 stopPhaseTimer();
4050
4051 if (instance.state !== oldState) {
4052 {
4053 var componentName = getComponentName(workInProgress.type) || 'Component';
4054 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4055 didWarnAboutStateAssignmentForComponent.add(componentName);
4056 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4057 }
4058 }
4059 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4060 }
4061}
4062
4063// Invokes the mount life-cycles on a previously never rendered instance.
4064function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4065 {
4066 checkClassInstance(workInProgress, ctor, newProps);
4067 }
4068
4069 var instance = workInProgress.stateNode;
4070 instance.props = newProps;
4071 instance.state = workInProgress.memoizedState;
4072 instance.refs = emptyRefsObject;
4073
4074 var contextType = ctor.contextType;
4075 if (typeof contextType === 'object' && contextType !== null) {
4076 instance.context = readContext(contextType);
4077 } else {
4078 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4079 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4080 }
4081
4082 {
4083 if (instance.state === newProps) {
4084 var componentName = getComponentName(ctor) || 'Component';
4085 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4086 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4087 warningWithoutStack$1(false, '%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
4088 }
4089 }
4090
4091 if (workInProgress.mode & StrictMode) {
4092 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4093
4094 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4095 }
4096
4097 if (warnAboutDeprecatedLifecycles) {
4098 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
4099 }
4100 }
4101
4102 var updateQueue = workInProgress.updateQueue;
4103 if (updateQueue !== null) {
4104 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4105 instance.state = workInProgress.memoizedState;
4106 }
4107
4108 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4109 if (typeof getDerivedStateFromProps === 'function') {
4110 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4111 instance.state = workInProgress.memoizedState;
4112 }
4113
4114 // In order to support react-lifecycles-compat polyfilled components,
4115 // Unsafe lifecycles should not be invoked for components using the new APIs.
4116 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4117 callComponentWillMount(workInProgress, instance);
4118 // If we had additional state updates during this life-cycle, let's
4119 // process them now.
4120 updateQueue = workInProgress.updateQueue;
4121 if (updateQueue !== null) {
4122 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4123 instance.state = workInProgress.memoizedState;
4124 }
4125 }
4126
4127 if (typeof instance.componentDidMount === 'function') {
4128 workInProgress.effectTag |= Update;
4129 }
4130}
4131
4132function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4133 var instance = workInProgress.stateNode;
4134
4135 var oldProps = workInProgress.memoizedProps;
4136 instance.props = oldProps;
4137
4138 var oldContext = instance.context;
4139 var contextType = ctor.contextType;
4140 var nextContext = void 0;
4141 if (typeof contextType === 'object' && contextType !== null) {
4142 nextContext = readContext(contextType);
4143 } else {
4144 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4145 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4146 }
4147
4148 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4149 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4150
4151 // Note: During these life-cycles, instance.props/instance.state are what
4152 // ever the previously attempted to render - not the "current". However,
4153 // during componentDidUpdate we pass the "current" props.
4154
4155 // In order to support react-lifecycles-compat polyfilled components,
4156 // Unsafe lifecycles should not be invoked for components using the new APIs.
4157 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4158 if (oldProps !== newProps || oldContext !== nextContext) {
4159 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4160 }
4161 }
4162
4163 resetHasForceUpdateBeforeProcessing();
4164
4165 var oldState = workInProgress.memoizedState;
4166 var newState = instance.state = oldState;
4167 var updateQueue = workInProgress.updateQueue;
4168 if (updateQueue !== null) {
4169 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4170 newState = workInProgress.memoizedState;
4171 }
4172 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4173 // If an update was already in progress, we should schedule an Update
4174 // effect even though we're bailing out, so that cWU/cDU are called.
4175 if (typeof instance.componentDidMount === 'function') {
4176 workInProgress.effectTag |= Update;
4177 }
4178 return false;
4179 }
4180
4181 if (typeof getDerivedStateFromProps === 'function') {
4182 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4183 newState = workInProgress.memoizedState;
4184 }
4185
4186 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4187
4188 if (shouldUpdate) {
4189 // In order to support react-lifecycles-compat polyfilled components,
4190 // Unsafe lifecycles should not be invoked for components using the new APIs.
4191 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4192 startPhaseTimer(workInProgress, 'componentWillMount');
4193 if (typeof instance.componentWillMount === 'function') {
4194 instance.componentWillMount();
4195 }
4196 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4197 instance.UNSAFE_componentWillMount();
4198 }
4199 stopPhaseTimer();
4200 }
4201 if (typeof instance.componentDidMount === 'function') {
4202 workInProgress.effectTag |= Update;
4203 }
4204 } else {
4205 // If an update was already in progress, we should schedule an Update
4206 // effect even though we're bailing out, so that cWU/cDU are called.
4207 if (typeof instance.componentDidMount === 'function') {
4208 workInProgress.effectTag |= Update;
4209 }
4210
4211 // If shouldComponentUpdate returned false, we should still update the
4212 // memoized state to indicate that this work can be reused.
4213 workInProgress.memoizedProps = newProps;
4214 workInProgress.memoizedState = newState;
4215 }
4216
4217 // Update the existing instance's state, props, and context pointers even
4218 // if shouldComponentUpdate returns false.
4219 instance.props = newProps;
4220 instance.state = newState;
4221 instance.context = nextContext;
4222
4223 return shouldUpdate;
4224}
4225
4226// Invokes the update life-cycles and returns false if it shouldn't rerender.
4227function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4228 var instance = workInProgress.stateNode;
4229
4230 var oldProps = workInProgress.memoizedProps;
4231 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4232
4233 var oldContext = instance.context;
4234 var contextType = ctor.contextType;
4235 var nextContext = void 0;
4236 if (typeof contextType === 'object' && contextType !== null) {
4237 nextContext = readContext(contextType);
4238 } else {
4239 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4240 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4241 }
4242
4243 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4244 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4245
4246 // Note: During these life-cycles, instance.props/instance.state are what
4247 // ever the previously attempted to render - not the "current". However,
4248 // during componentDidUpdate we pass the "current" props.
4249
4250 // In order to support react-lifecycles-compat polyfilled components,
4251 // Unsafe lifecycles should not be invoked for components using the new APIs.
4252 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4253 if (oldProps !== newProps || oldContext !== nextContext) {
4254 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4255 }
4256 }
4257
4258 resetHasForceUpdateBeforeProcessing();
4259
4260 var oldState = workInProgress.memoizedState;
4261 var newState = instance.state = oldState;
4262 var updateQueue = workInProgress.updateQueue;
4263 if (updateQueue !== null) {
4264 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4265 newState = workInProgress.memoizedState;
4266 }
4267
4268 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4269 // If an update was already in progress, we should schedule an Update
4270 // effect even though we're bailing out, so that cWU/cDU are called.
4271 if (typeof instance.componentDidUpdate === 'function') {
4272 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4273 workInProgress.effectTag |= Update;
4274 }
4275 }
4276 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4277 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4278 workInProgress.effectTag |= Snapshot;
4279 }
4280 }
4281 return false;
4282 }
4283
4284 if (typeof getDerivedStateFromProps === 'function') {
4285 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4286 newState = workInProgress.memoizedState;
4287 }
4288
4289 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4290
4291 if (shouldUpdate) {
4292 // In order to support react-lifecycles-compat polyfilled components,
4293 // Unsafe lifecycles should not be invoked for components using the new APIs.
4294 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4295 startPhaseTimer(workInProgress, 'componentWillUpdate');
4296 if (typeof instance.componentWillUpdate === 'function') {
4297 instance.componentWillUpdate(newProps, newState, nextContext);
4298 }
4299 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4300 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4301 }
4302 stopPhaseTimer();
4303 }
4304 if (typeof instance.componentDidUpdate === 'function') {
4305 workInProgress.effectTag |= Update;
4306 }
4307 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4308 workInProgress.effectTag |= Snapshot;
4309 }
4310 } else {
4311 // If an update was already in progress, we should schedule an Update
4312 // effect even though we're bailing out, so that cWU/cDU are called.
4313 if (typeof instance.componentDidUpdate === 'function') {
4314 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4315 workInProgress.effectTag |= Update;
4316 }
4317 }
4318 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4319 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4320 workInProgress.effectTag |= Snapshot;
4321 }
4322 }
4323
4324 // If shouldComponentUpdate returned false, we should still update the
4325 // memoized props/state to indicate that this work can be reused.
4326 workInProgress.memoizedProps = newProps;
4327 workInProgress.memoizedState = newState;
4328 }
4329
4330 // Update the existing instance's state, props, and context pointers even
4331 // if shouldComponentUpdate returns false.
4332 instance.props = newProps;
4333 instance.state = newState;
4334 instance.context = nextContext;
4335
4336 return shouldUpdate;
4337}
4338
4339var didWarnAboutMaps = void 0;
4340var didWarnAboutGenerators = void 0;
4341var didWarnAboutStringRefInStrictMode = void 0;
4342var ownerHasKeyUseWarning = void 0;
4343var ownerHasFunctionTypeWarning = void 0;
4344var warnForMissingKey = function (child) {};
4345
4346{
4347 didWarnAboutMaps = false;
4348 didWarnAboutGenerators = false;
4349 didWarnAboutStringRefInStrictMode = {};
4350
4351 /**
4352 * Warn if there's no key explicitly set on dynamic arrays of children or
4353 * object keys are not valid. This allows us to keep track of children between
4354 * updates.
4355 */
4356 ownerHasKeyUseWarning = {};
4357 ownerHasFunctionTypeWarning = {};
4358
4359 warnForMissingKey = function (child) {
4360 if (child === null || typeof child !== 'object') {
4361 return;
4362 }
4363 if (!child._store || child._store.validated || child.key != null) {
4364 return;
4365 }
4366 !(typeof child._store === 'object') ? invariant(false, 'React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.') : void 0;
4367 child._store.validated = true;
4368
4369 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4370 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4371 return;
4372 }
4373 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4374
4375 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4376 };
4377}
4378
4379var isArray = Array.isArray;
4380
4381function coerceRef(returnFiber, current, element) {
4382 var mixedRef = element.ref;
4383 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4384 {
4385 if (returnFiber.mode & StrictMode) {
4386 var componentName = getComponentName(returnFiber.type) || 'Component';
4387 if (!didWarnAboutStringRefInStrictMode[componentName]) {
4388 warningWithoutStack$1(false, 'A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using createRef() instead.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-string-ref', mixedRef, getStackByFiberInDevAndProd(returnFiber));
4389 didWarnAboutStringRefInStrictMode[componentName] = true;
4390 }
4391 }
4392 }
4393
4394 if (element._owner) {
4395 var owner = element._owner;
4396 var inst = void 0;
4397 if (owner) {
4398 var ownerFiber = owner;
4399 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
4400 inst = ownerFiber.stateNode;
4401 }
4402 !inst ? invariant(false, 'Missing owner for string ref %s. This error is likely caused by a bug in React. Please file an issue.', mixedRef) : void 0;
4403 var stringRef = '' + mixedRef;
4404 // Check if previous string ref matches new string ref
4405 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4406 return current.ref;
4407 }
4408 var ref = function (value) {
4409 var refs = inst.refs;
4410 if (refs === emptyRefsObject) {
4411 // This is a lazy pooled frozen object, so we need to initialize.
4412 refs = inst.refs = {};
4413 }
4414 if (value === null) {
4415 delete refs[stringRef];
4416 } else {
4417 refs[stringRef] = value;
4418 }
4419 };
4420 ref._stringRef = stringRef;
4421 return ref;
4422 } else {
4423 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
4424 !element._owner ? invariant(false, 'Element ref was specified as a string (%s) 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.', mixedRef) : void 0;
4425 }
4426 }
4427 return mixedRef;
4428}
4429
4430function throwOnInvalidObjectType(returnFiber, newChild) {
4431 if (returnFiber.type !== 'textarea') {
4432 var addendum = '';
4433 {
4434 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4435 }
4436 invariant(false, 'Objects are not valid as a React child (found: %s).%s', Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild, addendum);
4437 }
4438}
4439
4440function warnOnFunctionType() {
4441 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();
4442
4443 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4444 return;
4445 }
4446 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4447
4448 warning$1(false, 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
4449}
4450
4451// This wrapper function exists because I expect to clone the code in each path
4452// to be able to optimize each path individually by branching early. This needs
4453// a compiler or we can do it manually. Helpers that don't need this branching
4454// live outside of this function.
4455function ChildReconciler(shouldTrackSideEffects) {
4456 function deleteChild(returnFiber, childToDelete) {
4457 if (!shouldTrackSideEffects) {
4458 // Noop.
4459 return;
4460 }
4461 // Deletions are added in reversed order so we add it to the front.
4462 // At this point, the return fiber's effect list is empty except for
4463 // deletions, so we can just append the deletion to the list. The remaining
4464 // effects aren't added until the complete phase. Once we implement
4465 // resuming, this may not be true.
4466 var last = returnFiber.lastEffect;
4467 if (last !== null) {
4468 last.nextEffect = childToDelete;
4469 returnFiber.lastEffect = childToDelete;
4470 } else {
4471 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4472 }
4473 childToDelete.nextEffect = null;
4474 childToDelete.effectTag = Deletion;
4475 }
4476
4477 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4478 if (!shouldTrackSideEffects) {
4479 // Noop.
4480 return null;
4481 }
4482
4483 // TODO: For the shouldClone case, this could be micro-optimized a bit by
4484 // assuming that after the first child we've already added everything.
4485 var childToDelete = currentFirstChild;
4486 while (childToDelete !== null) {
4487 deleteChild(returnFiber, childToDelete);
4488 childToDelete = childToDelete.sibling;
4489 }
4490 return null;
4491 }
4492
4493 function mapRemainingChildren(returnFiber, currentFirstChild) {
4494 // Add the remaining children to a temporary map so that we can find them by
4495 // keys quickly. Implicit (null) keys get added to this set with their index
4496 var existingChildren = new Map();
4497
4498 var existingChild = currentFirstChild;
4499 while (existingChild !== null) {
4500 if (existingChild.key !== null) {
4501 existingChildren.set(existingChild.key, existingChild);
4502 } else {
4503 existingChildren.set(existingChild.index, existingChild);
4504 }
4505 existingChild = existingChild.sibling;
4506 }
4507 return existingChildren;
4508 }
4509
4510 function useFiber(fiber, pendingProps, expirationTime) {
4511 // We currently set sibling to null and index to 0 here because it is easy
4512 // to forget to do before returning it. E.g. for the single child case.
4513 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
4514 clone.index = 0;
4515 clone.sibling = null;
4516 return clone;
4517 }
4518
4519 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4520 newFiber.index = newIndex;
4521 if (!shouldTrackSideEffects) {
4522 // Noop.
4523 return lastPlacedIndex;
4524 }
4525 var current = newFiber.alternate;
4526 if (current !== null) {
4527 var oldIndex = current.index;
4528 if (oldIndex < lastPlacedIndex) {
4529 // This is a move.
4530 newFiber.effectTag = Placement;
4531 return lastPlacedIndex;
4532 } else {
4533 // This item can stay in place.
4534 return oldIndex;
4535 }
4536 } else {
4537 // This is an insertion.
4538 newFiber.effectTag = Placement;
4539 return lastPlacedIndex;
4540 }
4541 }
4542
4543 function placeSingleChild(newFiber) {
4544 // This is simpler for the single child case. We only need to do a
4545 // placement for inserting new children.
4546 if (shouldTrackSideEffects && newFiber.alternate === null) {
4547 newFiber.effectTag = Placement;
4548 }
4549 return newFiber;
4550 }
4551
4552 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4553 if (current === null || current.tag !== HostText) {
4554 // Insert
4555 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4556 created.return = returnFiber;
4557 return created;
4558 } else {
4559 // Update
4560 var existing = useFiber(current, textContent, expirationTime);
4561 existing.return = returnFiber;
4562 return existing;
4563 }
4564 }
4565
4566 function updateElement(returnFiber, current, element, expirationTime) {
4567 if (current !== null && current.elementType === element.type) {
4568 // Move based on index
4569 var existing = useFiber(current, element.props, expirationTime);
4570 existing.ref = coerceRef(returnFiber, current, element);
4571 existing.return = returnFiber;
4572 {
4573 existing._debugSource = element._source;
4574 existing._debugOwner = element._owner;
4575 }
4576 return existing;
4577 } else {
4578 // Insert
4579 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4580 created.ref = coerceRef(returnFiber, current, element);
4581 created.return = returnFiber;
4582 return created;
4583 }
4584 }
4585
4586 function updatePortal(returnFiber, current, portal, expirationTime) {
4587 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4588 // Insert
4589 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4590 created.return = returnFiber;
4591 return created;
4592 } else {
4593 // Update
4594 var existing = useFiber(current, portal.children || [], expirationTime);
4595 existing.return = returnFiber;
4596 return existing;
4597 }
4598 }
4599
4600 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4601 if (current === null || current.tag !== Fragment) {
4602 // Insert
4603 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4604 created.return = returnFiber;
4605 return created;
4606 } else {
4607 // Update
4608 var existing = useFiber(current, fragment, expirationTime);
4609 existing.return = returnFiber;
4610 return existing;
4611 }
4612 }
4613
4614 function createChild(returnFiber, newChild, expirationTime) {
4615 if (typeof newChild === 'string' || typeof newChild === 'number') {
4616 // Text nodes don't have keys. If the previous node is implicitly keyed
4617 // we can continue to replace it without aborting even if it is not a text
4618 // node.
4619 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4620 created.return = returnFiber;
4621 return created;
4622 }
4623
4624 if (typeof newChild === 'object' && newChild !== null) {
4625 switch (newChild.$$typeof) {
4626 case REACT_ELEMENT_TYPE:
4627 {
4628 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4629 _created.ref = coerceRef(returnFiber, null, newChild);
4630 _created.return = returnFiber;
4631 return _created;
4632 }
4633 case REACT_PORTAL_TYPE:
4634 {
4635 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4636 _created2.return = returnFiber;
4637 return _created2;
4638 }
4639 }
4640
4641 if (isArray(newChild) || getIteratorFn(newChild)) {
4642 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4643 _created3.return = returnFiber;
4644 return _created3;
4645 }
4646
4647 throwOnInvalidObjectType(returnFiber, newChild);
4648 }
4649
4650 {
4651 if (typeof newChild === 'function') {
4652 warnOnFunctionType();
4653 }
4654 }
4655
4656 return null;
4657 }
4658
4659 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4660 // Update the fiber if the keys match, otherwise return null.
4661
4662 var key = oldFiber !== null ? oldFiber.key : null;
4663
4664 if (typeof newChild === 'string' || typeof newChild === 'number') {
4665 // Text nodes don't have keys. If the previous node is implicitly keyed
4666 // we can continue to replace it without aborting even if it is not a text
4667 // node.
4668 if (key !== null) {
4669 return null;
4670 }
4671 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4672 }
4673
4674 if (typeof newChild === 'object' && newChild !== null) {
4675 switch (newChild.$$typeof) {
4676 case REACT_ELEMENT_TYPE:
4677 {
4678 if (newChild.key === key) {
4679 if (newChild.type === REACT_FRAGMENT_TYPE) {
4680 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4681 }
4682 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4683 } else {
4684 return null;
4685 }
4686 }
4687 case REACT_PORTAL_TYPE:
4688 {
4689 if (newChild.key === key) {
4690 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4691 } else {
4692 return null;
4693 }
4694 }
4695 }
4696
4697 if (isArray(newChild) || getIteratorFn(newChild)) {
4698 if (key !== null) {
4699 return null;
4700 }
4701
4702 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4703 }
4704
4705 throwOnInvalidObjectType(returnFiber, newChild);
4706 }
4707
4708 {
4709 if (typeof newChild === 'function') {
4710 warnOnFunctionType();
4711 }
4712 }
4713
4714 return null;
4715 }
4716
4717 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4718 if (typeof newChild === 'string' || typeof newChild === 'number') {
4719 // Text nodes don't have keys, so we neither have to check the old nor
4720 // new node for the key. If both are text nodes, they match.
4721 var matchedFiber = existingChildren.get(newIdx) || null;
4722 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4723 }
4724
4725 if (typeof newChild === 'object' && newChild !== null) {
4726 switch (newChild.$$typeof) {
4727 case REACT_ELEMENT_TYPE:
4728 {
4729 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4730 if (newChild.type === REACT_FRAGMENT_TYPE) {
4731 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4732 }
4733 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4734 }
4735 case REACT_PORTAL_TYPE:
4736 {
4737 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4738 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4739 }
4740 }
4741
4742 if (isArray(newChild) || getIteratorFn(newChild)) {
4743 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4744 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4745 }
4746
4747 throwOnInvalidObjectType(returnFiber, newChild);
4748 }
4749
4750 {
4751 if (typeof newChild === 'function') {
4752 warnOnFunctionType();
4753 }
4754 }
4755
4756 return null;
4757 }
4758
4759 /**
4760 * Warns if there is a duplicate or missing key
4761 */
4762 function warnOnInvalidKey(child, knownKeys) {
4763 {
4764 if (typeof child !== 'object' || child === null) {
4765 return knownKeys;
4766 }
4767 switch (child.$$typeof) {
4768 case REACT_ELEMENT_TYPE:
4769 case REACT_PORTAL_TYPE:
4770 warnForMissingKey(child);
4771 var key = child.key;
4772 if (typeof key !== 'string') {
4773 break;
4774 }
4775 if (knownKeys === null) {
4776 knownKeys = new Set();
4777 knownKeys.add(key);
4778 break;
4779 }
4780 if (!knownKeys.has(key)) {
4781 knownKeys.add(key);
4782 break;
4783 }
4784 warning$1(false, 'Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
4785 break;
4786 default:
4787 break;
4788 }
4789 }
4790 return knownKeys;
4791 }
4792
4793 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4794 // This algorithm can't optimize by searching from both ends since we
4795 // don't have backpointers on fibers. I'm trying to see how far we can get
4796 // with that model. If it ends up not being worth the tradeoffs, we can
4797 // add it later.
4798
4799 // Even with a two ended optimization, we'd want to optimize for the case
4800 // where there are few changes and brute force the comparison instead of
4801 // going for the Map. It'd like to explore hitting that path first in
4802 // forward-only mode and only go for the Map once we notice that we need
4803 // lots of look ahead. This doesn't handle reversal as well as two ended
4804 // search but that's unusual. Besides, for the two ended optimization to
4805 // work on Iterables, we'd need to copy the whole set.
4806
4807 // In this first iteration, we'll just live with hitting the bad case
4808 // (adding everything to a Map) in for every insert/move.
4809
4810 // If you change this code, also update reconcileChildrenIterator() which
4811 // uses the same algorithm.
4812
4813 {
4814 // First, validate keys.
4815 var knownKeys = null;
4816 for (var i = 0; i < newChildren.length; i++) {
4817 var child = newChildren[i];
4818 knownKeys = warnOnInvalidKey(child, knownKeys);
4819 }
4820 }
4821
4822 var resultingFirstChild = null;
4823 var previousNewFiber = null;
4824
4825 var oldFiber = currentFirstChild;
4826 var lastPlacedIndex = 0;
4827 var newIdx = 0;
4828 var nextOldFiber = null;
4829 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4830 if (oldFiber.index > newIdx) {
4831 nextOldFiber = oldFiber;
4832 oldFiber = null;
4833 } else {
4834 nextOldFiber = oldFiber.sibling;
4835 }
4836 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4837 if (newFiber === null) {
4838 // TODO: This breaks on empty slots like null children. That's
4839 // unfortunate because it triggers the slow path all the time. We need
4840 // a better way to communicate whether this was a miss or null,
4841 // boolean, undefined, etc.
4842 if (oldFiber === null) {
4843 oldFiber = nextOldFiber;
4844 }
4845 break;
4846 }
4847 if (shouldTrackSideEffects) {
4848 if (oldFiber && newFiber.alternate === null) {
4849 // We matched the slot, but we didn't reuse the existing fiber, so we
4850 // need to delete the existing child.
4851 deleteChild(returnFiber, oldFiber);
4852 }
4853 }
4854 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4855 if (previousNewFiber === null) {
4856 // TODO: Move out of the loop. This only happens for the first run.
4857 resultingFirstChild = newFiber;
4858 } else {
4859 // TODO: Defer siblings if we're not at the right index for this slot.
4860 // I.e. if we had null values before, then we want to defer this
4861 // for each null value. However, we also don't want to call updateSlot
4862 // with the previous one.
4863 previousNewFiber.sibling = newFiber;
4864 }
4865 previousNewFiber = newFiber;
4866 oldFiber = nextOldFiber;
4867 }
4868
4869 if (newIdx === newChildren.length) {
4870 // We've reached the end of the new children. We can delete the rest.
4871 deleteRemainingChildren(returnFiber, oldFiber);
4872 return resultingFirstChild;
4873 }
4874
4875 if (oldFiber === null) {
4876 // If we don't have any more existing children we can choose a fast path
4877 // since the rest will all be insertions.
4878 for (; newIdx < newChildren.length; newIdx++) {
4879 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
4880 if (!_newFiber) {
4881 continue;
4882 }
4883 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
4884 if (previousNewFiber === null) {
4885 // TODO: Move out of the loop. This only happens for the first run.
4886 resultingFirstChild = _newFiber;
4887 } else {
4888 previousNewFiber.sibling = _newFiber;
4889 }
4890 previousNewFiber = _newFiber;
4891 }
4892 return resultingFirstChild;
4893 }
4894
4895 // Add all children to a key map for quick lookups.
4896 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
4897
4898 // Keep scanning and use the map to restore deleted items as moves.
4899 for (; newIdx < newChildren.length; newIdx++) {
4900 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
4901 if (_newFiber2) {
4902 if (shouldTrackSideEffects) {
4903 if (_newFiber2.alternate !== null) {
4904 // The new fiber is a work in progress, but if there exists a
4905 // current, that means that we reused the fiber. We need to delete
4906 // it from the child list so that we don't add it to the deletion
4907 // list.
4908 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
4909 }
4910 }
4911 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
4912 if (previousNewFiber === null) {
4913 resultingFirstChild = _newFiber2;
4914 } else {
4915 previousNewFiber.sibling = _newFiber2;
4916 }
4917 previousNewFiber = _newFiber2;
4918 }
4919 }
4920
4921 if (shouldTrackSideEffects) {
4922 // Any existing children that weren't consumed above were deleted. We need
4923 // to add them to the deletion list.
4924 existingChildren.forEach(function (child) {
4925 return deleteChild(returnFiber, child);
4926 });
4927 }
4928
4929 return resultingFirstChild;
4930 }
4931
4932 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
4933 // This is the same implementation as reconcileChildrenArray(),
4934 // but using the iterator instead.
4935
4936 var iteratorFn = getIteratorFn(newChildrenIterable);
4937 !(typeof iteratorFn === 'function') ? invariant(false, 'An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.') : void 0;
4938
4939 {
4940 // We don't support rendering Generators because it's a mutation.
4941 // See https://github.com/facebook/react/issues/12995
4942 if (typeof Symbol === 'function' &&
4943 // $FlowFixMe Flow doesn't know about toStringTag
4944 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
4945 !didWarnAboutGenerators ? warning$1(false, 'Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.') : void 0;
4946 didWarnAboutGenerators = true;
4947 }
4948
4949 // Warn about using Maps as children
4950 if (newChildrenIterable.entries === iteratorFn) {
4951 !didWarnAboutMaps ? warning$1(false, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.') : void 0;
4952 didWarnAboutMaps = true;
4953 }
4954
4955 // First, validate keys.
4956 // We'll get a different iterator later for the main pass.
4957 var _newChildren = iteratorFn.call(newChildrenIterable);
4958 if (_newChildren) {
4959 var knownKeys = null;
4960 var _step = _newChildren.next();
4961 for (; !_step.done; _step = _newChildren.next()) {
4962 var child = _step.value;
4963 knownKeys = warnOnInvalidKey(child, knownKeys);
4964 }
4965 }
4966 }
4967
4968 var newChildren = iteratorFn.call(newChildrenIterable);
4969 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
4970
4971 var resultingFirstChild = null;
4972 var previousNewFiber = null;
4973
4974 var oldFiber = currentFirstChild;
4975 var lastPlacedIndex = 0;
4976 var newIdx = 0;
4977 var nextOldFiber = null;
4978
4979 var step = newChildren.next();
4980 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
4981 if (oldFiber.index > newIdx) {
4982 nextOldFiber = oldFiber;
4983 oldFiber = null;
4984 } else {
4985 nextOldFiber = oldFiber.sibling;
4986 }
4987 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
4988 if (newFiber === null) {
4989 // TODO: This breaks on empty slots like null children. That's
4990 // unfortunate because it triggers the slow path all the time. We need
4991 // a better way to communicate whether this was a miss or null,
4992 // boolean, undefined, etc.
4993 if (!oldFiber) {
4994 oldFiber = nextOldFiber;
4995 }
4996 break;
4997 }
4998 if (shouldTrackSideEffects) {
4999 if (oldFiber && newFiber.alternate === null) {
5000 // We matched the slot, but we didn't reuse the existing fiber, so we
5001 // need to delete the existing child.
5002 deleteChild(returnFiber, oldFiber);
5003 }
5004 }
5005 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5006 if (previousNewFiber === null) {
5007 // TODO: Move out of the loop. This only happens for the first run.
5008 resultingFirstChild = newFiber;
5009 } else {
5010 // TODO: Defer siblings if we're not at the right index for this slot.
5011 // I.e. if we had null values before, then we want to defer this
5012 // for each null value. However, we also don't want to call updateSlot
5013 // with the previous one.
5014 previousNewFiber.sibling = newFiber;
5015 }
5016 previousNewFiber = newFiber;
5017 oldFiber = nextOldFiber;
5018 }
5019
5020 if (step.done) {
5021 // We've reached the end of the new children. We can delete the rest.
5022 deleteRemainingChildren(returnFiber, oldFiber);
5023 return resultingFirstChild;
5024 }
5025
5026 if (oldFiber === null) {
5027 // If we don't have any more existing children we can choose a fast path
5028 // since the rest will all be insertions.
5029 for (; !step.done; newIdx++, step = newChildren.next()) {
5030 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5031 if (_newFiber3 === null) {
5032 continue;
5033 }
5034 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5035 if (previousNewFiber === null) {
5036 // TODO: Move out of the loop. This only happens for the first run.
5037 resultingFirstChild = _newFiber3;
5038 } else {
5039 previousNewFiber.sibling = _newFiber3;
5040 }
5041 previousNewFiber = _newFiber3;
5042 }
5043 return resultingFirstChild;
5044 }
5045
5046 // Add all children to a key map for quick lookups.
5047 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
5048
5049 // Keep scanning and use the map to restore deleted items as moves.
5050 for (; !step.done; newIdx++, step = newChildren.next()) {
5051 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5052 if (_newFiber4 !== null) {
5053 if (shouldTrackSideEffects) {
5054 if (_newFiber4.alternate !== null) {
5055 // The new fiber is a work in progress, but if there exists a
5056 // current, that means that we reused the fiber. We need to delete
5057 // it from the child list so that we don't add it to the deletion
5058 // list.
5059 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5060 }
5061 }
5062 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5063 if (previousNewFiber === null) {
5064 resultingFirstChild = _newFiber4;
5065 } else {
5066 previousNewFiber.sibling = _newFiber4;
5067 }
5068 previousNewFiber = _newFiber4;
5069 }
5070 }
5071
5072 if (shouldTrackSideEffects) {
5073 // Any existing children that weren't consumed above were deleted. We need
5074 // to add them to the deletion list.
5075 existingChildren.forEach(function (child) {
5076 return deleteChild(returnFiber, child);
5077 });
5078 }
5079
5080 return resultingFirstChild;
5081 }
5082
5083 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5084 // There's no need to check for keys on text nodes since we don't have a
5085 // way to define them.
5086 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5087 // We already have an existing node so let's just update it and delete
5088 // the rest.
5089 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5090 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5091 existing.return = returnFiber;
5092 return existing;
5093 }
5094 // The existing first child is not a text node so we need to create one
5095 // and delete the existing ones.
5096 deleteRemainingChildren(returnFiber, currentFirstChild);
5097 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5098 created.return = returnFiber;
5099 return created;
5100 }
5101
5102 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5103 var key = element.key;
5104 var child = currentFirstChild;
5105 while (child !== null) {
5106 // TODO: If key === null and child.key === null, then this only applies to
5107 // the first item in the list.
5108 if (child.key === key) {
5109 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
5110 deleteRemainingChildren(returnFiber, child.sibling);
5111 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
5112 existing.ref = coerceRef(returnFiber, child, element);
5113 existing.return = returnFiber;
5114 {
5115 existing._debugSource = element._source;
5116 existing._debugOwner = element._owner;
5117 }
5118 return existing;
5119 } else {
5120 deleteRemainingChildren(returnFiber, child);
5121 break;
5122 }
5123 } else {
5124 deleteChild(returnFiber, child);
5125 }
5126 child = child.sibling;
5127 }
5128
5129 if (element.type === REACT_FRAGMENT_TYPE) {
5130 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5131 created.return = returnFiber;
5132 return created;
5133 } else {
5134 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5135 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5136 _created4.return = returnFiber;
5137 return _created4;
5138 }
5139 }
5140
5141 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5142 var key = portal.key;
5143 var child = currentFirstChild;
5144 while (child !== null) {
5145 // TODO: If key === null and child.key === null, then this only applies to
5146 // the first item in the list.
5147 if (child.key === key) {
5148 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5149 deleteRemainingChildren(returnFiber, child.sibling);
5150 var existing = useFiber(child, portal.children || [], expirationTime);
5151 existing.return = returnFiber;
5152 return existing;
5153 } else {
5154 deleteRemainingChildren(returnFiber, child);
5155 break;
5156 }
5157 } else {
5158 deleteChild(returnFiber, child);
5159 }
5160 child = child.sibling;
5161 }
5162
5163 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5164 created.return = returnFiber;
5165 return created;
5166 }
5167
5168 // This API will tag the children with the side-effect of the reconciliation
5169 // itself. They will be added to the side-effect list as we pass through the
5170 // children and the parent.
5171 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5172 // This function is not recursive.
5173 // If the top level item is an array, we treat it as a set of children,
5174 // not as a fragment. Nested arrays on the other hand will be treated as
5175 // fragment nodes. Recursion happens at the normal flow.
5176
5177 // Handle top level unkeyed fragments as if they were arrays.
5178 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5179 // We treat the ambiguous cases above the same.
5180 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5181 if (isUnkeyedTopLevelFragment) {
5182 newChild = newChild.props.children;
5183 }
5184
5185 // Handle object types
5186 var isObject = typeof newChild === 'object' && newChild !== null;
5187
5188 if (isObject) {
5189 switch (newChild.$$typeof) {
5190 case REACT_ELEMENT_TYPE:
5191 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5192 case REACT_PORTAL_TYPE:
5193 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5194 }
5195 }
5196
5197 if (typeof newChild === 'string' || typeof newChild === 'number') {
5198 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5199 }
5200
5201 if (isArray(newChild)) {
5202 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5203 }
5204
5205 if (getIteratorFn(newChild)) {
5206 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5207 }
5208
5209 if (isObject) {
5210 throwOnInvalidObjectType(returnFiber, newChild);
5211 }
5212
5213 {
5214 if (typeof newChild === 'function') {
5215 warnOnFunctionType();
5216 }
5217 }
5218 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5219 // If the new child is undefined, and the return fiber is a composite
5220 // component, throw an error. If Fiber return types are disabled,
5221 // we already threw above.
5222 switch (returnFiber.tag) {
5223 case ClassComponent:
5224 {
5225 {
5226 var instance = returnFiber.stateNode;
5227 if (instance.render._isMockFunction) {
5228 // We allow auto-mocks to proceed as if they're returning null.
5229 break;
5230 }
5231 }
5232 }
5233 // Intentionally fall through to the next case, which handles both
5234 // functions and classes
5235 // eslint-disable-next-lined no-fallthrough
5236 case FunctionComponent:
5237 {
5238 var Component = returnFiber.type;
5239 invariant(false, '%s(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.', Component.displayName || Component.name || 'Component');
5240 }
5241 }
5242 }
5243
5244 // Remaining cases are all treated as empty.
5245 return deleteRemainingChildren(returnFiber, currentFirstChild);
5246 }
5247
5248 return reconcileChildFibers;
5249}
5250
5251var reconcileChildFibers = ChildReconciler(true);
5252var mountChildFibers = ChildReconciler(false);
5253
5254function cloneChildFibers(current, workInProgress) {
5255 !(current === null || workInProgress.child === current.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
5256
5257 if (workInProgress.child === null) {
5258 return;
5259 }
5260
5261 var currentChild = workInProgress.child;
5262 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5263 workInProgress.child = newChild;
5264
5265 newChild.return = workInProgress;
5266 while (currentChild.sibling !== null) {
5267 currentChild = currentChild.sibling;
5268 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5269 newChild.return = workInProgress;
5270 }
5271 newChild.sibling = null;
5272}
5273
5274var NO_CONTEXT$1 = {};
5275
5276var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5277var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5278var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5279
5280function requiredContext(c) {
5281 !(c !== NO_CONTEXT$1) ? invariant(false, 'Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.') : void 0;
5282 return c;
5283}
5284
5285function getRootHostContainer() {
5286 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5287 return rootInstance;
5288}
5289
5290function pushHostContainer(fiber, nextRootInstance) {
5291 // Push current root instance onto the stack;
5292 // This allows us to reset root when portals are popped.
5293 push(rootInstanceStackCursor, nextRootInstance, fiber);
5294 // Track the context and the Fiber that provided it.
5295 // This enables us to pop only Fibers that provide unique contexts.
5296 push(contextFiberStackCursor, fiber, fiber);
5297
5298 // Finally, we need to push the host context to the stack.
5299 // However, we can't just call getRootHostContext() and push it because
5300 // we'd have a different number of entries on the stack depending on
5301 // whether getRootHostContext() throws somewhere in renderer code or not.
5302 // So we push an empty value first. This lets us safely unwind on errors.
5303 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5304 var nextRootContext = getRootHostContext(nextRootInstance);
5305 // Now that we know this function doesn't throw, replace it.
5306 pop(contextStackCursor$1, fiber);
5307 push(contextStackCursor$1, nextRootContext, fiber);
5308}
5309
5310function popHostContainer(fiber) {
5311 pop(contextStackCursor$1, fiber);
5312 pop(contextFiberStackCursor, fiber);
5313 pop(rootInstanceStackCursor, fiber);
5314}
5315
5316function getHostContext() {
5317 var context = requiredContext(contextStackCursor$1.current);
5318 return context;
5319}
5320
5321function pushHostContext(fiber) {
5322 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5323 var context = requiredContext(contextStackCursor$1.current);
5324 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
5325
5326 // Don't push this Fiber's context unless it's unique.
5327 if (context === nextContext) {
5328 return;
5329 }
5330
5331 // Track the context and the Fiber that provided it.
5332 // This enables us to pop only Fibers that provide unique contexts.
5333 push(contextFiberStackCursor, fiber, fiber);
5334 push(contextStackCursor$1, nextContext, fiber);
5335}
5336
5337function popHostContext(fiber) {
5338 // Do not pop unless this Fiber provided the current context.
5339 // pushHostContext() only pushes Fibers that provide unique contexts.
5340 if (contextFiberStackCursor.current !== fiber) {
5341 return;
5342 }
5343
5344 pop(contextStackCursor$1, fiber);
5345 pop(contextFiberStackCursor, fiber);
5346}
5347
5348var NoEffect$1 = /* */0;
5349var UnmountSnapshot = /* */2;
5350var UnmountMutation = /* */4;
5351var MountMutation = /* */8;
5352var UnmountLayout = /* */16;
5353var MountLayout = /* */32;
5354var MountPassive = /* */64;
5355var UnmountPassive = /* */128;
5356
5357var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
5358
5359
5360var didWarnAboutMismatchedHooksForComponent = void 0;
5361{
5362 didWarnAboutMismatchedHooksForComponent = new Set();
5363}
5364
5365// These are set right before calling the component.
5366var renderExpirationTime = NoWork;
5367// The work-in-progress fiber. I've named it differently to distinguish it from
5368// the work-in-progress hook.
5369var currentlyRenderingFiber$1 = null;
5370
5371// Hooks are stored as a linked list on the fiber's memoizedState field. The
5372// current hook list is the list that belongs to the current fiber. The
5373// work-in-progress hook list is a new list that will be added to the
5374// work-in-progress fiber.
5375var currentHook = null;
5376var nextCurrentHook = null;
5377var firstWorkInProgressHook = null;
5378var workInProgressHook = null;
5379var nextWorkInProgressHook = null;
5380
5381var remainingExpirationTime = NoWork;
5382var componentUpdateQueue = null;
5383var sideEffectTag = 0;
5384
5385// Updates scheduled during render will trigger an immediate re-render at the
5386// end of the current pass. We can't store these updates on the normal queue,
5387// because if the work is aborted, they should be discarded. Because this is
5388// a relatively rare case, we also don't want to add an additional field to
5389// either the hook or queue object types. So we store them in a lazily create
5390// map of queue -> render-phase updates, which are discarded once the component
5391// completes without re-rendering.
5392
5393// Whether an update was scheduled during the currently executing render pass.
5394var didScheduleRenderPhaseUpdate = false;
5395// Lazily created map of render-phase updates
5396var renderPhaseUpdates = null;
5397// Counter to prevent infinite loops.
5398var numberOfReRenders = 0;
5399var RE_RENDER_LIMIT = 25;
5400
5401// In DEV, this is the name of the currently executing primitive hook
5402var currentHookNameInDev = null;
5403
5404// In DEV, this list ensures that hooks are called in the same order between renders.
5405// The list stores the order of hooks used during the initial render (mount).
5406// Subsequent renders (updates) reference this list.
5407var hookTypesDev = null;
5408var hookTypesUpdateIndexDev = -1;
5409
5410function mountHookTypesDev() {
5411 {
5412 var hookName = currentHookNameInDev;
5413
5414 if (hookTypesDev === null) {
5415 hookTypesDev = [hookName];
5416 } else {
5417 hookTypesDev.push(hookName);
5418 }
5419 }
5420}
5421
5422function updateHookTypesDev() {
5423 {
5424 var hookName = currentHookNameInDev;
5425
5426 if (hookTypesDev !== null) {
5427 hookTypesUpdateIndexDev++;
5428 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
5429 warnOnHookMismatchInDev(hookName);
5430 }
5431 }
5432 }
5433}
5434
5435function warnOnHookMismatchInDev(currentHookName) {
5436 {
5437 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5438 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5439 didWarnAboutMismatchedHooksForComponent.add(componentName);
5440
5441 if (hookTypesDev !== null) {
5442 var table = '';
5443
5444 var secondColumnStart = 30;
5445
5446 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
5447 var oldHookName = hookTypesDev[i];
5448 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
5449
5450 var row = i + 1 + '. ' + oldHookName;
5451
5452 // Extra space so second column lines up
5453 // lol @ IE not supporting String#repeat
5454 while (row.length < secondColumnStart) {
5455 row += ' ';
5456 }
5457
5458 row += newHookName + '\n';
5459
5460 table += row;
5461 }
5462
5463 warning$1(false, 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
5464 }
5465 }
5466 }
5467}
5468
5469function throwInvalidHookError() {
5470 invariant(false, '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.');
5471}
5472
5473function areHookInputsEqual(nextDeps, prevDeps) {
5474 if (prevDeps === null) {
5475 {
5476 warning$1(false, '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
5477 }
5478 return false;
5479 }
5480
5481 {
5482 // Don't bother comparing lengths in prod because these arrays should be
5483 // passed inline.
5484 if (nextDeps.length !== prevDeps.length) {
5485 warning$1(false, 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, '[' + nextDeps.join(', ') + ']', '[' + prevDeps.join(', ') + ']');
5486 }
5487 }
5488 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5489 if (is(nextDeps[i], prevDeps[i])) {
5490 continue;
5491 }
5492 return false;
5493 }
5494 return true;
5495}
5496
5497function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
5498 renderExpirationTime = nextRenderExpirationTime;
5499 currentlyRenderingFiber$1 = workInProgress;
5500 nextCurrentHook = current !== null ? current.memoizedState : null;
5501
5502 {
5503 hookTypesDev = current !== null ? current._debugHookTypes : null;
5504 hookTypesUpdateIndexDev = -1;
5505 }
5506
5507 // The following should have already been reset
5508 // currentHook = null;
5509 // workInProgressHook = null;
5510
5511 // remainingExpirationTime = NoWork;
5512 // componentUpdateQueue = null;
5513
5514 // didScheduleRenderPhaseUpdate = false;
5515 // renderPhaseUpdates = null;
5516 // numberOfReRenders = 0;
5517 // sideEffectTag = 0;
5518
5519 // TODO Warn if no hooks are used at all during mount, then some are used during update.
5520 // Currently we will identify the update render as a mount because nextCurrentHook === null.
5521 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
5522
5523 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
5524 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
5525 // so nextCurrentHook would be null during updates and mounts.
5526 {
5527 if (nextCurrentHook !== null) {
5528 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5529 } else if (hookTypesDev !== null) {
5530 // This dispatcher handles an edge case where a component is updating,
5531 // but no stateful hooks have been used.
5532 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
5533 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
5534 // This dispatcher does that.
5535 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
5536 } else {
5537 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
5538 }
5539 }
5540
5541 var children = Component(props, refOrContext);
5542
5543 if (didScheduleRenderPhaseUpdate) {
5544 do {
5545 didScheduleRenderPhaseUpdate = false;
5546 numberOfReRenders += 1;
5547
5548 // Start over from the beginning of the list
5549 nextCurrentHook = current !== null ? current.memoizedState : null;
5550 nextWorkInProgressHook = firstWorkInProgressHook;
5551
5552 currentHook = null;
5553 workInProgressHook = null;
5554 componentUpdateQueue = null;
5555
5556 {
5557 // Also validate hook order for cascading updates.
5558 hookTypesUpdateIndexDev = -1;
5559 }
5560
5561 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5562
5563 children = Component(props, refOrContext);
5564 } while (didScheduleRenderPhaseUpdate);
5565
5566 renderPhaseUpdates = null;
5567 numberOfReRenders = 0;
5568 }
5569
5570 // We can assume the previous dispatcher is always this one, since we set it
5571 // at the beginning of the render phase and there's no re-entrancy.
5572 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5573
5574 var renderedWork = currentlyRenderingFiber$1;
5575
5576 renderedWork.memoizedState = firstWorkInProgressHook;
5577 renderedWork.expirationTime = remainingExpirationTime;
5578 renderedWork.updateQueue = componentUpdateQueue;
5579 renderedWork.effectTag |= sideEffectTag;
5580
5581 {
5582 renderedWork._debugHookTypes = hookTypesDev;
5583 }
5584
5585 // This check uses currentHook so that it works the same in DEV and prod bundles.
5586 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
5587 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5588
5589 renderExpirationTime = NoWork;
5590 currentlyRenderingFiber$1 = null;
5591
5592 currentHook = null;
5593 nextCurrentHook = null;
5594 firstWorkInProgressHook = null;
5595 workInProgressHook = null;
5596 nextWorkInProgressHook = null;
5597
5598 {
5599 currentHookNameInDev = null;
5600 hookTypesDev = null;
5601 hookTypesUpdateIndexDev = -1;
5602 }
5603
5604 remainingExpirationTime = NoWork;
5605 componentUpdateQueue = null;
5606 sideEffectTag = 0;
5607
5608 // These were reset above
5609 // didScheduleRenderPhaseUpdate = false;
5610 // renderPhaseUpdates = null;
5611 // numberOfReRenders = 0;
5612
5613 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
5614
5615 return children;
5616}
5617
5618function bailoutHooks(current, workInProgress, expirationTime) {
5619 workInProgress.updateQueue = current.updateQueue;
5620 workInProgress.effectTag &= ~(Passive | Update);
5621 if (current.expirationTime <= expirationTime) {
5622 current.expirationTime = NoWork;
5623 }
5624}
5625
5626function resetHooks() {
5627 // We can assume the previous dispatcher is always this one, since we set it
5628 // at the beginning of the render phase and there's no re-entrancy.
5629 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5630
5631 // This is used to reset the state of this module when a component throws.
5632 // It's also called inside mountIndeterminateComponent if we determine the
5633 // component is a module-style component.
5634 renderExpirationTime = NoWork;
5635 currentlyRenderingFiber$1 = null;
5636
5637 currentHook = null;
5638 nextCurrentHook = null;
5639 firstWorkInProgressHook = null;
5640 workInProgressHook = null;
5641 nextWorkInProgressHook = null;
5642
5643 {
5644 hookTypesDev = null;
5645 hookTypesUpdateIndexDev = -1;
5646
5647 currentHookNameInDev = null;
5648 }
5649
5650 remainingExpirationTime = NoWork;
5651 componentUpdateQueue = null;
5652 sideEffectTag = 0;
5653
5654 didScheduleRenderPhaseUpdate = false;
5655 renderPhaseUpdates = null;
5656 numberOfReRenders = 0;
5657}
5658
5659function mountWorkInProgressHook() {
5660 var hook = {
5661 memoizedState: null,
5662
5663 baseState: null,
5664 queue: null,
5665 baseUpdate: null,
5666
5667 next: null
5668 };
5669
5670 if (workInProgressHook === null) {
5671 // This is the first hook in the list
5672 firstWorkInProgressHook = workInProgressHook = hook;
5673 } else {
5674 // Append to the end of the list
5675 workInProgressHook = workInProgressHook.next = hook;
5676 }
5677 return workInProgressHook;
5678}
5679
5680function updateWorkInProgressHook() {
5681 // This function is used both for updates and for re-renders triggered by a
5682 // render phase update. It assumes there is either a current hook we can
5683 // clone, or a work-in-progress hook from a previous render pass that we can
5684 // use as a base. When we reach the end of the base list, we must switch to
5685 // the dispatcher used for mounts.
5686 if (nextWorkInProgressHook !== null) {
5687 // There's already a work-in-progress. Reuse it.
5688 workInProgressHook = nextWorkInProgressHook;
5689 nextWorkInProgressHook = workInProgressHook.next;
5690
5691 currentHook = nextCurrentHook;
5692 nextCurrentHook = currentHook !== null ? currentHook.next : null;
5693 } else {
5694 // Clone from the current hook.
5695 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
5696 currentHook = nextCurrentHook;
5697
5698 var newHook = {
5699 memoizedState: currentHook.memoizedState,
5700
5701 baseState: currentHook.baseState,
5702 queue: currentHook.queue,
5703 baseUpdate: currentHook.baseUpdate,
5704
5705 next: null
5706 };
5707
5708 if (workInProgressHook === null) {
5709 // This is the first hook in the list.
5710 workInProgressHook = firstWorkInProgressHook = newHook;
5711 } else {
5712 // Append to the end of the list.
5713 workInProgressHook = workInProgressHook.next = newHook;
5714 }
5715 nextCurrentHook = currentHook.next;
5716 }
5717 return workInProgressHook;
5718}
5719
5720function createFunctionComponentUpdateQueue() {
5721 return {
5722 lastEffect: null
5723 };
5724}
5725
5726function basicStateReducer(state, action) {
5727 return typeof action === 'function' ? action(state) : action;
5728}
5729
5730function mountReducer(reducer, initialArg, init) {
5731 var hook = mountWorkInProgressHook();
5732 var initialState = void 0;
5733 if (init !== undefined) {
5734 initialState = init(initialArg);
5735 } else {
5736 initialState = initialArg;
5737 }
5738 hook.memoizedState = hook.baseState = initialState;
5739 var queue = hook.queue = {
5740 last: null,
5741 dispatch: null,
5742 lastRenderedReducer: reducer,
5743 lastRenderedState: initialState
5744 };
5745 var dispatch = queue.dispatch = dispatchAction.bind(null,
5746 // Flow doesn't know this is non-null, but we do.
5747 currentlyRenderingFiber$1, queue);
5748 return [hook.memoizedState, dispatch];
5749}
5750
5751function updateReducer(reducer, initialArg, init) {
5752 var hook = updateWorkInProgressHook();
5753 var queue = hook.queue;
5754 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
5755
5756 queue.lastRenderedReducer = reducer;
5757
5758 if (numberOfReRenders > 0) {
5759 // This is a re-render. Apply the new render phase updates to the previous
5760 var _dispatch = queue.dispatch;
5761 if (renderPhaseUpdates !== null) {
5762 // Render phase updates are stored in a map of queue -> linked list
5763 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
5764 if (firstRenderPhaseUpdate !== undefined) {
5765 renderPhaseUpdates.delete(queue);
5766 var newState = hook.memoizedState;
5767 var update = firstRenderPhaseUpdate;
5768 do {
5769 // Process this render phase update. We don't have to check the
5770 // priority because it will always be the same as the current
5771 // render's.
5772 var _action = update.action;
5773 newState = reducer(newState, _action);
5774 update = update.next;
5775 } while (update !== null);
5776
5777 // Mark that the fiber performed work, but only if the new state is
5778 // different from the current state.
5779 if (!is(newState, hook.memoizedState)) {
5780 markWorkInProgressReceivedUpdate();
5781 }
5782
5783 hook.memoizedState = newState;
5784 // Don't persist the state accumlated from the render phase updates to
5785 // the base state unless the queue is empty.
5786 // TODO: Not sure if this is the desired semantics, but it's what we
5787 // do for gDSFP. I can't remember why.
5788 if (hook.baseUpdate === queue.last) {
5789 hook.baseState = newState;
5790 }
5791
5792 queue.lastRenderedState = newState;
5793
5794 return [newState, _dispatch];
5795 }
5796 }
5797 return [hook.memoizedState, _dispatch];
5798 }
5799
5800 // The last update in the entire queue
5801 var last = queue.last;
5802 // The last update that is part of the base state.
5803 var baseUpdate = hook.baseUpdate;
5804 var baseState = hook.baseState;
5805
5806 // Find the first unprocessed update.
5807 var first = void 0;
5808 if (baseUpdate !== null) {
5809 if (last !== null) {
5810 // For the first update, the queue is a circular linked list where
5811 // `queue.last.next = queue.first`. Once the first update commits, and
5812 // the `baseUpdate` is no longer empty, we can unravel the list.
5813 last.next = null;
5814 }
5815 first = baseUpdate.next;
5816 } else {
5817 first = last !== null ? last.next : null;
5818 }
5819 if (first !== null) {
5820 var _newState = baseState;
5821 var newBaseState = null;
5822 var newBaseUpdate = null;
5823 var prevUpdate = baseUpdate;
5824 var _update = first;
5825 var didSkip = false;
5826 do {
5827 var updateExpirationTime = _update.expirationTime;
5828 if (updateExpirationTime < renderExpirationTime) {
5829 // Priority is insufficient. Skip this update. If this is the first
5830 // skipped update, the previous update/state is the new base
5831 // update/state.
5832 if (!didSkip) {
5833 didSkip = true;
5834 newBaseUpdate = prevUpdate;
5835 newBaseState = _newState;
5836 }
5837 // Update the remaining priority in the queue.
5838 if (updateExpirationTime > remainingExpirationTime) {
5839 remainingExpirationTime = updateExpirationTime;
5840 }
5841 } else {
5842 // Process this update.
5843 if (_update.eagerReducer === reducer) {
5844 // If this update was processed eagerly, and its reducer matches the
5845 // current reducer, we can use the eagerly computed state.
5846 _newState = _update.eagerState;
5847 } else {
5848 var _action2 = _update.action;
5849 _newState = reducer(_newState, _action2);
5850 }
5851 }
5852 prevUpdate = _update;
5853 _update = _update.next;
5854 } while (_update !== null && _update !== first);
5855
5856 if (!didSkip) {
5857 newBaseUpdate = prevUpdate;
5858 newBaseState = _newState;
5859 }
5860
5861 // Mark that the fiber performed work, but only if the new state is
5862 // different from the current state.
5863 if (!is(_newState, hook.memoizedState)) {
5864 markWorkInProgressReceivedUpdate();
5865 }
5866
5867 hook.memoizedState = _newState;
5868 hook.baseUpdate = newBaseUpdate;
5869 hook.baseState = newBaseState;
5870
5871 queue.lastRenderedState = _newState;
5872 }
5873
5874 var dispatch = queue.dispatch;
5875 return [hook.memoizedState, dispatch];
5876}
5877
5878function mountState(initialState) {
5879 var hook = mountWorkInProgressHook();
5880 if (typeof initialState === 'function') {
5881 initialState = initialState();
5882 }
5883 hook.memoizedState = hook.baseState = initialState;
5884 var queue = hook.queue = {
5885 last: null,
5886 dispatch: null,
5887 lastRenderedReducer: basicStateReducer,
5888 lastRenderedState: initialState
5889 };
5890 var dispatch = queue.dispatch = dispatchAction.bind(null,
5891 // Flow doesn't know this is non-null, but we do.
5892 currentlyRenderingFiber$1, queue);
5893 return [hook.memoizedState, dispatch];
5894}
5895
5896function updateState(initialState) {
5897 return updateReducer(basicStateReducer, initialState);
5898}
5899
5900function pushEffect(tag, create, destroy, deps) {
5901 var effect = {
5902 tag: tag,
5903 create: create,
5904 destroy: destroy,
5905 deps: deps,
5906 // Circular
5907 next: null
5908 };
5909 if (componentUpdateQueue === null) {
5910 componentUpdateQueue = createFunctionComponentUpdateQueue();
5911 componentUpdateQueue.lastEffect = effect.next = effect;
5912 } else {
5913 var _lastEffect = componentUpdateQueue.lastEffect;
5914 if (_lastEffect === null) {
5915 componentUpdateQueue.lastEffect = effect.next = effect;
5916 } else {
5917 var firstEffect = _lastEffect.next;
5918 _lastEffect.next = effect;
5919 effect.next = firstEffect;
5920 componentUpdateQueue.lastEffect = effect;
5921 }
5922 }
5923 return effect;
5924}
5925
5926function mountRef(initialValue) {
5927 var hook = mountWorkInProgressHook();
5928 var ref = { current: initialValue };
5929 {
5930 Object.seal(ref);
5931 }
5932 hook.memoizedState = ref;
5933 return ref;
5934}
5935
5936function updateRef(initialValue) {
5937 var hook = updateWorkInProgressHook();
5938 return hook.memoizedState;
5939}
5940
5941function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5942 var hook = mountWorkInProgressHook();
5943 var nextDeps = deps === undefined ? null : deps;
5944 sideEffectTag |= fiberEffectTag;
5945 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
5946}
5947
5948function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5949 var hook = updateWorkInProgressHook();
5950 var nextDeps = deps === undefined ? null : deps;
5951 var destroy = undefined;
5952
5953 if (currentHook !== null) {
5954 var prevEffect = currentHook.memoizedState;
5955 destroy = prevEffect.destroy;
5956 if (nextDeps !== null) {
5957 var prevDeps = prevEffect.deps;
5958 if (areHookInputsEqual(nextDeps, prevDeps)) {
5959 pushEffect(NoEffect$1, create, destroy, nextDeps);
5960 return;
5961 }
5962 }
5963 }
5964
5965 sideEffectTag |= fiberEffectTag;
5966 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
5967}
5968
5969function mountEffect(create, deps) {
5970 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5971}
5972
5973function updateEffect(create, deps) {
5974 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5975}
5976
5977function mountLayoutEffect(create, deps) {
5978 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5979}
5980
5981function updateLayoutEffect(create, deps) {
5982 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5983}
5984
5985function imperativeHandleEffect(create, ref) {
5986 if (typeof ref === 'function') {
5987 var refCallback = ref;
5988 var _inst = create();
5989 refCallback(_inst);
5990 return function () {
5991 refCallback(null);
5992 };
5993 } else if (ref !== null && ref !== undefined) {
5994 var refObject = ref;
5995 {
5996 !refObject.hasOwnProperty('current') ? warning$1(false, 'Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}') : void 0;
5997 }
5998 var _inst2 = create();
5999 refObject.current = _inst2;
6000 return function () {
6001 refObject.current = null;
6002 };
6003 }
6004}
6005
6006function mountImperativeHandle(ref, create, deps) {
6007 {
6008 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
6009 }
6010
6011 // TODO: If deps are provided, should we skip comparing the ref itself?
6012 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6013
6014 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6015}
6016
6017function updateImperativeHandle(ref, create, deps) {
6018 {
6019 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
6020 }
6021
6022 // TODO: If deps are provided, should we skip comparing the ref itself?
6023 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6024
6025 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6026}
6027
6028function mountDebugValue(value, formatterFn) {
6029 // This hook is normally a no-op.
6030 // The react-debug-hooks package injects its own implementation
6031 // so that e.g. DevTools can display custom hook values.
6032}
6033
6034var updateDebugValue = mountDebugValue;
6035
6036function mountCallback(callback, deps) {
6037 var hook = mountWorkInProgressHook();
6038 var nextDeps = deps === undefined ? null : deps;
6039 hook.memoizedState = [callback, nextDeps];
6040 return callback;
6041}
6042
6043function updateCallback(callback, deps) {
6044 var hook = updateWorkInProgressHook();
6045 var nextDeps = deps === undefined ? null : deps;
6046 var prevState = hook.memoizedState;
6047 if (prevState !== null) {
6048 if (nextDeps !== null) {
6049 var prevDeps = prevState[1];
6050 if (areHookInputsEqual(nextDeps, prevDeps)) {
6051 return prevState[0];
6052 }
6053 }
6054 }
6055 hook.memoizedState = [callback, nextDeps];
6056 return callback;
6057}
6058
6059function mountMemo(nextCreate, deps) {
6060 var hook = mountWorkInProgressHook();
6061 var nextDeps = deps === undefined ? null : deps;
6062 var nextValue = nextCreate();
6063 hook.memoizedState = [nextValue, nextDeps];
6064 return nextValue;
6065}
6066
6067function updateMemo(nextCreate, deps) {
6068 var hook = updateWorkInProgressHook();
6069 var nextDeps = deps === undefined ? null : deps;
6070 var prevState = hook.memoizedState;
6071 if (prevState !== null) {
6072 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6073 if (nextDeps !== null) {
6074 var prevDeps = prevState[1];
6075 if (areHookInputsEqual(nextDeps, prevDeps)) {
6076 return prevState[0];
6077 }
6078 }
6079 }
6080 var nextValue = nextCreate();
6081 hook.memoizedState = [nextValue, nextDeps];
6082 return nextValue;
6083}
6084
6085// in a test-like environment, we want to warn if dispatchAction()
6086// is called outside of a batchedUpdates/TestUtils.act(...) call.
6087var shouldWarnForUnbatchedSetState = false;
6088
6089{
6090 // jest isn't a 'global', it's just exposed to tests via a wrapped function
6091 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
6092 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
6093 if ('undefined' !== typeof jest) {
6094 shouldWarnForUnbatchedSetState = true;
6095 }
6096}
6097
6098function dispatchAction(fiber, queue, action) {
6099 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
6100
6101 {
6102 !(arguments.length <= 3) ? warning$1(false, "State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().') : void 0;
6103 }
6104
6105 var alternate = fiber.alternate;
6106 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6107 // This is a render phase update. Stash it in a lazily-created map of
6108 // queue -> linked list of updates. After this render pass, we'll restart
6109 // and apply the stashed updates on top of the work-in-progress hook.
6110 didScheduleRenderPhaseUpdate = true;
6111 var update = {
6112 expirationTime: renderExpirationTime,
6113 action: action,
6114 eagerReducer: null,
6115 eagerState: null,
6116 next: null
6117 };
6118 if (renderPhaseUpdates === null) {
6119 renderPhaseUpdates = new Map();
6120 }
6121 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6122 if (firstRenderPhaseUpdate === undefined) {
6123 renderPhaseUpdates.set(queue, update);
6124 } else {
6125 // Append the update to the end of the list.
6126 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
6127 while (lastRenderPhaseUpdate.next !== null) {
6128 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6129 }
6130 lastRenderPhaseUpdate.next = update;
6131 }
6132 } else {
6133 flushPassiveEffects();
6134
6135 var currentTime = requestCurrentTime();
6136 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
6137
6138 var _update2 = {
6139 expirationTime: _expirationTime,
6140 action: action,
6141 eagerReducer: null,
6142 eagerState: null,
6143 next: null
6144 };
6145
6146 // Append the update to the end of the list.
6147 var _last = queue.last;
6148 if (_last === null) {
6149 // This is the first update. Create a circular list.
6150 _update2.next = _update2;
6151 } else {
6152 var first = _last.next;
6153 if (first !== null) {
6154 // Still circular.
6155 _update2.next = first;
6156 }
6157 _last.next = _update2;
6158 }
6159 queue.last = _update2;
6160
6161 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6162 // The queue is currently empty, which means we can eagerly compute the
6163 // next state before entering the render phase. If the new state is the
6164 // same as the current state, we may be able to bail out entirely.
6165 var _lastRenderedReducer = queue.lastRenderedReducer;
6166 if (_lastRenderedReducer !== null) {
6167 var prevDispatcher = void 0;
6168 {
6169 prevDispatcher = ReactCurrentDispatcher$1.current;
6170 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6171 }
6172 try {
6173 var currentState = queue.lastRenderedState;
6174 var _eagerState = _lastRenderedReducer(currentState, action);
6175 // Stash the eagerly computed state, and the reducer used to compute
6176 // it, on the update object. If the reducer hasn't changed by the
6177 // time we enter the render phase, then the eager state can be used
6178 // without calling the reducer again.
6179 _update2.eagerReducer = _lastRenderedReducer;
6180 _update2.eagerState = _eagerState;
6181 if (is(_eagerState, currentState)) {
6182 // Fast path. We can bail out without scheduling React to re-render.
6183 // It's still possible that we'll need to rebase this update later,
6184 // if the component re-renders for a different reason and by that
6185 // time the reducer has changed.
6186 return;
6187 }
6188 } catch (error) {
6189 // Suppress the error. It will throw again in the render phase.
6190 } finally {
6191 {
6192 ReactCurrentDispatcher$1.current = prevDispatcher;
6193 }
6194 }
6195 }
6196 }
6197 {
6198 if (shouldWarnForUnbatchedSetState === true) {
6199 warnIfNotCurrentlyBatchingInDev(fiber);
6200 }
6201 }
6202 scheduleWork(fiber, _expirationTime);
6203 }
6204}
6205
6206var ContextOnlyDispatcher = {
6207 readContext: readContext,
6208
6209 useCallback: throwInvalidHookError,
6210 useContext: throwInvalidHookError,
6211 useEffect: throwInvalidHookError,
6212 useImperativeHandle: throwInvalidHookError,
6213 useLayoutEffect: throwInvalidHookError,
6214 useMemo: throwInvalidHookError,
6215 useReducer: throwInvalidHookError,
6216 useRef: throwInvalidHookError,
6217 useState: throwInvalidHookError,
6218 useDebugValue: throwInvalidHookError
6219};
6220
6221var HooksDispatcherOnMountInDEV = null;
6222var HooksDispatcherOnMountWithHookTypesInDEV = null;
6223var HooksDispatcherOnUpdateInDEV = null;
6224var InvalidNestedHooksDispatcherOnMountInDEV = null;
6225var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6226
6227{
6228 var warnInvalidContextAccess = function () {
6229 warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
6230 };
6231
6232 var warnInvalidHookAccess = function () {
6233 warning$1(false, 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');
6234 };
6235
6236 HooksDispatcherOnMountInDEV = {
6237 readContext: function (context, observedBits) {
6238 return readContext(context, observedBits);
6239 },
6240 useCallback: function (callback, deps) {
6241 currentHookNameInDev = 'useCallback';
6242 mountHookTypesDev();
6243 return mountCallback(callback, deps);
6244 },
6245 useContext: function (context, observedBits) {
6246 currentHookNameInDev = 'useContext';
6247 mountHookTypesDev();
6248 return readContext(context, observedBits);
6249 },
6250 useEffect: function (create, deps) {
6251 currentHookNameInDev = 'useEffect';
6252 mountHookTypesDev();
6253 return mountEffect(create, deps);
6254 },
6255 useImperativeHandle: function (ref, create, deps) {
6256 currentHookNameInDev = 'useImperativeHandle';
6257 mountHookTypesDev();
6258 return mountImperativeHandle(ref, create, deps);
6259 },
6260 useLayoutEffect: function (create, deps) {
6261 currentHookNameInDev = 'useLayoutEffect';
6262 mountHookTypesDev();
6263 return mountLayoutEffect(create, deps);
6264 },
6265 useMemo: function (create, deps) {
6266 currentHookNameInDev = 'useMemo';
6267 mountHookTypesDev();
6268 var prevDispatcher = ReactCurrentDispatcher$1.current;
6269 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6270 try {
6271 return mountMemo(create, deps);
6272 } finally {
6273 ReactCurrentDispatcher$1.current = prevDispatcher;
6274 }
6275 },
6276 useReducer: function (reducer, initialArg, init) {
6277 currentHookNameInDev = 'useReducer';
6278 mountHookTypesDev();
6279 var prevDispatcher = ReactCurrentDispatcher$1.current;
6280 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6281 try {
6282 return mountReducer(reducer, initialArg, init);
6283 } finally {
6284 ReactCurrentDispatcher$1.current = prevDispatcher;
6285 }
6286 },
6287 useRef: function (initialValue) {
6288 currentHookNameInDev = 'useRef';
6289 mountHookTypesDev();
6290 return mountRef(initialValue);
6291 },
6292 useState: function (initialState) {
6293 currentHookNameInDev = 'useState';
6294 mountHookTypesDev();
6295 var prevDispatcher = ReactCurrentDispatcher$1.current;
6296 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6297 try {
6298 return mountState(initialState);
6299 } finally {
6300 ReactCurrentDispatcher$1.current = prevDispatcher;
6301 }
6302 },
6303 useDebugValue: function (value, formatterFn) {
6304 currentHookNameInDev = 'useDebugValue';
6305 mountHookTypesDev();
6306 return mountDebugValue(value, formatterFn);
6307 }
6308 };
6309
6310 HooksDispatcherOnMountWithHookTypesInDEV = {
6311 readContext: function (context, observedBits) {
6312 return readContext(context, observedBits);
6313 },
6314 useCallback: function (callback, deps) {
6315 currentHookNameInDev = 'useCallback';
6316 updateHookTypesDev();
6317 return mountCallback(callback, deps);
6318 },
6319 useContext: function (context, observedBits) {
6320 currentHookNameInDev = 'useContext';
6321 updateHookTypesDev();
6322 return readContext(context, observedBits);
6323 },
6324 useEffect: function (create, deps) {
6325 currentHookNameInDev = 'useEffect';
6326 updateHookTypesDev();
6327 return mountEffect(create, deps);
6328 },
6329 useImperativeHandle: function (ref, create, deps) {
6330 currentHookNameInDev = 'useImperativeHandle';
6331 updateHookTypesDev();
6332 return mountImperativeHandle(ref, create, deps);
6333 },
6334 useLayoutEffect: function (create, deps) {
6335 currentHookNameInDev = 'useLayoutEffect';
6336 updateHookTypesDev();
6337 return mountLayoutEffect(create, deps);
6338 },
6339 useMemo: function (create, deps) {
6340 currentHookNameInDev = 'useMemo';
6341 updateHookTypesDev();
6342 var prevDispatcher = ReactCurrentDispatcher$1.current;
6343 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6344 try {
6345 return mountMemo(create, deps);
6346 } finally {
6347 ReactCurrentDispatcher$1.current = prevDispatcher;
6348 }
6349 },
6350 useReducer: function (reducer, initialArg, init) {
6351 currentHookNameInDev = 'useReducer';
6352 updateHookTypesDev();
6353 var prevDispatcher = ReactCurrentDispatcher$1.current;
6354 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6355 try {
6356 return mountReducer(reducer, initialArg, init);
6357 } finally {
6358 ReactCurrentDispatcher$1.current = prevDispatcher;
6359 }
6360 },
6361 useRef: function (initialValue) {
6362 currentHookNameInDev = 'useRef';
6363 updateHookTypesDev();
6364 return mountRef(initialValue);
6365 },
6366 useState: function (initialState) {
6367 currentHookNameInDev = 'useState';
6368 updateHookTypesDev();
6369 var prevDispatcher = ReactCurrentDispatcher$1.current;
6370 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6371 try {
6372 return mountState(initialState);
6373 } finally {
6374 ReactCurrentDispatcher$1.current = prevDispatcher;
6375 }
6376 },
6377 useDebugValue: function (value, formatterFn) {
6378 currentHookNameInDev = 'useDebugValue';
6379 updateHookTypesDev();
6380 return mountDebugValue(value, formatterFn);
6381 }
6382 };
6383
6384 HooksDispatcherOnUpdateInDEV = {
6385 readContext: function (context, observedBits) {
6386 return readContext(context, observedBits);
6387 },
6388 useCallback: function (callback, deps) {
6389 currentHookNameInDev = 'useCallback';
6390 updateHookTypesDev();
6391 return updateCallback(callback, deps);
6392 },
6393 useContext: function (context, observedBits) {
6394 currentHookNameInDev = 'useContext';
6395 updateHookTypesDev();
6396 return readContext(context, observedBits);
6397 },
6398 useEffect: function (create, deps) {
6399 currentHookNameInDev = 'useEffect';
6400 updateHookTypesDev();
6401 return updateEffect(create, deps);
6402 },
6403 useImperativeHandle: function (ref, create, deps) {
6404 currentHookNameInDev = 'useImperativeHandle';
6405 updateHookTypesDev();
6406 return updateImperativeHandle(ref, create, deps);
6407 },
6408 useLayoutEffect: function (create, deps) {
6409 currentHookNameInDev = 'useLayoutEffect';
6410 updateHookTypesDev();
6411 return updateLayoutEffect(create, deps);
6412 },
6413 useMemo: function (create, deps) {
6414 currentHookNameInDev = 'useMemo';
6415 updateHookTypesDev();
6416 var prevDispatcher = ReactCurrentDispatcher$1.current;
6417 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6418 try {
6419 return updateMemo(create, deps);
6420 } finally {
6421 ReactCurrentDispatcher$1.current = prevDispatcher;
6422 }
6423 },
6424 useReducer: function (reducer, initialArg, init) {
6425 currentHookNameInDev = 'useReducer';
6426 updateHookTypesDev();
6427 var prevDispatcher = ReactCurrentDispatcher$1.current;
6428 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6429 try {
6430 return updateReducer(reducer, initialArg, init);
6431 } finally {
6432 ReactCurrentDispatcher$1.current = prevDispatcher;
6433 }
6434 },
6435 useRef: function (initialValue) {
6436 currentHookNameInDev = 'useRef';
6437 updateHookTypesDev();
6438 return updateRef(initialValue);
6439 },
6440 useState: function (initialState) {
6441 currentHookNameInDev = 'useState';
6442 updateHookTypesDev();
6443 var prevDispatcher = ReactCurrentDispatcher$1.current;
6444 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6445 try {
6446 return updateState(initialState);
6447 } finally {
6448 ReactCurrentDispatcher$1.current = prevDispatcher;
6449 }
6450 },
6451 useDebugValue: function (value, formatterFn) {
6452 currentHookNameInDev = 'useDebugValue';
6453 updateHookTypesDev();
6454 return updateDebugValue(value, formatterFn);
6455 }
6456 };
6457
6458 InvalidNestedHooksDispatcherOnMountInDEV = {
6459 readContext: function (context, observedBits) {
6460 warnInvalidContextAccess();
6461 return readContext(context, observedBits);
6462 },
6463 useCallback: function (callback, deps) {
6464 currentHookNameInDev = 'useCallback';
6465 warnInvalidHookAccess();
6466 mountHookTypesDev();
6467 return mountCallback(callback, deps);
6468 },
6469 useContext: function (context, observedBits) {
6470 currentHookNameInDev = 'useContext';
6471 warnInvalidHookAccess();
6472 mountHookTypesDev();
6473 return readContext(context, observedBits);
6474 },
6475 useEffect: function (create, deps) {
6476 currentHookNameInDev = 'useEffect';
6477 warnInvalidHookAccess();
6478 mountHookTypesDev();
6479 return mountEffect(create, deps);
6480 },
6481 useImperativeHandle: function (ref, create, deps) {
6482 currentHookNameInDev = 'useImperativeHandle';
6483 warnInvalidHookAccess();
6484 mountHookTypesDev();
6485 return mountImperativeHandle(ref, create, deps);
6486 },
6487 useLayoutEffect: function (create, deps) {
6488 currentHookNameInDev = 'useLayoutEffect';
6489 warnInvalidHookAccess();
6490 mountHookTypesDev();
6491 return mountLayoutEffect(create, deps);
6492 },
6493 useMemo: function (create, deps) {
6494 currentHookNameInDev = 'useMemo';
6495 warnInvalidHookAccess();
6496 mountHookTypesDev();
6497 var prevDispatcher = ReactCurrentDispatcher$1.current;
6498 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6499 try {
6500 return mountMemo(create, deps);
6501 } finally {
6502 ReactCurrentDispatcher$1.current = prevDispatcher;
6503 }
6504 },
6505 useReducer: function (reducer, initialArg, init) {
6506 currentHookNameInDev = 'useReducer';
6507 warnInvalidHookAccess();
6508 mountHookTypesDev();
6509 var prevDispatcher = ReactCurrentDispatcher$1.current;
6510 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6511 try {
6512 return mountReducer(reducer, initialArg, init);
6513 } finally {
6514 ReactCurrentDispatcher$1.current = prevDispatcher;
6515 }
6516 },
6517 useRef: function (initialValue) {
6518 currentHookNameInDev = 'useRef';
6519 warnInvalidHookAccess();
6520 mountHookTypesDev();
6521 return mountRef(initialValue);
6522 },
6523 useState: function (initialState) {
6524 currentHookNameInDev = 'useState';
6525 warnInvalidHookAccess();
6526 mountHookTypesDev();
6527 var prevDispatcher = ReactCurrentDispatcher$1.current;
6528 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6529 try {
6530 return mountState(initialState);
6531 } finally {
6532 ReactCurrentDispatcher$1.current = prevDispatcher;
6533 }
6534 },
6535 useDebugValue: function (value, formatterFn) {
6536 currentHookNameInDev = 'useDebugValue';
6537 warnInvalidHookAccess();
6538 mountHookTypesDev();
6539 return mountDebugValue(value, formatterFn);
6540 }
6541 };
6542
6543 InvalidNestedHooksDispatcherOnUpdateInDEV = {
6544 readContext: function (context, observedBits) {
6545 warnInvalidContextAccess();
6546 return readContext(context, observedBits);
6547 },
6548 useCallback: function (callback, deps) {
6549 currentHookNameInDev = 'useCallback';
6550 warnInvalidHookAccess();
6551 updateHookTypesDev();
6552 return updateCallback(callback, deps);
6553 },
6554 useContext: function (context, observedBits) {
6555 currentHookNameInDev = 'useContext';
6556 warnInvalidHookAccess();
6557 updateHookTypesDev();
6558 return readContext(context, observedBits);
6559 },
6560 useEffect: function (create, deps) {
6561 currentHookNameInDev = 'useEffect';
6562 warnInvalidHookAccess();
6563 updateHookTypesDev();
6564 return updateEffect(create, deps);
6565 },
6566 useImperativeHandle: function (ref, create, deps) {
6567 currentHookNameInDev = 'useImperativeHandle';
6568 warnInvalidHookAccess();
6569 updateHookTypesDev();
6570 return updateImperativeHandle(ref, create, deps);
6571 },
6572 useLayoutEffect: function (create, deps) {
6573 currentHookNameInDev = 'useLayoutEffect';
6574 warnInvalidHookAccess();
6575 updateHookTypesDev();
6576 return updateLayoutEffect(create, deps);
6577 },
6578 useMemo: function (create, deps) {
6579 currentHookNameInDev = 'useMemo';
6580 warnInvalidHookAccess();
6581 updateHookTypesDev();
6582 var prevDispatcher = ReactCurrentDispatcher$1.current;
6583 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6584 try {
6585 return updateMemo(create, deps);
6586 } finally {
6587 ReactCurrentDispatcher$1.current = prevDispatcher;
6588 }
6589 },
6590 useReducer: function (reducer, initialArg, init) {
6591 currentHookNameInDev = 'useReducer';
6592 warnInvalidHookAccess();
6593 updateHookTypesDev();
6594 var prevDispatcher = ReactCurrentDispatcher$1.current;
6595 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6596 try {
6597 return updateReducer(reducer, initialArg, init);
6598 } finally {
6599 ReactCurrentDispatcher$1.current = prevDispatcher;
6600 }
6601 },
6602 useRef: function (initialValue) {
6603 currentHookNameInDev = 'useRef';
6604 warnInvalidHookAccess();
6605 updateHookTypesDev();
6606 return updateRef(initialValue);
6607 },
6608 useState: function (initialState) {
6609 currentHookNameInDev = 'useState';
6610 warnInvalidHookAccess();
6611 updateHookTypesDev();
6612 var prevDispatcher = ReactCurrentDispatcher$1.current;
6613 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6614 try {
6615 return updateState(initialState);
6616 } finally {
6617 ReactCurrentDispatcher$1.current = prevDispatcher;
6618 }
6619 },
6620 useDebugValue: function (value, formatterFn) {
6621 currentHookNameInDev = 'useDebugValue';
6622 warnInvalidHookAccess();
6623 updateHookTypesDev();
6624 return updateDebugValue(value, formatterFn);
6625 }
6626 };
6627}
6628
6629var commitTime = 0;
6630var profilerStartTime = -1;
6631
6632function getCommitTime() {
6633 return commitTime;
6634}
6635
6636function recordCommitTime() {
6637 if (!enableProfilerTimer) {
6638 return;
6639 }
6640 commitTime = unstable_now();
6641}
6642
6643function startProfilerTimer(fiber) {
6644 if (!enableProfilerTimer) {
6645 return;
6646 }
6647
6648 profilerStartTime = unstable_now();
6649
6650 if (fiber.actualStartTime < 0) {
6651 fiber.actualStartTime = unstable_now();
6652 }
6653}
6654
6655function stopProfilerTimerIfRunning(fiber) {
6656 if (!enableProfilerTimer) {
6657 return;
6658 }
6659 profilerStartTime = -1;
6660}
6661
6662function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
6663 if (!enableProfilerTimer) {
6664 return;
6665 }
6666
6667 if (profilerStartTime >= 0) {
6668 var elapsedTime = unstable_now() - profilerStartTime;
6669 fiber.actualDuration += elapsedTime;
6670 if (overrideBaseTime) {
6671 fiber.selfBaseDuration = elapsedTime;
6672 }
6673 profilerStartTime = -1;
6674 }
6675}
6676
6677// The deepest Fiber on the stack involved in a hydration context.
6678// This may have been an insertion or a hydration.
6679var hydrationParentFiber = null;
6680var nextHydratableInstance = null;
6681var isHydrating = false;
6682
6683function enterHydrationState(fiber) {
6684 if (!supportsHydration) {
6685 return false;
6686 }
6687
6688 var parentInstance = fiber.stateNode.containerInfo;
6689 nextHydratableInstance = getFirstHydratableChild(parentInstance);
6690 hydrationParentFiber = fiber;
6691 isHydrating = true;
6692 return true;
6693}
6694
6695function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
6696 if (!supportsHydration) {
6697 return false;
6698 }
6699
6700 var suspenseInstance = fiber.stateNode;
6701 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
6702 popToNextHostParent(fiber);
6703 isHydrating = true;
6704 return true;
6705}
6706
6707function deleteHydratableInstance(returnFiber, instance) {
6708 {
6709 switch (returnFiber.tag) {
6710 case HostRoot:
6711 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
6712 break;
6713 case HostComponent:
6714 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
6715 break;
6716 }
6717 }
6718
6719 var childToDelete = createFiberFromHostInstanceForDeletion();
6720 childToDelete.stateNode = instance;
6721 childToDelete.return = returnFiber;
6722 childToDelete.effectTag = Deletion;
6723
6724 // This might seem like it belongs on progressedFirstDeletion. However,
6725 // these children are not part of the reconciliation list of children.
6726 // Even if we abort and rereconcile the children, that will try to hydrate
6727 // again and the nodes are still in the host tree so these will be
6728 // recreated.
6729 if (returnFiber.lastEffect !== null) {
6730 returnFiber.lastEffect.nextEffect = childToDelete;
6731 returnFiber.lastEffect = childToDelete;
6732 } else {
6733 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
6734 }
6735}
6736
6737function insertNonHydratedInstance(returnFiber, fiber) {
6738 fiber.effectTag |= Placement;
6739 {
6740 switch (returnFiber.tag) {
6741 case HostRoot:
6742 {
6743 var parentContainer = returnFiber.stateNode.containerInfo;
6744 switch (fiber.tag) {
6745 case HostComponent:
6746 var type = fiber.type;
6747 var props = fiber.pendingProps;
6748 didNotFindHydratableContainerInstance(parentContainer, type, props);
6749 break;
6750 case HostText:
6751 var text = fiber.pendingProps;
6752 didNotFindHydratableContainerTextInstance(parentContainer, text);
6753 break;
6754 case SuspenseComponent:
6755 didNotFindHydratableContainerSuspenseInstance(parentContainer);
6756 break;
6757 }
6758 break;
6759 }
6760 case HostComponent:
6761 {
6762 var parentType = returnFiber.type;
6763 var parentProps = returnFiber.memoizedProps;
6764 var parentInstance = returnFiber.stateNode;
6765 switch (fiber.tag) {
6766 case HostComponent:
6767 var _type = fiber.type;
6768 var _props = fiber.pendingProps;
6769 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
6770 break;
6771 case HostText:
6772 var _text = fiber.pendingProps;
6773 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
6774 break;
6775 case SuspenseComponent:
6776 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
6777 break;
6778 }
6779 break;
6780 }
6781 default:
6782 return;
6783 }
6784 }
6785}
6786
6787function tryHydrate(fiber, nextInstance) {
6788 switch (fiber.tag) {
6789 case HostComponent:
6790 {
6791 var type = fiber.type;
6792 var props = fiber.pendingProps;
6793 var instance = canHydrateInstance(nextInstance, type, props);
6794 if (instance !== null) {
6795 fiber.stateNode = instance;
6796 return true;
6797 }
6798 return false;
6799 }
6800 case HostText:
6801 {
6802 var text = fiber.pendingProps;
6803 var textInstance = canHydrateTextInstance(nextInstance, text);
6804 if (textInstance !== null) {
6805 fiber.stateNode = textInstance;
6806 return true;
6807 }
6808 return false;
6809 }
6810 case SuspenseComponent:
6811 {
6812 if (enableSuspenseServerRenderer) {
6813 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
6814 if (suspenseInstance !== null) {
6815 // Downgrade the tag to a dehydrated component until we've hydrated it.
6816 fiber.tag = DehydratedSuspenseComponent;
6817 fiber.stateNode = suspenseInstance;
6818 return true;
6819 }
6820 }
6821 return false;
6822 }
6823 default:
6824 return false;
6825 }
6826}
6827
6828function tryToClaimNextHydratableInstance(fiber) {
6829 if (!isHydrating) {
6830 return;
6831 }
6832 var nextInstance = nextHydratableInstance;
6833 if (!nextInstance) {
6834 // Nothing to hydrate. Make it an insertion.
6835 insertNonHydratedInstance(hydrationParentFiber, fiber);
6836 isHydrating = false;
6837 hydrationParentFiber = fiber;
6838 return;
6839 }
6840 var firstAttemptedInstance = nextInstance;
6841 if (!tryHydrate(fiber, nextInstance)) {
6842 // If we can't hydrate this instance let's try the next one.
6843 // We use this as a heuristic. It's based on intuition and not data so it
6844 // might be flawed or unnecessary.
6845 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
6846 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
6847 // Nothing to hydrate. Make it an insertion.
6848 insertNonHydratedInstance(hydrationParentFiber, fiber);
6849 isHydrating = false;
6850 hydrationParentFiber = fiber;
6851 return;
6852 }
6853 // We matched the next one, we'll now assume that the first one was
6854 // superfluous and we'll delete it. Since we can't eagerly delete it
6855 // we'll have to schedule a deletion. To do that, this node needs a dummy
6856 // fiber associated with it.
6857 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
6858 }
6859 hydrationParentFiber = fiber;
6860 nextHydratableInstance = getFirstHydratableChild(nextInstance);
6861}
6862
6863function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
6864 if (!supportsHydration) {
6865 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6866 }
6867
6868 var instance = fiber.stateNode;
6869 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
6870 // TODO: Type this specific to this type of component.
6871 fiber.updateQueue = updatePayload;
6872 // If the update payload indicates that there is a change or if there
6873 // is a new ref we mark this as an update.
6874 if (updatePayload !== null) {
6875 return true;
6876 }
6877 return false;
6878}
6879
6880function prepareToHydrateHostTextInstance(fiber) {
6881 if (!supportsHydration) {
6882 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6883 }
6884
6885 var textInstance = fiber.stateNode;
6886 var textContent = fiber.memoizedProps;
6887 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
6888 {
6889 if (shouldUpdate) {
6890 // We assume that prepareToHydrateHostTextInstance is called in a context where the
6891 // hydration parent is the parent host component of this host text.
6892 var returnFiber = hydrationParentFiber;
6893 if (returnFiber !== null) {
6894 switch (returnFiber.tag) {
6895 case HostRoot:
6896 {
6897 var parentContainer = returnFiber.stateNode.containerInfo;
6898 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
6899 break;
6900 }
6901 case HostComponent:
6902 {
6903 var parentType = returnFiber.type;
6904 var parentProps = returnFiber.memoizedProps;
6905 var parentInstance = returnFiber.stateNode;
6906 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
6907 break;
6908 }
6909 }
6910 }
6911 }
6912 }
6913 return shouldUpdate;
6914}
6915
6916function skipPastDehydratedSuspenseInstance(fiber) {
6917 if (!supportsHydration) {
6918 invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6919 }
6920 var suspenseInstance = fiber.stateNode;
6921 !suspenseInstance ? invariant(false, 'Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.') : void 0;
6922 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
6923}
6924
6925function popToNextHostParent(fiber) {
6926 var parent = fiber.return;
6927 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
6928 parent = parent.return;
6929 }
6930 hydrationParentFiber = parent;
6931}
6932
6933function popHydrationState(fiber) {
6934 if (!supportsHydration) {
6935 return false;
6936 }
6937 if (fiber !== hydrationParentFiber) {
6938 // We're deeper than the current hydration context, inside an inserted
6939 // tree.
6940 return false;
6941 }
6942 if (!isHydrating) {
6943 // If we're not currently hydrating but we're in a hydration context, then
6944 // we were an insertion and now need to pop up reenter hydration of our
6945 // siblings.
6946 popToNextHostParent(fiber);
6947 isHydrating = true;
6948 return false;
6949 }
6950
6951 var type = fiber.type;
6952
6953 // If we have any remaining hydratable nodes, we need to delete them now.
6954 // We only do this deeper than head and body since they tend to have random
6955 // other nodes in them. We also ignore components with pure text content in
6956 // side of them.
6957 // TODO: Better heuristic.
6958 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
6959 var nextInstance = nextHydratableInstance;
6960 while (nextInstance) {
6961 deleteHydratableInstance(fiber, nextInstance);
6962 nextInstance = getNextHydratableSibling(nextInstance);
6963 }
6964 }
6965
6966 popToNextHostParent(fiber);
6967 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
6968 return true;
6969}
6970
6971function resetHydrationState() {
6972 if (!supportsHydration) {
6973 return;
6974 }
6975
6976 hydrationParentFiber = null;
6977 nextHydratableInstance = null;
6978 isHydrating = false;
6979}
6980
6981var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
6982
6983var didReceiveUpdate = false;
6984
6985var didWarnAboutBadClass = void 0;
6986var didWarnAboutContextTypeOnFunctionComponent = void 0;
6987var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
6988var didWarnAboutFunctionRefs = void 0;
6989var didWarnAboutReassigningProps = void 0;
6990
6991{
6992 didWarnAboutBadClass = {};
6993 didWarnAboutContextTypeOnFunctionComponent = {};
6994 didWarnAboutGetDerivedStateOnFunctionComponent = {};
6995 didWarnAboutFunctionRefs = {};
6996 didWarnAboutReassigningProps = false;
6997}
6998
6999function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
7000 if (current === null) {
7001 // If this is a fresh new component that hasn't been rendered yet, we
7002 // won't update its child set by applying minimal side-effects. Instead,
7003 // we will add them all to the child before it gets rendered. That means
7004 // we can optimize this reconciliation pass by not tracking side-effects.
7005 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7006 } else {
7007 // If the current child is the same as the work in progress, it means that
7008 // we haven't yet started any work on these children. Therefore, we use
7009 // the clone algorithm to create a copy of all the current children.
7010
7011 // If we had any progressed work already, that is invalid at this point so
7012 // let's throw it out.
7013 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
7014 }
7015}
7016
7017function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
7018 // This function is fork of reconcileChildren. It's used in cases where we
7019 // want to reconcile without matching against the existing set. This has the
7020 // effect of all current children being unmounted; even if the type and key
7021 // are the same, the old child is unmounted and a new child is created.
7022 //
7023 // To do this, we're going to go through the reconcile algorithm twice. In
7024 // the first pass, we schedule a deletion for all the current children by
7025 // passing null.
7026 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime);
7027 // In the second pass, we mount the new children. The trick here is that we
7028 // pass null in place of where we usually pass the current child set. This has
7029 // the effect of remounting all children regardless of whether their their
7030 // identity matches.
7031 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7032}
7033
7034function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
7035 // TODO: current can be non-null here even if the component
7036 // hasn't yet mounted. This happens after the first render suspends.
7037 // We'll need to figure out if this is fine or can cause issues.
7038
7039 {
7040 if (workInProgress.type !== workInProgress.elementType) {
7041 // Lazy component props can't be validated in createElement
7042 // because they're only guaranteed to be resolved here.
7043 var innerPropTypes = Component.propTypes;
7044 if (innerPropTypes) {
7045 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7046 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7047 }
7048 }
7049 }
7050
7051 var render = Component.render;
7052 var ref = workInProgress.ref;
7053
7054 // The rest is a fork of updateFunctionComponent
7055 var nextChildren = void 0;
7056 prepareToReadContext(workInProgress, renderExpirationTime);
7057 {
7058 ReactCurrentOwner$2.current = workInProgress;
7059 setCurrentPhase('render');
7060 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7061 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7062 // Only double-render components with Hooks
7063 if (workInProgress.memoizedState !== null) {
7064 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7065 }
7066 }
7067 setCurrentPhase(null);
7068 }
7069
7070 if (current !== null && !didReceiveUpdate) {
7071 bailoutHooks(current, workInProgress, renderExpirationTime);
7072 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7073 }
7074
7075 // React DevTools reads this flag.
7076 workInProgress.effectTag |= PerformedWork;
7077 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7078 return workInProgress.child;
7079}
7080
7081function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7082 if (current === null) {
7083 var type = Component.type;
7084 if (isSimpleFunctionComponent(type) && Component.compare === null &&
7085 // SimpleMemoComponent codepath doesn't resolve outer props either.
7086 Component.defaultProps === undefined) {
7087 // If this is a plain function component without default props,
7088 // and with only the default shallow comparison, we upgrade it
7089 // to a SimpleMemoComponent to allow fast path updates.
7090 workInProgress.tag = SimpleMemoComponent;
7091 workInProgress.type = type;
7092 {
7093 validateFunctionComponentInDev(workInProgress, type);
7094 }
7095 return updateSimpleMemoComponent(current, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
7096 }
7097 {
7098 var innerPropTypes = type.propTypes;
7099 if (innerPropTypes) {
7100 // Inner memo component props aren't currently validated in createElement.
7101 // We could move it there, but we'd still need this for lazy code path.
7102 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7103 'prop', getComponentName(type), getCurrentFiberStackInDev);
7104 }
7105 }
7106 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
7107 child.ref = workInProgress.ref;
7108 child.return = workInProgress;
7109 workInProgress.child = child;
7110 return child;
7111 }
7112 {
7113 var _type = Component.type;
7114 var _innerPropTypes = _type.propTypes;
7115 if (_innerPropTypes) {
7116 // Inner memo component props aren't currently validated in createElement.
7117 // We could move it there, but we'd still need this for lazy code path.
7118 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
7119 'prop', getComponentName(_type), getCurrentFiberStackInDev);
7120 }
7121 }
7122 var currentChild = current.child; // This is always exactly one child
7123 if (updateExpirationTime < renderExpirationTime) {
7124 // This will be the props with resolved defaultProps,
7125 // unlike current.memoizedProps which will be the unresolved ones.
7126 var prevProps = currentChild.memoizedProps;
7127 // Default to shallow comparison
7128 var compare = Component.compare;
7129 compare = compare !== null ? compare : shallowEqual;
7130 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
7131 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7132 }
7133 }
7134 // React DevTools reads this flag.
7135 workInProgress.effectTag |= PerformedWork;
7136 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
7137 newChild.ref = workInProgress.ref;
7138 newChild.return = workInProgress;
7139 workInProgress.child = newChild;
7140 return newChild;
7141}
7142
7143function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7144 // TODO: current can be non-null here even if the component
7145 // hasn't yet mounted. This happens when the inner render suspends.
7146 // We'll need to figure out if this is fine or can cause issues.
7147
7148 {
7149 if (workInProgress.type !== workInProgress.elementType) {
7150 // Lazy component props can't be validated in createElement
7151 // because they're only guaranteed to be resolved here.
7152 var outerMemoType = workInProgress.elementType;
7153 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
7154 // We warn when you define propTypes on lazy()
7155 // so let's just skip over it to find memo() outer wrapper.
7156 // Inner props for memo are validated later.
7157 outerMemoType = refineResolvedLazyComponent(outerMemoType);
7158 }
7159 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
7160 if (outerPropTypes) {
7161 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
7162 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
7163 }
7164 // Inner propTypes will be validated in the function component path.
7165 }
7166 }
7167 if (current !== null) {
7168 var prevProps = current.memoizedProps;
7169 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref) {
7170 didReceiveUpdate = false;
7171 if (updateExpirationTime < renderExpirationTime) {
7172 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7173 }
7174 }
7175 }
7176 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
7177}
7178
7179function updateFragment(current, workInProgress, renderExpirationTime) {
7180 var nextChildren = workInProgress.pendingProps;
7181 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7182 return workInProgress.child;
7183}
7184
7185function updateMode(current, workInProgress, renderExpirationTime) {
7186 var nextChildren = workInProgress.pendingProps.children;
7187 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7188 return workInProgress.child;
7189}
7190
7191function updateProfiler(current, workInProgress, renderExpirationTime) {
7192 if (enableProfilerTimer) {
7193 workInProgress.effectTag |= Update;
7194 }
7195 var nextProps = workInProgress.pendingProps;
7196 var nextChildren = nextProps.children;
7197 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7198 return workInProgress.child;
7199}
7200
7201function markRef(current, workInProgress) {
7202 var ref = workInProgress.ref;
7203 if (current === null && ref !== null || current !== null && current.ref !== ref) {
7204 // Schedule a Ref effect
7205 workInProgress.effectTag |= Ref;
7206 }
7207}
7208
7209function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7210 {
7211 if (workInProgress.type !== workInProgress.elementType) {
7212 // Lazy component props can't be validated in createElement
7213 // because they're only guaranteed to be resolved here.
7214 var innerPropTypes = Component.propTypes;
7215 if (innerPropTypes) {
7216 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7217 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7218 }
7219 }
7220 }
7221
7222 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
7223 var context = getMaskedContext(workInProgress, unmaskedContext);
7224
7225 var nextChildren = void 0;
7226 prepareToReadContext(workInProgress, renderExpirationTime);
7227 {
7228 ReactCurrentOwner$2.current = workInProgress;
7229 setCurrentPhase('render');
7230 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7231 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7232 // Only double-render components with Hooks
7233 if (workInProgress.memoizedState !== null) {
7234 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7235 }
7236 }
7237 setCurrentPhase(null);
7238 }
7239
7240 if (current !== null && !didReceiveUpdate) {
7241 bailoutHooks(current, workInProgress, renderExpirationTime);
7242 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7243 }
7244
7245 // React DevTools reads this flag.
7246 workInProgress.effectTag |= PerformedWork;
7247 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7248 return workInProgress.child;
7249}
7250
7251function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7252 {
7253 if (workInProgress.type !== workInProgress.elementType) {
7254 // Lazy component props can't be validated in createElement
7255 // because they're only guaranteed to be resolved here.
7256 var innerPropTypes = Component.propTypes;
7257 if (innerPropTypes) {
7258 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7259 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7260 }
7261 }
7262 }
7263
7264 // Push context providers early to prevent context stack mismatches.
7265 // During mounting we don't know the child context yet as the instance doesn't exist.
7266 // We will invalidate the child context in finishClassComponent() right after rendering.
7267 var hasContext = void 0;
7268 if (isContextProvider(Component)) {
7269 hasContext = true;
7270 pushContextProvider(workInProgress);
7271 } else {
7272 hasContext = false;
7273 }
7274 prepareToReadContext(workInProgress, renderExpirationTime);
7275
7276 var instance = workInProgress.stateNode;
7277 var shouldUpdate = void 0;
7278 if (instance === null) {
7279 if (current !== null) {
7280 // An class component without an instance only mounts if it suspended
7281 // inside a non- concurrent tree, in an inconsistent state. We want to
7282 // tree it like a new mount, even though an empty version of it already
7283 // committed. Disconnect the alternate pointers.
7284 current.alternate = null;
7285 workInProgress.alternate = null;
7286 // Since this is conceptually a new fiber, schedule a Placement effect
7287 workInProgress.effectTag |= Placement;
7288 }
7289 // In the initial pass we might need to construct the instance.
7290 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7291 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7292 shouldUpdate = true;
7293 } else if (current === null) {
7294 // In a resume, we'll already have an instance we can reuse.
7295 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7296 } else {
7297 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
7298 }
7299 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7300 {
7301 var inst = workInProgress.stateNode;
7302 if (inst.props !== nextProps) {
7303 !didWarnAboutReassigningProps ? warning$1(false, 'It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component') : void 0;
7304 didWarnAboutReassigningProps = true;
7305 }
7306 }
7307 return nextUnitOfWork;
7308}
7309
7310function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7311 // Refs should update even if shouldComponentUpdate returns false
7312 markRef(current, workInProgress);
7313
7314 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7315
7316 if (!shouldUpdate && !didCaptureError) {
7317 // Context providers should defer to sCU for rendering
7318 if (hasContext) {
7319 invalidateContextProvider(workInProgress, Component, false);
7320 }
7321
7322 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7323 }
7324
7325 var instance = workInProgress.stateNode;
7326
7327 // Rerender
7328 ReactCurrentOwner$2.current = workInProgress;
7329 var nextChildren = void 0;
7330 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7331 // If we captured an error, but getDerivedStateFrom catch is not defined,
7332 // unmount all the children. componentDidCatch will schedule an update to
7333 // re-render a fallback. This is temporary until we migrate everyone to
7334 // the new API.
7335 // TODO: Warn in a future release.
7336 nextChildren = null;
7337
7338 if (enableProfilerTimer) {
7339 stopProfilerTimerIfRunning(workInProgress);
7340 }
7341 } else {
7342 {
7343 setCurrentPhase('render');
7344 nextChildren = instance.render();
7345 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7346 instance.render();
7347 }
7348 setCurrentPhase(null);
7349 }
7350 }
7351
7352 // React DevTools reads this flag.
7353 workInProgress.effectTag |= PerformedWork;
7354 if (current !== null && didCaptureError) {
7355 // If we're recovering from an error, reconcile without reusing any of
7356 // the existing children. Conceptually, the normal children and the children
7357 // that are shown on error are two different sets, so we shouldn't reuse
7358 // normal children even if their identities match.
7359 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
7360 } else {
7361 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7362 }
7363
7364 // Memoize state using the values we just used to render.
7365 // TODO: Restructure so we never read values from the instance.
7366 workInProgress.memoizedState = instance.state;
7367
7368 // The context might have changed so we need to recalculate it.
7369 if (hasContext) {
7370 invalidateContextProvider(workInProgress, Component, true);
7371 }
7372
7373 return workInProgress.child;
7374}
7375
7376function pushHostRootContext(workInProgress) {
7377 var root = workInProgress.stateNode;
7378 if (root.pendingContext) {
7379 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7380 } else if (root.context) {
7381 // Should always be set
7382 pushTopLevelContextObject(workInProgress, root.context, false);
7383 }
7384 pushHostContainer(workInProgress, root.containerInfo);
7385}
7386
7387function updateHostRoot(current, workInProgress, renderExpirationTime) {
7388 pushHostRootContext(workInProgress);
7389 var updateQueue = workInProgress.updateQueue;
7390 !(updateQueue !== null) ? invariant(false, '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.') : void 0;
7391 var nextProps = workInProgress.pendingProps;
7392 var prevState = workInProgress.memoizedState;
7393 var prevChildren = prevState !== null ? prevState.element : null;
7394 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
7395 var nextState = workInProgress.memoizedState;
7396 // Caution: React DevTools currently depends on this property
7397 // being called "element".
7398 var nextChildren = nextState.element;
7399 if (nextChildren === prevChildren) {
7400 // If the state is the same as before, that's a bailout because we had
7401 // no work that expires at this time.
7402 resetHydrationState();
7403 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7404 }
7405 var root = workInProgress.stateNode;
7406 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
7407 // If we don't have any current children this might be the first pass.
7408 // We always try to hydrate. If this isn't a hydration pass there won't
7409 // be any children to hydrate which is effectively the same thing as
7410 // not hydrating.
7411
7412 // This is a bit of a hack. We track the host root as a placement to
7413 // know that we're currently in a mounting state. That way isMounted
7414 // works as expected. We must reset this before committing.
7415 // TODO: Delete this when we delete isMounted and findDOMNode.
7416 workInProgress.effectTag |= Placement;
7417
7418 // Ensure that children mount into this root without tracking
7419 // side-effects. This ensures that we don't store Placement effects on
7420 // nodes that will be hydrated.
7421 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7422 } else {
7423 // Otherwise reset hydration state in case we aborted and resumed another
7424 // root.
7425 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7426 resetHydrationState();
7427 }
7428 return workInProgress.child;
7429}
7430
7431function updateHostComponent(current, workInProgress, renderExpirationTime) {
7432 pushHostContext(workInProgress);
7433
7434 if (current === null) {
7435 tryToClaimNextHydratableInstance(workInProgress);
7436 }
7437
7438 var type = workInProgress.type;
7439 var nextProps = workInProgress.pendingProps;
7440 var prevProps = current !== null ? current.memoizedProps : null;
7441
7442 var nextChildren = nextProps.children;
7443 var isDirectTextChild = shouldSetTextContent(type, nextProps);
7444
7445 if (isDirectTextChild) {
7446 // We special case a direct text child of a host node. This is a common
7447 // case. We won't handle it as a reified child. We will instead handle
7448 // this in the host environment that also have access to this prop. That
7449 // avoids allocating another HostText fiber and traversing it.
7450 nextChildren = null;
7451 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
7452 // If we're switching from a direct text child to a normal child, or to
7453 // empty, we need to schedule the text content to be reset.
7454 workInProgress.effectTag |= ContentReset;
7455 }
7456
7457 markRef(current, workInProgress);
7458
7459 // Check the host config to see if the children are offscreen/hidden.
7460 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
7461 // Schedule this fiber to re-render at offscreen priority. Then bailout.
7462 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7463 return null;
7464 }
7465
7466 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7467 return workInProgress.child;
7468}
7469
7470function updateHostText(current, workInProgress) {
7471 if (current === null) {
7472 tryToClaimNextHydratableInstance(workInProgress);
7473 }
7474 // Nothing to do here. This is terminal. We'll do the completion step
7475 // immediately after.
7476 return null;
7477}
7478
7479function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7480 if (_current !== null) {
7481 // An lazy component only mounts if it suspended inside a non-
7482 // concurrent tree, in an inconsistent state. We want to treat it like
7483 // a new mount, even though an empty version of it already committed.
7484 // Disconnect the alternate pointers.
7485 _current.alternate = null;
7486 workInProgress.alternate = null;
7487 // Since this is conceptually a new fiber, schedule a Placement effect
7488 workInProgress.effectTag |= Placement;
7489 }
7490
7491 var props = workInProgress.pendingProps;
7492 // We can't start a User Timing measurement with correct label yet.
7493 // Cancel and resume right after we know the tag.
7494 cancelWorkTimer(workInProgress);
7495 var Component = readLazyComponentType(elementType);
7496 // Store the unwrapped component in the type.
7497 workInProgress.type = Component;
7498 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
7499 startWorkTimer(workInProgress);
7500 var resolvedProps = resolveDefaultProps(Component, props);
7501 var child = void 0;
7502 switch (resolvedTag) {
7503 case FunctionComponent:
7504 {
7505 {
7506 validateFunctionComponentInDev(workInProgress, Component);
7507 }
7508 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7509 break;
7510 }
7511 case ClassComponent:
7512 {
7513 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7514 break;
7515 }
7516 case ForwardRef:
7517 {
7518 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7519 break;
7520 }
7521 case MemoComponent:
7522 {
7523 {
7524 if (workInProgress.type !== workInProgress.elementType) {
7525 var outerPropTypes = Component.propTypes;
7526 if (outerPropTypes) {
7527 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
7528 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7529 }
7530 }
7531 }
7532 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
7533 updateExpirationTime, renderExpirationTime);
7534 break;
7535 }
7536 default:
7537 {
7538 var hint = '';
7539 {
7540 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
7541 hint = ' Did you wrap a component in React.lazy() more than once?';
7542 }
7543 }
7544 // This message intentionally doesn't mention ForwardRef or MemoComponent
7545 // because the fact that it's a separate type of work is an
7546 // implementation detail.
7547 invariant(false, 'Element type is invalid. Received a promise that resolves to: %s. Lazy element type must resolve to a class or function.%s', Component, hint);
7548 }
7549 }
7550 return child;
7551}
7552
7553function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
7554 if (_current !== null) {
7555 // An incomplete component only mounts if it suspended inside a non-
7556 // concurrent tree, in an inconsistent state. We want to treat it like
7557 // a new mount, even though an empty version of it already committed.
7558 // Disconnect the alternate pointers.
7559 _current.alternate = null;
7560 workInProgress.alternate = null;
7561 // Since this is conceptually a new fiber, schedule a Placement effect
7562 workInProgress.effectTag |= Placement;
7563 }
7564
7565 // Promote the fiber to a class and try rendering again.
7566 workInProgress.tag = ClassComponent;
7567
7568 // The rest of this function is a fork of `updateClassComponent`
7569
7570 // Push context providers early to prevent context stack mismatches.
7571 // During mounting we don't know the child context yet as the instance doesn't exist.
7572 // We will invalidate the child context in finishClassComponent() right after rendering.
7573 var hasContext = void 0;
7574 if (isContextProvider(Component)) {
7575 hasContext = true;
7576 pushContextProvider(workInProgress);
7577 } else {
7578 hasContext = false;
7579 }
7580 prepareToReadContext(workInProgress, renderExpirationTime);
7581
7582 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7583 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7584
7585 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7586}
7587
7588function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
7589 if (_current !== null) {
7590 // An indeterminate component only mounts if it suspended inside a non-
7591 // concurrent tree, in an inconsistent state. We want to treat it like
7592 // a new mount, even though an empty version of it already committed.
7593 // Disconnect the alternate pointers.
7594 _current.alternate = null;
7595 workInProgress.alternate = null;
7596 // Since this is conceptually a new fiber, schedule a Placement effect
7597 workInProgress.effectTag |= Placement;
7598 }
7599
7600 var props = workInProgress.pendingProps;
7601 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
7602 var context = getMaskedContext(workInProgress, unmaskedContext);
7603
7604 prepareToReadContext(workInProgress, renderExpirationTime);
7605
7606 var value = void 0;
7607
7608 {
7609 if (Component.prototype && typeof Component.prototype.render === 'function') {
7610 var componentName = getComponentName(Component) || 'Unknown';
7611
7612 if (!didWarnAboutBadClass[componentName]) {
7613 warningWithoutStack$1(false, "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
7614 didWarnAboutBadClass[componentName] = true;
7615 }
7616 }
7617
7618 if (workInProgress.mode & StrictMode) {
7619 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
7620 }
7621
7622 ReactCurrentOwner$2.current = workInProgress;
7623 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7624 }
7625 // React DevTools reads this flag.
7626 workInProgress.effectTag |= PerformedWork;
7627
7628 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
7629 // Proceed under the assumption that this is a class instance
7630 workInProgress.tag = ClassComponent;
7631
7632 // Throw out any hooks that were used.
7633 resetHooks();
7634
7635 // Push context providers early to prevent context stack mismatches.
7636 // During mounting we don't know the child context yet as the instance doesn't exist.
7637 // We will invalidate the child context in finishClassComponent() right after rendering.
7638 var hasContext = false;
7639 if (isContextProvider(Component)) {
7640 hasContext = true;
7641 pushContextProvider(workInProgress);
7642 } else {
7643 hasContext = false;
7644 }
7645
7646 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
7647
7648 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
7649 if (typeof getDerivedStateFromProps === 'function') {
7650 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
7651 }
7652
7653 adoptClassInstance(workInProgress, value);
7654 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
7655 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7656 } else {
7657 // Proceed under the assumption that this is a function component
7658 workInProgress.tag = FunctionComponent;
7659 {
7660 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7661 // Only double-render components with Hooks
7662 if (workInProgress.memoizedState !== null) {
7663 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7664 }
7665 }
7666 }
7667 reconcileChildren(null, workInProgress, value, renderExpirationTime);
7668 {
7669 validateFunctionComponentInDev(workInProgress, Component);
7670 }
7671 return workInProgress.child;
7672 }
7673}
7674
7675function validateFunctionComponentInDev(workInProgress, Component) {
7676 if (Component) {
7677 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
7678 }
7679 if (workInProgress.ref !== null) {
7680 var info = '';
7681 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
7682 if (ownerName) {
7683 info += '\n\nCheck the render method of `' + ownerName + '`.';
7684 }
7685
7686 var warningKey = ownerName || workInProgress._debugID || '';
7687 var debugSource = workInProgress._debugSource;
7688 if (debugSource) {
7689 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
7690 }
7691 if (!didWarnAboutFunctionRefs[warningKey]) {
7692 didWarnAboutFunctionRefs[warningKey] = true;
7693 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
7694 }
7695 }
7696
7697 if (typeof Component.getDerivedStateFromProps === 'function') {
7698 var componentName = getComponentName(Component) || 'Unknown';
7699
7700 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
7701 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
7702 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
7703 }
7704 }
7705
7706 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
7707 var _componentName = getComponentName(Component) || 'Unknown';
7708
7709 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
7710 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
7711 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
7712 }
7713 }
7714}
7715
7716function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
7717 var mode = workInProgress.mode;
7718 var nextProps = workInProgress.pendingProps;
7719
7720 // We should attempt to render the primary children unless this boundary
7721 // already suspended during this render (`alreadyCaptured` is true).
7722 var nextState = workInProgress.memoizedState;
7723
7724 var nextDidTimeout = void 0;
7725 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
7726 // This is the first attempt.
7727 nextState = null;
7728 nextDidTimeout = false;
7729 } else {
7730 // Something in this boundary's subtree already suspended. Switch to
7731 // rendering the fallback children.
7732 nextState = {
7733 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
7734 };
7735 nextDidTimeout = true;
7736 workInProgress.effectTag &= ~DidCapture;
7737 }
7738
7739 // This next part is a bit confusing. If the children timeout, we switch to
7740 // showing the fallback children in place of the "primary" children.
7741 // However, we don't want to delete the primary children because then their
7742 // state will be lost (both the React state and the host state, e.g.
7743 // uncontrolled form inputs). Instead we keep them mounted and hide them.
7744 // Both the fallback children AND the primary children are rendered at the
7745 // same time. Once the primary children are un-suspended, we can delete
7746 // the fallback children — don't need to preserve their state.
7747 //
7748 // The two sets of children are siblings in the host environment, but
7749 // semantically, for purposes of reconciliation, they are two separate sets.
7750 // So we store them using two fragment fibers.
7751 //
7752 // However, we want to avoid allocating extra fibers for every placeholder.
7753 // They're only necessary when the children time out, because that's the
7754 // only time when both sets are mounted.
7755 //
7756 // So, the extra fragment fibers are only used if the children time out.
7757 // Otherwise, we render the primary children directly. This requires some
7758 // custom reconciliation logic to preserve the state of the primary
7759 // children. It's essentially a very basic form of re-parenting.
7760
7761 // `child` points to the child fiber. In the normal case, this is the first
7762 // fiber of the primary children set. In the timed-out case, it's a
7763 // a fragment fiber containing the primary children.
7764 var child = void 0;
7765 // `next` points to the next fiber React should render. In the normal case,
7766 // it's the same as `child`: the first fiber of the primary children set.
7767 // In the timed-out case, it's a fragment fiber containing the *fallback*
7768 // children -- we skip over the primary children entirely.
7769 var next = void 0;
7770 if (current === null) {
7771 if (enableSuspenseServerRenderer) {
7772 // If we're currently hydrating, try to hydrate this boundary.
7773 // But only if this has a fallback.
7774 if (nextProps.fallback !== undefined) {
7775 tryToClaimNextHydratableInstance(workInProgress);
7776 // This could've changed the tag if this was a dehydrated suspense component.
7777 if (workInProgress.tag === DehydratedSuspenseComponent) {
7778 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
7779 }
7780 }
7781 }
7782
7783 // This is the initial mount. This branch is pretty simple because there's
7784 // no previous state that needs to be preserved.
7785 if (nextDidTimeout) {
7786 // Mount separate fragments for primary and fallback children.
7787 var nextFallbackChildren = nextProps.fallback;
7788 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
7789
7790 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7791 // Outside of concurrent mode, we commit the effects from the
7792 var progressedState = workInProgress.memoizedState;
7793 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
7794 primaryChildFragment.child = progressedPrimaryChild;
7795 }
7796
7797 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
7798 primaryChildFragment.sibling = fallbackChildFragment;
7799 child = primaryChildFragment;
7800 // Skip the primary children, and continue working on the
7801 // fallback children.
7802 next = fallbackChildFragment;
7803 child.return = next.return = workInProgress;
7804 } else {
7805 // Mount the primary children without an intermediate fragment fiber.
7806 var nextPrimaryChildren = nextProps.children;
7807 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
7808 }
7809 } else {
7810 // This is an update. This branch is more complicated because we need to
7811 // ensure the state of the primary children is preserved.
7812 var prevState = current.memoizedState;
7813 var prevDidTimeout = prevState !== null;
7814 if (prevDidTimeout) {
7815 // The current tree already timed out. That means each child set is
7816 var currentPrimaryChildFragment = current.child;
7817 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
7818 if (nextDidTimeout) {
7819 // Still timed out. Reuse the current primary children by cloning
7820 // its fragment. We're going to skip over these entirely.
7821 var _nextFallbackChildren = nextProps.fallback;
7822 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
7823
7824 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7825 // Outside of concurrent mode, we commit the effects from the
7826 var _progressedState = workInProgress.memoizedState;
7827 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
7828 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
7829 _primaryChildFragment.child = _progressedPrimaryChild;
7830 }
7831 }
7832
7833 // Because primaryChildFragment is a new fiber that we're inserting as the
7834 // parent of a new tree, we need to set its treeBaseDuration.
7835 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7836 // treeBaseDuration is the sum of all the child tree base durations.
7837 var treeBaseDuration = 0;
7838 var hiddenChild = _primaryChildFragment.child;
7839 while (hiddenChild !== null) {
7840 treeBaseDuration += hiddenChild.treeBaseDuration;
7841 hiddenChild = hiddenChild.sibling;
7842 }
7843 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
7844 }
7845
7846 // Clone the fallback child fragment, too. These we'll continue
7847 // working on.
7848 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
7849 child = _primaryChildFragment;
7850 _primaryChildFragment.childExpirationTime = NoWork;
7851 // Skip the primary children, and continue working on the
7852 // fallback children.
7853 next = _fallbackChildFragment;
7854 child.return = next.return = workInProgress;
7855 } else {
7856 // No longer suspended. Switch back to showing the primary children,
7857 // and remove the intermediate fragment fiber.
7858 var _nextPrimaryChildren = nextProps.children;
7859 var currentPrimaryChild = currentPrimaryChildFragment.child;
7860 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
7861
7862 // If this render doesn't suspend, we need to delete the fallback
7863 // children. Wait until the complete phase, after we've confirmed the
7864 // fallback is no longer needed.
7865 // TODO: Would it be better to store the fallback fragment on
7866 // the stateNode?
7867
7868 // Continue rendering the children, like we normally do.
7869 child = next = primaryChild;
7870 }
7871 } else {
7872 // The current tree has not already timed out. That means the primary
7873 // children are not wrapped in a fragment fiber.
7874 var _currentPrimaryChild = current.child;
7875 if (nextDidTimeout) {
7876 // Timed out. Wrap the children in a fragment fiber to keep them
7877 // separate from the fallback children.
7878 var _nextFallbackChildren2 = nextProps.fallback;
7879 var _primaryChildFragment2 = createFiberFromFragment(
7880 // It shouldn't matter what the pending props are because we aren't
7881 // going to render this fragment.
7882 null, mode, NoWork, null);
7883 _primaryChildFragment2.child = _currentPrimaryChild;
7884
7885 // Even though we're creating a new fiber, there are no new children,
7886 // because we're reusing an already mounted tree. So we don't need to
7887 // schedule a placement.
7888 // primaryChildFragment.effectTag |= Placement;
7889
7890 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7891 // Outside of concurrent mode, we commit the effects from the
7892 var _progressedState2 = workInProgress.memoizedState;
7893 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
7894 _primaryChildFragment2.child = _progressedPrimaryChild2;
7895 }
7896
7897 // Because primaryChildFragment is a new fiber that we're inserting as the
7898 // parent of a new tree, we need to set its treeBaseDuration.
7899 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7900 // treeBaseDuration is the sum of all the child tree base durations.
7901 var _treeBaseDuration = 0;
7902 var _hiddenChild = _primaryChildFragment2.child;
7903 while (_hiddenChild !== null) {
7904 _treeBaseDuration += _hiddenChild.treeBaseDuration;
7905 _hiddenChild = _hiddenChild.sibling;
7906 }
7907 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
7908 }
7909
7910 // Create a fragment from the fallback children, too.
7911 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
7912 _fallbackChildFragment2.effectTag |= Placement;
7913 child = _primaryChildFragment2;
7914 _primaryChildFragment2.childExpirationTime = NoWork;
7915 // Skip the primary children, and continue working on the
7916 // fallback children.
7917 next = _fallbackChildFragment2;
7918 child.return = next.return = workInProgress;
7919 } else {
7920 // Still haven't timed out. Continue rendering the children, like we
7921 // normally do.
7922 var _nextPrimaryChildren2 = nextProps.children;
7923 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
7924 }
7925 }
7926 workInProgress.stateNode = current.stateNode;
7927 }
7928
7929 workInProgress.memoizedState = nextState;
7930 workInProgress.child = child;
7931 return next;
7932}
7933
7934function updateDehydratedSuspenseComponent(current, workInProgress, renderExpirationTime) {
7935 if (current === null) {
7936 // During the first pass, we'll bail out and not drill into the children.
7937 // Instead, we'll leave the content in place and try to hydrate it later.
7938 workInProgress.expirationTime = Never;
7939 return null;
7940 }
7941 // We use childExpirationTime to indicate that a child might depend on context, so if
7942 // any context has changed, we need to treat is as if the input might have changed.
7943 var hasContextChanged$$1 = current.childExpirationTime >= renderExpirationTime;
7944 if (didReceiveUpdate || hasContextChanged$$1) {
7945 // This boundary has changed since the first render. This means that we are now unable to
7946 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
7947 // during this render we can't. Instead, we're going to delete the whole subtree and
7948 // instead inject a new real Suspense boundary to take its place, which may render content
7949 // or fallback. The real Suspense boundary will suspend for a while so we have some time
7950 // to ensure it can produce real content, but all state and pending events will be lost.
7951
7952 // Detach from the current dehydrated boundary.
7953 current.alternate = null;
7954 workInProgress.alternate = null;
7955
7956 // Insert a deletion in the effect list.
7957 var returnFiber = workInProgress.return;
7958 !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
7959 var last = returnFiber.lastEffect;
7960 if (last !== null) {
7961 last.nextEffect = current;
7962 returnFiber.lastEffect = current;
7963 } else {
7964 returnFiber.firstEffect = returnFiber.lastEffect = current;
7965 }
7966 current.nextEffect = null;
7967 current.effectTag = Deletion;
7968
7969 // Upgrade this work in progress to a real Suspense component.
7970 workInProgress.tag = SuspenseComponent;
7971 workInProgress.stateNode = null;
7972 workInProgress.memoizedState = null;
7973 // This is now an insertion.
7974 workInProgress.effectTag |= Placement;
7975 // Retry as a real Suspense component.
7976 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
7977 }
7978 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
7979 // This is the first attempt.
7980 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
7981 var nextProps = workInProgress.pendingProps;
7982 var nextChildren = nextProps.children;
7983 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7984 return workInProgress.child;
7985 } else {
7986 // Something suspended. Leave the existing children in place.
7987 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
7988 workInProgress.child = null;
7989 return null;
7990 }
7991}
7992
7993function updatePortalComponent(current, workInProgress, renderExpirationTime) {
7994 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
7995 var nextChildren = workInProgress.pendingProps;
7996 if (current === null) {
7997 // Portals are special because we don't append the children during mount
7998 // but at commit. Therefore we need to track insertions which the normal
7999 // flow doesn't do during mount. This doesn't happen at the root because
8000 // the root always starts with a "current" with a null child.
8001 // TODO: Consider unifying this with how the root works.
8002 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8003 } else {
8004 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8005 }
8006 return workInProgress.child;
8007}
8008
8009function updateContextProvider(current, workInProgress, renderExpirationTime) {
8010 var providerType = workInProgress.type;
8011 var context = providerType._context;
8012
8013 var newProps = workInProgress.pendingProps;
8014 var oldProps = workInProgress.memoizedProps;
8015
8016 var newValue = newProps.value;
8017
8018 {
8019 var providerPropTypes = workInProgress.type.propTypes;
8020
8021 if (providerPropTypes) {
8022 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
8023 }
8024 }
8025
8026 pushProvider(workInProgress, newValue);
8027
8028 if (oldProps !== null) {
8029 var oldValue = oldProps.value;
8030 var changedBits = calculateChangedBits(context, newValue, oldValue);
8031 if (changedBits === 0) {
8032 // No change. Bailout early if children are the same.
8033 if (oldProps.children === newProps.children && !hasContextChanged()) {
8034 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8035 }
8036 } else {
8037 // The context value changed. Search for matching consumers and schedule
8038 // them to update.
8039 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
8040 }
8041 }
8042
8043 var newChildren = newProps.children;
8044 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8045 return workInProgress.child;
8046}
8047
8048var hasWarnedAboutUsingContextAsConsumer = false;
8049
8050function updateContextConsumer(current, workInProgress, renderExpirationTime) {
8051 var context = workInProgress.type;
8052 // The logic below for Context differs depending on PROD or DEV mode. In
8053 // DEV mode, we create a separate object for Context.Consumer that acts
8054 // like a proxy to Context. This proxy object adds unnecessary code in PROD
8055 // so we use the old behaviour (Context.Consumer references Context) to
8056 // reduce size and overhead. The separate object references context via
8057 // a property called "_context", which also gives us the ability to check
8058 // in DEV mode if this property exists or not and warn if it does not.
8059 {
8060 if (context._context === undefined) {
8061 // This may be because it's a Context (rather than a Consumer).
8062 // Or it may be because it's older React where they're the same thing.
8063 // We only want to warn if we're sure it's a new React.
8064 if (context !== context.Consumer) {
8065 if (!hasWarnedAboutUsingContextAsConsumer) {
8066 hasWarnedAboutUsingContextAsConsumer = true;
8067 warning$1(false, 'Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
8068 }
8069 }
8070 } else {
8071 context = context._context;
8072 }
8073 }
8074 var newProps = workInProgress.pendingProps;
8075 var render = newProps.children;
8076
8077 {
8078 !(typeof render === 'function') ? warningWithoutStack$1(false, 'A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.') : void 0;
8079 }
8080
8081 prepareToReadContext(workInProgress, renderExpirationTime);
8082 var newValue = readContext(context, newProps.unstable_observedBits);
8083 var newChildren = void 0;
8084 {
8085 ReactCurrentOwner$2.current = workInProgress;
8086 setCurrentPhase('render');
8087 newChildren = render(newValue);
8088 setCurrentPhase(null);
8089 }
8090
8091 // React DevTools reads this flag.
8092 workInProgress.effectTag |= PerformedWork;
8093 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8094 return workInProgress.child;
8095}
8096
8097function markWorkInProgressReceivedUpdate() {
8098 didReceiveUpdate = true;
8099}
8100
8101function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
8102 cancelWorkTimer(workInProgress);
8103
8104 if (current !== null) {
8105 // Reuse previous context list
8106 workInProgress.contextDependencies = current.contextDependencies;
8107 }
8108
8109 if (enableProfilerTimer) {
8110 // Don't update "base" render times for bailouts.
8111 stopProfilerTimerIfRunning(workInProgress);
8112 }
8113
8114 // Check if the children have any pending work.
8115 var childExpirationTime = workInProgress.childExpirationTime;
8116 if (childExpirationTime < renderExpirationTime) {
8117 // The children don't have any work either. We can skip them.
8118 // TODO: Once we add back resuming, we should check if the children are
8119 // a work-in-progress set. If so, we need to transfer their effects.
8120 return null;
8121 } else {
8122 // This fiber doesn't have work, but its subtree does. Clone the child
8123 // fibers and continue.
8124 cloneChildFibers(current, workInProgress);
8125 return workInProgress.child;
8126 }
8127}
8128
8129function beginWork(current, workInProgress, renderExpirationTime) {
8130 var updateExpirationTime = workInProgress.expirationTime;
8131
8132 if (current !== null) {
8133 var oldProps = current.memoizedProps;
8134 var newProps = workInProgress.pendingProps;
8135
8136 if (oldProps !== newProps || hasContextChanged()) {
8137 // If props or context changed, mark the fiber as having performed work.
8138 // This may be unset if the props are determined to be equal later (memo).
8139 didReceiveUpdate = true;
8140 } else if (updateExpirationTime < renderExpirationTime) {
8141 didReceiveUpdate = false;
8142 // This fiber does not have any pending work. Bailout without entering
8143 // the begin phase. There's still some bookkeeping we that needs to be done
8144 // in this optimized path, mostly pushing stuff onto the stack.
8145 switch (workInProgress.tag) {
8146 case HostRoot:
8147 pushHostRootContext(workInProgress);
8148 resetHydrationState();
8149 break;
8150 case HostComponent:
8151 pushHostContext(workInProgress);
8152 break;
8153 case ClassComponent:
8154 {
8155 var Component = workInProgress.type;
8156 if (isContextProvider(Component)) {
8157 pushContextProvider(workInProgress);
8158 }
8159 break;
8160 }
8161 case HostPortal:
8162 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8163 break;
8164 case ContextProvider:
8165 {
8166 var newValue = workInProgress.memoizedProps.value;
8167 pushProvider(workInProgress, newValue);
8168 break;
8169 }
8170 case Profiler:
8171 if (enableProfilerTimer) {
8172 workInProgress.effectTag |= Update;
8173 }
8174 break;
8175 case SuspenseComponent:
8176 {
8177 var state = workInProgress.memoizedState;
8178 var didTimeout = state !== null;
8179 if (didTimeout) {
8180 // If this boundary is currently timed out, we need to decide
8181 // whether to retry the primary children, or to skip over it and
8182 // go straight to the fallback. Check the priority of the primary
8183 var primaryChildFragment = workInProgress.child;
8184 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
8185 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
8186 // The primary children have pending work. Use the normal path
8187 // to attempt to render the primary children again.
8188 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
8189 } else {
8190 // The primary children do not have pending work with sufficient
8191 // priority. Bailout.
8192 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8193 if (child !== null) {
8194 // The fallback children have pending work. Skip over the
8195 // primary children and work on the fallback.
8196 return child.sibling;
8197 } else {
8198 return null;
8199 }
8200 }
8201 }
8202 break;
8203 }
8204 case DehydratedSuspenseComponent:
8205 {
8206 if (enableSuspenseServerRenderer) {
8207 // We know that this component will suspend again because if it has
8208 // been unsuspended it has committed as a regular Suspense component.
8209 // If it needs to be retried, it should have work scheduled on it.
8210 workInProgress.effectTag |= DidCapture;
8211 break;
8212 }
8213 }
8214 }
8215 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8216 }
8217 } else {
8218 didReceiveUpdate = false;
8219 }
8220
8221 // Before entering the begin phase, clear the expiration time.
8222 workInProgress.expirationTime = NoWork;
8223
8224 switch (workInProgress.tag) {
8225 case IndeterminateComponent:
8226 {
8227 var elementType = workInProgress.elementType;
8228 return mountIndeterminateComponent(current, workInProgress, elementType, renderExpirationTime);
8229 }
8230 case LazyComponent:
8231 {
8232 var _elementType = workInProgress.elementType;
8233 return mountLazyComponent(current, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
8234 }
8235 case FunctionComponent:
8236 {
8237 var _Component = workInProgress.type;
8238 var unresolvedProps = workInProgress.pendingProps;
8239 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
8240 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
8241 }
8242 case ClassComponent:
8243 {
8244 var _Component2 = workInProgress.type;
8245 var _unresolvedProps = workInProgress.pendingProps;
8246 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
8247 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
8248 }
8249 case HostRoot:
8250 return updateHostRoot(current, workInProgress, renderExpirationTime);
8251 case HostComponent:
8252 return updateHostComponent(current, workInProgress, renderExpirationTime);
8253 case HostText:
8254 return updateHostText(current, workInProgress);
8255 case SuspenseComponent:
8256 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
8257 case HostPortal:
8258 return updatePortalComponent(current, workInProgress, renderExpirationTime);
8259 case ForwardRef:
8260 {
8261 var type = workInProgress.type;
8262 var _unresolvedProps2 = workInProgress.pendingProps;
8263 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
8264 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
8265 }
8266 case Fragment:
8267 return updateFragment(current, workInProgress, renderExpirationTime);
8268 case Mode:
8269 return updateMode(current, workInProgress, renderExpirationTime);
8270 case Profiler:
8271 return updateProfiler(current, workInProgress, renderExpirationTime);
8272 case ContextProvider:
8273 return updateContextProvider(current, workInProgress, renderExpirationTime);
8274 case ContextConsumer:
8275 return updateContextConsumer(current, workInProgress, renderExpirationTime);
8276 case MemoComponent:
8277 {
8278 var _type2 = workInProgress.type;
8279 var _unresolvedProps3 = workInProgress.pendingProps;
8280 // Resolve outer props first, then resolve inner props.
8281 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
8282 {
8283 if (workInProgress.type !== workInProgress.elementType) {
8284 var outerPropTypes = _type2.propTypes;
8285 if (outerPropTypes) {
8286 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
8287 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
8288 }
8289 }
8290 }
8291 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
8292 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
8293 }
8294 case SimpleMemoComponent:
8295 {
8296 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
8297 }
8298 case IncompleteClassComponent:
8299 {
8300 var _Component3 = workInProgress.type;
8301 var _unresolvedProps4 = workInProgress.pendingProps;
8302 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
8303 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
8304 }
8305 case DehydratedSuspenseComponent:
8306 {
8307 if (enableSuspenseServerRenderer) {
8308 return updateDehydratedSuspenseComponent(current, workInProgress, renderExpirationTime);
8309 }
8310 break;
8311 }
8312 }
8313 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
8314}
8315
8316var valueCursor = createCursor(null);
8317
8318var rendererSigil = void 0;
8319{
8320 // Use this to detect multiple renderers using the same context
8321 rendererSigil = {};
8322}
8323
8324var currentlyRenderingFiber = null;
8325var lastContextDependency = null;
8326var lastContextWithAllBitsObserved = null;
8327
8328var isDisallowedContextReadInDEV = false;
8329
8330function resetContextDependences() {
8331 // This is called right before React yields execution, to ensure `readContext`
8332 // cannot be called outside the render phase.
8333 currentlyRenderingFiber = null;
8334 lastContextDependency = null;
8335 lastContextWithAllBitsObserved = null;
8336 {
8337 isDisallowedContextReadInDEV = false;
8338 }
8339}
8340
8341function enterDisallowedContextReadInDEV() {
8342 {
8343 isDisallowedContextReadInDEV = true;
8344 }
8345}
8346
8347function exitDisallowedContextReadInDEV() {
8348 {
8349 isDisallowedContextReadInDEV = false;
8350 }
8351}
8352
8353function pushProvider(providerFiber, nextValue) {
8354 var context = providerFiber.type._context;
8355
8356 if (isPrimaryRenderer) {
8357 push(valueCursor, context._currentValue, providerFiber);
8358
8359 context._currentValue = nextValue;
8360 {
8361 !(context._currentRenderer === undefined || context._currentRenderer === null || context._currentRenderer === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
8362 context._currentRenderer = rendererSigil;
8363 }
8364 } else {
8365 push(valueCursor, context._currentValue2, providerFiber);
8366
8367 context._currentValue2 = nextValue;
8368 {
8369 !(context._currentRenderer2 === undefined || context._currentRenderer2 === null || context._currentRenderer2 === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
8370 context._currentRenderer2 = rendererSigil;
8371 }
8372 }
8373}
8374
8375function popProvider(providerFiber) {
8376 var currentValue = valueCursor.current;
8377
8378 pop(valueCursor, providerFiber);
8379
8380 var context = providerFiber.type._context;
8381 if (isPrimaryRenderer) {
8382 context._currentValue = currentValue;
8383 } else {
8384 context._currentValue2 = currentValue;
8385 }
8386}
8387
8388function calculateChangedBits(context, newValue, oldValue) {
8389 if (is(oldValue, newValue)) {
8390 // No change
8391 return 0;
8392 } else {
8393 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
8394
8395 {
8396 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
8397 }
8398 return changedBits | 0;
8399 }
8400}
8401
8402function scheduleWorkOnParentPath(parent, renderExpirationTime) {
8403 // Update the child expiration time of all the ancestors, including
8404 // the alternates.
8405 var node = parent;
8406 while (node !== null) {
8407 var alternate = node.alternate;
8408 if (node.childExpirationTime < renderExpirationTime) {
8409 node.childExpirationTime = renderExpirationTime;
8410 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8411 alternate.childExpirationTime = renderExpirationTime;
8412 }
8413 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8414 alternate.childExpirationTime = renderExpirationTime;
8415 } else {
8416 // Neither alternate was updated, which means the rest of the
8417 // ancestor path already has sufficient priority.
8418 break;
8419 }
8420 node = node.return;
8421 }
8422}
8423
8424function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
8425 var fiber = workInProgress.child;
8426 if (fiber !== null) {
8427 // Set the return pointer of the child to the work-in-progress fiber.
8428 fiber.return = workInProgress;
8429 }
8430 while (fiber !== null) {
8431 var nextFiber = void 0;
8432
8433 // Visit this fiber.
8434 var list = fiber.contextDependencies;
8435 if (list !== null) {
8436 nextFiber = fiber.child;
8437
8438 var dependency = list.first;
8439 while (dependency !== null) {
8440 // Check if the context matches.
8441 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
8442 // Match! Schedule an update on this fiber.
8443
8444 if (fiber.tag === ClassComponent) {
8445 // Schedule a force update on the work-in-progress.
8446 var update = createUpdate(renderExpirationTime);
8447 update.tag = ForceUpdate;
8448 // TODO: Because we don't have a work-in-progress, this will add the
8449 // update to the current fiber, too, which means it will persist even if
8450 // this render is thrown away. Since it's a race condition, not sure it's
8451 // worth fixing.
8452 enqueueUpdate(fiber, update);
8453 }
8454
8455 if (fiber.expirationTime < renderExpirationTime) {
8456 fiber.expirationTime = renderExpirationTime;
8457 }
8458 var alternate = fiber.alternate;
8459 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8460 alternate.expirationTime = renderExpirationTime;
8461 }
8462
8463 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
8464
8465 // Mark the expiration time on the list, too.
8466 if (list.expirationTime < renderExpirationTime) {
8467 list.expirationTime = renderExpirationTime;
8468 }
8469
8470 // Since we already found a match, we can stop traversing the
8471 // dependency list.
8472 break;
8473 }
8474 dependency = dependency.next;
8475 }
8476 } else if (fiber.tag === ContextProvider) {
8477 // Don't scan deeper if this is a matching provider
8478 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
8479 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
8480 // If a dehydrated suspense component is in this subtree, we don't know
8481 // if it will have any context consumers in it. The best we can do is
8482 // mark it as having updates on its children.
8483 if (fiber.expirationTime < renderExpirationTime) {
8484 fiber.expirationTime = renderExpirationTime;
8485 }
8486 var _alternate = fiber.alternate;
8487 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
8488 _alternate.expirationTime = renderExpirationTime;
8489 }
8490 // This is intentionally passing this fiber as the parent
8491 // because we want to schedule this fiber as having work
8492 // on its children. We'll use the childExpirationTime on
8493 // this fiber to indicate that a context has changed.
8494 scheduleWorkOnParentPath(fiber, renderExpirationTime);
8495 nextFiber = fiber.sibling;
8496 } else {
8497 // Traverse down.
8498 nextFiber = fiber.child;
8499 }
8500
8501 if (nextFiber !== null) {
8502 // Set the return pointer of the child to the work-in-progress fiber.
8503 nextFiber.return = fiber;
8504 } else {
8505 // No child. Traverse to next sibling.
8506 nextFiber = fiber;
8507 while (nextFiber !== null) {
8508 if (nextFiber === workInProgress) {
8509 // We're back to the root of this subtree. Exit.
8510 nextFiber = null;
8511 break;
8512 }
8513 var sibling = nextFiber.sibling;
8514 if (sibling !== null) {
8515 // Set the return pointer of the sibling to the work-in-progress fiber.
8516 sibling.return = nextFiber.return;
8517 nextFiber = sibling;
8518 break;
8519 }
8520 // No more siblings. Traverse up.
8521 nextFiber = nextFiber.return;
8522 }
8523 }
8524 fiber = nextFiber;
8525 }
8526}
8527
8528function prepareToReadContext(workInProgress, renderExpirationTime) {
8529 currentlyRenderingFiber = workInProgress;
8530 lastContextDependency = null;
8531 lastContextWithAllBitsObserved = null;
8532
8533 var currentDependencies = workInProgress.contextDependencies;
8534 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
8535 // Context list has a pending update. Mark that this fiber performed work.
8536 markWorkInProgressReceivedUpdate();
8537 }
8538
8539 // Reset the work-in-progress list
8540 workInProgress.contextDependencies = null;
8541}
8542
8543function readContext(context, observedBits) {
8544 {
8545 // This warning would fire if you read context inside a Hook like useMemo.
8546 // Unlike the class check below, it's not enforced in production for perf.
8547 !!isDisallowedContextReadInDEV ? warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().') : void 0;
8548 }
8549
8550 if (lastContextWithAllBitsObserved === context) {
8551 // Nothing to do. We already observe everything in this context.
8552 } else if (observedBits === false || observedBits === 0) {
8553 // Do not observe any updates.
8554 } else {
8555 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
8556 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
8557 // Observe all updates.
8558 lastContextWithAllBitsObserved = context;
8559 resolvedObservedBits = maxSigned31BitInt;
8560 } else {
8561 resolvedObservedBits = observedBits;
8562 }
8563
8564 var contextItem = {
8565 context: context,
8566 observedBits: resolvedObservedBits,
8567 next: null
8568 };
8569
8570 if (lastContextDependency === null) {
8571 !(currentlyRenderingFiber !== null) ? invariant(false, 'Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().') : void 0;
8572
8573 // This is the first dependency for this component. Create a new list.
8574 lastContextDependency = contextItem;
8575 currentlyRenderingFiber.contextDependencies = {
8576 first: contextItem,
8577 expirationTime: NoWork
8578 };
8579 } else {
8580 // Append a new context item.
8581 lastContextDependency = lastContextDependency.next = contextItem;
8582 }
8583 }
8584 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
8585}
8586
8587// UpdateQueue is a linked list of prioritized updates.
8588//
8589// Like fibers, update queues come in pairs: a current queue, which represents
8590// the visible state of the screen, and a work-in-progress queue, which can be
8591// mutated and processed asynchronously before it is committed — a form of
8592// double buffering. If a work-in-progress render is discarded before finishing,
8593// we create a new work-in-progress by cloning the current queue.
8594//
8595// Both queues share a persistent, singly-linked list structure. To schedule an
8596// update, we append it to the end of both queues. Each queue maintains a
8597// pointer to first update in the persistent list that hasn't been processed.
8598// The work-in-progress pointer always has a position equal to or greater than
8599// the current queue, since we always work on that one. The current queue's
8600// pointer is only updated during the commit phase, when we swap in the
8601// work-in-progress.
8602//
8603// For example:
8604//
8605// Current pointer: A - B - C - D - E - F
8606// Work-in-progress pointer: D - E - F
8607// ^
8608// The work-in-progress queue has
8609// processed more updates than current.
8610//
8611// The reason we append to both queues is because otherwise we might drop
8612// updates without ever processing them. For example, if we only add updates to
8613// the work-in-progress queue, some updates could be lost whenever a work-in
8614// -progress render restarts by cloning from current. Similarly, if we only add
8615// updates to the current queue, the updates will be lost whenever an already
8616// in-progress queue commits and swaps with the current queue. However, by
8617// adding to both queues, we guarantee that the update will be part of the next
8618// work-in-progress. (And because the work-in-progress queue becomes the
8619// current queue once it commits, there's no danger of applying the same
8620// update twice.)
8621//
8622// Prioritization
8623// --------------
8624//
8625// Updates are not sorted by priority, but by insertion; new updates are always
8626// appended to the end of the list.
8627//
8628// The priority is still important, though. When processing the update queue
8629// during the render phase, only the updates with sufficient priority are
8630// included in the result. If we skip an update because it has insufficient
8631// priority, it remains in the queue to be processed later, during a lower
8632// priority render. Crucially, all updates subsequent to a skipped update also
8633// remain in the queue *regardless of their priority*. That means high priority
8634// updates are sometimes processed twice, at two separate priorities. We also
8635// keep track of a base state, that represents the state before the first
8636// update in the queue is applied.
8637//
8638// For example:
8639//
8640// Given a base state of '', and the following queue of updates
8641//
8642// A1 - B2 - C1 - D2
8643//
8644// where the number indicates the priority, and the update is applied to the
8645// previous state by appending a letter, React will process these updates as
8646// two separate renders, one per distinct priority level:
8647//
8648// First render, at priority 1:
8649// Base state: ''
8650// Updates: [A1, C1]
8651// Result state: 'AC'
8652//
8653// Second render, at priority 2:
8654// Base state: 'A' <- The base state does not include C1,
8655// because B2 was skipped.
8656// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
8657// Result state: 'ABCD'
8658//
8659// Because we process updates in insertion order, and rebase high priority
8660// updates when preceding updates are skipped, the final result is deterministic
8661// regardless of priority. Intermediate state may vary according to system
8662// resources, but the final state is always the same.
8663
8664var UpdateState = 0;
8665var ReplaceState = 1;
8666var ForceUpdate = 2;
8667var CaptureUpdate = 3;
8668
8669// Global state that is reset at the beginning of calling `processUpdateQueue`.
8670// It should only be read right after calling `processUpdateQueue`, via
8671// `checkHasForceUpdateAfterProcessing`.
8672var hasForceUpdate = false;
8673
8674var didWarnUpdateInsideUpdate = void 0;
8675var currentlyProcessingQueue = void 0;
8676var resetCurrentlyProcessingQueue = void 0;
8677{
8678 didWarnUpdateInsideUpdate = false;
8679 currentlyProcessingQueue = null;
8680 resetCurrentlyProcessingQueue = function () {
8681 currentlyProcessingQueue = null;
8682 };
8683}
8684
8685function createUpdateQueue(baseState) {
8686 var queue = {
8687 baseState: baseState,
8688 firstUpdate: null,
8689 lastUpdate: null,
8690 firstCapturedUpdate: null,
8691 lastCapturedUpdate: null,
8692 firstEffect: null,
8693 lastEffect: null,
8694 firstCapturedEffect: null,
8695 lastCapturedEffect: null
8696 };
8697 return queue;
8698}
8699
8700function cloneUpdateQueue(currentQueue) {
8701 var queue = {
8702 baseState: currentQueue.baseState,
8703 firstUpdate: currentQueue.firstUpdate,
8704 lastUpdate: currentQueue.lastUpdate,
8705
8706 // TODO: With resuming, if we bail out and resuse the child tree, we should
8707 // keep these effects.
8708 firstCapturedUpdate: null,
8709 lastCapturedUpdate: null,
8710
8711 firstEffect: null,
8712 lastEffect: null,
8713
8714 firstCapturedEffect: null,
8715 lastCapturedEffect: null
8716 };
8717 return queue;
8718}
8719
8720function createUpdate(expirationTime) {
8721 return {
8722 expirationTime: expirationTime,
8723
8724 tag: UpdateState,
8725 payload: null,
8726 callback: null,
8727
8728 next: null,
8729 nextEffect: null
8730 };
8731}
8732
8733function appendUpdateToQueue(queue, update) {
8734 // Append the update to the end of the list.
8735 if (queue.lastUpdate === null) {
8736 // Queue is empty
8737 queue.firstUpdate = queue.lastUpdate = update;
8738 } else {
8739 queue.lastUpdate.next = update;
8740 queue.lastUpdate = update;
8741 }
8742}
8743
8744function enqueueUpdate(fiber, update) {
8745 // Update queues are created lazily.
8746 var alternate = fiber.alternate;
8747 var queue1 = void 0;
8748 var queue2 = void 0;
8749 if (alternate === null) {
8750 // There's only one fiber.
8751 queue1 = fiber.updateQueue;
8752 queue2 = null;
8753 if (queue1 === null) {
8754 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8755 }
8756 } else {
8757 // There are two owners.
8758 queue1 = fiber.updateQueue;
8759 queue2 = alternate.updateQueue;
8760 if (queue1 === null) {
8761 if (queue2 === null) {
8762 // Neither fiber has an update queue. Create new ones.
8763 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8764 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
8765 } else {
8766 // Only one fiber has an update queue. Clone to create a new one.
8767 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
8768 }
8769 } else {
8770 if (queue2 === null) {
8771 // Only one fiber has an update queue. Clone to create a new one.
8772 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
8773 } else {
8774 // Both owners have an update queue.
8775 }
8776 }
8777 }
8778 if (queue2 === null || queue1 === queue2) {
8779 // There's only a single queue.
8780 appendUpdateToQueue(queue1, update);
8781 } else {
8782 // There are two queues. We need to append the update to both queues,
8783 // while accounting for the persistent structure of the list — we don't
8784 // want the same update to be added multiple times.
8785 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
8786 // One of the queues is not empty. We must add the update to both queues.
8787 appendUpdateToQueue(queue1, update);
8788 appendUpdateToQueue(queue2, update);
8789 } else {
8790 // Both queues are non-empty. The last update is the same in both lists,
8791 // because of structural sharing. So, only append to one of the lists.
8792 appendUpdateToQueue(queue1, update);
8793 // But we still need to update the `lastUpdate` pointer of queue2.
8794 queue2.lastUpdate = update;
8795 }
8796 }
8797
8798 {
8799 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
8800 warningWithoutStack$1(false, 'An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
8801 didWarnUpdateInsideUpdate = true;
8802 }
8803 }
8804}
8805
8806function enqueueCapturedUpdate(workInProgress, update) {
8807 // Captured updates go into a separate list, and only on the work-in-
8808 // progress queue.
8809 var workInProgressQueue = workInProgress.updateQueue;
8810 if (workInProgressQueue === null) {
8811 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
8812 } else {
8813 // TODO: I put this here rather than createWorkInProgress so that we don't
8814 // clone the queue unnecessarily. There's probably a better way to
8815 // structure this.
8816 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
8817 }
8818
8819 // Append the update to the end of the list.
8820 if (workInProgressQueue.lastCapturedUpdate === null) {
8821 // This is the first render phase update
8822 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
8823 } else {
8824 workInProgressQueue.lastCapturedUpdate.next = update;
8825 workInProgressQueue.lastCapturedUpdate = update;
8826 }
8827}
8828
8829function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
8830 var current = workInProgress.alternate;
8831 if (current !== null) {
8832 // If the work-in-progress queue is equal to the current queue,
8833 // we need to clone it first.
8834 if (queue === current.updateQueue) {
8835 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
8836 }
8837 }
8838 return queue;
8839}
8840
8841function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
8842 switch (update.tag) {
8843 case ReplaceState:
8844 {
8845 var _payload = update.payload;
8846 if (typeof _payload === 'function') {
8847 // Updater function
8848 {
8849 enterDisallowedContextReadInDEV();
8850 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8851 _payload.call(instance, prevState, nextProps);
8852 }
8853 }
8854 var nextState = _payload.call(instance, prevState, nextProps);
8855 {
8856 exitDisallowedContextReadInDEV();
8857 }
8858 return nextState;
8859 }
8860 // State object
8861 return _payload;
8862 }
8863 case CaptureUpdate:
8864 {
8865 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
8866 }
8867 // Intentional fallthrough
8868 case UpdateState:
8869 {
8870 var _payload2 = update.payload;
8871 var partialState = void 0;
8872 if (typeof _payload2 === 'function') {
8873 // Updater function
8874 {
8875 enterDisallowedContextReadInDEV();
8876 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8877 _payload2.call(instance, prevState, nextProps);
8878 }
8879 }
8880 partialState = _payload2.call(instance, prevState, nextProps);
8881 {
8882 exitDisallowedContextReadInDEV();
8883 }
8884 } else {
8885 // Partial state object
8886 partialState = _payload2;
8887 }
8888 if (partialState === null || partialState === undefined) {
8889 // Null and undefined are treated as no-ops.
8890 return prevState;
8891 }
8892 // Merge the partial state and the previous state.
8893 return _assign({}, prevState, partialState);
8894 }
8895 case ForceUpdate:
8896 {
8897 hasForceUpdate = true;
8898 return prevState;
8899 }
8900 }
8901 return prevState;
8902}
8903
8904function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
8905 hasForceUpdate = false;
8906
8907 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
8908
8909 {
8910 currentlyProcessingQueue = queue;
8911 }
8912
8913 // These values may change as we process the queue.
8914 var newBaseState = queue.baseState;
8915 var newFirstUpdate = null;
8916 var newExpirationTime = NoWork;
8917
8918 // Iterate through the list of updates to compute the result.
8919 var update = queue.firstUpdate;
8920 var resultState = newBaseState;
8921 while (update !== null) {
8922 var updateExpirationTime = update.expirationTime;
8923 if (updateExpirationTime < renderExpirationTime) {
8924 // This update does not have sufficient priority. Skip it.
8925 if (newFirstUpdate === null) {
8926 // This is the first skipped update. It will be the first update in
8927 // the new list.
8928 newFirstUpdate = update;
8929 // Since this is the first update that was skipped, the current result
8930 // is the new base state.
8931 newBaseState = resultState;
8932 }
8933 // Since this update will remain in the list, update the remaining
8934 // expiration time.
8935 if (newExpirationTime < updateExpirationTime) {
8936 newExpirationTime = updateExpirationTime;
8937 }
8938 } else {
8939 // This update does have sufficient priority. Process it and compute
8940 // a new result.
8941 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8942 var _callback = update.callback;
8943 if (_callback !== null) {
8944 workInProgress.effectTag |= Callback;
8945 // Set this to null, in case it was mutated during an aborted render.
8946 update.nextEffect = null;
8947 if (queue.lastEffect === null) {
8948 queue.firstEffect = queue.lastEffect = update;
8949 } else {
8950 queue.lastEffect.nextEffect = update;
8951 queue.lastEffect = update;
8952 }
8953 }
8954 }
8955 // Continue to the next update.
8956 update = update.next;
8957 }
8958
8959 // Separately, iterate though the list of captured updates.
8960 var newFirstCapturedUpdate = null;
8961 update = queue.firstCapturedUpdate;
8962 while (update !== null) {
8963 var _updateExpirationTime = update.expirationTime;
8964 if (_updateExpirationTime < renderExpirationTime) {
8965 // This update does not have sufficient priority. Skip it.
8966 if (newFirstCapturedUpdate === null) {
8967 // This is the first skipped captured update. It will be the first
8968 // update in the new list.
8969 newFirstCapturedUpdate = update;
8970 // If this is the first update that was skipped, the current result is
8971 // the new base state.
8972 if (newFirstUpdate === null) {
8973 newBaseState = resultState;
8974 }
8975 }
8976 // Since this update will remain in the list, update the remaining
8977 // expiration time.
8978 if (newExpirationTime < _updateExpirationTime) {
8979 newExpirationTime = _updateExpirationTime;
8980 }
8981 } else {
8982 // This update does have sufficient priority. Process it and compute
8983 // a new result.
8984 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8985 var _callback2 = update.callback;
8986 if (_callback2 !== null) {
8987 workInProgress.effectTag |= Callback;
8988 // Set this to null, in case it was mutated during an aborted render.
8989 update.nextEffect = null;
8990 if (queue.lastCapturedEffect === null) {
8991 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
8992 } else {
8993 queue.lastCapturedEffect.nextEffect = update;
8994 queue.lastCapturedEffect = update;
8995 }
8996 }
8997 }
8998 update = update.next;
8999 }
9000
9001 if (newFirstUpdate === null) {
9002 queue.lastUpdate = null;
9003 }
9004 if (newFirstCapturedUpdate === null) {
9005 queue.lastCapturedUpdate = null;
9006 } else {
9007 workInProgress.effectTag |= Callback;
9008 }
9009 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
9010 // We processed every update, without skipping. That means the new base
9011 // state is the same as the result state.
9012 newBaseState = resultState;
9013 }
9014
9015 queue.baseState = newBaseState;
9016 queue.firstUpdate = newFirstUpdate;
9017 queue.firstCapturedUpdate = newFirstCapturedUpdate;
9018
9019 // Set the remaining expiration time to be whatever is remaining in the queue.
9020 // This should be fine because the only two other things that contribute to
9021 // expiration time are props and context. We're already in the middle of the
9022 // begin phase by the time we start processing the queue, so we've already
9023 // dealt with the props. Context in components that specify
9024 // shouldComponentUpdate is tricky; but we'll have to account for
9025 // that regardless.
9026 workInProgress.expirationTime = newExpirationTime;
9027 workInProgress.memoizedState = resultState;
9028
9029 {
9030 currentlyProcessingQueue = null;
9031 }
9032}
9033
9034function callCallback(callback, context) {
9035 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
9036 callback.call(context);
9037}
9038
9039function resetHasForceUpdateBeforeProcessing() {
9040 hasForceUpdate = false;
9041}
9042
9043function checkHasForceUpdateAfterProcessing() {
9044 return hasForceUpdate;
9045}
9046
9047function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
9048 // If the finished render included captured updates, and there are still
9049 // lower priority updates left over, we need to keep the captured updates
9050 // in the queue so that they are rebased and not dropped once we process the
9051 // queue again at the lower priority.
9052 if (finishedQueue.firstCapturedUpdate !== null) {
9053 // Join the captured update list to the end of the normal list.
9054 if (finishedQueue.lastUpdate !== null) {
9055 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
9056 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
9057 }
9058 // Clear the list of captured updates.
9059 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
9060 }
9061
9062 // Commit the effects
9063 commitUpdateEffects(finishedQueue.firstEffect, instance);
9064 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
9065
9066 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
9067 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
9068}
9069
9070function commitUpdateEffects(effect, instance) {
9071 while (effect !== null) {
9072 var _callback3 = effect.callback;
9073 if (_callback3 !== null) {
9074 effect.callback = null;
9075 callCallback(_callback3, instance);
9076 }
9077 effect = effect.nextEffect;
9078 }
9079}
9080
9081function createCapturedValue(value, source) {
9082 // If the value is an error, call this function immediately after it is thrown
9083 // so the stack is accurate.
9084 return {
9085 value: value,
9086 source: source,
9087 stack: getStackByFiberInDevAndProd(source)
9088 };
9089}
9090
9091function markUpdate(workInProgress) {
9092 // Tag the fiber with an update effect. This turns a Placement into
9093 // a PlacementAndUpdate.
9094 workInProgress.effectTag |= Update;
9095}
9096
9097function markRef$1(workInProgress) {
9098 workInProgress.effectTag |= Ref;
9099}
9100
9101var appendAllChildren = void 0;
9102var updateHostContainer = void 0;
9103var updateHostComponent$1 = void 0;
9104var updateHostText$1 = void 0;
9105if (supportsMutation) {
9106 // Mutation mode
9107
9108 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9109 // We only have the top Fiber that was created but we need recurse down its
9110 // children to find all the terminal nodes.
9111 var node = workInProgress.child;
9112 while (node !== null) {
9113 if (node.tag === HostComponent || node.tag === HostText) {
9114 appendInitialChild(parent, node.stateNode);
9115 } else if (node.tag === HostPortal) {
9116 // If we have a portal child, then we don't want to traverse
9117 // down its children. Instead, we'll get insertions from each child in
9118 // the portal directly.
9119 } else if (node.child !== null) {
9120 node.child.return = node;
9121 node = node.child;
9122 continue;
9123 }
9124 if (node === workInProgress) {
9125 return;
9126 }
9127 while (node.sibling === null) {
9128 if (node.return === null || node.return === workInProgress) {
9129 return;
9130 }
9131 node = node.return;
9132 }
9133 node.sibling.return = node.return;
9134 node = node.sibling;
9135 }
9136 };
9137
9138 updateHostContainer = function (workInProgress) {
9139 // Noop
9140 };
9141 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9142 // If we have an alternate, that means this is an update and we need to
9143 // schedule a side-effect to do the updates.
9144 var oldProps = current.memoizedProps;
9145 if (oldProps === newProps) {
9146 // In mutation mode, this is sufficient for a bailout because
9147 // we won't touch this node even if children changed.
9148 return;
9149 }
9150
9151 // If we get updated because one of our children updated, we don't
9152 // have newProps so we'll have to reuse them.
9153 // TODO: Split the update API as separate for the props vs. children.
9154 // Even better would be if children weren't special cased at all tho.
9155 var instance = workInProgress.stateNode;
9156 var currentHostContext = getHostContext();
9157 // TODO: Experiencing an error where oldProps is null. Suggests a host
9158 // component is hitting the resume path. Figure out why. Possibly
9159 // related to `hidden`.
9160 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9161 // TODO: Type this specific to this type of component.
9162 workInProgress.updateQueue = updatePayload;
9163 // If the update payload indicates that there is a change or if there
9164 // is a new ref we mark this as an update. All the work is done in commitWork.
9165 if (updatePayload) {
9166 markUpdate(workInProgress);
9167 }
9168 };
9169 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9170 // If the text differs, mark it as an update. All the work in done in commitWork.
9171 if (oldText !== newText) {
9172 markUpdate(workInProgress);
9173 }
9174 };
9175} else if (supportsPersistence) {
9176 // Persistent host tree mode
9177
9178 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9179 // We only have the top Fiber that was created but we need recurse down its
9180 // children to find all the terminal nodes.
9181 var node = workInProgress.child;
9182 while (node !== null) {
9183 // eslint-disable-next-line no-labels
9184 branches: if (node.tag === HostComponent) {
9185 var instance = node.stateNode;
9186 if (needsVisibilityToggle) {
9187 var props = node.memoizedProps;
9188 var type = node.type;
9189 if (isHidden) {
9190 // This child is inside a timed out tree. Hide it.
9191 instance = cloneHiddenInstance(instance, type, props, node);
9192 } else {
9193 // This child was previously inside a timed out tree. If it was not
9194 // updated during this render, it may need to be unhidden. Clone
9195 // again to be sure.
9196 instance = cloneUnhiddenInstance(instance, type, props, node);
9197 }
9198 node.stateNode = instance;
9199 }
9200 appendInitialChild(parent, instance);
9201 } else if (node.tag === HostText) {
9202 var _instance = node.stateNode;
9203 if (needsVisibilityToggle) {
9204 var text = node.memoizedProps;
9205 var rootContainerInstance = getRootHostContainer();
9206 var currentHostContext = getHostContext();
9207 if (isHidden) {
9208 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9209 } else {
9210 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9211 }
9212 node.stateNode = _instance;
9213 }
9214 appendInitialChild(parent, _instance);
9215 } else if (node.tag === HostPortal) {
9216 // If we have a portal child, then we don't want to traverse
9217 // down its children. Instead, we'll get insertions from each child in
9218 // the portal directly.
9219 } else if (node.tag === SuspenseComponent) {
9220 var current = node.alternate;
9221 if (current !== null) {
9222 var oldState = current.memoizedState;
9223 var newState = node.memoizedState;
9224 var oldIsHidden = oldState !== null;
9225 var newIsHidden = newState !== null;
9226 if (oldIsHidden !== newIsHidden) {
9227 // The placeholder either just timed out or switched back to the normal
9228 // children after having previously timed out. Toggle the visibility of
9229 // the direct host children.
9230 var primaryChildParent = newIsHidden ? node.child : node;
9231 if (primaryChildParent !== null) {
9232 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
9233 }
9234 // eslint-disable-next-line no-labels
9235 break branches;
9236 }
9237 }
9238 if (node.child !== null) {
9239 // Continue traversing like normal
9240 node.child.return = node;
9241 node = node.child;
9242 continue;
9243 }
9244 } else if (node.child !== null) {
9245 node.child.return = node;
9246 node = node.child;
9247 continue;
9248 }
9249 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9250 node = node;
9251 if (node === workInProgress) {
9252 return;
9253 }
9254 while (node.sibling === null) {
9255 if (node.return === null || node.return === workInProgress) {
9256 return;
9257 }
9258 node = node.return;
9259 }
9260 node.sibling.return = node.return;
9261 node = node.sibling;
9262 }
9263 };
9264
9265 // An unfortunate fork of appendAllChildren because we have two different parent types.
9266 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
9267 // We only have the top Fiber that was created but we need recurse down its
9268 // children to find all the terminal nodes.
9269 var node = workInProgress.child;
9270 while (node !== null) {
9271 // eslint-disable-next-line no-labels
9272 branches: if (node.tag === HostComponent) {
9273 var instance = node.stateNode;
9274 if (needsVisibilityToggle) {
9275 var props = node.memoizedProps;
9276 var type = node.type;
9277 if (isHidden) {
9278 // This child is inside a timed out tree. Hide it.
9279 instance = cloneHiddenInstance(instance, type, props, node);
9280 } else {
9281 // This child was previously inside a timed out tree. If it was not
9282 // updated during this render, it may need to be unhidden. Clone
9283 // again to be sure.
9284 instance = cloneUnhiddenInstance(instance, type, props, node);
9285 }
9286 node.stateNode = instance;
9287 }
9288 appendChildToContainerChildSet(containerChildSet, instance);
9289 } else if (node.tag === HostText) {
9290 var _instance2 = node.stateNode;
9291 if (needsVisibilityToggle) {
9292 var text = node.memoizedProps;
9293 var rootContainerInstance = getRootHostContainer();
9294 var currentHostContext = getHostContext();
9295 if (isHidden) {
9296 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9297 } else {
9298 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9299 }
9300 node.stateNode = _instance2;
9301 }
9302 appendChildToContainerChildSet(containerChildSet, _instance2);
9303 } else if (node.tag === HostPortal) {
9304 // If we have a portal child, then we don't want to traverse
9305 // down its children. Instead, we'll get insertions from each child in
9306 // the portal directly.
9307 } else if (node.tag === SuspenseComponent) {
9308 var current = node.alternate;
9309 if (current !== null) {
9310 var oldState = current.memoizedState;
9311 var newState = node.memoizedState;
9312 var oldIsHidden = oldState !== null;
9313 var newIsHidden = newState !== null;
9314 if (oldIsHidden !== newIsHidden) {
9315 // The placeholder either just timed out or switched back to the normal
9316 // children after having previously timed out. Toggle the visibility of
9317 // the direct host children.
9318 var primaryChildParent = newIsHidden ? node.child : node;
9319 if (primaryChildParent !== null) {
9320 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
9321 }
9322 // eslint-disable-next-line no-labels
9323 break branches;
9324 }
9325 }
9326 if (node.child !== null) {
9327 // Continue traversing like normal
9328 node.child.return = node;
9329 node = node.child;
9330 continue;
9331 }
9332 } else if (node.child !== null) {
9333 node.child.return = node;
9334 node = node.child;
9335 continue;
9336 }
9337 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9338 node = node;
9339 if (node === workInProgress) {
9340 return;
9341 }
9342 while (node.sibling === null) {
9343 if (node.return === null || node.return === workInProgress) {
9344 return;
9345 }
9346 node = node.return;
9347 }
9348 node.sibling.return = node.return;
9349 node = node.sibling;
9350 }
9351 };
9352 updateHostContainer = function (workInProgress) {
9353 var portalOrRoot = workInProgress.stateNode;
9354 var childrenUnchanged = workInProgress.firstEffect === null;
9355 if (childrenUnchanged) {
9356 // No changes, just reuse the existing instance.
9357 } else {
9358 var container = portalOrRoot.containerInfo;
9359 var newChildSet = createContainerChildSet(container);
9360 // If children might have changed, we have to add them all to the set.
9361 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
9362 portalOrRoot.pendingChildren = newChildSet;
9363 // Schedule an update on the container to swap out the container.
9364 markUpdate(workInProgress);
9365 finalizeContainerChildren(container, newChildSet);
9366 }
9367 };
9368 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9369 var currentInstance = current.stateNode;
9370 var oldProps = current.memoizedProps;
9371 // If there are no effects associated with this node, then none of our children had any updates.
9372 // This guarantees that we can reuse all of them.
9373 var childrenUnchanged = workInProgress.firstEffect === null;
9374 if (childrenUnchanged && oldProps === newProps) {
9375 // No changes, just reuse the existing instance.
9376 // Note that this might release a previous clone.
9377 workInProgress.stateNode = currentInstance;
9378 return;
9379 }
9380 var recyclableInstance = workInProgress.stateNode;
9381 var currentHostContext = getHostContext();
9382 var updatePayload = null;
9383 if (oldProps !== newProps) {
9384 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9385 }
9386 if (childrenUnchanged && updatePayload === null) {
9387 // No changes, just reuse the existing instance.
9388 // Note that this might release a previous clone.
9389 workInProgress.stateNode = currentInstance;
9390 return;
9391 }
9392 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9393 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9394 markUpdate(workInProgress);
9395 }
9396 workInProgress.stateNode = newInstance;
9397 if (childrenUnchanged) {
9398 // If there are no other effects in this tree, we need to flag this node as having one.
9399 // Even though we're not going to use it for anything.
9400 // Otherwise parents won't know that there are new children to propagate upwards.
9401 markUpdate(workInProgress);
9402 } else {
9403 // If children might have changed, we have to add them all to the set.
9404 appendAllChildren(newInstance, workInProgress, false, false);
9405 }
9406 };
9407 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9408 if (oldText !== newText) {
9409 // If the text content differs, we'll create a new text instance for it.
9410 var rootContainerInstance = getRootHostContainer();
9411 var currentHostContext = getHostContext();
9412 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9413 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9414 // This lets the parents know that at least one of their children has changed.
9415 markUpdate(workInProgress);
9416 }
9417 };
9418} else {
9419 // No host operations
9420 updateHostContainer = function (workInProgress) {
9421 // Noop
9422 };
9423 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9424 // Noop
9425 };
9426 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9427 // Noop
9428 };
9429}
9430
9431function completeWork(current, workInProgress, renderExpirationTime) {
9432 var newProps = workInProgress.pendingProps;
9433
9434 switch (workInProgress.tag) {
9435 case IndeterminateComponent:
9436 break;
9437 case LazyComponent:
9438 break;
9439 case SimpleMemoComponent:
9440 case FunctionComponent:
9441 break;
9442 case ClassComponent:
9443 {
9444 var Component = workInProgress.type;
9445 if (isContextProvider(Component)) {
9446 popContext(workInProgress);
9447 }
9448 break;
9449 }
9450 case HostRoot:
9451 {
9452 popHostContainer(workInProgress);
9453 popTopLevelContextObject(workInProgress);
9454 var fiberRoot = workInProgress.stateNode;
9455 if (fiberRoot.pendingContext) {
9456 fiberRoot.context = fiberRoot.pendingContext;
9457 fiberRoot.pendingContext = null;
9458 }
9459 if (current === null || current.child === null) {
9460 // If we hydrated, pop so that we can delete any remaining children
9461 // that weren't hydrated.
9462 popHydrationState(workInProgress);
9463 // This resets the hacky state to fix isMounted before committing.
9464 // TODO: Delete this when we delete isMounted and findDOMNode.
9465 workInProgress.effectTag &= ~Placement;
9466 }
9467 updateHostContainer(workInProgress);
9468 break;
9469 }
9470 case HostComponent:
9471 {
9472 popHostContext(workInProgress);
9473 var rootContainerInstance = getRootHostContainer();
9474 var type = workInProgress.type;
9475 if (current !== null && workInProgress.stateNode != null) {
9476 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9477
9478 if (current.ref !== workInProgress.ref) {
9479 markRef$1(workInProgress);
9480 }
9481 } else {
9482 if (!newProps) {
9483 !(workInProgress.stateNode !== null) ? invariant(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9484 // This can happen when we abort work.
9485 break;
9486 }
9487
9488 var currentHostContext = getHostContext();
9489 // TODO: Move createInstance to beginWork and keep it on a context
9490 // "stack" as the parent. Then append children as we go in beginWork
9491 // or completeWork depending on we want to add then top->down or
9492 // bottom->up. Top->down is faster in IE11.
9493 var wasHydrated = popHydrationState(workInProgress);
9494 if (wasHydrated) {
9495 // TODO: Move this and createInstance step into the beginPhase
9496 // to consolidate.
9497 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
9498 // If changes to the hydrated node needs to be applied at the
9499 // commit-phase we mark this as such.
9500 markUpdate(workInProgress);
9501 }
9502 } else {
9503 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9504
9505 appendAllChildren(instance, workInProgress, false, false);
9506
9507 // Certain renderers require commit-time effects for initial mount.
9508 // (eg DOM renderer supports auto-focus for certain elements).
9509 // Make sure such renderers get scheduled for later work.
9510 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
9511 markUpdate(workInProgress);
9512 }
9513 workInProgress.stateNode = instance;
9514 }
9515
9516 if (workInProgress.ref !== null) {
9517 // If there is a ref on a host node we need to schedule a callback
9518 markRef$1(workInProgress);
9519 }
9520 }
9521 break;
9522 }
9523 case HostText:
9524 {
9525 var newText = newProps;
9526 if (current && workInProgress.stateNode != null) {
9527 var oldText = current.memoizedProps;
9528 // If we have an alternate, that means this is an update and we need
9529 // to schedule a side-effect to do the updates.
9530 updateHostText$1(current, workInProgress, oldText, newText);
9531 } else {
9532 if (typeof newText !== 'string') {
9533 !(workInProgress.stateNode !== null) ? invariant(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0;
9534 // This can happen when we abort work.
9535 }
9536 var _rootContainerInstance = getRootHostContainer();
9537 var _currentHostContext = getHostContext();
9538 var _wasHydrated = popHydrationState(workInProgress);
9539 if (_wasHydrated) {
9540 if (prepareToHydrateHostTextInstance(workInProgress)) {
9541 markUpdate(workInProgress);
9542 }
9543 } else {
9544 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
9545 }
9546 }
9547 break;
9548 }
9549 case ForwardRef:
9550 break;
9551 case SuspenseComponent:
9552 {
9553 var nextState = workInProgress.memoizedState;
9554 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9555 // Something suspended. Re-render with the fallback children.
9556 workInProgress.expirationTime = renderExpirationTime;
9557 // Do not reset the effect list.
9558 return workInProgress;
9559 }
9560
9561 var nextDidTimeout = nextState !== null;
9562 var prevDidTimeout = current !== null && current.memoizedState !== null;
9563
9564 if (current !== null && !nextDidTimeout && prevDidTimeout) {
9565 // We just switched from the fallback to the normal children. Delete
9566 // the fallback.
9567 // TODO: Would it be better to store the fallback fragment on
9568 var currentFallbackChild = current.child.sibling;
9569 if (currentFallbackChild !== null) {
9570 // Deletions go at the beginning of the return fiber's effect list
9571 var first = workInProgress.firstEffect;
9572 if (first !== null) {
9573 workInProgress.firstEffect = currentFallbackChild;
9574 currentFallbackChild.nextEffect = first;
9575 } else {
9576 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9577 currentFallbackChild.nextEffect = null;
9578 }
9579 currentFallbackChild.effectTag = Deletion;
9580 }
9581 }
9582
9583 if (nextDidTimeout || prevDidTimeout) {
9584 // If the children are hidden, or if they were previous hidden, schedule
9585 // an effect to toggle their visibility. This is also used to attach a
9586 // retry listener to the promise.
9587 workInProgress.effectTag |= Update;
9588 }
9589 break;
9590 }
9591 case Fragment:
9592 break;
9593 case Mode:
9594 break;
9595 case Profiler:
9596 break;
9597 case HostPortal:
9598 popHostContainer(workInProgress);
9599 updateHostContainer(workInProgress);
9600 break;
9601 case ContextProvider:
9602 // Pop provider fiber
9603 popProvider(workInProgress);
9604 break;
9605 case ContextConsumer:
9606 break;
9607 case MemoComponent:
9608 break;
9609 case IncompleteClassComponent:
9610 {
9611 // Same as class component case. I put it down here so that the tags are
9612 // sequential to ensure this switch is compiled to a jump table.
9613 var _Component = workInProgress.type;
9614 if (isContextProvider(_Component)) {
9615 popContext(workInProgress);
9616 }
9617 break;
9618 }
9619 case DehydratedSuspenseComponent:
9620 {
9621 if (enableSuspenseServerRenderer) {
9622 if (current === null) {
9623 var _wasHydrated2 = popHydrationState(workInProgress);
9624 !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
9625 skipPastDehydratedSuspenseInstance(workInProgress);
9626 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
9627 // This boundary did not suspend so it's now hydrated.
9628 // To handle any future suspense cases, we're going to now upgrade it
9629 // to a Suspense component. We detach it from the existing current fiber.
9630 current.alternate = null;
9631 workInProgress.alternate = null;
9632 workInProgress.tag = SuspenseComponent;
9633 workInProgress.memoizedState = null;
9634 workInProgress.stateNode = null;
9635 }
9636 }
9637 break;
9638 }
9639 default:
9640 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9641 }
9642
9643 return null;
9644}
9645
9646function shouldCaptureSuspense(workInProgress) {
9647 // In order to capture, the Suspense component must have a fallback prop.
9648 if (workInProgress.memoizedProps.fallback === undefined) {
9649 return false;
9650 }
9651 // If it was the primary children that just suspended, capture and render the
9652 // fallback. Otherwise, don't capture and bubble to the next boundary.
9653 var nextState = workInProgress.memoizedState;
9654 return nextState === null;
9655}
9656
9657// This module is forked in different environments.
9658// By default, return `true` to log errors to the console.
9659// Forks can return `false` if this isn't desirable.
9660function showErrorDialog(capturedError) {
9661 return true;
9662}
9663
9664function logCapturedError(capturedError) {
9665 var logError = showErrorDialog(capturedError);
9666
9667 // Allow injected showErrorDialog() to prevent default console.error logging.
9668 // This enables renderers like ReactNative to better manage redbox behavior.
9669 if (logError === false) {
9670 return;
9671 }
9672
9673 var error = capturedError.error;
9674 {
9675 var componentName = capturedError.componentName,
9676 componentStack = capturedError.componentStack,
9677 errorBoundaryName = capturedError.errorBoundaryName,
9678 errorBoundaryFound = capturedError.errorBoundaryFound,
9679 willRetry = capturedError.willRetry;
9680
9681 // Browsers support silencing uncaught errors by calling
9682 // `preventDefault()` in window `error` handler.
9683 // We record this information as an expando on the error.
9684
9685 if (error != null && error._suppressLogging) {
9686 if (errorBoundaryFound && willRetry) {
9687 // The error is recoverable and was silenced.
9688 // Ignore it and don't print the stack addendum.
9689 // This is handy for testing error boundaries without noise.
9690 return;
9691 }
9692 // The error is fatal. Since the silencing might have
9693 // been accidental, we'll surface it anyway.
9694 // However, the browser would have silenced the original error
9695 // so we'll print it first, and then print the stack addendum.
9696 console.error(error);
9697 // For a more detailed description of this block, see:
9698 // https://github.com/facebook/react/pull/13384
9699 }
9700
9701 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
9702
9703 var errorBoundaryMessage = void 0;
9704 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
9705 if (errorBoundaryFound && errorBoundaryName) {
9706 if (willRetry) {
9707 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
9708 } else {
9709 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
9710 }
9711 } else {
9712 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.';
9713 }
9714 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
9715
9716 // In development, we provide our own message with just the component stack.
9717 // We don't include the original error message and JS stack because the browser
9718 // has already printed it. Even if the application swallows the error, it is still
9719 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
9720 console.error(combinedMessage);
9721 }
9722}
9723
9724var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
9725{
9726 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
9727}
9728
9729var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
9730
9731function logError(boundary, errorInfo) {
9732 var source = errorInfo.source;
9733 var stack = errorInfo.stack;
9734 if (stack === null && source !== null) {
9735 stack = getStackByFiberInDevAndProd(source);
9736 }
9737
9738 var capturedError = {
9739 componentName: source !== null ? getComponentName(source.type) : null,
9740 componentStack: stack !== null ? stack : '',
9741 error: errorInfo.value,
9742 errorBoundary: null,
9743 errorBoundaryName: null,
9744 errorBoundaryFound: false,
9745 willRetry: false
9746 };
9747
9748 if (boundary !== null && boundary.tag === ClassComponent) {
9749 capturedError.errorBoundary = boundary.stateNode;
9750 capturedError.errorBoundaryName = getComponentName(boundary.type);
9751 capturedError.errorBoundaryFound = true;
9752 capturedError.willRetry = true;
9753 }
9754
9755 try {
9756 logCapturedError(capturedError);
9757 } catch (e) {
9758 // This method must not throw, or React internal state will get messed up.
9759 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
9760 // we want to report this error outside of the normal stack as a last resort.
9761 // https://github.com/facebook/react/issues/13188
9762 setTimeout(function () {
9763 throw e;
9764 });
9765 }
9766}
9767
9768var callComponentWillUnmountWithTimer = function (current, instance) {
9769 startPhaseTimer(current, 'componentWillUnmount');
9770 instance.props = current.memoizedProps;
9771 instance.state = current.memoizedState;
9772 instance.componentWillUnmount();
9773 stopPhaseTimer();
9774};
9775
9776// Capture errors so they don't interrupt unmounting.
9777function safelyCallComponentWillUnmount(current, instance) {
9778 {
9779 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
9780 if (hasCaughtError()) {
9781 var unmountError = clearCaughtError();
9782 captureCommitPhaseError(current, unmountError);
9783 }
9784 }
9785}
9786
9787function safelyDetachRef(current) {
9788 var ref = current.ref;
9789 if (ref !== null) {
9790 if (typeof ref === 'function') {
9791 {
9792 invokeGuardedCallback(null, ref, null, null);
9793 if (hasCaughtError()) {
9794 var refError = clearCaughtError();
9795 captureCommitPhaseError(current, refError);
9796 }
9797 }
9798 } else {
9799 ref.current = null;
9800 }
9801 }
9802}
9803
9804function safelyCallDestroy(current, destroy) {
9805 {
9806 invokeGuardedCallback(null, destroy, null);
9807 if (hasCaughtError()) {
9808 var error = clearCaughtError();
9809 captureCommitPhaseError(current, error);
9810 }
9811 }
9812}
9813
9814function commitBeforeMutationLifeCycles(current, finishedWork) {
9815 switch (finishedWork.tag) {
9816 case FunctionComponent:
9817 case ForwardRef:
9818 case SimpleMemoComponent:
9819 {
9820 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
9821 return;
9822 }
9823 case ClassComponent:
9824 {
9825 if (finishedWork.effectTag & Snapshot) {
9826 if (current !== null) {
9827 var prevProps = current.memoizedProps;
9828 var prevState = current.memoizedState;
9829 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
9830 var instance = finishedWork.stateNode;
9831 // We could update instance props and state here,
9832 // but instead we rely on them being set during last render.
9833 // TODO: revisit this when we implement resuming.
9834 {
9835 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9836 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
9837 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
9838 }
9839 }
9840 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
9841 {
9842 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
9843 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
9844 didWarnSet.add(finishedWork.type);
9845 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
9846 }
9847 }
9848 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
9849 stopPhaseTimer();
9850 }
9851 }
9852 return;
9853 }
9854 case HostRoot:
9855 case HostComponent:
9856 case HostText:
9857 case HostPortal:
9858 case IncompleteClassComponent:
9859 // Nothing to do for these component types
9860 return;
9861 default:
9862 {
9863 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
9864 }
9865 }
9866}
9867
9868function commitHookEffectList(unmountTag, mountTag, finishedWork) {
9869 var updateQueue = finishedWork.updateQueue;
9870 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
9871 if (lastEffect !== null) {
9872 var firstEffect = lastEffect.next;
9873 var effect = firstEffect;
9874 do {
9875 if ((effect.tag & unmountTag) !== NoEffect$1) {
9876 // Unmount
9877 var destroy = effect.destroy;
9878 effect.destroy = undefined;
9879 if (destroy !== undefined) {
9880 destroy();
9881 }
9882 }
9883 if ((effect.tag & mountTag) !== NoEffect$1) {
9884 // Mount
9885 var create = effect.create;
9886 effect.destroy = create();
9887
9888 {
9889 var _destroy = effect.destroy;
9890 if (_destroy !== undefined && typeof _destroy !== 'function') {
9891 var addendum = void 0;
9892 if (_destroy === null) {
9893 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
9894 } else if (typeof _destroy.then === 'function') {
9895 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';
9896 } else {
9897 addendum = ' You returned: ' + _destroy;
9898 }
9899 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
9900 }
9901 }
9902 }
9903 effect = effect.next;
9904 } while (effect !== firstEffect);
9905 }
9906}
9907
9908function commitPassiveHookEffects(finishedWork) {
9909 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
9910 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
9911}
9912
9913function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
9914 switch (finishedWork.tag) {
9915 case FunctionComponent:
9916 case ForwardRef:
9917 case SimpleMemoComponent:
9918 {
9919 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
9920 break;
9921 }
9922 case ClassComponent:
9923 {
9924 var instance = finishedWork.stateNode;
9925 if (finishedWork.effectTag & Update) {
9926 if (current === null) {
9927 startPhaseTimer(finishedWork, 'componentDidMount');
9928 // We could update instance props and state here,
9929 // but instead we rely on them being set during last render.
9930 // TODO: revisit this when we implement resuming.
9931 {
9932 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9933 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
9934 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
9935 }
9936 }
9937 instance.componentDidMount();
9938 stopPhaseTimer();
9939 } else {
9940 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
9941 var prevState = current.memoizedState;
9942 startPhaseTimer(finishedWork, 'componentDidUpdate');
9943 // We could update instance props and state here,
9944 // but instead we rely on them being set during last render.
9945 // TODO: revisit this when we implement resuming.
9946 {
9947 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9948 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
9949 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
9950 }
9951 }
9952 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
9953 stopPhaseTimer();
9954 }
9955 }
9956 var updateQueue = finishedWork.updateQueue;
9957 if (updateQueue !== null) {
9958 {
9959 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9960 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
9961 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
9962 }
9963 }
9964 // We could update instance props and state here,
9965 // but instead we rely on them being set during last render.
9966 // TODO: revisit this when we implement resuming.
9967 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
9968 }
9969 return;
9970 }
9971 case HostRoot:
9972 {
9973 var _updateQueue = finishedWork.updateQueue;
9974 if (_updateQueue !== null) {
9975 var _instance = null;
9976 if (finishedWork.child !== null) {
9977 switch (finishedWork.child.tag) {
9978 case HostComponent:
9979 _instance = getPublicInstance(finishedWork.child.stateNode);
9980 break;
9981 case ClassComponent:
9982 _instance = finishedWork.child.stateNode;
9983 break;
9984 }
9985 }
9986 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
9987 }
9988 return;
9989 }
9990 case HostComponent:
9991 {
9992 var _instance2 = finishedWork.stateNode;
9993
9994 // Renderers may schedule work to be done after host components are mounted
9995 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
9996 // These effects should only be committed when components are first mounted,
9997 // aka when there is no current/alternate.
9998 if (current === null && finishedWork.effectTag & Update) {
9999 var type = finishedWork.type;
10000 var props = finishedWork.memoizedProps;
10001
10002 }
10003
10004 return;
10005 }
10006 case HostText:
10007 {
10008 // We have no life-cycles associated with text.
10009 return;
10010 }
10011 case HostPortal:
10012 {
10013 // We have no life-cycles associated with portals.
10014 return;
10015 }
10016 case Profiler:
10017 {
10018 if (enableProfilerTimer) {
10019 var onRender = finishedWork.memoizedProps.onRender;
10020
10021 if (enableSchedulerTracing) {
10022 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
10023 } else {
10024 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
10025 }
10026 }
10027 return;
10028 }
10029 case SuspenseComponent:
10030 break;
10031 case IncompleteClassComponent:
10032 break;
10033 default:
10034 {
10035 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
10036 }
10037 }
10038}
10039
10040function hideOrUnhideAllChildren(finishedWork, isHidden) {
10041 if (supportsMutation) {
10042 // We only have the top Fiber that was inserted but we need to recurse down its
10043 var node = finishedWork;
10044 while (true) {
10045 if (node.tag === HostComponent) {
10046 var instance = node.stateNode;
10047 if (isHidden) {
10048 hideInstance(instance);
10049 } else {
10050 unhideInstance(node.stateNode, node.memoizedProps);
10051 }
10052 } else if (node.tag === HostText) {
10053 var _instance3 = node.stateNode;
10054 if (isHidden) {
10055
10056 } else {
10057 unhideTextInstance(_instance3, node.memoizedProps);
10058 }
10059 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
10060 // Found a nested Suspense component that timed out. Skip over the
10061 var fallbackChildFragment = node.child.sibling;
10062 fallbackChildFragment.return = node;
10063 node = fallbackChildFragment;
10064 continue;
10065 } else if (node.child !== null) {
10066 node.child.return = node;
10067 node = node.child;
10068 continue;
10069 }
10070 if (node === finishedWork) {
10071 return;
10072 }
10073 while (node.sibling === null) {
10074 if (node.return === null || node.return === finishedWork) {
10075 return;
10076 }
10077 node = node.return;
10078 }
10079 node.sibling.return = node.return;
10080 node = node.sibling;
10081 }
10082 }
10083}
10084
10085function commitAttachRef(finishedWork) {
10086 var ref = finishedWork.ref;
10087 if (ref !== null) {
10088 var instance = finishedWork.stateNode;
10089 var instanceToUse = void 0;
10090 switch (finishedWork.tag) {
10091 case HostComponent:
10092 instanceToUse = getPublicInstance(instance);
10093 break;
10094 default:
10095 instanceToUse = instance;
10096 }
10097 if (typeof ref === 'function') {
10098 ref(instanceToUse);
10099 } else {
10100 {
10101 if (!ref.hasOwnProperty('current')) {
10102 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
10103 }
10104 }
10105
10106 ref.current = instanceToUse;
10107 }
10108 }
10109}
10110
10111function commitDetachRef(current) {
10112 var currentRef = current.ref;
10113 if (currentRef !== null) {
10114 if (typeof currentRef === 'function') {
10115 currentRef(null);
10116 } else {
10117 currentRef.current = null;
10118 }
10119 }
10120}
10121
10122// User-originating errors (lifecycles and refs) should not interrupt
10123// deletion, so don't let them throw. Host-originating errors should
10124// interrupt deletion, so it's okay
10125function commitUnmount(current) {
10126 onCommitUnmount(current);
10127
10128 switch (current.tag) {
10129 case FunctionComponent:
10130 case ForwardRef:
10131 case MemoComponent:
10132 case SimpleMemoComponent:
10133 {
10134 var updateQueue = current.updateQueue;
10135 if (updateQueue !== null) {
10136 var lastEffect = updateQueue.lastEffect;
10137 if (lastEffect !== null) {
10138 var firstEffect = lastEffect.next;
10139 var effect = firstEffect;
10140 do {
10141 var destroy = effect.destroy;
10142 if (destroy !== undefined) {
10143 safelyCallDestroy(current, destroy);
10144 }
10145 effect = effect.next;
10146 } while (effect !== firstEffect);
10147 }
10148 }
10149 break;
10150 }
10151 case ClassComponent:
10152 {
10153 safelyDetachRef(current);
10154 var instance = current.stateNode;
10155 if (typeof instance.componentWillUnmount === 'function') {
10156 safelyCallComponentWillUnmount(current, instance);
10157 }
10158 return;
10159 }
10160 case HostComponent:
10161 {
10162 safelyDetachRef(current);
10163 return;
10164 }
10165 case HostPortal:
10166 {
10167 // TODO: this is recursive.
10168 // We are also not using this parent because
10169 // the portal will get pushed immediately.
10170 if (supportsMutation) {
10171 unmountHostComponents(current);
10172 } else if (supportsPersistence) {
10173 emptyPortalContainer(current);
10174 }
10175 return;
10176 }
10177 }
10178}
10179
10180function commitNestedUnmounts(root) {
10181 // While we're inside a removed host node we don't want to call
10182 // removeChild on the inner nodes because they're removed by the top
10183 // call anyway. We also want to call componentWillUnmount on all
10184 // composites before this host node is removed from the tree. Therefore
10185 var node = root;
10186 while (true) {
10187 commitUnmount(node);
10188 // Visit children because they may contain more composite or host nodes.
10189 // Skip portals because commitUnmount() currently visits them recursively.
10190 if (node.child !== null && (
10191 // If we use mutation we drill down into portals using commitUnmount above.
10192 // If we don't use mutation we drill down into portals here instead.
10193 !supportsMutation || node.tag !== HostPortal)) {
10194 node.child.return = node;
10195 node = node.child;
10196 continue;
10197 }
10198 if (node === root) {
10199 return;
10200 }
10201 while (node.sibling === null) {
10202 if (node.return === null || node.return === root) {
10203 return;
10204 }
10205 node = node.return;
10206 }
10207 node.sibling.return = node.return;
10208 node = node.sibling;
10209 }
10210}
10211
10212function detachFiber(current) {
10213 // Cut off the return pointers to disconnect it from the tree. Ideally, we
10214 // should clear the child pointer of the parent alternate to let this
10215 // get GC:ed but we don't know which for sure which parent is the current
10216 // one so we'll settle for GC:ing the subtree of this child. This child
10217 // itself will be GC:ed when the parent updates the next time.
10218 current.return = null;
10219 current.child = null;
10220 current.memoizedState = null;
10221 current.updateQueue = null;
10222 var alternate = current.alternate;
10223 if (alternate !== null) {
10224 alternate.return = null;
10225 alternate.child = null;
10226 alternate.memoizedState = null;
10227 alternate.updateQueue = null;
10228 }
10229}
10230
10231function emptyPortalContainer(current) {
10232 if (!supportsPersistence) {
10233 return;
10234 }
10235
10236 var portal = current.stateNode;
10237 var containerInfo = portal.containerInfo;
10238
10239 var emptyChildSet = createContainerChildSet(containerInfo);
10240 replaceContainerChildren(containerInfo, emptyChildSet);
10241}
10242
10243function commitContainer(finishedWork) {
10244 if (!supportsPersistence) {
10245 return;
10246 }
10247
10248 switch (finishedWork.tag) {
10249 case ClassComponent:
10250 {
10251 return;
10252 }
10253 case HostComponent:
10254 {
10255 return;
10256 }
10257 case HostText:
10258 {
10259 return;
10260 }
10261 case HostRoot:
10262 case HostPortal:
10263 {
10264 var portalOrRoot = finishedWork.stateNode;
10265 var containerInfo = portalOrRoot.containerInfo,
10266 _pendingChildren = portalOrRoot.pendingChildren;
10267
10268 replaceContainerChildren(containerInfo, _pendingChildren);
10269 return;
10270 }
10271 default:
10272 {
10273 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
10274 }
10275 }
10276}
10277
10278function getHostParentFiber(fiber) {
10279 var parent = fiber.return;
10280 while (parent !== null) {
10281 if (isHostParent(parent)) {
10282 return parent;
10283 }
10284 parent = parent.return;
10285 }
10286 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
10287}
10288
10289function isHostParent(fiber) {
10290 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
10291}
10292
10293function getHostSibling(fiber) {
10294 // We're going to search forward into the tree until we find a sibling host
10295 // node. Unfortunately, if multiple insertions are done in a row we have to
10296 // search past them. This leads to exponential search for the next sibling.
10297 var node = fiber;
10298 siblings: while (true) {
10299 // If we didn't find anything, let's try the next sibling.
10300 while (node.sibling === null) {
10301 if (node.return === null || isHostParent(node.return)) {
10302 // If we pop out of the root or hit the parent the fiber we are the
10303 // last sibling.
10304 return null;
10305 }
10306 node = node.return;
10307 }
10308 node.sibling.return = node.return;
10309 node = node.sibling;
10310 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
10311 // If it is not host node and, we might have a host node inside it.
10312 // Try to search down until we find one.
10313 if (node.effectTag & Placement) {
10314 // If we don't have a child, try the siblings instead.
10315 continue siblings;
10316 }
10317 // If we don't have a child, try the siblings instead.
10318 // We also skip portals because they are not part of this host tree.
10319 if (node.child === null || node.tag === HostPortal) {
10320 continue siblings;
10321 } else {
10322 node.child.return = node;
10323 node = node.child;
10324 }
10325 }
10326 // Check if this host node is stable or about to be placed.
10327 if (!(node.effectTag & Placement)) {
10328 // Found it!
10329 return node.stateNode;
10330 }
10331 }
10332}
10333
10334function commitPlacement(finishedWork) {
10335 if (!supportsMutation) {
10336 return;
10337 }
10338
10339 // Recursively insert all host nodes into the parent.
10340 var parentFiber = getHostParentFiber(finishedWork);
10341
10342 // Note: these two variables *must* always be updated together.
10343 var parent = void 0;
10344 var isContainer = void 0;
10345
10346 switch (parentFiber.tag) {
10347 case HostComponent:
10348 parent = parentFiber.stateNode;
10349 isContainer = false;
10350 break;
10351 case HostRoot:
10352 parent = parentFiber.stateNode.containerInfo;
10353 isContainer = true;
10354 break;
10355 case HostPortal:
10356 parent = parentFiber.stateNode.containerInfo;
10357 isContainer = true;
10358 break;
10359 default:
10360 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
10361 }
10362 if (parentFiber.effectTag & ContentReset) {
10363 // Reset the text content of the parent before doing any insertions
10364 parentFiber.effectTag &= ~ContentReset;
10365 }
10366
10367 var before = getHostSibling(finishedWork);
10368 // We only have the top Fiber that was inserted but we need to recurse down its
10369 // children to find all the terminal nodes.
10370 var node = finishedWork;
10371 while (true) {
10372 if (node.tag === HostComponent || node.tag === HostText) {
10373 if (before) {
10374 if (isContainer) {
10375 insertInContainerBefore(parent, node.stateNode, before);
10376 } else {
10377 insertBefore(parent, node.stateNode, before);
10378 }
10379 } else {
10380 if (isContainer) {
10381 appendChildToContainer(parent, node.stateNode);
10382 } else {
10383 appendChild(parent, node.stateNode);
10384 }
10385 }
10386 } else if (node.tag === HostPortal) {
10387 // If the insertion itself is a portal, then we don't want to traverse
10388 // down its children. Instead, we'll get insertions from each child in
10389 // the portal directly.
10390 } else if (node.child !== null) {
10391 node.child.return = node;
10392 node = node.child;
10393 continue;
10394 }
10395 if (node === finishedWork) {
10396 return;
10397 }
10398 while (node.sibling === null) {
10399 if (node.return === null || node.return === finishedWork) {
10400 return;
10401 }
10402 node = node.return;
10403 }
10404 node.sibling.return = node.return;
10405 node = node.sibling;
10406 }
10407}
10408
10409function unmountHostComponents(current) {
10410 // We only have the top Fiber that was deleted but we need to recurse down its
10411 var node = current;
10412
10413 // Each iteration, currentParent is populated with node's host parent if not
10414 // currentParentIsValid.
10415 var currentParentIsValid = false;
10416
10417 // Note: these two variables *must* always be updated together.
10418 var currentParent = void 0;
10419 var currentParentIsContainer = void 0;
10420
10421 while (true) {
10422 if (!currentParentIsValid) {
10423 var parent = node.return;
10424 findParent: while (true) {
10425 !(parent !== null) ? invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10426 switch (parent.tag) {
10427 case HostComponent:
10428 currentParent = parent.stateNode;
10429 currentParentIsContainer = false;
10430 break findParent;
10431 case HostRoot:
10432 currentParent = parent.stateNode.containerInfo;
10433 currentParentIsContainer = true;
10434 break findParent;
10435 case HostPortal:
10436 currentParent = parent.stateNode.containerInfo;
10437 currentParentIsContainer = true;
10438 break findParent;
10439 }
10440 parent = parent.return;
10441 }
10442 currentParentIsValid = true;
10443 }
10444
10445 if (node.tag === HostComponent || node.tag === HostText) {
10446 commitNestedUnmounts(node);
10447 // After all the children have unmounted, it is now safe to remove the
10448 // node from the tree.
10449 if (currentParentIsContainer) {
10450 removeChildFromContainer(currentParent, node.stateNode);
10451 } else {
10452 removeChild(currentParent, node.stateNode);
10453 }
10454 // Don't visit children because we already visited them.
10455 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
10456 // Delete the dehydrated suspense boundary and all of its content.
10457 if (currentParentIsContainer) {
10458 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
10459 } else {
10460 clearSuspenseBoundary(currentParent, node.stateNode);
10461 }
10462 } else if (node.tag === HostPortal) {
10463 if (node.child !== null) {
10464 // When we go into a portal, it becomes the parent to remove from.
10465 // We will reassign it back when we pop the portal on the way up.
10466 currentParent = node.stateNode.containerInfo;
10467 currentParentIsContainer = true;
10468 // Visit children because portals might contain host components.
10469 node.child.return = node;
10470 node = node.child;
10471 continue;
10472 }
10473 } else {
10474 commitUnmount(node);
10475 // Visit children because we may find more host components below.
10476 if (node.child !== null) {
10477 node.child.return = node;
10478 node = node.child;
10479 continue;
10480 }
10481 }
10482 if (node === current) {
10483 return;
10484 }
10485 while (node.sibling === null) {
10486 if (node.return === null || node.return === current) {
10487 return;
10488 }
10489 node = node.return;
10490 if (node.tag === HostPortal) {
10491 // When we go out of the portal, we need to restore the parent.
10492 // Since we don't keep a stack of them, we will search for it.
10493 currentParentIsValid = false;
10494 }
10495 }
10496 node.sibling.return = node.return;
10497 node = node.sibling;
10498 }
10499}
10500
10501function commitDeletion(current) {
10502 if (supportsMutation) {
10503 // Recursively delete all host nodes from the parent.
10504 // Detach refs and call componentWillUnmount() on the whole subtree.
10505 unmountHostComponents(current);
10506 } else {
10507 // Detach refs and call componentWillUnmount() on the whole subtree.
10508 commitNestedUnmounts(current);
10509 }
10510 detachFiber(current);
10511}
10512
10513function commitWork(current, finishedWork) {
10514 if (!supportsMutation) {
10515 switch (finishedWork.tag) {
10516 case FunctionComponent:
10517 case ForwardRef:
10518 case MemoComponent:
10519 case SimpleMemoComponent:
10520 {
10521 // Note: We currently never use MountMutation, but useLayout uses
10522 // UnmountMutation.
10523 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10524 return;
10525 }
10526 }
10527
10528 commitContainer(finishedWork);
10529 return;
10530 }
10531
10532 switch (finishedWork.tag) {
10533 case FunctionComponent:
10534 case ForwardRef:
10535 case MemoComponent:
10536 case SimpleMemoComponent:
10537 {
10538 // Note: We currently never use MountMutation, but useLayout uses
10539 // UnmountMutation.
10540 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10541 return;
10542 }
10543 case ClassComponent:
10544 {
10545 return;
10546 }
10547 case HostComponent:
10548 {
10549 var instance = finishedWork.stateNode;
10550 if (instance != null) {
10551 // Commit the work prepared earlier.
10552 var newProps = finishedWork.memoizedProps;
10553 // For hydration we reuse the update path but we treat the oldProps
10554 // as the newProps. The updatePayload will contain the real change in
10555 // this case.
10556 var oldProps = current !== null ? current.memoizedProps : newProps;
10557 var type = finishedWork.type;
10558 // TODO: Type the updateQueue to be specific to host components.
10559 var updatePayload = finishedWork.updateQueue;
10560 finishedWork.updateQueue = null;
10561 if (updatePayload !== null) {
10562 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
10563 }
10564 }
10565 return;
10566 }
10567 case HostText:
10568 {
10569 !(finishedWork.stateNode !== null) ? invariant(false, 'This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.') : void 0;
10570 var textInstance = finishedWork.stateNode;
10571 var newText = finishedWork.memoizedProps;
10572 // For hydration we reuse the update path but we treat the oldProps
10573 // as the newProps. The updatePayload will contain the real change in
10574 // this case.
10575 var oldText = current !== null ? current.memoizedProps : newText;
10576 return;
10577 }
10578 case HostRoot:
10579 {
10580 return;
10581 }
10582 case Profiler:
10583 {
10584 return;
10585 }
10586 case SuspenseComponent:
10587 {
10588 var newState = finishedWork.memoizedState;
10589
10590 var newDidTimeout = void 0;
10591 var primaryChildParent = finishedWork;
10592 if (newState === null) {
10593 newDidTimeout = false;
10594 } else {
10595 newDidTimeout = true;
10596 primaryChildParent = finishedWork.child;
10597 if (newState.timedOutAt === NoWork) {
10598 // If the children had not already timed out, record the time.
10599 // This is used to compute the elapsed time during subsequent
10600 // attempts to render the children.
10601 newState.timedOutAt = requestCurrentTime();
10602 }
10603 }
10604
10605 if (primaryChildParent !== null) {
10606 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
10607 }
10608
10609 // If this boundary just timed out, then it will have a set of thenables.
10610 // For each thenable, attach a listener so that when it resolves, React
10611 // attempts to re-render the boundary in the primary (pre-timeout) state.
10612 var thenables = finishedWork.updateQueue;
10613 if (thenables !== null) {
10614 finishedWork.updateQueue = null;
10615 var retryCache = finishedWork.stateNode;
10616 if (retryCache === null) {
10617 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
10618 }
10619 thenables.forEach(function (thenable) {
10620 // Memoize using the boundary fiber to prevent redundant listeners.
10621 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
10622 if (enableSchedulerTracing) {
10623 retry = unstable_wrap(retry);
10624 }
10625 if (!retryCache.has(thenable)) {
10626 retryCache.add(thenable);
10627 thenable.then(retry, retry);
10628 }
10629 });
10630 }
10631
10632 return;
10633 }
10634 case IncompleteClassComponent:
10635 {
10636 return;
10637 }
10638 default:
10639 {
10640 invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.');
10641 }
10642 }
10643}
10644
10645function commitResetTextContent(current) {
10646 if (!supportsMutation) {
10647 return;
10648 }
10649 resetTextContent(current.stateNode);
10650}
10651
10652var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
10653var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
10654
10655function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
10656 var update = createUpdate(expirationTime);
10657 // Unmount the root by rendering null.
10658 update.tag = CaptureUpdate;
10659 // Caution: React DevTools currently depends on this property
10660 // being called "element".
10661 update.payload = { element: null };
10662 var error = errorInfo.value;
10663 update.callback = function () {
10664 onUncaughtError(error);
10665 logError(fiber, errorInfo);
10666 };
10667 return update;
10668}
10669
10670function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
10671 var update = createUpdate(expirationTime);
10672 update.tag = CaptureUpdate;
10673 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
10674 if (typeof getDerivedStateFromError === 'function') {
10675 var error = errorInfo.value;
10676 update.payload = function () {
10677 return getDerivedStateFromError(error);
10678 };
10679 }
10680
10681 var inst = fiber.stateNode;
10682 if (inst !== null && typeof inst.componentDidCatch === 'function') {
10683 update.callback = function callback() {
10684 if (typeof getDerivedStateFromError !== 'function') {
10685 // To preserve the preexisting retry behavior of error boundaries,
10686 // we keep track of which ones already failed during this batch.
10687 // This gets reset before we yield back to the browser.
10688 // TODO: Warn in strict mode if getDerivedStateFromError is
10689 // not defined.
10690 markLegacyErrorBoundaryAsFailed(this);
10691 }
10692 var error = errorInfo.value;
10693 var stack = errorInfo.stack;
10694 logError(fiber, errorInfo);
10695 this.componentDidCatch(error, {
10696 componentStack: stack !== null ? stack : ''
10697 });
10698 {
10699 if (typeof getDerivedStateFromError !== 'function') {
10700 // If componentDidCatch is the only error boundary method defined,
10701 // then it needs to call setState to recover from errors.
10702 // If no state update is scheduled then the boundary will swallow the error.
10703 !(fiber.expirationTime === Sync) ? warningWithoutStack$1(false, '%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown') : void 0;
10704 }
10705 }
10706 };
10707 }
10708 return update;
10709}
10710
10711function attachPingListener(root, renderExpirationTime, thenable) {
10712 // Attach a listener to the promise to "ping" the root and retry. But
10713 // only if one does not already exist for the current render expiration
10714 // time (which acts like a "thread ID" here).
10715 var pingCache = root.pingCache;
10716 var threadIDs = void 0;
10717 if (pingCache === null) {
10718 pingCache = root.pingCache = new PossiblyWeakMap();
10719 threadIDs = new Set();
10720 pingCache.set(thenable, threadIDs);
10721 } else {
10722 threadIDs = pingCache.get(thenable);
10723 if (threadIDs === undefined) {
10724 threadIDs = new Set();
10725 pingCache.set(thenable, threadIDs);
10726 }
10727 }
10728 if (!threadIDs.has(renderExpirationTime)) {
10729 // Memoize using the thread ID to prevent redundant listeners.
10730 threadIDs.add(renderExpirationTime);
10731 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
10732 if (enableSchedulerTracing) {
10733 ping = unstable_wrap(ping);
10734 }
10735 thenable.then(ping, ping);
10736 }
10737}
10738
10739function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
10740 // The source fiber did not complete.
10741 sourceFiber.effectTag |= Incomplete;
10742 // Its effect list is no longer valid.
10743 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
10744
10745 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
10746 // This is a thenable.
10747 var thenable = value;
10748
10749 // Find the earliest timeout threshold of all the placeholders in the
10750 // ancestor path. We could avoid this traversal by storing the thresholds on
10751 // the stack, but we choose not to because we only hit this path if we're
10752 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
10753 // the non-IO- bound case.
10754 var _workInProgress = returnFiber;
10755 var earliestTimeoutMs = -1;
10756 var startTimeMs = -1;
10757 do {
10758 if (_workInProgress.tag === SuspenseComponent) {
10759 var current = _workInProgress.alternate;
10760 if (current !== null) {
10761 var currentState = current.memoizedState;
10762 if (currentState !== null) {
10763 // Reached a boundary that already timed out. Do not search
10764 // any further.
10765 var timedOutAt = currentState.timedOutAt;
10766 startTimeMs = expirationTimeToMs(timedOutAt);
10767 // Do not search any further.
10768 break;
10769 }
10770 }
10771 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
10772 if (typeof timeoutPropMs === 'number') {
10773 if (timeoutPropMs <= 0) {
10774 earliestTimeoutMs = 0;
10775 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
10776 earliestTimeoutMs = timeoutPropMs;
10777 }
10778 }
10779 }
10780 // If there is a DehydratedSuspenseComponent we don't have to do anything because
10781 // if something suspends inside it, we will simply leave that as dehydrated. It
10782 // will never timeout.
10783 _workInProgress = _workInProgress.return;
10784 } while (_workInProgress !== null);
10785
10786 // Schedule the nearest Suspense to re-render the timed out view.
10787 _workInProgress = returnFiber;
10788 do {
10789 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
10790 // Found the nearest boundary.
10791
10792 // Stash the promise on the boundary fiber. If the boundary times out, we'll
10793 var thenables = _workInProgress.updateQueue;
10794 if (thenables === null) {
10795 var updateQueue = new Set();
10796 updateQueue.add(thenable);
10797 _workInProgress.updateQueue = updateQueue;
10798 } else {
10799 thenables.add(thenable);
10800 }
10801
10802 // If the boundary is outside of concurrent mode, we should *not*
10803 // suspend the commit. Pretend as if the suspended component rendered
10804 // null and keep rendering. In the commit phase, we'll schedule a
10805 // subsequent synchronous update to re-render the Suspense.
10806 //
10807 // Note: It doesn't matter whether the component that suspended was
10808 // inside a concurrent mode tree. If the Suspense is outside of it, we
10809 // should *not* suspend the commit.
10810 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
10811 _workInProgress.effectTag |= DidCapture;
10812
10813 // We're going to commit this fiber even though it didn't complete.
10814 // But we shouldn't call any lifecycle methods or callbacks. Remove
10815 // all lifecycle effect tags.
10816 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
10817
10818 if (sourceFiber.tag === ClassComponent) {
10819 var currentSourceFiber = sourceFiber.alternate;
10820 if (currentSourceFiber === null) {
10821 // This is a new mount. Change the tag so it's not mistaken for a
10822 // completed class component. For example, we should not call
10823 // componentWillUnmount if it is deleted.
10824 sourceFiber.tag = IncompleteClassComponent;
10825 } else {
10826 // When we try rendering again, we should not reuse the current fiber,
10827 // since it's known to be in an inconsistent state. Use a force updte to
10828 // prevent a bail out.
10829 var update = createUpdate(Sync);
10830 update.tag = ForceUpdate;
10831 enqueueUpdate(sourceFiber, update);
10832 }
10833 }
10834
10835 // The source fiber did not complete. Mark it with Sync priority to
10836 // indicate that it still has pending work.
10837 sourceFiber.expirationTime = Sync;
10838
10839 // Exit without suspending.
10840 return;
10841 }
10842
10843 // Confirmed that the boundary is in a concurrent mode tree. Continue
10844 // with the normal suspend path.
10845
10846 attachPingListener(root, renderExpirationTime, thenable);
10847
10848 var absoluteTimeoutMs = void 0;
10849 if (earliestTimeoutMs === -1) {
10850 // If no explicit threshold is given, default to an arbitrarily large
10851 // value. The actual size doesn't matter because the threshold for the
10852 // whole tree will be clamped to the expiration time.
10853 absoluteTimeoutMs = maxSigned31BitInt;
10854 } else {
10855 if (startTimeMs === -1) {
10856 // This suspend happened outside of any already timed-out
10857 // placeholders. We don't know exactly when the update was
10858 // scheduled, but we can infer an approximate start time from the
10859 // expiration time. First, find the earliest uncommitted expiration
10860 // time in the tree, including work that is suspended. Then subtract
10861 // the offset used to compute an async update's expiration time.
10862 // This will cause high priority (interactive) work to expire
10863 // earlier than necessary, but we can account for this by adjusting
10864 // for the Just Noticeable Difference.
10865 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
10866 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
10867 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
10868 }
10869 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
10870 }
10871
10872 // Mark the earliest timeout in the suspended fiber's ancestor path.
10873 // After completing the root, we'll take the largest of all the
10874 // suspended fiber's timeouts and use it to compute a timeout for the
10875 // whole tree.
10876 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
10877
10878 _workInProgress.effectTag |= ShouldCapture;
10879 _workInProgress.expirationTime = renderExpirationTime;
10880 return;
10881 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
10882 attachPingListener(root, renderExpirationTime, thenable);
10883
10884 // Since we already have a current fiber, we can eagerly add a retry listener.
10885 var retryCache = _workInProgress.memoizedState;
10886 if (retryCache === null) {
10887 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
10888 var _current = _workInProgress.alternate;
10889 !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
10890 _current.memoizedState = retryCache;
10891 }
10892 // Memoize using the boundary fiber to prevent redundant listeners.
10893 if (!retryCache.has(thenable)) {
10894 retryCache.add(thenable);
10895 var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
10896 if (enableSchedulerTracing) {
10897 retry = unstable_wrap(retry);
10898 }
10899 thenable.then(retry, retry);
10900 }
10901 _workInProgress.effectTag |= ShouldCapture;
10902 _workInProgress.expirationTime = renderExpirationTime;
10903 return;
10904 }
10905 // This boundary already captured during this render. Continue to the next
10906 // boundary.
10907 _workInProgress = _workInProgress.return;
10908 } while (_workInProgress !== null);
10909 // No boundary was found. Fallthrough to error mode.
10910 // TODO: Use invariant so the message is stripped in prod?
10911 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));
10912 }
10913
10914 // We didn't find a boundary that could handle this type of exception. Start
10915 // over and traverse parent path again, this time treating the exception
10916 // as an error.
10917 renderDidError();
10918 value = createCapturedValue(value, sourceFiber);
10919 var workInProgress = returnFiber;
10920 do {
10921 switch (workInProgress.tag) {
10922 case HostRoot:
10923 {
10924 var _errorInfo = value;
10925 workInProgress.effectTag |= ShouldCapture;
10926 workInProgress.expirationTime = renderExpirationTime;
10927 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
10928 enqueueCapturedUpdate(workInProgress, _update);
10929 return;
10930 }
10931 case ClassComponent:
10932 // Capture and retry
10933 var errorInfo = value;
10934 var ctor = workInProgress.type;
10935 var instance = workInProgress.stateNode;
10936 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
10937 workInProgress.effectTag |= ShouldCapture;
10938 workInProgress.expirationTime = renderExpirationTime;
10939 // Schedule the error boundary to re-render using updated state
10940 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
10941 enqueueCapturedUpdate(workInProgress, _update2);
10942 return;
10943 }
10944 break;
10945 default:
10946 break;
10947 }
10948 workInProgress = workInProgress.return;
10949 } while (workInProgress !== null);
10950}
10951
10952function unwindWork(workInProgress, renderExpirationTime) {
10953 switch (workInProgress.tag) {
10954 case ClassComponent:
10955 {
10956 var Component = workInProgress.type;
10957 if (isContextProvider(Component)) {
10958 popContext(workInProgress);
10959 }
10960 var effectTag = workInProgress.effectTag;
10961 if (effectTag & ShouldCapture) {
10962 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10963 return workInProgress;
10964 }
10965 return null;
10966 }
10967 case HostRoot:
10968 {
10969 popHostContainer(workInProgress);
10970 popTopLevelContextObject(workInProgress);
10971 var _effectTag = workInProgress.effectTag;
10972 !((_effectTag & DidCapture) === NoEffect) ? invariant(false, 'The root failed to unmount after an error. This is likely a bug in React. Please file an issue.') : void 0;
10973 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10974 return workInProgress;
10975 }
10976 case HostComponent:
10977 {
10978 // TODO: popHydrationState
10979 popHostContext(workInProgress);
10980 return null;
10981 }
10982 case SuspenseComponent:
10983 {
10984 var _effectTag2 = workInProgress.effectTag;
10985 if (_effectTag2 & ShouldCapture) {
10986 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
10987 // Captured a suspense effect. Re-render the boundary.
10988 return workInProgress;
10989 }
10990 return null;
10991 }
10992 case DehydratedSuspenseComponent:
10993 {
10994 if (enableSuspenseServerRenderer) {
10995 // TODO: popHydrationState
10996 var _effectTag3 = workInProgress.effectTag;
10997 if (_effectTag3 & ShouldCapture) {
10998 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
10999 // Captured a suspense effect. Re-render the boundary.
11000 return workInProgress;
11001 }
11002 }
11003 return null;
11004 }
11005 case HostPortal:
11006 popHostContainer(workInProgress);
11007 return null;
11008 case ContextProvider:
11009 popProvider(workInProgress);
11010 return null;
11011 default:
11012 return null;
11013 }
11014}
11015
11016function unwindInterruptedWork(interruptedWork) {
11017 switch (interruptedWork.tag) {
11018 case ClassComponent:
11019 {
11020 var childContextTypes = interruptedWork.type.childContextTypes;
11021 if (childContextTypes !== null && childContextTypes !== undefined) {
11022 popContext(interruptedWork);
11023 }
11024 break;
11025 }
11026 case HostRoot:
11027 {
11028 popHostContainer(interruptedWork);
11029 popTopLevelContextObject(interruptedWork);
11030 break;
11031 }
11032 case HostComponent:
11033 {
11034 popHostContext(interruptedWork);
11035 break;
11036 }
11037 case HostPortal:
11038 popHostContainer(interruptedWork);
11039 break;
11040 case ContextProvider:
11041 popProvider(interruptedWork);
11042 break;
11043 default:
11044 break;
11045 }
11046}
11047
11048var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
11049var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
11050
11051
11052var didWarnAboutStateTransition = void 0;
11053var didWarnSetStateChildContext = void 0;
11054var warnAboutUpdateOnUnmounted = void 0;
11055var warnAboutInvalidUpdates = void 0;
11056
11057if (enableSchedulerTracing) {
11058 // Provide explicit error message when production+profiling bundle of e.g. react-dom
11059 // is used with production (non-profiling) bundle of scheduler/tracing
11060 !(__interactionsRef != null && __interactionsRef.current != null) ? invariant(false, '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') : void 0;
11061}
11062
11063{
11064 didWarnAboutStateTransition = false;
11065 didWarnSetStateChildContext = false;
11066 var didWarnStateUpdateForUnmountedComponent = {};
11067
11068 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
11069 // We show the whole stack but dedupe on the top component's name because
11070 // the problematic code almost always lies inside that component.
11071 var componentName = getComponentName(fiber.type) || 'ReactComponent';
11072 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
11073 return;
11074 }
11075 warningWithoutStack$1(false, "Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', isClass ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
11076 didWarnStateUpdateForUnmountedComponent[componentName] = true;
11077 };
11078
11079 warnAboutInvalidUpdates = function (instance) {
11080 switch (phase) {
11081 case 'getChildContext':
11082 if (didWarnSetStateChildContext) {
11083 return;
11084 }
11085 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
11086 didWarnSetStateChildContext = true;
11087 break;
11088 case 'render':
11089 if (didWarnAboutStateTransition) {
11090 return;
11091 }
11092 warningWithoutStack$1(false, 'Cannot update during an existing state transition (such as within ' + '`render`). Render methods should be a pure function of props and state.');
11093 didWarnAboutStateTransition = true;
11094 break;
11095 }
11096 };
11097}
11098
11099var isWorking = false;
11100
11101// The next work in progress fiber that we're currently working on.
11102var nextUnitOfWork = null;
11103var nextRoot = null;
11104// The time at which we're currently rendering work.
11105var nextRenderExpirationTime = NoWork;
11106var nextLatestAbsoluteTimeoutMs = -1;
11107var nextRenderDidError = false;
11108
11109// The next fiber with an effect that we're currently committing.
11110var nextEffect = null;
11111
11112var isCommitting$1 = false;
11113var rootWithPendingPassiveEffects = null;
11114var passiveEffectCallbackHandle = null;
11115var passiveEffectCallback = null;
11116
11117var legacyErrorBoundariesThatAlreadyFailed = null;
11118
11119// Used for performance tracking.
11120var interruptedBy = null;
11121
11122var stashedWorkInProgressProperties = void 0;
11123var replayUnitOfWork = void 0;
11124var mayReplayFailedUnitOfWork = void 0;
11125var isReplayingFailedUnitOfWork = void 0;
11126var originalReplayError = void 0;
11127var rethrowOriginalError = void 0;
11128if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11129 stashedWorkInProgressProperties = null;
11130 mayReplayFailedUnitOfWork = true;
11131 isReplayingFailedUnitOfWork = false;
11132 originalReplayError = null;
11133 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
11134 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
11135 // Don't replay promises. Treat everything else like an error.
11136 // TODO: Need to figure out a different strategy if/when we add
11137 // support for catching other types.
11138 return;
11139 }
11140
11141 // Restore the original state of the work-in-progress
11142 if (stashedWorkInProgressProperties === null) {
11143 // This should never happen. Don't throw because this code is DEV-only.
11144 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
11145 return;
11146 }
11147 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
11148
11149 switch (failedUnitOfWork.tag) {
11150 case HostRoot:
11151 popHostContainer(failedUnitOfWork);
11152 popTopLevelContextObject(failedUnitOfWork);
11153 break;
11154 case HostComponent:
11155 popHostContext(failedUnitOfWork);
11156 break;
11157 case ClassComponent:
11158 {
11159 var Component = failedUnitOfWork.type;
11160 if (isContextProvider(Component)) {
11161 popContext(failedUnitOfWork);
11162 }
11163 break;
11164 }
11165 case HostPortal:
11166 popHostContainer(failedUnitOfWork);
11167 break;
11168 case ContextProvider:
11169 popProvider(failedUnitOfWork);
11170 break;
11171 }
11172 // Replay the begin phase.
11173 isReplayingFailedUnitOfWork = true;
11174 originalReplayError = thrownValue;
11175 invokeGuardedCallback(null, workLoop, null, isYieldy);
11176 isReplayingFailedUnitOfWork = false;
11177 originalReplayError = null;
11178 if (hasCaughtError()) {
11179 var replayError = clearCaughtError();
11180 if (replayError != null && thrownValue != null) {
11181 try {
11182 // Reading the expando property is intentionally
11183 // inside `try` because it might be a getter or Proxy.
11184 if (replayError._suppressLogging) {
11185 // Also suppress logging for the original error.
11186 thrownValue._suppressLogging = true;
11187 }
11188 } catch (inner) {
11189 // Ignore.
11190 }
11191 }
11192 } else {
11193 // If the begin phase did not fail the second time, set this pointer
11194 // back to the original value.
11195 nextUnitOfWork = failedUnitOfWork;
11196 }
11197 };
11198 rethrowOriginalError = function () {
11199 throw originalReplayError;
11200 };
11201}
11202
11203function resetStack() {
11204 if (nextUnitOfWork !== null) {
11205 var interruptedWork = nextUnitOfWork.return;
11206 while (interruptedWork !== null) {
11207 unwindInterruptedWork(interruptedWork);
11208 interruptedWork = interruptedWork.return;
11209 }
11210 }
11211
11212 {
11213 ReactStrictModeWarnings.discardPendingWarnings();
11214 checkThatStackIsEmpty();
11215 }
11216
11217 nextRoot = null;
11218 nextRenderExpirationTime = NoWork;
11219 nextLatestAbsoluteTimeoutMs = -1;
11220 nextRenderDidError = false;
11221 nextUnitOfWork = null;
11222}
11223
11224function commitAllHostEffects() {
11225 while (nextEffect !== null) {
11226 {
11227 setCurrentFiber(nextEffect);
11228 }
11229 recordEffect();
11230
11231 var effectTag = nextEffect.effectTag;
11232
11233 if (effectTag & ContentReset) {
11234 commitResetTextContent(nextEffect);
11235 }
11236
11237 if (effectTag & Ref) {
11238 var current = nextEffect.alternate;
11239 if (current !== null) {
11240 commitDetachRef(current);
11241 }
11242 }
11243
11244 // The following switch statement is only concerned about placement,
11245 // updates, and deletions. To avoid needing to add a case for every
11246 // possible bitmap value, we remove the secondary effects from the
11247 // effect tag and switch on that value.
11248 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
11249 switch (primaryEffectTag) {
11250 case Placement:
11251 {
11252 commitPlacement(nextEffect);
11253 // Clear the "placement" from effect tag so that we know that this is inserted, before
11254 // any life-cycles like componentDidMount gets called.
11255 // TODO: findDOMNode doesn't rely on this any more but isMounted
11256 // does and isMounted is deprecated anyway so we should be able
11257 // to kill this.
11258 nextEffect.effectTag &= ~Placement;
11259 break;
11260 }
11261 case PlacementAndUpdate:
11262 {
11263 // Placement
11264 commitPlacement(nextEffect);
11265 // Clear the "placement" from effect tag so that we know that this is inserted, before
11266 // any life-cycles like componentDidMount gets called.
11267 nextEffect.effectTag &= ~Placement;
11268
11269 // Update
11270 var _current = nextEffect.alternate;
11271 commitWork(_current, nextEffect);
11272 break;
11273 }
11274 case Update:
11275 {
11276 var _current2 = nextEffect.alternate;
11277 commitWork(_current2, nextEffect);
11278 break;
11279 }
11280 case Deletion:
11281 {
11282 commitDeletion(nextEffect);
11283 break;
11284 }
11285 }
11286 nextEffect = nextEffect.nextEffect;
11287 }
11288
11289 {
11290 resetCurrentFiber();
11291 }
11292}
11293
11294function commitBeforeMutationLifecycles() {
11295 while (nextEffect !== null) {
11296 {
11297 setCurrentFiber(nextEffect);
11298 }
11299
11300 var effectTag = nextEffect.effectTag;
11301 if (effectTag & Snapshot) {
11302 recordEffect();
11303 var current = nextEffect.alternate;
11304 commitBeforeMutationLifeCycles(current, nextEffect);
11305 }
11306
11307 nextEffect = nextEffect.nextEffect;
11308 }
11309
11310 {
11311 resetCurrentFiber();
11312 }
11313}
11314
11315function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
11316 {
11317 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
11318 ReactStrictModeWarnings.flushLegacyContextWarning();
11319
11320 if (warnAboutDeprecatedLifecycles) {
11321 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
11322 }
11323 }
11324 while (nextEffect !== null) {
11325 {
11326 setCurrentFiber(nextEffect);
11327 }
11328 var effectTag = nextEffect.effectTag;
11329
11330 if (effectTag & (Update | Callback)) {
11331 recordEffect();
11332 var current = nextEffect.alternate;
11333 commitLifeCycles(finishedRoot, current, nextEffect, committedExpirationTime);
11334 }
11335
11336 if (effectTag & Ref) {
11337 recordEffect();
11338 commitAttachRef(nextEffect);
11339 }
11340
11341 if (effectTag & Passive) {
11342 rootWithPendingPassiveEffects = finishedRoot;
11343 }
11344
11345 nextEffect = nextEffect.nextEffect;
11346 }
11347 {
11348 resetCurrentFiber();
11349 }
11350}
11351
11352function commitPassiveEffects(root, firstEffect) {
11353 rootWithPendingPassiveEffects = null;
11354 passiveEffectCallbackHandle = null;
11355 passiveEffectCallback = null;
11356
11357 // Set this to true to prevent re-entrancy
11358 var previousIsRendering = isRendering;
11359 isRendering = true;
11360
11361 var effect = firstEffect;
11362 do {
11363 {
11364 setCurrentFiber(effect);
11365 }
11366
11367 if (effect.effectTag & Passive) {
11368 var didError = false;
11369 var error = void 0;
11370 {
11371 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
11372 if (hasCaughtError()) {
11373 didError = true;
11374 error = clearCaughtError();
11375 }
11376 }
11377 if (didError) {
11378 captureCommitPhaseError(effect, error);
11379 }
11380 }
11381 effect = effect.nextEffect;
11382 } while (effect !== null);
11383 {
11384 resetCurrentFiber();
11385 }
11386
11387 isRendering = previousIsRendering;
11388
11389 // Check if work was scheduled by one of the effects
11390 var rootExpirationTime = root.expirationTime;
11391 if (rootExpirationTime !== NoWork) {
11392 requestWork(root, rootExpirationTime);
11393 }
11394 // Flush any sync work that was scheduled by effects
11395 if (!isBatchingUpdates && !isRendering) {
11396 performSyncWork();
11397 }
11398}
11399
11400function isAlreadyFailedLegacyErrorBoundary(instance) {
11401 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
11402}
11403
11404function markLegacyErrorBoundaryAsFailed(instance) {
11405 if (legacyErrorBoundariesThatAlreadyFailed === null) {
11406 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
11407 } else {
11408 legacyErrorBoundariesThatAlreadyFailed.add(instance);
11409 }
11410}
11411
11412function flushPassiveEffects() {
11413 if (passiveEffectCallbackHandle !== null) {
11414 cancelPassiveEffects(passiveEffectCallbackHandle);
11415 }
11416 if (passiveEffectCallback !== null) {
11417 // We call the scheduled callback instead of commitPassiveEffects directly
11418 // to ensure tracing works correctly.
11419 passiveEffectCallback();
11420 }
11421}
11422
11423function commitRoot(root, finishedWork) {
11424 isWorking = true;
11425 isCommitting$1 = true;
11426 startCommitTimer();
11427
11428 !(root.current !== finishedWork) ? invariant(false, 'Cannot commit the same tree as before. This is probably a bug related to the return field. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11429 var committedExpirationTime = root.pendingCommitExpirationTime;
11430 !(committedExpirationTime !== NoWork) ? invariant(false, 'Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11431 root.pendingCommitExpirationTime = NoWork;
11432
11433 // Update the pending priority levels to account for the work that we are
11434 // about to commit. This needs to happen before calling the lifecycles, since
11435 // they may schedule additional updates.
11436 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
11437 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
11438 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
11439 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
11440
11441 var prevInteractions = null;
11442 if (enableSchedulerTracing) {
11443 // Restore any pending interactions at this point,
11444 // So that cascading work triggered during the render phase will be accounted for.
11445 prevInteractions = __interactionsRef.current;
11446 __interactionsRef.current = root.memoizedInteractions;
11447 }
11448
11449 // Reset this to null before calling lifecycles
11450 ReactCurrentOwner$1.current = null;
11451
11452 var firstEffect = void 0;
11453 if (finishedWork.effectTag > PerformedWork) {
11454 // A fiber's effect list consists only of its children, not itself. So if
11455 // the root has an effect, we need to add it to the end of the list. The
11456 // resulting list is the set that would belong to the root's parent, if
11457 // it had one; that is, all the effects in the tree including the root.
11458 if (finishedWork.lastEffect !== null) {
11459 finishedWork.lastEffect.nextEffect = finishedWork;
11460 firstEffect = finishedWork.firstEffect;
11461 } else {
11462 firstEffect = finishedWork;
11463 }
11464 } else {
11465 // There is no effect on the root.
11466 firstEffect = finishedWork.firstEffect;
11467 }
11468
11469 prepareForCommit(root.containerInfo);
11470
11471 // Invoke instances of getSnapshotBeforeUpdate before mutation.
11472 nextEffect = firstEffect;
11473 startCommitSnapshotEffectsTimer();
11474 while (nextEffect !== null) {
11475 var didError = false;
11476 var error = void 0;
11477 {
11478 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
11479 if (hasCaughtError()) {
11480 didError = true;
11481 error = clearCaughtError();
11482 }
11483 }
11484 if (didError) {
11485 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11486 captureCommitPhaseError(nextEffect, error);
11487 // Clean-up
11488 if (nextEffect !== null) {
11489 nextEffect = nextEffect.nextEffect;
11490 }
11491 }
11492 }
11493 stopCommitSnapshotEffectsTimer();
11494
11495 if (enableProfilerTimer) {
11496 // Mark the current commit time to be shared by all Profilers in this batch.
11497 // This enables them to be grouped later.
11498 recordCommitTime();
11499 }
11500
11501 // Commit all the side-effects within a tree. We'll do this in two passes.
11502 // The first pass performs all the host insertions, updates, deletions and
11503 // ref unmounts.
11504 nextEffect = firstEffect;
11505 startCommitHostEffectsTimer();
11506 while (nextEffect !== null) {
11507 var _didError = false;
11508 var _error = void 0;
11509 {
11510 invokeGuardedCallback(null, commitAllHostEffects, null);
11511 if (hasCaughtError()) {
11512 _didError = true;
11513 _error = clearCaughtError();
11514 }
11515 }
11516 if (_didError) {
11517 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11518 captureCommitPhaseError(nextEffect, _error);
11519 // Clean-up
11520 if (nextEffect !== null) {
11521 nextEffect = nextEffect.nextEffect;
11522 }
11523 }
11524 }
11525 stopCommitHostEffectsTimer();
11526
11527 resetAfterCommit(root.containerInfo);
11528
11529 // The work-in-progress tree is now the current tree. This must come after
11530 // the first pass of the commit phase, so that the previous tree is still
11531 // current during componentWillUnmount, but before the second pass, so that
11532 // the finished work is current during componentDidMount/Update.
11533 root.current = finishedWork;
11534
11535 // In the second pass we'll perform all life-cycles and ref callbacks.
11536 // Life-cycles happen as a separate pass so that all placements, updates,
11537 // and deletions in the entire tree have already been invoked.
11538 // This pass also triggers any renderer-specific initial effects.
11539 nextEffect = firstEffect;
11540 startCommitLifeCyclesTimer();
11541 while (nextEffect !== null) {
11542 var _didError2 = false;
11543 var _error2 = void 0;
11544 {
11545 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
11546 if (hasCaughtError()) {
11547 _didError2 = true;
11548 _error2 = clearCaughtError();
11549 }
11550 }
11551 if (_didError2) {
11552 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11553 captureCommitPhaseError(nextEffect, _error2);
11554 if (nextEffect !== null) {
11555 nextEffect = nextEffect.nextEffect;
11556 }
11557 }
11558 }
11559
11560 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
11561 // This commit included a passive effect. These do not need to fire until
11562 // after the next paint. Schedule an callback to fire them in an async
11563 // event. To ensure serial execution, the callback will be flushed early if
11564 // we enter rootWithPendingPassiveEffects commit phase before then.
11565 var callback = commitPassiveEffects.bind(null, root, firstEffect);
11566 if (enableSchedulerTracing) {
11567 // TODO: Avoid this extra callback by mutating the tracing ref directly,
11568 // like we do at the beginning of commitRoot. I've opted not to do that
11569 // here because that code is still in flux.
11570 callback = unstable_wrap(callback);
11571 }
11572 passiveEffectCallbackHandle = unstable_runWithPriority(unstable_NormalPriority, function () {
11573 return schedulePassiveEffects(callback);
11574 });
11575 passiveEffectCallback = callback;
11576 }
11577
11578 isCommitting$1 = false;
11579 isWorking = false;
11580 stopCommitLifeCyclesTimer();
11581 stopCommitTimer();
11582 onCommitRoot(finishedWork.stateNode);
11583 if (true && ReactFiberInstrumentation_1.debugTool) {
11584 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
11585 }
11586
11587 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
11588 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
11589 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
11590 if (earliestRemainingTimeAfterCommit === NoWork) {
11591 // If there's no remaining work, we can clear the set of already failed
11592 // error boundaries.
11593 legacyErrorBoundariesThatAlreadyFailed = null;
11594 }
11595 onCommit(root, earliestRemainingTimeAfterCommit);
11596
11597 if (enableSchedulerTracing) {
11598 __interactionsRef.current = prevInteractions;
11599
11600 var subscriber = void 0;
11601
11602 try {
11603 subscriber = __subscriberRef.current;
11604 if (subscriber !== null && root.memoizedInteractions.size > 0) {
11605 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
11606 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
11607 }
11608 } catch (error) {
11609 // It's not safe for commitRoot() to throw.
11610 // Store the error for now and we'll re-throw in finishRendering().
11611 if (!hasUnhandledError) {
11612 hasUnhandledError = true;
11613 unhandledError = error;
11614 }
11615 } finally {
11616 // Clear completed interactions from the pending Map.
11617 // Unless the render was suspended or cascading work was scheduled,
11618 // In which case– leave pending interactions until the subsequent render.
11619 var pendingInteractionMap = root.pendingInteractionMap;
11620 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11621 // Only decrement the pending interaction count if we're done.
11622 // If there's still work at the current priority,
11623 // That indicates that we are waiting for suspense data.
11624 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
11625 pendingInteractionMap.delete(scheduledExpirationTime);
11626
11627 scheduledInteractions.forEach(function (interaction) {
11628 interaction.__count--;
11629
11630 if (subscriber !== null && interaction.__count === 0) {
11631 try {
11632 subscriber.onInteractionScheduledWorkCompleted(interaction);
11633 } catch (error) {
11634 // It's not safe for commitRoot() to throw.
11635 // Store the error for now and we'll re-throw in finishRendering().
11636 if (!hasUnhandledError) {
11637 hasUnhandledError = true;
11638 unhandledError = error;
11639 }
11640 }
11641 }
11642 });
11643 }
11644 });
11645 }
11646 }
11647}
11648
11649function resetChildExpirationTime(workInProgress, renderTime) {
11650 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
11651 // The children of this component are hidden. Don't bubble their
11652 // expiration times.
11653 return;
11654 }
11655
11656 var newChildExpirationTime = NoWork;
11657
11658 // Bubble up the earliest expiration time.
11659 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11660 // We're in profiling mode.
11661 // Let's use this same traversal to update the render durations.
11662 var actualDuration = workInProgress.actualDuration;
11663 var treeBaseDuration = workInProgress.selfBaseDuration;
11664
11665 // When a fiber is cloned, its actualDuration is reset to 0.
11666 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
11667 // When work is done, it should bubble to the parent's actualDuration.
11668 // If the fiber has not been cloned though, (meaning no work was done),
11669 // Then this value will reflect the amount of time spent working on a previous render.
11670 // In that case it should not bubble.
11671 // We determine whether it was cloned by comparing the child pointer.
11672 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
11673
11674 var child = workInProgress.child;
11675 while (child !== null) {
11676 var childUpdateExpirationTime = child.expirationTime;
11677 var childChildExpirationTime = child.childExpirationTime;
11678 if (childUpdateExpirationTime > newChildExpirationTime) {
11679 newChildExpirationTime = childUpdateExpirationTime;
11680 }
11681 if (childChildExpirationTime > newChildExpirationTime) {
11682 newChildExpirationTime = childChildExpirationTime;
11683 }
11684 if (shouldBubbleActualDurations) {
11685 actualDuration += child.actualDuration;
11686 }
11687 treeBaseDuration += child.treeBaseDuration;
11688 child = child.sibling;
11689 }
11690 workInProgress.actualDuration = actualDuration;
11691 workInProgress.treeBaseDuration = treeBaseDuration;
11692 } else {
11693 var _child = workInProgress.child;
11694 while (_child !== null) {
11695 var _childUpdateExpirationTime = _child.expirationTime;
11696 var _childChildExpirationTime = _child.childExpirationTime;
11697 if (_childUpdateExpirationTime > newChildExpirationTime) {
11698 newChildExpirationTime = _childUpdateExpirationTime;
11699 }
11700 if (_childChildExpirationTime > newChildExpirationTime) {
11701 newChildExpirationTime = _childChildExpirationTime;
11702 }
11703 _child = _child.sibling;
11704 }
11705 }
11706
11707 workInProgress.childExpirationTime = newChildExpirationTime;
11708}
11709
11710function completeUnitOfWork(workInProgress) {
11711 // Attempt to complete the current unit of work, then move to the
11712 // next sibling. If there are no more siblings, return to the
11713 // parent fiber.
11714 while (true) {
11715 // The current, flushed, state of this fiber is the alternate.
11716 // Ideally nothing should rely on this, but relying on it here
11717 // means that we don't need an additional field on the work in
11718 // progress.
11719 var current = workInProgress.alternate;
11720 {
11721 setCurrentFiber(workInProgress);
11722 }
11723
11724 var returnFiber = workInProgress.return;
11725 var siblingFiber = workInProgress.sibling;
11726
11727 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
11728 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11729 // Don't replay if it fails during completion phase.
11730 mayReplayFailedUnitOfWork = false;
11731 }
11732 // This fiber completed.
11733 // Remember we're completing this unit so we can find a boundary if it fails.
11734 nextUnitOfWork = workInProgress;
11735 if (enableProfilerTimer) {
11736 if (workInProgress.mode & ProfileMode) {
11737 startProfilerTimer(workInProgress);
11738 }
11739 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11740 if (workInProgress.mode & ProfileMode) {
11741 // Update render duration assuming we didn't error.
11742 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11743 }
11744 } else {
11745 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11746 }
11747 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11748 // We're out of completion phase so replaying is fine now.
11749 mayReplayFailedUnitOfWork = true;
11750 }
11751 stopWorkTimer(workInProgress);
11752 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
11753 {
11754 resetCurrentFiber();
11755 }
11756
11757 if (nextUnitOfWork !== null) {
11758 // Completing this fiber spawned new work. Work on that next.
11759 return nextUnitOfWork;
11760 }
11761
11762 if (returnFiber !== null &&
11763 // Do not append effects to parents if a sibling failed to complete
11764 (returnFiber.effectTag & Incomplete) === NoEffect) {
11765 // Append all the effects of the subtree and this fiber onto the effect
11766 // list of the parent. The completion order of the children affects the
11767 // side-effect order.
11768 if (returnFiber.firstEffect === null) {
11769 returnFiber.firstEffect = workInProgress.firstEffect;
11770 }
11771 if (workInProgress.lastEffect !== null) {
11772 if (returnFiber.lastEffect !== null) {
11773 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
11774 }
11775 returnFiber.lastEffect = workInProgress.lastEffect;
11776 }
11777
11778 // If this fiber had side-effects, we append it AFTER the children's
11779 // side-effects. We can perform certain side-effects earlier if
11780 // needed, by doing multiple passes over the effect list. We don't want
11781 // to schedule our own side-effect on our own list because if end up
11782 // reusing children we'll schedule this effect onto itself since we're
11783 // at the end.
11784 var effectTag = workInProgress.effectTag;
11785 // Skip both NoWork and PerformedWork tags when creating the effect list.
11786 // PerformedWork effect is read by React DevTools but shouldn't be committed.
11787 if (effectTag > PerformedWork) {
11788 if (returnFiber.lastEffect !== null) {
11789 returnFiber.lastEffect.nextEffect = workInProgress;
11790 } else {
11791 returnFiber.firstEffect = workInProgress;
11792 }
11793 returnFiber.lastEffect = workInProgress;
11794 }
11795 }
11796
11797 if (true && ReactFiberInstrumentation_1.debugTool) {
11798 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11799 }
11800
11801 if (siblingFiber !== null) {
11802 // If there is more work to do in this returnFiber, do that next.
11803 return siblingFiber;
11804 } else if (returnFiber !== null) {
11805 // If there's no more work in this returnFiber. Complete the returnFiber.
11806 workInProgress = returnFiber;
11807 continue;
11808 } else {
11809 // We've reached the root.
11810 return null;
11811 }
11812 } else {
11813 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11814 // Record the render duration for the fiber that errored.
11815 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11816
11817 // Include the time spent working on failed children before continuing.
11818 var actualDuration = workInProgress.actualDuration;
11819 var child = workInProgress.child;
11820 while (child !== null) {
11821 actualDuration += child.actualDuration;
11822 child = child.sibling;
11823 }
11824 workInProgress.actualDuration = actualDuration;
11825 }
11826
11827 // This fiber did not complete because something threw. Pop values off
11828 // the stack without entering the complete phase. If this is a boundary,
11829 // capture values if possible.
11830 var next = unwindWork(workInProgress, nextRenderExpirationTime);
11831 // Because this fiber did not complete, don't reset its expiration time.
11832 if (workInProgress.effectTag & DidCapture) {
11833 // Restarting an error boundary
11834 stopFailedWorkTimer(workInProgress);
11835 } else {
11836 stopWorkTimer(workInProgress);
11837 }
11838
11839 {
11840 resetCurrentFiber();
11841 }
11842
11843 if (next !== null) {
11844 stopWorkTimer(workInProgress);
11845 if (true && ReactFiberInstrumentation_1.debugTool) {
11846 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11847 }
11848
11849 // If completing this work spawned new work, do that next. We'll come
11850 // back here again.
11851 // Since we're restarting, remove anything that is not a host effect
11852 // from the effect tag.
11853 next.effectTag &= HostEffectMask;
11854 return next;
11855 }
11856
11857 if (returnFiber !== null) {
11858 // Mark the parent fiber as incomplete and clear its effect list.
11859 returnFiber.firstEffect = returnFiber.lastEffect = null;
11860 returnFiber.effectTag |= Incomplete;
11861 }
11862
11863 if (true && ReactFiberInstrumentation_1.debugTool) {
11864 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11865 }
11866
11867 if (siblingFiber !== null) {
11868 // If there is more work to do in this returnFiber, do that next.
11869 return siblingFiber;
11870 } else if (returnFiber !== null) {
11871 // If there's no more work in this returnFiber. Complete the returnFiber.
11872 workInProgress = returnFiber;
11873 continue;
11874 } else {
11875 return null;
11876 }
11877 }
11878 }
11879
11880 // Without this explicit null return Flow complains of invalid return type
11881 // TODO Remove the above while(true) loop
11882 // eslint-disable-next-line no-unreachable
11883 return null;
11884}
11885
11886function performUnitOfWork(workInProgress) {
11887 // The current, flushed, state of this fiber is the alternate.
11888 // Ideally nothing should rely on this, but relying on it here
11889 // means that we don't need an additional field on the work in
11890 // progress.
11891 var current = workInProgress.alternate;
11892
11893 // See if beginning this work spawns more work.
11894 startWorkTimer(workInProgress);
11895 {
11896 setCurrentFiber(workInProgress);
11897 }
11898
11899 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11900 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
11901 }
11902
11903 var next = void 0;
11904 if (enableProfilerTimer) {
11905 if (workInProgress.mode & ProfileMode) {
11906 startProfilerTimer(workInProgress);
11907 }
11908
11909 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11910 workInProgress.memoizedProps = workInProgress.pendingProps;
11911
11912 if (workInProgress.mode & ProfileMode) {
11913 // Record the render duration assuming we didn't bailout (or error).
11914 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
11915 }
11916 } else {
11917 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11918 workInProgress.memoizedProps = workInProgress.pendingProps;
11919 }
11920
11921 {
11922 resetCurrentFiber();
11923 if (isReplayingFailedUnitOfWork) {
11924 // Currently replaying a failed unit of work. This should be unreachable,
11925 // because the render phase is meant to be idempotent, and it should
11926 // have thrown again. Since it didn't, rethrow the original error, so
11927 // React's internal stack is not misaligned.
11928 rethrowOriginalError();
11929 }
11930 }
11931 if (true && ReactFiberInstrumentation_1.debugTool) {
11932 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
11933 }
11934
11935 if (next === null) {
11936 // If this doesn't spawn new work, complete the current work.
11937 next = completeUnitOfWork(workInProgress);
11938 }
11939
11940 ReactCurrentOwner$1.current = null;
11941
11942 return next;
11943}
11944
11945function workLoop(isYieldy) {
11946 if (!isYieldy) {
11947 // Flush work without yielding
11948 while (nextUnitOfWork !== null) {
11949 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11950 }
11951 } else {
11952 // Flush asynchronous work until there's a higher priority event
11953 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
11954 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11955 }
11956 }
11957}
11958
11959function renderRoot(root, isYieldy) {
11960 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11961
11962 flushPassiveEffects();
11963
11964 isWorking = true;
11965 var previousDispatcher = ReactCurrentDispatcher.current;
11966 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
11967
11968 var expirationTime = root.nextExpirationTimeToWorkOn;
11969
11970 // Check if we're starting from a fresh stack, or if we're resuming from
11971 // previously yielded work.
11972 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
11973 // Reset the stack and start working from the root.
11974 resetStack();
11975 nextRoot = root;
11976 nextRenderExpirationTime = expirationTime;
11977 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
11978 root.pendingCommitExpirationTime = NoWork;
11979
11980 if (enableSchedulerTracing) {
11981 // Determine which interactions this batch of work currently includes,
11982 // So that we can accurately attribute time spent working on it,
11983 var interactions = new Set();
11984 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11985 if (scheduledExpirationTime >= expirationTime) {
11986 scheduledInteractions.forEach(function (interaction) {
11987 return interactions.add(interaction);
11988 });
11989 }
11990 });
11991
11992 // Store the current set of interactions on the FiberRoot for a few reasons:
11993 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
11994 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
11995 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
11996 root.memoizedInteractions = interactions;
11997
11998 if (interactions.size > 0) {
11999 var subscriber = __subscriberRef.current;
12000 if (subscriber !== null) {
12001 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
12002 try {
12003 subscriber.onWorkStarted(interactions, threadID);
12004 } catch (error) {
12005 // Work thrown by an interaction tracing subscriber should be rethrown,
12006 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
12007 // Store the error for now and we'll re-throw in finishRendering().
12008 if (!hasUnhandledError) {
12009 hasUnhandledError = true;
12010 unhandledError = error;
12011 }
12012 }
12013 }
12014 }
12015 }
12016 }
12017
12018 var prevInteractions = null;
12019 if (enableSchedulerTracing) {
12020 // We're about to start new traced work.
12021 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
12022 prevInteractions = __interactionsRef.current;
12023 __interactionsRef.current = root.memoizedInteractions;
12024 }
12025
12026 var didFatal = false;
12027
12028 startWorkLoopTimer(nextUnitOfWork);
12029
12030 do {
12031 try {
12032 workLoop(isYieldy);
12033 } catch (thrownValue) {
12034 resetContextDependences();
12035 resetHooks();
12036
12037 // Reset in case completion throws.
12038 // This is only used in DEV and when replaying is on.
12039 var mayReplay = void 0;
12040 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
12041 mayReplay = mayReplayFailedUnitOfWork;
12042 mayReplayFailedUnitOfWork = true;
12043 }
12044
12045 if (nextUnitOfWork === null) {
12046 // This is a fatal error.
12047 didFatal = true;
12048 onUncaughtError(thrownValue);
12049 } else {
12050 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
12051 // Record the time spent rendering before an error was thrown.
12052 // This avoids inaccurate Profiler durations in the case of a suspended render.
12053 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
12054 }
12055
12056 {
12057 // Reset global debug state
12058 // We assume this is defined in DEV
12059 resetCurrentlyProcessingQueue();
12060 }
12061
12062 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
12063 if (mayReplay) {
12064 var failedUnitOfWork = nextUnitOfWork;
12065 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
12066 }
12067 }
12068
12069 // TODO: we already know this isn't true in some cases.
12070 // At least this shows a nicer error message until we figure out the cause.
12071 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
12072 !(nextUnitOfWork !== null) ? invariant(false, 'Failed to replay rendering after an error. This is likely caused by a bug in React. Please file an issue with a reproducing case to help us find it.') : void 0;
12073
12074 var sourceFiber = nextUnitOfWork;
12075 var returnFiber = sourceFiber.return;
12076 if (returnFiber === null) {
12077 // This is the root. The root could capture its own errors. However,
12078 // we don't know if it errors before or after we pushed the host
12079 // context. This information is needed to avoid a stack mismatch.
12080 // Because we're not sure, treat this as a fatal error. We could track
12081 // which phase it fails in, but doesn't seem worth it. At least
12082 // for now.
12083 didFatal = true;
12084 onUncaughtError(thrownValue);
12085 } else {
12086 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
12087 nextUnitOfWork = completeUnitOfWork(sourceFiber);
12088 continue;
12089 }
12090 }
12091 }
12092 break;
12093 } while (true);
12094
12095 if (enableSchedulerTracing) {
12096 // Traced work is done for now; restore the previous interactions.
12097 __interactionsRef.current = prevInteractions;
12098 }
12099
12100 // We're done performing work. Time to clean up.
12101 isWorking = false;
12102 ReactCurrentDispatcher.current = previousDispatcher;
12103 resetContextDependences();
12104 resetHooks();
12105
12106 // Yield back to main thread.
12107 if (didFatal) {
12108 var _didCompleteRoot = false;
12109 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
12110 interruptedBy = null;
12111 // There was a fatal error.
12112 {
12113 resetStackAfterFatalErrorInDev();
12114 }
12115 // `nextRoot` points to the in-progress root. A non-null value indicates
12116 // that we're in the middle of an async render. Set it to null to indicate
12117 // there's no more work to be done in the current batch.
12118 nextRoot = null;
12119 onFatal(root);
12120 return;
12121 }
12122
12123 if (nextUnitOfWork !== null) {
12124 // There's still remaining async work in this tree, but we ran out of time
12125 // in the current frame. Yield back to the renderer. Unless we're
12126 // interrupted by a higher priority update, we'll continue later from where
12127 // we left off.
12128 var _didCompleteRoot2 = false;
12129 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
12130 interruptedBy = null;
12131 onYield(root);
12132 return;
12133 }
12134
12135 // We completed the whole tree.
12136 var didCompleteRoot = true;
12137 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
12138 var rootWorkInProgress = root.current.alternate;
12139 !(rootWorkInProgress !== null) ? invariant(false, 'Finished root should have a work-in-progress. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12140
12141 // `nextRoot` points to the in-progress root. A non-null value indicates
12142 // that we're in the middle of an async render. Set it to null to indicate
12143 // there's no more work to be done in the current batch.
12144 nextRoot = null;
12145 interruptedBy = null;
12146
12147 if (nextRenderDidError) {
12148 // There was an error
12149 if (hasLowerPriorityWork(root, expirationTime)) {
12150 // There's lower priority work. If so, it may have the effect of fixing
12151 // the exception that was just thrown. Exit without committing. This is
12152 // similar to a suspend, but without a timeout because we're not waiting
12153 // for a promise to resolve. React will restart at the lower
12154 // priority level.
12155 markSuspendedPriorityLevel(root, expirationTime);
12156 var suspendedExpirationTime = expirationTime;
12157 var rootExpirationTime = root.expirationTime;
12158 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
12159 );
12160 return;
12161 } else if (
12162 // There's no lower priority work, but we're rendering asynchronously.
12163 // Synchronously attempt to render the same level one more time. This is
12164 // similar to a suspend, but without a timeout because we're not waiting
12165 // for a promise to resolve.
12166 !root.didError && isYieldy) {
12167 root.didError = true;
12168 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
12169 var _rootExpirationTime = root.expirationTime = Sync;
12170 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
12171 );
12172 return;
12173 }
12174 }
12175
12176 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
12177 // The tree was suspended.
12178 var _suspendedExpirationTime2 = expirationTime;
12179 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
12180
12181 // Find the earliest uncommitted expiration time in the tree, including
12182 // work that is suspended. The timeout threshold cannot be longer than
12183 // the overall expiration.
12184 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
12185 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
12186 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
12187 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
12188 }
12189
12190 // Subtract the current time from the absolute timeout to get the number
12191 // of milliseconds until the timeout. In other words, convert an absolute
12192 // timestamp to a relative time. This is the value that is passed
12193 // to `setTimeout`.
12194 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
12195 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
12196 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
12197
12198 // TODO: Account for the Just Noticeable Difference
12199
12200 var _rootExpirationTime2 = root.expirationTime;
12201 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
12202 return;
12203 }
12204
12205 // Ready to commit.
12206 onComplete(root, rootWorkInProgress, expirationTime);
12207}
12208
12209function captureCommitPhaseError(sourceFiber, value) {
12210 var expirationTime = Sync;
12211 var fiber = sourceFiber.return;
12212 while (fiber !== null) {
12213 switch (fiber.tag) {
12214 case ClassComponent:
12215 var ctor = fiber.type;
12216 var instance = fiber.stateNode;
12217 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
12218 var errorInfo = createCapturedValue(value, sourceFiber);
12219 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
12220 enqueueUpdate(fiber, update);
12221 scheduleWork(fiber, expirationTime);
12222 return;
12223 }
12224 break;
12225 case HostRoot:
12226 {
12227 var _errorInfo = createCapturedValue(value, sourceFiber);
12228 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
12229 enqueueUpdate(fiber, _update);
12230 scheduleWork(fiber, expirationTime);
12231 return;
12232 }
12233 }
12234 fiber = fiber.return;
12235 }
12236
12237 if (sourceFiber.tag === HostRoot) {
12238 // Error was thrown at the root. There is no parent, so the root
12239 // itself should capture it.
12240 var rootFiber = sourceFiber;
12241 var _errorInfo2 = createCapturedValue(value, rootFiber);
12242 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
12243 enqueueUpdate(rootFiber, _update2);
12244 scheduleWork(rootFiber, expirationTime);
12245 }
12246}
12247
12248function computeThreadID(expirationTime, interactionThreadID) {
12249 // Interaction threads are unique per root and expiration time.
12250 return expirationTime * 1000 + interactionThreadID;
12251}
12252
12253function computeExpirationForFiber(currentTime, fiber) {
12254 var priorityLevel = unstable_getCurrentPriorityLevel();
12255
12256 var expirationTime = void 0;
12257 if ((fiber.mode & ConcurrentMode) === NoContext) {
12258 // Outside of concurrent mode, updates are always synchronous.
12259 expirationTime = Sync;
12260 } else if (isWorking && !isCommitting$1) {
12261 // During render phase, updates expire during as the current render.
12262 expirationTime = nextRenderExpirationTime;
12263 } else {
12264 switch (priorityLevel) {
12265 case unstable_ImmediatePriority:
12266 expirationTime = Sync;
12267 break;
12268 case unstable_UserBlockingPriority:
12269 expirationTime = computeInteractiveExpiration(currentTime);
12270 break;
12271 case unstable_NormalPriority:
12272 // This is a normal, concurrent update
12273 expirationTime = computeAsyncExpiration(currentTime);
12274 break;
12275 case unstable_LowPriority:
12276 case unstable_IdlePriority:
12277 expirationTime = Never;
12278 break;
12279 default:
12280 invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
12281 }
12282
12283 // If we're in the middle of rendering a tree, do not update at the same
12284 // expiration time that is already rendering.
12285 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
12286 expirationTime -= 1;
12287 }
12288 }
12289
12290 // Keep track of the lowest pending interactive expiration time. This
12291 // allows us to synchronously flush all interactive updates
12292 // when needed.
12293 // TODO: Move this to renderer?
12294 return expirationTime;
12295}
12296
12297function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
12298 // Schedule the timeout.
12299 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
12300 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
12301 }
12302}
12303
12304function renderDidError() {
12305 nextRenderDidError = true;
12306}
12307
12308function pingSuspendedRoot(root, thenable, pingTime) {
12309 // A promise that previously suspended React from committing has resolved.
12310 // If React is still suspended, try again at the previous level (pingTime).
12311
12312 var pingCache = root.pingCache;
12313 if (pingCache !== null) {
12314 // The thenable resolved, so we no longer need to memoize, because it will
12315 // never be thrown again.
12316 pingCache.delete(thenable);
12317 }
12318
12319 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
12320 // Received a ping at the same priority level at which we're currently
12321 // rendering. Restart from the root.
12322 nextRoot = null;
12323 } else {
12324 // Confirm that the root is still suspended at this level. Otherwise exit.
12325 if (isPriorityLevelSuspended(root, pingTime)) {
12326 // Ping at the original level
12327 markPingedPriorityLevel(root, pingTime);
12328 var rootExpirationTime = root.expirationTime;
12329 if (rootExpirationTime !== NoWork) {
12330 requestWork(root, rootExpirationTime);
12331 }
12332 }
12333 }
12334}
12335
12336function retryTimedOutBoundary(boundaryFiber, thenable) {
12337 // The boundary fiber (a Suspense component) previously timed out and was
12338 // rendered in its fallback state. One of the promises that suspended it has
12339 // resolved, which means at least part of the tree was likely unblocked. Try
12340 var retryCache = void 0;
12341 if (enableSuspenseServerRenderer) {
12342 switch (boundaryFiber.tag) {
12343 case SuspenseComponent:
12344 retryCache = boundaryFiber.stateNode;
12345 break;
12346 case DehydratedSuspenseComponent:
12347 retryCache = boundaryFiber.memoizedState;
12348 break;
12349 default:
12350 invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
12351 }
12352 } else {
12353 retryCache = boundaryFiber.stateNode;
12354 }
12355 if (retryCache !== null) {
12356 // The thenable resolved, so we no longer need to memoize, because it will
12357 // never be thrown again.
12358 retryCache.delete(thenable);
12359 }
12360
12361 var currentTime = requestCurrentTime();
12362 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
12363 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
12364 if (root !== null) {
12365 markPendingPriorityLevel(root, retryTime);
12366 var rootExpirationTime = root.expirationTime;
12367 if (rootExpirationTime !== NoWork) {
12368 requestWork(root, rootExpirationTime);
12369 }
12370 }
12371}
12372
12373function scheduleWorkToRoot(fiber, expirationTime) {
12374 recordScheduleUpdate();
12375
12376 {
12377 if (fiber.tag === ClassComponent) {
12378 var instance = fiber.stateNode;
12379 warnAboutInvalidUpdates(instance);
12380 }
12381 }
12382
12383 // Update the source fiber's expiration time
12384 if (fiber.expirationTime < expirationTime) {
12385 fiber.expirationTime = expirationTime;
12386 }
12387 var alternate = fiber.alternate;
12388 if (alternate !== null && alternate.expirationTime < expirationTime) {
12389 alternate.expirationTime = expirationTime;
12390 }
12391 // Walk the parent path to the root and update the child expiration time.
12392 var node = fiber.return;
12393 var root = null;
12394 if (node === null && fiber.tag === HostRoot) {
12395 root = fiber.stateNode;
12396 } else {
12397 while (node !== null) {
12398 alternate = node.alternate;
12399 if (node.childExpirationTime < expirationTime) {
12400 node.childExpirationTime = expirationTime;
12401 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12402 alternate.childExpirationTime = expirationTime;
12403 }
12404 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12405 alternate.childExpirationTime = expirationTime;
12406 }
12407 if (node.return === null && node.tag === HostRoot) {
12408 root = node.stateNode;
12409 break;
12410 }
12411 node = node.return;
12412 }
12413 }
12414
12415 if (enableSchedulerTracing) {
12416 if (root !== null) {
12417 var interactions = __interactionsRef.current;
12418 if (interactions.size > 0) {
12419 var pendingInteractionMap = root.pendingInteractionMap;
12420 var pendingInteractions = pendingInteractionMap.get(expirationTime);
12421 if (pendingInteractions != null) {
12422 interactions.forEach(function (interaction) {
12423 if (!pendingInteractions.has(interaction)) {
12424 // Update the pending async work count for previously unscheduled interaction.
12425 interaction.__count++;
12426 }
12427
12428 pendingInteractions.add(interaction);
12429 });
12430 } else {
12431 pendingInteractionMap.set(expirationTime, new Set(interactions));
12432
12433 // Update the pending async work count for the current interactions.
12434 interactions.forEach(function (interaction) {
12435 interaction.__count++;
12436 });
12437 }
12438
12439 var subscriber = __subscriberRef.current;
12440 if (subscriber !== null) {
12441 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
12442 subscriber.onWorkScheduled(interactions, threadID);
12443 }
12444 }
12445 }
12446 }
12447 return root;
12448}
12449
12450function warnIfNotCurrentlyBatchingInDev(fiber) {
12451 {
12452 if (isRendering === false && isBatchingUpdates === false) {
12453 warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see in the browser." + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
12454 }
12455 }
12456}
12457
12458function scheduleWork(fiber, expirationTime) {
12459 var root = scheduleWorkToRoot(fiber, expirationTime);
12460 if (root === null) {
12461 {
12462 switch (fiber.tag) {
12463 case ClassComponent:
12464 warnAboutUpdateOnUnmounted(fiber, true);
12465 break;
12466 case FunctionComponent:
12467 case ForwardRef:
12468 case MemoComponent:
12469 case SimpleMemoComponent:
12470 warnAboutUpdateOnUnmounted(fiber, false);
12471 break;
12472 }
12473 }
12474 return;
12475 }
12476
12477 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
12478 // This is an interruption. (Used for performance tracking.)
12479 interruptedBy = fiber;
12480 resetStack();
12481 }
12482 markPendingPriorityLevel(root, expirationTime);
12483 if (
12484 // If we're in the render phase, we don't need to schedule this root
12485 // for an update, because we'll do it before we exit...
12486 !isWorking || isCommitting$1 ||
12487 // ...unless this is a different root than the one we're rendering.
12488 nextRoot !== root) {
12489 var rootExpirationTime = root.expirationTime;
12490 requestWork(root, rootExpirationTime);
12491 }
12492 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
12493 // Reset this back to zero so subsequent updates don't throw.
12494 nestedUpdateCount = 0;
12495 invariant(false, '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.');
12496 }
12497}
12498
12499// TODO: Everything below this is written as if it has been lifted to the
12500// renderers. I'll do this in a follow-up.
12501
12502// Linked-list of roots
12503var firstScheduledRoot = null;
12504var lastScheduledRoot = null;
12505
12506var callbackExpirationTime = NoWork;
12507var callbackID = void 0;
12508var isRendering = false;
12509var nextFlushedRoot = null;
12510var nextFlushedExpirationTime = NoWork;
12511var hasUnhandledError = false;
12512var unhandledError = null;
12513
12514var isBatchingUpdates = false;
12515var isUnbatchingUpdates = false;
12516
12517var completedBatches = null;
12518
12519var originalStartTimeMs = unstable_now();
12520var currentRendererTime = msToExpirationTime(originalStartTimeMs);
12521var currentSchedulerTime = currentRendererTime;
12522
12523// Use these to prevent an infinite loop of nested updates
12524var NESTED_UPDATE_LIMIT = 50;
12525var nestedUpdateCount = 0;
12526var lastCommittedRootDuringThisBatch = null;
12527
12528function recomputeCurrentRendererTime() {
12529 var currentTimeMs = unstable_now() - originalStartTimeMs;
12530 currentRendererTime = msToExpirationTime(currentTimeMs);
12531}
12532
12533function scheduleCallbackWithExpirationTime(root, expirationTime) {
12534 if (callbackExpirationTime !== NoWork) {
12535 // A callback is already scheduled. Check its expiration time (timeout).
12536 if (expirationTime < callbackExpirationTime) {
12537 // Existing callback has sufficient timeout. Exit.
12538 return;
12539 } else {
12540 if (callbackID !== null) {
12541 // Existing callback has insufficient timeout. Cancel and schedule a
12542 // new one.
12543 unstable_cancelCallback(callbackID);
12544 }
12545 }
12546 // The request callback timer is already running. Don't start a new one.
12547 } else {
12548 startRequestCallbackTimer();
12549 }
12550
12551 callbackExpirationTime = expirationTime;
12552 var currentMs = unstable_now() - originalStartTimeMs;
12553 var expirationTimeMs = expirationTimeToMs(expirationTime);
12554 var timeout = expirationTimeMs - currentMs;
12555 callbackID = unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
12556}
12557
12558// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
12559// onYield is called upon exiting. We use these in lieu of returning a tuple.
12560// I've also chosen not to inline them into renderRoot because these will
12561// eventually be lifted into the renderer.
12562function onFatal(root) {
12563 root.finishedWork = null;
12564}
12565
12566function onComplete(root, finishedWork, expirationTime) {
12567 root.pendingCommitExpirationTime = expirationTime;
12568 root.finishedWork = finishedWork;
12569}
12570
12571function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
12572 root.expirationTime = rootExpirationTime;
12573 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
12574 // Don't wait an additional tick. Commit the tree immediately.
12575 root.pendingCommitExpirationTime = suspendedExpirationTime;
12576 root.finishedWork = finishedWork;
12577 } else if (msUntilTimeout > 0) {
12578 // Wait `msUntilTimeout` milliseconds before committing.
12579 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
12580 }
12581}
12582
12583function onYield(root) {
12584 root.finishedWork = null;
12585}
12586
12587function onTimeout(root, finishedWork, suspendedExpirationTime) {
12588 // The root timed out. Commit it.
12589 root.pendingCommitExpirationTime = suspendedExpirationTime;
12590 root.finishedWork = finishedWork;
12591 // Read the current time before entering the commit phase. We can be
12592 // certain this won't cause tearing related to batching of event updates
12593 // because we're at the top of a timer event.
12594 recomputeCurrentRendererTime();
12595 currentSchedulerTime = currentRendererTime;
12596 flushRoot(root, suspendedExpirationTime);
12597}
12598
12599function onCommit(root, expirationTime) {
12600 root.expirationTime = expirationTime;
12601 root.finishedWork = null;
12602}
12603
12604function requestCurrentTime() {
12605 // requestCurrentTime is called by the scheduler to compute an expiration
12606 // time.
12607 //
12608 // Expiration times are computed by adding to the current time (the start
12609 // time). However, if two updates are scheduled within the same event, we
12610 // should treat their start times as simultaneous, even if the actual clock
12611 // time has advanced between the first and second call.
12612
12613 // In other words, because expiration times determine how updates are batched,
12614 // we want all updates of like priority that occur within the same event to
12615 // receive the same expiration time. Otherwise we get tearing.
12616 //
12617 // We keep track of two separate times: the current "renderer" time and the
12618 // current "scheduler" time. The renderer time can be updated whenever; it
12619 // only exists to minimize the calls performance.now.
12620 //
12621 // But the scheduler time can only be updated if there's no pending work, or
12622 // if we know for certain that we're not in the middle of an event.
12623
12624 if (isRendering) {
12625 // We're already rendering. Return the most recently read time.
12626 return currentSchedulerTime;
12627 }
12628 // Check if there's pending work.
12629 findHighestPriorityRoot();
12630 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
12631 // If there's no pending work, or if the pending work is offscreen, we can
12632 // read the current time without risk of tearing.
12633 recomputeCurrentRendererTime();
12634 currentSchedulerTime = currentRendererTime;
12635 return currentSchedulerTime;
12636 }
12637 // There's already pending work. We might be in the middle of a browser
12638 // event. If we were to read the current time, it could cause multiple updates
12639 // within the same event to receive different expiration times, leading to
12640 // tearing. Return the last read time. During the next idle callback, the
12641 // time will be updated.
12642 return currentSchedulerTime;
12643}
12644
12645// requestWork is called by the scheduler whenever a root receives an update.
12646// It's up to the renderer to call renderRoot at some point in the future.
12647function requestWork(root, expirationTime) {
12648 addRootToSchedule(root, expirationTime);
12649 if (isRendering) {
12650 // Prevent reentrancy. Remaining work will be scheduled at the end of
12651 // the currently rendering batch.
12652 return;
12653 }
12654
12655 if (isBatchingUpdates) {
12656 // Flush work at the end of the batch.
12657 if (isUnbatchingUpdates) {
12658 // ...unless we're inside unbatchedUpdates, in which case we should
12659 // flush it now.
12660 nextFlushedRoot = root;
12661 nextFlushedExpirationTime = Sync;
12662 performWorkOnRoot(root, Sync, false);
12663 }
12664 return;
12665 }
12666
12667 // TODO: Get rid of Sync and use current time?
12668 if (expirationTime === Sync) {
12669 performSyncWork();
12670 } else {
12671 scheduleCallbackWithExpirationTime(root, expirationTime);
12672 }
12673}
12674
12675function addRootToSchedule(root, expirationTime) {
12676 // Add the root to the schedule.
12677 // Check if this root is already part of the schedule.
12678 if (root.nextScheduledRoot === null) {
12679 // This root is not already scheduled. Add it.
12680 root.expirationTime = expirationTime;
12681 if (lastScheduledRoot === null) {
12682 firstScheduledRoot = lastScheduledRoot = root;
12683 root.nextScheduledRoot = root;
12684 } else {
12685 lastScheduledRoot.nextScheduledRoot = root;
12686 lastScheduledRoot = root;
12687 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12688 }
12689 } else {
12690 // This root is already scheduled, but its priority may have increased.
12691 var remainingExpirationTime = root.expirationTime;
12692 if (expirationTime > remainingExpirationTime) {
12693 // Update the priority.
12694 root.expirationTime = expirationTime;
12695 }
12696 }
12697}
12698
12699function findHighestPriorityRoot() {
12700 var highestPriorityWork = NoWork;
12701 var highestPriorityRoot = null;
12702 if (lastScheduledRoot !== null) {
12703 var previousScheduledRoot = lastScheduledRoot;
12704 var root = firstScheduledRoot;
12705 while (root !== null) {
12706 var remainingExpirationTime = root.expirationTime;
12707 if (remainingExpirationTime === NoWork) {
12708 // This root no longer has work. Remove it from the scheduler.
12709
12710 // TODO: This check is redudant, but Flow is confused by the branch
12711 // below where we set lastScheduledRoot to null, even though we break
12712 // from the loop right after.
12713 !(previousScheduledRoot !== null && lastScheduledRoot !== null) ? invariant(false, 'Should have a previous and last root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12714 if (root === root.nextScheduledRoot) {
12715 // This is the only root in the list.
12716 root.nextScheduledRoot = null;
12717 firstScheduledRoot = lastScheduledRoot = null;
12718 break;
12719 } else if (root === firstScheduledRoot) {
12720 // This is the first root in the list.
12721 var next = root.nextScheduledRoot;
12722 firstScheduledRoot = next;
12723 lastScheduledRoot.nextScheduledRoot = next;
12724 root.nextScheduledRoot = null;
12725 } else if (root === lastScheduledRoot) {
12726 // This is the last root in the list.
12727 lastScheduledRoot = previousScheduledRoot;
12728 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12729 root.nextScheduledRoot = null;
12730 break;
12731 } else {
12732 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
12733 root.nextScheduledRoot = null;
12734 }
12735 root = previousScheduledRoot.nextScheduledRoot;
12736 } else {
12737 if (remainingExpirationTime > highestPriorityWork) {
12738 // Update the priority, if it's higher
12739 highestPriorityWork = remainingExpirationTime;
12740 highestPriorityRoot = root;
12741 }
12742 if (root === lastScheduledRoot) {
12743 break;
12744 }
12745 if (highestPriorityWork === Sync) {
12746 // Sync is highest priority by definition so
12747 // we can stop searching.
12748 break;
12749 }
12750 previousScheduledRoot = root;
12751 root = root.nextScheduledRoot;
12752 }
12753 }
12754 }
12755
12756 nextFlushedRoot = highestPriorityRoot;
12757 nextFlushedExpirationTime = highestPriorityWork;
12758}
12759
12760// TODO: This wrapper exists because many of the older tests (the ones that use
12761// flushDeferredPri) rely on the number of times `shouldYield` is called. We
12762// should get rid of it.
12763var didYield = false;
12764function shouldYieldToRenderer() {
12765 if (didYield) {
12766 return true;
12767 }
12768 if (unstable_shouldYield()) {
12769 didYield = true;
12770 return true;
12771 }
12772 return false;
12773}
12774
12775function performAsyncWork() {
12776 try {
12777 if (!shouldYieldToRenderer()) {
12778 // The callback timed out. That means at least one update has expired.
12779 // Iterate through the root schedule. If they contain expired work, set
12780 // the next render expiration time to the current time. This has the effect
12781 // of flushing all expired work in a single batch, instead of flushing each
12782 // level one at a time.
12783 if (firstScheduledRoot !== null) {
12784 recomputeCurrentRendererTime();
12785 var root = firstScheduledRoot;
12786 do {
12787 didExpireAtExpirationTime(root, currentRendererTime);
12788 // The root schedule is circular, so this is never null.
12789 root = root.nextScheduledRoot;
12790 } while (root !== firstScheduledRoot);
12791 }
12792 }
12793 performWork(NoWork, true);
12794 } finally {
12795 didYield = false;
12796 }
12797}
12798
12799function performSyncWork() {
12800 performWork(Sync, false);
12801}
12802
12803function performWork(minExpirationTime, isYieldy) {
12804 // Keep working on roots until there's no more work, or until there's a higher
12805 // priority event.
12806 findHighestPriorityRoot();
12807
12808 if (isYieldy) {
12809 recomputeCurrentRendererTime();
12810 currentSchedulerTime = currentRendererTime;
12811
12812 if (enableUserTimingAPI) {
12813 var didExpire = nextFlushedExpirationTime > currentRendererTime;
12814 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
12815 stopRequestCallbackTimer(didExpire, timeout);
12816 }
12817
12818 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
12819 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
12820 findHighestPriorityRoot();
12821 recomputeCurrentRendererTime();
12822 currentSchedulerTime = currentRendererTime;
12823 }
12824 } else {
12825 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
12826 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
12827 findHighestPriorityRoot();
12828 }
12829 }
12830
12831 // We're done flushing work. Either we ran out of time in this callback,
12832 // or there's no more work left with sufficient priority.
12833
12834 // If we're inside a callback, set this to false since we just completed it.
12835 if (isYieldy) {
12836 callbackExpirationTime = NoWork;
12837 callbackID = null;
12838 }
12839 // If there's work left over, schedule a new callback.
12840 if (nextFlushedExpirationTime !== NoWork) {
12841 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
12842 }
12843
12844 // Clean-up.
12845 finishRendering();
12846}
12847
12848function flushRoot(root, expirationTime) {
12849 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
12850 // Perform work on root as if the given expiration time is the current time.
12851 // This has the effect of synchronously flushing all work up to and
12852 // including the given time.
12853 nextFlushedRoot = root;
12854 nextFlushedExpirationTime = expirationTime;
12855 performWorkOnRoot(root, expirationTime, false);
12856 // Flush any sync work that was scheduled by lifecycles
12857 performSyncWork();
12858}
12859
12860function finishRendering() {
12861 nestedUpdateCount = 0;
12862 lastCommittedRootDuringThisBatch = null;
12863
12864 if (completedBatches !== null) {
12865 var batches = completedBatches;
12866 completedBatches = null;
12867 for (var i = 0; i < batches.length; i++) {
12868 var batch = batches[i];
12869 try {
12870 batch._onComplete();
12871 } catch (error) {
12872 if (!hasUnhandledError) {
12873 hasUnhandledError = true;
12874 unhandledError = error;
12875 }
12876 }
12877 }
12878 }
12879
12880 if (hasUnhandledError) {
12881 var error = unhandledError;
12882 unhandledError = null;
12883 hasUnhandledError = false;
12884 throw error;
12885 }
12886}
12887
12888function performWorkOnRoot(root, expirationTime, isYieldy) {
12889 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12890
12891 isRendering = true;
12892
12893 // Check if this is async work or sync/expired work.
12894 if (!isYieldy) {
12895 // Flush work without yielding.
12896 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
12897 // may want to perform some work without yielding, but also without
12898 // requiring the root to complete (by triggering placeholders).
12899
12900 var finishedWork = root.finishedWork;
12901 if (finishedWork !== null) {
12902 // This root is already complete. We can commit it.
12903 completeRoot(root, finishedWork, expirationTime);
12904 } else {
12905 root.finishedWork = null;
12906 // If this root previously suspended, clear its existing timeout, since
12907 // we're about to try rendering again.
12908 var timeoutHandle = root.timeoutHandle;
12909 if (timeoutHandle !== noTimeout) {
12910 root.timeoutHandle = noTimeout;
12911 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12912 cancelTimeout(timeoutHandle);
12913 }
12914 renderRoot(root, isYieldy);
12915 finishedWork = root.finishedWork;
12916 if (finishedWork !== null) {
12917 // We've completed the root. Commit it.
12918 completeRoot(root, finishedWork, expirationTime);
12919 }
12920 }
12921 } else {
12922 // Flush async work.
12923 var _finishedWork = root.finishedWork;
12924 if (_finishedWork !== null) {
12925 // This root is already complete. We can commit it.
12926 completeRoot(root, _finishedWork, expirationTime);
12927 } else {
12928 root.finishedWork = null;
12929 // If this root previously suspended, clear its existing timeout, since
12930 // we're about to try rendering again.
12931 var _timeoutHandle = root.timeoutHandle;
12932 if (_timeoutHandle !== noTimeout) {
12933 root.timeoutHandle = noTimeout;
12934 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12935 cancelTimeout(_timeoutHandle);
12936 }
12937 renderRoot(root, isYieldy);
12938 _finishedWork = root.finishedWork;
12939 if (_finishedWork !== null) {
12940 // We've completed the root. Check the if we should yield one more time
12941 // before committing.
12942 if (!shouldYieldToRenderer()) {
12943 // Still time left. Commit the root.
12944 completeRoot(root, _finishedWork, expirationTime);
12945 } else {
12946 // There's no time left. Mark this root as complete. We'll come
12947 // back and commit it later.
12948 root.finishedWork = _finishedWork;
12949 }
12950 }
12951 }
12952 }
12953
12954 isRendering = false;
12955}
12956
12957function completeRoot(root, finishedWork, expirationTime) {
12958 // Check if there's a batch that matches this expiration time.
12959 var firstBatch = root.firstBatch;
12960 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
12961 if (completedBatches === null) {
12962 completedBatches = [firstBatch];
12963 } else {
12964 completedBatches.push(firstBatch);
12965 }
12966 if (firstBatch._defer) {
12967 // This root is blocked from committing by a batch. Unschedule it until
12968 // we receive another update.
12969 root.finishedWork = finishedWork;
12970 root.expirationTime = NoWork;
12971 return;
12972 }
12973 }
12974
12975 // Commit the root.
12976 root.finishedWork = null;
12977
12978 // Check if this is a nested update (a sync update scheduled during the
12979 // commit phase).
12980 if (root === lastCommittedRootDuringThisBatch) {
12981 // If the next root is the same as the previous root, this is a nested
12982 // update. To prevent an infinite loop, increment the nested update count.
12983 nestedUpdateCount++;
12984 } else {
12985 // Reset whenever we switch roots.
12986 lastCommittedRootDuringThisBatch = root;
12987 nestedUpdateCount = 0;
12988 }
12989 unstable_runWithPriority(unstable_ImmediatePriority, function () {
12990 commitRoot(root, finishedWork);
12991 });
12992}
12993
12994function onUncaughtError(error) {
12995 !(nextFlushedRoot !== null) ? invariant(false, 'Should be working on a root. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12996 // Unschedule this root so we don't work on it again until there's
12997 // another update.
12998 nextFlushedRoot.expirationTime = NoWork;
12999 if (!hasUnhandledError) {
13000 hasUnhandledError = true;
13001 unhandledError = error;
13002 }
13003}
13004
13005// 0 is PROD, 1 is DEV.
13006// Might add PROFILE later.
13007
13008
13009var didWarnAboutNestedUpdates = void 0;
13010{
13011 didWarnAboutNestedUpdates = false;
13012
13013}
13014
13015function getContextForSubtree(parentComponent) {
13016 if (!parentComponent) {
13017 return emptyContextObject;
13018 }
13019
13020 var fiber = get(parentComponent);
13021 var parentContext = findCurrentUnmaskedContext(fiber);
13022
13023 if (fiber.tag === ClassComponent) {
13024 var Component = fiber.type;
13025 if (isContextProvider(Component)) {
13026 return processChildContext(fiber, Component, parentContext);
13027 }
13028 }
13029
13030 return parentContext;
13031}
13032
13033function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
13034 {
13035 if (phase === 'render' && current$1 !== null && !didWarnAboutNestedUpdates) {
13036 didWarnAboutNestedUpdates = true;
13037 warningWithoutStack$1(false, 'Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName(current$1.type) || 'Unknown');
13038 }
13039 }
13040
13041 var update = createUpdate(expirationTime);
13042 // Caution: React DevTools currently depends on this property
13043 // being called "element".
13044 update.payload = { element: element };
13045
13046 callback = callback === undefined ? null : callback;
13047 if (callback !== null) {
13048 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
13049 update.callback = callback;
13050 }
13051
13052 flushPassiveEffects();
13053 enqueueUpdate(current$$1, update);
13054 scheduleWork(current$$1, expirationTime);
13055
13056 return expirationTime;
13057}
13058
13059function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
13060 // TODO: If this is a nested container, this won't be the root.
13061 var current$$1 = container.current;
13062
13063 {
13064 if (ReactFiberInstrumentation_1.debugTool) {
13065 if (current$$1.alternate === null) {
13066 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
13067 } else if (element === null) {
13068 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
13069 } else {
13070 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
13071 }
13072 }
13073 }
13074
13075 var context = getContextForSubtree(parentComponent);
13076 if (container.context === null) {
13077 container.context = context;
13078 } else {
13079 container.pendingContext = context;
13080 }
13081
13082 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
13083}
13084
13085function createContainer(containerInfo, isConcurrent, hydrate) {
13086 return createFiberRoot(containerInfo, isConcurrent, hydrate);
13087}
13088
13089function updateContainer(element, container, parentComponent, callback) {
13090 var current$$1 = container.current;
13091 var currentTime = requestCurrentTime();
13092 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
13093 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
13094}
13095
13096
13097
13098
13099
13100var overrideProps = null;
13101
13102{
13103 var copyWithSetImpl = function (obj, path, idx, value) {
13104 if (idx >= path.length) {
13105 return value;
13106 }
13107 var key = path[idx];
13108 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
13109 // $FlowFixMe number or string is fine here
13110 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
13111 return updated;
13112 };
13113
13114 var copyWithSet = function (obj, path, value) {
13115 return copyWithSetImpl(obj, path, 0, value);
13116 };
13117
13118 // Support DevTools props for function components, forwardRef, memo, host components, etc.
13119 overrideProps = function (fiber, path, value) {
13120 flushPassiveEffects();
13121 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
13122 if (fiber.alternate) {
13123 fiber.alternate.pendingProps = fiber.pendingProps;
13124 }
13125 scheduleWork(fiber, Sync);
13126 };
13127}
13128
13129function injectIntoDevTools(devToolsConfig) {
13130 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
13131 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
13132
13133
13134 return injectInternals(_assign({}, devToolsConfig, {
13135 overrideProps: overrideProps,
13136 currentDispatcherRef: ReactCurrentDispatcher,
13137 findHostInstanceByFiber: function (fiber) {
13138 var hostFiber = findCurrentHostFiber(fiber);
13139 if (hostFiber === null) {
13140 return null;
13141 }
13142 return hostFiber.stateNode;
13143 },
13144 findFiberByHostInstance: function (instance) {
13145 if (!findFiberByHostInstance) {
13146 // Might not be implemented by the renderer.
13147 return null;
13148 }
13149 return findFiberByHostInstance(instance);
13150 }
13151 }));
13152}
13153
13154// This file intentionally does *not* have the Flow annotation.
13155// Don't add it. See `./inline-typed.js` for an explanation.
13156
13157var container = _class({
13158
13159 grab: function(){
13160 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
13161 return this;
13162 },
13163
13164 empty: function(){
13165 var node;
13166 while (node = this.firstChild) node.eject();
13167 return this;
13168 }
13169
13170});
13171
13172function elementFrom(node){
13173 if (node.toElement) return node.toElement();
13174 if (node.getDOMNode) return node.getDOMNode();
13175 if (node.getNode) return node.getNode();
13176 return node;
13177}
13178
13179var native_1 = _class({
13180
13181 // conventions
13182
13183 toElement: function(){
13184 return this.element;
13185 },
13186
13187 getDOMNode: function(){
13188 return this.toElement();
13189 },
13190
13191 getNode: function(){
13192 return this.toElement();
13193 },
13194
13195 // placement
13196
13197 inject: function(container){
13198 (container.containerElement || elementFrom(container))
13199 .appendChild(this.element);
13200 return this;
13201 },
13202
13203 injectBefore: function(sibling){
13204 var element = elementFrom(sibling);
13205 element.parentNode.insertBefore(this.element, element);
13206 return this;
13207 },
13208
13209 eject: function(){
13210 var element = this.element, parent = element.parentNode;
13211 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
13212 return this;
13213 },
13214
13215 // events
13216
13217 subscribe: function(type, fn, bind){
13218 if (typeof type != 'string'){ // listen type / fn with object
13219 var subscriptions = [];
13220 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
13221 return function(){ // unsubscribe
13222 for (var i = 0, l = subscriptions.length; i < l; i++)
13223 subscriptions[i]();
13224 return this;
13225 };
13226 } else { // listen to one
13227 if (!bind) bind = this;
13228 var bound;
13229 if (typeof fn === 'function'){
13230 bound = fn.bind ? fn.bind(bind)
13231 : function(){ return fn.apply(bind, arguments); };
13232 } else {
13233 bound = fn;
13234 }
13235 var element = this.element;
13236 if (element.addEventListener){
13237 element.addEventListener(type, bound, false);
13238 return function(){ // unsubscribe
13239 element.removeEventListener(type, bound, false);
13240 return this;
13241 };
13242 } else {
13243 element.attachEvent('on' + type, bound);
13244 return function(){ // unsubscribe
13245 element.detachEvent('on' + type, bound);
13246 return this;
13247 };
13248 }
13249 }
13250 }
13251
13252});
13253
13254var fps = 1000 / 60;
13255var invalids = [];
13256var renderTimer;
13257var renderInvalids = function(){
13258 clearTimeout(renderTimer);
13259 renderTimer = null;
13260 var canvases = invalids;
13261 invalids = [];
13262 for (var i = 0, l = canvases.length; i < l; i++){
13263 var c = canvases[i];
13264 c._valid = true;
13265 c.render();
13266 }
13267};
13268
13269var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
13270
13271var previousHit = null;
13272var previousHitSurface = null;
13273
13274var CanvasSurface = _class(native_1, container, {
13275
13276 initialize: function(width, height, existingElement){
13277 var element = this.element = existingElement || document.createElement('canvas');
13278 var context = this.context = element.getContext('2d');
13279 this._valid = true;
13280 if (width != null && height != null) this.resize(width, height);
13281
13282 element.addEventListener('mousemove', this, false);
13283 element.addEventListener('mouseout', this, false);
13284 element.addEventListener('mouseover', this, false);
13285 element.addEventListener('mouseup', this, false);
13286 element.addEventListener('mousedown', this, false);
13287 element.addEventListener('click', this, false);
13288 },
13289
13290 handleEvent: function(event){
13291 if (event.clientX == null) return;
13292 var element = this.element,
13293 rect = element.getBoundingClientRect(),
13294 x = event.clientX - rect.left - element.clientLeft,
13295 y = event.clientY - rect.top - element.clientTop,
13296 hit = this.hitTest(x, y);
13297
13298 if (hit !== previousHit){
13299 if (previousHit){
13300 previousHit.dispatch({
13301 type: 'mouseout',
13302 target: previousHit,
13303 relatedTarget: hit,
13304 sourceEvent: event
13305 });
13306 }
13307 if (hit){
13308 hit.dispatch({
13309 type: 'mouseover',
13310 target: hit,
13311 relatedTarget: previousHit,
13312 sourceEvent: event
13313 });
13314 }
13315 previousHit = hit;
13316 previousHitSurface = this;
13317 this.refreshCursor();
13318 }
13319
13320 if (hit) hit.dispatch(event);
13321 },
13322
13323 refreshCursor: function(){
13324 if (previousHitSurface !== this) return;
13325 var hit = previousHit, hitCursor = '', hitTooltip = '';
13326 while (hit){
13327 if (!hitCursor && hit._cursor){
13328 hitCursor = hit._cursor;
13329 if (hitTooltip) break;
13330 }
13331 if (!hitTooltip && hit._tooltip){
13332 hitTooltip = hit._tooltip;
13333 if (hitCursor) break;
13334 }
13335 hit = hit.parentNode;
13336 }
13337 // TODO: No way to set cursor/title on the surface
13338 this.element.style.cursor = hitCursor;
13339 this.element.title = hitTooltip;
13340 },
13341
13342 resize: function(width, height){
13343 var element = this.element;
13344 element.setAttribute('width', width * resolution);
13345 element.setAttribute('height', height * resolution);
13346 element.style.width = width + 'px';
13347 element.style.height = height + 'px';
13348 this.width = width;
13349 this.height = height;
13350 return this;
13351 },
13352
13353 invalidate: function(left, top, width, height){
13354 if (this._valid){
13355 this._valid = false;
13356 invalids.push(this);
13357 if (!renderTimer){
13358 if (window.mozRequestAnimationFrame){
13359 renderTimer = true;
13360 window.mozRequestAnimationFrame(renderInvalids);
13361 } else {
13362 renderTimer = setTimeout(renderInvalids, fps);
13363 }
13364 }
13365 }
13366 return this;
13367 },
13368
13369 hitTest: function(x, y){
13370 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
13371 var node = this.lastChild;
13372 while (node){
13373 var hit = node.hitTest(x, y);
13374 if (hit) return hit;
13375 node = node.previousSibling;
13376 }
13377 return null;
13378 },
13379
13380 render: function(){
13381 var node = this.firstChild, context = this.context;
13382 context.setTransform(resolution, 0, 0, resolution, 0, 0);
13383 context.clearRect(0, 0, this.width, this.height);
13384 while (node){
13385 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
13386 node = node.nextSibling;
13387 }
13388 this.refreshCursor();
13389 }
13390
13391});
13392
13393CanvasSurface.tagName = 'canvas';
13394
13395var surface = CanvasSurface;
13396
13397var path$2 = _class({
13398
13399 initialize: function(path){
13400 this.reset().push(path);
13401 },
13402
13403 /* parser */
13404
13405 push: function(){
13406 var p = Array.prototype.join.call(arguments, ' ')
13407 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
13408 if (!p) return this;
13409
13410 var last, cmd = p[0], i = 1;
13411 while (cmd){
13412 switch (cmd){
13413 case 'm': this.move(p[i++], p[i++]); break;
13414 case 'l': this.line(p[i++], p[i++]); break;
13415 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
13416 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
13417 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
13418 case 't': this.curve(p[i++], p[i++]); break;
13419 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;
13420 case 'h': this.line(p[i++], 0); break;
13421 case 'v': this.line(0, p[i++]); break;
13422
13423 case 'M': this.moveTo(p[i++], p[i++]); break;
13424 case 'L': this.lineTo(p[i++], p[i++]); break;
13425 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
13426 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
13427 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
13428 case 'T': this.curveTo(p[i++], p[i++]); break;
13429 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;
13430 case 'H': this.lineTo(p[i++], this.penY); break;
13431 case 'V': this.lineTo(this.penX, p[i++]); break;
13432
13433 case 'Z': case 'z': this.close(); break;
13434 default: cmd = last; i--; continue;
13435 }
13436
13437 last = cmd;
13438 if (last == 'm') last = 'l';
13439 else if (last == 'M') last = 'L';
13440 cmd = p[i++];
13441 }
13442 return this;
13443 },
13444
13445 /* utility methods */
13446
13447 reset: function(){
13448 this.penX = this.penY = 0;
13449 this.penDownX = this.penDownY = null;
13450 this._pivotX = this._pivotY = 0;
13451 this.onReset();
13452 return this;
13453 },
13454
13455 move: function(x,y){
13456 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
13457 return this;
13458 },
13459 moveTo: function(x,y){
13460 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13461 return this;
13462 },
13463
13464 line: function(x,y){
13465 return this.lineTo(this.penX + (+x), this.penY + (+y));
13466 },
13467 lineTo: function(x,y){
13468 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13469 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13470 return this;
13471 },
13472
13473 curve: function(c1x, c1y, c2x, c2y, ex, ey){
13474 var x = this.penX, y = this.penY;
13475 return this.curveTo(
13476 x + (+c1x), y + (+c1y),
13477 c2x == null ? null : x + (+c2x),
13478 c2y == null ? null : y + (+c2y),
13479 ex == null ? null : x + (+ex),
13480 ey == null ? null : y + (+ey)
13481 );
13482 },
13483 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
13484 var x = this.penX, y = this.penY;
13485 if (c2x == null){
13486 c2x = +c1x; c2y = +c1y;
13487 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
13488 }
13489 if (ex == null){
13490 this._pivotX = +c1x; this._pivotY = +c1y;
13491 ex = +c2x; ey = +c2y;
13492 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
13493 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
13494 } else {
13495 this._pivotX = +c2x; this._pivotY = +c2y;
13496 }
13497 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
13498 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
13499 return this;
13500 },
13501
13502 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
13503 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
13504 },
13505 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
13506 ry = Math.abs(+ry || +rx || (+y - this.penY));
13507 rx = Math.abs(+rx || (+x - this.penX));
13508
13509 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
13510
13511 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
13512
13513 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
13514 x -= tX; y -= tY;
13515
13516 // Ellipse Center
13517 var cx = cos * x / 2 + sin * y / 2,
13518 cy = -sin * x / 2 + cos * y / 2,
13519 rxry = rx * rx * ry * ry,
13520 rycx = ry * ry * cx * cx,
13521 rxcy = rx * rx * cy * cy,
13522 a = rxry - rxcy - rycx;
13523
13524 if (a < 0){
13525 a = Math.sqrt(1 - a / rxry);
13526 rx *= a; ry *= a;
13527 cx = x / 2; cy = y / 2;
13528 } else {
13529 a = Math.sqrt(a / (rxcy + rycx));
13530 if (large == clockwise) a = -a;
13531 var cxd = -a * cy * rx / ry,
13532 cyd = a * cx * ry / rx;
13533 cx = cos * cxd - sin * cyd + x / 2;
13534 cy = sin * cxd + cos * cyd + y / 2;
13535 }
13536
13537 // Rotation + Scale Transform
13538 var xx = cos / rx, yx = sin / rx,
13539 xy = -sin / ry, yy = cos / ry;
13540
13541 // Start and End Angle
13542 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
13543 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
13544
13545 cx += tX; cy += tY;
13546 x += tX; y += tY;
13547
13548 // Circular Arc
13549 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13550 this.onArc(
13551 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
13552 cx, cy, rx, ry, sa, ea, !clockwise, rotation
13553 );
13554 return this;
13555 },
13556
13557 counterArc: function(x, y, rx, ry, outer){
13558 return this.arc(x, y, rx, ry, outer, true);
13559 },
13560 counterArcTo: function(x, y, rx, ry, outer){
13561 return this.arcTo(x, y, rx, ry, outer, true);
13562 },
13563
13564 close: function(){
13565 if (this.penDownX != null){
13566 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
13567 this.penDownX = null;
13568 }
13569 return this;
13570 },
13571
13572 /* overridable handlers */
13573
13574 onReset: function(){
13575 },
13576
13577 onMove: function(sx, sy, ex, ey){
13578 },
13579
13580 onLine: function(sx, sy, ex, ey){
13581 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
13582 },
13583
13584 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
13585 var gx = ex - sx, gy = ey - sy,
13586 g = gx * gx + gy * gy,
13587 v1, v2, cx, cy, u;
13588
13589 cx = c1x - sx; cy = c1y - sy;
13590 u = cx * gx + cy * gy;
13591
13592 if (u > g){
13593 cx -= gx;
13594 cy -= gy;
13595 } else if (u > 0 && g != 0){
13596 cx -= u/g * gx;
13597 cy -= u/g * gy;
13598 }
13599
13600 v1 = cx * cx + cy * cy;
13601
13602 cx = c2x - sx; cy = c2y - sy;
13603 u = cx * gx + cy * gy;
13604
13605 if (u > g){
13606 cx -= gx;
13607 cy -= gy;
13608 } else if (u > 0 && g != 0){
13609 cx -= u/g * gx;
13610 cy -= u/g * gy;
13611 }
13612
13613 v2 = cx * cx + cy * cy;
13614
13615 if (v1 < 0.01 && v2 < 0.01){
13616 this.onLine(sx, sy, ex, ey);
13617 return;
13618 }
13619
13620 // Avoid infinite recursion
13621 if (isNaN(v1) || isNaN(v2)){
13622 throw new Error('Bad input');
13623 }
13624
13625 // Split curve
13626 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
13627 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
13628 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
13629 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
13630 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
13631 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
13632
13633 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
13634 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
13635 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
13636 },
13637
13638 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13639 // Inverse Rotation + Scale Transform
13640 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
13641 xx = cos * rx, yx = -sin * ry,
13642 xy = sin * rx, yy = cos * ry;
13643
13644 // Bezier Curve Approximation
13645 var arc = ea - sa;
13646 if (arc < 0 && !ccw) arc += Math.PI * 2;
13647 else if (arc > 0 && ccw) arc -= Math.PI * 2;
13648
13649 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
13650 step = arc / n,
13651 k = (4 / 3) * Math.tan(step / 4);
13652
13653 var x = Math.cos(sa), y = Math.sin(sa);
13654
13655 for (var i = 0; i < n; i++){
13656 var cp1x = x - k * y, cp1y = y + k * x;
13657
13658 sa += step;
13659 x = Math.cos(sa); y = Math.sin(sa);
13660
13661 var cp2x = x + k * y, cp2y = y - k * x;
13662
13663 this.onBezierCurve(
13664 sx, sy,
13665 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
13666 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
13667 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
13668 );
13669 }
13670 },
13671
13672 onClose: function(sx, sy, ex, ey){
13673 this.onLine(sx, sy, ex, ey);
13674 }
13675
13676});
13677
13678var CanvasPath = _class(path$2, {
13679
13680 initialize: function(path){
13681 this.reset();
13682 if (path instanceof CanvasPath){
13683 this.path = path.path.slice(0);
13684 } else if (path){
13685 if (path.applyToPath)
13686 path.applyToPath(this);
13687 else
13688 this.push(path);
13689 }
13690 },
13691
13692 onReset: function(){
13693 this.path = [];
13694 },
13695
13696 onMove: function(sx, sy, x, y){
13697 this.path.push(function(context){
13698 context.moveTo(x, y);
13699 });
13700 },
13701
13702 onLine: function(sx, sy, x, y){
13703 this.path.push(function(context){
13704 context.lineTo(x, y);
13705 });
13706 },
13707
13708 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
13709 this.path.push(function(context){
13710 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
13711 });
13712 },
13713
13714 _arcToBezier: path$2.prototype.onArc,
13715
13716 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13717 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
13718 this.path.push(function(context){
13719 context.arc(cx, cy, rx, sa, ea, ccw);
13720 });
13721 },
13722
13723 onClose: function(){
13724 this.path.push(function(context){
13725 context.closePath();
13726 });
13727 },
13728
13729 toCommands: function(){
13730 return this.path.slice(0);
13731 }
13732
13733});
13734
13735var path = CanvasPath;
13736
13737var colors = {
13738 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
13739 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
13740 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
13741 black: '#000000', silver: '#c0c0c0', gray: '#808080'
13742};
13743
13744var map = function(array, fn){
13745 var results = [];
13746 for (var i = 0, l = array.length; i < l; i++)
13747 results[i] = fn(array[i], i);
13748 return results;
13749};
13750
13751var Color = function(color, type){
13752
13753 if (color.isColor){
13754
13755 this.red = color.red;
13756 this.green = color.green;
13757 this.blue = color.blue;
13758 this.alpha = color.alpha;
13759
13760 } else {
13761
13762 var namedColor = colors[color];
13763 if (namedColor){
13764 color = namedColor;
13765 type = 'hex';
13766 }
13767
13768 switch (typeof color){
13769 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
13770 case 'object': type = type || 'rgb'; color = color.toString(); break;
13771 case 'number': type = 'hex'; color = color.toString(16); break;
13772 }
13773
13774 color = Color['parse' + type.toUpperCase()](color);
13775 this.red = color[0];
13776 this.green = color[1];
13777 this.blue = color[2];
13778 this.alpha = color[3];
13779 }
13780
13781 this.isColor = true;
13782
13783};
13784
13785var limit = function(number, min, max){
13786 return Math.min(max, Math.max(min, number));
13787};
13788
13789var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
13790var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
13791
13792Color.parseRGB = function(color){
13793 return map(color.match(listMatch).slice(1), function(bit, i){
13794 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
13795 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13796 });
13797};
13798
13799Color.parseHEX = function(color){
13800 if (color.length == 1) color = color + color + color;
13801 return map(color.match(hexMatch).slice(1), function(bit, i){
13802 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
13803 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
13804 });
13805};
13806
13807Color.parseHSB = function(color){
13808 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13809 if (bit) bit = parseFloat(bit);
13810 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13811 else if (i < 3) return limit(Math.round(bit), 0, 100);
13812 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13813 });
13814
13815 var a = hsb[3];
13816 var br = Math.round(hsb[2] / 100 * 255);
13817 if (hsb[1] == 0) return [br, br, br, a];
13818
13819 var hue = hsb[0];
13820 var f = hue % 60;
13821 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
13822 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
13823 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
13824
13825 switch (Math.floor(hue / 60)){
13826 case 0: return [br, t, p, a];
13827 case 1: return [q, br, p, a];
13828 case 2: return [p, br, t, a];
13829 case 3: return [p, q, br, a];
13830 case 4: return [t, p, br, a];
13831 default: return [br, p, q, a];
13832 }
13833};
13834
13835Color.parseHSL = function(color){
13836 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13837 if (bit) bit = parseFloat(bit);
13838 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13839 else if (i < 3) return limit(Math.round(bit), 0, 100);
13840 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13841 });
13842
13843 var h = hsb[0] / 60;
13844 var s = hsb[1] / 100;
13845 var l = hsb[2] / 100;
13846 var a = hsb[3];
13847
13848 var c = (1 - Math.abs(2 * l - 1)) * s;
13849 var x = c * (1 - Math.abs(h % 2 - 1));
13850 var m = l - c / 2;
13851
13852 var p = Math.round((c + m) * 255);
13853 var q = Math.round((x + m) * 255);
13854 var t = Math.round((m) * 255);
13855
13856 switch (Math.floor(h)){
13857 case 0: return [p, q, t, a];
13858 case 1: return [q, p, t, a];
13859 case 2: return [t, p, q, a];
13860 case 3: return [t, q, p, a];
13861 case 4: return [q, t, p, a];
13862 default: return [p, t, q, a];
13863 }
13864};
13865
13866var toString = function(type, array){
13867 if (array[3] != 1) type += 'a';
13868 else array.pop();
13869 return type + '(' + array.join(', ') + ')';
13870};
13871
13872Color.prototype = {
13873
13874 toHSB: function(array){
13875 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13876
13877 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13878 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
13879 if (saturation){
13880 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13881 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13882 if ((hue /= 6) < 0) hue++;
13883 }
13884
13885 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
13886
13887 return (array) ? hsb : toString('hsb', hsb);
13888 },
13889
13890 toHSL: function(array){
13891 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13892
13893 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13894 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
13895 if (saturation){
13896 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13897 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13898 if ((hue /= 6) < 0) hue++;
13899 }
13900
13901 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
13902
13903 return (array) ? hsl : toString('hsl', hsl);
13904 },
13905
13906 toHEX: function(array){
13907
13908 var a = this.alpha;
13909 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
13910
13911 var hex = map([this.red, this.green, this.blue], function(bit){
13912 bit = bit.toString(16);
13913 return (bit.length == 1) ? '0' + bit : bit;
13914 });
13915
13916 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
13917 },
13918
13919 toRGB: function(array){
13920 var rgb = [this.red, this.green, this.blue, this.alpha];
13921 return (array) ? rgb : toString('rgb', rgb);
13922 }
13923
13924};
13925
13926Color.prototype.toString = Color.prototype.toRGB;
13927
13928Color.hex = function(hex){
13929 return new Color(hex, 'hex');
13930};
13931
13932if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
13933
13934Color.hsb = function(h, s, b, a){
13935 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
13936};
13937
13938if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
13939
13940Color.hsl = function(h, s, l, a){
13941 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
13942};
13943
13944if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
13945
13946Color.rgb = function(r, g, b, a){
13947 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
13948};
13949
13950if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
13951
13952Color.detach = function(color){
13953 color = new Color(color);
13954 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
13955};
13956
13957var color = Color;
13958
13959var dummy = _class({
13960
13961 // placement
13962
13963 _resetPlacement: function(){
13964 var container = this.parentNode;
13965 if (container){
13966 var previous = this.previousSibling, next = this.nextSibling;
13967 if (previous){
13968 previous.nextSibling = next;
13969 } else {
13970 container.firstChild = next;
13971 }
13972 if (next){
13973 next.previousSibling = previous;
13974 } else {
13975 container.lastChild = this.previousSibling;
13976 }
13977 }
13978 this.previousSibling = null;
13979 this.nextSibling = null;
13980 this.parentNode = null;
13981 return this;
13982 },
13983
13984 inject: function(container){
13985 this._resetPlacement();
13986 var last = container.lastChild;
13987 if (last){
13988 last.nextSibling = this;
13989 this.previousSibling = last;
13990 } else {
13991 container.firstChild = this;
13992 }
13993 container.lastChild = this;
13994 this.parentNode = container;
13995 this._place();
13996 return this;
13997 },
13998
13999 injectBefore: function(sibling){
14000 this._resetPlacement();
14001 var container = sibling.parentNode;
14002 if (!container) return this;
14003 var previous = sibling.previousSibling;
14004 if (previous){
14005 previous.nextSibling = this;
14006 this.previousSibling = previous;
14007 } else {
14008 container.firstChild = this;
14009 }
14010 sibling.previousSibling = this;
14011 this.nextSibling = sibling;
14012 this.parentNode = container;
14013 this._place();
14014 return this;
14015 },
14016
14017 eject: function(){
14018 this._resetPlacement();
14019 this._place();
14020 return this;
14021 },
14022
14023 _place: function(){},
14024
14025 // events
14026
14027 dispatch: function(event){
14028 var events = this._events,
14029 listeners = events && events[event.type];
14030 if (listeners){
14031 listeners = listeners.slice(0);
14032 for (var i = 0, l = listeners.length; i < l; i++){
14033 var fn = listeners[i], result;
14034 if (typeof fn == 'function')
14035 result = fn.call(this, event);
14036 else
14037 result = fn.handleEvent(event);
14038 if (result === false) event.preventDefault();
14039 }
14040 }
14041 if (this.parentNode && this.parentNode.dispatch){
14042 this.parentNode.dispatch(event);
14043 }
14044 },
14045
14046 subscribe: function(type, fn, bind){
14047 if (typeof type != 'string'){ // listen type / fn with object
14048 var subscriptions = [];
14049 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
14050 return function(){ // unsubscribe
14051 for (var i = 0, l = subscriptions.length; i < l; i++)
14052 subscriptions[i]();
14053 return this;
14054 };
14055 } else { // listen to one
14056 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
14057 events = this._events || (this._events = {}),
14058 listeners = events[type] || (events[type] = []);
14059 listeners.push(bound);
14060 return function(){
14061 // unsubscribe
14062 for (var i = 0, l = listeners.length; i < l; i++){
14063 if (listeners[i] === bound){
14064 listeners.splice(i, 1);
14065 break;
14066 }
14067 }
14068 }
14069 }
14070 }
14071
14072});
14073
14074var CanvasNode = _class(transform, dummy, {
14075
14076 invalidate: function(){
14077 if (this.parentNode) this.parentNode.invalidate();
14078 if (this._layer) this._layerCache = null;
14079 return this;
14080 },
14081
14082 _place: function(){
14083 this.invalidate();
14084 },
14085
14086 _transform: function(){
14087 this.invalidate();
14088 },
14089
14090 blend: function(opacity){
14091 if (opacity >= 1 && this._layer) this._layer = null;
14092 this._opacity = opacity;
14093 if (this.parentNode) this.parentNode.invalidate();
14094 return this;
14095 },
14096
14097 // visibility
14098
14099 hide: function(){
14100 this._invisible = true;
14101 if (this.parentNode) this.parentNode.invalidate();
14102 return this;
14103 },
14104
14105 show: function(){
14106 this._invisible = false;
14107 if (this.parentNode) this.parentNode.invalidate();
14108 return this;
14109 },
14110
14111 // interaction
14112
14113 indicate: function(cursor, tooltip){
14114 this._cursor = cursor;
14115 this._tooltip = tooltip;
14116 return this.invalidate();
14117 },
14118
14119 hitTest: function(x, y){
14120 if (this._invisible) return null;
14121 var point = this.inversePoint(x, y);
14122 if (!point) return null;
14123 return this.localHitTest(point.x, point.y);
14124 },
14125
14126 // rendering
14127
14128 renderTo: function(context, xx, yx, xy, yy, x, y){
14129 var opacity = this._opacity;
14130 if (opacity == null || opacity >= 1){
14131 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
14132 }
14133
14134 // Render to a compositing layer and cache it
14135
14136 var layer = this._layer, canvas, isDirty = true,
14137 w = context.canvas.width, h = context.canvas.height;
14138 if (layer){
14139 layer.setTransform(1, 0, 0, 1, 0, 0);
14140 canvas = layer.canvas;
14141 if (canvas.width < w || canvas.height < h){
14142 canvas.width = w;
14143 canvas.height = h;
14144 } else {
14145 var c = this._layerCache;
14146 if (c && c.xx === xx && c.yx === yx && c.xy === xy
14147 && c.yy === yy && c.x === x && c.y === y){
14148 isDirty = false;
14149 } else {
14150 layer.clearRect(0, 0, w, h);
14151 }
14152 }
14153 } else {
14154 canvas = document.createElement('canvas');
14155 canvas.width = w;
14156 canvas.height = h;
14157 this._layer = layer = canvas.getContext('2d');
14158 }
14159
14160 if (isDirty){
14161 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
14162 this._layerCache = {
14163 xx: xx,
14164 yx: yx,
14165 xy: xy,
14166 yy: yy,
14167 x: x,
14168 y: y
14169 };
14170 }
14171
14172 context.globalAlpha = opacity;
14173 context.setTransform(1, 0, 0, 1, 0, 0);
14174 context.drawImage(
14175 canvas,
14176 0, 0, w, h,
14177 0, 0, w, h
14178 );
14179 context.globalAlpha = 1;
14180 }
14181
14182});
14183
14184var node = CanvasNode;
14185
14186var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas');
14187var genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
14188
14189function recolorImage(img, color1, color2){
14190 // TODO: Fix this experimental implementation
14191 color1 = color.detach(color1);
14192 color2 = color.detach(color2);
14193 var canvas = document.createElement('canvas'),
14194 context = canvas.getContext('2d');
14195 canvas.width = img.width;
14196 canvas.height = img.height;
14197 context.fillStyle = color2[0];
14198 context.fillRect(0, 0, img.width, img.height);
14199 context.globalCompositeOperation = 'lighter';
14200 context.drawImage(img, 0, 0);
14201 return canvas;
14202}
14203
14204var Base = _class(node, {
14205
14206 initialize: function(){
14207 this._fill = null;
14208 this._pendingFill = null;
14209 this._fillTransform = null;
14210 this._stroke = null;
14211 this._strokeCap = null;
14212 this._strokeDash = null;
14213 this._strokeJoin = null;
14214 this._strokeWidth = null;
14215 },
14216
14217 /* styles */
14218
14219 _addColors: function(gradient, stops){
14220 // Enumerate stops, assumes offsets are enumerated in order
14221 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
14222 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
14223 gradient.addColorStop(i / l, new color(stops[i]).toString());
14224 else for (var offset in stops)
14225 gradient.addColorStop(offset, new color(stops[offset]).toString());
14226 return gradient;
14227 },
14228
14229
14230 fill: function(color$$1){
14231 if (arguments.length > 1) return this.fillLinear(arguments);
14232 if (this._pendingFill) this._pendingFill();
14233 this._fill = color$$1 ? new color(color$$1).toString() : null;
14234 return this.invalidate();
14235 },
14236
14237 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
14238 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
14239 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
14240 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
14241 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
14242 if (centerX == null) centerX = focusX;
14243 if (centerY == null) centerY = focusY;
14244
14245 centerX += centerX - focusX;
14246 centerY += centerY - focusY;
14247
14248 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
14249 var ys = radiusY / radiusX;
14250
14251 if (this._pendingFill) this._pendingFill();
14252
14253 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
14254
14255 // Double fill radius to simulate repeating gradient
14256 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
14257 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
14258 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
14259 } else for (var offset in stops){
14260 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
14261 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
14262 }
14263
14264 this._fill = gradient;
14265 this._fillTransform = new transform(1, 0, 0, ys);
14266 return this.invalidate();
14267 },
14268
14269 fillLinear: function(stops, x1, y1, x2, y2){
14270 if (arguments.length < 5){
14271 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
14272
14273 var x = Math.cos(angle), y = -Math.sin(angle),
14274 l = (Math.abs(x) + Math.abs(y)) / 2,
14275 w = this.width || 1, h = this.height || 1;
14276
14277 x *= l; y *= l;
14278
14279 x1 = 0.5 - x;
14280 x2 = 0.5 + x;
14281 y1 = 0.5 - y;
14282 y2 = 0.5 + y;
14283 this._fillTransform = new transform(w, 0, 0, h);
14284 } else {
14285 this._fillTransform = null;
14286 }
14287 if (this._pendingFill) this._pendingFill();
14288 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
14289 this._addColors(gradient, stops);
14290 this._fill = gradient;
14291 return this.invalidate();
14292 },
14293
14294 fillImage: function(url, width, height, left, top, color1, color2){
14295 if (this._pendingFill) this._pendingFill();
14296 var img = url;
14297 if (!(img instanceof Image)){
14298 img = new Image();
14299 img.src = url;
14300 }
14301 if (img.width && img.height){
14302 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
14303 }
14304
14305 // Not yet loaded
14306 this._fill = null;
14307 var self = this,
14308 callback = function(){
14309 cancel();
14310 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
14311 },
14312 cancel = function(){
14313 img.removeEventListener('load', callback, false);
14314 self._pendingFill = null;
14315 };
14316 this._pendingFill = cancel;
14317 img.addEventListener('load', callback, false);
14318 return this;
14319 },
14320
14321 _fillImage: function(img, width, height, left, top, color1, color2){
14322 var w = width ? width / img.width : 1,
14323 h = height ? height / img.height : 1;
14324 if (color1 != null) img = recolorImage(img, color1, color2);
14325 this._fill = genericContext.createPattern(img, 'repeat');
14326 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
14327 return this.invalidate();
14328 },
14329
14330 stroke: function(color$$1, width, cap, join, dash){
14331 this._stroke = color$$1 ? new color(color$$1).toString() : null;
14332 this._strokeWidth = (width != null) ? width : 1;
14333 this._strokeCap = (cap != null) ? cap : 'round';
14334 this._strokeJoin = (join != null) ? join : 'round';
14335 this._strokeDash = dash;
14336 return this.invalidate();
14337 },
14338
14339 // Rendering
14340
14341 element_renderTo: node.prototype.renderTo,
14342
14343 renderTo: function(context, xx, yx, xy, yy, x, y){
14344 var opacity = this._opacity;
14345 if (opacity == null || opacity >= 1){
14346 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
14347 }
14348 if (this._fill && this._stroke){
14349 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
14350 }
14351 context.globalAlpha = opacity;
14352 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
14353 context.globalAlpha = 1;
14354 return r;
14355 },
14356
14357 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
14358 context.setTransform(xx, yx, xy, yy, x, y);
14359 this.renderShapeTo(context);
14360 }
14361
14362});
14363
14364Base._genericContext = genericContext;
14365
14366var base = Base;
14367
14368var shape = _class(base, {
14369
14370 base_initialize: base.prototype.initialize,
14371
14372 initialize: function(path$$1, width, height){
14373 this.base_initialize();
14374 this.width = width;
14375 this.height = height;
14376 if (path$$1 != null) this.draw(path$$1);
14377 },
14378
14379 draw: function(path$$1, width, height){
14380 if (!(path$$1 instanceof path)) path$$1 = new path(path$$1);
14381 this.path = path$$1;
14382 this._commands = path$$1.toCommands();
14383 if (width != null) this.width = width;
14384 if (height != null) this.height = height;
14385 return this.invalidate();
14386 },
14387
14388 localHitTest: function(x, y){
14389 if (!this._fill) return null;
14390 if (this.width == null || this.height == null){
14391 var context = base._genericContext, commands = this._commands;
14392 if (!commands) return null;
14393 context.beginPath();
14394 for (var i = 0, l = commands.length; i < l; i++)
14395 commands[i](context);
14396 return context.isPointInPath(x, y) ? this : null;
14397 }
14398 if (x > 0 && y > 0 && x < this.width && y < this.height){
14399 return this;
14400 }
14401 return null;
14402 },
14403
14404 renderShapeTo: function(context){
14405 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
14406 return null;
14407 }
14408 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
14409 var commands = this._commands,
14410 fill = this._fill,
14411 stroke = this._stroke,
14412 dash = this._strokeDash;
14413
14414 context.beginPath();
14415
14416 if (dash) {
14417 if (context.setLineDash) {
14418 context.setLineDash(dash);
14419 } else {
14420 // TODO: Remove when FF supports setLineDash.
14421 context.mozDash = dash;
14422 }
14423 // TODO: Create fallback to other browsers.
14424 } else {
14425 if (context.setLineDash) {
14426 context.setLineDash([]);
14427 } else {
14428 context.mozDash = null;
14429 }
14430 }
14431
14432 for (var i = 0, l = commands.length; i < l; i++)
14433 commands[i](context);
14434
14435 if (fill){
14436 var m = this._fillTransform;
14437 if (m){
14438 context.save(); // TODO: Optimize away this by restoring the transform before stroking
14439 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
14440 context.fillStyle = fill;
14441 context.fill();
14442 context.restore();
14443 } else {
14444 context.fillStyle = fill;
14445 context.fill();
14446 }
14447 }
14448 if (stroke){
14449 context.strokeStyle = stroke;
14450 context.lineWidth = this._strokeWidth;
14451 context.lineCap = this._strokeCap;
14452 context.lineJoin = this._strokeJoin;
14453 context.stroke();
14454 }
14455 }
14456
14457});
14458
14459var group = _class(node, container, {
14460
14461 initialize: function(width, height){
14462 this.width = width;
14463 this.height = height;
14464 },
14465
14466 localHitTest: function(x, y){
14467 var node$$2 = this.lastChild;
14468 while (node$$2){
14469 var hit = node$$2.hitTest(x, y);
14470 if (hit) return hit;
14471 node$$2 = node$$2.previousSibling;
14472 }
14473 return null;
14474 },
14475
14476 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
14477 if (this._invisible) return;
14478
14479 x = xx * this.x + xy * this.y + x;
14480 y = yx * this.x + yy * this.y + y;
14481
14482 var t = xx;
14483 xx = t * this.xx + xy * this.yx;
14484 xy = t * this.xy + xy * this.yy;
14485 t = yx;
14486 yx = t * this.xx + yy * this.yx;
14487 yy = t * this.xy + yy * this.yy;
14488
14489 var node$$2 = this.firstChild;
14490 while (node$$2){
14491 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14492 node$$2 = node$$2.nextSibling;
14493 }
14494 }
14495
14496});
14497
14498var clippingrectangle = _class(node, container, {
14499
14500 initialize: function(width, height){
14501 this.width = width;
14502 this.height = height;
14503 },
14504
14505 localHitTest: function(x, y) {
14506 var node$$2 = this.lastChild;
14507 while (node$$2){
14508 var hit = node$$2.hitTest(x, y);
14509 if (hit) return hit;
14510 node$$2 = node$$2.previousSibling;
14511 }
14512 return null;
14513 },
14514
14515 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
14516 context.setTransform(xx, yx, xy, yy, x, y);
14517 context.save();
14518 // Need beginPath to fix Firefox bug. See 3354054.
14519 context.beginPath();
14520 context.rect(this.x, this.y, this.width, this.height);
14521 context.clip();
14522
14523 var node$$2 = this.firstChild;
14524 while(node$$2) {
14525 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14526 node$$2 = node$$2.nextSibling;
14527 }
14528 context.restore();
14529 }
14530});
14531
14532var fontAnchors = { middle: 'center' };
14533
14534var text = _class(base, {
14535
14536 base_initialize: base.prototype.initialize,
14537
14538 initialize: function(text, font, alignment, path){
14539 this.base_initialize();
14540 this.draw.apply(this, arguments);
14541 },
14542
14543 draw: function(text, font, alignment, path){
14544 var em;
14545 if (typeof font == 'string'){
14546 em = Number(/(\d+)/.exec(font)[0]);
14547 } else if (font){
14548 em = parseFloat(font.fontSize || font['font-size'] || '12');
14549 font = (font.fontStyle || font['font-style'] || '') + ' ' +
14550 (font.fontVariant || font['font-variant'] || '') + ' ' +
14551 (font.fontWeight || font['font-weight'] || '') + ' ' +
14552 em + 'px ' +
14553 (font.fontFamily || font['font-family'] || 'Arial');
14554 } else {
14555 font = this._font;
14556 }
14557
14558 var lines = text && text.split(/\r?\n/);
14559 this._font = font;
14560 this._fontSize = em;
14561 this._text = lines;
14562 this._alignment = fontAnchors[alignment] || alignment || 'left';
14563
14564 var context = base._genericContext;
14565
14566 context.font = this._font;
14567 context.textAlign = this._alignment;
14568 context.textBaseline = 'middle';
14569
14570 lines = this._text;
14571 var l = lines.length, width = 0;
14572 for (var i = 0; i < l; i++){
14573 var w = context.measureText(lines[i]).width;
14574 if (w > width) width = w;
14575 }
14576 this.width = width;
14577 this.height = l ? l * 1.1 * em : 0;
14578 return this.invalidate();
14579 },
14580
14581 // Interaction
14582
14583 localHitTest: function(x, y){
14584 if (!this._fill) return null;
14585 if (x > 0 && y > 0 && x < this.width && y < this.height){
14586 return this;
14587 }
14588 return null;
14589 },
14590
14591 // Rendering
14592
14593 renderShapeTo: function(context){
14594 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
14595 return null;
14596 }
14597 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
14598 var fill = this._fill,
14599 stroke = this._stroke,
14600 text = this._text,
14601 dash = this._strokeDash;
14602
14603 context.font = this._font;
14604 context.textAlign = this._alignment;
14605 context.textBaseline = 'middle';
14606
14607 var em = this._fontSize,
14608 y = em / 2,
14609 lineHeight = 1.1 * em,
14610 lines = text,
14611 l = lines.length;
14612
14613 if (fill){
14614 context.fillStyle = fill;
14615 for (var i = 0; i < l; i++)
14616 context.fillText(lines[i], 0, y + i * lineHeight);
14617 }
14618 if (stroke){
14619 if (dash) {
14620 if (context.setLineDash) {
14621 context.setLineDash(dash);
14622 } else {
14623 // TODO: Remove when FF supports setLineDash.
14624 context.mozDash = dash;
14625 }
14626 // TODO: Create fallback to other browsers.
14627 } else {
14628 if (context.setLineDash) {
14629 context.setLineDash([]);
14630 } else {
14631 context.mozDash = null;
14632 }
14633 }
14634
14635 context.strokeStyle = stroke;
14636 context.lineWidth = this._strokeWidth;
14637 context.lineCap = this._strokeCap;
14638 context.lineJoin = this._strokeJoin;
14639 for (i = 0; i < l; i++)
14640 context.strokeText(lines[i], 0, y + i * lineHeight);
14641 }
14642 }
14643
14644});
14645
14646var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
14647
14648var styleSheet;
14649var styledTags = {};
14650var styleTag = function(tag){
14651 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
14652};
14653
14654var init = function(document){
14655
14656 var namespaces;
14657 try { // IE9 workaround: sometimes it throws here
14658 namespaces = document.namespaces;
14659 } catch (e) {
14660 }
14661 if (!namespaces) return false;
14662
14663 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
14664 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
14665
14666 styleSheet = document.createStyleSheet();
14667 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
14668/* styleTag('skew');
14669 styleTag('fill');
14670 styleTag('stroke');
14671 styleTag('path');
14672 styleTag('textpath');
14673 styleTag('group');*/
14674
14675 styleTag('vml');
14676
14677 return true;
14678
14679};
14680
14681var createElement = function(tag){
14682 if (!(tag in styledTags)) styleTag(tag);
14683 return document.createElement('av:' + tag);
14684};
14685
14686var dom = {
14687 init: init,
14688 createElement: createElement
14689};
14690
14691var precision = 100;
14692
14693var VMLSurface = _class(native_1, container, {
14694
14695 initialize: function VMLSurface(width, height, existingElement){
14696 this.element = existingElement || document.createElement('vml');
14697 this.containerElement = dom.createElement('group');
14698 this.element.appendChild(this.containerElement);
14699 if (width != null && height != null) this.resize(width, height);
14700 },
14701
14702 resize: function(width, height){
14703 this.width = width;
14704 this.height = height;
14705
14706 var style = this.element.style;
14707 style.pixelWidth = width;
14708 style.pixelHeight = height;
14709
14710 style = this.containerElement.style;
14711 style.width = width;
14712 style.height = height;
14713
14714 var halfPixel = (0.5 * precision);
14715
14716 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
14717 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
14718
14719 return this;
14720 }
14721
14722});
14723
14724VMLSurface.tagName = 'av:vml';
14725
14726var surface$2 = VMLSurface;
14727
14728var precision$1 = 100;
14729
14730var round = Math.round;
14731
14732var VMLPath = _class(path$2, {
14733
14734 initialize: function(path){
14735 this.reset();
14736 if (path instanceof VMLPath){
14737 this.path = [Array.prototype.join.call(path.path, ' ')];
14738 } else if (path){
14739 if (path.applyToPath)
14740 path.applyToPath(this);
14741 else
14742 this.push(path);
14743 }
14744 },
14745
14746 onReset: function(){
14747 this.path = [];
14748 },
14749
14750 onMove: function(sx, sy, x, y){
14751 this.path.push('m', round(x * precision$1), round(y * precision$1));
14752 },
14753
14754 onLine: function(sx, sy, x, y){
14755 this.path.push('l', round(x * precision$1), round(y * precision$1));
14756 },
14757
14758 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
14759 this.path.push('c',
14760 round(p1x * precision$1), round(p1y * precision$1),
14761 round(p2x * precision$1), round(p2y * precision$1),
14762 round(x * precision$1), round(y * precision$1)
14763 );
14764 },
14765
14766 _arcToBezier: path$2.prototype.onArc,
14767
14768 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
14769 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
14770 cx *= precision$1;
14771 cy *= precision$1;
14772 rx *= precision$1;
14773 this.path.push(ccw ? 'at' : 'wa',
14774 round(cx - rx), round(cy - rx),
14775 round(cx + rx), round(cy + rx),
14776 round(sx * precision$1), round(sy * precision$1),
14777 round(ex * precision$1), round(ey * precision$1)
14778 );
14779 },
14780
14781 onClose: function(){
14782 this.path.push('x');
14783 },
14784
14785 toVML: function(){
14786 return this.path.join(' ');
14787 }
14788
14789});
14790
14791VMLPath.prototype.toString = VMLPath.prototype.toVML;
14792
14793var path$4 = VMLPath;
14794
14795var shadow = _class(dummy, native_1, {
14796
14797 dummy_inject: dummy.prototype.inject,
14798 dummy_injectBefore: dummy.prototype.injectBefore,
14799 dummy_eject: dummy.prototype.eject,
14800 native_inject: native_1.prototype.inject,
14801 native_injectBefore: native_1.prototype.injectBefore,
14802 native_eject: native_1.prototype.eject,
14803
14804 inject: function(container){
14805 this.dummy_inject(container);
14806 this.native_inject(container);
14807 return this;
14808 },
14809
14810 injectBefore: function(sibling){
14811 this.dummy_injectBefore(sibling);
14812 this.native_injectBefore(sibling);
14813 return this;
14814 },
14815
14816 eject: function(){
14817 this.dummy_eject();
14818 this.native_eject();
14819 return this;
14820 }
14821
14822});
14823
14824var node$2 = _class(shadow, transform, {
14825
14826 initialize: function(tag){
14827 //this.uid = uniqueID();
14828 var element = this.element = dom.createElement(tag);
14829 //element.setAttribute('id', 'e' + this.uid);
14830 },
14831
14832 _place: function(){
14833 if (this.parentNode){
14834 this._transform();
14835 }
14836 },
14837
14838 // visibility
14839
14840 hide: function(){
14841 this.element.style.display = 'none';
14842 return this;
14843 },
14844
14845 show: function(){
14846 this.element.style.display = '';
14847 return this;
14848 },
14849
14850 // interaction
14851
14852 indicate: function(cursor, tooltip){
14853 if (cursor) this.element.style.cursor = cursor;
14854 if (tooltip) this.element.title = tooltip;
14855 return this;
14856 }
14857
14858});
14859
14860var precision$3 = 100;
14861
14862var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
14863
14864var base$2 = _class(node$2, {
14865
14866 element_initialize: node$2.prototype.initialize,
14867
14868 initialize: function(tag){
14869 this.element_initialize(tag);
14870 var element = this.element;
14871
14872 var skew = this.skewElement = dom.createElement('skew');
14873 skew.on = true;
14874 element.appendChild(skew);
14875
14876 var fill = this.fillElement = dom.createElement('fill');
14877 fill.on = false;
14878 element.appendChild(fill);
14879
14880 var stroke = this.strokeElement = dom.createElement('stroke');
14881 stroke.on = false;
14882 element.appendChild(stroke);
14883 },
14884
14885 /* transform */
14886
14887 _transform: function(){
14888 var container = this.parentNode;
14889
14890 // Active Transformation Matrix
14891 var m = container ? new transform(container._activeTransform).transform(this) : this;
14892
14893 // Box in shape user space
14894
14895 var box = this._boxCoords || this._size || defaultBox;
14896
14897 var originX = box.left || 0,
14898 originY = box.top || 0,
14899 width = box.width || 1,
14900 height = box.height || 1;
14901
14902 // Flipped
14903 var flip = m.yx / m.xx > m.yy / m.xy;
14904 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
14905 flip = flip ? -1 : 1;
14906
14907 m = new transform().scale(flip, 1).transform(m);
14908
14909 // Rotation is approximated based on the transform
14910 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
14911
14912 // Reverse the rotation, leaving the final transform in box space
14913 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
14914
14915 var transform$$2 = new transform(
14916 (m.xx * cos - m.xy * sin),
14917 (m.yx * cos - m.yy * sin) * flip,
14918 (m.xy * cos + m.xx * sin) * flip,
14919 (m.yy * cos + m.yx * sin)
14920 );
14921
14922 var rotationTransform = new transform().rotate(rotation, 0, 0);
14923
14924 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
14925
14926 // Scale box after reversing rotation
14927 width *= Math.abs(shapeToBox.xx);
14928 height *= Math.abs(shapeToBox.yy);
14929
14930 // Place box
14931 var left = m.x, top = m.y;
14932
14933 // Compensate for offset by center origin rotation
14934 var vx = -width / 2, vy = -height / 2;
14935 var point = rotationTransform.point(vx, vy);
14936 left -= point.x - vx;
14937 top -= point.y - vy;
14938
14939 // Adjust box position based on offset
14940 var rsm = new transform(m).moveTo(0,0);
14941 point = rsm.point(originX, originY);
14942 left += point.x;
14943 top += point.y;
14944
14945 if (flip < 0) left = -left - width;
14946
14947 // Place transformation origin
14948 var point0 = rsm.point(-originX, -originY);
14949 var point1 = rotationTransform.point(width, height);
14950 var point2 = rotationTransform.point(width, 0);
14951 var point3 = rotationTransform.point(0, height);
14952
14953 var minX = Math.min(0, point1.x, point2.x, point3.x),
14954 maxX = Math.max(0, point1.x, point2.x, point3.x),
14955 minY = Math.min(0, point1.y, point2.y, point3.y),
14956 maxY = Math.max(0, point1.y, point2.y, point3.y);
14957
14958 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
14959 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
14960
14961 // Adjust the origin
14962 point = shapeToBox.point(originX, originY);
14963 originX = point.x;
14964 originY = point.y;
14965
14966 // Scale stroke
14967 var strokeWidth = this._strokeWidth;
14968 if (strokeWidth){
14969 // Scale is the hypothenus between the two vectors
14970 // TODO: Use area calculation instead
14971 var vx = m.xx + m.xy, vy = m.yy + m.yx;
14972 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
14973 }
14974
14975 // convert to multiplied precision space
14976 originX *= precision$3;
14977 originY *= precision$3;
14978 left *= precision$3;
14979 top *= precision$3;
14980 width *= precision$3;
14981 height *= precision$3;
14982
14983 // Set box
14984 var element = this.element;
14985 element.coordorigin = originX + ',' + originY;
14986 element.coordsize = width + ',' + height;
14987 element.style.left = left + 'px';
14988 element.style.top = top + 'px';
14989 element.style.width = width;
14990 element.style.height = height;
14991 element.style.rotation = rotation.toFixed(8);
14992 element.style.flip = flip < 0 ? 'x' : '';
14993
14994 // Set transform
14995 var skew = this.skewElement;
14996 skew.matrix = [transform$$2.xx.toFixed(4), transform$$2.xy.toFixed(4), transform$$2.yx.toFixed(4), transform$$2.yy.toFixed(4), 0, 0];
14997 skew.origin = transformOriginX + ',' + transformOriginY;
14998
14999 // Set stroke
15000 this.strokeElement.weight = strokeWidth + 'px';
15001 },
15002
15003 /* styles */
15004
15005 _createGradient: function(style, stops){
15006 var fill = this.fillElement;
15007
15008 // Temporarily eject the fill from the DOM
15009 this.element.removeChild(fill);
15010
15011 fill.type = style;
15012 fill.method = 'none';
15013 fill.rotate = true;
15014
15015 var colors = [], color1, color2;
15016
15017 var addColor = function(offset, color$$2){
15018 color$$2 = color.detach(color$$2);
15019 if (color1 == null) color1 = color2 = color$$2;
15020 else color2 = color$$2;
15021 colors.push(offset + ' ' + color$$2[0]);
15022 };
15023
15024 // Enumerate stops, assumes offsets are enumerated in order
15025 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
15026 else for (var offset in stops) addColor(offset, stops[offset]);
15027
15028 fill.color = color1[0];
15029 fill.color2 = color2[0];
15030
15031 //if (fill.colors) fill.colors.value = colors; else
15032 fill.colors = colors;
15033
15034 // Opacity order gets flipped when color stops are specified
15035 fill.opacity = color2[1];
15036 fill['ao:opacity2'] = color1[1];
15037
15038 fill.on = true;
15039 this.element.appendChild(fill);
15040 return fill;
15041 },
15042
15043 _setColor: function(type, color$$2){
15044 var element = type == 'fill' ? this.fillElement : this.strokeElement;
15045 if (color$$2 == null){
15046 element.on = false;
15047 } else {
15048 color$$2 = color.detach(color$$2);
15049 element.color = color$$2[0];
15050 element.opacity = color$$2[1];
15051 element.on = true;
15052 }
15053 },
15054
15055 fill: function(color$$2){
15056 if (arguments.length > 1){
15057 this.fillLinear(arguments);
15058 } else {
15059 this._boxCoords = defaultBox;
15060 var fill = this.fillElement;
15061 fill.type = 'solid';
15062 fill.color2 = '';
15063 fill['ao:opacity2'] = '';
15064 if (fill.colors) fill.colors.value = '';
15065 this._setColor('fill', color$$2);
15066 }
15067 return this;
15068 },
15069
15070 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
15071 var fill = this._createGradient('gradientradial', stops);
15072 if (focusX == null) focusX = this.left + this.width * 0.5;
15073 if (focusY == null) focusY = this.top + this.height * 0.5;
15074 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
15075 if (radiusX == null) radiusX = this.width * 0.5;
15076 if (centerX == null) centerX = focusX;
15077 if (centerY == null) centerY = focusY;
15078
15079 centerX += centerX - focusX;
15080 centerY += centerY - focusY;
15081
15082 var box = this._boxCoords = {
15083 left: centerX - radiusX * 2,
15084 top: centerY - radiusY * 2,
15085 width: radiusX * 4,
15086 height: radiusY * 4
15087 };
15088 focusX -= box.left;
15089 focusY -= box.top;
15090 focusX /= box.width;
15091 focusY /= box.height;
15092
15093 fill.focussize = '0 0';
15094 fill.focusposition = focusX + ',' + focusY;
15095 fill.focus = '50%';
15096
15097 this._transform();
15098
15099 return this;
15100 },
15101
15102 fillLinear: function(stops, x1, y1, x2, y2){
15103 var fill = this._createGradient('gradient', stops);
15104 fill.focus = '100%';
15105 if (arguments.length == 5){
15106 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
15107 this._boxCoords = {
15108 left: Math.min(x1, x2),
15109 top: Math.min(y1, y2),
15110 width: w < 1 ? h : w,
15111 height: h < 1 ? w : h
15112 };
15113 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
15114 } else {
15115 this._boxCoords = null;
15116 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
15117 }
15118 this._transform();
15119 return this;
15120 },
15121
15122 fillImage: function(url, width, height, left, top, color1, color2){
15123 var fill = this.fillElement;
15124 if (color1 != null){
15125 color1 = color.detach(color1);
15126 if (color2 != null) color2 = color.detach(color2);
15127 fill.type = 'pattern';
15128 fill.color = color1[0];
15129 fill.color2 = color2 == null ? color1[0] : color2[0];
15130 fill.opacity = color2 == null ? 0 : color2[1];
15131 fill['ao:opacity2'] = color1[1];
15132 } else {
15133 fill.type = 'tile';
15134 fill.color = '';
15135 fill.color2 = '';
15136 fill.opacity = 1;
15137 fill['ao:opacity2'] = 1;
15138 }
15139 if (fill.colors) fill.colors.value = '';
15140 fill.rotate = true;
15141 fill.src = url;
15142
15143 fill.size = '1,1';
15144 fill.position = '0,0';
15145 fill.origin = '0,0';
15146 fill.aspect = 'ignore'; // ignore, atleast, atmost
15147 fill.on = true;
15148
15149 if (!left) left = 0;
15150 if (!top) top = 0;
15151 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
15152 this._transform();
15153 return this;
15154 },
15155
15156 /* stroke */
15157
15158 stroke: function(color$$2, width, cap, join){
15159 var stroke = this.strokeElement;
15160 this._strokeWidth = (width != null) ? width : 1;
15161 stroke.weight = (width != null) ? width + 'px' : 1;
15162 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
15163 stroke.joinstyle = (join != null) ? join : 'round';
15164
15165 this._setColor('stroke', color$$2);
15166 return this;
15167 }
15168
15169});
15170
15171var precision$2 = 100;
15172
15173var shape$2 = _class(base$2, {
15174
15175 base_initialize: base$2.prototype.initialize,
15176
15177 initialize: function(path, width, height){
15178 this.base_initialize('shape');
15179
15180 var p = this.pathElement = dom.createElement('path');
15181 p.gradientshapeok = true;
15182 this.element.appendChild(p);
15183
15184 this.width = width;
15185 this.height = height;
15186
15187 if (path != null) this.draw(path);
15188 },
15189
15190 // SVG to VML
15191
15192 draw: function(path, width, height){
15193
15194 if (!(path instanceof path$4)) path = new path$4(path);
15195 this._vml = path.toVML();
15196 //this._size = path.measure();
15197
15198 if (width != null) this.width = width;
15199 if (height != null) this.height = height;
15200
15201 if (!this._boxCoords) this._transform();
15202 this._redraw(this._prefix, this._suffix);
15203
15204 return this;
15205 },
15206
15207 // radial gradient workaround
15208
15209 _redraw: function(prefix, suffix){
15210 var vml = this._vml || '';
15211
15212 this._prefix = prefix;
15213 this._suffix = suffix;
15214 if (prefix){
15215 vml = [
15216 prefix, vml, suffix,
15217 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
15218 'ns e', vml, 'nf'
15219 ].join(' ');
15220 }
15221
15222 this.element.path = vml + 'e';
15223 },
15224
15225 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
15226 var fill = this._createGradient('gradientradial', stops);
15227 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
15228 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
15229 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
15230 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
15231 if (centerX == null) centerX = focusX;
15232 if (centerY == null) centerY = focusY;
15233
15234 centerX += centerX - focusX;
15235 centerY += centerY - focusY;
15236
15237 var cx = Math.round(centerX * precision$2),
15238 cy = Math.round(centerY * precision$2),
15239
15240 rx = Math.round(radiusX * 2 * precision$2),
15241 ry = Math.round(radiusY * 2 * precision$2),
15242
15243 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
15244
15245 this._redraw(
15246 // Resolve rendering bug
15247 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
15248 // Draw an ellipse around the path to force an elliptical gradient on any shape
15249 [
15250 'm', cx, cy - ry,
15251 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
15252 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
15253 ].join(' ')
15254 );
15255
15256 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
15257
15258 fill.focusposition = '0.5,0.5';
15259 fill.focussize = '0 0';
15260 fill.focus = '50%';
15261
15262 this._transform();
15263
15264 return this;
15265 }
15266
15267});
15268
15269var group$2 = _class(node$2, container, {
15270
15271 element_initialize: node$2.prototype.initialize,
15272
15273 initialize: function(width, height){
15274 this.element_initialize('group');
15275 this.width = width;
15276 this.height = height;
15277 },
15278
15279 _transform: function(){
15280 var element = this.element;
15281 element.coordorigin = '0,0';
15282 element.coordsize = '1000,1000';
15283 element.style.left = 0;
15284 element.style.top = 0;
15285 element.style.width = 1000;
15286 element.style.height = 1000;
15287 element.style.rotation = 0;
15288
15289 var container$$2 = this.parentNode;
15290 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
15291 var node = this.firstChild;
15292 while (node){
15293 node._transform();
15294 node = node.nextSibling;
15295 }
15296 }
15297
15298});
15299
15300var clippingrectangle$2 = _class(node$2, container, {
15301
15302 element_initialize: node$2.prototype.initialize,
15303
15304 initialize: function(width, height){
15305 this.element_initialize('clippingrectangle');
15306 this.width = width;
15307 this.height = height;
15308 },
15309
15310 _transform: function(){
15311 var element = this.element;
15312 element.clip = true;
15313 element.coordorigin = -this.x + ',' + (-1 * this.y);
15314 element.coordsize = this.width + ',' + this.height;
15315 // IE8 doesn't like clipBottom. Don't ask me why.
15316 // element.style.clipBottom = this.height + this.y;
15317 element.style.clipLeft = this.x;
15318 element.style.clipRight = this.width + this.x;
15319 element.style.clipTop = this.y;
15320 element.style.left = -this.x;
15321 element.style.top = -this.y;
15322 element.style.width = this.width + this.x;
15323 element.style.height = this.height + this.y;
15324 element.style.rotation = 0;
15325
15326 var container$$2 = this.parentNode;
15327 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
15328 var node = this.firstChild;
15329 while (node){
15330 node._transform();
15331 node = node.nextSibling;
15332 }
15333 }
15334
15335});
15336
15337var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
15338
15339var text$2 = _class(base$2, {
15340
15341 base_initialize: base$2.prototype.initialize,
15342
15343 initialize: function(text, font, alignment, path){
15344 this.base_initialize('shape');
15345
15346 var p = this.pathElement = dom.createElement('path');
15347 p.textpathok = true;
15348 this.element.appendChild(p);
15349
15350 p = this.textPathElement = dom.createElement("textpath");
15351 p.on = true;
15352 p.style['v-text-align'] = 'left';
15353 this.element.appendChild(p);
15354
15355 this.draw.apply(this, arguments);
15356 },
15357
15358 draw: function(text, font, alignment, path){
15359 var element = this.element,
15360 textPath = this.textPathElement,
15361 style = textPath.style;
15362
15363 textPath.string = text;
15364
15365 if (font){
15366 if (typeof font == 'string'){
15367 style.font = font;
15368 } else {
15369 for (var key in font){
15370 var ckey = key.camelCase ? key.camelCase() : key;
15371 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
15372 // NOT UNIVERSALLY SUPPORTED OPTIONS
15373 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
15374 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
15375 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
15376 else style[ckey] = font[key];
15377 }
15378 }
15379 }
15380
15381 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
15382
15383 if (path){
15384 this.currentPath = path = new path$4(path);
15385 this.element.path = path.toVML();
15386 } else if (!this.currentPath){
15387 var i = -1, offsetRows = '\n';
15388 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
15389 textPath.string = offsetRows + textPath.string;
15390 this.element.path = 'm0,0l1,0';
15391 }
15392
15393 // Measuring the bounding box is currently necessary for gradients etc.
15394
15395 // Clone element because the element is dead once it has been in the DOM
15396 element = element.cloneNode(true);
15397 style = element.style;
15398
15399 // Reset coordinates while measuring
15400 element.coordorigin = '0,0';
15401 element.coordsize = '10000,10000';
15402 style.left = '0px';
15403 style.top = '0px';
15404 style.width = '10000px';
15405 style.height = '10000px';
15406 style.rotation = 0;
15407 element.removeChild(element.firstChild); // Remove skew
15408
15409 // Inject the clone into the document
15410
15411 var canvas = new surface$2(1, 1),
15412 group = new group$2(), // Wrapping it in a group seems to alleviate some client rect weirdness
15413 body = element.ownerDocument.body;
15414
15415 canvas.inject(body);
15416 group.element.appendChild(element);
15417 group.inject(canvas);
15418
15419 var ebb = element.getBoundingClientRect(),
15420 cbb = canvas.toElement().getBoundingClientRect();
15421
15422 canvas.eject();
15423
15424 this.left = ebb.left - cbb.left;
15425 this.top = ebb.top - cbb.top;
15426 this.width = ebb.right - ebb.left;
15427 this.height = ebb.bottom - ebb.top;
15428 this.right = ebb.right - cbb.left;
15429 this.bottom = ebb.bottom - cbb.top;
15430
15431 this._transform();
15432
15433 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
15434 return this;
15435 }
15436
15437});
15438
15439var fastNoSideEffects = createCommonjsModule(function (module, exports) {
15440var hasCanvas = function(){
15441
15442 var canvas = document.createElement('canvas');
15443 return canvas && !!canvas.getContext;
15444
15445};
15446
15447if (hasCanvas()) {
15448 exports.Surface = surface;
15449 exports.Path = path;
15450 exports.Shape = shape;
15451 exports.Group = group;
15452 exports.ClippingRectangle = clippingrectangle;
15453 exports.Text = text;
15454} else {
15455 exports.Surface = surface$2;
15456 exports.Path = path$4;
15457 exports.Shape = shape$2;
15458 exports.Group = group$2;
15459 exports.ClippingRectangle = clippingrectangle$2;
15460 exports.Text = text$2;
15461
15462 var DOM$$1 = dom;
15463 if (typeof document !== 'undefined') DOM$$1.init(document);
15464}
15465});
15466
15467var fastNoSideEffects_1 = fastNoSideEffects.Surface;
15468var fastNoSideEffects_2 = fastNoSideEffects.Path;
15469var fastNoSideEffects_3 = fastNoSideEffects.Shape;
15470var fastNoSideEffects_4 = fastNoSideEffects.Group;
15471var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
15472var fastNoSideEffects_6 = fastNoSideEffects.Text;
15473
15474var _extends = _assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
15475
15476function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
15477
15478function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
15479
15480function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
15481
15482current.setCurrent(
15483// Change to 'art/modes/dom' for easier debugging via SVG
15484fastNoSideEffects);
15485
15486/** Declarative fill-type objects; API design not finalized */
15487
15488var slice = Array.prototype.slice;
15489
15490var LinearGradient = function () {
15491 function LinearGradient(stops, x1, y1, x2, y2) {
15492 _classCallCheck(this, LinearGradient);
15493
15494 this._args = slice.call(arguments);
15495 }
15496
15497 LinearGradient.prototype.applyFill = function applyFill(node) {
15498 node.fillLinear.apply(node, this._args);
15499 };
15500
15501 return LinearGradient;
15502}();
15503
15504var RadialGradient = function () {
15505 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
15506 _classCallCheck(this, RadialGradient);
15507
15508 this._args = slice.call(arguments);
15509 }
15510
15511 RadialGradient.prototype.applyFill = function applyFill(node) {
15512 node.fillRadial.apply(node, this._args);
15513 };
15514
15515 return RadialGradient;
15516}();
15517
15518var Pattern = function () {
15519 function Pattern(url, width, height, left, top) {
15520 _classCallCheck(this, Pattern);
15521
15522 this._args = slice.call(arguments);
15523 }
15524
15525 Pattern.prototype.applyFill = function applyFill(node) {
15526 node.fillImage.apply(node, this._args);
15527 };
15528
15529 return Pattern;
15530}();
15531
15532/** React Components */
15533
15534var Surface = function (_React$Component) {
15535 _inherits(Surface, _React$Component);
15536
15537 function Surface() {
15538 _classCallCheck(this, Surface);
15539
15540 return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
15541 }
15542
15543 Surface.prototype.componentDidMount = function componentDidMount() {
15544 var _props = this.props,
15545 height = _props.height,
15546 width = _props.width;
15547
15548
15549 this._surface = current.Surface(+width, +height, this._tagRef);
15550
15551 this._mountNode = createContainer(this._surface);
15552 updateContainer(this.props.children, this._mountNode, this);
15553 };
15554
15555 Surface.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
15556 var props = this.props;
15557
15558 if (props.height !== prevProps.height || props.width !== prevProps.width) {
15559 this._surface.resize(+props.width, +props.height);
15560 }
15561
15562 updateContainer(this.props.children, this._mountNode, this);
15563
15564 if (this._surface.render) {
15565 this._surface.render();
15566 }
15567 };
15568
15569 Surface.prototype.componentWillUnmount = function componentWillUnmount() {
15570 updateContainer(null, this._mountNode, this);
15571 };
15572
15573 Surface.prototype.render = function render() {
15574 var _this2 = this;
15575
15576 // This is going to be a placeholder because we don't know what it will
15577 // actually resolve to because ART may render canvas, vml or svg tags here.
15578 // We only allow a subset of properties since others might conflict with
15579 // ART's properties.
15580 var props = this.props;
15581
15582 // TODO: ART's Canvas Mode overrides surface title and cursor
15583 var Tag = current.Surface.tagName;
15584
15585 return React.createElement(Tag, {
15586 ref: function (ref) {
15587 return _this2._tagRef = ref;
15588 },
15589 accessKey: props.accessKey,
15590 className: props.className,
15591 draggable: props.draggable,
15592 role: props.role,
15593 style: props.style,
15594 tabIndex: props.tabIndex,
15595 title: props.title
15596 });
15597 };
15598
15599 return Surface;
15600}(React.Component);
15601
15602var Text = function (_React$Component2) {
15603 _inherits(Text, _React$Component2);
15604
15605 function Text(props) {
15606 _classCallCheck(this, Text);
15607
15608 // We allow reading these props. Ideally we could expose the Text node as
15609 // ref directly.
15610 var _this3 = _possibleConstructorReturn(this, _React$Component2.call(this, props));
15611
15612 ['height', 'width', 'x', 'y'].forEach(function (key) {
15613 Object.defineProperty(_this3, key, {
15614 get: function () {
15615 return this._text ? this._text[key] : undefined;
15616 }
15617 });
15618 });
15619 return _this3;
15620 }
15621
15622 Text.prototype.render = function render() {
15623 var _this4 = this;
15624
15625 // This means you can't have children that render into strings...
15626 var T = TYPES.TEXT;
15627 return React.createElement(
15628 T,
15629 _extends({}, this.props, { ref: function (t) {
15630 return _this4._text = t;
15631 } }),
15632 childrenAsString(this.props.children)
15633 );
15634 };
15635
15636 return Text;
15637}(React.Component);
15638
15639injectIntoDevTools({
15640 findFiberByHostInstance: function () {
15641 return null;
15642 },
15643 bundleType: 1,
15644 version: ReactVersion,
15645 rendererPackageName: 'react-art'
15646});
15647
15648/** API */
15649
15650var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
15651var Group = TYPES.GROUP;
15652var Shape = TYPES.SHAPE;
15653var Path = current.Path;
15654
15655
15656var ReactART = Object.freeze({
15657 ClippingRectangle: ClippingRectangle,
15658 Group: Group,
15659 Shape: Shape,
15660 Path: Path,
15661 LinearGradient: LinearGradient,
15662 Pattern: Pattern,
15663 RadialGradient: RadialGradient,
15664 Surface: Surface,
15665 Text: Text,
15666 Transform: transform
15667});
15668
15669var reactArt = ReactART;
15670
15671return reactArt;
15672
15673})));