UNPKG

555 kBJavaScriptView Raw
1/** @license React v16.8.3
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.3';
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 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
2333 Object.preventExtensions(this);
2334 }
2335 }
2336}
2337
2338// This is a constructor function, rather than a POJO constructor, still
2339// please ensure we do the following:
2340// 1) Nobody should add any instance methods on this. Instance methods can be
2341// more difficult to predict when they get optimized and they are almost
2342// never inlined properly in static compilers.
2343// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
2344// always know when it is a fiber.
2345// 3) We might want to experiment with using numeric keys since they are easier
2346// to optimize in a non-JIT environment.
2347// 4) We can easily go from a constructor to a createFiber object literal if that
2348// is faster.
2349// 5) It should be easy to port this to a C struct and keep a C implementation
2350// compatible.
2351var createFiber = function (tag, pendingProps, key, mode) {
2352 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
2353 return new FiberNode(tag, pendingProps, key, mode);
2354};
2355
2356function shouldConstruct(Component) {
2357 var prototype = Component.prototype;
2358 return !!(prototype && prototype.isReactComponent);
2359}
2360
2361function isSimpleFunctionComponent(type) {
2362 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
2363}
2364
2365function resolveLazyComponentTag(Component) {
2366 if (typeof Component === 'function') {
2367 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
2368 } else if (Component !== undefined && Component !== null) {
2369 var $$typeof = Component.$$typeof;
2370 if ($$typeof === REACT_FORWARD_REF_TYPE) {
2371 return ForwardRef;
2372 }
2373 if ($$typeof === REACT_MEMO_TYPE) {
2374 return MemoComponent;
2375 }
2376 }
2377 return IndeterminateComponent;
2378}
2379
2380// This is used to create an alternate fiber to do work on.
2381function createWorkInProgress(current, pendingProps, expirationTime) {
2382 var workInProgress = current.alternate;
2383 if (workInProgress === null) {
2384 // We use a double buffering pooling technique because we know that we'll
2385 // only ever need at most two versions of a tree. We pool the "other" unused
2386 // node that we're free to reuse. This is lazily created to avoid allocating
2387 // extra objects for things that are never updated. It also allow us to
2388 // reclaim the extra memory if needed.
2389 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
2390 workInProgress.elementType = current.elementType;
2391 workInProgress.type = current.type;
2392 workInProgress.stateNode = current.stateNode;
2393
2394 {
2395 // DEV-only fields
2396 workInProgress._debugID = current._debugID;
2397 workInProgress._debugSource = current._debugSource;
2398 workInProgress._debugOwner = current._debugOwner;
2399 }
2400
2401 workInProgress.alternate = current;
2402 current.alternate = workInProgress;
2403 } else {
2404 workInProgress.pendingProps = pendingProps;
2405
2406 // We already have an alternate.
2407 // Reset the effect tag.
2408 workInProgress.effectTag = NoEffect;
2409
2410 // The effect list is no longer valid.
2411 workInProgress.nextEffect = null;
2412 workInProgress.firstEffect = null;
2413 workInProgress.lastEffect = null;
2414
2415 if (enableProfilerTimer) {
2416 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
2417 // This prevents time from endlessly accumulating in new commits.
2418 // This has the downside of resetting values for different priority renders,
2419 // But works for yielding (the common case) and should support resuming.
2420 workInProgress.actualDuration = 0;
2421 workInProgress.actualStartTime = -1;
2422 }
2423 }
2424
2425 workInProgress.childExpirationTime = current.childExpirationTime;
2426 workInProgress.expirationTime = current.expirationTime;
2427
2428 workInProgress.child = current.child;
2429 workInProgress.memoizedProps = current.memoizedProps;
2430 workInProgress.memoizedState = current.memoizedState;
2431 workInProgress.updateQueue = current.updateQueue;
2432 workInProgress.contextDependencies = current.contextDependencies;
2433
2434 // These will be overridden during the parent's reconciliation
2435 workInProgress.sibling = current.sibling;
2436 workInProgress.index = current.index;
2437 workInProgress.ref = current.ref;
2438
2439 if (enableProfilerTimer) {
2440 workInProgress.selfBaseDuration = current.selfBaseDuration;
2441 workInProgress.treeBaseDuration = current.treeBaseDuration;
2442 }
2443
2444 return workInProgress;
2445}
2446
2447function createHostRootFiber(isConcurrent) {
2448 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
2449
2450 if (enableProfilerTimer && isDevToolsPresent) {
2451 // Always collect profile timings when DevTools are present.
2452 // This enables DevTools to start capturing timing at any point–
2453 // Without some nodes in the tree having empty base times.
2454 mode |= ProfileMode;
2455 }
2456
2457 return createFiber(HostRoot, null, null, mode);
2458}
2459
2460function createFiberFromTypeAndProps(type, // React$ElementType
2461key, pendingProps, owner, mode, expirationTime) {
2462 var fiber = void 0;
2463
2464 var fiberTag = IndeterminateComponent;
2465 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
2466 var resolvedType = type;
2467 if (typeof type === 'function') {
2468 if (shouldConstruct(type)) {
2469 fiberTag = ClassComponent;
2470 }
2471 } else if (typeof type === 'string') {
2472 fiberTag = HostComponent;
2473 } else {
2474 getTag: switch (type) {
2475 case REACT_FRAGMENT_TYPE:
2476 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
2477 case REACT_CONCURRENT_MODE_TYPE:
2478 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
2479 case REACT_STRICT_MODE_TYPE:
2480 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
2481 case REACT_PROFILER_TYPE:
2482 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
2483 case REACT_SUSPENSE_TYPE:
2484 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
2485 default:
2486 {
2487 if (typeof type === 'object' && type !== null) {
2488 switch (type.$$typeof) {
2489 case REACT_PROVIDER_TYPE:
2490 fiberTag = ContextProvider;
2491 break getTag;
2492 case REACT_CONTEXT_TYPE:
2493 // This is a consumer
2494 fiberTag = ContextConsumer;
2495 break getTag;
2496 case REACT_FORWARD_REF_TYPE:
2497 fiberTag = ForwardRef;
2498 break getTag;
2499 case REACT_MEMO_TYPE:
2500 fiberTag = MemoComponent;
2501 break getTag;
2502 case REACT_LAZY_TYPE:
2503 fiberTag = LazyComponent;
2504 resolvedType = null;
2505 break getTag;
2506 }
2507 }
2508 var info = '';
2509 {
2510 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
2511 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.';
2512 }
2513 var ownerName = owner ? getComponentName(owner.type) : null;
2514 if (ownerName) {
2515 info += '\n\nCheck the render method of `' + ownerName + '`.';
2516 }
2517 }
2518 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);
2519 }
2520 }
2521 }
2522
2523 fiber = createFiber(fiberTag, pendingProps, key, mode);
2524 fiber.elementType = type;
2525 fiber.type = resolvedType;
2526 fiber.expirationTime = expirationTime;
2527
2528 return fiber;
2529}
2530
2531function createFiberFromElement(element, mode, expirationTime) {
2532 var owner = null;
2533 {
2534 owner = element._owner;
2535 }
2536 var type = element.type;
2537 var key = element.key;
2538 var pendingProps = element.props;
2539 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
2540 {
2541 fiber._debugSource = element._source;
2542 fiber._debugOwner = element._owner;
2543 }
2544 return fiber;
2545}
2546
2547function createFiberFromFragment(elements, mode, expirationTime, key) {
2548 var fiber = createFiber(Fragment, elements, key, mode);
2549 fiber.expirationTime = expirationTime;
2550 return fiber;
2551}
2552
2553function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
2554 {
2555 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
2556 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
2557 }
2558 }
2559
2560 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
2561 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
2562 fiber.elementType = REACT_PROFILER_TYPE;
2563 fiber.type = REACT_PROFILER_TYPE;
2564 fiber.expirationTime = expirationTime;
2565
2566 return fiber;
2567}
2568
2569function createFiberFromMode(pendingProps, mode, expirationTime, key) {
2570 var fiber = createFiber(Mode, pendingProps, key, mode);
2571
2572 // TODO: The Mode fiber shouldn't have a type. It has a tag.
2573 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
2574 fiber.elementType = type;
2575 fiber.type = type;
2576
2577 fiber.expirationTime = expirationTime;
2578 return fiber;
2579}
2580
2581function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
2582 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
2583
2584 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
2585 var type = REACT_SUSPENSE_TYPE;
2586 fiber.elementType = type;
2587 fiber.type = type;
2588
2589 fiber.expirationTime = expirationTime;
2590 return fiber;
2591}
2592
2593function createFiberFromText(content, mode, expirationTime) {
2594 var fiber = createFiber(HostText, content, null, mode);
2595 fiber.expirationTime = expirationTime;
2596 return fiber;
2597}
2598
2599function createFiberFromHostInstanceForDeletion() {
2600 var fiber = createFiber(HostComponent, null, null, NoContext);
2601 // TODO: These should not need a type.
2602 fiber.elementType = 'DELETED';
2603 fiber.type = 'DELETED';
2604 return fiber;
2605}
2606
2607function createFiberFromPortal(portal, mode, expirationTime) {
2608 var pendingProps = portal.children !== null ? portal.children : [];
2609 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
2610 fiber.expirationTime = expirationTime;
2611 fiber.stateNode = {
2612 containerInfo: portal.containerInfo,
2613 pendingChildren: null, // Used by persistent updates
2614 implementation: portal.implementation
2615 };
2616 return fiber;
2617}
2618
2619// Used for stashing WIP properties to replay failed work in DEV.
2620function assignFiberPropertiesInDEV(target, source) {
2621 if (target === null) {
2622 // This Fiber's initial properties will always be overwritten.
2623 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
2624 target = createFiber(IndeterminateComponent, null, null, NoContext);
2625 }
2626
2627 // This is intentionally written as a list of all properties.
2628 // We tried to use Object.assign() instead but this is called in
2629 // the hottest path, and Object.assign() was too slow:
2630 // https://github.com/facebook/react/issues/12502
2631 // This code is DEV-only so size is not a concern.
2632
2633 target.tag = source.tag;
2634 target.key = source.key;
2635 target.elementType = source.elementType;
2636 target.type = source.type;
2637 target.stateNode = source.stateNode;
2638 target.return = source.return;
2639 target.child = source.child;
2640 target.sibling = source.sibling;
2641 target.index = source.index;
2642 target.ref = source.ref;
2643 target.pendingProps = source.pendingProps;
2644 target.memoizedProps = source.memoizedProps;
2645 target.updateQueue = source.updateQueue;
2646 target.memoizedState = source.memoizedState;
2647 target.contextDependencies = source.contextDependencies;
2648 target.mode = source.mode;
2649 target.effectTag = source.effectTag;
2650 target.nextEffect = source.nextEffect;
2651 target.firstEffect = source.firstEffect;
2652 target.lastEffect = source.lastEffect;
2653 target.expirationTime = source.expirationTime;
2654 target.childExpirationTime = source.childExpirationTime;
2655 target.alternate = source.alternate;
2656 if (enableProfilerTimer) {
2657 target.actualDuration = source.actualDuration;
2658 target.actualStartTime = source.actualStartTime;
2659 target.selfBaseDuration = source.selfBaseDuration;
2660 target.treeBaseDuration = source.treeBaseDuration;
2661 }
2662 target._debugID = source._debugID;
2663 target._debugSource = source._debugSource;
2664 target._debugOwner = source._debugOwner;
2665 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
2666 return target;
2667}
2668
2669var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2670
2671var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
2672var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
2673var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
2674var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
2675var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
2676var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
2677var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
2678var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
2679var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
2680var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2681
2682// TODO: This should be lifted into the renderer.
2683
2684
2685// The following attributes are only used by interaction tracing builds.
2686// They enable interactions to be associated with their async work,
2687// And expose interaction metadata to the React DevTools Profiler plugin.
2688// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
2689
2690
2691// Exported FiberRoot type includes all properties,
2692// To avoid requiring potentially error-prone :any casts throughout the project.
2693// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
2694// The types are defined separately within this file to ensure they stay in sync.
2695// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
2696
2697
2698function createFiberRoot(containerInfo, isConcurrent, hydrate) {
2699 // Cyclic construction. This cheats the type system right now because
2700 // stateNode is any.
2701 var uninitializedFiber = createHostRootFiber(isConcurrent);
2702
2703 var root = void 0;
2704 if (enableSchedulerTracing) {
2705 root = {
2706 current: uninitializedFiber,
2707 containerInfo: containerInfo,
2708 pendingChildren: null,
2709
2710 earliestPendingTime: NoWork,
2711 latestPendingTime: NoWork,
2712 earliestSuspendedTime: NoWork,
2713 latestSuspendedTime: NoWork,
2714 latestPingedTime: NoWork,
2715
2716 pingCache: null,
2717
2718 didError: false,
2719
2720 pendingCommitExpirationTime: NoWork,
2721 finishedWork: null,
2722 timeoutHandle: noTimeout,
2723 context: null,
2724 pendingContext: null,
2725 hydrate: hydrate,
2726 nextExpirationTimeToWorkOn: NoWork,
2727 expirationTime: NoWork,
2728 firstBatch: null,
2729 nextScheduledRoot: null,
2730
2731 interactionThreadID: unstable_getThreadID(),
2732 memoizedInteractions: new Set(),
2733 pendingInteractionMap: new Map()
2734 };
2735 } else {
2736 root = {
2737 current: uninitializedFiber,
2738 containerInfo: containerInfo,
2739 pendingChildren: null,
2740
2741 pingCache: null,
2742
2743 earliestPendingTime: NoWork,
2744 latestPendingTime: NoWork,
2745 earliestSuspendedTime: NoWork,
2746 latestSuspendedTime: NoWork,
2747 latestPingedTime: NoWork,
2748
2749 didError: false,
2750
2751 pendingCommitExpirationTime: NoWork,
2752 finishedWork: null,
2753 timeoutHandle: noTimeout,
2754 context: null,
2755 pendingContext: null,
2756 hydrate: hydrate,
2757 nextExpirationTimeToWorkOn: NoWork,
2758 expirationTime: NoWork,
2759 firstBatch: null,
2760 nextScheduledRoot: null
2761 };
2762 }
2763
2764 uninitializedFiber.stateNode = root;
2765
2766 // The reason for the way the Flow types are structured in this file,
2767 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
2768 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
2769 // $FlowFixMe Remove this :any cast and replace it with something better.
2770 return root;
2771}
2772
2773var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
2774 var funcArgs = Array.prototype.slice.call(arguments, 3);
2775 try {
2776 func.apply(context, funcArgs);
2777 } catch (error) {
2778 this.onError(error);
2779 }
2780};
2781
2782{
2783 // In DEV mode, we swap out invokeGuardedCallback for a special version
2784 // that plays more nicely with the browser's DevTools. The idea is to preserve
2785 // "Pause on exceptions" behavior. Because React wraps all user-provided
2786 // functions in invokeGuardedCallback, and the production version of
2787 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
2788 // like caught exceptions, and the DevTools won't pause unless the developer
2789 // takes the extra step of enabling pause on caught exceptions. This is
2790 // unintuitive, though, because even though React has caught the error, from
2791 // the developer's perspective, the error is uncaught.
2792 //
2793 // To preserve the expected "Pause on exceptions" behavior, we don't use a
2794 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
2795 // DOM node, and call the user-provided callback from inside an event handler
2796 // for that fake event. If the callback throws, the error is "captured" using
2797 // a global event handler. But because the error happens in a different
2798 // event loop context, it does not interrupt the normal program flow.
2799 // Effectively, this gives us try-catch behavior without actually using
2800 // try-catch. Neat!
2801
2802 // Check that the browser supports the APIs we need to implement our special
2803 // DEV version of invokeGuardedCallback
2804 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
2805 var fakeNode = document.createElement('react');
2806
2807 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
2808 // If document doesn't exist we know for sure we will crash in this method
2809 // when we call document.createEvent(). However this can cause confusing
2810 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
2811 // So we preemptively throw with a better message instead.
2812 !(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;
2813 var evt = document.createEvent('Event');
2814
2815 // Keeps track of whether the user-provided callback threw an error. We
2816 // set this to true at the beginning, then set it to false right after
2817 // calling the function. If the function errors, `didError` will never be
2818 // set to false. This strategy works even if the browser is flaky and
2819 // fails to call our global error handler, because it doesn't rely on
2820 // the error event at all.
2821 var didError = true;
2822
2823 // Keeps track of the value of window.event so that we can reset it
2824 // during the callback to let user code access window.event in the
2825 // browsers that support it.
2826 var windowEvent = window.event;
2827
2828 // Keeps track of the descriptor of window.event to restore it after event
2829 // dispatching: https://github.com/facebook/react/issues/13688
2830 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
2831
2832 // Create an event handler for our fake event. We will synchronously
2833 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
2834 // call the user-provided callback.
2835 var funcArgs = Array.prototype.slice.call(arguments, 3);
2836 function callCallback() {
2837 // We immediately remove the callback from event listeners so that
2838 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
2839 // nested call would trigger the fake event handlers of any call higher
2840 // in the stack.
2841 fakeNode.removeEventListener(evtType, callCallback, false);
2842
2843 // We check for window.hasOwnProperty('event') to prevent the
2844 // window.event assignment in both IE <= 10 as they throw an error
2845 // "Member not found" in strict mode, and in Firefox which does not
2846 // support window.event.
2847 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
2848 window.event = windowEvent;
2849 }
2850
2851 func.apply(context, funcArgs);
2852 didError = false;
2853 }
2854
2855 // Create a global error event handler. We use this to capture the value
2856 // that was thrown. It's possible that this error handler will fire more
2857 // than once; for example, if non-React code also calls `dispatchEvent`
2858 // and a handler for that event throws. We should be resilient to most of
2859 // those cases. Even if our error event handler fires more than once, the
2860 // last error event is always used. If the callback actually does error,
2861 // we know that the last error event is the correct one, because it's not
2862 // possible for anything else to have happened in between our callback
2863 // erroring and the code that follows the `dispatchEvent` call below. If
2864 // the callback doesn't error, but the error event was fired, we know to
2865 // ignore it because `didError` will be false, as described above.
2866 var error = void 0;
2867 // Use this to track whether the error event is ever called.
2868 var didSetError = false;
2869 var isCrossOriginError = false;
2870
2871 function handleWindowError(event) {
2872 error = event.error;
2873 didSetError = true;
2874 if (error === null && event.colno === 0 && event.lineno === 0) {
2875 isCrossOriginError = true;
2876 }
2877 if (event.defaultPrevented) {
2878 // Some other error handler has prevented default.
2879 // Browsers silence the error report if this happens.
2880 // We'll remember this to later decide whether to log it or not.
2881 if (error != null && typeof error === 'object') {
2882 try {
2883 error._suppressLogging = true;
2884 } catch (inner) {
2885 // Ignore.
2886 }
2887 }
2888 }
2889 }
2890
2891 // Create a fake event type.
2892 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
2893
2894 // Attach our event handlers
2895 window.addEventListener('error', handleWindowError);
2896 fakeNode.addEventListener(evtType, callCallback, false);
2897
2898 // Synchronously dispatch our fake event. If the user-provided function
2899 // errors, it will trigger our global error handler.
2900 evt.initEvent(evtType, false, false);
2901 fakeNode.dispatchEvent(evt);
2902
2903 if (windowEventDescriptor) {
2904 Object.defineProperty(window, 'event', windowEventDescriptor);
2905 }
2906
2907 if (didError) {
2908 if (!didSetError) {
2909 // The callback errored, but the error event never fired.
2910 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.');
2911 } else if (isCrossOriginError) {
2912 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.');
2913 }
2914 this.onError(error);
2915 }
2916
2917 // Remove our event listeners
2918 window.removeEventListener('error', handleWindowError);
2919 };
2920
2921 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
2922 }
2923}
2924
2925var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
2926
2927// Used by Fiber to simulate a try-catch.
2928var hasError = false;
2929var caughtError = null;
2930
2931var reporter = {
2932 onError: function (error) {
2933 hasError = true;
2934 caughtError = error;
2935 }
2936};
2937
2938/**
2939 * Call a function while guarding against errors that happens within it.
2940 * Returns an error if it throws, otherwise null.
2941 *
2942 * In production, this is implemented using a try-catch. The reason we don't
2943 * use a try-catch directly is so that we can swap out a different
2944 * implementation in DEV mode.
2945 *
2946 * @param {String} name of the guard to use for logging or debugging
2947 * @param {Function} func The function to invoke
2948 * @param {*} context The context to use when calling the function
2949 * @param {...*} args Arguments for function
2950 */
2951function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
2952 hasError = false;
2953 caughtError = null;
2954 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
2955}
2956
2957/**
2958 * Same as invokeGuardedCallback, but instead of returning an error, it stores
2959 * it in a global so it can be rethrown by `rethrowCaughtError` later.
2960 * TODO: See if caughtError and rethrowError can be unified.
2961 *
2962 * @param {String} name of the guard to use for logging or debugging
2963 * @param {Function} func The function to invoke
2964 * @param {*} context The context to use when calling the function
2965 * @param {...*} args Arguments for function
2966 */
2967
2968
2969/**
2970 * During execution of guarded functions we will capture the first error which
2971 * we will rethrow to be handled by the top level error handler.
2972 */
2973
2974
2975function hasCaughtError() {
2976 return hasError;
2977}
2978
2979function clearCaughtError() {
2980 if (hasError) {
2981 var error = caughtError;
2982 hasError = false;
2983 caughtError = null;
2984 return error;
2985 } else {
2986 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
2987 }
2988}
2989
2990/**
2991 * Forked from fbjs/warning:
2992 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2993 *
2994 * Only change is we use console.warn instead of console.error,
2995 * and do nothing when 'console' is not supported.
2996 * This really simplifies the code.
2997 * ---
2998 * Similar to invariant but only logs a warning if the condition is not met.
2999 * This can be used to log issues in development environments in critical
3000 * paths. Removing the logging code for production environments will keep the
3001 * same logic and follow the same code paths.
3002 */
3003
3004var lowPriorityWarning = function () {};
3005
3006{
3007 var printWarning$1 = function (format) {
3008 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
3009 args[_key - 1] = arguments[_key];
3010 }
3011
3012 var argIndex = 0;
3013 var message = 'Warning: ' + format.replace(/%s/g, function () {
3014 return args[argIndex++];
3015 });
3016 if (typeof console !== 'undefined') {
3017 console.warn(message);
3018 }
3019 try {
3020 // --- Welcome to debugging React ---
3021 // This error was thrown as a convenience so that you can use this stack
3022 // to find the callsite that caused this warning to fire.
3023 throw new Error(message);
3024 } catch (x) {}
3025 };
3026
3027 lowPriorityWarning = function (condition, format) {
3028 if (format === undefined) {
3029 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
3030 }
3031 if (!condition) {
3032 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
3033 args[_key2 - 2] = arguments[_key2];
3034 }
3035
3036 printWarning$1.apply(undefined, [format].concat(args));
3037 }
3038 };
3039}
3040
3041var lowPriorityWarning$1 = lowPriorityWarning;
3042
3043var ReactStrictModeWarnings = {
3044 discardPendingWarnings: function () {},
3045 flushPendingDeprecationWarnings: function () {},
3046 flushPendingUnsafeLifecycleWarnings: function () {},
3047 recordDeprecationWarnings: function (fiber, instance) {},
3048 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
3049 recordLegacyContextWarning: function (fiber, instance) {},
3050 flushLegacyContextWarning: function () {}
3051};
3052
3053{
3054 var LIFECYCLE_SUGGESTIONS = {
3055 UNSAFE_componentWillMount: 'componentDidMount',
3056 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
3057 UNSAFE_componentWillUpdate: 'componentDidUpdate'
3058 };
3059
3060 var pendingComponentWillMountWarnings = [];
3061 var pendingComponentWillReceivePropsWarnings = [];
3062 var pendingComponentWillUpdateWarnings = [];
3063 var pendingUnsafeLifecycleWarnings = new Map();
3064 var pendingLegacyContextWarning = new Map();
3065
3066 // Tracks components we have already warned about.
3067 var didWarnAboutDeprecatedLifecycles = new Set();
3068 var didWarnAboutUnsafeLifecycles = new Set();
3069 var didWarnAboutLegacyContext = new Set();
3070
3071 var setToSortedString = function (set) {
3072 var array = [];
3073 set.forEach(function (value) {
3074 array.push(value);
3075 });
3076 return array.sort().join(', ');
3077 };
3078
3079 ReactStrictModeWarnings.discardPendingWarnings = function () {
3080 pendingComponentWillMountWarnings = [];
3081 pendingComponentWillReceivePropsWarnings = [];
3082 pendingComponentWillUpdateWarnings = [];
3083 pendingUnsafeLifecycleWarnings = new Map();
3084 pendingLegacyContextWarning = new Map();
3085 };
3086
3087 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
3088 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
3089 var lifecyclesWarningMessages = [];
3090
3091 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
3092 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
3093 if (lifecycleWarnings.length > 0) {
3094 var componentNames = new Set();
3095 lifecycleWarnings.forEach(function (fiber) {
3096 componentNames.add(getComponentName(fiber.type) || 'Component');
3097 didWarnAboutUnsafeLifecycles.add(fiber.type);
3098 });
3099
3100 var formatted = lifecycle.replace('UNSAFE_', '');
3101 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
3102 var sortedComponentNames = setToSortedString(componentNames);
3103
3104 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
3105 }
3106 });
3107
3108 if (lifecyclesWarningMessages.length > 0) {
3109 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3110
3111 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'));
3112 }
3113 });
3114
3115 pendingUnsafeLifecycleWarnings = new Map();
3116 };
3117
3118 var findStrictRoot = function (fiber) {
3119 var maybeStrictRoot = null;
3120
3121 var node = fiber;
3122 while (node !== null) {
3123 if (node.mode & StrictMode) {
3124 maybeStrictRoot = node;
3125 }
3126 node = node.return;
3127 }
3128
3129 return maybeStrictRoot;
3130 };
3131
3132 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
3133 if (pendingComponentWillMountWarnings.length > 0) {
3134 var uniqueNames = new Set();
3135 pendingComponentWillMountWarnings.forEach(function (fiber) {
3136 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3137 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3138 });
3139
3140 var sortedNames = setToSortedString(uniqueNames);
3141
3142 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);
3143
3144 pendingComponentWillMountWarnings = [];
3145 }
3146
3147 if (pendingComponentWillReceivePropsWarnings.length > 0) {
3148 var _uniqueNames = new Set();
3149 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
3150 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
3151 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3152 });
3153
3154 var _sortedNames = setToSortedString(_uniqueNames);
3155
3156 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);
3157
3158 pendingComponentWillReceivePropsWarnings = [];
3159 }
3160
3161 if (pendingComponentWillUpdateWarnings.length > 0) {
3162 var _uniqueNames2 = new Set();
3163 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
3164 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
3165 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3166 });
3167
3168 var _sortedNames2 = setToSortedString(_uniqueNames2);
3169
3170 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);
3171
3172 pendingComponentWillUpdateWarnings = [];
3173 }
3174 };
3175
3176 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
3177 // Dedup strategy: Warn once per component.
3178 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
3179 return;
3180 }
3181
3182 // Don't warn about react-lifecycles-compat polyfilled components.
3183 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3184 pendingComponentWillMountWarnings.push(fiber);
3185 }
3186 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3187 pendingComponentWillReceivePropsWarnings.push(fiber);
3188 }
3189 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3190 pendingComponentWillUpdateWarnings.push(fiber);
3191 }
3192 };
3193
3194 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
3195 var strictRoot = findStrictRoot(fiber);
3196 if (strictRoot === null) {
3197 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.');
3198 return;
3199 }
3200
3201 // Dedup strategy: Warn once per component.
3202 // This is difficult to track any other way since component names
3203 // are often vague and are likely to collide between 3rd party libraries.
3204 // An expand property is probably okay to use here since it's DEV-only,
3205 // and will only be set in the event of serious warnings.
3206 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
3207 return;
3208 }
3209
3210 var warningsForRoot = void 0;
3211 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
3212 warningsForRoot = {
3213 UNSAFE_componentWillMount: [],
3214 UNSAFE_componentWillReceiveProps: [],
3215 UNSAFE_componentWillUpdate: []
3216 };
3217
3218 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
3219 } else {
3220 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
3221 }
3222
3223 var unsafeLifecycles = [];
3224 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
3225 unsafeLifecycles.push('UNSAFE_componentWillMount');
3226 }
3227 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3228 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
3229 }
3230 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
3231 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
3232 }
3233
3234 if (unsafeLifecycles.length > 0) {
3235 unsafeLifecycles.forEach(function (lifecycle) {
3236 warningsForRoot[lifecycle].push(fiber);
3237 });
3238 }
3239 };
3240
3241 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
3242 var strictRoot = findStrictRoot(fiber);
3243 if (strictRoot === null) {
3244 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.');
3245 return;
3246 }
3247
3248 // Dedup strategy: Warn once per component.
3249 if (didWarnAboutLegacyContext.has(fiber.type)) {
3250 return;
3251 }
3252
3253 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
3254
3255 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
3256 if (warningsForRoot === undefined) {
3257 warningsForRoot = [];
3258 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
3259 }
3260 warningsForRoot.push(fiber);
3261 }
3262 };
3263
3264 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
3265 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
3266 var uniqueNames = new Set();
3267 fiberArray.forEach(function (fiber) {
3268 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3269 didWarnAboutLegacyContext.add(fiber.type);
3270 });
3271
3272 var sortedNames = setToSortedString(uniqueNames);
3273 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3274
3275 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);
3276 });
3277 };
3278}
3279
3280// This lets us hook into Fiber to debug what it's doing.
3281// See https://github.com/facebook/react/pull/8033.
3282// This is not part of the public API, not even for React DevTools.
3283// You may only inject a debugTool if you work on React Fiber itself.
3284var ReactFiberInstrumentation = {
3285 debugTool: null
3286};
3287
3288var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
3289
3290// TODO: Offscreen updates should never suspend. However, a promise that
3291// suspended inside an offscreen subtree should be able to ping at the priority
3292// of the outer render.
3293
3294function markPendingPriorityLevel(root, expirationTime) {
3295 // If there's a gap between completing a failed root and retrying it,
3296 // additional updates may be scheduled. Clear `didError`, in case the update
3297 // is sufficient to fix the error.
3298 root.didError = false;
3299
3300 // Update the latest and earliest pending times
3301 var earliestPendingTime = root.earliestPendingTime;
3302 if (earliestPendingTime === NoWork) {
3303 // No other pending updates.
3304 root.earliestPendingTime = root.latestPendingTime = expirationTime;
3305 } else {
3306 if (earliestPendingTime < expirationTime) {
3307 // This is the earliest pending update.
3308 root.earliestPendingTime = expirationTime;
3309 } else {
3310 var latestPendingTime = root.latestPendingTime;
3311 if (latestPendingTime > expirationTime) {
3312 // This is the latest pending update
3313 root.latestPendingTime = expirationTime;
3314 }
3315 }
3316 }
3317 findNextExpirationTimeToWorkOn(expirationTime, root);
3318}
3319
3320function markCommittedPriorityLevels(root, earliestRemainingTime) {
3321 root.didError = false;
3322
3323 if (earliestRemainingTime === NoWork) {
3324 // Fast path. There's no remaining work. Clear everything.
3325 root.earliestPendingTime = NoWork;
3326 root.latestPendingTime = NoWork;
3327 root.earliestSuspendedTime = NoWork;
3328 root.latestSuspendedTime = NoWork;
3329 root.latestPingedTime = NoWork;
3330 findNextExpirationTimeToWorkOn(NoWork, root);
3331 return;
3332 }
3333
3334 if (earliestRemainingTime < root.latestPingedTime) {
3335 root.latestPingedTime = NoWork;
3336 }
3337
3338 // Let's see if the previous latest known pending level was just flushed.
3339 var latestPendingTime = root.latestPendingTime;
3340 if (latestPendingTime !== NoWork) {
3341 if (latestPendingTime > earliestRemainingTime) {
3342 // We've flushed all the known pending levels.
3343 root.earliestPendingTime = root.latestPendingTime = NoWork;
3344 } else {
3345 var earliestPendingTime = root.earliestPendingTime;
3346 if (earliestPendingTime > earliestRemainingTime) {
3347 // We've flushed the earliest known pending level. Set this to the
3348 // latest pending time.
3349 root.earliestPendingTime = root.latestPendingTime;
3350 }
3351 }
3352 }
3353
3354 // Now let's handle the earliest remaining level in the whole tree. We need to
3355 // decide whether to treat it as a pending level or as suspended. Check
3356 // it falls within the range of known suspended levels.
3357
3358 var earliestSuspendedTime = root.earliestSuspendedTime;
3359 if (earliestSuspendedTime === NoWork) {
3360 // There's no suspended work. Treat the earliest remaining level as a
3361 // pending level.
3362 markPendingPriorityLevel(root, earliestRemainingTime);
3363 findNextExpirationTimeToWorkOn(NoWork, root);
3364 return;
3365 }
3366
3367 var latestSuspendedTime = root.latestSuspendedTime;
3368 if (earliestRemainingTime < latestSuspendedTime) {
3369 // The earliest remaining level is later than all the suspended work. That
3370 // means we've flushed all the suspended work.
3371 root.earliestSuspendedTime = NoWork;
3372 root.latestSuspendedTime = NoWork;
3373 root.latestPingedTime = NoWork;
3374
3375 // There's no suspended work. Treat the earliest remaining level as a
3376 // pending level.
3377 markPendingPriorityLevel(root, earliestRemainingTime);
3378 findNextExpirationTimeToWorkOn(NoWork, root);
3379 return;
3380 }
3381
3382 if (earliestRemainingTime > earliestSuspendedTime) {
3383 // The earliest remaining time is earlier than all the suspended work.
3384 // Treat it as a pending update.
3385 markPendingPriorityLevel(root, earliestRemainingTime);
3386 findNextExpirationTimeToWorkOn(NoWork, root);
3387 return;
3388 }
3389
3390 // The earliest remaining time falls within the range of known suspended
3391 // levels. We should treat this as suspended work.
3392 findNextExpirationTimeToWorkOn(NoWork, root);
3393}
3394
3395function hasLowerPriorityWork(root, erroredExpirationTime) {
3396 var latestPendingTime = root.latestPendingTime;
3397 var latestSuspendedTime = root.latestSuspendedTime;
3398 var latestPingedTime = root.latestPingedTime;
3399 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
3400}
3401
3402function isPriorityLevelSuspended(root, expirationTime) {
3403 var earliestSuspendedTime = root.earliestSuspendedTime;
3404 var latestSuspendedTime = root.latestSuspendedTime;
3405 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
3406}
3407
3408function markSuspendedPriorityLevel(root, suspendedTime) {
3409 root.didError = false;
3410 clearPing(root, suspendedTime);
3411
3412 // First, check the known pending levels and update them if needed.
3413 var earliestPendingTime = root.earliestPendingTime;
3414 var latestPendingTime = root.latestPendingTime;
3415 if (earliestPendingTime === suspendedTime) {
3416 if (latestPendingTime === suspendedTime) {
3417 // Both known pending levels were suspended. Clear them.
3418 root.earliestPendingTime = root.latestPendingTime = NoWork;
3419 } else {
3420 // The earliest pending level was suspended. Clear by setting it to the
3421 // latest pending level.
3422 root.earliestPendingTime = latestPendingTime;
3423 }
3424 } else if (latestPendingTime === suspendedTime) {
3425 // The latest pending level was suspended. Clear by setting it to the
3426 // latest pending level.
3427 root.latestPendingTime = earliestPendingTime;
3428 }
3429
3430 // Finally, update the known suspended levels.
3431 var earliestSuspendedTime = root.earliestSuspendedTime;
3432 var latestSuspendedTime = root.latestSuspendedTime;
3433 if (earliestSuspendedTime === NoWork) {
3434 // No other suspended levels.
3435 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
3436 } else {
3437 if (earliestSuspendedTime < suspendedTime) {
3438 // This is the earliest suspended level.
3439 root.earliestSuspendedTime = suspendedTime;
3440 } else if (latestSuspendedTime > suspendedTime) {
3441 // This is the latest suspended level
3442 root.latestSuspendedTime = suspendedTime;
3443 }
3444 }
3445
3446 findNextExpirationTimeToWorkOn(suspendedTime, root);
3447}
3448
3449function markPingedPriorityLevel(root, pingedTime) {
3450 root.didError = false;
3451
3452 // TODO: When we add back resuming, we need to ensure the progressed work
3453 // is thrown out and not reused during the restarted render. One way to
3454 // invalidate the progressed work is to restart at expirationTime + 1.
3455 var latestPingedTime = root.latestPingedTime;
3456 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
3457 root.latestPingedTime = pingedTime;
3458 }
3459 findNextExpirationTimeToWorkOn(pingedTime, root);
3460}
3461
3462function clearPing(root, completedTime) {
3463 var latestPingedTime = root.latestPingedTime;
3464 if (latestPingedTime >= completedTime) {
3465 root.latestPingedTime = NoWork;
3466 }
3467}
3468
3469function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
3470 var earliestExpirationTime = renderExpirationTime;
3471
3472 var earliestPendingTime = root.earliestPendingTime;
3473 var earliestSuspendedTime = root.earliestSuspendedTime;
3474 if (earliestPendingTime > earliestExpirationTime) {
3475 earliestExpirationTime = earliestPendingTime;
3476 }
3477 if (earliestSuspendedTime > earliestExpirationTime) {
3478 earliestExpirationTime = earliestSuspendedTime;
3479 }
3480 return earliestExpirationTime;
3481}
3482
3483function didExpireAtExpirationTime(root, currentTime) {
3484 var expirationTime = root.expirationTime;
3485 if (expirationTime !== NoWork && currentTime <= expirationTime) {
3486 // The root has expired. Flush all work up to the current time.
3487 root.nextExpirationTimeToWorkOn = currentTime;
3488 }
3489}
3490
3491function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
3492 var earliestSuspendedTime = root.earliestSuspendedTime;
3493 var latestSuspendedTime = root.latestSuspendedTime;
3494 var earliestPendingTime = root.earliestPendingTime;
3495 var latestPingedTime = root.latestPingedTime;
3496
3497 // Work on the earliest pending time. Failing that, work on the latest
3498 // pinged time.
3499 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
3500
3501 // If there is no pending or pinged work, check if there's suspended work
3502 // that's lower priority than what we just completed.
3503 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
3504 // The lowest priority suspended work is the work most likely to be
3505 // committed next. Let's start rendering it again, so that if it times out,
3506 // it's ready to commit.
3507 nextExpirationTimeToWorkOn = latestSuspendedTime;
3508 }
3509
3510 var expirationTime = nextExpirationTimeToWorkOn;
3511 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
3512 // Expire using the earliest known expiration time.
3513 expirationTime = earliestSuspendedTime;
3514 }
3515
3516 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
3517 root.expirationTime = expirationTime;
3518}
3519
3520/**
3521 * Similar to invariant but only logs a warning if the condition is not met.
3522 * This can be used to log issues in development environments in critical
3523 * paths. Removing the logging code for production environments will keep the
3524 * same logic and follow the same code paths.
3525 */
3526
3527var warning = warningWithoutStack$1;
3528
3529{
3530 warning = function (condition, format) {
3531 if (condition) {
3532 return;
3533 }
3534 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
3535 var stack = ReactDebugCurrentFrame.getStackAddendum();
3536 // eslint-disable-next-line react-internal/warning-and-invariant-args
3537
3538 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
3539 args[_key - 2] = arguments[_key];
3540 }
3541
3542 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
3543 };
3544}
3545
3546var warning$1 = warning;
3547
3548/**
3549 * inlined Object.is polyfill to avoid requiring consumers ship their own
3550 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3551 */
3552function is(x, y) {
3553 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
3554 ;
3555}
3556
3557var hasOwnProperty = Object.prototype.hasOwnProperty;
3558
3559/**
3560 * Performs equality by iterating through keys on an object and returning false
3561 * when any key has values which are not strictly equal between the arguments.
3562 * Returns true when the values of all keys are strictly equal.
3563 */
3564function shallowEqual(objA, objB) {
3565 if (is(objA, objB)) {
3566 return true;
3567 }
3568
3569 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3570 return false;
3571 }
3572
3573 var keysA = Object.keys(objA);
3574 var keysB = Object.keys(objB);
3575
3576 if (keysA.length !== keysB.length) {
3577 return false;
3578 }
3579
3580 // Test for A's keys different from B.
3581 for (var i = 0; i < keysA.length; i++) {
3582 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
3583 return false;
3584 }
3585 }
3586
3587 return true;
3588}
3589
3590function resolveDefaultProps(Component, baseProps) {
3591 if (Component && Component.defaultProps) {
3592 // Resolve default props. Taken from ReactElement
3593 var props = _assign({}, baseProps);
3594 var defaultProps = Component.defaultProps;
3595 for (var propName in defaultProps) {
3596 if (props[propName] === undefined) {
3597 props[propName] = defaultProps[propName];
3598 }
3599 }
3600 return props;
3601 }
3602 return baseProps;
3603}
3604
3605function readLazyComponentType(lazyComponent) {
3606 var status = lazyComponent._status;
3607 var result = lazyComponent._result;
3608 switch (status) {
3609 case Resolved:
3610 {
3611 var Component = result;
3612 return Component;
3613 }
3614 case Rejected:
3615 {
3616 var error = result;
3617 throw error;
3618 }
3619 case Pending:
3620 {
3621 var thenable = result;
3622 throw thenable;
3623 }
3624 default:
3625 {
3626 lazyComponent._status = Pending;
3627 var ctor = lazyComponent._ctor;
3628 var _thenable = ctor();
3629 _thenable.then(function (moduleObject) {
3630 if (lazyComponent._status === Pending) {
3631 var defaultExport = moduleObject.default;
3632 {
3633 if (defaultExport === undefined) {
3634 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);
3635 }
3636 }
3637 lazyComponent._status = Resolved;
3638 lazyComponent._result = defaultExport;
3639 }
3640 }, function (error) {
3641 if (lazyComponent._status === Pending) {
3642 lazyComponent._status = Rejected;
3643 lazyComponent._result = error;
3644 }
3645 });
3646 // Handle synchronous thenables.
3647 switch (lazyComponent._status) {
3648 case Resolved:
3649 return lazyComponent._result;
3650 case Rejected:
3651 throw lazyComponent._result;
3652 }
3653 lazyComponent._result = _thenable;
3654 throw _thenable;
3655 }
3656 }
3657}
3658
3659var fakeInternalInstance = {};
3660var isArray$1 = Array.isArray;
3661
3662// React.Component uses a shared frozen object by default.
3663// We'll use it to determine whether we need to initialize legacy refs.
3664var emptyRefsObject = new React.Component().refs;
3665
3666var didWarnAboutStateAssignmentForComponent = void 0;
3667var didWarnAboutUninitializedState = void 0;
3668var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
3669var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
3670var didWarnAboutUndefinedDerivedState = void 0;
3671var warnOnUndefinedDerivedState = void 0;
3672var warnOnInvalidCallback = void 0;
3673var didWarnAboutDirectlyAssigningPropsToState = void 0;
3674var didWarnAboutContextTypeAndContextTypes = void 0;
3675var didWarnAboutInvalidateContextType = void 0;
3676
3677{
3678 didWarnAboutStateAssignmentForComponent = new Set();
3679 didWarnAboutUninitializedState = new Set();
3680 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3681 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3682 didWarnAboutDirectlyAssigningPropsToState = new Set();
3683 didWarnAboutUndefinedDerivedState = new Set();
3684 didWarnAboutContextTypeAndContextTypes = new Set();
3685 didWarnAboutInvalidateContextType = new Set();
3686
3687 var didWarnOnInvalidCallback = new Set();
3688
3689 warnOnInvalidCallback = function (callback, callerName) {
3690 if (callback === null || typeof callback === 'function') {
3691 return;
3692 }
3693 var key = callerName + '_' + callback;
3694 if (!didWarnOnInvalidCallback.has(key)) {
3695 didWarnOnInvalidCallback.add(key);
3696 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3697 }
3698 };
3699
3700 warnOnUndefinedDerivedState = function (type, partialState) {
3701 if (partialState === undefined) {
3702 var componentName = getComponentName(type) || 'Component';
3703 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3704 didWarnAboutUndefinedDerivedState.add(componentName);
3705 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3706 }
3707 }
3708 };
3709
3710 // This is so gross but it's at least non-critical and can be removed if
3711 // it causes problems. This is meant to give a nicer error message for
3712 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3713 // ...)) which otherwise throws a "_processChildContext is not a function"
3714 // exception.
3715 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3716 enumerable: false,
3717 value: function () {
3718 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).');
3719 }
3720 });
3721 Object.freeze(fakeInternalInstance);
3722}
3723
3724function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3725 var prevState = workInProgress.memoizedState;
3726
3727 {
3728 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3729 // Invoke the function an extra time to help detect side-effects.
3730 getDerivedStateFromProps(nextProps, prevState);
3731 }
3732 }
3733
3734 var partialState = getDerivedStateFromProps(nextProps, prevState);
3735
3736 {
3737 warnOnUndefinedDerivedState(ctor, partialState);
3738 }
3739 // Merge the partial state and the previous state.
3740 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3741 workInProgress.memoizedState = memoizedState;
3742
3743 // Once the update queue is empty, persist the derived state onto the
3744 // base state.
3745 var updateQueue = workInProgress.updateQueue;
3746 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
3747 updateQueue.baseState = memoizedState;
3748 }
3749}
3750
3751var classComponentUpdater = {
3752 isMounted: isMounted,
3753 enqueueSetState: function (inst, payload, callback) {
3754 var fiber = get(inst);
3755 var currentTime = requestCurrentTime();
3756 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3757
3758 var update = createUpdate(expirationTime);
3759 update.payload = payload;
3760 if (callback !== undefined && callback !== null) {
3761 {
3762 warnOnInvalidCallback(callback, 'setState');
3763 }
3764 update.callback = callback;
3765 }
3766
3767 flushPassiveEffects();
3768 enqueueUpdate(fiber, update);
3769 scheduleWork(fiber, expirationTime);
3770 },
3771 enqueueReplaceState: function (inst, payload, callback) {
3772 var fiber = get(inst);
3773 var currentTime = requestCurrentTime();
3774 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3775
3776 var update = createUpdate(expirationTime);
3777 update.tag = ReplaceState;
3778 update.payload = payload;
3779
3780 if (callback !== undefined && callback !== null) {
3781 {
3782 warnOnInvalidCallback(callback, 'replaceState');
3783 }
3784 update.callback = callback;
3785 }
3786
3787 flushPassiveEffects();
3788 enqueueUpdate(fiber, update);
3789 scheduleWork(fiber, expirationTime);
3790 },
3791 enqueueForceUpdate: function (inst, callback) {
3792 var fiber = get(inst);
3793 var currentTime = requestCurrentTime();
3794 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3795
3796 var update = createUpdate(expirationTime);
3797 update.tag = ForceUpdate;
3798
3799 if (callback !== undefined && callback !== null) {
3800 {
3801 warnOnInvalidCallback(callback, 'forceUpdate');
3802 }
3803 update.callback = callback;
3804 }
3805
3806 flushPassiveEffects();
3807 enqueueUpdate(fiber, update);
3808 scheduleWork(fiber, expirationTime);
3809 }
3810};
3811
3812function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3813 var instance = workInProgress.stateNode;
3814 if (typeof instance.shouldComponentUpdate === 'function') {
3815 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3816 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3817 stopPhaseTimer();
3818
3819 {
3820 !(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;
3821 }
3822
3823 return shouldUpdate;
3824 }
3825
3826 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3827 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3828 }
3829
3830 return true;
3831}
3832
3833function checkClassInstance(workInProgress, ctor, newProps) {
3834 var instance = workInProgress.stateNode;
3835 {
3836 var name = getComponentName(ctor) || 'Component';
3837 var renderPresent = instance.render;
3838
3839 if (!renderPresent) {
3840 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3841 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3842 } else {
3843 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3844 }
3845 }
3846
3847 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
3848 !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;
3849 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
3850 !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;
3851 var noInstancePropTypes = !instance.propTypes;
3852 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
3853 var noInstanceContextType = !instance.contextType;
3854 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
3855 var noInstanceContextTypes = !instance.contextTypes;
3856 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
3857
3858 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3859 didWarnAboutContextTypeAndContextTypes.add(ctor);
3860 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3861 }
3862
3863 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
3864 !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;
3865 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3866 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');
3867 }
3868 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
3869 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
3870 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
3871 !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;
3872 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
3873 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
3874 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
3875 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
3876 var hasMutatedProps = instance.props !== newProps;
3877 !(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;
3878 var noInstanceDefaultProps = !instance.defaultProps;
3879 !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;
3880
3881 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3882 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3883 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3884 }
3885
3886 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
3887 !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;
3888 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
3889 !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;
3890 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
3891 !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;
3892 var _state = instance.state;
3893 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
3894 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
3895 }
3896 if (typeof instance.getChildContext === 'function') {
3897 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
3898 }
3899 }
3900}
3901
3902function adoptClassInstance(workInProgress, instance) {
3903 instance.updater = classComponentUpdater;
3904 workInProgress.stateNode = instance;
3905 // The instance needs access to the fiber so that it can schedule updates
3906 set(instance, workInProgress);
3907 {
3908 instance._reactInternalInstance = fakeInternalInstance;
3909 }
3910}
3911
3912function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
3913 var isLegacyContextConsumer = false;
3914 var unmaskedContext = emptyContextObject;
3915 var context = null;
3916 var contextType = ctor.contextType;
3917 if (typeof contextType === 'object' && contextType !== null) {
3918 {
3919 if (contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor)) {
3920 didWarnAboutInvalidateContextType.add(ctor);
3921 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext(). ' + 'Did you accidentally pass the Context.Provider instead?', getComponentName(ctor) || 'Component');
3922 }
3923 }
3924
3925 context = readContext(contextType);
3926 } else {
3927 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3928 var contextTypes = ctor.contextTypes;
3929 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
3930 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
3931 }
3932
3933 // Instantiate twice to help detect side-effects.
3934 {
3935 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3936 new ctor(props, context); // eslint-disable-line no-new
3937 }
3938 }
3939
3940 var instance = new ctor(props, context);
3941 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
3942 adoptClassInstance(workInProgress, instance);
3943
3944 {
3945 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
3946 var componentName = getComponentName(ctor) || 'Component';
3947 if (!didWarnAboutUninitializedState.has(componentName)) {
3948 didWarnAboutUninitializedState.add(componentName);
3949 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);
3950 }
3951 }
3952
3953 // If new component APIs are defined, "unsafe" lifecycles won't be called.
3954 // Warn about these lifecycles if they are present.
3955 // Don't warn about react-lifecycles-compat polyfilled methods though.
3956 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
3957 var foundWillMountName = null;
3958 var foundWillReceivePropsName = null;
3959 var foundWillUpdateName = null;
3960 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3961 foundWillMountName = 'componentWillMount';
3962 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
3963 foundWillMountName = 'UNSAFE_componentWillMount';
3964 }
3965 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3966 foundWillReceivePropsName = 'componentWillReceiveProps';
3967 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3968 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
3969 }
3970 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3971 foundWillUpdateName = 'componentWillUpdate';
3972 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3973 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
3974 }
3975 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
3976 var _componentName = getComponentName(ctor) || 'Component';
3977 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
3978 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
3979 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
3980 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 : '');
3981 }
3982 }
3983 }
3984 }
3985
3986 // Cache unmasked context so we can avoid recreating masked context unless necessary.
3987 // ReactFiberContext usually updates this cache but can't for newly-created instances.
3988 if (isLegacyContextConsumer) {
3989 cacheContext(workInProgress, unmaskedContext, context);
3990 }
3991
3992 return instance;
3993}
3994
3995function callComponentWillMount(workInProgress, instance) {
3996 startPhaseTimer(workInProgress, 'componentWillMount');
3997 var oldState = instance.state;
3998
3999 if (typeof instance.componentWillMount === 'function') {
4000 instance.componentWillMount();
4001 }
4002 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4003 instance.UNSAFE_componentWillMount();
4004 }
4005
4006 stopPhaseTimer();
4007
4008 if (oldState !== instance.state) {
4009 {
4010 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');
4011 }
4012 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4013 }
4014}
4015
4016function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4017 var oldState = instance.state;
4018 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4019 if (typeof instance.componentWillReceiveProps === 'function') {
4020 instance.componentWillReceiveProps(newProps, nextContext);
4021 }
4022 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4023 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4024 }
4025 stopPhaseTimer();
4026
4027 if (instance.state !== oldState) {
4028 {
4029 var componentName = getComponentName(workInProgress.type) || 'Component';
4030 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4031 didWarnAboutStateAssignmentForComponent.add(componentName);
4032 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4033 }
4034 }
4035 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4036 }
4037}
4038
4039// Invokes the mount life-cycles on a previously never rendered instance.
4040function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4041 {
4042 checkClassInstance(workInProgress, ctor, newProps);
4043 }
4044
4045 var instance = workInProgress.stateNode;
4046 instance.props = newProps;
4047 instance.state = workInProgress.memoizedState;
4048 instance.refs = emptyRefsObject;
4049
4050 var contextType = ctor.contextType;
4051 if (typeof contextType === 'object' && contextType !== null) {
4052 instance.context = readContext(contextType);
4053 } else {
4054 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4055 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4056 }
4057
4058 {
4059 if (instance.state === newProps) {
4060 var componentName = getComponentName(ctor) || 'Component';
4061 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4062 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4063 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);
4064 }
4065 }
4066
4067 if (workInProgress.mode & StrictMode) {
4068 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4069
4070 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4071 }
4072
4073 if (warnAboutDeprecatedLifecycles) {
4074 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
4075 }
4076 }
4077
4078 var updateQueue = workInProgress.updateQueue;
4079 if (updateQueue !== null) {
4080 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4081 instance.state = workInProgress.memoizedState;
4082 }
4083
4084 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4085 if (typeof getDerivedStateFromProps === 'function') {
4086 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4087 instance.state = workInProgress.memoizedState;
4088 }
4089
4090 // In order to support react-lifecycles-compat polyfilled components,
4091 // Unsafe lifecycles should not be invoked for components using the new APIs.
4092 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4093 callComponentWillMount(workInProgress, instance);
4094 // If we had additional state updates during this life-cycle, let's
4095 // process them now.
4096 updateQueue = workInProgress.updateQueue;
4097 if (updateQueue !== null) {
4098 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4099 instance.state = workInProgress.memoizedState;
4100 }
4101 }
4102
4103 if (typeof instance.componentDidMount === 'function') {
4104 workInProgress.effectTag |= Update;
4105 }
4106}
4107
4108function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4109 var instance = workInProgress.stateNode;
4110
4111 var oldProps = workInProgress.memoizedProps;
4112 instance.props = oldProps;
4113
4114 var oldContext = instance.context;
4115 var contextType = ctor.contextType;
4116 var nextContext = void 0;
4117 if (typeof contextType === 'object' && contextType !== null) {
4118 nextContext = readContext(contextType);
4119 } else {
4120 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4121 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4122 }
4123
4124 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4125 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4126
4127 // Note: During these life-cycles, instance.props/instance.state are what
4128 // ever the previously attempted to render - not the "current". However,
4129 // during componentDidUpdate we pass the "current" props.
4130
4131 // In order to support react-lifecycles-compat polyfilled components,
4132 // Unsafe lifecycles should not be invoked for components using the new APIs.
4133 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4134 if (oldProps !== newProps || oldContext !== nextContext) {
4135 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4136 }
4137 }
4138
4139 resetHasForceUpdateBeforeProcessing();
4140
4141 var oldState = workInProgress.memoizedState;
4142 var newState = instance.state = oldState;
4143 var updateQueue = workInProgress.updateQueue;
4144 if (updateQueue !== null) {
4145 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4146 newState = workInProgress.memoizedState;
4147 }
4148 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4149 // If an update was already in progress, we should schedule an Update
4150 // effect even though we're bailing out, so that cWU/cDU are called.
4151 if (typeof instance.componentDidMount === 'function') {
4152 workInProgress.effectTag |= Update;
4153 }
4154 return false;
4155 }
4156
4157 if (typeof getDerivedStateFromProps === 'function') {
4158 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4159 newState = workInProgress.memoizedState;
4160 }
4161
4162 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4163
4164 if (shouldUpdate) {
4165 // In order to support react-lifecycles-compat polyfilled components,
4166 // Unsafe lifecycles should not be invoked for components using the new APIs.
4167 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4168 startPhaseTimer(workInProgress, 'componentWillMount');
4169 if (typeof instance.componentWillMount === 'function') {
4170 instance.componentWillMount();
4171 }
4172 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4173 instance.UNSAFE_componentWillMount();
4174 }
4175 stopPhaseTimer();
4176 }
4177 if (typeof instance.componentDidMount === 'function') {
4178 workInProgress.effectTag |= Update;
4179 }
4180 } else {
4181 // If an update was already in progress, we should schedule an Update
4182 // effect even though we're bailing out, so that cWU/cDU are called.
4183 if (typeof instance.componentDidMount === 'function') {
4184 workInProgress.effectTag |= Update;
4185 }
4186
4187 // If shouldComponentUpdate returned false, we should still update the
4188 // memoized state to indicate that this work can be reused.
4189 workInProgress.memoizedProps = newProps;
4190 workInProgress.memoizedState = newState;
4191 }
4192
4193 // Update the existing instance's state, props, and context pointers even
4194 // if shouldComponentUpdate returns false.
4195 instance.props = newProps;
4196 instance.state = newState;
4197 instance.context = nextContext;
4198
4199 return shouldUpdate;
4200}
4201
4202// Invokes the update life-cycles and returns false if it shouldn't rerender.
4203function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4204 var instance = workInProgress.stateNode;
4205
4206 var oldProps = workInProgress.memoizedProps;
4207 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4208
4209 var oldContext = instance.context;
4210 var contextType = ctor.contextType;
4211 var nextContext = void 0;
4212 if (typeof contextType === 'object' && contextType !== null) {
4213 nextContext = readContext(contextType);
4214 } else {
4215 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4216 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4217 }
4218
4219 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4220 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4221
4222 // Note: During these life-cycles, instance.props/instance.state are what
4223 // ever the previously attempted to render - not the "current". However,
4224 // during componentDidUpdate we pass the "current" props.
4225
4226 // In order to support react-lifecycles-compat polyfilled components,
4227 // Unsafe lifecycles should not be invoked for components using the new APIs.
4228 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4229 if (oldProps !== newProps || oldContext !== nextContext) {
4230 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4231 }
4232 }
4233
4234 resetHasForceUpdateBeforeProcessing();
4235
4236 var oldState = workInProgress.memoizedState;
4237 var newState = instance.state = oldState;
4238 var updateQueue = workInProgress.updateQueue;
4239 if (updateQueue !== null) {
4240 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4241 newState = workInProgress.memoizedState;
4242 }
4243
4244 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4245 // If an update was already in progress, we should schedule an Update
4246 // effect even though we're bailing out, so that cWU/cDU are called.
4247 if (typeof instance.componentDidUpdate === 'function') {
4248 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4249 workInProgress.effectTag |= Update;
4250 }
4251 }
4252 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4253 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4254 workInProgress.effectTag |= Snapshot;
4255 }
4256 }
4257 return false;
4258 }
4259
4260 if (typeof getDerivedStateFromProps === 'function') {
4261 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4262 newState = workInProgress.memoizedState;
4263 }
4264
4265 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4266
4267 if (shouldUpdate) {
4268 // In order to support react-lifecycles-compat polyfilled components,
4269 // Unsafe lifecycles should not be invoked for components using the new APIs.
4270 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4271 startPhaseTimer(workInProgress, 'componentWillUpdate');
4272 if (typeof instance.componentWillUpdate === 'function') {
4273 instance.componentWillUpdate(newProps, newState, nextContext);
4274 }
4275 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4276 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4277 }
4278 stopPhaseTimer();
4279 }
4280 if (typeof instance.componentDidUpdate === 'function') {
4281 workInProgress.effectTag |= Update;
4282 }
4283 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4284 workInProgress.effectTag |= Snapshot;
4285 }
4286 } else {
4287 // If an update was already in progress, we should schedule an Update
4288 // effect even though we're bailing out, so that cWU/cDU are called.
4289 if (typeof instance.componentDidUpdate === 'function') {
4290 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4291 workInProgress.effectTag |= Update;
4292 }
4293 }
4294 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4295 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4296 workInProgress.effectTag |= Snapshot;
4297 }
4298 }
4299
4300 // If shouldComponentUpdate returned false, we should still update the
4301 // memoized props/state to indicate that this work can be reused.
4302 workInProgress.memoizedProps = newProps;
4303 workInProgress.memoizedState = newState;
4304 }
4305
4306 // Update the existing instance's state, props, and context pointers even
4307 // if shouldComponentUpdate returns false.
4308 instance.props = newProps;
4309 instance.state = newState;
4310 instance.context = nextContext;
4311
4312 return shouldUpdate;
4313}
4314
4315var didWarnAboutMaps = void 0;
4316var didWarnAboutGenerators = void 0;
4317var didWarnAboutStringRefInStrictMode = void 0;
4318var ownerHasKeyUseWarning = void 0;
4319var ownerHasFunctionTypeWarning = void 0;
4320var warnForMissingKey = function (child) {};
4321
4322{
4323 didWarnAboutMaps = false;
4324 didWarnAboutGenerators = false;
4325 didWarnAboutStringRefInStrictMode = {};
4326
4327 /**
4328 * Warn if there's no key explicitly set on dynamic arrays of children or
4329 * object keys are not valid. This allows us to keep track of children between
4330 * updates.
4331 */
4332 ownerHasKeyUseWarning = {};
4333 ownerHasFunctionTypeWarning = {};
4334
4335 warnForMissingKey = function (child) {
4336 if (child === null || typeof child !== 'object') {
4337 return;
4338 }
4339 if (!child._store || child._store.validated || child.key != null) {
4340 return;
4341 }
4342 !(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;
4343 child._store.validated = true;
4344
4345 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4346 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4347 return;
4348 }
4349 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4350
4351 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4352 };
4353}
4354
4355var isArray = Array.isArray;
4356
4357function coerceRef(returnFiber, current, element) {
4358 var mixedRef = element.ref;
4359 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4360 {
4361 if (returnFiber.mode & StrictMode) {
4362 var componentName = getComponentName(returnFiber.type) || 'Component';
4363 if (!didWarnAboutStringRefInStrictMode[componentName]) {
4364 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));
4365 didWarnAboutStringRefInStrictMode[componentName] = true;
4366 }
4367 }
4368 }
4369
4370 if (element._owner) {
4371 var owner = element._owner;
4372 var inst = void 0;
4373 if (owner) {
4374 var ownerFiber = owner;
4375 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
4376 inst = ownerFiber.stateNode;
4377 }
4378 !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;
4379 var stringRef = '' + mixedRef;
4380 // Check if previous string ref matches new string ref
4381 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4382 return current.ref;
4383 }
4384 var ref = function (value) {
4385 var refs = inst.refs;
4386 if (refs === emptyRefsObject) {
4387 // This is a lazy pooled frozen object, so we need to initialize.
4388 refs = inst.refs = {};
4389 }
4390 if (value === null) {
4391 delete refs[stringRef];
4392 } else {
4393 refs[stringRef] = value;
4394 }
4395 };
4396 ref._stringRef = stringRef;
4397 return ref;
4398 } else {
4399 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
4400 !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;
4401 }
4402 }
4403 return mixedRef;
4404}
4405
4406function throwOnInvalidObjectType(returnFiber, newChild) {
4407 if (returnFiber.type !== 'textarea') {
4408 var addendum = '';
4409 {
4410 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4411 }
4412 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);
4413 }
4414}
4415
4416function warnOnFunctionType() {
4417 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();
4418
4419 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4420 return;
4421 }
4422 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4423
4424 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.');
4425}
4426
4427// This wrapper function exists because I expect to clone the code in each path
4428// to be able to optimize each path individually by branching early. This needs
4429// a compiler or we can do it manually. Helpers that don't need this branching
4430// live outside of this function.
4431function ChildReconciler(shouldTrackSideEffects) {
4432 function deleteChild(returnFiber, childToDelete) {
4433 if (!shouldTrackSideEffects) {
4434 // Noop.
4435 return;
4436 }
4437 // Deletions are added in reversed order so we add it to the front.
4438 // At this point, the return fiber's effect list is empty except for
4439 // deletions, so we can just append the deletion to the list. The remaining
4440 // effects aren't added until the complete phase. Once we implement
4441 // resuming, this may not be true.
4442 var last = returnFiber.lastEffect;
4443 if (last !== null) {
4444 last.nextEffect = childToDelete;
4445 returnFiber.lastEffect = childToDelete;
4446 } else {
4447 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4448 }
4449 childToDelete.nextEffect = null;
4450 childToDelete.effectTag = Deletion;
4451 }
4452
4453 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4454 if (!shouldTrackSideEffects) {
4455 // Noop.
4456 return null;
4457 }
4458
4459 // TODO: For the shouldClone case, this could be micro-optimized a bit by
4460 // assuming that after the first child we've already added everything.
4461 var childToDelete = currentFirstChild;
4462 while (childToDelete !== null) {
4463 deleteChild(returnFiber, childToDelete);
4464 childToDelete = childToDelete.sibling;
4465 }
4466 return null;
4467 }
4468
4469 function mapRemainingChildren(returnFiber, currentFirstChild) {
4470 // Add the remaining children to a temporary map so that we can find them by
4471 // keys quickly. Implicit (null) keys get added to this set with their index
4472 var existingChildren = new Map();
4473
4474 var existingChild = currentFirstChild;
4475 while (existingChild !== null) {
4476 if (existingChild.key !== null) {
4477 existingChildren.set(existingChild.key, existingChild);
4478 } else {
4479 existingChildren.set(existingChild.index, existingChild);
4480 }
4481 existingChild = existingChild.sibling;
4482 }
4483 return existingChildren;
4484 }
4485
4486 function useFiber(fiber, pendingProps, expirationTime) {
4487 // We currently set sibling to null and index to 0 here because it is easy
4488 // to forget to do before returning it. E.g. for the single child case.
4489 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
4490 clone.index = 0;
4491 clone.sibling = null;
4492 return clone;
4493 }
4494
4495 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4496 newFiber.index = newIndex;
4497 if (!shouldTrackSideEffects) {
4498 // Noop.
4499 return lastPlacedIndex;
4500 }
4501 var current = newFiber.alternate;
4502 if (current !== null) {
4503 var oldIndex = current.index;
4504 if (oldIndex < lastPlacedIndex) {
4505 // This is a move.
4506 newFiber.effectTag = Placement;
4507 return lastPlacedIndex;
4508 } else {
4509 // This item can stay in place.
4510 return oldIndex;
4511 }
4512 } else {
4513 // This is an insertion.
4514 newFiber.effectTag = Placement;
4515 return lastPlacedIndex;
4516 }
4517 }
4518
4519 function placeSingleChild(newFiber) {
4520 // This is simpler for the single child case. We only need to do a
4521 // placement for inserting new children.
4522 if (shouldTrackSideEffects && newFiber.alternate === null) {
4523 newFiber.effectTag = Placement;
4524 }
4525 return newFiber;
4526 }
4527
4528 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4529 if (current === null || current.tag !== HostText) {
4530 // Insert
4531 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4532 created.return = returnFiber;
4533 return created;
4534 } else {
4535 // Update
4536 var existing = useFiber(current, textContent, expirationTime);
4537 existing.return = returnFiber;
4538 return existing;
4539 }
4540 }
4541
4542 function updateElement(returnFiber, current, element, expirationTime) {
4543 if (current !== null && current.elementType === element.type) {
4544 // Move based on index
4545 var existing = useFiber(current, element.props, expirationTime);
4546 existing.ref = coerceRef(returnFiber, current, element);
4547 existing.return = returnFiber;
4548 {
4549 existing._debugSource = element._source;
4550 existing._debugOwner = element._owner;
4551 }
4552 return existing;
4553 } else {
4554 // Insert
4555 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4556 created.ref = coerceRef(returnFiber, current, element);
4557 created.return = returnFiber;
4558 return created;
4559 }
4560 }
4561
4562 function updatePortal(returnFiber, current, portal, expirationTime) {
4563 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4564 // Insert
4565 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4566 created.return = returnFiber;
4567 return created;
4568 } else {
4569 // Update
4570 var existing = useFiber(current, portal.children || [], expirationTime);
4571 existing.return = returnFiber;
4572 return existing;
4573 }
4574 }
4575
4576 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4577 if (current === null || current.tag !== Fragment) {
4578 // Insert
4579 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4580 created.return = returnFiber;
4581 return created;
4582 } else {
4583 // Update
4584 var existing = useFiber(current, fragment, expirationTime);
4585 existing.return = returnFiber;
4586 return existing;
4587 }
4588 }
4589
4590 function createChild(returnFiber, newChild, expirationTime) {
4591 if (typeof newChild === 'string' || typeof newChild === 'number') {
4592 // Text nodes don't have keys. If the previous node is implicitly keyed
4593 // we can continue to replace it without aborting even if it is not a text
4594 // node.
4595 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4596 created.return = returnFiber;
4597 return created;
4598 }
4599
4600 if (typeof newChild === 'object' && newChild !== null) {
4601 switch (newChild.$$typeof) {
4602 case REACT_ELEMENT_TYPE:
4603 {
4604 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4605 _created.ref = coerceRef(returnFiber, null, newChild);
4606 _created.return = returnFiber;
4607 return _created;
4608 }
4609 case REACT_PORTAL_TYPE:
4610 {
4611 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4612 _created2.return = returnFiber;
4613 return _created2;
4614 }
4615 }
4616
4617 if (isArray(newChild) || getIteratorFn(newChild)) {
4618 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4619 _created3.return = returnFiber;
4620 return _created3;
4621 }
4622
4623 throwOnInvalidObjectType(returnFiber, newChild);
4624 }
4625
4626 {
4627 if (typeof newChild === 'function') {
4628 warnOnFunctionType();
4629 }
4630 }
4631
4632 return null;
4633 }
4634
4635 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4636 // Update the fiber if the keys match, otherwise return null.
4637
4638 var key = oldFiber !== null ? oldFiber.key : null;
4639
4640 if (typeof newChild === 'string' || typeof newChild === 'number') {
4641 // Text nodes don't have keys. If the previous node is implicitly keyed
4642 // we can continue to replace it without aborting even if it is not a text
4643 // node.
4644 if (key !== null) {
4645 return null;
4646 }
4647 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4648 }
4649
4650 if (typeof newChild === 'object' && newChild !== null) {
4651 switch (newChild.$$typeof) {
4652 case REACT_ELEMENT_TYPE:
4653 {
4654 if (newChild.key === key) {
4655 if (newChild.type === REACT_FRAGMENT_TYPE) {
4656 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4657 }
4658 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4659 } else {
4660 return null;
4661 }
4662 }
4663 case REACT_PORTAL_TYPE:
4664 {
4665 if (newChild.key === key) {
4666 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4667 } else {
4668 return null;
4669 }
4670 }
4671 }
4672
4673 if (isArray(newChild) || getIteratorFn(newChild)) {
4674 if (key !== null) {
4675 return null;
4676 }
4677
4678 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4679 }
4680
4681 throwOnInvalidObjectType(returnFiber, newChild);
4682 }
4683
4684 {
4685 if (typeof newChild === 'function') {
4686 warnOnFunctionType();
4687 }
4688 }
4689
4690 return null;
4691 }
4692
4693 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4694 if (typeof newChild === 'string' || typeof newChild === 'number') {
4695 // Text nodes don't have keys, so we neither have to check the old nor
4696 // new node for the key. If both are text nodes, they match.
4697 var matchedFiber = existingChildren.get(newIdx) || null;
4698 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4699 }
4700
4701 if (typeof newChild === 'object' && newChild !== null) {
4702 switch (newChild.$$typeof) {
4703 case REACT_ELEMENT_TYPE:
4704 {
4705 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4706 if (newChild.type === REACT_FRAGMENT_TYPE) {
4707 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4708 }
4709 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4710 }
4711 case REACT_PORTAL_TYPE:
4712 {
4713 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4714 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4715 }
4716 }
4717
4718 if (isArray(newChild) || getIteratorFn(newChild)) {
4719 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4720 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4721 }
4722
4723 throwOnInvalidObjectType(returnFiber, newChild);
4724 }
4725
4726 {
4727 if (typeof newChild === 'function') {
4728 warnOnFunctionType();
4729 }
4730 }
4731
4732 return null;
4733 }
4734
4735 /**
4736 * Warns if there is a duplicate or missing key
4737 */
4738 function warnOnInvalidKey(child, knownKeys) {
4739 {
4740 if (typeof child !== 'object' || child === null) {
4741 return knownKeys;
4742 }
4743 switch (child.$$typeof) {
4744 case REACT_ELEMENT_TYPE:
4745 case REACT_PORTAL_TYPE:
4746 warnForMissingKey(child);
4747 var key = child.key;
4748 if (typeof key !== 'string') {
4749 break;
4750 }
4751 if (knownKeys === null) {
4752 knownKeys = new Set();
4753 knownKeys.add(key);
4754 break;
4755 }
4756 if (!knownKeys.has(key)) {
4757 knownKeys.add(key);
4758 break;
4759 }
4760 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);
4761 break;
4762 default:
4763 break;
4764 }
4765 }
4766 return knownKeys;
4767 }
4768
4769 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4770 // This algorithm can't optimize by searching from both ends since we
4771 // don't have backpointers on fibers. I'm trying to see how far we can get
4772 // with that model. If it ends up not being worth the tradeoffs, we can
4773 // add it later.
4774
4775 // Even with a two ended optimization, we'd want to optimize for the case
4776 // where there are few changes and brute force the comparison instead of
4777 // going for the Map. It'd like to explore hitting that path first in
4778 // forward-only mode and only go for the Map once we notice that we need
4779 // lots of look ahead. This doesn't handle reversal as well as two ended
4780 // search but that's unusual. Besides, for the two ended optimization to
4781 // work on Iterables, we'd need to copy the whole set.
4782
4783 // In this first iteration, we'll just live with hitting the bad case
4784 // (adding everything to a Map) in for every insert/move.
4785
4786 // If you change this code, also update reconcileChildrenIterator() which
4787 // uses the same algorithm.
4788
4789 {
4790 // First, validate keys.
4791 var knownKeys = null;
4792 for (var i = 0; i < newChildren.length; i++) {
4793 var child = newChildren[i];
4794 knownKeys = warnOnInvalidKey(child, knownKeys);
4795 }
4796 }
4797
4798 var resultingFirstChild = null;
4799 var previousNewFiber = null;
4800
4801 var oldFiber = currentFirstChild;
4802 var lastPlacedIndex = 0;
4803 var newIdx = 0;
4804 var nextOldFiber = null;
4805 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4806 if (oldFiber.index > newIdx) {
4807 nextOldFiber = oldFiber;
4808 oldFiber = null;
4809 } else {
4810 nextOldFiber = oldFiber.sibling;
4811 }
4812 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4813 if (newFiber === null) {
4814 // TODO: This breaks on empty slots like null children. That's
4815 // unfortunate because it triggers the slow path all the time. We need
4816 // a better way to communicate whether this was a miss or null,
4817 // boolean, undefined, etc.
4818 if (oldFiber === null) {
4819 oldFiber = nextOldFiber;
4820 }
4821 break;
4822 }
4823 if (shouldTrackSideEffects) {
4824 if (oldFiber && newFiber.alternate === null) {
4825 // We matched the slot, but we didn't reuse the existing fiber, so we
4826 // need to delete the existing child.
4827 deleteChild(returnFiber, oldFiber);
4828 }
4829 }
4830 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4831 if (previousNewFiber === null) {
4832 // TODO: Move out of the loop. This only happens for the first run.
4833 resultingFirstChild = newFiber;
4834 } else {
4835 // TODO: Defer siblings if we're not at the right index for this slot.
4836 // I.e. if we had null values before, then we want to defer this
4837 // for each null value. However, we also don't want to call updateSlot
4838 // with the previous one.
4839 previousNewFiber.sibling = newFiber;
4840 }
4841 previousNewFiber = newFiber;
4842 oldFiber = nextOldFiber;
4843 }
4844
4845 if (newIdx === newChildren.length) {
4846 // We've reached the end of the new children. We can delete the rest.
4847 deleteRemainingChildren(returnFiber, oldFiber);
4848 return resultingFirstChild;
4849 }
4850
4851 if (oldFiber === null) {
4852 // If we don't have any more existing children we can choose a fast path
4853 // since the rest will all be insertions.
4854 for (; newIdx < newChildren.length; newIdx++) {
4855 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
4856 if (!_newFiber) {
4857 continue;
4858 }
4859 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
4860 if (previousNewFiber === null) {
4861 // TODO: Move out of the loop. This only happens for the first run.
4862 resultingFirstChild = _newFiber;
4863 } else {
4864 previousNewFiber.sibling = _newFiber;
4865 }
4866 previousNewFiber = _newFiber;
4867 }
4868 return resultingFirstChild;
4869 }
4870
4871 // Add all children to a key map for quick lookups.
4872 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
4873
4874 // Keep scanning and use the map to restore deleted items as moves.
4875 for (; newIdx < newChildren.length; newIdx++) {
4876 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
4877 if (_newFiber2) {
4878 if (shouldTrackSideEffects) {
4879 if (_newFiber2.alternate !== null) {
4880 // The new fiber is a work in progress, but if there exists a
4881 // current, that means that we reused the fiber. We need to delete
4882 // it from the child list so that we don't add it to the deletion
4883 // list.
4884 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
4885 }
4886 }
4887 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
4888 if (previousNewFiber === null) {
4889 resultingFirstChild = _newFiber2;
4890 } else {
4891 previousNewFiber.sibling = _newFiber2;
4892 }
4893 previousNewFiber = _newFiber2;
4894 }
4895 }
4896
4897 if (shouldTrackSideEffects) {
4898 // Any existing children that weren't consumed above were deleted. We need
4899 // to add them to the deletion list.
4900 existingChildren.forEach(function (child) {
4901 return deleteChild(returnFiber, child);
4902 });
4903 }
4904
4905 return resultingFirstChild;
4906 }
4907
4908 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
4909 // This is the same implementation as reconcileChildrenArray(),
4910 // but using the iterator instead.
4911
4912 var iteratorFn = getIteratorFn(newChildrenIterable);
4913 !(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;
4914
4915 {
4916 // We don't support rendering Generators because it's a mutation.
4917 // See https://github.com/facebook/react/issues/12995
4918 if (typeof Symbol === 'function' &&
4919 // $FlowFixMe Flow doesn't know about toStringTag
4920 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
4921 !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;
4922 didWarnAboutGenerators = true;
4923 }
4924
4925 // Warn about using Maps as children
4926 if (newChildrenIterable.entries === iteratorFn) {
4927 !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;
4928 didWarnAboutMaps = true;
4929 }
4930
4931 // First, validate keys.
4932 // We'll get a different iterator later for the main pass.
4933 var _newChildren = iteratorFn.call(newChildrenIterable);
4934 if (_newChildren) {
4935 var knownKeys = null;
4936 var _step = _newChildren.next();
4937 for (; !_step.done; _step = _newChildren.next()) {
4938 var child = _step.value;
4939 knownKeys = warnOnInvalidKey(child, knownKeys);
4940 }
4941 }
4942 }
4943
4944 var newChildren = iteratorFn.call(newChildrenIterable);
4945 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
4946
4947 var resultingFirstChild = null;
4948 var previousNewFiber = null;
4949
4950 var oldFiber = currentFirstChild;
4951 var lastPlacedIndex = 0;
4952 var newIdx = 0;
4953 var nextOldFiber = null;
4954
4955 var step = newChildren.next();
4956 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
4957 if (oldFiber.index > newIdx) {
4958 nextOldFiber = oldFiber;
4959 oldFiber = null;
4960 } else {
4961 nextOldFiber = oldFiber.sibling;
4962 }
4963 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
4964 if (newFiber === null) {
4965 // TODO: This breaks on empty slots like null children. That's
4966 // unfortunate because it triggers the slow path all the time. We need
4967 // a better way to communicate whether this was a miss or null,
4968 // boolean, undefined, etc.
4969 if (!oldFiber) {
4970 oldFiber = nextOldFiber;
4971 }
4972 break;
4973 }
4974 if (shouldTrackSideEffects) {
4975 if (oldFiber && newFiber.alternate === null) {
4976 // We matched the slot, but we didn't reuse the existing fiber, so we
4977 // need to delete the existing child.
4978 deleteChild(returnFiber, oldFiber);
4979 }
4980 }
4981 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4982 if (previousNewFiber === null) {
4983 // TODO: Move out of the loop. This only happens for the first run.
4984 resultingFirstChild = newFiber;
4985 } else {
4986 // TODO: Defer siblings if we're not at the right index for this slot.
4987 // I.e. if we had null values before, then we want to defer this
4988 // for each null value. However, we also don't want to call updateSlot
4989 // with the previous one.
4990 previousNewFiber.sibling = newFiber;
4991 }
4992 previousNewFiber = newFiber;
4993 oldFiber = nextOldFiber;
4994 }
4995
4996 if (step.done) {
4997 // We've reached the end of the new children. We can delete the rest.
4998 deleteRemainingChildren(returnFiber, oldFiber);
4999 return resultingFirstChild;
5000 }
5001
5002 if (oldFiber === null) {
5003 // If we don't have any more existing children we can choose a fast path
5004 // since the rest will all be insertions.
5005 for (; !step.done; newIdx++, step = newChildren.next()) {
5006 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5007 if (_newFiber3 === null) {
5008 continue;
5009 }
5010 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5011 if (previousNewFiber === null) {
5012 // TODO: Move out of the loop. This only happens for the first run.
5013 resultingFirstChild = _newFiber3;
5014 } else {
5015 previousNewFiber.sibling = _newFiber3;
5016 }
5017 previousNewFiber = _newFiber3;
5018 }
5019 return resultingFirstChild;
5020 }
5021
5022 // Add all children to a key map for quick lookups.
5023 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
5024
5025 // Keep scanning and use the map to restore deleted items as moves.
5026 for (; !step.done; newIdx++, step = newChildren.next()) {
5027 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5028 if (_newFiber4 !== null) {
5029 if (shouldTrackSideEffects) {
5030 if (_newFiber4.alternate !== null) {
5031 // The new fiber is a work in progress, but if there exists a
5032 // current, that means that we reused the fiber. We need to delete
5033 // it from the child list so that we don't add it to the deletion
5034 // list.
5035 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5036 }
5037 }
5038 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5039 if (previousNewFiber === null) {
5040 resultingFirstChild = _newFiber4;
5041 } else {
5042 previousNewFiber.sibling = _newFiber4;
5043 }
5044 previousNewFiber = _newFiber4;
5045 }
5046 }
5047
5048 if (shouldTrackSideEffects) {
5049 // Any existing children that weren't consumed above were deleted. We need
5050 // to add them to the deletion list.
5051 existingChildren.forEach(function (child) {
5052 return deleteChild(returnFiber, child);
5053 });
5054 }
5055
5056 return resultingFirstChild;
5057 }
5058
5059 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5060 // There's no need to check for keys on text nodes since we don't have a
5061 // way to define them.
5062 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5063 // We already have an existing node so let's just update it and delete
5064 // the rest.
5065 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5066 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5067 existing.return = returnFiber;
5068 return existing;
5069 }
5070 // The existing first child is not a text node so we need to create one
5071 // and delete the existing ones.
5072 deleteRemainingChildren(returnFiber, currentFirstChild);
5073 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5074 created.return = returnFiber;
5075 return created;
5076 }
5077
5078 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5079 var key = element.key;
5080 var child = currentFirstChild;
5081 while (child !== null) {
5082 // TODO: If key === null and child.key === null, then this only applies to
5083 // the first item in the list.
5084 if (child.key === key) {
5085 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
5086 deleteRemainingChildren(returnFiber, child.sibling);
5087 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
5088 existing.ref = coerceRef(returnFiber, child, element);
5089 existing.return = returnFiber;
5090 {
5091 existing._debugSource = element._source;
5092 existing._debugOwner = element._owner;
5093 }
5094 return existing;
5095 } else {
5096 deleteRemainingChildren(returnFiber, child);
5097 break;
5098 }
5099 } else {
5100 deleteChild(returnFiber, child);
5101 }
5102 child = child.sibling;
5103 }
5104
5105 if (element.type === REACT_FRAGMENT_TYPE) {
5106 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5107 created.return = returnFiber;
5108 return created;
5109 } else {
5110 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5111 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5112 _created4.return = returnFiber;
5113 return _created4;
5114 }
5115 }
5116
5117 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5118 var key = portal.key;
5119 var child = currentFirstChild;
5120 while (child !== null) {
5121 // TODO: If key === null and child.key === null, then this only applies to
5122 // the first item in the list.
5123 if (child.key === key) {
5124 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5125 deleteRemainingChildren(returnFiber, child.sibling);
5126 var existing = useFiber(child, portal.children || [], expirationTime);
5127 existing.return = returnFiber;
5128 return existing;
5129 } else {
5130 deleteRemainingChildren(returnFiber, child);
5131 break;
5132 }
5133 } else {
5134 deleteChild(returnFiber, child);
5135 }
5136 child = child.sibling;
5137 }
5138
5139 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5140 created.return = returnFiber;
5141 return created;
5142 }
5143
5144 // This API will tag the children with the side-effect of the reconciliation
5145 // itself. They will be added to the side-effect list as we pass through the
5146 // children and the parent.
5147 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5148 // This function is not recursive.
5149 // If the top level item is an array, we treat it as a set of children,
5150 // not as a fragment. Nested arrays on the other hand will be treated as
5151 // fragment nodes. Recursion happens at the normal flow.
5152
5153 // Handle top level unkeyed fragments as if they were arrays.
5154 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5155 // We treat the ambiguous cases above the same.
5156 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5157 if (isUnkeyedTopLevelFragment) {
5158 newChild = newChild.props.children;
5159 }
5160
5161 // Handle object types
5162 var isObject = typeof newChild === 'object' && newChild !== null;
5163
5164 if (isObject) {
5165 switch (newChild.$$typeof) {
5166 case REACT_ELEMENT_TYPE:
5167 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5168 case REACT_PORTAL_TYPE:
5169 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5170 }
5171 }
5172
5173 if (typeof newChild === 'string' || typeof newChild === 'number') {
5174 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5175 }
5176
5177 if (isArray(newChild)) {
5178 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5179 }
5180
5181 if (getIteratorFn(newChild)) {
5182 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5183 }
5184
5185 if (isObject) {
5186 throwOnInvalidObjectType(returnFiber, newChild);
5187 }
5188
5189 {
5190 if (typeof newChild === 'function') {
5191 warnOnFunctionType();
5192 }
5193 }
5194 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5195 // If the new child is undefined, and the return fiber is a composite
5196 // component, throw an error. If Fiber return types are disabled,
5197 // we already threw above.
5198 switch (returnFiber.tag) {
5199 case ClassComponent:
5200 {
5201 {
5202 var instance = returnFiber.stateNode;
5203 if (instance.render._isMockFunction) {
5204 // We allow auto-mocks to proceed as if they're returning null.
5205 break;
5206 }
5207 }
5208 }
5209 // Intentionally fall through to the next case, which handles both
5210 // functions and classes
5211 // eslint-disable-next-lined no-fallthrough
5212 case FunctionComponent:
5213 {
5214 var Component = returnFiber.type;
5215 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');
5216 }
5217 }
5218 }
5219
5220 // Remaining cases are all treated as empty.
5221 return deleteRemainingChildren(returnFiber, currentFirstChild);
5222 }
5223
5224 return reconcileChildFibers;
5225}
5226
5227var reconcileChildFibers = ChildReconciler(true);
5228var mountChildFibers = ChildReconciler(false);
5229
5230function cloneChildFibers(current, workInProgress) {
5231 !(current === null || workInProgress.child === current.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
5232
5233 if (workInProgress.child === null) {
5234 return;
5235 }
5236
5237 var currentChild = workInProgress.child;
5238 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5239 workInProgress.child = newChild;
5240
5241 newChild.return = workInProgress;
5242 while (currentChild.sibling !== null) {
5243 currentChild = currentChild.sibling;
5244 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5245 newChild.return = workInProgress;
5246 }
5247 newChild.sibling = null;
5248}
5249
5250var NO_CONTEXT$1 = {};
5251
5252var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5253var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5254var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5255
5256function requiredContext(c) {
5257 !(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;
5258 return c;
5259}
5260
5261function getRootHostContainer() {
5262 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5263 return rootInstance;
5264}
5265
5266function pushHostContainer(fiber, nextRootInstance) {
5267 // Push current root instance onto the stack;
5268 // This allows us to reset root when portals are popped.
5269 push(rootInstanceStackCursor, nextRootInstance, fiber);
5270 // Track the context and the Fiber that provided it.
5271 // This enables us to pop only Fibers that provide unique contexts.
5272 push(contextFiberStackCursor, fiber, fiber);
5273
5274 // Finally, we need to push the host context to the stack.
5275 // However, we can't just call getRootHostContext() and push it because
5276 // we'd have a different number of entries on the stack depending on
5277 // whether getRootHostContext() throws somewhere in renderer code or not.
5278 // So we push an empty value first. This lets us safely unwind on errors.
5279 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5280 var nextRootContext = getRootHostContext(nextRootInstance);
5281 // Now that we know this function doesn't throw, replace it.
5282 pop(contextStackCursor$1, fiber);
5283 push(contextStackCursor$1, nextRootContext, fiber);
5284}
5285
5286function popHostContainer(fiber) {
5287 pop(contextStackCursor$1, fiber);
5288 pop(contextFiberStackCursor, fiber);
5289 pop(rootInstanceStackCursor, fiber);
5290}
5291
5292function getHostContext() {
5293 var context = requiredContext(contextStackCursor$1.current);
5294 return context;
5295}
5296
5297function pushHostContext(fiber) {
5298 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5299 var context = requiredContext(contextStackCursor$1.current);
5300 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
5301
5302 // Don't push this Fiber's context unless it's unique.
5303 if (context === nextContext) {
5304 return;
5305 }
5306
5307 // Track the context and the Fiber that provided it.
5308 // This enables us to pop only Fibers that provide unique contexts.
5309 push(contextFiberStackCursor, fiber, fiber);
5310 push(contextStackCursor$1, nextContext, fiber);
5311}
5312
5313function popHostContext(fiber) {
5314 // Do not pop unless this Fiber provided the current context.
5315 // pushHostContext() only pushes Fibers that provide unique contexts.
5316 if (contextFiberStackCursor.current !== fiber) {
5317 return;
5318 }
5319
5320 pop(contextStackCursor$1, fiber);
5321 pop(contextFiberStackCursor, fiber);
5322}
5323
5324var NoEffect$1 = /* */0;
5325var UnmountSnapshot = /* */2;
5326var UnmountMutation = /* */4;
5327var MountMutation = /* */8;
5328var UnmountLayout = /* */16;
5329var MountLayout = /* */32;
5330var MountPassive = /* */64;
5331var UnmountPassive = /* */128;
5332
5333var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
5334
5335
5336var didWarnAboutMismatchedHooksForComponent = void 0;
5337{
5338 didWarnAboutMismatchedHooksForComponent = new Set();
5339}
5340
5341// These are set right before calling the component.
5342var renderExpirationTime = NoWork;
5343// The work-in-progress fiber. I've named it differently to distinguish it from
5344// the work-in-progress hook.
5345var currentlyRenderingFiber$1 = null;
5346
5347// Hooks are stored as a linked list on the fiber's memoizedState field. The
5348// current hook list is the list that belongs to the current fiber. The
5349// work-in-progress hook list is a new list that will be added to the
5350// work-in-progress fiber.
5351var firstCurrentHook = null;
5352var currentHook = null;
5353var nextCurrentHook = null;
5354var firstWorkInProgressHook = null;
5355var workInProgressHook = null;
5356var nextWorkInProgressHook = null;
5357
5358var remainingExpirationTime = NoWork;
5359var componentUpdateQueue = null;
5360var sideEffectTag = 0;
5361
5362// Updates scheduled during render will trigger an immediate re-render at the
5363// end of the current pass. We can't store these updates on the normal queue,
5364// because if the work is aborted, they should be discarded. Because this is
5365// a relatively rare case, we also don't want to add an additional field to
5366// either the hook or queue object types. So we store them in a lazily create
5367// map of queue -> render-phase updates, which are discarded once the component
5368// completes without re-rendering.
5369
5370// Whether an update was scheduled during the currently executing render pass.
5371var didScheduleRenderPhaseUpdate = false;
5372// Lazily created map of render-phase updates
5373var renderPhaseUpdates = null;
5374// Counter to prevent infinite loops.
5375var numberOfReRenders = 0;
5376var RE_RENDER_LIMIT = 25;
5377
5378// In DEV, this is the name of the currently executing primitive hook
5379var currentHookNameInDev = null;
5380
5381function warnOnHookMismatchInDev() {
5382 {
5383 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5384 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5385 didWarnAboutMismatchedHooksForComponent.add(componentName);
5386
5387 var secondColumnStart = 22;
5388
5389 var table = '';
5390 var prevHook = firstCurrentHook;
5391 var nextHook = firstWorkInProgressHook;
5392 var n = 1;
5393 while (prevHook !== null && nextHook !== null) {
5394 var oldHookName = prevHook._debugType;
5395 var newHookName = nextHook._debugType;
5396
5397 var row = n + '. ' + oldHookName;
5398
5399 // Extra space so second column lines up
5400 // lol @ IE not supporting String#repeat
5401 while (row.length < secondColumnStart) {
5402 row += ' ';
5403 }
5404
5405 row += newHookName + '\n';
5406
5407 table += row;
5408 prevHook = prevHook.next;
5409 nextHook = nextHook.next;
5410 n++;
5411 }
5412
5413 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);
5414 }
5415 }
5416}
5417
5418function throwInvalidHookError() {
5419 invariant(false, 'Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)');
5420}
5421
5422function areHookInputsEqual(nextDeps, prevDeps) {
5423 if (prevDeps === null) {
5424 {
5425 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);
5426 }
5427 return false;
5428 }
5429
5430 {
5431 // Don't bother comparing lengths in prod because these arrays should be
5432 // passed inline.
5433 if (nextDeps.length !== prevDeps.length) {
5434 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(', ') + ']');
5435 }
5436 }
5437 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5438 if (is(nextDeps[i], prevDeps[i])) {
5439 continue;
5440 }
5441 return false;
5442 }
5443 return true;
5444}
5445
5446function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
5447 renderExpirationTime = nextRenderExpirationTime;
5448 currentlyRenderingFiber$1 = workInProgress;
5449 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
5450
5451 // The following should have already been reset
5452 // currentHook = null;
5453 // workInProgressHook = null;
5454
5455 // remainingExpirationTime = NoWork;
5456 // componentUpdateQueue = null;
5457
5458 // didScheduleRenderPhaseUpdate = false;
5459 // renderPhaseUpdates = null;
5460 // numberOfReRenders = 0;
5461 // sideEffectTag = 0;
5462
5463 {
5464 ReactCurrentDispatcher$1.current = nextCurrentHook === null ? HooksDispatcherOnMountInDEV : HooksDispatcherOnUpdateInDEV;
5465 }
5466
5467 var children = Component(props, refOrContext);
5468
5469 if (didScheduleRenderPhaseUpdate) {
5470 do {
5471 didScheduleRenderPhaseUpdate = false;
5472 numberOfReRenders += 1;
5473
5474 // Start over from the beginning of the list
5475 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
5476 nextWorkInProgressHook = firstWorkInProgressHook;
5477
5478 currentHook = null;
5479 workInProgressHook = null;
5480 componentUpdateQueue = null;
5481
5482 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5483
5484 children = Component(props, refOrContext);
5485 } while (didScheduleRenderPhaseUpdate);
5486
5487 renderPhaseUpdates = null;
5488 numberOfReRenders = 0;
5489 }
5490
5491 {
5492 currentHookNameInDev = null;
5493 }
5494
5495 // We can assume the previous dispatcher is always this one, since we set it
5496 // at the beginning of the render phase and there's no re-entrancy.
5497 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5498
5499 var renderedWork = currentlyRenderingFiber$1;
5500
5501 renderedWork.memoizedState = firstWorkInProgressHook;
5502 renderedWork.expirationTime = remainingExpirationTime;
5503 renderedWork.updateQueue = componentUpdateQueue;
5504 renderedWork.effectTag |= sideEffectTag;
5505
5506 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5507
5508 renderExpirationTime = NoWork;
5509 currentlyRenderingFiber$1 = null;
5510
5511 firstCurrentHook = null;
5512 currentHook = null;
5513 nextCurrentHook = null;
5514 firstWorkInProgressHook = null;
5515 workInProgressHook = null;
5516 nextWorkInProgressHook = null;
5517
5518 remainingExpirationTime = NoWork;
5519 componentUpdateQueue = null;
5520 sideEffectTag = 0;
5521
5522 // These were reset above
5523 // didScheduleRenderPhaseUpdate = false;
5524 // renderPhaseUpdates = null;
5525 // numberOfReRenders = 0;
5526
5527 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
5528
5529 return children;
5530}
5531
5532function bailoutHooks(current, workInProgress, expirationTime) {
5533 workInProgress.updateQueue = current.updateQueue;
5534 workInProgress.effectTag &= ~(Passive | Update);
5535 if (current.expirationTime <= expirationTime) {
5536 current.expirationTime = NoWork;
5537 }
5538}
5539
5540function resetHooks() {
5541 // We can assume the previous dispatcher is always this one, since we set it
5542 // at the beginning of the render phase and there's no re-entrancy.
5543 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5544
5545 // This is used to reset the state of this module when a component throws.
5546 // It's also called inside mountIndeterminateComponent if we determine the
5547 // component is a module-style component.
5548 renderExpirationTime = NoWork;
5549 currentlyRenderingFiber$1 = null;
5550
5551 firstCurrentHook = null;
5552 currentHook = null;
5553 nextCurrentHook = null;
5554 firstWorkInProgressHook = null;
5555 workInProgressHook = null;
5556 nextWorkInProgressHook = null;
5557
5558 remainingExpirationTime = NoWork;
5559 componentUpdateQueue = null;
5560 sideEffectTag = 0;
5561
5562 {
5563 currentHookNameInDev = null;
5564 }
5565
5566 didScheduleRenderPhaseUpdate = false;
5567 renderPhaseUpdates = null;
5568 numberOfReRenders = 0;
5569}
5570
5571function mountWorkInProgressHook() {
5572 var hook = {
5573 memoizedState: null,
5574
5575 baseState: null,
5576 queue: null,
5577 baseUpdate: null,
5578
5579 next: null
5580 };
5581
5582 {
5583 hook._debugType = currentHookNameInDev;
5584 }
5585 if (workInProgressHook === null) {
5586 // This is the first hook in the list
5587 firstWorkInProgressHook = workInProgressHook = hook;
5588 } else {
5589 // Append to the end of the list
5590 workInProgressHook = workInProgressHook.next = hook;
5591 }
5592 return workInProgressHook;
5593}
5594
5595function updateWorkInProgressHook() {
5596 // This function is used both for updates and for re-renders triggered by a
5597 // render phase update. It assumes there is either a current hook we can
5598 // clone, or a work-in-progress hook from a previous render pass that we can
5599 // use as a base. When we reach the end of the base list, we must switch to
5600 // the dispatcher used for mounts.
5601 if (nextWorkInProgressHook !== null) {
5602 // There's already a work-in-progress. Reuse it.
5603 workInProgressHook = nextWorkInProgressHook;
5604 nextWorkInProgressHook = workInProgressHook.next;
5605
5606 currentHook = nextCurrentHook;
5607 nextCurrentHook = currentHook !== null ? currentHook.next : null;
5608 } else {
5609 // Clone from the current hook.
5610 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
5611 currentHook = nextCurrentHook;
5612
5613 var newHook = {
5614 memoizedState: currentHook.memoizedState,
5615
5616 baseState: currentHook.baseState,
5617 queue: currentHook.queue,
5618 baseUpdate: currentHook.baseUpdate,
5619
5620 next: null
5621 };
5622
5623 if (workInProgressHook === null) {
5624 // This is the first hook in the list.
5625 workInProgressHook = firstWorkInProgressHook = newHook;
5626 } else {
5627 // Append to the end of the list.
5628 workInProgressHook = workInProgressHook.next = newHook;
5629 }
5630 nextCurrentHook = currentHook.next;
5631
5632 {
5633 newHook._debugType = currentHookNameInDev;
5634 if (currentHookNameInDev !== currentHook._debugType) {
5635 warnOnHookMismatchInDev();
5636 }
5637 }
5638 }
5639 return workInProgressHook;
5640}
5641
5642function createFunctionComponentUpdateQueue() {
5643 return {
5644 lastEffect: null
5645 };
5646}
5647
5648function basicStateReducer(state, action) {
5649 return typeof action === 'function' ? action(state) : action;
5650}
5651
5652function mountContext(context, observedBits) {
5653 {
5654 mountWorkInProgressHook();
5655 }
5656 return readContext(context, observedBits);
5657}
5658
5659function updateContext(context, observedBits) {
5660 {
5661 updateWorkInProgressHook();
5662 }
5663 return readContext(context, observedBits);
5664}
5665
5666function mountReducer(reducer, initialArg, init) {
5667 var hook = mountWorkInProgressHook();
5668 var initialState = void 0;
5669 if (init !== undefined) {
5670 initialState = init(initialArg);
5671 } else {
5672 initialState = initialArg;
5673 }
5674 hook.memoizedState = hook.baseState = initialState;
5675 var queue = hook.queue = {
5676 last: null,
5677 dispatch: null,
5678 eagerReducer: reducer,
5679 eagerState: initialState
5680 };
5681 var dispatch = queue.dispatch = dispatchAction.bind(null,
5682 // Flow doesn't know this is non-null, but we do.
5683 currentlyRenderingFiber$1, queue);
5684 return [hook.memoizedState, dispatch];
5685}
5686
5687function updateReducer(reducer, initialArg, init) {
5688 var hook = updateWorkInProgressHook();
5689 var queue = hook.queue;
5690 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
5691
5692 if (numberOfReRenders > 0) {
5693 // This is a re-render. Apply the new render phase updates to the previous
5694 var _dispatch = queue.dispatch;
5695 if (renderPhaseUpdates !== null) {
5696 // Render phase updates are stored in a map of queue -> linked list
5697 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
5698 if (firstRenderPhaseUpdate !== undefined) {
5699 renderPhaseUpdates.delete(queue);
5700 var newState = hook.memoizedState;
5701 var update = firstRenderPhaseUpdate;
5702 do {
5703 // Process this render phase update. We don't have to check the
5704 // priority because it will always be the same as the current
5705 // render's.
5706 var _action = update.action;
5707 newState = reducer(newState, _action);
5708 update = update.next;
5709 } while (update !== null);
5710
5711 // Mark that the fiber performed work, but only if the new state is
5712 // different from the current state.
5713 if (!is(newState, hook.memoizedState)) {
5714 markWorkInProgressReceivedUpdate();
5715 }
5716
5717 hook.memoizedState = newState;
5718 // Don't persist the state accumlated from the render phase updates to
5719 // the base state unless the queue is empty.
5720 // TODO: Not sure if this is the desired semantics, but it's what we
5721 // do for gDSFP. I can't remember why.
5722 if (hook.baseUpdate === queue.last) {
5723 hook.baseState = newState;
5724 }
5725
5726 queue.eagerReducer = reducer;
5727 queue.eagerState = newState;
5728
5729 return [newState, _dispatch];
5730 }
5731 }
5732 return [hook.memoizedState, _dispatch];
5733 }
5734
5735 // The last update in the entire queue
5736 var last = queue.last;
5737 // The last update that is part of the base state.
5738 var baseUpdate = hook.baseUpdate;
5739 var baseState = hook.baseState;
5740
5741 // Find the first unprocessed update.
5742 var first = void 0;
5743 if (baseUpdate !== null) {
5744 if (last !== null) {
5745 // For the first update, the queue is a circular linked list where
5746 // `queue.last.next = queue.first`. Once the first update commits, and
5747 // the `baseUpdate` is no longer empty, we can unravel the list.
5748 last.next = null;
5749 }
5750 first = baseUpdate.next;
5751 } else {
5752 first = last !== null ? last.next : null;
5753 }
5754 if (first !== null) {
5755 var _newState = baseState;
5756 var newBaseState = null;
5757 var newBaseUpdate = null;
5758 var prevUpdate = baseUpdate;
5759 var _update = first;
5760 var didSkip = false;
5761 do {
5762 var updateExpirationTime = _update.expirationTime;
5763 if (updateExpirationTime < renderExpirationTime) {
5764 // Priority is insufficient. Skip this update. If this is the first
5765 // skipped update, the previous update/state is the new base
5766 // update/state.
5767 if (!didSkip) {
5768 didSkip = true;
5769 newBaseUpdate = prevUpdate;
5770 newBaseState = _newState;
5771 }
5772 // Update the remaining priority in the queue.
5773 if (updateExpirationTime > remainingExpirationTime) {
5774 remainingExpirationTime = updateExpirationTime;
5775 }
5776 } else {
5777 // Process this update.
5778 if (_update.eagerReducer === reducer) {
5779 // If this update was processed eagerly, and its reducer matches the
5780 // current reducer, we can use the eagerly computed state.
5781 _newState = _update.eagerState;
5782 } else {
5783 var _action2 = _update.action;
5784 _newState = reducer(_newState, _action2);
5785 }
5786 }
5787 prevUpdate = _update;
5788 _update = _update.next;
5789 } while (_update !== null && _update !== first);
5790
5791 if (!didSkip) {
5792 newBaseUpdate = prevUpdate;
5793 newBaseState = _newState;
5794 }
5795
5796 // Mark that the fiber performed work, but only if the new state is
5797 // different from the current state.
5798 if (!is(_newState, hook.memoizedState)) {
5799 markWorkInProgressReceivedUpdate();
5800 }
5801
5802 hook.memoizedState = _newState;
5803 hook.baseUpdate = newBaseUpdate;
5804 hook.baseState = newBaseState;
5805
5806 queue.eagerReducer = reducer;
5807 queue.eagerState = _newState;
5808 }
5809
5810 var dispatch = queue.dispatch;
5811 return [hook.memoizedState, dispatch];
5812}
5813
5814function mountState(initialState) {
5815 var hook = mountWorkInProgressHook();
5816 if (typeof initialState === 'function') {
5817 initialState = initialState();
5818 }
5819 hook.memoizedState = hook.baseState = initialState;
5820 var queue = hook.queue = {
5821 last: null,
5822 dispatch: null,
5823 eagerReducer: basicStateReducer,
5824 eagerState: initialState
5825 };
5826 var dispatch = queue.dispatch = dispatchAction.bind(null,
5827 // Flow doesn't know this is non-null, but we do.
5828 currentlyRenderingFiber$1, queue);
5829 return [hook.memoizedState, dispatch];
5830}
5831
5832function updateState(initialState) {
5833 return updateReducer(basicStateReducer, initialState);
5834}
5835
5836function pushEffect(tag, create, destroy, deps) {
5837 var effect = {
5838 tag: tag,
5839 create: create,
5840 destroy: destroy,
5841 deps: deps,
5842 // Circular
5843 next: null
5844 };
5845 if (componentUpdateQueue === null) {
5846 componentUpdateQueue = createFunctionComponentUpdateQueue();
5847 componentUpdateQueue.lastEffect = effect.next = effect;
5848 } else {
5849 var _lastEffect = componentUpdateQueue.lastEffect;
5850 if (_lastEffect === null) {
5851 componentUpdateQueue.lastEffect = effect.next = effect;
5852 } else {
5853 var firstEffect = _lastEffect.next;
5854 _lastEffect.next = effect;
5855 effect.next = firstEffect;
5856 componentUpdateQueue.lastEffect = effect;
5857 }
5858 }
5859 return effect;
5860}
5861
5862function mountRef(initialValue) {
5863 var hook = mountWorkInProgressHook();
5864 var ref = { current: initialValue };
5865 {
5866 Object.seal(ref);
5867 }
5868 hook.memoizedState = ref;
5869 return ref;
5870}
5871
5872function updateRef(initialValue) {
5873 var hook = updateWorkInProgressHook();
5874 return hook.memoizedState;
5875}
5876
5877function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5878 var hook = mountWorkInProgressHook();
5879 var nextDeps = deps === undefined ? null : deps;
5880 sideEffectTag |= fiberEffectTag;
5881 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
5882}
5883
5884function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5885 var hook = updateWorkInProgressHook();
5886 var nextDeps = deps === undefined ? null : deps;
5887 var destroy = undefined;
5888
5889 if (currentHook !== null) {
5890 var prevEffect = currentHook.memoizedState;
5891 destroy = prevEffect.destroy;
5892 if (nextDeps !== null) {
5893 var prevDeps = prevEffect.deps;
5894 if (areHookInputsEqual(nextDeps, prevDeps)) {
5895 pushEffect(NoEffect$1, create, destroy, nextDeps);
5896 return;
5897 }
5898 }
5899 }
5900
5901 sideEffectTag |= fiberEffectTag;
5902 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
5903}
5904
5905function mountEffect(create, deps) {
5906 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5907}
5908
5909function updateEffect(create, deps) {
5910 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5911}
5912
5913function mountLayoutEffect(create, deps) {
5914 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5915}
5916
5917function updateLayoutEffect(create, deps) {
5918 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5919}
5920
5921function imperativeHandleEffect(create, ref) {
5922 if (typeof ref === 'function') {
5923 var refCallback = ref;
5924 var _inst = create();
5925 refCallback(_inst);
5926 return function () {
5927 refCallback(null);
5928 };
5929 } else if (ref !== null && ref !== undefined) {
5930 var refObject = ref;
5931 {
5932 !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;
5933 }
5934 var _inst2 = create();
5935 refObject.current = _inst2;
5936 return function () {
5937 refObject.current = null;
5938 };
5939 }
5940}
5941
5942function mountImperativeHandle(ref, create, deps) {
5943 {
5944 !(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;
5945 }
5946
5947 // TODO: If deps are provided, should we skip comparing the ref itself?
5948 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
5949
5950 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
5951}
5952
5953function updateImperativeHandle(ref, create, deps) {
5954 {
5955 !(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;
5956 }
5957
5958 // TODO: If deps are provided, should we skip comparing the ref itself?
5959 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
5960
5961 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
5962}
5963
5964function mountDebugValue(value, formatterFn) {
5965 // This hook is normally a no-op.
5966 // The react-debug-hooks package injects its own implementation
5967 // so that e.g. DevTools can display custom hook values.
5968}
5969
5970var updateDebugValue = mountDebugValue;
5971
5972function mountCallback(callback, deps) {
5973 var hook = mountWorkInProgressHook();
5974 var nextDeps = deps === undefined ? null : deps;
5975 hook.memoizedState = [callback, nextDeps];
5976 return callback;
5977}
5978
5979function updateCallback(callback, deps) {
5980 var hook = updateWorkInProgressHook();
5981 var nextDeps = deps === undefined ? null : deps;
5982 var prevState = hook.memoizedState;
5983 if (prevState !== null) {
5984 if (nextDeps !== null) {
5985 var prevDeps = prevState[1];
5986 if (areHookInputsEqual(nextDeps, prevDeps)) {
5987 return prevState[0];
5988 }
5989 }
5990 }
5991 hook.memoizedState = [callback, nextDeps];
5992 return callback;
5993}
5994
5995function mountMemo(nextCreate, deps) {
5996 var hook = mountWorkInProgressHook();
5997 var nextDeps = deps === undefined ? null : deps;
5998 var nextValue = nextCreate();
5999 hook.memoizedState = [nextValue, nextDeps];
6000 return nextValue;
6001}
6002
6003function updateMemo(nextCreate, deps) {
6004 var hook = updateWorkInProgressHook();
6005 var nextDeps = deps === undefined ? null : deps;
6006 var prevState = hook.memoizedState;
6007 if (prevState !== null) {
6008 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6009 if (nextDeps !== null) {
6010 var prevDeps = prevState[1];
6011 if (areHookInputsEqual(nextDeps, prevDeps)) {
6012 return prevState[0];
6013 }
6014 }
6015 }
6016 var nextValue = nextCreate();
6017 hook.memoizedState = [nextValue, nextDeps];
6018 return nextValue;
6019}
6020
6021// in a test-like environment, we want to warn if dispatchAction()
6022// is called outside of a batchedUpdates/TestUtils.act(...) call.
6023var shouldWarnForUnbatchedSetState = false;
6024
6025{
6026 // jest isn't a 'global', it's just exposed to tests via a wrapped function
6027 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
6028 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
6029 if ('undefined' !== typeof jest) {
6030 shouldWarnForUnbatchedSetState = true;
6031 }
6032}
6033
6034function dispatchAction(fiber, queue, action) {
6035 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
6036
6037 {
6038 !(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;
6039 }
6040
6041 var alternate = fiber.alternate;
6042 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6043 // This is a render phase update. Stash it in a lazily-created map of
6044 // queue -> linked list of updates. After this render pass, we'll restart
6045 // and apply the stashed updates on top of the work-in-progress hook.
6046 didScheduleRenderPhaseUpdate = true;
6047 var update = {
6048 expirationTime: renderExpirationTime,
6049 action: action,
6050 eagerReducer: null,
6051 eagerState: null,
6052 next: null
6053 };
6054 if (renderPhaseUpdates === null) {
6055 renderPhaseUpdates = new Map();
6056 }
6057 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6058 if (firstRenderPhaseUpdate === undefined) {
6059 renderPhaseUpdates.set(queue, update);
6060 } else {
6061 // Append the update to the end of the list.
6062 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
6063 while (lastRenderPhaseUpdate.next !== null) {
6064 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6065 }
6066 lastRenderPhaseUpdate.next = update;
6067 }
6068 } else {
6069 flushPassiveEffects();
6070
6071 var currentTime = requestCurrentTime();
6072 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
6073
6074 var _update2 = {
6075 expirationTime: _expirationTime,
6076 action: action,
6077 eagerReducer: null,
6078 eagerState: null,
6079 next: null
6080 };
6081
6082 // Append the update to the end of the list.
6083 var _last = queue.last;
6084 if (_last === null) {
6085 // This is the first update. Create a circular list.
6086 _update2.next = _update2;
6087 } else {
6088 var first = _last.next;
6089 if (first !== null) {
6090 // Still circular.
6091 _update2.next = first;
6092 }
6093 _last.next = _update2;
6094 }
6095 queue.last = _update2;
6096
6097 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6098 // The queue is currently empty, which means we can eagerly compute the
6099 // next state before entering the render phase. If the new state is the
6100 // same as the current state, we may be able to bail out entirely.
6101 var _eagerReducer = queue.eagerReducer;
6102 if (_eagerReducer !== null) {
6103 var prevDispatcher = void 0;
6104 {
6105 prevDispatcher = ReactCurrentDispatcher$1.current;
6106 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6107 }
6108 try {
6109 var currentState = queue.eagerState;
6110 var _eagerState = _eagerReducer(currentState, action);
6111 // Stash the eagerly computed state, and the reducer used to compute
6112 // it, on the update object. If the reducer hasn't changed by the
6113 // time we enter the render phase, then the eager state can be used
6114 // without calling the reducer again.
6115 _update2.eagerReducer = _eagerReducer;
6116 _update2.eagerState = _eagerState;
6117 if (is(_eagerState, currentState)) {
6118 // Fast path. We can bail out without scheduling React to re-render.
6119 // It's still possible that we'll need to rebase this update later,
6120 // if the component re-renders for a different reason and by that
6121 // time the reducer has changed.
6122 return;
6123 }
6124 } catch (error) {
6125 // Suppress the error. It will throw again in the render phase.
6126 } finally {
6127 {
6128 ReactCurrentDispatcher$1.current = prevDispatcher;
6129 }
6130 }
6131 }
6132 }
6133 {
6134 if (shouldWarnForUnbatchedSetState === true) {
6135 warnIfNotCurrentlyBatchingInDev(fiber);
6136 }
6137 }
6138 scheduleWork(fiber, _expirationTime);
6139 }
6140}
6141
6142var ContextOnlyDispatcher = {
6143 readContext: readContext,
6144
6145 useCallback: throwInvalidHookError,
6146 useContext: throwInvalidHookError,
6147 useEffect: throwInvalidHookError,
6148 useImperativeHandle: throwInvalidHookError,
6149 useLayoutEffect: throwInvalidHookError,
6150 useMemo: throwInvalidHookError,
6151 useReducer: throwInvalidHookError,
6152 useRef: throwInvalidHookError,
6153 useState: throwInvalidHookError,
6154 useDebugValue: throwInvalidHookError
6155};
6156
6157var HooksDispatcherOnMountInDEV = null;
6158var HooksDispatcherOnUpdateInDEV = null;
6159var InvalidNestedHooksDispatcherOnMountInDEV = null;
6160var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6161
6162{
6163 var warnInvalidContextAccess = function () {
6164 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().');
6165 };
6166
6167 var warnInvalidHookAccess = function () {
6168 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');
6169 };
6170
6171 HooksDispatcherOnMountInDEV = {
6172 readContext: function (context, observedBits) {
6173 return readContext(context, observedBits);
6174 },
6175 useCallback: function (callback, deps) {
6176 currentHookNameInDev = 'useCallback';
6177 return mountCallback(callback, deps);
6178 },
6179 useContext: function (context, observedBits) {
6180 currentHookNameInDev = 'useContext';
6181 return mountContext(context, observedBits);
6182 },
6183 useEffect: function (create, deps) {
6184 currentHookNameInDev = 'useEffect';
6185 return mountEffect(create, deps);
6186 },
6187 useImperativeHandle: function (ref, create, deps) {
6188 currentHookNameInDev = 'useImperativeHandle';
6189 return mountImperativeHandle(ref, create, deps);
6190 },
6191 useLayoutEffect: function (create, deps) {
6192 currentHookNameInDev = 'useLayoutEffect';
6193 return mountLayoutEffect(create, deps);
6194 },
6195 useMemo: function (create, deps) {
6196 currentHookNameInDev = 'useMemo';
6197 var prevDispatcher = ReactCurrentDispatcher$1.current;
6198 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6199 try {
6200 return mountMemo(create, deps);
6201 } finally {
6202 ReactCurrentDispatcher$1.current = prevDispatcher;
6203 }
6204 },
6205 useReducer: function (reducer, initialArg, init) {
6206 currentHookNameInDev = 'useReducer';
6207 var prevDispatcher = ReactCurrentDispatcher$1.current;
6208 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6209 try {
6210 return mountReducer(reducer, initialArg, init);
6211 } finally {
6212 ReactCurrentDispatcher$1.current = prevDispatcher;
6213 }
6214 },
6215 useRef: function (initialValue) {
6216 currentHookNameInDev = 'useRef';
6217 return mountRef(initialValue);
6218 },
6219 useState: function (initialState) {
6220 currentHookNameInDev = 'useState';
6221 var prevDispatcher = ReactCurrentDispatcher$1.current;
6222 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6223 try {
6224 return mountState(initialState);
6225 } finally {
6226 ReactCurrentDispatcher$1.current = prevDispatcher;
6227 }
6228 },
6229 useDebugValue: function (value, formatterFn) {
6230 currentHookNameInDev = 'useDebugValue';
6231 return mountDebugValue(value, formatterFn);
6232 }
6233 };
6234
6235 HooksDispatcherOnUpdateInDEV = {
6236 readContext: function (context, observedBits) {
6237 return readContext(context, observedBits);
6238 },
6239 useCallback: function (callback, deps) {
6240 currentHookNameInDev = 'useCallback';
6241 return updateCallback(callback, deps);
6242 },
6243 useContext: function (context, observedBits) {
6244 currentHookNameInDev = 'useContext';
6245 return updateContext(context, observedBits);
6246 },
6247 useEffect: function (create, deps) {
6248 currentHookNameInDev = 'useEffect';
6249 return updateEffect(create, deps);
6250 },
6251 useImperativeHandle: function (ref, create, deps) {
6252 currentHookNameInDev = 'useImperativeHandle';
6253 return updateImperativeHandle(ref, create, deps);
6254 },
6255 useLayoutEffect: function (create, deps) {
6256 currentHookNameInDev = 'useLayoutEffect';
6257 return updateLayoutEffect(create, deps);
6258 },
6259 useMemo: function (create, deps) {
6260 currentHookNameInDev = 'useMemo';
6261 var prevDispatcher = ReactCurrentDispatcher$1.current;
6262 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6263 try {
6264 return updateMemo(create, deps);
6265 } finally {
6266 ReactCurrentDispatcher$1.current = prevDispatcher;
6267 }
6268 },
6269 useReducer: function (reducer, initialArg, init) {
6270 currentHookNameInDev = 'useReducer';
6271 var prevDispatcher = ReactCurrentDispatcher$1.current;
6272 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6273 try {
6274 return updateReducer(reducer, initialArg, init);
6275 } finally {
6276 ReactCurrentDispatcher$1.current = prevDispatcher;
6277 }
6278 },
6279 useRef: function (initialValue) {
6280 currentHookNameInDev = 'useRef';
6281 return updateRef(initialValue);
6282 },
6283 useState: function (initialState) {
6284 currentHookNameInDev = 'useState';
6285 var prevDispatcher = ReactCurrentDispatcher$1.current;
6286 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6287 try {
6288 return updateState(initialState);
6289 } finally {
6290 ReactCurrentDispatcher$1.current = prevDispatcher;
6291 }
6292 },
6293 useDebugValue: function (value, formatterFn) {
6294 currentHookNameInDev = 'useDebugValue';
6295 return updateDebugValue(value, formatterFn);
6296 }
6297 };
6298
6299 InvalidNestedHooksDispatcherOnMountInDEV = {
6300 readContext: function (context, observedBits) {
6301 warnInvalidContextAccess();
6302 return readContext(context, observedBits);
6303 },
6304 useCallback: function (callback, deps) {
6305 currentHookNameInDev = 'useCallback';
6306 warnInvalidHookAccess();
6307 return mountCallback(callback, deps);
6308 },
6309 useContext: function (context, observedBits) {
6310 currentHookNameInDev = 'useContext';
6311 warnInvalidHookAccess();
6312 return mountContext(context, observedBits);
6313 },
6314 useEffect: function (create, deps) {
6315 currentHookNameInDev = 'useEffect';
6316 warnInvalidHookAccess();
6317 return mountEffect(create, deps);
6318 },
6319 useImperativeHandle: function (ref, create, deps) {
6320 currentHookNameInDev = 'useImperativeHandle';
6321 warnInvalidHookAccess();
6322 return mountImperativeHandle(ref, create, deps);
6323 },
6324 useLayoutEffect: function (create, deps) {
6325 currentHookNameInDev = 'useLayoutEffect';
6326 warnInvalidHookAccess();
6327 return mountLayoutEffect(create, deps);
6328 },
6329 useMemo: function (create, deps) {
6330 currentHookNameInDev = 'useMemo';
6331 warnInvalidHookAccess();
6332 var prevDispatcher = ReactCurrentDispatcher$1.current;
6333 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6334 try {
6335 return mountMemo(create, deps);
6336 } finally {
6337 ReactCurrentDispatcher$1.current = prevDispatcher;
6338 }
6339 },
6340 useReducer: function (reducer, initialArg, init) {
6341 currentHookNameInDev = 'useReducer';
6342 warnInvalidHookAccess();
6343 var prevDispatcher = ReactCurrentDispatcher$1.current;
6344 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6345 try {
6346 return mountReducer(reducer, initialArg, init);
6347 } finally {
6348 ReactCurrentDispatcher$1.current = prevDispatcher;
6349 }
6350 },
6351 useRef: function (initialValue) {
6352 currentHookNameInDev = 'useRef';
6353 warnInvalidHookAccess();
6354 return mountRef(initialValue);
6355 },
6356 useState: function (initialState) {
6357 currentHookNameInDev = 'useState';
6358 warnInvalidHookAccess();
6359 var prevDispatcher = ReactCurrentDispatcher$1.current;
6360 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6361 try {
6362 return mountState(initialState);
6363 } finally {
6364 ReactCurrentDispatcher$1.current = prevDispatcher;
6365 }
6366 },
6367 useDebugValue: function (value, formatterFn) {
6368 currentHookNameInDev = 'useDebugValue';
6369 warnInvalidHookAccess();
6370 return mountDebugValue(value, formatterFn);
6371 }
6372 };
6373
6374 InvalidNestedHooksDispatcherOnUpdateInDEV = {
6375 readContext: function (context, observedBits) {
6376 warnInvalidContextAccess();
6377 return readContext(context, observedBits);
6378 },
6379 useCallback: function (callback, deps) {
6380 currentHookNameInDev = 'useCallback';
6381 warnInvalidHookAccess();
6382 return updateCallback(callback, deps);
6383 },
6384 useContext: function (context, observedBits) {
6385 currentHookNameInDev = 'useContext';
6386 warnInvalidHookAccess();
6387 return updateContext(context, observedBits);
6388 },
6389 useEffect: function (create, deps) {
6390 currentHookNameInDev = 'useEffect';
6391 warnInvalidHookAccess();
6392 return updateEffect(create, deps);
6393 },
6394 useImperativeHandle: function (ref, create, deps) {
6395 currentHookNameInDev = 'useImperativeHandle';
6396 warnInvalidHookAccess();
6397 return updateImperativeHandle(ref, create, deps);
6398 },
6399 useLayoutEffect: function (create, deps) {
6400 currentHookNameInDev = 'useLayoutEffect';
6401 warnInvalidHookAccess();
6402 return updateLayoutEffect(create, deps);
6403 },
6404 useMemo: function (create, deps) {
6405 currentHookNameInDev = 'useMemo';
6406 warnInvalidHookAccess();
6407 var prevDispatcher = ReactCurrentDispatcher$1.current;
6408 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6409 try {
6410 return updateMemo(create, deps);
6411 } finally {
6412 ReactCurrentDispatcher$1.current = prevDispatcher;
6413 }
6414 },
6415 useReducer: function (reducer, initialArg, init) {
6416 currentHookNameInDev = 'useReducer';
6417 warnInvalidHookAccess();
6418 var prevDispatcher = ReactCurrentDispatcher$1.current;
6419 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6420 try {
6421 return updateReducer(reducer, initialArg, init);
6422 } finally {
6423 ReactCurrentDispatcher$1.current = prevDispatcher;
6424 }
6425 },
6426 useRef: function (initialValue) {
6427 currentHookNameInDev = 'useRef';
6428 warnInvalidHookAccess();
6429 return updateRef(initialValue);
6430 },
6431 useState: function (initialState) {
6432 currentHookNameInDev = 'useState';
6433 warnInvalidHookAccess();
6434 var prevDispatcher = ReactCurrentDispatcher$1.current;
6435 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6436 try {
6437 return updateState(initialState);
6438 } finally {
6439 ReactCurrentDispatcher$1.current = prevDispatcher;
6440 }
6441 },
6442 useDebugValue: function (value, formatterFn) {
6443 currentHookNameInDev = 'useDebugValue';
6444 warnInvalidHookAccess();
6445 return updateDebugValue(value, formatterFn);
6446 }
6447 };
6448}
6449
6450var commitTime = 0;
6451var profilerStartTime = -1;
6452
6453function getCommitTime() {
6454 return commitTime;
6455}
6456
6457function recordCommitTime() {
6458 if (!enableProfilerTimer) {
6459 return;
6460 }
6461 commitTime = unstable_now();
6462}
6463
6464function startProfilerTimer(fiber) {
6465 if (!enableProfilerTimer) {
6466 return;
6467 }
6468
6469 profilerStartTime = unstable_now();
6470
6471 if (fiber.actualStartTime < 0) {
6472 fiber.actualStartTime = unstable_now();
6473 }
6474}
6475
6476function stopProfilerTimerIfRunning(fiber) {
6477 if (!enableProfilerTimer) {
6478 return;
6479 }
6480 profilerStartTime = -1;
6481}
6482
6483function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
6484 if (!enableProfilerTimer) {
6485 return;
6486 }
6487
6488 if (profilerStartTime >= 0) {
6489 var elapsedTime = unstable_now() - profilerStartTime;
6490 fiber.actualDuration += elapsedTime;
6491 if (overrideBaseTime) {
6492 fiber.selfBaseDuration = elapsedTime;
6493 }
6494 profilerStartTime = -1;
6495 }
6496}
6497
6498// The deepest Fiber on the stack involved in a hydration context.
6499// This may have been an insertion or a hydration.
6500var hydrationParentFiber = null;
6501var nextHydratableInstance = null;
6502var isHydrating = false;
6503
6504function enterHydrationState(fiber) {
6505 if (!supportsHydration) {
6506 return false;
6507 }
6508
6509 var parentInstance = fiber.stateNode.containerInfo;
6510 nextHydratableInstance = getFirstHydratableChild(parentInstance);
6511 hydrationParentFiber = fiber;
6512 isHydrating = true;
6513 return true;
6514}
6515
6516function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
6517 if (!supportsHydration) {
6518 return false;
6519 }
6520
6521 var suspenseInstance = fiber.stateNode;
6522 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
6523 popToNextHostParent(fiber);
6524 isHydrating = true;
6525 return true;
6526}
6527
6528function deleteHydratableInstance(returnFiber, instance) {
6529 {
6530 switch (returnFiber.tag) {
6531 case HostRoot:
6532 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
6533 break;
6534 case HostComponent:
6535 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
6536 break;
6537 }
6538 }
6539
6540 var childToDelete = createFiberFromHostInstanceForDeletion();
6541 childToDelete.stateNode = instance;
6542 childToDelete.return = returnFiber;
6543 childToDelete.effectTag = Deletion;
6544
6545 // This might seem like it belongs on progressedFirstDeletion. However,
6546 // these children are not part of the reconciliation list of children.
6547 // Even if we abort and rereconcile the children, that will try to hydrate
6548 // again and the nodes are still in the host tree so these will be
6549 // recreated.
6550 if (returnFiber.lastEffect !== null) {
6551 returnFiber.lastEffect.nextEffect = childToDelete;
6552 returnFiber.lastEffect = childToDelete;
6553 } else {
6554 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
6555 }
6556}
6557
6558function insertNonHydratedInstance(returnFiber, fiber) {
6559 fiber.effectTag |= Placement;
6560 {
6561 switch (returnFiber.tag) {
6562 case HostRoot:
6563 {
6564 var parentContainer = returnFiber.stateNode.containerInfo;
6565 switch (fiber.tag) {
6566 case HostComponent:
6567 var type = fiber.type;
6568 var props = fiber.pendingProps;
6569 didNotFindHydratableContainerInstance(parentContainer, type, props);
6570 break;
6571 case HostText:
6572 var text = fiber.pendingProps;
6573 didNotFindHydratableContainerTextInstance(parentContainer, text);
6574 break;
6575 case SuspenseComponent:
6576 didNotFindHydratableContainerSuspenseInstance(parentContainer);
6577 break;
6578 }
6579 break;
6580 }
6581 case HostComponent:
6582 {
6583 var parentType = returnFiber.type;
6584 var parentProps = returnFiber.memoizedProps;
6585 var parentInstance = returnFiber.stateNode;
6586 switch (fiber.tag) {
6587 case HostComponent:
6588 var _type = fiber.type;
6589 var _props = fiber.pendingProps;
6590 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
6591 break;
6592 case HostText:
6593 var _text = fiber.pendingProps;
6594 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
6595 break;
6596 case SuspenseComponent:
6597 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
6598 break;
6599 }
6600 break;
6601 }
6602 default:
6603 return;
6604 }
6605 }
6606}
6607
6608function tryHydrate(fiber, nextInstance) {
6609 switch (fiber.tag) {
6610 case HostComponent:
6611 {
6612 var type = fiber.type;
6613 var props = fiber.pendingProps;
6614 var instance = canHydrateInstance(nextInstance, type, props);
6615 if (instance !== null) {
6616 fiber.stateNode = instance;
6617 return true;
6618 }
6619 return false;
6620 }
6621 case HostText:
6622 {
6623 var text = fiber.pendingProps;
6624 var textInstance = canHydrateTextInstance(nextInstance, text);
6625 if (textInstance !== null) {
6626 fiber.stateNode = textInstance;
6627 return true;
6628 }
6629 return false;
6630 }
6631 case SuspenseComponent:
6632 {
6633 if (enableSuspenseServerRenderer) {
6634 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
6635 if (suspenseInstance !== null) {
6636 // Downgrade the tag to a dehydrated component until we've hydrated it.
6637 fiber.tag = DehydratedSuspenseComponent;
6638 fiber.stateNode = suspenseInstance;
6639 return true;
6640 }
6641 }
6642 return false;
6643 }
6644 default:
6645 return false;
6646 }
6647}
6648
6649function tryToClaimNextHydratableInstance(fiber) {
6650 if (!isHydrating) {
6651 return;
6652 }
6653 var nextInstance = nextHydratableInstance;
6654 if (!nextInstance) {
6655 // Nothing to hydrate. Make it an insertion.
6656 insertNonHydratedInstance(hydrationParentFiber, fiber);
6657 isHydrating = false;
6658 hydrationParentFiber = fiber;
6659 return;
6660 }
6661 var firstAttemptedInstance = nextInstance;
6662 if (!tryHydrate(fiber, nextInstance)) {
6663 // If we can't hydrate this instance let's try the next one.
6664 // We use this as a heuristic. It's based on intuition and not data so it
6665 // might be flawed or unnecessary.
6666 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
6667 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
6668 // Nothing to hydrate. Make it an insertion.
6669 insertNonHydratedInstance(hydrationParentFiber, fiber);
6670 isHydrating = false;
6671 hydrationParentFiber = fiber;
6672 return;
6673 }
6674 // We matched the next one, we'll now assume that the first one was
6675 // superfluous and we'll delete it. Since we can't eagerly delete it
6676 // we'll have to schedule a deletion. To do that, this node needs a dummy
6677 // fiber associated with it.
6678 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
6679 }
6680 hydrationParentFiber = fiber;
6681 nextHydratableInstance = getFirstHydratableChild(nextInstance);
6682}
6683
6684function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
6685 if (!supportsHydration) {
6686 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6687 }
6688
6689 var instance = fiber.stateNode;
6690 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
6691 // TODO: Type this specific to this type of component.
6692 fiber.updateQueue = updatePayload;
6693 // If the update payload indicates that there is a change or if there
6694 // is a new ref we mark this as an update.
6695 if (updatePayload !== null) {
6696 return true;
6697 }
6698 return false;
6699}
6700
6701function prepareToHydrateHostTextInstance(fiber) {
6702 if (!supportsHydration) {
6703 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6704 }
6705
6706 var textInstance = fiber.stateNode;
6707 var textContent = fiber.memoizedProps;
6708 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
6709 {
6710 if (shouldUpdate) {
6711 // We assume that prepareToHydrateHostTextInstance is called in a context where the
6712 // hydration parent is the parent host component of this host text.
6713 var returnFiber = hydrationParentFiber;
6714 if (returnFiber !== null) {
6715 switch (returnFiber.tag) {
6716 case HostRoot:
6717 {
6718 var parentContainer = returnFiber.stateNode.containerInfo;
6719 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
6720 break;
6721 }
6722 case HostComponent:
6723 {
6724 var parentType = returnFiber.type;
6725 var parentProps = returnFiber.memoizedProps;
6726 var parentInstance = returnFiber.stateNode;
6727 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
6728 break;
6729 }
6730 }
6731 }
6732 }
6733 }
6734 return shouldUpdate;
6735}
6736
6737function skipPastDehydratedSuspenseInstance(fiber) {
6738 if (!supportsHydration) {
6739 invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6740 }
6741 var suspenseInstance = fiber.stateNode;
6742 !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;
6743 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
6744}
6745
6746function popToNextHostParent(fiber) {
6747 var parent = fiber.return;
6748 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
6749 parent = parent.return;
6750 }
6751 hydrationParentFiber = parent;
6752}
6753
6754function popHydrationState(fiber) {
6755 if (!supportsHydration) {
6756 return false;
6757 }
6758 if (fiber !== hydrationParentFiber) {
6759 // We're deeper than the current hydration context, inside an inserted
6760 // tree.
6761 return false;
6762 }
6763 if (!isHydrating) {
6764 // If we're not currently hydrating but we're in a hydration context, then
6765 // we were an insertion and now need to pop up reenter hydration of our
6766 // siblings.
6767 popToNextHostParent(fiber);
6768 isHydrating = true;
6769 return false;
6770 }
6771
6772 var type = fiber.type;
6773
6774 // If we have any remaining hydratable nodes, we need to delete them now.
6775 // We only do this deeper than head and body since they tend to have random
6776 // other nodes in them. We also ignore components with pure text content in
6777 // side of them.
6778 // TODO: Better heuristic.
6779 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
6780 var nextInstance = nextHydratableInstance;
6781 while (nextInstance) {
6782 deleteHydratableInstance(fiber, nextInstance);
6783 nextInstance = getNextHydratableSibling(nextInstance);
6784 }
6785 }
6786
6787 popToNextHostParent(fiber);
6788 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
6789 return true;
6790}
6791
6792function resetHydrationState() {
6793 if (!supportsHydration) {
6794 return;
6795 }
6796
6797 hydrationParentFiber = null;
6798 nextHydratableInstance = null;
6799 isHydrating = false;
6800}
6801
6802var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
6803
6804var didReceiveUpdate = false;
6805
6806var didWarnAboutBadClass = void 0;
6807var didWarnAboutContextTypeOnFunctionComponent = void 0;
6808var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
6809var didWarnAboutFunctionRefs = void 0;
6810var didWarnAboutReassigningProps = void 0;
6811
6812{
6813 didWarnAboutBadClass = {};
6814 didWarnAboutContextTypeOnFunctionComponent = {};
6815 didWarnAboutGetDerivedStateOnFunctionComponent = {};
6816 didWarnAboutFunctionRefs = {};
6817 didWarnAboutReassigningProps = false;
6818}
6819
6820function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
6821 if (current === null) {
6822 // If this is a fresh new component that hasn't been rendered yet, we
6823 // won't update its child set by applying minimal side-effects. Instead,
6824 // we will add them all to the child before it gets rendered. That means
6825 // we can optimize this reconciliation pass by not tracking side-effects.
6826 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
6827 } else {
6828 // If the current child is the same as the work in progress, it means that
6829 // we haven't yet started any work on these children. Therefore, we use
6830 // the clone algorithm to create a copy of all the current children.
6831
6832 // If we had any progressed work already, that is invalid at this point so
6833 // let's throw it out.
6834 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
6835 }
6836}
6837
6838function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
6839 // This function is fork of reconcileChildren. It's used in cases where we
6840 // want to reconcile without matching against the existing set. This has the
6841 // effect of all current children being unmounted; even if the type and key
6842 // are the same, the old child is unmounted and a new child is created.
6843 //
6844 // To do this, we're going to go through the reconcile algorithm twice. In
6845 // the first pass, we schedule a deletion for all the current children by
6846 // passing null.
6847 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime);
6848 // In the second pass, we mount the new children. The trick here is that we
6849 // pass null in place of where we usually pass the current child set. This has
6850 // the effect of remounting all children regardless of whether their their
6851 // identity matches.
6852 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
6853}
6854
6855function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
6856 // TODO: current can be non-null here even if the component
6857 // hasn't yet mounted. This happens after the first render suspends.
6858 // We'll need to figure out if this is fine or can cause issues.
6859
6860 {
6861 if (workInProgress.type !== workInProgress.elementType) {
6862 // Lazy component props can't be validated in createElement
6863 // because they're only guaranteed to be resolved here.
6864 var innerPropTypes = Component.propTypes;
6865 if (innerPropTypes) {
6866 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6867 'prop', getComponentName(Component), getCurrentFiberStackInDev);
6868 }
6869 }
6870 }
6871
6872 var render = Component.render;
6873 var ref = workInProgress.ref;
6874
6875 // The rest is a fork of updateFunctionComponent
6876 var nextChildren = void 0;
6877 prepareToReadContext(workInProgress, renderExpirationTime);
6878 {
6879 ReactCurrentOwner$2.current = workInProgress;
6880 setCurrentPhase('render');
6881 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
6882 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
6883 // Only double-render components with Hooks
6884 if (workInProgress.memoizedState !== null) {
6885 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
6886 }
6887 }
6888 setCurrentPhase(null);
6889 }
6890
6891 if (current !== null && !didReceiveUpdate) {
6892 bailoutHooks(current, workInProgress, renderExpirationTime);
6893 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6894 }
6895
6896 // React DevTools reads this flag.
6897 workInProgress.effectTag |= PerformedWork;
6898 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6899 return workInProgress.child;
6900}
6901
6902function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
6903 if (current === null) {
6904 var type = Component.type;
6905 if (isSimpleFunctionComponent(type) && Component.compare === null &&
6906 // SimpleMemoComponent codepath doesn't resolve outer props either.
6907 Component.defaultProps === undefined) {
6908 // If this is a plain function component without default props,
6909 // and with only the default shallow comparison, we upgrade it
6910 // to a SimpleMemoComponent to allow fast path updates.
6911 workInProgress.tag = SimpleMemoComponent;
6912 workInProgress.type = type;
6913 {
6914 validateFunctionComponentInDev(workInProgress, type);
6915 }
6916 return updateSimpleMemoComponent(current, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
6917 }
6918 {
6919 var innerPropTypes = type.propTypes;
6920 if (innerPropTypes) {
6921 // Inner memo component props aren't currently validated in createElement.
6922 // We could move it there, but we'd still need this for lazy code path.
6923 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6924 'prop', getComponentName(type), getCurrentFiberStackInDev);
6925 }
6926 }
6927 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
6928 child.ref = workInProgress.ref;
6929 child.return = workInProgress;
6930 workInProgress.child = child;
6931 return child;
6932 }
6933 {
6934 var _type = Component.type;
6935 var _innerPropTypes = _type.propTypes;
6936 if (_innerPropTypes) {
6937 // Inner memo component props aren't currently validated in createElement.
6938 // We could move it there, but we'd still need this for lazy code path.
6939 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
6940 'prop', getComponentName(_type), getCurrentFiberStackInDev);
6941 }
6942 }
6943 var currentChild = current.child; // This is always exactly one child
6944 if (updateExpirationTime < renderExpirationTime) {
6945 // This will be the props with resolved defaultProps,
6946 // unlike current.memoizedProps which will be the unresolved ones.
6947 var prevProps = currentChild.memoizedProps;
6948 // Default to shallow comparison
6949 var compare = Component.compare;
6950 compare = compare !== null ? compare : shallowEqual;
6951 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
6952 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6953 }
6954 }
6955 // React DevTools reads this flag.
6956 workInProgress.effectTag |= PerformedWork;
6957 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
6958 newChild.ref = workInProgress.ref;
6959 newChild.return = workInProgress;
6960 workInProgress.child = newChild;
6961 return newChild;
6962}
6963
6964function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
6965 // TODO: current can be non-null here even if the component
6966 // hasn't yet mounted. This happens when the inner render suspends.
6967 // We'll need to figure out if this is fine or can cause issues.
6968
6969 {
6970 if (workInProgress.type !== workInProgress.elementType) {
6971 // Lazy component props can't be validated in createElement
6972 // because they're only guaranteed to be resolved here.
6973 var outerMemoType = workInProgress.elementType;
6974 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
6975 // We warn when you define propTypes on lazy()
6976 // so let's just skip over it to find memo() outer wrapper.
6977 // Inner props for memo are validated later.
6978 outerMemoType = refineResolvedLazyComponent(outerMemoType);
6979 }
6980 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
6981 if (outerPropTypes) {
6982 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
6983 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
6984 }
6985 // Inner propTypes will be validated in the function component path.
6986 }
6987 }
6988 if (current !== null) {
6989 var prevProps = current.memoizedProps;
6990 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref) {
6991 didReceiveUpdate = false;
6992 if (updateExpirationTime < renderExpirationTime) {
6993 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6994 }
6995 }
6996 }
6997 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
6998}
6999
7000function updateFragment(current, workInProgress, renderExpirationTime) {
7001 var nextChildren = workInProgress.pendingProps;
7002 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7003 return workInProgress.child;
7004}
7005
7006function updateMode(current, workInProgress, renderExpirationTime) {
7007 var nextChildren = workInProgress.pendingProps.children;
7008 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7009 return workInProgress.child;
7010}
7011
7012function updateProfiler(current, workInProgress, renderExpirationTime) {
7013 if (enableProfilerTimer) {
7014 workInProgress.effectTag |= Update;
7015 }
7016 var nextProps = workInProgress.pendingProps;
7017 var nextChildren = nextProps.children;
7018 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7019 return workInProgress.child;
7020}
7021
7022function markRef(current, workInProgress) {
7023 var ref = workInProgress.ref;
7024 if (current === null && ref !== null || current !== null && current.ref !== ref) {
7025 // Schedule a Ref effect
7026 workInProgress.effectTag |= Ref;
7027 }
7028}
7029
7030function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7031 {
7032 if (workInProgress.type !== workInProgress.elementType) {
7033 // Lazy component props can't be validated in createElement
7034 // because they're only guaranteed to be resolved here.
7035 var innerPropTypes = Component.propTypes;
7036 if (innerPropTypes) {
7037 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7038 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7039 }
7040 }
7041 }
7042
7043 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
7044 var context = getMaskedContext(workInProgress, unmaskedContext);
7045
7046 var nextChildren = void 0;
7047 prepareToReadContext(workInProgress, renderExpirationTime);
7048 {
7049 ReactCurrentOwner$2.current = workInProgress;
7050 setCurrentPhase('render');
7051 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7052 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7053 // Only double-render components with Hooks
7054 if (workInProgress.memoizedState !== null) {
7055 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7056 }
7057 }
7058 setCurrentPhase(null);
7059 }
7060
7061 if (current !== null && !didReceiveUpdate) {
7062 bailoutHooks(current, workInProgress, renderExpirationTime);
7063 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7064 }
7065
7066 // React DevTools reads this flag.
7067 workInProgress.effectTag |= PerformedWork;
7068 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7069 return workInProgress.child;
7070}
7071
7072function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7073 {
7074 if (workInProgress.type !== workInProgress.elementType) {
7075 // Lazy component props can't be validated in createElement
7076 // because they're only guaranteed to be resolved here.
7077 var innerPropTypes = Component.propTypes;
7078 if (innerPropTypes) {
7079 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7080 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7081 }
7082 }
7083 }
7084
7085 // Push context providers early to prevent context stack mismatches.
7086 // During mounting we don't know the child context yet as the instance doesn't exist.
7087 // We will invalidate the child context in finishClassComponent() right after rendering.
7088 var hasContext = void 0;
7089 if (isContextProvider(Component)) {
7090 hasContext = true;
7091 pushContextProvider(workInProgress);
7092 } else {
7093 hasContext = false;
7094 }
7095 prepareToReadContext(workInProgress, renderExpirationTime);
7096
7097 var instance = workInProgress.stateNode;
7098 var shouldUpdate = void 0;
7099 if (instance === null) {
7100 if (current !== null) {
7101 // An class component without an instance only mounts if it suspended
7102 // inside a non- concurrent tree, in an inconsistent state. We want to
7103 // tree it like a new mount, even though an empty version of it already
7104 // committed. Disconnect the alternate pointers.
7105 current.alternate = null;
7106 workInProgress.alternate = null;
7107 // Since this is conceptually a new fiber, schedule a Placement effect
7108 workInProgress.effectTag |= Placement;
7109 }
7110 // In the initial pass we might need to construct the instance.
7111 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7112 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7113 shouldUpdate = true;
7114 } else if (current === null) {
7115 // In a resume, we'll already have an instance we can reuse.
7116 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7117 } else {
7118 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
7119 }
7120 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7121 {
7122 var inst = workInProgress.stateNode;
7123 if (inst.props !== nextProps) {
7124 !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;
7125 didWarnAboutReassigningProps = true;
7126 }
7127 }
7128 return nextUnitOfWork;
7129}
7130
7131function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7132 // Refs should update even if shouldComponentUpdate returns false
7133 markRef(current, workInProgress);
7134
7135 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7136
7137 if (!shouldUpdate && !didCaptureError) {
7138 // Context providers should defer to sCU for rendering
7139 if (hasContext) {
7140 invalidateContextProvider(workInProgress, Component, false);
7141 }
7142
7143 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7144 }
7145
7146 var instance = workInProgress.stateNode;
7147
7148 // Rerender
7149 ReactCurrentOwner$2.current = workInProgress;
7150 var nextChildren = void 0;
7151 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7152 // If we captured an error, but getDerivedStateFrom catch is not defined,
7153 // unmount all the children. componentDidCatch will schedule an update to
7154 // re-render a fallback. This is temporary until we migrate everyone to
7155 // the new API.
7156 // TODO: Warn in a future release.
7157 nextChildren = null;
7158
7159 if (enableProfilerTimer) {
7160 stopProfilerTimerIfRunning(workInProgress);
7161 }
7162 } else {
7163 {
7164 setCurrentPhase('render');
7165 nextChildren = instance.render();
7166 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7167 instance.render();
7168 }
7169 setCurrentPhase(null);
7170 }
7171 }
7172
7173 // React DevTools reads this flag.
7174 workInProgress.effectTag |= PerformedWork;
7175 if (current !== null && didCaptureError) {
7176 // If we're recovering from an error, reconcile without reusing any of
7177 // the existing children. Conceptually, the normal children and the children
7178 // that are shown on error are two different sets, so we shouldn't reuse
7179 // normal children even if their identities match.
7180 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
7181 } else {
7182 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7183 }
7184
7185 // Memoize state using the values we just used to render.
7186 // TODO: Restructure so we never read values from the instance.
7187 workInProgress.memoizedState = instance.state;
7188
7189 // The context might have changed so we need to recalculate it.
7190 if (hasContext) {
7191 invalidateContextProvider(workInProgress, Component, true);
7192 }
7193
7194 return workInProgress.child;
7195}
7196
7197function pushHostRootContext(workInProgress) {
7198 var root = workInProgress.stateNode;
7199 if (root.pendingContext) {
7200 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7201 } else if (root.context) {
7202 // Should always be set
7203 pushTopLevelContextObject(workInProgress, root.context, false);
7204 }
7205 pushHostContainer(workInProgress, root.containerInfo);
7206}
7207
7208function updateHostRoot(current, workInProgress, renderExpirationTime) {
7209 pushHostRootContext(workInProgress);
7210 var updateQueue = workInProgress.updateQueue;
7211 !(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;
7212 var nextProps = workInProgress.pendingProps;
7213 var prevState = workInProgress.memoizedState;
7214 var prevChildren = prevState !== null ? prevState.element : null;
7215 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
7216 var nextState = workInProgress.memoizedState;
7217 // Caution: React DevTools currently depends on this property
7218 // being called "element".
7219 var nextChildren = nextState.element;
7220 if (nextChildren === prevChildren) {
7221 // If the state is the same as before, that's a bailout because we had
7222 // no work that expires at this time.
7223 resetHydrationState();
7224 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7225 }
7226 var root = workInProgress.stateNode;
7227 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
7228 // If we don't have any current children this might be the first pass.
7229 // We always try to hydrate. If this isn't a hydration pass there won't
7230 // be any children to hydrate which is effectively the same thing as
7231 // not hydrating.
7232
7233 // This is a bit of a hack. We track the host root as a placement to
7234 // know that we're currently in a mounting state. That way isMounted
7235 // works as expected. We must reset this before committing.
7236 // TODO: Delete this when we delete isMounted and findDOMNode.
7237 workInProgress.effectTag |= Placement;
7238
7239 // Ensure that children mount into this root without tracking
7240 // side-effects. This ensures that we don't store Placement effects on
7241 // nodes that will be hydrated.
7242 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7243 } else {
7244 // Otherwise reset hydration state in case we aborted and resumed another
7245 // root.
7246 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7247 resetHydrationState();
7248 }
7249 return workInProgress.child;
7250}
7251
7252function updateHostComponent(current, workInProgress, renderExpirationTime) {
7253 pushHostContext(workInProgress);
7254
7255 if (current === null) {
7256 tryToClaimNextHydratableInstance(workInProgress);
7257 }
7258
7259 var type = workInProgress.type;
7260 var nextProps = workInProgress.pendingProps;
7261 var prevProps = current !== null ? current.memoizedProps : null;
7262
7263 var nextChildren = nextProps.children;
7264 var isDirectTextChild = shouldSetTextContent(type, nextProps);
7265
7266 if (isDirectTextChild) {
7267 // We special case a direct text child of a host node. This is a common
7268 // case. We won't handle it as a reified child. We will instead handle
7269 // this in the host environment that also have access to this prop. That
7270 // avoids allocating another HostText fiber and traversing it.
7271 nextChildren = null;
7272 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
7273 // If we're switching from a direct text child to a normal child, or to
7274 // empty, we need to schedule the text content to be reset.
7275 workInProgress.effectTag |= ContentReset;
7276 }
7277
7278 markRef(current, workInProgress);
7279
7280 // Check the host config to see if the children are offscreen/hidden.
7281 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
7282 // Schedule this fiber to re-render at offscreen priority. Then bailout.
7283 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7284 return null;
7285 }
7286
7287 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7288 return workInProgress.child;
7289}
7290
7291function updateHostText(current, workInProgress) {
7292 if (current === null) {
7293 tryToClaimNextHydratableInstance(workInProgress);
7294 }
7295 // Nothing to do here. This is terminal. We'll do the completion step
7296 // immediately after.
7297 return null;
7298}
7299
7300function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7301 if (_current !== null) {
7302 // An lazy component only mounts if it suspended inside a non-
7303 // concurrent tree, in an inconsistent state. We want to treat it like
7304 // a new mount, even though an empty version of it already committed.
7305 // Disconnect the alternate pointers.
7306 _current.alternate = null;
7307 workInProgress.alternate = null;
7308 // Since this is conceptually a new fiber, schedule a Placement effect
7309 workInProgress.effectTag |= Placement;
7310 }
7311
7312 var props = workInProgress.pendingProps;
7313 // We can't start a User Timing measurement with correct label yet.
7314 // Cancel and resume right after we know the tag.
7315 cancelWorkTimer(workInProgress);
7316 var Component = readLazyComponentType(elementType);
7317 // Store the unwrapped component in the type.
7318 workInProgress.type = Component;
7319 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
7320 startWorkTimer(workInProgress);
7321 var resolvedProps = resolveDefaultProps(Component, props);
7322 var child = void 0;
7323 switch (resolvedTag) {
7324 case FunctionComponent:
7325 {
7326 {
7327 validateFunctionComponentInDev(workInProgress, Component);
7328 }
7329 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7330 break;
7331 }
7332 case ClassComponent:
7333 {
7334 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7335 break;
7336 }
7337 case ForwardRef:
7338 {
7339 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7340 break;
7341 }
7342 case MemoComponent:
7343 {
7344 {
7345 if (workInProgress.type !== workInProgress.elementType) {
7346 var outerPropTypes = Component.propTypes;
7347 if (outerPropTypes) {
7348 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
7349 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7350 }
7351 }
7352 }
7353 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
7354 updateExpirationTime, renderExpirationTime);
7355 break;
7356 }
7357 default:
7358 {
7359 var hint = '';
7360 {
7361 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
7362 hint = ' Did you wrap a component in React.lazy() more than once?';
7363 }
7364 }
7365 // This message intentionally doesn't mention ForwardRef or MemoComponent
7366 // because the fact that it's a separate type of work is an
7367 // implementation detail.
7368 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);
7369 }
7370 }
7371 return child;
7372}
7373
7374function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
7375 if (_current !== null) {
7376 // An incomplete component only mounts if it suspended inside a non-
7377 // concurrent tree, in an inconsistent state. We want to treat it like
7378 // a new mount, even though an empty version of it already committed.
7379 // Disconnect the alternate pointers.
7380 _current.alternate = null;
7381 workInProgress.alternate = null;
7382 // Since this is conceptually a new fiber, schedule a Placement effect
7383 workInProgress.effectTag |= Placement;
7384 }
7385
7386 // Promote the fiber to a class and try rendering again.
7387 workInProgress.tag = ClassComponent;
7388
7389 // The rest of this function is a fork of `updateClassComponent`
7390
7391 // Push context providers early to prevent context stack mismatches.
7392 // During mounting we don't know the child context yet as the instance doesn't exist.
7393 // We will invalidate the child context in finishClassComponent() right after rendering.
7394 var hasContext = void 0;
7395 if (isContextProvider(Component)) {
7396 hasContext = true;
7397 pushContextProvider(workInProgress);
7398 } else {
7399 hasContext = false;
7400 }
7401 prepareToReadContext(workInProgress, renderExpirationTime);
7402
7403 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7404 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7405
7406 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7407}
7408
7409function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
7410 if (_current !== null) {
7411 // An indeterminate component only mounts if it suspended inside a non-
7412 // concurrent tree, in an inconsistent state. We want to treat it like
7413 // a new mount, even though an empty version of it already committed.
7414 // Disconnect the alternate pointers.
7415 _current.alternate = null;
7416 workInProgress.alternate = null;
7417 // Since this is conceptually a new fiber, schedule a Placement effect
7418 workInProgress.effectTag |= Placement;
7419 }
7420
7421 var props = workInProgress.pendingProps;
7422 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
7423 var context = getMaskedContext(workInProgress, unmaskedContext);
7424
7425 prepareToReadContext(workInProgress, renderExpirationTime);
7426
7427 var value = void 0;
7428
7429 {
7430 if (Component.prototype && typeof Component.prototype.render === 'function') {
7431 var componentName = getComponentName(Component) || 'Unknown';
7432
7433 if (!didWarnAboutBadClass[componentName]) {
7434 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);
7435 didWarnAboutBadClass[componentName] = true;
7436 }
7437 }
7438
7439 if (workInProgress.mode & StrictMode) {
7440 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
7441 }
7442
7443 ReactCurrentOwner$2.current = workInProgress;
7444 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7445 }
7446 // React DevTools reads this flag.
7447 workInProgress.effectTag |= PerformedWork;
7448
7449 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
7450 // Proceed under the assumption that this is a class instance
7451 workInProgress.tag = ClassComponent;
7452
7453 // Throw out any hooks that were used.
7454 resetHooks();
7455
7456 // Push context providers early to prevent context stack mismatches.
7457 // During mounting we don't know the child context yet as the instance doesn't exist.
7458 // We will invalidate the child context in finishClassComponent() right after rendering.
7459 var hasContext = false;
7460 if (isContextProvider(Component)) {
7461 hasContext = true;
7462 pushContextProvider(workInProgress);
7463 } else {
7464 hasContext = false;
7465 }
7466
7467 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
7468
7469 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
7470 if (typeof getDerivedStateFromProps === 'function') {
7471 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
7472 }
7473
7474 adoptClassInstance(workInProgress, value);
7475 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
7476 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7477 } else {
7478 // Proceed under the assumption that this is a function component
7479 workInProgress.tag = FunctionComponent;
7480 {
7481 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7482 // Only double-render components with Hooks
7483 if (workInProgress.memoizedState !== null) {
7484 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7485 }
7486 }
7487 }
7488 reconcileChildren(null, workInProgress, value, renderExpirationTime);
7489 {
7490 validateFunctionComponentInDev(workInProgress, Component);
7491 }
7492 return workInProgress.child;
7493 }
7494}
7495
7496function validateFunctionComponentInDev(workInProgress, Component) {
7497 if (Component) {
7498 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
7499 }
7500 if (workInProgress.ref !== null) {
7501 var info = '';
7502 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
7503 if (ownerName) {
7504 info += '\n\nCheck the render method of `' + ownerName + '`.';
7505 }
7506
7507 var warningKey = ownerName || workInProgress._debugID || '';
7508 var debugSource = workInProgress._debugSource;
7509 if (debugSource) {
7510 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
7511 }
7512 if (!didWarnAboutFunctionRefs[warningKey]) {
7513 didWarnAboutFunctionRefs[warningKey] = true;
7514 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);
7515 }
7516 }
7517
7518 if (typeof Component.getDerivedStateFromProps === 'function') {
7519 var componentName = getComponentName(Component) || 'Unknown';
7520
7521 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
7522 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
7523 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
7524 }
7525 }
7526
7527 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
7528 var _componentName = getComponentName(Component) || 'Unknown';
7529
7530 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
7531 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
7532 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
7533 }
7534 }
7535}
7536
7537function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
7538 var mode = workInProgress.mode;
7539 var nextProps = workInProgress.pendingProps;
7540
7541 // We should attempt to render the primary children unless this boundary
7542 // already suspended during this render (`alreadyCaptured` is true).
7543 var nextState = workInProgress.memoizedState;
7544
7545 var nextDidTimeout = void 0;
7546 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
7547 // This is the first attempt.
7548 nextState = null;
7549 nextDidTimeout = false;
7550 } else {
7551 // Something in this boundary's subtree already suspended. Switch to
7552 // rendering the fallback children.
7553 nextState = {
7554 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
7555 };
7556 nextDidTimeout = true;
7557 workInProgress.effectTag &= ~DidCapture;
7558 }
7559
7560 // This next part is a bit confusing. If the children timeout, we switch to
7561 // showing the fallback children in place of the "primary" children.
7562 // However, we don't want to delete the primary children because then their
7563 // state will be lost (both the React state and the host state, e.g.
7564 // uncontrolled form inputs). Instead we keep them mounted and hide them.
7565 // Both the fallback children AND the primary children are rendered at the
7566 // same time. Once the primary children are un-suspended, we can delete
7567 // the fallback children — don't need to preserve their state.
7568 //
7569 // The two sets of children are siblings in the host environment, but
7570 // semantically, for purposes of reconciliation, they are two separate sets.
7571 // So we store them using two fragment fibers.
7572 //
7573 // However, we want to avoid allocating extra fibers for every placeholder.
7574 // They're only necessary when the children time out, because that's the
7575 // only time when both sets are mounted.
7576 //
7577 // So, the extra fragment fibers are only used if the children time out.
7578 // Otherwise, we render the primary children directly. This requires some
7579 // custom reconciliation logic to preserve the state of the primary
7580 // children. It's essentially a very basic form of re-parenting.
7581
7582 // `child` points to the child fiber. In the normal case, this is the first
7583 // fiber of the primary children set. In the timed-out case, it's a
7584 // a fragment fiber containing the primary children.
7585 var child = void 0;
7586 // `next` points to the next fiber React should render. In the normal case,
7587 // it's the same as `child`: the first fiber of the primary children set.
7588 // In the timed-out case, it's a fragment fiber containing the *fallback*
7589 // children -- we skip over the primary children entirely.
7590 var next = void 0;
7591 if (current === null) {
7592 if (enableSuspenseServerRenderer) {
7593 // If we're currently hydrating, try to hydrate this boundary.
7594 // But only if this has a fallback.
7595 if (nextProps.fallback !== undefined) {
7596 tryToClaimNextHydratableInstance(workInProgress);
7597 // This could've changed the tag if this was a dehydrated suspense component.
7598 if (workInProgress.tag === DehydratedSuspenseComponent) {
7599 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
7600 }
7601 }
7602 }
7603
7604 // This is the initial mount. This branch is pretty simple because there's
7605 // no previous state that needs to be preserved.
7606 if (nextDidTimeout) {
7607 // Mount separate fragments for primary and fallback children.
7608 var nextFallbackChildren = nextProps.fallback;
7609 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
7610
7611 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7612 // Outside of concurrent mode, we commit the effects from the
7613 var progressedState = workInProgress.memoizedState;
7614 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
7615 primaryChildFragment.child = progressedPrimaryChild;
7616 }
7617
7618 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
7619 primaryChildFragment.sibling = fallbackChildFragment;
7620 child = primaryChildFragment;
7621 // Skip the primary children, and continue working on the
7622 // fallback children.
7623 next = fallbackChildFragment;
7624 child.return = next.return = workInProgress;
7625 } else {
7626 // Mount the primary children without an intermediate fragment fiber.
7627 var nextPrimaryChildren = nextProps.children;
7628 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
7629 }
7630 } else {
7631 // This is an update. This branch is more complicated because we need to
7632 // ensure the state of the primary children is preserved.
7633 var prevState = current.memoizedState;
7634 var prevDidTimeout = prevState !== null;
7635 if (prevDidTimeout) {
7636 // The current tree already timed out. That means each child set is
7637 var currentPrimaryChildFragment = current.child;
7638 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
7639 if (nextDidTimeout) {
7640 // Still timed out. Reuse the current primary children by cloning
7641 // its fragment. We're going to skip over these entirely.
7642 var _nextFallbackChildren = nextProps.fallback;
7643 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
7644
7645 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7646 // Outside of concurrent mode, we commit the effects from the
7647 var _progressedState = workInProgress.memoizedState;
7648 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
7649 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
7650 _primaryChildFragment.child = _progressedPrimaryChild;
7651 }
7652 }
7653
7654 // Because primaryChildFragment is a new fiber that we're inserting as the
7655 // parent of a new tree, we need to set its treeBaseDuration.
7656 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7657 // treeBaseDuration is the sum of all the child tree base durations.
7658 var treeBaseDuration = 0;
7659 var hiddenChild = _primaryChildFragment.child;
7660 while (hiddenChild !== null) {
7661 treeBaseDuration += hiddenChild.treeBaseDuration;
7662 hiddenChild = hiddenChild.sibling;
7663 }
7664 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
7665 }
7666
7667 // Clone the fallback child fragment, too. These we'll continue
7668 // working on.
7669 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
7670 child = _primaryChildFragment;
7671 _primaryChildFragment.childExpirationTime = NoWork;
7672 // Skip the primary children, and continue working on the
7673 // fallback children.
7674 next = _fallbackChildFragment;
7675 child.return = next.return = workInProgress;
7676 } else {
7677 // No longer suspended. Switch back to showing the primary children,
7678 // and remove the intermediate fragment fiber.
7679 var _nextPrimaryChildren = nextProps.children;
7680 var currentPrimaryChild = currentPrimaryChildFragment.child;
7681 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
7682
7683 // If this render doesn't suspend, we need to delete the fallback
7684 // children. Wait until the complete phase, after we've confirmed the
7685 // fallback is no longer needed.
7686 // TODO: Would it be better to store the fallback fragment on
7687 // the stateNode?
7688
7689 // Continue rendering the children, like we normally do.
7690 child = next = primaryChild;
7691 }
7692 } else {
7693 // The current tree has not already timed out. That means the primary
7694 // children are not wrapped in a fragment fiber.
7695 var _currentPrimaryChild = current.child;
7696 if (nextDidTimeout) {
7697 // Timed out. Wrap the children in a fragment fiber to keep them
7698 // separate from the fallback children.
7699 var _nextFallbackChildren2 = nextProps.fallback;
7700 var _primaryChildFragment2 = createFiberFromFragment(
7701 // It shouldn't matter what the pending props are because we aren't
7702 // going to render this fragment.
7703 null, mode, NoWork, null);
7704 _primaryChildFragment2.child = _currentPrimaryChild;
7705
7706 // Even though we're creating a new fiber, there are no new children,
7707 // because we're reusing an already mounted tree. So we don't need to
7708 // schedule a placement.
7709 // primaryChildFragment.effectTag |= Placement;
7710
7711 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7712 // Outside of concurrent mode, we commit the effects from the
7713 var _progressedState2 = workInProgress.memoizedState;
7714 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
7715 _primaryChildFragment2.child = _progressedPrimaryChild2;
7716 }
7717
7718 // Because primaryChildFragment is a new fiber that we're inserting as the
7719 // parent of a new tree, we need to set its treeBaseDuration.
7720 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7721 // treeBaseDuration is the sum of all the child tree base durations.
7722 var _treeBaseDuration = 0;
7723 var _hiddenChild = _primaryChildFragment2.child;
7724 while (_hiddenChild !== null) {
7725 _treeBaseDuration += _hiddenChild.treeBaseDuration;
7726 _hiddenChild = _hiddenChild.sibling;
7727 }
7728 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
7729 }
7730
7731 // Create a fragment from the fallback children, too.
7732 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
7733 _fallbackChildFragment2.effectTag |= Placement;
7734 child = _primaryChildFragment2;
7735 _primaryChildFragment2.childExpirationTime = NoWork;
7736 // Skip the primary children, and continue working on the
7737 // fallback children.
7738 next = _fallbackChildFragment2;
7739 child.return = next.return = workInProgress;
7740 } else {
7741 // Still haven't timed out. Continue rendering the children, like we
7742 // normally do.
7743 var _nextPrimaryChildren2 = nextProps.children;
7744 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
7745 }
7746 }
7747 workInProgress.stateNode = current.stateNode;
7748 }
7749
7750 workInProgress.memoizedState = nextState;
7751 workInProgress.child = child;
7752 return next;
7753}
7754
7755function updateDehydratedSuspenseComponent(current, workInProgress, renderExpirationTime) {
7756 if (current === null) {
7757 // During the first pass, we'll bail out and not drill into the children.
7758 // Instead, we'll leave the content in place and try to hydrate it later.
7759 workInProgress.expirationTime = Never;
7760 return null;
7761 }
7762 // We use childExpirationTime to indicate that a child might depend on context, so if
7763 // any context has changed, we need to treat is as if the input might have changed.
7764 var hasContextChanged$$1 = current.childExpirationTime >= renderExpirationTime;
7765 if (didReceiveUpdate || hasContextChanged$$1) {
7766 // This boundary has changed since the first render. This means that we are now unable to
7767 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
7768 // during this render we can't. Instead, we're going to delete the whole subtree and
7769 // instead inject a new real Suspense boundary to take its place, which may render content
7770 // or fallback. The real Suspense boundary will suspend for a while so we have some time
7771 // to ensure it can produce real content, but all state and pending events will be lost.
7772
7773 // Detach from the current dehydrated boundary.
7774 current.alternate = null;
7775 workInProgress.alternate = null;
7776
7777 // Insert a deletion in the effect list.
7778 var returnFiber = workInProgress.return;
7779 !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
7780 var last = returnFiber.lastEffect;
7781 if (last !== null) {
7782 last.nextEffect = current;
7783 returnFiber.lastEffect = current;
7784 } else {
7785 returnFiber.firstEffect = returnFiber.lastEffect = current;
7786 }
7787 current.nextEffect = null;
7788 current.effectTag = Deletion;
7789
7790 // Upgrade this work in progress to a real Suspense component.
7791 workInProgress.tag = SuspenseComponent;
7792 workInProgress.stateNode = null;
7793 workInProgress.memoizedState = null;
7794 // This is now an insertion.
7795 workInProgress.effectTag |= Placement;
7796 // Retry as a real Suspense component.
7797 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
7798 }
7799 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
7800 // This is the first attempt.
7801 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
7802 var nextProps = workInProgress.pendingProps;
7803 var nextChildren = nextProps.children;
7804 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7805 return workInProgress.child;
7806 } else {
7807 // Something suspended. Leave the existing children in place.
7808 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
7809 workInProgress.child = null;
7810 return null;
7811 }
7812}
7813
7814function updatePortalComponent(current, workInProgress, renderExpirationTime) {
7815 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
7816 var nextChildren = workInProgress.pendingProps;
7817 if (current === null) {
7818 // Portals are special because we don't append the children during mount
7819 // but at commit. Therefore we need to track insertions which the normal
7820 // flow doesn't do during mount. This doesn't happen at the root because
7821 // the root always starts with a "current" with a null child.
7822 // TODO: Consider unifying this with how the root works.
7823 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7824 } else {
7825 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7826 }
7827 return workInProgress.child;
7828}
7829
7830function updateContextProvider(current, workInProgress, renderExpirationTime) {
7831 var providerType = workInProgress.type;
7832 var context = providerType._context;
7833
7834 var newProps = workInProgress.pendingProps;
7835 var oldProps = workInProgress.memoizedProps;
7836
7837 var newValue = newProps.value;
7838
7839 {
7840 var providerPropTypes = workInProgress.type.propTypes;
7841
7842 if (providerPropTypes) {
7843 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
7844 }
7845 }
7846
7847 pushProvider(workInProgress, newValue);
7848
7849 if (oldProps !== null) {
7850 var oldValue = oldProps.value;
7851 var changedBits = calculateChangedBits(context, newValue, oldValue);
7852 if (changedBits === 0) {
7853 // No change. Bailout early if children are the same.
7854 if (oldProps.children === newProps.children && !hasContextChanged()) {
7855 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7856 }
7857 } else {
7858 // The context value changed. Search for matching consumers and schedule
7859 // them to update.
7860 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
7861 }
7862 }
7863
7864 var newChildren = newProps.children;
7865 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
7866 return workInProgress.child;
7867}
7868
7869var hasWarnedAboutUsingContextAsConsumer = false;
7870
7871function updateContextConsumer(current, workInProgress, renderExpirationTime) {
7872 var context = workInProgress.type;
7873 // The logic below for Context differs depending on PROD or DEV mode. In
7874 // DEV mode, we create a separate object for Context.Consumer that acts
7875 // like a proxy to Context. This proxy object adds unnecessary code in PROD
7876 // so we use the old behaviour (Context.Consumer references Context) to
7877 // reduce size and overhead. The separate object references context via
7878 // a property called "_context", which also gives us the ability to check
7879 // in DEV mode if this property exists or not and warn if it does not.
7880 {
7881 if (context._context === undefined) {
7882 // This may be because it's a Context (rather than a Consumer).
7883 // Or it may be because it's older React where they're the same thing.
7884 // We only want to warn if we're sure it's a new React.
7885 if (context !== context.Consumer) {
7886 if (!hasWarnedAboutUsingContextAsConsumer) {
7887 hasWarnedAboutUsingContextAsConsumer = true;
7888 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?');
7889 }
7890 }
7891 } else {
7892 context = context._context;
7893 }
7894 }
7895 var newProps = workInProgress.pendingProps;
7896 var render = newProps.children;
7897
7898 {
7899 !(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;
7900 }
7901
7902 prepareToReadContext(workInProgress, renderExpirationTime);
7903 var newValue = readContext(context, newProps.unstable_observedBits);
7904 var newChildren = void 0;
7905 {
7906 ReactCurrentOwner$2.current = workInProgress;
7907 setCurrentPhase('render');
7908 newChildren = render(newValue);
7909 setCurrentPhase(null);
7910 }
7911
7912 // React DevTools reads this flag.
7913 workInProgress.effectTag |= PerformedWork;
7914 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
7915 return workInProgress.child;
7916}
7917
7918function markWorkInProgressReceivedUpdate() {
7919 didReceiveUpdate = true;
7920}
7921
7922function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
7923 cancelWorkTimer(workInProgress);
7924
7925 if (current !== null) {
7926 // Reuse previous context list
7927 workInProgress.contextDependencies = current.contextDependencies;
7928 }
7929
7930 if (enableProfilerTimer) {
7931 // Don't update "base" render times for bailouts.
7932 stopProfilerTimerIfRunning(workInProgress);
7933 }
7934
7935 // Check if the children have any pending work.
7936 var childExpirationTime = workInProgress.childExpirationTime;
7937 if (childExpirationTime < renderExpirationTime) {
7938 // The children don't have any work either. We can skip them.
7939 // TODO: Once we add back resuming, we should check if the children are
7940 // a work-in-progress set. If so, we need to transfer their effects.
7941 return null;
7942 } else {
7943 // This fiber doesn't have work, but its subtree does. Clone the child
7944 // fibers and continue.
7945 cloneChildFibers(current, workInProgress);
7946 return workInProgress.child;
7947 }
7948}
7949
7950function beginWork(current, workInProgress, renderExpirationTime) {
7951 var updateExpirationTime = workInProgress.expirationTime;
7952
7953 if (current !== null) {
7954 var oldProps = current.memoizedProps;
7955 var newProps = workInProgress.pendingProps;
7956
7957 if (oldProps !== newProps || hasContextChanged()) {
7958 // If props or context changed, mark the fiber as having performed work.
7959 // This may be unset if the props are determined to be equal later (memo).
7960 didReceiveUpdate = true;
7961 } else if (updateExpirationTime < renderExpirationTime) {
7962 didReceiveUpdate = false;
7963 // This fiber does not have any pending work. Bailout without entering
7964 // the begin phase. There's still some bookkeeping we that needs to be done
7965 // in this optimized path, mostly pushing stuff onto the stack.
7966 switch (workInProgress.tag) {
7967 case HostRoot:
7968 pushHostRootContext(workInProgress);
7969 resetHydrationState();
7970 break;
7971 case HostComponent:
7972 pushHostContext(workInProgress);
7973 break;
7974 case ClassComponent:
7975 {
7976 var Component = workInProgress.type;
7977 if (isContextProvider(Component)) {
7978 pushContextProvider(workInProgress);
7979 }
7980 break;
7981 }
7982 case HostPortal:
7983 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
7984 break;
7985 case ContextProvider:
7986 {
7987 var newValue = workInProgress.memoizedProps.value;
7988 pushProvider(workInProgress, newValue);
7989 break;
7990 }
7991 case Profiler:
7992 if (enableProfilerTimer) {
7993 workInProgress.effectTag |= Update;
7994 }
7995 break;
7996 case SuspenseComponent:
7997 {
7998 var state = workInProgress.memoizedState;
7999 var didTimeout = state !== null;
8000 if (didTimeout) {
8001 // If this boundary is currently timed out, we need to decide
8002 // whether to retry the primary children, or to skip over it and
8003 // go straight to the fallback. Check the priority of the primary
8004 var primaryChildFragment = workInProgress.child;
8005 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
8006 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
8007 // The primary children have pending work. Use the normal path
8008 // to attempt to render the primary children again.
8009 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
8010 } else {
8011 // The primary children do not have pending work with sufficient
8012 // priority. Bailout.
8013 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8014 if (child !== null) {
8015 // The fallback children have pending work. Skip over the
8016 // primary children and work on the fallback.
8017 return child.sibling;
8018 } else {
8019 return null;
8020 }
8021 }
8022 }
8023 break;
8024 }
8025 case DehydratedSuspenseComponent:
8026 {
8027 if (enableSuspenseServerRenderer) {
8028 // We know that this component will suspend again because if it has
8029 // been unsuspended it has committed as a regular Suspense component.
8030 // If it needs to be retried, it should have work scheduled on it.
8031 workInProgress.effectTag |= DidCapture;
8032 break;
8033 }
8034 }
8035 }
8036 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8037 }
8038 } else {
8039 didReceiveUpdate = false;
8040 }
8041
8042 // Before entering the begin phase, clear the expiration time.
8043 workInProgress.expirationTime = NoWork;
8044
8045 switch (workInProgress.tag) {
8046 case IndeterminateComponent:
8047 {
8048 var elementType = workInProgress.elementType;
8049 return mountIndeterminateComponent(current, workInProgress, elementType, renderExpirationTime);
8050 }
8051 case LazyComponent:
8052 {
8053 var _elementType = workInProgress.elementType;
8054 return mountLazyComponent(current, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
8055 }
8056 case FunctionComponent:
8057 {
8058 var _Component = workInProgress.type;
8059 var unresolvedProps = workInProgress.pendingProps;
8060 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
8061 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
8062 }
8063 case ClassComponent:
8064 {
8065 var _Component2 = workInProgress.type;
8066 var _unresolvedProps = workInProgress.pendingProps;
8067 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
8068 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
8069 }
8070 case HostRoot:
8071 return updateHostRoot(current, workInProgress, renderExpirationTime);
8072 case HostComponent:
8073 return updateHostComponent(current, workInProgress, renderExpirationTime);
8074 case HostText:
8075 return updateHostText(current, workInProgress);
8076 case SuspenseComponent:
8077 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
8078 case HostPortal:
8079 return updatePortalComponent(current, workInProgress, renderExpirationTime);
8080 case ForwardRef:
8081 {
8082 var type = workInProgress.type;
8083 var _unresolvedProps2 = workInProgress.pendingProps;
8084 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
8085 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
8086 }
8087 case Fragment:
8088 return updateFragment(current, workInProgress, renderExpirationTime);
8089 case Mode:
8090 return updateMode(current, workInProgress, renderExpirationTime);
8091 case Profiler:
8092 return updateProfiler(current, workInProgress, renderExpirationTime);
8093 case ContextProvider:
8094 return updateContextProvider(current, workInProgress, renderExpirationTime);
8095 case ContextConsumer:
8096 return updateContextConsumer(current, workInProgress, renderExpirationTime);
8097 case MemoComponent:
8098 {
8099 var _type2 = workInProgress.type;
8100 var _unresolvedProps3 = workInProgress.pendingProps;
8101 // Resolve outer props first, then resolve inner props.
8102 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
8103 {
8104 if (workInProgress.type !== workInProgress.elementType) {
8105 var outerPropTypes = _type2.propTypes;
8106 if (outerPropTypes) {
8107 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
8108 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
8109 }
8110 }
8111 }
8112 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
8113 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
8114 }
8115 case SimpleMemoComponent:
8116 {
8117 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
8118 }
8119 case IncompleteClassComponent:
8120 {
8121 var _Component3 = workInProgress.type;
8122 var _unresolvedProps4 = workInProgress.pendingProps;
8123 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
8124 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
8125 }
8126 case DehydratedSuspenseComponent:
8127 {
8128 if (enableSuspenseServerRenderer) {
8129 return updateDehydratedSuspenseComponent(current, workInProgress, renderExpirationTime);
8130 }
8131 break;
8132 }
8133 }
8134 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
8135}
8136
8137var valueCursor = createCursor(null);
8138
8139var rendererSigil = void 0;
8140{
8141 // Use this to detect multiple renderers using the same context
8142 rendererSigil = {};
8143}
8144
8145var currentlyRenderingFiber = null;
8146var lastContextDependency = null;
8147var lastContextWithAllBitsObserved = null;
8148
8149var isDisallowedContextReadInDEV = false;
8150
8151function resetContextDependences() {
8152 // This is called right before React yields execution, to ensure `readContext`
8153 // cannot be called outside the render phase.
8154 currentlyRenderingFiber = null;
8155 lastContextDependency = null;
8156 lastContextWithAllBitsObserved = null;
8157 {
8158 isDisallowedContextReadInDEV = false;
8159 }
8160}
8161
8162function enterDisallowedContextReadInDEV() {
8163 {
8164 isDisallowedContextReadInDEV = true;
8165 }
8166}
8167
8168function exitDisallowedContextReadInDEV() {
8169 {
8170 isDisallowedContextReadInDEV = false;
8171 }
8172}
8173
8174function pushProvider(providerFiber, nextValue) {
8175 var context = providerFiber.type._context;
8176
8177 if (isPrimaryRenderer) {
8178 push(valueCursor, context._currentValue, providerFiber);
8179
8180 context._currentValue = nextValue;
8181 {
8182 !(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;
8183 context._currentRenderer = rendererSigil;
8184 }
8185 } else {
8186 push(valueCursor, context._currentValue2, providerFiber);
8187
8188 context._currentValue2 = nextValue;
8189 {
8190 !(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;
8191 context._currentRenderer2 = rendererSigil;
8192 }
8193 }
8194}
8195
8196function popProvider(providerFiber) {
8197 var currentValue = valueCursor.current;
8198
8199 pop(valueCursor, providerFiber);
8200
8201 var context = providerFiber.type._context;
8202 if (isPrimaryRenderer) {
8203 context._currentValue = currentValue;
8204 } else {
8205 context._currentValue2 = currentValue;
8206 }
8207}
8208
8209function calculateChangedBits(context, newValue, oldValue) {
8210 if (is(oldValue, newValue)) {
8211 // No change
8212 return 0;
8213 } else {
8214 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
8215
8216 {
8217 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
8218 }
8219 return changedBits | 0;
8220 }
8221}
8222
8223function scheduleWorkOnParentPath(parent, renderExpirationTime) {
8224 // Update the child expiration time of all the ancestors, including
8225 // the alternates.
8226 var node = parent;
8227 while (node !== null) {
8228 var alternate = node.alternate;
8229 if (node.childExpirationTime < renderExpirationTime) {
8230 node.childExpirationTime = renderExpirationTime;
8231 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8232 alternate.childExpirationTime = renderExpirationTime;
8233 }
8234 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8235 alternate.childExpirationTime = renderExpirationTime;
8236 } else {
8237 // Neither alternate was updated, which means the rest of the
8238 // ancestor path already has sufficient priority.
8239 break;
8240 }
8241 node = node.return;
8242 }
8243}
8244
8245function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
8246 var fiber = workInProgress.child;
8247 if (fiber !== null) {
8248 // Set the return pointer of the child to the work-in-progress fiber.
8249 fiber.return = workInProgress;
8250 }
8251 while (fiber !== null) {
8252 var nextFiber = void 0;
8253
8254 // Visit this fiber.
8255 var list = fiber.contextDependencies;
8256 if (list !== null) {
8257 nextFiber = fiber.child;
8258
8259 var dependency = list.first;
8260 while (dependency !== null) {
8261 // Check if the context matches.
8262 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
8263 // Match! Schedule an update on this fiber.
8264
8265 if (fiber.tag === ClassComponent) {
8266 // Schedule a force update on the work-in-progress.
8267 var update = createUpdate(renderExpirationTime);
8268 update.tag = ForceUpdate;
8269 // TODO: Because we don't have a work-in-progress, this will add the
8270 // update to the current fiber, too, which means it will persist even if
8271 // this render is thrown away. Since it's a race condition, not sure it's
8272 // worth fixing.
8273 enqueueUpdate(fiber, update);
8274 }
8275
8276 if (fiber.expirationTime < renderExpirationTime) {
8277 fiber.expirationTime = renderExpirationTime;
8278 }
8279 var alternate = fiber.alternate;
8280 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8281 alternate.expirationTime = renderExpirationTime;
8282 }
8283
8284 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
8285
8286 // Mark the expiration time on the list, too.
8287 if (list.expirationTime < renderExpirationTime) {
8288 list.expirationTime = renderExpirationTime;
8289 }
8290
8291 // Since we already found a match, we can stop traversing the
8292 // dependency list.
8293 break;
8294 }
8295 dependency = dependency.next;
8296 }
8297 } else if (fiber.tag === ContextProvider) {
8298 // Don't scan deeper if this is a matching provider
8299 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
8300 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
8301 // If a dehydrated suspense component is in this subtree, we don't know
8302 // if it will have any context consumers in it. The best we can do is
8303 // mark it as having updates on its children.
8304 if (fiber.expirationTime < renderExpirationTime) {
8305 fiber.expirationTime = renderExpirationTime;
8306 }
8307 var _alternate = fiber.alternate;
8308 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
8309 _alternate.expirationTime = renderExpirationTime;
8310 }
8311 // This is intentionally passing this fiber as the parent
8312 // because we want to schedule this fiber as having work
8313 // on its children. We'll use the childExpirationTime on
8314 // this fiber to indicate that a context has changed.
8315 scheduleWorkOnParentPath(fiber, renderExpirationTime);
8316 nextFiber = fiber.sibling;
8317 } else {
8318 // Traverse down.
8319 nextFiber = fiber.child;
8320 }
8321
8322 if (nextFiber !== null) {
8323 // Set the return pointer of the child to the work-in-progress fiber.
8324 nextFiber.return = fiber;
8325 } else {
8326 // No child. Traverse to next sibling.
8327 nextFiber = fiber;
8328 while (nextFiber !== null) {
8329 if (nextFiber === workInProgress) {
8330 // We're back to the root of this subtree. Exit.
8331 nextFiber = null;
8332 break;
8333 }
8334 var sibling = nextFiber.sibling;
8335 if (sibling !== null) {
8336 // Set the return pointer of the sibling to the work-in-progress fiber.
8337 sibling.return = nextFiber.return;
8338 nextFiber = sibling;
8339 break;
8340 }
8341 // No more siblings. Traverse up.
8342 nextFiber = nextFiber.return;
8343 }
8344 }
8345 fiber = nextFiber;
8346 }
8347}
8348
8349function prepareToReadContext(workInProgress, renderExpirationTime) {
8350 currentlyRenderingFiber = workInProgress;
8351 lastContextDependency = null;
8352 lastContextWithAllBitsObserved = null;
8353
8354 var currentDependencies = workInProgress.contextDependencies;
8355 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
8356 // Context list has a pending update. Mark that this fiber performed work.
8357 markWorkInProgressReceivedUpdate();
8358 }
8359
8360 // Reset the work-in-progress list
8361 workInProgress.contextDependencies = null;
8362}
8363
8364function readContext(context, observedBits) {
8365 {
8366 // This warning would fire if you read context inside a Hook like useMemo.
8367 // Unlike the class check below, it's not enforced in production for perf.
8368 !!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;
8369 }
8370
8371 if (lastContextWithAllBitsObserved === context) {
8372 // Nothing to do. We already observe everything in this context.
8373 } else if (observedBits === false || observedBits === 0) {
8374 // Do not observe any updates.
8375 } else {
8376 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
8377 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
8378 // Observe all updates.
8379 lastContextWithAllBitsObserved = context;
8380 resolvedObservedBits = maxSigned31BitInt;
8381 } else {
8382 resolvedObservedBits = observedBits;
8383 }
8384
8385 var contextItem = {
8386 context: context,
8387 observedBits: resolvedObservedBits,
8388 next: null
8389 };
8390
8391 if (lastContextDependency === null) {
8392 !(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;
8393
8394 // This is the first dependency for this component. Create a new list.
8395 lastContextDependency = contextItem;
8396 currentlyRenderingFiber.contextDependencies = {
8397 first: contextItem,
8398 expirationTime: NoWork
8399 };
8400 } else {
8401 // Append a new context item.
8402 lastContextDependency = lastContextDependency.next = contextItem;
8403 }
8404 }
8405 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
8406}
8407
8408// UpdateQueue is a linked list of prioritized updates.
8409//
8410// Like fibers, update queues come in pairs: a current queue, which represents
8411// the visible state of the screen, and a work-in-progress queue, which can be
8412// mutated and processed asynchronously before it is committed — a form of
8413// double buffering. If a work-in-progress render is discarded before finishing,
8414// we create a new work-in-progress by cloning the current queue.
8415//
8416// Both queues share a persistent, singly-linked list structure. To schedule an
8417// update, we append it to the end of both queues. Each queue maintains a
8418// pointer to first update in the persistent list that hasn't been processed.
8419// The work-in-progress pointer always has a position equal to or greater than
8420// the current queue, since we always work on that one. The current queue's
8421// pointer is only updated during the commit phase, when we swap in the
8422// work-in-progress.
8423//
8424// For example:
8425//
8426// Current pointer: A - B - C - D - E - F
8427// Work-in-progress pointer: D - E - F
8428// ^
8429// The work-in-progress queue has
8430// processed more updates than current.
8431//
8432// The reason we append to both queues is because otherwise we might drop
8433// updates without ever processing them. For example, if we only add updates to
8434// the work-in-progress queue, some updates could be lost whenever a work-in
8435// -progress render restarts by cloning from current. Similarly, if we only add
8436// updates to the current queue, the updates will be lost whenever an already
8437// in-progress queue commits and swaps with the current queue. However, by
8438// adding to both queues, we guarantee that the update will be part of the next
8439// work-in-progress. (And because the work-in-progress queue becomes the
8440// current queue once it commits, there's no danger of applying the same
8441// update twice.)
8442//
8443// Prioritization
8444// --------------
8445//
8446// Updates are not sorted by priority, but by insertion; new updates are always
8447// appended to the end of the list.
8448//
8449// The priority is still important, though. When processing the update queue
8450// during the render phase, only the updates with sufficient priority are
8451// included in the result. If we skip an update because it has insufficient
8452// priority, it remains in the queue to be processed later, during a lower
8453// priority render. Crucially, all updates subsequent to a skipped update also
8454// remain in the queue *regardless of their priority*. That means high priority
8455// updates are sometimes processed twice, at two separate priorities. We also
8456// keep track of a base state, that represents the state before the first
8457// update in the queue is applied.
8458//
8459// For example:
8460//
8461// Given a base state of '', and the following queue of updates
8462//
8463// A1 - B2 - C1 - D2
8464//
8465// where the number indicates the priority, and the update is applied to the
8466// previous state by appending a letter, React will process these updates as
8467// two separate renders, one per distinct priority level:
8468//
8469// First render, at priority 1:
8470// Base state: ''
8471// Updates: [A1, C1]
8472// Result state: 'AC'
8473//
8474// Second render, at priority 2:
8475// Base state: 'A' <- The base state does not include C1,
8476// because B2 was skipped.
8477// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
8478// Result state: 'ABCD'
8479//
8480// Because we process updates in insertion order, and rebase high priority
8481// updates when preceding updates are skipped, the final result is deterministic
8482// regardless of priority. Intermediate state may vary according to system
8483// resources, but the final state is always the same.
8484
8485var UpdateState = 0;
8486var ReplaceState = 1;
8487var ForceUpdate = 2;
8488var CaptureUpdate = 3;
8489
8490// Global state that is reset at the beginning of calling `processUpdateQueue`.
8491// It should only be read right after calling `processUpdateQueue`, via
8492// `checkHasForceUpdateAfterProcessing`.
8493var hasForceUpdate = false;
8494
8495var didWarnUpdateInsideUpdate = void 0;
8496var currentlyProcessingQueue = void 0;
8497var resetCurrentlyProcessingQueue = void 0;
8498{
8499 didWarnUpdateInsideUpdate = false;
8500 currentlyProcessingQueue = null;
8501 resetCurrentlyProcessingQueue = function () {
8502 currentlyProcessingQueue = null;
8503 };
8504}
8505
8506function createUpdateQueue(baseState) {
8507 var queue = {
8508 baseState: baseState,
8509 firstUpdate: null,
8510 lastUpdate: null,
8511 firstCapturedUpdate: null,
8512 lastCapturedUpdate: null,
8513 firstEffect: null,
8514 lastEffect: null,
8515 firstCapturedEffect: null,
8516 lastCapturedEffect: null
8517 };
8518 return queue;
8519}
8520
8521function cloneUpdateQueue(currentQueue) {
8522 var queue = {
8523 baseState: currentQueue.baseState,
8524 firstUpdate: currentQueue.firstUpdate,
8525 lastUpdate: currentQueue.lastUpdate,
8526
8527 // TODO: With resuming, if we bail out and resuse the child tree, we should
8528 // keep these effects.
8529 firstCapturedUpdate: null,
8530 lastCapturedUpdate: null,
8531
8532 firstEffect: null,
8533 lastEffect: null,
8534
8535 firstCapturedEffect: null,
8536 lastCapturedEffect: null
8537 };
8538 return queue;
8539}
8540
8541function createUpdate(expirationTime) {
8542 return {
8543 expirationTime: expirationTime,
8544
8545 tag: UpdateState,
8546 payload: null,
8547 callback: null,
8548
8549 next: null,
8550 nextEffect: null
8551 };
8552}
8553
8554function appendUpdateToQueue(queue, update) {
8555 // Append the update to the end of the list.
8556 if (queue.lastUpdate === null) {
8557 // Queue is empty
8558 queue.firstUpdate = queue.lastUpdate = update;
8559 } else {
8560 queue.lastUpdate.next = update;
8561 queue.lastUpdate = update;
8562 }
8563}
8564
8565function enqueueUpdate(fiber, update) {
8566 // Update queues are created lazily.
8567 var alternate = fiber.alternate;
8568 var queue1 = void 0;
8569 var queue2 = void 0;
8570 if (alternate === null) {
8571 // There's only one fiber.
8572 queue1 = fiber.updateQueue;
8573 queue2 = null;
8574 if (queue1 === null) {
8575 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8576 }
8577 } else {
8578 // There are two owners.
8579 queue1 = fiber.updateQueue;
8580 queue2 = alternate.updateQueue;
8581 if (queue1 === null) {
8582 if (queue2 === null) {
8583 // Neither fiber has an update queue. Create new ones.
8584 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8585 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
8586 } else {
8587 // Only one fiber has an update queue. Clone to create a new one.
8588 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
8589 }
8590 } else {
8591 if (queue2 === null) {
8592 // Only one fiber has an update queue. Clone to create a new one.
8593 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
8594 } else {
8595 // Both owners have an update queue.
8596 }
8597 }
8598 }
8599 if (queue2 === null || queue1 === queue2) {
8600 // There's only a single queue.
8601 appendUpdateToQueue(queue1, update);
8602 } else {
8603 // There are two queues. We need to append the update to both queues,
8604 // while accounting for the persistent structure of the list — we don't
8605 // want the same update to be added multiple times.
8606 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
8607 // One of the queues is not empty. We must add the update to both queues.
8608 appendUpdateToQueue(queue1, update);
8609 appendUpdateToQueue(queue2, update);
8610 } else {
8611 // Both queues are non-empty. The last update is the same in both lists,
8612 // because of structural sharing. So, only append to one of the lists.
8613 appendUpdateToQueue(queue1, update);
8614 // But we still need to update the `lastUpdate` pointer of queue2.
8615 queue2.lastUpdate = update;
8616 }
8617 }
8618
8619 {
8620 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
8621 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.');
8622 didWarnUpdateInsideUpdate = true;
8623 }
8624 }
8625}
8626
8627function enqueueCapturedUpdate(workInProgress, update) {
8628 // Captured updates go into a separate list, and only on the work-in-
8629 // progress queue.
8630 var workInProgressQueue = workInProgress.updateQueue;
8631 if (workInProgressQueue === null) {
8632 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
8633 } else {
8634 // TODO: I put this here rather than createWorkInProgress so that we don't
8635 // clone the queue unnecessarily. There's probably a better way to
8636 // structure this.
8637 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
8638 }
8639
8640 // Append the update to the end of the list.
8641 if (workInProgressQueue.lastCapturedUpdate === null) {
8642 // This is the first render phase update
8643 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
8644 } else {
8645 workInProgressQueue.lastCapturedUpdate.next = update;
8646 workInProgressQueue.lastCapturedUpdate = update;
8647 }
8648}
8649
8650function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
8651 var current = workInProgress.alternate;
8652 if (current !== null) {
8653 // If the work-in-progress queue is equal to the current queue,
8654 // we need to clone it first.
8655 if (queue === current.updateQueue) {
8656 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
8657 }
8658 }
8659 return queue;
8660}
8661
8662function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
8663 switch (update.tag) {
8664 case ReplaceState:
8665 {
8666 var _payload = update.payload;
8667 if (typeof _payload === 'function') {
8668 // Updater function
8669 {
8670 enterDisallowedContextReadInDEV();
8671 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8672 _payload.call(instance, prevState, nextProps);
8673 }
8674 }
8675 var nextState = _payload.call(instance, prevState, nextProps);
8676 {
8677 exitDisallowedContextReadInDEV();
8678 }
8679 return nextState;
8680 }
8681 // State object
8682 return _payload;
8683 }
8684 case CaptureUpdate:
8685 {
8686 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
8687 }
8688 // Intentional fallthrough
8689 case UpdateState:
8690 {
8691 var _payload2 = update.payload;
8692 var partialState = void 0;
8693 if (typeof _payload2 === 'function') {
8694 // Updater function
8695 {
8696 enterDisallowedContextReadInDEV();
8697 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8698 _payload2.call(instance, prevState, nextProps);
8699 }
8700 }
8701 partialState = _payload2.call(instance, prevState, nextProps);
8702 {
8703 exitDisallowedContextReadInDEV();
8704 }
8705 } else {
8706 // Partial state object
8707 partialState = _payload2;
8708 }
8709 if (partialState === null || partialState === undefined) {
8710 // Null and undefined are treated as no-ops.
8711 return prevState;
8712 }
8713 // Merge the partial state and the previous state.
8714 return _assign({}, prevState, partialState);
8715 }
8716 case ForceUpdate:
8717 {
8718 hasForceUpdate = true;
8719 return prevState;
8720 }
8721 }
8722 return prevState;
8723}
8724
8725function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
8726 hasForceUpdate = false;
8727
8728 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
8729
8730 {
8731 currentlyProcessingQueue = queue;
8732 }
8733
8734 // These values may change as we process the queue.
8735 var newBaseState = queue.baseState;
8736 var newFirstUpdate = null;
8737 var newExpirationTime = NoWork;
8738
8739 // Iterate through the list of updates to compute the result.
8740 var update = queue.firstUpdate;
8741 var resultState = newBaseState;
8742 while (update !== null) {
8743 var updateExpirationTime = update.expirationTime;
8744 if (updateExpirationTime < renderExpirationTime) {
8745 // This update does not have sufficient priority. Skip it.
8746 if (newFirstUpdate === null) {
8747 // This is the first skipped update. It will be the first update in
8748 // the new list.
8749 newFirstUpdate = update;
8750 // Since this is the first update that was skipped, the current result
8751 // is the new base state.
8752 newBaseState = resultState;
8753 }
8754 // Since this update will remain in the list, update the remaining
8755 // expiration time.
8756 if (newExpirationTime < updateExpirationTime) {
8757 newExpirationTime = updateExpirationTime;
8758 }
8759 } else {
8760 // This update does have sufficient priority. Process it and compute
8761 // a new result.
8762 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8763 var _callback = update.callback;
8764 if (_callback !== null) {
8765 workInProgress.effectTag |= Callback;
8766 // Set this to null, in case it was mutated during an aborted render.
8767 update.nextEffect = null;
8768 if (queue.lastEffect === null) {
8769 queue.firstEffect = queue.lastEffect = update;
8770 } else {
8771 queue.lastEffect.nextEffect = update;
8772 queue.lastEffect = update;
8773 }
8774 }
8775 }
8776 // Continue to the next update.
8777 update = update.next;
8778 }
8779
8780 // Separately, iterate though the list of captured updates.
8781 var newFirstCapturedUpdate = null;
8782 update = queue.firstCapturedUpdate;
8783 while (update !== null) {
8784 var _updateExpirationTime = update.expirationTime;
8785 if (_updateExpirationTime < renderExpirationTime) {
8786 // This update does not have sufficient priority. Skip it.
8787 if (newFirstCapturedUpdate === null) {
8788 // This is the first skipped captured update. It will be the first
8789 // update in the new list.
8790 newFirstCapturedUpdate = update;
8791 // If this is the first update that was skipped, the current result is
8792 // the new base state.
8793 if (newFirstUpdate === null) {
8794 newBaseState = resultState;
8795 }
8796 }
8797 // Since this update will remain in the list, update the remaining
8798 // expiration time.
8799 if (newExpirationTime < _updateExpirationTime) {
8800 newExpirationTime = _updateExpirationTime;
8801 }
8802 } else {
8803 // This update does have sufficient priority. Process it and compute
8804 // a new result.
8805 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8806 var _callback2 = update.callback;
8807 if (_callback2 !== null) {
8808 workInProgress.effectTag |= Callback;
8809 // Set this to null, in case it was mutated during an aborted render.
8810 update.nextEffect = null;
8811 if (queue.lastCapturedEffect === null) {
8812 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
8813 } else {
8814 queue.lastCapturedEffect.nextEffect = update;
8815 queue.lastCapturedEffect = update;
8816 }
8817 }
8818 }
8819 update = update.next;
8820 }
8821
8822 if (newFirstUpdate === null) {
8823 queue.lastUpdate = null;
8824 }
8825 if (newFirstCapturedUpdate === null) {
8826 queue.lastCapturedUpdate = null;
8827 } else {
8828 workInProgress.effectTag |= Callback;
8829 }
8830 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
8831 // We processed every update, without skipping. That means the new base
8832 // state is the same as the result state.
8833 newBaseState = resultState;
8834 }
8835
8836 queue.baseState = newBaseState;
8837 queue.firstUpdate = newFirstUpdate;
8838 queue.firstCapturedUpdate = newFirstCapturedUpdate;
8839
8840 // Set the remaining expiration time to be whatever is remaining in the queue.
8841 // This should be fine because the only two other things that contribute to
8842 // expiration time are props and context. We're already in the middle of the
8843 // begin phase by the time we start processing the queue, so we've already
8844 // dealt with the props. Context in components that specify
8845 // shouldComponentUpdate is tricky; but we'll have to account for
8846 // that regardless.
8847 workInProgress.expirationTime = newExpirationTime;
8848 workInProgress.memoizedState = resultState;
8849
8850 {
8851 currentlyProcessingQueue = null;
8852 }
8853}
8854
8855function callCallback(callback, context) {
8856 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
8857 callback.call(context);
8858}
8859
8860function resetHasForceUpdateBeforeProcessing() {
8861 hasForceUpdate = false;
8862}
8863
8864function checkHasForceUpdateAfterProcessing() {
8865 return hasForceUpdate;
8866}
8867
8868function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
8869 // If the finished render included captured updates, and there are still
8870 // lower priority updates left over, we need to keep the captured updates
8871 // in the queue so that they are rebased and not dropped once we process the
8872 // queue again at the lower priority.
8873 if (finishedQueue.firstCapturedUpdate !== null) {
8874 // Join the captured update list to the end of the normal list.
8875 if (finishedQueue.lastUpdate !== null) {
8876 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
8877 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
8878 }
8879 // Clear the list of captured updates.
8880 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
8881 }
8882
8883 // Commit the effects
8884 commitUpdateEffects(finishedQueue.firstEffect, instance);
8885 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
8886
8887 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
8888 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
8889}
8890
8891function commitUpdateEffects(effect, instance) {
8892 while (effect !== null) {
8893 var _callback3 = effect.callback;
8894 if (_callback3 !== null) {
8895 effect.callback = null;
8896 callCallback(_callback3, instance);
8897 }
8898 effect = effect.nextEffect;
8899 }
8900}
8901
8902function createCapturedValue(value, source) {
8903 // If the value is an error, call this function immediately after it is thrown
8904 // so the stack is accurate.
8905 return {
8906 value: value,
8907 source: source,
8908 stack: getStackByFiberInDevAndProd(source)
8909 };
8910}
8911
8912function markUpdate(workInProgress) {
8913 // Tag the fiber with an update effect. This turns a Placement into
8914 // a PlacementAndUpdate.
8915 workInProgress.effectTag |= Update;
8916}
8917
8918function markRef$1(workInProgress) {
8919 workInProgress.effectTag |= Ref;
8920}
8921
8922var appendAllChildren = void 0;
8923var updateHostContainer = void 0;
8924var updateHostComponent$1 = void 0;
8925var updateHostText$1 = void 0;
8926if (supportsMutation) {
8927 // Mutation mode
8928
8929 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
8930 // We only have the top Fiber that was created but we need recurse down its
8931 // children to find all the terminal nodes.
8932 var node = workInProgress.child;
8933 while (node !== null) {
8934 if (node.tag === HostComponent || node.tag === HostText) {
8935 appendInitialChild(parent, node.stateNode);
8936 } else if (node.tag === HostPortal) {
8937 // If we have a portal child, then we don't want to traverse
8938 // down its children. Instead, we'll get insertions from each child in
8939 // the portal directly.
8940 } else if (node.child !== null) {
8941 node.child.return = node;
8942 node = node.child;
8943 continue;
8944 }
8945 if (node === workInProgress) {
8946 return;
8947 }
8948 while (node.sibling === null) {
8949 if (node.return === null || node.return === workInProgress) {
8950 return;
8951 }
8952 node = node.return;
8953 }
8954 node.sibling.return = node.return;
8955 node = node.sibling;
8956 }
8957 };
8958
8959 updateHostContainer = function (workInProgress) {
8960 // Noop
8961 };
8962 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
8963 // If we have an alternate, that means this is an update and we need to
8964 // schedule a side-effect to do the updates.
8965 var oldProps = current.memoizedProps;
8966 if (oldProps === newProps) {
8967 // In mutation mode, this is sufficient for a bailout because
8968 // we won't touch this node even if children changed.
8969 return;
8970 }
8971
8972 // If we get updated because one of our children updated, we don't
8973 // have newProps so we'll have to reuse them.
8974 // TODO: Split the update API as separate for the props vs. children.
8975 // Even better would be if children weren't special cased at all tho.
8976 var instance = workInProgress.stateNode;
8977 var currentHostContext = getHostContext();
8978 // TODO: Experiencing an error where oldProps is null. Suggests a host
8979 // component is hitting the resume path. Figure out why. Possibly
8980 // related to `hidden`.
8981 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
8982 // TODO: Type this specific to this type of component.
8983 workInProgress.updateQueue = updatePayload;
8984 // If the update payload indicates that there is a change or if there
8985 // is a new ref we mark this as an update. All the work is done in commitWork.
8986 if (updatePayload) {
8987 markUpdate(workInProgress);
8988 }
8989 };
8990 updateHostText$1 = function (current, workInProgress, oldText, newText) {
8991 // If the text differs, mark it as an update. All the work in done in commitWork.
8992 if (oldText !== newText) {
8993 markUpdate(workInProgress);
8994 }
8995 };
8996} else if (supportsPersistence) {
8997 // Persistent host tree mode
8998
8999 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9000 // We only have the top Fiber that was created but we need recurse down its
9001 // children to find all the terminal nodes.
9002 var node = workInProgress.child;
9003 while (node !== null) {
9004 // eslint-disable-next-line no-labels
9005 branches: if (node.tag === HostComponent) {
9006 var instance = node.stateNode;
9007 if (needsVisibilityToggle) {
9008 var props = node.memoizedProps;
9009 var type = node.type;
9010 if (isHidden) {
9011 // This child is inside a timed out tree. Hide it.
9012 instance = cloneHiddenInstance(instance, type, props, node);
9013 } else {
9014 // This child was previously inside a timed out tree. If it was not
9015 // updated during this render, it may need to be unhidden. Clone
9016 // again to be sure.
9017 instance = cloneUnhiddenInstance(instance, type, props, node);
9018 }
9019 node.stateNode = instance;
9020 }
9021 appendInitialChild(parent, instance);
9022 } else if (node.tag === HostText) {
9023 var _instance = node.stateNode;
9024 if (needsVisibilityToggle) {
9025 var text = node.memoizedProps;
9026 var rootContainerInstance = getRootHostContainer();
9027 var currentHostContext = getHostContext();
9028 if (isHidden) {
9029 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9030 } else {
9031 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9032 }
9033 node.stateNode = _instance;
9034 }
9035 appendInitialChild(parent, _instance);
9036 } else if (node.tag === HostPortal) {
9037 // If we have a portal child, then we don't want to traverse
9038 // down its children. Instead, we'll get insertions from each child in
9039 // the portal directly.
9040 } else if (node.tag === SuspenseComponent) {
9041 var current = node.alternate;
9042 if (current !== null) {
9043 var oldState = current.memoizedState;
9044 var newState = node.memoizedState;
9045 var oldIsHidden = oldState !== null;
9046 var newIsHidden = newState !== null;
9047 if (oldIsHidden !== newIsHidden) {
9048 // The placeholder either just timed out or switched back to the normal
9049 // children after having previously timed out. Toggle the visibility of
9050 // the direct host children.
9051 var primaryChildParent = newIsHidden ? node.child : node;
9052 if (primaryChildParent !== null) {
9053 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
9054 }
9055 // eslint-disable-next-line no-labels
9056 break branches;
9057 }
9058 }
9059 if (node.child !== null) {
9060 // Continue traversing like normal
9061 node.child.return = node;
9062 node = node.child;
9063 continue;
9064 }
9065 } else if (node.child !== null) {
9066 node.child.return = node;
9067 node = node.child;
9068 continue;
9069 }
9070 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9071 node = node;
9072 if (node === workInProgress) {
9073 return;
9074 }
9075 while (node.sibling === null) {
9076 if (node.return === null || node.return === workInProgress) {
9077 return;
9078 }
9079 node = node.return;
9080 }
9081 node.sibling.return = node.return;
9082 node = node.sibling;
9083 }
9084 };
9085
9086 // An unfortunate fork of appendAllChildren because we have two different parent types.
9087 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
9088 // We only have the top Fiber that was created but we need recurse down its
9089 // children to find all the terminal nodes.
9090 var node = workInProgress.child;
9091 while (node !== null) {
9092 // eslint-disable-next-line no-labels
9093 branches: if (node.tag === HostComponent) {
9094 var instance = node.stateNode;
9095 if (needsVisibilityToggle) {
9096 var props = node.memoizedProps;
9097 var type = node.type;
9098 if (isHidden) {
9099 // This child is inside a timed out tree. Hide it.
9100 instance = cloneHiddenInstance(instance, type, props, node);
9101 } else {
9102 // This child was previously inside a timed out tree. If it was not
9103 // updated during this render, it may need to be unhidden. Clone
9104 // again to be sure.
9105 instance = cloneUnhiddenInstance(instance, type, props, node);
9106 }
9107 node.stateNode = instance;
9108 }
9109 appendChildToContainerChildSet(containerChildSet, instance);
9110 } else if (node.tag === HostText) {
9111 var _instance2 = node.stateNode;
9112 if (needsVisibilityToggle) {
9113 var text = node.memoizedProps;
9114 var rootContainerInstance = getRootHostContainer();
9115 var currentHostContext = getHostContext();
9116 if (isHidden) {
9117 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9118 } else {
9119 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
9120 }
9121 node.stateNode = _instance2;
9122 }
9123 appendChildToContainerChildSet(containerChildSet, _instance2);
9124 } else if (node.tag === HostPortal) {
9125 // If we have a portal child, then we don't want to traverse
9126 // down its children. Instead, we'll get insertions from each child in
9127 // the portal directly.
9128 } else if (node.tag === SuspenseComponent) {
9129 var current = node.alternate;
9130 if (current !== null) {
9131 var oldState = current.memoizedState;
9132 var newState = node.memoizedState;
9133 var oldIsHidden = oldState !== null;
9134 var newIsHidden = newState !== null;
9135 if (oldIsHidden !== newIsHidden) {
9136 // The placeholder either just timed out or switched back to the normal
9137 // children after having previously timed out. Toggle the visibility of
9138 // the direct host children.
9139 var primaryChildParent = newIsHidden ? node.child : node;
9140 if (primaryChildParent !== null) {
9141 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
9142 }
9143 // eslint-disable-next-line no-labels
9144 break branches;
9145 }
9146 }
9147 if (node.child !== null) {
9148 // Continue traversing like normal
9149 node.child.return = node;
9150 node = node.child;
9151 continue;
9152 }
9153 } else if (node.child !== null) {
9154 node.child.return = node;
9155 node = node.child;
9156 continue;
9157 }
9158 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9159 node = node;
9160 if (node === workInProgress) {
9161 return;
9162 }
9163 while (node.sibling === null) {
9164 if (node.return === null || node.return === workInProgress) {
9165 return;
9166 }
9167 node = node.return;
9168 }
9169 node.sibling.return = node.return;
9170 node = node.sibling;
9171 }
9172 };
9173 updateHostContainer = function (workInProgress) {
9174 var portalOrRoot = workInProgress.stateNode;
9175 var childrenUnchanged = workInProgress.firstEffect === null;
9176 if (childrenUnchanged) {
9177 // No changes, just reuse the existing instance.
9178 } else {
9179 var container = portalOrRoot.containerInfo;
9180 var newChildSet = createContainerChildSet(container);
9181 // If children might have changed, we have to add them all to the set.
9182 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
9183 portalOrRoot.pendingChildren = newChildSet;
9184 // Schedule an update on the container to swap out the container.
9185 markUpdate(workInProgress);
9186 finalizeContainerChildren(container, newChildSet);
9187 }
9188 };
9189 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9190 var currentInstance = current.stateNode;
9191 var oldProps = current.memoizedProps;
9192 // If there are no effects associated with this node, then none of our children had any updates.
9193 // This guarantees that we can reuse all of them.
9194 var childrenUnchanged = workInProgress.firstEffect === null;
9195 if (childrenUnchanged && oldProps === newProps) {
9196 // No changes, just reuse the existing instance.
9197 // Note that this might release a previous clone.
9198 workInProgress.stateNode = currentInstance;
9199 return;
9200 }
9201 var recyclableInstance = workInProgress.stateNode;
9202 var currentHostContext = getHostContext();
9203 var updatePayload = null;
9204 if (oldProps !== newProps) {
9205 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9206 }
9207 if (childrenUnchanged && updatePayload === null) {
9208 // No changes, just reuse the existing instance.
9209 // Note that this might release a previous clone.
9210 workInProgress.stateNode = currentInstance;
9211 return;
9212 }
9213 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9214 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9215 markUpdate(workInProgress);
9216 }
9217 workInProgress.stateNode = newInstance;
9218 if (childrenUnchanged) {
9219 // If there are no other effects in this tree, we need to flag this node as having one.
9220 // Even though we're not going to use it for anything.
9221 // Otherwise parents won't know that there are new children to propagate upwards.
9222 markUpdate(workInProgress);
9223 } else {
9224 // If children might have changed, we have to add them all to the set.
9225 appendAllChildren(newInstance, workInProgress, false, false);
9226 }
9227 };
9228 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9229 if (oldText !== newText) {
9230 // If the text content differs, we'll create a new text instance for it.
9231 var rootContainerInstance = getRootHostContainer();
9232 var currentHostContext = getHostContext();
9233 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9234 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9235 // This lets the parents know that at least one of their children has changed.
9236 markUpdate(workInProgress);
9237 }
9238 };
9239} else {
9240 // No host operations
9241 updateHostContainer = function (workInProgress) {
9242 // Noop
9243 };
9244 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9245 // Noop
9246 };
9247 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9248 // Noop
9249 };
9250}
9251
9252function completeWork(current, workInProgress, renderExpirationTime) {
9253 var newProps = workInProgress.pendingProps;
9254
9255 switch (workInProgress.tag) {
9256 case IndeterminateComponent:
9257 break;
9258 case LazyComponent:
9259 break;
9260 case SimpleMemoComponent:
9261 case FunctionComponent:
9262 break;
9263 case ClassComponent:
9264 {
9265 var Component = workInProgress.type;
9266 if (isContextProvider(Component)) {
9267 popContext(workInProgress);
9268 }
9269 break;
9270 }
9271 case HostRoot:
9272 {
9273 popHostContainer(workInProgress);
9274 popTopLevelContextObject(workInProgress);
9275 var fiberRoot = workInProgress.stateNode;
9276 if (fiberRoot.pendingContext) {
9277 fiberRoot.context = fiberRoot.pendingContext;
9278 fiberRoot.pendingContext = null;
9279 }
9280 if (current === null || current.child === null) {
9281 // If we hydrated, pop so that we can delete any remaining children
9282 // that weren't hydrated.
9283 popHydrationState(workInProgress);
9284 // This resets the hacky state to fix isMounted before committing.
9285 // TODO: Delete this when we delete isMounted and findDOMNode.
9286 workInProgress.effectTag &= ~Placement;
9287 }
9288 updateHostContainer(workInProgress);
9289 break;
9290 }
9291 case HostComponent:
9292 {
9293 popHostContext(workInProgress);
9294 var rootContainerInstance = getRootHostContainer();
9295 var type = workInProgress.type;
9296 if (current !== null && workInProgress.stateNode != null) {
9297 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9298
9299 if (current.ref !== workInProgress.ref) {
9300 markRef$1(workInProgress);
9301 }
9302 } else {
9303 if (!newProps) {
9304 !(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;
9305 // This can happen when we abort work.
9306 break;
9307 }
9308
9309 var currentHostContext = getHostContext();
9310 // TODO: Move createInstance to beginWork and keep it on a context
9311 // "stack" as the parent. Then append children as we go in beginWork
9312 // or completeWork depending on we want to add then top->down or
9313 // bottom->up. Top->down is faster in IE11.
9314 var wasHydrated = popHydrationState(workInProgress);
9315 if (wasHydrated) {
9316 // TODO: Move this and createInstance step into the beginPhase
9317 // to consolidate.
9318 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
9319 // If changes to the hydrated node needs to be applied at the
9320 // commit-phase we mark this as such.
9321 markUpdate(workInProgress);
9322 }
9323 } else {
9324 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9325
9326 appendAllChildren(instance, workInProgress, false, false);
9327
9328 // Certain renderers require commit-time effects for initial mount.
9329 // (eg DOM renderer supports auto-focus for certain elements).
9330 // Make sure such renderers get scheduled for later work.
9331 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
9332 markUpdate(workInProgress);
9333 }
9334 workInProgress.stateNode = instance;
9335 }
9336
9337 if (workInProgress.ref !== null) {
9338 // If there is a ref on a host node we need to schedule a callback
9339 markRef$1(workInProgress);
9340 }
9341 }
9342 break;
9343 }
9344 case HostText:
9345 {
9346 var newText = newProps;
9347 if (current && workInProgress.stateNode != null) {
9348 var oldText = current.memoizedProps;
9349 // If we have an alternate, that means this is an update and we need
9350 // to schedule a side-effect to do the updates.
9351 updateHostText$1(current, workInProgress, oldText, newText);
9352 } else {
9353 if (typeof newText !== 'string') {
9354 !(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;
9355 // This can happen when we abort work.
9356 }
9357 var _rootContainerInstance = getRootHostContainer();
9358 var _currentHostContext = getHostContext();
9359 var _wasHydrated = popHydrationState(workInProgress);
9360 if (_wasHydrated) {
9361 if (prepareToHydrateHostTextInstance(workInProgress)) {
9362 markUpdate(workInProgress);
9363 }
9364 } else {
9365 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
9366 }
9367 }
9368 break;
9369 }
9370 case ForwardRef:
9371 break;
9372 case SuspenseComponent:
9373 {
9374 var nextState = workInProgress.memoizedState;
9375 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9376 // Something suspended. Re-render with the fallback children.
9377 workInProgress.expirationTime = renderExpirationTime;
9378 // Do not reset the effect list.
9379 return workInProgress;
9380 }
9381
9382 var nextDidTimeout = nextState !== null;
9383 var prevDidTimeout = current !== null && current.memoizedState !== null;
9384
9385 if (current !== null && !nextDidTimeout && prevDidTimeout) {
9386 // We just switched from the fallback to the normal children. Delete
9387 // the fallback.
9388 // TODO: Would it be better to store the fallback fragment on
9389 var currentFallbackChild = current.child.sibling;
9390 if (currentFallbackChild !== null) {
9391 // Deletions go at the beginning of the return fiber's effect list
9392 var first = workInProgress.firstEffect;
9393 if (first !== null) {
9394 workInProgress.firstEffect = currentFallbackChild;
9395 currentFallbackChild.nextEffect = first;
9396 } else {
9397 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9398 currentFallbackChild.nextEffect = null;
9399 }
9400 currentFallbackChild.effectTag = Deletion;
9401 }
9402 }
9403
9404 if (nextDidTimeout || prevDidTimeout) {
9405 // If the children are hidden, or if they were previous hidden, schedule
9406 // an effect to toggle their visibility. This is also used to attach a
9407 // retry listener to the promise.
9408 workInProgress.effectTag |= Update;
9409 }
9410 break;
9411 }
9412 case Fragment:
9413 break;
9414 case Mode:
9415 break;
9416 case Profiler:
9417 break;
9418 case HostPortal:
9419 popHostContainer(workInProgress);
9420 updateHostContainer(workInProgress);
9421 break;
9422 case ContextProvider:
9423 // Pop provider fiber
9424 popProvider(workInProgress);
9425 break;
9426 case ContextConsumer:
9427 break;
9428 case MemoComponent:
9429 break;
9430 case IncompleteClassComponent:
9431 {
9432 // Same as class component case. I put it down here so that the tags are
9433 // sequential to ensure this switch is compiled to a jump table.
9434 var _Component = workInProgress.type;
9435 if (isContextProvider(_Component)) {
9436 popContext(workInProgress);
9437 }
9438 break;
9439 }
9440 case DehydratedSuspenseComponent:
9441 {
9442 if (enableSuspenseServerRenderer) {
9443 if (current === null) {
9444 var _wasHydrated2 = popHydrationState(workInProgress);
9445 !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
9446 skipPastDehydratedSuspenseInstance(workInProgress);
9447 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
9448 // This boundary did not suspend so it's now hydrated.
9449 // To handle any future suspense cases, we're going to now upgrade it
9450 // to a Suspense component. We detach it from the existing current fiber.
9451 current.alternate = null;
9452 workInProgress.alternate = null;
9453 workInProgress.tag = SuspenseComponent;
9454 workInProgress.memoizedState = null;
9455 workInProgress.stateNode = null;
9456 }
9457 }
9458 break;
9459 }
9460 default:
9461 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9462 }
9463
9464 return null;
9465}
9466
9467function shouldCaptureSuspense(workInProgress) {
9468 // In order to capture, the Suspense component must have a fallback prop.
9469 if (workInProgress.memoizedProps.fallback === undefined) {
9470 return false;
9471 }
9472 // If it was the primary children that just suspended, capture and render the
9473 // fallback. Otherwise, don't capture and bubble to the next boundary.
9474 var nextState = workInProgress.memoizedState;
9475 return nextState === null;
9476}
9477
9478// This module is forked in different environments.
9479// By default, return `true` to log errors to the console.
9480// Forks can return `false` if this isn't desirable.
9481function showErrorDialog(capturedError) {
9482 return true;
9483}
9484
9485function logCapturedError(capturedError) {
9486 var logError = showErrorDialog(capturedError);
9487
9488 // Allow injected showErrorDialog() to prevent default console.error logging.
9489 // This enables renderers like ReactNative to better manage redbox behavior.
9490 if (logError === false) {
9491 return;
9492 }
9493
9494 var error = capturedError.error;
9495 {
9496 var componentName = capturedError.componentName,
9497 componentStack = capturedError.componentStack,
9498 errorBoundaryName = capturedError.errorBoundaryName,
9499 errorBoundaryFound = capturedError.errorBoundaryFound,
9500 willRetry = capturedError.willRetry;
9501
9502 // Browsers support silencing uncaught errors by calling
9503 // `preventDefault()` in window `error` handler.
9504 // We record this information as an expando on the error.
9505
9506 if (error != null && error._suppressLogging) {
9507 if (errorBoundaryFound && willRetry) {
9508 // The error is recoverable and was silenced.
9509 // Ignore it and don't print the stack addendum.
9510 // This is handy for testing error boundaries without noise.
9511 return;
9512 }
9513 // The error is fatal. Since the silencing might have
9514 // been accidental, we'll surface it anyway.
9515 // However, the browser would have silenced the original error
9516 // so we'll print it first, and then print the stack addendum.
9517 console.error(error);
9518 // For a more detailed description of this block, see:
9519 // https://github.com/facebook/react/pull/13384
9520 }
9521
9522 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
9523
9524 var errorBoundaryMessage = void 0;
9525 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
9526 if (errorBoundaryFound && errorBoundaryName) {
9527 if (willRetry) {
9528 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
9529 } else {
9530 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
9531 }
9532 } else {
9533 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.';
9534 }
9535 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
9536
9537 // In development, we provide our own message with just the component stack.
9538 // We don't include the original error message and JS stack because the browser
9539 // has already printed it. Even if the application swallows the error, it is still
9540 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
9541 console.error(combinedMessage);
9542 }
9543}
9544
9545var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
9546{
9547 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
9548}
9549
9550var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
9551
9552function logError(boundary, errorInfo) {
9553 var source = errorInfo.source;
9554 var stack = errorInfo.stack;
9555 if (stack === null && source !== null) {
9556 stack = getStackByFiberInDevAndProd(source);
9557 }
9558
9559 var capturedError = {
9560 componentName: source !== null ? getComponentName(source.type) : null,
9561 componentStack: stack !== null ? stack : '',
9562 error: errorInfo.value,
9563 errorBoundary: null,
9564 errorBoundaryName: null,
9565 errorBoundaryFound: false,
9566 willRetry: false
9567 };
9568
9569 if (boundary !== null && boundary.tag === ClassComponent) {
9570 capturedError.errorBoundary = boundary.stateNode;
9571 capturedError.errorBoundaryName = getComponentName(boundary.type);
9572 capturedError.errorBoundaryFound = true;
9573 capturedError.willRetry = true;
9574 }
9575
9576 try {
9577 logCapturedError(capturedError);
9578 } catch (e) {
9579 // This method must not throw, or React internal state will get messed up.
9580 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
9581 // we want to report this error outside of the normal stack as a last resort.
9582 // https://github.com/facebook/react/issues/13188
9583 setTimeout(function () {
9584 throw e;
9585 });
9586 }
9587}
9588
9589var callComponentWillUnmountWithTimer = function (current, instance) {
9590 startPhaseTimer(current, 'componentWillUnmount');
9591 instance.props = current.memoizedProps;
9592 instance.state = current.memoizedState;
9593 instance.componentWillUnmount();
9594 stopPhaseTimer();
9595};
9596
9597// Capture errors so they don't interrupt unmounting.
9598function safelyCallComponentWillUnmount(current, instance) {
9599 {
9600 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
9601 if (hasCaughtError()) {
9602 var unmountError = clearCaughtError();
9603 captureCommitPhaseError(current, unmountError);
9604 }
9605 }
9606}
9607
9608function safelyDetachRef(current) {
9609 var ref = current.ref;
9610 if (ref !== null) {
9611 if (typeof ref === 'function') {
9612 {
9613 invokeGuardedCallback(null, ref, null, null);
9614 if (hasCaughtError()) {
9615 var refError = clearCaughtError();
9616 captureCommitPhaseError(current, refError);
9617 }
9618 }
9619 } else {
9620 ref.current = null;
9621 }
9622 }
9623}
9624
9625function safelyCallDestroy(current, destroy) {
9626 {
9627 invokeGuardedCallback(null, destroy, null);
9628 if (hasCaughtError()) {
9629 var error = clearCaughtError();
9630 captureCommitPhaseError(current, error);
9631 }
9632 }
9633}
9634
9635function commitBeforeMutationLifeCycles(current, finishedWork) {
9636 switch (finishedWork.tag) {
9637 case FunctionComponent:
9638 case ForwardRef:
9639 case SimpleMemoComponent:
9640 {
9641 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
9642 return;
9643 }
9644 case ClassComponent:
9645 {
9646 if (finishedWork.effectTag & Snapshot) {
9647 if (current !== null) {
9648 var prevProps = current.memoizedProps;
9649 var prevState = current.memoizedState;
9650 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
9651 var instance = finishedWork.stateNode;
9652 // We could update instance props and state here,
9653 // but instead we rely on them being set during last render.
9654 // TODO: revisit this when we implement resuming.
9655 {
9656 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9657 !(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;
9658 !(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;
9659 }
9660 }
9661 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
9662 {
9663 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
9664 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
9665 didWarnSet.add(finishedWork.type);
9666 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
9667 }
9668 }
9669 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
9670 stopPhaseTimer();
9671 }
9672 }
9673 return;
9674 }
9675 case HostRoot:
9676 case HostComponent:
9677 case HostText:
9678 case HostPortal:
9679 case IncompleteClassComponent:
9680 // Nothing to do for these component types
9681 return;
9682 default:
9683 {
9684 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.');
9685 }
9686 }
9687}
9688
9689function commitHookEffectList(unmountTag, mountTag, finishedWork) {
9690 var updateQueue = finishedWork.updateQueue;
9691 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
9692 if (lastEffect !== null) {
9693 var firstEffect = lastEffect.next;
9694 var effect = firstEffect;
9695 do {
9696 if ((effect.tag & unmountTag) !== NoEffect$1) {
9697 // Unmount
9698 var destroy = effect.destroy;
9699 effect.destroy = undefined;
9700 if (destroy !== undefined) {
9701 destroy();
9702 }
9703 }
9704 if ((effect.tag & mountTag) !== NoEffect$1) {
9705 // Mount
9706 var create = effect.create;
9707 effect.destroy = create();
9708
9709 {
9710 var _destroy = effect.destroy;
9711 if (_destroy !== undefined && typeof _destroy !== 'function') {
9712 var addendum = void 0;
9713 if (_destroy === null) {
9714 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
9715 } else if (typeof _destroy.then === 'function') {
9716 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, you may write an async function separately ' + 'and then call it from inside the effect:\n\n' + 'async function fetchComment(commentId) {\n' + ' // You can await here\n' + '}\n\n' + 'useEffect(() => {\n' + ' fetchComment(commentId);\n' + '}, [commentId]);\n\n' + 'In the future, React will provide a more idiomatic solution for data fetching ' + "that doesn't involve writing effects manually.";
9717 } else {
9718 addendum = ' You returned: ' + _destroy;
9719 }
9720 warningWithoutStack$1(false, 'An Effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
9721 }
9722 }
9723 }
9724 effect = effect.next;
9725 } while (effect !== firstEffect);
9726 }
9727}
9728
9729function commitPassiveHookEffects(finishedWork) {
9730 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
9731 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
9732}
9733
9734function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
9735 switch (finishedWork.tag) {
9736 case FunctionComponent:
9737 case ForwardRef:
9738 case SimpleMemoComponent:
9739 {
9740 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
9741 break;
9742 }
9743 case ClassComponent:
9744 {
9745 var instance = finishedWork.stateNode;
9746 if (finishedWork.effectTag & Update) {
9747 if (current === null) {
9748 startPhaseTimer(finishedWork, 'componentDidMount');
9749 // We could update instance props and state here,
9750 // but instead we rely on them being set during last render.
9751 // TODO: revisit this when we implement resuming.
9752 {
9753 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9754 !(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;
9755 !(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;
9756 }
9757 }
9758 instance.componentDidMount();
9759 stopPhaseTimer();
9760 } else {
9761 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
9762 var prevState = current.memoizedState;
9763 startPhaseTimer(finishedWork, 'componentDidUpdate');
9764 // We could update instance props and state here,
9765 // but instead we rely on them being set during last render.
9766 // TODO: revisit this when we implement resuming.
9767 {
9768 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9769 !(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;
9770 !(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;
9771 }
9772 }
9773 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
9774 stopPhaseTimer();
9775 }
9776 }
9777 var updateQueue = finishedWork.updateQueue;
9778 if (updateQueue !== null) {
9779 {
9780 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9781 !(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;
9782 !(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;
9783 }
9784 }
9785 // We could update instance props and state here,
9786 // but instead we rely on them being set during last render.
9787 // TODO: revisit this when we implement resuming.
9788 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
9789 }
9790 return;
9791 }
9792 case HostRoot:
9793 {
9794 var _updateQueue = finishedWork.updateQueue;
9795 if (_updateQueue !== null) {
9796 var _instance = null;
9797 if (finishedWork.child !== null) {
9798 switch (finishedWork.child.tag) {
9799 case HostComponent:
9800 _instance = getPublicInstance(finishedWork.child.stateNode);
9801 break;
9802 case ClassComponent:
9803 _instance = finishedWork.child.stateNode;
9804 break;
9805 }
9806 }
9807 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
9808 }
9809 return;
9810 }
9811 case HostComponent:
9812 {
9813 var _instance2 = finishedWork.stateNode;
9814
9815 // Renderers may schedule work to be done after host components are mounted
9816 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
9817 // These effects should only be committed when components are first mounted,
9818 // aka when there is no current/alternate.
9819 if (current === null && finishedWork.effectTag & Update) {
9820 var type = finishedWork.type;
9821 var props = finishedWork.memoizedProps;
9822
9823 }
9824
9825 return;
9826 }
9827 case HostText:
9828 {
9829 // We have no life-cycles associated with text.
9830 return;
9831 }
9832 case HostPortal:
9833 {
9834 // We have no life-cycles associated with portals.
9835 return;
9836 }
9837 case Profiler:
9838 {
9839 if (enableProfilerTimer) {
9840 var onRender = finishedWork.memoizedProps.onRender;
9841
9842 if (enableSchedulerTracing) {
9843 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
9844 } else {
9845 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
9846 }
9847 }
9848 return;
9849 }
9850 case SuspenseComponent:
9851 break;
9852 case IncompleteClassComponent:
9853 break;
9854 default:
9855 {
9856 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.');
9857 }
9858 }
9859}
9860
9861function hideOrUnhideAllChildren(finishedWork, isHidden) {
9862 if (supportsMutation) {
9863 // We only have the top Fiber that was inserted but we need to recurse down its
9864 var node = finishedWork;
9865 while (true) {
9866 if (node.tag === HostComponent) {
9867 var instance = node.stateNode;
9868 if (isHidden) {
9869 hideInstance(instance);
9870 } else {
9871 unhideInstance(node.stateNode, node.memoizedProps);
9872 }
9873 } else if (node.tag === HostText) {
9874 var _instance3 = node.stateNode;
9875 if (isHidden) {
9876
9877 } else {
9878 unhideTextInstance(_instance3, node.memoizedProps);
9879 }
9880 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
9881 // Found a nested Suspense component that timed out. Skip over the
9882 var fallbackChildFragment = node.child.sibling;
9883 fallbackChildFragment.return = node;
9884 node = fallbackChildFragment;
9885 continue;
9886 } else if (node.child !== null) {
9887 node.child.return = node;
9888 node = node.child;
9889 continue;
9890 }
9891 if (node === finishedWork) {
9892 return;
9893 }
9894 while (node.sibling === null) {
9895 if (node.return === null || node.return === finishedWork) {
9896 return;
9897 }
9898 node = node.return;
9899 }
9900 node.sibling.return = node.return;
9901 node = node.sibling;
9902 }
9903 }
9904}
9905
9906function commitAttachRef(finishedWork) {
9907 var ref = finishedWork.ref;
9908 if (ref !== null) {
9909 var instance = finishedWork.stateNode;
9910 var instanceToUse = void 0;
9911 switch (finishedWork.tag) {
9912 case HostComponent:
9913 instanceToUse = getPublicInstance(instance);
9914 break;
9915 default:
9916 instanceToUse = instance;
9917 }
9918 if (typeof ref === 'function') {
9919 ref(instanceToUse);
9920 } else {
9921 {
9922 if (!ref.hasOwnProperty('current')) {
9923 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
9924 }
9925 }
9926
9927 ref.current = instanceToUse;
9928 }
9929 }
9930}
9931
9932function commitDetachRef(current) {
9933 var currentRef = current.ref;
9934 if (currentRef !== null) {
9935 if (typeof currentRef === 'function') {
9936 currentRef(null);
9937 } else {
9938 currentRef.current = null;
9939 }
9940 }
9941}
9942
9943// User-originating errors (lifecycles and refs) should not interrupt
9944// deletion, so don't let them throw. Host-originating errors should
9945// interrupt deletion, so it's okay
9946function commitUnmount(current) {
9947 onCommitUnmount(current);
9948
9949 switch (current.tag) {
9950 case FunctionComponent:
9951 case ForwardRef:
9952 case MemoComponent:
9953 case SimpleMemoComponent:
9954 {
9955 var updateQueue = current.updateQueue;
9956 if (updateQueue !== null) {
9957 var lastEffect = updateQueue.lastEffect;
9958 if (lastEffect !== null) {
9959 var firstEffect = lastEffect.next;
9960 var effect = firstEffect;
9961 do {
9962 var destroy = effect.destroy;
9963 if (destroy !== undefined) {
9964 safelyCallDestroy(current, destroy);
9965 }
9966 effect = effect.next;
9967 } while (effect !== firstEffect);
9968 }
9969 }
9970 break;
9971 }
9972 case ClassComponent:
9973 {
9974 safelyDetachRef(current);
9975 var instance = current.stateNode;
9976 if (typeof instance.componentWillUnmount === 'function') {
9977 safelyCallComponentWillUnmount(current, instance);
9978 }
9979 return;
9980 }
9981 case HostComponent:
9982 {
9983 safelyDetachRef(current);
9984 return;
9985 }
9986 case HostPortal:
9987 {
9988 // TODO: this is recursive.
9989 // We are also not using this parent because
9990 // the portal will get pushed immediately.
9991 if (supportsMutation) {
9992 unmountHostComponents(current);
9993 } else if (supportsPersistence) {
9994 emptyPortalContainer(current);
9995 }
9996 return;
9997 }
9998 }
9999}
10000
10001function commitNestedUnmounts(root) {
10002 // While we're inside a removed host node we don't want to call
10003 // removeChild on the inner nodes because they're removed by the top
10004 // call anyway. We also want to call componentWillUnmount on all
10005 // composites before this host node is removed from the tree. Therefore
10006 var node = root;
10007 while (true) {
10008 commitUnmount(node);
10009 // Visit children because they may contain more composite or host nodes.
10010 // Skip portals because commitUnmount() currently visits them recursively.
10011 if (node.child !== null && (
10012 // If we use mutation we drill down into portals using commitUnmount above.
10013 // If we don't use mutation we drill down into portals here instead.
10014 !supportsMutation || node.tag !== HostPortal)) {
10015 node.child.return = node;
10016 node = node.child;
10017 continue;
10018 }
10019 if (node === root) {
10020 return;
10021 }
10022 while (node.sibling === null) {
10023 if (node.return === null || node.return === root) {
10024 return;
10025 }
10026 node = node.return;
10027 }
10028 node.sibling.return = node.return;
10029 node = node.sibling;
10030 }
10031}
10032
10033function detachFiber(current) {
10034 // Cut off the return pointers to disconnect it from the tree. Ideally, we
10035 // should clear the child pointer of the parent alternate to let this
10036 // get GC:ed but we don't know which for sure which parent is the current
10037 // one so we'll settle for GC:ing the subtree of this child. This child
10038 // itself will be GC:ed when the parent updates the next time.
10039 current.return = null;
10040 current.child = null;
10041 current.memoizedState = null;
10042 current.updateQueue = null;
10043 var alternate = current.alternate;
10044 if (alternate !== null) {
10045 alternate.return = null;
10046 alternate.child = null;
10047 alternate.memoizedState = null;
10048 alternate.updateQueue = null;
10049 }
10050}
10051
10052function emptyPortalContainer(current) {
10053 if (!supportsPersistence) {
10054 return;
10055 }
10056
10057 var portal = current.stateNode;
10058 var containerInfo = portal.containerInfo;
10059
10060 var emptyChildSet = createContainerChildSet(containerInfo);
10061 replaceContainerChildren(containerInfo, emptyChildSet);
10062}
10063
10064function commitContainer(finishedWork) {
10065 if (!supportsPersistence) {
10066 return;
10067 }
10068
10069 switch (finishedWork.tag) {
10070 case ClassComponent:
10071 {
10072 return;
10073 }
10074 case HostComponent:
10075 {
10076 return;
10077 }
10078 case HostText:
10079 {
10080 return;
10081 }
10082 case HostRoot:
10083 case HostPortal:
10084 {
10085 var portalOrRoot = finishedWork.stateNode;
10086 var containerInfo = portalOrRoot.containerInfo,
10087 _pendingChildren = portalOrRoot.pendingChildren;
10088
10089 replaceContainerChildren(containerInfo, _pendingChildren);
10090 return;
10091 }
10092 default:
10093 {
10094 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.');
10095 }
10096 }
10097}
10098
10099function getHostParentFiber(fiber) {
10100 var parent = fiber.return;
10101 while (parent !== null) {
10102 if (isHostParent(parent)) {
10103 return parent;
10104 }
10105 parent = parent.return;
10106 }
10107 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
10108}
10109
10110function isHostParent(fiber) {
10111 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
10112}
10113
10114function getHostSibling(fiber) {
10115 // We're going to search forward into the tree until we find a sibling host
10116 // node. Unfortunately, if multiple insertions are done in a row we have to
10117 // search past them. This leads to exponential search for the next sibling.
10118 var node = fiber;
10119 siblings: while (true) {
10120 // If we didn't find anything, let's try the next sibling.
10121 while (node.sibling === null) {
10122 if (node.return === null || isHostParent(node.return)) {
10123 // If we pop out of the root or hit the parent the fiber we are the
10124 // last sibling.
10125 return null;
10126 }
10127 node = node.return;
10128 }
10129 node.sibling.return = node.return;
10130 node = node.sibling;
10131 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
10132 // If it is not host node and, we might have a host node inside it.
10133 // Try to search down until we find one.
10134 if (node.effectTag & Placement) {
10135 // If we don't have a child, try the siblings instead.
10136 continue siblings;
10137 }
10138 // If we don't have a child, try the siblings instead.
10139 // We also skip portals because they are not part of this host tree.
10140 if (node.child === null || node.tag === HostPortal) {
10141 continue siblings;
10142 } else {
10143 node.child.return = node;
10144 node = node.child;
10145 }
10146 }
10147 // Check if this host node is stable or about to be placed.
10148 if (!(node.effectTag & Placement)) {
10149 // Found it!
10150 return node.stateNode;
10151 }
10152 }
10153}
10154
10155function commitPlacement(finishedWork) {
10156 if (!supportsMutation) {
10157 return;
10158 }
10159
10160 // Recursively insert all host nodes into the parent.
10161 var parentFiber = getHostParentFiber(finishedWork);
10162
10163 // Note: these two variables *must* always be updated together.
10164 var parent = void 0;
10165 var isContainer = void 0;
10166
10167 switch (parentFiber.tag) {
10168 case HostComponent:
10169 parent = parentFiber.stateNode;
10170 isContainer = false;
10171 break;
10172 case HostRoot:
10173 parent = parentFiber.stateNode.containerInfo;
10174 isContainer = true;
10175 break;
10176 case HostPortal:
10177 parent = parentFiber.stateNode.containerInfo;
10178 isContainer = true;
10179 break;
10180 default:
10181 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
10182 }
10183 if (parentFiber.effectTag & ContentReset) {
10184 // Reset the text content of the parent before doing any insertions
10185 parentFiber.effectTag &= ~ContentReset;
10186 }
10187
10188 var before = getHostSibling(finishedWork);
10189 // We only have the top Fiber that was inserted but we need to recurse down its
10190 // children to find all the terminal nodes.
10191 var node = finishedWork;
10192 while (true) {
10193 if (node.tag === HostComponent || node.tag === HostText) {
10194 if (before) {
10195 if (isContainer) {
10196 insertInContainerBefore(parent, node.stateNode, before);
10197 } else {
10198 insertBefore(parent, node.stateNode, before);
10199 }
10200 } else {
10201 if (isContainer) {
10202 appendChildToContainer(parent, node.stateNode);
10203 } else {
10204 appendChild(parent, node.stateNode);
10205 }
10206 }
10207 } else if (node.tag === HostPortal) {
10208 // If the insertion itself is a portal, then we don't want to traverse
10209 // down its children. Instead, we'll get insertions from each child in
10210 // the portal directly.
10211 } else if (node.child !== null) {
10212 node.child.return = node;
10213 node = node.child;
10214 continue;
10215 }
10216 if (node === finishedWork) {
10217 return;
10218 }
10219 while (node.sibling === null) {
10220 if (node.return === null || node.return === finishedWork) {
10221 return;
10222 }
10223 node = node.return;
10224 }
10225 node.sibling.return = node.return;
10226 node = node.sibling;
10227 }
10228}
10229
10230function unmountHostComponents(current) {
10231 // We only have the top Fiber that was deleted but we need to recurse down its
10232 var node = current;
10233
10234 // Each iteration, currentParent is populated with node's host parent if not
10235 // currentParentIsValid.
10236 var currentParentIsValid = false;
10237
10238 // Note: these two variables *must* always be updated together.
10239 var currentParent = void 0;
10240 var currentParentIsContainer = void 0;
10241
10242 while (true) {
10243 if (!currentParentIsValid) {
10244 var parent = node.return;
10245 findParent: while (true) {
10246 !(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;
10247 switch (parent.tag) {
10248 case HostComponent:
10249 currentParent = parent.stateNode;
10250 currentParentIsContainer = false;
10251 break findParent;
10252 case HostRoot:
10253 currentParent = parent.stateNode.containerInfo;
10254 currentParentIsContainer = true;
10255 break findParent;
10256 case HostPortal:
10257 currentParent = parent.stateNode.containerInfo;
10258 currentParentIsContainer = true;
10259 break findParent;
10260 }
10261 parent = parent.return;
10262 }
10263 currentParentIsValid = true;
10264 }
10265
10266 if (node.tag === HostComponent || node.tag === HostText) {
10267 commitNestedUnmounts(node);
10268 // After all the children have unmounted, it is now safe to remove the
10269 // node from the tree.
10270 if (currentParentIsContainer) {
10271 removeChildFromContainer(currentParent, node.stateNode);
10272 } else {
10273 removeChild(currentParent, node.stateNode);
10274 }
10275 // Don't visit children because we already visited them.
10276 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
10277 // Delete the dehydrated suspense boundary and all of its content.
10278 if (currentParentIsContainer) {
10279 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
10280 } else {
10281 clearSuspenseBoundary(currentParent, node.stateNode);
10282 }
10283 } else if (node.tag === HostPortal) {
10284 if (node.child !== null) {
10285 // When we go into a portal, it becomes the parent to remove from.
10286 // We will reassign it back when we pop the portal on the way up.
10287 currentParent = node.stateNode.containerInfo;
10288 currentParentIsContainer = true;
10289 // Visit children because portals might contain host components.
10290 node.child.return = node;
10291 node = node.child;
10292 continue;
10293 }
10294 } else {
10295 commitUnmount(node);
10296 // Visit children because we may find more host components below.
10297 if (node.child !== null) {
10298 node.child.return = node;
10299 node = node.child;
10300 continue;
10301 }
10302 }
10303 if (node === current) {
10304 return;
10305 }
10306 while (node.sibling === null) {
10307 if (node.return === null || node.return === current) {
10308 return;
10309 }
10310 node = node.return;
10311 if (node.tag === HostPortal) {
10312 // When we go out of the portal, we need to restore the parent.
10313 // Since we don't keep a stack of them, we will search for it.
10314 currentParentIsValid = false;
10315 }
10316 }
10317 node.sibling.return = node.return;
10318 node = node.sibling;
10319 }
10320}
10321
10322function commitDeletion(current) {
10323 if (supportsMutation) {
10324 // Recursively delete all host nodes from the parent.
10325 // Detach refs and call componentWillUnmount() on the whole subtree.
10326 unmountHostComponents(current);
10327 } else {
10328 // Detach refs and call componentWillUnmount() on the whole subtree.
10329 commitNestedUnmounts(current);
10330 }
10331 detachFiber(current);
10332}
10333
10334function commitWork(current, finishedWork) {
10335 if (!supportsMutation) {
10336 switch (finishedWork.tag) {
10337 case FunctionComponent:
10338 case ForwardRef:
10339 case MemoComponent:
10340 case SimpleMemoComponent:
10341 {
10342 // Note: We currently never use MountMutation, but useLayout uses
10343 // UnmountMutation.
10344 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10345 return;
10346 }
10347 }
10348
10349 commitContainer(finishedWork);
10350 return;
10351 }
10352
10353 switch (finishedWork.tag) {
10354 case FunctionComponent:
10355 case ForwardRef:
10356 case MemoComponent:
10357 case SimpleMemoComponent:
10358 {
10359 // Note: We currently never use MountMutation, but useLayout uses
10360 // UnmountMutation.
10361 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10362 return;
10363 }
10364 case ClassComponent:
10365 {
10366 return;
10367 }
10368 case HostComponent:
10369 {
10370 var instance = finishedWork.stateNode;
10371 if (instance != null) {
10372 // Commit the work prepared earlier.
10373 var newProps = finishedWork.memoizedProps;
10374 // For hydration we reuse the update path but we treat the oldProps
10375 // as the newProps. The updatePayload will contain the real change in
10376 // this case.
10377 var oldProps = current !== null ? current.memoizedProps : newProps;
10378 var type = finishedWork.type;
10379 // TODO: Type the updateQueue to be specific to host components.
10380 var updatePayload = finishedWork.updateQueue;
10381 finishedWork.updateQueue = null;
10382 if (updatePayload !== null) {
10383 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
10384 }
10385 }
10386 return;
10387 }
10388 case HostText:
10389 {
10390 !(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;
10391 var textInstance = finishedWork.stateNode;
10392 var newText = finishedWork.memoizedProps;
10393 // For hydration we reuse the update path but we treat the oldProps
10394 // as the newProps. The updatePayload will contain the real change in
10395 // this case.
10396 var oldText = current !== null ? current.memoizedProps : newText;
10397 return;
10398 }
10399 case HostRoot:
10400 {
10401 return;
10402 }
10403 case Profiler:
10404 {
10405 return;
10406 }
10407 case SuspenseComponent:
10408 {
10409 var newState = finishedWork.memoizedState;
10410
10411 var newDidTimeout = void 0;
10412 var primaryChildParent = finishedWork;
10413 if (newState === null) {
10414 newDidTimeout = false;
10415 } else {
10416 newDidTimeout = true;
10417 primaryChildParent = finishedWork.child;
10418 if (newState.timedOutAt === NoWork) {
10419 // If the children had not already timed out, record the time.
10420 // This is used to compute the elapsed time during subsequent
10421 // attempts to render the children.
10422 newState.timedOutAt = requestCurrentTime();
10423 }
10424 }
10425
10426 if (primaryChildParent !== null) {
10427 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
10428 }
10429
10430 // If this boundary just timed out, then it will have a set of thenables.
10431 // For each thenable, attach a listener so that when it resolves, React
10432 // attempts to re-render the boundary in the primary (pre-timeout) state.
10433 var thenables = finishedWork.updateQueue;
10434 if (thenables !== null) {
10435 finishedWork.updateQueue = null;
10436 var retryCache = finishedWork.stateNode;
10437 if (retryCache === null) {
10438 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
10439 }
10440 thenables.forEach(function (thenable) {
10441 // Memoize using the boundary fiber to prevent redundant listeners.
10442 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
10443 if (enableSchedulerTracing) {
10444 retry = unstable_wrap(retry);
10445 }
10446 if (!retryCache.has(thenable)) {
10447 retryCache.add(thenable);
10448 thenable.then(retry, retry);
10449 }
10450 });
10451 }
10452
10453 return;
10454 }
10455 case IncompleteClassComponent:
10456 {
10457 return;
10458 }
10459 default:
10460 {
10461 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.');
10462 }
10463 }
10464}
10465
10466function commitResetTextContent(current) {
10467 if (!supportsMutation) {
10468 return;
10469 }
10470 resetTextContent(current.stateNode);
10471}
10472
10473var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
10474var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
10475
10476function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
10477 var update = createUpdate(expirationTime);
10478 // Unmount the root by rendering null.
10479 update.tag = CaptureUpdate;
10480 // Caution: React DevTools currently depends on this property
10481 // being called "element".
10482 update.payload = { element: null };
10483 var error = errorInfo.value;
10484 update.callback = function () {
10485 onUncaughtError(error);
10486 logError(fiber, errorInfo);
10487 };
10488 return update;
10489}
10490
10491function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
10492 var update = createUpdate(expirationTime);
10493 update.tag = CaptureUpdate;
10494 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
10495 if (typeof getDerivedStateFromError === 'function') {
10496 var error = errorInfo.value;
10497 update.payload = function () {
10498 return getDerivedStateFromError(error);
10499 };
10500 }
10501
10502 var inst = fiber.stateNode;
10503 if (inst !== null && typeof inst.componentDidCatch === 'function') {
10504 update.callback = function callback() {
10505 if (typeof getDerivedStateFromError !== 'function') {
10506 // To preserve the preexisting retry behavior of error boundaries,
10507 // we keep track of which ones already failed during this batch.
10508 // This gets reset before we yield back to the browser.
10509 // TODO: Warn in strict mode if getDerivedStateFromError is
10510 // not defined.
10511 markLegacyErrorBoundaryAsFailed(this);
10512 }
10513 var error = errorInfo.value;
10514 var stack = errorInfo.stack;
10515 logError(fiber, errorInfo);
10516 this.componentDidCatch(error, {
10517 componentStack: stack !== null ? stack : ''
10518 });
10519 {
10520 if (typeof getDerivedStateFromError !== 'function') {
10521 // If componentDidCatch is the only error boundary method defined,
10522 // then it needs to call setState to recover from errors.
10523 // If no state update is scheduled then the boundary will swallow the error.
10524 !(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;
10525 }
10526 }
10527 };
10528 }
10529 return update;
10530}
10531
10532function attachPingListener(root, renderExpirationTime, thenable) {
10533 // Attach a listener to the promise to "ping" the root and retry. But
10534 // only if one does not already exist for the current render expiration
10535 // time (which acts like a "thread ID" here).
10536 var pingCache = root.pingCache;
10537 var threadIDs = void 0;
10538 if (pingCache === null) {
10539 pingCache = root.pingCache = new PossiblyWeakMap();
10540 threadIDs = new Set();
10541 pingCache.set(thenable, threadIDs);
10542 } else {
10543 threadIDs = pingCache.get(thenable);
10544 if (threadIDs === undefined) {
10545 threadIDs = new Set();
10546 pingCache.set(thenable, threadIDs);
10547 }
10548 }
10549 if (!threadIDs.has(renderExpirationTime)) {
10550 // Memoize using the thread ID to prevent redundant listeners.
10551 threadIDs.add(renderExpirationTime);
10552 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
10553 if (enableSchedulerTracing) {
10554 ping = unstable_wrap(ping);
10555 }
10556 thenable.then(ping, ping);
10557 }
10558}
10559
10560function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
10561 // The source fiber did not complete.
10562 sourceFiber.effectTag |= Incomplete;
10563 // Its effect list is no longer valid.
10564 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
10565
10566 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
10567 // This is a thenable.
10568 var thenable = value;
10569
10570 // Find the earliest timeout threshold of all the placeholders in the
10571 // ancestor path. We could avoid this traversal by storing the thresholds on
10572 // the stack, but we choose not to because we only hit this path if we're
10573 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
10574 // the non-IO- bound case.
10575 var _workInProgress = returnFiber;
10576 var earliestTimeoutMs = -1;
10577 var startTimeMs = -1;
10578 do {
10579 if (_workInProgress.tag === SuspenseComponent) {
10580 var current = _workInProgress.alternate;
10581 if (current !== null) {
10582 var currentState = current.memoizedState;
10583 if (currentState !== null) {
10584 // Reached a boundary that already timed out. Do not search
10585 // any further.
10586 var timedOutAt = currentState.timedOutAt;
10587 startTimeMs = expirationTimeToMs(timedOutAt);
10588 // Do not search any further.
10589 break;
10590 }
10591 }
10592 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
10593 if (typeof timeoutPropMs === 'number') {
10594 if (timeoutPropMs <= 0) {
10595 earliestTimeoutMs = 0;
10596 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
10597 earliestTimeoutMs = timeoutPropMs;
10598 }
10599 }
10600 }
10601 // If there is a DehydratedSuspenseComponent we don't have to do anything because
10602 // if something suspends inside it, we will simply leave that as dehydrated. It
10603 // will never timeout.
10604 _workInProgress = _workInProgress.return;
10605 } while (_workInProgress !== null);
10606
10607 // Schedule the nearest Suspense to re-render the timed out view.
10608 _workInProgress = returnFiber;
10609 do {
10610 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
10611 // Found the nearest boundary.
10612
10613 // Stash the promise on the boundary fiber. If the boundary times out, we'll
10614 var thenables = _workInProgress.updateQueue;
10615 if (thenables === null) {
10616 var updateQueue = new Set();
10617 updateQueue.add(thenable);
10618 _workInProgress.updateQueue = updateQueue;
10619 } else {
10620 thenables.add(thenable);
10621 }
10622
10623 // If the boundary is outside of concurrent mode, we should *not*
10624 // suspend the commit. Pretend as if the suspended component rendered
10625 // null and keep rendering. In the commit phase, we'll schedule a
10626 // subsequent synchronous update to re-render the Suspense.
10627 //
10628 // Note: It doesn't matter whether the component that suspended was
10629 // inside a concurrent mode tree. If the Suspense is outside of it, we
10630 // should *not* suspend the commit.
10631 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
10632 _workInProgress.effectTag |= DidCapture;
10633
10634 // We're going to commit this fiber even though it didn't complete.
10635 // But we shouldn't call any lifecycle methods or callbacks. Remove
10636 // all lifecycle effect tags.
10637 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
10638
10639 if (sourceFiber.tag === ClassComponent) {
10640 var currentSourceFiber = sourceFiber.alternate;
10641 if (currentSourceFiber === null) {
10642 // This is a new mount. Change the tag so it's not mistaken for a
10643 // completed class component. For example, we should not call
10644 // componentWillUnmount if it is deleted.
10645 sourceFiber.tag = IncompleteClassComponent;
10646 } else {
10647 // When we try rendering again, we should not reuse the current fiber,
10648 // since it's known to be in an inconsistent state. Use a force updte to
10649 // prevent a bail out.
10650 var update = createUpdate(Sync);
10651 update.tag = ForceUpdate;
10652 enqueueUpdate(sourceFiber, update);
10653 }
10654 }
10655
10656 // The source fiber did not complete. Mark it with Sync priority to
10657 // indicate that it still has pending work.
10658 sourceFiber.expirationTime = Sync;
10659
10660 // Exit without suspending.
10661 return;
10662 }
10663
10664 // Confirmed that the boundary is in a concurrent mode tree. Continue
10665 // with the normal suspend path.
10666
10667 attachPingListener(root, renderExpirationTime, thenable);
10668
10669 var absoluteTimeoutMs = void 0;
10670 if (earliestTimeoutMs === -1) {
10671 // If no explicit threshold is given, default to an arbitrarily large
10672 // value. The actual size doesn't matter because the threshold for the
10673 // whole tree will be clamped to the expiration time.
10674 absoluteTimeoutMs = maxSigned31BitInt;
10675 } else {
10676 if (startTimeMs === -1) {
10677 // This suspend happened outside of any already timed-out
10678 // placeholders. We don't know exactly when the update was
10679 // scheduled, but we can infer an approximate start time from the
10680 // expiration time. First, find the earliest uncommitted expiration
10681 // time in the tree, including work that is suspended. Then subtract
10682 // the offset used to compute an async update's expiration time.
10683 // This will cause high priority (interactive) work to expire
10684 // earlier than necessary, but we can account for this by adjusting
10685 // for the Just Noticeable Difference.
10686 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
10687 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
10688 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
10689 }
10690 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
10691 }
10692
10693 // Mark the earliest timeout in the suspended fiber's ancestor path.
10694 // After completing the root, we'll take the largest of all the
10695 // suspended fiber's timeouts and use it to compute a timeout for the
10696 // whole tree.
10697 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
10698
10699 _workInProgress.effectTag |= ShouldCapture;
10700 _workInProgress.expirationTime = renderExpirationTime;
10701 return;
10702 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
10703 attachPingListener(root, renderExpirationTime, thenable);
10704
10705 // Since we already have a current fiber, we can eagerly add a retry listener.
10706 var retryCache = _workInProgress.memoizedState;
10707 if (retryCache === null) {
10708 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
10709 var _current = _workInProgress.alternate;
10710 !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
10711 _current.memoizedState = retryCache;
10712 }
10713 // Memoize using the boundary fiber to prevent redundant listeners.
10714 if (!retryCache.has(thenable)) {
10715 retryCache.add(thenable);
10716 var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
10717 if (enableSchedulerTracing) {
10718 retry = unstable_wrap(retry);
10719 }
10720 thenable.then(retry, retry);
10721 }
10722 _workInProgress.effectTag |= ShouldCapture;
10723 _workInProgress.expirationTime = renderExpirationTime;
10724 return;
10725 }
10726 // This boundary already captured during this render. Continue to the next
10727 // boundary.
10728 _workInProgress = _workInProgress.return;
10729 } while (_workInProgress !== null);
10730 // No boundary was found. Fallthrough to error mode.
10731 // TODO: Use invariant so the message is stripped in prod?
10732 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));
10733 }
10734
10735 // We didn't find a boundary that could handle this type of exception. Start
10736 // over and traverse parent path again, this time treating the exception
10737 // as an error.
10738 renderDidError();
10739 value = createCapturedValue(value, sourceFiber);
10740 var workInProgress = returnFiber;
10741 do {
10742 switch (workInProgress.tag) {
10743 case HostRoot:
10744 {
10745 var _errorInfo = value;
10746 workInProgress.effectTag |= ShouldCapture;
10747 workInProgress.expirationTime = renderExpirationTime;
10748 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
10749 enqueueCapturedUpdate(workInProgress, _update);
10750 return;
10751 }
10752 case ClassComponent:
10753 // Capture and retry
10754 var errorInfo = value;
10755 var ctor = workInProgress.type;
10756 var instance = workInProgress.stateNode;
10757 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
10758 workInProgress.effectTag |= ShouldCapture;
10759 workInProgress.expirationTime = renderExpirationTime;
10760 // Schedule the error boundary to re-render using updated state
10761 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
10762 enqueueCapturedUpdate(workInProgress, _update2);
10763 return;
10764 }
10765 break;
10766 default:
10767 break;
10768 }
10769 workInProgress = workInProgress.return;
10770 } while (workInProgress !== null);
10771}
10772
10773function unwindWork(workInProgress, renderExpirationTime) {
10774 switch (workInProgress.tag) {
10775 case ClassComponent:
10776 {
10777 var Component = workInProgress.type;
10778 if (isContextProvider(Component)) {
10779 popContext(workInProgress);
10780 }
10781 var effectTag = workInProgress.effectTag;
10782 if (effectTag & ShouldCapture) {
10783 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10784 return workInProgress;
10785 }
10786 return null;
10787 }
10788 case HostRoot:
10789 {
10790 popHostContainer(workInProgress);
10791 popTopLevelContextObject(workInProgress);
10792 var _effectTag = workInProgress.effectTag;
10793 !((_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;
10794 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10795 return workInProgress;
10796 }
10797 case HostComponent:
10798 {
10799 // TODO: popHydrationState
10800 popHostContext(workInProgress);
10801 return null;
10802 }
10803 case SuspenseComponent:
10804 {
10805 var _effectTag2 = workInProgress.effectTag;
10806 if (_effectTag2 & ShouldCapture) {
10807 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
10808 // Captured a suspense effect. Re-render the boundary.
10809 return workInProgress;
10810 }
10811 return null;
10812 }
10813 case DehydratedSuspenseComponent:
10814 {
10815 if (enableSuspenseServerRenderer) {
10816 // TODO: popHydrationState
10817 var _effectTag3 = workInProgress.effectTag;
10818 if (_effectTag3 & ShouldCapture) {
10819 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
10820 // Captured a suspense effect. Re-render the boundary.
10821 return workInProgress;
10822 }
10823 }
10824 return null;
10825 }
10826 case HostPortal:
10827 popHostContainer(workInProgress);
10828 return null;
10829 case ContextProvider:
10830 popProvider(workInProgress);
10831 return null;
10832 default:
10833 return null;
10834 }
10835}
10836
10837function unwindInterruptedWork(interruptedWork) {
10838 switch (interruptedWork.tag) {
10839 case ClassComponent:
10840 {
10841 var childContextTypes = interruptedWork.type.childContextTypes;
10842 if (childContextTypes !== null && childContextTypes !== undefined) {
10843 popContext(interruptedWork);
10844 }
10845 break;
10846 }
10847 case HostRoot:
10848 {
10849 popHostContainer(interruptedWork);
10850 popTopLevelContextObject(interruptedWork);
10851 break;
10852 }
10853 case HostComponent:
10854 {
10855 popHostContext(interruptedWork);
10856 break;
10857 }
10858 case HostPortal:
10859 popHostContainer(interruptedWork);
10860 break;
10861 case ContextProvider:
10862 popProvider(interruptedWork);
10863 break;
10864 default:
10865 break;
10866 }
10867}
10868
10869var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
10870var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
10871
10872
10873var didWarnAboutStateTransition = void 0;
10874var didWarnSetStateChildContext = void 0;
10875var warnAboutUpdateOnUnmounted = void 0;
10876var warnAboutInvalidUpdates = void 0;
10877
10878if (enableSchedulerTracing) {
10879 // Provide explicit error message when production+profiling bundle of e.g. react-dom
10880 // is used with production (non-profiling) bundle of scheduler/tracing
10881 !(__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;
10882}
10883
10884{
10885 didWarnAboutStateTransition = false;
10886 didWarnSetStateChildContext = false;
10887 var didWarnStateUpdateForUnmountedComponent = {};
10888
10889 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
10890 // We show the whole stack but dedupe on the top component's name because
10891 // the problematic code almost always lies inside that component.
10892 var componentName = getComponentName(fiber.type) || 'ReactComponent';
10893 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
10894 return;
10895 }
10896 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));
10897 didWarnStateUpdateForUnmountedComponent[componentName] = true;
10898 };
10899
10900 warnAboutInvalidUpdates = function (instance) {
10901 switch (phase) {
10902 case 'getChildContext':
10903 if (didWarnSetStateChildContext) {
10904 return;
10905 }
10906 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
10907 didWarnSetStateChildContext = true;
10908 break;
10909 case 'render':
10910 if (didWarnAboutStateTransition) {
10911 return;
10912 }
10913 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.');
10914 didWarnAboutStateTransition = true;
10915 break;
10916 }
10917 };
10918}
10919
10920var isWorking = false;
10921
10922// The next work in progress fiber that we're currently working on.
10923var nextUnitOfWork = null;
10924var nextRoot = null;
10925// The time at which we're currently rendering work.
10926var nextRenderExpirationTime = NoWork;
10927var nextLatestAbsoluteTimeoutMs = -1;
10928var nextRenderDidError = false;
10929
10930// The next fiber with an effect that we're currently committing.
10931var nextEffect = null;
10932
10933var isCommitting$1 = false;
10934var rootWithPendingPassiveEffects = null;
10935var passiveEffectCallbackHandle = null;
10936var passiveEffectCallback = null;
10937
10938var legacyErrorBoundariesThatAlreadyFailed = null;
10939
10940// Used for performance tracking.
10941var interruptedBy = null;
10942
10943var stashedWorkInProgressProperties = void 0;
10944var replayUnitOfWork = void 0;
10945var mayReplayFailedUnitOfWork = void 0;
10946var isReplayingFailedUnitOfWork = void 0;
10947var originalReplayError = void 0;
10948var rethrowOriginalError = void 0;
10949if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
10950 stashedWorkInProgressProperties = null;
10951 mayReplayFailedUnitOfWork = true;
10952 isReplayingFailedUnitOfWork = false;
10953 originalReplayError = null;
10954 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
10955 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
10956 // Don't replay promises. Treat everything else like an error.
10957 // TODO: Need to figure out a different strategy if/when we add
10958 // support for catching other types.
10959 return;
10960 }
10961
10962 // Restore the original state of the work-in-progress
10963 if (stashedWorkInProgressProperties === null) {
10964 // This should never happen. Don't throw because this code is DEV-only.
10965 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
10966 return;
10967 }
10968 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
10969
10970 switch (failedUnitOfWork.tag) {
10971 case HostRoot:
10972 popHostContainer(failedUnitOfWork);
10973 popTopLevelContextObject(failedUnitOfWork);
10974 break;
10975 case HostComponent:
10976 popHostContext(failedUnitOfWork);
10977 break;
10978 case ClassComponent:
10979 {
10980 var Component = failedUnitOfWork.type;
10981 if (isContextProvider(Component)) {
10982 popContext(failedUnitOfWork);
10983 }
10984 break;
10985 }
10986 case HostPortal:
10987 popHostContainer(failedUnitOfWork);
10988 break;
10989 case ContextProvider:
10990 popProvider(failedUnitOfWork);
10991 break;
10992 }
10993 // Replay the begin phase.
10994 isReplayingFailedUnitOfWork = true;
10995 originalReplayError = thrownValue;
10996 invokeGuardedCallback(null, workLoop, null, isYieldy);
10997 isReplayingFailedUnitOfWork = false;
10998 originalReplayError = null;
10999 if (hasCaughtError()) {
11000 var replayError = clearCaughtError();
11001 if (replayError != null && thrownValue != null) {
11002 try {
11003 // Reading the expando property is intentionally
11004 // inside `try` because it might be a getter or Proxy.
11005 if (replayError._suppressLogging) {
11006 // Also suppress logging for the original error.
11007 thrownValue._suppressLogging = true;
11008 }
11009 } catch (inner) {
11010 // Ignore.
11011 }
11012 }
11013 } else {
11014 // If the begin phase did not fail the second time, set this pointer
11015 // back to the original value.
11016 nextUnitOfWork = failedUnitOfWork;
11017 }
11018 };
11019 rethrowOriginalError = function () {
11020 throw originalReplayError;
11021 };
11022}
11023
11024function resetStack() {
11025 if (nextUnitOfWork !== null) {
11026 var interruptedWork = nextUnitOfWork.return;
11027 while (interruptedWork !== null) {
11028 unwindInterruptedWork(interruptedWork);
11029 interruptedWork = interruptedWork.return;
11030 }
11031 }
11032
11033 {
11034 ReactStrictModeWarnings.discardPendingWarnings();
11035 checkThatStackIsEmpty();
11036 }
11037
11038 nextRoot = null;
11039 nextRenderExpirationTime = NoWork;
11040 nextLatestAbsoluteTimeoutMs = -1;
11041 nextRenderDidError = false;
11042 nextUnitOfWork = null;
11043}
11044
11045function commitAllHostEffects() {
11046 while (nextEffect !== null) {
11047 {
11048 setCurrentFiber(nextEffect);
11049 }
11050 recordEffect();
11051
11052 var effectTag = nextEffect.effectTag;
11053
11054 if (effectTag & ContentReset) {
11055 commitResetTextContent(nextEffect);
11056 }
11057
11058 if (effectTag & Ref) {
11059 var current = nextEffect.alternate;
11060 if (current !== null) {
11061 commitDetachRef(current);
11062 }
11063 }
11064
11065 // The following switch statement is only concerned about placement,
11066 // updates, and deletions. To avoid needing to add a case for every
11067 // possible bitmap value, we remove the secondary effects from the
11068 // effect tag and switch on that value.
11069 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
11070 switch (primaryEffectTag) {
11071 case Placement:
11072 {
11073 commitPlacement(nextEffect);
11074 // Clear the "placement" from effect tag so that we know that this is inserted, before
11075 // any life-cycles like componentDidMount gets called.
11076 // TODO: findDOMNode doesn't rely on this any more but isMounted
11077 // does and isMounted is deprecated anyway so we should be able
11078 // to kill this.
11079 nextEffect.effectTag &= ~Placement;
11080 break;
11081 }
11082 case PlacementAndUpdate:
11083 {
11084 // Placement
11085 commitPlacement(nextEffect);
11086 // Clear the "placement" from effect tag so that we know that this is inserted, before
11087 // any life-cycles like componentDidMount gets called.
11088 nextEffect.effectTag &= ~Placement;
11089
11090 // Update
11091 var _current = nextEffect.alternate;
11092 commitWork(_current, nextEffect);
11093 break;
11094 }
11095 case Update:
11096 {
11097 var _current2 = nextEffect.alternate;
11098 commitWork(_current2, nextEffect);
11099 break;
11100 }
11101 case Deletion:
11102 {
11103 commitDeletion(nextEffect);
11104 break;
11105 }
11106 }
11107 nextEffect = nextEffect.nextEffect;
11108 }
11109
11110 {
11111 resetCurrentFiber();
11112 }
11113}
11114
11115function commitBeforeMutationLifecycles() {
11116 while (nextEffect !== null) {
11117 {
11118 setCurrentFiber(nextEffect);
11119 }
11120
11121 var effectTag = nextEffect.effectTag;
11122 if (effectTag & Snapshot) {
11123 recordEffect();
11124 var current = nextEffect.alternate;
11125 commitBeforeMutationLifeCycles(current, nextEffect);
11126 }
11127
11128 nextEffect = nextEffect.nextEffect;
11129 }
11130
11131 {
11132 resetCurrentFiber();
11133 }
11134}
11135
11136function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
11137 {
11138 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
11139 ReactStrictModeWarnings.flushLegacyContextWarning();
11140
11141 if (warnAboutDeprecatedLifecycles) {
11142 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
11143 }
11144 }
11145 while (nextEffect !== null) {
11146 {
11147 setCurrentFiber(nextEffect);
11148 }
11149 var effectTag = nextEffect.effectTag;
11150
11151 if (effectTag & (Update | Callback)) {
11152 recordEffect();
11153 var current = nextEffect.alternate;
11154 commitLifeCycles(finishedRoot, current, nextEffect, committedExpirationTime);
11155 }
11156
11157 if (effectTag & Ref) {
11158 recordEffect();
11159 commitAttachRef(nextEffect);
11160 }
11161
11162 if (effectTag & Passive) {
11163 rootWithPendingPassiveEffects = finishedRoot;
11164 }
11165
11166 nextEffect = nextEffect.nextEffect;
11167 }
11168 {
11169 resetCurrentFiber();
11170 }
11171}
11172
11173function commitPassiveEffects(root, firstEffect) {
11174 rootWithPendingPassiveEffects = null;
11175 passiveEffectCallbackHandle = null;
11176 passiveEffectCallback = null;
11177
11178 // Set this to true to prevent re-entrancy
11179 var previousIsRendering = isRendering;
11180 isRendering = true;
11181
11182 var effect = firstEffect;
11183 do {
11184 {
11185 setCurrentFiber(effect);
11186 }
11187
11188 if (effect.effectTag & Passive) {
11189 var didError = false;
11190 var error = void 0;
11191 {
11192 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
11193 if (hasCaughtError()) {
11194 didError = true;
11195 error = clearCaughtError();
11196 }
11197 }
11198 if (didError) {
11199 captureCommitPhaseError(effect, error);
11200 }
11201 }
11202 effect = effect.nextEffect;
11203 } while (effect !== null);
11204 {
11205 resetCurrentFiber();
11206 }
11207
11208 isRendering = previousIsRendering;
11209
11210 // Check if work was scheduled by one of the effects
11211 var rootExpirationTime = root.expirationTime;
11212 if (rootExpirationTime !== NoWork) {
11213 requestWork(root, rootExpirationTime);
11214 }
11215 // Flush any sync work that was scheduled by effects
11216 if (!isBatchingUpdates && !isRendering) {
11217 performSyncWork();
11218 }
11219}
11220
11221function isAlreadyFailedLegacyErrorBoundary(instance) {
11222 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
11223}
11224
11225function markLegacyErrorBoundaryAsFailed(instance) {
11226 if (legacyErrorBoundariesThatAlreadyFailed === null) {
11227 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
11228 } else {
11229 legacyErrorBoundariesThatAlreadyFailed.add(instance);
11230 }
11231}
11232
11233function flushPassiveEffects() {
11234 if (passiveEffectCallbackHandle !== null) {
11235 cancelPassiveEffects(passiveEffectCallbackHandle);
11236 }
11237 if (passiveEffectCallback !== null) {
11238 // We call the scheduled callback instead of commitPassiveEffects directly
11239 // to ensure tracing works correctly.
11240 passiveEffectCallback();
11241 }
11242}
11243
11244function commitRoot(root, finishedWork) {
11245 isWorking = true;
11246 isCommitting$1 = true;
11247 startCommitTimer();
11248
11249 !(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;
11250 var committedExpirationTime = root.pendingCommitExpirationTime;
11251 !(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;
11252 root.pendingCommitExpirationTime = NoWork;
11253
11254 // Update the pending priority levels to account for the work that we are
11255 // about to commit. This needs to happen before calling the lifecycles, since
11256 // they may schedule additional updates.
11257 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
11258 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
11259 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
11260 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
11261
11262 var prevInteractions = null;
11263 if (enableSchedulerTracing) {
11264 // Restore any pending interactions at this point,
11265 // So that cascading work triggered during the render phase will be accounted for.
11266 prevInteractions = __interactionsRef.current;
11267 __interactionsRef.current = root.memoizedInteractions;
11268 }
11269
11270 // Reset this to null before calling lifecycles
11271 ReactCurrentOwner$1.current = null;
11272
11273 var firstEffect = void 0;
11274 if (finishedWork.effectTag > PerformedWork) {
11275 // A fiber's effect list consists only of its children, not itself. So if
11276 // the root has an effect, we need to add it to the end of the list. The
11277 // resulting list is the set that would belong to the root's parent, if
11278 // it had one; that is, all the effects in the tree including the root.
11279 if (finishedWork.lastEffect !== null) {
11280 finishedWork.lastEffect.nextEffect = finishedWork;
11281 firstEffect = finishedWork.firstEffect;
11282 } else {
11283 firstEffect = finishedWork;
11284 }
11285 } else {
11286 // There is no effect on the root.
11287 firstEffect = finishedWork.firstEffect;
11288 }
11289
11290 prepareForCommit(root.containerInfo);
11291
11292 // Invoke instances of getSnapshotBeforeUpdate before mutation.
11293 nextEffect = firstEffect;
11294 startCommitSnapshotEffectsTimer();
11295 while (nextEffect !== null) {
11296 var didError = false;
11297 var error = void 0;
11298 {
11299 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
11300 if (hasCaughtError()) {
11301 didError = true;
11302 error = clearCaughtError();
11303 }
11304 }
11305 if (didError) {
11306 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11307 captureCommitPhaseError(nextEffect, error);
11308 // Clean-up
11309 if (nextEffect !== null) {
11310 nextEffect = nextEffect.nextEffect;
11311 }
11312 }
11313 }
11314 stopCommitSnapshotEffectsTimer();
11315
11316 if (enableProfilerTimer) {
11317 // Mark the current commit time to be shared by all Profilers in this batch.
11318 // This enables them to be grouped later.
11319 recordCommitTime();
11320 }
11321
11322 // Commit all the side-effects within a tree. We'll do this in two passes.
11323 // The first pass performs all the host insertions, updates, deletions and
11324 // ref unmounts.
11325 nextEffect = firstEffect;
11326 startCommitHostEffectsTimer();
11327 while (nextEffect !== null) {
11328 var _didError = false;
11329 var _error = void 0;
11330 {
11331 invokeGuardedCallback(null, commitAllHostEffects, null);
11332 if (hasCaughtError()) {
11333 _didError = true;
11334 _error = clearCaughtError();
11335 }
11336 }
11337 if (_didError) {
11338 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11339 captureCommitPhaseError(nextEffect, _error);
11340 // Clean-up
11341 if (nextEffect !== null) {
11342 nextEffect = nextEffect.nextEffect;
11343 }
11344 }
11345 }
11346 stopCommitHostEffectsTimer();
11347
11348 resetAfterCommit(root.containerInfo);
11349
11350 // The work-in-progress tree is now the current tree. This must come after
11351 // the first pass of the commit phase, so that the previous tree is still
11352 // current during componentWillUnmount, but before the second pass, so that
11353 // the finished work is current during componentDidMount/Update.
11354 root.current = finishedWork;
11355
11356 // In the second pass we'll perform all life-cycles and ref callbacks.
11357 // Life-cycles happen as a separate pass so that all placements, updates,
11358 // and deletions in the entire tree have already been invoked.
11359 // This pass also triggers any renderer-specific initial effects.
11360 nextEffect = firstEffect;
11361 startCommitLifeCyclesTimer();
11362 while (nextEffect !== null) {
11363 var _didError2 = false;
11364 var _error2 = void 0;
11365 {
11366 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
11367 if (hasCaughtError()) {
11368 _didError2 = true;
11369 _error2 = clearCaughtError();
11370 }
11371 }
11372 if (_didError2) {
11373 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11374 captureCommitPhaseError(nextEffect, _error2);
11375 if (nextEffect !== null) {
11376 nextEffect = nextEffect.nextEffect;
11377 }
11378 }
11379 }
11380
11381 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
11382 // This commit included a passive effect. These do not need to fire until
11383 // after the next paint. Schedule an callback to fire them in an async
11384 // event. To ensure serial execution, the callback will be flushed early if
11385 // we enter rootWithPendingPassiveEffects commit phase before then.
11386 var callback = commitPassiveEffects.bind(null, root, firstEffect);
11387 if (enableSchedulerTracing) {
11388 // TODO: Avoid this extra callback by mutating the tracing ref directly,
11389 // like we do at the beginning of commitRoot. I've opted not to do that
11390 // here because that code is still in flux.
11391 callback = unstable_wrap(callback);
11392 }
11393 passiveEffectCallbackHandle = unstable_runWithPriority(unstable_NormalPriority, function () {
11394 return schedulePassiveEffects(callback);
11395 });
11396 passiveEffectCallback = callback;
11397 }
11398
11399 isCommitting$1 = false;
11400 isWorking = false;
11401 stopCommitLifeCyclesTimer();
11402 stopCommitTimer();
11403 onCommitRoot(finishedWork.stateNode);
11404 if (true && ReactFiberInstrumentation_1.debugTool) {
11405 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
11406 }
11407
11408 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
11409 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
11410 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
11411 if (earliestRemainingTimeAfterCommit === NoWork) {
11412 // If there's no remaining work, we can clear the set of already failed
11413 // error boundaries.
11414 legacyErrorBoundariesThatAlreadyFailed = null;
11415 }
11416 onCommit(root, earliestRemainingTimeAfterCommit);
11417
11418 if (enableSchedulerTracing) {
11419 __interactionsRef.current = prevInteractions;
11420
11421 var subscriber = void 0;
11422
11423 try {
11424 subscriber = __subscriberRef.current;
11425 if (subscriber !== null && root.memoizedInteractions.size > 0) {
11426 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
11427 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
11428 }
11429 } catch (error) {
11430 // It's not safe for commitRoot() to throw.
11431 // Store the error for now and we'll re-throw in finishRendering().
11432 if (!hasUnhandledError) {
11433 hasUnhandledError = true;
11434 unhandledError = error;
11435 }
11436 } finally {
11437 // Clear completed interactions from the pending Map.
11438 // Unless the render was suspended or cascading work was scheduled,
11439 // In which case– leave pending interactions until the subsequent render.
11440 var pendingInteractionMap = root.pendingInteractionMap;
11441 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11442 // Only decrement the pending interaction count if we're done.
11443 // If there's still work at the current priority,
11444 // That indicates that we are waiting for suspense data.
11445 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
11446 pendingInteractionMap.delete(scheduledExpirationTime);
11447
11448 scheduledInteractions.forEach(function (interaction) {
11449 interaction.__count--;
11450
11451 if (subscriber !== null && interaction.__count === 0) {
11452 try {
11453 subscriber.onInteractionScheduledWorkCompleted(interaction);
11454 } catch (error) {
11455 // It's not safe for commitRoot() to throw.
11456 // Store the error for now and we'll re-throw in finishRendering().
11457 if (!hasUnhandledError) {
11458 hasUnhandledError = true;
11459 unhandledError = error;
11460 }
11461 }
11462 }
11463 });
11464 }
11465 });
11466 }
11467 }
11468}
11469
11470function resetChildExpirationTime(workInProgress, renderTime) {
11471 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
11472 // The children of this component are hidden. Don't bubble their
11473 // expiration times.
11474 return;
11475 }
11476
11477 var newChildExpirationTime = NoWork;
11478
11479 // Bubble up the earliest expiration time.
11480 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11481 // We're in profiling mode.
11482 // Let's use this same traversal to update the render durations.
11483 var actualDuration = workInProgress.actualDuration;
11484 var treeBaseDuration = workInProgress.selfBaseDuration;
11485
11486 // When a fiber is cloned, its actualDuration is reset to 0.
11487 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
11488 // When work is done, it should bubble to the parent's actualDuration.
11489 // If the fiber has not been cloned though, (meaning no work was done),
11490 // Then this value will reflect the amount of time spent working on a previous render.
11491 // In that case it should not bubble.
11492 // We determine whether it was cloned by comparing the child pointer.
11493 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
11494
11495 var child = workInProgress.child;
11496 while (child !== null) {
11497 var childUpdateExpirationTime = child.expirationTime;
11498 var childChildExpirationTime = child.childExpirationTime;
11499 if (childUpdateExpirationTime > newChildExpirationTime) {
11500 newChildExpirationTime = childUpdateExpirationTime;
11501 }
11502 if (childChildExpirationTime > newChildExpirationTime) {
11503 newChildExpirationTime = childChildExpirationTime;
11504 }
11505 if (shouldBubbleActualDurations) {
11506 actualDuration += child.actualDuration;
11507 }
11508 treeBaseDuration += child.treeBaseDuration;
11509 child = child.sibling;
11510 }
11511 workInProgress.actualDuration = actualDuration;
11512 workInProgress.treeBaseDuration = treeBaseDuration;
11513 } else {
11514 var _child = workInProgress.child;
11515 while (_child !== null) {
11516 var _childUpdateExpirationTime = _child.expirationTime;
11517 var _childChildExpirationTime = _child.childExpirationTime;
11518 if (_childUpdateExpirationTime > newChildExpirationTime) {
11519 newChildExpirationTime = _childUpdateExpirationTime;
11520 }
11521 if (_childChildExpirationTime > newChildExpirationTime) {
11522 newChildExpirationTime = _childChildExpirationTime;
11523 }
11524 _child = _child.sibling;
11525 }
11526 }
11527
11528 workInProgress.childExpirationTime = newChildExpirationTime;
11529}
11530
11531function completeUnitOfWork(workInProgress) {
11532 // Attempt to complete the current unit of work, then move to the
11533 // next sibling. If there are no more siblings, return to the
11534 // parent fiber.
11535 while (true) {
11536 // The current, flushed, state of this fiber is the alternate.
11537 // Ideally nothing should rely on this, but relying on it here
11538 // means that we don't need an additional field on the work in
11539 // progress.
11540 var current = workInProgress.alternate;
11541 {
11542 setCurrentFiber(workInProgress);
11543 }
11544
11545 var returnFiber = workInProgress.return;
11546 var siblingFiber = workInProgress.sibling;
11547
11548 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
11549 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11550 // Don't replay if it fails during completion phase.
11551 mayReplayFailedUnitOfWork = false;
11552 }
11553 // This fiber completed.
11554 // Remember we're completing this unit so we can find a boundary if it fails.
11555 nextUnitOfWork = workInProgress;
11556 if (enableProfilerTimer) {
11557 if (workInProgress.mode & ProfileMode) {
11558 startProfilerTimer(workInProgress);
11559 }
11560 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11561 if (workInProgress.mode & ProfileMode) {
11562 // Update render duration assuming we didn't error.
11563 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11564 }
11565 } else {
11566 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11567 }
11568 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11569 // We're out of completion phase so replaying is fine now.
11570 mayReplayFailedUnitOfWork = true;
11571 }
11572 stopWorkTimer(workInProgress);
11573 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
11574 {
11575 resetCurrentFiber();
11576 }
11577
11578 if (nextUnitOfWork !== null) {
11579 // Completing this fiber spawned new work. Work on that next.
11580 return nextUnitOfWork;
11581 }
11582
11583 if (returnFiber !== null &&
11584 // Do not append effects to parents if a sibling failed to complete
11585 (returnFiber.effectTag & Incomplete) === NoEffect) {
11586 // Append all the effects of the subtree and this fiber onto the effect
11587 // list of the parent. The completion order of the children affects the
11588 // side-effect order.
11589 if (returnFiber.firstEffect === null) {
11590 returnFiber.firstEffect = workInProgress.firstEffect;
11591 }
11592 if (workInProgress.lastEffect !== null) {
11593 if (returnFiber.lastEffect !== null) {
11594 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
11595 }
11596 returnFiber.lastEffect = workInProgress.lastEffect;
11597 }
11598
11599 // If this fiber had side-effects, we append it AFTER the children's
11600 // side-effects. We can perform certain side-effects earlier if
11601 // needed, by doing multiple passes over the effect list. We don't want
11602 // to schedule our own side-effect on our own list because if end up
11603 // reusing children we'll schedule this effect onto itself since we're
11604 // at the end.
11605 var effectTag = workInProgress.effectTag;
11606 // Skip both NoWork and PerformedWork tags when creating the effect list.
11607 // PerformedWork effect is read by React DevTools but shouldn't be committed.
11608 if (effectTag > PerformedWork) {
11609 if (returnFiber.lastEffect !== null) {
11610 returnFiber.lastEffect.nextEffect = workInProgress;
11611 } else {
11612 returnFiber.firstEffect = workInProgress;
11613 }
11614 returnFiber.lastEffect = workInProgress;
11615 }
11616 }
11617
11618 if (true && ReactFiberInstrumentation_1.debugTool) {
11619 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11620 }
11621
11622 if (siblingFiber !== null) {
11623 // If there is more work to do in this returnFiber, do that next.
11624 return siblingFiber;
11625 } else if (returnFiber !== null) {
11626 // If there's no more work in this returnFiber. Complete the returnFiber.
11627 workInProgress = returnFiber;
11628 continue;
11629 } else {
11630 // We've reached the root.
11631 return null;
11632 }
11633 } else {
11634 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11635 // Record the render duration for the fiber that errored.
11636 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11637
11638 // Include the time spent working on failed children before continuing.
11639 var actualDuration = workInProgress.actualDuration;
11640 var child = workInProgress.child;
11641 while (child !== null) {
11642 actualDuration += child.actualDuration;
11643 child = child.sibling;
11644 }
11645 workInProgress.actualDuration = actualDuration;
11646 }
11647
11648 // This fiber did not complete because something threw. Pop values off
11649 // the stack without entering the complete phase. If this is a boundary,
11650 // capture values if possible.
11651 var next = unwindWork(workInProgress, nextRenderExpirationTime);
11652 // Because this fiber did not complete, don't reset its expiration time.
11653 if (workInProgress.effectTag & DidCapture) {
11654 // Restarting an error boundary
11655 stopFailedWorkTimer(workInProgress);
11656 } else {
11657 stopWorkTimer(workInProgress);
11658 }
11659
11660 {
11661 resetCurrentFiber();
11662 }
11663
11664 if (next !== null) {
11665 stopWorkTimer(workInProgress);
11666 if (true && ReactFiberInstrumentation_1.debugTool) {
11667 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11668 }
11669
11670 // If completing this work spawned new work, do that next. We'll come
11671 // back here again.
11672 // Since we're restarting, remove anything that is not a host effect
11673 // from the effect tag.
11674 next.effectTag &= HostEffectMask;
11675 return next;
11676 }
11677
11678 if (returnFiber !== null) {
11679 // Mark the parent fiber as incomplete and clear its effect list.
11680 returnFiber.firstEffect = returnFiber.lastEffect = null;
11681 returnFiber.effectTag |= Incomplete;
11682 }
11683
11684 if (true && ReactFiberInstrumentation_1.debugTool) {
11685 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11686 }
11687
11688 if (siblingFiber !== null) {
11689 // If there is more work to do in this returnFiber, do that next.
11690 return siblingFiber;
11691 } else if (returnFiber !== null) {
11692 // If there's no more work in this returnFiber. Complete the returnFiber.
11693 workInProgress = returnFiber;
11694 continue;
11695 } else {
11696 return null;
11697 }
11698 }
11699 }
11700
11701 // Without this explicit null return Flow complains of invalid return type
11702 // TODO Remove the above while(true) loop
11703 // eslint-disable-next-line no-unreachable
11704 return null;
11705}
11706
11707function performUnitOfWork(workInProgress) {
11708 // The current, flushed, state of this fiber is the alternate.
11709 // Ideally nothing should rely on this, but relying on it here
11710 // means that we don't need an additional field on the work in
11711 // progress.
11712 var current = workInProgress.alternate;
11713
11714 // See if beginning this work spawns more work.
11715 startWorkTimer(workInProgress);
11716 {
11717 setCurrentFiber(workInProgress);
11718 }
11719
11720 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11721 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
11722 }
11723
11724 var next = void 0;
11725 if (enableProfilerTimer) {
11726 if (workInProgress.mode & ProfileMode) {
11727 startProfilerTimer(workInProgress);
11728 }
11729
11730 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11731 workInProgress.memoizedProps = workInProgress.pendingProps;
11732
11733 if (workInProgress.mode & ProfileMode) {
11734 // Record the render duration assuming we didn't bailout (or error).
11735 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
11736 }
11737 } else {
11738 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11739 workInProgress.memoizedProps = workInProgress.pendingProps;
11740 }
11741
11742 {
11743 resetCurrentFiber();
11744 if (isReplayingFailedUnitOfWork) {
11745 // Currently replaying a failed unit of work. This should be unreachable,
11746 // because the render phase is meant to be idempotent, and it should
11747 // have thrown again. Since it didn't, rethrow the original error, so
11748 // React's internal stack is not misaligned.
11749 rethrowOriginalError();
11750 }
11751 }
11752 if (true && ReactFiberInstrumentation_1.debugTool) {
11753 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
11754 }
11755
11756 if (next === null) {
11757 // If this doesn't spawn new work, complete the current work.
11758 next = completeUnitOfWork(workInProgress);
11759 }
11760
11761 ReactCurrentOwner$1.current = null;
11762
11763 return next;
11764}
11765
11766function workLoop(isYieldy) {
11767 if (!isYieldy) {
11768 // Flush work without yielding
11769 while (nextUnitOfWork !== null) {
11770 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11771 }
11772 } else {
11773 // Flush asynchronous work until there's a higher priority event
11774 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
11775 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11776 }
11777 }
11778}
11779
11780function renderRoot(root, isYieldy) {
11781 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11782
11783 flushPassiveEffects();
11784
11785 isWorking = true;
11786 var previousDispatcher = ReactCurrentDispatcher.current;
11787 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
11788
11789 var expirationTime = root.nextExpirationTimeToWorkOn;
11790
11791 // Check if we're starting from a fresh stack, or if we're resuming from
11792 // previously yielded work.
11793 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
11794 // Reset the stack and start working from the root.
11795 resetStack();
11796 nextRoot = root;
11797 nextRenderExpirationTime = expirationTime;
11798 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
11799 root.pendingCommitExpirationTime = NoWork;
11800
11801 if (enableSchedulerTracing) {
11802 // Determine which interactions this batch of work currently includes,
11803 // So that we can accurately attribute time spent working on it,
11804 var interactions = new Set();
11805 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11806 if (scheduledExpirationTime >= expirationTime) {
11807 scheduledInteractions.forEach(function (interaction) {
11808 return interactions.add(interaction);
11809 });
11810 }
11811 });
11812
11813 // Store the current set of interactions on the FiberRoot for a few reasons:
11814 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
11815 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
11816 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
11817 root.memoizedInteractions = interactions;
11818
11819 if (interactions.size > 0) {
11820 var subscriber = __subscriberRef.current;
11821 if (subscriber !== null) {
11822 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
11823 try {
11824 subscriber.onWorkStarted(interactions, threadID);
11825 } catch (error) {
11826 // Work thrown by an interaction tracing subscriber should be rethrown,
11827 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
11828 // Store the error for now and we'll re-throw in finishRendering().
11829 if (!hasUnhandledError) {
11830 hasUnhandledError = true;
11831 unhandledError = error;
11832 }
11833 }
11834 }
11835 }
11836 }
11837 }
11838
11839 var prevInteractions = null;
11840 if (enableSchedulerTracing) {
11841 // We're about to start new traced work.
11842 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
11843 prevInteractions = __interactionsRef.current;
11844 __interactionsRef.current = root.memoizedInteractions;
11845 }
11846
11847 var didFatal = false;
11848
11849 startWorkLoopTimer(nextUnitOfWork);
11850
11851 do {
11852 try {
11853 workLoop(isYieldy);
11854 } catch (thrownValue) {
11855 resetContextDependences();
11856 resetHooks();
11857
11858 // Reset in case completion throws.
11859 // This is only used in DEV and when replaying is on.
11860 var mayReplay = void 0;
11861 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11862 mayReplay = mayReplayFailedUnitOfWork;
11863 mayReplayFailedUnitOfWork = true;
11864 }
11865
11866 if (nextUnitOfWork === null) {
11867 // This is a fatal error.
11868 didFatal = true;
11869 onUncaughtError(thrownValue);
11870 } else {
11871 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
11872 // Record the time spent rendering before an error was thrown.
11873 // This avoids inaccurate Profiler durations in the case of a suspended render.
11874 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
11875 }
11876
11877 {
11878 // Reset global debug state
11879 // We assume this is defined in DEV
11880 resetCurrentlyProcessingQueue();
11881 }
11882
11883 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11884 if (mayReplay) {
11885 var failedUnitOfWork = nextUnitOfWork;
11886 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
11887 }
11888 }
11889
11890 // TODO: we already know this isn't true in some cases.
11891 // At least this shows a nicer error message until we figure out the cause.
11892 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
11893 !(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;
11894
11895 var sourceFiber = nextUnitOfWork;
11896 var returnFiber = sourceFiber.return;
11897 if (returnFiber === null) {
11898 // This is the root. The root could capture its own errors. However,
11899 // we don't know if it errors before or after we pushed the host
11900 // context. This information is needed to avoid a stack mismatch.
11901 // Because we're not sure, treat this as a fatal error. We could track
11902 // which phase it fails in, but doesn't seem worth it. At least
11903 // for now.
11904 didFatal = true;
11905 onUncaughtError(thrownValue);
11906 } else {
11907 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
11908 nextUnitOfWork = completeUnitOfWork(sourceFiber);
11909 continue;
11910 }
11911 }
11912 }
11913 break;
11914 } while (true);
11915
11916 if (enableSchedulerTracing) {
11917 // Traced work is done for now; restore the previous interactions.
11918 __interactionsRef.current = prevInteractions;
11919 }
11920
11921 // We're done performing work. Time to clean up.
11922 isWorking = false;
11923 ReactCurrentDispatcher.current = previousDispatcher;
11924 resetContextDependences();
11925 resetHooks();
11926
11927 // Yield back to main thread.
11928 if (didFatal) {
11929 var _didCompleteRoot = false;
11930 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
11931 interruptedBy = null;
11932 // There was a fatal error.
11933 {
11934 resetStackAfterFatalErrorInDev();
11935 }
11936 // `nextRoot` points to the in-progress root. A non-null value indicates
11937 // that we're in the middle of an async render. Set it to null to indicate
11938 // there's no more work to be done in the current batch.
11939 nextRoot = null;
11940 onFatal(root);
11941 return;
11942 }
11943
11944 if (nextUnitOfWork !== null) {
11945 // There's still remaining async work in this tree, but we ran out of time
11946 // in the current frame. Yield back to the renderer. Unless we're
11947 // interrupted by a higher priority update, we'll continue later from where
11948 // we left off.
11949 var _didCompleteRoot2 = false;
11950 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
11951 interruptedBy = null;
11952 onYield(root);
11953 return;
11954 }
11955
11956 // We completed the whole tree.
11957 var didCompleteRoot = true;
11958 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
11959 var rootWorkInProgress = root.current.alternate;
11960 !(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;
11961
11962 // `nextRoot` points to the in-progress root. A non-null value indicates
11963 // that we're in the middle of an async render. Set it to null to indicate
11964 // there's no more work to be done in the current batch.
11965 nextRoot = null;
11966 interruptedBy = null;
11967
11968 if (nextRenderDidError) {
11969 // There was an error
11970 if (hasLowerPriorityWork(root, expirationTime)) {
11971 // There's lower priority work. If so, it may have the effect of fixing
11972 // the exception that was just thrown. Exit without committing. This is
11973 // similar to a suspend, but without a timeout because we're not waiting
11974 // for a promise to resolve. React will restart at the lower
11975 // priority level.
11976 markSuspendedPriorityLevel(root, expirationTime);
11977 var suspendedExpirationTime = expirationTime;
11978 var rootExpirationTime = root.expirationTime;
11979 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
11980 );
11981 return;
11982 } else if (
11983 // There's no lower priority work, but we're rendering asynchronously.
11984 // Synchronously attempt to render the same level one more time. This is
11985 // similar to a suspend, but without a timeout because we're not waiting
11986 // for a promise to resolve.
11987 !root.didError && isYieldy) {
11988 root.didError = true;
11989 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
11990 var _rootExpirationTime = root.expirationTime = Sync;
11991 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
11992 );
11993 return;
11994 }
11995 }
11996
11997 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
11998 // The tree was suspended.
11999 var _suspendedExpirationTime2 = expirationTime;
12000 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
12001
12002 // Find the earliest uncommitted expiration time in the tree, including
12003 // work that is suspended. The timeout threshold cannot be longer than
12004 // the overall expiration.
12005 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
12006 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
12007 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
12008 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
12009 }
12010
12011 // Subtract the current time from the absolute timeout to get the number
12012 // of milliseconds until the timeout. In other words, convert an absolute
12013 // timestamp to a relative time. This is the value that is passed
12014 // to `setTimeout`.
12015 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
12016 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
12017 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
12018
12019 // TODO: Account for the Just Noticeable Difference
12020
12021 var _rootExpirationTime2 = root.expirationTime;
12022 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
12023 return;
12024 }
12025
12026 // Ready to commit.
12027 onComplete(root, rootWorkInProgress, expirationTime);
12028}
12029
12030function captureCommitPhaseError(sourceFiber, value) {
12031 var expirationTime = Sync;
12032 var fiber = sourceFiber.return;
12033 while (fiber !== null) {
12034 switch (fiber.tag) {
12035 case ClassComponent:
12036 var ctor = fiber.type;
12037 var instance = fiber.stateNode;
12038 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
12039 var errorInfo = createCapturedValue(value, sourceFiber);
12040 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
12041 enqueueUpdate(fiber, update);
12042 scheduleWork(fiber, expirationTime);
12043 return;
12044 }
12045 break;
12046 case HostRoot:
12047 {
12048 var _errorInfo = createCapturedValue(value, sourceFiber);
12049 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
12050 enqueueUpdate(fiber, _update);
12051 scheduleWork(fiber, expirationTime);
12052 return;
12053 }
12054 }
12055 fiber = fiber.return;
12056 }
12057
12058 if (sourceFiber.tag === HostRoot) {
12059 // Error was thrown at the root. There is no parent, so the root
12060 // itself should capture it.
12061 var rootFiber = sourceFiber;
12062 var _errorInfo2 = createCapturedValue(value, rootFiber);
12063 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
12064 enqueueUpdate(rootFiber, _update2);
12065 scheduleWork(rootFiber, expirationTime);
12066 }
12067}
12068
12069function computeThreadID(expirationTime, interactionThreadID) {
12070 // Interaction threads are unique per root and expiration time.
12071 return expirationTime * 1000 + interactionThreadID;
12072}
12073
12074function computeExpirationForFiber(currentTime, fiber) {
12075 var priorityLevel = unstable_getCurrentPriorityLevel();
12076
12077 var expirationTime = void 0;
12078 if ((fiber.mode & ConcurrentMode) === NoContext) {
12079 // Outside of concurrent mode, updates are always synchronous.
12080 expirationTime = Sync;
12081 } else if (isWorking && !isCommitting$1) {
12082 // During render phase, updates expire during as the current render.
12083 expirationTime = nextRenderExpirationTime;
12084 } else {
12085 switch (priorityLevel) {
12086 case unstable_ImmediatePriority:
12087 expirationTime = Sync;
12088 break;
12089 case unstable_UserBlockingPriority:
12090 expirationTime = computeInteractiveExpiration(currentTime);
12091 break;
12092 case unstable_NormalPriority:
12093 // This is a normal, concurrent update
12094 expirationTime = computeAsyncExpiration(currentTime);
12095 break;
12096 case unstable_LowPriority:
12097 case unstable_IdlePriority:
12098 expirationTime = Never;
12099 break;
12100 default:
12101 invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
12102 }
12103
12104 // If we're in the middle of rendering a tree, do not update at the same
12105 // expiration time that is already rendering.
12106 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
12107 expirationTime -= 1;
12108 }
12109 }
12110
12111 // Keep track of the lowest pending interactive expiration time. This
12112 // allows us to synchronously flush all interactive updates
12113 // when needed.
12114 // TODO: Move this to renderer?
12115 return expirationTime;
12116}
12117
12118function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
12119 // Schedule the timeout.
12120 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
12121 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
12122 }
12123}
12124
12125function renderDidError() {
12126 nextRenderDidError = true;
12127}
12128
12129function pingSuspendedRoot(root, thenable, pingTime) {
12130 // A promise that previously suspended React from committing has resolved.
12131 // If React is still suspended, try again at the previous level (pingTime).
12132
12133 var pingCache = root.pingCache;
12134 if (pingCache !== null) {
12135 // The thenable resolved, so we no longer need to memoize, because it will
12136 // never be thrown again.
12137 pingCache.delete(thenable);
12138 }
12139
12140 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
12141 // Received a ping at the same priority level at which we're currently
12142 // rendering. Restart from the root.
12143 nextRoot = null;
12144 } else {
12145 // Confirm that the root is still suspended at this level. Otherwise exit.
12146 if (isPriorityLevelSuspended(root, pingTime)) {
12147 // Ping at the original level
12148 markPingedPriorityLevel(root, pingTime);
12149 var rootExpirationTime = root.expirationTime;
12150 if (rootExpirationTime !== NoWork) {
12151 requestWork(root, rootExpirationTime);
12152 }
12153 }
12154 }
12155}
12156
12157function retryTimedOutBoundary(boundaryFiber, thenable) {
12158 // The boundary fiber (a Suspense component) previously timed out and was
12159 // rendered in its fallback state. One of the promises that suspended it has
12160 // resolved, which means at least part of the tree was likely unblocked. Try
12161 var retryCache = void 0;
12162 if (enableSuspenseServerRenderer) {
12163 switch (boundaryFiber.tag) {
12164 case SuspenseComponent:
12165 retryCache = boundaryFiber.stateNode;
12166 break;
12167 case DehydratedSuspenseComponent:
12168 retryCache = boundaryFiber.memoizedState;
12169 break;
12170 default:
12171 invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
12172 }
12173 } else {
12174 retryCache = boundaryFiber.stateNode;
12175 }
12176 if (retryCache !== null) {
12177 // The thenable resolved, so we no longer need to memoize, because it will
12178 // never be thrown again.
12179 retryCache.delete(thenable);
12180 }
12181
12182 var currentTime = requestCurrentTime();
12183 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
12184 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
12185 if (root !== null) {
12186 markPendingPriorityLevel(root, retryTime);
12187 var rootExpirationTime = root.expirationTime;
12188 if (rootExpirationTime !== NoWork) {
12189 requestWork(root, rootExpirationTime);
12190 }
12191 }
12192}
12193
12194function scheduleWorkToRoot(fiber, expirationTime) {
12195 recordScheduleUpdate();
12196
12197 {
12198 if (fiber.tag === ClassComponent) {
12199 var instance = fiber.stateNode;
12200 warnAboutInvalidUpdates(instance);
12201 }
12202 }
12203
12204 // Update the source fiber's expiration time
12205 if (fiber.expirationTime < expirationTime) {
12206 fiber.expirationTime = expirationTime;
12207 }
12208 var alternate = fiber.alternate;
12209 if (alternate !== null && alternate.expirationTime < expirationTime) {
12210 alternate.expirationTime = expirationTime;
12211 }
12212 // Walk the parent path to the root and update the child expiration time.
12213 var node = fiber.return;
12214 var root = null;
12215 if (node === null && fiber.tag === HostRoot) {
12216 root = fiber.stateNode;
12217 } else {
12218 while (node !== null) {
12219 alternate = node.alternate;
12220 if (node.childExpirationTime < expirationTime) {
12221 node.childExpirationTime = expirationTime;
12222 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12223 alternate.childExpirationTime = expirationTime;
12224 }
12225 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12226 alternate.childExpirationTime = expirationTime;
12227 }
12228 if (node.return === null && node.tag === HostRoot) {
12229 root = node.stateNode;
12230 break;
12231 }
12232 node = node.return;
12233 }
12234 }
12235
12236 if (enableSchedulerTracing) {
12237 if (root !== null) {
12238 var interactions = __interactionsRef.current;
12239 if (interactions.size > 0) {
12240 var pendingInteractionMap = root.pendingInteractionMap;
12241 var pendingInteractions = pendingInteractionMap.get(expirationTime);
12242 if (pendingInteractions != null) {
12243 interactions.forEach(function (interaction) {
12244 if (!pendingInteractions.has(interaction)) {
12245 // Update the pending async work count for previously unscheduled interaction.
12246 interaction.__count++;
12247 }
12248
12249 pendingInteractions.add(interaction);
12250 });
12251 } else {
12252 pendingInteractionMap.set(expirationTime, new Set(interactions));
12253
12254 // Update the pending async work count for the current interactions.
12255 interactions.forEach(function (interaction) {
12256 interaction.__count++;
12257 });
12258 }
12259
12260 var subscriber = __subscriberRef.current;
12261 if (subscriber !== null) {
12262 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
12263 subscriber.onWorkScheduled(interactions, threadID);
12264 }
12265 }
12266 }
12267 }
12268 return root;
12269}
12270
12271function warnIfNotCurrentlyBatchingInDev(fiber) {
12272 {
12273 if (isRendering === false && isBatchingUpdates === false) {
12274 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));
12275 }
12276 }
12277}
12278
12279function scheduleWork(fiber, expirationTime) {
12280 var root = scheduleWorkToRoot(fiber, expirationTime);
12281 if (root === null) {
12282 {
12283 switch (fiber.tag) {
12284 case ClassComponent:
12285 warnAboutUpdateOnUnmounted(fiber, true);
12286 break;
12287 case FunctionComponent:
12288 case ForwardRef:
12289 case MemoComponent:
12290 case SimpleMemoComponent:
12291 warnAboutUpdateOnUnmounted(fiber, false);
12292 break;
12293 }
12294 }
12295 return;
12296 }
12297
12298 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
12299 // This is an interruption. (Used for performance tracking.)
12300 interruptedBy = fiber;
12301 resetStack();
12302 }
12303 markPendingPriorityLevel(root, expirationTime);
12304 if (
12305 // If we're in the render phase, we don't need to schedule this root
12306 // for an update, because we'll do it before we exit...
12307 !isWorking || isCommitting$1 ||
12308 // ...unless this is a different root than the one we're rendering.
12309 nextRoot !== root) {
12310 var rootExpirationTime = root.expirationTime;
12311 requestWork(root, rootExpirationTime);
12312 }
12313 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
12314 // Reset this back to zero so subsequent updates don't throw.
12315 nestedUpdateCount = 0;
12316 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.');
12317 }
12318}
12319
12320// TODO: Everything below this is written as if it has been lifted to the
12321// renderers. I'll do this in a follow-up.
12322
12323// Linked-list of roots
12324var firstScheduledRoot = null;
12325var lastScheduledRoot = null;
12326
12327var callbackExpirationTime = NoWork;
12328var callbackID = void 0;
12329var isRendering = false;
12330var nextFlushedRoot = null;
12331var nextFlushedExpirationTime = NoWork;
12332var hasUnhandledError = false;
12333var unhandledError = null;
12334
12335var isBatchingUpdates = false;
12336var isUnbatchingUpdates = false;
12337
12338var completedBatches = null;
12339
12340var originalStartTimeMs = unstable_now();
12341var currentRendererTime = msToExpirationTime(originalStartTimeMs);
12342var currentSchedulerTime = currentRendererTime;
12343
12344// Use these to prevent an infinite loop of nested updates
12345var NESTED_UPDATE_LIMIT = 50;
12346var nestedUpdateCount = 0;
12347var lastCommittedRootDuringThisBatch = null;
12348
12349function recomputeCurrentRendererTime() {
12350 var currentTimeMs = unstable_now() - originalStartTimeMs;
12351 currentRendererTime = msToExpirationTime(currentTimeMs);
12352}
12353
12354function scheduleCallbackWithExpirationTime(root, expirationTime) {
12355 if (callbackExpirationTime !== NoWork) {
12356 // A callback is already scheduled. Check its expiration time (timeout).
12357 if (expirationTime < callbackExpirationTime) {
12358 // Existing callback has sufficient timeout. Exit.
12359 return;
12360 } else {
12361 if (callbackID !== null) {
12362 // Existing callback has insufficient timeout. Cancel and schedule a
12363 // new one.
12364 unstable_cancelCallback(callbackID);
12365 }
12366 }
12367 // The request callback timer is already running. Don't start a new one.
12368 } else {
12369 startRequestCallbackTimer();
12370 }
12371
12372 callbackExpirationTime = expirationTime;
12373 var currentMs = unstable_now() - originalStartTimeMs;
12374 var expirationTimeMs = expirationTimeToMs(expirationTime);
12375 var timeout = expirationTimeMs - currentMs;
12376 callbackID = unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
12377}
12378
12379// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
12380// onYield is called upon exiting. We use these in lieu of returning a tuple.
12381// I've also chosen not to inline them into renderRoot because these will
12382// eventually be lifted into the renderer.
12383function onFatal(root) {
12384 root.finishedWork = null;
12385}
12386
12387function onComplete(root, finishedWork, expirationTime) {
12388 root.pendingCommitExpirationTime = expirationTime;
12389 root.finishedWork = finishedWork;
12390}
12391
12392function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
12393 root.expirationTime = rootExpirationTime;
12394 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
12395 // Don't wait an additional tick. Commit the tree immediately.
12396 root.pendingCommitExpirationTime = suspendedExpirationTime;
12397 root.finishedWork = finishedWork;
12398 } else if (msUntilTimeout > 0) {
12399 // Wait `msUntilTimeout` milliseconds before committing.
12400 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
12401 }
12402}
12403
12404function onYield(root) {
12405 root.finishedWork = null;
12406}
12407
12408function onTimeout(root, finishedWork, suspendedExpirationTime) {
12409 // The root timed out. Commit it.
12410 root.pendingCommitExpirationTime = suspendedExpirationTime;
12411 root.finishedWork = finishedWork;
12412 // Read the current time before entering the commit phase. We can be
12413 // certain this won't cause tearing related to batching of event updates
12414 // because we're at the top of a timer event.
12415 recomputeCurrentRendererTime();
12416 currentSchedulerTime = currentRendererTime;
12417 flushRoot(root, suspendedExpirationTime);
12418}
12419
12420function onCommit(root, expirationTime) {
12421 root.expirationTime = expirationTime;
12422 root.finishedWork = null;
12423}
12424
12425function requestCurrentTime() {
12426 // requestCurrentTime is called by the scheduler to compute an expiration
12427 // time.
12428 //
12429 // Expiration times are computed by adding to the current time (the start
12430 // time). However, if two updates are scheduled within the same event, we
12431 // should treat their start times as simultaneous, even if the actual clock
12432 // time has advanced between the first and second call.
12433
12434 // In other words, because expiration times determine how updates are batched,
12435 // we want all updates of like priority that occur within the same event to
12436 // receive the same expiration time. Otherwise we get tearing.
12437 //
12438 // We keep track of two separate times: the current "renderer" time and the
12439 // current "scheduler" time. The renderer time can be updated whenever; it
12440 // only exists to minimize the calls performance.now.
12441 //
12442 // But the scheduler time can only be updated if there's no pending work, or
12443 // if we know for certain that we're not in the middle of an event.
12444
12445 if (isRendering) {
12446 // We're already rendering. Return the most recently read time.
12447 return currentSchedulerTime;
12448 }
12449 // Check if there's pending work.
12450 findHighestPriorityRoot();
12451 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
12452 // If there's no pending work, or if the pending work is offscreen, we can
12453 // read the current time without risk of tearing.
12454 recomputeCurrentRendererTime();
12455 currentSchedulerTime = currentRendererTime;
12456 return currentSchedulerTime;
12457 }
12458 // There's already pending work. We might be in the middle of a browser
12459 // event. If we were to read the current time, it could cause multiple updates
12460 // within the same event to receive different expiration times, leading to
12461 // tearing. Return the last read time. During the next idle callback, the
12462 // time will be updated.
12463 return currentSchedulerTime;
12464}
12465
12466// requestWork is called by the scheduler whenever a root receives an update.
12467// It's up to the renderer to call renderRoot at some point in the future.
12468function requestWork(root, expirationTime) {
12469 addRootToSchedule(root, expirationTime);
12470 if (isRendering) {
12471 // Prevent reentrancy. Remaining work will be scheduled at the end of
12472 // the currently rendering batch.
12473 return;
12474 }
12475
12476 if (isBatchingUpdates) {
12477 // Flush work at the end of the batch.
12478 if (isUnbatchingUpdates) {
12479 // ...unless we're inside unbatchedUpdates, in which case we should
12480 // flush it now.
12481 nextFlushedRoot = root;
12482 nextFlushedExpirationTime = Sync;
12483 performWorkOnRoot(root, Sync, false);
12484 }
12485 return;
12486 }
12487
12488 // TODO: Get rid of Sync and use current time?
12489 if (expirationTime === Sync) {
12490 performSyncWork();
12491 } else {
12492 scheduleCallbackWithExpirationTime(root, expirationTime);
12493 }
12494}
12495
12496function addRootToSchedule(root, expirationTime) {
12497 // Add the root to the schedule.
12498 // Check if this root is already part of the schedule.
12499 if (root.nextScheduledRoot === null) {
12500 // This root is not already scheduled. Add it.
12501 root.expirationTime = expirationTime;
12502 if (lastScheduledRoot === null) {
12503 firstScheduledRoot = lastScheduledRoot = root;
12504 root.nextScheduledRoot = root;
12505 } else {
12506 lastScheduledRoot.nextScheduledRoot = root;
12507 lastScheduledRoot = root;
12508 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12509 }
12510 } else {
12511 // This root is already scheduled, but its priority may have increased.
12512 var remainingExpirationTime = root.expirationTime;
12513 if (expirationTime > remainingExpirationTime) {
12514 // Update the priority.
12515 root.expirationTime = expirationTime;
12516 }
12517 }
12518}
12519
12520function findHighestPriorityRoot() {
12521 var highestPriorityWork = NoWork;
12522 var highestPriorityRoot = null;
12523 if (lastScheduledRoot !== null) {
12524 var previousScheduledRoot = lastScheduledRoot;
12525 var root = firstScheduledRoot;
12526 while (root !== null) {
12527 var remainingExpirationTime = root.expirationTime;
12528 if (remainingExpirationTime === NoWork) {
12529 // This root no longer has work. Remove it from the scheduler.
12530
12531 // TODO: This check is redudant, but Flow is confused by the branch
12532 // below where we set lastScheduledRoot to null, even though we break
12533 // from the loop right after.
12534 !(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;
12535 if (root === root.nextScheduledRoot) {
12536 // This is the only root in the list.
12537 root.nextScheduledRoot = null;
12538 firstScheduledRoot = lastScheduledRoot = null;
12539 break;
12540 } else if (root === firstScheduledRoot) {
12541 // This is the first root in the list.
12542 var next = root.nextScheduledRoot;
12543 firstScheduledRoot = next;
12544 lastScheduledRoot.nextScheduledRoot = next;
12545 root.nextScheduledRoot = null;
12546 } else if (root === lastScheduledRoot) {
12547 // This is the last root in the list.
12548 lastScheduledRoot = previousScheduledRoot;
12549 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12550 root.nextScheduledRoot = null;
12551 break;
12552 } else {
12553 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
12554 root.nextScheduledRoot = null;
12555 }
12556 root = previousScheduledRoot.nextScheduledRoot;
12557 } else {
12558 if (remainingExpirationTime > highestPriorityWork) {
12559 // Update the priority, if it's higher
12560 highestPriorityWork = remainingExpirationTime;
12561 highestPriorityRoot = root;
12562 }
12563 if (root === lastScheduledRoot) {
12564 break;
12565 }
12566 if (highestPriorityWork === Sync) {
12567 // Sync is highest priority by definition so
12568 // we can stop searching.
12569 break;
12570 }
12571 previousScheduledRoot = root;
12572 root = root.nextScheduledRoot;
12573 }
12574 }
12575 }
12576
12577 nextFlushedRoot = highestPriorityRoot;
12578 nextFlushedExpirationTime = highestPriorityWork;
12579}
12580
12581// TODO: This wrapper exists because many of the older tests (the ones that use
12582// flushDeferredPri) rely on the number of times `shouldYield` is called. We
12583// should get rid of it.
12584var didYield = false;
12585function shouldYieldToRenderer() {
12586 if (didYield) {
12587 return true;
12588 }
12589 if (unstable_shouldYield()) {
12590 didYield = true;
12591 return true;
12592 }
12593 return false;
12594}
12595
12596function performAsyncWork() {
12597 try {
12598 if (!shouldYieldToRenderer()) {
12599 // The callback timed out. That means at least one update has expired.
12600 // Iterate through the root schedule. If they contain expired work, set
12601 // the next render expiration time to the current time. This has the effect
12602 // of flushing all expired work in a single batch, instead of flushing each
12603 // level one at a time.
12604 if (firstScheduledRoot !== null) {
12605 recomputeCurrentRendererTime();
12606 var root = firstScheduledRoot;
12607 do {
12608 didExpireAtExpirationTime(root, currentRendererTime);
12609 // The root schedule is circular, so this is never null.
12610 root = root.nextScheduledRoot;
12611 } while (root !== firstScheduledRoot);
12612 }
12613 }
12614 performWork(NoWork, true);
12615 } finally {
12616 didYield = false;
12617 }
12618}
12619
12620function performSyncWork() {
12621 performWork(Sync, false);
12622}
12623
12624function performWork(minExpirationTime, isYieldy) {
12625 // Keep working on roots until there's no more work, or until there's a higher
12626 // priority event.
12627 findHighestPriorityRoot();
12628
12629 if (isYieldy) {
12630 recomputeCurrentRendererTime();
12631 currentSchedulerTime = currentRendererTime;
12632
12633 if (enableUserTimingAPI) {
12634 var didExpire = nextFlushedExpirationTime > currentRendererTime;
12635 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
12636 stopRequestCallbackTimer(didExpire, timeout);
12637 }
12638
12639 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
12640 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
12641 findHighestPriorityRoot();
12642 recomputeCurrentRendererTime();
12643 currentSchedulerTime = currentRendererTime;
12644 }
12645 } else {
12646 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
12647 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
12648 findHighestPriorityRoot();
12649 }
12650 }
12651
12652 // We're done flushing work. Either we ran out of time in this callback,
12653 // or there's no more work left with sufficient priority.
12654
12655 // If we're inside a callback, set this to false since we just completed it.
12656 if (isYieldy) {
12657 callbackExpirationTime = NoWork;
12658 callbackID = null;
12659 }
12660 // If there's work left over, schedule a new callback.
12661 if (nextFlushedExpirationTime !== NoWork) {
12662 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
12663 }
12664
12665 // Clean-up.
12666 finishRendering();
12667}
12668
12669function flushRoot(root, expirationTime) {
12670 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
12671 // Perform work on root as if the given expiration time is the current time.
12672 // This has the effect of synchronously flushing all work up to and
12673 // including the given time.
12674 nextFlushedRoot = root;
12675 nextFlushedExpirationTime = expirationTime;
12676 performWorkOnRoot(root, expirationTime, false);
12677 // Flush any sync work that was scheduled by lifecycles
12678 performSyncWork();
12679}
12680
12681function finishRendering() {
12682 nestedUpdateCount = 0;
12683 lastCommittedRootDuringThisBatch = null;
12684
12685 if (completedBatches !== null) {
12686 var batches = completedBatches;
12687 completedBatches = null;
12688 for (var i = 0; i < batches.length; i++) {
12689 var batch = batches[i];
12690 try {
12691 batch._onComplete();
12692 } catch (error) {
12693 if (!hasUnhandledError) {
12694 hasUnhandledError = true;
12695 unhandledError = error;
12696 }
12697 }
12698 }
12699 }
12700
12701 if (hasUnhandledError) {
12702 var error = unhandledError;
12703 unhandledError = null;
12704 hasUnhandledError = false;
12705 throw error;
12706 }
12707}
12708
12709function performWorkOnRoot(root, expirationTime, isYieldy) {
12710 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12711
12712 isRendering = true;
12713
12714 // Check if this is async work or sync/expired work.
12715 if (!isYieldy) {
12716 // Flush work without yielding.
12717 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
12718 // may want to perform some work without yielding, but also without
12719 // requiring the root to complete (by triggering placeholders).
12720
12721 var finishedWork = root.finishedWork;
12722 if (finishedWork !== null) {
12723 // This root is already complete. We can commit it.
12724 completeRoot(root, finishedWork, expirationTime);
12725 } else {
12726 root.finishedWork = null;
12727 // If this root previously suspended, clear its existing timeout, since
12728 // we're about to try rendering again.
12729 var timeoutHandle = root.timeoutHandle;
12730 if (timeoutHandle !== noTimeout) {
12731 root.timeoutHandle = noTimeout;
12732 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12733 cancelTimeout(timeoutHandle);
12734 }
12735 renderRoot(root, isYieldy);
12736 finishedWork = root.finishedWork;
12737 if (finishedWork !== null) {
12738 // We've completed the root. Commit it.
12739 completeRoot(root, finishedWork, expirationTime);
12740 }
12741 }
12742 } else {
12743 // Flush async work.
12744 var _finishedWork = root.finishedWork;
12745 if (_finishedWork !== null) {
12746 // This root is already complete. We can commit it.
12747 completeRoot(root, _finishedWork, expirationTime);
12748 } else {
12749 root.finishedWork = null;
12750 // If this root previously suspended, clear its existing timeout, since
12751 // we're about to try rendering again.
12752 var _timeoutHandle = root.timeoutHandle;
12753 if (_timeoutHandle !== noTimeout) {
12754 root.timeoutHandle = noTimeout;
12755 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12756 cancelTimeout(_timeoutHandle);
12757 }
12758 renderRoot(root, isYieldy);
12759 _finishedWork = root.finishedWork;
12760 if (_finishedWork !== null) {
12761 // We've completed the root. Check the if we should yield one more time
12762 // before committing.
12763 if (!shouldYieldToRenderer()) {
12764 // Still time left. Commit the root.
12765 completeRoot(root, _finishedWork, expirationTime);
12766 } else {
12767 // There's no time left. Mark this root as complete. We'll come
12768 // back and commit it later.
12769 root.finishedWork = _finishedWork;
12770 }
12771 }
12772 }
12773 }
12774
12775 isRendering = false;
12776}
12777
12778function completeRoot(root, finishedWork, expirationTime) {
12779 // Check if there's a batch that matches this expiration time.
12780 var firstBatch = root.firstBatch;
12781 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
12782 if (completedBatches === null) {
12783 completedBatches = [firstBatch];
12784 } else {
12785 completedBatches.push(firstBatch);
12786 }
12787 if (firstBatch._defer) {
12788 // This root is blocked from committing by a batch. Unschedule it until
12789 // we receive another update.
12790 root.finishedWork = finishedWork;
12791 root.expirationTime = NoWork;
12792 return;
12793 }
12794 }
12795
12796 // Commit the root.
12797 root.finishedWork = null;
12798
12799 // Check if this is a nested update (a sync update scheduled during the
12800 // commit phase).
12801 if (root === lastCommittedRootDuringThisBatch) {
12802 // If the next root is the same as the previous root, this is a nested
12803 // update. To prevent an infinite loop, increment the nested update count.
12804 nestedUpdateCount++;
12805 } else {
12806 // Reset whenever we switch roots.
12807 lastCommittedRootDuringThisBatch = root;
12808 nestedUpdateCount = 0;
12809 }
12810 unstable_runWithPriority(unstable_ImmediatePriority, function () {
12811 commitRoot(root, finishedWork);
12812 });
12813}
12814
12815function onUncaughtError(error) {
12816 !(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;
12817 // Unschedule this root so we don't work on it again until there's
12818 // another update.
12819 nextFlushedRoot.expirationTime = NoWork;
12820 if (!hasUnhandledError) {
12821 hasUnhandledError = true;
12822 unhandledError = error;
12823 }
12824}
12825
12826// 0 is PROD, 1 is DEV.
12827// Might add PROFILE later.
12828
12829
12830var didWarnAboutNestedUpdates = void 0;
12831{
12832 didWarnAboutNestedUpdates = false;
12833
12834}
12835
12836function getContextForSubtree(parentComponent) {
12837 if (!parentComponent) {
12838 return emptyContextObject;
12839 }
12840
12841 var fiber = get(parentComponent);
12842 var parentContext = findCurrentUnmaskedContext(fiber);
12843
12844 if (fiber.tag === ClassComponent) {
12845 var Component = fiber.type;
12846 if (isContextProvider(Component)) {
12847 return processChildContext(fiber, Component, parentContext);
12848 }
12849 }
12850
12851 return parentContext;
12852}
12853
12854function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
12855 {
12856 if (phase === 'render' && current$1 !== null && !didWarnAboutNestedUpdates) {
12857 didWarnAboutNestedUpdates = true;
12858 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');
12859 }
12860 }
12861
12862 var update = createUpdate(expirationTime);
12863 // Caution: React DevTools currently depends on this property
12864 // being called "element".
12865 update.payload = { element: element };
12866
12867 callback = callback === undefined ? null : callback;
12868 if (callback !== null) {
12869 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
12870 update.callback = callback;
12871 }
12872
12873 flushPassiveEffects();
12874 enqueueUpdate(current$$1, update);
12875 scheduleWork(current$$1, expirationTime);
12876
12877 return expirationTime;
12878}
12879
12880function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
12881 // TODO: If this is a nested container, this won't be the root.
12882 var current$$1 = container.current;
12883
12884 {
12885 if (ReactFiberInstrumentation_1.debugTool) {
12886 if (current$$1.alternate === null) {
12887 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
12888 } else if (element === null) {
12889 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
12890 } else {
12891 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
12892 }
12893 }
12894 }
12895
12896 var context = getContextForSubtree(parentComponent);
12897 if (container.context === null) {
12898 container.context = context;
12899 } else {
12900 container.pendingContext = context;
12901 }
12902
12903 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
12904}
12905
12906function createContainer(containerInfo, isConcurrent, hydrate) {
12907 return createFiberRoot(containerInfo, isConcurrent, hydrate);
12908}
12909
12910function updateContainer(element, container, parentComponent, callback) {
12911 var current$$1 = container.current;
12912 var currentTime = requestCurrentTime();
12913 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
12914 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
12915}
12916
12917
12918
12919
12920
12921var overrideProps = null;
12922
12923{
12924 var copyWithSetImpl = function (obj, path, idx, value) {
12925 if (idx >= path.length) {
12926 return value;
12927 }
12928 var key = path[idx];
12929 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
12930 // $FlowFixMe number or string is fine here
12931 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
12932 return updated;
12933 };
12934
12935 var copyWithSet = function (obj, path, value) {
12936 return copyWithSetImpl(obj, path, 0, value);
12937 };
12938
12939 // Support DevTools props for function components, forwardRef, memo, host components, etc.
12940 overrideProps = function (fiber, path, value) {
12941 flushPassiveEffects();
12942 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
12943 if (fiber.alternate) {
12944 fiber.alternate.pendingProps = fiber.pendingProps;
12945 }
12946 scheduleWork(fiber, Sync);
12947 };
12948}
12949
12950function injectIntoDevTools(devToolsConfig) {
12951 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
12952 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
12953
12954
12955 return injectInternals(_assign({}, devToolsConfig, {
12956 overrideProps: overrideProps,
12957 currentDispatcherRef: ReactCurrentDispatcher,
12958 findHostInstanceByFiber: function (fiber) {
12959 var hostFiber = findCurrentHostFiber(fiber);
12960 if (hostFiber === null) {
12961 return null;
12962 }
12963 return hostFiber.stateNode;
12964 },
12965 findFiberByHostInstance: function (instance) {
12966 if (!findFiberByHostInstance) {
12967 // Might not be implemented by the renderer.
12968 return null;
12969 }
12970 return findFiberByHostInstance(instance);
12971 }
12972 }));
12973}
12974
12975// This file intentionally does *not* have the Flow annotation.
12976// Don't add it. See `./inline-typed.js` for an explanation.
12977
12978var container = _class({
12979
12980 grab: function(){
12981 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
12982 return this;
12983 },
12984
12985 empty: function(){
12986 var node;
12987 while (node = this.firstChild) node.eject();
12988 return this;
12989 }
12990
12991});
12992
12993function elementFrom(node){
12994 if (node.toElement) return node.toElement();
12995 if (node.getDOMNode) return node.getDOMNode();
12996 if (node.getNode) return node.getNode();
12997 return node;
12998}
12999
13000var native_1 = _class({
13001
13002 // conventions
13003
13004 toElement: function(){
13005 return this.element;
13006 },
13007
13008 getDOMNode: function(){
13009 return this.toElement();
13010 },
13011
13012 getNode: function(){
13013 return this.toElement();
13014 },
13015
13016 // placement
13017
13018 inject: function(container){
13019 (container.containerElement || elementFrom(container))
13020 .appendChild(this.element);
13021 return this;
13022 },
13023
13024 injectBefore: function(sibling){
13025 var element = elementFrom(sibling);
13026 element.parentNode.insertBefore(this.element, element);
13027 return this;
13028 },
13029
13030 eject: function(){
13031 var element = this.element, parent = element.parentNode;
13032 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
13033 return this;
13034 },
13035
13036 // events
13037
13038 subscribe: function(type, fn, bind){
13039 if (typeof type != 'string'){ // listen type / fn with object
13040 var subscriptions = [];
13041 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
13042 return function(){ // unsubscribe
13043 for (var i = 0, l = subscriptions.length; i < l; i++)
13044 subscriptions[i]();
13045 return this;
13046 };
13047 } else { // listen to one
13048 if (!bind) bind = this;
13049 var bound;
13050 if (typeof fn === 'function'){
13051 bound = fn.bind ? fn.bind(bind)
13052 : function(){ return fn.apply(bind, arguments); };
13053 } else {
13054 bound = fn;
13055 }
13056 var element = this.element;
13057 if (element.addEventListener){
13058 element.addEventListener(type, bound, false);
13059 return function(){ // unsubscribe
13060 element.removeEventListener(type, bound, false);
13061 return this;
13062 };
13063 } else {
13064 element.attachEvent('on' + type, bound);
13065 return function(){ // unsubscribe
13066 element.detachEvent('on' + type, bound);
13067 return this;
13068 };
13069 }
13070 }
13071 }
13072
13073});
13074
13075var fps = 1000 / 60;
13076var invalids = [];
13077var renderTimer;
13078var renderInvalids = function(){
13079 clearTimeout(renderTimer);
13080 renderTimer = null;
13081 var canvases = invalids;
13082 invalids = [];
13083 for (var i = 0, l = canvases.length; i < l; i++){
13084 var c = canvases[i];
13085 c._valid = true;
13086 c.render();
13087 }
13088};
13089
13090var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
13091
13092var previousHit = null;
13093var previousHitSurface = null;
13094
13095var CanvasSurface = _class(native_1, container, {
13096
13097 initialize: function(width, height, existingElement){
13098 var element = this.element = existingElement || document.createElement('canvas');
13099 var context = this.context = element.getContext('2d');
13100 this._valid = true;
13101 if (width != null && height != null) this.resize(width, height);
13102
13103 element.addEventListener('mousemove', this, false);
13104 element.addEventListener('mouseout', this, false);
13105 element.addEventListener('mouseover', this, false);
13106 element.addEventListener('mouseup', this, false);
13107 element.addEventListener('mousedown', this, false);
13108 element.addEventListener('click', this, false);
13109 },
13110
13111 handleEvent: function(event){
13112 if (event.clientX == null) return;
13113 var element = this.element,
13114 rect = element.getBoundingClientRect(),
13115 x = event.clientX - rect.left - element.clientLeft,
13116 y = event.clientY - rect.top - element.clientTop,
13117 hit = this.hitTest(x, y);
13118
13119 if (hit !== previousHit){
13120 if (previousHit){
13121 previousHit.dispatch({
13122 type: 'mouseout',
13123 target: previousHit,
13124 relatedTarget: hit,
13125 sourceEvent: event
13126 });
13127 }
13128 if (hit){
13129 hit.dispatch({
13130 type: 'mouseover',
13131 target: hit,
13132 relatedTarget: previousHit,
13133 sourceEvent: event
13134 });
13135 }
13136 previousHit = hit;
13137 previousHitSurface = this;
13138 this.refreshCursor();
13139 }
13140
13141 if (hit) hit.dispatch(event);
13142 },
13143
13144 refreshCursor: function(){
13145 if (previousHitSurface !== this) return;
13146 var hit = previousHit, hitCursor = '', hitTooltip = '';
13147 while (hit){
13148 if (!hitCursor && hit._cursor){
13149 hitCursor = hit._cursor;
13150 if (hitTooltip) break;
13151 }
13152 if (!hitTooltip && hit._tooltip){
13153 hitTooltip = hit._tooltip;
13154 if (hitCursor) break;
13155 }
13156 hit = hit.parentNode;
13157 }
13158 // TODO: No way to set cursor/title on the surface
13159 this.element.style.cursor = hitCursor;
13160 this.element.title = hitTooltip;
13161 },
13162
13163 resize: function(width, height){
13164 var element = this.element;
13165 element.setAttribute('width', width * resolution);
13166 element.setAttribute('height', height * resolution);
13167 element.style.width = width + 'px';
13168 element.style.height = height + 'px';
13169 this.width = width;
13170 this.height = height;
13171 return this;
13172 },
13173
13174 invalidate: function(left, top, width, height){
13175 if (this._valid){
13176 this._valid = false;
13177 invalids.push(this);
13178 if (!renderTimer){
13179 if (window.mozRequestAnimationFrame){
13180 renderTimer = true;
13181 window.mozRequestAnimationFrame(renderInvalids);
13182 } else {
13183 renderTimer = setTimeout(renderInvalids, fps);
13184 }
13185 }
13186 }
13187 return this;
13188 },
13189
13190 hitTest: function(x, y){
13191 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
13192 var node = this.lastChild;
13193 while (node){
13194 var hit = node.hitTest(x, y);
13195 if (hit) return hit;
13196 node = node.previousSibling;
13197 }
13198 return null;
13199 },
13200
13201 render: function(){
13202 var node = this.firstChild, context = this.context;
13203 context.setTransform(resolution, 0, 0, resolution, 0, 0);
13204 context.clearRect(0, 0, this.width, this.height);
13205 while (node){
13206 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
13207 node = node.nextSibling;
13208 }
13209 this.refreshCursor();
13210 }
13211
13212});
13213
13214CanvasSurface.tagName = 'canvas';
13215
13216var surface = CanvasSurface;
13217
13218var path$2 = _class({
13219
13220 initialize: function(path){
13221 this.reset().push(path);
13222 },
13223
13224 /* parser */
13225
13226 push: function(){
13227 var p = Array.prototype.join.call(arguments, ' ')
13228 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
13229 if (!p) return this;
13230
13231 var last, cmd = p[0], i = 1;
13232 while (cmd){
13233 switch (cmd){
13234 case 'm': this.move(p[i++], p[i++]); break;
13235 case 'l': this.line(p[i++], p[i++]); break;
13236 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
13237 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
13238 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
13239 case 't': this.curve(p[i++], p[i++]); break;
13240 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;
13241 case 'h': this.line(p[i++], 0); break;
13242 case 'v': this.line(0, p[i++]); break;
13243
13244 case 'M': this.moveTo(p[i++], p[i++]); break;
13245 case 'L': this.lineTo(p[i++], p[i++]); break;
13246 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
13247 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
13248 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
13249 case 'T': this.curveTo(p[i++], p[i++]); break;
13250 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;
13251 case 'H': this.lineTo(p[i++], this.penY); break;
13252 case 'V': this.lineTo(this.penX, p[i++]); break;
13253
13254 case 'Z': case 'z': this.close(); break;
13255 default: cmd = last; i--; continue;
13256 }
13257
13258 last = cmd;
13259 if (last == 'm') last = 'l';
13260 else if (last == 'M') last = 'L';
13261 cmd = p[i++];
13262 }
13263 return this;
13264 },
13265
13266 /* utility methods */
13267
13268 reset: function(){
13269 this.penX = this.penY = 0;
13270 this.penDownX = this.penDownY = null;
13271 this._pivotX = this._pivotY = 0;
13272 this.onReset();
13273 return this;
13274 },
13275
13276 move: function(x,y){
13277 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
13278 return this;
13279 },
13280 moveTo: function(x,y){
13281 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13282 return this;
13283 },
13284
13285 line: function(x,y){
13286 return this.lineTo(this.penX + (+x), this.penY + (+y));
13287 },
13288 lineTo: function(x,y){
13289 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13290 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13291 return this;
13292 },
13293
13294 curve: function(c1x, c1y, c2x, c2y, ex, ey){
13295 var x = this.penX, y = this.penY;
13296 return this.curveTo(
13297 x + (+c1x), y + (+c1y),
13298 c2x == null ? null : x + (+c2x),
13299 c2y == null ? null : y + (+c2y),
13300 ex == null ? null : x + (+ex),
13301 ey == null ? null : y + (+ey)
13302 );
13303 },
13304 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
13305 var x = this.penX, y = this.penY;
13306 if (c2x == null){
13307 c2x = +c1x; c2y = +c1y;
13308 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
13309 }
13310 if (ex == null){
13311 this._pivotX = +c1x; this._pivotY = +c1y;
13312 ex = +c2x; ey = +c2y;
13313 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
13314 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
13315 } else {
13316 this._pivotX = +c2x; this._pivotY = +c2y;
13317 }
13318 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
13319 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
13320 return this;
13321 },
13322
13323 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
13324 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
13325 },
13326 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
13327 ry = Math.abs(+ry || +rx || (+y - this.penY));
13328 rx = Math.abs(+rx || (+x - this.penX));
13329
13330 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
13331
13332 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
13333
13334 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
13335 x -= tX; y -= tY;
13336
13337 // Ellipse Center
13338 var cx = cos * x / 2 + sin * y / 2,
13339 cy = -sin * x / 2 + cos * y / 2,
13340 rxry = rx * rx * ry * ry,
13341 rycx = ry * ry * cx * cx,
13342 rxcy = rx * rx * cy * cy,
13343 a = rxry - rxcy - rycx;
13344
13345 if (a < 0){
13346 a = Math.sqrt(1 - a / rxry);
13347 rx *= a; ry *= a;
13348 cx = x / 2; cy = y / 2;
13349 } else {
13350 a = Math.sqrt(a / (rxcy + rycx));
13351 if (large == clockwise) a = -a;
13352 var cxd = -a * cy * rx / ry,
13353 cyd = a * cx * ry / rx;
13354 cx = cos * cxd - sin * cyd + x / 2;
13355 cy = sin * cxd + cos * cyd + y / 2;
13356 }
13357
13358 // Rotation + Scale Transform
13359 var xx = cos / rx, yx = sin / rx,
13360 xy = -sin / ry, yy = cos / ry;
13361
13362 // Start and End Angle
13363 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
13364 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
13365
13366 cx += tX; cy += tY;
13367 x += tX; y += tY;
13368
13369 // Circular Arc
13370 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13371 this.onArc(
13372 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
13373 cx, cy, rx, ry, sa, ea, !clockwise, rotation
13374 );
13375 return this;
13376 },
13377
13378 counterArc: function(x, y, rx, ry, outer){
13379 return this.arc(x, y, rx, ry, outer, true);
13380 },
13381 counterArcTo: function(x, y, rx, ry, outer){
13382 return this.arcTo(x, y, rx, ry, outer, true);
13383 },
13384
13385 close: function(){
13386 if (this.penDownX != null){
13387 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
13388 this.penDownX = null;
13389 }
13390 return this;
13391 },
13392
13393 /* overridable handlers */
13394
13395 onReset: function(){
13396 },
13397
13398 onMove: function(sx, sy, ex, ey){
13399 },
13400
13401 onLine: function(sx, sy, ex, ey){
13402 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
13403 },
13404
13405 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
13406 var gx = ex - sx, gy = ey - sy,
13407 g = gx * gx + gy * gy,
13408 v1, v2, cx, cy, u;
13409
13410 cx = c1x - sx; cy = c1y - sy;
13411 u = cx * gx + cy * gy;
13412
13413 if (u > g){
13414 cx -= gx;
13415 cy -= gy;
13416 } else if (u > 0 && g != 0){
13417 cx -= u/g * gx;
13418 cy -= u/g * gy;
13419 }
13420
13421 v1 = cx * cx + cy * cy;
13422
13423 cx = c2x - sx; cy = c2y - sy;
13424 u = cx * gx + cy * gy;
13425
13426 if (u > g){
13427 cx -= gx;
13428 cy -= gy;
13429 } else if (u > 0 && g != 0){
13430 cx -= u/g * gx;
13431 cy -= u/g * gy;
13432 }
13433
13434 v2 = cx * cx + cy * cy;
13435
13436 if (v1 < 0.01 && v2 < 0.01){
13437 this.onLine(sx, sy, ex, ey);
13438 return;
13439 }
13440
13441 // Avoid infinite recursion
13442 if (isNaN(v1) || isNaN(v2)){
13443 throw new Error('Bad input');
13444 }
13445
13446 // Split curve
13447 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
13448 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
13449 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
13450 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
13451 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
13452 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
13453
13454 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
13455 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
13456 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
13457 },
13458
13459 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13460 // Inverse Rotation + Scale Transform
13461 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
13462 xx = cos * rx, yx = -sin * ry,
13463 xy = sin * rx, yy = cos * ry;
13464
13465 // Bezier Curve Approximation
13466 var arc = ea - sa;
13467 if (arc < 0 && !ccw) arc += Math.PI * 2;
13468 else if (arc > 0 && ccw) arc -= Math.PI * 2;
13469
13470 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
13471 step = arc / n,
13472 k = (4 / 3) * Math.tan(step / 4);
13473
13474 var x = Math.cos(sa), y = Math.sin(sa);
13475
13476 for (var i = 0; i < n; i++){
13477 var cp1x = x - k * y, cp1y = y + k * x;
13478
13479 sa += step;
13480 x = Math.cos(sa); y = Math.sin(sa);
13481
13482 var cp2x = x + k * y, cp2y = y - k * x;
13483
13484 this.onBezierCurve(
13485 sx, sy,
13486 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
13487 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
13488 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
13489 );
13490 }
13491 },
13492
13493 onClose: function(sx, sy, ex, ey){
13494 this.onLine(sx, sy, ex, ey);
13495 }
13496
13497});
13498
13499var CanvasPath = _class(path$2, {
13500
13501 initialize: function(path){
13502 this.reset();
13503 if (path instanceof CanvasPath){
13504 this.path = path.path.slice(0);
13505 } else if (path){
13506 if (path.applyToPath)
13507 path.applyToPath(this);
13508 else
13509 this.push(path);
13510 }
13511 },
13512
13513 onReset: function(){
13514 this.path = [];
13515 },
13516
13517 onMove: function(sx, sy, x, y){
13518 this.path.push(function(context){
13519 context.moveTo(x, y);
13520 });
13521 },
13522
13523 onLine: function(sx, sy, x, y){
13524 this.path.push(function(context){
13525 context.lineTo(x, y);
13526 });
13527 },
13528
13529 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
13530 this.path.push(function(context){
13531 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
13532 });
13533 },
13534
13535 _arcToBezier: path$2.prototype.onArc,
13536
13537 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13538 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
13539 this.path.push(function(context){
13540 context.arc(cx, cy, rx, sa, ea, ccw);
13541 });
13542 },
13543
13544 onClose: function(){
13545 this.path.push(function(context){
13546 context.closePath();
13547 });
13548 },
13549
13550 toCommands: function(){
13551 return this.path.slice(0);
13552 }
13553
13554});
13555
13556var path = CanvasPath;
13557
13558var colors = {
13559 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
13560 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
13561 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
13562 black: '#000000', silver: '#c0c0c0', gray: '#808080'
13563};
13564
13565var map = function(array, fn){
13566 var results = [];
13567 for (var i = 0, l = array.length; i < l; i++)
13568 results[i] = fn(array[i], i);
13569 return results;
13570};
13571
13572var Color = function(color, type){
13573
13574 if (color.isColor){
13575
13576 this.red = color.red;
13577 this.green = color.green;
13578 this.blue = color.blue;
13579 this.alpha = color.alpha;
13580
13581 } else {
13582
13583 var namedColor = colors[color];
13584 if (namedColor){
13585 color = namedColor;
13586 type = 'hex';
13587 }
13588
13589 switch (typeof color){
13590 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
13591 case 'object': type = type || 'rgb'; color = color.toString(); break;
13592 case 'number': type = 'hex'; color = color.toString(16); break;
13593 }
13594
13595 color = Color['parse' + type.toUpperCase()](color);
13596 this.red = color[0];
13597 this.green = color[1];
13598 this.blue = color[2];
13599 this.alpha = color[3];
13600 }
13601
13602 this.isColor = true;
13603
13604};
13605
13606var limit = function(number, min, max){
13607 return Math.min(max, Math.max(min, number));
13608};
13609
13610var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
13611var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
13612
13613Color.parseRGB = function(color){
13614 return map(color.match(listMatch).slice(1), function(bit, i){
13615 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
13616 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13617 });
13618};
13619
13620Color.parseHEX = function(color){
13621 if (color.length == 1) color = color + color + color;
13622 return map(color.match(hexMatch).slice(1), function(bit, i){
13623 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
13624 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
13625 });
13626};
13627
13628Color.parseHSB = function(color){
13629 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13630 if (bit) bit = parseFloat(bit);
13631 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13632 else if (i < 3) return limit(Math.round(bit), 0, 100);
13633 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13634 });
13635
13636 var a = hsb[3];
13637 var br = Math.round(hsb[2] / 100 * 255);
13638 if (hsb[1] == 0) return [br, br, br, a];
13639
13640 var hue = hsb[0];
13641 var f = hue % 60;
13642 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
13643 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
13644 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
13645
13646 switch (Math.floor(hue / 60)){
13647 case 0: return [br, t, p, a];
13648 case 1: return [q, br, p, a];
13649 case 2: return [p, br, t, a];
13650 case 3: return [p, q, br, a];
13651 case 4: return [t, p, br, a];
13652 default: return [br, p, q, a];
13653 }
13654};
13655
13656Color.parseHSL = function(color){
13657 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13658 if (bit) bit = parseFloat(bit);
13659 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13660 else if (i < 3) return limit(Math.round(bit), 0, 100);
13661 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13662 });
13663
13664 var h = hsb[0] / 60;
13665 var s = hsb[1] / 100;
13666 var l = hsb[2] / 100;
13667 var a = hsb[3];
13668
13669 var c = (1 - Math.abs(2 * l - 1)) * s;
13670 var x = c * (1 - Math.abs(h % 2 - 1));
13671 var m = l - c / 2;
13672
13673 var p = Math.round((c + m) * 255);
13674 var q = Math.round((x + m) * 255);
13675 var t = Math.round((m) * 255);
13676
13677 switch (Math.floor(h)){
13678 case 0: return [p, q, t, a];
13679 case 1: return [q, p, t, a];
13680 case 2: return [t, p, q, a];
13681 case 3: return [t, q, p, a];
13682 case 4: return [q, t, p, a];
13683 default: return [p, t, q, a];
13684 }
13685};
13686
13687var toString = function(type, array){
13688 if (array[3] != 1) type += 'a';
13689 else array.pop();
13690 return type + '(' + array.join(', ') + ')';
13691};
13692
13693Color.prototype = {
13694
13695 toHSB: function(array){
13696 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13697
13698 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13699 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
13700 if (saturation){
13701 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13702 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13703 if ((hue /= 6) < 0) hue++;
13704 }
13705
13706 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
13707
13708 return (array) ? hsb : toString('hsb', hsb);
13709 },
13710
13711 toHSL: function(array){
13712 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13713
13714 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13715 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
13716 if (saturation){
13717 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13718 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13719 if ((hue /= 6) < 0) hue++;
13720 }
13721
13722 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
13723
13724 return (array) ? hsl : toString('hsl', hsl);
13725 },
13726
13727 toHEX: function(array){
13728
13729 var a = this.alpha;
13730 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
13731
13732 var hex = map([this.red, this.green, this.blue], function(bit){
13733 bit = bit.toString(16);
13734 return (bit.length == 1) ? '0' + bit : bit;
13735 });
13736
13737 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
13738 },
13739
13740 toRGB: function(array){
13741 var rgb = [this.red, this.green, this.blue, this.alpha];
13742 return (array) ? rgb : toString('rgb', rgb);
13743 }
13744
13745};
13746
13747Color.prototype.toString = Color.prototype.toRGB;
13748
13749Color.hex = function(hex){
13750 return new Color(hex, 'hex');
13751};
13752
13753if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
13754
13755Color.hsb = function(h, s, b, a){
13756 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
13757};
13758
13759if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
13760
13761Color.hsl = function(h, s, l, a){
13762 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
13763};
13764
13765if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
13766
13767Color.rgb = function(r, g, b, a){
13768 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
13769};
13770
13771if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
13772
13773Color.detach = function(color){
13774 color = new Color(color);
13775 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
13776};
13777
13778var color = Color;
13779
13780var dummy = _class({
13781
13782 // placement
13783
13784 _resetPlacement: function(){
13785 var container = this.parentNode;
13786 if (container){
13787 var previous = this.previousSibling, next = this.nextSibling;
13788 if (previous){
13789 previous.nextSibling = next;
13790 } else {
13791 container.firstChild = next;
13792 }
13793 if (next){
13794 next.previousSibling = previous;
13795 } else {
13796 container.lastChild = this.previousSibling;
13797 }
13798 }
13799 this.previousSibling = null;
13800 this.nextSibling = null;
13801 this.parentNode = null;
13802 return this;
13803 },
13804
13805 inject: function(container){
13806 this._resetPlacement();
13807 var last = container.lastChild;
13808 if (last){
13809 last.nextSibling = this;
13810 this.previousSibling = last;
13811 } else {
13812 container.firstChild = this;
13813 }
13814 container.lastChild = this;
13815 this.parentNode = container;
13816 this._place();
13817 return this;
13818 },
13819
13820 injectBefore: function(sibling){
13821 this._resetPlacement();
13822 var container = sibling.parentNode;
13823 if (!container) return this;
13824 var previous = sibling.previousSibling;
13825 if (previous){
13826 previous.nextSibling = this;
13827 this.previousSibling = previous;
13828 } else {
13829 container.firstChild = this;
13830 }
13831 sibling.previousSibling = this;
13832 this.nextSibling = sibling;
13833 this.parentNode = container;
13834 this._place();
13835 return this;
13836 },
13837
13838 eject: function(){
13839 this._resetPlacement();
13840 this._place();
13841 return this;
13842 },
13843
13844 _place: function(){},
13845
13846 // events
13847
13848 dispatch: function(event){
13849 var events = this._events,
13850 listeners = events && events[event.type];
13851 if (listeners){
13852 listeners = listeners.slice(0);
13853 for (var i = 0, l = listeners.length; i < l; i++){
13854 var fn = listeners[i], result;
13855 if (typeof fn == 'function')
13856 result = fn.call(this, event);
13857 else
13858 result = fn.handleEvent(event);
13859 if (result === false) event.preventDefault();
13860 }
13861 }
13862 if (this.parentNode && this.parentNode.dispatch){
13863 this.parentNode.dispatch(event);
13864 }
13865 },
13866
13867 subscribe: function(type, fn, bind){
13868 if (typeof type != 'string'){ // listen type / fn with object
13869 var subscriptions = [];
13870 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
13871 return function(){ // unsubscribe
13872 for (var i = 0, l = subscriptions.length; i < l; i++)
13873 subscriptions[i]();
13874 return this;
13875 };
13876 } else { // listen to one
13877 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
13878 events = this._events || (this._events = {}),
13879 listeners = events[type] || (events[type] = []);
13880 listeners.push(bound);
13881 return function(){
13882 // unsubscribe
13883 for (var i = 0, l = listeners.length; i < l; i++){
13884 if (listeners[i] === bound){
13885 listeners.splice(i, 1);
13886 break;
13887 }
13888 }
13889 }
13890 }
13891 }
13892
13893});
13894
13895var CanvasNode = _class(transform, dummy, {
13896
13897 invalidate: function(){
13898 if (this.parentNode) this.parentNode.invalidate();
13899 if (this._layer) this._layerCache = null;
13900 return this;
13901 },
13902
13903 _place: function(){
13904 this.invalidate();
13905 },
13906
13907 _transform: function(){
13908 this.invalidate();
13909 },
13910
13911 blend: function(opacity){
13912 if (opacity >= 1 && this._layer) this._layer = null;
13913 this._opacity = opacity;
13914 if (this.parentNode) this.parentNode.invalidate();
13915 return this;
13916 },
13917
13918 // visibility
13919
13920 hide: function(){
13921 this._invisible = true;
13922 if (this.parentNode) this.parentNode.invalidate();
13923 return this;
13924 },
13925
13926 show: function(){
13927 this._invisible = false;
13928 if (this.parentNode) this.parentNode.invalidate();
13929 return this;
13930 },
13931
13932 // interaction
13933
13934 indicate: function(cursor, tooltip){
13935 this._cursor = cursor;
13936 this._tooltip = tooltip;
13937 return this.invalidate();
13938 },
13939
13940 hitTest: function(x, y){
13941 if (this._invisible) return null;
13942 var point = this.inversePoint(x, y);
13943 if (!point) return null;
13944 return this.localHitTest(point.x, point.y);
13945 },
13946
13947 // rendering
13948
13949 renderTo: function(context, xx, yx, xy, yy, x, y){
13950 var opacity = this._opacity;
13951 if (opacity == null || opacity >= 1){
13952 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
13953 }
13954
13955 // Render to a compositing layer and cache it
13956
13957 var layer = this._layer, canvas, isDirty = true,
13958 w = context.canvas.width, h = context.canvas.height;
13959 if (layer){
13960 layer.setTransform(1, 0, 0, 1, 0, 0);
13961 canvas = layer.canvas;
13962 if (canvas.width < w || canvas.height < h){
13963 canvas.width = w;
13964 canvas.height = h;
13965 } else {
13966 var c = this._layerCache;
13967 if (c && c.xx === xx && c.yx === yx && c.xy === xy
13968 && c.yy === yy && c.x === x && c.y === y){
13969 isDirty = false;
13970 } else {
13971 layer.clearRect(0, 0, w, h);
13972 }
13973 }
13974 } else {
13975 canvas = document.createElement('canvas');
13976 canvas.width = w;
13977 canvas.height = h;
13978 this._layer = layer = canvas.getContext('2d');
13979 }
13980
13981 if (isDirty){
13982 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
13983 this._layerCache = {
13984 xx: xx,
13985 yx: yx,
13986 xy: xy,
13987 yy: yy,
13988 x: x,
13989 y: y
13990 };
13991 }
13992
13993 context.globalAlpha = opacity;
13994 context.setTransform(1, 0, 0, 1, 0, 0);
13995 context.drawImage(
13996 canvas,
13997 0, 0, w, h,
13998 0, 0, w, h
13999 );
14000 context.globalAlpha = 1;
14001 }
14002
14003});
14004
14005var node = CanvasNode;
14006
14007var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas');
14008var genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
14009
14010function recolorImage(img, color1, color2){
14011 // TODO: Fix this experimental implementation
14012 color1 = color.detach(color1);
14013 color2 = color.detach(color2);
14014 var canvas = document.createElement('canvas'),
14015 context = canvas.getContext('2d');
14016 canvas.width = img.width;
14017 canvas.height = img.height;
14018 context.fillStyle = color2[0];
14019 context.fillRect(0, 0, img.width, img.height);
14020 context.globalCompositeOperation = 'lighter';
14021 context.drawImage(img, 0, 0);
14022 return canvas;
14023}
14024
14025var Base = _class(node, {
14026
14027 initialize: function(){
14028 this._fill = null;
14029 this._pendingFill = null;
14030 this._fillTransform = null;
14031 this._stroke = null;
14032 this._strokeCap = null;
14033 this._strokeDash = null;
14034 this._strokeJoin = null;
14035 this._strokeWidth = null;
14036 },
14037
14038 /* styles */
14039
14040 _addColors: function(gradient, stops){
14041 // Enumerate stops, assumes offsets are enumerated in order
14042 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
14043 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
14044 gradient.addColorStop(i / l, new color(stops[i]).toString());
14045 else for (var offset in stops)
14046 gradient.addColorStop(offset, new color(stops[offset]).toString());
14047 return gradient;
14048 },
14049
14050
14051 fill: function(color$$1){
14052 if (arguments.length > 1) return this.fillLinear(arguments);
14053 if (this._pendingFill) this._pendingFill();
14054 this._fill = color$$1 ? new color(color$$1).toString() : null;
14055 return this.invalidate();
14056 },
14057
14058 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
14059 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
14060 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
14061 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
14062 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
14063 if (centerX == null) centerX = focusX;
14064 if (centerY == null) centerY = focusY;
14065
14066 centerX += centerX - focusX;
14067 centerY += centerY - focusY;
14068
14069 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
14070 var ys = radiusY / radiusX;
14071
14072 if (this._pendingFill) this._pendingFill();
14073
14074 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
14075
14076 // Double fill radius to simulate repeating gradient
14077 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
14078 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
14079 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
14080 } else for (var offset in stops){
14081 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
14082 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
14083 }
14084
14085 this._fill = gradient;
14086 this._fillTransform = new transform(1, 0, 0, ys);
14087 return this.invalidate();
14088 },
14089
14090 fillLinear: function(stops, x1, y1, x2, y2){
14091 if (arguments.length < 5){
14092 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
14093
14094 var x = Math.cos(angle), y = -Math.sin(angle),
14095 l = (Math.abs(x) + Math.abs(y)) / 2,
14096 w = this.width || 1, h = this.height || 1;
14097
14098 x *= l; y *= l;
14099
14100 x1 = 0.5 - x;
14101 x2 = 0.5 + x;
14102 y1 = 0.5 - y;
14103 y2 = 0.5 + y;
14104 this._fillTransform = new transform(w, 0, 0, h);
14105 } else {
14106 this._fillTransform = null;
14107 }
14108 if (this._pendingFill) this._pendingFill();
14109 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
14110 this._addColors(gradient, stops);
14111 this._fill = gradient;
14112 return this.invalidate();
14113 },
14114
14115 fillImage: function(url, width, height, left, top, color1, color2){
14116 if (this._pendingFill) this._pendingFill();
14117 var img = url;
14118 if (!(img instanceof Image)){
14119 img = new Image();
14120 img.src = url;
14121 }
14122 if (img.width && img.height){
14123 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
14124 }
14125
14126 // Not yet loaded
14127 this._fill = null;
14128 var self = this,
14129 callback = function(){
14130 cancel();
14131 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
14132 },
14133 cancel = function(){
14134 img.removeEventListener('load', callback, false);
14135 self._pendingFill = null;
14136 };
14137 this._pendingFill = cancel;
14138 img.addEventListener('load', callback, false);
14139 return this;
14140 },
14141
14142 _fillImage: function(img, width, height, left, top, color1, color2){
14143 var w = width ? width / img.width : 1,
14144 h = height ? height / img.height : 1;
14145 if (color1 != null) img = recolorImage(img, color1, color2);
14146 this._fill = genericContext.createPattern(img, 'repeat');
14147 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
14148 return this.invalidate();
14149 },
14150
14151 stroke: function(color$$1, width, cap, join, dash){
14152 this._stroke = color$$1 ? new color(color$$1).toString() : null;
14153 this._strokeWidth = (width != null) ? width : 1;
14154 this._strokeCap = (cap != null) ? cap : 'round';
14155 this._strokeJoin = (join != null) ? join : 'round';
14156 this._strokeDash = dash;
14157 return this.invalidate();
14158 },
14159
14160 // Rendering
14161
14162 element_renderTo: node.prototype.renderTo,
14163
14164 renderTo: function(context, xx, yx, xy, yy, x, y){
14165 var opacity = this._opacity;
14166 if (opacity == null || opacity >= 1){
14167 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
14168 }
14169 if (this._fill && this._stroke){
14170 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
14171 }
14172 context.globalAlpha = opacity;
14173 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
14174 context.globalAlpha = 1;
14175 return r;
14176 },
14177
14178 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
14179 context.setTransform(xx, yx, xy, yy, x, y);
14180 this.renderShapeTo(context);
14181 }
14182
14183});
14184
14185Base._genericContext = genericContext;
14186
14187var base = Base;
14188
14189var shape = _class(base, {
14190
14191 base_initialize: base.prototype.initialize,
14192
14193 initialize: function(path$$1, width, height){
14194 this.base_initialize();
14195 this.width = width;
14196 this.height = height;
14197 if (path$$1 != null) this.draw(path$$1);
14198 },
14199
14200 draw: function(path$$1, width, height){
14201 if (!(path$$1 instanceof path)) path$$1 = new path(path$$1);
14202 this.path = path$$1;
14203 this._commands = path$$1.toCommands();
14204 if (width != null) this.width = width;
14205 if (height != null) this.height = height;
14206 return this.invalidate();
14207 },
14208
14209 localHitTest: function(x, y){
14210 if (!this._fill) return null;
14211 if (this.width == null || this.height == null){
14212 var context = base._genericContext, commands = this._commands;
14213 if (!commands) return null;
14214 context.beginPath();
14215 for (var i = 0, l = commands.length; i < l; i++)
14216 commands[i](context);
14217 return context.isPointInPath(x, y) ? this : null;
14218 }
14219 if (x > 0 && y > 0 && x < this.width && y < this.height){
14220 return this;
14221 }
14222 return null;
14223 },
14224
14225 renderShapeTo: function(context){
14226 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
14227 return null;
14228 }
14229 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
14230 var commands = this._commands,
14231 fill = this._fill,
14232 stroke = this._stroke,
14233 dash = this._strokeDash;
14234
14235 context.beginPath();
14236
14237 if (dash) {
14238 if (context.setLineDash) {
14239 context.setLineDash(dash);
14240 } else {
14241 // TODO: Remove when FF supports setLineDash.
14242 context.mozDash = dash;
14243 }
14244 // TODO: Create fallback to other browsers.
14245 } else {
14246 if (context.setLineDash) {
14247 context.setLineDash([]);
14248 } else {
14249 context.mozDash = null;
14250 }
14251 }
14252
14253 for (var i = 0, l = commands.length; i < l; i++)
14254 commands[i](context);
14255
14256 if (fill){
14257 var m = this._fillTransform;
14258 if (m){
14259 context.save(); // TODO: Optimize away this by restoring the transform before stroking
14260 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
14261 context.fillStyle = fill;
14262 context.fill();
14263 context.restore();
14264 } else {
14265 context.fillStyle = fill;
14266 context.fill();
14267 }
14268 }
14269 if (stroke){
14270 context.strokeStyle = stroke;
14271 context.lineWidth = this._strokeWidth;
14272 context.lineCap = this._strokeCap;
14273 context.lineJoin = this._strokeJoin;
14274 context.stroke();
14275 }
14276 }
14277
14278});
14279
14280var group = _class(node, container, {
14281
14282 initialize: function(width, height){
14283 this.width = width;
14284 this.height = height;
14285 },
14286
14287 localHitTest: function(x, y){
14288 var node$$2 = this.lastChild;
14289 while (node$$2){
14290 var hit = node$$2.hitTest(x, y);
14291 if (hit) return hit;
14292 node$$2 = node$$2.previousSibling;
14293 }
14294 return null;
14295 },
14296
14297 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
14298 if (this._invisible) return;
14299
14300 x = xx * this.x + xy * this.y + x;
14301 y = yx * this.x + yy * this.y + y;
14302
14303 var t = xx;
14304 xx = t * this.xx + xy * this.yx;
14305 xy = t * this.xy + xy * this.yy;
14306 t = yx;
14307 yx = t * this.xx + yy * this.yx;
14308 yy = t * this.xy + yy * this.yy;
14309
14310 var node$$2 = this.firstChild;
14311 while (node$$2){
14312 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14313 node$$2 = node$$2.nextSibling;
14314 }
14315 }
14316
14317});
14318
14319var clippingrectangle = _class(node, container, {
14320
14321 initialize: function(width, height){
14322 this.width = width;
14323 this.height = height;
14324 },
14325
14326 localHitTest: function(x, y) {
14327 var node$$2 = this.lastChild;
14328 while (node$$2){
14329 var hit = node$$2.hitTest(x, y);
14330 if (hit) return hit;
14331 node$$2 = node$$2.previousSibling;
14332 }
14333 return null;
14334 },
14335
14336 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
14337 context.setTransform(xx, yx, xy, yy, x, y);
14338 context.save();
14339 // Need beginPath to fix Firefox bug. See 3354054.
14340 context.beginPath();
14341 context.rect(this.x, this.y, this.width, this.height);
14342 context.clip();
14343
14344 var node$$2 = this.firstChild;
14345 while(node$$2) {
14346 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14347 node$$2 = node$$2.nextSibling;
14348 }
14349 context.restore();
14350 }
14351});
14352
14353var fontAnchors = { middle: 'center' };
14354
14355var text = _class(base, {
14356
14357 base_initialize: base.prototype.initialize,
14358
14359 initialize: function(text, font, alignment, path){
14360 this.base_initialize();
14361 this.draw.apply(this, arguments);
14362 },
14363
14364 draw: function(text, font, alignment, path){
14365 var em;
14366 if (typeof font == 'string'){
14367 em = Number(/(\d+)/.exec(font)[0]);
14368 } else if (font){
14369 em = parseFloat(font.fontSize || font['font-size'] || '12');
14370 font = (font.fontStyle || font['font-style'] || '') + ' ' +
14371 (font.fontVariant || font['font-variant'] || '') + ' ' +
14372 (font.fontWeight || font['font-weight'] || '') + ' ' +
14373 em + 'px ' +
14374 (font.fontFamily || font['font-family'] || 'Arial');
14375 } else {
14376 font = this._font;
14377 }
14378
14379 var lines = text && text.split(/\r?\n/);
14380 this._font = font;
14381 this._fontSize = em;
14382 this._text = lines;
14383 this._alignment = fontAnchors[alignment] || alignment || 'left';
14384
14385 var context = base._genericContext;
14386
14387 context.font = this._font;
14388 context.textAlign = this._alignment;
14389 context.textBaseline = 'middle';
14390
14391 lines = this._text;
14392 var l = lines.length, width = 0;
14393 for (var i = 0; i < l; i++){
14394 var w = context.measureText(lines[i]).width;
14395 if (w > width) width = w;
14396 }
14397 this.width = width;
14398 this.height = l ? l * 1.1 * em : 0;
14399 return this.invalidate();
14400 },
14401
14402 // Interaction
14403
14404 localHitTest: function(x, y){
14405 if (!this._fill) return null;
14406 if (x > 0 && y > 0 && x < this.width && y < this.height){
14407 return this;
14408 }
14409 return null;
14410 },
14411
14412 // Rendering
14413
14414 renderShapeTo: function(context){
14415 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
14416 return null;
14417 }
14418 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
14419 var fill = this._fill,
14420 stroke = this._stroke,
14421 text = this._text,
14422 dash = this._strokeDash;
14423
14424 context.font = this._font;
14425 context.textAlign = this._alignment;
14426 context.textBaseline = 'middle';
14427
14428 var em = this._fontSize,
14429 y = em / 2,
14430 lineHeight = 1.1 * em,
14431 lines = text,
14432 l = lines.length;
14433
14434 if (fill){
14435 context.fillStyle = fill;
14436 for (var i = 0; i < l; i++)
14437 context.fillText(lines[i], 0, y + i * lineHeight);
14438 }
14439 if (stroke){
14440 if (dash) {
14441 if (context.setLineDash) {
14442 context.setLineDash(dash);
14443 } else {
14444 // TODO: Remove when FF supports setLineDash.
14445 context.mozDash = dash;
14446 }
14447 // TODO: Create fallback to other browsers.
14448 } else {
14449 if (context.setLineDash) {
14450 context.setLineDash([]);
14451 } else {
14452 context.mozDash = null;
14453 }
14454 }
14455
14456 context.strokeStyle = stroke;
14457 context.lineWidth = this._strokeWidth;
14458 context.lineCap = this._strokeCap;
14459 context.lineJoin = this._strokeJoin;
14460 for (i = 0; i < l; i++)
14461 context.strokeText(lines[i], 0, y + i * lineHeight);
14462 }
14463 }
14464
14465});
14466
14467var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
14468
14469var styleSheet;
14470var styledTags = {};
14471var styleTag = function(tag){
14472 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
14473};
14474
14475var init = function(document){
14476
14477 var namespaces;
14478 try { // IE9 workaround: sometimes it throws here
14479 namespaces = document.namespaces;
14480 } catch (e) {
14481 }
14482 if (!namespaces) return false;
14483
14484 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
14485 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
14486
14487 styleSheet = document.createStyleSheet();
14488 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
14489/* styleTag('skew');
14490 styleTag('fill');
14491 styleTag('stroke');
14492 styleTag('path');
14493 styleTag('textpath');
14494 styleTag('group');*/
14495
14496 styleTag('vml');
14497
14498 return true;
14499
14500};
14501
14502var createElement = function(tag){
14503 if (!(tag in styledTags)) styleTag(tag);
14504 return document.createElement('av:' + tag);
14505};
14506
14507var dom = {
14508 init: init,
14509 createElement: createElement
14510};
14511
14512var precision = 100;
14513
14514var VMLSurface = _class(native_1, container, {
14515
14516 initialize: function VMLSurface(width, height, existingElement){
14517 this.element = existingElement || document.createElement('vml');
14518 this.containerElement = dom.createElement('group');
14519 this.element.appendChild(this.containerElement);
14520 if (width != null && height != null) this.resize(width, height);
14521 },
14522
14523 resize: function(width, height){
14524 this.width = width;
14525 this.height = height;
14526
14527 var style = this.element.style;
14528 style.pixelWidth = width;
14529 style.pixelHeight = height;
14530
14531 style = this.containerElement.style;
14532 style.width = width;
14533 style.height = height;
14534
14535 var halfPixel = (0.5 * precision);
14536
14537 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
14538 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
14539
14540 return this;
14541 }
14542
14543});
14544
14545VMLSurface.tagName = 'av:vml';
14546
14547var surface$2 = VMLSurface;
14548
14549var precision$1 = 100;
14550
14551var round = Math.round;
14552
14553var VMLPath = _class(path$2, {
14554
14555 initialize: function(path){
14556 this.reset();
14557 if (path instanceof VMLPath){
14558 this.path = [Array.prototype.join.call(path.path, ' ')];
14559 } else if (path){
14560 if (path.applyToPath)
14561 path.applyToPath(this);
14562 else
14563 this.push(path);
14564 }
14565 },
14566
14567 onReset: function(){
14568 this.path = [];
14569 },
14570
14571 onMove: function(sx, sy, x, y){
14572 this.path.push('m', round(x * precision$1), round(y * precision$1));
14573 },
14574
14575 onLine: function(sx, sy, x, y){
14576 this.path.push('l', round(x * precision$1), round(y * precision$1));
14577 },
14578
14579 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
14580 this.path.push('c',
14581 round(p1x * precision$1), round(p1y * precision$1),
14582 round(p2x * precision$1), round(p2y * precision$1),
14583 round(x * precision$1), round(y * precision$1)
14584 );
14585 },
14586
14587 _arcToBezier: path$2.prototype.onArc,
14588
14589 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
14590 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
14591 cx *= precision$1;
14592 cy *= precision$1;
14593 rx *= precision$1;
14594 this.path.push(ccw ? 'at' : 'wa',
14595 round(cx - rx), round(cy - rx),
14596 round(cx + rx), round(cy + rx),
14597 round(sx * precision$1), round(sy * precision$1),
14598 round(ex * precision$1), round(ey * precision$1)
14599 );
14600 },
14601
14602 onClose: function(){
14603 this.path.push('x');
14604 },
14605
14606 toVML: function(){
14607 return this.path.join(' ');
14608 }
14609
14610});
14611
14612VMLPath.prototype.toString = VMLPath.prototype.toVML;
14613
14614var path$4 = VMLPath;
14615
14616var shadow = _class(dummy, native_1, {
14617
14618 dummy_inject: dummy.prototype.inject,
14619 dummy_injectBefore: dummy.prototype.injectBefore,
14620 dummy_eject: dummy.prototype.eject,
14621 native_inject: native_1.prototype.inject,
14622 native_injectBefore: native_1.prototype.injectBefore,
14623 native_eject: native_1.prototype.eject,
14624
14625 inject: function(container){
14626 this.dummy_inject(container);
14627 this.native_inject(container);
14628 return this;
14629 },
14630
14631 injectBefore: function(sibling){
14632 this.dummy_injectBefore(sibling);
14633 this.native_injectBefore(sibling);
14634 return this;
14635 },
14636
14637 eject: function(){
14638 this.dummy_eject();
14639 this.native_eject();
14640 return this;
14641 }
14642
14643});
14644
14645var node$2 = _class(shadow, transform, {
14646
14647 initialize: function(tag){
14648 //this.uid = uniqueID();
14649 var element = this.element = dom.createElement(tag);
14650 //element.setAttribute('id', 'e' + this.uid);
14651 },
14652
14653 _place: function(){
14654 if (this.parentNode){
14655 this._transform();
14656 }
14657 },
14658
14659 // visibility
14660
14661 hide: function(){
14662 this.element.style.display = 'none';
14663 return this;
14664 },
14665
14666 show: function(){
14667 this.element.style.display = '';
14668 return this;
14669 },
14670
14671 // interaction
14672
14673 indicate: function(cursor, tooltip){
14674 if (cursor) this.element.style.cursor = cursor;
14675 if (tooltip) this.element.title = tooltip;
14676 return this;
14677 }
14678
14679});
14680
14681var precision$3 = 100;
14682
14683var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
14684
14685var base$2 = _class(node$2, {
14686
14687 element_initialize: node$2.prototype.initialize,
14688
14689 initialize: function(tag){
14690 this.element_initialize(tag);
14691 var element = this.element;
14692
14693 var skew = this.skewElement = dom.createElement('skew');
14694 skew.on = true;
14695 element.appendChild(skew);
14696
14697 var fill = this.fillElement = dom.createElement('fill');
14698 fill.on = false;
14699 element.appendChild(fill);
14700
14701 var stroke = this.strokeElement = dom.createElement('stroke');
14702 stroke.on = false;
14703 element.appendChild(stroke);
14704 },
14705
14706 /* transform */
14707
14708 _transform: function(){
14709 var container = this.parentNode;
14710
14711 // Active Transformation Matrix
14712 var m = container ? new transform(container._activeTransform).transform(this) : this;
14713
14714 // Box in shape user space
14715
14716 var box = this._boxCoords || this._size || defaultBox;
14717
14718 var originX = box.left || 0,
14719 originY = box.top || 0,
14720 width = box.width || 1,
14721 height = box.height || 1;
14722
14723 // Flipped
14724 var flip = m.yx / m.xx > m.yy / m.xy;
14725 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
14726 flip = flip ? -1 : 1;
14727
14728 m = new transform().scale(flip, 1).transform(m);
14729
14730 // Rotation is approximated based on the transform
14731 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
14732
14733 // Reverse the rotation, leaving the final transform in box space
14734 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
14735
14736 var transform$$2 = new transform(
14737 (m.xx * cos - m.xy * sin),
14738 (m.yx * cos - m.yy * sin) * flip,
14739 (m.xy * cos + m.xx * sin) * flip,
14740 (m.yy * cos + m.yx * sin)
14741 );
14742
14743 var rotationTransform = new transform().rotate(rotation, 0, 0);
14744
14745 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
14746
14747 // Scale box after reversing rotation
14748 width *= Math.abs(shapeToBox.xx);
14749 height *= Math.abs(shapeToBox.yy);
14750
14751 // Place box
14752 var left = m.x, top = m.y;
14753
14754 // Compensate for offset by center origin rotation
14755 var vx = -width / 2, vy = -height / 2;
14756 var point = rotationTransform.point(vx, vy);
14757 left -= point.x - vx;
14758 top -= point.y - vy;
14759
14760 // Adjust box position based on offset
14761 var rsm = new transform(m).moveTo(0,0);
14762 point = rsm.point(originX, originY);
14763 left += point.x;
14764 top += point.y;
14765
14766 if (flip < 0) left = -left - width;
14767
14768 // Place transformation origin
14769 var point0 = rsm.point(-originX, -originY);
14770 var point1 = rotationTransform.point(width, height);
14771 var point2 = rotationTransform.point(width, 0);
14772 var point3 = rotationTransform.point(0, height);
14773
14774 var minX = Math.min(0, point1.x, point2.x, point3.x),
14775 maxX = Math.max(0, point1.x, point2.x, point3.x),
14776 minY = Math.min(0, point1.y, point2.y, point3.y),
14777 maxY = Math.max(0, point1.y, point2.y, point3.y);
14778
14779 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
14780 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
14781
14782 // Adjust the origin
14783 point = shapeToBox.point(originX, originY);
14784 originX = point.x;
14785 originY = point.y;
14786
14787 // Scale stroke
14788 var strokeWidth = this._strokeWidth;
14789 if (strokeWidth){
14790 // Scale is the hypothenus between the two vectors
14791 // TODO: Use area calculation instead
14792 var vx = m.xx + m.xy, vy = m.yy + m.yx;
14793 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
14794 }
14795
14796 // convert to multiplied precision space
14797 originX *= precision$3;
14798 originY *= precision$3;
14799 left *= precision$3;
14800 top *= precision$3;
14801 width *= precision$3;
14802 height *= precision$3;
14803
14804 // Set box
14805 var element = this.element;
14806 element.coordorigin = originX + ',' + originY;
14807 element.coordsize = width + ',' + height;
14808 element.style.left = left + 'px';
14809 element.style.top = top + 'px';
14810 element.style.width = width;
14811 element.style.height = height;
14812 element.style.rotation = rotation.toFixed(8);
14813 element.style.flip = flip < 0 ? 'x' : '';
14814
14815 // Set transform
14816 var skew = this.skewElement;
14817 skew.matrix = [transform$$2.xx.toFixed(4), transform$$2.xy.toFixed(4), transform$$2.yx.toFixed(4), transform$$2.yy.toFixed(4), 0, 0];
14818 skew.origin = transformOriginX + ',' + transformOriginY;
14819
14820 // Set stroke
14821 this.strokeElement.weight = strokeWidth + 'px';
14822 },
14823
14824 /* styles */
14825
14826 _createGradient: function(style, stops){
14827 var fill = this.fillElement;
14828
14829 // Temporarily eject the fill from the DOM
14830 this.element.removeChild(fill);
14831
14832 fill.type = style;
14833 fill.method = 'none';
14834 fill.rotate = true;
14835
14836 var colors = [], color1, color2;
14837
14838 var addColor = function(offset, color$$2){
14839 color$$2 = color.detach(color$$2);
14840 if (color1 == null) color1 = color2 = color$$2;
14841 else color2 = color$$2;
14842 colors.push(offset + ' ' + color$$2[0]);
14843 };
14844
14845 // Enumerate stops, assumes offsets are enumerated in order
14846 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
14847 else for (var offset in stops) addColor(offset, stops[offset]);
14848
14849 fill.color = color1[0];
14850 fill.color2 = color2[0];
14851
14852 //if (fill.colors) fill.colors.value = colors; else
14853 fill.colors = colors;
14854
14855 // Opacity order gets flipped when color stops are specified
14856 fill.opacity = color2[1];
14857 fill['ao:opacity2'] = color1[1];
14858
14859 fill.on = true;
14860 this.element.appendChild(fill);
14861 return fill;
14862 },
14863
14864 _setColor: function(type, color$$2){
14865 var element = type == 'fill' ? this.fillElement : this.strokeElement;
14866 if (color$$2 == null){
14867 element.on = false;
14868 } else {
14869 color$$2 = color.detach(color$$2);
14870 element.color = color$$2[0];
14871 element.opacity = color$$2[1];
14872 element.on = true;
14873 }
14874 },
14875
14876 fill: function(color$$2){
14877 if (arguments.length > 1){
14878 this.fillLinear(arguments);
14879 } else {
14880 this._boxCoords = defaultBox;
14881 var fill = this.fillElement;
14882 fill.type = 'solid';
14883 fill.color2 = '';
14884 fill['ao:opacity2'] = '';
14885 if (fill.colors) fill.colors.value = '';
14886 this._setColor('fill', color$$2);
14887 }
14888 return this;
14889 },
14890
14891 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
14892 var fill = this._createGradient('gradientradial', stops);
14893 if (focusX == null) focusX = this.left + this.width * 0.5;
14894 if (focusY == null) focusY = this.top + this.height * 0.5;
14895 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
14896 if (radiusX == null) radiusX = this.width * 0.5;
14897 if (centerX == null) centerX = focusX;
14898 if (centerY == null) centerY = focusY;
14899
14900 centerX += centerX - focusX;
14901 centerY += centerY - focusY;
14902
14903 var box = this._boxCoords = {
14904 left: centerX - radiusX * 2,
14905 top: centerY - radiusY * 2,
14906 width: radiusX * 4,
14907 height: radiusY * 4
14908 };
14909 focusX -= box.left;
14910 focusY -= box.top;
14911 focusX /= box.width;
14912 focusY /= box.height;
14913
14914 fill.focussize = '0 0';
14915 fill.focusposition = focusX + ',' + focusY;
14916 fill.focus = '50%';
14917
14918 this._transform();
14919
14920 return this;
14921 },
14922
14923 fillLinear: function(stops, x1, y1, x2, y2){
14924 var fill = this._createGradient('gradient', stops);
14925 fill.focus = '100%';
14926 if (arguments.length == 5){
14927 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
14928 this._boxCoords = {
14929 left: Math.min(x1, x2),
14930 top: Math.min(y1, y2),
14931 width: w < 1 ? h : w,
14932 height: h < 1 ? w : h
14933 };
14934 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
14935 } else {
14936 this._boxCoords = null;
14937 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
14938 }
14939 this._transform();
14940 return this;
14941 },
14942
14943 fillImage: function(url, width, height, left, top, color1, color2){
14944 var fill = this.fillElement;
14945 if (color1 != null){
14946 color1 = color.detach(color1);
14947 if (color2 != null) color2 = color.detach(color2);
14948 fill.type = 'pattern';
14949 fill.color = color1[0];
14950 fill.color2 = color2 == null ? color1[0] : color2[0];
14951 fill.opacity = color2 == null ? 0 : color2[1];
14952 fill['ao:opacity2'] = color1[1];
14953 } else {
14954 fill.type = 'tile';
14955 fill.color = '';
14956 fill.color2 = '';
14957 fill.opacity = 1;
14958 fill['ao:opacity2'] = 1;
14959 }
14960 if (fill.colors) fill.colors.value = '';
14961 fill.rotate = true;
14962 fill.src = url;
14963
14964 fill.size = '1,1';
14965 fill.position = '0,0';
14966 fill.origin = '0,0';
14967 fill.aspect = 'ignore'; // ignore, atleast, atmost
14968 fill.on = true;
14969
14970 if (!left) left = 0;
14971 if (!top) top = 0;
14972 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
14973 this._transform();
14974 return this;
14975 },
14976
14977 /* stroke */
14978
14979 stroke: function(color$$2, width, cap, join){
14980 var stroke = this.strokeElement;
14981 this._strokeWidth = (width != null) ? width : 1;
14982 stroke.weight = (width != null) ? width + 'px' : 1;
14983 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
14984 stroke.joinstyle = (join != null) ? join : 'round';
14985
14986 this._setColor('stroke', color$$2);
14987 return this;
14988 }
14989
14990});
14991
14992var precision$2 = 100;
14993
14994var shape$2 = _class(base$2, {
14995
14996 base_initialize: base$2.prototype.initialize,
14997
14998 initialize: function(path, width, height){
14999 this.base_initialize('shape');
15000
15001 var p = this.pathElement = dom.createElement('path');
15002 p.gradientshapeok = true;
15003 this.element.appendChild(p);
15004
15005 this.width = width;
15006 this.height = height;
15007
15008 if (path != null) this.draw(path);
15009 },
15010
15011 // SVG to VML
15012
15013 draw: function(path, width, height){
15014
15015 if (!(path instanceof path$4)) path = new path$4(path);
15016 this._vml = path.toVML();
15017 //this._size = path.measure();
15018
15019 if (width != null) this.width = width;
15020 if (height != null) this.height = height;
15021
15022 if (!this._boxCoords) this._transform();
15023 this._redraw(this._prefix, this._suffix);
15024
15025 return this;
15026 },
15027
15028 // radial gradient workaround
15029
15030 _redraw: function(prefix, suffix){
15031 var vml = this._vml || '';
15032
15033 this._prefix = prefix;
15034 this._suffix = suffix;
15035 if (prefix){
15036 vml = [
15037 prefix, vml, suffix,
15038 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
15039 'ns e', vml, 'nf'
15040 ].join(' ');
15041 }
15042
15043 this.element.path = vml + 'e';
15044 },
15045
15046 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
15047 var fill = this._createGradient('gradientradial', stops);
15048 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
15049 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
15050 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
15051 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
15052 if (centerX == null) centerX = focusX;
15053 if (centerY == null) centerY = focusY;
15054
15055 centerX += centerX - focusX;
15056 centerY += centerY - focusY;
15057
15058 var cx = Math.round(centerX * precision$2),
15059 cy = Math.round(centerY * precision$2),
15060
15061 rx = Math.round(radiusX * 2 * precision$2),
15062 ry = Math.round(radiusY * 2 * precision$2),
15063
15064 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
15065
15066 this._redraw(
15067 // Resolve rendering bug
15068 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
15069 // Draw an ellipse around the path to force an elliptical gradient on any shape
15070 [
15071 'm', cx, cy - ry,
15072 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
15073 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
15074 ].join(' ')
15075 );
15076
15077 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
15078
15079 fill.focusposition = '0.5,0.5';
15080 fill.focussize = '0 0';
15081 fill.focus = '50%';
15082
15083 this._transform();
15084
15085 return this;
15086 }
15087
15088});
15089
15090var group$2 = _class(node$2, container, {
15091
15092 element_initialize: node$2.prototype.initialize,
15093
15094 initialize: function(width, height){
15095 this.element_initialize('group');
15096 this.width = width;
15097 this.height = height;
15098 },
15099
15100 _transform: function(){
15101 var element = this.element;
15102 element.coordorigin = '0,0';
15103 element.coordsize = '1000,1000';
15104 element.style.left = 0;
15105 element.style.top = 0;
15106 element.style.width = 1000;
15107 element.style.height = 1000;
15108 element.style.rotation = 0;
15109
15110 var container$$2 = this.parentNode;
15111 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
15112 var node = this.firstChild;
15113 while (node){
15114 node._transform();
15115 node = node.nextSibling;
15116 }
15117 }
15118
15119});
15120
15121var clippingrectangle$2 = _class(node$2, container, {
15122
15123 element_initialize: node$2.prototype.initialize,
15124
15125 initialize: function(width, height){
15126 this.element_initialize('clippingrectangle');
15127 this.width = width;
15128 this.height = height;
15129 },
15130
15131 _transform: function(){
15132 var element = this.element;
15133 element.clip = true;
15134 element.coordorigin = -this.x + ',' + (-1 * this.y);
15135 element.coordsize = this.width + ',' + this.height;
15136 // IE8 doesn't like clipBottom. Don't ask me why.
15137 // element.style.clipBottom = this.height + this.y;
15138 element.style.clipLeft = this.x;
15139 element.style.clipRight = this.width + this.x;
15140 element.style.clipTop = this.y;
15141 element.style.left = -this.x;
15142 element.style.top = -this.y;
15143 element.style.width = this.width + this.x;
15144 element.style.height = this.height + this.y;
15145 element.style.rotation = 0;
15146
15147 var container$$2 = this.parentNode;
15148 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
15149 var node = this.firstChild;
15150 while (node){
15151 node._transform();
15152 node = node.nextSibling;
15153 }
15154 }
15155
15156});
15157
15158var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
15159
15160var text$2 = _class(base$2, {
15161
15162 base_initialize: base$2.prototype.initialize,
15163
15164 initialize: function(text, font, alignment, path){
15165 this.base_initialize('shape');
15166
15167 var p = this.pathElement = dom.createElement('path');
15168 p.textpathok = true;
15169 this.element.appendChild(p);
15170
15171 p = this.textPathElement = dom.createElement("textpath");
15172 p.on = true;
15173 p.style['v-text-align'] = 'left';
15174 this.element.appendChild(p);
15175
15176 this.draw.apply(this, arguments);
15177 },
15178
15179 draw: function(text, font, alignment, path){
15180 var element = this.element,
15181 textPath = this.textPathElement,
15182 style = textPath.style;
15183
15184 textPath.string = text;
15185
15186 if (font){
15187 if (typeof font == 'string'){
15188 style.font = font;
15189 } else {
15190 for (var key in font){
15191 var ckey = key.camelCase ? key.camelCase() : key;
15192 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
15193 // NOT UNIVERSALLY SUPPORTED OPTIONS
15194 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
15195 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
15196 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
15197 else style[ckey] = font[key];
15198 }
15199 }
15200 }
15201
15202 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
15203
15204 if (path){
15205 this.currentPath = path = new path$4(path);
15206 this.element.path = path.toVML();
15207 } else if (!this.currentPath){
15208 var i = -1, offsetRows = '\n';
15209 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
15210 textPath.string = offsetRows + textPath.string;
15211 this.element.path = 'm0,0l1,0';
15212 }
15213
15214 // Measuring the bounding box is currently necessary for gradients etc.
15215
15216 // Clone element because the element is dead once it has been in the DOM
15217 element = element.cloneNode(true);
15218 style = element.style;
15219
15220 // Reset coordinates while measuring
15221 element.coordorigin = '0,0';
15222 element.coordsize = '10000,10000';
15223 style.left = '0px';
15224 style.top = '0px';
15225 style.width = '10000px';
15226 style.height = '10000px';
15227 style.rotation = 0;
15228 element.removeChild(element.firstChild); // Remove skew
15229
15230 // Inject the clone into the document
15231
15232 var canvas = new surface$2(1, 1),
15233 group = new group$2(), // Wrapping it in a group seems to alleviate some client rect weirdness
15234 body = element.ownerDocument.body;
15235
15236 canvas.inject(body);
15237 group.element.appendChild(element);
15238 group.inject(canvas);
15239
15240 var ebb = element.getBoundingClientRect(),
15241 cbb = canvas.toElement().getBoundingClientRect();
15242
15243 canvas.eject();
15244
15245 this.left = ebb.left - cbb.left;
15246 this.top = ebb.top - cbb.top;
15247 this.width = ebb.right - ebb.left;
15248 this.height = ebb.bottom - ebb.top;
15249 this.right = ebb.right - cbb.left;
15250 this.bottom = ebb.bottom - cbb.top;
15251
15252 this._transform();
15253
15254 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
15255 return this;
15256 }
15257
15258});
15259
15260var fastNoSideEffects = createCommonjsModule(function (module, exports) {
15261var hasCanvas = function(){
15262
15263 var canvas = document.createElement('canvas');
15264 return canvas && !!canvas.getContext;
15265
15266};
15267
15268if (hasCanvas()) {
15269 exports.Surface = surface;
15270 exports.Path = path;
15271 exports.Shape = shape;
15272 exports.Group = group;
15273 exports.ClippingRectangle = clippingrectangle;
15274 exports.Text = text;
15275} else {
15276 exports.Surface = surface$2;
15277 exports.Path = path$4;
15278 exports.Shape = shape$2;
15279 exports.Group = group$2;
15280 exports.ClippingRectangle = clippingrectangle$2;
15281 exports.Text = text$2;
15282
15283 var DOM$$1 = dom;
15284 if (typeof document !== 'undefined') DOM$$1.init(document);
15285}
15286});
15287
15288var fastNoSideEffects_1 = fastNoSideEffects.Surface;
15289var fastNoSideEffects_2 = fastNoSideEffects.Path;
15290var fastNoSideEffects_3 = fastNoSideEffects.Shape;
15291var fastNoSideEffects_4 = fastNoSideEffects.Group;
15292var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
15293var fastNoSideEffects_6 = fastNoSideEffects.Text;
15294
15295var _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; };
15296
15297function _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; }
15298
15299function _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; }
15300
15301function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
15302
15303current.setCurrent(
15304// Change to 'art/modes/dom' for easier debugging via SVG
15305fastNoSideEffects);
15306
15307/** Declarative fill-type objects; API design not finalized */
15308
15309var slice = Array.prototype.slice;
15310
15311var LinearGradient = function () {
15312 function LinearGradient(stops, x1, y1, x2, y2) {
15313 _classCallCheck(this, LinearGradient);
15314
15315 this._args = slice.call(arguments);
15316 }
15317
15318 LinearGradient.prototype.applyFill = function applyFill(node) {
15319 node.fillLinear.apply(node, this._args);
15320 };
15321
15322 return LinearGradient;
15323}();
15324
15325var RadialGradient = function () {
15326 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
15327 _classCallCheck(this, RadialGradient);
15328
15329 this._args = slice.call(arguments);
15330 }
15331
15332 RadialGradient.prototype.applyFill = function applyFill(node) {
15333 node.fillRadial.apply(node, this._args);
15334 };
15335
15336 return RadialGradient;
15337}();
15338
15339var Pattern = function () {
15340 function Pattern(url, width, height, left, top) {
15341 _classCallCheck(this, Pattern);
15342
15343 this._args = slice.call(arguments);
15344 }
15345
15346 Pattern.prototype.applyFill = function applyFill(node) {
15347 node.fillImage.apply(node, this._args);
15348 };
15349
15350 return Pattern;
15351}();
15352
15353/** React Components */
15354
15355var Surface = function (_React$Component) {
15356 _inherits(Surface, _React$Component);
15357
15358 function Surface() {
15359 _classCallCheck(this, Surface);
15360
15361 return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
15362 }
15363
15364 Surface.prototype.componentDidMount = function componentDidMount() {
15365 var _props = this.props,
15366 height = _props.height,
15367 width = _props.width;
15368
15369
15370 this._surface = current.Surface(+width, +height, this._tagRef);
15371
15372 this._mountNode = createContainer(this._surface);
15373 updateContainer(this.props.children, this._mountNode, this);
15374 };
15375
15376 Surface.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
15377 var props = this.props;
15378
15379 if (props.height !== prevProps.height || props.width !== prevProps.width) {
15380 this._surface.resize(+props.width, +props.height);
15381 }
15382
15383 updateContainer(this.props.children, this._mountNode, this);
15384
15385 if (this._surface.render) {
15386 this._surface.render();
15387 }
15388 };
15389
15390 Surface.prototype.componentWillUnmount = function componentWillUnmount() {
15391 updateContainer(null, this._mountNode, this);
15392 };
15393
15394 Surface.prototype.render = function render() {
15395 var _this2 = this;
15396
15397 // This is going to be a placeholder because we don't know what it will
15398 // actually resolve to because ART may render canvas, vml or svg tags here.
15399 // We only allow a subset of properties since others might conflict with
15400 // ART's properties.
15401 var props = this.props;
15402
15403 // TODO: ART's Canvas Mode overrides surface title and cursor
15404 var Tag = current.Surface.tagName;
15405
15406 return React.createElement(Tag, {
15407 ref: function (ref) {
15408 return _this2._tagRef = ref;
15409 },
15410 accessKey: props.accessKey,
15411 className: props.className,
15412 draggable: props.draggable,
15413 role: props.role,
15414 style: props.style,
15415 tabIndex: props.tabIndex,
15416 title: props.title
15417 });
15418 };
15419
15420 return Surface;
15421}(React.Component);
15422
15423var Text = function (_React$Component2) {
15424 _inherits(Text, _React$Component2);
15425
15426 function Text(props) {
15427 _classCallCheck(this, Text);
15428
15429 // We allow reading these props. Ideally we could expose the Text node as
15430 // ref directly.
15431 var _this3 = _possibleConstructorReturn(this, _React$Component2.call(this, props));
15432
15433 ['height', 'width', 'x', 'y'].forEach(function (key) {
15434 Object.defineProperty(_this3, key, {
15435 get: function () {
15436 return this._text ? this._text[key] : undefined;
15437 }
15438 });
15439 });
15440 return _this3;
15441 }
15442
15443 Text.prototype.render = function render() {
15444 var _this4 = this;
15445
15446 // This means you can't have children that render into strings...
15447 var T = TYPES.TEXT;
15448 return React.createElement(
15449 T,
15450 _extends({}, this.props, { ref: function (t) {
15451 return _this4._text = t;
15452 } }),
15453 childrenAsString(this.props.children)
15454 );
15455 };
15456
15457 return Text;
15458}(React.Component);
15459
15460injectIntoDevTools({
15461 findFiberByHostInstance: function () {
15462 return null;
15463 },
15464 bundleType: 1,
15465 version: ReactVersion,
15466 rendererPackageName: 'react-art'
15467});
15468
15469/** API */
15470
15471var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
15472var Group = TYPES.GROUP;
15473var Shape = TYPES.SHAPE;
15474var Path = current.Path;
15475
15476
15477var ReactART = Object.freeze({
15478 ClippingRectangle: ClippingRectangle,
15479 Group: Group,
15480 Shape: Shape,
15481 Path: Path,
15482 LinearGradient: LinearGradient,
15483 Pattern: Pattern,
15484 RadialGradient: RadialGradient,
15485 Surface: Surface,
15486 Text: Text,
15487 Transform: transform
15488});
15489
15490var reactArt = ReactART;
15491
15492return reactArt;
15493
15494})));